[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-arm] [RFC v4 26/27] vfio-pci: Set up fault regions
From: |
Eric Auger |
Subject: |
[Qemu-arm] [RFC v4 26/27] vfio-pci: Set up fault regions |
Date: |
Mon, 27 May 2019 13:42:02 +0200 |
We setup two fault regions: the producer fault is read-only from the
user space perspective. It is composed of the fault queue (mmappable)
and a header written by the kernel, located in a separate page.
The consumer fault is write-only from the user-space perspective.
Signed-off-by: Eric Auger <address@hidden>
---
---
hw/vfio/pci.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++
hw/vfio/pci.h | 2 ++
2 files changed, 101 insertions(+)
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 29d4f633b0..8208171f92 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2505,11 +2505,100 @@ int vfio_populate_vga(VFIOPCIDevice *vdev, Error
**errp)
return 0;
}
+static void vfio_init_fault_regions(VFIOPCIDevice *vdev, Error **errp)
+{
+ struct vfio_region_info *fault_region_info = NULL;
+ struct vfio_region_info_cap_fault *cap_fault;
+ VFIODevice *vbasedev = &vdev->vbasedev;
+ struct vfio_info_cap_header *hdr;
+ char *fault_region_name = NULL;
+ uint32_t max_version;
+ ssize_t bytes;
+ int ret;
+
+ /* Producer Fault Region */
+ ret = vfio_get_dev_region_info(&vdev->vbasedev,
+ VFIO_REGION_TYPE_NESTED,
+ VFIO_REGION_SUBTYPE_NESTED_FAULT_PROD,
+ &fault_region_info);
+ if (!ret) {
+ hdr = vfio_get_region_info_cap(fault_region_info,
+ VFIO_REGION_INFO_CAP_PRODUCER_FAULT);
+ if (!hdr) {
+ error_setg(errp, "failed to retrieve fault ABI max version");
+ g_free(fault_region_info);
+ return;
+ }
+ cap_fault = container_of(hdr, struct vfio_region_info_cap_fault,
+ header);
+ max_version = cap_fault->version;
+
+ fault_region_name = g_strdup_printf("%s FAULT PROD %d",
+ vbasedev->name,
+ fault_region_info->index);
+
+ ret = vfio_region_setup(OBJECT(vdev), vbasedev,
+ &vdev->fault_prod_region,
+ fault_region_info->index,
+ fault_region_name);
+ if (ret) {
+ error_setg_errno(errp, -ret,
+ "failed to setup the fault prod region %d",
+ fault_region_info->index);
+ goto out;
+ }
+
+ ret = vfio_region_mmap(&vdev->fault_prod_region);
+ if (ret) {
+ error_report("Failed to mmap fault queue(%d)", ret);
+ }
+
+ g_free(fault_region_info);
+ g_free(fault_region_name);
+ } else {
+ goto out;
+ }
+
+ /* Consumer Fault Region */
+ ret = vfio_get_dev_region_info(&vdev->vbasedev,
+ VFIO_REGION_TYPE_NESTED,
+ VFIO_REGION_SUBTYPE_NESTED_FAULT_CONS,
+ &fault_region_info);
+ if (!ret) {
+ fault_region_name = g_strdup_printf("%s FAULT CONS %d",
+ vbasedev->name,
+ fault_region_info->index);
+
+ ret = vfio_region_setup(OBJECT(vdev), vbasedev,
+ &vdev->fault_cons_region,
+ fault_region_info->index,
+ fault_region_name);
+ if (ret) {
+ error_setg_errno(errp, -ret,
+ "failed to setup the fault cons region %d",
+ fault_region_info->index);
+ }
+
+ /* Set the chosen fault ABI version in the consume header*/
+ bytes = pwrite(vdev->vbasedev.fd, &max_version, 4,
+ vdev->fault_cons_region.fd_offset);
+ if (bytes != 4) {
+ error_setg(errp,
+ "Unable to set the chosen fault ABI version (%d)",
+ max_version);
+ }
+ }
+out:
+ g_free(fault_region_name);
+ g_free(fault_region_info);
+}
+
static void vfio_populate_device(VFIOPCIDevice *vdev, Error **errp)
{
VFIODevice *vbasedev = &vdev->vbasedev;
struct vfio_region_info *reg_info;
struct vfio_irq_info irq_info = { .argsz = sizeof(irq_info) };
+ Error *err = NULL;
int i, ret = -1;
/* Sanity check device */
@@ -2573,6 +2662,12 @@ static void vfio_populate_device(VFIOPCIDevice *vdev,
Error **errp)
}
}
+ vfio_init_fault_regions(vdev, &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+
irq_info.index = VFIO_PCI_ERR_IRQ_INDEX;
ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_IRQ_INFO, &irq_info);
@@ -3105,6 +3200,8 @@ static void vfio_instance_finalize(Object *obj)
vfio_display_finalize(vdev);
vfio_bars_finalize(vdev);
+ vfio_region_finalize(&vdev->fault_prod_region);
+ vfio_region_finalize(&vdev->fault_cons_region);
g_free(vdev->emulated_config_bits);
g_free(vdev->rom);
/*
@@ -3125,6 +3222,8 @@ static void vfio_exitfn(PCIDevice *pdev)
vfio_unregister_req_notifier(vdev);
vfio_unregister_err_notifier(vdev);
vfio_unregister_dma_fault_notifier(vdev);
+ vfio_region_exit(&vdev->fault_prod_region);
+ vfio_region_exit(&vdev->fault_cons_region);
pci_device_set_intx_routing_notifier(&vdev->pdev, NULL);
vfio_disable_interrupts(vdev);
if (vdev->intx.mmap_timer) {
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index 96d29d667b..ee64081b47 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -136,6 +136,8 @@ typedef struct VFIOPCIDevice {
EventNotifier err_notifier;
EventNotifier req_notifier;
EventNotifier dma_fault_notifier;
+ VFIORegion fault_prod_region;
+ VFIORegion fault_cons_region;
int (*resetfn)(struct VFIOPCIDevice *);
uint32_t vendor_id;
uint32_t device_id;
--
2.20.1
- [Qemu-arm] [RFC v4 14/27] hw/arm/smmuv3: Fill the IOTLBEntry arch_id on NH_VA invalidation, (continued)
- [Qemu-arm] [RFC v4 14/27] hw/arm/smmuv3: Fill the IOTLBEntry arch_id on NH_VA invalidation, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 15/27] hw/arm/smmuv3: Fill the IOTLBEntry leaf field on NH_VA invalidation, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 16/27] hw/arm/smmuv3: Notify on config changes, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 17/27] hw/vfio/common: Introduce vfio_alloc_guest_iommu helper, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 18/27] hw/vfio/common: Introduce hostwin_from_range helper, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 19/27] hw/vfio/common: Introduce helpers to DMA map/unmap a RAM section, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 20/27] hw/vfio/common: Setup nested stage mappings, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 21/27] hw/vfio/common: Register a MAP notifier for MSI binding, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 22/27] vfio-pci: Expose MSI stage 1 bindings to the host, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 23/27] memory: Introduce IOMMU Memory Region inject_faults API, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 26/27] vfio-pci: Set up fault regions,
Eric Auger <=
- [Qemu-arm] [RFC v4 27/27] vfio-pci: Implement the DMA fault handler, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 24/27] hw/arm/smmuv3: Implement fault injection, Eric Auger, 2019/05/27
- [Qemu-arm] [RFC v4 25/27] vfio-pci: register handler for iommu fault, Eric Auger, 2019/05/27
- Re: [Qemu-arm] [Qemu-devel] [RFC v4 00/27] vSMMUv3/pSMMUv3 2 stage VFIO integration, no-reply, 2019/05/27