[RFC 1/2] x86/e820: Map EFI_MEMORY_MAPPED_IO to a new E820_TYPE_MMIO type

From: Hans de Goede
Date: Mon Feb 14 2022 - 10:18:34 EST


Map EFI_MEMORY_MAPPED_IO to a new E820_TYPE_MMIO type. The EFI memory-map
has a special type for Memory Mapped IO, add a new E820_TYPE_MMIO type and
when translating the EFI memory-map to an e820_table map
EFI_MEMORY_MAPPED_IO to this new E820_TYPE_MMIO type.

This is a preparation patch for making arch_remove_reservations() treat
EFI_MEMORY_MAPPED_IO ranges differently then other reserved ranged.

All users of E820_TYPE_* have been audited and modified where necessary
so that this patch should not introduce any functional changes.

Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx>
---
arch/x86/include/asm/e820/types.h | 3 +++
arch/x86/include/asm/iommu.h | 3 ++-
arch/x86/kernel/e820.c | 5 +++++
arch/x86/mm/ioremap.c | 1 +
arch/x86/pci/mmconfig-shared.c | 15 +++++++++++----
arch/x86/platform/efi/efi.c | 5 ++++-
drivers/firmware/efi/libstub/x86-stub.c | 5 ++++-
7 files changed, 30 insertions(+), 7 deletions(-)

diff --git a/arch/x86/include/asm/e820/types.h b/arch/x86/include/asm/e820/types.h
index 314f75d886d0..d91d4d28fe50 100644
--- a/arch/x86/include/asm/e820/types.h
+++ b/arch/x86/include/asm/e820/types.h
@@ -44,6 +44,9 @@ enum e820_type {
* might alter over the S3 transition:
*/
E820_TYPE_RESERVED_KERN = 128,
+
+ /* Used for EFI_MEMORY_MAPPED_IO when translating the EFI memmap */
+ E820_TYPE_MMIO = 129,
};

