diff options
author | Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> | 2016-04-11 07:20:57 -0400 |
---|---|---|
committer | Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> | 2016-06-25 10:26:35 -0400 |
commit | dcbeab194645486dc482b49b44ef5b8634153034 (patch) | |
tree | 120fa47c8681277704daaf071584922949df1cad | |
parent | d30b8e4f68ef182f8dd84c76af9f148ca5842ea3 (diff) |
tpm: fix crash in tpm_tis deinitialization
rmmod crashes the driver because tpm_chip_unregister() already sets ops
to NULL. This commit fixes the issue by moving tpm2_shutdown() to
tpm_chip_unregister(). This commit is also cleanup because it removes
duplicate code from tpm_crb and tpm_tis to the core.
Fixes: 4d3eac5e156a ("tpm: Provide strong locking for device removal")
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Reviewed-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
-rw-r--r-- | drivers/char/tpm/tpm-chip.c | 1 | ||||
-rw-r--r-- | drivers/char/tpm/tpm2-cmd.c | 1 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_crb.c | 3 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_tis.c | 3 |
4 files changed, 1 insertions, 7 deletions
diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index f62c8518cd68..5bc530ccbb86 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c | |||
@@ -269,6 +269,7 @@ static void tpm_del_char_device(struct tpm_chip *chip) | |||
269 | 269 | ||
270 | /* Make the driver uncallable. */ | 270 | /* Make the driver uncallable. */ |
271 | down_write(&chip->ops_sem); | 271 | down_write(&chip->ops_sem); |
272 | tpm2_shutdown(chip, TPM2_SU_CLEAR); | ||
272 | chip->ops = NULL; | 273 | chip->ops = NULL; |
273 | up_write(&chip->ops_sem); | 274 | up_write(&chip->ops_sem); |
274 | } | 275 | } |
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index 5fc0e7c64daa..e42266589ce6 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c | |||
@@ -773,7 +773,6 @@ void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type) | |||
773 | dev_warn(&chip->dev, "transmit returned %d while stopping the TPM", | 773 | dev_warn(&chip->dev, "transmit returned %d while stopping the TPM", |
774 | rc); | 774 | rc); |
775 | } | 775 | } |
776 | EXPORT_SYMBOL_GPL(tpm2_shutdown); | ||
777 | 776 | ||
778 | /* | 777 | /* |
779 | * tpm2_calc_ordinal_duration() - maximum duration for a command | 778 | * tpm2_calc_ordinal_duration() - maximum duration for a command |
diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c index a12b31940344..ec734de87b76 100644 --- a/drivers/char/tpm/tpm_crb.c +++ b/drivers/char/tpm/tpm_crb.c | |||
@@ -344,9 +344,6 @@ static int crb_acpi_remove(struct acpi_device *device) | |||
344 | struct device *dev = &device->dev; | 344 | struct device *dev = &device->dev; |
345 | struct tpm_chip *chip = dev_get_drvdata(dev); | 345 | struct tpm_chip *chip = dev_get_drvdata(dev); |
346 | 346 | ||
347 | if (chip->flags & TPM_CHIP_FLAG_TPM2) | ||
348 | tpm2_shutdown(chip, TPM2_SU_CLEAR); | ||
349 | |||
350 | tpm_chip_unregister(chip); | 347 | tpm_chip_unregister(chip); |
351 | 348 | ||
352 | return 0; | 349 | return 0; |
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 18236f66c084..0b0d44f9aaf2 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c | |||
@@ -653,9 +653,6 @@ static void tpm_tis_remove(struct tpm_chip *chip) | |||
653 | void __iomem *reg = chip->vendor.iobase + | 653 | void __iomem *reg = chip->vendor.iobase + |
654 | TPM_INT_ENABLE(chip->vendor.locality); | 654 | TPM_INT_ENABLE(chip->vendor.locality); |
655 | 655 | ||
656 | if (chip->flags & TPM_CHIP_FLAG_TPM2) | ||
657 | tpm2_shutdown(chip, TPM2_SU_CLEAR); | ||
658 | |||
659 | iowrite32(~TPM_GLOBAL_INT_ENABLE & ioread32(reg), reg); | 656 | iowrite32(~TPM_GLOBAL_INT_ENABLE & ioread32(reg), reg); |
660 | release_locality(chip, chip->vendor.locality, 1); | 657 | release_locality(chip, chip->vendor.locality, 1); |
661 | } | 658 | } |