Patchwork [RFC,v3,38/56] virtio-pci: convert to memory API

login
register
mail settings
Submitter Avi Kivity
Date July 10, 2011, 6:14 p.m.
Message ID <1310321709-30770-39-git-send-email-avi@redhat.com>
Download mbox | patch
Permalink /patch/104116/
State New
Headers show

Comments

Avi Kivity - July 10, 2011, 6:14 p.m.
except msix.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/virtio-pci.c |   84 +++++++++++++++++++++++++++++-------------------------
 hw/virtio-pci.h |    2 +-
 2 files changed, 46 insertions(+), 40 deletions(-)

Patch

diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index b3e7ba5..20e6c5b 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -162,6 +162,7 @@  static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy,
     VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
     EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
     int r;
+
     if (assign) {
         r = event_notifier_init(notifier, 1);
         if (r < 0) {
@@ -169,24 +170,11 @@  static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy,
                          __func__, r);
             return r;
         }
-        r = kvm_set_ioeventfd_pio_word(event_notifier_get_fd(notifier),
-                                       proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY,
-                                       n, assign);
-        if (r < 0) {
-            error_report("%s: unable to map ioeventfd: %d",
-                         __func__, r);
-            event_notifier_cleanup(notifier);
-        }
+        memory_region_add_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2,
+                                  true, n, event_notifier_get_fd(notifier));
     } else {
-        r = kvm_set_ioeventfd_pio_word(event_notifier_get_fd(notifier),
-                                       proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY,
-                                       n, assign);
-        if (r < 0) {
-            error_report("%s: unable to unmap ioeventfd: %d",
-                         __func__, r);
-            return r;
-        }
-
+        memory_region_del_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2,
+                                  true, n, event_notifier_get_fd(notifier));
         /* Handle the race condition where the guest kicked and we deassigned
          * before we got around to handling the kick.
          */
