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