[SeaBIOS] [PATCH] restore MSRs on S3 resume

Paolo Bonzini pbonzini at redhat.com
Thu Jul 7 16:00:40 CEST 2016


Currently the MTRRs and MSR_IA32_FEATURE_CONTROL are not restored on S3
resume.  Because these have to be applied to all processors, SMP setup
has to be added to S3 resume.

There are two differences between the boot and resume paths.  First,
romfile_* is not usable in the resume paths so we move the call out
of smp_setup and into a new function smp_boot_setup.  Second,
smp_msr has to be walked on the BSP as well, so we extract that
out of handle_smp and into a new function smp_write_msrs.  Then,
resume can call smp_write_msrs on the BSP followed by smp_setup to
initialize the APs.

Reported-by: Laszlo Ersek <lersek at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
---
 src/fw/paravirt.c |  1 +
 src/fw/smp.c      | 28 +++++++++++++++++++++++-----
 src/resume.c      |  1 +
 src/util.h        |  2 ++
 4 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/src/fw/paravirt.c b/src/fw/paravirt.c
index e8e419e..9189672 100644
--- a/src/fw/paravirt.c
+++ b/src/fw/paravirt.c
@@ -160,6 +160,7 @@ qemu_platform_setup(void)
     // Initialize mtrr, msr_feature_control and smp
     mtrr_setup();
     msr_feature_control_setup();
+    smp_boot_setup();
     smp_setup();
 
     // Create bios tables
diff --git a/src/fw/smp.c b/src/fw/smp.c
index 6e706e4..64e76b6 100644
--- a/src/fw/smp.c
+++ b/src/fw/smp.c
@@ -46,6 +46,15 @@ int apic_id_is_present(u8 apic_id)
     return !!(FoundAPICIDs[apic_id/32] & (1ul << (apic_id % 32)));
 }
 
+static void
+smp_write_msrs(void)
+{
+    // MTRR and MSR_IA32_FEATURE_CONTROL setup
+    int i;
+    for (i=0; i<smp_msr_count; i++)
+        wrmsr(smp_msr[i].index, smp_msr[i].val);
+}
+
 void VISIBLE32FLAT
 handle_smp(void)
 {
@@ -58,10 +67,7 @@ handle_smp(void)
     u8 apic_id = ebx>>24;
     dprintf(DEBUG_HDL_smp, "handle_smp: apic_id=%d\n", apic_id);
 
-    // MTRR and MSR_IA32_FEATURE_CONTROL setup
-    int i;
-    for (i=0; i<smp_msr_count; i++)
-        wrmsr(smp_msr[i].index, smp_msr[i].val);
+    smp_write_msrs();
 
     // Set bit on FoundAPICIDs
     FoundAPICIDs[apic_id/32] |= (1 << (apic_id % 32));
@@ -73,6 +79,12 @@ handle_smp(void)
 u32 SMPLock __VISIBLE;
 u32 SMPStack __VISIBLE;
 
+void
+smp_boot_setup(void)
+{
+    MaxCountCPUs = romfile_loadint("etc/max-cpus", 0);
+}
+
 // find and initialize the CPUs by launching a SIPI to them
 void
 smp_setup(void)
@@ -141,10 +153,16 @@ smp_setup(void)
     // Restore memory.
     *(u64*)BUILD_AP_BOOT_ADDR = old;
 
-    MaxCountCPUs = romfile_loadint("etc/max-cpus", 0);
     if (!MaxCountCPUs || MaxCountCPUs < CountCPUs)
         MaxCountCPUs = CountCPUs;
 
     dprintf(1, "Found %d cpu(s) max supported %d cpu(s)\n", CountCPUs,
             MaxCountCPUs);
 }
+
+void
+smp_resume(void)
+{
+    smp_write_msrs();
+    smp_setup();
+}
diff --git a/src/resume.c b/src/resume.c
index a5465d8..3a26f84 100644
--- a/src/resume.c
+++ b/src/resume.c
@@ -97,6 +97,7 @@ s3_resume(void)
 
     pic_setup();
     smm_setup();
+    smp_resume();
 
     pci_resume();
 
diff --git a/src/util.h b/src/util.h
index cba3359..510da73 100644
--- a/src/util.h
+++ b/src/util.h
@@ -131,7 +131,9 @@ void smm_setup(void);
 // fw/smp.c
 extern u32 MaxCountCPUs;
 void wrmsr_smp(u32 index, u64 val);
+void smp_boot_setup(void);
 void smp_setup(void);
+void smp_resume(void);
 int apic_id_is_present(u8 apic_id);
 
 // hw/dma.c
-- 
1.8.3.1




More information about the SeaBIOS mailing list