ANDROID: 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. Bug: 311830307 Change-Id: I26d61b04a4ccf040bd31802abb3c6b998ff4a48b Signed-off-by: Quentin Perret <qperret@google.com>
This commit is contained in:
parent
c5dc4b4b3d
commit
031f804149
1 changed files with 9 additions and 1 deletions
|
|
@ -875,7 +875,14 @@ void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt)
|
||||||
int ret = -EPERM;
|
int ret = -EPERM;
|
||||||
|
|
||||||
esr = read_sysreg_el2(SYS_ESR);
|
esr = read_sysreg_el2(SYS_ESR);
|
||||||
BUG_ON(!__get_fault_info(esr, &fault));
|
if (!__get_fault_info(esr, &fault)) {
|
||||||
|
addr = (u64)-1;
|
||||||
|
/*
|
||||||
|
* We've presumably raced with a page-table change which caused
|
||||||
|
* AT to fail, try again.
|
||||||
|
*/
|
||||||
|
goto return_to_host;
|
||||||
|
}
|
||||||
fault.esr_el2 = esr;
|
fault.esr_el2 = esr;
|
||||||
|
|
||||||
addr = (fault.hpfar_el2 & HPFAR_MASK) << 8;
|
addr = (fault.hpfar_el2 & HPFAR_MASK) << 8;
|
||||||
|
|
@ -902,6 +909,7 @@ void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt)
|
||||||
else
|
else
|
||||||
BUG_ON(ret && ret != -EAGAIN);
|
BUG_ON(ret && ret != -EAGAIN);
|
||||||
|
|
||||||
|
return_to_host:
|
||||||
trace_host_mem_abort(esr, addr);
|
trace_host_mem_abort(esr, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue