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:
Ricardo Koller
2021-06-10 18:10:19 -07:00
committed by Marc Zyngier
parent 67f709f52b
commit e3db7579ef
4 changed files with 287 additions and 1 deletions

View File

@@ -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 */