2013-01-18 15:12:19 +05:30
/*
* Signal Handling for ARC
*
* Copyright ( C ) 2004 , 2007 - 2010 , 2011 - 2012 Synopsys , Inc . ( www . synopsys . com )
*
* 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 .
*
* vineetg : Jan 2010 ( Restarting of timer related syscalls )
*
* vineetg : Nov 2009 ( Everything needed for TIF_RESTORE_SIGMASK )
* - do_signal ( ) supports TIF_RESTORE_SIGMASK
* - do_signal ( ) no loner needs oldset , required by OLD sys_sigsuspend
* - sys_rt_sigsuspend ( ) now comes from generic code , so discard arch implemen
* - sys_sigsuspend ( ) no longer needs to fudge ptregs , hence that arg removed
* - sys_sigsuspend ( ) no longer loops for do_signal ( ) , sets TIF_xxx and leaves
* the job to do_signal ( )
*
* vineetg : July 2009
* - Modified Code to support the uClibc provided userland sigreturn stub
* to avoid kernel synthesing it on user stack at runtime , costing TLB
* probes and Cache line flushes .
*
* vineetg : July 2009
* - In stash_usr_regs ( ) and restore_usr_regs ( ) , save / restore of user regs
* in done in block copy rather than one word at a time .
* This saves around 2 K of code and improves LMBench lat_sig < catch >
*
* rajeshwarr : Feb 2009
* - Support for Realtime Signals
*
* vineetg : Aug 11 th 2008 : Bug # 94183
* - ViXS were still seeing crashes when using insmod to load drivers .
* It turned out that the code to change Execute permssions for TLB entries
* of user was not guarded for interrupts ( mod_tlb_permission )
2016-05-21 13:45:35 +02:00
* This was causing TLB entries to be overwritten on unrelated indexes
2013-01-18 15:12:19 +05:30
*
* Vineetg : July 15 th 2008 : Bug # 94183
* - Exception happens in Delay slot of a JMP , and before user space resumes ,
* Signal is delivered ( Ctrl + C ) = > SIGINT .
* setup_frame ( ) sets up PC , SP , BLINK to enable user space signal handler
* to run , but doesn ' t clear the Delay slot bit from status32 . As a result ,
* on resuming user mode , signal handler branches off to BTA of orig JMP
* - FIX : clear the DE bit from status32 in setup_frame ( )
*
* Rahul Trivedi , Kanika Nema : Codito Technologies 2004
*/
# include <linux/signal.h>
# include <linux/ptrace.h>
# include <linux/personality.h>
# include <linux/uaccess.h>
# include <linux/syscalls.h>
# include <linux/tracehook.h>
2017-02-08 18:51:37 +01:00
# include <linux/sched/task_stack.h>
2013-01-18 15:12:19 +05:30
# include <asm/ucontext.h>
struct rt_sigframe {
struct siginfo info ;
struct ucontext uc ;
# define MAGIC_SIGALTSTK 0x07302004
unsigned int sigret_magic ;
} ;
static int
stash_usr_regs ( struct rt_sigframe __user * sf , struct pt_regs * regs ,
sigset_t * set )
{
int err ;
2014-05-14 19:35:15 +05:30
struct user_regs_struct uregs ;
uregs . scratch . bta = regs - > bta ;
uregs . scratch . lp_start = regs - > lp_start ;
uregs . scratch . lp_end = regs - > lp_end ;
uregs . scratch . lp_count = regs - > lp_count ;
uregs . scratch . status32 = regs - > status32 ;
uregs . scratch . ret = regs - > ret ;
uregs . scratch . blink = regs - > blink ;
uregs . scratch . fp = regs - > fp ;
uregs . scratch . gp = regs - > r26 ;
uregs . scratch . r12 = regs - > r12 ;
uregs . scratch . r11 = regs - > r11 ;
uregs . scratch . r10 = regs - > r10 ;
uregs . scratch . r9 = regs - > r9 ;
uregs . scratch . r8 = regs - > r8 ;
uregs . scratch . r7 = regs - > r7 ;
uregs . scratch . r6 = regs - > r6 ;
uregs . scratch . r5 = regs - > r5 ;
uregs . scratch . r4 = regs - > r4 ;
uregs . scratch . r3 = regs - > r3 ;
uregs . scratch . r2 = regs - > r2 ;
uregs . scratch . r1 = regs - > r1 ;
uregs . scratch . r0 = regs - > r0 ;
uregs . scratch . sp = regs - > sp ;
err = __copy_to_user ( & ( sf - > uc . uc_mcontext . regs . scratch ) , & uregs . scratch ,
2013-01-18 15:12:19 +05:30
sizeof ( sf - > uc . uc_mcontext . regs . scratch ) ) ;
err | = __copy_to_user ( & sf - > uc . uc_sigmask , set , sizeof ( sigset_t ) ) ;
return err ;
}
static int restore_usr_regs ( struct pt_regs * regs , struct rt_sigframe __user * sf )
{
sigset_t set ;
int err ;
2014-05-14 19:35:15 +05:30
struct user_regs_struct uregs ;
2013-01-18 15:12:19 +05:30
err = __copy_from_user ( & set , & sf - > uc . uc_sigmask , sizeof ( set ) ) ;
2014-05-14 19:35:15 +05:30
err | = __copy_from_user ( & uregs . scratch ,
& ( sf - > uc . uc_mcontext . regs . scratch ) ,
2013-01-18 15:12:19 +05:30
sizeof ( sf - > uc . uc_mcontext . regs . scratch ) ) ;
2016-09-10 16:31:04 -04:00
if ( err )
return err ;
2013-01-18 15:12:19 +05:30
2016-09-10 16:31:04 -04:00
set_current_blocked ( & set ) ;
2014-05-14 19:35:15 +05:30
regs - > bta = uregs . scratch . bta ;
regs - > lp_start = uregs . scratch . lp_start ;
regs - > lp_end = uregs . scratch . lp_end ;
regs - > lp_count = uregs . scratch . lp_count ;
regs - > status32 = uregs . scratch . status32 ;
regs - > ret = uregs . scratch . ret ;
regs - > blink = uregs . scratch . blink ;
regs - > fp = uregs . scratch . fp ;
regs - > r26 = uregs . scratch . gp ;
regs - > r12 = uregs . scratch . r12 ;
regs - > r11 = uregs . scratch . r11 ;
regs - > r10 = uregs . scratch . r10 ;
regs - > r9 = uregs . scratch . r9 ;
regs - > r8 = uregs . scratch . r8 ;
regs - > r7 = uregs . scratch . r7 ;
regs - > r6 = uregs . scratch . r6 ;
regs - > r5 = uregs . scratch . r5 ;
regs - > r4 = uregs . scratch . r4 ;
regs - > r3 = uregs . scratch . r3 ;
regs - > r2 = uregs . scratch . r2 ;
regs - > r1 = uregs . scratch . r1 ;
regs - > r0 = uregs . scratch . r0 ;
regs - > sp = uregs . scratch . sp ;
2016-09-10 16:31:04 -04:00
return 0 ;
2013-01-18 15:12:19 +05:30
}
static inline int is_do_ss_needed ( unsigned int magic )
{
if ( MAGIC_SIGALTSTK = = magic )
return 1 ;
else
return 0 ;
}
SYSCALL_DEFINE0 ( rt_sigreturn )
{
struct rt_sigframe __user * sf ;
unsigned int magic ;
struct pt_regs * regs = current_pt_regs ( ) ;
/* Always make any pending restarted system calls return -EINTR */
2015-02-12 15:01:14 -08:00
current - > restart_block . fn = do_no_restart_syscall ;
2013-01-18 15:12:19 +05:30
/* Since we stacked the signal on a word boundary,
* then ' sp ' should be word aligned here . If it ' s
* not , then the user is trying to mess with us .
*/
if ( regs - > sp & 3 )
goto badframe ;
sf = ( struct rt_sigframe __force __user * ) ( regs - > sp ) ;
if ( ! access_ok ( VERIFY_READ , sf , sizeof ( * sf ) ) )
goto badframe ;
2013-10-02 11:13:38 +02:00
if ( __get_user ( magic , & sf - > sigret_magic ) )
2013-01-18 15:12:19 +05:30
goto badframe ;
if ( unlikely ( is_do_ss_needed ( magic ) ) )
if ( restore_altstack ( & sf - > uc . uc_stack ) )
goto badframe ;
2013-10-02 11:13:38 +02:00
if ( restore_usr_regs ( regs , sf ) )
goto badframe ;
2013-01-18 15:12:19 +05:30
/* Don't restart from sigreturn */
syscall_wont_restart ( regs ) ;
2015-03-26 11:14:41 +05:30
/*
* Ensure that sigreturn always returns to user mode ( in case the
* regs saved on user stack got fudged between save and sigreturn )
* Otherwise it is easy to panic the kernel with a custom
* signal handler and / or restorer which clobberes the status32 / ret
* to return to a bogus location in kernel mode .
*/
regs - > status32 | = STATUS_U_MASK ;
2013-01-18 15:12:19 +05:30
return regs - > r0 ;
badframe :
force_sig ( SIGSEGV , current ) ;
return 0 ;
}
/*
* Determine which stack to use . .
*/
2014-03-05 13:26:26 +01:00
static inline void __user * get_sigframe ( struct ksignal * ksig ,
2013-01-18 15:12:19 +05:30
struct pt_regs * regs ,
unsigned long framesize )
{
2014-03-05 13:26:26 +01:00
unsigned long sp = sigsp ( regs - > sp , ksig ) ;
2013-01-18 15:12:19 +05:30
void __user * frame ;
/* No matter what happens, 'sp' must be word
* aligned otherwise nasty things could happen
*/
/* ATPCS B01 mandates 8-byte alignment */
frame = ( void __user * ) ( ( sp - framesize ) & ~ 7 ) ;
/* Check that we can actually write to the signal frame */
if ( ! access_ok ( VERIFY_WRITE , frame , framesize ) )
frame = NULL ;
return frame ;
}
static int
2013-10-06 22:42:38 +02:00
setup_rt_frame ( struct ksignal * ksig , sigset_t * set , struct pt_regs * regs )
2013-01-18 15:12:19 +05:30
{
struct rt_sigframe __user * sf ;
unsigned int magic = 0 ;
int err = 0 ;
2014-03-05 13:26:26 +01:00
sf = get_sigframe ( ksig , regs , sizeof ( struct rt_sigframe ) ) ;
2013-01-18 15:12:19 +05:30
if ( ! sf )
return 1 ;
2013-10-02 11:13:38 +02:00
/*
* w / o SA_SIGINFO , struct ucontext is partially populated ( only
* uc_mcontext / uc_sigmask ) for kernel ' s normal user state preservation
* during signal handler execution . This works for SA_SIGINFO as well
* although the semantics are now overloaded ( the same reg state can be
* inspected by userland : but are they allowed to fiddle with it ?
*/
err | = stash_usr_regs ( sf , regs , set ) ;
2013-01-18 15:12:19 +05:30
/*
* SA_SIGINFO requires 3 args to signal handler :
* # 1 : sig - no ( common to any handler )
* # 2 : struct siginfo
* # 3 : struct ucontext ( completely populated )
*/
2013-10-06 22:42:38 +02:00
if ( unlikely ( ksig - > ka . sa . sa_flags & SA_SIGINFO ) ) {
err | = copy_siginfo_to_user ( & sf - > info , & ksig - > info ) ;
2013-01-18 15:12:19 +05:30
err | = __put_user ( 0 , & sf - > uc . uc_flags ) ;
err | = __put_user ( NULL , & sf - > uc . uc_link ) ;
err | = __save_altstack ( & sf - > uc . uc_stack , regs - > sp ) ;
/* setup args 2 and 3 for user mode handler */
regs - > r1 = ( unsigned long ) & sf - > info ;
regs - > r2 = ( unsigned long ) & sf - > uc ;
/*
* small optim to avoid unconditonally calling do_sigaltstack
* in sigreturn path , now that we only have rt_sigreturn
*/
magic = MAGIC_SIGALTSTK ;
}
err | = __put_user ( magic , & sf - > sigret_magic ) ;
if ( err )
return err ;
/* #1 arg to the user Signal handler */
2015-03-27 09:55:52 +01:00
regs - > r0 = ksig - > sig ;
2013-01-18 15:12:19 +05:30
/* setup PC of user space signal handler */
2013-10-06 22:42:38 +02:00
regs - > ret = ( unsigned long ) ksig - > ka . sa . sa_handler ;
2013-01-18 15:12:19 +05:30
/*
* handler returns using sigreturn stub provided already by userpsace
2015-03-26 11:14:41 +05:30
* If not , nuke the process right away
2013-01-18 15:12:19 +05:30
*/
2015-03-26 11:14:41 +05:30
if ( ! ( ksig - > ka . sa . sa_flags & SA_RESTORER ) )
return 1 ;
2013-10-06 22:42:38 +02:00
regs - > blink = ( unsigned long ) ksig - > ka . sa . sa_restorer ;
2013-01-18 15:12:19 +05:30
/* User Stack for signal handler will be above the frame just carved */
regs - > sp = ( unsigned long ) sf ;
/*
* Bug 94183 , Clear the DE bit , so that when signal handler
* starts to run , it doesn ' t use BTA
*/
regs - > status32 & = ~ STATUS_DE_MASK ;
regs - > status32 | = STATUS_L_MASK ;
return err ;
}
static void arc_restart_syscall ( struct k_sigaction * ka , struct pt_regs * regs )
{
switch ( regs - > r0 ) {
case - ERESTART_RESTARTBLOCK :
case - ERESTARTNOHAND :
/*
* ERESTARTNOHAND means that the syscall should
* only be restarted if there was no handler for
* the signal , and since we only get here if there
* is a handler , we don ' t restart
*/
regs - > r0 = - EINTR ; /* ERESTART_xxx is internal */
break ;
case - ERESTARTSYS :
/*
* ERESTARTSYS means to restart the syscall if
* there is no handler or the handler was
* registered with SA_RESTART
*/
if ( ! ( ka - > sa . sa_flags & SA_RESTART ) ) {
regs - > r0 = - EINTR ;
break ;
}
/* fallthrough */
case - ERESTARTNOINTR :
/*
* ERESTARTNOINTR means that the syscall should
* be called again after the signal handler returns .
* Setup reg state just as it was before doing the trap
* r0 has been clobbered with sys call ret code thus it
* needs to be reloaded with orig first arg to syscall
* in orig_r0 . Rest of relevant reg - file :
* r8 ( syscall num ) and ( r1 - r7 ) will be reset to
* their orig user space value when we ret from kernel
*/
regs - > r0 = regs - > orig_r0 ;
ARCv2: Support for ARCv2 ISA and HS38x cores
The notable features are:
- SMP configurations of upto 4 cores with coherency
- Optional L2 Cache and IO-Coherency
- Revised Interrupt Architecture (multiple priorites, reg banks,
auto stack switch, auto regfile save/restore)
- MMUv4 (PIPT dcache, Huge Pages)
- Instructions for
* 64bit load/store: LDD, STD
* Hardware assisted divide/remainder: DIV, REM
* Function prologue/epilogue: ENTER_S, LEAVE_S
* IRQ enable/disable: CLRI, SETI
* pop count: FFS, FLS
* SETcc, BMSKN, XBFU...
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
2013-05-13 18:30:41 +05:30
regs - > ret - = is_isa_arcv2 ( ) ? 2 : 4 ;
2013-01-18 15:12:19 +05:30
break ;
}
}
/*
* OK , we ' re invoking a handler
*/
static void
2013-10-06 22:42:38 +02:00
handle_signal ( struct ksignal * ksig , struct pt_regs * regs )
2013-01-18 15:12:19 +05:30
{
sigset_t * oldset = sigmask_to_save ( ) ;
2015-03-26 11:14:41 +05:30
int failed ;
2013-01-18 15:12:19 +05:30
/* Set up the stack frame */
2015-03-26 11:14:41 +05:30
failed = setup_rt_frame ( ksig , oldset , regs ) ;
2013-01-18 15:12:19 +05:30
2015-03-26 11:14:41 +05:30
signal_setup_done ( failed , ksig , 0 ) ;
2013-01-18 15:12:19 +05:30
}
void do_signal ( struct pt_regs * regs )
{
2013-10-06 22:42:38 +02:00
struct ksignal ksig ;
2013-01-18 15:12:19 +05:30
int restart_scall ;
2013-01-18 15:12:19 +05:30
restart_scall = in_syscall ( regs ) & & syscall_restartable ( regs ) ;
2013-01-18 15:12:19 +05:30
2013-10-06 22:42:38 +02:00
if ( get_signal ( & ksig ) ) {
2013-01-18 15:12:19 +05:30
if ( restart_scall ) {
2013-10-06 22:42:38 +02:00
arc_restart_syscall ( & ksig . ka , regs ) ;
2013-01-18 15:12:19 +05:30
syscall_wont_restart ( regs ) ; /* No more restarts */
}
2013-10-06 22:42:38 +02:00
handle_signal ( & ksig , regs ) ;
2013-01-18 15:12:19 +05:30
return ;
}
if ( restart_scall ) {
/* No handler for syscall: restart it */
if ( regs - > r0 = = - ERESTARTNOHAND | |
regs - > r0 = = - ERESTARTSYS | | regs - > r0 = = - ERESTARTNOINTR ) {
regs - > r0 = regs - > orig_r0 ;
ARCv2: Support for ARCv2 ISA and HS38x cores
The notable features are:
- SMP configurations of upto 4 cores with coherency
- Optional L2 Cache and IO-Coherency
- Revised Interrupt Architecture (multiple priorites, reg banks,
auto stack switch, auto regfile save/restore)
- MMUv4 (PIPT dcache, Huge Pages)
- Instructions for
* 64bit load/store: LDD, STD
* Hardware assisted divide/remainder: DIV, REM
* Function prologue/epilogue: ENTER_S, LEAVE_S
* IRQ enable/disable: CLRI, SETI
* pop count: FFS, FLS
* SETcc, BMSKN, XBFU...
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
2013-05-13 18:30:41 +05:30
regs - > ret - = is_isa_arcv2 ( ) ? 2 : 4 ;
2013-01-18 15:12:19 +05:30
} else if ( regs - > r0 = = - ERESTART_RESTARTBLOCK ) {
regs - > r8 = __NR_restart_syscall ;
ARCv2: Support for ARCv2 ISA and HS38x cores
The notable features are:
- SMP configurations of upto 4 cores with coherency
- Optional L2 Cache and IO-Coherency
- Revised Interrupt Architecture (multiple priorites, reg banks,
auto stack switch, auto regfile save/restore)
- MMUv4 (PIPT dcache, Huge Pages)
- Instructions for
* 64bit load/store: LDD, STD
* Hardware assisted divide/remainder: DIV, REM
* Function prologue/epilogue: ENTER_S, LEAVE_S
* IRQ enable/disable: CLRI, SETI
* pop count: FFS, FLS
* SETcc, BMSKN, XBFU...
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
2013-05-13 18:30:41 +05:30
regs - > ret - = is_isa_arcv2 ( ) ? 2 : 4 ;
2013-01-18 15:12:19 +05:30
}
2013-01-18 15:12:19 +05:30
syscall_wont_restart ( regs ) ; /* No more restarts */
2013-01-18 15:12:19 +05:30
}
/* If there's no signal to deliver, restore the saved sigmask back */
restore_saved_sigmask ( ) ;
}
void do_notify_resume ( struct pt_regs * regs )
{
/*
* ASM glue gaurantees that this is only called when returning to
* user mode
*/
if ( test_and_clear_thread_flag ( TIF_NOTIFY_RESUME ) )
tracehook_notify_resume ( regs ) ;
}