Path: utzoo!attcan!uunet!lll-winken!lll-lcc!ames!umd5!uflorida!novavax!hcx1!hcx3!gwp From: gwp@hcx3.SSD.HARRIS.COM Newsgroups: comp.unix.wizards Subject: Re: phys(2) under sVr3? Message-ID: <48300009@hcx3> Date: 10 Jun 88 21:54:00 GMT References: <16090@brl-adm.ARPA> Lines: 72 Nf-ID: #R:brl-adm.ARPA:16090:hcx3:48300009:000:3760 Nf-From: hcx3.SSD.HARRIS.COM!gwp Jun 10 17:54:00 1988 From: Andrew Klossner > 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@ssd.harris.com