13 #include <linux/kvm_host.h>
14 #include <asm/kvm_emulate.h>
15 #include <asm/kvm_nested.h>
21 if (likely(!vcpu_has_nv(vcpu))) {
22 kvm_pend_exception(vcpu, EXCEPT_AA64_EL1_SYNC);
32 switch(*vcpu_cpsr(vcpu) & PSR_MODE_MASK) {
35 kvm_pend_exception(vcpu, EXCEPT_AA64_EL2_SYNC);
39 kvm_pend_exception(vcpu, EXCEPT_AA64_EL1_SYNC);
42 if (vcpu_el2_tge_is_set(vcpu))
43 kvm_pend_exception(vcpu, EXCEPT_AA64_EL2_SYNC);
45 kvm_pend_exception(vcpu, EXCEPT_AA64_EL1_SYNC);
54 return (vcpu_get_flag(vcpu, EXCEPT_MASK) == target);
57 static void inject_abt64(
struct kvm_vcpu *vcpu,
bool is_iabt,
unsigned long addr)
59 unsigned long cpsr = *vcpu_cpsr(vcpu);
60 bool is_aarch32 = vcpu_mode_is_32bit(vcpu);
69 if (kvm_vcpu_trap_il_is32bit(vcpu))
76 if (is_aarch32 || (cpsr & PSR_MODE_MASK) == PSR_MODE_EL0t)
77 esr |= (ESR_ELx_EC_IABT_LOW << ESR_ELx_EC_SHIFT);
79 esr |= (ESR_ELx_EC_IABT_CUR << ESR_ELx_EC_SHIFT);
82 esr |= ESR_ELx_EC_DABT_LOW << ESR_ELx_EC_SHIFT;
84 esr |= ESR_ELx_FSC_EXTABT;
97 u64 esr = (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT);
105 if (kvm_vcpu_trap_il_is32bit(vcpu))
114 #define DFSR_FSC_EXTABT_LPAE 0x10
115 #define DFSR_FSC_EXTABT_nLPAE 0x08
116 #define DFSR_LPAE BIT(9)
117 #define TTBCR_EAE BIT(31)
121 kvm_pend_exception(vcpu, EXCEPT_AA32_UND);
128 static void inject_abt32(
struct kvm_vcpu *vcpu,
bool is_pabt, u32 addr)
144 kvm_pend_exception(vcpu, EXCEPT_AA32_IABT);
145 far &= GENMASK(31, 0);
146 far |= (u64)addr << 32;
149 kvm_pend_exception(vcpu, EXCEPT_AA32_DABT);
150 far &= GENMASK(63, 32);
168 if (vcpu_el1_is_32bit(vcpu))
184 if (vcpu_el1_is_32bit(vcpu))
192 unsigned long addr, esr;
194 addr = kvm_vcpu_get_fault_ipa(vcpu);
195 addr |= kvm_vcpu_get_hfar(vcpu) & GENMASK(11, 0);
197 if (kvm_vcpu_trap_is_iabt(vcpu))
209 if (vcpu_el1_is_32bit(vcpu) &&
214 esr &= ~GENMASK_ULL(5, 0);
227 if (vcpu_el1_is_32bit(vcpu))
235 vcpu_set_vsesr(vcpu, esr & ESR_ELx_ISS_MASK);
236 *vcpu_hcr(vcpu) |= HCR_VSE;
void kvm_inject_vabt(struct kvm_vcpu *vcpu)
static void inject_abt32(struct kvm_vcpu *vcpu, bool is_pabt, u32 addr)
static bool match_target_el(struct kvm_vcpu *vcpu, unsigned long target)
static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr)
void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr)
static void inject_undef64(struct kvm_vcpu *vcpu)
static void pend_sync_exception(struct kvm_vcpu *vcpu)
#define DFSR_FSC_EXTABT_LPAE
void kvm_set_sei_esr(struct kvm_vcpu *vcpu, u64 esr)
#define DFSR_FSC_EXTABT_nLPAE
static void inject_undef32(struct kvm_vcpu *vcpu)
void kvm_inject_undefined(struct kvm_vcpu *vcpu)
void kvm_inject_size_fault(struct kvm_vcpu *vcpu)
void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr)
u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)