Path: utzoo!utgpu!attcan!uunet!pyrdc!netsys!ames!think!barmar From: barmar@think.COM (Barry Margolin) Newsgroups: comp.arch Subject: Re: PEP: Page Execution Priviledge Keywords: access level, User/Supervisor. Message-ID: <28881@think.UUCP> Date: 29 Sep 88 17:55:08 GMT References: <2550@sultra.UUCP> Sender: news@think.UUCP Reply-To: barmar@kulla.think.com.UUCP (Barry Margolin) Organization: Thinking Machines Corporation, Cambridge, MA Lines: 45 What you described is a simplified version of the ring protection scheme used on Multics. On Multics, each memory segment has three ring numbers (integers from 0 to 7) associated with it, called its write ring, its read ring, and its execute ring. Additionally, each process has a current ring of execution. You can read a segment if your ring of execution is less than the segment's read ring, you can write it if it is less than the write ring, and you can execute it if you are between the write and execute rings. The read and execute rings are normally the same, but if the read ring is less than the execute ring then the segment is called a gate. If your ring of execution is between the read ring and the execute ring, and you use a subroutine call instruction to transfer into a gate, then a ring crossing occurs and your ring of execution is lowered to the read ring of the segment; the matching return instruction restores the ring of execution. Gates also have special protection that allows them to only be called at specified entrypoints, so that a caller can't transfer to the instruction after some access checks are performed. This works well with dynamic linking of subroutines. When a routine is dynamically linked, a shared memory segment is mapped onto the file containing the library, and the ring numbers of the segment are taken from its attributes in the file system (in fact, this is how ALL file access is done on Multics -- there are no kernel interfaces that do explicit file I/O, although there is a user-ring library that implements various file access methods using shared segments mapped onto files). All supervisor data is in segments whose ring numbers are [0, 0, 0] (this is [write, read, execute]), so that they can only be accessed while executing in ring 0. System calls are implemented by doing a subroutine call to a segment whose ring numbers are [0, 0, 5], i.e. a gate from ring 5 to 0, and most normal users run in ring 4. A number of privileged system operations that aren't actually part of the supervisor are in rings 2 and 3. There is still a need for a supervisor/user state in the processor, though. When you are in ring 0 you are in supervisor state, which allows execution of privileged instructions (such as performing I/O, or manipulating segment descriptor registers). Barry Margolin Thinking Machines Corp. barmar@think.com {uunet,harvard}!think!barmar