diff options
| author | Paolo Bonzini <pbonzini@redhat.com> | 2022-04-29 12:32:14 -0400 |
|---|---|---|
| committer | Paolo Bonzini <pbonzini@redhat.com> | 2022-04-29 12:32:14 -0400 |
| commit | 484c22df5aa0548604e67f7cdc73e1bd736cbecc (patch) | |
| tree | e332c5fa330cc114d703de9c157a0954da5d0aff /arch/arm64/kvm/inject_fault.c | |
| parent | e852be8b148e117e25be1c98cf72ee489b05919e (diff) | |
| parent | 85ea6b1ec915c9dd90caf3674b203999d8c7e062 (diff) | |
| download | linux-484c22df5aa0548604e67f7cdc73e1bd736cbecc.tar.gz linux-484c22df5aa0548604e67f7cdc73e1bd736cbecc.tar.bz2 linux-484c22df5aa0548604e67f7cdc73e1bd736cbecc.zip | |
Merge tag 'kvmarm-fixes-5.18-2' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD
KVM/arm64 fixes for 5.18, take #2
- Take care of faults occuring between the PARange and
IPA range by injecting an exception
- Fix S2 faults taken from a host EL0 in protected mode
- Work around Oops caused by a PMU access from a 32bit
guest when PMU has been created. This is a temporary
bodge until we fix it for good.
Diffstat (limited to 'arch/arm64/kvm/inject_fault.c')
| -rw-r--r-- | arch/arm64/kvm/inject_fault.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c index b47df73e98d7..ba20405d2dc2 100644 --- a/arch/arm64/kvm/inject_fault.c +++ b/arch/arm64/kvm/inject_fault.c @@ -145,6 +145,34 @@ void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr) inject_abt64(vcpu, true, addr); } +void kvm_inject_size_fault(struct kvm_vcpu *vcpu) +{ + unsigned long addr, esr; + + addr = kvm_vcpu_get_fault_ipa(vcpu); + addr |= kvm_vcpu_get_hfar(vcpu) & GENMASK(11, 0); + + if (kvm_vcpu_trap_is_iabt(vcpu)) + kvm_inject_pabt(vcpu, addr); + else + kvm_inject_dabt(vcpu, addr); + + /* + * If AArch64 or LPAE, set FSC to 0 to indicate an Address + * Size Fault at level 0, as if exceeding PARange. + * + * Non-LPAE guests will only get the external abort, as there + * is no way to to describe the ASF. + */ + if (vcpu_el1_is_32bit(vcpu) && + !(vcpu_read_sys_reg(vcpu, TCR_EL1) & TTBCR_EAE)) + return; + + esr = vcpu_read_sys_reg(vcpu, ESR_EL1); + esr &= ~GENMASK_ULL(5, 0); + vcpu_write_sys_reg(vcpu, esr, ESR_EL1); +} + /** * kvm_inject_undefined - inject an undefined instruction into the guest * @vcpu: The vCPU in which to inject the exception |
