mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-15 11:47:47 +00:00
Merge branch 'next' of git://git.kernel.org/pub/scm/virt/kvm/kvm.git
This commit is contained in:
commit
589faffe7c
12
MAINTAINERS
12
MAINTAINERS
@ -12668,8 +12668,8 @@ F: arch/arm64/include/asm/kvm*
|
||||
F: arch/arm64/include/uapi/asm/kvm*
|
||||
F: arch/arm64/kvm/
|
||||
F: include/kvm/arm_*
|
||||
F: tools/testing/selftests/kvm/*/aarch64/
|
||||
F: tools/testing/selftests/kvm/aarch64/
|
||||
F: tools/testing/selftests/kvm/*/arm64/
|
||||
F: tools/testing/selftests/kvm/arm64/
|
||||
|
||||
KERNEL VIRTUAL MACHINE FOR LOONGARCH (KVM/LoongArch)
|
||||
M: Tianrui Zhao <zhaotianrui@loongson.cn>
|
||||
@ -12740,8 +12740,8 @@ F: arch/s390/kvm/
|
||||
F: arch/s390/mm/gmap.c
|
||||
F: drivers/s390/char/uvdevice.c
|
||||
F: tools/testing/selftests/drivers/s390x/uvdevice/
|
||||
F: tools/testing/selftests/kvm/*/s390x/
|
||||
F: tools/testing/selftests/kvm/s390x/
|
||||
F: tools/testing/selftests/kvm/*/s390/
|
||||
F: tools/testing/selftests/kvm/s390/
|
||||
|
||||
KERNEL VIRTUAL MACHINE FOR X86 (KVM/x86)
|
||||
M: Sean Christopherson <seanjc@google.com>
|
||||
@ -12758,8 +12758,8 @@ F: arch/x86/include/uapi/asm/svm.h
|
||||
F: arch/x86/include/uapi/asm/vmx.h
|
||||
F: arch/x86/kvm/
|
||||
F: arch/x86/kvm/*/
|
||||
F: tools/testing/selftests/kvm/*/x86_64/
|
||||
F: tools/testing/selftests/kvm/x86_64/
|
||||
F: tools/testing/selftests/kvm/*/x86/
|
||||
F: tools/testing/selftests/kvm/x86/
|
||||
|
||||
KERNFS
|
||||
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
|
@ -43,9 +43,6 @@
|
||||
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
|
||||
#define KVM_DIRTY_LOG_PAGE_OFFSET 64
|
||||
|
||||
#define KVM_REG_SIZE(id) \
|
||||
(1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
|
||||
|
||||
struct kvm_regs {
|
||||
struct user_pt_regs regs; /* sp = sp_el0 */
|
||||
|
||||
|
@ -211,9 +211,6 @@ struct kvm_riscv_sbi_sta {
|
||||
#define KVM_RISCV_TIMER_STATE_OFF 0
|
||||
#define KVM_RISCV_TIMER_STATE_ON 1
|
||||
|
||||
#define KVM_REG_SIZE(id) \
|
||||
(1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
|
||||
|
||||
/* If you need to interpret the index values, here is the key: */
|
||||
#define KVM_REG_RISCV_TYPE_MASK 0x00000000FF000000
|
||||
#define KVM_REG_RISCV_TYPE_SHIFT 24
|
||||
|
@ -1070,6 +1070,10 @@ struct kvm_dirty_tlb {
|
||||
|
||||
#define KVM_REG_SIZE_SHIFT 52
|
||||
#define KVM_REG_SIZE_MASK 0x00f0000000000000ULL
|
||||
|
||||
#define KVM_REG_SIZE(id) \
|
||||
(1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
|
||||
|
||||
#define KVM_REG_SIZE_U8 0x0000000000000000ULL
|
||||
#define KVM_REG_SIZE_U16 0x0010000000000000ULL
|
||||
#define KVM_REG_SIZE_U32 0x0020000000000000ULL
|
||||
|
1
tools/testing/selftests/kvm/.gitignore
vendored
1
tools/testing/selftests/kvm/.gitignore
vendored
@ -9,3 +9,4 @@
|
||||
!config
|
||||
!settings
|
||||
!Makefile
|
||||
!Makefile.kvm
|
@ -1,347 +1,16 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
include ../../../build/Build.include
|
||||
|
||||
all:
|
||||
|
||||
top_srcdir = ../../../..
|
||||
include $(top_srcdir)/scripts/subarch.include
|
||||
ARCH ?= $(SUBARCH)
|
||||
|
||||
ifeq ($(ARCH),x86)
|
||||
ARCH_DIR := x86_64
|
||||
else ifeq ($(ARCH),arm64)
|
||||
ARCH_DIR := aarch64
|
||||
else ifeq ($(ARCH),s390)
|
||||
ARCH_DIR := s390x
|
||||
else
|
||||
ARCH_DIR := $(ARCH)
|
||||
endif
|
||||
|
||||
LIBKVM += lib/assert.c
|
||||
LIBKVM += lib/elf.c
|
||||
LIBKVM += lib/guest_modes.c
|
||||
LIBKVM += lib/io.c
|
||||
LIBKVM += lib/kvm_util.c
|
||||
LIBKVM += lib/memstress.c
|
||||
LIBKVM += lib/guest_sprintf.c
|
||||
LIBKVM += lib/rbtree.c
|
||||
LIBKVM += lib/sparsebit.c
|
||||
LIBKVM += lib/test_util.c
|
||||
LIBKVM += lib/ucall_common.c
|
||||
LIBKVM += lib/userfaultfd_util.c
|
||||
|
||||
LIBKVM_STRING += lib/string_override.c
|
||||
|
||||
LIBKVM_x86_64 += lib/x86_64/apic.c
|
||||
LIBKVM_x86_64 += lib/x86_64/handlers.S
|
||||
LIBKVM_x86_64 += lib/x86_64/hyperv.c
|
||||
LIBKVM_x86_64 += lib/x86_64/memstress.c
|
||||
LIBKVM_x86_64 += lib/x86_64/pmu.c
|
||||
LIBKVM_x86_64 += lib/x86_64/processor.c
|
||||
LIBKVM_x86_64 += lib/x86_64/sev.c
|
||||
LIBKVM_x86_64 += lib/x86_64/svm.c
|
||||
LIBKVM_x86_64 += lib/x86_64/ucall.c
|
||||
LIBKVM_x86_64 += lib/x86_64/vmx.c
|
||||
|
||||
LIBKVM_aarch64 += lib/aarch64/gic.c
|
||||
LIBKVM_aarch64 += lib/aarch64/gic_v3.c
|
||||
LIBKVM_aarch64 += lib/aarch64/gic_v3_its.c
|
||||
LIBKVM_aarch64 += lib/aarch64/handlers.S
|
||||
LIBKVM_aarch64 += lib/aarch64/processor.c
|
||||
LIBKVM_aarch64 += lib/aarch64/spinlock.c
|
||||
LIBKVM_aarch64 += lib/aarch64/ucall.c
|
||||
LIBKVM_aarch64 += lib/aarch64/vgic.c
|
||||
|
||||
LIBKVM_s390x += lib/s390x/diag318_test_handler.c
|
||||
LIBKVM_s390x += lib/s390x/processor.c
|
||||
LIBKVM_s390x += lib/s390x/ucall.c
|
||||
LIBKVM_s390x += lib/s390x/facility.c
|
||||
|
||||
LIBKVM_riscv += lib/riscv/handlers.S
|
||||
LIBKVM_riscv += lib/riscv/processor.c
|
||||
LIBKVM_riscv += lib/riscv/ucall.c
|
||||
|
||||
# Non-compiled test targets
|
||||
TEST_PROGS_x86_64 += x86_64/nx_huge_pages_test.sh
|
||||
|
||||
# Compiled test targets
|
||||
TEST_GEN_PROGS_x86_64 = x86_64/cpuid_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/cr4_cpuid_sync_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/dirty_log_page_splitting_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/feature_msrs_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/exit_on_emulation_failure_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/fix_hypercall_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/hwcr_msr_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/hyperv_clock
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/hyperv_cpuid
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/hyperv_evmcs
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/hyperv_extended_hypercalls
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/hyperv_features
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/hyperv_ipi
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/hyperv_svm_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/hyperv_tlb_flush
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/kvm_clock_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/kvm_pv_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/monitor_mwait_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/nested_exceptions_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/platform_info_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/pmu_counters_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/pmu_event_filter_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/private_mem_conversions_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/private_mem_kvm_exits_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/set_boot_cpu_id
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/set_sregs_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/smaller_maxphyaddr_emulation_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/smm_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/state_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/vmx_preemption_timer_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/svm_vmcall_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/svm_int_ctl_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/svm_nested_shutdown_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/svm_nested_soft_inject_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/tsc_scaling_sync
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/sync_regs_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/ucna_injection_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/userspace_io_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/userspace_msr_exit_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/vmx_apic_access_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/vmx_close_while_nested_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/vmx_dirty_log_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/vmx_exception_with_invalid_guest_state
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/vmx_msrs_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/vmx_invalid_nested_guest_state
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/vmx_set_nested_state_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/vmx_tsc_adjust_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/vmx_nested_tsc_scaling_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/apic_bus_clock_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/xapic_ipi_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/xapic_state_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/xcr0_cpuid_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/xss_msr_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/debug_regs
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/tsc_msrs_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/vmx_pmu_caps_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/xen_shinfo_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/xen_vmcall_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/sev_init2_tests
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/sev_migrate_tests
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/sev_smoke_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/amx_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/max_vcpuid_cap_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/triple_fault_event_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/recalc_apic_map_test
|
||||
TEST_GEN_PROGS_x86_64 += access_tracking_perf_test
|
||||
TEST_GEN_PROGS_x86_64 += coalesced_io_test
|
||||
TEST_GEN_PROGS_x86_64 += demand_paging_test
|
||||
TEST_GEN_PROGS_x86_64 += dirty_log_test
|
||||
TEST_GEN_PROGS_x86_64 += dirty_log_perf_test
|
||||
TEST_GEN_PROGS_x86_64 += guest_memfd_test
|
||||
TEST_GEN_PROGS_x86_64 += guest_print_test
|
||||
TEST_GEN_PROGS_x86_64 += hardware_disable_test
|
||||
TEST_GEN_PROGS_x86_64 += kvm_create_max_vcpus
|
||||
TEST_GEN_PROGS_x86_64 += kvm_page_table_test
|
||||
TEST_GEN_PROGS_x86_64 += max_guest_memory_test
|
||||
TEST_GEN_PROGS_x86_64 += memslot_modification_stress_test
|
||||
TEST_GEN_PROGS_x86_64 += memslot_perf_test
|
||||
TEST_GEN_PROGS_x86_64 += rseq_test
|
||||
TEST_GEN_PROGS_x86_64 += set_memory_region_test
|
||||
TEST_GEN_PROGS_x86_64 += steal_time
|
||||
TEST_GEN_PROGS_x86_64 += kvm_binary_stats_test
|
||||
TEST_GEN_PROGS_x86_64 += system_counter_offset_test
|
||||
TEST_GEN_PROGS_x86_64 += pre_fault_memory_test
|
||||
|
||||
# Compiled outputs used by test targets
|
||||
TEST_GEN_PROGS_EXTENDED_x86_64 += x86_64/nx_huge_pages_test
|
||||
|
||||
TEST_GEN_PROGS_aarch64 += aarch64/aarch32_id_regs
|
||||
TEST_GEN_PROGS_aarch64 += aarch64/arch_timer_edge_cases
|
||||
TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
|
||||
TEST_GEN_PROGS_aarch64 += aarch64/hypercalls
|
||||
TEST_GEN_PROGS_aarch64 += aarch64/mmio_abort
|
||||
TEST_GEN_PROGS_aarch64 += aarch64/page_fault_test
|
||||
TEST_GEN_PROGS_aarch64 += aarch64/psci_test
|
||||
TEST_GEN_PROGS_aarch64 += aarch64/set_id_regs
|
||||
TEST_GEN_PROGS_aarch64 += aarch64/smccc_filter
|
||||
TEST_GEN_PROGS_aarch64 += aarch64/vcpu_width_config
|
||||
TEST_GEN_PROGS_aarch64 += aarch64/vgic_init
|
||||
TEST_GEN_PROGS_aarch64 += aarch64/vgic_irq
|
||||
TEST_GEN_PROGS_aarch64 += aarch64/vgic_lpi_stress
|
||||
TEST_GEN_PROGS_aarch64 += aarch64/vpmu_counter_access
|
||||
TEST_GEN_PROGS_aarch64 += aarch64/no-vgic-v3
|
||||
TEST_GEN_PROGS_aarch64 += access_tracking_perf_test
|
||||
TEST_GEN_PROGS_aarch64 += arch_timer
|
||||
TEST_GEN_PROGS_aarch64 += coalesced_io_test
|
||||
TEST_GEN_PROGS_aarch64 += demand_paging_test
|
||||
TEST_GEN_PROGS_aarch64 += dirty_log_test
|
||||
TEST_GEN_PROGS_aarch64 += dirty_log_perf_test
|
||||
TEST_GEN_PROGS_aarch64 += guest_print_test
|
||||
TEST_GEN_PROGS_aarch64 += get-reg-list
|
||||
TEST_GEN_PROGS_aarch64 += kvm_create_max_vcpus
|
||||
TEST_GEN_PROGS_aarch64 += kvm_page_table_test
|
||||
TEST_GEN_PROGS_aarch64 += memslot_modification_stress_test
|
||||
TEST_GEN_PROGS_aarch64 += memslot_perf_test
|
||||
TEST_GEN_PROGS_aarch64 += rseq_test
|
||||
TEST_GEN_PROGS_aarch64 += set_memory_region_test
|
||||
TEST_GEN_PROGS_aarch64 += steal_time
|
||||
TEST_GEN_PROGS_aarch64 += kvm_binary_stats_test
|
||||
|
||||
TEST_GEN_PROGS_s390x = s390x/memop
|
||||
TEST_GEN_PROGS_s390x += s390x/resets
|
||||
TEST_GEN_PROGS_s390x += s390x/sync_regs_test
|
||||
TEST_GEN_PROGS_s390x += s390x/tprot
|
||||
TEST_GEN_PROGS_s390x += s390x/cmma_test
|
||||
TEST_GEN_PROGS_s390x += s390x/debug_test
|
||||
TEST_GEN_PROGS_s390x += s390x/cpumodel_subfuncs_test
|
||||
TEST_GEN_PROGS_s390x += s390x/shared_zeropage_test
|
||||
TEST_GEN_PROGS_s390x += s390x/ucontrol_test
|
||||
TEST_GEN_PROGS_s390x += demand_paging_test
|
||||
TEST_GEN_PROGS_s390x += dirty_log_test
|
||||
TEST_GEN_PROGS_s390x += guest_print_test
|
||||
TEST_GEN_PROGS_s390x += kvm_create_max_vcpus
|
||||
TEST_GEN_PROGS_s390x += kvm_page_table_test
|
||||
TEST_GEN_PROGS_s390x += rseq_test
|
||||
TEST_GEN_PROGS_s390x += set_memory_region_test
|
||||
TEST_GEN_PROGS_s390x += kvm_binary_stats_test
|
||||
|
||||
TEST_GEN_PROGS_riscv += riscv/sbi_pmu_test
|
||||
TEST_GEN_PROGS_riscv += riscv/ebreak_test
|
||||
TEST_GEN_PROGS_riscv += arch_timer
|
||||
TEST_GEN_PROGS_riscv += coalesced_io_test
|
||||
TEST_GEN_PROGS_riscv += demand_paging_test
|
||||
TEST_GEN_PROGS_riscv += dirty_log_test
|
||||
TEST_GEN_PROGS_riscv += get-reg-list
|
||||
TEST_GEN_PROGS_riscv += guest_print_test
|
||||
TEST_GEN_PROGS_riscv += kvm_binary_stats_test
|
||||
TEST_GEN_PROGS_riscv += kvm_create_max_vcpus
|
||||
TEST_GEN_PROGS_riscv += kvm_page_table_test
|
||||
TEST_GEN_PROGS_riscv += set_memory_region_test
|
||||
TEST_GEN_PROGS_riscv += steal_time
|
||||
|
||||
SPLIT_TESTS += arch_timer
|
||||
SPLIT_TESTS += get-reg-list
|
||||
|
||||
TEST_PROGS += $(TEST_PROGS_$(ARCH_DIR))
|
||||
TEST_GEN_PROGS += $(TEST_GEN_PROGS_$(ARCH_DIR))
|
||||
TEST_GEN_PROGS_EXTENDED += $(TEST_GEN_PROGS_EXTENDED_$(ARCH_DIR))
|
||||
LIBKVM += $(LIBKVM_$(ARCH_DIR))
|
||||
|
||||
OVERRIDE_TARGETS = 1
|
||||
|
||||
# lib.mak defines $(OUTPUT), prepends $(OUTPUT)/ to $(TEST_GEN_PROGS), and most
|
||||
# importantly defines, i.e. overwrites, $(CC) (unless `make -e` or `make CC=`,
|
||||
# which causes the environment variable to override the makefile).
|
||||
include ../lib.mk
|
||||
|
||||
INSTALL_HDR_PATH = $(top_srcdir)/usr
|
||||
LINUX_HDR_PATH = $(INSTALL_HDR_PATH)/include/
|
||||
LINUX_TOOL_INCLUDE = $(top_srcdir)/tools/include
|
||||
ifeq ($(ARCH),$(filter $(ARCH),arm64 s390 riscv x86 x86_64))
|
||||
# Top-level selftests allows ARCH=x86_64 :-(
|
||||
ifeq ($(ARCH),x86_64)
|
||||
LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/x86/include
|
||||
ARCH := x86
|
||||
endif
|
||||
include Makefile.kvm
|
||||
else
|
||||
LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/$(ARCH)/include
|
||||
# Empty targets for unsupported architectures
|
||||
all:
|
||||
clean:
|
||||
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 \
|
||||
-fno-stack-protector -fno-PIE -fno-strict-aliasing \
|
||||
-I$(LINUX_TOOL_INCLUDE) -I$(LINUX_TOOL_ARCH_INCLUDE) \
|
||||
-I$(LINUX_HDR_PATH) -Iinclude -I$(<D) -Iinclude/$(ARCH_DIR) \
|
||||
-I ../rseq -I.. $(EXTRA_CFLAGS) $(KHDR_INCLUDES)
|
||||
ifeq ($(ARCH),s390)
|
||||
CFLAGS += -march=z10
|
||||
endif
|
||||
ifeq ($(ARCH),x86)
|
||||
ifeq ($(shell echo "void foo(void) { }" | $(CC) -march=x86-64-v2 -x c - -c -o /dev/null 2>/dev/null; echo "$$?"),0)
|
||||
CFLAGS += -march=x86-64-v2
|
||||
endif
|
||||
endif
|
||||
ifeq ($(ARCH),arm64)
|
||||
tools_dir := $(top_srcdir)/tools
|
||||
arm64_tools_dir := $(tools_dir)/arch/arm64/tools/
|
||||
|
||||
ifneq ($(abs_objdir),)
|
||||
arm64_hdr_outdir := $(abs_objdir)/tools/
|
||||
else
|
||||
arm64_hdr_outdir := $(tools_dir)/
|
||||
endif
|
||||
|
||||
GEN_HDRS := $(arm64_hdr_outdir)arch/arm64/include/generated/
|
||||
CFLAGS += -I$(GEN_HDRS)
|
||||
|
||||
$(GEN_HDRS): $(wildcard $(arm64_tools_dir)/*)
|
||||
$(MAKE) -C $(arm64_tools_dir) OUTPUT=$(arm64_hdr_outdir)
|
||||
endif
|
||||
|
||||
no-pie-option := $(call try-run, echo 'int main(void) { return 0; }' | \
|
||||
$(CC) -Werror $(CFLAGS) -no-pie -x c - -o "$$TMP", -no-pie)
|
||||
|
||||
# On s390, build the testcases KVM-enabled
|
||||
pgste-option = $(call try-run, echo 'int main(void) { return 0; }' | \
|
||||
$(CC) -Werror -Wl$(comma)--s390-pgste -x c - -o "$$TMP",-Wl$(comma)--s390-pgste)
|
||||
|
||||
LDLIBS += -ldl
|
||||
LDFLAGS += -pthread $(no-pie-option) $(pgste-option)
|
||||
|
||||
LIBKVM_C := $(filter %.c,$(LIBKVM))
|
||||
LIBKVM_S := $(filter %.S,$(LIBKVM))
|
||||
LIBKVM_C_OBJ := $(patsubst %.c, $(OUTPUT)/%.o, $(LIBKVM_C))
|
||||
LIBKVM_S_OBJ := $(patsubst %.S, $(OUTPUT)/%.o, $(LIBKVM_S))
|
||||
LIBKVM_STRING_OBJ := $(patsubst %.c, $(OUTPUT)/%.o, $(LIBKVM_STRING))
|
||||
LIBKVM_OBJS = $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ) $(LIBKVM_STRING_OBJ)
|
||||
SPLIT_TEST_GEN_PROGS := $(patsubst %, $(OUTPUT)/%, $(SPLIT_TESTS))
|
||||
SPLIT_TEST_GEN_OBJ := $(patsubst %, $(OUTPUT)/$(ARCH_DIR)/%.o, $(SPLIT_TESTS))
|
||||
|
||||
TEST_GEN_OBJ = $(patsubst %, %.o, $(TEST_GEN_PROGS))
|
||||
TEST_GEN_OBJ += $(patsubst %, %.o, $(TEST_GEN_PROGS_EXTENDED))
|
||||
TEST_DEP_FILES = $(patsubst %.o, %.d, $(TEST_GEN_OBJ))
|
||||
TEST_DEP_FILES += $(patsubst %.o, %.d, $(LIBKVM_OBJS))
|
||||
TEST_DEP_FILES += $(patsubst %.o, %.d, $(SPLIT_TEST_GEN_OBJ))
|
||||
-include $(TEST_DEP_FILES)
|
||||
|
||||
$(shell mkdir -p $(sort $(OUTPUT)/$(ARCH_DIR) $(dir $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ))))
|
||||
|
||||
$(filter-out $(SPLIT_TEST_GEN_PROGS), $(TEST_GEN_PROGS)) \
|
||||
$(TEST_GEN_PROGS_EXTENDED): %: %.o
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $< $(LIBKVM_OBJS) $(LDLIBS) -o $@
|
||||
$(TEST_GEN_OBJ): $(OUTPUT)/%.o: %.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
|
||||
|
||||
$(SPLIT_TEST_GEN_PROGS): $(OUTPUT)/%: $(OUTPUT)/%.o $(OUTPUT)/$(ARCH_DIR)/%.o
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^ $(LDLIBS) -o $@
|
||||
$(SPLIT_TEST_GEN_OBJ): $(OUTPUT)/$(ARCH_DIR)/%.o: $(ARCH_DIR)/%.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
|
||||
|
||||
EXTRA_CLEAN += $(GEN_HDRS) \
|
||||
$(LIBKVM_OBJS) \
|
||||
$(SPLIT_TEST_GEN_OBJ) \
|
||||
$(TEST_DEP_FILES) \
|
||||
$(TEST_GEN_OBJ) \
|
||||
cscope.*
|
||||
|
||||
$(LIBKVM_C_OBJ): $(OUTPUT)/%.o: %.c $(GEN_HDRS)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
|
||||
|
||||
$(LIBKVM_S_OBJ): $(OUTPUT)/%.o: %.S $(GEN_HDRS)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
|
||||
|
||||
# Compile the string overrides as freestanding to prevent the compiler from
|
||||
# generating self-referential code, e.g. without "freestanding" the compiler may
|
||||
# "optimize" memcmp() by invoking memcmp(), thus causing infinite recursion.
|
||||
$(LIBKVM_STRING_OBJ): $(OUTPUT)/%.o: %.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -ffreestanding $< -o $@
|
||||
|
||||
$(shell mkdir -p $(sort $(dir $(TEST_GEN_PROGS))))
|
||||
$(SPLIT_TEST_GEN_OBJ): $(GEN_HDRS)
|
||||
$(TEST_GEN_PROGS): $(LIBKVM_OBJS)
|
||||
$(TEST_GEN_PROGS_EXTENDED): $(LIBKVM_OBJS)
|
||||
$(TEST_GEN_OBJ): $(GEN_HDRS)
|
||||
|
||||
cscope: include_paths = $(LINUX_TOOL_INCLUDE) $(LINUX_HDR_PATH) include lib ..
|
||||
cscope:
|
||||
$(RM) cscope.*
|
||||
(find $(include_paths) -name '*.h' \
|
||||
-exec realpath --relative-base=$(PWD) {} \;; \
|
||||
find . -name '*.c' \
|
||||
-exec realpath --relative-base=$(PWD) {} \;) | sort -u > cscope.files
|
||||
cscope -b
|
||||
|
330
tools/testing/selftests/kvm/Makefile.kvm
Normal file
330
tools/testing/selftests/kvm/Makefile.kvm
Normal file
@ -0,0 +1,330 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
include ../../../build/Build.include
|
||||
|
||||
all:
|
||||
|
||||
LIBKVM += lib/assert.c
|
||||
LIBKVM += lib/elf.c
|
||||
LIBKVM += lib/guest_modes.c
|
||||
LIBKVM += lib/io.c
|
||||
LIBKVM += lib/kvm_util.c
|
||||
LIBKVM += lib/memstress.c
|
||||
LIBKVM += lib/guest_sprintf.c
|
||||
LIBKVM += lib/rbtree.c
|
||||
LIBKVM += lib/sparsebit.c
|
||||
LIBKVM += lib/test_util.c
|
||||
LIBKVM += lib/ucall_common.c
|
||||
LIBKVM += lib/userfaultfd_util.c
|
||||
|
||||
LIBKVM_STRING += lib/string_override.c
|
||||
|
||||
LIBKVM_x86 += lib/x86/apic.c
|
||||
LIBKVM_x86 += lib/x86/handlers.S
|
||||
LIBKVM_x86 += lib/x86/hyperv.c
|
||||
LIBKVM_x86 += lib/x86/memstress.c
|
||||
LIBKVM_x86 += lib/x86/pmu.c
|
||||
LIBKVM_x86 += lib/x86/processor.c
|
||||
LIBKVM_x86 += lib/x86/sev.c
|
||||
LIBKVM_x86 += lib/x86/svm.c
|
||||
LIBKVM_x86 += lib/x86/ucall.c
|
||||
LIBKVM_x86 += lib/x86/vmx.c
|
||||
|
||||
LIBKVM_arm64 += lib/arm64/gic.c
|
||||
LIBKVM_arm64 += lib/arm64/gic_v3.c
|
||||
LIBKVM_arm64 += lib/arm64/gic_v3_its.c
|
||||
LIBKVM_arm64 += lib/arm64/handlers.S
|
||||
LIBKVM_arm64 += lib/arm64/processor.c
|
||||
LIBKVM_arm64 += lib/arm64/spinlock.c
|
||||
LIBKVM_arm64 += lib/arm64/ucall.c
|
||||
LIBKVM_arm64 += lib/arm64/vgic.c
|
||||
|
||||
LIBKVM_s390 += lib/s390/diag318_test_handler.c
|
||||
LIBKVM_s390 += lib/s390/processor.c
|
||||
LIBKVM_s390 += lib/s390/ucall.c
|
||||
LIBKVM_s390 += lib/s390/facility.c
|
||||
|
||||
LIBKVM_riscv += lib/riscv/handlers.S
|
||||
LIBKVM_riscv += lib/riscv/processor.c
|
||||
LIBKVM_riscv += lib/riscv/ucall.c
|
||||
|
||||
# Non-compiled test targets
|
||||
TEST_PROGS_x86 += x86/nx_huge_pages_test.sh
|
||||
|
||||
# Compiled test targets
|
||||
TEST_GEN_PROGS_x86 = x86/cpuid_test
|
||||
TEST_GEN_PROGS_x86 += x86/cr4_cpuid_sync_test
|
||||
TEST_GEN_PROGS_x86 += x86/dirty_log_page_splitting_test
|
||||
TEST_GEN_PROGS_x86 += x86/feature_msrs_test
|
||||
TEST_GEN_PROGS_x86 += x86/exit_on_emulation_failure_test
|
||||
TEST_GEN_PROGS_x86 += x86/fix_hypercall_test
|
||||
TEST_GEN_PROGS_x86 += x86/hwcr_msr_test
|
||||
TEST_GEN_PROGS_x86 += x86/hyperv_clock
|
||||
TEST_GEN_PROGS_x86 += x86/hyperv_cpuid
|
||||
TEST_GEN_PROGS_x86 += x86/hyperv_evmcs
|
||||
TEST_GEN_PROGS_x86 += x86/hyperv_extended_hypercalls
|
||||
TEST_GEN_PROGS_x86 += x86/hyperv_features
|
||||
TEST_GEN_PROGS_x86 += x86/hyperv_ipi
|
||||
TEST_GEN_PROGS_x86 += x86/hyperv_svm_test
|
||||
TEST_GEN_PROGS_x86 += x86/hyperv_tlb_flush
|
||||
TEST_GEN_PROGS_x86 += x86/kvm_clock_test
|
||||
TEST_GEN_PROGS_x86 += x86/kvm_pv_test
|
||||
TEST_GEN_PROGS_x86 += x86/monitor_mwait_test
|
||||
TEST_GEN_PROGS_x86 += x86/nested_exceptions_test
|
||||
TEST_GEN_PROGS_x86 += x86/platform_info_test
|
||||
TEST_GEN_PROGS_x86 += x86/pmu_counters_test
|
||||
TEST_GEN_PROGS_x86 += x86/pmu_event_filter_test
|
||||
TEST_GEN_PROGS_x86 += x86/private_mem_conversions_test
|
||||
TEST_GEN_PROGS_x86 += x86/private_mem_kvm_exits_test
|
||||
TEST_GEN_PROGS_x86 += x86/set_boot_cpu_id
|
||||
TEST_GEN_PROGS_x86 += x86/set_sregs_test
|
||||
TEST_GEN_PROGS_x86 += x86/smaller_maxphyaddr_emulation_test
|
||||
TEST_GEN_PROGS_x86 += x86/smm_test
|
||||
TEST_GEN_PROGS_x86 += x86/state_test
|
||||
TEST_GEN_PROGS_x86 += x86/vmx_preemption_timer_test
|
||||
TEST_GEN_PROGS_x86 += x86/svm_vmcall_test
|
||||
TEST_GEN_PROGS_x86 += x86/svm_int_ctl_test
|
||||
TEST_GEN_PROGS_x86 += x86/svm_nested_shutdown_test
|
||||
TEST_GEN_PROGS_x86 += x86/svm_nested_soft_inject_test
|
||||
TEST_GEN_PROGS_x86 += x86/tsc_scaling_sync
|
||||
TEST_GEN_PROGS_x86 += x86/sync_regs_test
|
||||
TEST_GEN_PROGS_x86 += x86/ucna_injection_test
|
||||
TEST_GEN_PROGS_x86 += x86/userspace_io_test
|
||||
TEST_GEN_PROGS_x86 += x86/userspace_msr_exit_test
|
||||
TEST_GEN_PROGS_x86 += x86/vmx_apic_access_test
|
||||
TEST_GEN_PROGS_x86 += x86/vmx_close_while_nested_test
|
||||
TEST_GEN_PROGS_x86 += x86/vmx_dirty_log_test
|
||||
TEST_GEN_PROGS_x86 += x86/vmx_exception_with_invalid_guest_state
|
||||
TEST_GEN_PROGS_x86 += x86/vmx_msrs_test
|
||||
TEST_GEN_PROGS_x86 += x86/vmx_invalid_nested_guest_state
|
||||
TEST_GEN_PROGS_x86 += x86/vmx_set_nested_state_test
|
||||
TEST_GEN_PROGS_x86 += x86/vmx_tsc_adjust_test
|
||||
TEST_GEN_PROGS_x86 += x86/vmx_nested_tsc_scaling_test
|
||||
TEST_GEN_PROGS_x86 += x86/apic_bus_clock_test
|
||||
TEST_GEN_PROGS_x86 += x86/xapic_ipi_test
|
||||
TEST_GEN_PROGS_x86 += x86/xapic_state_test
|
||||
TEST_GEN_PROGS_x86 += x86/xcr0_cpuid_test
|
||||
TEST_GEN_PROGS_x86 += x86/xss_msr_test
|
||||
TEST_GEN_PROGS_x86 += x86/debug_regs
|
||||
TEST_GEN_PROGS_x86 += x86/tsc_msrs_test
|
||||
TEST_GEN_PROGS_x86 += x86/vmx_pmu_caps_test
|
||||
TEST_GEN_PROGS_x86 += x86/xen_shinfo_test
|
||||
TEST_GEN_PROGS_x86 += x86/xen_vmcall_test
|
||||
TEST_GEN_PROGS_x86 += x86/sev_init2_tests
|
||||
TEST_GEN_PROGS_x86 += x86/sev_migrate_tests
|
||||
TEST_GEN_PROGS_x86 += x86/sev_smoke_test
|
||||
TEST_GEN_PROGS_x86 += x86/amx_test
|
||||
TEST_GEN_PROGS_x86 += x86/max_vcpuid_cap_test
|
||||
TEST_GEN_PROGS_x86 += x86/triple_fault_event_test
|
||||
TEST_GEN_PROGS_x86 += x86/recalc_apic_map_test
|
||||
TEST_GEN_PROGS_x86 += access_tracking_perf_test
|
||||
TEST_GEN_PROGS_x86 += coalesced_io_test
|
||||
TEST_GEN_PROGS_x86 += demand_paging_test
|
||||
TEST_GEN_PROGS_x86 += dirty_log_test
|
||||
TEST_GEN_PROGS_x86 += dirty_log_perf_test
|
||||
TEST_GEN_PROGS_x86 += guest_memfd_test
|
||||
TEST_GEN_PROGS_x86 += guest_print_test
|
||||
TEST_GEN_PROGS_x86 += hardware_disable_test
|
||||
TEST_GEN_PROGS_x86 += kvm_create_max_vcpus
|
||||
TEST_GEN_PROGS_x86 += kvm_page_table_test
|
||||
TEST_GEN_PROGS_x86 += memslot_modification_stress_test
|
||||
TEST_GEN_PROGS_x86 += memslot_perf_test
|
||||
TEST_GEN_PROGS_x86 += mmu_stress_test
|
||||
TEST_GEN_PROGS_x86 += rseq_test
|
||||
TEST_GEN_PROGS_x86 += set_memory_region_test
|
||||
TEST_GEN_PROGS_x86 += steal_time
|
||||
TEST_GEN_PROGS_x86 += kvm_binary_stats_test
|
||||
TEST_GEN_PROGS_x86 += system_counter_offset_test
|
||||
TEST_GEN_PROGS_x86 += pre_fault_memory_test
|
||||
|
||||
# Compiled outputs used by test targets
|
||||
TEST_GEN_PROGS_EXTENDED_x86 += x86/nx_huge_pages_test
|
||||
|
||||
TEST_GEN_PROGS_arm64 += arm64/aarch32_id_regs
|
||||
TEST_GEN_PROGS_arm64 += arm64/arch_timer_edge_cases
|
||||
TEST_GEN_PROGS_arm64 += arm64/debug-exceptions
|
||||
TEST_GEN_PROGS_arm64 += arm64/hypercalls
|
||||
TEST_GEN_PROGS_arm64 += arm64/mmio_abort
|
||||
TEST_GEN_PROGS_arm64 += arm64/page_fault_test
|
||||
TEST_GEN_PROGS_arm64 += arm64/psci_test
|
||||
TEST_GEN_PROGS_arm64 += arm64/set_id_regs
|
||||
TEST_GEN_PROGS_arm64 += arm64/smccc_filter
|
||||
TEST_GEN_PROGS_arm64 += arm64/vcpu_width_config
|
||||
TEST_GEN_PROGS_arm64 += arm64/vgic_init
|
||||
TEST_GEN_PROGS_arm64 += arm64/vgic_irq
|
||||
TEST_GEN_PROGS_arm64 += arm64/vgic_lpi_stress
|
||||
TEST_GEN_PROGS_arm64 += arm64/vpmu_counter_access
|
||||
TEST_GEN_PROGS_arm64 += arm64/no-vgic-v3
|
||||
TEST_GEN_PROGS_arm64 += access_tracking_perf_test
|
||||
TEST_GEN_PROGS_arm64 += arch_timer
|
||||
TEST_GEN_PROGS_arm64 += coalesced_io_test
|
||||
TEST_GEN_PROGS_arm64 += demand_paging_test
|
||||
TEST_GEN_PROGS_arm64 += dirty_log_test
|
||||
TEST_GEN_PROGS_arm64 += dirty_log_perf_test
|
||||
TEST_GEN_PROGS_arm64 += guest_print_test
|
||||
TEST_GEN_PROGS_arm64 += get-reg-list
|
||||
TEST_GEN_PROGS_arm64 += kvm_create_max_vcpus
|
||||
TEST_GEN_PROGS_arm64 += kvm_page_table_test
|
||||
TEST_GEN_PROGS_arm64 += memslot_modification_stress_test
|
||||
TEST_GEN_PROGS_arm64 += memslot_perf_test
|
||||
TEST_GEN_PROGS_arm64 += mmu_stress_test
|
||||
TEST_GEN_PROGS_arm64 += rseq_test
|
||||
TEST_GEN_PROGS_arm64 += set_memory_region_test
|
||||
TEST_GEN_PROGS_arm64 += steal_time
|
||||
TEST_GEN_PROGS_arm64 += kvm_binary_stats_test
|
||||
|
||||
TEST_GEN_PROGS_s390 = s390/memop
|
||||
TEST_GEN_PROGS_s390 += s390/resets
|
||||
TEST_GEN_PROGS_s390 += s390/sync_regs_test
|
||||
TEST_GEN_PROGS_s390 += s390/tprot
|
||||
TEST_GEN_PROGS_s390 += s390/cmma_test
|
||||
TEST_GEN_PROGS_s390 += s390/debug_test
|
||||
TEST_GEN_PROGS_s390 += s390/cpumodel_subfuncs_test
|
||||
TEST_GEN_PROGS_s390 += s390/shared_zeropage_test
|
||||
TEST_GEN_PROGS_s390 += s390/ucontrol_test
|
||||
TEST_GEN_PROGS_s390 += demand_paging_test
|
||||
TEST_GEN_PROGS_s390 += dirty_log_test
|
||||
TEST_GEN_PROGS_s390 += guest_print_test
|
||||
TEST_GEN_PROGS_s390 += kvm_create_max_vcpus
|
||||
TEST_GEN_PROGS_s390 += kvm_page_table_test
|
||||
TEST_GEN_PROGS_s390 += rseq_test
|
||||
TEST_GEN_PROGS_s390 += set_memory_region_test
|
||||
TEST_GEN_PROGS_s390 += kvm_binary_stats_test
|
||||
|
||||
TEST_GEN_PROGS_riscv += riscv/sbi_pmu_test
|
||||
TEST_GEN_PROGS_riscv += riscv/ebreak_test
|
||||
TEST_GEN_PROGS_riscv += arch_timer
|
||||
TEST_GEN_PROGS_riscv += coalesced_io_test
|
||||
TEST_GEN_PROGS_riscv += demand_paging_test
|
||||
TEST_GEN_PROGS_riscv += dirty_log_test
|
||||
TEST_GEN_PROGS_riscv += get-reg-list
|
||||
TEST_GEN_PROGS_riscv += guest_print_test
|
||||
TEST_GEN_PROGS_riscv += kvm_binary_stats_test
|
||||
TEST_GEN_PROGS_riscv += kvm_create_max_vcpus
|
||||
TEST_GEN_PROGS_riscv += kvm_page_table_test
|
||||
TEST_GEN_PROGS_riscv += set_memory_region_test
|
||||
TEST_GEN_PROGS_riscv += steal_time
|
||||
|
||||
SPLIT_TESTS += arch_timer
|
||||
SPLIT_TESTS += get-reg-list
|
||||
|
||||
TEST_PROGS += $(TEST_PROGS_$(ARCH))
|
||||
TEST_GEN_PROGS += $(TEST_GEN_PROGS_$(ARCH))
|
||||
TEST_GEN_PROGS_EXTENDED += $(TEST_GEN_PROGS_EXTENDED_$(ARCH))
|
||||
LIBKVM += $(LIBKVM_$(ARCH))
|
||||
|
||||
OVERRIDE_TARGETS = 1
|
||||
|
||||
# lib.mak defines $(OUTPUT), prepends $(OUTPUT)/ to $(TEST_GEN_PROGS), and most
|
||||
# importantly defines, i.e. overwrites, $(CC) (unless `make -e` or `make CC=`,
|
||||
# which causes the environment variable to override the makefile).
|
||||
include ../lib.mk
|
||||
|
||||
INSTALL_HDR_PATH = $(top_srcdir)/usr
|
||||
LINUX_HDR_PATH = $(INSTALL_HDR_PATH)/include/
|
||||
LINUX_TOOL_INCLUDE = $(top_srcdir)/tools/include
|
||||
LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/$(ARCH)/include
|
||||
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 \
|
||||
-fno-stack-protector -fno-PIE -fno-strict-aliasing \
|
||||
-I$(LINUX_TOOL_INCLUDE) -I$(LINUX_TOOL_ARCH_INCLUDE) \
|
||||
-I$(LINUX_HDR_PATH) -Iinclude -I$(<D) -Iinclude/$(ARCH) \
|
||||
-I ../rseq -I.. $(EXTRA_CFLAGS) $(KHDR_INCLUDES)
|
||||
ifeq ($(ARCH),s390)
|
||||
CFLAGS += -march=z10
|
||||
endif
|
||||
ifeq ($(ARCH),x86)
|
||||
ifeq ($(shell echo "void foo(void) { }" | $(CC) -march=x86-64-v2 -x c - -c -o /dev/null 2>/dev/null; echo "$$?"),0)
|
||||
CFLAGS += -march=x86-64-v2
|
||||
endif
|
||||
endif
|
||||
ifeq ($(ARCH),arm64)
|
||||
tools_dir := $(top_srcdir)/tools
|
||||
arm64_tools_dir := $(tools_dir)/arch/arm64/tools/
|
||||
|
||||
ifneq ($(abs_objdir),)
|
||||
arm64_hdr_outdir := $(abs_objdir)/tools/
|
||||
else
|
||||
arm64_hdr_outdir := $(tools_dir)/
|
||||
endif
|
||||
|
||||
GEN_HDRS := $(arm64_hdr_outdir)arch/arm64/include/generated/
|
||||
CFLAGS += -I$(GEN_HDRS)
|
||||
|
||||
$(GEN_HDRS): $(wildcard $(arm64_tools_dir)/*)
|
||||
$(MAKE) -C $(arm64_tools_dir) OUTPUT=$(arm64_hdr_outdir)
|
||||
endif
|
||||
|
||||
no-pie-option := $(call try-run, echo 'int main(void) { return 0; }' | \
|
||||
$(CC) -Werror $(CFLAGS) -no-pie -x c - -o "$$TMP", -no-pie)
|
||||
|
||||
# On s390, build the testcases KVM-enabled
|
||||
pgste-option = $(call try-run, echo 'int main(void) { return 0; }' | \
|
||||
$(CC) -Werror -Wl$(comma)--s390-pgste -x c - -o "$$TMP",-Wl$(comma)--s390-pgste)
|
||||
|
||||
LDLIBS += -ldl
|
||||
LDFLAGS += -pthread $(no-pie-option) $(pgste-option)
|
||||
|
||||
LIBKVM_C := $(filter %.c,$(LIBKVM))
|
||||
LIBKVM_S := $(filter %.S,$(LIBKVM))
|
||||
LIBKVM_C_OBJ := $(patsubst %.c, $(OUTPUT)/%.o, $(LIBKVM_C))
|
||||
LIBKVM_S_OBJ := $(patsubst %.S, $(OUTPUT)/%.o, $(LIBKVM_S))
|
||||
LIBKVM_STRING_OBJ := $(patsubst %.c, $(OUTPUT)/%.o, $(LIBKVM_STRING))
|
||||
LIBKVM_OBJS = $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ) $(LIBKVM_STRING_OBJ)
|
||||
SPLIT_TEST_GEN_PROGS := $(patsubst %, $(OUTPUT)/%, $(SPLIT_TESTS))
|
||||
SPLIT_TEST_GEN_OBJ := $(patsubst %, $(OUTPUT)/$(ARCH)/%.o, $(SPLIT_TESTS))
|
||||
|
||||
TEST_GEN_OBJ = $(patsubst %, %.o, $(TEST_GEN_PROGS))
|
||||
TEST_GEN_OBJ += $(patsubst %, %.o, $(TEST_GEN_PROGS_EXTENDED))
|
||||
TEST_DEP_FILES = $(patsubst %.o, %.d, $(TEST_GEN_OBJ))
|
||||
TEST_DEP_FILES += $(patsubst %.o, %.d, $(LIBKVM_OBJS))
|
||||
TEST_DEP_FILES += $(patsubst %.o, %.d, $(SPLIT_TEST_GEN_OBJ))
|
||||
-include $(TEST_DEP_FILES)
|
||||
|
||||
$(shell mkdir -p $(sort $(OUTPUT)/$(ARCH) $(dir $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ))))
|
||||
|
||||
$(filter-out $(SPLIT_TEST_GEN_PROGS), $(TEST_GEN_PROGS)) \
|
||||
$(TEST_GEN_PROGS_EXTENDED): %: %.o
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $< $(LIBKVM_OBJS) $(LDLIBS) -o $@
|
||||
$(TEST_GEN_OBJ): $(OUTPUT)/%.o: %.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
|
||||
|
||||
$(SPLIT_TEST_GEN_PROGS): $(OUTPUT)/%: $(OUTPUT)/%.o $(OUTPUT)/$(ARCH)/%.o
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^ $(LDLIBS) -o $@
|
||||
$(SPLIT_TEST_GEN_OBJ): $(OUTPUT)/$(ARCH)/%.o: $(ARCH)/%.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
|
||||
|
||||
EXTRA_CLEAN += $(GEN_HDRS) \
|
||||
$(LIBKVM_OBJS) \
|
||||
$(SPLIT_TEST_GEN_OBJ) \
|
||||
$(TEST_DEP_FILES) \
|
||||
$(TEST_GEN_OBJ) \
|
||||
cscope.*
|
||||
|
||||
$(LIBKVM_C_OBJ): $(OUTPUT)/%.o: %.c $(GEN_HDRS)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
|
||||
|
||||
$(LIBKVM_S_OBJ): $(OUTPUT)/%.o: %.S $(GEN_HDRS)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
|
||||
|
||||
# Compile the string overrides as freestanding to prevent the compiler from
|
||||
# generating self-referential code, e.g. without "freestanding" the compiler may
|
||||
# "optimize" memcmp() by invoking memcmp(), thus causing infinite recursion.
|
||||
$(LIBKVM_STRING_OBJ): $(OUTPUT)/%.o: %.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -ffreestanding $< -o $@
|
||||
|
||||
$(shell mkdir -p $(sort $(dir $(TEST_GEN_PROGS))))
|
||||
$(SPLIT_TEST_GEN_OBJ): $(GEN_HDRS)
|
||||
$(TEST_GEN_PROGS): $(LIBKVM_OBJS)
|
||||
$(TEST_GEN_PROGS_EXTENDED): $(LIBKVM_OBJS)
|
||||
$(TEST_GEN_OBJ): $(GEN_HDRS)
|
||||
|
||||
cscope: include_paths = $(LINUX_TOOL_INCLUDE) $(LINUX_HDR_PATH) include lib ..
|
||||
cscope:
|
||||
$(RM) cscope.*
|
||||
(find $(include_paths) -name '*.h' \
|
||||
-exec realpath --relative-base=$(PWD) {} \;; \
|
||||
find . -name '*.c' \
|
||||
-exec realpath --relative-base=$(PWD) {} \;) | sort -u > cscope.files
|
||||
cscope -b
|
@ -97,7 +97,7 @@ static void test_user_raz_wi(struct kvm_vcpu *vcpu)
|
||||
uint64_t reg_id = raz_wi_reg_ids[i];
|
||||
uint64_t val;
|
||||
|
||||
vcpu_get_reg(vcpu, reg_id, &val);
|
||||
val = vcpu_get_reg(vcpu, reg_id);
|
||||
TEST_ASSERT_EQ(val, 0);
|
||||
|
||||
/*
|
||||
@ -106,7 +106,7 @@ static void test_user_raz_wi(struct kvm_vcpu *vcpu)
|
||||
*/
|
||||
vcpu_set_reg(vcpu, reg_id, BAD_ID_REG_VAL);
|
||||
|
||||
vcpu_get_reg(vcpu, reg_id, &val);
|
||||
val = vcpu_get_reg(vcpu, reg_id);
|
||||
TEST_ASSERT_EQ(val, 0);
|
||||
}
|
||||
}
|
||||
@ -126,14 +126,14 @@ static void test_user_raz_invariant(struct kvm_vcpu *vcpu)
|
||||
uint64_t reg_id = raz_invariant_reg_ids[i];
|
||||
uint64_t val;
|
||||
|
||||
vcpu_get_reg(vcpu, reg_id, &val);
|
||||
val = vcpu_get_reg(vcpu, reg_id);
|
||||
TEST_ASSERT_EQ(val, 0);
|
||||
|
||||
r = __vcpu_set_reg(vcpu, reg_id, BAD_ID_REG_VAL);
|
||||
TEST_ASSERT(r < 0 && errno == EINVAL,
|
||||
"unexpected KVM_SET_ONE_REG error: r=%d, errno=%d", r, errno);
|
||||
|
||||
vcpu_get_reg(vcpu, reg_id, &val);
|
||||
val = vcpu_get_reg(vcpu, reg_id);
|
||||
TEST_ASSERT_EQ(val, 0);
|
||||
}
|
||||
}
|
||||
@ -144,7 +144,7 @@ static bool vcpu_aarch64_only(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
uint64_t val, el0;
|
||||
|
||||
vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1), &val);
|
||||
val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1));
|
||||
|
||||
el0 = FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL0), val);
|
||||
return el0 == ID_AA64PFR0_EL1_ELx_64BIT_ONLY;
|
@ -501,7 +501,7 @@ void test_single_step_from_userspace(int test_cnt)
|
||||
TEST_ASSERT(ss_enable, "Unexpected KVM_EXIT_DEBUG");
|
||||
|
||||
/* Check if the current pc is expected. */
|
||||
vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pc), &pc);
|
||||
pc = vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pc));
|
||||
TEST_ASSERT(!test_pc || pc == test_pc,
|
||||
"Unexpected pc 0x%lx (expected 0x%lx)",
|
||||
pc, test_pc);
|
||||
@ -583,7 +583,7 @@ int main(int argc, char *argv[])
|
||||
uint64_t aa64dfr0;
|
||||
|
||||
vm = vm_create_with_one_vcpu(&vcpu, guest_code);
|
||||
vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64DFR0_EL1), &aa64dfr0);
|
||||
aa64dfr0 = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64DFR0_EL1));
|
||||
__TEST_REQUIRE(debug_version(aa64dfr0) >= 6,
|
||||
"Armv8 debug architecture not supported.");
|
||||
kvm_vm_free(vm);
|
@ -173,7 +173,7 @@ static void test_fw_regs_before_vm_start(struct kvm_vcpu *vcpu)
|
||||
const struct kvm_fw_reg_info *reg_info = &fw_reg_info[i];
|
||||
|
||||
/* First 'read' should be an upper limit of the features supported */
|
||||
vcpu_get_reg(vcpu, reg_info->reg, &val);
|
||||
val = vcpu_get_reg(vcpu, reg_info->reg);
|
||||
TEST_ASSERT(val == FW_REG_ULIMIT_VAL(reg_info->max_feat_bit),
|
||||
"Expected all the features to be set for reg: 0x%lx; expected: 0x%lx; read: 0x%lx",
|
||||
reg_info->reg, FW_REG_ULIMIT_VAL(reg_info->max_feat_bit), val);
|
||||
@ -184,7 +184,7 @@ static void test_fw_regs_before_vm_start(struct kvm_vcpu *vcpu)
|
||||
"Failed to clear all the features of reg: 0x%lx; ret: %d",
|
||||
reg_info->reg, errno);
|
||||
|
||||
vcpu_get_reg(vcpu, reg_info->reg, &val);
|
||||
val = vcpu_get_reg(vcpu, reg_info->reg);
|
||||
TEST_ASSERT(val == 0,
|
||||
"Expected all the features to be cleared for reg: 0x%lx", reg_info->reg);
|
||||
|
||||
@ -214,7 +214,7 @@ static void test_fw_regs_after_vm_start(struct kvm_vcpu *vcpu)
|
||||
* Before starting the VM, the test clears all the bits.
|
||||
* Check if that's still the case.
|
||||
*/
|
||||
vcpu_get_reg(vcpu, reg_info->reg, &val);
|
||||
val = vcpu_get_reg(vcpu, reg_info->reg);
|
||||
TEST_ASSERT(val == 0,
|
||||
"Expected all the features to be cleared for reg: 0x%lx",
|
||||
reg_info->reg);
|
@ -164,7 +164,7 @@ int main(int argc, char *argv[])
|
||||
uint64_t pfr0;
|
||||
|
||||
vm = vm_create_with_one_vcpu(&vcpu, NULL);
|
||||
vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1), &pfr0);
|
||||
pfr0 = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1));
|
||||
__TEST_REQUIRE(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_GIC), pfr0),
|
||||
"GICv3 not supported.");
|
||||
kvm_vm_free(vm);
|
@ -111,8 +111,8 @@ static void assert_vcpu_reset(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
uint64_t obs_pc, obs_x0;
|
||||
|
||||
vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pc), &obs_pc);
|
||||
vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.regs[0]), &obs_x0);
|
||||
obs_pc = vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pc));
|
||||
obs_x0 = vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.regs[0]));
|
||||
|
||||
TEST_ASSERT(obs_pc == CPU_ON_ENTRY_ADDR,
|
||||
"unexpected target cpu pc: %lx (expected: %lx)",
|
||||
@ -152,7 +152,7 @@ static void host_test_cpu_on(void)
|
||||
*/
|
||||
vcpu_power_off(target);
|
||||
|
||||
vcpu_get_reg(target, KVM_ARM64_SYS_REG(SYS_MPIDR_EL1), &target_mpidr);
|
||||
target_mpidr = vcpu_get_reg(target, KVM_ARM64_SYS_REG(SYS_MPIDR_EL1));
|
||||
vcpu_args_set(source, 1, target_mpidr & MPIDR_HWID_BITMASK);
|
||||
enter_guest(source);
|
||||
|
||||
@ -244,7 +244,7 @@ static void host_test_system_off2(void)
|
||||
|
||||
setup_vm(guest_test_system_off2, &source, &target);
|
||||
|
||||
vcpu_get_reg(target, KVM_REG_ARM_PSCI_VERSION, &psci_version);
|
||||
psci_version = vcpu_get_reg(target, KVM_REG_ARM_PSCI_VERSION);
|
||||
|
||||
TEST_ASSERT(psci_version >= PSCI_VERSION(1, 3),
|
||||
"Unexpected PSCI version %lu.%lu",
|
@ -345,7 +345,7 @@ static uint64_t test_reg_set_success(struct kvm_vcpu *vcpu, uint64_t reg,
|
||||
uint64_t mask = ftr_bits->mask;
|
||||
uint64_t val, new_val, ftr;
|
||||
|
||||
vcpu_get_reg(vcpu, reg, &val);
|
||||
val = vcpu_get_reg(vcpu, reg);
|
||||
ftr = (val & mask) >> shift;
|
||||
|
||||
ftr = get_safe_value(ftr_bits, ftr);
|
||||
@ -355,7 +355,7 @@ static uint64_t test_reg_set_success(struct kvm_vcpu *vcpu, uint64_t reg,
|
||||
val |= ftr;
|
||||
|
||||
vcpu_set_reg(vcpu, reg, val);
|
||||
vcpu_get_reg(vcpu, reg, &new_val);
|
||||
new_val = vcpu_get_reg(vcpu, reg);
|
||||
TEST_ASSERT_EQ(new_val, val);
|
||||
|
||||
return new_val;
|
||||
@ -369,7 +369,7 @@ static void test_reg_set_fail(struct kvm_vcpu *vcpu, uint64_t reg,
|
||||
uint64_t val, old_val, ftr;
|
||||
int r;
|
||||
|
||||
vcpu_get_reg(vcpu, reg, &val);
|
||||
val = vcpu_get_reg(vcpu, reg);
|
||||
ftr = (val & mask) >> shift;
|
||||
|
||||
ftr = get_invalid_value(ftr_bits, ftr);
|
||||
@ -383,7 +383,7 @@ static void test_reg_set_fail(struct kvm_vcpu *vcpu, uint64_t reg,
|
||||
TEST_ASSERT(r < 0 && errno == EINVAL,
|
||||
"Unexpected KVM_SET_ONE_REG error: r=%d, errno=%d", r, errno);
|
||||
|
||||
vcpu_get_reg(vcpu, reg, &val);
|
||||
val = vcpu_get_reg(vcpu, reg);
|
||||
TEST_ASSERT_EQ(val, old_val);
|
||||
}
|
||||
|
||||
@ -470,7 +470,7 @@ static void test_user_set_mpam_reg(struct kvm_vcpu *vcpu)
|
||||
}
|
||||
|
||||
/* Get the id register value */
|
||||
vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1), &val);
|
||||
val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1));
|
||||
|
||||
/* Try to set MPAM=0. This should always be possible. */
|
||||
val &= ~ID_AA64PFR0_EL1_MPAM_MASK;
|
||||
@ -507,7 +507,7 @@ static void test_user_set_mpam_reg(struct kvm_vcpu *vcpu)
|
||||
}
|
||||
|
||||
/* Get the id register value */
|
||||
vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR1_EL1), &val);
|
||||
val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR1_EL1));
|
||||
|
||||
/* Try to set MPAM_frac=0. This should always be possible. */
|
||||
val &= ~ID_AA64PFR1_EL1_MPAM_frac_MASK;
|
||||
@ -575,7 +575,7 @@ static void test_clidr(struct kvm_vcpu *vcpu)
|
||||
uint64_t clidr;
|
||||
int level;
|
||||
|
||||
vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_CLIDR_EL1), &clidr);
|
||||
clidr = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_CLIDR_EL1));
|
||||
|
||||
/* find the first empty level in the cache hierarchy */
|
||||
for (level = 1; level < 7; level++) {
|
||||
@ -600,7 +600,7 @@ static void test_ctr(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
u64 ctr;
|
||||
|
||||
vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_CTR_EL0), &ctr);
|
||||
ctr = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_CTR_EL0));
|
||||
ctr &= ~CTR_EL0_DIC_MASK;
|
||||
if (ctr & CTR_EL0_IminLine_MASK)
|
||||
ctr--;
|
||||
@ -616,7 +616,7 @@ static void test_vcpu_ftr_id_regs(struct kvm_vcpu *vcpu)
|
||||
test_clidr(vcpu);
|
||||
test_ctr(vcpu);
|
||||
|
||||
vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_MPIDR_EL1), &val);
|
||||
val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_MPIDR_EL1));
|
||||
val++;
|
||||
vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_MPIDR_EL1), val);
|
||||
|
||||
@ -629,7 +629,7 @@ static void test_assert_id_reg_unchanged(struct kvm_vcpu *vcpu, uint32_t encodin
|
||||
size_t idx = encoding_to_range_idx(encoding);
|
||||
uint64_t observed;
|
||||
|
||||
vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(encoding), &observed);
|
||||
observed = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(encoding));
|
||||
TEST_ASSERT_EQ(test_reg_vals[idx], observed);
|
||||
}
|
||||
|
||||
@ -664,7 +664,7 @@ int main(void)
|
||||
vm = vm_create_with_one_vcpu(&vcpu, guest_code);
|
||||
|
||||
/* Check for AARCH64 only system */
|
||||
vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1), &val);
|
||||
val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1));
|
||||
el0 = FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL0), val);
|
||||
aarch64_only = (el0 == ID_AA64PFR0_EL1_ELx_64BIT_ONLY);
|
||||
|
@ -440,8 +440,7 @@ static void create_vpmu_vm(void *guest_code)
|
||||
"Failed to create vgic-v3, skipping");
|
||||
|
||||
/* Make sure that PMUv3 support is indicated in the ID register */
|
||||
vcpu_get_reg(vpmu_vm.vcpu,
|
||||
KVM_ARM64_SYS_REG(SYS_ID_AA64DFR0_EL1), &dfr0);
|
||||
dfr0 = vcpu_get_reg(vpmu_vm.vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64DFR0_EL1));
|
||||
pmuver = FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMUVer), dfr0);
|
||||
TEST_ASSERT(pmuver != ID_AA64DFR0_EL1_PMUVer_IMP_DEF &&
|
||||
pmuver >= ID_AA64DFR0_EL1_PMUVer_IMP,
|
||||
@ -484,7 +483,7 @@ static void test_create_vpmu_vm_with_pmcr_n(uint64_t pmcr_n, bool expect_fail)
|
||||
create_vpmu_vm(guest_code);
|
||||
vcpu = vpmu_vm.vcpu;
|
||||
|
||||
vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0), &pmcr_orig);
|
||||
pmcr_orig = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0));
|
||||
pmcr = pmcr_orig;
|
||||
|
||||
/*
|
||||
@ -493,7 +492,7 @@ static void test_create_vpmu_vm_with_pmcr_n(uint64_t pmcr_n, bool expect_fail)
|
||||
*/
|
||||
set_pmcr_n(&pmcr, pmcr_n);
|
||||
vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0), pmcr);
|
||||
vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0), &pmcr);
|
||||
pmcr = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0));
|
||||
|
||||
if (expect_fail)
|
||||
TEST_ASSERT(pmcr_orig == pmcr,
|
||||
@ -521,7 +520,7 @@ static void run_access_test(uint64_t pmcr_n)
|
||||
vcpu = vpmu_vm.vcpu;
|
||||
|
||||
/* Save the initial sp to restore them later to run the guest again */
|
||||
vcpu_get_reg(vcpu, ARM64_CORE_REG(sp_el1), &sp);
|
||||
sp = vcpu_get_reg(vcpu, ARM64_CORE_REG(sp_el1));
|
||||
|
||||
run_vcpu(vcpu, pmcr_n);
|
||||
|
||||
@ -572,12 +571,12 @@ static void run_pmregs_validity_test(uint64_t pmcr_n)
|
||||
* Test if the 'set' and 'clr' variants of the registers
|
||||
* are initialized based on the number of valid counters.
|
||||
*/
|
||||
vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(set_reg_id), ®_val);
|
||||
reg_val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(set_reg_id));
|
||||
TEST_ASSERT((reg_val & (~valid_counters_mask)) == 0,
|
||||
"Initial read of set_reg: 0x%llx has unimplemented counters enabled: 0x%lx",
|
||||
KVM_ARM64_SYS_REG(set_reg_id), reg_val);
|
||||
|
||||
vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(clr_reg_id), ®_val);
|
||||
reg_val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(clr_reg_id));
|
||||
TEST_ASSERT((reg_val & (~valid_counters_mask)) == 0,
|
||||
"Initial read of clr_reg: 0x%llx has unimplemented counters enabled: 0x%lx",
|
||||
KVM_ARM64_SYS_REG(clr_reg_id), reg_val);
|
||||
@ -589,12 +588,12 @@ static void run_pmregs_validity_test(uint64_t pmcr_n)
|
||||
*/
|
||||
vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(set_reg_id), max_counters_mask);
|
||||
|
||||
vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(set_reg_id), ®_val);
|
||||
reg_val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(set_reg_id));
|
||||
TEST_ASSERT((reg_val & (~valid_counters_mask)) == 0,
|
||||
"Read of set_reg: 0x%llx has unimplemented counters enabled: 0x%lx",
|
||||
KVM_ARM64_SYS_REG(set_reg_id), reg_val);
|
||||
|
||||
vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(clr_reg_id), ®_val);
|
||||
reg_val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(clr_reg_id));
|
||||
TEST_ASSERT((reg_val & (~valid_counters_mask)) == 0,
|
||||
"Read of clr_reg: 0x%llx has unimplemented counters enabled: 0x%lx",
|
||||
KVM_ARM64_SYS_REG(clr_reg_id), reg_val);
|
||||
@ -625,7 +624,7 @@ static uint64_t get_pmcr_n_limit(void)
|
||||
uint64_t pmcr;
|
||||
|
||||
create_vpmu_vm(guest_code);
|
||||
vcpu_get_reg(vpmu_vm.vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0), &pmcr);
|
||||
pmcr = vcpu_get_reg(vpmu_vm.vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0));
|
||||
destroy_vpmu_vm();
|
||||
return get_pmcr_n(pmcr);
|
||||
}
|
@ -21,7 +21,7 @@
|
||||
#include "ucall_common.h"
|
||||
|
||||
#ifdef __aarch64__
|
||||
#include "aarch64/vgic.h"
|
||||
#include "arm64/vgic.h"
|
||||
|
||||
static int gic_fd;
|
||||
|
||||
|
@ -702,16 +702,22 @@ static inline int __vcpu_set_reg(struct kvm_vcpu *vcpu, uint64_t id, uint64_t va
|
||||
|
||||
return __vcpu_ioctl(vcpu, KVM_SET_ONE_REG, ®);
|
||||
}
|
||||
static inline void vcpu_get_reg(struct kvm_vcpu *vcpu, uint64_t id, void *addr)
|
||||
static inline uint64_t vcpu_get_reg(struct kvm_vcpu *vcpu, uint64_t id)
|
||||
{
|
||||
struct kvm_one_reg reg = { .id = id, .addr = (uint64_t)addr };
|
||||
uint64_t val;
|
||||
struct kvm_one_reg reg = { .id = id, .addr = (uint64_t)&val };
|
||||
|
||||
TEST_ASSERT(KVM_REG_SIZE(id) <= sizeof(val), "Reg %lx too big", id);
|
||||
|
||||
vcpu_ioctl(vcpu, KVM_GET_ONE_REG, ®);
|
||||
return val;
|
||||
}
|
||||
static inline void vcpu_set_reg(struct kvm_vcpu *vcpu, uint64_t id, uint64_t val)
|
||||
{
|
||||
struct kvm_one_reg reg = { .id = id, .addr = (uint64_t)&val };
|
||||
|
||||
TEST_ASSERT(KVM_REG_SIZE(id) <= sizeof(val), "Reg %lx too big", id);
|
||||
|
||||
vcpu_ioctl(vcpu, KVM_SET_ONE_REG, ®);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* tools/testing/selftests/kvm/include/x86_64/apic.h
|
||||
*
|
||||
* Copyright (C) 2021, Google LLC.
|
||||
*/
|
||||
|
@ -1,9 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* tools/testing/selftests/kvm/include/x86_64/evmcs.h
|
||||
*
|
||||
* Copyright (C) 2018, Red Hat, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SELFTEST_KVM_EVMCS_H
|
@ -1,9 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* tools/testing/selftests/kvm/include/x86_64/hyperv.h
|
||||
*
|
||||
* Copyright (C) 2021, Red Hat, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SELFTEST_KVM_HYPERV_H
|
@ -1,7 +1,5 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* tools/testing/selftests/kvm/include/x86_64/mce.h
|
||||
*
|
||||
* Copyright (C) 2022, Google LLC.
|
||||
*/
|
||||
|
@ -1,7 +1,5 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* tools/testing/selftests/kvm/include/x86_64/processor.h
|
||||
*
|
||||
* Copyright (C) 2018, Google LLC.
|
||||
*/
|
||||
|
@ -1,10 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* tools/testing/selftests/kvm/include/x86_64/svm.h
|
||||
* This is a copy of arch/x86/include/asm/svm.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SELFTEST_KVM_SVM_H
|
||||
#define SELFTEST_KVM_SVM_H
|
||||
|
@ -1,8 +1,5 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* tools/testing/selftests/kvm/include/x86_64/svm_utils.h
|
||||
* Header for nested SVM testing
|
||||
*
|
||||
* Copyright (C) 2020, Red Hat, Inc.
|
||||
*/
|
||||
|
@ -1,7 +1,5 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* tools/testing/selftests/kvm/include/x86_64/vmx.h
|
||||
*
|
||||
* Copyright (C) 2018, Google LLC.
|
||||
*/
|
||||
|
@ -281,8 +281,8 @@ void aarch64_vcpu_setup(struct kvm_vcpu *vcpu, struct kvm_vcpu_init *init)
|
||||
*/
|
||||
vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_CPACR_EL1), 3 << 20);
|
||||
|
||||
vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_SCTLR_EL1), &sctlr_el1);
|
||||
vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_TCR_EL1), &tcr_el1);
|
||||
sctlr_el1 = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_SCTLR_EL1));
|
||||
tcr_el1 = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_TCR_EL1));
|
||||
|
||||
/* Configure base granule size */
|
||||
switch (vm->mode) {
|
||||
@ -360,8 +360,8 @@ void vcpu_arch_dump(FILE *stream, struct kvm_vcpu *vcpu, uint8_t indent)
|
||||
{
|
||||
uint64_t pstate, pc;
|
||||
|
||||
vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pstate), &pstate);
|
||||
vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pc), &pc);
|
||||
pstate = vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pstate));
|
||||
pc = vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pc));
|
||||
|
||||
fprintf(stream, "%*spstate: 0x%.16lx pc: 0x%.16lx\n",
|
||||
indent, "", pstate, pc);
|
@ -1648,7 +1648,8 @@ int _vcpu_run(struct kvm_vcpu *vcpu)
|
||||
rc = __vcpu_run(vcpu);
|
||||
} while (rc == -1 && errno == EINTR);
|
||||
|
||||
assert_on_unhandled_exception(vcpu);
|
||||
if (!rc)
|
||||
assert_on_unhandled_exception(vcpu);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -221,39 +221,39 @@ void vcpu_arch_dump(FILE *stream, struct kvm_vcpu *vcpu, uint8_t indent)
|
||||
{
|
||||
struct kvm_riscv_core core;
|
||||
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(mode), &core.mode);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.pc), &core.regs.pc);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.ra), &core.regs.ra);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.sp), &core.regs.sp);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.gp), &core.regs.gp);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.tp), &core.regs.tp);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t0), &core.regs.t0);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t1), &core.regs.t1);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t2), &core.regs.t2);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s0), &core.regs.s0);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s1), &core.regs.s1);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a0), &core.regs.a0);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a1), &core.regs.a1);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a2), &core.regs.a2);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a3), &core.regs.a3);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a4), &core.regs.a4);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a5), &core.regs.a5);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a6), &core.regs.a6);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a7), &core.regs.a7);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s2), &core.regs.s2);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s3), &core.regs.s3);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s4), &core.regs.s4);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s5), &core.regs.s5);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s6), &core.regs.s6);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s7), &core.regs.s7);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s8), &core.regs.s8);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s9), &core.regs.s9);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s10), &core.regs.s10);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s11), &core.regs.s11);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t3), &core.regs.t3);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t4), &core.regs.t4);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t5), &core.regs.t5);
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t6), &core.regs.t6);
|
||||
core.mode = vcpu_get_reg(vcpu, RISCV_CORE_REG(mode));
|
||||
core.regs.pc = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.pc));
|
||||
core.regs.ra = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.ra));
|
||||
core.regs.sp = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.sp));
|
||||
core.regs.gp = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.gp));
|
||||
core.regs.tp = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.tp));
|
||||
core.regs.t0 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t0));
|
||||
core.regs.t1 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t1));
|
||||
core.regs.t2 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t2));
|
||||
core.regs.s0 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s0));
|
||||
core.regs.s1 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s1));
|
||||
core.regs.a0 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a0));
|
||||
core.regs.a1 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a1));
|
||||
core.regs.a2 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a2));
|
||||
core.regs.a3 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a3));
|
||||
core.regs.a4 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a4));
|
||||
core.regs.a5 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a5));
|
||||
core.regs.a6 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a6));
|
||||
core.regs.a7 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a7));
|
||||
core.regs.s2 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s2));
|
||||
core.regs.s3 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s3));
|
||||
core.regs.s4 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s4));
|
||||
core.regs.s5 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s5));
|
||||
core.regs.s6 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s6));
|
||||
core.regs.s7 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s7));
|
||||
core.regs.s8 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s8));
|
||||
core.regs.s9 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s9));
|
||||
core.regs.s10 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s10));
|
||||
core.regs.s11 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s11));
|
||||
core.regs.t3 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t3));
|
||||
core.regs.t4 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t4));
|
||||
core.regs.t5 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t5));
|
||||
core.regs.t6 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t6));
|
||||
|
||||
fprintf(stream,
|
||||
" MODE: 0x%lx\n", core.mode);
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* x86_64-specific extensions to memstress.c.
|
||||
* x86-specific extensions to memstress.c.
|
||||
*
|
||||
* Copyright (C) 2022, Google, Inc.
|
||||
*/
|
@ -1,7 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* tools/testing/selftests/kvm/lib/x86_64/processor.c
|
||||
*
|
||||
* Copyright (C) 2018, Google LLC.
|
||||
*/
|
||||
|
@ -1,6 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* tools/testing/selftests/kvm/lib/x86_64/svm.c
|
||||
* Helpers used for nested SVM testing
|
||||
* Largely inspired from KVM unit test svm.c
|
||||
*
|
@ -1,7 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* tools/testing/selftests/kvm/lib/x86_64/vmx.c
|
||||
*
|
||||
* Copyright (C) 2018, Google LLC.
|
||||
*/
|
||||
|
@ -15,16 +15,62 @@
|
||||
#include "test_util.h"
|
||||
#include "guest_modes.h"
|
||||
#include "processor.h"
|
||||
#include "ucall_common.h"
|
||||
|
||||
static bool mprotect_ro_done;
|
||||
|
||||
static void guest_code(uint64_t start_gpa, uint64_t end_gpa, uint64_t stride)
|
||||
{
|
||||
uint64_t gpa;
|
||||
int i;
|
||||
|
||||
for (;;) {
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (gpa = start_gpa; gpa < end_gpa; gpa += stride)
|
||||
*((volatile uint64_t *)gpa) = gpa;
|
||||
GUEST_SYNC(0);
|
||||
vcpu_arch_put_guest(*((volatile uint64_t *)gpa), gpa);
|
||||
GUEST_SYNC(i);
|
||||
}
|
||||
|
||||
for (gpa = start_gpa; gpa < end_gpa; gpa += stride)
|
||||
*((volatile uint64_t *)gpa);
|
||||
GUEST_SYNC(2);
|
||||
|
||||
/*
|
||||
* Write to the region while mprotect(PROT_READ) is underway. Keep
|
||||
* looping until the memory is guaranteed to be read-only, otherwise
|
||||
* vCPUs may complete their writes and advance to the next stage
|
||||
* prematurely.
|
||||
*
|
||||
* For architectures that support skipping the faulting instruction,
|
||||
* generate the store via inline assembly to ensure the exact length
|
||||
* of the instruction is known and stable (vcpu_arch_put_guest() on
|
||||
* fixed-length architectures should work, but the cost of paranoia
|
||||
* is low in this case). For x86, hand-code the exact opcode so that
|
||||
* there is no room for variability in the generated instruction.
|
||||
*/
|
||||
do {
|
||||
for (gpa = start_gpa; gpa < end_gpa; gpa += stride)
|
||||
#ifdef __x86_64__
|
||||
asm volatile(".byte 0x48,0x89,0x00" :: "a"(gpa) : "memory"); /* mov %rax, (%rax) */
|
||||
#elif defined(__aarch64__)
|
||||
asm volatile("str %0, [%0]" :: "r" (gpa) : "memory");
|
||||
#else
|
||||
vcpu_arch_put_guest(*((volatile uint64_t *)gpa), gpa);
|
||||
#endif
|
||||
} while (!READ_ONCE(mprotect_ro_done));
|
||||
|
||||
/*
|
||||
* Only architectures that write the entire range can explicitly sync,
|
||||
* as other architectures will be stuck on the write fault.
|
||||
*/
|
||||
#if defined(__x86_64__) || defined(__aarch64__)
|
||||
GUEST_SYNC(3);
|
||||
#endif
|
||||
|
||||
for (gpa = start_gpa; gpa < end_gpa; gpa += stride)
|
||||
vcpu_arch_put_guest(*((volatile uint64_t *)gpa), gpa);
|
||||
GUEST_SYNC(4);
|
||||
|
||||
GUEST_ASSERT(0);
|
||||
}
|
||||
|
||||
struct vcpu_info {
|
||||
@ -51,34 +97,100 @@ static void rendezvous_with_boss(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void run_vcpu(struct kvm_vcpu *vcpu)
|
||||
static void assert_sync_stage(struct kvm_vcpu *vcpu, int stage)
|
||||
{
|
||||
struct ucall uc;
|
||||
|
||||
TEST_ASSERT_EQ(get_ucall(vcpu, &uc), UCALL_SYNC);
|
||||
TEST_ASSERT_EQ(uc.args[1], stage);
|
||||
}
|
||||
|
||||
static void run_vcpu(struct kvm_vcpu *vcpu, int stage)
|
||||
{
|
||||
vcpu_run(vcpu);
|
||||
TEST_ASSERT_EQ(get_ucall(vcpu, NULL), UCALL_SYNC);
|
||||
assert_sync_stage(vcpu, stage);
|
||||
}
|
||||
|
||||
static void *vcpu_worker(void *data)
|
||||
{
|
||||
struct kvm_sregs __maybe_unused sregs;
|
||||
struct vcpu_info *info = data;
|
||||
struct kvm_vcpu *vcpu = info->vcpu;
|
||||
struct kvm_vm *vm = vcpu->vm;
|
||||
struct kvm_sregs sregs;
|
||||
int r;
|
||||
|
||||
vcpu_args_set(vcpu, 3, info->start_gpa, info->end_gpa, vm->page_size);
|
||||
|
||||
rendezvous_with_boss();
|
||||
|
||||
run_vcpu(vcpu);
|
||||
/* Stage 0, write all of guest memory. */
|
||||
run_vcpu(vcpu, 0);
|
||||
rendezvous_with_boss();
|
||||
vcpu_sregs_get(vcpu, &sregs);
|
||||
#ifdef __x86_64__
|
||||
vcpu_sregs_get(vcpu, &sregs);
|
||||
/* Toggle CR0.WP to trigger a MMU context reset. */
|
||||
sregs.cr0 ^= X86_CR0_WP;
|
||||
#endif
|
||||
vcpu_sregs_set(vcpu, &sregs);
|
||||
#endif
|
||||
rendezvous_with_boss();
|
||||
|
||||
run_vcpu(vcpu);
|
||||
/* Stage 1, re-write all of guest memory. */
|
||||
run_vcpu(vcpu, 1);
|
||||
rendezvous_with_boss();
|
||||
|
||||
/* Stage 2, read all of guest memory, which is now read-only. */
|
||||
run_vcpu(vcpu, 2);
|
||||
|
||||
/*
|
||||
* Stage 3, write guest memory and verify KVM returns -EFAULT for once
|
||||
* the mprotect(PROT_READ) lands. Only architectures that support
|
||||
* validating *all* of guest memory sync for this stage, as vCPUs will
|
||||
* be stuck on the faulting instruction for other architectures. Go to
|
||||
* stage 3 without a rendezvous
|
||||
*/
|
||||
do {
|
||||
r = _vcpu_run(vcpu);
|
||||
} while (!r);
|
||||
TEST_ASSERT(r == -1 && errno == EFAULT,
|
||||
"Expected EFAULT on write to RO memory, got r = %d, errno = %d", r, errno);
|
||||
|
||||
#if defined(__x86_64__) || defined(__aarch64__)
|
||||
/*
|
||||
* Verify *all* writes from the guest hit EFAULT due to the VMA now
|
||||
* being read-only. x86 and arm64 only at this time as skipping the
|
||||
* instruction that hits the EFAULT requires advancing the program
|
||||
* counter, which is arch specific and relies on inline assembly.
|
||||
*/
|
||||
#ifdef __x86_64__
|
||||
vcpu->run->kvm_valid_regs = KVM_SYNC_X86_REGS;
|
||||
#endif
|
||||
for (;;) {
|
||||
r = _vcpu_run(vcpu);
|
||||
if (!r)
|
||||
break;
|
||||
TEST_ASSERT_EQ(errno, EFAULT);
|
||||
#if defined(__x86_64__)
|
||||
WRITE_ONCE(vcpu->run->kvm_dirty_regs, KVM_SYNC_X86_REGS);
|
||||
vcpu->run->s.regs.regs.rip += 3;
|
||||
#elif defined(__aarch64__)
|
||||
vcpu_set_reg(vcpu, ARM64_CORE_REG(regs.pc),
|
||||
vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pc)) + 4);
|
||||
#endif
|
||||
|
||||
}
|
||||
assert_sync_stage(vcpu, 3);
|
||||
#endif /* __x86_64__ || __aarch64__ */
|
||||
rendezvous_with_boss();
|
||||
|
||||
/*
|
||||
* Stage 4. Run to completion, waiting for mprotect(PROT_WRITE) to
|
||||
* make the memory writable again.
|
||||
*/
|
||||
do {
|
||||
r = _vcpu_run(vcpu);
|
||||
} while (r && errno == EFAULT);
|
||||
TEST_ASSERT_EQ(r, 0);
|
||||
assert_sync_stage(vcpu, 4);
|
||||
rendezvous_with_boss();
|
||||
|
||||
return NULL;
|
||||
@ -161,7 +273,7 @@ int main(int argc, char *argv[])
|
||||
const uint64_t start_gpa = SZ_4G;
|
||||
const int first_slot = 1;
|
||||
|
||||
struct timespec time_start, time_run1, time_reset, time_run2;
|
||||
struct timespec time_start, time_run1, time_reset, time_run2, time_ro, time_rw;
|
||||
uint64_t max_gpa, gpa, slot_size, max_mem, i;
|
||||
int max_slots, slot, opt, fd;
|
||||
bool hugepages = false;
|
||||
@ -209,7 +321,13 @@ int main(int argc, char *argv[])
|
||||
vcpus = malloc(nr_vcpus * sizeof(*vcpus));
|
||||
TEST_ASSERT(vcpus, "Failed to allocate vCPU array");
|
||||
|
||||
vm = vm_create_with_vcpus(nr_vcpus, guest_code, vcpus);
|
||||
vm = __vm_create_with_vcpus(VM_SHAPE_DEFAULT, nr_vcpus,
|
||||
#ifdef __x86_64__
|
||||
max_mem / SZ_1G,
|
||||
#else
|
||||
max_mem / vm_guest_mode_params[VM_MODE_DEFAULT].page_size,
|
||||
#endif
|
||||
guest_code, vcpus);
|
||||
|
||||
max_gpa = vm->max_gfn << vm->page_shift;
|
||||
TEST_ASSERT(max_gpa > (4 * slot_size), "MAXPHYADDR <4gb ");
|
||||
@ -259,14 +377,28 @@ int main(int argc, char *argv[])
|
||||
rendezvous_with_vcpus(&time_reset, "reset");
|
||||
rendezvous_with_vcpus(&time_run2, "run 2");
|
||||
|
||||
mprotect(mem, slot_size, PROT_READ);
|
||||
usleep(10);
|
||||
mprotect_ro_done = true;
|
||||
sync_global_to_guest(vm, mprotect_ro_done);
|
||||
|
||||
rendezvous_with_vcpus(&time_ro, "mprotect RO");
|
||||
mprotect(mem, slot_size, PROT_READ | PROT_WRITE);
|
||||
rendezvous_with_vcpus(&time_rw, "mprotect RW");
|
||||
|
||||
time_rw = timespec_sub(time_rw, time_ro);
|
||||
time_ro = timespec_sub(time_ro, time_run2);
|
||||
time_run2 = timespec_sub(time_run2, time_reset);
|
||||
time_reset = timespec_sub(time_reset, time_run1);
|
||||
time_reset = timespec_sub(time_reset, time_run1);
|
||||
time_run1 = timespec_sub(time_run1, time_start);
|
||||
|
||||
pr_info("run1 = %ld.%.9lds, reset = %ld.%.9lds, run2 = %ld.%.9lds\n",
|
||||
pr_info("run1 = %ld.%.9lds, reset = %ld.%.9lds, run2 = %ld.%.9lds, "
|
||||
"ro = %ld.%.9lds, rw = %ld.%.9lds\n",
|
||||
time_run1.tv_sec, time_run1.tv_nsec,
|
||||
time_reset.tv_sec, time_reset.tv_nsec,
|
||||
time_run2.tv_sec, time_run2.tv_nsec);
|
||||
time_run2.tv_sec, time_run2.tv_nsec,
|
||||
time_ro.tv_sec, time_ro.tv_nsec,
|
||||
time_rw.tv_sec, time_rw.tv_nsec);
|
||||
|
||||
/*
|
||||
* Delete even numbered slots (arbitrary) and unmap the first half of
|
@ -93,7 +93,7 @@ struct kvm_vm *test_vm_create(void)
|
||||
vcpu_init_vector_tables(vcpus[i]);
|
||||
|
||||
/* Initialize guest timer frequency. */
|
||||
vcpu_get_reg(vcpus[0], RISCV_TIMER_REG(frequency), &timer_freq);
|
||||
timer_freq = vcpu_get_reg(vcpus[0], RISCV_TIMER_REG(frequency));
|
||||
sync_global_to_guest(vm, timer_freq);
|
||||
pr_debug("timer_freq: %lu\n", timer_freq);
|
||||
|
||||
|
@ -60,7 +60,7 @@ int main(void)
|
||||
|
||||
TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_DEBUG);
|
||||
|
||||
vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.pc), &pc);
|
||||
pc = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.pc));
|
||||
TEST_ASSERT_EQ(pc, LABEL_ADDRESS(sw_bp_1));
|
||||
|
||||
/* skip sw_bp_1 */
|
||||
|
@ -608,7 +608,7 @@ static void test_vm_events_overflow(void *guest_code)
|
||||
|
||||
vcpu_init_vector_tables(vcpu);
|
||||
/* Initialize guest timer frequency. */
|
||||
vcpu_get_reg(vcpu, RISCV_TIMER_REG(frequency), &timer_freq);
|
||||
timer_freq = vcpu_get_reg(vcpu, RISCV_TIMER_REG(frequency));
|
||||
sync_global_to_guest(vm, timer_freq);
|
||||
|
||||
run_vcpu(vcpu);
|
||||
|
@ -61,7 +61,7 @@ static void test_one_reg(struct kvm_vcpu *vcpu, uint64_t id, uint64_t value)
|
||||
{
|
||||
uint64_t eval_reg;
|
||||
|
||||
vcpu_get_reg(vcpu, id, &eval_reg);
|
||||
eval_reg = vcpu_get_reg(vcpu, id);
|
||||
TEST_ASSERT(eval_reg == value, "value == 0x%lx", value);
|
||||
}
|
||||
|
@ -17,9 +17,9 @@
|
||||
#include <processor.h>
|
||||
|
||||
/*
|
||||
* s390x needs at least 1MB alignment, and the x86_64 MOVE/DELETE tests need a
|
||||
* 2MB sized and aligned region so that the initial region corresponds to
|
||||
* exactly one large page.
|
||||
* s390 needs at least 1MB alignment, and the x86 MOVE/DELETE tests need a 2MB
|
||||
* sized and aligned region so that the initial region corresponds to exactly
|
||||
* one large page.
|
||||
*/
|
||||
#define MEM_REGION_SIZE 0x200000
|
||||
|
||||
|
@ -269,9 +269,8 @@ static void guest_code(int cpu)
|
||||
static bool is_steal_time_supported(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
uint64_t id = RISCV_SBI_EXT_REG(KVM_RISCV_SBI_EXT_STA);
|
||||
unsigned long enabled;
|
||||
unsigned long enabled = vcpu_get_reg(vcpu, id);
|
||||
|
||||
vcpu_get_reg(vcpu, id, &enabled);
|
||||
TEST_ASSERT(enabled == 0 || enabled == 1, "Expected boolean result");
|
||||
|
||||
return enabled;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user