aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/armksyms.c6
-rw-r--r--arch/arm/kernel/setup.c3
-rw-r--r--arch/arm/kernel/smp.c123
3 files changed, 125 insertions, 7 deletions
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 4c38bd8bc298..b713c44c6fb4 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -30,9 +30,6 @@ extern void __lshrdi3(void);
30extern void __modsi3(void); 30extern void __modsi3(void);
31extern void __muldi3(void); 31extern void __muldi3(void);
32extern void __ucmpdi2(void); 32extern void __ucmpdi2(void);
33extern void __udivdi3(void);
34extern void __umoddi3(void);
35extern void __udivmoddi4(void);
36extern void __udivsi3(void); 33extern void __udivsi3(void);
37extern void __umodsi3(void); 34extern void __umodsi3(void);
38extern void __do_div64(void); 35extern void __do_div64(void);
@@ -134,9 +131,6 @@ EXPORT_SYMBOL(__lshrdi3);
134EXPORT_SYMBOL(__modsi3); 131EXPORT_SYMBOL(__modsi3);
135EXPORT_SYMBOL(__muldi3); 132EXPORT_SYMBOL(__muldi3);
136EXPORT_SYMBOL(__ucmpdi2); 133EXPORT_SYMBOL(__ucmpdi2);
137EXPORT_SYMBOL(__udivdi3);
138EXPORT_SYMBOL(__umoddi3);
139EXPORT_SYMBOL(__udivmoddi4);
140EXPORT_SYMBOL(__udivsi3); 134EXPORT_SYMBOL(__udivsi3);
141EXPORT_SYMBOL(__umodsi3); 135EXPORT_SYMBOL(__umodsi3);
142EXPORT_SYMBOL(__do_div64); 136EXPORT_SYMBOL(__do_div64);
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 8cf733daa800..35b7273cfdb4 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -359,7 +359,8 @@ void cpu_init(void)
359 "I" (offsetof(struct stack, abt[0])), 359 "I" (offsetof(struct stack, abt[0])),
360 "I" (PSR_F_BIT | PSR_I_BIT | UND_MODE), 360 "I" (PSR_F_BIT | PSR_I_BIT | UND_MODE),
361 "I" (offsetof(struct stack, und[0])), 361 "I" (offsetof(struct stack, und[0])),
362 "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE)); 362 "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
363 : "r14");
363} 364}
364 365
365static struct machine_desc * __init setup_machine(unsigned int nr) 366static struct machine_desc * __init setup_machine(unsigned int nr)
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 34892758f098..a931409c8fe4 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -502,3 +502,126 @@ int __init setup_profiling_timer(unsigned int multiplier)
502{ 502{
503 return -EINVAL; 503 return -EINVAL;
504} 504}
505
506static int
507on_each_cpu_mask(void (*func)(void *), void *info, int retry, int wait,
508 cpumask_t mask)
509{
510 int ret = 0;
511
512 preempt_disable();
513
514 ret = smp_call_function_on_cpu(func, info, retry, wait, mask);
515 if (cpu_isset(smp_processor_id(), mask))
516 func(info);
517
518 preempt_enable();
519
520 return ret;
521}
522
523/**********************************************************************/
524
525/*
526 * TLB operations
527 */
528struct tlb_args {
529 struct vm_area_struct *ta_vma;
530 unsigned long ta_start;
531 unsigned long ta_end;
532};
533
534static inline void ipi_flush_tlb_all(void *ignored)
535{
536 local_flush_tlb_all();
537}
538
539static inline void ipi_flush_tlb_mm(void *arg)
540{
541 struct mm_struct *mm = (struct mm_struct *)arg;
542
543 local_flush_tlb_mm(mm);
544}
545
546static inline void ipi_flush_tlb_page(void *arg)
547{
548 struct tlb_args *ta = (struct tlb_args *)arg;
549
550 local_flush_tlb_page(ta->ta_vma, ta->ta_start);
551}
552
553static inline void ipi_flush_tlb_kernel_page(void *arg)
554{
555 struct tlb_args *ta = (struct tlb_args *)arg;
556
557 local_flush_tlb_kernel_page(ta->ta_start);
558}
559
560static inline void ipi_flush_tlb_range(void *arg)
561{
562 struct tlb_args *ta = (struct tlb_args *)arg;
563
564 local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end);
565}
566
567static inline void ipi_flush_tlb_kernel_range(void *arg)
568{
569 struct tlb_args *ta = (struct tlb_args *)arg;
570
571 local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end);
572}
573
574void flush_tlb_all(void)
575{
576 on_each_cpu(ipi_flush_tlb_all, NULL, 1, 1);
577}
578
579void flush_tlb_mm(struct mm_struct *mm)
580{
581 cpumask_t mask = mm->cpu_vm_mask;
582
583 on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, 1, mask);
584}
585
586void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
587{
588 cpumask_t mask = vma->vm_mm->cpu_vm_mask;
589 struct tlb_args ta;
590
591 ta.ta_vma = vma;
592 ta.ta_start = uaddr;
593
594 on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, 1, mask);
595}
596
597void flush_tlb_kernel_page(unsigned long kaddr)
598{
599 struct tlb_args ta;
600
601 ta.ta_start = kaddr;
602
603 on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1, 1);
604}
605
606void flush_tlb_range(struct vm_area_struct *vma,
607 unsigned long start, unsigned long end)
608{
609 cpumask_t mask = vma->vm_mm->cpu_vm_mask;
610 struct tlb_args ta;
611
612 ta.ta_vma = vma;
613 ta.ta_start = start;
614 ta.ta_end = end;
615
616 on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, 1, mask);
617}
618
619void flush_tlb_kernel_range(unsigned long start, unsigned long end)
620{
621 struct tlb_args ta;
622
623 ta.ta_start = start;
624 ta.ta_end = end;
625
626 on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1, 1);
627}