qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v16 09/14] add check reset mechanism when hotplu


From: Marcel Apfelbaum
Subject: Re: [Qemu-devel] [PATCH v16 09/14] add check reset mechanism when hotplug vfio device
Date: Mon, 18 Jan 2016 13:03:24 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0

On 01/12/2016 04:43 AM, Cao jin wrote:
From: Chen Fan <address@hidden>

Since we support multi-function hotplug. the function 0 indicate

I think you wanted , instead of ., also I would suggest
"..., function 0 indicates..."

the closure of the slot, so we have the chance to do the check.

Signed-off-by: Chen Fan <address@hidden>
---
  hw/pci/pci.c             | 29 +++++++++++++++++++++++++++++
  hw/vfio/pci.c            | 19 +++++++++++++++++++
  hw/vfio/pci.h            |  2 ++
  include/hw/pci/pci_bus.h |  5 +++++
  4 files changed, 55 insertions(+)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 168b9cc..f6ca6ef 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -81,6 +81,7 @@ static void pci_bus_realize(BusState *qbus, Error **errp)
      PCIBus *bus = PCI_BUS(qbus);

      vmstate_register(NULL, -1, &vmstate_pcibus, bus);
+    notifier_with_return_list_init(&bus->hotplug_notifiers);
  }

  static void pci_bus_unrealize(BusState *qbus, Error **errp)
@@ -1835,6 +1836,22 @@ PCIDevice *pci_find_device(PCIBus *bus, int bus_num, 
uint8_t devfn)
      return bus->devices[devfn];
  }

+void pci_bus_add_hotplug_notifier(PCIBus *bus, NotifierWithReturn *notify)
+{
+    notifier_with_return_list_add(&bus->hotplug_notifiers, notify);
+}
+
+void pci_bus_remove_hotplug_notifier(NotifierWithReturn *notifier)
+{
+    notifier_with_return_remove(notifier);
+}
+
+static int pci_bus_hotplug_notifier(PCIBus *bus, void *opaque)

Maybe  pci_bus_hotplug_notify instead of pci_bus_hotplug_notifier


Thanks,
Marcel

+{
+    return notifier_with_return_list_notify(&bus->hotplug_notifiers,
+                                            opaque);
+}
+
  static void pci_qdev_realize(DeviceState *qdev, Error **errp)
  {
      PCIDevice *pci_dev = (PCIDevice *)qdev;
@@ -1877,6 +1894,18 @@ static void pci_qdev_realize(DeviceState *qdev, Error 
**errp)
          pci_qdev_unrealize(DEVICE(pci_dev), NULL);
          return;
      }
+
+    /*
+     *  If the function is func 0, indicate the closure of the slot.
+     *  signal the callback.
+     */
+    if (DEVICE(pci_dev)->hotplugged &&
+        pci_get_function_0(pci_dev) == pci_dev &&
+        pci_bus_hotplug_notifier(bus, pci_dev)) {
+        error_setg(errp, "failed to hotplug function 0");
+        pci_qdev_unrealize(DEVICE(pci_dev), NULL);
+        return;
+    }
  }

  static void pci_default_realize(PCIDevice *dev, Error **errp)
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 16ab0e3..ff25c9b 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2044,6 +2044,19 @@ static int vfio_check_devices_host_bus_reset(void)
      return 0;
  }

+static int vfio_check_bus_reset(NotifierWithReturn *n, void *opaque)
+{
+    VFIOPCIDevice *vdev = container_of(n, VFIOPCIDevice, hotplug_notifier);
+    PCIDevice *pci_dev = PCI_DEVICE(vdev);
+    PCIDevice *pci_func0 = opaque;
+
+    if (pci_get_function_0(pci_dev) != pci_func0) {
+        return 0;
+    }
+
+    return vfio_check_host_bus_reset(vdev);
+}
+
  static int vfio_setup_aer(VFIOPCIDevice *vdev, uint8_t cap_ver,
                            int pos, uint16_t size)
  {
@@ -2091,6 +2104,9 @@ static int vfio_setup_aer(VFIOPCIDevice *vdev, uint8_t 
cap_ver,
          pdev->exp.aer_log.log_max = 0;
      }

+    vdev->hotplug_notifier.notify = vfio_check_bus_reset;
+    pci_bus_add_hotplug_notifier(pdev->bus, &vdev->hotplug_notifier);
+
      pcie_cap_deverr_init(pdev);
      return pcie_aer_init(pdev, pos, size);

@@ -2972,6 +2988,9 @@ static void vfio_exitfn(PCIDevice *pdev)
      vfio_unregister_req_notifier(vdev);
      vfio_unregister_err_notifier(vdev);
      pci_device_set_intx_routing_notifier(&vdev->pdev, NULL);
+    if (vdev->features & VFIO_FEATURE_ENABLE_AER) {
+        pci_bus_remove_hotplug_notifier(&vdev->hotplug_notifier);
+    }
      vfio_disable_interrupts(vdev);
      if (vdev->intx.mmap_timer) {
          timer_free(vdev->intx.mmap_timer);
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index 59ae194..b385f07 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -142,6 +142,8 @@ typedef struct VFIOPCIDevice {
      bool no_kvm_intx;
      bool no_kvm_msi;
      bool no_kvm_msix;
+
+    NotifierWithReturn hotplug_notifier;
  } VFIOPCIDevice;

  uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len);
diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
index 403fec6..7812fa9 100644
--- a/include/hw/pci/pci_bus.h
+++ b/include/hw/pci/pci_bus.h
@@ -39,8 +39,13 @@ struct PCIBus {
         Keep a count of the number of devices with raised IRQs.  */
      int nirq;
      int *irq_count;
+
+    NotifierWithReturnList hotplug_notifiers;
  };

+void pci_bus_add_hotplug_notifier(PCIBus *bus, NotifierWithReturn *notify);
+void pci_bus_remove_hotplug_notifier(NotifierWithReturn *notify);
+
  typedef struct PCIBridgeWindows PCIBridgeWindows;

  /*





reply via email to

[Prev in Thread] Current Thread [Next in Thread]