mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
KVM selftests treewide updates for 6.10:
- Define _GNU_SOURCE for all selftests to fix a warning that was introduced by a change to kselftest_harness.h late in the 6.9 cycle, and because forcing every test to #define _GNU_SOURCE is painful. - Provide a global psuedo-RNG instance for all tests, so that library code can generate random, but determinstic numbers. - Use the global pRNG to randomly force emulation of select writes from guest code on x86, e.g. to help validate KVM's emulation of locked accesses. - Rename kvm_util_base.h back to kvm_util.h, as the weird layer of indirection was added purely to avoid manually #including ucall_common.h in a handful of locations. - Allocate and initialize x86's GDT, IDT, TSS, segments, and default exception handlers at VM creation, instead of forcing tests to manually trigger the related setup. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEKTobbabEP7vbhhN9OlYIJqCjN/0FAmY+qhoACgkQOlYIJqCj N/2coRAAicA2485dlMjLbRazrb58dFiT8XheKKTHQwWRZPhxUMI8Rqo9Hp74t2tc hU1+VXIupzTH4hXxTmqrTtsJsulhdgbQMzxeefK9U8WxS2jsHnC5Ltx9hmGWQG92 FeUhkDka1zc52bhMGOY43A5rNxCfQ0GYCWdHnILw2tqWQhqAvEuma7CwVYm85zTe gl6Bfe1sokjnx1EIdwC4SyfDAh9DXIah02b7GvbTvkrNcLBpxnRp19mZlmSqSg9L 5VVPup2oSeKZAhXYP3dWgUGGJtT96tpz60QwkmVxcNIqvL41CsmW7wB9ODzYlihQ uBmlchx9NIR9+ICL2DaZi5UfmrfeRW2sYVH9K0NewDswV8N36/pMabN+gWCKjZ7m 5K99nY6xtVmTkxdgJEQ1n4+oa2VTD68H52/hwvO5e6Kd1yab+SKoBf4LKxXu6gO7 P2hcM+FGwJlSU6gmI7B4+2RNFPurplVgC5MN7cJuEivKXhTXL8GzbOCxsRhCynIk z+L+nnrSRiXAD45uYon1UIXLszANYfjizx7/fL5hC2mtpARP9S35zIDCCzEBNWWt VI30/O0GAH/d6p1Rows/DzPmFJKbc+YVHoW9Ck8OP9axQHZuFoj6Qdy8BSwb8O+u B0rJXUyVFh2jwZ2zkMPDnDS5FOhqmTXxZSNj+i5tX/BZus7Iews= =vsRz -----END PGP SIGNATURE----- Merge tag 'kvm-x86-selftests_utils-6.10' of https://github.com/kvm-x86/linux into HEAD KVM selftests treewide updates for 6.10: - Define _GNU_SOURCE for all selftests to fix a warning that was introduced by a change to kselftest_harness.h late in the 6.9 cycle, and because forcing every test to #define _GNU_SOURCE is painful. - Provide a global psuedo-RNG instance for all tests, so that library code can generate random, but determinstic numbers. - Use the global pRNG to randomly force emulation of select writes from guest code on x86, e.g. to help validate KVM's emulation of locked accesses. - Rename kvm_util_base.h back to kvm_util.h, as the weird layer of indirection was added purely to avoid manually #including ucall_common.h in a handful of locations. - Allocate and initialize x86's GDT, IDT, TSS, segments, and default exception handlers at VM creation, instead of forcing tests to manually trigger the related setup.
This commit is contained in:
commit
dee7ea42a1
@ -230,8 +230,8 @@ LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/$(ARCH)/include
|
||||
endif
|
||||
CFLAGS += -Wall -Wstrict-prototypes -Wuninitialized -O2 -g -std=gnu99 \
|
||||
-Wno-gnu-variable-sized-type-not-at-end -MD -MP -DCONFIG_64BIT \
|
||||
-fno-builtin-memcmp -fno-builtin-memcpy -fno-builtin-memset \
|
||||
-fno-builtin-strnlen \
|
||||
-D_GNU_SOURCE -fno-builtin-memcmp -fno-builtin-memcpy \
|
||||
-fno-builtin-memset -fno-builtin-strnlen \
|
||||
-fno-stack-protector -fno-PIE -I$(LINUX_TOOL_INCLUDE) \
|
||||
-I$(LINUX_TOOL_ARCH_INCLUDE) -I$(LINUX_HDR_PATH) -Iinclude \
|
||||
-I$(<D) -Iinclude/$(ARCH_DIR) -I ../rseq -I.. $(EXTRA_CFLAGS) \
|
||||
|
@ -5,13 +5,12 @@
|
||||
*
|
||||
* Copyright (c) 2021, Google LLC.
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "arch_timer.h"
|
||||
#include "delay.h"
|
||||
#include "gic.h"
|
||||
#include "processor.h"
|
||||
#include "timer_test.h"
|
||||
#include "ucall_common.h"
|
||||
#include "vgic.h"
|
||||
|
||||
enum guest_stage {
|
||||
|
@ -7,7 +7,6 @@
|
||||
* hugetlbfs with a hole). It checks that the expected handling method is
|
||||
* called (e.g., uffd faults with the right address and write/read flag).
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
#include <linux/bitmap.h>
|
||||
#include <fcntl.h>
|
||||
#include <test_util.h>
|
||||
|
@ -11,8 +11,6 @@
|
||||
* KVM_SYSTEM_EVENT_SUSPEND UAPI.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/psci.h>
|
||||
#include <asm/cputype.h>
|
||||
|
@ -4,7 +4,6 @@
|
||||
*
|
||||
* Copyright (C) 2020, Red Hat, Inc.
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
#include <linux/kernel.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <asm/kvm.h>
|
||||
|
@ -19,9 +19,6 @@
|
||||
*
|
||||
* Copyright (c) 2021, Google LLC.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <linux/sizes.h>
|
||||
@ -29,6 +26,7 @@
|
||||
#include <sys/sysinfo.h>
|
||||
|
||||
#include "timer_test.h"
|
||||
#include "ucall_common.h"
|
||||
|
||||
struct test_args test_args = {
|
||||
.nr_vcpus = NR_VCPUS_DEF,
|
||||
|
@ -6,9 +6,6 @@
|
||||
* Copyright (C) 2018, Red Hat, Inc.
|
||||
* Copyright (C) 2019, Google, Inc.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for pipe2 */
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -21,6 +18,7 @@
|
||||
#include "test_util.h"
|
||||
#include "memstress.h"
|
||||
#include "guest_modes.h"
|
||||
#include "ucall_common.h"
|
||||
#include "userfaultfd_util.h"
|
||||
|
||||
#ifdef __NR_userfaultfd
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "test_util.h"
|
||||
#include "memstress.h"
|
||||
#include "guest_modes.h"
|
||||
#include "ucall_common.h"
|
||||
|
||||
#ifdef __aarch64__
|
||||
#include "aarch64/vgic.h"
|
||||
@ -129,7 +130,6 @@ struct test_params {
|
||||
enum vm_mem_backing_src_type backing_src;
|
||||
int slots;
|
||||
uint32_t write_percent;
|
||||
uint32_t random_seed;
|
||||
bool random_access;
|
||||
};
|
||||
|
||||
@ -153,8 +153,6 @@ static void run_test(enum vm_guest_mode mode, void *arg)
|
||||
p->slots, p->backing_src,
|
||||
p->partition_vcpu_memory_access);
|
||||
|
||||
pr_info("Random seed: %u\n", p->random_seed);
|
||||
memstress_set_random_seed(vm, p->random_seed);
|
||||
memstress_set_write_percent(vm, p->write_percent);
|
||||
|
||||
guest_num_pages = (nr_vcpus * guest_percpu_mem_size) >> vm->page_shift;
|
||||
@ -343,11 +341,13 @@ int main(int argc, char *argv[])
|
||||
.partition_vcpu_memory_access = true,
|
||||
.backing_src = DEFAULT_VM_MEM_SRC,
|
||||
.slots = 1,
|
||||
.random_seed = 1,
|
||||
.write_percent = 100,
|
||||
};
|
||||
int opt;
|
||||
|
||||
/* Override the seed to be deterministic by default. */
|
||||
guest_random_seed = 1;
|
||||
|
||||
dirty_log_manual_caps =
|
||||
kvm_check_cap(KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2);
|
||||
dirty_log_manual_caps &= (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE |
|
||||
@ -392,7 +392,7 @@ int main(int argc, char *argv[])
|
||||
p.phys_offset = strtoull(optarg, NULL, 0);
|
||||
break;
|
||||
case 'r':
|
||||
p.random_seed = atoi_positive("Random seed", optarg);
|
||||
guest_random_seed = atoi_positive("Random seed", optarg);
|
||||
break;
|
||||
case 's':
|
||||
p.backing_src = parse_backing_src_type(optarg);
|
||||
|
@ -4,9 +4,6 @@
|
||||
*
|
||||
* Copyright (C) 2018, Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for program_invocation_name */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
@ -23,6 +20,7 @@
|
||||
#include "test_util.h"
|
||||
#include "guest_modes.h"
|
||||
#include "processor.h"
|
||||
#include "ucall_common.h"
|
||||
|
||||
#define DIRTY_MEM_BITS 30 /* 1G */
|
||||
#define PAGE_SHIFT_4K 12
|
||||
@ -76,7 +74,6 @@
|
||||
static uint64_t host_page_size;
|
||||
static uint64_t guest_page_size;
|
||||
static uint64_t guest_num_pages;
|
||||
static uint64_t random_array[TEST_PAGES_PER_LOOP];
|
||||
static uint64_t iteration;
|
||||
|
||||
/*
|
||||
@ -109,19 +106,19 @@ static void guest_code(void)
|
||||
*/
|
||||
for (i = 0; i < guest_num_pages; i++) {
|
||||
addr = guest_test_virt_mem + i * guest_page_size;
|
||||
*(uint64_t *)addr = READ_ONCE(iteration);
|
||||
vcpu_arch_put_guest(*(uint64_t *)addr, READ_ONCE(iteration));
|
||||
}
|
||||
|
||||
while (true) {
|
||||
for (i = 0; i < TEST_PAGES_PER_LOOP; i++) {
|
||||
addr = guest_test_virt_mem;
|
||||
addr += (READ_ONCE(random_array[i]) % guest_num_pages)
|
||||
addr += (guest_random_u64(&guest_rng) % guest_num_pages)
|
||||
* guest_page_size;
|
||||
addr = align_down(addr, host_page_size);
|
||||
*(uint64_t *)addr = READ_ONCE(iteration);
|
||||
|
||||
vcpu_arch_put_guest(*(uint64_t *)addr, READ_ONCE(iteration));
|
||||
}
|
||||
|
||||
/* Tell the host that we need more random numbers */
|
||||
GUEST_SYNC(1);
|
||||
}
|
||||
}
|
||||
@ -508,20 +505,10 @@ static void log_mode_after_vcpu_run(struct kvm_vcpu *vcpu, int ret, int err)
|
||||
mode->after_vcpu_run(vcpu, ret, err);
|
||||
}
|
||||
|
||||
static void generate_random_array(uint64_t *guest_array, uint64_t size)
|
||||
{
|
||||
uint64_t i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
guest_array[i] = random();
|
||||
}
|
||||
|
||||
static void *vcpu_worker(void *data)
|
||||
{
|
||||
int ret;
|
||||
struct kvm_vcpu *vcpu = data;
|
||||
struct kvm_vm *vm = vcpu->vm;
|
||||
uint64_t *guest_array;
|
||||
uint64_t pages_count = 0;
|
||||
struct kvm_signal_mask *sigmask = alloca(offsetof(struct kvm_signal_mask, sigset)
|
||||
+ sizeof(sigset_t));
|
||||
@ -540,11 +527,8 @@ static void *vcpu_worker(void *data)
|
||||
sigemptyset(sigset);
|
||||
sigaddset(sigset, SIG_IPI);
|
||||
|
||||
guest_array = addr_gva2hva(vm, (vm_vaddr_t)random_array);
|
||||
|
||||
while (!READ_ONCE(host_quit)) {
|
||||
/* Clear any existing kick signals */
|
||||
generate_random_array(guest_array, TEST_PAGES_PER_LOOP);
|
||||
pages_count += TEST_PAGES_PER_LOOP;
|
||||
/* Let the guest dirty the random pages */
|
||||
ret = __vcpu_run(vcpu);
|
||||
|
@ -4,8 +4,6 @@
|
||||
*
|
||||
* Author: Chao Peng <chao.p.peng@linux.intel.com>
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
@ -19,8 +17,8 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "kvm_util.h"
|
||||
#include "test_util.h"
|
||||
#include "kvm_util_base.h"
|
||||
|
||||
static void test_file_read_write(int fd)
|
||||
{
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "test_util.h"
|
||||
#include "kvm_util.h"
|
||||
#include "processor.h"
|
||||
#include "ucall_common.h"
|
||||
|
||||
struct guest_vals {
|
||||
uint64_t a;
|
||||
|
@ -4,9 +4,6 @@
|
||||
* kvm_arch_hardware_disable is called and it attempts to unregister the user
|
||||
* return notifiers.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
|
@ -8,6 +8,8 @@
|
||||
#define SELFTEST_KVM_PROCESSOR_H
|
||||
|
||||
#include "kvm_util.h"
|
||||
#include "ucall_common.h"
|
||||
|
||||
#include <linux/stringify.h>
|
||||
#include <linux/types.h>
|
||||
#include <asm/sysreg.h>
|
||||
|
@ -2,7 +2,7 @@
|
||||
#ifndef SELFTEST_KVM_UCALL_H
|
||||
#define SELFTEST_KVM_UCALL_H
|
||||
|
||||
#include "kvm_util_base.h"
|
||||
#include "kvm_util.h"
|
||||
|
||||
#define UCALL_EXIT_REASON KVM_EXIT_MMIO
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -27,12 +27,12 @@
|
||||
|
||||
/*
|
||||
* Provide a version of static_assert() that is guaranteed to have an optional
|
||||
* message param. If _ISOC11_SOURCE is defined, glibc (/usr/include/assert.h)
|
||||
* #undefs and #defines static_assert() as a direct alias to _Static_assert(),
|
||||
* i.e. effectively makes the message mandatory. Many KVM selftests #define
|
||||
* _GNU_SOURCE for various reasons, and _GNU_SOURCE implies _ISOC11_SOURCE. As
|
||||
* a result, static_assert() behavior is non-deterministic and may or may not
|
||||
* require a message depending on #include order.
|
||||
* message param. _GNU_SOURCE is defined for all KVM selftests, _GNU_SOURCE
|
||||
* implies _ISOC11_SOURCE, and if _ISOC11_SOURCE is defined, glibc #undefs and
|
||||
* #defines static_assert() as a direct alias to _Static_assert() (see
|
||||
* usr/include/assert.h). Define a custom macro instead of redefining
|
||||
* static_assert() to avoid creating non-deterministic behavior that is
|
||||
* dependent on include order.
|
||||
*/
|
||||
#define __kvm_static_assert(expr, msg, ...) _Static_assert(expr, msg)
|
||||
#define kvm_static_assert(expr, ...) __kvm_static_assert(expr, ##__VA_ARGS__, #expr)
|
||||
@ -609,6 +609,9 @@ void *addr_gva2hva(struct kvm_vm *vm, vm_vaddr_t gva);
|
||||
vm_paddr_t addr_hva2gpa(struct kvm_vm *vm, void *hva);
|
||||
void *addr_gpa2alias(struct kvm_vm *vm, vm_paddr_t gpa);
|
||||
|
||||
#ifndef vcpu_arch_put_guest
|
||||
#define vcpu_arch_put_guest(mem, val) do { (mem) = (val); } while (0)
|
||||
#endif
|
||||
|
||||
static inline vm_paddr_t vm_untag_gpa(struct kvm_vm *vm, vm_paddr_t gpa)
|
||||
{
|
||||
|
20
tools/testing/selftests/kvm/include/kvm_util_types.h
Normal file
20
tools/testing/selftests/kvm/include/kvm_util_types.h
Normal file
@ -0,0 +1,20 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
#ifndef SELFTEST_KVM_UTIL_TYPES_H
|
||||
#define SELFTEST_KVM_UTIL_TYPES_H
|
||||
|
||||
/*
|
||||
* Provide a version of static_assert() that is guaranteed to have an optional
|
||||
* message param. _GNU_SOURCE is defined for all KVM selftests, _GNU_SOURCE
|
||||
* implies _ISOC11_SOURCE, and if _ISOC11_SOURCE is defined, glibc #undefs and
|
||||
* #defines static_assert() as a direct alias to _Static_assert() (see
|
||||
* usr/include/assert.h). Define a custom macro instead of redefining
|
||||
* static_assert() to avoid creating non-deterministic behavior that is
|
||||
* dependent on include order.
|
||||
*/
|
||||
#define __kvm_static_assert(expr, msg, ...) _Static_assert(expr, msg)
|
||||
#define kvm_static_assert(expr, ...) __kvm_static_assert(expr, ##__VA_ARGS__, #expr)
|
||||
|
||||
typedef uint64_t vm_paddr_t; /* Virtual Machine (Guest) physical address */
|
||||
typedef uint64_t vm_vaddr_t; /* Virtual Machine (Guest) virtual address */
|
||||
|
||||
#endif /* SELFTEST_KVM_UTIL_TYPES_H */
|
@ -62,7 +62,6 @@ struct kvm_vm *memstress_create_vm(enum vm_guest_mode mode, int nr_vcpus,
|
||||
void memstress_destroy_vm(struct kvm_vm *vm);
|
||||
|
||||
void memstress_set_write_percent(struct kvm_vm *vm, uint32_t write_percent);
|
||||
void memstress_set_random_seed(struct kvm_vm *vm, uint32_t random_seed);
|
||||
void memstress_set_random_access(struct kvm_vm *vm, bool random_access);
|
||||
|
||||
void memstress_start_vcpu_threads(int vcpus, void (*vcpu_fn)(struct memstress_vcpu_args *));
|
||||
|
@ -2,7 +2,7 @@
|
||||
#ifndef SELFTEST_KVM_UCALL_H
|
||||
#define SELFTEST_KVM_UCALL_H
|
||||
|
||||
#include "kvm_util_base.h"
|
||||
#include "kvm_util.h"
|
||||
|
||||
#define UCALL_EXIT_REASON KVM_EXIT_S390_SIEIC
|
||||
|
||||
|
@ -91,9 +91,28 @@ struct guest_random_state {
|
||||
uint32_t seed;
|
||||
};
|
||||
|
||||
extern uint32_t guest_random_seed;
|
||||
extern struct guest_random_state guest_rng;
|
||||
|
||||
struct guest_random_state new_guest_random_state(uint32_t seed);
|
||||
uint32_t guest_random_u32(struct guest_random_state *state);
|
||||
|
||||
static inline bool __guest_random_bool(struct guest_random_state *state,
|
||||
uint8_t percent)
|
||||
{
|
||||
return (guest_random_u32(state) % 100) < percent;
|
||||
}
|
||||
|
||||
static inline bool guest_random_bool(struct guest_random_state *state)
|
||||
{
|
||||
return __guest_random_bool(state, 50);
|
||||
}
|
||||
|
||||
static inline uint64_t guest_random_u64(struct guest_random_state *state)
|
||||
{
|
||||
return ((uint64_t)guest_random_u32(state) << 32) | guest_random_u32(state);
|
||||
}
|
||||
|
||||
enum vm_mem_backing_src_type {
|
||||
VM_MEM_SRC_ANONYMOUS,
|
||||
VM_MEM_SRC_ANONYMOUS_THP,
|
||||
|
@ -5,9 +5,6 @@
|
||||
* Copyright (C) 2018, Red Hat, Inc.
|
||||
* Copyright (C) 2019-2022 Google LLC
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for pipe2 */
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <time.h>
|
||||
#include <pthread.h>
|
||||
|
@ -5,7 +5,16 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "kvm_util_types.h"
|
||||
#include "test_util.h"
|
||||
|
||||
extern bool is_forced_emulation_enabled;
|
||||
|
||||
struct kvm_vm_arch {
|
||||
vm_vaddr_t gdt;
|
||||
vm_vaddr_t tss;
|
||||
vm_vaddr_t idt;
|
||||
|
||||
uint64_t c_bit;
|
||||
uint64_t s_bit;
|
||||
int sev_fd;
|
||||
@ -20,4 +29,23 @@ static inline bool __vm_arch_has_protected_memory(struct kvm_vm_arch *arch)
|
||||
#define vm_arch_has_protected_memory(vm) \
|
||||
__vm_arch_has_protected_memory(&(vm)->arch)
|
||||
|
||||
#define vcpu_arch_put_guest(mem, __val) \
|
||||
do { \
|
||||
const typeof(mem) val = (__val); \
|
||||
\
|
||||
if (!is_forced_emulation_enabled || guest_random_bool(&guest_rng)) { \
|
||||
(mem) = val; \
|
||||
} else if (guest_random_bool(&guest_rng)) { \
|
||||
__asm__ __volatile__(KVM_FEP "mov %1, %0" \
|
||||
: "+m" (mem) \
|
||||
: "r" (val) : "memory"); \
|
||||
} else { \
|
||||
uint64_t __old = READ_ONCE(mem); \
|
||||
\
|
||||
__asm__ __volatile__(KVM_FEP LOCK_PREFIX "cmpxchg %[new], %[ptr]" \
|
||||
: [ptr] "+m" (mem), [old] "+a" (__old) \
|
||||
: [new]"r" (val) : "memory", "cc"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif // SELFTEST_KVM_UTIL_ARCH_H
|
||||
|
@ -18,7 +18,8 @@
|
||||
#include <linux/kvm_para.h>
|
||||
#include <linux/stringify.h>
|
||||
|
||||
#include "../kvm_util.h"
|
||||
#include "kvm_util.h"
|
||||
#include "ucall_common.h"
|
||||
|
||||
extern bool host_cpu_is_intel;
|
||||
extern bool host_cpu_is_amd;
|
||||
@ -1133,8 +1134,6 @@ struct idt_entry {
|
||||
uint32_t offset2; uint32_t reserved;
|
||||
};
|
||||
|
||||
void vm_init_descriptor_tables(struct kvm_vm *vm);
|
||||
void vcpu_init_descriptor_tables(struct kvm_vcpu *vcpu);
|
||||
void vm_install_exception_handler(struct kvm_vm *vm, int vector,
|
||||
void (*handler)(struct ex_regs *));
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
#ifndef SELFTEST_KVM_UCALL_H
|
||||
#define SELFTEST_KVM_UCALL_H
|
||||
|
||||
#include "kvm_util_base.h"
|
||||
#include "kvm_util.h"
|
||||
|
||||
#define UCALL_EXIT_REASON KVM_EXIT_IO
|
||||
|
||||
|
@ -6,8 +6,6 @@
|
||||
*
|
||||
* Test the fd-based interface for KVM statistics.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -6,8 +6,6 @@
|
||||
*
|
||||
* Test for KVM_CAP_MAX_VCPUS and KVM_CAP_MAX_VCPU_ID.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -8,9 +8,6 @@
|
||||
* page size have been pre-allocated on your system, if you are planning to
|
||||
* use hugepages to back the guest memory for testing.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for program_invocation_name */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
@ -21,6 +18,7 @@
|
||||
#include "kvm_util.h"
|
||||
#include "processor.h"
|
||||
#include "guest_modes.h"
|
||||
#include "ucall_common.h"
|
||||
|
||||
#define TEST_MEM_SLOT_INDEX 1
|
||||
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include "guest_modes.h"
|
||||
#include "kvm_util.h"
|
||||
#include "processor.h"
|
||||
#include "ucall_common.h"
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/sizes.h>
|
||||
|
||||
|
@ -4,9 +4,6 @@
|
||||
*
|
||||
* Copyright (C) 2018, Google LLC.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for getline(3) and strchrnul(3)*/
|
||||
|
||||
#include "test_util.h"
|
||||
|
||||
#include <execinfo.h>
|
||||
|
@ -4,11 +4,10 @@
|
||||
*
|
||||
* Copyright (C) 2018, Google LLC.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for program_invocation_name */
|
||||
#include "test_util.h"
|
||||
#include "kvm_util.h"
|
||||
#include "processor.h"
|
||||
#include "ucall_common.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <sched.h>
|
||||
@ -20,6 +19,9 @@
|
||||
|
||||
#define KVM_UTIL_MIN_PFN 2
|
||||
|
||||
uint32_t guest_random_seed;
|
||||
struct guest_random_state guest_rng;
|
||||
|
||||
static int vcpu_mmap_sz(void);
|
||||
|
||||
int open_path_or_exit(const char *path, int flags)
|
||||
@ -432,6 +434,10 @@ struct kvm_vm *__vm_create(struct vm_shape shape, uint32_t nr_runnable_vcpus,
|
||||
slot0 = memslot2region(vm, 0);
|
||||
ucall_init(vm, slot0->region.guest_phys_addr + slot0->region.memory_size);
|
||||
|
||||
pr_info("Random seed: 0x%x\n", guest_random_seed);
|
||||
guest_rng = new_guest_random_state(guest_random_seed);
|
||||
sync_global_to_guest(vm, guest_rng);
|
||||
|
||||
kvm_arch_vm_post_create(vm);
|
||||
|
||||
return vm;
|
||||
@ -2313,6 +2319,8 @@ void __attribute((constructor)) kvm_selftest_init(void)
|
||||
/* Tell stdout not to buffer its content. */
|
||||
setbuf(stdout, NULL);
|
||||
|
||||
guest_random_seed = random();
|
||||
|
||||
kvm_selftest_arch_init();
|
||||
}
|
||||
|
||||
|
@ -2,14 +2,13 @@
|
||||
/*
|
||||
* Copyright (C) 2020, Google LLC.
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <linux/bitmap.h>
|
||||
|
||||
#include "kvm_util.h"
|
||||
#include "memstress.h"
|
||||
#include "processor.h"
|
||||
#include "ucall_common.h"
|
||||
|
||||
struct memstress_args memstress_args;
|
||||
|
||||
@ -56,7 +55,7 @@ void memstress_guest_code(uint32_t vcpu_idx)
|
||||
uint64_t page;
|
||||
int i;
|
||||
|
||||
rand_state = new_guest_random_state(args->random_seed + vcpu_idx);
|
||||
rand_state = new_guest_random_state(guest_random_seed + vcpu_idx);
|
||||
|
||||
gva = vcpu_args->gva;
|
||||
pages = vcpu_args->pages;
|
||||
@ -76,7 +75,7 @@ void memstress_guest_code(uint32_t vcpu_idx)
|
||||
|
||||
addr = gva + (page * args->guest_page_size);
|
||||
|
||||
if (guest_random_u32(&rand_state) % 100 < args->write_percent)
|
||||
if (__guest_random_bool(&rand_state, args->write_percent))
|
||||
*(uint64_t *)addr = 0x0123456789ABCDEF;
|
||||
else
|
||||
READ_ONCE(*(uint64_t *)addr);
|
||||
@ -243,12 +242,6 @@ void memstress_set_write_percent(struct kvm_vm *vm, uint32_t write_percent)
|
||||
sync_global_to_guest(vm, memstress_args.write_percent);
|
||||
}
|
||||
|
||||
void memstress_set_random_seed(struct kvm_vm *vm, uint32_t random_seed)
|
||||
{
|
||||
memstress_args.random_seed = random_seed;
|
||||
sync_global_to_guest(vm, memstress_args.random_seed);
|
||||
}
|
||||
|
||||
void memstress_set_random_access(struct kvm_vm *vm, bool random_access)
|
||||
{
|
||||
memstress_args.random_access = random_access;
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "kvm_util.h"
|
||||
#include "processor.h"
|
||||
#include "ucall_common.h"
|
||||
|
||||
#define DEFAULT_RISCV_GUEST_STACK_VADDR_MIN 0xac0000
|
||||
|
||||
|
@ -4,8 +4,6 @@
|
||||
*
|
||||
* Copyright (C) 2020, Google LLC.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
|
@ -1,9 +1,12 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
#include "kvm_util.h"
|
||||
#include "linux/types.h"
|
||||
#include "linux/bitmap.h"
|
||||
#include "linux/atomic.h"
|
||||
|
||||
#include "kvm_util.h"
|
||||
#include "ucall_common.h"
|
||||
|
||||
|
||||
#define GUEST_UCALL_FAILED -1
|
||||
|
||||
struct ucall_header {
|
||||
|
@ -6,9 +6,6 @@
|
||||
* Copyright (C) 2018, Red Hat, Inc.
|
||||
* Copyright (C) 2019-2022 Google LLC
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for pipe2 */
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -15,14 +15,16 @@
|
||||
#define NUM_INTERRUPTS 256
|
||||
#endif
|
||||
|
||||
#define DEFAULT_CODE_SELECTOR 0x8
|
||||
#define DEFAULT_DATA_SELECTOR 0x10
|
||||
#define KERNEL_CS 0x8
|
||||
#define KERNEL_DS 0x10
|
||||
#define KERNEL_TSS 0x18
|
||||
|
||||
#define MAX_NR_CPUID_ENTRIES 100
|
||||
|
||||
vm_vaddr_t exception_handlers;
|
||||
bool host_cpu_is_amd;
|
||||
bool host_cpu_is_intel;
|
||||
bool is_forced_emulation_enabled;
|
||||
|
||||
static void regs_dump(FILE *stream, struct kvm_regs *regs, uint8_t indent)
|
||||
{
|
||||
@ -417,7 +419,7 @@ static void kvm_seg_set_unusable(struct kvm_segment *segp)
|
||||
|
||||
static void kvm_seg_fill_gdt_64bit(struct kvm_vm *vm, struct kvm_segment *segp)
|
||||
{
|
||||
void *gdt = addr_gva2hva(vm, vm->gdt);
|
||||
void *gdt = addr_gva2hva(vm, vm->arch.gdt);
|
||||
struct desc64 *desc = gdt + (segp->selector >> 3) * 8;
|
||||
|
||||
desc->limit0 = segp->limit & 0xFFFF;
|
||||
@ -437,27 +439,10 @@ static void kvm_seg_fill_gdt_64bit(struct kvm_vm *vm, struct kvm_segment *segp)
|
||||
desc->base3 = segp->base >> 32;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set Long Mode Flat Kernel Code Segment
|
||||
*
|
||||
* Input Args:
|
||||
* vm - VM whose GDT is being filled, or NULL to only write segp
|
||||
* selector - selector value
|
||||
*
|
||||
* Output Args:
|
||||
* segp - Pointer to KVM segment
|
||||
*
|
||||
* Return: None
|
||||
*
|
||||
* Sets up the KVM segment pointed to by @segp, to be a code segment
|
||||
* with the selector value given by @selector.
|
||||
*/
|
||||
static void kvm_seg_set_kernel_code_64bit(struct kvm_vm *vm, uint16_t selector,
|
||||
struct kvm_segment *segp)
|
||||
static void kvm_seg_set_kernel_code_64bit(struct kvm_segment *segp)
|
||||
{
|
||||
memset(segp, 0, sizeof(*segp));
|
||||
segp->selector = selector;
|
||||
segp->selector = KERNEL_CS;
|
||||
segp->limit = 0xFFFFFFFFu;
|
||||
segp->s = 0x1; /* kTypeCodeData */
|
||||
segp->type = 0x08 | 0x01 | 0x02; /* kFlagCode | kFlagCodeAccessed
|
||||
@ -466,30 +451,12 @@ static void kvm_seg_set_kernel_code_64bit(struct kvm_vm *vm, uint16_t selector,
|
||||
segp->g = true;
|
||||
segp->l = true;
|
||||
segp->present = 1;
|
||||
if (vm)
|
||||
kvm_seg_fill_gdt_64bit(vm, segp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set Long Mode Flat Kernel Data Segment
|
||||
*
|
||||
* Input Args:
|
||||
* vm - VM whose GDT is being filled, or NULL to only write segp
|
||||
* selector - selector value
|
||||
*
|
||||
* Output Args:
|
||||
* segp - Pointer to KVM segment
|
||||
*
|
||||
* Return: None
|
||||
*
|
||||
* Sets up the KVM segment pointed to by @segp, to be a data segment
|
||||
* with the selector value given by @selector.
|
||||
*/
|
||||
static void kvm_seg_set_kernel_data_64bit(struct kvm_vm *vm, uint16_t selector,
|
||||
struct kvm_segment *segp)
|
||||
static void kvm_seg_set_kernel_data_64bit(struct kvm_segment *segp)
|
||||
{
|
||||
memset(segp, 0, sizeof(*segp));
|
||||
segp->selector = selector;
|
||||
segp->selector = KERNEL_DS;
|
||||
segp->limit = 0xFFFFFFFFu;
|
||||
segp->s = 0x1; /* kTypeCodeData */
|
||||
segp->type = 0x00 | 0x01 | 0x02; /* kFlagData | kFlagDataAccessed
|
||||
@ -497,8 +464,6 @@ static void kvm_seg_set_kernel_data_64bit(struct kvm_vm *vm, uint16_t selector,
|
||||
*/
|
||||
segp->g = true;
|
||||
segp->present = true;
|
||||
if (vm)
|
||||
kvm_seg_fill_gdt_64bit(vm, segp);
|
||||
}
|
||||
|
||||
vm_paddr_t addr_arch_gva2gpa(struct kvm_vm *vm, vm_vaddr_t gva)
|
||||
@ -516,67 +481,147 @@ vm_paddr_t addr_arch_gva2gpa(struct kvm_vm *vm, vm_vaddr_t gva)
|
||||
return vm_untag_gpa(vm, PTE_GET_PA(*pte)) | (gva & ~HUGEPAGE_MASK(level));
|
||||
}
|
||||
|
||||
static void kvm_setup_gdt(struct kvm_vm *vm, struct kvm_dtable *dt)
|
||||
static void kvm_seg_set_tss_64bit(vm_vaddr_t base, struct kvm_segment *segp)
|
||||
{
|
||||
if (!vm->gdt)
|
||||
vm->gdt = __vm_vaddr_alloc_page(vm, MEM_REGION_DATA);
|
||||
|
||||
dt->base = vm->gdt;
|
||||
dt->limit = getpagesize();
|
||||
}
|
||||
|
||||
static void kvm_setup_tss_64bit(struct kvm_vm *vm, struct kvm_segment *segp,
|
||||
int selector)
|
||||
{
|
||||
if (!vm->tss)
|
||||
vm->tss = __vm_vaddr_alloc_page(vm, MEM_REGION_DATA);
|
||||
|
||||
memset(segp, 0, sizeof(*segp));
|
||||
segp->base = vm->tss;
|
||||
segp->base = base;
|
||||
segp->limit = 0x67;
|
||||
segp->selector = selector;
|
||||
segp->selector = KERNEL_TSS;
|
||||
segp->type = 0xb;
|
||||
segp->present = 1;
|
||||
kvm_seg_fill_gdt_64bit(vm, segp);
|
||||
}
|
||||
|
||||
static void vcpu_setup(struct kvm_vm *vm, struct kvm_vcpu *vcpu)
|
||||
static void vcpu_init_sregs(struct kvm_vm *vm, struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm_sregs sregs;
|
||||
|
||||
TEST_ASSERT_EQ(vm->mode, VM_MODE_PXXV48_4K);
|
||||
|
||||
/* Set mode specific system register values. */
|
||||
vcpu_sregs_get(vcpu, &sregs);
|
||||
|
||||
sregs.idt.limit = 0;
|
||||
sregs.idt.base = vm->arch.idt;
|
||||
sregs.idt.limit = NUM_INTERRUPTS * sizeof(struct idt_entry) - 1;
|
||||
sregs.gdt.base = vm->arch.gdt;
|
||||
sregs.gdt.limit = getpagesize() - 1;
|
||||
|
||||
kvm_setup_gdt(vm, &sregs.gdt);
|
||||
|
||||
switch (vm->mode) {
|
||||
case VM_MODE_PXXV48_4K:
|
||||
sregs.cr0 = X86_CR0_PE | X86_CR0_NE | X86_CR0_PG;
|
||||
sregs.cr4 |= X86_CR4_PAE | X86_CR4_OSFXSR;
|
||||
sregs.efer |= (EFER_LME | EFER_LMA | EFER_NX);
|
||||
|
||||
kvm_seg_set_unusable(&sregs.ldt);
|
||||
kvm_seg_set_kernel_code_64bit(vm, DEFAULT_CODE_SELECTOR, &sregs.cs);
|
||||
kvm_seg_set_kernel_data_64bit(vm, DEFAULT_DATA_SELECTOR, &sregs.ds);
|
||||
kvm_seg_set_kernel_data_64bit(vm, DEFAULT_DATA_SELECTOR, &sregs.es);
|
||||
kvm_setup_tss_64bit(vm, &sregs.tr, 0x18);
|
||||
break;
|
||||
|
||||
default:
|
||||
TEST_FAIL("Unknown guest mode, mode: 0x%x", vm->mode);
|
||||
}
|
||||
kvm_seg_set_kernel_code_64bit(&sregs.cs);
|
||||
kvm_seg_set_kernel_data_64bit(&sregs.ds);
|
||||
kvm_seg_set_kernel_data_64bit(&sregs.es);
|
||||
kvm_seg_set_kernel_data_64bit(&sregs.gs);
|
||||
kvm_seg_set_tss_64bit(vm->arch.tss, &sregs.tr);
|
||||
|
||||
sregs.cr3 = vm->pgd;
|
||||
vcpu_sregs_set(vcpu, &sregs);
|
||||
}
|
||||
|
||||
static void set_idt_entry(struct kvm_vm *vm, int vector, unsigned long addr,
|
||||
int dpl, unsigned short selector)
|
||||
{
|
||||
struct idt_entry *base =
|
||||
(struct idt_entry *)addr_gva2hva(vm, vm->arch.idt);
|
||||
struct idt_entry *e = &base[vector];
|
||||
|
||||
memset(e, 0, sizeof(*e));
|
||||
e->offset0 = addr;
|
||||
e->selector = selector;
|
||||
e->ist = 0;
|
||||
e->type = 14;
|
||||
e->dpl = dpl;
|
||||
e->p = 1;
|
||||
e->offset1 = addr >> 16;
|
||||
e->offset2 = addr >> 32;
|
||||
}
|
||||
|
||||
static bool kvm_fixup_exception(struct ex_regs *regs)
|
||||
{
|
||||
if (regs->r9 != KVM_EXCEPTION_MAGIC || regs->rip != regs->r10)
|
||||
return false;
|
||||
|
||||
if (regs->vector == DE_VECTOR)
|
||||
return false;
|
||||
|
||||
regs->rip = regs->r11;
|
||||
regs->r9 = regs->vector;
|
||||
regs->r10 = regs->error_code;
|
||||
return true;
|
||||
}
|
||||
|
||||
void route_exception(struct ex_regs *regs)
|
||||
{
|
||||
typedef void(*handler)(struct ex_regs *);
|
||||
handler *handlers = (handler *)exception_handlers;
|
||||
|
||||
if (handlers && handlers[regs->vector]) {
|
||||
handlers[regs->vector](regs);
|
||||
return;
|
||||
}
|
||||
|
||||
if (kvm_fixup_exception(regs))
|
||||
return;
|
||||
|
||||
ucall_assert(UCALL_UNHANDLED,
|
||||
"Unhandled exception in guest", __FILE__, __LINE__,
|
||||
"Unhandled exception '0x%lx' at guest RIP '0x%lx'",
|
||||
regs->vector, regs->rip);
|
||||
}
|
||||
|
||||
static void vm_init_descriptor_tables(struct kvm_vm *vm)
|
||||
{
|
||||
extern void *idt_handlers;
|
||||
struct kvm_segment seg;
|
||||
int i;
|
||||
|
||||
vm->arch.gdt = __vm_vaddr_alloc_page(vm, MEM_REGION_DATA);
|
||||
vm->arch.idt = __vm_vaddr_alloc_page(vm, MEM_REGION_DATA);
|
||||
vm->handlers = __vm_vaddr_alloc_page(vm, MEM_REGION_DATA);
|
||||
vm->arch.tss = __vm_vaddr_alloc_page(vm, MEM_REGION_DATA);
|
||||
|
||||
/* Handlers have the same address in both address spaces.*/
|
||||
for (i = 0; i < NUM_INTERRUPTS; i++)
|
||||
set_idt_entry(vm, i, (unsigned long)(&idt_handlers)[i], 0, KERNEL_CS);
|
||||
|
||||
*(vm_vaddr_t *)addr_gva2hva(vm, (vm_vaddr_t)(&exception_handlers)) = vm->handlers;
|
||||
|
||||
kvm_seg_set_kernel_code_64bit(&seg);
|
||||
kvm_seg_fill_gdt_64bit(vm, &seg);
|
||||
|
||||
kvm_seg_set_kernel_data_64bit(&seg);
|
||||
kvm_seg_fill_gdt_64bit(vm, &seg);
|
||||
|
||||
kvm_seg_set_tss_64bit(vm->arch.tss, &seg);
|
||||
kvm_seg_fill_gdt_64bit(vm, &seg);
|
||||
}
|
||||
|
||||
void vm_install_exception_handler(struct kvm_vm *vm, int vector,
|
||||
void (*handler)(struct ex_regs *))
|
||||
{
|
||||
vm_vaddr_t *handlers = (vm_vaddr_t *)addr_gva2hva(vm, vm->handlers);
|
||||
|
||||
handlers[vector] = (vm_vaddr_t)handler;
|
||||
}
|
||||
|
||||
void assert_on_unhandled_exception(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct ucall uc;
|
||||
|
||||
if (get_ucall(vcpu, &uc) == UCALL_UNHANDLED)
|
||||
REPORT_GUEST_ASSERT(uc);
|
||||
}
|
||||
|
||||
void kvm_arch_vm_post_create(struct kvm_vm *vm)
|
||||
{
|
||||
vm_create_irqchip(vm);
|
||||
vm_init_descriptor_tables(vm);
|
||||
|
||||
sync_global_to_guest(vm, host_cpu_is_intel);
|
||||
sync_global_to_guest(vm, host_cpu_is_amd);
|
||||
sync_global_to_guest(vm, is_forced_emulation_enabled);
|
||||
|
||||
if (vm->type == KVM_X86_SEV_VM || vm->type == KVM_X86_SEV_ES_VM) {
|
||||
struct kvm_sev_init init = { 0 };
|
||||
@ -622,7 +667,7 @@ struct kvm_vcpu *vm_arch_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id)
|
||||
|
||||
vcpu = __vm_vcpu_add(vm, vcpu_id);
|
||||
vcpu_init_cpuid(vcpu, kvm_get_supported_cpuid());
|
||||
vcpu_setup(vm, vcpu);
|
||||
vcpu_init_sregs(vm, vcpu);
|
||||
|
||||
/* Setup guest general purpose registers */
|
||||
vcpu_regs_get(vcpu, ®s);
|
||||
@ -1091,102 +1136,6 @@ void kvm_init_vm_address_properties(struct kvm_vm *vm)
|
||||
}
|
||||
}
|
||||
|
||||
static void set_idt_entry(struct kvm_vm *vm, int vector, unsigned long addr,
|
||||
int dpl, unsigned short selector)
|
||||
{
|
||||
struct idt_entry *base =
|
||||
(struct idt_entry *)addr_gva2hva(vm, vm->idt);
|
||||
struct idt_entry *e = &base[vector];
|
||||
|
||||
memset(e, 0, sizeof(*e));
|
||||
e->offset0 = addr;
|
||||
e->selector = selector;
|
||||
e->ist = 0;
|
||||
e->type = 14;
|
||||
e->dpl = dpl;
|
||||
e->p = 1;
|
||||
e->offset1 = addr >> 16;
|
||||
e->offset2 = addr >> 32;
|
||||
}
|
||||
|
||||
|
||||
static bool kvm_fixup_exception(struct ex_regs *regs)
|
||||
{
|
||||
if (regs->r9 != KVM_EXCEPTION_MAGIC || regs->rip != regs->r10)
|
||||
return false;
|
||||
|
||||
if (regs->vector == DE_VECTOR)
|
||||
return false;
|
||||
|
||||
regs->rip = regs->r11;
|
||||
regs->r9 = regs->vector;
|
||||
regs->r10 = regs->error_code;
|
||||
return true;
|
||||
}
|
||||
|
||||
void route_exception(struct ex_regs *regs)
|
||||
{
|
||||
typedef void(*handler)(struct ex_regs *);
|
||||
handler *handlers = (handler *)exception_handlers;
|
||||
|
||||
if (handlers && handlers[regs->vector]) {
|
||||
handlers[regs->vector](regs);
|
||||
return;
|
||||
}
|
||||
|
||||
if (kvm_fixup_exception(regs))
|
||||
return;
|
||||
|
||||
ucall_assert(UCALL_UNHANDLED,
|
||||
"Unhandled exception in guest", __FILE__, __LINE__,
|
||||
"Unhandled exception '0x%lx' at guest RIP '0x%lx'",
|
||||
regs->vector, regs->rip);
|
||||
}
|
||||
|
||||
void vm_init_descriptor_tables(struct kvm_vm *vm)
|
||||
{
|
||||
extern void *idt_handlers;
|
||||
int i;
|
||||
|
||||
vm->idt = __vm_vaddr_alloc_page(vm, MEM_REGION_DATA);
|
||||
vm->handlers = __vm_vaddr_alloc_page(vm, MEM_REGION_DATA);
|
||||
/* Handlers have the same address in both address spaces.*/
|
||||
for (i = 0; i < NUM_INTERRUPTS; i++)
|
||||
set_idt_entry(vm, i, (unsigned long)(&idt_handlers)[i], 0,
|
||||
DEFAULT_CODE_SELECTOR);
|
||||
}
|
||||
|
||||
void vcpu_init_descriptor_tables(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm_vm *vm = vcpu->vm;
|
||||
struct kvm_sregs sregs;
|
||||
|
||||
vcpu_sregs_get(vcpu, &sregs);
|
||||
sregs.idt.base = vm->idt;
|
||||
sregs.idt.limit = NUM_INTERRUPTS * sizeof(struct idt_entry) - 1;
|
||||
sregs.gdt.base = vm->gdt;
|
||||
sregs.gdt.limit = getpagesize() - 1;
|
||||
kvm_seg_set_kernel_data_64bit(NULL, DEFAULT_DATA_SELECTOR, &sregs.gs);
|
||||
vcpu_sregs_set(vcpu, &sregs);
|
||||
*(vm_vaddr_t *)addr_gva2hva(vm, (vm_vaddr_t)(&exception_handlers)) = vm->handlers;
|
||||
}
|
||||
|
||||
void vm_install_exception_handler(struct kvm_vm *vm, int vector,
|
||||
void (*handler)(struct ex_regs *))
|
||||
{
|
||||
vm_vaddr_t *handlers = (vm_vaddr_t *)addr_gva2hva(vm, vm->handlers);
|
||||
|
||||
handlers[vector] = (vm_vaddr_t)handler;
|
||||
}
|
||||
|
||||
void assert_on_unhandled_exception(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct ucall uc;
|
||||
|
||||
if (get_ucall(vcpu, &uc) == UCALL_UNHANDLED)
|
||||
REPORT_GUEST_ASSERT(uc);
|
||||
}
|
||||
|
||||
const struct kvm_cpuid_entry2 *get_cpuid_entry(const struct kvm_cpuid2 *cpuid,
|
||||
uint32_t function, uint32_t index)
|
||||
{
|
||||
@ -1348,6 +1297,7 @@ void kvm_selftest_arch_init(void)
|
||||
{
|
||||
host_cpu_is_intel = this_cpu_is_intel();
|
||||
host_cpu_is_amd = this_cpu_is_amd();
|
||||
is_forced_emulation_enabled = kvm_is_forced_emulation_enabled();
|
||||
}
|
||||
|
||||
bool sys_clocksource_is_based_on_tsc(void)
|
||||
|
@ -1,5 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
|
@ -6,9 +6,6 @@
|
||||
* Copyright (C) 2018, Red Hat, Inc.
|
||||
* Copyright (C) 2020, Google, Inc.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for program_invocation_name */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/syscall.h>
|
||||
|
@ -7,13 +7,11 @@
|
||||
*
|
||||
* Copyright (c) 2024, Intel Corporation.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "arch_timer.h"
|
||||
#include "kvm_util.h"
|
||||
#include "processor.h"
|
||||
#include "timer_test.h"
|
||||
#include "ucall_common.h"
|
||||
|
||||
static int timer_irq = IRQ_S_TIMER;
|
||||
|
||||
|
@ -1,5 +1,13 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
|
||||
/*
|
||||
* Include rseq.c without _GNU_SOURCE defined, before including any headers, so
|
||||
* that rseq.c is compiled with its configuration, not KVM selftests' config.
|
||||
*/
|
||||
#undef _GNU_SOURCE
|
||||
#include "../rseq/rseq.c"
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
@ -19,8 +27,7 @@
|
||||
#include "kvm_util.h"
|
||||
#include "processor.h"
|
||||
#include "test_util.h"
|
||||
|
||||
#include "../rseq/rseq.c"
|
||||
#include "ucall_common.h"
|
||||
|
||||
/*
|
||||
* Any bug related to task migration is likely to be timing-dependent; perform
|
||||
|
@ -7,8 +7,6 @@
|
||||
* Authors:
|
||||
* Nico Boehr <nrb@linux.ibm.com>
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -18,6 +16,7 @@
|
||||
#include "test_util.h"
|
||||
#include "kvm_util.h"
|
||||
#include "kselftest.h"
|
||||
#include "ucall_common.h"
|
||||
|
||||
#define MAIN_PAGE_COUNT 512
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "test_util.h"
|
||||
#include "kvm_util.h"
|
||||
#include "kselftest.h"
|
||||
#include "ucall_common.h"
|
||||
|
||||
enum mop_target {
|
||||
LOGICAL,
|
||||
|
@ -10,8 +10,6 @@
|
||||
*
|
||||
* Test expected behavior of the KVM_CAP_SYNC_REGS functionality.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "test_util.h"
|
||||
#include "kvm_util.h"
|
||||
#include "kselftest.h"
|
||||
#include "ucall_common.h"
|
||||
|
||||
#define PAGE_SHIFT 12
|
||||
#define PAGE_SIZE (1 << PAGE_SHIFT)
|
||||
|
@ -1,5 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <sched.h>
|
||||
@ -221,8 +220,20 @@ static void test_move_memory_region(void)
|
||||
|
||||
static void guest_code_delete_memory_region(void)
|
||||
{
|
||||
struct desc_ptr idt;
|
||||
uint64_t val;
|
||||
|
||||
/*
|
||||
* Clobber the IDT so that a #PF due to the memory region being deleted
|
||||
* escalates to triple-fault shutdown. Because the memory region is
|
||||
* deleted, there will be no valid mappings. As a result, KVM will
|
||||
* repeatedly intercepts the state-2 page fault that occurs when trying
|
||||
* to vector the guest's #PF. I.e. trying to actually handle the #PF
|
||||
* in the guest will never succeed, and so isn't an option.
|
||||
*/
|
||||
memset(&idt, 0, sizeof(idt));
|
||||
__asm__ __volatile__("lidt %0" :: "m"(idt));
|
||||
|
||||
GUEST_SYNC(0);
|
||||
|
||||
/* Spin until the memory region is deleted. */
|
||||
|
@ -4,7 +4,6 @@
|
||||
*
|
||||
* Copyright (C) 2020, Red Hat, Inc.
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <sched.h>
|
||||
@ -20,6 +19,7 @@
|
||||
#include "test_util.h"
|
||||
#include "kvm_util.h"
|
||||
#include "processor.h"
|
||||
#include "ucall_common.h"
|
||||
|
||||
#define NR_VCPUS 4
|
||||
#define ST_GPA_BASE (1 << 30)
|
||||
|
@ -6,8 +6,6 @@
|
||||
*
|
||||
* Tests for amx #NM exception and save/restore.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -246,8 +244,6 @@ int main(int argc, char *argv[])
|
||||
vcpu_regs_get(vcpu, ®s1);
|
||||
|
||||
/* Register #NM handler */
|
||||
vm_init_descriptor_tables(vm);
|
||||
vcpu_init_descriptor_tables(vcpu);
|
||||
vm_install_exception_handler(vm, NM_VECTOR, guest_nm_handler);
|
||||
|
||||
/* amx cfg for guest_code */
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "test_util.h"
|
||||
#include "memstress.h"
|
||||
#include "guest_modes.h"
|
||||
#include "ucall_common.h"
|
||||
|
||||
#define VCPUS 2
|
||||
#define SLOTS 2
|
||||
|
@ -4,12 +4,9 @@
|
||||
*
|
||||
* Test for KVM_CAP_EXIT_ON_EMULATION_FAILURE.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
|
||||
#include "flds_emulation.h"
|
||||
|
||||
#include "test_util.h"
|
||||
#include "ucall_common.h"
|
||||
|
||||
#define MMIO_GPA 0x700000000
|
||||
#define MMIO_GVA MMIO_GPA
|
||||
|
@ -110,8 +110,6 @@ static void test_fix_hypercall(struct kvm_vcpu *vcpu, bool disable_quirk)
|
||||
{
|
||||
struct kvm_vm *vm = vcpu->vm;
|
||||
|
||||
vm_init_descriptor_tables(vm);
|
||||
vcpu_init_descriptor_tables(vcpu);
|
||||
vm_install_exception_handler(vcpu->vm, UD_VECTOR, guest_ud_handler);
|
||||
|
||||
if (disable_quirk)
|
||||
|
@ -2,8 +2,6 @@
|
||||
/*
|
||||
* Copyright (C) 2023, Google LLC.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "test_util.h"
|
||||
|
@ -7,8 +7,6 @@
|
||||
* This work is licensed under the terms of the GNU GPL, version 2.
|
||||
*
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -4,7 +4,6 @@
|
||||
*
|
||||
* Tests for Enlightened VMCS, including nested guest state.
|
||||
*/
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -258,8 +257,6 @@ int main(int argc, char *argv[])
|
||||
vcpu_args_set(vcpu, 3, vmx_pages_gva, hv_pages_gva, addr_gva2gpa(vm, hcall_page));
|
||||
vcpu_set_msr(vcpu, HV_X64_MSR_VP_INDEX, vcpu->id);
|
||||
|
||||
vm_init_descriptor_tables(vm);
|
||||
vcpu_init_descriptor_tables(vcpu);
|
||||
vm_install_exception_handler(vm, UD_VECTOR, guest_ud_handler);
|
||||
vm_install_exception_handler(vm, NMI_VECTOR, guest_nmi_handler);
|
||||
|
||||
|
@ -156,9 +156,6 @@ static void guest_test_msrs_access(void)
|
||||
vcpu_init_cpuid(vcpu, prev_cpuid);
|
||||
}
|
||||
|
||||
vm_init_descriptor_tables(vm);
|
||||
vcpu_init_descriptor_tables(vcpu);
|
||||
|
||||
/* TODO: Make this entire test easier to maintain. */
|
||||
if (stage >= 21)
|
||||
vcpu_enable_cap(vcpu, KVM_CAP_HYPERV_SYNIC2, 0);
|
||||
@ -532,9 +529,6 @@ static void guest_test_hcalls_access(void)
|
||||
while (true) {
|
||||
vm = vm_create_with_one_vcpu(&vcpu, guest_hcall);
|
||||
|
||||
vm_init_descriptor_tables(vm);
|
||||
vcpu_init_descriptor_tables(vcpu);
|
||||
|
||||
/* Hypercall input/output */
|
||||
hcall_page = vm_vaddr_alloc_pages(vm, 2);
|
||||
memset(addr_gva2hva(vm, hcall_page), 0x0, 2 * getpagesize());
|
||||
|
@ -5,8 +5,6 @@
|
||||
* Copyright (C) 2022, Red Hat, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <pthread.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
@ -256,16 +254,13 @@ int main(int argc, char *argv[])
|
||||
hcall_page = vm_vaddr_alloc_pages(vm, 2);
|
||||
memset(addr_gva2hva(vm, hcall_page), 0x0, 2 * getpagesize());
|
||||
|
||||
vm_init_descriptor_tables(vm);
|
||||
|
||||
vcpu[1] = vm_vcpu_add(vm, RECEIVER_VCPU_ID_1, receiver_code);
|
||||
vcpu_init_descriptor_tables(vcpu[1]);
|
||||
vcpu_args_set(vcpu[1], 2, hcall_page, addr_gva2gpa(vm, hcall_page));
|
||||
vcpu_set_msr(vcpu[1], HV_X64_MSR_VP_INDEX, RECEIVER_VCPU_ID_1);
|
||||
vcpu_set_hv_cpuid(vcpu[1]);
|
||||
|
||||
vcpu[2] = vm_vcpu_add(vm, RECEIVER_VCPU_ID_2, receiver_code);
|
||||
vcpu_init_descriptor_tables(vcpu[2]);
|
||||
vcpu_args_set(vcpu[2], 2, hcall_page, addr_gva2gpa(vm, hcall_page));
|
||||
vcpu_set_msr(vcpu[2], HV_X64_MSR_VP_INDEX, RECEIVER_VCPU_ID_2);
|
||||
vcpu_set_hv_cpuid(vcpu[2]);
|
||||
|
@ -4,7 +4,6 @@
|
||||
*
|
||||
* Tests for Hyper-V extensions to SVM.
|
||||
*/
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -5,8 +5,6 @@
|
||||
* Copyright (C) 2022, Red Hat, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <asm/barrier.h>
|
||||
#include <pthread.h>
|
||||
#include <inttypes.h>
|
||||
|
@ -183,9 +183,6 @@ int main(void)
|
||||
|
||||
vcpu_clear_cpuid_entry(vcpu, KVM_CPUID_FEATURES);
|
||||
|
||||
vm_init_descriptor_tables(vm);
|
||||
vcpu_init_descriptor_tables(vcpu);
|
||||
|
||||
enter_guest(vcpu);
|
||||
kvm_vm_free(vm);
|
||||
|
||||
|
@ -81,9 +81,6 @@ int main(int argc, char *argv[])
|
||||
vm = vm_create_with_one_vcpu(&vcpu, guest_code);
|
||||
vcpu_clear_cpuid_feature(vcpu, X86_FEATURE_MWAIT);
|
||||
|
||||
vm_init_descriptor_tables(vm);
|
||||
vcpu_init_descriptor_tables(vcpu);
|
||||
|
||||
while (1) {
|
||||
vcpu_run(vcpu);
|
||||
TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
|
||||
|
@ -1,6 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
|
||||
#include "test_util.h"
|
||||
#include "kvm_util.h"
|
||||
#include "processor.h"
|
||||
|
@ -5,9 +5,6 @@
|
||||
*
|
||||
* Copyright (C) 2022, Google LLC.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
@ -9,8 +9,6 @@
|
||||
* Verifies expected behavior of controlling guest access to
|
||||
* MSR_PLATFORM_INFO.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -26,36 +24,18 @@
|
||||
static void guest_code(void)
|
||||
{
|
||||
uint64_t msr_platform_info;
|
||||
uint8_t vector;
|
||||
|
||||
for (;;) {
|
||||
GUEST_SYNC(true);
|
||||
msr_platform_info = rdmsr(MSR_PLATFORM_INFO);
|
||||
GUEST_SYNC(msr_platform_info);
|
||||
asm volatile ("inc %r11");
|
||||
}
|
||||
}
|
||||
|
||||
static void test_msr_platform_info_enabled(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct ucall uc;
|
||||
|
||||
vm_enable_cap(vcpu->vm, KVM_CAP_MSR_PLATFORM_INFO, true);
|
||||
vcpu_run(vcpu);
|
||||
TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
|
||||
|
||||
get_ucall(vcpu, &uc);
|
||||
TEST_ASSERT(uc.cmd == UCALL_SYNC,
|
||||
"Received ucall other than UCALL_SYNC: %lu", uc.cmd);
|
||||
TEST_ASSERT((uc.args[1] & MSR_PLATFORM_INFO_MAX_TURBO_RATIO) ==
|
||||
MSR_PLATFORM_INFO_MAX_TURBO_RATIO,
|
||||
"Expected MSR_PLATFORM_INFO to have max turbo ratio mask: %i.",
|
||||
GUEST_ASSERT_EQ(msr_platform_info & MSR_PLATFORM_INFO_MAX_TURBO_RATIO,
|
||||
MSR_PLATFORM_INFO_MAX_TURBO_RATIO);
|
||||
}
|
||||
|
||||
static void test_msr_platform_info_disabled(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
vm_enable_cap(vcpu->vm, KVM_CAP_MSR_PLATFORM_INFO, false);
|
||||
vcpu_run(vcpu);
|
||||
TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_SHUTDOWN);
|
||||
GUEST_SYNC(false);
|
||||
vector = rdmsr_safe(MSR_PLATFORM_INFO, &msr_platform_info);
|
||||
GUEST_ASSERT_EQ(vector, GP_VECTOR);
|
||||
|
||||
GUEST_DONE();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@ -63,6 +43,7 @@ int main(int argc, char *argv[])
|
||||
struct kvm_vcpu *vcpu;
|
||||
struct kvm_vm *vm;
|
||||
uint64_t msr_platform_info;
|
||||
struct ucall uc;
|
||||
|
||||
TEST_REQUIRE(kvm_has_cap(KVM_CAP_MSR_PLATFORM_INFO));
|
||||
|
||||
@ -71,8 +52,26 @@ int main(int argc, char *argv[])
|
||||
msr_platform_info = vcpu_get_msr(vcpu, MSR_PLATFORM_INFO);
|
||||
vcpu_set_msr(vcpu, MSR_PLATFORM_INFO,
|
||||
msr_platform_info | MSR_PLATFORM_INFO_MAX_TURBO_RATIO);
|
||||
test_msr_platform_info_enabled(vcpu);
|
||||
test_msr_platform_info_disabled(vcpu);
|
||||
|
||||
for (;;) {
|
||||
vcpu_run(vcpu);
|
||||
TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
|
||||
|
||||
switch (get_ucall(vcpu, &uc)) {
|
||||
case UCALL_SYNC:
|
||||
vm_enable_cap(vm, KVM_CAP_MSR_PLATFORM_INFO, uc.args[1]);
|
||||
break;
|
||||
case UCALL_DONE:
|
||||
goto done;
|
||||
case UCALL_ABORT:
|
||||
REPORT_GUEST_ASSERT(uc);
|
||||
default:
|
||||
TEST_FAIL("Unexpected ucall %lu", uc.cmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
vcpu_set_msr(vcpu, MSR_PLATFORM_INFO, msr_platform_info);
|
||||
|
||||
kvm_vm_free(vm);
|
||||
|
@ -2,8 +2,6 @@
|
||||
/*
|
||||
* Copyright (C) 2023, Tencent, Inc.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <x86intrin.h>
|
||||
|
||||
#include "pmu.h"
|
||||
@ -21,7 +19,6 @@
|
||||
|
||||
static uint8_t kvm_pmu_version;
|
||||
static bool kvm_has_perf_caps;
|
||||
static bool is_forced_emulation_enabled;
|
||||
|
||||
static struct kvm_vm *pmu_vm_create_with_one_vcpu(struct kvm_vcpu **vcpu,
|
||||
void *guest_code,
|
||||
@ -31,11 +28,7 @@ static struct kvm_vm *pmu_vm_create_with_one_vcpu(struct kvm_vcpu **vcpu,
|
||||
struct kvm_vm *vm;
|
||||
|
||||
vm = vm_create_with_one_vcpu(vcpu, guest_code);
|
||||
vm_init_descriptor_tables(vm);
|
||||
vcpu_init_descriptor_tables(*vcpu);
|
||||
|
||||
sync_global_to_guest(vm, kvm_pmu_version);
|
||||
sync_global_to_guest(vm, is_forced_emulation_enabled);
|
||||
|
||||
/*
|
||||
* Set PERF_CAPABILITIES before PMU version as KVM disallows enabling
|
||||
@ -630,7 +623,6 @@ int main(int argc, char *argv[])
|
||||
|
||||
kvm_pmu_version = kvm_cpu_property(X86_PROPERTY_PMU_VERSION);
|
||||
kvm_has_perf_caps = kvm_cpu_has(X86_FEATURE_PDCM);
|
||||
is_forced_emulation_enabled = kvm_is_forced_emulation_enabled();
|
||||
|
||||
test_intel_counters();
|
||||
|
||||
|
@ -9,9 +9,6 @@
|
||||
* Verifies the expected behavior of allow lists and deny lists for
|
||||
* virtual PMU events.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
|
||||
#include "kvm_util.h"
|
||||
#include "pmu.h"
|
||||
#include "processor.h"
|
||||
@ -337,9 +334,6 @@ static void test_pmu_config_disable(void (*guest_code)(void))
|
||||
vm_enable_cap(vm, KVM_CAP_PMU_CAPABILITY, KVM_PMU_CAP_DISABLE);
|
||||
|
||||
vcpu = vm_vcpu_add(vm, 0, guest_code);
|
||||
vm_init_descriptor_tables(vm);
|
||||
vcpu_init_descriptor_tables(vcpu);
|
||||
|
||||
TEST_ASSERT(!sanity_check_pmu(vcpu),
|
||||
"Guest should not be able to use disabled PMU.");
|
||||
|
||||
@ -876,9 +870,6 @@ int main(int argc, char *argv[])
|
||||
|
||||
vm = vm_create_with_one_vcpu(&vcpu, guest_code);
|
||||
|
||||
vm_init_descriptor_tables(vm);
|
||||
vcpu_init_descriptor_tables(vcpu);
|
||||
|
||||
TEST_REQUIRE(sanity_check_pmu(vcpu));
|
||||
|
||||
if (use_amd_pmu())
|
||||
|
@ -2,7 +2,6 @@
|
||||
/*
|
||||
* Copyright (C) 2022, Google LLC.
|
||||
*/
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
|
@ -4,7 +4,6 @@
|
||||
*
|
||||
* Copyright (C) 2020, Red Hat, Inc.
|
||||
*/
|
||||
#define _GNU_SOURCE /* for program_invocation_name */
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -10,7 +10,6 @@
|
||||
* That bug allowed a user-mode program that called the KVM_SET_SREGS
|
||||
* ioctl to put a VCPU's local APIC into an invalid state.
|
||||
*/
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -5,9 +5,6 @@
|
||||
* Test that KVM emulates instructions in response to EPT violations when
|
||||
* allow_smaller_maxphyaddr is enabled and guest.MAXPHYADDR < host.MAXPHYADDR.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
|
||||
#include "flds_emulation.h"
|
||||
|
||||
#include "test_util.h"
|
||||
@ -60,9 +57,6 @@ int main(int argc, char *argv[])
|
||||
vm = vm_create_with_one_vcpu(&vcpu, guest_code);
|
||||
vcpu_args_set(vcpu, 1, kvm_is_tdp_enabled());
|
||||
|
||||
vm_init_descriptor_tables(vm);
|
||||
vcpu_init_descriptor_tables(vcpu);
|
||||
|
||||
vcpu_set_cpuid_property(vcpu, X86_PROPERTY_MAX_PHY_ADDR, MAXPHYADDR);
|
||||
|
||||
rc = kvm_check_cap(KVM_CAP_EXIT_ON_EMULATION_FAILURE);
|
||||
|
@ -4,7 +4,6 @@
|
||||
*
|
||||
* Tests for SMM.
|
||||
*/
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -6,7 +6,6 @@
|
||||
*
|
||||
* Tests for vCPU state save/restore, including nested guest state.
|
||||
*/
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -93,9 +93,6 @@ int main(int argc, char *argv[])
|
||||
|
||||
vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code);
|
||||
|
||||
vm_init_descriptor_tables(vm);
|
||||
vcpu_init_descriptor_tables(vcpu);
|
||||
|
||||
vm_install_exception_handler(vm, VINTR_IRQ_NUMBER, vintr_irq_handler);
|
||||
vm_install_exception_handler(vm, INTR_IRQ_NUMBER, intr_irq_handler);
|
||||
|
||||
|
@ -48,12 +48,9 @@ int main(int argc, char *argv[])
|
||||
TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SVM));
|
||||
|
||||
vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code);
|
||||
vm_init_descriptor_tables(vm);
|
||||
vcpu_init_descriptor_tables(vcpu);
|
||||
|
||||
vcpu_alloc_svm(vm, &svm_gva);
|
||||
|
||||
vcpu_args_set(vcpu, 2, svm_gva, vm->idt);
|
||||
vcpu_args_set(vcpu, 2, svm_gva, vm->arch.idt);
|
||||
|
||||
vcpu_run(vcpu);
|
||||
TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_SHUTDOWN);
|
||||
|
@ -152,9 +152,6 @@ static void run_test(bool is_nmi)
|
||||
|
||||
vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code);
|
||||
|
||||
vm_init_descriptor_tables(vm);
|
||||
vcpu_init_descriptor_tables(vcpu);
|
||||
|
||||
vm_install_exception_handler(vm, NMI_VECTOR, guest_nmi_handler);
|
||||
vm_install_exception_handler(vm, BP_VECTOR, guest_bp_handler);
|
||||
vm_install_exception_handler(vm, INT_NR, guest_int_handler);
|
||||
@ -166,7 +163,7 @@ static void run_test(bool is_nmi)
|
||||
|
||||
idt_alt_vm = vm_vaddr_alloc_page(vm);
|
||||
idt_alt = addr_gva2hva(vm, idt_alt_vm);
|
||||
idt = addr_gva2hva(vm, vm->idt);
|
||||
idt = addr_gva2hva(vm, vm->arch.idt);
|
||||
memcpy(idt_alt, idt, getpagesize());
|
||||
} else {
|
||||
idt_alt_vm = 0;
|
||||
|
@ -8,8 +8,6 @@
|
||||
* including requesting an invalid register set, updates to/from values
|
||||
* in kvm_run.s.regs when kvm_valid_regs and kvm_dirty_regs are toggled.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -17,14 +17,11 @@
|
||||
* delivered into the guest or not.
|
||||
*
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <pthread.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "kvm_util_base.h"
|
||||
#include "kvm_util.h"
|
||||
#include "mce.h"
|
||||
#include "processor.h"
|
||||
@ -285,10 +282,6 @@ int main(int argc, char *argv[])
|
||||
cmcidis_vcpu = create_vcpu_with_mce_cap(vm, 1, false, cmci_disabled_guest_code);
|
||||
cmci_vcpu = create_vcpu_with_mce_cap(vm, 2, true, cmci_enabled_guest_code);
|
||||
|
||||
vm_init_descriptor_tables(vm);
|
||||
vcpu_init_descriptor_tables(ucna_vcpu);
|
||||
vcpu_init_descriptor_tables(cmcidis_vcpu);
|
||||
vcpu_init_descriptor_tables(cmci_vcpu);
|
||||
vm_install_exception_handler(vm, CMCI_VECTOR, guest_cmci_handler);
|
||||
vm_install_exception_handler(vm, GP_VECTOR, guest_gp_handler);
|
||||
|
||||
|
@ -4,8 +4,6 @@
|
||||
*
|
||||
* Tests for exiting into userspace on registered MSRs
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "kvm_test_harness.h"
|
||||
@ -13,8 +11,6 @@
|
||||
#include "kvm_util.h"
|
||||
#include "vmx.h"
|
||||
|
||||
static bool fep_available;
|
||||
|
||||
#define MSR_NON_EXISTENT 0x474f4f00
|
||||
|
||||
static u64 deny_bits = 0;
|
||||
@ -258,7 +254,7 @@ static void guest_code_filter_allow(void)
|
||||
GUEST_ASSERT(data == 2);
|
||||
GUEST_ASSERT(guest_exception_count == 0);
|
||||
|
||||
if (fep_available) {
|
||||
if (is_forced_emulation_enabled) {
|
||||
/* Let userspace know we aren't done. */
|
||||
GUEST_SYNC(0);
|
||||
|
||||
@ -520,8 +516,6 @@ KVM_ONE_VCPU_TEST(user_msr, msr_filter_allow, guest_code_filter_allow)
|
||||
uint64_t cmd;
|
||||
int rc;
|
||||
|
||||
sync_global_to_guest(vm, fep_available);
|
||||
|
||||
rc = kvm_check_cap(KVM_CAP_X86_USER_SPACE_MSR);
|
||||
TEST_ASSERT(rc, "KVM_CAP_X86_USER_SPACE_MSR is available");
|
||||
vm_enable_cap(vm, KVM_CAP_X86_USER_SPACE_MSR, KVM_MSR_EXIT_REASON_FILTER);
|
||||
@ -531,9 +525,6 @@ KVM_ONE_VCPU_TEST(user_msr, msr_filter_allow, guest_code_filter_allow)
|
||||
|
||||
vm_ioctl(vm, KVM_X86_SET_MSR_FILTER, &filter_allow);
|
||||
|
||||
vm_init_descriptor_tables(vm);
|
||||
vcpu_init_descriptor_tables(vcpu);
|
||||
|
||||
vm_install_exception_handler(vm, GP_VECTOR, guest_gp_handler);
|
||||
|
||||
/* Process guest code userspace exits. */
|
||||
@ -551,7 +542,7 @@ KVM_ONE_VCPU_TEST(user_msr, msr_filter_allow, guest_code_filter_allow)
|
||||
vcpu_run(vcpu);
|
||||
cmd = process_ucall(vcpu);
|
||||
|
||||
if (fep_available) {
|
||||
if (is_forced_emulation_enabled) {
|
||||
TEST_ASSERT_EQ(cmd, UCALL_SYNC);
|
||||
vm_install_exception_handler(vm, GP_VECTOR, guest_fep_gp_handler);
|
||||
|
||||
@ -774,7 +765,5 @@ KVM_ONE_VCPU_TEST(user_msr, user_exit_msr_flags, NULL)
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
fep_available = kvm_is_forced_emulation_enabled();
|
||||
|
||||
return test_harness_run(argc, argv);
|
||||
}
|
||||
|
@ -4,9 +4,6 @@
|
||||
*
|
||||
* Copyright (C) 2018, Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for program_invocation_name */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <linux/bitmap.h>
|
||||
|
@ -115,9 +115,6 @@ int main(int argc, char *argv[])
|
||||
vm = vm_create_with_one_vcpu(&vcpu, guest_code);
|
||||
get_set_sigalrm_vcpu(vcpu);
|
||||
|
||||
vm_init_descriptor_tables(vm);
|
||||
vcpu_init_descriptor_tables(vcpu);
|
||||
|
||||
vm_install_exception_handler(vm, UD_VECTOR, guest_ud_handler);
|
||||
|
||||
/*
|
||||
|
@ -10,7 +10,6 @@
|
||||
* and check it can be retrieved with KVM_GET_MSR, also test
|
||||
* the invalid LBR formats are rejected.
|
||||
*/
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <linux/bitmap.h>
|
||||
@ -86,9 +85,6 @@ KVM_ONE_VCPU_TEST(vmx_pmu_caps, guest_wrmsr_perf_capabilities, guest_code)
|
||||
struct ucall uc;
|
||||
int r, i;
|
||||
|
||||
vm_init_descriptor_tables(vcpu->vm);
|
||||
vcpu_init_descriptor_tables(vcpu);
|
||||
|
||||
vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, host_cap.capabilities);
|
||||
|
||||
vcpu_args_set(vcpu, 1, host_cap.capabilities);
|
||||
|
@ -9,7 +9,6 @@
|
||||
* value instead of partially decayed timer value
|
||||
*
|
||||
*/
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -19,8 +19,6 @@
|
||||
* Migration is a command line option. When used on non-numa machines will
|
||||
* exit with error. Test is still usefull on non-numa for testing IPIs.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <getopt.h>
|
||||
#include <pthread.h>
|
||||
#include <inttypes.h>
|
||||
@ -410,8 +408,6 @@ int main(int argc, char *argv[])
|
||||
|
||||
vm = vm_create_with_one_vcpu(¶ms[0].vcpu, halter_guest_code);
|
||||
|
||||
vm_init_descriptor_tables(vm);
|
||||
vcpu_init_descriptor_tables(params[0].vcpu);
|
||||
vm_install_exception_handler(vm, IPI_VECTOR, guest_ipi_handler);
|
||||
|
||||
virt_pg_map(vm, APIC_DEFAULT_GPA, APIC_DEFAULT_GPA);
|
||||
|
@ -1,5 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -109,9 +109,6 @@ int main(int argc, char *argv[])
|
||||
vm = vm_create_with_one_vcpu(&vcpu, guest_code);
|
||||
run = vcpu->run;
|
||||
|
||||
vm_init_descriptor_tables(vm);
|
||||
vcpu_init_descriptor_tables(vcpu);
|
||||
|
||||
while (1) {
|
||||
vcpu_run(vcpu);
|
||||
|
||||
|
@ -171,8 +171,9 @@ static volatile bool guest_saw_irq;
|
||||
static void evtchn_handler(struct ex_regs *regs)
|
||||
{
|
||||
struct vcpu_info *vi = (void *)VCPU_INFO_VADDR;
|
||||
vi->evtchn_upcall_pending = 0;
|
||||
vi->evtchn_pending_sel = 0;
|
||||
|
||||
vcpu_arch_put_guest(vi->evtchn_upcall_pending, 0);
|
||||
vcpu_arch_put_guest(vi->evtchn_pending_sel, 0);
|
||||
guest_saw_irq = true;
|
||||
|
||||
GUEST_SYNC(TEST_GUEST_SAW_IRQ);
|
||||
@ -536,8 +537,6 @@ int main(int argc, char *argv[])
|
||||
};
|
||||
vm_ioctl(vm, KVM_XEN_HVM_SET_ATTR, &vec);
|
||||
|
||||
vm_init_descriptor_tables(vm);
|
||||
vcpu_init_descriptor_tables(vcpu);
|
||||
vm_install_exception_handler(vm, EVTCHN_VECTOR, evtchn_handler);
|
||||
|
||||
if (do_runstate_tests) {
|
||||
|
@ -4,8 +4,6 @@
|
||||
*
|
||||
* Tests for the IA32_XSS MSR.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for program_invocation_short_name */
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "test_util.h"
|
||||
|
Loading…
Reference in New Issue
Block a user