On Thu, 10 Oct 2019 at 01:19, Dan Williams <dan.j.williams@xxxxxxxxx> wrote: > > UEFI 2.8 defines an EFI_MEMORY_SP attribute bit to augment the > interpretation of the EFI Memory Types as "reserved for a specific > purpose". > > The proposed Linux behavior for specific purpose memory is that it is > reserved for direct-access (device-dax) by default and not available for > any kernel usage, not even as an OOM fallback. Later, through udev > scripts or another init mechanism, these device-dax claimed ranges can > be reconfigured and hot-added to the available System-RAM with a unique > node identifier. This device-dax management scheme implements "soft" in > the "soft reserved" designation by allowing some or all of the > reservation to be recovered as typical memory. This policy can be > disabled at compile-time with CONFIG_EFI_SOFT_RESERVE=n, or runtime with > efi=nosoftreserve. > > For this patch, update the ARM paths that consider > EFI_CONVENTIONAL_MEMORY to optionally take the EFI_MEMORY_SP attribute > into account as a reservation indicator. Publish the soft reservation as > IORES_DESC_SOFT_RESERVED memory, similar to x86. > > (Based on an original patch by Ard) > > Cc: Will Deacon <will@xxxxxxxxxx> > Cc: Catalin Marinas <catalin.marinas@xxxxxxx> > Cc: Ard Biesheuvel <ard.biesheuvel@xxxxxxxxxx> > Signed-off-by: Dan Williams <dan.j.williams@xxxxxxxxx> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@xxxxxxxxxx> > --- > arch/arm64/mm/mmu.c | 2 ++ > drivers/firmware/efi/arm-init.c | 9 +++++++++ > drivers/firmware/efi/arm-runtime.c | 24 ++++++++++++++++++++++++ > drivers/firmware/efi/libstub/arm32-stub.c | 5 +++++ > drivers/firmware/efi/libstub/random.c | 4 ++++ > 5 files changed, 44 insertions(+) > > diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c > index 60c929f3683b..2c385fe05fde 100644 > --- a/arch/arm64/mm/mmu.c > +++ b/arch/arm64/mm/mmu.c > @@ -1061,6 +1061,8 @@ int arch_add_memory(int nid, u64 start, u64 size, > __create_pgd_mapping(swapper_pg_dir, start, __phys_to_virt(start), > size, PAGE_KERNEL, __pgd_pgtable_alloc, flags); > > + memblock_clear_nomap(start, size); > + > return __add_pages(nid, start >> PAGE_SHIFT, size >> PAGE_SHIFT, > restrictions); > } > diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c > index 311cd349a862..904fa09e6a6b 100644 > --- a/drivers/firmware/efi/arm-init.c > +++ b/drivers/firmware/efi/arm-init.c > @@ -163,6 +163,15 @@ static __init int is_usable_memory(efi_memory_desc_t *md) > case EFI_BOOT_SERVICES_DATA: > case EFI_CONVENTIONAL_MEMORY: > case EFI_PERSISTENT_MEMORY: > + /* > + * Special purpose memory is 'soft reserved', which means it > + * is set aside initially, but can be hotplugged back in or > + * be assigned to the dax driver after boot. > + */ > + if (efi_soft_reserve_enabled() && > + (md->attribute & EFI_MEMORY_SP)) > + return false; > + > /* > * According to the spec, these regions are no longer reserved > * after calling ExitBootServices(). However, we can only use > diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c > index e2ac5fa5531b..899b803842bb 100644 > --- a/drivers/firmware/efi/arm-runtime.c > +++ b/drivers/firmware/efi/arm-runtime.c > @@ -121,6 +121,30 @@ static int __init arm_enable_runtime_services(void) > return 0; > } > > + if (efi_soft_reserve_enabled()) { > + efi_memory_desc_t *md; > + > + for_each_efi_memory_desc(md) { > + int md_size = md->num_pages << EFI_PAGE_SHIFT; > + struct resource *res; > + > + if (!(md->attribute & EFI_MEMORY_SP)) > + continue; > + > + res = kzalloc(sizeof(*res), GFP_KERNEL); > + if (WARN_ON(!res)) > + break; > + > + res->start = md->phys_addr; > + res->end = md->phys_addr + md_size - 1; > + res->name = "Soft Reserved"; > + res->flags = IORESOURCE_MEM; > + res->desc = IORES_DESC_SOFT_RESERVED; > + > + insert_resource(&iomem_resource, res); > + } > + } > + > if (efi_runtime_disabled()) { > pr_info("EFI runtime services will be disabled.\n"); > return 0; > diff --git a/drivers/firmware/efi/libstub/arm32-stub.c b/drivers/firmware/efi/libstub/arm32-stub.c > index e8f7aefb6813..3cd54d2096c6 100644 > --- a/drivers/firmware/efi/libstub/arm32-stub.c > +++ b/drivers/firmware/efi/libstub/arm32-stub.c > @@ -146,6 +146,11 @@ static efi_status_t reserve_kernel_base(efi_system_table_t *sys_table_arg, > continue; > > case EFI_CONVENTIONAL_MEMORY: > + /* Skip soft reserved conventional memory */ > + if (efi_soft_reserve_enabled() && > + (desc->attribute & EFI_MEMORY_SP)) > + continue; > + > /* > * Reserve the intersection between this entry and the > * region. > diff --git a/drivers/firmware/efi/libstub/random.c b/drivers/firmware/efi/libstub/random.c > index b4b1d1dcb5fd..6c188695e730 100644 > --- a/drivers/firmware/efi/libstub/random.c > +++ b/drivers/firmware/efi/libstub/random.c > @@ -46,6 +46,10 @@ static unsigned long get_entry_num_slots(efi_memory_desc_t *md, > if (md->type != EFI_CONVENTIONAL_MEMORY) > return 0; > > + if (efi_soft_reserve_enabled() && > + (md->attribute & EFI_MEMORY_SP)) > + return 0; > + > region_end = min((u64)ULONG_MAX, md->phys_addr + md->num_pages*EFI_PAGE_SIZE - 1); > > first_slot = round_up(md->phys_addr, align); >