]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
arm/efi: EFI soft reservation to memblock
authorDan Williams <dan.j.williams@intel.com>
Thu, 7 Nov 2019 01:43:21 +0000 (17:43 -0800)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Thu, 7 Nov 2019 14:44:19 +0000 (15:44 +0100)
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)

Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
arch/arm64/mm/mmu.c
drivers/firmware/efi/arm-init.c
drivers/firmware/efi/arm-runtime.c
drivers/firmware/efi/libstub/arm32-stub.c
drivers/firmware/efi/libstub/random.c

index 60c929f3683b967e9531db22665c5a850ecccda1..2c385fe05fde56f4a8f3c282af3c360177e90a94 100644 (file)
@@ -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);
 }
index 311cd349a8628bbe1e8b8441f5be32dc9ac71204..904fa09e6a6b0341ab3437080a25ed7b228bd806 100644 (file)
@@ -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
index e2ac5fa5531b9f4ce39e96d0953bb82251a49cbe..899b803842bbe4ec471b861ab2f1774a2ae6698c 100644 (file)
@@ -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;
index 41213bf5fcf5e8a84619923757fd033cce66761b..4566640de650d41856de686619a4e6e4226d4772 100644 (file)
@@ -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.
index b4b1d1dcb5fdc0ce690af90e65b1ddfcdf898f74..6c188695e7305ed7ae08f15f3b31f3df0a70ab8a 100644 (file)
@@ -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);