From: Greg Kroah-Hartman Date: Thu, 30 Jul 2015 19:41:39 +0000 (-0700) Subject: 4.1-stable patches X-Git-Tag: v4.1.4~29 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8705844396b3c3ddf21c0aa952a473faaceae30a;p=thirdparty%2Fkernel%2Fstable-queue.git 4.1-stable patches added patches: tpm-fix-initialization-of-the-cdev.patch tpm-tpm_crb-fail-when-tpm2-acpi-table-contents-look-corrupted.patch tpm-tpm_crb-fix-le64_to_cpu-conversions-in-crb_acpi_add.patch vtpm-set-virtual-device-before-passing-to-ibmvtpm_reset_crq.patch w1_therm-reference-count-family-data.patch xfs-don-t-truncate-attribute-extents-if-no-extents-exist.patch xfs-fix-remote-symlinks-on-v5-crc-filesystems.patch --- diff --git a/queue-4.1/series b/queue-4.1/series index c851bfbe4fb..dc8bffa20bf 100644 --- a/queue-4.1/series +++ b/queue-4.1/series @@ -162,3 +162,10 @@ drm-add-a-check-for-x-y-in-drm_mode_setcrtc.patch drm-provide-compat-ioctl-for-addfb2.1.patch drm-stop-resetting-connector-state-to-unknown.patch libata-fix-regression-when-the-ncq-send-and-receive-log-page-is-absent.patch +xfs-fix-remote-symlinks-on-v5-crc-filesystems.patch +xfs-don-t-truncate-attribute-extents-if-no-extents-exist.patch +w1_therm-reference-count-family-data.patch +tpm-tpm_crb-fix-le64_to_cpu-conversions-in-crb_acpi_add.patch +vtpm-set-virtual-device-before-passing-to-ibmvtpm_reset_crq.patch +tpm-fix-initialization-of-the-cdev.patch +tpm-tpm_crb-fail-when-tpm2-acpi-table-contents-look-corrupted.patch diff --git a/queue-4.1/tpm-fix-initialization-of-the-cdev.patch b/queue-4.1/tpm-fix-initialization-of-the-cdev.patch new file mode 100644 index 00000000000..43b84fa1952 --- /dev/null +++ b/queue-4.1/tpm-fix-initialization-of-the-cdev.patch @@ -0,0 +1,41 @@ +From ba0ef85479c46a2ab354c2220bdb6152f7f4baf3 Mon Sep 17 00:00:00 2001 +From: Jason Gunthorpe +Date: Tue, 30 Jun 2015 13:15:31 -0600 +Subject: tpm: Fix initialization of the cdev + +From: Jason Gunthorpe + +commit ba0ef85479c46a2ab354c2220bdb6152f7f4baf3 upstream. + +When a cdev is contained in a dynamic structure the cdev parent kobj +should be set to the kobj that controls the lifetime of the enclosing +structure. In TPM's case this is the embedded struct device. + +Also, cdev_init 0's the whole structure, so all sets must be after, +not before. This fixes module ref counting and cdev. + +Fixes: 313d21eeab92 ("tpm: device class for tpm") +Signed-off-by: Jason Gunthorpe +Reviewed-by: Dmitry Torokhov +Reviewed-by: Jarkko Sakkinen +Tested-by: Jarkko Sakkinen +Signed-off-by: Peter Huewe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/tpm/tpm-chip.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/char/tpm/tpm-chip.c ++++ b/drivers/char/tpm/tpm-chip.c +@@ -129,8 +129,9 @@ struct tpm_chip *tpmm_chip_alloc(struct + + device_initialize(&chip->dev); + +- chip->cdev.owner = chip->pdev->driver->owner; + cdev_init(&chip->cdev, &tpm_fops); ++ chip->cdev.owner = chip->pdev->driver->owner; ++ chip->cdev.kobj.parent = &chip->dev.kobj; + + return chip; + } diff --git a/queue-4.1/tpm-tpm_crb-fail-when-tpm2-acpi-table-contents-look-corrupted.patch b/queue-4.1/tpm-tpm_crb-fail-when-tpm2-acpi-table-contents-look-corrupted.patch new file mode 100644 index 00000000000..d1020f00501 --- /dev/null +++ b/queue-4.1/tpm-tpm_crb-fail-when-tpm2-acpi-table-contents-look-corrupted.patch @@ -0,0 +1,42 @@ +From b371616b8537d6450ebca0819defbf53452bebf3 Mon Sep 17 00:00:00 2001 +From: Jarkko Sakkinen +Date: Wed, 24 Jun 2015 17:14:55 +0300 +Subject: tpm, tpm_crb: fail when TPM2 ACPI table contents look corrupted + +From: Jarkko Sakkinen + +commit b371616b8537d6450ebca0819defbf53452bebf3 upstream. + +At least some versions of AMI BIOS have corrupted contents in the TPM2 +ACPI table and namely the physical address of the control area is set to +zero. + +This patch changes the driver to fail gracefully when we observe a zero +address instead of continuing to ioremap. + +Signed-off-by: Jarkko Sakkinen +Reviewed-by: Peter Huewe +Signed-off-by: Peter Huewe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/tpm/tpm_crb.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/char/tpm/tpm_crb.c ++++ b/drivers/char/tpm/tpm_crb.c +@@ -233,6 +233,14 @@ static int crb_acpi_add(struct acpi_devi + return -ENODEV; + } + ++ /* At least some versions of AMI BIOS have a bug that TPM2 table has ++ * zero address for the control area and therefore we must fail. ++ */ ++ if (!buf->control_area_pa) { ++ dev_err(dev, "TPM2 ACPI table has a zero address for the control area\n"); ++ return -EINVAL; ++ } ++ + if (buf->hdr.length < sizeof(struct acpi_tpm2)) { + dev_err(dev, "TPM2 ACPI table has wrong size"); + return -EINVAL; diff --git a/queue-4.1/tpm-tpm_crb-fix-le64_to_cpu-conversions-in-crb_acpi_add.patch b/queue-4.1/tpm-tpm_crb-fix-le64_to_cpu-conversions-in-crb_acpi_add.patch new file mode 100644 index 00000000000..56d2846c2b1 --- /dev/null +++ b/queue-4.1/tpm-tpm_crb-fix-le64_to_cpu-conversions-in-crb_acpi_add.patch @@ -0,0 +1,44 @@ +From 49afd7289bd937401c5f7faa193054bc3c41dad6 Mon Sep 17 00:00:00 2001 +From: Jarkko Sakkinen +Date: Tue, 9 Jun 2015 15:07:59 +0300 +Subject: tpm, tpm_crb: fix le64_to_cpu conversions in crb_acpi_add() + +From: Jarkko Sakkinen + +commit 49afd7289bd937401c5f7faa193054bc3c41dad6 upstream. + +le64_to_cpu() was applied twice to the physical addresses read from the +control area. This hasn't shown any visible regressions because CRB +driver has been tested only on the little endian platofrms so far. + +Reported-by: Matt Fleming +Signed-off-by: Jarkko Sakkinen +Reviewed-By: Jason Gunthorpe +Fixes: 30fc8d138e91 ("tpm: TPM 2.0 CRB Interface") +Signed-off-by: Peter Huewe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/tpm/tpm_crb.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/char/tpm/tpm_crb.c ++++ b/drivers/char/tpm/tpm_crb.c +@@ -267,7 +267,7 @@ static int crb_acpi_add(struct acpi_devi + + memcpy_fromio(&pa, &priv->cca->cmd_pa, 8); + pa = le64_to_cpu(pa); +- priv->cmd = devm_ioremap_nocache(dev, le64_to_cpu(pa), ++ priv->cmd = devm_ioremap_nocache(dev, pa, + ioread32(&priv->cca->cmd_size)); + if (!priv->cmd) { + dev_err(dev, "ioremap of the command buffer failed\n"); +@@ -276,7 +276,7 @@ static int crb_acpi_add(struct acpi_devi + + memcpy_fromio(&pa, &priv->cca->rsp_pa, 8); + pa = le64_to_cpu(pa); +- priv->rsp = devm_ioremap_nocache(dev, le64_to_cpu(pa), ++ priv->rsp = devm_ioremap_nocache(dev, pa, + ioread32(&priv->cca->rsp_size)); + if (!priv->rsp) { + dev_err(dev, "ioremap of the response buffer failed\n"); diff --git a/queue-4.1/vtpm-set-virtual-device-before-passing-to-ibmvtpm_reset_crq.patch b/queue-4.1/vtpm-set-virtual-device-before-passing-to-ibmvtpm_reset_crq.patch new file mode 100644 index 00000000000..5207c5ab500 --- /dev/null +++ b/queue-4.1/vtpm-set-virtual-device-before-passing-to-ibmvtpm_reset_crq.patch @@ -0,0 +1,45 @@ +From 9d75f08946e8485109458ccf16f714697c207f41 Mon Sep 17 00:00:00 2001 +From: "Hon Ching \\(Vicky\\) Lo" +Date: Fri, 22 May 2015 13:23:02 -0400 +Subject: vTPM: set virtual device before passing to ibmvtpm_reset_crq + +From: "Hon Ching \\(Vicky\\) Lo" + +commit 9d75f08946e8485109458ccf16f714697c207f41 upstream. + +tpm_ibmvtpm_probe() calls ibmvtpm_reset_crq(ibmvtpm) without having yet +set the virtual device in the ibmvtpm structure. So in ibmvtpm_reset_crq, +the phype call contains empty unit addresses, ibmvtpm->vdev->unit_address. + +Signed-off-by: Hon Ching(Vicky) Lo +Signed-off-by: Joy Latten +Reviewed-by: Ashley Lai +Fixes: 132f76294744 ("drivers/char/tpm: Add new device driver to support IBM vTPM") +Signed-off-by: Peter Huewe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/tpm/tpm_ibmvtpm.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/char/tpm/tpm_ibmvtpm.c ++++ b/drivers/char/tpm/tpm_ibmvtpm.c +@@ -578,6 +578,9 @@ static int tpm_ibmvtpm_probe(struct vio_ + goto cleanup; + } + ++ ibmvtpm->dev = dev; ++ ibmvtpm->vdev = vio_dev; ++ + crq_q = &ibmvtpm->crq_queue; + crq_q->crq_addr = (struct ibmvtpm_crq *)get_zeroed_page(GFP_KERNEL); + if (!crq_q->crq_addr) { +@@ -622,8 +625,6 @@ static int tpm_ibmvtpm_probe(struct vio_ + + crq_q->index = 0; + +- ibmvtpm->dev = dev; +- ibmvtpm->vdev = vio_dev; + TPM_VPRIV(chip) = (void *)ibmvtpm; + + spin_lock_init(&ibmvtpm->rtce_lock); diff --git a/queue-4.1/w1_therm-reference-count-family-data.patch b/queue-4.1/w1_therm-reference-count-family-data.patch new file mode 100644 index 00000000000..b088e247aff --- /dev/null +++ b/queue-4.1/w1_therm-reference-count-family-data.patch @@ -0,0 +1,144 @@ +From f7134eea05b2fb4a2c0935f8a540539fff01f3eb Mon Sep 17 00:00:00 2001 +From: David Fries +Date: Fri, 8 May 2015 19:51:50 -0500 +Subject: w1_therm reference count family data + +From: David Fries + +commit f7134eea05b2fb4a2c0935f8a540539fff01f3eb upstream. + +A temperature conversion can take 750 ms and when possible the +w1_therm slave driver drops the bus_mutex to allow other bus +operations, but that includes operations such as a periodic slave +search, which can remove this slave when it is no longer detected. +If that happens the sl->family_data will be freed and set to NULL +causing w1_slave_show to crash when it wakes up. + +Signed-off-by: David Fries +Reported-By: Thorsten Bschorr +Tested-by: Thorsten Bschorr +Acked-by: Evgeniy Polyakov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/w1/slaves/w1_therm.c | 62 ++++++++++++++++++++++++++++++++----------- + 1 file changed, 47 insertions(+), 15 deletions(-) + +--- a/drivers/w1/slaves/w1_therm.c ++++ b/drivers/w1/slaves/w1_therm.c +@@ -59,16 +59,32 @@ MODULE_ALIAS("w1-family-" __stringify(W1 + static int w1_strong_pullup = 1; + module_param_named(strong_pullup, w1_strong_pullup, int, 0); + ++struct w1_therm_family_data { ++ uint8_t rom[9]; ++ atomic_t refcnt; ++}; ++ ++/* return the address of the refcnt in the family data */ ++#define THERM_REFCNT(family_data) \ ++ (&((struct w1_therm_family_data*)family_data)->refcnt) ++ + static int w1_therm_add_slave(struct w1_slave *sl) + { +- sl->family_data = kzalloc(9, GFP_KERNEL); ++ sl->family_data = kzalloc(sizeof(struct w1_therm_family_data), ++ GFP_KERNEL); + if (!sl->family_data) + return -ENOMEM; ++ atomic_set(THERM_REFCNT(sl->family_data), 1); + return 0; + } + + static void w1_therm_remove_slave(struct w1_slave *sl) + { ++ int refcnt = atomic_sub_return(1, THERM_REFCNT(sl->family_data)); ++ while(refcnt) { ++ msleep(1000); ++ refcnt = atomic_read(THERM_REFCNT(sl->family_data)); ++ } + kfree(sl->family_data); + sl->family_data = NULL; + } +@@ -194,13 +210,22 @@ static ssize_t w1_slave_show(struct devi + struct w1_slave *sl = dev_to_w1_slave(device); + struct w1_master *dev = sl->master; + u8 rom[9], crc, verdict, external_power; +- int i, max_trying = 10; ++ int i, ret, max_trying = 10; + ssize_t c = PAGE_SIZE; ++ u8 *family_data = sl->family_data; ++ ++ ret = mutex_lock_interruptible(&dev->bus_mutex); ++ if (ret != 0) ++ goto post_unlock; + +- i = mutex_lock_interruptible(&dev->bus_mutex); +- if (i != 0) +- return i; ++ if(!sl->family_data) ++ { ++ ret = -ENODEV; ++ goto pre_unlock; ++ } + ++ /* prevent the slave from going away in sleep */ ++ atomic_inc(THERM_REFCNT(family_data)); + memset(rom, 0, sizeof(rom)); + + while (max_trying--) { +@@ -230,17 +255,19 @@ static ssize_t w1_slave_show(struct devi + mutex_unlock(&dev->bus_mutex); + + sleep_rem = msleep_interruptible(tm); +- if (sleep_rem != 0) +- return -EINTR; ++ if (sleep_rem != 0) { ++ ret = -EINTR; ++ goto post_unlock; ++ } + +- i = mutex_lock_interruptible(&dev->bus_mutex); +- if (i != 0) +- return i; ++ ret = mutex_lock_interruptible(&dev->bus_mutex); ++ if (ret != 0) ++ goto post_unlock; + } else if (!w1_strong_pullup) { + sleep_rem = msleep_interruptible(tm); + if (sleep_rem != 0) { +- mutex_unlock(&dev->bus_mutex); +- return -EINTR; ++ ret = -EINTR; ++ goto pre_unlock; + } + } + +@@ -269,19 +296,24 @@ static ssize_t w1_slave_show(struct devi + c -= snprintf(buf + PAGE_SIZE - c, c, ": crc=%02x %s\n", + crc, (verdict) ? "YES" : "NO"); + if (verdict) +- memcpy(sl->family_data, rom, sizeof(rom)); ++ memcpy(family_data, rom, sizeof(rom)); + else + dev_warn(device, "Read failed CRC check\n"); + + for (i = 0; i < 9; ++i) + c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", +- ((u8 *)sl->family_data)[i]); ++ ((u8 *)family_data)[i]); + + c -= snprintf(buf + PAGE_SIZE - c, c, "t=%d\n", + w1_convert_temp(rom, sl->family->fid)); ++ ret = PAGE_SIZE - c; ++ ++pre_unlock: + mutex_unlock(&dev->bus_mutex); + +- return PAGE_SIZE - c; ++post_unlock: ++ atomic_dec(THERM_REFCNT(family_data)); ++ return ret; + } + + static int __init w1_therm_init(void) diff --git a/queue-4.1/xfs-don-t-truncate-attribute-extents-if-no-extents-exist.patch b/queue-4.1/xfs-don-t-truncate-attribute-extents-if-no-extents-exist.patch new file mode 100644 index 00000000000..4aa130a3b15 --- /dev/null +++ b/queue-4.1/xfs-don-t-truncate-attribute-extents-if-no-extents-exist.patch @@ -0,0 +1,63 @@ +From f66bf042693b620133d39af8d2f13615f03eadfc Mon Sep 17 00:00:00 2001 +From: Brian Foster +Date: Tue, 23 Jun 2015 08:47:20 +1000 +Subject: xfs: don't truncate attribute extents if no extents exist + +From: Brian Foster + +commit f66bf042693b620133d39af8d2f13615f03eadfc upstream. + +The xfs_attr3_root_inactive() call from xfs_attr_inactive() assumes that +attribute blocks exist to invalidate. It is possible to have an +attribute fork without extents, however. Consider the case where the +attribute fork is created towards the beginning of xfs_attr_set() but +some part of the subsequent attribute set fails. + +If an inode in such a state hits xfs_attr_inactive(), it eventually +calls xfs_dabuf_map() and possibly xfs_bmapi_read(). The former emits a +filesystem corruption warning, returns an error that bubbles back up to +xfs_attr_inactive(), and leads to destruction of the in-core attribute +fork without an on-disk reset. If the inode happens to make it back +through xfs_inactive() in this state (e.g., via a concurrent bulkstat +that cycles the inode from the reclaim state and releases it), i_afp +might not exist when xfs_bmapi_read() is called and causes a NULL +dereference panic. + +A '-p 2' fsstress run to ENOSPC on a relatively small fs (1GB) +reproduces these problems. The behavior is a regression caused by: + +6dfe5a0 xfs: xfs_attr_inactive leaves inconsistent attr fork state behind + +... which removed logic that avoided the attribute extent truncate when +no extents exist. Restore this logic to ensure the attribute fork is +destroyed and reset correctly if it exists without any allocated +extents. + +Signed-off-by: Brian Foster +Reviewed-by: Dave Chinner +Signed-off-by: Dave Chinner +Signed-off-by: Greg Kroah-Hartman + +--- + fs/xfs/xfs_attr_inactive.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/fs/xfs/xfs_attr_inactive.c ++++ b/fs/xfs/xfs_attr_inactive.c +@@ -435,8 +435,14 @@ xfs_attr_inactive( + */ + xfs_trans_ijoin(trans, dp, 0); + +- /* invalidate and truncate the attribute fork extents */ +- if (dp->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) { ++ /* ++ * Invalidate and truncate the attribute fork extents. Make sure the ++ * fork actually has attributes as otherwise the invalidation has no ++ * blocks to read and returns an error. In this case, just do the fork ++ * removal below. ++ */ ++ if (xfs_inode_hasattr(dp) && ++ dp->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) { + error = xfs_attr3_root_inactive(&trans, dp); + if (error) + goto out_cancel; diff --git a/queue-4.1/xfs-fix-remote-symlinks-on-v5-crc-filesystems.patch b/queue-4.1/xfs-fix-remote-symlinks-on-v5-crc-filesystems.patch new file mode 100644 index 00000000000..10aba64ba37 --- /dev/null +++ b/queue-4.1/xfs-fix-remote-symlinks-on-v5-crc-filesystems.patch @@ -0,0 +1,49 @@ +From 2ac56d3d4bd625450a54d4c3f9292d58f6b88232 Mon Sep 17 00:00:00 2001 +From: Eric Sandeen +Date: Mon, 22 Jun 2015 09:42:48 +1000 +Subject: xfs: fix remote symlinks on V5/CRC filesystems + +From: Eric Sandeen + +commit 2ac56d3d4bd625450a54d4c3f9292d58f6b88232 upstream. + +If we create a CRC filesystem, mount it, and create a symlink with +a path long enough that it can't live in the inode, we get a very +strange result upon remount: + +# ls -l mnt +total 4 +lrwxrwxrwx. 1 root root 929 Jun 15 16:58 link -> XSLM + +XSLM is the V5 symlink block header magic (which happens to be +followed by a NUL, so the string looks terminated). + +xfs_readlink_bmap() advanced cur_chunk by the size of the header +for CRC filesystems, but never actually used that pointer; it +kept reading from bp->b_addr, which is the start of the block, +rather than the start of the symlink data after the header. + +Looks like this problem goes back to v3.10. + +Fixing this gets us reading the proper link target, again. + +Signed-off-by: Eric Sandeen +Reviewed-by: Dave Chinner +Signed-off-by: Dave Chinner +Signed-off-by: Greg Kroah-Hartman + +--- + fs/xfs/xfs_symlink.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/xfs/xfs_symlink.c ++++ b/fs/xfs/xfs_symlink.c +@@ -104,7 +104,7 @@ xfs_readlink_bmap( + cur_chunk += sizeof(struct xfs_dsymlink_hdr); + } + +- memcpy(link + offset, bp->b_addr, byte_cnt); ++ memcpy(link + offset, cur_chunk, byte_cnt); + + pathlen -= byte_cnt; + offset += byte_cnt;