git: e5c0e6d7810c - stable/12 - arm: Fix handling of undefined instruction aborts in THUMB2 mode.

From: Olivier Houchard <cognet_at_FreeBSD.org>
Date: Fri, 18 Nov 2022 10:02:48 UTC
The branch stable/12 has been updated by cognet:

URL: https://cgit.FreeBSD.org/src/commit/?id=e5c0e6d7810cbfc57b80f123ca48b485bdcd48d1

commit e5c0e6d7810cbfc57b80f123ca48b485bdcd48d1
Author:     Michal Meloun <mmel@FreeBSD.org>
AuthorDate: 2021-10-17 17:36:33 +0000
Commit:     Olivier Houchard <cognet@FreeBSD.org>
CommitDate: 2022-11-18 09:45:31 +0000

    arm: Fix handling of undefined instruction aborts in THUMB2 mode.
    
    Correctly recognize NEON/SIMD and VFP instructions in THUMB2 mode and pass
    these to the appropriate handler. Note that it is not necessary to filter
    all undefined instruction variant or register combinations, this is a job
    for given handler.
    
    Reported by:    Robert Clausecker <fuz@fuz.su>
    PR:             259187
    MFC after:      2 weks
    
    (cherry picked from commit a670e1c13a522df4fb8c63bb023b88b1d65de797)
    Signed-off-by: Olivier Houchard <cognet@FreeBSD.org>
---
 sys/arm/arm/undefined.c | 39 +++++++++++++++++++++++----------------
 1 file changed, 23 insertions(+), 16 deletions(-)

diff --git a/sys/arm/arm/undefined.c b/sys/arm/arm/undefined.c
index f6fd5bfab266..74ed1c2acc41 100644
--- a/sys/arm/arm/undefined.c
+++ b/sys/arm/arm/undefined.c
@@ -91,13 +91,25 @@ __FBSDID("$FreeBSD$");
 
 #define	ARM_COPROC_INSN(insn)	(((insn) & (1 << 27)) != 0)
 #define	ARM_VFP_INSN(insn)	((((insn) & 0xfe000000) == 0xf2000000) || \
-    (((insn) & 0xff100000) == 0xf4000000))
+				 (((insn) & 0xff100000) == 0xf4000000))
 #define	ARM_COPROC(insn)	(((insn) >> 8) & 0xf)
 
-#define	THUMB_32BIT_INSN(insn)	((insn) >= 0xe800)
+#define	THUMB_32BIT_INSN(insn)	((((insn) & 0xe000) == 0xe000) && \
+				 (((insn) & 0x1800) != 0))
+/*
+ * Coprocessor, Advanced SIMD, and
+ * Floating-point instructions on page A6-251
+ * OP1 == 01 OR 11
+ * OP2 == 1xxxxxx
+ */
 #define	THUMB_COPROC_INSN(insn)	(((insn) & (3 << 26)) == (3 << 26))
-#define	THUMB_COPROC_UNDEFINED(insn) (((insn) & 0x3e << 20) == 0)
-#define	THUMB_VFP_INSN(insn)	(((insn) & (3 << 24)) == (3 << 24))
+/*
+ * Advanced SIMD element or structure
+ * load/store instructions on page A7-275
+ * OP1 == 11
+ * OP2 == 001xxx0
+*/
+#define	THUMB_VFP_INSN(insn)	(((insn) & (0x1F1 << 20)) == (0x190 << 20))
 #define	THUMB_COPROC(insn)	(((insn) >> 8) & 0xf)
 
 #define	COPROC_VFP	10
@@ -282,18 +294,13 @@ undefinedinstruction(struct trapframe *frame)
 			fault_instruction <<= 16;
 			fault_instruction |= *(uint16_t *)(fault_pc + 2);
 
-			/*
-			 * Is it a Coprocessor, Advanced SIMD, or
-			 * Floating-point instruction.
-			 */
-			if (THUMB_COPROC_INSN(fault_instruction)) {
-				if (THUMB_COPROC_UNDEFINED(fault_instruction)) {
-					/* undefined insn */
-				} else if (THUMB_VFP_INSN(fault_instruction))
-					coprocessor = COPROC_VFP;
-				else
-					coprocessor =
-					    THUMB_COPROC(fault_instruction);
+			/* Coprocessor, Advanced SIMD and Floating-point */
+			if (THUMB_COPROC_INSN(fault_instruction))
+				coprocessor = THUMB_COPROC(fault_instruction);
+			else {
+				/* Advanced SIMD load/store */
+				if (THUMB_VFP_INSN(fault_instruction))
+					coprocessor = COPROC_VFP; /* SIMD */
 			}
 		}
 #else