• Matt Fleming's avatar
    efivars: Handle duplicate names from get_next_variable() · e971318b
    Matt Fleming authored
    Some firmware exhibits a bug where the same VariableName and
    VendorGuid values are returned on multiple invocations of
    GetNextVariableName(). See,
    
        https://bugzilla.kernel.org/show_bug.cgi?id=47631
    
    As a consequence of such a bug, Andre reports hitting the following
    WARN_ON() in the sysfs code after updating the BIOS on his, "Gigabyte
    Technology Co., Ltd. To be filled by O.E.M./Z77X-UD3H, BIOS F19e
    11/21/2012)" machine,
    
    [    0.581554] EFI Variables Facility v0.08 2004-May-17
    [    0.584914] ------------[ cut here ]------------
    [    0.585639] WARNING: at /home/andre/linux/fs/sysfs/dir.c:536 sysfs_add_one+0xd4/0x100()
    [    0.586381] Hardware name: To be filled by O.E.M.
    [    0.587123] sysfs: cannot create duplicate filename '/firmware/efi/vars/SbAslBufferPtrVar-01f33c25-764d-43ea-aeea-6b5a41f3f3e8'
    [    0.588694] Modules linked in:
    [    0.589484] Pid: 1, comm: swapper/0 Not tainted 3.8.0+ #7
    [    0.590280] Call Trace:
    [    0.591066]  [<ffffffff81208954>] ? sysfs_add_one+0xd4/0x100
    [    0.591861]  [<ffffffff810587bf>] warn_slowpath_common+0x7f/0xc0
    [    0.592650]  [<ffffffff810588bc>] warn_slowpath_fmt+0x4c/0x50
    [    0.593429]  [<ffffffff8134dd85>] ? strlcat+0x65/0x80
    [    0.594203]  [<ffffffff81208954>] sysfs_add_one+0xd4/0x100
    [    0.594979]  [<ffffffff81208b78>] create_dir+0x78/0xd0
    [    0.595753]  [<ffffffff81208ec6>] sysfs_create_dir+0x86/0xe0
    [    0.596532]  [<ffffffff81347e4c>] kobject_add_internal+0x9c/0x220
    [    0.597310]  [<ffffffff81348307>] kobject_init_and_add+0x67/0x90
    [    0.598083]  [<ffffffff81584a71>] ? efivar_create_sysfs_entry+0x61/0x1c0
    [    0.598859]  [<ffffffff81584b2b>] efivar_create_sysfs_entry+0x11b/0x1c0
    [    0.599631]  [<ffffffff8158517e>] register_efivars+0xde/0x420
    [    0.600395]  [<ffffffff81d430a7>] ? edd_init+0x2f5/0x2f5
    [    0.601150]  [<ffffffff81d4315f>] efivars_init+0xb8/0x104
    [    0.601903]  [<ffffffff8100215a>] do_one_initcall+0x12a/0x180
    [    0.602659]  [<ffffffff81d05d80>] kernel_init_freeable+0x13e/0x1c6
    [    0.603418]  [<ffffffff81d05586>] ? loglevel+0x31/0x31
    [    0.604183]  [<ffffffff816a6530>] ? rest_init+0x80/0x80
    [    0.604936]  [<ffffffff816a653e>] kernel_init+0xe/0xf0
    [    0.605681]  [<ffffffff816ce7ec>] ret_from_fork+0x7c/0xb0
    [    0.606414]  [<ffffffff816a6530>] ? rest_init+0x80/0x80
    [    0.607143] ---[ end trace 1609741ab737eb29 ]---
    
    There's not much we can do to work around and keep traversing the
    variable list once we hit this firmware bug. Our only solution is to
    terminate the loop because, as Lingzhu reports, some machines get
    stuck when they encounter duplicate names,
    
      > I had an IBM System x3100 M4 and x3850 X5 on which kernel would
      > get stuck in infinite loop creating duplicate sysfs files because,
      > for some reason, there are several duplicate boot entries in nvram
      > getting GetNextVariableName into a circle of iteration (with
      > period > 2).
    
    Also disable the workqueue, as efivar_update_sysfs_entries() uses
    GetNextVariableName() to figure out which variables have been created
    since the last iteration. That algorithm isn't going to work if
    GetNextVariableName() returns duplicates. Note that we don't disable
    EFI variable creation completely on the affected machines, it's just
    that any pstore dump-* files won't appear in sysfs until the next
    boot.
    Reported-by: default avatarAndre Heider <a.heider@gmail.com>
    Reported-by: default avatarLingzhu Xiang <lxiang@redhat.com>
    Tested-by: default avatarLingzhu Xiang <lxiang@redhat.com>
    Cc: Seiji Aguchi <seiji.aguchi@hds.com>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: default avatarMatt Fleming <matt.fleming@intel.com>
    e971318b
efivars.c 53.6 KB