Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752783AbcDEAaO (ORCPT ); Mon, 4 Apr 2016 20:30:14 -0400 Received: from e28smtp05.in.ibm.com ([125.16.236.5]:54627 "EHLO e28smtp05.in.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751264AbcDEAaM (ORCPT ); Mon, 4 Apr 2016 20:30:12 -0400 X-IBM-Helo: d28relay04.in.ibm.com X-IBM-MailFrom: honclo@linux.vnet.ibm.com X-IBM-RcptTo: linux-kernel@vger.kernel.org From: "Hon Ching(Vicky) Lo" To: tpmdd-devel@lists.sourceforge.net Cc: Peter Huewe , Ashley Lai , Jarkko Sakkinen , linux-kernel@vger.kernel.org, "Hon Ching(Vicky) Lo" Subject: [PATCH v3] vTPM: fix missing error handling for suspend operation Date: Mon, 4 Apr 2016 20:29:46 -0400 Message-Id: <1459816186-7220-1-git-send-email-honclo@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.1 X-TM-AS-MML: disable x-cbid: 16040500-0017-0000-0000-00001DBF2627 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3297 Lines: 105 ibmvtpm_send_crq in tpm_ibmvtpm_suspend returns errors in a more granular level than what the existing code does, according to the PAPR standard. This patch adds the missing CRQ transport event code checks to ensure the appropriate actions are taken, in the case that ibmvtpm_send_crq returns H_CLOSED. Signed-off-by: Hon Ching(Vicky) Lo --- drivers/char/tpm/tpm_ibmvtpm.c | 43 ++++++++++++++++++++++++++++++++++++--- drivers/char/tpm/tpm_ibmvtpm.h | 7 ++++++ 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c index 3e6a226..ea2a970 100644 --- a/drivers/char/tpm/tpm_ibmvtpm.c +++ b/drivers/char/tpm/tpm_ibmvtpm.c @@ -335,17 +335,46 @@ static int tpm_ibmvtpm_suspend(struct device *dev) struct ibmvtpm_crq crq; u64 *buf = (u64 *) &crq; int rc = 0; + int counter = 0; + int sig; - crq.valid = (u8)IBMVTPM_VALID_CMD; - crq.msg = (u8)VTPM_PREPARE_TO_SUSPEND; +suspend: + crq_initialized = 0; + crq.valid = (u8) IBMVTPM_VALID_CMD; + crq.msg = (u8) VTPM_PREPARE_TO_SUSPEND; rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(buf[0]), cpu_to_be64(buf[1])); + + if ((rc == H_CLOSED) && (crq.valid == (u8) VALID_TRANSPORT_EVENT)) { + if (crq.msg == (u8) PARTNER_PARTITION_FAILED) { + dev_err(ibmvtpm->dev, + "vtpm has terminated fatally; reboot to reinstate a trusted state.\n"); + } + + if ((crq.msg == (u8) PARTNER_PARTITION_DEREG_CRQ) + && (counter < 1)) { + counter++; + + /* The vtpm is in the process of being reloaded by + * firmware and has de-registered CRQ. The client + * must wait for the CRQ INITIALIZATION message and + * respond and must resubmit suspend message. + */ + sig = + wait_event_interruptible(ibmvtpm->wq, + crq_initialized == 1); + if (sig) + return -EINTR; + goto suspend; + } + } + if (rc != H_SUCCESS) - dev_err(ibmvtpm->dev, - "tpm_ibmvtpm_suspend failed rc=%d\n", rc); + dev_err(ibmvtpm->dev, "tpm_ibmvtpm_suspend failed rc=%d\n", rc); return rc; + } /** @@ -477,6 +506,9 @@ static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq, case INIT_CRQ_COMP_RES: dev_info(ibmvtpm->dev, "CRQ initialization completed\n"); + /* in case vtpm is being reloaded */ + crq_initialized = 1; + wake_up_interruptible(&ibmvtpm->wq); return; default: dev_err(ibmvtpm->dev, "Unknown crq message type: %d\n", crq->msg); @@ -517,6 +549,9 @@ static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq, ibmvtpm->res_len = be16_to_cpu(crq->len); wake_up_interruptible(&ibmvtpm->wq); return; + case VTPM_PREPARE_TO_SUSPEND_RES: + dev_info(ibmvtpm->dev, "Prepare to Suspend Response\n"); + return; default: return; } diff --git a/drivers/char/tpm/tpm_ibmvtpm.h b/drivers/char/tpm/tpm_ibmvtpm.h index 6af9289..ed5fd5f 100644 --- a/drivers/char/tpm/tpm_ibmvtpm.h +++ b/drivers/char/tpm/tpm_ibmvtpm.h @@ -73,4 +73,11 @@ struct ibmvtpm_dev { #define VTPM_PREPARE_TO_SUSPEND 0x04 #define VTPM_PREPARE_TO_SUSPEND_RES (0x04 | VTPM_MSG_RES) +/* vTPM CRQ Transport Event codes */ +#define VALID_TRANSPORT_EVENT 0xFF +#define PARTNER_PARTITION_FAILED 0x01 +#define PARTNER_PARTITION_DEREG_CRQ 0x02 + +int crq_initialized; + #endif -- 1.7.1