aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/i386/microvm.c4
-rw-r--r--hw/i386/pc.c5
-rw-r--r--target/i386/cpu.c13
-rw-r--r--target/i386/cpu.h2
-rw-r--r--target/i386/kvm/hyperv.c4
-rw-r--r--target/i386/kvm/kvm.c24
-rw-r--r--target/i386/kvm/kvm_i386.h1
7 files changed, 40 insertions, 13 deletions
diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
index 7fe8cce..52f9aa9 100644
--- a/hw/i386/microvm.c
+++ b/hw/i386/microvm.c
@@ -485,9 +485,7 @@ static void microvm_machine_reset(MachineState *machine)
CPU_FOREACH(cs) {
cpu = X86_CPU(cs);
- if (cpu->apic_state) {
- device_legacy_reset(cpu->apic_state);
- }
+ x86_cpu_after_reset(cpu);
}
}
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 566accf..768982a 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -92,6 +92,7 @@
#include "hw/virtio/virtio-mem-pci.h"
#include "hw/mem/memory-device.h"
#include "sysemu/replay.h"
+#include "target/i386/cpu.h"
#include "qapi/qmp/qerror.h"
#include "e820_memory_layout.h"
#include "fw_cfg.h"
@@ -1859,9 +1860,7 @@ static void pc_machine_reset(MachineState *machine)
CPU_FOREACH(cs) {
cpu = X86_CPU(cs);
- if (cpu->apic_state) {
- device_legacy_reset(cpu->apic_state);
- }
+ x86_cpu_after_reset(cpu);
}
}
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 8a11470..90aec2f 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -6035,6 +6035,19 @@ static void x86_cpu_reset(DeviceState *dev)
#endif
}
+void x86_cpu_after_reset(X86CPU *cpu)
+{
+#ifndef CONFIG_USER_ONLY
+ if (kvm_enabled()) {
+ kvm_arch_after_reset_vcpu(cpu);
+ }
+
+ if (cpu->apic_state) {
+ device_legacy_reset(cpu->apic_state);
+ }
+#endif
+}
+
static void mce_init(X86CPU *cpu)
{
CPUX86State *cenv = &cpu->env;
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 7edf5df..4d21c57 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -2082,6 +2082,8 @@ typedef struct PropValue {
} PropValue;
void x86_cpu_apply_props(X86CPU *cpu, PropValue *props);
+void x86_cpu_after_reset(X86CPU *cpu);
+
uint32_t cpu_x86_virtual_addr_width(CPUX86State *env);
/* cpu.c other functions (cpuid) */
diff --git a/target/i386/kvm/hyperv.c b/target/i386/kvm/hyperv.c
index 9026ef3..e3ac978 100644
--- a/target/i386/kvm/hyperv.c
+++ b/target/i386/kvm/hyperv.c
@@ -23,6 +23,10 @@ int hyperv_x86_synic_add(X86CPU *cpu)
return 0;
}
+/*
+ * All devices possibly using SynIC have to be reset before calling this to let
+ * them remove their SINT routes first.
+ */
void hyperv_x86_synic_reset(X86CPU *cpu)
{
hyperv_synic_reset(CPU(cpu));
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index bed6c00..dac100c 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -2203,20 +2203,30 @@ void kvm_arch_reset_vcpu(X86CPU *cpu)
env->mp_state = KVM_MP_STATE_RUNNABLE;
}
+ /* enabled by default */
+ env->poll_control_msr = 1;
+
+ kvm_init_nested_state(env);
+
+ sev_es_set_reset_vector(CPU(cpu));
+}
+
+void kvm_arch_after_reset_vcpu(X86CPU *cpu)
+{
+ CPUX86State *env = &cpu->env;
+ int i;
+
+ /*
+ * Reset SynIC after all other devices have been reset to let them remove
+ * their SINT routes first.
+ */
if (hyperv_feat_enabled(cpu, HYPERV_FEAT_SYNIC)) {
- int i;
for (i = 0; i < ARRAY_SIZE(env->msr_hv_synic_sint); i++) {
env->msr_hv_synic_sint[i] = HV_SINT_MASKED;
}
hyperv_x86_synic_reset(cpu);
}
- /* enabled by default */
- env->poll_control_msr = 1;
-
- kvm_init_nested_state(env);
-
- sev_es_set_reset_vector(CPU(cpu));
}
void kvm_arch_do_init_vcpu(X86CPU *cpu)
diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h
index 2ed586c..b7c38ba 100644
--- a/target/i386/kvm/kvm_i386.h
+++ b/target/i386/kvm/kvm_i386.h
@@ -38,6 +38,7 @@ bool kvm_has_adjust_clock_stable(void);
bool kvm_has_exception_payload(void);
void kvm_synchronize_all_tsc(void);
void kvm_arch_reset_vcpu(X86CPU *cs);
+void kvm_arch_after_reset_vcpu(X86CPU *cpu);
void kvm_arch_do_init_vcpu(X86CPU *cs);
void kvm_put_apicbase(X86CPU *cpu, uint64_t value);