Support 64 bits and prefetchable BARs (#792)
* Support 64 bits and prefetchable BARs
Add two new flags for lib user to request 64bits and/or prefetchable
BARs.
Tested with a vfio-user client patched QEMU.
Signed-off-by: Jérémy Fanguède <jfanguede@kalrayinc.com>
diff --git a/include/libvfio-user.h b/include/libvfio-user.h
index e4cfa60..c74902b 100644
--- a/include/libvfio-user.h
+++ b/include/libvfio-user.h
@@ -238,8 +238,11 @@
/* If unset, this is an IO region. */
#define VFU_REGION_FLAG_MEM (1 << 2)
#define VFU_REGION_FLAG_ALWAYS_CB (1 << 3)
+#define VFU_REGION_FLAG_64_BITS (1 << 4)
+#define VFU_REGION_FLAG_PREFETCH (1 << 5)
#define VFU_REGION_FLAG_MASK (VFU_REGION_FLAG_RW | VFU_REGION_FLAG_MEM | \
- VFU_REGION_FLAG_ALWAYS_CB)
+ VFU_REGION_FLAG_ALWAYS_CB | VFU_REGION_FLAG_64_BITS | \
+ VFU_REGION_FLAG_PREFETCH)
/**
* Set up a device region.
diff --git a/include/pci_defs.h b/include/pci_defs.h
index 5a77b65..11ab919 100644
--- a/include/pci_defs.h
+++ b/include/pci_defs.h
@@ -48,6 +48,10 @@
* instead?
*/
+#define PCI_BASE_ADDRESS_MEM_TYPE_LOCATABLE_32 (PCI_BASE_ADDRESS_MEM_TYPE_32 >> 1)
+#define PCI_BASE_ADDRESS_MEM_TYPE_LOCATABLE_1M (PCI_BASE_ADDRESS_MEM_TYPE_1M >> 1)
+#define PCI_BASE_ADDRESS_MEM_TYPE_LOCATABLE_64 (PCI_BASE_ADDRESS_MEM_TYPE_64 >> 1)
+
typedef union {
uint32_t raw;
struct {
diff --git a/lib/libvfio-user.c b/lib/libvfio-user.c
index dc13ea5..62efd30 100644
--- a/lib/libvfio-user.c
+++ b/lib/libvfio-user.c
@@ -1729,6 +1729,17 @@
if (!(vfu_ctx->reg_info[i].flags & VFU_REGION_FLAG_MEM)) {
vfu_ctx->pci.config_space->hdr.bars[i].io.region_type |= 0x1;
}
+ if ((vfu_ctx->reg_info[i].flags & VFU_REGION_FLAG_64_BITS)) {
+ vfu_ctx->pci.config_space->hdr.bars[i].mem.locatable
+ = PCI_BASE_ADDRESS_MEM_TYPE_LOCATABLE_64;
+ }
+ if ((vfu_ctx->reg_info[i].flags & VFU_REGION_FLAG_PREFETCH)) {
+ vfu_ctx->pci.config_space->hdr.bars[i].mem.prefetchable = 1;
+ if (!(vfu_ctx->reg_info[i].flags & VFU_REGION_FLAG_64_BITS)) {
+ vfu_log(vfu_ctx, LOG_WARNING,
+ "Region %d has prefetchable flag set, but not 64bits flag", i);
+ }
+ }
}
if (vfu_ctx->irqs == NULL) {
diff --git a/test/py/libvfio_user.py b/test/py/libvfio_user.py
index 289f10a..976590c 100644
--- a/test/py/libvfio_user.py
+++ b/test/py/libvfio_user.py
@@ -84,6 +84,13 @@
PCI_EXT_CAP_VNDR_HDR_SIZEOF = 8
+PCI_BASE_ADDRESS_SPACE_IO = 0x01
+PCI_BASE_ADDRESS_SPACE_MEMORY = 0x00
+PCI_BASE_ADDRESS_MEM_TYPE_32 = 0x00
+PCI_BASE_ADDRESS_MEM_TYPE_1M = 0x02
+PCI_BASE_ADDRESS_MEM_TYPE_64 = 0x04
+PCI_BASE_ADDRESS_MEM_PREFETCH = 0x08
+
# MSI registers
PCI_MSI_FLAGS = 2 # Message Control offset
PCI_MSI_ADDRESS_LO = 4 # Message Address offset
@@ -201,6 +208,8 @@
VFU_REGION_FLAG_RW = (VFU_REGION_FLAG_READ | VFU_REGION_FLAG_WRITE)
VFU_REGION_FLAG_MEM = 4
VFU_REGION_FLAG_ALWAYS_CB = 8
+VFU_REGION_FLAG_64_BITS = 16
+VFU_REGION_FLAG_PREFETCH = 32
VFIO_USER_F_DMA_REGION_READ = (1 << 0)
VFIO_USER_F_DMA_REGION_WRITE = (1 << 1)
diff --git a/test/py/test_vfu_realize_ctx.py b/test/py/test_vfu_realize_ctx.py
index ab0b86a..4b001a4 100644
--- a/test/py/test_vfu_realize_ctx.py
+++ b/test/py/test_vfu_realize_ctx.py
@@ -73,14 +73,30 @@
ret = vfu_setup_region(ctx, index=VFU_PCI_DEV_BAR1_REGION_IDX, size=4096,
flags=(VFU_REGION_FLAG_RW | VFU_REGION_FLAG_MEM))
assert ret == 0
+ ret = vfu_setup_region(ctx, index=VFU_PCI_DEV_BAR2_REGION_IDX,
+ size=1048576,
+ flags=(VFU_REGION_FLAG_RW | VFU_REGION_FLAG_MEM
+ | VFU_REGION_FLAG_64_BITS))
+ assert ret == 0
+ ret = vfu_setup_region(ctx, index=VFU_PCI_DEV_BAR4_REGION_IDX,
+ size=1073741824,
+ flags=(VFU_REGION_FLAG_RW | VFU_REGION_FLAG_MEM
+ | VFU_REGION_FLAG_64_BITS
+ | VFU_REGION_FLAG_PREFETCH))
+ assert ret == 0
ret = vfu_realize_ctx(ctx)
assert ret == 0
# region_type should be set non-MEM BAR, unset otherwise
hdr = get_pci_header(ctx)
- assert hdr.bars[0].io == 0x1
- assert hdr.bars[1].io == 0
+ assert hdr.bars[0].io == PCI_BASE_ADDRESS_SPACE_IO
+ assert hdr.bars[1].mem == PCI_BASE_ADDRESS_SPACE_MEMORY
+ assert hdr.bars[2].mem == (PCI_BASE_ADDRESS_SPACE_MEMORY
+ | PCI_BASE_ADDRESS_MEM_TYPE_64)
+ assert hdr.bars[4].mem == (PCI_BASE_ADDRESS_SPACE_MEMORY
+ | PCI_BASE_ADDRESS_MEM_TYPE_64
+ | PCI_BASE_ADDRESS_MEM_PREFETCH)
vfu_destroy_ctx(ctx)