diff options
author | honclo <honclo@imap.linux.ibm.com> | 2015-02-12 21:02:24 -0500 |
---|---|---|
committer | Peter Huewe <peterhuewe@gmx.de> | 2015-02-15 11:36:05 -0500 |
commit | eb71f8a5e33fa1066fb92f0111ab366a341e1f6c (patch) | |
tree | 7c6c007038f542d86133a7645f5ac631426ad726 | |
parent | 4d5f2051cd24adc19a645e920344e05afe8d69b9 (diff) |
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>
-rw-r--r-- | drivers/char/tpm/tpm_ibmvtpm.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c index 0840347e251c..b1e53e3aece5 100644 --- a/drivers/char/tpm/tpm_ibmvtpm.c +++ b/drivers/char/tpm/tpm_ibmvtpm.c | |||
@@ -148,7 +148,8 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count) | |||
148 | crq.len = (u16)count; | 148 | crq.len = (u16)count; |
149 | crq.data = ibmvtpm->rtce_dma_handle; | 149 | crq.data = ibmvtpm->rtce_dma_handle; |
150 | 150 | ||
151 | rc = ibmvtpm_send_crq(ibmvtpm->vdev, word[0], word[1]); | 151 | rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(word[0]), |
152 | cpu_to_be64(word[1])); | ||
152 | if (rc != H_SUCCESS) { | 153 | if (rc != H_SUCCESS) { |
153 | dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc); | 154 | dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc); |
154 | rc = 0; | 155 | rc = 0; |
@@ -186,7 +187,8 @@ static int ibmvtpm_crq_get_rtce_size(struct ibmvtpm_dev *ibmvtpm) | |||
186 | crq.valid = (u8)IBMVTPM_VALID_CMD; | 187 | crq.valid = (u8)IBMVTPM_VALID_CMD; |
187 | crq.msg = (u8)VTPM_GET_RTCE_BUFFER_SIZE; | 188 | crq.msg = (u8)VTPM_GET_RTCE_BUFFER_SIZE; |
188 | 189 | ||
189 | rc = ibmvtpm_send_crq(ibmvtpm->vdev, buf[0], buf[1]); | 190 | rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(buf[0]), |
191 | cpu_to_be64(buf[1])); | ||
190 | if (rc != H_SUCCESS) | 192 | if (rc != H_SUCCESS) |
191 | dev_err(ibmvtpm->dev, | 193 | dev_err(ibmvtpm->dev, |
192 | "ibmvtpm_crq_get_rtce_size failed rc=%d\n", rc); | 194 | "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 | crq.valid = (u8)IBMVTPM_VALID_CMD; | 214 | crq.valid = (u8)IBMVTPM_VALID_CMD; |
213 | crq.msg = (u8)VTPM_GET_VERSION; | 215 | crq.msg = (u8)VTPM_GET_VERSION; |
214 | 216 | ||
215 | rc = ibmvtpm_send_crq(ibmvtpm->vdev, buf[0], buf[1]); | 217 | rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(buf[0]), |
218 | cpu_to_be64(buf[1])); | ||
216 | if (rc != H_SUCCESS) | 219 | if (rc != H_SUCCESS) |
217 | dev_err(ibmvtpm->dev, | 220 | dev_err(ibmvtpm->dev, |
218 | "ibmvtpm_crq_get_version failed rc=%d\n", rc); | 221 | "ibmvtpm_crq_get_version failed rc=%d\n", rc); |
@@ -336,7 +339,8 @@ static int tpm_ibmvtpm_suspend(struct device *dev) | |||
336 | crq.valid = (u8)IBMVTPM_VALID_CMD; | 339 | crq.valid = (u8)IBMVTPM_VALID_CMD; |
337 | crq.msg = (u8)VTPM_PREPARE_TO_SUSPEND; | 340 | crq.msg = (u8)VTPM_PREPARE_TO_SUSPEND; |
338 | 341 | ||
339 | rc = ibmvtpm_send_crq(ibmvtpm->vdev, buf[0], buf[1]); | 342 | rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(buf[0]), |
343 | cpu_to_be64(buf[1])); | ||
340 | if (rc != H_SUCCESS) | 344 | if (rc != H_SUCCESS) |
341 | dev_err(ibmvtpm->dev, | 345 | dev_err(ibmvtpm->dev, |
342 | "tpm_ibmvtpm_suspend failed rc=%d\n", rc); | 346 | "tpm_ibmvtpm_suspend failed rc=%d\n", rc); |
@@ -481,11 +485,11 @@ static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq, | |||
481 | case IBMVTPM_VALID_CMD: | 485 | case IBMVTPM_VALID_CMD: |
482 | switch (crq->msg) { | 486 | switch (crq->msg) { |
483 | case VTPM_GET_RTCE_BUFFER_SIZE_RES: | 487 | case VTPM_GET_RTCE_BUFFER_SIZE_RES: |
484 | if (crq->len <= 0) { | 488 | if (be16_to_cpu(crq->len) <= 0) { |
485 | dev_err(ibmvtpm->dev, "Invalid rtce size\n"); | 489 | dev_err(ibmvtpm->dev, "Invalid rtce size\n"); |
486 | return; | 490 | return; |
487 | } | 491 | } |
488 | ibmvtpm->rtce_size = crq->len; | 492 | ibmvtpm->rtce_size = be16_to_cpu(crq->len); |
489 | ibmvtpm->rtce_buf = kmalloc(ibmvtpm->rtce_size, | 493 | ibmvtpm->rtce_buf = kmalloc(ibmvtpm->rtce_size, |
490 | GFP_KERNEL); | 494 | GFP_KERNEL); |
491 | if (!ibmvtpm->rtce_buf) { | 495 | if (!ibmvtpm->rtce_buf) { |
@@ -506,11 +510,11 @@ static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq, | |||
506 | 510 | ||
507 | return; | 511 | return; |
508 | case VTPM_GET_VERSION_RES: | 512 | case VTPM_GET_VERSION_RES: |
509 | ibmvtpm->vtpm_version = crq->data; | 513 | ibmvtpm->vtpm_version = be32_to_cpu(crq->data); |
510 | return; | 514 | return; |
511 | case VTPM_TPM_COMMAND_RES: | 515 | case VTPM_TPM_COMMAND_RES: |
512 | /* len of the data in rtce buffer */ | 516 | /* len of the data in rtce buffer */ |
513 | ibmvtpm->res_len = crq->len; | 517 | ibmvtpm->res_len = be16_to_cpu(crq->len); |
514 | wake_up_interruptible(&ibmvtpm->wq); | 518 | wake_up_interruptible(&ibmvtpm->wq); |
515 | return; | 519 | return; |
516 | default: | 520 | default: |