From: James Bottomley <James.Bottomley(a)HansenPartnership.com>
BugLink: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1881710
It has been reported that some TIS based TPMs are giving unexpected
errors when using the O_NONBLOCK path of the TPM device. The problem
is that some TPMs don't like it when you get and then relinquish a
locality (as the tpm_try_get_ops()/tpm_put_ops() pair does) without
sending a command. This currently happens all the time in the
O_NONBLOCK write path. Fix this by moving the tpm_try_get_ops()
further down the code to after the O_NONBLOCK determination is made.
This is safe because the priv->buffer_mutex still protects the priv
state being modified.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=206275
Fixes: d23d12484307 ("tpm: fix invalid locking in NONBLOCKING mode")
Reported-by: Mario Limonciello <Mario.Limonciello(a)dell.com>
Tested-by: Alex Guzman <alex(a)guzman.io>
Cc: stable(a)vger.kernel.org
Reviewed-by: Jerry Snitselaar <jsnitsel(a)redhat.com>
Signed-off-by: James Bottomley <James.Bottomley(a)HansenPartnership.com>
Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen(a)linux.intel.com>
(cherry picked from https://patchwork.kernel.org/patch/11576453/)
Signed-off-by: Ivan Hu <ivan.hu(a)canonical.com>
---
drivers/char/tpm/tpm-dev-common.c | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/drivers/char/tpm/tpm-dev-common.c b/drivers/char/tpm/tpm-dev-common.c
index 87f449340202..1784530b8387 100644
--- a/drivers/char/tpm/tpm-dev-common.c
+++ b/drivers/char/tpm/tpm-dev-common.c
@@ -189,15 +189,6 @@ ssize_t tpm_common_write(struct file *file, const char __user *buf,
goto out;
}
- /* atomic tpm command send and result receive. We only hold the ops
- * lock during this period so that the tpm can be unregistered even if
- * the char dev is held open.
- */
- if (tpm_try_get_ops(priv->chip)) {
- ret = -EPIPE;
- goto out;
- }
-
priv->response_length = 0;
priv->response_read = false;
*off = 0;
@@ -211,11 +202,19 @@ ssize_t tpm_common_write(struct file *file, const char __user *buf,
if (file->f_flags & O_NONBLOCK) {
priv->command_enqueued = true;
queue_work(tpm_dev_wq, &priv->async_work);
- tpm_put_ops(priv->chip);
mutex_unlock(&priv->buffer_mutex);
return size;
}
+ /* atomic tpm command send and result receive. We only hold the ops
+ * lock during this period so that the tpm can be unregistered even if
+ * the char dev is held open.
+ */
+ if (tpm_try_get_ops(priv->chip)) {
+ ret = -EPIPE;
+ goto out;
+ }
+
ret = tpm_dev_transmit(priv->chip, priv->space, priv->data_buffer,
sizeof(priv->data_buffer));
tpm_put_ops(priv->chip);
--
2.17.1
From: James Bottomley <James.Bottomley(a)HansenPartnership.com>
BugLink: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1881710
It has been reported that some TIS based TPMs are giving unexpected
errors when using the O_NONBLOCK path of the TPM device. The problem
is that some TPMs don't like it when you get and then relinquish a
locality (as the tpm_try_get_ops()/tpm_put_ops() pair does) without
sending a command. This currently happens all the time in the
O_NONBLOCK write path. Fix this by moving the tpm_try_get_ops()
further down the code to after the O_NONBLOCK determination is made.
This is safe because the priv->buffer_mutex still protects the priv
state being modified.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=206275
Fixes: d23d12484307 ("tpm: fix invalid locking in NONBLOCKING mode")
Reported-by: Mario Limonciello <Mario.Limonciello(a)dell.com>
Tested-by: Alex Guzman <alex(a)guzman.io>
Cc: stable(a)vger.kernel.org
Reviewed-by: Jerry Snitselaar <jsnitsel(a)redhat.com>
Signed-off-by: James Bottomley <James.Bottomley(a)HansenPartnership.com>
Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen(a)linux.intel.com>
(backported from https://patchwork.kernel.org/patch/11576453/)
Signed-off-by: Ivan Hu <ivan.hu(a)canonical.com>
---
drivers/char/tpm/tpm-dev-common.c | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/drivers/char/tpm/tpm-dev-common.c b/drivers/char/tpm/tpm-dev-common.c
index 10b9f63701e6..de55205d3a11 100644
--- a/drivers/char/tpm/tpm-dev-common.c
+++ b/drivers/char/tpm/tpm-dev-common.c
@@ -164,15 +164,6 @@ ssize_t tpm_common_write(struct file *file, const char __user *buf,
goto out;
}
- /* atomic tpm command send and result receive. We only hold the ops
- * lock during this period so that the tpm can be unregistered even if
- * the char dev is held open.
- */
- if (tpm_try_get_ops(priv->chip)) {
- ret = -EPIPE;
- goto out;
- }
-
priv->response_length = 0;
priv->response_read = false;
*off = 0;
@@ -186,11 +177,19 @@ ssize_t tpm_common_write(struct file *file, const char __user *buf,
if (file->f_flags & O_NONBLOCK) {
priv->command_enqueued = true;
queue_work(tpm_dev_wq, &priv->async_work);
- tpm_put_ops(priv->chip);
mutex_unlock(&priv->buffer_mutex);
return size;
}
+ /* atomic tpm command send and result receive. We only hold the ops
+ * lock during this period so that the tpm can be unregistered even if
+ * the char dev is held open.
+ */
+ if (tpm_try_get_ops(priv->chip)) {
+ ret = -EPIPE;
+ goto out;
+ }
+
ret = tpm_transmit(priv->chip, priv->space, priv->data_buffer,
sizeof(priv->data_buffer), 0);
tpm_put_ops(priv->chip);
--
2.17.1
Before commit cfc4c189bc70 ("pwm: Read initial hardware state at request
time"), a driver's get_state callback would get called once per PWM from
pwmchip_add().
pwm-lpss' runtime-pm code was relying on this, getting a runtime-pm ref for
PWMs which are enabled at probe time from within its get_state callback,
before enabling runtime-pm.
The change to calling get_state at request time causes a number of
problems:
1. PWMs enabled at probe time may get runtime suspended before they are
requested, causing e.g. a LCD backlight controlled by the PWM to turn off.
2. When the request happens when the PWM has been runtime suspended, the
ctrl register will read all 1 / 0xffffffff, causing get_state to store
bogus values in the pwm_state.
3. get_state was using an async pm_runtime_get() call, because it assumed
that runtime-pm has not been enabled yet. If shortly after the request an
apply call is made, then the pwm_lpss_is_updating() check may trigger
because the resume triggered by the pm_runtime_get() call is not complete
yet, so the ctrl register still reads all 1 / 0xffffffff.
This commit fixes these issues by moving the initial pm_runtime_get() call
for PWMs which are enabled at probe time to the pwm_lpss_probe() function;
and by making get_state take a runtime-pm ref before reading the ctrl reg.
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1828927
Fixes: cfc4c189bc70 ("pwm: Read initial hardware state at request time")
Cc: stable(a)vger.kernel.org
Signed-off-by: Hans de Goede <hdegoede(a)redhat.com>
---
drivers/pwm/pwm-lpss.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/pwm/pwm-lpss.c b/drivers/pwm/pwm-lpss.c
index 75bbfe5f3bc2..9d965ffe66d1 100644
--- a/drivers/pwm/pwm-lpss.c
+++ b/drivers/pwm/pwm-lpss.c
@@ -158,7 +158,6 @@ static int pwm_lpss_apply(struct pwm_chip *chip, struct pwm_device *pwm,
return 0;
}
-/* This function gets called once from pwmchip_add to get the initial state */
static void pwm_lpss_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
struct pwm_state *state)
{
@@ -167,6 +166,8 @@ static void pwm_lpss_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
unsigned long long base_unit, freq, on_time_div;
u32 ctrl;
+ pm_runtime_get_sync(chip->dev);
+
base_unit_range = BIT(lpwm->info->base_unit_bits);
ctrl = pwm_lpss_read(pwm);
@@ -187,8 +188,7 @@ static void pwm_lpss_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
state->polarity = PWM_POLARITY_NORMAL;
state->enabled = !!(ctrl & PWM_ENABLE);
- if (state->enabled)
- pm_runtime_get(chip->dev);
+ pm_runtime_put(chip->dev);
}
static const struct pwm_ops pwm_lpss_ops = {
@@ -202,7 +202,8 @@ struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r,
{
struct pwm_lpss_chip *lpwm;
unsigned long c;
- int ret;
+ int i, ret;
+ u32 ctrl;
if (WARN_ON(info->npwm > MAX_PWMS))
return ERR_PTR(-ENODEV);
@@ -232,6 +233,12 @@ struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r,
return ERR_PTR(ret);
}
+ for (i = 0; i < lpwm->info->npwm; i++) {
+ ctrl = pwm_lpss_read(&lpwm->chip.pwms[i]);
+ if (ctrl & PWM_ENABLE)
+ pm_runtime_get(dev);
+ }
+
return lpwm;
}
EXPORT_SYMBOL_GPL(pwm_lpss_probe);
--
2.26.0
This is the start of the stable review cycle for the 4.4.226 release.
There are 48 patches in this series, all will be posted as a response
to this one. If anyone has any issues with these being applied, please
let me know.
Responses should be made by Wed, 03 Jun 2020 17:38:19 +0000.
Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.226-rc…
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.4.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Linux 4.4.226-rc1
Ben Hutchings <ben.hutchings(a)codethink.co.uk>
drm/msm: Fix possible null dereference on failure of get_pages()
Guoqing Jiang <gqjiang(a)suse.com>
sc16is7xx: move label 'err_spi' to correct section
Michal Marek <mmarek(a)suse.com>
asm-prototypes: Clear any CPP defines before declaring the functions
Liviu Dudau <liviu(a)dudau.co.uk>
mm/vmalloc.c: don't dereference possible NULL pointer in __vunmap()
Roopa Prabhu <roopa(a)cumulusnetworks.com>
net: rtnl_configure_link: fix dev flags changes arg to __dev_notify_flags
Sudip Mukherjee <sudip(a)vectorindia.org>
mac80211: fix memory leak
Yoshihiro Shimoda <yoshihiro.shimoda.uh(a)renesas.com>
usb: renesas_usbhs: gadget: fix spin_lock_init() for &uep->lock
Thomas Gleixner <tglx(a)linutronix.de>
genirq/generic_pending: Do not lose pending affinity update
Matt Roper <matthew.d.roper(a)intel.com>
drm/fb-helper: Use proper plane mask for fb cleanup
Konstantin Khlebnikov <khlebnikov(a)yandex-team.ru>
mm: remove VM_BUG_ON(PageSlab()) from page_mapcount()
Pablo Neira Ayuso <pablo(a)netfilter.org>
netfilter: nf_conntrack_pptp: fix compilation warning with W=1 build
Dmitry Torokhov <dmitry.torokhov(a)gmail.com>
Revert "Input: i8042 - add ThinkPad S230u to i8042 nomux list"
Qiushi Wu <wu000273(a)umn.edu>
bonding: Fix reference count leak in bond_sysfs_slave_add.
Qiushi Wu <wu000273(a)umn.edu>
qlcnic: fix missing release in qlcnic_83xx_interrupt_test.
Pablo Neira Ayuso <pablo(a)netfilter.org>
netfilter: nf_conntrack_pptp: prevent buffer overflows in debug code
Phil Sutter <phil(a)nwl.cc>
netfilter: ipset: Fix subcounter update skip
Michael Braun <michael-dev(a)fami-braun.de>
netfilter: nft_reject_bridge: enable reject with bridge vlan
Xin Long <lucien.xin(a)gmail.com>
ip_vti: receive ipip packet by calling ip_tunnel_rcv
Jeremy Sowden <jeremy(a)azazel.net>
vti4: eliminated some duplicate code.
Xin Long <lucien.xin(a)gmail.com>
xfrm: fix a NULL-ptr deref in xfrm_local_error
Xin Long <lucien.xin(a)gmail.com>
xfrm: fix a warning in xfrm_policy_insert_list
Xin Long <lucien.xin(a)gmail.com>
xfrm: allow to accept packets with ipv6 NEXTHDR_HOP in xfrm_input
Alexander Dahl <post(a)lespocky.de>
x86/dma: Fix max PFN arithmetic overflow on 32 bit systems
Helge Deller <deller(a)gmx.de>
parisc: Fix kernel panic in mem_init()
Qiushi Wu <wu000273(a)umn.edu>
iommu: Fix reference count leak in iommu_group_alloc.
Arnd Bergmann <arnd(a)arndb.de>
include/asm-generic/topology.h: guard cpumask_of_node() macro argument
Alexander Potapenko <glider(a)google.com>
fs/binfmt_elf.c: allocate initialized memory in fill_thread_core_info()
Eric W. Biederman <ebiederm(a)xmission.com>
exec: Always set cap_ambient in cap_bprm_set_creds
Chris Chiu <chiu(a)endlessm.com>
ALSA: usb-audio: mixer: volume quirk for ESS Technology Asus USB DAC
Changming Liu <liu.changm(a)northeastern.edu>
ALSA: hwdep: fix a left shifting 1 by 31 UB bug
Kaike Wan <kaike.wan(a)intel.com>
IB/qib: Call kobject_put() when kobject_init_and_add() fails
Kevin Locke <kevin(a)kevinlocke.name>
Input: i8042 - add ThinkPad S230u to i8042 reset list
Łukasz Patron <priv.luk(a)gmail.com>
Input: xpad - add custom init packet for Xbox One S controllers
Brendan Shanks <bshanks(a)codeweavers.com>
Input: evdev - call input_flush_device() on release(), not flush()
Kevin Locke <kevin(a)kevinlocke.name>
Input: i8042 - add ThinkPad S230u to i8042 nomux list
James Hilliard <james.hilliard1(a)gmail.com>
Input: usbtouchscreen - add support for BonXeon TP
Steve French <stfrench(a)microsoft.com>
cifs: Fix null pointer check in cifs_read
Masahiro Yamada <masahiroy(a)kernel.org>
usb: gadget: legacy: fix redundant initialization warnings
Lei Xue <carmark.dlut(a)gmail.com>
cachefiles: Fix race between read_waiter and read_copier involving op->to_do
Bob Peterson <rpeterso(a)redhat.com>
gfs2: don't call quota_unhold if quotas are not locked
Kalderon, Michal <Michal.Kalderon(a)cavium.com>
IB/cma: Fix reference count leak when no ipv4 addresses are set
Dmitry V. Levin <ldv(a)altlinux.org>
uapi: fix linux/if_pppol2tp.h userspace compilation errors
Qiushi Wu <wu000273(a)umn.edu>
net/mlx4_core: fix a memory leak bug.
Qiushi Wu <wu000273(a)umn.edu>
net: sun: fix missing release regions in cas_init_one().
Moshe Shemesh <moshe(a)mellanox.com>
net/mlx5: Add command entry handling completion
Jere Leppänen <jere.leppanen(a)nokia.com>
sctp: Start shutdown on association restart if in SHUTDOWN-SENT state and socket is closed
Yuqi Jin <jinyuqi(a)huawei.com>
net: revert "net: get rid of an signed integer overflow in ip_idents_reserve()"
Eric Dumazet <edumazet(a)google.com>
ax25: fix setsockopt(SO_BINDTODEVICE)
-------------
Diffstat:
Makefile | 4 +-
arch/parisc/mm/init.c | 2 +-
arch/x86/include/asm/dma.h | 2 +-
drivers/gpu/drm/drm_fb_helper.c | 2 +-
drivers/gpu/drm/msm/msm_gem.c | 20 +++---
drivers/infiniband/hw/qib/qib_sysfs.c | 9 +--
drivers/input/evdev.c | 19 ++----
drivers/input/joystick/xpad.c | 12 ++++
drivers/input/serio/i8042-x86ia64io.h | 7 ++
drivers/input/touchscreen/usbtouchscreen.c | 1 +
drivers/iommu/iommu.c | 2 +-
drivers/net/bonding/bond_sysfs_slave.c | 4 +-
drivers/net/ethernet/mellanox/mlx4/fw.c | 2 +-
drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 15 +++++
.../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 4 +-
drivers/net/ethernet/sun/cassini.c | 3 +-
drivers/tty/serial/sc16is7xx.c | 2 +
drivers/usb/gadget/legacy/inode.c | 3 +-
drivers/usb/renesas_usbhs/mod_gadget.c | 2 +-
fs/binfmt_elf.c | 2 +-
fs/cachefiles/rdwr.c | 2 +-
fs/cifs/file.c | 2 +-
fs/gfs2/quota.c | 3 +-
include/asm-generic/asm-prototypes.h | 6 ++
include/asm-generic/topology.h | 2 +-
include/linux/mlx5/driver.h | 1 +
include/linux/mm.h | 1 -
include/linux/netfilter/nf_conntrack_pptp.h | 2 +-
include/rdma/ib_addr.h | 6 +-
include/uapi/linux/l2tp.h | 7 +-
kernel/irq/migration.c | 26 ++++++--
mm/vmalloc.c | 2 +-
net/ax25/af_ax25.c | 6 +-
net/bridge/netfilter/nft_reject_bridge.c | 6 ++
net/core/rtnetlink.c | 2 +-
net/ipv4/ip_vti.c | 75 ++++++++++++----------
net/ipv4/netfilter/nf_nat_pptp.c | 7 +-
net/ipv4/route.c | 14 ++--
net/mac80211/sta_info.c | 1 +
net/netfilter/ipset/ip_set_list_set.c | 2 +-
net/netfilter/nf_conntrack_pptp.c | 62 ++++++++++--------
net/sctp/sm_statefuns.c | 9 +--
net/xfrm/xfrm_input.c | 2 +-
net/xfrm/xfrm_output.c | 3 +-
net/xfrm/xfrm_policy.c | 7 +-
security/commoncap.c | 1 +
sound/core/hwdep.c | 4 +-
sound/usb/mixer.c | 8 +++
48 files changed, 229 insertions(+), 157 deletions(-)