Commit 48fd33b2 authored by Kylene Hall's avatar Kylene Hall Committed by Greg Kroah-Hartman

[PATCH] tpm: fix cause of SMP stack traces

There were misplaced spinlock acquires and releases in the probe, close and release
paths which were causing might_sleep and schedule while atomic error messages accompanied
by stack traces when the kernel was compiled with SMP support. Bug reported by Reben Jenster
<ruben@hotheads.de>
Signed-off-by: default avatarKylene Hall <kjhall@us.ibm.com>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent 4aea4047
......@@ -422,21 +422,24 @@ EXPORT_SYMBOL_GPL(tpm_open);
int tpm_release(struct inode *inode, struct file *file)
{
struct tpm_chip *chip = file->private_data;
file->private_data = NULL;
spin_lock(&driver_lock);
chip->num_opens--;
spin_unlock(&driver_lock);
down(&chip->timer_manipulation_mutex);
if (timer_pending(&chip->user_read_timer))
del_singleshot_timer_sync(&chip->user_read_timer);
else if (timer_pending(&chip->device_timer))
del_singleshot_timer_sync(&chip->device_timer);
up(&chip->timer_manipulation_mutex);
kfree(chip->data_buffer);
atomic_set(&chip->data_pending, 0);
pci_dev_put(chip->pci_dev);
file->private_data = NULL;
spin_unlock(&driver_lock);
return 0;
}
......@@ -534,6 +537,8 @@ void __devexit tpm_remove(struct pci_dev *pci_dev)
list_del(&chip->list);
spin_unlock(&driver_lock);
pci_set_drvdata(pci_dev, NULL);
misc_deregister(&chip->vendor->miscdev);
......@@ -541,8 +546,6 @@ void __devexit tpm_remove(struct pci_dev *pci_dev)
device_remove_file(&pci_dev->dev, &dev_attr_pcrs);
device_remove_file(&pci_dev->dev, &dev_attr_caps);
spin_unlock(&driver_lock);
pci_disable_device(pci_dev);
dev_mask[chip->dev_num / 32] &= !(1 << (chip->dev_num % 32));
......@@ -583,6 +586,7 @@ EXPORT_SYMBOL_GPL(tpm_pm_suspend);
int tpm_pm_resume(struct pci_dev *pci_dev)
{
struct tpm_chip *chip = pci_get_drvdata(pci_dev);
if (chip == NULL)
return -ENODEV;
......@@ -650,15 +654,12 @@ int tpm_register_hardware(struct pci_dev *pci_dev,
chip->vendor->miscdev.dev = &(pci_dev->dev);
chip->pci_dev = pci_dev_get(pci_dev);
spin_lock(&driver_lock);
if (misc_register(&chip->vendor->miscdev)) {
dev_err(&chip->pci_dev->dev,
"unable to misc_register %s, minor %d\n",
chip->vendor->miscdev.name,
chip->vendor->miscdev.minor);
pci_dev_put(pci_dev);
spin_unlock(&driver_lock);
kfree(chip);
dev_mask[i] &= !(1 << j);
return -ENODEV;
......@@ -672,7 +673,6 @@ int tpm_register_hardware(struct pci_dev *pci_dev,
device_create_file(&pci_dev->dev, &dev_attr_pcrs);
device_create_file(&pci_dev->dev, &dev_attr_caps);
spin_unlock(&driver_lock);
return 0;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment