[PATCH] [Karmic] SRU: arm: fix singal restart when Old EABI enabled
Stefan Bader
stefan.bader at canonical.com
Sun Dec 13 12:34:06 UTC 2009
Eric Miao wrote:
> Stefan,
>
> This patch is verified to fix bug #453682 for Karmic on dove, although not yet
> hit -stable.
It also does not have hit upstream as well. While for arm I think we could
go ahead of stable, I would prefer to have it upstream, so I can add that
commit id as reference.
> From 09f30d75269669eca5706fe2105196ee2f2c744c Mon Sep 17 00:00:00 2001
> From: Russle King <rmk+kernel at arm.linux.org.uk>
> Date: Tue, 27 Oct 2009 11:02:16 +0200
> Subject: [PATCH] arm: fix singal restart when Old EABI enabled
>
<please add some description here>
CC: stable at kernel.org
> Signed-off-by: Saeed Bishara <saeed at marvell.com>
> ---
> arch/arm/kernel/signal.c | 41 +++++++++++++++++------------------------
> arch/arm/kernel/signal.h | 4 +++-
> arch/arm/kernel/traps.c | 4 +++-
> 3 files changed, 23 insertions(+), 26 deletions(-)
> mode change 100644 => 100755 arch/arm/kernel/signal.c
>
> diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
> old mode 100644
> new mode 100755
> index f6bc5d4..b09af17
> --- a/arch/arm/kernel/signal.c
> +++ b/arch/arm/kernel/signal.c
> @@ -1,7 +1,7 @@
> /*
> * linux/arch/arm/kernel/signal.c
> *
> - * Copyright (C) 1995-2002 Russell King
> + * Copyright (C) 1995-2009 Russell King
> *
> * This program is free software; you can redistribute it and/or modify
> * it under the terms of the GNU General Public License version 2 as
> @@ -28,6 +28,7 @@
> */
> #define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE))
> #define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE))
> +#define SWI_SYS_RESTART (0xef000000|__NR_restart_syscall|__NR_OABI_SYSCALL_BASE)
This is just minor nitpick, but is there a specific reason that this definition
does not use the same layout as the definitions above?
> /*
> * With EABI, the syscall number has to be loaded into r7.
> @@ -50,6 +51,18 @@ const unsigned long sigreturn_codes[7] = {
> static int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall);
>
> /*
> + * Either we support OABI only, or we have EABI with the OABI
> + * compat layer enabled. In the later case we don't know if
> + * user space is EABI or not, and if not we must not clobber r7.
> + * Always using the OABI syscall solves that issue and works for
> + * all those cases.
> + */
> +const unsigned long syscall_restart_code[2] = {
> + SWI_SYS_RESTART, /* swi __NR_restart_syscall */
> + 0xe49df004, /* ldr pc, [sp], #4 */
> +};
> +
> +/*
> * atomically swap in the new signal mask, and wait for a signal.
> */
> asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask,
> old_sigset_t mask, struct pt_regs *regs)
> @@ -663,32 +676,12 @@ static int do_signal(sigset_t *oldset, struct
> pt_regs *regs, int syscall)
> regs->ARM_pc -= 4;
> #else
> u32 __user *usp;
> - u32 swival = __NR_restart_syscall;
>
> - regs->ARM_sp -= 12;
> + regs->ARM_sp -= 4;
> usp = (u32 __user *)regs->ARM_sp;
>
> - /*
> - * Either we supports OABI only, or we have
> - * EABI with the OABI compat layer enabled.
> - * In the later case we don't know if user
> - * space is EABI or not, and if not we must
> - * not clobber r7. Always using the OABI
> - * syscall solves that issue and works for
> - * all those cases.
> - */
> - swival = swival - __NR_SYSCALL_BASE + __NR_OABI_SYSCALL_BASE;
> -
> - put_user(regs->ARM_pc, &usp[0]);
> - /* swi __NR_restart_syscall */
> - put_user(0xef000000 | swival, &usp[1]);
> - /* ldr pc, [sp], #12 */
> - put_user(0xe49df00c, &usp[2]);
> -
> - flush_icache_range((unsigned long)usp,
> - (unsigned long)(usp + 3));
> -
> - regs->ARM_pc = regs->ARM_sp + 4;
> + put_user(regs->ARM_pc, usp);
> + regs->ARM_pc = KERN_RESTART_CODE;
> #endif
> }
> }
> diff --git a/arch/arm/kernel/signal.h b/arch/arm/kernel/signal.h
> index 27beece..6fcfe83 100644
> --- a/arch/arm/kernel/signal.h
> +++ b/arch/arm/kernel/signal.h
> @@ -1,12 +1,14 @@
> /*
> * linux/arch/arm/kernel/signal.h
> *
> - * Copyright (C) 2005 Russell King.
> + * Copyright (C) 2005-2009 Russell King.
> *
> * This program is free software; you can redistribute it and/or modify
> * it under the terms of the GNU General Public License version 2 as
> * published by the Free Software Foundation.
> */
> #define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500)
> +#define KERN_RESTART_CODE (KERN_SIGRETURN_CODE + sizeof(sigreturn_codes))
>
> extern const unsigned long sigreturn_codes[7];
> +extern const unsigned long syscall_restart_code[2];
> diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
> index 57eb0f6..9cc19c9 100644
> --- a/arch/arm/kernel/traps.c
> +++ b/arch/arm/kernel/traps.c
> @@ -1,7 +1,7 @@
> /*
> * linux/arch/arm/kernel/traps.c
> *
> - * Copyright (C) 1995-2002 Russell King
> + * Copyright (C) 1995-2009 Russell King
> * Fragments that appear the same as linux/arch/i386/kernel/traps.c
> (C) Linus Torvalds
> *
> * This program is free software; you can redistribute it and/or modify
> @@ -742,6 +742,8 @@ void __init early_trap_init(void)
> */
> memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes,
> sizeof(sigreturn_codes));
> + memcpy((void *)KERN_RESTART_CODE, syscall_restart_code,
> + sizeof(syscall_restart_code));
>
> flush_icache_range(vectors, vectors + PAGE_SIZE);
> modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
-Stefan
More information about the kernel-team
mailing list