Commit d8117ce5 authored by Christoph Lameter's avatar Christoph Lameter Committed by Tony Luck

[IA64] Fix race in the accessed/dirty bit handlers

A pte may be zapped by the swapper, exiting process, unmapping or page
migration while the accessed or dirty bit handers are about to run. In that
case the accessed bit or dirty is set on an zeroed pte which leads the VM to
conclude that this is a swap pte. This may lead to

- Messages from the vm like

swap_free: Bad swap file entry 4000000000000000

- Processes being aborted

swap_dup: Bad swap file entry 4000000000000000
VM: killing process ....

Page migration is particular suitable for the creation of this race since
it needs to remove and restore page table entries.

The fix here is to check for the present bit and simply not update
the pte if the page is not present anymore. If the page is not present
then the fault handler should run next which will take care of the problem
by bringing the page back and then mark the page dirty or move it onto the
active list.
Signed-off-by: default avatarChristoph Lameter <clameter@sgi.com>
Signed-off-by: default avatarTony Luck <tony.luck@intel.com>
parent 2ec5e3a8
...@@ -561,11 +561,12 @@ ENTRY(dirty_bit) ...@@ -561,11 +561,12 @@ ENTRY(dirty_bit)
;; // avoid RAW on r18 ;; // avoid RAW on r18
mov ar.ccv=r18 // set compare value for cmpxchg mov ar.ccv=r18 // set compare value for cmpxchg
or r25=_PAGE_D|_PAGE_A,r18 // set the dirty and accessed bits or r25=_PAGE_D|_PAGE_A,r18 // set the dirty and accessed bits
tbit.z p7,p6 = r18,_PAGE_P_BIT // Check present bit
;; ;;
cmpxchg8.acq r26=[r17],r25,ar.ccv (p6) cmpxchg8.acq r26=[r17],r25,ar.ccv // Only update if page is present
mov r24=PAGE_SHIFT<<2 mov r24=PAGE_SHIFT<<2
;; ;;
cmp.eq p6,p7=r26,r18 (p6) cmp.eq p6,p7=r26,r18 // Only compare if page is present
;; ;;
(p6) itc.d r25 // install updated PTE (p6) itc.d r25 // install updated PTE
;; ;;
...@@ -626,11 +627,12 @@ ENTRY(iaccess_bit) ...@@ -626,11 +627,12 @@ ENTRY(iaccess_bit)
;; ;;
mov ar.ccv=r18 // set compare value for cmpxchg mov ar.ccv=r18 // set compare value for cmpxchg
or r25=_PAGE_A,r18 // set the accessed bit or r25=_PAGE_A,r18 // set the accessed bit
tbit.z p7,p6 = r18,_PAGE_P_BIT // Check present bit
;; ;;
cmpxchg8.acq r26=[r17],r25,ar.ccv (p6) cmpxchg8.acq r26=[r17],r25,ar.ccv // Only if page present
mov r24=PAGE_SHIFT<<2 mov r24=PAGE_SHIFT<<2
;; ;;
cmp.eq p6,p7=r26,r18 (p6) cmp.eq p6,p7=r26,r18 // Only if page present
;; ;;
(p6) itc.i r25 // install updated PTE (p6) itc.i r25 // install updated PTE
;; ;;
...@@ -680,11 +682,12 @@ ENTRY(daccess_bit) ...@@ -680,11 +682,12 @@ ENTRY(daccess_bit)
;; // avoid RAW on r18 ;; // avoid RAW on r18
mov ar.ccv=r18 // set compare value for cmpxchg mov ar.ccv=r18 // set compare value for cmpxchg
or r25=_PAGE_A,r18 // set the dirty bit or r25=_PAGE_A,r18 // set the dirty bit
tbit.z p7,p6 = r18,_PAGE_P_BIT // Check present bit
;; ;;
cmpxchg8.acq r26=[r17],r25,ar.ccv (p6) cmpxchg8.acq r26=[r17],r25,ar.ccv // Only if page is present
mov r24=PAGE_SHIFT<<2 mov r24=PAGE_SHIFT<<2
;; ;;
cmp.eq p6,p7=r26,r18 (p6) cmp.eq p6,p7=r26,r18 // Only if page is present
;; ;;
(p6) itc.d r25 // install updated PTE (p6) itc.d r25 // install updated PTE
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment