summaryrefslogtreecommitdiff
path: root/arch/arm64/kvm/inject_fault.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2022-04-29 12:32:14 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2022-04-29 12:32:14 -0400
commit484c22df5aa0548604e67f7cdc73e1bd736cbecc (patch)
treee332c5fa330cc114d703de9c157a0954da5d0aff /arch/arm64/kvm/inject_fault.c
parente852be8b148e117e25be1c98cf72ee489b05919e (diff)
parent85ea6b1ec915c9dd90caf3674b203999d8c7e062 (diff)
downloadlinux-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.c28
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