From daf423db3b6afd90ecdd776dbc32c0b57cc78edb Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Wed, 30 Jul 2008 10:29:39 +1000 Subject: kdump: sh: parse elfcorehdr command line argument A quick cut and paste from other architectures to allow SH to parse the elfcorehdr command line argument which is required for both is_kdump_kernel() and vmcore to function. (the former is as yet unused on SH). Tested compilation only Signed-off-by: Simon Horman Signed-off-by: Paul Mundt --- arch/sh/kernel/setup.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 6339d0c9571..a35207655e7 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -286,6 +287,25 @@ static void __init setup_memory(void) extern void __init setup_memory(void); #endif +/* + * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by + * is_kdump_kernel() to determine if we are booting after a panic. Hence + * ifdef it under CONFIG_CRASH_DUMP and not CONFIG_PROC_VMCORE. + */ +#ifdef CONFIG_CRASH_DUMP +/* elfcorehdr= specifies the location of elf core header + * stored by the crashed kernel. + */ +static int __init parse_elfcorehdr(char *arg) +{ + if (!arg) + return -EINVAL; + elfcorehdr_addr = memparse(arg, &arg); + return 0; +} +early_param("elfcorehdr", parse_elfcorehdr); +#endif + void __init setup_arch(char **cmdline_p) { enable_mmu(); -- cgit v1.2.3 From cec3fd3e2a7cacf37e2bd6d9fa915337245cc563 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 30 Jul 2008 13:11:26 +0900 Subject: sh: Tidy up the _TIF work masks, and fix syscall trace bug on singlestep. Signed-off-by: Paul Mundt --- arch/sh/include/asm/thread_info.h | 40 +++++++++++++++++++++++++++------------ arch/sh/kernel/cpu/sh5/entry.S | 2 +- arch/sh/kernel/entry-common.S | 4 ++-- 3 files changed, 31 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h index eeb4c747119..c05b1afd132 100644 --- a/arch/sh/include/asm/thread_info.h +++ b/arch/sh/include/asm/thread_info.h @@ -123,18 +123,34 @@ static inline struct thread_info *current_thread_info(void) #define TIF_MEMDIE 18 #define TIF_FREEZE 19 -#define _TIF_SYSCALL_TRACE (1<flags ! r8: current_thread_info - tst #_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | _TIF_SYSCALL_AUDIT, r0 + tst #_TIF_WORK_SYSCALL_MASK, r0 bt/s work_pending tst #_TIF_NEED_RESCHED, r0 #ifdef CONFIG_TRACE_IRQFLAGS @@ -351,7 +351,7 @@ ENTRY(system_call) ! get_current_thread_info r8, r10 mov.l @(TI_FLAGS,r8), r8 - mov #(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT), r10 + mov #_TIF_WORK_SYSCALL_MASK, r10 tst r10, r8 bf syscall_trace_entry ! -- cgit v1.2.3 From c4637d475170ca0d99973efd07df727012db6cd1 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 30 Jul 2008 15:30:52 +0900 Subject: sh: seccomp support. This hooks up the seccomp thread flag and associated callback from the syscall tracer. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 17 +++++++++++++++++ arch/sh/include/asm/seccomp.h | 10 ++++++++++ arch/sh/include/asm/thread_info.h | 6 ++++-- arch/sh/kernel/ptrace_32.c | 3 +++ arch/sh/kernel/ptrace_64.c | 3 +++ 5 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 arch/sh/include/asm/seccomp.h (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index cb992c3d6b7..0ae541107f3 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -483,6 +483,23 @@ config CRASH_DUMP For more details see Documentation/kdump/kdump.txt +config SECCOMP + bool "Enable seccomp to safely compute untrusted bytecode" + depends on PROC_FS + default y + help + This kernel feature is useful for number crunching applications + that may need to compute untrusted bytecode during their + execution. By using pipes or other transports made available to + the process as file descriptors supporting the read/write + syscalls, it's possible to isolate those applications in + their own address space using seccomp. Once seccomp is + enabled via prctl, it cannot be disabled and the task is only + allowed to execute a few safe syscalls defined by each seccomp + mode. + + If unsure, say N. + config SMP bool "Symmetric multi-processing support" depends on SYS_SUPPORTS_SMP diff --git a/arch/sh/include/asm/seccomp.h b/arch/sh/include/asm/seccomp.h new file mode 100644 index 00000000000..3280ed3802e --- /dev/null +++ b/arch/sh/include/asm/seccomp.h @@ -0,0 +1,10 @@ +#ifndef __ASM_SECCOMP_H + +#include + +#define __NR_seccomp_read __NR_read +#define __NR_seccomp_write __NR_write +#define __NR_seccomp_exit __NR_exit +#define __NR_seccomp_sigreturn __NR_rt_sigreturn + +#endif /* __ASM_SECCOMP_H */ diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h index c05b1afd132..03d1e386670 100644 --- a/arch/sh/include/asm/thread_info.h +++ b/arch/sh/include/asm/thread_info.h @@ -117,7 +117,8 @@ static inline struct thread_info *current_thread_info(void) #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ #define TIF_RESTORE_SIGMASK 3 /* restore signal mask in do_signal() */ #define TIF_SINGLESTEP 4 /* singlestepping active */ -#define TIF_SYSCALL_AUDIT 5 +#define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */ +#define TIF_SECCOMP 6 /* secure computing */ #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_MEMDIE 18 @@ -129,6 +130,7 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) +#define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_USEDFPU (1 << TIF_USEDFPU) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_FREEZE (1 << TIF_FREEZE) @@ -141,7 +143,7 @@ static inline struct thread_info *current_thread_info(void) /* work to do in syscall trace */ #define _TIF_WORK_SYSCALL_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \ - _TIF_SYSCALL_AUDIT) + _TIF_SYSCALL_AUDIT | _TIF_SECCOMP) /* work to do on any return to u-space */ #define _TIF_ALLWORK_MASK (_TIF_SYSCALL_TRACE | _TIF_SIGPENDING | \ diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c index 2bc72def5cf..e9bd4b2aa9c 100644 --- a/arch/sh/kernel/ptrace_32.c +++ b/arch/sh/kernel/ptrace_32.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -276,6 +277,8 @@ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) { struct task_struct *tsk = current; + secure_computing(regs->regs[0]); + if (unlikely(current->audit_context) && entryexit) audit_syscall_exit(AUDITSC_RESULT(regs->regs[0]), regs->regs[0]); diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c index d453c47dc52..7d877626095 100644 --- a/arch/sh/kernel/ptrace_64.c +++ b/arch/sh/kernel/ptrace_64.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -277,6 +278,8 @@ asmlinkage void syscall_trace(struct pt_regs *regs, int entryexit) { struct task_struct *tsk = current; + secure_computing(regs->regs[9]); + if (unlikely(current->audit_context) && entryexit) audit_syscall_exit(AUDITSC_RESULT(regs->regs[9]), regs->regs[9]); -- cgit v1.2.3 From c459dbf294b4a3d70490a468a7ca3907fb2c2f57 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 30 Jul 2008 19:09:31 +0900 Subject: sh: ptrace single stepping cleanups. This converts the single stepping done by sh/sh64 ptrace implementations to use the generic user_enable/disable_single_step(), and subsequently rips out a lot of ptrace request cases that are now handled generically. Signed-off-by: Paul Mundt --- arch/sh/include/asm/ptrace.h | 9 +++++ arch/sh/kernel/ptrace_32.c | 93 +++++++++----------------------------------- arch/sh/kernel/ptrace_64.c | 77 ++++++------------------------------ 3 files changed, 39 insertions(+), 140 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h index 643ab5a7cf3..b86aeabba61 100644 --- a/arch/sh/include/asm/ptrace.h +++ b/arch/sh/include/asm/ptrace.h @@ -104,6 +104,15 @@ struct pt_dspregs { extern void show_regs(struct pt_regs *); +/* + * These are defined as per linux/ptrace.h. + */ +struct task_struct; + +#define arch_has_single_step() (1) +extern void user_enable_single_step(struct task_struct *); +extern void user_disable_single_step(struct task_struct *); + #ifdef CONFIG_SH_DSP #define task_pt_regs(task) \ ((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE \ diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c index e9bd4b2aa9c..ff66f97c564 100644 --- a/arch/sh/kernel/ptrace_32.c +++ b/arch/sh/kernel/ptrace_32.c @@ -58,7 +58,23 @@ static inline int put_stack_long(struct task_struct *task, int offset, return 0; } -static void ptrace_disable_singlestep(struct task_struct *child) +void user_enable_single_step(struct task_struct *child) +{ + struct pt_regs *regs = task_pt_regs(child); + long pc; + + pc = get_stack_long(child, (long)®s->pc); + + /* Next scheduling will set up UBC */ + if (child->thread.ubc_pc == 0) + ubc_usercnt += 1; + + child->thread.ubc_pc = pc; + + set_tsk_thread_flag(child, TIF_SINGLESTEP); +} + +void user_disable_single_step(struct task_struct *child) { clear_tsk_thread_flag(child, TIF_SINGLESTEP); @@ -82,7 +98,7 @@ static void ptrace_disable_singlestep(struct task_struct *child) */ void ptrace_disable(struct task_struct *child) { - ptrace_disable_singlestep(child); + user_disable_single_step(child); } long arch_ptrace(struct task_struct *child, long request, long addr, long data) @@ -91,12 +107,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) int ret; switch (request) { - /* when I and D space are separate, these will need to be fixed. */ - case PTRACE_PEEKTEXT: /* read word at location addr. */ - case PTRACE_PEEKDATA: - ret = generic_ptrace_peekdata(child, addr, data); - break; - /* read the word at location addr in the USER area. */ case PTRACE_PEEKUSR: { unsigned long tmp; @@ -126,12 +136,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; } - /* when I and D space are separate, this will have to be fixed. */ - case PTRACE_POKETEXT: /* write the word at location addr. */ - case PTRACE_POKEDATA: - ret = generic_ptrace_pokedata(child, addr, data); - break; - case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ ret = -EIO; if ((addr & 3) || addr < 0 || @@ -152,67 +156,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) } break; - case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ - case PTRACE_CONT: { /* restart after signal. */ - ret = -EIO; - if (!valid_signal(data)) - break; - if (request == PTRACE_SYSCALL) - set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - else - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - - ptrace_disable_singlestep(child); - - child->exit_code = data; - wake_up_process(child); - ret = 0; - break; - } - -/* - * make the child exit. Best I can do is send it a sigkill. - * perhaps it should be put in the status that it wants to - * exit. - */ - case PTRACE_KILL: { - ret = 0; - if (child->exit_state == EXIT_ZOMBIE) /* already dead */ - break; - ptrace_disable_singlestep(child); - child->exit_code = SIGKILL; - wake_up_process(child); - break; - } - - case PTRACE_SINGLESTEP: { /* set the trap flag. */ - long pc; - struct pt_regs *regs = NULL; - - ret = -EIO; - if (!valid_signal(data)) - break; - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - if ((child->ptrace & PT_DTRACE) == 0) { - /* Spurious delayed TF traps may occur */ - child->ptrace |= PT_DTRACE; - } - - pc = get_stack_long(child, (long)®s->pc); - - /* Next scheduling will set up UBC */ - if (child->thread.ubc_pc == 0) - ubc_usercnt += 1; - child->thread.ubc_pc = pc; - - set_tsk_thread_flag(child, TIF_SINGLESTEP); - child->exit_code = data; - /* give it a chance to run. */ - wake_up_process(child); - ret = 0; - break; - } - #ifdef CONFIG_SH_DSP case PTRACE_GETDSPREGS: { unsigned long dp; diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c index 7d877626095..108f3962e39 100644 --- a/arch/sh/kernel/ptrace_64.c +++ b/arch/sh/kernel/ptrace_64.c @@ -121,18 +121,23 @@ put_fpu_long(struct task_struct *task, unsigned long addr, unsigned long data) return 0; } +void user_enable_single_step(struct task_struct *child) +{ + struct pt_regs *regs = child->thread.uregs; + + regs->sr |= SR_SSTEP; /* auto-resetting upon exception */ +} + +void user_disable_single_step(struct task_struct *child) +{ + regs->sr &= ~SR_SSTEP; +} long arch_ptrace(struct task_struct *child, long request, long addr, long data) { int ret; switch (request) { - /* when I and D space are separate, these will need to be fixed. */ - case PTRACE_PEEKTEXT: /* read word at location addr. */ - case PTRACE_PEEKDATA: - ret = generic_ptrace_peekdata(child, addr, data); - break; - /* read the word at location addr in the USER area. */ case PTRACE_PEEKUSR: { unsigned long tmp; @@ -155,12 +160,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; } - /* when I and D space are separate, this will have to be fixed. */ - case PTRACE_POKETEXT: /* write the word at location addr. */ - case PTRACE_POKEDATA: - ret = generic_ptrace_pokedata(child, addr, data); - break; - case PTRACE_POKEUSR: /* write the word at location addr in the USER area. We must disallow any changes to certain SR bits or u_fpvalid, since @@ -192,58 +191,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) } break; - case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ - case PTRACE_CONT: { /* restart after signal. */ - ret = -EIO; - if (!valid_signal(data)) - break; - if (request == PTRACE_SYSCALL) - set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - else - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - child->exit_code = data; - wake_up_process(child); - ret = 0; - break; - } - -/* - * make the child exit. Best I can do is send it a sigkill. - * perhaps it should be put in the status that it wants to - * exit. - */ - case PTRACE_KILL: { - ret = 0; - if (child->exit_state == EXIT_ZOMBIE) /* already dead */ - break; - child->exit_code = SIGKILL; - wake_up_process(child); - break; - } - - case PTRACE_SINGLESTEP: { /* set the trap flag. */ - struct pt_regs *regs; - - ret = -EIO; - if (!valid_signal(data)) - break; - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - if ((child->ptrace & PT_DTRACE) == 0) { - /* Spurious delayed TF traps may occur */ - child->ptrace |= PT_DTRACE; - } - - regs = child->thread.uregs; - - regs->sr |= SR_SSTEP; /* auto-resetting upon exception */ - - child->exit_code = data; - /* give it a chance to run. */ - wake_up_process(child); - ret = 0; - break; - } - default: ret = ptrace_request(child, request, addr, data); break; @@ -341,5 +288,5 @@ asmlinkage void do_software_break_point(unsigned long long vec, */ void ptrace_disable(struct task_struct *child) { - /* nothing to do.. */ + user_disable_single_step(child); } -- cgit v1.2.3 From ab99c733ae73cce31f2a2434f7099564e5a73d95 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 30 Jul 2008 19:55:30 +0900 Subject: sh: Make syscall tracer use tracehook notifiers, add TIF_NOTIFY_RESUME. This follows the changes in commits: 7d6d637dac2050f30a1b57b0a3dc5de4a10616ba 4f72c4279eab1e5f3ed1ac4e55d4527617582392 on powerpc. Adding in TIF_NOTIFY_RESUME, and cleaning up the syscall tracing to be more generic. This is an incremental step to turning on tracehook, as well as unifying more of the ptrace and signal code across the 32/64 split. Signed-off-by: Paul Mundt --- arch/sh/include/asm/thread_info.h | 11 ++- arch/sh/kernel/cpu/sh5/entry.S | 17 ++-- arch/sh/kernel/entry-common.S | 12 ++- arch/sh/kernel/ptrace_32.c | 54 ++++++------- arch/sh/kernel/ptrace_64.c | 50 ++++++------ arch/sh/kernel/signal_32.c | 22 +++-- arch/sh/kernel/signal_64.c | 166 ++++++++++++++++++++------------------ 7 files changed, 174 insertions(+), 158 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h index 03d1e386670..0a894cafb1d 100644 --- a/arch/sh/include/asm/thread_info.h +++ b/arch/sh/include/asm/thread_info.h @@ -119,10 +119,11 @@ static inline struct thread_info *current_thread_info(void) #define TIF_SINGLESTEP 4 /* singlestepping active */ #define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */ #define TIF_SECCOMP 6 /* secure computing */ +#define TIF_NOTIFY_RESUME 7 /* callback before returning to user */ #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_MEMDIE 18 -#define TIF_FREEZE 19 +#define TIF_FREEZE 19 /* Freezing for suspend */ #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) @@ -131,6 +132,7 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SECCOMP (1 << TIF_SECCOMP) +#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_USEDFPU (1 << TIF_USEDFPU) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_FREEZE (1 << TIF_FREEZE) @@ -146,9 +148,10 @@ static inline struct thread_info *current_thread_info(void) _TIF_SYSCALL_AUDIT | _TIF_SECCOMP) /* work to do on any return to u-space */ -#define _TIF_ALLWORK_MASK (_TIF_SYSCALL_TRACE | _TIF_SIGPENDING | \ - _TIF_NEED_RESCHED | _TIF_SYSCALL_AUDIT | \ - _TIF_SINGLESTEP | _TIF_RESTORE_SIGMASK) +#define _TIF_ALLWORK_MASK (_TIF_SYSCALL_TRACE | _TIF_SIGPENDING | \ + _TIF_NEED_RESCHED | _TIF_SYSCALL_AUDIT | \ + _TIF_SINGLESTEP | _TIF_RESTORE_SIGMASK | \ + _TIF_NOTIFY_RESUME) /* work to do on interrupt/exception return */ #define _TIF_WORK_MASK (_TIF_ALLWORK_MASK & ~(_TIF_SYSCALL_TRACE | \ diff --git a/arch/sh/kernel/cpu/sh5/entry.S b/arch/sh/kernel/cpu/sh5/entry.S index bba331d5ef7..04c7da96814 100644 --- a/arch/sh/kernel/cpu/sh5/entry.S +++ b/arch/sh/kernel/cpu/sh5/entry.S @@ -987,11 +987,11 @@ work_resched: work_notifysig: gettr tr1, LINK - movi do_signal, r6 + movi do_notify_resume, r6 ptabs r6, tr0 or SP, ZERO, r2 - or ZERO, ZERO, r3 - blink tr0, LINK /* Call do_signal(regs, 0), return here */ + or r7, ZERO, r3 + blink tr0, LINK /* Call do_notify_resume(regs, current_thread_info->flags), return here */ restore_all: /* Do prefetches */ @@ -1305,13 +1305,15 @@ syscall_allowed: beq/l r6, ZERO, tr0 /* Trace it by calling syscall_trace before and after */ - movi syscall_trace, r4 + movi do_syscall_trace_enter, r4 or SP, ZERO, r2 - or ZERO, ZERO, r3 ptabs r4, tr0 blink tr0, LINK - /* Reload syscall number as r5 is trashed by syscall_trace */ + /* Save the retval */ + st.q SP, FRAME_R(2), r2 + + /* Reload syscall number as r5 is trashed by do_syscall_trace_enter */ ld.q SP, FRAME_S(FSYSCALL_ID), r5 andi r5, 0x1ff, r5 @@ -1343,9 +1345,8 @@ syscall_ret_trace: /* We get back here only if under trace */ st.q SP, FRAME_R(9), r2 /* Save return value */ - movi syscall_trace, LINK + movi do_syscall_trace_leave, LINK or SP, ZERO, r2 - movi 1, r3 ptabs LINK, tr0 blink tr0, LINK diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S index a34417c8ee0..0bc17def55a 100644 --- a/arch/sh/kernel/entry-common.S +++ b/arch/sh/kernel/entry-common.S @@ -211,10 +211,8 @@ syscall_exit_work: nop #endif sti - ! XXX setup arguments... mov r15, r4 - mov #1, r5 - mov.l 4f, r0 ! do_syscall_trace + mov.l 8f, r0 ! do_syscall_trace_leave jsr @r0 nop bra resume_userspace @@ -223,12 +221,11 @@ syscall_exit_work: .align 2 syscall_trace_entry: ! Yes it is traced. - ! XXX setup arguments... mov r15, r4 - mov #0, r5 - mov.l 4f, r11 ! Call do_syscall_trace which notifies + mov.l 7f, r11 ! Call do_syscall_trace_enter which notifies jsr @r11 ! superior (will chomp R[0-7]) nop + mov.l r0, @(OFF_R0,r15) ! Save return value ! Reload R0-R4 from kernel stack, where the ! parent may have modified them using ! ptrace(POKEUSR). (Note that R0-R2 are @@ -389,8 +386,9 @@ syscall_exit: #endif 2: .long NR_syscalls 3: .long sys_call_table -4: .long do_syscall_trace #ifdef CONFIG_TRACE_IRQFLAGS 5: .long trace_hardirqs_on 6: .long trace_hardirqs_off #endif +7: .long do_syscall_trace_enter +8: .long do_syscall_trace_leave diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c index ff66f97c564..f48769b23bd 100644 --- a/arch/sh/kernel/ptrace_32.c +++ b/arch/sh/kernel/ptrace_32.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -216,41 +217,38 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) return ret; } -asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) +asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) { - struct task_struct *tsk = current; + long ret = 0; secure_computing(regs->regs[0]); - if (unlikely(current->audit_context) && entryexit) - audit_syscall_exit(AUDITSC_RESULT(regs->regs[0]), - regs->regs[0]); - - if (!test_thread_flag(TIF_SYSCALL_TRACE) && - !test_thread_flag(TIF_SINGLESTEP)) - goto out; - if (!(tsk->ptrace & PT_PTRACED)) - goto out; - - /* the 0x80 provides a way for the tracing parent to distinguish - between a syscall stop and SIGTRAP delivery */ - ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) && - !test_thread_flag(TIF_SINGLESTEP) ? 0x80 : 0)); - - /* - * this isn't the same as continuing with a signal, but it will do - * for normal use. strace only continues with a signal if the - * stopping signal is not SIGTRAP. -brl - */ - if (tsk->exit_code) { - send_sig(tsk->exit_code, tsk, 1); - tsk->exit_code = 0; - } + if (test_thread_flag(TIF_SYSCALL_TRACE) && + tracehook_report_syscall_entry(regs)) + /* + * Tracing decided this syscall should not happen. + * We'll return a bogus call number to get an ENOSYS + * error, but leave the original number in regs->regs[0]. + */ + ret = -1L; -out: - if (unlikely(current->audit_context) && !entryexit) + if (unlikely(current->audit_context)) audit_syscall_entry(AUDIT_ARCH_SH, regs->regs[3], regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); + return ret ?: regs->regs[0]; +} + +asmlinkage void do_syscall_trace_leave(struct pt_regs *regs) +{ + int step; + + if (unlikely(current->audit_context)) + audit_syscall_exit(AUDITSC_RESULT(regs->regs[0]), + regs->regs[0]); + + step = test_thread_flag(TIF_SINGLESTEP); + if (step || test_thread_flag(TIF_SYSCALL_TRACE)) + tracehook_report_syscall_exit(regs, step); } diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c index 108f3962e39..236d8bef9cc 100644 --- a/arch/sh/kernel/ptrace_64.c +++ b/arch/sh/kernel/ptrace_64.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -221,40 +222,37 @@ asmlinkage int sh64_ptrace(long request, long pid, long addr, long data) return sys_ptrace(request, pid, addr, data); } -asmlinkage void syscall_trace(struct pt_regs *regs, int entryexit) +asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs) { - struct task_struct *tsk = current; + long long ret = 0; secure_computing(regs->regs[9]); - if (unlikely(current->audit_context) && entryexit) - audit_syscall_exit(AUDITSC_RESULT(regs->regs[9]), - regs->regs[9]); - - if (!test_thread_flag(TIF_SYSCALL_TRACE) && - !test_thread_flag(TIF_SINGLESTEP)) - goto out; - if (!(tsk->ptrace & PT_PTRACED)) - goto out; - - ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) && - !test_thread_flag(TIF_SINGLESTEP) ? 0x80 : 0)); - - /* - * this isn't the same as continuing with a signal, but it will do - * for normal use. strace only continues with a signal if the - * stopping signal is not SIGTRAP. -brl - */ - if (tsk->exit_code) { - send_sig(tsk->exit_code, tsk, 1); - tsk->exit_code = 0; - } + if (test_thread_flag(TIF_SYSCALL_TRACE) && + tracehook_report_syscall_entry(regs)) + /* + * Tracing decided this syscall should not happen. + * We'll return a bogus call number to get an ENOSYS + * error, but leave the original number in regs->regs[0]. + */ + ret = -1LL; -out: - if (unlikely(current->audit_context) && !entryexit) + if (unlikely(current->audit_context)) audit_syscall_entry(AUDIT_ARCH_SH, regs->regs[1], regs->regs[2], regs->regs[3], regs->regs[4], regs->regs[5]); + + return ret ?: regs->regs[9]; +} + +asmlinkage void do_syscall_trace_leave(struct pt_regs *regs) +{ + if (unlikely(current->audit_context)) + audit_syscall_exit(AUDITSC_RESULT(regs->regs[9]), + regs->regs[9]); + + if (test_thread_flag(TIF_SYSCALL_TRACE)) + tracehook_report_syscall_exit(regs, 0); } /* Called with interrupts disabled */ diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c index 4bbbde895a5..51689d29ad4 100644 --- a/arch/sh/kernel/signal_32.c +++ b/arch/sh/kernel/signal_32.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -507,14 +508,13 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, switch (regs->regs[0]) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: + no_system_call_restart: regs->regs[0] = -EINTR; break; case -ERESTARTSYS: - if (!(ka->sa.sa_flags & SA_RESTART)) { - regs->regs[0] = -EINTR; - break; - } + if (!(ka->sa.sa_flags & SA_RESTART)) + goto no_system_call_restart; /* fallthrough */ case -ERESTARTNOINTR: regs->regs[0] = save_r0; @@ -589,12 +589,15 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0) * clear the TIF_RESTORE_SIGMASK flag */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) clear_thread_flag(TIF_RESTORE_SIGMASK); + + tracehook_signal_handler(signr, &info, &ka, regs, + test_thread_flag(TIF_SINGLESTEP)); } return; } - no_signal: +no_signal: /* Did we come from a system call? */ if (regs->tra >= 0) { /* Restart the system call - no handlers present */ @@ -618,9 +621,14 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0) } asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned int save_r0, - __u32 thread_info_flags) + unsigned long thread_info_flags) { /* deal with pending signal delivery */ - if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) + if (thread_info_flags & _TIF_SIGPENDING) do_signal(regs, save_r0); + + if (thread_info_flags & _TIF_NOTIFY_RESUME) { + clear_thread_flag(TIF_NOTIFY_RESUME); + tracehook_notify_resume(regs); + } } diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c index 552eb810cd8..1d62dfef77f 100644 --- a/arch/sh/kernel/signal_64.c +++ b/arch/sh/kernel/signal_64.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -42,7 +43,84 @@ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) -asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); +/* + * Note that 'init' is a special process: it doesn't get signals it doesn't + * want to handle. Thus you cannot kill init even with a SIGKILL even by + * mistake. + * + * Note that we go through the signals twice: once to check the signals that + * the kernel can handle, and then we build all the user-level signal handling + * stack-frames in one go after that. + */ +static int do_signal(struct pt_regs *regs, sigset_t *oldset) +{ + siginfo_t info; + int signr; + struct k_sigaction ka; + + /* + * We want the common case to go fast, which + * is why we may in certain cases get here from + * kernel mode. Just return without doing anything + * if so. + */ + if (!user_mode(regs)) + return 1; + + if (try_to_freeze()) + goto no_signal; + + if (test_thread_flag(TIF_RESTORE_SIGMASK)) + oldset = ¤t->saved_sigmask; + else if (!oldset) + oldset = ¤t->blocked; + + signr = get_signal_to_deliver(&info, &ka, regs, 0); + + if (signr > 0) { + /* Whee! Actually deliver the signal. */ + handle_signal(signr, &info, &ka, oldset, regs); + + /* + * If a signal was successfully delivered, the saved sigmask + * is in its frame, and we can clear the TIF_RESTORE_SIGMASK + * flag. + */ + if (test_thread_flag(TIF_RESTORE_SIGMASK)) + clear_thread_flag(TIF_RESTORE_SIGMASK); + + tracehook_signal_handler(signr, &info, &ka, regs, 0); + return 1; + } + +no_signal: + /* Did we come from a system call? */ + if (regs->syscall_nr >= 0) { + /* Restart the system call - no handlers present */ + switch (regs->regs[REG_RET]) { + case -ERESTARTNOHAND: + case -ERESTARTSYS: + case -ERESTARTNOINTR: + /* Decode Syscall # */ + regs->regs[REG_RET] = regs->syscall_nr; + regs->pc -= 4; + break; + + case -ERESTART_RESTARTBLOCK: + regs->regs[REG_RET] = __NR_restart_syscall; + regs->pc -= 4; + break; + } + } + + /* No signal to deliver -- put the saved sigmask back */ + if (test_thread_flag(TIF_RESTORE_SIGMASK)) { + clear_thread_flag(TIF_RESTORE_SIGMASK); + sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); + } + + return 0; +} /* * Atomically swap in the new signal mask, and wait for a signal. @@ -643,14 +721,13 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, switch (regs->regs[REG_RET]) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: + no_system_call_restart: regs->regs[REG_RET] = -EINTR; break; case -ERESTARTSYS: - if (!(ka->sa.sa_flags & SA_RESTART)) { - regs->regs[REG_RET] = -EINTR; - break; - } + if (!(ka->sa.sa_flags & SA_RESTART)) + goto no_system_call_restart; /* fallthrough */ case -ERESTARTNOINTR: /* Decode syscall # */ @@ -673,80 +750,13 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, spin_unlock_irq(¤t->sighand->siglock); } -/* - * Note that 'init' is a special process: it doesn't get signals it doesn't - * want to handle. Thus you cannot kill init even with a SIGKILL even by - * mistake. - * - * Note that we go through the signals twice: once to check the signals that - * the kernel can handle, and then we build all the user-level signal handling - * stack-frames in one go after that. - */ -int do_signal(struct pt_regs *regs, sigset_t *oldset) +asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) { - siginfo_t info; - int signr; - struct k_sigaction ka; - - /* - * We want the common case to go fast, which - * is why we may in certain cases get here from - * kernel mode. Just return without doing anything - * if so. - */ - if (!user_mode(regs)) - return 1; - - if (try_to_freeze()) - goto no_signal; - - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - oldset = ¤t->saved_sigmask; - else if (!oldset) - oldset = ¤t->blocked; - - signr = get_signal_to_deliver(&info, &ka, regs, 0); - - if (signr > 0) { - /* Whee! Actually deliver the signal. */ - handle_signal(signr, &info, &ka, oldset, regs); + if (thread_info_flags & _TIF_SIGPENDING) + do_signal(regs, 0); - /* - * If a signal was successfully delivered, the saved sigmask - * is in its frame, and we can clear the TIF_RESTORE_SIGMASK - * flag. - */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - clear_thread_flag(TIF_RESTORE_SIGMASK); - - return 1; + if (thread_info_flags & _TIF_NOTIFY_RESUME) { + clear_thread_flag(TIF_NOTIFY_RESUME); + tracehook_notify_resume(regs); } - -no_signal: - /* Did we come from a system call? */ - if (regs->syscall_nr >= 0) { - /* Restart the system call - no handlers present */ - switch (regs->regs[REG_RET]) { - case -ERESTARTNOHAND: - case -ERESTARTSYS: - case -ERESTARTNOINTR: - /* Decode Syscall # */ - regs->regs[REG_RET] = regs->syscall_nr; - regs->pc -= 4; - break; - - case -ERESTART_RESTARTBLOCK: - regs->regs[REG_RET] = __NR_restart_syscall; - regs->pc -= 4; - break; - } - } - - /* No signal to deliver -- put the saved sigmask back */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { - clear_thread_flag(TIF_RESTORE_SIGMASK); - sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); - } - - return 0; } -- cgit v1.2.3 From 9e5e21170e4de269cd5b9d53ac9d60d220e3be63 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 30 Jul 2008 20:05:35 +0900 Subject: sh: Fix up the audit arch endian specification. Presently this was always being set to AUDIT_ARCH_SH, which assumes big endian. Fix this up so that the architecture actually reflects what we're running on. Signed-off-by: Paul Mundt --- arch/sh/kernel/ptrace_32.c | 13 ++++++++++++- arch/sh/kernel/ptrace_64.c | 16 +++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c index f48769b23bd..035cb300d3d 100644 --- a/arch/sh/kernel/ptrace_32.c +++ b/arch/sh/kernel/ptrace_32.c @@ -217,6 +217,17 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) return ret; } +static inline int audit_arch(void) +{ + int arch = EM_SH; + +#ifdef CONFIG_CPU_LITTLE_ENDIAN + arch |= __AUDIT_ARCH_LE; +#endif + + return arch; +} + asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) { long ret = 0; @@ -233,7 +244,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) ret = -1L; if (unlikely(current->audit_context)) - audit_syscall_entry(AUDIT_ARCH_SH, regs->regs[3], + audit_syscall_entry(audit_arch(), regs->regs[3], regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c index 236d8bef9cc..5922edd416d 100644 --- a/arch/sh/kernel/ptrace_64.c +++ b/arch/sh/kernel/ptrace_64.c @@ -222,6 +222,20 @@ asmlinkage int sh64_ptrace(long request, long pid, long addr, long data) return sys_ptrace(request, pid, addr, data); } +static inline int audit_arch(void) +{ + int arch = EM_SH; + +#ifdef CONFIG_64BIT + arch |= __AUDIT_ARCH_64BIT; +#endif +#ifdef CONFIG_CPU_LITTLE_ENDIAN + arch |= __AUDIT_ARCH_LE; +#endif + + return arch; +} + asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs) { long long ret = 0; @@ -238,7 +252,7 @@ asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs) ret = -1LL; if (unlikely(current->audit_context)) - audit_syscall_entry(AUDIT_ARCH_SH, regs->regs[1], + audit_syscall_entry(audit_arch(), regs->regs[1], regs->regs[2], regs->regs[3], regs->regs[4], regs->regs[5]); -- cgit v1.2.3 From 4385e12b291a6816987cb88a74fc116f520180f8 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sat, 2 Aug 2008 07:14:09 +0900 Subject: sh: Revert the location change of auto-generated asm/machtypes.h This ended up causing build breakage on O= builds, as reported by Adrian: <-- snip --> ... CC init/main.o In file included from /home/bunk/linux/kernel-2.6/git/linux-2.6/arch/sh/include/asm/irq.h:4, from /home/bunk/linux/kernel-2.6/git/linux-2.6/include/linux/irq.h:23, from /home/bunk/linux/kernel-2.6/git/linux-2.6/arch/sh/include/asm/hardirq.h:5, from /home/bunk/linux/kernel-2.6/git/linux-2.6/include/linux/hardirq.h:7, from /home/bunk/linux/kernel-2.6/git/linux-2.6/include/asm-generic/local.h:5, from /home/bunk/linux/kernel-2.6/git/linux-2.6/arch/sh/include/asm/local.h:4, from /home/bunk/linux/kernel-2.6/git/linux-2.6/include/linux/module.h:19, from /home/bunk/linux/kernel-2.6/git/linux-2.6/init/main.c:13: /home/bunk/linux/kernel-2.6/git/linux-2.6/arch/sh/include/asm/machvec.h:15:27: error: asm/machtypes.h: No such file or directory make[2]: *** [init/main.o] Error 1 <-- snip --> So we simply move machtypes.h back to its original place. asm-offsets.h is still generated there regardless, until such a time that we find a better place to stash auto-generated files. Reported-by: Adrian Bunk Signed-off-by: Paul Mundt --- arch/sh/Makefile | 4 ++-- arch/sh/tools/Makefile | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 25659ce74ba..7b70cfd2516 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -164,7 +164,7 @@ KBUILD_AFLAGS += $(cflags-y) PHONY += maketools FORCE maketools: include/linux/version.h FORCE - $(Q)$(MAKE) $(build)=arch/sh/tools arch/sh/include/asm/machtypes.h + $(Q)$(MAKE) $(build)=arch/sh/tools include/asm-sh/machtypes.h all: $(KBUILD_IMAGE) @@ -215,4 +215,4 @@ arch/sh/lib64/syscalltab.h: arch/sh/kernel/syscalls_64.S $(call filechk,gen-syscalltab) CLEAN_FILES += arch/sh/lib64/syscalltab.h \ - arch/sh/include/asm/machtypes.h + include/asm-sh/machtypes.h diff --git a/arch/sh/tools/Makefile b/arch/sh/tools/Makefile index b5d202be820..567516b58ac 100644 --- a/arch/sh/tools/Makefile +++ b/arch/sh/tools/Makefile @@ -10,7 +10,7 @@ # Shamelessly cloned from ARM. # -arch/sh/include/asm/machtypes.h: $(src)/gen-mach-types $(src)/mach-types +include/asm-sh/machtypes.h: $(src)/gen-mach-types $(src)/mach-types @echo ' Generating $@' - $(Q)if [ ! -d arch/sh/include/asm ]; then mkdir -p arch/sh/include/asm; fi + $(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi $(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; } -- cgit v1.2.3 From 49de935c107a53b0eba336efceb1dc3a8be64f87 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 2 Aug 2008 01:13:44 +0300 Subject: sh: fix LIBGCC Commit f15cbe6f1a4b4d9df59142fc8e4abb973302cf44 (sh: migrate to arch/sh/include/) moved KBUILD_CFLAGS (which is used by LIBGCC) below LIBGCC, causing build errors like the following: <-- snip --> ... LD .tmp_vmlinux1 arch/sh/kernel/built-in.o: In function `module_clk_recalc': clock-sh4.c:(.text+0x80f0): undefined reference to `__udivsi3_i4i' ... make[1]: *** [.tmp_vmlinux1] Error 1 <-- snip --> Reported-by: Adrian Bunk Signed-off-by: Adrian Bunk Signed-off-by: Paul Mundt --- arch/sh/Makefile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 7b70cfd2516..01d85c74481 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -95,8 +95,6 @@ head-y := arch/sh/kernel/init_task.o head-$(CONFIG_SUPERH32) += arch/sh/kernel/head_32.o head-$(CONFIG_SUPERH64) += arch/sh/kernel/head_64.o -LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) - core-y += arch/sh/kernel/ arch/sh/mm/ arch/sh/boards/ core-$(CONFIG_SH_FPU_EMU) += arch/sh/math-emu/ @@ -145,10 +143,6 @@ cpuincdir-$(CONFIG_CPU_SH4) += cpu-sh4 cpuincdir-$(CONFIG_CPU_SH5) += cpu-sh5 cpuincdir-y += cpu-common # Must be last -libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y) -libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y) -libs-y += $(LIBGCC) - drivers-y += arch/sh/drivers/ drivers-$(CONFIG_OPROFILE) += arch/sh/oprofile/ @@ -161,6 +155,12 @@ KBUILD_CFLAGS += -pipe $(cflags-y) KBUILD_CPPFLAGS += $(cflags-y) KBUILD_AFLAGS += $(cflags-y) +LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) + +libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y) +libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y) +libs-y += $(LIBGCC) + PHONY += maketools FORCE maketools: include/linux/version.h FORCE -- cgit v1.2.3 From 596400f0f322c78347e35c197b66faf09a9c1e02 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 2 Aug 2008 19:53:44 +0300 Subject: sh/boards/Makefile typo fix The following build error was caused by an obvious typo: <-- snip --> ... LD arch/sh/mm/built-in.o make[2]: *** No rule to make target `arch/sh/boards/board-shmin..o', needed by `arch/sh/boards/built-in.o'. Stop. <-- snip --> Reported-by: Adrian Bunk Signed-off-by: Adrian Bunk Signed-off-by: Paul Mundt --- arch/sh/boards/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/boards/Makefile b/arch/sh/boards/Makefile index ff9b93c5a91..463022c7df3 100644 --- a/arch/sh/boards/Makefile +++ b/arch/sh/boards/Makefile @@ -5,4 +5,4 @@ obj-$(CONFIG_SH_AP325RXA) += board-ap325rxa.o obj-$(CONFIG_SH_MAGIC_PANEL_R2) += board-magicpanelr2.o obj-$(CONFIG_SH_RSK7203) += board-rsk7203.o obj-$(CONFIG_SH_SH7785LCR) += board-sh7785lcr.o -obj-$(CONFIG_SH_SHMIN) += board-shmin..o +obj-$(CONFIG_SH_SHMIN) += board-shmin.o -- cgit v1.2.3 From 8edd744202e83ac2fce13f4898a90b403cc22141 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Sun, 3 Aug 2008 22:18:48 +0800 Subject: arch/sh/boards/board-ap325rxa.c: removed duplicated #include Removed duplicated include in arch/sh/boards/board-ap325rxa.c. Signed-off-by: Huang Weiyi Signed-off-by: Paul Mundt --- arch/sh/boards/board-ap325rxa.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/boards/board-ap325rxa.c b/arch/sh/boards/board-ap325rxa.c index 9c71603d29a..025d4fe55a5 100644 --- a/arch/sh/boards/board-ap325rxa.c +++ b/arch/sh/boards/board-ap325rxa.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From c48e64ae574a1e30a23174701560a222a192e4c3 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Sun, 3 Aug 2008 22:18:51 +0800 Subject: arch/sh/boards/mach-se/7343/irq.c: removed duplicated #include Removed duplicated include in arch/sh/boards/mach-se/7343/irq.c. Signed-off-by: Huang Weiyi Signed-off-by: Paul Mundt --- arch/sh/boards/mach-se/7343/irq.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/boards/mach-se/7343/irq.c b/arch/sh/boards/mach-se/7343/irq.c index 5d96e2eef82..051c29d4eae 100644 --- a/arch/sh/boards/mach-se/7343/irq.c +++ b/arch/sh/boards/mach-se/7343/irq.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include -- cgit v1.2.3 From c07abb6dbec754511427dd847f10cfdec6d36b3c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 4 Aug 2008 08:11:03 +0900 Subject: sh: /proc/asids depends on MMU. Signed-off-by: Paul Mundt --- arch/sh/Kconfig.debug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index 36f4b1f7066..4d2d102e00d 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug @@ -182,7 +182,7 @@ if SUPERH64 config SH64_PROC_ASIDS bool "Debug: report ASIDs through /proc/asids" - depends on PROC_FS + depends on PROC_FS && MMU config SH64_SR_WATCH bool "Debug: set SR.WATCH to enable hardware watchpoints and trace" -- cgit v1.2.3 From 6a9545bd95e88d61df942b9087cb59b8c7a6dc56 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 4 Aug 2008 12:51:06 +0900 Subject: sh: Fix up broken kerneldoc comments. These were completely unparseable, so fix them up. Signed-off-by: Paul Mundt --- arch/sh/include/asm/tlb_64.h | 12 +++--------- arch/sh/kernel/cpu/sh4/sq.c | 2 +- arch/sh/mm/tlb-sh5.c | 20 ++++++-------------- 3 files changed, 10 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/tlb_64.h b/arch/sh/include/asm/tlb_64.h index 0a96f3af69e..ef0ae2a28f2 100644 --- a/arch/sh/include/asm/tlb_64.h +++ b/arch/sh/include/asm/tlb_64.h @@ -21,11 +21,9 @@ #ifndef __ASSEMBLY__ /** - * for_each_dtlb_entry + * for_each_dtlb_entry - Iterate over free (non-wired) DTLB entries * * @tlb: TLB entry - * - * Iterate over free (non-wired) DTLB entries */ #define for_each_dtlb_entry(tlb) \ for (tlb = cpu_data->dtlb.first; \ @@ -33,11 +31,9 @@ tlb += cpu_data->dtlb.step) /** - * for_each_itlb_entry + * for_each_itlb_entry - Iterate over free (non-wired) ITLB entries * * @tlb: TLB entry - * - * Iterate over free (non-wired) ITLB entries */ #define for_each_itlb_entry(tlb) \ for (tlb = cpu_data->itlb.first; \ @@ -45,11 +41,9 @@ tlb += cpu_data->itlb.step) /** - * __flush_tlb_slot + * __flush_tlb_slot - Flushes TLB slot @slot. * * @slot: Address of TLB slot. - * - * Flushes TLB slot @slot. */ static inline void __flush_tlb_slot(unsigned long long slot) { diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c index dcdf959a3d4..8a8a993f55e 100644 --- a/arch/sh/kernel/cpu/sh4/sq.c +++ b/arch/sh/kernel/cpu/sh4/sq.c @@ -199,7 +199,7 @@ EXPORT_SYMBOL(sq_remap); /** * sq_unmap - Unmap a Store Queue allocation - * @map: Pre-allocated Store Queue mapping. + * @vaddr: Pre-allocated Store Queue mapping. * * Unmaps the store queue allocation @map that was previously created by * sq_remap(). Also frees up the pte that was previously inserted into diff --git a/arch/sh/mm/tlb-sh5.c b/arch/sh/mm/tlb-sh5.c index f34274a1ded..dae131243bc 100644 --- a/arch/sh/mm/tlb-sh5.c +++ b/arch/sh/mm/tlb-sh5.c @@ -15,9 +15,7 @@ #include /** - * sh64_tlb_init - * - * Perform initial setup for the DTLB and ITLB. + * sh64_tlb_init - Perform initial setup for the DTLB and ITLB. */ int __init sh64_tlb_init(void) { @@ -46,9 +44,7 @@ int __init sh64_tlb_init(void) } /** - * sh64_next_free_dtlb_entry - * - * Find the next available DTLB entry + * sh64_next_free_dtlb_entry - Find the next available DTLB entry */ unsigned long long sh64_next_free_dtlb_entry(void) { @@ -56,9 +52,7 @@ unsigned long long sh64_next_free_dtlb_entry(void) } /** - * sh64_get_wired_dtlb_entry - * - * Allocate a wired (locked-in) entry in the DTLB + * sh64_get_wired_dtlb_entry - Allocate a wired (locked-in) entry in the DTLB */ unsigned long long sh64_get_wired_dtlb_entry(void) { @@ -71,12 +65,10 @@ unsigned long long sh64_get_wired_dtlb_entry(void) } /** - * sh64_put_wired_dtlb_entry + * sh64_put_wired_dtlb_entry - Free a wired (locked-in) entry in the DTLB. * * @entry: Address of TLB slot. * - * Free a wired (locked-in) entry in the DTLB. - * * Works like a stack, last one to allocate must be first one to free. */ int sh64_put_wired_dtlb_entry(unsigned long long entry) @@ -115,7 +107,7 @@ int sh64_put_wired_dtlb_entry(unsigned long long entry) } /** - * sh64_setup_tlb_slot + * sh64_setup_tlb_slot - Load up a translation in a wired slot. * * @config_addr: Address of TLB slot. * @eaddr: Virtual address. @@ -154,7 +146,7 @@ inline void sh64_setup_tlb_slot(unsigned long long config_addr, } /** - * sh64_teardown_tlb_slot + * sh64_teardown_tlb_slot - Teardown a translation. * * @config_addr: Address of TLB slot. * -- cgit v1.2.3 From 3108cf061228c2c2951006c80fb6fe832000adda Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 4 Aug 2008 13:32:04 +0900 Subject: sh: Fix up __bug_table handling in module loader. We should be calling in to the lib/bug.c module helpers, fix that up. Signed-off-by: Paul Mundt --- arch/sh/kernel/module.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/kernel/module.c b/arch/sh/kernel/module.c index 5482e65375a..6ba2b79b826 100644 --- a/arch/sh/kernel/module.c +++ b/arch/sh/kernel/module.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -145,9 +146,10 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *me) { - return 0; + return module_bug_finalize(hdr, sechdrs, me); } void module_arch_cleanup(struct module *mod) { + module_bug_cleanup(mod); } -- cgit v1.2.3 From 4b59c97325371d51275bdb50523fa98a301615b0 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 4 Aug 2008 13:34:29 +0900 Subject: sh: module_alloc() should be using vmalloc_exec(). SH-X2 extended mode TLB allows for toggling of the exec bit, so make sure we are using the right protection bits for module space there also. Signed-off-by: Paul Mundt --- arch/sh/kernel/module.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/kernel/module.c b/arch/sh/kernel/module.c index 6ba2b79b826..c43081039dd 100644 --- a/arch/sh/kernel/module.c +++ b/arch/sh/kernel/module.c @@ -37,7 +37,8 @@ void *module_alloc(unsigned long size) { if (size == 0) return NULL; - return vmalloc(size); + + return vmalloc_exec(size); } -- cgit v1.2.3 From c3b4adfa65bae300a143188491e285556ca80fff Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 4 Aug 2008 13:42:49 +0900 Subject: sh: Save NUMA node data in vmcore for crash dumps. Presently the NUMA node data isn't saved on kexec. This implements a simple arch_crash_save_vmcoreinfo() for saving off the relevant data. Signed-off-by: Paul Mundt --- arch/sh/kernel/machine_kexec.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c index ec1eadce4aa..4703dff174d 100644 --- a/arch/sh/kernel/machine_kexec.c +++ b/arch/sh/kernel/machine_kexec.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -104,3 +105,10 @@ void machine_kexec(struct kimage *image) (*rnk)(page_list, reboot_code_buffer, image->start, vbr_reg); } +void arch_crash_save_vmcoreinfo(void) +{ +#ifdef CONFIG_NUMA + VMCOREINFO_SYMBOL(node_data); + VMCOREINFO_LENGTH(node_data, MAX_NUMNODES); +#endif +} -- cgit v1.2.3 From bdcab87b1c54f61dbc0a77648fee4c2b17964d5c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 4 Aug 2008 14:09:15 +0900 Subject: sh: define GENERIC_LOCKBREAK. Needed for fixing up the __raw_spin_is_contended() reference which results in a build error. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 0ae541107f3..37b91017818 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -63,6 +63,10 @@ config GENERIC_TIME config GENERIC_CLOCKEVENTS def_bool n +config GENERIC_LOCKBREAK + def_bool y + depends on SMP && PREEMPT + config SYS_SUPPORTS_PM bool -- cgit v1.2.3 From 5093c9a4e41518425d42c0bb5bb92f514ec77b1d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 4 Aug 2008 14:17:13 +0900 Subject: sh: define GENERIC_HARDIRQS_NO__DO_IRQ. We haven't called in to __do_IRQ() in a long time, so it seems like a reasonable time to switch this on by default. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 37b91017818..1a4dc766344 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -48,6 +48,9 @@ config GENERIC_HWEIGHT config GENERIC_HARDIRQS def_bool y +config GENERIC_HARDIRQS_NO__DO_IRQ + def_bool y + config GENERIC_IRQ_PROBE def_bool y -- cgit v1.2.3 From 42ced5561a3f49ba0ef09e94ccc016841fc94aa7 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 4 Aug 2008 14:18:53 +0900 Subject: sh: Kill off ARCH_SUPPORTS_AOUT and remnants of a.out support. SH never really supported a.out, so this was all just copied over blindly from x86 way back when. As we don't reference linux/a.out.h anywhere in the tree, these can now safely be killed off. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 3 --- arch/sh/include/asm/a.out.h | 20 -------------------- 2 files changed, 23 deletions(-) delete mode 100644 arch/sh/include/asm/a.out.h (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 1a4dc766344..5131d50f851 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -101,9 +101,6 @@ config ARCH_HAS_ILOG2_U64 config ARCH_NO_VIRT_TO_BUS def_bool y -config ARCH_SUPPORTS_AOUT - def_bool y - config IO_TRAPPED bool diff --git a/arch/sh/include/asm/a.out.h b/arch/sh/include/asm/a.out.h deleted file mode 100644 index 1f93130e179..00000000000 --- a/arch/sh/include/asm/a.out.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __ASM_SH_A_OUT_H -#define __ASM_SH_A_OUT_H - -struct exec -{ - unsigned long a_info; /* Use macros N_MAGIC, etc for access */ - unsigned a_text; /* length of text, in bytes */ - unsigned a_data; /* length of data, in bytes */ - unsigned a_bss; /* length of uninitialized data area for file, in bytes */ - unsigned a_syms; /* length of symbol table data in file, in bytes */ - unsigned a_entry; /* start address */ - unsigned a_trsize; /* length of relocation info for text, in bytes */ - unsigned a_drsize; /* length of relocation info for data, in bytes */ -}; - -#define N_TRSIZE(a) ((a).a_trsize) -#define N_DRSIZE(a) ((a).a_drsize) -#define N_SYMSIZE(a) ((a).a_syms) - -#endif /* __ASM_SH_A_OUT_H */ -- cgit v1.2.3 From d8eb2fab18b856fcaebe2619e8eaaa152baebc66 Mon Sep 17 00:00:00 2001 From: Takashi Yoshii Date: Mon, 4 Aug 2008 14:28:38 +0900 Subject: add addrespace definition for sh2a. Newfile: arch/sh/include/cpu-sh2a/cpu/addrspace.h This file seems had be removed to use fallback (cpu-common/cpu/addrspace.h), but, I'd like to add sh2a specific file here, because 1. the values defined there are not suitable for sh2a. 2. I don't think there is "common" definition for these values. Values are chosen by consideration of followings... P1 is 0. perhaps no question. P2 is from hardware manual, which says no-cache area starts at 20000000. It means that P? space size=20000000. P3 is P2+size since asm/ptrace.h uses P3 as a end of P2. P4 is P3+size since asm/fixup.h uses P4 as a end of P3. Signed-off-by: Takashi YOSHII Signed-off-by: Paul Mundt --- arch/sh/include/cpu-sh2a/cpu/addrspace.h | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 arch/sh/include/cpu-sh2a/cpu/addrspace.h (limited to 'arch') diff --git a/arch/sh/include/cpu-sh2a/cpu/addrspace.h b/arch/sh/include/cpu-sh2a/cpu/addrspace.h new file mode 100644 index 00000000000..31eb4b58aa6 --- /dev/null +++ b/arch/sh/include/cpu-sh2a/cpu/addrspace.h @@ -0,0 +1,10 @@ +#ifndef __ASM_SH_CPU_SH2A_ADDRSPACE_H +#define __ASM_SH_CPU_SH2A_ADDRSPACE_H + +#define P0SEG 0x00000000 +#define P1SEG 0x00000000 +#define P2SEG 0x20000000 +#define P3SEG 0x40000000 +#define P4SEG 0x60000000 + +#endif /* __ASM_SH_CPU_SH2A_ADDRSPACE_H */ -- cgit v1.2.3 From cce2d453e4940d3fccd42a6917d01027148e11c3 Mon Sep 17 00:00:00 2001 From: Yoshinori Sato Date: Mon, 4 Aug 2008 16:33:47 +0900 Subject: SH2(A) cache update Includes: - SH2 (7619) Writeback support. - SH2A cache handling fix. Signed-off-by: Yoshinori Sato Signed-off-by: Paul Mundt --- arch/sh/include/cpu-sh2/cpu/cache.h | 6 +- arch/sh/include/cpu-sh2a/cpu/cache.h | 3 + arch/sh/include/cpu-sh2a/cpu/cacheflush.h | 34 ++++++++ arch/sh/mm/Kconfig | 1 - arch/sh/mm/Makefile_32 | 11 ++- arch/sh/mm/cache-sh2.c | 45 ++++++++--- arch/sh/mm/cache-sh2a.c | 129 ++++++++++++++++++++++++++++++ 7 files changed, 213 insertions(+), 16 deletions(-) create mode 100644 arch/sh/include/cpu-sh2a/cpu/cacheflush.h create mode 100644 arch/sh/mm/cache-sh2a.c (limited to 'arch') diff --git a/arch/sh/include/cpu-sh2/cpu/cache.h b/arch/sh/include/cpu-sh2/cpu/cache.h index 4e0b1650068..673515bc413 100644 --- a/arch/sh/include/cpu-sh2/cpu/cache.h +++ b/arch/sh/include/cpu-sh2/cpu/cache.h @@ -21,11 +21,11 @@ #define CCR 0xffffffec #define CCR_CACHE_CE 0x01 /* Cache enable */ -#define CCR_CACHE_WT 0x06 /* CCR[bit1=1,bit2=1] */ +#define CCR_CACHE_WT 0x02 /* CCR[bit1=1,bit2=1] */ /* 0x00000000-0x7fffffff: Write-through */ /* 0x80000000-0x9fffffff: Write-back */ /* 0xc0000000-0xdfffffff: Write-through */ -#define CCR_CACHE_CB 0x00 /* CCR[bit1=0,bit2=0] */ +#define CCR_CACHE_CB 0x04 /* CCR[bit1=0,bit2=0] */ /* 0x00000000-0x7fffffff: Write-back */ /* 0x80000000-0x9fffffff: Write-through */ /* 0xc0000000-0xdfffffff: Write-back */ @@ -36,6 +36,8 @@ #define CCR_CACHE_ENABLE CCR_CACHE_CE #define CCR_CACHE_INVALIDATE CCR_CACHE_CF +#define CACHE_PHYSADDR_MASK 0x1ffffc00 + #endif #endif /* __ASM_CPU_SH2_CACHE_H */ diff --git a/arch/sh/include/cpu-sh2a/cpu/cache.h b/arch/sh/include/cpu-sh2a/cpu/cache.h index afe228b3f49..defb0baa5a0 100644 --- a/arch/sh/include/cpu-sh2a/cpu/cache.h +++ b/arch/sh/include/cpu-sh2a/cpu/cache.h @@ -36,5 +36,8 @@ #define CCR_CACHE_ENABLE (CCR_CACHE_OCE | CCR_CACHE_ICE) #define CCR_CACHE_INVALIDATE (CCR_CACHE_OCI | CCR_CACHE_ICI) +#define CCR_ICACHE_INVALIDATE CCR_CACHE_ICI +#define CCR_OCACHE_INVALIDATE CCR_CACHE_OCI +#define CACHE_PHYSADDR_MASK 0x1ffffc00 #endif /* __ASM_CPU_SH2A_CACHE_H */ diff --git a/arch/sh/include/cpu-sh2a/cpu/cacheflush.h b/arch/sh/include/cpu-sh2a/cpu/cacheflush.h new file mode 100644 index 00000000000..3d3b9205d2a --- /dev/null +++ b/arch/sh/include/cpu-sh2a/cpu/cacheflush.h @@ -0,0 +1,34 @@ +#ifndef __ASM_CPU_SH2A_CACHEFLUSH_H +#define __ASM_CPU_SH2A_CACHEFLUSH_H + +/* + * Cache flushing: + * + * - flush_cache_all() flushes entire cache + * - flush_cache_mm(mm) flushes the specified mm context's cache lines + * - flush_cache_dup mm(mm) handles cache flushing when forking + * - flush_cache_page(mm, vmaddr, pfn) flushes a single page + * - flush_cache_range(vma, start, end) flushes a range of pages + * + * - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache + * - flush_icache_range(start, end) flushes(invalidates) a range for icache + * - flush_icache_page(vma, pg) flushes(invalidates) a page for icache + * + * Caches are indexed (effectively) by physical address on SH-2, so + * we don't need them. + */ +#define flush_cache_all() do { } while (0) +#define flush_cache_mm(mm) do { } while (0) +#define flush_cache_dup_mm(mm) do { } while (0) +#define flush_cache_range(vma, start, end) do { } while (0) +#define flush_cache_page(vma, vmaddr, pfn) do { } while (0) +#define flush_dcache_page(page) do { } while (0) +#define flush_dcache_mmap_lock(mapping) do { } while (0) +#define flush_dcache_mmap_unlock(mapping) do { } while (0) +void flush_icache_range(unsigned long start, unsigned long end); +#define flush_icache_page(vma,pg) do { } while (0) +#define flush_icache_user_range(vma,pg,adr,len) do { } while (0) +#define flush_cache_sigtramp(vaddr) do { } while (0) + +#define p3_cache_init() do { } while (0) +#endif /* __ASM_CPU_SH2A_CACHEFLUSH_H */ diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 56d0a7daa34..9c131cac91a 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -237,7 +237,6 @@ choice config CACHE_WRITEBACK bool "Write-back" - depends on CPU_SH2A || CPU_SH3 || CPU_SH4 || CPU_SH5 config CACHE_WRITETHROUGH bool "Write-through" diff --git a/arch/sh/mm/Makefile_32 b/arch/sh/mm/Makefile_32 index e295db60b91..70e0906023c 100644 --- a/arch/sh/mm/Makefile_32 +++ b/arch/sh/mm/Makefile_32 @@ -5,12 +5,15 @@ obj-y := init.o extable_32.o consistent.o ifndef CONFIG_CACHE_OFF -obj-$(CONFIG_CPU_SH2) += cache-sh2.o -obj-$(CONFIG_CPU_SH3) += cache-sh3.o -obj-$(CONFIG_CPU_SH4) += cache-sh4.o -obj-$(CONFIG_SH7705_CACHE_32KB) += cache-sh7705.o +cache-$(CONFIG_CPU_SH2) := cache-sh2.o +cache-$(CONFIG_CPU_SH2A) := cache-sh2a.o +cache-$(CONFIG_CPU_SH3) := cache-sh3.o +cache-$(CONFIG_CPU_SH4) := cache-sh4.o +cache-$(CONFIG_SH7705_CACHE_32KB) += cache-sh7705.o endif +obj-y += $(cache-y) + mmu-y := tlb-nommu.o pg-nommu.o mmu-$(CONFIG_MMU) := fault_32.o tlbflush_32.o ioremap_32.o diff --git a/arch/sh/mm/cache-sh2.c b/arch/sh/mm/cache-sh2.c index 6614033f6be..c4e80d2b764 100644 --- a/arch/sh/mm/cache-sh2.c +++ b/arch/sh/mm/cache-sh2.c @@ -2,6 +2,7 @@ * arch/sh/mm/cache-sh2.c * * Copyright (C) 2002 Paul Mundt + * Copyright (C) 2008 Yoshinori Sato * * Released under the terms of the GNU GPL v2.0. */ @@ -24,8 +25,15 @@ void __flush_wback_region(void *start, int size) end = ((unsigned long)start + size + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1); for (v = begin; v < end; v+=L1_CACHE_BYTES) { - /* FIXME cache purge */ - ctrl_outl((v & 0x1ffffc00), (v & 0x00000ff0) | 0x00000008); + unsigned long addr = CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0); + int way; + for (way = 0; way < 4; way++) { + unsigned long data = ctrl_inl(addr | (way << 12)); + if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) { + data &= ~SH_CACHE_UPDATED; + ctrl_outl(data, addr | (way << 12)); + } + } } } @@ -37,21 +45,40 @@ void __flush_purge_region(void *start, int size) begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); end = ((unsigned long)start + size + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1); - for (v = begin; v < end; v+=L1_CACHE_BYTES) { - ctrl_outl((v & 0x1ffffc00), (v & 0x00000ff0) | 0x00000008); - } + + for (v = begin; v < end; v+=L1_CACHE_BYTES) + ctrl_outl((v & CACHE_PHYSADDR_MASK), + CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0) | 0x00000008); } void __flush_invalidate_region(void *start, int size) { +#ifdef CONFIG_CACHE_WRITEBACK + /* + * SH-2 does not support individual line invalidation, only a + * global invalidate. + */ + unsigned long ccr; + unsigned long flags; + local_irq_save(flags); + jump_to_uncached(); + + ccr = ctrl_inl(CCR); + ccr |= CCR_CACHE_INVALIDATE; + ctrl_outl(ccr, CCR); + + back_to_cached(); + local_irq_restore(flags); +#else unsigned long v; unsigned long begin, end; begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); end = ((unsigned long)start + size + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1); - for (v = begin; v < end; v+=L1_CACHE_BYTES) { - ctrl_outl((v & 0x1ffffc00), (v & 0x00000ff0) | 0x00000008); - } -} + for (v = begin; v < end; v+=L1_CACHE_BYTES) + ctrl_outl((v & CACHE_PHYSADDR_MASK), + CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0) | 0x00000008); +#endif +} diff --git a/arch/sh/mm/cache-sh2a.c b/arch/sh/mm/cache-sh2a.c new file mode 100644 index 00000000000..62c0c5f3512 --- /dev/null +++ b/arch/sh/mm/cache-sh2a.c @@ -0,0 +1,129 @@ +/* + * arch/sh/mm/cache-sh2a.c + * + * Copyright (C) 2008 Yoshinori Sato + * + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include + +#include +#include +#include +#include +#include + +void __flush_wback_region(void *start, int size) +{ + unsigned long v; + unsigned long begin, end; + unsigned long flags; + + begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); + end = ((unsigned long)start + size + L1_CACHE_BYTES-1) + & ~(L1_CACHE_BYTES-1); + + local_irq_save(flags); + jump_to_uncached(); + + for (v = begin; v < end; v+=L1_CACHE_BYTES) { + unsigned long addr = CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0); + int way; + for (way = 0; way < 4; way++) { + unsigned long data = ctrl_inl(addr | (way << 11)); + if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) { + data &= ~SH_CACHE_UPDATED; + ctrl_outl(data, addr | (way << 11)); + } + } + } + + back_to_cached(); + local_irq_restore(flags); +} + +void __flush_purge_region(void *start, int size) +{ + unsigned long v; + unsigned long begin, end; + unsigned long flags; + + begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); + end = ((unsigned long)start + size + L1_CACHE_BYTES-1) + & ~(L1_CACHE_BYTES-1); + + local_irq_save(flags); + jump_to_uncached(); + + for (v = begin; v < end; v+=L1_CACHE_BYTES) { + ctrl_outl((v & CACHE_PHYSADDR_MASK), + CACHE_OC_ADDRESS_ARRAY | (v & 0x000003f0) | 0x00000008); + } + back_to_cached(); + local_irq_restore(flags); +} + +void __flush_invalidate_region(void *start, int size) +{ + unsigned long v; + unsigned long begin, end; + unsigned long flags; + + begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); + end = ((unsigned long)start + size + L1_CACHE_BYTES-1) + & ~(L1_CACHE_BYTES-1); + local_irq_save(flags); + jump_to_uncached(); + +#ifdef CONFIG_CACHE_WRITEBACK + ctrl_outl(ctrl_inl(CCR) | CCR_OCACHE_INVALIDATE, CCR); + /* I-cache invalidate */ + for (v = begin; v < end; v+=L1_CACHE_BYTES) { + ctrl_outl((v & CACHE_PHYSADDR_MASK), + CACHE_IC_ADDRESS_ARRAY | (v & 0x000003f0) | 0x00000008); + } +#else + for (v = begin; v < end; v+=L1_CACHE_BYTES) { + ctrl_outl((v & CACHE_PHYSADDR_MASK), + CACHE_IC_ADDRESS_ARRAY | (v & 0x000003f0) | 0x00000008); + ctrl_outl((v & CACHE_PHYSADDR_MASK), + CACHE_OC_ADDRESS_ARRAY | (v & 0x000003f0) | 0x00000008); + } +#endif + back_to_cached(); + local_irq_restore(flags); +} + +/* WBack O-Cache and flush I-Cache */ +void flush_icache_range(unsigned long start, unsigned long end) +{ + unsigned long v; + unsigned long flags; + + start = start & ~(L1_CACHE_BYTES-1); + end = (end + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1); + + local_irq_save(flags); + jump_to_uncached(); + + for (v = start; v < end; v+=L1_CACHE_BYTES) { + unsigned long addr = (v & 0x000007f0); + int way; + /* O-Cache writeback */ + for (way = 0; way < 4; way++) { + unsigned long data = ctrl_inl(CACHE_OC_ADDRESS_ARRAY | addr | (way << 11)); + if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) { + data &= ~SH_CACHE_UPDATED; + ctrl_outl(data, CACHE_OC_ADDRESS_ARRAY | addr | (way << 11)); + } + } + /* I-Cache invalidate */ + ctrl_outl(addr, + CACHE_IC_ADDRESS_ARRAY | addr | 0x00000008); + } + + back_to_cached(); + local_irq_restore(flags); +} -- cgit v1.2.3 From f5663f5bded3364158e2d31904173cb1debc2ecd Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 4 Aug 2008 16:52:34 +0900 Subject: sh: enable maple_keyb in dreamcast_defconfig. Signed-off-by: Paul Mundt --- arch/sh/configs/dreamcast_defconfig | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/sh/configs/dreamcast_defconfig b/arch/sh/configs/dreamcast_defconfig index d4075283956..3dc1cbd8a98 100644 --- a/arch/sh/configs/dreamcast_defconfig +++ b/arch/sh/configs/dreamcast_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.26 -# Wed Jul 30 01:34:24 2008 +# Linux kernel version: 2.6.27-rc1 +# Mon Aug 4 16:49:13 2008 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -11,6 +11,7 @@ CONFIG_GENERIC_BUG=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_TIME=y @@ -21,7 +22,6 @@ CONFIG_LOCKDEP_SUPPORT=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_ARCH_NO_VIRT_TO_BUS=y -CONFIG_ARCH_SUPPORTS_AOUT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -87,6 +87,7 @@ CONFIG_HAVE_OPROFILE=y # CONFIG_USE_GENERIC_SMP_HELPERS is not set CONFIG_HAVE_CLK=y CONFIG_PROC_PAGE_MONITOR=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set @@ -284,6 +285,7 @@ CONFIG_HZ=250 # CONFIG_SCHED_HRTICK is not set # CONFIG_KEXEC is not set # CONFIG_CRASH_DUMP is not set +CONFIG_SECCOMP=y # CONFIG_PREEMPT_NONE is not set # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y @@ -317,10 +319,6 @@ CONFIG_PCI_LEGACY=y # CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set - -# -# Networking -# CONFIG_NET=y # @@ -555,7 +553,7 @@ CONFIG_INPUT_KEYBOARD=y # CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_NEWTON is not set # CONFIG_KEYBOARD_STOWAWAY is not set -# CONFIG_KEYBOARD_MAPLE is not set +CONFIG_KEYBOARD_MAPLE=y # CONFIG_KEYBOARD_SH_KEYSC is not set CONFIG_INPUT_MOUSE=y # CONFIG_MOUSE_PS2 is not set -- cgit v1.2.3