Skip to content

Commit

Permalink
tpm: move the PPI attributes to character device directory.
Browse files Browse the repository at this point in the history
Moved PPI attributes to the character device directory. This aligns with
the sysfs guidelines and makes them race free because they are created
atomically with the character device as part of device_register().The
character device and the sysfs attributes appear at the same time to the
user space.

As part of this change we enable PPI attributes also for TPM 2.0
devices. In order to retain backwards compatibility with TPM 1.x
devices, a symlink is created to the platform device directory.

Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Reviewed-by: Jason Gunthorpe <jason.gunthorpe@obsidianresearch.com>
Tested-by: Mimi Zohar <zohar@linux.vnet.ibm.com> (on TPM 1.2)
Tested-by: Chris J Arges <chris.j.arges@canonical.com>
Tested-by: Colin Ian King <colin.king@canonical.com>
Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
  • Loading branch information
Jarkko Sakkinen authored and Peter Huewe committed Oct 18, 2015
1 parent 37c1c04 commit 9b774d5
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 42 deletions.
24 changes: 16 additions & 8 deletions drivers/char/tpm/tpm-chip.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
chip->dev.class = tpm_class;
chip->dev.release = tpm_dev_release;
chip->dev.parent = chip->pdev;
#ifdef CONFIG_ACPI
chip->dev.groups = chip->groups;
#endif

if (chip->dev_num == 0)
chip->dev.devt = MKDEV(MISC_MAJOR, TPM_MINOR);
Expand Down Expand Up @@ -182,12 +185,6 @@ static int tpm1_chip_register(struct tpm_chip *chip)
if (rc)
return rc;

rc = tpm_add_ppi(chip);
if (rc) {
tpm_sysfs_del_device(chip);
return rc;
}

chip->bios_dir = tpm_bios_log_setup(chip->devname);

return 0;
Expand All @@ -201,8 +198,6 @@ static void tpm1_chip_unregister(struct tpm_chip *chip)
if (chip->bios_dir)
tpm_bios_log_teardown(chip->bios_dir);

tpm_remove_ppi(chip);

tpm_sysfs_del_device(chip);
}

Expand All @@ -225,10 +220,20 @@ int tpm_chip_register(struct tpm_chip *chip)
if (rc)
return rc;

tpm_add_ppi(chip);

rc = tpm_dev_add_device(chip);
if (rc)
goto out_err;

if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
rc = __compat_only_sysfs_link_entry_to_kobj(&chip->pdev->kobj,
&chip->dev.kobj,
"ppi");
if (rc)
goto out_err;
}

/* Make the chip available. */
spin_lock(&driver_lock);
list_add_rcu(&chip->list, &tpm_chip_list);
Expand Down Expand Up @@ -263,6 +268,9 @@ void tpm_chip_unregister(struct tpm_chip *chip)
spin_unlock(&driver_lock);
synchronize_rcu();

if (!(chip->flags & TPM_CHIP_FLAG_TPM2))
sysfs_remove_link(&chip->pdev->kobj, "ppi");

