KVM: selftests: Add exception handling support for aarch64
Add the infrastructure needed to enable exception handling in aarch64 selftests. The exception handling defaults to an unhandled-exception handler which aborts the test, just like x86. These handlers can be overridden by calling vm_install_exception_handler(vector) or vm_install_sync_handler(vector, ec). The unhandled exception reporting from the guest is done using the ucall type introduced in a previous commit, UCALL_UNHANDLED. The exception handling code is inspired on kvm-unit-tests. Signed-off-by: Ricardo Koller <ricarkol@google.com> Reviewed-by: Andrew Jones <drjones@redhat.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20210611011020.3420067-6-ricarkol@google.com
This commit is contained in:
committed by
Marc Zyngier
parent
67f709f52b
commit
e3db7579ef
@@ -8,6 +8,7 @@
|
||||
#define SELFTEST_KVM_PROCESSOR_H
|
||||
|
||||
#include "kvm_util.h"
|
||||
#include <linux/stringify.h>
|
||||
|
||||
|
||||
#define ARM64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
|
||||
@@ -18,6 +19,7 @@
|
||||
#define MAIR_EL1 3, 0, 10, 2, 0
|
||||
#define TTBR0_EL1 3, 0, 2, 0, 0
|
||||
#define SCTLR_EL1 3, 0, 1, 0, 0
|
||||
#define VBAR_EL1 3, 0, 12, 0, 0
|
||||
|
||||
/*
|
||||
* Default MAIR
|
||||
@@ -56,4 +58,65 @@ void aarch64_vcpu_setup(struct kvm_vm *vm, int vcpuid, struct kvm_vcpu_init *ini
|
||||
void aarch64_vcpu_add_default(struct kvm_vm *vm, uint32_t vcpuid,
|
||||
struct kvm_vcpu_init *init, void *guest_code);
|
||||
|
||||
struct ex_regs {
|
||||
u64 regs[31];
|
||||
u64 sp;
|
||||
u64 pc;
|
||||
u64 pstate;
|
||||
};
|
||||
|
||||
#define VECTOR_NUM 16
|
||||
|
||||
enum {
|
||||
VECTOR_SYNC_CURRENT_SP0,
|
||||
VECTOR_IRQ_CURRENT_SP0,
|
||||
VECTOR_FIQ_CURRENT_SP0,
|
||||
VECTOR_ERROR_CURRENT_SP0,
|
||||
|
||||
VECTOR_SYNC_CURRENT,
|
||||
VECTOR_IRQ_CURRENT,
|
||||
VECTOR_FIQ_CURRENT,
|
||||
VECTOR_ERROR_CURRENT,
|
||||
|
||||
VECTOR_SYNC_LOWER_64,
|
||||
VECTOR_IRQ_LOWER_64,
|
||||
VECTOR_FIQ_LOWER_64,
|
||||
VECTOR_ERROR_LOWER_64,
|
||||
|
||||
VECTOR_SYNC_LOWER_32,
|
||||
VECTOR_IRQ_LOWER_32,
|
||||
VECTOR_FIQ_LOWER_32,
|
||||
VECTOR_ERROR_LOWER_32,
|
||||
};
|
||||
|
||||
#define VECTOR_IS_SYNC(v) ((v) == VECTOR_SYNC_CURRENT_SP0 || \
|
||||
(v) == VECTOR_SYNC_CURRENT || \
|
||||
(v) == VECTOR_SYNC_LOWER_64 || \
|
||||
(v) == VECTOR_SYNC_LOWER_32)
|
||||
|
||||
#define ESR_EC_NUM 64
|
||||
#define ESR_EC_SHIFT 26
|
||||
#define ESR_EC_MASK (ESR_EC_NUM - 1)
|
||||
|
||||
void vm_init_descriptor_tables(struct kvm_vm *vm);
|
||||
void vcpu_init_descriptor_tables(struct kvm_vm *vm, uint32_t vcpuid);
|
||||
|
||||
typedef void(*handler_fn)(struct ex_regs *);
|
||||
void vm_install_exception_handler(struct kvm_vm *vm,
|
||||
int vector, handler_fn handler);
|
||||
void vm_install_sync_handler(struct kvm_vm *vm,
|
||||
int vector, int ec, handler_fn handler);
|
||||
|
||||
#define write_sysreg(reg, val) \
|
||||
({ \
|
||||
u64 __val = (u64)(val); \
|
||||
asm volatile("msr " __stringify(reg) ", %x0" : : "rZ" (__val)); \
|
||||
})
|
||||
|
||||
#define read_sysreg(reg) \
|
||||
({ u64 val; \
|
||||
asm volatile("mrs %0, "__stringify(reg) : "=r"(val) : : "memory");\
|
||||
val; \
|
||||
})
|
||||
|
||||
#endif /* SELFTEST_KVM_PROCESSOR_H */
|
||||
|
||||
Reference in New Issue
Block a user