int open_path_or_exit(const char *path, int flags);
 int open_kvm_dev_path_or_exit(void);
 int kvm_check_cap(long cap);
-int vm_check_cap(struct kvm_vm *vm, long cap);
-int vm_enable_cap(struct kvm_vm *vm, struct kvm_enable_cap *cap);
 
 #define __KVM_SYSCALL_ERROR(_name, _ret) \
        "%s failed, rc: %i errno: %i (%s)", (_name), (_ret), errno, strerror(errno)
 #define vcpu_ioctl(vm, vcpuid, cmd, arg) \
        _vcpu_ioctl(vm, vcpuid, cmd, #cmd, arg)
 
+/*
+ * Looks up and returns the value corresponding to the capability
+ * (KVM_CAP_*) given by cap.
+ */
+static inline int vm_check_cap(struct kvm_vm *vm, long cap)
+{
+       int ret =  __vm_ioctl(vm, KVM_CHECK_EXTENSION, (void *)cap);
+
+       TEST_ASSERT(ret >= 0, KVM_IOCTL_ERROR(KVM_CHECK_EXTENSION, ret));
+       return ret;
+}
+
+static inline void vm_enable_cap(struct kvm_vm *vm, struct kvm_enable_cap *cap)
+{
+       vm_ioctl(vm, KVM_ENABLE_CAP, cap);
+}
+
 void vm_enable_dirty_ring(struct kvm_vm *vm, uint32_t ring_size);
 const char *vm_guest_mode_string(uint32_t i);
 
 void kvm_vm_free(struct kvm_vm *vmp);
 void kvm_vm_restart(struct kvm_vm *vmp);
 void kvm_vm_release(struct kvm_vm *vmp);
-void kvm_vm_get_dirty_log(struct kvm_vm *vm, int slot, void *log);
-void kvm_vm_clear_dirty_log(struct kvm_vm *vm, int slot, void *log,
-                           uint64_t first_page, uint32_t num_pages);
-uint32_t kvm_vm_reset_dirty_ring(struct kvm_vm *vm);
-
 int kvm_memcmp_hva_gva(void *hva, struct kvm_vm *vm, const vm_vaddr_t gva,
                       size_t len);
-
 void kvm_vm_elf_load(struct kvm_vm *vm, const char *filename);
 int kvm_memfd_alloc(size_t size, bool hugepages);
 
 void vm_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent);
 
+static inline void kvm_vm_get_dirty_log(struct kvm_vm *vm, int slot, void *log)
+{
+       struct kvm_dirty_log args = { .dirty_bitmap = log, .slot = slot };
+
+       vm_ioctl(vm, KVM_GET_DIRTY_LOG, &args);
+}
+
+static inline void kvm_vm_clear_dirty_log(struct kvm_vm *vm, int slot, void *log,
+                                         uint64_t first_page, uint32_t num_pages)
+{
+       struct kvm_clear_dirty_log args = {
+               .dirty_bitmap = log,
+               .slot = slot,
+               .first_page = first_page,
+               .num_pages = num_pages
+       };
+
+       vm_ioctl(vm, KVM_CLEAR_DIRTY_LOG, &args);
+}
+
+static inline uint32_t kvm_vm_reset_dirty_ring(struct kvm_vm *vm)
+{
+       return __vm_ioctl(vm, KVM_RESET_DIRTY_RINGS, NULL);
+}
+
+static inline int vm_get_stats_fd(struct kvm_vm *vm)
+{
+       int fd = __vm_ioctl(vm, KVM_GET_STATS_FD, NULL);
+
+       TEST_ASSERT(fd >= 0, KVM_IOCTL_ERROR(KVM_GET_STATS_FD, fd));
+       return fd;
+}
+
 /*
  * VM VCPU Dump
  *
 
 void assert_on_unhandled_exception(struct kvm_vm *vm, uint32_t vcpuid);
 
-int vm_get_stats_fd(struct kvm_vm *vm);
-
 uint32_t guest_get_vcpuid(void);
 
 #endif /* SELFTEST_KVM_UTIL_BASE_H */
 
        return ret;
 }
 
