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 190cc64b08SSean Christopherson 207d9a662eSMichael Roth #include <sys/ioctl.h> 217d9a662eSMichael Roth 227d9a662eSMichael Roth #include "sparsebit.h" 237d9a662eSMichael Roth 247d9a662eSMichael Roth #define KVM_DEV_PATH "/dev/kvm" 257d9a662eSMichael Roth #define KVM_MAX_VCPUS 512 267d9a662eSMichael Roth 277d9a662eSMichael Roth #define NSEC_PER_SEC 1000000000L 287d9a662eSMichael Roth 297d9a662eSMichael Roth typedef uint64_t vm_paddr_t; /* Virtual Machine (Guest) physical address */ 307d9a662eSMichael Roth typedef uint64_t vm_vaddr_t; /* Virtual Machine (Guest) virtual address */ 317d9a662eSMichael Roth 32b530eba1SSean Christopherson struct userspace_mem_region { 33b530eba1SSean Christopherson struct kvm_userspace_memory_region region; 34b530eba1SSean Christopherson struct sparsebit *unused_phy_pages; 35b530eba1SSean Christopherson int fd; 36b530eba1SSean Christopherson off_t offset; 37*bd3ed7e1SRicardo Koller enum vm_mem_backing_src_type backing_src_type; 38b530eba1SSean Christopherson void *host_mem; 39b530eba1SSean Christopherson void *host_alias; 40b530eba1SSean Christopherson void *mmap_start; 41b530eba1SSean Christopherson void *mmap_alias; 42b530eba1SSean Christopherson size_t mmap_size; 43b530eba1SSean Christopherson struct rb_node gpa_node; 44b530eba1SSean Christopherson struct rb_node hva_node; 45b530eba1SSean Christopherson struct hlist_node slot_node; 46b530eba1SSean Christopherson }; 47b530eba1SSean Christopherson 480cc64b08SSean Christopherson struct kvm_vcpu { 49b530eba1SSean Christopherson struct list_head list; 50b530eba1SSean Christopherson uint32_t id; 51b530eba1SSean Christopherson int fd; 52c472df1aSSean Christopherson struct kvm_vm *vm; 531079c3d4SSean Christopherson struct kvm_run *run; 547fbc6038SSean Christopherson #ifdef __x86_64__ 557fbc6038SSean Christopherson struct kvm_cpuid2 *cpuid; 567fbc6038SSean Christopherson #endif 57b530eba1SSean Christopherson struct kvm_dirty_gfn *dirty_gfns; 58b530eba1SSean Christopherson uint32_t fetch_index; 59b530eba1SSean Christopherson uint32_t dirty_gfns_count; 60b530eba1SSean Christopherson }; 61b530eba1SSean Christopherson 62b530eba1SSean Christopherson struct userspace_mem_regions { 63b530eba1SSean Christopherson struct rb_root gpa_tree; 64b530eba1SSean Christopherson struct rb_root hva_tree; 65b530eba1SSean Christopherson DECLARE_HASHTABLE(slot_hash, 9); 66b530eba1SSean Christopherson }; 67b530eba1SSean Christopherson 68b530eba1SSean Christopherson struct kvm_vm { 69b530eba1SSean Christopherson int mode; 70b530eba1SSean Christopherson unsigned long type; 71b530eba1SSean Christopherson int kvm_fd; 72b530eba1SSean Christopherson int fd; 73b530eba1SSean Christopherson unsigned int pgtable_levels; 74b530eba1SSean Christopherson unsigned int page_size; 75b530eba1SSean Christopherson unsigned int page_shift; 76b530eba1SSean Christopherson unsigned int pa_bits; 77b530eba1SSean Christopherson unsigned int va_bits; 78b530eba1SSean Christopherson uint64_t max_gfn; 79b530eba1SSean Christopherson struct list_head vcpus; 80b530eba1SSean Christopherson struct userspace_mem_regions regions; 81b530eba1SSean Christopherson struct sparsebit *vpages_valid; 82b530eba1SSean Christopherson struct sparsebit *vpages_mapped; 83b530eba1SSean Christopherson bool has_irqchip; 84b530eba1SSean Christopherson bool pgd_created; 85b530eba1SSean Christopherson vm_paddr_t pgd; 86b530eba1SSean Christopherson vm_vaddr_t gdt; 87b530eba1SSean Christopherson vm_vaddr_t tss; 88b530eba1SSean Christopherson vm_vaddr_t idt; 89b530eba1SSean Christopherson vm_vaddr_t handlers; 90b530eba1SSean Christopherson uint32_t dirty_ring_size; 9183f6e109SBen Gardon 9283f6e109SBen Gardon /* Cache of information for binary stats interface */ 9383f6e109SBen Gardon int stats_fd; 9483f6e109SBen Gardon struct kvm_stats_header stats_header; 9583f6e109SBen Gardon struct kvm_stats_desc *stats_desc; 96b530eba1SSean Christopherson }; 97b530eba1SSean Christopherson 98b530eba1SSean Christopherson 99b530eba1SSean Christopherson #define kvm_for_each_vcpu(vm, i, vcpu) \ 100b530eba1SSean Christopherson for ((i) = 0; (i) <= (vm)->last_vcpu_id; (i)++) \ 101b530eba1SSean Christopherson if (!((vcpu) = vm->vcpus[i])) \ 102b530eba1SSean Christopherson continue; \ 103b530eba1SSean Christopherson else 104b530eba1SSean Christopherson 105b530eba1SSean Christopherson struct userspace_mem_region * 106b530eba1SSean Christopherson memslot2region(struct kvm_vm *vm, uint32_t memslot); 107b530eba1SSean Christopherson 1087d9a662eSMichael Roth /* Minimum allocated guest virtual and physical addresses */ 1097d9a662eSMichael Roth #define KVM_UTIL_MIN_VADDR 0x2000 1107d9a662eSMichael Roth #define KVM_GUEST_PAGE_TABLE_MIN_PADDR 0x180000 1117d9a662eSMichael Roth 1127d9a662eSMichael Roth #define DEFAULT_GUEST_STACK_VADDR_MIN 0xab6000 1137d9a662eSMichael Roth #define DEFAULT_STACK_PGS 5 1147d9a662eSMichael Roth 1157d9a662eSMichael Roth enum vm_guest_mode { 1167d9a662eSMichael Roth VM_MODE_P52V48_4K, 1177d9a662eSMichael Roth VM_MODE_P52V48_64K, 1187d9a662eSMichael Roth VM_MODE_P48V48_4K, 1197d9a662eSMichael Roth VM_MODE_P48V48_16K, 1207d9a662eSMichael Roth VM_MODE_P48V48_64K, 1217d9a662eSMichael Roth VM_MODE_P40V48_4K, 1227d9a662eSMichael Roth VM_MODE_P40V48_16K, 1237d9a662eSMichael Roth VM_MODE_P40V48_64K, 1247d9a662eSMichael Roth VM_MODE_PXXV48_4K, /* For 48bits VA but ANY bits PA */ 1257d9a662eSMichael Roth VM_MODE_P47V64_4K, 1267d9a662eSMichael Roth VM_MODE_P44V64_4K, 1277d9a662eSMichael Roth VM_MODE_P36V48_4K, 1287d9a662eSMichael Roth VM_MODE_P36V48_16K, 1297d9a662eSMichael Roth VM_MODE_P36V48_64K, 1307d9a662eSMichael Roth VM_MODE_P36V47_16K, 1317d9a662eSMichael Roth NUM_VM_MODES, 1327d9a662eSMichael Roth }; 1337d9a662eSMichael Roth 1347d9a662eSMichael Roth #if defined(__aarch64__) 1357d9a662eSMichael Roth 1367d9a662eSMichael Roth extern enum vm_guest_mode vm_mode_default; 1377d9a662eSMichael Roth 1387d9a662eSMichael Roth #define VM_MODE_DEFAULT vm_mode_default 1397d9a662eSMichael Roth #define MIN_PAGE_SHIFT 12U 1407d9a662eSMichael Roth #define ptes_per_page(page_size) ((page_size) / 8) 1417d9a662eSMichael Roth 1427d9a662eSMichael Roth #elif defined(__x86_64__) 1437d9a662eSMichael Roth 1447d9a662eSMichael Roth #define VM_MODE_DEFAULT VM_MODE_PXXV48_4K 1457d9a662eSMichael Roth #define MIN_PAGE_SHIFT 12U 1467d9a662eSMichael Roth #define ptes_per_page(page_size) ((page_size) / 8) 1477d9a662eSMichael Roth 1487d9a662eSMichael Roth #elif defined(__s390x__) 1497d9a662eSMichael Roth 1507d9a662eSMichael Roth #define VM_MODE_DEFAULT VM_MODE_P44V64_4K 1517d9a662eSMichael Roth #define MIN_PAGE_SHIFT 12U 1527d9a662eSMichael Roth #define ptes_per_page(page_size) ((page_size) / 16) 1537d9a662eSMichael Roth 1547d9a662eSMichael Roth #elif defined(__riscv) 1557d9a662eSMichael Roth 1567d9a662eSMichael Roth #if __riscv_xlen == 32 1577d9a662eSMichael Roth #error "RISC-V 32-bit kvm selftests not supported" 1587d9a662eSMichael Roth #endif 1597d9a662eSMichael Roth 1607d9a662eSMichael Roth #define VM_MODE_DEFAULT VM_MODE_P40V48_4K 1617d9a662eSMichael Roth #define MIN_PAGE_SHIFT 12U 1627d9a662eSMichael Roth #define ptes_per_page(page_size) ((page_size) / 8) 1637d9a662eSMichael Roth 1647d9a662eSMichael Roth #endif 1657d9a662eSMichael Roth 1667d9a662eSMichael Roth #define MIN_PAGE_SIZE (1U << MIN_PAGE_SHIFT) 1677d9a662eSMichael Roth #define PTES_PER_MIN_PAGE ptes_per_page(MIN_PAGE_SIZE) 1687d9a662eSMichael Roth 1697d9a662eSMichael Roth struct vm_guest_mode_params { 1707d9a662eSMichael Roth unsigned int pa_bits; 1717d9a662eSMichael Roth unsigned int va_bits; 1727d9a662eSMichael Roth unsigned int page_size; 1737d9a662eSMichael Roth unsigned int page_shift; 1747d9a662eSMichael Roth }; 1757d9a662eSMichael Roth extern const struct vm_guest_mode_params vm_guest_mode_params[]; 1767d9a662eSMichael Roth 1777d9a662eSMichael Roth int open_path_or_exit(const char *path, int flags); 1787d9a662eSMichael Roth int open_kvm_dev_path_or_exit(void); 1794d2bd143SDavid Matlack 1804d2bd143SDavid Matlack bool get_kvm_intel_param_bool(const char *param); 1814d2bd143SDavid Matlack bool get_kvm_amd_param_bool(const char *param); 1824d2bd143SDavid Matlack 183d8ba3f14SSean Christopherson unsigned int kvm_check_cap(long cap); 18471ab5a6fSSean Christopherson 1853ea9b809SSean Christopherson static inline bool kvm_has_cap(long cap) 1863ea9b809SSean Christopherson { 1873ea9b809SSean Christopherson return kvm_check_cap(cap); 1883ea9b809SSean Christopherson } 1893ea9b809SSean Christopherson 19071ab5a6fSSean Christopherson #define __KVM_SYSCALL_ERROR(_name, _ret) \ 19171ab5a6fSSean Christopherson "%s failed, rc: %i errno: %i (%s)", (_name), (_ret), errno, strerror(errno) 19271ab5a6fSSean Christopherson 19371ab5a6fSSean Christopherson #define __KVM_IOCTL_ERROR(_name, _ret) __KVM_SYSCALL_ERROR(_name, _ret) 19471ab5a6fSSean Christopherson #define KVM_IOCTL_ERROR(_ioctl, _ret) __KVM_IOCTL_ERROR(#_ioctl, _ret) 19571ab5a6fSSean Christopherson 196fcba483eSSean Christopherson #define kvm_do_ioctl(fd, cmd, arg) \ 197fcba483eSSean Christopherson ({ \ 198fcba483eSSean Christopherson static_assert(!_IOC_SIZE(cmd) || sizeof(*arg) == _IOC_SIZE(cmd), ""); \ 199fcba483eSSean Christopherson ioctl(fd, cmd, arg); \ 200fcba483eSSean Christopherson }) 201fcba483eSSean Christopherson 2022de1b7b1SSean Christopherson #define __kvm_ioctl(kvm_fd, cmd, arg) \ 203fcba483eSSean Christopherson kvm_do_ioctl(kvm_fd, cmd, arg) 2042de1b7b1SSean Christopherson 2052de1b7b1SSean Christopherson 206fcba483eSSean Christopherson #define _kvm_ioctl(kvm_fd, cmd, name, arg) \ 207fcba483eSSean Christopherson ({ \ 208fcba483eSSean Christopherson int ret = __kvm_ioctl(kvm_fd, cmd, arg); \ 209fcba483eSSean Christopherson \ 210fcba483eSSean Christopherson TEST_ASSERT(!ret, __KVM_IOCTL_ERROR(name, ret)); \ 211fcba483eSSean Christopherson }) 2122de1b7b1SSean Christopherson 2132de1b7b1SSean Christopherson #define kvm_ioctl(kvm_fd, cmd, arg) \ 2142de1b7b1SSean Christopherson _kvm_ioctl(kvm_fd, cmd, #cmd, arg) 21571ab5a6fSSean Christopherson 216ad125f30SSean Christopherson static __always_inline void static_assert_is_vm(struct kvm_vm *vm) { } 217ad125f30SSean Christopherson 218fcba483eSSean Christopherson #define __vm_ioctl(vm, cmd, arg) \ 219fcba483eSSean Christopherson ({ \ 220ad125f30SSean Christopherson static_assert_is_vm(vm); \ 221fcba483eSSean Christopherson kvm_do_ioctl((vm)->fd, cmd, arg); \ 222fcba483eSSean Christopherson }) 22371ab5a6fSSean Christopherson 224fcba483eSSean Christopherson #define _vm_ioctl(vm, cmd, name, arg) \ 225fcba483eSSean Christopherson ({ \ 226fcba483eSSean Christopherson int ret = __vm_ioctl(vm, cmd, arg); \ 227fcba483eSSean Christopherson \ 228fcba483eSSean Christopherson TEST_ASSERT(!ret, __KVM_IOCTL_ERROR(name, ret)); \ 229fcba483eSSean Christopherson }) 230fcba483eSSean Christopherson 231fcba483eSSean Christopherson #define vm_ioctl(vm, cmd, arg) \ 232fcba483eSSean Christopherson _vm_ioctl(vm, cmd, #cmd, arg) 233fcba483eSSean Christopherson 234ad125f30SSean Christopherson 235ad125f30SSean Christopherson static __always_inline void static_assert_is_vcpu(struct kvm_vcpu *vcpu) { } 236ad125f30SSean Christopherson 237fcba483eSSean Christopherson #define __vcpu_ioctl(vcpu, cmd, arg) \ 238fcba483eSSean Christopherson ({ \ 239ad125f30SSean Christopherson static_assert_is_vcpu(vcpu); \ 240fcba483eSSean Christopherson kvm_do_ioctl((vcpu)->fd, cmd, arg); \ 241fcba483eSSean Christopherson }) 242fcba483eSSean Christopherson 243fcba483eSSean Christopherson #define _vcpu_ioctl(vcpu, cmd, name, arg) \ 244fcba483eSSean Christopherson ({ \ 245fcba483eSSean Christopherson int ret = __vcpu_ioctl(vcpu, cmd, arg); \ 246fcba483eSSean Christopherson \ 247fcba483eSSean Christopherson TEST_ASSERT(!ret, __KVM_IOCTL_ERROR(name, ret)); \ 248fcba483eSSean Christopherson }) 249fcba483eSSean Christopherson 250768e9a61SSean Christopherson #define vcpu_ioctl(vcpu, cmd, arg) \ 251768e9a61SSean Christopherson _vcpu_ioctl(vcpu, cmd, #cmd, arg) 25271ab5a6fSSean Christopherson 25310825b55SSean Christopherson /* 25410825b55SSean Christopherson * Looks up and returns the value corresponding to the capability 25510825b55SSean Christopherson * (KVM_CAP_*) given by cap. 25610825b55SSean Christopherson */ 25710825b55SSean Christopherson static inline int vm_check_cap(struct kvm_vm *vm, long cap) 25810825b55SSean Christopherson { 25910825b55SSean Christopherson int ret = __vm_ioctl(vm, KVM_CHECK_EXTENSION, (void *)cap); 26010825b55SSean Christopherson 26110825b55SSean Christopherson TEST_ASSERT(ret >= 0, KVM_IOCTL_ERROR(KVM_CHECK_EXTENSION, ret)); 26210825b55SSean Christopherson return ret; 26310825b55SSean Christopherson } 26410825b55SSean Christopherson 265a12c86c4SSean Christopherson static inline int __vm_enable_cap(struct kvm_vm *vm, uint32_t cap, uint64_t arg0) 266ac712209SSean Christopherson { 267a12c86c4SSean Christopherson struct kvm_enable_cap enable_cap = { .cap = cap, .args = { arg0 } }; 268a12c86c4SSean Christopherson 269a12c86c4SSean Christopherson return __vm_ioctl(vm, KVM_ENABLE_CAP, &enable_cap); 270ac712209SSean Christopherson } 271a12c86c4SSean Christopherson static inline void vm_enable_cap(struct kvm_vm *vm, uint32_t cap, uint64_t arg0) 27210825b55SSean Christopherson { 273a12c86c4SSean Christopherson struct kvm_enable_cap enable_cap = { .cap = cap, .args = { arg0 } }; 274a12c86c4SSean Christopherson 275a12c86c4SSean Christopherson vm_ioctl(vm, KVM_ENABLE_CAP, &enable_cap); 27610825b55SSean Christopherson } 27710825b55SSean Christopherson 2787d9a662eSMichael Roth void vm_enable_dirty_ring(struct kvm_vm *vm, uint32_t ring_size); 2797d9a662eSMichael Roth const char *vm_guest_mode_string(uint32_t i); 2807d9a662eSMichael Roth 2817d9a662eSMichael Roth void kvm_vm_free(struct kvm_vm *vmp); 282ccc82ba6SSean Christopherson void kvm_vm_restart(struct kvm_vm *vmp); 2837d9a662eSMichael Roth void kvm_vm_release(struct kvm_vm *vmp); 2847d9a662eSMichael Roth int kvm_memcmp_hva_gva(void *hva, struct kvm_vm *vm, const vm_vaddr_t gva, 2857d9a662eSMichael Roth size_t len); 2867d9a662eSMichael Roth void kvm_vm_elf_load(struct kvm_vm *vm, const char *filename); 287a4187c9bSSean Christopherson int kvm_memfd_alloc(size_t size, bool hugepages); 2887d9a662eSMichael Roth 2897d9a662eSMichael Roth void vm_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent); 2907d9a662eSMichael Roth 29110825b55SSean Christopherson static inline void kvm_vm_get_dirty_log(struct kvm_vm *vm, int slot, void *log) 29210825b55SSean Christopherson { 29310825b55SSean Christopherson struct kvm_dirty_log args = { .dirty_bitmap = log, .slot = slot }; 29410825b55SSean Christopherson 29510825b55SSean Christopherson vm_ioctl(vm, KVM_GET_DIRTY_LOG, &args); 29610825b55SSean Christopherson } 29710825b55SSean Christopherson 29810825b55SSean Christopherson static inline void kvm_vm_clear_dirty_log(struct kvm_vm *vm, int slot, void *log, 29910825b55SSean Christopherson uint64_t first_page, uint32_t num_pages) 30010825b55SSean Christopherson { 30110825b55SSean Christopherson struct kvm_clear_dirty_log args = { 30210825b55SSean Christopherson .dirty_bitmap = log, 30310825b55SSean Christopherson .slot = slot, 30410825b55SSean Christopherson .first_page = first_page, 30510825b55SSean Christopherson .num_pages = num_pages 30610825b55SSean Christopherson }; 30710825b55SSean Christopherson 30810825b55SSean Christopherson vm_ioctl(vm, KVM_CLEAR_DIRTY_LOG, &args); 30910825b55SSean Christopherson } 31010825b55SSean Christopherson 31110825b55SSean Christopherson static inline uint32_t kvm_vm_reset_dirty_ring(struct kvm_vm *vm) 31210825b55SSean Christopherson { 31310825b55SSean Christopherson return __vm_ioctl(vm, KVM_RESET_DIRTY_RINGS, NULL); 31410825b55SSean Christopherson } 31510825b55SSean Christopherson 31610825b55SSean Christopherson static inline int vm_get_stats_fd(struct kvm_vm *vm) 31710825b55SSean Christopherson { 31810825b55SSean Christopherson int fd = __vm_ioctl(vm, KVM_GET_STATS_FD, NULL); 31910825b55SSean Christopherson 32010825b55SSean Christopherson TEST_ASSERT(fd >= 0, KVM_IOCTL_ERROR(KVM_GET_STATS_FD, fd)); 32110825b55SSean Christopherson return fd; 32210825b55SSean Christopherson } 32310825b55SSean Christopherson 32432faa064SBen Gardon static inline void read_stats_header(int stats_fd, struct kvm_stats_header *header) 32532faa064SBen Gardon { 32632faa064SBen Gardon ssize_t ret; 32732faa064SBen Gardon 32832faa064SBen Gardon ret = read(stats_fd, header, sizeof(*header)); 32932faa064SBen Gardon TEST_ASSERT(ret == sizeof(*header), "Read stats header"); 33032faa064SBen Gardon } 33132faa064SBen Gardon 3324d0a0594SBen Gardon struct kvm_stats_desc *read_stats_descriptors(int stats_fd, 3334d0a0594SBen Gardon struct kvm_stats_header *header); 3344d0a0594SBen Gardon 3354d0a0594SBen Gardon static inline ssize_t get_stats_descriptor_size(struct kvm_stats_header *header) 3364d0a0594SBen Gardon { 3374d0a0594SBen Gardon /* 3384d0a0594SBen Gardon * The base size of the descriptor is defined by KVM's ABI, but the 3394d0a0594SBen Gardon * size of the name field is variable, as far as KVM's ABI is 3404d0a0594SBen Gardon * concerned. For a given instance of KVM, the name field is the same 3414d0a0594SBen Gardon * size for all stats and is provided in the overall stats header. 3424d0a0594SBen Gardon */ 3434d0a0594SBen Gardon return sizeof(struct kvm_stats_desc) + header->name_size; 3444d0a0594SBen Gardon } 3454d0a0594SBen Gardon 3464d0a0594SBen Gardon static inline struct kvm_stats_desc *get_stats_descriptor(struct kvm_stats_desc *stats, 3474d0a0594SBen Gardon int index, 3484d0a0594SBen Gardon struct kvm_stats_header *header) 3494d0a0594SBen Gardon { 3504d0a0594SBen Gardon /* 3514d0a0594SBen Gardon * Note, size_desc includes the size of the name field, which is 3524d0a0594SBen Gardon * variable. i.e. this is NOT equivalent to &stats_desc[i]. 3534d0a0594SBen Gardon */ 3544d0a0594SBen Gardon return (void *)stats + index * get_stats_descriptor_size(header); 3554d0a0594SBen Gardon } 3564d0a0594SBen Gardon 357ed6b53ecSBen Gardon void read_stat_data(int stats_fd, struct kvm_stats_header *header, 358ed6b53ecSBen Gardon struct kvm_stats_desc *desc, uint64_t *data, 359ed6b53ecSBen Gardon size_t max_elements); 360ed6b53ecSBen Gardon 3618448ec59SBen Gardon void __vm_get_stat(struct kvm_vm *vm, const char *stat_name, uint64_t *data, 3628448ec59SBen Gardon size_t max_elements); 3638448ec59SBen Gardon 3648448ec59SBen Gardon static inline uint64_t vm_get_stat(struct kvm_vm *vm, const char *stat_name) 3658448ec59SBen Gardon { 3668448ec59SBen Gardon uint64_t data; 3678448ec59SBen Gardon 3688448ec59SBen Gardon __vm_get_stat(vm, stat_name, &data, 1); 3698448ec59SBen Gardon return data; 3708448ec59SBen Gardon } 3718448ec59SBen Gardon 3727d9a662eSMichael Roth void vm_create_irqchip(struct kvm_vm *vm); 3737d9a662eSMichael Roth 3743d7d6043SSean Christopherson void vm_set_user_memory_region(struct kvm_vm *vm, uint32_t slot, uint32_t flags, 3753d7d6043SSean Christopherson uint64_t gpa, uint64_t size, void *hva); 3763d7d6043SSean Christopherson int __vm_set_user_memory_region(struct kvm_vm *vm, uint32_t slot, uint32_t flags, 3773d7d6043SSean Christopherson uint64_t gpa, uint64_t size, void *hva); 3787d9a662eSMichael Roth void vm_userspace_mem_region_add(struct kvm_vm *vm, 3797d9a662eSMichael Roth enum vm_mem_backing_src_type src_type, 3807d9a662eSMichael Roth uint64_t guest_paddr, uint32_t slot, uint64_t npages, 3817d9a662eSMichael Roth uint32_t flags); 3827d9a662eSMichael Roth 3837d9a662eSMichael Roth void vm_mem_region_set_flags(struct kvm_vm *vm, uint32_t slot, uint32_t flags); 3847d9a662eSMichael Roth void vm_mem_region_move(struct kvm_vm *vm, uint32_t slot, uint64_t new_gpa); 3857d9a662eSMichael Roth void vm_mem_region_delete(struct kvm_vm *vm, uint32_t slot); 386768e9a61SSean Christopherson struct kvm_vcpu *__vm_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id); 3877d9a662eSMichael Roth vm_vaddr_t vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min); 3887d9a662eSMichael Roth vm_vaddr_t vm_vaddr_alloc_pages(struct kvm_vm *vm, int nr_pages); 3897d9a662eSMichael Roth vm_vaddr_t vm_vaddr_alloc_page(struct kvm_vm *vm); 3907d9a662eSMichael Roth 3917d9a662eSMichael Roth void virt_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, 3927d9a662eSMichael Roth unsigned int npages); 3937d9a662eSMichael Roth void *addr_gpa2hva(struct kvm_vm *vm, vm_paddr_t gpa); 3947d9a662eSMichael Roth void *addr_gva2hva(struct kvm_vm *vm, vm_vaddr_t gva); 3957d9a662eSMichael Roth vm_paddr_t addr_hva2gpa(struct kvm_vm *vm, void *hva); 3967d9a662eSMichael Roth void *addr_gpa2alias(struct kvm_vm *vm, vm_paddr_t gpa); 3977d9a662eSMichael Roth 398768e9a61SSean Christopherson void vcpu_run(struct kvm_vcpu *vcpu); 399768e9a61SSean Christopherson int _vcpu_run(struct kvm_vcpu *vcpu); 40038d4a385SSean Christopherson 401768e9a61SSean Christopherson static inline int __vcpu_run(struct kvm_vcpu *vcpu) 40238d4a385SSean Christopherson { 403768e9a61SSean Christopherson return __vcpu_ioctl(vcpu, KVM_RUN, NULL); 40438d4a385SSean Christopherson } 40538d4a385SSean Christopherson 406768e9a61SSean Christopherson void vcpu_run_complete_io(struct kvm_vcpu *vcpu); 407768e9a61SSean Christopherson struct kvm_reg_list *vcpu_get_reg_list(struct kvm_vcpu *vcpu); 408ffb7c77fSSean Christopherson 409768e9a61SSean Christopherson static inline void vcpu_enable_cap(struct kvm_vcpu *vcpu, uint32_t cap, 410768e9a61SSean Christopherson uint64_t arg0) 411ffb7c77fSSean Christopherson { 412a12c86c4SSean Christopherson struct kvm_enable_cap enable_cap = { .cap = cap, .args = { arg0 } }; 413a12c86c4SSean Christopherson 414768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_ENABLE_CAP, &enable_cap); 415ffb7c77fSSean Christopherson } 416ffb7c77fSSean Christopherson 417768e9a61SSean Christopherson static inline void vcpu_guest_debug_set(struct kvm_vcpu *vcpu, 418ffb7c77fSSean Christopherson struct kvm_guest_debug *debug) 419ffb7c77fSSean Christopherson { 420768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_SET_GUEST_DEBUG, debug); 421ffb7c77fSSean Christopherson } 422ffb7c77fSSean Christopherson 423768e9a61SSean Christopherson static inline void vcpu_mp_state_get(struct kvm_vcpu *vcpu, 424877bd399SSean Christopherson struct kvm_mp_state *mp_state) 425877bd399SSean Christopherson { 426768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_GET_MP_STATE, mp_state); 427877bd399SSean Christopherson } 428768e9a61SSean Christopherson static inline void vcpu_mp_state_set(struct kvm_vcpu *vcpu, 429ffb7c77fSSean Christopherson struct kvm_mp_state *mp_state) 430ffb7c77fSSean Christopherson { 431768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_SET_MP_STATE, mp_state); 432ffb7c77fSSean Christopherson } 433ffb7c77fSSean Christopherson 434768e9a61SSean Christopherson static inline void vcpu_regs_get(struct kvm_vcpu *vcpu, struct kvm_regs *regs) 435ffb7c77fSSean Christopherson { 436768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_GET_REGS, regs); 437ffb7c77fSSean Christopherson } 438ffb7c77fSSean Christopherson 439768e9a61SSean Christopherson static inline void vcpu_regs_set(struct kvm_vcpu *vcpu, struct kvm_regs *regs) 440ffb7c77fSSean Christopherson { 441768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_SET_REGS, regs); 442ffb7c77fSSean Christopherson } 443768e9a61SSean Christopherson static inline void vcpu_sregs_get(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) 444ffb7c77fSSean Christopherson { 445768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_GET_SREGS, sregs); 446ffb7c77fSSean Christopherson 447ffb7c77fSSean Christopherson } 448768e9a61SSean Christopherson static inline void vcpu_sregs_set(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) 449ffb7c77fSSean Christopherson { 450768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_SET_SREGS, sregs); 451ffb7c77fSSean Christopherson } 452768e9a61SSean Christopherson static inline int _vcpu_sregs_set(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) 453ffb7c77fSSean Christopherson { 454768e9a61SSean Christopherson return __vcpu_ioctl(vcpu, KVM_SET_SREGS, sregs); 455ffb7c77fSSean Christopherson } 456768e9a61SSean Christopherson static inline void vcpu_fpu_get(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) 457ffb7c77fSSean Christopherson { 458768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_GET_FPU, fpu); 459ffb7c77fSSean Christopherson } 460768e9a61SSean Christopherson static inline void vcpu_fpu_set(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) 461ffb7c77fSSean Christopherson { 462768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_SET_FPU, fpu); 463ffb7c77fSSean Christopherson } 464bfff0f60SSean Christopherson 465768e9a61SSean Christopherson static inline int __vcpu_get_reg(struct kvm_vcpu *vcpu, uint64_t id, void *addr) 466ffb7c77fSSean Christopherson { 467768e9a61SSean Christopherson struct kvm_one_reg reg = { .id = id, .addr = (uint64_t)addr }; 468bfff0f60SSean Christopherson 469768e9a61SSean Christopherson return __vcpu_ioctl(vcpu, KVM_GET_ONE_REG, ®); 470bfff0f60SSean Christopherson } 471768e9a61SSean Christopherson static inline int __vcpu_set_reg(struct kvm_vcpu *vcpu, uint64_t id, uint64_t val) 472bfff0f60SSean Christopherson { 473768e9a61SSean Christopherson struct kvm_one_reg reg = { .id = id, .addr = (uint64_t)&val }; 474bfff0f60SSean Christopherson 475768e9a61SSean Christopherson return __vcpu_ioctl(vcpu, KVM_SET_ONE_REG, ®); 476bfff0f60SSean Christopherson } 477768e9a61SSean Christopherson static inline void vcpu_get_reg(struct kvm_vcpu *vcpu, uint64_t id, void *addr) 478bfff0f60SSean Christopherson { 479768e9a61SSean Christopherson struct kvm_one_reg reg = { .id = id, .addr = (uint64_t)addr }; 480bfff0f60SSean Christopherson 481768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_GET_ONE_REG, ®); 482ffb7c77fSSean Christopherson } 483768e9a61SSean Christopherson static inline void vcpu_set_reg(struct kvm_vcpu *vcpu, uint64_t id, uint64_t val) 484ffb7c77fSSean Christopherson { 485768e9a61SSean Christopherson struct kvm_one_reg reg = { .id = id, .addr = (uint64_t)&val }; 486bfff0f60SSean Christopherson 487768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_SET_ONE_REG, ®); 488ffb7c77fSSean Christopherson } 489bfff0f60SSean Christopherson 490ffb7c77fSSean Christopherson #ifdef __KVM_HAVE_VCPU_EVENTS 491768e9a61SSean Christopherson static inline void vcpu_events_get(struct kvm_vcpu *vcpu, 492ffb7c77fSSean Christopherson struct kvm_vcpu_events *events) 493ffb7c77fSSean Christopherson { 494768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_GET_VCPU_EVENTS, events); 495ffb7c77fSSean Christopherson } 496768e9a61SSean Christopherson static inline void vcpu_events_set(struct kvm_vcpu *vcpu, 497ffb7c77fSSean Christopherson struct kvm_vcpu_events *events) 498ffb7c77fSSean Christopherson { 499768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_SET_VCPU_EVENTS, events); 500ffb7c77fSSean Christopherson } 501ffb7c77fSSean Christopherson #endif 502ffb7c77fSSean Christopherson #ifdef __x86_64__ 503768e9a61SSean Christopherson static inline void vcpu_nested_state_get(struct kvm_vcpu *vcpu, 504ffb7c77fSSean Christopherson struct kvm_nested_state *state) 505ffb7c77fSSean Christopherson { 506768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_GET_NESTED_STATE, state); 507ffb7c77fSSean Christopherson } 508768e9a61SSean Christopherson static inline int __vcpu_nested_state_set(struct kvm_vcpu *vcpu, 509ffb7c77fSSean Christopherson struct kvm_nested_state *state) 510ffb7c77fSSean Christopherson { 511768e9a61SSean Christopherson return __vcpu_ioctl(vcpu, KVM_SET_NESTED_STATE, state); 512ffb7c77fSSean Christopherson } 513ffb7c77fSSean Christopherson 514768e9a61SSean Christopherson static inline void vcpu_nested_state_set(struct kvm_vcpu *vcpu, 515ffb7c77fSSean Christopherson struct kvm_nested_state *state) 516ffb7c77fSSean Christopherson { 517768e9a61SSean Christopherson vcpu_ioctl(vcpu, KVM_SET_NESTED_STATE, state); 518ffb7c77fSSean Christopherson } 519ffb7c77fSSean Christopherson #endif 520768e9a61SSean Christopherson static inline int vcpu_get_stats_fd(struct kvm_vcpu *vcpu) 521ffb7c77fSSean Christopherson { 522768e9a61SSean Christopherson int fd = __vcpu_ioctl(vcpu, KVM_GET_STATS_FD, NULL); 523ffb7c77fSSean Christopherson 524ffb7c77fSSean Christopherson TEST_ASSERT(fd >= 0, KVM_IOCTL_ERROR(KVM_GET_STATS_FD, fd)); 525ffb7c77fSSean Christopherson return fd; 526ffb7c77fSSean Christopherson } 527ffb7c77fSSean Christopherson 52840918184SSean Christopherson int __kvm_has_device_attr(int dev_fd, uint32_t group, uint64_t attr); 52940918184SSean Christopherson 53040918184SSean Christopherson static inline void kvm_has_device_attr(int dev_fd, uint32_t group, uint64_t attr) 53140918184SSean Christopherson { 53240918184SSean Christopherson int ret = __kvm_has_device_attr(dev_fd, group, attr); 53340918184SSean Christopherson 53440918184SSean Christopherson TEST_ASSERT(!ret, "KVM_HAS_DEVICE_ATTR failed, rc: %i errno: %i", ret, errno); 53540918184SSean Christopherson } 53640918184SSean Christopherson 53740918184SSean Christopherson int __kvm_device_attr_get(int dev_fd, uint32_t group, uint64_t attr, void *val); 53840918184SSean Christopherson 53940918184SSean Christopherson static inline void kvm_device_attr_get(int dev_fd, uint32_t group, 54040918184SSean Christopherson uint64_t attr, void *val) 54140918184SSean Christopherson { 54240918184SSean Christopherson int ret = __kvm_device_attr_get(dev_fd, group, attr, val); 54340918184SSean Christopherson 54440918184SSean Christopherson TEST_ASSERT(!ret, KVM_IOCTL_ERROR(KVM_GET_DEVICE_ATTR, ret)); 54540918184SSean Christopherson } 54640918184SSean Christopherson 54740918184SSean Christopherson int __kvm_device_attr_set(int dev_fd, uint32_t group, uint64_t attr, void *val); 54840918184SSean Christopherson 54940918184SSean Christopherson static inline void kvm_device_attr_set(int dev_fd, uint32_t group, 55040918184SSean Christopherson uint64_t attr, void *val) 55140918184SSean Christopherson { 55240918184SSean Christopherson int ret = __kvm_device_attr_set(dev_fd, group, attr, val); 55340918184SSean Christopherson 55440918184SSean Christopherson TEST_ASSERT(!ret, KVM_IOCTL_ERROR(KVM_SET_DEVICE_ATTR, ret)); 55540918184SSean Christopherson } 55640918184SSean Christopherson 557768e9a61SSean Christopherson static inline int __vcpu_has_device_attr(struct kvm_vcpu *vcpu, uint32_t group, 558768e9a61SSean Christopherson uint64_t attr) 55940918184SSean Christopherson { 560768e9a61SSean Christopherson return __kvm_has_device_attr(vcpu->fd, group, attr); 56140918184SSean Christopherson } 56240918184SSean Christopherson 563768e9a61SSean Christopherson static inline void vcpu_has_device_attr(struct kvm_vcpu *vcpu, uint32_t group, 564768e9a61SSean Christopherson uint64_t attr) 565768e9a61SSean Christopherson { 566768e9a61SSean Christopherson kvm_has_device_attr(vcpu->fd, group, attr); 567768e9a61SSean Christopherson } 568768e9a61SSean Christopherson 569768e9a61SSean Christopherson static inline int __vcpu_device_attr_get(struct kvm_vcpu *vcpu, uint32_t group, 570768e9a61SSean Christopherson uint64_t attr, void *val) 571768e9a61SSean Christopherson { 572768e9a61SSean Christopherson return __kvm_device_attr_get(vcpu->fd, group, attr, val); 573768e9a61SSean Christopherson } 574768e9a61SSean Christopherson 575768e9a61SSean Christopherson static inline void vcpu_device_attr_get(struct kvm_vcpu *vcpu, uint32_t group, 576768e9a61SSean Christopherson uint64_t attr, void *val) 577768e9a61SSean Christopherson { 578768e9a61SSean Christopherson kvm_device_attr_get(vcpu->fd, group, attr, val); 579768e9a61SSean Christopherson } 580768e9a61SSean Christopherson 581768e9a61SSean Christopherson static inline int __vcpu_device_attr_set(struct kvm_vcpu *vcpu, uint32_t group, 582768e9a61SSean Christopherson uint64_t attr, void *val) 583768e9a61SSean Christopherson { 584768e9a61SSean Christopherson return __kvm_device_attr_set(vcpu->fd, group, attr, val); 585768e9a61SSean Christopherson } 586768e9a61SSean Christopherson 587768e9a61SSean Christopherson static inline void vcpu_device_attr_set(struct kvm_vcpu *vcpu, uint32_t group, 588768e9a61SSean Christopherson uint64_t attr, void *val) 589768e9a61SSean Christopherson { 590768e9a61SSean Christopherson kvm_device_attr_set(vcpu->fd, group, attr, val); 591768e9a61SSean Christopherson } 592768e9a61SSean Christopherson 59340918184SSean Christopherson int __kvm_test_create_device(struct kvm_vm *vm, uint64_t type); 59440918184SSean Christopherson int __kvm_create_device(struct kvm_vm *vm, uint64_t type); 59540918184SSean Christopherson 59640918184SSean Christopherson static inline int kvm_create_device(struct kvm_vm *vm, uint64_t type) 59740918184SSean Christopherson { 59840918184SSean Christopherson int fd = __kvm_create_device(vm, type); 59940918184SSean Christopherson 60040918184SSean Christopherson TEST_ASSERT(fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_DEVICE, fd)); 60140918184SSean Christopherson return fd; 60240918184SSean Christopherson } 60340918184SSean Christopherson 604768e9a61SSean Christopherson void *vcpu_map_dirty_ring(struct kvm_vcpu *vcpu); 6057d9a662eSMichael Roth 6067d9a662eSMichael Roth /* 6077d9a662eSMichael Roth * VM VCPU Args Set 6087d9a662eSMichael Roth * 6097d9a662eSMichael Roth * Input Args: 6107d9a662eSMichael Roth * vm - Virtual Machine 6117d9a662eSMichael Roth * num - number of arguments 6127d9a662eSMichael Roth * ... - arguments, each of type uint64_t 6137d9a662eSMichael Roth * 6147d9a662eSMichael Roth * Output Args: None 6157d9a662eSMichael Roth * 6167d9a662eSMichael Roth * Return: None 6177d9a662eSMichael Roth * 618768e9a61SSean Christopherson * Sets the first @num input parameters for the function at @vcpu's entry point, 619768e9a61SSean Christopherson * per the C calling convention of the architecture, to the values given as 620768e9a61SSean Christopherson * variable args. Each of the variable args is expected to be of type uint64_t. 621768e9a61SSean Christopherson * The maximum @num can be is specific to the architecture. 6227d9a662eSMichael Roth */ 623768e9a61SSean Christopherson void vcpu_args_set(struct kvm_vcpu *vcpu, unsigned int num, ...); 6247d9a662eSMichael Roth 6257d9a662eSMichael Roth void kvm_irq_line(struct kvm_vm *vm, uint32_t irq, int level); 6267d9a662eSMichael Roth int _kvm_irq_line(struct kvm_vm *vm, uint32_t irq, int level); 6277d9a662eSMichael Roth 6287d9a662eSMichael Roth #define KVM_MAX_IRQ_ROUTES 4096 6297d9a662eSMichael Roth 6307d9a662eSMichael Roth struct kvm_irq_routing *kvm_gsi_routing_create(void); 6317d9a662eSMichael Roth void kvm_gsi_routing_irqchip_add(struct kvm_irq_routing *routing, 6327d9a662eSMichael Roth uint32_t gsi, uint32_t pin); 6337d9a662eSMichael Roth int _kvm_gsi_routing_write(struct kvm_vm *vm, struct kvm_irq_routing *routing); 6347d9a662eSMichael Roth void kvm_gsi_routing_write(struct kvm_vm *vm, struct kvm_irq_routing *routing); 6357d9a662eSMichael Roth 6367d9a662eSMichael Roth const char *exit_reason_str(unsigned int exit_reason); 6377d9a662eSMichael Roth 6387d9a662eSMichael Roth vm_paddr_t vm_phy_page_alloc(struct kvm_vm *vm, vm_paddr_t paddr_min, 6397d9a662eSMichael Roth uint32_t memslot); 6407d9a662eSMichael Roth vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num, 6417d9a662eSMichael Roth vm_paddr_t paddr_min, uint32_t memslot); 6427d9a662eSMichael Roth vm_paddr_t vm_alloc_page_table(struct kvm_vm *vm); 6437d9a662eSMichael Roth 6443f44e7fdSSean Christopherson /* 6453f44e7fdSSean Christopherson * ____vm_create() does KVM_CREATE_VM and little else. __vm_create() also 6463f44e7fdSSean Christopherson * loads the test binary into guest memory and creates an IRQ chip (x86 only). 6476e1d13bfSSean Christopherson * __vm_create() does NOT create vCPUs, @nr_runnable_vcpus is used purely to 6486e1d13bfSSean Christopherson * calculate the amount of memory needed for per-vCPU data, e.g. stacks. 6493f44e7fdSSean Christopherson */ 6503f44e7fdSSean Christopherson struct kvm_vm *____vm_create(enum vm_guest_mode mode, uint64_t nr_pages); 6516e1d13bfSSean Christopherson struct kvm_vm *__vm_create(enum vm_guest_mode mode, uint32_t nr_runnable_vcpus, 6526e1d13bfSSean Christopherson uint64_t nr_extra_pages); 6533f44e7fdSSean Christopherson 65495fb0460SSean Christopherson static inline struct kvm_vm *vm_create_barebones(void) 65595fb0460SSean Christopherson { 6563f44e7fdSSean Christopherson return ____vm_create(VM_MODE_DEFAULT, 0); 6573f44e7fdSSean Christopherson } 6583f44e7fdSSean Christopherson 6596e1d13bfSSean Christopherson static inline struct kvm_vm *vm_create(uint32_t nr_runnable_vcpus) 6603f44e7fdSSean Christopherson { 6616e1d13bfSSean Christopherson return __vm_create(VM_MODE_DEFAULT, nr_runnable_vcpus, 0); 66295fb0460SSean Christopherson } 66395fb0460SSean Christopherson 6640ffc70eaSSean Christopherson struct kvm_vm *__vm_create_with_vcpus(enum vm_guest_mode mode, uint32_t nr_vcpus, 665acaf50adSSean Christopherson uint64_t extra_mem_pages, 6663222d026SSean Christopherson void *guest_code, struct kvm_vcpu *vcpus[]); 6670ffc70eaSSean Christopherson 6680ffc70eaSSean Christopherson static inline struct kvm_vm *vm_create_with_vcpus(uint32_t nr_vcpus, 6690ffc70eaSSean Christopherson void *guest_code, 6700ffc70eaSSean Christopherson struct kvm_vcpu *vcpus[]) 6710ffc70eaSSean Christopherson { 672acaf50adSSean Christopherson return __vm_create_with_vcpus(VM_MODE_DEFAULT, nr_vcpus, 0, 6735114c3e2SSean Christopherson guest_code, vcpus); 6740ffc70eaSSean Christopherson } 6757d9a662eSMichael Roth 6767d9a662eSMichael Roth /* 677f17686aaSSean Christopherson * Create a VM with a single vCPU with reasonable defaults and @extra_mem_pages 678f17686aaSSean Christopherson * additional pages of guest memory. Returns the VM and vCPU (via out param). 679f17686aaSSean Christopherson */ 6800cc64b08SSean Christopherson struct kvm_vm *__vm_create_with_one_vcpu(struct kvm_vcpu **vcpu, 681f17686aaSSean Christopherson uint64_t extra_mem_pages, 682f17686aaSSean Christopherson void *guest_code); 683f17686aaSSean Christopherson 6840cc64b08SSean Christopherson static inline struct kvm_vm *vm_create_with_one_vcpu(struct kvm_vcpu **vcpu, 685f17686aaSSean Christopherson void *guest_code) 686f17686aaSSean Christopherson { 687f17686aaSSean Christopherson return __vm_create_with_one_vcpu(vcpu, 0, guest_code); 688f17686aaSSean Christopherson } 689f17686aaSSean Christopherson 6900cc64b08SSean Christopherson struct kvm_vcpu *vm_recreate_with_one_vcpu(struct kvm_vm *vm); 691f17686aaSSean Christopherson 6927d9a662eSMichael Roth unsigned long vm_compute_max_gfn(struct kvm_vm *vm); 6937d9a662eSMichael Roth unsigned int vm_calc_num_guest_pages(enum vm_guest_mode mode, size_t size); 6947d9a662eSMichael Roth unsigned int vm_num_host_pages(enum vm_guest_mode mode, unsigned int num_guest_pages); 6957d9a662eSMichael Roth unsigned int vm_num_guest_pages(enum vm_guest_mode mode, unsigned int num_host_pages); 6967d9a662eSMichael Roth static inline unsigned int 6977d9a662eSMichael Roth vm_adjust_num_guest_pages(enum vm_guest_mode mode, unsigned int num_guest_pages) 6987d9a662eSMichael Roth { 6997d9a662eSMichael Roth unsigned int n; 7007d9a662eSMichael Roth n = vm_num_guest_pages(mode, vm_num_host_pages(mode, num_guest_pages)); 7017d9a662eSMichael Roth #ifdef __s390x__ 7027d9a662eSMichael Roth /* s390 requires 1M aligned guest sizes */ 7037d9a662eSMichael Roth n = (n + 255) & ~255; 7047d9a662eSMichael Roth #endif 7057d9a662eSMichael Roth return n; 7067d9a662eSMichael Roth } 7077d9a662eSMichael Roth 7087d9a662eSMichael Roth struct kvm_userspace_memory_region * 7097d9a662eSMichael Roth kvm_userspace_memory_region_find(struct kvm_vm *vm, uint64_t start, 7107d9a662eSMichael Roth uint64_t end); 7117d9a662eSMichael Roth 7127d9a662eSMichael Roth #define sync_global_to_guest(vm, g) ({ \ 7137d9a662eSMichael Roth typeof(g) *_p = addr_gva2hva(vm, (vm_vaddr_t)&(g)); \ 7147d9a662eSMichael Roth memcpy(_p, &(g), sizeof(g)); \ 7157d9a662eSMichael Roth }) 7167d9a662eSMichael Roth 7177d9a662eSMichael Roth #define sync_global_from_guest(vm, g) ({ \ 7187d9a662eSMichael Roth typeof(g) *_p = addr_gva2hva(vm, (vm_vaddr_t)&(g)); \ 7197d9a662eSMichael Roth memcpy(&(g), _p, sizeof(g)); \ 7207d9a662eSMichael Roth }) 7217d9a662eSMichael Roth 722768e9a61SSean Christopherson void assert_on_unhandled_exception(struct kvm_vcpu *vcpu); 7237d9a662eSMichael Roth 724768e9a61SSean Christopherson void vcpu_arch_dump(FILE *stream, struct kvm_vcpu *vcpu, 7259931be3fSSean Christopherson uint8_t indent); 7269931be3fSSean Christopherson 727768e9a61SSean Christopherson static inline void vcpu_dump(FILE *stream, struct kvm_vcpu *vcpu, 7289931be3fSSean Christopherson uint8_t indent) 7299931be3fSSean Christopherson { 730768e9a61SSean Christopherson vcpu_arch_dump(stream, vcpu, indent); 7319931be3fSSean Christopherson } 7329931be3fSSean Christopherson 7339931be3fSSean Christopherson /* 7349931be3fSSean Christopherson * Adds a vCPU with reasonable defaults (e.g. a stack) 7359931be3fSSean Christopherson * 7369931be3fSSean Christopherson * Input Args: 7379931be3fSSean Christopherson * vm - Virtual Machine 738768e9a61SSean Christopherson * vcpu_id - The id of the VCPU to add to the VM. 7399931be3fSSean Christopherson * guest_code - The vCPU's entry point 7409931be3fSSean Christopherson */ 7411422efd6SSean Christopherson struct kvm_vcpu *vm_arch_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id, 7421422efd6SSean Christopherson void *guest_code); 7439931be3fSSean Christopherson 744f742d94fSSean Christopherson static inline struct kvm_vcpu *vm_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id, 7459931be3fSSean Christopherson void *guest_code) 7469931be3fSSean Christopherson { 7471422efd6SSean Christopherson return vm_arch_vcpu_add(vm, vcpu_id, guest_code); 7489931be3fSSean Christopherson } 7499931be3fSSean Christopherson 7504c16fa3eSSean Christopherson /* Re-create a vCPU after restarting a VM, e.g. for state save/restore tests. */ 7514c16fa3eSSean Christopherson struct kvm_vcpu *vm_arch_vcpu_recreate(struct kvm_vm *vm, uint32_t vcpu_id); 7524c16fa3eSSean Christopherson 7534c16fa3eSSean Christopherson static inline struct kvm_vcpu *vm_vcpu_recreate(struct kvm_vm *vm, 7544c16fa3eSSean Christopherson uint32_t vcpu_id) 7554c16fa3eSSean Christopherson { 7564c16fa3eSSean Christopherson return vm_arch_vcpu_recreate(vm, vcpu_id); 7574c16fa3eSSean Christopherson } 7584c16fa3eSSean Christopherson 7597fbc6038SSean Christopherson void vcpu_arch_free(struct kvm_vcpu *vcpu); 7607fbc6038SSean Christopherson 7619931be3fSSean Christopherson void virt_arch_pgd_alloc(struct kvm_vm *vm); 7629931be3fSSean Christopherson 7639931be3fSSean Christopherson static inline void virt_pgd_alloc(struct kvm_vm *vm) 7649931be3fSSean Christopherson { 7659931be3fSSean Christopherson virt_arch_pgd_alloc(vm); 7669931be3fSSean Christopherson } 7679931be3fSSean Christopherson 7689931be3fSSean Christopherson /* 7699931be3fSSean Christopherson * VM Virtual Page Map 7709931be3fSSean Christopherson * 7719931be3fSSean Christopherson * Input Args: 7729931be3fSSean Christopherson * vm - Virtual Machine 7739931be3fSSean Christopherson * vaddr - VM Virtual Address 7749931be3fSSean Christopherson * paddr - VM Physical Address 7759931be3fSSean Christopherson * memslot - Memory region slot for new virtual translation tables 7769931be3fSSean Christopherson * 7779931be3fSSean Christopherson * Output Args: None 7789931be3fSSean Christopherson * 7799931be3fSSean Christopherson * Return: None 7809931be3fSSean Christopherson * 7819931be3fSSean Christopherson * Within @vm, creates a virtual translation for the page starting 7829931be3fSSean Christopherson * at @vaddr to the page starting at @paddr. 7839931be3fSSean Christopherson */ 7849931be3fSSean Christopherson void virt_arch_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr); 7859931be3fSSean Christopherson 7869931be3fSSean Christopherson static inline void virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr) 7879931be3fSSean Christopherson { 7889931be3fSSean Christopherson virt_arch_pg_map(vm, vaddr, paddr); 7899931be3fSSean Christopherson } 7909931be3fSSean Christopherson 7919931be3fSSean Christopherson 7929931be3fSSean Christopherson /* 7939931be3fSSean Christopherson * Address Guest Virtual to Guest Physical 7949931be3fSSean Christopherson * 7959931be3fSSean Christopherson * Input Args: 7969931be3fSSean Christopherson * vm - Virtual Machine 7979931be3fSSean Christopherson * gva - VM virtual address 7989931be3fSSean Christopherson * 7999931be3fSSean Christopherson * Output Args: None 8009931be3fSSean Christopherson * 8019931be3fSSean Christopherson * Return: 8029931be3fSSean Christopherson * Equivalent VM physical address 8039931be3fSSean Christopherson * 8049931be3fSSean Christopherson * Returns the VM physical address of the translated VM virtual 8059931be3fSSean Christopherson * address given by @gva. 8069931be3fSSean Christopherson */ 8079931be3fSSean Christopherson vm_paddr_t addr_arch_gva2gpa(struct kvm_vm *vm, vm_vaddr_t gva); 8089931be3fSSean Christopherson 8099931be3fSSean Christopherson static inline vm_paddr_t addr_gva2gpa(struct kvm_vm *vm, vm_vaddr_t gva) 8109931be3fSSean Christopherson { 8119931be3fSSean Christopherson return addr_arch_gva2gpa(vm, gva); 8129931be3fSSean Christopherson } 8139931be3fSSean Christopherson 8149931be3fSSean Christopherson /* 8159931be3fSSean Christopherson * Virtual Translation Tables Dump 8169931be3fSSean Christopherson * 8179931be3fSSean Christopherson * Input Args: 8189931be3fSSean Christopherson * stream - Output FILE stream 8199931be3fSSean Christopherson * vm - Virtual Machine 8209931be3fSSean Christopherson * indent - Left margin indent amount 8219931be3fSSean Christopherson * 8229931be3fSSean Christopherson * Output Args: None 8239931be3fSSean Christopherson * 8249931be3fSSean Christopherson * Return: None 8259931be3fSSean Christopherson * 8269931be3fSSean Christopherson * Dumps to the FILE stream given by @stream, the contents of all the 8279931be3fSSean Christopherson * virtual translation tables for the VM given by @vm. 8289931be3fSSean Christopherson */ 8299931be3fSSean Christopherson void virt_arch_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent); 8309931be3fSSean Christopherson 8319931be3fSSean Christopherson static inline void virt_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent) 8329931be3fSSean Christopherson { 8339931be3fSSean Christopherson virt_arch_dump(stream, vm, indent); 8349931be3fSSean Christopherson } 8359931be3fSSean Christopherson 836b774da3fSBen Gardon 837b774da3fSBen Gardon static inline int __vm_disable_nx_huge_pages(struct kvm_vm *vm) 838b774da3fSBen Gardon { 839b774da3fSBen Gardon return __vm_enable_cap(vm, KVM_CAP_VM_DISABLE_NX_HUGE_PAGES, 0); 840b774da3fSBen Gardon } 841b774da3fSBen Gardon 8427d9a662eSMichael Roth #endif /* SELFTEST_KVM_UTIL_BASE_H */ 843