tpm/ppi: Possibly show command parameter if TPM PPI 1.3 is used
authorStefan Berger <stefanb@linux.ibm.com>
Thu, 17 Jan 2019 17:41:34 +0000 (12:41 -0500)
committerJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Wed, 13 Feb 2019 07:48:53 +0000 (09:48 +0200)
TPM PPI 1.3 introduces an additional optional command parameter
that may be needed for some commands. Display the parameter if the
command requires such a parameter. Only command 23 needs one.

The PPI request file will show output like this then:

   # echo "23 16" > request
   # cat request
   23 16

   # echo "5" > request
   # cat request
   5

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Tested-by: David Safford <david.safford@ge.com>
Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
drivers/char/tpm/tpm_ppi.c

index fdfd627..942a2f7 100644 (file)
@@ -21,6 +21,7 @@
 #include "tpm.h"
 
 #define TPM_PPI_REVISION_ID_1  1
+#define TPM_PPI_REVISION_ID_2  2
 #define TPM_PPI_FN_VERSION     1
 #define TPM_PPI_FN_SUBREQ      2
 #define TPM_PPI_FN_GETREQ      3
@@ -36,6 +37,11 @@ static const guid_t tpm_ppi_guid =
        GUID_INIT(0x3DDDFAA6, 0x361B, 0x4EB4,
                  0xA4, 0x24, 0x8D, 0x10, 0x08, 0x9D, 0x16, 0x53);
 
+static bool tpm_ppi_req_has_parameter(u64 req)
+{
+       return req == 23;
+}
+
 static inline union acpi_object *
 tpm_eval_dsm(acpi_handle ppi_handle, int func, acpi_object_type type,
             union acpi_object *argv4, u64 rev)
@@ -59,9 +65,14 @@ static ssize_t tpm_show_ppi_request(struct device *dev,
        ssize_t size = -EINVAL;
        union acpi_object *obj;
        struct tpm_chip *chip = to_tpm_chip(dev);
+       u64 rev = TPM_PPI_REVISION_ID_2;
+       u64 req;
+
+       if (strcmp(chip->ppi_version, "1.2") < 0)
+               rev = TPM_PPI_REVISION_ID_1;
 
        obj = tpm_eval_dsm(chip->acpi_dev_handle, TPM_PPI_FN_GETREQ,
-                          ACPI_TYPE_PACKAGE, NULL, TPM_PPI_REVISION_ID_1);
+                          ACPI_TYPE_PACKAGE, NULL, rev);
        if (!obj)
                return -ENXIO;
 
@@ -71,7 +82,23 @@ static ssize_t tpm_show_ppi_request(struct device *dev,
         * error. The second is pending TPM operation requested by the OS, 0
         * means none and >0 means operation value.
         */
-       if (obj->package.count == 2 &&
+       if (obj->package.count == 3 &&
+           obj->package.elements[0].type == ACPI_TYPE_INTEGER &&
+           obj->package.elements[1].type == ACPI_TYPE_INTEGER &&
+           obj->package.elements[2].type == ACPI_TYPE_INTEGER) {
+               if (obj->package.elements[0].integer.value)
+                       size = -EFAULT;
+               else {
+                       req = obj->package.elements[1].integer.value;
+                       if (tpm_ppi_req_has_parameter(req))
+                               size = scnprintf(buf, PAGE_SIZE,
+                                   "%llu %llu\n", req,
+                                   obj->package.elements[2].integer.value);
+                       else
+                               size = scnprintf(buf, PAGE_SIZE,
+                                               "%llu\n", req);
+               }
+       } else if (obj->package.count == 2 &&
            obj->package.elements[0].type == ACPI_TYPE_INTEGER &&
            obj->package.elements[1].type == ACPI_TYPE_INTEGER) {
                if (obj->package.elements[0].integer.value)