diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2009-06-11 10:35:00 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-06-11 10:35:00 -0400 |
commit | 42578c82e0f1810a07ebe29cb05e874893243d8c (patch) | |
tree | e2a3811677d3594e891fc82c940438f6b6abc3e0 /arch/arm/kernel | |
parent | 2631182bf93919577730e6a6c4345308db590057 (diff) | |
parent | 85d6943af50537d3aec58b967ffbd3fec88453e9 (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.S | 3 | ||||
-rw-r--r-- | arch/arm/kernel/entry-common.S | 3 | ||||
-rw-r--r-- | arch/arm/kernel/process.c | 2 | ||||
-rw-r--r-- | arch/arm/kernel/signal.c | 8 | ||||
-rw-r--r-- | arch/arm/kernel/smp.c | 69 | ||||
-rw-r--r-- | arch/arm/kernel/vmlinux.lds.S | 2 |
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 |
484 | 1: ldreqt r0, [r4] | 484 | 1: 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, ®s, 0, NULL, NULL); | 370 | return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 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 */ | ||
590 | static inline int tlb_ops_need_broadcast(void) | ||
591 | { | ||
592 | return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2; | ||
593 | } | ||
594 | |||
588 | static inline void ipi_flush_tlb_all(void *ignored) | 595 | static 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 | ||
628 | void flush_tlb_all(void) | 635 | void 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 | ||
633 | void flush_tlb_mm(struct mm_struct *mm) | 643 | void 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 | ||
638 | void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) | 651 | void 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 | ||
648 | void flush_tlb_kernel_page(unsigned long kaddr) | 662 | void 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 | ||
657 | void flush_tlb_range(struct vm_area_struct *vma, | 672 | void 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 | ||
669 | void flush_tlb_kernel_range(unsigned long start, unsigned long end) | 685 | void 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. */ |