a8f80ad4fd
was converted to use Mach VM for Net2/4.4BSD. The user segment table pointer was originally stored in the PCB. When Mach VM came along, however, it was also stored in the pmap, and loaded into the PCB in pmap_activate(). pmap_activate() would then note that the PCB's USTP was now in sync with the pmap's USTP, and the low-level context switch code would use the value from the PCB. However, pmap_activate() would also load the hardware MMU context if the pmap was the current pmap (or, in the case where pmaps can be shared, such as in NetBSD, if the proc was the current proc). The low-level context switch code would then reload the hardware _again_ using the USTP from the PCB. However, the optimization of not calling pmap_activate() if "stchanged" was false ended up causing some processes to use stale USTP values from the PCB when the low-level context switch code reloaded the hardware! This was noticed by using a real vfork(2) (which worked for some time before failing, surprisingly!) Since I'm hard pressed to find any real optimization here (since the hardware was always reloaded once, sometimes twice!), the code now always calls pmap_activate(), which uses the correct USTP value (the one in the pmap). The PCB's USTP is now ignored, and should eventually be g/c'd. Another optimization can actually be performed, and I have added a comment describing what it is, but have not yet implemented it. Also note that most of the loadustp() functions where actually incomplete. This has been corrected. These functions should probably be split up into MMU-specific operations, and called indirectly, rather than doing constant run-time decision making based on values that will never change during the course of a boot's lifetime. |
||
---|---|---|
bin | ||
distrib | ||
etc | ||
games | ||
gnu | ||
include | ||
lib | ||
libexec | ||
regress | ||
sbin | ||
share | ||
sys | ||
usr.bin | ||
usr.sbin | ||
Makefile |