diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2022-11-07 09:43:05 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2022-11-07 09:43:05 +0000 |
commit | 66481bd82897646be9910d4ec6eaa8b1ebf0fa84 (patch) | |
tree | b91f8bb587c3651517a76200dac06db3d7d0e4e2 /sys/arch | |
parent | 4aedb1f89f2371a4ca16888274f2474d89f1049a (diff) |
Implement db_write_text/bytes() which add support for ddb(4)'s breakpoints.
Based on a diff from gerhard@, ok kettenis@
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/arm64/arm64/db_interface.c | 70 | ||||
-rw-r--r-- | sys/arch/arm64/arm64/pmap.c | 22 | ||||
-rw-r--r-- | sys/arch/arm64/arm64/trap.c | 3 | ||||
-rw-r--r-- | sys/arch/arm64/include/pmap.h | 3 |
4 files changed, 75 insertions, 23 deletions
diff --git a/sys/arch/arm64/arm64/db_interface.c b/sys/arch/arm64/arm64/db_interface.c index 0d9c43b1be8..7b2a14e9e8a 100644 --- a/sys/arch/arm64/arm64/db_interface.c +++ b/sys/arch/arm64/arm64/db_interface.c @@ -1,4 +1,4 @@ -/* $OpenBSD: db_interface.c,v 1.13 2022/10/15 08:04:02 jsg Exp $ */ +/* $OpenBSD: db_interface.c,v 1.14 2022/11/07 09:43:04 mpi Exp $ */ /* $NetBSD: db_interface.c,v 1.34 2003/10/26 23:11:15 chris Exp $ */ /* @@ -34,28 +34,28 @@ /* * Interface to new debugger. */ + #include <sys/param.h> #include <sys/proc.h> #include <sys/reboot.h> -#include <sys/systm.h> /* just for boothowto */ -#include <sys/exec.h> +#include <sys/systm.h> #include <sys/mutex.h> #include <uvm/uvm_extern.h> -#include <arm64/db_machdep.h> +#include <dev/cons.h> + +#include <machine/cpufunc.h> +#include <machine/db_machdep.h> #include <machine/pmap.h> -#include <ddb/db_access.h> + +#include <ddb/db_sym.h> #include <ddb/db_command.h> +#include <ddb/db_extern.h> #include <ddb/db_output.h> #include <ddb/db_run.h> #include <ddb/db_variables.h> -#include <ddb/db_sym.h> -#include <ddb/db_extern.h> -#include <ddb/db_interface.h> -#include <dev/cons.h> -//static long nil; int db_access_und_sp (struct db_variable *, db_expr_t *, int); int db_access_abt_sp (struct db_variable *, db_expr_t *, int); @@ -230,14 +230,48 @@ db_read_bytes(vaddr_t addr, size_t size, char *data) } } -#if 0 +/* + * Write bytes somewhere in the kernel text. Make the text + * pages writable temporarily. + */ static void db_write_text(vaddr_t addr, size_t size, char *data) { - // Implement - return ; + vaddr_t pgva; + size_t limit; + char *dst; + + if (size == 0) + return; + + dst = (char *)addr; + + do { + /* + * Get the VA for the page. + */ + pgva = trunc_page((vaddr_t)dst); + + /* + * Compute number of bytes that can be written + * with this mapping and subtract it from the + * total size. + */ + limit = PAGE_SIZE - ((vaddr_t)dst & PGOFSET); + if (limit > size) + limit = size; + size -= limit; + + pmap_page_rw(pmap_kernel(), pgva); + + for (; limit > 0; limit--) + *dst++ = *data++; + + /* Restore protection */ + pmap_page_ro(pmap_kernel(), pgva, PROT_READ|PROT_EXEC); + + } while (size != 0); } -#endif /* * Write bytes to kernel address space for debugger. @@ -245,14 +279,12 @@ db_write_text(vaddr_t addr, size_t size, char *data) void db_write_bytes(vaddr_t addr, size_t size, char *data) { -#if 0 extern char etext[]; - extern char kernel_text[]; char *dst; size_t loop; /* If any part is in kernel text, use db_write_text() */ - if (addr >= (vaddr_t) kernel_text && addr < (vaddr_t) etext) { + if (addr >= KERNBASE && addr < (vaddr_t)&etext) { db_write_text(addr, size, data); return; } @@ -270,9 +302,7 @@ db_write_bytes(vaddr_t addr, size_t size, char *data) cpu_icache_sync_range(addr, size); /* In case the current page tables have been modified ... */ - cpu_tlb_flushID(); - cpu_cpwait(); -#endif + cpu_tlb_flush(); } void diff --git a/sys/arch/arm64/arm64/pmap.c b/sys/arch/arm64/arm64/pmap.c index 49a6308319e..abe0b61eb82 100644 --- a/sys/arch/arm64/arm64/pmap.c +++ b/sys/arch/arm64/arm64/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.85 2022/09/10 20:35:28 miod Exp $ */ +/* $OpenBSD: pmap.c,v 1.86 2022/11/07 09:43:04 mpi Exp $ */ /* * Copyright (c) 2008-2009,2014-2016 Dale Rahn <drahn@dalerahn.com> * @@ -1540,6 +1540,26 @@ pmap_page_ro(pmap_t pm, vaddr_t va, vm_prot_t prot) ttlb_flush(pm, pted->pted_va & ~PAGE_MASK); } +#ifdef DDB +void +pmap_page_rw(pmap_t pm, vaddr_t va) +{ + struct pte_desc *pted; + uint64_t *pl3; + + /* Every VA needs a pted, even unmanaged ones. */ + pted = pmap_vp_lookup(pm, va, &pl3); + if (!pted || !PTED_VALID(pted)) { + return; + } + + pted->pted_va |= PROT_WRITE; + pted->pted_pte |= PROT_WRITE; + pmap_pte_update(pted, pl3); + ttlb_flush(pm, pted->pted_va & ~PAGE_MASK); +} +#endif /* DDB */ + /* * Lower the protection on the specified physical page. * diff --git a/sys/arch/arm64/arm64/trap.c b/sys/arch/arm64/arm64/trap.c index 1932e3850d6..4d089fc3774 100644 --- a/sys/arch/arm64/arm64/trap.c +++ b/sys/arch/arm64/arm64/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.41 2022/11/06 11:44:30 kettenis Exp $ */ +/* $OpenBSD: trap.c,v 1.42 2022/11/07 09:43:04 mpi Exp $ */ /*- * Copyright (c) 2014 Andrew Turner * All rights reserved. @@ -243,6 +243,7 @@ do_el1h_sync(struct trapframe *frame) /* XXX */ int db_trapper (u_int, u_int, trapframe_t *, int); db_trapper(frame->tf_elr, 0/*XXX*/, frame, exception); + break; } #endif panic("Unknown kernel exception %x esr_el1 %llx lr %lxpc %lx", diff --git a/sys/arch/arm64/include/pmap.h b/sys/arch/arm64/include/pmap.h index 5a655287bdd..73ce53b5ba0 100644 --- a/sys/arch/arm64/include/pmap.h +++ b/sys/arch/arm64/include/pmap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.h,v 1.19 2022/02/04 18:15:40 kettenis Exp $ */ +/* $OpenBSD: pmap.h,v 1.20 2022/11/07 09:43:04 mpi Exp $ */ /* * Copyright (c) 2008,2009,2014 Dale Rahn <drahn@dalerahn.com> * @@ -97,6 +97,7 @@ vaddr_t pmap_bootstrap(long kvo, paddr_t lpt1, long kernelstart, long kernelend, long ram_start, long ram_end); void pmap_kenter_cache(vaddr_t va, paddr_t pa, vm_prot_t prot, int cacheable); void pmap_page_ro(pmap_t pm, vaddr_t va, vm_prot_t prot); +void pmap_page_rw(pmap_t pm, vaddr_t va); paddr_t pmap_steal_avail(size_t size, int align, void **kva); void pmap_avail_fixup(void); |