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.c188
1 files changed, 65 insertions, 123 deletions
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 55856b2310d3..5ae2eb09419e 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,
@@ -786,9 +708,6 @@ void __init efi_init(void)
786 char vendor[100] = "unknown"; 708 char vendor[100] = "unknown";
787 int i = 0; 709 int i = 0;
788 void *tmp; 710 void *tmp;
789 struct setup_data *data;
790 struct efi_var_bootdata *efi_var_data;
791 u64 pa_data;
792 711
793#ifdef CONFIG_X86_32 712#ifdef CONFIG_X86_32
794 if (boot_params.efi_info.efi_systab_hi || 713 if (boot_params.efi_info.efi_systab_hi ||
@@ -806,22 +725,6 @@ void __init efi_init(void)
806 if (efi_systab_init(efi_phys.systab)) 725 if (efi_systab_init(efi_phys.systab))
807 return; 726 return;
808 727
809 pa_data = boot_params.hdr.setup_data;
810 while (pa_data) {
811 data = early_ioremap(pa_data, sizeof(*efi_var_data));
812 if (data->type == SETUP_EFI_VARS) {
813 efi_var_data = (struct efi_var_bootdata *)data;
814
815 efi_var_store_size = efi_var_data->store_size;
816 efi_var_remaining_size = efi_var_data->remaining_size;
817 efi_var_max_var_size = efi_var_data->max_var_size;
818 }
819 pa_data = data->next;
820 early_iounmap(data, sizeof(*efi_var_data));
821 }
822
823 boot_used_size = efi_var_store_size - efi_var_remaining_size;
824
825 set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility); 728 set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility);
826 729
827 /* 730 /*
@@ -1085,6 +988,13 @@ void __init efi_enter_virtual_mode(void)
1085 runtime_code_page_mkexec(); 988 runtime_code_page_mkexec();
1086 989
1087 kfree(new_memmap); 990 kfree(new_memmap);
991
992 /* clean DUMMY object */
993 efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID,
994 EFI_VARIABLE_NON_VOLATILE |
995 EFI_VARIABLE_BOOTSERVICE_ACCESS |
996 EFI_VARIABLE_RUNTIME_ACCESS,
997 0, NULL);
1088} 998}
1089 999
1090/* 1000/*
@@ -1136,33 +1046,65 @@ efi_status_t efi_query_variable_store(u32 attributes, unsigned long size)
1136 efi_status_t status; 1046 efi_status_t status;
1137 u64 storage_size, remaining_size, max_size; 1047 u64 storage_size, remaining_size, max_size;
1138 1048
1049 if (!(attributes & EFI_VARIABLE_NON_VOLATILE))
1050 return 0;
1051
1139 status = efi.query_variable_info(attributes, &storage_size, 1052 status = efi.query_variable_info(attributes, &storage_size,
1140 &remaining_size, &max_size); 1053 &remaining_size, &max_size);
1141 if (status != EFI_SUCCESS) 1054 if (status != EFI_SUCCESS)
1142 return status; 1055 return status;
1143 1056
1144 if (!max_size && remaining_size > size)
1145 printk_once(KERN_ERR FW_BUG "Broken EFI implementation"
1146 " is returning MaxVariableSize=0\n");
1147 /* 1057 /*
1148 * Some firmware implementations refuse to boot if there's insufficient 1058 * Some firmware implementations refuse to boot if there's insufficient
1149 * space in the variable store. We account for that by refusing the 1059 * space in the variable store. We account for that by refusing the
1150 * write if permitting it would reduce the available space to under 1060 * write if permitting it would reduce the available space to under
1151 * 50%. However, some firmware won't reclaim variable space until 1061 * 5KB. This figure was provided by Samsung, so should be safe.
1152 * after the used (not merely the actively used) space drops below
1153 * a threshold. We can approximate that case with the value calculated
1154 * above. If both the firmware and our calculations indicate that the
1155 * available space would drop below 50%, refuse the write.
1156 */ 1062 */
1063 if ((remaining_size - size < EFI_MIN_RESERVE) &&
1064 !efi_no_storage_paranoia) {
1065
1066 /*
1067 * Triggering garbage collection may require that the firmware
1068 * generate a real EFI_OUT_OF_RESOURCES error. We can force
1069 * that by attempting to use more space than is available.
1070 */
1071 unsigned long dummy_size = remaining_size + 1024;
1072 void *dummy = kmalloc(dummy_size, GFP_ATOMIC);
1073
1074 status = efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID,
1075 EFI_VARIABLE_NON_VOLATILE |
1076 EFI_VARIABLE_BOOTSERVICE_ACCESS |
1077 EFI_VARIABLE_RUNTIME_ACCESS,
1078 dummy_size, dummy);
1079
1080 if (status == EFI_SUCCESS) {
1081 /*
1082 * This should have failed, so if it didn't make sure
1083 * that we delete it...
1084 */
1085 efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID,
1086 EFI_VARIABLE_NON_VOLATILE |
1087 EFI_VARIABLE_BOOTSERVICE_ACCESS |
1088 EFI_VARIABLE_RUNTIME_ACCESS,
1089 0, dummy);
1090 }
1157 1091
1158 if (!storage_size || size > remaining_size || 1092 /*
1159 (max_size && size > max_size)) 1093 * The runtime code may now have triggered a garbage collection
1160 return EFI_OUT_OF_RESOURCES; 1094 * run, so check the variable info again
1095 */
1096 status = efi.query_variable_info(attributes, &storage_size,
1097 &remaining_size, &max_size);
1161 1098
1162 if (!efi_no_storage_paranoia && 1099 if (status != EFI_SUCCESS)
1163 ((active_size + size + VAR_METADATA_SIZE > storage_size / 2) && 1100 return status;
1164 (remaining_size - size < storage_size / 2))) 1101
1165 return EFI_OUT_OF_RESOURCES; 1102 /*
1103 * There still isn't enough room, so return an error
1104 */
1105 if (remaining_size - size < EFI_MIN_RESERVE)
1106 return EFI_OUT_OF_RESOURCES;
1107 }
1166 1108
1167 return EFI_SUCCESS; 1109 return EFI_SUCCESS;
1168} 1110}