aboutsummaryrefslogtreecommitdiff
path: root/test/py
diff options
context:
space:
mode:
authorFlorian Freudiger <25648113+FlorianFreudiger@users.noreply.github.com>2023-08-15 13:24:23 +0200
committerGitHub <noreply@github.com>2023-08-15 12:24:23 +0100
commit1cca91aeb8ae8f531f9c3b9c59d83630e9941a5e (patch)
treea0b700608a3f29be7cc8cb14060eb2b703edf59c /test/py
parent852ca25f41bf7be8a6a2a8b30c0e2374c10b480e (diff)
downloadlibvfio-user-1cca91aeb8ae8f531f9c3b9c59d83630e9941a5e.zip
libvfio-user-1cca91aeb8ae8f531f9c3b9c59d83630e9941a5e.tar.gz
libvfio-user-1cca91aeb8ae8f531f9c3b9c59d83630e9941a5e.tar.bz2
Allow adding MSI capability via vfu_pci_add_capability (#758)
Signed-off-by: Florian Freudiger <25648113+FlorianFreudiger@users.noreply.github.com>
Diffstat (limited to 'test/py')
-rw-r--r--test/py/libvfio_user.py7
-rw-r--r--test/py/test_pci_caps.py58
2 files changed, 65 insertions, 0 deletions
diff --git a/test/py/libvfio_user.py b/test/py/libvfio_user.py
index 8848dbf..6d60798 100644
--- a/test/py/libvfio_user.py
+++ b/test/py/libvfio_user.py
@@ -70,6 +70,7 @@ PCI_CAP_LIST_NEXT = 1
PCI_CAP_ID_PM = 0x1
PCI_CAP_ID_VNDR = 0x9
+PCI_CAP_ID_MSI = 0x5
PCI_CAP_ID_MSIX = 0x11
PCI_CAP_ID_EXP = 0x10
@@ -83,6 +84,12 @@ PCI_EXT_CAP_DSN_SIZEOF = 12
PCI_EXT_CAP_VNDR_HDR_SIZEOF = 8
+# MSI registers
+PCI_MSI_FLAGS = 2 # Message Control offset
+PCI_MSI_ADDRESS_LO = 4 # Message Address offset
+PCI_MSI_FLAGS_ENABLE = 0x0001 # MSI enable
+PCI_CAP_MSI_SIZEOF = 24 # size of MSI registers
+
# MSI-X registers
PCI_MSIX_FLAGS = 2 # Message Control
PCI_MSIX_TABLE = 4 # Table offset
diff --git a/test/py/test_pci_caps.py b/test/py/test_pci_caps.py
index edd1683..b7ad07b 100644
--- a/test/py/test_pci_caps.py
+++ b/test/py/test_pci_caps.py
@@ -342,6 +342,64 @@ def test_pci_cap_write_px(mock_quiesce, mock_reset):
expect=errno.EINVAL)
+def test_pci_cap_write_msi():
+ setup_pci_dev(realize=True)
+ sock = connect_client(ctx)
+
+ # Set MMC to 100b (16 interrupt vectors)
+ mmc = 0b00001000
+
+ # Bad MME with 101b (32 interrupt vectors), over MMC
+ mme_bad = 0b01010000
+ # Test MME with 100b (16 interrupt vectors)
+ mme_good = 0b01000000
+
+ # Test if capability is placed at right offset
+ pos = vfu_pci_add_capability(ctx, pos=0, flags=0,
+ data=struct.pack("ccHIIIII",
+ to_byte(PCI_CAP_ID_MSI),
+ b'\0', mmc, 0, 0, 0, 0, 0))
+ assert pos == cap_offsets[0]
+
+ offset = vfu_pci_find_capability(ctx, False, PCI_CAP_ID_MSI)
+
+ # Test if write fails as expected
+ # as MME is out of bounds, 111b is over the max of 101b (32 vectors)
+ data = b'\xff\xff'
+ write_region(ctx, sock, VFU_PCI_DEV_CFG_REGION_IDX,
+ offset=offset + PCI_MSI_FLAGS,
+ count=len(data), data=data, expect=errno.EINVAL)
+
+ # Test if write fails as expected
+ # as MME is over MMC, 101b (32 vectors) > 100b (16 vectors)
+ data = to_bytes_le(mme_bad, 2)
+ write_region(ctx, sock, VFU_PCI_DEV_CFG_REGION_IDX,
+ offset=offset + PCI_MSI_FLAGS,
+ count=len(data), data=data, expect=errno.EINVAL)
+
+ # Test good write, MSI Enable + good MME
+ data = to_bytes_le(PCI_MSI_FLAGS_ENABLE | mme_good, 2)
+ write_region(ctx, sock, VFU_PCI_DEV_CFG_REGION_IDX,
+ offset=offset + PCI_MSI_FLAGS,
+ count=len(data), data=data)
+
+ size_before_flags = PCI_CAP_MSI_SIZEOF - PCI_MSI_FLAGS
+ size_after_flags = PCI_CAP_MSI_SIZEOF - PCI_MSI_ADDRESS_LO
+
+ # reset
+ data = size_before_flags * b'\x00'
+ write_region(ctx, sock, VFU_PCI_DEV_CFG_REGION_IDX,
+ offset=offset + PCI_MSI_FLAGS,
+ count=len(data), data=data)
+
+ # Check if MMC is still present after reset (since it is RO)
+ expected = (to_bytes_le(PCI_CAP_ID_MSI) + b'\x00' +
+ to_bytes_le(mmc, 2) + (size_after_flags * b'\x00'))
+ payload = read_region(ctx, sock, VFU_PCI_DEV_CFG_REGION_IDX, offset=offset,
+ count=len(expected))
+ assert expected == payload
+
+
def test_pci_cap_write_msix():
setup_pci_dev(realize=True)
sock = connect_client(ctx)