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)
Summary: debug of TRAP 12 kernel 5k display issues (fixes provided) leads to pre-init ...
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 15.1-RELEASE
Hardware: Any Any
: --- Affects Some People
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2026-09-01 23:02 UTC by Thomas Goldthorpe
Modified: 2026-09-02 17:44 UTC (History)
6 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Goldthorpe 2026-09-01 23:02:21 UTC
Files involved/modified:

usr/src/sys/amd64/amd64/pmap.c
usr/src/sys/arm64/arm64/pmap.c
usr/src/sys/arm64/include/pte.h
usr/src/sys/dev/vt/hw/efifb/efifb.c (the caller that snowballs it all)
usr/src/sys/dev/vt/hw/fb/vt_early_fb.c (stride/bpp calculation error)
usr/src/sys/dev/vt/vt.h

It was assumed that https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=280597 had fixed 5k (5120x2880) screen issues at boot and was closed.  A part of the assumption that the bug was in the loader only was due to never seeing the initial kernel banner.  The crash/hang happened when printing the screen configuration and calling the loaded kernel.

Replacing the loader with a custom one that purposely set things up revealed that the crashes are happening pre-init in the kernel, specifically in pmap_mapdev_internal() during a call to pmap_kenter_attr(), which is looped many times with a small page size on the newly allocated pa to va range.

Though the crash is here, doing some pre-init debugging via some inserted profiling code dumping to EARLY_PRINTF, the problem in pmap_kenter_attr() is due to an invalid va being stumbled on part way through the execution of the loop.

This invalid va comes from an allocation out of virtual_avail, with no bounds check in place before doing the allocation.

The bounds comes from the outdated constants that make up how much virtual_avail is allocated (via nkpt).

As I have amd64 and arm64, I did the trackdown on the amd64 and made a bounds check for use in the pre-init case.  Also updated the constants for amd64 and arm64.

I did not bother writing a check for similar bounds problems in the arm code, but did update the requisite constants there too to stop the crashes/hangs.

The problem:

The vitual_avail is set up and sized by way of code and constants that make assumptions about the things encountered pre init.  These include some slop as well as the default framebuffer.

When the framebuffer is a large size modern one, the sizes compiled in do not come close to matching what is requested of virtual_avail.  This means it is easy to be given a va which is past what is reserved for pre-init use.

A 5k display can easily be a stride of 8k with a 3k depth and 4 byte pixel.  An 8k display can easily be 8k x 5k x 4.  Just the 5k one is over twice the available reserved space in the default kernel.  My display, for example, needs 90 megabytes.  An 8k display needs 130 megabytes.

Meanwhile, the kernel, with slop included, only has 64MBytes allocated.

Additionally, the VT sizings are not up to par for large displays either.  These are fixed below too.

To make it usable, all of the below are related and need to be done.  The history change is a nice to have because it affects debugging of things that are printed (and 500 is just too small for a workable history).

TODO:  All of the pre-init allocation for architectures other than amd64 (done below) needs to be looked at for making a bounds check.  The constants for the sizing of the virtual_avail needs to be updated for architectures other than amd64 and arm64 (which are done below) to allow for modern framebuffers without hitting a pre init bounds.



All changes here are against 15.1p3



*** usr/src/sys/amd64/amd64/pmap.c	Mon Aug 31 19:29:19 2026
--- usr/src/sys/amd64/amd64/pmap.c.orig	Thu Aug 27 16:12:44 2026
***************
*** 1676,1695 ****
  	 * before vm_mem_init() and pmap_init(). 20MB for a frame buffer
  	 * is not uncommon.
  	 */
! 
! 	/*
! 	 * 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;
  }
--- 1676,1682 ----
  	 * before vm_mem_init() and pmap_init(). 20MB for a frame buffer
  	 * is not uncommon.
  	 */
! 	pt_pages += 32;		/* 64MB additional slop. */
  #endif
  	nkpt = pt_pages;
  }
***************
*** 9417,9437 ****
  	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;
--- 9404,9413 ----
***************
*** 9474,9490 ****
  		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));
  }
  
--- 9450,9460 ----




*** usr/src/sys/arm64/arm64/pmap.c	Mon Aug 31 19:29:35 2026
--- usr/src/sys/arm64/arm64/pmap.c.orig	Mon Aug 31 13:57:21 2026
***************
*** 303,309 ****
  struct pmap kernel_pmap_store;
  
  /* Used for mapping ACPI memory before VM is initialized */
! #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 */
--- 303,309 ----
  struct pmap kernel_pmap_store;
  
  /* Used for mapping ACPI memory before VM is initialized */
! #define	PMAP_PREINIT_MAPPING_COUNT	32
  #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 */




*** usr/src/sys/arm64/include/pte.h	Mon Aug 31 19:29:46 2026
--- usr/src/sys/arm64/include/pte.h.orig	Mon Aug 31 13:54:54 2026
***************
*** 211,221 ****
   * 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.
   */
! /*
!  * 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
--- 211,217 ----
   * 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)
  
  #if PAGE_SIZE == PAGE_SIZE_4K
  #define	L0_ENTRIES_SHIFT 9





*** usr/src/sys/dev/vt/hw/fb/vt_early_fb.c	Mon Aug 31 19:29:57 2026
--- usr/src/sys/dev/vt/hw/fb/vt_early_fb.c.orig	Thu Aug 20 19:02:25 2026
***************
*** 282,295 ****
  
  	/* 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);
--- 282,287 ----




*** usr/src/sys/dev/vt/vt.h	Tue Sep  1 16:31:04 2026
--- usr/src/sys/dev/vt/vt.h.orig	Thu Aug 20 19:00:13 2026
***************
*** 222,236 ****
  	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	5000
  #endif
  
  void vtbuf_lock(struct vt_buf *);
--- 222,231 ----
  	term_char_t		**vb_rows;	/* (u) Array of rows */
  };
  
  #ifdef SC_HISTORY_SIZE
  #define	VBF_DEFAULT_HISTORY_SIZE	SC_HISTORY_SIZE
  #else
