]>
Commit | Line | Data |
---|---|---|
eeb9db09 ST |
1 | #include <linux/init.h> |
2 | #include <linux/kernel.h> | |
3 | #include <linux/string.h> | |
4 | #include <linux/time.h> | |
5 | #include <linux/types.h> | |
6 | #include <linux/efi.h> | |
7 | #include <linux/slab.h> | |
8 | #include <linux/memblock.h> | |
9 | #include <linux/bootmem.h> | |
44be28e9 | 10 | #include <linux/acpi.h> |
eeb9db09 ST |
11 | #include <asm/efi.h> |
12 | #include <asm/uv/uv.h> | |
13 | ||
14 | #define EFI_MIN_RESERVE 5120 | |
15 | ||
16 | #define EFI_DUMMY_GUID \ | |
17 | EFI_GUID(0x4424ac57, 0xbe4b, 0x47dd, 0x9e, 0x97, 0xed, 0x50, 0xf0, 0x9f, 0x92, 0xa9) | |
18 | ||
19 | static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 }; | |
20 | ||
21 | static bool efi_no_storage_paranoia; | |
22 | ||
23 | /* | |
24 | * Some firmware implementations refuse to boot if there's insufficient | |
25 | * space in the variable store. The implementation of garbage collection | |
26 | * in some FW versions causes stale (deleted) variables to take up space | |
27 | * longer than intended and space is only freed once the store becomes | |
28 | * almost completely full. | |
29 | * | |
30 | * Enabling this option disables the space checks in | |
31 | * efi_query_variable_store() and forces garbage collection. | |
32 | * | |
33 | * Only enable this option if deleting EFI variables does not free up | |
34 | * space in your variable store, e.g. if despite deleting variables | |
35 | * you're unable to create new ones. | |
36 | */ | |
37 | static int __init setup_storage_paranoia(char *arg) | |
38 | { | |
39 | efi_no_storage_paranoia = true; | |
40 | return 0; | |
41 | } | |
42 | early_param("efi_no_storage_paranoia", setup_storage_paranoia); | |
43 | ||
44 | /* | |
45 | * Deleting the dummy variable which kicks off garbage collection | |
46 | */ | |
47 | void efi_delete_dummy_variable(void) | |
48 | { | |
49 | efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, | |
50 | EFI_VARIABLE_NON_VOLATILE | | |
51 | EFI_VARIABLE_BOOTSERVICE_ACCESS | | |
52 | EFI_VARIABLE_RUNTIME_ACCESS, | |
53 | 0, NULL); | |
54 | } | |
55 | ||
56 | /* | |
57 | * Some firmware implementations refuse to boot if there's insufficient space | |
58 | * in the variable store. Ensure that we never use more than a safe limit. | |
59 | * | |
60 | * Return EFI_SUCCESS if it is safe to write 'size' bytes to the variable | |
61 | * store. | |
62 | */ | |
63 | efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) | |
64 | { | |
65 | efi_status_t status; | |
66 | u64 storage_size, remaining_size, max_size; | |
67 | ||
68 | if (!(attributes & EFI_VARIABLE_NON_VOLATILE)) | |
69 | return 0; | |
70 | ||
71 | status = efi.query_variable_info(attributes, &storage_size, | |
72 | &remaining_size, &max_size); | |
73 | if (status != EFI_SUCCESS) | |
74 | return status; | |
75 | ||
76 | /* | |
77 | * We account for that by refusing the write if permitting it would | |
78 | * reduce the available space to under 5KB. This figure was provided by | |
79 | * Samsung, so should be safe. | |
80 | */ | |
81 | if ((remaining_size - size < EFI_MIN_RESERVE) && | |
82 | !efi_no_storage_paranoia) { | |
83 | ||
84 | /* | |
85 | * Triggering garbage collection may require that the firmware | |
86 | * generate a real EFI_OUT_OF_RESOURCES error. We can force | |
87 | * that by attempting to use more space than is available. | |
88 | */ | |
89 | unsigned long dummy_size = remaining_size + 1024; | |
90 | void *dummy = kzalloc(dummy_size, GFP_ATOMIC); | |
91 | ||
92 | if (!dummy) | |
93 | return EFI_OUT_OF_RESOURCES; | |
94 | ||
95 | status = efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, | |
96 | EFI_VARIABLE_NON_VOLATILE | | |
97 | EFI_VARIABLE_BOOTSERVICE_ACCESS | | |
98 | EFI_VARIABLE_RUNTIME_ACCESS, | |
99 | dummy_size, dummy); | |
100 | ||
101 | if (status == EFI_SUCCESS) { | |
102 | /* | |
103 | * This should have failed, so if it didn't make sure | |
104 | * that we delete it... | |
105 | */ | |
106 | efi_delete_dummy_variable(); | |
107 | } | |
108 | ||
109 | kfree(dummy); | |
110 | ||
111 | /* | |
112 | * The runtime code may now have triggered a garbage collection | |
113 | * run, so check the variable info again | |
114 | */ | |
115 | status = efi.query_variable_info(attributes, &storage_size, | |
116 | &remaining_size, &max_size); | |
117 | ||
118 | if (status != EFI_SUCCESS) | |
119 | return status; | |
120 | ||
121 | /* | |
122 | * There still isn't enough room, so return an error | |
123 | */ | |
124 | if (remaining_size - size < EFI_MIN_RESERVE) | |
125 | return EFI_OUT_OF_RESOURCES; | |
126 | } | |
127 | ||
128 | return EFI_SUCCESS; | |
129 | } | |
130 | EXPORT_SYMBOL_GPL(efi_query_variable_store); | |
131 | ||
132 | /* | |
133 | * The UEFI specification makes it clear that the operating system is free to do | |
134 | * whatever it wants with boot services code after ExitBootServices() has been | |
135 | * called. Ignoring this recommendation a significant bunch of EFI implementations | |
136 | * continue calling into boot services code (SetVirtualAddressMap). In order to | |
137 | * work around such buggy implementations we reserve boot services region during | |
138 | * EFI init and make sure it stays executable. Then, after SetVirtualAddressMap(), it | |
139 | * is discarded. | |
140 | */ | |
141 | void __init efi_reserve_boot_services(void) | |
142 | { | |
143 | void *p; | |
144 | ||
145 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | |
146 | efi_memory_desc_t *md = p; | |
147 | u64 start = md->phys_addr; | |
148 | u64 size = md->num_pages << EFI_PAGE_SHIFT; | |
149 | ||
150 | if (md->type != EFI_BOOT_SERVICES_CODE && | |
151 | md->type != EFI_BOOT_SERVICES_DATA) | |
152 | continue; | |
153 | /* Only reserve where possible: | |
154 | * - Not within any already allocated areas | |
155 | * - Not over any memory area (really needed, if above?) | |
156 | * - Not within any part of the kernel | |
157 | * - Not the bios reserved area | |
158 | */ | |
159 | if ((start + size > __pa_symbol(_text) | |
160 | && start <= __pa_symbol(_end)) || | |
161 | !e820_all_mapped(start, start+size, E820_RAM) || | |
162 | memblock_is_region_reserved(start, size)) { | |
163 | /* Could not reserve, skip it */ | |
164 | md->num_pages = 0; | |
165 | memblock_dbg("Could not reserve boot range [0x%010llx-0x%010llx]\n", | |
166 | start, start+size-1); | |
167 | } else | |
168 | memblock_reserve(start, size); | |
169 | } | |
170 | } | |
171 | ||
172 | void __init efi_free_boot_services(void) | |
173 | { | |
174 | void *p; | |
175 | ||
176 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | |
177 | efi_memory_desc_t *md = p; | |
178 | unsigned long long start = md->phys_addr; | |
179 | unsigned long long size = md->num_pages << EFI_PAGE_SHIFT; | |
180 | ||
181 | if (md->type != EFI_BOOT_SERVICES_CODE && | |
182 | md->type != EFI_BOOT_SERVICES_DATA) | |
183 | continue; | |
184 | ||
185 | /* Could not reserve boot area */ | |
186 | if (!size) | |
187 | continue; | |
188 | ||
189 | free_bootmem_late(start, size); | |
190 | } | |
191 | ||
192 | efi_unmap_memmap(); | |
193 | } | |
194 | ||
195 | /* | |
196 | * A number of config table entries get remapped to virtual addresses | |
197 | * after entering EFI virtual mode. However, the kexec kernel requires | |
198 | * their physical addresses therefore we pass them via setup_data and | |
199 | * correct those entries to their respective physical addresses here. | |
200 | * | |
201 | * Currently only handles smbios which is necessary for some firmware | |
202 | * implementation. | |
203 | */ | |
204 | int __init efi_reuse_config(u64 tables, int nr_tables) | |
205 | { | |
206 | int i, sz, ret = 0; | |
207 | void *p, *tablep; | |
208 | struct efi_setup_data *data; | |
209 | ||
210 | if (!efi_setup) | |
211 | return 0; | |
212 | ||
213 | if (!efi_enabled(EFI_64BIT)) | |
214 | return 0; | |
215 | ||
216 | data = early_memremap(efi_setup, sizeof(*data)); | |
217 | if (!data) { | |
218 | ret = -ENOMEM; | |
219 | goto out; | |
220 | } | |
221 | ||
222 | if (!data->smbios) | |
223 | goto out_memremap; | |
224 | ||
225 | sz = sizeof(efi_config_table_64_t); | |
226 | ||
227 | p = tablep = early_memremap(tables, nr_tables * sz); | |
228 | if (!p) { | |
229 | pr_err("Could not map Configuration table!\n"); | |
230 | ret = -ENOMEM; | |
231 | goto out_memremap; | |
232 | } | |
233 | ||
234 | for (i = 0; i < efi.systab->nr_tables; i++) { | |
235 | efi_guid_t guid; | |
236 | ||
237 | guid = ((efi_config_table_64_t *)p)->guid; | |
238 | ||
239 | if (!efi_guidcmp(guid, SMBIOS_TABLE_GUID)) | |
240 | ((efi_config_table_64_t *)p)->table = data->smbios; | |
241 | p += sz; | |
242 | } | |
98a716b6 | 243 | early_memunmap(tablep, nr_tables * sz); |
eeb9db09 ST |
244 | |
245 | out_memremap: | |
98a716b6 | 246 | early_memunmap(data, sizeof(*data)); |
eeb9db09 ST |
247 | out: |
248 | return ret; | |
249 | } | |
250 | ||
251 | void __init efi_apply_memmap_quirks(void) | |
252 | { | |
253 | /* | |
254 | * Once setup is done earlier, unmap the EFI memory map on mismatched | |
255 | * firmware/kernel architectures since there is no support for runtime | |
256 | * services. | |
257 | */ | |
258 | if (!efi_runtime_supported()) { | |
259 | pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n"); | |
260 | efi_unmap_memmap(); | |
261 | } | |
262 | ||
263 | /* | |
264 | * UV doesn't support the new EFI pagetable mapping yet. | |
265 | */ | |
266 | if (is_uv_system()) | |
267 | set_bit(EFI_OLD_MEMMAP, &efi.flags); | |
268 | } | |
44be28e9 MF |
269 | |
270 | /* | |
271 | * For most modern platforms the preferred method of powering off is via | |
272 | * ACPI. However, there are some that are known to require the use of | |
273 | * EFI runtime services and for which ACPI does not work at all. | |
274 | * | |
275 | * Using EFI is a last resort, to be used only if no other option | |
276 | * exists. | |
277 | */ | |
278 | bool efi_reboot_required(void) | |
279 | { | |
280 | if (!acpi_gbl_reduced_hardware) | |
281 | return false; | |
282 | ||
283 | efi_reboot_quirk_mode = EFI_RESET_WARM; | |
284 | return true; | |
285 | } | |
286 | ||
287 | bool efi_poweroff_required(void) | |
288 | { | |
289 | return !!acpi_gbl_reduced_hardware; | |
290 | } |