diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig index bc428b5f126c18b48d5b52e502d39eaf6241ac84..a4787197d8fe3ea39b28c646ecfed383263ea0f1 100644 --- a/arch/openrisc/Kconfig +++ b/arch/openrisc/Kconfig @@ -16,6 +16,7 @@ config OPENRISC select GENERIC_IRQ_SHOW select GENERIC_IOMAP select GENERIC_CPU_DEVICES + select GENERIC_ATOMIC64 config MMU def_bool y diff --git a/arch/openrisc/include/asm/page.h b/arch/openrisc/include/asm/page.h index b041b344b229e6329396b46dce1e13f02599b899..108906f991d6766c7ec9d9dd94e3ab3da1aec07c 100644 --- a/arch/openrisc/include/asm/page.h +++ b/arch/openrisc/include/asm/page.h @@ -71,9 +71,6 @@ typedef struct page *pgtable_t; #define __pgd(x) ((pgd_t) { (x) }) #define __pgprot(x) ((pgprot_t) { (x) }) -extern unsigned long memory_start; -extern unsigned long memory_end; - #endif /* !__ASSEMBLY__ */ @@ -94,8 +91,7 @@ extern unsigned long memory_end; #define pfn_valid(pfn) ((pfn) < max_mapnr) -#define virt_addr_valid(kaddr) (((void *)(kaddr) >= (void *)PAGE_OFFSET) && \ - ((void *)(kaddr) < (void *)memory_end)) +#define virt_addr_valid(kaddr) (pfn_valid(virt_to_pfn(kaddr))) #endif /* __ASSEMBLY__ */ diff --git a/arch/openrisc/include/asm/processor.h b/arch/openrisc/include/asm/processor.h index bb54c97b9783cd0feed94534e3f493c27c8b70fe..f7516fa78b58a2e2311433f63a1a401d7de9d044 100644 --- a/arch/openrisc/include/asm/processor.h +++ b/arch/openrisc/include/asm/processor.h @@ -81,8 +81,8 @@ extern inline void prepare_to_copy(struct task_struct *tsk) #define INIT_THREAD { } -#define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc); -#define KSTK_ESP(tsk) (task_pt_regs(tsk)->sp); +#define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc) +#define KSTK_ESP(tsk) (task_pt_regs(tsk)->sp) extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); diff --git a/arch/openrisc/include/asm/ptrace.h b/arch/openrisc/include/asm/ptrace.h index e612ce4512c73db468d6597673d87fa729b24226..4651a737591d5a12f4ca04b260da8bbf78783e28 100644 --- a/arch/openrisc/include/asm/ptrace.h +++ b/arch/openrisc/include/asm/ptrace.h @@ -73,9 +73,13 @@ struct pt_regs { }; }; long pc; + /* For restarting system calls: + * Set to syscall number for syscall exceptions, + * -1 for all other exceptions. + */ long orig_gpr11; /* For restarting system calls */ - long syscallno; /* Syscall number (used by strace) */ long dummy; /* Cheap alignment fix */ + long dummy2; /* Cheap alignment fix */ }; /* TODO: Rename this to REDZONE because that's what it is */ diff --git a/arch/openrisc/include/asm/syscall.h b/arch/openrisc/include/asm/syscall.h index 9f0337055d26f4b407f29c2ab2f34ed3930fb6e9..b752bb67891db2da9358abc3af1bc1f8b95c57cc 100644 --- a/arch/openrisc/include/asm/syscall.h +++ b/arch/openrisc/include/asm/syscall.h @@ -25,7 +25,7 @@ static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs) { - return regs->syscallno ? regs->syscallno : -1; + return regs->orig_gpr11; } static inline void @@ -50,10 +50,7 @@ static inline void syscall_set_return_value(struct task_struct *task, struct pt_regs *regs, int error, long val) { - if (error) - regs->gpr[11] = -error; - else - regs->gpr[11] = val; + regs->gpr[11] = (long) error ?: val; } static inline void diff --git a/arch/openrisc/include/asm/uaccess.h b/arch/openrisc/include/asm/uaccess.h index c310e45b538ed21e3973373b97a1352503d9d298..f5abaa0ffc38c407799b17e97595204277ff4fa4 100644 --- a/arch/openrisc/include/asm/uaccess.h +++ b/arch/openrisc/include/asm/uaccess.h @@ -26,7 +26,6 @@ #include #include #include -#include #include #define VERIFY_READ 0 diff --git a/arch/openrisc/kernel/entry.S b/arch/openrisc/kernel/entry.S index d5f9c35a583ff21568dfee733199a8d93475e47e..6e61af8682b8dc010e78da67a38bd40e8af4e5fa 100644 --- a/arch/openrisc/kernel/entry.S +++ b/arch/openrisc/kernel/entry.S @@ -95,7 +95,6 @@ handler: ;\ /* r1, EPCR, ESR a already saved */ ;\ l.sw PT_GPR2(r1),r2 ;\ l.sw PT_GPR3(r1),r3 ;\ - l.sw PT_ORIG_GPR11(r1),r11 ;\ /* r4 already save */ ;\ l.sw PT_GPR5(r1),r5 ;\ l.sw PT_GPR6(r1),r6 ;\ @@ -125,7 +124,9 @@ handler: ;\ /* r30 already save */ ;\ /* l.sw PT_GPR30(r1),r30*/ ;\ l.sw PT_GPR31(r1),r31 ;\ - l.sw PT_SYSCALLNO(r1),r0 + /* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\ + l.addi r30,r0,-1 ;\ + l.sw PT_ORIG_GPR11(r1),r30 #define UNHANDLED_EXCEPTION(handler,vector) \ .global handler ;\ @@ -133,7 +134,6 @@ handler: ;\ /* r1, EPCR, ESR already saved */ ;\ l.sw PT_GPR2(r1),r2 ;\ l.sw PT_GPR3(r1),r3 ;\ - l.sw PT_ORIG_GPR11(r1),r11 ;\ l.sw PT_GPR5(r1),r5 ;\ l.sw PT_GPR6(r1),r6 ;\ l.sw PT_GPR7(r1),r7 ;\ @@ -162,7 +162,9 @@ handler: ;\ /* r31 already saved */ ;\ l.sw PT_GPR30(r1),r30 ;\ /* l.sw PT_GPR31(r1),r31 */ ;\ - l.sw PT_SYSCALLNO(r1),r0 ;\ + /* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\ + l.addi r30,r0,-1 ;\ + l.sw PT_ORIG_GPR11(r1),r30 ;\ l.addi r3,r1,0 ;\ /* r4 is exception EA */ ;\ l.addi r5,r0,vector ;\ @@ -554,6 +556,7 @@ ENTRY(_sys_call_handler) l.sw PT_GPR9(r1),r9 /* r10 already saved */ l.sw PT_GPR11(r1),r11 + /* orig_gpr11 must be set for syscalls */ l.sw PT_ORIG_GPR11(r1),r11 /* r12,r13 already saved */ @@ -567,9 +570,6 @@ ENTRY(_sys_call_handler) /* r30 is the only register we clobber in the fast path */ /* r30 already saved */ /* l.sw PT_GPR30(r1),r30 */ - /* This is used by do_signal to determine whether to check for - * syscall restart or not */ - l.sw PT_SYSCALLNO(r1),r11 _syscall_check_trace_enter: /* If TIF_SYSCALL_TRACE is set, then we want to do syscall tracing */ @@ -731,7 +731,7 @@ _syscall_trace_enter: * so that we can do the syscall for real and return to the syscall * hot path. */ - l.lwz r11,PT_SYSCALLNO(r1) + l.lwz r11,PT_GPR11(r1) l.lwz r3,PT_GPR3(r1) l.lwz r4,PT_GPR4(r1) l.lwz r5,PT_GPR5(r1) diff --git a/arch/openrisc/kernel/head.S b/arch/openrisc/kernel/head.S index c75018d2264429f7428e40d8dfd2510f36cef3aa..1088b5fca3bdd44abed7ec4432dc135e918856f8 100644 --- a/arch/openrisc/kernel/head.S +++ b/arch/openrisc/kernel/head.S @@ -26,6 +26,7 @@ #include #include #include +#include #define tophys(rd,rs) \ l.movhi rd,hi(-KERNELBASE) ;\ @@ -440,6 +441,9 @@ _dispatch_do_ipage_fault: __HEAD .global _start _start: + /* save kernel parameters */ + l.or r25,r0,r3 /* pointer to fdt */ + /* * ensure a deterministic start */ @@ -471,7 +475,6 @@ _start: CLEAR_GPR(r22) CLEAR_GPR(r23) CLEAR_GPR(r24) - CLEAR_GPR(r25) CLEAR_GPR(r26) CLEAR_GPR(r27) CLEAR_GPR(r28) @@ -565,6 +568,18 @@ enable_mmu: // reset the simulation counters l.nop 5 + /* check fdt header magic word */ + l.lwz r3,0(r25) /* load magic from fdt into r3 */ + l.movhi r4,hi(OF_DT_HEADER) + l.ori r4,r4,lo(OF_DT_HEADER) + l.sfeq r3,r4 + l.bf _fdt_found + l.nop + /* magic number mismatch, set fdt pointer to null */ + l.or r25,r0,r0 +_fdt_found: + /* pass fdt pointer to or32_early_setup in r3 */ + l.or r3,r0,r25 LOAD_SYMBOL_2_GPR(r24, or32_early_setup) l.jalr r24 l.nop diff --git a/arch/openrisc/kernel/ptrace.c b/arch/openrisc/kernel/ptrace.c index 7259047d5f9dbd21cc8529119dfc21f61cd2b840..6deacb6b95a454b5496f0d4e37c6d8b4fac74c45 100644 --- a/arch/openrisc/kernel/ptrace.c +++ b/arch/openrisc/kernel/ptrace.c @@ -188,11 +188,11 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) */ ret = -1L; - audit_syscall_entry(audit_arch(), regs->syscallno, + audit_syscall_entry(audit_arch(), regs->gpr[11], regs->gpr[3], regs->gpr[4], regs->gpr[5], regs->gpr[6]); - return ret ? : regs->syscallno; + return ret ? : regs->gpr[11]; } asmlinkage void do_syscall_trace_leave(struct pt_regs *regs) diff --git a/arch/openrisc/kernel/setup.c b/arch/openrisc/kernel/setup.c index 1422f747f52bed163ea2aab449c919656228a813..bf5eba22ce9e1b6503c01c311362fe9e3fd0756b 100644 --- a/arch/openrisc/kernel/setup.c +++ b/arch/openrisc/kernel/setup.c @@ -207,18 +207,18 @@ void __init setup_cpuinfo(void) * Handles the pointer to the device tree that this kernel is to use * for establishing the available platform devices. * - * For now, this is limited to using the built-in device tree. In the future, - * it is intended that this function will take a pointer to the device tree - * that is potentially built-in, but potentially also passed in by the - * bootloader, or discovered by some equally clever means... + * Falls back on built-in device tree in case null pointer is passed. */ -void __init or32_early_setup(void) +void __init or32_early_setup(unsigned int fdt) { - - early_init_devtree(__dtb_start); - - printk(KERN_INFO "Compiled-in FDT at 0x%p\n", __dtb_start); + if (fdt) { + early_init_devtree((void*) fdt); + printk(KERN_INFO "FDT at 0x%08x\n", fdt); + } else { + early_init_devtree(__dtb_start); + printk(KERN_INFO "Compiled-in FDT at %p\n", __dtb_start); + } } static int __init openrisc_device_probe(void) diff --git a/arch/openrisc/kernel/signal.c b/arch/openrisc/kernel/signal.c index 95207ab0c99ed536016e88b8be1a2b077ec3bae5..e970743251ae3c922fb4ff4f9722f4dc596f1f6f 100644 --- a/arch/openrisc/kernel/signal.c +++ b/arch/openrisc/kernel/signal.c @@ -102,10 +102,7 @@ asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs) goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + set_current_blocked(&set); if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) goto badframe; @@ -189,8 +186,8 @@ static inline void __user *get_sigframe(struct k_sigaction *ka, * trampoline which performs the syscall sigreturn, or a provided * user-mode trampoline. */ -static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, - sigset_t *set, struct pt_regs *regs) +static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, + sigset_t *set, struct pt_regs *regs) { struct rt_sigframe *frame; unsigned long return_ip; @@ -247,31 +244,27 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, /* actually move the usp to reflect the stacked frame */ regs->sp = (unsigned long)frame; - return; + return 0; give_sigsegv: - if (sig == SIGSEGV) - ka->sa.sa_handler = SIG_DFL; - force_sig(SIGSEGV, current); + force_sigsegv(sig, current); + return -EFAULT; } -static inline void +static inline int handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs) { - setup_rt_frame(sig, ka, info, oldset, regs); + int ret; - if (ka->sa.sa_flags & SA_ONESHOT) - ka->sa.sa_handler = SIG_DFL; + ret = setup_rt_frame(sig, ka, info, oldset, regs); + if (ret) + return ret; - spin_lock_irq(¤t->sighand->siglock); - sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); - if (!(ka->sa.sa_flags & SA_NODEFER)) - sigaddset(¤t->blocked, sig); - recalc_sigpending(); + block_sigmask(ka, sig); - spin_unlock_irq(¤t->sighand->siglock); + return 0; } /* @@ -312,7 +305,7 @@ void do_signal(struct pt_regs *regs) * below mean that the syscall executed to completion and no * restart is necessary. */ - if (regs->syscallno) { + if (regs->orig_gpr11) { int restart = 0; switch (regs->gpr[11]) { @@ -360,13 +353,13 @@ void do_signal(struct pt_regs *regs) oldset = ¤t->blocked; /* Whee! Actually deliver the signal. */ - handle_signal(signr, &info, &ka, oldset, regs); - /* a signal was successfully delivered; the saved - * sigmask will have been stored in the signal frame, - * and will be restored by sigreturn, so we can simply - * clear the TIF_RESTORE_SIGMASK flag */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) + if (!handle_signal(signr, &info, &ka, oldset, regs)) { + /* a signal was successfully delivered; the saved + * sigmask will have been stored in the signal frame, + * and will be restored by sigreturn, so we can simply + * clear the TIF_RESTORE_SIGMASK flag */ clear_thread_flag(TIF_RESTORE_SIGMASK); + } tracehook_signal_handler(signr, &info, &ka, regs, test_thread_flag(TIF_SINGLESTEP)); diff --git a/arch/openrisc/kernel/time.c b/arch/openrisc/kernel/time.c index bd946ef1623d6fdb10c5d1d0588085ce7f1cdae5..7c52e9494a8de02f589f88586187bafa0d1688d1 100644 --- a/arch/openrisc/kernel/time.c +++ b/arch/openrisc/kernel/time.c @@ -125,16 +125,13 @@ irqreturn_t __irq_entry timer_interrupt(struct pt_regs *regs) static __init void openrisc_clockevent_init(void) { - clockevents_calc_mult_shift(&clockevent_openrisc_timer, - cpuinfo.clock_frequency, 4); + clockevent_openrisc_timer.cpumask = cpumask_of(0); /* We only have 28 bits */ - clockevent_openrisc_timer.max_delta_ns = - clockevent_delta2ns((u32) 0x0fffffff, &clockevent_openrisc_timer); - clockevent_openrisc_timer.min_delta_ns = - clockevent_delta2ns(1, &clockevent_openrisc_timer); - clockevent_openrisc_timer.cpumask = cpumask_of(0); - clockevents_register_device(&clockevent_openrisc_timer); + clockevents_config_and_register(&clockevent_openrisc_timer, + cpuinfo.clock_frequency, + 100, 0x0fffffff); + } /** diff --git a/arch/openrisc/kernel/traps.c b/arch/openrisc/kernel/traps.c index a4ec44a052b23403fdb716d9f1f6a682c12b46df..a2ee12948f4056d9f6d50a4e03b42818569f949c 100644 --- a/arch/openrisc/kernel/traps.c +++ b/arch/openrisc/kernel/traps.c @@ -115,6 +115,7 @@ void dump_stack(void) show_stack(current, &stack); } +EXPORT_SYMBOL(dump_stack); void show_registers(struct pt_regs *regs) { @@ -145,8 +146,8 @@ void show_registers(struct pt_regs *regs) regs->gpr[24], regs->gpr[25], regs->gpr[26], regs->gpr[27]); printk("GPR28: %08lx GPR29: %08lx GPR30: %08lx GPR31: %08lx\n", regs->gpr[28], regs->gpr[29], regs->gpr[30], regs->gpr[31]); - printk(" RES: %08lx oGPR11: %08lx syscallno: %08lx\n", - regs->gpr[11], regs->orig_gpr11, regs->syscallno); + printk(" RES: %08lx oGPR11: %08lx\n", + regs->gpr[11], regs->orig_gpr11); printk("Process %s (pid: %d, stackpage=%08lx)\n", current->comm, current->pid, (unsigned long)current); @@ -207,8 +208,8 @@ void nommu_dump_state(struct pt_regs *regs, regs->gpr[24], regs->gpr[25], regs->gpr[26], regs->gpr[27]); printk("GPR28: %08lx GPR29: %08lx GPR30: %08lx GPR31: %08lx\n", regs->gpr[28], regs->gpr[29], regs->gpr[30], regs->gpr[31]); - printk(" RES: %08lx oGPR11: %08lx syscallno: %08lx\n", - regs->gpr[11], regs->orig_gpr11, regs->syscallno); + printk(" RES: %08lx oGPR11: %08lx\n", + regs->gpr[11], regs->orig_gpr11); printk("Process %s (pid: %d, stackpage=%08lx)\n", ((struct task_struct *)(__pa(current)))->comm, diff --git a/arch/openrisc/mm/init.c b/arch/openrisc/mm/init.c index 359dcb20fe85770b00f920b81eb047eaff1c243f..736f6b2f30af3ffa528131c64ebdcda521b7405e 100644 --- a/arch/openrisc/mm/init.c +++ b/arch/openrisc/mm/init.c @@ -222,8 +222,7 @@ void __init mem_init(void) { int codesize, reservedpages, datasize, initsize; - if (!mem_map) - BUG(); + BUG_ON(!mem_map); set_max_mapnr_init();