Skip to content

Commit 782b597

Browse files
committed
Merge branch 'acpi-mm'
* acpi-mm: ACPI: HMAT: use %u instead of %d to print u32 values ACPI: NUMA: HMAT: fix a section mismatch ACPI: HMAT: don't mix pxm and nid when setting memory target processor_pxm ACPI: NUMA: HMAT: Register "soft reserved" memory as an "hmem" device ACPI: NUMA: HMAT: Register HMAT at device_initcall level device-dax: Add a driver for "hmem" devices dax: Fix alloc_dax_region() compile warning lib: Uplevel the pmem "region" ida to a global allocator x86/efi: Add efi_fake_mem support for EFI_MEMORY_SP arm/efi: EFI soft reservation to memblock x86/efi: EFI soft reservation to E820 enumeration efi: Common enable/disable infrastructure for EFI soft reservation x86/efi: Push EFI_MEMMAP check into leaf routines efi: Enumerate EFI_MEMORY_SP ACPI: NUMA: Establish a new drivers/acpi/numa/ directory
2 parents 995e2ef + 0f1839d commit 782b597

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+644
-100
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,7 +1168,8 @@
11681168
Format: {"off" | "on" | "skip[mbr]"}
11691169

11701170
efi= [EFI]
1171-
Format: { "old_map", "nochunk", "noruntime", "debug" }
1171+
Format: { "old_map", "nochunk", "noruntime", "debug",
1172+
"nosoftreserve" }
11721173
old_map [X86-64]: switch to the old ioremap-based EFI
11731174
runtime services mapping. 32-bit still uses this one by
11741175
default.
@@ -1177,6 +1178,12 @@
11771178
firmware implementations.
11781179
noruntime : disable EFI runtime services support
11791180
debug: enable misc debug output
1181+
nosoftreserve: The EFI_MEMORY_SP (Specific Purpose)
1182+
attribute may cause the kernel to reserve the
1183+
memory range for a memory mapping driver to
1184+
claim. Specify efi=nosoftreserve to disable this
1185+
reservation and treat the memory by its base type
1186+
(i.e. EFI_CONVENTIONAL_MEMORY / "System RAM").
11801187

11811188
efi_no_storage_paranoia [EFI; X86]
11821189
Using this parameter you can use more than 50% of
@@ -1189,15 +1196,21 @@
11891196
updating original EFI memory map.
11901197
Region of memory which aa attribute is added to is
11911198
from ss to ss+nn.
1199+
11921200
If efi_fake_mem=2G@4G:0x10000,2G@0x10a0000000:0x10000
11931201
is specified, EFI_MEMORY_MORE_RELIABLE(0x10000)
11941202
attribute is added to range 0x100000000-0x180000000 and
11951203
0x10a0000000-0x1120000000.
11961204

1205+
If efi_fake_mem=8G@9G:0x40000 is specified, the
1206+
EFI_MEMORY_SP(0x40000) attribute is added to
1207+
range 0x240000000-0x43fffffff.
1208+
11971209
Using this parameter you can do debugging of EFI memmap
1198-
related feature. For example, you can do debugging of
1210+
related features. For example, you can do debugging of
11991211
Address Range Mirroring feature even if your box
1200-
doesn't support it.
1212+
doesn't support it, or mark specific memory as
1213+
"soft reserved".
12011214

12021215
efivar_ssdt= [EFI; X86] Name of an EFI variable that contains an SSDT
12031216
that is to be dynamically loaded by Linux. If there are

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
}

