It's not clear this is needed - Linux doesn't use the MPS table even if available, and no system having one was seen so far. Signed-off-by: Jan Beulich --- a/xen/arch/x86/efi/boot.c +++ b/xen/arch/x86/efi/boot.c @@ -897,12 +897,15 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SY { static EFI_GUID __initdata acpi2_guid = ACPI_20_TABLE_GUID; static EFI_GUID __initdata acpi_guid = ACPI_TABLE_GUID; + static EFI_GUID __initdata mps_guid = MPS_TABLE_GUID; static EFI_GUID __initdata smbios_guid = SMBIOS_TABLE_GUID; if ( match_guid(&acpi2_guid, &efi_ct[i].VendorGuid) ) efi.acpi20 = (long)efi_ct[i].VendorTable; if ( match_guid(&acpi_guid, &efi_ct[i].VendorGuid) ) efi.acpi = (long)efi_ct[i].VendorTable; + if ( match_guid(&mps_guid, &efi_ct[i].VendorGuid) ) + efi.mps = (long)efi_ct[i].VendorTable; if ( match_guid(&smbios_guid, &efi_ct[i].VendorGuid) ) efi.smbios = (long)efi_ct[i].VendorTable; } --- a/xen/arch/x86/efi/runtime.c +++ b/xen/arch/x86/efi/runtime.c @@ -29,6 +29,7 @@ void *__read_mostly efi_memmap; struct efi __read_mostly efi = { .acpi = EFI_INVALID_TABLE_ADDR, .acpi20 = EFI_INVALID_TABLE_ADDR, + .mps = EFI_INVALID_TABLE_ADDR, .smbios = EFI_INVALID_TABLE_ADDR, }; --- a/xen/arch/x86/mpparse.c +++ b/xen/arch/x86/mpparse.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -514,6 +515,14 @@ static inline void __init construct_defa } } +#define FIX_EFI_MPF FIX_KEXEC_BASE_0 + +static __init void efi_unmap_mpf(void) +{ + if (efi_enabled) + __set_fixmap(FIX_EFI_MPF, 0, 0); +} + static struct intel_mp_floating *__initdata mpf_found; /* @@ -528,6 +537,7 @@ void __init get_smp_config (void) * processors, where MPS only supports physical. */ if (acpi_lapic && acpi_ioapic) { + efi_unmap_mpf(); printk(KERN_INFO "Using ACPI (MADT) for SMP configuration information\n"); return; } @@ -558,6 +568,7 @@ void __init get_smp_config (void) * override the defaults. */ if (!smp_read_mpc((void *)(unsigned long)mpf->mpf_physptr)) { + efi_unmap_mpf(); smp_found_config = 0; printk(KERN_ERR "BIOS bug, MP table errors detected!...\n"); printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n"); @@ -584,6 +595,8 @@ void __init get_smp_config (void) } else BUG(); + efi_unmap_mpf(); + printk(KERN_INFO "Processors: %d\n", num_processors); /* * Only use the first configuration found. @@ -638,10 +651,37 @@ static int __init smp_scan_config (unsig return 0; } +static void __init efi_check_config(void) +{ + struct intel_mp_floating *mpf; + + if (efi.mps == EFI_INVALID_TABLE_ADDR) + return; + + __set_fixmap(FIX_EFI_MPF, PFN_DOWN(efi.mps), __PAGE_HYPERVISOR); + mpf = (void *)fix_to_virt(FIX_EFI_MPF) + ((long)efi.mps & (PAGE_SIZE-1)); + + if (memcmp(mpf->mpf_signature, "_MP_", 4) == 0 && + mpf->mpf_length == 1 && + mpf_checksum((void *)mpf, 16) && + (mpf->mpf_specification == 1 || mpf->mpf_specification == 4)) { + smp_found_config = 1; + printk(KERN_INFO "SMP MP-table at %08"PRIx64"\n", efi.mps); + mpf_found = mpf; + } + else + efi_unmap_mpf(); +} + void __init find_smp_config (void) { unsigned int address; + if (efi_enabled) { + efi_check_config(); + return; + } + /* * FIXME: Linux assumes you have 640K of base ram.. * this continues the error... --- a/xen/include/xen/efi.h +++ b/xen/include/xen/efi.h @@ -17,6 +17,7 @@ extern const bool_t efi_enabled; /* Add fields here only if they need to be referenced from non-EFI code. */ struct efi { + unsigned long mps; /* MPS table */ unsigned long acpi; /* ACPI table (IA64 ext 0.71) */ unsigned long acpi20; /* ACPI table (ACPI 2.0) */ unsigned long smbios; /* SM BIOS table */