Commit c213da80 authored by honclo's avatar honclo Committed by Greg Kroah-Hartman

Added Little Endian support to vtpm module

commit eb71f8a5 upstream.

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: default avatarHon Ching(Vicky) Lo <honclo@linux.vnet.ibm.com>
Signed-off-by: default avatarJoy Latten <jmlatten@linux.vnet.ibm.com>
[phuewe: manually applied the patch :( ]
Reviewed-by: default avatarAshley Lai <ashley@ahsleylai.com>
Signed-off-by: default avatarPeter Huewe <peterhuewe@gmx.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 6280501c
...@@ -148,7 +148,8 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count) ...@@ -148,7 +148,8 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
crq.len = (u16)count; crq.len = (u16)count;
crq.data = ibmvtpm->rtce_dma_handle; 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) { if (rc != H_SUCCESS) {
dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc); dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc);
rc = 0; rc = 0;
...@@ -186,7 +187,8 @@ static int ibmvtpm_crq_get_rtce_size(struct ibmvtpm_dev *ibmvtpm) ...@@ -186,7 +187,8 @@ static int ibmvtpm_crq_get_rtce_size(struct ibmvtpm_dev *ibmvtpm)
crq.valid = (u8)IBMVTPM_VALID_CMD; crq.valid = (u8)IBMVTPM_VALID_CMD;
crq.msg = (u8)VTPM_GET_RTCE_BUFFER_SIZE; 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) if (rc != H_SUCCESS)
dev_err(ibmvtpm->dev, dev_err(ibmvtpm->dev,
"ibmvtpm_crq_get_rtce_size failed rc=%d\n", rc); "ibmvtpm_crq_get_rtce_size failed rc=%d\n", rc);
...@@ -212,7 +214,8 @@ static int ibmvtpm_crq_get_version(struct ibmvtpm_dev *ibmvtpm) ...@@ -212,7 +214,8 @@ static int ibmvtpm_crq_get_version(struct ibmvtpm_dev *ibmvtpm)
crq.valid = (u8)IBMVTPM_VALID_CMD; crq.valid = (u8)IBMVTPM_VALID_CMD;
crq.msg = (u8)VTPM_GET_VERSION; 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) if (rc != H_SUCCESS)
dev_err(ibmvtpm->dev, dev_err(ibmvtpm->dev,
"ibmvtpm_crq_get_version failed rc=%d\n", rc); "ibmvtpm_crq_get_version failed rc=%d\n", rc);
...@@ -335,7 +338,8 @@ static int tpm_ibmvtpm_suspend(struct device *dev) ...@@ -335,7 +338,8 @@ static int tpm_ibmvtpm_suspend(struct device *dev)
crq.valid = (u8)IBMVTPM_VALID_CMD; crq.valid = (u8)IBMVTPM_VALID_CMD;
crq.msg = (u8)VTPM_PREPARE_TO_SUSPEND; 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) if (rc != H_SUCCESS)
dev_err(ibmvtpm->dev, dev_err(ibmvtpm->dev,
"tpm_ibmvtpm_suspend failed rc=%d\n", rc); "tpm_ibmvtpm_suspend failed rc=%d\n", rc);
...@@ -519,11 +523,11 @@ static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq, ...@@ -519,11 +523,11 @@ static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq,
case IBMVTPM_VALID_CMD: case IBMVTPM_VALID_CMD:
switch (crq->msg) { switch (crq->msg) {
case VTPM_GET_RTCE_BUFFER_SIZE_RES: 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"); dev_err(ibmvtpm->dev, "Invalid rtce size\n");
return; return;
} }
ibmvtpm->rtce_size = crq->len; ibmvtpm->rtce_size = be16_to_cpu(crq->len);
ibmvtpm->rtce_buf = kmalloc(ibmvtpm->rtce_size, ibmvtpm->rtce_buf = kmalloc(ibmvtpm->rtce_size,
GFP_KERNEL); GFP_KERNEL);
if (!ibmvtpm->rtce_buf) { if (!ibmvtpm->rtce_buf) {
...@@ -544,11 +548,11 @@ static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq, ...@@ -544,11 +548,11 @@ static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq,
return; return;
case VTPM_GET_VERSION_RES: case VTPM_GET_VERSION_RES:
ibmvtpm->vtpm_version = crq->data; ibmvtpm->vtpm_version = be32_to_cpu(crq->data);
return; return;
case VTPM_TPM_COMMAND_RES: case VTPM_TPM_COMMAND_RES:
/* len of the data in rtce buffer */ /* 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); wake_up_interruptible(&ibmvtpm->wq);
return; return;
default: default:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment