Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 19913b6d authored by Jarkko Sakkinen's avatar Jarkko Sakkinen Committed by Peter Huewe
Browse files

tpm: fix call order in tpm-chip.c



- tpm_dev_add_device(): cdev_add() must be done before uevent is
  propagated in order to avoid races.
- tpm_chip_register(): tpm_dev_add_device() must be done as the
  last step before exposing device to the user space in order to
  avoid races.

In addition clarified description in tpm_chip_register().

Fixes: 313d21ee ("tpm: device class for tpm")
Fixes: afb5abc2 ("tpm: two-phase chip management functions")

Signed-off-by: default avatarJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Reviewed-by: default avatarPeter Huewe <peterhuewe@gmx.de>
Signed-off-by: default avatarPeter Huewe <peterhuewe@gmx.de>
parent 62dfd912
Loading
Loading
Loading
Loading
+14 −20
Original line number Original line Diff line number Diff line
@@ -140,24 +140,24 @@ static int tpm_dev_add_device(struct tpm_chip *chip)
{
{
	int rc;
	int rc;


	rc = device_add(&chip->dev);
	rc = cdev_add(&chip->cdev, chip->dev.devt, 1);
	if (rc) {
	if (rc) {
		dev_err(&chip->dev,
		dev_err(&chip->dev,
			"unable to device_register() %s, major %d, minor %d, err=%d\n",
			"unable to cdev_add() %s, major %d, minor %d, err=%d\n",
			chip->devname, MAJOR(chip->dev.devt),
			chip->devname, MAJOR(chip->dev.devt),
			MINOR(chip->dev.devt), rc);
			MINOR(chip->dev.devt), rc);


		device_unregister(&chip->dev);
		return rc;
		return rc;
	}
	}


	rc = cdev_add(&chip->cdev, chip->dev.devt, 1);
	rc = device_add(&chip->dev);
	if (rc) {
	if (rc) {
		dev_err(&chip->dev,
		dev_err(&chip->dev,
			"unable to cdev_add() %s, major %d, minor %d, err=%d\n",
			"unable to device_register() %s, major %d, minor %d, err=%d\n",
			chip->devname, MAJOR(chip->dev.devt),
			chip->devname, MAJOR(chip->dev.devt),
			MINOR(chip->dev.devt), rc);
			MINOR(chip->dev.devt), rc);


		device_unregister(&chip->dev);
		return rc;
		return rc;
	}
	}


@@ -174,27 +174,17 @@ static void tpm_dev_del_device(struct tpm_chip *chip)
 * tpm_chip_register() - create a character device for the TPM chip
 * tpm_chip_register() - create a character device for the TPM chip
 * @chip: TPM chip to use.
 * @chip: TPM chip to use.
 *
 *
 * Creates a character device for the TPM chip and adds sysfs interfaces for
 * Creates a character device for the TPM chip and adds sysfs attributes for
 * the device, PPI and TCPA. As the last step this function adds the
 * the device. As the last step this function adds the chip to the list of TPM
 * chip to the list of TPM chips available for use.
 * chips available for in-kernel use.
 *
 *
 * NOTE: This function should be only called after the chip initialization
 * This function should be only called after the chip initialization is
 * is complete.
 * complete.
 *
 * Called from tpm_<specific>.c probe function only for devices
 * the driver has determined it should claim.  Prior to calling
 * this function the specific probe function has called pci_enable_device
 * upon errant exit from this function specific probe function should call
 * pci_disable_device
 */
 */
int tpm_chip_register(struct tpm_chip *chip)
int tpm_chip_register(struct tpm_chip *chip)
{
{
	int rc;
	int rc;


	rc = tpm_dev_add_device(chip);
	if (rc)
		return rc;

	/* Populate sysfs for TPM1 devices. */
	/* Populate sysfs for TPM1 devices. */
	if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
	if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
		rc = tpm_sysfs_add_device(chip);
		rc = tpm_sysfs_add_device(chip);
@@ -208,6 +198,10 @@ int tpm_chip_register(struct tpm_chip *chip)
		chip->bios_dir = tpm_bios_log_setup(chip->devname);
		chip->bios_dir = tpm_bios_log_setup(chip->devname);
	}
	}


	rc = tpm_dev_add_device(chip);
	if (rc)
		return rc;

	/* Make the chip available. */
	/* Make the chip available. */
	spin_lock(&driver_lock);
	spin_lock(&driver_lock);
	list_add_rcu(&chip->list, &tpm_chip_list);
	list_add_rcu(&chip->list, &tpm_chip_list);