History

efi: Common enable/disable infrastructure for EFI soft reservation

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. As for this patch, define the common helpers to determine if the EFI_MEMORY_SP attribute should be honored. The determination needs to be made early to prevent the kernel from being loaded into soft-reserved memory, or otherwise allowing early allocations to land there. Follow-on changes are needed per architecture to leverage these helpers in their respective mem-init paths.

Dan Williams committed 7 years ago

Commit b617c521 parent 6950e315 files · +70 −1Browse files

Unified · Split

5 files
  1. Documentation/admin-guide/kernel-parameters.txt +8 −1
  2. drivers/firmware/efi/Kconfig +21 −0
  3. drivers/firmware/efi/efi.c +8 −0
  4. drivers/firmware/efi/libstub/efi-stub-helper.c +19 −0
  5. include/linux/efi.h +14 −0
Documentation/admin-guide/kernel-parameters.txt+8−1
@@ -1168,7 +1168,8 @@ · 1167 unmodified lines
1168 Format: {"off" | "on" | "skip[mbr]"}1168 Format: {"off" | "on" | "skip[mbr]"}
1169 1169
1170 efi= [EFI]1170 efi= [EFI]
1171 Format: { "old_map", "nochunk", "noruntime", "debug" }1171 Format: { "old_map", "nochunk", "noruntime", "debug",
1172 "nosoftreserve" }
1172 old_map [X86-64]: switch to the old ioremap-based EFI1173 old_map [X86-64]: switch to the old ioremap-based EFI
1173 runtime services mapping. 32-bit still uses this one by1174 runtime services mapping. 32-bit still uses this one by
1174 default.1175 default.
@@ -1177,6 +1178,12 @@ · 2 unmodified lines
1177 firmware implementations.1178 firmware implementations.
1178 noruntime : disable EFI runtime services support1179 noruntime : disable EFI runtime services support
1179 debug: enable misc debug output1180 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").
1180 1187
1181 efi_no_storage_paranoia [EFI; X86]1188 efi_no_storage_paranoia [EFI; X86]
1182 Using this parameter you can use more than 50% of1189 Using this parameter you can use more than 50% of
drivers/firmware/efi/Kconfig+21−0
@@ -75,6 +75,27 @@ config EFI_MAX_FAKE_MEM · 74 unmodified lines
75 Ranges can be set up to this value using comma-separated list.75 Ranges can be set up to this value using comma-separated list.
76 The default value is 8.76 The default value is 8.
77 77
78config EFI_SOFT_RESERVE
79 bool "Reserve EFI Specific Purpose Memory"
80 depends on EFI && EFI_STUB && ACPI_HMAT
81 default ACPI_HMAT
82 help
83 On systems that have mixed performance classes of memory EFI
84 may indicate specific purpose memory with an attribute (See
85 EFI_MEMORY_SP in UEFI 2.8). A memory range tagged with this
86 attribute may have unique performance characteristics compared
87 to the system's general purpose "System RAM" pool. On the
88 expectation that such memory has application specific usage,
89 and its base EFI memory type is "conventional" answer Y to
90 arrange for the kernel to reserve it as a "Soft Reserved"
91 resource, and set aside for direct-access (device-dax) by
92 default. The memory range can later be optionally assigned to
93 the page allocator by system administrator policy via the
94 device-dax kmem facility. Say N to have the kernel treat this
95 memory as "System RAM" by default.
96
97 If unsure, say Y.
98
78config EFI_PARAMS_FROM_FDT99config EFI_PARAMS_FROM_FDT
79 bool100 bool
80 help101 help
drivers/firmware/efi/efi.c+8−0
@@ -81,6 +81,11 @@ bool efi_runtime_disabled(void) · 80 unmodified lines
81 return disable_runtime;81 return disable_runtime;
82}82}
83 83
84bool __pure __efi_soft_reserve_enabled(void)
85{
86 return !efi_enabled(EFI_MEM_NO_SOFT_RESERVE);
87}
88
84static int __init parse_efi_cmdline(char *str)89static int __init parse_efi_cmdline(char *str)
85{90{
86 if (!str) {91 if (!str) {
@@ -94,6 +99,9 @@ static int __init parse_efi_cmdline(char *str) · 7 unmodified lines
94 if (parse_option_str(str, "noruntime"))99 if (parse_option_str(str, "noruntime"))
95 disable_runtime = true;100 disable_runtime = true;
96 101
102 if (parse_option_str(str, "nosoftreserve"))
103 set_bit(EFI_MEM_NO_SOFT_RESERVE, &efi.flags);
104
97 return 0;105 return 0;
98}106}
99early_param("efi", parse_efi_cmdline);107early_param("efi", parse_efi_cmdline);
drivers/firmware/efi/libstub/efi-stub-helper.c+19−0
@@ -32,6 +32,7 @@ static unsigned long __chunk_size = EFI_READ_CHUNK_SIZE; · 31 unmodified lines
32static int __section(.data) __nokaslr;32static int __section(.data) __nokaslr;
33static int __section(.data) __quiet;33static int __section(.data) __quiet;
34static int __section(.data) __novamap;34static int __section(.data) __novamap;
35static bool __section(.data) efi_nosoftreserve;
35 36
36int __pure nokaslr(void)37int __pure nokaslr(void)
37{38{
@@ -45,6 +46,10 @@ int __pure novamap(void) · 7 unmodified lines
45{46{
46 return __novamap;47 return __novamap;
47}48}
49bool __pure __efi_soft_reserve_enabled(void)
50{
51 return !efi_nosoftreserve;
52}
48 53
49#define EFI_MMAP_NR_SLACK_SLOTS 854#define EFI_MMAP_NR_SLACK_SLOTS 8
50 55
@@ -211,6 +216,10 @@ again: · 160 unmodified lines
211 if (desc->type != EFI_CONVENTIONAL_MEMORY)216 if (desc->type != EFI_CONVENTIONAL_MEMORY)
212 continue;217 continue;
213 218
219 if (efi_soft_reserve_enabled() &&
220 (desc->attribute & EFI_MEMORY_SP))
221 continue;
222
214 if (desc->num_pages < nr_pages)223 if (desc->num_pages < nr_pages)
215 continue;224 continue;
216 225
@@ -305,6 +314,10 @@ efi_status_t efi_low_alloc_above(efi_system_table_t *sys_table_arg, · 88 unmodified lines
305 if (desc->type != EFI_CONVENTIONAL_MEMORY)314 if (desc->type != EFI_CONVENTIONAL_MEMORY)
306 continue;315 continue;
307 316
317 if (efi_soft_reserve_enabled() &&
318 (desc->attribute & EFI_MEMORY_SP))
319 continue;
320
308 if (desc->num_pages < nr_pages)321 if (desc->num_pages < nr_pages)
309 continue;322 continue;
310 323
@@ -484,6 +497,12 @@ efi_status_t efi_parse_options(char const *cmdline) · 173 unmodified lines
484 __novamap = 1;497 __novamap = 1;
485 }498 }
486 499
500 if (IS_ENABLED(CONFIG_EFI_SOFT_RESERVE) &&
501 !strncmp(str, "nosoftreserve", 7)) {
502 str += strlen("nosoftreserve");
503 efi_nosoftreserve = 1;
504 }
505
487 /* Group words together, delimited by "," */506 /* Group words together, delimited by "," */
488 while (*str && *str != ' ' && *str != ',')507 while (*str && *str != ' ' && *str != ',')
489 str++;508 str++;
include/linux/efi.h+14−0
@@ -1202,6 +1202,7 @@ extern int __init efi_setup_pcdp_console(char *); · 1201 unmodified lines
1202#define EFI_DBG 8 /* Print additional debug info at runtime */1202#define EFI_DBG 8 /* Print additional debug info at runtime */
1203#define EFI_NX_PE_DATA 9 /* Can runtime data regions be mapped non-executable? */1203#define EFI_NX_PE_DATA 9 /* Can runtime data regions be mapped non-executable? */
1204#define EFI_MEM_ATTR 10 /* Did firmware publish an EFI_MEMORY_ATTRIBUTES table? */1204#define EFI_MEM_ATTR 10 /* Did firmware publish an EFI_MEMORY_ATTRIBUTES table? */
1205#define EFI_MEM_NO_SOFT_RESERVE 11 /* Is the kernel configured to ignore soft reservations? */
1205 1206
1206#ifdef CONFIG_EFI1207#ifdef CONFIG_EFI
1207/*1208/*
@@ -1212,6 +1213,14 @@ static inline bool efi_enabled(int feature) · 4 unmodified lines
1212 return test_bit(feature, &efi.flags) != 0;1213 return test_bit(feature, &efi.flags) != 0;
1213}1214}
1214extern void efi_reboot(enum reboot_mode reboot_mode, const char *__unused);1215extern void efi_reboot(enum reboot_mode reboot_mode, const char *__unused);
1216
1217bool __pure __efi_soft_reserve_enabled(void);
1218
1219static inline bool __pure efi_soft_reserve_enabled(void)
1220{
1221 return IS_ENABLED(CONFIG_EFI_SOFT_RESERVE)
1222 && __efi_soft_reserve_enabled();
1223}
1215#else1224#else
1216static inline bool efi_enabled(int feature)1225static inline bool efi_enabled(int feature)
1217{1226{
@@ -1225,6 +1234,11 @@ efi_capsule_pending(int *reset_type) · 7 unmodified lines
1225{1234{
1226 return false;1235 return false;
1227}1236}
1237
1238static inline bool efi_soft_reserve_enabled(void)
1239{
1240 return false;
1241}
1228#endif1242#endif
1229 1243
1230extern int efi_status_to_err(efi_status_t status);1244extern int efi_status_to_err(efi_status_t status);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t