phys(2) under sVr3?

gwp at hcx3.SSD.HARRIS.COM gwp at hcx3.SSD.HARRIS.COM
Sat Jun 11 07:54:00 AEST 1988


From: Andrew Klossner <andrew at frip.gwd.tek.com>
> I need to augment sys V release 3 so as to let a user process map a
> video frame buffer into its address space.  Something like the version 7
> phys(2) call, or what the 4.2BSD mmap(2) call promised but didn't
> deliver, is what I'm looking for.

I went around and around with this problem and finally came up with
something called shmbind(2).  This system service takes an existing
shared memory region (created via shmget(2)) and binds a chunk of
physical memory to that region.  User processes may then attach this
chunk of physically-mapped virtual memory into their address space
with the shmat(2) service.

This sounds a bit complicated at first but I think it has several
advantages over phys(2), mmap(2) et. al.

The first is security/usability.  Allowing users direct access to
physical or I/O memory (for those architectures with memory mapped
I/O) is _extremely_ _dangerous_ (imagine Joe user mapping the device
controller registers for your root-partition disk into his address
space).  The usual solution to this is to make phys(2), mmap(2) etc.
super-user only, which then causes everyone to write their
applications suid-root thus voiding _all_ user protections.  By
binding a chunk of physical memory to a shared memory region you allow
access to that chunk to be controlled through the user-group-other
bits of the ipc_perm handle.  Of course shmbind(2) must be restricted
to super-user, but the objects it creates can be accessed by anyone
you wish.

Furthermore multiple processes can attach and detach the same chunk of
physical memory in an simple and straightforward manner without
creating multiple regions or sets of page tables.

The second advantage is one of consistency (at least for Sys V types).
There already exists a system service for adding a chunk of virtual
memory to a users address space.  That service is "shmat(2)".  Why
should there be another service that does pretty much the same thing,
except that the chunk of virtual memory is now associated with a
specific range of physical memory ?  Why not create a service that
performs this later operation, and then leave the rest to shmat(2) ?

The interface to shmbind(1) as I have written it is:

int shmbind(int shmid, caddr_t p_addr)

Shmid is the id returned from shmget(2) and p_addr is the starting
physical address of the chunk you wish to map. The size of the
physical chunk mapped is the size of the shared memory region you arre
mapping it into (the "size" argument to the shmget(2) call).  The
physical addresses can lie in either "normal" RAM-space or in I/O
memory space (our machines use memory-mapped I/O).  If the requested
physical memory lies in RAM-space the system will attempt to allocate
the appropriate pages at shmbind(2) time.  If the desired pages of
physical memory are already allocated the shmbind(2) service returns
the ENOMEM error.  Bind operations involving I/O memory are always
honored since I/O memory "pages" are not a critical resource (they're
really "ghost pages" consisting of page table entries pointing to I/O
locations).  It is possible to reserve sections of RAM-memory for
later binding by placing "reserve" entries in the config file and
rebuilding the kernel.

I've also have a utility called shmconfig(1) (with more options than
you probably care about) that performs the shmget(2), shmbind(2), and
shmctl(2) operations necessary to create a physically-bound shared
memory region with the desired user, group and permission bits.  This
utility is primarily for use in /etc/rc so that you can configure a
system with the desired "mappable objects" already present at init
time.

What do you think ?

        Gil Pilz -=|=- Harris Computer Systems -=|=- gwp at ssd.harris.com



More information about the Comp.unix.wizards mailing list