[Bug 298105] debug of TRAP 12 kernel 5k display issues (fixes provided) leads to pre-init pmap bug, stride/bpp bug and many outdated kernel constants on amd64 arm64 (and possibly others)
Date: Wed, 02 Sep 2026 17:21:06 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=298105
--- Comment #3 from Thomas Goldthorpe <tagoldth@gmail.com> ---
From a git pull of release/15.1.0-p3, git diff -p format
Note, fixed a typo in vt_early_fb.c that made it into the context diffs in
prior comments. Also note, vt_early_fb.c is just a bounds fix to bpp, it is
optional to include it as a patch to the system.
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 497c85c3f..f7c76dc1b 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -1676,7 +1676,20 @@ nkpt_init(vm_paddr_t addr)
* before vm_mem_init() and pmap_init(). 20MB for a frame buffer
* is not uncommon.
*/
- pt_pages += 32; /* 64MB additional slop. */
+
+ /*
+ * The 32 that was here was based on sizing of yesteryear. Thing
+ * is, modern framebuffers can easily be 90MB for the efifb portion.
+ * Lets be generous and give it twice that, or 192MB. I know I use
90MB
+ * of it at boot on a 5120x2880 (90MB is 8192stride*2880line*4byte)
+ * framebuffer. This has been manifesting as a trap 12 in early
+ * boot below because of passing the limit of pages allocated here.
+ * Those traps occur in the tmpsize/pmap_kenter_attr() loop when it
+ * hits the invalid space provided above it in the code.
+ *
+ * There are places NKPT are discussed that need new updating too.
+ */
+ pt_pages += 96; /* 192MB additional slop. */
#endif
nkpt = pt_pages;
}
@@ -9404,10 +9417,21 @@ pmap_mapdev_internal(vm_paddr_t pa, vm_size_t size, int
mode, int flags)
pa = trunc_page(pa);
if (!pmap_initialized) {
+ printf("%s: avail: 0x%016lx end: 0x%016lx free: 0x%016lx
(%luMB) req-paddr: 0x%016lx req-size:
%lu\n",__func__,virtual_avail,MAX(KERNBASE + nkpt * NBPDR,
kernel_vm_end),MAX(KERNBASE + nkpt * NBPDR,
kernel_vm_end)-virtual_avail,(MAX(KERNBASE + nkpt * NBPDR,
kernel_vm_end)-virtual_avail)/1024L/1024L,pa,size);
va = 0;
for (i = 0; i < PMAP_PREINIT_MAPPING_COUNT; i++) {
ppim = pmap_preinit_mapping + i;
if (ppim->va == 0) {
+ /*
+ * The code past this happily does the
erroneous allocation past virtual addresses
+ * reserved. The trap 12 crashes in early boot
seen because of this manifest themselves
+ * farther in the tmpsize loop doing
pmap_kenter_attr().
+ *
+ * Doing a panic() here, but, perhaps this
should return errors to the caller and
+ * let them deal with it? That may require too
much other coding, however.
+ */
+ if((virtual_avail+size)>=(MAX(KERNBASE + nkpt *
NBPDR, kernel_vm_end)))
+ panic("%s: passing end of kernel
virtual addresses allocated", __func__);
ppim->pa = pa;
ppim->sz = size;
ppim->mode = mode;
@@ -9450,11 +9474,17 @@ pmap_mapdev_internal(vm_paddr_t pa, vm_size_t size, int
mode, int flags)
if (va == 0)
panic("%s: Couldn't allocate KVA", __func__);
}
+
+
for (tmpsize = 0; tmpsize < size; tmpsize += PAGE_SIZE)
pmap_kenter_attr(va + tmpsize, pa + tmpsize, mode);
+
pmap_invalidate_range(kernel_pmap, va, va + tmpsize);
+
+
if ((flags & MAPDEV_FLUSHCACHE) != 0)
pmap_invalidate_cache_range(va, va + tmpsize);
+
return ((void *)(va + offset));
}
diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c
index 12ab8750c..be2b50ff4 100644
--- a/sys/arm64/arm64/pmap.c
+++ b/sys/arm64/arm64/pmap.c
@@ -303,7 +303,7 @@ VM_PAGE_TO_PV_LIST_LOCK(vm_page_t m)
struct pmap kernel_pmap_store;
/* Used for mapping ACPI memory before VM is initialized */
-#define PMAP_PREINIT_MAPPING_COUNT 32
+#define PMAP_PREINIT_MAPPING_COUNT 96
#define PMAP_PREINIT_MAPPING_SIZE (PMAP_PREINIT_MAPPING_COUNT *
L2_SIZE)
static vm_offset_t preinit_map_va; /* Start VA of pre-init mapping space
*/
static int vm_initialized = 0; /* No need to use pre-init maps when
set */
diff --git a/sys/arm64/include/pte.h b/sys/arm64/include/pte.h
index 464d8c941..846520640 100644
--- a/sys/arm64/include/pte.h
+++ b/sys/arm64/include/pte.h
@@ -211,7 +211,11 @@ typedef uint64_t pt_entry_t; /* page
table entry */
* A substantial portion of this is to make sure that we can cope with 4K
* framebuffers in early boot, assuming a common 4K resolution @ 32-bit depth.
*/
-#define PMAP_MAPDEV_EARLY_SIZE (L2_SIZE * 20)
+/*
+ * Framebuffers of 5k and 8k now easily possible with 32 bit depth
+ * Be sure these can work.
+ */
+#define PMAP_MAPDEV_EARLY_SIZE (L2_SIZE * 60)
#if PAGE_SIZE == PAGE_SIZE_4K
#define L0_ENTRIES_SHIFT 9
diff --git a/sys/dev/vt/hw/fb/vt_early_fb.c b/sys/dev/vt/hw/fb/vt_early_fb.c
index 9d66f5cd1..358bdaf98 100644
--- a/sys/dev/vt/hw/fb/vt_early_fb.c
+++ b/sys/dev/vt/hw/fb/vt_early_fb.c
@@ -282,6 +282,14 @@ vt_efb_init(struct vt_device *vd)
/* Get pixel storage size. */
info->fb_bpp = info->fb_stride / info->fb_width * 8;
+
+ /*
+ * XXX: above compuation fails with big strides on large framebuffers
+ * an 8192 stride on 5120 line gives 32768/5120*8 => 5*8 => 40 bits
+ */
+
+ if((info->fb_bpp)>32)
+ info->fb_bpp = 32;
#ifdef FDT
vt_efb_initialize(info, node);
diff --git a/sys/dev/vt/vt.h b/sys/dev/vt/vt.h
index 4abe99e4a..5a46db6dc 100644
--- a/sys/dev/vt/vt.h
+++ b/sys/dev/vt/vt.h
@@ -222,10 +222,15 @@ struct vt_buf {
term_char_t **vb_rows; /* (u) Array of rows */
};
+/*
+ * Modern machine console debugging has much more to scroll through, 500 ->
5000
+ * covers most of it
+ */
+
#ifdef SC_HISTORY_SIZE
#define VBF_DEFAULT_HISTORY_SIZE SC_HISTORY_SIZE
#else
-#define VBF_DEFAULT_HISTORY_SIZE 500
+#define VBF_DEFAULT_HISTORY_SIZE 5000
#endif
void vtbuf_lock(struct vt_buf *);
@@ -413,11 +418,15 @@ void vt_upgrade(struct vt_device *vd);
#define PIXEL_WIDTH(w) ((w) / 8)
#define PIXEL_HEIGHT(h) ((h) / 16)
+/*
+ * Modern framebuffers are much larger than 4096x2048, they could be 8192
landscape or portrait
+ */
+
#ifndef VT_FB_MAX_WIDTH
-#define VT_FB_MAX_WIDTH 4096
+#define VT_FB_MAX_WIDTH 8192
#endif
#ifndef VT_FB_MAX_HEIGHT
-#define VT_FB_MAX_HEIGHT 2400
+#define VT_FB_MAX_HEIGHT 8192
#endif
/* name argument is not used yet. */
--
You are receiving this mail because:
You are the assignee for the bug.