Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/arm32 if Thumb-32 bit instruction located on a ...



details:   https://anonhg.NetBSD.org/src/rev/4615af0ca027
branches:  trunk
changeset: 465585:4615af0ca027
user:      ryo <ryo%NetBSD.org@localhost>
date:      Fri Nov 29 17:33:43 2019 +0000

description:
if Thumb-32 bit instruction located on a page boundariy, also need to consider the pc + 2 address.

Fix PR/54720. more detail and PoC are descrived in the PR.

diffstat:

 sys/arch/arm/arm32/fault.c |  19 +++++++++++++++++--
 1 files changed, 17 insertions(+), 2 deletions(-)

diffs (47 lines):

diff -r 062c92f0c317 -r 4615af0ca027 sys/arch/arm/arm32/fault.c
--- a/sys/arch/arm/arm32/fault.c        Fri Nov 29 17:29:31 2019 +0000
+++ b/sys/arch/arm/arm32/fault.c        Fri Nov 29 17:33:43 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fault.c,v 1.108 2019/04/06 03:06:25 thorpej Exp $      */
+/*     $NetBSD: fault.c,v 1.109 2019/11/29 17:33:43 ryo Exp $  */
 
 /*
  * Copyright 2003 Wasabi Systems, Inc.
@@ -81,7 +81,7 @@
 #include "opt_kgdb.h"
 
 #include <sys/types.h>
-__KERNEL_RCSID(0, "$NetBSD: fault.c,v 1.108 2019/04/06 03:06:25 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fault.c,v 1.109 2019/11/29 17:33:43 ryo Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -838,6 +838,9 @@
        UVMHIST_LOG(maphist, " (pc=0x%jx, l=0x%#jx, tf=0x%#jx)",
            fault_pc, (uintptr_t)l, (uintptr_t)tf, 0);
 
+#ifdef THUMB_CODE
+ recheck:
+#endif
        /* Ok validate the address, can only execute in USER space */
        if (__predict_false(fault_pc >= VM_MAXUSER_ADDRESS ||
            (fault_pc < VM_MIN_ADDRESS && vector_page == ARM_VECTORS_LOW))) {
@@ -897,6 +900,18 @@
        call_trapsignal(l, tf, &ksi);
 
 out:
+
+#ifdef THUMB_CODE
+#define THUMB_32BIT(hi) (((hi) & 0xe000) == 0xe000 && ((hi) & 0x1800))
+       /* thumb-32 instruction was located on page boundary? */
+       if ((tf->tf_spsr & PSR_T_bit) &&
+           ((fault_pc & PAGE_MASK) == (PAGE_SIZE - THUMB_INSN_SIZE)) &&
+           THUMB_32BIT(*(uint16_t *)tf->tf_pc)) {
+               fault_pc = tf->tf_pc + THUMB_INSN_SIZE;
+               goto recheck;
+       }
+#endif /* THUMB_CODE */
+
        KASSERT(!TRAP_USERMODE(tf) || VALID_R15_PSR(tf->tf_pc, tf->tf_spsr));
        userret(l);
 }



Home | Main Index | Thread Index | Old Index