11 #include <linux/kvm.h>
12 #include <linux/kvm_host.h>
15 #include <asm/exception.h>
16 #include <asm/kvm_asm.h>
17 #include <asm/kvm_emulate.h>
18 #include <asm/kvm_mmu.h>
19 #include <asm/kvm_nested.h>
20 #include <asm/debug-monitors.h>
21 #include <asm/stacktrace/nvhe.h>
22 #include <asm/traps.h>
26 #define CREATE_TRACE_POINTS
33 if (!arm64_is_ras_serror(esr) || arm64_is_fatal_ras_serror(NULL, esr))
39 trace_kvm_hvc_arm64(*vcpu_pc(vcpu), vcpu_get_reg(vcpu, 0),
40 kvm_vcpu_hvc_get_imm(vcpu));
41 vcpu->stat.hvc_exit_stat++;
44 if (vcpu_has_nv(vcpu)) {
74 if (kvm_vcpu_hvc_get_imm(vcpu)) {
75 vcpu_set_reg(vcpu, 0, ~0UL);
116 u64 esr = kvm_vcpu_get_esr(vcpu);
118 if (esr & ESR_ELx_WFx_ISS_WFE) {
119 trace_kvm_wfx_arm64(*vcpu_pc(vcpu),
true);
120 vcpu->stat.wfe_exit_stat++;
122 trace_kvm_wfx_arm64(*vcpu_pc(vcpu),
false);
123 vcpu->stat.wfi_exit_stat++;
126 if (esr & ESR_ELx_WFx_ISS_WFxT) {
127 if (esr & ESR_ELx_WFx_ISS_RV) {
131 val = vcpu_get_reg(vcpu, kvm_vcpu_sys_get_rt(vcpu));
137 esr &= ~ESR_ELx_WFx_ISS_WFxT;
141 if (esr & ESR_ELx_WFx_ISS_WFE) {
144 if (esr & ESR_ELx_WFx_ISS_WFxT)
145 vcpu_set_flag(vcpu, IN_WFIT);
168 struct kvm_run *run = vcpu->run;
169 u64 esr = kvm_vcpu_get_esr(vcpu);
171 run->exit_reason = KVM_EXIT_DEBUG;
172 run->debug.arch.hsr = lower_32_bits(esr);
173 run->debug.arch.hsr_high = upper_32_bits(esr);
174 run->flags = KVM_DEBUG_ARCH_HSR_HIGH_VALID;
176 switch (ESR_ELx_EC(esr)) {
177 case ESR_ELx_EC_WATCHPT_LOW:
178 run->debug.arch.far = vcpu->arch.fault.far_el2;
180 case ESR_ELx_EC_SOFTSTP_LOW:
181 vcpu_clear_flag(vcpu, DBG_SS_ACTIVE_PENDING);
190 u64 esr = kvm_vcpu_get_esr(vcpu);
192 kvm_pr_unimpl(
"Unknown exception class: esr: %#016llx -- %s\n",
193 esr, esr_get_class_string(esr));
222 if (kvm_vcpu_get_esr(vcpu) & ESR_ELx_ERET_ISS_ERET)
236 if (is_hyp_ctxt(vcpu))
285 u64 esr = kvm_vcpu_get_esr(vcpu);
286 u8 esr_ec = ESR_ELx_EC(esr);
305 if (!kvm_condition_valid(vcpu)) {
312 handled = exit_handler(vcpu);
324 struct kvm_run *run = vcpu->run;
326 if (ARM_SERROR_PENDING(exception_index)) {
334 exception_index = ARM_EXCEPTION_CODE(exception_index);
336 switch (exception_index) {
337 case ARM_EXCEPTION_IRQ:
339 case ARM_EXCEPTION_EL1_SERROR:
341 case ARM_EXCEPTION_TRAP:
343 case ARM_EXCEPTION_HYP_GONE:
348 run->exit_reason = KVM_EXIT_FAIL_ENTRY;
350 case ARM_EXCEPTION_IL:
355 run->exit_reason = KVM_EXIT_FAIL_ENTRY;
360 run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
368 if (ARM_SERROR_PENDING(exception_index)) {
369 if (this_cpu_has_cap(ARM64_HAS_RAS_EXTN)) {
370 u64 disr = kvm_vcpu_get_disr(vcpu);
380 exception_index = ARM_EXCEPTION_CODE(exception_index);
382 if (exception_index == ARM_EXCEPTION_EL1_SERROR)
387 u64 elr_virt, u64 elr_phys,
388 u64 par, uintptr_t vcpu,
389 u64 far, u64 hpfar) {
390 u64 elr_in_kimg = __phys_to_kimg(elr_phys);
391 u64 hyp_offset = elr_in_kimg - kaslr_offset() - elr_virt;
392 u64 mode = spsr & PSR_MODE_MASK;
393 u64 panic_addr = elr_virt + hyp_offset;
395 if (mode != PSR_MODE_EL2t && mode != PSR_MODE_EL2h) {
396 kvm_err(
"Invalid host exception to nVHE hyp!\n");
397 }
else if (ESR_ELx_EC(esr) == ESR_ELx_EC_BRK64 &&
398 (esr & ESR_ELx_BRK64_ISS_COMMENT_MASK) == BUG_BRK_IMM) {
399 const char *file = NULL;
400 unsigned int line = 0;
403 if (!is_protected_kvm_enabled() ||
404 IS_ENABLED(CONFIG_NVHE_EL2_DEBUG)) {
405 struct bug_entry *bug = find_bug(elr_in_kimg);
408 bug_get_file_line(bug, &file, &line);
412 kvm_err(
"nVHE hyp BUG at: %s:%u!\n", file, line);
414 kvm_err(
"nVHE hyp BUG at: [<%016llx>] %pB!\n", panic_addr,
415 (
void *)(panic_addr + kaslr_offset()));
417 kvm_err(
"nVHE hyp panic at: [<%016llx>] %pB!\n", panic_addr,
418 (
void *)(panic_addr + kaslr_offset()));
430 kvm_err(
"Hyp Offset: 0x%llx\n", hyp_offset);
432 panic(
"HYP panic:\nPS:%08llx PC:%016llx ESR:%016llx\nFAR:%016llx HPFAR:%016llx PAR:%016llx\nVCPU:%016lx\n",
433 spsr, elr_virt, esr, far, hpfar, par, vcpu);
u64 kvm_arm_timer_get_reg(struct kvm_vcpu *vcpu, u64 regid)
void kvm_vcpu_wfi(struct kvm_vcpu *vcpu)
void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu)
int kvm_inject_nested_sync(struct kvm_vcpu *vcpu, u64 esr_el2)
static int kvm_handle_ptrauth(struct kvm_vcpu *vcpu)
static int kvm_handle_wfx(struct kvm_vcpu *vcpu)
static int kvm_handle_unknown_ec(struct kvm_vcpu *vcpu)
int(* exit_handle_fn)(struct kvm_vcpu *)
static int handle_sve(struct kvm_vcpu *vcpu)
static int handle_hvc(struct kvm_vcpu *vcpu)
static exit_handle_fn kvm_get_exit_handler(struct kvm_vcpu *vcpu)
void __noreturn __cold nvhe_hyp_panic_handler(u64 esr, u64 spsr, u64 elr_virt, u64 elr_phys, u64 par, uintptr_t vcpu, u64 far, u64 hpfar)
static int handle_no_fpsimd(struct kvm_vcpu *vcpu)
static void kvm_handle_guest_serror(struct kvm_vcpu *vcpu, u64 esr)
static exit_handle_fn arm_exit_handlers[]
static int handle_smc(struct kvm_vcpu *vcpu)
static int kvm_handle_eret(struct kvm_vcpu *vcpu)
static int handle_svc(struct kvm_vcpu *vcpu)
void handle_exit_early(struct kvm_vcpu *vcpu, int exception_index)
static int handle_trap_exceptions(struct kvm_vcpu *vcpu)
static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu)
int handle_exit(struct kvm_vcpu *vcpu, int exception_index)
int kvm_smccc_call_handler(struct kvm_vcpu *vcpu)
void kvm_inject_vabt(struct kvm_vcpu *vcpu)
void kvm_inject_undefined(struct kvm_vcpu *vcpu)
void kvm_vcpu_on_spin(struct kvm_vcpu *me, bool yield_to_kernel_mode)
int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
void kvm_nvhe_dump_backtrace(unsigned long hyp_offset)
int kvm_handle_cp10_id(struct kvm_vcpu *vcpu)
int kvm_handle_sys_reg(struct kvm_vcpu *vcpu)
int kvm_handle_cp14_32(struct kvm_vcpu *vcpu)
int kvm_handle_cp14_64(struct kvm_vcpu *vcpu)
int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu)
u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
int kvm_handle_cp15_32(struct kvm_vcpu *vcpu)
int kvm_handle_cp15_64(struct kvm_vcpu *vcpu)
kvm_pr_unimpl("%pV { Op0(%2u), Op1(%2u), CRn(%2u), CRm(%2u), Op2(%2u), func_%s },\n", &(struct va_format){ fmt, &va }, p->Op0, p->Op1, p->CRn, p->CRm, p->Op2, p->is_write ? "write" :"read")