[PATCH] (validated against 50k+ i686 machines) for vmparam.h and vesa.c

From: Mahmoud Al-Qudsi <mqudsi_at_neosmart.net>
Date: Tue, 30 Jan 2018 14:27:51 -0600
Hello list,

NeoSmart Technologies has been using these patches to address issues in
production for live CDs that are used by end users on their own (generic)
hardware. We've validated the patches against well over 50k i686 machines,
(not fleet machines, each is more or less unique/random), running a patched
10.x kernel over many years (you can see the original date in the attached
patches).

The first (and perhaps more important) addresses a common bug on x86 hardware,
which results in the following error message combined with a panic at boot
time:

> Too many segments in the physical address map, giving up

The second addresses bug kern/162373 which causes the framebuffer
initialization to fail on certain graphics cards (AMD models seem particularly
affected) with EINVAL, caused by incorrect range checks (which are actually
prefaced with a "XXX: is this correct?" comment in the original source).

We have our own framebuffer-based Xorg display driver (xf86-video-scfb, see
[0]), so it was particularly important for us to have the framebuffer working
correctly. I know some (extensive) changes have been made to the framebuffer
with FreeBSD 11, so I'm not sure if the patch applies to code still in use or
not; I have not taken the time to check under 12-CURRENT.

[0]: https://github.com/neosmart/xf86-video-scfb

Thanks,

Mahmoud Al-Qudsi
NeoSmart Technologies

Patches follow.

------------------------------------------------------------------------------
>From 5829531f379d14939a4ec78e0d6647558cf4aa26 Mon Sep 17 00:00:00 2001
From: Mahmoud Al-Qudsi <mqudsi_at_neosmart.net>
Date: Thu, 17 Apr 2014 14:09:59 -0500
Subject: [PATCH] Increased VM_PHSYSSEG_MAX on i386

Trying to fix an error "Too many segments in the physical address
map, giving up" on boot that is seen on certain hardware
configurations when booting the i386 GENERIC kernel.

Previously attempted to work around this by setting hw.physmem to 3G,
but that only resulted in a kernel segfault instead of the too many
segments error.

Using VM_PHYSSEG_MAX set to 31, as taken from the AMD64 configuration,
initial testing seems to indicate this is OK for use on i386 as well.
---
 sys/i386/include/vmparam.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/i386/include/vmparam.h b/sys/i386/include/vmparam.h
index 19cdd8e115eff..48e41a321d39b 100644
--- a/sys/i386/include/vmparam.h
+++ b/sys/i386/include/vmparam.h
_at__at_ -74,7 +74,7 _at__at_
  * largest physical address that is accessible by ISA DMA is split
  * into two PHYSSEG entries.
  */
-#define VM_PHYSSEG_MAX 17
+#define VM_PHYSSEG_MAX 31

 /*
  * Create two free page pools.  Since the i386 kernel virtual address
------------------------------------------------------------------------------


------------------------------------------------------------------------------
>From b3af2d1ed4a63fe1a5d771ed3a052242250098d7 Mon Sep 17 00:00:00 2001
From: Mahmoud Al-Qudsi <mqudsi_at_neosmart.net>
Date: Thu, 17 Apr 2014 12:17:44 -0500
Subject: [PATCH] Fixed incorrect range checks in mmap of framebuffer
 (kern/162373)

Implemented a fix for incorrect/invalid range checks in the vesa
framebuffer when attempting to mmap the framebuffer device. As
described in kern/162373, the original code contains a bug and will
incorrectly refuse to mmap at certain modes/resolutions because it
thinks the mmap length is out-of-range when it isn't.

Testing indicates that the revised framebuffer range check (mmap
offset is less than the window buffer size instead of the old check
that the offset is less than the window size minuse pagesize, which
really makes no sense) is the correct way to go.
---
 sys/dev/fb/vesa.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/dev/fb/vesa.c b/sys/dev/fb/vesa.c
index 48067b6401fe6..c67b8f24e0d71 100644
--- a/sys/dev/fb/vesa.c
+++ b/sys/dev/fb/vesa.c
_at__at_ -1631,7 +1631,7 _at__at_ vesa_mmap(video_adapter_t *adp, vm_ooffset_t
offset, vm_paddr_t *paddr,
(adp->va_info.vi_flags & V_INFO_LINEAR) != 0) {
/* va_window_size == va_buffer_size/vi_planes */
/* XXX: is this correct? */
- if (offset > adp->va_window_size - PAGE_SIZE)
+ if (offset >= adp->va_info.vi_buffer_size)
return (-1);
*paddr = adp->va_info.vi_buffer + offset;
return (0);
------------------------------------------------------------------------------
Received on Tue Jan 30 2018 - 19:28:13 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:41:14 UTC