]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 30 Jun 2015 00:29:42 +0000 (17:29 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 30 Jun 2015 00:29:42 +0000 (17:29 -0700)
added patches:
btrfs-make-xattr-replace-operations-atomic.patch
hpsa-add-missing-pci_set_master-in-kdump-path.patch
hpsa-refine-the-pci-enable-disable-handling.patch
net-mlx4_en-don-t-attempt-to-tx-offload-the-outer-udp-checksum-for-vxlan.patch
sb_edac-fix-erroneous-bytes-gigabytes-conversion.patch
x86-microcode-intel-guard-against-stack-overflow-in-the-loader.patch

queue-3.14/btrfs-make-xattr-replace-operations-atomic.patch [new file with mode: 0644]
queue-3.14/hpsa-add-missing-pci_set_master-in-kdump-path.patch [new file with mode: 0644]
queue-3.14/hpsa-refine-the-pci-enable-disable-handling.patch [new file with mode: 0644]
queue-3.14/net-mlx4_en-don-t-attempt-to-tx-offload-the-outer-udp-checksum-for-vxlan.patch [new file with mode: 0644]
queue-3.14/sb_edac-fix-erroneous-bytes-gigabytes-conversion.patch [new file with mode: 0644]
queue-3.14/series
queue-3.14/x86-microcode-intel-guard-against-stack-overflow-in-the-loader.patch [new file with mode: 0644]

diff --git a/queue-3.14/btrfs-make-xattr-replace-operations-atomic.patch b/queue-3.14/btrfs-make-xattr-replace-operations-atomic.patch
new file mode 100644 (file)
index 0000000..77564ee
--- /dev/null
@@ -0,0 +1,295 @@
+From 5f5bc6b1e2d5a6f827bc860ef2dc5b6f365d1339 Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Sun, 9 Nov 2014 08:38:39 +0000
+Subject: Btrfs: make xattr replace operations atomic
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 5f5bc6b1e2d5a6f827bc860ef2dc5b6f365d1339 upstream.
+
+Replacing a xattr consists of doing a lookup for its existing value, delete
+the current value from the respective leaf, release the search path and then
+finally insert the new value. This leaves a time window where readers (getxattr,
+listxattrs) won't see any value for the xattr. Xattrs are used to store ACLs,
+so this has security implications.
+
+This change also fixes 2 other existing issues which were:
+
+*) Deleting the old xattr value without verifying first if the new xattr will
+   fit in the existing leaf item (in case multiple xattrs are packed in the
+   same item due to name hash collision);
+
+*) Returning -EEXIST when the flag XATTR_CREATE is given and the xattr doesn't
+   exist but we have have an existing item that packs muliple xattrs with
+   the same name hash as the input xattr. In this case we should return ENOSPC.
+
+A test case for xfstests follows soon.
+
+Thanks to Alexandre Oliva for reporting the non-atomicity of the xattr replace
+implementation.
+
+Reported-by: Alexandre Oliva <oliva@gnu.org>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Chris Mason <clm@fb.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/ctree.c    |    2 
+ fs/btrfs/ctree.h    |    5 +
+ fs/btrfs/dir-item.c |   10 +--
+ fs/btrfs/xattr.c    |  150 ++++++++++++++++++++++++++++++++--------------------
+ 4 files changed, 102 insertions(+), 65 deletions(-)
+
+--- a/fs/btrfs/ctree.c
++++ b/fs/btrfs/ctree.c
+@@ -2963,7 +2963,7 @@ done:
+        */
+       if (!p->leave_spinning)
+               btrfs_set_path_blocking(p);
+-      if (ret < 0)
++      if (ret < 0 && !p->skip_release_on_error)
+               btrfs_release_path(p);
+       return ret;
+ }
+--- a/fs/btrfs/ctree.h
++++ b/fs/btrfs/ctree.h
+@@ -608,6 +608,7 @@ struct btrfs_path {
+       unsigned int skip_locking:1;
+       unsigned int leave_spinning:1;
+       unsigned int search_commit_root:1;
++      unsigned int skip_release_on_error:1;
+ };
+ /*
+@@ -3609,6 +3610,10 @@ struct btrfs_dir_item *btrfs_lookup_xatt
+ int verify_dir_item(struct btrfs_root *root,
+                   struct extent_buffer *leaf,
+                   struct btrfs_dir_item *dir_item);
++struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root,
++                                               struct btrfs_path *path,
++                                               const char *name,
++                                               int name_len);
+ /* orphan.c */
+ int btrfs_insert_orphan_item(struct btrfs_trans_handle *trans,
+--- a/fs/btrfs/dir-item.c
++++ b/fs/btrfs/dir-item.c
+@@ -21,10 +21,6 @@
+ #include "hash.h"
+ #include "transaction.h"
+-static struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root,
+-                            struct btrfs_path *path,
+-                            const char *name, int name_len);
+-
+ /*
+  * insert a name into a directory, doing overflow properly if there is a hash
+  * collision.  data_size indicates how big the item inserted should be.  On
+@@ -383,9 +379,9 @@ struct btrfs_dir_item *btrfs_lookup_xatt
+  * this walks through all the entries in a dir item and finds one
+  * for a specific name.
+  */
+-static struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root,
+-                            struct btrfs_path *path,
+-                            const char *name, int name_len)
++struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root,
++                                               struct btrfs_path *path,
++                                               const char *name, int name_len)
+ {
+       struct btrfs_dir_item *dir_item;
+       unsigned long name_ptr;
+--- a/fs/btrfs/xattr.c
++++ b/fs/btrfs/xattr.c
+@@ -29,6 +29,7 @@
+ #include "xattr.h"
+ #include "disk-io.h"
+ #include "props.h"
++#include "locking.h"
+ ssize_t __btrfs_getxattr(struct inode *inode, const char *name,
+@@ -91,7 +92,7 @@ static int do_setxattr(struct btrfs_tran
+                      struct inode *inode, const char *name,
+                      const void *value, size_t size, int flags)
+ {
+-      struct btrfs_dir_item *di;
++      struct btrfs_dir_item *di = NULL;
+       struct btrfs_root *root = BTRFS_I(inode)->root;
+       struct btrfs_path *path;
+       size_t name_len = strlen(name);
+@@ -103,84 +104,119 @@ static int do_setxattr(struct btrfs_tran
+       path = btrfs_alloc_path();
+       if (!path)
+               return -ENOMEM;
++      path->skip_release_on_error = 1;
++
++      if (!value) {
++              di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode),
++                                      name, name_len, -1);
++              if (!di && (flags & XATTR_REPLACE))
++                      ret = -ENODATA;
++              else if (di)
++                      ret = btrfs_delete_one_dir_name(trans, root, path, di);
++              goto out;
++      }
++      /*
++       * For a replace we can't just do the insert blindly.
++       * Do a lookup first (read-only btrfs_search_slot), and return if xattr
++       * doesn't exist. If it exists, fall down below to the insert/replace
++       * path - we can't race with a concurrent xattr delete, because the VFS
++       * locks the inode's i_mutex before calling setxattr or removexattr.
++       */
+       if (flags & XATTR_REPLACE) {
+-              di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode), name,
+-                                      name_len, -1);
+-              if (IS_ERR(di)) {
+-                      ret = PTR_ERR(di);
+-                      goto out;
+-              } else if (!di) {
++              ASSERT(mutex_is_locked(&inode->i_mutex));
++              di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(inode),
++                                      name, name_len, 0);
++              if (!di) {
+                       ret = -ENODATA;
+                       goto out;
+               }
+-              ret = btrfs_delete_one_dir_name(trans, root, path, di);
+-              if (ret)
+-                      goto out;
+               btrfs_release_path(path);
++              di = NULL;
++      }
++      ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(inode),
++                                    name, name_len, value, size);
++      if (ret == -EOVERFLOW) {
+               /*
+-               * remove the attribute
++               * We have an existing item in a leaf, split_leaf couldn't
++               * expand it. That item might have or not a dir_item that
++               * matches our target xattr, so lets check.
+                */
+-              if (!value)
+-                      goto out;
+-      } else {
+-              di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(inode),
+-                                      name, name_len, 0);
+-              if (IS_ERR(di)) {
+-                      ret = PTR_ERR(di);
++              ret = 0;
++              btrfs_assert_tree_locked(path->nodes[0]);
++              di = btrfs_match_dir_item_name(root, path, name, name_len);
++              if (!di && !(flags & XATTR_REPLACE)) {
++                      ret = -ENOSPC;
+                       goto out;
+               }
+-              if (!di && !value)
+-                      goto out;
+-              btrfs_release_path(path);
++      } else if (ret == -EEXIST) {
++              ret = 0;
++              di = btrfs_match_dir_item_name(root, path, name, name_len);
++              ASSERT(di); /* logic error */
++      } else if (ret) {
++              goto out;
+       }
+-again:
+-      ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(inode),
+-                                    name, name_len, value, size);
+-      /*
+-       * If we're setting an xattr to a new value but the new value is say
+-       * exactly BTRFS_MAX_XATTR_SIZE, we could end up with EOVERFLOW getting
+-       * back from split_leaf.  This is because it thinks we'll be extending
+-       * the existing item size, but we're asking for enough space to add the
+-       * item itself.  So if we get EOVERFLOW just set ret to EEXIST and let
+-       * the rest of the function figure it out.
+-       */
+-      if (ret == -EOVERFLOW)
++      if (di && (flags & XATTR_CREATE)) {
+               ret = -EEXIST;
++              goto out;
++      }
+-      if (ret == -EEXIST) {
+-              if (flags & XATTR_CREATE)
+-                      goto out;
++      if (di) {
+               /*
+-               * We can't use the path we already have since we won't have the
+-               * proper locking for a delete, so release the path and
+-               * re-lookup to delete the thing.
++               * We're doing a replace, and it must be atomic, that is, at
++               * any point in time we have either the old or the new xattr
++               * value in the tree. We don't want readers (getxattr and
++               * listxattrs) to miss a value, this is specially important
++               * for ACLs.
+                */
+-              btrfs_release_path(path);
+-              di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode),
+-                                      name, name_len, -1);
+-              if (IS_ERR(di)) {
+-                      ret = PTR_ERR(di);
+-                      goto out;
+-              } else if (!di) {
+-                      /* Shouldn't happen but just in case... */
+-                      btrfs_release_path(path);
+-                      goto again;
++              const int slot = path->slots[0];
++              struct extent_buffer *leaf = path->nodes[0];
++              const u16 old_data_len = btrfs_dir_data_len(leaf, di);
++              const u32 item_size = btrfs_item_size_nr(leaf, slot);
++              const u32 data_size = sizeof(*di) + name_len + size;
++              struct btrfs_item *item;
++              unsigned long data_ptr;
++              char *ptr;
++
++              if (size > old_data_len) {
++                      if (btrfs_leaf_free_space(root, leaf) <
++                          (size - old_data_len)) {
++                              ret = -ENOSPC;
++                              goto out;
++                      }
+               }
+-              ret = btrfs_delete_one_dir_name(trans, root, path, di);
+-              if (ret)
+-                      goto out;
++              if (old_data_len + name_len + sizeof(*di) == item_size) {
++                      /* No other xattrs packed in the same leaf item. */
++                      if (size > old_data_len)
++                              btrfs_extend_item(root, path,
++                                                size - old_data_len);
++                      else if (size < old_data_len)
++                              btrfs_truncate_item(root, path, data_size, 1);
++              } else {
++                      /* There are other xattrs packed in the same item. */
++                      ret = btrfs_delete_one_dir_name(trans, root, path, di);
++                      if (ret)
++                              goto out;
++                      btrfs_extend_item(root, path, data_size);
++              }
++              item = btrfs_item_nr(slot);
++              ptr = btrfs_item_ptr(leaf, slot, char);
++              ptr += btrfs_item_size(leaf, item) - data_size;
++              di = (struct btrfs_dir_item *)ptr;
++              btrfs_set_dir_data_len(leaf, di, size);
++              data_ptr = ((unsigned long)(di + 1)) + name_len;
++              write_extent_buffer(leaf, value, data_ptr, size);
++              btrfs_mark_buffer_dirty(leaf);
++      } else {
+               /*
+-               * We have a value to set, so go back and try to insert it now.
++               * Insert, and we had space for the xattr, so path->slots[0] is
++               * where our xattr dir_item is and btrfs_insert_xattr_item()
++               * filled it.
+                */
+-              if (value) {
+-                      btrfs_release_path(path);
+-                      goto again;
+-              }
+       }
+ out:
+       btrfs_free_path(path);
diff --git a/queue-3.14/hpsa-add-missing-pci_set_master-in-kdump-path.patch b/queue-3.14/hpsa-add-missing-pci_set_master-in-kdump-path.patch
new file mode 100644 (file)
index 0000000..2d215b4
--- /dev/null
@@ -0,0 +1,34 @@
+From 859c75aba20264d87dd026bab0d0ca3bff385955 Mon Sep 17 00:00:00 2001
+From: Tomas Henzl <thenzl@redhat.com>
+Date: Fri, 12 Sep 2014 14:44:15 +0200
+Subject: hpsa: add missing pci_set_master in kdump path
+
+From: Tomas Henzl <thenzl@redhat.com>
+
+commit 859c75aba20264d87dd026bab0d0ca3bff385955 upstream.
+
+Add a call to pci_set_master(...)  missing in the previous
+patch "hpsa: refine the pci enable/disable handling".
+Found thanks to Rob Elliot.
+
+Signed-off-by: Tomas Henzl <thenzl@redhat.com>
+Reviewed-by: Robert Elliott <elliott@hp.com>
+Tested-by: Robert Elliott <elliott@hp.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/hpsa.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -4532,7 +4532,7 @@ static int hpsa_init_reset_devices(struc
+               dev_warn(&pdev->dev, "failed to enable device.\n");
+               return -ENODEV;
+       }
+-
++      pci_set_master(pdev);
+       /* Reset the controller with a PCI power-cycle or via doorbell */
+       rc = hpsa_kdump_hard_reset_controller(pdev);
diff --git a/queue-3.14/hpsa-refine-the-pci-enable-disable-handling.patch b/queue-3.14/hpsa-refine-the-pci-enable-disable-handling.patch
new file mode 100644 (file)
index 0000000..e0d7cdb
--- /dev/null
@@ -0,0 +1,116 @@
+From 132aa220b45d60e9b20def1e9d8be9422eed9616 Mon Sep 17 00:00:00 2001
+From: Tomas Henzl <thenzl@redhat.com>
+Date: Thu, 14 Aug 2014 16:12:39 +0200
+Subject: hpsa: refine the pci enable/disable handling
+
+From: Tomas Henzl <thenzl@redhat.com>
+
+commit 132aa220b45d60e9b20def1e9d8be9422eed9616 upstream.
+
+When a second(kdump) kernel starts and the hard reset method is used
+the driver calls pci_disable_device without previously enabling it,
+so the kernel shows a warning -
+[   16.876248] WARNING: at drivers/pci/pci.c:1431 pci_disable_device+0x84/0x90()
+[   16.882686] Device hpsa
+disabling already-disabled device
+...
+This patch fixes it, in addition to this I tried to balance also some other pairs
+of enable/disable device in the driver.
+Unfortunately I wasn't able to verify the functionality for the case of a sw reset,
+because of a lack of proper hw.
+
+Signed-off-by: Tomas Henzl <thenzl@redhat.com>
+Reviewed-by: Stephen M. Cameron <scameron@beardog.cce.hp.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/hpsa.c |   42 ++++++++++++++++++++++++++++--------------
+ 1 file changed, 28 insertions(+), 14 deletions(-)
+
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -3984,10 +3984,6 @@ static int hpsa_kdump_hard_reset_control
+       /* Save the PCI command register */
+       pci_read_config_word(pdev, 4, &command_register);
+-      /* Turn the board off.  This is so that later pci_restore_state()
+-       * won't turn the board on before the rest of config space is ready.
+-       */
+-      pci_disable_device(pdev);
+       pci_save_state(pdev);
+       /* find the first memory BAR, so we can find the cfg table */
+@@ -4035,11 +4031,6 @@ static int hpsa_kdump_hard_reset_control
+               goto unmap_cfgtable;
+       pci_restore_state(pdev);
+-      rc = pci_enable_device(pdev);
+-      if (rc) {
+-              dev_warn(&pdev->dev, "failed to enable device.\n");
+-              goto unmap_cfgtable;
+-      }
+       pci_write_config_word(pdev, 4, command_register);
+       /* Some devices (notably the HP Smart Array 5i Controller)
+@@ -4525,6 +4516,23 @@ static int hpsa_init_reset_devices(struc
+       if (!reset_devices)
+               return 0;
++      /* kdump kernel is loading, we don't know in which state is
++       * the pci interface. The dev->enable_cnt is equal zero
++       * so we call enable+disable, wait a while and switch it on.
++       */
++      rc = pci_enable_device(pdev);
++      if (rc) {
++              dev_warn(&pdev->dev, "Failed to enable PCI device\n");
++              return -ENODEV;
++      }
++      pci_disable_device(pdev);
++      msleep(260);                    /* a randomly chosen number */
++      rc = pci_enable_device(pdev);
++      if (rc) {
++              dev_warn(&pdev->dev, "failed to enable device.\n");
++              return -ENODEV;
++      }
++
+       /* Reset the controller with a PCI power-cycle or via doorbell */
+       rc = hpsa_kdump_hard_reset_controller(pdev);
+@@ -4533,10 +4541,11 @@ static int hpsa_init_reset_devices(struc
+        * "performant mode".  Or, it might be 640x, which can't reset
+        * due to concerns about shared bbwc between 6402/6404 pair.
+        */
+-      if (rc == -ENOTSUPP)
+-              return rc; /* just try to do the kdump anyhow. */
+-      if (rc)
+-              return -ENODEV;
++      if (rc) {
++              if (rc != -ENOTSUPP) /* just try to do the kdump anyhow. */
++                      rc = -ENODEV;
++              goto out_disable;
++      }
+       /* Now try to get the controller to respond to a no-op */
+       dev_warn(&pdev->dev, "Waiting for controller to respond to no-op\n");
+@@ -4547,7 +4556,11 @@ static int hpsa_init_reset_devices(struc
+                       dev_warn(&pdev->dev, "no-op failed%s\n",
+                                       (i < 11 ? "; re-trying" : ""));
+       }
+-      return 0;
++
++out_disable:
++
++      pci_disable_device(pdev);
++      return rc;
+ }
+ static int hpsa_allocate_cmd_pool(struct ctlr_info *h)
+@@ -4690,6 +4703,7 @@ static void hpsa_undo_allocations_after_
+               iounmap(h->transtable);
+       if (h->cfgtable)
+               iounmap(h->cfgtable);
++      pci_disable_device(h->pdev);
+       pci_release_regions(h->pdev);
+       kfree(h);
+ }
diff --git a/queue-3.14/net-mlx4_en-don-t-attempt-to-tx-offload-the-outer-udp-checksum-for-vxlan.patch b/queue-3.14/net-mlx4_en-don-t-attempt-to-tx-offload-the-outer-udp-checksum-for-vxlan.patch
new file mode 100644 (file)
index 0000000..e2060c2
--- /dev/null
@@ -0,0 +1,42 @@
+From a4f2dacbf2a5045e34b98a35d9a3857800f25a7b Mon Sep 17 00:00:00 2001
+From: Or Gerlitz <ogerlitz@mellanox.com>
+Date: Thu, 30 Oct 2014 15:59:27 +0200
+Subject: net/mlx4_en: Don't attempt to TX offload the outer UDP checksum for VXLAN
+
+From: Or Gerlitz <ogerlitz@mellanox.com>
+
+commit a4f2dacbf2a5045e34b98a35d9a3857800f25a7b upstream.
+
+For VXLAN/NVGRE encapsulation, the current HW doesn't support offloading
+both the outer UDP TX checksum and the inner TCP/UDP TX checksum.
+
+The driver doesn't advertize SKB_GSO_UDP_TUNNEL_CSUM, however we are wrongly
+telling the HW to offload the outer UDP checksum for encapsulated packets,
+fix that.
+
+Fixes: 837052d0ccc5 ('net/mlx4_en: Add netdev support for TCP/IP
+                    offloads of vxlan tunneling')
+Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/mellanox/mlx4/en_tx.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c
++++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
+@@ -810,8 +810,11 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff
+       tx_desc->ctrl.fence_size = (real_size / 16) & 0x3f;
+       tx_desc->ctrl.srcrb_flags = priv->ctrl_flags;
+       if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
+-              tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM |
+-                                                       MLX4_WQE_CTRL_TCP_UDP_CSUM);
++              if (!skb->encapsulation)
++                      tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM |
++                                                               MLX4_WQE_CTRL_TCP_UDP_CSUM);
++              else
++                      tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM);
+               ring->tx_csum++;
+       }
diff --git a/queue-3.14/sb_edac-fix-erroneous-bytes-gigabytes-conversion.patch b/queue-3.14/sb_edac-fix-erroneous-bytes-gigabytes-conversion.patch
new file mode 100644 (file)
index 0000000..e26bd90
--- /dev/null
@@ -0,0 +1,139 @@
+From 8c009100295597f23978c224aec5751a365bc965 Mon Sep 17 00:00:00 2001
+From: Jim Snow <jim.m.snow@intel.com>
+Date: Tue, 18 Nov 2014 14:51:09 +0100
+Subject: sb_edac: Fix erroneous bytes->gigabytes conversion
+
+From: Jim Snow <jim.m.snow@intel.com>
+
+commit 8c009100295597f23978c224aec5751a365bc965 upstream.
+
+Signed-off-by: Jim Snow <jim.snow@intel.com>
+Signed-off-by: Lukasz Anaczkowski <lukasz.anaczkowski@intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+[ vlee: Backported to 3.14. Adjusted context. ]
+Signed-off-by: Vinson Lee <vlee@twitter.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/edac/sb_edac.c |   38 ++++++++++++++++++++------------------
+ 1 file changed, 20 insertions(+), 18 deletions(-)
+
+--- a/drivers/edac/sb_edac.c
++++ b/drivers/edac/sb_edac.c
+@@ -765,7 +765,7 @@ static void get_memory_layout(const stru
+       u32 reg;
+       u64 limit, prv = 0;
+       u64 tmp_mb;
+-      u32 mb, kb;
++      u32 gb, mb;
+       u32 rir_way;
+       /*
+@@ -775,15 +775,17 @@ static void get_memory_layout(const stru
+       pvt->tolm = pvt->info.get_tolm(pvt);
+       tmp_mb = (1 + pvt->tolm) >> 20;
+-      mb = div_u64_rem(tmp_mb, 1000, &kb);
+-      edac_dbg(0, "TOLM: %u.%03u GB (0x%016Lx)\n", mb, kb, (u64)pvt->tolm);
++      gb = div_u64_rem(tmp_mb, 1024, &mb);
++      edac_dbg(0, "TOLM: %u.%03u GB (0x%016Lx)\n",
++              gb, (mb*1000)/1024, (u64)pvt->tolm);
+       /* Address range is already 45:25 */
+       pvt->tohm = pvt->info.get_tohm(pvt);
+       tmp_mb = (1 + pvt->tohm) >> 20;
+-      mb = div_u64_rem(tmp_mb, 1000, &kb);
+-      edac_dbg(0, "TOHM: %u.%03u GB (0x%016Lx)\n", mb, kb, (u64)pvt->tohm);
++      gb = div_u64_rem(tmp_mb, 1024, &mb);
++      edac_dbg(0, "TOHM: %u.%03u GB (0x%016Lx)\n",
++              gb, (mb*1000)/1024, (u64)pvt->tohm);
+       /*
+        * Step 2) Get SAD range and SAD Interleave list
+@@ -805,11 +807,11 @@ static void get_memory_layout(const stru
+                       break;
+               tmp_mb = (limit + 1) >> 20;
+-              mb = div_u64_rem(tmp_mb, 1000, &kb);
++              gb = div_u64_rem(tmp_mb, 1024, &mb);
+               edac_dbg(0, "SAD#%d %s up to %u.%03u GB (0x%016Lx) Interleave: %s reg=0x%08x\n",
+                        n_sads,
+                        get_dram_attr(reg),
+-                       mb, kb,
++                       gb, (mb*1000)/1024,
+                        ((u64)tmp_mb) << 20L,
+                        INTERLEAVE_MODE(reg) ? "8:6" : "[8:6]XOR[18:16]",
+                        reg);
+@@ -840,9 +842,9 @@ static void get_memory_layout(const stru
+                       break;
+               tmp_mb = (limit + 1) >> 20;
+-              mb = div_u64_rem(tmp_mb, 1000, &kb);
++              gb = div_u64_rem(tmp_mb, 1024, &mb);
+               edac_dbg(0, "TAD#%d: up to %u.%03u GB (0x%016Lx), socket interleave %d, memory interleave %d, TGT: %d, %d, %d, %d, reg=0x%08x\n",
+-                       n_tads, mb, kb,
++                       n_tads, gb, (mb*1000)/1024,
+                        ((u64)tmp_mb) << 20L,
+                        (u32)TAD_SOCK(reg),
+                        (u32)TAD_CH(reg),
+@@ -865,10 +867,10 @@ static void get_memory_layout(const stru
+                                             tad_ch_nilv_offset[j],
+                                             &reg);
+                       tmp_mb = TAD_OFFSET(reg) >> 20;
+-                      mb = div_u64_rem(tmp_mb, 1000, &kb);
++                      gb = div_u64_rem(tmp_mb, 1024, &mb);
+                       edac_dbg(0, "TAD CH#%d, offset #%d: %u.%03u GB (0x%016Lx), reg=0x%08x\n",
+                                i, j,
+-                               mb, kb,
++                               gb, (mb*1000)/1024,
+                                ((u64)tmp_mb) << 20L,
+                                reg);
+               }
+@@ -890,10 +892,10 @@ static void get_memory_layout(const stru
+                       tmp_mb = RIR_LIMIT(reg) >> 20;
+                       rir_way = 1 << RIR_WAY(reg);
+-                      mb = div_u64_rem(tmp_mb, 1000, &kb);
++                      gb = div_u64_rem(tmp_mb, 1024, &mb);
+                       edac_dbg(0, "CH#%d RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d, reg=0x%08x\n",
+                                i, j,
+-                               mb, kb,
++                               gb, (mb*1000)/1024,
+                                ((u64)tmp_mb) << 20L,
+                                rir_way,
+                                reg);
+@@ -904,10 +906,10 @@ static void get_memory_layout(const stru
+                                                     &reg);
+                               tmp_mb = RIR_OFFSET(reg) << 6;
+-                              mb = div_u64_rem(tmp_mb, 1000, &kb);
++                              gb = div_u64_rem(tmp_mb, 1024, &mb);
+                               edac_dbg(0, "CH#%d RIR#%d INTL#%d, offset %u.%03u GB (0x%016Lx), tgt: %d, reg=0x%08x\n",
+                                        i, j, k,
+-                                       mb, kb,
++                                       gb, (mb*1000)/1024,
+                                        ((u64)tmp_mb) << 20L,
+                                        (u32)RIR_RNK_TGT(reg),
+                                        reg);
+@@ -945,7 +947,7 @@ static int get_memory_error_data(struct
+       u8                      ch_way, sck_way, pkg, sad_ha = 0;
+       u32                     tad_offset;
+       u32                     rir_way;
+-      u32                     mb, kb;
++      u32                     mb, gb;
+       u64                     ch_addr, offset, limit = 0, prv = 0;
+@@ -1183,10 +1185,10 @@ static int get_memory_error_data(struct
+                       continue;
+               limit = RIR_LIMIT(reg);
+-              mb = div_u64_rem(limit >> 20, 1000, &kb);
++              gb = div_u64_rem(limit >> 20, 1024, &mb);
+               edac_dbg(0, "RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d\n",
+                        n_rir,
+-                       mb, kb,
++                       gb, (mb*1000)/1024,
+                        limit,
+                        1 << RIR_WAY(reg));
+               if  (ch_addr <= limit)
index 5255d33e62e667b50af7e672660540e87a3c1223..f1ae97310886ba519e0a08fcf5154048af26bdc7 100644 (file)
@@ -2,6 +2,12 @@ arm64-dma-mapping-always-clear-allocated-buffers.patch
 kprobes-x86-return-correct-length-in-__copy_instruction.patch
 config-enable-need_dma_map_state-by-default-when-swiotlb-is-selected.patch
 netfilter-nfnetlink_cthelper-remove-const-and-to-avoid-warnings.patch
+sb_edac-fix-erroneous-bytes-gigabytes-conversion.patch
+hpsa-refine-the-pci-enable-disable-handling.patch
 netfilter-zero-the-tuple-in-nfnl_cthelper_parse_tuple.patch
 netfilter-nft_compat-set-ip6t_f_proto-flag-if-protocol-is-set.patch
 netfilter-nf_tables-allow-to-change-chain-policy-without-hook-if-it-exists.patch
+hpsa-add-missing-pci_set_master-in-kdump-path.patch
+x86-microcode-intel-guard-against-stack-overflow-in-the-loader.patch
+btrfs-make-xattr-replace-operations-atomic.patch
+net-mlx4_en-don-t-attempt-to-tx-offload-the-outer-udp-checksum-for-vxlan.patch
diff --git a/queue-3.14/x86-microcode-intel-guard-against-stack-overflow-in-the-loader.patch b/queue-3.14/x86-microcode-intel-guard-against-stack-overflow-in-the-loader.patch
new file mode 100644 (file)
index 0000000..6f8d0e6
--- /dev/null
@@ -0,0 +1,36 @@
+From f84598bd7c851f8b0bf8cd0d7c3be0d73c432ff4 Mon Sep 17 00:00:00 2001
+From: Quentin Casasnovas <quentin.casasnovas@oracle.com>
+Date: Tue, 3 Feb 2015 13:00:22 +0100
+Subject: x86/microcode/intel: Guard against stack overflow in the loader
+
+From: Quentin Casasnovas <quentin.casasnovas@oracle.com>
+
+commit f84598bd7c851f8b0bf8cd0d7c3be0d73c432ff4 upstream.
+
+mc_saved_tmp is a static array allocated on the stack, we need to make
+sure mc_saved_count stays within its bounds, otherwise we're overflowing
+the stack in _save_mc(). A specially crafted microcode header could lead
+to a kernel crash or potentially kernel execution.
+
+Signed-off-by: Quentin Casasnovas <quentin.casasnovas@oracle.com>
+Cc: "H. Peter Anvin" <hpa@zytor.com>
+Cc: Fenghua Yu <fenghua.yu@intel.com>
+Link: http://lkml.kernel.org/r/1422964824-22056-1-git-send-email-quentin.casasnovas@oracle.com
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/cpu/microcode/intel_early.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/x86/kernel/cpu/microcode/intel_early.c
++++ b/arch/x86/kernel/cpu/microcode/intel_early.c
+@@ -321,7 +321,7 @@ get_matching_model_microcode(int cpu, un
+       unsigned int mc_saved_count = mc_saved_data->mc_saved_count;
+       int i;
+-      while (leftover) {
++      while (leftover && mc_saved_count < ARRAY_SIZE(mc_saved_tmp)) {
+               mc_header = (struct microcode_header_intel *)ucode_ptr;
+               mc_size = get_totalsize(mc_header);