From: Greg Kroah-Hartman Date: Tue, 30 Jun 2015 00:29:42 +0000 (-0700) Subject: 3.14-stable patches X-Git-Tag: v3.10.83~18 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9802a320b7c114ceb7123224fd744be32ca879af;p=thirdparty%2Fkernel%2Fstable-queue.git 3.14-stable patches 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 --- 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 index 00000000000..77564ee7226 --- /dev/null +++ b/queue-3.14/btrfs-make-xattr-replace-operations-atomic.patch @@ -0,0 +1,295 @@ +From 5f5bc6b1e2d5a6f827bc860ef2dc5b6f365d1339 Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Sun, 9 Nov 2014 08:38:39 +0000 +Subject: Btrfs: make xattr replace operations atomic + +From: Filipe Manana + +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 +Signed-off-by: Filipe Manana +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..2d215b4f659 --- /dev/null +++ b/queue-3.14/hpsa-add-missing-pci_set_master-in-kdump-path.patch @@ -0,0 +1,34 @@ +From 859c75aba20264d87dd026bab0d0ca3bff385955 Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Fri, 12 Sep 2014 14:44:15 +0200 +Subject: hpsa: add missing pci_set_master in kdump path + +From: Tomas Henzl + +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 +Reviewed-by: Robert Elliott +Tested-by: Robert Elliott +Signed-off-by: Christoph Hellwig +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..e0d7cdb5906 --- /dev/null +++ b/queue-3.14/hpsa-refine-the-pci-enable-disable-handling.patch @@ -0,0 +1,116 @@ +From 132aa220b45d60e9b20def1e9d8be9422eed9616 Mon Sep 17 00:00:00 2001 +From: Tomas Henzl +Date: Thu, 14 Aug 2014 16:12:39 +0200 +Subject: hpsa: refine the pci enable/disable handling + +From: Tomas Henzl + +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 +Reviewed-by: Stephen M. Cameron +Signed-off-by: Christoph Hellwig +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..e2060c22546 --- /dev/null +++ b/queue-3.14/net-mlx4_en-don-t-attempt-to-tx-offload-the-outer-udp-checksum-for-vxlan.patch @@ -0,0 +1,42 @@ +From a4f2dacbf2a5045e34b98a35d9a3857800f25a7b Mon Sep 17 00:00:00 2001 +From: Or Gerlitz +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 + +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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..e26bd9031b9 --- /dev/null +++ b/queue-3.14/sb_edac-fix-erroneous-bytes-gigabytes-conversion.patch @@ -0,0 +1,139 @@ +From 8c009100295597f23978c224aec5751a365bc965 Mon Sep 17 00:00:00 2001 +From: Jim Snow +Date: Tue, 18 Nov 2014 14:51:09 +0100 +Subject: sb_edac: Fix erroneous bytes->gigabytes conversion + +From: Jim Snow + +commit 8c009100295597f23978c224aec5751a365bc965 upstream. + +Signed-off-by: Jim Snow +Signed-off-by: Lukasz Anaczkowski +Signed-off-by: Mauro Carvalho Chehab +[ vlee: Backported to 3.14. Adjusted context. ] +Signed-off-by: Vinson Lee +Signed-off-by: Greg Kroah-Hartman +--- + 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], + ®); + 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 + ®); + 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) diff --git a/queue-3.14/series b/queue-3.14/series index 5255d33e62e..f1ae9731088 100644 --- a/queue-3.14/series +++ b/queue-3.14/series @@ -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 index 00000000000..6f8d0e6e906 --- /dev/null +++ b/queue-3.14/x86-microcode-intel-guard-against-stack-overflow-in-the-loader.patch @@ -0,0 +1,36 @@ +From f84598bd7c851f8b0bf8cd0d7c3be0d73c432ff4 Mon Sep 17 00:00:00 2001 +From: Quentin Casasnovas +Date: Tue, 3 Feb 2015 13:00:22 +0100 +Subject: x86/microcode/intel: Guard against stack overflow in the loader + +From: Quentin Casasnovas + +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 +Cc: "H. Peter Anvin" +Cc: Fenghua Yu +Link: http://lkml.kernel.org/r/1422964824-22056-1-git-send-email-quentin.casasnovas@oracle.com +Signed-off-by: Borislav Petkov +Signed-off-by: Greg Kroah-Hartman + +--- + 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);