From c5a1ebd24547df5738138ebc154e1abccfa85468 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 3 Nov 2005 16:02:23 +1100 Subject: powerpc: merge stat.h Signed-off-by: Stephen Rothwell --- include/asm-powerpc/stat.h | 81 ++++++++++++++++++++++++++++++++++++++++++++++ include/asm-ppc/stat.h | 69 --------------------------------------- include/asm-ppc64/stat.h | 60 ---------------------------------- 3 files changed, 81 insertions(+), 129 deletions(-) create mode 100644 include/asm-powerpc/stat.h delete mode 100644 include/asm-ppc/stat.h delete mode 100644 include/asm-ppc64/stat.h diff --git a/include/asm-powerpc/stat.h b/include/asm-powerpc/stat.h new file mode 100644 index 0000000..e4edc51 --- /dev/null +++ b/include/asm-powerpc/stat.h @@ -0,0 +1,81 @@ +#ifndef _ASM_POWERPC_STAT_H +#define _ASM_POWERPC_STAT_H +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include + +#define STAT_HAVE_NSEC 1 + +#ifndef __powerpc64__ +struct __old_kernel_stat { + unsigned short st_dev; + unsigned short st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned short st_rdev; + unsigned long st_size; + unsigned long st_atime; + unsigned long st_mtime; + unsigned long st_ctime; +}; +#endif /* !__powerpc64__ */ + +struct stat { + unsigned long st_dev; + ino_t st_ino; +#ifdef __powerpc64__ + nlink_t st_nlink; + mode_t st_mode; +#else + mode_t st_mode; + nlink_t st_nlink; +#endif + uid_t st_uid; + gid_t st_gid; + unsigned long st_rdev; + off_t st_size; + unsigned long st_blksize; + unsigned long st_blocks; + unsigned long st_atime; + unsigned long st_atime_nsec; + unsigned long st_mtime; + unsigned long st_mtime_nsec; + unsigned long st_ctime; + unsigned long st_ctime_nsec; + unsigned long __unused4; + unsigned long __unused5; +#ifdef __powerpc64__ + unsigned long __unused6; +#endif +}; + +/* This matches struct stat64 in glibc2.1. Only used for 32 bit. */ +struct stat64 { + unsigned long long st_dev; /* Device. */ + unsigned long long st_ino; /* File serial number. */ + unsigned int st_mode; /* File mode. */ + unsigned int st_nlink; /* Link count. */ + unsigned int st_uid; /* User ID of the file's owner. */ + unsigned int st_gid; /* Group ID of the file's group. */ + unsigned long long st_rdev; /* Device number, if device. */ + unsigned short __pad2; + long long st_size; /* Size of file, in bytes. */ + int st_blksize; /* Optimal block size for I/O. */ + long long st_blocks; /* Number 512-byte blocks allocated. */ + int st_atime; /* Time of last access. */ + unsigned int st_atime_nsec; + int st_mtime; /* Time of last modification. */ + unsigned int st_mtime_nsec; + int st_ctime; /* Time of last status change. */ + unsigned int st_ctime_nsec; + unsigned int __unused4; + unsigned int __unused5; +}; + +#endif /* _ASM_POWERPC_STAT_H */ diff --git a/include/asm-ppc/stat.h b/include/asm-ppc/stat.h deleted file mode 100644 index cadb342..0000000 --- a/include/asm-ppc/stat.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef _PPC_STAT_H -#define _PPC_STAT_H - -#ifdef __KERNEL__ -#include -#endif /* __KERNEL__ */ - -struct __old_kernel_stat { - unsigned short st_dev; - unsigned short st_ino; - unsigned short st_mode; - unsigned short st_nlink; - unsigned short st_uid; - unsigned short st_gid; - unsigned short st_rdev; - unsigned long st_size; - unsigned long st_atime; - unsigned long st_mtime; - unsigned long st_ctime; -}; - -#define STAT_HAVE_NSEC 1 - -struct stat { - unsigned st_dev; - ino_t st_ino; - mode_t st_mode; - nlink_t st_nlink; - uid_t st_uid; - gid_t st_gid; - unsigned st_rdev; - off_t st_size; - unsigned long st_blksize; - unsigned long st_blocks; - unsigned long st_atime; - unsigned long st_atime_nsec; - unsigned long st_mtime; - unsigned long st_mtime_nsec; - unsigned long st_ctime; - unsigned long st_ctime_nsec; - unsigned long __unused4; - unsigned long __unused5; -}; - -/* This matches struct stat64 in glibc2.1. - */ -struct stat64 { - unsigned long long st_dev; /* Device. */ - unsigned long long st_ino; /* File serial number. */ - unsigned int st_mode; /* File mode. */ - unsigned int st_nlink; /* Link count. */ - unsigned int st_uid; /* User ID of the file's owner. */ - unsigned int st_gid; /* Group ID of the file's group. */ - unsigned long long st_rdev; /* Device number, if device. */ - unsigned short int __pad2; - long long st_size; /* Size of file, in bytes. */ - long st_blksize; /* Optimal block size for I/O. */ - - long long st_blocks; /* Number 512-byte blocks allocated. */ - long st_atime; /* Time of last access. */ - unsigned long st_atime_nsec; - long st_mtime; /* Time of last modification. */ - unsigned long int st_mtime_nsec; - long st_ctime; /* Time of last status change. */ - unsigned long int st_ctime_nsec; - unsigned long int __unused4; - unsigned long int __unused5; -}; -#endif diff --git a/include/asm-ppc64/stat.h b/include/asm-ppc64/stat.h deleted file mode 100644 index 973a5f9..0000000 --- a/include/asm-ppc64/stat.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef _PPC64_STAT_H -#define _PPC64_STAT_H - -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include - -struct stat { - unsigned long st_dev; - ino_t st_ino; - nlink_t st_nlink; - mode_t st_mode; - uid_t st_uid; - gid_t st_gid; - unsigned long st_rdev; - off_t st_size; - unsigned long st_blksize; - unsigned long st_blocks; - unsigned long st_atime; - unsigned long st_atime_nsec; - unsigned long st_mtime; - unsigned long st_mtime_nsec; - unsigned long st_ctime; - unsigned long st_ctime_nsec; - unsigned long __unused4; - unsigned long __unused5; - unsigned long __unused6; -}; - -#define STAT_HAVE_NSEC 1 - -/* This matches struct stat64 in glibc2.1. Only used for 32 bit. */ -struct stat64 { - unsigned long st_dev; /* Device. */ - unsigned long st_ino; /* File serial number. */ - unsigned int st_mode; /* File mode. */ - unsigned int st_nlink; /* Link count. */ - unsigned int st_uid; /* User ID of the file's owner. */ - unsigned int st_gid; /* Group ID of the file's group. */ - unsigned long st_rdev; /* Device number, if device. */ - unsigned short __pad2; - long st_size; /* Size of file, in bytes. */ - int st_blksize; /* Optimal block size for I/O. */ - - long st_blocks; /* Number 512-byte blocks allocated. */ - int st_atime; /* Time of last access. */ - int st_atime_nsec; - int st_mtime; /* Time of last modification. */ - int st_mtime_nsec; - int st_ctime; /* Time of last status change. */ - int st_ctime_nsec; - unsigned int __unused4; - unsigned int __unused5; -}; -#endif -- cgit v1.1 From da80d460bf4606671df3ba53408f45ab848e67ba Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 3 Nov 2005 15:14:36 +1100 Subject: powerpc: merge ptrace.h Move struct ptregs32 into asm-ppc64/ppc32.h Signed-off-by: Stephen Rothwell --- include/asm-powerpc/ptrace.h | 248 +++++++++++++++++++++++++++++++++++++++++++ include/asm-ppc/ptrace.h | 152 -------------------------- include/asm-ppc64/ppc32.h | 16 +++ include/asm-ppc64/ptrace.h | 213 ------------------------------------- 4 files changed, 264 insertions(+), 365 deletions(-) create mode 100644 include/asm-powerpc/ptrace.h delete mode 100644 include/asm-ppc/ptrace.h delete mode 100644 include/asm-ppc64/ptrace.h diff --git a/include/asm-powerpc/ptrace.h b/include/asm-powerpc/ptrace.h new file mode 100644 index 0000000..1f7ecdb --- /dev/null +++ b/include/asm-powerpc/ptrace.h @@ -0,0 +1,248 @@ +#ifndef _ASM_POWERPC_PTRACE_H +#define _ASM_POWERPC_PTRACE_H + +/* + * Copyright (C) 2001 PPC64 Team, IBM Corp + * + * This struct defines the way the registers are stored on the + * kernel stack during a system call or other kernel entry. + * + * this should only contain volatile regs + * since we can keep non-volatile in the thread_struct + * should set this up when only volatiles are saved + * by intr code. + * + * Since this is going on the stack, *CARE MUST BE TAKEN* to insure + * that the overall structure is a multiple of 16 bytes in length. + * + * Note that the offsets of the fields in this struct correspond with + * the PT_* values below. This simplifies arch/powerpc/kernel/ptrace.c. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef __ASSEMBLY__ + +struct pt_regs { + unsigned long gpr[32]; + unsigned long nip; + unsigned long msr; + unsigned long orig_gpr3; /* Used for restarting system calls */ + unsigned long ctr; + unsigned long link; + unsigned long xer; + unsigned long ccr; +#ifdef __powerpc64__ + unsigned long softe; /* Soft enabled/disabled */ +#else + unsigned long mq; /* 601 only (not used at present) */ + /* Used on APUS to hold IPL value. */ +#endif + unsigned long trap; /* Reason for being here */ + /* N.B. for critical exceptions on 4xx, the dar and dsisr + fields are overloaded to hold srr0 and srr1. */ + unsigned long dar; /* Fault registers */ + unsigned long dsisr; /* on 4xx/Book-E used for ESR */ + unsigned long result; /* Result of a system call */ +}; + +#endif /* __ASSEMBLY__ */ + +#ifdef __KERNEL__ + +#ifdef __powerpc64__ + +#define STACK_FRAME_OVERHEAD 112 /* size of minimum stack frame */ + +/* Size of dummy stack frame allocated when calling signal handler. */ +#define __SIGNAL_FRAMESIZE 128 +#define __SIGNAL_FRAMESIZE32 64 + +#else /* __powerpc64__ */ + +#define STACK_FRAME_OVERHEAD 16 /* size of minimum stack frame */ + +/* Size of stack frame allocated when calling signal handler. */ +#define __SIGNAL_FRAMESIZE 64 + +#endif /* __powerpc64__ */ + +#ifndef __ASSEMBLY__ + +#define instruction_pointer(regs) ((regs)->nip) +#ifdef CONFIG_SMP +extern unsigned long profile_pc(struct pt_regs *regs); +#else +#define profile_pc(regs) instruction_pointer(regs) +#endif + +#ifdef __powerpc64__ +#define user_mode(regs) ((((regs)->msr) >> MSR_PR_LG) & 0x1) +#else +#define user_mode(regs) (((regs)->msr & MSR_PR) != 0) +#endif + +#define force_successful_syscall_return() \ + do { \ + current_thread_info()->syscall_noerror = 1; \ + } while(0) + +/* + * We use the least-significant bit of the trap field to indicate + * whether we have saved the full set of registers, or only a + * partial set. A 1 there means the partial set. + * On 4xx we use the next bit to indicate whether the exception + * is a critical exception (1 means it is). + */ +#define FULL_REGS(regs) (((regs)->trap & 1) == 0) +#ifndef __powerpc64__ +#define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) == 0) +#endif /* ! __powerpc64__ */ +#define TRAP(regs) ((regs)->trap & ~0xF) +#ifdef __powerpc64__ +#define CHECK_FULL_REGS(regs) BUG_ON(regs->trap & 1) +#else +#define CHECK_FULL_REGS(regs) \ +do { \ + if ((regs)->trap & 1) \ + printk(KERN_CRIT "%s: partial register set\n", __FUNCTION__); \ +} while (0) +#endif /* __powerpc64__ */ + +#endif /* __ASSEMBLY__ */ + +#endif /* __KERNEL__ */ + +/* + * Offsets used by 'ptrace' system call interface. + * These can't be changed without breaking binary compatibility + * with MkLinux, etc. + */ +#define PT_R0 0 +#define PT_R1 1 +#define PT_R2 2 +#define PT_R3 3 +#define PT_R4 4 +#define PT_R5 5 +#define PT_R6 6 +#define PT_R7 7 +#define PT_R8 8 +#define PT_R9 9 +#define PT_R10 10 +#define PT_R11 11 +#define PT_R12 12 +#define PT_R13 13 +#define PT_R14 14 +#define PT_R15 15 +#define PT_R16 16 +#define PT_R17 17 +#define PT_R18 18 +#define PT_R19 19 +#define PT_R20 20 +#define PT_R21 21 +#define PT_R22 22 +#define PT_R23 23 +#define PT_R24 24 +#define PT_R25 25 +#define PT_R26 26 +#define PT_R27 27 +#define PT_R28 28 +#define PT_R29 29 +#define PT_R30 30 +#define PT_R31 31 + +#define PT_NIP 32 +#define PT_MSR 33 +#ifdef __KERNEL__ +#define PT_ORIG_R3 34 +#endif +#define PT_CTR 35 +#define PT_LNK 36 +#define PT_XER 37 +#define PT_CCR 38 +#ifndef __powerpc64__ +#define PT_MQ 39 +#else +#define PT_SOFTE 39 +#define PT_TRAP 40 +#define PT_DAR 41 +#define PT_DSISR 42 +#define PT_RESULT 43 +#endif + +#define PT_FPR0 48 /* each FP reg occupies 2 slots in this space */ + +#ifndef __powerpc64__ + +#define PT_FPR31 (PT_FPR0 + 2*31) +#define PT_FPSCR (PT_FPR0 + 2*32 + 1) + +#else /* __powerpc64__ */ + +#define PT_FPSCR (PT_FPR0 + 32) /* each FP reg occupies 1 slot in 64-bit space */ + +#ifdef __KERNEL__ +#define PT_FPSCR32 (PT_FPR0 + 2*32 + 1) /* each FP reg occupies 2 32-bit userspace slots */ +#endif + +#define PT_VR0 82 /* each Vector reg occupies 2 slots in 64-bit */ +#define PT_VSCR (PT_VR0 + 32*2 + 1) +#define PT_VRSAVE (PT_VR0 + 33*2) + +#ifdef __KERNEL__ +#define PT_VR0_32 164 /* each Vector reg occupies 4 slots in 32-bit */ +#define PT_VSCR_32 (PT_VR0 + 32*4 + 3) +#define PT_VRSAVE_32 (PT_VR0 + 33*4) +#endif + +#endif /* __powerpc64__ */ + +/* + * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go. + * The transfer totals 34 quadword. Quadwords 0-31 contain the + * corresponding vector registers. Quadword 32 contains the vscr as the + * last word (offset 12) within that quadword. Quadword 33 contains the + * vrsave as the first word (offset 0) within the quadword. + * + * This definition of the VMX state is compatible with the current PPC32 + * ptrace interface. This allows signal handling and ptrace to use the same + * structures. This also simplifies the implementation of a bi-arch + * (combined (32- and 64-bit) gdb. + */ +#define PTRACE_GETVRREGS 18 +#define PTRACE_SETVRREGS 19 + +#ifndef __powerpc64__ +/* Get/set all the upper 32-bits of the SPE registers, accumulator, and + * spefscr, in one go */ +#define PTRACE_GETEVRREGS 20 +#define PTRACE_SETEVRREGS 21 +#endif /* __powerpc64__ */ + +/* + * Get or set a debug register. The first 16 are DABR registers and the + * second 16 are IABR registers. + */ +#define PTRACE_GET_DEBUGREG 25 +#define PTRACE_SET_DEBUGREG 26 + +#ifdef __powerpc64__ +/* Additional PTRACE requests implemented on PowerPC. */ +#define PPC_PTRACE_GETREGS 0x99 /* Get GPRs 0 - 31 */ +#define PPC_PTRACE_SETREGS 0x98 /* Set GPRs 0 - 31 */ +#define PPC_PTRACE_GETFPREGS 0x97 /* Get FPRs 0 - 31 */ +#define PPC_PTRACE_SETFPREGS 0x96 /* Set FPRs 0 - 31 */ + +/* Calls to trace a 64bit program from a 32bit program */ +#define PPC_PTRACE_PEEKTEXT_3264 0x95 +#define PPC_PTRACE_PEEKDATA_3264 0x94 +#define PPC_PTRACE_POKETEXT_3264 0x93 +#define PPC_PTRACE_POKEDATA_3264 0x92 +#define PPC_PTRACE_PEEKUSR_3264 0x91 +#define PPC_PTRACE_POKEUSR_3264 0x90 +#endif /* __powerpc64__ */ + +#endif /* _ASM_POWERPC_PTRACE_H */ diff --git a/include/asm-ppc/ptrace.h b/include/asm-ppc/ptrace.h deleted file mode 100644 index c34fb4e..0000000 --- a/include/asm-ppc/ptrace.h +++ /dev/null @@ -1,152 +0,0 @@ -#ifndef _PPC_PTRACE_H -#define _PPC_PTRACE_H - -/* - * This struct defines the way the registers are stored on the - * kernel stack during a system call or other kernel entry. - * - * this should only contain volatile regs - * since we can keep non-volatile in the thread_struct - * should set this up when only volatiles are saved - * by intr code. - * - * Since this is going on the stack, *CARE MUST BE TAKEN* to insure - * that the overall structure is a multiple of 16 bytes in length. - * - * Note that the offsets of the fields in this struct correspond with - * the PT_* values below. This simplifies arch/ppc/kernel/ptrace.c. - */ - -#ifndef __ASSEMBLY__ -struct pt_regs { - unsigned long gpr[32]; - unsigned long nip; - unsigned long msr; - unsigned long orig_gpr3; /* Used for restarting system calls */ - unsigned long ctr; - unsigned long link; - unsigned long xer; - unsigned long ccr; - unsigned long mq; /* 601 only (not used at present) */ - /* Used on APUS to hold IPL value. */ - unsigned long trap; /* Reason for being here */ - /* N.B. for critical exceptions on 4xx, the dar and dsisr - fields are overloaded to hold srr0 and srr1. */ - unsigned long dar; /* Fault registers */ - unsigned long dsisr; /* on 4xx/Book-E used for ESR */ - unsigned long result; /* Result of a system call */ -}; - -#endif /* __ASSEMBLY__ */ - -#ifdef __KERNEL__ -#define STACK_FRAME_OVERHEAD 16 /* size of minimum stack frame */ - -/* Size of stack frame allocated when calling signal handler. */ -#define __SIGNAL_FRAMESIZE 64 - -#ifndef __ASSEMBLY__ -#define instruction_pointer(regs) ((regs)->nip) -#ifdef CONFIG_SMP -extern unsigned long profile_pc(struct pt_regs *regs); -#else -#define profile_pc(regs) instruction_pointer(regs) -#endif - -#define user_mode(regs) (((regs)->msr & MSR_PR) != 0) - -#define force_successful_syscall_return() \ - do { \ - current_thread_info()->syscall_noerror = 1; \ - } while(0) - -/* - * We use the least-significant bit of the trap field to indicate - * whether we have saved the full set of registers, or only a - * partial set. A 1 there means the partial set. - * On 4xx we use the next bit to indicate whether the exception - * is a critical exception (1 means it is). - */ -#define FULL_REGS(regs) (((regs)->trap & 1) == 0) -#define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) == 0) -#define TRAP(regs) ((regs)->trap & ~0xF) - -#define CHECK_FULL_REGS(regs) \ -do { \ - if ((regs)->trap & 1) \ - printk(KERN_CRIT "%s: partial register set\n", __FUNCTION__); \ -} while (0) -#endif /* __ASSEMBLY__ */ - -#endif /* __KERNEL__ */ - -/* - * Offsets used by 'ptrace' system call interface. - * These can't be changed without breaking binary compatibility - * with MkLinux, etc. - */ -#define PT_R0 0 -#define PT_R1 1 -#define PT_R2 2 -#define PT_R3 3 -#define PT_R4 4 -#define PT_R5 5 -#define PT_R6 6 -#define PT_R7 7 -#define PT_R8 8 -#define PT_R9 9 -#define PT_R10 10 -#define PT_R11 11 -#define PT_R12 12 -#define PT_R13 13 -#define PT_R14 14 -#define PT_R15 15 -#define PT_R16 16 -#define PT_R17 17 -#define PT_R18 18 -#define PT_R19 19 -#define PT_R20 20 -#define PT_R21 21 -#define PT_R22 22 -#define PT_R23 23 -#define PT_R24 24 -#define PT_R25 25 -#define PT_R26 26 -#define PT_R27 27 -#define PT_R28 28 -#define PT_R29 29 -#define PT_R30 30 -#define PT_R31 31 - -#define PT_NIP 32 -#define PT_MSR 33 -#ifdef __KERNEL__ -#define PT_ORIG_R3 34 -#endif -#define PT_CTR 35 -#define PT_LNK 36 -#define PT_XER 37 -#define PT_CCR 38 -#define PT_MQ 39 - -#define PT_FPR0 48 /* each FP reg occupies 2 slots in this space */ -#define PT_FPR31 (PT_FPR0 + 2*31) -#define PT_FPSCR (PT_FPR0 + 2*32 + 1) - -/* Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go */ -#define PTRACE_GETVRREGS 18 -#define PTRACE_SETVRREGS 19 - -/* Get/set all the upper 32-bits of the SPE registers, accumulator, and - * spefscr, in one go */ -#define PTRACE_GETEVRREGS 20 -#define PTRACE_SETEVRREGS 21 - -/* - * Get or set a debug register. The first 16 are DABR registers and the - * second 16 are IABR registers. - */ -#define PTRACE_GET_DEBUGREG 25 -#define PTRACE_SET_DEBUGREG 26 - -#endif diff --git a/include/asm-ppc64/ppc32.h b/include/asm-ppc64/ppc32.h index 3945a55..90e5627 100644 --- a/include/asm-ppc64/ppc32.h +++ b/include/asm-ppc64/ppc32.h @@ -91,6 +91,22 @@ typedef struct sigaltstack_32 { compat_size_t ss_size; } stack_32_t; +struct pt_regs32 { + unsigned int gpr[32]; + unsigned int nip; + unsigned int msr; + unsigned int orig_gpr3; /* Used for restarting system calls */ + unsigned int ctr; + unsigned int link; + unsigned int xer; + unsigned int ccr; + unsigned int mq; /* 601 only (not used at present) */ + unsigned int trap; /* Reason for being here */ + unsigned int dar; /* Fault registers */ + unsigned int dsisr; + unsigned int result; /* Result of a system call */ +}; + struct sigcontext32 { unsigned int _unused[4]; int signal; diff --git a/include/asm-ppc64/ptrace.h b/include/asm-ppc64/ptrace.h deleted file mode 100644 index 3a55377..0000000 --- a/include/asm-ppc64/ptrace.h +++ /dev/null @@ -1,213 +0,0 @@ -#ifndef _PPC64_PTRACE_H -#define _PPC64_PTRACE_H - -/* - * Copyright (C) 2001 PPC64 Team, IBM Corp - * - * This struct defines the way the registers are stored on the - * kernel stack during a system call or other kernel entry. - * - * this should only contain volatile regs - * since we can keep non-volatile in the thread_struct - * should set this up when only volatiles are saved - * by intr code. - * - * Since this is going on the stack, *CARE MUST BE TAKEN* to insure - * that the overall structure is a multiple of 16 bytes in length. - * - * Note that the offsets of the fields in this struct correspond with - * the PT_* values below. This simplifies arch/ppc64/kernel/ptrace.c. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#ifndef __ASSEMBLY__ - -struct pt_regs { - unsigned long gpr[32]; - unsigned long nip; - unsigned long msr; - unsigned long orig_gpr3; /* Used for restarting system calls */ - unsigned long ctr; - unsigned long link; - unsigned long xer; - unsigned long ccr; - unsigned long softe; /* Soft enabled/disabled */ - unsigned long trap; /* Reason for being here */ - unsigned long dar; /* Fault registers */ - unsigned long dsisr; - unsigned long result; /* Result of a system call */ -}; - -struct pt_regs32 { - unsigned int gpr[32]; - unsigned int nip; - unsigned int msr; - unsigned int orig_gpr3; /* Used for restarting system calls */ - unsigned int ctr; - unsigned int link; - unsigned int xer; - unsigned int ccr; - unsigned int mq; /* 601 only (not used at present) */ - unsigned int trap; /* Reason for being here */ - unsigned int dar; /* Fault registers */ - unsigned int dsisr; - unsigned int result; /* Result of a system call */ -}; - -#ifdef __KERNEL__ - -#define instruction_pointer(regs) ((regs)->nip) - -#ifdef CONFIG_SMP -extern unsigned long profile_pc(struct pt_regs *regs); -#else -#define profile_pc(regs) instruction_pointer(regs) -#endif - -#define user_mode(regs) ((((regs)->msr) >> MSR_PR_LG) & 0x1) - -#define force_successful_syscall_return() \ - (current_thread_info()->syscall_noerror = 1) - -/* - * We use the least-significant bit of the trap field to indicate - * whether we have saved the full set of registers, or only a - * partial set. A 1 there means the partial set. - */ -#define FULL_REGS(regs) (((regs)->trap & 1) == 0) -#define TRAP(regs) ((regs)->trap & ~0xF) -#define CHECK_FULL_REGS(regs) BUG_ON(regs->trap & 1) - -#endif /* __KERNEL__ */ - -#endif /* __ASSEMBLY__ */ - -#define STACK_FRAME_OVERHEAD 112 /* size of minimum stack frame */ - -/* Size of dummy stack frame allocated when calling signal handler. */ -#define __SIGNAL_FRAMESIZE 128 -#define __SIGNAL_FRAMESIZE32 64 - -/* - * Offsets used by 'ptrace' system call interface. - */ -#define PT_R0 0 -#define PT_R1 1 -#define PT_R2 2 -#define PT_R3 3 -#define PT_R4 4 -#define PT_R5 5 -#define PT_R6 6 -#define PT_R7 7 -#define PT_R8 8 -#define PT_R9 9 -#define PT_R10 10 -#define PT_R11 11 -#define PT_R12 12 -#define PT_R13 13 -#define PT_R14 14 -#define PT_R15 15 -#define PT_R16 16 -#define PT_R17 17 -#define PT_R18 18 -#define PT_R19 19 -#define PT_R20 20 -#define PT_R21 21 -#define PT_R22 22 -#define PT_R23 23 -#define PT_R24 24 -#define PT_R25 25 -#define PT_R26 26 -#define PT_R27 27 -#define PT_R28 28 -#define PT_R29 29 -#define PT_R30 30 -#define PT_R31 31 - -#define PT_NIP 32 -#define PT_MSR 33 -#ifdef __KERNEL__ -#define PT_ORIG_R3 34 -#endif -#define PT_CTR 35 -#define PT_LNK 36 -#define PT_XER 37 -#define PT_CCR 38 -#define PT_SOFTE 39 -#define PT_TRAP 40 -#define PT_DAR 41 -#define PT_DSISR 42 -#define PT_RESULT 43 - -#define PT_FPR0 48 - -/* - * Kernel and userspace will both use this PT_FPSCR value. 32-bit apps will - * have visibility to the asm-ppc/ptrace.h header instead of this one. - */ -#define PT_FPSCR (PT_FPR0 + 32) /* each FP reg occupies 1 slot in 64-bit space */ - -#ifdef __KERNEL__ -#define PT_FPSCR32 (PT_FPR0 + 2*32 + 1) /* each FP reg occupies 2 32-bit userspace slots */ -#endif - -#define PT_VR0 82 /* each Vector reg occupies 2 slots in 64-bit */ -#define PT_VSCR (PT_VR0 + 32*2 + 1) -#define PT_VRSAVE (PT_VR0 + 33*2) - -#ifdef __KERNEL__ -#define PT_VR0_32 164 /* each Vector reg occupies 4 slots in 32-bit */ -#define PT_VSCR_32 (PT_VR0 + 32*4 + 3) -#define PT_VRSAVE_32 (PT_VR0 + 33*4) -#endif - -/* - * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go. - * The transfer totals 34 quadword. Quadwords 0-31 contain the - * corresponding vector registers. Quadword 32 contains the vscr as the - * last word (offset 12) within that quadword. Quadword 33 contains the - * vrsave as the first word (offset 0) within the quadword. - * - * This definition of the VMX state is compatible with the current PPC32 - * ptrace interface. This allows signal handling and ptrace to use the same - * structures. This also simplifies the implementation of a bi-arch - * (combined (32- and 64-bit) gdb. - */ -#define PTRACE_GETVRREGS 18 -#define PTRACE_SETVRREGS 19 - -/* - * While we dont have 64bit book E processors, we need to reserve the - * relevant ptrace calls for 32bit compatibility. - */ -#if 0 -#define PTRACE_GETEVRREGS 20 -#define PTRACE_SETEVRREGS 21 -#endif - -/* - * Get or set a debug register. The first 16 are DABR registers and the - * second 16 are IABR registers. - */ -#define PTRACE_GET_DEBUGREG 25 -#define PTRACE_SET_DEBUGREG 26 - -/* Additional PTRACE requests implemented on PowerPC. */ -#define PPC_PTRACE_GETREGS 0x99 /* Get GPRs 0 - 31 */ -#define PPC_PTRACE_SETREGS 0x98 /* Set GPRs 0 - 31 */ -#define PPC_PTRACE_GETFPREGS 0x97 /* Get FPRs 0 - 31 */ -#define PPC_PTRACE_SETFPREGS 0x96 /* Set FPRs 0 - 31 */ - -/* Calls to trace a 64bit program from a 32bit program */ -#define PPC_PTRACE_PEEKTEXT_3264 0x95 -#define PPC_PTRACE_PEEKDATA_3264 0x94 -#define PPC_PTRACE_POKETEXT_3264 0x93 -#define PPC_PTRACE_POKEDATA_3264 0x92 -#define PPC_PTRACE_PEEKUSR_3264 0x91 -#define PPC_PTRACE_POKEUSR_3264 0x90 - -#endif /* _PPC64_PTRACE_H */ -- cgit v1.1 From 62f4f47da64a10630d5f6dabc616477b0e09b612 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 3 Nov 2005 15:26:23 +1100 Subject: powerpc: move ppc64/kernel/signal.c to arch/powerpc Signed-off-by: Stephen Rothwell --- arch/powerpc/kernel/Makefile | 2 +- arch/powerpc/kernel/signal_64.c | 581 ++++++++++++++++++++++++++++++++++++++++ arch/ppc64/kernel/Makefile | 1 - arch/ppc64/kernel/signal.c | 581 ---------------------------------------- 4 files changed, 582 insertions(+), 583 deletions(-) create mode 100644 arch/powerpc/kernel/signal_64.c delete mode 100644 arch/ppc64/kernel/signal.c diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 601ddbf..7a3e115 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -13,7 +13,7 @@ endif obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ signal_32.o pmc.o obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ - ptrace32.o systbl.o + signal_64.o ptrace32.o systbl.o obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_POWER4) += idle_power4.o obj-$(CONFIG_PPC_OF) += of_device.o diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c new file mode 100644 index 0000000..ec9d098 --- /dev/null +++ b/arch/powerpc/kernel/signal_64.c @@ -0,0 +1,581 @@ +/* + * linux/arch/ppc64/kernel/signal.c + * + * PowerPC version + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Derived from "arch/i386/kernel/signal.c" + * Copyright (C) 1991, 1992 Linus Torvalds + * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG_SIG 0 + +#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) + +#define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs)) +#define FP_REGS_SIZE sizeof(elf_fpregset_t) + +#define TRAMP_TRACEBACK 3 +#define TRAMP_SIZE 6 + +/* + * When we have signals to deliver, we set up on the user stack, + * going down from the original stack pointer: + * 1) a rt_sigframe struct which contains the ucontext + * 2) a gap of __SIGNAL_FRAMESIZE bytes which acts as a dummy caller + * frame for the signal handler. + */ + +struct rt_sigframe { + /* sys_rt_sigreturn requires the ucontext be the first field */ + struct ucontext uc; + unsigned long _unused[2]; + unsigned int tramp[TRAMP_SIZE]; + struct siginfo *pinfo; + void *puc; + struct siginfo info; + /* 64 bit ABI allows for 288 bytes below sp before decrementing it. */ + char abigap[288]; +} __attribute__ ((aligned (16))); + + +/* + * Atomically swap in the new signal mask, and wait for a signal. + */ +long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, int p3, int p4, + int p6, int p7, struct pt_regs *regs) +{ + sigset_t saveset, newset; + + /* XXX: Don't preclude handling different sized sigset_t's. */ + if (sigsetsize != sizeof(sigset_t)) + return -EINVAL; + + if (copy_from_user(&newset, unewset, sizeof(newset))) + return -EFAULT; + sigdelsetmask(&newset, ~_BLOCKABLE); + + spin_lock_irq(¤t->sighand->siglock); + saveset = current->blocked; + current->blocked = newset; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + regs->result = -EINTR; + regs->gpr[3] = EINTR; + regs->ccr |= 0x10000000; + while (1) { + current->state = TASK_INTERRUPTIBLE; + schedule(); + if (do_signal(&saveset, regs)) + return 0; + } +} + +long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, unsigned long r5, + unsigned long r6, unsigned long r7, unsigned long r8, + struct pt_regs *regs) +{ + return do_sigaltstack(uss, uoss, regs->gpr[1]); +} + + +/* + * Set up the sigcontext for the signal frame. + */ + +static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, + int signr, sigset_t *set, unsigned long handler) +{ + /* When CONFIG_ALTIVEC is set, we _always_ setup v_regs even if the + * process never used altivec yet (MSR_VEC is zero in pt_regs of + * the context). This is very important because we must ensure we + * don't lose the VRSAVE content that may have been set prior to + * the process doing its first vector operation + * Userland shall check AT_HWCAP to know wether it can rely on the + * v_regs pointer or not + */ +#ifdef CONFIG_ALTIVEC + elf_vrreg_t __user *v_regs = (elf_vrreg_t __user *)(((unsigned long)sc->vmx_reserve + 15) & ~0xful); +#endif + long err = 0; + + flush_fp_to_thread(current); + + /* Make sure signal doesn't get spurrious FP exceptions */ + current->thread.fpscr.val = 0; + +#ifdef CONFIG_ALTIVEC + err |= __put_user(v_regs, &sc->v_regs); + + /* save altivec registers */ + if (current->thread.used_vr) { + flush_altivec_to_thread(current); + /* Copy 33 vec registers (vr0..31 and vscr) to the stack */ + err |= __copy_to_user(v_regs, current->thread.vr, 33 * sizeof(vector128)); + /* set MSR_VEC in the MSR value in the frame to indicate that sc->v_reg) + * contains valid data. + */ + regs->msr |= MSR_VEC; + } + /* We always copy to/from vrsave, it's 0 if we don't have or don't + * use altivec. + */ + err |= __put_user(current->thread.vrsave, (u32 __user *)&v_regs[33]); +#else /* CONFIG_ALTIVEC */ + err |= __put_user(0, &sc->v_regs); +#endif /* CONFIG_ALTIVEC */ + err |= __put_user(&sc->gp_regs, &sc->regs); + err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE); + err |= __copy_to_user(&sc->fp_regs, ¤t->thread.fpr, FP_REGS_SIZE); + err |= __put_user(signr, &sc->signal); + err |= __put_user(handler, &sc->handler); + if (set != NULL) + err |= __put_user(set->sig[0], &sc->oldmask); + + return err; +} + +/* + * Restore the sigcontext from the signal frame. + */ + +static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig, + struct sigcontext __user *sc) +{ +#ifdef CONFIG_ALTIVEC + elf_vrreg_t __user *v_regs; +#endif + unsigned long err = 0; + unsigned long save_r13 = 0; + elf_greg_t *gregs = (elf_greg_t *)regs; +#ifdef CONFIG_ALTIVEC + unsigned long msr; +#endif + int i; + + /* If this is not a signal return, we preserve the TLS in r13 */ + if (!sig) + save_r13 = regs->gpr[13]; + + /* copy everything before MSR */ + err |= __copy_from_user(regs, &sc->gp_regs, + PT_MSR*sizeof(unsigned long)); + + /* skip MSR and SOFTE */ + for (i = PT_MSR+1; i <= PT_RESULT; i++) { + if (i == PT_SOFTE) + continue; + err |= __get_user(gregs[i], &sc->gp_regs[i]); + } + + if (!sig) + regs->gpr[13] = save_r13; + err |= __copy_from_user(¤t->thread.fpr, &sc->fp_regs, FP_REGS_SIZE); + if (set != NULL) + err |= __get_user(set->sig[0], &sc->oldmask); + +#ifdef CONFIG_ALTIVEC + err |= __get_user(v_regs, &sc->v_regs); + err |= __get_user(msr, &sc->gp_regs[PT_MSR]); + if (err) + return err; + /* Copy 33 vec registers (vr0..31 and vscr) from the stack */ + if (v_regs != 0 && (msr & MSR_VEC) != 0) + err |= __copy_from_user(current->thread.vr, v_regs, + 33 * sizeof(vector128)); + else if (current->thread.used_vr) + memset(current->thread.vr, 0, 33 * sizeof(vector128)); + /* Always get VRSAVE back */ + if (v_regs != 0) + err |= __get_user(current->thread.vrsave, (u32 __user *)&v_regs[33]); + else + current->thread.vrsave = 0; +#endif /* CONFIG_ALTIVEC */ + +#ifndef CONFIG_SMP + preempt_disable(); + if (last_task_used_math == current) + last_task_used_math = NULL; + if (last_task_used_altivec == current) + last_task_used_altivec = NULL; + preempt_enable(); +#endif + /* Force reload of FP/VEC */ + regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1 | MSR_VEC); + + return err; +} + +/* + * Allocate space for the signal frame + */ +static inline void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, + size_t frame_size) +{ + unsigned long newsp; + + /* Default to using normal stack */ + newsp = regs->gpr[1]; + + if (ka->sa.sa_flags & SA_ONSTACK) { + if (! on_sig_stack(regs->gpr[1])) + newsp = (current->sas_ss_sp + current->sas_ss_size); + } + + return (void __user *)((newsp - frame_size) & -16ul); +} + +/* + * Setup the trampoline code on the stack + */ +static long setup_trampoline(unsigned int syscall, unsigned int __user *tramp) +{ + int i; + long err = 0; + + /* addi r1, r1, __SIGNAL_FRAMESIZE # Pop the dummy stackframe */ + err |= __put_user(0x38210000UL | (__SIGNAL_FRAMESIZE & 0xffff), &tramp[0]); + /* li r0, __NR_[rt_]sigreturn| */ + err |= __put_user(0x38000000UL | (syscall & 0xffff), &tramp[1]); + /* sc */ + err |= __put_user(0x44000002UL, &tramp[2]); + + /* Minimal traceback info */ + for (i=TRAMP_TRACEBACK; i < TRAMP_SIZE ;i++) + err |= __put_user(0, &tramp[i]); + + if (!err) + flush_icache_range((unsigned long) &tramp[0], + (unsigned long) &tramp[TRAMP_SIZE]); + + return err; +} + +/* + * Restore the user process's signal mask (also used by signal32.c) + */ +void restore_sigmask(sigset_t *set) +{ + sigdelsetmask(set, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = *set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); +} + + +/* + * Handle {get,set,swap}_context operations + */ +int sys_swapcontext(struct ucontext __user *old_ctx, + struct ucontext __user *new_ctx, + long ctx_size, long r6, long r7, long r8, struct pt_regs *regs) +{ + unsigned char tmp; + sigset_t set; + + /* Context size is for future use. Right now, we only make sure + * we are passed something we understand + */ + if (ctx_size < sizeof(struct ucontext)) + return -EINVAL; + + if (old_ctx != NULL) { + if (!access_ok(VERIFY_WRITE, old_ctx, sizeof(*old_ctx)) + || setup_sigcontext(&old_ctx->uc_mcontext, regs, 0, NULL, 0) + || __copy_to_user(&old_ctx->uc_sigmask, + ¤t->blocked, sizeof(sigset_t))) + return -EFAULT; + } + if (new_ctx == NULL) + return 0; + if (!access_ok(VERIFY_READ, new_ctx, sizeof(*new_ctx)) + || __get_user(tmp, (u8 __user *) new_ctx) + || __get_user(tmp, (u8 __user *) (new_ctx + 1) - 1)) + return -EFAULT; + + /* + * If we get a fault copying the context into the kernel's + * image of the user's registers, we can't just return -EFAULT + * because the user's registers will be corrupted. For instance + * the NIP value may have been updated but not some of the + * other registers. Given that we have done the access_ok + * and successfully read the first and last bytes of the region + * above, this should only happen in an out-of-memory situation + * or if another thread unmaps the region containing the context. + * We kill the task with a SIGSEGV in this situation. + */ + + if (__copy_from_user(&set, &new_ctx->uc_sigmask, sizeof(set))) + do_exit(SIGSEGV); + restore_sigmask(&set); + if (restore_sigcontext(regs, NULL, 0, &new_ctx->uc_mcontext)) + do_exit(SIGSEGV); + + /* This returns like rt_sigreturn */ + return 0; +} + + +/* + * Do a signal return; undo the signal stack. + */ + +int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7, unsigned long r8, + struct pt_regs *regs) +{ + struct ucontext __user *uc = (struct ucontext __user *)regs->gpr[1]; + sigset_t set; + + /* Always make any pending restarted system calls return -EINTR */ + current_thread_info()->restart_block.fn = do_no_restart_syscall; + + if (!access_ok(VERIFY_READ, uc, sizeof(*uc))) + goto badframe; + + if (__copy_from_user(&set, &uc->uc_sigmask, sizeof(set))) + goto badframe; + restore_sigmask(&set); + if (restore_sigcontext(regs, NULL, 1, &uc->uc_mcontext)) + goto badframe; + + /* do_sigaltstack expects a __user pointer and won't modify + * what's in there anyway + */ + do_sigaltstack(&uc->uc_stack, NULL, regs->gpr[1]); + + return regs->result; + +badframe: +#if DEBUG_SIG + printk("badframe in sys_rt_sigreturn, regs=%p uc=%p &uc->uc_mcontext=%p\n", + regs, uc, &uc->uc_mcontext); +#endif + force_sig(SIGSEGV, current); + return 0; +} + +static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info, + sigset_t *set, struct pt_regs *regs) +{ + /* Handler is *really* a pointer to the function descriptor for + * the signal routine. The first entry in the function + * descriptor is the entry address of signal and the second + * entry is the TOC value we need to use. + */ + func_descr_t __user *funct_desc_ptr; + struct rt_sigframe __user *frame; + unsigned long newsp = 0; + long err = 0; + + frame = get_sigframe(ka, regs, sizeof(*frame)); + + if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) + goto badframe; + + err |= __put_user(&frame->info, &frame->pinfo); + err |= __put_user(&frame->uc, &frame->puc); + err |= copy_siginfo_to_user(&frame->info, info); + if (err) + goto badframe; + + /* Create the ucontext. */ + err |= __put_user(0, &frame->uc.uc_flags); + err |= __put_user(0, &frame->uc.uc_link); + err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); + err |= __put_user(sas_ss_flags(regs->gpr[1]), + &frame->uc.uc_stack.ss_flags); + err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); + err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, signr, NULL, + (unsigned long)ka->sa.sa_handler); + err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); + if (err) + goto badframe; + + /* Set up to return from userspace. */ + if (vdso64_rt_sigtramp && current->thread.vdso_base) { + regs->link = current->thread.vdso_base + vdso64_rt_sigtramp; + } else { + err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]); + if (err) + goto badframe; + regs->link = (unsigned long) &frame->tramp[0]; + } + funct_desc_ptr = (func_descr_t __user *) ka->sa.sa_handler; + + /* Allocate a dummy caller frame for the signal handler. */ + newsp = (unsigned long)frame - __SIGNAL_FRAMESIZE; + err |= put_user(regs->gpr[1], (unsigned long __user *)newsp); + + /* Set up "regs" so we "return" to the signal handler. */ + err |= get_user(regs->nip, &funct_desc_ptr->entry); + regs->gpr[1] = newsp; + err |= get_user(regs->gpr[2], &funct_desc_ptr->toc); + regs->gpr[3] = signr; + regs->result = 0; + if (ka->sa.sa_flags & SA_SIGINFO) { + err |= get_user(regs->gpr[4], (unsigned long __user *)&frame->pinfo); + err |= get_user(regs->gpr[5], (unsigned long __user *)&frame->puc); + regs->gpr[6] = (unsigned long) frame; + } else { + regs->gpr[4] = (unsigned long)&frame->uc.uc_mcontext; + } + if (err) + goto badframe; + + if (test_thread_flag(TIF_SINGLESTEP)) + ptrace_notify(SIGTRAP); + + return 1; + +badframe: +#if DEBUG_SIG + printk("badframe in setup_rt_frame, regs=%p frame=%p newsp=%lx\n", + regs, frame, newsp); +#endif + force_sigsegv(signr, current); + return 0; +} + + +/* + * OK, we're invoking a handler + */ +static int handle_signal(unsigned long sig, struct k_sigaction *ka, + siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) +{ + int ret; + + /* Set up Signal Frame */ + ret = setup_rt_frame(sig, ka, info, oldset, regs); + + if (ret) { + spin_lock_irq(¤t->sighand->siglock); + sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); + if (!(ka->sa.sa_flags & SA_NODEFER)) + sigaddset(¤t->blocked,sig); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + } + + return ret; +} + +static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) +{ + switch ((int)regs->result) { + case -ERESTART_RESTARTBLOCK: + case -ERESTARTNOHAND: + /* ERESTARTNOHAND means that the syscall should only be + * restarted if there was no handler for the signal, and since + * we only get here if there is a handler, we dont restart. + */ + regs->result = -EINTR; + break; + case -ERESTARTSYS: + /* ERESTARTSYS means to restart the syscall if there is no + * handler or the handler was registered with SA_RESTART + */ + if (!(ka->sa.sa_flags & SA_RESTART)) { + regs->result = -EINTR; + break; + } + /* fallthrough */ + case -ERESTARTNOINTR: + /* ERESTARTNOINTR means that the syscall should be + * called again after the signal handler returns. + */ + regs->gpr[3] = regs->orig_gpr3; + regs->nip -= 4; + regs->result = 0; + break; + } +} + +/* + * Note that 'init' is a special process: it doesn't get signals it doesn't + * want to handle. Thus you cannot kill init even with a SIGKILL even by + * mistake. + */ +int do_signal(sigset_t *oldset, struct pt_regs *regs) +{ + siginfo_t info; + int signr; + struct k_sigaction ka; + + /* + * If the current thread is 32 bit - invoke the + * 32 bit signal handling code + */ + if (test_thread_flag(TIF_32BIT)) + return do_signal32(oldset, regs); + + if (!oldset) + oldset = ¤t->blocked; + + signr = get_signal_to_deliver(&info, &ka, regs, NULL); + if (signr > 0) { + /* Whee! Actually deliver the signal. */ + if (TRAP(regs) == 0x0C00) + syscall_restart(regs, &ka); + + /* + * Reenable the DABR before delivering the signal to + * user space. The DABR will have been cleared if it + * triggered inside the kernel. + */ + if (current->thread.dabr) + set_dabr(current->thread.dabr); + + return handle_signal(signr, &ka, &info, oldset, regs); + } + + if (TRAP(regs) == 0x0C00) { /* System Call! */ + if ((int)regs->result == -ERESTARTNOHAND || + (int)regs->result == -ERESTARTSYS || + (int)regs->result == -ERESTARTNOINTR) { + regs->gpr[3] = regs->orig_gpr3; + regs->nip -= 4; /* Back up & retry system call */ + regs->result = 0; + } else if ((int)regs->result == -ERESTART_RESTARTBLOCK) { + regs->gpr[0] = __NR_restart_syscall; + regs->nip -= 4; + regs->result = 0; + } + } + + return 0; +} +EXPORT_SYMBOL(do_signal); diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 74892ad..430cb39 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -12,7 +12,6 @@ obj-y := misc.o prom.o endif obj-y += irq.o idle.o dma.o \ - signal.o \ align.o pacaData.o \ udbg.o ioctl32.o \ rtc.o \ diff --git a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c deleted file mode 100644 index ec9d098..0000000 --- a/arch/ppc64/kernel/signal.c +++ /dev/null @@ -1,581 +0,0 @@ -/* - * linux/arch/ppc64/kernel/signal.c - * - * PowerPC version - * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) - * - * Derived from "arch/i386/kernel/signal.c" - * Copyright (C) 1991, 1992 Linus Torvalds - * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG_SIG 0 - -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) - -#define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs)) -#define FP_REGS_SIZE sizeof(elf_fpregset_t) - -#define TRAMP_TRACEBACK 3 -#define TRAMP_SIZE 6 - -/* - * When we have signals to deliver, we set up on the user stack, - * going down from the original stack pointer: - * 1) a rt_sigframe struct which contains the ucontext - * 2) a gap of __SIGNAL_FRAMESIZE bytes which acts as a dummy caller - * frame for the signal handler. - */ - -struct rt_sigframe { - /* sys_rt_sigreturn requires the ucontext be the first field */ - struct ucontext uc; - unsigned long _unused[2]; - unsigned int tramp[TRAMP_SIZE]; - struct siginfo *pinfo; - void *puc; - struct siginfo info; - /* 64 bit ABI allows for 288 bytes below sp before decrementing it. */ - char abigap[288]; -} __attribute__ ((aligned (16))); - - -/* - * Atomically swap in the new signal mask, and wait for a signal. - */ -long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, int p3, int p4, - int p6, int p7, struct pt_regs *regs) -{ - sigset_t saveset, newset; - - /* XXX: Don't preclude handling different sized sigset_t's. */ - if (sigsetsize != sizeof(sigset_t)) - return -EINVAL; - - if (copy_from_user(&newset, unewset, sizeof(newset))) - return -EFAULT; - sigdelsetmask(&newset, ~_BLOCKABLE); - - spin_lock_irq(¤t->sighand->siglock); - saveset = current->blocked; - current->blocked = newset; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - regs->result = -EINTR; - regs->gpr[3] = EINTR; - regs->ccr |= 0x10000000; - while (1) { - current->state = TASK_INTERRUPTIBLE; - schedule(); - if (do_signal(&saveset, regs)) - return 0; - } -} - -long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, unsigned long r5, - unsigned long r6, unsigned long r7, unsigned long r8, - struct pt_regs *regs) -{ - return do_sigaltstack(uss, uoss, regs->gpr[1]); -} - - -/* - * Set up the sigcontext for the signal frame. - */ - -static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, - int signr, sigset_t *set, unsigned long handler) -{ - /* When CONFIG_ALTIVEC is set, we _always_ setup v_regs even if the - * process never used altivec yet (MSR_VEC is zero in pt_regs of - * the context). This is very important because we must ensure we - * don't lose the VRSAVE content that may have been set prior to - * the process doing its first vector operation - * Userland shall check AT_HWCAP to know wether it can rely on the - * v_regs pointer or not - */ -#ifdef CONFIG_ALTIVEC - elf_vrreg_t __user *v_regs = (elf_vrreg_t __user *)(((unsigned long)sc->vmx_reserve + 15) & ~0xful); -#endif - long err = 0; - - flush_fp_to_thread(current); - - /* Make sure signal doesn't get spurrious FP exceptions */ - current->thread.fpscr.val = 0; - -#ifdef CONFIG_ALTIVEC - err |= __put_user(v_regs, &sc->v_regs); - - /* save altivec registers */ - if (current->thread.used_vr) { - flush_altivec_to_thread(current); - /* Copy 33 vec registers (vr0..31 and vscr) to the stack */ - err |= __copy_to_user(v_regs, current->thread.vr, 33 * sizeof(vector128)); - /* set MSR_VEC in the MSR value in the frame to indicate that sc->v_reg) - * contains valid data. - */ - regs->msr |= MSR_VEC; - } - /* We always copy to/from vrsave, it's 0 if we don't have or don't - * use altivec. - */ - err |= __put_user(current->thread.vrsave, (u32 __user *)&v_regs[33]); -#else /* CONFIG_ALTIVEC */ - err |= __put_user(0, &sc->v_regs); -#endif /* CONFIG_ALTIVEC */ - err |= __put_user(&sc->gp_regs, &sc->regs); - err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE); - err |= __copy_to_user(&sc->fp_regs, ¤t->thread.fpr, FP_REGS_SIZE); - err |= __put_user(signr, &sc->signal); - err |= __put_user(handler, &sc->handler); - if (set != NULL) - err |= __put_user(set->sig[0], &sc->oldmask); - - return err; -} - -/* - * Restore the sigcontext from the signal frame. - */ - -static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig, - struct sigcontext __user *sc) -{ -#ifdef CONFIG_ALTIVEC - elf_vrreg_t __user *v_regs; -#endif - unsigned long err = 0; - unsigned long save_r13 = 0; - elf_greg_t *gregs = (elf_greg_t *)regs; -#ifdef CONFIG_ALTIVEC - unsigned long msr; -#endif - int i; - - /* If this is not a signal return, we preserve the TLS in r13 */ - if (!sig) - save_r13 = regs->gpr[13]; - - /* copy everything before MSR */ - err |= __copy_from_user(regs, &sc->gp_regs, - PT_MSR*sizeof(unsigned long)); - - /* skip MSR and SOFTE */ - for (i = PT_MSR+1; i <= PT_RESULT; i++) { - if (i == PT_SOFTE) - continue; - err |= __get_user(gregs[i], &sc->gp_regs[i]); - } - - if (!sig) - regs->gpr[13] = save_r13; - err |= __copy_from_user(¤t->thread.fpr, &sc->fp_regs, FP_REGS_SIZE); - if (set != NULL) - err |= __get_user(set->sig[0], &sc->oldmask); - -#ifdef CONFIG_ALTIVEC - err |= __get_user(v_regs, &sc->v_regs); - err |= __get_user(msr, &sc->gp_regs[PT_MSR]); - if (err) - return err; - /* Copy 33 vec registers (vr0..31 and vscr) from the stack */ - if (v_regs != 0 && (msr & MSR_VEC) != 0) - err |= __copy_from_user(current->thread.vr, v_regs, - 33 * sizeof(vector128)); - else if (current->thread.used_vr) - memset(current->thread.vr, 0, 33 * sizeof(vector128)); - /* Always get VRSAVE back */ - if (v_regs != 0) - err |= __get_user(current->thread.vrsave, (u32 __user *)&v_regs[33]); - else - current->thread.vrsave = 0; -#endif /* CONFIG_ALTIVEC */ - -#ifndef CONFIG_SMP - preempt_disable(); - if (last_task_used_math == current) - last_task_used_math = NULL; - if (last_task_used_altivec == current) - last_task_used_altivec = NULL; - preempt_enable(); -#endif - /* Force reload of FP/VEC */ - regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1 | MSR_VEC); - - return err; -} - -/* - * Allocate space for the signal frame - */ -static inline void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, - size_t frame_size) -{ - unsigned long newsp; - - /* Default to using normal stack */ - newsp = regs->gpr[1]; - - if (ka->sa.sa_flags & SA_ONSTACK) { - if (! on_sig_stack(regs->gpr[1])) - newsp = (current->sas_ss_sp + current->sas_ss_size); - } - - return (void __user *)((newsp - frame_size) & -16ul); -} - -/* - * Setup the trampoline code on the stack - */ -static long setup_trampoline(unsigned int syscall, unsigned int __user *tramp) -{ - int i; - long err = 0; - - /* addi r1, r1, __SIGNAL_FRAMESIZE # Pop the dummy stackframe */ - err |= __put_user(0x38210000UL | (__SIGNAL_FRAMESIZE & 0xffff), &tramp[0]); - /* li r0, __NR_[rt_]sigreturn| */ - err |= __put_user(0x38000000UL | (syscall & 0xffff), &tramp[1]); - /* sc */ - err |= __put_user(0x44000002UL, &tramp[2]); - - /* Minimal traceback info */ - for (i=TRAMP_TRACEBACK; i < TRAMP_SIZE ;i++) - err |= __put_user(0, &tramp[i]); - - if (!err) - flush_icache_range((unsigned long) &tramp[0], - (unsigned long) &tramp[TRAMP_SIZE]); - - return err; -} - -/* - * Restore the user process's signal mask (also used by signal32.c) - */ -void restore_sigmask(sigset_t *set) -{ - sigdelsetmask(set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = *set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); -} - - -/* - * Handle {get,set,swap}_context operations - */ -int sys_swapcontext(struct ucontext __user *old_ctx, - struct ucontext __user *new_ctx, - long ctx_size, long r6, long r7, long r8, struct pt_regs *regs) -{ - unsigned char tmp; - sigset_t set; - - /* Context size is for future use. Right now, we only make sure - * we are passed something we understand - */ - if (ctx_size < sizeof(struct ucontext)) - return -EINVAL; - - if (old_ctx != NULL) { - if (!access_ok(VERIFY_WRITE, old_ctx, sizeof(*old_ctx)) - || setup_sigcontext(&old_ctx->uc_mcontext, regs, 0, NULL, 0) - || __copy_to_user(&old_ctx->uc_sigmask, - ¤t->blocked, sizeof(sigset_t))) - return -EFAULT; - } - if (new_ctx == NULL) - return 0; - if (!access_ok(VERIFY_READ, new_ctx, sizeof(*new_ctx)) - || __get_user(tmp, (u8 __user *) new_ctx) - || __get_user(tmp, (u8 __user *) (new_ctx + 1) - 1)) - return -EFAULT; - - /* - * If we get a fault copying the context into the kernel's - * image of the user's registers, we can't just return -EFAULT - * because the user's registers will be corrupted. For instance - * the NIP value may have been updated but not some of the - * other registers. Given that we have done the access_ok - * and successfully read the first and last bytes of the region - * above, this should only happen in an out-of-memory situation - * or if another thread unmaps the region containing the context. - * We kill the task with a SIGSEGV in this situation. - */ - - if (__copy_from_user(&set, &new_ctx->uc_sigmask, sizeof(set))) - do_exit(SIGSEGV); - restore_sigmask(&set); - if (restore_sigcontext(regs, NULL, 0, &new_ctx->uc_mcontext)) - do_exit(SIGSEGV); - - /* This returns like rt_sigreturn */ - return 0; -} - - -/* - * Do a signal return; undo the signal stack. - */ - -int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, unsigned long r8, - struct pt_regs *regs) -{ - struct ucontext __user *uc = (struct ucontext __user *)regs->gpr[1]; - sigset_t set; - - /* Always make any pending restarted system calls return -EINTR */ - current_thread_info()->restart_block.fn = do_no_restart_syscall; - - if (!access_ok(VERIFY_READ, uc, sizeof(*uc))) - goto badframe; - - if (__copy_from_user(&set, &uc->uc_sigmask, sizeof(set))) - goto badframe; - restore_sigmask(&set); - if (restore_sigcontext(regs, NULL, 1, &uc->uc_mcontext)) - goto badframe; - - /* do_sigaltstack expects a __user pointer and won't modify - * what's in there anyway - */ - do_sigaltstack(&uc->uc_stack, NULL, regs->gpr[1]); - - return regs->result; - -badframe: -#if DEBUG_SIG - printk("badframe in sys_rt_sigreturn, regs=%p uc=%p &uc->uc_mcontext=%p\n", - regs, uc, &uc->uc_mcontext); -#endif - force_sig(SIGSEGV, current); - return 0; -} - -static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info, - sigset_t *set, struct pt_regs *regs) -{ - /* Handler is *really* a pointer to the function descriptor for - * the signal routine. The first entry in the function - * descriptor is the entry address of signal and the second - * entry is the TOC value we need to use. - */ - func_descr_t __user *funct_desc_ptr; - struct rt_sigframe __user *frame; - unsigned long newsp = 0; - long err = 0; - - frame = get_sigframe(ka, regs, sizeof(*frame)); - - if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) - goto badframe; - - err |= __put_user(&frame->info, &frame->pinfo); - err |= __put_user(&frame->uc, &frame->puc); - err |= copy_siginfo_to_user(&frame->info, info); - if (err) - goto badframe; - - /* Create the ucontext. */ - err |= __put_user(0, &frame->uc.uc_flags); - err |= __put_user(0, &frame->uc.uc_link); - err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); - err |= __put_user(sas_ss_flags(regs->gpr[1]), - &frame->uc.uc_stack.ss_flags); - err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); - err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, signr, NULL, - (unsigned long)ka->sa.sa_handler); - err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); - if (err) - goto badframe; - - /* Set up to return from userspace. */ - if (vdso64_rt_sigtramp && current->thread.vdso_base) { - regs->link = current->thread.vdso_base + vdso64_rt_sigtramp; - } else { - err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]); - if (err) - goto badframe; - regs->link = (unsigned long) &frame->tramp[0]; - } - funct_desc_ptr = (func_descr_t __user *) ka->sa.sa_handler; - - /* Allocate a dummy caller frame for the signal handler. */ - newsp = (unsigned long)frame - __SIGNAL_FRAMESIZE; - err |= put_user(regs->gpr[1], (unsigned long __user *)newsp); - - /* Set up "regs" so we "return" to the signal handler. */ - err |= get_user(regs->nip, &funct_desc_ptr->entry); - regs->gpr[1] = newsp; - err |= get_user(regs->gpr[2], &funct_desc_ptr->toc); - regs->gpr[3] = signr; - regs->result = 0; - if (ka->sa.sa_flags & SA_SIGINFO) { - err |= get_user(regs->gpr[4], (unsigned long __user *)&frame->pinfo); - err |= get_user(regs->gpr[5], (unsigned long __user *)&frame->puc); - regs->gpr[6] = (unsigned long) frame; - } else { - regs->gpr[4] = (unsigned long)&frame->uc.uc_mcontext; - } - if (err) - goto badframe; - - if (test_thread_flag(TIF_SINGLESTEP)) - ptrace_notify(SIGTRAP); - - return 1; - -badframe: -#if DEBUG_SIG - printk("badframe in setup_rt_frame, regs=%p frame=%p newsp=%lx\n", - regs, frame, newsp); -#endif - force_sigsegv(signr, current); - return 0; -} - - -/* - * OK, we're invoking a handler - */ -static int handle_signal(unsigned long sig, struct k_sigaction *ka, - siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) -{ - int ret; - - /* Set up Signal Frame */ - ret = setup_rt_frame(sig, ka, info, oldset, regs); - - if (ret) { - spin_lock_irq(¤t->sighand->siglock); - sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); - if (!(ka->sa.sa_flags & SA_NODEFER)) - sigaddset(¤t->blocked,sig); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - } - - return ret; -} - -static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) -{ - switch ((int)regs->result) { - case -ERESTART_RESTARTBLOCK: - case -ERESTARTNOHAND: - /* ERESTARTNOHAND means that the syscall should only be - * restarted if there was no handler for the signal, and since - * we only get here if there is a handler, we dont restart. - */ - regs->result = -EINTR; - break; - case -ERESTARTSYS: - /* ERESTARTSYS means to restart the syscall if there is no - * handler or the handler was registered with SA_RESTART - */ - if (!(ka->sa.sa_flags & SA_RESTART)) { - regs->result = -EINTR; - break; - } - /* fallthrough */ - case -ERESTARTNOINTR: - /* ERESTARTNOINTR means that the syscall should be - * called again after the signal handler returns. - */ - regs->gpr[3] = regs->orig_gpr3; - regs->nip -= 4; - regs->result = 0; - break; - } -} - -/* - * Note that 'init' is a special process: it doesn't get signals it doesn't - * want to handle. Thus you cannot kill init even with a SIGKILL even by - * mistake. - */ -int do_signal(sigset_t *oldset, struct pt_regs *regs) -{ - siginfo_t info; - int signr; - struct k_sigaction ka; - - /* - * If the current thread is 32 bit - invoke the - * 32 bit signal handling code - */ - if (test_thread_flag(TIF_32BIT)) - return do_signal32(oldset, regs); - - if (!oldset) - oldset = ¤t->blocked; - - signr = get_signal_to_deliver(&info, &ka, regs, NULL); - if (signr > 0) { - /* Whee! Actually deliver the signal. */ - if (TRAP(regs) == 0x0C00) - syscall_restart(regs, &ka); - - /* - * Reenable the DABR before delivering the signal to - * user space. The DABR will have been cleared if it - * triggered inside the kernel. - */ - if (current->thread.dabr) - set_dabr(current->thread.dabr); - - return handle_signal(signr, &ka, &info, oldset, regs); - } - - if (TRAP(regs) == 0x0C00) { /* System Call! */ - if ((int)regs->result == -ERESTARTNOHAND || - (int)regs->result == -ERESTARTSYS || - (int)regs->result == -ERESTARTNOINTR) { - regs->gpr[3] = regs->orig_gpr3; - regs->nip -= 4; /* Back up & retry system call */ - regs->result = 0; - } else if ((int)regs->result == -ERESTART_RESTARTBLOCK) { - regs->gpr[0] = __NR_restart_syscall; - regs->nip -= 4; - regs->result = 0; - } - } - - return 0; -} -EXPORT_SYMBOL(do_signal); -- cgit v1.1 From 879168ee51925f7e68165577fba8ef781ccfccb9 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 3 Nov 2005 15:32:07 +1100 Subject: powerpc: move include/asm-ppc64/ppc32.h to arch/powerpc/kernel It is only included by signal_32.c Signed-off-by: Stephen Rothwell --- arch/powerpc/kernel/ppc32.h | 138 ++++++++++++++++++++++++++++++++++++++++ arch/powerpc/kernel/signal_32.c | 2 +- include/asm-ppc64/ppc32.h | 138 ---------------------------------------- 3 files changed, 139 insertions(+), 139 deletions(-) create mode 100644 arch/powerpc/kernel/ppc32.h delete mode 100644 include/asm-ppc64/ppc32.h diff --git a/arch/powerpc/kernel/ppc32.h b/arch/powerpc/kernel/ppc32.h new file mode 100644 index 0000000..90e5627 --- /dev/null +++ b/arch/powerpc/kernel/ppc32.h @@ -0,0 +1,138 @@ +#ifndef _PPC64_PPC32_H +#define _PPC64_PPC32_H + +#include +#include +#include + +/* + * Data types and macros for providing 32b PowerPC support. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +/* These are here to support 32-bit syscalls on a 64-bit kernel. */ + +typedef struct compat_siginfo { + int si_signo; + int si_errno; + int si_code; + + union { + int _pad[SI_PAD_SIZE32]; + + /* kill() */ + struct { + compat_pid_t _pid; /* sender's pid */ + compat_uid_t _uid; /* sender's uid */ + } _kill; + + /* POSIX.1b timers */ + struct { + compat_timer_t _tid; /* timer id */ + int _overrun; /* overrun count */ + compat_sigval_t _sigval; /* same as below */ + int _sys_private; /* not to be passed to user */ + } _timer; + + /* POSIX.1b signals */ + struct { + compat_pid_t _pid; /* sender's pid */ + compat_uid_t _uid; /* sender's uid */ + compat_sigval_t _sigval; + } _rt; + + /* SIGCHLD */ + struct { + compat_pid_t _pid; /* which child */ + compat_uid_t _uid; /* sender's uid */ + int _status; /* exit code */ + compat_clock_t _utime; + compat_clock_t _stime; + } _sigchld; + + /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */ + struct { + unsigned int _addr; /* faulting insn/memory ref. */ + } _sigfault; + + /* SIGPOLL */ + struct { + int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ + int _fd; + } _sigpoll; + } _sifields; +} compat_siginfo_t; + +#define __old_sigaction32 old_sigaction32 + +struct __old_sigaction32 { + compat_uptr_t sa_handler; + compat_old_sigset_t sa_mask; + unsigned int sa_flags; + compat_uptr_t sa_restorer; /* not used by Linux/SPARC yet */ +}; + + + +struct sigaction32 { + compat_uptr_t sa_handler; /* Really a pointer, but need to deal with 32 bits */ + unsigned int sa_flags; + compat_uptr_t sa_restorer; /* Another 32 bit pointer */ + compat_sigset_t sa_mask; /* A 32 bit mask */ +}; + +typedef struct sigaltstack_32 { + unsigned int ss_sp; + int ss_flags; + compat_size_t ss_size; +} stack_32_t; + +struct pt_regs32 { + unsigned int gpr[32]; + unsigned int nip; + unsigned int msr; + unsigned int orig_gpr3; /* Used for restarting system calls */ + unsigned int ctr; + unsigned int link; + unsigned int xer; + unsigned int ccr; + unsigned int mq; /* 601 only (not used at present) */ + unsigned int trap; /* Reason for being here */ + unsigned int dar; /* Fault registers */ + unsigned int dsisr; + unsigned int result; /* Result of a system call */ +}; + +struct sigcontext32 { + unsigned int _unused[4]; + int signal; + compat_uptr_t handler; + unsigned int oldmask; + compat_uptr_t regs; /* 4 byte pointer to the pt_regs32 structure. */ +}; + +struct mcontext32 { + elf_gregset_t32 mc_gregs; + elf_fpregset_t mc_fregs; + unsigned int mc_pad[2]; + elf_vrregset_t32 mc_vregs __attribute__((__aligned__(16))); +}; + +struct ucontext32 { + unsigned int uc_flags; + unsigned int uc_link; + stack_32_t uc_stack; + int uc_pad[7]; + compat_uptr_t uc_regs; /* points to uc_mcontext field */ + compat_sigset_t uc_sigmask; /* mask last for extensibility */ + /* glibc has 1024-bit signal masks, ours are 64-bit */ + int uc_maskext[30]; + int uc_pad2[3]; + struct mcontext32 uc_mcontext; +}; + +#endif /* _PPC64_PPC32_H */ diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 444c3e8..876c57c 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -43,7 +43,7 @@ #include #include #ifdef CONFIG_PPC64 -#include +#include "ppc32.h" #include #include #include diff --git a/include/asm-ppc64/ppc32.h b/include/asm-ppc64/ppc32.h deleted file mode 100644 index 90e5627..0000000 --- a/include/asm-ppc64/ppc32.h +++ /dev/null @@ -1,138 +0,0 @@ -#ifndef _PPC64_PPC32_H -#define _PPC64_PPC32_H - -#include -#include -#include - -/* - * Data types and macros for providing 32b PowerPC support. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -/* These are here to support 32-bit syscalls on a 64-bit kernel. */ - -typedef struct compat_siginfo { - int si_signo; - int si_errno; - int si_code; - - union { - int _pad[SI_PAD_SIZE32]; - - /* kill() */ - struct { - compat_pid_t _pid; /* sender's pid */ - compat_uid_t _uid; /* sender's uid */ - } _kill; - - /* POSIX.1b timers */ - struct { - compat_timer_t _tid; /* timer id */ - int _overrun; /* overrun count */ - compat_sigval_t _sigval; /* same as below */ - int _sys_private; /* not to be passed to user */ - } _timer; - - /* POSIX.1b signals */ - struct { - compat_pid_t _pid; /* sender's pid */ - compat_uid_t _uid; /* sender's uid */ - compat_sigval_t _sigval; - } _rt; - - /* SIGCHLD */ - struct { - compat_pid_t _pid; /* which child */ - compat_uid_t _uid; /* sender's uid */ - int _status; /* exit code */ - compat_clock_t _utime; - compat_clock_t _stime; - } _sigchld; - - /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */ - struct { - unsigned int _addr; /* faulting insn/memory ref. */ - } _sigfault; - - /* SIGPOLL */ - struct { - int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ - int _fd; - } _sigpoll; - } _sifields; -} compat_siginfo_t; - -#define __old_sigaction32 old_sigaction32 - -struct __old_sigaction32 { - compat_uptr_t sa_handler; - compat_old_sigset_t sa_mask; - unsigned int sa_flags; - compat_uptr_t sa_restorer; /* not used by Linux/SPARC yet */ -}; - - - -struct sigaction32 { - compat_uptr_t sa_handler; /* Really a pointer, but need to deal with 32 bits */ - unsigned int sa_flags; - compat_uptr_t sa_restorer; /* Another 32 bit pointer */ - compat_sigset_t sa_mask; /* A 32 bit mask */ -}; - -typedef struct sigaltstack_32 { - unsigned int ss_sp; - int ss_flags; - compat_size_t ss_size; -} stack_32_t; - -struct pt_regs32 { - unsigned int gpr[32]; - unsigned int nip; - unsigned int msr; - unsigned int orig_gpr3; /* Used for restarting system calls */ - unsigned int ctr; - unsigned int link; - unsigned int xer; - unsigned int ccr; - unsigned int mq; /* 601 only (not used at present) */ - unsigned int trap; /* Reason for being here */ - unsigned int dar; /* Fault registers */ - unsigned int dsisr; - unsigned int result; /* Result of a system call */ -}; - -struct sigcontext32 { - unsigned int _unused[4]; - int signal; - compat_uptr_t handler; - unsigned int oldmask; - compat_uptr_t regs; /* 4 byte pointer to the pt_regs32 structure. */ -}; - -struct mcontext32 { - elf_gregset_t32 mc_gregs; - elf_fpregset_t mc_fregs; - unsigned int mc_pad[2]; - elf_vrregset_t32 mc_vregs __attribute__((__aligned__(16))); -}; - -struct ucontext32 { - unsigned int uc_flags; - unsigned int uc_link; - stack_32_t uc_stack; - int uc_pad[7]; - compat_uptr_t uc_regs; /* points to uc_mcontext field */ - compat_sigset_t uc_sigmask; /* mask last for extensibility */ - /* glibc has 1024-bit signal masks, ours are 64-bit */ - int uc_maskext[30]; - int uc_pad2[3]; - struct mcontext32 uc_mcontext; -}; - -#endif /* _PPC64_PPC32_H */ -- cgit v1.1 From 608f8b3cf3a7fbd009e6bf78e680ea04e6a4e46f Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 3 Nov 2005 16:24:25 +1100 Subject: powerpc: merge sigcontext.h Signed-off-by: Stephen Rothwell --- include/asm-powerpc/sigcontext.h | 52 ++++++++++++++++++++++++++++++++++++++++ include/asm-ppc/sigcontext.h | 15 ------------ include/asm-ppc64/sigcontext.h | 47 ------------------------------------ 3 files changed, 52 insertions(+), 62 deletions(-) create mode 100644 include/asm-powerpc/sigcontext.h delete mode 100644 include/asm-ppc/sigcontext.h delete mode 100644 include/asm-ppc64/sigcontext.h diff --git a/include/asm-powerpc/sigcontext.h b/include/asm-powerpc/sigcontext.h new file mode 100644 index 0000000..165d630 --- /dev/null +++ b/include/asm-powerpc/sigcontext.h @@ -0,0 +1,52 @@ +#ifndef _ASM_POWERPC_SIGCONTEXT_H +#define _ASM_POWERPC_SIGCONTEXT_H + +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include +#include +#ifdef __powerpc64__ +#include +#endif + +struct sigcontext { + unsigned long _unused[4]; + int signal; +#ifdef __powerpc64__ + int _pad0; +#endif + unsigned long handler; + unsigned long oldmask; + struct pt_regs __user *regs; +#ifdef __powerpc64__ + elf_gregset_t gp_regs; + elf_fpregset_t fp_regs; +/* + * To maintain compatibility with current implementations the sigcontext is + * extended by appending a pointer (v_regs) to a quadword type (elf_vrreg_t) + * followed by an unstructured (vmx_reserve) field of 69 doublewords. This + * allows the array of vector registers to be quadword aligned independent of + * the alignment of the containing sigcontext or ucontext. It is the + * responsibility of the code setting the sigcontext to set this pointer to + * either NULL (if this processor does not support the VMX feature) or the + * address of the first quadword within the allocated (vmx_reserve) area. + * + * The pointer (v_regs) of vector type (elf_vrreg_t) is type compatible with + * an array of 34 quadword entries (elf_vrregset_t). The entries with + * indexes 0-31 contain the corresponding vector registers. The entry with + * index 32 contains the vscr as the last word (offset 12) within the + * quadword. This allows the vscr to be stored as either a quadword (since + * it must be copied via a vector register to/from storage) or as a word. + * The entry with index 33 contains the vrsave as the first word (offset 0) + * within the quadword. + */ + elf_vrreg_t __user *v_regs; + long vmx_reserve[ELF_NVRREG+ELF_NVRREG+1]; +#endif +}; + +#endif /* _ASM_POWERPC_SIGCONTEXT_H */ diff --git a/include/asm-ppc/sigcontext.h b/include/asm-ppc/sigcontext.h deleted file mode 100644 index b7a417e..0000000 --- a/include/asm-ppc/sigcontext.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _ASM_PPC_SIGCONTEXT_H -#define _ASM_PPC_SIGCONTEXT_H - -#include -#include - -struct sigcontext { - unsigned long _unused[4]; - int signal; - unsigned long handler; - unsigned long oldmask; - struct pt_regs __user *regs; -}; - -#endif diff --git a/include/asm-ppc64/sigcontext.h b/include/asm-ppc64/sigcontext.h deleted file mode 100644 index 6f8aee7..0000000 --- a/include/asm-ppc64/sigcontext.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef _ASM_PPC64_SIGCONTEXT_H -#define _ASM_PPC64_SIGCONTEXT_H - -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#include -#include -#include - - -struct sigcontext { - unsigned long _unused[4]; - int signal; - int _pad0; - unsigned long handler; - unsigned long oldmask; - struct pt_regs __user *regs; - elf_gregset_t gp_regs; - elf_fpregset_t fp_regs; -/* - * To maintain compatibility with current implementations the sigcontext is - * extended by appending a pointer (v_regs) to a quadword type (elf_vrreg_t) - * followed by an unstructured (vmx_reserve) field of 69 doublewords. This - * allows the array of vector registers to be quadword aligned independent of - * the alignment of the containing sigcontext or ucontext. It is the - * responsibility of the code setting the sigcontext to set this pointer to - * either NULL (if this processor does not support the VMX feature) or the - * address of the first quadword within the allocated (vmx_reserve) area. - * - * The pointer (v_regs) of vector type (elf_vrreg_t) is type compatible with - * an array of 34 quadword entries (elf_vrregset_t). The entries with - * indexes 0-31 contain the corresponding vector registers. The entry with - * index 32 contains the vscr as the last word (offset 12) within the - * quadword. This allows the vscr to be stored as either a quadword (since - * it must be copied via a vector register to/from storage) or as a word. - * The entry with index 33 contains the vrsave as the first word (offset 0) - * within the quadword. - */ - elf_vrreg_t __user *v_regs; - long vmx_reserve[ELF_NVRREG+ELF_NVRREG+1]; -}; - -#endif /* _ASM_PPC64_SIGCONTEXT_H */ -- cgit v1.1 From 5adb83c2fa136e14172b1a65b0f8aa28f2cb9f62 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 3 Nov 2005 16:59:17 +1100 Subject: powerpc: merge ucontext.h Signed-off-by: Stephen Rothwell --- include/asm-powerpc/ucontext.h | 40 ++++++++++++++++++++++++++++++++++++++++ include/asm-ppc/ucontext.h | 27 --------------------------- include/asm-ppc64/ucontext.h | 22 ---------------------- 3 files changed, 40 insertions(+), 49 deletions(-) create mode 100644 include/asm-powerpc/ucontext.h delete mode 100644 include/asm-ppc/ucontext.h delete mode 100644 include/asm-ppc64/ucontext.h diff --git a/include/asm-powerpc/ucontext.h b/include/asm-powerpc/ucontext.h new file mode 100644 index 0000000..d9a4ddf --- /dev/null +++ b/include/asm-powerpc/ucontext.h @@ -0,0 +1,40 @@ +#ifndef _ASM_POWERPC_UCONTEXT_H +#define _ASM_POWERPC_UCONTEXT_H + +#ifdef __powerpc64__ +#include +#else +#include +#endif +#include + +#ifndef __powerpc64__ +struct mcontext { + elf_gregset_t mc_gregs; + elf_fpregset_t mc_fregs; + unsigned long mc_pad[2]; + elf_vrregset_t mc_vregs __attribute__((__aligned__(16))); +}; +#endif + +struct ucontext { + unsigned long uc_flags; + struct ucontext __user *uc_link; + stack_t uc_stack; +#ifndef __powerpc64__ + int uc_pad[7]; + struct mcontext __user *uc_regs;/* points to uc_mcontext field */ +#endif + sigset_t uc_sigmask; + /* glibc has 1024-bit signal masks, ours are 64-bit */ +#ifdef __powerpc64__ + sigset_t __unused[15]; /* Allow for uc_sigmask growth */ + struct sigcontext uc_mcontext; /* last for extensibility */ +#else + int uc_maskext[30]; + int uc_pad2[3]; + struct mcontext uc_mcontext; +#endif +}; + +#endif /* _ASM_POWERPC_UCONTEXT_H */ diff --git a/include/asm-ppc/ucontext.h b/include/asm-ppc/ucontext.h deleted file mode 100644 index 664bc98..0000000 --- a/include/asm-ppc/ucontext.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _ASMPPC_UCONTEXT_H -#define _ASMPPC_UCONTEXT_H - -#include -#include - -struct mcontext { - elf_gregset_t mc_gregs; - elf_fpregset_t mc_fregs; - unsigned long mc_pad[2]; - elf_vrregset_t mc_vregs __attribute__((__aligned__(16))); -}; - -struct ucontext { - unsigned long uc_flags; - struct ucontext __user *uc_link; - stack_t uc_stack; - int uc_pad[7]; - struct mcontext __user *uc_regs;/* points to uc_mcontext field */ - sigset_t uc_sigmask; - /* glibc has 1024-bit signal masks, ours are 64-bit */ - int uc_maskext[30]; - int uc_pad2[3]; - struct mcontext uc_mcontext; -}; - -#endif /* !_ASMPPC_UCONTEXT_H */ diff --git a/include/asm-ppc64/ucontext.h b/include/asm-ppc64/ucontext.h deleted file mode 100644 index ef8cc5b..0000000 --- a/include/asm-ppc64/ucontext.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _ASMPPC64_UCONTEXT_H -#define _ASMPPC64_UCONTEXT_H - -#include - -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -struct ucontext { - unsigned long uc_flags; - struct ucontext *uc_link; - stack_t uc_stack; - sigset_t uc_sigmask; - sigset_t __unsued[15]; /* Allow for uc_sigmask growth */ - struct sigcontext uc_mcontext; /* last for extensibility */ -}; - -#endif /* _ASMPPC64_UCONTEXT_H */ -- cgit v1.1