aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/py/test_dirty_pages.py104
1 files changed, 74 insertions, 30 deletions
diff --git a/test/py/test_dirty_pages.py b/test/py/test_dirty_pages.py
index 6cf87fb..8b4e3dc 100644
--- a/test/py/test_dirty_pages.py
+++ b/test/py/test_dirty_pages.py
@@ -89,13 +89,13 @@ def test_dirty_pages_setup():
payload = vfio_user_dma_map(argsz=len(vfio_user_dma_map()),
flags=(VFIO_USER_F_DMA_REGION_READ | VFIO_USER_F_DMA_REGION_WRITE),
- offset=0, addr=0x10000, size=0x10000)
+ offset=0, addr=0x10000, size=0x20000)
msg(ctx, sock, VFIO_USER_DMA_MAP, payload, fds=[f.fileno()])
payload = vfio_user_dma_map(argsz=len(vfio_user_dma_map()),
flags=(VFIO_USER_F_DMA_REGION_READ | VFIO_USER_F_DMA_REGION_WRITE),
- offset=0, addr=0x20000, size=0x10000)
+ offset=0, addr=0x40000, size=0x10000)
msg(ctx, sock, VFIO_USER_DMA_MAP, payload)
@@ -247,7 +247,7 @@ def test_get_dirty_page_bitmap_unmapped():
dirty_pages = vfio_user_dirty_pages(argsz=argsz,
flags=VFIO_IOMMU_DIRTY_PAGES_FLAG_GET_BITMAP)
bitmap = vfio_user_bitmap(pgsize=0x1000, size=8)
- br = vfio_user_bitmap_range(iova=0x20000, size=0x10000, bitmap=bitmap)
+ br = vfio_user_bitmap_range(iova=0x40000, size=0x10000, bitmap=bitmap)
payload = bytes(dirty_pages) + bytes(br)
@@ -283,13 +283,7 @@ def test_dirty_pages_get_unmodified():
assert br.bitmap.size == 8
-def get_dirty_page_bitmap_result(resp):
- _, resp = vfio_user_dirty_pages.pop_from_buffer(resp)
- _, resp = vfio_user_bitmap_range.pop_from_buffer(resp)
- return struct.unpack("Q", resp)[0]
-
-
-def send_dirty_page_bitmap(busy=False):
+def get_dirty_page_bitmap():
argsz = len(vfio_user_dirty_pages()) + len(vfio_user_bitmap_range()) + 8
dirty_pages = vfio_user_dirty_pages(argsz=argsz,
@@ -299,18 +293,33 @@ def send_dirty_page_bitmap(busy=False):
payload = bytes(dirty_pages) + bytes(br)
- return msg(ctx, sock, VFIO_USER_DIRTY_PAGES, payload, busy=busy)
+ result = msg(ctx, sock, VFIO_USER_DIRTY_PAGES, payload)
+
+ _, result = vfio_user_dirty_pages.pop_from_buffer(result)
+ _, result = vfio_user_bitmap_range.pop_from_buffer(result)
+ assert(len(result) == 8)
-def get_dirty_page_bitmap():
- result = send_dirty_page_bitmap()
- return get_dirty_page_bitmap_result(result)
+ return struct.unpack("Q", result)[0]
sg3 = None
iovec3 = None
+def write_to_addr(ctx, addr, size, get_bitmap=True):
+ """Simulate a write to the given address and size."""
+ ret, sg = vfu_addr_to_sgl(ctx, dma_addr=addr, length=size)
+ assert ret == 1
+ iovec = iovec_t()
+ ret = vfu_sgl_get(ctx, sg, iovec)
+ assert ret == 0
+ vfu_sgl_put(ctx, sg, iovec)
+ if get_bitmap:
+ return get_dirty_page_bitmap()
+ return None
+
+
def test_dirty_pages_get_modified():
ret, sg1 = vfu_addr_to_sgl(ctx, dma_addr=0x10000, length=0x1000)
assert ret == 1
@@ -326,13 +335,15 @@ def test_dirty_pages_get_modified():
ret = vfu_sgl_get(ctx, sg2, iovec2)
assert ret == 0
+ # simple single bitmap entry map
ret, sg3 = vfu_addr_to_sgl(ctx, dma_addr=0x12000, length=0x1000)
assert ret == 1
iovec3 = iovec_t()
ret = vfu_sgl_get(ctx, sg3, iovec3)
assert ret == 0
- ret, sg4 = vfu_addr_to_sgl(ctx, dma_addr=0x14000, length=0x4000)
+ # write that spans bytes in bitmap
+ ret, sg4 = vfu_addr_to_sgl(ctx, dma_addr=0x16000, length=0x4000)
assert ret == 1
iovec4 = iovec_t()
ret = vfu_sgl_get(ctx, sg4, iovec4)
@@ -340,23 +351,65 @@ def test_dirty_pages_get_modified():
# not put yet, dirty bitmap should be zero
bitmap = get_dirty_page_bitmap()
- assert bitmap == 0b00000000
+ assert bitmap == 0b0000000000000000
# put SGLs, dirty bitmap should be updated
vfu_sgl_put(ctx, sg1, iovec1)
vfu_sgl_put(ctx, sg4, iovec4)
bitmap = get_dirty_page_bitmap()
- assert bitmap == 0b11110001
+ assert bitmap == 0b0000001111000001
# after another two puts, should just be one dirty page
vfu_sgl_put(ctx, sg2, iovec2)
vfu_sgl_put(ctx, sg3, iovec3)
bitmap = get_dirty_page_bitmap()
- assert bitmap == 0b00000100
+ assert bitmap == 0b0000000000000100
# and should now be clear
bitmap = get_dirty_page_bitmap()
- assert bitmap == 0b00000000
+ assert bitmap == 0b0000000000000000
+
+ #
+ # check various edge cases of bitmap values.
+ #
+
+ # very first bit
+ bitmap = write_to_addr(ctx, 0x10000, 0x1000)
+ assert bitmap == 0b0000000000000001
+
+ # top bit of first byte
+ bitmap = write_to_addr(ctx, 0x17000, 0x1000)
+ assert bitmap == 0b0000000010000000
+
+ # all bits except top one of first byte
+ bitmap = write_to_addr(ctx, 0x10000, 0x7000)
+ assert bitmap == 0b0000000001111111
+
+ # all bits of first byte
+ bitmap = write_to_addr(ctx, 0x10000, 0x8000)
+ assert bitmap == 0b0000000011111111
+
+ # all bits of first byte plus bottom bit of next
+ bitmap = write_to_addr(ctx, 0x10000, 0x9000)
+ assert bitmap == 0b0000000111111111
+
+ # straddle top/bottom bit
+ bitmap = write_to_addr(ctx, 0x17000, 0x2000)
+ assert bitmap == 0b0000000110000000
+
+ # top bit of second byte
+ bitmap = write_to_addr(ctx, 0x1f000, 0x1000)
+ assert bitmap == 0b1000000000000000
+
+ # top bit of third byte
+ bitmap = write_to_addr(ctx, 0x27000, 0x1000)
+ assert bitmap == 0b100000000000000000000000
+
+ # bits in third and first byte
+ write_to_addr(ctx, 0x26000, 0x1000, get_bitmap=False)
+ write_to_addr(ctx, 0x12000, 0x2000, get_bitmap=False)
+ bitmap = get_dirty_page_bitmap()
+ assert bitmap == 0b010000000000000000001100
def test_dirty_pages_stop():
@@ -399,17 +452,8 @@ def test_dirty_pages_bitmap_with_quiesce():
assert ret == 0
vfu_sgl_put(ctx, sg1, iovec1)
- send_dirty_page_bitmap(busy=True)
-
- ret = vfu_device_quiesced(ctx, 0)
- assert ret == 0
-
- # now should be able to get the reply
- result = get_reply(sock, expect=0)
- bitmap = get_dirty_page_bitmap_result(result)
- assert bitmap == 0b00000001
-
- quiesce_errno = 0
+ bitmap = get_dirty_page_bitmap()
+ assert bitmap == 0b0000000000000001
def test_dirty_pages_stop_with_quiesce():