Commit e0723c45 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

kvm: forward INIT signals coming from the chipset

parent 50a2c6e5
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

#include "cpu.h"
#include "sysemu/kvm.h"
#include "kvm_i386.h"
#ifndef CONFIG_USER_ONLY
#include "sysemu/sysemu.h"
#include "monitor/monitor.h"
@@ -1335,6 +1336,9 @@ void do_cpu_init(X86CPU *cpu)
    cpu_reset(cs);
    cs->interrupt_request = sipi;
    env->pat = pat;
    if (kvm_enabled()) {
        kvm_arch_do_init_vcpu(cpu);
    }
    apic_init_reset(cpu->apic_state);
}

+25 −11
Original line number Diff line number Diff line
@@ -30,6 +30,8 @@
#include "qemu/config-file.h"
#include "hw/i386/pc.h"
#include "hw/i386/apic.h"
#include "hw/i386/apic_internal.h"
#include "hw/i386/apic-msidef.h"
#include "exec/ioport.h"
#include <asm/hyperv.h>
#include "hw/pci/pci.h"
@@ -738,6 +740,16 @@ void kvm_arch_reset_vcpu(X86CPU *cpu)
    }
}

void kvm_arch_do_init_vcpu(X86CPU *cpu)
{
    CPUX86State *env = &cpu->env;

    /* APs get directly into wait-for-SIPI state.  */
    if (env->mp_state == KVM_MP_STATE_UNINITIALIZED) {
        env->mp_state = KVM_MP_STATE_INIT_RECEIVED;
    }
}

static int kvm_get_supported_msrs(KVMState *s)
{
    static int kvm_supported_msrs;
@@ -2003,14 +2015,15 @@ void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run)
        }
    }

    if (!kvm_irqchip_in_kernel()) {
    /* Force the VCPU out of its inner loop to process any INIT requests
         * or pending TPR access reports. */
        if (cpu->interrupt_request &
            (CPU_INTERRUPT_INIT | CPU_INTERRUPT_TPR)) {
     * or (for userspace APIC, but it is cheap to combine the checks here)
     * pending TPR access reports.
     */
    if (cpu->interrupt_request & (CPU_INTERRUPT_INIT | CPU_INTERRUPT_TPR)) {
        cpu->exit_request = 1;
    }

    if (!kvm_irqchip_in_kernel()) {
        /* Try to inject an interrupt if the guest can accept it */
        if (run->ready_for_interrupt_injection &&
            (cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
@@ -2090,6 +2103,11 @@ int kvm_arch_process_async_events(CPUState *cs)
        }
    }

    if (cs->interrupt_request & CPU_INTERRUPT_INIT) {
        kvm_cpu_synchronize_state(cs);
        do_cpu_init(cpu);
    }

    if (kvm_irqchip_in_kernel()) {
        return 0;
    }
@@ -2103,10 +2121,6 @@ int kvm_arch_process_async_events(CPUState *cs)
        (cs->interrupt_request & CPU_INTERRUPT_NMI)) {
        cs->halted = 0;
    }
    if (cs->interrupt_request & CPU_INTERRUPT_INIT) {
        kvm_cpu_synchronize_state(cs);
        do_cpu_init(cpu);
    }
    if (cs->interrupt_request & CPU_INTERRUPT_SIPI) {
        kvm_cpu_synchronize_state(cs);
        do_cpu_sipi(cpu);
+1 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@

bool kvm_allows_irq0_override(void);
void kvm_arch_reset_vcpu(X86CPU *cs);
void kvm_arch_do_init_vcpu(X86CPU *cs);

int kvm_device_pci_assign(KVMState *s, PCIHostDeviceAddress *dev_addr,
                          uint32_t flags, uint32_t *dev_id);