Mirror of strace – the linux syscall tracer
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

s390.c 41KB

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