arch/x86/boot/compressed/eboot.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,11 @@ setup_e820(struct boot_params *params, struct setup_data *e820ext, u32 e820ext_s
554554
case EFI_BOOT_SERVICES_CODE:
555555
case EFI_BOOT_SERVICES_DATA:
556556
case EFI_CONVENTIONAL_MEMORY:
557-
e820_type = E820_TYPE_RAM;
557+
if (efi_soft_reserve_enabled() &&
558+
(d->attribute & EFI_MEMORY_SP))
559+
e820_type = E820_TYPE_SOFT_RESERVED;
560+
else
561+
e820_type = E820_TYPE_RAM;
558562
break;
559563

560564
case EFI_ACPI_MEMORY_NVS:

arch/x86/boot/compressed/kaslr.c

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,14 @@ char *skip_spaces(const char *str)
132132
#include "../../../../lib/ctype.c"
133133
#include "../../../../lib/cmdline.c"
134134

135+
enum parse_mode {
136+
PARSE_MEMMAP,
137+
PARSE_EFI,
138+
};
139+
135140
static int
136-
parse_memmap(char *p, unsigned long long *start, unsigned long long *size)
141+
parse_memmap(char *p, unsigned long long *start, unsigned long long *size,
142+
enum parse_mode mode)
137143
{
138144
char *oldp;
139145

@@ -156,8 +162,29 @@ parse_memmap(char *p, unsigned long long *start, unsigned long long *size)
156162
*start = memparse(p + 1, &p);
157163
return 0;
158164
case '@':
159-
/* memmap=nn@ss specifies usable region, should be skipped */
160-
*size = 0;
165+
if (mode == PARSE_MEMMAP) {
166+
/*
167+
* memmap=nn@ss specifies usable region, should
168+
* be skipped
169+
*/
170+
*size = 0;
171+
} else {
172+
unsigned long long flags;
173+
174+
/*
175+
* efi_fake_mem=nn@ss:attr the attr specifies
176+
* flags that might imply a soft-reservation.
177+
*/
178+
*start = memparse(p + 1, &p);
179+
if (p && *p == ':') {
180+
p++;
181+
if (kstrtoull(p, 0, &flags) < 0)
182+
*size = 0;
183+
else if (flags & EFI_MEMORY_SP)
184+
return 0;
185+
}
186+
*size = 0;
187+
}
161188
/* Fall through */
162189
default:
163190
/*
@@ -172,7 +199,7 @@ parse_memmap(char *p, unsigned long long *start, unsigned long long *size)
172199
return -EINVAL;
173200
}
174201

175-
static void mem_avoid_memmap(char *str)
202+
static void mem_avoid_memmap(enum parse_mode mode, char *str)
176203
{
177204
static int i;
178205

@@ -187,7 +214,7 @@ static void mem_avoid_memmap(char *str)
187214
if (k)
188215
*k++ = 0;
189216

190-
rc = parse_memmap(str, &start, &size);
217+
rc = parse_memmap(str, &start, &size, mode);
191218
if (rc < 0)
192219
break;
193220
str = k;
@@ -238,7 +265,6 @@ static void parse_gb_huge_pages(char *param, char *val)
238265
}
239266
}
240267

241-
242268
static void handle_mem_options(void)
243269
{
244270
char *args = (char *)get_cmd_line_ptr();
@@ -271,7 +297,7 @@ static void handle_mem_options(void)
271297
}
272298

273299
if (!strcmp(param, "memmap")) {
274-
mem_avoid_memmap(val);
300+
mem_avoid_memmap(PARSE_MEMMAP, val);
275301
} else if (strstr(param, "hugepages")) {
276302
parse_gb_huge_pages(param, val);
277303
} else if (!strcmp(param, "mem")) {
@@ -284,6 +310,8 @@ static void handle_mem_options(void)
284310
goto out;
285311

286312
mem_limit = mem_size;
313+
} else if (!strcmp(param, "efi_fake_mem")) {
314+
mem_avoid_memmap(PARSE_EFI, val);
287315
}
288316
}
289317

@@ -760,6 +788,10 @@ process_efi_entries(unsigned long minimum, unsigned long image_size)
760788
if (md->type != EFI_CONVENTIONAL_MEMORY)
761789
continue;
762790

791+
if (efi_soft_reserve_enabled() &&
792+
(md->attribute & EFI_MEMORY_SP))
793+
continue;
794+
763795
if (efi_mirror_found &&
764796
!(md->attribute & EFI_MEMORY_MORE_RELIABLE))
765797
continue;

arch/x86/include/asm/e820/types.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ enum e820_type {
2828
*/
2929
E820_TYPE_PRAM = 12,
3030

31+
/*
32+
* Special-purpose memory is indicated to the system via the
33+
* EFI_MEMORY_SP attribute. Define an e820 translation of this
34+
* memory type for the purpose of reserving this range and
35+
* marking it with the IORES_DESC_SOFT_RESERVED designation.
36+
*/
37+
E820_TYPE_SOFT_RESERVED = 0xefffffff,
38+
3139
/*
3240
* Reserved RAM used by the kernel itself if
3341
* CONFIG_INTEL_TXT=y is enabled, memory of this type

arch/x86/include/asm/efi.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,6 @@ extern void efi_delete_dummy_variable(void);
140140
extern void efi_switch_mm(struct mm_struct *mm);
141141
extern void efi_recover_from_page_fault(unsigned long phys_addr);
142142
extern void efi_free_boot_services(void);
143-
extern void efi_reserve_boot_services(void);
144143

145144
struct efi_setup_data {
146145
u64 fw_vendor;
@@ -244,6 +243,8 @@ static inline bool efi_is_64bit(void)
244243
extern bool efi_reboot_required(void);
245244
extern bool efi_is_table_address(unsigned long phys_addr);
246245

246+
extern void efi_find_mirror(void);
247+
extern void efi_reserve_boot_services(void);
247248
#else
248249
static inline void parse_efi_setup(u64 phys_addr, u32 data_len) {}
249250
static inline bool efi_reboot_required(void)
@@ -254,6 +255,20 @@ static inline bool efi_is_table_address(unsigned long phys_addr)
254255
{
255256
return false;
256257
}
258+
static inline void efi_find_mirror(void)
259+
{
260+
}
261+
static inline void efi_reserve_boot_services(void)
262+
{
263+
}
257264
#endif /* CONFIG_EFI */
258265

266+
#ifdef CONFIG_EFI_FAKE_MEMMAP
267+
extern void __init efi_fake_memmap_early(void);
268+
#else
269+
static inline void efi_fake_memmap_early(void)
270+
{
271+
}
272+
#endif
273+
259274
#endif /* _ASM_X86_EFI_H */

arch/x86/kernel/e820.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ static void __init e820_print_type(enum e820_type type)
190190
case E820_TYPE_RAM: /* Fall through: */
191191
case E820_TYPE_RESERVED_KERN: pr_cont("usable"); break;
192192
case E820_TYPE_RESERVED: pr_cont("reserved"); break;
193+
case E820_TYPE_SOFT_RESERVED: pr_cont("soft reserved"); break;
193194
case E820_TYPE_ACPI: pr_cont("ACPI data"); break;
194195
case E820_TYPE_NVS: pr_cont("ACPI NVS"); break;
195196
case E820_TYPE_UNUSABLE: pr_cont("unusable"); break;
@@ -1037,6 +1038,7 @@ static const char *__init e820_type_to_string(struct e820_entry *entry)
10371038
case E820_TYPE_PRAM: return "Persistent Memory (legacy)";
10381039
case E820_TYPE_PMEM: return "Persistent Memory";
10391040
case E820_TYPE_RESERVED: return "Reserved";
1041+
case E820_TYPE_SOFT_RESERVED: return "Soft Reserved";
10401042
default: return "Unknown E820 type";
10411043
}
10421044
}
@@ -1052,6 +1054,7 @@ static unsigned long __init e820_type_to_iomem_type(struct e820_entry *entry)
10521054
case E820_TYPE_PRAM: /* Fall-through: */
10531055
case E820_TYPE_PMEM: /* Fall-through: */
10541056
case E820_TYPE_RESERVED: /* Fall-through: */
1057+
case E820_TYPE_SOFT_RESERVED: /* Fall-through: */
10551058
default: return IORESOURCE_MEM;
10561059
}
10571060
}
@@ -1064,6 +1067,7 @@ static unsigned long __init e820_type_to_iores_desc(struct e820_entry *entry)
10641067
case E820_TYPE_PMEM: return IORES_DESC_PERSISTENT_MEMORY;
10651068
case E820_TYPE_PRAM: return IORES_DESC_PERSISTENT_MEMORY_LEGACY;
10661069
case E820_TYPE_RESERVED: return IORES_DESC_RESERVED;
1070+
case E820_TYPE_SOFT_RESERVED: return IORES_DESC_SOFT_RESERVED;
10671071
case E820_TYPE_RESERVED_KERN: /* Fall-through: */
10681072
case E820_TYPE_RAM: /* Fall-through: */
10691073
case E820_TYPE_UNUSABLE: /* Fall-through: */
@@ -1078,11 +1082,12 @@ static bool __init do_mark_busy(enum e820_type type, struct resource *res)
10781082
return true;
10791083

