xref: /linux/arch/s390/kernel/dis.c (revision 3a39d672e7f48b8d6b91a09afa4b55352773b4b5)
1  // SPDX-License-Identifier: GPL-2.0
2  /*
3   * Disassemble s390 instructions.
4   *
5   * Copyright IBM Corp. 2007
6   * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
7   */
8  
9  #include <linux/sched.h>
10  #include <linux/kernel.h>
11  #include <linux/string.h>
12  #include <linux/errno.h>
13  #include <linux/ptrace.h>
14  #include <linux/timer.h>
15  #include <linux/mm.h>
16  #include <linux/smp.h>
17  #include <linux/init.h>
18  #include <linux/interrupt.h>
19  #include <linux/delay.h>
20  #include <linux/export.h>
21  #include <linux/kallsyms.h>
22  #include <linux/reboot.h>
23  #include <linux/kprobes.h>
24  #include <linux/kdebug.h>
25  #include <linux/uaccess.h>
26  #include <linux/atomic.h>
27  #include <linux/io.h>
28  #include <asm/dis.h>
29  #include <asm/cpcmd.h>
30  #include <asm/lowcore.h>
31  #include <asm/debug.h>
32  #include <asm/irq.h>
33  
34  /* Type of operand */
35  #define OPERAND_GPR	0x1	/* Operand printed as %rx */
36  #define OPERAND_FPR	0x2	/* Operand printed as %fx */
37  #define OPERAND_AR	0x4	/* Operand printed as %ax */
38  #define OPERAND_CR	0x8	/* Operand printed as %cx */
39  #define OPERAND_VR	0x10	/* Operand printed as %vx */
40  #define OPERAND_DISP	0x20	/* Operand printed as displacement */
41  #define OPERAND_BASE	0x40	/* Operand printed as base register */
42  #define OPERAND_INDEX	0x80	/* Operand printed as index register */
43  #define OPERAND_PCREL	0x100	/* Operand printed as pc-relative symbol */
44  #define OPERAND_SIGNED	0x200	/* Operand printed as signed value */
45  #define OPERAND_LENGTH	0x400	/* Operand printed as length (+1) */
46  
47  struct s390_operand {
48  	unsigned char bits;	/* The number of bits in the operand. */
49  	unsigned char shift;	/* The number of bits to shift. */
50  	unsigned short flags;	/* One bit syntax flags. */
51  };
52  
53  struct s390_insn {
54  	union {
55  		const char name[5];
56  		struct {
57  			unsigned char zero;
58  			unsigned int offset;
59  		} __packed;
60  	};
61  	unsigned char opfrag;
62  	unsigned char format;
63  };
64  
65  struct s390_opcode_offset {
66  	unsigned char opcode;
67  	unsigned char mask;
68  	unsigned char byte;
69  	unsigned short offset;
70  	unsigned short count;
71  } __packed;
72  
73  enum {
74  	UNUSED,
75  	A_8,	/* Access reg. starting at position 8 */
76  	A_12,	/* Access reg. starting at position 12 */
77  	A_24,	/* Access reg. starting at position 24 */
78  	A_28,	/* Access reg. starting at position 28 */
79  	B_16,	/* Base register starting at position 16 */
80  	B_32,	/* Base register starting at position 32 */
81  	C_8,	/* Control reg. starting at position 8 */
82  	C_12,	/* Control reg. starting at position 12 */
83  	D20_20, /* 20 bit displacement starting at 20 */
84  	D_20,	/* Displacement starting at position 20 */
85  	D_36,	/* Displacement starting at position 36 */
86  	F_8,	/* FPR starting at position 8 */
87  	F_12,	/* FPR starting at position 12 */
88  	F_16,	/* FPR starting at position 16 */
89  	F_24,	/* FPR starting at position 24 */
90  	F_28,	/* FPR starting at position 28 */
91  	F_32,	/* FPR starting at position 32 */
92  	I8_8,	/* 8 bit signed value starting at 8 */
93  	I8_32,	/* 8 bit signed value starting at 32 */
94  	I16_16, /* 16 bit signed value starting at 16 */
95  	I16_32, /* 16 bit signed value starting at 32 */
96  	I32_16, /* 32 bit signed value starting at 16 */
97  	J12_12, /* 12 bit PC relative offset at 12 */
98  	J16_16, /* 16 bit PC relative offset at 16 */
99  	J16_32, /* 16 bit PC relative offset at 32 */
100  	J24_24, /* 24 bit PC relative offset at 24 */
101  	J32_16, /* 32 bit PC relative offset at 16 */
102  	L4_8,	/* 4 bit length starting at position 8 */
103  	L4_12,	/* 4 bit length starting at position 12 */
104  	L8_8,	/* 8 bit length starting at position 8 */
105  	R_8,	/* GPR starting at position 8 */
106  	R_12,	/* GPR starting at position 12 */
107  	R_16,	/* GPR starting at position 16 */
108  	R_24,	/* GPR starting at position 24 */
109  	R_28,	/* GPR starting at position 28 */
110  	U4_8,	/* 4 bit unsigned value starting at 8 */
111  	U4_12,	/* 4 bit unsigned value starting at 12 */
112  	U4_16,	/* 4 bit unsigned value starting at 16 */
113  	U4_20,	/* 4 bit unsigned value starting at 20 */
114  	U4_24,	/* 4 bit unsigned value starting at 24 */
115  	U4_28,	/* 4 bit unsigned value starting at 28 */
116  	U4_32,	/* 4 bit unsigned value starting at 32 */
117  	U4_36,	/* 4 bit unsigned value starting at 36 */
118  	U8_8,	/* 8 bit unsigned value starting at 8 */
119  	U8_16,	/* 8 bit unsigned value starting at 16 */
120  	U8_24,	/* 8 bit unsigned value starting at 24 */
121  	U8_28,	/* 8 bit unsigned value starting at 28 */
122  	U8_32,	/* 8 bit unsigned value starting at 32 */
123  	U12_16, /* 12 bit unsigned value starting at 16 */
124  	U16_16, /* 16 bit unsigned value starting at 16 */
125  	U16_20, /* 16 bit unsigned value starting at 20 */
126  	U16_32, /* 16 bit unsigned value starting at 32 */
127  	U32_16, /* 32 bit unsigned value starting at 16 */
128  	VX_12,	/* Vector index register starting at position 12 */
129  	V_8,	/* Vector reg. starting at position 8 */
130  	V_12,	/* Vector reg. starting at position 12 */
131  	V_16,	/* Vector reg. starting at position 16 */
132  	V_32,	/* Vector reg. starting at position 32 */
133  	X_12,	/* Index register starting at position 12 */
134  };
135  
136  static const struct s390_operand operands[] = {
137  	[UNUSED] = {  0,  0, 0 },
138  	[A_8]	 = {  4,  8, OPERAND_AR },
139  	[A_12]	 = {  4, 12, OPERAND_AR },
140  	[A_24]	 = {  4, 24, OPERAND_AR },
141  	[A_28]	 = {  4, 28, OPERAND_AR },
142  	[B_16]	 = {  4, 16, OPERAND_BASE | OPERAND_GPR },
143  	[B_32]	 = {  4, 32, OPERAND_BASE | OPERAND_GPR },
144  	[C_8]	 = {  4,  8, OPERAND_CR },
145  	[C_12]	 = {  4, 12, OPERAND_CR },
146  	[D20_20] = { 20, 20, OPERAND_DISP | OPERAND_SIGNED },
147  	[D_20]	 = { 12, 20, OPERAND_DISP },
148  	[D_36]	 = { 12, 36, OPERAND_DISP },
149  	[F_8]	 = {  4,  8, OPERAND_FPR },
150  	[F_12]	 = {  4, 12, OPERAND_FPR },
151  	[F_16]	 = {  4, 16, OPERAND_FPR },
152  	[F_24]	 = {  4, 24, OPERAND_FPR },
153  	[F_28]	 = {  4, 28, OPERAND_FPR },
154  	[F_32]	 = {  4, 32, OPERAND_FPR },
155  	[I8_8]	 = {  8,  8, OPERAND_SIGNED },
156  	[I8_32]	 = {  8, 32, OPERAND_SIGNED },
157  	[I16_16] = { 16, 16, OPERAND_SIGNED },
158  	[I16_32] = { 16, 32, OPERAND_SIGNED },
159  	[I32_16] = { 32, 16, OPERAND_SIGNED },
160  	[J12_12] = { 12, 12, OPERAND_PCREL },
161  	[J16_16] = { 16, 16, OPERAND_PCREL },
162  	[J16_32] = { 16, 32, OPERAND_PCREL },
163  	[J24_24] = { 24, 24, OPERAND_PCREL },
164  	[J32_16] = { 32, 16, OPERAND_PCREL },
165  	[L4_8]	 = {  4,  8, OPERAND_LENGTH },
166  	[L4_12]	 = {  4, 12, OPERAND_LENGTH },
167  	[L8_8]	 = {  8,  8, OPERAND_LENGTH },
168  	[R_8]	 = {  4,  8, OPERAND_GPR },
169  	[R_12]	 = {  4, 12, OPERAND_GPR },
170  	[R_16]	 = {  4, 16, OPERAND_GPR },
171  	[R_24]	 = {  4, 24, OPERAND_GPR },
172  	[R_28]	 = {  4, 28, OPERAND_GPR },
173  	[U4_8]	 = {  4,  8, 0 },
174  	[U4_12]	 = {  4, 12, 0 },
175  	[U4_16]	 = {  4, 16, 0 },
176  	[U4_20]	 = {  4, 20, 0 },
177  	[U4_24]	 = {  4, 24, 0 },
178  	[U4_28]	 = {  4, 28, 0 },
179  	[U4_32]	 = {  4, 32, 0 },
180  	[U4_36]	 = {  4, 36, 0 },
181  	[U8_8]	 = {  8,  8, 0 },
182  	[U8_16]	 = {  8, 16, 0 },
183  	[U8_24]	 = {  8, 24, 0 },
184  	[U8_28]	 = {  8, 28, 0 },
185  	[U8_32]	 = {  8, 32, 0 },
186  	[U12_16] = { 12, 16, 0 },
187  	[U16_16] = { 16, 16, 0 },
188  	[U16_20] = { 16, 20, 0 },
189  	[U16_32] = { 16, 32, 0 },
190  	[U32_16] = { 32, 16, 0 },
191  	[VX_12]	 = {  4, 12, OPERAND_INDEX | OPERAND_VR },
192  	[V_8]	 = {  4,  8, OPERAND_VR },
193  	[V_12]	 = {  4, 12, OPERAND_VR },
194  	[V_16]	 = {  4, 16, OPERAND_VR },
195  	[V_32]	 = {  4, 32, OPERAND_VR },
196  	[X_12]	 = {  4, 12, OPERAND_INDEX | OPERAND_GPR },
197  };
198  
199  static const unsigned char formats[][6] = {
200  	[INSTR_E]	     = { 0, 0, 0, 0, 0, 0 },
201  	[INSTR_IE_UU]	     = { U4_24, U4_28, 0, 0, 0, 0 },
202  	[INSTR_MII_UPP]	     = { U4_8, J12_12, J24_24 },
203  	[INSTR_RIE_R0IU]     = { R_8, I16_16, U4_32, 0, 0, 0 },
204  	[INSTR_RIE_R0UU]     = { R_8, U16_16, U4_32, 0, 0, 0 },
205  	[INSTR_RIE_RRI0]     = { R_8, R_12, I16_16, 0, 0, 0 },
206  	[INSTR_RIE_RRP]	     = { R_8, R_12, J16_16, 0, 0, 0 },
207  	[INSTR_RIE_RRPU]     = { R_8, R_12, U4_32, J16_16, 0, 0 },
208  	[INSTR_RIE_RRUUU]    = { R_8, R_12, U8_16, U8_24, U8_32, 0 },
209  	[INSTR_RIE_RUI0]     = { R_8, I16_16, U4_12, 0, 0, 0 },
210  	[INSTR_RIE_RUPI]     = { R_8, I8_32, U4_12, J16_16, 0, 0 },
211  	[INSTR_RIE_RUPU]     = { R_8, U8_32, U4_12, J16_16, 0, 0 },
212  	[INSTR_RIL_RI]	     = { R_8, I32_16, 0, 0, 0, 0 },
213  	[INSTR_RIL_RP]	     = { R_8, J32_16, 0, 0, 0, 0 },
214  	[INSTR_RIL_RU]	     = { R_8, U32_16, 0, 0, 0, 0 },
215  	[INSTR_RIL_UP]	     = { U4_8, J32_16, 0, 0, 0, 0 },
216  	[INSTR_RIS_RURDI]    = { R_8, I8_32, U4_12, D_20, B_16, 0 },
217  	[INSTR_RIS_RURDU]    = { R_8, U8_32, U4_12, D_20, B_16, 0 },
218  	[INSTR_RI_RI]	     = { R_8, I16_16, 0, 0, 0, 0 },
219  	[INSTR_RI_RP]	     = { R_8, J16_16, 0, 0, 0, 0 },
220  	[INSTR_RI_RU]	     = { R_8, U16_16, 0, 0, 0, 0 },
221  	[INSTR_RI_UP]	     = { U4_8, J16_16, 0, 0, 0, 0 },
222  	[INSTR_RRE_00]	     = { 0, 0, 0, 0, 0, 0 },
223  	[INSTR_RRE_AA]	     = { A_24, A_28, 0, 0, 0, 0 },
224  	[INSTR_RRE_AR]	     = { A_24, R_28, 0, 0, 0, 0 },
225  	[INSTR_RRE_F0]	     = { F_24, 0, 0, 0, 0, 0 },
226  	[INSTR_RRE_FF]	     = { F_24, F_28, 0, 0, 0, 0 },
227  	[INSTR_RRE_FR]	     = { F_24, R_28, 0, 0, 0, 0 },
228  	[INSTR_RRE_R0]	     = { R_24, 0, 0, 0, 0, 0 },
229  	[INSTR_RRE_RA]	     = { R_24, A_28, 0, 0, 0, 0 },
230  	[INSTR_RRE_RF]	     = { R_24, F_28, 0, 0, 0, 0 },
231  	[INSTR_RRE_RR]	     = { R_24, R_28, 0, 0, 0, 0 },
232  	[INSTR_RRF_0UFF]     = { F_24, F_28, U4_20, 0, 0, 0 },
233  	[INSTR_RRF_0URF]     = { R_24, F_28, U4_20, 0, 0, 0 },
234  	[INSTR_RRF_F0FF]     = { F_16, F_24, F_28, 0, 0, 0 },
235  	[INSTR_RRF_F0FF2]    = { F_24, F_16, F_28, 0, 0, 0 },
236  	[INSTR_RRF_F0FR]     = { F_24, F_16, R_28, 0, 0, 0 },
237  	[INSTR_RRF_FFRU]     = { F_24, F_16, R_28, U4_20, 0, 0 },
238  	[INSTR_RRF_FUFF]     = { F_24, F_16, F_28, U4_20, 0, 0 },
239  	[INSTR_RRF_FUFF2]    = { F_24, F_28, F_16, U4_20, 0, 0 },
240  	[INSTR_RRF_R0RR]     = { R_24, R_16, R_28, 0, 0, 0 },
241  	[INSTR_RRF_R0RR2]    = { R_24, R_28, R_16, 0, 0, 0 },
242  	[INSTR_RRF_RURR]     = { R_24, R_28, R_16, U4_20, 0, 0 },
243  	[INSTR_RRF_RURR2]    = { R_24, R_16, R_28, U4_20, 0, 0 },
244  	[INSTR_RRF_U0FF]     = { F_24, U4_16, F_28, 0, 0, 0 },
245  	[INSTR_RRF_U0RF]     = { R_24, U4_16, F_28, 0, 0, 0 },
246  	[INSTR_RRF_U0RR]     = { R_24, R_28, U4_16, 0, 0, 0 },
247  	[INSTR_RRF_URR]	     = { R_24, R_28, U8_16, 0, 0, 0 },
248  	[INSTR_RRF_UUFF]     = { F_24, U4_16, F_28, U4_20, 0, 0 },
249  	[INSTR_RRF_UUFR]     = { F_24, U4_16, R_28, U4_20, 0, 0 },
250  	[INSTR_RRF_UURF]     = { R_24, U4_16, F_28, U4_20, 0, 0 },
251  	[INSTR_RRS_RRRDU]    = { R_8, R_12, U4_32, D_20, B_16 },
252  	[INSTR_RR_FF]	     = { F_8, F_12, 0, 0, 0, 0 },
253  	[INSTR_RR_R0]	     = { R_8,  0, 0, 0, 0, 0 },
254  	[INSTR_RR_RR]	     = { R_8, R_12, 0, 0, 0, 0 },
255  	[INSTR_RR_U0]	     = { U8_8,	0, 0, 0, 0, 0 },
256  	[INSTR_RR_UR]	     = { U4_8, R_12, 0, 0, 0, 0 },
257  	[INSTR_RSI_RRP]	     = { R_8, R_12, J16_16, 0, 0, 0 },
258  	[INSTR_RSL_LRDFU]    = { F_32, D_20, L8_8, B_16, U4_36, 0 },
259  	[INSTR_RSL_R0RD]     = { D_20, L4_8, B_16, 0, 0, 0 },
260  	[INSTR_RSY_AARD]     = { A_8, A_12, D20_20, B_16, 0, 0 },
261  	[INSTR_RSY_CCRD]     = { C_8, C_12, D20_20, B_16, 0, 0 },
262  	[INSTR_RSY_RRRD]     = { R_8, R_12, D20_20, B_16, 0, 0 },
263  	[INSTR_RSY_RURD]     = { R_8, U4_12, D20_20, B_16, 0, 0 },
264  	[INSTR_RSY_RURD2]    = { R_8, D20_20, B_16, U4_12, 0, 0 },
265  	[INSTR_RS_AARD]	     = { A_8, A_12, D_20, B_16, 0, 0 },
266  	[INSTR_RS_CCRD]	     = { C_8, C_12, D_20, B_16, 0, 0 },
267  	[INSTR_RS_R0RD]	     = { R_8, D_20, B_16, 0, 0, 0 },
268  	[INSTR_RS_RRRD]	     = { R_8, R_12, D_20, B_16, 0, 0 },
269  	[INSTR_RS_RURD]	     = { R_8, U4_12, D_20, B_16, 0, 0 },
270  	[INSTR_RXE_FRRD]     = { F_8, D_20, X_12, B_16, 0, 0 },
271  	[INSTR_RXE_RRRDU]    = { R_8, D_20, X_12, B_16, U4_32, 0 },
272  	[INSTR_RXF_FRRDF]    = { F_32, F_8, D_20, X_12, B_16, 0 },
273  	[INSTR_RXY_FRRD]     = { F_8, D20_20, X_12, B_16, 0, 0 },
274  	[INSTR_RXY_RRRD]     = { R_8, D20_20, X_12, B_16, 0, 0 },
275  	[INSTR_RXY_URRD]     = { U4_8, D20_20, X_12, B_16, 0, 0 },
276  	[INSTR_RX_FRRD]	     = { F_8, D_20, X_12, B_16, 0, 0 },
277  	[INSTR_RX_RRRD]	     = { R_8, D_20, X_12, B_16, 0, 0 },
278  	[INSTR_RX_URRD]	     = { U4_8, D_20, X_12, B_16, 0, 0 },
279  	[INSTR_SIL_RDI]	     = { D_20, B_16, I16_32, 0, 0, 0 },
280  	[INSTR_SIL_RDU]	     = { D_20, B_16, U16_32, 0, 0, 0 },
281  	[INSTR_SIY_IRD]	     = { D20_20, B_16, I8_8, 0, 0, 0 },
282  	[INSTR_SIY_RD]	     = { D20_20, B_16, 0, 0, 0, 0 },
283  	[INSTR_SIY_URD]	     = { D20_20, B_16, U8_8, 0, 0, 0 },
284  	[INSTR_SI_RD]	     = { D_20, B_16, 0, 0, 0, 0 },
285  	[INSTR_SI_URD]	     = { D_20, B_16, U8_8, 0, 0, 0 },
286  	[INSTR_SMI_U0RDP]    = { U4_8, J16_32, D_20, B_16, 0, 0 },
287  	[INSTR_SSE_RDRD]     = { D_20, B_16, D_36, B_32, 0, 0 },
288  	[INSTR_SSF_RRDRD]    = { D_20, B_16, D_36, B_32, R_8, 0 },
289  	[INSTR_SSF_RRDRD2]   = { R_8, D_20, B_16, D_36, B_32, 0 },
290  	[INSTR_SS_L0RDRD]    = { D_20, L8_8, B_16, D_36, B_32, 0 },
291  	[INSTR_SS_L2RDRD]    = { D_20, B_16, D_36, L8_8, B_32, 0 },
292  	[INSTR_SS_LIRDRD]    = { D_20, L4_8, B_16, D_36, B_32, U4_12 },
293  	[INSTR_SS_LLRDRD]    = { D_20, L4_8, B_16, D_36, L4_12, B_32 },
294  	[INSTR_SS_RRRDRD]    = { D_20, R_8, B_16, D_36, B_32, R_12 },
295  	[INSTR_SS_RRRDRD2]   = { R_8, D_20, B_16, R_12, D_36, B_32 },
296  	[INSTR_SS_RRRDRD3]   = { R_8, R_12, D_20, B_16, D_36, B_32 },
297  	[INSTR_S_00]	     = { 0, 0, 0, 0, 0, 0 },
298  	[INSTR_S_RD]	     = { D_20, B_16, 0, 0, 0, 0 },
299  	[INSTR_VRI_V0IU]     = { V_8, I16_16, U4_32, 0, 0, 0 },
300  	[INSTR_VRI_V0U]	     = { V_8, U16_16, 0, 0, 0, 0 },
301  	[INSTR_VRI_V0UU2]    = { V_8, U16_16, U4_32, 0, 0, 0 },
302  	[INSTR_VRI_V0UUU]    = { V_8, U8_16, U8_24, U4_32, 0, 0 },
303  	[INSTR_VRI_VR0UU]    = { V_8, R_12, U8_28, U4_24, 0, 0 },
304  	[INSTR_VRI_VV0UU]    = { V_8, V_12, U8_28, U4_24, 0, 0 },
305  	[INSTR_VRI_VVUU]     = { V_8, V_12, U16_16, U4_32, 0, 0 },
306  	[INSTR_VRI_VVUUU]    = { V_8, V_12, U12_16, U4_32, U4_28, 0 },
307  	[INSTR_VRI_VVUUU2]   = { V_8, V_12, U8_28, U8_16, U4_24, 0 },
308  	[INSTR_VRI_VVV0U]    = { V_8, V_12, V_16, U8_24, 0, 0 },
309  	[INSTR_VRI_VVV0UU]   = { V_8, V_12, V_16, U8_24, U4_32, 0 },
310  	[INSTR_VRI_VVV0UU2]  = { V_8, V_12, V_16, U8_28, U4_24, 0 },
311  	[INSTR_VRI_VVV0UV]   = { V_8, V_12, V_16, V_32, U8_24, 0 },
312  	[INSTR_VRR_0V0U]     = { V_12, U16_20, 0, 0, 0, 0 },
313  	[INSTR_VRR_0VV0U]    = { V_12, V_16, U4_24, 0, 0, 0 },
314  	[INSTR_VRR_0VVU]     = { V_12, V_16, U16_20, 0, 0, 0 },
315  	[INSTR_VRR_RV0UU]    = { R_8, V_12, U4_24, U4_28, 0, 0 },
316  	[INSTR_VRR_VRR]	     = { V_8, R_12, R_16, 0, 0, 0 },
317  	[INSTR_VRR_VV]	     = { V_8, V_12, 0, 0, 0, 0 },
318  	[INSTR_VRR_VV0U]     = { V_8, V_12, U4_32, 0, 0, 0 },
319  	[INSTR_VRR_VV0U0U]   = { V_8, V_12, U4_32, U4_24, 0, 0 },
320  	[INSTR_VRR_VV0U2]    = { V_8, V_12, U4_24, 0, 0, 0 },
321  	[INSTR_VRR_VV0UU2]   = { V_8, V_12, U4_32, U4_28, 0, 0 },
322  	[INSTR_VRR_VV0UUU]   = { V_8, V_12, U4_32, U4_28, U4_24, 0 },
323  	[INSTR_VRR_VVV]	     = { V_8, V_12, V_16, 0, 0, 0 },
324  	[INSTR_VRR_VVV0U]    = { V_8, V_12, V_16, U4_32, 0, 0 },
325  	[INSTR_VRR_VVV0U0]   = { V_8, V_12, V_16, U4_24, 0, 0 },
326  	[INSTR_VRR_VVV0U0U]  = { V_8, V_12, V_16, U4_32, U4_24, 0 },
327  	[INSTR_VRR_VVV0UU]   = { V_8, V_12, V_16, U4_32, U4_28, 0 },
328  	[INSTR_VRR_VVV0UUU]  = { V_8, V_12, V_16, U4_32, U4_28, U4_24 },
329  	[INSTR_VRR_VVV0V]    = { V_8, V_12, V_16, V_32, 0, 0 },
330  	[INSTR_VRR_VVVU0UV]  = { V_8, V_12, V_16, V_32, U4_28, U4_20 },
331  	[INSTR_VRR_VVVU0V]   = { V_8, V_12, V_16, V_32, U4_20, 0 },
332  	[INSTR_VRR_VVVUU0V]  = { V_8, V_12, V_16, V_32, U4_20, U4_24 },
333  	[INSTR_VRS_RRDV]     = { V_32, R_12, D_20, B_16, 0, 0 },
334  	[INSTR_VRS_RVRDU]    = { R_8, V_12, D_20, B_16, U4_32, 0 },
335  	[INSTR_VRS_VRRD]     = { V_8, R_12, D_20, B_16, 0, 0 },
336  	[INSTR_VRS_VRRDU]    = { V_8, R_12, D_20, B_16, U4_32, 0 },
337  	[INSTR_VRS_VVRDU]    = { V_8, V_12, D_20, B_16, U4_32, 0 },
338  	[INSTR_VRV_VVXRDU]   = { V_8, D_20, VX_12, B_16, U4_32, 0 },
339  	[INSTR_VRX_VRRDU]    = { V_8, D_20, X_12, B_16, U4_32, 0 },
340  	[INSTR_VRX_VV]	     = { V_8, V_12, 0, 0, 0, 0 },
341  	[INSTR_VSI_URDV]     = { V_32, D_20, B_16, U8_8, 0, 0 },
342  };
343  
344  static char long_insn_name[][7] = LONG_INSN_INITIALIZER;
345  static struct s390_insn opcode[] = OPCODE_TABLE_INITIALIZER;
346  static struct s390_opcode_offset opcode_offset[] = OPCODE_OFFSET_INITIALIZER;
347  
348  /* Extracts an operand value from an instruction.  */
extract_operand(unsigned char * code,const struct s390_operand * operand)349  static unsigned int extract_operand(unsigned char *code,
350  				    const struct s390_operand *operand)
351  {
352  	unsigned char *cp;
353  	unsigned int val;
354  	int bits;
355  
356  	/* Extract fragments of the operand byte for byte.  */
357  	cp = code + operand->shift / 8;
358  	bits = (operand->shift & 7) + operand->bits;
359  	val = 0;
360  	do {
361  		val <<= 8;
362  		val |= (unsigned int) *cp++;
363  		bits -= 8;
364  	} while (bits > 0);
365  	val >>= -bits;
366  	val &= ((1U << (operand->bits - 1)) << 1) - 1;
367  
368  	/* Check for special long displacement case.  */
369  	if (operand->bits == 20 && operand->shift == 20)
370  		val = (val & 0xff) << 12 | (val & 0xfff00) >> 8;
371  
372  	/* Check for register extensions bits for vector registers. */
373  	if (operand->flags & OPERAND_VR) {
374  		if (operand->shift == 8)
375  			val |= (code[4] & 8) << 1;
376  		else if (operand->shift == 12)
377  			val |= (code[4] & 4) << 2;
378  		else if (operand->shift == 16)
379  			val |= (code[4] & 2) << 3;
380  		else if (operand->shift == 32)
381  			val |= (code[4] & 1) << 4;
382  	}
383  
384  	/* Sign extend value if the operand is signed or pc relative.  */
385  	if ((operand->flags & (OPERAND_SIGNED | OPERAND_PCREL)) &&
386  	    (val & (1U << (operand->bits - 1))))
387  		val |= (-1U << (operand->bits - 1)) << 1;
388  
389  	/* Double value if the operand is pc relative.	*/
390  	if (operand->flags & OPERAND_PCREL)
391  		val <<= 1;
392  
393  	/* Length x in an instructions has real length x + 1.  */
394  	if (operand->flags & OPERAND_LENGTH)
395  		val++;
396  	return val;
397  }
398  
find_insn(unsigned char * code)399  struct s390_insn *find_insn(unsigned char *code)
400  {
401  	struct s390_opcode_offset *entry;
402  	struct s390_insn *insn;
403  	unsigned char opfrag;
404  	int i;
405  
406  	/* Search the opcode offset table to find an entry which
407  	 * matches the beginning of the opcode. If there is no match
408  	 * the last entry will be used, which is the default entry for
409  	 * unknown instructions as well as 1-byte opcode instructions.
410  	 */
411  	for (i = 0; i < ARRAY_SIZE(opcode_offset); i++) {
412  		entry = &opcode_offset[i];
413  		if (entry->opcode == code[0])
414  			break;
415  	}
416  
417  	opfrag = *(code + entry->byte) & entry->mask;
418  
419  	insn = &opcode[entry->offset];
420  	for (i = 0; i < entry->count; i++) {
421  		if (insn->opfrag == opfrag)
422  			return insn;
423  		insn++;
424  	}
425  	return NULL;
426  }
427  
print_insn(char * buffer,unsigned char * code,unsigned long addr)428  static int print_insn(char *buffer, unsigned char *code, unsigned long addr)
429  {
430  	struct s390_insn *insn;
431  	const unsigned char *ops;
432  	const struct s390_operand *operand;
433  	unsigned int value;
434  	char separator;
435  	char *ptr;
436  	int i;
437  
438  	ptr = buffer;
439  	insn = find_insn(code);
440  	if (insn) {
441  		if (insn->zero == 0)
442  			ptr += sprintf(ptr, "%.7s\t",
443  				       long_insn_name[insn->offset]);
444  		else
445  			ptr += sprintf(ptr, "%.5s\t", insn->name);
446  		/* Extract the operands. */
447  		separator = 0;
448  		for (ops = formats[insn->format], i = 0;
449  		     *ops != 0 && i < 6; ops++, i++) {
450  			operand = operands + *ops;
451  			value = extract_operand(code, operand);
452  			if ((operand->flags & OPERAND_INDEX)  && value == 0)
453  				continue;
454  			if ((operand->flags & OPERAND_BASE) &&
455  			    value == 0 && separator == '(') {
456  				separator = ',';
457  				continue;
458  			}
459  			if (separator)
460  				ptr += sprintf(ptr, "%c", separator);
461  			if (operand->flags & OPERAND_GPR)
462  				ptr += sprintf(ptr, "%%r%u", value);
463  			else if (operand->flags & OPERAND_FPR)
464  				ptr += sprintf(ptr, "%%f%u", value);
465  			else if (operand->flags & OPERAND_AR)
466  				ptr += sprintf(ptr, "%%a%u", value);
467  			else if (operand->flags & OPERAND_CR)
468  				ptr += sprintf(ptr, "%%c%u", value);
469  			else if (operand->flags & OPERAND_VR)
470  				ptr += sprintf(ptr, "%%v%u", value);
471  			else if (operand->flags & OPERAND_PCREL) {
472  				void *pcrel = (void *)((int)value + addr);
473  
474  				ptr += sprintf(ptr, "%px", pcrel);
475  			} else if (operand->flags & OPERAND_SIGNED)
476  				ptr += sprintf(ptr, "%i", (int)value);
477  			else
478  				ptr += sprintf(ptr, "%u", value);
479  			if (operand->flags & OPERAND_DISP)
480  				separator = '(';
481  			else if (operand->flags & OPERAND_BASE) {
482  				ptr += sprintf(ptr, ")");
483  				separator = ',';
484  			} else
485  				separator = ',';
486  		}
487  	} else
488  		ptr += sprintf(ptr, "unknown");
489  	return (int) (ptr - buffer);
490  }
491  
copy_from_regs(struct pt_regs * regs,void * dst,void * src,int len)492  static int copy_from_regs(struct pt_regs *regs, void *dst, void *src, int len)
493  {
494  	if (user_mode(regs)) {
495  		if (copy_from_user(dst, (char __user *)src, len))
496  			return -EFAULT;
497  	} else {
498  		if (copy_from_kernel_nofault(dst, src, len))
499  			return -EFAULT;
500  	}
501  	return 0;
502  }
503  
show_code(struct pt_regs * regs)504  void show_code(struct pt_regs *regs)
505  {
506  	char *mode = user_mode(regs) ? "User" : "Krnl";
507  	unsigned char code[64];
508  	char buffer[128], *ptr;
509  	unsigned long addr;
510  	int start, end, opsize, hops, i;
511  
512  	/* Get a snapshot of the 64 bytes surrounding the fault address. */
513  	for (start = 32; start && regs->psw.addr >= 34 - start; start -= 2) {
514  		addr = regs->psw.addr - 34 + start;
515  		if (copy_from_regs(regs, code + start - 2, (void *)addr, 2))
516  			break;
517  	}
518  	for (end = 32; end < 64; end += 2) {
519  		addr = regs->psw.addr + end - 32;
520  		if (copy_from_regs(regs, code + end, (void *)addr, 2))
521  			break;
522  	}
523  	/* Code snapshot usable ? */
524  	if ((regs->psw.addr & 1) || start >= end) {
525  		printk("%s Code: Bad PSW.\n", mode);
526  		return;
527  	}
528  	/* Find a starting point for the disassembly. */
529  	while (start < 32) {
530  		for (i = 0, hops = 0; start + i < 32 && hops < 3; hops++) {
531  			if (!find_insn(code + start + i))
532  				break;
533  			i += insn_length(code[start + i]);
534  		}
535  		if (start + i == 32)
536  			/* Looks good, sequence ends at PSW. */
537  			break;
538  		start += 2;
539  	}
540  	/* Decode the instructions. */
541  	ptr = buffer;
542  	ptr += sprintf(ptr, "%s Code:", mode);
543  	hops = 0;
544  	while (start < end && hops < 8) {
545  		opsize = insn_length(code[start]);
546  		if  (start + opsize == 32)
547  			*ptr++ = '#';
548  		else if (start == 32)
549  			*ptr++ = '>';
550  		else
551  			*ptr++ = ' ';
552  		addr = regs->psw.addr + start - 32;
553  		ptr += sprintf(ptr, "%px: ", (void *)addr);
554  		if (start + opsize >= end)
555  			break;
556  		for (i = 0; i < opsize; i++)
557  			ptr += sprintf(ptr, "%02x", code[start + i]);
558  		*ptr++ = '\t';
559  		if (i < 6)
560  			*ptr++ = '\t';
561  		ptr += print_insn(ptr, code + start, addr);
562  		start += opsize;
563  		pr_cont("%s", buffer);
564  		ptr = buffer;
565  		ptr += sprintf(ptr, "\n          ");
566  		hops++;
567  	}
568  	pr_cont("\n");
569  }
570  
print_fn_code(unsigned char * code,unsigned long len)571  void print_fn_code(unsigned char *code, unsigned long len)
572  {
573  	char buffer[128], *ptr;
574  	int opsize, i;
575  
576  	while (len) {
577  		ptr = buffer;
578  		opsize = insn_length(*code);
579  		if (opsize > len)
580  			break;
581  		ptr += sprintf(ptr, "%px: ", code);
582  		for (i = 0; i < opsize; i++)
583  			ptr += sprintf(ptr, "%02x", code[i]);
584  		*ptr++ = '\t';
585  		if (i < 4)
586  			*ptr++ = '\t';
587  		ptr += print_insn(ptr, code, (unsigned long) code);
588  		*ptr++ = '\n';
589  		*ptr++ = 0;
590  		printk("%s", buffer);
591  		code += opsize;
592  		len -= opsize;
593  	}
594  }
595