1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 2c6557e7fSMartin Schwidefsky /* 3c6557e7fSMartin Schwidefsky * S390 version 4a53c8fabSHeiko Carstens * Copyright IBM Corp. 1999, 2000 5c6557e7fSMartin Schwidefsky * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) 6c6557e7fSMartin Schwidefsky */ 7c6557e7fSMartin Schwidefsky #ifndef _S390_PTRACE_H 8c6557e7fSMartin Schwidefsky #define _S390_PTRACE_H 9c6557e7fSMartin Schwidefsky 10fe6ba88bSMasahiro Yamada #include <linux/bits.h> 119807f759SDavid Howells #include <uapi/asm/ptrace.h> 12c6557e7fSMartin Schwidefsky 13d3a73acbSMartin Schwidefsky #define PIF_SYSCALL 0 /* inside a system call */ 14d3a73acbSMartin Schwidefsky #define PIF_PER_TRAP 1 /* deliver sigtrap on return to user */ 1523fefe11SMartin Schwidefsky #define PIF_SYSCALL_RESTART 2 /* restart the current system call */ 16c771320eSMartin Schwidefsky #define PIF_GUEST_FAULT 3 /* indicates program check in sie64a */ 17d3a73acbSMartin Schwidefsky 18fe6ba88bSMasahiro Yamada #define _PIF_SYSCALL BIT(PIF_SYSCALL) 19fe6ba88bSMasahiro Yamada #define _PIF_PER_TRAP BIT(PIF_PER_TRAP) 20fe6ba88bSMasahiro Yamada #define _PIF_SYSCALL_RESTART BIT(PIF_SYSCALL_RESTART) 21fe6ba88bSMasahiro Yamada #define _PIF_GUEST_FAULT BIT(PIF_GUEST_FAULT) 22d3a73acbSMartin Schwidefsky 23c6557e7fSMartin Schwidefsky #ifndef __ASSEMBLY__ 2463dd9b44SHeiko Carstens 25e258d719SMartin Schwidefsky #define PSW_KERNEL_BITS (PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_ASC_HOME | \ 26e258d719SMartin Schwidefsky PSW_MASK_EA | PSW_MASK_BA) 27e258d719SMartin Schwidefsky #define PSW_USER_BITS (PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | \ 28e258d719SMartin Schwidefsky PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_MCHECK | \ 29e258d719SMartin Schwidefsky PSW_MASK_PSTATE | PSW_ASC_PRIMARY) 30c6557e7fSMartin Schwidefsky 311365632bSHeiko Carstens struct psw_bits { 32cb951785SHeiko Carstens unsigned long : 1; 33a7525982SHeiko Carstens unsigned long per : 1; /* PER-Mask */ 34cb951785SHeiko Carstens unsigned long : 3; 35a7525982SHeiko Carstens unsigned long dat : 1; /* DAT Mode */ 36a7525982SHeiko Carstens unsigned long io : 1; /* Input/Output Mask */ 37a7525982SHeiko Carstens unsigned long ext : 1; /* External Mask */ 38cb951785SHeiko Carstens unsigned long key : 4; /* PSW Key */ 39cb951785SHeiko Carstens unsigned long : 1; 40a7525982SHeiko Carstens unsigned long mcheck : 1; /* Machine-Check Mask */ 41a7525982SHeiko Carstens unsigned long wait : 1; /* Wait State */ 42a7525982SHeiko Carstens unsigned long pstate : 1; /* Problem State */ 43cb951785SHeiko Carstens unsigned long as : 2; /* Address Space Control */ 44cb951785SHeiko Carstens unsigned long cc : 2; /* Condition Code */ 45cb951785SHeiko Carstens unsigned long pm : 4; /* Program Mask */ 46cb951785SHeiko Carstens unsigned long ri : 1; /* Runtime Instrumentation */ 47cb951785SHeiko Carstens unsigned long : 6; 48cb951785SHeiko Carstens unsigned long eaba : 2; /* Addressing Mode */ 49cb951785SHeiko Carstens unsigned long : 31; 50cb951785SHeiko Carstens unsigned long ia : 64; /* Instruction Address */ 511365632bSHeiko Carstens }; 521365632bSHeiko Carstens 531365632bSHeiko Carstens enum { 548bb3fdd6SHeiko Carstens PSW_BITS_AMODE_24BIT = 0, 558bb3fdd6SHeiko Carstens PSW_BITS_AMODE_31BIT = 1, 568bb3fdd6SHeiko Carstens PSW_BITS_AMODE_64BIT = 3 571365632bSHeiko Carstens }; 581365632bSHeiko Carstens 591365632bSHeiko Carstens enum { 608bb3fdd6SHeiko Carstens PSW_BITS_AS_PRIMARY = 0, 618bb3fdd6SHeiko Carstens PSW_BITS_AS_ACCREG = 1, 628bb3fdd6SHeiko Carstens PSW_BITS_AS_SECONDARY = 2, 638bb3fdd6SHeiko Carstens PSW_BITS_AS_HOME = 3 641365632bSHeiko Carstens }; 651365632bSHeiko Carstens 661365632bSHeiko Carstens #define psw_bits(__psw) (*({ \ 671365632bSHeiko Carstens typecheck(psw_t, __psw); \ 681365632bSHeiko Carstens &(*(struct psw_bits *)(&(__psw))); \ 691365632bSHeiko Carstens })) 701365632bSHeiko Carstens 71c6557e7fSMartin Schwidefsky /* 72c6557e7fSMartin Schwidefsky * The pt_regs struct defines the way the registers are stored on 73c6557e7fSMartin Schwidefsky * the stack during a system call. 74c6557e7fSMartin Schwidefsky */ 75c6557e7fSMartin Schwidefsky struct pt_regs 76c6557e7fSMartin Schwidefsky { 77466698e6SHendrik Brueckner union { 78466698e6SHendrik Brueckner user_pt_regs user_regs; 79466698e6SHendrik Brueckner struct { 80c6557e7fSMartin Schwidefsky unsigned long args[1]; 81c6557e7fSMartin Schwidefsky psw_t psw; 82c6557e7fSMartin Schwidefsky unsigned long gprs[NUM_GPRS]; 83466698e6SHendrik Brueckner }; 84466698e6SHendrik Brueckner }; 85c6557e7fSMartin Schwidefsky unsigned long orig_gpr2; 86aa33c8cbSMartin Schwidefsky unsigned int int_code; 8748f6b00cSMartin Schwidefsky unsigned int int_parm; 88aa33c8cbSMartin Schwidefsky unsigned long int_parm_long; 89d3a73acbSMartin Schwidefsky unsigned long flags; 90c6557e7fSMartin Schwidefsky }; 915e9a2692SMartin Schwidefsky 925e9a2692SMartin Schwidefsky /* 935e9a2692SMartin Schwidefsky * Program event recording (PER) register set. 945e9a2692SMartin Schwidefsky */ 955e9a2692SMartin Schwidefsky struct per_regs { 965e9a2692SMartin Schwidefsky unsigned long control; /* PER control bits */ 975e9a2692SMartin Schwidefsky unsigned long start; /* PER starting address */ 985e9a2692SMartin Schwidefsky unsigned long end; /* PER ending address */ 995e9a2692SMartin Schwidefsky }; 1005e9a2692SMartin Schwidefsky 1015e9a2692SMartin Schwidefsky /* 1025e9a2692SMartin Schwidefsky * PER event contains information about the cause of the last PER exception. 1035e9a2692SMartin Schwidefsky */ 1045e9a2692SMartin Schwidefsky struct per_event { 1055e9a2692SMartin Schwidefsky unsigned short cause; /* PER code, ATMID and AI */ 1065e9a2692SMartin Schwidefsky unsigned long address; /* PER address */ 1075e9a2692SMartin Schwidefsky unsigned char paid; /* PER access identification */ 1085e9a2692SMartin Schwidefsky }; 1095e9a2692SMartin Schwidefsky 1105e9a2692SMartin Schwidefsky /* 1115e9a2692SMartin Schwidefsky * Simplified per_info structure used to decode the ptrace user space ABI. 1125e9a2692SMartin Schwidefsky */ 1135e9a2692SMartin Schwidefsky struct per_struct_kernel { 1145e9a2692SMartin Schwidefsky unsigned long cr9; /* PER control bits */ 1155e9a2692SMartin Schwidefsky unsigned long cr10; /* PER starting address */ 1165e9a2692SMartin Schwidefsky unsigned long cr11; /* PER ending address */ 1175e9a2692SMartin Schwidefsky unsigned long bits; /* Obsolete software bits */ 1185e9a2692SMartin Schwidefsky unsigned long starting_addr; /* User specified start address */ 1195e9a2692SMartin Schwidefsky unsigned long ending_addr; /* User specified end address */ 1205e9a2692SMartin Schwidefsky unsigned short perc_atmid; /* PER trap ATMID */ 1215e9a2692SMartin Schwidefsky unsigned long address; /* PER trap instruction address */ 1225e9a2692SMartin Schwidefsky unsigned char access_id; /* PER trap access identification */ 1235e9a2692SMartin Schwidefsky }; 1245e9a2692SMartin Schwidefsky 125d35339a4SMartin Schwidefsky #define PER_EVENT_MASK 0xEB000000UL 1265e9a2692SMartin Schwidefsky 1275e9a2692SMartin Schwidefsky #define PER_EVENT_BRANCH 0x80000000UL 1285e9a2692SMartin Schwidefsky #define PER_EVENT_IFETCH 0x40000000UL 1295e9a2692SMartin Schwidefsky #define PER_EVENT_STORE 0x20000000UL 1305e9a2692SMartin Schwidefsky #define PER_EVENT_STORE_REAL 0x08000000UL 131d35339a4SMartin Schwidefsky #define PER_EVENT_TRANSACTION_END 0x02000000UL 1325e9a2692SMartin Schwidefsky #define PER_EVENT_NULLIFICATION 0x01000000UL 1335e9a2692SMartin Schwidefsky 134d35339a4SMartin Schwidefsky #define PER_CONTROL_MASK 0x00e00000UL 1355e9a2692SMartin Schwidefsky 1365e9a2692SMartin Schwidefsky #define PER_CONTROL_BRANCH_ADDRESS 0x00800000UL 137d35339a4SMartin Schwidefsky #define PER_CONTROL_SUSPENSION 0x00400000UL 1385e9a2692SMartin Schwidefsky #define PER_CONTROL_ALTERATION 0x00200000UL 1395e9a2692SMartin Schwidefsky 140d3a73acbSMartin Schwidefsky static inline void set_pt_regs_flag(struct pt_regs *regs, int flag) 141d3a73acbSMartin Schwidefsky { 142ac25e790SHeiko Carstens regs->flags |= (1UL << flag); 143d3a73acbSMartin Schwidefsky } 144d3a73acbSMartin Schwidefsky 145d3a73acbSMartin Schwidefsky static inline void clear_pt_regs_flag(struct pt_regs *regs, int flag) 146d3a73acbSMartin Schwidefsky { 147ac25e790SHeiko Carstens regs->flags &= ~(1UL << flag); 148d3a73acbSMartin Schwidefsky } 149d3a73acbSMartin Schwidefsky 150d3a73acbSMartin Schwidefsky static inline int test_pt_regs_flag(struct pt_regs *regs, int flag) 151d3a73acbSMartin Schwidefsky { 152ac25e790SHeiko Carstens return !!(regs->flags & (1UL << flag)); 153d3a73acbSMartin Schwidefsky } 154d3a73acbSMartin Schwidefsky 155c6557e7fSMartin Schwidefsky /* 156c6557e7fSMartin Schwidefsky * These are defined as per linux/ptrace.h, which see. 157c6557e7fSMartin Schwidefsky */ 158c6557e7fSMartin Schwidefsky #define arch_has_single_step() (1) 159818a330cSMartin Schwidefsky #define arch_has_block_step() (1) 160c6557e7fSMartin Schwidefsky 161c6557e7fSMartin Schwidefsky #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) 1629cb1ccecSHeiko Carstens #define instruction_pointer(regs) ((regs)->psw.addr) 163753c4dd6SMartin Schwidefsky #define user_stack_pointer(regs)((regs)->gprs[15]) 164c6557e7fSMartin Schwidefsky #define profile_pc(regs) instruction_pointer(regs) 165952974acSHeiko Carstens 166d7e7528bSEric Paris static inline long regs_return_value(struct pt_regs *regs) 167d7e7528bSEric Paris { 168d7e7528bSEric Paris return regs->gprs[2]; 169d7e7528bSEric Paris } 170d7e7528bSEric Paris 1712a0a5b22SJan Willeke static inline void instruction_pointer_set(struct pt_regs *regs, 1722a0a5b22SJan Willeke unsigned long val) 1732a0a5b22SJan Willeke { 174fecc868aSHeiko Carstens regs->psw.addr = val; 1752a0a5b22SJan Willeke } 1762a0a5b22SJan Willeke 177952974acSHeiko Carstens int regs_query_register_offset(const char *name); 178952974acSHeiko Carstens const char *regs_query_register_name(unsigned int offset); 179952974acSHeiko Carstens unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset); 180952974acSHeiko Carstens unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n); 181952974acSHeiko Carstens 182952974acSHeiko Carstens static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) 183952974acSHeiko Carstens { 1849cb1ccecSHeiko Carstens return regs->gprs[15]; 185952974acSHeiko Carstens } 186952974acSHeiko Carstens 18773d6eb48SIlya Leoshkevich static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) 18873d6eb48SIlya Leoshkevich { 18973d6eb48SIlya Leoshkevich regs->gprs[2] = rc; 19073d6eb48SIlya Leoshkevich } 19173d6eb48SIlya Leoshkevich 192c6557e7fSMartin Schwidefsky #endif /* __ASSEMBLY__ */ 193c6557e7fSMartin Schwidefsky #endif /* _S390_PTRACE_H */ 194