/*
diff --git a/arch/x86/include/asm/iommu.h b/arch/x86/include/asm/iommu.h
index bf1ed2ddc74b..ed7329137fef 100644
--- a/arch/x86/include/asm/iommu.h
+++ b/arch/x86/include/asm/iommu.h
@@ -18,7 +18,8 @@ arch_rmrr_sanity_check(struct acpi_dmar_reserved_memory *rmrr)
u64 start = rmrr->base_address;
u64 end = rmrr->end_address + 1;

- if (e820__mapped_all(start, end, E820_TYPE_RESERVED))
+ if (e820__mapped_all(start, end, E820_TYPE_RESERVED) ||
+ e820__mapped_all(start, end, E820_TYPE_MMIO))
return 0;

pr_err(FW_BUG "No firmware reserved region can cover this RMRR [%#018Lx-%#018Lx], contact BIOS vendor for fixes\n",
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index bc0657f0deed..5fbd2505b10e 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -196,6 +196,7 @@ static void __init e820_print_type(enum e820_type type)
case E820_TYPE_UNUSABLE: pr_cont("unusable"); break;
case E820_TYPE_PMEM: /* Fall through: */
case E820_TYPE_PRAM: pr_cont("persistent (type %u)", type); break;
+ case E820_TYPE_MMIO: pr_cont("MMIO"); break;
default: pr_cont("type %u", type); break;
}
}
@@ -1064,6 +1065,7 @@ static const char *__init e820_type_to_string(struct e820_entry *entry)
case E820_TYPE_PMEM: return "Persistent Memory";
case E820_TYPE_RESERVED: return "Reserved";
case E820_TYPE_SOFT_RESERVED: return "Soft Reserved";
+ case E820_TYPE_MMIO: return "Memory Mapped IO";
default: return "Unknown E820 type";
}
}
@@ -1080,6 +1082,7 @@ static unsigned long __init e820_type_to_iomem_type(struct e820_entry *entry)
case E820_TYPE_PMEM: /* Fall-through: */
case E820_TYPE_RESERVED: /* Fall-through: */
case E820_TYPE_SOFT_RESERVED: /* Fall-through: */
+ case E820_TYPE_MMIO: /* Fall-through: */
default: return IORESOURCE_MEM;
}
}
@@ -1091,6 +1094,7 @@ static unsigned long __init e820_type_to_iores_desc(struct e820_entry *entry)
case E820_TYPE_NVS: return IORES_DESC_ACPI_NV_STORAGE;
case E820_TYPE_PMEM: return IORES_DESC_PERSISTENT_MEMORY;
case E820_TYPE_PRAM: return IORES_DESC_PERSISTENT_MEMORY_LEGACY;
+ case E820_TYPE_MMIO: /* Fall-through: */
case E820_TYPE_RESERVED: return IORES_DESC_RESERVED;
case E820_TYPE_SOFT_RESERVED: return IORES_DESC_SOFT_RESERVED;
case E820_TYPE_RESERVED_KERN: /* Fall-through: */
@@ -1113,6 +1117,7 @@ static bool __init do_mark_busy(enum e820_type type, struct resource *res)
switch (type) {
case E820_TYPE_RESERVED:
case E820_TYPE_SOFT_RESERVED:
+ case E820_TYPE_MMIO:
case E820_TYPE_PRAM:
case E820_TYPE_PMEM:
return false;
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 026031b3b782..7987e9c899fa 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -552,6 +552,7 @@ static bool memremap_should_map_decrypted(resource_size_t phys_addr,
/* Check if the address is outside kernel usable area */
switch (e820__get_entry_type(phys_addr, phys_addr + size - 1)) {
case E820_TYPE_RESERVED:
+ case E820_TYPE_MMIO:
case E820_TYPE_ACPI:
case E820_TYPE_NVS:
case E820_TYPE_UNUSABLE:
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 758cbfe55daa..3c19353bae10 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -425,7 +425,7 @@ static acpi_status find_mboard_resource(acpi_handle handle, u32 lvl,
return AE_OK;
}

-static bool is_acpi_reserved(u64 start, u64 end, enum e820_type not_used)
+static bool is_acpi_reserved(u64 start, u64 end)
{
struct resource mcfg_res;

@@ -442,7 +442,14 @@ static bool is_acpi_reserved(u64 start, u64 end, enum e820_type not_used)
return mcfg_res.flags;
}

-typedef bool (*check_reserved_t)(u64 start, u64 end, enum e820_type type);
+static bool is_e820_reserved(u64 start, u64 end)
+{
+ int type = e820__get_entry_type(start, end);
+
+ return type == E820_TYPE_RESERVED || type == E820_TYPE_MMIO;
+}
+
+typedef bool (*check_reserved_t)(u64 start, u64 end);

static bool __ref is_mmconf_reserved(check_reserved_t is_reserved,
struct pci_mmcfg_region *cfg,
@@ -454,7 +461,7 @@ static bool __ref is_mmconf_reserved(check_reserved_t is_reserved,
int num_buses;
char *method = with_e820 ? "E820" : "ACPI motherboard resources";

- while (!is_reserved(addr, addr + size, E820_TYPE_RESERVED)) {
+ while (!is_reserved(addr, addr + size)) {
size >>= 1;
if (size < (16UL<<20))
break;
@@ -527,7 +534,7 @@ pci_mmcfg_check_reserved(struct device *dev, struct pci_mmcfg_region *cfg, int e
/* Don't try to do this check unless configuration
type 1 is available. how about type 2 ?*/
if (raw_pci_ops)
- return is_mmconf_reserved(e820__mapped_all, cfg, dev, 1);
+ return is_mmconf_reserved(is_e820_reserved, cfg, dev, 1);

return false;
}
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 147c30a81f15..23b361447417 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -173,10 +173,13 @@ static void __init do_add_efi_memmap(void)
case EFI_PERSISTENT_MEMORY:
e820_type = E820_TYPE_PMEM;
break;
+ case EFI_MEMORY_MAPPED_IO:
+ e820_type = E820_TYPE_MMIO;
+ break;
default:
/*
* EFI_RESERVED_TYPE EFI_RUNTIME_SERVICES_CODE
- * EFI_RUNTIME_SERVICES_DATA EFI_MEMORY_MAPPED_IO
+ * EFI_RUNTIME_SERVICES_DATA
* EFI_MEMORY_MAPPED_IO_PORT_SPACE EFI_PAL_CODE
*/
e820_type = E820_TYPE_RESERVED;
diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c
index 01ddd4502e28..d0795adc2534 100644
--- a/drivers/firmware/efi/libstub/x86-stub.c
+++ b/drivers/firmware/efi/libstub/x86-stub.c
@@ -470,12 +470,15 @@ setup_e820(struct boot_params *params, struct setup_data *e820ext, u32 e820ext_s
case EFI_RESERVED_TYPE:
case EFI_RUNTIME_SERVICES_CODE:
case EFI_RUNTIME_SERVICES_DATA:
- case EFI_MEMORY_MAPPED_IO:
case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
case EFI_PAL_CODE:
e820_type = E820_TYPE_RESERVED;
break;

+ case EFI_MEMORY_MAPPED_IO:
+ e820_type = E820_TYPE_MMIO;
+ break;
+
case EFI_UNUSABLE_MEMORY:
e820_type = E820_TYPE_UNUSABLE;
break;
--
2.33.1