must retrieve the program counter, fetch the instruction, and parse it
in software to figure out what it was doing when the fault hit.
4. Once the virtual address that caused the fault is known, the system
checks to see if this address is valid and the protection is consistent
with the access.
If not, the process is sent a signal or killed.
If the ad-
dress is valid and no protection fault has occurred, the system checks
to see if a page frame is free.
If no frames are free, the page re-
placement algorithm is run to select a victim.
If the page frame selected is dirty, the page is scheduled for transfer to
the disk, and a context switch takes place, suspending the faulting
process and letting another one run until the disk transfer has com-
pleted. In any event, the frame is marked as busy to prevent it from
being used for another purpose.
As soon as the page frame is clean (either immediately or after it is
written to disk), the operating system looks up the disk address where
the needed page is, and schedules a disk operation to bring it in.
While the page is being loaded, the faulting process is still suspended
and another user process is run, if one is available.
When the disk interrupt indicates that the page has arrived, the page
tables are updated to reflect its position, and the frame is marked as
being in the normal state.
The faulting instruction is backed up to the state it had when it began
and the program counter is reset to point to that instruction.
The faulting process is scheduled, and the operating system returns to
the (assembly-language) routine that called it.
This routine reloads the registers and other state information and re-
turns to user space to continue execution, as if no fault had occurred.
3.6.3 Instruction Backup
When a program references a page that is not in memory, the instruction caus-
ing the fault is stopped partway through and a trap to the operating system occurs.
After the operating system has fetched the page needed, it must restart the instruc-
tion causing the trap. This is easier said than done.
To see the nature of this problem at its worst, consider a CPU that has instruc-
tions with two addresses, such as the Motorola 680x0, widely used in embedded
systems. The instruction
is 6 bytes, for example (see Fig. 3-27). In order to restart the instruction, the oper-
ating system must determine where the first byte of the instruction is. The value of
the program counter at the time of the trap depends on which operand faulted and
how the CPU’s microcode has been implemented.
MOVE.L #6(A1), 2(A0)
An instruction causing a page fault.
In Fig. 3-27, we have an instruction starting at address 1000 that makes three
memory references: the instruction word and two offsets for the operands. Depend-
ing on which of these three memory references caused the page fault, the program
counter might be 1000, 1002, or 1004 at the time of the fault. It is frequently im-
possible for the operating system to determine unambiguously where the instruc-
tion began. If the program counter is 1002 at the time of the fault, the operating
system has no way of telling whether the word in 1002 is a memory address asso-
ciated with an instruction at 1000 (e.g., the address of an operand) or an opcode.
Bad as this problem may be, it could have been worse. Some 680x0 addressing
modes use autoincrementing, which means that a side effect of executing the in-
struction is to increment one (or more) registers. Instructions that use autoincre-
ment mode can also fault. Depending on the details of the microcode, the incre-
ment may be done before the memory reference, in which case the operating sys-
tem must decrement the register in software before restarting the instruction.
the autoincrement may be done after the memory reference, in which case it will
not have been done at the time of the trap and must not be undone by the operating
system. Autodecrement mode also exists and causes a similar problem.
cise details of whether autoincrements and autodecrements have or have not been
done before the corresponding memory references may differ from instruction to
instruction and from CPU model to CPU model.
Fortunately, on some machines the CPU designers provide a solution, usually
in the form of a hidden internal register into which the program counter is copied
just before each instruction is executed. These machines may also have a second
register telling which registers have already been autoincremented or autodecre-
mented, and by how much. Given this information, the operating system can unam-
biguously undo all the effects of the faulting instruction so that it can be restarted.
If this information is not available, the operating system has to jump through hoops
to figure out what happened and how to repair it.
It is as though the hardware de-
signers were unable to solve the problem, so they threw up their hands and told the
operating system writers to deal with it. Nice guys.