Re: Having problem with mmap system call!!!

From: Richard B. Johnson
Date: Thu Sep 16 2004 - 13:27:28 EST


On Thu, 16 Sep 2004, Alan Cox wrote:

> On Iau, 2004-09-16 at 15:54, Richard B. Johnson wrote:
> > > SHM_FAIL is the wrong error check btw.
> > >
> >
> > MAP_FAILED only appeared in real late 'C' runtime library headers.
> > That's why the code defines SHM_FAIL, which is also correct, but
> > doesn't cause a redefinition error.
>
> SuS doesn't permit the use of SHM_FAIL. And you don't get redefinition
> errors if you use ds
>
> > Well that's really nice. Now, how do you do that? The kernel DS
> > is not the user DS so you end up with a kernel hack instead of
> > a user hack?
>
> Who cares about DS ? the user space page tables get mapped, its how all
> mmap functions work. A simple example is the sound drivers (2.4
> drivers/sound) which kmalloc a buffer of kernel space then make it
> mappable to the user
>

Alan,
Here is some code from a video driver.

static int vino_mmap(struct file *file, struct vm_area_struct *vma)
{
struct video_device *dev = video_devdata(file);
struct vino_device *v = dev->priv;
unsigned long start = vma->vm_start;
unsigned long size = vma->vm_end - vma->vm_start;
int i, err = 0;

if (down_interruptible(&v->sem))
return -EINTR;
if (size > v->page_count * PAGE_SIZE) {
err = -EINVAL;
goto out;
}
for (i = 0; i < v->page_count; i++) {
unsigned long page = virt_to_phys((void *)v->desc[i]);
if (remap_page_range(start, page, PAGE_SIZE, PAGE_READONLY)) {
err = -EAGAIN;
goto out;
}
start += PAGE_SIZE;
if (size <= PAGE_SIZE) break;
size -= PAGE_SIZE;
}
out:
up(&v->sem);
return err;

}

I deliberately used this as a sample so you can't say what
you usually say... Anyway are you aware that ...

unsigned long size = vma->vm_end - vma->vm_start;

... ends up being 32 bytes longer than the length the user-mode
code put into mmap()?

That's why I use a driver ioctl() to return the physical address
and the length so user-mode code can mmap() without the hassle
of "optimizations" (read kernel bugs) mucking with buffers,
especially those then end up overlapping because of bugs like
above.

Now, if somebody is having trouble with mmap(), it is quite
a bit better I believe, to reduce the basic user-mode mem-mapping
to its lowest common denominator. Therefore, I showed what was
guaranteed to work.

Cheers,
Dick Johnson
Penguin : Linux version 2.4.26 on an i686 machine (5570.56 BogoMips).
Note 96.31% of all statistics are fiction.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/