diff options
-rw-r--r-- | arch/x86/include/asm/irq_vectors.h | 33 | ||||
-rw-r--r-- | arch/x86/kernel/tlb_32.c | 10 | ||||
-rw-r--r-- | arch/x86/kernel/tlb_64.c | 18 |
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 | ||
89 | void smp_invalidate_interrupt(struct pt_regs *regs) | 91 | void 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 | } |
117 | out: | ||
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(); |
119 | out: | ||
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 | } |
218 | EXPORT_SYMBOL(flush_tlb_page); | ||
219 | 219 | ||
220 | static void do_flush_tlb_all(void *info) | 220 | static 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 | ||
20 | DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) | 14 | DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) |
@@ -121,8 +115,8 @@ EXPORT_SYMBOL_GPL(leave_mm); | |||
121 | 115 | ||
122 | asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs) | 116 | asmlinkage 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 | } |
156 | out: | 150 | out: |
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 | ||
162 | static void flush_tlb_others_ipi(const struct cpumask *cpumask, | 158 | static 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 */ |