Merge tag 'tpmdd-next-20200316' of git://git.infradead.org/users/jjs/linux-tpmdd
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 30 Mar 2020 17:57:32 +0000 (10:57 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 30 Mar 2020 17:57:32 +0000 (10:57 -0700)
Pull tpm updates from Jarkko Sakkinen:
 "tpmdd updates for Linux v5.7"

* tag 'tpmdd-next-20200316' of git://git.infradead.org/users/jjs/linux-tpmdd:
  KEYS: reaching the keys quotas correctly
  tpm: ibmvtpm: Add support for TPM2
  tpm: ibmvtpm: Wait for buffer to be set before proceeding
  tpm: of: Handle IBM,vtpm20 case when getting log parameters
  MAINTAINERS: adjust to trusted keys subsystem creation
  tpm: tpm_tis_spi_cr50: use new structure for SPI transfer delays
  tpm_tis_spi: use new 'delay' structure for SPI transfer delays
  tpm: tpm2_bios_measurements_next should increase position index
  tpm: tpm1_bios_measurements_next should increase position index
  tpm: Don't make log failures fatal

14 files changed:
MAINTAINERS
drivers/char/tpm/eventlog/common.c
drivers/char/tpm/eventlog/of.c
drivers/char/tpm/eventlog/tpm1.c
drivers/char/tpm/eventlog/tpm2.c
drivers/char/tpm/tpm-chip.c
drivers/char/tpm/tpm.h
drivers/char/tpm/tpm2-cmd.c
drivers/char/tpm/tpm_ibmvtpm.c
drivers/char/tpm/tpm_ibmvtpm.h
drivers/char/tpm/tpm_tis_spi_cr50.c
drivers/char/tpm/tpm_tis_spi_main.c
security/keys/key.c
security/keys/keyctl.c

index 5a5332b..8b6e2d8 100644 (file)
@@ -9280,8 +9280,8 @@ L:        keyrings@vger.kernel.org
 S:     Supported
 F:     Documentation/security/keys/trusted-encrypted.rst
 F:     include/keys/trusted-type.h
-F:     security/keys/trusted.c
-F:     include/keys/trusted.h
+F:     include/keys/trusted_tpm.h
+F:     security/keys/trusted-keys/
 
 KEYS/KEYRINGS
 M:     David Howells <dhowells@redhat.com>
index 7a0fca6..7460f23 100644 (file)
@@ -99,11 +99,8 @@ static int tpm_read_log(struct tpm_chip *chip)
  *
  * If an event log is found then the securityfs files are setup to
  * export it to userspace, otherwise nothing is done.
- *
- * Returns -ENODEV if the firmware has no event log or securityfs is not
- * supported.
  */
-int tpm_bios_log_setup(struct tpm_chip *chip)
+void tpm_bios_log_setup(struct tpm_chip *chip)
 {
        const char *name = dev_name(&chip->dev);
        unsigned int cnt;
@@ -112,7 +109,7 @@ int tpm_bios_log_setup(struct tpm_chip *chip)
 
        rc = tpm_read_log(chip);
        if (rc < 0)
-               return rc;
+               return;
        log_version = rc;
 
        cnt = 0;
@@ -158,13 +155,12 @@ int tpm_bios_log_setup(struct tpm_chip *chip)
                cnt++;
        }
 
-       return 0;
+       return;
 
 err:
-       rc = PTR_ERR(chip->bios_dir[cnt]);
        chip->bios_dir[cnt] = NULL;
        tpm_bios_log_teardown(chip);
-       return rc;
+       return;
 }
 
 void tpm_bios_log_teardown(struct tpm_chip *chip)
index af347c1..a9ce66d 100644 (file)
@@ -51,7 +51,8 @@ int tpm_read_log_of(struct tpm_chip *chip)
         * endian format. For this reason, vtpm doesn't need conversion
         * but physical tpm needs the conversion.
         */
