1
2
3
4
5
6
7
8
9
10
11#include <linux/init.h>
12
13#include <linux/mm.h>
14#include <linux/delay.h>
15#include <linux/spinlock.h>
16#include <linux/kernel_stat.h>
17#include <linux/mc146818rtc.h>
18#include <linux/cache.h>
19#include <linux/interrupt.h>
20#include <linux/cpu.h>
21#include <linux/module.h>
22
23#include <asm/mtrr.h>
24#include <asm/tlbflush.h>
25#include <mach_apic.h>
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, };
107
108
109
110
111
112
113
114static inline int __prepare_ICR (unsigned int shortcut, int vector)
115{
116 unsigned int icr = shortcut | APIC_DEST_LOGICAL;
117
118 switch (vector) {
119 default:
120 icr |= APIC_DM_FIXED | vector;
121 break;
122 case NMI_VECTOR:
123 icr |= APIC_DM_NMI;
124 break;
125 }
126 return icr;
127}
128
129static inline int __prepare_ICR2 (unsigned int mask)
130{
131 return SET_APIC_DEST_FIELD(mask);
132}
133
134void __send_IPI_shortcut(unsigned int shortcut, int vector)
135{
136
137
138
139
140
141
142
143 unsigned int cfg;
144
145
146
147
148 apic_wait_icr_idle();
149
150
151
152
153 cfg = __prepare_ICR(shortcut, vector);
154
155
156
157
158 apic_write_around(APIC_ICR, cfg);
159}
160
161void fastcall send_IPI_self(int vector)
162{
163 __send_IPI_shortcut(APIC_DEST_SELF, vector);
164}
165
166
167
168
169
170static inline void __send_IPI_dest_field(unsigned long mask, int vector)
171{
172 unsigned long cfg;
173
174
175
176
177 if (unlikely(vector == NMI_VECTOR))
178 safe_apic_wait_icr_idle();
179 else
180 apic_wait_icr_idle();
181
182
183
184
185 cfg = __prepare_ICR2(mask);
186 apic_write_around(APIC_ICR2, cfg);
187
188
189
190
191 cfg = __prepare_ICR(0, vector);
192
193
194
195
196 apic_write_around(APIC_ICR, cfg);
197}
198
199
200
201
202void send_IPI_mask_bitmask(cpumask_t cpumask, int vector)
203{
204 unsigned long mask = cpus_addr(cpumask)[0];
205 unsigned long flags;
206
207 local_irq_save(flags);
208 WARN_ON(mask & ~cpus_addr(cpu_online_map)[0]);
209 __send_IPI_dest_field(mask, vector);
210 local_irq_restore(flags);
211}
212
213void send_IPI_mask_sequence(cpumask_t mask, int vector)
214{
215 unsigned long flags;
216 unsigned int query_cpu;
217
218
219
220
221
222
223
224 local_irq_save(flags);
225 for (query_cpu = 0; query_cpu < NR_CPUS; ++query_cpu) {
226 if (cpu_isset(query_cpu, mask)) {
227 __send_IPI_dest_field(cpu_to_logical_apicid(query_cpu),
228 vector);
229 }
230 }
231 local_irq_restore(flags);
232}
233
234#include <mach_ipi.h>
235
236
237
238
239
240
241
242
243
244
245
246static cpumask_t flush_cpumask;
247static struct mm_struct * flush_mm;
248static unsigned long flush_va;
249static DEFINE_SPINLOCK(tlbstate_lock);
250
251
252
253
254
255
256
257
258static inline void leave_mm (unsigned long cpu)
259{
260 if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK)
261 BUG();
262 cpu_clear(cpu, per_cpu(cpu_tlbstate, cpu).active_mm->cpu_vm_mask);
263 load_cr3(swapper_pg_dir);
264}
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312fastcall void smp_invalidate_interrupt(struct pt_regs *regs)
313{
314 unsigned long cpu;
315
316 cpu = get_cpu();
317
318 if (!cpu_isset(cpu, flush_cpumask))
319 goto out;
320
321
322
323
324
325
326
327
328
329 if (flush_mm == per_cpu(cpu_tlbstate, cpu).active_mm) {
330 if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK) {
331 if (flush_va == TLB_FLUSH_ALL)
332 local_flush_tlb();
333 else
334 __flush_tlb_one(flush_va);
335 } else
336 leave_mm(cpu);
337 }
338 ack_APIC_irq();
339 smp_mb__before_clear_bit();
340 cpu_clear(cpu, flush_cpumask);
341 smp_mb__after_clear_bit();
342out:
343 put_cpu_no_resched();
344}
345
346void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm,
347 unsigned long va)
348{
349 cpumask_t cpumask = *cpumaskp;
350
351
352
353
354
355
356
357 BUG_ON(cpus_empty(cpumask));
358 BUG_ON(cpu_isset(smp_processor_id(), cpumask));
359 BUG_ON(!mm);
360
361#ifdef CONFIG_HOTPLUG_CPU
362
363 cpus_and(cpumask, cpumask, cpu_online_map);
364 if (unlikely(cpus_empty(cpumask)))
365 return;
366#endif
367
368
369
370
371
372
373 spin_lock(&tlbstate_lock);
374
375 flush_mm = mm;
376 flush_va = va;
377 cpus_or(flush_cpumask, cpumask, flush_cpumask);
378
379
380
381
382 send_IPI_mask(cpumask, INVALIDATE_TLB_VECTOR);
383
384 while (!cpus_empty(flush_cpumask))
385
386 cpu_relax();
387
388 flush_mm = NULL;
389 flush_va = 0;
390 spin_unlock(&tlbstate_lock);
391}
392
393void flush_tlb_current_task(void)
394{
395 struct mm_struct *mm = current->mm;
396 cpumask_t cpu_mask;
397
398 preempt_disable();
399 cpu_mask = mm->cpu_vm_mask;
400 cpu_clear(smp_processor_id(), cpu_mask);
401
402 local_flush_tlb();
403 if (!cpus_empty(cpu_mask))
404 flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL);
405 preempt_enable();
406}
407
408void flush_tlb_mm (struct mm_struct * mm)
409{
410 cpumask_t cpu_mask;
411
412 preempt_disable();
413 cpu_mask = mm->cpu_vm_mask;
414 cpu_clear(smp_processor_id(), cpu_mask);
415
416 if (current->active_mm == mm) {
417 if (current->mm)
418 local_flush_tlb();
419 else
420 leave_mm(smp_processor_id());
421 }
422 if (!cpus_empty(cpu_mask))
423 flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL);
424
425 preempt_enable();
426}
427
428void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
429{
430 struct mm_struct *mm = vma->vm_mm;
431 cpumask_t cpu_mask;
432
433 preempt_disable();
434 cpu_mask = mm->cpu_vm_mask;
435 cpu_clear(smp_processor_id(), cpu_mask);
436
437 if (current->active_mm == mm) {
438 if(current->mm)
439 __flush_tlb_one(va);
440 else
441 leave_mm(smp_processor_id());
442 }
443
444 if (!cpus_empty(cpu_mask))
445 flush_tlb_others(cpu_mask, mm, va);
446
447 preempt_enable();
448}
449EXPORT_SYMBOL(flush_tlb_page);
450
451static void do_flush_tlb_all(void* info)
452{
453 unsigned long cpu = smp_processor_id();
454
455 __flush_tlb_all();
456 if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_LAZY)
457 leave_mm(cpu);
458}
459
460void flush_tlb_all(void)
461{
462 on_each_cpu(do_flush_tlb_all, NULL, 1, 1);
463}
464
465
466
467
468
469
470static void native_smp_send_reschedule(int cpu)
471{
472 WARN_ON(cpu_is_offline(cpu));
473 send_IPI_mask(cpumask_of_cpu(cpu), RESCHEDULE_VECTOR);
474}
475
476
477
478
479
480static DEFINE_SPINLOCK(call_lock);
481
482struct call_data_struct {
483 void (*func) (void *info);
484 void *info;
485 atomic_t started;
486 atomic_t finished;
487 int wait;
488};
489
490void lock_ipi_call_lock(void)
491{
492 spin_lock_irq(&call_lock);
493}
494
495void unlock_ipi_call_lock(void)
496{
497 spin_unlock_irq(&call_lock);
498}
499
500static struct call_data_struct *call_data;
501
502static void __smp_call_function(void (*func) (void *info), void *info,
503 int nonatomic, int wait)
504{
505 struct call_data_struct data;
506 int cpus = num_online_cpus() - 1;
507
508 if (!cpus)
509 return;
510
511 data.func = func;
512 data.info = info;
513 atomic_set(&data.started, 0);
514 data.wait = wait;
515 if (wait)
516 atomic_set(&data.finished, 0);
517
518 call_data = &data;
519 mb();
520
521
522 send_IPI_allbutself(CALL_FUNCTION_VECTOR);
523
524
525 while (atomic_read(&data.started) != cpus)
526 cpu_relax();
527
528 if (wait)
529 while (atomic_read(&data.finished) != cpus)
530 cpu_relax();
531}
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549static int
550native_smp_call_function_mask(cpumask_t mask,
551 void (*func)(void *), void *info,
552 int wait)
553{
554 struct call_data_struct data;
555 cpumask_t allbutself;
556 int cpus;
557
558
559 WARN_ON(irqs_disabled());
560
561
562 spin_lock(&call_lock);
563
564 allbutself = cpu_online_map;
565 cpu_clear(smp_processor_id(), allbutself);
566
567 cpus_and(mask, mask, allbutself);
568 cpus = cpus_weight(mask);
569
570 if (!cpus) {
571 spin_unlock(&call_lock);
572 return 0;
573 }
574
575 data.func = func;
576 data.info = info;
577 atomic_set(&data.started, 0);
578 data.wait = wait;
579 if (wait)
580 atomic_set(&data.finished, 0);
581
582 call_data = &data;
583 mb();
584
585
586 if (cpus_equal(mask, allbutself))
587 send_IPI_allbutself(CALL_FUNCTION_VECTOR);
588 else
589 send_IPI_mask(mask, CALL_FUNCTION_VECTOR);
590
591
592 while (atomic_read(&data.started) != cpus)
593 cpu_relax();
594
595 if (wait)
596 while (atomic_read(&data.finished) != cpus)
597 cpu_relax();
598 spin_unlock(&call_lock);
599
600 return 0;
601}
602
603static void stop_this_cpu (void * dummy)
604{
605 local_irq_disable();
606
607
608
609 cpu_clear(smp_processor_id(), cpu_online_map);
610 disable_local_APIC();
611 if (cpu_data[smp_processor_id()].hlt_works_ok)
612 for(;;) halt();
613 for (;;);
614}
615
616
617
618
619
620static void native_smp_send_stop(void)
621{
622
623 int nolock = !spin_trylock(&call_lock);
624 unsigned long flags;
625
626 local_irq_save(flags);
627 __smp_call_function(stop_this_cpu, NULL, 0, 0);
628 if (!nolock)
629 spin_unlock(&call_lock);
630 disable_local_APIC();
631 local_irq_restore(flags);
632}
633
634
635
636
637
638
639fastcall void smp_reschedule_interrupt(struct pt_regs *regs)
640{
641 ack_APIC_irq();
642}
643
644fastcall void smp_call_function_interrupt(struct pt_regs *regs)
645{
646 void (*func) (void *info) = call_data->func;
647 void *info = call_data->info;
648 int wait = call_data->wait;
649
650 ack_APIC_irq();
651
652
653
654
655 mb();
656 atomic_inc(&call_data->started);
657
658
659
660 irq_enter();
661 (*func)(info);
662 irq_exit();
663
664 if (wait) {
665 mb();
666 atomic_inc(&call_data->finished);
667 }
668}
669
670static int convert_apicid_to_cpu(int apic_id)
671{
672 int i;
673
674 for (i = 0; i < NR_CPUS; i++) {
675 if (x86_cpu_to_apicid[i] == apic_id)
676 return i;
677 }
678 return -1;
679}
680
681int safe_smp_processor_id(void)
682{
683 int apicid, cpuid;
684
685 if (!boot_cpu_has(X86_FEATURE_APIC))
686 return 0;
687
688 apicid = hard_smp_processor_id();
689 if (apicid == BAD_APICID)
690 return 0;
691
692 cpuid = convert_apicid_to_cpu(apicid);
693
694 return cpuid >= 0 ? cpuid : 0;
695}
696
697struct smp_ops smp_ops = {
698 .smp_prepare_boot_cpu = native_smp_prepare_boot_cpu,
699 .smp_prepare_cpus = native_smp_prepare_cpus,
700 .cpu_up = native_cpu_up,
701 .smp_cpus_done = native_smp_cpus_done,
702
703 .smp_send_stop = native_smp_send_stop,
704 .smp_send_reschedule = native_smp_send_reschedule,
705 .smp_call_function_mask = native_smp_call_function_mask,
706};
707