@@ -564,6 +564,13 @@ static __init int match_config_table(const efi_guid_t *guid,
for (i = 0; efi_guidcmp(table_types[i].guid, NULL_GUID); i++) {
if (!efi_guidcmp(*guid, table_types[i].guid)) {
+ if (IS_ENABLED(CONFIG_XEN_EFI) &&
+ !xen_efi_config_table_is_usable(guid, table)) {
+ if (table_types[i].name[0])
+ pr_cont("(%s=0x%lx) may have been clobbered by Xen ",
+ table_types[i].name, table);
+ return 1;
+ }
*(table_types[i].ptr) = table;
if (table_types[i].name[0])
pr_cont("%s=0x%lx ",
@@ -328,3 +328,28 @@ int efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md)
return 0;
}
+
+bool __init xen_efi_config_table_is_usable(const efi_guid_t *guid,
+ unsigned long table)
+{
+ efi_memory_desc_t md;
+ int rc;
+
+ if (!efi_enabled(EFI_PARAVIRT))
+ return true;
+
+ rc = efi_mem_desc_lookup(table, &md);
+ if (rc)
+ return false;
+
+ switch (md.type) {
+ case EFI_RUNTIME_SERVICES_CODE:
+ case EFI_RUNTIME_SERVICES_DATA:
+ case EFI_ACPI_RECLAIM_MEMORY:
+ case EFI_ACPI_MEMORY_NVS:
+ case EFI_RESERVED_TYPE:
+ return true;
+ default:
+ return false;
+ }
+}
@@ -1322,4 +1322,6 @@ struct linux_efi_coco_secret_area {
/* Header of a populated EFI secret area */
#define EFI_SECRET_TABLE_HEADER_GUID EFI_GUID(0x1e74f542, 0x71dd, 0x4d66, 0x96, 0x3e, 0xef, 0x42, 0x87, 0xff, 0x17, 0x3b)
+bool xen_efi_config_table_is_usable(const efi_guid_t *guid, unsigned long table);
+
#endif /* _LINUX_EFI_H */