-       if (of_property_match_string(np, "compatible", "IBM,vtpm") < 0) {
+       if (of_property_match_string(np, "compatible", "IBM,vtpm") < 0 &&
+           of_property_match_string(np, "compatible", "IBM,vtpm20") < 0) {
                size = be32_to_cpup((__force __be32 *)sizep);
                base = be64_to_cpup((__force __be64 *)basep);
        } else {
index 739b1d9..2c96977 100644 (file)
@@ -115,6 +115,7 @@ static void *tpm1_bios_measurements_next(struct seq_file *m, void *v,
        u32 converted_event_size;
        u32 converted_event_type;
 
+       (*pos)++;
        converted_event_size = do_endian_conversion(event->event_size);
 
        v += sizeof(struct tcpa_event) + converted_event_size;
@@ -132,7 +133,6 @@ static void *tpm1_bios_measurements_next(struct seq_file *m, void *v,
            ((v + sizeof(struct tcpa_event) + converted_event_size) > limit))
                return NULL;
 
-       (*pos)++;
        return v;
 }
 
index b9aeda1..e741b11 100644 (file)
@@ -94,6 +94,7 @@ static void *tpm2_bios_measurements_next(struct seq_file *m, void *v,
        size_t event_size;
        void *marker;
 
+       (*pos)++;
        event_header = log->bios_event_log;
 
        if (v == SEQ_START_TOKEN) {
@@ -118,7 +119,6 @@ static void *tpm2_bios_measurements_next(struct seq_file *m, void *v,
        if (((v + event_size) >= limit) || (event_size == 0))
                return NULL;
 
-       (*pos)++;
        return v;
 }
 
index 3d6d394..5807383 100644 (file)
@@ -596,9 +596,7 @@ int tpm_chip_register(struct tpm_chip *chip)
 
        tpm_sysfs_add_device(chip);
 
-       rc = tpm_bios_log_setup(chip);
-       if (rc != 0 && rc != -ENODEV)
-               return rc;
+       tpm_bios_log_setup(chip);
 
        tpm_add_ppi(chip);
 
index 5620747..0fbcede 100644 (file)
@@ -226,6 +226,7 @@ int tpm2_auto_startup(struct tpm_chip *chip);
 void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type);
 unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
 int tpm2_probe(struct tpm_chip *chip);
+int tpm2_get_cc_attrs_tbl(struct tpm_chip *chip);
 int tpm2_find_cc(struct tpm_chip *chip, u32 cc);
 int tpm2_init_space(struct tpm_space *space);
 void tpm2_del_space(struct tpm_chip *chip, struct tpm_space *space);
@@ -235,7 +236,7 @@ int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u8 *cmd,
 int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space, void *buf,
                      size_t *bufsiz);
 
-int tpm_bios_log_setup(struct tpm_chip *chip);
+void tpm_bios_log_setup(struct tpm_chip *chip);
 void tpm_bios_log_teardown(struct tpm_chip *chip);
 int tpm_dev_common_init(void);
 void tpm_dev_common_exit(void);
index 7603295..76f67b1 100644 (file)
@@ -615,7 +615,7 @@ out:
        return rc;
 }
 
-static int tpm2_get_cc_attrs_tbl(struct tpm_chip *chip)
+int tpm2_get_cc_attrs_tbl(struct tpm_chip *chip)
 {
        struct tpm_buf buf;
        u32 nr_commands;
index 78cc526..1a49db9 100644 (file)
@@ -29,6 +29,7 @@ static const char tpm_ibmvtpm_driver_name[] = "tpm_ibmvtpm";
 
 static const struct vio_device_id tpm_ibmvtpm_device_table[] = {
        { "IBM,vtpm", "IBM,vtpm"},
+       { "IBM,vtpm", "IBM,vtpm20"},
        { "", "" }
 };
 MODULE_DEVICE_TABLE(vio, tpm_ibmvtpm_device_table);
@@ -571,6 +572,7 @@ static irqreturn_t ibmvtpm_interrupt(int irq, void *vtpm_instance)
         */
        while ((crq = ibmvtpm_crq_get_next(ibmvtpm)) != NULL) {
                ibmvtpm_crq_process(crq, ibmvtpm);
+               wake_up_interruptible(&ibmvtpm->crq_queue.wq);
                crq->valid = 0;
                smp_wmb();
        }
@@ -618,6 +620,7 @@ static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev,
        }
 
        crq_q->num_entry = CRQ_RES_BUF_SIZE / sizeof(*crq_q->crq_addr);
+       init_waitqueue_head(&crq_q->wq);
        ibmvtpm->crq_dma_handle = dma_map_single(dev, crq_q->crq_addr,
                                                 CRQ_RES_BUF_SIZE,
                                                 DMA_BIDIRECTIONAL);
@@ -670,6 +673,20 @@ static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev,
        if (rc)
                goto init_irq_cleanup;
 
+       if (!strcmp(id->compat, "IBM,vtpm20")) {
+               chip->flags |= TPM_CHIP_FLAG_TPM2;
+               rc = tpm2_get_cc_attrs_tbl(chip);
+               if (rc)
+                       goto init_irq_cleanup;
+       }
+
+       if (!wait_event_timeout(ibmvtpm->crq_queue.wq,
+                               ibmvtpm->rtce_buf != NULL,
+                               HZ)) {
+               dev_err(dev, "CRQ response timed out\n");
+               goto init_irq_cleanup;
+       }
+
        return tpm_chip_register(chip);
 init_irq_cleanup:
        do {
index 7983f1a..b92aa7d 100644 (file)
@@ -26,6 +26,7 @@ struct ibmvtpm_crq_queue {
        struct ibmvtpm_crq *crq_addr;
        u32 index;
        u32 num_entry;
+       wait_queue_head_t wq;
 };
 
 struct ibmvtpm_dev {
index 37d72e8..ea759af 100644 (file)
@@ -132,7 +132,12 @@ static void cr50_wake_if_needed(struct cr50_spi_phy *cr50_phy)
 
        if (cr50_needs_waking(cr50_phy)) {
                /* Assert CS, wait 1 msec, deassert CS */
-               struct spi_transfer spi_cs_wake = { .delay_usecs = 1000 };
+               struct spi_transfer spi_cs_wake = {
+                       .delay = {
+                               .value = 1000,
+                               .unit = SPI_DELAY_UNIT_USECS
+                       }
+               };
 
                spi_sync_transfer(phy->spi_device, &spi_cs_wake, 1);
                /* Wait for it to fully wake */
index d1754fd..d967559 100644 (file)
@@ -110,7 +110,8 @@ int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
 
                spi_xfer.cs_change = 0;
                spi_xfer.len = transfer_len;
-               spi_xfer.delay_usecs = 5;
+               spi_xfer.delay.value = 5;
+               spi_xfer.delay.unit = SPI_DELAY_UNIT_USECS;
 
                if (in) {
                        spi_xfer.tx_buf = NULL;
index 718bf72..e959b3c 100644 (file)
@@ -382,7 +382,7 @@ int key_payload_reserve(struct key *key, size_t datalen)
                spin_lock(&key->user->lock);
 
                if (delta > 0 &&
-                   (key->user->qnbytes + delta >= maxbytes ||
+                   (key->user->qnbytes + delta > maxbytes ||
                     key->user->qnbytes + delta < key->user->qnbytes)) {
                        ret = -EDQUOT;
                }
index 9b898c9..d1a3dea 100644 (file)
@@ -937,8 +937,8 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group)
                                key_quota_root_maxbytes : key_quota_maxbytes;
 
                        spin_lock(&newowner->lock);
-                       if (newowner->qnkeys + 1 >= maxkeys ||
-                           newowner->qnbytes + key->quotalen >= maxbytes ||
+                       if (newowner->qnkeys + 1 > maxkeys ||
+                           newowner->qnbytes + key->quotalen > maxbytes ||
                            newowner->qnbytes + key->quotalen <
                            newowner->qnbytes)
                                goto quota_overrun;