From fab25f7eb656b49b75a3b4fdcc0d347aa512bbb2 Mon Sep 17 00:00:00 2001 From: mpi Date: Mon, 7 Nov 2022 09:43:04 +0000 Subject: [PATCH] Implement db_write_text/bytes() which add support for ddb(4)'s breakpoints. Based on a diff from gerhard@, ok kettenis@ --- sys/arch/arm64/arm64/db_interface.c | 70 ++++++++++++++++++++--------- sys/arch/arm64/arm64/pmap.c | 22 ++++++++- sys/arch/arm64/arm64/trap.c | 3 +- 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 #include #include -#include /* just for boothowto */ -#include +#include #include #include -#include +#include + +#include +#include #include -#include + +#include #include +#include #include #include #include -#include -#include -#include -#include -//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 * @@ -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 * @@ -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); -- 2.20.1