summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/firmware/efi/efivars.c30
-rw-r--r--fs/efivarfs/super.c7
2 files changed, 14 insertions, 23 deletions
diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c
index 756eca8c4cf8..f4ff8abc5f3e 100644
--- a/drivers/firmware/efi/efivars.c
+++ b/drivers/firmware/efi/efivars.c
@@ -540,38 +540,30 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
540static int 540static int
541efivar_create_sysfs_entry(struct efivar_entry *new_var) 541efivar_create_sysfs_entry(struct efivar_entry *new_var)
542{ 542{
543 int i, short_name_size; 543 int short_name_size;
544 char *short_name; 544 char *short_name;
545 unsigned long variable_name_size; 545 unsigned long utf8_name_size;
546 efi_char16_t *variable_name; 546 efi_char16_t *variable_name = new_var->var.VariableName;
547 int ret; 547 int ret;
548 548
549 variable_name = new_var->var.VariableName;
550 variable_name_size = ucs2_strlen(variable_name) * sizeof(efi_char16_t);
551
552 /* 549 /*
553 * Length of the variable bytes in ASCII, plus the '-' separator, 550 * Length of the variable bytes in UTF8, plus the '-' separator,
554 * plus the GUID, plus trailing NUL 551 * plus the GUID, plus trailing NUL
555 */ 552 */
556 short_name_size = variable_name_size / sizeof(efi_char16_t) 553 utf8_name_size = ucs2_utf8size(variable_name);
557 + 1 + EFI_VARIABLE_GUID_LEN + 1; 554 short_name_size = utf8_name_size + 1 + EFI_VARIABLE_GUID_LEN + 1;
558
559 short_name = kzalloc(short_name_size, GFP_KERNEL);
560 555
556 short_name = kmalloc(short_name_size, GFP_KERNEL);
561 if (!short_name) 557 if (!short_name)
562 return -ENOMEM; 558 return -ENOMEM;
563 559
564 /* Convert Unicode to normal chars (assume top bits are 0), 560 ucs2_as_utf8(short_name, variable_name, short_name_size);
565 ala UTF-8 */ 561
566 for (i=0; i < (int)(variable_name_size / sizeof(efi_char16_t)); i++) {
567 short_name[i] = variable_name[i] & 0xFF;
568 }
569 /* This is ugly, but necessary to separate one vendor's 562 /* This is ugly, but necessary to separate one vendor's
570 private variables from another's. */ 563 private variables from another's. */
571 564 short_name[utf8_name_size] = '-';
572 *(short_name + strlen(short_name)) = '-';
573 efi_guid_to_str(&new_var->var.VendorGuid, 565 efi_guid_to_str(&new_var->var.VendorGuid,
574 short_name + strlen(short_name)); 566 short_name + utf8_name_size + 1);
575 567
576 new_var->kobj.kset = efivars_kset; 568 new_var->kobj.kset = efivars_kset;
577 569
diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
index b8a564f29107..8651ac28ec0d 100644
--- a/fs/efivarfs/super.c
+++ b/fs/efivarfs/super.c
@@ -118,7 +118,7 @@ static int efivarfs_callback(efi_char16_t *name16, efi_guid_t vendor,
118 struct dentry *dentry, *root = sb->s_root; 118 struct dentry *dentry, *root = sb->s_root;
119 unsigned long size = 0; 119 unsigned long size = 0;
120 char *name; 120 char *name;
121 int len, i; 121 int len;
122 int err = -ENOMEM; 122 int err = -ENOMEM;
123 123
124 entry = kzalloc(sizeof(*entry), GFP_KERNEL); 124 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
@@ -128,15 +128,14 @@ static int efivarfs_callback(efi_char16_t *name16, efi_guid_t vendor,
128 memcpy(entry->var.VariableName, name16, name_size); 128 memcpy(entry->var.VariableName, name16, name_size);
129 memcpy(&(entry->var.VendorGuid), &vendor, sizeof(efi_guid_t)); 129 memcpy(&(entry->var.VendorGuid), &vendor, sizeof(efi_guid_t));
130 130
131 len = ucs2_strlen(entry->var.VariableName); 131 len = ucs2_utf8size(entry->var.VariableName);
132 132
133 /* name, plus '-', plus GUID, plus NUL*/ 133 /* name, plus '-', plus GUID, plus NUL*/
134 name = kmalloc(len + 1 + EFI_VARIABLE_GUID_LEN + 1, GFP_KERNEL); 134 name = kmalloc(len + 1 + EFI_VARIABLE_GUID_LEN + 1, GFP_KERNEL);
135 if (!name) 135 if (!name)
136 goto fail; 136 goto fail;
137 137
138 for (i = 0; i < len; i++) 138 ucs2_as_utf8(name, entry->var.VariableName, len);
139 name[i] = entry->var.VariableName[i] & 0xFF;
140 139
141 name[len] = '-'; 140 name[len] = '-';
142 141