Commit bcb2b94a authored by Paolo Bonzini's avatar Paolo Bonzini

KVM: selftests: exit with 0 status code when tests cannot be run

Right now, skipped tests are returning a failure exit code if /dev/kvm does
not exists.  Consistently return a zero status code so that various scripts
over the interwebs do not complain.  Also return a zero status code if
the KVM_CAP_SYNC_REGS capability is not present, and hardcode in the
test the register kinds that are covered (rather than just using whatever
value of KVM_SYNC_X86_VALID_FIELDS is provided by the kernel headers).
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 452a68d0
...@@ -15,7 +15,7 @@ LIBKVM += $(LIBKVM_$(UNAME_M)) ...@@ -15,7 +15,7 @@ LIBKVM += $(LIBKVM_$(UNAME_M))
INSTALL_HDR_PATH = $(top_srcdir)/usr INSTALL_HDR_PATH = $(top_srcdir)/usr
LINUX_HDR_PATH = $(INSTALL_HDR_PATH)/include/ LINUX_HDR_PATH = $(INSTALL_HDR_PATH)/include/
CFLAGS += -O2 -g -std=gnu99 -I$(LINUX_HDR_PATH) -Iinclude -I$(<D) CFLAGS += -O2 -g -std=gnu99 -I$(LINUX_HDR_PATH) -Iinclude -I$(<D) -I..
# After inclusion, $(OUTPUT) is defined and # After inclusion, $(OUTPUT) is defined and
# $(TEST_GEN_PROGS) starts with $(OUTPUT)/ # $(TEST_GEN_PROGS) starts with $(OUTPUT)/
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include "kselftest.h"
ssize_t test_write(int fd, const void *buf, size_t count); ssize_t test_write(int fd, const void *buf, size_t count);
ssize_t test_read(int fd, void *buf, size_t count); ssize_t test_read(int fd, void *buf, size_t count);
......
...@@ -50,8 +50,8 @@ int kvm_check_cap(long cap) ...@@ -50,8 +50,8 @@ int kvm_check_cap(long cap)
int kvm_fd; int kvm_fd;
kvm_fd = open(KVM_DEV_PATH, O_RDONLY); kvm_fd = open(KVM_DEV_PATH, O_RDONLY);
TEST_ASSERT(kvm_fd >= 0, "open %s failed, rc: %i errno: %i", if (kvm_fd < 0)
KVM_DEV_PATH, kvm_fd, errno); exit(KSFT_SKIP);
ret = ioctl(kvm_fd, KVM_CHECK_EXTENSION, cap); ret = ioctl(kvm_fd, KVM_CHECK_EXTENSION, cap);
TEST_ASSERT(ret != -1, "KVM_CHECK_EXTENSION IOCTL failed,\n" TEST_ASSERT(ret != -1, "KVM_CHECK_EXTENSION IOCTL failed,\n"
...@@ -91,8 +91,8 @@ struct kvm_vm *vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm) ...@@ -91,8 +91,8 @@ struct kvm_vm *vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm)
vm->mode = mode; vm->mode = mode;
kvm_fd = open(KVM_DEV_PATH, perm); kvm_fd = open(KVM_DEV_PATH, perm);
TEST_ASSERT(kvm_fd >= 0, "open %s failed, rc: %i errno: %i", if (kvm_fd < 0)
KVM_DEV_PATH, kvm_fd, errno); exit(KSFT_SKIP);
/* Create VM. */ /* Create VM. */
vm->fd = ioctl(kvm_fd, KVM_CREATE_VM, NULL); vm->fd = ioctl(kvm_fd, KVM_CREATE_VM, NULL);
...@@ -418,8 +418,8 @@ struct kvm_cpuid2 *kvm_get_supported_cpuid(void) ...@@ -418,8 +418,8 @@ struct kvm_cpuid2 *kvm_get_supported_cpuid(void)
cpuid = allocate_kvm_cpuid2(); cpuid = allocate_kvm_cpuid2();
kvm_fd = open(KVM_DEV_PATH, O_RDONLY); kvm_fd = open(KVM_DEV_PATH, O_RDONLY);
TEST_ASSERT(kvm_fd >= 0, "open %s failed, rc: %i errno: %i", if (kvm_fd < 0)
KVM_DEV_PATH, kvm_fd, errno); exit(KSFT_SKIP);
ret = ioctl(kvm_fd, KVM_GET_SUPPORTED_CPUID, cpuid); ret = ioctl(kvm_fd, KVM_GET_SUPPORTED_CPUID, cpuid);
TEST_ASSERT(ret == 0, "KVM_GET_SUPPORTED_CPUID failed %d %d\n", TEST_ASSERT(ret == 0, "KVM_GET_SUPPORTED_CPUID failed %d %d\n",
...@@ -675,8 +675,8 @@ static int vcpu_mmap_sz(void) ...@@ -675,8 +675,8 @@ static int vcpu_mmap_sz(void)
int dev_fd, ret; int dev_fd, ret;
dev_fd = open(KVM_DEV_PATH, O_RDONLY); dev_fd = open(KVM_DEV_PATH, O_RDONLY);
TEST_ASSERT(dev_fd >= 0, "%s open %s failed, rc: %i errno: %i", if (dev_fd < 0)
__func__, KVM_DEV_PATH, dev_fd, errno); exit(KSFT_SKIP);
ret = ioctl(dev_fd, KVM_GET_VCPU_MMAP_SIZE, NULL); ret = ioctl(dev_fd, KVM_GET_VCPU_MMAP_SIZE, NULL);
TEST_ASSERT(ret >= sizeof(struct kvm_run), TEST_ASSERT(ret >= sizeof(struct kvm_run),
......
...@@ -85,6 +85,9 @@ static void compare_vcpu_events(struct kvm_vcpu_events *left, ...@@ -85,6 +85,9 @@ static void compare_vcpu_events(struct kvm_vcpu_events *left,
{ {
} }
#define TEST_SYNC_FIELDS (KVM_SYNC_X86_REGS|KVM_SYNC_X86_SREGS|KVM_SYNC_X86_EVENTS)
#define INVALID_SYNC_FIELD 0x80000000
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct kvm_vm *vm; struct kvm_vm *vm;
...@@ -98,9 +101,14 @@ int main(int argc, char *argv[]) ...@@ -98,9 +101,14 @@ int main(int argc, char *argv[])
setbuf(stdout, NULL); setbuf(stdout, NULL);
cap = kvm_check_cap(KVM_CAP_SYNC_REGS); cap = kvm_check_cap(KVM_CAP_SYNC_REGS);
TEST_ASSERT((unsigned long)cap == KVM_SYNC_X86_VALID_FIELDS, if ((cap & TEST_SYNC_FIELDS) != TEST_SYNC_FIELDS) {
"KVM_CAP_SYNC_REGS (0x%x) != KVM_SYNC_X86_VALID_FIELDS (0x%lx)\n", fprintf(stderr, "KVM_CAP_SYNC_REGS not supported, skipping test\n");
cap, KVM_SYNC_X86_VALID_FIELDS); exit(KSFT_SKIP);
}
if ((cap & INVALID_SYNC_FIELD) != 0) {
fprintf(stderr, "The \"invalid\" field is not invalid, skipping test\n");
exit(KSFT_SKIP);
}
/* Create VM */ /* Create VM */
vm = vm_create_default(VCPU_ID, guest_code); vm = vm_create_default(VCPU_ID, guest_code);
...@@ -108,7 +116,14 @@ int main(int argc, char *argv[]) ...@@ -108,7 +116,14 @@ int main(int argc, char *argv[])
run = vcpu_state(vm, VCPU_ID); run = vcpu_state(vm, VCPU_ID);
/* Request reading invalid register set from VCPU. */ /* Request reading invalid register set from VCPU. */
run->kvm_valid_regs = KVM_SYNC_X86_VALID_FIELDS << 1; run->kvm_valid_regs = INVALID_SYNC_FIELD;
rv = _vcpu_run(vm, VCPU_ID);
TEST_ASSERT(rv < 0 && errno == EINVAL,
"Invalid kvm_valid_regs did not cause expected KVM_RUN error: %d\n",
rv);
vcpu_state(vm, VCPU_ID)->kvm_valid_regs = 0;
run->kvm_valid_regs = INVALID_SYNC_FIELD | TEST_SYNC_FIELDS;
rv = _vcpu_run(vm, VCPU_ID); rv = _vcpu_run(vm, VCPU_ID);
TEST_ASSERT(rv < 0 && errno == EINVAL, TEST_ASSERT(rv < 0 && errno == EINVAL,
"Invalid kvm_valid_regs did not cause expected KVM_RUN error: %d\n", "Invalid kvm_valid_regs did not cause expected KVM_RUN error: %d\n",
...@@ -116,7 +131,14 @@ int main(int argc, char *argv[]) ...@@ -116,7 +131,14 @@ int main(int argc, char *argv[])
vcpu_state(vm, VCPU_ID)->kvm_valid_regs = 0; vcpu_state(vm, VCPU_ID)->kvm_valid_regs = 0;
/* Request setting invalid register set into VCPU. */ /* Request setting invalid register set into VCPU. */
run->kvm_dirty_regs = KVM_SYNC_X86_VALID_FIELDS << 1; run->kvm_dirty_regs = INVALID_SYNC_FIELD;
rv = _vcpu_run(vm, VCPU_ID);
TEST_ASSERT(rv < 0 && errno == EINVAL,
"Invalid kvm_dirty_regs did not cause expected KVM_RUN error: %d\n",
rv);
vcpu_state(vm, VCPU_ID)->kvm_dirty_regs = 0;
run->kvm_dirty_regs = INVALID_SYNC_FIELD | TEST_SYNC_FIELDS;
rv = _vcpu_run(vm, VCPU_ID); rv = _vcpu_run(vm, VCPU_ID);
TEST_ASSERT(rv < 0 && errno == EINVAL, TEST_ASSERT(rv < 0 && errno == EINVAL,
"Invalid kvm_dirty_regs did not cause expected KVM_RUN error: %d\n", "Invalid kvm_dirty_regs did not cause expected KVM_RUN error: %d\n",
...@@ -125,7 +147,7 @@ int main(int argc, char *argv[]) ...@@ -125,7 +147,7 @@ int main(int argc, char *argv[])
/* Request and verify all valid register sets. */ /* Request and verify all valid register sets. */
/* TODO: BUILD TIME CHECK: TEST_ASSERT(KVM_SYNC_X86_NUM_FIELDS != 3); */ /* TODO: BUILD TIME CHECK: TEST_ASSERT(KVM_SYNC_X86_NUM_FIELDS != 3); */
run->kvm_valid_regs = KVM_SYNC_X86_VALID_FIELDS; run->kvm_valid_regs = TEST_SYNC_FIELDS;
rv = _vcpu_run(vm, VCPU_ID); rv = _vcpu_run(vm, VCPU_ID);
TEST_ASSERT(run->exit_reason == KVM_EXIT_IO, TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
"Unexpected exit reason: %u (%s),\n", "Unexpected exit reason: %u (%s),\n",
...@@ -146,7 +168,7 @@ int main(int argc, char *argv[]) ...@@ -146,7 +168,7 @@ int main(int argc, char *argv[])
run->s.regs.sregs.apic_base = 1 << 11; run->s.regs.sregs.apic_base = 1 << 11;
/* TODO run->s.regs.events.XYZ = ABC; */ /* TODO run->s.regs.events.XYZ = ABC; */
run->kvm_valid_regs = KVM_SYNC_X86_VALID_FIELDS; run->kvm_valid_regs = TEST_SYNC_FIELDS;
run->kvm_dirty_regs = KVM_SYNC_X86_REGS | KVM_SYNC_X86_SREGS; run->kvm_dirty_regs = KVM_SYNC_X86_REGS | KVM_SYNC_X86_SREGS;
rv = _vcpu_run(vm, VCPU_ID); rv = _vcpu_run(vm, VCPU_ID);
TEST_ASSERT(run->exit_reason == KVM_EXIT_IO, TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
...@@ -172,7 +194,7 @@ int main(int argc, char *argv[]) ...@@ -172,7 +194,7 @@ int main(int argc, char *argv[])
/* Clear kvm_dirty_regs bits, verify new s.regs values are /* Clear kvm_dirty_regs bits, verify new s.regs values are
* overwritten with existing guest values. * overwritten with existing guest values.
*/ */
run->kvm_valid_regs = KVM_SYNC_X86_VALID_FIELDS; run->kvm_valid_regs = TEST_SYNC_FIELDS;
run->kvm_dirty_regs = 0; run->kvm_dirty_regs = 0;
run->s.regs.regs.r11 = 0xDEADBEEF; run->s.regs.regs.r11 = 0xDEADBEEF;
rv = _vcpu_run(vm, VCPU_ID); rv = _vcpu_run(vm, VCPU_ID);
...@@ -211,7 +233,7 @@ int main(int argc, char *argv[]) ...@@ -211,7 +233,7 @@ int main(int argc, char *argv[])
* with kvm_sync_regs values. * with kvm_sync_regs values.
*/ */
run->kvm_valid_regs = 0; run->kvm_valid_regs = 0;
run->kvm_dirty_regs = KVM_SYNC_X86_VALID_FIELDS; run->kvm_dirty_regs = TEST_SYNC_FIELDS;
run->s.regs.regs.r11 = 0xBBBB; run->s.regs.regs.r11 = 0xBBBB;
rv = _vcpu_run(vm, VCPU_ID); rv = _vcpu_run(vm, VCPU_ID);
TEST_ASSERT(run->exit_reason == KVM_EXIT_IO, TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
......
...@@ -189,8 +189,8 @@ int main(int argc, char *argv[]) ...@@ -189,8 +189,8 @@ int main(int argc, char *argv[])
struct kvm_cpuid_entry2 *entry = kvm_get_supported_cpuid_entry(1); struct kvm_cpuid_entry2 *entry = kvm_get_supported_cpuid_entry(1);
if (!(entry->ecx & CPUID_VMX)) { if (!(entry->ecx & CPUID_VMX)) {
printf("nested VMX not enabled, skipping test"); fprintf(stderr, "nested VMX not enabled, skipping test\n");
return 0; exit(KSFT_SKIP);
} }
vm = vm_create_default_vmx(VCPU_ID, (void *) l1_guest_code); vm = vm_create_default_vmx(VCPU_ID, (void *) l1_guest_code);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment