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