diff options
Diffstat (limited to 'arch/ppc')
-rw-r--r-- | arch/ppc/Kconfig | 17 | ||||
-rw-r--r-- | arch/ppc/kernel/cputable.c | 11 | ||||
-rw-r--r-- | arch/ppc/kernel/entry.S | 16 | ||||
-rw-r--r-- | arch/ppc/kernel/misc.S | 6 | ||||
-rw-r--r-- | arch/ppc/kernel/ppc_ksyms.c | 2 | ||||
-rw-r--r-- | arch/ppc/kernel/ptrace.c | 40 | ||||
-rw-r--r-- | arch/ppc/platforms/pmac_cpufreq.c | 7 |
7 files changed, 81 insertions, 18 deletions
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index 6e6377a69d5b..54ce6da22644 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig | |||
@@ -1083,6 +1083,23 @@ source "drivers/zorro/Kconfig" | |||
1083 | 1083 | ||
1084 | source kernel/power/Kconfig | 1084 | source kernel/power/Kconfig |
1085 | 1085 | ||
1086 | config SECCOMP | ||
1087 | bool "Enable seccomp to safely compute untrusted bytecode" | ||
1088 | depends on PROC_FS | ||
1089 | default y | ||
1090 | help | ||
1091 | This kernel feature is useful for number crunching applications | ||
1092 | that may need to compute untrusted bytecode during their | ||
1093 | execution. By using pipes or other transports made available to | ||
1094 | the process as file descriptors supporting the read/write | ||
1095 | syscalls, it's possible to isolate those applications in | ||
1096 | their own address space using seccomp. Once seccomp is | ||
1097 | enabled via /proc/<pid>/seccomp, it cannot be disabled | ||
1098 | and the task is only allowed to execute a few safe syscalls | ||
1099 | defined by each seccomp mode. | ||
1100 | |||
1101 | If unsure, say Y. Only embedded should say N here. | ||
1102 | |||
1086 | endmenu | 1103 | endmenu |
1087 | 1104 | ||
1088 | config ISA_DMA_API | 1105 | config ISA_DMA_API |
diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c index 8aa5e8c69009..d44b7dc5390a 100644 --- a/arch/ppc/kernel/cputable.c +++ b/arch/ppc/kernel/cputable.c | |||
@@ -838,6 +838,17 @@ struct cpu_spec cpu_specs[] = { | |||
838 | .icache_bsize = 32, | 838 | .icache_bsize = 32, |
839 | .dcache_bsize = 32, | 839 | .dcache_bsize = 32, |
840 | }, | 840 | }, |
841 | { /* 405EP */ | ||
842 | .pvr_mask = 0xffff0000, | ||
843 | .pvr_value = 0x51210000, | ||
844 | .cpu_name = "405EP", | ||
845 | .cpu_features = CPU_FTR_SPLIT_ID_CACHE | | ||
846 | CPU_FTR_USE_TB, | ||
847 | .cpu_user_features = PPC_FEATURE_32 | | ||
848 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | ||
849 | .icache_bsize = 32, | ||
850 | .dcache_bsize = 32, | ||
851 | }, | ||
841 | 852 | ||
842 | #endif /* CONFIG_40x */ | 853 | #endif /* CONFIG_40x */ |
843 | #ifdef CONFIG_44x | 854 | #ifdef CONFIG_44x |
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S index 5f075dbc4ee7..661523707e8c 100644 --- a/arch/ppc/kernel/entry.S +++ b/arch/ppc/kernel/entry.S | |||
@@ -202,7 +202,7 @@ _GLOBAL(DoSyscall) | |||
202 | rlwinm r11,r11,0,~_TIFL_FORCE_NOERROR | 202 | rlwinm r11,r11,0,~_TIFL_FORCE_NOERROR |
203 | stw r11,TI_LOCAL_FLAGS(r10) | 203 | stw r11,TI_LOCAL_FLAGS(r10) |
204 | lwz r11,TI_FLAGS(r10) | 204 | lwz r11,TI_FLAGS(r10) |
205 | andi. r11,r11,_TIF_SYSCALL_TRACE | 205 | andi. r11,r11,_TIF_SYSCALL_T_OR_A |
206 | bne- syscall_dotrace | 206 | bne- syscall_dotrace |
207 | syscall_dotrace_cont: | 207 | syscall_dotrace_cont: |
208 | cmplwi 0,r0,NR_syscalls | 208 | cmplwi 0,r0,NR_syscalls |
@@ -237,7 +237,7 @@ ret_from_syscall: | |||
237 | SYNC | 237 | SYNC |
238 | MTMSRD(r10) | 238 | MTMSRD(r10) |
239 | lwz r9,TI_FLAGS(r12) | 239 | lwz r9,TI_FLAGS(r12) |
240 | andi. r0,r9,(_TIF_SYSCALL_TRACE|_TIF_SIGPENDING|_TIF_NEED_RESCHED) | 240 | andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED) |
241 | bne- syscall_exit_work | 241 | bne- syscall_exit_work |
242 | syscall_exit_cont: | 242 | syscall_exit_cont: |
243 | #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) | 243 | #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) |
@@ -277,7 +277,8 @@ syscall_dotrace: | |||
277 | SAVE_NVGPRS(r1) | 277 | SAVE_NVGPRS(r1) |
278 | li r0,0xc00 | 278 | li r0,0xc00 |
279 | stw r0,TRAP(r1) | 279 | stw r0,TRAP(r1) |
280 | bl do_syscall_trace | 280 | addi r3,r1,STACK_FRAME_OVERHEAD |
281 | bl do_syscall_trace_enter | ||
281 | lwz r0,GPR0(r1) /* Restore original registers */ | 282 | lwz r0,GPR0(r1) /* Restore original registers */ |
282 | lwz r3,GPR3(r1) | 283 | lwz r3,GPR3(r1) |
283 | lwz r4,GPR4(r1) | 284 | lwz r4,GPR4(r1) |
@@ -291,7 +292,7 @@ syscall_dotrace: | |||
291 | syscall_exit_work: | 292 | syscall_exit_work: |
292 | stw r6,RESULT(r1) /* Save result */ | 293 | stw r6,RESULT(r1) /* Save result */ |
293 | stw r3,GPR3(r1) /* Update return value */ | 294 | stw r3,GPR3(r1) /* Update return value */ |
294 | andi. r0,r9,_TIF_SYSCALL_TRACE | 295 | andi. r0,r9,_TIF_SYSCALL_T_OR_A |
295 | beq 5f | 296 | beq 5f |
296 | ori r10,r10,MSR_EE | 297 | ori r10,r10,MSR_EE |
297 | SYNC | 298 | SYNC |
@@ -303,7 +304,8 @@ syscall_exit_work: | |||
303 | li r4,0xc00 | 304 | li r4,0xc00 |
304 | stw r4,TRAP(r1) | 305 | stw r4,TRAP(r1) |
305 | 4: | 306 | 4: |
306 | bl do_syscall_trace | 307 | addi r3,r1,STACK_FRAME_OVERHEAD |
308 | bl do_syscall_trace_leave | ||
307 | REST_NVGPRS(r1) | 309 | REST_NVGPRS(r1) |
308 | 2: | 310 | 2: |
309 | lwz r3,GPR3(r1) | 311 | lwz r3,GPR3(r1) |
@@ -627,8 +629,8 @@ sigreturn_exit: | |||
627 | subi r1,r3,STACK_FRAME_OVERHEAD | 629 | subi r1,r3,STACK_FRAME_OVERHEAD |
628 | rlwinm r12,r1,0,0,18 /* current_thread_info() */ | 630 | rlwinm r12,r1,0,0,18 /* current_thread_info() */ |
629 | lwz r9,TI_FLAGS(r12) | 631 | lwz r9,TI_FLAGS(r12) |
630 | andi. r0,r9,_TIF_SYSCALL_TRACE | 632 | andi. r0,r9,_TIF_SYSCALL_T_OR_A |
631 | bnel- do_syscall_trace | 633 | bnel- do_syscall_trace_leave |
632 | /* fall through */ | 634 | /* fall through */ |
633 | 635 | ||
634 | .globl ret_from_except_full | 636 | .globl ret_from_except_full |
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index e4f1615ec13f..7329ef177a18 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S | |||
@@ -619,7 +619,7 @@ _GLOBAL(flush_instruction_cache) | |||
619 | _GLOBAL(flush_icache_range) | 619 | _GLOBAL(flush_icache_range) |
620 | BEGIN_FTR_SECTION | 620 | BEGIN_FTR_SECTION |
621 | blr /* for 601, do nothing */ | 621 | blr /* for 601, do nothing */ |
622 | END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE) | 622 | END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) |
623 | li r5,L1_CACHE_LINE_SIZE-1 | 623 | li r5,L1_CACHE_LINE_SIZE-1 |
624 | andc r3,r3,r5 | 624 | andc r3,r3,r5 |
625 | subf r4,r3,r4 | 625 | subf r4,r3,r4 |
@@ -736,7 +736,7 @@ _GLOBAL(flush_dcache_all) | |||
736 | _GLOBAL(__flush_dcache_icache) | 736 | _GLOBAL(__flush_dcache_icache) |
737 | BEGIN_FTR_SECTION | 737 | BEGIN_FTR_SECTION |
738 | blr /* for 601, do nothing */ | 738 | blr /* for 601, do nothing */ |
739 | END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE) | 739 | END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) |
740 | rlwinm r3,r3,0,0,19 /* Get page base address */ | 740 | rlwinm r3,r3,0,0,19 /* Get page base address */ |
741 | li r4,4096/L1_CACHE_LINE_SIZE /* Number of lines in a page */ | 741 | li r4,4096/L1_CACHE_LINE_SIZE /* Number of lines in a page */ |
742 | mtctr r4 | 742 | mtctr r4 |
@@ -764,7 +764,7 @@ END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE) | |||
764 | _GLOBAL(__flush_dcache_icache_phys) | 764 | _GLOBAL(__flush_dcache_icache_phys) |
765 | BEGIN_FTR_SECTION | 765 | BEGIN_FTR_SECTION |
766 | blr /* for 601, do nothing */ | 766 | blr /* for 601, do nothing */ |
767 | END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE) | 767 | END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) |
768 | mfmsr r10 | 768 | mfmsr r10 |
769 | rlwinm r0,r10,0,28,26 /* clear DR */ | 769 | rlwinm r0,r10,0,28,26 /* clear DR */ |
770 | mtmsr r0 | 770 | mtmsr r0 |
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index 2ccb58fe4fc3..d59ad07de8e7 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c | |||
@@ -55,7 +55,6 @@ | |||
55 | #define EXPORT_SYMTAB_STROPS | 55 | #define EXPORT_SYMTAB_STROPS |
56 | 56 | ||
57 | extern void transfer_to_handler(void); | 57 | extern void transfer_to_handler(void); |
58 | extern void do_syscall_trace(void); | ||
59 | extern void do_IRQ(struct pt_regs *regs); | 58 | extern void do_IRQ(struct pt_regs *regs); |
60 | extern void MachineCheckException(struct pt_regs *regs); | 59 | extern void MachineCheckException(struct pt_regs *regs); |
61 | extern void AlignmentException(struct pt_regs *regs); | 60 | extern void AlignmentException(struct pt_regs *regs); |
@@ -74,7 +73,6 @@ extern unsigned long mm_ptov (unsigned long paddr); | |||
74 | EXPORT_SYMBOL(clear_pages); | 73 | EXPORT_SYMBOL(clear_pages); |
75 | EXPORT_SYMBOL(clear_user_page); | 74 | EXPORT_SYMBOL(clear_user_page); |
76 | EXPORT_SYMBOL(do_signal); | 75 | EXPORT_SYMBOL(do_signal); |
77 | EXPORT_SYMBOL(do_syscall_trace); | ||
78 | EXPORT_SYMBOL(transfer_to_handler); | 76 | EXPORT_SYMBOL(transfer_to_handler); |
79 | EXPORT_SYMBOL(do_IRQ); | 77 | EXPORT_SYMBOL(do_IRQ); |
80 | EXPORT_SYMBOL(MachineCheckException); | 78 | EXPORT_SYMBOL(MachineCheckException); |
diff --git a/arch/ppc/kernel/ptrace.c b/arch/ppc/kernel/ptrace.c index 59d59a8dc249..e7aee4108dea 100644 --- a/arch/ppc/kernel/ptrace.c +++ b/arch/ppc/kernel/ptrace.c | |||
@@ -27,6 +27,9 @@ | |||
27 | #include <linux/user.h> | 27 | #include <linux/user.h> |
28 | #include <linux/security.h> | 28 | #include <linux/security.h> |
29 | #include <linux/signal.h> | 29 | #include <linux/signal.h> |
30 | #include <linux/seccomp.h> | ||
31 | #include <linux/audit.h> | ||
32 | #include <linux/module.h> | ||
30 | 33 | ||
31 | #include <asm/uaccess.h> | 34 | #include <asm/uaccess.h> |
32 | #include <asm/page.h> | 35 | #include <asm/page.h> |
@@ -455,11 +458,10 @@ out: | |||
455 | return ret; | 458 | return ret; |
456 | } | 459 | } |
457 | 460 | ||
458 | void do_syscall_trace(void) | 461 | static void do_syscall_trace(void) |
459 | { | 462 | { |
460 | if (!test_thread_flag(TIF_SYSCALL_TRACE) | 463 | /* the 0x80 provides a way for the tracing parent to distinguish |
461 | || !(current->ptrace & PT_PTRACED)) | 464 | between a syscall stop and SIGTRAP delivery */ |
462 | return; | ||
463 | ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) | 465 | ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) |
464 | ? 0x80 : 0)); | 466 | ? 0x80 : 0)); |
465 | 467 | ||
@@ -473,3 +475,33 @@ void do_syscall_trace(void) | |||
473 | current->exit_code = 0; | 475 | current->exit_code = 0; |
474 | } | 476 | } |
475 | } | 477 | } |
478 | |||
479 | void do_syscall_trace_enter(struct pt_regs *regs) | ||
480 | { | ||
481 | if (test_thread_flag(TIF_SYSCALL_TRACE) | ||
482 | && (current->ptrace & PT_PTRACED)) | ||
483 | do_syscall_trace(); | ||
484 | |||
485 | if (unlikely(current->audit_context)) | ||
486 | audit_syscall_entry(current, AUDIT_ARCH_PPC, | ||
487 | regs->gpr[0], | ||
488 | regs->gpr[3], regs->gpr[4], | ||
489 | regs->gpr[5], regs->gpr[6]); | ||
490 | } | ||
491 | |||
492 | void do_syscall_trace_leave(struct pt_regs *regs) | ||
493 | { | ||
494 | secure_computing(regs->gpr[0]); | ||
495 | |||
496 | if (unlikely(current->audit_context)) | ||
497 | audit_syscall_exit(current, | ||
498 | (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS, | ||
499 | regs->result); | ||
500 | |||
501 | if ((test_thread_flag(TIF_SYSCALL_TRACE)) | ||
502 | && (current->ptrace & PT_PTRACED)) | ||
503 | do_syscall_trace(); | ||
504 | } | ||
505 | |||
506 | EXPORT_SYMBOL(do_syscall_trace_enter); | ||
507 | EXPORT_SYMBOL(do_syscall_trace_leave); | ||
diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c index 937f46df711e..5fdd4f607a40 100644 --- a/arch/ppc/platforms/pmac_cpufreq.c +++ b/arch/ppc/platforms/pmac_cpufreq.c | |||
@@ -83,7 +83,7 @@ static u32 frequency_gpio; | |||
83 | static u32 slew_done_gpio; | 83 | static u32 slew_done_gpio; |
84 | static int no_schedule; | 84 | static int no_schedule; |
85 | static int has_cpu_l2lve; | 85 | static int has_cpu_l2lve; |
86 | 86 | static int is_pmu_based; | |
87 | 87 | ||
88 | /* There are only two frequency states for each processor. Values | 88 | /* There are only two frequency states for each processor. Values |
89 | * are in kHz for the time being. | 89 | * are in kHz for the time being. |
@@ -463,7 +463,7 @@ static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, u32 state) | |||
463 | */ | 463 | */ |
464 | no_schedule = 1; | 464 | no_schedule = 1; |
465 | sleep_freq = cur_freq; | 465 | sleep_freq = cur_freq; |
466 | if (cur_freq == low_freq) | 466 | if (cur_freq == low_freq && !is_pmu_based) |
467 | do_set_cpu_speed(CPUFREQ_HIGH, 0); | 467 | do_set_cpu_speed(CPUFREQ_HIGH, 0); |
468 | return 0; | 468 | return 0; |
469 | } | 469 | } |
@@ -588,6 +588,7 @@ static int __pmac pmac_cpufreq_init_MacRISC3(struct device_node *cpunode) | |||
588 | return 1; | 588 | return 1; |
589 | hi_freq = (*value) / 1000; | 589 | hi_freq = (*value) / 1000; |
590 | set_speed_proc = pmu_set_cpu_speed; | 590 | set_speed_proc = pmu_set_cpu_speed; |
591 | is_pmu_based = 1; | ||
591 | 592 | ||
592 | return 0; | 593 | return 0; |
593 | } | 594 | } |
@@ -692,6 +693,7 @@ static int __init pmac_cpufreq_setup(void) | |||
692 | hi_freq = cur_freq; | 693 | hi_freq = cur_freq; |
693 | low_freq = 400000; | 694 | low_freq = 400000; |
694 | set_speed_proc = pmu_set_cpu_speed; | 695 | set_speed_proc = pmu_set_cpu_speed; |
696 | is_pmu_based = 1; | ||
695 | } | 697 | } |
696 | /* Else check for TiPb 400 & 500 */ | 698 | /* Else check for TiPb 400 & 500 */ |
697 | else if (machine_is_compatible("PowerBook3,2")) { | 699 | else if (machine_is_compatible("PowerBook3,2")) { |
@@ -703,6 +705,7 @@ static int __init pmac_cpufreq_setup(void) | |||
703 | hi_freq = cur_freq; | 705 | hi_freq = cur_freq; |
704 | low_freq = 300000; | 706 | low_freq = 300000; |
705 | set_speed_proc = pmu_set_cpu_speed; | 707 | set_speed_proc = pmu_set_cpu_speed; |
708 | is_pmu_based = 1; | ||
706 | } | 709 | } |
707 | /* Else check for 750FX */ | 710 | /* Else check for 750FX */ |
708 | else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000) | 711 | else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000) |