aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorMatthew Garrett <matthew.garrett@nebula.com>2013-04-15 16:09:46 -0400
committerMatt Fleming <matt.fleming@intel.com>2013-04-15 16:31:09 -0400
commitcc5a080c5d40c36089bb08a8a16fa3fc7047fe0f (patch)
treebd3160fc5b3ce71036d5e218ecd5e3dbf1632d02 /arch/x86
parent0635eb8a54cf0fea64b174bb68bc36b9c3d622db (diff)
efi: Pass boot services variable info to runtime code
EFI variables can be flagged as being accessible only within boot services. This makes it awkward for us to figure out how much space they use at runtime. In theory we could figure this out by simply comparing the results from QueryVariableInfo() to the space used by all of our variables, but that fails if the platform doesn't garbage collect on every boot. Thankfully, calling QueryVariableInfo() while still inside boot services gives a more reliable answer. This patch passes that information from the EFI boot stub up to the efi platform code. Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com> Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/boot/compressed/eboot.c47
-rw-r--r--arch/x86/include/asm/efi.h7
-rw-r--r--arch/x86/include/uapi/asm/bootparam.h1
-rw-r--r--arch/x86/platform/efi/efi.c21
4 files changed, 76 insertions, 0 deletions
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index c205035a6b96..8615f7581820 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -251,6 +251,51 @@ static void find_bits(unsigned long mask, u8 *pos, u8 *size)
251 *size = len; 251 *size = len;
252} 252}
253 253
254static efi_status_t setup_efi_vars(struct boot_params *params)
255{
256 struct setup_data *data;
257 struct efi_var_bootdata *efidata;
258 u64 store_size, remaining_size, var_size;
259 efi_status_t status;
260
261 if (!sys_table->runtime->query_variable_info)
262 return EFI_UNSUPPORTED;
263
264 data = (struct setup_data *)(unsigned long)params->hdr.setup_data;
265
266 while (data && data->next)
267 data = (struct setup_data *)(unsigned long)data->next;
268
269 status = efi_call_phys4(sys_table->runtime->query_variable_info,
270 EFI_VARIABLE_NON_VOLATILE |
271 EFI_VARIABLE_BOOTSERVICE_ACCESS |
272 EFI_VARIABLE_RUNTIME_ACCESS, &store_size,
273 &remaining_size, &var_size);
274
275 if (status != EFI_SUCCESS)
276 return status;
277
278 status = efi_call_phys3(sys_table->boottime->allocate_pool,
279 EFI_LOADER_DATA, sizeof(*efidata), &efidata);
280
281 if (status != EFI_SUCCESS)
282 return status;
283
284 efidata->data.type = SETUP_EFI_VARS;
285 efidata->data.len = sizeof(struct efi_var_bootdata) -
286 sizeof(struct setup_data);
287 efidata->data.next = 0;
288 efidata->store_size = store_size;
289 efidata->remaining_size = remaining_size;
290 efidata->max_var_size = var_size;
291
292 if (data)
293 data->next = (unsigned long)efidata;
294 else
295 params->hdr.setup_data = (unsigned long)efidata;
296
297}
298
254static efi_status_t setup_efi_pci(struct boot_params *params) 299static efi_status_t setup_efi_pci(struct boot_params *params)
255{ 300{
256 efi_pci_io_protocol *pci; 301 efi_pci_io_protocol *pci;
@@ -1157,6 +1202,8 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
1157 1202
1158 setup_graphics(boot_params); 1203 setup_graphics(boot_params);
1159 1204
1205 setup_efi_vars(boot_params);
1206
1160 setup_efi_pci(boot_params); 1207 setup_efi_pci(boot_params);
1161 1208
1162 status = efi_call_phys3(sys_table->boottime->allocate_pool, 1209 status = efi_call_phys3(sys_table->boottime->allocate_pool,
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index 60c89f30c727..2fb5d5884e23 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -102,6 +102,13 @@ extern void efi_call_phys_epilog(void);
102extern void efi_unmap_memmap(void); 102extern void efi_unmap_memmap(void);
103extern void efi_memory_uc(u64 addr, unsigned long size); 103extern void efi_memory_uc(u64 addr, unsigned long size);
104 104
105struct efi_var_bootdata {
106 struct setup_data data;
107 u64 store_size;
108 u64 remaining_size;
109 u64 max_var_size;
110};
111
105#ifdef CONFIG_EFI 112#ifdef CONFIG_EFI
106 113
107static inline bool efi_is_native(void) 114static inline bool efi_is_native(void)
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
index c15ddaf90710..08744242b8d2 100644
--- a/arch/x86/include/uapi/asm/bootparam.h
+++ b/arch/x86/include/uapi/asm/bootparam.h
@@ -6,6 +6,7 @@
6#define SETUP_E820_EXT 1 6#define SETUP_E820_EXT 1
7#define SETUP_DTB 2 7#define SETUP_DTB 2
8#define SETUP_PCI 3 8#define SETUP_PCI 3
9#define SETUP_EFI_VARS 4
9 10
10/* ram_size flags */ 11/* ram_size flags */
11#define RAMDISK_IMAGE_START_MASK 0x07FF 12#define RAMDISK_IMAGE_START_MASK 0x07FF
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 3f96a487aa2a..977d1ce7e173 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -69,6 +69,10 @@ struct efi_memory_map memmap;
69static struct efi efi_phys __initdata; 69static struct efi efi_phys __initdata;
70static efi_system_table_t efi_systab __initdata; 70static efi_system_table_t efi_systab __initdata;
71 71
72static u64 efi_var_store_size;
73static u64 efi_var_remaining_size;
74static u64 efi_var_max_var_size;
75
72unsigned long x86_efi_facility; 76unsigned long x86_efi_facility;
73 77
74/* 78/*
@@ -682,6 +686,9 @@ void __init efi_init(void)
682 char vendor[100] = "unknown"; 686 char vendor[100] = "unknown";
683 int i = 0; 687 int i = 0;
684 void *tmp; 688 void *tmp;
689 struct setup_data *data;
690 struct efi_var_bootdata *efi_var_data;
691 u64 pa_data;
685 692
686#ifdef CONFIG_X86_32 693#ifdef CONFIG_X86_32
687 if (boot_params.efi_info.efi_systab_hi || 694 if (boot_params.efi_info.efi_systab_hi ||
@@ -699,6 +706,20 @@ void __init efi_init(void)
699 if (efi_systab_init(efi_phys.systab)) 706 if (efi_systab_init(efi_phys.systab))
700 return; 707 return;
701 708
709 pa_data = boot_params.hdr.setup_data;
710 while (pa_data) {
711 data = early_ioremap(pa_data, sizeof(*efi_var_data));
712 if (data->type == SETUP_EFI_VARS) {
713 efi_var_data = (struct efi_var_bootdata *)data;
714
715 efi_var_store_size = efi_var_data->store_size;
716 efi_var_remaining_size = efi_var_data->remaining_size;
717 efi_var_max_var_size = efi_var_data->max_var_size;
718 }
719 pa_data = data->next;
720 early_iounmap(data, sizeof(*efi_var_data));
721 }
722
702 set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility); 723 set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility);
703 724
704 /* 725 /*