diff options
author | John Levon <john.levon@nutanix.com> | 2021-05-24 11:41:30 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-24 11:41:30 +0100 |
commit | 7443fbedd1f94288fbe0d3563b72c4938aa9ff2f (patch) | |
tree | afaad7d00e33409c3104d25ca18790960157f72d /test | |
parent | bf3938dec68e1c820063db4f63aa2355c5703e4b (diff) | |
download | libvfio-user-7443fbedd1f94288fbe0d3563b72c4938aa9ff2f.zip libvfio-user-7443fbedd1f94288fbe0d3563b72c4938aa9ff2f.tar.gz libvfio-user-7443fbedd1f94288fbe0d3563b72c4938aa9ff2f.tar.bz2 |
python tests: add VFIO_USER_DEVICE_SET_IRQS (#473)
Signed-off-by: John Levon <john.levon@nutanix.com>
Reviewed-by: Thanos Makatos <thanos.makatos@nutanix.com>
Diffstat (limited to 'test')
-rw-r--r-- | test/py/libvfio_user.py | 16 | ||||
-rw-r--r-- | test/py/test_device_set_irqs.py | 345 | ||||
-rw-r--r-- | test/unit-tests.c | 209 |
3 files changed, 359 insertions, 211 deletions
diff --git a/test/py/libvfio_user.py b/test/py/libvfio_user.py index 21f7732..61cb7cc 100644 --- a/test/py/libvfio_user.py +++ b/test/py/libvfio_user.py @@ -82,6 +82,13 @@ VFIO_REGION_SUBTYPE_MIGRATION = 1 VFIO_REGION_INFO_CAP_SPARSE_MMAP = 1 VFIO_REGION_INFO_CAP_TYPE = 2 +VFIO_IRQ_SET_DATA_NONE = (1 << 0) +VFIO_IRQ_SET_DATA_BOOL = (1 << 1) +VFIO_IRQ_SET_DATA_EVENTFD = (1 << 2) +VFIO_IRQ_SET_ACTION_MASK = (1 << 3) +VFIO_IRQ_SET_ACTION_UNMASK = (1 << 4) +VFIO_IRQ_SET_ACTION_TRIGGER = (1 << 5) + # libvfio-user defines VFU_TRANS_SOCK = 0 @@ -160,8 +167,7 @@ topdir = os.path.realpath(os.path.dirname(__file__) + "/../..") build_type = os.getenv("BUILD_TYPE", default="dbg") libname = "%s/build/%s/lib/libvfio-user.so" % (topdir, build_type) lib = c.CDLL(libname, use_errno=True) - -msg_id = 1 +libc = c.CDLL("libc.so.6", use_errno=True) # # Structures @@ -260,6 +266,10 @@ def parse_json(json_str): """Parse JSON into an object with attributes (instead of using a dict).""" return json.loads(json_str, object_hook=lambda d: SimpleNamespace(**d)) +def eventfd(initval=0, flags=0): + libc.eventfd.argtypes = (c.c_uint, c.c_int) + return libc.eventfd(initval, flags) + def connect_sock(): sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock.connect(SOCK_PATH) @@ -369,6 +379,8 @@ def vfio_region_sparse_mmap_area(buf): # Library wrappers # +msg_id = 1 + @c.CFUNCTYPE(None, c.c_void_p, c.c_int, c.c_char_p) def log(ctx, level, msg): print(msg.decode("utf-8")) diff --git a/test/py/test_device_set_irqs.py b/test/py/test_device_set_irqs.py new file mode 100644 index 0000000..79c706e --- /dev/null +++ b/test/py/test_device_set_irqs.py @@ -0,0 +1,345 @@ +# +# Copyright (c) 2021 Nutanix Inc. All rights reserved. +# +# Authors: John Levon <john.levon@nutanix.com> +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of Nutanix nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. +# + +from libvfio_user import * +import ctypes as c +import errno +import os +import sys + +ctx = None +sock = None + +def test_device_set_irqs_setup(): + global ctx, sock + + ctx = vfu_create_ctx(flags=LIBVFIO_USER_FLAG_ATTACH_NB) + assert ctx != None + + ret = vfu_pci_init(ctx) + assert ret == 0 + + ret = vfu_setup_device_nr_irqs(ctx, VFU_DEV_REQ_IRQ, 1) + assert ret == 0 + ret = vfu_setup_device_nr_irqs(ctx, VFU_DEV_ERR_IRQ, 1) + assert ret == 0 + ret = vfu_setup_device_nr_irqs(ctx, VFU_DEV_MSIX_IRQ, 2048) + assert ret == 0 + + ret = vfu_realize_ctx(ctx) + assert ret == 0 + + sock = connect_client(ctx) + +def test_device_set_irqs_short_write(): + payload = struct.pack("II", 0, 0) + + hdr = vfio_user_header(VFIO_USER_DEVICE_SET_IRQS, size=len(payload)) + sock.send(hdr + payload) + vfu_run_ctx(ctx) + get_reply(sock, expect=errno.EINVAL) + +def test_device_set_irqs_bad_argsz(): + # struct vfio_irq_set + payload = struct.pack("IIIII", 3, VFIO_IRQ_SET_ACTION_TRIGGER | + VFIO_IRQ_SET_DATA_NONE, VFU_DEV_REQ_IRQ, 0, 0) + + hdr = vfio_user_header(VFIO_USER_DEVICE_SET_IRQS, size=len(payload)) + sock.send(hdr + payload) + vfu_run_ctx(ctx) + get_reply(sock, expect=errno.EINVAL) + +def test_device_set_irqs_bad_index(): + # struct vfio_irq_set + payload = struct.pack("IIIII", 20, VFIO_IRQ_SET_ACTION_TRIGGER | + VFIO_IRQ_SET_DATA_NONE, VFU_DEV_NUM_IRQS, 0, 0) + + hdr = vfio_user_header(VFIO_USER_DEVICE_SET_IRQS, size=len(payload)) + sock.send(hdr + payload) + vfu_run_ctx(ctx) + get_reply(sock, expect=errno.EINVAL) + +def test_device_set_irqs_bad_flags_MASK_and_UNMASK(): + # struct vfio_irq_set + payload = struct.pack("IIIII", 20, VFIO_IRQ_SET_ACTION_MASK | + VFIO_IRQ_SET_ACTION_UNMASK, VFU_DEV_MSIX_IRQ, 0, 0) + + hdr = vfio_user_header(VFIO_USER_DEVICE_SET_IRQS, size=len(payload)) + sock.send(hdr + payload) + vfu_run_ctx(ctx) + get_reply(sock, expect=errno.EINVAL) + +def test_device_set_irqs_bad_flags_DATA_NONE_and_DATA_BOOL(): + # struct vfio_irq_set + payload = struct.pack("IIIII", 20, VFIO_IRQ_SET_ACTION_MASK | + VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_DATA_BOOL, + VFU_DEV_MSIX_IRQ, 0, 0) + + hdr = vfio_user_header(VFIO_USER_DEVICE_SET_IRQS, size=len(payload)) + sock.send(hdr + payload) + vfu_run_ctx(ctx) + get_reply(sock, expect=errno.EINVAL) + +def test_device_set_irqs_bad_start_count_range(): + # struct vfio_irq_set + payload = struct.pack("IIIII", 20, VFIO_IRQ_SET_ACTION_MASK | + VFIO_IRQ_SET_DATA_NONE, VFU_DEV_MSIX_IRQ, 2047, 2) + + hdr = vfio_user_header(VFIO_USER_DEVICE_SET_IRQS, size=len(payload)) + sock.send(hdr + payload) + vfu_run_ctx(ctx) + get_reply(sock, expect=errno.EINVAL) + +def test_device_set_irqs_bad_start_count_range(): + # struct vfio_irq_set + payload = struct.pack("IIIII", 20, VFIO_IRQ_SET_ACTION_MASK | + VFIO_IRQ_SET_DATA_NONE, VFU_DEV_MSIX_IRQ, 2049, 1) + + hdr = vfio_user_header(VFIO_USER_DEVICE_SET_IRQS, size=len(payload)) + sock.send(hdr + payload) + vfu_run_ctx(ctx) + get_reply(sock, expect=errno.EINVAL) + +def test_device_set_irqs_bad_action_for_err_irq(): + # struct vfio_irq_set + payload = struct.pack("IIIII", 20, VFIO_IRQ_SET_ACTION_MASK | + VFIO_IRQ_SET_DATA_NONE, VFU_DEV_ERR_IRQ, 0, 1) + + hdr = vfio_user_header(VFIO_USER_DEVICE_SET_IRQS, size=len(payload)) + sock.send(hdr + payload) + vfu_run_ctx(ctx) + get_reply(sock, expect=errno.EINVAL) + +def test_device_set_irqs_bad_action_for_req_irq(): + # struct vfio_irq_set + payload = struct.pack("IIIII", 20, VFIO_IRQ_SET_ACTION_MASK | + VFIO_IRQ_SET_DATA_NONE, VFU_DEV_REQ_IRQ, 0, 1) + + hdr = vfio_user_header(VFIO_USER_DEVICE_SET_IRQS, size=len(payload)) + sock.send(hdr + payload) + vfu_run_ctx(ctx) + get_reply(sock, expect=errno.EINVAL) + +def test_device_set_irqs_bad_start_for_count_0(): + # struct vfio_irq_set + payload = struct.pack("IIIII", 20, VFIO_IRQ_SET_ACTION_MASK | + VFIO_IRQ_SET_DATA_NONE, VFU_DEV_MSIX_IRQ, 1, 0) + + hdr = vfio_user_header(VFIO_USER_DEVICE_SET_IRQS, size=len(payload)) + sock.send(hdr + payload) + vfu_run_ctx(ctx) + get_reply(sock, expect=errno.EINVAL) + +def test_device_set_irqs_bad_action_for_count_0(): + # struct vfio_irq_set + payload = struct.pack("IIIII", 20, VFIO_IRQ_SET_ACTION_MASK | + VFIO_IRQ_SET_DATA_NONE, VFU_DEV_MSIX_IRQ, 0, 0) + + hdr = vfio_user_header(VFIO_USER_DEVICE_SET_IRQS, size=len(payload)) + sock.send(hdr + payload) + vfu_run_ctx(ctx) + get_reply(sock, expect=errno.EINVAL) + +def test_device_set_irqs_bad_action_and_data_type_for_count_0(): + # struct vfio_irq_set + payload = struct.pack("IIIII", 20, VFIO_IRQ_SET_ACTION_TRIGGER | + VFIO_IRQ_SET_DATA_BOOL, VFU_DEV_MSIX_IRQ, 0, 0) + + hdr = vfio_user_header(VFIO_USER_DEVICE_SET_IRQS, size=len(payload)) + sock.send(hdr + payload) + vfu_run_ctx(ctx) + get_reply(sock, expect=errno.EINVAL) + +def test_device_set_irqs_bad_fds_for_DATA_BOOL(): + # struct vfio_irq_set + payload = struct.pack("IIIII", 20, VFIO_IRQ_SET_ACTION_TRIGGER | + VFIO_IRQ_SET_DATA_BOOL, VFU_DEV_MSIX_IRQ, 0, 1) + + fd = eventfd() + + hdr = vfio_user_header(VFIO_USER_DEVICE_SET_IRQS, size=len(payload)) + sock.sendmsg([hdr + payload], [(socket.SOL_SOCKET, socket.SCM_RIGHTS, + struct.pack("I", fd))]) + vfu_run_ctx(ctx) + get_reply(sock, expect=errno.EINVAL) + + os.close(fd) + +def test_device_set_irqs_bad_fds_for_DATA_NONE(): + # struct vfio_irq_set + payload = struct.pack("IIIII", 20, VFIO_IRQ_SET_ACTION_TRIGGER | + VFIO_IRQ_SET_DATA_NONE, VFU_DEV_MSIX_IRQ, 0, 1) + + fd = eventfd() + + hdr = vfio_user_header(VFIO_USER_DEVICE_SET_IRQS, size=len(payload)) + sock.sendmsg([hdr + payload], [(socket.SOL_SOCKET, socket.SCM_RIGHTS, + struct.pack("I", fd))]) + vfu_run_ctx(ctx) + get_reply(sock, expect=errno.EINVAL) + + os.close(fd) + +def test_device_set_irqs_bad_fds_for_count_2(): + # struct vfio_irq_set + payload = struct.pack("IIIII", 20, VFIO_IRQ_SET_ACTION_TRIGGER | + VFIO_IRQ_SET_DATA_EVENTFD, VFU_DEV_MSIX_IRQ, 0, 2) + + fd = eventfd() + + hdr = vfio_user_header(VFIO_USER_DEVICE_SET_IRQS, size=len(payload)) + sock.sendmsg([hdr + payload], [(socket.SOL_SOCKET, socket.SCM_RIGHTS, + struct.pack("I", fd))]) + vfu_run_ctx(ctx) + get_reply(sock, expect=errno.EINVAL) + + os.close(fd) + +def test_device_set_irqs_disable(): + # struct vfio_irq_set + payload = struct.pack("IIIII", 20, VFIO_IRQ_SET_ACTION_TRIGGER | + VFIO_IRQ_SET_DATA_NONE, VFU_DEV_REQ_IRQ, 0, 0) + + hdr = vfio_user_header(VFIO_USER_DEVICE_SET_IRQS, size=len(payload)) + sock.send(hdr + payload) + vfu_run_ctx(ctx) + get_reply(sock) + + # struct vfio_irq_set + payload = struct.pack("IIIII", 20, VFIO_IRQ_SET_ACTION_TRIGGER | + VFIO_IRQ_SET_DATA_EVENTFD, VFU_DEV_REQ_IRQ, 0, 1) + + hdr = vfio_user_header(VFIO_USER_DEVICE_SET_IRQS, size=len(payload)) + sock.send(hdr + payload) + vfu_run_ctx(ctx) + get_reply(sock) + +def test_device_set_irqs_enable(): + # struct vfio_irq_set + payload = struct.pack("IIIII", 20, VFIO_IRQ_SET_ACTION_TRIGGER | + VFIO_IRQ_SET_DATA_EVENTFD, VFU_DEV_MSIX_IRQ, 0, 1) + + fd = eventfd() + + hdr = vfio_user_header(VFIO_USER_DEVICE_SET_IRQS, size=len(payload)) + sock.sendmsg([hdr + payload], [(socket.SOL_SOCKET, socket.SCM_RIGHTS, + struct.pack("I", fd))]) + vfu_run_ctx(ctx) + get_reply(sock) + +def test_device_set_irqs_trigger_bool_too_small(): + # struct vfio_irq_set + payload = struct.pack("IIIII?", 21, VFIO_IRQ_SET_ACTION_TRIGGER | + VFIO_IRQ_SET_DATA_BOOL, VFU_DEV_MSIX_IRQ, 0, 2, + False) + + hdr = vfio_user_header(VFIO_USER_DEVICE_SET_IRQS, size=len(payload)) + sock.send(hdr + payload) + vfu_run_ctx(ctx) + get_reply(sock, expect=errno.EINVAL) + +def test_device_set_irqs_trigger_bool_too_large(): + # struct vfio_irq_set + payload = struct.pack("IIIII???", 23, VFIO_IRQ_SET_ACTION_TRIGGER | + VFIO_IRQ_SET_DATA_BOOL, VFU_DEV_MSIX_IRQ, 0, 2, + False, False, False) + + hdr = vfio_user_header(VFIO_USER_DEVICE_SET_IRQS, size=len(payload)) + sock.send(hdr + payload) + vfu_run_ctx(ctx) + get_reply(sock, expect=errno.EINVAL) + +def test_device_set_irqs_enable_update(): + # struct vfio_irq_set + payload = struct.pack("IIIII", 20, VFIO_IRQ_SET_ACTION_TRIGGER | + VFIO_IRQ_SET_DATA_EVENTFD, VFU_DEV_MSIX_IRQ, 0, 1) + + fd = eventfd() + + hdr = vfio_user_header(VFIO_USER_DEVICE_SET_IRQS, size=len(payload)) + sock.sendmsg([hdr + payload], [(socket.SOL_SOCKET, socket.SCM_RIGHTS, + struct.pack("I", fd))]) + vfu_run_ctx(ctx) + get_reply(sock) + +def test_device_set_irqs_enable_trigger_none(): + # struct vfio_irq_set + payload = struct.pack("IIIII", 20, VFIO_IRQ_SET_ACTION_TRIGGER | + VFIO_IRQ_SET_DATA_EVENTFD, VFU_DEV_MSIX_IRQ, 0, 2) + + fd1 = eventfd(initval=4) + fd2 = eventfd(initval=8) + + hdr = vfio_user_header(VFIO_USER_DEVICE_SET_IRQS, size=len(payload)) + sock.sendmsg([hdr + payload], [(socket.SOL_SOCKET, socket.SCM_RIGHTS, + struct.pack("II", fd1, fd2))]) + vfu_run_ctx(ctx) + get_reply(sock) + + # struct vfio_irq_set + payload = struct.pack("IIIII", 20, VFIO_IRQ_SET_ACTION_TRIGGER | + VFIO_IRQ_SET_DATA_NONE, VFU_DEV_MSIX_IRQ, 1, 1) + + hdr = vfio_user_header(VFIO_USER_DEVICE_SET_IRQS, size=len(payload)) + sock.send(hdr + payload) + vfu_run_ctx(ctx) + get_reply(sock) + + assert struct.unpack("Q", os.read(fd1, 8))[0] == 4 + assert struct.unpack("Q", os.read(fd2, 8))[0] == 9 + +def test_device_set_irqs_enable_trigger_bool(): + # struct vfio_irq_set + payload = struct.pack("IIIII", 20, VFIO_IRQ_SET_ACTION_TRIGGER | + VFIO_IRQ_SET_DATA_EVENTFD, VFU_DEV_MSIX_IRQ, 0, 2) + + fd1 = eventfd(initval=4) + fd2 = eventfd(initval=8) + + hdr = vfio_user_header(VFIO_USER_DEVICE_SET_IRQS, size=len(payload)) + sock.sendmsg([hdr + payload], [(socket.SOL_SOCKET, socket.SCM_RIGHTS, + struct.pack("II", fd1, fd2))]) + vfu_run_ctx(ctx) + get_reply(sock) + + # struct vfio_irq_set + payload = struct.pack("IIIII??", 22, VFIO_IRQ_SET_ACTION_TRIGGER | + VFIO_IRQ_SET_DATA_BOOL, VFU_DEV_MSIX_IRQ, 0, 2, + False, True) + + hdr = vfio_user_header(VFIO_USER_DEVICE_SET_IRQS, size=len(payload)) + sock.send(hdr + payload) + vfu_run_ctx(ctx) + get_reply(sock) + + assert struct.unpack("Q", os.read(fd1, 8))[0] == 4 + assert struct.unpack("Q", os.read(fd2, 8))[0] == 9 + +def test_device_set_irqs_cleanup(): + vfu_destroy_ctx(ctx) diff --git a/test/unit-tests.c b/test/unit-tests.c index 2d42f6f..3953b0c 100644 --- a/test/unit-tests.c +++ b/test/unit-tests.c @@ -632,214 +632,6 @@ test_dirty_pages_without_dma(UNUSED void **state) } static void -test_device_set_irqs(UNUSED void **state) -{ - vfu_irqs_t *irqs = alloca(sizeof (*irqs) + sizeof (int)); - struct vfio_irq_set irq_set = { 0, }; - //int fd = 0xdead; - - vfu_ctx.irq_count[VFU_DEV_MSIX_IRQ] = 2048; - vfu_ctx.irq_count[VFU_DEV_ERR_IRQ] = 1; - vfu_ctx.irq_count[VFU_DEV_REQ_IRQ] = 1; - vfu_ctx.irqs = irqs; - - memset(irqs, 0, sizeof (*irqs) + sizeof (int)); - - irq_set.argsz = sizeof (irq_set); - - /* - * Validation tests. - */ - - /* bad message size */ - ret = handle_device_set_irqs(&vfu_ctx, mkmsg(VFIO_USER_DEVICE_SET_IRQS, - &irq_set, 0)); - assert_int_equal(-1, ret); - assert_int_equal(EINVAL, errno); - - /* bad .argsz */ - irq_set.argsz = 3; - - ret = handle_device_set_irqs(&vfu_ctx, mkmsg(VFIO_USER_DEVICE_SET_IRQS, - &irq_set, sizeof (irq_set))); - assert_int_equal(-1, ret); - assert_int_equal(EINVAL, errno); - - /* bad .index */ - irq_set.argsz = sizeof (irq_set); - irq_set.index = VFU_DEV_NUM_IRQS; - - ret = handle_device_set_irqs(&vfu_ctx, mkmsg(VFIO_USER_DEVICE_SET_IRQS, - &irq_set, sizeof (irq_set))); - assert_int_equal(-1, ret); - assert_int_equal(EINVAL, errno); - - /* bad flags, MASK and UNMASK */ - irq_set.index = VFU_DEV_MSIX_IRQ; - irq_set.flags = VFIO_IRQ_SET_ACTION_MASK | VFIO_IRQ_SET_ACTION_UNMASK; - - ret = handle_device_set_irqs(&vfu_ctx, mkmsg(VFIO_USER_DEVICE_SET_IRQS, - &irq_set, sizeof (irq_set))); - assert_int_equal(-1, ret); - assert_int_equal(EINVAL, errno); - - /* bad flags, DATA_NONE and DATA_BOOL */ - irq_set.flags = VFIO_IRQ_SET_ACTION_MASK | VFIO_IRQ_SET_DATA_NONE | - VFIO_IRQ_SET_DATA_BOOL; - - ret = handle_device_set_irqs(&vfu_ctx, mkmsg(VFIO_USER_DEVICE_SET_IRQS, - &irq_set, sizeof (irq_set))); - assert_int_equal(-1, ret); - assert_int_equal(EINVAL, errno); - - /* bad start, count range */ - irq_set.flags = VFIO_IRQ_SET_ACTION_MASK | VFIO_IRQ_SET_DATA_NONE; - irq_set.start = 2047; - irq_set.count = 2; - - ret = handle_device_set_irqs(&vfu_ctx, mkmsg(VFIO_USER_DEVICE_SET_IRQS, - &irq_set, sizeof (irq_set))); - assert_int_equal(-1, ret); - assert_int_equal(EINVAL, errno); - - /* bad start, count range */ - irq_set.start = 2049; - irq_set.count = 1; - - ret = handle_device_set_irqs(&vfu_ctx, mkmsg(VFIO_USER_DEVICE_SET_IRQS, - &irq_set, sizeof (irq_set))); - assert_int_equal(-1, ret); - assert_int_equal(EINVAL, errno); - - /* bad action for err irq */ - irq_set.start = 0; - irq_set.count = 1; - irq_set.index = VFU_DEV_ERR_IRQ; - - ret = handle_device_set_irqs(&vfu_ctx, mkmsg(VFIO_USER_DEVICE_SET_IRQS, - &irq_set, sizeof (irq_set))); - assert_int_equal(-1, ret); - assert_int_equal(EINVAL, errno); - - /* bad action for req irq */ - irq_set.index = VFU_DEV_REQ_IRQ; - - ret = handle_device_set_irqs(&vfu_ctx, mkmsg(VFIO_USER_DEVICE_SET_IRQS, - &irq_set, sizeof (irq_set))); - assert_int_equal(-1, ret); - assert_int_equal(EINVAL, errno); - - /* bad start for count == 0 */ - irq_set.start = 1; - irq_set.count = 0; - irq_set.index = VFU_DEV_MSIX_IRQ; - - ret = handle_device_set_irqs(&vfu_ctx, mkmsg(VFIO_USER_DEVICE_SET_IRQS, - &irq_set, sizeof (irq_set))); - assert_int_equal(-1, ret); - assert_int_equal(EINVAL, errno); - - /* bad action for count == 0 */ - irq_set.flags = VFIO_IRQ_SET_ACTION_MASK | VFIO_IRQ_SET_DATA_NONE; - irq_set.count = 0; - irq_set.start = 0; - - ret = handle_device_set_irqs(&vfu_ctx, mkmsg(VFIO_USER_DEVICE_SET_IRQS, - &irq_set, sizeof (irq_set))); - assert_int_equal(-1, ret); - assert_int_equal(EINVAL, errno); - - /* bad action and data type for count == 0 */ - irq_set.flags = VFIO_IRQ_SET_ACTION_TRIGGER | VFIO_IRQ_SET_DATA_BOOL; - irq_set.count = 0; - irq_set.start = 0; - - ret = handle_device_set_irqs(&vfu_ctx, mkmsg(VFIO_USER_DEVICE_SET_IRQS, - &irq_set, sizeof (irq_set))); - assert_int_equal(-1, ret); - assert_int_equal(EINVAL, errno); - - /* bad fds for DATA_BOOL */ - irq_set.flags = VFIO_IRQ_SET_ACTION_TRIGGER | VFIO_IRQ_SET_DATA_BOOL; - irq_set.count = 1; - irq_set.start = 0; - nr_fds = 1; - fds[0] = 0xbeef; - - ret = handle_device_set_irqs(&vfu_ctx, mkmsg(VFIO_USER_DEVICE_SET_IRQS, - &irq_set, sizeof (irq_set))); - assert_int_equal(-1, ret); - assert_int_equal(EINVAL, errno); - - /* bad fds for DATA_NONE */ - irq_set.flags = VFIO_IRQ_SET_ACTION_TRIGGER | VFIO_IRQ_SET_DATA_NONE; - irq_set.count = 1; - irq_set.start = 0; - - ret = handle_device_set_irqs(&vfu_ctx, mkmsg(VFIO_USER_DEVICE_SET_IRQS, - &irq_set, sizeof (irq_set))); - assert_int_equal(-1, ret); - assert_int_equal(EINVAL, errno); - - /* bad fds for count == 2 */ - irq_set.flags = VFIO_IRQ_SET_ACTION_TRIGGER | VFIO_IRQ_SET_DATA_EVENTFD; - irq_set.count = 2; - irq_set.start = 0; - - ret = handle_device_set_irqs(&vfu_ctx, mkmsg(VFIO_USER_DEVICE_SET_IRQS, - &irq_set, sizeof (irq_set))); - assert_int_equal(-1, ret); - assert_int_equal(EINVAL, errno); - - irqs->err_efd = irqs->req_efd = -1; - - /* - * Basic disable functionality. - */ - - nr_fds = 0; - - irq_set.index = VFU_DEV_REQ_IRQ; - irq_set.flags = VFIO_IRQ_SET_ACTION_TRIGGER | VFIO_IRQ_SET_DATA_NONE; - irq_set.count = 0; - irq_set.start = 0; - - ret = handle_device_set_irqs(&vfu_ctx, mkmsg(VFIO_USER_DEVICE_SET_IRQS, - &irq_set, sizeof (irq_set))); - assert_int_equal(0, ret); - - irq_set.index = VFU_DEV_REQ_IRQ; - irq_set.flags = VFIO_IRQ_SET_ACTION_TRIGGER | VFIO_IRQ_SET_DATA_EVENTFD; - irq_set.count = 1; - irq_set.start = 0; - - ret = handle_device_set_irqs(&vfu_ctx, mkmsg(VFIO_USER_DEVICE_SET_IRQS, - &irq_set, sizeof (irq_set))); - assert_int_equal(0, ret); - - /* - * Basic enable functionality. - */ - - irq_set.index = VFU_DEV_MSIX_IRQ; - vfu_ctx.irq_count[VFU_DEV_MSIX_IRQ] = 1; - irqs->efds[0] = -1; - - nr_fds = 1; - fds[0] = 0xbeef; - - irq_set.index = VFU_DEV_MSIX_IRQ; - irq_set.flags = VFIO_IRQ_SET_ACTION_TRIGGER | VFIO_IRQ_SET_DATA_EVENTFD; - irq_set.count = 1; - irq_set.start = 0; - - ret = handle_device_set_irqs(&vfu_ctx, mkmsg(VFIO_USER_DEVICE_SET_IRQS, - &irq_set, sizeof (irq_set))); - assert_int_equal(0, ret); - assert_int_equal(0xbeef, irqs->efds[0]); - -} -static void test_migration_state_transitions(void **state UNUSED) { bool (*f)(uint32_t, uint32_t) = vfio_migr_state_transition_is_valid; @@ -1262,7 +1054,6 @@ main(void) cmocka_unit_test_setup(test_vfu_setup_device_dma, setup), cmocka_unit_test_setup(test_setup_sparse_region, setup), cmocka_unit_test_setup(test_dirty_pages_without_dma, setup), - cmocka_unit_test_setup(test_device_set_irqs, setup), cmocka_unit_test_setup(test_migration_state_transitions, setup), cmocka_unit_test_setup_teardown(test_setup_migration_region_too_small, setup_test_setup_migration_region, |