diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-17 19:52:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-17 19:52:29 -0400 |
commit | 42ea7d7f2a7356962022cdd124d9043c488ca5e2 (patch) | |
tree | 5afe09d5d024945178be458b39f96f8c720ac433 | |
parent | 39c2028531332cab1325637c2100f3189fa1be72 (diff) | |
parent | 56cb248428ead13a6b423ed3f3cf9e4aa01244b1 (diff) |
Merge branch 'fixes' of git://git.linaro.org/people/rmk/linux-arm
Pull ARM fixes from Russell King:
"Small set of fixes again."
* 'fixes' of git://git.linaro.org/people/rmk/linux-arm:
ARM: 7419/1: vfp: fix VFP flushing regression on sigreturn path
ARM: 7418/1: LPAE: fix access flag setup in mem_type_table
ARM: prevent VM_GROWSDOWN mmaps extending below FIRST_USER_ADDRESS
ARM: 7417/1: vfp: ensure preemption is disabled when enabling VFP access
-rw-r--r-- | arch/arm/mm/fault.c | 4 | ||||
-rw-r--r-- | arch/arm/mm/mmu.c | 3 | ||||
-rw-r--r-- | arch/arm/vfp/vfpmodule.c | 24 |
3 files changed, 13 insertions, 18 deletions
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index f07467533365..5bb48356d217 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c | |||
@@ -247,7 +247,9 @@ good_area: | |||
247 | return handle_mm_fault(mm, vma, addr & PAGE_MASK, flags); | 247 | return handle_mm_fault(mm, vma, addr & PAGE_MASK, flags); |
248 | 248 | ||
249 | check_stack: | 249 | check_stack: |
250 | if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr)) | 250 | /* Don't allow expansion below FIRST_USER_ADDRESS */ |
251 | if (vma->vm_flags & VM_GROWSDOWN && | ||
252 | addr >= FIRST_USER_ADDRESS && !expand_stack(vma, addr)) | ||
251 | goto good_area; | 253 | goto good_area; |
252 | out: | 254 | out: |
253 | return fault; | 255 | return fault; |
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 2c7cf2f9c837..aa78de8bfdd3 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
@@ -489,7 +489,8 @@ static void __init build_mem_type_table(void) | |||
489 | */ | 489 | */ |
490 | for (i = 0; i < ARRAY_SIZE(mem_types); i++) { | 490 | for (i = 0; i < ARRAY_SIZE(mem_types); i++) { |
491 | mem_types[i].prot_pte |= PTE_EXT_AF; | 491 | mem_types[i].prot_pte |= PTE_EXT_AF; |
492 | mem_types[i].prot_sect |= PMD_SECT_AF; | 492 | if (mem_types[i].prot_sect) |
493 | mem_types[i].prot_sect |= PMD_SECT_AF; | ||
493 | } | 494 | } |
494 | kern_pgprot |= PTE_EXT_AF; | 495 | kern_pgprot |= PTE_EXT_AF; |
495 | vecs_pgprot |= PTE_EXT_AF; | 496 | vecs_pgprot |= PTE_EXT_AF; |
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index bc683b8219b5..b0197b2c857d 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/types.h> | 11 | #include <linux/types.h> |
12 | #include <linux/cpu.h> | 12 | #include <linux/cpu.h> |
13 | #include <linux/cpu_pm.h> | 13 | #include <linux/cpu_pm.h> |
14 | #include <linux/hardirq.h> | ||
14 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
15 | #include <linux/notifier.h> | 16 | #include <linux/notifier.h> |
16 | #include <linux/signal.h> | 17 | #include <linux/signal.h> |
@@ -432,7 +433,10 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) | |||
432 | 433 | ||
433 | static void vfp_enable(void *unused) | 434 | static void vfp_enable(void *unused) |
434 | { | 435 | { |
435 | u32 access = get_copro_access(); | 436 | u32 access; |
437 | |||
438 | BUG_ON(preemptible()); | ||
439 | access = get_copro_access(); | ||
436 | 440 | ||
437 | /* | 441 | /* |
438 | * Enable full access to VFP (cp10 and cp11) | 442 | * Enable full access to VFP (cp10 and cp11) |
@@ -573,12 +577,6 @@ int vfp_preserve_user_clear_hwstate(struct user_vfp __user *ufp, | |||
573 | * entry. | 577 | * entry. |
574 | */ | 578 | */ |
575 | hwstate->fpscr &= ~(FPSCR_LENGTH_MASK | FPSCR_STRIDE_MASK); | 579 | hwstate->fpscr &= ~(FPSCR_LENGTH_MASK | FPSCR_STRIDE_MASK); |
576 | |||
577 | /* | ||
578 | * Disable VFP in the hwstate so that we can detect if it gets | ||
579 | * used. | ||
580 | */ | ||
581 | hwstate->fpexc &= ~FPEXC_EN; | ||
582 | return 0; | 580 | return 0; |
583 | } | 581 | } |
584 | 582 | ||
@@ -591,12 +589,8 @@ int vfp_restore_user_hwstate(struct user_vfp __user *ufp, | |||
591 | unsigned long fpexc; | 589 | unsigned long fpexc; |
592 | int err = 0; | 590 | int err = 0; |
593 | 591 | ||
594 | /* | 592 | /* Disable VFP to avoid corrupting the new thread state. */ |
595 | * If VFP has been used, then disable it to avoid corrupting | 593 | vfp_flush_hwstate(thread); |
596 | * the new thread state. | ||
597 | */ | ||
598 | if (hwstate->fpexc & FPEXC_EN) | ||
599 | vfp_flush_hwstate(thread); | ||
600 | 594 | ||
601 | /* | 595 | /* |
602 | * Copy the floating point registers. There can be unused | 596 | * Copy the floating point registers. There can be unused |
@@ -657,7 +651,7 @@ static int __init vfp_init(void) | |||
657 | unsigned int cpu_arch = cpu_architecture(); | 651 | unsigned int cpu_arch = cpu_architecture(); |
658 | 652 | ||
659 | if (cpu_arch >= CPU_ARCH_ARMv6) | 653 | if (cpu_arch >= CPU_ARCH_ARMv6) |
660 | vfp_enable(NULL); | 654 | on_each_cpu(vfp_enable, NULL, 1); |
661 | 655 | ||
662 | /* | 656 | /* |
663 | * First check that there is a VFP that we can use. | 657 | * First check that there is a VFP that we can use. |
@@ -678,8 +672,6 @@ static int __init vfp_init(void) | |||
678 | } else { | 672 | } else { |
679 | hotcpu_notifier(vfp_hotplug, 0); | 673 | hotcpu_notifier(vfp_hotplug, 0); |
680 | 674 | ||
681 | smp_call_function(vfp_enable, NULL, 1); | ||
682 | |||
683 | VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */ | 675 | VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */ |
684 | printk("implementor %02x architecture %d part %02x variant %x rev %x\n", | 676 | printk("implementor %02x architecture %d part %02x variant %x rev %x\n", |
685 | (vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT, | 677 | (vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT, |