Root/arch/s390/kernel/ptrace.c

1/*
2 * arch/s390/kernel/ptrace.c
3 *
4 * S390 version
5 * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
6 * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
7 * Martin Schwidefsky (schwidefsky@de.ibm.com)
8 *
9 * Based on PowerPC version
10 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
11 *
12 * Derived from "arch/m68k/kernel/ptrace.c"
13 * Copyright (C) 1994 by Hamish Macdonald
14 * Taken from linux/kernel/ptrace.c and modified for M680x0.
15 * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
16 *
17 * Modified by Cort Dougan (cort@cs.nmt.edu)
18 *
19 *
20 * This file is subject to the terms and conditions of the GNU General
21 * Public License. See the file README.legal in the main directory of
22 * this archive for more details.
23 */
24
25#include <linux/kernel.h>
26#include <linux/sched.h>
27#include <linux/mm.h>
28#include <linux/smp.h>
29#include <linux/errno.h>
30#include <linux/ptrace.h>
31#include <linux/user.h>
32#include <linux/security.h>
33#include <linux/audit.h>
34#include <linux/signal.h>
35#include <linux/elf.h>
36#include <linux/regset.h>
37#include <linux/tracehook.h>
38#include <linux/seccomp.h>
39#include <trace/syscall.h>
40#include <asm/compat.h>
41#include <asm/segment.h>
42#include <asm/page.h>
43#include <asm/pgtable.h>
44#include <asm/pgalloc.h>
45#include <asm/system.h>
46#include <asm/uaccess.h>
47#include <asm/unistd.h>
48#include "entry.h"
49
50#ifdef CONFIG_COMPAT
51#include "compat_ptrace.h"
52#endif
53
54#define CREATE_TRACE_POINTS
55#include <trace/events/syscalls.h>
56
57enum s390_regset {
58    REGSET_GENERAL,
59    REGSET_FP,
60    REGSET_LAST_BREAK,
61    REGSET_GENERAL_EXTENDED,
62};
63
64static void
65FixPerRegisters(struct task_struct *task)
66{
67    struct pt_regs *regs;
68    per_struct *per_info;
69    per_cr_words cr_words;
70
71    regs = task_pt_regs(task);
72    per_info = (per_struct *) &task->thread.per_info;
73    per_info->control_regs.bits.em_instruction_fetch =
74        per_info->single_step | per_info->instruction_fetch;
75    
76    if (per_info->single_step) {
77        per_info->control_regs.bits.starting_addr = 0;
78#ifdef CONFIG_COMPAT
79        if (is_compat_task())
80            per_info->control_regs.bits.ending_addr = 0x7fffffffUL;
81        else
82#endif
83            per_info->control_regs.bits.ending_addr = PSW_ADDR_INSN;
84    } else {
85        per_info->control_regs.bits.starting_addr =
86            per_info->starting_addr;
87        per_info->control_regs.bits.ending_addr =
88            per_info->ending_addr;
89    }
90    /*
91     * if any of the control reg tracing bits are on
92     * we switch on per in the psw
93     */
94    if (per_info->control_regs.words.cr[0] & PER_EM_MASK)
95        regs->psw.mask |= PSW_MASK_PER;
96    else
97        regs->psw.mask &= ~PSW_MASK_PER;
98
99    if (per_info->control_regs.bits.em_storage_alteration)
100        per_info->control_regs.bits.storage_alt_space_ctl = 1;
101    else
102        per_info->control_regs.bits.storage_alt_space_ctl = 0;
103
104    if (task == current) {
105        __ctl_store(cr_words, 9, 11);
106        if (memcmp(&cr_words, &per_info->control_regs.words,
107               sizeof(cr_words)) != 0)
108            __ctl_load(per_info->control_regs.words, 9, 11);
109    }
110}
111
112void user_enable_single_step(struct task_struct *task)
113{
114    task->thread.per_info.single_step = 1;
115    FixPerRegisters(task);
116}
117
118void user_disable_single_step(struct task_struct *task)
119{
120    task->thread.per_info.single_step = 0;
121    FixPerRegisters(task);
122}
123
124/*
125 * Called by kernel/ptrace.c when detaching..
126 *
127 * Make sure single step bits etc are not set.
128 */
129void
130ptrace_disable(struct task_struct *child)
131{
132    /* make sure the single step bit is not set. */
133    user_disable_single_step(child);
134}
135
136#ifndef CONFIG_64BIT
137# define __ADDR_MASK 3
138#else
139# define __ADDR_MASK 7
140#endif
141
142/*
143 * Read the word at offset addr from the user area of a process. The
144 * trouble here is that the information is littered over different
145 * locations. The process registers are found on the kernel stack,
146 * the floating point stuff and the trace settings are stored in
147 * the task structure. In addition the different structures in
148 * struct user contain pad bytes that should be read as zeroes.
149 * Lovely...
150 */
151static unsigned long __peek_user(struct task_struct *child, addr_t addr)
152{
153    struct user *dummy = NULL;
154    addr_t offset, tmp;
155
156    if (addr < (addr_t) &dummy->regs.acrs) {
157        /*
158         * psw and gprs are stored on the stack
159         */
160        tmp = *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr);
161        if (addr == (addr_t) &dummy->regs.psw.mask)
162            /* Remove per bit from user psw. */
163            tmp &= ~PSW_MASK_PER;
164
165    } else if (addr < (addr_t) &dummy->regs.orig_gpr2) {
166        /*
167         * access registers are stored in the thread structure
168         */
169        offset = addr - (addr_t) &dummy->regs.acrs;
170#ifdef CONFIG_64BIT
171        /*
172         * Very special case: old & broken 64 bit gdb reading
173         * from acrs[15]. Result is a 64 bit value. Read the
174         * 32 bit acrs[15] value and shift it by 32. Sick...
175         */
176        if (addr == (addr_t) &dummy->regs.acrs[15])
177            tmp = ((unsigned long) child->thread.acrs[15]) << 32;
178        else
179#endif
180        tmp = *(addr_t *)((addr_t) &child->thread.acrs + offset);
181
182    } else if (addr == (addr_t) &dummy->regs.orig_gpr2) {
183        /*
184         * orig_gpr2 is stored on the kernel stack
185         */
186        tmp = (addr_t) task_pt_regs(child)->orig_gpr2;
187
188    } else if (addr < (addr_t) &dummy->regs.fp_regs) {
189        /*
190         * prevent reads of padding hole between
191         * orig_gpr2 and fp_regs on s390.
192         */
193        tmp = 0;
194
195    } else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) {
196        /*
197         * floating point regs. are stored in the thread structure
198         */
199        offset = addr - (addr_t) &dummy->regs.fp_regs;
200        tmp = *(addr_t *)((addr_t) &child->thread.fp_regs + offset);
201        if (addr == (addr_t) &dummy->regs.fp_regs.fpc)
202            tmp &= (unsigned long) FPC_VALID_MASK
203                << (BITS_PER_LONG - 32);
204
205    } else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
206        /*
207         * per_info is found in the thread structure
208         */
209        offset = addr - (addr_t) &dummy->regs.per_info;
210        tmp = *(addr_t *)((addr_t) &child->thread.per_info + offset);
211
212    } else
213        tmp = 0;
214
215    return tmp;
216}
217
218static int
219peek_user(struct task_struct *child, addr_t addr, addr_t data)
220{
221    addr_t tmp, mask;
222
223    /*
224     * Stupid gdb peeks/pokes the access registers in 64 bit with
225     * an alignment of 4. Programmers from hell...
226     */
227    mask = __ADDR_MASK;
228#ifdef CONFIG_64BIT
229    if (addr >= (addr_t) &((struct user *) NULL)->regs.acrs &&
230        addr < (addr_t) &((struct user *) NULL)->regs.orig_gpr2)
231        mask = 3;
232#endif
233    if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK)
234        return -EIO;
235
236    tmp = __peek_user(child, addr);
237    return put_user(tmp, (addr_t __user *) data);
238}
239
240/*
241 * Write a word to the user area of a process at location addr. This
242 * operation does have an additional problem compared to peek_user.
243 * Stores to the program status word and on the floating point
244 * control register needs to get checked for validity.
245 */
246static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
247{
248    struct user *dummy = NULL;
249    addr_t offset;
250
251    if (addr < (addr_t) &dummy->regs.acrs) {
252        /*
253         * psw and gprs are stored on the stack
254         */
255        if (addr == (addr_t) &dummy->regs.psw.mask &&
256#ifdef CONFIG_COMPAT
257            data != PSW_MASK_MERGE(psw_user32_bits, data) &&
258#endif
259            data != PSW_MASK_MERGE(psw_user_bits, data))
260            /* Invalid psw mask. */
261            return -EINVAL;
262#ifndef CONFIG_64BIT
263        if (addr == (addr_t) &dummy->regs.psw.addr)
264            /* I'd like to reject addresses without the
265               high order bit but older gdb's rely on it */
266            data |= PSW_ADDR_AMODE;
267#endif
268        *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data;
269
270    } else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) {
271        /*
272         * access registers are stored in the thread structure
273         */
274        offset = addr - (addr_t) &dummy->regs.acrs;
275#ifdef CONFIG_64BIT
276        /*
277         * Very special case: old & broken 64 bit gdb writing
278         * to acrs[15] with a 64 bit value. Ignore the lower
279         * half of the value and write the upper 32 bit to
280         * acrs[15]. Sick...
281         */
282        if (addr == (addr_t) &dummy->regs.acrs[15])
283            child->thread.acrs[15] = (unsigned int) (data >> 32);
284        else
285#endif
286        *(addr_t *)((addr_t) &child->thread.acrs + offset) = data;
287
288    } else if (addr == (addr_t) &dummy->regs.orig_gpr2) {
289        /*
290         * orig_gpr2 is stored on the kernel stack
291         */
292        task_pt_regs(child)->orig_gpr2 = data;
293
294    } else if (addr < (addr_t) &dummy->regs.fp_regs) {
295        /*
296         * prevent writes of padding hole between
297         * orig_gpr2 and fp_regs on s390.
298         */
299        return 0;
300
301    } else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) {
302        /*
303         * floating point regs. are stored in the thread structure
304         */
305        if (addr == (addr_t) &dummy->regs.fp_regs.fpc &&
306            (data & ~((unsigned long) FPC_VALID_MASK
307                  << (BITS_PER_LONG - 32))) != 0)
308            return -EINVAL;
309        offset = addr - (addr_t) &dummy->regs.fp_regs;
310        *(addr_t *)((addr_t) &child->thread.fp_regs + offset) = data;
311
312    } else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
313        /*
314         * per_info is found in the thread structure
315         */
316        offset = addr - (addr_t) &dummy->regs.per_info;
317        *(addr_t *)((addr_t) &child->thread.per_info + offset) = data;
318
319    }
320
321    FixPerRegisters(child);
322    return 0;
323}
324
325static int
326poke_user(struct task_struct *child, addr_t addr, addr_t data)
327{
328    addr_t mask;
329
330    /*
331     * Stupid gdb peeks/pokes the access registers in 64 bit with
332     * an alignment of 4. Programmers from hell indeed...
333     */
334    mask = __ADDR_MASK;
335#ifdef CONFIG_64BIT
336    if (addr >= (addr_t) &((struct user *) NULL)->regs.acrs &&
337        addr < (addr_t) &((struct user *) NULL)->regs.orig_gpr2)
338        mask = 3;
339#endif
340    if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK)
341        return -EIO;
342
343    return __poke_user(child, addr, data);
344}
345
346long arch_ptrace(struct task_struct *child, long request,
347         unsigned long addr, unsigned long data)
348{
349    ptrace_area parea;
350    int copied, ret;
351
352    switch (request) {
353    case PTRACE_PEEKUSR:
354        /* read the word at location addr in the USER area. */
355        return peek_user(child, addr, data);
356
357    case PTRACE_POKEUSR:
358        /* write the word at location addr in the USER area */
359        return poke_user(child, addr, data);
360
361    case PTRACE_PEEKUSR_AREA:
362    case PTRACE_POKEUSR_AREA:
363        if (copy_from_user(&parea, (void __force __user *) addr,
364                            sizeof(parea)))
365            return -EFAULT;
366        addr = parea.kernel_addr;
367        data = parea.process_addr;
368        copied = 0;
369        while (copied < parea.len) {
370            if (request == PTRACE_PEEKUSR_AREA)
371                ret = peek_user(child, addr, data);
372            else {
373                addr_t utmp;
374                if (get_user(utmp,
375                         (addr_t __force __user *) data))
376                    return -EFAULT;
377                ret = poke_user(child, addr, utmp);
378            }
379            if (ret)
380                return ret;
381            addr += sizeof(unsigned long);
382            data += sizeof(unsigned long);
383            copied += sizeof(unsigned long);
384        }
385        return 0;
386    case PTRACE_GET_LAST_BREAK:
387        put_user(task_thread_info(child)->last_break,
388             (unsigned long __user *) data);
389        return 0;
390    default:
391        /* Removing high order bit from addr (only for 31 bit). */
392        addr &= PSW_ADDR_INSN;
393        return ptrace_request(child, request, addr, data);
394    }
395}
396
397#ifdef CONFIG_COMPAT
398/*
399 * Now the fun part starts... a 31 bit program running in the
400 * 31 bit emulation tracing another program. PTRACE_PEEKTEXT,
401 * PTRACE_PEEKDATA, PTRACE_POKETEXT and PTRACE_POKEDATA are easy
402 * to handle, the difference to the 64 bit versions of the requests
403 * is that the access is done in multiples of 4 byte instead of
404 * 8 bytes (sizeof(unsigned long) on 31/64 bit).
405 * The ugly part are PTRACE_PEEKUSR, PTRACE_PEEKUSR_AREA,
406 * PTRACE_POKEUSR and PTRACE_POKEUSR_AREA. If the traced program
407 * is a 31 bit program too, the content of struct user can be
408 * emulated. A 31 bit program peeking into the struct user of
409 * a 64 bit program is a no-no.
410 */
411
412/*
413 * Same as peek_user but for a 31 bit program.
414 */
415static u32 __peek_user_compat(struct task_struct *child, addr_t addr)
416{
417    struct user32 *dummy32 = NULL;
418    per_struct32 *dummy_per32 = NULL;
419    addr_t offset;
420    __u32 tmp;
421
422    if (addr < (addr_t) &dummy32->regs.acrs) {
423        /*
424         * psw and gprs are stored on the stack
425         */
426        if (addr == (addr_t) &dummy32->regs.psw.mask) {
427            /* Fake a 31 bit psw mask. */
428            tmp = (__u32)(task_pt_regs(child)->psw.mask >> 32);
429            tmp = PSW32_MASK_MERGE(psw32_user_bits, tmp);
430        } else if (addr == (addr_t) &dummy32->regs.psw.addr) {
431            /* Fake a 31 bit psw address. */
432            tmp = (__u32) task_pt_regs(child)->psw.addr |
433                PSW32_ADDR_AMODE31;
434        } else {
435            /* gpr 0-15 */
436            tmp = *(__u32 *)((addr_t) &task_pt_regs(child)->psw +
437                     addr*2 + 4);
438        }
439    } else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) {
440        /*
441         * access registers are stored in the thread structure
442         */
443        offset = addr - (addr_t) &dummy32->regs.acrs;
444        tmp = *(__u32*)((addr_t) &child->thread.acrs + offset);
445
446    } else if (addr == (addr_t) (&dummy32->regs.orig_gpr2)) {
447        /*
448         * orig_gpr2 is stored on the kernel stack
449         */
450        tmp = *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4);
451
452    } else if (addr < (addr_t) &dummy32->regs.fp_regs) {
453        /*
454         * prevent reads of padding hole between
455         * orig_gpr2 and fp_regs on s390.
456         */
457        tmp = 0;
458
459    } else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
460        /*
461         * floating point regs. are stored in the thread structure
462         */
463            offset = addr - (addr_t) &dummy32->regs.fp_regs;
464        tmp = *(__u32 *)((addr_t) &child->thread.fp_regs + offset);
465
466    } else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) {
467        /*
468         * per_info is found in the thread structure
469         */
470        offset = addr - (addr_t) &dummy32->regs.per_info;
471        /* This is magic. See per_struct and per_struct32. */
472        if ((offset >= (addr_t) &dummy_per32->control_regs &&
473             offset < (addr_t) (&dummy_per32->control_regs + 1)) ||
474            (offset >= (addr_t) &dummy_per32->starting_addr &&
475             offset <= (addr_t) &dummy_per32->ending_addr) ||
476            offset == (addr_t) &dummy_per32->lowcore.words.address)
477            offset = offset*2 + 4;
478        else
479            offset = offset*2;
480        tmp = *(__u32 *)((addr_t) &child->thread.per_info + offset);
481
482    } else
483        tmp = 0;
484
485    return tmp;
486}
487
488static int peek_user_compat(struct task_struct *child,
489                addr_t addr, addr_t data)
490{
491    __u32 tmp;
492
493    if (!is_compat_task() || (addr & 3) || addr > sizeof(struct user) - 3)
494        return -EIO;
495
496    tmp = __peek_user_compat(child, addr);
497    return put_user(tmp, (__u32 __user *) data);
498}
499
500/*
501 * Same as poke_user but for a 31 bit program.
502 */
503static int __poke_user_compat(struct task_struct *child,
504                  addr_t addr, addr_t data)
505{
506    struct user32 *dummy32 = NULL;
507    per_struct32 *dummy_per32 = NULL;
508    __u32 tmp = (__u32) data;
509    addr_t offset;
510
511    if (addr < (addr_t) &dummy32->regs.acrs) {
512        /*
513         * psw, gprs, acrs and orig_gpr2 are stored on the stack
514         */
515        if (addr == (addr_t) &dummy32->regs.psw.mask) {
516            /* Build a 64 bit psw mask from 31 bit mask. */
517            if (tmp != PSW32_MASK_MERGE(psw32_user_bits, tmp))
518                /* Invalid psw mask. */
519                return -EINVAL;
520            task_pt_regs(child)->psw.mask =
521                PSW_MASK_MERGE(psw_user32_bits, (__u64) tmp << 32);
522        } else if (addr == (addr_t) &dummy32->regs.psw.addr) {
523            /* Build a 64 bit psw address from 31 bit address. */
524            task_pt_regs(child)->psw.addr =
525                (__u64) tmp & PSW32_ADDR_INSN;
526        } else {
527            /* gpr 0-15 */
528            *(__u32*)((addr_t) &task_pt_regs(child)->psw
529                  + addr*2 + 4) = tmp;
530        }
531    } else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) {
532        /*
533         * access registers are stored in the thread structure
534         */
535        offset = addr - (addr_t) &dummy32->regs.acrs;
536        *(__u32*)((addr_t) &child->thread.acrs + offset) = tmp;
537
538    } else if (addr == (addr_t) (&dummy32->regs.orig_gpr2)) {
539        /*
540         * orig_gpr2 is stored on the kernel stack
541         */
542        *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4) = tmp;
543
544    } else if (addr < (addr_t) &dummy32->regs.fp_regs) {
545        /*
546         * prevent writess of padding hole between
547         * orig_gpr2 and fp_regs on s390.
548         */
549        return 0;
550
551    } else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
552        /*
553         * floating point regs. are stored in the thread structure
554         */
555        if (addr == (addr_t) &dummy32->regs.fp_regs.fpc &&
556            (tmp & ~FPC_VALID_MASK) != 0)
557            /* Invalid floating point control. */
558            return -EINVAL;
559            offset = addr - (addr_t) &dummy32->regs.fp_regs;
560        *(__u32 *)((addr_t) &child->thread.fp_regs + offset) = tmp;
561
562    } else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) {
563        /*
564         * per_info is found in the thread structure.
565         */
566        offset = addr - (addr_t) &dummy32->regs.per_info;
567        /*
568         * This is magic. See per_struct and per_struct32.
569         * By incident the offsets in per_struct are exactly
570         * twice the offsets in per_struct32 for all fields.
571         * The 8 byte fields need special handling though,
572         * because the second half (bytes 4-7) is needed and
573         * not the first half.
574         */
575        if ((offset >= (addr_t) &dummy_per32->control_regs &&
576             offset < (addr_t) (&dummy_per32->control_regs + 1)) ||
577            (offset >= (addr_t) &dummy_per32->starting_addr &&
578             offset <= (addr_t) &dummy_per32->ending_addr) ||
579            offset == (addr_t) &dummy_per32->lowcore.words.address)
580            offset = offset*2 + 4;
581        else
582            offset = offset*2;
583        *(__u32 *)((addr_t) &child->thread.per_info + offset) = tmp;
584
585    }
586
587    FixPerRegisters(child);
588    return 0;
589}
590
591static int poke_user_compat(struct task_struct *child,
592                addr_t addr, addr_t data)
593{
594    if (!is_compat_task() || (addr & 3) || addr > sizeof(struct user32) - 3)
595        return -EIO;
596
597    return __poke_user_compat(child, addr, data);
598}
599
600long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
601            compat_ulong_t caddr, compat_ulong_t cdata)
602{
603    unsigned long addr = caddr;
604    unsigned long data = cdata;
605    ptrace_area_emu31 parea;
606    int copied, ret;
607
608    switch (request) {
609    case PTRACE_PEEKUSR:
610        /* read the word at location addr in the USER area. */
611        return peek_user_compat(child, addr, data);
612
613    case PTRACE_POKEUSR:
614        /* write the word at location addr in the USER area */
615        return poke_user_compat(child, addr, data);
616
617    case PTRACE_PEEKUSR_AREA:
618    case PTRACE_POKEUSR_AREA:
619        if (copy_from_user(&parea, (void __force __user *) addr,
620                            sizeof(parea)))
621            return -EFAULT;
622        addr = parea.kernel_addr;
623        data = parea.process_addr;
624        copied = 0;
625        while (copied < parea.len) {
626            if (request == PTRACE_PEEKUSR_AREA)
627                ret = peek_user_compat(child, addr, data);
628            else {
629                __u32 utmp;
630                if (get_user(utmp,
631                         (__u32 __force __user *) data))
632                    return -EFAULT;
633                ret = poke_user_compat(child, addr, utmp);
634            }
635            if (ret)
636                return ret;
637            addr += sizeof(unsigned int);
638            data += sizeof(unsigned int);
639            copied += sizeof(unsigned int);
640        }
641        return 0;
642    case PTRACE_GET_LAST_BREAK:
643        put_user(task_thread_info(child)->last_break,
644             (unsigned int __user *) data);
645        return 0;
646    }
647    return compat_ptrace_request(child, request, addr, data);
648}
649#endif
650
651asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
652{
653    long ret = 0;
654
655    /* Do the secure computing check first. */
656    secure_computing(regs->gprs[2]);
657
658    /*
659     * The sysc_tracesys code in entry.S stored the system
660     * call number to gprs[2].
661     */
662    if (test_thread_flag(TIF_SYSCALL_TRACE) &&
663        (tracehook_report_syscall_entry(regs) ||
664         regs->gprs[2] >= NR_syscalls)) {
665        /*
666         * Tracing decided this syscall should not happen or the
667         * debugger stored an invalid system call number. Skip
668         * the system call and the system call restart handling.
669         */
670        regs->svcnr = 0;
671        ret = -1;
672    }
673
674    if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
675        trace_sys_enter(regs, regs->gprs[2]);
676
677    if (unlikely(current->audit_context))
678        audit_syscall_entry(is_compat_task() ?
679                    AUDIT_ARCH_S390 : AUDIT_ARCH_S390X,
680                    regs->gprs[2], regs->orig_gpr2,
681                    regs->gprs[3], regs->gprs[4],
682                    regs->gprs[5]);
683    return ret ?: regs->gprs[2];
684}
685
686asmlinkage void do_syscall_trace_exit(struct pt_regs *regs)
687{
688    if (unlikely(current->audit_context))
689        audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]),
690                   regs->gprs[2]);
691
692    if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
693        trace_sys_exit(regs, regs->gprs[2]);
694
695    if (test_thread_flag(TIF_SYSCALL_TRACE))
696        tracehook_report_syscall_exit(regs, 0);
697}
698
699/*
700 * user_regset definitions.
701 */
702
703static int s390_regs_get(struct task_struct *target,
704             const struct user_regset *regset,
705             unsigned int pos, unsigned int count,
706             void *kbuf, void __user *ubuf)
707{
708    if (target == current)
709        save_access_regs(target->thread.acrs);
710
711    if (kbuf) {
712        unsigned long *k = kbuf;
713        while (count > 0) {
714            *k++ = __peek_user(target, pos);
715            count -= sizeof(*k);
716            pos += sizeof(*k);
717        }
718    } else {
719        unsigned long __user *u = ubuf;
720        while (count > 0) {
721            if (__put_user(__peek_user(target, pos), u++))
722                return -EFAULT;
723            count -= sizeof(*u);
724            pos += sizeof(*u);
725        }
726    }
727    return 0;
728}
729
730static int s390_regs_set(struct task_struct *target,
731             const struct user_regset *regset,
732             unsigned int pos, unsigned int count,
733             const void *kbuf, const void __user *ubuf)
734{
735    int rc = 0;
736
737    if (target == current)
738        save_access_regs(target->thread.acrs);
739
740    if (kbuf) {
741        const unsigned long *k = kbuf;
742        while (count > 0 && !rc) {
743            rc = __poke_user(target, pos, *k++);
744            count -= sizeof(*k);
745            pos += sizeof(*k);
746        }
747    } else {
748        const unsigned long __user *u = ubuf;
749        while (count > 0 && !rc) {
750            unsigned long word;
751            rc = __get_user(word, u++);
752            if (rc)
753                break;
754            rc = __poke_user(target, pos, word);
755            count -= sizeof(*u);
756            pos += sizeof(*u);
757        }
758    }
759
760    if (rc == 0 && target == current)
761        restore_access_regs(target->thread.acrs);
762
763    return rc;
764}
765
766static int s390_fpregs_get(struct task_struct *target,
767               const struct user_regset *regset, unsigned int pos,
768               unsigned int count, void *kbuf, void __user *ubuf)
769{
770    if (target == current)
771        save_fp_regs(&target->thread.fp_regs);
772
773    return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
774                   &target->thread.fp_regs, 0, -1);
775}
776
777static int s390_fpregs_set(struct task_struct *target,
778               const struct user_regset *regset, unsigned int pos,
779               unsigned int count, const void *kbuf,
780               const void __user *ubuf)
781{
782    int rc = 0;
783
784    if (target == current)
785        save_fp_regs(&target->thread.fp_regs);
786
787    /* If setting FPC, must validate it first. */
788    if (count > 0 && pos < offsetof(s390_fp_regs, fprs)) {
789        u32 fpc[2] = { target->thread.fp_regs.fpc, 0 };
790        rc = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &fpc,
791                    0, offsetof(s390_fp_regs, fprs));
792        if (rc)
793            return rc;
794        if ((fpc[0] & ~FPC_VALID_MASK) != 0 || fpc[1] != 0)
795            return -EINVAL;
796        target->thread.fp_regs.fpc = fpc[0];
797    }
798
799    if (rc == 0 && count > 0)
800        rc = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
801                    target->thread.fp_regs.fprs,
802                    offsetof(s390_fp_regs, fprs), -1);
803
804    if (rc == 0 && target == current)
805        restore_fp_regs(&target->thread.fp_regs);
806
807    return rc;
808}
809
810#ifdef CONFIG_64BIT
811
812static int s390_last_break_get(struct task_struct *target,
813                   const struct user_regset *regset,
814                   unsigned int pos, unsigned int count,
815                   void *kbuf, void __user *ubuf)
816{
817    if (count > 0) {
818        if (kbuf) {
819            unsigned long *k = kbuf;
820            *k = task_thread_info(target)->last_break;
821        } else {
822            unsigned long __user *u = ubuf;
823            if (__put_user(task_thread_info(target)->last_break, u))
824                return -EFAULT;
825        }
826    }
827    return 0;
828}
829
830#endif
831
832static const struct user_regset s390_regsets[] = {
833    [REGSET_GENERAL] = {
834        .core_note_type = NT_PRSTATUS,
835        .n = sizeof(s390_regs) / sizeof(long),
836        .size = sizeof(long),
837        .align = sizeof(long),
838        .get = s390_regs_get,
839        .set = s390_regs_set,
840    },
841    [REGSET_FP] = {
842        .core_note_type = NT_PRFPREG,
843        .n = sizeof(s390_fp_regs) / sizeof(long),
844        .size = sizeof(long),
845        .align = sizeof(long),
846        .get = s390_fpregs_get,
847        .set = s390_fpregs_set,
848    },
849#ifdef CONFIG_64BIT
850    [REGSET_LAST_BREAK] = {
851        .core_note_type = NT_S390_LAST_BREAK,
852        .n = 1,
853        .size = sizeof(long),
854        .align = sizeof(long),
855        .get = s390_last_break_get,
856    },
857#endif
858};
859
860static const struct user_regset_view user_s390_view = {
861    .name = UTS_MACHINE,
862    .e_machine = EM_S390,
863    .regsets = s390_regsets,
864    .n = ARRAY_SIZE(s390_regsets)
865};
866
867#ifdef CONFIG_COMPAT
868static int s390_compat_regs_get(struct task_struct *target,
869                const struct user_regset *regset,
870                unsigned int pos, unsigned int count,
871                void *kbuf, void __user *ubuf)
872{
873    if (target == current)
874        save_access_regs(target->thread.acrs);
875
876    if (kbuf) {
877        compat_ulong_t *k = kbuf;
878        while (count > 0) {
879            *k++ = __peek_user_compat(target, pos);
880            count -= sizeof(*k);
881            pos += sizeof(*k);
882        }
883    } else {
884        compat_ulong_t __user *u = ubuf;
885        while (count > 0) {
886            if (__put_user(__peek_user_compat(target, pos), u++))
887                return -EFAULT;
888            count -= sizeof(*u);
889            pos += sizeof(*u);
890        }
891    }
892    return 0;
893}
894
895static int s390_compat_regs_set(struct task_struct *target,
896                const struct user_regset *regset,
897                unsigned int pos, unsigned int count,
898                const void *kbuf, const void __user *ubuf)
899{
900    int rc = 0;
901
902    if (target == current)
903        save_access_regs(target->thread.acrs);
904
905    if (kbuf) {
906        const compat_ulong_t *k = kbuf;
907        while (count > 0 && !rc) {
908            rc = __poke_user_compat(target, pos, *k++);
909            count -= sizeof(*k);
910            pos += sizeof(*k);
911        }
912    } else {
913        const compat_ulong_t __user *u = ubuf;
914        while (count > 0 && !rc) {
915            compat_ulong_t word;
916            rc = __get_user(word, u++);
917            if (rc)
918                break;
919            rc = __poke_user_compat(target, pos, word);
920            count -= sizeof(*u);
921            pos += sizeof(*u);
922        }
923    }
924
925    if (rc == 0 && target == current)
926        restore_access_regs(target->thread.acrs);
927
928    return rc;
929}
930
931static int s390_compat_regs_high_get(struct task_struct *target,
932                     const struct user_regset *regset,
933                     unsigned int pos, unsigned int count,
934                     void *kbuf, void __user *ubuf)
935{
936    compat_ulong_t *gprs_high;
937
938    gprs_high = (compat_ulong_t *)
939        &task_pt_regs(target)->gprs[pos / sizeof(compat_ulong_t)];
940    if (kbuf) {
941        compat_ulong_t *k = kbuf;
942        while (count > 0) {
943            *k++ = *gprs_high;
944            gprs_high += 2;
945            count -= sizeof(*k);
946        }
947    } else {
948        compat_ulong_t __user *u = ubuf;
949        while (count > 0) {
950            if (__put_user(*gprs_high, u++))
951                return -EFAULT;
952            gprs_high += 2;
953            count -= sizeof(*u);
954        }
955    }
956    return 0;
957}
958
959static int s390_compat_regs_high_set(struct task_struct *target,
960                     const struct user_regset *regset,
961                     unsigned int pos, unsigned int count,
962                     const void *kbuf, const void __user *ubuf)
963{
964    compat_ulong_t *gprs_high;
965    int rc = 0;
966
967    gprs_high = (compat_ulong_t *)
968        &task_pt_regs(target)->gprs[pos / sizeof(compat_ulong_t)];
969    if (kbuf) {
970        const compat_ulong_t *k = kbuf;
971        while (count > 0) {
972            *gprs_high = *k++;
973            *gprs_high += 2;
974            count -= sizeof(*k);
975        }
976    } else {
977        const compat_ulong_t __user *u = ubuf;
978        while (count > 0 && !rc) {
979            unsigned long word;
980            rc = __get_user(word, u++);
981            if (rc)
982                break;
983            *gprs_high = word;
984            *gprs_high += 2;
985            count -= sizeof(*u);
986        }
987    }
988
989    return rc;
990}
991
992static int s390_compat_last_break_get(struct task_struct *target,
993                      const struct user_regset *regset,
994                      unsigned int pos, unsigned int count,
995                      void *kbuf, void __user *ubuf)
996{
997    compat_ulong_t last_break;
998
999    if (count > 0) {
1000        last_break = task_thread_info(target)->last_break;
1001        if (kbuf) {
1002            unsigned long *k = kbuf;
1003            *k = last_break;
1004        } else {
1005            unsigned long __user *u = ubuf;
1006            if (__put_user(last_break, u))
1007                return -EFAULT;
1008        }
1009    }
1010    return 0;
1011}
1012
1013static const struct user_regset s390_compat_regsets[] = {
1014    [REGSET_GENERAL] = {
1015        .core_note_type = NT_PRSTATUS,
1016        .n = sizeof(s390_compat_regs) / sizeof(compat_long_t),
1017        .size = sizeof(compat_long_t),
1018        .align = sizeof(compat_long_t),
1019        .get = s390_compat_regs_get,
1020        .set = s390_compat_regs_set,
1021    },
1022    [REGSET_FP] = {
1023        .core_note_type = NT_PRFPREG,
1024        .n = sizeof(s390_fp_regs) / sizeof(compat_long_t),
1025        .size = sizeof(compat_long_t),
1026        .align = sizeof(compat_long_t),
1027        .get = s390_fpregs_get,
1028        .set = s390_fpregs_set,
1029    },
1030    [REGSET_LAST_BREAK] = {
1031        .core_note_type = NT_S390_LAST_BREAK,
1032        .n = 1,
1033        .size = sizeof(long),
1034        .align = sizeof(long),
1035        .get = s390_compat_last_break_get,
1036    },
1037    [REGSET_GENERAL_EXTENDED] = {
1038        .core_note_type = NT_S390_HIGH_GPRS,
1039        .n = sizeof(s390_compat_regs_high) / sizeof(compat_long_t),
1040        .size = sizeof(compat_long_t),
1041        .align = sizeof(compat_long_t),
1042        .get = s390_compat_regs_high_get,
1043        .set = s390_compat_regs_high_set,
1044    },
1045};
1046
1047static const struct user_regset_view user_s390_compat_view = {
1048    .name = "s390",
1049    .e_machine = EM_S390,
1050    .regsets = s390_compat_regsets,
1051    .n = ARRAY_SIZE(s390_compat_regsets)
1052};
1053#endif
1054
1055const struct user_regset_view *task_user_regset_view(struct task_struct *task)
1056{
1057#ifdef CONFIG_COMPAT
1058    if (test_tsk_thread_flag(task, TIF_31BIT))
1059        return &user_s390_compat_view;
1060#endif
1061    return &user_s390_view;
1062}
1063
1064static const char *gpr_names[NUM_GPRS] = {
1065    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1066    "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1067};
1068
1069unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset)
1070{
1071    if (offset >= NUM_GPRS)
1072        return 0;
1073    return regs->gprs[offset];
1074}
1075
1076int regs_query_register_offset(const char *name)
1077{
1078    unsigned long offset;
1079
1080    if (!name || *name != 'r')
1081        return -EINVAL;
1082    if (strict_strtoul(name + 1, 10, &offset))
1083        return -EINVAL;
1084    if (offset >= NUM_GPRS)
1085        return -EINVAL;
1086    return offset;
1087}
1088
1089const char *regs_query_register_name(unsigned int offset)
1090{
1091    if (offset >= NUM_GPRS)
1092        return NULL;
1093    return gpr_names[offset];
1094}
1095
1096static int regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr)
1097{
1098    unsigned long ksp = kernel_stack_pointer(regs);
1099
1100    return (addr & ~(THREAD_SIZE - 1)) == (ksp & ~(THREAD_SIZE - 1));
1101}
1102
1103/**
1104 * regs_get_kernel_stack_nth() - get Nth entry of the stack
1105 * @regs:pt_regs which contains kernel stack pointer.
1106 * @n:stack entry number.
1107 *
1108 * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
1109 * is specifined by @regs. If the @n th entry is NOT in the kernel stack,
1110 * this returns 0.
1111 */
1112unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
1113{
1114    unsigned long addr;
1115
1116    addr = kernel_stack_pointer(regs) + n * sizeof(long);
1117    if (!regs_within_kernel_stack(regs, addr))
1118        return 0;
1119    return *(unsigned long *)addr;
1120}
1121

Archive Download this file



interactive