ANDROID: arm64: Call fixup_exception() within do_sea()

path_lookupat() is capable of safely reading unampped VAs. If an
unmapped VA is read whilst the function is being called, the resulting
page fault will get re-directed to __do_page_fault(), which will call
fixup_exception() to handle the aforementioned unmapped VA read.

Now, for an OS running in a VM, let's say that memory was still mapped
at S1 but lent to another VM (i.e. unmapped at S2 for the given VM).
The reading of an unmapped VA in path_lookupat() still needs to be
handled. For hypervisors that inject an abort leading to a do_sea()
call, call fixup_exception() from do_sea() if
trace_android_vh_try_fixup_sea() indicates that we can do so.

Bug: 320358381
Change-Id: I0aedcd954f08e3011b27524f9a7b038debbb246d
Signed-off-by: Chris Goldsworthy <quic_cgoldswo@quicinc.com>
This commit is contained in:
Chris Goldsworthy 2024-02-05 20:55:12 -08:00 committed by Will Deacon
parent d6b58cc171
commit 9be763fb64
3 changed files with 11 additions and 0 deletions

View file

@ -746,6 +746,11 @@ static int do_sea(unsigned long far, unsigned long esr, struct pt_regs *regs)
{
const struct fault_info *inf;
unsigned long siaddr;
bool can_fixup = false;
trace_android_vh_try_fixup_sea(far, esr, regs, &can_fixup);
if (can_fixup && fixup_exception(regs))
return 0;
inf = esr_to_fault_info(esr);

View file

@ -244,6 +244,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_try_to_freeze_todo_unfrozen);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_die_kernel_fault);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_do_sea);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_do_sp_pc_abort);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_try_fixup_sea);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_do_undefinstr);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_do_el1_bti);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_do_el1_fpac);

View file

@ -21,6 +21,11 @@ DECLARE_RESTRICTED_HOOK(android_rvh_do_sp_pc_abort,
TP_ARGS(addr, esr, regs),
TP_CONDITION(!user_mode(regs)));
DECLARE_HOOK(android_vh_try_fixup_sea,
TP_PROTO(unsigned long addr, unsigned long esr, struct pt_regs *regs,
bool *can_fixup),
TP_ARGS(addr, esr, regs, can_fixup));
#endif /* _TRACE_HOOK_FAULT_H */
/* This part must be outside protection */
#include <trace/define_trace.h>