Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 31 Oct 2000 06:07:58 -0800 (PST)
From:      carp@world.std.com
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   i386/22441: pmap_growkernel() is not effective at kernel vm limit of 0xffc00000
Message-ID:  <20001031140758.4943437B4C5@hub.freebsd.org>

index | next in thread | raw e-mail


>Number:         22441
>Category:       i386
>Synopsis:       pmap_growkernel() is not effective at kernel vm limit of 0xffc00000
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Oct 31 06:10:01 PST 2000
>Closed-Date:
>Last-Modified:
>Originator:     Bill Carpenter
>Release:        FreeBSD 4.1.1-RELEASE
>Organization:
>Environment:
FreeBSD buffoon.eng.infolibria.com 4.1.1-RELEASE FreeBSD 
4.1.1-RELEASE #0: Tue Sep 26 00:46:59 GMT 2000     
jkh@narf.osd.bsdi.com:/usr/src/sys/compile/GENERIC  i386
>Description:
When called with a kernel vm limit of 0xffc00000, pamp_growkernel()
does not set-up the page mapping hardware because of an overflow.

In this line:

  addr = (addr + PAGE_SIZE * NPTEPG) & ~(PAGE_SIZE * NPTEPG - 1);
  ( Line 1403 in $FreeBSD: src/sys/i386/i386/pmap.c,v 1.250.2.5 2000/08/05 00:39:08 peter Exp $)

addr + PAGE_SIZE * NPTEPG overflows to zero when addr is 0xffc00000.

When addr is zero, the conditional in the following while loop is
never satisfied and the hardware page mapping data structures are
never initialized to cover the extended kernel vm.

I would also like to suggest that test of kernel_vm_end in 
vm_map_findspace() (src/sys/vm/vm_map.c) is a minor software 
layering violation.  kernel_vm_end is properly a pmap layer variable
and the test against kernel_vm_end should occur in pmap_growkernel().
I realize that making this change might appear to impede performance, 
but pmap_growkernel() only gets called during kernel initialization 
when the kernel is setting up sub-maps of the kernel map. (kernel_map)
>How-To-Repeat:

I am writing a driver that creates kernel vm up against the limit
of kernel vm and therefore requests that the kernel vm grow to 
0xffc00000.  I could submit a sample of the driver, but paper and
pencil should convince the reader that when PAGE_SIZE is 4096 and 
NPTEPG is 1024, 0xffc00000 + (4096 * 1024) overflows to zero.


>Fix:
In line 1403, I used a standard rounding macro and all appears well.

For instance, I have compiled and tested the kernel with:

  addr = roundup(addr, (PAGE_SIZE*NPTEPG));

Now that I got all of this typed, it appears that the kernel
is being extended an extra 4Mbytes whenever the limit submitted
to pmap_growkernel() falls on a 4Mbyte (i386 page directory) boundary.
The kernel, correctly, rounds up its vm limit to the next page and in 
most cases, the boundary submitted to pmap_growkernel() falls on
a page boundary.

>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message



home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20001031140758.4943437B4C5>