aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/smp.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2006-03-28 16:29:26 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-04-01 02:03:34 -0500
commit6f25f3986af0353b0bdc220f79b89c997d0ceda4 (patch)
tree2c5dc949eff3cc3c216432d2034e159b579a6da9 /arch/sparc64/kernel/smp.c
parent683aa4012f53b2ada0f430487e05d37b0d94e90a (diff)
[SPARC64]: Make tsb_sync() mm comparison more precise.
switch_mm() changes the mm state and does a tsb_context_switch() first, then we do the cpu register state switch which changes current_thread_info() and current(). So it's safer to check the PGD physical address stored in the trap block (which will be updated by the tsb_context_switch() in switch_mm()) than current->active_mm. Technically we should never run here in between those two updates, because interrupts are disabled during the entire context switch operation. But some day we might like to leave interrupts enabled during the context switch and this change allows that to happen without any surprises. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/smp.c')
-rw-r--r--arch/sparc64/kernel/smp.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 7dc28a48426..8175a6968c6 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -830,9 +830,16 @@ void smp_call_function_client(int irq, struct pt_regs *regs)
830 830
831static void tsb_sync(void *info) 831static void tsb_sync(void *info)
832{ 832{
833 struct trap_per_cpu *tp = &trap_block[raw_smp_processor_id()];
833 struct mm_struct *mm = info; 834 struct mm_struct *mm = info;
834 835
835 if (current->active_mm == mm) 836 /* It is not valid to test "currrent->active_mm == mm" here.
837 *
838 * The value of "current" is not changed atomically with
839 * switch_mm(). But that's OK, we just need to check the
840 * current cpu's trap block PGD physical address.
841 */
842 if (tp->pgd_paddr == __pa(mm->pgd))
836 tsb_context_switch(mm); 843 tsb_context_switch(mm);
837} 844}
838 845