From d417d26ce8e1ac89946669c952c04f37a5b813cb Mon Sep 17 00:00:00 2001 From: Sebastian Sumpf Date: Fri, 24 May 2019 14:40:24 +0200 Subject: [PATCH] hw: fix calculation of CPU count on x86_64 On x86 the CPU count is determined through ACPI's MADT by counting the local APICs reported there. Some platforms report more APICs than there are actual CPUs. These might be physically disabled CPUs. Therefore, a check if the LAPIC is actually physically enabled in hardware fixes this issue. Thanks to Alex Boettcher fixes #3376 --- repos/base-hw/src/bootstrap/spec/x86_64/platform.cc | 10 ++++++++-- repos/base-hw/src/include/hw/spec/x86_64/acpi.h | 4 +++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/repos/base-hw/src/bootstrap/spec/x86_64/platform.cc b/repos/base-hw/src/bootstrap/spec/x86_64/platform.cc index 9022906652..fbc2553b5d 100644 --- a/repos/base-hw/src/bootstrap/spec/x86_64/platform.cc +++ b/repos/base-hw/src/bootstrap/spec/x86_64/platform.cc @@ -175,7 +175,10 @@ Bootstrap::Platform::Board::Board() Hw::for_each_apic_struct(*table,[&](Hw::Apic_madt const *e){ if (e->type == Hw::Apic_madt::LAPIC) { Hw::Apic_madt::Lapic lapic(e); - cpus ++; + + /* check if APIC is enabled in hardware */ + if (lapic.valid()) + cpus ++; } }); }); @@ -190,7 +193,10 @@ Bootstrap::Platform::Board::Board() Hw::for_each_apic_struct(*table,[&](Hw::Apic_madt const *e){ if (e->type == Hw::Apic_madt::LAPIC) { Hw::Apic_madt::Lapic lapic(e); - cpus ++; + + /* check if APIC is enabled in hardware */ + if (lapic.valid()) + cpus ++; } }); }); diff --git a/repos/base-hw/src/include/hw/spec/x86_64/acpi.h b/repos/base-hw/src/include/hw/spec/x86_64/acpi.h index 5682aafa6f..e1b78e7329 100644 --- a/repos/base-hw/src/include/hw/spec/x86_64/acpi.h +++ b/repos/base-hw/src/include/hw/spec/x86_64/acpi.h @@ -65,9 +65,11 @@ struct Hw::Apic_madt struct Lapic : Genode::Mmio { - struct Flags : Register <0x04, 32> { enum { ENABLED = 1 }; }; + struct Flags : Register <0x04, 32> { enum { VALID = 1 }; }; Lapic(Apic_madt const * a) : Mmio(reinterpret_cast(a)) { } + + bool valid() { return read() & Flags::VALID; }; }; } __attribute__((packed));