linux/drivers/firmware/efivars.c
<<
>>
Prefs
   1/*
   2 * EFI Variables - efivars.c
   3 *
   4 * Copyright (C) 2001,2003,2004 Dell <Matt_Domsch@dell.com>
   5 * Copyright (C) 2004 Intel Corporation <matthew.e.tolentino@intel.com>
   6 *
   7 * This code takes all variables accessible from EFI runtime and
   8 *  exports them via sysfs
   9 *
  10 *  This program is free software; you can redistribute it and/or modify
  11 *  it under the terms of the GNU General Public License as published by
  12 *  the Free Software Foundation; either version 2 of the License, or
  13 *  (at your option) any later version.
  14 *
  15 *  This program is distributed in the hope that it will be useful,
  16 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18 *  GNU General Public License for more details.
  19 *
  20 *  You should have received a copy of the GNU General Public License
  21 *  along with this program; if not, write to the Free Software
  22 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  23 *
  24 * Changelog:
  25 *
  26 *  17 May 2004 - Matt Domsch <Matt_Domsch@dell.com>
  27 *   remove check for efi_enabled in exit
  28 *   add MODULE_VERSION
  29 *
  30 *  26 Apr 2004 - Matt Domsch <Matt_Domsch@dell.com>
  31 *   minor bug fixes
  32 *
  33 *  21 Apr 2004 - Matt Tolentino <matthew.e.tolentino@intel.com)
  34 *   converted driver to export variable information via sysfs
  35 *   and moved to drivers/firmware directory
  36 *   bumped revision number to v0.07 to reflect conversion & move
  37 *
  38 *  10 Dec 2002 - Matt Domsch <Matt_Domsch@dell.com>
  39 *   fix locking per Peter Chubb's findings
  40 *
  41 *  25 Mar 2002 - Matt Domsch <Matt_Domsch@dell.com>
  42 *   move uuid_unparse() to include/asm-ia64/efi.h:efi_guid_unparse()
  43 *
  44 *  12 Feb 2002 - Matt Domsch <Matt_Domsch@dell.com>
  45 *   use list_for_each_safe when deleting vars.
  46 *   remove ifdef CONFIG_SMP around include <linux/smp.h>
  47 *   v0.04 release to linux-ia64@linuxia64.org
  48 *
  49 *  20 April 2001 - Matt Domsch <Matt_Domsch@dell.com>
  50 *   Moved vars from /proc/efi to /proc/efi/vars, and made
  51 *   efi.c own the /proc/efi directory.
  52 *   v0.03 release to linux-ia64@linuxia64.org
  53 *
  54 *  26 March 2001 - Matt Domsch <Matt_Domsch@dell.com>
  55 *   At the request of Stephane, moved ownership of /proc/efi
  56 *   to efi.c, and now efivars lives under /proc/efi/vars.
  57 *
  58 *  12 March 2001 - Matt Domsch <Matt_Domsch@dell.com>
  59 *   Feedback received from Stephane Eranian incorporated.
  60 *   efivar_write() checks copy_from_user() return value.
  61 *   efivar_read/write() returns proper errno.
  62 *   v0.02 release to linux-ia64@linuxia64.org
  63 *
  64 *  26 February 2001 - Matt Domsch <Matt_Domsch@dell.com>
  65 *   v0.01 release to linux-ia64@linuxia64.org
  66 */
  67
  68#include <linux/capability.h>
  69#include <linux/types.h>
  70#include <linux/errno.h>
  71#include <linux/init.h>
  72#include <linux/mm.h>
  73#include <linux/module.h>
  74#include <linux/string.h>
  75#include <linux/smp.h>
  76#include <linux/efi.h>
  77#include <linux/sysfs.h>
  78#include <linux/kobject.h>
  79#include <linux/device.h>
  80#include <linux/slab.h>
  81#include <linux/pstore.h>
  82#include <linux/ctype.h>
  83
  84#include <linux/fs.h>
  85#include <linux/ramfs.h>
  86#include <linux/pagemap.h>
  87
  88#include <asm/uaccess.h>
  89
  90#define EFIVARS_VERSION "0.08"
  91#define EFIVARS_DATE "2004-May-17"
  92
  93MODULE_AUTHOR("Matt Domsch <Matt_Domsch@Dell.com>");
  94MODULE_DESCRIPTION("sysfs interface to EFI Variables");
  95MODULE_LICENSE("GPL");
  96MODULE_VERSION(EFIVARS_VERSION);
  97
  98#define DUMP_NAME_LEN 52
  99
 100/*
 101 * Length of a GUID string (strlen("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"))
 102 * not including trailing NUL
 103 */
 104#define GUID_LEN 36
 105
 106static bool efivars_pstore_disable =
 107        IS_ENABLED(CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE);
 108
 109module_param_named(pstore_disable, efivars_pstore_disable, bool, 0644);
 110
 111/*
 112 * The maximum size of VariableName + Data = 1024
 113 * Therefore, it's reasonable to save that much
 114 * space in each part of the structure,
 115 * and we use a page for reading/writing.
 116 */
 117
 118struct efi_variable {
 119        efi_char16_t  VariableName[1024/sizeof(efi_char16_t)];
 120        efi_guid_t    VendorGuid;
 121        unsigned long DataSize;
 122        __u8          Data[1024];
 123        efi_status_t  Status;
 124        __u32         Attributes;
 125} __attribute__((packed));
 126
 127struct efivar_entry {
 128        struct efivars *efivars;
 129        struct efi_variable var;
 130        struct list_head list;
 131        struct kobject kobj;
 132};
 133
 134struct efivar_attribute {
 135        struct attribute attr;
 136        ssize_t (*show) (struct efivar_entry *entry, char *buf);
 137        ssize_t (*store)(struct efivar_entry *entry, const char *buf, size_t count);
 138};
 139
 140static struct efivars __efivars;
 141static struct efivar_operations ops;
 142
 143#define PSTORE_EFI_ATTRIBUTES \
 144        (EFI_VARIABLE_NON_VOLATILE | \
 145         EFI_VARIABLE_BOOTSERVICE_ACCESS | \
 146         EFI_VARIABLE_RUNTIME_ACCESS)
 147
 148#define EFIVAR_ATTR(_name, _mode, _show, _store) \
 149struct efivar_attribute efivar_attr_##_name = { \
 150        .attr = {.name = __stringify(_name), .mode = _mode}, \
 151        .show = _show, \
 152        .store = _store, \
 153};
 154
 155#define to_efivar_attr(_attr) container_of(_attr, struct efivar_attribute, attr)
 156#define to_efivar_entry(obj)  container_of(obj, struct efivar_entry, kobj)
 157
 158/*
 159 * Prototype for sysfs creation function
 160 */
 161static int
 162efivar_create_sysfs_entry(struct efivars *efivars,
 163                          unsigned long variable_name_size,
 164                          efi_char16_t *variable_name,
 165                          efi_guid_t *vendor_guid);
 166
 167/* Return the number of unicode characters in data */
 168static unsigned long
 169utf16_strnlen(efi_char16_t *s, size_t maxlength)
 170{
 171        unsigned long length = 0;
 172
 173        while (*s++ != 0 && length < maxlength)
 174                length++;
 175        return length;
 176}
 177
 178static inline unsigned long
 179utf16_strlen(efi_char16_t *s)
 180{
 181        return utf16_strnlen(s, ~0UL);
 182}
 183
 184/*
 185 * Return the number of bytes is the length of this string
 186 * Note: this is NOT the same as the number of unicode characters
 187 */
 188static inline unsigned long
 189utf16_strsize(efi_char16_t *data, unsigned long maxlength)
 190{
 191        return utf16_strnlen(data, maxlength/sizeof(efi_char16_t)) * sizeof(efi_char16_t);
 192}
 193
 194static inline int
 195utf16_strncmp(const efi_char16_t *a, const efi_char16_t *b, size_t len)
 196{
 197        while (1) {
 198                if (len == 0)
 199                        return 0;
 200                if (*a < *b)
 201                        return -1;
 202                if (*a > *b)
 203                        return 1;
 204                if (*a == 0) /* implies *b == 0 */
 205                        return 0;
 206                a++;
 207                b++;
 208                len--;
 209        }
 210}
 211
 212static bool
 213validate_device_path(struct efi_variable *var, int match, u8 *buffer,
 214                     unsigned long len)
 215{
 216        struct efi_generic_dev_path *node;
 217        int offset = 0;
 218
 219        node = (struct efi_generic_dev_path *)buffer;
 220
 221        if (len < sizeof(*node))
 222                return false;
 223
 224        while (offset <= len - sizeof(*node) &&
 225               node->length >= sizeof(*node) &&
 226                node->length <= len - offset) {
 227                offset += node->length;
 228
 229                if ((node->type == EFI_DEV_END_PATH ||
 230                     node->type == EFI_DEV_END_PATH2) &&
 231                    node->sub_type == EFI_DEV_END_ENTIRE)
 232                        return true;
 233
 234                node = (struct efi_generic_dev_path *)(buffer + offset);
 235        }
 236
 237        /*
 238         * If we're here then either node->length pointed past the end
 239         * of the buffer or we reached the end of the buffer without
 240         * finding a device path end node.
 241         */
 242        return false;
 243}
 244
 245static bool
 246validate_boot_order(struct efi_variable *var, int match, u8 *buffer,
 247                    unsigned long len)
 248{
 249        /* An array of 16-bit integers */
 250        if ((len % 2) != 0)
 251                return false;
 252
 253        return true;
 254}
 255
 256static bool
 257validate_load_option(struct efi_variable *var, int match, u8 *buffer,
 258                     unsigned long len)
 259{
 260        u16 filepathlength;
 261        int i, desclength = 0, namelen;
 262
 263        namelen = utf16_strnlen(var->VariableName, sizeof(var->VariableName));
 264
 265        /* Either "Boot" or "Driver" followed by four digits of hex */
 266        for (i = match; i < match+4; i++) {
 267                if (var->VariableName[i] > 127 ||
 268                    hex_to_bin(var->VariableName[i] & 0xff) < 0)
 269                        return true;
 270        }
 271
 272        /* Reject it if there's 4 digits of hex and then further content */
 273        if (namelen > match + 4)
 274                return false;
 275
 276        /* A valid entry must be at least 8 bytes */
 277        if (len < 8)
 278                return false;
 279
 280        filepathlength = buffer[4] | buffer[5] << 8;
 281
 282        /*
 283         * There's no stored length for the description, so it has to be
 284         * found by hand
 285         */
 286        desclength = utf16_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2;
 287
 288        /* Each boot entry must have a descriptor */
 289        if (!desclength)
 290                return false;
 291
 292        /*
 293         * If the sum of the length of the description, the claimed filepath
 294         * length and the original header are greater than the length of the
 295         * variable, it's malformed
 296         */
 297        if ((desclength + filepathlength + 6) > len)
 298                return false;
 299
 300        /*
 301         * And, finally, check the filepath
 302         */
 303        return validate_device_path(var, match, buffer + desclength + 6,
 304                                    filepathlength);
 305}
 306
 307static bool
 308validate_uint16(struct efi_variable *var, int match, u8 *buffer,
 309                unsigned long len)
 310{
 311        /* A single 16-bit integer */
 312        if (len != 2)
 313                return false;
 314
 315        return true;
 316}
 317
 318static bool
 319validate_ascii_string(struct efi_variable *var, int match, u8 *buffer,
 320                      unsigned long len)
 321{
 322        int i;
 323
 324        for (i = 0; i < len; i++) {
 325                if (buffer[i] > 127)
 326                        return false;
 327
 328                if (buffer[i] == 0)
 329                        return true;
 330        }
 331
 332        return false;
 333}
 334
 335struct variable_validate {
 336        char *name;
 337        bool (*validate)(struct efi_variable *var, int match, u8 *data,
 338                         unsigned long len);
 339};
 340
 341static const struct variable_validate variable_validate[] = {
 342        { "BootNext", validate_uint16 },
 343        { "BootOrder", validate_boot_order },
 344        { "DriverOrder", validate_boot_order },
 345        { "Boot*", validate_load_option },
 346        { "Driver*", validate_load_option },
 347        { "ConIn", validate_device_path },
 348        { "ConInDev", validate_device_path },
 349        { "ConOut", validate_device_path },
 350        { "ConOutDev", validate_device_path },
 351        { "ErrOut", validate_device_path },
 352        { "ErrOutDev", validate_device_path },
 353        { "Timeout", validate_uint16 },
 354        { "Lang", validate_ascii_string },
 355        { "PlatformLang", validate_ascii_string },
 356        { "", NULL },
 357};
 358
 359static bool
 360validate_var(struct efi_variable *var, u8 *data, unsigned long len)
 361{
 362        int i;
 363        u16 *unicode_name = var->VariableName;
 364
 365        for (i = 0; variable_validate[i].validate != NULL; i++) {
 366                const char *name = variable_validate[i].name;
 367                int match;
 368
 369                for (match = 0; ; match++) {
 370                        char c = name[match];
 371                        u16 u = unicode_name[match];
 372
 373                        /* All special variables are plain ascii */
 374                        if (u > 127)
 375                                return true;
 376
 377                        /* Wildcard in the matching name means we've matched */
 378                        if (c == '*')
 379                                return variable_validate[i].validate(var,
 380                                                             match, data, len);
 381
 382                        /* Case sensitive match */
 383                        if (c != u)
 384                                break;
 385
 386                        /* Reached the end of the string while matching */
 387                        if (!c)
 388                                return variable_validate[i].validate(var,
 389                                                             match, data, len);
 390                }
 391        }
 392
 393        return true;
 394}
 395
 396static efi_status_t
 397get_var_data_locked(struct efivars *efivars, struct efi_variable *var)
 398{
 399        efi_status_t status;
 400
 401        var->DataSize = 1024;
 402        status = efivars->ops->get_variable(var->VariableName,
 403                                            &var->VendorGuid,
 404                                            &var->Attributes,
 405                                            &var->DataSize,
 406                                            var->Data);
 407        return status;
 408}
 409
 410static efi_status_t
 411get_var_data(struct efivars *efivars, struct efi_variable *var)
 412{
 413        efi_status_t status;
 414        unsigned long flags;
 415
 416        spin_lock_irqsave(&efivars->lock, flags);
 417        status = get_var_data_locked(efivars, var);
 418        spin_unlock_irqrestore(&efivars->lock, flags);
 419
 420        if (status != EFI_SUCCESS) {
 421                printk(KERN_WARNING "efivars: get_variable() failed 0x%lx!\n",
 422                        status);
 423        }
 424        return status;
 425}
 426
 427static efi_status_t
 428check_var_size_locked(struct efivars *efivars, u32 attributes,
 429                        unsigned long size)
 430{
 431        u64 storage_size, remaining_size, max_size;
 432        efi_status_t status;
 433        const struct efivar_operations *fops = efivars->ops;
 434
 435        if (!efivars->ops->query_variable_info)
 436                return EFI_UNSUPPORTED;
 437
 438        status = fops->query_variable_info(attributes, &storage_size,
 439                                           &remaining_size, &max_size);
 440
 441        if (status != EFI_SUCCESS)
 442                return status;
 443
 444        if (!storage_size || size > remaining_size || size > max_size ||
 445            (remaining_size - size) < (storage_size / 2))
 446                return EFI_OUT_OF_RESOURCES;
 447
 448        return status;
 449}
 450
 451
 452static efi_status_t
 453check_var_size(struct efivars *efivars, u32 attributes, unsigned long size)
 454{
 455        efi_status_t status;
 456        unsigned long flags;
 457
 458        spin_lock_irqsave(&efivars->lock, flags);
 459        status = check_var_size_locked(efivars, attributes, size);
 460        spin_unlock_irqrestore(&efivars->lock, flags);
 461
 462        return status;
 463}
 464
 465static ssize_t
 466efivar_guid_read(struct efivar_entry *entry, char *buf)
 467{
 468        struct efi_variable *var = &entry->var;
 469        char *str = buf;
 470
 471        if (!entry || !buf)
 472                return 0;
 473
 474        efi_guid_unparse(&var->VendorGuid, str);
 475        str += strlen(str);
 476        str += sprintf(str, "\n");
 477
 478        return str - buf;
 479}
 480
 481static ssize_t
 482efivar_attr_read(struct efivar_entry *entry, char *buf)
 483{
 484        struct efi_variable *var = &entry->var;
 485        char *str = buf;
 486        efi_status_t status;
 487
 488        if (!entry || !buf)
 489                return -EINVAL;
 490
 491        status = get_var_data(entry->efivars, var);
 492        if (status != EFI_SUCCESS)
 493                return -EIO;
 494
 495        if (var->Attributes & EFI_VARIABLE_NON_VOLATILE)
 496                str += sprintf(str, "EFI_VARIABLE_NON_VOLATILE\n");
 497        if (var->Attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS)
 498                str += sprintf(str, "EFI_VARIABLE_BOOTSERVICE_ACCESS\n");
 499        if (var->Attributes & EFI_VARIABLE_RUNTIME_ACCESS)
 500                str += sprintf(str, "EFI_VARIABLE_RUNTIME_ACCESS\n");
 501        if (var->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD)
 502                str += sprintf(str, "EFI_VARIABLE_HARDWARE_ERROR_RECORD\n");
 503        if (var->Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS)
 504                str += sprintf(str,
 505                        "EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS\n");
 506        if (var->Attributes &
 507                        EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)
 508                str += sprintf(str,
 509                        "EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS\n");
 510        if (var->Attributes & EFI_VARIABLE_APPEND_WRITE)
 511                str += sprintf(str, "EFI_VARIABLE_APPEND_WRITE\n");
 512        return str - buf;
 513}
 514
 515static ssize_t
 516efivar_size_read(struct efivar_entry *entry, char *buf)
 517{
 518        struct efi_variable *var = &entry->var;
 519        char *str = buf;
 520        efi_status_t status;
 521
 522        if (!entry || !buf)
 523                return -EINVAL;
 524
 525        status = get_var_data(entry->efivars, var);
 526        if (status != EFI_SUCCESS)
 527                return -EIO;
 528
 529        str += sprintf(str, "0x%lx\n", var->DataSize);
 530        return str - buf;
 531}
 532
 533static ssize_t
 534efivar_data_read(struct efivar_entry *entry, char *buf)
 535{
 536        struct efi_variable *var = &entry->var;
 537        efi_status_t status;
 538
 539        if (!entry || !buf)
 540                return -EINVAL;
 541
 542        status = get_var_data(entry->efivars, var);
 543        if (status != EFI_SUCCESS)
 544                return -EIO;
 545
 546        memcpy(buf, var->Data, var->DataSize);
 547        return var->DataSize;
 548}
 549/*
 550 * We allow each variable to be edited via rewriting the
 551 * entire efi variable structure.
 552 */
 553static ssize_t
 554efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
 555{
 556        struct efi_variable *new_var, *var = &entry->var;
 557        struct efivars *efivars = entry->efivars;
 558        efi_status_t status = EFI_NOT_FOUND;
 559
 560        if (count != sizeof(struct efi_variable))
 561                return -EINVAL;
 562
 563        new_var = (struct efi_variable *)buf;
 564        /*
 565         * If only updating the variable data, then the name
 566         * and guid should remain the same
 567         */
 568        if (memcmp(new_var->VariableName, var->VariableName, sizeof(var->VariableName)) ||
 569                efi_guidcmp(new_var->VendorGuid, var->VendorGuid)) {
 570                printk(KERN_ERR "efivars: Cannot edit the wrong variable!\n");
 571                return -EINVAL;
 572        }
 573
 574        if ((new_var->DataSize <= 0) || (new_var->Attributes == 0)){
 575                printk(KERN_ERR "efivars: DataSize & Attributes must be valid!\n");
 576                return -EINVAL;
 577        }
 578
 579        if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 ||
 580            validate_var(new_var, new_var->Data, new_var->DataSize) == false) {
 581                printk(KERN_ERR "efivars: Malformed variable content\n");
 582                return -EINVAL;
 583        }
 584
 585        spin_lock_irq(&efivars->lock);
 586
 587        status = check_var_size_locked(efivars, new_var->Attributes,
 588               new_var->DataSize + utf16_strsize(new_var->VariableName, 1024));
 589
 590        if (status == EFI_SUCCESS || status == EFI_UNSUPPORTED)
 591                status = efivars->ops->set_variable(new_var->VariableName,
 592                                                    &new_var->VendorGuid,
 593                                                    new_var->Attributes,
 594                                                    new_var->DataSize,
 595                                                    new_var->Data);
 596
 597        spin_unlock_irq(&efivars->lock);
 598
 599        if (status != EFI_SUCCESS) {
 600                printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
 601                        status);
 602                return -EIO;
 603        }
 604
 605        memcpy(&entry->var, new_var, count);
 606        return count;
 607}
 608
 609static ssize_t
 610efivar_show_raw(struct efivar_entry *entry, char *buf)
 611{
 612        struct efi_variable *var = &entry->var;
 613        efi_status_t status;
 614
 615        if (!entry || !buf)
 616                return 0;
 617
 618        status = get_var_data(entry->efivars, var);
 619        if (status != EFI_SUCCESS)
 620                return -EIO;
 621
 622        memcpy(buf, var, sizeof(*var));
 623        return sizeof(*var);
 624}
 625
 626/*
 627 * Generic read/write functions that call the specific functions of
 628 * the attributes...
 629 */
 630static ssize_t efivar_attr_show(struct kobject *kobj, struct attribute *attr,
 631                                char *buf)
 632{
 633        struct efivar_entry *var = to_efivar_entry(kobj);
 634        struct efivar_attribute *efivar_attr = to_efivar_attr(attr);
 635        ssize_t ret = -EIO;
 636
 637        if (!capable(CAP_SYS_ADMIN))
 638                return -EACCES;
 639
 640        if (efivar_attr->show) {
 641                ret = efivar_attr->show(var, buf);
 642        }
 643        return ret;
 644}
 645
 646static ssize_t efivar_attr_store(struct kobject *kobj, struct attribute *attr,
 647                                const char *buf, size_t count)
 648{
 649        struct efivar_entry *var = to_efivar_entry(kobj);
 650        struct efivar_attribute *efivar_attr = to_efivar_attr(attr);
 651        ssize_t ret = -EIO;
 652
 653        if (!capable(CAP_SYS_ADMIN))
 654                return -EACCES;
 655
 656        if (efivar_attr->store)
 657                ret = efivar_attr->store(var, buf, count);
 658
 659        return ret;
 660}
 661
 662static const struct sysfs_ops efivar_attr_ops = {
 663        .show = efivar_attr_show,
 664        .store = efivar_attr_store,
 665};
 666
 667static void efivar_release(struct kobject *kobj)
 668{
 669        struct efivar_entry *var = container_of(kobj, struct efivar_entry, kobj);
 670        kfree(var);
 671}
 672
 673static EFIVAR_ATTR(guid, 0400, efivar_guid_read, NULL);
 674static EFIVAR_ATTR(attributes, 0400, efivar_attr_read, NULL);
 675static EFIVAR_ATTR(size, 0400, efivar_size_read, NULL);
 676static EFIVAR_ATTR(data, 0400, efivar_data_read, NULL);
 677static EFIVAR_ATTR(raw_var, 0600, efivar_show_raw, efivar_store_raw);
 678
 679static struct attribute *def_attrs[] = {
 680        &efivar_attr_guid.attr,
 681        &efivar_attr_size.attr,
 682        &efivar_attr_attributes.attr,
 683        &efivar_attr_data.attr,
 684        &efivar_attr_raw_var.attr,
 685        NULL,
 686};
 687
 688static struct kobj_type efivar_ktype = {
 689        .release = efivar_release,
 690        .sysfs_ops = &efivar_attr_ops,
 691        .default_attrs = def_attrs,
 692};
 693
 694static inline void
 695efivar_unregister(struct efivar_entry *var)
 696{
 697        kobject_put(&var->kobj);
 698}
 699
 700static int efivarfs_file_open(struct inode *inode, struct file *file)
 701{
 702        file->private_data = inode->i_private;
 703        return 0;
 704}
 705
 706static int efi_status_to_err(efi_status_t status)
 707{
 708        int err;
 709
 710        switch (status) {
 711        case EFI_INVALID_PARAMETER:
 712                err = -EINVAL;
 713                break;
 714        case EFI_OUT_OF_RESOURCES:
 715                err = -ENOSPC;
 716                break;
 717        case EFI_DEVICE_ERROR:
 718                err = -EIO;
 719                break;
 720        case EFI_WRITE_PROTECTED:
 721                err = -EROFS;
 722                break;
 723        case EFI_SECURITY_VIOLATION:
 724                err = -EACCES;
 725                break;
 726        case EFI_NOT_FOUND:
 727                err = -EIO;
 728                break;
 729        default:
 730                err = -EINVAL;
 731        }
 732
 733        return err;
 734}
 735
 736static ssize_t efivarfs_file_write(struct file *file,
 737                const char __user *userbuf, size_t count, loff_t *ppos)
 738{
 739        struct efivar_entry *var = file->private_data;
 740        struct efivars *efivars;
 741        efi_status_t status;
 742        void *data;
 743        u32 attributes;
 744        struct inode *inode = file->f_mapping->host;
 745        unsigned long datasize = count - sizeof(attributes);
 746        unsigned long newdatasize, varsize;
 747        ssize_t bytes = 0;
 748
 749        if (count < sizeof(attributes))
 750                return -EINVAL;
 751
 752        if (copy_from_user(&attributes, userbuf, sizeof(attributes)))
 753                return -EFAULT;
 754
 755        if (attributes & ~(EFI_VARIABLE_MASK))
 756                return -EINVAL;
 757
 758        efivars = var->efivars;
 759
 760        /*
 761         * Ensure that the user can't allocate arbitrarily large
 762         * amounts of memory. Pick a default size of 64K if
 763         * QueryVariableInfo() isn't supported by the firmware.
 764         */
 765
 766        varsize = datasize + utf16_strsize(var->var.VariableName, 1024);
 767        status = check_var_size(efivars, attributes, varsize);
 768
 769        if (status != EFI_SUCCESS) {
 770                if (status != EFI_UNSUPPORTED)
 771                        return efi_status_to_err(status);
 772
 773                if (datasize > 65536)
 774                        return -ENOSPC;
 775        }
 776
 777        data = kmalloc(datasize, GFP_KERNEL);
 778        if (!data)
 779                return -ENOMEM;
 780
 781        if (copy_from_user(data, userbuf + sizeof(attributes), datasize)) {
 782                bytes = -EFAULT;
 783                goto out;
 784        }
 785
 786        if (validate_var(&var->var, data, datasize) == false) {
 787                bytes = -EINVAL;
 788                goto out;
 789        }
 790
 791        /*
 792         * The lock here protects the get_variable call, the conditional
 793         * set_variable call, and removal of the variable from the efivars
 794         * list (in the case of an authenticated delete).
 795         */
 796        spin_lock_irq(&efivars->lock);
 797
 798        /*
 799         * Ensure that the available space hasn't shrunk below the safe level
 800         */
 801
 802        status = check_var_size_locked(efivars, attributes, varsize);
 803
 804        if (status != EFI_SUCCESS && status != EFI_UNSUPPORTED) {
 805                spin_unlock_irq(&efivars->lock);
 806                kfree(data);
 807
 808                return efi_status_to_err(status);
 809        }
 810
 811        status = efivars->ops->set_variable(var->var.VariableName,
 812                                            &var->var.VendorGuid,
 813                                            attributes, datasize,
 814                                            data);
 815
 816        if (status != EFI_SUCCESS) {
 817                spin_unlock_irq(&efivars->lock);
 818                kfree(data);
 819
 820                return efi_status_to_err(status);
 821        }
 822
 823        bytes = count;
 824
 825        /*
 826         * Writing to the variable may have caused a change in size (which
 827         * could either be an append or an overwrite), or the variable to be
 828         * deleted. Perform a GetVariable() so we can tell what actually
 829         * happened.
 830         */
 831        newdatasize = 0;
 832        status = efivars->ops->get_variable(var->var.VariableName,
 833                                            &var->var.VendorGuid,
 834                                            NULL, &newdatasize,
 835                                            NULL);
 836
 837        if (status == EFI_BUFFER_TOO_SMALL) {
 838                spin_unlock_irq(&efivars->lock);
 839                mutex_lock(&inode->i_mutex);
 840                i_size_write(inode, newdatasize + sizeof(attributes));
 841                mutex_unlock(&inode->i_mutex);
 842
 843        } else if (status == EFI_NOT_FOUND) {
 844                list_del(&var->list);
 845                spin_unlock_irq(&efivars->lock);
 846                efivar_unregister(var);
 847                drop_nlink(inode);
 848                d_delete(file->f_dentry);
 849                dput(file->f_dentry);
 850
 851        } else {
 852                spin_unlock_irq(&efivars->lock);
 853                pr_warn("efivarfs: inconsistent EFI variable implementation? "
 854                                "status = %lx\n", status);
 855        }
 856
 857out:
 858        kfree(data);
 859
 860        return bytes;
 861}
 862
 863static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
 864                size_t count, loff_t *ppos)
 865{
 866        struct efivar_entry *var = file->private_data;
 867        struct efivars *efivars = var->efivars;
 868        efi_status_t status;
 869        unsigned long datasize = 0;
 870        u32 attributes;
 871        void *data;
 872        ssize_t size = 0;
 873
 874        spin_lock_irq(&efivars->lock);
 875        status = efivars->ops->get_variable(var->var.VariableName,
 876                                            &var->var.VendorGuid,
 877                                            &attributes, &datasize, NULL);
 878        spin_unlock_irq(&efivars->lock);
 879
 880        if (status != EFI_BUFFER_TOO_SMALL)
 881                return efi_status_to_err(status);
 882
 883        data = kmalloc(datasize + sizeof(attributes), GFP_KERNEL);
 884
 885        if (!data)
 886                return -ENOMEM;
 887
 888        spin_lock_irq(&efivars->lock);
 889        status = efivars->ops->get_variable(var->var.VariableName,
 890                                            &var->var.VendorGuid,
 891                                            &attributes, &datasize,
 892                                            (data + sizeof(attributes)));
 893        spin_unlock_irq(&efivars->lock);
 894
 895        if (status != EFI_SUCCESS) {
 896                size = efi_status_to_err(status);
 897                goto out_free;
 898        }
 899
 900        memcpy(data, &attributes, sizeof(attributes));
 901        size = simple_read_from_buffer(userbuf, count, ppos,
 902                                       data, datasize + sizeof(attributes));
 903out_free:
 904        kfree(data);
 905
 906        return size;
 907}
 908
 909static void efivarfs_evict_inode(struct inode *inode)
 910{
 911        clear_inode(inode);
 912}
 913
 914static const struct super_operations efivarfs_ops = {
 915        .statfs = simple_statfs,
 916        .drop_inode = generic_delete_inode,
 917        .evict_inode = efivarfs_evict_inode,
 918        .show_options = generic_show_options,
 919};
 920
 921static struct super_block *efivarfs_sb;
 922
 923static const struct inode_operations efivarfs_dir_inode_operations;
 924
 925static const struct file_operations efivarfs_file_operations = {
 926        .open   = efivarfs_file_open,
 927        .read   = efivarfs_file_read,
 928        .write  = efivarfs_file_write,
 929        .llseek = no_llseek,
 930};
 931
 932static struct inode *efivarfs_get_inode(struct super_block *sb,
 933                                const struct inode *dir, int mode, dev_t dev)
 934{
 935        struct inode *inode = new_inode(sb);
 936
 937        if (inode) {
 938                inode->i_ino = get_next_ino();
 939                inode->i_mode = mode;
 940                inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 941                switch (mode & S_IFMT) {
 942                case S_IFREG:
 943                        inode->i_fop = &efivarfs_file_operations;
 944                        break;
 945                case S_IFDIR:
 946                        inode->i_op = &efivarfs_dir_inode_operations;
 947                        inode->i_fop = &simple_dir_operations;
 948                        inc_nlink(inode);
 949                        break;
 950                }
 951        }
 952        return inode;
 953}
 954
 955/*
 956 * Return true if 'str' is a valid efivarfs filename of the form,
 957 *
 958 *      VariableName-12345678-1234-1234-1234-1234567891bc
 959 */
 960static bool efivarfs_valid_name(const char *str, int len)
 961{
 962        static const char dashes[GUID_LEN] = {
 963                [8] = 1, [13] = 1, [18] = 1, [23] = 1
 964        };
 965        const char *s = str + len - GUID_LEN;
 966        int i;
 967
 968        /*
 969         * We need a GUID, plus at least one letter for the variable name,
 970         * plus the '-' separator
 971         */
 972        if (len < GUID_LEN + 2)
 973                return false;
 974
 975        /* GUID must be preceded by a '-' */
 976        if (*(s - 1) != '-')
 977                return false;
 978
 979        /*
 980         * Validate that 's' is of the correct format, e.g.
 981         *
 982         *      12345678-1234-1234-1234-123456789abc
 983         */
 984        for (i = 0; i < GUID_LEN; i++) {
 985                if (dashes[i]) {
 986                        if (*s++ != '-')
 987                                return false;
 988                } else {
 989                        if (!isxdigit(*s++))
 990                                return false;
 991                }
 992        }
 993
 994        return true;
 995}
 996
 997static void efivarfs_hex_to_guid(const char *str, efi_guid_t *guid)
 998{
 999        guid->b[0] = hex_to_bin(str[6]) << 4 | hex_to_bin(str[7]);
1000        guid->b[1] = hex_to_bin(str[4]) << 4 | hex_to_bin(str[5]);
1001        guid->b[2] = hex_to_bin(str[2]) << 4 | hex_to_bin(str[3]);
1002        guid->b[3] = hex_to_bin(str[0]) << 4 | hex_to_bin(str[1]);
1003        guid->b[4] = hex_to_bin(str[11]) << 4 | hex_to_bin(str[12]);
1004        guid->b[5] = hex_to_bin(str[9]) << 4 | hex_to_bin(str[10]);
1005        guid->b[6] = hex_to_bin(str[16]) << 4 | hex_to_bin(str[17]);
1006        guid->b[7] = hex_to_bin(str[14]) << 4 | hex_to_bin(str[15]);
1007        guid->b[8] = hex_to_bin(str[19]) << 4 | hex_to_bin(str[20]);
1008        guid->b[9] = hex_to_bin(str[21]) << 4 | hex_to_bin(str[22]);
1009        guid->b[10] = hex_to_bin(str[24]) << 4 | hex_to_bin(str[25]);
1010        guid->b[11] = hex_to_bin(str[26]) << 4 | hex_to_bin(str[27]);
1011        guid->b[12] = hex_to_bin(str[28]) << 4 | hex_to_bin(str[29]);
1012        guid->b[13] = hex_to_bin(str[30]) << 4 | hex_to_bin(str[31]);
1013        guid->b[14] = hex_to_bin(str[32]) << 4 | hex_to_bin(str[33]);
1014        guid->b[15] = hex_to_bin(str[34]) << 4 | hex_to_bin(str[35]);
1015}
1016
1017static int efivarfs_create(struct inode *dir, struct dentry *dentry,
1018                          umode_t mode, bool excl)
1019{
1020        struct inode *inode;
1021        struct efivars *efivars = &__efivars;
1022        struct efivar_entry *var;
1023        int namelen, i = 0, err = 0;
1024
1025        if (!efivarfs_valid_name(dentry->d_name.name, dentry->d_name.len))
1026                return -EINVAL;
1027
1028        inode = efivarfs_get_inode(dir->i_sb, dir, mode, 0);
1029        if (!inode)
1030                return -ENOMEM;
1031
1032        var = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL);
1033        if (!var) {
1034                err = -ENOMEM;
1035                goto out;
1036        }
1037
1038        /* length of the variable name itself: remove GUID and separator */
1039        namelen = dentry->d_name.len - GUID_LEN - 1;
1040
1041        efivarfs_hex_to_guid(dentry->d_name.name + namelen + 1,
1042                        &var->var.VendorGuid);
1043
1044        for (i = 0; i < namelen; i++)
1045                var->var.VariableName[i] = dentry->d_name.name[i];
1046
1047        var->var.VariableName[i] = '\0';
1048
1049        inode->i_private = var;
1050        var->efivars = efivars;
1051        var->kobj.kset = efivars->kset;
1052
1053        err = kobject_init_and_add(&var->kobj, &efivar_ktype, NULL, "%s",
1054                             dentry->d_name.name);
1055        if (err)
1056                goto out;
1057
1058        kobject_uevent(&var->kobj, KOBJ_ADD);
1059        spin_lock_irq(&efivars->lock);
1060        list_add(&var->list, &efivars->list);
1061        spin_unlock_irq(&efivars->lock);
1062        d_instantiate(dentry, inode);
1063        dget(dentry);
1064out:
1065        if (err) {
1066                kfree(var);
1067                iput(inode);
1068        }
1069        return err;
1070}
1071
1072static int efivarfs_unlink(struct inode *dir, struct dentry *dentry)
1073{
1074        struct efivar_entry *var = dentry->d_inode->i_private;
1075        struct efivars *efivars = var->efivars;
1076        efi_status_t status;
1077
1078        spin_lock_irq(&efivars->lock);
1079
1080        status = efivars->ops->set_variable(var->var.VariableName,
1081                                            &var->var.VendorGuid,
1082                                            0, 0, NULL);
1083
1084        if (status == EFI_SUCCESS || status == EFI_NOT_FOUND) {
1085                list_del(&var->list);
1086                spin_unlock_irq(&efivars->lock);
1087                efivar_unregister(var);
1088                drop_nlink(dentry->d_inode);
1089                dput(dentry);
1090                return 0;
1091        }
1092
1093        spin_unlock_irq(&efivars->lock);
1094        return -EINVAL;
1095};
1096
1097/*
1098 * Compare two efivarfs file names.
1099 *
1100 * An efivarfs filename is composed of two parts,
1101 *
1102 *      1. A case-sensitive variable name
1103 *      2. A case-insensitive GUID
1104 *
1105 * So we need to perform a case-sensitive match on part 1 and a
1106 * case-insensitive match on part 2.
1107 */
1108static int efivarfs_d_compare(const struct dentry *parent, const struct inode *pinode,
1109                              const struct dentry *dentry, const struct inode *inode,
1110                              unsigned int len, const char *str,
1111                              const struct qstr *name)
1112{
1113        int guid = len - GUID_LEN;
1114
1115        if (name->len != len)
1116                return 1;
1117
1118        /* Case-sensitive compare for the variable name */
1119        if (memcmp(str, name->name, guid))
1120                return 1;
1121
1122        /* Case-insensitive compare for the GUID */
1123        return strncasecmp(name->name + guid, str + guid, GUID_LEN);
1124}
1125
1126static int efivarfs_d_hash(const struct dentry *dentry,
1127                           const struct inode *inode, struct qstr *qstr)
1128{
1129        unsigned long hash = init_name_hash();
1130        const unsigned char *s = qstr->name;
1131        unsigned int len = qstr->len;
1132
1133        if (!efivarfs_valid_name(s, len))
1134                return -EINVAL;
1135
1136        while (len-- > GUID_LEN)
1137                hash = partial_name_hash(*s++, hash);
1138
1139        /* GUID is case-insensitive. */
1140        while (len--)
1141                hash = partial_name_hash(tolower(*s++), hash);
1142
1143        qstr->hash = end_name_hash(hash);
1144        return 0;
1145}
1146
1147/*
1148 * Retaining negative dentries for an in-memory filesystem just wastes
1149 * memory and lookup time: arrange for them to be deleted immediately.
1150 */
1151static int efivarfs_delete_dentry(const struct dentry *dentry)
1152{
1153        return 1;
1154}
1155
1156static struct dentry_operations efivarfs_d_ops = {
1157        .d_compare = efivarfs_d_compare,
1158        .d_hash = efivarfs_d_hash,
1159        .d_delete = efivarfs_delete_dentry,
1160};
1161
1162static struct dentry *efivarfs_alloc_dentry(struct dentry *parent, char *name)
1163{
1164        struct dentry *d;
1165        struct qstr q;
1166        int err;
1167
1168        q.name = name;
1169        q.len = strlen(name);
1170
1171        err = efivarfs_d_hash(NULL, NULL, &q);
1172        if (err)
1173                return ERR_PTR(err);
1174
1175        d = d_alloc(parent, &q);
1176        if (d)
1177                return d;
1178
1179        return ERR_PTR(-ENOMEM);
1180}
1181
1182static int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
1183{
1184        struct inode *inode = NULL;
1185        struct dentry *root;
1186        struct efivar_entry *entry, *n;
1187        struct efivars *efivars = &__efivars;
1188        char *name;
1189        int err = -ENOMEM;
1190
1191        efivarfs_sb = sb;
1192
1193        sb->s_maxbytes          = MAX_LFS_FILESIZE;
1194        sb->s_blocksize         = PAGE_CACHE_SIZE;
1195        sb->s_blocksize_bits    = PAGE_CACHE_SHIFT;
1196        sb->s_magic             = EFIVARFS_MAGIC;
1197        sb->s_op                = &efivarfs_ops;
1198        sb->s_d_op              = &efivarfs_d_ops;
1199        sb->s_time_gran         = 1;
1200
1201        inode = efivarfs_get_inode(sb, NULL, S_IFDIR | 0755, 0);
1202        if (!inode)
1203                return -ENOMEM;
1204        inode->i_op = &efivarfs_dir_inode_operations;
1205
1206        root = d_make_root(inode);
1207        sb->s_root = root;
1208        if (!root)
1209                return -ENOMEM;
1210
1211        list_for_each_entry_safe(entry, n, &efivars->list, list) {
1212                struct dentry *dentry, *root = efivarfs_sb->s_root;
1213                unsigned long size = 0;
1214                int len, i;
1215
1216                inode = NULL;
1217
1218                len = utf16_strlen(entry->var.VariableName);
1219
1220                /* name, plus '-', plus GUID, plus NUL*/
1221                name = kmalloc(len + 1 + GUID_LEN + 1, GFP_ATOMIC);
1222                if (!name)
1223                        goto fail;
1224
1225                for (i = 0; i < len; i++)
1226                        name[i] = entry->var.VariableName[i] & 0xFF;
1227
1228                name[len] = '-';
1229
1230                efi_guid_unparse(&entry->var.VendorGuid, name + len + 1);
1231
1232                name[len+GUID_LEN+1] = '\0';
1233
1234                inode = efivarfs_get_inode(efivarfs_sb, root->d_inode,
1235                                          S_IFREG | 0644, 0);
1236                if (!inode)
1237                        goto fail_name;
1238
1239                dentry = efivarfs_alloc_dentry(root, name);
1240                if (IS_ERR(dentry)) {
1241                        err = PTR_ERR(dentry);
1242                        goto fail_inode;
1243                }
1244
1245                /* copied by the above to local storage in the dentry. */
1246                kfree(name);
1247
1248                spin_lock_irq(&efivars->lock);
1249                efivars->ops->get_variable(entry->var.VariableName,
1250                                           &entry->var.VendorGuid,
1251                                           &entry->var.Attributes,
1252                                           &size,
1253                                           NULL);
1254                spin_unlock_irq(&efivars->lock);
1255
1256                mutex_lock(&inode->i_mutex);
1257                inode->i_private = entry;
1258                i_size_write(inode, size+4);
1259                mutex_unlock(&inode->i_mutex);
1260                d_add(dentry, inode);
1261        }
1262
1263        return 0;
1264
1265fail_inode:
1266        iput(inode);
1267fail_name:
1268        kfree(name);
1269fail:
1270        return err;
1271}
1272
1273static struct dentry *efivarfs_mount(struct file_system_type *fs_type,
1274                                    int flags, const char *dev_name, void *data)
1275{
1276        return mount_single(fs_type, flags, data, efivarfs_fill_super);
1277}
1278
1279static void efivarfs_kill_sb(struct super_block *sb)
1280{
1281        kill_litter_super(sb);
1282        efivarfs_sb = NULL;
1283}
1284
1285static struct file_system_type efivarfs_type = {
1286        .name    = "efivarfs",
1287        .mount   = efivarfs_mount,
1288        .kill_sb = efivarfs_kill_sb,
1289};
1290
1291/*
1292 * Handle negative dentry.
1293 */
1294static struct dentry *efivarfs_lookup(struct inode *dir, struct dentry *dentry,
1295                                      unsigned int flags)
1296{
1297        if (dentry->d_name.len > NAME_MAX)
1298                return ERR_PTR(-ENAMETOOLONG);
1299        d_add(dentry, NULL);
1300        return NULL;
1301}
1302
1303static const struct inode_operations efivarfs_dir_inode_operations = {
1304        .lookup = efivarfs_lookup,
1305        .unlink = efivarfs_unlink,
1306        .create = efivarfs_create,
1307};
1308
1309#ifdef CONFIG_EFI_VARS_PSTORE
1310
1311static int efi_pstore_open(struct pstore_info *psi)
1312{
1313        struct efivars *efivars = psi->data;
1314
1315        spin_lock_irq(&efivars->lock);
1316        efivars->walk_entry = list_first_entry(&efivars->list,
1317                                               struct efivar_entry, list);
1318        return 0;
1319}
1320
1321static int efi_pstore_close(struct pstore_info *psi)
1322{
1323        struct efivars *efivars = psi->data;
1324
1325        spin_unlock_irq(&efivars->lock);
1326        return 0;
1327}
1328
1329static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
1330                               int *count, struct timespec *timespec,
1331                               char **buf, struct pstore_info *psi)
1332{
1333        efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
1334        struct efivars *efivars = psi->data;
1335        char name[DUMP_NAME_LEN];
1336        int i;
1337        int cnt;
1338        unsigned int part, size;
1339        unsigned long time;
1340
1341        while (&efivars->walk_entry->list != &efivars->list) {
1342                if (!efi_guidcmp(efivars->walk_entry->var.VendorGuid,
1343                                 vendor)) {
1344                        for (i = 0; i < DUMP_NAME_LEN; i++) {
1345                                name[i] = efivars->walk_entry->var.VariableName[i];
1346                        }
1347                        if (sscanf(name, "dump-type%u-%u-%d-%lu",
1348                                   type, &part, &cnt, &time) == 4) {
1349                                *id = part;
1350                                *count = cnt;
1351                                timespec->tv_sec = time;
1352                                timespec->tv_nsec = 0;
1353                        } else if (sscanf(name, "dump-type%u-%u-%lu",
1354                                   type, &part, &time) == 3) {
1355                                /*
1356                                 * Check if an old format,
1357                                 * which doesn't support holding
1358                                 * multiple logs, remains.
1359                                 */
1360                                *id = part;
1361                                *count = 0;
1362                                timespec->tv_sec = time;
1363                                timespec->tv_nsec = 0;
1364                        } else {
1365                                efivars->walk_entry = list_entry(
1366                                                efivars->walk_entry->list.next,
1367                                                struct efivar_entry, list);
1368                                continue;
1369                        }
1370
1371                        get_var_data_locked(efivars, &efivars->walk_entry->var);
1372                        size = efivars->walk_entry->var.DataSize;
1373                        *buf = kmalloc(size, GFP_KERNEL);
1374                        if (*buf == NULL)
1375                                return -ENOMEM;
1376                        memcpy(*buf, efivars->walk_entry->var.Data,
1377                               size);
1378                        efivars->walk_entry = list_entry(
1379                                        efivars->walk_entry->list.next,
1380                                        struct efivar_entry, list);
1381                        return size;
1382                }
1383                efivars->walk_entry = list_entry(efivars->walk_entry->list.next,
1384                                                 struct efivar_entry, list);
1385        }
1386        return 0;
1387}
1388
1389static int efi_pstore_write(enum pstore_type_id type,
1390                enum kmsg_dump_reason reason, u64 *id,
1391                unsigned int part, int count, size_t size,
1392                struct pstore_info *psi)
1393{
1394        char name[DUMP_NAME_LEN];
1395        efi_char16_t efi_name[DUMP_NAME_LEN];
1396        efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
1397        struct efivars *efivars = psi->data;
1398        int i, ret = 0;
1399        efi_status_t status = EFI_NOT_FOUND;
1400        unsigned long flags;
1401
1402        spin_lock_irqsave(&efivars->lock, flags);
1403
1404        /*
1405         * Check if there is a space enough to log.
1406         * size: a size of logging data
1407         * DUMP_NAME_LEN * 2: a maximum size of variable name
1408         */
1409
1410        status = check_var_size_locked(efivars, PSTORE_EFI_ATTRIBUTES,
1411                                         size + DUMP_NAME_LEN * 2);
1412
1413        if (status) {
1414                spin_unlock_irqrestore(&efivars->lock, flags);
1415                *id = part;
1416                return -ENOSPC;
1417        }
1418
1419        sprintf(name, "dump-type%u-%u-%d-%lu", type, part, count,
1420                get_seconds());
1421
1422        for (i = 0; i < DUMP_NAME_LEN; i++)
1423                efi_name[i] = name[i];
1424
1425        efivars->ops->set_variable(efi_name, &vendor, PSTORE_EFI_ATTRIBUTES,
1426                                   size, psi->buf);
1427
1428        spin_unlock_irqrestore(&efivars->lock, flags);
1429
1430        if (size)
1431                ret = efivar_create_sysfs_entry(efivars,
1432                                          utf16_strsize(efi_name,
1433                                                        DUMP_NAME_LEN * 2),
1434                                          efi_name, &vendor);
1435
1436        *id = part;
1437        return ret;
1438};
1439
1440static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
1441                            struct timespec time, struct pstore_info *psi)
1442{
1443        char name[DUMP_NAME_LEN];
1444        efi_char16_t efi_name[DUMP_NAME_LEN];
1445        char name_old[DUMP_NAME_LEN];
1446        efi_char16_t efi_name_old[DUMP_NAME_LEN];
1447        efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
1448        struct efivars *efivars = psi->data;
1449        struct efivar_entry *entry, *found = NULL;
1450        int i;
1451
1452        sprintf(name, "dump-type%u-%u-%d-%lu", type, (unsigned int)id, count,
1453                time.tv_sec);
1454
1455        spin_lock_irq(&efivars->lock);
1456
1457        for (i = 0; i < DUMP_NAME_LEN; i++)
1458                efi_name[i] = name[i];
1459
1460        /*
1461         * Clean up an entry with the same name
1462         */
1463
1464        list_for_each_entry(entry, &efivars->list, list) {
1465                get_var_data_locked(efivars, &entry->var);
1466
1467                if (efi_guidcmp(entry->var.VendorGuid, vendor))
1468                        continue;
1469                if (utf16_strncmp(entry->var.VariableName, efi_name,
1470                                  utf16_strlen(efi_name))) {
1471                        /*
1472                         * Check if an old format,
1473                         * which doesn't support holding
1474                         * multiple logs, remains.
1475                         */
1476                        sprintf(name_old, "dump-type%u-%u-%lu", type,
1477                                (unsigned int)id, time.tv_sec);
1478
1479                        for (i = 0; i < DUMP_NAME_LEN; i++)
1480                                efi_name_old[i] = name_old[i];
1481
1482                        if (utf16_strncmp(entry->var.VariableName, efi_name_old,
1483                                          utf16_strlen(efi_name_old)))
1484                                continue;
1485                }
1486
1487                /* found */
1488                found = entry;
1489                efivars->ops->set_variable(entry->var.VariableName,
1490                                           &entry->var.VendorGuid,
1491                                           PSTORE_EFI_ATTRIBUTES,
1492                                           0, NULL);
1493                break;
1494        }
1495
1496        if (found)
1497                list_del(&found->list);
1498
1499        spin_unlock_irq(&efivars->lock);
1500
1501        if (found)
1502                efivar_unregister(found);
1503
1504        return 0;
1505}
1506
1507static struct pstore_info efi_pstore_info = {
1508        .owner          = THIS_MODULE,
1509        .name           = "efi",
1510        .open           = efi_pstore_open,
1511        .close          = efi_pstore_close,
1512        .read           = efi_pstore_read,
1513        .write          = efi_pstore_write,
1514        .erase          = efi_pstore_erase,
1515};
1516
1517static void efivar_pstore_register(struct efivars *efivars)
1518{
1519        efivars->efi_pstore_info = efi_pstore_info;
1520        efivars->efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL);
1521        if (efivars->efi_pstore_info.buf) {
1522                efivars->efi_pstore_info.bufsize = 1024;
1523                efivars->efi_pstore_info.data = efivars;
1524                spin_lock_init(&efivars->efi_pstore_info.buf_lock);
1525                pstore_register(&efivars->efi_pstore_info);
1526        }
1527}
1528#else
1529static void efivar_pstore_register(struct efivars *efivars)
1530{
1531        return;
1532}
1533#endif
1534
1535static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
1536                             struct bin_attribute *bin_attr,
1537                             char *buf, loff_t pos, size_t count)
1538{
1539        struct efi_variable *new_var = (struct efi_variable *)buf;
1540        struct efivars *efivars = bin_attr->private;
1541        struct efivar_entry *search_efivar, *n;
1542        unsigned long strsize1, strsize2;
1543        efi_status_t status = EFI_NOT_FOUND;
1544        int found = 0;
1545
1546        if (!capable(CAP_SYS_ADMIN))
1547                return -EACCES;
1548
1549        if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 ||
1550            validate_var(new_var, new_var->Data, new_var->DataSize) == false) {
1551                printk(KERN_ERR "efivars: Malformed variable content\n");
1552                return -EINVAL;
1553        }
1554
1555        spin_lock_irq(&efivars->lock);
1556
1557        /*
1558         * Does this variable already exist?
1559         */
1560        list_for_each_entry_safe(search_efivar, n, &efivars->list, list) {
1561                strsize1 = utf16_strsize(search_efivar->var.VariableName, 1024);
1562                strsize2 = utf16_strsize(new_var->VariableName, 1024);
1563                if (strsize1 == strsize2 &&
1564                        !memcmp(&(search_efivar->var.VariableName),
1565                                new_var->VariableName, strsize1) &&
1566                        !efi_guidcmp(search_efivar->var.VendorGuid,
1567                                new_var->VendorGuid)) {
1568                        found = 1;
1569                        break;
1570                }
1571        }
1572        if (found) {
1573                spin_unlock_irq(&efivars->lock);
1574                return -EINVAL;
1575        }
1576
1577        status = check_var_size_locked(efivars, new_var->Attributes,
1578               new_var->DataSize + utf16_strsize(new_var->VariableName, 1024));
1579
1580        if (status && status != EFI_UNSUPPORTED) {
1581                spin_unlock_irq(&efivars->lock);
1582                return efi_status_to_err(status);
1583        }
1584
1585        /* now *really* create the variable via EFI */
1586        status = efivars->ops->set_variable(new_var->VariableName,
1587                                            &new_var->VendorGuid,
1588                                            new_var->Attributes,
1589                                            new_var->DataSize,
1590                                            new_var->Data);
1591
1592        if (status != EFI_SUCCESS) {
1593                printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
1594                        status);
1595                spin_unlock_irq(&efivars->lock);
1596                return -EIO;
1597        }
1598        spin_unlock_irq(&efivars->lock);
1599
1600        /* Create the entry in sysfs.  Locking is not required here */
1601        status = efivar_create_sysfs_entry(efivars,
1602                                           utf16_strsize(new_var->VariableName,
1603                                                         1024),
1604                                           new_var->VariableName,
1605                                           &new_var->VendorGuid);
1606        if (status) {
1607                printk(KERN_WARNING "efivars: variable created, but sysfs entry wasn't.\n");
1608        }
1609        return count;
1610}
1611
1612static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
1613                             struct bin_attribute *bin_attr,
1614                             char *buf, loff_t pos, size_t count)
1615{
1616        struct efi_variable *del_var = (struct efi_variable *)buf;
1617        struct efivars *efivars = bin_attr->private;
1618        struct efivar_entry *search_efivar, *n;
1619        unsigned long strsize1, strsize2;
1620        efi_status_t status = EFI_NOT_FOUND;
1621        int found = 0;
1622
1623        if (!capable(CAP_SYS_ADMIN))
1624                return -EACCES;
1625
1626        spin_lock_irq(&efivars->lock);
1627
1628        /*
1629         * Does this variable already exist?
1630         */
1631        list_for_each_entry_safe(search_efivar, n, &efivars->list, list) {
1632                strsize1 = utf16_strsize(search_efivar->var.VariableName, 1024);
1633                strsize2 = utf16_strsize(del_var->VariableName, 1024);
1634                if (strsize1 == strsize2 &&
1635                        !memcmp(&(search_efivar->var.VariableName),
1636                                del_var->VariableName, strsize1) &&
1637                        !efi_guidcmp(search_efivar->var.VendorGuid,
1638                                del_var->VendorGuid)) {
1639                        found = 1;
1640                        break;
1641                }
1642        }
1643        if (!found) {
1644                spin_unlock_irq(&efivars->lock);
1645                return -EINVAL;
1646        }
1647        /* force the Attributes/DataSize to 0 to ensure deletion */
1648        del_var->Attributes = 0;
1649        del_var->DataSize = 0;
1650
1651        status = efivars->ops->set_variable(del_var->VariableName,
1652                                            &del_var->VendorGuid,
1653                                            del_var->Attributes,
1654                                            del_var->DataSize,
1655                                            del_var->Data);
1656
1657        if (status != EFI_SUCCESS) {
1658                printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
1659                        status);
1660                spin_unlock_irq(&efivars->lock);
1661                return -EIO;
1662        }
1663        list_del(&search_efivar->list);
1664        /* We need to release this lock before unregistering. */
1665        spin_unlock_irq(&efivars->lock);
1666        efivar_unregister(search_efivar);
1667
1668        /* It's dead Jim.... */
1669        return count;
1670}
1671
1672static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor)
1673{
1674        struct efivar_entry *entry, *n;
1675        struct efivars *efivars = &__efivars;
1676        unsigned long strsize1, strsize2;
1677        bool found = false;
1678
1679        strsize1 = utf16_strsize(variable_name, 1024);
1680        list_for_each_entry_safe(entry, n, &efivars->list, list) {
1681                strsize2 = utf16_strsize(entry->var.VariableName, 1024);
1682                if (strsize1 == strsize2 &&
1683                        !memcmp(variable_name, &(entry->var.VariableName),
1684                                strsize2) &&
1685                        !efi_guidcmp(entry->var.VendorGuid,
1686                                *vendor)) {
1687                        found = true;
1688                        break;
1689                }
1690        }
1691        return found;
1692}
1693
1694/*
1695 * Returns the size of variable_name, in bytes, including the
1696 * terminating NULL character, or variable_name_size if no NULL
1697 * character is found among the first variable_name_size bytes.
1698 */
1699static unsigned long var_name_strnsize(efi_char16_t *variable_name,
1700                                       unsigned long variable_name_size)
1701{
1702        unsigned long len;
1703        efi_char16_t c;
1704
1705        /*
1706         * The variable name is, by definition, a NULL-terminated
1707         * string, so make absolutely sure that variable_name_size is
1708         * the value we expect it to be. If not, return the real size.
1709         */
1710        for (len = 2; len <= variable_name_size; len += sizeof(c)) {
1711                c = variable_name[(len / sizeof(c)) - 1];
1712                if (!c)
1713                        break;
1714        }
1715
1716        return min(len, variable_name_size);
1717}
1718
1719/*
1720 * Let's not leave out systab information that snuck into
1721 * the efivars driver
1722 */
1723static ssize_t systab_show(struct kobject *kobj,
1724                           struct kobj_attribute *attr, char *buf)
1725{
1726        char *str = buf;
1727
1728        if (!kobj || !buf)
1729                return -EINVAL;
1730
1731        if (efi.mps != EFI_INVALID_TABLE_ADDR)
1732                str += sprintf(str, "MPS=0x%lx\n", efi.mps);
1733        if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
1734                str += sprintf(str, "ACPI20=0x%lx\n", efi.acpi20);
1735        if (efi.acpi != EFI_INVALID_TABLE_ADDR)
1736                str += sprintf(str, "ACPI=0x%lx\n", efi.acpi);
1737        if (efi.smbios != EFI_INVALID_TABLE_ADDR)
1738                str += sprintf(str, "SMBIOS=0x%lx\n", efi.smbios);
1739        if (efi.hcdp != EFI_INVALID_TABLE_ADDR)
1740                str += sprintf(str, "HCDP=0x%lx\n", efi.hcdp);
1741        if (efi.boot_info != EFI_INVALID_TABLE_ADDR)
1742                str += sprintf(str, "BOOTINFO=0x%lx\n", efi.boot_info);
1743        if (efi.uga != EFI_INVALID_TABLE_ADDR)
1744                str += sprintf(str, "UGA=0x%lx\n", efi.uga);
1745
1746        return str - buf;
1747}
1748
1749static struct kobj_attribute efi_attr_systab =
1750                        __ATTR(systab, 0400, systab_show, NULL);
1751
1752static struct attribute *efi_subsys_attrs[] = {
1753        &efi_attr_systab.attr,
1754        NULL,   /* maybe more in the future? */
1755};
1756
1757static struct attribute_group efi_subsys_attr_group = {
1758        .attrs = efi_subsys_attrs,
1759};
1760
1761static struct kobject *efi_kobj;
1762
1763/*
1764 * efivar_create_sysfs_entry()
1765 * Requires:
1766 *    variable_name_size = number of bytes required to hold
1767 *                         variable_name (not counting the NULL
1768 *                         character at the end.
1769 *    efivars->lock is not held on entry or exit.
1770 * Returns 1 on failure, 0 on success
1771 */
1772static int
1773efivar_create_sysfs_entry(struct efivars *efivars,
1774                          unsigned long variable_name_size,
1775                          efi_char16_t *variable_name,
1776                          efi_guid_t *vendor_guid)
1777{
1778        int i, short_name_size;
1779        char *short_name;
1780        struct efivar_entry *new_efivar;
1781
1782        /*
1783         * Length of the variable bytes in ASCII, plus the '-' separator,
1784         * plus the GUID, plus trailing NUL
1785         */
1786        short_name_size = variable_name_size / sizeof(efi_char16_t)
1787                                + 1 + GUID_LEN + 1;
1788
1789        short_name = kzalloc(short_name_size, GFP_KERNEL);
1790        new_efivar = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL);
1791
1792        if (!short_name || !new_efivar)  {
1793                kfree(short_name);
1794                kfree(new_efivar);
1795                return 1;
1796        }
1797
1798        new_efivar->efivars = efivars;
1799        memcpy(new_efivar->var.VariableName, variable_name,
1800                variable_name_size);
1801        memcpy(&(new_efivar->var.VendorGuid), vendor_guid, sizeof(efi_guid_t));
1802
1803        /* Convert Unicode to normal chars (assume top bits are 0),
1804           ala UTF-8 */
1805        for (i=0; i < (int)(variable_name_size / sizeof(efi_char16_t)); i++) {
1806                short_name[i] = variable_name[i] & 0xFF;
1807        }
1808        /* This is ugly, but necessary to separate one vendor's
1809           private variables from another's.         */
1810
1811        *(short_name + strlen(short_name)) = '-';
1812        efi_guid_unparse(vendor_guid, short_name + strlen(short_name));
1813
1814        new_efivar->kobj.kset = efivars->kset;
1815        i = kobject_init_and_add(&new_efivar->kobj, &efivar_ktype, NULL,
1816                                 "%s", short_name);
1817        if (i) {
1818                kfree(short_name);
1819                kfree(new_efivar);
1820                return 1;
1821        }
1822
1823        kobject_uevent(&new_efivar->kobj, KOBJ_ADD);
1824        kfree(short_name);
1825        short_name = NULL;
1826
1827        spin_lock_irq(&efivars->lock);
1828        list_add(&new_efivar->list, &efivars->list);
1829        spin_unlock_irq(&efivars->lock);
1830
1831        return 0;
1832}
1833
1834static int
1835create_efivars_bin_attributes(struct efivars *efivars)
1836{
1837        struct bin_attribute *attr;
1838        int error;
1839
1840        /* new_var */
1841        attr = kzalloc(sizeof(*attr), GFP_KERNEL);
1842        if (!attr)
1843                return -ENOMEM;
1844
1845        attr->attr.name = "new_var";
1846        attr->attr.mode = 0200;
1847        attr->write = efivar_create;
1848        attr->private = efivars;
1849        efivars->new_var = attr;
1850
1851        /* del_var */
1852        attr = kzalloc(sizeof(*attr), GFP_KERNEL);
1853        if (!attr) {
1854                error = -ENOMEM;
1855                goto out_free;
1856        }
1857        attr->attr.name = "del_var";
1858        attr->attr.mode = 0200;
1859        attr->write = efivar_delete;
1860        attr->private = efivars;
1861        efivars->del_var = attr;
1862
1863        sysfs_bin_attr_init(efivars->new_var);
1864        sysfs_bin_attr_init(efivars->del_var);
1865
1866        /* Register */
1867        error = sysfs_create_bin_file(&efivars->kset->kobj,
1868                                      efivars->new_var);
1869        if (error) {
1870                printk(KERN_ERR "efivars: unable to create new_var sysfs file"
1871                        " due to error %d\n", error);
1872                goto out_free;
1873        }
1874        error = sysfs_create_bin_file(&efivars->kset->kobj,
1875                                      efivars->del_var);
1876        if (error) {
1877                printk(KERN_ERR "efivars: unable to create del_var sysfs file"
1878                        " due to error %d\n", error);
1879                sysfs_remove_bin_file(&efivars->kset->kobj,
1880                                      efivars->new_var);
1881                goto out_free;
1882        }
1883
1884        return 0;
1885out_free:
1886        kfree(efivars->del_var);
1887        efivars->del_var = NULL;
1888        kfree(efivars->new_var);
1889        efivars->new_var = NULL;
1890        return error;
1891}
1892
1893void unregister_efivars(struct efivars *efivars)
1894{
1895        struct efivar_entry *entry, *n;
1896
1897        list_for_each_entry_safe(entry, n, &efivars->list, list) {
1898                spin_lock_irq(&efivars->lock);
1899                list_del(&entry->list);
1900                spin_unlock_irq(&efivars->lock);
1901                efivar_unregister(entry);
1902        }
1903        if (efivars->new_var)
1904                sysfs_remove_bin_file(&efivars->kset->kobj, efivars->new_var);
1905        if (efivars->del_var)
1906                sysfs_remove_bin_file(&efivars->kset->kobj, efivars->del_var);
1907        kfree(efivars->new_var);
1908        kfree(efivars->del_var);
1909        kobject_put(efivars->kobject);
1910        kset_unregister(efivars->kset);
1911}
1912EXPORT_SYMBOL_GPL(unregister_efivars);
1913
1914/*
1915 * Print a warning when duplicate EFI variables are encountered and
1916 * disable the sysfs workqueue since the firmware is buggy.
1917 */
1918static void dup_variable_bug(efi_char16_t *s16, efi_guid_t *vendor_guid,
1919                             unsigned long len16)
1920{
1921        size_t i, len8 = len16 / sizeof(efi_char16_t);
1922        char *s8;
1923
1924        s8 = kzalloc(len8, GFP_KERNEL);
1925        if (!s8)
1926                return;
1927
1928        for (i = 0; i < len8; i++)
1929                s8[i] = s16[i];
1930
1931        printk(KERN_WARNING "efivars: duplicate variable: %s-%pUl\n",
1932               s8, vendor_guid);
1933        kfree(s8);
1934}
1935
1936int register_efivars(struct efivars *efivars,
1937                     const struct efivar_operations *ops,
1938                     struct kobject *parent_kobj)
1939{
1940        efi_status_t status = EFI_NOT_FOUND;
1941        efi_guid_t vendor_guid;
1942        efi_char16_t *variable_name;
1943        unsigned long variable_name_size = 1024;
1944        int error = 0;
1945
1946        variable_name = kzalloc(variable_name_size, GFP_KERNEL);
1947        if (!variable_name) {
1948                printk(KERN_ERR "efivars: Memory allocation failed.\n");
1949                return -ENOMEM;
1950        }
1951
1952        spin_lock_init(&efivars->lock);
1953        INIT_LIST_HEAD(&efivars->list);
1954        efivars->ops = ops;
1955
1956        efivars->kset = kset_create_and_add("vars", NULL, parent_kobj);
1957        if (!efivars->kset) {
1958                printk(KERN_ERR "efivars: Subsystem registration failed.\n");
1959                error = -ENOMEM;
1960                goto out;
1961        }
1962
1963        efivars->kobject = kobject_create_and_add("efivars", parent_kobj);
1964        if (!efivars->kobject) {
1965                pr_err("efivars: Subsystem registration failed.\n");
1966                error = -ENOMEM;
1967                kset_unregister(efivars->kset);
1968                goto out;
1969        }
1970
1971        /*
1972         * Per EFI spec, the maximum storage allocated for both
1973         * the variable name and variable data is 1024 bytes.
1974         */
1975
1976        do {
1977                variable_name_size = 1024;
1978
1979                status = ops->get_next_variable(&variable_name_size,
1980                                                variable_name,
1981                                                &vendor_guid);
1982                switch (status) {
1983                case EFI_SUCCESS:
1984                        variable_name_size = var_name_strnsize(variable_name,
1985                                                               variable_name_size);
1986
1987                        /*
1988                         * Some firmware implementations return the
1989                         * same variable name on multiple calls to
1990                         * get_next_variable(). Terminate the loop
1991                         * immediately as there is no guarantee that
1992                         * we'll ever see a different variable name,
1993                         * and may end up looping here forever.
1994                         */
1995                        if (variable_is_present(variable_name, &vendor_guid)) {
1996                                dup_variable_bug(variable_name, &vendor_guid,
1997                                                 variable_name_size);
1998                                status = EFI_NOT_FOUND;
1999                                break;
2000                        }
2001
2002                        efivar_create_sysfs_entry(efivars,
2003                                                  variable_name_size,
2004                                                  variable_name,
2005                                                  &vendor_guid);
2006                        break;
2007                case EFI_NOT_FOUND:
2008                        break;
2009                default:
2010                        printk(KERN_WARNING "efivars: get_next_variable: status=%lx\n",
2011                                status);
2012                        status = EFI_NOT_FOUND;
2013                        break;
2014                }
2015        } while (status != EFI_NOT_FOUND);
2016
2017        error = create_efivars_bin_attributes(efivars);
2018        if (error)
2019                unregister_efivars(efivars);
2020
2021        if (!efivars_pstore_disable)
2022                efivar_pstore_register(efivars);
2023
2024        register_filesystem(&efivarfs_type);
2025
2026out:
2027        kfree(variable_name);
2028
2029        return error;
2030}
2031EXPORT_SYMBOL_GPL(register_efivars);
2032
2033/*
2034 * For now we register the efi subsystem with the firmware subsystem
2035 * and the vars subsystem with the efi subsystem.  In the future, it
2036 * might make sense to split off the efi subsystem into its own
2037 * driver, but for now only efivars will register with it, so just
2038 * include it here.
2039 */
2040
2041static int __init
2042efivars_init(void)
2043{
2044        int error = 0;
2045
2046        printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION,
2047               EFIVARS_DATE);
2048
2049        if (!efi_enabled(EFI_RUNTIME_SERVICES))
2050                return 0;
2051
2052        /* For now we'll register the efi directory at /sys/firmware/efi */
2053        efi_kobj = kobject_create_and_add("efi", firmware_kobj);
2054        if (!efi_kobj) {
2055                printk(KERN_ERR "efivars: Firmware registration failed.\n");
2056                return -ENOMEM;
2057        }
2058
2059        ops.get_variable = efi.get_variable;
2060        ops.set_variable = efi.set_variable;
2061        ops.get_next_variable = efi.get_next_variable;
2062        ops.query_variable_info = efi.query_variable_info;
2063
2064        error = register_efivars(&__efivars, &ops, efi_kobj);
2065        if (error)
2066                goto err_put;
2067
2068        /* Don't forget the systab entry */
2069        error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group);
2070        if (error) {
2071                printk(KERN_ERR
2072                       "efivars: Sysfs attribute export failed with error %d.\n",
2073                       error);
2074                goto err_unregister;
2075        }
2076
2077        return 0;
2078
2079err_unregister:
2080        unregister_efivars(&__efivars);
2081err_put:
2082        kobject_put(efi_kobj);
2083        return error;
2084}
2085
2086static void __exit
2087efivars_exit(void)
2088{
2089        if (efi_enabled(EFI_RUNTIME_SERVICES)) {
2090                unregister_efivars(&__efivars);
2091                kobject_put(efi_kobj);
2092        }
2093}
2094
2095module_init(efivars_init);
2096module_exit(efivars_exit);
2097
2098
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.