--- a/sys/platform/vkernel64/x86_64/db_trace.c 2026-10-06 02:39:23.807794758 +0000 +++ b/sys/platform/vkernel64/x86_64/db_trace.c 2026-10-06 02:39:38.363605685 +0000 @@ -128,8 +128,18 @@ /* * Stack trace. + * + * NOTE: the inherited pc64 definition of INKERNEL() as `>= USRSTACK` is + * WRONG for the vkernel: the vkernel's kernel lives in [KvaStart, KvaEnd) + * (vmparam.h KERNEL_KVA_START 512GB .. +KERNEL_KVA_SIZE, mapped at + * platform/init.c:609-621), which is deep INSIDE the guest-user VA range + * [0, USRSTACK) — the inherited test would reject every real kernel frame + * and accept every guest-user address. Keep the macro but bound the walk + * by the actual kernel KVA range (KvaStart/KvaEnd, vm/pmap.h). */ -#define INKERNEL(va) (((vm_offset_t)(va)) >= USRSTACK) +#define INKERNEL(va) \ + (((vm_offset_t)(va)) >= KvaStart && \ + ((vm_offset_t)(va)) < KvaEnd) struct x86_64_frame { struct x86_64_frame *f_frame; @@ -224,7 +234,8 @@ db_expr_t offset; const char *sym, *name; - if ((unsigned long)*fp < PAGE_SIZE) { + if ((unsigned long)*fp < PAGE_SIZE || !INKERNEL((vm_offset_t)*fp)) { + db_printf("frame %p is not in kernel space\n", *fp); *fp = NULL; return; } @@ -255,6 +266,18 @@ */ if (frame_type == NORMAL) { *ip = (db_addr_t) rip; + /* + * The adopted frame must be in kernel KVA and must move + * strictly up the stack: kills wild pointers, cycles, and + * guest-user frame chains adopted from corrupted stack + * content (which fault in db_read_bytes — whose no-fault + * recovery is broken outside a DDB session). + */ + if (!INKERNEL((vm_offset_t)rbp) || + (struct x86_64_frame *)rbp <= *fp) { + *fp = NULL; + return; + } *fp = (struct x86_64_frame *) rbp; return; } @@ -306,7 +329,10 @@ } *ip = (db_addr_t) rip; - *fp = (struct x86_64_frame *) rbp; + if (!INKERNEL((vm_offset_t)rbp)) + *fp = NULL; + else + *fp = (struct x86_64_frame *) rbp; } void @@ -333,6 +359,10 @@ * a convenience. */ frame = (struct x86_64_frame *)addr; + if (!INKERNEL((vm_offset_t)frame)) { + db_printf("%p is not in kernel space\n", (void *)addr); + return; + } for (i = 0; i < 4096; i += 8) { struct x86_64_frame *check;