From: Greg Kroah-Hartman Date: Sat, 28 Feb 2015 23:05:59 +0000 (-0800) Subject: 3.14-stable patches X-Git-Tag: v3.10.71~35 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=118d27705e897c40d5795903a2d0c3460ef6751e;p=thirdparty%2Fkernel%2Fstable-queue.git 3.14-stable patches added patches: added-little-endian-support-to-vtpm-module.patch cfq-iosched-fix-incorrect-filing-of-rt-async-cfqq.patch cfq-iosched-handle-failure-of-cfq-group-allocation.patch char-tpm-add-missing-error-check-for-devm_kzalloc.patch iscsi-target-drop-problematic-active_ts_list-usage.patch nfsv4.1-fix-a-kfree-of-uninitialised-pointers-in-decode_cb_sequence_args.patch sunrpc-null-utsname-dereference-on-nfs-umount-during-namespace-cleanup.patch tpm-add-new-tpms-to-the-tail-of-the-list-to-prevent-inadvertent-change-of-dev.patch tpm-fix-null-return-in-tpm_ibmvtpm_get_desired_dma.patch tpm-tpm_i2c_stm_st33-fix-potential-bug-in-tpm_stm_i2c_send.patch --- diff --git a/queue-3.14/added-little-endian-support-to-vtpm-module.patch b/queue-3.14/added-little-endian-support-to-vtpm-module.patch new file mode 100644 index 00000000000..d1176366b46 --- /dev/null +++ b/queue-3.14/added-little-endian-support-to-vtpm-module.patch @@ -0,0 +1,100 @@ +From eb71f8a5e33fa1066fb92f0111ab366a341e1f6c Mon Sep 17 00:00:00 2001 +From: honclo +Date: Thu, 12 Feb 2015 21:02:24 -0500 +Subject: Added Little Endian support to vtpm module + +From: honclo + +commit eb71f8a5e33fa1066fb92f0111ab366a341e1f6c upstream. + +The tpm_ibmvtpm module is affected by an unaligned access problem. +ibmvtpm_crq_get_version failed with rc=-4 during boot when vTPM is +enabled in Power partition, which supports both little endian and +big endian modes. + +We added little endian support to fix this problem: +1) added cpu_to_be64 calls to ensure BE data is sent from an LE OS. +2) added be16_to_cpu and be32_to_cpu calls to make sure data received + is in LE format on a LE OS. + +Signed-off-by: Hon Ching(Vicky) Lo +Signed-off-by: Joy Latten +[phuewe: manually applied the patch :( ] +Reviewed-by: Ashley Lai +Signed-off-by: Peter Huewe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/tpm/tpm_ibmvtpm.c | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +--- a/drivers/char/tpm/tpm_ibmvtpm.c ++++ b/drivers/char/tpm/tpm_ibmvtpm.c +@@ -148,7 +148,8 @@ static int tpm_ibmvtpm_send(struct tpm_c + crq.len = (u16)count; + crq.data = ibmvtpm->rtce_dma_handle; + +- rc = ibmvtpm_send_crq(ibmvtpm->vdev, word[0], word[1]); ++ rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(word[0]), ++ cpu_to_be64(word[1])); + if (rc != H_SUCCESS) { + dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc); + rc = 0; +@@ -186,7 +187,8 @@ static int ibmvtpm_crq_get_rtce_size(str + crq.valid = (u8)IBMVTPM_VALID_CMD; + crq.msg = (u8)VTPM_GET_RTCE_BUFFER_SIZE; + +- rc = ibmvtpm_send_crq(ibmvtpm->vdev, buf[0], buf[1]); ++ rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(buf[0]), ++ cpu_to_be64(buf[1])); + if (rc != H_SUCCESS) + dev_err(ibmvtpm->dev, + "ibmvtpm_crq_get_rtce_size failed rc=%d\n", rc); +@@ -212,7 +214,8 @@ static int ibmvtpm_crq_get_version(struc + crq.valid = (u8)IBMVTPM_VALID_CMD; + crq.msg = (u8)VTPM_GET_VERSION; + +- rc = ibmvtpm_send_crq(ibmvtpm->vdev, buf[0], buf[1]); ++ rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(buf[0]), ++ cpu_to_be64(buf[1])); + if (rc != H_SUCCESS) + dev_err(ibmvtpm->dev, + "ibmvtpm_crq_get_version failed rc=%d\n", rc); +@@ -335,7 +338,8 @@ static int tpm_ibmvtpm_suspend(struct de + crq.valid = (u8)IBMVTPM_VALID_CMD; + crq.msg = (u8)VTPM_PREPARE_TO_SUSPEND; + +- rc = ibmvtpm_send_crq(ibmvtpm->vdev, buf[0], buf[1]); ++ rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(buf[0]), ++ cpu_to_be64(buf[1])); + if (rc != H_SUCCESS) + dev_err(ibmvtpm->dev, + "tpm_ibmvtpm_suspend failed rc=%d\n", rc); +@@ -480,11 +484,11 @@ static void ibmvtpm_crq_process(struct i + case IBMVTPM_VALID_CMD: + switch (crq->msg) { + case VTPM_GET_RTCE_BUFFER_SIZE_RES: +- if (crq->len <= 0) { ++ if (be16_to_cpu(crq->len) <= 0) { + dev_err(ibmvtpm->dev, "Invalid rtce size\n"); + return; + } +- ibmvtpm->rtce_size = crq->len; ++ ibmvtpm->rtce_size = be16_to_cpu(crq->len); + ibmvtpm->rtce_buf = kmalloc(ibmvtpm->rtce_size, + GFP_KERNEL); + if (!ibmvtpm->rtce_buf) { +@@ -505,11 +509,11 @@ static void ibmvtpm_crq_process(struct i + + return; + case VTPM_GET_VERSION_RES: +- ibmvtpm->vtpm_version = crq->data; ++ ibmvtpm->vtpm_version = be32_to_cpu(crq->data); + return; + case VTPM_TPM_COMMAND_RES: + /* len of the data in rtce buffer */ +- ibmvtpm->res_len = crq->len; ++ ibmvtpm->res_len = be16_to_cpu(crq->len); + wake_up_interruptible(&ibmvtpm->wq); + return; + default: diff --git a/queue-3.14/cfq-iosched-fix-incorrect-filing-of-rt-async-cfqq.patch b/queue-3.14/cfq-iosched-fix-incorrect-filing-of-rt-async-cfqq.patch new file mode 100644 index 00000000000..230a7a55dcd --- /dev/null +++ b/queue-3.14/cfq-iosched-fix-incorrect-filing-of-rt-async-cfqq.patch @@ -0,0 +1,116 @@ +From c6ce194325cef342313e3d27620411ce90a89c50 Mon Sep 17 00:00:00 2001 +From: Jeff Moyer +Date: Mon, 12 Jan 2015 15:21:01 -0500 +Subject: cfq-iosched: fix incorrect filing of rt async cfqq + +From: Jeff Moyer + +commit c6ce194325cef342313e3d27620411ce90a89c50 upstream. + +Hi, + +If you can manage to submit an async write as the first async I/O from +the context of a process with realtime scheduling priority, then a +cfq_queue is allocated, but filed into the wrong async_cfqq bucket. It +ends up in the best effort array, but actually has realtime I/O +scheduling priority set in cfqq->ioprio. + +The reason is that cfq_get_queue assumes the default scheduling class and +priority when there is no information present (i.e. when the async cfqq +is created): + +static struct cfq_queue * +cfq_get_queue(struct cfq_data *cfqd, bool is_sync, struct cfq_io_cq *cic, + struct bio *bio, gfp_t gfp_mask) +{ + const int ioprio_class = IOPRIO_PRIO_CLASS(cic->ioprio); + const int ioprio = IOPRIO_PRIO_DATA(cic->ioprio); + +cic->ioprio starts out as 0, which is "invalid". So, class of 0 +(IOPRIO_CLASS_NONE) is passed to cfq_async_queue_prio like so: + + async_cfqq = cfq_async_queue_prio(cfqd, ioprio_class, ioprio); + +static struct cfq_queue ** +cfq_async_queue_prio(struct cfq_data *cfqd, int ioprio_class, int ioprio) +{ + switch (ioprio_class) { + case IOPRIO_CLASS_RT: + return &cfqd->async_cfqq[0][ioprio]; + case IOPRIO_CLASS_NONE: + ioprio = IOPRIO_NORM; + /* fall through */ + case IOPRIO_CLASS_BE: + return &cfqd->async_cfqq[1][ioprio]; + case IOPRIO_CLASS_IDLE: + return &cfqd->async_idle_cfqq; + default: + BUG(); + } +} + +Here, instead of returning a class mapped from the process' scheduling +priority, we get back the bucket associated with IOPRIO_CLASS_BE. + +Now, there is no queue allocated there yet, so we create it: + + cfqq = cfq_find_alloc_queue(cfqd, is_sync, cic, bio, gfp_mask); + +That function ends up doing this: + + cfq_init_cfqq(cfqd, cfqq, current->pid, is_sync); + cfq_init_prio_data(cfqq, cic); + +cfq_init_cfqq marks the priority as having changed. Then, cfq_init_prio +data does this: + + ioprio_class = IOPRIO_PRIO_CLASS(cic->ioprio); + switch (ioprio_class) { + default: + printk(KERN_ERR "cfq: bad prio %x\n", ioprio_class); + case IOPRIO_CLASS_NONE: + /* + * no prio set, inherit CPU scheduling settings + */ + cfqq->ioprio = task_nice_ioprio(tsk); + cfqq->ioprio_class = task_nice_ioclass(tsk); + break; + +So we basically have two code paths that treat IOPRIO_CLASS_NONE +differently, which results in an RT async cfqq filed into a best effort +bucket. + +Attached is a patch which fixes the problem. I'm not sure how to make +it cleaner. Suggestions would be welcome. + +Signed-off-by: Jeff Moyer +Tested-by: Hidehiro Kawai +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + block/cfq-iosched.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/block/cfq-iosched.c ++++ b/block/cfq-iosched.c +@@ -3656,12 +3656,17 @@ static struct cfq_queue * + cfq_get_queue(struct cfq_data *cfqd, bool is_sync, struct cfq_io_cq *cic, + struct bio *bio, gfp_t gfp_mask) + { +- const int ioprio_class = IOPRIO_PRIO_CLASS(cic->ioprio); +- const int ioprio = IOPRIO_PRIO_DATA(cic->ioprio); ++ int ioprio_class = IOPRIO_PRIO_CLASS(cic->ioprio); ++ int ioprio = IOPRIO_PRIO_DATA(cic->ioprio); + struct cfq_queue **async_cfqq = NULL; + struct cfq_queue *cfqq = NULL; + + if (!is_sync) { ++ if (!ioprio_valid(cic->ioprio)) { ++ struct task_struct *tsk = current; ++ ioprio = task_nice_ioprio(tsk); ++ ioprio_class = task_nice_ioclass(tsk); ++ } + async_cfqq = cfq_async_queue_prio(cfqd, ioprio_class, ioprio); + cfqq = *async_cfqq; + } diff --git a/queue-3.14/cfq-iosched-handle-failure-of-cfq-group-allocation.patch b/queue-3.14/cfq-iosched-handle-failure-of-cfq-group-allocation.patch new file mode 100644 index 00000000000..11693b0ed61 --- /dev/null +++ b/queue-3.14/cfq-iosched-handle-failure-of-cfq-group-allocation.patch @@ -0,0 +1,54 @@ +From 69abaffec7d47a083739b79e3066cb3730eba72e Mon Sep 17 00:00:00 2001 +From: Konstantin Khlebnikov +Date: Mon, 9 Feb 2015 16:42:49 +0300 +Subject: cfq-iosched: handle failure of cfq group allocation + +From: Konstantin Khlebnikov + +commit 69abaffec7d47a083739b79e3066cb3730eba72e upstream. + +Cfq_lookup_create_cfqg() allocates struct blkcg_gq using GFP_ATOMIC. +In cfq_find_alloc_queue() possible allocation failure is not handled. +As a result kernel oopses on NULL pointer dereference when +cfq_link_cfqq_cfqg() calls cfqg_get() for NULL pointer. + +Bug was introduced in v3.5 in commit cd1604fab4f9 ("blkcg: factor +out blkio_group creation"). Prior to that commit cfq group lookup +had returned pointer to root group as fallback. + +This patch handles this error using existing fallback oom_cfqq. + +Signed-off-by: Konstantin Khlebnikov +Acked-by: Tejun Heo +Acked-by: Vivek Goyal +Fixes: cd1604fab4f9 ("blkcg: factor out blkio_group creation") +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + block/cfq-iosched.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/block/cfq-iosched.c ++++ b/block/cfq-iosched.c +@@ -3585,6 +3585,11 @@ retry: + + blkcg = bio_blkcg(bio); + cfqg = cfq_lookup_create_cfqg(cfqd, blkcg); ++ if (!cfqg) { ++ cfqq = &cfqd->oom_cfqq; ++ goto out; ++ } ++ + cfqq = cic_to_cfqq(cic, is_sync); + + /* +@@ -3621,7 +3626,7 @@ retry: + } else + cfqq = &cfqd->oom_cfqq; + } +- ++out: + if (new_cfqq) + kmem_cache_free(cfq_pool, new_cfqq); + diff --git a/queue-3.14/char-tpm-add-missing-error-check-for-devm_kzalloc.patch b/queue-3.14/char-tpm-add-missing-error-check-for-devm_kzalloc.patch new file mode 100644 index 00000000000..ab263a8858e --- /dev/null +++ b/queue-3.14/char-tpm-add-missing-error-check-for-devm_kzalloc.patch @@ -0,0 +1,51 @@ +From bb95cd34ba4c9467114acc78eeddd53ab1c10085 Mon Sep 17 00:00:00 2001 +From: Kiran Padwal +Date: Fri, 19 Sep 2014 12:44:39 +0530 +Subject: char: tpm: Add missing error check for devm_kzalloc + +From: Kiran Padwal + +commit bb95cd34ba4c9467114acc78eeddd53ab1c10085 upstream. + +Currently these driver are missing a check on the return value of devm_kzalloc, +which would cause a NULL pointer dereference in a OOM situation. + +This patch adds a missing check for tpm_i2c_atmel.c and tpm_i2c_nuvoton.c + +Signed-off-by: Kiran Padwal +Reviewed-By: Jason Gunthorpe +Signed-off-by: Peter Huewe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/tpm/tpm_i2c_atmel.c | 4 ++++ + drivers/char/tpm/tpm_i2c_nuvoton.c | 5 +++++ + 2 files changed, 9 insertions(+) + +--- a/drivers/char/tpm/tpm_i2c_atmel.c ++++ b/drivers/char/tpm/tpm_i2c_atmel.c +@@ -168,6 +168,10 @@ static int i2c_atmel_probe(struct i2c_cl + + chip->vendor.priv = devm_kzalloc(dev, sizeof(struct priv_data), + GFP_KERNEL); ++ if (!chip->vendor.priv) { ++ rc = -ENOMEM; ++ goto out_err; ++ } + + /* Default timeouts */ + chip->vendor.timeout_a = msecs_to_jiffies(TPM_I2C_SHORT_TIMEOUT); +--- a/drivers/char/tpm/tpm_i2c_nuvoton.c ++++ b/drivers/char/tpm/tpm_i2c_nuvoton.c +@@ -538,6 +538,11 @@ static int i2c_nuvoton_probe(struct i2c_ + + chip->vendor.priv = devm_kzalloc(dev, sizeof(struct priv_data), + GFP_KERNEL); ++ if (!chip->vendor.priv) { ++ rc = -ENOMEM; ++ goto out_err; ++ } ++ + init_waitqueue_head(&chip->vendor.read_queue); + init_waitqueue_head(&chip->vendor.int_queue); + diff --git a/queue-3.14/iscsi-target-drop-problematic-active_ts_list-usage.patch b/queue-3.14/iscsi-target-drop-problematic-active_ts_list-usage.patch new file mode 100644 index 00000000000..c47d56a5788 --- /dev/null +++ b/queue-3.14/iscsi-target-drop-problematic-active_ts_list-usage.patch @@ -0,0 +1,133 @@ +From 3fd7b60f2c7418239d586e359e0c6d8503e10646 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Thu, 22 Jan 2015 00:56:53 -0800 +Subject: iscsi-target: Drop problematic active_ts_list usage + +From: Nicholas Bellinger + +commit 3fd7b60f2c7418239d586e359e0c6d8503e10646 upstream. + +This patch drops legacy active_ts_list usage within iscsi_target_tq.c +code. It was originally used to track the active thread sets during +iscsi-target shutdown, and is no longer used by modern upstream code. + +Two people have reported list corruption using traditional iscsi-target +and iser-target with the following backtrace, that appears to be related +to iscsi_thread_set->ts_list being used across both active_ts_list and +inactive_ts_list. + +[ 60.782534] ------------[ cut here ]------------ +[ 60.782543] WARNING: CPU: 0 PID: 9430 at lib/list_debug.c:53 __list_del_entry+0x63/0xd0() +[ 60.782545] list_del corruption, ffff88045b00d180->next is LIST_POISON1 (dead000000100100) +[ 60.782546] Modules linked in: ib_srpt tcm_qla2xxx qla2xxx tcm_loop tcm_fc libfc scsi_transport_fc scsi_tgt ib_isert rdma_cm iw_cm ib_addr iscsi_target_mod target_core_pscsi target_core_file target_core_iblock target_core_mod configfs ebtable_nat ebtables ipt_MASQUERADE iptable_nat nf_nat_ipv4 nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 ipt_REJECT xt_CHECKSUM iptable_mangle iptable_filter ip_tables bridge stp llc autofs4 sunrpc ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables ipv6 ib_ipoib ib_cm ib_uverbs ib_umad mlx4_en mlx4_ib ib_sa ib_mad ib_core mlx4_core dm_mirror dm_region_hash dm_log dm_mod vhost_net macvtap macvlan vhost tun kvm_intel kvm uinput iTCO_wdt iTCO_vendor_support microcode serio_raw pcspkr sb_edac edac_core sg i2c_i801 lpc_ich mfd_core mtip32xx igb i2c_algo_bit i2c_core ptp pps_core ioatdma dca wmi ext3(F) jbd(F) mbcache(F) sd_mod(F) crc_t10dif(F) crct10dif_common(F) ahci(F) libahci(F) isci(F) libsas(F) scsi_transport_sas(F) [last unloaded: speedstep_lib] +[ 60.782597] CPU: 0 PID: 9430 Comm: iscsi_ttx Tainted: GF 3.12.19+ #2 +[ 60.782598] Hardware name: Supermicro X9DRX+-F/X9DRX+-F, BIOS 3.00 07/09/2013 +[ 60.782599] 0000000000000035 ffff88044de31d08 ffffffff81553ae7 0000000000000035 +[ 60.782602] ffff88044de31d58 ffff88044de31d48 ffffffff8104d1cc 0000000000000002 +[ 60.782605] ffff88045b00d180 ffff88045b00d0c0 ffff88045b00d0c0 ffff88044de31e58 +[ 60.782607] Call Trace: +[ 60.782611] [] dump_stack+0x49/0x62 +[ 60.782615] [] warn_slowpath_common+0x8c/0xc0 +[ 60.782618] [] warn_slowpath_fmt+0x46/0x50 +[ 60.782620] [] __list_del_entry+0x63/0xd0 +[ 60.782622] [] list_del+0x11/0x40 +[ 60.782630] [] iscsi_del_ts_from_active_list+0x29/0x50 [iscsi_target_mod] +[ 60.782635] [] iscsi_tx_thread_pre_handler+0xa1/0x180 [iscsi_target_mod] +[ 60.782642] [] iscsi_target_tx_thread+0x4e/0x220 [iscsi_target_mod] +[ 60.782647] [] ? iscsit_handle_snack+0x190/0x190 [iscsi_target_mod] +[ 60.782652] [] ? iscsit_handle_snack+0x190/0x190 [iscsi_target_mod] +[ 60.782655] [] kthread+0xce/0xe0 +[ 60.782657] [] ? kthread_freezable_should_stop+0x70/0x70 +[ 60.782660] [] ret_from_fork+0x7c/0xb0 +[ 60.782662] [] ? kthread_freezable_should_stop+0x70/0x70 +[ 60.782663] ---[ end trace 9662f4a661d33965 ]--- + +Since this code is no longer used, go ahead and drop the problematic usage +all-together. + +Reported-by: Gavin Guo +Reported-by: Moussa Ba +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/iscsi/iscsi_target_tq.c | 28 +++++----------------------- + 1 file changed, 5 insertions(+), 23 deletions(-) + +--- a/drivers/target/iscsi/iscsi_target_tq.c ++++ b/drivers/target/iscsi/iscsi_target_tq.c +@@ -24,36 +24,22 @@ + #include "iscsi_target_tq.h" + #include "iscsi_target.h" + +-static LIST_HEAD(active_ts_list); + static LIST_HEAD(inactive_ts_list); +-static DEFINE_SPINLOCK(active_ts_lock); + static DEFINE_SPINLOCK(inactive_ts_lock); + static DEFINE_SPINLOCK(ts_bitmap_lock); + +-static void iscsi_add_ts_to_active_list(struct iscsi_thread_set *ts) +-{ +- spin_lock(&active_ts_lock); +- list_add_tail(&ts->ts_list, &active_ts_list); +- iscsit_global->active_ts++; +- spin_unlock(&active_ts_lock); +-} +- + static void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set *ts) + { ++ if (!list_empty(&ts->ts_list)) { ++ WARN_ON(1); ++ return; ++ } + spin_lock(&inactive_ts_lock); + list_add_tail(&ts->ts_list, &inactive_ts_list); + iscsit_global->inactive_ts++; + spin_unlock(&inactive_ts_lock); + } + +-static void iscsi_del_ts_from_active_list(struct iscsi_thread_set *ts) +-{ +- spin_lock(&active_ts_lock); +- list_del(&ts->ts_list); +- iscsit_global->active_ts--; +- spin_unlock(&active_ts_lock); +-} +- + static struct iscsi_thread_set *iscsi_get_ts_from_inactive_list(void) + { + struct iscsi_thread_set *ts; +@@ -66,7 +52,7 @@ static struct iscsi_thread_set *iscsi_ge + + ts = list_first_entry(&inactive_ts_list, struct iscsi_thread_set, ts_list); + +- list_del(&ts->ts_list); ++ list_del_init(&ts->ts_list); + iscsit_global->inactive_ts--; + spin_unlock(&inactive_ts_lock); + +@@ -204,8 +190,6 @@ static void iscsi_deallocate_extra_threa + + void iscsi_activate_thread_set(struct iscsi_conn *conn, struct iscsi_thread_set *ts) + { +- iscsi_add_ts_to_active_list(ts); +- + spin_lock_bh(&ts->ts_state_lock); + conn->thread_set = ts; + ts->conn = conn; +@@ -397,7 +381,6 @@ struct iscsi_conn *iscsi_rx_thread_pre_h + + if (ts->delay_inactive && (--ts->thread_count == 0)) { + spin_unlock_bh(&ts->ts_state_lock); +- iscsi_del_ts_from_active_list(ts); + + if (!iscsit_global->in_shutdown) + iscsi_deallocate_extra_thread_sets(); +@@ -452,7 +435,6 @@ struct iscsi_conn *iscsi_tx_thread_pre_h + + if (ts->delay_inactive && (--ts->thread_count == 0)) { + spin_unlock_bh(&ts->ts_state_lock); +- iscsi_del_ts_from_active_list(ts); + + if (!iscsit_global->in_shutdown) + iscsi_deallocate_extra_thread_sets(); diff --git a/queue-3.14/nfsv4.1-fix-a-kfree-of-uninitialised-pointers-in-decode_cb_sequence_args.patch b/queue-3.14/nfsv4.1-fix-a-kfree-of-uninitialised-pointers-in-decode_cb_sequence_args.patch new file mode 100644 index 00000000000..bb0206d282c --- /dev/null +++ b/queue-3.14/nfsv4.1-fix-a-kfree-of-uninitialised-pointers-in-decode_cb_sequence_args.patch @@ -0,0 +1,36 @@ +From d8ba1f971497c19cf80da1ea5391a46a5f9fbd41 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Wed, 11 Feb 2015 17:27:55 -0500 +Subject: NFSv4.1: Fix a kfree() of uninitialised pointers in decode_cb_sequence_args + +From: Trond Myklebust + +commit d8ba1f971497c19cf80da1ea5391a46a5f9fbd41 upstream. + +If the call to decode_rc_list() fails due to a memory allocation error, +then we need to truncate the array size to ensure that we only call +kfree() on those pointer that were allocated. + +Reported-by: David Ramos +Fixes: 4aece6a19cf7f ("nfs41: cb_sequence xdr implementation") +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/callback_xdr.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/fs/nfs/callback_xdr.c ++++ b/fs/nfs/callback_xdr.c +@@ -464,8 +464,10 @@ static __be32 decode_cb_sequence_args(st + + for (i = 0; i < args->csa_nrclists; i++) { + status = decode_rc_list(xdr, &args->csa_rclists[i]); +- if (status) ++ if (status) { ++ args->csa_nrclists = i; + goto out_free; ++ } + } + } + status = 0; diff --git a/queue-3.14/series b/queue-3.14/series index 78734c61501..fc8f9893867 100644 --- a/queue-3.14/series +++ b/queue-3.14/series @@ -33,3 +33,13 @@ arm-dra7-hwmod-fix-boot-crash-with-debug_ll-enabled-on-uart3.patch arm-dts-tegra20-fix-gr3d-dsi-unit-and-reg-base-addresses.patch arm-dts-am335x-bone-usb0-is-hardwired-for-peripheral.patch tpm_tis-verify-interrupt-during-init.patch +tpm-add-new-tpms-to-the-tail-of-the-list-to-prevent-inadvertent-change-of-dev.patch +char-tpm-add-missing-error-check-for-devm_kzalloc.patch +tpm-fix-null-return-in-tpm_ibmvtpm_get_desired_dma.patch +tpm-tpm_i2c_stm_st33-fix-potential-bug-in-tpm_stm_i2c_send.patch +added-little-endian-support-to-vtpm-module.patch +sunrpc-null-utsname-dereference-on-nfs-umount-during-namespace-cleanup.patch +nfsv4.1-fix-a-kfree-of-uninitialised-pointers-in-decode_cb_sequence_args.patch +iscsi-target-drop-problematic-active_ts_list-usage.patch +cfq-iosched-handle-failure-of-cfq-group-allocation.patch +cfq-iosched-fix-incorrect-filing-of-rt-async-cfqq.patch diff --git a/queue-3.14/sunrpc-null-utsname-dereference-on-nfs-umount-during-namespace-cleanup.patch b/queue-3.14/sunrpc-null-utsname-dereference-on-nfs-umount-during-namespace-cleanup.patch new file mode 100644 index 00000000000..50f92d6f567 --- /dev/null +++ b/queue-3.14/sunrpc-null-utsname-dereference-on-nfs-umount-during-namespace-cleanup.patch @@ -0,0 +1,183 @@ +From 03a9a42a1a7e5b3e7919ddfacc1d1cc81882a955 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Fri, 30 Jan 2015 18:12:28 -0500 +Subject: SUNRPC: NULL utsname dereference on NFS umount during namespace cleanup +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Trond Myklebust + +commit 03a9a42a1a7e5b3e7919ddfacc1d1cc81882a955 upstream. + +Fix an Oopsable condition when nsm_mon_unmon is called as part of the +namespace cleanup, which now apparently happens after the utsname +has been freed. + +Link: http://lkml.kernel.org/r/20150125220604.090121ae@neptune.home +Reported-by: Bruno Prémont +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + fs/lockd/mon.c | 13 +++++++++---- + include/linux/sunrpc/clnt.h | 3 ++- + net/sunrpc/clnt.c | 12 +++++++----- + net/sunrpc/rpcb_clnt.c | 8 ++++++-- + 4 files changed, 24 insertions(+), 12 deletions(-) + +--- a/fs/lockd/mon.c ++++ b/fs/lockd/mon.c +@@ -65,7 +65,7 @@ static inline struct sockaddr *nsm_addr( + return (struct sockaddr *)&nsm->sm_addr; + } + +-static struct rpc_clnt *nsm_create(struct net *net) ++static struct rpc_clnt *nsm_create(struct net *net, const char *nodename) + { + struct sockaddr_in sin = { + .sin_family = AF_INET, +@@ -77,6 +77,7 @@ static struct rpc_clnt *nsm_create(struc + .address = (struct sockaddr *)&sin, + .addrsize = sizeof(sin), + .servername = "rpc.statd", ++ .nodename = nodename, + .program = &nsm_program, + .version = NSM_VERSION, + .authflavor = RPC_AUTH_NULL, +@@ -102,7 +103,7 @@ out: + return clnt; + } + +-static struct rpc_clnt *nsm_client_get(struct net *net) ++static struct rpc_clnt *nsm_client_get(struct net *net, const char *nodename) + { + struct rpc_clnt *clnt, *new; + struct lockd_net *ln = net_generic(net, lockd_net_id); +@@ -111,7 +112,7 @@ static struct rpc_clnt *nsm_client_get(s + if (clnt != NULL) + goto out; + +- clnt = new = nsm_create(net); ++ clnt = new = nsm_create(net, nodename); + if (IS_ERR(clnt)) + goto out; + +@@ -190,19 +191,23 @@ int nsm_monitor(const struct nlm_host *h + struct nsm_res res; + int status; + struct rpc_clnt *clnt; ++ const char *nodename = NULL; + + dprintk("lockd: nsm_monitor(%s)\n", nsm->sm_name); + + if (nsm->sm_monitored) + return 0; + ++ if (host->h_rpcclnt) ++ nodename = host->h_rpcclnt->cl_nodename; ++ + /* + * Choose whether to record the caller_name or IP address of + * this peer in the local rpc.statd's database. + */ + nsm->sm_mon_name = nsm_use_hostnames ? nsm->sm_name : nsm->sm_addrbuf; + +- clnt = nsm_client_get(host->net); ++ clnt = nsm_client_get(host->net, nodename); + if (IS_ERR(clnt)) { + status = PTR_ERR(clnt); + dprintk("lockd: failed to create NSM upcall transport, " +--- a/include/linux/sunrpc/clnt.h ++++ b/include/linux/sunrpc/clnt.h +@@ -57,7 +57,7 @@ struct rpc_clnt { + const struct rpc_timeout *cl_timeout; /* Timeout strategy */ + + int cl_nodelen; /* nodename length */ +- char cl_nodename[UNX_MAXNODENAME]; ++ char cl_nodename[UNX_MAXNODENAME+1]; + struct rpc_pipe_dir_head cl_pipedir_objects; + struct rpc_clnt * cl_parent; /* Points to parent of clones */ + struct rpc_rtt cl_rtt_default; +@@ -109,6 +109,7 @@ struct rpc_create_args { + struct sockaddr *saddress; + const struct rpc_timeout *timeout; + const char *servername; ++ const char *nodename; + const struct rpc_program *program; + u32 prognumber; /* overrides program->number */ + u32 version; +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -286,10 +286,8 @@ static struct rpc_xprt *rpc_clnt_set_tra + + static void rpc_clnt_set_nodename(struct rpc_clnt *clnt, const char *nodename) + { +- clnt->cl_nodelen = strlen(nodename); +- if (clnt->cl_nodelen > UNX_MAXNODENAME) +- clnt->cl_nodelen = UNX_MAXNODENAME; +- memcpy(clnt->cl_nodename, nodename, clnt->cl_nodelen); ++ clnt->cl_nodelen = strlcpy(clnt->cl_nodename, ++ nodename, sizeof(clnt->cl_nodename)); + } + + static int rpc_client_register(struct rpc_clnt *clnt, +@@ -360,6 +358,7 @@ static struct rpc_clnt * rpc_new_client( + const struct rpc_version *version; + struct rpc_clnt *clnt = NULL; + const struct rpc_timeout *timeout; ++ const char *nodename = args->nodename; + int err; + + /* sanity check the name before trying to print it */ +@@ -415,8 +414,10 @@ static struct rpc_clnt * rpc_new_client( + + atomic_set(&clnt->cl_count, 1); + ++ if (nodename == NULL) ++ nodename = utsname()->nodename; + /* save the nodename */ +- rpc_clnt_set_nodename(clnt, utsname()->nodename); ++ rpc_clnt_set_nodename(clnt, nodename); + + err = rpc_client_register(clnt, args->authflavor, args->client_name); + if (err) +@@ -563,6 +564,7 @@ static struct rpc_clnt *__rpc_clone_clie + if (xprt == NULL) + goto out_err; + args->servername = xprt->servername; ++ args->nodename = clnt->cl_nodename; + + new = rpc_new_client(args, xprt, clnt); + if (IS_ERR(new)) { +--- a/net/sunrpc/rpcb_clnt.c ++++ b/net/sunrpc/rpcb_clnt.c +@@ -355,7 +355,8 @@ out: + return result; + } + +-static struct rpc_clnt *rpcb_create(struct net *net, const char *hostname, ++static struct rpc_clnt *rpcb_create(struct net *net, const char *nodename, ++ const char *hostname, + struct sockaddr *srvaddr, size_t salen, + int proto, u32 version) + { +@@ -365,6 +366,7 @@ static struct rpc_clnt *rpcb_create(stru + .address = srvaddr, + .addrsize = salen, + .servername = hostname, ++ .nodename = nodename, + .program = &rpcb_program, + .version = version, + .authflavor = RPC_AUTH_UNIX, +@@ -740,7 +742,9 @@ void rpcb_getport_async(struct rpc_task + dprintk("RPC: %5u %s: trying rpcbind version %u\n", + task->tk_pid, __func__, bind_version); + +- rpcb_clnt = rpcb_create(xprt->xprt_net, xprt->servername, sap, salen, ++ rpcb_clnt = rpcb_create(xprt->xprt_net, ++ clnt->cl_nodename, ++ xprt->servername, sap, salen, + xprt->prot, bind_version); + if (IS_ERR(rpcb_clnt)) { + status = PTR_ERR(rpcb_clnt); diff --git a/queue-3.14/tpm-add-new-tpms-to-the-tail-of-the-list-to-prevent-inadvertent-change-of-dev.patch b/queue-3.14/tpm-add-new-tpms-to-the-tail-of-the-list-to-prevent-inadvertent-change-of-dev.patch new file mode 100644 index 00000000000..a2d6ea96607 --- /dev/null +++ b/queue-3.14/tpm-add-new-tpms-to-the-tail-of-the-list-to-prevent-inadvertent-change-of-dev.patch @@ -0,0 +1,34 @@ +From 398a1e71dc827b994b7f2f56c7c2186fea7f8d75 Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Fri, 29 Aug 2014 10:33:02 +0100 +Subject: TPM: Add new TPMs to the tail of the list to prevent inadvertent change of dev + +From: David Howells + +commit 398a1e71dc827b994b7f2f56c7c2186fea7f8d75 upstream. + +Add newly registered TPMs to the tail of the list, not the beginning, so that +things that are specifying TPM_ANY_NUM don't find that the device they're +using has inadvertently changed. Adding a second device would break IMA, for +instance. + +Signed-off-by: David Howells +Reviewed-by: Jason Gunthorpe +Signed-off-by: Peter Huewe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/tpm/tpm-interface.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/char/tpm/tpm-interface.c ++++ b/drivers/char/tpm/tpm-interface.c +@@ -1122,7 +1122,7 @@ struct tpm_chip *tpm_register_hardware(s + + /* Make chip available */ + spin_lock(&driver_lock); +- list_add_rcu(&chip->list, &tpm_chip_list); ++ list_add_tail_rcu(&chip->list, &tpm_chip_list); + spin_unlock(&driver_lock); + + return chip; diff --git a/queue-3.14/tpm-fix-null-return-in-tpm_ibmvtpm_get_desired_dma.patch b/queue-3.14/tpm-fix-null-return-in-tpm_ibmvtpm_get_desired_dma.patch new file mode 100644 index 00000000000..3734fd8164d --- /dev/null +++ b/queue-3.14/tpm-fix-null-return-in-tpm_ibmvtpm_get_desired_dma.patch @@ -0,0 +1,49 @@ +From 84eb186bc37c0900b53077ca21cf6dd15823a232 Mon Sep 17 00:00:00 2001 +From: "Hon Ching (Vicky) Lo" +Date: Sun, 30 Nov 2014 15:01:28 +0100 +Subject: tpm: Fix NULL return in tpm_ibmvtpm_get_desired_dma + +From: "Hon Ching (Vicky) Lo" + +commit 84eb186bc37c0900b53077ca21cf6dd15823a232 upstream. + +There was an oops in tpm_ibmvtpm_get_desired_dma, which caused +kernel panic during boot when vTPM is enabled in Power partition +configured in AMS mode. + +vio_bus_probe calls vio_cmo_bus_probe which calls +tpm_ibmvtpm_get_desired_dma to get the size needed for DMA allocation. +The problem is, vio_cmo_bus_probe is called before calling probe, which +for vtpm is tpm_ibmvtpm_probe and it's this function that initializes +and sets up vtpm's CRQ and gets required data values. Therefore, +since this has not yet been done, NULL is returned in attempt to get +the size for DMA allocation. + +We added a NULL check. In addition, a default buffer size will +be set when NULL is returned. + +Signed-off-by: Hon Ching (Vicky) Lo +Signed-off-by: Peter Huewe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/tpm/tpm_ibmvtpm.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/char/tpm/tpm_ibmvtpm.c ++++ b/drivers/char/tpm/tpm_ibmvtpm.c +@@ -307,6 +307,14 @@ static int tpm_ibmvtpm_remove(struct vio + static unsigned long tpm_ibmvtpm_get_desired_dma(struct vio_dev *vdev) + { + struct ibmvtpm_dev *ibmvtpm = ibmvtpm_get_data(&vdev->dev); ++ ++ /* ibmvtpm initializes at probe time, so the data we are ++ * asking for may not be set yet. Estimate that 4K required ++ * for TCE-mapped buffer in addition to CRQ. ++ */ ++ if (!ibmvtpm) ++ return CRQ_RES_BUF_SIZE + PAGE_SIZE; ++ + return CRQ_RES_BUF_SIZE + ibmvtpm->rtce_size; + } + diff --git a/queue-3.14/tpm-tpm_i2c_stm_st33-fix-potential-bug-in-tpm_stm_i2c_send.patch b/queue-3.14/tpm-tpm_i2c_stm_st33-fix-potential-bug-in-tpm_stm_i2c_send.patch new file mode 100644 index 00000000000..6e9ccf18290 --- /dev/null +++ b/queue-3.14/tpm-tpm_i2c_stm_st33-fix-potential-bug-in-tpm_stm_i2c_send.patch @@ -0,0 +1,37 @@ +From 1ba3b0b6f218072afe8372d12f1b6bf26a26008e Mon Sep 17 00:00:00 2001 +From: Christophe Ricard +Date: Mon, 1 Dec 2014 19:32:46 +0100 +Subject: tpm/tpm_i2c_stm_st33: Fix potential bug in tpm_stm_i2c_send + +From: Christophe Ricard + +commit 1ba3b0b6f218072afe8372d12f1b6bf26a26008e upstream. + +When sending data in tpm_stm_i2c_send, each loop iteration send buf. +Send buf + i instead as the goal of this for loop is to send a number +of byte from buf that fit in burstcnt. Once those byte are sent, we are +supposed to send the next ones. + +The driver was working because the burstcount value returns always the maximum size for a TPM +command or response. (0x800 for a command and 0x400 for a response). + +Reviewed-by: Jason Gunthorpe +Signed-off-by: Christophe Ricard +Signed-off-by: Peter Huewe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/tpm/tpm_i2c_stm_st33.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/char/tpm/tpm_i2c_stm_st33.c ++++ b/drivers/char/tpm/tpm_i2c_stm_st33.c +@@ -488,7 +488,7 @@ static int tpm_stm_i2c_send(struct tpm_c + if (burstcnt < 0) + return burstcnt; + size = min_t(int, len - i - 1, burstcnt); +- ret = I2C_WRITE_DATA(client, TPM_DATA_FIFO, buf, size); ++ ret = I2C_WRITE_DATA(client, TPM_DATA_FIFO, buf + i, size); + if (ret < 0) + goto out_err; +