git: kernel - Fix some rare pmap races in i386 and x86_64.

Matthew Dillon dillon at
Sun Feb 21 18:36:16 PST 2010

commit c2fb025d4cd1fc6d547f7ae973ee7b227c83bf15
Author: Matthew Dillon <dillon at>
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

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(-)

DragonFly BSD source repository

More information about the Commits mailing list