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> 1234bbeed0SSven Schnelle #include <asm/tpi.h> 13c6557e7fSMartin Schwidefsky 14d3a73acbSMartin Schwidefsky #define PIF_SYSCALL 0 /* inside a system call */ 1556e62a73SSven Schnelle #define PIF_SYSCALL_RESTART 1 /* restart the current system call */ 1656e62a73SSven Schnelle #define PIF_SYSCALL_RET_SET 2 /* return value was set via ptrace */ 17c771320eSMartin Schwidefsky #define PIF_GUEST_FAULT 3 /* indicates program check in sie64a */ 18d3a73acbSMartin Schwidefsky 19fe6ba88bSMasahiro Yamada #define _PIF_SYSCALL BIT(PIF_SYSCALL) 20fe6ba88bSMasahiro Yamada #define _PIF_SYSCALL_RESTART BIT(PIF_SYSCALL_RESTART) 2156e62a73SSven Schnelle #define _PIF_SYSCALL_RET_SET BIT(PIF_SYSCALL_RET_SET) 22fe6ba88bSMasahiro Yamada #define _PIF_GUEST_FAULT BIT(PIF_GUEST_FAULT) 23d3a73acbSMartin Schwidefsky 24c6557e7fSMartin Schwidefsky #ifndef __ASSEMBLY__ 2563dd9b44SHeiko Carstens 26e258d719SMartin Schwidefsky #define PSW_KERNEL_BITS (PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_ASC_HOME | \ 27e258d719SMartin Schwidefsky PSW_MASK_EA | PSW_MASK_BA) 28e258d719SMartin Schwidefsky #define PSW_USER_BITS (PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | \ 29e258d719SMartin Schwidefsky PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_MCHECK | \ 30e258d719SMartin Schwidefsky PSW_MASK_PSTATE | PSW_ASC_PRIMARY) 31c6557e7fSMartin Schwidefsky 321365632bSHeiko Carstens struct psw_bits { 33cb951785SHeiko Carstens unsigned long : 1; 34a7525982SHeiko Carstens unsigned long per : 1; /* PER-Mask */ 35cb951785SHeiko Carstens unsigned long : 3; 36a7525982SHeiko Carstens unsigned long dat : 1; /* DAT Mode */ 37a7525982SHeiko Carstens unsigned long io : 1; /* Input/Output Mask */ 38a7525982SHeiko Carstens unsigned long ext : 1; /* External Mask */ 39cb951785SHeiko Carstens unsigned long key : 4; /* PSW Key */ 40cb951785SHeiko Carstens unsigned long : 1; 41a7525982SHeiko Carstens unsigned long mcheck : 1; /* Machine-Check Mask */ 42a7525982SHeiko Carstens unsigned long wait : 1; /* Wait State */ 43a7525982SHeiko Carstens unsigned long pstate : 1; /* Problem State */ 44cb951785SHeiko Carstens unsigned long as : 2; /* Address Space Control */ 45cb951785SHeiko Carstens unsigned long cc : 2; /* Condition Code */ 46cb951785SHeiko Carstens unsigned long pm : 4; /* Program Mask */ 47cb951785SHeiko Carstens unsigned long ri : 1; /* Runtime Instrumentation */ 48cb951785SHeiko Carstens unsigned long : 6; 49cb951785SHeiko Carstens unsigned long eaba : 2; /* Addressing Mode */ 50cb951785SHeiko Carstens unsigned long : 31; 51cb951785SHeiko Carstens unsigned long ia : 64; /* Instruction Address */ 521365632bSHeiko Carstens }; 531365632bSHeiko Carstens 541365632bSHeiko Carstens enum { 558bb3fdd6SHeiko Carstens PSW_BITS_AMODE_24BIT = 0, 568bb3fdd6SHeiko Carstens PSW_BITS_AMODE_31BIT = 1, 578bb3fdd6SHeiko Carstens PSW_BITS_AMODE_64BIT = 3 581365632bSHeiko Carstens }; 591365632bSHeiko Carstens 601365632bSHeiko Carstens enum { 618bb3fdd6SHeiko Carstens PSW_BITS_AS_PRIMARY = 0, 628bb3fdd6SHeiko Carstens PSW_BITS_AS_ACCREG = 1, 638bb3fdd6SHeiko Carstens PSW_BITS_AS_SECONDARY = 2, 648bb3fdd6SHeiko Carstens PSW_BITS_AS_HOME = 3 651365632bSHeiko Carstens }; 661365632bSHeiko Carstens 671365632bSHeiko Carstens #define psw_bits(__psw) (*({ \ 681365632bSHeiko Carstens typecheck(psw_t, __psw); \ 691365632bSHeiko Carstens &(*(struct psw_bits *)(&(__psw))); \ 701365632bSHeiko Carstens })) 711365632bSHeiko Carstens 7256e62a73SSven Schnelle #define PGM_INT_CODE_MASK 0x7f 7356e62a73SSven Schnelle #define PGM_INT_CODE_PER 0x80 7456e62a73SSven Schnelle 75c6557e7fSMartin Schwidefsky /* 76c6557e7fSMartin Schwidefsky * The pt_regs struct defines the way the registers are stored on 77c6557e7fSMartin Schwidefsky * the stack during a system call. 78c6557e7fSMartin Schwidefsky */ 79c6557e7fSMartin Schwidefsky struct pt_regs 80c6557e7fSMartin Schwidefsky { 81466698e6SHendrik Brueckner union { 82466698e6SHendrik Brueckner user_pt_regs user_regs; 83466698e6SHendrik Brueckner struct { 84c6557e7fSMartin Schwidefsky unsigned long args[1]; 85c6557e7fSMartin Schwidefsky psw_t psw; 86c6557e7fSMartin Schwidefsky unsigned long gprs[NUM_GPRS]; 87466698e6SHendrik Brueckner }; 88466698e6SHendrik Brueckner }; 89c6557e7fSMartin Schwidefsky unsigned long orig_gpr2; 9034bbeed0SSven Schnelle union { 9134bbeed0SSven Schnelle struct { 92aa33c8cbSMartin Schwidefsky unsigned int int_code; 9348f6b00cSMartin Schwidefsky unsigned int int_parm; 94aa33c8cbSMartin Schwidefsky unsigned long int_parm_long; 9534bbeed0SSven Schnelle }; 9634bbeed0SSven Schnelle struct tpi_info tpi_info; 9734bbeed0SSven Schnelle }; 98d3a73acbSMartin Schwidefsky unsigned long flags; 9987d59863SHeiko Carstens unsigned long cr1; 100c6557e7fSMartin Schwidefsky }; 1015e9a2692SMartin Schwidefsky 1025e9a2692SMartin Schwidefsky /* 1035e9a2692SMartin Schwidefsky * Program event recording (PER) register set. 1045e9a2692SMartin Schwidefsky */ 1055e9a2692SMartin Schwidefsky struct per_regs { 1065e9a2692SMartin Schwidefsky unsigned long control; /* PER control bits */ 1075e9a2692SMartin Schwidefsky unsigned long start; /* PER starting address */ 1085e9a2692SMartin Schwidefsky unsigned long end; /* PER ending address */ 1095e9a2692SMartin Schwidefsky }; 1105e9a2692SMartin Schwidefsky 1115e9a2692SMartin Schwidefsky /* 1125e9a2692SMartin Schwidefsky * PER event contains information about the cause of the last PER exception. 1135e9a2692SMartin Schwidefsky */ 1145e9a2692SMartin Schwidefsky struct per_event { 1155e9a2692SMartin Schwidefsky unsigned short cause; /* PER code, ATMID and AI */ 1165e9a2692SMartin Schwidefsky unsigned long address; /* PER address */ 1175e9a2692SMartin Schwidefsky unsigned char paid; /* PER access identification */ 1185e9a2692SMartin Schwidefsky }; 1195e9a2692SMartin Schwidefsky 1205e9a2692SMartin Schwidefsky /* 1215e9a2692SMartin Schwidefsky * Simplified per_info structure used to decode the ptrace user space ABI. 1225e9a2692SMartin Schwidefsky */ 1235e9a2692SMartin Schwidefsky struct per_struct_kernel { 1245e9a2692SMartin Schwidefsky unsigned long cr9; /* PER control bits */ 1255e9a2692SMartin Schwidefsky unsigned long cr10; /* PER starting address */ 1265e9a2692SMartin Schwidefsky unsigned long cr11; /* PER ending address */ 1275e9a2692SMartin Schwidefsky unsigned long bits; /* Obsolete software bits */ 1285e9a2692SMartin Schwidefsky unsigned long starting_addr; /* User specified start address */ 1295e9a2692SMartin Schwidefsky unsigned long ending_addr; /* User specified end address */ 1305e9a2692SMartin Schwidefsky unsigned short perc_atmid; /* PER trap ATMID */ 1315e9a2692SMartin Schwidefsky unsigned long address; /* PER trap instruction address */ 1325e9a2692SMartin Schwidefsky unsigned char access_id; /* PER trap access identification */ 1335e9a2692SMartin Schwidefsky }; 1345e9a2692SMartin Schwidefsky 135d35339a4SMartin Schwidefsky #define PER_EVENT_MASK 0xEB000000UL 1365e9a2692SMartin Schwidefsky 1375e9a2692SMartin Schwidefsky #define PER_EVENT_BRANCH 0x80000000UL 1385e9a2692SMartin Schwidefsky #define PER_EVENT_IFETCH 0x40000000UL 1395e9a2692SMartin Schwidefsky #define PER_EVENT_STORE 0x20000000UL 1405e9a2692SMartin Schwidefsky #define PER_EVENT_STORE_REAL 0x08000000UL 141d35339a4SMartin Schwidefsky #define PER_EVENT_TRANSACTION_END 0x02000000UL 1425e9a2692SMartin Schwidefsky #define PER_EVENT_NULLIFICATION 0x01000000UL 1435e9a2692SMartin Schwidefsky 144d35339a4SMartin Schwidefsky #define PER_CONTROL_MASK 0x00e00000UL 1455e9a2692SMartin Schwidefsky 1465e9a2692SMartin Schwidefsky #define PER_CONTROL_BRANCH_ADDRESS 0x00800000UL 147d35339a4SMartin Schwidefsky #define PER_CONTROL_SUSPENSION 0x00400000UL 1485e9a2692SMartin Schwidefsky #define PER_CONTROL_ALTERATION 0x00200000UL 1495e9a2692SMartin Schwidefsky 150d3a73acbSMartin Schwidefsky static inline void set_pt_regs_flag(struct pt_regs *regs, int flag) 151d3a73acbSMartin Schwidefsky { 152ac25e790SHeiko Carstens regs->flags |= (1UL << flag); 153d3a73acbSMartin Schwidefsky } 154d3a73acbSMartin Schwidefsky 155d3a73acbSMartin Schwidefsky static inline void clear_pt_regs_flag(struct pt_regs *regs, int flag) 156d3a73acbSMartin Schwidefsky { 157ac25e790SHeiko Carstens regs->flags &= ~(1UL << flag); 158d3a73acbSMartin Schwidefsky } 159d3a73acbSMartin Schwidefsky 160d3a73acbSMartin Schwidefsky static inline int test_pt_regs_flag(struct pt_regs *regs, int flag) 161d3a73acbSMartin Schwidefsky { 162ac25e790SHeiko Carstens return !!(regs->flags & (1UL << flag)); 163d3a73acbSMartin Schwidefsky } 164d3a73acbSMartin Schwidefsky 165*e3c7a8d7SSven Schnelle static inline int test_and_clear_pt_regs_flag(struct pt_regs *regs, int flag) 166*e3c7a8d7SSven Schnelle { 167*e3c7a8d7SSven Schnelle int ret = test_pt_regs_flag(regs, flag); 168*e3c7a8d7SSven Schnelle 169*e3c7a8d7SSven Schnelle clear_pt_regs_flag(regs, flag); 170*e3c7a8d7SSven Schnelle return ret; 171*e3c7a8d7SSven Schnelle } 172*e3c7a8d7SSven Schnelle 173c6557e7fSMartin Schwidefsky /* 174c6557e7fSMartin Schwidefsky * These are defined as per linux/ptrace.h, which see. 175c6557e7fSMartin Schwidefsky */ 176c6557e7fSMartin Schwidefsky #define arch_has_single_step() (1) 177818a330cSMartin Schwidefsky #define arch_has_block_step() (1) 178c6557e7fSMartin Schwidefsky 179c6557e7fSMartin Schwidefsky #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) 1809cb1ccecSHeiko Carstens #define instruction_pointer(regs) ((regs)->psw.addr) 181753c4dd6SMartin Schwidefsky #define user_stack_pointer(regs)((regs)->gprs[15]) 182c6557e7fSMartin Schwidefsky #define profile_pc(regs) instruction_pointer(regs) 183952974acSHeiko Carstens 184d7e7528bSEric Paris static inline long regs_return_value(struct pt_regs *regs) 185d7e7528bSEric Paris { 186d7e7528bSEric Paris return regs->gprs[2]; 187d7e7528bSEric Paris } 188d7e7528bSEric Paris 1892a0a5b22SJan Willeke static inline void instruction_pointer_set(struct pt_regs *regs, 1902a0a5b22SJan Willeke unsigned long val) 1912a0a5b22SJan Willeke { 192fecc868aSHeiko Carstens regs->psw.addr = val; 1932a0a5b22SJan Willeke } 1942a0a5b22SJan Willeke 195952974acSHeiko Carstens int regs_query_register_offset(const char *name); 196952974acSHeiko Carstens const char *regs_query_register_name(unsigned int offset); 197952974acSHeiko Carstens unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset); 198952974acSHeiko Carstens unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n); 199952974acSHeiko Carstens 200952974acSHeiko Carstens static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) 201952974acSHeiko Carstens { 2029cb1ccecSHeiko Carstens return regs->gprs[15]; 203952974acSHeiko Carstens } 204952974acSHeiko Carstens 20573d6eb48SIlya Leoshkevich static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) 20673d6eb48SIlya Leoshkevich { 20773d6eb48SIlya Leoshkevich regs->gprs[2] = rc; 20873d6eb48SIlya Leoshkevich } 20973d6eb48SIlya Leoshkevich 210c6557e7fSMartin Schwidefsky #endif /* __ASSEMBLY__ */ 211c6557e7fSMartin Schwidefsky #endif /* _S390_PTRACE_H */ 212