@@ -423,7 +411,6 @@  static uint32_t virtio_pci_config_readb(void *opaque, uint32_t addr)
 {
     VirtIOPCIProxy *proxy = opaque;
     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-    addr -= proxy->addr;
     if (addr < config)
         return virtio_ioport_read(proxy, addr);
     addr -= config;
@@ -434,7 +421,6 @@  static uint32_t virtio_pci_config_readw(void *opaque, uint32_t addr)
 {
     VirtIOPCIProxy *proxy = opaque;
     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-    addr -= proxy->addr;
     if (addr < config)
         return virtio_ioport_read(proxy, addr);
     addr -= config;
@@ -445,7 +431,6 @@  static uint32_t virtio_pci_config_readl(void *opaque, uint32_t addr)
 {
     VirtIOPCIProxy *proxy = opaque;
     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-    addr -= proxy->addr;
     if (addr < config)
         return virtio_ioport_read(proxy, addr);
     addr -= config;
@@ -456,7 +441,6 @@  static void virtio_pci_config_writeb(void *opaque, uint32_t addr, uint32_t val)
 {
     VirtIOPCIProxy *proxy = opaque;
     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-    addr -= proxy->addr;
     if (addr < config) {
         virtio_ioport_write(proxy, addr, val);
         return;
@@ -469,7 +453,6 @@  static void virtio_pci_config_writew(void *opaque, uint32_t addr, uint32_t val)
 {
     VirtIOPCIProxy *proxy = opaque;
     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-    addr -= proxy->addr;
     if (addr < config) {
         virtio_ioport_write(proxy, addr, val);
         return;
@@ -482,7 +465,6 @@  static void virtio_pci_config_writel(void *opaque, uint32_t addr, uint32_t val)
 {
     VirtIOPCIProxy *proxy = opaque;
     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-    addr -= proxy->addr;
     if (addr < config) {
         virtio_ioport_write(proxy, addr, val);
         return;
@@ -491,30 +473,46 @@  static void virtio_pci_config_writel(void *opaque, uint32_t addr, uint32_t val)
     virtio_config_writel(proxy->vdev, addr, val);
 }
 
-static void virtio_map(PCIDevice *pci_dev, int region_num,
-                       pcibus_t addr, pcibus_t size, int type)
+static uint64_t virtio_pci_config_read(void *opaque,
+                                       target_phys_addr_t addr,
+                                       unsigned size)
 {
-    VirtIOPCIProxy *proxy = container_of(pci_dev, VirtIOPCIProxy, pci_dev);
-    VirtIODevice *vdev = proxy->vdev;
-    unsigned config_len = VIRTIO_PCI_REGION_SIZE(pci_dev) + vdev->config_len;
+    VirtIOPCIProxy *proxy = opaque;
 
-    proxy->addr = addr;
+    switch (size) {
+    case 1: return virtio_pci_config_readb(proxy, addr);
+    case 2: return virtio_pci_config_readw(proxy, addr);
+    case 4: return virtio_pci_config_readl(proxy, addr);
+    default: abort();
+    }
+}
 
-    register_ioport_write(addr, config_len, 1, virtio_pci_config_writeb, proxy);
-    register_ioport_write(addr, config_len, 2, virtio_pci_config_writew, proxy);
-    register_ioport_write(addr, config_len, 4, virtio_pci_config_writel, proxy);
-    register_ioport_read(addr, config_len, 1, virtio_pci_config_readb, proxy);
-    register_ioport_read(addr, config_len, 2, virtio_pci_config_readw, proxy);
-    register_ioport_read(addr, config_len, 4, virtio_pci_config_readl, proxy);
+static void virtio_pci_config_write(void *opaque,
+                                    target_phys_addr_t addr,
+                                    uint64_t data,
+                                    unsigned size)
+{
+    VirtIOPCIProxy *proxy = opaque;
 
-    if (vdev->config_len)
-        vdev->get_config(vdev, vdev->config);
+    switch (size) {
+    case 1: return virtio_pci_config_writeb(proxy, addr, data);
+    case 2: return virtio_pci_config_writew(proxy, addr, data);
+    case 4: return virtio_pci_config_writel(proxy, addr, data);
+    default: abort();
+    }
 }
 
+static MemoryRegionOps virtio_pci_config_ops = {
+    .read = virtio_pci_config_read,
+    .write = virtio_pci_config_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
                                 uint32_t val, int len)
 {
     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+    VirtIODevice *vdev = proxy->vdev;
 
     if (PCI_COMMAND == address) {
         if (!(val & PCI_COMMAND_MASTER)) {
@@ -525,6 +523,9 @@  static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
             }
         }
     }
+    if (address == PCI_BASE_ADDRESS_0 && vdev->config_len) {
+        vdev->get_config(vdev, vdev->config);
+    }
 
     pci_default_write_config(pci_dev, address, val, len);
     msix_write_config(pci_dev, address, val, len);
@@ -678,8 +679,10 @@  void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev)
     if (size & (size-1))
         size = 1 << qemu_fls(size);
 
-    pci_register_bar(&proxy->pci_dev, 0, size, PCI_BASE_ADDRESS_SPACE_IO,
-                           virtio_map);
+    memory_region_init_io(&proxy->bar, &virtio_pci_config_ops, proxy,
+                          "virtio-pci", size);
+    pci_register_bar_region(&proxy->pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
+                            &proxy->bar);
 
     if (!kvm_has_many_ioeventfds()) {
         proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
@@ -713,6 +716,9 @@  static int virtio_blk_init_pci(PCIDevice *pci_dev)
 
 static int virtio_exit_pci(PCIDevice *pci_dev)
 {
+    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+
+    memory_region_destroy(&proxy->bar);
     return msix_uninit(pci_dev);
 }
 
diff --git a/hw/virtio-pci.h b/hw/virtio-pci.h
index b518917..d17e5fc 100644
--- a/hw/virtio-pci.h
+++ b/hw/virtio-pci.h
@@ -21,8 +21,8 @@ 
 typedef struct {
     PCIDevice pci_dev;
     VirtIODevice *vdev;
+    MemoryRegion bar;
     uint32_t flags;
-    uint32_t addr;
     uint32_t class_code;
     uint32_t nvectors;
     BlockConf block;