1. 08 Jan, 2015 1 commit
  2. 18 Jul, 2014 1 commit
  3. 17 Apr, 2014 5 commits
  4. 04 Mar, 2014 1 commit
  5. 28 Nov, 2013 1 commit
    • Seiji Aguchi's avatar
      efivars, efi-pstore: Hold off deletion of sysfs entry until the scan is completed · e0d59733
      Seiji Aguchi authored
      Currently, when mounting pstore file system, a read callback of
      efi_pstore driver runs mutiple times as below.
      - In the first read callback, scan efivar_sysfs_list from head and pass
        a kmsg buffer of a entry to an upper pstore layer.
      - In the second read callback, rescan efivar_sysfs_list from the entry
        and pass another kmsg buffer to it.
      - Repeat the scan and pass until the end of efivar_sysfs_list.
      In this process, an entry is read across the multiple read function
      calls. To avoid race between the read and erasion, the whole process
      above is protected by a spinlock, holding in open() and releasing in
      At the same time, kmemdup() is called to pass the buffer to pstore
      filesystem during it. And then, it causes a following lockdep warning.
      To make the dynamic memory allocation runnable without taking spinlock,
      holding off a deletion of sysfs entry if it happens while scanning it
      via efi_pstore, and deleting it after the scan is completed.
      To implement it, this patch introduces two flags, scanning and deleting,
      to efivar_entry.
      On the code basis, it seems that all the scanning and deleting logic is
      not needed because __efivars->lock are not dropped when reading from the
      EFI variable store.
      But, the scanning and deleting logic is still needed because an
      efi-pstore and a pstore filesystem works as follows.
      In case an entry(A) is found, the pointer is saved to psi->data.  And
      efi_pstore_read() passes the entry(A) to a pstore filesystem by
      releasing  __efivars->lock.
      And then, the pstore filesystem calls efi_pstore_read() again and the
      same entry(A), which is saved to psi->data, is used for resuming to scan
      a sysfs-list.
      So, to protect the entry(A), the logic is needed.
      [    1.143710] ------------[ cut here ]------------
      [    1.144058] WARNING: CPU: 1 PID: 1 at kernel/lockdep.c:2740 lockdep_trace_alloc+0x104/0x110()
      [    1.144058] DEBUG_LOCKS_WARN_ON(irqs_disabled_flags(flags))
      [    1.144058] Modules linked in:
      [    1.144058] CPU: 1 PID: 1 Comm: systemd Not tainted 3.11.0-rc5 #2
      [    1.144058]  0000000000000009 ffff8800797e9ae0 ffffffff816614a5 ffff8800797e9b28
      [    1.144058]  ffff8800797e9b18 ffffffff8105510d 0000000000000080 0000000000000046
      [    1.144058]  00000000000000d0 00000000000003af ffffffff81ccd0c0 ffff8800797e9b78
      [    1.144058] Call Trace:
      [    1.144058]  [<ffffffff816614a5>] dump_stack+0x54/0x74
      [    1.144058]  [<ffffffff8105510d>] warn_slowpath_common+0x7d/0xa0
      [    1.144058]  [<ffffffff8105517c>] warn_slowpath_fmt+0x4c/0x50
      [    1.144058]  [<ffffffff8131290f>] ? vsscanf+0x57f/0x7b0
      [    1.144058]  [<ffffffff810bbd74>] lockdep_trace_alloc+0x104/0x110
      [    1.144058]  [<ffffffff81192da0>] __kmalloc_track_caller+0x50/0x280
      [    1.144058]  [<ffffffff815147bb>] ? efi_pstore_read_func.part.1+0x12b/0x170
      [    1.144058]  [<ffffffff8115b260>] kmemdup+0x20/0x50
      [    1.144058]  [<ffffffff815147bb>] efi_pstore_read_func.part.1+0x12b/0x170
      [    1.144058]  [<ffffffff81514800>] ? efi_pstore_read_func.part.1+0x170/0x170
      [    1.144058]  [<ffffffff815148b4>] efi_pstore_read_func+0xb4/0xe0
      [    1.144058]  [<ffffffff81512b7b>] __efivar_entry_iter+0xfb/0x120
      [    1.144058]  [<ffffffff8151428f>] efi_pstore_read+0x3f/0x50
      [    1.144058]  [<ffffffff8128d7ba>] pstore_get_records+0x9a/0x150
      [    1.158207]  [<ffffffff812af25c>] ? selinux_d_instantiate+0x1c/0x20
      [    1.158207]  [<ffffffff8128ce30>] ? parse_options+0x80/0x80
      [    1.158207]  [<ffffffff8128ced5>] pstore_fill_super+0xa5/0xc0
      [    1.158207]  [<ffffffff811ae7d2>] mount_single+0xa2/0xd0
      [    1.158207]  [<ffffffff8128ccf8>] pstore_mount+0x18/0x20
      [    1.158207]  [<ffffffff811ae8b9>] mount_fs+0x39/0x1b0
      [    1.158207]  [<ffffffff81160550>] ? __alloc_percpu+0x10/0x20
      [    1.158207]  [<ffffffff811c9493>] vfs_kern_mount+0x63/0xf0
      [    1.158207]  [<ffffffff811cbb0e>] do_mount+0x23e/0xa20
      [    1.158207]  [<ffffffff8115b51b>] ? strndup_user+0x4b/0xf0
      [    1.158207]  [<ffffffff811cc373>] SyS_mount+0x83/0xc0
      [    1.158207]  [<ffffffff81673cc2>] system_call_fastpath+0x16/0x1b
      [    1.158207] ---[ end trace 61981bc62de9f6f4 ]---
      Signed-off-by: default avatarSeiji Aguchi <seiji.aguchi@hds.com>
      Tested-by: default avatarMadper Xie <cxie@redhat.com>
      Cc: stable@kernel.org
      Signed-off-by: default avatarMatt Fleming <matt.fleming@intel.com>
  6. 05 Sep, 2013 1 commit
  7. 11 Jul, 2013 1 commit
  8. 13 May, 2013 1 commit
    • Seiji Aguchi's avatar
      efivar: fix oops in efivar_update_sysfs_entries() caused by memory reuse · d51df2c5
      Seiji Aguchi authored
      The loop in efivar_update_sysfs_entries() reuses the same allocation for
      entries each time it calls efivar_create_sysfs_entry(entry).  This is
      wrong because efivar_create_sysfs_entry() expects to keep the memory it
      was passed, so the caller may not free it (and may not pass the same
      memory in multiple times).  This leads to the oops below.  Fix by
      getting a new allocation each time we go around the loop.
      ---[ end trace ba4907d5c519d111 ]---
      BUG: unable to handle kernel NULL pointer dereference at           (null)
      IP: [<ffffffff8142f81f>] efivar_entry_find+0x14f/0x2d0
      PGD 0
      Oops: 0000 [#2] SMP
      Modules linked in: oops(OF+) ebtable_nat ebtables xt_CHECKSUM [...]
      CPU: 0 PID: 301 Comm: kworker/0:2 Tainted: GF     D    O 3.9.0+ #1
      Hardware name: LENOVO 4291EV7/4291EV7, BIOS 8DET52WW (1.22 ) 09/15/2011
      Workqueue: events efivar_update_sysfs_entries
      task: ffff8801955920c0 ti: ffff88019413e000 task.ti: ffff88019413e000
      RIP: 0010:[<ffffffff8142f81f>]  [<ffffffff8142f81f>] efivar_entry_find+0x14f/0x2d0
      RSP: 0018:ffff88019413fa48  EFLAGS: 00010006
      RAX: 0000000000000000 RBX: ffff880195d87c00 RCX: ffffffff81ab6f60
      RDX: ffff88019413fb88 RSI: 0000000000000400 RDI: ffff880196254000
      RBP: ffff88019413fbd8 R08: 0000000000000000 R09: ffff8800dad99037
      R10: ffff880195d87c00 R11: 0000000000000430 R12: ffffffff81ab6f60
      R13: fffffffffffff7d8 R14: ffff880196254000 R15: 0000000000000000
      FS:  0000000000000000(0000) GS:ffff88019e200000(0000) knlGS:0000000000000000
      CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      CR2: 0000000000000000 CR3: 0000000001a0b000 CR4: 00000000000407f0
      DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
      DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
       ffff88019413fb78 ffff88019413fb88 ffffffff81e85d60 03000000972b5c00
       ffff88019413fa29 ffffffff81e85d60 ffff88019413fbfb 0000000197087280
       00000000000000fe 0000000000000001 ffffffff81e85dd9 ffff880197087280
      Call Trace:
       [<ffffffff81254371>] ? idr_get_empty_slot+0x131/0x240
       [<ffffffff8125b6d2>] ? put_dec+0x72/0x90
       [<ffffffff81158e40>] ? cache_alloc_refill+0x170/0x2f0
       [<ffffffff81430420>] efivar_update_sysfs_entry+0x150/0x220
       [<ffffffff8103dd29>] ? efi_call2+0x9/0x70
       [<ffffffff8103d787>] ? virt_efi_get_next_variable+0x47/0x1b0
       [<ffffffff8115a8df>] ? kmem_cache_alloc_trace+0x1af/0x1c0
       [<ffffffff81430033>] efivar_init+0x2c3/0x380
       [<ffffffff814302d0>] ? efivar_delete+0xd0/0xd0
       [<ffffffff8143111f>] efivar_update_sysfs_entries+0x6f/0x90
       [<ffffffff810605f3>] process_one_work+0x183/0x490
       [<ffffffff81061780>] worker_thread+0x120/0x3a0
       [<ffffffff81061660>] ? manage_workers+0x160/0x160
       [<ffffffff8106752e>] kthread+0xce/0xe0
       [<ffffffff81067460>] ? kthread_freezable_should_stop+0x70/0x70
       [<ffffffff81543c5c>] ret_from_fork+0x7c/0xb0
       [<ffffffff81067460>] ? kthread_freezable_should_stop+0x70/0x70
      Code: 8d 55 b0 48 8d 45 a0 49 81 ed 28 08 00 00 48 89 95 78 fe [...]
      RIP  [<ffffffff8142f81f>] efivar_entry_find+0x14f/0x2d0
       RSP <ffff88019413fa48>
      CR2: 0000000000000000
      ---[ end trace ba4907d5c519d112 ]---
      Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
      Cc: Tomoki Sekiyama <tomoki.sekiyama@hds.com>
      Signed-off-by: default avatarSeiji Aguchi <seiji.aguchi@hds.com>
      Signed-off-by: default avatarMatt Fleming <matt.fleming@intel.com>
  9. 30 Apr, 2013 1 commit
  10. 17 Apr, 2013 1 commit
    • Tom Gundersen's avatar
      efi: split efisubsystem from efivars · a9499fa7
      Tom Gundersen authored
      This registers /sys/firmware/efi/{,systab,efivars/} whenever EFI is enabled
      and the system is booted with EFI.
      This allows
       *) userspace to check for the existence of /sys/firmware/efi as a way
          to determine whether or it is running on an EFI system.
       *) 'mount -t efivarfs none /sys/firmware/efi/efivars' without manually
          loading any modules.
      [ Also, move the efivar API into vars.c and unconditionally compile it.
        This allows us to move efivars.c, which now only contains the sysfs
        variable code, into the firmware/efi directory. Note that the efivars.c
        filename is kept to maintain backwards compatability with the old
        efivars.ko module. With this patch it is now possible for efivarfs
        to be built without CONFIG_EFI_VARS - Matt ]
      Cc: Seiji Aguchi <seiji.aguchi@hds.com>
      Cc: Tony Luck <tony.luck@intel.com>
      Cc: Mike Waychison <mikew@google.com>
      Cc: Kay Sievers <kay@vrfy.org>
      Cc: Jeremy Kerr <jk@ozlabs.org>
      Cc: Matthew Garrett <mjg59@srcf.ucam.org>
      Cc: Chun-Yi Lee <jlee@suse.com>
      Cc: Andy Whitcroft <apw@canonical.com>
      Cc: Tobias Powalowski <tpowa@archlinux.org>
      Signed-off-by: default avatarTom Gundersen <teg@jklm.no>
      Signed-off-by: default avatarMatt Fleming <matt.fleming@intel.com>