PROTECTION

Each reference into the segment defined by a segment register is checked by the hardware to verify that it is within the defined limits of the segment and is of the proper type. For example, a code segment or read-only data segment cannot be written. All these checks are made before the memory cycle is started; any violation will prevent that cycle from starting and cause an exception to occur. Since the checks are performed concurrently with address formation, there is no performance penalty.

By controlling the access rights and privilege attributes of segments, the system designer can assure a program will not change its code or overwrite data belonging to another task. Such assurances are vital to maintaining system integrity in the face of error-prone programs.

7.2.1 Separation of Address Spaces

\

As described in Chapter 6, each task can address up to a gigabyte (214- 2 segments of up to 65,536 bytes each) of virtual memory defined by the task's LDT (Local Descriptor Table) and the system GDT. Up to one-half gigabyte (2 13 segments of up to 65,536 bytes each) of the task's address space is defined by the LDT and represents the task's private address space. The remaining virtual address space is defined by the GDT and is common to all tasks in the system.

Each descriptor table is itself a special kind of segment recognized by the 80286 architecture. These tables are defined by descriptors in the GDT (Global Descriptor Table). The CPU has a set of base and limit registers that point to the GDT and the LDT of the currently running task. The local descrip- tor table register is loaded by a task switch operation.

An active task can only load selectors that reference segments defined by descriptors in either the GDT or its private LDT. Since a task cannot reference descriptors in other LDTs, and no descriptors in its LDT refer to data or code belonging to other tasks, it cannot gain access to another tasks' private code and data (see figure 7-3).

Since the GDT contains information that is accessible by all users (e.g., library routines, common data, Operating System services, etc.), the 80286 uses privilege levels and special descriptor types to control access (see section 7.2.2). Privilege levels protect more trusted data and code (in GDT and LDT) from less trusted access (WITHIN a task), while the private virtual address spaces defined by unique LDTs provide protection BETWEEN tasks (see figure 7-4).

7.2.2 LOT and GOT Access Checks

All descriptor tables have a limit used by the protection hardware to ensure address space separation of tasks. Each task's LDT can be a different size as defined by its descriptor in the GDT. The GDT may also contain less than 8191 descriptors as defined by the GDT limit value. The descriptor table limit identifies the last valid byte of the last descriptor in that table. Since each descriptor is eight bytes long, the limit value is N X 8 -1 for N descriptors.

Any attempt by a program to load a segment register, local descriptor table register (LDTR), or task register (TR) with a selector that refers to a descriptor outside the corresponding limit causes an excep- tion with an error code identifying the invalid selector used (see figure 7-5).

Not all descriptor entries in the GDT or LDT need contain a valid descriptor. There can be holes, or "empty" descriptors, in the LDT and GDT. "Empty" descriptors allow dynamic allocation and deletion of segments or other system objects without changing the size of the GDT or LDT. Any descriptor with an access byte equal to zero is considered empty. Any attempt to load a segment register with a selector that refers to an empty descriptor will cause an exception with an error code identifying the invalid selection.

7-5

Page 131
Image 131
Intel 80286, 80287 manual Separation of Address Spaces, LOT and GOT Access Checks