Skip to content

Commit a509a66

Browse files
ardbiesheuvelctmarinas
authored andcommitted
arm64: permit ACPI core to map kernel memory used for table overrides
Jonathan reports that the strict policy for memory mapped by the ACPI core breaks the use case of passing ACPI table overrides via initramfs. This is due to the fact that the memory type used for loading the initramfs in memory is not recognized as a memory type that is typically used by firmware to pass firmware tables. Since the purpose of the strict policy is to ensure that no AML or other ACPI code can manipulate any memory that is used by the kernel to keep its internal state or the state of user tasks, we can relax the permission check, and allow mappings of memory that is reserved and marked as NOMAP via memblock, and therefore not covered by the linear mapping to begin with. Fixes: 1583052 ("arm64/acpi: disallow AML memory opregions to access kernel memory") Fixes: 325f558 ("arm64/acpi: disallow writeable AML opregion mapping for EFI code regions") Reported-by: Jonathan Cameron <[email protected]> Signed-off-by: Ard Biesheuvel <[email protected]> Tested-by: Jonathan Cameron <[email protected]> Cc: Sudeep Holla <[email protected]> Cc: Lorenzo Pieralisi <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Catalin Marinas <[email protected]>
1 parent 75df529 commit a509a66

File tree

2 files changed

+21
-3
lines changed

2 files changed

+21
-3
lines changed

arch/arm64/kernel/acpi.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,8 +298,21 @@ void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size)
298298
case EFI_BOOT_SERVICES_DATA:
299299
case EFI_CONVENTIONAL_MEMORY:
300300
case EFI_PERSISTENT_MEMORY:
301-
pr_warn(FW_BUG "requested region covers kernel memory @ %pa\n", &phys);
302-
return NULL;
301+
if (memblock_is_map_memory(phys) ||
302+
!memblock_is_region_memory(phys, size)) {
303+
pr_warn(FW_BUG "requested region covers kernel memory @ %pa\n", &phys);
304+
return NULL;
305+
}
306+
/*
307+
* Mapping kernel memory is permitted if the region in
308+
* question is covered by a single memblock with the
309+
* NOMAP attribute set: this enables the use of ACPI
310+
* table overrides passed via initramfs, which are
311+
* reserved in memory using arch_reserve_mem_area()
312+
* below. As this particular use case only requires
313+
* read access, fall through to the R/O mapping case.
314+
*/
315+
fallthrough;
303316

304317
case EFI_RUNTIME_SERVICES_CODE:
305318
/*
@@ -388,3 +401,8 @@ int apei_claim_sea(struct pt_regs *regs)
388401

389402
return err;
390403
}
404+
405+
void arch_reserve_mem_area(acpi_physical_address addr, size_t size)
406+
{
407+
memblock_mark_nomap(addr, size);
408+
}

include/linux/acpi.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -958,7 +958,7 @@ void acpi_os_set_prepare_extended_sleep(int (*func)(u8 sleep_state,
958958
acpi_status acpi_os_prepare_extended_sleep(u8 sleep_state,
959959
u32 val_a, u32 val_b);
960960

961-
#ifdef CONFIG_X86
961+
#ifndef CONFIG_IA64
962962
void arch_reserve_mem_area(acpi_physical_address addr, size_t size);
963963
#else
964964
static inline void arch_reserve_mem_area(acpi_physical_address addr,

0 commit comments

Comments
 (0)