aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2016-08-25 12:17:09 -0400
committerMatt Fleming <matt@codeblueprint.co.uk>2016-09-09 11:08:54 -0400
commitcb82cce7035ec22a69ab3bd4d2fe6729527ce1ca (patch)
treedeeeace2fbde1727bd92e99cda75a7a5dc3ff4c4
parentff6301dabc3ca20ab8f50f8d0252ac05da610d89 (diff)
efi/arm64: Treat regions with WT/WC set but WB cleared as memory
Currently, memory regions are only recorded in the memblock memory table if they have the EFI_MEMORY_WB memory type attribute set. In case the region is of a reserved type, it is also marked as MEMBLOCK_NOMAP, which will leave it out of the linear mapping. However, memory regions may legally have the EFI_MEMORY_WT or EFI_MEMORY_WC attributes set, and the EFI_MEMORY_WB cleared, in which case the region in question is obviously backed by normal memory, but is not recorded in the memblock memory table at all. Since it would be useful to be able to identify any UEFI reported memory region using memblock_is_memory(), it makes sense to add all memory to the memblock memory table, and simply mark it as MEMBLOCK_NOMAP if it lacks the EFI_MEMORY_WB attribute. While implementing this, let's refactor the code slightly to make it easier to understand: replace is_normal_ram() with is_memory(), and make it return true for each region that has any of the WB|WT|WC bits set. (This follows the AArch64 bindings in the UEFI spec, which state that those are the attributes that map to normal memory) Also, replace is_reserve_region() with is_usable_memory(), and only invoke it if the region in question was identified as memory by is_memory() in the first place. The net result is the same (only reserved regions that are backed by memory end up in the memblock memory table with the MEMBLOCK_NOMAP flag set) but carried out in a more straightforward way. Finally, we remove the trailing asterisk in the EFI debug output. Keeping it clutters the code, and it serves no real purpose now that we no longer temporarily reserve BootServices code and data regions like we did in the early days of EFI support on arm64 Linux (which it inherited from the x86 implementation) Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org> Tested-by: James Morse <james.morse@arm.com> Reviewed-by: James Morse <james.morse@arm.com> Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
-rw-r--r--drivers/firmware/efi/arm-init.c32
1 files changed, 17 insertions, 15 deletions
diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c
index e0a511d4074f..8efe13075c92 100644
--- a/drivers/firmware/efi/arm-init.c
+++ b/drivers/firmware/efi/arm-init.c
@@ -26,9 +26,9 @@
26 26
27u64 efi_system_table; 27u64 efi_system_table;
28 28
29static int __init is_normal_ram(efi_memory_desc_t *md) 29static int __init is_memory(efi_memory_desc_t *md)
30{ 30{
31 if (md->attribute & EFI_MEMORY_WB) 31 if (md->attribute & (EFI_MEMORY_WB|EFI_MEMORY_WT|EFI_MEMORY_WC))
32 return 1; 32 return 1;
33 return 0; 33 return 0;
34} 34}
@@ -152,9 +152,9 @@ out:
152} 152}
153 153
154/* 154/*
155 * Return true for RAM regions we want to permanently reserve. 155 * Return true for regions that can be used as System RAM.
156 */ 156 */
157static __init int is_reserve_region(efi_memory_desc_t *md) 157static __init int is_usable_memory(efi_memory_desc_t *md)
158{ 158{
159 switch (md->type) { 159 switch (md->type) {
160 case EFI_LOADER_CODE: 160 case EFI_LOADER_CODE:
@@ -163,18 +163,22 @@ static __init int is_reserve_region(efi_memory_desc_t *md)
163 case EFI_BOOT_SERVICES_DATA: 163 case EFI_BOOT_SERVICES_DATA:
164 case EFI_CONVENTIONAL_MEMORY: 164 case EFI_CONVENTIONAL_MEMORY:
165 case EFI_PERSISTENT_MEMORY: 165 case EFI_PERSISTENT_MEMORY:
166 return 0; 166 /*
167 * According to the spec, these regions are no longer reserved
168 * after calling ExitBootServices(). However, we can only use
169 * them as System RAM if they can be mapped writeback cacheable.
170 */
171 return (md->attribute & EFI_MEMORY_WB);
167 default: 172 default:
168 break; 173 break;
169 } 174 }
170 return is_normal_ram(md); 175 return false;
171} 176}
172 177
173static __init void reserve_regions(void) 178static __init void reserve_regions(void)
174{ 179{
175 efi_memory_desc_t *md; 180 efi_memory_desc_t *md;
176 u64 paddr, npages, size; 181 u64 paddr, npages, size;
177 int resv;
178 182
179 if (efi_enabled(EFI_DBG)) 183 if (efi_enabled(EFI_DBG))
180 pr_info("Processing EFI memory map:\n"); 184 pr_info("Processing EFI memory map:\n");
@@ -191,25 +195,23 @@ static __init void reserve_regions(void)
191 paddr = md->phys_addr; 195 paddr = md->phys_addr;
192 npages = md->num_pages; 196 npages = md->num_pages;
193 197
194 resv = is_reserve_region(md);
195 if (efi_enabled(EFI_DBG)) { 198 if (efi_enabled(EFI_DBG)) {
196 char buf[64]; 199 char buf[64];
197 200
198 pr_info(" 0x%012llx-0x%012llx %s%s\n", 201 pr_info(" 0x%012llx-0x%012llx %s\n",
199 paddr, paddr + (npages << EFI_PAGE_SHIFT) - 1, 202 paddr, paddr + (npages << EFI_PAGE_SHIFT) - 1,
200 efi_md_typeattr_format(buf, sizeof(buf), md), 203 efi_md_typeattr_format(buf, sizeof(buf), md));
201 resv ? "*" : "");
202 } 204 }
203 205
204 memrange_efi_to_native(&paddr, &npages); 206 memrange_efi_to_native(&paddr, &npages);
205 size = npages << PAGE_SHIFT; 207 size = npages << PAGE_SHIFT;
206 208
207 if (is_normal_ram(md)) 209 if (is_memory(md)) {
208 early_init_dt_add_memory_arch(paddr, size); 210 early_init_dt_add_memory_arch(paddr, size);
209 211
210 if (resv) 212 if (!is_usable_memory(md))
211 memblock_mark_nomap(paddr, size); 213 memblock_mark_nomap(paddr, size);
212 214 }
213 } 215 }
214} 216}
215 217