git: kernel - Fix some rare pmap races in i386 and x86_64.
Matthew Dillon
dillon at crater.dragonflybsd.org
Sun Feb 21 18:36:16 PST 2010
commit c2fb025d4cd1fc6d547f7ae973ee7b227c83bf15
Author: Matthew Dillon <dillon at apollo.backplane.com>
Date: Sun Feb 21 18:23:13 2010 -0800
kernel - Fix some rare pmap races in i386 and x86_64.
* Adjust pmap_inval_init() to enter a critical section and add
a new pmap_inval_done() function which flushes and exits it.
It was possible for an interrupt or other preemptive action to
come along during a pmap operation and issue its own pmap operation,
potentially leading to races which corrupt the pmap.
This case was tested an could actually occur, though the damage (if any)
is unknown. x86_64 machines have had a long standing and difficult to
reproduce bug where a program would sometimes seg-fault for no reason.
It is unknown whether this fixes the bug or not.
* Interlock the pmap structure when invalidating pages using a bit
in the pm_active field.
Check for the interlock in swtch.s when switching into threads
and print a nice warning if it occurs.
It was possible for one cpu to initiate a pmap modifying operation
while another switches into a thread using the pmap the first cpu
was in the middle of modifying. The case is extremely rare but can
occur if the cpu doing the modifying operation receives a SMI
interrupt, stalling it long enough for the other cpu to switch
into the thread and resume running in userspace.
* pmap_protect() assumed no races when clearing PG_RW and PG_M due
to the pmap_inval operations it runs. This should in fact be
true with the above fixes. However, the rest of the pmap code
uses atomic operations so adjust pmap_protect() to also use atomic
operations.
Summary of changes:
sys/platform/pc32/i386/genassym.c | 5 ++
sys/platform/pc32/i386/globals.s | 3 +-
sys/platform/pc32/i386/pmap.c | 124 +++++++++++++++++++-------------
sys/platform/pc32/i386/pmap_inval.c | 37 +++++++++-
sys/platform/pc32/i386/swtch.s | 16 ++++-
sys/platform/pc32/include/pmap.h | 6 ++-
sys/platform/pc32/include/pmap_inval.h | 4 +-
sys/platform/pc64/include/pmap.h | 6 ++-
sys/platform/pc64/include/pmap_inval.h | 4 +-
sys/platform/pc64/x86_64/genassym.c | 5 ++
sys/platform/pc64/x86_64/global.s | 3 +-
sys/platform/pc64/x86_64/pmap.c | 124 ++++++++++++++++++++------------
sys/platform/pc64/x86_64/pmap_inval.c | 37 +++++++++-
sys/platform/pc64/x86_64/swtch.s | 15 +++-
sys/platform/vkernel/i386/genassym.c | 5 ++
sys/platform/vkernel/i386/global.s | 3 +-
sys/platform/vkernel/platform/pmap.c | 7 +-
17 files changed, 285 insertions(+), 119 deletions(-)
http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/c2fb025d4cd1fc6d547f7ae973ee7b227c83bf15
--
DragonFly BSD source repository
More information about the Commits
mailing list