diff options
Diffstat (limited to 'arch/ia64/mm')
-rw-r--r-- | arch/ia64/mm/tlb.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c index cef164729db7..655da240d13c 100644 --- a/arch/ia64/mm/tlb.c +++ b/arch/ia64/mm/tlb.c | |||
@@ -10,6 +10,7 @@ | |||
10 | * IPI based ptc implementation and A-step IPI implementation. | 10 | * IPI based ptc implementation and A-step IPI implementation. |
11 | * Rohit Seth <rohit.seth@intel.com> | 11 | * Rohit Seth <rohit.seth@intel.com> |
12 | * Ken Chen <kenneth.w.chen@intel.com> | 12 | * Ken Chen <kenneth.w.chen@intel.com> |
13 | * Christophe de Dinechin <ddd@hp.com>: Avoid ptc.e on memory allocation | ||
13 | */ | 14 | */ |
14 | #include <linux/module.h> | 15 | #include <linux/module.h> |
15 | #include <linux/init.h> | 16 | #include <linux/init.h> |
@@ -89,9 +90,16 @@ ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start, | |||
89 | { | 90 | { |
90 | static DEFINE_SPINLOCK(ptcg_lock); | 91 | static DEFINE_SPINLOCK(ptcg_lock); |
91 | 92 | ||
92 | if (mm != current->active_mm || !current->mm) { | 93 | struct mm_struct *active_mm = current->active_mm; |
93 | flush_tlb_all(); | 94 | |
94 | return; | 95 | if (mm != active_mm) { |
96 | /* Restore region IDs for mm */ | ||
97 | if (mm && active_mm) { | ||
98 | activate_context(mm); | ||
99 | } else { | ||
100 | flush_tlb_all(); | ||
101 | return; | ||
102 | } | ||
95 | } | 103 | } |
96 | 104 | ||
97 | /* HW requires global serialization of ptc.ga. */ | 105 | /* HW requires global serialization of ptc.ga. */ |
@@ -107,6 +115,10 @@ ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start, | |||
107 | } while (start < end); | 115 | } while (start < end); |
108 | } | 116 | } |
109 | spin_unlock(&ptcg_lock); | 117 | spin_unlock(&ptcg_lock); |
118 | |||
119 | if (mm != active_mm) { | ||
120 | activate_context(active_mm); | ||
121 | } | ||
110 | } | 122 | } |
111 | 123 | ||
112 | void | 124 | void |