linux/tools/testing/selftests/kvm/include/kvm_util.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * tools/testing/selftests/kvm/include/kvm_util.h
   4 *
   5 * Copyright (C) 2018, Google LLC.
   6 */
   7#ifndef SELFTEST_KVM_UTIL_H
   8#define SELFTEST_KVM_UTIL_H
   9
  10#include "test_util.h"
  11
  12#include "asm/kvm.h"
  13#include "linux/list.h"
  14#include "linux/kvm.h"
  15#include <sys/ioctl.h>
  16
  17#include "sparsebit.h"
  18
  19
  20/*
  21 * Callers of kvm_util only have an incomplete/opaque description of the
  22 * structure kvm_util is using to maintain the state of a VM.
  23 */
  24struct kvm_vm;
  25
  26typedef uint64_t vm_paddr_t; /* Virtual Machine (Guest) physical address */
  27typedef uint64_t vm_vaddr_t; /* Virtual Machine (Guest) virtual address */
  28
  29/* Minimum allocated guest virtual and physical addresses */
  30#define KVM_UTIL_MIN_VADDR              0x2000
  31
  32#define DEFAULT_GUEST_PHY_PAGES         512
  33#define DEFAULT_GUEST_STACK_VADDR_MIN   0xab6000
  34#define DEFAULT_STACK_PGS               5
  35
  36enum vm_guest_mode {
  37        VM_MODE_P52V48_4K,
  38        VM_MODE_P52V48_64K,
  39        VM_MODE_P48V48_4K,
  40        VM_MODE_P48V48_64K,
  41        VM_MODE_P40V48_4K,
  42        VM_MODE_P40V48_64K,
  43        VM_MODE_PXXV48_4K,      /* For 48bits VA but ANY bits PA */
  44        NUM_VM_MODES,
  45};
  46
  47#if defined(__aarch64__)
  48#define VM_MODE_DEFAULT VM_MODE_P40V48_4K
  49#elif defined(__x86_64__)
  50#define VM_MODE_DEFAULT VM_MODE_PXXV48_4K
  51#else
  52#define VM_MODE_DEFAULT VM_MODE_P52V48_4K
  53#endif
  54
  55#define vm_guest_mode_string(m) vm_guest_mode_string[m]
  56extern const char * const vm_guest_mode_string[];
  57
  58enum vm_mem_backing_src_type {
  59        VM_MEM_SRC_ANONYMOUS,
  60        VM_MEM_SRC_ANONYMOUS_THP,
  61        VM_MEM_SRC_ANONYMOUS_HUGETLB,
  62};
  63
  64int kvm_check_cap(long cap);
  65int vm_enable_cap(struct kvm_vm *vm, struct kvm_enable_cap *cap);
  66
  67struct kvm_vm *vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm);
  68struct kvm_vm *_vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm);
  69void kvm_vm_free(struct kvm_vm *vmp);
  70void kvm_vm_restart(struct kvm_vm *vmp, int perm);
  71void kvm_vm_release(struct kvm_vm *vmp);
  72void kvm_vm_get_dirty_log(struct kvm_vm *vm, int slot, void *log);
  73void kvm_vm_clear_dirty_log(struct kvm_vm *vm, int slot, void *log,
  74                            uint64_t first_page, uint32_t num_pages);
  75
  76int kvm_memcmp_hva_gva(void *hva, struct kvm_vm *vm, const vm_vaddr_t gva,
  77                       size_t len);
  78
  79void kvm_vm_elf_load(struct kvm_vm *vm, const char *filename,
  80                     uint32_t data_memslot, uint32_t pgd_memslot);
  81
  82void vm_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent);
  83
  84/*
  85 * VM VCPU Dump
  86 *
  87 * Input Args:
  88 *   stream - Output FILE stream
  89 *   vm     - Virtual Machine
  90 *   vcpuid - VCPU ID
  91 *   indent - Left margin indent amount
  92 *
  93 * Output Args: None
  94 *
  95 * Return: None
  96 *
  97 * Dumps the current state of the VCPU specified by @vcpuid, within the VM
  98 * given by @vm, to the FILE stream given by @stream.
  99 */
 100void vcpu_dump(FILE *stream, struct kvm_vm *vm, uint32_t vcpuid,
 101               uint8_t indent);
 102
 103void vm_create_irqchip(struct kvm_vm *vm);
 104
 105void vm_userspace_mem_region_add(struct kvm_vm *vm,
 106        enum vm_mem_backing_src_type src_type,
 107        uint64_t guest_paddr, uint32_t slot, uint64_t npages,
 108        uint32_t flags);
 109
 110void vcpu_ioctl(struct kvm_vm *vm, uint32_t vcpuid, unsigned long ioctl,
 111                void *arg);
 112int _vcpu_ioctl(struct kvm_vm *vm, uint32_t vcpuid, unsigned long ioctl,
 113                void *arg);
 114void vm_ioctl(struct kvm_vm *vm, unsigned long ioctl, void *arg);
 115void vm_mem_region_set_flags(struct kvm_vm *vm, uint32_t slot, uint32_t flags);
 116void vm_mem_region_move(struct kvm_vm *vm, uint32_t slot, uint64_t new_gpa);
 117void vm_mem_region_delete(struct kvm_vm *vm, uint32_t slot);
 118void vm_vcpu_add(struct kvm_vm *vm, uint32_t vcpuid);
 119vm_vaddr_t vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min,
 120                          uint32_t data_memslot, uint32_t pgd_memslot);
 121void virt_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr,
 122              unsigned int npages, uint32_t pgd_memslot);
 123void *addr_gpa2hva(struct kvm_vm *vm, vm_paddr_t gpa);
 124void *addr_gva2hva(struct kvm_vm *vm, vm_vaddr_t gva);
 125vm_paddr_t addr_hva2gpa(struct kvm_vm *vm, void *hva);
 126
 127/*
 128 * Address Guest Virtual to Guest Physical
 129 *
 130 * Input Args:
 131 *   vm - Virtual Machine
 132 *   gva - VM virtual address
 133 *
 134 * Output Args: None
 135 *
 136 * Return:
 137 *   Equivalent VM physical address
 138 *
 139 * Returns the VM physical address of the translated VM virtual
 140 * address given by @gva.
 141 */
 142vm_paddr_t addr_gva2gpa(struct kvm_vm *vm, vm_vaddr_t gva);
 143
 144struct kvm_run *vcpu_state(struct kvm_vm *vm, uint32_t vcpuid);
 145void vcpu_run(struct kvm_vm *vm, uint32_t vcpuid);
 146int _vcpu_run(struct kvm_vm *vm, uint32_t vcpuid);
 147void vcpu_run_complete_io(struct kvm_vm *vm, uint32_t vcpuid);
 148void vcpu_set_guest_debug(struct kvm_vm *vm, uint32_t vcpuid,
 149                          struct kvm_guest_debug *debug);
 150void vcpu_set_mp_state(struct kvm_vm *vm, uint32_t vcpuid,
 151                       struct kvm_mp_state *mp_state);
 152void vcpu_regs_get(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_regs *regs);
 153void vcpu_regs_set(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_regs *regs);
 154
 155/*
 156 * VM VCPU Args Set
 157 *
 158 * Input Args:
 159 *   vm - Virtual Machine
 160 *   vcpuid - VCPU ID
 161 *   num - number of arguments
 162 *   ... - arguments, each of type uint64_t
 163 *
 164 * Output Args: None
 165 *
 166 * Return: None
 167 *
 168 * Sets the first @num function input registers of the VCPU with @vcpuid,
 169 * per the C calling convention of the architecture, to the values given
 170 * as variable args. Each of the variable args is expected to be of type
 171 * uint64_t. The maximum @num can be is specific to the architecture.
 172 */
 173void vcpu_args_set(struct kvm_vm *vm, uint32_t vcpuid, unsigned int num, ...);
 174
 175void vcpu_sregs_get(struct kvm_vm *vm, uint32_t vcpuid,
 176                    struct kvm_sregs *sregs);
 177void vcpu_sregs_set(struct kvm_vm *vm, uint32_t vcpuid,
 178                    struct kvm_sregs *sregs);
 179int _vcpu_sregs_set(struct kvm_vm *vm, uint32_t vcpuid,
 180                    struct kvm_sregs *sregs);
 181void vcpu_fpu_get(struct kvm_vm *vm, uint32_t vcpuid,
 182                  struct kvm_fpu *fpu);
 183void vcpu_fpu_set(struct kvm_vm *vm, uint32_t vcpuid,
 184                  struct kvm_fpu *fpu);
 185void vcpu_get_reg(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_one_reg *reg);
 186void vcpu_set_reg(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_one_reg *reg);
 187#ifdef __KVM_HAVE_VCPU_EVENTS
 188void vcpu_events_get(struct kvm_vm *vm, uint32_t vcpuid,
 189                     struct kvm_vcpu_events *events);
 190void vcpu_events_set(struct kvm_vm *vm, uint32_t vcpuid,
 191                     struct kvm_vcpu_events *events);
 192#endif
 193#ifdef __x86_64__
 194void vcpu_nested_state_get(struct kvm_vm *vm, uint32_t vcpuid,
 195                           struct kvm_nested_state *state);
 196int vcpu_nested_state_set(struct kvm_vm *vm, uint32_t vcpuid,
 197                          struct kvm_nested_state *state, bool ignore_error);
 198#endif
 199
 200const char *exit_reason_str(unsigned int exit_reason);
 201
 202void virt_pgd_alloc(struct kvm_vm *vm, uint32_t pgd_memslot);
 203
 204/*
 205 * VM Virtual Page Map
 206 *
 207 * Input Args:
 208 *   vm - Virtual Machine
 209 *   vaddr - VM Virtual Address
 210 *   paddr - VM Physical Address
 211 *   memslot - Memory region slot for new virtual translation tables
 212 *
 213 * Output Args: None
 214 *
 215 * Return: None
 216 *
 217 * Within @vm, creates a virtual translation for the page starting
 218 * at @vaddr to the page starting at @paddr.
 219 */
 220void virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr,
 221                 uint32_t memslot);
 222
 223vm_paddr_t vm_phy_page_alloc(struct kvm_vm *vm, vm_paddr_t paddr_min,
 224                             uint32_t memslot);
 225vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
 226                              vm_paddr_t paddr_min, uint32_t memslot);
 227
 228/*
 229 * Create a VM with reasonable defaults
 230 *
 231 * Input Args:
 232 *   vcpuid - The id of the single VCPU to add to the VM.
 233 *   extra_mem_pages - The number of extra pages to add (this will
 234 *                     decide how much extra space we will need to
 235 *                     setup the page tables using memslot 0)
 236 *   guest_code - The vCPU's entry point
 237 *
 238 * Output Args: None
 239 *
 240 * Return:
 241 *   Pointer to opaque structure that describes the created VM.
 242 */
 243struct kvm_vm *vm_create_default(uint32_t vcpuid, uint64_t extra_mem_pages,
 244                                 void *guest_code);
 245
 246/*
 247 * Adds a vCPU with reasonable defaults (e.g. a stack)
 248 *
 249 * Input Args:
 250 *   vm - Virtual Machine
 251 *   vcpuid - The id of the VCPU to add to the VM.
 252 *   guest_code - The vCPU's entry point
 253 */
 254void vm_vcpu_add_default(struct kvm_vm *vm, uint32_t vcpuid, void *guest_code);
 255
 256bool vm_is_unrestricted_guest(struct kvm_vm *vm);
 257
 258unsigned int vm_get_page_size(struct kvm_vm *vm);
 259unsigned int vm_get_page_shift(struct kvm_vm *vm);
 260unsigned int vm_get_max_gfn(struct kvm_vm *vm);
 261int vm_get_fd(struct kvm_vm *vm);
 262
 263unsigned int vm_calc_num_guest_pages(enum vm_guest_mode mode, size_t size);
 264unsigned int vm_num_host_pages(enum vm_guest_mode mode, unsigned int num_guest_pages);
 265unsigned int vm_num_guest_pages(enum vm_guest_mode mode, unsigned int num_host_pages);
 266static inline unsigned int
 267vm_adjust_num_guest_pages(enum vm_guest_mode mode, unsigned int num_guest_pages)
 268{
 269        unsigned int n;
 270        n = vm_num_guest_pages(mode, vm_num_host_pages(mode, num_guest_pages));
 271#ifdef __s390x__
 272        /* s390 requires 1M aligned guest sizes */
 273        n = (n + 255) & ~255;
 274#endif
 275        return n;
 276}
 277
 278struct kvm_userspace_memory_region *
 279kvm_userspace_memory_region_find(struct kvm_vm *vm, uint64_t start,
 280                                 uint64_t end);
 281
 282struct kvm_dirty_log *
 283allocate_kvm_dirty_log(struct kvm_userspace_memory_region *region);
 284
 285int vm_create_device(struct kvm_vm *vm, struct kvm_create_device *cd);
 286
 287#define sync_global_to_guest(vm, g) ({                          \
 288        typeof(g) *_p = addr_gva2hva(vm, (vm_vaddr_t)&(g));     \
 289        memcpy(_p, &(g), sizeof(g));                            \
 290})
 291
 292#define sync_global_from_guest(vm, g) ({                        \
 293        typeof(g) *_p = addr_gva2hva(vm, (vm_vaddr_t)&(g));     \
 294        memcpy(&(g), _p, sizeof(g));                            \
 295})
 296
 297/* Common ucalls */
 298enum {
 299        UCALL_NONE,
 300        UCALL_SYNC,
 301        UCALL_ABORT,
 302        UCALL_DONE,
 303};
 304
 305#define UCALL_MAX_ARGS 6
 306
 307struct ucall {
 308        uint64_t cmd;
 309        uint64_t args[UCALL_MAX_ARGS];
 310};
 311
 312void ucall_init(struct kvm_vm *vm, void *arg);
 313void ucall_uninit(struct kvm_vm *vm);
 314void ucall(uint64_t cmd, int nargs, ...);
 315uint64_t get_ucall(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc);
 316
 317#define GUEST_SYNC_ARGS(stage, arg1, arg2, arg3, arg4)  \
 318                                ucall(UCALL_SYNC, 6, "hello", stage, arg1, arg2, arg3, arg4)
 319#define GUEST_SYNC(stage)       ucall(UCALL_SYNC, 2, "hello", stage)
 320#define GUEST_DONE()            ucall(UCALL_DONE, 0)
 321#define __GUEST_ASSERT(_condition, _nargs, _args...) do {       \
 322        if (!(_condition))                                      \
 323                ucall(UCALL_ABORT, 2 + _nargs,                  \
 324                        "Failed guest assert: "                 \
 325                        #_condition, __LINE__, _args);          \
 326} while (0)
 327
 328#define GUEST_ASSERT(_condition) \
 329        __GUEST_ASSERT((_condition), 0, 0)
 330
 331#define GUEST_ASSERT_1(_condition, arg1) \
 332        __GUEST_ASSERT((_condition), 1, (arg1))
 333
 334#define GUEST_ASSERT_2(_condition, arg1, arg2) \
 335        __GUEST_ASSERT((_condition), 2, (arg1), (arg2))
 336
 337#define GUEST_ASSERT_3(_condition, arg1, arg2, arg3) \
 338        __GUEST_ASSERT((_condition), 3, (arg1), (arg2), (arg3))
 339
 340#define GUEST_ASSERT_4(_condition, arg1, arg2, arg3, arg4) \
 341        __GUEST_ASSERT((_condition), 4, (arg1), (arg2), (arg3), (arg4))
 342
 343#endif /* SELFTEST_KVM_UTIL_H */
 344