Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

kvm: selftests: add sync_regs_test

This includes the infrastructure to map the test into the guest and
run code from the test program inside a VM.

Signed-off-by: Ken Hofsass <hofsass@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

+595 -1
+2 -1
tools/testing/selftests/kvm/Makefile
··· 3 3 top_srcdir = ../../../../ 4 4 UNAME_M := $(shell uname -m) 5 5 6 - LIBKVM = lib/assert.c lib/kvm_util.c lib/sparsebit.c 6 + LIBKVM = lib/assert.c lib/elf.c lib/io.c lib/kvm_util.c lib/sparsebit.c 7 7 LIBKVM_x86_64 = lib/x86.c 8 8 9 9 TEST_GEN_PROGS_x86_64 = set_sregs_test 10 + TEST_GEN_PROGS_x86_64 += sync_regs_test 10 11 11 12 TEST_GEN_PROGS += $(TEST_GEN_PROGS_$(UNAME_M)) 12 13 LIBKVM += $(LIBKVM_$(UNAME_M))
+3
tools/testing/selftests/kvm/include/kvm_util.h
··· 57 57 int kvm_memcmp_hva_gva(void *hva, 58 58 struct kvm_vm *vm, const vm_vaddr_t gva, size_t len); 59 59 60 + void kvm_vm_elf_load(struct kvm_vm *vm, const char *filename, 61 + uint32_t data_memslot, uint32_t pgd_memslot); 62 + 60 63 void vm_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent); 61 64 void vcpu_dump(FILE *stream, struct kvm_vm *vm, 62 65 uint32_t vcpuid, uint8_t indent);
+197
tools/testing/selftests/kvm/lib/elf.c
··· 1 + /* 2 + * tools/testing/selftests/kvm/lib/elf.c 3 + * 4 + * Copyright (C) 2018, Google LLC. 5 + * 6 + * This work is licensed under the terms of the GNU GPL, version 2. 7 + */ 8 + 9 + #include "test_util.h" 10 + 11 + #include <bits/endian.h> 12 + #include <linux/elf.h> 13 + 14 + #include "kvm_util.h" 15 + #include "kvm_util_internal.h" 16 + 17 + static void elfhdr_get(const char *filename, Elf64_Ehdr *hdrp) 18 + { 19 + off_t offset_rv; 20 + 21 + /* Open the ELF file. */ 22 + int fd; 23 + fd = open(filename, O_RDONLY); 24 + TEST_ASSERT(fd >= 0, "Failed to open ELF file,\n" 25 + " filename: %s\n" 26 + " rv: %i errno: %i", filename, fd, errno); 27 + 28 + /* Read in and validate ELF Identification Record. 29 + * The ELF Identification record is the first 16 (EI_NIDENT) bytes 30 + * of the ELF header, which is at the beginning of the ELF file. 31 + * For now it is only safe to read the first EI_NIDENT bytes. Once 32 + * read and validated, the value of e_ehsize can be used to determine 33 + * the real size of the ELF header. 34 + */ 35 + unsigned char ident[EI_NIDENT]; 36 + test_read(fd, ident, sizeof(ident)); 37 + TEST_ASSERT((ident[EI_MAG0] == ELFMAG0) && (ident[EI_MAG1] == ELFMAG1) 38 + && (ident[EI_MAG2] == ELFMAG2) && (ident[EI_MAG3] == ELFMAG3), 39 + "ELF MAGIC Mismatch,\n" 40 + " filename: %s\n" 41 + " ident[EI_MAG0 - EI_MAG3]: %02x %02x %02x %02x\n" 42 + " Expected: %02x %02x %02x %02x", 43 + filename, 44 + ident[EI_MAG0], ident[EI_MAG1], ident[EI_MAG2], ident[EI_MAG3], 45 + ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3); 46 + TEST_ASSERT(ident[EI_CLASS] == ELFCLASS64, 47 + "Current implementation only able to handle ELFCLASS64,\n" 48 + " filename: %s\n" 49 + " ident[EI_CLASS]: %02x\n" 50 + " expected: %02x", 51 + filename, 52 + ident[EI_CLASS], ELFCLASS64); 53 + TEST_ASSERT(((BYTE_ORDER == LITTLE_ENDIAN) 54 + && (ident[EI_DATA] == ELFDATA2LSB)) 55 + || ((BYTE_ORDER == BIG_ENDIAN) 56 + && (ident[EI_DATA] == ELFDATA2MSB)), "Current " 57 + "implementation only able to handle\n" 58 + "cases where the host and ELF file endianness\n" 59 + "is the same:\n" 60 + " host BYTE_ORDER: %u\n" 61 + " host LITTLE_ENDIAN: %u\n" 62 + " host BIG_ENDIAN: %u\n" 63 + " ident[EI_DATA]: %u\n" 64 + " ELFDATA2LSB: %u\n" 65 + " ELFDATA2MSB: %u", 66 + BYTE_ORDER, LITTLE_ENDIAN, BIG_ENDIAN, 67 + ident[EI_DATA], ELFDATA2LSB, ELFDATA2MSB); 68 + TEST_ASSERT(ident[EI_VERSION] == EV_CURRENT, 69 + "Current implementation only able to handle current " 70 + "ELF version,\n" 71 + " filename: %s\n" 72 + " ident[EI_VERSION]: %02x\n" 73 + " expected: %02x", 74 + filename, ident[EI_VERSION], EV_CURRENT); 75 + 76 + /* Read in the ELF header. 77 + * With the ELF Identification portion of the ELF header 78 + * validated, especially that the value at EI_VERSION is 79 + * as expected, it is now safe to read the entire ELF header. 80 + */ 81 + offset_rv = lseek(fd, 0, SEEK_SET); 82 + TEST_ASSERT(offset_rv == 0, "Seek to ELF header failed,\n" 83 + " rv: %zi expected: %i", offset_rv, 0); 84 + test_read(fd, hdrp, sizeof(*hdrp)); 85 + TEST_ASSERT(hdrp->e_phentsize == sizeof(Elf64_Phdr), 86 + "Unexpected physical header size,\n" 87 + " hdrp->e_phentsize: %x\n" 88 + " expected: %zx", 89 + hdrp->e_phentsize, sizeof(Elf64_Phdr)); 90 + TEST_ASSERT(hdrp->e_shentsize == sizeof(Elf64_Shdr), 91 + "Unexpected section header size,\n" 92 + " hdrp->e_shentsize: %x\n" 93 + " expected: %zx", 94 + hdrp->e_shentsize, sizeof(Elf64_Shdr)); 95 + } 96 + 97 + /* VM ELF Load 98 + * 99 + * Input Args: 100 + * filename - Path to ELF file 101 + * 102 + * Output Args: None 103 + * 104 + * Input/Output Args: 105 + * vm - Pointer to opaque type that describes the VM. 106 + * 107 + * Return: None, TEST_ASSERT failures for all error conditions 108 + * 109 + * Loads the program image of the ELF file specified by filename, 110 + * into the virtual address space of the VM pointed to by vm. On entry 111 + * the VM needs to not be using any of the virtual address space used 112 + * by the image and it needs to have sufficient available physical pages, to 113 + * back the virtual pages used to load the image. 114 + */ 115 + void kvm_vm_elf_load(struct kvm_vm *vm, const char *filename, 116 + uint32_t data_memslot, uint32_t pgd_memslot) 117 + { 118 + off_t offset, offset_rv; 119 + Elf64_Ehdr hdr; 120 + 121 + /* Open the ELF file. */ 122 + int fd; 123 + fd = open(filename, O_RDONLY); 124 + TEST_ASSERT(fd >= 0, "Failed to open ELF file,\n" 125 + " filename: %s\n" 126 + " rv: %i errno: %i", filename, fd, errno); 127 + 128 + /* Read in the ELF header. */ 129 + elfhdr_get(filename, &hdr); 130 + 131 + /* For each program header. 132 + * The following ELF header members specify the location 133 + * and size of the program headers: 134 + * 135 + * e_phoff - File offset to start of program headers 136 + * e_phentsize - Size of each program header 137 + * e_phnum - Number of program header entries 138 + */ 139 + for (unsigned int n1 = 0; n1 < hdr.e_phnum; n1++) { 140 + /* Seek to the beginning of the program header. */ 141 + offset = hdr.e_phoff + (n1 * hdr.e_phentsize); 142 + offset_rv = lseek(fd, offset, SEEK_SET); 143 + TEST_ASSERT(offset_rv == offset, 144 + "Failed to seek to begining of program header %u,\n" 145 + " filename: %s\n" 146 + " rv: %jd errno: %i", 147 + n1, filename, (intmax_t) offset_rv, errno); 148 + 149 + /* Read in the program header. */ 150 + Elf64_Phdr phdr; 151 + test_read(fd, &phdr, sizeof(phdr)); 152 + 153 + /* Skip if this header doesn't describe a loadable segment. */ 154 + if (phdr.p_type != PT_LOAD) 155 + continue; 156 + 157 + /* Allocate memory for this segment within the VM. */ 158 + TEST_ASSERT(phdr.p_memsz > 0, "Unexpected loadable segment " 159 + "memsize of 0,\n" 160 + " phdr index: %u p_memsz: 0x%" PRIx64, 161 + n1, (uint64_t) phdr.p_memsz); 162 + vm_vaddr_t seg_vstart = phdr.p_vaddr; 163 + seg_vstart &= ~(vm_vaddr_t)(vm->page_size - 1); 164 + vm_vaddr_t seg_vend = phdr.p_vaddr + phdr.p_memsz - 1; 165 + seg_vend |= vm->page_size - 1; 166 + size_t seg_size = seg_vend - seg_vstart + 1; 167 + 168 + vm_vaddr_t vaddr = vm_vaddr_alloc(vm, seg_size, seg_vstart, 169 + data_memslot, pgd_memslot); 170 + TEST_ASSERT(vaddr == seg_vstart, "Unable to allocate " 171 + "virtual memory for segment at requested min addr,\n" 172 + " segment idx: %u\n" 173 + " seg_vstart: 0x%lx\n" 174 + " vaddr: 0x%lx", 175 + n1, seg_vstart, vaddr); 176 + memset(addr_gva2hva(vm, vaddr), 0, seg_size); 177 + /* TODO(lhuemill): Set permissions of each memory segment 178 + * based on the least-significant 3 bits of phdr.p_flags. 179 + */ 180 + 181 + /* Load portion of initial state that is contained within 182 + * the ELF file. 183 + */ 184 + if (phdr.p_filesz) { 185 + offset_rv = lseek(fd, phdr.p_offset, SEEK_SET); 186 + TEST_ASSERT(offset_rv == phdr.p_offset, 187 + "Seek to program segment offset failed,\n" 188 + " program header idx: %u errno: %i\n" 189 + " offset_rv: 0x%jx\n" 190 + " expected: 0x%jx\n", 191 + n1, errno, (intmax_t) offset_rv, 192 + (intmax_t) phdr.p_offset); 193 + test_read(fd, addr_gva2hva(vm, phdr.p_vaddr), 194 + phdr.p_filesz); 195 + } 196 + } 197 + }
+158
tools/testing/selftests/kvm/lib/io.c
··· 1 + /* 2 + * tools/testing/selftests/kvm/lib/io.c 3 + * 4 + * Copyright (C) 2018, Google LLC. 5 + * 6 + * This work is licensed under the terms of the GNU GPL, version 2. 7 + */ 8 + 9 + #include "test_util.h" 10 + 11 + /* Test Write 12 + * 13 + * A wrapper for write(2), that automatically handles the following 14 + * special conditions: 15 + * 16 + * + Interrupted system call (EINTR) 17 + * + Write of less than requested amount 18 + * + Non-block return (EAGAIN) 19 + * 20 + * For each of the above, an additional write is performed to automatically 21 + * continue writing the requested data. 22 + * There are also many cases where write(2) can return an unexpected 23 + * error (e.g. EIO). Such errors cause a TEST_ASSERT failure. 24 + * 25 + * Note, for function signature compatibility with write(2), this function 26 + * returns the number of bytes written, but that value will always be equal 27 + * to the number of requested bytes. All other conditions in this and 28 + * future enhancements to this function either automatically issue another 29 + * write(2) or cause a TEST_ASSERT failure. 30 + * 31 + * Args: 32 + * fd - Opened file descriptor to file to be written. 33 + * count - Number of bytes to write. 34 + * 35 + * Output: 36 + * buf - Starting address of data to be written. 37 + * 38 + * Return: 39 + * On success, number of bytes written. 40 + * On failure, a TEST_ASSERT failure is caused. 41 + */ 42 + ssize_t test_write(int fd, const void *buf, size_t count) 43 + { 44 + ssize_t rc; 45 + ssize_t num_written = 0; 46 + size_t num_left = count; 47 + const char *ptr = buf; 48 + 49 + /* Note: Count of zero is allowed (see "RETURN VALUE" portion of 50 + * write(2) manpage for details. 51 + */ 52 + TEST_ASSERT(count >= 0, "Unexpected count, count: %li", count); 53 + 54 + do { 55 + rc = write(fd, ptr, num_left); 56 + 57 + switch (rc) { 58 + case -1: 59 + TEST_ASSERT(errno == EAGAIN || errno == EINTR, 60 + "Unexpected write failure,\n" 61 + " rc: %zi errno: %i", rc, errno); 62 + continue; 63 + 64 + case 0: 65 + TEST_ASSERT(false, "Unexpected EOF,\n" 66 + " rc: %zi num_written: %zi num_left: %zu", 67 + rc, num_written, num_left); 68 + break; 69 + 70 + default: 71 + TEST_ASSERT(rc >= 0, "Unexpected ret from write,\n" 72 + " rc: %zi errno: %i", rc, errno); 73 + num_written += rc; 74 + num_left -= rc; 75 + ptr += rc; 76 + break; 77 + } 78 + } while (num_written < count); 79 + 80 + return num_written; 81 + } 82 + 83 + /* Test Read 84 + * 85 + * A wrapper for read(2), that automatically handles the following 86 + * special conditions: 87 + * 88 + * + Interrupted system call (EINTR) 89 + * + Read of less than requested amount 90 + * + Non-block return (EAGAIN) 91 + * 92 + * For each of the above, an additional read is performed to automatically 93 + * continue reading the requested data. 94 + * There are also many cases where read(2) can return an unexpected 95 + * error (e.g. EIO). Such errors cause a TEST_ASSERT failure. Note, 96 + * it is expected that the file opened by fd at the current file position 97 + * contains at least the number of requested bytes to be read. A TEST_ASSERT 98 + * failure is produced if an End-Of-File condition occurs, before all the 99 + * data is read. It is the callers responsibility to assure that sufficient 100 + * data exists. 101 + * 102 + * Note, for function signature compatibility with read(2), this function 103 + * returns the number of bytes read, but that value will always be equal 104 + * to the number of requested bytes. All other conditions in this and 105 + * future enhancements to this function either automatically issue another 106 + * read(2) or cause a TEST_ASSERT failure. 107 + * 108 + * Args: 109 + * fd - Opened file descriptor to file to be read. 110 + * count - Number of bytes to read. 111 + * 112 + * Output: 113 + * buf - Starting address of where to write the bytes read. 114 + * 115 + * Return: 116 + * On success, number of bytes read. 117 + * On failure, a TEST_ASSERT failure is caused. 118 + */ 119 + ssize_t test_read(int fd, void *buf, size_t count) 120 + { 121 + ssize_t rc; 122 + ssize_t num_read = 0; 123 + size_t num_left = count; 124 + char *ptr = buf; 125 + 126 + /* Note: Count of zero is allowed (see "If count is zero" portion of 127 + * read(2) manpage for details. 128 + */ 129 + TEST_ASSERT(count >= 0, "Unexpected count, count: %li", count); 130 + 131 + do { 132 + rc = read(fd, ptr, num_left); 133 + 134 + switch (rc) { 135 + case -1: 136 + TEST_ASSERT(errno == EAGAIN || errno == EINTR, 137 + "Unexpected read failure,\n" 138 + " rc: %zi errno: %i", rc, errno); 139 + break; 140 + 141 + case 0: 142 + TEST_ASSERT(false, "Unexpected EOF,\n" 143 + " rc: %zi num_read: %zi num_left: %zu", 144 + rc, num_read, num_left); 145 + break; 146 + 147 + default: 148 + TEST_ASSERT(rc > 0, "Unexpected ret from read,\n" 149 + " rc: %zi errno: %i", rc, errno); 150 + num_read += rc; 151 + num_left -= rc; 152 + ptr += rc; 153 + break; 154 + } 155 + } while (num_read < count); 156 + 157 + return num_read; 158 + }
+3
tools/testing/selftests/kvm/lib/x86.c
··· 687 687 /* Create VM */ 688 688 vm = vm_create(VM_MODE_FLAT48PG, DEFAULT_GUEST_PHY_PAGES, O_RDWR); 689 689 690 + /* Setup guest code */ 691 + kvm_vm_elf_load(vm, program_invocation_name, 0, 0); 692 + 690 693 /* Setup IRQ Chip */ 691 694 vm_create_irqchip(vm); 692 695
+232
tools/testing/selftests/kvm/sync_regs_test.c
··· 1 + /* 2 + * Test for x86 KVM_CAP_SYNC_REGS 3 + * 4 + * Copyright (C) 2018, Google LLC. 5 + * 6 + * This work is licensed under the terms of the GNU GPL, version 2. 7 + * 8 + * Verifies expected behavior of x86 KVM_CAP_SYNC_REGS functionality, 9 + * including requesting an invalid register set, updates to/from values 10 + * in kvm_run.s.regs when kvm_valid_regs and kvm_dirty_regs are toggled. 11 + */ 12 + 13 + #define _GNU_SOURCE /* for program_invocation_short_name */ 14 + #include <fcntl.h> 15 + #include <stdio.h> 16 + #include <stdlib.h> 17 + #include <string.h> 18 + #include <sys/ioctl.h> 19 + 20 + #include "test_util.h" 21 + #include "kvm_util.h" 22 + #include "x86.h" 23 + 24 + #define VCPU_ID 5 25 + #define PORT_HOST_SYNC 0x1000 26 + 27 + static void __exit_to_l0(uint16_t port, uint64_t arg0, uint64_t arg1) 28 + { 29 + __asm__ __volatile__("in %[port], %%al" 30 + : 31 + : [port]"d"(port), "D"(arg0), "S"(arg1) 32 + : "rax"); 33 + } 34 + 35 + #define exit_to_l0(_port, _arg0, _arg1) \ 36 + __exit_to_l0(_port, (uint64_t) (_arg0), (uint64_t) (_arg1)) 37 + 38 + #define GUEST_ASSERT(_condition) do { \ 39 + if (!(_condition)) \ 40 + exit_to_l0(PORT_ABORT, "Failed guest assert: " #_condition, 0);\ 41 + } while (0) 42 + 43 + void guest_code(void) 44 + { 45 + for (;;) { 46 + exit_to_l0(PORT_HOST_SYNC, "hello", 0); 47 + asm volatile ("inc %r11"); 48 + } 49 + } 50 + 51 + static void compare_regs(struct kvm_regs *left, struct kvm_regs *right) 52 + { 53 + #define REG_COMPARE(reg) \ 54 + TEST_ASSERT(left->reg == right->reg, \ 55 + "Register " #reg \ 56 + " values did not match: 0x%llx, 0x%llx\n", \ 57 + left->reg, right->reg) 58 + REG_COMPARE(rax); 59 + REG_COMPARE(rbx); 60 + REG_COMPARE(rcx); 61 + REG_COMPARE(rdx); 62 + REG_COMPARE(rsi); 63 + REG_COMPARE(rdi); 64 + REG_COMPARE(rsp); 65 + REG_COMPARE(rbp); 66 + REG_COMPARE(r8); 67 + REG_COMPARE(r9); 68 + REG_COMPARE(r10); 69 + REG_COMPARE(r11); 70 + REG_COMPARE(r12); 71 + REG_COMPARE(r13); 72 + REG_COMPARE(r14); 73 + REG_COMPARE(r15); 74 + REG_COMPARE(rip); 75 + REG_COMPARE(rflags); 76 + #undef REG_COMPARE 77 + } 78 + 79 + static void compare_sregs(struct kvm_sregs *left, struct kvm_sregs *right) 80 + { 81 + } 82 + 83 + static void compare_vcpu_events(struct kvm_vcpu_events *left, 84 + struct kvm_vcpu_events *right) 85 + { 86 + } 87 + 88 + int main(int argc, char *argv[]) 89 + { 90 + struct kvm_vm *vm; 91 + struct kvm_run *run; 92 + struct kvm_regs regs; 93 + struct kvm_sregs sregs; 94 + struct kvm_vcpu_events events; 95 + int rv, cap; 96 + 97 + /* Tell stdout not to buffer its content */ 98 + setbuf(stdout, NULL); 99 + 100 + cap = kvm_check_cap(KVM_CAP_SYNC_REGS); 101 + TEST_ASSERT((unsigned long)cap == KVM_SYNC_X86_VALID_FIELDS, 102 + "KVM_CAP_SYNC_REGS (0x%x) != KVM_SYNC_X86_VALID_FIELDS (0x%lx)\n", 103 + cap, KVM_SYNC_X86_VALID_FIELDS); 104 + 105 + /* Create VM */ 106 + vm = vm_create_default(VCPU_ID, guest_code); 107 + 108 + run = vcpu_state(vm, VCPU_ID); 109 + 110 + /* Request reading invalid register set from VCPU. */ 111 + run->kvm_valid_regs = KVM_SYNC_X86_VALID_FIELDS << 1; 112 + rv = _vcpu_run(vm, VCPU_ID); 113 + TEST_ASSERT(rv < 0 && errno == EINVAL, 114 + "Invalid kvm_valid_regs did not cause expected KVM_RUN error: %d\n", 115 + rv); 116 + vcpu_state(vm, VCPU_ID)->kvm_valid_regs = 0; 117 + 118 + /* Request setting invalid register set into VCPU. */ 119 + run->kvm_dirty_regs = KVM_SYNC_X86_VALID_FIELDS << 1; 120 + rv = _vcpu_run(vm, VCPU_ID); 121 + TEST_ASSERT(rv < 0 && errno == EINVAL, 122 + "Invalid kvm_dirty_regs did not cause expected KVM_RUN error: %d\n", 123 + rv); 124 + vcpu_state(vm, VCPU_ID)->kvm_dirty_regs = 0; 125 + 126 + /* Request and verify all valid register sets. */ 127 + /* TODO: BUILD TIME CHECK: TEST_ASSERT(KVM_SYNC_X86_NUM_FIELDS != 3); */ 128 + run->kvm_valid_regs = KVM_SYNC_X86_VALID_FIELDS; 129 + rv = _vcpu_run(vm, VCPU_ID); 130 + TEST_ASSERT(run->exit_reason == KVM_EXIT_IO, 131 + "Unexpected exit reason: %u (%s),\n", 132 + run->exit_reason, 133 + exit_reason_str(run->exit_reason)); 134 + 135 + vcpu_regs_get(vm, VCPU_ID, &regs); 136 + compare_regs(&regs, &run->s.regs.regs); 137 + 138 + vcpu_sregs_get(vm, VCPU_ID, &sregs); 139 + compare_sregs(&sregs, &run->s.regs.sregs); 140 + 141 + vcpu_events_get(vm, VCPU_ID, &events); 142 + compare_vcpu_events(&events, &run->s.regs.events); 143 + 144 + /* Set and verify various register values. */ 145 + run->s.regs.regs.r11 = 0xBAD1DEA; 146 + run->s.regs.sregs.apic_base = 1 << 11; 147 + /* TODO run->s.regs.events.XYZ = ABC; */ 148 + 149 + run->kvm_valid_regs = KVM_SYNC_X86_VALID_FIELDS; 150 + run->kvm_dirty_regs = KVM_SYNC_X86_REGS | KVM_SYNC_X86_SREGS; 151 + rv = _vcpu_run(vm, VCPU_ID); 152 + TEST_ASSERT(run->exit_reason == KVM_EXIT_IO, 153 + "Unexpected exit reason: %u (%s),\n", 154 + run->exit_reason, 155 + exit_reason_str(run->exit_reason)); 156 + TEST_ASSERT(run->s.regs.regs.r11 == 0xBAD1DEA + 1, 157 + "r11 sync regs value incorrect 0x%llx.", 158 + run->s.regs.regs.r11); 159 + TEST_ASSERT(run->s.regs.sregs.apic_base == 1 << 11, 160 + "apic_base sync regs value incorrect 0x%llx.", 161 + run->s.regs.sregs.apic_base); 162 + 163 + vcpu_regs_get(vm, VCPU_ID, &regs); 164 + compare_regs(&regs, &run->s.regs.regs); 165 + 166 + vcpu_sregs_get(vm, VCPU_ID, &sregs); 167 + compare_sregs(&sregs, &run->s.regs.sregs); 168 + 169 + vcpu_events_get(vm, VCPU_ID, &events); 170 + compare_vcpu_events(&events, &run->s.regs.events); 171 + 172 + /* Clear kvm_dirty_regs bits, verify new s.regs values are 173 + * overwritten with existing guest values. 174 + */ 175 + run->kvm_valid_regs = KVM_SYNC_X86_VALID_FIELDS; 176 + run->kvm_dirty_regs = 0; 177 + run->s.regs.regs.r11 = 0xDEADBEEF; 178 + rv = _vcpu_run(vm, VCPU_ID); 179 + TEST_ASSERT(run->exit_reason == KVM_EXIT_IO, 180 + "Unexpected exit reason: %u (%s),\n", 181 + run->exit_reason, 182 + exit_reason_str(run->exit_reason)); 183 + TEST_ASSERT(run->s.regs.regs.r11 != 0xDEADBEEF, 184 + "r11 sync regs value incorrect 0x%llx.", 185 + run->s.regs.regs.r11); 186 + 187 + /* Clear kvm_valid_regs bits and kvm_dirty_bits. 188 + * Verify s.regs values are not overwritten with existing guest values 189 + * and that guest values are not overwritten with kvm_sync_regs values. 190 + */ 191 + run->kvm_valid_regs = 0; 192 + run->kvm_dirty_regs = 0; 193 + run->s.regs.regs.r11 = 0xAAAA; 194 + regs.r11 = 0xBAC0; 195 + vcpu_regs_set(vm, VCPU_ID, &regs); 196 + rv = _vcpu_run(vm, VCPU_ID); 197 + TEST_ASSERT(run->exit_reason == KVM_EXIT_IO, 198 + "Unexpected exit reason: %u (%s),\n", 199 + run->exit_reason, 200 + exit_reason_str(run->exit_reason)); 201 + TEST_ASSERT(run->s.regs.regs.r11 == 0xAAAA, 202 + "r11 sync regs value incorrect 0x%llx.", 203 + run->s.regs.regs.r11); 204 + vcpu_regs_get(vm, VCPU_ID, &regs); 205 + TEST_ASSERT(regs.r11 == 0xBAC0 + 1, 206 + "r11 guest value incorrect 0x%llx.", 207 + regs.r11); 208 + 209 + /* Clear kvm_valid_regs bits. Verify s.regs values are not overwritten 210 + * with existing guest values but that guest values are overwritten 211 + * with kvm_sync_regs values. 212 + */ 213 + run->kvm_valid_regs = 0; 214 + run->kvm_dirty_regs = KVM_SYNC_X86_VALID_FIELDS; 215 + run->s.regs.regs.r11 = 0xBBBB; 216 + rv = _vcpu_run(vm, VCPU_ID); 217 + TEST_ASSERT(run->exit_reason == KVM_EXIT_IO, 218 + "Unexpected exit reason: %u (%s),\n", 219 + run->exit_reason, 220 + exit_reason_str(run->exit_reason)); 221 + TEST_ASSERT(run->s.regs.regs.r11 == 0xBBBB, 222 + "r11 sync regs value incorrect 0x%llx.", 223 + run->s.regs.regs.r11); 224 + vcpu_regs_get(vm, VCPU_ID, &regs); 225 + TEST_ASSERT(regs.r11 == 0xBBBB + 1, 226 + "r11 guest value incorrect 0x%llx.", 227 + regs.r11); 228 + 229 + kvm_vm_free(vm); 230 + 231 + return 0; 232 + }