OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [sparc64/] [kernel/] [signal32.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*  $Id: signal32.c,v 1.1.1.1 2004-04-15 01:34:45 phoenix Exp $
2
 *  arch/sparc64/kernel/signal32.c
3
 *
4
 *  Copyright (C) 1991, 1992  Linus Torvalds
5
 *  Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
6
 *  Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
7
 *  Copyright (C) 1997 Eddie C. Dost   (ecd@skynet.be)
8
 *  Copyright (C) 1997,1998 Jakub Jelinek   (jj@sunsite.mff.cuni.cz)
9
 */
10
 
11
#include <linux/sched.h>
12
#include <linux/kernel.h>
13
#include <linux/signal.h>
14
#include <linux/errno.h>
15
#include <linux/wait.h>
16
#include <linux/ptrace.h>
17
#include <linux/unistd.h>
18
#include <linux/mm.h>
19
#include <linux/smp_lock.h>
20
 
21
#include <asm/uaccess.h>
22
#include <asm/bitops.h>
23
#include <asm/ptrace.h>
24
#include <asm/svr4.h>
25
#include <asm/pgtable.h>
26
#include <asm/psrcompat.h>
27
#include <asm/fpumacro.h>
28
#include <asm/visasm.h>
29
 
30
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
31
 
32
asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs *regs,
33
                         unsigned long orig_o0, int ret_from_syscall);
34
 
35
/* This turned off for production... */
36
/* #define DEBUG_SIGNALS 1 */
37
/* #define DEBUG_SIGNALS_TRACE 1 */
38
/* #define DEBUG_SIGNALS_MAPS 1 */
39
/* #define DEBUG_SIGNALS_TLB 1 */
40
 
41
/* Signal frames: the original one (compatible with SunOS):
42
 *
43
 * Set up a signal frame... Make the stack look the way SunOS
44
 * expects it to look which is basically:
45
 *
46
 * ---------------------------------- <-- %sp at signal time
47
 * Struct sigcontext
48
 * Signal address
49
 * Ptr to sigcontext area above
50
 * Signal code
51
 * The signal number itself
52
 * One register window
53
 * ---------------------------------- <-- New %sp
54
 */
55
struct signal_sframe32 {
56
        struct reg_window32 sig_window;
57
        int sig_num;
58
        int sig_code;
59
        /* struct sigcontext32 * */ u32 sig_scptr;
60
        int sig_address;
61
        struct sigcontext32 sig_context;
62
        unsigned extramask[_NSIG_WORDS32 - 1];
63
};
64
 
65
/*
66
 * And the new one, intended to be used for Linux applications only
67
 * (we have enough in there to work with clone).
68
 * All the interesting bits are in the info field.
69
 */
70
struct new_signal_frame32 {
71
        struct sparc_stackf32   ss;
72
        __siginfo32_t           info;
73
        /* __siginfo_fpu32_t * */ u32 fpu_save;
74
        unsigned int            insns [2];
75
        unsigned                extramask[_NSIG_WORDS32 - 1];
76
        unsigned                extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
77
        /* Only valid if (info.si_regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
78
        siginfo_extra_v8plus_t  v8plus;
79
        __siginfo_fpu_t         fpu_state;
80
};
81
 
82
struct rt_signal_frame32 {
83
        struct sparc_stackf32   ss;
84
        siginfo_t32             info;
85
        struct pt_regs32        regs;
86
        sigset_t32              mask;
87
        /* __siginfo_fpu32_t * */ u32 fpu_save;
88
        unsigned int            insns [2];
89
        stack_t32               stack;
90
        unsigned                extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
91
        /* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
92
        siginfo_extra_v8plus_t  v8plus;
93
        __siginfo_fpu_t         fpu_state;
94
};
95
 
96
/* Align macros */
97
#define SF_ALIGNEDSZ  (((sizeof(struct signal_sframe32) + 7) & (~7)))
98
#define NF_ALIGNEDSZ  (((sizeof(struct new_signal_frame32) + 7) & (~7)))
99
#define RT_ALIGNEDSZ  (((sizeof(struct rt_signal_frame32) + 7) & (~7)))
100
 
101
int copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from)
102
{
103
        int err;
104
 
105
        if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t32)))
106
                return -EFAULT;
107
 
108
        /* If you change siginfo_t structure, please be sure
109
           this code is fixed accordingly.
110
           It should never copy any pad contained in the structure
111
           to avoid security leaks, but must copy the generic
112
           3 ints plus the relevant union member.
113
           This routine must convert siginfo from 64bit to 32bit as well
114
           at the same time.  */
115
        err = __put_user(from->si_signo, &to->si_signo);
116
        err |= __put_user(from->si_errno, &to->si_errno);
117
        err |= __put_user((short)from->si_code, &to->si_code);
118
        if (from->si_code < 0)
119
                err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
120
        else {
121
                switch (from->si_code >> 16) {
122
                case __SI_CHLD >> 16:
123
                        err |= __put_user(from->si_utime, &to->si_utime);
124
                        err |= __put_user(from->si_stime, &to->si_stime);
125
                        err |= __put_user(from->si_status, &to->si_status);
126
                default:
127
                        err |= __put_user(from->si_pid, &to->si_pid);
128
                        err |= __put_user(from->si_uid, &to->si_uid);
129
                        break;
130
                case __SI_FAULT >> 16:
131
                case __SI_POLL >> 16:
132
                        err |= __put_user(from->si_trapno, &to->si_trapno);
133
                        err |= __put_user((long)from->si_addr, &to->si_addr);
134
                        break;
135
                /* case __SI_RT: This is not generated by the kernel as of now.  */
136
                }
137
        }
138
        return err;
139
}
140
 
141
/*
142
 * atomically swap in the new signal mask, and wait for a signal.
143
 * This is really tricky on the Sparc, watch out...
144
 */
145
asmlinkage void _sigpause32_common(old_sigset_t32 set, struct pt_regs *regs)
146
{
147
        sigset_t saveset;
148
 
149
        set &= _BLOCKABLE;
150
        spin_lock_irq(&current->sigmask_lock);
151
        saveset = current->blocked;
152
        siginitset(&current->blocked, set);
153
        recalc_sigpending(current);
154
        spin_unlock_irq(&current->sigmask_lock);
155
 
156
        regs->tpc = regs->tnpc;
157
        regs->tnpc += 4;
158
        if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
159
                regs->tpc &= 0xffffffff;
160
                regs->tnpc &= 0xffffffff;
161
        }
162
 
163
        /* Condition codes and return value where set here for sigpause,
164
         * and so got used by setup_frame, which again causes sigreturn()
165
         * to return -EINTR.
166
         */
167
        while (1) {
168
                current->state = TASK_INTERRUPTIBLE;
169
                schedule();
170
                /*
171
                 * Return -EINTR and set condition code here,
172
                 * so the interrupted system call actually returns
173
                 * these.
174
                 */
175
                regs->tstate |= TSTATE_ICARRY;
176
                regs->u_regs[UREG_I0] = EINTR;
177
                if (do_signal32(&saveset, regs, 0, 0))
178
                        return;
179
        }
180
}
181
 
182
asmlinkage void do_rt_sigsuspend32(u32 uset, size_t sigsetsize, struct pt_regs *regs)
183
{
184
        sigset_t oldset, set;
185
        sigset_t32 set32;
186
 
187
        /* XXX: Don't preclude handling different sized sigset_t's.  */
188
        if (((__kernel_size_t32)sigsetsize) != sizeof(sigset_t)) {
189
                regs->tstate |= TSTATE_ICARRY;
190
                regs->u_regs[UREG_I0] = EINVAL;
191
                return;
192
        }
193
        if (copy_from_user(&set32, (void *)(long)uset, sizeof(set32))) {
194
                regs->tstate |= TSTATE_ICARRY;
195
                regs->u_regs[UREG_I0] = EFAULT;
196
                return;
197
        }
198
        switch (_NSIG_WORDS) {
199
        case 4: set.sig[3] = set32.sig[6] + (((long)set32.sig[7]) << 32);
200
        case 3: set.sig[2] = set32.sig[4] + (((long)set32.sig[5]) << 32);
201
        case 2: set.sig[1] = set32.sig[2] + (((long)set32.sig[3]) << 32);
202
        case 1: set.sig[0] = set32.sig[0] + (((long)set32.sig[1]) << 32);
203
        }
204
        sigdelsetmask(&set, ~_BLOCKABLE);
205
        spin_lock_irq(&current->sigmask_lock);
206
        oldset = current->blocked;
207
        current->blocked = set;
208
        recalc_sigpending(current);
209
        spin_unlock_irq(&current->sigmask_lock);
210
 
211
        regs->tpc = regs->tnpc;
212
        regs->tnpc += 4;
213
        if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
214
                regs->tpc &= 0xffffffff;
215
                regs->tnpc &= 0xffffffff;
216
        }
