Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eb71f8a5 authored by honclo's avatar honclo Committed by Peter Huewe
Browse files

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: default avatarHon Ching(Vicky) Lo <honclo@linux.vnet.ibm.com>
Signed-off-by: default avatarJoy Latten <jmlatten@linux.vnet.ibm.com>
Cc: <stable@vger.kernel.org>
[phuewe: manually applied the patch :( ]
Reviewed-by: default avatarAshley Lai <ashley@ahsleylai.com>
Signed-off-by: default avatarPeter Huewe <peterhuewe@gmx.de>
parent 4d5f2051
Loading
Loading
Loading
Loading
+12 −8
Original line number Original line Diff line number Diff line
@@ -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)
	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)
	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);
@@ -336,7 +339,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);
@@ -481,11 +485,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) {
@@ -506,11 +510,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: