@@ -33,6 +33,9 @@
extern struct exception_table_entry __start___kvm_ex_table;
extern struct exception_table_entry __stop___kvm_ex_table;
+int kvm_handle_pvm_sys64(struct kvm_vcpu *vcpu);
+int kvm_handle_pvm_restricted(struct kvm_vcpu *vcpu);
+
/* Check whether the FP regs were dirtied while in the host-side run loop: */
static inline bool update_fp_enabled(struct kvm_vcpu *vcpu)
{
@@ -159,27 +159,27 @@ static void __pmu_switch_to_host(struct kvm_cpu_context *host_ctxt)
}
static exit_handle_fn hyp_exit_handlers[] = {
- [0 ... ESR_ELx_EC_MAX] = NULL,
+ [0 ... ESR_ELx_EC_MAX] = kvm_handle_pvm_restricted,
[ESR_ELx_EC_WFx] = NULL,
- [ESR_ELx_EC_CP15_32] = NULL,
- [ESR_ELx_EC_CP15_64] = NULL,
- [ESR_ELx_EC_CP14_MR] = NULL,
- [ESR_ELx_EC_CP14_LS] = NULL,
- [ESR_ELx_EC_CP14_64] = NULL,
+ [ESR_ELx_EC_CP15_32] = kvm_handle_pvm_restricted,
+ [ESR_ELx_EC_CP15_64] = kvm_handle_pvm_restricted,
+ [ESR_ELx_EC_CP14_MR] = kvm_handle_pvm_restricted,
+ [ESR_ELx_EC_CP14_LS] = kvm_handle_pvm_restricted,
+ [ESR_ELx_EC_CP14_64] = kvm_handle_pvm_restricted,
[ESR_ELx_EC_HVC32] = NULL,
[ESR_ELx_EC_SMC32] = NULL,
[ESR_ELx_EC_HVC64] = NULL,
[ESR_ELx_EC_SMC64] = NULL,
- [ESR_ELx_EC_SYS64] = NULL,
- [ESR_ELx_EC_SVE] = NULL,
+ [ESR_ELx_EC_SYS64] = kvm_handle_pvm_sys64,
+ [ESR_ELx_EC_SVE] = kvm_handle_pvm_restricted,
[ESR_ELx_EC_IABT_LOW] = NULL,
[ESR_ELx_EC_DABT_LOW] = NULL,
- [ESR_ELx_EC_SOFTSTP_LOW] = NULL,
- [ESR_ELx_EC_WATCHPT_LOW] = NULL,
- [ESR_ELx_EC_BREAKPT_LOW] = NULL,
- [ESR_ELx_EC_BKPT32] = NULL,
- [ESR_ELx_EC_BRK64] = NULL,
- [ESR_ELx_EC_FP_ASIMD] = NULL,
+ [ESR_ELx_EC_SOFTSTP_LOW] = kvm_handle_pvm_restricted,
+ [ESR_ELx_EC_WATCHPT_LOW] = kvm_handle_pvm_restricted,
+ [ESR_ELx_EC_BREAKPT_LOW] = kvm_handle_pvm_restricted,
+ [ESR_ELx_EC_BKPT32] = kvm_handle_pvm_restricted,
+ [ESR_ELx_EC_BRK64] = kvm_handle_pvm_restricted,
+ [ESR_ELx_EC_FP_ASIMD] = kvm_handle_pvm_restricted,
[ESR_ELx_EC_PAC] = NULL,
};
@@ -188,7 +188,11 @@ exit_handle_fn kvm_get_nvhe_exit_handler(struct kvm_vcpu *vcpu)
u32 esr = kvm_vcpu_get_esr(vcpu);
u8 esr_ec = ESR_ELx_EC(esr);
- return hyp_exit_handlers[esr_ec];
+ /* For now, only protected VMs have exit handlers. */
+ if (unlikely(kvm_vm_is_protected(kern_hyp_va(vcpu->kvm))))
+ return hyp_exit_handlers[esr_ec];
+ else
+ return NULL;
}
/* Switch to the guest for legacy non-VHE systems */