aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/platform/efi/efi.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/platform/efi/efi.c')
-rw-r--r--arch/x86/platform/efi/efi.c193
1 files changed, 70 insertions, 123 deletions
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index dd3b82530145..90f6ed127096 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -42,7 +42,6 @@
42#include <linux/io.h> 42#include <linux/io.h>
43#include <linux/reboot.h> 43#include <linux/reboot.h>
44#include <linux/bcd.h> 44#include <linux/bcd.h>
45#include <linux/ucs2_string.h>
46 45
47#include <asm/setup.h> 46#include <asm/setup.h>
48#include <asm/efi.h> 47#include <asm/efi.h>
@@ -54,12 +53,12 @@
54 53
55#define EFI_DEBUG 1 54#define EFI_DEBUG 1
56 55
57/* 56#define EFI_MIN_RESERVE 5120
58 * There's some additional metadata associated with each 57
59 * variable. Intel's reference implementation is 60 bytes - bump that 58#define EFI_DUMMY_GUID \
60 * to account for potential alignment constraints 59 EFI_GUID(0x4424ac57, 0xbe4b, 0x47dd, 0x9e, 0x97, 0xed, 0x50, 0xf0, 0x9f, 0x92, 0xa9)
61 */ 60
62#define VAR_METADATA_SIZE 64 61static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 };
63 62
64struct efi __read_mostly efi = { 63struct efi __read_mostly efi = {
65 .mps = EFI_INVALID_TABLE_ADDR, 64 .mps = EFI_INVALID_TABLE_ADDR,
@@ -79,13 +78,6 @@ struct efi_memory_map memmap;
79static struct efi efi_phys __initdata; 78static struct efi efi_phys __initdata;
80static efi_system_table_t efi_systab __initdata; 79static efi_system_table_t efi_systab __initdata;
81 80
82static u64 efi_var_store_size;
83static u64 efi_var_remaining_size;
84static u64 efi_var_max_var_size;
85static u64 boot_used_size;
86static u64 boot_var_size;
87static u64 active_size;
88
89unsigned long x86_efi_facility; 81unsigned long x86_efi_facility;
90 82
91/* 83/*
@@ -188,53 +180,8 @@ static efi_status_t virt_efi_get_next_variable(unsigned long *name_size,
188 efi_char16_t *name, 180 efi_char16_t *name,
189 efi_guid_t *vendor) 181 efi_guid_t *vendor)
190{ 182{
191 efi_status_t status; 183 return efi_call_virt3(get_next_variable,
192 static bool finished = false; 184 name_size, name, vendor);
193 static u64 var_size;
194
195 status = efi_call_virt3(get_next_variable,
196 name_size, name, vendor);
197
198 if (status == EFI_NOT_FOUND) {
199 finished = true;
200 if (var_size < boot_used_size) {
201 boot_var_size = boot_used_size - var_size;
202 active_size += boot_var_size;
203 } else {
204 printk(KERN_WARNING FW_BUG "efi: Inconsistent initial sizes\n");
205 }
206 }
207
208 if (boot_used_size && !finished) {
209 unsigned long size;
210 u32 attr;
211 efi_status_t s;
212 void *tmp;
213
214 s = virt_efi_get_variable(name, vendor, &attr, &size, NULL);
215
216 if (s != EFI_BUFFER_TOO_SMALL || !size)
217 return status;
218
219 tmp = kmalloc(size, GFP_ATOMIC);
220
221 if (!tmp)
222 return status;
223
224 s = virt_efi_get_variable(name, vendor, &attr, &size, tmp);
225
226 if (s == EFI_SUCCESS && (attr & EFI_VARIABLE_NON_VOLATILE)) {
227 var_size += size;
228 var_size += ucs2_strsize(name, 1024);
229 active_size += size;
230 active_size += VAR_METADATA_SIZE;
231 active_size += ucs2_strsize(name, 1024);
232 }
233
234 kfree(tmp);
235 }
236
237 return status;
238} 185}
239 186
240static efi_status_t virt_efi_set_variable(efi_char16_t *name, 187static efi_status_t virt_efi_set_variable(efi_char16_t *name,
@@ -243,34 +190,9 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name,
243 unsigned long data_size, 190 unsigned long data_size,
244 void *data) 191 void *data)
245{ 192{
246 efi_status_t status; 193 return efi_call_virt5(set_variable,
247 u32 orig_attr = 0; 194 name, vendor, attr,
248 unsigned long orig_size = 0; 195 data_size, data);
249
250 status = virt_efi_get_variable(name, vendor, &orig_attr, &orig_size,
251 NULL);
252
253 if (status != EFI_BUFFER_TOO_SMALL)
254 orig_size = 0;
255
256 status = efi_call_virt5(set_variable,
257 name, vendor, attr,
258 data_size, data);
259
260 if (status == EFI_SUCCESS) {
261 if (orig_size) {
262 active_size -= orig_size;
263 active_size -= ucs2_strsize(name, 1024);
264 active_size -= VAR_METADATA_SIZE;
265 }
266 if (data_size) {
267 active_size += data_size;
268 active_size += ucs2_strsize(name, 1024);
269 active_size += VAR_METADATA_SIZE;
270 }
271 }
272
273 return status;
274} 196}
275 197
276static efi_status_t virt_efi_query_variable_info(u32 attr, 198static efi_status_t virt_efi_query_variable_info(u32 attr,
@@ -788,9 +710,6 @@ void __init efi_init(void)
788 char vendor[100] = "unknown"; 710 char vendor[100] = "unknown";
789 int i = 0; 711 int i = 0;
790 void *tmp; 712 void *tmp;
791 struct setup_data *data;
792 struct efi_var_bootdata *efi_var_data;
793 u64 pa_data;
794 713
795#ifdef CONFIG_X86_32 714#ifdef CONFIG_X86_32
796 if (boot_params.efi_info.efi_systab_hi || 715 if (boot_params.efi_info.efi_systab_hi ||
@@ -808,22 +727,6 @@ void __init efi_init(void)
808 if (efi_systab_init(efi_phys.systab)) 727 if (efi_systab_init(efi_phys.systab))
809 return; 728 return;
810 729
811 pa_data = boot_params.hdr.setup_data;
812 while (pa_data) {
813 data = early_ioremap(pa_data, sizeof(*efi_var_data));
814 if (data->type == SETUP_EFI_VARS) {
815 efi_var_data = (struct efi_var_bootdata *)data;
816
817 efi_var_store_size = efi_var_data->store_size;
818 efi_var_remaining_size = efi_var_data->remaining_size;
819 efi_var_max_var_size = efi_var_data->max_var_size;
820 }
821 pa_data = data->next;
822 early_iounmap(data, sizeof(*efi_var_data));
823 }
824
825 boot_used_size = efi_var_store_size - efi_var_remaining_size;
826
827 set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility); 730 set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility);
828 731
829 /* 732 /*
@@ -1087,6 +990,13 @@ void __init efi_enter_virtual_mode(void)
1087 runtime_code_page_mkexec(); 990 runtime_code_page_mkexec();
1088 991
1089 kfree(new_memmap); 992 kfree(new_memmap);
993
994 /* clean DUMMY object */
995 efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID,
996 EFI_VARIABLE_NON_VOLATILE |
997 EFI_VARIABLE_BOOTSERVICE_ACCESS |
998 EFI_VARIABLE_RUNTIME_ACCESS,
999 0, NULL);
1090} 1000}
1091 1001
1092/* 1002/*
@@ -1138,33 +1048,70 @@ efi_status_t efi_query_variable_store(u32 attributes, unsigned long size)
1138 efi_status_t status; 1048 efi_status_t status;
1139 u64 storage_size, remaining_size, max_size; 1049 u64 storage_size, remaining_size, max_size;
1140 1050
1051 if (!(attributes & EFI_VARIABLE_NON_VOLATILE))
1052 return 0;
1053
1141 status = efi.query_variable_info(attributes, &storage_size, 1054 status = efi.query_variable_info(attributes, &storage_size,
1142 &remaining_size, &max_size); 1055 &remaining_size, &max_size);
1143 if (status != EFI_SUCCESS) 1056 if (status != EFI_SUCCESS)
1144 return status; 1057 return status;
1145 1058
1146 if (!max_size && remaining_size > size)
1147 printk_once(KERN_ERR FW_BUG "Broken EFI implementation"
1148 " is returning MaxVariableSize=0\n");
1149 /* 1059 /*
1150 * Some firmware implementations refuse to boot if there's insufficient 1060 * Some firmware implementations refuse to boot if there's insufficient
1151 * space in the variable store. We account for that by refusing the 1061 * space in the variable store. We account for that by refusing the
1152 * write if permitting it would reduce the available space to under 1062 * write if permitting it would reduce the available space to under
1153 * 50%. However, some firmware won't reclaim variable space until 1063 * 5KB. This figure was provided by Samsung, so should be safe.
1154 * after the used (not merely the actively used) space drops below
1155 * a threshold. We can approximate that case with the value calculated
1156 * above. If both the firmware and our calculations indicate that the
1157 * available space would drop below 50%, refuse the write.
1158 */ 1064 */
1065 if ((remaining_size - size < EFI_MIN_RESERVE) &&
1066 !efi_no_storage_paranoia) {
1067
1068 /*
1069 * Triggering garbage collection may require that the firmware
1070 * generate a real EFI_OUT_OF_RESOURCES error. We can force
1071 * that by attempting to use more space than is available.
1072 */
1073 unsigned long dummy_size = remaining_size + 1024;
1074 void *dummy = kzalloc(dummy_size, GFP_ATOMIC);
1075
1076 if (!dummy)
1077 return EFI_OUT_OF_RESOURCES;
1078
1079 status = efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID,
1080 EFI_VARIABLE_NON_VOLATILE |
1081 EFI_VARIABLE_BOOTSERVICE_ACCESS |
1082 EFI_VARIABLE_RUNTIME_ACCESS,
1083 dummy_size, dummy);
1084
1085 if (status == EFI_SUCCESS) {
1086 /*
1087 * This should have failed, so if it didn't make sure
1088 * that we delete it...
1089 */
1090 efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID,
1091 EFI_VARIABLE_NON_VOLATILE |
1092 EFI_VARIABLE_BOOTSERVICE_ACCESS |
1093 EFI_VARIABLE_RUNTIME_ACCESS,
1094 0, dummy);
1095 }
1096
1097 kfree(dummy);
1159 1098
1160 if (!storage_size || size > remaining_size || 1099 /*
1161 (max_size && size > max_size)) 1100 * The runtime code may now have triggered a garbage collection
1162 return EFI_OUT_OF_RESOURCES; 1101 * run, so check the variable info again
1102 */
1103 status = efi.query_variable_info(attributes, &storage_size,
1104 &remaining_size, &max_size);
1163 1105
1164 if (!efi_no_storage_paranoia && 1106 if (status != EFI_SUCCESS)
1165 ((active_size + size + VAR_METADATA_SIZE > storage_size / 2) && 1107 return status;
1166 (remaining_size - size < storage_size / 2))) 1108
1167 return EFI_OUT_OF_RESOURCES; 1109 /*
1110 * There still isn't enough room, so return an error
1111 */
1112 if (remaining_size - size < EFI_MIN_RESERVE)
1113 return EFI_OUT_OF_RESOURCES;
1114 }
1168 1115
1169 return EFI_SUCCESS; 1116 return EFI_SUCCESS;
1170} 1117}