blob: 557a47829d03f2b14b0c3b664e1044e7e2cb86bc [file] [log] [blame]
Tom Gundersena9499fa2013-02-08 15:37:06 +00001/*
2 * efi.c - EFI subsystem
3 *
4 * Copyright (C) 2001,2003,2004 Dell <Matt_Domsch@dell.com>
5 * Copyright (C) 2004 Intel Corporation <matthew.e.tolentino@intel.com>
6 * Copyright (C) 2013 Tom Gundersen <teg@jklm.no>
7 *
8 * This code registers /sys/firmware/efi{,/efivars} when EFI is supported,
9 * allowing the efivarfs to be mounted or the efivars module to be loaded.
10 * The existance of /sys/firmware/efi may also be used by userspace to
11 * determine that the system supports EFI.
12 *
13 * This file is released under the GPLv2.
14 */
15
Leif Lindholm272686b2013-09-05 11:34:54 +010016#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17
Tom Gundersena9499fa2013-02-08 15:37:06 +000018#include <linux/kobject.h>
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/device.h>
22#include <linux/efi.h>
Mark Salter0302f712013-12-30 12:12:12 -050023#include <linux/of.h>
24#include <linux/of_fdt.h>
Leif Lindholm272686b2013-09-05 11:34:54 +010025#include <linux/io.h>
Ard Biesheuvel63625982016-11-12 21:32:31 +000026#include <linux/kexec.h>
Lee, Chun-Yi28d54022014-07-09 18:39:29 +080027#include <linux/platform_device.h>
Ard Biesheuvel63625982016-11-12 21:32:31 +000028#include <linux/random.h>
29#include <linux/reboot.h>
Octavian Purdila475fb4e2016-07-08 19:13:12 +030030#include <linux/slab.h>
31#include <linux/acpi.h>
32#include <linux/ucs2_string.h>
Matt Fleming816e7612016-02-29 21:22:52 +000033#include <linux/memblock.h>
Leif Lindholm272686b2013-09-05 11:34:54 +010034
Ard Biesheuvel0f7f2f02016-01-12 14:22:46 +010035#include <asm/early_ioremap.h>
Ard Biesheuvelf7d92482015-11-30 13:28:19 +010036
Leif Lindholm272686b2013-09-05 11:34:54 +010037struct efi __read_mostly efi = {
Ard Biesheuvelbf924862015-09-09 10:08:15 +020038 .mps = EFI_INVALID_TABLE_ADDR,
39 .acpi = EFI_INVALID_TABLE_ADDR,
40 .acpi20 = EFI_INVALID_TABLE_ADDR,
41 .smbios = EFI_INVALID_TABLE_ADDR,
42 .smbios3 = EFI_INVALID_TABLE_ADDR,
43 .sal_systab = EFI_INVALID_TABLE_ADDR,
44 .boot_info = EFI_INVALID_TABLE_ADDR,
45 .hcdp = EFI_INVALID_TABLE_ADDR,
46 .uga = EFI_INVALID_TABLE_ADDR,
47 .uv_systab = EFI_INVALID_TABLE_ADDR,
48 .fw_vendor = EFI_INVALID_TABLE_ADDR,
49 .runtime = EFI_INVALID_TABLE_ADDR,
50 .config_table = EFI_INVALID_TABLE_ADDR,
51 .esrt = EFI_INVALID_TABLE_ADDR,
52 .properties_table = EFI_INVALID_TABLE_ADDR,
Ard Biesheuvela604af02016-04-25 21:06:44 +010053 .mem_attr_table = EFI_INVALID_TABLE_ADDR,
Ard Biesheuvel63625982016-11-12 21:32:31 +000054 .rng_seed = EFI_INVALID_TABLE_ADDR,
Leif Lindholm272686b2013-09-05 11:34:54 +010055};
56EXPORT_SYMBOL(efi);
Tom Gundersena9499fa2013-02-08 15:37:06 +000057
Tom Lendackya19d66c2017-07-17 16:10:13 -050058static unsigned long *efi_tables[] = {
59 &efi.mps,
60 &efi.acpi,
61 &efi.acpi20,
62 &efi.smbios,
63 &efi.smbios3,
64 &efi.sal_systab,
65 &efi.boot_info,
66 &efi.hcdp,
67 &efi.uga,
68 &efi.uv_systab,
69 &efi.fw_vendor,
70 &efi.runtime,
71 &efi.config_table,
72 &efi.esrt,
73 &efi.properties_table,
74 &efi.mem_attr_table,
75};
76
Dave Youngb2e0a542014-08-14 17:15:26 +080077static bool disable_runtime;
78static int __init setup_noefi(char *arg)
79{
80 disable_runtime = true;
81 return 0;
82}
83early_param("noefi", setup_noefi);
84
85bool efi_runtime_disabled(void)
86{
87 return disable_runtime;
88}
89
Dave Young5ae36832014-08-14 17:15:28 +080090static int __init parse_efi_cmdline(char *str)
91{
Ricardo Neri9115c752015-07-15 19:36:03 -070092 if (!str) {
93 pr_warn("need at least one option\n");
94 return -EINVAL;
95 }
96
Leif Lindholm12dd00e2015-08-26 14:24:56 +010097 if (parse_option_str(str, "debug"))
98 set_bit(EFI_DBG, &efi.flags);
99
Dave Young5ae36832014-08-14 17:15:28 +0800100 if (parse_option_str(str, "noruntime"))
101 disable_runtime = true;
102
103 return 0;
104}
105early_param("efi", parse_efi_cmdline);
106
Peter Jones0bb54902015-04-28 18:44:31 -0400107struct kobject *efi_kobj;
Tom Gundersena9499fa2013-02-08 15:37:06 +0000108
109/*
110 * Let's not leave out systab information that snuck into
111 * the efivars driver
Dave Young0b02e442017-12-06 09:50:10 +0000112 * Note, do not add more fields in systab sysfs file as it breaks sysfs
113 * one value per file rule!
Tom Gundersena9499fa2013-02-08 15:37:06 +0000114 */
115static ssize_t systab_show(struct kobject *kobj,
116 struct kobj_attribute *attr, char *buf)
117{
118 char *str = buf;
119
120 if (!kobj || !buf)
121 return -EINVAL;
122
123 if (efi.mps != EFI_INVALID_TABLE_ADDR)
124 str += sprintf(str, "MPS=0x%lx\n", efi.mps);
125 if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
126 str += sprintf(str, "ACPI20=0x%lx\n", efi.acpi20);
127 if (efi.acpi != EFI_INVALID_TABLE_ADDR)
128 str += sprintf(str, "ACPI=0x%lx\n", efi.acpi);
Jean Delvareb119fe02015-04-30 15:23:05 +0200129 /*
130 * If both SMBIOS and SMBIOS3 entry points are implemented, the
131 * SMBIOS3 entry point shall be preferred, so we list it first to
132 * let applications stop parsing after the first match.
133 */
Ard Biesheuvele1ccbbc2014-10-14 16:34:47 +0200134 if (efi.smbios3 != EFI_INVALID_TABLE_ADDR)
135 str += sprintf(str, "SMBIOS3=0x%lx\n", efi.smbios3);
Jean Delvareb119fe02015-04-30 15:23:05 +0200136 if (efi.smbios != EFI_INVALID_TABLE_ADDR)
137 str += sprintf(str, "SMBIOS=0x%lx\n", efi.smbios);
Tom Gundersena9499fa2013-02-08 15:37:06 +0000138 if (efi.hcdp != EFI_INVALID_TABLE_ADDR)
139 str += sprintf(str, "HCDP=0x%lx\n", efi.hcdp);
140 if (efi.boot_info != EFI_INVALID_TABLE_ADDR)
141 str += sprintf(str, "BOOTINFO=0x%lx\n", efi.boot_info);
142 if (efi.uga != EFI_INVALID_TABLE_ADDR)
143 str += sprintf(str, "UGA=0x%lx\n", efi.uga);
144
145 return str - buf;
146}
147
Greg Kroah-Hartmanaf97a772017-12-06 09:50:08 +0000148static struct kobj_attribute efi_attr_systab = __ATTR_RO_MODE(systab, 0400);
Tom Gundersena9499fa2013-02-08 15:37:06 +0000149
Dave Younga0998eb2013-12-20 18:02:17 +0800150#define EFI_FIELD(var) efi.var
151
152#define EFI_ATTR_SHOW(name) \
153static ssize_t name##_show(struct kobject *kobj, \
154 struct kobj_attribute *attr, char *buf) \
155{ \
156 return sprintf(buf, "0x%lx\n", EFI_FIELD(name)); \
157}
158
159EFI_ATTR_SHOW(fw_vendor);
160EFI_ATTR_SHOW(runtime);
161EFI_ATTR_SHOW(config_table);
162
Steve McIntyre2859dff2015-01-09 15:29:53 +0000163static ssize_t fw_platform_size_show(struct kobject *kobj,
164 struct kobj_attribute *attr, char *buf)
165{
166 return sprintf(buf, "%d\n", efi_enabled(EFI_64BIT) ? 64 : 32);
167}
168
Dave Younga0998eb2013-12-20 18:02:17 +0800169static struct kobj_attribute efi_attr_fw_vendor = __ATTR_RO(fw_vendor);
170static struct kobj_attribute efi_attr_runtime = __ATTR_RO(runtime);
171static struct kobj_attribute efi_attr_config_table = __ATTR_RO(config_table);
Steve McIntyre2859dff2015-01-09 15:29:53 +0000172static struct kobj_attribute efi_attr_fw_platform_size =
173 __ATTR_RO(fw_platform_size);
Dave Younga0998eb2013-12-20 18:02:17 +0800174
Tom Gundersena9499fa2013-02-08 15:37:06 +0000175static struct attribute *efi_subsys_attrs[] = {
176 &efi_attr_systab.attr,
Dave Younga0998eb2013-12-20 18:02:17 +0800177 &efi_attr_fw_vendor.attr,
178 &efi_attr_runtime.attr,
179 &efi_attr_config_table.attr,
Steve McIntyre2859dff2015-01-09 15:29:53 +0000180 &efi_attr_fw_platform_size.attr,
Dave Younga0998eb2013-12-20 18:02:17 +0800181 NULL,
Tom Gundersena9499fa2013-02-08 15:37:06 +0000182};
183
Dave Younga0998eb2013-12-20 18:02:17 +0800184static umode_t efi_attr_is_visible(struct kobject *kobj,
185 struct attribute *attr, int n)
186{
Daniel Kiper9f27bc52014-06-30 19:52:58 +0200187 if (attr == &efi_attr_fw_vendor.attr) {
188 if (efi_enabled(EFI_PARAVIRT) ||
189 efi.fw_vendor == EFI_INVALID_TABLE_ADDR)
190 return 0;
191 } else if (attr == &efi_attr_runtime.attr) {
192 if (efi.runtime == EFI_INVALID_TABLE_ADDR)
193 return 0;
194 } else if (attr == &efi_attr_config_table.attr) {
195 if (efi.config_table == EFI_INVALID_TABLE_ADDR)
196 return 0;
197 }
Dave Younga0998eb2013-12-20 18:02:17 +0800198
Daniel Kiper9f27bc52014-06-30 19:52:58 +0200199 return attr->mode;
Dave Younga0998eb2013-12-20 18:02:17 +0800200}
201
Arvind Yadav3ad6bd72017-08-18 20:49:46 +0100202static const struct attribute_group efi_subsys_attr_group = {
Tom Gundersena9499fa2013-02-08 15:37:06 +0000203 .attrs = efi_subsys_attrs,
Dave Younga0998eb2013-12-20 18:02:17 +0800204 .is_visible = efi_attr_is_visible,
Tom Gundersena9499fa2013-02-08 15:37:06 +0000205};
206
207static struct efivars generic_efivars;
208static struct efivar_operations generic_ops;
209
210static int generic_ops_register(void)
211{
212 generic_ops.get_variable = efi.get_variable;
213 generic_ops.set_variable = efi.set_variable;
Ard Biesheuvel9c6672a2016-02-01 22:06:55 +0000214 generic_ops.set_variable_nonblocking = efi.set_variable_nonblocking;
Tom Gundersena9499fa2013-02-08 15:37:06 +0000215 generic_ops.get_next_variable = efi.get_next_variable;
Matt Fleminga614e192013-04-30 11:30:24 +0100216 generic_ops.query_variable_store = efi_query_variable_store;
Tom Gundersena9499fa2013-02-08 15:37:06 +0000217
218 return efivars_register(&generic_efivars, &generic_ops, efi_kobj);
219}
220
221static void generic_ops_unregister(void)
222{
223 efivars_unregister(&generic_efivars);
224}
225
Octavian Purdila475fb4e2016-07-08 19:13:12 +0300226#if IS_ENABLED(CONFIG_ACPI)
227#define EFIVAR_SSDT_NAME_MAX 16
228static char efivar_ssdt[EFIVAR_SSDT_NAME_MAX] __initdata;
229static int __init efivar_ssdt_setup(char *str)
230{
231 if (strlen(str) < sizeof(efivar_ssdt))
232 memcpy(efivar_ssdt, str, strlen(str));
233 else
234 pr_warn("efivar_ssdt: name too long: %s\n", str);
235 return 0;
236}
237__setup("efivar_ssdt=", efivar_ssdt_setup);
238
239static __init int efivar_ssdt_iter(efi_char16_t *name, efi_guid_t vendor,
240 unsigned long name_size, void *data)
241{
242 struct efivar_entry *entry;
243 struct list_head *list = data;
244 char utf8_name[EFIVAR_SSDT_NAME_MAX];
245 int limit = min_t(unsigned long, EFIVAR_SSDT_NAME_MAX, name_size);
246
247 ucs2_as_utf8(utf8_name, name, limit - 1);
248 if (strncmp(utf8_name, efivar_ssdt, limit) != 0)
249 return 0;
250
251 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
252 if (!entry)
253 return 0;
254
255 memcpy(entry->var.VariableName, name, name_size);
256 memcpy(&entry->var.VendorGuid, &vendor, sizeof(efi_guid_t));
257
258 efivar_entry_add(entry, list);
259
260 return 0;
261}
262
263static __init int efivar_ssdt_load(void)
264{
265 LIST_HEAD(entries);
266 struct efivar_entry *entry, *aux;
267 unsigned long size;
268 void *data;
269 int ret;
270
271 ret = efivar_init(efivar_ssdt_iter, &entries, true, &entries);
272
273 list_for_each_entry_safe(entry, aux, &entries, list) {
274 pr_info("loading SSDT from variable %s-%pUl\n", efivar_ssdt,
275 &entry->var.VendorGuid);
276
277 list_del(&entry->list);
278
279 ret = efivar_entry_size(entry, &size);
280 if (ret) {
281 pr_err("failed to get var size\n");
282 goto free_entry;
283 }
284
285 data = kmalloc(size, GFP_KERNEL);
Dan Carpentera75dcb52016-10-18 15:33:18 +0100286 if (!data) {
287 ret = -ENOMEM;
Octavian Purdila475fb4e2016-07-08 19:13:12 +0300288 goto free_entry;
Dan Carpentera75dcb52016-10-18 15:33:18 +0100289 }
Octavian Purdila475fb4e2016-07-08 19:13:12 +0300290
291 ret = efivar_entry_get(entry, NULL, &size, data);
292 if (ret) {
293 pr_err("failed to get var data\n");
294 goto free_data;
295 }
296
297 ret = acpi_load_table(data);
298 if (ret) {
299 pr_err("failed to load table: %d\n", ret);
300 goto free_data;
301 }
302
303 goto free_entry;
304
305free_data:
306 kfree(data);
307
308free_entry:
309 kfree(entry);
310 }
311
312 return ret;
313}
314#else
315static inline int efivar_ssdt_load(void) { return 0; }
316#endif
317
Tom Gundersena9499fa2013-02-08 15:37:06 +0000318/*
319 * We register the efi subsystem with the firmware subsystem and the
320 * efivars subsystem with the efi subsystem, if the system was booted with
321 * EFI.
322 */
323static int __init efisubsys_init(void)
324{
325 int error;
326
327 if (!efi_enabled(EFI_BOOT))
328 return 0;
329
330 /* We register the efi directory at /sys/firmware/efi */
331 efi_kobj = kobject_create_and_add("efi", firmware_kobj);
332 if (!efi_kobj) {
333 pr_err("efi: Firmware registration failed.\n");
334 return -ENOMEM;
335 }
336
337 error = generic_ops_register();
338 if (error)
339 goto err_put;
340
Octavian Purdila475fb4e2016-07-08 19:13:12 +0300341 if (efi_enabled(EFI_RUNTIME_SERVICES))
342 efivar_ssdt_load();
343
Tom Gundersena9499fa2013-02-08 15:37:06 +0000344 error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group);
345 if (error) {
346 pr_err("efi: Sysfs attribute export failed with error %d.\n",
347 error);
348 goto err_unregister;
349 }
350
Dave Young926172d2013-12-20 18:02:18 +0800351 error = efi_runtime_map_init(efi_kobj);
352 if (error)
353 goto err_remove_group;
354
Tom Gundersena9499fa2013-02-08 15:37:06 +0000355 /* and the standard mountpoint for efivarfs */
Eric W. Biedermanf9bb4882015-05-13 17:35:41 -0500356 error = sysfs_create_mount_point(efi_kobj, "efivars");
357 if (error) {
Tom Gundersena9499fa2013-02-08 15:37:06 +0000358 pr_err("efivars: Subsystem registration failed.\n");
Tom Gundersena9499fa2013-02-08 15:37:06 +0000359 goto err_remove_group;
360 }
361
362 return 0;
363
364err_remove_group:
365 sysfs_remove_group(efi_kobj, &efi_subsys_attr_group);
366err_unregister:
367 generic_ops_unregister();
368err_put:
369 kobject_put(efi_kobj);
370 return error;
371}
372
373subsys_initcall(efisubsys_init);
Leif Lindholm272686b2013-09-05 11:34:54 +0100374
Peter Jones0bb54902015-04-28 18:44:31 -0400375/*
376 * Find the efi memory descriptor for a given physical address. Given a
Matt Flemingdca0f972016-02-27 15:52:50 +0000377 * physical address, determine if it exists within an EFI Memory Map entry,
Peter Jones0bb54902015-04-28 18:44:31 -0400378 * and if so, populate the supplied memory descriptor with the appropriate
379 * data.
380 */
381int __init efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md)
382{
Matt Flemingdca0f972016-02-27 15:52:50 +0000383 efi_memory_desc_t *md;
Peter Jones0bb54902015-04-28 18:44:31 -0400384
385 if (!efi_enabled(EFI_MEMMAP)) {
386 pr_err_once("EFI_MEMMAP is not enabled.\n");
387 return -EINVAL;
388 }
389
Peter Jones0bb54902015-04-28 18:44:31 -0400390 if (!out_md) {
391 pr_err_once("out_md is null.\n");
392 return -EINVAL;
393 }
Peter Jones0bb54902015-04-28 18:44:31 -0400394
Matt Flemingdca0f972016-02-27 15:52:50 +0000395 for_each_efi_memory_desc(md) {
Peter Jones0bb54902015-04-28 18:44:31 -0400396 u64 size;
397 u64 end;
398
Peter Jones0bb54902015-04-28 18:44:31 -0400399 if (!(md->attribute & EFI_MEMORY_RUNTIME) &&
400 md->type != EFI_BOOT_SERVICES_DATA &&
401 md->type != EFI_RUNTIME_SERVICES_DATA) {
Peter Jones0bb54902015-04-28 18:44:31 -0400402 continue;
403 }
404
405 size = md->num_pages << EFI_PAGE_SHIFT;
406 end = md->phys_addr + size;
407 if (phys_addr >= md->phys_addr && phys_addr < end) {
408 memcpy(out_md, md, sizeof(*out_md));
Peter Jones0bb54902015-04-28 18:44:31 -0400409 return 0;
410 }
Peter Jones0bb54902015-04-28 18:44:31 -0400411 }
Peter Jones0bb54902015-04-28 18:44:31 -0400412 return -ENOENT;
413}
414
415/*
416 * Calculate the highest address of an efi memory descriptor.
417 */
418u64 __init efi_mem_desc_end(efi_memory_desc_t *md)
419{
420 u64 size = md->num_pages << EFI_PAGE_SHIFT;
421 u64 end = md->phys_addr + size;
422 return end;
423}
Leif Lindholm272686b2013-09-05 11:34:54 +0100424
Matt Fleming816e7612016-02-29 21:22:52 +0000425void __init __weak efi_arch_mem_reserve(phys_addr_t addr, u64 size) {}
426
427/**
428 * efi_mem_reserve - Reserve an EFI memory region
429 * @addr: Physical address to reserve
430 * @size: Size of reservation
431 *
432 * Mark a region as reserved from general kernel allocation and
433 * prevent it being released by efi_free_boot_services().
434 *
435 * This function should be called drivers once they've parsed EFI
436 * configuration tables to figure out where their data lives, e.g.
437 * efi_esrt_init().
438 */
439void __init efi_mem_reserve(phys_addr_t addr, u64 size)
440{
441 if (!memblock_is_region_reserved(addr, size))
442 memblock_reserve(addr, size);
443
444 /*
445 * Some architectures (x86) reserve all boot services ranges
446 * until efi_free_boot_services() because of buggy firmware
447 * implementations. This means the above memblock_reserve() is
448 * superfluous on x86 and instead what it needs to do is
449 * ensure the @start, @size is not freed.
450 */
451 efi_arch_mem_reserve(addr, size);
452}
453
Leif Lindholm272686b2013-09-05 11:34:54 +0100454static __initdata efi_config_table_type_t common_tables[] = {
455 {ACPI_20_TABLE_GUID, "ACPI 2.0", &efi.acpi20},
456 {ACPI_TABLE_GUID, "ACPI", &efi.acpi},
457 {HCDP_TABLE_GUID, "HCDP", &efi.hcdp},
458 {MPS_TABLE_GUID, "MPS", &efi.mps},
459 {SAL_SYSTEM_TABLE_GUID, "SALsystab", &efi.sal_systab},
460 {SMBIOS_TABLE_GUID, "SMBIOS", &efi.smbios},
Ard Biesheuvele1ccbbc2014-10-14 16:34:47 +0200461 {SMBIOS3_TABLE_GUID, "SMBIOS 3.0", &efi.smbios3},
Leif Lindholm272686b2013-09-05 11:34:54 +0100462 {UGA_IO_PROTOCOL_GUID, "UGA", &efi.uga},
Peter Jones0bb54902015-04-28 18:44:31 -0400463 {EFI_SYSTEM_RESOURCE_TABLE_GUID, "ESRT", &efi.esrt},
Ard Biesheuvelbf924862015-09-09 10:08:15 +0200464 {EFI_PROPERTIES_TABLE_GUID, "PROP", &efi.properties_table},
Ard Biesheuvela604af02016-04-25 21:06:44 +0100465 {EFI_MEMORY_ATTRIBUTES_TABLE_GUID, "MEMATTR", &efi.mem_attr_table},
Ard Biesheuvel63625982016-11-12 21:32:31 +0000466 {LINUX_EFI_RANDOM_SEED_TABLE_GUID, "RNG", &efi.rng_seed},
Daeseok Youn69e60842014-02-13 17:16:36 +0900467 {NULL_GUID, NULL, NULL},
Leif Lindholm272686b2013-09-05 11:34:54 +0100468};
469
470static __init int match_config_table(efi_guid_t *guid,
471 unsigned long table,
472 efi_config_table_type_t *table_types)
473{
Leif Lindholm272686b2013-09-05 11:34:54 +0100474 int i;
475
476 if (table_types) {
Leif Lindholm272686b2013-09-05 11:34:54 +0100477 for (i = 0; efi_guidcmp(table_types[i].guid, NULL_GUID); i++) {
Leif Lindholm272686b2013-09-05 11:34:54 +0100478 if (!efi_guidcmp(*guid, table_types[i].guid)) {
479 *(table_types[i].ptr) = table;
Ard Biesheuvel801820b2016-04-25 21:06:53 +0100480 if (table_types[i].name)
481 pr_cont(" %s=0x%lx ",
482 table_types[i].name, table);
Leif Lindholm272686b2013-09-05 11:34:54 +0100483 return 1;
484 }
485 }
486 }
487
488 return 0;
489}
490
Ard Biesheuvel7bb68412014-10-18 15:04:15 +0200491int __init efi_config_parse_tables(void *config_tables, int count, int sz,
492 efi_config_table_type_t *arch_tables)
493{
494 void *tablep;
495 int i;
496
497 tablep = config_tables;
498 pr_info("");
499 for (i = 0; i < count; i++) {
500 efi_guid_t guid;
501 unsigned long table;
502
503 if (efi_enabled(EFI_64BIT)) {
504 u64 table64;
505 guid = ((efi_config_table_64_t *)tablep)->guid;
506 table64 = ((efi_config_table_64_t *)tablep)->table;
507 table = table64;
508#ifndef CONFIG_64BIT
509 if (table64 >> 32) {
510 pr_cont("\n");
511 pr_err("Table located above 4GB, disabling EFI.\n");
512 return -EINVAL;
513 }
514#endif
515 } else {
516 guid = ((efi_config_table_32_t *)tablep)->guid;
517 table = ((efi_config_table_32_t *)tablep)->table;
518 }
519
520 if (!match_config_table(&guid, table, common_tables))
521 match_config_table(&guid, table, arch_tables);
522
523 tablep += sz;
524 }
525 pr_cont("\n");
526 set_bit(EFI_CONFIG_TABLES, &efi.flags);
Ard Biesheuvela1041712015-09-23 07:29:34 -0700527
Ard Biesheuvel63625982016-11-12 21:32:31 +0000528 if (efi.rng_seed != EFI_INVALID_TABLE_ADDR) {
529 struct linux_efi_random_seed *seed;
530 u32 size = 0;
531
532 seed = early_memremap(efi.rng_seed, sizeof(*seed));
533 if (seed != NULL) {
534 size = seed->size;
535 early_memunmap(seed, sizeof(*seed));
536 } else {
537 pr_err("Could not map UEFI random seed!\n");
538 }
539 if (size > 0) {
540 seed = early_memremap(efi.rng_seed,
541 sizeof(*seed) + size);
542 if (seed != NULL) {
543 add_device_randomness(seed->bits, seed->size);
544 early_memunmap(seed, sizeof(*seed) + size);
Ard Biesheuvelc2ceb5f2017-08-25 16:50:16 +0100545 pr_notice("seeding entropy pool\n");
Ard Biesheuvel63625982016-11-12 21:32:31 +0000546 } else {
547 pr_err("Could not map UEFI random seed!\n");
548 }
549 }
550 }
551
Daniel Kiper457ea3f2017-06-22 12:51:36 +0200552 if (efi_enabled(EFI_MEMMAP))
553 efi_memattr_init();
Sai Praneeth3a6b6c62017-01-31 13:21:35 +0000554
Ard Biesheuvela1041712015-09-23 07:29:34 -0700555 /* Parse the EFI Properties table if it exists */
556 if (efi.properties_table != EFI_INVALID_TABLE_ADDR) {
557 efi_properties_table_t *tbl;
558
559 tbl = early_memremap(efi.properties_table, sizeof(*tbl));
560 if (tbl == NULL) {
561 pr_err("Could not map Properties table!\n");
562 return -ENOMEM;
563 }
564
565 if (tbl->memory_protection_attribute &
566 EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA)
567 set_bit(EFI_NX_PE_DATA, &efi.flags);
568
569 early_memunmap(tbl, sizeof(*tbl));
570 }
571
Ard Biesheuvel7bb68412014-10-18 15:04:15 +0200572 return 0;
573}
574
Leif Lindholm272686b2013-09-05 11:34:54 +0100575int __init efi_config_init(efi_config_table_type_t *arch_tables)
576{
Ard Biesheuvel7bb68412014-10-18 15:04:15 +0200577 void *config_tables;
578 int sz, ret;
Leif Lindholm272686b2013-09-05 11:34:54 +0100579
580 if (efi_enabled(EFI_64BIT))
581 sz = sizeof(efi_config_table_64_t);
582 else
583 sz = sizeof(efi_config_table_32_t);
584
585 /*
586 * Let's see what config tables the firmware passed to us.
587 */
588 config_tables = early_memremap(efi.systab->tables,
589 efi.systab->nr_tables * sz);
590 if (config_tables == NULL) {
591 pr_err("Could not map Configuration table!\n");
592 return -ENOMEM;
593 }
594
Ard Biesheuvel7bb68412014-10-18 15:04:15 +0200595 ret = efi_config_parse_tables(config_tables, efi.systab->nr_tables, sz,
596 arch_tables);
Leif Lindholm272686b2013-09-05 11:34:54 +0100597
Daniel Kiperabc93f82014-06-30 19:52:56 +0200598 early_memunmap(config_tables, efi.systab->nr_tables * sz);
Ard Biesheuvel7bb68412014-10-18 15:04:15 +0200599 return ret;
Leif Lindholm272686b2013-09-05 11:34:54 +0100600}
Mark Salter0302f712013-12-30 12:12:12 -0500601
Lee, Chun-Yi28d54022014-07-09 18:39:29 +0800602#ifdef CONFIG_EFI_VARS_MODULE
603static int __init efi_load_efivars(void)
604{
605 struct platform_device *pdev;
606
607 if (!efi_enabled(EFI_RUNTIME_SERVICES))
608 return 0;
609
610 pdev = platform_device_register_simple("efivars", 0, NULL, 0);
611 return IS_ERR(pdev) ? PTR_ERR(pdev) : 0;
612}
613device_initcall(efi_load_efivars);
614#endif
615
Mark Salter0302f712013-12-30 12:12:12 -0500616#ifdef CONFIG_EFI_PARAMS_FROM_FDT
617
618#define UEFI_PARAM(name, prop, field) \
619 { \
620 { name }, \
621 { prop }, \
622 offsetof(struct efi_fdt_params, field), \
623 FIELD_SIZEOF(struct efi_fdt_params, field) \
624 }
625
Shannon Zhao0cac5c32016-05-12 20:19:54 +0800626struct params {
Mark Salter0302f712013-12-30 12:12:12 -0500627 const char name[32];
628 const char propname[32];
629 int offset;
630 int size;
Shannon Zhao0cac5c32016-05-12 20:19:54 +0800631};
632
633static __initdata struct params fdt_params[] = {
Mark Salter0302f712013-12-30 12:12:12 -0500634 UEFI_PARAM("System Table", "linux,uefi-system-table", system_table),
635 UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
636 UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
637 UEFI_PARAM("MemMap Desc. Size", "linux,uefi-mmap-desc-size", desc_size),
638 UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
639};
640
Shannon Zhao0cac5c32016-05-12 20:19:54 +0800641static __initdata struct params xen_fdt_params[] = {
642 UEFI_PARAM("System Table", "xen,uefi-system-table", system_table),
643 UEFI_PARAM("MemMap Address", "xen,uefi-mmap-start", mmap),
644 UEFI_PARAM("MemMap Size", "xen,uefi-mmap-size", mmap_size),
645 UEFI_PARAM("MemMap Desc. Size", "xen,uefi-mmap-desc-size", desc_size),
646 UEFI_PARAM("MemMap Desc. Version", "xen,uefi-mmap-desc-ver", desc_ver)
647};
648
649#define EFI_FDT_PARAMS_SIZE ARRAY_SIZE(fdt_params)
650
651static __initdata struct {
652 const char *uname;
653 const char *subnode;
654 struct params *params;
655} dt_params[] = {
656 { "hypervisor", "uefi", xen_fdt_params },
657 { "chosen", NULL, fdt_params },
658};
659
Mark Salter0302f712013-12-30 12:12:12 -0500660struct param_info {
Catalin Marinas29e24352014-07-08 16:54:18 +0100661 int found;
Mark Salter0302f712013-12-30 12:12:12 -0500662 void *params;
Shannon Zhao0cac5c32016-05-12 20:19:54 +0800663 const char *missing;
Mark Salter0302f712013-12-30 12:12:12 -0500664};
665
Shannon Zhao0cac5c32016-05-12 20:19:54 +0800666static int __init __find_uefi_params(unsigned long node,
667 struct param_info *info,
668 struct params *params)
Mark Salter0302f712013-12-30 12:12:12 -0500669{
Catalin Marinas6fb8cc82014-06-02 11:31:06 +0100670 const void *prop;
671 void *dest;
Mark Salter0302f712013-12-30 12:12:12 -0500672 u64 val;
Catalin Marinas6fb8cc82014-06-02 11:31:06 +0100673 int i, len;
Mark Salter0302f712013-12-30 12:12:12 -0500674
Shannon Zhao0cac5c32016-05-12 20:19:54 +0800675 for (i = 0; i < EFI_FDT_PARAMS_SIZE; i++) {
676 prop = of_get_flat_dt_prop(node, params[i].propname, &len);
677 if (!prop) {
678 info->missing = params[i].name;
Mark Salter0302f712013-12-30 12:12:12 -0500679 return 0;
Shannon Zhao0cac5c32016-05-12 20:19:54 +0800680 }
681
682 dest = info->params + params[i].offset;
Catalin Marinas29e24352014-07-08 16:54:18 +0100683 info->found++;
Mark Salter0302f712013-12-30 12:12:12 -0500684
685 val = of_read_number(prop, len / sizeof(u32));
686
Shannon Zhao0cac5c32016-05-12 20:19:54 +0800687 if (params[i].size == sizeof(u32))
Mark Salter0302f712013-12-30 12:12:12 -0500688 *(u32 *)dest = val;
689 else
690 *(u64 *)dest = val;
691
Leif Lindholm7968c0e2015-08-26 14:24:58 +0100692 if (efi_enabled(EFI_DBG))
Shannon Zhao0cac5c32016-05-12 20:19:54 +0800693 pr_info(" %s: 0x%0*llx\n", params[i].name,
694 params[i].size * 2, val);
Mark Salter0302f712013-12-30 12:12:12 -0500695 }
Shannon Zhao0cac5c32016-05-12 20:19:54 +0800696
Mark Salter0302f712013-12-30 12:12:12 -0500697 return 1;
698}
699
Shannon Zhao0cac5c32016-05-12 20:19:54 +0800700static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
701 int depth, void *data)
702{
703 struct param_info *info = data;
704 int i;
705
706 for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
707 const char *subnode = dt_params[i].subnode;
708
709 if (depth != 1 || strcmp(uname, dt_params[i].uname) != 0) {
710 info->missing = dt_params[i].params[0].name;
711 continue;
712 }
713
714 if (subnode) {
Andrzej Hajda4af9ed52016-08-30 12:41:37 +0200715 int err = of_get_flat_dt_subnode_by_name(node, subnode);
716
717 if (err < 0)
Shannon Zhao0cac5c32016-05-12 20:19:54 +0800718 return 0;
Andrzej Hajda4af9ed52016-08-30 12:41:37 +0200719
720 node = err;
Shannon Zhao0cac5c32016-05-12 20:19:54 +0800721 }
722
723 return __find_uefi_params(node, info, dt_params[i].params);
724 }
725
726 return 0;
727}
728
Leif Lindholm7968c0e2015-08-26 14:24:58 +0100729int __init efi_get_fdt_params(struct efi_fdt_params *params)
Mark Salter0302f712013-12-30 12:12:12 -0500730{
731 struct param_info info;
Catalin Marinas29e24352014-07-08 16:54:18 +0100732 int ret;
733
734 pr_info("Getting EFI parameters from FDT:\n");
Mark Salter0302f712013-12-30 12:12:12 -0500735
Catalin Marinas29e24352014-07-08 16:54:18 +0100736 info.found = 0;
Mark Salter0302f712013-12-30 12:12:12 -0500737 info.params = params;
738
Catalin Marinas29e24352014-07-08 16:54:18 +0100739 ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
740 if (!info.found)
741 pr_info("UEFI not found.\n");
742 else if (!ret)
743 pr_err("Can't find '%s' in device tree!\n",
Shannon Zhao0cac5c32016-05-12 20:19:54 +0800744 info.missing);
Catalin Marinas29e24352014-07-08 16:54:18 +0100745
746 return ret;
Mark Salter0302f712013-12-30 12:12:12 -0500747}
748#endif /* CONFIG_EFI_PARAMS_FROM_FDT */
Laszlo Ersek98d2a6c2014-09-03 13:32:20 +0200749
750static __initdata char memory_type_name[][20] = {
751 "Reserved",
752 "Loader Code",
753 "Loader Data",
754 "Boot Code",
755 "Boot Data",
756 "Runtime Code",
757 "Runtime Data",
758 "Conventional Memory",
759 "Unusable Memory",
760 "ACPI Reclaim Memory",
761 "ACPI Memory NVS",
762 "Memory Mapped I/O",
763 "MMIO Port Space",
Robert Elliott35575e02016-02-01 22:07:07 +0000764 "PAL Code",
765 "Persistent Memory",
Laszlo Ersek98d2a6c2014-09-03 13:32:20 +0200766};
767
768char * __init efi_md_typeattr_format(char *buf, size_t size,
769 const efi_memory_desc_t *md)
770{
771 char *pos;
772 int type_len;
773 u64 attr;
774
775 pos = buf;
776 if (md->type >= ARRAY_SIZE(memory_type_name))
777 type_len = snprintf(pos, size, "[type=%u", md->type);
778 else
779 type_len = snprintf(pos, size, "[%-*s",
780 (int)(sizeof(memory_type_name[0]) - 1),
781 memory_type_name[md->type]);
782 if (type_len >= size)
783 return buf;
784
785 pos += type_len;
786 size -= type_len;
787
788 attr = md->attribute;
789 if (attr & ~(EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT |
Ard Biesheuvel87db73ae2015-08-07 09:36:54 +0100790 EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_RO |
791 EFI_MEMORY_WP | EFI_MEMORY_RP | EFI_MEMORY_XP |
Robert Elliottc016ca02016-02-01 22:07:06 +0000792 EFI_MEMORY_NV |
Taku Izumi8be44322015-08-27 02:11:19 +0900793 EFI_MEMORY_RUNTIME | EFI_MEMORY_MORE_RELIABLE))
Laszlo Ersek98d2a6c2014-09-03 13:32:20 +0200794 snprintf(pos, size, "|attr=0x%016llx]",
795 (unsigned long long)attr);
796 else
Robert Elliottc016ca02016-02-01 22:07:06 +0000797 snprintf(pos, size,
798 "|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]",
Laszlo Ersek98d2a6c2014-09-03 13:32:20 +0200799 attr & EFI_MEMORY_RUNTIME ? "RUN" : "",
Taku Izumi8be44322015-08-27 02:11:19 +0900800 attr & EFI_MEMORY_MORE_RELIABLE ? "MR" : "",
Robert Elliottc016ca02016-02-01 22:07:06 +0000801 attr & EFI_MEMORY_NV ? "NV" : "",
Laszlo Ersek98d2a6c2014-09-03 13:32:20 +0200802 attr & EFI_MEMORY_XP ? "XP" : "",
803 attr & EFI_MEMORY_RP ? "RP" : "",
804 attr & EFI_MEMORY_WP ? "WP" : "",
Ard Biesheuvel87db73ae2015-08-07 09:36:54 +0100805 attr & EFI_MEMORY_RO ? "RO" : "",
Laszlo Ersek98d2a6c2014-09-03 13:32:20 +0200806 attr & EFI_MEMORY_UCE ? "UCE" : "",
807 attr & EFI_MEMORY_WB ? "WB" : "",
808 attr & EFI_MEMORY_WT ? "WT" : "",
809 attr & EFI_MEMORY_WC ? "WC" : "",
810 attr & EFI_MEMORY_UC ? "UC" : "");
811 return buf;
812}
Jonathan (Zhixiong) Zhang7bf79312015-08-07 09:36:57 +0100813
814/*
Jan Beulich23f05712017-08-25 16:50:18 +0100815 * IA64 has a funky EFI memory map that doesn't work the same way as
816 * other architectures.
817 */
818#ifndef CONFIG_IA64
819/*
Jonathan (Zhixiong) Zhang7bf79312015-08-07 09:36:57 +0100820 * efi_mem_attributes - lookup memmap attributes for physical address
821 * @phys_addr: the physical address to lookup
822 *
823 * Search in the EFI memory map for the region covering
824 * @phys_addr. Returns the EFI memory attributes if the region
825 * was found in the memory map, 0 otherwise.
Jonathan (Zhixiong) Zhang7bf79312015-08-07 09:36:57 +0100826 */
Jan Beulich23f05712017-08-25 16:50:18 +0100827u64 efi_mem_attributes(unsigned long phys_addr)
Jonathan (Zhixiong) Zhang7bf79312015-08-07 09:36:57 +0100828{
829 efi_memory_desc_t *md;
Jonathan (Zhixiong) Zhang7bf79312015-08-07 09:36:57 +0100830
831 if (!efi_enabled(EFI_MEMMAP))
832 return 0;
833
Matt Fleming78ce2482016-04-25 21:06:38 +0100834 for_each_efi_memory_desc(md) {
Jonathan (Zhixiong) Zhang7bf79312015-08-07 09:36:57 +0100835 if ((md->phys_addr <= phys_addr) &&
836 (phys_addr < (md->phys_addr +
837 (md->num_pages << EFI_PAGE_SHIFT))))
838 return md->attribute;
839 }
840 return 0;
841}
Matt Fleming806b0352016-04-25 21:06:58 +0100842
Jan Beulich23f05712017-08-25 16:50:18 +0100843/*
844 * efi_mem_type - lookup memmap type for physical address
845 * @phys_addr: the physical address to lookup
846 *
847 * Search in the EFI memory map for the region covering @phys_addr.
848 * Returns the EFI memory type if the region was found in the memory
849 * map, EFI_RESERVED_TYPE (zero) otherwise.
850 */
851int efi_mem_type(unsigned long phys_addr)
852{
853 const efi_memory_desc_t *md;
854
855 if (!efi_enabled(EFI_MEMMAP))
856 return -ENOTSUPP;
857
858 for_each_efi_memory_desc(md) {
859 if ((md->phys_addr <= phys_addr) &&
860 (phys_addr < (md->phys_addr +
861 (md->num_pages << EFI_PAGE_SHIFT))))
862 return md->type;
863 }
864 return -EINVAL;
865}
866#endif
867
Matt Fleming806b0352016-04-25 21:06:58 +0100868int efi_status_to_err(efi_status_t status)
869{
870 int err;
871
872 switch (status) {
873 case EFI_SUCCESS:
874 err = 0;
875 break;
876 case EFI_INVALID_PARAMETER:
877 err = -EINVAL;
878 break;
879 case EFI_OUT_OF_RESOURCES:
880 err = -ENOSPC;
881 break;
882 case EFI_DEVICE_ERROR:
883 err = -EIO;
884 break;
885 case EFI_WRITE_PROTECTED:
886 err = -EROFS;
887 break;
888 case EFI_SECURITY_VIOLATION:
889 err = -EACCES;
890 break;
891 case EFI_NOT_FOUND:
892 err = -ENOENT;
893 break;
Ard Biesheuveldce48e32016-07-15 21:36:31 +0200894 case EFI_ABORTED:
895 err = -EINTR;
896 break;
Matt Fleming806b0352016-04-25 21:06:58 +0100897 default:
898 err = -EINVAL;
899 }
900
901 return err;
902}
Ard Biesheuvel63625982016-11-12 21:32:31 +0000903
Tom Lendackya19d66c2017-07-17 16:10:13 -0500904bool efi_is_table_address(unsigned long phys_addr)
905{
906 unsigned int i;
907
908 if (phys_addr == EFI_INVALID_TABLE_ADDR)
909 return false;
910
911 for (i = 0; i < ARRAY_SIZE(efi_tables); i++)
912 if (*(efi_tables[i]) == phys_addr)
913 return true;
914
915 return false;
916}
917
Ard Biesheuvel63625982016-11-12 21:32:31 +0000918#ifdef CONFIG_KEXEC
919static int update_efi_random_seed(struct notifier_block *nb,
920 unsigned long code, void *unused)
921{
922 struct linux_efi_random_seed *seed;
923 u32 size = 0;
924
925 if (!kexec_in_progress)
926 return NOTIFY_DONE;
927
928 seed = memremap(efi.rng_seed, sizeof(*seed), MEMREMAP_WB);
929 if (seed != NULL) {
Ard Biesheuvelc2ceb5f2017-08-25 16:50:16 +0100930 size = min(seed->size, EFI_RANDOM_SEED_SIZE);
Ard Biesheuvel63625982016-11-12 21:32:31 +0000931 memunmap(seed);
932 } else {
933 pr_err("Could not map UEFI random seed!\n");
934 }
935 if (size > 0) {
936 seed = memremap(efi.rng_seed, sizeof(*seed) + size,
937 MEMREMAP_WB);
938 if (seed != NULL) {
939 seed->size = size;
940 get_random_bytes(seed->bits, seed->size);
941 memunmap(seed);
942 } else {
943 pr_err("Could not map UEFI random seed!\n");
944 }
945 }
946 return NOTIFY_DONE;
947}
948
949static struct notifier_block efi_random_seed_nb = {
950 .notifier_call = update_efi_random_seed,
951};
952
953static int register_update_efi_random_seed(void)
954{
955 if (efi.rng_seed == EFI_INVALID_TABLE_ADDR)
956 return 0;
957 return register_reboot_notifier(&efi_random_seed_nb);
958}
959late_initcall(register_update_efi_random_seed);
960#endif