Added Little Endian support to vtpm module
The tpm_ibmvtpm module is affected by an unaligned access problem. ibmvtpm_crq_get_version failed with rc=-4 during boot when vTPM is enabled in Power partition, which supports both little endian and big endian modes. We added little endian support to fix this problem: 1) added cpu_to_be64 calls to ensure BE data is sent from an LE OS. 2) added be16_to_cpu and be32_to_cpu calls to make sure data received is in LE format on a LE OS. Signed-off-by: Hon Ching(Vicky) Lo <honclo@linux.vnet.ibm.com> Signed-off-by: Joy Latten <jmlatten@linux.vnet.ibm.com> Cc: <stable@vger.kernel.org> [phuewe: manually applied the patch :( ] Reviewed-by: Ashley Lai <ashley@ahsleylai.com> Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
This commit is contained in:
Родитель
4d5f2051cd
Коммит
eb71f8a5e3
|
@ -148,7 +148,8 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
|
|||
crq.len = (u16)count;
|
||||
crq.data = ibmvtpm->rtce_dma_handle;
|
||||
|
||||
rc = ibmvtpm_send_crq(ibmvtpm->vdev, word[0], word[1]);
|
||||
rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(word[0]),
|
||||
cpu_to_be64(word[1]));
|
||||
if (rc != H_SUCCESS) {
|
||||
dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc);
|
||||
rc = 0;
|
||||
|
@ -186,7 +187,8 @@ static int ibmvtpm_crq_get_rtce_size(struct ibmvtpm_dev *ibmvtpm)
|
|||
crq.valid = (u8)IBMVTPM_VALID_CMD;
|
||||
crq.msg = (u8)VTPM_GET_RTCE_BUFFER_SIZE;
|
||||
|
||||
rc = ibmvtpm_send_crq(ibmvtpm->vdev, buf[0], buf[1]);
|
||||
rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(buf[0]),
|
||||
cpu_to_be64(buf[1]));
|
||||
if (rc != H_SUCCESS)
|
||||
dev_err(ibmvtpm->dev,
|
||||
"ibmvtpm_crq_get_rtce_size failed rc=%d\n", rc);
|
||||
|
@ -212,7 +214,8 @@ static int ibmvtpm_crq_get_version(struct ibmvtpm_dev *ibmvtpm)
|
|||
crq.valid = (u8)IBMVTPM_VALID_CMD;
|
||||
crq.msg = (u8)VTPM_GET_VERSION;
|
||||
|
||||
rc = ibmvtpm_send_crq(ibmvtpm->vdev, buf[0], buf[1]);
|
||||
rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(buf[0]),
|
||||
cpu_to_be64(buf[1]));
|
||||
if (rc != H_SUCCESS)
|
||||
dev_err(ibmvtpm->dev,
|
||||
"ibmvtpm_crq_get_version failed rc=%d\n", rc);
|
||||
|
@ -336,7 +339,8 @@ static int tpm_ibmvtpm_suspend(struct device *dev)
|
|||
crq.valid = (u8)IBMVTPM_VALID_CMD;
|
||||
crq.msg = (u8)VTPM_PREPARE_TO_SUSPEND;
|
||||
|
||||
rc = ibmvtpm_send_crq(ibmvtpm->vdev, buf[0], buf[1]);
|
||||
rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(buf[0]),
|
||||
cpu_to_be64(buf[1]));
|
||||
if (rc != H_SUCCESS)
|
||||
dev_err(ibmvtpm->dev,
|
||||
"tpm_ibmvtpm_suspend failed rc=%d\n", rc);
|
||||
|
@ -481,11 +485,11 @@ static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq,
|
|||
case IBMVTPM_VALID_CMD:
|
||||
switch (crq->msg) {
|
||||
case VTPM_GET_RTCE_BUFFER_SIZE_RES:
|
||||
if (crq->len <= 0) {
|
||||
if (be16_to_cpu(crq->len) <= 0) {
|
||||
dev_err(ibmvtpm->dev, "Invalid rtce size\n");
|
||||
return;
|
||||
}
|
||||
ibmvtpm->rtce_size = crq->len;
|
||||
ibmvtpm->rtce_size = be16_to_cpu(crq->len);
|
||||
ibmvtpm->rtce_buf = kmalloc(ibmvtpm->rtce_size,
|
||||
GFP_KERNEL);
|
||||
if (!ibmvtpm->rtce_buf) {
|
||||
|
@ -506,11 +510,11 @@ static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq,
|
|||
|
||||
return;
|
||||
case VTPM_GET_VERSION_RES:
|
||||
ibmvtpm->vtpm_version = crq->data;
|
||||
ibmvtpm->vtpm_version = be32_to_cpu(crq->data);
|
||||
return;
|
||||
case VTPM_TPM_COMMAND_RES:
|
||||
/* len of the data in rtce buffer */
|
||||
ibmvtpm->res_len = crq->len;
|
||||
ibmvtpm->res_len = be16_to_cpu(crq->len);
|
||||
wake_up_interruptible(&ibmvtpm->wq);
|
||||
return;
|
||||
default:
|
||||
|
|
Загрузка…
Ссылка в новой задаче