217
 
218
        /* Condition codes and return value where set here for sigpause,
219
         * and so got used by setup_frame, which again causes sigreturn()
220
         * to return -EINTR.
221
         */
222
        while (1) {
223
                current->state = TASK_INTERRUPTIBLE;
224
                schedule();
225
                /*
226
                 * Return -EINTR and set condition code here,
227
                 * so the interrupted system call actually returns
228
                 * these.
229
                 */
230
                regs->tstate |= TSTATE_ICARRY;
231
                regs->u_regs[UREG_I0] = EINTR;
232
                if (do_signal32(&oldset, regs, 0, 0))
233
                        return;
234
        }
235
}
236
 
237
static inline int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t *fpu)
238
{
239
        unsigned long *fpregs = (unsigned long *)(((char *)current) + AOFF_task_fpregs);
240
        unsigned long fprs;
241
        int err;
242
 
243
        err = __get_user(fprs, &fpu->si_fprs);
244
        fprs_write(0);
245
        regs->tstate &= ~TSTATE_PEF;
246
        if (fprs & FPRS_DL)
247
                err |= copy_from_user(fpregs, &fpu->si_float_regs[0], (sizeof(unsigned int) * 32));
248
        if (fprs & FPRS_DU)
249
                err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32], (sizeof(unsigned int) * 32));
250
        err |= __get_user(current->thread.xfsr[0], &fpu->si_fsr);
251
        err |= __get_user(current->thread.gsr[0], &fpu->si_gsr);
252
        current->thread.fpsaved[0] |= fprs;
253
        return err;
254
}
255
 
256
void do_new_sigreturn32(struct pt_regs *regs)
257
{
258
        struct new_signal_frame32 *sf;
259
        unsigned int psr;
260
        unsigned pc, npc, fpu_save;
261
        sigset_t set;
262
        unsigned seta[_NSIG_WORDS32];
263
        int err, i;
264
 
265
        regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
266
        sf = (struct new_signal_frame32 *) regs->u_regs [UREG_FP];
267
 
268
        /* 1. Make sure we are not getting garbage from the user */
269
        if (verify_area (VERIFY_READ, sf, sizeof (*sf)) ||
270
            (((unsigned long) sf) & 3))
271
                goto segv;
272
 
273
        get_user(pc, &sf->info.si_regs.pc);
274
        __get_user(npc, &sf->info.si_regs.npc);
275
 
276
        if ((pc | npc) & 3)
277
                goto segv;
278
 
279
        if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
280
                pc &= 0xffffffff;
281
                npc &= 0xffffffff;
282
        }
283
        regs->tpc = pc;
284
        regs->tnpc = npc;
285
 
286
        /* 2. Restore the state */
287
        err = __get_user(regs->y, &sf->info.si_regs.y);
288
        err |= __get_user(psr, &sf->info.si_regs.psr);
289
 
290
        for (i = UREG_G1; i <= UREG_I7; i++)
291
                err |= __get_user(regs->u_regs[i], &sf->info.si_regs.u_regs[i]);
292
        if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS) {
293
                err |= __get_user(i, &sf->v8plus.g_upper[0]);
294
                if (i == SIGINFO_EXTRA_V8PLUS_MAGIC) {
295
                        for (i = UREG_G1; i <= UREG_I7; i++)
296
                                err |= __get_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]);
297
                }
298
        }
299
 
300
        /* User can only change condition codes in %tstate. */
301
        regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
302
        regs->tstate |= psr_to_tstate_icc(psr);
303
 
304
        err |= __get_user(fpu_save, &sf->fpu_save);
305
        if (fpu_save)
306
                err |= restore_fpu_state32(regs, &sf->fpu_state);
307
        err |= __get_user(seta[0], &sf->info.si_mask);
308
        err |= copy_from_user(seta+1, &sf->extramask, (_NSIG_WORDS32 - 1) * sizeof(unsigned));
309
        if (err)
310
                goto segv;
311
        switch (_NSIG_WORDS) {
312
                case 4: set.sig[3] = seta[6] + (((long)seta[7]) << 32);
313
                case 3: set.sig[2] = seta[4] + (((long)seta[5]) << 32);
314
                case 2: set.sig[1] = seta[2] + (((long)seta[3]) << 32);
315
                case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32);
316
        }
317
        sigdelsetmask(&set, ~_BLOCKABLE);
318
        spin_lock_irq(&current->sigmask_lock);
319
        current->blocked = set;
320
        recalc_sigpending(current);
321
        spin_unlock_irq(&current->sigmask_lock);
322
        return;
323
 
324
segv:
325
        do_exit(SIGSEGV);
326
}
327
 
328
asmlinkage void do_sigreturn32(struct pt_regs *regs)
329
{
330
        struct sigcontext32 *scptr;
331
        unsigned pc, npc, psr;
332
        sigset_t set;
333
        unsigned seta[_NSIG_WORDS32];
334
        int err;
335
 
336
        synchronize_user_stack();
337
        if (current->thread.flags & SPARC_FLAG_NEWSIGNALS)
338
                return do_new_sigreturn32(regs);
339
 
340
        scptr = (struct sigcontext32 *)
341
                (regs->u_regs[UREG_I0] & 0x00000000ffffffffUL);
342
        /* Check sanity of the user arg. */
343
        if(verify_area(VERIFY_READ, scptr, sizeof(struct sigcontext32)) ||
344
           (((unsigned long) scptr) & 3))
345
                goto segv;
346
 
347
        err = __get_user(pc, &scptr->sigc_pc);
348
        err |= __get_user(npc, &scptr->sigc_npc);
349
 
350
        if((pc | npc) & 3)
351
                goto segv; /* Nice try. */
352
 
353
        err |= __get_user(seta[0], &scptr->sigc_mask);
354
        /* Note that scptr + 1 points to extramask */
355
        err |= copy_from_user(seta+1, scptr + 1, (_NSIG_WORDS32 - 1) * sizeof(unsigned));
356
        if (err)
357
                goto segv;
358
        switch (_NSIG_WORDS) {
359
                case 4: set.sig[3] = seta[6] + (((long)seta[7]) << 32);
360
                case 3: set.sig[2] = seta[4] + (((long)seta[5]) << 32);
361
                case 2: set.sig[1] = seta[2] + (((long)seta[3]) << 32);
362
                case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32);
363
        }
364
        sigdelsetmask(&set, ~_BLOCKABLE);
365
        spin_lock_irq(&current->sigmask_lock);
366
        current->blocked = set;
367
        recalc_sigpending(current);
368
        spin_unlock_irq(&current->sigmask_lock);
369
 
370
        if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
371
                pc &= 0xffffffff;
372
                npc &= 0xffffffff;
373
        }
374
        regs->tpc = pc;
375
        regs->tnpc = npc;
376
        err = __get_user(regs->u_regs[UREG_FP], &scptr->sigc_sp);
377
        err |= __get_user(regs->u_regs[UREG_I0], &scptr->sigc_o0);
378
        err |= __get_user(regs->u_regs[UREG_G1], &scptr->sigc_g1);
379
 
380
        /* User can only change condition codes in %tstate. */
381
        err |= __get_user(psr, &scptr->sigc_psr);
382
        if (err)
383
                goto segv;
384
        regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
385
        regs->tstate |= psr_to_tstate_icc(psr);
386
        return;
387
 
388
segv:
389
        do_exit(SIGSEGV);
390
}
391
 
392
asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
393
{
394
        struct rt_signal_frame32 *sf;
395
        unsigned int psr;
396
        unsigned pc, npc, fpu_save;
397
        mm_segment_t old_fs;
398
        sigset_t set;
399
        sigset_t32 seta;
400
        stack_t st;
401
        int err, i;
402
 
403
        synchronize_user_stack();
404
        regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
405
        sf = (struct rt_signal_frame32 *) regs->u_regs [UREG_FP];
406
 
407
        /* 1. Make sure we are not getting garbage from the user */
408
        if (verify_area (VERIFY_READ, sf, sizeof (*sf)) ||
409
            (((unsigned long) sf) & 3))
410
                goto segv;
411
 
412
        get_user(pc, &sf->regs.pc);
413
        __get_user(npc, &sf->regs.npc);
414
 
415
        if ((pc | npc) & 3)
416
                goto segv;
417
 
418
        if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
419
                pc &= 0xffffffff;
420
                npc &= 0xffffffff;
421
        }
