]> granicus.if.org Git - strace/blob - s390.c
build: prepare for -Wimplicit-fallthrough=5
[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 static bool
455 is_filled(char *ptr, char fill, size_t size)
456 {
457         while (size--)
458                 if (*ptr++ != fill)
459                         return false;
460
461         return true;
462 }
463
464 #define IS_ZERO(arr_) \
465         is_filled(arr_, '\0', sizeof(arr_) + MUST_BE_ARRAY(arr_))
466 #define IS_BLANK(arr_) /* 0x40 is space in EBCDIC */ \
467         is_filled(arr_, '\x40', sizeof(arr_) + MUST_BE_ARRAY(arr_))
468
469 #define CHECK_SIZE(hdr_, size_, name_, ...) \
470         do { \
471                 if ((size_) < sizeof(*(hdr_))) { \
472                         tprintf_comment("Invalid " name_ " with size " \
473                                         "%hu < %zu expected", \
474                                         ##__VA_ARGS__, \
475                                         (size_), sizeof(*(hdr_))); \
476                         print_quoted_string((char *) (hdr_), (size_), \
477                                             QUOTE_FORCE_HEX); \
478                         \
479                         return; \
480                 } \
481         } while (0)
482
483 #define PRINT_UNKNOWN_TAIL(hdr_, size_) \
484         do { \
485                 if ((size_) > sizeof(*(hdr_)) && \
486                     !is_filled((char *) ((hdr_) + 1), '\0', \
487                                (size_) - sizeof(*(hdr_)))) \
488                         print_quoted_string((char *) ((hdr_) + 1), \
489                                             (size_) - sizeof(*(hdr_)), \
490                                             QUOTE_FORCE_HEX); \
491         } while (0)
492
493 static void
494 print_sthyi_machine(struct tcb *tcp, struct sthyi_machine *hdr, uint16_t size,
495                     bool *dummy)
496 {
497         int cnt_val, name_val, id_val;
498
499         CHECK_SIZE(hdr, size, "machine structure");
500
501         tprints("/* machine */ {");
502         if (!abbrev(tcp)) {
503                 if (hdr->infmflg1) { /* Reserved */
504                         PRINT_FIELD_0X("", *hdr, infmflg1);
505                         tprints(", ");
506                 }
507                 if (hdr->infmflg2) { /* Reserved */
508                         PRINT_FIELD_0X(", ", *hdr, infmflg2);
509                         tprints(", ");
510                 }
511         }
512
513         PRINT_FIELD_0X("", *hdr, infmval1);
514         cnt_val  = !!(hdr->infmval1 & 0x80);
515         id_val   = !!(hdr->infmval1 & 0x40);
516         name_val = !!(hdr->infmval1 & 0x20);
517
518         if (!abbrev(tcp)) {
519                 if (hdr->infmval1)
520                         tprintf_comment("processor count validity: %d, "
521                                         "machine ID validity: %d, "
522                                         "machine name validity: %d%s%#.0x%s",
523                                         cnt_val, id_val, name_val,
524                                         hdr->infmval1 & 0x1F ? ", " : "",
525                                         hdr->infmval1 & 0x1F,
526                                         hdr->infmval1 & 0x1F ? " - ???" : "");
527                 if (hdr->infmval2)
528                         PRINT_FIELD_0X(", ", *hdr, infmval2);
529         }
530
531         if (cnt_val || hdr->infmscps)
532                 PRINT_FIELD_U(", ", *hdr, infmscps);
533         if (cnt_val || hdr->infmdcps)
534                 PRINT_FIELD_U(", ", *hdr, infmdcps);
535         if (cnt_val || hdr->infmsifl)
536                 PRINT_FIELD_U(", ", *hdr, infmsifl);
537         if (cnt_val || hdr->infmdifl)
538                 PRINT_FIELD_U(", ", *hdr, infmdifl);
539
540         if (!abbrev(tcp)) {
541                 if (name_val || hdr->infmname)
542                         PRINT_FIELD_EBCDIC(", ", *hdr, infmname);
543
544                 if (id_val || !IS_ZERO(hdr->infmtype))
545                         PRINT_FIELD_EBCDIC(", ", *hdr, infmtype);
546                 if (id_val || !IS_ZERO(hdr->infmmanu))
547                         PRINT_FIELD_EBCDIC(", ", *hdr, infmmanu);
548                 if (id_val || !IS_ZERO(hdr->infmseq))
549                         PRINT_FIELD_EBCDIC(", ", *hdr, infmseq);
550                 if (id_val || !IS_ZERO(hdr->infmpman))
551                         PRINT_FIELD_EBCDIC(", ", *hdr, infmpman);
552
553                 PRINT_UNKNOWN_TAIL(hdr, size);
554         } else {
555                 tprints(", ...");
556         }
557
558         tprints("}");
559 }
560
561 static void
562 print_sthyi_partition(struct tcb *tcp, struct sthyi_partition *hdr,
563                       uint16_t size, bool *mt)
564 {
565         int cnt_val, wcap_val, acap_val, id_val, lpar_val;
566
567         *mt = false;
568
569         CHECK_SIZE(hdr, size, "partition structure");
570
571         *mt = !!(hdr->infpflg1 & 0x80);
572
573         PRINT_FIELD_0X("/* partition */ {", *hdr, infpflg1);
574         if (!abbrev(tcp) && hdr->infpflg1)
575                 tprintf_comment("%s%s%#.0x%s",
576                         hdr->infpflg1 & 0x80 ?
577                                 "0x80 - multithreading is enabled" : "",
578                         (hdr->infpflg1 & 0x80) && (hdr->infpflg1 & 0x7F) ?
579                                 ", " : "",
580                         hdr->infpflg1 & 0x7F,
581                         hdr->infpflg1 & 0x7F ? " - ???" : "");
582         if (!abbrev(tcp) && hdr->infpflg2) /* Reserved */
583                 PRINT_FIELD_0X(", ", *hdr, infpflg2);
584
585         PRINT_FIELD_0X(", ", *hdr, infpval1);
586         cnt_val  = !!(hdr->infpval1 & 0x80);
587         wcap_val = !!(hdr->infpval1 & 0x40);
588         acap_val = !!(hdr->infpval1 & 0x20);
589         id_val   = !!(hdr->infpval1 & 0x10);
590         lpar_val = !!(hdr->infpval1 & 0x08);
591
592         if (!abbrev(tcp) && hdr->infpval1)
593                 tprintf_comment("processor count validity: %d, "
594                                 "partition weight-based capacity validity: %d, "
595                                 "partition absolute capacity validity: %d, "
596                                 "partition ID validity: %d, "
597                                 "LPAR group absolute capacity capping "
598                                 "information validity: %d%s%#.0x%s",
599                                 cnt_val, wcap_val, acap_val, id_val, lpar_val,
600                                 hdr->infpval1 & 0x07 ? ", " : "",
601                                 hdr->infpval1 & 0x07,
602                                 hdr->infpval1 & 0x07 ? " - ???" : "");
603         if (!abbrev(tcp) && hdr->infpval2) /* Reserved */
604                 PRINT_FIELD_0X(", ", *hdr, infpval2);
605
606         if (id_val || hdr->infppnum)
607                 PRINT_FIELD_U(", ", *hdr, infppnum);
608
609         if (cnt_val || hdr->infpscps)
610                 PRINT_FIELD_U(", ", *hdr, infpscps);
611         if (cnt_val || hdr->infpdcps)
612                 PRINT_FIELD_U(", ", *hdr, infpdcps);
613         if (cnt_val || hdr->infpsifl)
614                 PRINT_FIELD_U(", ", *hdr, infpsifl);
615         if (cnt_val || hdr->infpdifl)
616                 PRINT_FIELD_U(", ", *hdr, infpdifl);
617
618         if (!abbrev(tcp) && !IS_ZERO(hdr->reserved_1__))
619                 PRINT_FIELD_HEX_ARRAY(", ", *hdr, reserved_1__);
620
621         if (id_val || !IS_ZERO(hdr->infppnam))
622                 PRINT_FIELD_EBCDIC(", ", *hdr, infppnam);
623
624         if (!abbrev(tcp)) {
625                 if (wcap_val || hdr->infpwbcp)
626                         PRINT_FIELD_WEIGHT(", ", *hdr, infpwbcp);
627                 if (acap_val || hdr->infpabcp)
628                         PRINT_FIELD_WEIGHT(", ", *hdr, infpabcp);
629                 if (wcap_val || hdr->infpwbif)
630                         PRINT_FIELD_WEIGHT(", ", *hdr, infpwbif);
631                 if (acap_val || hdr->infpabif)
632                         PRINT_FIELD_WEIGHT(", ", *hdr, infpabif);
633
634                 if (!IS_ZERO(hdr->infplgnm)) {
635                         PRINT_FIELD_EBCDIC(", ", *hdr, infplgnm);
636
637                         PRINT_FIELD_WEIGHT(", ", *hdr, infplgcp);
638                         PRINT_FIELD_WEIGHT(", ", *hdr, infplgif);
639                 } else {
640                         if (lpar_val)
641                                 PRINT_FIELD_HEX_ARRAY(", ", *hdr, infplgnm);
642                         if (hdr->infplgcp)
643                                 PRINT_FIELD_X(", ", *hdr, infplgcp);
644                         if (hdr->infplgif)
645                                 PRINT_FIELD_X(", ", *hdr, infplgif);
646                 }
647
648                 PRINT_UNKNOWN_TAIL(hdr, size);
649         } else {
650                 tprints(", ...");
651         }
652
653         tprints("}");
654 }
655
656 static void
657 print_sthyi_hypervisor(struct tcb *tcp, struct sthyi_hypervisor *hdr,
658                        uint16_t size, int num, bool mt)
659 {
660         CHECK_SIZE(hdr, size, "hypervisor %d structure", num);
661
662         tprintf("/* hypervisor %d */ ", num);
663         PRINT_FIELD_0X("{", *hdr, infyflg1);
664         if (!abbrev(tcp) && hdr->infyflg1)
665                 tprintf_comment("%s%s%s%s%#.0x%s",
666                         hdr->infyflg1 & 0x80 ?
667                                 "0x80 - guest CPU usage had limiting is using "
668                                 "the consumption method" : "",
669                         (hdr->infyflg1 & 0x80) && (hdr->infyflg1 & 0x40) ?
670                                 ", " : "",
671                         hdr->infyflg1 & 0x40 ?
672                                 "0x40 - LIMITHARD caps use prorated core time "
673                                 "for capping" : "",
674                         (hdr->infyflg1 & 0xC0) && (hdr->infyflg1 & 0x3F) ?
675                                 ", " : "",
676                         hdr->infyflg1 & 0x3F,
677                         hdr->infyflg1 & 0x3F ? " - ???" : "");
678
679         if (!abbrev(tcp)) {
680                 if (hdr->infyflg2) /* Reserved */
681                         PRINT_FIELD_0X(", ", *hdr, infyflg2);
682                 if (hdr->infyval1) /* Reserved */
683                         PRINT_FIELD_0X(", ", *hdr, infyval1);
684                 if (hdr->infyval2) /* Reserved */
685                         PRINT_FIELD_0X(", ", *hdr, infyval2);
686
687                 PRINT_FIELD_U(", ", *hdr, infytype);
688                 switch (hdr->infytype) {
689                 case 1:
690                         tprints_comment("z/VM is the hypervisor");
691                         break;
692                 default:
693                         tprints_comment("unknown hypervisor type");
694                 }
695
696                 if (!IS_ZERO(hdr->reserved_1__))
697                         PRINT_FIELD_HEX_ARRAY(", ", *hdr, reserved_1__);
698
699                 if (mt || hdr->infycpt)
700                         PRINT_FIELD_U(", ", *hdr, infycpt);
701                 if (mt || hdr->infyiflt)
702                         PRINT_FIELD_U(", ", *hdr, infyiflt);
703         }
704
705         if (!abbrev(tcp) || !IS_BLANK(hdr->infysyid))
706                 PRINT_FIELD_EBCDIC(", ", *hdr, infysyid);
707         if (!abbrev(tcp) || !IS_BLANK(hdr->infyclnm))
708                 PRINT_FIELD_EBCDIC(", ", *hdr, infyclnm);
709
710         if (!abbrev(tcp) || hdr->infyscps)
711                 PRINT_FIELD_U(", ", *hdr, infyscps);
712         if (!abbrev(tcp) || hdr->infydcps)
713                 PRINT_FIELD_U(", ", *hdr, infydcps);
714         if (!abbrev(tcp) || hdr->infysifl)
715                 PRINT_FIELD_U(", ", *hdr, infysifl);
716         if (!abbrev(tcp) || hdr->infydifl)
717                 PRINT_FIELD_U(", ", *hdr, infydifl);
718
719         if (!abbrev(tcp)) {
720                 PRINT_UNKNOWN_TAIL(hdr, size);
721         } else {
722                 tprints(", ...");
723         }
724
725         tprints("}");
726 }
727
728 static void
729 print_sthyi_guest(struct tcb *tcp, struct sthyi_guest *hdr, uint16_t size,
730                   int num, bool mt)
731 {
732         CHECK_SIZE(hdr, size, "guest %d structure", num);
733
734         tprintf("/* guest %d */ ", num);
735         PRINT_FIELD_0X("{", *hdr, infgflg1);
736         if (!abbrev(tcp) && hdr->infgflg1)
737                 tprintf_comment("%s%s%s%s%s%s%s%s%s%s%s%s%#.0x%s",
738                         hdr->infgflg1 & 0x80 ?
739                                 "0x80 - guest is mobility enabled" : "",
740                         (hdr->infgflg1 & 0x80) && (hdr->infgflg1 & 0x40) ?
741                                 ", " : "",
742                         hdr->infgflg1 & 0x40 ?
743                                 "0x40 - guest has multiple virtual CPU types" :
744                                 "",
745                         (hdr->infgflg1 & 0xC0) && (hdr->infgflg1 & 0x20) ?
746                                 ", " : "",
747                         hdr->infgflg1 & 0x20 ?
748                                 "0x20 - guest CP dispatch type has LIMITHARD "
749                                 "cap" : "",
750                         (hdr->infgflg1 & 0xE0) && (hdr->infgflg1 & 0x10) ?
751                                 ", " : "",
752                         hdr->infgflg1 & 0x10 ?
753                                 "0x10 - guest IFL dispatch type has LIMITHARD "
754                                 "cap" : "",
755                         (hdr->infgflg1 & 0xF0) && (hdr->infgflg1 & 0x08) ?
756                                 ", " : "",
757                         hdr->infgflg1 & 0x08 ?
758                                 "0x08 - virtual CPs are thread dispatched" :
759                                 "",
760                         (hdr->infgflg1 & 0xF8) && (hdr->infgflg1 & 0x04) ?
761                                 ", " : "",
762                         hdr->infgflg1 & 0x04 ?
763                                 "0x04 - virtual IFLs are thread dispatched" :
764                                 "",
765                         (hdr->infgflg1 & 0xFC) && (hdr->infgflg1 & 0x03) ?
766                                 ", " : "",
767                         hdr->infgflg1 & 0x03,
768                         hdr->infgflg1 & 0x03 ? " - ???" : "");
769         if (!abbrev(tcp)) {
770                 if (hdr->infgflg2) /* Reserved */
771                         PRINT_FIELD_0X(", ", *hdr, infgflg2);
772                 if (hdr->infgval1) /* Reserved */
773                         PRINT_FIELD_0X(", ", *hdr, infgval1);
774                 if (hdr->infgval2) /* Reserved */
775                         PRINT_FIELD_0X(", ", *hdr, infgval2);
776         }
777
778         PRINT_FIELD_EBCDIC(", ", *hdr, infgusid);
779
780         if (!abbrev(tcp) || hdr->infgscps)
781                 PRINT_FIELD_U(", ", *hdr, infgscps);
782         if (!abbrev(tcp) || hdr->infgdcps)
783                 PRINT_FIELD_U(", ", *hdr, infgdcps);
784
785         if (!abbrev(tcp)) {
786                 PRINT_FIELD_U(", ", *hdr, infgcpdt);
787                 switch (hdr->infgcpdt) {
788                 case 0:
789                         tprints_comment("General Purpose (CP)");
790                         break;
791                 default:
792                         tprints_comment("unknown");
793                 }
794
795                 if (!IS_ZERO(hdr->reserved_1__))
796                         PRINT_FIELD_HEX_ARRAY(", ", *hdr, reserved_1__);
797         }
798
799         if (!abbrev(tcp) || hdr->infgcpcc)
800                 PRINT_FIELD_WEIGHT(", ", *hdr, infgcpcc);
801
802         if (!abbrev(tcp) || hdr->infgsifl)
803                 PRINT_FIELD_U(", ", *hdr, infgsifl);
804         if (!abbrev(tcp) || hdr->infgdifl)
805                 PRINT_FIELD_U(", ", *hdr, infgdifl);
806
807         if (!abbrev(tcp)) {
808                 PRINT_FIELD_U(", ", *hdr, infgifdt);
809                 switch (hdr->infgifdt) {
810                 case 0:
811                         tprints_comment("General Purpose (CP)");
812                         break;
813                 case 3:
814                         tprints_comment("Integrated Facility for Linux (IFL)");
815                         break;
816                 default:
817                         tprints_comment("unknown");
818                 }
819
820                 if (!IS_ZERO(hdr->reserved_2__))
821                         PRINT_FIELD_HEX_ARRAY(", ", *hdr, reserved_2__);
822         }
823
824         if (!abbrev(tcp) || hdr->infgifcc)
825                 PRINT_FIELD_WEIGHT(", ", *hdr, infgifcc);
826
827         PRINT_FIELD_0X(", ", *hdr, infgpflg);
828         if (!abbrev(tcp) && hdr->infgpflg)
829                 tprintf_comment("%s%s%s%s%s%s%s%s%s%s%#.0x%s",
830                         hdr->infgpflg & 0x80 ?
831                                 "0x80 - CPU pool's CP virtual type has "
832                                 "LIMITHARD cap" : "",
833                         (hdr->infgpflg & 0x80) && (hdr->infgpflg & 0x40) ?
834                                 ", " : "",
835                         hdr->infgpflg & 0x40 ?
836                                 "0x40 - CPU pool's CP virtual type has "
837                                 "CAPACITY cap" : "",
838                         (hdr->infgpflg & 0xC0) && (hdr->infgpflg & 0x20) ?
839                                 ", " : "",
840                         hdr->infgpflg & 0x20 ?
841                                 "0x20 - CPU pool's IFL virtual type has "
842                                 "LIMITHARD cap" : "",
843                         (hdr->infgpflg & 0xE0) && (hdr->infgpflg & 0x10) ?
844                                 ", " : "",
845                         hdr->infgpflg & 0x10 ?
846                                 "0x10 - CPU pool's IFL virtual type has "
847                                 "CAPACITY cap" : "",
848                         (hdr->infgpflg & 0xF0) && (hdr->infgpflg & 0x08) ?
849                                 ", " : "",
850                         hdr->infgpflg & 0x08 ?
851                                 "0x08 - CPU pool uses prorated core time" : "",
852                         (hdr->infgpflg & 0xF8) && (hdr->infgpflg & 0x07) ?
853                                 ", " : "",
854                         hdr->infgpflg & 0x07,
855                         hdr->infgpflg & 0x07 ? " - ???" : "");
856
857         if (!abbrev(tcp)) {
858                 if (!IS_ZERO(hdr->reserved_3__))
859                         PRINT_FIELD_HEX_ARRAY(", ", *hdr, reserved_3__);
860
861                 if (!IS_BLANK(hdr->infgpnam))
862                         PRINT_FIELD_EBCDIC(", ", *hdr, infgpnam);
863
864                 PRINT_FIELD_WEIGHT(", ", *hdr, infgpccc);
865                 PRINT_FIELD_WEIGHT(", ", *hdr, infgpicc);
866
867                 PRINT_UNKNOWN_TAIL(hdr, size);
868         } else {
869                 tprints(", ...");
870         }
871
872         tprints("}");
873 }
874
875 #define STHYI_PRINT_STRUCT(l_, name_) \
876         do { \
877                 if (hdr->inf ##l_## off && hdr->inf ##l_## off + \
878                     hdr->inf ##l_## len <= sizeof(data)) { \
879                         tprints(", "); \
880                         print_sthyi_ ##name_(tcp, (struct sthyi_ ##name_ *) \
881                                              (data + hdr->inf ##l_## off), \
882                                              hdr->inf ##l_## len, &mt); \
883                 } \
884         } while (0)
885
886 #define STHYI_PRINT_HV_STRUCT(l_, n_, name_) \
887         do { \
888                 if (hdr->inf ##l_## off ##n_ && hdr->inf ##l_## off ##n_ + \
889                     hdr->inf ##l_## len ##n_ <= sizeof(data)) { \
890                         tprints(", "); \
891                         print_sthyi_ ##name_(tcp, (struct sthyi_ ##name_ *) \
892                                              (data + hdr->inf ##l_## off ##n_), \
893                                              hdr->inf ##l_## len ##n_, n_, mt); \
894                 } \
895         } while (0)
896
897 static void
898 print_sthyi_buf(struct tcb *tcp, kernel_ulong_t ptr)
899 {
900         char data[PAGE_SIZE];
901         struct sthyi_hdr *hdr = (struct sthyi_hdr *) data;
902         bool mt = false;
903
904         if (umove_or_printaddr(tcp, ptr, &data))
905                 return;
906
907         tprints("{");
908
909         /* Header */
910         PRINT_FIELD_0X("/* header */ {", *hdr, infhflg1);
911
912         if (abbrev(tcp)) {
913                 tprints(", ...");
914                 goto sthyi_sections;
915         }
916
917         if (hdr->infhflg1)
918                 tprintf_comment("%s%s%s%s%s%s%s%s%#.0x%s",
919                         hdr->infhflg1 & 0x80 ?
920                                 "0x80 - Global Performance Data unavailable" :
921                                 "",
922                         (hdr->infhflg1 & 0x80) && (hdr->infhflg1 & 0x40) ?
923                                 ", " : "",
924                         hdr->infhflg1 & 0x40 ?
925                                 "0x40 - One or more hypervisor levels below "
926                                 "this level does not support the STHYI "
927                                 "instruction" : "",
928                         (hdr->infhflg1 & 0xC0) && (hdr->infhflg1 & 0x20) ?
929                                 ", " : "",
930                         hdr->infhflg1 & 0x20 ?
931                                 "0x20 - Virtualization stack is incomplete" :
932                                 "",
933                         (hdr->infhflg1 & 0xE0) && (hdr->infhflg1 & 0x10) ?
934                                 ", " : "",
935                         hdr->infhflg1 & 0x10 ?
936                                 "0x10 - Execution environment is not within "
937                                 "a logical partition" : "",
938                         (hdr->infhflg1 & 0xF0) && (hdr->infhflg1 & 0x0F) ?
939                                 ", " : "",
940                         hdr->infhflg1 & 0x0F,
941                         hdr->infhflg1 & 0x0F ? " - ???" : "");
942         if (hdr->infhflg2) /* Reserved */
943                 PRINT_FIELD_0X(", ", *hdr, infhflg2);
944         if (hdr->infhval1) /* Reserved */
945                 PRINT_FIELD_0X(", ", *hdr, infhval1);
946         if (hdr->infhval2) /* Reserved */
947                 PRINT_FIELD_0X(", ", *hdr, infhval2);
948
949         if (!IS_ZERO(hdr->reserved_1__))
950                 PRINT_FIELD_HEX_ARRAY(", ", *hdr, reserved_1__);
951
952         PRINT_FIELD_U(", ", *hdr, infhygct);
953         PRINT_FIELD_U(", ", *hdr, infhtotl);
954
955         PRINT_FIELD_U(", ", *hdr, infhdln);
956         PRINT_FIELD_U(", ", *hdr, infmoff);
957         PRINT_FIELD_U(", ", *hdr, infmlen);
958         PRINT_FIELD_U(", ", *hdr, infpoff);
959         PRINT_FIELD_U(", ", *hdr, infplen);
960
961         PRINT_FIELD_U(", ", *hdr, infhoff1);
962         PRINT_FIELD_U(", ", *hdr, infhlen1);
963         PRINT_FIELD_U(", ", *hdr, infgoff1);
964         PRINT_FIELD_U(", ", *hdr, infglen1);
965         PRINT_FIELD_U(", ", *hdr, infhoff2);
966         PRINT_FIELD_U(", ", *hdr, infhlen2);
967         PRINT_FIELD_U(", ", *hdr, infgoff2);
968         PRINT_FIELD_U(", ", *hdr, infglen2);
969         PRINT_FIELD_U(", ", *hdr, infhoff3);
970         PRINT_FIELD_U(", ", *hdr, infhlen3);
971         PRINT_FIELD_U(", ", *hdr, infgoff3);
972         PRINT_FIELD_U(", ", *hdr, infglen3);
973
974         PRINT_UNKNOWN_TAIL(hdr, hdr->infhdln);
975
976 sthyi_sections:
977         tprints("}");
978
979         STHYI_PRINT_STRUCT(m, machine);
980         STHYI_PRINT_STRUCT(p, partition);
981
982         STHYI_PRINT_HV_STRUCT(h, 1, hypervisor);
983         STHYI_PRINT_HV_STRUCT(g, 1, guest);
984         STHYI_PRINT_HV_STRUCT(h, 2, hypervisor);
985         STHYI_PRINT_HV_STRUCT(g, 2, guest);
986         STHYI_PRINT_HV_STRUCT(h, 3, hypervisor);
987         STHYI_PRINT_HV_STRUCT(g, 3, guest);
988
989         tprints("}");
990 }
991
992 /**
993  * Wrapper for the s390 STHYI instruction that provides hypervisor information.
994  *
995  * See https://www.ibm.com/support/knowledgecenter/SSB27U_6.3.0/com.ibm.zvm.v630.hcpb4/hcpb4sth.htm
996  * for the instruction documentation.
997  *
998  * The difference in the kernel wrapper is that it doesn't require the 4K
999  * alignment for the resp_buffer page (as it just copies from the internal
1000  * cache).
1001  */
1002 SYS_FUNC(s390_sthyi)
1003 {
1004         /* in, function ID from s390_sthyi_function_codes */
1005         kernel_ulong_t function_code = tcp->u_arg[0];
1006         /* out, pointer to page-sized buffer */
1007         kernel_ulong_t resp_buffer_ptr = tcp->u_arg[1];
1008         /* out, pointer to u64 containing function result */
1009         kernel_ulong_t return_code_ptr = tcp->u_arg[2];
1010         /* in, should be 0, at the moment */
1011         kernel_ulong_t flags = tcp->u_arg[3];
1012
1013         if (entering(tcp)) {
1014                 printxval64(s390_sthyi_function_codes, function_code,
1015                             "STHYI_FC_???");
1016                 tprints(", ");
1017         } else {
1018                 switch (function_code) {
1019                 case STHYI_FC_CP_IFL_CAP:
1020                         print_sthyi_buf(tcp, resp_buffer_ptr);
1021                         break;
1022
1023                 default:
1024                         printaddr(resp_buffer_ptr);
1025                 }
1026
1027                 tprints(", ");
1028                 printnum_int64(tcp, return_code_ptr, "%" PRIu64);
1029                 tprintf(", %#" PRI_klx, flags);
1030         }
1031
1032         return 0;
1033 }
1034
1035
1036 /*
1037  * Structures are written based on
1038  * https://www-304.ibm.com/support/docview.wss?uid=isg29c69415c1e82603c852576700058075a&aid=1#page=85
1039  */
1040
1041 struct guard_storage_control_block {
1042         uint64_t reserved;
1043         /**
1044          * Guard Storage Designation
1045          *  - Bits 0..J, J == 64-GSC - Guard Storage Origin (GSO)
1046          *  - Bits 53..55 - Guard Load Shift (GLS)
1047          *  - Bits 58..63 - Guard Storage Characteristic (GSC), this is J from
1048          *                  the first item, valud values are 25..56.
1049          */
1050         uint64_t gsd;
1051         uint64_t gssm;     /**< Guard Storage Section Mask */
1052         uint64_t gs_epl_a; /**< Guard Storage Event Parameter List Address */
1053 };
1054
1055 struct guard_storage_event_parameter_list {
1056         uint8_t  pad1;
1057         /**
1058          * Guard Storage Event Addressing Mode
1059          *  - 0x40 - Extended addressing mode (E)
1060          *  - 0x80 - Basic addressing mode (B)
1061          */
1062         uint8_t  gs_eam;
1063         /**
1064          * Guard Storage Event Cause indication
1065          *  - 0x01 - CPU was in transaction execution mode (TX)
1066          *  - 0x02 - CPU was in constrained transaction execution mode (CX)
1067          *  - 0x80 - Instruction causing the event: 0 - LGG, 1 - LLGFGS
1068          */
1069         uint8_t  gs_eci;
1070         /**
1071          * Guard Storage Event Access Information
1072          *  - 0x01 - DAT mode
1073          *  - Bits 1..2 - Address space indication
1074          *  - Bits 4..7 - AR number
1075          */
1076         uint8_t  gs_eai;
1077         uint32_t pad2;
1078         uint64_t gs_eha; /**< Guard Storage Event Handler Address */
1079         uint64_t gs_eia; /**< Guard Storage Event Instruction Address */
1080         uint64_t gs_eoa; /**< Guard Storage Event Operation Address */
1081         uint64_t gs_eir; /**< Guard Storage Event Intermediate Result */
1082         uint64_t gs_era; /**< Guard Storage Event Return Address */
1083 };
1084
1085 static void
1086 guard_storage_print_gsepl(struct tcb *tcp, uint64_t addr)
1087 {
1088         struct guard_storage_event_parameter_list gsepl;
1089
1090         /* Since it is 64-bit even on 31-bit s390... */
1091         if (sizeof(addr) > current_klongsize &&
1092             addr >= (1ULL << (current_klongsize * 8))) {
1093                 tprintf("%#" PRIx64, addr);
1094
1095                 return;
1096         }
1097
1098         if (umove_or_printaddr(tcp, addr, &gsepl))
1099                 return;
1100
1101         tprints("[{");
1102
1103         if (!abbrev(tcp)) {
1104                 if (gsepl.pad1) {
1105                         PRINT_FIELD_0X("", gsepl, pad1);
1106                         tprints(", ");
1107                 }
1108
1109                 PRINT_FIELD_0X("",   gsepl, gs_eam);
1110                 tprintf_comment("extended addressing mode: %u, "
1111                                 "basic addressing mode: %u",
1112                                 !!(gsepl.gs_eam & 0x2), !!(gsepl.gs_eam & 0x1));
1113
1114                 PRINT_FIELD_0X(", ", gsepl, gs_eci);
1115                 tprintf_comment("CPU in TX: %u, CPU in CX: %u, instruction: %s",
1116                                 !!(gsepl.gs_eci & 0x80),
1117                                 !!(gsepl.gs_eci & 0x40),
1118                                 gsepl.gs_eci & 0x01 ? "LLGFGS" : "LGG");
1119
1120                 PRINT_FIELD_0X(", ", gsepl, gs_eai);
1121                 tprintf_comment("DAT: %u, address space indication: %u, "
1122                                 "AR number: %u",
1123                                 !!(gsepl.gs_eai & 0x40),
1124                                 (gsepl.gs_eai >> 4) & 0x3,
1125                                 gsepl.gs_eai & 0xF);
1126
1127                 if (gsepl.pad2)
1128                         PRINT_FIELD_0X(", ", gsepl, pad2);
1129
1130                 tprints(", ");
1131         }
1132
1133         PRINT_FIELD_X("", gsepl, gs_eha);
1134
1135         if (!abbrev(tcp)) {
1136                 PRINT_FIELD_X(", ", gsepl, gs_eia);
1137                 PRINT_FIELD_X(", ", gsepl, gs_eoa);
1138                 PRINT_FIELD_X(", ", gsepl, gs_eir);
1139                 PRINT_FIELD_X(", ", gsepl, gs_era);
1140         } else {
1141                 tprints(", ...");
1142         }
1143
1144         tprints("}]");
1145 }
1146
1147 # define DIV_ROUND_UP(x,y) (((x) + ((y) - 1)) / (y))
1148
1149 static void
1150 guard_storage_print_gscb(struct tcb *tcp, kernel_ulong_t addr)
1151 {
1152         struct guard_storage_control_block gscb;
1153
1154         if (umove_or_printaddr(tcp, addr, &gscb))
1155                 return;
1156
1157         tprints("{");
1158
1159         if (gscb.reserved) {
1160                 PRINT_FIELD_0X("", gscb, reserved);
1161                 tprints(", ");
1162         }
1163
1164         PRINT_FIELD_0X("", gscb, gsd);
1165
1166         if (!abbrev(tcp)) {
1167                 unsigned int gsc = gscb.gsd & 0x3F;
1168                 bool gsc_valid = gsc >= 25 && gsc <= 56;
1169                 tprintf_comment("GS origin: %#*.*" PRIx64 "%s, "
1170                                 "guard load shift: %" PRIu64 ", "
1171                                 "GS characteristic: %u",
1172                                 gsc_valid ? 2 + DIV_ROUND_UP(64 - gsc, 4) : 0,
1173                                 gsc_valid ? DIV_ROUND_UP(64 - gsc, 4) : 0,
1174                                 gsc_valid ? gscb.gsd >> gsc : 0,
1175                                 gsc_valid ? "" : "[invalid]",
1176                                 (gscb.gsd >> 8) & 0x7, gsc);
1177         }
1178
1179         PRINT_FIELD_0X(", ", gscb, gssm);
1180
1181         tprints(", gs_epl_a=");
1182         guard_storage_print_gsepl(tcp, gscb.gs_epl_a);
1183
1184         tprints("}");
1185 }
1186
1187 SYS_FUNC(s390_guarded_storage)
1188 {
1189         int command = (int) tcp->u_arg[0];
1190         kernel_ulong_t gs_cb = tcp->u_arg[1];
1191
1192         printxval(s390_guarded_storage_commands, command, "GS_???");
1193
1194         switch (command) {
1195         case GS_ENABLE:
1196         case GS_DISABLE:
1197         case GS_CLEAR_BC_CB:
1198         case GS_BROADCAST:
1199                 break;
1200
1201         case GS_SET_BC_CB:
1202                 tprints(", ");
1203                 guard_storage_print_gscb(tcp, gs_cb);
1204                 break;
1205
1206         default:
1207                 tprints(", ");
1208                 printaddr(gs_cb);
1209         }
1210
1211         return RVAL_DECODED;
1212 }
1213
1214 SYS_FUNC(s390_runtime_instr)
1215 {
1216         int command = (int) tcp->u_arg[0];
1217         int signum = (int) tcp->u_arg[1];
1218
1219         const char *command_descr =
1220                 xlookup(s390_runtime_instr_commands, command);
1221
1222         tprintf("%d", command);
1223         tprints_comment(command_descr ? command_descr :
1224                         "S390_RUNTIME_INSTR_???");
1225
1226         /*
1227          * signum is ignored since Linux 4.4, but let's print it for start
1228          * command anyway.
1229          */
1230         switch (command) {
1231         case S390_RUNTIME_INSTR_START:
1232                 tprints(", ");
1233                 tprints(signame(signum));
1234                 break;
1235
1236         case S390_RUNTIME_INSTR_STOP:
1237         default:
1238                 break;
1239         }
1240
1241         return RVAL_DECODED;
1242 }
1243
1244 SYS_FUNC(s390_pci_mmio_write)
1245 {
1246         kernel_ulong_t mmio_addr = tcp->u_arg[0];
1247         kernel_ulong_t user_buf  = tcp->u_arg[1];
1248         kernel_ulong_t length    = tcp->u_arg[2];
1249
1250         tprintf("%#" PRI_klx ", ", mmio_addr);
1251         printstr_ex(tcp, user_buf, length, QUOTE_FORCE_HEX);
1252         tprintf(", %" PRI_klu, length);
1253
1254         return RVAL_DECODED;
1255 }
1256
1257 SYS_FUNC(s390_pci_mmio_read)
1258 {
1259         kernel_ulong_t mmio_addr = tcp->u_arg[0];
1260         kernel_ulong_t user_buf  = tcp->u_arg[1];
1261         kernel_ulong_t length    = tcp->u_arg[2];
1262
1263         if (entering(tcp)) {
1264                 tprintf("%#" PRI_klx ", ", mmio_addr);
1265         } else {
1266                 if (!syserror(tcp))
1267                         printstr_ex(tcp, user_buf, length, QUOTE_FORCE_HEX);
1268                 else
1269                         printaddr(user_buf);
1270
1271                 tprintf(", %" PRI_klu, length);
1272         }
1273
1274         return 0;
1275 }
1276
1277 #endif /* defined S390 || defined S390X */