summaryrefslogtreecommitdiff
path: root/drivers/char/tpm/tpm-sysfs.c
diff options
context:
space:
mode:
authorJason Gunthorpe <jgunthorpe@obsidianresearch.com>2016-02-13 03:29:53 (GMT)
committerJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>2016-06-25 14:26:35 (GMT)
commit4e26195f240d73150e8308ae42874702e3df8d2c (patch)
treec0e8ff3604b09484393d10a927ed1e9a46a7ed0d /drivers/char/tpm/tpm-sysfs.c
parent3635e2ec7cbb9aa054f8d4361dec27b0ca625905 (diff)
downloadlinux-4e26195f240d73150e8308ae42874702e3df8d2c.tar.xz
tpm: Provide strong locking for device removal
Add a read/write semaphore around the ops function pointers so ops can be set to null when the driver un-registers. Previously the tpm core expected module locking to be enough to ensure that tpm_unregister could not be called during certain times, however that hasn't been sufficient for a long time. Introduce a read/write semaphore around 'ops' so the core can set it to null when unregistering. This provides a strong fence around the driver callbacks, guaranteeing to the driver that no callbacks are running or will run again. For now the ops_lock is placed very high in the call stack, it could be pushed down and made more granular in future if necessary. Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Diffstat (limited to 'drivers/char/tpm/tpm-sysfs.c')
-rw-r--r--drivers/char/tpm/tpm-sysfs.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c
index d93736a..34e7fc7 100644
--- a/drivers/char/tpm/tpm-sysfs.c
+++ b/drivers/char/tpm/tpm-sysfs.c
@@ -295,5 +295,10 @@ int tpm_sysfs_add_device(struct tpm_chip *chip)
void tpm_sysfs_del_device(struct tpm_chip *chip)
{
+ /* The sysfs routines rely on an implicit tpm_try_get_ops, this
+ * function is called before ops is null'd and the sysfs core
+ * synchronizes this removal so that no callbacks are running or can
+ * run again
+ */
sysfs_remove_group(&chip->dev.parent->kobj, &tpm_dev_group);
}