422
        regs->tpc = pc;
423
        regs->tnpc = npc;
424
 
425
        /* 2. Restore the state */
426
        err = __get_user(regs->y, &sf->regs.y);
427
        err |= __get_user(psr, &sf->regs.psr);
428
 
429
        for (i = UREG_G1; i <= UREG_I7; i++)
430
                err |= __get_user(regs->u_regs[i], &sf->regs.u_regs[i]);
431
        if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS) {
432
                err |= __get_user(i, &sf->v8plus.g_upper[0]);
433
                if (i == SIGINFO_EXTRA_V8PLUS_MAGIC) {
434
                        for (i = UREG_G1; i <= UREG_I7; i++)
435
                                err |= __get_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]);
436
                }
437
        }
438
 
439
        /* User can only change condition codes in %tstate. */
440
        regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
441
        regs->tstate |= psr_to_tstate_icc(psr);
442
 
443
        err |= __get_user(fpu_save, &sf->fpu_save);
444
        if (fpu_save)
445
                err |= restore_fpu_state32(regs, &sf->fpu_state);
446
        err |= copy_from_user(&seta, &sf->mask, sizeof(sigset_t32));
447
        err |= __get_user((long)st.ss_sp, &sf->stack.ss_sp);
448
        err |= __get_user(st.ss_flags, &sf->stack.ss_flags);
449
        err |= __get_user(st.ss_size, &sf->stack.ss_size);
450
        if (err)
451
                goto segv;
452
 
453
        /* It is more difficult to avoid calling this function than to
454
           call it and ignore errors.  */
455
        old_fs = get_fs();
456
        set_fs(KERNEL_DS);
457
        do_sigaltstack(&st, NULL, (unsigned long)sf);
458
        set_fs(old_fs);
459
 
460
        switch (_NSIG_WORDS) {
461
                case 4: set.sig[3] = seta.sig[6] + (((long)seta.sig[7]) << 32);
462
                case 3: set.sig[2] = seta.sig[4] + (((long)seta.sig[5]) << 32);
463
                case 2: set.sig[1] = seta.sig[2] + (((long)seta.sig[3]) << 32);
464
                case 1: set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32);
465
        }
466
        sigdelsetmask(&set, ~_BLOCKABLE);
467
        spin_lock_irq(&current->sigmask_lock);
468
        current->blocked = set;
469
        recalc_sigpending(current);
470
        spin_unlock_irq(&current->sigmask_lock);
471
        return;
472
segv:
473
        do_exit(SIGSEGV);
474
}
475
 
476
/* Checks if the fp is valid */
477
static int invalid_frame_pointer(void *fp, int fplen)
478
{
479
        if ((((unsigned long) fp) & 7) || ((unsigned long)fp) > 0x100000000ULL - fplen)
480
                return 1;
481
        return 0;
482
}
483
 
484
static inline void *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize)
485
{
486
        unsigned long sp;
487
 
488
        regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
489
        sp = regs->u_regs[UREG_FP];
490
 
491
        /* This is the X/Open sanctioned signal stack switching.  */
492
        if (sa->sa_flags & SA_ONSTACK) {
493
                if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7))
494
                        sp = current->sas_ss_sp + current->sas_ss_size;
495
        }
496
        return (void *)(sp - framesize);
497
}
498
 
499
static void
500
setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *oldset, siginfo_t *info)
501
{
502
        struct signal_sframe32 *sframep;
503
        struct sigcontext32 *sc;
504
        unsigned seta[_NSIG_WORDS32];
505
        int err = 0;
506
        void *sig_address;
507
        int sig_code;
508
        unsigned long pc = regs->tpc;
509
        unsigned long npc = regs->tnpc;
510
 
511
#if 0   
512
        int window = 0;
513
#endif  
514
        unsigned psr;
515
 
516
        if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
517
                pc &= 0xffffffff;
518
                npc &= 0xffffffff;
519
        }
520
 
521
        synchronize_user_stack();
522
        save_and_clear_fpu();
523
 
524
        sframep = (struct signal_sframe32 *)get_sigframe(sa, regs, SF_ALIGNEDSZ);
525
        if (invalid_frame_pointer (sframep, sizeof(*sframep))){
526
#ifdef DEBUG_SIGNALS /* fills up the console logs during crashme runs, yuck... */
527
                printk("%s [%d]: User has trashed signal stack\n",
528
                       current->comm, current->pid);
529
                printk("Sigstack ptr %p handler at pc<%016lx> for sig<%d>\n",
530
                       sframep, pc, signr);
531
#endif
532
                /* Don't change signal code and address, so that
533
                 * post mortem debuggers can have a look.
534
                 */
535
                do_exit(SIGILL);
536
        }
537
 
538
        sc = &sframep->sig_context;
539
 
540
        /* We've already made sure frame pointer isn't in kernel space... */
541
        err = __put_user((sas_ss_flags(regs->u_regs[UREG_FP]) == SS_ONSTACK),
542
                         &sc->sigc_onstack);
543
 
544
        switch (_NSIG_WORDS) {
545
        case 4: seta[7] = (oldset->sig[3] >> 32);
546
                seta[6] = oldset->sig[3];
547
        case 3: seta[5] = (oldset->sig[2] >> 32);
548
                seta[4] = oldset->sig[2];
549
        case 2: seta[3] = (oldset->sig[1] >> 32);
550
                seta[2] = oldset->sig[1];
551
        case 1: seta[1] = (oldset->sig[0] >> 32);
552
                seta[0] = oldset->sig[0];
553
        }
554
        err |= __put_user(seta[0], &sc->sigc_mask);
555
        err |= __copy_to_user(sframep->extramask, seta + 1,
556
                              (_NSIG_WORDS32 - 1) * sizeof(unsigned));
557
        err |= __put_user(regs->u_regs[UREG_FP], &sc->sigc_sp);
558
        err |= __put_user(pc, &sc->sigc_pc);
559
        err |= __put_user(npc, &sc->sigc_npc);
560
        psr = tstate_to_psr (regs->tstate);
561
        if(current->thread.fpsaved[0] & FPRS_FEF)
562
                psr |= PSR_EF;
563
        err |= __put_user(psr, &sc->sigc_psr);
564
        err |= __put_user(regs->u_regs[UREG_G1], &sc->sigc_g1);
565
        err |= __put_user(regs->u_regs[UREG_I0], &sc->sigc_o0);
566
        err |= __put_user(current->thread.w_saved, &sc->sigc_oswins);
567
#if 0
568
/* w_saved is not currently used... */
569
        if(current->thread.w_saved)
570
                for(window = 0; window < current->thread.w_saved; window++) {
571
                        sc->sigc_spbuf[window] =
572
                                (char *)current->thread.rwbuf_stkptrs[window];
573
                        err |= copy_to_user(&sc->sigc_wbuf[window],
574
                                            &current->thread.reg_window[window],
575
                                            sizeof(struct reg_window));
576
                }
577
        else
578
#endif  
579
                err |= copy_in_user((u32 *)sframep,
580
                                    (u32 *)(regs->u_regs[UREG_FP]),
581
                                    sizeof(struct reg_window32));
582
 
583
        current->thread.w_saved = 0; /* So process is allowed to execute. */
584
        err |= __put_user(signr, &sframep->sig_num);
585
        sig_address = NULL;
586
        sig_code = 0;
