aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel/ivt.S
diff options
context:
space:
mode:
authorChristoph Lameter <clameter@engr.sgi.com>2006-03-07 22:05:32 -0500
committerTony Luck <tony.luck@intel.com>2006-03-08 19:07:55 -0500
commitd8117ce5a679ff1f48df247da30fb62c16d562c5 (patch)
tree7b44619de328e773f2e8b41043343341e47a850e /arch/ia64/kernel/ivt.S
parent2ec5e3a867d63d04932e11c6097f63760d9be3fe (diff)
[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: Christoph Lameter <clameter@sgi.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64/kernel/ivt.S')
-rw-r--r--arch/ia64/kernel/ivt.S15
1 files changed, 9 insertions, 6 deletions
diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S
index 9f80569a32b0..dcd906fe5749 100644
--- a/arch/ia64/kernel/ivt.S
+++ b/arch/ia64/kernel/ivt.S
@@ -561,11 +561,12 @@ ENTRY(dirty_bit)
561 ;; // avoid RAW on r18 561 ;; // avoid RAW on r18
562 mov ar.ccv=r18 // set compare value for cmpxchg 562 mov ar.ccv=r18 // set compare value for cmpxchg
563 or r25=_PAGE_D|_PAGE_A,r18 // set the dirty and accessed bits 563 or r25=_PAGE_D|_PAGE_A,r18 // set the dirty and accessed bits
564 tbit.z p7,p6 = r18,_PAGE_P_BIT // Check present bit
564 ;; 565 ;;
565 cmpxchg8.acq r26=[r17],r25,ar.ccv 566(p6) cmpxchg8.acq r26=[r17],r25,ar.ccv // Only update if page is present
566 mov r24=PAGE_SHIFT<<2 567 mov r24=PAGE_SHIFT<<2
567 ;; 568 ;;
568 cmp.eq p6,p7=r26,r18 569(p6) cmp.eq p6,p7=r26,r18 // Only compare if page is present
569 ;; 570 ;;
570(p6) itc.d r25 // install updated PTE 571(p6) itc.d r25 // install updated PTE
571 ;; 572 ;;
@@ -626,11 +627,12 @@ ENTRY(iaccess_bit)
626 ;; 627 ;;
627 mov ar.ccv=r18 // set compare value for cmpxchg 628 mov ar.ccv=r18 // set compare value for cmpxchg
628 or r25=_PAGE_A,r18 // set the accessed bit 629 or r25=_PAGE_A,r18 // set the accessed bit
630 tbit.z p7,p6 = r18,_PAGE_P_BIT // Check present bit
629 ;; 631 ;;
630 cmpxchg8.acq r26=[r17],r25,ar.ccv 632(p6) cmpxchg8.acq r26=[r17],r25,ar.ccv // Only if page present
631 mov r24=PAGE_SHIFT<<2 633 mov r24=PAGE_SHIFT<<2
632 ;; 634 ;;
633 cmp.eq p6,p7=r26,r18 635(p6) cmp.eq p6,p7=r26,r18 // Only if page present
634 ;; 636 ;;
635(p6) itc.i r25 // install updated PTE 637(p6) itc.i r25 // install updated PTE
636 ;; 638 ;;
@@ -680,11 +682,12 @@ ENTRY(daccess_bit)
680 ;; // avoid RAW on r18 682 ;; // avoid RAW on r18
681 mov ar.ccv=r18 // set compare value for cmpxchg 683 mov ar.ccv=r18 // set compare value for cmpxchg
682 or r25=_PAGE_A,r18 // set the dirty bit 684 or r25=_PAGE_A,r18 // set the dirty bit
685 tbit.z p7,p6 = r18,_PAGE_P_BIT // Check present bit
683 ;; 686 ;;
684 cmpxchg8.acq r26=[r17],r25,ar.ccv 687(p6) cmpxchg8.acq r26=[r17],r25,ar.ccv // Only if page is present
685 mov r24=PAGE_SHIFT<<2 688 mov r24=PAGE_SHIFT<<2
686 ;; 689 ;;
687 cmp.eq p6,p7=r26,r18 690(p6) cmp.eq p6,p7=r26,r18 // Only if page is present
688 ;; 691 ;;
689(p6) itc.d r25 // install updated PTE 692(p6) itc.d r25 // install updated PTE
690 /* 693 /*