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