587
        if (SI_FROMKERNEL (info) && (info->si_code & __SI_MASK) == __SI_FAULT) {
588
                sig_address = info->si_addr;
589
                switch (signr) {
590
                case SIGSEGV:
591
                        switch (info->si_code) {
592
                        case SEGV_MAPERR: sig_code = SUBSIG_NOMAPPING; break;
593
                        default: sig_code = SUBSIG_PROTECTION; break;
594
                        }
595
                        break;
596
                case SIGILL:
597
                        switch (info->si_code) {
598
                        case ILL_ILLOPC: sig_code = SUBSIG_ILLINST; break;
599
                        case ILL_PRVOPC: sig_code = SUBSIG_PRIVINST; break;
600
                        case ILL_ILLTRP: sig_code = SUBSIG_BADTRAP (info->si_trapno); break;
601
                        default: sig_code = SUBSIG_STACK; break;
602
                        }
603
                        break;
604
                case SIGFPE:
605
                        switch (info->si_code) {
606
                        case FPE_INTDIV: sig_code = SUBSIG_IDIVZERO; break;
607
                        case FPE_INTOVF: sig_code = SUBSIG_FPINTOVFL; break;
608
                        case FPE_FLTDIV: sig_code = SUBSIG_FPDIVZERO; break;
609
                        case FPE_FLTOVF: sig_code = SUBSIG_FPOVFLOW; break;
610
                        case FPE_FLTUND: sig_code = SUBSIG_FPUNFLOW; break;
611
                        case FPE_FLTRES: sig_code = SUBSIG_FPINEXACT; break;
612
                        case FPE_FLTINV: sig_code = SUBSIG_FPOPERROR; break;
613
                        default: sig_code = SUBSIG_FPERROR; break;
614
                        }
615
                        break;
616
                case SIGBUS:
617
                        switch (info->si_code) {
618
                        case BUS_ADRALN: sig_code = SUBSIG_ALIGNMENT; break;
619
                        case BUS_ADRERR: sig_code = SUBSIG_MISCERROR; break;
620
                        default: sig_code = SUBSIG_BUSTIMEOUT; break;
621
                        }
622
                        break;
623
                case SIGEMT:
624
                        switch (info->si_code) {
625
                        case EMT_TAGOVF: sig_code = SUBSIG_TAG; break;
626
                        }
627
                        break;
628
                case SIGSYS:
629
                        if (info->si_code == (__SI_FAULT|0x100)) {
630
                                /* See sys_sunos32.c */
631
                                sig_code = info->si_trapno;
632
                                break;
633
                        }
634
                default:
635
                        sig_address = NULL;
636
                }
637
        }
638
        err |= __put_user((long)sig_address, &sframep->sig_address);
639
        err |= __put_user(sig_code, &sframep->sig_code);
640
        err |= __put_user((u64)sc, &sframep->sig_scptr);
641
        if (err)
642
                goto sigsegv;
643
 
644
        regs->u_regs[UREG_FP] = (unsigned long) sframep;
645
        regs->tpc = (unsigned long) sa->sa_handler;
646
        regs->tnpc = (regs->tpc + 4);
647
        if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
648
                regs->tpc &= 0xffffffff;
649
                regs->tnpc &= 0xffffffff;
650
        }
651
        return;
652
 
653
sigsegv:
654
        do_exit(SIGSEGV);
655
}
656
 
657
 
658
static inline int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t *fpu)
659
{
660
        unsigned long *fpregs = (unsigned long *)(((char *)current) + AOFF_task_fpregs);
661
        unsigned long fprs;
662
        int err = 0;
663
 
664
        fprs = current->thread.fpsaved[0];
665
        if (fprs & FPRS_DL)
666
                err |= copy_to_user(&fpu->si_float_regs[0], fpregs,
667
                                    (sizeof(unsigned int) * 32));
668
        if (fprs & FPRS_DU)
669
                err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16,
670
                                    (sizeof(unsigned int) * 32));
671
        err |= __put_user(current->thread.xfsr[0], &fpu->si_fsr);
672
        err |= __put_user(current->thread.gsr[0], &fpu->si_gsr);
673
        err |= __put_user(fprs, &fpu->si_fprs);
674
 
675
        return err;
676
}
677
 
678
static inline void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
679
                                     int signo, sigset_t *oldset)
680
{
681
        struct new_signal_frame32 *sf;
682
        int sigframe_size;
683
        u32 psr;
684
        int i, err;
685
        unsigned seta[_NSIG_WORDS32];
686
 
687
        /* 1. Make sure everything is clean */
688
        synchronize_user_stack();
689
        save_and_clear_fpu();
690
 
691
        sigframe_size = NF_ALIGNEDSZ;
692
        if (!(current->thread.fpsaved[0] & FPRS_FEF))
693
                sigframe_size -= sizeof(__siginfo_fpu_t);
694
 
695
        sf = (struct new_signal_frame32 *)get_sigframe(&ka->sa, regs, sigframe_size);
696
 
697
        if (invalid_frame_pointer (sf, sigframe_size)) {
698
#ifdef DEBUG_SIGNALS
699
                printk("new_setup_frame32(%s:%d): invalid_frame_pointer(%p, %d)\n",
700
                       current->comm, current->pid, sf, sigframe_size);
701
#endif
702
                goto sigill;
703
        }
704
 
705
        if (current->thread.w_saved != 0) {
706
#ifdef DEBUG_SIGNALS
707
                printk ("%s[%d]: Invalid user stack frame for "
708
                        "signal delivery.\n", current->comm, current->pid);
709
#endif
710
                goto sigill;
711
        }
712
 
713
        /* 2. Save the current process state */
714
        if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
715
                regs->tpc &= 0xffffffff;
716
                regs->tnpc &= 0xffffffff;
717
        }
718
        err  = put_user(regs->tpc, &sf->info.si_regs.pc);
719
        err |= __put_user(regs->tnpc, &sf->info.si_regs.npc);
720
        err |= __put_user(regs->y, &sf->info.si_regs.y);
721
        psr = tstate_to_psr (regs->tstate);
722
        if(current->thread.fpsaved[0] & FPRS_FEF)
723
                psr |= PSR_EF;
724
        err |= __put_user(psr, &sf->info.si_regs.psr);
725
        for (i = 0; i < 16; i++)
726
                err |= __put_user(regs->u_regs[i], &sf->info.si_regs.u_regs[i]);
727
        err |= __put_user(sizeof(siginfo_extra_v8plus_t), &sf->extra_size);
728
        err |= __put_user(SIGINFO_EXTRA_V8PLUS_MAGIC, &sf->v8plus.g_upper[0]);
729
        for (i = 1; i < 16; i++)
730
                err |= __put_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]);
731
 
732
        if (psr & PSR_EF) {
733
                err |= save_fpu_state32(regs, &sf->fpu_state);
734
                err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
735
        } else {
736
                err |= __put_user(0, &sf->fpu_save);
737
        }
738
 
739
        switch (_NSIG_WORDS) {
740
        case 4: seta[7] = (oldset->sig[3] >> 32);
741
                seta[6] = oldset->sig[3];
742
        case 3: seta[5] = (oldset->sig[2] >> 32);
743
                seta[4] = oldset->sig[2];
744
        case 2: seta[3] = (oldset->sig[1] >> 32);
745
                seta[2] = oldset->sig[1];
746
        case 1: seta[1] = (oldset->sig[0] >> 32);
747
                seta[0] = oldset->sig[0];
748
        }
749
        err |= __put_user(seta[0], &sf->info.si_mask);
750
        err |= __copy_to_user(sf->extramask, seta + 1,
751
                              (_NSIG_WORDS32 - 1) * sizeof(unsigned));
752
 
753
        err |= copy_in_user((u32 *)sf,
754
                            (u32 *)(regs->u_regs[UREG_FP]),
755
                            sizeof(struct reg_window32));
756
 
757
        if (err)
758
                goto sigsegv;
759
 
760
        /* 3. signal handler back-trampoline and parameters */
761
        regs->u_regs[UREG_FP] = (unsigned long) sf;
762
        regs->u_regs[UREG_I0] = signo;
763
        regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
764
        regs->u_regs[UREG_I2] = (unsigned long) &sf->info;
765
 
766
        /* 4. signal handler */
767
        regs->tpc = (unsigned long) ka->sa.sa_handler;
768
        regs->tnpc = (regs->tpc + 4);
769
        if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
770
                regs->tpc &= 0xffffffff;
771
                regs->tnpc &= 0xffffffff;
772
        }
773
 
774
        /* 5. return to kernel instructions */
775
        if (ka->ka_restorer) {
776
                regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
777
        } else {
778
                /* Flush instruction space. */
779
                unsigned long address = ((unsigned long)&(sf->insns[0]));
780
                pgd_t *pgdp = pgd_offset(current->mm, address);
781
                pmd_t *pmdp = pmd_offset(pgdp, address);
782
                pte_t *ptep = pte_offset(pmdp, address);
783
 
784
                regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
785
 
786
                err  = __put_user(0x821020d8, &sf->insns[0]); /*mov __NR_sigreturn, %g1*/
787
                err |= __put_user(0x91d02010, &sf->insns[1]); /*t 0x10*/
788
                if(err)
789
                        goto sigsegv;
790
 
791
                if(pte_present(*ptep)) {
792
                        unsigned long page = (unsigned long) page_address(pte_page(*ptep));
793
 
794
                        __asm__ __volatile__(
795
                        "       membar  #StoreStore\n"
796
                        "       flush   %0 + %1"
797
                        : : "r" (page), "r" (address & (PAGE_SIZE - 1))
798
                        : "memory");
799
                }
800
        }
