From 9d8b3016b97023d6911f597e79c291396ba0a4e5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 17 Oct 2015 16:53:21 -0700 Subject: [PATCH] 3.10-stable patches added patches: ib-qib-change-lkey-table-allocation-to-support-more-mrs.patch ubi-return-enospc-if-no-enough-space-available.patch ubi-validate-data_size.patch --- ...table-allocation-to-support-more-mrs.patch | 146 ++++++++++++++++++ queue-3.10/series | 3 + ...-enospc-if-no-enough-space-available.patch | 50 ++++++ queue-3.10/ubi-validate-data_size.patch | 35 +++++ 4 files changed, 234 insertions(+) create mode 100644 queue-3.10/ib-qib-change-lkey-table-allocation-to-support-more-mrs.patch create mode 100644 queue-3.10/ubi-return-enospc-if-no-enough-space-available.patch create mode 100644 queue-3.10/ubi-validate-data_size.patch diff --git a/queue-3.10/ib-qib-change-lkey-table-allocation-to-support-more-mrs.patch b/queue-3.10/ib-qib-change-lkey-table-allocation-to-support-more-mrs.patch new file mode 100644 index 00000000000..a97f7af189f --- /dev/null +++ b/queue-3.10/ib-qib-change-lkey-table-allocation-to-support-more-mrs.patch @@ -0,0 +1,146 @@ +From d6f1c17e162b2a11e708f28fa93f2f79c164b442 Mon Sep 17 00:00:00 2001 +From: Mike Marciniszyn +Date: Tue, 21 Jul 2015 08:36:07 -0400 +Subject: IB/qib: Change lkey table allocation to support more MRs + +From: Mike Marciniszyn + +commit d6f1c17e162b2a11e708f28fa93f2f79c164b442 upstream. + +The lkey table is allocated with with a get_user_pages() with an +order based on a number of index bits from a module parameter. + +The underlying kernel code cannot allocate that many contiguous pages. + +There is no reason the underlying memory needs to be physically +contiguous. + +This patch: +- switches the allocation/deallocation to vmalloc/vfree +- caps the number of bits to 23 to insure at least 1 generation bit + o this matches the module parameter description + +Reviewed-by: Vinit Agnihotri +Signed-off-by: Mike Marciniszyn +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/qib/qib.h | 27 +++++++++++---------------- + drivers/infiniband/hw/qib/qib_keys.c | 4 ++++ + drivers/infiniband/hw/qib/qib_verbs.c | 14 ++++++++++---- + drivers/infiniband/hw/qib/qib_verbs.h | 2 ++ + 4 files changed, 27 insertions(+), 20 deletions(-) + +--- a/drivers/infiniband/hw/qib/qib.h ++++ b/drivers/infiniband/hw/qib/qib.h +@@ -1467,27 +1467,22 @@ extern struct mutex qib_mutex; + * first to avoid possible serial port delays from printk. + */ + #define qib_early_err(dev, fmt, ...) \ +- do { \ +- dev_err(dev, fmt, ##__VA_ARGS__); \ +- } while (0) ++ dev_err(dev, fmt, ##__VA_ARGS__) + + #define qib_dev_err(dd, fmt, ...) \ +- do { \ +- dev_err(&(dd)->pcidev->dev, "%s: " fmt, \ +- qib_get_unit_name((dd)->unit), ##__VA_ARGS__); \ +- } while (0) ++ dev_err(&(dd)->pcidev->dev, "%s: " fmt, \ ++ qib_get_unit_name((dd)->unit), ##__VA_ARGS__) + +-#define qib_dev_porterr(dd, port, fmt, ...) \ +- do { \ +- dev_err(&(dd)->pcidev->dev, "%s: IB%u:%u " fmt, \ +- qib_get_unit_name((dd)->unit), (dd)->unit, (port), \ +- ##__VA_ARGS__); \ +- } while (0) ++#define qib_dev_warn(dd, fmt, ...) \ ++ dev_warn(&(dd)->pcidev->dev, "%s: " fmt, \ ++ qib_get_unit_name((dd)->unit), ##__VA_ARGS__) + ++#define qib_dev_porterr(dd, port, fmt, ...) \ ++ dev_err(&(dd)->pcidev->dev, "%s: IB%u:%u " fmt, \ ++ qib_get_unit_name((dd)->unit), (dd)->unit, (port), \ ++ ##__VA_ARGS__) + #define qib_devinfo(pcidev, fmt, ...) \ +- do { \ +- dev_info(&(pcidev)->dev, fmt, ##__VA_ARGS__); \ +- } while (0) ++ dev_info(&(pcidev)->dev, fmt, ##__VA_ARGS__) + + /* + * this is used for formatting hw error messages... +--- a/drivers/infiniband/hw/qib/qib_keys.c ++++ b/drivers/infiniband/hw/qib/qib_keys.c +@@ -86,6 +86,10 @@ int qib_alloc_lkey(struct qib_mregion *m + * unrestricted LKEY. + */ + rkt->gen++; ++ /* ++ * bits are capped in qib_verbs.c to insure enough bits ++ * for generation number ++ */ + mr->lkey = (r << (32 - ib_qib_lkey_table_size)) | + ((((1 << (24 - ib_qib_lkey_table_size)) - 1) & rkt->gen) + << 8); +--- a/drivers/infiniband/hw/qib/qib_verbs.c ++++ b/drivers/infiniband/hw/qib/qib_verbs.c +@@ -40,6 +40,7 @@ + #include + #include + #include ++#include + + #include "qib.h" + #include "qib_common.h" +@@ -2084,10 +2085,16 @@ int qib_register_ib_device(struct qib_de + * the LKEY). The remaining bits act as a generation number or tag. + */ + spin_lock_init(&dev->lk_table.lock); ++ /* insure generation is at least 4 bits see keys.c */ ++ if (ib_qib_lkey_table_size > MAX_LKEY_TABLE_BITS) { ++ qib_dev_warn(dd, "lkey bits %u too large, reduced to %u\n", ++ ib_qib_lkey_table_size, MAX_LKEY_TABLE_BITS); ++ ib_qib_lkey_table_size = MAX_LKEY_TABLE_BITS; ++ } + dev->lk_table.max = 1 << ib_qib_lkey_table_size; + lk_tab_size = dev->lk_table.max * sizeof(*dev->lk_table.table); + dev->lk_table.table = (struct qib_mregion __rcu **) +- __get_free_pages(GFP_KERNEL, get_order(lk_tab_size)); ++ vmalloc(lk_tab_size); + if (dev->lk_table.table == NULL) { + ret = -ENOMEM; + goto err_lk; +@@ -2260,7 +2267,7 @@ err_tx: + sizeof(struct qib_pio_header), + dev->pio_hdrs, dev->pio_hdrs_phys); + err_hdrs: +- free_pages((unsigned long) dev->lk_table.table, get_order(lk_tab_size)); ++ vfree(dev->lk_table.table); + err_lk: + kfree(dev->qp_table); + err_qpt: +@@ -2314,8 +2321,7 @@ void qib_unregister_ib_device(struct qib + sizeof(struct qib_pio_header), + dev->pio_hdrs, dev->pio_hdrs_phys); + lk_tab_size = dev->lk_table.max * sizeof(*dev->lk_table.table); +- free_pages((unsigned long) dev->lk_table.table, +- get_order(lk_tab_size)); ++ vfree(dev->lk_table.table); + kfree(dev->qp_table); + } + +--- a/drivers/infiniband/hw/qib/qib_verbs.h ++++ b/drivers/infiniband/hw/qib/qib_verbs.h +@@ -645,6 +645,8 @@ struct qib_qpn_table { + struct qpn_map map[QPNMAP_ENTRIES]; + }; + ++#define MAX_LKEY_TABLE_BITS 23 ++ + struct qib_lkey_table { + spinlock_t lock; /* protect changes in this struct */ + u32 next; /* next unused index (speeds search) */ diff --git a/queue-3.10/series b/queue-3.10/series index 36b8dacd6fd..d62c0949e68 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -38,3 +38,6 @@ usb-add-reset-resume-quirk-for-two-plantronics-usb-headphones.patch mips-dma-default-fix-32-bit-fall-back-to-gfp_dma.patch md-flush-event_work-before-stopping-array.patch powerpc-msi-fix-race-condition-in-tearing-down-msi-interrupts.patch +ubi-validate-data_size.patch +ubi-return-enospc-if-no-enough-space-available.patch +ib-qib-change-lkey-table-allocation-to-support-more-mrs.patch diff --git a/queue-3.10/ubi-return-enospc-if-no-enough-space-available.patch b/queue-3.10/ubi-return-enospc-if-no-enough-space-available.patch new file mode 100644 index 00000000000..b41a42616f7 --- /dev/null +++ b/queue-3.10/ubi-return-enospc-if-no-enough-space-available.patch @@ -0,0 +1,50 @@ +From 7c7feb2ebfc9c0552c51f0c050db1d1a004faac5 Mon Sep 17 00:00:00 2001 +From: shengyong +Date: Mon, 28 Sep 2015 17:57:19 +0000 +Subject: UBI: return ENOSPC if no enough space available + +From: shengyong + +commit 7c7feb2ebfc9c0552c51f0c050db1d1a004faac5 upstream. + +UBI: attaching mtd1 to ubi0 +UBI: scanning is finished +UBI error: init_volumes: not enough PEBs, required 706, available 686 +UBI error: ubi_wl_init: no enough physical eraseblocks (-20, need 1) +UBI error: ubi_attach_mtd_dev: failed to attach mtd1, error -12 <= NOT ENOMEM +UBI error: ubi_init: cannot attach mtd1 + +If available PEBs are not enough when initializing volumes, return -ENOSPC +directly. If available PEBs are not enough when initializing WL, return +-ENOSPC instead of -ENOMEM. + +Signed-off-by: Sheng Yong +Signed-off-by: Richard Weinberger +Reviewed-by: David Gstir +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mtd/ubi/vtbl.c | 1 + + drivers/mtd/ubi/wl.c | 1 + + 2 files changed, 2 insertions(+) + +--- a/drivers/mtd/ubi/vtbl.c ++++ b/drivers/mtd/ubi/vtbl.c +@@ -651,6 +651,7 @@ static int init_volumes(struct ubi_devic + if (ubi->corr_peb_count) + ubi_err("%d PEBs are corrupted and not used", + ubi->corr_peb_count); ++ return -ENOSPC; + } + ubi->rsvd_pebs += reserved_pebs; + ubi->avail_pebs -= reserved_pebs; +--- a/drivers/mtd/ubi/wl.c ++++ b/drivers/mtd/ubi/wl.c +@@ -1978,6 +1978,7 @@ int ubi_wl_init(struct ubi_device *ubi, + if (ubi->corr_peb_count) + ubi_err("%d PEBs are corrupted and not used", + ubi->corr_peb_count); ++ err = -ENOSPC; + goto out_free; + } + ubi->avail_pebs -= reserved_pebs; diff --git a/queue-3.10/ubi-validate-data_size.patch b/queue-3.10/ubi-validate-data_size.patch new file mode 100644 index 00000000000..ad8941f1973 --- /dev/null +++ b/queue-3.10/ubi-validate-data_size.patch @@ -0,0 +1,35 @@ +From 281fda27673f833a01d516658a64d22a32c8e072 Mon Sep 17 00:00:00 2001 +From: Richard Weinberger +Date: Tue, 22 Sep 2015 23:58:07 +0200 +Subject: UBI: Validate data_size + +From: Richard Weinberger + +commit 281fda27673f833a01d516658a64d22a32c8e072 upstream. + +Make sure that data_size is less than LEB size. +Otherwise a handcrafted UBI image is able to trigger +an out of bounds memory access in ubi_compare_lebs(). + +Signed-off-by: Richard Weinberger +Reviewed-by: David Gstir +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mtd/ubi/io.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/mtd/ubi/io.c ++++ b/drivers/mtd/ubi/io.c +@@ -931,6 +931,11 @@ static int validate_vid_hdr(const struct + goto bad; + } + ++ if (data_size > ubi->leb_size) { ++ ubi_err("bad data_size"); ++ goto bad; ++ } ++ + if (vol_type == UBI_VID_STATIC) { + /* + * Although from high-level point of view static volumes may -- 2.47.3