Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/aarch64/aarch64 Use the PAR register to check for a...



details:   https://anonhg.NetBSD.org/src/rev/02aa5f59e739
branches:  trunk
changeset: 366523:02aa5f59e739
user:      ryo <ryo%NetBSD.org@localhost>
date:      Sun May 29 16:39:22 2022 +0000

description:
Use the PAR register to check for accessibility in db_(read|write)_bytes().

db_(read|write)_bytes() uses the TTBR[01] at that time, so it must check
if it is accessible in context at that time, not pmap_extract()
which uses the struct pmap of the process.

- It also checks if the address is writable.
- db_write_bytes() also requires ARMV81_PAN control.

diffstat:

 sys/arch/aarch64/aarch64/db_interface.c |  58 ++++++++++++++++++++++++--------
 1 files changed, 43 insertions(+), 15 deletions(-)

diffs (120 lines):

diff -r 6bd4d2491b9c -r 02aa5f59e739 sys/arch/aarch64/aarch64/db_interface.c
--- a/sys/arch/aarch64/aarch64/db_interface.c   Sun May 29 16:30:44 2022 +0000
+++ b/sys/arch/aarch64/aarch64/db_interface.c   Sun May 29 16:39:22 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: db_interface.c,v 1.17 2022/05/26 17:11:05 ryo Exp $ */
+/* $NetBSD: db_interface.c,v 1.18 2022/05/29 16:39:22 ryo Exp $ */
 
 /*
  * Copyright (c) 2017 Ryo Shimizu <ryo%nerv.org@localhost>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.17 2022/05/26 17:11:05 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.18 2022/05/29 16:39:22 ryo Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -39,7 +39,9 @@
 #include <uvm/pmap/pmap_pvt.h>
 #endif
 
+#include <aarch64/armreg.h>
 #include <aarch64/db_machdep.h>
+#include <aarch64/locore.h>
 #include <aarch64/machdep.h>
 #include <aarch64/pmap.h>
 
@@ -57,19 +59,40 @@
 
 db_regs_t ddb_regs;
 
-static int
-db_validate_address(vaddr_t addr)
+static bool
+db_accessible_address(vaddr_t addr, bool readonly)
 {
-       struct proc *p = curcpu()->ci_onproc->l_proc;
-       struct pmap *pmap;
+       register_t s;
+       uint64_t par;
+       int space;
+
+       space = aarch64_addressspace(addr);
+       if (space != AARCH64_ADDRSPACE_LOWER &&
+           space != AARCH64_ADDRSPACE_UPPER)
+               return false;
+
+       s = daif_disable(DAIF_I|DAIF_F);
 
-       if (!p || !p->p_vmspace || !p->p_vmspace->vm_map.pmap ||
-           addr >= VM_MAXUSER_ADDRESS)
-               pmap = pmap_kernel();
-       else
-               pmap = p->p_vmspace->vm_map.pmap;
+       switch (aarch64_addressspace(addr)) {
+       case AARCH64_ADDRSPACE_LOWER:
+               if (readonly)
+                       reg_s1e0r_write(addr);
+               else
+                       reg_s1e0w_write(addr);
+               break;
+       case AARCH64_ADDRSPACE_UPPER:
+               if (readonly)
+                       reg_s1e1r_write(addr);
+               else
+                       reg_s1e1w_write(addr);
+               break;
+       }
+       isb();
+       par = reg_par_el1_read();
 
-       return (pmap_extract(pmap, addr, NULL) == false);
+       reg_daif_write(s);
+
+       return ((par & PAR_F) == 0);
 }
 
 void
@@ -82,7 +105,7 @@
                const vaddr_t va = (vaddr_t)src;
                uintptr_t tmp;
 
-               if (lastpage != atop(va) && db_validate_address(va)) {
+               if (lastpage != atop(va) && !db_accessible_address(va, true)) {
                        db_printf("address %p is invalid\n", src);
                        memset(data, 0, size);  /* stubs are filled by zero */
                        return;
@@ -190,17 +213,19 @@
                data += s;
        }
 
-       /* XXX: need to check read only block/page */
        for (dst = (char *)addr; size > 0;) {
                const vaddr_t va = (vaddr_t)dst;
                uintptr_t tmp;
 
-               if (lastpage != atop(va) && db_validate_address(va)) {
+               if (lastpage != atop(va) && !db_accessible_address(va, false)) {
                        db_printf("address %p is invalid\n", dst);
                        return;
                }
                lastpage = atop(va);
 
+               if (aarch64_pan_enabled)
+                       reg_pan_write(0); /* disable PAN */
+
                tmp = (uintptr_t)dst | (uintptr_t)data;
                if (size >= 8 && (tmp & 7) == 0) {
                        *(uint64_t *)dst = *(const uint64_t *)data;
@@ -221,6 +246,9 @@
                        *dst++ = *data++;
                        size--;
                }
+
+               if (aarch64_pan_enabled)
+                       reg_pan_write(1); /* enable PAN */
        }
 }
 



Home | Main Index | Thread Index | Old Index