From nobody Thu Mar 23 19:02:47 2023 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4PjF8l4fPtz41h6f; Thu, 23 Mar 2023 19:02:47 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4PjF8l3K7xz3pKk; Thu, 23 Mar 2023 19:02:47 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1679598167; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=6mQIdqrm8xpdUM9jmazHVHUGv18hOH1QolSOuwn86us=; b=DhKWdw/flyM9xy9TlpnOqbiex9VT5uFGz0otA5Zau3BxOxSK/dAI6E8IbOCflf2yZ00RVU N0ggxKsn1meRfAYJVqitqOnqIKRjx6z1cqCzkGL3h8qDMoUBZMIcqMPoYHiYF9JowriSBT jQXQcGu5IpeaSqZojrO7M0YRZnvmYfzLLBNIIs4ZCJKnszZb4N8NVUMGq0wyrMheupGqbN uS7CvTZsB3J5vbLal/rwQuk/+bx6ef6JVyk/y8cO7mhwdVNvxZcU6TzlG6dLKhxzKe2R0R GXvB4O50NzeJeu7U9vzFaQaMJQ3EXo8YApuHxaMKokJ+sESlGvj0QvtrX/JWLw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1679598167; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=6mQIdqrm8xpdUM9jmazHVHUGv18hOH1QolSOuwn86us=; b=extOb+IMRqRQ1ZxZqZzo8G2PsmZDjokXlD+ic04VLsig4uTDWOQ9G5aZTIK7gBp4eTyGpS RHY4itkehR9/PPgj8LMmAWgBqqRz5DiK7+4PMjKuCThrtyVmIYFRDy3mGmJHsMcb2pQqOY 1oXUfplXo7OWCx81AIPkbQ+6HoZlLjG7wy0tCqW7p3ApiMf8eJbV5GpEkqCUKZlTljae7Y N+ByKePF2v2mx2vPnrQfnP9BulStIOBDsUi97b2FQoPVmEwXDZ2vo+dNDEHGDK4wVrEitO IxL9sP1JTUpqFAA+ij2Z99xVZF6NezO1ndW7Ai3LCqHFKkfjmmtZvwownCyDBQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1679598167; a=rsa-sha256; cv=none; b=jRYzDWdqWhgxyQ/KN+bPrVSRwhJetlHNmeA0yRdQqMr0zbIlSp34rxoYpbfjhLE1oLHyeQ SJoAX1iLSnJ5U9cLFADE9Xu6HnxxlX9+omw3/pSQpzL+iTPCj3KReQHC2bBLTb0eMuVhUw WzECUrHSDmm7oBbOlIJNTiAHtXM+Rncvc4uZYWRysUu9+6ooPtSds+SWGhedQycx3e0Df7 21FMLu/Y8dBulVdhIdnyLNQgxyndFkORqqRhaZs9JfjN8pEiHivMwsTxgzk9ST8tZfxVfM ZUF6u8gMeBHX988s/wezCGIPDOAj6L+vIiJQ1K+h0DItP5EqXRscF2qDiuEyRg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4PjF8l2L1qzn4R; Thu, 23 Mar 2023 19:02:47 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 32NJ2l7G039328; Thu, 23 Mar 2023 19:02:47 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 32NJ2l9Q039327; Thu, 23 Mar 2023 19:02:47 GMT (envelope-from git) Date: Thu, 23 Mar 2023 19:02:47 GMT Message-Id: <202303231902.32NJ2l9Q039327@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Andrew Turner Subject: git: f4036a92346e - main - arm64: add fault address to trapframe List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: andrew X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: f4036a92346e9f7c70a9db88352f172e198e3402 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=f4036a92346e9f7c70a9db88352f172e198e3402 commit f4036a92346e9f7c70a9db88352f172e198e3402 Author: Zachary Leaf AuthorDate: 2023-03-02 14:15:54 +0000 Commit: Andrew Turner CommitDate: 2023-03-23 18:56:26 +0000 arm64: add fault address to trapframe It was previously possible for the fault address register to get clobbered before it was saved. This small window occurred when an additional exception was encountered inside the exception handler, overwriting the previous value. Commit f29942229d24 ("Read the arm64 far early in el0 exceptions") patched this issue, but avoided changing the trapframe since this could be considered a KBI change in FreeBSD 13. Revert the above fix and save the fault address in the trapframe instead. This saves the fault address even earlier in the exception handling process, and is a more robust and simple fix. Reviewed by: andrew, jhb, jrtc27 Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D38984 --- sys/arm64/arm64/exception.S | 20 +++----------------- sys/arm64/arm64/genassym.c | 1 + sys/arm64/arm64/trap.c | 17 +++++++++-------- sys/arm64/include/frame.h | 2 +- 4 files changed, 14 insertions(+), 26 deletions(-) diff --git a/sys/arm64/arm64/exception.S b/sys/arm64/arm64/exception.S index e23a7868b56f..c82b8307ab17 100644 --- a/sys/arm64/arm64/exception.S +++ b/sys/arm64/arm64/exception.S @@ -65,9 +65,10 @@ __FBSDID("$FreeBSD$"); mrs x10, elr_el1 mrs x11, spsr_el1 mrs x12, esr_el1 + mrs x13, far_el1 stp x18, lr, [sp, #(TF_SP - TF_X)]! - str x10, [sp, #(TF_ELR)] - stp x11, x12, [sp, #(TF_SPSR)] + stp x10, x11, [sp, #(TF_ELR)] + stp x12, x13, [sp, #(TF_ESR)] mrs x18, tpidr_el1 .endm @@ -211,25 +212,10 @@ ENTRY(handle_el1h_irq) END(handle_el1h_irq) ENTRY(handle_el0_sync) - /* - * Read the fault address early. The current thread structure may - * be transiently unmapped if it is part of a memory range being - * promoted or demoted to/from a superpage. As this involves a - * break-before-make sequence there is a short period of time where - * an access will raise an exception. If this happens the fault - * address will be changed to the kernel address so a later read of - * far_el1 will give the wrong value. - * - * The earliest memory access that could trigger a fault is in a - * function called by the save_registers macro so this is the latest - * we can read the userspace value. - */ - mrs x19, far_el1 save_registers 0 ldr x0, [x18, #PC_CURTHREAD] mov x1, sp str x1, [x0, #TD_FRAME] - mov x2, x19 bl do_el0_sync do_ast restore_registers 0 diff --git a/sys/arm64/arm64/genassym.c b/sys/arm64/arm64/genassym.c index 3d88835c0f8e..db07f1714f5a 100644 --- a/sys/arm64/arm64/genassym.c +++ b/sys/arm64/arm64/genassym.c @@ -77,4 +77,5 @@ ASSYM(TF_SIZE, sizeof(struct trapframe)); ASSYM(TF_SP, offsetof(struct trapframe, tf_sp)); ASSYM(TF_ELR, offsetof(struct trapframe, tf_elr)); ASSYM(TF_SPSR, offsetof(struct trapframe, tf_spsr)); +ASSYM(TF_ESR, offsetof(struct trapframe, tf_esr)); ASSYM(TF_X, offsetof(struct trapframe, tf_x)); diff --git a/sys/arm64/arm64/trap.c b/sys/arm64/arm64/trap.c index 50f6e9de874b..1b7d945ff115 100644 --- a/sys/arm64/arm64/trap.c +++ b/sys/arm64/arm64/trap.c @@ -76,7 +76,7 @@ __FBSDID("$FreeBSD$"); /* Called from exception.S */ void do_el1h_sync(struct thread *, struct trapframe *); -void do_el0_sync(struct thread *, struct trapframe *, uint64_t far); +void do_el0_sync(struct thread *, struct trapframe *); void do_el0_error(struct trapframe *); void do_serror(struct trapframe *); void unhandled_exception(struct trapframe *); @@ -465,6 +465,7 @@ do_el1h_sync(struct thread *td, struct trapframe *frame) uint64_t esr, far; int dfsc; + far = frame->tf_far; /* Read the esr register to get the exception details */ esr = frame->tf_esr; exception = ESR_ELx_EXCEPTION(esr); @@ -502,7 +503,6 @@ do_el1h_sync(struct thread *td, struct trapframe *frame) break; case EXCP_INSN_ABORT: case EXCP_DATA_ABORT: - far = READ_SPECIALREG(far_el1); dfsc = esr & ISS_DATA_DFSC_MASK; if (dfsc < nitems(abort_handlers) && abort_handlers[dfsc] != NULL) { @@ -541,7 +541,7 @@ do_el1h_sync(struct thread *td, struct trapframe *frame) case EXCP_FPAC: /* We can see this if the authentication on PAC fails */ print_registers(frame); - printf(" far: %16lx\n", READ_SPECIALREG(far_el1)); + print_gp_register("far", far); panic("FPAC kernel exception"); break; case EXCP_UNKNOWN: @@ -552,18 +552,18 @@ do_el1h_sync(struct thread *td, struct trapframe *frame) /* FALLTHROUGH */ default: print_registers(frame); - print_gp_register("far", READ_SPECIALREG(far_el1)); + print_gp_register("far", far); panic("Unknown kernel exception %x esr_el1 %lx", exception, esr); } } void -do_el0_sync(struct thread *td, struct trapframe *frame, uint64_t far) +do_el0_sync(struct thread *td, struct trapframe *frame) { pcpu_bp_harden bp_harden; uint32_t exception; - uint64_t esr; + uint64_t esr, far; int dfsc; /* Check we have a sane environment when entering from userland */ @@ -571,6 +571,7 @@ do_el0_sync(struct thread *td, struct trapframe *frame, uint64_t far) ("Invalid pcpu address from userland: %p (tpidr %lx)", get_pcpu(), READ_SPECIALREG(tpidr_el1))); + far = frame->tf_far; esr = frame->tf_esr; exception = ESR_ELx_EXCEPTION(esr); if (exception == EXCP_INSN_ABORT_L && far > VM_MAXUSER_ADDRESS) { @@ -711,7 +712,7 @@ do_serror(struct trapframe *frame) { uint64_t esr, far; - far = READ_SPECIALREG(far_el1); + far = frame->tf_far; esr = frame->tf_esr; print_registers(frame); @@ -725,7 +726,7 @@ unhandled_exception(struct trapframe *frame) { uint64_t esr, far; - far = READ_SPECIALREG(far_el1); + far = frame->tf_far; esr = frame->tf_esr; print_registers(frame); diff --git a/sys/arm64/include/frame.h b/sys/arm64/include/frame.h index 91ed6dbce920..fc10f8574161 100644 --- a/sys/arm64/include/frame.h +++ b/sys/arm64/include/frame.h @@ -47,7 +47,7 @@ struct trapframe { uint64_t tf_elr; uint64_t tf_spsr; uint64_t tf_esr; - uint64_t pad; /* struct must be 16B aligned */ + uint64_t tf_far; uint64_t tf_x[30]; };