Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Peter Anvin:
"Three groups of fixes:

1. Make sure we don't execute the early microcode patching if family
< 6, since it would touch MSRs which don't exist on those
families, causing crashes.

2. The Xen partial emulation of HyperV can be dealt with more
gracefully than just disabling the driver.

3. More EFI variable space magic. In particular, variables hidden
from runtime code need to be taken into account too."

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86, microcode: Verify the family before dispatching microcode patching
x86, hyperv: Handle Xen emulation of Hyper-V more gracefully
x86,efi: Implement efi_no_storage_paranoia parameter
efi: Export efi_query_variable_store() for efivars.ko
x86/Kconfig: Make EFI select UCS2_STRING
efi: Distinguish between "remaining space" and actually used space
efi: Pass boot services variable info to runtime code
Move utf16 functions to kernel core and rename
x86,efi: Check max_size only if it is non-zero.
x86, efivars: firmware bug workarounds should be in platform code

+361 -103
+6
Documentation/kernel-parameters.txt
··· 788 788 edd= [EDD] 789 789 Format: {"off" | "on" | "skip[mbr]"} 790 790 791 + efi_no_storage_paranoia [EFI; X86] 792 + Using this parameter you can use more than 50% of 793 + your efi variable storage. Use this parameter only if 794 + you are really sure that your UEFI does sane gc and 795 + fulfills the spec otherwise your board may brick. 796 + 791 797 eisa_irq_edge= [PARISC,HW] 792 798 See header of drivers/parisc/eisa.c. 793 799
+1
arch/x86/Kconfig
··· 1549 1549 config EFI 1550 1550 bool "EFI runtime service support" 1551 1551 depends on ACPI 1552 + select UCS2_STRING 1552 1553 ---help--- 1553 1554 This enables the kernel to use EFI runtime services that are 1554 1555 available (such as the EFI variable services).
+47
arch/x86/boot/compressed/eboot.c
··· 251 251 *size = len; 252 252 } 253 253 254 + static 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 + 254 299 static efi_status_t setup_efi_pci(struct boot_params *params) 255 300 { 256 301 efi_pci_io_protocol *pci; ··· 1201 1156 goto fail; 1202 1157 1203 1158 setup_graphics(boot_params); 1159 + 1160 + setup_efi_vars(boot_params); 1204 1161 1205 1162 setup_efi_pci(boot_params); 1206 1163
+7
arch/x86/include/asm/efi.h
··· 102 102 extern void efi_unmap_memmap(void); 103 103 extern void efi_memory_uc(u64 addr, unsigned long size); 104 104 105 + struct efi_var_bootdata { 106 + struct setup_data data; 107 + u64 store_size; 108 + u64 remaining_size; 109 + u64 max_var_size; 110 + }; 111 + 105 112 #ifdef CONFIG_EFI 106 113 107 114 static inline bool efi_is_native(void)
+1
arch/x86/include/uapi/asm/bootparam.h
··· 6 6 #define SETUP_E820_EXT 1 7 7 #define SETUP_DTB 2 8 8 #define SETUP_PCI 3 9 + #define SETUP_EFI_VARS 4 9 10 10 11 /* ram_size flags */ 11 12 #define RAMDISK_IMAGE_START_MASK 0x07FF
+5 -13
arch/x86/kernel/cpu/mshyperv.c
··· 35 35 if (!boot_cpu_has(X86_FEATURE_HYPERVISOR)) 36 36 return false; 37 37 38 - /* 39 - * Xen emulates Hyper-V to support enlightened Windows. 40 - * Check to see first if we are on a Xen Hypervisor. 41 - */ 42 - if (xen_cpuid_base()) 43 - return false; 44 - 45 38 cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS, 46 39 &eax, &hyp_signature[0], &hyp_signature[1], &hyp_signature[2]); 47 40 ··· 75 82 76 83 if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE) 77 84 clocksource_register_hz(&hyperv_cs, NSEC_PER_SEC/100); 78 - #if IS_ENABLED(CONFIG_HYPERV) 79 - /* 80 - * Setup the IDT for hypervisor callback. 81 - */ 82 - alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector); 83 - #endif 84 85 } 85 86 86 87 const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = { ··· 90 103 91 104 void hv_register_vmbus_handler(int irq, irq_handler_t handler) 92 105 { 106 + /* 107 + * Setup the IDT for hypervisor callback. 108 + */ 109 + alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector); 110 + 93 111 vmbus_irq = irq; 94 112 vmbus_isr = handler; 95 113 }
+31 -7
arch/x86/kernel/microcode_core_early.c
··· 45 45 u32 eax = 0x00000000; 46 46 u32 ebx, ecx = 0, edx; 47 47 48 - if (!have_cpuid_p()) 49 - return X86_VENDOR_UNKNOWN; 50 - 51 48 native_cpuid(&eax, &ebx, &ecx, &edx); 52 49 53 50 if (CPUID_IS(CPUID_INTEL1, CPUID_INTEL2, CPUID_INTEL3, ebx, ecx, edx)) ··· 56 59 return X86_VENDOR_UNKNOWN; 57 60 } 58 61 62 + static int __cpuinit x86_family(void) 63 + { 64 + u32 eax = 0x00000001; 65 + u32 ebx, ecx = 0, edx; 66 + int x86; 67 + 68 + native_cpuid(&eax, &ebx, &ecx, &edx); 69 + 70 + x86 = (eax >> 8) & 0xf; 71 + if (x86 == 15) 72 + x86 += (eax >> 20) & 0xff; 73 + 74 + return x86; 75 + } 76 + 59 77 void __init load_ucode_bsp(void) 60 78 { 61 - int vendor = x86_vendor(); 79 + int vendor, x86; 62 80 63 - if (vendor == X86_VENDOR_INTEL) 81 + if (!have_cpuid_p()) 82 + return; 83 + 84 + vendor = x86_vendor(); 85 + x86 = x86_family(); 86 + 87 + if (vendor == X86_VENDOR_INTEL && x86 >= 6) 64 88 load_ucode_intel_bsp(); 65 89 } 66 90 67 91 void __cpuinit load_ucode_ap(void) 68 92 { 69 - int vendor = x86_vendor(); 93 + int vendor, x86; 70 94 71 - if (vendor == X86_VENDOR_INTEL) 95 + if (!have_cpuid_p()) 96 + return; 97 + 98 + vendor = x86_vendor(); 99 + x86 = x86_family(); 100 + 101 + if (vendor == X86_VENDOR_INTEL && x86 >= 6) 72 102 load_ucode_intel_ap(); 73 103 }
+163 -5
arch/x86/platform/efi/efi.c
··· 41 41 #include <linux/io.h> 42 42 #include <linux/reboot.h> 43 43 #include <linux/bcd.h> 44 + #include <linux/ucs2_string.h> 44 45 45 46 #include <asm/setup.h> 46 47 #include <asm/efi.h> ··· 51 50 #include <asm/x86_init.h> 52 51 53 52 #define EFI_DEBUG 1 53 + 54 + /* 55 + * There's some additional metadata associated with each 56 + * variable. Intel's reference implementation is 60 bytes - bump that 57 + * to account for potential alignment constraints 58 + */ 59 + #define VAR_METADATA_SIZE 64 54 60 55 61 struct efi __read_mostly efi = { 56 62 .mps = EFI_INVALID_TABLE_ADDR, ··· 76 68 77 69 static struct efi efi_phys __initdata; 78 70 static efi_system_table_t efi_systab __initdata; 71 + 72 + static u64 efi_var_store_size; 73 + static u64 efi_var_remaining_size; 74 + static u64 efi_var_max_var_size; 75 + static u64 boot_used_size; 76 + static u64 boot_var_size; 77 + static u64 active_size; 79 78 80 79 unsigned long x86_efi_facility; 81 80 ··· 112 97 return 0; 113 98 } 114 99 early_param("add_efi_memmap", setup_add_efi_memmap); 100 + 101 + static bool efi_no_storage_paranoia; 102 + 103 + static int __init setup_storage_paranoia(char *arg) 104 + { 105 + efi_no_storage_paranoia = true; 106 + return 0; 107 + } 108 + early_param("efi_no_storage_paranoia", setup_storage_paranoia); 115 109 116 110 117 111 static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) ··· 186 162 efi_char16_t *name, 187 163 efi_guid_t *vendor) 188 164 { 189 - return efi_call_virt3(get_next_variable, 190 - name_size, name, vendor); 165 + efi_status_t status; 166 + static bool finished = false; 167 + static u64 var_size; 168 + 169 + status = efi_call_virt3(get_next_variable, 170 + name_size, name, vendor); 171 + 172 + if (status == EFI_NOT_FOUND) { 173 + finished = true; 174 + if (var_size < boot_used_size) { 175 + boot_var_size = boot_used_size - var_size; 176 + active_size += boot_var_size; 177 + } else { 178 + printk(KERN_WARNING FW_BUG "efi: Inconsistent initial sizes\n"); 179 + } 180 + } 181 + 182 + if (boot_used_size && !finished) { 183 + unsigned long size; 184 + u32 attr; 185 + efi_status_t s; 186 + void *tmp; 187 + 188 + s = virt_efi_get_variable(name, vendor, &attr, &size, NULL); 189 + 190 + if (s != EFI_BUFFER_TOO_SMALL || !size) 191 + return status; 192 + 193 + tmp = kmalloc(size, GFP_ATOMIC); 194 + 195 + if (!tmp) 196 + return status; 197 + 198 + s = virt_efi_get_variable(name, vendor, &attr, &size, tmp); 199 + 200 + if (s == EFI_SUCCESS && (attr & EFI_VARIABLE_NON_VOLATILE)) { 201 + var_size += size; 202 + var_size += ucs2_strsize(name, 1024); 203 + active_size += size; 204 + active_size += VAR_METADATA_SIZE; 205 + active_size += ucs2_strsize(name, 1024); 206 + } 207 + 208 + kfree(tmp); 209 + } 210 + 211 + return status; 191 212 } 192 213 193 214 static efi_status_t virt_efi_set_variable(efi_char16_t *name, ··· 241 172 unsigned long data_size, 242 173 void *data) 243 174 { 244 - return efi_call_virt5(set_variable, 245 - name, vendor, attr, 246 - data_size, data); 175 + efi_status_t status; 176 + u32 orig_attr = 0; 177 + unsigned long orig_size = 0; 178 + 179 + status = virt_efi_get_variable(name, vendor, &orig_attr, &orig_size, 180 + NULL); 181 + 182 + if (status != EFI_BUFFER_TOO_SMALL) 183 + orig_size = 0; 184 + 185 + status = efi_call_virt5(set_variable, 186 + name, vendor, attr, 187 + data_size, data); 188 + 189 + if (status == EFI_SUCCESS) { 190 + if (orig_size) { 191 + active_size -= orig_size; 192 + active_size -= ucs2_strsize(name, 1024); 193 + active_size -= VAR_METADATA_SIZE; 194 + } 195 + if (data_size) { 196 + active_size += data_size; 197 + active_size += ucs2_strsize(name, 1024); 198 + active_size += VAR_METADATA_SIZE; 199 + } 200 + } 201 + 202 + return status; 247 203 } 248 204 249 205 static efi_status_t virt_efi_query_variable_info(u32 attr, ··· 776 682 char vendor[100] = "unknown"; 777 683 int i = 0; 778 684 void *tmp; 685 + struct setup_data *data; 686 + struct efi_var_bootdata *efi_var_data; 687 + u64 pa_data; 779 688 780 689 #ifdef CONFIG_X86_32 781 690 if (boot_params.efi_info.efi_systab_hi || ··· 795 698 796 699 if (efi_systab_init(efi_phys.systab)) 797 700 return; 701 + 702 + pa_data = boot_params.hdr.setup_data; 703 + while (pa_data) { 704 + data = early_ioremap(pa_data, sizeof(*efi_var_data)); 705 + if (data->type == SETUP_EFI_VARS) { 706 + efi_var_data = (struct efi_var_bootdata *)data; 707 + 708 + efi_var_store_size = efi_var_data->store_size; 709 + efi_var_remaining_size = efi_var_data->remaining_size; 710 + efi_var_max_var_size = efi_var_data->max_var_size; 711 + } 712 + pa_data = data->next; 713 + early_iounmap(data, sizeof(*efi_var_data)); 714 + } 715 + 716 + boot_used_size = efi_var_store_size - efi_var_remaining_size; 798 717 799 718 set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility); 800 719 ··· 1112 999 } 1113 1000 return 0; 1114 1001 } 1002 + 1003 + /* 1004 + * Some firmware has serious problems when using more than 50% of the EFI 1005 + * variable store, i.e. it triggers bugs that can brick machines. Ensure that 1006 + * we never use more than this safe limit. 1007 + * 1008 + * Return EFI_SUCCESS if it is safe to write 'size' bytes to the variable 1009 + * store. 1010 + */ 1011 + efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) 1012 + { 1013 + efi_status_t status; 1014 + u64 storage_size, remaining_size, max_size; 1015 + 1016 + status = efi.query_variable_info(attributes, &storage_size, 1017 + &remaining_size, &max_size); 1018 + if (status != EFI_SUCCESS) 1019 + return status; 1020 + 1021 + if (!max_size && remaining_size > size) 1022 + printk_once(KERN_ERR FW_BUG "Broken EFI implementation" 1023 + " is returning MaxVariableSize=0\n"); 1024 + /* 1025 + * Some firmware implementations refuse to boot if there's insufficient 1026 + * space in the variable store. We account for that by refusing the 1027 + * write if permitting it would reduce the available space to under 1028 + * 50%. However, some firmware won't reclaim variable space until 1029 + * after the used (not merely the actively used) space drops below 1030 + * a threshold. We can approximate that case with the value calculated 1031 + * above. If both the firmware and our calculations indicate that the 1032 + * available space would drop below 50%, refuse the write. 1033 + */ 1034 + 1035 + if (!storage_size || size > remaining_size || 1036 + (max_size && size > max_size)) 1037 + return EFI_OUT_OF_RESOURCES; 1038 + 1039 + if (!efi_no_storage_paranoia && 1040 + ((active_size + size + VAR_METADATA_SIZE > storage_size / 2) && 1041 + (remaining_size - size < storage_size / 2))) 1042 + return EFI_OUT_OF_RESOURCES; 1043 + 1044 + return EFI_SUCCESS; 1045 + } 1046 + EXPORT_SYMBOL_GPL(efi_query_variable_store);
+1
drivers/firmware/Kconfig
··· 39 39 config EFI_VARS 40 40 tristate "EFI Variable Support via sysfs" 41 41 depends on EFI 42 + select UCS2_STRING 42 43 default n 43 44 help 44 45 If you say Y here, you are able to get EFI (Extensible Firmware
+21 -77
drivers/firmware/efivars.c
··· 80 80 #include <linux/slab.h> 81 81 #include <linux/pstore.h> 82 82 #include <linux/ctype.h> 83 + #include <linux/ucs2_string.h> 83 84 84 85 #include <linux/fs.h> 85 86 #include <linux/ramfs.h> ··· 173 172 static DECLARE_WORK(efivar_work, efivar_update_sysfs_entries); 174 173 static bool efivar_wq_enabled = true; 175 174 176 - /* Return the number of unicode characters in data */ 177 - static unsigned long 178 - utf16_strnlen(efi_char16_t *s, size_t maxlength) 179 - { 180 - unsigned long length = 0; 181 - 182 - while (*s++ != 0 && length < maxlength) 183 - length++; 184 - return length; 185 - } 186 - 187 - static inline unsigned long 188 - utf16_strlen(efi_char16_t *s) 189 - { 190 - return utf16_strnlen(s, ~0UL); 191 - } 192 - 193 - /* 194 - * Return the number of bytes is the length of this string 195 - * Note: this is NOT the same as the number of unicode characters 196 - */ 197 - static inline unsigned long 198 - utf16_strsize(efi_char16_t *data, unsigned long maxlength) 199 - { 200 - return utf16_strnlen(data, maxlength/sizeof(efi_char16_t)) * sizeof(efi_char16_t); 201 - } 202 - 203 - static inline int 204 - utf16_strncmp(const efi_char16_t *a, const efi_char16_t *b, size_t len) 205 - { 206 - while (1) { 207 - if (len == 0) 208 - return 0; 209 - if (*a < *b) 210 - return -1; 211 - if (*a > *b) 212 - return 1; 213 - if (*a == 0) /* implies *b == 0 */ 214 - return 0; 215 - a++; 216 - b++; 217 - len--; 218 - } 219 - } 220 - 221 175 static bool 222 176 validate_device_path(struct efi_variable *var, int match, u8 *buffer, 223 177 unsigned long len) ··· 224 268 u16 filepathlength; 225 269 int i, desclength = 0, namelen; 226 270 227 - namelen = utf16_strnlen(var->VariableName, sizeof(var->VariableName)); 271 + namelen = ucs2_strnlen(var->VariableName, sizeof(var->VariableName)); 228 272 229 273 /* Either "Boot" or "Driver" followed by four digits of hex */ 230 274 for (i = match; i < match+4; i++) { ··· 247 291 * There's no stored length for the description, so it has to be 248 292 * found by hand 249 293 */ 250 - desclength = utf16_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2; 294 + desclength = ucs2_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2; 251 295 252 296 /* Each boot entry must have a descriptor */ 253 297 if (!desclength) ··· 392 436 check_var_size_locked(struct efivars *efivars, u32 attributes, 393 437 unsigned long size) 394 438 { 395 - u64 storage_size, remaining_size, max_size; 396 - efi_status_t status; 397 439 const struct efivar_operations *fops = efivars->ops; 398 440 399 - if (!efivars->ops->query_variable_info) 441 + if (!efivars->ops->query_variable_store) 400 442 return EFI_UNSUPPORTED; 401 443 402 - status = fops->query_variable_info(attributes, &storage_size, 403 - &remaining_size, &max_size); 404 - 405 - if (status != EFI_SUCCESS) 406 - return status; 407 - 408 - if (!storage_size || size > remaining_size || size > max_size || 409 - (remaining_size - size) < (storage_size / 2)) 410 - return EFI_OUT_OF_RESOURCES; 411 - 412 - return status; 444 + return fops->query_variable_store(attributes, size); 413 445 } 414 446 415 447 ··· 537 593 spin_lock_irq(&efivars->lock); 538 594 539 595 status = check_var_size_locked(efivars, new_var->Attributes, 540 - new_var->DataSize + utf16_strsize(new_var->VariableName, 1024)); 596 + new_var->DataSize + ucs2_strsize(new_var->VariableName, 1024)); 541 597 542 598 if (status == EFI_SUCCESS || status == EFI_UNSUPPORTED) 543 599 status = efivars->ops->set_variable(new_var->VariableName, ··· 715 771 * QueryVariableInfo() isn't supported by the firmware. 716 772 */ 717 773 718 - varsize = datasize + utf16_strsize(var->var.VariableName, 1024); 774 + varsize = datasize + ucs2_strsize(var->var.VariableName, 1024); 719 775 status = check_var_size(efivars, attributes, varsize); 720 776 721 777 if (status != EFI_SUCCESS) { ··· 1167 1223 1168 1224 inode = NULL; 1169 1225 1170 - len = utf16_strlen(entry->var.VariableName); 1226 + len = ucs2_strlen(entry->var.VariableName); 1171 1227 1172 1228 /* name, plus '-', plus GUID, plus NUL*/ 1173 1229 name = kmalloc(len + 1 + GUID_LEN + 1, GFP_ATOMIC); ··· 1425 1481 1426 1482 if (efi_guidcmp(entry->var.VendorGuid, vendor)) 1427 1483 continue; 1428 - if (utf16_strncmp(entry->var.VariableName, efi_name, 1429 - utf16_strlen(efi_name))) { 1484 + if (ucs2_strncmp(entry->var.VariableName, efi_name, 1485 + ucs2_strlen(efi_name))) { 1430 1486 /* 1431 1487 * Check if an old format, 1432 1488 * which doesn't support holding ··· 1438 1494 for (i = 0; i < DUMP_NAME_LEN; i++) 1439 1495 efi_name_old[i] = name_old[i]; 1440 1496 1441 - if (utf16_strncmp(entry->var.VariableName, efi_name_old, 1442 - utf16_strlen(efi_name_old))) 1497 + if (ucs2_strncmp(entry->var.VariableName, efi_name_old, 1498 + ucs2_strlen(efi_name_old))) 1443 1499 continue; 1444 1500 } 1445 1501 ··· 1517 1573 * Does this variable already exist? 1518 1574 */ 1519 1575 list_for_each_entry_safe(search_efivar, n, &efivars->list, list) { 1520 - strsize1 = utf16_strsize(search_efivar->var.VariableName, 1024); 1521 - strsize2 = utf16_strsize(new_var->VariableName, 1024); 1576 + strsize1 = ucs2_strsize(search_efivar->var.VariableName, 1024); 1577 + strsize2 = ucs2_strsize(new_var->VariableName, 1024); 1522 1578 if (strsize1 == strsize2 && 1523 1579 !memcmp(&(search_efivar->var.VariableName), 1524 1580 new_var->VariableName, strsize1) && ··· 1534 1590 } 1535 1591 1536 1592 status = check_var_size_locked(efivars, new_var->Attributes, 1537 - new_var->DataSize + utf16_strsize(new_var->VariableName, 1024)); 1593 + new_var->DataSize + ucs2_strsize(new_var->VariableName, 1024)); 1538 1594 1539 1595 if (status && status != EFI_UNSUPPORTED) { 1540 1596 spin_unlock_irq(&efivars->lock); ··· 1558 1614 1559 1615 /* Create the entry in sysfs. Locking is not required here */ 1560 1616 status = efivar_create_sysfs_entry(efivars, 1561 - utf16_strsize(new_var->VariableName, 1617 + ucs2_strsize(new_var->VariableName, 1562 1618 1024), 1563 1619 new_var->VariableName, 1564 1620 &new_var->VendorGuid); ··· 1588 1644 * Does this variable already exist? 1589 1645 */ 1590 1646 list_for_each_entry_safe(search_efivar, n, &efivars->list, list) { 1591 - strsize1 = utf16_strsize(search_efivar->var.VariableName, 1024); 1592 - strsize2 = utf16_strsize(del_var->VariableName, 1024); 1647 + strsize1 = ucs2_strsize(search_efivar->var.VariableName, 1024); 1648 + strsize2 = ucs2_strsize(del_var->VariableName, 1024); 1593 1649 if (strsize1 == strsize2 && 1594 1650 !memcmp(&(search_efivar->var.VariableName), 1595 1651 del_var->VariableName, strsize1) && ··· 1635 1691 unsigned long strsize1, strsize2; 1636 1692 bool found = false; 1637 1693 1638 - strsize1 = utf16_strsize(variable_name, 1024); 1694 + strsize1 = ucs2_strsize(variable_name, 1024); 1639 1695 list_for_each_entry_safe(entry, n, &efivars->list, list) { 1640 - strsize2 = utf16_strsize(entry->var.VariableName, 1024); 1696 + strsize2 = ucs2_strsize(entry->var.VariableName, 1024); 1641 1697 if (strsize1 == strsize2 && 1642 1698 !memcmp(variable_name, &(entry->var.VariableName), 1643 1699 strsize2) && ··· 2075 2131 ops.get_variable = efi.get_variable; 2076 2132 ops.set_variable = efi.set_variable; 2077 2133 ops.get_next_variable = efi.get_next_variable; 2078 - ops.query_variable_info = efi.query_variable_info; 2134 + ops.query_variable_store = efi_query_variable_store; 2079 2135 2080 2136 error = register_efivars(&__efivars, &ops, efi_kobj); 2081 2137 if (error)
+8 -1
include/linux/efi.h
··· 333 333 unsigned long count, 334 334 u64 *max_size, 335 335 int *reset_type); 336 + typedef efi_status_t efi_query_variable_store_t(u32 attributes, unsigned long size); 336 337 337 338 /* 338 339 * EFI Configuration Table and GUID definitions ··· 576 575 #ifdef CONFIG_X86 577 576 extern void efi_late_init(void); 578 577 extern void efi_free_boot_services(void); 578 + extern efi_status_t efi_query_variable_store(u32 attributes, unsigned long size); 579 579 #else 580 580 static inline void efi_late_init(void) {} 581 581 static inline void efi_free_boot_services(void) {} 582 + 583 + static inline efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) 584 + { 585 + return EFI_SUCCESS; 586 + } 582 587 #endif 583 588 extern void __iomem *efi_lookup_mapped_addr(u64 phys_addr); 584 589 extern u64 efi_get_iobase (void); ··· 738 731 efi_get_variable_t *get_variable; 739 732 efi_get_next_variable_t *get_next_variable; 740 733 efi_set_variable_t *set_variable; 741 - efi_query_variable_info_t *query_variable_info; 734 + efi_query_variable_store_t *query_variable_store; 742 735 }; 743 736 744 737 struct efivars {
+14
include/linux/ucs2_string.h
··· 1 + #ifndef _LINUX_UCS2_STRING_H_ 2 + #define _LINUX_UCS2_STRING_H_ 3 + 4 + #include <linux/types.h> /* for size_t */ 5 + #include <linux/stddef.h> /* for NULL */ 6 + 7 + typedef u16 ucs2_char_t; 8 + 9 + unsigned long ucs2_strnlen(const ucs2_char_t *s, size_t maxlength); 10 + unsigned long ucs2_strlen(const ucs2_char_t *s); 11 + unsigned long ucs2_strsize(const ucs2_char_t *data, unsigned long maxlength); 12 + int ucs2_strncmp(const ucs2_char_t *a, const ucs2_char_t *b, size_t len); 13 + 14 + #endif /* _LINUX_UCS2_STRING_H_ */
+3
lib/Kconfig
··· 404 404 help 405 405 Enable fast lookup object identifier registry. 406 406 407 + config UCS2_STRING 408 + tristate 409 + 407 410 endmenu
+2
lib/Makefile
··· 174 174 cmd_build_OID_registry = perl $(srctree)/$(src)/build_OID_registry $< $@ 175 175 176 176 clean-files += oid_registry_data.c 177 + 178 + obj-$(CONFIG_UCS2_STRING) += ucs2_string.o
+51
lib/ucs2_string.c
··· 1 + #include <linux/ucs2_string.h> 2 + #include <linux/module.h> 3 + 4 + /* Return the number of unicode characters in data */ 5 + unsigned long 6 + ucs2_strnlen(const ucs2_char_t *s, size_t maxlength) 7 + { 8 + unsigned long length = 0; 9 + 10 + while (*s++ != 0 && length < maxlength) 11 + length++; 12 + return length; 13 + } 14 + EXPORT_SYMBOL(ucs2_strnlen); 15 + 16 + unsigned long 17 + ucs2_strlen(const ucs2_char_t *s) 18 + { 19 + return ucs2_strnlen(s, ~0UL); 20 + } 21 + EXPORT_SYMBOL(ucs2_strlen); 22 + 23 + /* 24 + * Return the number of bytes is the length of this string 25 + * Note: this is NOT the same as the number of unicode characters 26 + */ 27 + unsigned long 28 + ucs2_strsize(const ucs2_char_t *data, unsigned long maxlength) 29 + { 30 + return ucs2_strnlen(data, maxlength/sizeof(ucs2_char_t)) * sizeof(ucs2_char_t); 31 + } 32 + EXPORT_SYMBOL(ucs2_strsize); 33 + 34 + int 35 + ucs2_strncmp(const ucs2_char_t *a, const ucs2_char_t *b, size_t len) 36 + { 37 + while (1) { 38 + if (len == 0) 39 + return 0; 40 + if (*a < *b) 41 + return -1; 42 + if (*a > *b) 43 + return 1; 44 + if (*a == 0) /* implies *b == 0 */ 45 + return 0; 46 + a++; 47 + b++; 48 + len--; 49 + } 50 + } 51 + EXPORT_SYMBOL(ucs2_strncmp);