Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757102AbcCaOlv (ORCPT ); Thu, 31 Mar 2016 10:41:51 -0400 Received: from e28smtp06.in.ibm.com ([125.16.236.6]:57613 "EHLO e28smtp06.in.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752768AbcCaOlt (ORCPT ); Thu, 31 Mar 2016 10:41:49 -0400 X-IBM-Helo: d28relay03.in.ibm.com X-IBM-MailFrom: honclo@linux.vnet.ibm.com X-IBM-RcptTo: stable@vger.kernel.org;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, stable@vger.kernel.org, "Hon Ching(Vicky) Lo" Subject: [PATCH v2] vTPM: fix missing error handling for suspend operation Date: Thu, 31 Mar 2016 10:41:23 -0400 Message-Id: <1459435283-1163-1-git-send-email-honclo@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.1 X-TM-AS-MML: disable x-cbid: 16033114-0021-0000-0000-00000B3B1E3E Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3256 Lines: 104 ibmvtpm_send_crq in tpm_ibmvtpm_suspend returns errors in a more granular level than what the existing code does. This patch adds the missing CRQ transport event code checks to ensure appropriate action 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