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