10801084
/*
1081-
* Treat persistent memory like device memory, i.e. reserve it
1082-
* for exclusive use of a driver
1085+
* Treat persistent memory and other special memory ranges like
1086+
* device memory, i.e. reserve it for exclusive use of a driver
10831087
*/
10841088
switch (type) {
10851089
case E820_TYPE_RESERVED:
1090+
case E820_TYPE_SOFT_RESERVED:
10861091
case E820_TYPE_PRAM:
10871092
case E820_TYPE_PMEM:
10881093
return false;
@@ -1285,6 +1290,9 @@ void __init e820__memblock_setup(void)
12851290
if (end != (resource_size_t)end)
12861291
continue;
12871292

1293+
if (entry->type == E820_TYPE_SOFT_RESERVED)
1294+
memblock_reserve(entry->addr, entry->size);
1295+
12881296
if (entry->type != E820_TYPE_RAM && entry->type != E820_TYPE_RESERVED_KERN)
12891297
continue;
12901298

arch/x86/kernel/setup.c

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,17 +1122,15 @@ void __init setup_arch(char **cmdline_p)
11221122

11231123
reserve_bios_regions();
11241124

1125-
if (efi_enabled(EFI_MEMMAP)) {
1126-
efi_fake_memmap();
1127-
efi_find_mirror();
1128-
efi_esrt_init();
1125+
efi_fake_memmap();
1126+
efi_find_mirror();
1127+
efi_esrt_init();
11291128

1130-
/*
1131-
* The EFI specification says that boot service code won't be
1132-
* called after ExitBootServices(). This is, in fact, a lie.
1133-
*/
1134-
efi_reserve_boot_services();
1135-
}
1129+
/*
1130+
* The EFI specification says that boot service code won't be
1131+
* called after ExitBootServices(). This is, in fact, a lie.
1132+
*/
1133+
efi_reserve_boot_services();
11361134

11371135
/* preallocate 4k for mptable mpc */
11381136
e820__memblock_alloc_reserved_mpc_new();

0 commit comments

Comments
 (0)