@@ -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,
};
/*
@@ -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",
@@ -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;
@@ -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:
@@ -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;
}
@@ -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;
@@ -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;
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@redhat.com> --- 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(-)