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, &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, &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, &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, &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