KVM: selftests: riscv: Improve unexpected guest trap handling
Currently, we simply hang using "while (1) ;" upon any unexpected guest traps because the default guest trap handler is guest_hang(). The above approach is not useful to anyone because KVM selftests users will only see a hung application upon any unexpected guest trap. This patch improves unexpected guest trap handling for KVM RISC-V selftests by doing the following: 1) Return to host user-space 2) Dump VCPU registers 3) Die using TEST_ASSERT(0, ...) Signed-off-by: Anup Patel <apatel@ventanamicro.com> Tested-by: Mayuresh Chitale <mchitale@ventanamicro.com> Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
parent
42226c9897
commit
ac6c85e962
@ -119,10 +119,12 @@ static inline void set_reg(struct kvm_vm *vm, uint32_t vcpuid, uint64_t id,
|
||||
#define SATP_ASID_SHIFT 44
|
||||
#define SATP_ASID_MASK _AC(0xFFFF, UL)
|
||||
|
||||
#define SBI_EXT_EXPERIMENTAL_START 0x08000000
|
||||
#define SBI_EXT_EXPERIMENTAL_END 0x08FFFFFF
|
||||
#define SBI_EXT_EXPERIMENTAL_START 0x08000000
|
||||
#define SBI_EXT_EXPERIMENTAL_END 0x08FFFFFF
|
||||
|
||||
#define KVM_RISCV_SELFTESTS_SBI_EXT SBI_EXT_EXPERIMENTAL_END
|
||||
#define KVM_RISCV_SELFTESTS_SBI_EXT SBI_EXT_EXPERIMENTAL_END
|
||||
#define KVM_RISCV_SELFTESTS_SBI_UCALL 0
|
||||
#define KVM_RISCV_SELFTESTS_SBI_UNEXP 1
|
||||
|
||||
struct sbiret {
|
||||
long error;
|
||||
|
@ -268,10 +268,11 @@ void vcpu_dump(FILE *stream, struct kvm_vm *vm, uint32_t vcpuid, uint8_t indent)
|
||||
core.regs.t3, core.regs.t4, core.regs.t5, core.regs.t6);
|
||||
}
|
||||
|
||||
static void __aligned(16) guest_hang(void)
|
||||
static void __aligned(16) guest_unexp_trap(void)
|
||||
{
|
||||
while (1)
|
||||
;
|
||||
sbi_ecall(KVM_RISCV_SELFTESTS_SBI_EXT,
|
||||
KVM_RISCV_SELFTESTS_SBI_UNEXP,
|
||||
0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void vm_vcpu_add_default(struct kvm_vm *vm, uint32_t vcpuid, void *guest_code)
|
||||
@ -310,7 +311,7 @@ void vm_vcpu_add_default(struct kvm_vm *vm, uint32_t vcpuid, void *guest_code)
|
||||
|
||||
/* Setup default exception vector of guest */
|
||||
set_reg(vm, vcpuid, RISCV_CSR_REG(stvec),
|
||||
(unsigned long)guest_hang);
|
||||
(unsigned long)guest_unexp_trap);
|
||||
}
|
||||
|
||||
void vcpu_args_set(struct kvm_vm *vm, uint32_t vcpuid, unsigned int num, ...)
|
||||
|
@ -60,8 +60,9 @@ void ucall(uint64_t cmd, int nargs, ...)
|
||||
uc.args[i] = va_arg(va, uint64_t);
|
||||
va_end(va);
|
||||
|
||||
sbi_ecall(KVM_RISCV_SELFTESTS_SBI_EXT, 0, (vm_vaddr_t)&uc,
|
||||
0, 0, 0, 0, 0);
|
||||
sbi_ecall(KVM_RISCV_SELFTESTS_SBI_EXT,
|
||||
KVM_RISCV_SELFTESTS_SBI_UCALL,
|
||||
(vm_vaddr_t)&uc, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
uint64_t get_ucall(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc)
|
||||
@ -73,14 +74,24 @@ uint64_t get_ucall(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc)
|
||||
memset(uc, 0, sizeof(*uc));
|
||||
|
||||
if (run->exit_reason == KVM_EXIT_RISCV_SBI &&
|
||||
run->riscv_sbi.extension_id == KVM_RISCV_SELFTESTS_SBI_EXT &&
|
||||
run->riscv_sbi.function_id == 0) {
|
||||
memcpy(&ucall, addr_gva2hva(vm, run->riscv_sbi.args[0]),
|
||||
sizeof(ucall));
|
||||
run->riscv_sbi.extension_id == KVM_RISCV_SELFTESTS_SBI_EXT) {
|
||||
switch (run->riscv_sbi.function_id) {
|
||||
case KVM_RISCV_SELFTESTS_SBI_UCALL:
|
||||
memcpy(&ucall, addr_gva2hva(vm,
|
||||
run->riscv_sbi.args[0]), sizeof(ucall));
|
||||
|
||||
vcpu_run_complete_io(vm, vcpu_id);
|
||||
if (uc)
|
||||
memcpy(uc, &ucall, sizeof(ucall));
|
||||
vcpu_run_complete_io(vm, vcpu_id);
|
||||
if (uc)
|
||||
memcpy(uc, &ucall, sizeof(ucall));
|
||||
|
||||
break;
|
||||
case KVM_RISCV_SELFTESTS_SBI_UNEXP:
|
||||
vcpu_dump(stderr, vm, vcpu_id, 2);
|
||||
TEST_ASSERT(0, "Unexpected trap taken by guest");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ucall.cmd;
|
||||
|
Loading…
x
Reference in New Issue
Block a user