Re: UIO: mapping UIO_MEM_LOGICAL fails for size < PAGE_SIZE

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Oct 31, 2008 at 05:29:25PM +0100, Christoph Gysin wrote:

Hi Christoph,

> I'm playing around with UIO, and got problems getting the following to work:
> 
> dev_info.mem[0].memtype = UIO_MEM_LOGICAL;
> dev_info.mem[0].addr = (unsigned long) kmalloc(16, GFP_KERNEL);
> dev_info.mem[0].size = 16;
> 
> If I increase size to PAGE_SIZE, everything works as expected.
> 
> Is this a bug or just not documented? Does size have to be a multiple
> of PAGE_SIZE?

No, you can pick any size you like. You run into the following problem:

If you kmalloc 16 bytes, kmalloc might return an address that is
somewhere in the middle of a page. But the mmap mechanism works for full
pages only, so any address returned by mmap() in userspace will be on a
page boundary. To get a pointer to your 16 bytes, you need to add an
offset to the pointer returned by mmap().

To address this problem, we recently added a sysfs file called "offset",
that gives you exactly the value you need to add. If you use a recent
kernel (2.6.28-rcX), you'll find that file under
/sys/class/uio/uioX/memY/.

As a workaround (if you need to use an older kernel), you can look at
the sysfs file "addr" in the same directory. It contains the value you
got from kmalloc. The lower bits of this addr are the offset you need.
You could calculate it like this:

offset = addr & (getpagesize() - 1);

Add this offset to the pointer returned by mmap(), and you should be
able to access your 16 bytes buffer.

Thanks for asking, certainly others had (or will have) the same problem.

HTH,
Hans


--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux