From: Xiaoyao Li <[email protected]>

The SMM cpu address space is initialized in a machine_init_done
notifier. It only runs once when QEMU starts up, which leads to the
issue that for any hotplugged CPU after the machine is ready, SMM
cpu address space doesn't get initialized.

Fix the issue by initializing the SMM cpu address space in x86_cpu_plug()
when the cpu is hotplugged.

Fixes: 591f817d819f ("target/i386: Define enum X86ASIdx for x86's address 
spaces")
Reported-by: Peter Maydell <[email protected]>
Closes: 
https://lore.kernel.org/qemu-devel/cafeaca_3kkz+a5rtzgmk8w5k6j7qpyd31hkvjbnxwr-fgt2...@mail.gmail.com/
Signed-off-by: Xiaoyao Li <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Paolo Bonzini <[email protected]>
(cherry picked from commit 639a29422754f62b4bfd26cff936b3c981758010)
(Mjt: the original Fixes: line is wrong:
 
https://lore.kernel.org/qemu-devel/[email protected]/T/#u
 )
Fixes: 0516f4b70264 ("i386/cpu: Enable SMM cpu address space under KVM")
Fixes: 232d5c627589 ("i386/cpu: Enable SMM cpu address space under KVM"), 10.1.5
Signed-off-by: Michael Tokarev <[email protected]>

diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c
index 1b0671c523..0ab27c053f 100644
--- a/hw/i386/x86-common.c
+++ b/hw/i386/x86-common.c
@@ -182,6 +182,17 @@ void x86_cpu_plug(HotplugHandler *hotplug_dev,
         fw_cfg_modify_i16(x86ms->fw_cfg, FW_CFG_NB_CPUS, x86ms->boot_cpus);
     }
 
+    /*
+     * Non-hotplugged CPUs get their SMM cpu address space initialized in
+     * machine init done notifier: register_smram_listener().
+     *
+     * We need initialize the SMM cpu address space for the hotplugged CPU
+     * specifically.
+     */
+    if (kvm_enabled() && dev->hotplugged && x86_machine_is_smm_enabled(x86ms)) 
{
+        kvm_smm_cpu_address_space_init(cpu);
+    }
+
     found_cpu = x86_find_cpu_slot(MACHINE(x86ms), cpu->apic_id, NULL);
     found_cpu->cpu = CPU(dev);
 out:
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index e77fb752c2..98e99374e7 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -2722,6 +2722,12 @@ static void register_smram_listener(Notifier *n, void 
*unused)
     }
 }
 
+/* It should only be called in cpu's hotplug callback */
+void kvm_smm_cpu_address_space_init(X86CPU *cpu)
+{
+    cpu_address_space_init(CPU(cpu), X86ASIdx_SMM, "cpu-smm", &smram_as_root);
+}
+
 static void *kvm_msr_energy_thread(void *data)
 {
     KVMState *s = data;
diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h
index 88565e8dba..b5f274c27f 100644
--- a/target/i386/kvm/kvm_i386.h
+++ b/target/i386/kvm/kvm_i386.h
@@ -59,6 +59,7 @@ void kvm_update_msi_routes_all(void *private, bool global,
 
 #endif /* CONFIG_KVM */
 
+void kvm_smm_cpu_address_space_init(X86CPU *cpu);
 void kvm_pc_setup_irq_routing(bool pci_enabled);
 
 #endif
-- 
2.47.3


Reply via email to