Ignore PC/SP contents in SEGV_MTEAERR faults.

SEGV_MTEAERR (Async MTE fault) is delivered at an arbitrary point
after the actual fault. Register contents, including PC and SP, are
unrelated to the fault and can only confuse ART signal handlers.

To be more precise, SEGV_MTEAERR is delivered at the nearest kernel
entry after the invalid memory access. It is normally a system call, but
can also be a random process scheduling event.

I could not reproduce the problem locally, but it is apparently
possible to crash with "Check failed: found_virtual Didn't find oat
method index for virtual method:" if the garbage PC value passes all the
sanity checks in FaultManager::HandleFault, with a stack trace like
this:
  art::FindOatMethodFor
  art::ArtMethod::GetOatQuickMethodHeader
  art::FaultManager::IsInGeneratedCode
  art::FaultManager::HandleFault

Bug: 201492782
Test: none

Change-Id: I028067f1350574ea002f3e98a94babe2b10c2559
diff --git a/runtime/arch/arm64/fault_handler_arm64.cc b/runtime/arch/arm64/fault_handler_arm64.cc
index c139e21..058c52d 100644
--- a/runtime/arch/arm64/fault_handler_arm64.cc
+++ b/runtime/arch/arm64/fault_handler_arm64.cc
@@ -38,7 +38,7 @@
 
 namespace art {
 
-void FaultManager::GetMethodAndReturnPcAndSp(siginfo_t* siginfo ATTRIBUTE_UNUSED,
+void FaultManager::GetMethodAndReturnPcAndSp(siginfo_t* siginfo,
                                              void* context,
                                              ArtMethod** out_method,
                                              uintptr_t* out_return_pc,
@@ -46,6 +46,14 @@
                                              bool* out_is_stack_overflow) {
   struct ucontext *uc = reinterpret_cast<struct ucontext *>(context);
   struct sigcontext *sc = reinterpret_cast<struct sigcontext*>(&uc->uc_mcontext);
+
+  // SEGV_MTEAERR (Async MTE fault) is delivered at an arbitrary point after the actual fault.
+  // Register contents, including PC and SP, are unrelated to the fault and can only confuse ART
+  // signal handlers.
+  if (siginfo->si_signo == SIGSEGV && siginfo->si_code == SEGV_MTEAERR) {
+    return;
+  }
+
   *out_sp = static_cast<uintptr_t>(sc->sp);
   VLOG(signals) << "sp: " << *out_sp;
   if (*out_sp == 0) {
@@ -190,4 +198,3 @@
   return true;
 }
 }       // namespace art
-