Module Name: src Committed By: ryo Date: Sun May 29 16:39:22 UTC 2022
Modified Files: src/sys/arch/aarch64/aarch64: db_interface.c Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.17 -r1.18 src/sys/arch/aarch64/aarch64/db_interface.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/aarch64/aarch64/db_interface.c diff -u src/sys/arch/aarch64/aarch64/db_interface.c:1.17 src/sys/arch/aarch64/aarch64/db_interface.c:1.18 --- src/sys/arch/aarch64/aarch64/db_interface.c:1.17 Thu May 26 17:11:05 2022 +++ src/sys/arch/aarch64/aarch64/db_interface.c Sun May 29 16:39:22 2022 @@ -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 <r...@nerv.org> @@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: db_interface #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 @@ __KERNEL_RCSID(0, "$NetBSD: db_interface 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; - 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; + space = aarch64_addressspace(addr); + if (space != AARCH64_ADDRSPACE_LOWER && + space != AARCH64_ADDRSPACE_UPPER) + return false; + + s = daif_disable(DAIF_I|DAIF_F); - return (pmap_extract(pmap, addr, NULL) == false); + 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(); + + reg_daif_write(s); + + return ((par & PAR_F) == 0); } void @@ -82,7 +105,7 @@ db_read_bytes(vaddr_t addr, size_t size, 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 @@ db_write_bytes(vaddr_t addr, size_t size 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 @@ db_write_bytes(vaddr_t addr, size_t size *dst++ = *data++; size--; } + + if (aarch64_pan_enabled) + reg_pan_write(1); /* enable PAN */ } }