! #define	VBF_DEFAULT_HISTORY_SIZE	500
  #endif
  
  void vtbuf_lock(struct vt_buf *);
***************
*** 418,432 ****
  #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 8192
  #endif
  #ifndef VT_FB_MAX_HEIGHT
! #define	VT_FB_MAX_HEIGHT 8192
  #endif
  
  /* name argument is not used yet. */
--- 413,423 ----
  #define	PIXEL_WIDTH(w)	((w) / 8)
  #define	PIXEL_HEIGHT(h)	((h) / 16)
  
  #ifndef VT_FB_MAX_WIDTH
! #define	VT_FB_MAX_WIDTH	4096
  #endif
  #ifndef VT_FB_MAX_HEIGHT
! #define	VT_FB_MAX_HEIGHT	2400
  #endif
  
  /* name argument is not used yet. */
Comment 1 Thomas Goldthorpe 2026-09-02 00:38:33 UTC
Ugh.... I put context diffs up that convert back to original rather than original to my currently running.

Here are orig (15.1p3) to current running.


*** usr/src/sys/amd64/amd64/pmap.c.orig	Thu Aug 27 16:12:44 2026
--- usr/src/sys/amd64/amd64/pmap.c	Mon Aug 31 19:29:19 2026
***************
*** 1676,1682 ****
  	 * before vm_mem_init() and pmap_init(). 20MB for a frame buffer
  	 * is not uncommon.
  	 */
! 	pt_pages += 32;		/* 64MB additional slop. */
  #endif
  	nkpt = pt_pages;
  }
--- 1676,1695 ----
  	 * before vm_mem_init() and pmap_init(). 20MB for a frame buffer
  	 * is not uncommon.
  	 */
! 
! 	/*
! 	 * 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,9413 ****
--- 9417,9437 ----
  	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,9460 ****
--- 9474,9490 ----
  		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));
  }
  




*** usr/src/sys/arm64/arm64/pmap.c.orig	Mon Aug 31 13:57:21 2026
--- usr/src/sys/arm64/arm64/pmap.c	Mon Aug 31 19:29:35 2026
***************
*** 303,309 ****
  struct pmap kernel_pmap_store;
  
  /* Used for mapping ACPI memory before VM is initialized */
! #define	PMAP_PREINIT_MAPPING_COUNT	32
  #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 */
--- 303,309 ----
  struct pmap kernel_pmap_store;
  
  /* Used for mapping ACPI memory before VM is initialized */
! #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 */




*** usr/src/sys/arm64/include/pte.h.orig	Mon Aug 31 13:54:54 2026
--- usr/src/sys/arm64/include/pte.h	Mon Aug 31 19:29:46 2026
***************
*** 211,217 ****
   * 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)
  
  #if PAGE_SIZE == PAGE_SIZE_4K
  #define	L0_ENTRIES_SHIFT 9
--- 211,221 ----
   * 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.
   */
! /*
!  * 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








*** usr/src/sys/dev/vt/hw/fb/vt_early_fb.c.orig	Thu Aug 20 19:02:25 2026
--- usr/src/sys/dev/vt/hw/fb/vt_early_fb.c	Mon Aug 31 19:29:57 2026
***************
*** 282,287 ****
--- 282,295 ----
  
  	/* 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);




*** usr/src/sys/dev/vt/vt.h.orig	Thu Aug 20 19:00:13 2026
--- usr/src/sys/dev/vt/vt.h	Tue Sep  1 16:31:04 2026
***************
*** 222,231 ****
  	term_char_t		**vb_rows;	/* (u) Array of rows */
  };
  
  #ifdef SC_HISTORY_SIZE
  #define	VBF_DEFAULT_HISTORY_SIZE	SC_HISTORY_SIZE
  #else
! #define	VBF_DEFAULT_HISTORY_SIZE	500
  #endif
  
  void vtbuf_lock(struct vt_buf *);
--- 222,236 ----
  	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	5000
  #endif
  
  void vtbuf_lock(struct vt_buf *);
***************
*** 413,423 ****
  #define	PIXEL_WIDTH(w)	((w) / 8)
  #define	PIXEL_HEIGHT(h)	((h) / 16)
  
  #ifndef VT_FB_MAX_WIDTH
! #define	VT_FB_MAX_WIDTH	4096
  #endif
  #ifndef VT_FB_MAX_HEIGHT
! #define	VT_FB_MAX_HEIGHT	2400
  #endif
  
  /* name argument is not used yet. */
--- 418,432 ----
  #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 8192
  #endif
  #ifndef VT_FB_MAX_HEIGHT
! #define	VT_FB_MAX_HEIGHT 8192
  #endif
  
  /* name argument is not used yet. */
Comment 2 Mark Linimon freebsd_committer freebsd_triage 2026-09-02 01:19:27 UTC
(In reply to Thomas Goldthorpe from comment #1)
We have deprecated context diffs in favor of git diffs.  Can you resubmit?

Also, we prefer patches to be rooted at the top of the tree, e.g. s@/usr/src@@ .
Comment 3 Thomas Goldthorpe 2026-09-02 17:21:06 UTC
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. */