1 /*
2 * s390-specific syscalls decoders.
3 *
4 * Copyright (c) 2018 The strace developers.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include "defs.h"
31
32 #if defined S390 || defined S390X
33
34 #include <sys/user.h>
35
36 #include "print_fields.h"
37
38 #include "xlat/s390_guarded_storage_commands.h"
39 #include "xlat/s390_runtime_instr_commands.h"
40 #include "xlat/s390_sthyi_function_codes.h"
41
42 /*
43 * Since, for some reason, kernel doesn't expose all these nice constants and
44 * structures in UAPI, we have to re-declare them ourselves.
45 */
46
47 /**
48 * "The header section is placed at the beginning of the response buffer and
49 * identifies the location and length of all other sections. Valid sections have
50 * nonzero offset values in the header. Each section provides information about
51 * validity of fields within that section."
52 */
53 struct sthyi_hdr {
54 /**
55 * Header Flag Byte 1 - These flag settings indicate the environment
56 * that the instruction was executed in and may influence the value of
57 * the validity bits. The validity bits, and not these flags, should be
58 * used to determine if a field is valid.
59 * - 0x80 - Global Performance Data unavailable
60 * - 0x40 - One or more hypervisor levels below this level does not
61 * support the STHYI instruction. When this flag is set the
62 * value of INFGPDU is not meaningful because the state of the
63 * Global Performance Data setting cannot be determined.
64 * - 0x20 - Virtualization stack is incomplete. This bit indicates one
65 * of two cases:
66 * - One or more hypervisor levels does not support the STHYI
67 * instruction. For this case, INFSTHYI will also be set.
68 * - There were more than three levels of guest/hypervisor information
69 * to report.
70 * - 0x10 - Execution environment is not within a logical partition.
71 */
72 uint8_t infhflg1;
73 uint8_t infhflg2; /**< Header Flag Byte 2 reserved for IBM(R) use */
74 uint8_t infhval1; /**< Header Validity Byte 1 reserved for IBM use */
75 uint8_t infhval2; /**< Header Validity Byte 2 reserved for IBM use */
76 char reserved_1__[3]; /**< Reserved for future IBM use */
77 uint8_t infhygct; /**< Count of Hypervisor and Guest Sections */
78 uint16_t infhtotl; /**< Total length of response buffer */
79 uint16_t infhdln; /**< Length of Header Section mapped by INF0HDR */
80 uint16_t infmoff; /**< Offset to Machine Section mapped by INF0MAC */
81 uint16_t infmlen; /**< Length of Machine Section */
82 uint16_t infpoff; /**< Offset to Partition Section mapped by INF0PAR */
83 uint16_t infplen; /**< Length of Partition Section */
84 uint16_t infhoff1; /**< Offset to Hypervisor Section1 mapped by INF0HYP */
85 uint16_t infhlen1; /**< Length of Hypervisor Section1 */
86 uint16_t infgoff1; /**< Offset to Guest Section1 mapped by INF0GST */
87 uint16_t infglen1; /**< Length of Guest Section1 */
88 uint16_t infhoff2; /**< Offset to Hypervisor Section2 mapped by INF0HYP */
89 uint16_t infhlen2; /**< Length of Hypervisor Section2 */
90 uint16_t infgoff2; /**< Offset to Guest Section2 mapped by INF0GST */
91 uint16_t infglen2; /**< Length of Guest Section2 */
92 uint16_t infhoff3; /**< Offset to Hypervisor Section3 mapped by INF0HYP */
93 uint16_t infhlen3; /**< Length of Hypervisor Section3 */
94 uint16_t infgoff3; /**< Offset to Guest Section3 mapped by INF0GST */
95 uint16_t infglen3; /**< Length of Guest Section3 */
96 /* 44 bytes in total */
97 } ATTRIBUTE_PACKED;
98
99 struct sthyi_machine {
100 uint8_t infmflg1; /**< Machine Flag Byte 1 reserved for IBM use */
101 uint8_t infmflg2; /**< Machine Flag Byte 2 reserved for IBM use */
102 /**
103 * Machine Validity Byte 1
104 * - 0x80 - Processor Count Validity. When this bit is on, it indicates
105 * that INFMSCPS, INFMDCPS, INFMSIFL, and INFMDIFL contain
106 * valid counts. The validity bit may be off when:
107 * - STHYI support is not available on a lower level hypervisor, or
108 * - Global Performance Data is not enabled.
109 * - 0x40 - Machine ID Validity. This bit being on indicates that a
110 * SYSIB 1.1.1 was obtained from STSI and information reported
111 * in the following fields is valid: INFMTYPE, INFMMANU,
112 * INFMSEQ, and INFMPMAN.
113 * - 0x20 - Machine Name Validity. This bit being on indicates that the
114 * INFMNAME field is valid.
115 */
116 uint8_t infmval1;
117 uint8_t infmval2; /**< Machine Validity Byte 2 reserved for IBM use */
118 /**
119 * Number of shared CPs configured in the machine or in the physical
120 * partition if the system is physically partitioned.
121 */
122 uint16_t infmscps;
123 /**
124 * Number of dedicated CPs configured in this machine or in the physical
125 * partition if the system is physically partitioned.
126 */
127 uint16_t infmdcps;
128 /**
129 * Number of shared IFLs configured in this machine or in the physical
130 * partition if the system is physically partitioned.
131 */
132 uint16_t infmsifl;
133 /**
134 * Number of dedicated IFLs configured in this machine or in the
135 * physical partition if the system is physically partitioned.
136 */
137 uint16_t infmdifl;
138 char infmname[8]; /**< EBCDIC Machine Name */
139 char infmtype[4]; /**< EBCDIC Type */
140 char infmmanu[16]; /**< EBCDIC Manufacturer */
141 char infmseq[16]; /**< EBCDIC Sequence Code */
142 char infmpman[4]; /**< EBCDIC Plant of Manufacture */
143 /* 60 bytes in total*/
144 } ATTRIBUTE_PACKED;
145
146 struct sthyi_partition {
147 /**
148 * Partition Flag Byte 1
149 * - 0x80 - Multithreading (MT) is enabled.
150 */
151 uint8_t infpflg1;
152 /** Partition Flag Byte 2 reserved for IBM use */
153 uint8_t infpflg2;
154 /**
155 * Partition Validity Byte 1
156 * - 0x80 - Processor count validity. This bit being on indicates that
157 * INFPSCPS, INFPDCPS, INFPSIFL, and INFPDIFL contain valid
158 * counts.
159 * - 0x40 - Partition weight-based capped capacity validity. This bit
160 * being on indicates that INFPWBCP and INFPWBIF are valid
161 * - 0x20 - Partition absolute capped capacity validity. This bit being
162 * on indicates that INFPABCP and INFPABIF are valid.
163 * - 0x10 - Partition ID validity. This bit being on indicates that a
164 * SYSIB 2.2.2 was obtained from STSI and information reported
165 * in the following fields is valid: INFPPNUM and INFPPNAM.
166 * - 0x08 - LPAR group absolute capacity capping information validity.
167 * This bit being on indicates that INFPLGNM, INFPLGCP, and
168 * INFPLGIF are valid.
169 */
170 uint8_t infpval1;
171 /** Partition Validity Byte 2 reserved for IBM use */
172 uint8_t infpval2;
173 /** Logical partition number */
174 uint16_t infppnum;
175 /**
176 * Number of shared logical CPs configured for this partition. Count
177 * of cores when MT is enabled.
178 */
179 uint16_t infpscps;
180 /**
181 * Number of dedicated logical CPs configured for this partition. Count
182 * of cores when MT is enabled.
183 */
184 uint16_t infpdcps;
185 /**
186 * Number of shared logical IFLs configured for this partition. Count
187 * of cores when MT is enabled.
188 */
189 uint16_t infpsifl;
190 /**
191 * Number of dedicated logical IFLs configured for this partition.
192 * Count of cores when MT is enabled.
193 */
194 uint16_t infpdifl;
195 /** Reserved for future IBM use */
196 char reserved_1__[2];
197 /** EBCIDIC Logical partition name */
198 char infppnam[8];
199 /**
200 * Partition weight-based capped capacity for CPs, a scaled number where
201 * 0x00010000 represents one core. Zero if not capped.
202 */
203 uint32_t infpwbcp;
204 /**
205 * Partition absolute capped capacity for CPs, a scaled number where
206 * 0x00010000 represents one core. Zero if not capped.
207 */
208 uint32_t infpabcp;
209 /**
210 * Partition weight-based capped capacity for IFLs, a scaled number
211 * where 0x00010000 represents one core. Zero if not capped.
212 */
213 uint32_t infpwbif;
214 /**
215 * Partition absolute capped capacity for IFLs, a scaled number where
216 * 0x00010000 represents one core. Zero if not capped.
217 */
218 uint32_t infpabif;
219 /**
220 * EBCIDIC LPAR group name. Binary zeros when the partition is not in
221 * an LPAR group. EBCDIC and padded with blanks on the right when in a
222 * group. The group name is reported only when there is a group cap on
223 * CP or IFL CPU types and the partition has the capped CPU type.
224 */
225 char infplgnm[8];
226 /**
227 * LPAR group absolute capacity value for CP CPU type when nonzero. This
228 * field will be nonzero only when INFPLGNM is nonzero and a cap is
229 * defined for the LPAR group for the CP CPU type. When nonzero,
230 * contains a scaled number where 0x00010000 represents one core.
231 */
232 uint32_t infplgcp;
233 /**
234 * LPAR group absolute capacity value for IFL CPU type when nonzero.
235 * This field will be nonzero only when INFPLGNM is nonzero and a cap
236 * is defined for the LPAR group for the IFL CPU type. When nonzero,
237 * contains a scaled number where 0x00010000 represents one core.
238 */
239 uint32_t infplgif;
240 /* 56 bytes */
241 } ATTRIBUTE_PACKED;
242
243 struct sthyi_hypervisor {
244 /**
245 * Hypervisor Flag Byte 1
246 * - 0x80 - Guest CPU usage hard limiting is using the consumption
247 * method.
248 * - 0x40 - If on, LIMITHARD caps use prorated core time for capping.
249 * If off, raw CPU time is used.
250 */
251 uint8_t infyflg1;
252 uint8_t infyflg2; /**< Hypervisor Flag Byte 2 reserved for IBM use */
253 uint8_t infyval1; /**< Hypervisor Validity Byte 1 reserved for IBM use */
254 uint8_t infyval2; /**< Hypervisor Validity Byte 2 reserved for IBM use */
255 /**
256 * Hypervisor Type
257 * - 1 - z/VM is the hypervisor.
258 */
259 uint8_t infytype;
260 char reserved_1__[1]; /**< Reserved for future IBM use */
261 /**
262 * Threads in use per CP core. Only valid when MT enabled
263 * (INFPFLG1 0x80 is ON).
264 */
265 uint8_t infycpt;
266 /**
267 * Threads in use per IFL core. Only valid when MT enabled
268 * (INFPFLG1 0x80 is ON).
269 */
270 uint8_t infyiflt;
271 /**
272 * EBCID System Identifier. Left justified and padded with blanks.
273 * This field will be blanks if non-existent.
274 */
275 char infysyid[8];
276 /**
277 * EBCID Cluster Name. Left justified and padded with blanks. This is
278 * the name on the SSI statement in the system configuration file. This
279 * field will be blanks if nonexistent.
280 */
281 char infyclnm[8];
282 /**
283 * Total number of CPs shared among guests of this hypervisor.
284 * Number of cores when MT enabled.
285 */
286 uint16_t infyscps;
287 /**
288 * Total number of CPs dedicated to guests of this hypervisor.
289 * Number of cores when MT enabled.
290 */
291 uint16_t infydcps;
292 /**
293 * Total number of IFLs shared among guests of this hypervisor.
294 * Number of cores when MT enabled.
295 */
296 uint16_t infysifl;
297 /**
298 * Total number of IFLs dedicated to guests of this hypervisor.
299 * Number of cores when MT enabled.
300 */
301 uint16_t infydifl;
302 /* 32 bytes */
303 } ATTRIBUTE_PACKED;
304
305 struct sthyi_guest {
306 /**
307 * Guest Flag Byte 1
308 * - 0x80 - Guest is mobility enabled
309 * - 0x40 - Guest has multiple virtual CPU types
310 * - 0x20 - Guest CP dispatch type has LIMITHARD cap
311 * - 0x10 - Guest IFL dispatch type has LIMITHARD cap
312 * - 0x08 - Virtual CPs are thread dispatched
313 * - 0x04 - Virtual IFLs are thread dispatched
314 */
315 uint8_t infgflg1;
316 uint8_t infgflg2; /**< Guest Flag Byte 2 reserved for IBM use */
317 uint8_t infgval1; /**< Guest Validity Byte 1 reserved for IBM use */
318 uint8_t infgval2; /**< Guest Validity Byte 2 reserved for IBM use */
319 char infgusid[8]; /**< EBCDIC Userid */
320 uint16_t infgscps; /**< Number of guest shared CPs */
321 uint16_t infgdcps; /**< Number of guest dedicated CPs */
322 /**
323 * Dispatch type for guest CPs. This field is valid if INFGSCPS or
324 * INFGDCPS is greater than zero.
325 * - 0 - General Purpose (CP)
326 */
327 uint8_t infgcpdt;
328 char reserved_1__[3]; /**< Reserved for future IBM use */
329 /**
330 * Guest current capped capacity for shared virtual CPs, a scaled number
331 * where 0x00010000 represents one core. This field is zero to
332 * indicate not capped when:
333 * - There is no CP individual limit (that is, the "Guest CP dispatch
334 * type has LIMITHARD cap" bit in field INFGFLG1 is OFF).
335 * - There are no shared CPs on the system (that is, INFYSCPS = 0).
336 * If there is a CP limit but there are no shared CPs or virtual CPs,
337 * the limit is meaningless and does not apply to anything.
338 */
339 uint32_t infgcpcc;
340 uint16_t infgsifl; /**< Number of guest shared IFLs */
341 uint16_t infgdifl; /**< Number of guest dedicated IFLs */
342 /**
343 * Dispatch type for guest IFLs. This field is valid if INFGSIFL or
344 * INFGDIFL is greater than zero.
345 * - 0 - General Purpose (CP)
346 * - 3 - Integrated Facility for Linux (IFL)
347 */
348 uint8_t infgifdt;
349 char reserved_2__[3]; /**< Reserved for future IBM use */
350 /**
351 * Guest current capped capacity for shared virtual IFLs, a scaled
352 * number where 0x00010000 represents one core. This field is zero
353 * to indicate not capped with an IFL limit when:
354 * - There is no IFL individual limit (that is, the "Guest IFL dispatch
355 * type has LIMITHARD cap" bit in field INFGFLG1 is OFF).
356 * - The guest's IFLs are dispatched on CPs (that is, INFGIFDT = 00).
357 * When the guest's IFLs are dispatched on CPs, the CP individual
358 * limit (in INFGCPCC) is applied to the guest's virtual IFLs and
359 * virtual CPs.
360 */
361 uint32_t infgifcc;
362 /**
363 * CPU Pool Capping Flags
364 * - 0x80 - CPU Pool's CP virtual type has LIMITHARD cap
365 * - 0x40 - CPU Pool's CP virtual type has CAPACITY cap
366 * - 0x20 - CPU Pool's IFL virtual type has LIMITHARD cap
367 * - 0x10 - CPU Pool's IFL virtual type has CAPACITY cap
368 * - 0x08 - CPU Pool uses prorated core time.
369 */
370 uint8_t infgpflg;
371 char reserved_3__[3]; /**< Reserved for future IBM use */
372 /**
373 * EBCDIC CPU Pool Name. This field will be blanks if the guest is not
374 * in a CPU Pool.
375 */
376 char infgpnam[8];
377 /**
378 * CPU Pool capped capacity for shared virtual CPs, a scaled number
379 * where 0x00010000 represents one core. This field will be zero if
380 * not capped.
381 */
382 uint32_t infgpccc;
383 /**
384 * CPU Pool capped capacity for shared virtual IFLs, a scaled number
385 * where 0x00010000 represents one core. This field will be zero if
386 * not capped.
387 */
388 uint32_t infgpicc;
389 /* 56 bytes */
390 } ATTRIBUTE_PACKED;
391
392
393 static void
decode_ebcdic(const char * ebcdic,char * ascii,size_t size)394 decode_ebcdic(const char *ebcdic, char *ascii, size_t size)
395 {
396 /*
397 * This is mostly Linux's EBCDIC-ASCII conversion table, except for
398 * various non-representable characters that are converted to spaces for
399 * readability purposes, as it is intended to be a hint for the string
400 * contents and not precise conversion.
401 */
402 static char conv_table[] =
403 "\0\1\2\3 \11 \177 \13\14\15\16\17"
404 "\20\21\22\23 \n\10 \30\31 \34\35\36\37"
405 " \34 \n\27\33 \5\6\7"
406 " \26 \4 \24\25 \32"
407 " " " .<(+|"
408 "& " "!$*);~"
409 "-/ " "|,%_>?"
410 " `" ":#@'=\""
411 " abcdefghi" " "
412 " jklmnopqr" " "
413 " ~stuvwxyz" " "
414 "^ " "[] "
415 "{ABCDEFGHI" " "
416 "}JKLMNOPQR" " "
417 "\\ STUVWXYZ" " "
418 "0123456789" " ";
419
420 while (size--)
421 *ascii++ = conv_table[(unsigned char) *ebcdic++];
422 }
423
424 #define DECODE_EBCDIC(ebcdic_, ascii_) \
425 decode_ebcdic((ebcdic_), (ascii_), \
426 sizeof(ebcdic_) + MUST_BE_ARRAY(ebcdic_))
427 #define PRINT_EBCDIC(ebcdic_) \
428 do { \
429 char ascii_str[sizeof(ebcdic_) + MUST_BE_ARRAY(ebcdic_)]; \
430 \
431 DECODE_EBCDIC(ebcdic_, ascii_str); \
432 print_quoted_string(ascii_str, sizeof(ascii_str), \
433 QUOTE_EMIT_COMMENT); \
434 } while (0)
435
436 #define PRINT_FIELD_EBCDIC(prefix_, where_, field_) \
437 do { \
438 PRINT_FIELD_HEX_ARRAY(prefix_, where_, field_); \
439 PRINT_EBCDIC((where_).field_); \
440 } while (0)
441
442 #define PRINT_FIELD_WEIGHT(prefix_, where_, field_) \
443 do { \
444 PRINT_FIELD_X(prefix_, where_, field_); \
445 if ((where_).field_) \
446 tprintf_comment("%u %u/65536 cores", \
447 (where_).field_ >> 16, \
448 (where_).field_ & 0xFFFF); \
449 else \
450 tprints_comment("unlimited"); \
451 } while (0)
452
453
454 #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
print_sthyi_machine(struct tcb * tcp,struct sthyi_machine * hdr,uint16_t size,bool * dummy)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
print_sthyi_partition(struct tcb * tcp,struct sthyi_partition * hdr,uint16_t size,bool * mt)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
print_sthyi_hypervisor(struct tcb * tcp,struct sthyi_hypervisor * hdr,uint16_t size,int num,bool mt)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
print_sthyi_guest(struct tcb * tcp,struct sthyi_guest * hdr,uint16_t size,int num,bool mt)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
print_sthyi_buf(struct tcb * tcp,kernel_ulong_t ptr)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 */
SYS_FUNC(s390_sthyi)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
guard_storage_print_gsepl(struct tcb * tcp,uint64_t addr)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
guard_storage_print_gscb(struct tcb * tcp,kernel_ulong_t addr)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
SYS_FUNC(s390_guarded_storage)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
SYS_FUNC(s390_runtime_instr)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
SYS_FUNC(s390_pci_mmio_write)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
SYS_FUNC(s390_pci_mmio_read)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 */
1263