/** * ibmvtpm_crq_send_init - Send a CRQ initialize message * @ibmvtpm: vtpm device struct * * Return value: * 0 - Success * Non-zero - Failure */ static int ibmvtpm_crq_send_init(struct ibmvtpm_dev *ibmvtpm) { int rc; rc = ibmvtpm_send_crq(ibmvtpm->vdev, INIT_CRQ_CMD, 0); if (rc != H_SUCCESS) dev_err(ibmvtpm->dev, "ibmvtpm_crq_send_init failed rc=%d\n", rc); return rc; }
/** * tpm_ibmvtpm_send - Send tpm request * @chip: tpm chip struct * @buf: buffer contains data to send * count: size of buffer * * Return value: * Number of bytes sent */ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count) { struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev); struct ibmvtpm_crq crq; __be64 *word = (__be64 *)&crq; int rc, sig; if (!ibmvtpm->rtce_buf) { dev_err(ibmvtpm->dev, "ibmvtpm device is not ready\n"); return 0; } if (count > ibmvtpm->rtce_size) { dev_err(ibmvtpm->dev, "Invalid size in send: count=%zd, rtce_size=%d\n", count, ibmvtpm->rtce_size); return -EIO; } if (ibmvtpm->tpm_processing_cmd) { dev_info(ibmvtpm->dev, "Need to wait for TPM to finish\n"); /* wait for previous command to finish */ sig = wait_event_interruptible(ibmvtpm->wq, !ibmvtpm->tpm_processing_cmd); if (sig) return -EINTR; } spin_lock(&ibmvtpm->rtce_lock); ibmvtpm->res_len = 0; memcpy((void *)ibmvtpm->rtce_buf, (void *)buf, count); crq.valid = (u8)IBMVTPM_VALID_CMD; crq.msg = (u8)VTPM_TPM_COMMAND; crq.len = cpu_to_be16(count); crq.data = cpu_to_be32(ibmvtpm->rtce_dma_handle); /* * set the processing flag before the Hcall, since we may get the * result (interrupt) before even being able to check rc. */ ibmvtpm->tpm_processing_cmd = true; rc = ibmvtpm_send_crq(ibmvtpm->vdev, be64_to_cpu(word[0]), be64_to_cpu(word[1])); if (rc != H_SUCCESS) { dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc); rc = 0; ibmvtpm->tpm_processing_cmd = false; } else rc = count; spin_unlock(&ibmvtpm->rtce_lock); return rc; }
/** * ibmvtpm_crq_get_version - Send a CRQ request to get vtpm version * - Note that this is vtpm version and not tpm version * @ibmvtpm: vtpm device struct * * Return value: * 0 - Success * Non-zero - Failure */ static int ibmvtpm_crq_get_version(struct ibmvtpm_dev *ibmvtpm) { struct ibmvtpm_crq crq; u64 *buf = (u64 *) &crq; int rc; crq.valid = (u8)IBMVTPM_VALID_CMD; crq.msg = (u8)VTPM_GET_VERSION; rc = ibmvtpm_send_crq(ibmvtpm->vdev, buf[0], buf[1]); if (rc != H_SUCCESS) dev_err(ibmvtpm->dev, "ibmvtpm_crq_get_version failed rc=%d\n", rc); return rc; }
/** * ibmvtpm_crq_get_rtce_size - Send a CRQ request to get rtce size * @ibmvtpm: vtpm device struct * * Return value: * 0 - Success * Non-zero - Failure */ static int ibmvtpm_crq_get_rtce_size(struct ibmvtpm_dev *ibmvtpm) { struct ibmvtpm_crq crq; u64 *buf = (u64 *) &crq; int rc; crq.valid = (u8)IBMVTPM_VALID_CMD; crq.msg = (u8)VTPM_GET_RTCE_BUFFER_SIZE; rc = ibmvtpm_send_crq(ibmvtpm->vdev, buf[0], buf[1]); if (rc != H_SUCCESS) dev_err(ibmvtpm->dev, "ibmvtpm_crq_get_rtce_size failed rc=%d\n", rc); return rc; }
/** * tpm_ibmvtpm_suspend - Suspend * @dev: device struct * * Return value: * 0 */ static int tpm_ibmvtpm_suspend(struct device *dev) { struct ibmvtpm_dev *ibmvtpm = ibmvtpm_get_data(dev); struct ibmvtpm_crq crq; u64 *buf = (u64 *) &crq; int rc = 0; crq.valid = (u8)IBMVTPM_VALID_CMD; crq.msg = (u8)VTPM_PREPARE_TO_SUSPEND; rc = ibmvtpm_send_crq(ibmvtpm->vdev, buf[0], buf[1]); if (rc != H_SUCCESS) dev_err(ibmvtpm->dev, "tpm_ibmvtpm_suspend failed rc=%d\n", rc); return rc; }
/** * tpm_ibmvtpm_send - Send tpm request * @chip: tpm chip struct * @buf: buffer contains data to send * count: size of buffer * * Return value: * Number of bytes sent */ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count) { struct ibmvtpm_dev *ibmvtpm; struct ibmvtpm_crq crq; __be64 *word = (__be64 *)&crq; int rc; ibmvtpm = (struct ibmvtpm_dev *)TPM_VPRIV(chip); if (!ibmvtpm->rtce_buf) { dev_err(ibmvtpm->dev, "ibmvtpm device is not ready\n"); return 0; } if (count > ibmvtpm->rtce_size) { dev_err(ibmvtpm->dev, "Invalid size in send: count=%ld, rtce_size=%d\n", count, ibmvtpm->rtce_size); return -EIO; } spin_lock(&ibmvtpm->rtce_lock); memcpy((void *)ibmvtpm->rtce_buf, (void *)buf, count); crq.valid = (u8)IBMVTPM_VALID_CMD; crq.msg = (u8)VTPM_TPM_COMMAND; crq.len = cpu_to_be16(count); crq.data = cpu_to_be32(ibmvtpm->rtce_dma_handle); rc = ibmvtpm_send_crq(ibmvtpm->vdev, be64_to_cpu(word[0]), be64_to_cpu(word[1])); if (rc != H_SUCCESS) { dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc); rc = 0; } else rc = count; spin_unlock(&ibmvtpm->rtce_lock); return rc; }