]> xenbits.xensource.com Git - seabios.git/commitdiff
smp: restore MSRs on S3 resume
authorPaolo Bonzini <pbonzini@redhat.com>
Thu, 7 Jul 2016 14:00:40 +0000 (16:00 +0200)
committerKevin O'Connor <kevin@koconnor.net>
Thu, 7 Jul 2016 15:51:18 +0000 (11:51 -0400)
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 separate out the
remaining common code to a new smp_scan function.  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_scan to initialize the APs.

Reported-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
src/fw/smp.c
src/resume.c
src/util.h

index 6e706e42a4e74f6a01c47538d606b8acd829dc28..719d51d6fc343e63b462576e114fffb02d8bccf3 100644 (file)
@@ -36,6 +36,15 @@ wrmsr_smp(u32 index, u64 val)
     smp_msr_count++;
 }
 
+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);
+}
+
 u32 MaxCountCPUs;
 static u32 CountCPUs;
 // 256 bits for the found APIC IDs
@@ -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));
@@ -74,12 +80,9 @@ u32 SMPLock __VISIBLE;
 u32 SMPStack __VISIBLE;
 
 // find and initialize the CPUs by launching a SIPI to them
-void
-smp_setup(void)
+static void
+smp_scan(void)
 {
-    if (!CONFIG_QEMU)
-        return;
-
     ASSERT32FLAT();
     u32 eax, ebx, ecx, cpuid_features;
     cpuid(1, &eax, &ebx, &ecx, &cpuid_features);
@@ -87,7 +90,6 @@ smp_setup(void)
         // No apic - only the main cpu is present.
         dprintf(1, "No apic - only the main cpu is present.\n");
         CountCPUs= 1;
-        MaxCountCPUs = 1;
         return;
     }
 
@@ -141,10 +143,30 @@ 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_setup(void)
+{
+    if (!CONFIG_QEMU)
+        return;
+
+    MaxCountCPUs = romfile_loadint("etc/max-cpus", 0);
+    u8 cmos_smp_count = rtc_read(CMOS_BIOS_SMP_COUNT) + 1;
+    if (MaxCountCPUs < cmos_smp_count)
+        MaxCountCPUs = cmos_smp_count;
+
+    smp_scan();
+}
+
+void
+smp_resume(void)
+{
+    if (!CONFIG_QEMU)
+        return;
+
+    smp_write_msrs();
+    smp_scan();
+}
index afeadcf24530f11713261a67425d3d204c47032d..e67cfce782941065f3be2a0d288d653b43d4e8ca 100644 (file)
@@ -97,6 +97,7 @@ s3_resume(void)
 
     pic_setup();
     smm_setup();
+    smp_resume();
 
     pci_resume();
 
index 7b41207595d94ce6453ef8156682391ca18990a5..7bfd2b8051de4f418fcaf0c00ccf91825a9c6c86 100644 (file)
@@ -135,6 +135,7 @@ void smm_setup(void);
 extern u32 MaxCountCPUs;
 void wrmsr_smp(u32 index, u64 val);
 void smp_setup(void);
+void smp_resume(void);
 int apic_id_is_present(u8 apic_id);
 
 // hw/dma.c