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