git: 570206bdc227 - stable/13 - arm64: Enable the floating-point exception traps
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 17 Jun 2022 19:40:48 UTC
The branch stable/13 has been updated by dchagin:
URL: https://cgit.FreeBSD.org/src/commit/?id=570206bdc227c59d1e1e34f76387d3817d2c0354
commit 570206bdc227c59d1e1e34f76387d3817d2c0354
Author: Dmitry Chagin <dchagin@FreeBSD.org>
AuthorDate: 2022-05-19 16:53:56 +0000
Commit: Dmitry Chagin <dchagin@FreeBSD.org>
CommitDate: 2022-06-17 19:35:25 +0000
arm64: Enable the floating-point exception traps
To enable it user-space needs to call feenableexcept().
FPE_FLTIDO has been added as the IDF bit can't be mapped to any existing
FPE code.
Reviewed by: andrew@
Differential revision: https://reviews.freebsd.org/D35247
MFC after: 2 weeks
(cherry picked from commit 6e2caba7a1297eeda4f43e6377667d2e049f24f9)
---
sys/arm64/arm64/trap.c | 32 +++++++++++++++++++++++++++++++-
sys/arm64/include/armreg.h | 8 ++++++++
sys/sys/signal.h | 1 +
3 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/sys/arm64/arm64/trap.c b/sys/arm64/arm64/trap.c
index 5638bb9f496e..e9afbd47c0af 100644
--- a/sys/arm64/arm64/trap.c
+++ b/sys/arm64/arm64/trap.c
@@ -409,6 +409,29 @@ print_registers(struct trapframe *frame)
printf("spsr: %8x\n", frame->tf_spsr);
}
+#ifdef VFP
+static void
+fpe_trap(struct thread *td, void *addr, uint32_t exception)
+{
+ int code;
+
+ code = FPE_FLTIDO;
+ if ((exception & ISS_FP_TFV) != 0) {
+ if ((exception & ISS_FP_IOF) != 0)
+ code = FPE_FLTINV;
+ else if ((exception & ISS_FP_DZF) != 0)
+ code = FPE_FLTDIV;
+ else if ((exception & ISS_FP_OFF) != 0)
+ code = FPE_FLTOVF;
+ else if ((exception & ISS_FP_UFF) != 0)
+ code = FPE_FLTUND;
+ else if ((exception & ISS_FP_IXF) != 0)
+ code = FPE_FLTRES;
+ }
+ call_trapsignal(td, SIGFPE, code, addr, exception);
+}
+#endif
+
void
do_el1h_sync(struct thread *td, struct trapframe *frame)
{
@@ -548,11 +571,18 @@ do_el0_sync(struct thread *td, struct trapframe *frame)
switch (exception) {
case EXCP_FP_SIMD:
- case EXCP_TRAP_FP:
#ifdef VFP
vfp_restore_state();
#else
panic("VFP exception in userland");
+#endif
+ break;
+ case EXCP_TRAP_FP:
+#ifdef VFP
+ fpe_trap(td, (void *)frame->tf_elr, esr);
+ userret(td, frame);
+#else
+ panic("VFP exception in userland");
#endif
break;
case EXCP_SVC32:
diff --git a/sys/arm64/include/armreg.h b/sys/arm64/include/armreg.h
index 8dc517f11a20..e16b17aa4cab 100644
--- a/sys/arm64/include/armreg.h
+++ b/sys/arm64/include/armreg.h
@@ -179,6 +179,14 @@
/* ESR_ELx */
#define ESR_ELx_ISS_MASK 0x01ffffff
+#define ISS_FP_TFV_SHIFT 23
+#define ISS_FP_TFV (0x01 << ISS_FP_TFV_SHIFT)
+#define ISS_FP_IOF 0x01
+#define ISS_FP_DZF 0x02
+#define ISS_FP_OFF 0x04
+#define ISS_FP_UFF 0x08
+#define ISS_FP_IXF 0x10
+#define ISS_FP_IDF 0x80
#define ISS_INSN_FnV (0x01 << 10)
#define ISS_INSN_EA (0x01 << 9)
#define ISS_INSN_S1PTW (0x01 << 7)
diff --git a/sys/sys/signal.h b/sys/sys/signal.h
index 8b45a521c3ee..5985ec9e94ee 100644
--- a/sys/sys/signal.h
+++ b/sys/sys/signal.h
@@ -332,6 +332,7 @@ struct siginfo32 {
#define FPE_FLTRES 6 /* Floating point inexact result. */
#define FPE_FLTINV 7 /* Invalid floating point operation. */
#define FPE_FLTSUB 8 /* Subscript out of range. */
+#define FPE_FLTIDO 9 /* Input denormal operation */
/* codes for SIGTRAP */
#define TRAP_BRKPT 1 /* Process breakpoint. */