aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQuentin Perret <[email protected]>2024-04-23 16:05:14 +0100
committerMarc Zyngier <[email protected]>2024-05-01 16:46:58 +0100
commit02949f36bc7b723944bf754b71cfdf75e5e36f44 (patch)
treed22ca24b0b8a199f4bd1d10767fc6010199a432c
parentcb16301626c339b3ccde93e5deea0569e508cb98 (diff)
KVM: arm64: Avoid BUG-ing from the host abort path
Under certain circumstances __get_fault_info() may resolve the faulting address using the AT instruction. Given that this is being done outside of the host lock critical section, it is racy and the resolution via AT may fail. We currently BUG() in this situation, which is obviously less than ideal. Moving the address resolution to the critical section may have a performance impact, so let's keep it where it is, but bail out and return to the host to try a second time. Signed-off-by: Quentin Perret <[email protected]> Signed-off-by: Fuad Tabba <[email protected]> Acked-by: Oliver Upton <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Marc Zyngier <[email protected]>
-rw-r--r--arch/arm64/kvm/hyp/nvhe/mem_protect.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index 861c76021a25..caba3e4bd09e 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -533,7 +533,13 @@ void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt)
int ret = 0;
esr = read_sysreg_el2(SYS_ESR);
- BUG_ON(!__get_fault_info(esr, &fault));
+ if (!__get_fault_info(esr, &fault)) {
+ /*
+ * We've presumably raced with a page-table change which caused
+ * AT to fail, try again.
+ */
+ return;
+ }
addr = (fault.hpfar_el2 & HPFAR_MASK) << 8;
ret = host_stage2_idmap(addr);