From patchwork Wed Mar 11 06:34:11 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gavin Shan X-Patchwork-Id: 448823 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 5B7FA140172 for ; Wed, 11 Mar 2015 17:36:13 +1100 (AEDT) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3E9851A0BB2 for ; Wed, 11 Mar 2015 17:36:13 +1100 (AEDT) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Received: from ozlabs.org (ozlabs.org [IPv6:2401:3900:2:1::2]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 5E78F1A0631 for ; Wed, 11 Mar 2015 17:35:14 +1100 (AEDT) Received: by ozlabs.org (Postfix) id 481F5140172; Wed, 11 Mar 2015 17:35:14 +1100 (AEDT) Delivered-To: linuxppc-dev@ozlabs.org Received: from e23smtp03.au.ibm.com (e23smtp03.au.ibm.com [202.81.31.145]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 2ADC914016A for ; Wed, 11 Mar 2015 17:35:14 +1100 (AEDT) Received: from /spool/local by e23smtp03.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 11 Mar 2015 16:35:13 +1000 Received: from d23dlp03.au.ibm.com (202.81.31.214) by e23smtp03.au.ibm.com (202.81.31.209) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 11 Mar 2015 16:35:11 +1000 Received: from d23relay10.au.ibm.com (d23relay10.au.ibm.com [9.190.26.77]) by d23dlp03.au.ibm.com (Postfix) with ESMTP id 161853578048 for ; Wed, 11 Mar 2015 17:35:11 +1100 (EST) Received: from d23av01.au.ibm.com (d23av01.au.ibm.com [9.190.234.96]) by d23relay10.au.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id t2B6Z27240370388 for ; Wed, 11 Mar 2015 17:35:11 +1100 Received: from d23av01.au.ibm.com (localhost [127.0.0.1]) by d23av01.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id t2B6YbJL024887 for ; Wed, 11 Mar 2015 17:34:37 +1100 Received: from ozlabs.au.ibm.com (ozlabs.au.ibm.com [9.192.253.14]) by d23av01.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id t2B6Yb5V024364; Wed, 11 Mar 2015 17:34:37 +1100 Received: from bran.ozlabs.ibm.com (haven.au.ibm.com [9.192.253.15]) by ozlabs.au.ibm.com (Postfix) with ESMTP id DDA61A011C; Wed, 11 Mar 2015 17:34:13 +1100 (AEDT) Received: from shangw (shangw.ozlabs.ibm.com [10.61.2.199]) by bran.ozlabs.ibm.com (Postfix) with ESMTP id 7758616A9C4; Wed, 11 Mar 2015 17:34:13 +1100 (AEDT) Received: by shangw (Postfix, from userid 1000) id 52A893E02AC; Wed, 11 Mar 2015 17:34:13 +1100 (EST) From: Gavin Shan To: linuxppc-dev@ozlabs.org Subject: [PATCH 2/2] drivers/vfio: Support EEH error injection Date: Wed, 11 Mar 2015 17:34:11 +1100 Message-Id: <1426055651-22925-2-git-send-email-gwshan@linux.vnet.ibm.com> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1426055651-22925-1-git-send-email-gwshan@linux.vnet.ibm.com> References: <1426055651-22925-1-git-send-email-gwshan@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15031106-0009-0000-0000-00000109DB88 Cc: kvm@vger.kernel.org, aik@ozlabs.ru, Gavin Shan , agraf@suse.de, alex.williamson@redhat.com, david@gibson.dropbear.id.au X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" The patch adds one more EEH sub-command (VFIO_EEH_PE_INJECT_ERR) to inject the specified EEH error, which is represented by (struct vfio_eeh_pe_err), to the indicated PE for testing purpose. Signed-off-by: Gavin Shan --- Documentation/vfio.txt | 47 ++++++++++++++++++++++++++++++------------- drivers/vfio/vfio_spapr_eeh.c | 14 +++++++++++++ include/uapi/linux/vfio.h | 34 ++++++++++++++++++++++++++++++- 3 files changed, 80 insertions(+), 15 deletions(-) diff --git a/Documentation/vfio.txt b/Documentation/vfio.txt index 96978ec..2e7f736 100644 --- a/Documentation/vfio.txt +++ b/Documentation/vfio.txt @@ -328,7 +328,13 @@ So 4 additional ioctls have been added: The code flow from the example above should be slightly changed: - struct vfio_eeh_pe_op pe_op = { .argsz = sizeof(pe_op), .flags = 0 }; + struct vfio_eeh_pe_op *pe_op; + struct vfio_eeh_pe_err *pe_err; + + pe_op = malloc(sizeof(*pe_op) + sizeof(*pe_err)); + pe_err = (void *)pe_op + sizeof(*pe_op); + pe_op->argsz = sizeof(*pe_op) + sizeof(*pe_err); + pe_op->flags = 0; ..... /* Add the group to the container */ @@ -367,8 +373,8 @@ The code flow from the example above should be slightly changed: ioctl(container, VFIO_CHECK_EXTENSION, VFIO_EEH); /* Enable the EEH functionality on the device */ - pe_op.op = VFIO_EEH_PE_ENABLE; - ioctl(container, VFIO_EEH_PE_OP, &pe_op); + pe_op->op = VFIO_EEH_PE_ENABLE; + ioctl(container, VFIO_EEH_PE_OP, pe_op); /* You're suggested to create additional data struct to represent * PE, and put child devices belonging to same IOMMU group to the @@ -376,8 +382,8 @@ The code flow from the example above should be slightly changed: */ /* Check the PE's state and make sure it's in functional state */ - pe_op.op = VFIO_EEH_PE_GET_STATE; - ioctl(container, VFIO_EEH_PE_OP, &pe_op); + pe_op->op = VFIO_EEH_PE_GET_STATE; + ioctl(container, VFIO_EEH_PE_OP, pe_op); /* Save device state using pci_save_state(). * EEH should be enabled on the specified device. @@ -385,11 +391,24 @@ The code flow from the example above should be slightly changed: .... + /* Inject EEH error, which is expected to be caused by 32-bits + * config load. + */ + pe_err->type = VFIO_EEH_ERR_TYPE_32; + pe_err->func = VFIO_EEH_ERR_FUNC_LD_CFG_ADDR; + pe_err->addr = 0ul; + pe_err->mask = 0ul; + pe_op->op = VFIO_EEH_PE_INJECT_ERR; + ioctl(container, VFIO_EEH_PE_OP, pe_op); + + .... + /* When 0xFF's returned from reading PCI config space or IO BARs * of the PCI device. Check the PE's state to see if that has been * frozen. */ - ioctl(container, VFIO_EEH_PE_OP, &pe_op); + pe_op->op = VFIO_EEH_PE_GET_STATE; + ioctl(container, VFIO_EEH_PE_OP, pe_op); /* Waiting for pending PCI transactions to be completed and don't * produce any more PCI traffic from/to the affected PE until @@ -400,22 +419,22 @@ The code flow from the example above should be slightly changed: * standard part of PCI config space, AER registers are dumped * as logs for further analysis. */ - pe_op.op = VFIO_EEH_PE_UNFREEZE_IO; - ioctl(container, VFIO_EEH_PE_OP, &pe_op); + pe_op->op = VFIO_EEH_PE_UNFREEZE_IO; + ioctl(container, VFIO_EEH_PE_OP, pe_op); /* * Issue PE reset: hot or fundamental reset. Usually, hot reset * is enough. However, the firmware of some PCI adapters would * require fundamental reset. */ - pe_op.op = VFIO_EEH_PE_RESET_HOT; - ioctl(container, VFIO_EEH_PE_OP, &pe_op); - pe_op.op = VFIO_EEH_PE_RESET_DEACTIVATE; - ioctl(container, VFIO_EEH_PE_OP, &pe_op); + pe_op->op = VFIO_EEH_PE_RESET_HOT; + ioctl(container, VFIO_EEH_PE_OP, pe_op); + pe_op->op = VFIO_EEH_PE_RESET_DEACTIVATE; + ioctl(container, VFIO_EEH_PE_OP, pe_op); /* Configure the PCI bridges for the affected PE */ - pe_op.op = VFIO_EEH_PE_CONFIGURE; - ioctl(container, VFIO_EEH_PE_OP, &pe_op); + pe_op->op = VFIO_EEH_PE_CONFIGURE; + ioctl(container, VFIO_EEH_PE_OP, pe_op); /* Restored state we saved at initialization time. pci_restore_state() * is good enough as an example. diff --git a/drivers/vfio/vfio_spapr_eeh.c b/drivers/vfio/vfio_spapr_eeh.c index 5fa42db..4f1ebc1 100644 --- a/drivers/vfio/vfio_spapr_eeh.c +++ b/drivers/vfio/vfio_spapr_eeh.c @@ -85,6 +85,20 @@ long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group, case VFIO_EEH_PE_CONFIGURE: ret = eeh_pe_configure(pe); break; + case VFIO_EEH_PE_INJECT_ERR: { + struct vfio_eeh_pe_err err; + + if (op.argsz < minsz + sizeof(err)) + return -EINVAL; + if (copy_from_user(&err, + (void __user *)(arg + minsz), + sizeof(err))) + return -EFAULT; + + ret = eeh_pe_inject_err(pe, err.type, err.func, + err.addr, err.mask); + break; + } default: ret = -EINVAL; } diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h index 82889c3..0b32422 100644 --- a/include/uapi/linux/vfio.h +++ b/include/uapi/linux/vfio.h @@ -468,12 +468,21 @@ struct vfio_iommu_spapr_tce_info { * - unfreeze IO/DMA for frozen PE; * - read PE state; * - reset PE; - * - configure PE. + * - configure PE; + * - inject EEH error. */ +struct vfio_eeh_pe_err { + __u32 type; + __u32 func; + __u64 addr; + __u64 mask; +}; + struct vfio_eeh_pe_op { __u32 argsz; __u32 flags; __u32 op; + __u8 data[]; }; #define VFIO_EEH_PE_DISABLE 0 /* Disable EEH functionality */ @@ -490,6 +499,29 @@ struct vfio_eeh_pe_op { #define VFIO_EEH_PE_RESET_HOT 6 /* Assert hot reset */ #define VFIO_EEH_PE_RESET_FUNDAMENTAL 7 /* Assert fundamental reset */ #define VFIO_EEH_PE_CONFIGURE 8 /* PE configuration */ +#define VFIO_EEH_PE_INJECT_ERR 9 /* Inject EEH error */ +#define VFIO_EEH_ERR_TYPE_32 0 /* 32-bits EEH error type */ +#define VFIO_EEH_ERR_TYPE_64 1 /* 64-bits EEH error type */ +#define VFIO_EEH_ERR_FUNC_LD_MEM_ADDR 0 /* Memory load */ +#define VFIO_EEH_ERR_FUNC_LD_MEM_DATA 1 +#define VFIO_EEH_ERR_FUNC_LD_IO_ADDR 2 /* IO load */ +#define VFIO_EEH_ERR_FUNC_LD_IO_DATA 3 +#define VFIO_EEH_ERR_FUNC_LD_CFG_ADDR 4 /* Config load */ +#define VFIO_EEH_ERR_FUNC_LD_CFG_DATA 5 +#define VFIO_EEH_ERR_FUNC_ST_MEM_ADDR 6 /* Memory store */ +#define VFIO_EEH_ERR_FUNC_ST_MEM_DATA 7 +#define VFIO_EEH_ERR_FUNC_ST_IO_ADDR 8 /* IO store */ +#define VFIO_EEH_ERR_FUNC_ST_IO_DATA 9 +#define VFIO_EEH_ERR_FUNC_ST_CFG_ADDR 10 /* Config store */ +#define VFIO_EEH_ERR_FUNC_ST_CFG_DATA 11 +#define VFIO_EEH_ERR_FUNC_DMA_RD_ADDR 12 /* DMA read */ +#define VFIO_EEH_ERR_FUNC_DMA_RD_DATA 13 +#define VFIO_EEH_ERR_FUNC_DMA_RD_MASTER 14 +#define VFIO_EEH_ERR_FUNC_DMA_RD_TARGET 15 +#define VFIO_EEH_ERR_FUNC_DMA_WR_ADDR 16 /* DMA write */ +#define VFIO_EEH_ERR_FUNC_DMA_WR_DATA 17 +#define VFIO_EEH_ERR_FUNC_DMA_WR_MASTER 18 +#define VFIO_EEH_ERR_FUNC_DMA_WR_TARGET 19 #define VFIO_EEH_PE_OP _IO(VFIO_TYPE, VFIO_BASE + 21)