801
        return;
802
 
803
sigill:
804
        do_exit(SIGILL);
805
sigsegv:
806
        do_exit(SIGSEGV);
807
}
808
 
809
/* Setup a Solaris stack frame */
810
static inline void
811
setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
812
                   struct pt_regs *regs, int signr, sigset_t *oldset)
813
{
814
        svr4_signal_frame_t *sfp;
815
        svr4_gregset_t  *gr;
816
        svr4_siginfo_t  *si;
817
        svr4_mcontext_t *mc;
818
        svr4_gwindows_t *gw;
819
        svr4_ucontext_t *uc;
820
        svr4_sigset_t setv;
821
#if 0   
822
        int window = 0;
823
#endif  
824
        unsigned psr;
825
        int i, err;
826
 
827
        synchronize_user_stack();
828
        save_and_clear_fpu();
829
 
830
        regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
831
        sfp = (svr4_signal_frame_t *) get_sigframe(sa, regs, sizeof(struct reg_window32) + SVR4_SF_ALIGNED);
832
 
833
        if (invalid_frame_pointer (sfp, sizeof (*sfp))){
834
#ifdef DEBUG_SIGNALS
835
                printk ("Invalid stack frame\n");
836
#endif
837
                do_exit(SIGILL);
838
        }
839
 
840
        /* Start with a clean frame pointer and fill it */
841
        err = clear_user(sfp, sizeof (*sfp));
842
 
843
        /* Setup convenience variables */
844
        si = &sfp->si;
845
        uc = &sfp->uc;
846
        gw = &sfp->gw;
847
        mc = &uc->mcontext;
848
        gr = &mc->greg;
849
 
850
        /* FIXME: where am I supposed to put this?
851
         * sc->sigc_onstack = old_status;
852
         * anyways, it does not look like it is used for anything at all.
853
         */
854
        setv.sigbits[0] = oldset->sig[0];
855
        setv.sigbits[1] = (oldset->sig[0] >> 32);
856
        if (_NSIG_WORDS >= 2) {
857
                setv.sigbits[2] = oldset->sig[1];
858
                setv.sigbits[3] = (oldset->sig[1] >> 32);
859
                err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t));
860
        } else
861
                err |= __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned));
862
 
863
        /* Store registers */
864
        if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
865
                regs->tpc &= 0xffffffff;
866
                regs->tnpc &= 0xffffffff;
867
        }
868
        err |= __put_user(regs->tpc, &((*gr) [SVR4_PC]));
869
        err |= __put_user(regs->tnpc, &((*gr) [SVR4_NPC]));
870
        psr = tstate_to_psr (regs->tstate);
871
        if(current->thread.fpsaved[0] & FPRS_FEF)
872
                psr |= PSR_EF;
873
        err |= __put_user(psr, &((*gr) [SVR4_PSR]));
874
        err |= __put_user(regs->y, &((*gr) [SVR4_Y]));
875
 
876
        /* Copy g [1..7] and o [0..7] registers */
877
        for (i = 0; i < 7; i++)
878
                err |= __put_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
879
        for (i = 0; i < 8; i++)
880
                err |= __put_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
881
 
882
        /* Setup sigaltstack */
883
        err |= __put_user(current->sas_ss_sp, &uc->stack.sp);
884
        err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags);
885
        err |= __put_user(current->sas_ss_size, &uc->stack.size);
886
 
887
        /* Save the currently window file: */
888
 
889
        /* 1. Link sfp->uc->gwins to our windows */
890
        err |= __put_user((u32)(long)gw, &mc->gwin);
891
 
892
        /* 2. Number of windows to restore at setcontext (): */
893
        err |= __put_user(current->thread.w_saved, &gw->count);
894
 
895
        /* 3. Save each valid window
896
         *    Currently, it makes a copy of the windows from the kernel copy.
897
         *    David's code for SunOS, makes the copy but keeps the pointer to
898
         *    the kernel.  My version makes the pointer point to a userland
899
         *    copy of those.  Mhm, I wonder if I shouldn't just ignore those
900
         *    on setcontext and use those that are on the kernel, the signal
901
         *    handler should not be modyfing those, mhm.
902
         *
903
         *    These windows are just used in case synchronize_user_stack failed
904
         *    to flush the user windows.
905
         */
906
#if 0    
907
        for(window = 0; window < current->thread.w_saved; window++) {
908
                err |= __put_user((int *) &(gw->win [window]),
909
                                  (int **)gw->winptr +window );
910
                err |= copy_to_user(&gw->win [window],
911
                                    &current->thread.reg_window [window],
912
                                    sizeof (svr4_rwindow_t));
913
                err |= __put_user(0, (int *)gw->winptr + window);
914
        }
915
#endif  
916
 
917
        /* 4. We just pay attention to the gw->count field on setcontext */
918
        current->thread.w_saved = 0; /* So process is allowed to execute. */
919
 
920
        /* Setup the signal information.  Solaris expects a bunch of
921
         * information to be passed to the signal handler, we don't provide
922
         * that much currently, should use siginfo.
923
         */
924
        err |= __put_user(signr, &si->siginfo.signo);
925
        err |= __put_user(SVR4_SINOINFO, &si->siginfo.code);
926
        if (err)
927
                goto sigsegv;
928
 
929
        regs->u_regs[UREG_FP] = (unsigned long) sfp;
930
        regs->tpc = (unsigned long) sa->sa_handler;
931
        regs->tnpc = (regs->tpc + 4);
932
        if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
933
                regs->tpc &= 0xffffffff;
934
                regs->tnpc &= 0xffffffff;
935
        }
936
 
937
#ifdef DEBUG_SIGNALS
938
        printk ("Solaris-frame: %x %x\n", (int) regs->tpc, (int) regs->tnpc);
939
#endif
940
        /* Arguments passed to signal handler */
941
        if (regs->u_regs [14]){
942
                struct reg_window32 *rw = (struct reg_window32 *)
943
                        (regs->u_regs [14] & 0x00000000ffffffffUL);
944
 
945
                err |= __put_user(signr, &rw->ins [0]);
946
                err |= __put_user((u64)si, &rw->ins [1]);
947
                err |= __put_user((u64)uc, &rw->ins [2]);
948
                err |= __put_user((u64)sfp, &rw->ins [6]);      /* frame pointer */
949
                if (err)
950
                        goto sigsegv;
951
 
952
                regs->u_regs[UREG_I0] = signr;
953
                regs->u_regs[UREG_I1] = (u32)(u64) si;
954
                regs->u_regs[UREG_I2] = (u32)(u64) uc;
955
        }
956
        return;
957
 
958
sigsegv:
959
        do_exit(SIGSEGV);
960
}
961
 
962
asmlinkage int
963
svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs)
964
{
965
        svr4_gregset_t  *gr;
966
        svr4_mcontext_t *mc;
967
        svr4_sigset_t setv;
968
        int i, err;
969
 
970
        synchronize_user_stack();
971
        save_and_clear_fpu();
972
 
973
        if (current->thread.w_saved){
974
                printk ("Uh oh, w_saved is not zero (%d)\n", (int) current->thread.w_saved);
975
                do_exit (SIGSEGV);
976
        }
977
        err = clear_user(uc, sizeof (*uc));
978
 
979
        /* Setup convenience variables */
980
        mc = &uc->mcontext;
981
        gr = &mc->greg;
982
 
983
        setv.sigbits[0] = current->blocked.sig[0];
984
        setv.sigbits[1] = (current->blocked.sig[0] >> 32);
985
        if (_NSIG_WORDS >= 2) {
986
                setv.sigbits[2] = current->blocked.sig[1];
987
                setv.sigbits[3] = (current->blocked.sig[1] >> 32);
988
                err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t));
989
        } else
990
                err |= __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned));
991
 
992
        /* Store registers */
993
        if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
994
                regs->tpc &= 0xffffffff;
995
                regs->tnpc &= 0xffffffff;
996
        }
997
        err |= __put_user(regs->tpc, &uc->mcontext.greg [SVR4_PC]);
