Signed-off-by: Igor Mammedov imammedo@redhat.com --- src/fw/paravirt.h | 3 +++ src/fw/paravirt.c | 38 ++++++++++++++++++++++++++++++++++++++ src/fw/smp.c | 11 ++++++----- 3 files changed, 47 insertions(+), 5 deletions(-)
diff --git a/src/fw/paravirt.h b/src/fw/paravirt.h index ed8e5f1..6f26fd0 100644 --- a/src/fw/paravirt.h +++ b/src/fw/paravirt.h @@ -52,4 +52,7 @@ void qemu_preinit(void); void qemu_platform_setup(void); void qemu_cfg_init(void);
+u16 qemu_init_present_cpus_count(void); +u16 qemu_get_present_cpus_count(void); + #endif diff --git a/src/fw/paravirt.c b/src/fw/paravirt.c index 33a471b..125066d 100644 --- a/src/fw/paravirt.c +++ b/src/fw/paravirt.c @@ -319,6 +319,44 @@ qemu_romfile_add(char *name, int select, int skip, int size) romfile_add(&qfile->file); }
+static int +qemu_romfile_get_fwcfg_entry(char *name, int *select) +{ + struct romfile_s *file = romfile_find(name); + if (!file) + return 0; + struct qemu_romfile_s *qfile; + qfile = container_of(file, struct qemu_romfile_s, file); + if (select) + *select = qfile->select; + return file->size; +} + +static int boot_cpus_sel; +static int boot_cpus_file_sz; + +u16 +qemu_init_present_cpus_count(void) +{ + u16 smp_count = romfile_loadint("etc/boot-cpus", + rtc_read(CMOS_BIOS_SMP_COUNT) + 1); + boot_cpus_file_sz = + qemu_romfile_get_fwcfg_entry("etc/boot-cpus", &boot_cpus_sel); + return smp_count; +} + +u16 +qemu_get_present_cpus_count(void) +{ + u16 smp_count; + if (!boot_cpus_file_sz) { + smp_count = rtc_read(CMOS_BIOS_SMP_COUNT) + 1; + } else { + qemu_cfg_read_entry(&smp_count, boot_cpus_sel, boot_cpus_file_sz); + } + return smp_count; +} + struct e820_reservation { u64 address; u64 length; diff --git a/src/fw/smp.c b/src/fw/smp.c index 31bcc6a..9c404b9 100644 --- a/src/fw/smp.c +++ b/src/fw/smp.c @@ -12,6 +12,7 @@ #include "stacks.h" // yield #include "util.h" // smp_setup, msr_feature_control_setup #include "x86.h" // wrmsr +#include "paravirt.h" // qemu_*_present_cpus_count
#define APIC_ICR_LOW ((u8*)BUILD_APIC_ADDR + 0x300) #define APIC_SVR ((u8*)BUILD_APIC_ADDR + 0x0F0) @@ -131,8 +132,8 @@ smp_scan(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 expected_cpus_count = qemu_get_present_cpus_count(); + while (expected_cpus_count != CountCPUs) asm volatile( // Release lock and allow other processors to use the stack. " movl %%esp, %1\n" @@ -159,9 +160,9 @@ smp_setup(void) 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; + u16 smp_count = qemu_init_present_cpus_count(); + if (MaxCountCPUs < smp_count) + MaxCountCPUs = smp_count;
smp_scan(); }