tpm1_chip_unregister(chip);
tpm_dev_del_device(chip);
}
Expand Down
17 changes: 6 additions & 11 deletions drivers/char/tpm/tpm.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,7 @@ struct tpm_vendor_specific {

enum tpm_chip_flags {
TPM_CHIP_FLAG_REGISTERED = BIT(0),
TPM_CHIP_FLAG_PPI = BIT(1),
TPM_CHIP_FLAG_TPM2 = BIT(2),
TPM_CHIP_FLAG_TPM2 = BIT(1),
};

struct tpm_chip {
Expand All @@ -182,14 +181,16 @@ struct tpm_chip {
struct dentry **bios_dir;

#ifdef CONFIG_ACPI
const struct attribute_group *groups[2];
unsigned int groups_cnt;
acpi_handle acpi_dev_handle;
char ppi_version[TPM_PPI_VERSION_LEN + 1];
#endif /* CONFIG_ACPI */

struct list_head list;
};

#define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor)
#define to_tpm_chip(d) container_of(d, struct tpm_chip, dev)

static inline void tpm_chip_put(struct tpm_chip *chip)
{
Expand Down Expand Up @@ -419,15 +420,9 @@ void tpm_sysfs_del_device(struct tpm_chip *chip);
int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf);

#ifdef CONFIG_ACPI
extern int tpm_add_ppi(struct tpm_chip *chip);
extern void tpm_remove_ppi(struct tpm_chip *chip);
extern void tpm_add_ppi(struct tpm_chip *chip);
#else
static inline int tpm_add_ppi(struct tpm_chip *chip)
{
return 0;
}

static inline void tpm_remove_ppi(struct tpm_chip *chip)
static inline void tpm_add_ppi(struct tpm_chip *chip)
{
}
#endif
Expand Down
34 changes: 11 additions & 23 deletions drivers/char/tpm/tpm_ppi.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ tpm_eval_dsm(acpi_handle ppi_handle, int func, acpi_object_type type,
static ssize_t tpm_show_ppi_version(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct tpm_chip *chip = dev_get_drvdata(dev);
struct tpm_chip *chip = to_tpm_chip(dev);

return scnprintf(buf, PAGE_SIZE, "%s\n", chip->ppi_version);
}
Expand All @@ -63,7 +63,7 @@ static ssize_t tpm_show_ppi_request(struct device *dev,
{
ssize_t size = -EINVAL;
union acpi_object *obj;
struct tpm_chip *chip = dev_get_drvdata(dev);
struct tpm_chip *chip = to_tpm_chip(dev);

obj = tpm_eval_dsm(chip->acpi_dev_handle, TPM_PPI_FN_GETREQ,
ACPI_TYPE_PACKAGE, NULL);
Expand Down Expand Up @@ -100,7 +100,7 @@ static ssize_t tpm_store_ppi_request(struct device *dev,
int func = TPM_PPI_FN_SUBREQ;
union acpi_object *obj, tmp;
union acpi_object argv4 = ACPI_INIT_DSM_ARGV4(1, &tmp);
struct tpm_chip *chip = dev_get_drvdata(dev);
struct tpm_chip *chip = to_tpm_chip(dev);

/*
* the function to submit TPM operation request to pre-os environment
Expand Down Expand Up @@ -156,7 +156,7 @@ static ssize_t tpm_show_ppi_transition_action(struct device *dev,
.buffer.length = 0,
.buffer.pointer = NULL
};
struct tpm_chip *chip = dev_get_drvdata(dev);
struct tpm_chip *chip = to_tpm_chip(dev);

static char *info[] = {
"None",
Expand Down Expand Up @@ -197,7 +197,7 @@ static ssize_t tpm_show_ppi_response(struct device *dev,
acpi_status status = -EINVAL;
union acpi_object *obj, *ret_obj;
u64 req, res;
struct tpm_chip *chip = dev_get_drvdata(dev);
struct tpm_chip *chip = to_tpm_chip(dev);

obj = tpm_eval_dsm(chip->acpi_dev_handle, TPM_PPI_FN_GETRSP,
ACPI_TYPE_PACKAGE, NULL);
Expand Down Expand Up @@ -296,7 +296,7 @@ static ssize_t tpm_show_ppi_tcg_operations(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct tpm_chip *chip = dev_get_drvdata(dev);
struct tpm_chip *chip = to_tpm_chip(dev);

return show_ppi_operations(chip->acpi_dev_handle, buf, 0,
PPI_TPM_REQ_MAX);
Expand All @@ -306,7 +306,7 @@ static ssize_t tpm_show_ppi_vs_operations(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct tpm_chip *chip = dev_get_drvdata(dev);
struct tpm_chip *chip = to_tpm_chip(dev);

return show_ppi_operations(chip->acpi_dev_handle, buf, PPI_VS_REQ_START,
PPI_VS_REQ_END);
Expand Down Expand Up @@ -334,17 +334,16 @@ static struct attribute_group ppi_attr_grp = {
.attrs = ppi_attrs
};

int tpm_add_ppi(struct tpm_chip *chip)
void tpm_add_ppi(struct tpm_chip *chip)
{
union acpi_object *obj;
int rc;

if (!chip->acpi_dev_handle)
return 0;
return;

if (!acpi_check_dsm(chip->acpi_dev_handle, tpm_ppi_uuid,
TPM_PPI_REVISION_ID, 1 << TPM_PPI_FN_VERSION))
return 0;
return;

/* Cache PPI version string. */
obj = acpi_evaluate_dsm_typed(chip->acpi_dev_handle, tpm_ppi_uuid,
Expand All @@ -356,16 +355,5 @@ int tpm_add_ppi(struct tpm_chip *chip)
ACPI_FREE(obj);
}

rc = sysfs_create_group(&chip->pdev->kobj, &ppi_attr_grp);

if (!rc)
chip->flags |= TPM_CHIP_FLAG_PPI;

return rc;
}

void tpm_remove_ppi(struct tpm_chip *chip)
{
if (chip->flags & TPM_CHIP_FLAG_PPI)
sysfs_remove_group(&chip->pdev->kobj, &ppi_attr_grp);
chip->groups[chip->groups_cnt++] = &ppi_attr_grp;
}

0 comments on commit 9b774d5

Please sign in to comment.