998
        err |= __put_user(regs->tnpc, &uc->mcontext.greg [SVR4_NPC]);
999
#if 1
1000
        err |= __put_user(0, &uc->mcontext.greg [SVR4_PSR]);
1001
#else
1002
        i = tstate_to_psr(regs->tstate) & ~PSR_EF;
1003
        if (current->thread.fpsaved[0] & FPRS_FEF)
1004
                i |= PSR_EF;
1005
        err |= __put_user(i, &uc->mcontext.greg [SVR4_PSR]);
1006
#endif
1007
        err |= __put_user(regs->y, &uc->mcontext.greg [SVR4_Y]);
1008
 
1009
        /* Copy g [1..7] and o [0..7] registers */
1010
        for (i = 0; i < 7; i++)
1011
                err |= __put_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
1012
        for (i = 0; i < 8; i++)
1013
                err |= __put_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
1014
 
1015
        /* Setup sigaltstack */
1016
        err |= __put_user(current->sas_ss_sp, &uc->stack.sp);
1017
        err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags);
1018
        err |= __put_user(current->sas_ss_size, &uc->stack.size);
1019
 
1020
        /* The register file is not saved
1021
         * we have already stuffed all of it with sync_user_stack
1022
         */
1023
        return (err ? -EFAULT : 0);
1024
}
1025
 
1026
 
1027
/* Set the context for a svr4 application, this is Solaris way to sigreturn */
1028
asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs)
1029
{
1030
        struct thread_struct *tp = &current->thread;
1031
        svr4_gregset_t  *gr;
1032
        mm_segment_t old_fs;
1033
        u32 pc, npc, psr;
1034
        sigset_t set;
1035
        svr4_sigset_t setv;
1036
        int i, err;
1037
        stack_t st;
1038
 
1039
        /* Fixme: restore windows, or is this already taken care of in
1040
         * svr4_setup_frame when sync_user_windows is done?
1041
         */
1042
        flush_user_windows();
1043
 
1044
        if (tp->w_saved){
1045
                printk ("Uh oh, w_saved is: 0x%x\n", tp->w_saved);
1046
                goto sigsegv;
1047
        }
1048
        if (((unsigned long) c) & 3){
1049
                printk ("Unaligned structure passed\n");
1050
                goto sigsegv;
1051
        }
1052
 
1053
        if(!__access_ok((unsigned long)c, sizeof(*c))) {
1054
                /* Miguel, add nice debugging msg _here_. ;-) */
1055
                goto sigsegv;
1056
        }
1057
 
1058
        /* Check for valid PC and nPC */
1059
        gr = &c->mcontext.greg;
1060
        err = __get_user(pc, &((*gr)[SVR4_PC]));
1061
        err |= __get_user(npc, &((*gr)[SVR4_NPC]));
1062
        if((pc | npc) & 3) {
1063
#ifdef DEBUG_SIGNALS    
1064
                printk ("setcontext, PC or nPC were bogus\n");
1065
#endif
1066
                goto sigsegv;
1067
        }
1068
 
1069
        /* Retrieve information from passed ucontext */
1070
        /* note that nPC is ored a 1, this is used to inform entry.S */
1071
        /* that we don't want it to mess with our PC and nPC */
1072
 
1073
        err |= copy_from_user (&setv, &c->sigmask, sizeof(svr4_sigset_t));
1074
        set.sig[0] = setv.sigbits[0] | (((long)setv.sigbits[1]) << 32);
1075
        if (_NSIG_WORDS >= 2)
1076
                set.sig[1] = setv.sigbits[2] | (((long)setv.sigbits[3]) << 32);
1077
 
1078
        err |= __get_user((long)st.ss_sp, &c->stack.sp);
1079
        err |= __get_user(st.ss_flags, &c->stack.flags);
1080
        err |= __get_user(st.ss_size, &c->stack.size);
1081
        if (err)
1082
                goto sigsegv;
1083
 
1084
        /* It is more difficult to avoid calling this function than to
1085
           call it and ignore errors.  */
1086
        old_fs = get_fs();
1087
        set_fs(KERNEL_DS);
1088
        do_sigaltstack(&st, NULL, regs->u_regs[UREG_I6]);
1089
        set_fs(old_fs);
1090
 
1091
        sigdelsetmask(&set, ~_BLOCKABLE);
1092
        spin_lock_irq(&current->sigmask_lock);
1093
        current->blocked = set;
1094
        recalc_sigpending(current);
1095
        spin_unlock_irq(&current->sigmask_lock);
1096
        regs->tpc = pc;
1097
        regs->tnpc = npc | 1;
1098
        if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
1099
                regs->tpc &= 0xffffffff;
1100
                regs->tnpc &= 0xffffffff;
1101
        }
1102
        err |= __get_user(regs->y, &((*gr) [SVR4_Y]));
1103
        err |= __get_user(psr, &((*gr) [SVR4_PSR]));
1104
        regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
1105
        regs->tstate |= psr_to_tstate_icc(psr);
1106
#if 0   
1107
        if(psr & PSR_EF)
1108
                regs->tstate |= TSTATE_PEF;
1109
#endif
1110
        /* Restore g[1..7] and o[0..7] registers */
1111
        for (i = 0; i < 7; i++)
1112
                err |= __get_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
1113
        for (i = 0; i < 8; i++)
1114
                err |= __get_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
1115
        if(err)
1116
                goto sigsegv;
1117
 
1118
        return -EINTR;
1119
sigsegv:
1120
        do_exit(SIGSEGV);
1121
}
1122
 
1123
static inline void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
1124
                                        unsigned long signr, sigset_t *oldset,
1125
                                        siginfo_t *info)
1126
{
1127
        struct rt_signal_frame32 *sf;
1128
        int sigframe_size;
1129
        u32 psr;
1130
        int i, err;
1131
        sigset_t32 seta;
1132
 
1133
        /* 1. Make sure everything is clean */
1134
        synchronize_user_stack();
1135
        save_and_clear_fpu();
1136
 
1137
        sigframe_size = RT_ALIGNEDSZ;
1138
        if (!(current->thread.fpsaved[0] & FPRS_FEF))
1139
                sigframe_size -= sizeof(__siginfo_fpu_t);
1140
 
1141
        sf = (struct rt_signal_frame32 *)get_sigframe(&ka->sa, regs, sigframe_size);
1142
 
1143
        if (invalid_frame_pointer (sf, sigframe_size)) {
1144
#ifdef DEBUG_SIGNALS
1145
                printk("rt_setup_frame32(%s:%d): invalid_frame_pointer(%p, %d)\n",
1146
                       current->comm, current->pid, sf, sigframe_size);
1147
#endif
1148
                goto sigill;
1149
        }
1150
 
1151
        if (current->thread.w_saved != 0) {
1152
#ifdef DEBUG_SIGNALS
1153
                printk ("%s[%d]: Invalid user stack frame for "
1154
                        "signal delivery.\n", current->comm, current->pid);
1155
#endif
1156
                goto sigill;
1157
        }
1158
 
1159
        /* 2. Save the current process state */
1160
        if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
1161
                regs->tpc &= 0xffffffff;
1162
                regs->tnpc &= 0xffffffff;
1163
        }
1164
        err  = put_user(regs->tpc, &sf->regs.pc);
1165
        err |= __put_user(regs->tnpc, &sf->regs.npc);
1166
        err |= __put_user(regs->y, &sf->regs.y);
1167
        psr = tstate_to_psr (regs->tstate);
1168
        if(current->thread.fpsaved[0] & FPRS_FEF)
1169
                psr |= PSR_EF;
1170
        err |= __put_user(psr, &sf->regs.psr);
1171
        for (i = 0; i < 16; i++)
1172
                err |= __put_user(regs->u_regs[i], &sf->regs.u_regs[i]);
1173
        err |= __put_user(sizeof(siginfo_extra_v8plus_t), &sf->extra_size);
1174
        err |= __put_user(SIGINFO_EXTRA_V8PLUS_MAGIC, &sf->v8plus.g_upper[0]);
1175
        for (i = 1; i < 16; i++)
1176
                err |= __put_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]);
1177
 
1178
        if (psr & PSR_EF) {
1179
                err |= save_fpu_state32(regs, &sf->fpu_state);
1180
                err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
1181
        } else {
1182
                err |= __put_user(0, &sf->fpu_save);
1183
        }
1184
 
1185
        /* Update the siginfo structure.  */
1186
        err |= copy_siginfo_to_user32(&sf->info, info);
