Changelog: since RFC: * move out max-cpus check out of mptable_setup() * factor out CPU counting/apic ID detection in separate function * return back accidentially deleted debug message with APIC ID * drop unused code in smp_setup()
According to SDM, if CPUs have APIC ID more than 254 firmware should pass control to OS in x2APIC mode. This series adds x2APIC bootstrap initialization.
QEMU side of x2APIC support: https://lists.gnu.org/archive/html/qemu-devel/2016-05/msg01094.html
Igor Mammedov (3): paravirt: disable legacy bios tables in case of more than 255 CPUs support booting with more than 255 CPUs cleanup smp_setup()
Kevin O'Connor (1): smp: refactor present CPU APIC ID detection and counting
src/fw/paravirt.c | 6 +++-- src/fw/smp.c | 67 ++++++++++++++++++++++++++++++++++++++++--------------- src/x86.h | 1 + 3 files changed, 54 insertions(+), 20 deletions(-)
MPTable doesn't support more than 255 CPUs and QEMU supplies an alternative MADT table which guest will use instead of it. So do not install legacy tables if more than 254 CPUs are provided
Signed-off-by: Igor Mammedov imammedo@redhat.com --- src/fw/paravirt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/fw/paravirt.c b/src/fw/paravirt.c index 8ed4380..9b07aaa 100644 --- a/src/fw/paravirt.c +++ b/src/fw/paravirt.c @@ -154,8 +154,10 @@ qemu_platform_setup(void) smp_setup();
// Create bios tables - pirtable_setup(); - mptable_setup(); + if (MaxCountCPUs <= 255) { + pirtable_setup(); + mptable_setup(); + } smbios_setup();
if (CONFIG_FW_ROMFILE_LOAD) {
From: Kevin O'Connor kevin@koconnor.net
Signed-off-by: "Kevin O'Connor" kevin@koconnor.net Signed-off-by: Igor Mammedov imammedo@redhat.com --- src/fw/smp.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-)
diff --git a/src/fw/smp.c b/src/fw/smp.c index 579acdb..ad98a5f 100644 --- a/src/fw/smp.c +++ b/src/fw/smp.c @@ -46,27 +46,34 @@ int apic_id_is_present(u8 apic_id) return !!(FoundAPICIDs[apic_id/32] & (1ul << (apic_id % 32))); }
+static int +count_cpu(void) +{ + CountCPUs++; + + // Track found apic id for use in legacy internal bios tables + u32 eax, ebx, ecx, cpuid_features; + cpuid(1, &eax, &ebx, &ecx, &cpuid_features); + u8 apic_id = ebx>>24; + FoundAPICIDs[apic_id/32] |= 1 << (apic_id % 32); + + return apic_id; +} + void VISIBLE32FLAT handle_smp(void) { if (!CONFIG_QEMU) return;
- // Detect apic_id - u32 eax, ebx, ecx, cpuid_features; - cpuid(1, &eax, &ebx, &ecx, &cpuid_features); - u8 apic_id = ebx>>24; + // Track this CPU and detect the apic_id + int apic_id = count_cpu(); dprintf(DEBUG_HDL_smp, "handle_smp: apic_id=%d\n", apic_id);
// MTRR setup int i; for (i=0; i<smp_mtrr_count; i++) wrmsr(smp_mtrr[i].index, smp_mtrr[i].val); - - // Set bit on FoundAPICIDs - FoundAPICIDs[apic_id/32] |= (1 << (apic_id % 32)); - - CountCPUs++; }
// Atomic lock for shared stack across processors. @@ -91,10 +98,8 @@ smp_setup(void) return; }
- // mark the BSP initial APIC ID as found, too: - u8 apic_id = ebx>>24; - FoundAPICIDs[apic_id/32] |= (1 << (apic_id % 32)); - CountCPUs = 1; + // Detect initial boot cpu + count_cpu();
// Setup jump trampoline to counter code. u64 old = *(u64*)BUILD_AP_BOOT_ADDR;
SDM[*1] says that if there are CPUs with APIC ID greater than 254, BIOS is to pass control to OS in x2APIC mode. Use the fact that QEMU passes in "etc/max-cpus" max possible "APIC ID + 1" to detect need for x2APIC mode. Also instead of CMOS_BIOS_SMP_COUNT which is limited to 256 CPUs use a new rom file "etc/boot-cpus" that QEMU supporting more than 256 CPUs will provide.
*1) SDM: Volume 3: EXTENDED XAPIC (X2APIC): Initialization by System Software
Signed-off-by: Igor Mammedov imammedo@redhat.com --- src/fw/smp.c | 40 ++++++++++++++++++++++++++++++++++------ src/x86.h | 1 + 2 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/src/fw/smp.c b/src/fw/smp.c index ad98a5f..18a4c77 100644 --- a/src/fw/smp.c +++ b/src/fw/smp.c @@ -19,6 +19,9 @@ #define APIC_LINT1 ((u8*)BUILD_APIC_ADDR + 0x360)
#define APIC_ENABLED 0x0100 +#define MSR_IA32_APIC_BASE 0x01B +#define MSR_LOCAL_APIC_ID 0x802 +#define MSR_IA32_APICBASE_EXTD (1ULL << 10) /* Enable x2APIC mode */
static struct { u32 index; u64 val; } smp_mtrr[32]; static u32 smp_mtrr_count; @@ -49,23 +52,46 @@ int apic_id_is_present(u8 apic_id) static int count_cpu(void) { + u32 apic_id; CountCPUs++;
- // Track found apic id for use in legacy internal bios tables u32 eax, ebx, ecx, cpuid_features; cpuid(1, &eax, &ebx, &ecx, &cpuid_features); - u8 apic_id = ebx>>24; - FoundAPICIDs[apic_id/32] |= 1 << (apic_id % 32); + apic_id = ebx>>24; + if (MaxCountCPUs < 256) { // xAPIC mode + // Track found apic id for use in legacy internal bios tables + FoundAPICIDs[apic_id/32] |= 1 << (apic_id % 32); + } + if (rdmsr(MSR_IA32_APIC_BASE) & MSR_IA32_APICBASE_EXTD) { // x2APIC mode + apic_id = rdmsr(MSR_LOCAL_APIC_ID); + }
return apic_id; }
+static void +handle_x2apic(void) +{ + if (MaxCountCPUs < 256) + return; + + u32 eax, ebx, ecx, edx; + cpuid(1, &eax, &ebx, &ecx, &edx); + if (!(ecx & CPUID_X2APIC)) + return; + + // switch to x2APIC mode + u64 apic_base = rdmsr(MSR_IA32_APIC_BASE); + wrmsr(MSR_IA32_APIC_BASE, apic_base | MSR_IA32_APICBASE_EXTD); +} + void VISIBLE32FLAT handle_smp(void) { if (!CONFIG_QEMU) return;
+ handle_x2apic(); // Track this CPU and detect the apic_id int apic_id = count_cpu(); dprintf(DEBUG_HDL_smp, "handle_smp: apic_id=%d\n", apic_id); @@ -98,6 +124,7 @@ smp_setup(void) return; }
+ MaxCountCPUs = romfile_loadint("etc/max-cpus", 1); // Detect initial boot cpu count_cpu();
@@ -129,8 +156,9 @@ smp_setup(void) writel(APIC_ICR_LOW, 0x000C4600 | sipi_vector);
// Wait for other CPUs to process the SIPI. - u8 cmos_smp_count = rtc_read(CMOS_BIOS_SMP_COUNT) + 1; - while (cmos_smp_count != CountCPUs) + u16 boot_cpus_count = romfile_loadint("etc/boot-cpus", + rtc_read(CMOS_BIOS_SMP_COUNT) + 1); + while (boot_cpus_count != CountCPUs) asm volatile( // Release lock and allow other processors to use the stack. " movl %%esp, %1\n" @@ -146,7 +174,7 @@ smp_setup(void) // Restore memory. *(u64*)BUILD_AP_BOOT_ADDR = old;
- MaxCountCPUs = romfile_loadint("etc/max-cpus", 0); + handle_x2apic(); if (!MaxCountCPUs || MaxCountCPUs < CountCPUs) MaxCountCPUs = CountCPUs;
diff --git a/src/x86.h b/src/x86.h index 53378e9..a770e6f 100644 --- a/src/x86.h +++ b/src/x86.h @@ -68,6 +68,7 @@ static inline void wbinvd(void) #define CPUID_MSR (1 << 5) #define CPUID_APIC (1 << 9) #define CPUID_MTRR (1 << 12) +#define CPUID_X2APIC (1 << 21) static inline void __cpuid(u32 index, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx) { asm("cpuid"
On Tue, May 10, 2016 at 04:43:33PM +0200, Igor Mammedov wrote:
SDM[*1] says that if there are CPUs with APIC ID greater than 254, BIOS is to pass control to OS in x2APIC mode. Use the fact that QEMU passes in "etc/max-cpus" max possible "APIC ID + 1" to detect need for x2APIC mode. Also instead of CMOS_BIOS_SMP_COUNT which is limited to 256 CPUs use a new rom file "etc/boot-cpus" that QEMU supporting more than 256 CPUs will provide.
*1) SDM: Volume 3: EXTENDED XAPIC (X2APIC): Initialization by System Software
Signed-off-by: Igor Mammedov imammedo@redhat.com
src/fw/smp.c | 40 ++++++++++++++++++++++++++++++++++------ src/x86.h | 1 + 2 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/src/fw/smp.c b/src/fw/smp.c index ad98a5f..18a4c77 100644 --- a/src/fw/smp.c +++ b/src/fw/smp.c @@ -19,6 +19,9 @@ #define APIC_LINT1 ((u8*)BUILD_APIC_ADDR + 0x360)
#define APIC_ENABLED 0x0100 +#define MSR_IA32_APIC_BASE 0x01B +#define MSR_LOCAL_APIC_ID 0x802 +#define MSR_IA32_APICBASE_EXTD (1ULL << 10) /* Enable x2APIC mode */
static struct { u32 index; u64 val; } smp_mtrr[32]; static u32 smp_mtrr_count; @@ -49,23 +52,46 @@ int apic_id_is_present(u8 apic_id) static int count_cpu(void) {
- u32 apic_id; CountCPUs++;
- // Track found apic id for use in legacy internal bios tables u32 eax, ebx, ecx, cpuid_features; cpuid(1, &eax, &ebx, &ecx, &cpuid_features);
- u8 apic_id = ebx>>24;
- FoundAPICIDs[apic_id/32] |= 1 << (apic_id % 32);
apic_id = ebx>>24;
if (MaxCountCPUs < 256) { // xAPIC mode
// Track found apic id for use in legacy internal bios tables
FoundAPICIDs[apic_id/32] |= 1 << (apic_id % 32);
}
if (rdmsr(MSR_IA32_APIC_BASE) & MSR_IA32_APICBASE_EXTD) { // x2APIC mode
apic_id = rdmsr(MSR_LOCAL_APIC_ID);
}
return apic_id;
}
+static void +handle_x2apic(void) +{
- if (MaxCountCPUs < 256)
return;
- u32 eax, ebx, ecx, edx;
- cpuid(1, &eax, &ebx, &ecx, &edx);
- if (!(ecx & CPUID_X2APIC))
return;
- // switch to x2APIC mode
- u64 apic_base = rdmsr(MSR_IA32_APIC_BASE);
- wrmsr(MSR_IA32_APIC_BASE, apic_base | MSR_IA32_APICBASE_EXTD);
+}
Can we integrate handle_x2apic() into count_cpu() as in:
static int count_cpu(void) { CountCPUs++;
u32 eax, ebx, ecx, cpuid_features; cpuid(1, &eax, &ebx, &ecx, &cpuid_features); if (MaxCountCPUs < 256) { // xAPIC mode // Track found apic id for use in legacy internal bios tables FoundAPICIDs[apic_id/32] |= 1 << (apic_id % 32); return ebx>>24; }
// x2APIC mode if (!(ecx & CPUID_X2APIC)) return -1; u64 apic_base = rdmsr(MSR_IA32_APIC_BASE); wrmsr(MSR_IA32_APIC_BASE, apic_base | MSR_IA32_APICBASE_EXTD); return rdmsr(MSR_LOCAL_APIC_ID); }
count_cpu may be a poor choice of name, but if we could put all the apic stuff in one function and call it from both handle_smp() and smp_setup() I think it would make the code a little easier to understand.
-Kevin
On Tue, 10 May 2016 11:20:54 -0400 "Kevin O'Connor" kevin@koconnor.net wrote:
On Tue, May 10, 2016 at 04:43:33PM +0200, Igor Mammedov wrote:
SDM[*1] says that if there are CPUs with APIC ID greater than 254, BIOS is to pass control to OS in x2APIC mode. Use the fact that QEMU passes in "etc/max-cpus" max possible "APIC ID + 1" to detect need for x2APIC mode. Also instead of CMOS_BIOS_SMP_COUNT which is limited to 256 CPUs use a new rom file "etc/boot-cpus" that QEMU supporting more than 256 CPUs will provide.
*1) SDM: Volume 3: EXTENDED XAPIC (X2APIC): Initialization by System Software
Signed-off-by: Igor Mammedov imammedo@redhat.com
src/fw/smp.c | 40 ++++++++++++++++++++++++++++++++++------ src/x86.h | 1 + 2 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/src/fw/smp.c b/src/fw/smp.c index ad98a5f..18a4c77 100644 --- a/src/fw/smp.c +++ b/src/fw/smp.c @@ -19,6 +19,9 @@ #define APIC_LINT1 ((u8*)BUILD_APIC_ADDR + 0x360)
#define APIC_ENABLED 0x0100 +#define MSR_IA32_APIC_BASE 0x01B +#define MSR_LOCAL_APIC_ID 0x802 +#define MSR_IA32_APICBASE_EXTD (1ULL << 10) /* Enable x2APIC mode */
static struct { u32 index; u64 val; } smp_mtrr[32]; static u32 smp_mtrr_count; @@ -49,23 +52,46 @@ int apic_id_is_present(u8 apic_id) static int count_cpu(void) {
- u32 apic_id; CountCPUs++;
- // Track found apic id for use in legacy internal bios tables u32 eax, ebx, ecx, cpuid_features; cpuid(1, &eax, &ebx, &ecx, &cpuid_features);
- u8 apic_id = ebx>>24;
- FoundAPICIDs[apic_id/32] |= 1 << (apic_id % 32);
apic_id = ebx>>24;
if (MaxCountCPUs < 256) { // xAPIC mode
// Track found apic id for use in legacy internal bios tables
FoundAPICIDs[apic_id/32] |= 1 << (apic_id % 32);
}
if (rdmsr(MSR_IA32_APIC_BASE) & MSR_IA32_APICBASE_EXTD) { // x2APIC mode
apic_id = rdmsr(MSR_LOCAL_APIC_ID);
}
return apic_id;
}
+static void +handle_x2apic(void) +{
- if (MaxCountCPUs < 256)
return;
- u32 eax, ebx, ecx, edx;
- cpuid(1, &eax, &ebx, &ecx, &edx);
- if (!(ecx & CPUID_X2APIC))
return;
- // switch to x2APIC mode
- u64 apic_base = rdmsr(MSR_IA32_APIC_BASE);
- wrmsr(MSR_IA32_APIC_BASE, apic_base | MSR_IA32_APICBASE_EXTD);
+}
Can we integrate handle_x2apic() into count_cpu() as in:
static int count_cpu(void) { CountCPUs++;
u32 eax, ebx, ecx, cpuid_features; cpuid(1, &eax, &ebx, &ecx, &cpuid_features); if (MaxCountCPUs < 256) { // xAPIC mode // Track found apic id for use in legacy internal bios tables FoundAPICIDs[apic_id/32] |= 1 << (apic_id % 32); return ebx>>24; } // x2APIC mode if (!(ecx & CPUID_X2APIC)) return -1; u64 apic_base = rdmsr(MSR_IA32_APIC_BASE); wrmsr(MSR_IA32_APIC_BASE, apic_base | MSR_IA32_APICBASE_EXTD); return rdmsr(MSR_LOCAL_APIC_ID);
}
count_cpu may be a poor choice of name, but if we could put all the apic stuff in one function and call it from both handle_smp() and smp_setup() I think it would make the code a little easier to understand.
sure
perhaps 's/count_cpu/apic_id_init/'
-Kevin
On Tue, May 10, 2016 at 05:31:33PM +0200, Igor Mammedov wrote:
On Tue, 10 May 2016 11:20:54 -0400 "Kevin O'Connor" kevin@koconnor.net wrote:
On Tue, May 10, 2016 at 04:43:33PM +0200, Igor Mammedov wrote:
SDM[*1] says that if there are CPUs with APIC ID greater than 254, BIOS is to pass control to OS in x2APIC mode. Use the fact that QEMU passes in "etc/max-cpus" max possible "APIC ID + 1" to detect need for x2APIC mode. Also instead of CMOS_BIOS_SMP_COUNT which is limited to 256 CPUs use a new rom file "etc/boot-cpus" that QEMU supporting more than 256 CPUs will provide.
*1) SDM: Volume 3: EXTENDED XAPIC (X2APIC): Initialization by System Software
Signed-off-by: Igor Mammedov imammedo@redhat.com
src/fw/smp.c | 40 ++++++++++++++++++++++++++++++++++------ src/x86.h | 1 + 2 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/src/fw/smp.c b/src/fw/smp.c index ad98a5f..18a4c77 100644 --- a/src/fw/smp.c +++ b/src/fw/smp.c @@ -19,6 +19,9 @@ #define APIC_LINT1 ((u8*)BUILD_APIC_ADDR + 0x360)
#define APIC_ENABLED 0x0100 +#define MSR_IA32_APIC_BASE 0x01B +#define MSR_LOCAL_APIC_ID 0x802 +#define MSR_IA32_APICBASE_EXTD (1ULL << 10) /* Enable x2APIC mode */
static struct { u32 index; u64 val; } smp_mtrr[32]; static u32 smp_mtrr_count; @@ -49,23 +52,46 @@ int apic_id_is_present(u8 apic_id) static int count_cpu(void) {
- u32 apic_id; CountCPUs++;
- // Track found apic id for use in legacy internal bios tables u32 eax, ebx, ecx, cpuid_features; cpuid(1, &eax, &ebx, &ecx, &cpuid_features);
- u8 apic_id = ebx>>24;
- FoundAPICIDs[apic_id/32] |= 1 << (apic_id % 32);
apic_id = ebx>>24;
if (MaxCountCPUs < 256) { // xAPIC mode
// Track found apic id for use in legacy internal bios tables
FoundAPICIDs[apic_id/32] |= 1 << (apic_id % 32);
}
if (rdmsr(MSR_IA32_APIC_BASE) & MSR_IA32_APICBASE_EXTD) { // x2APIC mode
apic_id = rdmsr(MSR_LOCAL_APIC_ID);
}
return apic_id;
}
+static void +handle_x2apic(void) +{
- if (MaxCountCPUs < 256)
return;
- u32 eax, ebx, ecx, edx;
- cpuid(1, &eax, &ebx, &ecx, &edx);
- if (!(ecx & CPUID_X2APIC))
return;
- // switch to x2APIC mode
- u64 apic_base = rdmsr(MSR_IA32_APIC_BASE);
- wrmsr(MSR_IA32_APIC_BASE, apic_base | MSR_IA32_APICBASE_EXTD);
+}
Can we integrate handle_x2apic() into count_cpu() as in:
static int count_cpu(void) { CountCPUs++;
u32 eax, ebx, ecx, cpuid_features; cpuid(1, &eax, &ebx, &ecx, &cpuid_features); if (MaxCountCPUs < 256) { // xAPIC mode // Track found apic id for use in legacy internal bios tables FoundAPICIDs[apic_id/32] |= 1 << (apic_id % 32); return ebx>>24; } // x2APIC mode if (!(ecx & CPUID_X2APIC)) return -1; u64 apic_base = rdmsr(MSR_IA32_APIC_BASE); wrmsr(MSR_IA32_APIC_BASE, apic_base | MSR_IA32_APICBASE_EXTD); return rdmsr(MSR_LOCAL_APIC_ID);
}
count_cpu may be a poor choice of name, but if we could put all the apic stuff in one function and call it from both handle_smp() and smp_setup() I think it would make the code a little easier to understand.
sure
perhaps 's/count_cpu/apic_id_init/'
Great. Thanks. -Kevin
MaxCountCPUs could never be 0 or less CountCPUs anymore, remove code that wouldn't be executed.
Signed-off-by: Igor Mammedov imammedo@redhat.com --- src/fw/smp.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/src/fw/smp.c b/src/fw/smp.c index 18a4c77..4d82502 100644 --- a/src/fw/smp.c +++ b/src/fw/smp.c @@ -175,8 +175,6 @@ smp_setup(void) *(u64*)BUILD_AP_BOOT_ADDR = old;
handle_x2apic(); - if (!MaxCountCPUs || MaxCountCPUs < CountCPUs) - MaxCountCPUs = CountCPUs;
dprintf(1, "Found %d cpu(s) max supported %d cpu(s)\n", CountCPUs, MaxCountCPUs);
On Tue, 10 May 2016 16:43:34 +0200 Igor Mammedov imammedo@redhat.com wrote:
MaxCountCPUs could never be 0 or less CountCPUs anymore, remove code that wouldn't be executed.
Signed-off-by: Igor Mammedov imammedo@redhat.com
src/fw/smp.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/src/fw/smp.c b/src/fw/smp.c index 18a4c77..4d82502 100644 --- a/src/fw/smp.c +++ b/src/fw/smp.c @@ -175,8 +175,6 @@ smp_setup(void) *(u64*)BUILD_AP_BOOT_ADDR = old;
Also looking at usage of BUILD_AP_BOOT_ADDR, it doesn't seem to user anywhere beside of smp_setup() and smp_setup every time overwrites it to point to entry_smp trampoline So saving/restoring 'old' value doesn't look like necessary, should it be cleaned up as well?
handle_x2apic();
if (!MaxCountCPUs || MaxCountCPUs < CountCPUs)
MaxCountCPUs = CountCPUs;
dprintf(1, "Found %d cpu(s) max supported %d cpu(s)\n", CountCPUs, MaxCountCPUs);
On Wed, May 11, 2016 at 11:50:36AM +0200, Igor Mammedov wrote:
On Tue, 10 May 2016 16:43:34 +0200 Igor Mammedov imammedo@redhat.com wrote:
MaxCountCPUs could never be 0 or less CountCPUs anymore, remove code that wouldn't be executed.
Signed-off-by: Igor Mammedov imammedo@redhat.com
src/fw/smp.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/src/fw/smp.c b/src/fw/smp.c index 18a4c77..4d82502 100644 --- a/src/fw/smp.c +++ b/src/fw/smp.c @@ -175,8 +175,6 @@ smp_setup(void) *(u64*)BUILD_AP_BOOT_ADDR = old;
Also looking at usage of BUILD_AP_BOOT_ADDR, it doesn't seem to user anywhere beside of smp_setup() and smp_setup every time overwrites it to point to entry_smp trampoline So saving/restoring 'old' value doesn't look like necessary, should it be cleaned up as well?
That's in there because technically malloc_tmplow() could give out that address range (see alloc_add(&ZoneTmpLow) in malloc_preinit). So, the idea is to save/restore the area so that the trampoline doesn't alter anything stored there. In practice nothing that early in the boot would use enough malloc_tmplow space to give out that address, but it doesn't hurt to save/restore either.
handle_x2apic();
- if (!MaxCountCPUs || MaxCountCPUs < CountCPUs)
MaxCountCPUs = CountCPUs;
BTW, the "MaxCountCPUs < CountCPUs" check was in there for really old versions of QEMU that didn't populate "etc/max-cpus". Unless you're sure that "etc/max-cpus" predates CMOS_BIOS_SMP_COUNT, I'd be inclined to leave the check in there. (No need to resend the series if not sure).
-Kevin
On Wed, 11 May 2016 10:08:11 -0400 "Kevin O'Connor" kevin@koconnor.net wrote:
On Wed, May 11, 2016 at 11:50:36AM +0200, Igor Mammedov wrote:
On Tue, 10 May 2016 16:43:34 +0200 Igor Mammedov imammedo@redhat.com wrote:
MaxCountCPUs could never be 0 or less CountCPUs anymore, remove code that wouldn't be executed.
Signed-off-by: Igor Mammedov imammedo@redhat.com
src/fw/smp.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/src/fw/smp.c b/src/fw/smp.c index 18a4c77..4d82502 100644 --- a/src/fw/smp.c +++ b/src/fw/smp.c @@ -175,8 +175,6 @@ smp_setup(void)
[...]
handle_x2apic();
- if (!MaxCountCPUs || MaxCountCPUs < CountCPUs)
MaxCountCPUs = CountCPUs;
BTW, the "MaxCountCPUs < CountCPUs" check was in there for really old versions of QEMU that didn't populate "etc/max-cpus". Unless you're sure that "etc/max-cpus" predates CMOS_BIOS_SMP_COUNT, I'd be inclined to leave the check in there. (No need to resend the series if not sure).
yep, taking in account that, only '!MaxCountCPUs ||' should be removed as since 3/4 MaxCountCPUs is always >= 1. I can just post only 1 v3 patch as reply to v2_4/4
-Kevin
On Tue, 10 May 2016 16:43:30 +0200 Igor Mammedov imammedo@redhat.com wrote:
Probably question to Kevin, I've tried to make AP bootstrap run in parallel to speed up smp_setup with many CPUs. However it hangs and I couldn't debug it. Debugging works fine in 16bit mode as described in wiki but from the point when entry_smp() switches to 32bit mode I don't know how to/where/where from load symbols for 32-bit code, even 'disassemble $ip,+xxx' in gdb doesn't work as expected. Perhaps the debugging section in wiki needs to be updated to show how to debug seabios when it's in 32 mode.
Changelog: since RFC: * move out max-cpus check out of mptable_setup() * factor out CPU counting/apic ID detection in separate function * return back accidentially deleted debug message with APIC ID * drop unused code in smp_setup()
According to SDM, if CPUs have APIC ID more than 254 firmware should pass control to OS in x2APIC mode. This series adds x2APIC bootstrap initialization.
QEMU side of x2APIC support: https://lists.gnu.org/archive/html/qemu-devel/2016-05/msg01094.html
Igor Mammedov (3): paravirt: disable legacy bios tables in case of more than 255 CPUs support booting with more than 255 CPUs cleanup smp_setup()
Kevin O'Connor (1): smp: refactor present CPU APIC ID detection and counting
src/fw/paravirt.c | 6 +++-- src/fw/smp.c | 67 ++++++++++++++++++++++++++++++++++++++++--------------- src/x86.h | 1 + 3 files changed, 54 insertions(+), 20 deletions(-)
On Wed, May 11, 2016 at 12:02:40PM +0200, Igor Mammedov wrote:
On Tue, 10 May 2016 16:43:30 +0200 Igor Mammedov imammedo@redhat.com wrote:
Probably question to Kevin, I've tried to make AP bootstrap run in parallel to speed up smp_setup with many CPUs. However it hangs and I couldn't debug it. Debugging works fine in 16bit mode as described in wiki but from the point when entry_smp() switches to 32bit mode I don't know how to/where/where from load symbols for 32-bit code, even 'disassemble $ip,+xxx' in gdb doesn't work as expected. Perhaps the debugging section in wiki needs to be updated to show how to debug seabios when it's in 32 mode.
Did you disable CONFIG_RELOCATE_INIT as described in the wiki? (The smp.c code is considered part of the "init" portion of SeaBIOS.) Otherwise, the addresses should just work in 32bit mode.
As for threading the smp init - the code currently takes an atomic lock to control access to a shared stack. That would need to change in order to support simultaneous smp init. Also note that the core code, such as dprintf, doesn't support true smp multi-threading.
-Kevin