From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58046) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YOfhD-00030P-9g for qemu-devel@nongnu.org; Fri, 20 Feb 2015 00:00:16 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YOfh1-0002P1-94 for qemu-devel@nongnu.org; Fri, 20 Feb 2015 00:00:11 -0500 Received: from e23smtp09.au.ibm.com ([202.81.31.142]:58502) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YOfh0-0002Oc-HF for qemu-devel@nongnu.org; Thu, 19 Feb 2015 23:59:59 -0500 Received: from /spool/local by e23smtp09.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 20 Feb 2015 14:59:55 +1000 From: Gavin Shan Date: Fri, 20 Feb 2015 15:58:53 +1100 Message-Id: <1424408333-26548-3-git-send-email-gwshan@linux.vnet.ibm.com> In-Reply-To: <1424408333-26548-1-git-send-email-gwshan@linux.vnet.ibm.com> References: <1424408333-26548-1-git-send-email-gwshan@linux.vnet.ibm.com> Subject: [Qemu-devel] [PATCH v19 2/2] sPAPR: Implement sPAPRPHBClass EEH callbacks List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: aik@ozlabs.ru, mdroth@linux.vnet.ibm.com, agraf@suse.de, alex.williamson@redhat.com, qemu-ppc@nongnu.org, Gavin Shan , david@gibson.dropbear.id.au The patch implements sPAPRPHBClass EEH callbacks so that the EEH RTAS requests can be routed to VFIO for further handling. Signed-off-by: Gavin Shan Reviewed-by: David Gibson --- hw/ppc/spapr_pci_vfio.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++ hw/vfio/common.c | 1 + 2 files changed, 116 insertions(+) diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c index 144912b..99a1be5 100644 --- a/hw/ppc/spapr_pci_vfio.c +++ b/hw/ppc/spapr_pci_vfio.c @@ -76,6 +76,117 @@ static void spapr_phb_vfio_reset(DeviceState *qdev) /* Do nothing */ } +static int spapr_phb_vfio_eeh_set_option(sPAPRPHBState *sphb, + unsigned int addr, int option) +{ + sPAPRPHBVFIOState *svphb = SPAPR_PCI_VFIO_HOST_BRIDGE(sphb); + struct vfio_eeh_pe_op op = { .argsz = sizeof(op) }; + int ret; + + switch (option) { + case RTAS_EEH_DISABLE: + op.op = VFIO_EEH_PE_DISABLE; + break; + case RTAS_EEH_ENABLE: { + PCIHostState *phb; + PCIDevice *pdev; + + /* + * The EEH functionality is enabled on basis of PCI device, + * instead of PE. We need check the validity of the PCI + * device address. + */ + phb = PCI_HOST_BRIDGE(sphb); + pdev = pci_find_device(phb->bus, + (addr >> 16) & 0xFF, (addr >> 8) & 0xFF); + if (!pdev) { + return RTAS_OUT_PARAM_ERROR; + } + + op.op = VFIO_EEH_PE_ENABLE; + break; + } + case RTAS_EEH_THAW_IO: + op.op = VFIO_EEH_PE_UNFREEZE_IO; + break; + case RTAS_EEH_THAW_DMA: + op.op = VFIO_EEH_PE_UNFREEZE_DMA; + break; + default: + return RTAS_OUT_PARAM_ERROR; + } + + ret = vfio_container_ioctl(&svphb->phb.iommu_as, svphb->iommugroupid, + VFIO_EEH_PE_OP, &op); + if (ret < 0) { + return RTAS_OUT_HW_ERROR; + } + + return RTAS_OUT_SUCCESS; +} + +static int spapr_phb_vfio_eeh_get_state(sPAPRPHBState *sphb, int *state) +{ + sPAPRPHBVFIOState *svphb = SPAPR_PCI_VFIO_HOST_BRIDGE(sphb); + struct vfio_eeh_pe_op op = { .argsz = sizeof(op) }; + int ret; + + op.op = VFIO_EEH_PE_GET_STATE; + ret = vfio_container_ioctl(&svphb->phb.iommu_as, svphb->iommugroupid, + VFIO_EEH_PE_OP, &op); + if (ret < 0) { + return RTAS_OUT_PARAM_ERROR; + } + + *state = ret; + return RTAS_OUT_SUCCESS; +} + +static int spapr_phb_vfio_eeh_reset(sPAPRPHBState *sphb, int option) +{ + sPAPRPHBVFIOState *svphb = SPAPR_PCI_VFIO_HOST_BRIDGE(sphb); + struct vfio_eeh_pe_op op = { .argsz = sizeof(op) }; + int ret; + + switch (option) { + case RTAS_SLOT_RESET_DEACTIVATE: + op.op = VFIO_EEH_PE_RESET_DEACTIVATE; + break; + case RTAS_SLOT_RESET_HOT: + op.op = VFIO_EEH_PE_RESET_HOT; + break; + case RTAS_SLOT_RESET_FUNDAMENTAL: + op.op = VFIO_EEH_PE_RESET_FUNDAMENTAL; + break; + default: + return RTAS_OUT_PARAM_ERROR; + } + + ret = vfio_container_ioctl(&svphb->phb.iommu_as, svphb->iommugroupid, + VFIO_EEH_PE_OP, &op); + if (ret < 0) { + return RTAS_OUT_HW_ERROR; + } + + return RTAS_OUT_SUCCESS; +} + +static int spapr_phb_vfio_eeh_configure(sPAPRPHBState *sphb) +{ + sPAPRPHBVFIOState *svphb = SPAPR_PCI_VFIO_HOST_BRIDGE(sphb); + struct vfio_eeh_pe_op op = { .argsz = sizeof(op) }; + int ret; + + op.op = VFIO_EEH_PE_CONFIGURE; + ret = vfio_container_ioctl(&svphb->phb.iommu_as, svphb->iommugroupid, + VFIO_EEH_PE_OP, &op); + if (ret < 0) { + return RTAS_OUT_PARAM_ERROR; + } + + return RTAS_OUT_SUCCESS; +} + static void spapr_phb_vfio_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -84,6 +195,10 @@ static void spapr_phb_vfio_class_init(ObjectClass *klass, void *data) dc->props = spapr_phb_vfio_properties; dc->reset = spapr_phb_vfio_reset; spc->finish_realize = spapr_phb_vfio_finish_realize; + spc->eeh_set_option = spapr_phb_vfio_eeh_set_option; + spc->eeh_get_state = spapr_phb_vfio_eeh_get_state; + spc->eeh_reset = spapr_phb_vfio_eeh_reset; + spc->eeh_configure = spapr_phb_vfio_eeh_configure; } static const TypeInfo spapr_phb_vfio_info = { diff --git a/hw/vfio/common.c b/hw/vfio/common.c index e71385e..50cd19f 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -948,6 +948,7 @@ int vfio_container_ioctl(AddressSpace *as, int32_t groupid, switch (req) { case VFIO_CHECK_EXTENSION: case VFIO_IOMMU_SPAPR_TCE_GET_INFO: + case VFIO_EEH_PE_OP: break; default: /* Return an error on unknown requests */ -- 1.8.3.2