diff options
author | Quentin Perret <qperret@google.com> | 2024-04-23 18:05:14 +0300 |
---|---|---|
committer | Marc Zyngier <maz@kernel.org> | 2024-05-01 18:46:58 +0300 |
commit | 02949f36bc7b723944bf754b71cfdf75e5e36f44 (patch) | |
tree | d22ca24b0b8a199f4bd1d10767fc6010199a432c | |
parent | cb16301626c339b3ccde93e5deea0569e508cb98 (diff) | |
download | linux-02949f36bc7b723944bf754b71cfdf75e5e36f44.tar.xz |
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 <qperret@google.com>
Signed-off-by: Fuad Tabba <tabba@google.com>
Acked-by: Oliver Upton <oliver.upton@linux.dev>
Link: https://lore.kernel.org/r/20240423150538.2103045-7-tabba@google.com
Signed-off-by: Marc Zyngier <maz@kernel.org>
-rw-r--r-- | arch/arm64/kvm/hyp/nvhe/mem_protect.c | 8 |
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); |