Path: blob/master/tools/testing/selftests/kvm/include/kvm_util.h
38237 views
/* SPDX-License-Identifier: GPL-2.0-only */1/*2* Copyright (C) 2018, Google LLC.3*/4#ifndef SELFTEST_KVM_UTIL_H5#define SELFTEST_KVM_UTIL_H67#include "test_util.h"89#include <linux/compiler.h>10#include "linux/hashtable.h"11#include "linux/list.h"12#include <linux/kernel.h>13#include <linux/kvm.h>14#include "linux/rbtree.h"15#include <linux/types.h>1617#include <asm/atomic.h>18#include <asm/kvm.h>1920#include <sys/eventfd.h>21#include <sys/ioctl.h>2223#include <pthread.h>2425#include "kvm_syscalls.h"26#include "kvm_util_arch.h"27#include "kvm_util_types.h"28#include "sparsebit.h"2930#define KVM_DEV_PATH "/dev/kvm"31#define KVM_MAX_VCPUS 5123233#define NSEC_PER_SEC 1000000000L3435struct userspace_mem_region {36struct kvm_userspace_memory_region2 region;37struct sparsebit *unused_phy_pages;38struct sparsebit *protected_phy_pages;39int fd;40off_t offset;41enum vm_mem_backing_src_type backing_src_type;42void *host_mem;43void *host_alias;44void *mmap_start;45void *mmap_alias;46size_t mmap_size;47struct rb_node gpa_node;48struct rb_node hva_node;49struct hlist_node slot_node;50};5152struct kvm_binary_stats {53int fd;54struct kvm_stats_header header;55struct kvm_stats_desc *desc;56};5758struct kvm_vcpu {59struct list_head list;60uint32_t id;61int fd;62struct kvm_vm *vm;63struct kvm_run *run;64#ifdef __x86_64__65struct kvm_cpuid2 *cpuid;66#endif67#ifdef __aarch64__68struct kvm_vcpu_init init;69#endif70struct kvm_binary_stats stats;71struct kvm_dirty_gfn *dirty_gfns;72uint32_t fetch_index;73uint32_t dirty_gfns_count;74};7576struct userspace_mem_regions {77struct rb_root gpa_tree;78struct rb_root hva_tree;79DECLARE_HASHTABLE(slot_hash, 9);80};8182enum kvm_mem_region_type {83MEM_REGION_CODE,84MEM_REGION_DATA,85MEM_REGION_PT,86MEM_REGION_TEST_DATA,87NR_MEM_REGIONS,88};8990struct kvm_vm {91int mode;92unsigned long type;93int kvm_fd;94int fd;95unsigned int pgtable_levels;96unsigned int page_size;97unsigned int page_shift;98unsigned int pa_bits;99unsigned int va_bits;100uint64_t max_gfn;101struct list_head vcpus;102struct userspace_mem_regions regions;103struct sparsebit *vpages_valid;104struct sparsebit *vpages_mapped;105bool has_irqchip;106bool pgd_created;107vm_paddr_t ucall_mmio_addr;108vm_paddr_t pgd;109vm_vaddr_t handlers;110uint32_t dirty_ring_size;111uint64_t gpa_tag_mask;112113struct kvm_vm_arch arch;114115struct kvm_binary_stats stats;116117/*118* KVM region slots. These are the default memslots used by page119* allocators, e.g., lib/elf uses the memslots[MEM_REGION_CODE]120* memslot.121*/122uint32_t memslots[NR_MEM_REGIONS];123};124125struct vcpu_reg_sublist {126const char *name;127long capability;128int feature;129int feature_type;130bool finalize;131__u64 *regs;132__u64 regs_n;133__u64 *rejects_set;134__u64 rejects_set_n;135__u64 *skips_set;136__u64 skips_set_n;137};138139struct vcpu_reg_list {140char *name;141struct vcpu_reg_sublist sublists[];142};143144#define for_each_sublist(c, s) \145for ((s) = &(c)->sublists[0]; (s)->regs; ++(s))146147#define kvm_for_each_vcpu(vm, i, vcpu) \148for ((i) = 0; (i) <= (vm)->last_vcpu_id; (i)++) \149if (!((vcpu) = vm->vcpus[i])) \150continue; \151else152153struct userspace_mem_region *154memslot2region(struct kvm_vm *vm, uint32_t memslot);155156static inline struct userspace_mem_region *vm_get_mem_region(struct kvm_vm *vm,157enum kvm_mem_region_type type)158{159assert(type < NR_MEM_REGIONS);160return memslot2region(vm, vm->memslots[type]);161}162163/* Minimum allocated guest virtual and physical addresses */164#define KVM_UTIL_MIN_VADDR 0x2000165#define KVM_GUEST_PAGE_TABLE_MIN_PADDR 0x180000166167#define DEFAULT_GUEST_STACK_VADDR_MIN 0xab6000168#define DEFAULT_STACK_PGS 5169170enum vm_guest_mode {171VM_MODE_P52V48_4K,172VM_MODE_P52V48_16K,173VM_MODE_P52V48_64K,174VM_MODE_P48V48_4K,175VM_MODE_P48V48_16K,176VM_MODE_P48V48_64K,177VM_MODE_P40V48_4K,178VM_MODE_P40V48_16K,179VM_MODE_P40V48_64K,180VM_MODE_PXXVYY_4K, /* For 48-bit or 57-bit VA, depending on host support */181VM_MODE_P47V64_4K,182VM_MODE_P44V64_4K,183VM_MODE_P36V48_4K,184VM_MODE_P36V48_16K,185VM_MODE_P36V48_64K,186VM_MODE_P47V47_16K,187VM_MODE_P36V47_16K,188NUM_VM_MODES,189};190191struct vm_shape {192uint32_t type;193uint8_t mode;194uint8_t pad0;195uint16_t pad1;196};197198kvm_static_assert(sizeof(struct vm_shape) == sizeof(uint64_t));199200#define VM_TYPE_DEFAULT 0201202#define VM_SHAPE(__mode) \203({ \204struct vm_shape shape = { \205.mode = (__mode), \206.type = VM_TYPE_DEFAULT \207}; \208\209shape; \210})211212#if defined(__aarch64__)213214extern enum vm_guest_mode vm_mode_default;215216#define VM_MODE_DEFAULT vm_mode_default217#define MIN_PAGE_SHIFT 12U218#define ptes_per_page(page_size) ((page_size) / 8)219220#elif defined(__x86_64__)221222#define VM_MODE_DEFAULT VM_MODE_PXXVYY_4K223#define MIN_PAGE_SHIFT 12U224#define ptes_per_page(page_size) ((page_size) / 8)225226#elif defined(__s390x__)227228#define VM_MODE_DEFAULT VM_MODE_P44V64_4K229#define MIN_PAGE_SHIFT 12U230#define ptes_per_page(page_size) ((page_size) / 16)231232#elif defined(__riscv)233234#if __riscv_xlen == 32235#error "RISC-V 32-bit kvm selftests not supported"236#endif237238#define VM_MODE_DEFAULT VM_MODE_P40V48_4K239#define MIN_PAGE_SHIFT 12U240#define ptes_per_page(page_size) ((page_size) / 8)241242#elif defined(__loongarch__)243#define VM_MODE_DEFAULT VM_MODE_P47V47_16K244#define MIN_PAGE_SHIFT 12U245#define ptes_per_page(page_size) ((page_size) / 8)246247#endif248249#define VM_SHAPE_DEFAULT VM_SHAPE(VM_MODE_DEFAULT)250251#define MIN_PAGE_SIZE (1U << MIN_PAGE_SHIFT)252#define PTES_PER_MIN_PAGE ptes_per_page(MIN_PAGE_SIZE)253254struct vm_guest_mode_params {255unsigned int pa_bits;256unsigned int va_bits;257unsigned int page_size;258unsigned int page_shift;259};260extern const struct vm_guest_mode_params vm_guest_mode_params[];261262int __open_path_or_exit(const char *path, int flags, const char *enoent_help);263int open_path_or_exit(const char *path, int flags);264int open_kvm_dev_path_or_exit(void);265266int kvm_get_module_param_integer(const char *module_name, const char *param);267bool kvm_get_module_param_bool(const char *module_name, const char *param);268269static inline bool get_kvm_param_bool(const char *param)270{271return kvm_get_module_param_bool("kvm", param);272}273274static inline int get_kvm_param_integer(const char *param)275{276return kvm_get_module_param_integer("kvm", param);277}278279unsigned int kvm_check_cap(long cap);280281static inline bool kvm_has_cap(long cap)282{283return kvm_check_cap(cap);284}285286/*287* Use the "inner", double-underscore macro when reporting errors from within288* other macros so that the name of ioctl() and not its literal numeric value289* is printed on error. The "outer" macro is strongly preferred when reporting290* errors "directly", i.e. without an additional layer of macros, as it reduces291* the probability of passing in the wrong string.292*/293#define __KVM_IOCTL_ERROR(_name, _ret) __KVM_SYSCALL_ERROR(_name, _ret)294#define KVM_IOCTL_ERROR(_ioctl, _ret) __KVM_IOCTL_ERROR(#_ioctl, _ret)295296#define kvm_do_ioctl(fd, cmd, arg) \297({ \298kvm_static_assert(!_IOC_SIZE(cmd) || sizeof(*arg) == _IOC_SIZE(cmd)); \299ioctl(fd, cmd, arg); \300})301302#define __kvm_ioctl(kvm_fd, cmd, arg) \303kvm_do_ioctl(kvm_fd, cmd, arg)304305#define kvm_ioctl(kvm_fd, cmd, arg) \306({ \307int ret = __kvm_ioctl(kvm_fd, cmd, arg); \308\309TEST_ASSERT(!ret, __KVM_IOCTL_ERROR(#cmd, ret)); \310})311312static __always_inline void static_assert_is_vm(struct kvm_vm *vm) { }313314#define __vm_ioctl(vm, cmd, arg) \315({ \316static_assert_is_vm(vm); \317kvm_do_ioctl((vm)->fd, cmd, arg); \318})319320/*321* Assert that a VM or vCPU ioctl() succeeded, with extra magic to detect if322* the ioctl() failed because KVM killed/bugged the VM. To detect a dead VM,323* probe KVM_CAP_USER_MEMORY, which (a) has been supported by KVM since before324* selftests existed and (b) should never outright fail, i.e. is supposed to325* return 0 or 1. If KVM kills a VM, KVM returns -EIO for all ioctl()s for the326* VM and its vCPUs, including KVM_CHECK_EXTENSION.327*/328#define __TEST_ASSERT_VM_VCPU_IOCTL(cond, name, ret, vm) \329do { \330int __errno = errno; \331\332static_assert_is_vm(vm); \333\334if (cond) \335break; \336\337if (errno == EIO && \338__vm_ioctl(vm, KVM_CHECK_EXTENSION, (void *)KVM_CAP_USER_MEMORY) < 0) { \339TEST_ASSERT(errno == EIO, "KVM killed the VM, should return -EIO"); \340TEST_FAIL("KVM killed/bugged the VM, check the kernel log for clues"); \341} \342errno = __errno; \343TEST_ASSERT(cond, __KVM_IOCTL_ERROR(name, ret)); \344} while (0)345346#define TEST_ASSERT_VM_VCPU_IOCTL(cond, cmd, ret, vm) \347__TEST_ASSERT_VM_VCPU_IOCTL(cond, #cmd, ret, vm)348349#define vm_ioctl(vm, cmd, arg) \350({ \351int ret = __vm_ioctl(vm, cmd, arg); \352\353__TEST_ASSERT_VM_VCPU_IOCTL(!ret, #cmd, ret, vm); \354})355356static __always_inline void static_assert_is_vcpu(struct kvm_vcpu *vcpu) { }357358#define __vcpu_ioctl(vcpu, cmd, arg) \359({ \360static_assert_is_vcpu(vcpu); \361kvm_do_ioctl((vcpu)->fd, cmd, arg); \362})363364#define vcpu_ioctl(vcpu, cmd, arg) \365({ \366int ret = __vcpu_ioctl(vcpu, cmd, arg); \367\368__TEST_ASSERT_VM_VCPU_IOCTL(!ret, #cmd, ret, (vcpu)->vm); \369})370371/*372* Looks up and returns the value corresponding to the capability373* (KVM_CAP_*) given by cap.374*/375static inline int vm_check_cap(struct kvm_vm *vm, long cap)376{377int ret = __vm_ioctl(vm, KVM_CHECK_EXTENSION, (void *)cap);378379TEST_ASSERT_VM_VCPU_IOCTL(ret >= 0, KVM_CHECK_EXTENSION, ret, vm);380return ret;381}382383static inline int __vm_enable_cap(struct kvm_vm *vm, uint32_t cap, uint64_t arg0)384{385struct kvm_enable_cap enable_cap = { .cap = cap, .args = { arg0 } };386387return __vm_ioctl(vm, KVM_ENABLE_CAP, &enable_cap);388}389static inline void vm_enable_cap(struct kvm_vm *vm, uint32_t cap, uint64_t arg0)390{391struct kvm_enable_cap enable_cap = { .cap = cap, .args = { arg0 } };392393vm_ioctl(vm, KVM_ENABLE_CAP, &enable_cap);394}395396static inline void vm_set_memory_attributes(struct kvm_vm *vm, uint64_t gpa,397uint64_t size, uint64_t attributes)398{399struct kvm_memory_attributes attr = {400.attributes = attributes,401.address = gpa,402.size = size,403.flags = 0,404};405406/*407* KVM_SET_MEMORY_ATTRIBUTES overwrites _all_ attributes. These flows408* need significant enhancements to support multiple attributes.409*/410TEST_ASSERT(!attributes || attributes == KVM_MEMORY_ATTRIBUTE_PRIVATE,411"Update me to support multiple attributes!");412413vm_ioctl(vm, KVM_SET_MEMORY_ATTRIBUTES, &attr);414}415416417static inline void vm_mem_set_private(struct kvm_vm *vm, uint64_t gpa,418uint64_t size)419{420vm_set_memory_attributes(vm, gpa, size, KVM_MEMORY_ATTRIBUTE_PRIVATE);421}422423static inline void vm_mem_set_shared(struct kvm_vm *vm, uint64_t gpa,424uint64_t size)425{426vm_set_memory_attributes(vm, gpa, size, 0);427}428429void vm_guest_mem_fallocate(struct kvm_vm *vm, uint64_t gpa, uint64_t size,430bool punch_hole);431432static inline void vm_guest_mem_punch_hole(struct kvm_vm *vm, uint64_t gpa,433uint64_t size)434{435vm_guest_mem_fallocate(vm, gpa, size, true);436}437438static inline void vm_guest_mem_allocate(struct kvm_vm *vm, uint64_t gpa,439uint64_t size)440{441vm_guest_mem_fallocate(vm, gpa, size, false);442}443444void vm_enable_dirty_ring(struct kvm_vm *vm, uint32_t ring_size);445const char *vm_guest_mode_string(uint32_t i);446447void kvm_vm_free(struct kvm_vm *vmp);448void kvm_vm_restart(struct kvm_vm *vmp);449void kvm_vm_release(struct kvm_vm *vmp);450void kvm_vm_elf_load(struct kvm_vm *vm, const char *filename);451int kvm_memfd_alloc(size_t size, bool hugepages);452453void vm_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent);454455static inline void kvm_vm_get_dirty_log(struct kvm_vm *vm, int slot, void *log)456{457struct kvm_dirty_log args = { .dirty_bitmap = log, .slot = slot };458459vm_ioctl(vm, KVM_GET_DIRTY_LOG, &args);460}461462static inline void kvm_vm_clear_dirty_log(struct kvm_vm *vm, int slot, void *log,463uint64_t first_page, uint32_t num_pages)464{465struct kvm_clear_dirty_log args = {466.dirty_bitmap = log,467.slot = slot,468.first_page = first_page,469.num_pages = num_pages470};471472vm_ioctl(vm, KVM_CLEAR_DIRTY_LOG, &args);473}474475static inline uint32_t kvm_vm_reset_dirty_ring(struct kvm_vm *vm)476{477return __vm_ioctl(vm, KVM_RESET_DIRTY_RINGS, NULL);478}479480static inline void kvm_vm_register_coalesced_io(struct kvm_vm *vm,481uint64_t address,482uint64_t size, bool pio)483{484struct kvm_coalesced_mmio_zone zone = {485.addr = address,486.size = size,487.pio = pio,488};489490vm_ioctl(vm, KVM_REGISTER_COALESCED_MMIO, &zone);491}492493static inline void kvm_vm_unregister_coalesced_io(struct kvm_vm *vm,494uint64_t address,495uint64_t size, bool pio)496{497struct kvm_coalesced_mmio_zone zone = {498.addr = address,499.size = size,500.pio = pio,501};502503vm_ioctl(vm, KVM_UNREGISTER_COALESCED_MMIO, &zone);504}505506static inline int vm_get_stats_fd(struct kvm_vm *vm)507{508int fd = __vm_ioctl(vm, KVM_GET_STATS_FD, NULL);509510TEST_ASSERT_VM_VCPU_IOCTL(fd >= 0, KVM_GET_STATS_FD, fd, vm);511return fd;512}513514static inline int __kvm_irqfd(struct kvm_vm *vm, uint32_t gsi, int eventfd,515uint32_t flags)516{517struct kvm_irqfd irqfd = {518.fd = eventfd,519.gsi = gsi,520.flags = flags,521.resamplefd = -1,522};523524return __vm_ioctl(vm, KVM_IRQFD, &irqfd);525}526527static inline void kvm_irqfd(struct kvm_vm *vm, uint32_t gsi, int eventfd,528uint32_t flags)529{530int ret = __kvm_irqfd(vm, gsi, eventfd, flags);531532TEST_ASSERT_VM_VCPU_IOCTL(!ret, KVM_IRQFD, ret, vm);533}534535static inline void kvm_assign_irqfd(struct kvm_vm *vm, uint32_t gsi, int eventfd)536{537kvm_irqfd(vm, gsi, eventfd, 0);538}539540static inline void kvm_deassign_irqfd(struct kvm_vm *vm, uint32_t gsi, int eventfd)541{542kvm_irqfd(vm, gsi, eventfd, KVM_IRQFD_FLAG_DEASSIGN);543}544545static inline int kvm_new_eventfd(void)546{547int fd = eventfd(0, 0);548549TEST_ASSERT(fd >= 0, __KVM_SYSCALL_ERROR("eventfd()", fd));550return fd;551}552553static inline void read_stats_header(int stats_fd, struct kvm_stats_header *header)554{555ssize_t ret;556557ret = pread(stats_fd, header, sizeof(*header), 0);558TEST_ASSERT(ret == sizeof(*header),559"Failed to read '%lu' header bytes, ret = '%ld'",560sizeof(*header), ret);561}562563struct kvm_stats_desc *read_stats_descriptors(int stats_fd,564struct kvm_stats_header *header);565566static inline ssize_t get_stats_descriptor_size(struct kvm_stats_header *header)567{568/*569* The base size of the descriptor is defined by KVM's ABI, but the570* size of the name field is variable, as far as KVM's ABI is571* concerned. For a given instance of KVM, the name field is the same572* size for all stats and is provided in the overall stats header.573*/574return sizeof(struct kvm_stats_desc) + header->name_size;575}576577static inline struct kvm_stats_desc *get_stats_descriptor(struct kvm_stats_desc *stats,578int index,579struct kvm_stats_header *header)580{581/*582* Note, size_desc includes the size of the name field, which is583* variable. i.e. this is NOT equivalent to &stats_desc[i].584*/585return (void *)stats + index * get_stats_descriptor_size(header);586}587588void read_stat_data(int stats_fd, struct kvm_stats_header *header,589struct kvm_stats_desc *desc, uint64_t *data,590size_t max_elements);591592void kvm_get_stat(struct kvm_binary_stats *stats, const char *name,593uint64_t *data, size_t max_elements);594595#define __get_stat(stats, stat) \596({ \597uint64_t data; \598\599kvm_get_stat(stats, #stat, &data, 1); \600data; \601})602603#define vm_get_stat(vm, stat) __get_stat(&(vm)->stats, stat)604#define vcpu_get_stat(vcpu, stat) __get_stat(&(vcpu)->stats, stat)605606static inline bool read_smt_control(char *buf, size_t buf_size)607{608FILE *f = fopen("/sys/devices/system/cpu/smt/control", "r");609bool ret;610611if (!f)612return false;613614ret = fread(buf, sizeof(*buf), buf_size, f) > 0;615fclose(f);616617return ret;618}619620static inline bool is_smt_possible(void)621{622char buf[16];623624if (read_smt_control(buf, sizeof(buf)) &&625(!strncmp(buf, "forceoff", 8) || !strncmp(buf, "notsupported", 12)))626return false;627628return true;629}630631static inline bool is_smt_on(void)632{633char buf[16];634635if (read_smt_control(buf, sizeof(buf)) && !strncmp(buf, "on", 2))636return true;637638return false;639}640641void vm_create_irqchip(struct kvm_vm *vm);642643static inline int __vm_create_guest_memfd(struct kvm_vm *vm, uint64_t size,644uint64_t flags)645{646struct kvm_create_guest_memfd guest_memfd = {647.size = size,648.flags = flags,649};650651return __vm_ioctl(vm, KVM_CREATE_GUEST_MEMFD, &guest_memfd);652}653654static inline int vm_create_guest_memfd(struct kvm_vm *vm, uint64_t size,655uint64_t flags)656{657int fd = __vm_create_guest_memfd(vm, size, flags);658659TEST_ASSERT(fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_GUEST_MEMFD, fd));660return fd;661}662663void vm_set_user_memory_region(struct kvm_vm *vm, uint32_t slot, uint32_t flags,664uint64_t gpa, uint64_t size, void *hva);665int __vm_set_user_memory_region(struct kvm_vm *vm, uint32_t slot, uint32_t flags,666uint64_t gpa, uint64_t size, void *hva);667void vm_set_user_memory_region2(struct kvm_vm *vm, uint32_t slot, uint32_t flags,668uint64_t gpa, uint64_t size, void *hva,669uint32_t guest_memfd, uint64_t guest_memfd_offset);670int __vm_set_user_memory_region2(struct kvm_vm *vm, uint32_t slot, uint32_t flags,671uint64_t gpa, uint64_t size, void *hva,672uint32_t guest_memfd, uint64_t guest_memfd_offset);673674void vm_userspace_mem_region_add(struct kvm_vm *vm,675enum vm_mem_backing_src_type src_type,676uint64_t gpa, uint32_t slot, uint64_t npages,677uint32_t flags);678void vm_mem_add(struct kvm_vm *vm, enum vm_mem_backing_src_type src_type,679uint64_t gpa, uint32_t slot, uint64_t npages, uint32_t flags,680int guest_memfd_fd, uint64_t guest_memfd_offset);681682#ifndef vm_arch_has_protected_memory683static inline bool vm_arch_has_protected_memory(struct kvm_vm *vm)684{685return false;686}687#endif688689void vm_mem_region_set_flags(struct kvm_vm *vm, uint32_t slot, uint32_t flags);690void vm_mem_region_reload(struct kvm_vm *vm, uint32_t slot);691void vm_mem_region_move(struct kvm_vm *vm, uint32_t slot, uint64_t new_gpa);692void vm_mem_region_delete(struct kvm_vm *vm, uint32_t slot);693struct kvm_vcpu *__vm_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id);694void vm_populate_vaddr_bitmap(struct kvm_vm *vm);695vm_vaddr_t vm_vaddr_unused_gap(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min);696vm_vaddr_t vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min);697vm_vaddr_t __vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min,698enum kvm_mem_region_type type);699vm_vaddr_t vm_vaddr_alloc_shared(struct kvm_vm *vm, size_t sz,700vm_vaddr_t vaddr_min,701enum kvm_mem_region_type type);702vm_vaddr_t vm_vaddr_alloc_pages(struct kvm_vm *vm, int nr_pages);703vm_vaddr_t __vm_vaddr_alloc_page(struct kvm_vm *vm,704enum kvm_mem_region_type type);705vm_vaddr_t vm_vaddr_alloc_page(struct kvm_vm *vm);706707void virt_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr,708unsigned int npages);709void *addr_gpa2hva(struct kvm_vm *vm, vm_paddr_t gpa);710void *addr_gva2hva(struct kvm_vm *vm, vm_vaddr_t gva);711vm_paddr_t addr_hva2gpa(struct kvm_vm *vm, void *hva);712void *addr_gpa2alias(struct kvm_vm *vm, vm_paddr_t gpa);713714#ifndef vcpu_arch_put_guest715#define vcpu_arch_put_guest(mem, val) do { (mem) = (val); } while (0)716#endif717718static inline vm_paddr_t vm_untag_gpa(struct kvm_vm *vm, vm_paddr_t gpa)719{720return gpa & ~vm->gpa_tag_mask;721}722723void vcpu_run(struct kvm_vcpu *vcpu);724int _vcpu_run(struct kvm_vcpu *vcpu);725726static inline int __vcpu_run(struct kvm_vcpu *vcpu)727{728return __vcpu_ioctl(vcpu, KVM_RUN, NULL);729}730731void vcpu_run_complete_io(struct kvm_vcpu *vcpu);732struct kvm_reg_list *vcpu_get_reg_list(struct kvm_vcpu *vcpu);733734static inline void vcpu_enable_cap(struct kvm_vcpu *vcpu, uint32_t cap,735uint64_t arg0)736{737struct kvm_enable_cap enable_cap = { .cap = cap, .args = { arg0 } };738739vcpu_ioctl(vcpu, KVM_ENABLE_CAP, &enable_cap);740}741742static inline void vcpu_guest_debug_set(struct kvm_vcpu *vcpu,743struct kvm_guest_debug *debug)744{745vcpu_ioctl(vcpu, KVM_SET_GUEST_DEBUG, debug);746}747748static inline void vcpu_mp_state_get(struct kvm_vcpu *vcpu,749struct kvm_mp_state *mp_state)750{751vcpu_ioctl(vcpu, KVM_GET_MP_STATE, mp_state);752}753static inline void vcpu_mp_state_set(struct kvm_vcpu *vcpu,754struct kvm_mp_state *mp_state)755{756vcpu_ioctl(vcpu, KVM_SET_MP_STATE, mp_state);757}758759static inline void vcpu_regs_get(struct kvm_vcpu *vcpu, struct kvm_regs *regs)760{761vcpu_ioctl(vcpu, KVM_GET_REGS, regs);762}763764static inline void vcpu_regs_set(struct kvm_vcpu *vcpu, struct kvm_regs *regs)765{766vcpu_ioctl(vcpu, KVM_SET_REGS, regs);767}768static inline void vcpu_sregs_get(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)769{770vcpu_ioctl(vcpu, KVM_GET_SREGS, sregs);771772}773static inline void vcpu_sregs_set(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)774{775vcpu_ioctl(vcpu, KVM_SET_SREGS, sregs);776}777static inline int _vcpu_sregs_set(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)778{779return __vcpu_ioctl(vcpu, KVM_SET_SREGS, sregs);780}781static inline void vcpu_fpu_get(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)782{783vcpu_ioctl(vcpu, KVM_GET_FPU, fpu);784}785static inline void vcpu_fpu_set(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)786{787vcpu_ioctl(vcpu, KVM_SET_FPU, fpu);788}789790static inline int __vcpu_get_reg(struct kvm_vcpu *vcpu, uint64_t id, void *addr)791{792struct kvm_one_reg reg = { .id = id, .addr = (uint64_t)addr };793794return __vcpu_ioctl(vcpu, KVM_GET_ONE_REG, ®);795}796static inline int __vcpu_set_reg(struct kvm_vcpu *vcpu, uint64_t id, uint64_t val)797{798struct kvm_one_reg reg = { .id = id, .addr = (uint64_t)&val };799800return __vcpu_ioctl(vcpu, KVM_SET_ONE_REG, ®);801}802static inline uint64_t vcpu_get_reg(struct kvm_vcpu *vcpu, uint64_t id)803{804uint64_t val;805struct kvm_one_reg reg = { .id = id, .addr = (uint64_t)&val };806807TEST_ASSERT(KVM_REG_SIZE(id) <= sizeof(val), "Reg %lx too big", id);808809vcpu_ioctl(vcpu, KVM_GET_ONE_REG, ®);810return val;811}812static inline void vcpu_set_reg(struct kvm_vcpu *vcpu, uint64_t id, uint64_t val)813{814struct kvm_one_reg reg = { .id = id, .addr = (uint64_t)&val };815816TEST_ASSERT(KVM_REG_SIZE(id) <= sizeof(val), "Reg %lx too big", id);817818vcpu_ioctl(vcpu, KVM_SET_ONE_REG, ®);819}820821#ifdef __KVM_HAVE_VCPU_EVENTS822static inline void vcpu_events_get(struct kvm_vcpu *vcpu,823struct kvm_vcpu_events *events)824{825vcpu_ioctl(vcpu, KVM_GET_VCPU_EVENTS, events);826}827static inline void vcpu_events_set(struct kvm_vcpu *vcpu,828struct kvm_vcpu_events *events)829{830vcpu_ioctl(vcpu, KVM_SET_VCPU_EVENTS, events);831}832#endif833#ifdef __x86_64__834static inline void vcpu_nested_state_get(struct kvm_vcpu *vcpu,835struct kvm_nested_state *state)836{837vcpu_ioctl(vcpu, KVM_GET_NESTED_STATE, state);838}839static inline int __vcpu_nested_state_set(struct kvm_vcpu *vcpu,840struct kvm_nested_state *state)841{842return __vcpu_ioctl(vcpu, KVM_SET_NESTED_STATE, state);843}844845static inline void vcpu_nested_state_set(struct kvm_vcpu *vcpu,846struct kvm_nested_state *state)847{848vcpu_ioctl(vcpu, KVM_SET_NESTED_STATE, state);849}850#endif851static inline int vcpu_get_stats_fd(struct kvm_vcpu *vcpu)852{853int fd = __vcpu_ioctl(vcpu, KVM_GET_STATS_FD, NULL);854855TEST_ASSERT_VM_VCPU_IOCTL(fd >= 0, KVM_CHECK_EXTENSION, fd, vcpu->vm);856return fd;857}858859int __kvm_has_device_attr(int dev_fd, uint32_t group, uint64_t attr);860861static inline void kvm_has_device_attr(int dev_fd, uint32_t group, uint64_t attr)862{863int ret = __kvm_has_device_attr(dev_fd, group, attr);864865TEST_ASSERT(!ret, "KVM_HAS_DEVICE_ATTR failed, rc: %i errno: %i", ret, errno);866}867868int __kvm_device_attr_get(int dev_fd, uint32_t group, uint64_t attr, void *val);869870static inline void kvm_device_attr_get(int dev_fd, uint32_t group,871uint64_t attr, void *val)872{873int ret = __kvm_device_attr_get(dev_fd, group, attr, val);874875TEST_ASSERT(!ret, KVM_IOCTL_ERROR(KVM_GET_DEVICE_ATTR, ret));876}877878int __kvm_device_attr_set(int dev_fd, uint32_t group, uint64_t attr, void *val);879880static inline void kvm_device_attr_set(int dev_fd, uint32_t group,881uint64_t attr, void *val)882{883int ret = __kvm_device_attr_set(dev_fd, group, attr, val);884885TEST_ASSERT(!ret, KVM_IOCTL_ERROR(KVM_SET_DEVICE_ATTR, ret));886}887888static inline int __vcpu_has_device_attr(struct kvm_vcpu *vcpu, uint32_t group,889uint64_t attr)890{891return __kvm_has_device_attr(vcpu->fd, group, attr);892}893894static inline void vcpu_has_device_attr(struct kvm_vcpu *vcpu, uint32_t group,895uint64_t attr)896{897kvm_has_device_attr(vcpu->fd, group, attr);898}899900static inline int __vcpu_device_attr_get(struct kvm_vcpu *vcpu, uint32_t group,901uint64_t attr, void *val)902{903return __kvm_device_attr_get(vcpu->fd, group, attr, val);904}905906static inline void vcpu_device_attr_get(struct kvm_vcpu *vcpu, uint32_t group,907uint64_t attr, void *val)908{909kvm_device_attr_get(vcpu->fd, group, attr, val);910}911912static inline int __vcpu_device_attr_set(struct kvm_vcpu *vcpu, uint32_t group,913uint64_t attr, void *val)914{915return __kvm_device_attr_set(vcpu->fd, group, attr, val);916}917918static inline void vcpu_device_attr_set(struct kvm_vcpu *vcpu, uint32_t group,919uint64_t attr, void *val)920{921kvm_device_attr_set(vcpu->fd, group, attr, val);922}923924int __kvm_test_create_device(struct kvm_vm *vm, uint64_t type);925int __kvm_create_device(struct kvm_vm *vm, uint64_t type);926927static inline int kvm_create_device(struct kvm_vm *vm, uint64_t type)928{929int fd = __kvm_create_device(vm, type);930931TEST_ASSERT(fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_DEVICE, fd));932return fd;933}934935void *vcpu_map_dirty_ring(struct kvm_vcpu *vcpu);936937/*938* VM VCPU Args Set939*940* Input Args:941* vm - Virtual Machine942* num - number of arguments943* ... - arguments, each of type uint64_t944*945* Output Args: None946*947* Return: None948*949* Sets the first @num input parameters for the function at @vcpu's entry point,950* per the C calling convention of the architecture, to the values given as951* variable args. Each of the variable args is expected to be of type uint64_t.952* The maximum @num can be is specific to the architecture.953*/954void vcpu_args_set(struct kvm_vcpu *vcpu, unsigned int num, ...);955956void kvm_irq_line(struct kvm_vm *vm, uint32_t irq, int level);957int _kvm_irq_line(struct kvm_vm *vm, uint32_t irq, int level);958959#define KVM_MAX_IRQ_ROUTES 4096960961struct kvm_irq_routing *kvm_gsi_routing_create(void);962void kvm_gsi_routing_irqchip_add(struct kvm_irq_routing *routing,963uint32_t gsi, uint32_t pin);964int _kvm_gsi_routing_write(struct kvm_vm *vm, struct kvm_irq_routing *routing);965void kvm_gsi_routing_write(struct kvm_vm *vm, struct kvm_irq_routing *routing);966967const char *exit_reason_str(unsigned int exit_reason);968969vm_paddr_t vm_phy_page_alloc(struct kvm_vm *vm, vm_paddr_t paddr_min,970uint32_t memslot);971vm_paddr_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,972vm_paddr_t paddr_min, uint32_t memslot,973bool protected);974vm_paddr_t vm_alloc_page_table(struct kvm_vm *vm);975976static inline vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,977vm_paddr_t paddr_min, uint32_t memslot)978{979/*980* By default, allocate memory as protected for VMs that support981* protected memory, as the majority of memory for such VMs is982* protected, i.e. using shared memory is effectively opt-in.983*/984return __vm_phy_pages_alloc(vm, num, paddr_min, memslot,985vm_arch_has_protected_memory(vm));986}987988/*989* ____vm_create() does KVM_CREATE_VM and little else. __vm_create() also990* loads the test binary into guest memory and creates an IRQ chip (x86 only).991* __vm_create() does NOT create vCPUs, @nr_runnable_vcpus is used purely to992* calculate the amount of memory needed for per-vCPU data, e.g. stacks.993*/994struct kvm_vm *____vm_create(struct vm_shape shape);995struct kvm_vm *__vm_create(struct vm_shape shape, uint32_t nr_runnable_vcpus,996uint64_t nr_extra_pages);997998static inline struct kvm_vm *vm_create_barebones(void)999{1000return ____vm_create(VM_SHAPE_DEFAULT);1001}10021003static inline struct kvm_vm *vm_create_barebones_type(unsigned long type)1004{1005const struct vm_shape shape = {1006.mode = VM_MODE_DEFAULT,1007.type = type,1008};10091010return ____vm_create(shape);1011}10121013static inline struct kvm_vm *vm_create(uint32_t nr_runnable_vcpus)1014{1015return __vm_create(VM_SHAPE_DEFAULT, nr_runnable_vcpus, 0);1016}10171018struct kvm_vm *__vm_create_with_vcpus(struct vm_shape shape, uint32_t nr_vcpus,1019uint64_t extra_mem_pages,1020void *guest_code, struct kvm_vcpu *vcpus[]);10211022static inline struct kvm_vm *vm_create_with_vcpus(uint32_t nr_vcpus,1023void *guest_code,1024struct kvm_vcpu *vcpus[])1025{1026return __vm_create_with_vcpus(VM_SHAPE_DEFAULT, nr_vcpus, 0,1027guest_code, vcpus);1028}102910301031struct kvm_vm *__vm_create_shape_with_one_vcpu(struct vm_shape shape,1032struct kvm_vcpu **vcpu,1033uint64_t extra_mem_pages,1034void *guest_code);10351036/*1037* Create a VM with a single vCPU with reasonable defaults and @extra_mem_pages1038* additional pages of guest memory. Returns the VM and vCPU (via out param).1039*/1040static inline struct kvm_vm *__vm_create_with_one_vcpu(struct kvm_vcpu **vcpu,1041uint64_t extra_mem_pages,1042void *guest_code)1043{1044return __vm_create_shape_with_one_vcpu(VM_SHAPE_DEFAULT, vcpu,1045extra_mem_pages, guest_code);1046}10471048static inline struct kvm_vm *vm_create_with_one_vcpu(struct kvm_vcpu **vcpu,1049void *guest_code)1050{1051return __vm_create_with_one_vcpu(vcpu, 0, guest_code);1052}10531054static inline struct kvm_vm *vm_create_shape_with_one_vcpu(struct vm_shape shape,1055struct kvm_vcpu **vcpu,1056void *guest_code)1057{1058return __vm_create_shape_with_one_vcpu(shape, vcpu, 0, guest_code);1059}10601061struct kvm_vcpu *vm_recreate_with_one_vcpu(struct kvm_vm *vm);10621063void kvm_set_files_rlimit(uint32_t nr_vcpus);10641065int __pin_task_to_cpu(pthread_t task, int cpu);10661067static inline void pin_task_to_cpu(pthread_t task, int cpu)1068{1069int r;10701071r = __pin_task_to_cpu(task, cpu);1072TEST_ASSERT(!r, "Failed to set thread affinity to pCPU '%u'", cpu);1073}10741075static inline int pin_task_to_any_cpu(pthread_t task)1076{1077int cpu = sched_getcpu();10781079pin_task_to_cpu(task, cpu);1080return cpu;1081}10821083static inline void pin_self_to_cpu(int cpu)1084{1085pin_task_to_cpu(pthread_self(), cpu);1086}10871088static inline int pin_self_to_any_cpu(void)1089{1090return pin_task_to_any_cpu(pthread_self());1091}10921093void kvm_print_vcpu_pinning_help(void);1094void kvm_parse_vcpu_pinning(const char *pcpus_string, uint32_t vcpu_to_pcpu[],1095int nr_vcpus);10961097unsigned long vm_compute_max_gfn(struct kvm_vm *vm);1098unsigned int vm_calc_num_guest_pages(enum vm_guest_mode mode, size_t size);1099unsigned int vm_num_host_pages(enum vm_guest_mode mode, unsigned int num_guest_pages);1100unsigned int vm_num_guest_pages(enum vm_guest_mode mode, unsigned int num_host_pages);1101static inline unsigned int1102vm_adjust_num_guest_pages(enum vm_guest_mode mode, unsigned int num_guest_pages)1103{1104unsigned int n;1105n = vm_num_guest_pages(mode, vm_num_host_pages(mode, num_guest_pages));1106#ifdef __s390x__1107/* s390 requires 1M aligned guest sizes */1108n = (n + 255) & ~255;1109#endif1110return n;1111}11121113#define sync_global_to_guest(vm, g) ({ \1114typeof(g) *_p = addr_gva2hva(vm, (vm_vaddr_t)&(g)); \1115memcpy(_p, &(g), sizeof(g)); \1116})11171118#define sync_global_from_guest(vm, g) ({ \1119typeof(g) *_p = addr_gva2hva(vm, (vm_vaddr_t)&(g)); \1120memcpy(&(g), _p, sizeof(g)); \1121})11221123/*1124* Write a global value, but only in the VM's (guest's) domain. Primarily used1125* for "globals" that hold per-VM values (VMs always duplicate code and global1126* data into their own region of physical memory), but can be used anytime it's1127* undesirable to change the host's copy of the global.1128*/1129#define write_guest_global(vm, g, val) ({ \1130typeof(g) *_p = addr_gva2hva(vm, (vm_vaddr_t)&(g)); \1131typeof(g) _val = val; \1132\1133memcpy(_p, &(_val), sizeof(g)); \1134})11351136void assert_on_unhandled_exception(struct kvm_vcpu *vcpu);11371138void vcpu_arch_dump(FILE *stream, struct kvm_vcpu *vcpu,1139uint8_t indent);11401141static inline void vcpu_dump(FILE *stream, struct kvm_vcpu *vcpu,1142uint8_t indent)1143{1144vcpu_arch_dump(stream, vcpu, indent);1145}11461147/*1148* Adds a vCPU with reasonable defaults (e.g. a stack)1149*1150* Input Args:1151* vm - Virtual Machine1152* vcpu_id - The id of the VCPU to add to the VM.1153*/1154struct kvm_vcpu *vm_arch_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id);1155void vcpu_arch_set_entry_point(struct kvm_vcpu *vcpu, void *guest_code);11561157static inline struct kvm_vcpu *vm_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id,1158void *guest_code)1159{1160struct kvm_vcpu *vcpu = vm_arch_vcpu_add(vm, vcpu_id);11611162vcpu_arch_set_entry_point(vcpu, guest_code);11631164return vcpu;1165}11661167/* Re-create a vCPU after restarting a VM, e.g. for state save/restore tests. */1168struct kvm_vcpu *vm_arch_vcpu_recreate(struct kvm_vm *vm, uint32_t vcpu_id);11691170static inline struct kvm_vcpu *vm_vcpu_recreate(struct kvm_vm *vm,1171uint32_t vcpu_id)1172{1173return vm_arch_vcpu_recreate(vm, vcpu_id);1174}11751176void vcpu_arch_free(struct kvm_vcpu *vcpu);11771178void virt_arch_pgd_alloc(struct kvm_vm *vm);11791180static inline void virt_pgd_alloc(struct kvm_vm *vm)1181{1182virt_arch_pgd_alloc(vm);1183}11841185/*1186* VM Virtual Page Map1187*1188* Input Args:1189* vm - Virtual Machine1190* vaddr - VM Virtual Address1191* paddr - VM Physical Address1192* memslot - Memory region slot for new virtual translation tables1193*1194* Output Args: None1195*1196* Return: None1197*1198* Within @vm, creates a virtual translation for the page starting1199* at @vaddr to the page starting at @paddr.1200*/1201void virt_arch_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr);12021203static inline void virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr)1204{1205virt_arch_pg_map(vm, vaddr, paddr);1206sparsebit_set(vm->vpages_mapped, vaddr >> vm->page_shift);1207}120812091210/*1211* Address Guest Virtual to Guest Physical1212*1213* Input Args:1214* vm - Virtual Machine1215* gva - VM virtual address1216*1217* Output Args: None1218*1219* Return:1220* Equivalent VM physical address1221*1222* Returns the VM physical address of the translated VM virtual1223* address given by @gva.1224*/1225vm_paddr_t addr_arch_gva2gpa(struct kvm_vm *vm, vm_vaddr_t gva);12261227static inline vm_paddr_t addr_gva2gpa(struct kvm_vm *vm, vm_vaddr_t gva)1228{1229return addr_arch_gva2gpa(vm, gva);1230}12311232/*1233* Virtual Translation Tables Dump1234*1235* Input Args:1236* stream - Output FILE stream1237* vm - Virtual Machine1238* indent - Left margin indent amount1239*1240* Output Args: None1241*1242* Return: None1243*1244* Dumps to the FILE stream given by @stream, the contents of all the1245* virtual translation tables for the VM given by @vm.1246*/1247void virt_arch_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent);12481249static inline void virt_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent)1250{1251virt_arch_dump(stream, vm, indent);1252}125312541255static inline int __vm_disable_nx_huge_pages(struct kvm_vm *vm)1256{1257return __vm_enable_cap(vm, KVM_CAP_VM_DISABLE_NX_HUGE_PAGES, 0);1258}12591260/*1261* Arch hook that is invoked via a constructor, i.e. before exeucting main(),1262* to allow for arch-specific setup that is common to all tests, e.g. computing1263* the default guest "mode".1264*/1265void kvm_selftest_arch_init(void);12661267void kvm_arch_vm_post_create(struct kvm_vm *vm, unsigned int nr_vcpus);1268void kvm_arch_vm_finalize_vcpus(struct kvm_vm *vm);1269void kvm_arch_vm_release(struct kvm_vm *vm);12701271bool vm_is_gpa_protected(struct kvm_vm *vm, vm_paddr_t paddr);12721273uint32_t guest_get_vcpuid(void);12741275bool kvm_arch_has_default_irqchip(void);12761277#endif /* SELFTEST_KVM_UTIL_H */127812791280