Subject: Re: /dev/vga and /dev/mem XFree problems with UVM
To: None <tls@rek.tjls.com>
From: Chuck Cranor <chuck@dworkin.wustl.edu>
List: port-i386
Date: 02/09/1998 19:12:11
>I'm having some trouble using XFree with UVM.
> 284 XF86_SVGA CALL open(0xaf26c,0x2,0xf9000000)
> 284 XF86_SVGA NAMI "/dev/mem"
> 284 XF86_SVGA RET open 4
> 284 XF86_SVGA CALL mmap(0,0x1000,0x3,0,0x4,0,0xa0000,0)
mmap(addr=0, len=0x1000, prot=0x3, flags=0 (!!),
fd=4, offset=whatever)
> 284 XF86_SVGA RET mmap -1 errno 22 Invalid argument
i'm not sure about the other one, but this one is easy i think.
does your kernel have COMPAT_13 defined?
the problem is that XFree86 likes to mmap /dev/mem with flags=MAP_FILE
(and MAP_FILE is defined to be zero, and thus is meaningless). the
single unix spec says you are supposed to specify either MAP_SHARED
or MAP_PRIVATE, else you can return an error:
[EINVAL]
The value of flags is invalid (neither MAP_PRIVATE nor
MAP_SHARED is set).
so UVM enforces that unless you define COMPAT_13. the semantics
of MAP_FILE seem to be:
#if defined(COMPAT_13)
if ((flags & (MAP_SHARED|MAP_PRIVATE|MAP_COPY)) == 0) {
#if defined(DIAGNOSTIC)
printf("WARNING: corrected bogus mmap (pid %d comm %s)\n", p->p_pid,
p->p_comm);
#endif
if (vp->v_type == VCHR)
flags |= MAP_SHARED; /* for a device */
else
flags |= MAP_PRIVATE; /* for a file */
}
#else
if ((flags & (MAP_SHARED|MAP_PRIVATE|MAP_COPY)) == 0)
return(EINVAL); /* sorry, old timer */
#endif
interestingly enough, on the sparc X tries to map the framebuffer
MAP_PRIVATE (which turns on copy-on-write .. and that doesn't make
a lot of sense for a framebuffer). so there is another hack
to handle that.
generally speaking, if you are going to mmap a device with uvm
use MAP_SHARED.
maybe someone could volunteer to see about fixing this in the XFree86
source?
chuck