1 /*
2  * s390-specific syscalls decoders.
3  *
4  * Copyright (c) 2018 The strace developers.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include "defs.h"
31 
32 #if defined S390 || defined S390X
33 
34 #include <sys/user.h>
35 
36 #include "print_fields.h"
37 
38 #include "xlat/s390_guarded_storage_commands.h"
39 #include "xlat/s390_runtime_instr_commands.h"
40 #include "xlat/s390_sthyi_function_codes.h"
41 
42 /*
43  * Since, for some reason, kernel doesn't expose all these nice constants and
44  * structures in UAPI, we have to re-declare them ourselves.
45  */
46 
47 /**
48  * "The header section is placed at the beginning of the response buffer and
49  * identifies the location and length of all other sections. Valid sections have
50  * nonzero offset values in the header. Each section provides information about
51  * validity of fields within that section."
52  */
53 struct sthyi_hdr {
54 	/**
55 	 * Header Flag Byte 1 - These flag settings indicate the environment
56 	 * that the instruction was executed in and may influence the value of
57 	 * the validity bits. The validity bits, and not these flags, should be
58 	 * used to determine if a field is valid.
59 	 *  - 0x80 - Global Performance Data unavailable
60 	 *  - 0x40 - One or more hypervisor levels below this level does not
61 	 *           support the STHYI instruction. When this flag is set the
62 	 *           value of INFGPDU is not meaningful because the state of the
63 	 *           Global Performance Data setting cannot be determined.
64 	 *  - 0x20 - Virtualization stack is incomplete. This bit indicates one
65 	 *           of two cases:
66 	 *   - One or more hypervisor levels does not support the STHYI
67 	 *     instruction. For this case, INFSTHYI will also be set.
68 	 *   - There were more than three levels of guest/hypervisor information
69 	 *     to report.
70 	 *  - 0x10 - Execution environment is not within a logical partition.
71 	 */
72 	uint8_t  infhflg1;
73 	uint8_t  infhflg2; /**< Header Flag Byte 2 reserved for IBM(R) use */
74 	uint8_t  infhval1; /**< Header Validity Byte 1 reserved for IBM use */
75 	uint8_t  infhval2; /**< Header Validity Byte 2 reserved for IBM use */
76 	char     reserved_1__[3]; /**< Reserved for future IBM use */
77 	uint8_t  infhygct; /**< Count of Hypervisor and Guest Sections */
78 	uint16_t infhtotl; /**< Total length of response buffer */
79 	uint16_t infhdln;  /**< Length of Header Section mapped by INF0HDR */
80 	uint16_t infmoff;  /**< Offset to Machine Section mapped by INF0MAC */
81 	uint16_t infmlen;  /**< Length of Machine Section */
82 	uint16_t infpoff;  /**< Offset to Partition Section mapped by INF0PAR */
83 	uint16_t infplen;  /**< Length of Partition Section */
84 	uint16_t infhoff1; /**< Offset to Hypervisor Section1 mapped by INF0HYP */
85 	uint16_t infhlen1; /**< Length of Hypervisor Section1 */
86 	uint16_t infgoff1; /**< Offset to Guest Section1 mapped by INF0GST */
87 	uint16_t infglen1; /**< Length of Guest Section1 */
88 	uint16_t infhoff2; /**< Offset to Hypervisor Section2 mapped by INF0HYP */
89 	uint16_t infhlen2; /**< Length of Hypervisor Section2 */
90 	uint16_t infgoff2; /**< Offset to Guest Section2 mapped by INF0GST */
91 	uint16_t infglen2; /**< Length of Guest Section2 */
92 	uint16_t infhoff3; /**< Offset to Hypervisor Section3 mapped by INF0HYP */
93 	uint16_t infhlen3; /**< Length of Hypervisor Section3 */
94 	uint16_t infgoff3; /**< Offset to Guest Section3 mapped by INF0GST */
95 	uint16_t infglen3; /**< Length of Guest Section3 */
96 	/* 44 bytes in total */
97 } ATTRIBUTE_PACKED;
98 
99 struct sthyi_machine {
100 	uint8_t  infmflg1; /**< Machine Flag Byte 1 reserved for IBM use */
101 	uint8_t  infmflg2; /**< Machine Flag Byte 2 reserved for IBM use */
102 	/**
103 	 * Machine Validity Byte 1
104 	 *  - 0x80 - Processor Count Validity. When this bit is on, it indicates
105 	 *           that INFMSCPS, INFMDCPS, INFMSIFL, and INFMDIFL contain
106 	 *           valid counts. The validity bit may be off when:
107 	 *   - STHYI support is not available on a lower level hypervisor, or
108 	 *   - Global Performance Data is not enabled.
109 	 *  - 0x40 - Machine ID Validity. This bit being on indicates that a
110 	 *           SYSIB 1.1.1 was obtained from STSI and information reported
111 	 *           in the following fields is valid: INFMTYPE, INFMMANU,
112 	 *           INFMSEQ, and INFMPMAN.
113 	 *  - 0x20 - Machine Name Validity. This bit being on indicates that the
114 	 *           INFMNAME field is valid.
115 	 */
116 	uint8_t  infmval1;
117 	uint8_t  infmval2; /**< Machine Validity Byte 2 reserved for IBM use */
118 	/**
119 	 * Number of shared CPs configured in the machine or in the physical
120 	 * partition if the system is physically partitioned.
121 	 */
122 	uint16_t infmscps;
123 	/**
124 	 * Number of dedicated CPs configured in this machine or in the physical
125 	 * partition if the system is physically partitioned.
126 	 */
127 	uint16_t infmdcps;
128 	/**
129 	 * Number of shared IFLs configured in this machine or in the physical
130 	 * partition if the system is physically partitioned.
131 	 */
132 	uint16_t infmsifl;
133 	/**
134 	 * Number of dedicated IFLs configured in this machine or in the
135 	 * physical partition if the system is physically partitioned.
136 	 */
137 	uint16_t infmdifl;
138 	char     infmname[8];  /**< EBCDIC Machine Name */
139 	char     infmtype[4];  /**< EBCDIC Type */
140 	char     infmmanu[16]; /**< EBCDIC Manufacturer */
141 	char     infmseq[16];  /**< EBCDIC Sequence Code */
142 	char     infmpman[4];  /**< EBCDIC Plant of Manufacture */
143 	/* 60 bytes in total*/
144 } ATTRIBUTE_PACKED;
145 
146 struct sthyi_partition {
147 	/**
148 	 * Partition Flag Byte 1
149 	 *  - 0x80 - Multithreading (MT) is enabled.
150 	 */
151 	uint8_t  infpflg1;
152 	/** Partition Flag Byte 2 reserved for IBM use */
153 	uint8_t  infpflg2;
154 	/**
155 	 * Partition Validity Byte 1
156 	 *  - 0x80 - Processor count validity. This bit being on indicates that
157 	 *           INFPSCPS, INFPDCPS, INFPSIFL, and INFPDIFL contain valid
158 	 *           counts.
159 	 *  - 0x40 - Partition weight-based capped capacity validity. This bit
160 	 *           being on indicates that INFPWBCP and INFPWBIF are valid
161 	 *  - 0x20 - Partition absolute capped capacity validity. This bit being
162 	 *           on indicates that INFPABCP and INFPABIF are valid.
163 	 *  - 0x10 - Partition ID validity. This bit being on indicates that a
164 	 *           SYSIB 2.2.2 was obtained from STSI and information reported
165 	 *           in the following fields is valid: INFPPNUM and INFPPNAM.
166 	 *  - 0x08 - LPAR group absolute capacity capping information validity.
167 	 *           This bit being on indicates that INFPLGNM, INFPLGCP, and
168 	 *           INFPLGIF are valid.
169 	 */
170 	uint8_t  infpval1;
171 	/** Partition Validity Byte 2 reserved for IBM use */
172 	uint8_t  infpval2;
173 	/** Logical partition number */
174 	uint16_t infppnum;
175 	/**
176 	 * Number of shared logical CPs configured for this partition.  Count
177 	 * of cores when MT is enabled.
178 	 */
179 	uint16_t infpscps;
180 	/**
181 	 * Number of dedicated logical CPs configured for this partition.  Count
182 	 * of cores when MT is enabled.
183 	 */
184 	uint16_t infpdcps;
185 	/**
186 	 * Number of shared logical IFLs configured for this partition.  Count
187 	 * of cores when MT is enabled.
188 	 */
189 	uint16_t infpsifl;
190 	/**
191 	 * Number of dedicated logical IFLs configured for this partition.
192 	 * Count of cores when MT is enabled.
193 	 */
194 	uint16_t infpdifl;
195 	/** Reserved for future IBM use */
196 	char     reserved_1__[2];
197 	/** EBCIDIC Logical partition name */
198 	char     infppnam[8];
199 	/**
200 	 * Partition weight-based capped capacity for CPs, a scaled number where
201 	 * 0x00010000 represents one  core.  Zero if not capped.
202 	 */
203 	uint32_t infpwbcp;
204 	/**
205 	 * Partition absolute capped capacity for CPs, a scaled number where
206 	 * 0x00010000 represents one  core.  Zero if not capped.
207 	 */
208 	uint32_t infpabcp;
209 	/**
210 	 * Partition weight-based capped capacity for IFLs, a scaled number
211 	 * where 0x00010000 represents one  core.  Zero if not capped.
212 	 */
213 	uint32_t infpwbif;
214 	/**
215 	 * Partition absolute capped capacity for IFLs, a scaled number where
216 	 * 0x00010000 represents one  core.  Zero if not capped.
217 	 */
218 	uint32_t infpabif;
219 	/**
220 	 * EBCIDIC LPAR group name. Binary zeros when the partition is not in
221 	 * an LPAR group. EBCDIC and padded with blanks on the right when in a
222 	 * group. The group name is reported only when there is a group cap on
223 	 * CP or IFL CPU types and the partition has the capped CPU type.
224 	 */
225 	char     infplgnm[8];
226 	/**
227 	 * LPAR group absolute capacity value for CP CPU type when nonzero. This
228 	 * field will be nonzero only when INFPLGNM is nonzero and a cap is
229 	 * defined for the LPAR group for the CP CPU type. When nonzero,
230 	 * contains a scaled number where 0x00010000 represents one core.
231 	 */
232 	uint32_t infplgcp;
233 	/**
234 	 * LPAR group absolute capacity value for IFL CPU type when nonzero.
235 	 * This field will be nonzero only when INFPLGNM is nonzero and a cap
236 	 * is defined for the LPAR group for the IFL CPU type. When nonzero,
237 	 * contains a scaled number where 0x00010000 represents one core.
238 	 */
239 	uint32_t infplgif;
240 	/* 56 bytes */
241 } ATTRIBUTE_PACKED;
242 
243 struct sthyi_hypervisor {
244 	/**
245 	 * Hypervisor Flag Byte 1
246 	 *  - 0x80 - Guest CPU usage hard limiting is using the consumption
247 	 *           method.
248 	 *  - 0x40 - If on, LIMITHARD caps use prorated core time for capping.
249 	 *           If off, raw CPU time is used.
250 	 */
251 	uint8_t infyflg1;
252 	uint8_t infyflg2; /**< Hypervisor Flag Byte 2 reserved for IBM use */
253 	uint8_t infyval1; /**< Hypervisor Validity Byte 1 reserved for IBM use */
254 	uint8_t infyval2; /**< Hypervisor Validity Byte 2 reserved for IBM use */
255 	/**
256 	 * Hypervisor Type
257 	 *  - 1 - z/VM is the hypervisor.
258 	 */
259 	uint8_t infytype;
260 	char    reserved_1__[1]; /**< Reserved for future IBM use */
261 	/**
262 	 * Threads in use per CP core. Only valid when MT enabled
263 	 * (INFPFLG1 0x80 is ON).
264 	 */
265 	uint8_t infycpt;
266 	/**
267 	 * Threads in use per IFL core. Only valid when MT enabled
268 	 * (INFPFLG1 0x80 is ON).
269 	 */
270 	uint8_t infyiflt;
271 	/**
272 	 * EBCID System Identifier. Left justified and padded with blanks.
273 	 * This field will be blanks if non-existent.
274 	 */
275 	char     infysyid[8];
276 	/**
277 	 * EBCID Cluster Name. Left justified and padded with blanks. This is
278 	 * the name on the SSI statement in the system configuration file. This
279 	 * field will be blanks if nonexistent.
280 	 */
281 	char     infyclnm[8];
282 	/**
283 	 * Total number of CPs shared among guests of this hypervisor.
284 	 * Number of cores when MT enabled.
285 	 */
286 	uint16_t infyscps;
287 	/**
288 	 * Total number of CPs dedicated to guests of this hypervisor.
289 	 * Number of cores when MT enabled.
290 	 */
291 	uint16_t infydcps;
292 	/**
293 	 * Total number of IFLs shared among guests of this hypervisor.
294 	 * Number of cores when MT enabled.
295 	 */
296 	uint16_t infysifl;
297 	/**
298 	 * Total number of IFLs dedicated to guests of this hypervisor.
299 	 * Number of cores when MT enabled.
300 	 */
301 	uint16_t infydifl;
302 	/* 32 bytes */
303 } ATTRIBUTE_PACKED;
304 
305 struct sthyi_guest {
306 	/**
307 	 * Guest Flag Byte 1
308 	 *  - 0x80 - Guest is mobility enabled
309 	 *  - 0x40 - Guest has multiple virtual CPU types
310 	 *  - 0x20 - Guest CP dispatch type has LIMITHARD cap
311 	 *  - 0x10 - Guest IFL dispatch type has LIMITHARD cap
312 	 *  - 0x08 - Virtual CPs are thread dispatched
313 	 *  - 0x04 - Virtual IFLs are thread dispatched
314 	 */
315 	uint8_t  infgflg1;
316 	uint8_t  infgflg2;    /**< Guest Flag Byte 2 reserved for IBM use */
317 	uint8_t  infgval1;    /**< Guest Validity Byte 1 reserved for IBM use */
318 	uint8_t  infgval2;    /**< Guest Validity Byte 2 reserved for IBM use */
319 	char     infgusid[8]; /**< EBCDIC Userid */
320 	uint16_t infgscps;    /**< Number of guest shared CPs */
321 	uint16_t infgdcps;    /**< Number of guest dedicated CPs */
322 	/**
323 	 * Dispatch type for guest CPs.  This field is valid if INFGSCPS or
324 	 * INFGDCPS is greater than zero.
325 	 *  - 0 - General Purpose (CP)
326 	 */
327 	uint8_t  infgcpdt;
328 	char     reserved_1__[3]; /**< Reserved for future IBM use */
329 	/**
330 	 * Guest current capped capacity for shared virtual CPs, a scaled number
331 	 * where 0x00010000 represents one  core.   This field is zero to
332 	 * indicate not capped when:
333 	 *  - There is no CP individual limit (that is, the "Guest CP dispatch
334 	 *    type has LIMITHARD cap" bit in field INFGFLG1 is OFF).
335 	 *  - There are no shared CPs on the system (that is, INFYSCPS = 0).
336 	 *    If there is a CP limit but there are no shared CPs or virtual CPs,
337 	 *    the limit is meaningless and does not apply to anything.
338 	 */
339 	uint32_t infgcpcc;
340 	uint16_t infgsifl; /**< Number of guest shared IFLs */
341 	uint16_t infgdifl; /**< Number of guest dedicated IFLs */
342 	/**
343 	 * Dispatch type for guest IFLs. This field is valid if INFGSIFL or
344 	 * INFGDIFL is greater than zero.
345 	 *  - 0 - General Purpose (CP)
346 	 *  - 3 - Integrated Facility for Linux (IFL)
347 	 */
348 	uint8_t  infgifdt;
349 	char     reserved_2__[3]; /**< Reserved for future IBM use */
350 	/**
351 	 * Guest current capped capacity for shared virtual IFLs,  a scaled
352 	 * number where 0x00010000 represents one core.   This field is zero
353 	 * to indicate not capped with an IFL limit when:
354 	 *  - There is no IFL individual limit (that is, the "Guest IFL dispatch
355 	 *    type has LIMITHARD cap" bit in field INFGFLG1 is OFF).
356 	 *  - The guest's IFLs are dispatched on CPs (that is, INFGIFDT = 00).
357 	 *    When the guest's IFLs are dispatched on CPs, the CP individual
358 	 *    limit (in INFGCPCC) is applied to the guest's virtual IFLs and
359 	 *    virtual CPs.
360 	 */
361 	uint32_t infgifcc;
362 	/**
363 	 * CPU Pool Capping Flags
364 	 *  - 0x80 - CPU Pool's CP virtual type has LIMITHARD cap
365 	 *  - 0x40 - CPU Pool's CP virtual type has CAPACITY cap
366 	 *  - 0x20 - CPU Pool's IFL virtual type has LIMITHARD cap
367 	 *  - 0x10 - CPU Pool's IFL virtual type has CAPACITY cap
368 	 *  - 0x08 - CPU Pool uses prorated core time.
369 	 */
370 	uint8_t  infgpflg;
371 	char     reserved_3__[3]; /**< Reserved for future IBM use */
372 	/**
373 	 * EBCDIC CPU Pool Name. This field will be blanks if the guest is not
374 	 * in a CPU Pool.
375 	 */
376 	char     infgpnam[8];
377 	/**
378 	 * CPU Pool capped capacity for shared virtual CPs, a scaled number
379 	 * where 0x00010000 represents one  core.  This field will be zero if
380 	 * not capped.
381 	 */
382 	uint32_t infgpccc;
383 	/**
384 	 * CPU Pool capped capacity for shared virtual IFLs, a scaled number
385 	 * where 0x00010000 represents one  core.  This field will be zero if
386 	 * not capped.
387 	 */
388 	uint32_t infgpicc;
389 	/* 56 bytes */
390 } ATTRIBUTE_PACKED;
391 
392 
393 static void
decode_ebcdic(const char * ebcdic,char * ascii,size_t size)394 decode_ebcdic(const char *ebcdic, char *ascii, size_t size)
395 {
396 	/*
397 	 * This is mostly Linux's EBCDIC-ASCII conversion table, except for
398 	 * various non-representable characters that are converted to spaces for
399 	 * readability purposes, as it is intended to be a hint for the string
400 	 * contents and not precise conversion.
401 	 */
402 	static char conv_table[] =
403 		 "\0\1\2\3 \11 \177   \13\14\15\16\17"
404 		 "\20\21\22\23 \n\10 \30\31  \34\35\36\37"
405 		 "  \34  \n\27\33     \5\6\7"
406 		 "  \26    \4    \24\25 \32"
407 		 "          " " .<(+|"
408 		 "&         " "!$*);~"
409 		 "-/        " "|,%_>?"
410 		 "         `" ":#@'=\""
411 		 " abcdefghi" "      "
412 		 " jklmnopqr" "      "
413 		 " ~stuvwxyz" "      "
414 		 "^         " "[]    "
415 		 "{ABCDEFGHI" "      "
416 		 "}JKLMNOPQR" "      "
417 		"\\ STUVWXYZ" "      "
418 		 "0123456789" "      ";
419 
420 	while (size--)
421 		*ascii++ = conv_table[(unsigned char) *ebcdic++];
422 }
423 
424 #define DECODE_EBCDIC(ebcdic_, ascii_) \
425 	decode_ebcdic((ebcdic_), (ascii_), \
426 		      sizeof(ebcdic_) + MUST_BE_ARRAY(ebcdic_))
427 #define PRINT_EBCDIC(ebcdic_) \
428 	do { \
429 		char ascii_str[sizeof(ebcdic_) + MUST_BE_ARRAY(ebcdic_)]; \
430 		\
431 		DECODE_EBCDIC(ebcdic_, ascii_str); \
432 		print_quoted_string(ascii_str, sizeof(ascii_str), \
433 				    QUOTE_EMIT_COMMENT); \
434 	} while (0)
435 
436 #define PRINT_FIELD_EBCDIC(prefix_, where_, field_) \
437 	do { \
438 		PRINT_FIELD_HEX_ARRAY(prefix_, where_, field_); \
439 		PRINT_EBCDIC((where_).field_); \
440 	} while (0)
441 
442 #define PRINT_FIELD_WEIGHT(prefix_, where_, field_) \
443 	do { \
444 		PRINT_FIELD_X(prefix_, where_, field_); \
445 		if ((where_).field_) \
446 			tprintf_comment("%u %u/65536 cores", \
447 				(where_).field_ >> 16, \
448 				(where_).field_ & 0xFFFF); \
449 		else \
450 			tprints_comment("unlimited"); \
451 	} while (0)
452 
453 
454 static bool
is_filled(char * ptr,char fill,size_t size)455 is_filled(char *ptr, char fill, size_t size)
456 {
457 	while (size--)
458 		if (*ptr++ != fill)
459 			return false;
460 
461 	return true;
462 }
463 
464 #define IS_ZERO(arr_) \
465 	is_filled(arr_, '\0', sizeof(arr_) + MUST_BE_ARRAY(arr_))
466 #define IS_BLANK(arr_) /* 0x40 is space in EBCDIC */ \
467 	is_filled(arr_, '\x40', sizeof(arr_) + MUST_BE_ARRAY(arr_))
468 
469 #define CHECK_SIZE(hdr_, size_, name_, ...) \
470 	do { \
471 		if ((size_) < sizeof(*(hdr_))) { \
472 			tprintf_comment("Invalid " name_ " with size " \
473 					"%hu < %zu expected", \
474 					##__VA_ARGS__, \
475 					(size_), sizeof(*(hdr_))); \
476 			print_quoted_string((char *) (hdr_), (size_), \
477 					    QUOTE_FORCE_HEX); \
478 			\
479 			return; \
480 		} \
481 	} while (0)
482 
483 #define PRINT_UNKNOWN_TAIL(hdr_, size_) \
484 	do { \
485 		if ((size_) > sizeof(*(hdr_)) && \
486 		    !is_filled((char *) ((hdr_) + 1), '\0', \
487 		               (size_) - sizeof(*(hdr_)))) \
488 			print_quoted_string((char *) ((hdr_) + 1), \
489 					    (size_) - sizeof(*(hdr_)), \
490 					    QUOTE_FORCE_HEX); \
491 	} while (0)
492 
493 static void
print_sthyi_machine(struct tcb * tcp,struct sthyi_machine * hdr,uint16_t size,bool * dummy)494 print_sthyi_machine(struct tcb *tcp, struct sthyi_machine *hdr, uint16_t size,
495 		    bool *dummy)
496 {
497 	int cnt_val, name_val, id_val;
498 
499 	CHECK_SIZE(hdr, size, "machine structure");
500 
501 	tprints("/* machine */ {");
502 	if (!abbrev(tcp)) {
503 		if (hdr->infmflg1) { /* Reserved */
504 			PRINT_FIELD_0X("", *hdr, infmflg1);
505 			tprints(", ");
506 		}
507 		if (hdr->infmflg2) { /* Reserved */
508 			PRINT_FIELD_0X(", ", *hdr, infmflg2);
509 			tprints(", ");
510 		}
511 	}
512 
513 	PRINT_FIELD_0X("", *hdr, infmval1);
514 	cnt_val  = !!(hdr->infmval1 & 0x80);
515 	id_val   = !!(hdr->infmval1 & 0x40);
516 	name_val = !!(hdr->infmval1 & 0x20);
517 
518 	if (!abbrev(tcp)) {
519 		if (hdr->infmval1)
520 			tprintf_comment("processor count validity: %d, "
521 					"machine ID validity: %d, "
522 					"machine name validity: %d%s%#.0x%s",
523 					cnt_val, id_val, name_val,
524 					hdr->infmval1 & 0x1F ? ", " : "",
525 					hdr->infmval1 & 0x1F,
526 					hdr->infmval1 & 0x1F ? " - ???" : "");
527 		if (hdr->infmval2)
528 			PRINT_FIELD_0X(", ", *hdr, infmval2);
529 	}
530 
531 	if (cnt_val || hdr->infmscps)
532 		PRINT_FIELD_U(", ", *hdr, infmscps);
533 	if (cnt_val || hdr->infmdcps)
534 		PRINT_FIELD_U(", ", *hdr, infmdcps);
535 	if (cnt_val || hdr->infmsifl)
536 		PRINT_FIELD_U(", ", *hdr, infmsifl);
537 	if (cnt_val || hdr->infmdifl)
538 		PRINT_FIELD_U(", ", *hdr, infmdifl);
539 
540 	if (!abbrev(tcp)) {
541 		if (name_val || hdr->infmname)
542 			PRINT_FIELD_EBCDIC(", ", *hdr, infmname);
543 
544 		if (id_val || !IS_ZERO(hdr->infmtype))
545 			PRINT_FIELD_EBCDIC(", ", *hdr, infmtype);
546 		if (id_val || !IS_ZERO(hdr->infmmanu))
547 			PRINT_FIELD_EBCDIC(", ", *hdr, infmmanu);
548 		if (id_val || !IS_ZERO(hdr->infmseq))
549 			PRINT_FIELD_EBCDIC(", ", *hdr, infmseq);
550 		if (id_val || !IS_ZERO(hdr->infmpman))
551 			PRINT_FIELD_EBCDIC(", ", *hdr, infmpman);
552 
553 		PRINT_UNKNOWN_TAIL(hdr, size);
554 	} else {
555 		tprints(", ...");
556 	}
557 
558 	tprints("}");
559 }
560 
561 static void
print_sthyi_partition(struct tcb * tcp,struct sthyi_partition * hdr,uint16_t size,bool * mt)562 print_sthyi_partition(struct tcb *tcp, struct sthyi_partition *hdr,
563 		      uint16_t size, bool *mt)
564 {
565 	int cnt_val, wcap_val, acap_val, id_val, lpar_val;
566 
567 	*mt = false;
568 
569 	CHECK_SIZE(hdr, size, "partition structure");
570 
571 	*mt = !!(hdr->infpflg1 & 0x80);
572 
573 	PRINT_FIELD_0X("/* partition */ {", *hdr, infpflg1);
574 	if (!abbrev(tcp) && hdr->infpflg1)
575 		tprintf_comment("%s%s%#.0x%s",
576 			hdr->infpflg1 & 0x80 ?
577 				"0x80 - multithreading is enabled" : "",
578 			(hdr->infpflg1 & 0x80) && (hdr->infpflg1 & 0x7F) ?
579 				", " : "",
580 			hdr->infpflg1 & 0x7F,
581 			hdr->infpflg1 & 0x7F ? " - ???" : "");
582 	if (!abbrev(tcp) && hdr->infpflg2) /* Reserved */
583 		PRINT_FIELD_0X(", ", *hdr, infpflg2);
584 
585 	PRINT_FIELD_0X(", ", *hdr, infpval1);
586 	cnt_val  = !!(hdr->infpval1 & 0x80);
587 	wcap_val = !!(hdr->infpval1 & 0x40);
588 	acap_val = !!(hdr->infpval1 & 0x20);
589 	id_val   = !!(hdr->infpval1 & 0x10);
590 	lpar_val = !!(hdr->infpval1 & 0x08);
591 
592 	if (!abbrev(tcp) && hdr->infpval1)
593 		tprintf_comment("processor count validity: %d, "
594 				"partition weight-based capacity validity: %d, "
595 				"partition absolute capacity validity: %d, "
596 				"partition ID validity: %d, "
597 				"LPAR group absolute capacity capping "
598 				"information validity: %d%s%#.0x%s",
599 				cnt_val, wcap_val, acap_val, id_val, lpar_val,
600 				hdr->infpval1 & 0x07 ? ", " : "",
601 				hdr->infpval1 & 0x07,
602 				hdr->infpval1 & 0x07 ? " - ???" : "");
603 	if (!abbrev(tcp) && hdr->infpval2) /* Reserved */
604 		PRINT_FIELD_0X(", ", *hdr, infpval2);
605 
606 	if (id_val || hdr->infppnum)
607 		PRINT_FIELD_U(", ", *hdr, infppnum);
608 
609 	if (cnt_val || hdr->infpscps)
610 		PRINT_FIELD_U(", ", *hdr, infpscps);
611 	if (cnt_val || hdr->infpdcps)
612 		PRINT_FIELD_U(", ", *hdr, infpdcps);
613 	if (cnt_val || hdr->infpsifl)
614 		PRINT_FIELD_U(", ", *hdr, infpsifl);
615 	if (cnt_val || hdr->infpdifl)
616 		PRINT_FIELD_U(", ", *hdr, infpdifl);
617 
618 	if (!abbrev(tcp) && !IS_ZERO(hdr->reserved_1__))
619 		PRINT_FIELD_HEX_ARRAY(", ", *hdr, reserved_1__);
620 
621 	if (id_val || !IS_ZERO(hdr->infppnam))
622 		PRINT_FIELD_EBCDIC(", ", *hdr, infppnam);
623 
624 	if (!abbrev(tcp)) {
625 		if (wcap_val || hdr->infpwbcp)
626 			PRINT_FIELD_WEIGHT(", ", *hdr, infpwbcp);
627 		if (acap_val || hdr->infpabcp)
628 			PRINT_FIELD_WEIGHT(", ", *hdr, infpabcp);
629 		if (wcap_val || hdr->infpwbif)
630 			PRINT_FIELD_WEIGHT(", ", *hdr, infpwbif);
631 		if (acap_val || hdr->infpabif)
632 			PRINT_FIELD_WEIGHT(", ", *hdr, infpabif);
633 
634 		if (!IS_ZERO(hdr->infplgnm)) {
635 			PRINT_FIELD_EBCDIC(", ", *hdr, infplgnm);
636 
637 			PRINT_FIELD_WEIGHT(", ", *hdr, infplgcp);
638 			PRINT_FIELD_WEIGHT(", ", *hdr, infplgif);
639 		} else {
640 			if (lpar_val)
641 				PRINT_FIELD_HEX_ARRAY(", ", *hdr, infplgnm);
642 			if (hdr->infplgcp)
643 				PRINT_FIELD_X(", ", *hdr, infplgcp);
644 			if (hdr->infplgif)
645 				PRINT_FIELD_X(", ", *hdr, infplgif);
646 		}
647 
648 		PRINT_UNKNOWN_TAIL(hdr, size);
649 	} else {
650 		tprints(", ...");
651 	}
652 
653 	tprints("}");
654 }
655 
656 static void
print_sthyi_hypervisor(struct tcb * tcp,struct sthyi_hypervisor * hdr,uint16_t size,int num,bool mt)657 print_sthyi_hypervisor(struct tcb *tcp, struct sthyi_hypervisor *hdr,
658 		       uint16_t size, int num, bool mt)
659 {
660 	CHECK_SIZE(hdr, size, "hypervisor %d structure", num);
661 
662 	tprintf("/* hypervisor %d */ ", num);
663 	PRINT_FIELD_0X("{", *hdr, infyflg1);
664 	if (!abbrev(tcp) && hdr->infyflg1)
665 		tprintf_comment("%s%s%s%s%#.0x%s",
666 			hdr->infyflg1 & 0x80 ?
667 				"0x80 - guest CPU usage had limiting is using "
668 				"the consumption method" : "",
669 			(hdr->infyflg1 & 0x80) && (hdr->infyflg1 & 0x40) ?
670 				", " : "",
671 			hdr->infyflg1 & 0x40 ?
672 				"0x40 - LIMITHARD caps use prorated core time "
673 				"for capping" : "",
674 			(hdr->infyflg1 & 0xC0) && (hdr->infyflg1 & 0x3F) ?
675 				", " : "",
676 			hdr->infyflg1 & 0x3F,
677 			hdr->infyflg1 & 0x3F ? " - ???" : "");
678 
679 	if (!abbrev(tcp)) {
680 		if (hdr->infyflg2) /* Reserved */
681 			PRINT_FIELD_0X(", ", *hdr, infyflg2);
682 		if (hdr->infyval1) /* Reserved */
683 			PRINT_FIELD_0X(", ", *hdr, infyval1);
684 		if (hdr->infyval2) /* Reserved */
685 			PRINT_FIELD_0X(", ", *hdr, infyval2);
686 
687 		PRINT_FIELD_U(", ", *hdr, infytype);
688 		switch (hdr->infytype) {
689 		case 1:
690 			tprints_comment("z/VM is the hypervisor");
691 			break;
692 		default:
693 			tprints_comment("unknown hypervisor type");
694 		}
695 
696 		if (!IS_ZERO(hdr->reserved_1__))
697 			PRINT_FIELD_HEX_ARRAY(", ", *hdr, reserved_1__);
698 
699 		if (mt || hdr->infycpt)
700 			PRINT_FIELD_U(", ", *hdr, infycpt);
701 		if (mt || hdr->infyiflt)
702 			PRINT_FIELD_U(", ", *hdr, infyiflt);
703 	}
704 
705 	if (!abbrev(tcp) || !IS_BLANK(hdr->infysyid))
706 		PRINT_FIELD_EBCDIC(", ", *hdr, infysyid);
707 	if (!abbrev(tcp) || !IS_BLANK(hdr->infyclnm))
708 		PRINT_FIELD_EBCDIC(", ", *hdr, infyclnm);
709 
710 	if (!abbrev(tcp) || hdr->infyscps)
711 		PRINT_FIELD_U(", ", *hdr, infyscps);
712 	if (!abbrev(tcp) || hdr->infydcps)
713 		PRINT_FIELD_U(", ", *hdr, infydcps);
714 	if (!abbrev(tcp) || hdr->infysifl)
715 		PRINT_FIELD_U(", ", *hdr, infysifl);
716 	if (!abbrev(tcp) || hdr->infydifl)
717 		PRINT_FIELD_U(", ", *hdr, infydifl);
718 
719 	if (!abbrev(tcp)) {
720 		PRINT_UNKNOWN_TAIL(hdr, size);
721 	} else {
722 		tprints(", ...");
723 	}
724 
725 	tprints("}");
726 }
727 
728 static void
print_sthyi_guest(struct tcb * tcp,struct sthyi_guest * hdr,uint16_t size,int num,bool mt)729 print_sthyi_guest(struct tcb *tcp, struct sthyi_guest *hdr, uint16_t size,
730 		  int num, bool mt)
731 {
732 	CHECK_SIZE(hdr, size, "guest %d structure", num);
733 
734 	tprintf("/* guest %d */ ", num);
735 	PRINT_FIELD_0X("{", *hdr, infgflg1);
736 	if (!abbrev(tcp) && hdr->infgflg1)
737 		tprintf_comment("%s%s%s%s%s%s%s%s%s%s%s%s%#.0x%s",
738 			hdr->infgflg1 & 0x80 ?
739 				"0x80 - guest is mobility enabled" : "",
740 			(hdr->infgflg1 & 0x80) && (hdr->infgflg1 & 0x40) ?
741 				", " : "",
742 			hdr->infgflg1 & 0x40 ?
743 				"0x40 - guest has multiple virtual CPU types" :
744 				"",
745 			(hdr->infgflg1 & 0xC0) && (hdr->infgflg1 & 0x20) ?
746 				", " : "",
747 			hdr->infgflg1 & 0x20 ?
748 				"0x20 - guest CP dispatch type has LIMITHARD "
749 				"cap" : "",
750 			(hdr->infgflg1 & 0xE0) && (hdr->infgflg1 & 0x10) ?
751 				", " : "",
752 			hdr->infgflg1 & 0x10 ?
753 				"0x10 - guest IFL dispatch type has LIMITHARD "
754 				"cap" : "",
755 			(hdr->infgflg1 & 0xF0) && (hdr->infgflg1 & 0x08) ?
756 				", " : "",
757 			hdr->infgflg1 & 0x08 ?
758 				"0x08 - virtual CPs are thread dispatched" :
759 				"",
760 			(hdr->infgflg1 & 0xF8) && (hdr->infgflg1 & 0x04) ?
761 				", " : "",
762 			hdr->infgflg1 & 0x04 ?
763 				"0x04 - virtual IFLs are thread dispatched" :
764 				"",
765 			(hdr->infgflg1 & 0xFC) && (hdr->infgflg1 & 0x03) ?
766 				", " : "",
767 			hdr->infgflg1 & 0x03,
768 			hdr->infgflg1 & 0x03 ? " - ???" : "");
769 	if (!abbrev(tcp)) {
770 		if (hdr->infgflg2) /* Reserved */
771 			PRINT_FIELD_0X(", ", *hdr, infgflg2);
772 		if (hdr->infgval1) /* Reserved */
773 			PRINT_FIELD_0X(", ", *hdr, infgval1);
774 		if (hdr->infgval2) /* Reserved */
775 			PRINT_FIELD_0X(", ", *hdr, infgval2);
776 	}
777 
778 	PRINT_FIELD_EBCDIC(", ", *hdr, infgusid);
779 
780 	if (!abbrev(tcp) || hdr->infgscps)
781 		PRINT_FIELD_U(", ", *hdr, infgscps);
782 	if (!abbrev(tcp) || hdr->infgdcps)
783 		PRINT_FIELD_U(", ", *hdr, infgdcps);
784 
785 	if (!abbrev(tcp)) {
786 		PRINT_FIELD_U(", ", *hdr, infgcpdt);
787 		switch (hdr->infgcpdt) {
788 		case 0:
789 			tprints_comment("General Purpose (CP)");
790 			break;
791 		default:
792 			tprints_comment("unknown");
793 		}
794 
795 		if (!IS_ZERO(hdr->reserved_1__))
796 			PRINT_FIELD_HEX_ARRAY(", ", *hdr, reserved_1__);
797 	}
798 
799 	if (!abbrev(tcp) || hdr->infgcpcc)
800 		PRINT_FIELD_WEIGHT(", ", *hdr, infgcpcc);
801 
802 	if (!abbrev(tcp) || hdr->infgsifl)
803 		PRINT_FIELD_U(", ", *hdr, infgsifl);
804 	if (!abbrev(tcp) || hdr->infgdifl)
805 		PRINT_FIELD_U(", ", *hdr, infgdifl);
806 
807 	if (!abbrev(tcp)) {
808 		PRINT_FIELD_U(", ", *hdr, infgifdt);
809 		switch (hdr->infgifdt) {
810 		case 0:
811 			tprints_comment("General Purpose (CP)");
812 			break;
813 		case 3:
814 			tprints_comment("Integrated Facility for Linux (IFL)");
815 			break;
816 		default:
817 			tprints_comment("unknown");
818 		}
819 
820 		if (!IS_ZERO(hdr->reserved_2__))
821 			PRINT_FIELD_HEX_ARRAY(", ", *hdr, reserved_2__);
822 	}
823 
824 	if (!abbrev(tcp) || hdr->infgifcc)
825 		PRINT_FIELD_WEIGHT(", ", *hdr, infgifcc);
826 
827 	PRINT_FIELD_0X(", ", *hdr, infgpflg);
828 	if (!abbrev(tcp) && hdr->infgpflg)
829 		tprintf_comment("%s%s%s%s%s%s%s%s%s%s%#.0x%s",
830 			hdr->infgpflg & 0x80 ?
831 				"0x80 - CPU pool's CP virtual type has "
832 				"LIMITHARD cap" : "",
833 			(hdr->infgpflg & 0x80) && (hdr->infgpflg & 0x40) ?
834 				", " : "",
835 			hdr->infgpflg & 0x40 ?
836 				"0x40 - CPU pool's CP virtual type has "
837 				"CAPACITY cap" : "",
838 			(hdr->infgpflg & 0xC0) && (hdr->infgpflg & 0x20) ?
839 				", " : "",
840 			hdr->infgpflg & 0x20 ?
841 				"0x20 - CPU pool's IFL virtual type has "
842 				"LIMITHARD cap" : "",
843 			(hdr->infgpflg & 0xE0) && (hdr->infgpflg & 0x10) ?
844 				", " : "",
845 			hdr->infgpflg & 0x10 ?
846 				"0x10 - CPU pool's IFL virtual type has "
847 				"CAPACITY cap" : "",
848 			(hdr->infgpflg & 0xF0) && (hdr->infgpflg & 0x08) ?
849 				", " : "",
850 			hdr->infgpflg & 0x08 ?
851 				"0x08 - CPU pool uses prorated core time" : "",
852 			(hdr->infgpflg & 0xF8) && (hdr->infgpflg & 0x07) ?
853 				", " : "",
854 			hdr->infgpflg & 0x07,
855 			hdr->infgpflg & 0x07 ? " - ???" : "");
856 
857 	if (!abbrev(tcp)) {
858 		if (!IS_ZERO(hdr->reserved_3__))
859 			PRINT_FIELD_HEX_ARRAY(", ", *hdr, reserved_3__);
860 
861 		if (!IS_BLANK(hdr->infgpnam))
862 			PRINT_FIELD_EBCDIC(", ", *hdr, infgpnam);
863 
864 		PRINT_FIELD_WEIGHT(", ", *hdr, infgpccc);
865 		PRINT_FIELD_WEIGHT(", ", *hdr, infgpicc);
866 
867 		PRINT_UNKNOWN_TAIL(hdr, size);
868 	} else {
869 		tprints(", ...");
870 	}
871 
872 	tprints("}");
873 }
874 
875 #define STHYI_PRINT_STRUCT(l_, name_) \
876 	do { \
877 		if (hdr->inf ##l_## off && hdr->inf ##l_## off + \
878 		    hdr->inf ##l_## len <= sizeof(data)) { \
879 			tprints(", "); \
880 			print_sthyi_ ##name_(tcp, (struct sthyi_ ##name_ *) \
881 					     (data + hdr->inf ##l_## off), \
882 					     hdr->inf ##l_## len, &mt); \
883 		} \
884 	} while (0)
885 
886 #define STHYI_PRINT_HV_STRUCT(l_, n_, name_) \
887 	do { \
888 		if (hdr->inf ##l_## off ##n_ && hdr->inf ##l_## off ##n_ + \
889 		    hdr->inf ##l_## len ##n_ <= sizeof(data)) { \
890 			tprints(", "); \
891 			print_sthyi_ ##name_(tcp, (struct sthyi_ ##name_ *) \
892 					     (data + hdr->inf ##l_## off ##n_), \
893 					     hdr->inf ##l_## len ##n_, n_, mt); \
894 		} \
895 	} while (0)
896 
897 static void
print_sthyi_buf(struct tcb * tcp,kernel_ulong_t ptr)898 print_sthyi_buf(struct tcb *tcp, kernel_ulong_t ptr)
899 {
900 	char data[PAGE_SIZE];
901 	struct sthyi_hdr *hdr = (struct sthyi_hdr *) data;
902 	bool mt = false;
903 
904 	if (umove_or_printaddr(tcp, ptr, &data))
905 		return;
906 
907 	tprints("{");
908 
909 	/* Header */
910 	PRINT_FIELD_0X("/* header */ {", *hdr, infhflg1);
911 
912 	if (abbrev(tcp)) {
913 		tprints(", ...");
914 		goto sthyi_sections;
915 	}
916 
917 	if (hdr->infhflg1)
918 		tprintf_comment("%s%s%s%s%s%s%s%s%#.0x%s",
919 			hdr->infhflg1 & 0x80 ?
920 				"0x80 - Global Performance Data unavailable" :
921 				"",
922 			(hdr->infhflg1 & 0x80) && (hdr->infhflg1 & 0x40) ?
923 				", " : "",
924 			hdr->infhflg1 & 0x40 ?
925 				"0x40 - One or more hypervisor levels below "
926 				"this level does not support the STHYI "
927 				"instruction" : "",
928 			(hdr->infhflg1 & 0xC0) && (hdr->infhflg1 & 0x20) ?
929 				", " : "",
930 			hdr->infhflg1 & 0x20 ?
931 				"0x20 - Virtualization stack is incomplete" :
932 				"",
933 			(hdr->infhflg1 & 0xE0) && (hdr->infhflg1 & 0x10) ?
934 				", " : "",
935 			hdr->infhflg1 & 0x10 ?
936 				"0x10 - Execution environment is not within "
937 				"a logical partition" : "",
938 			(hdr->infhflg1 & 0xF0) && (hdr->infhflg1 & 0x0F) ?
939 				", " : "",
940 			hdr->infhflg1 & 0x0F,
941 			hdr->infhflg1 & 0x0F ? " - ???" : "");
942 	if (hdr->infhflg2) /* Reserved */
943 		PRINT_FIELD_0X(", ", *hdr, infhflg2);
944 	if (hdr->infhval1) /* Reserved */
945 		PRINT_FIELD_0X(", ", *hdr, infhval1);
946 	if (hdr->infhval2) /* Reserved */
947 		PRINT_FIELD_0X(", ", *hdr, infhval2);
948 
949 	if (!IS_ZERO(hdr->reserved_1__))
950 		PRINT_FIELD_HEX_ARRAY(", ", *hdr, reserved_1__);
951 
952 	PRINT_FIELD_U(", ", *hdr, infhygct);
953 	PRINT_FIELD_U(", ", *hdr, infhtotl);
954 
955 	PRINT_FIELD_U(", ", *hdr, infhdln);
956 	PRINT_FIELD_U(", ", *hdr, infmoff);
957 	PRINT_FIELD_U(", ", *hdr, infmlen);
958 	PRINT_FIELD_U(", ", *hdr, infpoff);
959 	PRINT_FIELD_U(", ", *hdr, infplen);
960 
961 	PRINT_FIELD_U(", ", *hdr, infhoff1);
962 	PRINT_FIELD_U(", ", *hdr, infhlen1);
963 	PRINT_FIELD_U(", ", *hdr, infgoff1);
964 	PRINT_FIELD_U(", ", *hdr, infglen1);
965 	PRINT_FIELD_U(", ", *hdr, infhoff2);
966 	PRINT_FIELD_U(", ", *hdr, infhlen2);
967 	PRINT_FIELD_U(", ", *hdr, infgoff2);
968 	PRINT_FIELD_U(", ", *hdr, infglen2);
969 	PRINT_FIELD_U(", ", *hdr, infhoff3);
970 	PRINT_FIELD_U(", ", *hdr, infhlen3);
971 	PRINT_FIELD_U(", ", *hdr, infgoff3);
972 	PRINT_FIELD_U(", ", *hdr, infglen3);
973 
974 	PRINT_UNKNOWN_TAIL(hdr, hdr->infhdln);
975 
976 sthyi_sections:
977 	tprints("}");
978 
979 	STHYI_PRINT_STRUCT(m, machine);
980 	STHYI_PRINT_STRUCT(p, partition);
981 
982 	STHYI_PRINT_HV_STRUCT(h, 1, hypervisor);
983 	STHYI_PRINT_HV_STRUCT(g, 1, guest);
984 	STHYI_PRINT_HV_STRUCT(h, 2, hypervisor);
985 	STHYI_PRINT_HV_STRUCT(g, 2, guest);
986 	STHYI_PRINT_HV_STRUCT(h, 3, hypervisor);
987 	STHYI_PRINT_HV_STRUCT(g, 3, guest);
988 
989 	tprints("}");
990 }
991 
992 /**
993  * Wrapper for the s390 STHYI instruction that provides hypervisor information.
994  *
995  * See https://www.ibm.com/support/knowledgecenter/SSB27U_6.3.0/com.ibm.zvm.v630.hcpb4/hcpb4sth.htm
996  * for the instruction documentation.
997  *
998  * The difference in the kernel wrapper is that it doesn't require the 4K
999  * alignment for the resp_buffer page (as it just copies from the internal
1000  * cache).
1001  */
SYS_FUNC(s390_sthyi)1002 SYS_FUNC(s390_sthyi)
1003 {
1004 	/* in, function ID from s390_sthyi_function_codes */
1005 	kernel_ulong_t function_code = tcp->u_arg[0];
1006 	/* out, pointer to page-sized buffer */
1007 	kernel_ulong_t resp_buffer_ptr = tcp->u_arg[1];
1008 	/* out, pointer to u64 containing function result */
1009 	kernel_ulong_t return_code_ptr = tcp->u_arg[2];
1010 	/* in, should be 0, at the moment */
1011 	kernel_ulong_t flags = tcp->u_arg[3];
1012 
1013 	if (entering(tcp)) {
1014 		printxval64(s390_sthyi_function_codes, function_code,
1015 			    "STHYI_FC_???");
1016 		tprints(", ");
1017 	} else {
1018 		switch (function_code) {
1019 		case STHYI_FC_CP_IFL_CAP:
1020 			print_sthyi_buf(tcp, resp_buffer_ptr);
1021 			break;
1022 
1023 		default:
1024 			printaddr(resp_buffer_ptr);
1025 		}
1026 
1027 		tprints(", ");
1028 		printnum_int64(tcp, return_code_ptr, "%" PRIu64);
1029 		tprintf(", %#" PRI_klx, flags);
1030 	}
1031 
1032 	return 0;
1033 }
1034 
1035 
1036 /*
1037  * Structures are written based on
1038  * https://www-304.ibm.com/support/docview.wss?uid=isg29c69415c1e82603c852576700058075a&aid=1#page=85
1039  */
1040 
1041 struct guard_storage_control_block {
1042 	uint64_t reserved;
1043 	/**
1044 	 * Guard Storage Designation
1045 	 *  - Bits 0..J, J == 64-GSC - Guard Storage Origin (GSO)
1046 	 *  - Bits 53..55 - Guard Load Shift (GLS)
1047 	 *  - Bits 58..63 - Guard Storage Characteristic (GSC), this is J from
1048 	 *                  the first item, valud values are 25..56.
1049 	 */
1050 	uint64_t gsd;
1051 	uint64_t gssm;     /**< Guard Storage Section Mask */
1052 	uint64_t gs_epl_a; /**< Guard Storage Event Parameter List Address */
1053 };
1054 
1055 struct guard_storage_event_parameter_list {
1056 	uint8_t  pad1;
1057 	/**
1058 	 * Guard Storage Event Addressing Mode
1059 	 *  - 0x40 - Extended addressing mode (E)
1060 	 *  - 0x80 - Basic addressing mode (B)
1061 	 */
1062 	uint8_t  gs_eam;
1063 	/**
1064 	 * Guard Storage Event Cause indication
1065 	 *  - 0x01 - CPU was in transaction execution mode (TX)
1066 	 *  - 0x02 - CPU was in constrained transaction execution mode (CX)
1067 	 *  - 0x80 - Instruction causing the event: 0 - LGG, 1 - LLGFGS
1068 	 */
1069 	uint8_t  gs_eci;
1070 	/**
1071 	 * Guard Storage Event Access Information
1072 	 *  - 0x01 - DAT mode
1073 	 *  - Bits 1..2 - Address space indication
1074 	 *  - Bits 4..7 - AR number
1075 	 */
1076 	uint8_t  gs_eai;
1077 	uint32_t pad2;
1078 	uint64_t gs_eha; /**< Guard Storage Event Handler Address */
1079 	uint64_t gs_eia; /**< Guard Storage Event Instruction Address */
1080 	uint64_t gs_eoa; /**< Guard Storage Event Operation Address */
1081 	uint64_t gs_eir; /**< Guard Storage Event Intermediate Result */
1082 	uint64_t gs_era; /**< Guard Storage Event Return Address */
1083 };
1084 
1085 static void
guard_storage_print_gsepl(struct tcb * tcp,uint64_t addr)1086 guard_storage_print_gsepl(struct tcb *tcp, uint64_t addr)
1087 {
1088 	struct guard_storage_event_parameter_list gsepl;
1089 
1090 	/* Since it is 64-bit even on 31-bit s390... */
1091 	if (sizeof(addr) > current_klongsize &&
1092 	    addr >= (1ULL << (current_klongsize * 8))) {
1093 		tprintf("%#" PRIx64, addr);
1094 
1095 		return;
1096 	}
1097 
1098 	if (umove_or_printaddr(tcp, addr, &gsepl))
1099 		return;
1100 
1101 	tprints("[{");
1102 
1103 	if (!abbrev(tcp)) {
1104 		if (gsepl.pad1) {
1105 			PRINT_FIELD_0X("", gsepl, pad1);
1106 			tprints(", ");
1107 		}
1108 
1109 		PRINT_FIELD_0X("",   gsepl, gs_eam);
1110 		tprintf_comment("extended addressing mode: %u, "
1111 				"basic addressing mode: %u",
1112 				!!(gsepl.gs_eam & 0x2), !!(gsepl.gs_eam & 0x1));
1113 
1114 		PRINT_FIELD_0X(", ", gsepl, gs_eci);
1115 		tprintf_comment("CPU in TX: %u, CPU in CX: %u, instruction: %s",
1116 				!!(gsepl.gs_eci & 0x80),
1117 				!!(gsepl.gs_eci & 0x40),
1118 				gsepl.gs_eci & 0x01 ? "LLGFGS" : "LGG");
1119 
1120 		PRINT_FIELD_0X(", ", gsepl, gs_eai);
1121 		tprintf_comment("DAT: %u, address space indication: %u, "
1122 				"AR number: %u",
1123 				!!(gsepl.gs_eai & 0x40),
1124 				(gsepl.gs_eai >> 4) & 0x3,
1125 				gsepl.gs_eai & 0xF);
1126 
1127 		if (gsepl.pad2)
1128 			PRINT_FIELD_0X(", ", gsepl, pad2);
1129 
1130 		tprints(", ");
1131 	}
1132 
1133 	PRINT_FIELD_X("", gsepl, gs_eha);
1134 
1135 	if (!abbrev(tcp)) {
1136 		PRINT_FIELD_X(", ", gsepl, gs_eia);
1137 		PRINT_FIELD_X(", ", gsepl, gs_eoa);
1138 		PRINT_FIELD_X(", ", gsepl, gs_eir);
1139 		PRINT_FIELD_X(", ", gsepl, gs_era);
1140 	} else {
1141 		tprints(", ...");
1142 	}
1143 
1144 	tprints("}]");
1145 }
1146 
1147 # define DIV_ROUND_UP(x,y) (((x) + ((y) - 1)) / (y))
1148 
1149 static void
guard_storage_print_gscb(struct tcb * tcp,kernel_ulong_t addr)1150 guard_storage_print_gscb(struct tcb *tcp, kernel_ulong_t addr)
1151 {
1152 	struct guard_storage_control_block gscb;
1153 
1154 	if (umove_or_printaddr(tcp, addr, &gscb))
1155 		return;
1156 
1157 	tprints("{");
1158 
1159 	if (gscb.reserved) {
1160 		PRINT_FIELD_0X("", gscb, reserved);
1161 		tprints(", ");
1162 	}
1163 
1164 	PRINT_FIELD_0X("", gscb, gsd);
1165 
1166 	if (!abbrev(tcp)) {
1167 		unsigned int gsc = gscb.gsd & 0x3F;
1168 		bool gsc_valid = gsc >= 25 && gsc <= 56;
1169 		tprintf_comment("GS origin: %#*.*" PRIx64 "%s, "
1170 				"guard load shift: %" PRIu64 ", "
1171 				"GS characteristic: %u",
1172 				gsc_valid ? 2 + DIV_ROUND_UP(64 - gsc, 4) : 0,
1173 				gsc_valid ? DIV_ROUND_UP(64 - gsc, 4) : 0,
1174 				gsc_valid ? gscb.gsd >> gsc : 0,
1175 				gsc_valid ? "" : "[invalid]",
1176 				(gscb.gsd >> 8) & 0x7, gsc);
1177 	}
1178 
1179 	PRINT_FIELD_0X(", ", gscb, gssm);
1180 
1181 	tprints(", gs_epl_a=");
1182 	guard_storage_print_gsepl(tcp, gscb.gs_epl_a);
1183 
1184 	tprints("}");
1185 }
1186 
SYS_FUNC(s390_guarded_storage)1187 SYS_FUNC(s390_guarded_storage)
1188 {
1189 	int command = (int) tcp->u_arg[0];
1190 	kernel_ulong_t gs_cb = tcp->u_arg[1];
1191 
1192 	printxval(s390_guarded_storage_commands, command, "GS_???");
1193 
1194 	switch (command) {
1195 	case GS_ENABLE:
1196 	case GS_DISABLE:
1197 	case GS_CLEAR_BC_CB:
1198 	case GS_BROADCAST:
1199 		break;
1200 
1201 	case GS_SET_BC_CB:
1202 		tprints(", ");
1203 		guard_storage_print_gscb(tcp, gs_cb);
1204 		break;
1205 
1206 	default:
1207 		tprints(", ");
1208 		printaddr(gs_cb);
1209 	}
1210 
1211 	return RVAL_DECODED;
1212 }
1213 
SYS_FUNC(s390_runtime_instr)1214 SYS_FUNC(s390_runtime_instr)
1215 {
1216 	int command = (int) tcp->u_arg[0];
1217 	int signum = (int) tcp->u_arg[1];
1218 
1219 	const char *command_descr =
1220 		xlookup(s390_runtime_instr_commands, command);
1221 
1222 	tprintf("%d", command);
1223 	tprints_comment(command_descr ? command_descr :
1224 			"S390_RUNTIME_INSTR_???");
1225 
1226 	/*
1227 	 * signum is ignored since Linux 4.4, but let's print it for start
1228 	 * command anyway.
1229 	 */
1230 	switch (command) {
1231 	case S390_RUNTIME_INSTR_START:
1232 		tprints(", ");
1233 		tprints(signame(signum));
1234 		break;
1235 
1236 	case S390_RUNTIME_INSTR_STOP:
1237 	default:
1238 		break;
1239 	}
1240 
1241 	return RVAL_DECODED;
1242 }
1243 
SYS_FUNC(s390_pci_mmio_write)1244 SYS_FUNC(s390_pci_mmio_write)
1245 {
1246 	kernel_ulong_t mmio_addr = tcp->u_arg[0];
1247 	kernel_ulong_t user_buf  = tcp->u_arg[1];
1248 	kernel_ulong_t length    = tcp->u_arg[2];
1249 
1250 	tprintf("%#" PRI_klx ", ", mmio_addr);
1251 	printstr_ex(tcp, user_buf, length, QUOTE_FORCE_HEX);
1252 	tprintf(", %" PRI_klu, length);
1253 
1254 	return RVAL_DECODED;
1255 }
1256 
SYS_FUNC(s390_pci_mmio_read)1257 SYS_FUNC(s390_pci_mmio_read)
1258 {
1259 	kernel_ulong_t mmio_addr = tcp->u_arg[0];
1260 	kernel_ulong_t user_buf  = tcp->u_arg[1];
1261 	kernel_ulong_t length    = tcp->u_arg[2];
1262 
1263 	if (entering(tcp)) {
1264 		tprintf("%#" PRI_klx ", ", mmio_addr);
1265 	} else {
1266 		if (!syserror(tcp))
1267 			printstr_ex(tcp, user_buf, length, QUOTE_FORCE_HEX);
1268 		else
1269 			printaddr(user_buf);
1270 
1271 		tprintf(", %" PRI_klu, length);
1272 	}
1273 
1274 	return 0;
1275 }
1276 
1277 #endif /* defined S390 || defined S390X */
1278