-/* VM Check Capability
- *
- * Input Args:
- *   vm - Virtual Machine
- *   cap - Capability
- *
- * Output Args: None
- *
- * Return:
- *   On success, the Value corresponding to the capability (KVM_CAP_*)
- *   specified by the value of cap.  On failure a TEST_ASSERT failure
- *   is produced.
- *
- * Looks up and returns the value corresponding to the capability
- * (KVM_CAP_*) given by cap.
- */
-int vm_check_cap(struct kvm_vm *vm, long cap)
-{
-       int ret;
-
-       ret = ioctl(vm->fd, KVM_CHECK_EXTENSION, cap);
-       TEST_ASSERT(ret >= 0, "KVM_CHECK_EXTENSION VM IOCTL failed,\n"
-               "  rc: %i errno: %i", ret, errno);
-
-       return ret;
-}
-
-/* VM Enable Capability
- *
- * Input Args:
- *   vm - Virtual Machine
- *   cap - Capability
- *
- * Output Args: None
- *
- * Return: On success, 0. On failure a TEST_ASSERT failure is produced.
- *
- * Enables a capability (KVM_CAP_*) on the VM.
- */
-int vm_enable_cap(struct kvm_vm *vm, struct kvm_enable_cap *cap)
-{
-       int ret;
-
-       ret = ioctl(vm->fd, KVM_ENABLE_CAP, cap);
-       TEST_ASSERT(ret == 0, "KVM_ENABLE_CAP IOCTL failed,\n"
-               "  rc: %i errno: %i", ret, errno);
-
-       return ret;
-}
-
 void vm_enable_dirty_ring(struct kvm_vm *vm, uint32_t ring_size)
 {
        struct kvm_enable_cap cap = { 0 };
        }
 }
 
-void kvm_vm_get_dirty_log(struct kvm_vm *vm, int slot, void *log)
-{
-       struct kvm_dirty_log args = { .dirty_bitmap = log, .slot = slot };
-       int ret;
-
-       ret = ioctl(vm->fd, KVM_GET_DIRTY_LOG, &args);
-       TEST_ASSERT(ret == 0, "%s: KVM_GET_DIRTY_LOG failed: %s",
-                   __func__, strerror(-ret));
-}
-
-void kvm_vm_clear_dirty_log(struct kvm_vm *vm, int slot, void *log,
-                           uint64_t first_page, uint32_t num_pages)
-{
-       struct kvm_clear_dirty_log args = {
-               .dirty_bitmap = log, .slot = slot,
-               .first_page = first_page,
-               .num_pages = num_pages
-       };
-       int ret;
-
-       ret = ioctl(vm->fd, KVM_CLEAR_DIRTY_LOG, &args);
-       TEST_ASSERT(ret == 0, "%s: KVM_CLEAR_DIRTY_LOG failed: %s",
-                   __func__, strerror(-ret));
-}
-
-uint32_t kvm_vm_reset_dirty_ring(struct kvm_vm *vm)
-{
-       return ioctl(vm->fd, KVM_RESET_DIRTY_RINGS);
-}
-
 /*
  * Userspace Memory Region Find
  *
        }
 
        region->region.memory_size = 0;
-       ret = ioctl(vm->fd, KVM_SET_USER_MEMORY_REGION, ®ion->region);
-       TEST_ASSERT(ret == 0, "KVM_SET_USER_MEMORY_REGION IOCTL failed, "
-                   "rc: %i errno: %i", ret, errno);
+       vm_ioctl(vm, KVM_SET_USER_MEMORY_REGION, ®ion->region);
 
        sparsebit_free(®ion->unused_phy_pages);
        ret = munmap(region->mmap_start, region->mmap_size);
        region->region.guest_phys_addr = guest_paddr;
        region->region.memory_size = npages * vm->page_size;
        region->region.userspace_addr = (uintptr_t) region->host_mem;
-       ret = ioctl(vm->fd, KVM_SET_USER_MEMORY_REGION, ®ion->region);
+       ret = __vm_ioctl(vm, KVM_SET_USER_MEMORY_REGION, ®ion->region);
        TEST_ASSERT(ret == 0, "KVM_SET_USER_MEMORY_REGION IOCTL failed,\n"
                "  rc: %i errno: %i\n"
                "  slot: %u flags: 0x%x\n"
 
        region->region.flags = flags;
 
-       ret = ioctl(vm->fd, KVM_SET_USER_MEMORY_REGION, ®ion->region);
+       ret = __vm_ioctl(vm, KVM_SET_USER_MEMORY_REGION, ®ion->region);
 
        TEST_ASSERT(ret == 0, "KVM_SET_USER_MEMORY_REGION IOCTL failed,\n"
                "  rc: %i errno: %i slot: %u flags: 0x%x",
 
        region->region.guest_phys_addr = new_gpa;
 
-       ret = ioctl(vm->fd, KVM_SET_USER_MEMORY_REGION, ®ion->region);
+       ret = __vm_ioctl(vm, KVM_SET_USER_MEMORY_REGION, ®ion->region);
 
        TEST_ASSERT(!ret, "KVM_SET_USER_MEMORY_REGION failed\n"
                    "ret: %i errno: %i slot: %u new_gpa: 0x%lx",
        /* Allocate and initialize new vcpu structure. */
        vcpu = calloc(1, sizeof(*vcpu));
        TEST_ASSERT(vcpu != NULL, "Insufficient Memory");
