All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [Qemu-devel] Qemu-devel Digest, Vol 137, Issue 266
       [not found] <mailman.109949.1407594386.1146.qemu-devel@nongnu.org>
@ 2014-08-09 14:52 ` Fernando Oliveira
  0 siblings, 0 replies; only message in thread
From: Fernando Oliveira @ 2014-08-09 14:52 UTC (permalink / raw)
  To: qemu-devel, Susan Whittemore Oliveira

[-- Attachment #1: Type: text/plain, Size: 31486 bytes --]

On Aug 9, 2014 10:28 AM, <qemu-devel-request@nongnu.org> wrote:
>
> Send Qemu-devel mailing list submissions to
>         qemu-devel@nongnu.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
>         https://lists.nongnu.orgl/mailman/listinfo/qemu-devel
> or, via email, send a message with subject or body 'help' to
>         qemu-devel-request@nongnu.org
>
> You can reach the person managing the list at
>         qemu-devel-owner@nongnu.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Qemu-devel digest..."
>
> Today's Topics:
>
>    1. [PATCH v5 03/10] hw/vfio/pci: introduce VFIODevice (Eric Auger)
>
>
> ---------- Forwarded message ----------
> From: Eric Auger <eric.auger@linaro.org>
> To: eric.auger@st.com, christoffer.dall@linaro.org, qemu-devel@nongnu.org,
kim.phillips@freescale.com, a.rigo@virtualopensystems.com
> Cc: peter.maydell@linaro.org, eric.auger@linaro.org, patches@linaro.org,
will.deacon@arm.com, agraf@suse.de, stuart.yoder@freescale.com,
Bharat.Bhushan@freescale.com, alex.williamson@redhat.com,
joel.schopp@amd.com, a.motakis@virtualopensystems.com,
kvmarm@lists.cs.columbia.edu
> Date: Sat, 9 Aug 2014 15:25:42 +0100
> Subject: [Qemu-devel] [PATCH v5 03/10] hw/vfio/pci: introduce VFIODevice
> Introduce the VFIODevice struct that is going to be shared by
> VFIOPCIDevice and VFIOPlatformDevice.
>
> Additional fields will be added there later on for review
> convenience.
>
> the group's device_list becomes a list of VFIODevice
>
> This obliges to rework the reset_handler which becomes generic and
> calls VFIODevice ops that are specialized in each parent object.
> Also functions that iterate on this list must take care that the
> devices can be something else than VFIOPCIDevice. The type is used
> to discriminate them.
>
> we profit from this step to change the prototype of
> vfio_unmask_intx, vfio_mask_intx, vfio_disable_irqindex which now
> apply to VFIODevice. They are renamed as *_irqindex.
> The index is passed as parameter to anticipate their usage for
> platform IRQs
>
> Signed-off-by: Eric Auger <eric.auger@linaro.org>
>
> ---
>
> v4->v5:
> - fix style issues
> - in vfio_initfn, rework allocation of vdev->vbasedev.name and
>   replace snprintf by g_strdup_printf
> ---
>  hw/vfio/pci.c | 239
+++++++++++++++++++++++++++++++++++-----------------------
>  1 file changed, 146 insertions(+), 93 deletions(-)
>
> diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
> index c2cdd73..ae827c5 100644
> --- a/hw/vfio/pci.c
> +++ b/hw/vfio/pci.c
> @@ -56,6 +56,11 @@
>  #define VFIO_ALLOW_KVM_MSI 1
>  #define VFIO_ALLOW_KVM_MSIX 1
>
> +enum {
> +    VFIO_DEVICE_TYPE_PCI = 0,
> +    VFIO_DEVICE_TYPE_PLATFORM = 1,
> +};
> +
>  struct VFIOPCIDevice;
>
>  typedef struct VFIOQuirk {
> @@ -193,9 +198,27 @@ typedef struct VFIOMSIXInfo {
>      void *mmap;
>  } VFIOMSIXInfo;
>
> +typedef struct VFIODeviceOps VFIODeviceOps;
> +
> +typedef struct VFIODevice {
> +    QLIST_ENTRY(VFIODevice) next;
> +    struct VFIOGroup *group;
> +    char *name;
> +    int fd;
> +    int type;
> +    bool reset_works;
> +    bool needs_reset;
> +    VFIODeviceOps *ops;
> +} VFIODevice;
> +
> +struct VFIODeviceOps {
> +    bool (*vfio_compute_needs_reset)(VFIODevice *vdev);
> +    int (*vfio_hot_reset_multi)(VFIODevice *vdev);
> +};
> +
>  typedef struct VFIOPCIDevice {
>      PCIDevice pdev;
> -    int fd;
> +    VFIODevice vbasedev;
>      VFIOINTx intx;
>      unsigned int config_size;
>      uint8_t *emulated_config_bits; /* QEMU emulated bits, little-endian
*/
> @@ -211,20 +234,16 @@ typedef struct VFIOPCIDevice {
>      VFIOBAR bars[PCI_NUM_REGIONS - 1]; /* No ROM */
>      VFIOVGA vga; /* 0xa0000, 0x3b0, 0x3c0 */
>      PCIHostDeviceAddress host;
> -    QLIST_ENTRY(VFIOPCIDevice) next;
> -    struct VFIOGroup *group;
>      EventNotifier err_notifier;
>      uint32_t features;
>  #define VFIO_FEATURE_ENABLE_VGA_BIT 0
>  #define VFIO_FEATURE_ENABLE_VGA (1 << VFIO_FEATURE_ENABLE_VGA_BIT)
>      int32_t bootindex;
>      uint8_t pm_cap;
> -    bool reset_works;
>      bool has_vga;
>      bool pci_aer;
>      bool has_flr;
>      bool has_pm_reset;
> -    bool needs_reset;
>      bool rom_read_failed;
>  } VFIOPCIDevice;
>
> @@ -232,7 +251,7 @@ typedef struct VFIOGroup {
>      int fd;
>      int groupid;
>      VFIOContainer *container;
> -    QLIST_HEAD(, VFIOPCIDevice) device_list;
> +    QLIST_HEAD(, VFIODevice) device_list;
>      QLIST_ENTRY(VFIOGroup) next;
>      QLIST_ENTRY(VFIOGroup) container_next;
>  } VFIOGroup;
> @@ -285,7 +304,7 @@ static void vfio_mmap_set_enabled(VFIOPCIDevice
*vdev, bool enabled);
>  /*
>   * Common VFIO interrupt disable
>   */
> -static void vfio_disable_irqindex(VFIOPCIDevice *vdev, int index)
> +static void vfio_disable_irqindex(VFIODevice *vbasedev, int index)
>  {
>      struct vfio_irq_set irq_set = {
>          .argsz = sizeof(irq_set),
> @@ -295,37 +314,37 @@ static void vfio_disable_irqindex(VFIOPCIDevice
*vdev, int index)
>          .count = 0,
>      };
>
> -    ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, &irq_set);
> +    ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, &irq_set);
>  }
>
>  /*
>   * INTx
>   */
> -static void vfio_unmask_intx(VFIOPCIDevice *vdev)
> +static void vfio_unmask_irqindex(VFIODevice *vbasedev, int index)
>  {
>      struct vfio_irq_set irq_set = {
>          .argsz = sizeof(irq_set),
>          .flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_UNMASK,
> -        .index = VFIO_PCI_INTX_IRQ_INDEX,
> +        .index = index,
>          .start = 0,
>          .count = 1,
>      };
>
> -    ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, &irq_set);
> +    ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, &irq_set);
>  }
>
>  #ifdef CONFIG_KVM /* Unused outside of CONFIG_KVM code */
> -static void vfio_mask_intx(VFIOPCIDevice *vdev)
> +static void vfio_mask_irqindex(VFIODevice *vbasedev, int index)
>  {
>      struct vfio_irq_set irq_set = {
>          .argsz = sizeof(irq_set),
>          .flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_MASK,
> -        .index = VFIO_PCI_INTX_IRQ_INDEX,
> +        .index = index,
>          .start = 0,
>          .count = 1,
>      };
>
> -    ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, &irq_set);
> +    ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, &irq_set);
>  }
>  #endif
>
> @@ -389,7 +408,7 @@ static void vfio_eoi(VFIOPCIDevice *vdev)
>
>      vdev->intx.pending = false;
>      pci_irq_deassert(&vdev->pdev);
> -    vfio_unmask_intx(vdev);
> +    vfio_unmask_irqindex(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX);
>  }
>
>  static void vfio_enable_intx_kvm(VFIOPCIDevice *vdev)
> @@ -412,7 +431,7 @@ static void vfio_enable_intx_kvm(VFIOPCIDevice *vdev)
>
>      /* Get to a known interrupt state */
>      qemu_set_fd_handler(irqfd.fd, NULL, NULL, vdev);
> -    vfio_mask_intx(vdev);
> +    vfio_mask_irqindex(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX);
>      vdev->intx.pending = false;
>      pci_irq_deassert(&vdev->pdev);
>
> @@ -442,7 +461,7 @@ static void vfio_enable_intx_kvm(VFIOPCIDevice *vdev)
>
>      *pfd = irqfd.resamplefd;
>
> -    ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
> +    ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set);
>      g_free(irq_set);
>      if (ret) {
>          error_report("vfio: Error: Failed to setup INTx unmask fd: %m");
> @@ -450,7 +469,7 @@ static void vfio_enable_intx_kvm(VFIOPCIDevice *vdev)
>      }
>
>      /* Let'em rip */
> -    vfio_unmask_intx(vdev);
> +    vfio_unmask_irqindex(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX);
>
>      vdev->intx.kvm_accel = true;
>
> @@ -467,7 +486,7 @@ fail_irqfd:
>      event_notifier_cleanup(&vdev->intx.unmask);
>  fail:
>      qemu_set_fd_handler(irqfd.fd, vfio_intx_interrupt, NULL, vdev);
> -    vfio_unmask_intx(vdev);
> +    vfio_unmask_irqindex(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX);
>  #endif
>  }
>
> @@ -488,7 +507,7 @@ static void vfio_disable_intx_kvm(VFIOPCIDevice *vdev)
>       * Get to a known state, hardware masked, QEMU ready to accept new
>       * interrupts, QEMU IRQ de-asserted.
>       */
> -    vfio_mask_intx(vdev);
> +    vfio_mask_irqindex(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX);
>      vdev->intx.pending = false;
>      pci_irq_deassert(&vdev->pdev);
>
> @@ -506,7 +525,7 @@ static void vfio_disable_intx_kvm(VFIOPCIDevice *vdev)
>      vdev->intx.kvm_accel = false;
>
>      /* If we've missed an event, let it re-fire through QEMU */
> -    vfio_unmask_intx(vdev);
> +    vfio_unmask_irqindex(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX);
>
>      DPRINTF("%s(%04x:%02x:%02x.%x) KVM INTx accel disabled\n",
>              __func__, vdev->host.domain, vdev->host.bus,
> @@ -594,7 +613,7 @@ static int vfio_enable_intx(VFIOPCIDevice *vdev)
>      *pfd = event_notifier_get_fd(&vdev->intx.interrupt);
>      qemu_set_fd_handler(*pfd, vfio_intx_interrupt, NULL, vdev);
>
> -    ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
> +    ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set);
>      g_free(irq_set);
>      if (ret) {
>          error_report("vfio: Error: Failed to setup INTx fd: %m");
> @@ -619,7 +638,7 @@ static void vfio_disable_intx(VFIOPCIDevice *vdev)
>
>      timer_del(vdev->intx.mmap_timer);
>      vfio_disable_intx_kvm(vdev);
> -    vfio_disable_irqindex(vdev, VFIO_PCI_INTX_IRQ_INDEX);
> +    vfio_disable_irqindex(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX);
>      vdev->intx.pending = false;
>      pci_irq_deassert(&vdev->pdev);
>      vfio_mmap_set_enabled(vdev, true);
> @@ -709,7 +728,7 @@ static int vfio_enable_vectors(VFIOPCIDevice *vdev,
bool msix)
>          fds[i] = fd;
>      }
>
> -    ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
> +    ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set);
>
>      g_free(irq_set);
>
> @@ -806,7 +825,7 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev,
unsigned int nr,
>       * increase them as needed.
>       */
>      if (vdev->nr_vectors < nr + 1) {
> -        vfio_disable_irqindex(vdev, VFIO_PCI_MSIX_IRQ_INDEX);
> +        vfio_disable_irqindex(&vdev->vbasedev, VFIO_PCI_MSIX_IRQ_INDEX);
>          vdev->nr_vectors = nr + 1;
>          ret = vfio_enable_vectors(vdev, true);
>          if (ret) {
> @@ -834,7 +853,7 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev,
unsigned int nr,
>              *pfd = event_notifier_get_fd(&vector->interrupt);
>          }
>
> -        ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
> +        ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set);
>          g_free(irq_set);
>          if (ret) {
>              error_report("vfio: failed to modify vector, %d", ret);
> @@ -885,7 +904,7 @@ static void vfio_msix_vector_release(PCIDevice *pdev,
unsigned int nr)
>
>          *pfd = event_notifier_get_fd(&vector->interrupt);
>
> -        ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
> +        ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set);
>
>          g_free(irq_set);
>      }
> @@ -1044,7 +1063,7 @@ static void vfio_disable_msix(VFIOPCIDevice *vdev)
>      }
>
>      if (vdev->nr_vectors) {
> -        vfio_disable_irqindex(vdev, VFIO_PCI_MSIX_IRQ_INDEX);
> +        vfio_disable_irqindex(&vdev->vbasedev, VFIO_PCI_MSIX_IRQ_INDEX);
>      }
>
>      vfio_disable_msi_common(vdev);
> @@ -1055,7 +1074,7 @@ static void vfio_disable_msix(VFIOPCIDevice *vdev)
>
>  static void vfio_disable_msi(VFIOPCIDevice *vdev)
>  {
> -    vfio_disable_irqindex(vdev, VFIO_PCI_MSI_IRQ_INDEX);
> +    vfio_disable_irqindex(&vdev->vbasedev, VFIO_PCI_MSI_IRQ_INDEX);
>      vfio_disable_msi_common(vdev);
>
>      DPRINTF("%s(%04x:%02x:%02x.%x)\n", __func__, vdev->host.domain,
> @@ -1201,7 +1220,7 @@ static void vfio_pci_load_rom(VFIOPCIDevice *vdev)
>      off_t off = 0;
>      size_t bytes;
>
> -    if (ioctl(vdev->fd, VFIO_DEVICE_GET_REGION_INFO, &reg_info)) {
> +    if (ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_REGION_INFO,
&reg_info)) {
>          error_report("vfio: Error getting ROM info: %m");
>          return;
>      }
> @@ -1231,7 +1250,8 @@ static void vfio_pci_load_rom(VFIOPCIDevice *vdev)
>      memset(vdev->rom, 0xff, size);
>
>      while (size) {
> -        bytes = pread(vdev->fd, vdev->rom + off, size, vdev->rom_offset
+ off);
> +        bytes = pread(vdev->vbasedev.fd, vdev->rom + off,
> +                      size, vdev->rom_offset + off);
>          if (bytes == 0) {
>              break;
>          } else if (bytes > 0) {
> @@ -1325,6 +1345,7 @@ static void vfio_pci_size_rom(VFIOPCIDevice *vdev)
>      off_t offset = vdev->config_offset + PCI_ROM_ADDRESS;
>      DeviceState *dev = DEVICE(vdev);
>      char name[32];
> +    int fd = vdev->vbasedev.fd;
>
>      if (vdev->pdev.romfile || !vdev->pdev.rom_bar) {
>          /* Since pci handles romfile, just print a message and return */
> @@ -1343,10 +1364,10 @@ static void vfio_pci_size_rom(VFIOPCIDevice *vdev)
>       * Use the same size ROM BAR as the physical device.  The contents
>       * will get filled in later when the guest tries to read it.
>       */
> -    if (pread(vdev->fd, &orig, 4, offset) != 4 ||
> -        pwrite(vdev->fd, &size, 4, offset) != 4 ||
> -        pread(vdev->fd, &size, 4, offset) != 4 ||
> -        pwrite(vdev->fd, &orig, 4, offset) != 4) {
> +    if (pread(fd, &orig, 4, offset) != 4 ||
> +        pwrite(fd, &size, 4, offset) != 4 ||
> +        pread(fd, &size, 4, offset) != 4 ||
> +        pwrite(fd, &orig, 4, offset) != 4) {
>          error_report("%s(%04x:%02x:%02x.%x) failed: %m",
>                       __func__, vdev->host.domain, vdev->host.bus,
>                       vdev->host.slot, vdev->host.function);
> @@ -2330,7 +2351,8 @@ static uint32_t vfio_pci_read_config(PCIDevice
*pdev, uint32_t addr, int len)
>      if (~emu_bits & (0xffffffffU >> (32 - len * 8))) {
>          ssize_t ret;
>
> -        ret = pread(vdev->fd, &phys_val, len, vdev->config_offset +
addr);
> +        ret = pread(vdev->vbasedev.fd, &phys_val, len,
> +                    vdev->config_offset + addr);
>          if (ret != len) {
>              error_report("%s(%04x:%02x:%02x.%x, 0x%x, 0x%x) failed: %m",
>                           __func__, vdev->host.domain, vdev->host.bus,
> @@ -2360,7 +2382,8 @@ static void vfio_pci_write_config(PCIDevice *pdev,
uint32_t addr,
>              vdev->host.function, addr, val, len);
>
>      /* Write everything to VFIO, let it filter out what we can't write */
> -    if (pwrite(vdev->fd, &val_le, len, vdev->config_offset + addr) !=
len) {
> +    if (pwrite(vdev->vbasedev.fd, &val_le, len, vdev->config_offset +
addr)
> +                != len) {
>          error_report("%s(%04x:%02x:%02x.%x, 0x%x, 0x%x, 0x%x) failed:
%m",
>                       __func__, vdev->host.domain, vdev->host.bus,
>                       vdev->host.slot, vdev->host.function, addr, val,
len);
> @@ -2730,7 +2753,7 @@ static int vfio_setup_msi(VFIOPCIDevice *vdev, int
pos)
>      bool msi_64bit, msi_maskbit;
>      int ret, entries;
>
> -    if (pread(vdev->fd, &ctrl, sizeof(ctrl),
> +    if (pread(vdev->vbasedev.fd, &ctrl, sizeof(ctrl),
>                vdev->config_offset + pos + PCI_CAP_FLAGS) !=
sizeof(ctrl)) {
>          return -errno;
>      }
> @@ -2769,23 +2792,24 @@ static int vfio_early_setup_msix(VFIOPCIDevice
*vdev)
>      uint8_t pos;
>      uint16_t ctrl;
>      uint32_t table, pba;
> +    int fd = vdev->vbasedev.fd;
>
>      pos = pci_find_capability(&vdev->pdev, PCI_CAP_ID_MSIX);
>      if (!pos) {
>          return 0;
>      }
>
> -    if (pread(vdev->fd, &ctrl, sizeof(ctrl),
> +    if (pread(fd, &ctrl, sizeof(ctrl),
>                vdev->config_offset + pos + PCI_CAP_FLAGS) !=
sizeof(ctrl)) {
>          return -errno;
>      }
>
> -    if (pread(vdev->fd, &table, sizeof(table),
> +    if (pread(fd, &table, sizeof(table),
>                vdev->config_offset + pos + PCI_MSIX_TABLE) !=
sizeof(table)) {
>          return -errno;
>      }
>
> -    if (pread(vdev->fd, &pba, sizeof(pba),
> +    if (pread(fd, &pba, sizeof(pba),
>                vdev->config_offset + pos + PCI_MSIX_PBA) != sizeof(pba)) {
>          return -errno;
>      }
> @@ -2941,7 +2965,7 @@ static void vfio_map_bar(VFIOPCIDevice *vdev, int
nr)
>               vdev->host.function, nr);
>
>      /* Determine what type of BAR this is for registration */
> -    ret = pread(vdev->fd, &pci_bar, sizeof(pci_bar),
> +    ret = pread(vdev->vbasedev.fd, &pci_bar, sizeof(pci_bar),
>                  vdev->config_offset + PCI_BASE_ADDRESS_0 + (4 * nr));
>      if (ret != sizeof(pci_bar)) {
>          error_report("vfio: Failed to read BAR %d (%m)", nr);
> @@ -3362,12 +3386,12 @@ static int vfio_pci_hot_reset(VFIOPCIDevice
*vdev, bool single)
>              single ? "one" : "multi");
>
>      vfio_pci_pre_reset(vdev);
> -    vdev->needs_reset = false;
> +    vdev->vbasedev.needs_reset = false;
>
>      info = g_malloc0(sizeof(*info));
>      info->argsz = sizeof(*info);
>
> -    ret = ioctl(vdev->fd, VFIO_DEVICE_GET_PCI_HOT_RESET_INFO, info);
> +    ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_PCI_HOT_RESET_INFO,
info);
>      if (ret && errno != ENOSPC) {
>          ret = -errno;
>          if (!vdev->has_pm_reset) {
> @@ -3383,7 +3407,7 @@ static int vfio_pci_hot_reset(VFIOPCIDevice *vdev,
bool single)
>      info->argsz = sizeof(*info) + (count * sizeof(*devices));
>      devices = &info->devices[0];
>
> -    ret = ioctl(vdev->fd, VFIO_DEVICE_GET_PCI_HOT_RESET_INFO, info);
> +    ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_PCI_HOT_RESET_INFO,
info);
>      if (ret) {
>          ret = -errno;
>          error_report("vfio: hot reset info failed: %m");
> @@ -3398,6 +3422,7 @@ static int vfio_pci_hot_reset(VFIOPCIDevice *vdev,
bool single)
>      for (i = 0; i < info->count; i++) {
>          PCIHostDeviceAddress host;
>          VFIOPCIDevice *tmp;
> +        VFIODevice *vbasedev_iter;
>
>          host.domain = devices[i].segment;
>          host.bus = devices[i].bus;
> @@ -3429,7 +3454,11 @@ static int vfio_pci_hot_reset(VFIOPCIDevice *vdev,
bool single)
>          }
>
>          /* Prep dependent devices for reset and clear our marker. */
> -        QLIST_FOREACH(tmp, &group->device_list, next) {
> +        QLIST_FOREACH(vbasedev_iter, &group->device_list, next) {
> +            if (vbasedev_iter->type != VFIO_DEVICE_TYPE_PCI) {
> +                continue;
> +            }
> +            tmp = container_of(vbasedev_iter, VFIOPCIDevice, vbasedev);
>              if (vfio_pci_host_match(&host, &tmp->host)) {
>                  if (single) {
>                      DPRINTF("vfio: found another in-use device "
> @@ -3439,7 +3468,7 @@ static int vfio_pci_hot_reset(VFIOPCIDevice *vdev,
bool single)
>                      goto out_single;
>                  }
>                  vfio_pci_pre_reset(tmp);
> -                tmp->needs_reset = false;
> +                tmp->vbasedev.needs_reset = false;
>                  multi = true;
>                  break;
>              }
> @@ -3478,7 +3507,7 @@ static int vfio_pci_hot_reset(VFIOPCIDevice *vdev,
bool single)
>      }
>
>      /* Bus reset! */
> -    ret = ioctl(vdev->fd, VFIO_DEVICE_PCI_HOT_RESET, reset);
> +    ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_PCI_HOT_RESET, reset);
>      g_free(reset);
>
>      DPRINTF("%04x:%02x:%02x.%x hot reset: %s\n", vdev->host.domain,
> @@ -3490,6 +3519,7 @@ out:
>      for (i = 0; i < info->count; i++) {
>          PCIHostDeviceAddress host;
>          VFIOPCIDevice *tmp;
> +        VFIODevice *vbasedev_iter;
>
>          host.domain = devices[i].segment;
>          host.bus = devices[i].bus;
> @@ -3510,7 +3540,11 @@ out:
>              break;
>          }
>
> -        QLIST_FOREACH(tmp, &group->device_list, next) {
> +        QLIST_FOREACH(vbasedev_iter, &group->device_list, next) {
> +            if (vbasedev_iter->type != VFIO_DEVICE_TYPE_PCI) {
> +                continue;
> +            }
> +            tmp = container_of(vbasedev_iter, VFIOPCIDevice, vbasedev);
>              if (vfio_pci_host_match(&host, &tmp->host)) {
>                  vfio_pci_post_reset(tmp);
>                  break;
> @@ -3544,28 +3578,41 @@ static int vfio_pci_hot_reset_one(VFIOPCIDevice
*vdev)
>      return vfio_pci_hot_reset(vdev, true);
>  }
>
> -static int vfio_pci_hot_reset_multi(VFIOPCIDevice *vdev)
> +static int vfio_pci_hot_reset_multi(VFIODevice *vbasedev)
>  {
> +    VFIOPCIDevice *vdev = container_of(vbasedev, VFIOPCIDevice,
vbasedev);
>      return vfio_pci_hot_reset(vdev, false);
>  }
>
> -static void vfio_pci_reset_handler(void *opaque)
> +static bool vfio_pci_compute_needs_reset(VFIODevice *vbasedev)
> +{
> +    VFIOPCIDevice *vdev = container_of(vbasedev, VFIOPCIDevice,
vbasedev);
> +    if (!vbasedev->reset_works || (!vdev->has_flr &&
vdev->has_pm_reset)) {
> +        vbasedev->needs_reset = true;
> +    }
> +    return vbasedev->needs_reset;
> +}
> +
> +static VFIODeviceOps vfio_pci_ops = {
> +    .vfio_compute_needs_reset = vfio_pci_compute_needs_reset,
> +    .vfio_hot_reset_multi = vfio_pci_hot_reset_multi,
> +};
> +
> +static void vfio_reset_handler(void *opaque)
>  {
>      VFIOGroup *group;
> -    VFIOPCIDevice *vdev;
> +    VFIODevice *vbasedev;
>
>      QLIST_FOREACH(group, &group_list, next) {
> -        QLIST_FOREACH(vdev, &group->device_list, next) {
> -            if (!vdev->reset_works || (!vdev->has_flr &&
vdev->has_pm_reset)) {
> -                vdev->needs_reset = true;
> -            }
> +        QLIST_FOREACH(vbasedev, &group->device_list, next) {
> +            vbasedev->ops->vfio_compute_needs_reset(vbasedev);
>          }
>      }
>
>      QLIST_FOREACH(group, &group_list, next) {
> -        QLIST_FOREACH(vdev, &group->device_list, next) {
> -            if (vdev->needs_reset) {
> -                vfio_pci_hot_reset_multi(vdev);
> +        QLIST_FOREACH(vbasedev, &group->device_list, next) {
> +            if (vbasedev->needs_reset) {
> +                vbasedev->ops->vfio_hot_reset_multi(vbasedev);
>              }
>          }
>      }
> @@ -3854,7 +3901,7 @@ static VFIOGroup *vfio_get_group(int groupid,
AddressSpace *as)
>      }
>
>      if (QLIST_EMPTY(&group_list)) {
> -        qemu_register_reset(vfio_pci_reset_handler, NULL);
> +        qemu_register_reset(vfio_reset_handler, NULL);
>      }
>
>      QLIST_INSERT_HEAD(&group_list, group, next);
> @@ -3886,7 +3933,7 @@ static void vfio_put_group(VFIOGroup *group)
>      g_free(group);
>
>      if (QLIST_EMPTY(&group_list)) {
> -        qemu_unregister_reset(vfio_pci_reset_handler, NULL);
> +        qemu_unregister_reset(vfio_reset_handler, NULL);
>      }
>  }
>
> @@ -3907,12 +3954,12 @@ static int vfio_get_device(VFIOGroup *group,
const char *name,
>          return ret;
>      }
>
> -    vdev->fd = ret;
> -    vdev->group = group;
> -    QLIST_INSERT_HEAD(&group->device_list, vdev, next);
> +    vdev->vbasedev.fd = ret;
> +    vdev->vbasedev.group = group;
> +    QLIST_INSERT_HEAD(&group->device_list, &vdev->vbasedev, next);
>
>      /* Sanity check device */
> -    ret = ioctl(vdev->fd, VFIO_DEVICE_GET_INFO, &dev_info);
> +    ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_INFO, &dev_info);
>      if (ret) {
>          error_report("vfio: error getting device info: %m");
>          goto error;
> @@ -3926,7 +3973,7 @@ static int vfio_get_device(VFIOGroup *group, const
char *name,
>          goto error;
>      }
>
> -    vdev->reset_works = !!(dev_info.flags & VFIO_DEVICE_FLAGS_RESET);
> +    vdev->vbasedev.reset_works = !!(dev_info.flags &
VFIO_DEVICE_FLAGS_RESET);
>
>      if (dev_info.num_regions < VFIO_PCI_CONFIG_REGION_INDEX + 1) {
>          error_report("vfio: unexpected number of io regions %u",
> @@ -3942,7 +3989,7 @@ static int vfio_get_device(VFIOGroup *group, const
char *name,
>      for (i = VFIO_PCI_BAR0_REGION_INDEX; i < VFIO_PCI_ROM_REGION_INDEX;
i++) {
>          reg_info.index = i;
>
> -        ret = ioctl(vdev->fd, VFIO_DEVICE_GET_REGION_INFO, &reg_info);
> +        ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_REGION_INFO,
&reg_info);
>          if (ret) {
>              error_report("vfio: Error getting region %d info: %m", i);
>              goto error;
> @@ -3956,14 +4003,14 @@ static int vfio_get_device(VFIOGroup *group,
const char *name,
>          vdev->bars[i].flags = reg_info.flags;
>          vdev->bars[i].size = reg_info.size;
>          vdev->bars[i].fd_offset = reg_info.offset;
> -        vdev->bars[i].fd = vdev->fd;
> +        vdev->bars[i].fd = vdev->vbasedev.fd;
>          vdev->bars[i].nr = i;
>          QLIST_INIT(&vdev->bars[i].quirks);
>      }
>
>      reg_info.index = VFIO_PCI_CONFIG_REGION_INDEX;
>
> -    ret = ioctl(vdev->fd, VFIO_DEVICE_GET_REGION_INFO, &reg_info);
> +    ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_REGION_INFO,
&reg_info);
>      if (ret) {
>          error_report("vfio: Error getting config info: %m");
>          goto error;
> @@ -3987,7 +4034,7 @@ static int vfio_get_device(VFIOGroup *group, const
char *name,
>              .index = VFIO_PCI_VGA_REGION_INDEX,
>           };
>
> -        ret = ioctl(vdev->fd, VFIO_DEVICE_GET_REGION_INFO, &vga_info);
> +        ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_REGION_INFO,
&vga_info);
>          if (ret) {
>              error_report(
>                  "vfio: Device does not support requested feature x-vga");
> @@ -4004,7 +4051,7 @@ static int vfio_get_device(VFIOGroup *group, const
char *name,
>          }
>
>          vdev->vga.fd_offset = vga_info.offset;
> -        vdev->vga.fd = vdev->fd;
> +        vdev->vga.fd = vdev->vbasedev.fd;
>
>          vdev->vga.region[QEMU_PCI_VGA_MEM].offset =
QEMU_PCI_VGA_MEM_BASE;
>          vdev->vga.region[QEMU_PCI_VGA_MEM].nr = QEMU_PCI_VGA_MEM;
> @@ -4022,7 +4069,7 @@ static int vfio_get_device(VFIOGroup *group, const
char *name,
>      }
>      irq_info.index = VFIO_PCI_ERR_IRQ_INDEX;
>
> -    ret = ioctl(vdev->fd, VFIO_DEVICE_GET_IRQ_INFO, &irq_info);
> +    ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_IRQ_INFO, &irq_info);
>      if (ret) {
>          /* This can fail for an old kernel or legacy PCI dev */
>          DPRINTF("VFIO_DEVICE_GET_IRQ_INFO failure: %m\n");
> @@ -4038,19 +4085,20 @@ static int vfio_get_device(VFIOGroup *group,
const char *name,
>
>  error:
>      if (ret) {
> -        QLIST_REMOVE(vdev, next);
> -        vdev->group = NULL;
> -        close(vdev->fd);
> +        QLIST_REMOVE(&vdev->vbasedev, next);
> +        vdev->vbasedev.group = NULL;
> +        close(vdev->vbasedev.fd);
>      }
>      return ret;
>  }
>
>  static void vfio_put_device(VFIOPCIDevice *vdev)
>  {
> -    QLIST_REMOVE(vdev, next);
> -    vdev->group = NULL;
> +    QLIST_REMOVE(&vdev->vbasedev, next);
> +    vdev->vbasedev.group = NULL;
>      DPRINTF("vfio_put_device: close vdev->fd\n");
> -    close(vdev->fd);
> +    close(vdev->vbasedev.fd);
> +    g_free(vdev->vbasedev.name);
>      if (vdev->msix) {
>          g_free(vdev->msix);
>          vdev->msix = NULL;
> @@ -4119,7 +4167,7 @@ static void
vfio_register_err_notifier(VFIOPCIDevice *vdev)
>      *pfd = event_notifier_get_fd(&vdev->err_notifier);
>      qemu_set_fd_handler(*pfd, vfio_err_notifier_handler, NULL, vdev);
>
> -    ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
> +    ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set);
>      if (ret) {
>          error_report("vfio: Failed to set up error notification");
>          qemu_set_fd_handler(*pfd, NULL, NULL, vdev);
> @@ -4152,7 +4200,7 @@ static void
vfio_unregister_err_notifier(VFIOPCIDevice *vdev)
>      pfd = (int32_t *)&irq_set->data;
>      *pfd = -1;
>
> -    ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
> +    ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set);
>      if (ret) {
>          error_report("vfio: Failed to de-assign error fd: %m");
>      }
> @@ -4164,7 +4212,8 @@ static void
vfio_unregister_err_notifier(VFIOPCIDevice *vdev)
>
>  static int vfio_initfn(PCIDevice *pdev)
>  {
> -    VFIOPCIDevice *pvdev, *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
> +    VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
> +    VFIODevice *vbasedev_iter;
>      VFIOGroup *group;
>      char path[PATH_MAX], iommu_group_path[PATH_MAX], *group_name;
>      ssize_t len;
> @@ -4182,6 +4231,13 @@ static int vfio_initfn(PCIDevice *pdev)
>          return -errno;
>      }
>
> +    vdev->vbasedev.ops = &vfio_pci_ops;
> +
> +    vdev->vbasedev.type = VFIO_DEVICE_TYPE_PCI;
> +    g_strdup_printf(vdev->vbasedev.name, "%04x:%02x:%02x.%01x",
> +            vdev->host.domain, vdev->host.bus, vdev->host.slot,
> +            vdev->host.function);
> +
>      strncat(path, "iommu_group", sizeof(path) - strlen(path) - 1);
>
>      len = readlink(path, iommu_group_path, sizeof(path));
> @@ -4211,12 +4267,8 @@ static int vfio_initfn(PCIDevice *pdev)
>              vdev->host.domain, vdev->host.bus, vdev->host.slot,
>              vdev->host.function);
>
> -    QLIST_FOREACH(pvdev, &group->device_list, next) {
> -        if (pvdev->host.domain == vdev->host.domain &&
> -            pvdev->host.bus == vdev->host.bus &&
> -            pvdev->host.slot == vdev->host.slot &&
> -            pvdev->host.function == vdev->host.function) {
> -
> +    QLIST_FOREACH(vbasedev_iter, &group->device_list, next) {
> +        if (strcmp(vbasedev_iter->name, vdev->vbasedev.name) == 0) {
>              error_report("vfio: error: device %s is already attached",
path);
>              vfio_put_group(group);
>              return -EBUSY;
> @@ -4231,7 +4283,7 @@ static int vfio_initfn(PCIDevice *pdev)
>      }
>
>      /* Get a copy of config space */
> -    ret = pread(vdev->fd, vdev->pdev.config,
> +    ret = pread(vdev->vbasedev.fd, vdev->pdev.config,
>                  MIN(pci_config_size(&vdev->pdev), vdev->config_size),
>                  vdev->config_offset);
>      if (ret < (int)MIN(pci_config_size(&vdev->pdev), vdev->config_size))
{
> @@ -4319,7 +4371,7 @@ out_put:
>  static void vfio_exitfn(PCIDevice *pdev)
>  {
>      VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
> -    VFIOGroup *group = vdev->group;
> +    VFIOGroup *group = vdev->vbasedev.group;
>
>      vfio_unregister_err_notifier(vdev);
>      pci_device_set_intx_routing_notifier(&vdev->pdev, NULL);
> @@ -4345,8 +4397,9 @@ static void vfio_pci_reset(DeviceState *dev)
>
>      vfio_pci_pre_reset(vdev);
>
> -    if (vdev->reset_works && (vdev->has_flr || !vdev->has_pm_reset) &&
> -        !ioctl(vdev->fd, VFIO_DEVICE_RESET)) {
> +    if (vdev->vbasedev.reset_works &&
> +        (vdev->has_flr || !vdev->has_pm_reset) &&
> +        !ioctl(vdev->vbasedev.fd, VFIO_DEVICE_RESET)) {
>          DPRINTF("%04x:%02x:%02x.%x FLR/VFIO_DEVICE_RESET\n",
vdev->host.domain,
>              vdev->host.bus, vdev->host.slot, vdev->host.function);
>          goto post_reset;
> @@ -4358,8 +4411,8 @@ static void vfio_pci_reset(DeviceState *dev)
>      }
>
>      /* If nothing else works and the device supports PM reset, use it */
> -    if (vdev->reset_works && vdev->has_pm_reset &&
> -        !ioctl(vdev->fd, VFIO_DEVICE_RESET)) {
> +    if (vdev->vbasedev.reset_works && vdev->has_pm_reset &&
> +        !ioctl(vdev->vbasedev.fd, VFIO_DEVICE_RESET)) {
>          DPRINTF("%04x:%02x:%02x.%x PCI PM Reset\n", vdev->host.domain,
>              vdev->host.bus, vdev->host.slot, vdev->host.function);
>          goto post_reset;
> --
> 1.8.3.2
>
>
>
>
> _______________________________________________
> Qemu-devel mailing list
> Qemu-devel@nongnu.org
> https://lists.nongnu.org/mailman/listinfo/qemu-devel
>

[-- Attachment #2: Type: text/html, Size: 42904 bytes --]

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2014-08-09 14:53 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <mailman.109949.1407594386.1146.qemu-devel@nongnu.org>
2014-08-09 14:52 ` [Qemu-devel] Qemu-devel Digest, Vol 137, Issue 266 Fernando Oliveira

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.