diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /arch/x86/include/asm/pgtable-3level.h | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'arch/x86/include/asm/pgtable-3level.h')
-rw-r--r-- | arch/x86/include/asm/pgtable-3level.h | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/arch/x86/include/asm/pgtable-3level.h b/arch/x86/include/asm/pgtable-3level.h index 177b0165ea01..effff47a3c82 100644 --- a/arch/x86/include/asm/pgtable-3level.h +++ b/arch/x86/include/asm/pgtable-3level.h | |||
@@ -69,8 +69,6 @@ static inline void native_pmd_clear(pmd_t *pmd) | |||
69 | 69 | ||
70 | static inline void pud_clear(pud_t *pudp) | 70 | static inline void pud_clear(pud_t *pudp) |
71 | { | 71 | { |
72 | unsigned long pgd; | ||
73 | |||
74 | set_pud(pudp, __pud(0)); | 72 | set_pud(pudp, __pud(0)); |
75 | 73 | ||
76 | /* | 74 | /* |
@@ -79,13 +77,10 @@ static inline void pud_clear(pud_t *pudp) | |||
79 | * section 8.1: in PAE mode we explicitly have to flush the | 77 | * section 8.1: in PAE mode we explicitly have to flush the |
80 | * TLB via cr3 if the top-level pgd is changed... | 78 | * TLB via cr3 if the top-level pgd is changed... |
81 | * | 79 | * |
82 | * Make sure the pud entry we're updating is within the | 80 | * Currently all places where pud_clear() is called either have |
83 | * current pgd to avoid unnecessary TLB flushes. | 81 | * flush_tlb_mm() followed or don't need TLB flush (x86_64 code or |
82 | * pud_clear_bad()), so we don't need TLB flush here. | ||
84 | */ | 83 | */ |
85 | pgd = read_cr3(); | ||
86 | if (__pa(pudp) >= pgd && __pa(pudp) < | ||
87 | (pgd + sizeof(pgd_t)*PTRS_PER_PGD)) | ||
88 | write_cr3(pgd); | ||
89 | } | 84 | } |
90 | 85 | ||
91 | #ifdef CONFIG_SMP | 86 | #ifdef CONFIG_SMP |
@@ -104,6 +99,29 @@ static inline pte_t native_ptep_get_and_clear(pte_t *ptep) | |||
104 | #define native_ptep_get_and_clear(xp) native_local_ptep_get_and_clear(xp) | 99 | #define native_ptep_get_and_clear(xp) native_local_ptep_get_and_clear(xp) |
105 | #endif | 100 | #endif |
106 | 101 | ||
102 | #ifdef CONFIG_SMP | ||
103 | union split_pmd { | ||
104 | struct { | ||
105 | u32 pmd_low; | ||
106 | u32 pmd_high; | ||
107 | }; | ||
108 | pmd_t pmd; | ||
109 | }; | ||
110 | static inline pmd_t native_pmdp_get_and_clear(pmd_t *pmdp) | ||
111 | { | ||
112 | union split_pmd res, *orig = (union split_pmd *)pmdp; | ||
113 | |||
114 | /* xchg acts as a barrier before setting of the high bits */ | ||
115 | res.pmd_low = xchg(&orig->pmd_low, 0); | ||
116 | res.pmd_high = orig->pmd_high; | ||
117 | orig->pmd_high = 0; | ||
118 | |||
119 | return res.pmd; | ||
120 | } | ||
121 | #else | ||
122 | #define native_pmdp_get_and_clear(xp) native_local_pmdp_get_and_clear(xp) | ||
123 | #endif | ||
124 | |||
107 | /* | 125 | /* |
108 | * Bits 0, 6 and 7 are taken in the low part of the pte, | 126 | * Bits 0, 6 and 7 are taken in the low part of the pte, |
109 | * put the 32 bits of offset into the high part. | 127 | * put the 32 bits of offset into the high part. |