1187
 
1188
        /* Setup sigaltstack */
1189
        err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
1190
        err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
1191
        err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
1192
 
1193
        switch (_NSIG_WORDS) {
1194
        case 4: seta.sig[7] = (oldset->sig[3] >> 32);
1195
                seta.sig[6] = oldset->sig[3];
1196
        case 3: seta.sig[5] = (oldset->sig[2] >> 32);
1197
                seta.sig[4] = oldset->sig[2];
1198
        case 2: seta.sig[3] = (oldset->sig[1] >> 32);
1199
                seta.sig[2] = oldset->sig[1];
1200
        case 1: seta.sig[1] = (oldset->sig[0] >> 32);
1201
                seta.sig[0] = oldset->sig[0];
1202
        }
1203
        err |= __copy_to_user(&sf->mask, &seta, sizeof(sigset_t32));
1204
 
1205
        err |= copy_in_user((u32 *)sf,
1206
                            (u32 *)(regs->u_regs[UREG_FP]),
1207
                            sizeof(struct reg_window32));
1208
        if (err)
1209
                goto sigsegv;
1210
 
1211
        /* 3. signal handler back-trampoline and parameters */
1212
        regs->u_regs[UREG_FP] = (unsigned long) sf;
1213
        regs->u_regs[UREG_I0] = signr;
1214
        regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
1215
        regs->u_regs[UREG_I2] = (unsigned long) &sf->regs;
1216
 
1217
        /* 4. signal handler */
1218
        regs->tpc = (unsigned long) ka->sa.sa_handler;
1219
        regs->tnpc = (regs->tpc + 4);
1220
        if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
1221
                regs->tpc &= 0xffffffff;
1222
                regs->tnpc &= 0xffffffff;
1223
        }
1224
 
1225
        /* 5. return to kernel instructions */
1226
        if (ka->ka_restorer)
1227
                regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
1228
        else {
1229
                /* Flush instruction space. */
1230
                unsigned long address = ((unsigned long)&(sf->insns[0]));
1231
                pgd_t *pgdp = pgd_offset(current->mm, address);
1232
                pmd_t *pmdp = pmd_offset(pgdp, address);
1233
                pte_t *ptep = pte_offset(pmdp, address);
1234
 
1235
                regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
1236
 
1237
                /* mov __NR_rt_sigreturn, %g1 */
1238
                err |= __put_user(0x82102065, &sf->insns[0]);
1239
 
1240
                /* t 0x10 */
1241
                err |= __put_user(0x91d02010, &sf->insns[1]);
1242
                if (err)
1243
                        goto sigsegv;
1244
 
1245
                if(pte_present(*ptep)) {
1246
                        unsigned long page = (unsigned long) page_address(pte_page(*ptep));
1247
 
1248
                        __asm__ __volatile__(
1249
                        "       membar  #StoreStore\n"
1250
                        "       flush   %0 + %1"
1251
                        : : "r" (page), "r" (address & (PAGE_SIZE - 1))
1252
                        : "memory");
1253
                }
1254
        }
1255
        return;
1256
 
1257
sigill:
1258
        do_exit(SIGILL);
1259
sigsegv:
1260
        do_exit(SIGSEGV);
1261
}
1262
 
1263
static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
1264
                                   siginfo_t *info,
1265
                                   sigset_t *oldset, struct pt_regs *regs,
1266
                                   int svr4_signal)
1267
{
1268
        if(svr4_signal)
1269
                setup_svr4_frame32(&ka->sa, regs->tpc, regs->tnpc, regs, signr, oldset);
1270
        else {
1271
                if (ka->sa.sa_flags & SA_SIGINFO)
1272
                        setup_rt_frame32(ka, regs, signr, oldset, info);
1273
                else if (current->thread.flags & SPARC_FLAG_NEWSIGNALS)
1274
                        new_setup_frame32(ka, regs, signr, oldset);
1275
                else
1276
                        setup_frame32(&ka->sa, regs, signr, oldset, info);
1277
        }
1278
        if(ka->sa.sa_flags & SA_ONESHOT)
1279
                ka->sa.sa_handler = SIG_DFL;
1280
        if(!(ka->sa.sa_flags & SA_NOMASK)) {
1281
                spin_lock_irq(&current->sigmask_lock);
1282
                sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
1283
                sigaddset(&current->blocked,signr);
1284
                recalc_sigpending(current);
1285
                spin_unlock_irq(&current->sigmask_lock);
1286
        }
1287
}
1288
 
1289
static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
1290
                                     struct sigaction *sa)
1291
{
1292
        switch(regs->u_regs[UREG_I0]) {
1293
                case ERESTARTNOHAND:
1294
                no_system_call_restart:
1295
                        regs->u_regs[UREG_I0] = EINTR;
1296
                        regs->tstate |= TSTATE_ICARRY;
1297
                        break;
1298
                case ERESTARTSYS:
1299
                        if(!(sa->sa_flags & SA_RESTART))
1300
                                goto no_system_call_restart;
1301
                /* fallthrough */
1302
                case ERESTARTNOINTR:
1303
                        regs->u_regs[UREG_I0] = orig_i0;
1304
                        regs->tpc -= 4;
1305
                        regs->tnpc -= 4;
1306
        }
1307
}
1308
 
1309
#ifdef DEBUG_SIGNALS_MAPS
1310
 
1311
#define MAPS_LINE_FORMAT          "%016lx-%016lx %s %016lx %s %lu "
1312
 
1313
static inline void read_maps (void)
1314
{
1315
        struct vm_area_struct * map, * next;
1316
        char * buffer;
1317
        ssize_t i;
1318
 
1319
        buffer = (char*)__get_free_page(GFP_KERNEL);
1320
        if (!buffer)
1321
                return;
1322
 
1323
        for (map = current->mm->mmap ; map ; map = next ) {
1324
                /* produce the next line */
1325
                char *line;
1326
                char str[5], *cp = str;
1327
                int flags;
1328
                kdev_t dev;
1329
                unsigned long ino;
1330
 
1331
                /*
1332
                 * Get the next vma now (but it won't be used if we sleep).
1333
                 */
1334
                next = map->vm_next;
1335
                flags = map->vm_flags;
1336
 
1337
                *cp++ = flags & VM_READ ? 'r' : '-';
1338
                *cp++ = flags & VM_WRITE ? 'w' : '-';
1339
                *cp++ = flags & VM_EXEC ? 'x' : '-';
1340
                *cp++ = flags & VM_MAYSHARE ? 's' : 'p';
1341
                *cp++ = 0;
1342
 
1343
                dev = 0;
1344
                ino = 0;
1345
                if (map->vm_file != NULL) {
1346
                        dev = map->vm_file->f_dentry->d_inode->i_dev;
1347
                        ino = map->vm_file->f_dentry->d_inode->i_ino;
1348
                        line = d_path(map->vm_file->f_dentry,
1349
                                      map->vm_file->f_vfsmnt,
1350
                                      buffer, PAGE_SIZE);
1351
                        if (IS_ERR(line))
1352
                                break;
1353
                }
1354
                printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT,
1355
                              kdevname(dev), ino);
1356
                if (map->vm_file != NULL)
1357
                        printk("%s\n", line);
1358
                else
1359
                        printk("\n");
1360
        }
1361
        free_page((unsigned long)buffer);
1362
        return;
1363
}
1364
 
1365
#endif
1366
 
1367
/* Note that 'init' is a special process: it doesn't get signals it doesn't
1368
 * want to handle. Thus you cannot kill init even with a SIGKILL even by
1369
 * mistake.
1370
 */
1371
asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs * regs,
1372
                           unsigned long orig_i0, int restart_syscall)
