summaryrefslogtreecommitdiff
blob: b7cf4fadbcc5b8eb76728ee6994c089abcbb6599 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# HG changeset 265+266 patch
# User Keir Fraser <keir@xensource.com>
# Date 1192720728 -3600
# Node ID 7837d0ec57bce4578c17018ca1ef1ded64fe1dd3
# Parent  3116d92146522ae5989b40e1915d0baf6daa1008
Subject: Fix ptep_get_and_clear() on init_mm pte that is not mapped into
current address space.
Signed-off-by: Keir Fraser <keir@xensource.com>

Fix ptep_get_and_clear(): atomic operation required on user ptes to
get correct snapshot of A/D bits.

Signed-off-by: Keir Fraser <keir@xensource.com>

Acked-by: jbeulich@novell.com

Index: 10.3-2007-10-22/include/asm-i386/mach-xen/asm/pgtable-2level.h
===================================================================
--- 10.3-2007-10-22.orig/include/asm-i386/mach-xen/asm/pgtable-2level.h	2007-10-22 13:48:12.000000000 +0200
+++ 10.3-2007-10-22/include/asm-i386/mach-xen/asm/pgtable-2level.h	2007-10-22 13:52:04.000000000 +0200
@@ -42,10 +42,9 @@ static inline pte_t ptep_get_and_clear(s
 {
 	pte_t pte = *ptep;
 	if (!pte_none(pte)) {
-		if (mm != &init_mm)
+		if ((mm != &init_mm) ||
+		    HYPERVISOR_update_va_mapping(addr, __pte(0), 0))
 			pte = __pte_ma(xchg(&ptep->pte_low, 0));
-		else
-			HYPERVISOR_update_va_mapping(addr, __pte(0), 0);
 	}
 	return pte;
 }
Index: 10.3-2007-10-22/include/asm-i386/mach-xen/asm/pgtable-3level.h
===================================================================
--- 10.3-2007-10-22.orig/include/asm-i386/mach-xen/asm/pgtable-3level.h	2007-10-22 13:48:12.000000000 +0200
+++ 10.3-2007-10-22/include/asm-i386/mach-xen/asm/pgtable-3level.h	2007-10-22 13:52:04.000000000 +0200
@@ -125,7 +125,8 @@ static inline pte_t ptep_get_and_clear(s
 {
 	pte_t pte = *ptep;
 	if (!pte_none(pte)) {
-		if (mm != &init_mm) {
+		if ((mm != &init_mm) ||
+		    HYPERVISOR_update_va_mapping(addr, __pte(0), 0)) {
 			uint64_t val = pte_val_ma(pte);
 			if (__cmpxchg64(ptep, val, 0) != val) {
 				/* xchg acts as a barrier before the setting of the high bits */
@@ -133,8 +134,7 @@ static inline pte_t ptep_get_and_clear(s
 				pte.pte_high = ptep->pte_high;
 				ptep->pte_high = 0;
 			}
-		} else
-			HYPERVISOR_update_va_mapping(addr, __pte(0), 0);
+		}
 	}
 	return pte;
 }
Index: 10.3-2007-10-22/include/asm-x86_64/mach-xen/asm/pgtable.h
===================================================================
--- 10.3-2007-10-22.orig/include/asm-x86_64/mach-xen/asm/pgtable.h	2007-10-22 13:48:12.000000000 +0200
+++ 10.3-2007-10-22/include/asm-x86_64/mach-xen/asm/pgtable.h	2007-10-22 13:52:04.000000000 +0200
@@ -282,10 +282,9 @@ static inline pte_t ptep_get_and_clear(s
 {
 	pte_t pte = *ptep;
 	if (!pte_none(pte)) {
-		if (mm != &init_mm)
+		if ((mm != &init_mm) ||
+		    HYPERVISOR_update_va_mapping(addr, __pte(0), 0))
 			pte = __pte_ma(xchg(&ptep->pte, 0));
-		else
-			HYPERVISOR_update_va_mapping(addr, __pte(0), 0);
 	}
 	return pte;
 }