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 <[email protected]>
@@ -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 */
}
}