Compare commits

..

101 Commits

Author SHA1 Message Date
Jan Höppner
25968033bb New release s390-tools-2.15.0
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-15 15:56:15 +02:00
Jan Höppner
1e746990c0 gitignore: Sort ignore list
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-15 15:56:15 +02:00
Jan Höppner
3002e7f754 gitignore: Add zkey and libekmfweb generated files
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-15 15:56:15 +02:00
Thomas Richter
ea10995f4d cpumf/chcpumf.c: Fix version and help printout when CPUMF not installed.
chcpumf does not print out version (option -v) or help text
(option -h) when the CPU Measurement Sampling facility is not
installed. This was different up to and including release 4.10.
Fix this and hounour option -v and option -h even when
the sampling facility is not installed.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Sven Schnelle
8b31319ddf s390-tools: add lsstp utility
A small utility to display the STP information present in sysfs
in a more readable way.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Sven Schnelle
1df4d66387 libutil: add util_file_read_va()
Takes a format string and parses a file accordingly and returns the
parsed values.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Sven Schnelle
37348ef662 libutil: add util_file_read_i()/util_file_read_ui()
These functions parse a sysfs file and return either an
unsigned integer or signed integer.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Thomas Richter
644432ba23 cpumf/man/lscpumf.1: Fix invocation list in man page
Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Harald Freudenberger
6eddae9a8a zcrypt: Support new config state with lszcrypt and chzcrypt
lszcrypt now shows a card/queue which is in 'deconfigured' state as
'deconfig' in the STATE column (verbose and non verbose mode).

chzcrypt became two new options: --config-on and --config-off to
switch one or more card devices to 'configured' or 'deconfigured'
state.

Both applications are able to handle older kernels which do now
provide the config sysfs attribute required for this new feature.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Alexander Egorenkov
d19f0915c3 dumpconf: support NVMe dump/reipl device
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Gerald Schaefer
0ecf18b66d ipl_tools: support clear attribute for nvme re-IPL
This patch adds support for the "clear" sysfs attribute for nvme re-IPL,
if available. This attribute allows to control whether the memory should
be cleared on re-IPL.

Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Fedor Loshakov
26c544998e ziomon/ziorep_printers: fix virtual adapter CSV output
During using of ziorep_utilization utility for generating of CSV format output,
there is one extra comma added after Bus-ID column in virtual adapter report
for each line. This creates one extra column with empty content for each
line. As a result in CSV viewer programs 'qdio utilization max %' column has
no content, all subsequent columns have shifted content from previous
column and the last column has no header. Avoid this situation by deleting
of extra comma.

Before patch application typical line of virtual adapter report looks like:
2020-05-14 13:55:43,0,60,0.0.1906,,0.000000,0.782567,0,0,0.0,321.8,1,1251

After patch application typical line of virtual adapter report looks like:
2020-05-14 13:55:43,0,60,0.0.1906,0.000000,0.782567,0,0,0.0,321.8,1,1251

Signed-off-by: Fedor Loshakov <loshakov@linux.ibm.com>
Reviewed-by: Julian Wiedmann <jwi@linux.ibm.com>
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
edaa72d68a libekmfweb: Fix sparse and gcc 10 warnings
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
041e3ad996 zkey: Fix sparse, gcc 10, and -Wpedantic warnings
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Eduard Shishkin
301eece09b zipl: fix Error when title is not the first field in BLS file
Problem:
zipl implementation (specifically the scan code) implicitly
assumes that title field is always on the top of BLS file,
and this assumption doesn't comply the bootloader standards:
https://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/

Solution:
Before parsing in-memory BLS entry, rearrange its lines as
following: search for a line with keyword "title" and move it
to the top. The scan code is invariant against such transform

Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/64
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
36bd05c4ba zkey-ekmfweb: Add man page for the EKMF Web plugin
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
8aa3f064af zkey-ekmfweb: Import keys from EKMF Web into zkey repository
Import existing keys that are stored in EKMF Web into the zkey repository.
The keys are imported including their associated information, such as
textual description, volumes, sector size, etc.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
48a7da096d zkey-ekmfweb: List keys stored in EKMF Web
Add the possibility to list keys stored in EKMF Web that are eligible to
be used with zkey. The list of keys can be filtered by name, label,
associated volumes, state and export-ability.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
094f52d604 zkey-ekmfweb: Change key state in EKMF Web when removing a key
When a key is removed from the zkey repository, the state of the key in
EKMF web can optionally be changed. Keys are usually not removed in EKMF
Web, but the state of the keys are changed to e.g. DEACTIVATED.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
0626dc7a72 zkey-ekmfweb: Set and get key properties
Add functions to get and set key properties (i.e. custom tags) of
keys stored in EKMF Web. The key properties are set when the information
associated with a key in the zkey repository is changed, e.g. using the
'zkey change' command.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
0180054d07 zkey-ekmfweb: Generate volume encryption keys in EKMF Web
Generate and import volume encryption keys of type CCA-AESCIPHER in
EKMF Web and import them int the zkey repository. Additional information
can be associated with the keys, such as a textual description, volumes
encrypted with the key, sector size of the volumes, etc. This is
also stored in EKMF Web with the keys as custom tags.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
800fe15d21 zkey-ekmfweb: Register the zkey client with EKMF Web
To register the zkey client with EKMF Web, the X.509 certificate
generated with the identity key is sent to EKMF Web, and an identity
key object is generated in EKMF Web with the public key from the
certificate. This identity key is then used to control the export of
keys stored in EKMF Web, and to verify the cryptographically signed
requests sent by the plugin.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
c570f51f5f zkey-ekmfweb: Generate certificate or CSR with identity key
To identify the zkey client with EKMF Web, an X.509 certificate must be
generated using the identity key, and must be made known to EKMF Web.
Either a self signed certificate can be generated, or a certificate
signing request (CSR) that is then passed to a certificate authority
(CA) to have a certificate issued.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
57b70a0fe0 zkey-ekmfweb: Re-encipher the identity key
The identity key of the plugin is a secure key. When the APKA master key
of the associated APQNs is changed, the identity key must be re-enciphered
under the new master key.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
cc0d030ce9 zkey-ekmfweb: Generate an identity key
To identify the zkey client with EKMF Web, the plugin generates a secure
ECC or RSA identity key, and stores it in its configuration directory.
This key is then used to cryptographically sign requests sent to EKMF Web.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
9dce6793ab zkey-ekmfweb: Get EKMF Web system settings
Retrieve several settings from EKMF Web after the connection to
EKMF Web has been configured. This includes the EKMF Web server's
public key, which is user later on to verify cryptographically signed
responses. Also the key templates used by EKMF Web to generate keys
for zkey are retrieved, and it is checked if the require feature
'Pervasive Encryption' is available.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
d8054d1a1a zkey-ekmfweb: Add login support
To perform operations in EKMF Web, the user must log in with a EKMF Web
user id and a time based one time passcode. The passcode can be obtained
by the user from the EKMF Web user interface, after logging in into EKMF
Web. That way a two factor authentication is performed. The plugin passes
the passcode to EKMF Web retrieves a bearer token from EKMF Web which it
then uses on subsequent requests to authenticate with EKMF Web. Such a
bearer token is valid for several minutes, thus no re-login is required
for zkey commands run during that time.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
5a9c381225 zkey-ekmfweb: Configure EKMF Web server and TLS options
Allow the user to configure the connection to the EKMF Web server
using the 'zkey kms configure' command. The communication is based
on a RESTful API via HTTPS. Besides the URL of the EKMF Web server,
other TLS related settings can be configured.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
3c6890317a zkey-ekmfweb: Configure APQNs and cross check APKA master keys
The EKMF Web plugin requires APQNs of one or multiple IBM cryptographic
adapters in CCA coprocessor mode to operate. It makes use of secure
RSA and ECC keys, and thus requires the APKA master keys of the CCA APQNs
to be set.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
1c42b9e3e4 zkey-ekmfweb: Add zkey-ekmfweb KMS plugin
Add support to integrate the external key management system EKMF Web
(IBM Enterprise Key Management Foundation - Web Edition) into zkey by
providing a zkey KMS plugin for EKMF Web. The plugin communicates
with EKMF Web using libekmfweb via a RESTful API.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:52 +02:00
Ingo Franzki
beb6a1d6fd zkey: Do not check secure key for C-XLATE flag
The C-XLATE flag determines if the secure key can be used with the
CCA Cipher Text Translate2 verb. Cipher Text Translate2 deciphers
encrypted data under one key and re-enciphers it under another key
without having the data appear in the clear outside the cryptographic
coprocessor. Since this is not a security risk, the check can be
removed.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
40e4b71159 libekmfweb: Get EKMF Web settings and check features
Retrieve EKMF Web settings such as the template names used by
EKMF Web for generating identity keys, as well as volume encryption
keys (XTS and non-XTS). Also check that the EKMF Web server has the
required 'Pervasive Encryption' feature installed.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
8c0f2491a3 libekmfweb: Login to EKMF Web
To perform operations in EKMF Web, the user must log in with a EKMF Web
user id and a time based one time passcode. The passcode can be obtained
by the user from the EKMF Web user interface, after logging in into EKMF
Web. That way a two factor authentication is performed. The client passes
the passcode to EKMF Web retrieves a bearer token from EKMF Web which it
then uses on subsequent requests to authenticate with EKMF Web. Such a
bearer token is valid for several minutes, thus no re-login is required
for zkey commands run during that time.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
e44ae22989 libekmfweb: Add, change and delete key tags
Allow to add, change and delete custom tags of a key. Custom tags
can be used store any kind of textual information with a key. Tags
have a name and a value.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
3be8be4ac7 libekmfweb: Change the key state
EKMF Web maintains a key state for each key. Keys can be in state
PRE-ACTIVATION, ACTIVE, DEACTIVATED, COMPROMISED, DESTROYED, and
DESTROYED-COMPROMISED. Key states can be changed as defined in NIST
Special Publication 800-57 Part 1.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
544c88ca39 libekmfweb: Generate a new key in EKMF Web
Allow to request EKMF Web to generate a new key in its repository.
The newly generated key is generated based on the key template used.
Also, custom properties can be specified that are stored together with
the key, as well as export control information defining who is allowed
to request an export of the key later on.

Besides generating new random keys in EKMF Web, you can also register
the client's public identity key with EKMF Web by generating a new
identity key using an X.509 certificate containing the client's public
key.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
c7afb5baec libekmfweb: Retrieve information about keys
Retrieve information about keys managed by EKMF Web, such as the
key algorithm, the key size and type. Additional, the key's tags
are retrieved. Label tags are used to build the label name of a key.
Custom tags can be used to store any kind of textual data together with
a key.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
cc9b202a9b libekmfweb: Retrieve information about key templates
Key templates are used by EKMF Web to generate new keys. The template
specifies the key algorithm, the key size, and type (e.g. CCA DATA or
CIPHER). It also determines how a newly generated key is named through
a key label template containing label tags.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
9f99706c26 libekmfweb: Retrieve a key from EKMF Web using an EC-DH protocol
To retrieve a secure key from EKMF Web, a Elliptic-curve Diffie-Hellman
(EC-DH) protocol is used to securely transport the key, without revealing
the key to be transported in clear. The key to be transported remains
encrypted all the time, either encrypted with the master key of the
cryptographic adapter on the source or target side, or with a transport
key, that is derived using the EC-DH key agreement protocol. The transport
key is also a secure key, itself encrypted with the master key of the
cryptographic adapters on both sides.

To generate the transport key, each side generates a new secure ECC
session key with its cryptographic adapter. This session keys are then
used with EC-DH to derive the secure transport key. The secure key to
be transported is then exported by EKMF Web under the transport key, is
sent to the client, and is then imported using the transport key.

The key retrieval request is signed using the identity key of the client.
EKMF Web knows the public key of the client's identity key through a one
time registration process, and can therefore verify the signature with
the client's public key. The response is also signed by the EKMF Web
server's identity key, and the client can verify the signature with the
server's public key that it retrieved once during registration.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
8137128a96 libekmfweb: Generate certificate or CSR with identity key
To identify the client with EKMF Web, an X.509 certificate must be
generated using the identity key, and must be made known to EKMF Web.
Either a self signed certificate can be generated, or a certificate
signing request (CSR) that is then passed to a certificate authority
(CA) to have a certificate issued. The certificate is then used to
register the client with EKMF Web, so that EKMF Web knows the public
part of the client's identity key.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
1cdfb4946e libekmfweb: Re-encipher the identity key
The identity key of the client is a secure key enciphered with the
master key of a cryptographic adapter (APQN). When the master key of
the used APQNs is changed, the identity key must be re-enciphered
under the new master key.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
5fb30f1e6f libekmfweb: Generate an identity key
To identify the client with EKMF Web, the client generates a secure
ECC or RSA identity key. This identity key is then used to
cryptographically sign certain requests sent to EKMF Web.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
d8089e69fa libekmfweb: Allow to check if a JSON Web Token (JWT) is expired
When login in with EKMF Web, a bearer token is retrieved from EKMF Web
which is then used on subsequent requests to authenticate with EKMF Web.
Such a bearer token is valid for several minutes, thus no re-login is
required during that time. The bearer token contains a JSON Web Token
(JWT, see RFC7519).

Allow to check such a token if it is still valid, or already expired.
That way a client application can check the token before issuing the next
request, and re-login if needed.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
cbf7f02d69 libekmfweb: Add EKMFWeb client library
The EKMFWeb client library provides functions to communicate
with an EKMF Web server via REST calls over HTTPS. EKMF Web stands
for IBM Enterprise Key Management Foundation - Web Edition and is
used to manage keys in an enterprise.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
91b1692b16 zkey: Add 'zkey kms refresh' command to update a KMS-bound key
Allow to refresh or update a KMS-bound key in the repository.
The secure key is re-imported from the KMS, and optionally also
its properties are updates from the KMS.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
cd8a733c82 zkey: Add 'zkey kms import' command to import keys from a KMS
Allow to import keys that exist in a key management system into the
repository. The key together with its properties is imported.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
bcce1e8d18 zkey: Add 'zkey kms list' command to list keys in a KMS
Allow to list the keys managed by a key management system. The keys
are displayed together with the key properties stored in the KMS.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
f832428109 zkey: Add KMS support for the 'zkey remove' command
When removing a KMS-bound key from the local repository, call the
KMS plugin and let it perform an action in the KMS. Usually keys are
not removed from key management systems, instead the key state is
changed to non-active or similar.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
1d7bb283fd zkey: Update properties in the KMS for change and rename commands
When key properties are changed with the 'change' command, also update
the key properties in the KMS, if the key is bound to a KMS. Do not
allow to change the associated APQNs for KMS bound keys. KMS bound keys
inherit the APQNs from the KMS plugin.

When a key is renamed in the repository, also update the key name
property in the KMS if the key is KMS bound.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
a2f14fcfd7 zkey: Add KMS restrictions for the convert and copy commands
Do not allow to convert a KMS bound key. The key type of a KMS
bound key is determined by what the KMS plugin supports, thus it
can not be converted.

Do only allow to copy a KMS bound key, if the '--local' option is
specified. The result of the copy is a local key, that is not bound
to a KMS.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
bb6a47db55 zkey: Add KMS support for 'zkey generate' command
When a repository that is bound to a key management system, the
keys are generated by the key management system by default. To
generate a local key, add option '--local'.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
35dd59d04c zkey: Add more key management system specific commands
Add the following sub-commands for key management system plugin
handling:
- configure:  Configure a KMS plugin
- reencipher: Re-encipher secure keys used by a KMS plugin

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
3fa511cfb9 zkey: Support KMS plugin specific options
Some commands requires additional options that are to be determined
by the KMS plugin. Add support to let the KMS plugin provide an
option vector per command, and add the options to the already existing
command options.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
c6c4df9697 zkey: Add key management system specific commands
Add command 'kms' and the following sub-commands of it to handle
key management system plugin binding and unbinding:
- plugins: List available/configured KMS plugins
- bind:    Binds a KMS plugin to the repository
- unbind:  Unbinds a KMS plugin from the repository
- info:    Displays information about the currently bound KMS plugin

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
1b0ab844b4 zkey: Add helper functions for KMS-bound keys
Add helper functions to iterate over KMS-bound keys in the repository.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
92fc94f152 zkey: Add KMS key properties and show them with list and validate
To support keys that are bound to a key management system (via a KMS
plugin) add new key properties that reflect this. Display if a key is
bound to a KMS with the 'zkey list' and 'zkey validate' commands.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
f25aaf32b8 zkey: Add support for key management system plugins
Add support to integrate external key management systems into zkey
by using a plugin concept. Add helper functions to load, bind, and
unbind a key management system plugin.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
13f8709ec2 zkey: Add support for sub-commands
Add support for sub-commands to zkey. Sub-commands allow to group a
set of commands within a sub command.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
6a860a01c3 libutil: Add -fPIC option for building libutil objects
Add the -fPIC option when building the libutil objects to generate
position-independent code, and allow them to be used in dynamically
loaded shared libraries.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Julian Wiedmann
131a910ac5 ziomon/ziorep_printers: fix typo in csv column headers
s/requqests/requests

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Reviewed-by: Fedor Loshakov <loshakov@linux.ibm.com>
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Jan Höppner
7007937456 Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-08-21 12:12:02 +02:00
Jan Höppner
a528bb41e0 New release s390-tools-2.14.0
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-08-21 12:12:02 +02:00
Jan Höppner
ed52031821 cpumf: Remove TESTS from Makefile
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-08-21 09:12:29 +02:00
Stefan Haberland
60f33fb2de zdsfs: add coordinated read access to man page
Add description for coordinated read access to man page as well as some
editorial changes after ID review.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-08-20 17:05:39 +02:00
Stefan Haberland
5737a57920 zdsfs: coordinated read access
For data consistency it is essential that datasets are not modified by
z/OS applications during zdsfs access. This is currently ensured by
manually setting the device offline in z/OS before mounting it in Linux.

This patch improves the usability and data security by making this manual
step obsolete.
Before opening a dataset zdsfs will obtain an ENQ to mark it as in use for
z/OS and release the ENQ when closing the dataset.
A timer is set up that pings the z/OSMF REST services with the ENQ to
prevent it from a timeout after 10 minutes.
The behavior of zdsfs can be configured in a new config file or with new
command line options.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-08-20 17:05:39 +02:00
Stefan Haberland
b044aec4ff libzds: add curl interface to access zosmf rest api
Add library functions that allow to communicate with z/OSMF REST services
using libcurl.
Following three functions are added:

lzds_rest_get_enq()
	to obtain an ENQ that will mark a dataset as in use to z/OS until
	it is released again
lzds_rest_release_enq()
	to release an ENQ and mark a dataset as no longer in use to z/OS
lzds_rest_ping()
	to ping a z/OSMF REST server to check if it accessible
	or to refresh an ENQ and prevent it from a timeout after 10 minutes

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-08-20 17:05:39 +02:00
Ingo Franzki
e584c88d8f zkey: Minor correction in man page
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-08-20 17:05:39 +02:00
Alexander Egorenkov
fd817280d3 zipl: fix incorrect setup of stage3 flags
Stage 3 flags is a 64bit integer but function add_ipl_program
used a 32bit integer instead. Due to this bug
STAGE3_FLAG_SCSI and STAGE3_FLAG_KDUMP were not correctly set.

Fixes: 412d3e8c ("zipl: consolidate stage3_params structs and stage3 flags")
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-08-20 17:05:39 +02:00
Ingo Franzki
046d27a05b zkey-cryptsetup: Fix typo in man page
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-08-20 17:05:39 +02:00
Juergen Christ
fd174cb952 cpacfstats: Bugfix to remove libpfm from cpacfstats
libpfm does not yet include counters introduced with z15 in a release.
cpacfstatsd now implements its own counter logic to become independent
of the slow release cycles of libpfm.

Reviewd-By: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewd-By: Harald Freudenberger <freude@de.ibm.com>
Signed-off-by: Juergen Christ <jchrist@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-07-27 17:34:24 +02:00
Marc Hartmayer
70f1dcd770 genprotimg/check_hostkeydoc: improve documentation
+ remove outdated comment that the revocation list checking is not implemented
 + improve usage example

Reviewed-by: Viktor Mihajlovski <mihajlov@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-07-24 13:01:09 +02:00
Marc Hartmayer
fcd5d64a45 genprotimg/check_hostkeydoc: use POSIX compatibility mode
Use the POSIX compatibility mode in a bash shell.

Reviewed-by: Viktor Mihajlovski <mihajlov@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-07-24 13:01:09 +02:00
Marc Hartmayer
320e11dcf9 genprotimg/check_hostkeydoc: fix bash detection
We cannot rely on what $SHELL says as it describes what the users
default shell is and not which kind of shell /bin/sh is. So instead of
checking the environment variable $SHELL, we can test whether the
environment variable $BASH is set. If this is the case, we can be
pretty sure that the script is executed by the bash shell.

This fixes the error on Ubuntu 20.04:

./check_hostkeydoc se-certs/host-key.crt se-certs/ibm-z-host-key-signing.crt -c se-certs/DigiCertCA.crt -r se-certs/ibm-z-host-key.crl
./check_hostkeydoc: 42: set: Illegal option -o pipefail

Reviewed-by: Viktor Mihajlovski <mihajlov@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-07-24 13:01:09 +02:00
Thomas Richter
34cfca722c cpumf/lscpumf.c: Add support for counter number 265
Set the counter name for z15 counter numbered 265. It is either named
DFLT_CCERROR or DFLT_CCFINISH, depending on the linux version. The
counter was renamed from CCERROR to CCFINISH in linux version 5.8.
Check for existence of file /sys/devices/cpum_cf/events/DLFT_CCERROR.
f this file exists the counter is named DFLT_CCERROR else
DFLT_CCFINISH (only for z15), other machines do not have this counter.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-07-24 13:01:09 +02:00
Gerald Schaefer
2215ba672e mon_tools: update udevadm location
Modern distributions do not provide the symlink /sbin/udevadm any more.
Use /usr/bin/udevadm instead for the example init script / systemd units.
Note that those are meant for example purpose and would need to be adjusted
by distributions, so no extra effort is taken to determine the actual
location of udevadm.

Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-07-24 13:01:09 +02:00
Guevenc Guelce
1003d81412 znetconf: introduce better ways to locate udevadm
When udevadm is going to be used, try to locate it
in $PATH and if it fails, try to locate it in well-known
binary paths.

Signed-off-by: Guevenc Guelce <guvenc@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-07-17 17:55:39 +02:00
Stefan Haberland
943c5dc51d zipl/stage3: correctly handle diag308 response code
In case diag308 gives a response code 0x102 the stage3 loader can
safely assume that no secure IPL is required since no IPL report
block exists.

Suggested-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Tested-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-07-17 17:55:39 +02:00
Marc Hartmayer
c367a6bb65 zipl/libc: libc_stop move 'noreturn' to declaration
Commit 86856f98db ("zipl: Make use of __noreturn macro") moved the
'noreturn' attribute from declaration to definition. With this the
compiler can no longer optimize when the function is called in a
separate source file. Move the attribute back to the declaration

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-07-17 17:55:39 +02:00
Ingo Franzki
0db89894b5 zkey: Minor man page corrections
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-07-17 17:55:39 +02:00
Ingo Franzki
2f87cba1c7 util_opt: Change util_opt_init() to honor current command, if set
Function util_opt_init() build the option string for getopt_long().
If a command has been set via util_opt_set_command(), then util_opt_init()
must honor that command and only add those options that match the command,
or are command independent.

That way the same option can be used in different commands with different
flags and different argument settings. E.g. for command 'a' option '-x'
might require an argument, for command 'b' the same option '-x' might not
require an argument.

The behavior of util_opt_init() is unchanged if no command is set, and
also if different commands use the same option, but with the same flags
and argument settings. Currently only the zkey tools set a command, but
use unique options per command.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-07-17 17:55:39 +02:00
Sa Liu
c31eba5e00 dbginfo: Added collection of /proc/softirqs
Signed-off-by: Sa Liu <saliu@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-07-17 17:55:39 +02:00
Ingo Franzki
04b0b43739 zkey: Fix memory leak during validate and reencipher command
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-07-17 17:55:39 +02:00
Ingo Franzki
798967aba3 zkey: Fix -Wmaybe-uninitialized warnings in zkey-cryptsetup.c
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-07-17 17:55:39 +02:00
Alexander Egorenkov
f2f4dc209c zfcpdump: remove unused constants for zcore/{mem,memmap}
Remove obsolete and unused constants for zcore memory
character devices '/sys/kernel/debug/zcore/mem' and
'/sys/kernel/debug/zcore/memmap'.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-07-17 17:55:39 +02:00
Stefan Haberland
d7b816ff58 zipl: fix BLS error message
Fix that a misleading BLS error message is printed in any case for missing
files.
The scan_check code in zipl already does proper error handling for missing
file. Remove the duplicated error handling from scan_check_bls and just use
the function to update the file with the target path if needed.
To indicate the intention of this function also rename it.

Fixes: #84

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Tuan Hoang <tmhoang@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-07-17 17:55:39 +02:00
Dan Horák
ae66f79512 zipl: fix handling of values with load address in BLS
Various keywords (like image or ramdisk) allow specifying a load address
as an optional argument. Adapt the logic for checking the presence of
the files to take this into the account.

Fixes: d71628326d
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1772054

Closes: #76

Signed-off-by: Dan Horák <dan@danny.cz>
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-07-17 17:55:39 +02:00
Dan Horák
3217e0438f zipl: set reason not text for failed check
GitHub-ID: #76

Signed-off-by: Dan Horák <dan@danny.cz>
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-07-17 17:55:39 +02:00
Dan Horák
41fae58ecd zipl: drop redundant string duplication
GitHub-ID: #76

Signed-off-by: Dan Horák <dan@danny.cz>
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-07-17 17:55:39 +02:00
Jan Höppner
6dab7637fb gitignore: Fix entries
With the rewrite of cpumf, the bin directory and cpumf_helper got
removed. Fix it.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-07-17 17:55:39 +02:00
Thomas Richter
53b949926f vmcp: Change sequence of failed exit
When vmcp fails to execute a CP command with both error conditions
- response buffer is too small
- CP command failed
then the vmcp program exits with 'response buffer too small' indication.
However, an exit code indicating 'CP command failed' would be more
important in this case.
So change the vmcp exit code and return 'CP command failed' for above
error scenario.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-06-16 10:32:19 +02:00
Juergen Christ
e08e07baa9 cpacfstats: Add ECC counters to cpacfstats
z15 architecture supports counters for ECC operations.  We now add and evaluate
these counters on supported architectures.  If ECC counters are not supported,
we simply print "unsupported" for ECC counter values.

Manpages adapted accordingly.

Signed-off-by: Juergen Christ <juergen.christ@ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-06-16 10:32:19 +02:00
Julian Wiedmann
e679a4002e lsluns: try harder to find udevadm
Hard-coding udevadm's location isn't robust enough - for instance,
Ubuntu 20.04 moved it to /usr/bin.

First see if we can reach it through $PATH, then fall back to hard-coded
locations that we know about.
Also when finally falling back to udevsettle, check that it exists.
Otherwise we end up throwing tons of "No such file or directory" error
messages at the user.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Fedor Loshakov <loshakov@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-29 15:18:31 +02:00
Thomas Richter
20b05e1f82 cpumf/chcpumf.8: Add description for option verbose
Add description for option verbose.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-29 15:18:31 +02:00
Thomas Richter
ce02dd7167 cpumf/chcpumf.c: Print verbose message on success
Print verbose message on success only.

Reviewed-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-29 15:18:31 +02:00
Thomas Richter
d2fc700b73 man/lscpumf.1: Fix wording and typos
Linux in upper case L.

Reviewed-by: Horst Weber <hweber@linux.ibm.com>
Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-29 15:18:31 +02:00
Thomas Richter
199b030580 cpumf: Rewrite chcpumf and lscpumf in C
Rewrite lscpumf and chcpumf in C. The previous version
habe been written in perl which require a lot of instructure.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-29 15:18:31 +02:00
Jason J. Herne
71b36d17f0 zipl: Fix NVMe partition and base device detection
Copying the SCSI scheme wasn't good enough due to how major/minor
numbers are assigned by the blkext driver. We now query the relevant
information via sysfs.

Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-12 17:03:33 +02:00
Julian Wiedmann
ca8750e820 zdev: qeth: remove the fake_broadcast attribute
This attribute is a no-op and never provided the described functionality.
It will be removed in the 5.7 kernel release with
commit 5f4019a80839 ("s390/qeth: remove fake_broadcast attribute").

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-12 17:03:33 +02:00
Jason J. Herne
0472b5ea5c ipl-tools: Add nvme device support to lsreipl/chreipl
Support is added to lsreipl to detect the nvme reipl type and list the
appropriate parameters.

Support is added to chreipl to specify and populate sysfs reipl entries
with nvme device targets.

Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-12 17:03:28 +02:00
Marc Hartmayer
94a3272dac genprotimg/samples: fix typo
Fix typo.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-12 17:01:53 +02:00
Jan Höppner
d72cf322c0 Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-12 17:01:53 +02:00
115 changed files with 32060 additions and 3605 deletions

22
.gitignore vendored
View File

@@ -11,9 +11,8 @@
cmsfs-fuse/cmsfs-fuse
cpacfstats/cpacfstats
cpacfstats/cpacfstatsd
cpumf/bin/chcpumf
cpumf/bin/cpumf_helper
cpumf/bin/lscpumf
cpumf/chcpumf
cpumf/lscpumf
cpuplugd/cpuplugd
dasdfmt/dasdfmt
dasdinfo/dasdinfo
@@ -35,6 +34,9 @@ iucvterm/src/iucvconn
iucvterm/src/iucvtty
iucvterm/src/ttyrun
iucvterm/test/test_afiucv
libekmfweb/check-dep-libekmfweb
libekmfweb/detect-openssl-version.dep
libekmfweb/libekmfweb.so
libutil/util_base_example
libutil/util_file_example
libutil/util_libc_example
@@ -45,8 +47,9 @@ libutil/util_path_example
libutil/util_prg_example
libutil/util_rec_example
libutil/util_scandir_example
libzds/libzds.a
libvmcp/vmcp_example
libzds/libzds.a
lsstp/lsstp
mon_tools/mon_fsstatd
mon_tools/mon_procd
osasnmpd/osasnmpd
@@ -76,10 +79,10 @@ zdev/src/lszdev
zdev/src/lszdev_usage.c
zdsfs/zdsfs
zdump/zgetdump
zfcpdump/cpioinit
zfcpdump/zfcpdump_part
zfcpdump/zfcpdump-initrd
zfcpdump/10-zfcpdump.install
zfcpdump/cpioinit
zfcpdump/zfcpdump-initrd
zfcpdump/zfcpdump_part
ziomon/ziomon_mgr
ziomon/ziomon_util
ziomon/ziomon_zfcpdd
@@ -91,9 +94,10 @@ zipl/boot/data.h
zipl/src/chreipl_helper.device-mapper
zipl/src/zipl
zipl/src/zipl_helper.device-mapper
zkey/zkey
zkey/zkey-cryptsetup
zkey/check-dep-zkey
zkey/check-dep-zkey-cryptsetup
zkey/detect-libcryptsetup.dep
zkey/ekmfweb/zkey-ekmfweb.so
zkey/zkey
zkey/zkey-cryptsetup
zpcictl/zpcictl

View File

@@ -1,6 +1,7 @@
List of all individuals having contributed content to s390-tools
----------------------------------------------------------------
- Alexander Egorenkov
- Alexey Ishchuk
- Andreas Herrmann
- Andre Wild
@@ -18,6 +19,7 @@ List of all individuals having contributed content to s390-tools
- Despina Papadopoulou
- Dimitri John Ledkov
- Eberhard Pasch
- Eduard Shishkin
- Einar Lueck
- Eric Sandeen
- Erwin Vicari
@@ -32,6 +34,7 @@ List of all individuals having contributed content to s390-tools
- Fritz Elfert
- Gerald Schaefer
- Gerhard Tonn
- Guevenc Guelce
- Hannes Reinecke
- Hans-Joachim Picht
- Hans Wippel
@@ -52,6 +55,7 @@ List of all individuals having contributed content to s390-tools
- Jean-Baptiste Joret
- Jens Remus
- Jochen Roehrig
- Juergen Christ
- Julian Wiedmann
- Karsten Graul
- Kittipon Meesompop
@@ -94,6 +98,7 @@ List of all individuals having contributed content to s390-tools
- Steffen Maier
- Steffen Thoss
- Susanne Wintenberger
- Sven Schnelle
- Sven Schuetz
- Swen Schillig
- Taraka R. Bodireddy

View File

@@ -1,5 +1,48 @@
Release history for s390-tools (MIT version)
--------------------------------------------
* __v2.15.0 (2020-10-15)__
For Linux kernel version: 5.9
Add new tool:
- lsstp: A small utility to display the Server Time Protocol (STP) information present in sysfs
Changes of existing tools:
- dumpconf: support NVMe dump/reipl device
- ipl_tools: support clear attribute for nvme re-IPL
- zcrypt: Support new config state with lszcrypt and chzcrypt
- zkey: Add support for key management system plugins
including the KMS commands:
bind, unbind, info, configure, rencipher, list, import, refresh
- zkey: Add EKMFWeb support to remotely generate secure keys
- libekmfweb: Add new EKMFWeb client library
- libutil: Add util_file_read_va()
- libutil: Add util_file_read_i()/util_file_read_ui()
Bug Fixes:
- cpumf: Fix version and help printout when CPUMF is not installed
- ziomon/ziorep_printers: fix virtual adapter CSV output
- zipl: Fix Error when title is not the first field in BLS file
* __v2.14.0 (2020-08-21)__
For Linux kernel version: 5.7 / 5.8
Changes of existing tools:
- cpacfstats: Add ECC counters
- dbginfo: Added collection of /proc/softirqs
- ipl-tools: Add nvme device support to lsreipl/chreipl
- zdsfs: Add coordinated read access
- libzds: Add curl interface to access zosmf rest api
- util_opt: Change util_opt_init() to honor current command, if set
Bug Fixes:
- lsluns: Try harder to find udevadm
- mon_tools: Update udevadm location
- zipl: Fix NVMe partition and base device detection
- zipl/stage3: Correctly handle diag308 response code
- znetconf: Introduce better ways to locate udevadm
* __v2.13.0 (2020-05-06)__
For Linux kernel version: 5.5 / 5.6

View File

@@ -3,13 +3,13 @@ ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/ar
# Include common definitions
include common.mak
LIB_DIRS = libvtoc libutil libzds libdasd libvmdump libccw libvmcp
LIB_DIRS = libvtoc libutil libzds libdasd libvmdump libccw libvmcp libekmfweb
TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
tape390 osasnmpd qetharp ip_watcher qethconf scripts zconf \
vmconvert vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \
ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc zpcictl \
genprotimg
genprotimg lsstp
SUB_DIRS = $(LIB_DIRS) $(TOOL_DIRS)

View File

@@ -243,6 +243,12 @@ Package contents
Provides simple tools to create a binary that can be used to implement
simple network boot setups following the PXELINUX conventions.
* libekmfweb:
A shared library that provides functions to communicate with an EKMF Web
server via REST calls over HTTPS. EKMF Web stands for IBM Enterprise Key
Management Foundation - Web Edition, and is used to manage keys in an
enterprise.
For more information refer to the following publications:
* "Device Drivers, Features, and Commands" chapter "Useful Linux commands"
@@ -267,10 +273,11 @@ build options:
| pfm | `HAVE_PFM` | cpacfstats |
| net-snmp | `HAVE_SNMP` | osasnmpd |
| glibc-static | `HAVE_LIBC_STATIC` | zfcpdump |
| openssl | `HAVE_OPENSSL` | genprotimg,zkey |
| openssl | `HAVE_OPENSSL` | genprotimg, zkey, libekmfweb |
| cryptsetup | `HAVE_CRYPTSETUP2` | zkey-cryptsetup |
| json-c | `HAVE_JSONC` | zkey-cryptsetup |
| json-c | `HAVE_JSONC` | zkey-cryptsetup, libekmfweb |
| glib2 | `HAVE_GLIB2` | genprotimg |
| libcurl | `HAVE_LIBCURL` | libekmfweb |
This table lists additional build or install options:
@@ -397,3 +404,11 @@ the different tools are provided:
tool must be added to this group. The owner of the default key repository
'/etc/zkey/repository' must be set to group 'zkeyadm' with write permission
for this group.
* libekmfweb:
For building the libekmfweb shared library you need openssl version 1.1.1 or
newer installed (openssl-devel.rpm). Also required are json-c version 0.13 or
newer (json-c-devel.rpm), and libcurl version 7.59 or newer
(libcurl-devel.rpm).
Tip: you may skip the libekmfweb build by adding `HAVE_OPENSSL=0`,
`HAVE_JSONC=0`, or `HAVE_LIBCURL=0` to the make invocation.

View File

@@ -5,7 +5,7 @@ COMMON_INCLUDED = true
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
VERSION = 2
RELEASE = 13
RELEASE = 15
PATCHLEVEL = 0
DISTRELEASE = build-$(shell date +%Y%m%d)
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
@@ -163,6 +163,7 @@ USRSBINDIR = $(INSTALLDIR)/usr/sbin
USRBINDIR = $(INSTALLDIR)/usr/bin
BINDIR = $(INSTALLDIR)/sbin
LIBDIR = $(INSTALLDIR)/lib
LIB64DIR = $(INSTALLDIR)/lib64
SYSCONFDIR = $(INSTALLDIR)/etc
MANDIR = $(INSTALLDIR)/usr/share/man
VARDIR = $(INSTALLDIR)/var
@@ -172,14 +173,16 @@ ZFCPDUMP_DIR = $(TOOLS_LIBDIR)/zfcpdump
# Systemd support files are installed only if a directory is specified
# for SYSTEMDSYSTEMUNITDIR (e.g. /lib/systemd/system)
SYSTEMDSYSTEMUNITDIR =
USRINCLUDEDIR = $(INSTALLDIR)/usr/include
INSTDIRS = $(USRSBINDIR) $(USRBINDIR) $(BINDIR) $(LIBDIR) $(MANDIR) \
$(SYSCONFDIR) $(SYSCONFDIR)/sysconfig \
$(TOOLS_LIBDIR) $(TOOLS_DATADIR) \
$(ZFCPDUMP_DIR) $(SYSTEMDSYSTEMUNITDIR)
$(ZFCPDUMP_DIR) $(SYSTEMDSYSTEMUNITDIR) \
$(LIB64DIR) $(USRINCLUDEDIR)
OWNER = $(shell id -un)
GROUP = $(shell id -gn)
export INSTALLDIR BINDIR LIBDIR MANDIR OWNER GROUP
export INSTALLDIR BINDIR LIBDIR LIB64DIR MANDIR OWNER GROUP
# Special defines for zfcpdump
ZFCPDUMP_IMAGE = zfcpdump-image
@@ -339,6 +342,10 @@ $(rootdir)/libvmcp/libvmcp.a: $(rootdir)/libvmcp
$(MAKE) -C $(rootdir)/libvmcp/ libvmcp.a
.PHONY: $(rootdir)/libvmcp
$(rootdir)/libekmfweb/libekmfweb.so: $(rootdir)/libekmfweb
$(MAKE) -C $(rootdir)/libekmfweb/ libekmfweb.so
.PHONY: $(rootdir)/libekmfweb
$(rootdir)/zipl/boot/data.o:
$(MAKE) -C $(rootdir)/zipl/boot/ data.o

View File

@@ -2,28 +2,10 @@ include ../common.mak
ALL_CPPFLAGS += -DVERSION=$(VERSION)
ifeq (${HAVE_PFM},0)
all:
$(SKIP) HAVE_PFM=0
install:
$(SKIP) HAVE_PFM=0
else
check_dep:
$(call check_dep, \
"cpacfstats", \
"perfmon/pfmlib.h", \
"libpfm-devel or libpfm4-dev", \
"HAVE_PFM=0")
all: check_dep cpacfstats cpacfstatsd
all: cpacfstats cpacfstatsd
cpacfstatsd: cpacfstatsd.o stats_sock.o perf_crypto.o
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -lpfm -o $@
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
cpacfstats: cpacfstats.o stats_sock.o
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
@@ -34,7 +16,6 @@ install: all
$(INSTALL) -m 644 cpacfstatsd.8 $(DESTDIR)$(MANDIR)/man8
$(INSTALL) -m 644 cpacfstats.1 $(DESTDIR)$(MANDIR)/man1
endif
clean:
rm -f *.o *~ cpacfstatsd cpacfstats

View File

@@ -1,6 +1,6 @@
.\" cpacfstats.1
.\"
.\" Copyright IBM Corp. 2015, 2017
.\" Copyright IBM Corp. 2015, 2020
.\" s390-tools is free software; you can redistribute it and/or modify
.\" it under the terms of the MIT license. See LICENSE for details.
.\"
@@ -80,31 +80,33 @@ Display help information for the command.
Display version and copyright information for the command.
.TP
\fB\-e\fR or \fB\-\-enable\fR [counter]
Enable one or all CPACF performance counters. The optional counter argument
can be one of: \fBdes\fR, \fBaes\fR, \fBsha\fR, \fBprng\fR or \fBall\fR. If
the counter argument is omitted, all performance counters are
enabled. Enabling a counter does not reset it. New events are added to the
current counter value.
Enable one or all CPACF performance counters. The optional counter
argument can be one of: \fBdes\fR, \fBaes\fR, \fBsha\fR, \fBprng\fR,
\fBecc\fR, or \fBall\fR. If the counter argument is omitted, all
performance counters are enabled. Enabling a counter does not reset
it. New events are added to the current counter value.
.TP
\fB\-d\fR or \fB\-\-disable\fR [counter]
Disable one or all CPACF performance counters. The optional counter
argument can be one of: \fBdes\fR, \fBaes\fR, \fBsha\fR, \fBprng\fR or
\fBall\fR. If the counter argument is omitted, all performance counters
are disabled. Disabling a counter does not reset it. The counter value is
preserved when a counter is disabled, and counting will resume using the
preserved value when the counter is re-enabled.
argument can be one of: \fBdes\fR, \fBaes\fR, \fBsha\fR, \fBprng\fR,
\fBecc\fR, or \fBall\fR. If the counter argument is omitted, all
performance counters are disabled. Disabling a counter does not reset
it. The counter value is preserved when a counter is disabled, and
counting will resume using the preserved value when the counter is
re-enabled.
.TP
\fB\-r\fR or \fB\-\-reset\fR [counter]
Reset one or all CPACF performance counters. The optional counter
argument can be one of: \fBdes\fR, \fBaes\fR, \fBsha\fR, \fBprng\fR or
\fBall\fR. If the counter argument is omitted, all performance counters are
reset to 0.
argument can be one of: \fBdes\fR, \fBaes\fR, \fBsha\fR, \fBprng\fR,
\fBecc\fR, or \fBall\fR. If the counter argument is omitted, all
performance counters are reset to 0.
.TP
\fB\-p\fR or \fB\-\-print\fR [counter]
Display the value of one or all CPACF performance counters. The optional
counter argument can be one of: \fBdes\fR, \fBaes\fR, \fBsha\fR, \fBprng\fR
or \fBall\fR. If the counter argument is omitted or if there is no
argument, all performance counters are displayed.
Display the value of one or all CPACF performance counters. The
optional counter argument can be one of: \fBdes\fR, \fBaes\fR,
\fBsha\fR, \fBprng\fR, \fBecc\fR, or \fBall\fR. If the counter
argument is omitted or if there is no argument, all performance
counters are displayed.
.TP
The default command is --print all.
.
@@ -123,5 +125,10 @@ version mismatch between client and daemon, or the application is out of
memory. The application prints a message with the details of the error and
the errno value.
.
.SH NOTES
ECC counters are only available since z15. cpacfstats will show the
counters as \fIunsupported\fR if the hardware does not support ECC
counters.
.
.SH SEE ALSO
cpacfstatsd (8)
.BR cpacfstatsd (8)

View File

@@ -3,7 +3,7 @@
*
* cpacfstats client implementation
*
* Copyright IBM Corp. 2015, 2017
* Copyright IBM Corp. 2015, 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -39,13 +39,14 @@ static const char *const usage =
"\t-d, --disable [counter] Disable one or all counters\n"
"\t-r, --reset [counter] Reset one or all counter values\n"
"\t-p, --print [counter] Print one or all counter values\n"
"\tcounter can be: 'aes' 'des' 'rng' 'sha' or 'all'\n";
"\tcounter can be: 'aes' 'des' 'rng' 'sha' 'ecc' or 'all'\n";
static const char *const counter_str[] = {
[DES_FUNCTIONS] = "des",
[AES_FUNCTIONS] = "aes",
[SHA_FUNCTIONS] = "sha",
[PRNG_FUNCTIONS] = "rng",
[ECC_FUNCTIONS] = "ecc",
[ALL_COUNTER] = "all"
};
@@ -98,6 +99,8 @@ static void print_answer(int ctr, int state, uint64_t value)
counter_str[ctr], state);
else if (state == DISABLED)
printf(" %s counter: disabled\n", counter_str[ctr]);
else if (state == UNSUPPORTED)
printf(" %s counter: unsupported\n", counter_str[ctr]);
else
printf(" %s counter: %"PRIu64"\n", counter_str[ctr], value);
}

View File

@@ -3,7 +3,7 @@
*
* common function prototypes and definitions
*
* Copyright IBM Corp. 2015, 2017
* Copyright IBM Corp. 2015, 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -14,7 +14,7 @@
#include "lib/zt_common.h"
#define COPYRIGHT "Copyright IBM Corp. 2015, 2017"
#define COPYRIGHT "Copyright IBM Corp. 2015, 2020"
int eprint(const char *format, ...);
@@ -27,6 +27,7 @@ enum ctr_e {
AES_FUNCTIONS,
SHA_FUNCTIONS,
PRNG_FUNCTIONS,
ECC_FUNCTIONS,
ALL_COUNTER
};
@@ -44,7 +45,8 @@ enum cmd_e {
enum state_e {
DISABLED = 0,
ENABLED
ENABLED,
UNSUPPORTED
};
/*
@@ -108,5 +110,6 @@ int perf_enable_ctr(enum ctr_e ctr);
int perf_disable_ctr(enum ctr_e ctr);
int perf_reset_ctr(enum ctr_e ctr);
int perf_read_ctr(enum ctr_e ctr, uint64_t *value);
int perf_ecc_supported(void);
#endif

View File

@@ -1,6 +1,6 @@
.\" cpacfstatsd.8
.\"
.\" Copyright IBM Corp. 2015, 2017
.\" Copyright IBM Corp. 2015, 2020
.\" s390-tools is free software; you can redistribute it and/or modify
.\" it under the terms of the MIT license. See LICENSE for details.
.\"
@@ -37,7 +37,10 @@ config option enabled.
.P
- Libpfm version 4 or higher is needed to successfully run the daemon.
.P
- Your LPAR must be configured to enable the "Counter Facility Security Options".
- On the HMC or SE, authorize the LPAR for each counter set you want
to use. Customize the LPAR activation profile and modify the Counter
Facility Security Options. You need to activate the "Crypto activity
counter set authorization control" checkbox.
.P
- The daemon requires root privileges to interact with the performance
ioctls of the kernel.
@@ -47,7 +50,7 @@ restart the daemon to ensure correct summing of the per-CPU performance
counters.
The starting daemon first checks for any stale pid file
/run/cpacfstatsd.pid. If this file exists, and the process ID in the
\%/run/cpacfstatsd.pid. If this file exists, and the process ID in the
file belongs to an active process, an error message is printed to the
console and the program terminates.
@@ -94,4 +97,4 @@ done in the re-spawned process. Check the syslog for success or failure.
The daemon could not be set to run in the background.
.SH SEE ALSO
cpacfstats (1)
.BR cpacfstats (1)

View File

@@ -94,20 +94,24 @@ static int do_enable(int s, enum ctr_e ctr)
for (i = 0; i < ALL_COUNTER; i++) {
if (i == (int) ctr || ctr == ALL_COUNTER) {
if (!ctr_state[i]) {
if (ctr_state[i] == DISABLED) {
rc = perf_enable_ctr(i);
if (rc != 0) {
send_answer(s, i, rc, 0);
break;
}
ctr_state[i] = 1;
ctr_state[i] = ENABLED;
}
rc = perf_read_ctr(i, &value);
if (rc != 0) {
send_answer(s, i, rc, 0);
break;
if (ctr_state[i] == UNSUPPORTED) {
send_answer(s, i, UNSUPPORTED, 0);
} else {
rc = perf_read_ctr(i, &value);
if (rc != 0) {
send_answer(s, i, rc, 0);
break;
}
send_answer(s, i, ENABLED, value);
}
send_answer(s, i, ENABLED, value);
}
}
@@ -121,7 +125,7 @@ static int do_disable(int s, enum ctr_e ctr)
for (i = 0; i < ALL_COUNTER; i++) {
if (i == (int) ctr || ctr == ALL_COUNTER) {
if (ctr_state[i]) {
if (ctr_state[i] == ENABLED) {
rc = perf_disable_ctr(i);
if (rc != 0) {
send_answer(s, i, rc, 0);
@@ -129,7 +133,7 @@ static int do_disable(int s, enum ctr_e ctr)
}
ctr_state[i] = 0;
}
send_answer(s, i, DISABLED, 0);
send_answer(s, i, ctr_state[i], 0);
}
}
@@ -143,7 +147,7 @@ static int do_reset(int s, enum ctr_e ctr)
for (i = 0; i < ALL_COUNTER; i++) {
if (i == (int) ctr || ctr == ALL_COUNTER) {
if (ctr_state[i]) {
if (ctr_state[i] == ENABLED) {
rc = perf_reset_ctr(i);
if (rc != 0) {
send_answer(s, i, rc, 0);
@@ -151,7 +155,7 @@ static int do_reset(int s, enum ctr_e ctr)
}
send_answer(s, i, ENABLED, 0);
} else {
send_answer(s, i, DISABLED, 0);
send_answer(s, i, ctr_state[i], 0);
}
}
}
@@ -166,7 +170,7 @@ static int do_print(int s, enum ctr_e ctr)
for (i = 0; i < ALL_COUNTER; i++) {
if (i == (int) ctr || ctr == ALL_COUNTER) {
if (ctr_state[i]) {
if (ctr_state[i] == ENABLED) {
rc = perf_read_ctr(i, &value);
if (rc != 0) {
send_answer(s, i, rc, 0);
@@ -174,7 +178,7 @@ static int do_print(int s, enum ctr_e ctr)
}
send_answer(s, i, ENABLED, value);
} else {
send_answer(s, i, DISABLED, 0);
send_answer(s, i, ctr_state[i], 0);
}
}
}
@@ -412,6 +416,9 @@ int main(int argc, char *argv[])
}
atexit(perf_close);
if (!perf_ecc_supported())
ctr_state[ECC_FUNCTIONS] = UNSUPPORTED;
sfd = open_socket(SERVER);
if (sfd < 0) {
eprint("Couldn't initialize server socket\n");

View File

@@ -3,36 +3,39 @@
*
* low level perf functions
*
* Copyright IBM Corp. 2015, 2017
* Copyright IBM Corp. 2015, 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <asm/unistd.h>
#include <errno.h>
#include <getopt.h>
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <perfmon/perf_event.h>
#include <perfmon/pfmlib.h>
#include <perfmon/pfmlib_perf_event.h>
#include <limits.h>
#include <linux/perf_event.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include "cpacfstats.h"
/* correlation between counter and perf counter string */
static const struct {
char pfm_name[80];
char pmu[20];
char pfm_name[60];
enum ctr_e ctr;
} pmf_counter_name[ALL_COUNTER] = {
{"cpum_cf::DEA_FUNCTIONS", DES_FUNCTIONS},
{"cpum_cf::AES_FUNCTIONS", AES_FUNCTIONS},
{"cpum_cf::SHA_FUNCTIONS", SHA_FUNCTIONS},
{"cpum_cf::PRNG_FUNCTIONS", PRNG_FUNCTIONS}
{"cpum_cf", "DEA_FUNCTIONS", DES_FUNCTIONS},
{"cpum_cf", "AES_FUNCTIONS", AES_FUNCTIONS},
{"cpum_cf", "SHA_FUNCTIONS", SHA_FUNCTIONS},
{"cpum_cf", "PRNG_FUNCTIONS", PRNG_FUNCTIONS},
{"cpum_cf", "ECC_FUNCTION_COUNT", ECC_FUNCTIONS}
};
/*
@@ -53,27 +56,106 @@ static const struct {
*/
static int *ctr_fds[ALL_COUNTER];
static int ecc_supported;
static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
int cpu, int group_fd, unsigned long flags)
{
int ret;
ret = syscall(__NR_perf_event_open, hw_event, pid, cpu,
group_fd, flags);
return ret;
}
static int perf_supported(void)
{
return !access("/proc/sys/kernel/perf_event_paranoid", R_OK);
}
static int perf_counter_supported(const char *pmu, const char *counter)
{
char buf[PATH_MAX];
if (snprintf(buf, PATH_MAX, "/sys/bus/event_source/devices/%s/events/%s",
pmu, counter) >= PATH_MAX) {
eprint("overflow in path name");
return 0;
}
return !access(buf, R_OK);
}
static int perf_event_encode(struct perf_event_attr *attr,
const char *pmu, const char *event)
{
FILE *f;
int eventid;
int pmutype;
char buf[PATH_MAX];
if (snprintf(buf, PATH_MAX, "/sys/bus/event_source/devices/%s/events/%s",
pmu, event) >= PATH_MAX) {
eprint("overflow in path name");
return -1;
}
f = fopen(buf, "r");
if (!f) {
eprint("Event %s for pmu %s not found (%d:%s)\n", event, pmu,
errno, strerror(errno));
return -1;
}
if (fscanf(f, "event=0x%x\n", &eventid) != 1) {
fclose(f);
eprint("Event file %s has invalid format\n", buf);
return -1;
}
fclose(f);
if (snprintf(buf, PATH_MAX, "/sys/bus/event_source/devices/%s/type",
pmu) >= PATH_MAX) {
eprint("overflow in path name");
return -1;
}
f = fopen(buf, "r");
if (!f) {
eprint("Event %s for pmu %s not found (%d:%s)\n", event, pmu,
errno, strerror(errno));
return -1;
}
if (fscanf(f, "%d\n", &pmutype) != 1) {
fclose(f);
eprint("Type file %s has invalid format\n", buf);
return -1;
}
attr->type = pmutype;
attr->config = eventid;
return 0;
}
int perf_init(void)
{
int i, cpus, ctr, cpu, ec, *fds;
int i, cpus, ctr, cpu, *fds;
memset(ctr_fds, 0, sizeof(ctr_fds));
/* initialize performance monitoring library */
ec = pfm_initialize();
if (ec != PFM_SUCCESS) {
eprint("Pfm_initialize() returned with failure (%d:%s)\n",
ec, pfm_strerror(ec));
if (!perf_supported()) {
eprint("Performance counter not supported");
return -1;
}
/* Check if ECC is supported on current hardware */
ecc_supported = perf_counter_supported("cpum_cf", "ECC_FUNCTION_COUNT");
/* get number of logical processors */
cpus = sysconf(_SC_NPROCESSORS_ONLN);
/* for each counter */
for (ctr = 0; ctr < ALL_COUNTER; ctr++) {
/* Skip ECC counters completely if unsupported */
if (ctr == ECC_FUNCTIONS && !ecc_supported)
continue;
/*
* allocate an array of ints to store for each CPU
* one filedescriptor + a terminating 0
@@ -88,37 +170,28 @@ int perf_init(void)
ctr_fds[ctr] = fds;
/* search for the counter's corresponding pfm name */
for (i = ALL_COUNTER-1; i >= 0; i--)
if ((int) pmf_counter_name[i].ctr == ctr)
break;
if (i < 0) {
eprint("Pfm ctr name not found for counter %d, please adjust pmf_counter_name[] in %s\n",
ctr, __FILE__);
return -1;
}
for (cpu = 0; cpu < cpus; cpu++) {
pfm_perf_encode_arg_t pfm_arg;
struct perf_event_attr pfm_event;
int fd;
memset(&pfm_arg, 0, sizeof(pfm_arg));
memset(&pfm_event, 0, sizeof(pfm_event));
pfm_arg.attr = &pfm_event;
pfm_arg.size = sizeof(pfm_arg);
pfm_event.size = sizeof(pfm_event);
/* search for the counter's corresponding pfm name */
for (i = ALL_COUNTER-1; i >= 0; i--)
if ((int) pmf_counter_name[i].ctr == ctr)
break;
if (i < 0) {
eprint("Pfm ctr name not found for counter %d, please adjust pmf_counter_name[] in %s\n",
ctr, __FILE__);
return -1;
}
/* encode the counters perf event into pfm_arg.attr */
ec = pfm_get_os_event_encoding(
pmf_counter_name[i].pfm_name,
PFM_PLM0,
PFM_OS_PERF_EVENT,
&pfm_arg);
if (ec != PFM_SUCCESS) {
eprint("Pfm_initialize() for %s failed (%d:%s)\n",
if (perf_event_encode(&pfm_event,
pmf_counter_name[i].pmu,
pmf_counter_name[i].pfm_name)) {
eprint("Failed to initialize counter %s for pmu %s\n",
pmf_counter_name[i].pfm_name,
ec, pfm_strerror(ec));
pmf_counter_name[i].pmu);
return -1;
}
@@ -257,3 +330,8 @@ int perf_read_ctr(enum ctr_e ctr, uint64_t *value)
return rc;
}
int perf_ecc_supported(void)
{
return ecc_supported;
}

View File

@@ -1,67 +1,28 @@
#!/usr/bin/make -f
include ../common.mak
CPUMF_DATADIR = $(TOOLS_DATADIR)/cpumf
DATA_FILES = cpum-cf-hw-counter.map \
cpum-cf-cfvn-1.ctr cpum-cf-cfvn-3.ctr \
cpum-cf-csvn-12345.ctr cpum-cf-csvn-6.ctr \
cpum-cf-extended-z10.ctr cpum-cf-extended-z196.ctr \
cpum-cf-extended-zEC12.ctr cpum-sf-modes.ctr \
cpum-cf-extended-z13.ctr cpum-cf-extended-z14.ctr \
cpum-cf-extended-z15.ctr
LIB_FILES = bin/cpumf_helper
USRBIN_SCRIPTS = bin/lscpumf
USRSBIN_SCRIPTS = bin/chcpumf
BIN_FILES = lscpumf chcpumf
MAN_FILES = lscpumf.1 chcpumf.8
all:
all: $(BIN_FILES)
scripts: $(USRBIN_SCRIPTS) $(USRSBIN_SCRIPTS) $(LIB_FILES)
chmod +x $(USRBIN_SCRIPTS) $(USRSBIN_SCRIPTS) $(LIB_FILES)
libs = $(rootdir)/libutil/libutil.a
check:
lscpumf: lscpumf.o $(libs)
chcpumf: chcpumf.o $(libs)
install: scripts install-man
for prg in $(USRBIN_SCRIPTS); do \
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 $$prg $(DESTDIR)$(USRBINDIR) ; \
done
for prg in $(USRSBIN_SCRIPTS); do \
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 $$prg $(DESTDIR)$(USRSBINDIR) ; \
done
test -d $(DESTDIR)$(CPUMF_DATADIR) || mkdir -p $(DESTDIR)$(CPUMF_DATADIR)
for lib in $(LIB_FILES); do \
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 $$lib $(DESTDIR)$(TOOLS_LIBDIR) ; \
done
for data in $(DATA_FILES); do \
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 data/$$data $(DESTDIR)$(CPUMF_DATADIR) ; \
install: all install-man
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man8
for binf in $(BIN_FILES); do \
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 $$binf $(DESTDIR)$(BINDIR); \
done
clean:
rm -f *.o *~ $(BIN_FILES) core
install-man:
for man in $(MAN_FILES); do \
msection=`echo $$man |sed 's/.*\.\([1-9]\)$$/man\1/'` ; \
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 -D man/$$man $(DESTDIR)$(MANDIR)/$$msection/$$man ; \
done
man2pdf:
for man in $(MAN_FILES); do \
man -t man/$$man |ps2pdf -sPAPERSIZE=a4 - man/$${man}.pdf ; \
done
man2text:
for man in $(MAN_FILES); do \
MANWIDTH=80 LANG=C man man/$$man |col -b |expand > man/$${man}.txt ; \
done
clean:
rm -f $(LIB_FILES) $(USRBIN_SCRIPTS) $(USRSBIN_SCRIPTS)
%: %.in
real_libdir=$(TOOLS_LIBDIR); \
real_cpumfdatadir=$(CPUMF_DATADIR); \
$(SED) -e "s#@lib_path@#$$real_libdir#g" \
-e "s#@cpumfdata_path@#$$real_cpumfdatadir#g" \
-e 's#@S390_TOOLS_RELEASE@#$(S390_TOOLS_RELEASE)#g' \
< $< > $@
.PHONY: all scripts install install-man man2pdf man2text clean
.PHONY: all install clean

View File

@@ -1,182 +0,0 @@
#!/usr/bin/perl -W
#
# chcpumf - Control CPU-measurement facilities
#
# Copyright IBM Corp. 2014, 2017
#
# s390-tools is free software; you can redistribute it and/or modify
# it under the terms of the MIT license. See LICENSE for details.
#
use strict;
use warnings;
use File::Basename qw/fileparse/;
use Data::Dumper;
use Getopt::Long qw/:config no_ignore_case/;
# Global constants
my $CPUMF_HELPER = '@lib_path@/cpumf_helper';
my $CPUM_SFB_SIZE = '/sys/module/kernel/parameters/cpum_sfb_size';
# Prototypes
sub main();
sub show_help();
sub show_version();
sub do_set_sfb_size($);
sub cpumf_set_sfb_size($);
sub invoke_cpumf_helper($);
sub main()
{
my $config = {
# Internal data
cpumf => {}, # CPU-MF information hash
};
unless (GetOptions(
# General options for help, version, verbose,...
"h|help" => \&show_help,
"v|version" => \&show_version,
"V|verbose+" => \$config->{verbose},
# Change specific options
"m|min=i" => \$config->{min},
"x|max=i" => \$config->{max},
)) {
print STDERR "One or more options are not valid\n";
print STDERR "Try '" . fileparse($0) .
" --help' for more information\n";
exit 1;
}
# Collect CPU-MF information
$config->{cpumf} = invoke_cpumf_helper("-i");
die "Failed to collect CPU-MF information: $!\n" unless $config->{cpumf};
# Process parameters
my $exitval = 5;
if (defined($config->{min}) || defined($config->{max})) {
$exitval = do_set_sfb_size($config);
} else {
print STDERR "You must specify a valid option\n";
exit 1;
}
exit($exitval);
}
sub show_help()
{
my $prog = fileparse($0);
print <<"EoHelp";
Usage: chcpumf -h|-v
chcpumf -m <num_sdb>
chcpumf -x <num_sdb>
Options:
-m <num_sdb> Specifies the initial size of the sampling buffer.
A sample-data-block (SDB) consumes about 4 kilobytes.
-x <num_sdb> Specifies the maximum size of the sampling buffer.
A sample-data-block (SDB) consumes about 4 kilobytes.
-h Displays help information, then exits.
-v Displays version information, then exits.
For more help information, issue 'man $prog'.
EoHelp
exit 0;
}
sub show_version()
{
print <<'EoVersion';
CPU-measurement facility utilities, version @S390_TOOLS_RELEASE@
Copyright IBM Corp. 2014, 2017
EoVersion
exit 0;
}
sub cpumf_set_sfb_size($)
{
my @size = @{shift()};
my $val = join ',', @size[0,1];
my ($SFBSIZE, $rc);
return undef unless open($SFBSIZE, '>', $CPUM_SFB_SIZE);
# Check the return code of print and close to detect error conditions
# reported by the device driver. Because perl might buffer data, print
# might be successful, but close might then report the error condition.
# So check the return code of both functions and always close the file
# handle.
$rc = print { $SFBSIZE } "$val\n";
unless ($rc) {
close($SFBSIZE);
return $rc;
}
return close($SFBSIZE);
}
sub do_set_sfb_size($)
{
my $c = shift();
my $size;
# Check if sampling facility is available
unless (exists $c->{cpumf}->{sf}) {
print STDERR "No CPU-measurement sampling facility detected\n";
return 2;
}
# Check if perf support is available
unless (exists $c->{cpumf}->{sf}->{perf}) {
print STDERR "No perf support for the CPU-measurement" .
" sampling facility availalble\n";
return 2;
}
# Optionally, change the sampling buffer sizes
if (defined($c->{min}) || defined($c->{max})) {
$size = invoke_cpumf_helper("--sfb-size");
# Use current size value for zero min/max specifications
$size->[0] = $c->{min} if defined($c->{min});
$size->[1] = $c->{max} if defined($c->{max});
# Validate new settings
if ($size->[0] < 1 || $size->[1] < 1) {
die "The specified number(s) are not valid\n";
}
if ($size->[0] >= $size->[1]) {
die "The specified maximum must be greater " .
"than the minimum\n";
}
# Set new sampling buffer sizes
unless (cpumf_set_sfb_size($size)) {
die "Failed to change sampling buffer size: $!\n";
}
}
# Finally, show sampling buffer sizes
if ($c->{verbose}) {
$size = invoke_cpumf_helper("--sfb-size");
print "Sampling buffer sizes:\n";
printf " Minimum: %6u sample-data-blocks\n", $size->[0];
printf " Maximum: %6u sample-data-blocks\n", $size->[1];
}
return 0;
}
sub invoke_cpumf_helper($)
{
my $parms = shift();
my $result;
# Call helper module
my $output = qx"$CPUMF_HELPER $parms";
die "Failed to run helper module for '$parms'\n" if $? >> 8;
$result = eval "$output";
die "Failed to parse helper module data\n" if $@;
return $result;
}
&main();
__DATA__
__END__

View File

@@ -1,489 +0,0 @@
#!/usr/bin/perl -W
#
# cpumf_helper - Helper module for managing CPU-measurement facilities (CPU-MF)
#
# Copyright IBM Corp. 2014, 2017
#
# s390-tools is free software; you can redistribute it and/or modify
# it under the terms of the MIT license. See LICENSE for details.
#
use strict;
use warnings;
use Carp qw/croak/;
use Data::Dumper;
use Getopt::Long qw/:config no_ignore_case/;
# Global constants
my $SERVICE_LEVELS = '/proc/service_levels';
my $CPUMF_DATA_DIR = '@cpumfdata_path@';
my $CPUM_SFB_SIZE = '/sys/module/kernel/parameters/cpum_sfb_size';
my $CPUM_SF_DBF='/sys/kernel/debug/s390dbf/cpum_sf';
# Counter set bits (according to QUERY COUNTER INFORMATION)
my $BASIC_SET = 0x0002;
my $PROBLEM_STATE_SET = 0x0004;
my $CRYPTO_SET = 0x0008;
my $EXTENTED_SET = 0x0001;
my $MT_DIAG_SET = 0x0020;
my $COPROC_GRP_SET = 0x8000;
# Public prototypes
sub cpumf_collect_data();
sub cpumf_get_sfb_size();
sub cpumf_set_sfb_size($);
sub cpumf_parse_ctrdef($;$);
sub cpumf_load_ctrdef($;$);
sub cpumf_get_counter_set($);
sub cpumf_counter_set_names();
sub cpumf_counter_set_ids();
sub cpumf_hardware_counter_map();
# Internal prototypes
sub cpumf_parse_cf($$);
sub cpumf_parse_sf($$);
sub cpumf_get_sfb_size()
{
my $val = "0,0";
my $SFBSIZE;
if (open($SFBSIZE, '<', $CPUM_SFB_SIZE)) {
$val = <$SFBSIZE>;
chomp($val);
close($SFBSIZE);
}
return [split /,/, $val];
}
sub cpumf_set_sfb_size($)
{
my @size = @{shift()};
my $val = join ',', @size[0,1];
my ($SFBSIZE, $rc);
return undef unless open($SFBSIZE, '>', $CPUM_SFB_SIZE);
# Check the return code of print and close to detect error conditions
# reported by the device driver. Because perl might buffer data, print
# might be successful, but close might then report the error condition.
# So check the return code of both functions and always close the file
# handle.
$rc = print { $SFBSIZE } "$val\n";
unless ($rc) {
close($SFBSIZE);
return $rc;
}
return close($SFBSIZE);
}
sub cpumf_parse_cf($$)
{
my ($ent, $data) = @_;
if ($ent =~ /version=([0-9.]+) authorization=([[:xdigit:]]+)/) {
$data->{cf} = { version => $1, auth => hex($2) };
}
}
sub cpumf_parse_sf($$)
{
my ($ent, $data) = @_;
# Parse common sampling facility entry
if ($ent =~ /min_rate=(\d+) max_rate=(\d+) cpu_speed=(\d+)/) {
$data->{sf} = {
min_sampl_interval => $1,
max_sampl_interval => $2,
cpu_speed => $3,
# This contains a list of authorized sampling modes, for
# example, basic
modes => {},
};
}
# Parse sampling facility mode entries
if ($ent =~ /mode=(\w+) sample_size=(\d+)/) {
$data->{sf}->{modes}->{$1}->{sample_size} = $2;
}
}
sub cpumf_collect_data()
{
my $SL;
# Collect CPU-MF information from /proc/service_levels
return undef unless open($SL, '<', $SERVICE_LEVELS);
my @sl = <$SL>;
chomp(@sl);
close($SL);
# Process CPU-MF information and build data hash
my $data = {};
foreach my $ent (@sl) {
$ent =~ s/^CPU-MF: // or next;
cpumf_parse_cf($ent, $data) if $ent =~ s/Counter facility: //;
cpumf_parse_sf($ent, $data) if $ent =~ s/Sampling facility: //;
}
# Collect perf support for available facilities
if (-e '/sys/bus/event_source/devices/cpum_cf') {
$data->{cf}->{perf} = "cpum_cf" if exists $data->{cf};
}
if (-e '/sys/bus/event_source/devices/cpum_sf') {
$data->{sf}->{perf} = "cpum_sf" if exists $data->{sf};
}
return $data;
}
# Parse the specified counter definition file and returns a hash containing
# the parsed counter definition. The optional argument specifies a hash
# reference to which the new definitions are added. This reference is returned.
sub cpumf_parse_ctrdef($;$)
{
my $ctrdef = shift();
my $h = @_ ? shift() : {};
my $CTRDEF;
return undef unless open($CTRDEF, '<', "$CPUMF_DATA_DIR/$ctrdef");
my ($ctr, $name);
while (my $line = <$CTRDEF>) {
next if $line =~ /^#/;
chomp($line);
# Parse start of counter definition entry
if ($line =~ m/^Counter:\s*(0x[[:xdigit:]]+|\d+)
\s+Name:\s*([[:alnum:]_]+)$/x) {
($ctr, $name) = ($1, $2);
$ctr = hex($ctr) if $ctr =~ /^0x/;
unless (length($ctr)) {
print STDERR "Found invalid entry in counter " .
"definition: line $.\n";
}
$h->{$ctr} = { name => $name || "" };
}
# At this point, a counter must be defined
next unless defined($ctr);
# Parse short description (optional)
if ($line =~ m/^Short-Description:\s*(\S.*)?$/) {
$h->{$ctr}->{shortdesc} = $1 || "";
# Parse start of counter description
} elsif ($line =~ m/^Description:\s*(\S.*)?$/) {
$h->{$ctr}->{desc} = $1 || "";
# Parse end of counter description
} elsif ($line =~ m/^\.$/) {
# Complete the counter definition
$h->{$ctr}->{set} = cpumf_get_counter_set($ctr);
# Trim whitespaces
$h->{$ctr}->{shortdesc} =~ s/^\s+|\s+$//g if $h->{$ctr}->{shortdesc};
$h->{$ctr}->{desc} =~ s/^\s+|\s+$//g if $h->{$ctr}->{desc};
# Finally, reset counter for next entry
$ctr = undef;
# Line is part of counter description (if $ctr_num is set)
} else {
$h->{$ctr}->{desc} .= " $line";
}
}
close($CTRDEF);
return $h;
}
# IBM System z hardware with CPU-M counter facility support
my $system_z_hwtype_map = {
# Machine type Description
'' => 'Unknown hardware model',
2097 => 'IBM System z10 EC',
2098 => 'IBM System z10 BC',
2817 => 'IBM zEnterprise 196',
2818 => 'IBM zEnterprise 114',
2827 => 'IBM zEnterprise EC12',
2828 => 'IBM zEnterprise BC12',
2964 => 'IBM z13',
2965 => 'IBM z13s',
3906 => 'IBM z14',
3907 => 'IBM z14 ZR1',
8561 => 'IBM z15',
};
sub get_hardware_type()
{
my $type = "";
my $SYSINFO;
return undef unless open($SYSINFO, '<', '/proc/sysinfo');
while (my $line = <$SYSINFO>) {
if ($line =~ m/^Type:\s*(\d+)\s*$/) {
$type = $1;
last;
}
}
close($SYSINFO);
return $type;
}
sub get_cpum_cf_version()
{
my $SL;
my $v = {
cfvn => 0,
csvn => 0,
};
return $v unless open($SL, '<', $SERVICE_LEVELS);
while (my $line = <$SL>) {
# CPU-MF: Counter facility: version=3.5
if ($line =~ m/^CPU-MF: Counter facility: version=(\d+)\.(\d+)/) {
$v->{cfvn} = $1; # Counter First Version Number
$v->{csvn} = $2; # Counter Second Version Number
last;
}
}
close($SL);
return $v
}
sub cpumf_load_ctrdef($;$)
{
my $hw_type = shift();
my $authorized = @_ ? shift() : 0xffff; # Counter Set authorization
my $ctrmap = cpumf_hardware_counter_map();
return unless $ctrmap;
# Obtain CPU-MF counter facility versions
my $version = get_cpum_cf_version();
# List of "generic" counter sets
my @def = ();
push @def, "cfvn-" . $version->{cfvn};
if ($version->{csvn} >= 1 && $version->{csvn} <= 6) {
push @def, "csvn-12345";
}
if ($version->{csvn} == 6) {
push @def, "csvn-6";
}
my $h = {};
# Load counter set definition
foreach my $ent (@def) {
cpumf_parse_ctrdef($ctrmap->{$ent}, $h) or
croak "Failed to read counter definition for $ent: $!\n";
}
# Load hardware model specific counter set(s)
if ($hw_type && $ctrmap->{$hw_type}) {
# Hardware-model specific counter sets are:
# - Extended Counter Set
# - MT-diagnostic Counter Set
cpumf_parse_ctrdef($ctrmap->{$hw_type}, $h) or
croak "Failed to read hardware-model counter definition: $!\n";
}
# Remove counter sets that miss authorizations
my @no_auth_list = ();
foreach my $ctr (sort keys %$h) {
push @no_auth_list, $ctr unless $h->{$ctr}->{set} & $authorized;
}
delete $h->{$_} foreach (@no_auth_list);
return $h;
}
sub cpumf_get_counter_set($)
{
my $ctr = shift();
return $BASIC_SET if $ctr < 32;
return $PROBLEM_STATE_SET if $ctr < 64;
return $CRYPTO_SET if $ctr < 128;
#
# The extended counter set ranges from
# 128 to
# 159 for csvn == 1
# 175 for csvn == 2
# 255 for csvn > 2
# Tolerate any future counters up to
# the MT-diagnostic counter set.
return $EXTENTED_SET if $ctr < 448;
#
# The MT-diagnostic counter set ranges from
# 448 to
# 495 for cvsn > 3
return $MT_DIAG_SET if $ctr <= 495;
return 0;
}
sub cpumf_counter_set_names()
{
return {
# Identifier Name
$BASIC_SET => 'Basic Counter Set',
$PROBLEM_STATE_SET => 'Problem-State Counter Set',
$CRYPTO_SET => 'Crypto-Activity Counter Set',
$EXTENTED_SET => 'Extended Counter Set',
$MT_DIAG_SET => 'MT-diagnostic Counter Set',
$COPROC_GRP_SET => 'Coprocessor Group Counter Set',
};
}
sub cpumf_counter_set_ids()
{
return [$BASIC_SET, $PROBLEM_STATE_SET, $CRYPTO_SET, $EXTENTED_SET,
$MT_DIAG_SET, $COPROC_GRP_SET];
}
sub cpumf_hardware_counter_map()
{
my $map = do "$CPUMF_DATA_DIR/cpum-cf-hw-counter.map";
croak "Failed to parse mapfile: $@" if $@;
croak "Failed to read mapfile: $!" unless defined $map;
return $map;
}
my $cpumf_helper_str = <<'END_MESSAGE';
cpumf_helper - Helper module for managing CPU-Measurement Facilities (CPU-MF)
Options:
-i, --info:
Displays detailed information about installed and available
CPU-measurement facilities and the related Linux support.
-c, --counter authorization_value
Displays counter information for the current System z hardware.
The authorization value provides information about the authorized
counter sets. The value must be specified in decimal format.
To display all supported counters, specify C<65535> (FFFF hex).
To display supported counters for a particular System z hardware,
use the --ctr-def option and specify the System z hardware type.
--hardware-type
Displays the System z hardware type.
--ctr-def ctr-definition
Displays detailed information about the specified counter definition.
Valid counter definitions start with C<cfvn-> or <csvn-> followed by
the counter first/second version number of the CPU-Measurement Counter
Facility. To display counter information of model-specific counter
sets, specify the System z hardware type for I<ctr-definition>.
--ctr-set-names
Displays the mapping of counter set IDs to counter set names.
The counter set IDs are numbers that are used in counter definitions.
--ctr-set-ids
Displays the counter set IDs. The counter set IDs are numbers that
match the authorization bits (see QUERY COUNTER INFORMATION).
The output format is a list. To get the ID for a particular counter
set, use an index number as follows:
0: Basic Counter Set
1: Problem-State Counter Set
2: Crypto-Activity Counter Set
3: Extended Counter Set
4: MT-diagnostic Counter Set
5: Coprocessor Group Counter Set
--ctr-sf
Displays the counter definitions for the sampling facility support.
These counter definitions are specific to Linux perf infrastructure.
--sfb-size
Displays the size of the sampling facility buffer (SFB). The minimum
and maximum numbers are measured in units of sample-data-blocks. A
sample-data-block uses about 4 kilobytes.
END_MESSAGE
sub cpumf_helper_main()
{
# Configuration settings and options
my $conf = {
};
# Parse command line option
GetOptions(
"i|info" => \$conf->{opt_info},
"c|counter=i" => \$conf->{opt_ctr},
"ctr-def=s" => \$conf->{opt_ctrdef},
"hardware-type" => \$conf->{opt_hwtype},
"ctr-set-names" => \$conf->{opt_ctrset_names},
"ctr-set-ids" => \$conf->{opt_ctrset_ids},
"sfb-size" => \$conf->{opt_sfb_size},
"ctr-sf" => \$conf->{opt_sf_ctr},
) or die("One or more options are not valid\n" . $cpumf_helper_str);
# Setting up Data::Dumper to create parseable Perl output
local $Data::Dumper::Purity = 1;
local $Data::Dumper::Sortkeys = 1;
local $Data::Dumper::Terse = 1;
###print STDERR "CONF: " . Dumper($conf) . "\n";
# Process command line options
my $exitval = 0;
my $result;
if (defined($conf->{opt_info})) {
$result = cpumf_collect_data();
# Display System z hardware type
} elsif (defined($conf->{opt_hwtype})) {
my $type = get_hardware_type();
$result = [$type, $system_z_hwtype_map->{$type} || ""];
# Display counters for current System z hardware
} elsif (defined($conf->{opt_ctr})) {
my $type = get_hardware_type();
$type = 0 unless $type;
$result = cpumf_load_ctrdef($type, $conf->{opt_ctr});
# Display counters for a particular System z hardware type
} elsif (defined($conf->{opt_ctrdef})) {
my $m = cpumf_hardware_counter_map();
if (exists $m->{$conf->{opt_ctrdef}}) {
$result = cpumf_parse_ctrdef($m->{$conf->{opt_ctrdef}});
} else {
printf STDERR "Invalid counter definition\n";
$exitval = 2;
}
# Display the size of the sampling facility buffer (sfb)
} elsif (defined($conf->{opt_sfb_size})) {
$result = cpumf_get_sfb_size();
# Display counter definitions for the sampling facility support (perf)
} elsif (defined($conf->{opt_sf_ctr})) {
$result = cpumf_parse_ctrdef('cpum-sf-modes.ctr');
# Display mapping of counter set IDs to counter set names
} elsif (defined($conf->{opt_ctrset_names})) {
$result = cpumf_counter_set_names();
# Display counter set IDs
} elsif (defined($conf->{opt_ctrset_ids})) {
$result = cpumf_counter_set_ids();
} else {
die("No option specified\n" . $cpumf_helper_str);
}
# Display result
print Dumper($result) if $result;
exit $exitval;
}
&cpumf_helper_main();
__DATA__
__END__

View File

@@ -1,387 +0,0 @@
#!/usr/bin/perl -W
#
# lscpumf - Display information about CPU-measurement facilities
#
# Copyright IBM Corp. 2014, 2017
#
# s390-tools is free software; you can redistribute it and/or modify
# it under the terms of the MIT license. See LICENSE for details.
#
use strict;
use warnings;
use Data::Dumper;
use File::Basename qw/fileparse/;
use Getopt::Long qw/:config no_ignore_case/;
# Global constants
my $CPUMF_HELPER = '@lib_path@/cpumf_helper';
# Prototypes
sub main();
sub show_help();
sub show_version();
sub do_show_info($);
sub do_show_cf($);
sub do_show_sf($);
sub do_show_ctr($;$);
sub do_show_sf_events($);
sub invoke_cpumf_helper($);
sub main()
{
my $config = {
# Internal data
cpumf => {}, # CPU-MF information hash
};
unless (GetOptions(
# General options for help, version,...
"h|help" => \&show_help,
"v|version" => \&show_version,
# Display options
"i|info" => \$config->{opt_info},
"c|list-counters" => \$config->{opt_ctr},
"C|list-all-counters" => \$config->{opt_ctr_all},
"s|list-sampling-events" => \$config->{opt_ctr_sf},
)) {
print STDERR "One or more options are not valid\n";
print STDERR "Try '" . fileparse($0) .
" --help' for more information\n";
exit 1;
}
# Collect CPU-MF information
$config->{cpumf} = invoke_cpumf_helper("-i");
die "Failed to collect CPU-MF information: $!\n" unless $config->{cpumf};
# Process parameters
my $exitval = 5;
if (defined($config->{opt_info})) {
do_show_cf($config);
do_show_sf($config);
$exitval = 0;
} elsif (defined($config->{opt_ctr})) {
$exitval = do_show_ctr($config);
} elsif (defined($config->{opt_ctr_all})) {
$exitval = do_show_ctr($config, "all")
} elsif (defined($config->{opt_ctr_sf})) {
$exitval = do_show_sf_events($config);
} else {
$exitval = do_show_info($config);
}
exit($exitval);
}
sub show_help()
{
my $prog = fileparse($0);
print <<"EoHelp";
Usage: lscpumf -h|-v
lscpumf [-i]
lscpumf -c|-C
Options:
-i Displays detailed information.
-c Lists counters for which the LPAR is authorized.
-C Lists counters regardless of LPAR authorization.
-s Lists perf raw events that activate the sampling facility.
-h Displays help information, then exits.
-v Displays version information, then exits.
For more help information, issue 'man $prog'.
EoHelp
exit 0;
}
sub show_version()
{
print <<'EoVersion';
CPU-measurement facility utilities, version @S390_TOOLS_RELEASE@
Copyright IBM Corp. 2014, 2017
EoVersion
exit 0;
}
sub do_show_info($)
{
my $c = shift();
my $cpumf = $c->{cpumf};
my @f = ();
push @f, "CPU-measurement Counter Facility" if exists $cpumf->{cf};
push @f, "CPU-measurement Sampling Facility" if exists $cpumf->{sf};
if (@f) {
print((join "\n", @f) . "\n");
} else {
print STDERR "No CPU-measurement facilities detected\n";
return 2;
}
return 0;
}
sub do_show_cf($)
{
my $c = shift();
# Check if counter facility is available
unless (exists $c->{cpumf}->{cf}) {
print STDERR "No CPU-measurement counter facility detected\n";
return 2;
}
# Retrieve counter facility information
my $cf = $c->{cpumf}->{cf};
# Create list of authorized counter sets
my @sets = ();
push @sets, "None" unless $cf->{auth};
push @sets, "Crypto-Activity counter set" if $cf->{auth} & 0x8;
push @sets, "Problem-State counter set" if $cf->{auth} & 0x4;
push @sets, "Basic counter set" if $cf->{auth} & 0x2;
push @sets, "Extented counter set" if $cf->{auth} & 0x1;
push @sets, "MT-diagnostic counter set" if $cf->{auth} & 0x20;
print "CPU-measurement counter facility\n";
print "-" x 74 . "\n";
# TODO Display additional information about available conters depending
# on the version information
print "Version: " . $cf->{version} . "\n";
print "\n";
print "Authorized counter sets:\n";
print " $_\n" foreach (sort @sets);
printf "\nLinux perf event support: %s\n\n",
exists $cf->{perf} ? "Yes (PMU: $cf->{perf})" : "No";
return 0;
}
sub div_ceil($$)
{
my ($a, $b) = @_;
return int(($a + $b - 1) / $b);
}
sub humanize_bytes($;$)
{
my $bytes = shift();
my @units = split //, " KMGTPEZY";
my $u = @_ ? shift() : 0;
while ($bytes >= 1024 && $u <= $#units) {
$bytes /= 1024;
$u++;
}
return sprintf "%.f%sB", $bytes, $units[$u];
}
sub get_sfb_details($)
{
my $n_sdb = shift();
# Calculate sampling buffer structure
my $n_sdbt = div_ceil($n_sdb, 511);
my $n_pages = $n_sdb + $n_sdbt;
return [
$n_sdb, # number of sample-data-blocks
$n_sdbt, # number of sample-data-block-tables
$n_pages, # number of 4K pages
$n_pages * 4096, # size in bytes
];
}
sub do_show_sf($)
{
my $c = shift();
# Check if sampling facility is available
unless (exists $c->{cpumf}->{sf}) {
print STDERR "No CPU-measurement sampling facility detected\n";
return 2;
}
my $sf = $c->{cpumf}->{sf};
my $size = invoke_cpumf_helper("--sfb-size");
# Sampling facility information
print "CPU-measurement sampling facility\n";
print "-" x 74 . "\n";
print "Sampling Interval:\n";
printf " Minimum: %10u cycles (approx. %8u Hz)\n",
$sf->{min_sampl_interval},
1000000 * $sf->{cpu_speed} / $sf->{min_sampl_interval};
printf " Maximum: %10u cycles (approx. %8u Hz)\n",
$sf->{max_sampl_interval},
1000000 * $sf->{cpu_speed} / $sf->{max_sampl_interval};
print "\n";
print "Authorized sampling modes:\n";
foreach my $m (sort keys %{$sf->{modes}}) {
printf " %-10s (sample size: %3u bytes)\n", $m,
$sf->{modes}->{$m}->{sample_size};
}
print "\n";
printf "\nLinux perf event support: %s\n\n",
exists $sf->{perf} ? "Yes (PMU: $sf->{perf})" : "No";
# Sampling buffer settings for cpum_sf
goto out unless exists $sf->{perf};
print "Current sampling buffer settings for $sf->{perf}:\n";
printf " Basic-sampling mode\n";
my $s = get_sfb_details($size->[0]);
printf " Minimum: %6u sample-data-blocks (%6s)\n",
$s->[0], humanize_bytes($s->[3]);
$s = get_sfb_details($size->[1]);
printf " Maximum: %6u sample-data-blocks (%6s)\n",
$s->[0], humanize_bytes($s->[3]);
unless (exists $sf->{modes}->{diagnostic}) {
goto out;
}
# Sampling buffer setting specific to diagnostic-sampling mode
my $f_diag = div_ceil($sf->{modes}->{diagnostic}->{sample_size},
$sf->{modes}->{basic}->{sample_size});
print "\n";
printf " Diagnostic-sampling mode (including basic-sampling)\n";
$s = get_sfb_details($size->[0] * $f_diag);
printf " Minimum: %6u sample-data-blocks (%6s)\n",
$s->[0], humanize_bytes($s->[3]);
$s = get_sfb_details($size->[1] * $f_diag);
printf " Maximum: %6u sample-data-blocks (%6s)\n",
$s->[0], humanize_bytes($s->[3]);
printf " Size factor: %2u\n", $f_diag;
out:
return 0;
}
sub print_counters($$)
{
my ($ctrdef, $header) = @_;
my $set_name_map = invoke_cpumf_helper('--ctr-set-names');
my $out = [];
my ($ctr_perf, $ctr_num, $set, $name, $desc);
format PERF_CTR_FORM =
r@<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$ctr_perf, $name
^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$desc
^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
$desc
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$set
.
print $header;
$~ = "PERF_CTR_FORM";
foreach my $ctr (sort { $a <=> $b } keys %$ctrdef) {
$ctr_perf = sprintf "%x", $ctr;
$ctr_num = $ctr < (1 << 16) ? $ctr : "";
$name = $ctrdef->{$ctr}->{name};
$desc = $ctrdef->{$ctr}->{shortdesc} ?
$ctrdef->{$ctr}->{shortdesc}
: $ctrdef->{$ctr}->{desc};
$desc .= ".";
$set = $set_name_map->{$ctrdef->{$ctr}->{set}};
if ($set) {
$set = "Counter $ctr_num / $set.";
} else {
$set = "This event is not associated with a counter set.";
}
write;
}
}
sub do_show_ctr($;$)
{
my $c = shift();
# Check if counter facility is available
unless (exists $c->{cpumf}->{cf}) {
print STDERR "No CPU-measurement counter facility detected\n";
return 2;
}
# Retrieve counter authorization ("all" or authorized counters only)
my $auth = @_ ? hex("0xFFFF") : $c->{cpumf}->{cf}->{auth};
# Retrieve counter information
my $ctrs = invoke_cpumf_helper("-c $auth");
unless ($ctrs) {
print STDERR "No counters are available or authorized\n";
return 3;
}
# Retrieve hardware type
my $hwtype = invoke_cpumf_helper("--hardware-type");
my $model = length $hwtype->[1] ? "for $hwtype->[1]" : "";
my $header = <<"EoHeader";
Perf event counter list $model
==============================================================================
Raw
event Name Description
------------------------------------------------------------------------------
EoHeader
print_counters($ctrs, $header);
return 0;
}
sub do_show_sf_events($)
{
my $c = shift();
# Check if sampling facility is available
unless (exists $c->{cpumf}->{sf}) {
print STDERR "No CPU-measurement sampling facility detected\n";
return 2;
}
my $sf = $c->{cpumf}->{sf};
my $events = invoke_cpumf_helper("--ctr-sf");
# Remove events with missing authorization
delete $events->{0xB0000} unless exists $sf->{modes}->{basic};
delete $events->{0xBD000} unless exists $sf->{modes}->{diagnostic};
unless ($events) {
print STDERR "Sampling facility is not authorized\n";
return 3;
}
# Display sampling facility events (aka. counters)
my $header = <<"EoHeader";
Perf events for activating the sampling facility
==============================================================================
Raw
event Name Description
------------------------------------------------------------------------------
EoHeader
print_counters($events, $header);
return 0;
}
sub invoke_cpumf_helper($)
{
my $parms = shift();
my $result;
# Call helper module
my $output = qx"$CPUMF_HELPER $parms";
die "Failed to run helper module for '$parms'\n" if $? >> 8;
$result = eval "$output";
die "Failed to parse helper module data\n" if $@;
return $result;
}
&main();
__DATA__
__END__

215
cpumf/chcpumf.c Normal file
View File

@@ -0,0 +1,215 @@
/*
* chcpumf - Change CPU Measurement Facility Characteristics
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include "lib/util_opt.h"
#include "lib/util_prg.h"
#include "lib/util_base.h"
#include "defines.h"
static int verbose;
static unsigned long min_sdb, max_sdb;
static struct util_opt opt_vec[] = {
UTIL_OPT_SECTION("OPTIONS"),
{
.option = { "min", required_argument, NULL, 'm' },
.argument = "num_sdb",
.desc = "Specifies the initial size of the sampling buffer.\n"
"A sample-data-block (SDB) consumes about 4 kilobytes.",
},
{
.option = { "max", required_argument, NULL, 'x' },
.argument = "num_sdb",
.desc = "Specifies the maximum size of the sampling buffer.\n"
"A sample-data-block (SDB) consumes about 4 kilobytes.",
},
{
.option = { "verbose", no_argument, NULL, 'V' },
.desc = "Verbose, display new sample-data-block values.",
},
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
static const struct util_prg prg = {
.desc = "Change CPU Measurement facility charactertics",
.copyright_vec = {
{
.owner = "IBM Corp.",
.pub_first = 2020,
.pub_last = 2020,
},
UTIL_PRG_COPYRIGHT_END
}
};
static long parse_buffersize(char *string)
{
char *suffix;
long bytes;
bytes = strtol(string, &suffix, 10);
if (strlen(suffix) > 1)
return -1;
switch (*suffix) {
case 'k':
case 'K':
bytes *= 1024;
break;
case 'm':
case 'M':
bytes *= 1048576;
break;
case '\0':
break;
default:
return 0;
}
return bytes;
}
static int read_sfb(unsigned long *min, unsigned long *max)
{
unsigned long cur_min_sdb, cur_max_sdb;
int rc = EXIT_SUCCESS;
FILE *fp;
fp = fopen(PERF_SFB_SIZE, "r");
if (fp == NULL) {
linux_error(PERF_SFB_SIZE);
return EXIT_FAILURE;
}
if (fscanf(fp, "%ld,%ld", &cur_min_sdb, &cur_max_sdb) != 2) {
fprintf(stderr, "Error: Can not parse file " PERF_SFB_SIZE);
rc = EXIT_FAILURE;
} else {
if (*min == 0)
*min = cur_min_sdb;
if (*max == 0)
*max = cur_max_sdb;
}
fclose(fp);
return rc;
}
static int write_sfb(unsigned long min, unsigned long max)
{
int rc = EXIT_SUCCESS;
char text[64];
size_t len;
FILE *fp;
fp = fopen(PERF_SFB_SIZE, "w");
if (fp == NULL) {
linux_error(PERF_SFB_SIZE);
return EXIT_FAILURE;
}
snprintf(text, sizeof text, "%ld,%ld", min, max);
len = strlen(text) + 1;
if (fwrite(text, 1, len, fp) != len) {
linux_error(PERF_SFB_SIZE);
rc = EXIT_FAILURE;
}
if (fclose(fp)) {
linux_error(PERF_SFB_SIZE);
rc = EXIT_FAILURE;
}
if (verbose && rc != EXIT_FAILURE)
fprintf(stderr, "Sampling buffer sizes:\n"
" Minimum:%7ld sample-data-blocks\n"
" Maximum:%7ld sample-data-blocks\n",
min, max);
return rc;
}
static int parse_args(int argc, char **argv)
{
int opt, action = 0;
long new;
while ((opt = util_opt_getopt_long(argc, argv)) != -1) {
switch (opt) {
case 'h':
util_prg_print_help();
util_opt_print_help();
exit(EXIT_SUCCESS);
case 'v':
util_prg_print_version();
exit(EXIT_SUCCESS);
case 'x':
new = parse_buffersize(optarg);
if (new < 1) {
fprintf(stderr, "The specified number(s)"
" are not valid\n");
exit(EXIT_FAILURE);
}
max_sdb = new;
action = 1;
break;
case 'm':
new = parse_buffersize(optarg);
if (new < 1) {
fprintf(stderr, "The specified number(s)"
" are not valid\n");
exit(EXIT_FAILURE);
}
min_sdb = new;
action = 1;
break;
case 'V':
verbose = 1;
break;
case '?':
fprintf(stderr, "One or more options are not valid\n");
fprintf(stderr, "Try 'chcpumf --help' for more"
" information\n");
exit(EXIT_FAILURE);
}
}
if (!action) {
fprintf(stderr, "You must specify a valid option\n");
exit(EXIT_FAILURE);
}
return action;
}
int main(int argc, char **argv)
{
int ret = EXIT_FAILURE;
struct stat sbuf;
util_prg_init(&prg);
util_opt_init(opt_vec, NULL);
parse_args(argc, argv);
if (stat(PERF_PATH PERF_SF, &sbuf) != 0) {
fprintf(stderr,
"No CPU-measurement sampling facility detected\n");
return ret;
}
if (read_sfb(&min_sdb, &max_sdb))
return ret;
if (min_sdb >= max_sdb) {
fprintf(stderr, "The specified maximum must be greater "
"than the minimum\n");
return ret;
}
return write_sfb(min_sdb, max_sdb);
}

View File

@@ -1,60 +0,0 @@
Counter: 0 Name:CPU_CYCLES
Short-Description:CPU Cycles
Description:
Cycle Count
.
Counter: 1 Name:INSTRUCTIONS
Short-Description:Instructions
Description:
Instruction Count
.
Counter: 2 Name:L1I_DIR_WRITES
Short-Description:L1I Directory Writes
Description:
Level-1 I-Cache Directory Write Count
.
Counter: 3 Name:L1I_PENALTY_CYCLES
Short-Description:L1I Penalty Cycles
Description:
Level-1 I-Cache Penalty Cycle Count
.
Counter: 4 Name:L1D_DIR_WRITES
Short-Description:L1D Directory Writes
Description:
Level-1 D-Cache Directory Write Count
.
Counter: 5 Name:L1D_PENALTY_CYCLES
Short-Description:L1D Penalty Cycles
Description:
Level-1 D-Cache Penalty Cycle Count
.
Counter: 32 Name:PROBLEM_STATE_CPU_CYCLES
Short-Description:Problem-State CPU Cycles
Description:
Problem-State Cycle Count
.
Counter: 33 Name:PROBLEM_STATE_INSTRUCTIONS
Short-Description:Problem-State Instructions
Description:
Problem-State Instruction Count
.
Counter: 34 Name:PROBLEM_STATE_L1I_DIR_WRITES
Short-Description:Problem-State L1I Directory Writes
Description:
Problem-State Level-1 I-Cache Directory Write Count
.
Counter: 35 Name:PROBLEM_STATE_L1I_PENALTY_CYCLES
Short-Description:Problem-State L1I Penalty Cycles
Description:
Problem-State Level-1 I-Cache Penalty Cycle Count
.
Counter: 36 Name:PROBLEM_STATE_L1D_DIR_WRITES
Short-Description:Problem-State L1D Directory Writes
Description:
Problem-State Level-1 D-Cache Directory Write Count
.
Counter: 37 Name:PROBLEM_STATE_L1D_PENALTY_CYCLES
Short-Description:Problem-State L1D Penalty Cycles
Description:
Problem-State Level-1 D-Cache Penalty Cycle Count
.

View File

@@ -1,40 +0,0 @@
Counter: 0 Name:CPU_CYCLES
Short-Description:CPU Cycles
Description:
Cycle Count
.
Counter: 1 Name:INSTRUCTIONS
Short-Description:Instructions
Description:
Instruction Count
.
Counter: 2 Name:L1I_DIR_WRITES
Short-Description:L1I Directory Writes
Description:
Level-1 I-Cache Directory Write Count
.
Counter: 3 Name:L1I_PENALTY_CYCLES
Short-Description:L1I Penalty Cycles
Description:
Level-1 I-Cache Penalty Cycle Count
.
Counter: 4 Name:L1D_DIR_WRITES
Short-Description:L1D Directory Writes
Description:
Level-1 D-Cache Directory Write Count
.
Counter: 5 Name:L1D_PENALTY_CYCLES
Short-Description:L1D Penalty Cycles
Description:
Level-1 D-Cache Penalty Cycle Count
.
Counter: 32 Name:PROBLEM_STATE_CPU_CYCLES
Short-Description:Problem-State CPU Cycles
Description:
Problem-State Cycle Count
.
Counter: 33 Name:PROBLEM_STATE_INSTRUCTIONS
Short-Description:Problem-State Instructions
Description:
Problem-State Instruction Count
.

View File

@@ -1,100 +0,0 @@
Counter: 64 Name:PRNG_FUNCTIONS
Short-Description:PRNG Functions
Description:
Total number of the PRNG functions issued by the CPU
.
Counter: 65 Name:PRNG_CYCLES
Short-Description:PRNG Cycles
Description:
Total number of CPU cycles when the DEA/AES coprocessor is busy
performing PRNG functions issued by the CPU
.
Counter: 66 Name:PRNG_BLOCKED_FUNCTIONS
Short-Description:PRNG Blocked Functions
Description:
Total number of the PRNG functions that are issued by the CPU and are
blocked because the DEA/AES coprocessor is busy performing a function
issued by another CPU
.
Counter: 67 Name:PRNG_BLOCKED_CYCLES
Short-Description:PRNG Blocked Cycles
Description:
Total number of CPU cycles blocked for the PRNG functions issued by
the CPU because the DEA/AES coprocessor is busy performing a function
issued by another CPU
.
Counter: 68 Name:SHA_FUNCTIONS
Short-Description:SHA Functions
Description:
Total number of SHA functions issued by the CPU
.
Counter: 69 Name:SHA_CYCLES
Short-Description:SHA Cycles
Description:
Total number of CPU cycles when the SHA coprocessor is busy performing
the SHA functions issued by the CPU
.
Counter: 70 Name:SHA_BLOCKED_FUNCTIONS
Short-Description:SHA Blocked Functions
Description:
Total number of the SHA functions that are issued by the CPU and are
blocked because the SHA coprocessor is busy performing a function issued
by another CPU
.
Counter: 71 Name:SHA_BLOCKED_CYCLES
Short-Description:SHA Bloced Cycles
Description:
Total number of CPU cycles blocked for the SHA functions issued by the
CPU because the SHA coprocessor is busy performing a function issued
by another CPU
.
Counter: 72 Name:DEA_FUNCTIONS
Short-Description:DEA Functions
Description:
Total number of the DEA functions issued by the CPU
.
Counter: 73 Name:DEA_CYCLES
Short-Description:DEA Cycles
Description:
Total number of CPU cycles when the DEA/AES coprocessor is busy
performing the DEA functions issued by the CPU
.
Counter: 74 Name:DEA_BLOCKED_FUNCTIONS
Short-Description:DEA Blocked Functions
Description:
Total number of the DEA functions that are issued by the CPU and are
blocked because the DEA/AES coprocessor is busy performing a function
issued by another CPU
.
Counter: 75 Name:DEA_BLOCKED_CYCLES
Short-Description:DEA Blocked Cycles
Description:
Total number of CPU cycles blocked for the DEA functions issued by the
CPU because the DEA/AES coprocessor is busy performing a function issued
by another CPU
.
Counter: 76 Name:AES_FUNCTIONS
Short-Description:AES Functions
Description:
Total number of AES functions issued by the CPU
.
Counter: 77 Name:AES_CYCLES
Short-Description:AES Cycles
Description:
Total number of CPU cycles when the DEA/AES coprocessor is busy
performing the AES functions issued by the CPU
.
Counter: 78 Name:AES_BLOCKED_FUNCTIONS
Short-Description:AES Blocked Functions
Description:
Total number of AES functions that are issued by the CPU and are blocked
because the DEA/AES coprocessor is busy performing a function issued
by another CPU
.
Counter: 79 Name:AES_BLOCKED_CYCLES
Short-Description:AES Blocked Cycles
Description:
Total number of CPU cycles blocked for the AES functions issued by the
CPU because the DEA/AES coprocessor is busy performing a function issued
by another CPU
.

View File

@@ -1,33 +0,0 @@
Counter: 80 Name:ECC_FUNCTION_COUNT
Short-Description:ECC Function Count
Description:
This counter counts the
total number of the elliptic-curve cryptography (ECC)
functions issued by the CPU.
.
Counter: 81 Name:ECC_CYCLES_COUNT
Short-Description:ECC Cycles Count
Description:
This counter counts the total
number of CPU cycles when the ECC coprocessor is
busy performing the elliptic-curve cryptography
(ECC) functions issued by the CPU.
.
Counter: 82 Name:ECC_BLOCKED_FUNCTION_COUNT
Short-Description:Ecc Blocked Function Count
Description:
This counter
counts the total number of the elliptic-curve
cryptography (ECC) functions that are issued by the CPU
and are blocked because the ECC coprocessor is
busy performing a function issued by another CPU.
.
Counter: 83 Name:ECC_BLOCKED_CYCLES_COUNT
Short-Description:ECC Blocked Cycles Count
Description:
This counter counts
the total number of CPU cycles blocked for the elliptic-curve
cryptography (ECC) functions issued by the
CPU because the ECC coprocessor is busy perform-
ing a function issued by another CPU.
.

View File

@@ -1,114 +0,0 @@
Counter: 128 Name:L1I_L2_SOURCED_WRITES
Short-Description:L1I L2 Sourced Writes
Description:
A directory write to the Level-1 I-Cache directory where the returned
cache line was sourced from the Level-2 (L1.5) cache
.
Counter: 129 Name:L1D_L2_SOURCED_WRITES
Short-Description:L1D L2 Sourced Writes
Description:
A directory write to the Level-1 D-Cache directory where the installed
cache line was sourced from the Level-2 (L1.5) cache
.
Counter: 130 Name:L1I_L3_LOCAL_WRITES
Short-Description:L1I L3 Local Writes
Description:
A directory write to the Level-1 I-Cache directory where the installed
cache line was sourced from the Level-3 cache that is on the same book
as the Instruction cache (Local L2 cache)
.
Counter: 131 Name:L1D_L3_LOCAL_WRITES
Short-Description:L1D L3 Local Writes
Description:
A directory write to the Level-1 D-Cache directory where the installtion
cache line was source from the Level-3 cache that is on the same book
as the Data cache (Local L2 cache)
.
Counter: 132 Name:L1I_L3_REMOTE_WRITES
Short-Description:L1I L3 Remote Writes
Description:
A directory write to the Level-1 I-Cache directory where the installed
cache line was sourced from a Level-3 cache that is not on the same
book as the Instruction cache (Remote L2 cache)
.
Counter: 133 Name:L1D_L3_REMOTE_WRITES
Short-Description:L1D L3 Remote Writes
Description:
A directory write to the Level-1 D-Cache directory where the installed
cache line was sourced from a Level-3 cache that is not on the same
book as the Data cache (Remote L2 cache)
.
Counter: 134 Name:L1D_LMEM_SOURCED_WRITES
Short-Description:L1D Local Memory Sourced Writes
Description:
A directory write to the Level-1 D-Cache directory where the installed
cache line was sourced from memory that is attached to the same book
as the Data cache (Local Memory)
.
Counter: 135 Name:L1I_LMEM_SOURCED_WRITES
Short-Description:L1I Local Memory Sourced Writes
Description:
A directory write to the Level-1 I-Cache where the installed cache
line was sourced from memory that is attached to the s ame book as the
Instruction cache (Local Memory)
.
Counter: 136 Name:L1D_RO_EXCL_WRITES
Short-Description:L1D Read-only Exclusive Writes
Description:
A directory write to the Level-1 D-Cache where the line was originally
in a Read-Only state in the cache but has been updated to be in the
Exclusive state that allows stores to the cache line
.
Counter: 137 Name:L1I_CACHELINE_INVALIDATES
Short-Description:L1I Cacheline Invalidates
Description:
A cache line in the Level-1 I-Cache has been invalidated by a store on
the same CPU as the Level-1 I-Cache
.
Counter: 138 Name:ITLB1_WRITES
Short-Description:ITLB1 Writes
Description:
A translation entry has been written into the Level-1 Instruction
Translation Lookaside Buffer
.
Counter: 139 Name:DTLB1_WRITES
Short-Description:DTLB1 Writes
Description:
A translation entry has been written to the Level-1 Data Translation
Lookaside Buffer
.
Counter: 140 Name:TLB2_PTE_WRITES
Short-Description:TLB2 PTE Writes
Description:
A translation entry has been written to the Level-2 TLB Page Table
Entry arrays
.
Counter: 141 Name:TLB2_CRSTE_WRITES
Short-Description:TLB2 CRSTE Writes
Description:
A translation entry has been written to the Level-2 TLB Common Region
Segment Table Entry arrays
.
Counter: 142 Name:TLB2_CRSTE_HPAGE_WRITES
Short-Description:TLB2 CRSTE One-Megabyte Page Writes
Description:
A translation entry has been written to the Level-2 TLB Common Region
Segment Table Entry arrays for a one-megabyte large page translation
.
Counter: 145 Name:ITLB1_MISSES
Short-Description:ITLB1 Misses
Description:
Level-1 Instruction TLB miss in progress. Incremented by one for every
cycle an ITLB1 miss is in progress
.
Counter: 146 Name:DTLB1_MISSES
Short-Description:DTLB1 Misses
Description:
Level-1 Data TLB miss in progress. Incremented by one for every cycle
an DTLB1 miss is in progress
.
Counter: 147 Name:L2C_STORES_SENT
Short-Description:L2C Stores Sent
Description:
Incremented by one for every store sent to Level-2 (L1.5) cache
.

View File

@@ -1,373 +0,0 @@
# Counter decriptions for the
# IBM z13 extended counter and MT-diagnostic counter set
#
# Notes for transactional-execution mode symbolic names:
# TX .. transactional-execution mode
# NC .. nonconstrained
# C .. constrained
#
# Undefined counters in the extended counter set:
# 142
# 180-217
# 221-225
# Undefined counters in the MT-diagnostic counter set:
# 450-495
#
#
# Extended Counter Set
# ---------------------------------------------------------------------
Counter:128 Name:L1D_RO_EXCL_WRITES
Short-Description:L1D Read-only Exclusive Writes
Description:
A directory write to the Level-1 Data cache where the line was
originally in a Read-Only state in the cache but has been updated
to be in the Exclusive state that allows stores to the cache line.
.
Counter:129 Name:DTLB1_WRITES
Short-Description:DTLB1 Writes
Description:
A translation entry has been written to the Level-1 Data Translation
Lookaside Buffer
.
Counter:130 Name:DTLB1_MISSES
Short-Description:DTLB1 Misses
Description:
Level-1 Data TLB miss in progress. Incremented by one for every cycle
a DTLB1 miss is in progress.
.
Counter:131 Name:DTLB1_HPAGE_WRITES
Short-Description:DTLB1 One-Megabyte Page Writes
Description:
A translation entry has been written to the Level-1 Data Translation
Lookaside Buffer for a one-megabyte page
.
Counter:132 Name:DTLB1_GPAGE_WRITES
Short-Description:DTLB1 Two-Gigabyte Page Writes
A translation entry has been written to the Level-1 Data Translation
Lookaside Buffer for a two-gigabyte page.
.
Counter:133 Name:L1D_L2D_SOURCED_WRITES
Short-Description:L1D L2D Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from the Level-2 Data cache
.
Counter:134 Name:ITLB1_WRITES
Short-Description:ITLB1 Writes
Description:
A translation entry has been written to the Level-1 Instruction
Translation Lookaside Buffer
.
Counter:135 Name:ITLB1_MISSES
Short-Description:ITLB1 Misses
Description:
Level-1 Instruction TLB miss in progress. Incremented by one for every
cycle an ITLB1 miss is in progress
.
Counter:136 Name:L1I_L2I_SOURCED_WRITES
Short-Description:L1I L2I Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from the Level-2 Instruction cache
.
Counter:137 Name:TLB2_PTE_WRITES
Short-Description:TLB2 PTE Writes
Description:
A translation entry has been written to the Level-2 TLB Page Table
Entry arrays
.
Counter:138 Name:TLB2_CRSTE_HPAGE_WRITES
Short-Description:TLB2 CRSTE One-Megabyte Page Writes
Description:
A translation entry has been written to the Level-2 TLB Combined Region
Segment Table Entry arrays for a one-megabyte large page translation
.
Counter:139 Name:TLB2_CRSTE_WRITES
Short-Description:TLB2 CRSTE Writes
Description:
A translation entry has been written to the Level-2 TLB Combined Region
Segment Table Entry arrays
.
Counter:140 Name:TX_C_TEND
Short-Description:Completed TEND instructions in constrained TX mode
Description:
A TEND instruction has completed in a constrained transactional-execution
mode
.
Counter:141 Name:TX_NC_TEND
Short-Description:Completed TEND instructions in non-constrained TX mode
Description:
A TEND instruction has completed in a non-constrained
transactional-execution mode
.
Counter:143 Name:L1C_TLB1_MISSES
Short-Description:L1C TLB1 Misses
Description:
Increments by one for any cycle where a Level-1 cache or Level-1 TLB miss
is in progress.
.
Counter:144 Name:L1D_ONCHIP_L3_SOURCED_WRITES
Short-Description:L1D On-Chip L3 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an On-Chip Level-3 cache without intervention
.
Counter:145 Name:L1D_ONCHIP_L3_SOURCED_WRITES_IV
Short-Description:L1D On-Chip L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an On-Chip Level-3 cache with intervention
.
Counter:146 Name:L1D_ONNODE_L4_SOURCED_WRITES
Short-Description:L1D On-Node L4 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an On-Node Level-4 cache
.
Counter:147 Name:L1D_ONNODE_L3_SOURCED_WRITES_IV
Short-Description:L1D On-Node L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an On-Node Level-3 cache with intervention
.
Counter:148 Name:L1D_ONNODE_L3_SOURCED_WRITES
Short-Description:L1D On-Node L3 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an On-Node Level-3 cache without intervention
.
Counter:149 Name:L1D_ONDRAWER_L4_SOURCED_WRITES
Short-Description:L1D On-Drawer L4 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an On-Drawer Level-4 cache
.
Counter:150 Name:L1D_ONDRAWER_L3_SOURCED_WRITES_IV
Short-Description:L1D On-Drawer L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an On-Drawer Level-3 cache with intervention
.
Counter:151 Name:L1D_ONDRAWER_L3_SOURCED_WRITES
Short-Description:L1D On-Drawer L3 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an On-Drawer Level-3 cache without intervention
.
Counter:152 Name:L1D_OFFDRAWER_SCOL_L4_SOURCED_WRITES
Short-Description:L1D Off-Drawer Same-Column L4 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an Off-Drawer Same-Column Level-4 cache
.
Counter:153 Name:L1D_OFFDRAWER_SCOL_L3_SOURCED_WRITES_IV
Short-Description:L1D Off-Drawer Same-Column L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an Off-Drawer Same-Column Level-3 cache with
intervention
.
Counter:154 Name:L1D_OFFDRAWER_SCOL_L3_SOURCED_WRITES
Short-Description:L1D Off-Drawer Same-Column L3 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an Off-Drawer Same-Column Level-3 cache
without intervention
.
Counter:155 Name:L1D_OFFDRAWER_FCOL_L4_SOURCED_WRITES
Short-Description:L1D Off-Drawer Far-Column L3 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an Off-Drawer Far-Column Level-4 cache
.
Counter:156 Name:L1D_OFFDRAWER_FCOL_L3_SOURCED_WRITES_IV
Short-Description:L1D Off-Drawer Far-Column L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an Off-Drawer Far-Column Level-3 cache with
intervention
.
Counter:157 Name:L1D_OFFDRAWER_FCOL_L3_SOURCED_WRITES
Short-Description:L1D Off-Drawer Far-Column L3 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an Off-Drawer Far-Column Level-3 cache
without intervention
.
Counter:158 Name:L1D_ONNODE_MEM_SOURCED_WRITES
Short-Description:L1D On-Node Memory Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from On-Node memory
.
Counter:159 Name:L1D_ONDRAWER_MEM_SOURCED_WRITES
Short-Description:L1D On-Drawer Memory Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from On-Drawer memory
.
Counter:160 Name:L1D_OFFDRAWER_MEM_SOURCED_WRITES
Short-Description:L1D Off-Drawer Memory Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from On-Drawer memory
.
Counter:161 Name:L1D_ONCHIP_MEM_SOURCED_WRITES
Short-Description:L1D On-Chip Memory Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from On-Chip memory
.
Counter:162 Name:L1I_ONCHIP_L3_SOURCED_WRITES
Short-Description:L1I On-Chip L3 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an On-Chip Level-3 cache without
intervention
.
Counter:163 Name:L1I_ONCHIP_L3_SOURCED_WRITES_IV
Short-Description:L1I On-Chip L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an On Chip Level-3 cache with
intervention
.
Counter:164 Name:L1I_ONNODE_L4_SOURCED_WRITES
Short-Description:L1I On-Chip L4 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an On-Node Level-4 cache
.
Counter:165 Name:L1I_ONNODE_L3_SOURCED_WRITES_IV
Short-Description:L1I On-Node L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Instruction cache directory where
the returned cache line was sourced from an On-Node Level-3 cache
with intervention
.
Counter:166 Name:L1I_ONNODE_L3_SOURCED_WRITES
Short-Description:L1I On-Node L3 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where
the returned cache line was sourced from an On-Node Level-3 cache
without intervention
.
Counter:167 Name:L1I_ONDRAWER_L4_SOURCED_WRITES
Short-Description:L1I On-Drawer L4 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where
the returned cache line was sourced from an On-Drawer Level-4 cache
.
Counter:168 Name:L1I_ONDRAWER_L3_SOURCED_WRITES_IV
Short-Description:L1I On-Drawer L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Instruction cache directory where
the returned cache line was sourced from an On-Drawer Level-3 cache
with intervention
.
Counter:169 Name:L1I_ONDRAWER_L3_SOURCED_WRITES
Short-Description:L1I On-Drawer L3 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where
the returned cache line was sourced from an On-Drawer Level-3 cache
without intervention
.
Counter:170 Name:L1I_OFFDRAWER_SCOL_L4_SOURCED_WRITES
Short-Description:L1I Off-Drawer Same-Column L4 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where
the returned cache line was sourced from an Off-Drawer Same-Column
Level-4 cache
.
Counter:171 Name:L1I_OFFDRAWER_SCOL_L3_SOURCED_WRITES_IV
Short-Description:L1I Off-Drawer Same-Column L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Instruction cache directory where
the returned cache line was sourced from an Off-Drawer Same-Column
Level-3 cache with intervention
.
Counter:172 Name:L1I_OFFDRAWER_SCOL_L3_SOURCED_WRITES
Short-Description:L1I Off-Drawer Same-Column L3 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where
the returned cache line was sourced from an Off-Drawer Same-Column
Level-3 cache without intervention
.
Counter:173 Name:L1I_OFFDRAWER_FCOL_L4_SOURCED_WRITES
Short-Description:L1I Off-Drawer Far-Column L4 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where
the returned cache line was sourced from an Off-Drawer Far-Column
Level-4 cache
.
Counter:174 Name:L1I_OFFDRAWER_FCOL_L3_SOURCED_WRITES_IV
Short-Description:L1I Off-Drawer Far-Column L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Instruction cache directory where
the returned cache line was sourced from an Off-Drawer Far-Column
Level-3 cache with intervention
.
Counter:175 Name:L1I_OFFDRAWER_FCOL_L3_SOURCED_WRITES
Short-Description:L1I Off-Drawer Far-Column L3 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where
the returned cache line was sourced from an Off-Drawer Far-Column
Level-3 cache without intervention
.
Counter:176 Name:L1I_ONNODE_MEM_SOURCED_WRITES
Short-Description:L1I On-Node Memory Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where
the returned cache line was sourced from On-Node memory
.
Counter:177 Name:L1I_ONDRAWER_MEM_SOURCED_WRITES
Short-Description:L1I On-Drawer Memory Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where
the returned cache line was sourced from On-Drawer memory
.
Counter:178 Name:L1I_OFFDRAWER_MEM_SOURCED_WRITES
Short-Description:L1I Off-Drawer Memory Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where
the returned cache line was sourced from On-Drawer memory
.
Counter:179 Name:L1I_ONCHIP_MEM_SOURCED_WRITES
Short-Description:L1I On-Chip Memory Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where
the returned cache line was sourced from On-Chip memory
.
Counter:218 Name:TX_NC_TABORT
Short-Description:Aborted transactions in non-constrained TX mode
Description:
A transaction abort has occurred in a non-constrained
transactional-execution mode
.
Counter:219 Name:TX_C_TABORT_NO_SPECIAL
Short-Description:Aborted transactions in constrained TX mode not using special completion logic
Description:
A transaction abort has occurred in a constrained transactional-execution
mode and the CPU is not using any special logic to allow the transaction
to complete
.
Counter:220 Name:TX_C_TABORT_SPECIAL
Short-Description:Aborted transactions in constrained TX mode using special completion logic
Description:
A transaction abort has occurred in a constrained transactional-execution
mode and the CPU is using special logic to allow the transaction to
complete
.
#
# MT-diagnostic counter set
# ---------------------------------------------------------------------
Counter:448 Name:MT_DIAG_CYCLES_ONE_THR_ACTIVE
Short-Description:Cycle count with one thread active
Description:
Cycle count with one thread active
.
Counter:449 Name:MT_DIAG_CYCLES_TWO_THR_ACTIVE
Short-Description:Cycle count with two threads active
Description:
Cycle count with two threads active
.

View File

@@ -1,357 +0,0 @@
# Counter decriptions for the
# IBM z14 extended counter and MT-diagnostic counter set
#
# Notes for transactional-execution mode symbolic names:
# TX .. transactional-execution mode
# NC .. nonconstrained
# C .. constrained
#
# Undefined counters in the extended counter set:
# 142
# 158-161
# 176-223
# 227-231
# 233-242
# 246-255
# Undefined counters in the MT-diagnostic counter set:
# 450-495
#
#
# Extended Counter Set
# ---------------------------------------------------------------------
Counter:128 Name:L1D_RO_EXCL_WRITES
Short-Description:L1D Read-only Exclusive Writes
Description:
A directory write to the Level-1 Data cache where the line was
originally in a Read-Only state in the cache but has been updated
to be in the Exclusive state that allows stores to the cache line
.
Counter:129 Name:DTLB2_WRITES
Short-Description:DTLB2 Writes
Description:
A translation has been written into The Translation Lookaside
Buffer 2 (TLB2) and the request was made by the data cache
.
Counter:130 Name:DTLB2_MISSES
Short-Description:DTLB2 Misses
Description:
A TLB2 miss is in progress for a request made by the data cache.
Incremented by one for every TLB2 miss in progress for the Level-1
Data cache on this cycle
.
Counter:131 Name:DTLB2_HPAGE_WRITES
Short-Description:DTLB2 One-Megabyte Page Writes
Description:
A translation entry was written into the Combined Region and Segment
Table Entry array in the Level-2 TLB for a one-megabyte page or a
Last Host Translation was done
.
Counter:132 Name:DTLB2_GPAGE_WRITES
Short-Description:DTLB2 Two-Gigabyte Page Writes
Description:
A translation entry for a two-gigabyte page was written into the
Level-2 TLB
.
Counter:133 Name:L1D_L2D_SOURCED_WRITES
Short-Description:L1D L2D Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the
returned cache line was sourced from the Level-2 Data cache
.
Counter:134 Name:ITLB2_WRITES
Short-Description:ITLB2 Writes
Description:
A translation entry has been written into the Translation Lookaside
Buffer 2 (TLB2) and the request was made by the instruction cache
.
Counter:135 Name:ITLB2_MISSES
Short-Description:ITLB2 Misses
Description:
A TLB2 miss is in progress for a request made by the instruction cache.
Incremented by one for every TLB2 miss in progress for the Level-1
Instruction cache in a cycle
.
Counter:136 Name:L1I_L2I_SOURCED_WRITES
Short-Description:L1I L2I Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from the Level-2 Instruction cache
.
Counter:137 Name:TLB2_PTE_WRITES
Short-Description:TLB2 PTE Writes
Description:
A translation entry was written into the Page Table Entry array in the
Level-2 TLB
.
Counter:138 Name:TLB2_CRSTE_WRITES
Short-Description:TLB2 CRSTE Writes
Description:
Translation entries were written into the Combined Region and Segment
Table Entry array and the Page Table Entry array in the Level-2 TLB
.
Counter:139 Name:TLB2_ENGINES_BUSY
Short-Description:TLB2 Engines Busy
Description:
The number of Level-2 TLB translation engines busy in a cycle
.
Counter:140 Name:TX_C_TEND
Short-Description:Completed TEND instructions in constrained TX mode
Description:
A TEND instruction has completed in a constrained transactional-execution
mode
.
Counter:141 Name:TX_NC_TEND
Short-Description:Completed TEND instructions in non-constrained TX mode
Description:
A TEND instruction has completed in a non-constrained
transactional-execution mode
.
Counter:143 Name:L1C_TLB2_MISSES
Short-Description:L1C TLB2 Misses
Description:
Increments by one for any cycle where a level-1 cache or level-2 TLB miss
is in progress
.
Counter:144 Name:L1D_ONCHIP_L3_SOURCED_WRITES
Short-Description:L1D On-Chip L3 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an On-Chip Level-3 cache without intervention
.
Counter:145 Name:L1D_ONCHIP_MEMORY_SOURCED_WRITES
Short-Description:L1D On-Chip Memory Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from On-Chip memory
.
Counter:146 Name:L1D_ONCHIP_L3_SOURCED_WRITES_IV
Short-Description:L1D On-Chip L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an On-Chip Level-3 cache with intervention
.
Counter:147 Name:L1D_ONCLUSTER_L3_SOURCED_WRITES
Short-Description:L1D On-Cluster L3 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from On-Cluster Level-3 cache withountervention
.
Counter:148 Name:L1D_ONCLUSTER_MEMORY_SOURCED_WRITES
Short-Description:L1D On-Cluster Memory Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an On-Cluster memory
.
Counter:149 Name:L1D_ONCLUSTER_L3_SOURCED_WRITES_IV
Short-Description:L1D On-Cluster L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an On-Cluster Level-3 cache with intervention
.
Counter:150 Name:L1D_OFFCLUSTER_L3_SOURCED_WRITES
Short-Description:L1D Off-Cluster L3 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an Off-Cluster Level-3 cache without
intervention
.
Counter:151 Name:L1D_OFFCLUSTER_MEMORY_SOURCED_WRITES
Short-Description:L1D Off-Cluster Memory Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from Off-Cluster memory
.
Counter:152 Name:L1D_OFFCLUSTER_L3_SOURCED_WRITES_IV
Short-Description:L1D Off-Cluster L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an Off-Cluster Level-3 cache with intervention
.
Counter:153 Name:L1D_OFFDRAWER_L3_SOURCED_WRITES
Short-Description:L1D Off-Drawer L3 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an Off-Drawer Level-3 cache without
intervention
.
Counter:154 Name:L1D_OFFDRAWER_MEMORY_SOURCED_WRITES
Short-Description:L1D Off-Drawer Memory Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from Off-Drawer memory
.
Counter:155 Name:L1D_OFFDRAWER_L3_SOURCED_WRITES_IV
Short-Description:L1D Off-Drawer L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an Off-Drawer Level-3 cache with intervention
.
Counter:156 Name:L1D_ONDRAWER_L4_SOURCED_WRITES
Short-Description:L1D On-Drawer L4 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from On-Drawer Level-4 cache
.
Counter:157 Name:L1D_OFFDRAWER_L4_SOURCED_WRITES
Short-Description:L1D Off-Drawer L4 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from Off-Drawer Level-4 cache
.
Counter:158 Name:L1D_ONCHIP_L3_SOURCED_WRITES_RO
Short-Description:L1D On-Chip L3 Sourced Writes read-only
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from On-Chip L3 but a read-only invalidate was
done to remove other copies of the cache line
.
Counter:162 Name:L1I_ONCHIP_L3_SOURCED_WRITES
Short-Description:L1I On-Chip L3 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache ine was sourced from an On-Chip Level-3 cache without
intervention
.
Counter:163 Name:L1I_ONCHIP_MEMORY_SOURCED_WRITES
Short-Description:L1I On-Chip Memory Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache ine was sourced from On-Chip memory
.
Counter:164 Name:L1I_ONCHIP_L3_SOURCED_WRITES_IV
Short-Description:L1I On-Chip L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache ine was sourced from an On-Chip Level-3 cache with
intervention
.
Counter:165 Name:L1I_ONCLUSTER_L3_SOURCED_WRITES
Short-Description:L1I On-Cluster L3 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an On-Cluster Level-3 cache without
intervention
.
Counter:166 Name:L1I_ONCLUSTER_MEMORY_SOURCED_WRITES
Short-Description:L1I On-Cluster Memory Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an On-Cluster memory
.
Counter:167 Name:L1I_ONCLUSTER_L3_SOURCED_WRITES_IV
Short-Description:L1I On-Cluster L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from On-Cluster Level-3 cache with
intervention
.
Counter:168 Name:L1I_OFFCLUSTER_L3_SOURCED_WRITES
Short-Description:L1I Off-Cluster L3 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an Off-Cluster Level-3 cache without
intervention
.
Counter:169 Name:L1I_OFFCLUSTER_MEMORY_SOURCED_WRITES
Short-Description:L1I Off-Cluster Memory Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from Off-Cluster memory
.
Counter:170 Name:L1I_OFFCLUSTER_L3_SOURCED_WRITES_IV
Short-Description:L1I Off-Cluster L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an Off-Cluster Level-3 cache with
intervention
.
Counter:171 Name:L1I_OFFDRAWER_L3_SOURCED_WRITES
Short-Description:L1I Off-Drawer L3 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an Off-Drawer Level-3 cache without
intervention
.
Counter:172 Name:L1I_OFFDRAWER_MEMORY_SOURCED_WRITES
Short-Description:L1I Off-Drawer Memory Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from Off-Drawer memory
.
Counter:173 Name:L1I_OFFDRAWER_L3_SOURCED_WRITES_IV
Short-Description:L1I Off-Drawer L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an Off-Drawer Level-3 cache with
intervention
.
Counter:174 Name:L1I_ONDRAWER_L4_SOURCED_WRITES
Short-Description:L1I On-Drawer L4 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from On-Drawer Level-4 cache
.
Counter:175 Name:L1I_OFFDRAWER_L4_SOURCED_WRITES
Short-Description:L1I Off-Drawer L4 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from Off-Drawer Level-4 cache
.
Counter:224 Name:BCD_DFP_EXECUTION_SLOTS
Short-Description:BCD DFP Execution Slots
Description:
Count of floating point execution slots used for finished Binary Coded
Decimal to Decimal Floating Point conversions. Instructions: CDZT,
CXZT, CZDT, CZXT
.
Counter:225 Name:VX_BCD_EXECUTION_SLOTS
Short-Description:VX BCD Execution Slots
Description:
Count of floating point execution slots used for finished vector arithmetic
Binary Coded Decimal instructions. Instructions: VAP, VSP, VMPVMSP, VDP,
VSDP, VRP, VLIP, VSRP, VPSOPVCP, VTP, VPKZ, VUPKZ, VCVB, VCVBG, VCVDVCVDG
.
Counter:226 Name:DECIMAL_INSTRUCTIONS
Short-Description:Decimal Instructions
Description:
Decimal instructions dispatched. Instructions: CVB, CVD, AP, CP, DP, ED,
EDMK, MP, SRP, SP, ZAP
.
Counter:232 Name:LAST_HOST_TRANSLATIONS
Short-Description:Last host translation done
Description:
Last Host Translation done
.
Counter:243 Name:TX_NC_TABORT
Short-Description:Aborted transactions in non-constrained TX mode
Description:
A transaction abort has occurred in a non-constrained
transactional-execution mode
.
Counter:244 Name:TX_C_TABORT_NO_SPECIAL
Short-Description:Aborted transactions in constrained TX mode not using special completion logic
Description:
A transaction abort has occurred in a constrained transactional-execution
mode and the CPU is not using any special logic to allow the transaction
to complete
.
Counter:245 Name:TX_C_TABORT_SPECIAL
Short-Description:Aborted transactions in constrained TX mode using special completion logic
Description:
A transaction abort has occurred in a constrained transactional-execution
mode and the CPU is using special logic to allow the transaction to
complete
.
#
# MT-diagnostic counter set
# ---------------------------------------------------------------------
Counter:448 Name:MT_DIAG_CYCLES_ONE_THR_ACTIVE
Short-Description:Cycle count with one thread active
Description:
Cycle count with one thread active
.
Counter:449 Name:MT_DIAG_CYCLES_TWO_THR_ACTIVE
Short-Description:Cycle count with two threads active
Description:
Cycle count with two threads active
.

View File

@@ -1,376 +0,0 @@
# Counter decriptions for the
# IBM z14 extended counter and MT-diagnostic counter set
#
# Notes for transactional-execution mode symbolic names:
# TX .. transactional-execution mode
# NC .. nonconstrained
# C .. constrained
#
# Undefined counters in the extended counter set:
# 142
# 158-161
# 176-223
# 227-231
# 233-242
# 246-255
# Undefined counters in the MT-diagnostic counter set:
# 450-495
#
#
# Extended Counter Set
# ---------------------------------------------------------------------
Counter:128 Name:L1D_RO_EXCL_WRITES
Short-Description:L1D Read-only Exclusive Writes
Description:
A directory write to the Level-1 Data cache where the line was
originally in a Read-Only state in the cache but has been updated
to be in the Exclusive state that allows stores to the cache line
.
Counter:129 Name:DTLB2_WRITES
Short-Description:DTLB2 Writes
Description:
A translation has been written into The Translation Lookaside
Buffer 2 (TLB2) and the request was made by the data cache
.
Counter:130 Name:DTLB2_MISSES
Short-Description:DTLB2 Misses
Description:
A TLB2 miss is in progress for a request made by the data cache.
Incremented by one for every TLB2 miss in progress for the Level-1
Data cache on this cycle
.
Counter:131 Name:DTLB2_HPAGE_WRITES
Short-Description:DTLB2 One-Megabyte Page Writes
Description:
A translation entry was written into the Combined Region and Segment
Table Entry array in the Level-2 TLB for a one-megabyte page
.
Counter:132 Name:DTLB2_GPAGE_WRITES
Short-Description:DTLB2 Two-Gigabyte Page Writes
Description:
A translation entry for a two-gigabyte page was written into the
Level-2 TLB
.
Counter:133 Name:L1D_L2D_SOURCED_WRITES
Short-Description:L1D L2D Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the
returned cache line was sourced from the Level-2 Data cache
.
Counter:134 Name:ITLB2_WRITES
Short-Description:ITLB2 Writes
Description:
A translation entry has been written into the Translation Lookaside
Buffer 2 (TLB2) and the request was made by the instruction cache
.
Counter:135 Name:ITLB2_MISSES
Short-Description:ITLB2 Misses
Description:
A TLB2 miss is in progress for a request made by the instruction cache.
Incremented by one for every TLB2 miss in progress for the Level-1
Instruction cache in a cycle
.
Counter:136 Name:L1I_L2I_SOURCED_WRITES
Short-Description:L1I L2I Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from the Level-2 Instruction cache
.
Counter:137 Name:TLB2_PTE_WRITES
Short-Description:TLB2 PTE Writes
Description:
A translation entry was written into the Page Table Entry array in the
Level-2 TLB
.
Counter:138 Name:TLB2_CRSTE_WRITES
Short-Description:TLB2 CRSTE Writes
Description:
Translation entries were written into the Combined Region and Segment
Table Entry array and the Page Table Entry array in the Level-2 TLB
.
Counter:139 Name:TLB2_ENGINES_BUSY
Short-Description:TLB2 Engines Busy
Description:
The number of Level-2 TLB translation engines busy in a cycle
.
Counter:140 Name:TX_C_TEND
Short-Description:Completed TEND instructions in constrained TX mode
Description:
A TEND instruction has completed in a constrained transactional-execution
mode
.
Counter:141 Name:TX_NC_TEND
Short-Description:Completed TEND instructions in non-constrained TX mode
Description:
A TEND instruction has completed in a non-constrained
transactional-execution mode
.
Counter:143 Name:L1C_TLB2_MISSES
Short-Description:L1C TLB2 Misses
Description:
Increments by one for any cycle where a level-1 cache or level-2 TLB miss
is in progress
.
Counter:144 Name:L1D_ONCHIP_L3_SOURCED_WRITES
Short-Description:L1D On-Chip L3 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an On-Chip Level-3 cache without intervention
.
Counter:145 Name:L1D_ONCHIP_MEMORY_SOURCED_WRITES
Short-Description:L1D On-Chip Memory Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from On-Chip memory
.
Counter:146 Name:L1D_ONCHIP_L3_SOURCED_WRITES_IV
Short-Description:L1D On-Chip L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an On-Chip Level-3 cache with intervention
.
Counter:147 Name:L1D_ONCLUSTER_L3_SOURCED_WRITES
Short-Description:L1D On-Cluster L3 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from On-Cluster Level-3 cache withountervention
.
Counter:148 Name:L1D_ONCLUSTER_MEMORY_SOURCED_WRITES
Short-Description:L1D On-Cluster Memory Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an On-Cluster memory
.
Counter:149 Name:L1D_ONCLUSTER_L3_SOURCED_WRITES_IV
Short-Description:L1D On-Cluster L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an On-Cluster Level-3 cache with intervention
.
Counter:150 Name:L1D_OFFCLUSTER_L3_SOURCED_WRITES
Short-Description:L1D Off-Cluster L3 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an Off-Cluster Level-3 cache without
intervention
.
Counter:151 Name:L1D_OFFCLUSTER_MEMORY_SOURCED_WRITES
Short-Description:L1D Off-Cluster Memory Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from Off-Cluster memory
.
Counter:152 Name:L1D_OFFCLUSTER_L3_SOURCED_WRITES_IV
Short-Description:L1D Off-Cluster L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an Off-Cluster Level-3 cache with intervention
.
Counter:153 Name:L1D_OFFDRAWER_L3_SOURCED_WRITES
Short-Description:L1D Off-Drawer L3 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an Off-Drawer Level-3 cache without
intervention
.
Counter:154 Name:L1D_OFFDRAWER_MEMORY_SOURCED_WRITES
Short-Description:L1D Off-Drawer Memory Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from Off-Drawer memory
.
Counter:155 Name:L1D_OFFDRAWER_L3_SOURCED_WRITES_IV
Short-Description:L1D Off-Drawer L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an Off-Drawer Level-3 cache with intervention
.
Counter:156 Name:L1D_ONDRAWER_L4_SOURCED_WRITES
Short-Description:L1D On-Drawer L4 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from On-Drawer Level-4 cache
.
Counter:157 Name:L1D_OFFDRAWER_L4_SOURCED_WRITES
Short-Description:L1D Off-Drawer L4 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from Off-Drawer Level-4 cache
.
Counter:158 Name:L1D_ONCHIP_L3_SOURCED_WRITES_RO
Short-Description:L1D On-Chip L3 Sourced Writes read-only
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from On-Chip L3 but a read-only invalidate was
done to remove other copies of the cache line
.
Counter:162 Name:L1I_ONCHIP_L3_SOURCED_WRITES
Short-Description:L1I On-Chip L3 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache ine was sourced from an On-Chip Level-3 cache without
intervention
.
Counter:163 Name:L1I_ONCHIP_MEMORY_SOURCED_WRITES
Short-Description:L1I On-Chip Memory Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache ine was sourced from On-Chip memory
.
Counter:164 Name:L1I_ONCHIP_L3_SOURCED_WRITES_IV
Short-Description:L1I On-Chip L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache ine was sourced from an On-Chip Level-3 cache with
intervention
.
Counter:165 Name:L1I_ONCLUSTER_L3_SOURCED_WRITES
Short-Description:L1I On-Cluster L3 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an On-Cluster Level-3 cache without
intervention
.
Counter:166 Name:L1I_ONCLUSTER_MEMORY_SOURCED_WRITES
Short-Description:L1I On-Cluster Memory Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an On-Cluster memory
.
Counter:167 Name:L1I_ONCLUSTER_L3_SOURCED_WRITES_IV
Short-Description:L1I On-Cluster L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from On-Cluster Level-3 cache with
intervention
.
Counter:168 Name:L1I_OFFCLUSTER_L3_SOURCED_WRITES
Short-Description:L1I Off-Cluster L3 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an Off-Cluster Level-3 cache without
intervention
.
Counter:169 Name:L1I_OFFCLUSTER_MEMORY_SOURCED_WRITES
Short-Description:L1I Off-Cluster Memory Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from Off-Cluster memory
.
Counter:170 Name:L1I_OFFCLUSTER_L3_SOURCED_WRITES_IV
Short-Description:L1I Off-Cluster L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an Off-Cluster Level-3 cache with
intervention
.
Counter:171 Name:L1I_OFFDRAWER_L3_SOURCED_WRITES
Short-Description:L1I Off-Drawer L3 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an Off-Drawer Level-3 cache without
intervention
.
Counter:172 Name:L1I_OFFDRAWER_MEMORY_SOURCED_WRITES
Short-Description:L1I Off-Drawer Memory Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from Off-Drawer memory
.
Counter:173 Name:L1I_OFFDRAWER_L3_SOURCED_WRITES_IV
Short-Description:L1I Off-Drawer L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an Off-Drawer Level-3 cache with
intervention
.
Counter:174 Name:L1I_ONDRAWER_L4_SOURCED_WRITES
Short-Description:L1I On-Drawer L4 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from On-Drawer Level-4 cache
.
Counter:175 Name:L1I_OFFDRAWER_L4_SOURCED_WRITES
Short-Description:L1I Off-Drawer L4 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from Off-Drawer Level-4 cache
.
Counter:224 Name:BCD_DFP_EXECUTION_SLOTS
Short-Description:BCD DFP Execution Slots
Description:
Count of floating point execution slots used for finished Binary Coded
Decimal to Decimal Floating Point conversions. Instructions: CDZT,
CXZT, CZDT, CZXT
.
Counter:225 Name:VX_BCD_EXECUTION_SLOTS
Short-Description:VX BCD Execution Slots
Description:
Count of floating point execution slots used for finished vector arithmetic
Binary Coded Decimal instructions. Instructions: VAP, VSP, VMPVMSP, VDP,
VSDP, VRP, VLIP, VSRP, VPSOPVCP, VTP, VPKZ, VUPKZ, VCVB, VCVBG, VCVDVCVDG
.
Counter:226 Name:DECIMAL_INSTRUCTIONS
Short-Description:Decimal Instructions
Description:
Decimal instructions dispatched. Instructions: CVB, CVD, AP, CP, DP, ED,
EDMK, MP, SRP, SP, ZAP
.
Counter:232 Name:LAST_HOST_TRANSLATIONS
Short-Description:Last host translation done
Description:
Last Host Translation done
.
Counter:243 Name:TX_NC_TABORT
Short-Description:Aborted transactions in non-constrained TX mode
Description:
A transaction abort has occurred in a non-constrained
transactional-execution mode
.
Counter:244 Name:TX_C_TABORT_NO_SPECIAL
Short-Description:Aborted transactions in constrained TX mode not using special completion logic
Description:
A transaction abort has occurred in a constrained transactional-execution
mode and the CPU is not using any special logic to allow the transaction
to complete
.
Counter:245 Name:TX_C_TABORT_SPECIAL
Short-Description:Aborted transactions in constrained TX mode using special completion logic
Description:
A transaction abort has occurred in a constrained transactional-execution
mode and the CPU is using special logic to allow the transaction to
complete
.
Counter:247 Name:DFLT_ACCESS
Short-Description:Cycles CPU spent obtaining access to Deflate unit
Description:
Cycles CPU spent obtaining access to Deflate unit
.
Counter:252 Name:DFLT_CYCLES
Short-Description:Cycles CPU is using Deflate unit
Description:
Cycles CPU is using Deflate unit
.
Counter:264 Name:DFLT_CC
Short-Description:Increments by one for every DEFLATE CONVERSION CALL instruction executed
Description:
Increments by one for every DEFLATE CONVERSION CALL instruction executed
.
Counter:265 Name:DFLT_CCERROR
Short-Description:Increments by one for every DEFLATE CONVERSION CALL instruction executed that ended in Condition Codes 0, 1 or 2
Description:
Increments by one for every DEFLATE CONVERSION CALL instruction executed that ended in Condition Codes 0, 1 or 2
.
#
# MT-diagnostic counter set
# ---------------------------------------------------------------------
Counter:448 Name:MT_DIAG_CYCLES_ONE_THR_ACTIVE
Short-Description:Cycle count with one thread active
Description:
Cycle count with one thread active
.
Counter:449 Name:MT_DIAG_CYCLES_TWO_THR_ACTIVE
Short-Description:Cycle count with two threads active
Description:
Cycle count with two threads active
.

View File

@@ -1,146 +0,0 @@
Counter: 128 Name:L1D_L2_SOURCED_WRITES
Short-Description:L1D L2 Sourced Writes
Description:
A directory write to the Level-1 D-Cache directory where the returned
cache line was sourced from the Level-2 cache
.
Counter: 129 Name:L1I_L2_SOURCED_WRITES
Short-Description:L1I L2 Sourced Writes
Description:
A directory write to the Level-1 I-Cache directory where the returned
cache line was sourced from the Level-2 cache
.
Counter: 130 Name:DTLB1_MISSES
Short-Description:DTLB1 Misses
Description:
Level-1 Data TLB miss in progress. Incremented by one for every cycle
a DTLB1 miss is in progress.
.
Counter: 131 Name:ITLB1_MISSES
Short-Description:ITLB1 Misses
Description:
Level-1 Instruction TLB miss in progress. Incremented by one for every
cycle a ITLB1 miss is in progress.
.
Counter: 133 Name:L2C_STORES_SENT
Short-Description:L2C Stores Sent
Description:
Incremented by one for every store sent to Level-2 cache
.
Counter: 134 Name:L1D_OFFBOOK_L3_SOURCED_WRITES
Short-Description:L1D Off-Book L3 Sourced Writes
Description:
A directory write to the Level-1 D-Cache directory where the returned
cache line was sourced from an Off Book Level-3 cache
.
Counter: 135 Name:L1D_ONBOOK_L4_SOURCED_WRITES
Short-Description:L1D On-Book L4 Sourced Writes
Description:
A directory write to the Level-1 D-Cache directory where the returned
cache line was sourced from an On Book Level-4 cache
.
Counter: 136 Name:L1I_ONBOOK_L4_SOURCED_WRITES
Short-Description:L1I On-Book L4 Sourced Writes
Description:
A directory write to the Level-1 I-Cache directory where the returned
cache line was sourced from an On Book Level-4 cache
.
Counter: 137 Name:L1D_RO_EXCL_WRITES
Short-Description:L1D Read-only Exclusive Writes
Description:
A directory write to the Level-1 D-Cache where the line was originally
in a Read-Only state in the cache but has been updated to be in the
Exclusive state that allows stores to the cache line
.
Counter: 138 Name:L1D_OFFBOOK_L4_SOURCED_WRITES
Short-Description:L1D Off-Book L4 Sourced Writes
Description:
A directory write to the Level-1 D-Cache directory where the returned
cache line was sourced from an Off Book Level-4 cache
.
Counter: 139 Name:L1I_OFFBOOK_L4_SOURCED_WRITES
Short-Description:L1I Off-Book L4 Sourced Writes
Description:
A directory write to the Level-1 I-Cache directory where the returned
cache line was sourced from an Off Book Level-4 cache
.
Counter: 140 Name:DTLB1_HPAGE_WRITES
Short-Description:DTLB1 One-Megabyte Page Writes
Description:
A translation entry has been written to the Level-1 Data Translation
Lookaside Buffer for a one-megabyte page
.
Counter: 141 Name:L1D_LMEM_SOURCED_WRITES
Short-Description:L1D Local Memory Sourced Writes
Description:
A directory write to the Level-1 D-Cache where the installed cache line
was sourced from memory that is attached to the same book as the Data
cache (Local Memory)
.
Counter: 142 Name:L1I_LMEM_SOURCED_WRITES
Short-Description:L1I Local Memory Sourced Writes
Description:
A directory write to the Level-1 I-Cache where the installed cache
line was sourced from memory that is attached to the same book as the
Instruction cache (Local Memory)
.
Counter: 143 Name:L1I_OFFBOOK_L3_SOURCED_WRITES
Short-Description:L1I Off-Book L3 Sourced Writes
Description:
A directory write to the Level-1 I-Cache directory where the returned
cache line was sourced from an Off Book Level-3 cache
.
Counter: 144 Name:DTLB1_WRITES
Short-Description:DTLB1 Writes
Description:
A translation entry has been written to the Level-1 Data Translation
Lookaside Buffer
.
Counter: 145 Name:ITLB1_WRITES
Short-Description:ITLB1 Writes
Description:
A translation entry has been written to the Level-1 Instruction
Translation Lookaside Buffer
.
Counter: 146 Name:TLB2_PTE_WRITES
Short-Description:TLB2 PTE Writes
Description:
A translation entry has been written to the Level-2 TLB Page Table
Entry arrays
.
Counter: 147 Name:TLB2_CRSTE_HPAGE_WRITES
Short-Description:TLB2 CRSTE One-Megabyte Page Writes
Description:
A translation entry has been written to the Level-2 TLB Common Region
Segment Table Entry arrays for a one-megabyte large page translation
.
Counter: 148 Name:TLB2_CRSTE_WRITES
Short-Description:TLB2 CRSTE Writes
Description:
A translation entry has been written to the Level-2 TLB Common Region
Segment Table Entry arrays
.
Counter: 150 Name:L1D_ONCHIP_L3_SOURCED_WRITES
Short-Description:L1D On-Chip L3 Sourced Writes
Description:
A directory write to the Level-1 D-Cache directory where the returned
cache line was sourced from an On Chip Level-3 cache
.
Counter: 152 Name:L1D_OFFCHIP_L3_SOURCED_WRITES
Short-Description:L1D Off-Chip L3 Sourced Writes
Description:
A directory write to the Level-1 D-Cache directory where the returned
cache line was sourced from an Off Chip/On Book Level-3 cache
.
Counter: 153 Name:L1I_ONCHIP_L3_SOURCED_WRITES
Short-Description:L1I On-Chip L3 Sourced Writes
Description:
A directory write to the Level-1 I-Cache directory where the returned
cache line was sourced from an On Chip Level-3 cache
.
Counter: 155 Name:L1I_OFFCHIP_L3_SOURCED_WRITES
Short-Description:L1I Off-Chip L3 Sourced Writes
Description:
A directory write to the Level-1 I-Cache directory where the returned
cache line was sourced from an Off Chip/On Book Level-3 cache
.

View File

@@ -1,230 +0,0 @@
Counter: 128 Name:DTLB1_MISSES
Short-Description:DTLB1 Misses
Description:
Level-1 Data TLB miss in progress. Incremented by one for every cycle
a DTLB1 miss is in progress.
.
Counter:129 Name:ITLB1_MISSES
Short-Description:ITLB1 Misses
Description:
Level-1 Instruction TLB miss in progress. Incremented by one for every
cycle a ITLB1 miss is in progress.
.
Counter:130 Name:L1D_L2I_SOURCED_WRITES
Short-Description:L1D L2I Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from the Level-2 Instruction cache
.
Counter:131 Name:L1I_L2I_SOURCED_WRITES
Short-Description:L1I L2I Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from the Level-2 Instruction cache
.
Counter:132 Name:L1D_L2D_SOURCED_WRITES
Short-Description:L1D L2D Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from the Level-2 Data cache
.
Counter:133 Name:DTLB1_WRITES
Short-Description:DTLB1 Writes
Description:
A translation entry has been written to the Level-1 Data Translation
Lookaside Buffer
.
Counter:135 Name:L1D_LMEM_SOURCED_WRITES
Short-Description:L1D Local Memory Sourced Writes
Description:
A directory write to the Level-1 Data cache where the installed cache line
was sourced from memory that is attached to the same book as the Data
cache (Local Memory)
.
Counter:137 Name:L1I_LMEM_SOURCED_WRITES
Short-Description:L1I Local Memory Sourced Writes
Description:
A directory write to the Level-1 Instruction cache where the installed cache
line was sourced from memory that is attached to the same book as the
Instruction cache (Local Memory)
.
Counter:138 Name:L1D_RO_EXCL_WRITES
Short-Description:L1D Read-only Exclusive Writes
Description:
A directory write to the Level-1 D-Cache where the line was originally
in a Read-Only state in the cache but has been updated to be in the
Exclusive state that allows stores to the cache line
.
Counter:139 Name:DTLB1_HPAGE_WRITES
Short-Description:DTLB1 One-Megabyte Page Writes
Description:
A translation entry has been written to the Level-1 Data Translation
Lookaside Buffer for a one-megabyte page
.
Counter:140 Name:ITLB1_WRITES
Short-Description:ITLB1 Writes
Description:
A translation entry has been written to the Level-1 Instruction
Translation Lookaside Buffer
.
Counter:141 Name:TLB2_PTE_WRITES
Short-Description:TLB2 PTE Writes
Description:
A translation entry has been written to the Level-2 TLB Page Table
Entry arrays
.
Counter:142 Name:TLB2_CRSTE_HPAGE_WRITES
Short-Description:TLB2 CRSTE One-Megabyte Page Writes
Description:
A translation entry has been written to the Level-2 TLB Common Region
Segment Table Entry arrays for a one-megabyte large page translation
.
Counter:143 Name:TLB2_CRSTE_WRITES
Short-Description:TLB2 CRSTE Writes
Description:
A translation entry has been written to the Level-2 TLB Common Region
Segment Table Entry arrays
.
Counter:144 Name:L1D_ONCHIP_L3_SOURCED_WRITES
Short-Description:L1D On-Chip L3 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an On Chip Level-3 cache without intervention
.
Counter:145 Name:L1D_OFFCHIP_L3_SOURCED_WRITES
Short-Description:L1D Off-Chip L3 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an Off Chip/On Book Level-3 cache without
intervention
.
Counter:146 Name:L1D_OFFBOOK_L3_SOURCED_WRITES
Short-Description:L1D Off-Book L3 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an Off Book Level-3 cache without intervention
.
Counter:147 Name:L1D_ONBOOK_L4_SOURCED_WRITES
Short-Description:L1D On-Book L4 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an On Book Level-4 cache
.
Counter:148 Name:L1D_OFFBOOK_L4_SOURCED_WRITES
Short-Description:L1D Off-Book L4 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an Off Book Level-4 cache
.
#
# Notes for the transactional-execution mode notations:
# TX .. transactional-execution mode
# NC .. nonconstrained
# C .. constrained
#
Counter:149 Name:TX_NC_TEND
Short-Description:Completed TEND instructions in non-constrained TX mode
Description:
A TEND instruction has completed in a nonconstrained
transactional-execution mode
.
Counter:150 Name:L1D_ONCHIP_L3_SOURCED_WRITES_IV
Short-Description:L1D On-Chip L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from a On Chip Level-3 cache with intervention
.
Counter:151 Name:L1D_OFFCHIP_L3_SOURCED_WRITES_IV
Short-Description:L1D Off-Chip L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an Off Chip/On Book Level-3 cache with
intervention
.
# XXX Remove SOURCED from L1D_OFFBOOK_L3_SOURCED_WRITES...
Counter:152 Name:L1D_OFFBOOK_L3_SOURCED_WRITES_IV
Short-Description:L1D Off-Book L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an Off Book Level-3 cache with intervention
.
Counter:153 Name:L1I_ONCHIP_L3_SOURCED_WRITES
Short-Description:L1I On-Chip L3 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an On Chip Level-3 cache without
intervention
.
Counter:154 Name:L1I_OFFCHIP_L3_SOURCED_WRITES
Short-Description:L1I Off-Chip L3 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an Off Chip/On Book Level-3 cache
without intervention
.
Counter:155 Name:L1I_OFFBOOK_L3_SOURCED_WRITES
Short-Description:L1I Off-Book L3 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an Off Book Level-3 cache without
intervention
.
Counter:156 Name:L1I_ONBOOK_L4_SOURCED_WRITES
Short-Description:L1I On-Book L4 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an On Book Level-4 cache
.
Counter:157 Name:L1I_OFFBOOK_L4_SOURCED_WRITES
Short-Description:L1I Off-Book L4 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an Off Book Level-4 cache
.
Counter:158 Name:TX_C_TEND
Short-Description:Completed TEND instructions in constrained TX mode
Description:
A TEND instruction has completed in a constrained transactional-execution
mode
.
Counter:159 Name:L1I_ONCHIP_L3_SOURCED_WRITES_IV
Short-Description:L1I On-Chip L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an On Chip Level-3 cache with
intervention
.
Counter:160 Name:L1I_OFFCHIP_L3_SOURCED_WRITES_IV
Short-Description:L1I Off-Chip L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an Off Chip/On Book Level-3 cache
with intervention
.
Counter:161 Name:L1I_OFFBOOK_L3_SOURCED_WRITES_IV
Short-Description:L1I Off-Book L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an Off Book Level-3 cache with
intervention
.
Counter:177 Name:TX_NC_TABORT
Short-Description:Aborted transactions in non-constrained TX mode
Description:
A transaction abort has occurred in a nonconstrained
transactional-execution mode
.
Counter:178 Name:TX_C_TABORT_NO_SPECIAL
Short-Description:Aborted transactions in constrained TX mode not using special completion logic
Description:
A transaction abort has occurred in a constrained transactional-execution
mode and the CPU is not using any special logic to allow the transaction
to complete
.
Counter:179 Name:TX_C_TABORT_SPECIAL
Short-Description:Aborted transactions in constrained TX mode using special completion logic
Description:
A transaction abort has occurred in a constrained transactional-execution
mode and the CPU is using special logic to allow the transaction to
complete
.

View File

@@ -1,33 +0,0 @@
# CPU-measurement facilities
#
# Mapping of:
# 1. CPU-MF counter first/second version numbers to "generic" counter
# definitions
# 2. IBM z Systems hardware to respective extended counter set definitions
#
#
{
# Definition # File name
# CFVN
'cfvn-1' => 'cpum-cf-cfvn-1.ctr',
'cfvn-3' => 'cpum-cf-cfvn-3.ctr',
# CSVN
'csvn-12345' => 'cpum-cf-csvn-12345.ctr',
'csvn-6' => 'cpum-cf-csvn-6.ctr',
# Extended counters
2097 => 'cpum-cf-extended-z10.ctr',
2098 => 'cpum-cf-extended-z10.ctr',
2817 => 'cpum-cf-extended-z196.ctr',
2818 => 'cpum-cf-extended-z196.ctr',
2827 => 'cpum-cf-extended-zEC12.ctr',
2828 => 'cpum-cf-extended-zEC12.ctr',
2964 => 'cpum-cf-extended-z13.ctr',
2965 => 'cpum-cf-extended-z13.ctr',
3906 => 'cpum-cf-extended-z14.ctr',
3907 => 'cpum-cf-extended-z14.ctr',
8561 => 'cpum-cf-extended-z15.ctr',
8562 => 'cpum-cf-extended-z15.ctr',
};

View File

@@ -1,15 +0,0 @@
# Perf raw event counter definitions for the
# CPU-measurment sampling facility
#
# Basic-sampling mode
Counter: 0xB0000 Name:SF_CYCLES_BASIC
Short-Description:Sample CPU Cycles Using Basic-sampling Mode
Description:
Sample CPU cycles using basic-sampling mode
.
# Diagnostic-sampling mode (includes basic-sampling)
Counter: 0xBD000 Name:SF_CYCLES_BASIC_DIAG
Short-Description:Sample CPU Cycle Using Diagnostic-sampling Mode (not for ordinary use)
Description:
Sample CPU cycle using diagnostic-sampling mode (not for ordinary use)
.

23
cpumf/defines.h Normal file
View File

@@ -0,0 +1,23 @@
/*
* Defines for CPU Measurement Facility Characteristics
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef DEFINES_H
#define DEFINES_H
#define PERF_SFB_SIZE "/sys/module/kernel/parameters/cpum_sfb_size"
#define PERF_PATH "/sys/bus/event_source/devices/"
#define PERF_SF "cpum_sf"
#define PERF_CF "cpum_cf"
static inline void linux_error(const char *message)
{
fprintf(stderr, "Error: %s: %s\n", message, strerror(errno));
}
#endif

3120
cpumf/lscpumf.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -20,6 +20,7 @@ chcpumf \- manage the CPU-measurement facilities support
.IR num_sdb ]
.RB [ \-x | \-\-max
.IR num_sdb ]
.RB [ \-V | \-\-verbose ]
.br
.B chcpumf
.BR \-h | \-\-help

View File

@@ -1,11 +1,11 @@
\" lscpumf.1
.\"
.\"
.\" Copyright IBM Corp. 2014, 2017
.\" Copyright IBM Corp. 2014, 2020
.\" s390-tools is free software; you can redistribute it and/or modify
.\" it under the terms of the MIT license. See LICENSE for details.
.\" ----------------------------------------------------------------------
.TH lscpumf "1" "February 2014" "s390-tools" "CPU-MF management programs"
.TH lscpumf "1" "May 2020" "s390-tools" "CPU-MF management programs"
.
.ds c \fBlscpumf\fP
.
@@ -19,9 +19,11 @@ lscpumf \- display information about CPU-measurement facilities
.RB [ \-i | \-\-info ]
.br
.B lscpumf
.RB [ \-c | \-\-list\-counters ]
.RB [ \-C | \-\-list\-all\-counters ]
.RB [ \-s | \-\-list\-sampling\-events ]
.RB \-c | \-\-list\-counters | \-C | \-\-list\-all\-counters
.RB [ \-n ]
.br
.B lscpumf
.RB \-s | \-\-list\-sampling\-events
.br
.B lscpumf
.BR \-h | \-\-help
@@ -46,12 +48,25 @@ facilities.
Lists counters that are provided by the CPU-measurement facility, omitting
counters for which the LPAR is not authorized. For counter measurements with
the perf program, the raw event identifier is displayed.
For Linux version 5.5 and later, the raw event identifier is
displayed as <type>:<number>, where type is an integer that the kernel
assignes to the CPU Measurement counter facility device driver.
For earlier Linux versions the raw event identifier is displayed as r<number>.
.
.TP
.BR \-C ", " \-\-list\-all\-counters
Lists all counters that are provided by the CPU-measurement counter facility,
regardless of LPAR authorization. To list only those counters for which the
LPAR is authorized, use the -c option.
For linux version 5.5 and later the raw event identifier is
displayed as <type>:<number>, where type is the number the CPU Measurement
counter facility device driver was assigned to by the kernel.
For earlier linux versions the raw event identifier is displayed as r<number>.
.
.TP
.BR \-n ", " \-\-name
.
Display the counter name together with the raw event identifier.
.
.TP
.BR \-s ", " \-\-list\-sampling\-events

View File

@@ -1,14 +1,39 @@
include ../common.mak
ALL_CPPFLAGS += -DSYSFS
all: dasdview
libs = $(rootdir)/libdasd/libdasd.a \
$(rootdir)/libzds/libzds.a \
$(rootdir)/libvtoc/libvtoc.a \
$(rootdir)/libutil/libutil.a
ifneq (${HAVE_CURL},0)
check_dep:
$(call check_dep, \
"dasdview", \
"curl/curl.h", \
"curl-devel or libcurl-dev", \
"HAVE_CURL=0")
BUILDTARGET = check_dep
ifneq ($(shell sh -c 'command -v pkg-config'),)
CURL_CFLAGS = $(shell pkg-config --silence-errors --cflags libcurl)
CURL_LDLIBS = $(shell pkg-config --silence-errors --libs libcurl)
else
CURL_CFLAGS = -I/usr/include/s390x-linux-gnu/curl
CURL_LDLIBS = -lcurl
endif # shell
endif # HAVE_CURL
BUILDTARGET += dasdview
ALL_CPPFLAGS += -DSYSFS
ALL_CFLAGS += $(CURL_CFLAGS)
LDLIBS += $(CURL_LDLIBS)
all: $(BUILDTARGET)
dasdview: dasdview.o $(libs)
install: all

View File

@@ -225,7 +225,7 @@ function CheckDeviceString() {
fi
}
setup_device()
setup_ccw_device()
{
DEV="$(CheckDeviceString $DEVICE)"
if [ "$DEV" != "" ]; then
@@ -235,27 +235,37 @@ setup_device()
pr_error "ERROR: Invalid DEVICE '$DEVICE'." $ERRMSG
return
fi
if [ $2 == "fcp" ]; then
echo $WWPN > $1/fcp/wwpn 2>/dev/null || RETVAL=1
if [ $RETVAL -eq 1 ]; then
pr_error "ERROR: Invalid WWPN '$WWPN'." $ERRMSG
return
fi
echo $LUN > $1/fcp/lun 2>/dev/null || RETVAL=1
if [ $RETVAL -eq 1 ]; then
pr_error "ERROR: Invalid LUN '$LUN'." $ERRMSG
return
fi
echo $BOOTPROG > $1/fcp/bootprog 2>/dev/null || RETVAL=1
if [ $RETVAL -eq 1 ]; then
pr_error "ERROR: Invalid BOOTPROG '$BOOTPROG'." $ERRMSG
return
fi
echo $BR_LBA > $1/fcp/br_lba 2>/dev/null || RETVAL=1
if [ $RETVAL -eq 1 ]; then
pr_error "ERROR: Invalid BR_LBA '$BR_LBA'." $ERRMSG
return
fi
}
setup_fcp_device()
{
DEV="$(CheckDeviceString $DEVICE)"
if [ "$DEV" != "" ]; then
echo $DEV > $1/$2/device
else
RETVAL=1
pr_error "ERROR: Invalid DEVICE '$DEVICE'." $ERRMSG
return
fi
echo $WWPN > $1/fcp/wwpn 2>/dev/null || RETVAL=1
if [ $RETVAL -eq 1 ]; then
pr_error "ERROR: Invalid WWPN '$WWPN'." $ERRMSG
return
fi
echo $LUN > $1/fcp/lun 2>/dev/null || RETVAL=1
if [ $RETVAL -eq 1 ]; then
pr_error "ERROR: Invalid LUN '$LUN'." $ERRMSG
return
fi
echo $BOOTPROG > $1/fcp/bootprog 2>/dev/null || RETVAL=1
if [ $RETVAL -eq 1 ]; then
pr_error "ERROR: Invalid BOOTPROG '$BOOTPROG'." $ERRMSG
return
fi
echo $BR_LBA > $1/fcp/br_lba 2>/dev/null || RETVAL=1
if [ $RETVAL -eq 1 ]; then
pr_error "ERROR: Invalid BR_LBA '$BR_LBA'." $ERRMSG
return
fi
}
@@ -264,6 +274,30 @@ setup_nss_device()
echo $NSS_NAME > $1/nss/name || RETVAL=1
}
setup_nvme_device()
{
echo $FID > $1/nvme/fid 2>/dev/null || RETVAL=1
if [ $RETVAL -eq 1 ]; then
pr_error "ERROR: Invalid FID '$FID'." $ERRMSG
return
fi
echo $NSID > $1/nvme/nsid 2>/dev/null || RETVAL=1
if [ $RETVAL -eq 1 ]; then
pr_error "ERROR: Invalid NSID '$NSID'." $ERRMSG
return
fi
echo $BOOTPROG > $1/nvme/bootprog 2>/dev/null || RETVAL=1
if [ $RETVAL -eq 1 ]; then
pr_error "ERROR: Invalid BOOTPROG '$BOOTPROG'." $ERRMSG
return
fi
echo $BR_LBA > $1/nvme/br_lba 2>/dev/null || RETVAL=1
if [ $RETVAL -eq 1 ]; then
pr_error "ERROR: Invalid BR_LBA '$BR_LBA'." $ERRMSG
return
fi
}
setup_reipl()
{
if [ "$REIPL_TYPE" == "" ]; then
@@ -271,15 +305,25 @@ setup_reipl()
return
fi
if [ "$REIPL_TYPE" == "ccw" ] || [ "$REIPL_TYPE" == "fcp" ]; then
setup_device $REIPL_CONFIG_DIR $REIPL_TYPE
elif [ "$REIPL_TYPE" == "nss" ]; then
setup_nss_device $REIPL_CONFIG_DIR
else
pr_error "ERROR: Unknown reipl type '$REIPL_TYPE'." $ERRMSG
RETVAL=1
return
fi
case "$REIPL_TYPE" in
ccw)
setup_ccw_device $REIPL_CONFIG_DIR $REIPL_TYPE
;;
fcp)
setup_fcp_device $REIPL_CONFIG_DIR $REIPL_TYPE
;;
nvme)
setup_nvme_device $REIPL_CONFIG_DIR
;;
nss)
setup_nss_device $REIPL_CONFIG_DIR
;;
*)
pr_error "ERROR: Unknown reipl type '$REIPL_TYPE'." $ERRMSG
RETVAL=1
return
;;
esac
echo $REIPL_TYPE > $REIPL_CONFIG_DIR/reipl_type || RETVAL=1
@@ -292,13 +336,24 @@ setup_reipl()
setup_dump()
{
if [ "$DUMP_TYPE" == "ccw" ] || [ "$DUMP_TYPE" == "fcp" ]; then
setup_device $DUMP_CONFIG_DIR $DUMP_TYPE
elif [ "$DUMP_TYPE" != "none" ]; then
pr_error "ERROR: Unknown dump type '$DUMP_TYPE'." $ERRMSG
RETVAL=1
return
fi
case "$DUMP_TYPE" in
ccw)
setup_ccw_device $DUMP_CONFIG_DIR $DUMP_TYPE
;;
fcp)
setup_fcp_device $DUMP_CONFIG_DIR $DUMP_TYPE
;;
nvme)
setup_nvme_device $DUMP_CONFIG_DIR
;;
none)
;;
*)
pr_error "ERROR: Unknown dump type '$DUMP_TYPE'." $ERRMSG
RETVAL=1
return
;;
esac
echo $DUMP_TYPE > $DUMP_CONFIG_DIR/dump_type || RETVAL=1
@@ -358,6 +413,18 @@ print_ccw_device()
pr_info "device..: $DEVICE"
}
print_nvme_device()
{
FID=$(cat $1/nvme/fid) || RETVAL=1
pr_info "fid.....: $FID"
NSID=$(cat $1/nvme/nsid) || RETVAL=1
pr_info "nsid....: $NSID"
BOOTPROG=$(cat $1/nvme/bootprog) || RETVAL=1
pr_info "bootprog: $BOOTPROG"
BR_LBA=$(cat $1/nvme/br_lba) || RETVAL=1
pr_info "br_lba..: $BR_LBA"
}
print_nss_name()
{
NAME=$(cat $1/nss/device) || RETVAL=1
@@ -367,35 +434,52 @@ print_nss_name()
status_dump()
{
CONF_DUMP_TYPE=$(cat $DUMP_CONFIG_DIR/dump_type) || RETVAL=1
if [ "$CONF_DUMP_TYPE" == "none" ]; then
pr_info "type....: no dump device configured"
elif [ "$CONF_DUMP_TYPE" == "ccw" ]; then
pr_info "type....: ccw"
print_ccw_device $DUMP_CONFIG_DIR
verify_ccw_dump_device $(cat $DUMP_CONFIG_DIR/ccw/device)
elif [ "$CONF_DUMP_TYPE" == "fcp" ]; then
pr_info "type....: fcp"
print_fcp_device $DUMP_CONFIG_DIR
else
pr_error "ERROR: Unknown dump device type '$CONF_DUMP_TYPE'!"
pr_error " Please check if you have the latest dumpconf package!"
fi
case "$CONF_DUMP_TYPE" in
none)
pr_info "type....: no dump device configured"
;;
ccw)
pr_info "type....: ccw"
print_ccw_device $DUMP_CONFIG_DIR
verify_ccw_dump_device $(cat $DUMP_CONFIG_DIR/ccw/device)
;;
fcp)
pr_info "type....: fcp"
print_fcp_device $DUMP_CONFIG_DIR
;;
nvme)
pr_info "type....: nvme"
print_nvme_device $DUMP_CONFIG_DIR
;;
*)
pr_error "ERROR: Unknown dump device type '$CONF_DUMP_TYPE'!"
pr_error " Please check if you have the latest dumpconf package!"
;;
esac
}
status_reipl()
{
REIPL_TYPE=$(cat $REIPL_CONFIG_DIR/reipl_type) || RETVAL=1
pr_info "type....: $REIPL_TYPE"
if [ "$REIPL_TYPE" == "ccw" ]; then
print_ccw_device $REIPL_CONFIG_DIR
elif [ "$REIPL_TYPE" == "fcp" ]; then
print_fcp_device $REIPL_CONFIG_DIR
elif [ "$REIPL_TYPE" == "nss" ]; then
print_nss_name $REIPL_CONFIG_DIR
else
pr_error "ERROR: Unknown reipl device type '$REIPL_TYPE'!"
pr_error " Please check if you have the latest dumpconf package!"
fi
case "$REIPL_TYPE" in
ccw)
print_ccw_device $REIPL_CONFIG_DIR
;;
fcp)
print_fcp_device $REIPL_CONFIG_DIR
;;
nvme)
print_nvme_device $REIPL_CONFIG_DIR
;;
nss)
print_nss_name $REIPL_CONFIG_DIR
;;
*)
pr_error "ERROR: Unknown reipl device type '$REIPL_TYPE'!"
pr_error " Please check if you have the latest dumpconf package!"
;;
esac
}
status_dump_reipl()

View File

@@ -31,7 +31,7 @@ if [ -f $CONFIG_FILE ]; then
. $CONFIG_FILE
fi
UDEVSETTLE=/sbin/udevadm
UDEVSETTLE=/usr/bin/udevadm
if [ ! -e $UDEVSETTLE ]
then
UDEVSETTLE=/sbin/udevsettle

View File

@@ -39,6 +39,16 @@
# BOOTPROG=0
# BR_LBA=0
#
# Dump on nvme device (NVMe Disk)
#
# ON_PANIC=dump
# DUMP_TYPE=nvme
# FID=0x00000300
# NSID=0x00000001
# BOOTPROG=3
# BR_LBA=0
#
# Use VMDUMP
#

View File

@@ -6,11 +6,9 @@
# verifying the issuer, the validity date and the signature.
# Optionally verify the full trust chain using a CA certficate.
#
# Revocation list checking not yet implemented.
#
# Sample invocation:
#
# ./check_hostkeydoc HKD1234.crt signing-key.crt
# ./check_hostkeydoc HKD1234.crt ibm-z-host-key-signing.crt -c DigiCertCA.crt -r ibm-z-host-key.crl
#
# Copyright IBM Corp. 2020
#
@@ -37,8 +35,9 @@ cleanup()
trap cleanup EXIT
# Enhanced error checking for bash
if echo $SHELL | grep /bin/bash > /dev/null
if [ -n "${BASH}" ]
then
set -o posix
set -o pipefail
set -o nounset
fi
@@ -101,7 +100,7 @@ extract_body()
verify_signature()
{
# Assuming that the signature algorith is SHA512 with RSA
# Assuming that the signature algorithm is SHA512 with RSA
openssl sha512 -verify $1 -signature $2 $3
}

View File

@@ -286,6 +286,7 @@ enum diag308_subcode {
enum diag308_rc {
DIAG308_RC_OK = 0x0001,
DIAG308_RC_NO_CONF = 0x0102,
};
static __always_inline unsigned long diag308(unsigned long subcode, void *addr)

1071
include/ekmfweb/ekmfweb.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -191,6 +191,8 @@
#define ENDTOKEN 0xFFFFFFFFFFFFFFFFULL
#define MAX_LINE_LENGTH 512
#define MAX_SERVER 3
/**
* @brief This structure represents the count field in an ECKD record.
@@ -854,6 +856,7 @@ int lzds_zdsroot_extract_datasets_from_dasd(struct zdsroot *root,
void lzds_dslist_free(struct zdsroot *root);
int lzds_ping_rest(struct dshandle *dsh, char *server);
/** @} */ /* end of group libzds_functions_high */
@@ -878,6 +881,8 @@ int lzds_analyse_open_count(struct zdsroot *root, int warn);
/** @} */ /* end of group libzds_functions_helper */
int lzds_rest_get_enq(struct dshandle *dsh, char *server);
int lzds_rest_release_enq(struct dshandle *dsh, char *server);
int lzds_rest_ping(struct dshandle *dsh, char *server);
#endif /* LIB_LIBZDS_H */

View File

@@ -12,8 +12,10 @@
#define LIB_UTIL_FILE_H
int util_file_read_line(char *str, size_t size, const char *fmt, ...);
int util_file_read_i(int *val, int base, const char *fmt, ...);
int util_file_read_l(long *val, int base, const char *fmt, ...);
int util_file_read_ll(long long *val, int base, const char *fmt, ...);
int util_file_read_ui(unsigned int *val, int base, const char *fmt, ...);
int util_file_read_ul(unsigned long *val, int base, const char *fmt, ...);
int util_file_read_ull(unsigned long long *val, int base, const char *fmt, ...);
@@ -23,4 +25,5 @@ int util_file_write_ll(long long val, int base, const char *fmt, ...);
int util_file_write_ul(unsigned long val, int base, const char *fmt, ...);
int util_file_write_ull(unsigned long long val, int base, const char *fmt, ...);
int util_file_read_va(const char *path, const char *fmt, ...);
#endif /** LIB_UTIL_FILE_H @} */

View File

@@ -4,9 +4,7 @@ libs = $(rootdir)/libutil/libutil.a
all: chreipl lsreipl chshut lsshut
libs = $(rootdir)/libutil/libutil.a
objects = main.o ccw.o fcp.o system.o shutdown.o \
objects = main.o ccw.o fcp.o nvme.o system.o shutdown.o \
cmd_lsshut.o cmd_chshut.o cmd_lsreipl.o cmd_chreipl.o proc.o
chreipl: $(objects) $(libs)

View File

@@ -28,12 +28,14 @@ enum target_type {
TT_FCP,
TT_NSS,
TT_NODE,
TT_NVME,
};
enum reipl_type {
REIPL_FCP,
REIPL_CCW,
REIPL_NSS
REIPL_NSS,
REIPL_NVME,
};
static const char *const usage_chreipl =
@@ -41,6 +43,7 @@ static const char *const usage_chreipl =
"\n"
" chreipl [ccw] [-d] <DEVICE> [OPTIONS]\n"
" chreipl [fcp] [-d] <DEVICE> [-w] <WWPN> [-l] <LUN> [OPTIONS]\n"
" chreipl nvme [-i] <FID> [-s] <NSID> [OPTIONS]\n"
" chreipl [node] <NODE|DIR> [OPTIONS]\n"
" chreipl nss [-n] <NAME> [OPTIONS]\n"
" chreipl [-h] [-v]\n"
@@ -48,6 +51,7 @@ static const char *const usage_chreipl =
"The following re-IPL targets are supported:\n"
" ccw IPL from CCW device\n"
" fcp IPL from FCP device\n"
" nvme IPL from NVME device\n"
" nss IPL from NSS\n"
" node IPL from device specified by device node or directory\n"
"\n"
@@ -70,6 +74,13 @@ static const char *const usage_chreipl =
" -L, --loadparm <PARM> Loadparm specification\n"
" -c, --clear 0|1 Control if memory is cleared on re-IPL\n"
"\n"
"Options for nvme target:\n"
" -i, --fid <FUNCTION_ID> PCI Function ID of NVME IPL device (hex)\n"
" -s --nsid <NAMESPACE_ID> Namespace ID of NVME IPL device (decimal, default 1)\n"
" -b, --bootprog <BPROG> Bootprog specification\n"
" -L, --loadparm <PARM> Loadparm specification\n"
" -c, --clear 0|1 Control if memory is cleared on re-IPL\n"
"\n"
"Options for nss target:\n"
" -n, --name <NAME> Identifier of the NSS\n"
"\n"
@@ -86,6 +97,10 @@ static struct locals {
char lun[20]; /* 18 character +0x" */
int lun_set;
char busid[10]; /* Bus ID e.g. 0.0.4711 */
int fid_set;
char fid[FID_MAX_LEN];
int nsid_set;
char nsid[11]; /* 10 decimal chars + null */
int busid_set;
char dev[15]; /* Device (e.g. dasda) */
int dev_set;
@@ -94,10 +109,10 @@ static struct locals {
char bootparms[4096];
int bootparms_set;
int force_set;
enum target_type target_type; /* CCW, FCP, NSS or NODE */
enum target_type target_type; /* CCW,FCP,NVME,NSS or NODE */
int target_type_set;
int target_type_auto_mode;
enum reipl_type reipl_type; /* CCW, FCP, NSS */
enum reipl_type reipl_type; /* CCW, FCP, NVME, NSS */
int reipl_clear;
} l;
@@ -229,6 +244,34 @@ static void set_wwpn(const char *wwpn)
l.wwpn_set = 1;
}
static void set_nvme_nsid(const char *nsid)
{
unsigned long long nsid_tmp;
char *endptr;
nsid_tmp = strtoull(nsid, &endptr, 10);
if (*endptr)
ERR_EXIT("NSID \"%s\" is not a decimal number", nsid);
snprintf(l.nsid, sizeof(l.nsid), "%08llu", nsid_tmp);
l.nsid_set = 1;
}
static void set_nvme_fid(const char *fid)
{
unsigned long long fid_tmp;
char *endptr;
fid_tmp = strtoull(fid, &endptr, 16);
if (*endptr)
ERR_EXIT("FID \"%s\" is not a hexadecimal number", fid);
snprintf(l.fid, sizeof(l.fid), "0x%08llx", fid_tmp);
l.fid_set = 1;
/* nsid defaults to 1, if not already set */
if (!l.nsid_set)
set_nvme_nsid("1");
}
static void parse_fcp_args(char *nargv[], int nargc)
{
/*
@@ -248,6 +291,28 @@ static void parse_fcp_args(char *nargv[], int nargc)
set_lun(nargv[2]);
}
static void parse_nvme_args(char *nargv[], int nargc)
{
/*
* we might be called like this:
* chreipl nvme 0x13 1
*/
if (l.busid_set || l.fid_set || l.nsid_set || l.dev_set)
ERR_EXIT("Use either options or positional parameters");
if (nargc > 2)
ERR_EXIT("Too many arguments specified for \"nvme\" re-IPL "
"type");
else if (nargc < 1)
ERR_EXIT("The \"nvme\" re-IPL type requires function id, and "
"optional namespace id");
set_nvme_fid(nargv[0]);
if (nargc == 2)
set_nvme_nsid(nargv[1]);
else
set_nvme_nsid("1");
}
static void parse_ccw_args(char *nargv[], int nargc)
{
/*
@@ -288,6 +353,13 @@ static void dev_from_part(char *dev_name)
dev_name[i] = 0;
}
static void dev_from_part_nvme(char *dev_name)
{
char *delim = strrchr(dev_name, 'p');
if (delim)
*delim = 0;
}
static int set_reipl_type(const char *dev_name)
{
if (strncmp(dev_name, "dasd", strlen("dasd")) == 0 ||
@@ -295,11 +367,18 @@ static int set_reipl_type(const char *dev_name)
l.reipl_type = REIPL_CCW;
else if (strncmp(dev_name, "sd", strlen("sd")) == 0)
l.reipl_type = REIPL_FCP;
else if (strncmp(dev_name, "nvme", strlen("nvme")) == 0)
l.reipl_type = REIPL_NVME;
else
return -1;
util_strlcpy(l.dev, dev_name, sizeof(l.dev));
dev_from_part(l.dev);
if (l.reipl_type == REIPL_NVME)
dev_from_part_nvme(l.dev);
else
dev_from_part(l.dev);
l.dev_set = 1;
return 0;
}
@@ -402,6 +481,9 @@ static void parse_pos_args(char *nargv[], int nargc)
case TT_FCP:
parse_fcp_args(nargv, nargc);
break;
case TT_NVME:
parse_nvme_args(nargv, nargc);
break;
case TT_CCW:
parse_ccw_args(nargv, nargc);
break;
@@ -423,6 +505,14 @@ static void check_fcp_opts(void)
"and LUN");
}
static void check_nvme_opts(void)
{
if (l.nss_name_set || l.wwpn_set || l.lun_set || l.busid_set)
ERR_EXIT("Invalid option for \"nvme\" target specified");
if (!(l.fid_set && l.nsid_set))
ERR_EXIT("The \"nvme\" target requires FID, and optional NSID");
}
static void check_ccw_opts(void)
{
if (l.bootprog_set || l.lun_set || l.wwpn_set || l.nss_name_set)
@@ -482,6 +572,8 @@ static void parse_chreipl_options(int argc, char *argv[])
{ "device", required_argument, NULL, 'd' },
{ "lun", required_argument, NULL, 'l' },
{ "wwpn", required_argument, NULL, 'w' },
{ "fid", required_argument, NULL, 'i' },
{ "nsid", required_argument, NULL, 's' },
{ "loadparm", required_argument, NULL, 'L' },
{ "name", required_argument, NULL, 'n' },
{ "bootparms", required_argument, NULL, 'p' },
@@ -490,7 +582,7 @@ static void parse_chreipl_options(int argc, char *argv[])
{ "clear", required_argument, NULL, 'c' },
{ NULL, 0, NULL, 0 }
};
static const char optstr[] = "hd:vw:l:fL:b:n:p:c:";
static const char optstr[] = "hd:vw:l:fL:b:n:p:c:i:s:";
/* dont run without any argument */
if (argc == 1)
@@ -502,6 +594,8 @@ static void parse_chreipl_options(int argc, char *argv[])
set_target_type(TT_CCW, 0);
else if (strcmp(argv[1], "nss") == 0)
set_target_type(TT_NSS, 0);
else if (strcmp(argv[1], "nvme") == 0)
set_target_type(TT_NVME, 0);
else if (strcmp(argv[1], "node") == 0)
set_target_type(TT_NODE, 0);
else
@@ -516,9 +610,15 @@ static void parse_chreipl_options(int argc, char *argv[])
case 'd':
set_device(optarg);
break;
case 'i':
set_nvme_fid(optarg);
break;
case 'l':
set_lun(optarg);
break;
case 's':
set_nvme_nsid(optarg);
break;
case 'w':
set_wwpn(optarg);
break;
@@ -680,6 +780,45 @@ static void chreipl_fcp(void)
print_fcp(0, 0);
}
static void chreipl_nvme(void)
{
check_nvme_opts();
if (!nvme_is_device(l.fid, l.nsid) && !l.force_set) {
ERR_EXIT("Could not find NVME device with fid %s and nsid %s",
l.fid, l.nsid);
}
check_exists("reipl/nvme/fid", "\"nvme\" re-IPL target");
if (l.bootparms_set && strlen(l.bootparms) > BOOTPARMS_FCP_MAX) {
ERR_EXIT("Maximum boot parameter length exceeded (%zu/%u)",
strlen(l.bootparms), BOOTPARMS_FCP_MAX);
}
if (l.reipl_clear >= 0) {
check_exists("reipl/nvme/clear", "NVME re-IPL clear attribute");
write_str(l.reipl_clear ? "1" : "0", "reipl/nvme/clear");
}
write_str_optional(l.loadparm, "reipl/nvme/loadparm", l.loadparm_set,
"loadparm");
write_str_optional(l.bootparms, "reipl/nvme/scp_data", l.bootparms_set,
"boot parameters");
write_str(l.fid, "reipl/nvme/fid");
write_str(l.nsid, "reipl/nvme/nsid");
/*
* set the boot record logical block address. Master boot
* record. It is always 0 for Linux
*/
write_str("0", "reipl/nvme/br_lba");
if (!l.bootprog_set)
sprintf(l.bootprog, "0");
write_str(l.bootprog, "reipl/nvme/bootprog");
write_str("nvme", "reipl/reipl_type");
print_nvme(0, 0);
}
static void chreipl_nss(void)
{
check_nss_opts();
@@ -720,6 +859,13 @@ static void chreipl_node(void)
l.busid_set = 1;
chreipl_fcp();
break;
case REIPL_NVME:
nvme_fid_get(l.dev, l.fid);
l.fid_set = 1;
nvme_nsid_get(l.dev, l.nsid);
l.nsid_set = 1;
chreipl_nvme();
break;
default:
ERR_EXIT("Internal error: chreipl_node");
}
@@ -735,6 +881,9 @@ void cmd_chreipl(int argc, char *argv[])
case TT_FCP:
chreipl_fcp();
break;
case TT_NVME:
chreipl_nvme();
break;
case TT_NSS:
chreipl_nss();
break;

View File

@@ -84,6 +84,38 @@ void print_fcp(int show_ipl, int dump)
print_fw_str("clear: %s\n", dir, "clear");
}
void print_nvme(int show_ipl, int dump)
{
char *dir = show_ipl ? "ipl" : "reipl/nvme";
char *path_bootparms = show_ipl ? "/sys/firmware/ipl/scp_data" :
"/sys/firmware/reipl/nvme/scp_data";
char *path_loadparm = show_ipl ? "/sys/firmware/ipl/loadparm" :
"/sys/firmware/reipl/nvme/loadparm";
char loadparm[9], loadparm_path[PATH_MAX];
char *path_reipl_clear = "/sys/firmware/reipl/nvme/clear";
if (dump)
printf("%-12s nvme_dump\n", get_ipl_banner(show_ipl));
else
printf("%-12s nvme\n", get_ipl_banner(show_ipl));
print_fw_str("FID: %s\n", dir, "fid");
print_fw_str("NSID: %s\n", dir, "nsid");
print_fw_str("bootprog: %s\n", dir, "bootprog");
print_fw_str("br_lba: %s\n", dir, "br_lba");
if (access(path_loadparm, R_OK) == 0) {
sprintf(loadparm_path, "%s/%s", dir, "loadparm");
read_fw_str(loadparm, loadparm_path, sizeof(loadparm));
if (strcmp(loadparm, " ") == 0)
loadparm[0] = 0;
printf("Loadparm: \"%s\"\n", loadparm);
}
if (access(path_bootparms, R_OK) == 0)
print_fw_str("Bootparms: \"%s\"\n", dir, "scp_data");
if (!show_ipl && access(path_reipl_clear, R_OK) == 0)
print_fw_str("clear: %s\n", dir, "clear");
}
void print_ccw(int show_ipl)
{
char loadparm[9], loadparm_path[PATH_MAX];
@@ -155,6 +187,10 @@ void cmd_lsreipl(int argc, char *argv[])
print_fcp(l.ipl_set, 0);
else if (strcmp(reipl_type_str, "fcp_dump") == 0)
print_fcp(l.ipl_set, 1);
else if (strcmp(reipl_type_str, "nvme") == 0)
print_nvme(l.ipl_set, 0);
else if (strcmp(reipl_type_str, "nvme_dump") == 0)
print_nvme(l.ipl_set, 1);
else if (strcmp(reipl_type_str, "ccw") == 0)
print_ccw(l.ipl_set);
else if (strcmp(reipl_type_str, "nss") == 0)

View File

@@ -43,6 +43,7 @@ extern void cmd_chreipl(int argc, char *argv[]);
extern void print_ccw(int show_ipl);
extern void print_fcp(int show_ipl, int dump);
extern void print_nvme(int show_ipl, int dump);
extern void print_nss(int show_ipl);
/*
@@ -70,6 +71,16 @@ extern void fcp_lun_get(const char *device, char *lun);
extern void fcp_wwpn_get(const char *device, char *wwpn);
extern void fcp_busid_get(const char *device, char *devno);
/*
* NVME
*/
#define FID_MAX_LEN 11 /* 8 characters + 0x + null */
#define NVME_PATH_MAX (PATH_MAX + NAME_MAX + 1)
extern void nvme_fid_get(const char *device, char *fid);
extern void nvme_nsid_get(const char *device, char *nsid);
int nvme_is_device(char *fid_str, char *nsid_str);
/*
* CCW
*/

View File

@@ -39,6 +39,9 @@ Specify a DASD CCW device for reboot
.RB "- " fcp :
Specify a FCP device for reboot
.TP
.RB "- " nvme :
Specify an NVMe device for reboot
.TP
.RB "- " nss :
Specify a named saved system (NSS) for reboot
.TP
@@ -118,6 +121,11 @@ WWPN 0x500507630300c562, and LUN 0x401040b300000000. In addition to that
append kernel parameter "mem=" to restrict memory to 512 MB:
\fB# chreipl 0.0.1700 0x500507630300c562 0x401040b300000000 -p "mem=512M"\fP
4. Next time reboot from the NVMe device with function id 0x13, namespace 1:
\fB# chreipl nvme 0x13 1
.SH ccw
Use the ccw re-IPL target for DASD devices that are accessed by the hardware
using channel command word (CCW) channels.
@@ -207,6 +215,51 @@ use options instead of positional parameters:
.br
\fB# chreipl fcp -d 0.0.1700 -w 0x5005076... -l 0x401040b3... -b 2\fP
.SH nvme
Use the nvme re-IPL target for specifying an NVMe disk for reboot.
.TP
.BR "\-i" " or " "\-\-fid"
PCI Function ID of NVME IPL device (hex).
.TP
.BR "\-s" " or " "\-\-nsid"
Namespace ID of the NVME IPL device (decimal, default 1).
.TP
.BR "\-b" " or " "\-\-bootprog"
Specifies an entry in the boot configuration by defining the IPL boot
program selector. If omitted, '0' will be used.
.TP
.BR "\-L" " or " "\-\-loadparm"
The loadparm for the nvme re-IPL target is not used to control the boot
configuration that is defined by the
.BR zipl (8)
boot menu. Instead it can be used to control higher level boot loaders
like GRUB. For more details refer to distribution specific documentation.
.TP
.BR "\-c" " or " "\-\-clear"
Specify whether memory should be cleared on re-IPL. Possible values are 0 to
disable and 1 to enable memory clearing on re-IPL.
Memory clearing is supported if the "clear" attribute is present in
/sys/firmware/reipl/nvme/.
.PP
\fBExamples:\fP
.br
1. Next time reboot from the NVMe disk with function-id 0x13 and namespace 1:
.br
\fB# chreipl nvme 0x13 1\fP
.br
2. Use same configuration as (1) but choose boot program selector 2 and
use options instead of positional parameters:
.br
\fB# chreipl nvme -i 0x13 -s 1 -b 2\fP
.SH nss
Use the nss re-IPL target to specify z/VM named saved systems (NSS) for
reboot.
@@ -221,7 +274,7 @@ Use the NSS named LINUX1 for the next reboot:
\fB# chreipl nss LINUX1\fP
.SH node
You can identify DASD or SCSI re-IPL devices indirectly through a device
You can identify DASD, SCSI, or NVMe re-IPL devices indirectly through a device
node or directory. The chreipl tool then determines the information
that you would otherwise have to specify with the ccw or fcp target.
.PP
@@ -244,6 +297,11 @@ that you would otherwise have to specify with the ccw or fcp target.
\fB# chreipl node /mnt/boot\fP
4. Next time reboot from the NVMe device represented by /dev/nvme0n1
.br
\fB# chreipl node /dev/nvme0n1\fP
.SH SEE ALSO
.BR lsreipl (8),
.BR zipl (8),

169
ipl_tools/nvme.c Normal file
View File

@@ -0,0 +1,169 @@
/*
* ipl_tools - Linux for System z reipl and shutdown tools
*
* NVMe device functions
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <sys/types.h>
#include <dirent.h>
#include <limits.h>
#include <stdlib.h>
#include <unistd.h>
#include "lib/util_libc.h"
#include "lib/util_file.h"
#include "ipl_tools.h"
/*
* Return the fid of a device
*/
void nvme_fid_get(const char *device, char *fid)
{
char path[PATH_MAX], buf[FID_MAX_LEN];
snprintf(path, PATH_MAX, "/sys/block/%s/device/device/function_id",
device);
if (util_file_read_line(buf, FID_MAX_LEN, path))
ERR_EXIT_ERRNO("Could not read from \"%s\"", path);
util_strlcpy(fid, buf, FID_MAX_LEN);
}
/*
* Return the nsid of a device
*/
void nvme_nsid_get(const char *device, char *nsid)
{
char path[PATH_MAX], buf[FID_MAX_LEN];
snprintf(path, PATH_MAX, "/sys/block/%s/nsid", device);
if (util_file_read_line(buf, FID_MAX_LEN, path))
ERR_EXIT_ERRNO("Could not read from \"%s\"", path);
util_strlcpy(nsid, buf, FID_MAX_LEN);
}
static int next_entry(DIR *dir, char *in_path, char *out_path,
unsigned char entry_type)
{
struct dirent *dirent;
char temp_path[NVME_PATH_MAX];
while ((dirent = readdir(dir)) != NULL) {
if (strcmp(dirent->d_name, ".") == 0 ||
strcmp(dirent->d_name, "..") == 0 ||
dirent->d_type != entry_type)
continue;
/* Resolve the symlink, if needed */
if (dirent->d_type == DT_LNK) {
snprintf(temp_path, sizeof(temp_path), "%s/%s", in_path,
dirent->d_name);
if (!realpath(temp_path, out_path))
ERR_EXIT_ERRNO("Could not resolve link %s",
temp_path);
return 1;
}
snprintf(out_path, NVME_PATH_MAX, "%s/%s", in_path,
dirent->d_name);
return 1;
}
return 0;
}
static int nvme_getdev_by_fid(char *fidstr, char *devpath)
{
char temp_path[PATH_MAX+19], real_path[PATH_MAX];
char *sys_path = "/sys/class/nvme";
u_int64_t target_fid, curfid;
DIR *dir;
char *end;
int rc = -1;
target_fid = strtoul(fidstr, &end, 16);
if (*end)
ERR_EXIT("Invalid function_id given %s", fidstr);
dir = opendir(sys_path);
if (!dir)
ERR_EXIT("Could not open %s", sys_path);
errno = 0;
while (next_entry(dir, sys_path, real_path, DT_LNK)) {
snprintf(temp_path, sizeof(temp_path), "%s/%s", real_path,
"device/function_id");
if (access(temp_path, F_OK))
continue;
if (util_file_read_ul(&curfid, 16, temp_path))
ERR_EXIT("Invalid function_id found in %s", temp_path);
if (curfid == target_fid) {
strncpy(devpath, real_path, PATH_MAX);
rc = 0;
break;
}
}
closedir(dir);
return rc;
}
static int nvme_getdev_by_nsid(char *nsid_str, char *path, char *dev_path)
{
char full_path[NVME_PATH_MAX+1], nsid_path[sizeof(full_path)+5];
char *end;
u_int64_t nsid, curnsid;
DIR *dir;
nsid = strtoul(nsid_str, &end, 10);
if (*end)
ERR_EXIT_ERRNO("Invalid namespace id given %s", nsid_str);
dir = opendir(path);
if (!dir)
ERR_EXIT_ERRNO("Could not open %s", path);
errno = 0;
while (next_entry(dir, path, full_path, DT_DIR)) {
snprintf(nsid_path, sizeof(nsid_path), "%s/%s", full_path,
"nsid");
if (access(nsid_path, F_OK))
continue;
if (util_file_read_ul(&curnsid, 10, nsid_path))
ERR_EXIT("Invalid namespace id found in %s", nsid_path);
if (curnsid == nsid) {
strncpy(dev_path, full_path, NVME_PATH_MAX+1);
closedir(dir);
return 0;
}
}
closedir(dir);
return -1;
}
static int nvme_getdev(char *fid_str, char *nsid_str, char *dev_path)
{
char path_tmp[NVME_PATH_MAX];
if (nvme_getdev_by_fid(fid_str, path_tmp))
return -1;
return nvme_getdev_by_nsid(nsid_str, path_tmp, dev_path);
}
/*
* Check if the specified fid and nsid leads to a valid nvme device
*/
int nvme_is_device(char *fid_str, char *nsid_str)
{
char path_tmp[NVME_PATH_MAX+1];
return !(nvme_getdev(fid_str, nsid_str, path_tmp));
}

85
libekmfweb/Makefile Normal file
View File

@@ -0,0 +1,85 @@
include ../common.mak
ifneq (${HAVE_OPENSSL},0)
ifneq (${HAVE_JSONC},0)
ifneq (${HAVE_LIBCURL},0)
BUILD_TARGETS += libekmfweb.so
INSTALL_TARGETS += install-libekmfweb.so
else
BUILD_TARGETS += skip-libekmfweb-curl
INSTALL_TARGETS += skip-libekmfweb-curl
endif
else
BUILD_TARGETS += skip-libekmfweb-jsonc
INSTALL_TARGETS += skip-libekmfweb-jsonc
endif
else
BUILD_TARGETS += skip-libekmfweb-openssl
INSTALL_TARGETS += skip-libekmfweb-openssl
endif
libs = $(rootdir)/libutil/libutil.a
detect-openssl-version.dep:
echo "#include <openssl/opensslv.h>" > detect-openssl-version.dep
echo "#include <openssl/evp.h>" >> detect-openssl-version.dep
echo "#if OPENSSL_VERSION_NUMBER < 0x10101000L" >> detect-openssl-version.dep
echo " #error openssl version 1.1.1 is required" >> detect-openssl-version.dep
echo "#endif" >> detect-openssl-version.dep
echo "static void __attribute__((unused)) test(void) {" >> detect-openssl-version.dep
echo " EVP_PKEY_meth_remove(NULL);" >> detect-openssl-version.dep
echo "}" >> detect-openssl-version.dep
check-dep-libekmfweb: detect-openssl-version.dep
$(call check_dep, \
"libekmfweb", \
"detect-openssl-version.dep", \
"openssl-devel version >= 1.1.1", \
"HAVE_OPENSSL=0", \
-I. -lcrypto)
$(call check_dep, \
"libekmfweb", \
"json-c/json.h", \
"json-c-devel", \
"HAVE_JSONC=0")
$(call check_dep, \
"libekmfweb", \
"curl/curl.h", \
"libcurl-devel", \
"HAVE_LIBCURL=0")
touch check-dep-libekmfweb
skip-libekmfweb-openssl:
echo " SKIP libekmfweb due to HAVE_OPENSSL=0"
skip-libekmfweb-jsonc:
echo " SKIP libekmfweb due to HAVE_JSONC=0"
skip-libekmfweb-curl:
echo " SKIP libekmfweb due to HAVE_LIBCURL=0"
all: $(BUILD_TARGETS)
ekmfweb.o: check-dep-libekmfweb ekmfweb.c utilities.h cca.h $(rootdir)include/ekmfweb/ekmfweb.h
utilities.o: check-dep-libekmfweb utilities.c utilities.h $(rootdir)include/ekmfweb/ekmfweb.h
cca.o: check-dep-libekmfweb cca.c cca.h utilities.h $(rootdir)include/ekmfweb/ekmfweb.h
libekmfweb.so: ALL_CFLAGS += -fPIC
libekmfweb.so: LDLIBS = -ljson-c -lcrypto -lssl -lcurl -ldl -shared
libekmfweb.so: LDFLAGS = -shared -Wl,--version-script=libekmfweb.map \
-Wl,-z,defs,-Bsymbolic
libekmfweb.so: ekmfweb.o utilities.o cca.o
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
install-libekmfweb.so: libekmfweb.so
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 -T libekmfweb.so $(DESTDIR)$(LIB64DIR)/libekmfweb.so
$(INSTALL) -d -m 770 $(DESTDIR)$(USRINCLUDEDIR)/ekmfweb
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 $(rootdir)include/ekmfweb/ekmfweb.h $(DESTDIR)$(USRINCLUDEDIR)/ekmfweb
install: all $(INSTALL_TARGETS)
clean:
rm -f *.o libekmfweb.so check-dep-libekmfweb detect-openssl-version.dep
.PHONY: all install clean skip-libekmfweb-openssl skip-libekmfweb-jsonc \
skip-libekmfweb-curl install-libekmfweb.so

1793
libekmfweb/cca.c Normal file

File diff suppressed because it is too large Load Diff

247
libekmfweb/cca.h Normal file
View File

@@ -0,0 +1,247 @@
/*
* libekmfweb - EKMFWeb client library
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef CCA_H
#define CCA_H
#include <stddef.h>
#include <stdbool.h>
#include <openssl/evp.h>
#include <json-c/json.h>
#include "ekmfweb/ekmfweb.h"
/* CCA PKA Key Generate function */
typedef void (*CSNDPKG_t)(long *return_code,
long *reason_code,
long *exit_data_length,
unsigned char *exit_data,
long *rule_array_count,
unsigned char *rule_array,
long *regeneration_data_length,
unsigned char *regeneration_data,
long *skeleton_key_token_length,
unsigned char *skeleton_key_token,
unsigned char *transport_key_identifier,
long *generated_key_identifier_length,
unsigned char *generated_key_identifier);
/* CCA PKA Key Token Build function */
typedef void (*CSNDPKB_t)(long *return_code,
long *reason_code,
long *exit_data_length,
unsigned char *exit_data,
long *rule_array_count,
unsigned char *rule_array,
long *key_values_structure_length,
unsigned char *key_values_structure,
long *key_name_ln,
unsigned char *key_name,
long *reserved_1_length,
unsigned char *reserved_1,
long *reserved_2_length,
unsigned char *reserved_2,
long *reserved_3_length,
unsigned char *reserved_3,
long *reserved_4_length,
unsigned char *reserved_4,
long *reserved_5_length,
unsigned char *reserved_5,
long *token_length, unsigned char *token);
/* CCA PKA Key Token Change function */
typedef void (*CSNDKTC_t)(long *return_code,
long *reason_code,
long *exit_data_length,
unsigned char *exit_data,
long *rule_array_count,
unsigned char *rule_array,
long *key_identifier_length,
unsigned char *key_identifier);
/* CCA Digital Signature Generate function */
typedef void (*CSNDDSG_t)(long *return_code,
long *reason_code,
long *exit_data_length,
unsigned char *exit_data,
long *rule_array_count,
unsigned char *rule_array,
long *PKA_private_key_identifier_length,
unsigned char *PKA_private_key_identifier,
long *hash_length,
unsigned char *hash,
long *signature_field_length,
long *signature_bit_length,
unsigned char *signature_field);
/* CCA Key Token Build2 function */
typedef void (*CSNBKTB2_t)(long *return_code,
long *reason_code,
long *exit_data_length,
unsigned char *exit_data,
long *rule_array_count,
unsigned char *rule_array,
long *clear_key_bit_length,
unsigned char *clear_key_value,
long *key_name_length,
unsigned char *key_name,
long *user_associated_data_length,
unsigned char *user_associated_data,
long *token_data_length,
unsigned char *token_data,
long *verb_data_length,
unsigned char *verb_data,
long *target_key_token_length,
unsigned char *target_key_token);
/* CCA EC Diffie-Hellman function */
typedef void (*CSNDEDH_t)(long *return_code,
long *reason_code,
long *exit_data_length,
unsigned char *exit_data,
long *rule_array_count,
unsigned char *rule_array,
long *private_key_identifier_length,
unsigned char *private_key_identifier,
long *private_KEK_key_identifier_length,
unsigned char *private_KEK_key_identifier,
long *public_key_identifier_length,
unsigned char *public_key_identifier,
long *chaining_vector_length,
unsigned char *chaining_vector,
long *party_info_length,
unsigned char *party_info,
long *key_bit_length,
long *reserved_1_length,
unsigned char *reserved_1,
long *reserved_2_length,
unsigned char *reserved_2,
long *reserved_3_length,
unsigned char *reserved_3,
long *reserved_4_length,
unsigned char *reserved_4,
long *reserved_5_length,
unsigned char *reserved_5,
long *output_KEK_key_identifier_length,
unsigned char *output_KEK_key_identifier,
long *output_key_identifier_length,
unsigned char *output_key_identifier);
/* CCA Symmetric Key Import2 function */
typedef void (*CSNDSYI2_t)(long *return_code,
long *reason_code,
long *exit_data_length,
unsigned char *exit_data,
long *rule_array_count,
unsigned char *rule_array,
long *enciphered_key_length,
unsigned char *enciphered_key,
long *transport_key_identifier_length,
unsigned char *transport_key_identifier,
long *key_name_length,
unsigned char *key_name,
long *target_key_identifier_length,
unsigned char *target_key_identifier);
struct cca_lib {
CSNDPKB_t dll_CSNDPKB;
CSNDPKG_t dll_CSNDPKG;
CSNDKTC_t dll_CSNDKTC;
CSNDDSG_t dll_CSNDDSG;
CSNBKTB2_t dll_CSNBKTB2;
CSNDEDH_t dll_CSNDEDH;
CSNDSYI2_t dll_CSNDSYI2;
};
#define CCA_MAX_PKA_KEY_TOKEN_SIZE 3500
#define CCA_MAX_SYM_KEY_TOKEN_SIZE 725
int cca_generate_ecc_key_pair(const struct ekmf_cca_lib *cca_lib,
int curve_nid, unsigned char *key_token,
size_t *key_token_length, bool verbose);
int cca_generate_rsa_key_pair(const struct ekmf_cca_lib *cca_lib,
size_t modulus_bits, unsigned int pub_exp,
unsigned char *key_token,
size_t *key_token_length, bool verbose);
int cca_get_key_type(const unsigned char *key_token, size_t key_token_length,
int *pkey_type);
int cca_reencipher_key(const struct ekmf_cca_lib *cca_lib,
const unsigned char *key_token, size_t key_token_length,
bool to_new, bool verbose);
int cca_get_ecc_pub_key_as_pkey(const unsigned char *key_token,
size_t key_token_length,
EVP_PKEY **pkey, bool verbose);
int cca_get_ecc_pub_key_as_json_web_key(const unsigned char *key_token,
size_t key_token_length,
json_object **jwk, bool verbose);
int cca_get_rsa_pub_key_as_pkey(const unsigned char *key_token,
size_t key_token_length,
int pkey_type, EVP_PKEY **pkey, bool verbose);
int cca_import_key_from_json_web_key(const struct ekmf_cca_lib *cca_lib,
json_object *jwk, unsigned char *key_token,
size_t *key_token_length, bool verbose);
enum cca_kdf {
CCA_KDF_ANS_X9_63_CCA = 1, /* CCA DERIVE01 method */
CCA_KDF_ANS_X9_63_SHA224 = 2, /* CCA DERIVE02 method with SHA-224 */
CCA_KDF_ANS_X9_63_SHA256 = 3, /* CCA DERIVE02 method with SHA-256 */
CCA_KDF_ANS_X9_63_SHA384 = 4, /* CCA DERIVE02 method with SHA-284 */
CCA_KDF_ANS_X9_63_SHA512 = 5, /* CCA DERIVE02 method with SHA-512 */
};
int cca_ec_dh_derive_importer(const struct ekmf_cca_lib *cca_lib,
const unsigned char *priv_ecc_key_token,
size_t priv_ecc_key_token_length,
const unsigned char *pub_ecc_key_token,
size_t pub_ecc_key_token_length,
const unsigned char *party_info,
size_t party_info_length,
enum cca_kdf kdf,
unsigned char *derived_key_token,
size_t *derived_key_token_length,
bool verbose);
int cca_import_external_key(const struct ekmf_cca_lib *cca_lib,
const unsigned char *external_key_token,
size_t external_key_token_length,
const unsigned char *importer_key_token,
size_t importer_key_token_length,
unsigned char *imported_key_token,
size_t *imported_key_token_length,
bool verbose);
int cca_rsa_sign(const struct ekmf_cca_lib *cca_lib,
const unsigned char *key_token, size_t key_token_length,
unsigned char *sig, size_t *siglen,
const unsigned char *tbs, size_t tbslen,
int padding_type, int digest_nid, bool verbose);
int cca_rsa_pss_sign(const struct ekmf_cca_lib *cca_lib,
const unsigned char *key_token, size_t key_token_length,
unsigned char *sig, size_t *siglen,
const unsigned char *tbs, size_t tbslen,
int digest_nid, int mgf_digest_nid, int saltlen,
bool verbose);
int cca_ecdsa_sign(const struct ekmf_cca_lib *cca_lib,
const unsigned char *key_token, size_t key_token_length,
unsigned char *sig, size_t *siglen,
const unsigned char *tbs, size_t tbslen, int digest_nid,
bool verbose);
#endif

5631
libekmfweb/ekmfweb.c Normal file

File diff suppressed because it is too large Load Diff

30
libekmfweb/libekmfweb.map Normal file
View File

@@ -0,0 +1,30 @@
LIBEKMFWEB_1.0 {
global:
ekmf_get_server_cert_chain;
ekmf_print_certificates;
ekmf_check_login_token;
ekmf_login;
ekmf_generate_identity_key;
ekmf_reencipher_identity_key;
ekmf_generate_csr;
ekmf_generate_ss_cert;
ekmf_get_public_key;
ekmf_get_settings;
ekmf_check_feature;
ekmf_retrieve_key;
ekmf_list_templates;
ekmf_get_template;
ekmf_get_last_seq_no;
ekmf_clone_template_info;
ekmf_free_template_info;
ekmf_list_keys;
ekmf_get_key_info;
ekmf_set_key_state;
ekmf_set_key_tags;
ekmf_delete_key_tags;
ekmf_clone_key_info;
ekmf_free_key_info;
ekmf_generate_key;
ekmf_curl_destroy;
local: *;
};

3528
libekmfweb/utilities.c Normal file

File diff suppressed because it is too large Load Diff

179
libekmfweb/utilities.h Normal file
View File

@@ -0,0 +1,179 @@
/*
* libekmfweb - EKMFWeb client library
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef UTILITIES_H
#define UTILITIES_H
#include <stddef.h>
#include <stdbool.h>
#include <openssl/x509.h>
#include <openssl/obj_mac.h>
#include <openssl/evp.h>
#include <json-c/json.h>
#include <curl/curl.h>
#include "ekmfweb/ekmfweb.h"
int decode_base64url(unsigned char *output, size_t *outlen,
const char *input, size_t inlen);
int encode_base64url(char *output, size_t *outlen,
const unsigned char *input, size_t inlen);
int parse_json_web_token(const char *token, json_object **header_obj,
json_object **payload_obj, unsigned char **signature,
size_t *signature_len);
int create_json_web_signature(const char *algorithm, bool b64, const char *kid,
const unsigned char *payload, size_t payload_len,
bool detached_payload, EVP_MD_CTX *md_ctx,
char **jws);
int verify_json_web_signature(const char *jws, const unsigned char *payload,
size_t payload_len, EVP_PKEY *pkey);
json_object *get_json_timestamp(void);
int json_build_tag_def_list(json_object *array,
struct ekmf_tag_def_list *tag_def_list,
bool copy);
int clone_tag_def_list(const struct ekmf_tag_def_list *src,
struct ekmf_tag_def_list *dest);
void free_tag_def_list(struct ekmf_tag_def_list *tag_def_list, bool free_tags);
int json_build_template_info(json_object *obj,
struct ekmf_template_info *template,
bool copy);
int clone_template_info(const struct ekmf_template_info *src,
struct ekmf_template_info *dest);
void free_template_info(struct ekmf_template_info *template);
int json_build_tag_list(json_object *array, struct ekmf_tag_list *tag_list,
bool copy);
int build_json_tag_list(const struct ekmf_tag_list *tag_list,
json_object **tags_obj);
int clone_tag_list(const struct ekmf_tag_list *src,
struct ekmf_tag_list *dest);
void free_tag_list(struct ekmf_tag_list *tag_list, bool free_tags);
int json_build_export_control(json_object *export_control,
struct ekmf_export_control *export_info,
bool copy);
int clone_export_control(const struct ekmf_export_control *src,
struct ekmf_export_control *dest);
void free_export_control(struct ekmf_export_control *export_control,
bool free_keys);
int json_build_key_info(json_object *obj, json_object *custom_tags,
json_object *export_control,
struct ekmf_key_info *key, bool copy);
int clone_key_info(const struct ekmf_key_info *src,
struct ekmf_key_info *dest);
void free_key_info(struct ekmf_key_info *key);
char *get_http_header_value(const struct curl_slist *headers, const char *name);
size_t ecc_get_curve_prime_bits(int curve_nid);
size_t ecc_get_curve_prime_length(int curve_nid);
const char *ecc_get_curve_id(int curve_nid);
bool ecc_is_prime_curve(int curve_nid);
bool ecc_is_brainpool_curve(int curve_nid);
int ecc_get_curve_by_id(const char *curve_id);
int ecc_get_prime_curve_by_prime_bits(size_t prime_bits);
int ecc_get_brainpool_curve_by_prime_bits(size_t prime_bits);
int ecc_calculate_y_coordinate(int nid, size_t prime_len,
const unsigned char *x, int y_bit,
unsigned char *y);
int ecc_pub_key_as_pkey(int nid, size_t prime_len, const unsigned char *x,
const unsigned char *y, EVP_PKEY **pkey);
int rsa_pub_key_as_pkey(const unsigned char *modulus, size_t modulus_length,
const unsigned char *pub_exp, size_t pub_exp_length,
int pkey_type, EVP_PKEY **pkey);
int json_web_key_as_pkey(json_object *jwk, int pkey_type, EVP_PKEY **pkey);
int write_key_blob(const char *filename, unsigned char *key_blob,
size_t key_blob_len);
int read_key_blob(const char *filename, unsigned char *key_blob,
size_t *key_blob_len);
int read_x509_certificate(const char *pem_filename, X509 **cert);
int write_x509_certificate(const char *pem_filename, X509 *cert);
int write_x509_request(const char *pem_filename, X509_REQ *req, bool new_hdr);
int read_public_key(const char *pem_filename, EVP_PKEY **pkey);
int write_public_key(const char *pem_filename, EVP_PKEY *pkey);
typedef int (*rsa_sign_t)(const unsigned char *key_blob, size_t key_blob_length,
unsigned char *sig, size_t *siglen,
const unsigned char *tbs, size_t tbslen,
int padding_type, int md_nid,
void *private);
typedef int (*rsa_pss_sign_t)(const unsigned char *key_blob,
size_t key_blob_length, unsigned char *sig,
size_t *siglen, const unsigned char *tbs,
size_t tbslen, int md_nid, int mfgmd_nid,
int saltlen, void *private);
typedef int (*ecdsa_sign_t)(const unsigned char *key_blob,
size_t key_blob_length, unsigned char *sig,
size_t *siglen, const unsigned char *tbs,
size_t tbslen, int md_nid, void *private);
struct sk_pkey_sign_func {
rsa_sign_t rsa_sign;
rsa_pss_sign_t rsa_pss_sign;
ecdsa_sign_t ecdsa_sign;
};
int setup_secure_key_pkey_method(int pkey_id);
int cleanup_secure_key_pkey_method(int pkey_id);
int setup_secure_key_pkey_context(EVP_PKEY_CTX *pkey_ctx,
const unsigned char *key_blob,
size_t key_blob_len,
struct sk_pkey_sign_func *sign_funcs,
void *private);
int setup_rsa_pss_pkey_context(EVP_PKEY_CTX *pkey_ctx,
struct ekmf_rsa_pss_params *rsa_pss_params);
int build_subject_name(X509_NAME **name, const char *rdns[], size_t num_rdns,
bool utf8);
int build_certificate_extensions(X509 *cert, X509_REQ *req,
const char *exts[], size_t num_exts,
const STACK_OF(X509_EXTENSION) *addl_exts);
int generate_x509_serial_number(X509 *cert, size_t sn_bit_size);
const char *json_get_string(json_object *obj, const char *name);
int json_object_get_base64url(json_object *obj, const char *name,
unsigned char *data, size_t *data_len);
json_object *json_object_new_base64url(const unsigned char *data, size_t len);
#ifndef JSON_C_OBJECT_ADD_KEY_IS_NEW
#define JSON_C_OBJECT_ADD_KEY_IS_NEW (1 << 1)
#define IMPLEMENT_LOCAL_JSON_OBJECT_OBJECT_ADD
int json_object_object_add_ex(struct json_object *obj, const char *const key,
struct json_object *const val,
const unsigned int opts);
#endif
#endif

View File

@@ -43,6 +43,7 @@ util_prg_example: util_prg_example.o $(lib)
util_rec_example: util_rec_example.o $(lib)
$(lib): $(objects)
$(lib): ALL_CFLAGS += -fPIC
install: all

View File

@@ -281,6 +281,44 @@ int util_file_write_ull(unsigned long long val, int base, const char *fmt, ...)
return rc;
}
/**
* Read a file and convert it to signed int according to given base
*
* @param[out] val Buffer for value
* @param[in] base Base for conversion, either 8, 10, or 16
* @param[in] fmt Format string for generation of the path name
* @param[in] ... Parameters for format string
*
* @retval 0 Integer has been read correctly
* @retval -1 Error while reading file
*/
int util_file_read_i(int *val, int base, const char *fmt, ...)
{
char path[PATH_MAX], buf[512];
va_list ap;
int count;
/* Construct the file name */
UTIL_VSPRINTF(path, fmt, ap);
if (file_gets(buf, sizeof(buf), path))
return -1;
switch (base) {
case 8:
count = sscanf(buf, "%do", val);
break;
case 10:
count = sscanf(buf, "%dd", val);
break;
case 16:
count = sscanf(buf, "%dx", val);
break;
default:
util_panic("Invalid base: %d\n", base);
}
return (count == 1) ? 0 : -1;
}
/**
* Read a file and convert it to signed long according to given base
*
@@ -357,6 +395,44 @@ int util_file_read_ll(long long *val, int base, const char *fmt, ...)
return (count == 1) ? 0 : -1;
}
/**
* Read a file and convert it to unsigned int according to given base
*
* @param[out] val Buffer for value
* @param[in] base Base for conversion, either 8, 10, or 16
* @param[in] fmt Format string for generation of the path name
* @param[in] ... Parameters for format string
*
* @retval 0 Integer has been read correctly
* @retval -1 Error while reading file
*/
int util_file_read_ui(unsigned int *val, int base, const char *fmt, ...)
{
char path[PATH_MAX], buf[512];
va_list ap;
int count;
/* Construct the file name */
UTIL_VSPRINTF(path, fmt, ap);
if (file_gets(buf, sizeof(buf), path))
return -1;
switch (base) {
case 8:
count = sscanf(buf, "%uo", val);
break;
case 10:
count = sscanf(buf, "%uu", val);
break;
case 16:
count = sscanf(buf, "%ux", val);
break;
default:
util_panic("Invalid base: %d\n", base);
}
return (count == 1) ? 0 : -1;
}
/**
* Read a file and convert it to unsigned long according to given base
*
@@ -432,3 +508,31 @@ int util_file_read_ull(unsigned long long *val, int base, const char *fmt, ...)
}
return (count == 1) ? 0 : -1;
}
/**
* Read a file and convert it according to format string
*
* @param[in] path File name to read
* @param[in] fmt Format string for parsing the content
* @param[out] ... Parameters for format string
*
* @retval != -1 Number of values parsed correctly
* @retval -1 Error while reading file
*/
int util_file_read_va(const char *path, const char *fmt, ...)
{
char buf[512];
va_list ap;
int ret;
if (file_gets(buf, sizeof(buf), path))
return -1;
va_start(ap, fmt);
ret = vsscanf(buf, fmt, ap);
va_end(ap);
if (ret == EOF)
return -1;
return ret;
}

View File

@@ -49,6 +49,7 @@ struct util_opt_l *util_opt_l = &l;
#define MAX_OPTLEN 256
static int opt_max_len(void);
static bool opt_is_active(struct util_opt *opt);
/**
* Initialize the command line options
@@ -68,7 +69,9 @@ void util_opt_init(struct util_opt *opt_vec, const char *opt_prefix)
opterr = 0;
/* Get number of options */
for (count = 0; opt_vec[count].desc != NULL; count++);
for (i = 0, count = 0; opt_vec[i].desc != NULL; i++)
if (opt_is_active(&opt_vec[i]))
count++;
/*
* Allocate short option string for worst case when all options have
* optional parameters e.g "x::" and long option string.
@@ -85,7 +88,9 @@ void util_opt_init(struct util_opt *opt_vec, const char *opt_prefix)
/* Force getopt_long() to return ':' for missing required arguments */
*str++ = ':';
/* Construction of input structures for getopt_long() function. */
for (i = 0, j = 0; i < count; i++) {
for (i = 0, j = 0; opt_vec[i].desc != NULL; i++) {
if (!opt_is_active(&opt_vec[i]))
continue;
if (opt_vec[i].flags & UTIL_OPT_FLAG_SECTION)
continue;
if (!(opt_vec[i].flags & UTIL_OPT_FLAG_NOLONG)) {

View File

@@ -42,6 +42,12 @@ static struct util_opt opt_vec[] = {
.desc = "Option with a required argument REQ_ARG",
.command = COMMAND_PULL,
},
{
.option = { "test", required_argument, NULL, 't'},
.argument = "TEST",
.desc = "Option 'test' with a required argument TEST for pull",
.command = COMMAND_PULL,
},
{
.desc = "OPTIONS",
.flags = UTIL_OPT_FLAG_SECTION,
@@ -57,7 +63,12 @@ static struct util_opt opt_vec[] = {
.option = { NULL, no_argument, NULL, 'l'},
.desc = "Option with only a short name",
.flags = UTIL_OPT_FLAG_NOLONG,
.command = "push",
.command = COMMAND_PUSH,
},
{
.option = { "test", no_argument, NULL, 't'},
.desc = "Option 'test' without an argument for push",
.command = COMMAND_PUSH,
},
UTIL_OPT_SECTION("COMMON OPTIONS"),
/* Standard option: -h,--help */
@@ -122,9 +133,6 @@ int main(int argc, char *argv[])
char **my_argv = argv;
char *command = NULL;
/* Install option vector */
util_opt_init(opt_vec, NULL);
/* The command name is the very first argument */
if (argc >= 2 && strncmp(argv[1], "-", 1) != 0) {
command = argv[1];
@@ -144,6 +152,9 @@ int main(int argc, char *argv[])
util_opt_set_command(command);
util_prg_set_command(command);
/* Install option vector */
util_opt_init(opt_vec, NULL);
/* Parse all options specified in my_argv[] */
while (1) {
/* Get the next option 'c' from my_argv[] */
@@ -173,6 +184,9 @@ int main(int argc, char *argv[])
case 'l':
printf("Specified: -l\n");
break;
case 't':
printf("Specified: --test %s\n", optarg ? optarg : "");
break;
default:
util_opt_print_parse_error(c, my_argv);
return EXIT_FAILURE;

View File

@@ -2,6 +2,10 @@ include ../common.mak
ALL_CFLAGS += -D_FILE_OFFSET_BITS=64
ifneq (${HAVE_CURL},0)
ALL_CFLAGS += -DHAVE_CURL
endif
lib = libzds.a
all: $(lib)

View File

@@ -18,7 +18,12 @@
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_CURL
#include <curl/curl.h>
#endif /* HAVE_CURL */
#include "lib/util_libc.h"
#include "lib/dasd_base.h"
#include "lib/dasd_sys.h"
#include "lib/libzds.h"
@@ -300,6 +305,8 @@ struct dshandle {
unsigned long long skip;
/** @brief Detailed error messages in case of a problem */
struct errorlog *log;
char *session_ref;
};
/** @endcond */
@@ -2942,6 +2949,280 @@ void lzds_dshandle_close(struct dshandle *dsh)
dsh->is_open = 0;
}
#ifdef HAVE_CURL
struct response_data {
char *session_ref;
unsigned long statuscode;
};
static size_t
parse_response_callback(void *data, size_t size, size_t member, void *target)
{
struct response_data *response = target;
if (strstr(data, "HTTP/1.1 500 Internal Server Error")) {
response->statuscode = 500;
} else if (strstr(data, "HTTP/1.1 200 OK")) {
response->statuscode = 200;
} else
sscanf(data, "X-IBM-Session-Ref: %m[^\n]\n",
&response->session_ref);
return size*member;
}
static size_t write_discard_callback(void *UNUSED(data), size_t size, size_t member,
void *UNUSED(target))
{
/* do nothing just pretend all data has been processed */
return size*member;
}
CURL *lzds_prepare_curl(char *url)
{
CURL *curl;
curl = curl_easy_init();
if (!curl)
return NULL;
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 0L);
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_discard_callback);
return curl;
}
/**
* Ping the z/OSMS REST server.
* Used to check if the server is responding and accessible and to prevent
* the ENQ from timing out. If not used it would be automatically released
* after 10 minutes.
*
* @param[in] dsh The dshandle that keeps track of the I/O operations.
* server The URL to the z/OSMF REST services
* @return 1 on success, 0 otherwise
*/
int lzds_rest_ping(struct dshandle *dsh, char *server)
{
struct curl_slist *list = NULL;
char *release;
CURLcode res;
size_t size;
CURL *curl;
char *url;
url = util_strcat_realloc(NULL, server);
url = util_strcat_realloc(url, "restfiles/ping");
curl = lzds_prepare_curl(url);
if (!curl) {
free(url);
return 0;
}
list = curl_slist_append(list, "X-CSRF-ZOSMF-HEADER: none");
if (dsh && dsh->session_ref) {
size = sizeof("X-IBM-Session-Ref: ") + strlen(dsh->session_ref);
release = util_zalloc(size);
snprintf(release, size, "X-IBM-Session-Ref: %s",
dsh->session_ref);
list = curl_slist_append(list, release);
}
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
res = curl_easy_perform(curl);
curl_slist_free_all(list);
curl_easy_cleanup(curl);
if (res == CURLE_OK) {
free(url);
return 1;
}
fprintf(stderr, "URL: %s\n", url);
fprintf(stderr, "Error: %s\n", curl_easy_strerror(res));
free(url);
return 0;
}
/**
* Mark the dataset as in use for z/OS.
* Use z/OSMF REST services to read a small amount of data and get an exclusive
* ENQ that prevents z/OS applications from writing to the dataset in parallel
* until the ENQ is released.
*
* @param[in] dsh The dshandle that keeps track of the I/O operations.
* server The URL to the z/OSMF REST services
* @return 0 on success, otherwise one of the following error codes:
* - ENOTSUP Unable to setup curl and therefore no further access possible.
* - EPERM ENQ not obtained and therefore access is not allowed.
*/
int lzds_rest_get_enq(struct dshandle *dsh, char *server)
{
struct curl_slist *list = NULL;
struct response_data response;
int first_run;
CURLcode res;
CURL *curl;
char *url;
int rc;
url = util_strcat_realloc(NULL, server);
url = util_strcat_realloc(url, "restfiles/ds/");
url = util_strcat_realloc(url, dsh->ds->name);
memset(&response, 0, sizeof(response));
/*
* in the first run provide a range statement to read only 1 record of
* the dataset to get an ENQ.
* For the unlikely case that the dataset is empty
* "500 Internal Server Error" will be returned.
* If this is the case give it a second try without a range statement
*/
first_run = 1;
list = curl_slist_append(list, "X-IBM-Record-Range: 0-1");
retry:
rc = 1;
curl = lzds_prepare_curl(url);
if (!curl) {
free(url);
return errorlog_add_message(
&dsh->log,
NULL, ENOTSUP,
"curl handle not established for dataset %s\n",
dsh->ds->name);
}
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, parse_response_callback);
curl_easy_setopt(curl, CURLOPT_HEADERDATA, &response);
list = curl_slist_append(list, "X-CSRF-ZOSMF-HEADER: none");
list = curl_slist_append(list, "X-IBM-Obtain-ENQ: EXCLU");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
rc = errorlog_add_message(&dsh->log, NULL, ECONNREFUSED,
"Error: %s\n",
curl_easy_strerror(res));
} else {
if (first_run && response.statuscode == 500) {
curl_slist_free_all(list);
curl_easy_cleanup(curl);
first_run = 0;
list = NULL;
goto retry;
}
/* expect that the callback function found a reference string, double check */
if (response.statuscode == 200 && response.session_ref) {
dsh->session_ref = response.session_ref;
rc = 0;
} else {
rc = errorlog_add_message(
&dsh->log,
NULL, EPERM,
"no session ref obtained for dataset %s rest rc %ld\n",
dsh->ds->name, response.statuscode);
}
}
free(url);
curl_slist_free_all(list);
curl_easy_cleanup(curl);
return rc;
}
/**
* Mark the dataset as no longer in use for z/OS.
* Use z/OSMF REST services to read a small amount of data and release the exclusive
* ENQ that was previously obtained.
*
* @param[in] dsh The dshandle that keeps track of the I/O operations.
* server The URL to the z/OSMF REST services
* @return 0 on success, otherwise one of the following error codes:
* - ENOTSUP Unable to release the ENQ.
*/
int lzds_rest_release_enq(struct dshandle *dsh, char *server)
{
struct curl_slist *list = NULL;
struct response_data response;
char *release;
int first_run;
CURLcode res;
CURL *curl;
char *url;
if (!dsh->session_ref) {
fprintf(stderr, "No ENQ to release.\n");
return 0;
}
url = util_strcat_realloc(NULL, server);
url = util_strcat_realloc(url, "restfiles/ds/");
url = util_strcat_realloc(url, dsh->ds->name);
release = util_strcat_realloc(NULL, "X-IBM-Session-Ref: ");
release = util_strcat_realloc(release, dsh->session_ref);
memset(&response, 0, sizeof(response));
/*
* in the first run provide a range statement to read only 1 record of
* the dataset to release the ENQ.
* For the unlikely case that the dataset is empty
* "500 Internal Server Error" will be returned.
* If this is the case give it a second try without a range statement
*/
first_run = 1;
list = curl_slist_append(list, "X-IBM-Record-Range: 0-1");
retry:
curl = lzds_prepare_curl(url);
if (!curl) {
free(url);
free(release);
return errorlog_add_message(
&dsh->log,
NULL, ENOTSUP,
"curl handle not established for dataset %s\n",
dsh->ds->name);
}
list = curl_slist_append(list, "X-CSRF-ZOSMF-HEADER: none");
list = curl_slist_append(list, "X-IBM-Release-ENQ: true");
list = curl_slist_append(list, release);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, parse_response_callback);
curl_easy_setopt(curl, CURLOPT_HEADERDATA, &response);
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
errorlog_add_message(&dsh->log, NULL, ENOTSUP, "Error: %s\n",
curl_easy_strerror(res));
} else if (first_run && response.statuscode == 500) {
curl_slist_free_all(list);
curl_easy_cleanup(curl);
first_run = 0;
list = NULL;
goto retry;
}
curl_slist_free_all(list);
curl_easy_cleanup(curl);
free(dsh->session_ref);
free(release);
free(url);
dsh->session_ref = NULL;
return res;
}
#endif /* HAVE_CURL */
/**
* This makes the data set context ready for read operations.

18
lsstp/Makefile Normal file
View File

@@ -0,0 +1,18 @@
include ../common.mak
libs = $(rootdir)/libutil/libutil.a
all: lsstp
lsstp: lsstp.o $(libs)
install: all
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) \
$(DESTDIR)$(MANDIR)/man8
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 lsstp $(DESTDIR)$(BINDIR)
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 lsstp.8 \
$(DESTDIR)$(MANDIR)/man8
clean:
rm -f *.o *~ lsstp core
.PHONY: all install clean

79
lsstp/lsstp.8 Normal file
View File

@@ -0,0 +1,79 @@
.\" Copyright 2020 IBM Corp.
.\" s390-tools is free software; you can redistribute it and/or modify
.\" it under the terms of the MIT license. See LICENSE for details.
.\"
.TH LSSTP 8 "Jul 2020" "s390-tools" "Linux Administrator's Manual"
.SH NAME
.B "lsstp "
\- tool to show STP system information
.SH SYNOPSIS
.BI "lsstp "
.SH DESCRIPTION
.B lsstp
displays information about the currenta Server Time Protocol (STP) configuration
like Coordianted Timing Network (CTN) ID, Timing state and Leap seconds.
.SH OUTPUT
.TP
.B STP online
Whether the STP subsystem is online
.TP
.B CTN ID
The ID of the Coordinated Time Network. If it can be decoded as EBCDIC it will be shown as EBCDIC String, otherwise a hexadecimal representation is shown.
.TP
.B CTN Type
The type of timing network.
.IP
.B No CTN
STP is not configured for attachment to a CTN.
.IP
.B STP-only
STP is configured and attached to a CTN with only STP nodes.
.IP
.B Mixed
STP is configured and attached to a CTN which contains both STP and External Time Reference (ETR) nodes.
.TP
.B Stratum
The Stratum level of the STP clock. This indicates the number of servers in the timing path between the local STP clock and the selected primary time server.
.TP
.B Timing mode
.IP
.B Local
The Time-of-day (TOD) clock is stepped to the local hardware oscillator and is not steered by the STP facility.
.IP
.B ETR
The TOD clock is synchronized with an attached 9037 Sysplex Timer.
.IP
.B STP
The TOD clock is steered by the STP facility to maintain synchronization with a Coordinated Server Time (CST).
.IP
.B Uninitialized
The TOD clock is not initialized. The STP facility is allowed to perform a step adjustment to the TOD clock for synchronization.
.TP
.B Timing state
The synchronization state of the STP facilty. Can be unsynchronzied, synchronized and stopped.
.TP
.B DST offset
The Daylight savings time offset relative to UTC in minutes.
.TP
.B Timezone offset
The offset of the local time relative to UTC in minutes.
.TP
.B Time offset
The total time offset at the server. This field is only valid in mixed CTN configurations.
.TP
.B Active Leap seconds
The number of Leap seconds that are currently in effect at the STP facility.
.TP
.B Leap second <insertion|delation> at
If a Leap second insertion or deletetion is scheduled in the STP facility, this field will show the Day and Time of the scheduled change.
.SH OPTIONS
.TP
.BI "-v|--version"
Print version number.
.TP
.BI "-h|--help"
Print usage text.
.SH AUTHORS
Sven Schnelle <svens@linux.ibm.com>

218
lsstp/lsstp.c Normal file
View File

@@ -0,0 +1,218 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <iconv.h>
#include <inttypes.h>
#include "lib/util_opt.h"
#include "lib/util_file.h"
#include "lib/util_prg.h"
#include "lib/util_path.h"
static const struct util_prg prg = {
.desc = "Display STP system information",
.args = "",
.copyright_vec = {
{
.owner = "IBM Corp.",
.pub_first = 2020,
},
UTIL_PRG_COPYRIGHT_END
}
};
static struct util_opt opt_vec[] = {
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
struct stp_parms {
uint64_t ctn_id;
unsigned int online;
unsigned int leap_seconds;
int leap_seconds_diff;
unsigned int leap_seconds_utc;
unsigned int stratum;
unsigned int ctn_type;
unsigned int timing_mode;
unsigned int timing_state;
int dst_offset;
int time_offset;
int time_zone_offset;
};
static int convert_ctn_id(char *in, char *out)
{
iconv_t ic;
size_t inlen = sizeof(unsigned long long);
size_t outlen = sizeof(unsigned long long);
ic = iconv_open("ISO-8859-1", "EBCDIC-US");
if (ic == (iconv_t)-1) {
warn("Could not initialize EBCDIC to ISO-8859-1 conversion table");
return -1;
}
if (iconv(ic, &in, &inlen, (char **)&out, &outlen) == (size_t)-1) {
warn("Code page translation EBCDIC to ISO-8859-1 failed");
iconv_close(ic);
return -1;
}
iconv_close(ic);
return 0;
}
static const char *ctn_type_str(int type)
{
switch (type) {
case 0:
return "No CTN defined";
case 1:
return "STP-only";
case 2:
return "mixed";
default:
return "unknown";
}
}
static const char *tmd_to_str(int mode)
{
switch (mode) {
case 0:
return "Local";
case 1:
return "ETR";
case 2:
return "STP";
case 15:
return "Uninitialized";
default:
return "unknown";
}
}
static const char *tst_to_str(int mode)
{
switch (mode) {
case 0:
return "Unsynchronized";
case 1:
return "Synchronized";
case 2:
return "Physical clock stopped";
default:
return "unknown";
}
}
static const char *yesno_str(int val)
{
return val ? "yes" : "no";
}
#define read_sysfs_attr(attr, parm, func, base) \
do { \
path = util_path_sysfs("devices/system/stp/%s", attr); \
ret = func(parm, base, path); \
if (ret) { \
fprintf(stderr, "failed to open %s: %s\n", path, strerror(errno)); \
free(path); \
exit(EXIT_FAILURE); \
} \
free(path); \
} while (0)
int main(int argc, char **argv)
{
struct stp_parms parm = { 0 };
char ctn_id[32] = { 0 };
char *path;
int ret, c;
util_prg_init(&prg);
util_opt_init(opt_vec, NULL);
for (;;) {
c = util_opt_getopt_long(argc, argv);
if (c == -1)
break;
switch (c) {
case 'v':
util_prg_print_version();
exit(EXIT_SUCCESS);
case 'h':
util_prg_print_help();
util_opt_print_help();
exit(EXIT_SUCCESS);
default:
fprintf(stderr, "Try 'lsstp --help' for more information.\n");
exit(EXIT_FAILURE);
}
}
read_sysfs_attr("online", &parm.online, util_file_read_ui, 10);
if (!parm.online) {
printf("STP disabled\n");
goto out;
}
read_sysfs_attr("ctn_id", &parm.ctn_id, util_file_read_ul, 16);
read_sysfs_attr("ctn_type", &parm.ctn_type, util_file_read_ui, 10);
read_sysfs_attr("stratum", &parm.stratum, util_file_read_ui, 10);
read_sysfs_attr("leap_seconds", &parm.leap_seconds, util_file_read_ui, 10);
read_sysfs_attr("timing_mode", &parm.timing_mode, util_file_read_ui, 10);
read_sysfs_attr("timing_state", &parm.timing_state, util_file_read_ui, 10);
read_sysfs_attr("dst_offset", &parm.dst_offset, util_file_read_i, 10);
read_sysfs_attr("time_offset", &parm.time_offset, util_file_read_i, 10);
read_sysfs_attr("time_zone_offset", &parm.time_zone_offset, util_file_read_i, 10);
if (convert_ctn_id((char *)&parm.ctn_id, ctn_id))
snprintf(ctn_id, sizeof(ctn_id)-1, "%016" PRIx64, parm.ctn_id);
printf("STP online: %s\n"
"CTN ID: %s\n"
"CTN type: %s\n"
"Stratum: %d\n"
"Timing mode: %s\n"
"Timing state: %s\n"
"DST offset: %d\n"
"Timezone offset: %d\n"
"Time offset: %d\n"
"Active leap seconds: %d\n",
yesno_str(parm.online),
ctn_id,
ctn_type_str(parm.ctn_type),
parm.stratum,
tmd_to_str(parm.timing_mode),
tst_to_str(parm.timing_state),
parm.dst_offset,
parm.time_zone_offset,
parm.time_offset,
parm.leap_seconds);
printf("Scheduled leap second: ");
path = util_path_sysfs("devices/system/stp/leap_seconds_scheduled");
if (util_file_read_va(path, "%d,%d", &parm.leap_seconds_utc,
&parm.leap_seconds_diff) == 2 &&
parm.leap_seconds_diff && parm.leap_seconds_utc) {
time_t lsoup = parm.leap_seconds_utc;
printf("%s at: %s UTC",
parm.leap_seconds_diff > 0 ? "insertion" : "deletion",
ctime(&lsoup));
} else {
printf("-\n");
}
free(path);
return 0;
out:
return 1;
}

View File

@@ -45,7 +45,7 @@ vmcmd: Trigger CP command according to the 'VMCMD_X' configuration in
.TP
\fB - DUMP_TYPE:\fR
Type of dump device. Possible values are 'ccw' and 'fcp'.
Type of dump device. Possible values are 'ccw', 'fcp' and 'nvme'.
.TP
\fB - DEVICE:\fR
@@ -59,6 +59,14 @@ WWPN for SCSI dump device.
\fB - LUN\fR
LUN for SCSI dump device.
.TP
\fB - FID\fR
Function ID for NVMe dump device.
.TP
\fB - NSID\fR
Namespace ID for NVMe dump device.
.TP
\fB - BOOTPROG:\fR
Boot program selector.
@@ -159,6 +167,25 @@ BOOTPROG=0
BR_LBA=0
.br
#
.br
# Example configuration for an NVMe dump device (NVMe Disk)
.br
#
.br
ON_PANIC=dump
.br
DUMP_TYPE=nvme
.br
FID=0x0300
.br
NSID=0x0001
.br
BOOTPROG=0
.br
BR_LBA=0
.br
#
.br
# Example configuration for CP commands

View File

@@ -269,6 +269,7 @@ PROCFILES="\
/proc/schedstat\
/proc/service_levels\
/proc/slabinfo\
/proc/softirqs\
/proc/stat\
/proc/swaps\
/proc/sys/kernel\

View File

@@ -29,7 +29,7 @@ EnvironmentFile=@sysconf_path@/sysconfig/mon_fsstatd
#Environment=FSSTAT_INTERVAL=30
ExecStartPre=-/sbin/modprobe monwriter
ExecStartPre=/sbin/udevadm settle --timeout=10
ExecStartPre=/usr/bin/udevadm settle --timeout=10
ExecStart=@usrsbin_path@/mon_fsstatd -i $FSSTAT_INTERVAL
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process

View File

@@ -29,7 +29,7 @@ EnvironmentFile=@sysconf_path@/sysconfig/mon_procd
#Environment=PROC_INTERVAL=30
ExecStartPre=-/sbin/modprobe monwriter
ExecStartPre=/sbin/udevadm settle --timeout=10
ExecStartPre=/usr/bin/udevadm settle --timeout=10
ExecStart=@usrsbin_path@/mon_procd -i $PROC_INTERVAL
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process

View File

@@ -235,15 +235,15 @@ int main(int argc, char **argv)
write_buffer(STDOUT_FILENO, cp.response,
MIN(cp.response_size, cp.buffer_size));
free(cp.response);
if (ret == VMCP_ERR_TOOSMALL) {
fprintf(stderr, "Error: output (%d bytes) was truncated, try "
"--buffer to increase size\n", cp.response_size);
return VMCP_BUF;
}
if (cp.cprc > 0) {
fprintf(stderr, "Error: non-zero CP response for command '%s': "
"#%d\n", command, cp.cprc);
return VMCP_CP;
}
if (ret == VMCP_ERR_TOOSMALL) {
fprintf(stderr, "Error: output (%d bytes) was truncated, try "
"--buffer to increase size\n", cp.response_size);
return VMCP_BUF;
}
return EXIT_SUCCESS;
}

View File

@@ -24,13 +24,22 @@ my $wlun = "0xc101000000000000";
my $lun0 = "0x0000000000000000";
my $sg_dir = "/sys/class/scsi_generic";
my $udevsettle_call;
my $udevadm = "/sbin/udevadm";
if (! -e $udevadm) {
$udevsettle_call = "/sbin/udevsettle";
# See if we can find udevadm through $PATH:
if (!system("udevadm --version > /dev/null 2>&1")) {
$udevsettle_call = "udevadm settle";
# Search udevadm in well-known locations:
} elsif (-e "/sbin/udevadm") {
$udevsettle_call = "/sbin/udevadm settle";
} elsif (-e "/usr/bin/udevadm") {
$udevsettle_call = "/usr/bin/udevadm settle";
# Fall back to udevsettle:
} elsif (-e "/sbin/udevsettle") {
$udevsettle_call = "/sbin/udevsettle";
} else {
$udevsettle_call = "$udevadm settle";
$udevsettle_call = "";
print "Failed to find any candidate for udevsettle.\n";
}
# read the first line of a sysfs-entry and compare it to a given string

View File

@@ -1,8 +1,10 @@
.\" Copyright 2019 IBM Corp.
.\" chzcrypt.8
.\"
.\" Copyright 2020 IBM Corp.
.\" s390-tools is free software; you can redistribute it and/or modify
.\" it under the terms of the MIT license. See LICENSE for details.
.\"
.TH CHZCRYPT 8 "AUG 2019" "s390-tools"
.TH CHZCRYPT 8 "OCT 2020" "s390-tools"
.SH NAME
chzcrypt \- modify zcrypt configuration
.SH SYNOPSIS
@@ -16,6 +18,14 @@ chzcrypt \- modify zcrypt configuration
[...] )
.TP
.B chzcrypt
.B --config-on
.RB "|"
.B --config-off
.RB "( " -a " | "
.I <device id>
[...] )
.TP
.B chzcrypt
.RB "[ " -p " | " -n " ] [ " -t
.I <timeout>
]
@@ -54,11 +64,22 @@ Set the given cryptographic device(s) offline.
.B -a, --all
Set all available cryptographic device(s) online or offline.
.TP 8
.B --config-on
Set the given cryptographic card device(s) config on ('configured').
.TP 8
.B --config-off
Set the given cryptographic card device(s) config off ('deconfigured').
.TP 8
.B <device id>
Specifies a cryptographic device which will be set either online or offline.
The device can either be a card device or a queue device.
A queue device can only get switched online when the providing card is online.
Specifies a cryptographic device which will be set either online or
offline or configured on or off. For online and offline the device can
either be a card device or a queue device. A queue device can only get
switched online when the providing card is online.
.br
For config on/off the device needs to be a card device. A card or
queue device cannot get switched online if the card is in deconfigured
state.
.br
Please note that the card device and queue device representation are both
in hexadecimal notation.
.TP 8
@@ -103,11 +124,25 @@ Will set the cryptographic device '10.0038' respectively card id 16
.B chzcrypt -d -a
Will set all available cryptographic devices offline.
.TP
.B chzcrypt --config-on -a -V
Set all available crypto cards to config on, be verbose.
.TP
.B chzcrypt -V --config-off card01 card03
Switch the two crypto cards 1 and 3 to deconfigured, be verbose.
.TP
.B chzcrypt -c 60 -n
Will set configuration timer for re-scanning the AP bus to 60 seconds and
disable zcrypt's poll thread.
.TP
.B chzcrypt -q 67
Will set the default domain to 67.
.SH NOTES
Support for crypto cards to get switched config on or off requires a
Linux kernel supporting this. If the required sysfs attribute file
does not exist, it is assumed there is an older kernel running and
chzcrypt exits with an appropriate message. Even more config on/off
may require support from a hypervisor like KVM or zVM and may fail if
the Linux kernel is unable to perform the SCLP command. Check syslog
on failure.
.SH SEE ALSO
\fBlszcrypt\fR(8)

View File

@@ -1,7 +1,7 @@
/*
* chzcrypt - Tool to modify zcrypt configuration
*
* Copyright IBM Corp. 2008, 2019
* Copyright IBM Corp. 2008, 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -47,7 +47,7 @@ const struct util_prg prg = {
{
.owner = "IBM Corp.",
.pub_first = 2008,
.pub_last = 2019,
.pub_last = 2020,
},
UTIL_PRG_COPYRIGHT_END
}
@@ -56,6 +56,10 @@ const struct util_prg prg = {
/*
* Configuration of command line options
*/
#define OPT_CONFIG_ON 0x80
#define OPT_CONFIG_OFF 0x81
static struct util_opt opt_vec[] = {
{
.option = { "enable", no_argument, NULL, 'e'},
@@ -73,6 +77,18 @@ static struct util_opt opt_vec[] = {
"online/offline, must be used in conjunction "
"with the enable or disable option",
},
{
.option = { "config-on", no_argument, NULL, OPT_CONFIG_ON},
.argument = "DEVICE_IDS",
.flags = UTIL_OPT_FLAG_NOSHORT,
.desc = "Set the given cryptographic card device(s) configured"
},
{
.option = { "config-off", no_argument, NULL, OPT_CONFIG_OFF},
.argument = "DEVICE_IDS",
.flags = UTIL_OPT_FLAG_NOSHORT,
.desc = "Set the given cryptographic card device(s) deconfigured"
},
{
.option = { "poll-thread-enable", no_argument, NULL, 'p'},
.desc = "Enable zcrypt's poll thread",
@@ -212,6 +228,116 @@ static void default_domain_set(const char *default_domain_str)
free(attr);
}
static void set_online(const char *online, const char *online_text,
char *dev_list, size_t len)
{
long value;
int id, dom;
char *dev, *dev_path;
char device[256], online_read[32];
for (dev = dev_list; dev != NULL; dev = argz_next(dev_list, len, dev)) {
if (strncmp(dev, "card", 4) == 0) {
/* dev == "card2" */
if (sscanf(dev, "card%02x", &id) != 1)
errx(EXIT_FAILURE, "Error - unable to parse '%s'.", dev);
sprintf(device, "card%02x", id);
} else if (strncmp(dev, "0x", 2) == 0) {
/* dev == "0x.." */
if (sscanf(dev, "0x%02x", &id) != 1)
errx(EXIT_FAILURE, "Error - unable to parse '%s'.", dev);
sprintf(device, "card%02x", id);
} else if (misc_regex_match(dev, "^[0-9a-fA-F]+$")) {
/* dev == "2" */
if (sscanf(dev, "%02x", &id) != 1)
errx(EXIT_FAILURE, "Error - unable to parse '%s'.", dev);
sprintf(device, "card%02x", id);
} else {
/* Form: 01.0003 ? */
if (sscanf(dev, "%02x.%04x", &id, &dom) != 2)
errx(EXIT_FAILURE,
"Error - cryptographic device %s malformed.", dev);
sprintf(device, "card%02x/%02x.%04x", id, id, dom);
}
dev_path = util_path_sysfs("bus/ap/devices/%s", device);
if (!util_path_is_dir(dev_path))
errx(EXIT_FAILURE,
"Error - cryptographic device %s does not exist.", device);
if (!util_path_is_writable("%s/online", dev_path))
errx(EXIT_FAILURE, "Error - can't write to %s/online.\n"
" Wrong permissions or wrong tools version.", dev_path);
if (*online == '1' && util_path_is_readable("%s/config", dev_path)) {
util_file_read_l(&value, 10, "%s/config", dev_path);
if (value <= 0) {
warnx("Warning - device %s is deconfigured,"
" can't set to online.\n", dev);
goto next;
}
}
verbose("Setting cryptographic device %s %s\n", device, online_text);
util_file_write_s(online, "%s/online", dev_path);
util_file_read_line(online_read, sizeof(online_read), "%s/online", dev_path);
if (strcmp(online, online_read) != 0)
errx(EXIT_FAILURE, "Error - unable to set cryptographic device %s %s.",
device, online_text);
next:
free(dev_path);
}
}
static void set_config(const char *config, const char *config_text,
char *dev_list, size_t len)
{
int id;
char *dev, *dev_path;
char device[256], config_read[32];
for (dev = dev_list; dev != NULL; dev = argz_next(dev_list, len, dev)) {
if (strncmp(dev, "card", 4) == 0) {
/* dev == "card2" */
if (sscanf(dev, "card%02x", &id) != 1)
errx(EXIT_FAILURE, "Error - unable to parse '%s'.", dev);
sprintf(device, "card%02x", id);
} else if (strncmp(dev, "0x", 2) == 0) {
/* dev == "0x.." */
if (sscanf(dev, "0x%02x", &id) != 1)
errx(EXIT_FAILURE, "Error - unable to parse '%s'.", dev);
sprintf(device, "card%02x", id);
} else if (misc_regex_match(dev, "^[0-9a-fA-F]+$")) {
/* dev == "2" */
if (sscanf(dev, "%02x", &id) != 1)
errx(EXIT_FAILURE, "Error - unable to parse '%s'.", dev);
sprintf(device, "card%02x", id);
} else {
errx(EXIT_FAILURE, "Error - invalid device %s\n"
" Config on/off is only valid for card devices.", dev);
}
dev_path = util_path_sysfs("bus/ap/devices/%s", device);
if (!util_path_is_dir(dev_path))
errx(EXIT_FAILURE,
"Error - cryptographic device %s does not exist.", device);
if (!util_path_is_readable("%s/config", dev_path))
errx(EXIT_FAILURE, "Error - can't read %s/config.\n"
"File may not exist due to an older zcrypt device driver.", dev_path);
util_file_read_line(config_read, sizeof(config_read), "%s/config", dev_path);
if (strcmp(config, config_read) == 0) {
warnx("Warning - device %s is already %s.", device, config_text);
goto next;
}
if (!util_path_is_writable("%s/config", dev_path))
errx(EXIT_FAILURE, "Error - can't write to %s/config.\n"
"Wrong permissions or wrong tools version.", dev_path);
verbose("Setting cryptographic device %s %s\n", device, config_text);
util_file_write_s(config, "%s/config", dev_path);
util_file_read_line(config_read, sizeof(config_read), "%s/config", dev_path);
if (strcmp(config, config_read) != 0)
errx(EXIT_FAILURE, "Error - unable to set cryptographic device %s %s.",
device, config_text);
next:
free(dev_path);
}
}
/*
* Print invalid commandline error message and then exit with error code
*/
@@ -276,7 +402,6 @@ void print_adapter_id_help(void)
printf(" Enable the cryptographic devices with card id '03' and domain id '0005'.\n");
printf(" #>chzcrypt -e 03.0005\n");
printf(" \n");
}
/*
@@ -284,19 +409,19 @@ void print_adapter_id_help(void)
*/
int main(int argc, char *argv[])
{
const char *online, *online_text = NULL, *poll_thread, *config_time;
const char *poll_timeout, *default_domain;
char *path, *dev_path, *dev, *dev_list, device[256], online_read[32];
const char *online = NULL, *online_text = NULL, *poll_thread = NULL;
const char *config_time = NULL, *poll_timeout = NULL;
const char *default_domain = NULL, *config = NULL, *config_text = NULL;
char *path, *dev_list;
bool all = false, actionset = false;
size_t len;
int id, dom, c, i, j;
int c, i, j;
for (i=0; i < argc; i++)
for (j=2; j < (int) strlen(argv[i]); j++)
if (argv[i][j] == '_')
argv[i][j] = '-';
online = poll_thread = config_time = poll_timeout = default_domain = NULL;
util_prg_init(&prg);
util_opt_init(opt_vec, NULL);
while (1) {
@@ -348,6 +473,16 @@ int main(int argc, char *argv[])
case 'v':
util_prg_print_version();
return EXIT_SUCCESS;
case OPT_CONFIG_ON:
actionset = true;
config = "1";
config_text = "config on";
break;
case OPT_CONFIG_OFF:
actionset = true;
config = "0";
config_text = "config off";
break;
default:
util_opt_print_parse_error(c, argv);
return EXIT_FAILURE;
@@ -380,42 +515,13 @@ int main(int argc, char *argv[])
else
dev_list_argv(&dev_list, &len, &argv[optind]);
if (online && len == 0)
if ((online || config) && len == 0)
errx(EXIT_FAILURE, "Error - missing cryptographic device id(s).");
for (dev = dev_list; dev != NULL; dev = argz_next(dev_list, len, dev)) {
if (strncmp(dev, "card", 4) == 0) {
/* dev == "card2" */
sscanf(dev, "card%02x", &id);
sprintf(device, "card%02x", id);
} else if (strncmp(dev, "0x", 2) == 0) {
/* dev == "0x.." */
sscanf(dev, "0x%02x", &id);
sprintf(device, "card%02x", id);
} else if (misc_regex_match(dev, "^[0-9a-fA-F]+$")) {
/* dev == "2" */
sscanf(dev, "%02x", &id);
sprintf(device, "card%02x", id);
} else {
/* Form: 01.0003 ? */
if (sscanf(dev, "%02x.%04x", &id, &dom) != 2)
errx(EXIT_FAILURE, "Error - cryptographic device %s malformed.", dev);
sprintf(device, "card%02x/%02x.%04x", id, id, dom);
}
dev_path = util_path_sysfs("bus/ap/devices/%s", device);
if (!util_path_is_dir(dev_path))
errx(EXIT_FAILURE, "Error - cryptographic device %s does not exist.", device);
if (!util_path_is_writable("%s/online", dev_path))
errx(EXIT_FAILURE, "Error - can't write to %s/online.\n Wrong permissions"
" or wrong tools version.", dev_path);
verbose("Setting cryptographic device %s %s\n", device, online_text);
util_file_write_s(online, "%s/online", dev_path);
util_file_read_line(online_read, sizeof(online_read), "%s/online", dev_path);
if (strcmp(online, online_read) != 0)
errx(EXIT_FAILURE, "Error - unable to set cryptographic device %s %s.",
device, online_text);
free(dev_path);
}
free(dev_list);
if (online)
set_online(online, online_text, dev_list, len);
else if (config)
set_config(config, config_text, dev_list, len);
return EXIT_SUCCESS;
}

View File

@@ -10,7 +10,7 @@
.\" nroff -man lszcrypt.8
.\" to process this source
.\"
.TH LSZCRYPT 8 "AUG 2019" "s390-tools"
.TH LSZCRYPT 8 "OCT 2020" "s390-tools"
.SH NAME
lszcrypt \- display zcrypt device and configuration information
.SH SYNOPSIS
@@ -111,9 +111,9 @@ Displays help text and exits.
.TP 8
.B -v, --version
Displays version information and exits.
.SH VERBOSE LISTING DETAILS
Some of the columns showing up in verbose listing mode may need some
explanation:
.SH LISTING DETAILS
Here is an explanation of the columns displayed. Please note that some
of the columns show up in verbose mode only.
.TP
.B TYPE and HWTYPE
The HWTYPE is a numeric value showing which type of hardware the zcrypt
@@ -124,6 +124,31 @@ The TYPE is a human readable value showing the hardware type and the basic
function type (A=Accelerator, C=CCA Coprocessor, P=EP11 Coprocessor). So
for example CEX6P means a CEX6 card in EP11 Coprocessor mode.
.TP
.B MODE
A crypto card can be configured to run into one of 3 modes:
.br
Accelerator - Acceleration of clear key RSA (CRT and ME) cryptographic
operations.
.br
CCA Coprocessor - Support CCA secure key cryptographic operations.
.br
EP11 Coprocessor - Support EP11 secure key cryptographic operations.
.TP
.B STATUS
A crypto card and/or a crypto queue may be switched offline to
prohibit it's use. There are two levels of offline state. A software
online/offline state is kept by the zcrypt device driver and can be
switched on or off with the help of the chzcrypt application.
.br
A crypto card can also be 'configured' or 'deconfigured'. This state
may be adjusted on the HMC or SE. The chzcrypt application can also
trigger this state with the --config-on and --config-off options.
.br
lszcrypt shows 'online' when a card or queue is available for
cryptograhic operations. 'offline' is displayed when a card or queue
is switched to (software) offline. If a card is 'deconfigured' via
HMC, SE or chzcrypt the field shows 'deconfig'.
.TP
.B REQUESTS
This is the counter value of successful processed requests on card or queue
level. Successful here means the request was processed without any failure

View File

@@ -1,7 +1,7 @@
/**
* lszcrypt - Display zcrypt devices and configuration settings
*
* Copyright IBM Corp. 2008, 2019
* Copyright IBM Corp. 2008, 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -86,7 +86,7 @@ const struct util_prg prg = {
{
.owner = "IBM Corp.",
.pub_first = 2008,
.pub_last = 2019,
.pub_last = 2020,
},
UTIL_PRG_COPYRIGHT_END
}
@@ -339,6 +339,7 @@ static void show_capability(const char *id_str)
static void read_subdev_rec_default(struct util_rec *rec, const char *grp_dev,
const char *sub_dev)
{
long value;
char buf[256];
unsigned long facility;
@@ -347,14 +348,25 @@ static void read_subdev_rec_default(struct util_rec *rec, const char *grp_dev,
else
util_rec_set(rec, "type", buf);
if (util_file_read_line(buf, sizeof(buf), "%s/%s/online",
grp_dev, sub_dev))
util_rec_set(rec, "online", "-");
else
if (strcmp(buf, "0") == 0)
util_rec_set(rec, "online", "offline");
else
if (util_path_is_readable("%s/%s/online", grp_dev, sub_dev)) {
util_file_read_l(&value, 10, "%s/%s/online", grp_dev, sub_dev);
if (value > 0)
util_rec_set(rec, "online", "online");
else {
/* device is offline, check config (if available) */
if (util_path_is_readable("%s/%s/config", grp_dev, sub_dev)) {
util_file_read_l(&value, 10, "%s/%s/config", grp_dev, sub_dev);
if (value > 0)
util_rec_set(rec, "online", "offline");
else
util_rec_set(rec, "online", "deconfig");
} else
util_rec_set(rec, "online", "offline");
}
} else {
/* no online attribute */
util_rec_set(rec, "online", "-");
}
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
if (facility & MASK_COPRO)
@@ -457,6 +469,7 @@ static void show_subdevices(struct util_rec *rec, const char *grp_dev)
*/
static void read_rec_default(struct util_rec *rec, const char *grp_dev)
{
long value;
char buf[256];
unsigned long facility;
@@ -475,13 +488,21 @@ static void read_rec_default(struct util_rec *rec, const char *grp_dev)
else
util_rec_set(rec, "mode", "Unknown");
if (util_file_read_line(buf, sizeof(buf), "%s/online", grp_dev))
util_rec_set(rec, "online", "-");
else
if (strcmp(buf, "0") == 0)
util_rec_set(rec, "online", "offline");
else
if (util_path_is_readable("%s/online", grp_dev)) {
util_file_read_l(&value, 10, "%s/online", grp_dev);
if (value > 0)
util_rec_set(rec, "online", "online");
else {
if (util_path_is_readable("%s/config", grp_dev)) {
util_file_read_l(&value, 10, "%s/config", grp_dev);
if (value > 0)
util_rec_set(rec, "online", "offline");
else
util_rec_set(rec, "online", "deconfig");
} else
util_rec_set(rec, "online", "offline");
}
}
util_file_read_line(buf, sizeof(buf), "%s/request_count", grp_dev);
util_rec_set(rec, "requests", buf);
@@ -567,7 +588,7 @@ static void define_rec_default(struct util_rec *rec)
util_rec_def(rec, "card", UTIL_REC_ALIGN_LEFT, 11, "CARD.DOMAIN");
util_rec_def(rec, "type", UTIL_REC_ALIGN_LEFT, 5, "TYPE");
util_rec_def(rec, "mode", UTIL_REC_ALIGN_LEFT, 11, "MODE");
util_rec_def(rec, "online", UTIL_REC_ALIGN_LEFT, 7, "STATUS");
util_rec_def(rec, "online", UTIL_REC_ALIGN_LEFT, 8, "STATUS");
util_rec_def(rec, "requests", UTIL_REC_ALIGN_RIGHT, 8, "REQUESTS");
}

View File

@@ -63,14 +63,8 @@ CMD=$(basename $0)
LSZNET=/lib/s390-tools/lsznet.raw
LSZNET_ARGS=-a
LSZNET_CALL="$LSZNET $LSZNET_ARGS"
UDEVSETTLE=/sbin/udevadm
if [ ! -e $UDEVSETTLE ]
then
UDEVSETTLE=/sbin/udevsettle
UDEVSETTLE_CALL="$UDEVSETTLE --timeout=10"
else
UDEVSETTLE_CALL="$UDEVSETTLE settle --timeout=10"
fi
UDEVSETTLE=udevadm
UDEVSETTLE_CALL="$UDEVSETTLE settle --timeout=10"
SYSFSDIR=$(cat /proc/mounts|awk '$3=="sysfs"{print $2; exit}')
CCWGROUPBUS_DIR=$SYSFSDIR/bus/ccwgroup
CCWDEV_DIR=$SYSFSDIR/bus/ccw/devices
@@ -261,6 +255,35 @@ function lookup_lan_layer()
#==============================================================================
function prepare_udevsettle_cmd()
{
# is the command available in $PATH
if ! [ -x "$(command -v $UDEVSETTLE)" ]
then
# check the well known locations.
if [ -e "/sbin/udevadm" ]
then
UDEVSETTLE=/sbin/udevadm
UDEVSETTLE_CALL="$UDEVSETTLE settle --timeout=10"
elif [ -e "/usr/bin/udevadm" ]
then
UDEVSETTLE=/usr/bin/udevadm
UDEVSETTLE_CALL="$UDEVSETTLE settle --timeout=10"
elif [ -e "/sbin/udevsettle" ]
then
# Fallback to udevsettle
UDEVSETTLE=/sbin/udevsettle
UDEVSETTLE_CALL="$UDEVSETTLE --timeout=10"
else
UDEVSETTLE=""
UDEVSETTLE_CALL=""
echo "Failed to find any candidate for udevsettle"
fi
fi
}
#==============================================================================
function lookup_type_and_lan_or_vswitch_name()
{
local DEVNO="$1"
@@ -506,8 +529,9 @@ function wait_for_net_device()
local CMD_FINDNETLINK="find $CCWGROUPBUS_DEVICEDIR/$CCWGROUPDEVNO/ -type l -name net*"
local LINKNAME=""
prepare_udevsettle_cmd
# polling loop to wait for net device to become available
if [ -e $UDEVSETTLE ]
if [ "$UDEVSETTLE" != "" ]
then
$UDEVSETTLE_CALL
fi

View File

@@ -511,20 +511,6 @@ static struct attrib qeth_attr_route6 = {
.st_data = QETH_DATA(layer_3, group_none),
};
static struct attrib qeth_attr_fake_broadcast = {
.name = "fake_broadcast",
.title = "Enable simulation of broadcast capability",
.desc =
"Control whether a QETH device that doesn't support broadcast should\n"
"fake the broadcast capability.\n"
" 0: Fake broadcasting depending on hardware capabilities\n"
" 1: No faked broadcasting\n",
.defval = "0",
.order_cmp = after_layer2_order_cmp,
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
.st_data = QETH_DATA(layer_3, group_none),
};
static struct attrib qeth_attr_ipa_takeover_enable = {
.name = "ipa_takeover/enable",
.title = "Control IP address takeover",
@@ -1451,7 +1437,6 @@ struct subtype qeth_subtype_qeth = {
&qeth_attr_hw_trap,
&qeth_attr_route4,
&qeth_attr_route6,
&qeth_attr_fake_broadcast,
&qeth_attr_ipa_takeover_enable,
&qeth_attr_ipa_takeover_add4,
&qeth_attr_ipa_takeover_add6,

View File

@@ -13,6 +13,17 @@ all:
install:
$(SKIP) HAVE_FUSE=0
else
ifeq (${HAVE_CURL},0)
all:
$(SKIP) HAVE_CURL=0
install:
$(SKIP) HAVE_CURL=0
else
check_dep:
@@ -21,17 +32,26 @@ check_dep:
"fuse.h", \
"fuse-devel or libfuse-dev", \
"HAVE_FUSE=0")
$(call check_dep, \
"zdsfs", \
"curl/curl.h", \
"curl-devel or libcurl-dev", \
"HAVE_CURL=0")
ifneq ($(shell sh -c 'command -v pkg-config'),)
FUSE_CFLAGS = $(shell pkg-config --silence-errors --cflags fuse)
FUSE_LDLIBS = $(shell pkg-config --silence-errors --libs fuse)
CURL_CFLAGS = $(shell pkg-config --silence-errors --cflags libcurl)
CURL_LDLIBS = $(shell pkg-config --silence-errors --libs libcurl)
else
FUSE_CFLAGS = -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse
FUSE_LDLIBS = -lfuse
CURL_CFLAGS = -I/usr/include/s390x-linux-gnu/curl
CURL_LDLIBS = -lcurl
endif
ALL_CPPFLAGS += -DSYSFS
ALL_CFLAGS += -DHAVE_SETXATTR -pthread $(FUSE_CFLAGS)
LDLIBS += $(FUSE_LDLIBS) -lpthread -lrt -lm
ALL_CFLAGS += -DHAVE_SETXATTR -pthread $(FUSE_CFLAGS) $(CURL_CFLAGS)
LDLIBS += $(FUSE_LDLIBS) $(CURL_LDLIBS) -lpthread -lrt -lm
all: check_dep zdsfs
@@ -45,6 +65,8 @@ install: all
endif
endif
clean:
rm -f *.o *~ zdsfs core

View File

@@ -34,21 +34,33 @@ Data sets on tape devices are not supported.
To maintain data consistency, a DASD must not be modified while it is
in use by zdsfs. This can be assured by varying the device offline
in z/OS before setting it online in Linux.
in z/OS before setting it online in Linux or by using z/OSMF REST
services to notify z/OS about access to data sets.
The access to the device by Linux is not subject to RACF or any other
z/OS auditing mechanism. The safety of the data on the device must be
established by the respective Linux mechanisms. The default behavior
of zdsfs is to grant access to the files in the fuse file system only
to the user who has started the tool. This behavior can be
configured by using the options `allow_other', `default_permissions',
`umask', `uid', and `gid'.
Device access by Linux is not subject to RACF or other
z/OS auditing mechanisms unless the z/OSMF REST services are used for
a coordinated read access.
The safety of the data on the device must be established by
therespective Linux mechanisms. By default, zdsfs grants access to the
files in the fuse file system only to the user who started the
tool. This behavior can be changed by using the options `allow_other',
`default_permissions', `umask', `uid', and `gid'.
When using the z/OSMF REST services for coordinated read access, a
connection is established for every opened file. The z/OSMF REST
services confirm that the z/OS userid that is specified in the .netrc
configuration file has the required access rights for the data set.
Using this mechanism also an exclusive ENQ is obtained to mark the
data set as in use to z/OS. The ENQ prevents z/OS applications from
modifying the data set during zdsfs access.
If the ENQ cannot be obtained, the access from Linux fails with an
error.
Only physical sequential (PS) and partitioned data sets (PDS) are
supported. Supported record formats are: V, F, U, B, S, A, and M.
The file system is limited to basic operations (readdir, stat, open,
read, seek). Because the actual size of the data in each track is not
The file system is limited to basic operations: readdir, stat, open,
read, and seek. Because the actual size of the data in each track is not
always known, zdsfs does not support mmap. Seek operations read the
whole data set to the given offset. The performance of seek
operations to previous offsets can be improved by buffering seek
@@ -59,11 +71,11 @@ cannot provide exact file sizes. As a heuristic, the given file sizes
are the maximum possible data sizes, based on the number and size of
the extents that belong to each data set. When the actual end of the
data is reached during read, the usual end of file (EOF) is returned.
To make sure that the EOF is passed to the user correctly, the option
To ensure that the EOF is passed to the user correctly, the option
`-o direct_io' is set by zdsfs implicitly.
The detection of incomplete multi volume data sets does not work for
data sets for which only the first volume (device) is present.
Incomplete multi-volume data sets are not detected if only the first
volume (device) of the data set is present.
.SH OPTIONS
.SS "general options:"
@@ -89,7 +101,7 @@ Print version information, then exit.
\fB\-l\fR \fI<device_list>\fR
The specified file \fI<device_list>\fR contains a list of device
nodes, separated by white space (space, tab or new line). All device
nodes in this file are mounted as if given directly via the command
nodes in this file are mounted as if specified directly via the command
line.
.TP
\fB\-o\fR rdw
@@ -119,9 +131,9 @@ standard error stream.
\fB\-o\fR tracks=\fI<n>\fR
Size of the track buffer in tracks. The default for \fI<n>\fR is 128.
The data that is read from the DASD has to be stored in a buffer, because
The data that is read from the DASD must be stored in a buffer, because
the minimum size for a read operation in raw access mode is one track,
and the user data has to be extracted from the track images. Reading
and the user data must be extracted from the track images. Reading
more than one track at a time improves the overall performance, but
requires larger buffers.
@@ -154,7 +166,25 @@ read from the beginning of the data set.
.TP
\fB\-o\fR check_host_count
Stop processing if the device is used by another operating system instance.
Stop processing if the device is used by another operating system
instance.
.TP
\fB\-c\fR \fI<config_file>\fR
zdsfs configuration file. The default is /etc/zdsfs.conf.
.TP
\fB\-o\fR restapi
Make zdsfs use z/OSMF REST services for coordinated read access to
data sets. The user credentials are taken from .netrc file in the
user's home directory or where the NETRC environment variable points
to.
.TP
\fB\-o\fR restserver=<server_URL>
Specify up to 3 server URLs to z/OSMF REST services.
For multiple specifications, the URLs are tried sequentially, and the
first functioning URL is used.
.SS "Applicable FUSE options (version 2.8):"
This is a selected subset of all FUSE options. Use the zdsfs
@@ -220,11 +250,10 @@ by z/OS.
dsn=<data set name>,recfm=<fmt>,lrecl=<size>,dsorg=<org>
\fBdsn\fR: The data set name.
For physical sequential data sets this is the
same name as the file name in the mount directory. For partitioned
data sets (PDS) this is the same as the directory name in the mount
directory. For PDS members the member name is placed in parentheses
after the PDS name.
For physical sequential data sets, this is the same as the file name in the mount directory. For partitioned
data sets (PDS), this is the same as the directory name in the mount
directory. For PDS members, the member name is placed after the PDS
name, in parentheses.
\fBrecfm\fR: The record format.
@@ -244,6 +273,44 @@ directory:
\fBuser.dsorg\fR: The data set organization of a file.
.SH zdsfs configuration file
The default search path is /etc/zdsfs.conf.
Use the \fB\-c\fR \fI<config_file>\fR option to specify other zdsfs
configuration file locations.
.br
The configuration file can contain the following options:
.PP
.B restapi
=
.IR 0 / 1
.IP
Setting this option to 1 enables the z/OSMF REST services.
The z/OSMF REST services require a valid URL specification for a REST
server, and a .netrc file with a valid z/OS user ID and password.
.PP
.B restserver
=
.IR URL
.IP
Specifies the URL of the z/OSMF REST server that is
used for coordinated read access. For failover, up to 3 different
server addresses can be provided.
.PP
.B keepalive
=
.I timeout
(in seconds)
.IP
Specifies the keepalive timer for ENQs.
By default the timer is set to 540 seconds to prevent the ENQ from a
timeout after 10 minutes in case access to the data set takes longer
than this.
.SH EXAMPLES
To mount the z/OS disk with the name dasde enter:
@@ -270,6 +337,13 @@ To list all extended attributes of file FOOBAR.TEST.TXT
assuming the z/OS disk was mounted on /mnt:
# getfattr -d /mnt/FOOBAR.TEST.TXT
.br
To mount the z/OS disk using the z/OSMF REST services for coordinated
read access:
.br
# ./zdsfs -o restapi -o restserver=zos1.server.tld/zosmf /dev/dasde /mnt/
.SH SEE ALSO
getfattr(1), fuse(8), z/OS DFSMS Using Data Sets,

View File

@@ -21,6 +21,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include <time.h>
#include <signal.h>
#ifdef HAVE_SETXATTR
#include <linux/xattr.h>
@@ -36,6 +39,8 @@
/* defaults for file and directory permissions (octal) */
#define DEF_FILE_PERM 0440
#define DEF_DIR_PERM 0550
/* default timer interval 9 minutes, enq times out after 10 minutes */
#define DEFAULT_KEEPALIVE_SEC 540
struct zdsfs_info {
int devcount;
@@ -50,11 +55,24 @@ struct zdsfs_info {
size_t metasize; /* total size of meta data buffer */
size_t metaused; /* how many bytes of buffer are already filled */
time_t metatime; /* when did we create this meta data */
char *configfile;
int restapi;
unsigned int nr_server;
int active_server;
char *server[MAX_SERVER];
long keepalive;
};
static struct zdsfs_info zdsfsinfo;
static int zdsfs_create_meta_data_buffer(struct zdsfs_info *);
static int zdsfs_verify_datasets(void);
static struct util_list *open_dsh;
static int timer_running;
struct dsh_node {
struct util_list_node node;
struct dshandle *dsh;
};
struct zdsfs_file_info {
struct dshandle *dsh;
@@ -64,6 +82,67 @@ struct zdsfs_file_info {
size_t metaread; /* how many bytes have already been read */
};
/* Allocate and initialize a new list of struct dsh_node. */
static struct util_list *dshlist_alloc(void)
{
struct util_list *list;
list = util_malloc(sizeof(struct util_list));
util_list_init(list, struct dsh_node, node);
return list;
}
/* free list of struct dsh_node. */
static void dshlist_free(struct util_list *list)
{
struct dsh_node *s, *n;
if (!list)
return;
util_list_iterate_safe(list, s, n) {
util_list_remove(list, s);
free(s);
}
free(list);
}
/* add dsh to list */
static void dshlist_add(struct util_list *list, struct dshandle *dsh)
{
struct dsh_node *s;
s = util_malloc(sizeof(struct dsh_node));
s->dsh = dsh;
util_list_add_tail(list, s);
}
/* Find a dsh_node. */
static struct dsh_node *dshlist_find(struct util_list *list, struct dshandle *dsh)
{
struct dsh_node *s;
util_list_iterate(list, s) {
if (s->dsh == dsh)
return s;
}
return NULL;
}
/* Remove a dsh_node from the list. */
void dshlist_remove(struct util_list *list, struct dshandle *dsh)
{
struct dsh_node *p;
p = dshlist_find(list, dsh);
if (p) {
util_list_remove(list, p);
free(p);
}
}
/* normalize the given path name to a dataset name
@@ -97,7 +176,47 @@ static void path_to_member_name(const char *path, char *normds, size_t size)
}
}
static void setup_timer(long sec)
{
static struct itimerval timer;
memset(&timer, 0, sizeof(struct itimerval));
timer.it_value.tv_sec = sec;
setitimer(ITIMER_REAL, &timer, NULL);
}
static void keep_alive(int UNUSED(signal))
{
struct dsh_node *s;
if (!open_dsh) {
timer_running = 0;
setup_timer(0);
return;
}
util_list_iterate(open_dsh, s) {
lzds_rest_ping(s->dsh,
zdsfsinfo.server[zdsfsinfo.active_server]);
}
timer_running = 1;
setup_timer(zdsfsinfo.keepalive);
}
void keepalive_start(void)
{
struct sigaction act;
if (!open_dsh || timer_running)
return;
timer_running = 1;
/* Setup timer for periodic ping. */
memset(&act, 0, sizeof(struct sigaction));
act.sa_handler = &keep_alive;
sigaction(SIGALRM, &act, NULL);
setup_timer(zdsfsinfo.keepalive);
}
static int zdsfs_getattr(const char *path, struct stat *stbuf)
{
@@ -375,6 +494,43 @@ static int zdsfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
return 0;
}
/*
* walk through the serverlist and check if the URLs start with http or https
* if not attach a https:// prefix
* also check if they end with / and if not attach it
*
* afterwards ping the z/OSMF server and use the first working one
*
* return 1 if working server found 0 otherwise
*/
static int zdsfs_test_restserver(void)
{
unsigned int i;
char *server;
char *prefix;
for (i = 0; i < zdsfsinfo.nr_server; i++) {
server = zdsfsinfo.server[i];
if (strncmp(server, "http", 4)) {
prefix = util_strdup("https://");
server = util_strcat_realloc(prefix, server);
free(zdsfsinfo.server[i]);
zdsfsinfo.server[i] = server;
}
if (strncmp(server + strlen(server) - 1, "/", 1)) {
server = util_strcat_realloc(server, "/");
zdsfsinfo.server[i] = server;
}
if (lzds_rest_ping(NULL, zdsfsinfo.server[i])) {
zdsfsinfo.active_server = i;
fprintf(stdout, "Using z/OSMF REST services on %s\n",
zdsfsinfo.server[i]);
return 1;
}
}
return 0;
}
static int zdsfs_open(const char *path, struct fuse_file_info *fi)
{
@@ -464,13 +620,32 @@ static int zdsfs_open(const char *path, struct fuse_file_info *fi)
rc = -rc;
goto error2;
}
retry:
if (zdsfsinfo.restapi && zdsfsinfo.active_server >= 0) {
rc = lzds_rest_get_enq(dsh,
zdsfsinfo.server[zdsfsinfo.active_server]);
/* if the REST server is not responding try the other */
if (rc == ECONNREFUSED && zdsfs_test_restserver()) {
goto retry;
} else if (rc) {
lzds_dshandle_get_errorlog(dsh, &log);
lzds_errorlog_fprint(log, stderr);
rc = -rc;
goto error2;
} else {
dshlist_add(open_dsh, dsh);
/* add to open dsh list */
keepalive_start();
}
}
rc = lzds_dshandle_open(dsh);
if (rc) {
fprintf(stderr, "Error when opening data set:\n");
lzds_dshandle_get_errorlog(dsh, &log);
lzds_errorlog_fprint(log, stderr);
rc = -rc;
goto error2;
goto error3;
}
zfi->is_metadata_file = 0;
zfi->metaread = 0;
@@ -478,6 +653,8 @@ static int zdsfs_open(const char *path, struct fuse_file_info *fi)
fi->fh = (uint64_t)(unsigned long)zfi;
return 0;
error3:
dshlist_remove(open_dsh, dsh);
error2:
lzds_dshandle_free(dsh);
error1:
@@ -495,7 +672,10 @@ static int zdsfs_release(const char *UNUSED(path), struct fuse_file_info *fi)
return -EINVAL;
zfi = (struct zdsfs_file_info *)(unsigned long)fi->fh;
if (zfi->dsh) {
lzds_rest_release_enq(zfi->dsh,
zdsfsinfo.server[zdsfsinfo.active_server]);
lzds_dshandle_close(zfi->dsh);
dshlist_remove(open_dsh, zfi->dsh);
lzds_dshandle_free(zfi->dsh);
}
rc = pthread_mutex_destroy(&zfi->mutex);
@@ -831,6 +1011,8 @@ enum {
KEY_DEVFILE,
KEY_TRACKS,
KEY_SEEKBUFFER,
KEY_CONFIG,
KEY_SERVER,
};
#define ZDSFS_OPT(t, p, v) { t, offsetof(struct zdsfs_info, p), v }
@@ -843,9 +1025,12 @@ static const struct fuse_opt zdsfs_opts[] = {
FUSE_OPT_KEY("-l %s", KEY_DEVFILE),
FUSE_OPT_KEY("tracks=", KEY_TRACKS),
FUSE_OPT_KEY("seekbuffer=", KEY_SEEKBUFFER),
FUSE_OPT_KEY("-c %s", KEY_CONFIG),
FUSE_OPT_KEY("restserver=", KEY_SERVER),
ZDSFS_OPT("rdw", keepRDW, 1),
ZDSFS_OPT("ignore_incomplete", allow_inclomplete_multi_volume, 1),
ZDSFS_OPT("check_host_count", host_count, 1),
ZDSFS_OPT("restapi", restapi, 1),
FUSE_OPT_END
};
@@ -865,6 +1050,8 @@ static void usage(const char *progname)
"ZDSFS options:\n"
" -l list_file Text file that contains a list of DASD device"
" nodes\n"
" -c config_file Text file that contains configuration options\n"
" for zdsfs\n"
" -o rdw Keep record descriptor words in byte stream\n"
" -o ignore_incomplete Continue processing even if parts of a multi"
" volume\n"
@@ -874,6 +1061,10 @@ static void usage(const char *progname)
" size (default 1048576)\n"
" -o check_host_count Stop processing if the device is used by another\n"
" operating system instance\n"
" -o restapi Enable using z/OSMF REST services for coordinated\n"
" access to datasets\n"
" -o restserver=URL The URL of the z/OSMF REST server to be used for\n"
" coordinated access to datasets\n"
, progname);
}
@@ -973,6 +1164,67 @@ static void zdsfs_process_device_file(const char *devfile)
free(buffer);
}
void remove_whitespace(const char *s, char *t)
{
while (*s != '\0') {
if (!isspace(*s)) {
*t = *s;
t++;
}
s++;
}
*t = '\0';
}
static void zdsfs_process_config_file(const char *config)
{
char line[MAX_LINE_LENGTH];
char *tmp, *key, *value;
FILE *fd;
char delimiter[] = " =#\n";
unsigned long enabled;
fd = fopen(config, "r");
if (!fd) {
fprintf(stderr, "could not open file %s: %s\n",
config, strerror(errno));
return;
}
while (fgets(line, sizeof(line), fd)) {
/* skip empty lines */
if (*line == '\n' || *line == '#')
continue;
/* remove all whitespaces */
tmp = util_malloc(strlen(line));
remove_whitespace(line, tmp);
key = strtok(tmp, delimiter);
if (strcmp(key, "restserver") == 0) {
if (zdsfsinfo.nr_server >= MAX_SERVER) {
free(tmp);
continue;
}
value = strtok(NULL, delimiter);
zdsfsinfo.server[zdsfsinfo.nr_server] =
util_strdup(value);
zdsfsinfo.nr_server++;
} else if (strcmp(key, "restapi") == 0) {
value = strtok(NULL, delimiter);
enabled = strtoul(value, NULL, 0);
if (enabled == 1)
zdsfsinfo.restapi = true;
} else if (strcmp(key, "keepalive") == 0) {
value = strtok(NULL, delimiter);
zdsfsinfo.keepalive = strtoul(value, NULL, 0);
}
free(tmp);
}
fclose(fd);
}
static int zdsfs_process_args(void *UNUSED(data), const char *arg, int key,
struct fuse_args *outargs)
{
@@ -1057,6 +1309,18 @@ static int zdsfs_process_args(void *UNUSED(data), const char *arg, int key,
", program version %s\n", RELEASE_STRING);
fprintf(stdout, "Copyright IBM Corp. 2013, 2017\n");
exit(0);
case KEY_CONFIG:
/* note that arg starts with "-c" */
zdsfsinfo.configfile = util_strdup(arg + 2);
return 0;
case KEY_SERVER:
if (zdsfsinfo.nr_server >= MAX_SERVER)
return 0;
value = arg + strlen("restserver=");
zdsfsinfo.server[zdsfsinfo.nr_server] =
util_strdup(value);
zdsfsinfo.nr_server++;
return 0;
default:
fprintf(stderr, "Unknown argument key %x\n", key);
exit(1);
@@ -1069,13 +1333,18 @@ int main(int argc, char *argv[])
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
int rc;
timer_running = 0;
bzero(&zdsfsinfo, sizeof(zdsfsinfo));
zdsfsinfo.keepRDW = 0;
zdsfsinfo.allow_inclomplete_multi_volume = 0;
zdsfsinfo.tracks_per_frame = 128;
zdsfsinfo.seek_buffer_size = 1048576;
zdsfsinfo.configfile = "/etc/zdsfs.conf";
zdsfsinfo.keepalive = DEFAULT_KEEPALIVE_SEC;
zdsfsinfo.active_server = -1;
rc = lzds_zdsroot_alloc(&zdsfsinfo.zdsroot);
open_dsh = dshlist_alloc();
if (rc) {
fprintf(stderr, "Could not allocate internal structures\n");
exit(1);
@@ -1085,6 +1354,7 @@ int main(int argc, char *argv[])
fprintf(stderr, "Failed to parse option\n");
exit(1);
}
zdsfs_process_config_file(zdsfsinfo.configfile);
if (!zdsfsinfo.devcount) {
fprintf(stderr, "Please specify a block device\n");
@@ -1111,9 +1381,21 @@ int main(int argc, char *argv[])
if (rc)
goto cleanup;
if (zdsfsinfo.restapi) {
curl_global_init(CURL_GLOBAL_DEFAULT);
zdsfs_test_restserver();
if (zdsfsinfo.active_server < 0) {
fprintf(stderr, "Error: No z/OSMF REST Server reachable\n");
rc = -EACCES;
goto cleanup;
}
}
rc = fuse_main(args.argc, args.argv, &rdf_oper, NULL);
cleanup:
curl_global_cleanup();
dshlist_free(open_dsh);
lzds_zdsroot_free(zdsfsinfo.zdsroot);
fuse_opt_free_args(&args);

View File

@@ -69,8 +69,6 @@ struct globals {
extern struct globals g;
#define PROC_CMDLINE "/proc/cmdline"
#define DEV_ZCORE "/sys/kernel/debug/zcore/mem"
#define DEV_ZCORE_MAP "/sys/kernel/debug/zcore/memmap"
#define DEV_ZCORE_REIPL "/sys/kernel/debug/zcore/reipl"
#define DEV_ZCORE_HSA "/sys/kernel/debug/zcore/hsa"
#define REIPL "1"

View File

@@ -420,7 +420,7 @@ void VirtAdapterPrinter::print_virt_adpt(FILE *fp, __u32 devno,
int *rc)
{
if (m_csv)
fprintf(fp, "%x,%x.%x.%04x,",
fprintf(fp, "%x,%x.%x.%04x",
m_cfg->get_chpid_by_devno(devno, rc),
ZIOREP_BUSID_UNPACKED(devno));
else
@@ -517,7 +517,7 @@ void VirtAdapterPrinter::print_num_requests(FILE *fp, const struct blkiomon_stat
void VirtAdapterPrinter::print_topline(FILE *fp)
{
if (m_csv)
fprintf(fp, "timestamp,aggregated,CHPID,Bus-ID,qdio utilization max %%,qdio utilization avg %%,queue full,fail erc,throughput read / MS/s,throughput write / MS/s,I/O requests read,I/O requqests write\n");
fprintf(fp, "timestamp,aggregated,CHPID,Bus-ID,qdio utilization max %%,qdio utilization avg %%,queue full,fail erc,throughput read / MS/s,throughput write / MS/s,I/O requests read,I/O requests write\n");
else {
fprintf(fp, "CHP Bus-ID |qdio util.%%|queu|fail|-thp in MB/s-|I/O reqs-|\n");
fprintf(fp, " ID max avg full erc rd wrt rd wrt\n");

View File

@@ -13,7 +13,6 @@
#include <stdarg.h>
#include "lib/zt_common.h"
#include "boot/s390.h"
#include "error.h"
@@ -501,7 +500,7 @@ void initialize(void)
/*
* Load disabled wait PSW with reason code in address field
*/
void __noreturn libc_stop(unsigned long reason)
void libc_stop(unsigned long reason)
{
struct psw_t psw;

View File

@@ -14,6 +14,8 @@
#include <stdint.h>
#include <stddef.h>
#include "lib/zt_common.h"
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
@@ -55,7 +57,7 @@ char *strcpy(char *, const char *);
unsigned long get_zeroed_page(void);
void free_page(unsigned long);
void initialize(void);
void libc_stop(unsigned long);
void libc_stop(unsigned long) __noreturn;
void start(void);
void pgm_check_handler(void);
void pgm_check_handler_fn(void);

View File

@@ -57,18 +57,6 @@ static inline void __noreturn start_kernel(void)
while (1);
}
unsigned int store_ipl_parmblock(struct ipl_pl_hdr *pl_hdr)
{
int rc;
rc = diag308(DIAG308_STORE, pl_hdr);
if (rc == DIAG308_RC_OK &&
pl_hdr->version <= IPL_MAX_SUPPORTED_VERSION)
return 0;
return 1;
}
unsigned int
is_verified_address(unsigned long image_addr)
{
@@ -126,9 +114,18 @@ secure_boot_enabled()
unsigned int rc;
pl_hdr = (void *)get_zeroed_page();
if (!pl_hdr || store_ipl_parmblock(pl_hdr))
switch (diag308(DIAG308_STORE, pl_hdr)) {
case DIAG308_RC_OK:
rc = pl_hdr->version <= IPL_MAX_SUPPORTED_VERSION &&
!!(pl_hdr->flags & IPL_FLAG_SECURE);
break;
case DIAG308_RC_NO_CONF:
rc = 0;
break;
default:
panic(ESECUREBOOT, "%s", msg_sipl_noparm);
rc = !!(pl_hdr->flags & IPL_FLAG_SECURE);
break;
}
free_page((unsigned long) pl_hdr);
return rc;

View File

@@ -126,7 +126,7 @@ char* scan_keyword_name(enum scan_keyword_id id);
int scan_check_defaultboot(struct scan_token* scan);
struct scan_token* scan_build_automenu(struct scan_token* scan);
int scan_check(struct scan_token* scan);
int scan_check_bls(struct scan_token *scan);
void scan_update_bls_path(struct scan_token *scan);
int scan_find_section(struct scan_token* scan, char* name, enum scan_id type,
int offset);
int scan_check_section_data(char* keyword[], int* line, char* name,

View File

@@ -509,7 +509,8 @@ add_ipl_program(int fd, struct job_ipl_data* ipl, disk_blockptr_t* program,
size_t stage3_params_size;
const char *comp_name[10];
size_t signature_size;
int offset, flags = 0;
int offset;
uint64_t flags = 0;
void *stage3_params;
struct stat stats;
void *signature;

View File

@@ -89,6 +89,88 @@ disk_determine_dasd_type(struct disk_info *data,
return 0;
}
static int blkext_get_partnum(dev_t dev)
{
char path[PATH_MAX], *buf;
int dev_major, dev_minor, partnum = -1;
dev_major = major(dev);
dev_minor = minor(dev);
snprintf(path, PATH_MAX, "/sys/dev/block/%d:%d/partition",
dev_major, dev_minor);
if (misc_read_special_file(path, &buf, NULL, 1)) {
error_text("Could not read from path '%s'", path);
return -1;
}
partnum = atoi(buf);
free(buf);
if (partnum < 0) {
error_text("Bad partition number in '%s'", path);
return -1;
}
return partnum;
}
static int blkext_is_base_device(dev_t dev)
{
int dev_major, dev_minor;
char path[PATH_MAX];
struct stat stats;
dev_major = major(dev);
dev_minor = minor(dev);
snprintf(path, PATH_MAX, "/sys/dev/block/%d:%d/partition",
dev_major, dev_minor);
return (stat(path, &stats));
}
static int blkext_get_base_dev(dev_t dev, dev_t *base_dev)
{
int base_major, base_minor;
char dev_path[PATH_MAX], base_path[PATH_MAX];
char *temp_path, *buf;
misc_asprintf(&temp_path, "/sys/dev/block/%d:%d", major(dev), minor(dev));
if (!realpath(temp_path, dev_path)) {
error_reason(strerror(errno));
error_text("Could not resolve link %s", temp_path);
free(temp_path);
return -1;
}
free(temp_path);
misc_asprintf(&temp_path, "%s/..", dev_path);
if (!realpath(temp_path, base_path)) {
error_reason(strerror(errno));
error_text("Could not resolve path %s", temp_path);
free(temp_path);
return -1;
}
free(temp_path);
misc_asprintf(&temp_path, "%s/dev", base_path);
if (misc_read_special_file(temp_path, &buf, NULL, 1)) {
error_text("Could not read from path '%s'", temp_path);
free(temp_path);
return -1;
}
free(temp_path);
if (sscanf(buf, "%i:%i", &base_major, &base_minor) != 2) {
error_text("Could not parse major:minor from string '%s'", buf);
free(buf);
return -1;
}
free(buf);
*base_dev = makedev(base_major, base_minor);
return 0;
}
/* Return non-zero for ECKD type. */
int
disk_is_eckd(disk_type_t type)
@@ -409,8 +491,17 @@ disk_get_info(const char* device, struct job_target_data* target,
} else if (strcmp(data->drv_name, "blkext") == 0) {
data->devno = -1;
data->type = disk_type_scsi;
data->partnum = stats.st_rdev & SCSI_PARTN_MASK;
data->device = stats.st_rdev & ~SCSI_PARTN_MASK;
if (blkext_is_base_device(stats.st_rdev)) {
data->device = stats.st_rdev;
data->partnum = 0;
} else {
if (blkext_get_base_dev(stats.st_rdev, &data->device))
goto out_close;
data->partnum = blkext_get_partnum(stats.st_rdev);
if (data->partnum == -1)
goto out_close;
}
} else {
/* Driver name is unknown */
error_reason("Unsupported device driver '%s'", data->drv_name);

View File

@@ -1874,12 +1874,8 @@ get_job_from_config_file(struct command_line* cmdline, struct job_data* job)
scan_free(scan);
return rc;
}
rc = scan_check_bls(scan);
if (rc) {
error_text("BLS parsing '%s'", blsdir);
scan_free(scan);
return rc;
}
/* maybe we need to update bls search path with target path */
scan_update_bls_path(scan);
/* Get job from config file data */
if (cmdline->menu != NULL)
rc = get_menu_job(scan, cmdline->menu, job);

View File

@@ -21,6 +21,7 @@
#define _GNU_SOURCE
#endif
#include <assert.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
@@ -28,6 +29,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <sys/stat.h>
@@ -730,6 +732,67 @@ scan_bls_field(struct misc_file_buffer *file, struct scan_token* scan,
return 0;
}
/**
* find a line with keyword "title" and move it to the top
*/
static int sort_bls_fields(struct misc_file_buffer *file, char *filename)
{
bool is_title = false;
size_t title_len = 0;
int nr_titles = 0;
size_t title_off;
char *title;
int current;
size_t len;
while (file->length - file->pos > 4 /* for "title" */) {
if (strncmp("title", &file->buffer[file->pos], 5) == 0) {
is_title = true;
nr_titles++;
title_off = file->pos;
}
for (len = 0;; file->pos++, len++) {
current = misc_get_char(file, 0);
if (current == '\n' || current == EOF)
break;
}
if (is_title == true)
title_len = len;
if (current == EOF)
break;
file->pos++;
}
file->pos = 0;
if (nr_titles == 0) {
error_reason("no title in %s", filename);
return -1;
}
if (nr_titles > 1) {
error_reason("more than one title in %s", filename);
return -1;
}
if (title_off == 0)
return 0;
title = misc_malloc(title_len);
if (!title)
return -1;
/*
* copy the title field w/o trailing '\n' to the temporary buffer
*/
memcpy(title, &file->buffer[title_off], title_len);
/*
* shift preceded memory region w/o trailing '\n' to the right
*/
assert(file->buffer[title_off - 1] == '\n');
memmove(&file->buffer[title_len + 1], &file->buffer[0], title_off - 1);
file->buffer[title_len] = '\n';
memcpy(&file->buffer[0], title, title_len);
free(title);
return 0;
}
int
scan_bls(const char* blsdir, struct scan_token** token, int scan_size)
@@ -780,6 +843,10 @@ scan_bls(const char* blsdir, struct scan_token** token, int scan_size)
if (rc)
goto err;
rc = sort_bls_fields(&file, filename);
if (rc)
goto err;
while ((size_t)file.pos < file.length) {
current = misc_get_char(&file, 0);
switch (current) {
@@ -1567,15 +1634,17 @@ scan_check(struct scan_token* scan)
/*
* Check if kernel and initrd image paths provided by BLS files are readable.
* If not, add value of 'scan_keyword_target' into search path and silently
* update scan list.
* update scan list if the file exists.
* In case neither path works the scan_check code will correctly handle missing
* files
*/
int
scan_check_bls(struct scan_token *scan)
void scan_update_bls_path(struct scan_token *scan)
{
int i, rc;
char *target_value = NULL;
char *img_value = NULL;
char *buffer = NULL;
char *file = NULL;
char *tmp, *value;
int i;
/*
* In the BLS case, each BLS section heading inherits a keyword
* assignment target= from zipl.conf, and they are all the same.
@@ -1589,38 +1658,46 @@ scan_check_bls(struct scan_token *scan)
}
}
if (!target_value)
return -1;
return;
for (i = 0 ; scan[i].id != scan_id_empty; i++) {
if (scan[i].id != scan_id_keyword_assignment)
continue;
if (scan[i].content.keyword.keyword == scan_keyword_image ||
scan[i].content.keyword.keyword == scan_keyword_ramdisk) {
rc = misc_check_readable_file(
scan[i].content.keyword.value);
if (rc) {
value = scan[i].content.keyword.value;
/*
* put the filename only into the file var before
* checking its presence
*/
if (contains_address(value)) {
tmp = strrchr(value, ',');
file = strndup(value, tmp - value);
} else {
file = value;
}
if (misc_check_readable_file(file)) {
misc_asprintf(&img_value, "%s%s",
target_value,
scan[i].content.keyword.value);
rc = misc_check_readable_file(img_value);
if (rc) {
error_text(
"Image file '%s' is not accessible",
scan[i].content.keyword.value);
return rc;
target_value, file);
if (misc_check_readable_file(img_value))
continue;
/*
* when file has stripped the load address part,
* do generate a prefixed value
*/
if (file != value) {
free(file);
free(img_value);
misc_asprintf(&img_value, "%s%s",
target_value, value);
}
buffer = (char *)
misc_malloc(strlen(img_value) + 1);
if (buffer == NULL)
return -1;
memcpy(buffer, img_value, strlen(img_value));
buffer[strlen(img_value)] = 0;
free(scan[i].content.keyword.value);
scan[i].content.keyword.value = buffer;
scan[i].content.keyword.value = img_value;
}
}
}
return 0;
return;
}
static int

View File

@@ -1,5 +1,7 @@
include ../common.mak
SUB_DIRS = ekmfweb
ifneq (${HAVE_OPENSSL},0)
BUILD_TARGETS += zkey
INSTALL_TARGETS += install-zkey
@@ -62,7 +64,7 @@ zkey-cryptsetup-skip-cryptsetup2:
zkey-cryptsetup-skip-jsonc:
echo " SKIP zkey-cryptsetup due to HAVE_JSONC=0"
all: $(BUILD_TARGETS)
all: $(BUILD_TARGETS) $(SUB_DIRS)
zkey.o: zkey.c pkey.h cca.h ep11.h misc.h
pkey.o: pkey.c pkey.h cca.h ep11.h utils.h
@@ -73,9 +75,10 @@ properties.o: check-dep-zkey properties.c properties.h
keystore.o: keystore.c keystore.h properties.h pkey.h cca.h ep11.h utils.h
zkey-cryptsetup.o: check-dep-zkey-cryptsetup zkey-cryptsetup.c pkey.h cca.h \
ep11.h misc.h utils.h
kms.o: kms.c kms.h kms-plugin.h utils.h pkey.h
zkey: LDLIBS = -ldl -lcrypto
zkey: zkey.o pkey.o cca.o ep11.o properties.o keystore.o utils.o $(libs)
zkey: zkey.o pkey.o cca.o ep11.o properties.o keystore.o utils.o kms.o $(libs)
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
zkey-cryptsetup: LDLIBS = -ldl -lcryptsetup -ljson-c -lcrypto
@@ -86,22 +89,35 @@ install-common:
$(INSTALL) -d -m 755 $(DESTDIR)$(USRBINDIR)
$(INSTALL) -d -m 755 $(DESTDIR)$(MANDIR)/man1
install-zkey:
install-zkey: zkey
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zkey $(DESTDIR)$(USRBINDIR)
$(INSTALL) -m 644 -c zkey.1 $(DESTDIR)$(MANDIR)/man1
$(INSTALL) -d -m 770 $(DESTDIR)$(SYSCONFDIR)/zkey
$(INSTALL) -d -m 770 $(DESTDIR)$(SYSCONFDIR)/zkey/repository
$(INSTALL) -m 644 -c kms-plugins.conf $(DESTDIR)$(SYSCONFDIR)/zkey
install-zkey-cryptsetup:
install-zkey-cryptsetup: zkey-cryptsetup
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zkey-cryptsetup $(DESTDIR)$(USRBINDIR)
$(INSTALL) -m 644 -c zkey-cryptsetup.1 $(DESTDIR)$(MANDIR)/man1
install: all install-common $(INSTALL_TARGETS)
install: all install-common $(INSTALL_TARGETS) $(SUB_DIRS)
clean:
clean: $(SUB_DIRS)
rm -f *.o zkey zkey-cryptsetup detect-libcryptsetup.dep \
check-dep-zkey check-dep-zkey-cryptsetup
#
# For simple "make" we explicitly set the MAKECMDGOALS to "all".
#
ifeq ($(MAKECMDGOALS),)
MAKECMDGOALS = all
endif
$(SUB_DIRS):
$(foreach goal,$(MAKECMDGOALS), \
$(MAKE) -C $@ TOPDIR=$(TOPDIR) ARCH=$(ARCH) $(goal) ;)
.PHONY: $(SUB_DIRS)
.PHONY: all install clean zkey-skip zkey-cryptsetup-skip-cryptsetup2 \
zkey-cryptsetup-skip-jsonc install-common install-zkey \
install-zkey-cryptsetup

View File

@@ -554,7 +554,8 @@ static int get_cca_adapter_version(struct cca_lib *cca,
* because the zcrypt kernel module is on an older level. -ENODEV is
* returned if the APQN is not available.
*/
int select_cca_adapter(struct cca_lib *cca, int card, int domain, bool verbose)
int select_cca_adapter(struct cca_lib *cca, unsigned int card,
unsigned int domain, bool verbose)
{
unsigned int adapters, adapter;
char adapter_serialnr[9];
@@ -633,12 +634,12 @@ struct find_mkvp_info {
u8 mkvp[MKVP_LENGTH];
unsigned int flags;
bool found;
int card;
int domain;
unsigned int card;
unsigned int domain;
bool verbose;
};
static int find_mkvp(int card, int domain, void *handler_data)
static int find_mkvp(unsigned int card, unsigned int domain, void *handler_data)
{
struct find_mkvp_info *info = (struct find_mkvp_info *)handler_data;
struct mk_info mk_info;
@@ -711,7 +712,7 @@ int select_cca_adapter_by_mkvp(struct cca_lib *cca, u8 *mkvp, const char *apqns,
pr_verbose(verbose, "Select mkvp %s in APQNs %s for the CCA host "
"library", printable_mkvp(CARD_TYPE_CCA, mkvp),
apqns == 0 ? "ANY" : apqns);
apqns == NULL ? "ANY" : apqns);
memcpy(info.mkvp, mkvp, sizeof(info.mkvp));
info.flags = flags;

View File

@@ -123,7 +123,8 @@ int key_token_change(struct cca_lib *cca,
u8 *secure_key, unsigned int secure_key_size,
char *method, bool verbose);
int select_cca_adapter(struct cca_lib *cca, int card, int domain, bool verbose);
int select_cca_adapter(struct cca_lib *cca, unsigned int card,
unsigned int domain, bool verbose);
#define FLAG_SEL_CCA_MATCH_CUR_MKVP 0x01
#define FLAG_SEL_CCA_MATCH_OLD_MKVP 0x02

48
zkey/ekmfweb/Makefile Normal file
View File

@@ -0,0 +1,48 @@
include ../../common.mak
all: zkey-ekmfweb.so
libs = $(rootdir)/libutil/libutil.a
export LIBRARY_PATH = $(rootdir)/libekmfweb:$LIBRARY_PATH
zkey-ekmfweb.o: zkey-ekmfweb.c zkey-ekmfweb.h ../kms-plugin.h \
../cca.h ../utils.h ../pkey.h ../properties.h \
$(rootdir)include/ekmfweb/ekmfweb.h $(rootdir)/libekmfweb/libekmfweb.so
properties.o: ../properties.c ../properties.h
$(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -fPIC -c $< -o $@
pkey.o: ../pkey.c ../pkey.h ../cca.h ../ep11.h ../utils.h
$(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -fPIC -c $< -o $@
cca.o: ../cca.c ../cca.h ../pkey.h ../ep11.h ../utils.h
$(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -fPIC -c $< -o $@
ep11.o: ../ep11.c ../ep11.h ../pkey.h ../cca.h ../utils.h
$(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -fPIC -c $< -o $@
utils.o: ../utils.c ../utils.h ../pkey.h ../cca.h ../ep11.h
$(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -fPIC -c $< -o $@
zkey-ekmfweb.so: ALL_CFLAGS += -fPIC
zkey-ekmfweb.so: LDLIBS = -lekmfweb -ldl -lcrypto -shared
zkey-ekmfweb.so: LDFLAGS = -shared -Wl,--version-script=zkey-ekmfweb.map \
-Wl,-z,defs,-Bsymbolic
zkey-ekmfweb.so: zkey-ekmfweb.o properties.o pkey.o cca.o ep11.o utils.o $(libs)
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
install-libekmfweb.dep:
$(MAKE) -C $(rootdir)/libekmfweb/ TOPDIR=$(TOPDIR) ARCH=$(ARCH) install
touch install-libekmfweb.dep
install: all install-libekmfweb.dep zkey-ekmfweb.so
$(INSTALL) -d -m 755 $(DESTDIR)$(MANDIR)/man1
$(INSTALL) -m 644 -c zkey-ekmfweb.1 $(DESTDIR)$(MANDIR)/man1
$(INSTALL) -d -m 755 $(DESTDIR)$(LIB64DIR)
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 -T zkey-ekmfweb.so $(DESTDIR)$(LIB64DIR)/zkey-ekmfweb.so
clean:
rm -f *.o zkey-ekmfweb.so install-libekmfweb.dep
.PHONY: all install clean

497
zkey/ekmfweb/zkey-ekmfweb.1 Normal file
View File

@@ -0,0 +1,497 @@
.\" Copyright IBM Corp. 2020
.\" s390-tools is free software; you can redistribute it and/or modify
.\" it under the terms of the MIT license. See LICENSE for details.
.\"
.TH ZKEY\-EKMFWEB 1 "July 2020" "s390-tools"
.SH NAME
zkey\-ekmfweb \- Key management system plugin for EKMF Web (IBM Enterprise Key
Management Foundation \- Web Edition)
.
.
.
.SH DESCRIPTION
The \fBzkey\-ekmfweb.so\fP library is a key management system plugin for
\fBzkey\fP and provides an interface to \fBEKMF Web\fP (IBM Enterprise Key
Management Foundation \- Web Edition). It allows to integrate the external key
management system EKMF Web into zkey.
.PP
Secure AES keys can be generated in EKMF Web and are then imported into the zkey
secure key repository. The keys can be used to encrypt volumes, the same way
as with secure AES keys generated by zkey locally.
.PP
EKMF Web supports secure keys of type \fBCCA\-AESCIPHER\fP, and requires one or
multiple \fBIBM cryptographic adapters in CCA coprocessor mode\fP of version 6
or later, e.g. a CEX6C.
.
.SS "Bind the zkey secure key repository to EKMF Web"
.
To use EKMF Web with zkey, the zkey secure key repository must first be bound to
the EKMF Web key management system plugin.
.PP
Use the \fBzkey kms plugins\fP command to list available key management system
plugins. The EKMF Web plugin appears as plugin \fBEKMFWeb\fP in the list of
available plugins. If it does not appear, check if it is configured properly in
configuration file \fB/etc/zkey/kms\-plugins.conf\fP. Refer to the \fBzkey\fP
man page for details about this configuration file.
.PP
Use the \fBzkey kms bind EKMFWeb\fP command to bind the EKMF Web key management
system plugin to the zkey repository. You must then configure the EKMF Web
plugin with command \fBzkey kms configure\fP before it can be used.
.
.SS "Display information about the EKMF Web key management system plugin"
.
Use the \fBzkey kms info\fP command to display information about the EKMF Web
key management system plugin and its configuration. If any of the settings are
displayed as \fB'(configuration required)'\fP, then you must configure these
settings before you can use the EKMF Web plugin. Use the \fBzkey kms
configure\fP to do so.
.
.SS "Configure the EKMF Web key management system plugin"
.
Use the \fBzkey kms configure\fP command to configure or re\-configure the
EKMF Web plugin. Use command \fBzkey kms configure \-\-help\fP to display the
possible command line options to perform the configuration.
.PP
Configuring the EKMF Web plugin may be a multi-step task. You can supply all
configuration options at once or use the \fBzkey kms configure\fP command
several times supplying only one or a few configuration options each time.
.PP
The following settings must be configured:
.RS 2
.IP "\(bu" 2
The \fBAPQNs\fP associated with the EKMF Web key management system plugin. These
APQNs are used by the EKMF Web plugin to generate internally used secure keys
(i.e. the identity key), as well as to import secure AES keys from EKMF Web into
the zkey repository, enciphered with the current CCA master key. Secure keys
imported from EKMF Web will automatically be associated with the APQNs
associated with the EKMF Web plugin. Use the \fB\-\-apqns\fP option to specify
the APQNs to associate with the EKMF Web plugin.
.
.IP "\(bu" 2
The \fBconnection to the EKMF Web server\fP. The EKMF Web plugin communicates
with EKMF Web via RESTful web services over HTTPS (Hypertext Transfer Protocol
Secure). Use option \fB\-\-ekmfweb\-url\fP to specify the URL of the EKMF Web
server. The URL should start with \fB'https://'\fP, and may contain a port
number separated by a colon. If no port number is specified, 443 is used for
HTTPS. Additional TLS (Transport Layer Security) specific options can be
specified to control the behavior of the TLS protocol and the validation of the
EKMF Web server's certificate. Use command \fBzkey kms configure \-\-help\fP to
display the possible command line options.
.
.IP "\(bu" 2
The \fBEKMF Web settings\fP, such as the EKMF Web server's public key and the
key templates used by EKMF Web to generate keys. These settings are
automatically retrieved from EKMF Web, once the connection to the EKMF Web
server has been configured. Use option \fB\-\-refresh\-settings\fP to refresh
the settings, when they have changed in EKMF Web.
.
.IP "\(bu" 2
The secure \fBidentity key\fP used to identify the zkey client with EKMF Web,
and to cryptographically sign requests sent to EKMF Web. The identity key
is a secure key, and is automatically generated once the connection to the
EKMF Web server has been configured. Use option \fB\-\-gen\-identity\-key\fP to
re-generate the identity key, if needed. You must re-generate a
registration certificate with the newly generated identity key and re-register
this zkey client with the EKMF Web server.
.
.IP "\(bu" 2
The \fBregistration certificate\fP to register the zkey client with EKMF Web.
The registration certificate is an X.509 certificate generated with the secure
identity key. Use option \fB\-\-gen\-csr\fP to generate a \fBcertificate signing
request\fP (CSR) with the identity key. You pass this CSR to a certificate
authority (CA) to have it issue a CA signed certificate for the EKMF Web
plugin. Alternatively, use option \fB\-\-gen\-self\-signed\-cert\fP to generate
a \fBself signed certificate\fP with the identity key for the EKMF Web plugin.
Use options \fB\-\-cert\-subject\fP and \fB\-\-cert\-extensions\fP to specify
the certificate subject name and extensions (if any). To renew an existing
certificate, use option \fB\-\-renew\-cert\fP. The subject name and extensions
are then read from the certificate that is to be renewed.
.
.IP "\(bu" 2
\fBRegister\fP the zkey client with EKMF Web. Use option \fB\-\-register\fP to
register the zkey client using the \fBregistration certificate\fP from the
previous step. An identity key is generated in EKMF Web using the public
key from the certificate. You may also need to use option
\fB\-\-label\-tags\fP to specify the label tags for creating the identity key
in EKMF Web. Use command \fBzkey kms info\fP to find out which label tags the
identity key template uses.
.RE
.
.SS "Re-encipher the secure identity key"
.
Use the \fBzkey kms reencipher\fP command to re-encipher the secure identity
key of the EKMF Web plugin with a new master key.
The secure identity key must be re-enciphered when the \fBAPKA master key\fP
of the CCA cryptographic adapter changes.
.PP
See the man page of \fBzkey\fP for a description of the the \fBzkey kms
reencipher\fP command.
.PP
\fBNote:\fP The \fBzkey kms reencipher\fP command does \fBnot\fP re-encipher
secure keys that have been generated by or have been imported from EKMF Web and
are now stored in the secure key repository. Use the regular \fBzkey
reencipher\fP command to re-encipher those secure keys.
.
.SS "Generating secure AES keys with EKMF Web"
.
Use the \fBzkey generate\fP command to generate secure AES keys in EKMF Web and
import the newly generated key into the secure key repository. When the zkey
repository is bound to the EKMF Web plugin, then the \fBzkey generate\fP command
always generates the keys in EKMF Web, except when the \fB\-\-local\fP
option is specified.
.PP
Keys generated in EKMF Web are always of type \fBCCA\-AESCIPHER\fP. The
cryptographic size of the keys depend on the underlying EKMF Web template.
Use \fBzkey kms info\fP to display the names of the key templates configured.
If option \fB\-\-key\-bits\fP is specified, it must match the key size in the
template.
.PP
You may need to use option \fB\-\-label\-tags\fP to specify the label tags
for creating keys in EKMF Web. Use command \fBzkey kms info\fP to find out
which label tags the configured key template uses.
.PP
Keys generated with EKMF Web are bound to EKMF Web, and also inherit the APQN
association from the EKMF Web plugin. You cannot associate different APQNs to
a key that is bound to EKMF Web. Other additional information can be associated
with a secure key as usual, using the \fB\-\-description\fP, \fB\-\-volumes\fP,
\fB\-\-volume\-type\fP, or the \fB\-\-sector\-size\fP options. This associated
information is also stored in EKMF Web with the key.
.
.SS "Remove secure keys bound to EKMF Web from the key repository"
.
Use the \fBzkey remove\fP command to remove an existing secure key from the
secure key repository. If the key is bound to EKMF Web, then you can also
change the state of the key in EKMF Web, while removing it. Use option
\fB\-\-state\fP to specify the new state of the key in EKMF Web. If no state is
specified, the key remains unchanged in EKMF Web, but is removed from the local
secure key repository only.
.
.SS "Change secure keys bound to EKMF Web"
.
Use the \fBzkey change\fP command to change the description, the associated
volumes, the sector size, and the volume type of a secure key contained in the
secure key repository. If the key is bound to EKMF Web, then the changed
information is also updated for the key in EKMF Web.
.PP
You cannot change the associated cryptographic adapters (APQNs) of a key that
is bound to EKMF Web, because it inherits the APQN association from the EKMF
Web plugin. To change the APQNs associated with the EKMF Web plugin, use the
\fBzkey kms configure\fP command with the \fB--apqns\fP option. This also
changes the APQN associations of all secure keys in the secure key repository,
that are bound to the EKMF Web plugin.
.
.SS "Rename secure keys bound to EKMF Web"
.
Use the \fBzkey rename\fP command to rename an existing secure key in the
secure key repository. If the key is bound to EKMF Web, then the new name
is also updated for the key in EKMF Web. Note that the key label as it
is known in EKMF Web cannot be changed. Only the associated zkey name is
updated.
.
.SS "List secure keys managed by EKMF Web"
.
Use the \fBzkey kms list\fP command to display eligible secure keys managed by
EKMF Web. You can filter the displayed list by key label, key name, associated
volumes, and volume type. Refer to the man page of \fBzkey\fP for the details
on these filter options.
.PP
Use option \fB\-\-states\fP to filter the list by the key state in EKMF Web.
You can specify multiple states, separated by comma. If this option is omitted,
then only keys in \fBACTIVE\fP state are displayed.
.PP
By default, only keys are displayed, which this zkey client is allowed to use.
Only keys where the export control options include the identity key of this zkey
client as allowed exporting key can be used by this zkey client.
Specify option \fB\-\-all\fP to also list keys that this zkey client is
not allowed to use. The EKMF Web operator can change the export control options
of a key to allow a certain zkey identity key to export the key.
.
.SS "Import secure keys managed by EKMF Web into the repository"
.
Use the \fBzkey kms import\fP command to import secure keys managed by EKMF Web
into the secure key repository. You can filter the list of keys to be imported
by key label, key name, associated volumes, and volume type. Refer to the man
page of \fBzkey\fP for the details on these filter options.
.PP
Only keys are imported, which this zkey client is allowed to use. Only keys
where the export control options include the identity key of this zkey
client as allowed exporting key can be used by this zkey client. The EKMF Web
operator can change the export control options of a key, to allow a certain
zkey identity key to export the key.
.
.SS "Refresh secure keys bound to EKMF Web"
.
Use the \fBzkey kms refresh\fP command to refresh secure keys that are bound to
EKMF Web. You can filter the list of keys to be refreshed by name, associated
volumes, volume type, and key type. Refreshing a key updates the secure key by
re-importing it from EKMF Web. Use option \fB\-\-refresh\-properties\fP to also
update the associated information, such as the textual description, associated
volumes, volume type, and sector size, with the information stored with the key
in EKMF Web. Refer to the man page of \fBzkey\fP for the details on the \fBzkey
kms refresh\fP command.
.PP
The \fBzkey kms refresh\fP command can also help if the secure keys have not
been re-enciphered properly after a CCA master key change, and thus became
invalid. By refreshing the keys using the \fBzkey kms refresh\fP command, the
secure key is re-imported under the current CCA master key. So this command
could also be used as an alternative to the \fBzkey reencipher\fP command for
keys that are bound to EKMF Web.
.
.
.
.SH OPTIONS
This section describes the EKMF Web plugin specific options of the \fBzkey\fP
commands. Refer to the \fBzkey\fP man page for the remaining, non EKMF Web
plugin specific options.
.
.SS "Options for the zkey kms configure command"
.TP
.BR \-u ", " \-\-ekmfweb\-url\~\fIurl\fP
Specifies the URL of the EKMF Web server. The URL should start with
\fBhttps://\fP, and may contain a port number separated by a colon. If no
port number is specified, 443 is used for HTTPS.
.TP
.BR \-b ", " \-\-tls\-ca\-bundle\~\fIca\-bundle\fP
Specifies the CA bundle PEM file or directory containing the CA certificates
used to verify the EKMF Web server certificate during TLS handshake. If this
specifies a directory path, then this directory must have been prepared
with OpenSSL's \fBc_rehash\fP utility. Default are the system CA certificates.
.TP
.BR \-\-tls\-client\-cert\~\fIpem\-file\fP
Specifies the PEM file containing the client's TLS certificate for use with
TLS client authentication.
.TP
.BR \-\-tls\-client\-key\~\fIpem\-file\fP
Specifies the PEM file containing the client's private key for use with TLS
client authentication.
.TP
.BR \-\-tls\-client\-key\-passphrase\~\fIpassphrase\fP
If the PEM file is passphrase protected, this option specifies the passphrase
to unlock the PEM file that is specified with option \fB\-\-tls\-client\-key\fP.
.TP
.BR \-\-tls\-pin\-server\-pubkey
Pin the EKMF Web server's public key to verify on every connection that the
public key of the EKMF Web server's certificate is the same that was used when
the connection to the EKMF Web server was configured. This option can only be
used with CA signed EKMF Web server certificates.
.TP
.BR \-\-tls\-trust\-server\-cert
Trust the EKMF Web server's certificate even if it is a self signed
certificate, or could not be verified due to other reasons. This option can be
used instead of option \fB\-\-tls\-pin\-server\-pubkey\fP with self signed
EKMF Web server certificates.
.TP
.BR \-\-tls\-dont\-verify\-server\-cert
Do not verify the authenticity of the EKMF Web server's certificate. For self
signed EKMF Web server certificates, this is the default. Use option
\fB\-\-tls\-pin\-server\-cert\fP to ensure the self signed certificate's
authenticity explicitly. CA signed EKMF Web server certificates are verified by
default. This option disables the verification.
.TP
.BR \-\-tls\-verify\-hostname
Verify that the EKMF Web server certificate's \fBCommon Name\fP field or a
\fBSubject Alternate Name\fP field matches the host name used to connect to the
EKMF Web server.
.TP
.BR \-R ", " \-\-refresh\-settings
Refresh the EKMF Web server settings. This is automatically performed when the
connection to the EKMF Web server is (re-)configured. Use this option when the
settings of the already configured EKMF Web server have changed.
.TP
.BR \-i ", " \-\-gen\-identity\-key
Generate an identity key for the EKMF Web plugin. An identity key is
automatically generated when the EKMF Web server connection has been configured.
Use this option to generate a new identity key. You need to re-generate a
registration certificate with the newly generated identity key, and re-register
this zkey client with the EKMF Web server.
.TP
.BR \-c ", " \-\-gen\-csr\~\fIcsr\-pem\-file\fP
Generate a certificate signing request (CSR) with the identity key and store it
into the specified PEM file. You pass this CSR to a certificate authority (CA)
to have it issue a CA signed certificate for the EKMF Web plugin. You need to
register the certificate with EKMF Web before you can access EKMF Web.
.TP
.BR \-C ", " \-\-gen\-self\-signed\-cert\~\fIcert\-pem\-file\fP
Generate a self signed certificate with the identity key and store it into the
specified PEM file. You need to register the certificate with EKMF Web before
you can access EKMF Web.
.TP
.BR \-s ", " \-\-cert\-subject\~\fIsubject\-rdns\fP
Specifies the subject name for generating a certificate signing request (CSR)
or self signed certificate, in the form
\fB<type>=<value>(;<type>=<value>)*[;]\fP with types recognized by OpenSSL.
.TP
.BR \-s ", " \-\-cert\-extensions\~\fIextensions\fP
Specifies the certificate extensions for generating a certificate signing
request (CSR) or self signed certificate, in the form
\fB<name>=[critical,]<value(s)>(;<name>=[critical,]<value(s)>)*[;]\fP
with extension names and values recognized by OpenSSL.
.TP
.BR \-N ", " \-\-renew\-cert\~\fIcert\-pem\-file\fP
Specifies an existing PEM file containing the certificate to be renewed. The
certificate's subject name and extensions are used to generate the certificate
signing request (CSR) or renewed self signed certificate.
.TP
.BR \-n ", " \-\-csr\-new\-header
Adds the word \fBNEW\fP to the PEM file header and footer lines on the
certificate signing request. Some software and some CAs need this.
.TP
.BR \-d ", " \-\-cert\-validity\-days\~\fIdays\fP
Specifies the number of days to certify the self signed certificate. The
default is 30 days.
.TP
.BR \-D ", " \-\-cert\-digest\~\fIdigest\fP
Specifies the digest algorithm to use when generating a certificate signing
request or self signed certificate. The default is determined by OpenSSL.
.TP
.BR \-r ", " \-\-register\~\fIcert\-file\fP
Register the zkey client with EKMF Web by generating an identity key in EKMF
Web using the certificate from the specified file. Supported certificate files
formats are \fB.pem\fP, \fB.crt\fP, \fB.cert\fP, \fB.cer\fP, and \fB.der\fP
(i.e. either base64 or DER encoded). If you want to register a self signed
certificate that you are about to generate using option
\fB\-\-gen\-self\-signed\-cert\fP, then specify the same certificate file
name here, and the generated certificate is registered right away.
.TP
.BR \-T ", " \-\-label\-tags\~\fIlabel\-tags\fP
Specifies the label tags for generating the identity key in EKMF Web when
registering the zkey client, in the form
\fB<tag>=<value>(,<tag>=<value>)*[,]\fP with tags as defined by the key
template. Use the \fBzkey kms info\fP command to display the key templates used
by zkey. For registration, the template for identity keys is used.
.
.SS "Options for the zkey generate command"
.
.TP
.BR \-T ", " \-\-label\-tags\~\fIlabel\-tags\fP
Specifies the label tags for generating a secure key in EKMF Web, in the form
\fB<tag>=<value>(,<tag>=<value>)*[,]\fP with tags as defined by the key
template. Use the \fBzkey kms info\fP command to display the key templates used
by zkey. For XTS type keys the two templates for \fBXTS-Key1\fP and
\fBXTS-Key2\fP are used. For non-XTS type keys, the template for \fBNon-XTS\fP
keys is used.
.
.SS "Options for the zkey remove command"
.
.TP
.BR \-s ", " \-\-state\~\fIstate\fP
Specifies the state to which to change the key in EKMF Web, after removing
the secure key from the local secure key repository. Possible states are
\fBDEACTIVATED\fP, \fBCOMPROMISED\fP, \fBDESTROYED\fP, and
\fBDESTROYED\-COMPROMISED\fP. If this option is not specified, the state of the
key in EKMF Web is not changed, but the key is removed from the local secure
key repository only.
.
.SS "Options for the zkey kms list command"
.
.TP
.BR \-s ", " \-\-states\~\fIstates\fP
Specifies the states of the keys that are to be listed. Multiple states can be
separated by comma. Possible states are \fBPRE\-ACTIVATION\fP, \fBACTIVE\fP,
\fBDEACTIVATED\fP, \fBCOMPROMISED\fP, \fBDESTROYED\fP, and
\fBDESTROYED\-COMPROMISED\fP. If this option is not specified, only keys in
state \fBACTIVE\fP are listed.
.TP
.BR \-a ", " \-\-all
List all keys that can be used for volume encryption. If this option is not
specified, then only volume encryption keys that are allowed to be exported by
EKMF Web using the identity key of this zkey client are listed.
.
.
.
.SH EXAMPLES
.TP
.B zkey kms plugins
Lists available key manamgement system plugins.
.TP
.B zkey kms bind EKMFWeb
Binds the EKMF Web plugin to the current secure key repository.
.TP
.B zkey kms configure \-\-apqns 03.004c
Configures the APQN '03.004c' to be associated with the EKMF Web plugin.
.TP
.B zkey kms configure \-\-ekmfweb\-url https://my.ekmfweb.server
Configures the connection to the EKMF Web server on 'my.ekmfweb.server'.
.TP
.B zkey kms configure \-\-ekmfweb\-url https://my.ekmfweb.server \-\-tls\-pin\-server\-pubkey \-\-tls\-verify\-hostname
Configures the connection to the EKMF Web server on 'my.ekmfweb.server' and
pins the server's public key from the server's TSL certificate as well as
enables verification of the host nmae to match the server's Common Name in the
certificate.
.TP
.B zkey kms configure \-\-gen\-csr csr.pem \-\-cert\-subject \(dqCN=my.zkey.client;OU=Example;C=US\(dq
Generates a certificate signing request with the identity key and the specified
subject name and stores it in file 'csr.pem'.
.TP
.B zkey kms configure \-\-gen\-csr csr.pem \-\-renew\-cert cert.pem
Generates a certificate signing request with the identity key to renew the
existing certificate in file cert.pem and stores it in file 'csr.pem'.
.TP
.B zkey kms configure \-\-gen\-self\-signed\-cert cert.pem \-\-cert\-subject \(dqCN=my.zkey.client;OU=Example;C=US\(dq \-\-cert\-validity\-days 50
Generates a self signed certificate with the identity key and the specified
subject name and a validity of 50 days, and stores it in file 'cert.pem'.
.TP
.B zkey kms configure \-\-gen\-self\-signed\-cert cert.pem \-\-cert\-subject \(dqCN=my.zkey.client;OU=Example;C=US\(dq \-\-cert\-extensions \(dqkeyUsage=critical,digitalSignature,keyAgreement\(dq
Generates a self signed certificate with the identity key and the specified
subject name and a certificate extension to limit the key usage, and stores it
in file 'cert.pem'.
.TP
.B zkey kms configure \-\-register cert.pem
Registers the zkey client with EKMF Web using the certifcate in file 'cert.pem'.
.TP
.B zkey kms configure \-\-register cert.pem \-\-label\-tags \(dqENV=TEST,APP=LINUX\(dq
Registers the zkey client with EKMF Web using the certifcate in file 'cert.pem'
and the label tags 'ENV=TEST' and 'APP=LINUX' for the identity key.
.TP
.B zkey kms info
Displays information about the EKMF Web plugin and its configuration.
.TP
.B zkey kms reencipher --staged
Re-enciphers the EKMF Plugin's identity key with a new CCA master key in staged
mode
.TP
.B zkey generate \-\-name seckey \-\-volumes /dev/dasdc1:encvol \-\-label\-tags \(dqENV=TEST,APP=LINUX\(dq
Generates a secure AES key in EKMF Web using the label tags 'ENV=TEST' and
'APP=LINUX' and stores it in the secure key repository using the name 'seckey'
and associates it with block device '/dev/dasdc1' and device-mapper name
'encvol'.
.TP
.B zkey generate \-\-name seckey \-\-xts \-\-volumes /dev/dasdc1:encvol \-\-volume-type luks2 \-\-label\-tags \(dqENV=TEST,APP=LINUX\(dq
Generates a secure AES key for the XTS cipher mode in EKMF Web using the label
tags 'ENV=TEST' and 'APP=LINUX' and stores it in the secure key repository
using the name 'seckey' and associates it with block device '/dev/dasdc1' and
device-mapper name 'encvol', and a volume type of luks2.
.TP
.B zkey remove \-\-name seckey \-\-state DEACTIVATED
Removes secure key 'seckey' from the repository and sets the state of the key
to 'DEACTIVATED' in EKMF Web.
.TP
.B zkey kms list
Displays eligible secure keys managed by EKMF Web which this zkey client is
allowed to use and are in state 'ACTIVE'
.TP
.B zkey kms list \-\-states ACTIVE,DEACTIVATED
Displays eligible secure keys managed by EKMF Web which this zkey client is
allowed to use and are in state 'ACTIVE' or 'DEACTIVATED'
.TP
.B zkey kms list \-\-all
Displays eligible secure keys managed by EKMF Web, regardless if this zkey
client is allowed to use it or not.
.TP
.B zkey kms list \-\-label \(dq*LUKS2*\(dq
Displays eligible secure keys managed by EKMF Web where the label name in EKMF
Web contains the work 'LUKS2'.
.TP
.B zkey kms import \-\-name seckey
Imports the secure key managed by EKMF Web with a zkey name of 'seckey'.
.TP
.B zkey kms import \-\-volume\-type LUKS2
Imports secure keys managed by EKMF Web that are associated with volumes of
volume type LUKS2.
.TP
.B zkey kms refresh \-\-name \(dqsec*\(dq
Refreshes secure keys from EKMF Web where the name starts with 'sec'.
.TP
.B zkey kms refresh \-\-name seckey \-\-refresh\-properties
Refreshes the secure key with the name 'seckey' from EKMF Web and also refreshs
the key properties.

5745
zkey/ekmfweb/zkey-ekmfweb.c Normal file

File diff suppressed because it is too large Load Diff

108
zkey/ekmfweb/zkey-ekmfweb.h Normal file
View File

@@ -0,0 +1,108 @@
/*
* zkey-ekmfweb - EKMFWeb zkey KMS plugin
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef ZKEY_EKMFWEB_H
#define ZKEY_EKMFWEB_H
#include <stddef.h>
#include <stdbool.h>
#include <sys/stat.h>
#include "ekmfweb/ekmfweb.h"
struct plugin_handle {
const char *config_path;
mode_t config_path_mode;
gid_t config_path_owner;
struct properties *properties;
bool apqns_configured;
bool connection_configured;
bool settings_retrieved;
bool templates_retrieved;
bool identity_key_generated;
bool registered;
bool config_complete;
struct ekmf_ext_lib ext_lib;
struct ekmf_cca_lib cca;
struct ekmf_config ekmf_config;
CURL *curl_handle;
char error_msg[1024];
bool verbose;
};
#define EKMFWEB_CONFIG_FILE "ekmfweb.conf"
#define EKMFWEB_CONFIG_SERVER_CERT_FILE "server-cert.pem"
#define EKMFWEB_CONFIG_SERVER_PUBKEY_FILE "server-pubkey.pem"
#define EKMFWEB_CONFIG_LOGIN_TOKEN_FILE "login.token"
#define EKMFWEB_CONFIG_EKMFWEB_PUBKEY_FILE "ekmfweb-pubkey.pem"
#define EKMFWEB_CONFIG_IDENTITY_KEY_FILE "identity-key.skey"
#define EKMFWEB_CONFIG_IDENTITY_KEY_REENC_FILE "identity-key.reenc"
#define EKMFWEB_CONFIG_APQNS "apqns"
#define EKMFWEB_CONFIG_URL "url"
#define EKMFWEB_CONFIG_CA_BUNDLE "ca-bundle"
#define EKMFWEB_CONFIG_CLIENT_CERT "client-cert"
#define EKMFWEB_CONFIG_CLIENT_KEY "client-key"
#define EKMFWEB_CONFIG_CLIENT_KEY_PASSPHRASE "client-key-passphrase"
#define EKMFWEB_CONFIG_SERVER_CERT "server-cert"
#define EKMFWEB_CONFIG_SERVER_PUBKEY "server-pubkey"
#define EKMFWEB_CONFIG_VERIFY_SERVER_CERT "verify-server-cert"
#define EKMFWEB_CONFIG_VERIFY_HOSTNAME "verify-hostname"
#define EKMFWEB_CONFIG_LOGIN_TOKEN "login-token"
#define EKMFWEB_CONFIG_PASSCODE_URL "passcode-url"
#define EKMFWEB_CONFIG_EKMFWEB_PUBKEY "ekmfweb-pubkey"
#define EKMFWEB_CONFIG_TEMPLATE_XTS1 "template-xts1"
#define EKMFWEB_CONFIG_TEMPLATE_XTS2 "template-xts2"
#define EKMFWEB_CONFIG_TEMPLATE_NONXTS "template-nonxts"
#define EKMFWEB_CONFIG_TEMPLATE_IDENTITY "template-identity"
#define EKMFWEB_CONFIG_TEMPLATE_XTS1_LABEL "template-xts1-label"
#define EKMFWEB_CONFIG_TEMPLATE_XTS2_LABEL "template-xts2-label"
#define EKMFWEB_CONFIG_TEMPLATE_NONXTS_LABEL "template-nonxts-label"
#define EKMFWEB_CONFIG_TEMPLATE_IDENTITY_LABEL "template-identity-label"
#define EKMFWEB_CONFIG_TEMPLATE_XTS1_ID "template-xts1-id"
#define EKMFWEB_CONFIG_TEMPLATE_XTS2_ID "template-xts2-id"
#define EKMFWEB_CONFIG_TEMPLATE_NONXTS_ID "template-nonxts-id"
#define EKMFWEB_CONFIG_TEMPLATE_IDENTITY_ID "template-identity-id"
#define EKMFWEB_CONFIG_IDENTITY_KEY "identity-key"
#define EKMFWEB_CONFIG_IDENTITY_KEY_ALGORITHM "identity-key-algorithm"
#define EKMFWEB_CONFIG_IDENTITY_KEY_PARAMS "identity-key-params"
#define EKMFWEB_CONFIG_IDENTITY_KEY_REENC "identity-key-reenc"
#define EKMFWEB_CONFIG_IDENTITY_KEY_LABEL "identity-key-label"
#define EKMFWEB_CONFIG_IDENTITY_KEY_ID "identity-key-id"
#define EKMFWEB_CONFIG_SESSION_KEY_CURVE "session-key-curve"
#ifdef EKMFWEB_SUPPORTS_RSA_DIGESTS_AND_PSS_SIGNATURES
#define EKMFWEB_CONFIG_SESSION_RSA_SIGN_DIGEST "session-rsa-sign-digest"
#define EKMFWEB_CONFIG_SESSION_RSA_SIGN_PSS "session-rsa-sign-pss"
#endif
#define EKMFWEB_PASSCODE_URL "/administration/passcode"
#define EKMFWEB_TEMPLATE_STATE_ACTIVE "ACTIVE"
#define EKMFWEB_TEMPLATE_STATE_HISTORY "HISTORY"
#define EKMFWEB_KEYSTORE_TYPE_PERV_ENCR "PERVASIVE_ENCRYPTION"
#define EKMFWEB_KEYSTORE_TYPE_IDENTITY "IDENTITY"
#define EKMFWEB_KEY_ALGORITHM_AES "AES"
#define EKMFWEB_KEY_ALGORITHM_ECC "ECC"
#define EKMFWEB_KEY_ALGORITHM_RSA "RSA"
#define EKMFWEB_KEY_TYPE_CIPHER "CIPHER"
#define EKMFWEB_KEY_STATE_PRE_ACTIVATION "PRE-ACTIVATION"
#define EKMFWEB_KEY_STATE_ACTIVE "ACTIVE"
#define EKMFWEB_KEY_STATE_DEACTIVATED "DEACTIVATED"
#define EKMFWEB_KEY_STATE_COMPROMISED "COMPROMISED"
#define EKMFWEB_KEY_STATE_DESTROYED "DESTROYED"
#define EKMFWEB_KEY_STATE_DESTROYED_COMPROMISED "DESTROYED-COMPROMISED"
#define EKMFWEB_CURVE_PRIME "PRIME_CURVE"
#define EKMFWEB_CURVE_BAINPOOL "BRAINPOOL_CURVE"
#define EKMFWEB_SEQNO_TAG "seqno"
#define DEFAULT_IDENTITY_KEY_PUBLIC_EXPONENT 65537
#define CCA_LIBRARY_NAME "libcsulcca.so"
#define CCA_WEB_PAGE "http://www.ibm.com/security/cryptocards"
#endif

View File

@@ -0,0 +1,5 @@
ZKEY_EKMFWEB_1.0 {
global:
kms_get_functions;
local: *;
};

View File

@@ -182,8 +182,9 @@ int load_ep11_library(struct ep11_lib *ep11, bool verbose)
*
* @returns 0 on success, a negative errno in case of errors
*/
int get_ep11_target_for_apqn(struct ep11_lib *ep11, int card, int domain,
target_t *target, bool verbose)
int get_ep11_target_for_apqn(struct ep11_lib *ep11, unsigned int card,
unsigned int domain, target_t *target,
bool verbose)
{
ep11_target_t *target_list;
struct XCP_Module module;
@@ -248,12 +249,12 @@ struct find_mkvp_info {
u8 mkvp[MKVP_LENGTH];
unsigned int flags;
bool found;
int card;
int domain;
unsigned int card;
unsigned int domain;
bool verbose;
};
static int find_mkvp(int card, int domain, void *handler_data)
static int find_mkvp(unsigned int card, unsigned int domain, void *handler_data)
{
struct find_mkvp_info *info = (struct find_mkvp_info *)handler_data;
struct mk_info mk_info;
@@ -312,8 +313,8 @@ static int find_mkvp(int card, int domain, void *handler_data)
*/
int select_ep11_apqn_by_mkvp(struct ep11_lib *ep11, u8 *mkvp,
const char *apqns, unsigned int flags,
target_t *target, int *card, int *domain,
bool verbose)
target_t *target, unsigned int *card,
unsigned int *domain, bool verbose)
{
struct find_mkvp_info info;
int rc;
@@ -323,7 +324,7 @@ int select_ep11_apqn_by_mkvp(struct ep11_lib *ep11, u8 *mkvp,
pr_verbose(verbose, "Select mkvp %s in APQNs %s for the EP11 host "
"library", printable_mkvp(CARD_TYPE_EP11, mkvp),
apqns == 0 ? "ANY" : apqns);
apqns == NULL ? "ANY" : apqns);
memcpy(info.mkvp, mkvp, sizeof(info.mkvp));
info.flags = flags;
@@ -369,8 +370,9 @@ int select_ep11_apqn_by_mkvp(struct ep11_lib *ep11, u8 *mkvp,
*
* @returns 0 on success, a negative errno in case of errors
*/
static int ep11_adm_reencrypt(struct ep11_lib *ep11, target_t target, int card,
int domain, struct ep11keytoken *ep11key,
static int ep11_adm_reencrypt(struct ep11_lib *ep11, target_t target,
unsigned int card, unsigned int domain,
struct ep11keytoken *ep11key,
unsigned int ep11key_size, bool verbose)
{
CK_BYTE resp[MAX_BLOBSIZE];
@@ -406,8 +408,8 @@ static int ep11_adm_reencrypt(struct ep11_lib *ep11, target_t target, int card,
return -EIO;
}
rv = ep11->dll_m_admin(resp, &resp_len, NULL, 0, req, req_len, NULL, 0,
target);
rv = ep11->dll_m_admin(resp, &resp_len, NULL, NULL, req, req_len, NULL,
0, target);
if (rv != CKR_OK || resp_len == 0) {
pr_verbose(verbose, "Command XCP_ADM_REENCRYPT failed. "
"rc = 0x%lx, resp_len = %ld", rv, resp_len);
@@ -461,8 +463,8 @@ static int ep11_adm_reencrypt(struct ep11_lib *ep11, target_t target, int card,
*
* @returns 0 on success, a negative errno in case of errors
*/
int reencipher_ep11_key(struct ep11_lib *ep11, target_t target, int card,
int domain, u8 *secure_key,
int reencipher_ep11_key(struct ep11_lib *ep11, target_t target,
unsigned int card, unsigned int domain, u8 *secure_key,
unsigned int secure_key_size, bool verbose)
{
struct ep11keytoken *ep11key = (struct ep11keytoken *)secure_key;

View File

@@ -158,8 +158,9 @@ struct ep11_lib {
int load_ep11_library(struct ep11_lib *ep11, bool verbose);
int get_ep11_target_for_apqn(struct ep11_lib *ep11, int card, int domain,
target_t *target, bool verbose);
int get_ep11_target_for_apqn(struct ep11_lib *ep11, unsigned int card,
unsigned int domain, target_t *target,
bool verbose);
void free_ep11_target_for_apqn(struct ep11_lib *ep11, target_t target);
@@ -168,11 +169,11 @@ void free_ep11_target_for_apqn(struct ep11_lib *ep11, target_t target);
int select_ep11_apqn_by_mkvp(struct ep11_lib *ep11, u8 *mkvp,
const char *apqns, unsigned int flags,
target_t *target, int *card, int *domain,
bool verbose);
target_t *target, unsigned int *card,
unsigned int *domain, bool verbose);
int reencipher_ep11_key(struct ep11_lib *ep11, target_t target, int card,
int domain, u8 *secure_key,
int reencipher_ep11_key(struct ep11_lib *ep11, target_t target,
unsigned int card, unsigned int domain, u8 *secure_key,
unsigned int secure_key_size, bool verbose);
#endif

Some files were not shown because too many files have changed in this diff Show More