+
        vcpu->id = vcpuid;
-       vcpu->fd = ioctl(vm->fd, KVM_CREATE_VCPU, vcpuid);
-       TEST_ASSERT(vcpu->fd >= 0, "KVM_CREATE_VCPU failed, rc: %i errno: %i",
-               vcpu->fd, errno);
+       vcpu->fd = __vm_ioctl(vm, KVM_CREATE_VCPU, (void *)(unsigned long)vcpuid);
+       TEST_ASSERT(vcpu->fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_VCPU, vcpu->fd));
 
        TEST_ASSERT(vcpu_mmap_sz() >= sizeof(*vcpu->state), "vcpu mmap size "
                "smaller than expected, vcpu_mmap_sz: %i expected_min: %zi",
  */
 void vm_create_irqchip(struct kvm_vm *vm)
 {
-       int ret;
-
-       ret = ioctl(vm->fd, KVM_CREATE_IRQCHIP, 0);
-       TEST_ASSERT(ret == 0, "KVM_CREATE_IRQCHIP IOCTL failed, "
-               "rc: %i errno: %i", ret, errno);
+       vm_ioctl(vm, KVM_CREATE_IRQCHIP, NULL);
 
        vm->has_irqchip = true;
 }
        create_dev.type = type;
        create_dev.fd = -1;
        create_dev.flags = test ? KVM_CREATE_DEVICE_TEST : 0;
-       ret = ioctl(vm_get_fd(vm), KVM_CREATE_DEVICE, &create_dev);
+       ret = __vm_ioctl(vm, KVM_CREATE_DEVICE, &create_dev);
        *fd = create_dev.fd;
        return ret;
 }
 {
        int ret = _kvm_irq_line(vm, irq, level);
 
-       TEST_ASSERT(ret >= 0, "KVM_IRQ_LINE failed, rc: %i errno: %i", ret, errno);
+       TEST_ASSERT(ret >= 0, KVM_IOCTL_ERROR(KVM_IRQ_LINE, ret));
 }
 
 struct kvm_irq_routing *kvm_gsi_routing_create(void)
        int ret;
 
        assert(routing);
-       ret = ioctl(vm_get_fd(vm), KVM_SET_GSI_ROUTING, routing);
+       ret = __vm_ioctl(vm, KVM_SET_GSI_ROUTING, routing);
        free(routing);
 
        return ret;
        int ret;
 
        ret = _kvm_gsi_routing_write(vm, routing);
-       TEST_ASSERT(ret == 0, "KVM_SET_GSI_ROUTING failed, rc: %i errno: %i",
-                               ret, errno);
+       TEST_ASSERT(!ret, KVM_IOCTL_ERROR(KVM_SET_GSI_ROUTING, ret));
 }
 
 /*
        n = DIV_ROUND_UP(size, vm_guest_mode_params[mode].page_size);
        return vm_adjust_num_guest_pages(mode, n);
 }
-
-int vm_get_stats_fd(struct kvm_vm *vm)
-{
-       return ioctl(vm->fd, KVM_GET_STATS_FD, NULL);
-}