Merge tag 'pstore-v4.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 6 Oct 2016 22:16:16 +0000 (15:16 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 6 Oct 2016 22:16:16 +0000 (15:16 -0700)
Pull pstore updates from Kees Cook:

 - Fix bug in module unloading

 - Switch to always using spinlock over cmpxchg

 - Explicitly define pstore backend's supported modes

 - Remove bounce buffer from pmsg

 - Switch to using memcpy_to/fromio()

 - Error checking improvements

* tag 'pstore-v4.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
  ramoops: move spin_lock_init after kmalloc error checking
  pstore/ram: Use memcpy_fromio() to save old buffer
  pstore/ram: Use memcpy_toio instead of memcpy
  pstore/pmsg: drop bounce buffer
  pstore/ram: Set pstore flags dynamically
  pstore: Split pstore fragile flags
  pstore/core: drop cmpxchg based updates
  pstore/ramoops: fixup driver removal

1  2 
drivers/firmware/efi/efi-pstore.c

index 1c33d7469e4a2779d0f7282d130efd69aff420d2,4daa5acd9117b12ae245ee0f1eb1831ef95a2600..f402ba2eed46461d0402c403db87b9a017399659
@@@ -125,19 -125,16 +125,19 @@@ static void efi_pstore_scan_sysfs_enter
   * @entry: deleting entry
   * @turn_off_scanning: Check if a scanning flag should be turned off
   */
 -static inline void __efi_pstore_scan_sysfs_exit(struct efivar_entry *entry,
 +static inline int __efi_pstore_scan_sysfs_exit(struct efivar_entry *entry,
                                                bool turn_off_scanning)
  {
        if (entry->deleting) {
                list_del(&entry->list);
                efivar_entry_iter_end();
                efivar_unregister(entry);
 -              efivar_entry_iter_begin();
 +              if (efivar_entry_iter_begin())
 +                      return -EINTR;
        } else if (turn_off_scanning)
                entry->scanning = false;
 +
 +      return 0;
  }
  
  /**
   * @head: list head
   * @stop: a flag checking if scanning will stop
   */
 -static void efi_pstore_scan_sysfs_exit(struct efivar_entry *pos,
 +static int efi_pstore_scan_sysfs_exit(struct efivar_entry *pos,
                                       struct efivar_entry *next,
                                       struct list_head *head, bool stop)
  {
 -      __efi_pstore_scan_sysfs_exit(pos, true);
 +      int ret = __efi_pstore_scan_sysfs_exit(pos, true);
 +
 +      if (ret)
 +              return ret;
 +
        if (stop)
 -              __efi_pstore_scan_sysfs_exit(next, &next->list != head);
 +              ret = __efi_pstore_scan_sysfs_exit(next, &next->list != head);
 +      return ret;
  }
  
  /**
@@@ -180,17 -172,13 +180,17 @@@ static int efi_pstore_sysfs_entry_iter(
        struct efivar_entry *entry, *n;
        struct list_head *head = &efivar_sysfs_list;
        int size = 0;
 +      int ret;
  
        if (!*pos) {
                list_for_each_entry_safe(entry, n, head, list) {
                        efi_pstore_scan_sysfs_enter(entry, n, head);
  
                        size = efi_pstore_read_func(entry, data);
 -                      efi_pstore_scan_sysfs_exit(entry, n, head, size < 0);
 +                      ret = efi_pstore_scan_sysfs_exit(entry, n, head,
 +                                                       size < 0);
 +                      if (ret)
 +                              return ret;
                        if (size)
                                break;
                }
                efi_pstore_scan_sysfs_enter((*pos), n, head);
  
                size = efi_pstore_read_func((*pos), data);
 -              efi_pstore_scan_sysfs_exit((*pos), n, head, size < 0);
 +              ret = efi_pstore_scan_sysfs_exit((*pos), n, head, size < 0);
 +              if (ret)
 +                      return ret;
                if (size)
                        break;
        }
@@@ -246,10 -232,7 +246,10 @@@ static ssize_t efi_pstore_read(u64 *id
        if (!*data.buf)
                return -ENOMEM;
  
 -      efivar_entry_iter_begin();
 +      if (efivar_entry_iter_begin()) {
 +              kfree(*data.buf);
 +              return -EINTR;
 +      }
        size = efi_pstore_sysfs_entry_iter(&data,
                                           (struct efivar_entry **)&psi->data);
        efivar_entry_iter_end();
@@@ -364,8 -347,7 +364,8 @@@ static int efi_pstore_erase(enum pstore
        edata.time = time;
        edata.name = efi_name;
  
 -      efivar_entry_iter_begin();
 +      if (efivar_entry_iter_begin())
 +              return -EINTR;
        found = __efivar_entry_iter(efi_pstore_erase_func, &efivar_sysfs_list, &edata, &entry);
  
        if (found && !entry->scanning) {
  static struct pstore_info efi_pstore_info = {
        .owner          = THIS_MODULE,
        .name           = "efi",
-       .flags          = PSTORE_FLAGS_FRAGILE,
+       .flags          = PSTORE_FLAGS_DMESG,
        .open           = efi_pstore_open,
        .close          = efi_pstore_close,
        .read           = efi_pstore_read,