aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2009-06-11 10:35:00 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-06-11 10:35:00 -0400
commit42578c82e0f1810a07ebe29cb05e874893243d8c (patch)
treee2a3811677d3594e891fc82c940438f6b6abc3e0 /arch/arm/kernel
parent2631182bf93919577730e6a6c4345308db590057 (diff)
parent85d6943af50537d3aec58b967ffbd3fec88453e9 (diff)
Merge branch 'for-rmk' of git://linux-arm.org/linux-2.6 into devel
Conflicts: arch/arm/Kconfig arch/arm/kernel/smp.c arch/arm/mach-realview/Makefile arch/arm/mach-realview/platsmp.c
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/entry-armv.S3
-rw-r--r--arch/arm/kernel/entry-common.S3
-rw-r--r--arch/arm/kernel/process.c2
-rw-r--r--arch/arm/kernel/signal.c8
-rw-r--r--arch/arm/kernel/smp.c69
-rw-r--r--arch/arm/kernel/vmlinux.lds.S2
6 files changed, 58 insertions, 29 deletions
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 83b1da6b7baa..fc8af43c5000 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -482,6 +482,9 @@ __und_usr:
482 subeq r4, r2, #4 @ ARM instr at LR - 4 482 subeq r4, r2, #4 @ ARM instr at LR - 4
483 subne r4, r2, #2 @ Thumb instr at LR - 2 483 subne r4, r2, #2 @ Thumb instr at LR - 2
4841: ldreqt r0, [r4] 4841: ldreqt r0, [r4]
485#ifdef CONFIG_CPU_ENDIAN_BE8
486 reveq r0, r0 @ little endian instruction
487#endif
485 beq call_fpe 488 beq call_fpe
486 @ Thumb instruction 489 @ Thumb instruction
487#if __LINUX_ARM_ARCH__ >= 7 490#if __LINUX_ARM_ARCH__ >= 7
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index b55cb0331809..366e5097a41a 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -210,6 +210,9 @@ ENTRY(vector_swi)
210 A710( teq ip, #0x0f000000 ) 210 A710( teq ip, #0x0f000000 )
211 A710( bne .Larm710bug ) 211 A710( bne .Larm710bug )
212#endif 212#endif
213#ifdef CONFIG_CPU_ENDIAN_BE8
214 rev r10, r10 @ little endian instruction
215#endif
213 216
214#elif defined(CONFIG_AEABI) 217#elif defined(CONFIG_AEABI)
215 218
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index c3265a2e7cd4..1585423699ee 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -365,7 +365,7 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
365 regs.ARM_r2 = (unsigned long)fn; 365 regs.ARM_r2 = (unsigned long)fn;
366 regs.ARM_r3 = (unsigned long)do_exit; 366 regs.ARM_r3 = (unsigned long)do_exit;
367 regs.ARM_pc = (unsigned long)kernel_thread_helper; 367 regs.ARM_pc = (unsigned long)kernel_thread_helper;
368 regs.ARM_cpsr = SVC_MODE; 368 regs.ARM_cpsr = SVC_MODE | PSR_ENDSTATE;
369 369
370 return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL); 370 return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
371} 371}
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 80b8b5c7e07a..442b87476f97 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -426,9 +426,13 @@ setup_return(struct pt_regs *regs, struct k_sigaction *ka,
426 */ 426 */
427 thumb = handler & 1; 427 thumb = handler & 1;
428 428
429 if (thumb) 429 if (thumb) {
430 cpsr |= PSR_T_BIT; 430 cpsr |= PSR_T_BIT;
431 else 431#if __LINUX_ARM_ARCH__ >= 7
432 /* clear the If-Then Thumb-2 execution state */
433 cpsr &= ~PSR_IT_MASK;
434#endif
435 } else
432 cpsr &= ~PSR_T_BIT; 436 cpsr &= ~PSR_T_BIT;
433 } 437 }
434#endif 438#endif
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 0d8097fa4ca5..de885fd256c5 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -28,6 +28,7 @@
28#include <asm/atomic.h> 28#include <asm/atomic.h>
29#include <asm/cacheflush.h> 29#include <asm/cacheflush.h>
30#include <asm/cpu.h> 30#include <asm/cpu.h>
31#include <asm/cputype.h>
31#include <asm/mmu_context.h> 32#include <asm/mmu_context.h>
32#include <asm/pgtable.h> 33#include <asm/pgtable.h>
33#include <asm/pgalloc.h> 34#include <asm/pgalloc.h>
@@ -585,6 +586,12 @@ struct tlb_args {
585 unsigned long ta_end; 586 unsigned long ta_end;
586}; 587};
587 588
589/* all SMP configurations have the extended CPUID registers */
590static inline int tlb_ops_need_broadcast(void)
591{
592 return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2;
593}
594
588static inline void ipi_flush_tlb_all(void *ignored) 595static inline void ipi_flush_tlb_all(void *ignored)
589{ 596{
590 local_flush_tlb_all(); 597 local_flush_tlb_all();
@@ -627,51 +634,61 @@ static inline void ipi_flush_tlb_kernel_range(void *arg)
627 634
628void flush_tlb_all(void) 635void flush_tlb_all(void)
629{ 636{
630 on_each_cpu(ipi_flush_tlb_all, NULL, 1); 637 if (tlb_ops_need_broadcast())
638 on_each_cpu(ipi_flush_tlb_all, NULL, 1);
639 else
640 local_flush_tlb_all();
631} 641}
632 642
633void flush_tlb_mm(struct mm_struct *mm) 643void flush_tlb_mm(struct mm_struct *mm)
634{ 644{
635 on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, &mm->cpu_vm_mask); 645 if (tlb_ops_need_broadcast())
646 on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, &mm->cpu_vm_mask);
647 else
648 local_flush_tlb_mm(mm);
636} 649}
637 650
638void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) 651void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
639{ 652{
640 struct tlb_args ta; 653 if (tlb_ops_need_broadcast()) {
641 654 struct tlb_args ta;
642 ta.ta_vma = vma; 655 ta.ta_vma = vma;
643 ta.ta_start = uaddr; 656 ta.ta_start = uaddr;
644 657 on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, &vma->vm_mm->cpu_vm_mask);
645 on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, &vma->vm_mm->cpu_vm_mask); 658 } else
659 local_flush_tlb_page(vma, uaddr);
646} 660}
647 661
648void flush_tlb_kernel_page(unsigned long kaddr) 662void flush_tlb_kernel_page(unsigned long kaddr)
649{ 663{
650 struct tlb_args ta; 664 if (tlb_ops_need_broadcast()) {
651 665 struct tlb_args ta;
652 ta.ta_start = kaddr; 666 ta.ta_start = kaddr;
653 667 on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1);
654 on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1); 668 } else
669 local_flush_tlb_kernel_page(kaddr);
655} 670}
656 671
657void flush_tlb_range(struct vm_area_struct *vma, 672void flush_tlb_range(struct vm_area_struct *vma,
658 unsigned long start, unsigned long end) 673 unsigned long start, unsigned long end)
659{ 674{
660 struct tlb_args ta; 675 if (tlb_ops_need_broadcast()) {
661 676 struct tlb_args ta;
662 ta.ta_vma = vma; 677 ta.ta_vma = vma;
663 ta.ta_start = start; 678 ta.ta_start = start;
664 ta.ta_end = end; 679 ta.ta_end = end;
665 680 on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, &vma->vm_mm->cpu_vm_mask);
666 on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, &vma->vm_mm->cpu_vm_mask); 681 } else
682 local_flush_tlb_range(vma, start, end);
667} 683}
668 684
669void flush_tlb_kernel_range(unsigned long start, unsigned long end) 685void flush_tlb_kernel_range(unsigned long start, unsigned long end)
670{ 686{
671 struct tlb_args ta; 687 if (tlb_ops_need_broadcast()) {
672 688 struct tlb_args ta;
673 ta.ta_start = start; 689 ta.ta_start = start;
674 ta.ta_end = end; 690 ta.ta_end = end;
675 691 on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1);
676 on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1); 692 } else
693 local_flush_tlb_kernel_range(start, end);
677} 694}
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index c90f27250ead..6c0779792546 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -141,6 +141,7 @@ SECTIONS
141 141
142 .data : AT(__data_loc) { 142 .data : AT(__data_loc) {
143 _data = .; /* address in memory */ 143 _data = .; /* address in memory */
144 _sdata = .;
144 145
145 /* 146 /*
146 * first, the init task union, aligned 147 * first, the init task union, aligned
@@ -192,6 +193,7 @@ SECTIONS
192 __bss_start = .; /* BSS */ 193 __bss_start = .; /* BSS */
193 *(.bss) 194 *(.bss)
194 *(COMMON) 195 *(COMMON)
196 __bss_stop = .;
195 _end = .; 197 _end = .;
196 } 198 }
197 /* Stabs debugging sections. */ 199 /* Stabs debugging sections. */