17d9a662eSMichael Roth /* SPDX-License-Identifier: GPL-2.0-only */ 27d9a662eSMichael Roth /* 37d9a662eSMichael Roth * tools/testing/selftests/kvm/include/kvm_util_base.h 47d9a662eSMichael Roth * 57d9a662eSMichael Roth * Copyright (C) 2018, Google LLC. 67d9a662eSMichael Roth */ 77d9a662eSMichael Roth #ifndef SELFTEST_KVM_UTIL_BASE_H 87d9a662eSMichael Roth #define SELFTEST_KVM_UTIL_BASE_H 97d9a662eSMichael Roth 107d9a662eSMichael Roth #include "test_util.h" 117d9a662eSMichael Roth 12b530eba1SSean Christopherson #include <linux/compiler.h> 13b530eba1SSean Christopherson #include "linux/hashtable.h" 147d9a662eSMichael Roth #include "linux/list.h" 15b530eba1SSean Christopherson #include <linux/kernel.h> 16b530eba1SSean Christopherson #include <linux/kvm.h> 17b530eba1SSean Christopherson #include "linux/rbtree.h" 18b530eba1SSean Christopherson 1903b47505SSean Christopherson #include <asm/atomic.h> 200cc64b08SSean Christopherson 217d9a662eSMichael Roth #include <sys/ioctl.h> 227d9a662eSMichael Roth 237d9a662eSMichael Roth #include "sparsebit.h" 247d9a662eSMichael Roth 257d9a662eSMichael Roth #define KVM_DEV_PATH "/dev/kvm" 267d9a662eSMichael Roth #define KVM_MAX_VCPUS 512 277d9a662eSMichael Roth 287d9a662eSMichael Roth #define NSEC_PER_SEC 1000000000L 297d9a662eSMichael Roth 307d9a662eSMichael Roth typedef uint64_t vm_paddr_t; /* Virtual Machine (Guest) physical address */ 317d9a662eSMichael Roth typedef uint64_t vm_vaddr_t; /* Virtual Machine (Guest) virtual address */ 327d9a662eSMichael Roth 33b530eba1SSean Christopherson struct userspace_mem_region { 34b530eba1SSean Christopherson struct kvm_userspace_memory_region region; 35b530eba1SSean Christopherson struct sparsebit *unused_phy_pages; 36b530eba1SSean Christopherson int fd; 37b530eba1SSean Christopherson off_t offset; 38bd3ed7e1SRicardo Koller enum vm_mem_backing_src_type backing_src_type; 39b530eba1SSean Christopherson void *host_mem; 40b530eba1SSean Christopherson void *host_alias; 41b530eba1SSean Christopherson void *mmap_start; 42b530eba1SSean Christopherson void *mmap_alias; 43b530eba1SSean Christopherson size_t mmap_size; 44b530eba1SSean Christopherson struct rb_node gpa_node; 45b530eba1SSean Christopherson struct rb_node hva_node; 46b530eba1SSean Christopherson struct hlist_node slot_node; 47b530eba1SSean Christopherson }; 48b530eba1SSean Christopherson 490cc64b08SSean Christopherson struct kvm_vcpu { 50b530eba1SSean Christopherson struct list_head list; 51b530eba1SSean Christopherson uint32_t id; 52b530eba1SSean Christopherson int fd; 53c472df1aSSean Christopherson struct kvm_vm *vm; 541079c3d4SSean Christopherson struct kvm_run *run; 557fbc6038SSean Christopherson #ifdef __x86_64__ 567fbc6038SSean Christopherson struct kvm_cpuid2 *cpuid; 577fbc6038SSean Christopherson #endif 58b530eba1SSean Christopherson struct kvm_dirty_gfn *dirty_gfns; 59b530eba1SSean Christopherson uint32_t fetch_index; 60b530eba1SSean Christopherson uint32_t dirty_gfns_count; 61b530eba1SSean Christopherson }; 62b530eba1SSean Christopherson 63b530eba1SSean Christopherson struct userspace_mem_regions { 64b530eba1SSean Christopherson struct rb_root gpa_tree; 65b530eba1SSean Christopherson struct rb_root hva_tree; 66b530eba1SSean Christopherson DECLARE_HASHTABLE(slot_hash, 9); 67b530eba1SSean Christopherson }; 68b530eba1SSean Christopherson 69290c5b54SRicardo Koller enum kvm_mem_region_type { 70290c5b54SRicardo Koller MEM_REGION_CODE, 71290c5b54SRicardo Koller MEM_REGION_DATA, 72290c5b54SRicardo Koller MEM_REGION_PT, 73290c5b54SRicardo Koller MEM_REGION_TEST_DATA, 74290c5b54SRicardo Koller NR_MEM_REGIONS, 75290c5b54SRicardo Koller }; 76290c5b54SRicardo Koller 77b530eba1SSean Christopherson struct kvm_vm { 78b530eba1SSean Christopherson int mode; 79b530eba1SSean Christopherson unsigned long type; 80b530eba1SSean Christopherson int kvm_fd; 81b530eba1SSean Christopherson int fd; 82b530eba1SSean Christopherson unsigned int pgtable_levels; 83b530eba1SSean Christopherson unsigned int page_size; 84b530eba1SSean Christopherson unsigned int page_shift; 85b530eba1SSean Christopherson unsigned int pa_bits; 86b530eba1SSean Christopherson unsigned int va_bits; 87b530eba1SSean Christopherson uint64_t max_gfn; 88b530eba1SSean Christopherson struct list_head vcpus; 89b530eba1SSean Christopherson struct userspace_mem_regions regions; 90b530eba1SSean Christopherson struct sparsebit *vpages_valid; 91b530eba1SSean Christopherson struct sparsebit *vpages_mapped; 92b530eba1SSean Christopherson bool has_irqchip; 93b530eba1SSean Christopherson bool pgd_created; 9403b47505SSean Christopherson vm_paddr_t ucall_mmio_addr; 95b530eba1SSean Christopherson vm_paddr_t pgd; 96b530eba1SSean Christopherson vm_vaddr_t gdt; 97b530eba1SSean Christopherson vm_vaddr_t tss; 98b530eba1SSean Christopherson vm_vaddr_t idt; 99b530eba1SSean Christopherson vm_vaddr_t handlers; 100b530eba1SSean Christopherson uint32_t dirty_ring_size; 10183f6e109SBen Gardon 10283f6e109SBen Gardon /* Cache of information for binary stats interface */ 10383f6e109SBen Gardon int stats_fd; 10483f6e109SBen Gardon struct kvm_stats_header stats_header; 10583f6e109SBen Gardon struct kvm_stats_desc *stats_desc; 106290c5b54SRicardo Koller 107290c5b54SRicardo Koller /* 108290c5b54SRicardo Koller * KVM region slots. These are the default memslots used by page 109290c5b54SRicardo Koller * allocators, e.g., lib/elf uses the memslots[MEM_REGION_CODE] 110290c5b54SRicardo Koller * memslot. 111290c5b54SRicardo Koller */ 112290c5b54SRicardo Koller uint32_t memslots[NR_MEM_REGIONS]; 113b530eba1SSean Christopherson }; 114b530eba1SSean Christopherson 115b530eba1SSean Christopherson 116b530eba1SSean Christopherson #define kvm_for_each_vcpu(vm, i, vcpu) \ 117b530eba1SSean Christopherson for ((i) = 0; (i) <= (vm)->last_vcpu_id; (i)++) \ 118b530eba1SSean Christopherson if (!((vcpu) = vm->vcpus[i])) \ 119b530eba1SSean Christopherson continue; \ 120b530eba1SSean Christopherson else 121b530eba1SSean Christopherson 122b530eba1SSean Christopherson struct userspace_mem_region * 123b530eba1SSean Christopherson memslot2region(struct kvm_vm *vm, uint32_t memslot); 124b530eba1SSean Christopherson 125290c5b54SRicardo Koller static inline struct userspace_mem_region *vm_get_mem_region(struct kvm_vm *vm, 126290c5b54SRicardo Koller enum kvm_mem_region_type type) 127290c5b54SRicardo Koller { 128290c5b54SRicardo Koller assert(type < NR_MEM_REGIONS); 129290c5b54SRicardo Koller return memslot2region(vm, vm->memslots[type]); 130290c5b54SRicardo Koller } 131290c5b54SRicardo Koller 1327d9a662eSMichael Roth /* Minimum allocated guest virtual and physical addresses */ 1337d9a662eSMichael Roth #define KVM_UTIL_MIN_VADDR 0x2000 1347d9a662eSMichael Roth #define KVM_GUEST_PAGE_TABLE_MIN_PADDR 0x180000 1357d9a662eSMichael Roth 1367d9a662eSMichael Roth #define DEFAULT_GUEST_STACK_VADDR_MIN 0xab6000 1377d9a662eSMichael Roth #define DEFAULT_STACK_PGS 5 1387d9a662eSMichael Roth 1397d9a662eSMichael Roth enum vm_guest_mode { 1407d9a662eSMichael Roth VM_MODE_P52V48_4K, 1417d9a662eSMichael Roth VM_MODE_P52V48_64K, 1427d9a662eSMichael Roth VM_MODE_P48V48_4K, 1437d9a662eSMichael Roth VM_MODE_P48V48_16K, 1447d9a662eSMichael Roth VM_MODE_P48V48_64K, 1457d9a662eSMichael Roth VM_MODE_P40V48_4K, 1467d9a662eSMichael Roth VM_MODE_P40V48_16K, 1477d9a662eSMichael Roth VM_MODE_P40V48_64K, 1487d9a662eSMichael Roth VM_MODE_PXXV48_4K, /* For 48bits VA but ANY bits PA */ 1497d9a662eSMichael Roth VM_MODE_P47V64_4K, 1507d9a662eSMichael Roth VM_MODE_P44V64_4K, 1517d9a662eSMichael Roth VM_MODE_P36V48_4K, 1527d9a662eSMichael Roth VM_MODE_P36V48_16K, 1537d9a662eSMichael Roth VM_MODE_P36V48_64K, 1547d9a662eSMichael Roth VM_MODE_P36V47_16K, 1557d9a662eSMichael Roth NUM_VM_MODES, 1567d9a662eSMichael Roth }; 1577d9a662eSMichael Roth 1587d9a662eSMichael Roth #if defined(__aarch64__) 1597d9a662eSMichael Roth 1607d9a662eSMichael Roth extern enum vm_guest_mode vm_mode_default; 1617d9a662eSMichael Roth 1627d9a662eSMichael Roth #define VM_MODE_DEFAULT vm_mode_default 1637d9a662eSMichael Roth #define MIN_PAGE_SHIFT 12U 1647d9a662eSMichael Roth #define ptes_per_page(page_size) ((page_size) / 8) 1657d9a662eSMichael Roth 1667d9a662eSMichael Roth #elif defined(__x86_64__) 1677d9a662eSMichael Roth 1687d9a662eSMichael Roth #define VM_MODE_DEFAULT VM_MODE_PXXV48_4K 1697d9a662eSMichael Roth #define MIN_PAGE_SHIFT 12U 1707d9a662eSMichael Roth #define ptes_per_page(page_size) ((page_size) / 8) 1717d9a662eSMichael Roth 1727d9a662eSMichael Roth #elif defined(__s390x__) 1737d9a662eSMichael Roth 1747d9a662eSMichael Roth #define VM_MODE_DEFAULT VM_MODE_P44V64_4K 1757d9a662eSMichael Roth #define MIN_PAGE_SHIFT 12U 1767d9a662eSMichael Roth #define ptes_per_page(page_size) ((page_size) / 16) 1777d9a662eSMichael Roth 1787d9a662eSMichael Roth #elif defined(__riscv) 1797d9a662eSMichael Roth 1807d9a662eSMichael Roth #if __riscv_xlen == 32 1817d9a662eSMichael Roth #error "RISC-V 32-bit kvm selftests not supported" 1827d9a662eSMichael Roth #endif 1837d9a662eSMichael Roth 1847d9a662eSMichael Roth #define VM_MODE_DEFAULT VM_MODE_P40V48_4K 1857d9a662eSMichael Roth #define MIN_PAGE_SHIFT 12U 1867d9a662eSMichael Roth #define ptes_per_page(page_size) ((page_size) / 8) 1877d9a662eSMichael Roth 1887d9a662eSMichael Roth #endif 1897d9a662eSMichael Roth 1907d9a662eSMichael Roth #define MIN_PAGE_SIZE (1U << MIN_PAGE_SHIFT) 1917d9a662eSMichael Roth #define PTES_PER_MIN_PAGE ptes_per_page(MIN_PAGE_SIZE) 1927d9a662eSMichael Roth 1937d9a662eSMichael Roth struct vm_guest_mode_params { 1947d9a662eSMichael Roth unsigned int pa_bits; 1957d9a662eSMichael Roth unsigned int va_bits; 1967d9a662eSMichael Roth unsigned int page_size; 1977d9a662eSMichael Roth unsigned int page_shift; 1987d9a662eSMichael Roth }; 1997d9a662eSMichael Roth extern const struct vm_guest_mode_params vm_guest_mode_params[]; 2007d9a662eSMichael Roth 2017d9a662eSMichael Roth int open_path_or_exit(const char *path, int flags); 2027d9a662eSMichael Roth int open_kvm_dev_path_or_exit(void); 2034d2bd143SDavid Matlack 2044d2bd143SDavid Matlack bool get_kvm_intel_param_bool(const char *param); 2054d2bd143SDavid Matlack bool get_kvm_amd_param_bool(const char *param); 2064d2bd143SDavid Matlack 207d8ba3f14SSean Christopherson unsigned int kvm_check_cap(long cap); 20871ab5a6fSSean Christopherson 2093ea9b809SSean Christopherson static inline bool kvm_has_cap(long cap) 2103ea9b809SSean Christopherson { 2113ea9b809SSean Christopherson return kvm_check_cap(cap); 2123ea9b809SSean Christopherson } 2133ea9b809SSean Christopherson 21471ab5a6fSSean Christopherson #define __KVM_SYSCALL_ERROR(_name, _ret) \ 21571ab5a6fSSean Christopherson "%s failed, rc: %i errno: %i (%s)", (_name), (_ret), errno, strerror(errno) 21671ab5a6fSSean Christopherson 21771ab5a6fSSean Christopherson #define __KVM_IOCTL_ERROR(_name, _ret) __KVM_SYSCALL_ERROR(_name, _ret) 21871ab5a6fSSean Christopherson #define KVM_IOCTL_ERROR(_ioctl, _ret) __KVM_IOCTL_ERROR(#_ioctl, _ret) 21971ab5a6fSSean Christopherson 220fcba483eSSean Christopherson #define kvm_do_ioctl(fd, cmd, arg) \ 221fcba483eSSean Christopherson ({ \ 222fcba483eSSean Christopherson static_assert(!_IOC_SIZE(cmd) || sizeof(*arg) == _IOC_SIZE(cmd), ""); \ 223fcba483eSSean Christopherson ioctl(fd, cmd, arg); \ 224fcba483eSSean Christopherson }) 225fcba483eSSean Christopherson 2262de1b7b1SSean Christopherson #define __kvm_ioctl(kvm_fd, cmd, arg) \ 227fcba483eSSean Christopherson kvm_do_ioctl(kvm_fd, cmd, arg) 2282de1b7b1SSean Christopherson 2292de1b7b1SSean Christopherson 230fcba483eSSean Christopherson #define _kvm_ioctl(kvm_fd, cmd, name, arg) \ 231fcba483eSSean Christopherson ({ \ 232fcba483eSSean Christopherson int ret = __kvm_ioctl(kvm_fd, cmd, arg); \ 233fcba483eSSean Christopherson \ 234fcba483eSSean Christopherson TEST_ASSERT(!ret, __KVM_IOCTL_ERROR(name, ret)); \ 235fcba483eSSean Christopherson }) 2362de1b7b1SSean Christopherson 2372de1b7b1SSean Christopherson #define kvm_ioctl(kvm_fd, cmd, arg) \ 2382de1b7b1SSean Christopherson _kvm_ioctl(kvm_fd, cmd, #cmd, arg) 23971ab5a6fSSean Christopherson 240ad125f30SSean Christopherson static __always_inline void static_assert_is_vm(struct kvm_vm *vm) { } 241ad125f30SSean Christopherson 242fcba483eSSean Christopherson #define __vm_ioctl(vm, cmd, arg) \ 243fcba483eSSean Christopherson ({ \ 244ad125f30SSean Christopherson static_assert_is_vm(vm); \ 245fcba483eSSean Christopherson kvm_do_ioctl((vm)->fd, cmd, arg); \ 246fcba483eSSean Christopherson }) 24771ab5a6fSSean Christopherson 248fcba483eSSean Christopherson #define _vm_ioctl(vm, cmd, name, arg) \ 249fcba483eSSean Christopherson ({ \ 250fcba483eSSean Christopherson int ret = __vm_ioctl(vm, cmd, arg); \ 251fcba483eSSean Christopherson \ 252fcba483eSSean Christopherson TEST_ASSERT(!ret, __KVM_IOCTL_ERROR(name, ret)); \ 253fcba483eSSean Christopherson }) 254fcba483eSSean Christopherson 255fcba483eSSean Christopherson #define vm_ioctl(vm, cmd, arg) \ 256fcba483eSSean Christopherson _vm_ioctl(vm, cmd, #cmd, arg) 257fcba483eSSean Christopherson 258ad125f30SSean Christopherson 259ad125f30SSean Christopherson static __always_inline void static_assert_is_vcpu(struct kvm_vcpu *vcpu) { } 260ad125f30SSean Christopherson 261fcba483eSSean Christopherson #define __vcpu_ioctl(vcpu, cmd, arg) \ 262fcba483eSSean Christopherson ({ \ 263ad125f30SSean Christopherson static_assert_is_vcpu(vcpu); \ 264fcba483eSSean Christopherson kvm_do_ioctl((vcpu)->fd, cmd, arg); \ 265fcba483eSSean Christopherson }) 266fcba483eSSean Christopherson 267fcba483eSSean Christopherson #define _vcpu_ioctl(vcpu, cmd, name, arg) \ 268fcba483eSSean Christopherson ({ \ 269fcba483eSSean Christopherson int ret = __vcpu_ioctl(vcpu, cmd, arg); \ 270fcba483eSSean Christopherson \ 271fcba483eSSean Christopherson TEST_ASSERT(!ret, __KVM_IOCTL_ERROR(name, ret)); \ 272fcba483eSSean Christopherson }) 273fcba483eSSean Christopherson 274768e9a61SSean Christopherson #define vcpu_ioctl(vcpu, cmd, arg) \ 275768e9a61SSean Christopherson _vcpu_ioctl(vcpu, cmd, #cmd, arg) 27671ab5a6fSSean Christopherson 27710825b55SSean Christopherson /* 27810825b55SSean Christopherson * Looks up and returns the value corresponding to the capability 27910825b55SSean Christopherson * (KVM_CAP_*) given by cap. 28010825b55SSean Christopherson */ 28110825b55SSean Christopherson static inline int vm_check_cap(struct kvm_vm *vm, long cap) 28210825b55SSean Christopherson { 28310825b55SSean Christopherson int ret = __vm_ioctl(vm, KVM_CHECK_EXTENSION, (void *)cap); 28410825b55SSean Christopherson 28510825b55SSean Christopherson TEST_ASSERT(ret >= 0, KVM_IOCTL_ERROR(KVM_CHECK_EXTENSION, ret)); 28610825b55SSean Christopherson return ret; 28710825b55SSean Christopherson } 28810825b55SSean Christopherson 289a12c86c4SSean Christopherson static inline int __vm_enable_cap(struct kvm_vm *vm, uint32_t cap, uint64_t arg0) 290ac712209SSean Christopherson { 291a12c86c4SSean Christopherson struct kvm_enable_cap enable_cap = { .cap = cap, .args = { arg0 } }; 292a12c86c4SSean Christopherson 293a12c86c4SSean Christopherson return __vm_ioctl(vm, KVM_ENABLE_CAP, &enable_cap); 294ac712209SSean Christopherson } 295a12c86c4SSean Christopherson static inline void vm_enable_cap(struct kvm_vm *vm, uint32_t cap, uint64_t arg0) 29610825b55SSean Christopherson { 297a12c86c4SSean Christopherson struct kvm_enable_cap enable_cap = { .cap = cap, .args = { arg0 } }; 298a12c86c4SSean Christopherson 299a12c86c4SSean Christopherson vm_ioctl(vm, KVM_ENABLE_CAP, &enable_cap); 30010825b55SSean Christopherson } 30110825b55SSean Christopherson 3027d9a662eSMichael Roth void vm_enable_dirty_ring(struct kvm_vm *vm, uint32_t ring_size); 3037d9a662eSMichael Roth const char *vm_guest_mode_string(uint32_t i); 3047d9a662eSMichael Roth 3057d9a662eSMichael Roth void kvm_vm_free(struct kvm_vm *vmp); 306ccc82ba6SSean Christopherson void kvm_vm_restart(struct kvm_vm *vmp); 3077d9a662eSMichael Roth void kvm_vm_release(struct kvm_vm *vmp); 3087d9a662eSMichael Roth int kvm_memcmp_hva_gva(void *hva, struct kvm_vm *vm, const vm_vaddr_t gva, 3097d9a662eSMichael Roth size_t len); 3107d9a662eSMichael Roth void kvm_vm_elf_load(struct kvm_vm *vm, const char *filename); 311a4187c9bSSean Christopherson int kvm_memfd_alloc(size_t size, bool hugepages); 3127d9a662eSMichael Roth 3137d9a662eSMichael Roth void vm_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent); 3147d9a662eSMichael Roth 31510825b55SSean Christopherson static inline void kvm_vm_get_dirty_log(struct kvm_vm *vm, int slot, void *log) 31610825b55SSean Christopherson { 31710825b55SSean Christopherson struct kvm_dirty_log args = { .dirty_bitmap = log, .slot = slot }; 31810825b55SSean Christopherson 31910825b55SSean Christopherson vm_ioctl(vm, KVM_GET_DIRTY_LOG, &args); 32010825b55SSean Christopherson } 32110825b55SSean Christopherson 32210825b55SSean Christopherson static inline void kvm_vm_clear_dirty_log(struct kvm_vm *vm, int slot, void *log, 32310825b55SSean Christopherson uint64_t first_page, uint32_t num_pages) 32410825b55SSean Christopherson { 32510825b55SSean Christopherson struct kvm_clear_dirty_log args = { 32610825b55SSean Christopherson .dirty_bitmap = log, 32710825b55SSean Christopherson .slot = slot, 32810825b55SSean Christopherson .first_page = first_page, 32910825b55SSean Christopherson .num_pages = num_pages 33010825b55SSean Christopherson }; 33110825b55SSean Christopherson 33210825b55SSean Christopherson vm_ioctl(vm, KVM_CLEAR_DIRTY_LOG, &args); 33310825b55SSean Christopherson } 33410825b55SSean Christopherson 33510825b55SSean Christopherson static inline uint32_t kvm_vm_reset_dirty_ring(struct kvm_vm *vm) 33610825b55SSean Christopherson { 33710825b55SSean Christopherson return __vm_ioctl(vm, KVM_RESET_DIRTY_RINGS, NULL); 33810825b55SSean Christopherson } 33910825b55SSean Christopherson 34010825b55SSean Christopherson static inline int vm_get_stats_fd(struct kvm_vm *vm) 34110825b55SSean Christopherson { 34210825b55SSean Christopherson int fd = __vm_ioctl(vm, KVM_GET_STATS_FD, NULL); 34310825b55SSean Christopherson 34410825b55SSean Christopherson TEST_ASSERT(fd >= 0, KVM_IOCTL_ERROR(KVM_GET_STATS_FD, fd)); 34510825b55SSean Christopherson return fd; 34610825b55SSean Christopherson } 34710825b55SSean Christopherson 34832faa064SBen Gardon static inline void read_stats_header(int stats_fd, struct kvm_stats_header *header) 34932faa064SBen Gardon { 35032faa064SBen Gardon ssize_t ret; 35132faa064SBen Gardon 35232faa064SBen Gardon ret = read(stats_fd, header, sizeof(*header)); 35332faa064SBen Gardon TEST_ASSERT(ret == sizeof(*header), "Read stats header"); 35432faa064SBen Gardon } 35532faa064SBen Gardon 3564d0a0594SBen Gardon struct kvm_stats_desc *read_stats_descriptors(int stats_fd, 3574d0a0594SBen Gardon struct kvm_stats_header *header); 3584d0a0594SBen Gardon 3594d0a0594SBen Gardon static inline ssize_t get_stats_descriptor_size(struct kvm_stats_header *header) 3604d0a0594SBen Gardon { 3614d0a0594SBen Gardon /* 3624d0a0594SBen Gardon * The base size of the descriptor is defined by KVM's ABI, but the 3634d0a0594SBen Gardon * size of the name field is variable, as far as KVM's ABI is 3644d0a0594SBen Gardon * concerned. For a given instance of KVM, the name field is the same 3654d0a0594SBen Gardon * size for all stats and is provided in the overall stats header. 3664d0a0594SBen Gardon */ 3674d0a0594SBen Gardon return sizeof(struct kvm_stats_desc) + header->name_size; 3684d0a0594SBen Gardon } 3694d0a0594SBen Gardon 3704d0a0594SBen Gardon static inline struct kvm_stats_desc *get_stats_descriptor(struct kvm_stats_desc *stats, 3714d0a0594SBen Gardon int index, 3724d0a0594SBen Gardon struct kvm_stats_header *header) 3734d0a0594SBen Gardon { 3744d0a0594SBen Gardon /* 3754d0a0594SBen Gardon * Note, size_desc includes the size of the name field, which is 3764d0a0594SBen Gardon * variable. i.e. this is NOT equivalent to &stats_desc[i]. 3774d0a0594SBen Gardon */ 3784d0a0594SBen Gardon return (void *)stats + index * get_stats_descriptor_size(header); 3794d0a0594SBen Gardon } 3804d0a0594SBen Gardon 381ed6b53ecSBen Gardon void read_stat_data(int stats_fd, struct kvm_stats_header *header, 382ed6b53ecSBen Gardon struct kvm_stats_desc *desc, uint64_t *data, 383ed6b53ecSBen Gardon size_t max_elements); 384ed6b53ecSBen Gardon 3858448ec59SBen Gardon void __vm_get_stat(struct kvm_vm *vm, const char *stat_name, uint64_t *data, 3868448ec59SBen Gardon size_t max_elements); 3878448ec59SBen Gardon 3888448ec59SBen Gardon static inline uint64_t vm_get_stat(struct kvm_vm *vm, const char *stat_name) 3898448ec59SBen Gardon { 3908448ec59SBen Gardon uint64_t data; 3918448ec59SBen Gardon 3928448ec59SBen Gardon __vm_get_stat(vm, stat_name, &data, 1); 3938448ec59SBen Gardon return data; 3948448ec59SBen Gardon } 3958448ec59SBen Gardon 3967d9a662eSMichael Roth void vm_create_irqchip(struct kvm_vm *vm); 3977d9a662eSMichael Roth 3983d7d6043SSean Christopherson void vm_set_user_memory_region(struct kvm_vm *vm, uint32_t slot, uint32_t flags, 3993d7d6043SSean Christopherson uint64_t gpa, uint64_t size, void *hva); 4003d7d6043SSean Christopherson int __vm_set_user_memory_region(struct kvm_vm *vm, uint32_t slot, uint32_t flags, 4013d7d6043SSean Christopherson uint64_t gpa, uint64_t size, void *hva); 4027d9a662eSMichael Roth void vm_userspace_mem_region_add(struct kvm_vm *vm, 4037d9a662eSMichael Roth enum vm_mem_backing_src_type src_type, 4047d9a662eSMichael Roth uint64_t guest_paddr, uint32_t slot, uint64_t npages, 4057d9a662eSMichael Roth uint32_t flags); 4067d9a662eSMichael Roth 4077d9a662eSMichael Roth void vm_mem_region_set_flags(struct kvm_vm *vm, uint32_t slot, uint32_t flags); 4087d9a662eSMichael Roth void vm_mem_region_move(struct kvm_vm *vm, uint32_t slot, uint64_t new_gpa); 4097d9a662eSMichael Roth void vm_mem_region_delete(struct kvm_vm *vm, uint32_t slot); 410768e9a61SSean Christopherson struct kvm_vcpu *__vm_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id); 411*e8b9a055SOliver Upton void vm_populate_vaddr_bitmap(struct kvm_vm *vm); 4122d4a5f91SVitaly Kuznetsov vm_vaddr_t vm_vaddr_unused_gap(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min); 4137d9a662eSMichael Roth vm_vaddr_t vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min); 4141446e331SRicardo Koller vm_vaddr_t __vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min, 4151446e331SRicardo Koller enum kvm_mem_region_type type); 4167d9a662eSMichael Roth vm_vaddr_t vm_vaddr_alloc_pages(struct kvm_vm *vm, int nr_pages); 4171446e331SRicardo Koller vm_vaddr_t __vm_vaddr_alloc_page(struct kvm_vm *vm, 4181446e331SRicardo Koller enum kvm_mem_region_type type); 4197d9a662eSMichael Roth vm_vaddr_t vm_vaddr_alloc_page(struct kvm_vm *vm); 4207d9a662eSMichael Roth 4217d9a662eSMichael Roth void virt_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, 4227d9a662eSMichael Roth unsigned int npages); 4237d9a662eSMichael Roth void *addr_gpa2hva(struct kvm_vm *vm, vm_paddr_t gpa); 4247d9a662eSMichael Roth void *addr_gva2hva(struct kvm_vm *vm, vm_vaddr_t gva); 4257d9a662eSMichael Roth vm_paddr_t addr_hva2gpa(struct kvm_vm *vm, void *hva); 4267d9a662eSMichael Roth void *addr_gpa2alias(struct kvm_vm *vm, vm_paddr_t gpa); 4277d9a662eSMichael Roth 428768e9a61SSean Christopherson void vcpu_run(struct kvm_vcpu *vcpu); 429768e9a61SSean Christopherson int _vcpu_run(struct kvm_vcpu *vcpu); 43038d4a385SSean Christopherson 431768e9a61SSean Christopherson static inline int __vcpu_run(struct kvm_vcpu *vcpu) 43238d4a385SSean Christopherson { 433768e9a61SSean Christopherson return __vcpu_ioctl(vcpu, KVM_RUN, NULL); 43438d4a385SSean Christopherson } 43538d4a385SSean Christopherson 436768e9a61SSean Christopherson void vcpu_run_complete_io(struct kvm_vcpu *vcpu); 437768e9a61SSean Christopherson struct kvm_reg_list *vcpu_get_reg_list(struct kvm_vcpu *vcpu); 438ffb7c77fSSean Christopherson 439768e9a61SSean Christopherson static inline void vcpu_enable_cap(struct kvm_vcpu *vcpu, uint32_t cap, 440768e9a61SSean Christopherson uint64_t arg0) 441ffb7c77fSSean Christopherson { 442a12c86c4SSean Christopherson struct kvm_enable_cap enable_cap = { .cap = cap, .args = { arg0 } }; 443a12c86c4SSean Christopherson 444768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_ENABLE_CAP, &enable_cap); 445ffb7c77fSSean Christopherson } 446ffb7c77fSSean Christopherson 447768e9a61SSean Christopherson static inline void vcpu_guest_debug_set(struct kvm_vcpu *vcpu, 448ffb7c77fSSean Christopherson struct kvm_guest_debug *debug) 449ffb7c77fSSean Christopherson { 450768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_SET_GUEST_DEBUG, debug); 451ffb7c77fSSean Christopherson } 452ffb7c77fSSean Christopherson 453768e9a61SSean Christopherson static inline void vcpu_mp_state_get(struct kvm_vcpu *vcpu, 454877bd399SSean Christopherson struct kvm_mp_state *mp_state) 455877bd399SSean Christopherson { 456768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_GET_MP_STATE, mp_state); 457877bd399SSean Christopherson } 458768e9a61SSean Christopherson static inline void vcpu_mp_state_set(struct kvm_vcpu *vcpu, 459ffb7c77fSSean Christopherson struct kvm_mp_state *mp_state) 460ffb7c77fSSean Christopherson { 461768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_SET_MP_STATE, mp_state); 462ffb7c77fSSean Christopherson } 463ffb7c77fSSean Christopherson 464768e9a61SSean Christopherson static inline void vcpu_regs_get(struct kvm_vcpu *vcpu, struct kvm_regs *regs) 465ffb7c77fSSean Christopherson { 466768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_GET_REGS, regs); 467ffb7c77fSSean Christopherson } 468ffb7c77fSSean Christopherson 469768e9a61SSean Christopherson static inline void vcpu_regs_set(struct kvm_vcpu *vcpu, struct kvm_regs *regs) 470ffb7c77fSSean Christopherson { 471768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_SET_REGS, regs); 472ffb7c77fSSean Christopherson } 473768e9a61SSean Christopherson static inline void vcpu_sregs_get(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) 474ffb7c77fSSean Christopherson { 475768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_GET_SREGS, sregs); 476ffb7c77fSSean Christopherson 477ffb7c77fSSean Christopherson } 478768e9a61SSean Christopherson static inline void vcpu_sregs_set(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) 479ffb7c77fSSean Christopherson { 480768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_SET_SREGS, sregs); 481ffb7c77fSSean Christopherson } 482768e9a61SSean Christopherson static inline int _vcpu_sregs_set(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) 483ffb7c77fSSean Christopherson { 484768e9a61SSean Christopherson return __vcpu_ioctl(vcpu, KVM_SET_SREGS, sregs); 485ffb7c77fSSean Christopherson } 486768e9a61SSean Christopherson static inline void vcpu_fpu_get(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) 487ffb7c77fSSean Christopherson { 488768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_GET_FPU, fpu); 489ffb7c77fSSean Christopherson } 490768e9a61SSean Christopherson static inline void vcpu_fpu_set(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) 491ffb7c77fSSean Christopherson { 492768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_SET_FPU, fpu); 493ffb7c77fSSean Christopherson } 494bfff0f60SSean Christopherson 495768e9a61SSean Christopherson static inline int __vcpu_get_reg(struct kvm_vcpu *vcpu, uint64_t id, void *addr) 496ffb7c77fSSean Christopherson { 497768e9a61SSean Christopherson struct kvm_one_reg reg = { .id = id, .addr = (uint64_t)addr }; 498bfff0f60SSean Christopherson 499768e9a61SSean Christopherson return __vcpu_ioctl(vcpu, KVM_GET_ONE_REG, ®); 500bfff0f60SSean Christopherson } 501768e9a61SSean Christopherson static inline int __vcpu_set_reg(struct kvm_vcpu *vcpu, uint64_t id, uint64_t val) 502bfff0f60SSean Christopherson { 503768e9a61SSean Christopherson struct kvm_one_reg reg = { .id = id, .addr = (uint64_t)&val }; 504bfff0f60SSean Christopherson 505768e9a61SSean Christopherson return __vcpu_ioctl(vcpu, KVM_SET_ONE_REG, ®); 506bfff0f60SSean Christopherson } 507768e9a61SSean Christopherson static inline void vcpu_get_reg(struct kvm_vcpu *vcpu, uint64_t id, void *addr) 508bfff0f60SSean Christopherson { 509768e9a61SSean Christopherson struct kvm_one_reg reg = { .id = id, .addr = (uint64_t)addr }; 510bfff0f60SSean Christopherson 511768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_GET_ONE_REG, ®); 512ffb7c77fSSean Christopherson } 513768e9a61SSean Christopherson static inline void vcpu_set_reg(struct kvm_vcpu *vcpu, uint64_t id, uint64_t val) 514ffb7c77fSSean Christopherson { 515768e9a61SSean Christopherson struct kvm_one_reg reg = { .id = id, .addr = (uint64_t)&val }; 516bfff0f60SSean Christopherson 517768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_SET_ONE_REG, ®); 518ffb7c77fSSean Christopherson } 519bfff0f60SSean Christopherson 520ffb7c77fSSean Christopherson #ifdef __KVM_HAVE_VCPU_EVENTS 521768e9a61SSean Christopherson static inline void vcpu_events_get(struct kvm_vcpu *vcpu, 522ffb7c77fSSean Christopherson struct kvm_vcpu_events *events) 523ffb7c77fSSean Christopherson { 524768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_GET_VCPU_EVENTS, events); 525ffb7c77fSSean Christopherson } 526768e9a61SSean Christopherson static inline void vcpu_events_set(struct kvm_vcpu *vcpu, 527ffb7c77fSSean Christopherson struct kvm_vcpu_events *events) 528ffb7c77fSSean Christopherson { 529768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_SET_VCPU_EVENTS, events); 530ffb7c77fSSean Christopherson } 531ffb7c77fSSean Christopherson #endif 532ffb7c77fSSean Christopherson #ifdef __x86_64__ 533768e9a61SSean Christopherson static inline void vcpu_nested_state_get(struct kvm_vcpu *vcpu, 534ffb7c77fSSean Christopherson struct kvm_nested_state *state) 535ffb7c77fSSean Christopherson { 536768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_GET_NESTED_STATE, state); 537ffb7c77fSSean Christopherson } 538768e9a61SSean Christopherson static inline int __vcpu_nested_state_set(struct kvm_vcpu *vcpu, 539ffb7c77fSSean Christopherson struct kvm_nested_state *state) 540ffb7c77fSSean Christopherson { 541768e9a61SSean Christopherson return __vcpu_ioctl(vcpu, KVM_SET_NESTED_STATE, state); 542ffb7c77fSSean Christopherson } 543ffb7c77fSSean Christopherson 544768e9a61SSean Christopherson static inline void vcpu_nested_state_set(struct kvm_vcpu *vcpu, 545ffb7c77fSSean Christopherson struct kvm_nested_state *state) 546ffb7c77fSSean Christopherson { 547768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_SET_NESTED_STATE, state); 548ffb7c77fSSean Christopherson } 549ffb7c77fSSean Christopherson #endif 550768e9a61SSean Christopherson static inline int vcpu_get_stats_fd(struct kvm_vcpu *vcpu) 551ffb7c77fSSean Christopherson { 552768e9a61SSean Christopherson int fd = __vcpu_ioctl(vcpu, KVM_GET_STATS_FD, NULL); 553ffb7c77fSSean Christopherson 554ffb7c77fSSean Christopherson TEST_ASSERT(fd >= 0, KVM_IOCTL_ERROR(KVM_GET_STATS_FD, fd)); 555ffb7c77fSSean Christopherson return fd; 556ffb7c77fSSean Christopherson } 557ffb7c77fSSean Christopherson 55840918184SSean Christopherson int __kvm_has_device_attr(int dev_fd, uint32_t group, uint64_t attr); 55940918184SSean Christopherson 56040918184SSean Christopherson static inline void kvm_has_device_attr(int dev_fd, uint32_t group, uint64_t attr) 56140918184SSean Christopherson { 56240918184SSean Christopherson int ret = __kvm_has_device_attr(dev_fd, group, attr); 56340918184SSean Christopherson 56440918184SSean Christopherson TEST_ASSERT(!ret, "KVM_HAS_DEVICE_ATTR failed, rc: %i errno: %i", ret, errno); 56540918184SSean Christopherson } 56640918184SSean Christopherson 56740918184SSean Christopherson int __kvm_device_attr_get(int dev_fd, uint32_t group, uint64_t attr, void *val); 56840918184SSean Christopherson 56940918184SSean Christopherson static inline void kvm_device_attr_get(int dev_fd, uint32_t group, 57040918184SSean Christopherson uint64_t attr, void *val) 57140918184SSean Christopherson { 57240918184SSean Christopherson int ret = __kvm_device_attr_get(dev_fd, group, attr, val); 57340918184SSean Christopherson 57440918184SSean Christopherson TEST_ASSERT(!ret, KVM_IOCTL_ERROR(KVM_GET_DEVICE_ATTR, ret)); 57540918184SSean Christopherson } 57640918184SSean Christopherson 57740918184SSean Christopherson int __kvm_device_attr_set(int dev_fd, uint32_t group, uint64_t attr, void *val); 57840918184SSean Christopherson 57940918184SSean Christopherson static inline void kvm_device_attr_set(int dev_fd, uint32_t group, 58040918184SSean Christopherson uint64_t attr, void *val) 58140918184SSean Christopherson { 58240918184SSean Christopherson int ret = __kvm_device_attr_set(dev_fd, group, attr, val); 58340918184SSean Christopherson 58440918184SSean Christopherson TEST_ASSERT(!ret, KVM_IOCTL_ERROR(KVM_SET_DEVICE_ATTR, ret)); 58540918184SSean Christopherson } 58640918184SSean Christopherson 587768e9a61SSean Christopherson static inline int __vcpu_has_device_attr(struct kvm_vcpu *vcpu, uint32_t group, 588768e9a61SSean Christopherson uint64_t attr) 58940918184SSean Christopherson { 590768e9a61SSean Christopherson return __kvm_has_device_attr(vcpu->fd, group, attr); 59140918184SSean Christopherson } 59240918184SSean Christopherson 593768e9a61SSean Christopherson static inline void vcpu_has_device_attr(struct kvm_vcpu *vcpu, uint32_t group, 594768e9a61SSean Christopherson uint64_t attr) 595768e9a61SSean Christopherson { 596768e9a61SSean Christopherson kvm_has_device_attr(vcpu->fd, group, attr); 597768e9a61SSean Christopherson } 598768e9a61SSean Christopherson 599768e9a61SSean Christopherson static inline int __vcpu_device_attr_get(struct kvm_vcpu *vcpu, uint32_t group, 600768e9a61SSean Christopherson uint64_t attr, void *val) 601768e9a61SSean Christopherson { 602768e9a61SSean Christopherson return __kvm_device_attr_get(vcpu->fd, group, attr, val); 603768e9a61SSean Christopherson } 604768e9a61SSean Christopherson 605768e9a61SSean Christopherson static inline void vcpu_device_attr_get(struct kvm_vcpu *vcpu, uint32_t group, 606768e9a61SSean Christopherson uint64_t attr, void *val) 607768e9a61SSean Christopherson { 608768e9a61SSean Christopherson kvm_device_attr_get(vcpu->fd, group, attr, val); 609768e9a61SSean Christopherson } 610768e9a61SSean Christopherson 611768e9a61SSean Christopherson static inline int __vcpu_device_attr_set(struct kvm_vcpu *vcpu, uint32_t group, 612768e9a61SSean Christopherson uint64_t attr, void *val) 613768e9a61SSean Christopherson { 614768e9a61SSean Christopherson return __kvm_device_attr_set(vcpu->fd, group, attr, val); 615768e9a61SSean Christopherson } 616768e9a61SSean Christopherson 617768e9a61SSean Christopherson static inline void vcpu_device_attr_set(struct kvm_vcpu *vcpu, uint32_t group, 618768e9a61SSean Christopherson uint64_t attr, void *val) 619768e9a61SSean Christopherson { 620768e9a61SSean Christopherson kvm_device_attr_set(vcpu->fd, group, attr, val); 621768e9a61SSean Christopherson } 622768e9a61SSean Christopherson 62340918184SSean Christopherson int __kvm_test_create_device(struct kvm_vm *vm, uint64_t type); 62440918184SSean Christopherson int __kvm_create_device(struct kvm_vm *vm, uint64_t type); 62540918184SSean Christopherson 62640918184SSean Christopherson static inline int kvm_create_device(struct kvm_vm *vm, uint64_t type) 62740918184SSean Christopherson { 62840918184SSean Christopherson int fd = __kvm_create_device(vm, type); 62940918184SSean Christopherson 63040918184SSean Christopherson TEST_ASSERT(fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_DEVICE, fd)); 63140918184SSean Christopherson return fd; 63240918184SSean Christopherson } 63340918184SSean Christopherson 634768e9a61SSean Christopherson void *vcpu_map_dirty_ring(struct kvm_vcpu *vcpu); 6357d9a662eSMichael Roth 6367d9a662eSMichael Roth /* 6377d9a662eSMichael Roth * VM VCPU Args Set 6387d9a662eSMichael Roth * 6397d9a662eSMichael Roth * Input Args: 6407d9a662eSMichael Roth * vm - Virtual Machine 6417d9a662eSMichael Roth * num - number of arguments 6427d9a662eSMichael Roth * ... - arguments, each of type uint64_t 6437d9a662eSMichael Roth * 6447d9a662eSMichael Roth * Output Args: None 6457d9a662eSMichael Roth * 6467d9a662eSMichael Roth * Return: None 6477d9a662eSMichael Roth * 648768e9a61SSean Christopherson * Sets the first @num input parameters for the function at @vcpu's entry point, 649768e9a61SSean Christopherson * per the C calling convention of the architecture, to the values given as 650768e9a61SSean Christopherson * variable args. Each of the variable args is expected to be of type uint64_t. 651768e9a61SSean Christopherson * The maximum @num can be is specific to the architecture. 6527d9a662eSMichael Roth */ 653768e9a61SSean Christopherson void vcpu_args_set(struct kvm_vcpu *vcpu, unsigned int num, ...); 6547d9a662eSMichael Roth 6557d9a662eSMichael Roth void kvm_irq_line(struct kvm_vm *vm, uint32_t irq, int level); 6567d9a662eSMichael Roth int _kvm_irq_line(struct kvm_vm *vm, uint32_t irq, int level); 6577d9a662eSMichael Roth 6587d9a662eSMichael Roth #define KVM_MAX_IRQ_ROUTES 4096 6597d9a662eSMichael Roth 6607d9a662eSMichael Roth struct kvm_irq_routing *kvm_gsi_routing_create(void); 6617d9a662eSMichael Roth void kvm_gsi_routing_irqchip_add(struct kvm_irq_routing *routing, 6627d9a662eSMichael Roth uint32_t gsi, uint32_t pin); 6637d9a662eSMichael Roth int _kvm_gsi_routing_write(struct kvm_vm *vm, struct kvm_irq_routing *routing); 6647d9a662eSMichael Roth void kvm_gsi_routing_write(struct kvm_vm *vm, struct kvm_irq_routing *routing); 6657d9a662eSMichael Roth 6667d9a662eSMichael Roth const char *exit_reason_str(unsigned int exit_reason); 6677d9a662eSMichael Roth 6687d9a662eSMichael Roth vm_paddr_t vm_phy_page_alloc(struct kvm_vm *vm, vm_paddr_t paddr_min, 6697d9a662eSMichael Roth uint32_t memslot); 6707d9a662eSMichael Roth vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num, 6717d9a662eSMichael Roth vm_paddr_t paddr_min, uint32_t memslot); 6727d9a662eSMichael Roth vm_paddr_t vm_alloc_page_table(struct kvm_vm *vm); 6737d9a662eSMichael Roth 6743f44e7fdSSean Christopherson /* 6753f44e7fdSSean Christopherson * ____vm_create() does KVM_CREATE_VM and little else. __vm_create() also 6763f44e7fdSSean Christopherson * loads the test binary into guest memory and creates an IRQ chip (x86 only). 6776e1d13bfSSean Christopherson * __vm_create() does NOT create vCPUs, @nr_runnable_vcpus is used purely to 6786e1d13bfSSean Christopherson * calculate the amount of memory needed for per-vCPU data, e.g. stacks. 6793f44e7fdSSean Christopherson */ 680290c5b54SRicardo Koller struct kvm_vm *____vm_create(enum vm_guest_mode mode); 6816e1d13bfSSean Christopherson struct kvm_vm *__vm_create(enum vm_guest_mode mode, uint32_t nr_runnable_vcpus, 6826e1d13bfSSean Christopherson uint64_t nr_extra_pages); 6833f44e7fdSSean Christopherson 68495fb0460SSean Christopherson static inline struct kvm_vm *vm_create_barebones(void) 68595fb0460SSean Christopherson { 686290c5b54SRicardo Koller return ____vm_create(VM_MODE_DEFAULT); 6873f44e7fdSSean Christopherson } 6883f44e7fdSSean Christopherson 6896e1d13bfSSean Christopherson static inline struct kvm_vm *vm_create(uint32_t nr_runnable_vcpus) 6903f44e7fdSSean Christopherson { 6916e1d13bfSSean Christopherson return __vm_create(VM_MODE_DEFAULT, nr_runnable_vcpus, 0); 69295fb0460SSean Christopherson } 69395fb0460SSean Christopherson 6940ffc70eaSSean Christopherson struct kvm_vm *__vm_create_with_vcpus(enum vm_guest_mode mode, uint32_t nr_vcpus, 695acaf50adSSean Christopherson uint64_t extra_mem_pages, 6963222d026SSean Christopherson void *guest_code, struct kvm_vcpu *vcpus[]); 6970ffc70eaSSean Christopherson 6980ffc70eaSSean Christopherson static inline struct kvm_vm *vm_create_with_vcpus(uint32_t nr_vcpus, 6990ffc70eaSSean Christopherson void *guest_code, 7000ffc70eaSSean Christopherson struct kvm_vcpu *vcpus[]) 7010ffc70eaSSean Christopherson { 702acaf50adSSean Christopherson return __vm_create_with_vcpus(VM_MODE_DEFAULT, nr_vcpus, 0, 7035114c3e2SSean Christopherson guest_code, vcpus); 7040ffc70eaSSean Christopherson } 7057d9a662eSMichael Roth 7067d9a662eSMichael Roth /* 707f17686aaSSean Christopherson * Create a VM with a single vCPU with reasonable defaults and @extra_mem_pages 708f17686aaSSean Christopherson * additional pages of guest memory. Returns the VM and vCPU (via out param). 709f17686aaSSean Christopherson */ 7100cc64b08SSean Christopherson struct kvm_vm *__vm_create_with_one_vcpu(struct kvm_vcpu **vcpu, 711f17686aaSSean Christopherson uint64_t extra_mem_pages, 712f17686aaSSean Christopherson void *guest_code); 713f17686aaSSean Christopherson 7140cc64b08SSean Christopherson static inline struct kvm_vm *vm_create_with_one_vcpu(struct kvm_vcpu **vcpu, 715f17686aaSSean Christopherson void *guest_code) 716f17686aaSSean Christopherson { 717f17686aaSSean Christopherson return __vm_create_with_one_vcpu(vcpu, 0, guest_code); 718f17686aaSSean Christopherson } 719f17686aaSSean Christopherson 7200cc64b08SSean Christopherson struct kvm_vcpu *vm_recreate_with_one_vcpu(struct kvm_vm *vm); 721f17686aaSSean Christopherson 722d886724eSVipin Sharma void kvm_pin_this_task_to_pcpu(uint32_t pcpu); 723d886724eSVipin Sharma void kvm_parse_vcpu_pinning(const char *pcpus_string, uint32_t vcpu_to_pcpu[], 724d886724eSVipin Sharma int nr_vcpus); 725d886724eSVipin Sharma 7267d9a662eSMichael Roth unsigned long vm_compute_max_gfn(struct kvm_vm *vm); 7277d9a662eSMichael Roth unsigned int vm_calc_num_guest_pages(enum vm_guest_mode mode, size_t size); 7287d9a662eSMichael Roth unsigned int vm_num_host_pages(enum vm_guest_mode mode, unsigned int num_guest_pages); 7297d9a662eSMichael Roth unsigned int vm_num_guest_pages(enum vm_guest_mode mode, unsigned int num_host_pages); 7307d9a662eSMichael Roth static inline unsigned int 7317d9a662eSMichael Roth vm_adjust_num_guest_pages(enum vm_guest_mode mode, unsigned int num_guest_pages) 7327d9a662eSMichael Roth { 7337d9a662eSMichael Roth unsigned int n; 7347d9a662eSMichael Roth n = vm_num_guest_pages(mode, vm_num_host_pages(mode, num_guest_pages)); 7357d9a662eSMichael Roth #ifdef __s390x__ 7367d9a662eSMichael Roth /* s390 requires 1M aligned guest sizes */ 7377d9a662eSMichael Roth n = (n + 255) & ~255; 7387d9a662eSMichael Roth #endif 7397d9a662eSMichael Roth return n; 7407d9a662eSMichael Roth } 7417d9a662eSMichael Roth 7427d9a662eSMichael Roth struct kvm_userspace_memory_region * 7437d9a662eSMichael Roth kvm_userspace_memory_region_find(struct kvm_vm *vm, uint64_t start, 7447d9a662eSMichael Roth uint64_t end); 7457d9a662eSMichael Roth 7467d9a662eSMichael Roth #define sync_global_to_guest(vm, g) ({ \ 7477d9a662eSMichael Roth typeof(g) *_p = addr_gva2hva(vm, (vm_vaddr_t)&(g)); \ 7487d9a662eSMichael Roth memcpy(_p, &(g), sizeof(g)); \ 7497d9a662eSMichael Roth }) 7507d9a662eSMichael Roth 7517d9a662eSMichael Roth #define sync_global_from_guest(vm, g) ({ \ 7527d9a662eSMichael Roth typeof(g) *_p = addr_gva2hva(vm, (vm_vaddr_t)&(g)); \ 7537d9a662eSMichael Roth memcpy(&(g), _p, sizeof(g)); \ 7547d9a662eSMichael Roth }) 7557d9a662eSMichael Roth 75603b47505SSean Christopherson /* 75703b47505SSean Christopherson * Write a global value, but only in the VM's (guest's) domain. Primarily used 75803b47505SSean Christopherson * for "globals" that hold per-VM values (VMs always duplicate code and global 75903b47505SSean Christopherson * data into their own region of physical memory), but can be used anytime it's 76003b47505SSean Christopherson * undesirable to change the host's copy of the global. 76103b47505SSean Christopherson */ 76203b47505SSean Christopherson #define write_guest_global(vm, g, val) ({ \ 76303b47505SSean Christopherson typeof(g) *_p = addr_gva2hva(vm, (vm_vaddr_t)&(g)); \ 76403b47505SSean Christopherson typeof(g) _val = val; \ 76503b47505SSean Christopherson \ 76603b47505SSean Christopherson memcpy(_p, &(_val), sizeof(g)); \ 76703b47505SSean Christopherson }) 76803b47505SSean Christopherson 769768e9a61SSean Christopherson void assert_on_unhandled_exception(struct kvm_vcpu *vcpu); 7707d9a662eSMichael Roth 771768e9a61SSean Christopherson void vcpu_arch_dump(FILE *stream, struct kvm_vcpu *vcpu, 7729931be3fSSean Christopherson uint8_t indent); 7739931be3fSSean Christopherson 774768e9a61SSean Christopherson static inline void vcpu_dump(FILE *stream, struct kvm_vcpu *vcpu, 7759931be3fSSean Christopherson uint8_t indent) 7769931be3fSSean Christopherson { 777768e9a61SSean Christopherson vcpu_arch_dump(stream, vcpu, indent); 7789931be3fSSean Christopherson } 7799931be3fSSean Christopherson 7809931be3fSSean Christopherson /* 7819931be3fSSean Christopherson * Adds a vCPU with reasonable defaults (e.g. a stack) 7829931be3fSSean Christopherson * 7839931be3fSSean Christopherson * Input Args: 7849931be3fSSean Christopherson * vm - Virtual Machine 785768e9a61SSean Christopherson * vcpu_id - The id of the VCPU to add to the VM. 7869931be3fSSean Christopherson * guest_code - The vCPU's entry point 7879931be3fSSean Christopherson */ 7881422efd6SSean Christopherson struct kvm_vcpu *vm_arch_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id, 7891422efd6SSean Christopherson void *guest_code); 7909931be3fSSean Christopherson 791f742d94fSSean Christopherson static inline struct kvm_vcpu *vm_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id, 7929931be3fSSean Christopherson void *guest_code) 7939931be3fSSean Christopherson { 7941422efd6SSean Christopherson return vm_arch_vcpu_add(vm, vcpu_id, guest_code); 7959931be3fSSean Christopherson } 7969931be3fSSean Christopherson 7974c16fa3eSSean Christopherson /* Re-create a vCPU after restarting a VM, e.g. for state save/restore tests. */ 7984c16fa3eSSean Christopherson struct kvm_vcpu *vm_arch_vcpu_recreate(struct kvm_vm *vm, uint32_t vcpu_id); 7994c16fa3eSSean Christopherson 8004c16fa3eSSean Christopherson static inline struct kvm_vcpu *vm_vcpu_recreate(struct kvm_vm *vm, 8014c16fa3eSSean Christopherson uint32_t vcpu_id) 8024c16fa3eSSean Christopherson { 8034c16fa3eSSean Christopherson return vm_arch_vcpu_recreate(vm, vcpu_id); 8044c16fa3eSSean Christopherson } 8054c16fa3eSSean Christopherson 8067fbc6038SSean Christopherson void vcpu_arch_free(struct kvm_vcpu *vcpu); 8077fbc6038SSean Christopherson 8089931be3fSSean Christopherson void virt_arch_pgd_alloc(struct kvm_vm *vm); 8099931be3fSSean Christopherson 8109931be3fSSean Christopherson static inline void virt_pgd_alloc(struct kvm_vm *vm) 8119931be3fSSean Christopherson { 8129931be3fSSean Christopherson virt_arch_pgd_alloc(vm); 8139931be3fSSean Christopherson } 8149931be3fSSean Christopherson 8159931be3fSSean Christopherson /* 8169931be3fSSean Christopherson * VM Virtual Page Map 8179931be3fSSean Christopherson * 8189931be3fSSean Christopherson * Input Args: 8199931be3fSSean Christopherson * vm - Virtual Machine 8209931be3fSSean Christopherson * vaddr - VM Virtual Address 8219931be3fSSean Christopherson * paddr - VM Physical Address 8229931be3fSSean Christopherson * memslot - Memory region slot for new virtual translation tables 8239931be3fSSean Christopherson * 8249931be3fSSean Christopherson * Output Args: None 8259931be3fSSean Christopherson * 8269931be3fSSean Christopherson * Return: None 8279931be3fSSean Christopherson * 8289931be3fSSean Christopherson * Within @vm, creates a virtual translation for the page starting 8299931be3fSSean Christopherson * at @vaddr to the page starting at @paddr. 8309931be3fSSean Christopherson */ 8319931be3fSSean Christopherson void virt_arch_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr); 8329931be3fSSean Christopherson 8339931be3fSSean Christopherson static inline void virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr) 8349931be3fSSean Christopherson { 8359931be3fSSean Christopherson virt_arch_pg_map(vm, vaddr, paddr); 8369931be3fSSean Christopherson } 8379931be3fSSean Christopherson 8389931be3fSSean Christopherson 8399931be3fSSean Christopherson /* 8409931be3fSSean Christopherson * Address Guest Virtual to Guest Physical 8419931be3fSSean Christopherson * 8429931be3fSSean Christopherson * Input Args: 8439931be3fSSean Christopherson * vm - Virtual Machine 8449931be3fSSean Christopherson * gva - VM virtual address 8459931be3fSSean Christopherson * 8469931be3fSSean Christopherson * Output Args: None 8479931be3fSSean Christopherson * 8489931be3fSSean Christopherson * Return: 8499931be3fSSean Christopherson * Equivalent VM physical address 8509931be3fSSean Christopherson * 8519931be3fSSean Christopherson * Returns the VM physical address of the translated VM virtual 8529931be3fSSean Christopherson * address given by @gva. 8539931be3fSSean Christopherson */ 8549931be3fSSean Christopherson vm_paddr_t addr_arch_gva2gpa(struct kvm_vm *vm, vm_vaddr_t gva); 8559931be3fSSean Christopherson 8569931be3fSSean Christopherson static inline vm_paddr_t addr_gva2gpa(struct kvm_vm *vm, vm_vaddr_t gva) 8579931be3fSSean Christopherson { 8589931be3fSSean Christopherson return addr_arch_gva2gpa(vm, gva); 8599931be3fSSean Christopherson } 8609931be3fSSean Christopherson 8619931be3fSSean Christopherson /* 8629931be3fSSean Christopherson * Virtual Translation Tables Dump 8639931be3fSSean Christopherson * 8649931be3fSSean Christopherson * Input Args: 8659931be3fSSean Christopherson * stream - Output FILE stream 8669931be3fSSean Christopherson * vm - Virtual Machine 8679931be3fSSean Christopherson * indent - Left margin indent amount 8689931be3fSSean Christopherson * 8699931be3fSSean Christopherson * Output Args: None 8709931be3fSSean Christopherson * 8719931be3fSSean Christopherson * Return: None 8729931be3fSSean Christopherson * 8739931be3fSSean Christopherson * Dumps to the FILE stream given by @stream, the contents of all the 8749931be3fSSean Christopherson * virtual translation tables for the VM given by @vm. 8759931be3fSSean Christopherson */ 8769931be3fSSean Christopherson void virt_arch_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent); 8779931be3fSSean Christopherson 8789931be3fSSean Christopherson static inline void virt_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent) 8799931be3fSSean Christopherson { 8809931be3fSSean Christopherson virt_arch_dump(stream, vm, indent); 8819931be3fSSean Christopherson } 8829931be3fSSean Christopherson 883b774da3fSBen Gardon 884b774da3fSBen Gardon static inline int __vm_disable_nx_huge_pages(struct kvm_vm *vm) 885b774da3fSBen Gardon { 886b774da3fSBen Gardon return __vm_enable_cap(vm, KVM_CAP_VM_DISABLE_NX_HUGE_PAGES, 0); 887b774da3fSBen Gardon } 888b774da3fSBen Gardon 889e1ab3124SVishal Annapurve /* 890e1ab3124SVishal Annapurve * Arch hook that is invoked via a constructor, i.e. before exeucting main(), 891e1ab3124SVishal Annapurve * to allow for arch-specific setup that is common to all tests, e.g. computing 892e1ab3124SVishal Annapurve * the default guest "mode". 893e1ab3124SVishal Annapurve */ 894e1ab3124SVishal Annapurve void kvm_selftest_arch_init(void); 895e1ab3124SVishal Annapurve 8962115713cSVishal Annapurve void kvm_arch_vm_post_create(struct kvm_vm *vm); 8972115713cSVishal Annapurve 8987d9a662eSMichael Roth #endif /* SELFTEST_KVM_UTIL_BASE_H */ 899