1373
{
1374
        unsigned long signr;
1375
        struct k_sigaction *ka;
1376
        siginfo_t info;
1377
 
1378
        int svr4_signal = current->personality == PER_SVR4;
1379
 
1380
        for (;;) {
1381
                spin_lock_irq(&current->sigmask_lock);
1382
                signr = dequeue_signal(&current->blocked, &info);
1383
                spin_unlock_irq(&current->sigmask_lock);
1384
 
1385
                if (!signr)
1386
                        break;
1387
 
1388
                if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
1389
                        /* Do the syscall restart before we let the debugger
1390
                         * look at the child registers.
1391
                         */
1392
                        if (restart_syscall &&
1393
                            (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
1394
                             regs->u_regs[UREG_I0] == ERESTARTSYS ||
1395
                             regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
1396
                                regs->u_regs[UREG_I0] = orig_i0;
1397
                                regs->tpc -= 4;
1398
                                regs->tnpc -= 4;
1399
                                restart_syscall = 0;
1400
                        }
1401
 
1402
                        current->exit_code = signr;
1403
                        current->state = TASK_STOPPED;
1404
                        notify_parent(current, SIGCHLD);
1405
                        schedule();
1406
                        if (!(signr = current->exit_code))
1407
                                continue;
1408
                        current->exit_code = 0;
1409
                        if (signr == SIGSTOP)
1410
                                continue;
1411
 
1412
                        /* Update the siginfo structure.  Is this good?  */
1413
                        if (signr != info.si_signo) {
1414
                                info.si_signo = signr;
1415
                                info.si_errno = 0;
1416
                                info.si_code = SI_USER;
1417
                                info.si_pid = current->p_pptr->pid;
1418
                                info.si_uid = current->p_pptr->uid;
1419
                        }
1420
 
1421
                        /* If the (new) signal is now blocked, requeue it.  */
1422
                        if (sigismember(&current->blocked, signr)) {
1423
                                send_sig_info(signr, &info, current);
1424
                                continue;
1425
                        }
1426
                }
1427
 
1428
                ka = &current->sig->action[signr-1];
1429
 
1430
                if (ka->sa.sa_handler == SIG_IGN) {
1431
                        if (signr != SIGCHLD)
1432
                                continue;
1433
 
1434
                        /* sys_wait4() grabs the master kernel lock, so
1435
                         * we need not do so, that sucker should be
1436
                         * threaded and would not be that difficult to
1437
                         * do anyways.
1438
                         */
1439
                        while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
1440
                                ;
1441
                        continue;
1442
                }
1443
                if (ka->sa.sa_handler == SIG_DFL) {
1444
                        unsigned long exit_code = signr;
1445
 
1446
                        if (current->pid == 1)
1447
                                continue;
1448
                        switch (signr) {
1449
                        case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
1450
                                continue;
1451
 
1452
                        case SIGTSTP: case SIGTTIN: case SIGTTOU:
1453
                                if (is_orphaned_pgrp(current->pgrp))
1454
                                        continue;
1455
 
1456
                        case SIGSTOP:
1457
                                if (current->ptrace & PT_PTRACED)
1458
                                        continue;
1459
                                current->state = TASK_STOPPED;
1460
                                current->exit_code = signr;
1461
                                if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags &
1462
                                      SA_NOCLDSTOP))
1463
                                        notify_parent(current, SIGCHLD);
1464
                                schedule();
1465
                                continue;
1466
 
1467
                        case SIGQUIT: case SIGILL: case SIGTRAP:
1468
                        case SIGABRT: case SIGFPE: case SIGSEGV:
1469
                        case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
1470
                                if (do_coredump(signr, regs))
1471
                                        exit_code |= 0x80;
1472
#ifdef DEBUG_SIGNALS
1473
                                /* Very useful to debug dynamic linker problems */
1474
                                printk ("Sig %ld going for %s[%d]...\n", signr, current->comm, current->pid);
1475
                                /* On SMP we are only interested in the current
1476
                                 * CPU's registers.
1477
                                 */
1478
                                __show_regs (regs);
1479
#ifdef DEBUG_SIGNALS_TLB
1480
                                do {
1481
                                        extern void sparc_ultra_dump_itlb(void);
1482
                                        extern void sparc_ultra_dump_dtlb(void);
1483
                                        sparc_ultra_dump_dtlb();
1484
                                        sparc_ultra_dump_itlb();
1485
                                } while(0);
1486
#endif
1487
#ifdef DEBUG_SIGNALS_TRACE
1488
                                {
1489
                                        struct reg_window32 *rw = (struct reg_window32 *)(regs->u_regs[UREG_FP] & 0xffffffff);
1490
                                        unsigned int ins[8];
1491
 
1492
                                        while (rw &&
1493
                                               !(((unsigned long) rw) & 0x3)) {
1494
                                                copy_from_user(ins, &rw->ins[0], sizeof(ins));
1495
                                                printk("Caller[%08x](%08x,%08x,%08x,%08x,%08x,%08x)\n", ins[7], ins[0], ins[1], ins[2], ins[3], ins[4], ins[5]);
1496
                                                rw = (struct reg_window32 *)(unsigned long)ins[6];
1497
                                        }
1498
                                }
1499
#endif                  
1500
#ifdef DEBUG_SIGNALS_MAPS       
1501
                                printk("Maps:\n");
1502
                                read_maps();
1503
#endif
1504
#endif
1505
                                /* fall through */
1506
                        default:
1507
                                sig_exit(signr, exit_code, &info);
1508
                                /* NOT REACHED */
1509
                        }
1510
                }
1511
                if (restart_syscall)
1512
                        syscall_restart32(orig_i0, regs, &ka->sa);
1513
                handle_signal32(signr, ka, &info, oldset, regs, svr4_signal);
1514
                return 1;
1515
        }
1516
        if (restart_syscall &&
1517
            (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
1518
             regs->u_regs[UREG_I0] == ERESTARTSYS ||
1519
             regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
1520
                /* replay the system call when we are done */
1521
                regs->u_regs[UREG_I0] = orig_i0;
1522
                regs->tpc -= 4;
1523
                regs->tnpc -= 4;
1524
        }
1525
        return 0;
1526
}
1527
 
1528
struct sigstack32 {
1529
        u32 the_stack;
1530
        int cur_status;
1531
};
1532
 
1533
asmlinkage int do_sys32_sigstack(u32 u_ssptr, u32 u_ossptr, unsigned long sp)
1534
{
1535
        struct sigstack32 *ssptr = (struct sigstack32 *)((unsigned long)(u_ssptr));
1536
        struct sigstack32 *ossptr = (struct sigstack32 *)((unsigned long)(u_ossptr));
1537
        int ret = -EFAULT;
1538
 
1539
        /* First see if old state is wanted. */
1540
        if (ossptr) {
1541
                if (put_user(current->sas_ss_sp + current->sas_ss_size, &ossptr->the_stack) ||
1542
                    __put_user(on_sig_stack(sp), &ossptr->cur_status))
1543
                        goto out;
1544
        }
1545
 
1546
        /* Now see if we want to update the new state. */
1547
        if (ssptr) {
1548
                void *ss_sp;
1549
 
1550
                if (get_user((long)ss_sp, &ssptr->the_stack))
1551
                        goto out;
1552
                /* If the current stack was set with sigaltstack, don't
1553
                   swap stacks while we are on it.  */
1554
                ret = -EPERM;
1555
                if (current->sas_ss_sp && on_sig_stack(sp))
1556
                        goto out;
1557
 
1558
                /* Since we don't know the extent of the stack, and we don't
1559
                   track onstack-ness, but rather calculate it, we must
1560
                   presume a size.  Ho hum this interface is lossy.  */
1561
                current->sas_ss_sp = (unsigned long)ss_sp - SIGSTKSZ;
1562
                current->sas_ss_size = SIGSTKSZ;
1563
        }
1564
 
1565
        ret = 0;
1566
out:
1567
        return ret;
1568
}
1569
 
1570
asmlinkage int do_sys32_sigaltstack(u32 ussa, u32 uossa, unsigned long sp)
1571
{
1572
        stack_t uss, uoss;
1573
        int ret;
1574
        mm_segment_t old_fs;
1575
 
1576
        if (ussa && (get_user((long)uss.ss_sp, &((stack_t32 *)(long)ussa)->ss_sp) ||
1577
                    __get_user(uss.ss_flags, &((stack_t32 *)(long)ussa)->ss_flags) ||
1578
                    __get_user(uss.ss_size, &((stack_t32 *)(long)ussa)->ss_size)))
1579
                return -EFAULT;
1580
        old_fs = get_fs();
1581
        set_fs(KERNEL_DS);
1582
        ret = do_sigaltstack(ussa ? &uss : NULL, uossa ? &uoss : NULL, sp);
1583
        set_fs(old_fs);
1584
        if (!ret && uossa && (put_user((long)uoss.ss_sp, &((stack_t32 *)(long)uossa)->ss_sp) ||
1585
                    __put_user(uoss.ss_flags, &((stack_t32 *)(long)uossa)->ss_flags) ||
1586
                    __put_user(uoss.ss_size, &((stack_t32 *)(long)uossa)->ss_size)))
1587
                return -EFAULT;
1588
        return ret;
1589
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.