Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 12 Jan 2001 15:52:09 +1100 (EST)
From:      Bruce Evans <bde@zeta.org.au>
To:        Jeff Roberson <jeff@midstream.com>
Cc:        "'freebsd-current@freebsd.org'" <freebsd-current@FreeBSD.ORG>
Subject:   Re: Broken mmap in current?
Message-ID:  <Pine.BSF.4.21.0101121448170.2302-100000@besplex.bde.org>
In-Reply-To: <31E4B6337A4FD411BD45000102472E0C05E729@EMAIL_SERVER>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, 11 Jan 2001, Jeff Roberson wrote:

> I have written a character device driver for a proprietary PCI device that
> has a large sum of mapable memory.  The character device supports mmap()
> which I use to export the memory into a user process.  I have no problems
> accessing the memory on this device, but I notice that my mmap routine is
> called for every access!  Is this a problem with current, or a problem with
> my mmap?

Maybe both.  The device mmap routine is called mainly by the mmap
syscall for every page to be mmapped.  It is also called by
dev_pager_getpages() for some pagefaults, but I think this rarely happens.

> I use bus_alloc_resource and then rman_get_start to get the physical address
> in my attach, and then the mmap just returns atop(physical address).  I
> assumed this is correct since I have verified with a logical analyzer that I
> am indeed writing to the memory on the device.

This is correct.  I looked at some examples.  Many drivers get this
wrong by using i386_btop(), alpha_btop(), etc.  (AFAIK, atop() is
for addresses which are what we are converting here, btop() is for
(byte) offsets, and the machine-dependent prefixes are a vestige of
page clustering code that mostly went away 7 years ago.

> Also, I noticed that the
> device's mmap interface does not provide any way to limit the size of the
> block being mapped?  Can I specify the length of the region?

The length is implicitly PAGE_SIZE.  The device mmap function is called
for each page to be mapped.  It must verify that the memory from offset
to (offset + PAGE_SIZE - 1) belongs to the device and can be accessed
with the given protection, and do any device-specific things necessary to
enable this memory.  This scheme can't support bank-switched device
memory very well, if at all.

pcvvt_mmap() in the pcvt driver is the simplest example of this.
agp_mmap() is a more up to date example with the same old bug that the
vga drivers used to have (off by 1 (page) error checking the offset).

Bruce



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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.21.0101121448170.2302-100000>