Skip to content

Commit 16993c0

Browse files
djbwrafaeljw
authored andcommitted
arm/efi: EFI soft reservation to memblock
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 <[email protected]> Signed-off-by: Dan Williams <[email protected]> Acked-by: Thomas Gleixner <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 262b45a commit 16993c0

File tree

5 files changed

+44
-0
lines changed

5 files changed

+44
-0
lines changed

arch/arm64/mm/mmu.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,6 +1061,8 @@ int arch_add_memory(int nid, u64 start, u64 size,
10611061
__create_pgd_mapping(swapper_pg_dir, start, __phys_to_virt(start),
10621062
size, PAGE_KERNEL, __pgd_pgtable_alloc, flags);
10631063

1064+
memblock_clear_nomap(start, size);
1065+
10641066
return __add_pages(nid, start >> PAGE_SHIFT, size >> PAGE_SHIFT,
10651067
restrictions);
10661068
}

drivers/firmware/efi/arm-init.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,15 @@ static __init int is_usable_memory(efi_memory_desc_t *md)
163163
case EFI_BOOT_SERVICES_DATA:
164164
case EFI_CONVENTIONAL_MEMORY:
165165
case EFI_PERSISTENT_MEMORY:
166+
/*
167+
* Special purpose memory is 'soft reserved', which means it
168+
* is set aside initially, but can be hotplugged back in or
169+
* be assigned to the dax driver after boot.
170+
*/
171+
if (efi_soft_reserve_enabled() &&
172+
(md->attribute & EFI_MEMORY_SP))
173+
return false;
174+
166175
/*
167176
* According to the spec, these regions are no longer reserved
168177
* after calling ExitBootServices(). However, we can only use

drivers/firmware/efi/arm-runtime.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,30 @@ static int __init arm_enable_runtime_services(void)
121121
return 0;
122122
}
123123

124+
if (efi_soft_reserve_enabled()) {
125+
efi_memory_desc_t *md;
126+
127+
for_each_efi_memory_desc(md) {
128+
int md_size = md->num_pages << EFI_PAGE_SHIFT;
129+
struct resource *res;
130+
131+
if (!(md->attribute & EFI_MEMORY_SP))
132+
continue;
133+
134+
res = kzalloc(sizeof(*res), GFP_KERNEL);
135+
if (WARN_ON(!res))
136+
break;
137+
138+
res->start = md->phys_addr;
139+
res->end = md->phys_addr + md_size - 1;
140+
res->name = "Soft Reserved";
141+
res->flags = IORESOURCE_MEM;
142+
res->desc = IORES_DESC_SOFT_RESERVED;
143+
144+
insert_resource(&iomem_resource, res);
145+
}
146+
}
147+
124148
if (efi_runtime_disabled()) {
125149
pr_info("EFI runtime services will be disabled.\n");
126150
return 0;

drivers/firmware/efi/libstub/arm32-stub.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,11 @@ static efi_status_t reserve_kernel_base(efi_system_table_t *sys_table_arg,
146146
continue;
147147

148148
case EFI_CONVENTIONAL_MEMORY:
149+
/* Skip soft reserved conventional memory */
150+
if (efi_soft_reserve_enabled() &&
151+
(desc->attribute & EFI_MEMORY_SP))
152+
continue;
153+
149154
/*
150155
* Reserve the intersection between this entry and the
151156
* region.

drivers/firmware/efi/libstub/random.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ static unsigned long get_entry_num_slots(efi_memory_desc_t *md,
4646
if (md->type != EFI_CONVENTIONAL_MEMORY)
4747
return 0;
4848

49+
if (efi_soft_reserve_enabled() &&
50+
(md->attribute & EFI_MEMORY_SP))
51+
return 0;
52+
4953
region_end = min((u64)ULONG_MAX, md->phys_addr + md->num_pages*EFI_PAGE_SIZE - 1);
5054

5155
first_slot = round_up(md->phys_addr, align);

0 commit comments

Comments
 (0)