aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/irq_vectors.h33
-rw-r--r--arch/x86/kernel/tlb_32.c10
-rw-r--r--arch/x86/kernel/tlb_64.c18
3 files changed, 28 insertions, 33 deletions
diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h
index a16a2ab2b429..4ee8f800504b 100644
--- a/arch/x86/include/asm/irq_vectors.h
+++ b/arch/x86/include/asm/irq_vectors.h
@@ -49,31 +49,30 @@
49 * some of the following vectors are 'rare', they are merged 49 * some of the following vectors are 'rare', they are merged
50 * into a single vector (CALL_FUNCTION_VECTOR) to save vector space. 50 * into a single vector (CALL_FUNCTION_VECTOR) to save vector space.
51 * TLB, reschedule and local APIC vectors are performance-critical. 51 * TLB, reschedule and local APIC vectors are performance-critical.
52 *
53 * Vectors 0xf0-0xfa are free (reserved for future Linux use).
54 */ 52 */
55#ifdef CONFIG_X86_32 53#ifdef CONFIG_X86_32
56 54
57# define SPURIOUS_APIC_VECTOR 0xff 55# define SPURIOUS_APIC_VECTOR 0xff
58# define ERROR_APIC_VECTOR 0xfe 56# define ERROR_APIC_VECTOR 0xfe
59# define INVALIDATE_TLB_VECTOR 0xfd 57# define RESCHEDULE_VECTOR 0xfd
60# define RESCHEDULE_VECTOR 0xfc 58# define CALL_FUNCTION_VECTOR 0xfc
61# define CALL_FUNCTION_VECTOR 0xfb 59# define CALL_FUNCTION_SINGLE_VECTOR 0xfb
62# define CALL_FUNCTION_SINGLE_VECTOR 0xfa 60# define THERMAL_APIC_VECTOR 0xfa
63# define THERMAL_APIC_VECTOR 0xf0 61/* 0xf1 - 0xf9 : free */
62# define INVALIDATE_TLB_VECTOR 0xf0
64 63
65#else 64#else
66 65
67#define SPURIOUS_APIC_VECTOR 0xff 66# define SPURIOUS_APIC_VECTOR 0xff
68#define ERROR_APIC_VECTOR 0xfe 67# define ERROR_APIC_VECTOR 0xfe
69#define RESCHEDULE_VECTOR 0xfd 68# define RESCHEDULE_VECTOR 0xfd
70#define CALL_FUNCTION_VECTOR 0xfc 69# define CALL_FUNCTION_VECTOR 0xfc
71#define CALL_FUNCTION_SINGLE_VECTOR 0xfb 70# define CALL_FUNCTION_SINGLE_VECTOR 0xfb
72#define THERMAL_APIC_VECTOR 0xfa 71# define THERMAL_APIC_VECTOR 0xfa
73#define THRESHOLD_APIC_VECTOR 0xf9 72# define THRESHOLD_APIC_VECTOR 0xf9
74#define UV_BAU_MESSAGE 0xf8 73# define UV_BAU_MESSAGE 0xf8
75#define INVALIDATE_TLB_VECTOR_END 0xf7 74# define INVALIDATE_TLB_VECTOR_END 0xf7
76#define INVALIDATE_TLB_VECTOR_START 0xf0 /* f0-f7 used for TLB flush */ 75# define INVALIDATE_TLB_VECTOR_START 0xf0 /* f0-f7 used for TLB flush */
77 76
78#define NUM_INVALIDATE_TLB_VECTORS 8 77#define NUM_INVALIDATE_TLB_VECTORS 8
79 78
diff --git a/arch/x86/kernel/tlb_32.c b/arch/x86/kernel/tlb_32.c
index abf0808d6fc4..93fcb05c7d43 100644
--- a/arch/x86/kernel/tlb_32.c
+++ b/arch/x86/kernel/tlb_32.c
@@ -84,13 +84,15 @@ EXPORT_SYMBOL_GPL(leave_mm);
84 * 84 *
85 * 1) Flush the tlb entries if the cpu uses the mm that's being flushed. 85 * 1) Flush the tlb entries if the cpu uses the mm that's being flushed.
86 * 2) Leave the mm if we are in the lazy tlb mode. 86 * 2) Leave the mm if we are in the lazy tlb mode.
87 *
88 * Interrupts are disabled.
87 */ 89 */
88 90
89void smp_invalidate_interrupt(struct pt_regs *regs) 91void smp_invalidate_interrupt(struct pt_regs *regs)
90{ 92{
91 unsigned long cpu; 93 unsigned int cpu;
92 94
93 cpu = get_cpu(); 95 cpu = smp_processor_id();
94 96
95 if (!cpumask_test_cpu(cpu, flush_cpumask)) 97 if (!cpumask_test_cpu(cpu, flush_cpumask))
96 goto out; 98 goto out;
@@ -112,12 +114,11 @@ void smp_invalidate_interrupt(struct pt_regs *regs)
112 } else 114 } else
113 leave_mm(cpu); 115 leave_mm(cpu);
114 } 116 }
117out:
115 ack_APIC_irq(); 118 ack_APIC_irq();
116 smp_mb__before_clear_bit(); 119 smp_mb__before_clear_bit();
117 cpumask_clear_cpu(cpu, flush_cpumask); 120 cpumask_clear_cpu(cpu, flush_cpumask);
118 smp_mb__after_clear_bit(); 121 smp_mb__after_clear_bit();
119out:
120 put_cpu_no_resched();
121 inc_irq_stat(irq_tlb_count); 122 inc_irq_stat(irq_tlb_count);
122} 123}
123 124
@@ -215,7 +216,6 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
215 flush_tlb_others(&mm->cpu_vm_mask, mm, va); 216 flush_tlb_others(&mm->cpu_vm_mask, mm, va);
216 preempt_enable(); 217 preempt_enable();
217} 218}
218EXPORT_SYMBOL(flush_tlb_page);
219 219
220static void do_flush_tlb_all(void *info) 220static void do_flush_tlb_all(void *info)
221{ 221{
diff --git a/arch/x86/kernel/tlb_64.c b/arch/x86/kernel/tlb_64.c
index b8bed841ad67..19ac661422f7 100644
--- a/arch/x86/kernel/tlb_64.c
+++ b/arch/x86/kernel/tlb_64.c
@@ -1,20 +1,14 @@
1#include <linux/init.h> 1#include <linux/init.h>
2 2
3#include <linux/mm.h> 3#include <linux/mm.h>
4#include <linux/delay.h>
5#include <linux/spinlock.h> 4#include <linux/spinlock.h>
6#include <linux/smp.h> 5#include <linux/smp.h>
7#include <linux/kernel_stat.h>
8#include <linux/mc146818rtc.h>
9#include <linux/interrupt.h> 6#include <linux/interrupt.h>
7#include <linux/module.h>
10 8
11#include <asm/mtrr.h>
12#include <asm/pgalloc.h>
13#include <asm/tlbflush.h> 9#include <asm/tlbflush.h>
14#include <asm/mmu_context.h> 10#include <asm/mmu_context.h>
15#include <asm/proto.h> 11#include <asm/apic.h>
16#include <asm/apicdef.h>
17#include <asm/idle.h>
18#include <asm/uv/uv.h> 12#include <asm/uv/uv.h>
19 13
20DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) 14DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate)
@@ -121,8 +115,8 @@ EXPORT_SYMBOL_GPL(leave_mm);
121 115
122asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs) 116asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs)
123{ 117{
124 int cpu; 118 unsigned int cpu;
125 int sender; 119 unsigned int sender;
126 union smp_flush_state *f; 120 union smp_flush_state *f;
127 121
128 cpu = smp_processor_id(); 122 cpu = smp_processor_id();
@@ -155,14 +149,16 @@ asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs)
155 } 149 }
156out: 150out:
157 ack_APIC_irq(); 151 ack_APIC_irq();
152 smp_mb__before_clear_bit();
158 cpumask_clear_cpu(cpu, to_cpumask(f->flush_cpumask)); 153 cpumask_clear_cpu(cpu, to_cpumask(f->flush_cpumask));
154 smp_mb__after_clear_bit();
159 inc_irq_stat(irq_tlb_count); 155 inc_irq_stat(irq_tlb_count);
160} 156}
161 157
162static void flush_tlb_others_ipi(const struct cpumask *cpumask, 158static void flush_tlb_others_ipi(const struct cpumask *cpumask,
163 struct mm_struct *mm, unsigned long va) 159 struct mm_struct *mm, unsigned long va)
164{ 160{
165 int sender; 161 unsigned int sender;
166 union smp_flush_state *f; 162 union smp_flush_state *f;
167 163
168 /* Caller has disabled preemption */ 164 /* Caller has disabled preemption */