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

[Xen-devel] [PATCH v2] qemu/xen: Add 64 bits big bar support on qemu



Changes from v1:
- Rebase to qemu upstream from qemu-xen

Currently it is assumed PCI device BAR access < 4G memory. If there is such a
device whose BAR size is larger than 4G, it must access > 4G memory address.
This patch enable the 64bits big BAR support on qemu.

Signed-off-by: Xudong Hao <xudong.hao@xxxxxxxxx>
Signed-off-by: Xiantao Zhang <xiantao.zhang@xxxxxxxxx>
---
 hw/xen_pt.c             |   16 ++++++++--------
 hw/xen_pt_config_init.c |   42 +++++++++++++++++++++++++++++-------------

diff --git a/hw/xen_pt.c b/hw/xen_pt.c
index 307119a..2a8bcf3 100644
--- a/hw/xen_pt.c
+++ b/hw/xen_pt.c
@@ -403,21 +403,21 @@ static int xen_pt_register_regions(XenPCIPassthroughState 
*s)
 
         s->bases[i].access.u = r->base_addr;
 
-        if (r->type & XEN_HOST_PCI_REGION_TYPE_IO) {
+        if (r->type & XEN_HOST_PCI_REGION_TYPE_IO)
             type = PCI_BASE_ADDRESS_SPACE_IO;
-        } else {
+        else if (r->type & XEN_HOST_PCI_REGION_TYPE_MEM_64)
+            type = PCI_BASE_ADDRESS_MEM_TYPE_64;
+        else if (r->type & XEN_HOST_PCI_REGION_TYPE_PREFETCH)
+            type |= PCI_BASE_ADDRESS_MEM_PREFETCH;
+        else
             type = PCI_BASE_ADDRESS_SPACE_MEMORY;
-            if (r->type & XEN_HOST_PCI_REGION_TYPE_PREFETCH) {
-                type |= PCI_BASE_ADDRESS_MEM_PREFETCH;
-            }
-        }
 
         memory_region_init_io(&s->bar[i], &ops, &s->dev,
                               "xen-pci-pt-bar", r->size);
         pci_register_bar(&s->dev, i, type, &s->bar[i]);
 
-        XEN_PT_LOG(&s->dev, "IO region %i registered (size=0x%08"PRIx64
-                   " base_addr=0x%08"PRIx64" type: %#x)\n",
+        XEN_PT_LOG(&s->dev, "IO region %i registered (size=0x%lx"PRIx64
+                   " base_addr=0x%lx"PRIx64" type: %#x)\n",
                    i, r->size, r->base_addr, type);
     }
 
diff --git a/hw/xen_pt_config_init.c b/hw/xen_pt_config_init.c
index e524a40..5e7ca22 100644
--- a/hw/xen_pt_config_init.c
+++ b/hw/xen_pt_config_init.c
@@ -342,6 +342,7 @@ static int xen_pt_cmd_reg_write(XenPCIPassthroughState *s, 
XenPTReg *cfg_entry,
 #define XEN_PT_BAR_IO_RO_MASK     0x00000003  /* BAR ReadOnly mask(I/O) */
 #define XEN_PT_BAR_IO_EMU_MASK    0xFFFFFFFC  /* BAR emul mask(I/O) */
 
+static uint64_t xen_pt_get_bar_size(PCIIORegion *r);
 static XenPTBarFlag xen_pt_bar_reg_parse(XenPCIPassthroughState *s,
                                          XenPTRegInfo *reg)
 {
@@ -366,7 +367,7 @@ static XenPTBarFlag 
xen_pt_bar_reg_parse(XenPCIPassthroughState *s,
 
     /* check unused BAR */
     r = &d->io_regions[index];
-    if (r->size == 0) {
+    if (!xen_pt_get_bar_size(r)) {
         return XEN_PT_BAR_FLAG_UNUSED;
     }
 
@@ -383,6 +384,24 @@ static XenPTBarFlag 
xen_pt_bar_reg_parse(XenPCIPassthroughState *s,
     }
 }
 
+static bool is_64bit_bar(PCIIORegion *r)
+{
+    return !!(r->type & PCI_BASE_ADDRESS_MEM_TYPE_64);
+}
+
+static uint64_t xen_pt_get_bar_size(PCIIORegion *r)
+{
+    if (is_64bit_bar(r))
+    {
+        uint64_t size64;
+        size64 = (r + 1)->size; 
+        size64 <<= 32; 
+        size64 += r->size;
+        return size64; 
+    }
+    return r->size; 
+}
+
 static inline uint32_t base_address_with_flags(XenHostPCIIORegion *hr)
 {
     if (hr->type & XEN_HOST_PCI_REGION_TYPE_IO) {
@@ -481,7 +500,10 @@ static int xen_pt_bar_reg_write(XenPCIPassthroughState *s, 
XenPTReg *cfg_entry,
     switch (s->bases[index].bar_flag) {
     case XEN_PT_BAR_FLAG_MEM:
         bar_emu_mask = XEN_PT_BAR_MEM_EMU_MASK;
-        bar_ro_mask = XEN_PT_BAR_MEM_RO_MASK | (r_size - 1);
+        if (!r_size)
+            bar_ro_mask = XEN_PT_BAR_ALLF;
+        else
+            bar_ro_mask = XEN_PT_BAR_MEM_RO_MASK | (r_size - 1);
         break;
     case XEN_PT_BAR_FLAG_IO:
         bar_emu_mask = XEN_PT_BAR_IO_EMU_MASK;
@@ -489,7 +511,10 @@ static int xen_pt_bar_reg_write(XenPCIPassthroughState *s, 
XenPTReg *cfg_entry,
         break;
     case XEN_PT_BAR_FLAG_UPPER:
         bar_emu_mask = XEN_PT_BAR_ALLF;
-        bar_ro_mask = 0;    /* all upper 32bit are R/W */
+        if (!r_size)
+            bar_ro_mask = 0;
+        else
+            bar_ro_mask = r_size - 1;
         break;
     default:
         break;
@@ -501,22 +526,13 @@ static int xen_pt_bar_reg_write(XenPCIPassthroughState 
*s, XenPTReg *cfg_entry,
 
     /* check whether we need to update the virtual region address or not */
     switch (s->bases[index].bar_flag) {
+    case XEN_PT_BAR_FLAG_UPPER:
     case XEN_PT_BAR_FLAG_MEM:
         /* nothing to do */
         break;
     case XEN_PT_BAR_FLAG_IO:
         /* nothing to do */
         break;
-    case XEN_PT_BAR_FLAG_UPPER:
-        if (cfg_entry->data) {
-            if (cfg_entry->data != (XEN_PT_BAR_ALLF & ~bar_ro_mask)) {
-                XEN_PT_WARN(d, "Guest attempt to set high MMIO Base Address. "
-                            "Ignore mapping. "
-                            "(offset: 0x%02x, high address: 0x%08x)\n",
-                            reg->offset, cfg_entry->data);
-            }
-        }
-        break;
     default:
         break;
     }
-- 
1.5.5


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.