Compare commits

...

268 Commits

Author SHA1 Message Date
Jan Höppner fe187eb3d3 New release s390-tools-2.17.0
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 15:18:51 +02:00
Jan Höppner 4a8afd4ed6 README.md: Add lshwc description
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 15:18:51 +02:00
Jan Höppner 74e6ebe1df libdasd: Free memory for previously used sysfs path
util_path_sysfs() allocates memory for the created path which must be
freed by the user.

Fixes: 8023a72b11 ("libdasd: Provide function to read ese sysfs attribute")
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 14:02:13 +02:00
Ingo Franzki ec83da3a39 zkey-kmip: Add man page for the KMIP plugin
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 14:02:13 +02:00
Ingo Franzki c11b0cdcaa zkey-kmip: List and import keys managed by KMIP
List (find) and import a key that exists in a KMIP server into the zkey
repository. Retrieve the key attributes of a key stored in a KMIP server,
and extract the zkey properties from it.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 14:02:13 +02:00
Ingo Franzki 4f3cba406e zkey-kmip: Remove keys and optionally set its state in KMIP
When a key is removed from the zkey repository, it is usually not removed
from the KMIP server. Optionally, the state of a KMIP key can be changed
when it is removed by zkey.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 14:02:13 +02:00
Ingo Franzki c55ac2c016 zkey-kmip: Set properties of an existing key
Change the attributes of a key at the KMIP server when the properties
of a key are changed in zkey.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 14:01:49 +02:00
Ingo Franzki 4eab80ef44 zkey-kmip: Generate keys in the KMIP server and retrieve them
Allow to generate a new AES key at the KMIP server, and retrieved it.
Keys are always retrieved in wrapped format, wrapped by the public RSA
wrapping key used by the KMIP plugin. The KMIP plugin can then unwrap
the retrieved key with its secure private RSA key, and can then import
the retrieved AES key into the zkey repository as secure key. That way,
the retrieved AES key is never in clear, once it leaves the KMIP server.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki 41ddd35bc1 zkey-kmip: Re-encipher identity and wrapping keys on MK change
When the master keys of the configured APQNs are changed, the secure
identity key as well as the secure wrapping key must be re-enciphered.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki bdc44cafb6 zkey-kmip: Generate and register wrapping key
Keys retrieved from a KMIP server are wrapped with an RSA key. The
RSA wrapping key is a secure key generated by the KMIP plugin. The
public RSA key is registered at the KMIP server, and the KMIP server
can then wrap the keys with it. The KMIP plugin can unwrap the retrieved
key with the private RSA key and import it as secure key into the zkey
repository.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki 46583b4db6 zkey-kmip: Configure connection to KMIP server
Configure a connection to a KMIP server, establish trust between
server and client, query the KMIP server and verify if it supports
the required KMIP operations. Also, the profile to be used with this
KMIP server is tried to matched. If not specified in the profile,
the KMIP protocol version to be used is discovered.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki a2359dbe5f zkey-kmip: Add support for KMIP server profiles
KMIP server profiles (not to be confused with profiles defined by
the KMIP standard) define how the KMIP plugin talks to the KMIP
server. Profiles can be used to configure certain KMIP usages for
certain KMIP servers.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki 52b6e57743 zkey: Allow comments and empty lines in properties files
Lines with '#' as first character are treated as comments, and are
skipped. Empty lines are also skipped.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki b1997c7aac zkey-kmip: Generate CSR or self signed certificate
For the client certificate to authenticate with the KMIP server,
a certificate signing request (CSR) or self signed certificate can be
generated. The generated CSR or certificate is signed with the secure
identity key of the KMIP plugin.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki c56aea0fa9 zkey-kmip: Generate an secure identity key
Authentication with KMIP servers is based on TLS client authentication.
To establish trust between zkey and the KMIP server, a client certificate
must be registered with the KMIP server before a client can communicate
with it.

The signature key of the client's certificate is a secure key created by
zkey. It can either be an RSA or an ECC key, using either CCA or EP11
type crypto adapters configured with the KMIP plugin.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki e24629b977 zkey-kmip: Configure APQNs
The KMIP plugin supports CCA and EP11 APQNs, but only it can only be
configured with one type. Once configured with one type of APQN, it accepts
only APQNs of the same type.

It supports key types matching to the APQn type it is configured with.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki 268dcebe23 zkey-kmip: Add new zkey KMS plugin for KMIP
Add support to integrate the external key management systems based
on the KMIP protocol (KMIP: OASIS Key Management Interoperability
Protocol) into zkey by providing a zkey KMS plugin for KMIP. The
plugin communicates with KMIP servers using libkmipclient over a
TLS or HTTPS connection.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki 030c0054b1 zkey-ekmfweb: Move some functions used by multiple KMS plugins to common code
Some functions are likely to be used by multiple plugins. Move them
into zkey common code (plugin-utils.c), this module is then linked
into the plugins.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki 154914ee7a zkey: Allow KMS plugin to import a key of a specific type
KMS plugins that support multiple key types need to know which
key type to produce with the kms_import_key() function. Extend
the plugin API to allow a plugin to provide a kms_import_key2()
function, that accepts the key type as additional parameter.

Existing plugins do not need to be changed, as the old function
kms_import_key() still exists, and is still used when the plugin
does not provide a kms_import_key2() function.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki 56fecf1832 libkmipclient: Add KMIP client shared library
libkmipclient is a shared library that provides an KMIP client to
communicate with an KMIP server. KMIP stands for Key Management
Interoperability Protocol, and is an extensible communication protocol
that defines message formats for the manipulation of cryptographic
keys on a key management server.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki 081499f355 zkey-ekmfweb: Fix deprecation warnings with OpenSSL 3.0
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki 26c34a49b1 libekmfweb: Make use of the new libseckey
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki e70cde2c5d libseckey: Add a secure key library
The libseckey is a secure key library to perform secure key operations
with OpenSSL. It provides a framework to create OpenSSL PKEYs with a
secure key attached. Such a PKEY contains the public key parts in clear,
but the private key as secure key blob. Only the private key operations
are actually performed with the secure key, public key operations are
performed in software by OpenSSL. It supports CCA and EP11 secure
keys for RSA and ECC crypto operations.

Because many PKEY method related functions are deprecated since OpenSSL
3.0, two versions of the OpenSSL secure key support are needed. One (using
a PKEY method override) for OpenSSL 1.1.1, and another one (using an own
OpenSSL provider) for OpenSSL 3.0 and later. The desired implementation is
selected automatically at compile time, using OpenSSL version defines. The
interface of both implementations is the same, so a user does not need to
care which one is used.

Reviewed-by: Juergen Christ <jchrist@linux.ibm.com>
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Alexander Egorenkov fff83fc116 hsavmcore: Let make create list of object files instead of hard-coding it
Use idiomatic make constructs.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Alexander Egorenkov 5a7d2a58c8 hsavmcore: Fix fuse dependency checking
all target should not depend on check_dep but only objects which
use fuse header.

This fixes issues with parallel build of hsavmcore.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reported-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>
2021-07-07 13:53:04 +02:00
Alexander Egorenkov 89d25559e0 hsavmcore: Disable systemd support during build if systemd header not found
Check for systemd C header and disable systemd support even if HAVE_SYSTEMD
make variable is set to 1.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:49:57 +02:00
Alexander Egorenkov 49901079d4 common.mak: Introduce user-defined function check_header_prereq()
The new user-defined function allows to check for C headers in
make's conditional statements.

Example:

ifeq ($(call check_header_prereq,"systemd/sd-daemon.h"),yes)
  $(warning "systemd support enabled")
else
  $(warning "systemd support disabled")
endif

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:49:57 +02:00
Ingo Franzki 317384b5c9 libekmfweb: Ensure that libcurl supports the OpenSSL backend
The callback function used for CURLOPT_SSL_CTX_FUNCTION requires
that OpenSSL is used as SSL backend.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:57:06 +02:00
Marc Hartmayer 8db32a8cb9 genprotimg: add --(enable|disable)-pckmo flag
Add the genprotimg flags `--(enable|disable)-pckmo` flag to enable/disable the
support for PCKMO-encrypt-DEA/TDEA/AES/ECC-key functions.

Acked-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>
2021-07-05 13:57:06 +02:00
Marc Hartmayer 4cf73238fc genprotimg: allow PCKMO functions by default
Allow the PCKMO-encrypt-DEA/TDEA/AES/ECC-key functions to be used in a protected
virtualization guest by default.

Acked-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>
2021-07-05 13:57:06 +02:00
Marc Hartmayer 27120f2824 genprotimg: rename PV_CFLAG_NO_DECRYPTION to PV_PCF_NO_DECRYPTION
The new name reflects that it's a plaintext control flag. While at it, use a
left shift operation to calculate the value.

Acked-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>
2021-07-05 13:57:06 +02:00
Alexander Egorenkov 8f32a60c22 zipl: Use util_arch_hsa_maxsize() to compute address limit for kdump
The HSA size, which limits the address space in kdump case, is not constant
and depends on the underlying architecture.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:57:06 +02:00
Alexander Egorenkov 0fa2f9acf7 cpumf: Use helpers from util_arch
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:57:06 +02:00
Alexander Egorenkov 2ca7db75d3 libutil: Introduce util_arch module
The util_arch module is supposed to provide general information about
the underlying architecture of the machine in use.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:57:06 +02:00
Ingo Franzki 02aaff72fa zkey: Use secure_getenv() instead of getenv() for all environment variables
... to avoid vulnerabilities that could occur if set-user-ID or
set-group-ID programs accidentally trusted the environment.

zkey is usually NOT a set-user-ID or set-group-ID program, but its
safer to use secure_getenv() anyway.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:57:06 +02:00
Marc Hartmayer 8723dbce04 genprotimg: add OpenSSL 3.0 support
Add OpenSSL 3.0 support while still supporting OpenSSL 1.1.0 and newer. For this
set the OPENSSL_API_COMPAT user defined macro to OpenSSL 1.1.0 (see
https://www.openssl.org/docs/manmaster/man7/OPENSSL_API_COMPAT.html) so we don't
see any deprecation warnings when using OpenSSL 3.0. In addition, add an
compatibility layer for OpenSSL since some OpenSSL API functions were constified
with OpenSSL 3.0.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/112
Reviewed-by: Patrick Steuer <patrick.steuer@de.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:57:06 +02:00
Marc Hartmayer c5d566a4da genprotimg/crypto: use X509_get0_not(After|Before)
Use X509_get0_not(After|Before) since X509_get_notBefore() and
X509_get_notAfter() were deprecated in OpenSSL 1.1.0 (see
https://www.openssl.org/docs/man1.1.0/man3/X509_set1_notBefore.html).

Github-ID: https://github.com/ibm-s390-linux/s390-tools/issues/112
Reviewed-by: Patrick Steuer <patrick.steuer@de.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:57:06 +02:00
Marc Hartmayer d90344a2d5 genprotimg: check return value of BIO_reset
Add missing return value checks for BIO_reset. Unfortunately, the OpenSSL
documentation says:

"BIO_reset() normally returns 1 for success and 0 or -1 for failure. File BIOs
are an exception, they return 0 for success and -1 for failure."

Github-ID: https://github.com/ibm-s390-linux/s390-tools/issues/112
Reviewed-by: Patrick Steuer <patrick.steuer@de.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:57:06 +02:00
Marc Hartmayer 71a667fbf0 genprotimg: add missing return values
Fixes: 65b9fc442c ("genprotimg: introduce new tool for the creation of PV images")
Reviewed-by: Patrick Steuer <patrick.steuer@de.ibm.com>
Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:57:06 +02:00
Alexander Egorenkov d2611b472b gitignore: Ignore all example executables in libutil/
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:57:06 +02:00
Alexander Egorenkov 34482d67c0 libutil: Refactor and clean up Makefile
Use idiomatic make constructs.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:57:00 +02:00
Alexander Egorenkov b77523ab4d libutil: Fix typo in doxygen group of util_log
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:55:54 +02:00
Jan Höppner 802e5f6607 libutil: Remove /proc/mount related functions
The only user of util_proc_mnt_get_entry() so far was util_path_sysfs().
With the simplified version there is no user left. Remove
util_proc_mnt_get_entry() and related code.

Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:55:54 +02:00
Jan Höppner 5e5d49264f libutil: Simplify util_path_sysfs and helper functions
Using util_path_sysfs always leaves 5 bytes of memory unfreed as the
value for the sysfs mount point is stored in a static variable to avoid
multiple queries of /proc/mount.

$ valgrind ./util_path_example sysfs
==3629315== Memcheck, a memory error detector
==3629315== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3629315== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==3629315== Command: ./util_path_example sysfs
==3629315==
Path for    cpu: "/sys/devices/system/cpu"
Path for memory: "/sys/devices/system/memory"
==3629315==
==3629315== HEAP SUMMARY:
==3629315==     in use at exit: 5 bytes in 1 blocks
==3629315==   total heap usage: 22 allocs, 21 frees, 18,435 bytes allocated
==3629315==
==3629315== LEAK SUMMARY:
==3629315==    definitely lost: 0 bytes in 0 blocks
==3629315==    indirectly lost: 0 bytes in 0 blocks
==3629315==      possibly lost: 0 bytes in 0 blocks
==3629315==    still reachable: 5 bytes in 1 blocks
==3629315==         suppressed: 0 bytes in 0 blocks
==3629315== Rerun with --leak-check=full to see details of leaked memory
==3629315==
==3629315== For lists of detected and suppressed errors, rerun with: -s
==3629315== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

As per the Kernel rules for accessing sysfs information [1], searching
for the sysfs mount point is a waste of time and systems that don't have
sysfs mounted at /sys are considered broken.

With those things in mind, util_path_sysfs() and especially
sys_mount_point() can be simplified. sys_mount_point() will always
return '/sys' unless the environment variable SYSFS_ROOT is set.

With SYSFS_ROOT still being present, special container setups or test
case scenarios are still possible but might need to be modified if they
previously relied on util_path_sysfs() automatically finding the correct
sysfs mount point.

To make things more secure against malicious strings in SYSFS_ROOT,
secure_getenv() is being used and the ordering of creating the formatted
path string in util_path_sysfs() is changed slightly.

Furthermore, the static variable is removed as no complicated query of
the /proc fs is required anymore. Memory for the sysfs mount point value
is properly freed now at the end of util_path_sysfs().

[1] https://www.kernel.org/doc/html/latest/admin-guide/sysfs-rules.html
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:55:54 +02:00
Ingo Franzki 3e818c53b2 zconf/zcrypt: Fix sparse warnings
A compile with sparse (make C=1) shows a couple of warnings:
like:

  chzcrypt.c:36:3: warning: symbol 'l' was not declared.
  Should it be static?

  lszcrypt.c: In function 'show_device':
  lszcrypt.c:556:9: warning: 'card' may be used uninitialized
  [-Wmaybe-uninitialized]

Fix those warnings.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:55:54 +02:00
Ingo Franzki 9100d6f40e libutil/util_rec: Declare internal only functions static
A compile with sparse (make C=1) shows the following warnings:

  util_rec.c:211:6: warning: symbol 'rec_print_wide' was not declared.
  Should it be static?
  util_rec.c:383:6: warning: symbol 'rec_print_csv_hdr' was not declared.
  Should it be static?
  util_rec.c:404:6: warning: symbol 'rec_print_csv' was not declared.
  Should it be static?

These functions are only used internally from function util_rec_print_hdr(),
declare them as static.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:55:54 +02:00
Ingo Franzki 8bcb93673e libutil/util_opt: Remove unused global variables
A compile with sparse (make C=1) shows the following warnings:

  util_opt.c:42:19: warning: symbol 'util_opt_l' was not declared.
  Should it be static?
  util_prg.c:28:19: warning: symbol 'util_prg_l' was not declared.
  Should it be static?

util_opt_l and util_prg_l are not used anywhere, and also not declared in
any header file. Looks like they are superfluous, remove them.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:55:54 +02:00
Jan Höppner 21fe08ad23 gitignore: Add ctags files
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-06-18 13:20:08 +02:00
Alexander Egorenkov f8d3e5069a hsavmcore: add dracut modules and systemd services for kdump initramfs
* Provide a dracut module and a systemd service for Fedora, RHEL and SLES.
* Provide a systemd service for Ubuntu.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-06-18 13:20:08 +02:00
Alexander Egorenkov 9fb2568134 hsavmcore: add man pages for hsavmcore and hsavmcore.conf
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-06-18 13:20:08 +02:00
Alexander Egorenkov a38d82e8f9 hsavmcore: add hsavmcore.conf example
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-06-18 13:20:08 +02:00
Alexander Egorenkov 8c9cc6e12a s390-tools: add hsavmcore utility
hsavmcore is designed to make the dump process with kdump more efficient.
With hsavmcore, the HSA memory that contains a part of the production
kernel's memory can be released early in the process. Depending on the size
of the production kernel's memory, writing the dump to persistent storage
can be time consuming and prevent the HSA memory from being reused
by other LPARs.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-06-18 13:20:08 +02:00
Ingo Franzki ce8383e5ac zkey: Fix conversion of CCA DATA keys to CCA CIPHER keys
The CCA Key Translate2 verb needs a pre-built AES CIPHER key token skeleton
with XPRTCPAC set in the output buffer, to produce an AES CIPHER key
that can be exported to CAPCF.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-06-18 13:20:08 +02:00
Jan Höppner 9696b4c9b5 gitignore: Add lshwc binary
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-06-18 13:20:08 +02:00
Ingo Franzki 466ceb02a1 libekmfweb: Fix certificate extensions compare function
Correctly dereference the extensions passed to the compare function.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-06-18 13:20:08 +02:00
Alexander Egorenkov f6ab7f6cda libutil: Add an example for util_log
Build:
$ make -C libutil/util_log_example

* Every time a -V option is passed, the verbosity level increases and extra
messages are enabled.

Test:
$ ./libutil/util_log_example
 # No output
$ ./libutil/util_log_example -V
ERROR: This is an ERROR message
$ ./libutil/util_log_example -VV
ERROR: This is an ERROR message
 WARN: This is a WARN message
$ ./libutil/util_log_example -VVV
ERROR: This is an ERROR message
 WARN: This is a WARN message
 INFO: This is an INFO message
$ ./libutil/util_log_example -VVVV
ERROR: This is an ERROR message
 WARN: This is a WARN message
 INFO: This is an INFO message
DEBUG: This is a DEBUG message
$ ./libutil/util_log_example -VVVVV
ERROR: This is an ERROR message
 WARN: This is a WARN message
 INFO: This is an INFO message
DEBUG: This is a DEBUG message
TRACE: This is a TRACE message

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-06-18 13:20:08 +02:00
Alexander Egorenkov 568caa0501 libutil: Introduce multi-level message logging
The goal of util_log is to provide a facility for a multi-level message
logging on stderr. This allows to selectively enable/disable log messages
via a log level which can be adjusted at runtime.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-06-18 13:20:08 +02:00
Stefan Haberland 2ece47ee1a zdsfs: fix out of bound access in config file parsing
The tmp buffer is one byte too short missing space for the final \0 byte
leading to out of bound access.
Fix by increasing the buffer by one.

Reported-by: Niklas Schnelle <schnelle@linux.ibm.com>
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>
2021-05-21 12:24:27 +02:00
Stefan Haberland 0fafbcf3bb zdsfs: add dataset conversion to manpage
Update zdsfs manpage to include information about dataset conversion.

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>
2021-05-21 12:24:27 +02:00
Stefan Haberland 7244785279 zdsfs: transparent codepage conversion
Add transparent codepage conversion feature to zdsfs.
Add options to specify that codepage conversion should be done using
default codepages from 'CP1047' to 'UTF-8' or using user defined codepage
tables.
Also add a new config file allowing the user to specify codepage conversion
options on a per dataset basis.

When a dataset is opened and codepage conversion settings match this
dataset an iconv handle is created and the conversion itself is performed
by the lzds_dshandle_read() function.

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>
2021-05-21 12:23:57 +02:00
Stefan Haberland cdf716a7a9 libzds: add codepage conversion
Add codepage conversion capabilities to libzds.
Whenever a dataset is read and an appropriate iconv handle is set for the
dataset the conversion is automatically performed.

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>
2021-05-21 12:21:09 +02:00
Thomas Richter 529ad4000e cpumf/lscpumf.c: Replace function linux_error by err/warn
Replace function linux_error() by err/warn family.
Delete function linux_error() which is not used anymore.
Also fix some checkpatch warnings regarding comparison to zero.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:50:53 +02:00
Thomas Richter 0772c0f01b cpumf/chcpumf: Simplify function read_sfb
Simplify function read_sfb(). Convert it to type void
and return only when no errors occurred.
On error print error message and exit instead of return.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:50:53 +02:00
Thomas Richter 27a562da0a cpumf/lshwc: Program to extract complete counter sets
Program reads complete counter sets from any CPU by opening
device /dev/hwctr which is available with linux version 5.12.
The counter sets and CPUs can be specified on the command line.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:50:48 +02:00
Thomas Richter cd532cb6cd cpumf/chcpumf: Replace linux_error by err/warn
Replace function linux_error() by err/warn functions.

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>
2021-05-20 18:49:45 +02:00
Thomas Richter 80b1306102 cpumf/chcpumf: Replace fprintf to stderr by err/warn
Replace fprintf(stderr,...) by warnx and errx.

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>
2021-05-20 18:49:45 +02:00
Stefan Haberland 4b0403a963 zdsfs: improve man page for coordinated read access
Incorporate some ID feedback.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:49:44 +02:00
Thomas Richter 1d9e7b614c cpumf/chcpumf: Use util_opt_print_parse_error function
Use function util_opt_print_parse_error() instead of fprintf to stderr.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:49:44 +02:00
Thomas Richter 44de579311 cpumf/chcpumf: Simplify comparison against 0
Simplify comparison against 0 or NULL and fix a checkpatch.pl
warning.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:49:44 +02:00
Wenjia Zhang 4fb18a1e7b znetconf: avoid conflict with "chzdev -e"
Using "chzdev -e" to configurate a device persistently, the
corresponding udev rule is also created, which will trigger a uevent
that sets the device online as soon as the group device is created.

If 'znetconf -r/R' is first used to remove such a configured device
(which won't remove the corresponding udev rule) and then
'znetconf -a/A' afterwards on the same device, either the error
"Failed to make <device> online" or "Failed to configure layer2=1"
will occur.

For the first error, the udev queue might not have been fully processed
and hence the check whether a device is online may fail due to that
race. Call 'udevadm settle' to ensure a fully processed queue before
checking whether a device is online.

The second error occurs, because configure_ccwgroupdev_option() does
not check whether the device is online. Add the check and set the
device offline if necessary. Also, log any details for debugging
purposes.

Signed-off-by: Wenjia Zhang <wenjia@linux.ibm.com>
Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:49:44 +02:00
Thomas Richter 59206b88d8 cpumf/lscpumf: Use util_opt_print_parse_error function
Use function util_opt_print_parse_error() instead of
fprintf to stdout.

Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:49:44 +02:00
Thomas Richter 7a64b88396 cpumf/lscpumf: Use warnx instead of fprintf
Use function warnx() instead of fprintf() to stderr.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:49:44 +02:00
Siglen b7807d0195 dbginfo.sh: Add KVM commands and rework data collection
Add virsh commands for KVM debug data collection and rework the domain
data collection and step numbering. Update the man page accordingly.

[hoeppner@linux.ibm.com: Reword commit message]
Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:49:44 +02:00
Siglen 2f436d6ee0 CHANGELOG.md: Add dbginfo changes
Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:49:44 +02:00
Siglen 302cd4ed7e dbginfo.sh: fix typo
Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:49:44 +02:00
Jan Höppner 69526998f0 libdasd: Check return value for util_file_read_l
The return code of util_file_read_l() isn't checked and therefore
'value' could contain anything in case of an error. Check the return
code and set 'value' to 0 in the error case.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/110
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:49:44 +02:00
Stefan Haberland a65bc51cf4 udev/dasd: change DASD udev-rule to set none scheduler
Performance evaluation showed that using the mq-deadline scheduler for DASD
devices leads to a significantly higher CPU consumption compared to using
none scheduler while having the same amount of throughput.
Setting none scheduler as default in the dasd udev rule.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-03-16 17:18:51 +01:00
Mario Held eb1fd47a85 dbginfo: Added and removed commands
Added kallsyms and lscpu -ye, added vmcp commands
q memassist, q pcifunction, q vmrelocate and removed q cache

Signed-off-by: Mario Held <mario.held@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-03-16 17:18:51 +01:00
Ingo Franzki c4918fe713 zkey: Fix typos in man pages
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-03-16 17:18:51 +01:00
Jan Höppner d23558f1d1 ttyrun-getty: Avoid conflicts with serial-getty@
Starting ttyrun-getty@ will fail as it conflicts with the serial-getty@
service. Add Conflicts= option to avoid any conflicts.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/105
Suggested-by: Dan Horák <dan@danny.cz>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-03-16 17:18:51 +01:00
Fabrice Fontaine 3d79a542d4 osasnmpd/Makefile: fix cross-compilation
Fix the following build failure by allowing the user to provide
NET_SNMP_CONFIG:

/bin/sh: net-snmp-config: command not found
/home/buildroot/autobuild/run/instance-2/output-1/host/lib/gcc/s390x-buildroot-linux-gnu/9.3.0/../../../../s390x-buildroot-linux-gnu/bin/ld: osasnmpd.o: in function `main':
osasnmpd.c:(.text.startup+0xcc): undefined reference to `snmp_log_perror'

Fixes: http://autobuild.buildroot.org/results/00796f2ebd5fb0e08ac7a05a9ee566f2bc4bd1c3
Closes: https://github.com/ibm-s390-linux/s390-tools/pull/99
Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-24 18:34:27 +01:00
Marc Hartmayer b6bdd7744a genprotimg: use pv_ namespace for our Buffer implementation
Use `pv_` namespace for our Buffer implementation so a symbol clash with other
libraries is less likely.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/109
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-24 18:33:44 +01:00
Ingo Franzki 3f3f063c98 zkey: Fix build error when the compiler flags are overridden
When the compiler flags are overridden, the build of zkey may fail with:

kms.c:44:2: error: #error KMS_PLUGIN_LOCATION must be defined
   44 | #error KMS_PLUGIN_LOCATION must be defined
      |  ^~~~~

The Makefile uses CFLAGS variable for defining the KMS_PLUGIN_LOCATION,
but it should rather use ALL_CFLAGS.

Also use ALL_CPPFLAGS for defining HAVE_LUKS2_SUPPORT.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/108

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-23 16:49:09 +01:00
Jan Höppner 78d63f2333 Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-23 16:49:09 +01:00
Jan Höppner 1bb9a9ec5b New release s390-tools-2.16.0
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 15:46:37 +01:00
Nikita Dubrovskii 4a3957fab5 zipl: fix reading 4k disk's geometry
On 4k SCSI disks zipl stores wrong values to 'scsi_mbr.program_table_pointer',
which makes system unbootable.
This happens in 'zipl/src/disk.c:656':

```
/* Convert file system block to physical */
*physical = mapped * phy_per_fs + subblock;
/* Add partition start */
*physical += info->geo.start;

```

So 'hd_geometry.start' should be adjusted before being used.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1918723
Closes: https://github.com/ibm-s390-linux/s390-tools/pull/107
Signed-off-by: Nikita Dubrovskii <nikita@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:47:07 +01:00
Ingo Franzki e506c94839 zkey-ekmfweb: Fix typos in messages
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:47:07 +01:00
Wenjia Zhang dfd9f52873 hsci: fix packet loss caused by large MTU
For maximum performance the MTU of an HSCI interface was set to the value
of the MTU of its HiperSockets interface. However, the MTU of a
HiperSockets interface can be very large, and when the data packets are
not sent over the HiperSocket but over the corresponding ethernet
interface (which usually has a smaller MTU size) then it can happen that
the large packets are silently dropped. One example would be communication
from an HSCI in one CEC to another HSCI in another CEC via Ethernet.

To solve the problem, the MTU setting in this tool is removed, and the
default MTU value is used. Thus, the minimum value of the MTUs of the both
converged interfaces is used as the MTU of the HSCI interface.

Fixes: 0566a492ae ("s390-tools: add hsci tool")
Signed-off-by: Wenjia Zhang <wenjia@linux.ibm.com>
Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:47:07 +01:00
Jan Höppner 14ca7c5080 s390-tools: Change GitHub link to new name
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:47:07 +01:00
Steffen Maier 4fc1a92a8d zfcpdbf: deal with crash 7.2.9 change in caller name formatting
Since crash 7.2.9 commit
https://github.com/crash-utility/crash/commit/f1f43bf355df2564543c39f5d7e13b15c67eb13d
in support of kernel v5.9 commit 0990d836cecb
("s390/debug: debug feature version 3"),
the symbolic caller function name is left aligned instead of right
aligned, so now we alternatively have to remove whitespace between
function name and offset.

Otherwise, zfcpdbf output contains wrong warnings about ambiguous payload
records with wrong values for reqid and area, as well as incorrectly
decoded trace records with wrong content values and potential error
messages on not defined record id, and finally a potential list of
occurrences of unknown tags which should empty:

Loading trace records ...(this might take a while)
Warning: Ambiguous PAYload records. reqid:>>>wrong<<< area:V^D^@fcp_
Warning: Ambiguous PAYload records. reqid:>>>wrong<<< area:W^D^@fsf_
Warning: Ambiguous PAYload records. reqid:>>>wrong<<< area:i^B^@san_

...

Timestamp      : ...
Area           : SAN
Subarea        : 00
Level          : 1
Exception      : -
CPU ID         : 0001
Caller         : <zfcp_dbf_san_in_els
Record ID      : 0
Tag            : 6^B^Cfcie
Request ID     : >>>wrong<<<
Destination ID : >>>wrong<<<
SAN record id=0 not defined.
Timestamp      : ...
Area           : SAN
Subarea        : 00
Level          : 1
Exception      : -
CPU ID         : 0002
Caller         : <zfcp_dbf_san_in_els
Record ID      : 0
Tag            : 6^B^Cfcie
Request ID     : >>>wrong<<<
Destination ID : >>>wrong<<<
SAN record id=0 not defined.

...

occurrences of unknown tags:
...

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:46:54 +01:00
Ingo Franzki d73d7f91ac zkey-ekmfweb: Fix typos in man page
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:43:41 +01:00
Alexander Egorenkov 800df6bef8 zipl/boot: fix heap OOM in stage2 of DASD dumper
For the stage2 of zipl's boot loaders only 3 heap pages are available
[0x6000, 0x6000 + 0x3000]. Therefore, stage2 code needs to be very careful
when and for how long it allocates a heap page.

The heap OOM problem in stage2 was hidden until the commit 252be376
("zipl/boot: fix potential heap overflow in stage2"). Before this commit,
stage2 assumed that heap is 4 pages large which is apparently very wrong
but get_zeroed_page() still allowed allocating an extra 4th page by
overriding the memory segment following the heap area of stage2 (stage3
parameter area).

Try to avoid allocating a heap page and keeping it allocated over a long
period of time in the DASD dumpers. Free a heap page as soon as possible
if not required anymore.

And be extra careful with printf() because it always tries to allocate
a free heap page.

Fixes: 252be376 ("zipl/boot: fix potential heap overflow in stage2")
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>
2021-02-19 13:43:41 +01:00
Marc Hartmayer 3c661da4ee genprotimg: boot: make boot loader -march=z900 compatible
Replace the `lgfi` opcode with equivalents as z900 has no support for
it.

While at it, fix a comment in `genprotimg/boot/head.S` and remove a
useless label in `genprotimg/boot/stage3b_reloc.S`.

Closes: https://github.com/ibm-s390-tools/s390-tools/issues/86
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:43:41 +01:00
Ingo Franzki bf5ca4367d libekmfweb: Check length of JWK EC public key coordinates
RFC 7517 requires that the x and y coordinates of a ECC JSON Web Key
(JWK) are specified in its full size of a coordinate for the curve used.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:43:41 +01:00
Wenjia Zhang faf26220a7 hsci: fix failed to delete an HSCI connected with VLAN
Deleting an HSCI interface, the connected HiperSockets interface's name
and the connected Ethernet interface's name are extracted from "ip link
show". Currently the extracted names are directly used in "bridge -d link
show dev ifname" for further checking. If "iflink" and "ifindex" of an
interface are not matched, ip commands will print @ifXX appended to the
real interface's name. Thus, it will be failed if the interface's name
with the ending @ifXX is used in "bridge -d link show dev ifname" for
further checking.

To solve the problem, the ending @ifXX must be removed before the
interface name is used further.

Signed-off-by: Wenjia Zhang <wenjia@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:43:41 +01:00
Wenjia Zhang 522252d18a hsci: fix wrong return code
In the current code, after the function check_pnetids() and the function
verify_precon() are called, $? from each function is used twice
successively. It is used for the first time in the condition of the IF
statement, while for the second time as return code of the current
function. In bash, $? can be used to get the return code, but only for
the first time directly after the previous function is called.
Afterwards, $? will be reset to "0". Thus, the right return code can not
be get, if $? is used second time.

To solve the problem, using $? for the second time should be avoided.

Signed-off-by: Wenjia Zhang <wenjia@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:43:41 +01:00
Alexander Egorenkov 42889edc0c make: add address sanitizer support
Install libasan first, e.g. on Fedora 32:
  dnf install -y libasan libasan-static.

To compile with address sanitizer, pass ASAN=1 to make.
AdressSanitizer helps to catch various memory bugs for which C/C++ is
infamous.

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>
2021-02-19 13:43:41 +01:00
Alexander Egorenkov 13016ebc5a cmsfs-fuse: ASAN fix dec_to_hex() and hex_to_dec()
This fixes the following compiler errors when ASAN is enabled:

  CC      cmsfs-fuse/cmsfs-fuse.o
cmsfs-fuse.c: Assembler messages:
cmsfs-fuse.c:310: Error: operand out of range (0xffffffffffffff00 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:310: Error: operand out of range (0xffffffffffffff00 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:310: Error: operand out of range (0xffffffffffffff00 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:310: Error: operand out of range (0xffffffffffffff00 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:310: Error: operand out of range (0xffffffffffffff00 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:310: Error: operand out of range (0xffffffffffffff00 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:302: Error: operand out of range (0xfffffffffffffda0 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:302: Error: operand out of range (0xfffffffffffffda0 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:302: Error: operand out of range (0xfffffffffffffda0 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:302: Error: operand out of range (0xfffffffffffffda0 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:302: Error: operand out of range (0xfffffffffffffda0 is not between 0x0000000000000000 and 0x0000000000000fff)

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>
2021-02-19 13:43:41 +01:00
Ingo Franzki c4546daf34 zkey-ekmfweb: Avoid sequence number clash when generating keys
When keys are generated concurrently in EKMF Web from multiple clients,
and the key labels use a sequence number tag, then the assignment logic
of the sequence number may cause a duplicate sequence number to be used,
because another key might have already been generated with the same
sequence number, since the next-to-use sequence number has been retrieved
from EKMF Web. This results in a HTTP response code of 409 and a -EEXIST
return code from ekmf_generate_key().

Instead of getting the last used sequence number from EKMFWeb, tell
EKMFWeb to automatically use the next available sequence number when
generating a key. When the sequence number label tag value is 'next'
then EKMFWeb will automatically assign the next available sequence number
to the label tag and increment the sequence number in an atomic way.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-01-25 13:19:33 +01:00
Alexander Egorenkov 1e18429f69 zdump: fix invalid memory access on memory chunk's data
If a memory chunk is added to mem_phys as well as mem_virt
in dfi_mem_chunk_add_vol() then an illegal memory access might occur
when accessing mem_chunk->data e.g. in dfi_elf_mem_chunk_read_fn()
because the data block pointed to by the data field is now being referenced
by two memory chunks, one in mem_phys and one in mem_virt. If it happens
that the memory chunk from mem_virt is freed in mem_unmap() then
the memory chunk in mem_phys still points to the common data block
which has been already freed. This leads to all sort of bad behavior
in dfi_elf_mem_chunk_read_fn() and other places where mem_chunk->data
might be accessed.

Fixes the following bug:
zgetdump: Unexpected end of file for "dump.all.elf"

And this was found by AddressSanitizer:

=================================================================
==81170==ERROR: AddressSanitizer: heap-use-after-free on address 0x602000000570 at pc 0x00000101ac10 bp 0x03ffd897e250 sp 0x03ffd897e248
READ of size 8 at 0x602000000570 thread T0
    #0 0x101ac0f in dfi_elf_mem_chunk_read_fn s390-tools/zdump/dfi_elf.c:27
    #1 0x100d8a5 in mem_read s390-tools/zdump/dfi.c:339
    #2 0x100d8a5 in dfi_mem_phys_read s390-tools/zdump/dfi.c:616
    #3 0x100d8a5 in mem_chunk_map_read_fn s390-tools/zdump/dfi.c:353
    #4 0x100fd29 in mem_read s390-tools/zdump/dfi.c:339
    #5 0x100fd29 in dfi_mem_read s390-tools/zdump/dfi.c:608
    #6 0x1018e89 in os_info_get s390-tools/zdump/dfi_vmcoreinfo.c:65
    #7 0x1018e89 in dfi_vmcoreinfo_init s390-tools/zdump/dfi_vmcoreinfo.c:86
    #8 0x10175b3 in dfi_init s390-tools/zdump/dfi.c:1215
    #9 0x1006e71 in do_stdout s390-tools/zdump/zgetdump.c:161
    #10 0x1006e71 in main s390-tools/zdump/zgetdump.c:180
    #11 0x3ffb07abb89 in __libc_start_main (/lib64/libc.so.6+0x2bb89)
    #12 0x1007e8d  (s390-tools/zdump/zgetdump+0x1007e8d)

0x602000000570 is located 0 bytes inside of 8-byte region [0x602000000570,0x602000000578)
freed by thread T0 here:
    #0 0x3ffb0bc961b in free (/lib64/libasan.so.6+0xc961b)
    #1 0x100d2d9 in mem_unmap s390-tools/zdump/dfi.c:1050

previously allocated by thread T0 here:
    #0 0x3ffb0bc9aa9 in calloc (/lib64/libasan.so.6+0xc9aa9)
    #1 0x100a271 in zg_alloc s390-tools/zdump/zg.c:93

SUMMARY: AddressSanitizer: heap-use-after-free s390-tools/zdump/dfi_elf.c:27 in dfi_elf_mem_chunk_read_fn
Shadow bytes around the buggy address:
  0x100c0400000050: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
  0x100c0400000060: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
  0x100c0400000070: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
  0x100c0400000080: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
  0x100c0400000090: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
=>0x100c04000000a0: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa[fd]fa
  0x100c04000000b0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x100c04000000c0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa 04 fa
  0x100c04000000d0: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
  0x100c04000000e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x100c04000000f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==81170==ABORTING

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>
2021-01-25 13:19:33 +01:00
Alexander Egorenkov 11e78cada5 zdump: catch attempts to seek past end of file in zg_seek()
Make zg_seek() more robust.

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>
2021-01-25 13:19:33 +01:00
Alexander Egorenkov 0a7df9e030 zdump: improve error handling in pt_load_add()
Verify the given ELF header before adding any memory chunks otherwise
a memory chunk might be added even if the given ELF header is invalid.

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>
2021-01-25 13:19:33 +01:00
Vineeth Vijayan 7dd03eaeec zdev: Add build option to update initial RAM-disk by default
Some Linux distributions always include a copy of all persistent device
configuration data when updating the initial RAM-disk. This makes
chzdev's persistent device configuration changes ineffective because
device configuration directives applied in the RAM-disk take precedence
over those stored in the root filesystem.

This patch introduces a new build-time switch which allows distributions
to specify that whenever there is a persistent device configuration
change, the RAM-disk is updated automatically.

This feature can be enabled by adding 'ZDEV_ALWAYS_UPDATE_INITRD=1' as
a zdev build option. Where, by default ZDEV_ALWAYS_UPDATE_INITRD is 0.

Co-developed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-01-25 13:19:33 +01:00
Ingo Franzki 663262c962 zkey: Prevent sporadic error during key verification pattern generation
After a master key change, it can happen that the AF_ALG setkey
operation returns EINVAL, although the key is valid. This is a
temporary situation and the operation will succeed, once the firmware
has completed some internal processing related with the master key
change. Delay 1 second and retry up to 10 times.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-01-25 13:19:33 +01:00
Nikita Dubrovskii bf9482709f fdasd: Use increased retry count for dasd_reread_partition_table
If fdasd is used right after dasdfmt, it may fail with the following
error due to udev still processing events for the device:

```
fdasd error:  IOCTL error: Error while rereading partition table.
```

Call dasd_reread_partition_table() with an increased retry value to
circumvent this issue.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/103
Signed-off-by: Nikita Dubrovskii <nikita@linux.ibm.com>
[hoeppner@linux.ibm.com: Reword commit message]
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Dan Horák cdf0b5d66f hsci: fix help text
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/102
Signed-off-by: Dan Horák <dan@danny.cz>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Vance Morris 4aafd6962a netboot: Bump busybox version in pxelinux.0 build
`stime` was removed in glibc-2.31.
Busybox fixes this in https://git.busybox.net/busybox/patch/?id=d3539be8f27b8cbfdfee460fe08299158f08bcd9

Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/100
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/101
Signed-off-by: Vance Morris <vmorris@us.ibm.com>
Reviewed-by: Viktor Mihajlovski mihajlov@de.ibm.com
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Ingo Franzki 863e1c3fa4 zkey: Remove warning about sector size support with crypttab
Current distributions should now all support the sector size option
in crypttab entries for plain mode dm-crypt volumes.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Juergen Christ <jchrist@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Ingo Franzki 7c47ea8e09 zkey: Add support to store LUKS2 dummy passphrase in key repository
Extend zkey to allow to store a (dummy) LUKS2 passphrase together with a
secure key, for use with LUKS2 volumes. That way, when the repository is
backed up, or archived, also the passphrases of the associated LUKS2
volumes are backed up, or archived, and thus can not be forgotten.
This passphrase is then used in generated commands to format and open
the LUKS2 volumes.

Because of the use of secure keys to encrypt the volumes, the LUKS2
passphrase is of no or less relevance for security. It is therefore OK to
store the passphrase in clear text in the key repository, and also use
them in /etc/crypttab. Therefore, the passphrase could actually be a
trivial passphrase, or a dummy passphrase.

Note: Such a dummy passphrase is NOT considered a secret that needs to
be protected. If for a certain usage the passphrase is of relevance for
security, then the zkey dummy passphrase option must not be used to store
the passphrase.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Juergen Christ <jchrist@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Alexander Egorenkov c239d99379 genprotimg: do not fail on inline warnings caused by glib
gcc's -Werror switch also enables -Werror=inline which leads to a compilation
failure due to inline warnings caused by GLIB macros. To fix it, disable
the conversion of inline warnings into errors.

In file included from buildroot/qemu-s390x/host/bin/../s390x-buildroot-linux-gnu/sysroot/usr/lib/glib-2.0/include/glibconfig.h:9,
                 from buildroot/qemu-s390x/host/bin/../s390x-buildroot-linux-gnu/sysroot/usr/include/glib-2.0/glib/gtypes.h:32,
                 from buildroot/qemu-s390x/host/bin/../s390x-buildroot-linux-gnu/sysroot/usr/include/glib-2.0/glib/galloca.h:32,
                 from buildroot/qemu-s390x/host/bin/../s390x-buildroot-linux-gnu/sysroot/usr/include/glib-2.0/glib.h:30,
                 from pv/pv_hdr.c:10:
buildroot/qemu-s390x/build/s390-tools-2.15.1/genprotimg/src/utils/buffer.h: In function ‘pv_hdr_new’:
buildroot/qemu-s390x/host/bin/../s390x-buildroot-linux-gnu/sysroot/usr/include/glib-2.0/glib/gmacros.h:1028:49: error: inlining failed in call to ‘glib_autoptr_clear_Buffer’: call is unlikely and code size would grow [-Werror=inline]
 1028 | #define _GLIB_AUTOPTR_CLEAR_FUNC_NAME(TypeName) glib_autoptr_clear_##TypeName
      |                                                 ^~~~~~~~~~~~~~~~~~~

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Alexander Egorenkov 6c6e3a2b0e zipl/boot: fix potential heap overflow in stage2
Current heap size in stage2 is three pages long [0x6000-0x9000] but
get_zeroed_page() assumes it is one page more which might lead to
a heap overflow which will corrupt data located at 0x9000 (stage3
parameters). Calculate the heap size of a stage at run-time
by using the symbols provided by linker.

Furthermore, validate the given address in free_page() to stop illegal
memory accesses.

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-12-15 11:10:50 +01:00
Alexander Egorenkov 2dca5d193f zipl/boot: fix memory use after free in stage2
Prevent access to freed memory still pointed to by entry.
entry still points into load_page that has been released with free_page.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Ingo Franzki 75675ec627 libekmfweb: Make install directory for shared libraries configurable
If LIBDIR is not passed to the make invocation, install shared libraries
to USRLIB64DIR (/usr/lib64/), even though LIBDIR defaults to /lib/. If
LIBDIR is overridden for the make invocation, install shared libraries to
whatever is specified as LIBDIR.

Closes: https://github.com/ibm-s390-tools/s390-tools/issues/98

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-12-15 11:10:50 +01:00
Ingo Franzki 18bf2cce06 zkey/zkey-ekmfweb: Install KMS plugins into configurable location
Install KMS plugins into a configurable location. The default KMS plugin
location is '/usr/lib64/zkey/', but one can set ZKEYKMSPLUGINDIR on the make
invocation to change the plugin location, e.g. to '/usr/libexec/zkey/'.

Closes: https://github.com/ibm-s390-tools/s390-tools/issues/98

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-12-15 11:10:50 +01:00
Ingo Franzki 8781dd3e7b zkey-ekmfweb: Fix selection of key properties to set or remove
When some of the key properties are skipped due to null_values_only
being true or false, then the resulting EKMF tag list might be built
incorrectly.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Ingo Franzki 6380e77f28 zkey-ekmfweb: Allow NULL as property value to remove a property
To remove a KMS property function kms_set_key_properties() can be
called with the property value set to NULL. Do not assert for non-NULL
property values.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Marc Hartmayer 733b86c02a genprotimg: remove -Winline cflag
`-Winline` can cause problems with the cleanup functions defined by
glib. Therefore let's remove the cflag for now.

DEBUG: /usr/include/glib-2.0/glib/gmacros.h:1031:43: error: inlining failed in call to 'glib_autoptr_cleanup_STACK_OF_X509_CRL.isra.0': call is unlikely and \
code size would grow [-Werror=inline]
DEBUG:  1031 | #define _GLIB_AUTOPTR_FUNC_NAME(TypeName) glib_autoptr_cleanup_##TypeName

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Marc Hartmayer 7827a791c9 genprotimg: add missing return
This should be no problem (if OpenSSL works correctly), because
`crls_download_cb` is only called out of the verification context of
OpenSSL. It's used to look up a CRL and therefore
X509_STORE_CTX_get_current_cert should always return a certificate
since X509_STORE_CTX_get_current_cert returns NULL only if an error
has occurred during the verification (see
https://www.openssl.org/docs/man1.1.0/man3/X509_STORE_CTX_get_current_cert.html).

Fixes: 074de1e14e ("genprotimg: add host-key document verification support")
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Marc Hartmayer 074de1e14e genprotimg: add host-key document verification support
Add host-key document verification support to genprotimg. This ensures
that a host-key document is genuine and provided by IBM. For this the
user must provide the IBM Z signing key, the intermediate CA
certificate (signed by the root CA used) so a chain of trust starting
from the host-key document and ending in the root CA can be
established.

By default, genprotimg tries to download all revocation lists needed
by looking up in the corresponding certificate on how CRL information
can be obtained (see https://tools.ietf.org/html/rfc5280#section-4.2.1.13
for details).

Acked-by: Patrick Steuer <patrick.steuer@de.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-18 11:28:35 +01:00
Ingo Franzki 07d181e29b zkey: Fix APQN property names
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-18 11:28:35 +01:00
Marc Hartmayer 895a88b2f8 genprotimg: require argument for 'ramdisk' and 'parmfile' options
A argument is required for the optional options 'ramdisk' and
'parmfile'.

Fixes: 65b9fc442c ("genprotimg: introduce new tool for the creation of PV images")
Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-18 11:28:35 +01:00
Ingo Franzki f01f8b240c zkey-ekmfweb: Fix typo in message
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-18 11:28:35 +01:00
Jan Höppner be2bc610b7 netboot: Add version information to scripts
Add the -v short option for version information to the mk-s390image and
mk-pxelinux-ramfs. Adjust the Makefile accordingly to set the correct
s390-tools version during installation.

Acked-by: Viktor Mihajlovski <mihajlov@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-18 11:28:35 +01:00
Marc Hartmayer c48d45ba92 common.mak: use '--' for rm calls to distinguish between options and files
Use '--' for rm calls to distinguish between options and files. This
fixes, for example, the following error:

make[1]: Entering directory '/root/git/s390-tools/genprotimg/src'
rm -f *.gcda *.gcno *.gcov
rm: invalid option -- '.'
Try 'rm ./-.gcno' to remove the file '-.gcno'.
Try 'rm --help' for more information.
make[1]: *** [../../common.mak:369: clean_gcov] Error 1

Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-18 11:28:35 +01:00
Thomas Richter 886476a207 cpumf/chcpumf.c: Print proper error message on non-root invocation
chcpumf must be executed as root. A non-root user sees this error
message:

[tester@t35lp46 ~]$ chcpumf -m 1000
Error: /sys/module/kernel/parameters/cpum_sfb_size: Permission denied
[tester@t35lp46 ~]$

Enhance the error message and be clear about the root cause:
[tester@t35lp46 ~]$ chcpumf-new  -m 1000
Error: Must run as root
[tester@t35lp46 ~]$

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-18 11:28:35 +01:00
Thomas Richter 86685f001d cpumf/lscpumf.c: Check for help and version options first
Check command line arguments for help text and version
string first, before doing any action. This ensures this
information is always printed, even when invoked as non-root
user.

Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/97
Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-18 11:28:35 +01:00
Jan Höppner d619b492e9 lsdasd: Add FC Endpoint Security information
Provide the status of the FC Endpoint Security information via the long
output of lsdasd for online Base and Alias devices.

New Output:

$ lsdasd -l c600
0.0.c600/dasdd/9412
  status:                               n/f
  type:                                 ECKD
  blksz:                                512
  size:
  blocks:
  extent_size:                          1113
  logical_capacity:                     1113
  space_allocated:                      1113
  use_diag:                             0
  readonly:                             0
  eer_enabled:                          0
  erplog:                               0
  hpf:                                  1
  uid:                                  IBM.750000000KMV11.c600.00
  fc_security:                          Encryption
  paths_installed:                      38 39 3a 3b
  paths_in_use:                         38 39 3a 3b
  paths_non_preferred:
  paths_invalid_cabling:
  paths_cuir_quiesced:
  paths_invalid_hpf_characteristics:
  paths_error_threshold_exceeded:

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-12 10:50:48 +01:00
Jan Höppner 79e4798061 zdev: Add FC Endpoint Security information for DASD devices
Provide information for the DASD device attribute 'fc_security'.
The help output for this attribute can be queried like this:

chzdev dasd --help-attribute

The lszdev tool can be used to display the current state of the FC
Endpoint Security information:

lszdev dasd -a -c TYPE,ID,ATTR:fc_security,ATTRPATH:fc_security

Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-12 10:50:48 +01:00
Ingo Franzki cf2311f1f1 zcryptstats: Fix handling of partial results with many domains
When many domains per card are available, then the results of the SCDMD
CHSC call may not fit into the output area, and a partial result is
returned. The further results must be retrieved with another CHSC call.

Fix the code to pass the correct next-domain to the subsequent CHSC call
of a partial response. Otherwise the same set of domains 1 to n are
retrieved again, resulting in an infinite loop, because this will always
produce a partial result.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-12 08:06:11 +01:00
Colin Walters 7e832da790 systemd/cpi.service: Add RemainAfterExit=yes
Noticed this while looking at the unit file for a different
RHEL CoreOS issue.

See https://github.com/ostreedev/ostree/pull/1697
and https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=750683

Omitting this can cause the service to run multiple times if
something else ends up depending on it, which I'm guessing
we don't want.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/72
Signed-off-by: Colin Walters <walters@verbum.org>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-11 14:25:46 +01:00
Dan Horák 3b402a0630 lscpumf: add z15 Model T02
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/87
Signed-off-by: Dan Horák <dan@danny.cz>
Reviewed-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-11 14:25:46 +01:00
Dan Horák 3437c9bb90 netboot/mk-s390image: add simple man page
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/94
Signed-off-by: Dan Horák <dan@danny.cz>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-11 14:25:46 +01:00
Philipp Kern 8898650266 scripts/zipl-switch-to-blscfg.1: Fix some typos
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/90
Signed-off-by: Philipp Kern <pkern@google.com>
Acked-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-11 14:25:46 +01:00
Prashanth Sundararaman 3ae2100d5e systemd/cpi.service: Add sysinit.target dependency to make sure /var is created
Noticed on RHEL CoreOS that the CPI service failed to start with:

"Cannot access lock file: /var/lock/cpictl.lock"

This was a timing issue where /var was not created yet and the symlink
to /run/lock was not present. Add sysinit.target to fix this.
This fix has been tested with RHEL CoreOS.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/82
Signed-off-by: Prashanth Sundararaman <psundara@redhat.com>
Suggested-by: Colin Walters <walters@verbum.org>
Reviewed-by: Dan Horák <dan@danny.cz>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-11 14:25:46 +01:00
Alexander Egorenkov 93e4249fd3 zkey/ekmfweb: fix linking of libekmfweb
Use -L compiler's parameter instead of the environment variable
LIBRARY_PATH.

Fixes the following problem on buildroot:

buildroot/qemu-s390x/host/bin/s390x-linux-gcc -shared -Wl,--version-script=zkey-ekmfweb.map -Wl,-z,defs,-Bsymbolic -Wl,-soname,zkey-ekmfweb.so.1 zkey-ekmfweb.o properties.o pkey.o cca.o ep11.o utils.o ../..//libutil/libutil.a -lekmfweb -ldl -lcrypto -o zkey-ekmfweb.so
buildroot/qemu-s390x/host/bin/s390x-linux-gcc -I ../../include -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I ../include -std=gnu99 -Wno-unused-parameter -Wno-missing-field-initializers -DS390_TOOLS_RELEASE=2.15.1-build-20201105 -DS390_TOOLS_LIBDIR=/lib/s390-tools -DS390_TOOLS_DATADIR=/usr/share/s390-tools -DS390_TOOLS_SYSCONFDIR=/etc -DS390_TOOLS_BINDIR=/sbin -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64  -Os   -D_GNU_SOURCE -c udev_ccwgroup.c -o udev_ccwgroup.o
buildroot/qemu-s390x/host/bin/s390x-linux-gcc -I ../../include -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I ../include -std=gnu99 -Wno-unused-parameter -Wno-missing-field-initializers -DS390_TOOLS_RELEASE=2.15.1-build-20201105 -DS390_TOOLS_LIBDIR=/lib/s390-tools -DS390_TOOLS_DATADIR=/usr/share/s390-tools -DS390_TOOLS_SYSCONFDIR=/etc -DS390_TOOLS_BINDIR=/sbin -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64  -Os   -D_GNU_SOURCE -c iscsi.c -o iscsi.o
buildroot/qemu-s390x/host/bin/s390x-linux-gcc -I ../../include -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I ../include -std=gnu99 -Wno-unused-parameter -Wno-missing-field-initializers -DS390_TOOLS_RELEASE=2.15.1-build-20201105 -DS390_TOOLS_LIBDIR=/lib/s390-tools -DS390_TOOLS_DATADIR=/usr/share/s390-tools -DS390_TOOLS_SYSCONFDIR=/etc -DS390_TOOLS_BINDIR=/sbin -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64  -Os   -D_GNU_SOURCE -c dasd.c -o dasd.o
buildroot/qemu-s390x/host/opt/ext-toolchain/bin/../lib/gcc/s390x-buildroot-linux-gnu/9.3.0/../../../../s390x-buildroot-linux-gnu/bin/ld: cannot find -lekmfweb
collect2: error: ld returned 1 exit status
make[4]: *** [Makefile:36: zkey-ekmfweb.so] Error 1
make[3]: *** [Makefile:128: ekmfweb] Error 2
buildroot/qemu-s390x/host/bin/s390x-linux-gcc -I ../../include -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I ../include -std=gnu99 -Wno-unused-parameter -Wno-missing-field-initializers -DS390_TOOLS_RELEASE=2.15.1-build-20201105 -DS390_TOOLS_LIBDIR=/lib/s390-tools -DS390_TOOLS_DATADIR=/usr/share/s390-tools -DS390_TOOLS_SYSCONFDIR=/etc -DS390_TOOLS_BINDIR=/sbin -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64  -Os   -D_GNU_SOURCE -c zfcp.c -o zfcp.o
make[2]: *** [Makefile:43: zkey] Error 2
make[2]: *** Waiting for unfinished jobs....

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Acked-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-11 14:25:46 +01:00
Jan Höppner 8ec4705239 libutil: Compare proc entries to vfstype
Modern systems have systemd manage system mount points like sysfs which
specify 'sysfs' as a keyword for the device as there is no device
associated with this special filesystem. However, any arbitrary string
could be specified here and the determination of the sysfs mount point
would fail in such a case.
To make sure that the mount point of the sysfs is still found when
mounted with a device keyword specified other than 'sysfs', check for
the filesystem type instead, which is more specific.

Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/91
Suggested-by: Mark Post <mpost@suse.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-09 12:24:32 +01:00
Jan Höppner cad450fdf9 dasdfmt: Make error function less error-prone
Add a proper definition to the dasdfmt header file of the error()
function that lets the compiler check the format string against the
provided parameters.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-09 12:24:32 +01:00
Dan Horák 3a1cda59ce libekmfweb: fix permissions for ekmfweb.h
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/96
Signed-off-by: Dan Horák <dan@danny.cz>
Acked-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-09 10:39:46 +01:00
Wenjia Zhang 0566a492ae hsci: Add new tool to control HiperSockets Converged Interfaces
hsci is used to control and show HSCI (HiperSockets Converged Interfaces)
settings. A HiperSockets interface and an external network interface are
converged to an HSCI interface.

Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
Signed-off-by: Wenjia Zhang <wenjia@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-09 10:16:22 +01:00
Marc Hartmayer bc7359d2a3 iucvterm: abort if one of the recursive targets is failing
Abort processing as soon as one of the recursive targets is failing.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-06 16:18:21 +01:00
Marc Hartmayer db6f272607 genprotimg: fix two memory leaks
==1005844== HEAP SUMMARY:
==1005844==     in use at exit: 18,907 bytes in 14 blocks
==1005844==   total heap usage: 82 allocs, 68 frees, 32,529 bytes allocated
==1005844==
==1005844== 136 (104 direct, 32 indirect) bytes in 1 blocks are definitely lost in loss record 12 of 14
==1005844==    at 0x483885A: calloc (vg_replace_malloc.c:760)
==1005844==    by 0x48C950D: g_malloc0 (gmem.c:132)
==1005844==    by 0x100EC41: pv_args_new (pv_args.c:364)
==1005844==    by 0x100587F: main (genprotimg.c:122)
==1005844==
==1005844== LEAK SUMMARY:
==1005844==    definitely lost: 104 bytes in 1 blocks
==1005844==    indirectly lost: 32 bytes in 1 blocks
==1005844==      possibly lost: 0 bytes in 0 blocks
==1005844==    still reachable: 18,771 bytes in 12 blocks
==1005844==         suppressed: 0 bytes in 0 blocks
==1005844== Reachable blocks (those to which a pointer was found) are not shown.
==1005844== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==1005844==
==1005844== For lists of detected and suppressed errors, rerun with: -s
==1005844== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-06 16:18:21 +01:00
Marc Hartmayer 6db7fbe018 genprotimg: abort if one of the recursive targets is failing
Abort compilation as soon as one of the recursive targets is failing.

Fixes: 65b9fc442c ("genprotimg: introduce new tool for the creation of PV images")
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-06 16:18:21 +01:00
Sven Schnelle 2f154fa49d cmsfs-fuse: fix pointer block level calculation
Adding one to the pointer per block value results in a wrong
calculation of pointer block levels. When writing a file that
would result in about 454MB size, the code would calculate that
it needs a two level pointer directory but correct would be a three
level pointer directory. This causes an invalid filesystem state:
besides missing all the records of one top level pointer directory
entry, it would also record a higher record number in the FST than
what is present in the pointer blocks.

Note that this bug only hits when the file is about 454MB and the write
is stopped (means the file is closed) - if file writing continues the
problem doesn't happen because at some point in time cmsfs-fuse would
switch to three levels of pointer blocks anyways as the file grows.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-06 16:18:21 +01:00
Jan Höppner 148d3f9b64 dasdfmt: Fix segfault when an incorrect option is specified
When specifying an incorrect program option, dasdfmt segfaults as the
format string for the corresponding error message has no parameter.
Add the missing parameter to fix this.

Fixes: 732b3dddab ("dasdfmt: Replace ERRMSG_EXIT macro with an error handling function")
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-03 09:05:29 +01:00
Brian C. Lane 702dc96264 netboot: Clear kernel cmdline data before writing new parmfile
If this isn't cleared first it can end up with an unexpected cmdline if
it doesn't completely overwrite the default data.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/95
Reviewed-by: Viktor Mihajlovski <mihajlov@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-03 09:05:29 +01:00
Jan Höppner 313092b202 Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-03 09:05:29 +01:00
Jan Höppner b098990abe New release s390-tools-2.15.1
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 15:31:59 +01:00
Stefan Haberland 6802b86414 libutil: determine base device address in case of given partition
util_sys_get_dev_addr() returns the device address for a given blockdevice.
This does not work for partitions but some tools rely on the ability to get
the device address for partitions.

Add code that first determines the base device for a partition.

Fixes: 6014d07cb1 ("dasdview/libdasd/zipl: Use util_sys_get_dev_addr() instead of u2s_getbusid()")
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 15:08:29 +01:00
Stefan Haberland aa8c2945cc zipl: make use of util_sys functions to get base device
Remove the implementation in zipl and use the util_sys one.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 15:08:24 +01:00
Stefan Haberland fa7a4dafa3 libutil: add function to get base device for blockdevice
Some operations are only possible on base devices not on partitions.
Add functions to determine if a given device is a partition or a base
device and to get the base device to a given partition.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 15:08:02 +01:00
Jan Höppner 7eb04cdc54 zfcpdump: Fix dump location in README
Commit 724f1fea2c ("Makefile: Rename ZFCPDUMP_PART_* macros") renamed
the zfcpdump image from zfcpdump_part.image to zfcpdump-image. Fix the
image name in the README as well.

Closes: https://github.com/ibm-s390-tools/s390-tools/issues/89
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner d55b787d05 zgetdump: Fix device node determination via sysfs
When using zgetdump on a multi-volume device dump, the sysfs path to
determine the device node is incomplete, resulting in the following
error:

$ zgetdump -i /dev/dasdb1
zgetdump: Could not open "/sys/bus/ccw/devices/0.0.9300/dasdb/dev" (No
such file or directory)

A simple fix would be to add the missing "block" part in the sysfs path.
However, the logic still assumes sysfs links like "block:" that have
been deprecated a decade ago and are no longer present on modern
systems anyway.
Therefore, the logic can greatly be improved. Create a separate function
to determine whether a device is online, remove the logic for "block:"
entries, and use libutil functions to reduce the complexity even further.

Fixes: 70a79fab3c ("zgetdump: Avoid using PATH_MAX")
Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner da4fdeeb82 dasdfmt: Set prog_name to last component of program name
In the process of switching to glibc defined error functions it becomes
apparent that self-defined error functions that do special things are
not in line with the output of the glibc functions.

To address this, set the prog_name variable to the last component of the
program name (stored in argv[0]) and guarantee a uniform error output.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner 9fe491df27 dasdfmt: Improve error message construction
In check_track_format() the base error message is the same for all cases
but has different additional content depending on which mode dasdfmt is
running.

Currently the message is compiled by using different outputs. To make it
a little bit cleaner and for a better error message handling, construct
the message string completely before passing it to the error() function
for output.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner 732b3dddab dasdfmt: Replace ERRMSG_EXIT macro with an error handling function
The ERRMSG_EXIT macro is a bit clunky in its usage and a change is
necessary in order to free memory in error cases.

Create a new function error() that takes only a format string and adds
all other relevant information by itself. This function frees memory
before terminating the program with the EXIT_FAILURE exit code.

This simplifies the error handling for pretty much all calls and makes
the code a bit cleaner.

While at it, the defines EXIT_MISUSE and EXIT_BUSY don't provide any
value. Neither are they documented nor are these standardized. Also, a
parent process is mostly interessted in success or failure only anyway.
Replace these by using only EXIT_FAILURE in the error() function.

Also, change multiline output to a combination of warnx and error to
have a uniformed output. So this:

WARNING: Device is formatted with a different blocksize (4096).
Use --mode=full to perform a clean format.

becomes this:

dasdfmt: WARNING: Device is formatted with a different blocksize (4096).
dasdfmt: Use --mode=full to perform a clean format.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner cb76e39cef dasdfmt: Fix bad file descriptor error when running on symlinks
When calling dasdfmt on device node symlinks like
/dev/disk/by-id/ccw-0X9300, dasdfmt fails with "dasdfmt: the ioctl to get
the blocksize of the device failed (Bad file descriptor)"

This is because before the actual formatting process starts, the disk
will be disabled calling the BIODASDDISABLE ioctl, resulting in the
removal of the symlink. Trying to open this file later in the process to
retrieve e.g. blocksize information results in the mentioned error, as
the file doesn't exist any longer.

This incorrect behaviour was introduced with commit 8826028bdc
("dasdfmt: Use libdasd provided ioctl functions") at which the use of a
globally available file descriptor was omitted. Instead, the ioctl
library functions require a device node to be passed as a function
parameter and will open a file descriptor themselves.
So, before that change, the global file descriptor was always valid even
when the file was removed.

In order to fix this without modifying the behaviour of libdasd,
introduce the two global variables dev_node and dev_path. dev_path is
the original device path entered by the user. dev_node on the other hand
is the reliable device node under /dev/block/ using the major and minor
numbers and is determined in get_device_name().
The dev_path is used for message output only and the dev_node variable
is used for the actual disk operations.

As these two variables are global, the device parameters for several
functions are removed to make the code a bit cleaner.

Fixes: 8826028bdc ("dasdfmt: Use libdasd provided ioctl functions")
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner 09be935c54 dasdfmt: Make program relevant information global
The global program options (and other actually globally used
information) are currently passed through via function parameter
whenever this information is needed. However, in reality, this
information is used almost everywhere across the program.

Make this information globally available and get rid of all the
unnecessary function parameters for dasdfmt_info_t. This makes the code
a little bit cleaner and more readable. Also, rename the global struct
to a more suitable name.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner 65e18bff67 dasdfmt: Remove function dasdfmt_format
dasdfmt_format() does nothing but calling process_tracks() with the same
parameters. Get rid of it, call process_tracks() directly, and avoid
confusion.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner 07ab32fa8b dasdfmt: Fix whitespace
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner 353403824b libdasd: Fix dasd_get_host_access_count()
Since commit 75e3afb6a0 ("libdasd: Move get_host_access_count() to
libdasd") dasd_get_host_access_count() reports always 0 as the check for
unsuccessful execution of util_sys_get_dev_addr() is incorrect.
Fix the behaviour by turning the check around.

Fixes: 75e3afb6a0 ("libdasd: Move get_host_access_count() to libdasd")
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Ingo Franzki 8a58389e2f zkey: Add library versioning for libekmfweb and zkey-ekmfweb
Closes: https://github.com/ibm-s390-tools/s390-tools/issues/93

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Alexander Egorenkov f2cc871b02 genprotimg/boot: disable SSP
SSP cannot work with boot loaders because it requires libc.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Alexander Egorenkov 4dbdc8dfab zipl/boot: disable SSP
SSP cannot work with boot loaders because it requires libc.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Ingo Franzki 60900de5e9 zkey: Skip build of zkey-ekmfweb.so if libekmfweb dependencies are missing
zkey-ekmfweb.so requires libekmfweb.so. If libekmfweb.so can not be built
due to missing build requirements, then zkey-ekmfweb.so can't be built
either.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Sven Schnelle 2bba362e9a lsstp: Improve wording and fix typos in man page
Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Ingo Franzki 76044be98d zkey: Ensure zkey and friends are skipped with HAVE_OPENSSL=0
Building zkey-ekmfweb.so will also trigger to build libekmfweb.so,
which requires OpenSSL. So, skip zkey-ekmfweb.so if HAVE_OPENSSL=0.

zkey-cryptsetup also has a dependency on OpenSSL, so skip it also
if HAVE_OPENSSL=0

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:29 +01:00
Jan Höppner 885ff0a03f Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-15 15:56:15 +02:00
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: https://github.com/ibm-s390-tools/s390-tools/commit/d71628326d80e623fc9f008fe4ea93edb5592b2e
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
283 changed files with 79270 additions and 4847 deletions
+32 -19
View File
@@ -5,15 +5,19 @@
*.a *.a
*.o.d *.o.d
# ctags files
tags
TAGS
# #
# Ignore generated executables and other generated files # Ignore generated executables and other generated files
# #
cmsfs-fuse/cmsfs-fuse cmsfs-fuse/cmsfs-fuse
cpacfstats/cpacfstats cpacfstats/cpacfstats
cpacfstats/cpacfstatsd cpacfstats/cpacfstatsd
cpumf/bin/chcpumf cpumf/chcpumf
cpumf/bin/cpumf_helper cpumf/lscpumf
cpumf/bin/lscpumf cpumf/lshwc
cpuplugd/cpuplugd cpuplugd/cpuplugd
dasdfmt/dasdfmt dasdfmt/dasdfmt
dasdinfo/dasdinfo dasdinfo/dasdinfo
@@ -21,6 +25,7 @@ dasdview/dasdview
dump2tar/src/dump2tar dump2tar/src/dump2tar
fdasd/fdasd fdasd/fdasd
hmcdrvfs/hmcdrvfs hmcdrvfs/hmcdrvfs
hsavmcore/hsavmcore
hyptop/hyptop hyptop/hyptop
ip_watcher/xcec-bridge ip_watcher/xcec-bridge
ipl_tools/chreipl ipl_tools/chreipl
@@ -35,18 +40,22 @@ iucvterm/src/iucvconn
iucvterm/src/iucvtty iucvterm/src/iucvtty
iucvterm/src/ttyrun iucvterm/src/ttyrun
iucvterm/test/test_afiucv iucvterm/test/test_afiucv
libutil/util_base_example libekmfweb/check-dep-libekmfweb
libutil/util_file_example libekmfweb/detect-openssl-version.dep
libutil/util_libc_example libekmfweb/libekmfweb.so
libutil/util_opt_command_example libekmfweb/libekmfweb.so.1
libutil/util_opt_example libekmfweb/libekmfweb.so.1.0
libutil/util_panic_example libkmipclient/check-dep-libkmipclient
libutil/util_path_example libkmipclient/detect-openssl-version.dep
libutil/util_prg_example libkmipclient/libkmipclient.so
libutil/util_rec_example libkmipclient/libkmipclient.so.1
libutil/util_scandir_example libkmipclient/libkmipclient.so.1.0
libzds/libzds.a libseckey/check-dep-libseckey
libseckey/detect-openssl-version.dep
libutil/*_example
libvmcp/vmcp_example libvmcp/vmcp_example
libzds/libzds.a
lsstp/lsstp
mon_tools/mon_fsstatd mon_tools/mon_fsstatd
mon_tools/mon_procd mon_tools/mon_procd
osasnmpd/osasnmpd osasnmpd/osasnmpd
@@ -76,10 +85,10 @@ zdev/src/lszdev
zdev/src/lszdev_usage.c zdev/src/lszdev_usage.c
zdsfs/zdsfs zdsfs/zdsfs
zdump/zgetdump zdump/zgetdump
zfcpdump/cpioinit
zfcpdump/zfcpdump_part
zfcpdump/zfcpdump-initrd
zfcpdump/10-zfcpdump.install zfcpdump/10-zfcpdump.install
zfcpdump/cpioinit
zfcpdump/zfcpdump-initrd
zfcpdump/zfcpdump_part
ziomon/ziomon_mgr ziomon/ziomon_mgr
ziomon/ziomon_util ziomon/ziomon_util
ziomon/ziomon_zfcpdd ziomon/ziomon_zfcpdd
@@ -91,9 +100,13 @@ zipl/boot/data.h
zipl/src/chreipl_helper.device-mapper zipl/src/chreipl_helper.device-mapper
zipl/src/zipl zipl/src/zipl
zipl/src/zipl_helper.device-mapper zipl/src/zipl_helper.device-mapper
zkey/zkey
zkey/zkey-cryptsetup
zkey/check-dep-zkey zkey/check-dep-zkey
zkey/check-dep-zkey-cryptsetup zkey/check-dep-zkey-cryptsetup
zkey/detect-libcryptsetup.dep zkey/detect-libcryptsetup.dep
zkey/ekmfweb/libekmfweb.dep
zkey/ekmfweb/zkey-ekmfweb.so
zkey/kmip/libkmipclient.dep
zkey/kmip/zkey-kmip.so
zkey/zkey
zkey/zkey-cryptsetup
zpcictl/zpcictl zpcictl/zpcictl
+15
View File
@@ -1,6 +1,7 @@
List of all individuals having contributed content to s390-tools List of all individuals having contributed content to s390-tools
---------------------------------------------------------------- ----------------------------------------------------------------
- Alexander Egorenkov
- Alexey Ishchuk - Alexey Ishchuk
- Andreas Herrmann - Andreas Herrmann
- Andre Wild - Andre Wild
@@ -8,21 +9,25 @@ List of all individuals having contributed content to s390-tools
- Arnd Bergmann - Arnd Bergmann
- Axel Wirbser - Axel Wirbser
- Benjamin Block - Benjamin Block
- Brian C. Lane
- Carsten Otte - Carsten Otte
- Christian Borntraeger - Christian Borntraeger
- Christian Ehrhardt - Christian Ehrhardt
- Christof Schmitt - Christof Schmitt
- Claudio Imbrenda - Claudio Imbrenda
- Clemens von Mann - Clemens von Mann
- Colin Walters
- Dan Horak - Dan Horak
- Despina Papadopoulou - Despina Papadopoulou
- Dimitri John Ledkov - Dimitri John Ledkov
- Eberhard Pasch - Eberhard Pasch
- Eduard Shishkin
- Einar Lueck - Einar Lueck
- Eric Sandeen - Eric Sandeen
- Erwin Vicari - Erwin Vicari
- Eugene Crosser - Eugene Crosser
- Eugene Dvurechenski - Eugene Dvurechenski
- Fabrice Fontaine
- Farhan Ali - Farhan Ali
- Fedor Loshakov - Fedor Loshakov
- Felix Beck - Felix Beck
@@ -32,6 +37,7 @@ List of all individuals having contributed content to s390-tools
- Fritz Elfert - Fritz Elfert
- Gerald Schaefer - Gerald Schaefer
- Gerhard Tonn - Gerhard Tonn
- Guevenc Guelce
- Hannes Reinecke - Hannes Reinecke
- Hans-Joachim Picht - Hans-Joachim Picht
- Hans Wippel - Hans Wippel
@@ -52,12 +58,15 @@ List of all individuals having contributed content to s390-tools
- Jean-Baptiste Joret - Jean-Baptiste Joret
- Jens Remus - Jens Remus
- Jochen Roehrig - Jochen Roehrig
- Joern Siglen
- Juergen Christ
- Julian Wiedmann - Julian Wiedmann
- Karsten Graul - Karsten Graul
- Kittipon Meesompop - Kittipon Meesompop
- Klaus-Dieter Wacker - Klaus-Dieter Wacker
- Lakhvich Dmitriy - Lakhvich Dmitriy
- Marc Hartmayer - Marc Hartmayer
- Mario Held
- Mark Dettinger - Mark Dettinger
- Mark Post - Mark Post
- Martin Kammerer - Martin Kammerer
@@ -71,11 +80,13 @@ List of all individuals having contributed content to s390-tools
- Michael Mueller - Michael Mueller
- Mijo Safradin - Mijo Safradin
- Mikhail Zaslonko - Mikhail Zaslonko
- Nikita Dubrovskii
- Niklas Schnelle - Niklas Schnelle
- Peter Oberparleiter - Peter Oberparleiter
- Peter Tiedemann - Peter Tiedemann
- Philipp Kern - Philipp Kern
- Philipp Rudo - Philipp Rudo
- Prashanth Sundararaman
- Rafael Fonseca - Rafael Fonseca
- Raimund Schroeder - Raimund Schroeder
- Ralph Wuerthner - Ralph Wuerthner
@@ -94,6 +105,7 @@ List of all individuals having contributed content to s390-tools
- Steffen Maier - Steffen Maier
- Steffen Thoss - Steffen Thoss
- Susanne Wintenberger - Susanne Wintenberger
- Sven Schnelle
- Sven Schuetz - Sven Schuetz
- Swen Schillig - Swen Schillig
- Taraka R. Bodireddy - Taraka R. Bodireddy
@@ -104,7 +116,10 @@ List of all individuals having contributed content to s390-tools
- Tuan Hoang - Tuan Hoang
- Ursula Braun - Ursula Braun
- Utz Bacher - Utz Bacher
- Vance Morris
- Vasily Gorbik - Vasily Gorbik
- Viktor Mihajlovski - Viktor Mihajlovski
- Vineeth Vijayan
- Volker Sameske - Volker Sameske
- Wenjia Zhang
- Wolfgang Taphorn - Wolfgang Taphorn
+120
View File
@@ -1,5 +1,125 @@
Release history for s390-tools (MIT version) Release history for s390-tools (MIT version)
-------------------------------------------- --------------------------------------------
* __v2.17.0 (2021-07-07)__
For Linux kernel version: 5.12 / 5.13
Add new tools / libraries:
- hsavmcore: New utility to make the dump process with kdump more efficient
- libkmipclient: Add KMIP client shared library
- libseckey: Add a secure key library
- lshwc: New tool to extract and list complete counter sets
Changes of existing tools:
- genprotimg: Add '--(enable|disable)-pckmo' options
- genprotimg: Add OpenSSL 3.0 support
- genprotimg: Change plaintext control flags defaults so PCKMO functions are allowed
- libutil: Introduce multi-level message logging (util_log)
- libutil: Introduce util_arch module
- udev/dasd: Change DASD udev-rule to set none scheduler
- zdsfs: Add transparent codepage conversion
- zkey: Add support for KMIP-based key management systems
Bug Fixes:
- ttyrun-getty: Avoid conflicts with serial-getty@
- dbginfo: add /proc/kallsyms - refresh zVM, lscpu - fix WORKARCHIVE handling
- dbginfo: add KVM data collection for server and guest - fix lszdev
- genprotimg: Add missing return values in error paths
- zkey: Fix conversion of CCA DATA keys to CCA CIPHER keys
- znetconf: avoid conflict with "chzdev -e"
* __v2.16.0 (2021-02-19)__
For Linux kernel version: 5.10 / 5.11
Add new tool:
- hsci: New tool to manage HSCI (HiperSockets Converged Interfaces)
Changes of existing tools:
- genprotimg: Add host-key document verification support
- genprotimg: boot: Make boot loader -march=z900 compatible
- libekmfweb: Make install directory for shared libraries configurable
- lsdasd: Add FC Endpoint Security information
- make: Add address sanitizer support
- netboot: Add version information to scripts
- netboot: Bump busybox version in pxelinux.0 build
- zdev: Add FC Endpoint Security information for DASD devices
- zdev: Add build option to update initial RAM-disk by default
- zkey-ekmfweb: Avoid sequence number clash when generating keys
- zkey/zkey-ekmfweb: Install KMS plugins into configurable location
- zkey: Add support to store LUKS2 dummy passphrase in key repository
Bug Fixes:
- dasdfmt: Fix segfault when an incorrect option is specified
- genprotimg: Fix several build issues
- genprotimg: Require argument for 'ramdisk' and 'parmfile' options
- zcryptstats: Fix handling of partial results with many domains
- zfcpdbf: Deal with crash 7.2.9 change in caller name formatting
- zipl/boot: Fix memory use after free in stage2
- zipl/boot: Fix potential heap overflow in stage2
- zipl: Fix reading 4k disk's geometry
* __v2.15.1 (2020-10-28)__
For Linux kernel version: 5.9
Changes of existing tools:
- lsstp: Improve wording and fix typos in man page
- zkey: Ensure zkey and friends are skipped with HAVE_OPENSSL=0
- zkey: Add library versioning for libekmfweb and zkey-ekmfweb
- libutil: Add function to determine base device of a partition block device
Bug Fixes:
- dasdfmt: Fix bad file descriptor error when running on symlinks
- libdasd: Fix dasd_get_host_access_count()
- zipl: Fix multivolume dump
- zgetdump: Fix device node determination via sysfs to work with multivolume again
- genprotimg/boot: Fix build by disabling SSP
- zipl/boot: Fix build by disabling SSP
* __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)__ * __v2.13.0 (2020-05-06)__
For Linux kernel version: 5.5 / 5.6 For Linux kernel version: 5.5 / 5.6
+4 -4
View File
@@ -72,7 +72,7 @@ In the examples below we use this fictive identity:
### Setup GitHub and local git ### Setup GitHub and local git
1. Create a fork of this repository by clicking the `Fork` button on the top 1. Create a fork of this repository by clicking the `Fork` button on the top
right of the [s390-tools](https://github.com/ibm-s390-tools/s390-tools) right of the [s390-tools](https://github.com/ibm-s390-linux/s390-tools)
main page main page
2. Clone your forked repository to your local development system 2. Clone your forked repository to your local development system
@@ -84,7 +84,7 @@ In the examples below we use this fictive identity:
s390-tools repository on GitHub s390-tools repository on GitHub
``` ```
$ cd s390-tools $ cd s390-tools
~/s390-tools $ git remote add upstream https://github.com/ibm-s390-tools/s390-tools.git ~/s390-tools $ git remote add upstream https://github.com/ibm-s390-linux/s390-tools.git
``` ```
4. Verify your remotes 4. Verify your remotes
@@ -92,8 +92,8 @@ In the examples below we use this fictive identity:
~/s390-tools $ git remote -v ~/s390-tools $ git remote -v
origin https://github.com/random-developer/s390-tools.git (fetch) origin https://github.com/random-developer/s390-tools.git (fetch)
origin https://github.com/random-developer/s390-tools.git (push) origin https://github.com/random-developer/s390-tools.git (push)
upstream https://github.com/ibm-s390-tools/s390-tools.git (fetch) upstream https://github.com/ibm-s390-linux/s390-tools.git (fetch)
upstream https://github.com/ibm-s390-tools/s390-tools.git (push) upstream https://github.com/ibm-s390-linux/s390-tools.git (push)
``` ```
You now have two remotes: The "origin" remote points to your fork You now have two remotes: The "origin" remote points to your fork
and the "upstream" remote to the official s390-tools repository. and the "upstream" remote to the official s390-tools repository.
+3 -2
View File
@@ -3,13 +3,14 @@ ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/ar
# Include common definitions # Include common definitions
include common.mak include common.mak
LIB_DIRS = libvtoc libutil libzds libdasd libvmdump libccw libvmcp LIB_DIRS = libvtoc libutil libzds libdasd libvmdump libccw libvmcp libekmfweb \
libseckey libkmipclient
TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \ TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
tape390 osasnmpd qetharp ip_watcher qethconf scripts zconf \ tape390 osasnmpd qetharp ip_watcher qethconf scripts zconf \
vmconvert vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \ vmconvert vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \
ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \ ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc zpcictl \ systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc zpcictl \
genprotimg genprotimg lsstp hsci hsavmcore
SUB_DIRS = $(LIB_DIRS) $(TOOL_DIRS) SUB_DIRS = $(LIB_DIRS) $(TOOL_DIRS)
+73 -8
View File
@@ -223,7 +223,8 @@ Package contents
* CPU-measurement facilities (CPU-MF) tools: * CPU-measurement facilities (CPU-MF) tools:
Use the lscpumf tool to display information about the CPU-measurement Use the lscpumf tool to display information about the CPU-measurement
counter and sampling facilities. Use the chcpumf tool to control the counter and sampling facilities. Use the chcpumf tool to control the
sampling facility support. sampling facility support. Use lshwc to extract complete counter sets from
the CPU Measurement Facilities.
* cpacfstats: * cpacfstats:
The cpacfstats tools provide a client/server application set to monitor The cpacfstats tools provide a client/server application set to monitor
@@ -243,6 +244,29 @@ Package contents
Provides simple tools to create a binary that can be used to implement Provides simple tools to create a binary that can be used to implement
simple network boot setups following the PXELINUX conventions. 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.
* libkmipclient:
A shared library that provides an KMIP client to communicate with an KMIP
server. KMIP stands for Key Management Interoperability Protocol, and is an
extensible communication protocol that defines message formats for the
manipulation of cryptographic keys on a key management server.
* hsci:
Manage HiperSockets Converged Interfaces (HSCI).
* hsavmcore:
hsavmcore is designed to make the dump process with kdump more efficient.
With hsavmcore, the HSA memory that contains a part of the production
kernel's memory can be released early in the process. Depending on the size
of the production kernel's memory, writing the dump to persistent storage
can be time consuming and prevent the HSA memory from being reused
by other LPARs.
For more information refer to the following publications: For more information refer to the following publications:
* "Device Drivers, Features, and Commands" chapter "Useful Linux commands" * "Device Drivers, Features, and Commands" chapter "Useful Linux commands"
@@ -261,23 +285,30 @@ build options:
| __LIBRARY__ | __BUILD OPTION__ | __TOOLS__ | | __LIBRARY__ | __BUILD OPTION__ | __TOOLS__ |
|----------------|:------------------:|:-------------------------------------:| |----------------|:------------------:|:-------------------------------------:|
| fuse | `HAVE_FUSE` | cmsfs-fuse, zdsfs, hmcdrvfs, zgetdump | | fuse | `HAVE_FUSE` | cmsfs-fuse, zdsfs, hmcdrvfs, zgetdump,|
| | | hsavmcore |
| zlib | `HAVE_ZLIB` | zgetdump, dump2tar | | zlib | `HAVE_ZLIB` | zgetdump, dump2tar |
| ncurses | `HAVE_NCURSES` | hyptop | | ncurses | `HAVE_NCURSES` | hyptop |
| pfm | `HAVE_PFM` | cpacfstats | | pfm | `HAVE_PFM` | cpacfstats |
| net-snmp | `HAVE_SNMP` | osasnmpd | | net-snmp | `HAVE_SNMP` | osasnmpd |
| glibc-static | `HAVE_LIBC_STATIC` | zfcpdump | | glibc-static | `HAVE_LIBC_STATIC` | zfcpdump |
| openssl | `HAVE_OPENSSL` | genprotimg,zkey | | openssl | `HAVE_OPENSSL` | genprotimg, zkey, libekmfweb, |
| | | libkmipclient |
| cryptsetup | `HAVE_CRYPTSETUP2` | zkey-cryptsetup | | cryptsetup | `HAVE_CRYPTSETUP2` | zkey-cryptsetup |
| json-c | `HAVE_JSONC` | zkey-cryptsetup | | json-c | `HAVE_JSONC` | zkey-cryptsetup, libekmfweb, |
| | | libkmipclient |
| glib2 | `HAVE_GLIB2` | genprotimg | | glib2 | `HAVE_GLIB2` | genprotimg |
| libcurl | `HAVE_LIBCURL` | genprotimg, libekmfweb, libkmipclient |
| libxml2 | `HAVE_LIBXML2` | libkmipclient |
| systemd | `HAVE_SYSTEMD` | hsavmcore |
This table lists additional build or install options: This table lists additional build or install options:
| __COMPONENT__ | __OPTION__ | __TOOLS__ | | __COMPONENT__ | __OPTION__ | __TOOLS__ |
|----------------|:----------------:|:-------------------------------:| |------------------|:----------------------------:|:--------------:|
| dracut | `HAVE_DRACUT` | zdev | | dracut | `HAVE_DRACUT` | zdev |
| initramfs-tools| `HAVE_INITRAMFS` | zdev | | initramfs-tools | `HAVE_INITRAMFS` | zdev |
| | `ZDEV_ALWAYS_UPDATE_INITRD` | zdev |
The s390-tools build process uses "pkg-config" if available and hard-coded The s390-tools build process uses "pkg-config" if available and hard-coded
compiler and linker options otherwise. compiler and linker options otherwise.
@@ -368,6 +399,17 @@ the different tools are provided:
Distributors with different boot or RAM-disk mechanisms should provide Distributors with different boot or RAM-disk mechanisms should provide
a custom zdev-root-update helper script. a custom zdev-root-update helper script.
- `ZDEV_ALWAYS_UPDATE_INITRD=1` upon modification of any persistent device
configuration, chzdev updates the initial RAM-disk by default, without any
additional user interaction.
For some distributions, all the configuration attributes must be copied to
the initial RAM-disk. Because the device configuration directives applied
in the initial RAM-disk takes precedence over those stored in the root file-
system. This copying is done usually by explicitly invoking a command. This
build option makes it user-friendly and does this copying without any manual
intervention.
Some functions of zdev require that the following programs are available: Some functions of zdev require that the following programs are available:
- modprobe (kmod) - modprobe (kmod)
@@ -397,3 +439,26 @@ the different tools are provided:
tool must be added to this group. The owner of the default key repository 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 '/etc/zkey/repository' must be set to group 'zkeyadm' with write permission
for this group. 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.
* hsavmcore:
For building the hsavmcore tool you need fuse version 2.6 and optionally
systemd which is enabled by default, to disable systemd support,
add `HAVE_SYSTEMD=0` to the make invocation.
Tip: you may skip the hsavmcore build by adding `HAVE_FUSE=0`
to the make invocation.
* libkmipclient:
For building the libkmipclient 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), libxml2 version 2.9.10 or newer
(libxml2-devel.rpm), and libcurl version 7.59 or newer (libcurl-devel.rpm).
Tip: you may skip the libkmipclient build by adding `HAVE_OPENSSL=0`,
`HAVE_JSONC=0`, `HAVE_LIBXML2=0`, or `HAVE_LIBCURL=0` to the make invocation.
+4 -4
View File
@@ -299,7 +299,7 @@ static unsigned long dec_to_hex(unsigned long long num)
{ {
unsigned long res; unsigned long res;
asm volatile("cvb %0,%1" : "=d" (res) : "m" (num)); asm volatile("cvb %0,%1" : "=d" (res) : "Q" (num));
return res & 0xffffffff; return res & 0xffffffff;
} }
@@ -307,7 +307,7 @@ static unsigned int hex_to_dec(unsigned int num)
{ {
unsigned long long res; unsigned long long res;
asm volatile("cvd %1,%0" : "=m" (res) : "d" (num)); asm volatile("cvd %1,%0" : "=Q" (res) : "d" (num));
return res & 0xffffffff; return res & 0xffffffff;
} }
@@ -2050,7 +2050,7 @@ static int update_dir_levels(int blocks)
if (blocks < 2) if (blocks < 2)
return 0; return 0;
while (blocks / (PTRS_PER_BLOCK + 1)) { while (blocks / PTRS_PER_BLOCK) {
levels++; levels++;
blocks /= PTRS_PER_BLOCK; blocks /= PTRS_PER_BLOCK;
} }
@@ -3103,7 +3103,7 @@ static void update_levels(struct file *f)
return; return;
} }
while (blocks / (per_block + 1)) { while (blocks / per_block) {
levels++; levels++;
blocks /= per_block; blocks /= per_block;
} }
+48 -5
View File
@@ -5,7 +5,7 @@ COMMON_INCLUDED = true
# The variable "DISTRELEASE" should be overwritten in rpm spec files with: # The variable "DISTRELEASE" should be overwritten in rpm spec files with:
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}" # "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
VERSION = 2 VERSION = 2
RELEASE = 13 RELEASE = 17
PATCHLEVEL = 0 PATCHLEVEL = 0
DISTRELEASE = build-$(shell date +%Y%m%d) DISTRELEASE = build-$(shell date +%Y%m%d)
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE) S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
@@ -106,6 +106,25 @@ endif
DEFAULT_CPPFLAGS = -D_GNU_SOURCE DEFAULT_CPPFLAGS = -D_GNU_SOURCE
DEFAULT_LDFLAGS = -rdynamic DEFAULT_LDFLAGS = -rdynamic
ifeq ("${ASAN}","1")
DEFAULT_CFLAGS += -fsanitize=address -fno-omit-frame-pointer
DEFAULT_LDFLAGS += -fsanitize=address
endif
#
# Check for header prerequisite
#
# $1: Name of include file to check
# $2: Additional compiler & linker options (optional)
#
# Returns "yes" on success and nothing otherwise
#
define check_header_prereq
$(shell printf "#include <%s>\n int main(void) {return 0;}" $1 | \
( $(CC) $(filter-out --coverage, $(ALL_CFLAGS)) $(ALL_CPPFLAGS) \
$2 -o /dev/null -xc - ) >/dev/null 2>&1 && echo -n yes)
endef
# #
# Check for build dependency # Check for build dependency
# #
@@ -163,6 +182,7 @@ USRSBINDIR = $(INSTALLDIR)/usr/sbin
USRBINDIR = $(INSTALLDIR)/usr/bin USRBINDIR = $(INSTALLDIR)/usr/bin
BINDIR = $(INSTALLDIR)/sbin BINDIR = $(INSTALLDIR)/sbin
LIBDIR = $(INSTALLDIR)/lib LIBDIR = $(INSTALLDIR)/lib
USRLIB64DIR = $(INSTALLDIR)/usr/lib64
SYSCONFDIR = $(INSTALLDIR)/etc SYSCONFDIR = $(INSTALLDIR)/etc
MANDIR = $(INSTALLDIR)/usr/share/man MANDIR = $(INSTALLDIR)/usr/share/man
VARDIR = $(INSTALLDIR)/var VARDIR = $(INSTALLDIR)/var
@@ -172,14 +192,24 @@ ZFCPDUMP_DIR = $(TOOLS_LIBDIR)/zfcpdump
# Systemd support files are installed only if a directory is specified # Systemd support files are installed only if a directory is specified
# for SYSTEMDSYSTEMUNITDIR (e.g. /lib/systemd/system) # for SYSTEMDSYSTEMUNITDIR (e.g. /lib/systemd/system)
SYSTEMDSYSTEMUNITDIR = SYSTEMDSYSTEMUNITDIR =
USRINCLUDEDIR = $(INSTALLDIR)/usr/include
ZKEYKMSPLUGINDIR = $(USRLIB64DIR)/zkey
ifeq ($(LIBDIR),$(INSTALLDIR)/lib)
SOINSTALLDIR = $(USRLIB64DIR)
else
SOINSTALLDIR = $(LIBDIR)
endif
INSTDIRS = $(USRSBINDIR) $(USRBINDIR) $(BINDIR) $(LIBDIR) $(MANDIR) \ INSTDIRS = $(USRSBINDIR) $(USRBINDIR) $(BINDIR) $(LIBDIR) $(MANDIR) \
$(SYSCONFDIR) $(SYSCONFDIR)/sysconfig \ $(SYSCONFDIR) $(SYSCONFDIR)/sysconfig \
$(TOOLS_LIBDIR) $(TOOLS_DATADIR) \ $(TOOLS_LIBDIR) $(TOOLS_DATADIR) \
$(ZFCPDUMP_DIR) $(SYSTEMDSYSTEMUNITDIR) $(ZFCPDUMP_DIR) $(SYSTEMDSYSTEMUNITDIR) \
$(USRLIB64DIR) $(USRINCLUDEDIR) $(ZKEYKMSPLUGINDIR) \
$(SOINSTALLDIR)
OWNER = $(shell id -un) OWNER = $(shell id -un)
GROUP = $(shell id -gn) GROUP = $(shell id -gn)
export INSTALLDIR BINDIR LIBDIR MANDIR OWNER GROUP export INSTALLDIR BINDIR LIBDIR USRLIB64DIR MANDIR OWNER GROUP
# Special defines for zfcpdump # Special defines for zfcpdump
ZFCPDUMP_IMAGE = zfcpdump-image ZFCPDUMP_IMAGE = zfcpdump-image
@@ -261,6 +291,7 @@ help:
@echo ' G=1 Build with gcov to collect code coverage data' @echo ' G=1 Build with gcov to collect code coverage data'
@echo ' V=1 Generate verbose build output' @echo ' V=1 Generate verbose build output'
@echo ' W=1 Build with higher warning level' @echo ' W=1 Build with higher warning level'
@echo ' ASAN=1 Build with address sanitizer'
@echo '' @echo ''
@echo 'EXAMPLES' @echo 'EXAMPLES'
@echo ' # make clean all D=1 W=1 -j' @echo ' # make clean all D=1 W=1 -j'
@@ -339,6 +370,18 @@ $(rootdir)/libvmcp/libvmcp.a: $(rootdir)/libvmcp
$(MAKE) -C $(rootdir)/libvmcp/ libvmcp.a $(MAKE) -C $(rootdir)/libvmcp/ libvmcp.a
.PHONY: $(rootdir)/libvmcp .PHONY: $(rootdir)/libvmcp
$(rootdir)/libekmfweb/libekmfweb.so: $(rootdir)/libekmfweb
$(MAKE) -C $(rootdir)/libekmfweb/ libekmfweb.so
.PHONY: $(rootdir)/libekmfweb
$(rootdir)/libseckey/libseckey.a: $(rootdir)/libseckey
$(MAKE) -C $(rootdir)/libseckey/ libseckey.a
.PHONY: $(rootdir)/libseckey
$(rootdir)/libkmipclient/libkmipclient.so: $(rootdir)/libkmipclient
$(MAKE) -C $(rootdir)/libkmipclient/ libkmipclient.so
.PHONY: $(rootdir)/libkmipclient
$(rootdir)/zipl/boot/data.o: $(rootdir)/zipl/boot/data.o:
$(MAKE) -C $(rootdir)/zipl/boot/ data.o $(MAKE) -C $(rootdir)/zipl/boot/ data.o
@@ -359,9 +402,9 @@ install: install_echo install_dirs
clean_echo: clean_echo:
$(call echocmd," CLEAN ") $(call echocmd," CLEAN ")
clean_gcov: clean_gcov:
rm -f *.gcda *.gcno *.gcov rm -f -- *.gcda *.gcno *.gcov
clean_dep: clean_dep:
rm -f .*.o.d rm -f -- .*.o.d
clean: clean_echo clean_gcov clean_dep clean: clean_echo clean_gcov clean_dep
endif endif
+2 -21
View File
@@ -2,28 +2,10 @@ include ../common.mak
ALL_CPPFLAGS += -DVERSION=$(VERSION) ALL_CPPFLAGS += -DVERSION=$(VERSION)
all: cpacfstats cpacfstatsd
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
cpacfstatsd: cpacfstatsd.o stats_sock.o perf_crypto.o 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 cpacfstats: cpacfstats.o stats_sock.o
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@ $(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
@@ -34,7 +16,6 @@ install: all
$(INSTALL) -m 644 cpacfstatsd.8 $(DESTDIR)$(MANDIR)/man8 $(INSTALL) -m 644 cpacfstatsd.8 $(DESTDIR)$(MANDIR)/man8
$(INSTALL) -m 644 cpacfstats.1 $(DESTDIR)$(MANDIR)/man1 $(INSTALL) -m 644 cpacfstats.1 $(DESTDIR)$(MANDIR)/man1
endif
clean: clean:
rm -f *.o *~ cpacfstatsd cpacfstats rm -f *.o *~ cpacfstatsd cpacfstats
+26 -19
View File
@@ -1,6 +1,6 @@
.\" cpacfstats.1 .\" cpacfstats.1
.\" .\"
.\" Copyright IBM Corp. 2015, 2017 .\" Copyright IBM Corp. 2015, 2020
.\" s390-tools is free software; you can redistribute it and/or modify .\" s390-tools is free software; you can redistribute it and/or modify
.\" it under the terms of the MIT license. See LICENSE for details. .\" 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. Display version and copyright information for the command.
.TP .TP
\fB\-e\fR or \fB\-\-enable\fR [counter] \fB\-e\fR or \fB\-\-enable\fR [counter]
Enable one or all CPACF performance counters. The optional counter argument Enable one or all CPACF performance counters. The optional counter
can be one of: \fBdes\fR, \fBaes\fR, \fBsha\fR, \fBprng\fR or \fBall\fR. If argument can be one of: \fBdes\fR, \fBaes\fR, \fBsha\fR, \fBprng\fR,
the counter argument is omitted, all performance counters are \fBecc\fR, or \fBall\fR. If the counter argument is omitted, all
enabled. Enabling a counter does not reset it. New events are added to the performance counters are enabled. Enabling a counter does not reset
current counter value. it. New events are added to the current counter value.
.TP .TP
\fB\-d\fR or \fB\-\-disable\fR [counter] \fB\-d\fR or \fB\-\-disable\fR [counter]
Disable one or all CPACF performance counters. The optional 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 argument can be one of: \fBdes\fR, \fBaes\fR, \fBsha\fR, \fBprng\fR,
\fBall\fR. If the counter argument is omitted, all performance counters \fBecc\fR, or \fBall\fR. If the counter argument is omitted, all
are disabled. Disabling a counter does not reset it. The counter value is performance counters are disabled. Disabling a counter does not reset
preserved when a counter is disabled, and counting will resume using the it. The counter value is preserved when a counter is disabled, and
preserved value when the counter is re-enabled. counting will resume using the preserved value when the counter is
re-enabled.
.TP .TP
\fB\-r\fR or \fB\-\-reset\fR [counter] \fB\-r\fR or \fB\-\-reset\fR [counter]
Reset one or all CPACF performance counters. The optional 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 argument can be one of: \fBdes\fR, \fBaes\fR, \fBsha\fR, \fBprng\fR,
\fBall\fR. If the counter argument is omitted, all performance counters are \fBecc\fR, or \fBall\fR. If the counter argument is omitted, all
reset to 0. performance counters are reset to 0.
.TP .TP
\fB\-p\fR or \fB\-\-print\fR [counter] \fB\-p\fR or \fB\-\-print\fR [counter]
Display the value of one or all CPACF performance counters. The optional Display the value of one or all CPACF performance counters. The
counter argument can be one of: \fBdes\fR, \fBaes\fR, \fBsha\fR, \fBprng\fR optional counter argument can be one of: \fBdes\fR, \fBaes\fR,
or \fBall\fR. If the counter argument is omitted or if there is no \fBsha\fR, \fBprng\fR, \fBecc\fR, or \fBall\fR. If the counter
argument, all performance counters are displayed. argument is omitted or if there is no argument, all performance
counters are displayed.
.TP .TP
The default command is --print all. 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 memory. The application prints a message with the details of the error and
the errno value. 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 .SH SEE ALSO
cpacfstatsd (8) .BR cpacfstatsd (8)
+5 -2
View File
@@ -3,7 +3,7 @@
* *
* cpacfstats client implementation * 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 * s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details. * 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-d, --disable [counter] Disable one or all counters\n"
"\t-r, --reset [counter] Reset one or all counter values\n" "\t-r, --reset [counter] Reset one or all counter values\n"
"\t-p, --print [counter] Print 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[] = { static const char *const counter_str[] = {
[DES_FUNCTIONS] = "des", [DES_FUNCTIONS] = "des",
[AES_FUNCTIONS] = "aes", [AES_FUNCTIONS] = "aes",
[SHA_FUNCTIONS] = "sha", [SHA_FUNCTIONS] = "sha",
[PRNG_FUNCTIONS] = "rng", [PRNG_FUNCTIONS] = "rng",
[ECC_FUNCTIONS] = "ecc",
[ALL_COUNTER] = "all" [ALL_COUNTER] = "all"
}; };
@@ -98,6 +99,8 @@ static void print_answer(int ctr, int state, uint64_t value)
counter_str[ctr], state); counter_str[ctr], state);
else if (state == DISABLED) else if (state == DISABLED)
printf(" %s counter: disabled\n", counter_str[ctr]); printf(" %s counter: disabled\n", counter_str[ctr]);
else if (state == UNSUPPORTED)
printf(" %s counter: unsupported\n", counter_str[ctr]);
else else
printf(" %s counter: %"PRIu64"\n", counter_str[ctr], value); printf(" %s counter: %"PRIu64"\n", counter_str[ctr], value);
} }
+6 -3
View File
@@ -3,7 +3,7 @@
* *
* common function prototypes and definitions * 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 * s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details. * it under the terms of the MIT license. See LICENSE for details.
@@ -14,7 +14,7 @@
#include "lib/zt_common.h" #include "lib/zt_common.h"
#define COPYRIGHT "Copyright IBM Corp. 2015, 2017" #define COPYRIGHT "Copyright IBM Corp. 2015, 2020"
int eprint(const char *format, ...); int eprint(const char *format, ...);
@@ -27,6 +27,7 @@ enum ctr_e {
AES_FUNCTIONS, AES_FUNCTIONS,
SHA_FUNCTIONS, SHA_FUNCTIONS,
PRNG_FUNCTIONS, PRNG_FUNCTIONS,
ECC_FUNCTIONS,
ALL_COUNTER ALL_COUNTER
}; };
@@ -44,7 +45,8 @@ enum cmd_e {
enum state_e { enum state_e {
DISABLED = 0, 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_disable_ctr(enum ctr_e ctr);
int perf_reset_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_read_ctr(enum ctr_e ctr, uint64_t *value);
int perf_ecc_supported(void);
#endif #endif
+7 -4
View File
@@ -1,6 +1,6 @@
.\" cpacfstatsd.8 .\" cpacfstatsd.8
.\" .\"
.\" Copyright IBM Corp. 2015, 2017 .\" Copyright IBM Corp. 2015, 2020
.\" s390-tools is free software; you can redistribute it and/or modify .\" s390-tools is free software; you can redistribute it and/or modify
.\" it under the terms of the MIT license. See LICENSE for details. .\" it under the terms of the MIT license. See LICENSE for details.
.\" .\"
@@ -37,7 +37,10 @@ config option enabled.
.P .P
- Libpfm version 4 or higher is needed to successfully run the daemon. - Libpfm version 4 or higher is needed to successfully run the daemon.
.P .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 .P
- The daemon requires root privileges to interact with the performance - The daemon requires root privileges to interact with the performance
ioctls of the kernel. ioctls of the kernel.
@@ -47,7 +50,7 @@ restart the daemon to ensure correct summing of the per-CPU performance
counters. counters.
The starting daemon first checks for any stale pid file 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 file belongs to an active process, an error message is printed to the
console and the program terminates. 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. The daemon could not be set to run in the background.
.SH SEE ALSO .SH SEE ALSO
cpacfstats (1) .BR cpacfstats (1)
+20 -13
View File
@@ -94,20 +94,24 @@ static int do_enable(int s, enum ctr_e ctr)
for (i = 0; i < ALL_COUNTER; i++) { for (i = 0; i < ALL_COUNTER; i++) {
if (i == (int) ctr || ctr == ALL_COUNTER) { if (i == (int) ctr || ctr == ALL_COUNTER) {
if (!ctr_state[i]) { if (ctr_state[i] == DISABLED) {
rc = perf_enable_ctr(i); rc = perf_enable_ctr(i);
if (rc != 0) { if (rc != 0) {
send_answer(s, i, rc, 0); send_answer(s, i, rc, 0);
break; break;
} }
ctr_state[i] = 1; ctr_state[i] = ENABLED;
} }
rc = perf_read_ctr(i, &value); if (ctr_state[i] == UNSUPPORTED) {
if (rc != 0) { send_answer(s, i, UNSUPPORTED, 0);
send_answer(s, i, rc, 0); } else {
break; 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++) { for (i = 0; i < ALL_COUNTER; i++) {
if (i == (int) ctr || ctr == ALL_COUNTER) { if (i == (int) ctr || ctr == ALL_COUNTER) {
if (ctr_state[i]) { if (ctr_state[i] == ENABLED) {
rc = perf_disable_ctr(i); rc = perf_disable_ctr(i);
if (rc != 0) { if (rc != 0) {
send_answer(s, i, 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; 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++) { for (i = 0; i < ALL_COUNTER; i++) {
if (i == (int) ctr || ctr == ALL_COUNTER) { if (i == (int) ctr || ctr == ALL_COUNTER) {
if (ctr_state[i]) { if (ctr_state[i] == ENABLED) {
rc = perf_reset_ctr(i); rc = perf_reset_ctr(i);
if (rc != 0) { if (rc != 0) {
send_answer(s, i, 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); send_answer(s, i, ENABLED, 0);
} else { } 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++) { for (i = 0; i < ALL_COUNTER; i++) {
if (i == (int) ctr || ctr == ALL_COUNTER) { if (i == (int) ctr || ctr == ALL_COUNTER) {
if (ctr_state[i]) { if (ctr_state[i] == ENABLED) {
rc = perf_read_ctr(i, &value); rc = perf_read_ctr(i, &value);
if (rc != 0) { if (rc != 0) {
send_answer(s, i, 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); send_answer(s, i, ENABLED, value);
} else { } 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); atexit(perf_close);
if (!perf_ecc_supported())
ctr_state[ECC_FUNCTIONS] = UNSUPPORTED;
sfd = open_socket(SERVER); sfd = open_socket(SERVER);
if (sfd < 0) { if (sfd < 0) {
eprint("Couldn't initialize server socket\n"); eprint("Couldn't initialize server socket\n");
+116 -38
View File
@@ -3,36 +3,39 @@
* *
* low level perf functions * 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 * s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details. * it under the terms of the MIT license. See LICENSE for details.
*/ */
#include <asm/unistd.h>
#include <errno.h> #include <errno.h>
#include <getopt.h> #include <getopt.h>
#define __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS
#include <inttypes.h> #include <inttypes.h>
#include <perfmon/perf_event.h> #include <limits.h>
#include <perfmon/pfmlib.h> #include <linux/perf_event.h>
#include <perfmon/pfmlib_perf_event.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/ioctl.h>
#include <unistd.h> #include <unistd.h>
#include "cpacfstats.h" #include "cpacfstats.h"
/* correlation between counter and perf counter string */ /* correlation between counter and perf counter string */
static const struct { static const struct {
char pfm_name[80]; char pmu[20];
char pfm_name[60];
enum ctr_e ctr; enum ctr_e ctr;
} pmf_counter_name[ALL_COUNTER] = { } pmf_counter_name[ALL_COUNTER] = {
{"cpum_cf::DEA_FUNCTIONS", DES_FUNCTIONS}, {"cpum_cf", "DEA_FUNCTIONS", DES_FUNCTIONS},
{"cpum_cf::AES_FUNCTIONS", AES_FUNCTIONS}, {"cpum_cf", "AES_FUNCTIONS", AES_FUNCTIONS},
{"cpum_cf::SHA_FUNCTIONS", SHA_FUNCTIONS}, {"cpum_cf", "SHA_FUNCTIONS", SHA_FUNCTIONS},
{"cpum_cf::PRNG_FUNCTIONS", PRNG_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 *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 perf_init(void)
{ {
int i, cpus, ctr, cpu, ec, *fds; int i, cpus, ctr, cpu, *fds;
memset(ctr_fds, 0, sizeof(ctr_fds)); memset(ctr_fds, 0, sizeof(ctr_fds));
/* initialize performance monitoring library */ /* initialize performance monitoring library */
ec = pfm_initialize(); if (!perf_supported()) {
if (ec != PFM_SUCCESS) { eprint("Performance counter not supported");
eprint("Pfm_initialize() returned with failure (%d:%s)\n",
ec, pfm_strerror(ec));
return -1; 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 */ /* get number of logical processors */
cpus = sysconf(_SC_NPROCESSORS_ONLN); cpus = sysconf(_SC_NPROCESSORS_ONLN);
/* for each counter */ /* for each counter */
for (ctr = 0; ctr < ALL_COUNTER; ctr++) { 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 * allocate an array of ints to store for each CPU
* one filedescriptor + a terminating 0 * one filedescriptor + a terminating 0
@@ -88,37 +170,28 @@ int perf_init(void)
ctr_fds[ctr] = fds; 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++) { for (cpu = 0; cpu < cpus; cpu++) {
pfm_perf_encode_arg_t pfm_arg;
struct perf_event_attr pfm_event; struct perf_event_attr pfm_event;
int fd; int fd;
memset(&pfm_arg, 0, sizeof(pfm_arg));
memset(&pfm_event, 0, sizeof(pfm_event)); memset(&pfm_event, 0, sizeof(pfm_event));
pfm_arg.attr = &pfm_event;
pfm_arg.size = sizeof(pfm_arg);
pfm_event.size = sizeof(pfm_event); pfm_event.size = sizeof(pfm_event);
if (perf_event_encode(&pfm_event,
/* search for the counter's corresponding pfm name */ pmf_counter_name[i].pmu,
for (i = ALL_COUNTER-1; i >= 0; i--) pmf_counter_name[i].pfm_name)) {
if ((int) pmf_counter_name[i].ctr == ctr) eprint("Failed to initialize counter %s for pmu %s\n",
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",
pmf_counter_name[i].pfm_name, pmf_counter_name[i].pfm_name,
ec, pfm_strerror(ec)); pmf_counter_name[i].pmu);
return -1; return -1;
} }
@@ -257,3 +330,8 @@ int perf_read_ctr(enum ctr_e ctr, uint64_t *value)
return rc; return rc;
} }
int perf_ecc_supported(void)
{
return ecc_supported;
}
+15 -53
View File
@@ -1,67 +1,29 @@
#!/usr/bin/make -f
include ../common.mak include ../common.mak
BIN_FILES = lscpumf chcpumf lshwc
MAN_FILES = lscpumf.1 chcpumf.8 lshwc.1
CPUMF_DATADIR = $(TOOLS_DATADIR)/cpumf all: $(BIN_FILES)
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
MAN_FILES = lscpumf.1 chcpumf.8
all: libs = $(rootdir)/libutil/libutil.a
scripts: $(USRBIN_SCRIPTS) $(USRSBIN_SCRIPTS) $(LIB_FILES) lscpumf: lscpumf.o $(libs)
chmod +x $(USRBIN_SCRIPTS) $(USRSBIN_SCRIPTS) $(LIB_FILES) chcpumf: chcpumf.o $(libs)
lshwc: lshwc.o $(libs)
check: install: all install-man
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man8
install: scripts install-man for binf in $(BIN_FILES); do \
for prg in $(USRBIN_SCRIPTS); do \ $(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 $$binf $(DESTDIR)$(BINDIR); \
$(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) ; \
done done
clean:
rm -f *.o *~ $(BIN_FILES) core
install-man: install-man:
for man in $(MAN_FILES); do \ for man in $(MAN_FILES); do \
msection=`echo $$man |sed 's/.*\.\([1-9]\)$$/man\1/'` ; \ msection=`echo $$man |sed 's/.*\.\([1-9]\)$$/man\1/'` ; \
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 -D man/$$man $(DESTDIR)$(MANDIR)/$$msection/$$man ; \ $(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 -D man/$$man $(DESTDIR)$(MANDIR)/$$msection/$$man ; \
done done
man2pdf: .PHONY: all install clean
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
-182
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__
-489
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__
-387
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__
+197
View File
@@ -0,0 +1,197 @@
/*
* 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 void read_sfb(unsigned long *min, unsigned long *max)
{
unsigned long cur_min_sdb, cur_max_sdb;
FILE *fp;
if (geteuid())
errx(EXIT_FAILURE, "Must run as root");
fp = fopen(PERF_SFB_SIZE, "r");
if (!fp)
err(EXIT_FAILURE, PERF_SFB_SIZE);
if (fscanf(fp, "%ld,%ld", &cur_min_sdb, &cur_max_sdb) != 2) {
fclose(fp);
errx(EXIT_FAILURE, "Can not parse file " PERF_SFB_SIZE);
} else {
if (*min == 0)
*min = cur_min_sdb;
if (*max == 0)
*max = cur_max_sdb;
}
fclose(fp);
if (*min >= *max)
errx(EXIT_FAILURE,
"The specified maximum must be greater than the minimum");
}
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)
err(EXIT_FAILURE, PERF_SFB_SIZE);
snprintf(text, sizeof text, "%ld,%ld", min, max);
len = strlen(text) + 1;
if (fwrite(text, 1, len, fp) != len) {
warn(PERF_SFB_SIZE);
rc = EXIT_FAILURE;
}
if (fclose(fp)) {
warn(PERF_SFB_SIZE);
rc = EXIT_FAILURE;
}
if (verbose && rc != EXIT_FAILURE)
warnx("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)
errx(EXIT_FAILURE,
"The specified number(s) are not valid");
max_sdb = new;
action = 1;
break;
case 'm':
new = parse_buffersize(optarg);
if (new < 1)
errx(EXIT_FAILURE,
"The specified number(s) are not valid");
min_sdb = new;
action = 1;
break;
case 'V':
verbose = 1;
break;
default:
util_opt_print_parse_error(opt, argv);
exit(EXIT_FAILURE);
}
}
if (!action)
errx(EXIT_FAILURE, "You must specify a valid option");
return action;
}
int main(int argc, char **argv)
{
struct stat sbuf;
util_prg_init(&prg);
util_opt_init(opt_vec, NULL);
parse_args(argc, argv);
if (stat(PERF_PATH PERF_SF, &sbuf))
errx(EXIT_FAILURE,
"No CPU-measurement sampling facility detected");
read_sfb(&min_sdb, &max_sdb);
return write_sfb(min_sdb, max_sdb);
}
-60
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
.
-40
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
.
-100
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
.
-33
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.
.
-114
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
.
-373
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
.
-357
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
.
-376
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
.
-146
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
.
-230
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
.
-33
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',
};
-15
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)
.
+18
View File
@@ -0,0 +1,18 @@
/*
* 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"
#endif
+3070
View File
File diff suppressed because it is too large Load Diff
+775
View File
@@ -0,0 +1,775 @@
/* Copyright IBM Corp. 2021
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
/* CPU Measurements counter facility counter sets can be extracted by a
* device driver accessible by opening device /dev/hwctr.
* This program extracts complete counter set using this device.
* Counter sets are per CPU, the interface allows to specify counter sets
* for individual CPUs. The supported flags are executed from left to
* right, the first error encountered stops the execution of the program.
*/
#include <ctype.h>
#include <dirent.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/limits.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/user.h>
#include <time.h>
#include <unistd.h>
#include "lib/util_opt.h"
#include "lib/util_prg.h"
#include "lib/util_base.h"
#include "lib/util_path.h"
#include "lib/util_scandir.h"
#include "lib/util_libc.h"
#include "lshwc.h"
#define SERVICELEVEL "/proc/service_levels"
#define CPUS_ONLINE "/sys/devices/system/cpu/online"
#define CPUS_POSSIBLE "/sys/devices/system/cpu/possible"
#define CPUS_KERNELMAX "/sys/devices/system/cpu/kernel_max"
#define MAXCTRS 512
static const unsigned int ioctlsleep = 60;
static unsigned int read_interval = ioctlsleep, cfvn, csvn, authorization;
static unsigned long loop_count = 1;
static unsigned char *ioctlbuffer;
static bool allcpu;
static unsigned int max_possible_cpus; /* No of possible CPUs */
struct ctrname { /* List of defined counters */
char *name; /* Counter name */
bool hitcnt; /* Counter number read from ioctl() */
unsigned long total; /* Total counter value */
unsigned long *ccv; /* Per CPU counter value */
} ctrname[MAXCTRS];
/* Open file and extract counter number */
static int read_counter(const char *p)
{
FILE *fp = fopen(p, "r");
int rc = 0, ctr;
if (fp) {
rc = fscanf(fp, "event=%x", &ctr);
fclose(fp);
}
return rc == 1 ? ctr : -EINVAL;
}
static int add_countername(char *name, int nr)
{
ctrname[nr].name = strdup(name);
return ctrname[nr].name ? 0 : -ENOMEM;
}
static bool read_counternames(void)
{
struct dirent **namelist = NULL;
int i, ctr = 0, count = 0;
char *path, *ctrpath;
path = util_path_sysfs("/bus/event_source/devices/cpum_cf/events/");
count = util_scandir(&namelist, alphasort, path, "[^.]");
if (count <= 0) {
warnx("Cannot open %s", path);
free(path);
return false;
}
for (i = 0; i < count && ctr >= 0; i++) {
util_asprintf(&ctrpath, "%s/%s", path, namelist[i]->d_name);
ctr = read_counter(ctrpath);
free(ctrpath);
if (ctr >= 0)
ctr = add_countername(namelist[i]->d_name, ctr);
}
if (ctr < 0)
warnx("Cannot parse %s", path);
util_scandir_free(namelist, count);
free(path);
return ctr < 0 ? false : true;
}
static void free_counternames(void)
{
for (size_t i = 0; i < ARRAY_SIZE(ctrname); ++i) {
free(ctrname[i].name);
free(ctrname[i].ccv);
}
}
static struct check_result {
bool cpu_pos; /* CPU Number possible */
bool cpu_req; /* CPU Number requested */
bool cpu_hit; /* CPU Number received */
unsigned char sets_req; /* Counters sets requested */
unsigned char sets_hit; /* Counters sets received */
} *check;
static bool check_set(unsigned long a, unsigned long b, unsigned long sets)
{
if (a > b)
return false;
for (; a <= b; ++a) {
if (a >= max_possible_cpus || !check[a].cpu_pos)
return false;
check[a].cpu_req = true;
check[a].sets_req = sets;
}
return true;
}
/*
* Functions to parse command line parameters
* Convert a number from ascii to int.
*/
static unsigned long getnumber(char *word, char stopchar)
{
unsigned long no;
char *endp;
no = strtoul(word, &endp, 0);
if (*endp != stopchar)
errx(EXIT_FAILURE, "Invalid parameter %s", word);
return no;
}
/* Remove all whitespace from string. */
static void kill_whitespace(char *s)
{
char *cp = s;
for (; *s != '\0'; ++s) {
if (isspace(*s))
continue;
if (isprint(*s))
*cp++ = *s;
}
*cp = '\0';
}
/* Read file to get all online CPUs */
static bool get_cpus(char *file, char *buf, size_t bufsz)
{
char fmt[16];
FILE *slp;
int rc;
slp = fopen(file, "r");
if (!slp) {
warnx("Cannot open %s", file);
return false;
}
snprintf(fmt, sizeof(fmt), "%%%zus", bufsz - 1);
rc = fscanf(slp, fmt, buf);
fclose(slp);
if (rc != 1)
warnx("Cannot parse %s", file);
return rc == 1 ? true : false;
}
/* Parse counter set specification */
static unsigned long parse_ctrset(char *cp)
{
unsigned long x = 0;
for (; *cp; ++cp) {
switch (tolower(*cp)) {
case 'b':
x |= S390_HWCTR_BASIC;
break;
case 'c':
x |= S390_HWCTR_CRYPTO;
break;
case 'e':
x |= S390_HWCTR_EXT;
break;
case 'm':
x |= S390_HWCTR_MT_DIAG;
break;
case 'p':
case 'u':
x |= S390_HWCTR_USER;
break;
case 'a':
x |= S390_HWCTR_ALL;
break;
default:
errx(EXIT_FAILURE,
"Invalid counter set specification '%c'", *cp);
}
}
return x;
}
static char *show_ctrset(unsigned long set)
{
static char text[16];
int i = 0;
if (set & S390_HWCTR_BASIC)
text[i++] = 'B';
if (set & S390_HWCTR_CRYPTO)
text[i++] = 'C';
if (set & S390_HWCTR_EXT)
text[i++] = 'E';
if (set & S390_HWCTR_MT_DIAG)
text[i++] = 'M';
if (set & S390_HWCTR_USER)
text[i++] = 'U';
text[i] = '\0';
return text;
}
/* Parse CPU list and counter sets */
static void parse_cpulist(char *parm, struct s390_hwctr_start *start)
{
__u64 *words = start->cpumask;
unsigned long i, no_a, no_b;
char *cp, *tokens[16]; /* Used to parse command line params */
char cpubuf[256];
start->data_bytes = 0;
if (parm)
kill_whitespace(parm);
if (!parm || *parm == ':') {
/* No CPU list or just counter sets */
if (!get_cpus(CPUS_ONLINE, cpubuf, sizeof(cpubuf)))
exit(EXIT_FAILURE);
if (parm)
strcat(cpubuf, parm);
parm = cpubuf;
}
cp = strchr(parm, ':');
if (cp) { /* Handle counter set */
*cp = '\0';
start->counter_sets = parse_ctrset(++cp);
} else {
start->counter_sets = S390_HWCTR_ALL;
}
/* Check with authorized counter sets */
if ((start->counter_sets & authorization) != start->counter_sets) {
unsigned int noton = ~(start->counter_sets & authorization);
start->counter_sets &= authorization;
if (!start->counter_sets)
errx(EXIT_FAILURE, "No counter sets are authorized");
warnx("One or more counter sets are not authorized: %s",
show_ctrset(noton));
}
for (i = 0; i < ARRAY_SIZE(tokens) && (tokens[i] = strtok(parm, ",")) != 0;
++i, parm = 0) {
cp = strchr(tokens[i], '-'); /* Range character? */
if (cp) {
no_a = getnumber(tokens[i], *cp);
no_b = getnumber(++cp, '\0');
} else {
no_b = getnumber(tokens[i], '\0');
no_a = no_b;
}
if (!check_set(no_a, no_b, start->counter_sets))
errx(EXIT_FAILURE, "Invalid CPU list %s", tokens[i]);
}
/* Convert the CPU list to a bitmask for kernel cpumask_t */
for (i = 0, no_b = 0; i < max_possible_cpus; ++i) {
if (check[i].cpu_req) {
no_a = i % __BITS_PER_LONG;
no_b = i / __BITS_PER_LONG;
words[no_b] |= 1ULL << no_a;
}
}
/* no_b is highest used index, swap array */
start->cpumask_len = (no_b + 1) * 8;
for (no_a = 0; no_a < no_b; ++no_a, --no_b) {
__u64 tmp = words[no_a];
words[no_a] = words[no_b];
words[no_b] = tmp;
}
start->version = S390_HWCTR_START_VERSION;
}
static bool check_setpossible(void)
{
char *cp, *parm, *tokens[16]; /* Used to parse command line params */
unsigned long i, no_a, no_b;
char cpubuf[1024];
if (!get_cpus(CPUS_KERNELMAX, cpubuf, sizeof(cpubuf)))
return false;
max_possible_cpus = getnumber(cpubuf, '\0') + 1;
check = calloc(max_possible_cpus, sizeof(*check));
if (!check)
err(EXIT_FAILURE, "Maximum CPUs %u", max_possible_cpus);
if (!get_cpus(CPUS_POSSIBLE, cpubuf, sizeof(cpubuf))) {
free(check);
return false;
}
parm = cpubuf;
for (i = 0; i < ARRAY_SIZE(tokens) && (tokens[i] = strtok(parm, ","));
++i, parm = 0) {
cp = strchr(tokens[i], '-');
if (cp) { /* Range */
no_a = getnumber(tokens[i], *cp);
no_b = getnumber(++cp, '\0');
} else {
no_b = getnumber(tokens[i], '\0');
no_a = no_b;
}
for (; no_a <= no_b; ++no_a)
check[no_a].cpu_pos = true;
}
return true;
}
static void show_header(void)
{
static bool header;
bool comma = false;
if (header)
return; /* Printed already */
printf("Date,Time,CPU,"); /* Print counter name and number */
for (size_t i = 0; i < ARRAY_SIZE(ctrname); ++i) {
if (!ctrname[i].hitcnt)
continue;
if (comma)
putchar(',');
printf("%s(%ld)", ctrname[i].name ?: "Counter", i);
comma = true;
}
putchar('\n');
header = true;
}
static void line(char *header)
{
bool comma;
show_header();
if (allcpu) {
for (unsigned int h = 0; h < max_possible_cpus; ++h) {
char txt[16];
if (!check[h].cpu_hit)
continue;
comma = false;
snprintf(txt, sizeof(txt), "CPU%d,", h);
printf("%s%s", header, txt);
for (size_t i = 0; i < ARRAY_SIZE(ctrname); ++i) {
if (!ctrname[i].hitcnt)
continue;
if (comma)
putchar(',');
printf("%ld", ctrname[i].ccv[h]);
comma = true;
}
putchar('\n');
}
}
/* Print total count of all CPUs */
printf("%sTotal,", header);
comma = false;
for (size_t i = 0; i < ARRAY_SIZE(ctrname); ++i) {
if (!ctrname[i].hitcnt)
continue;
if (comma)
putchar(',');
printf("%ld", ctrname[i].total);
comma = true;
}
putchar('\n');
}
static void show(void)
{
time_t now = time(NULL);
struct tm *now_tm;
char now_text[32];
now_tm = localtime(&now);
strftime(now_text, sizeof(now_text), "%F,%T,", now_tm);
line(now_text);
}
/* Return Counter set size numbers (in counters) */
static unsigned int ctrset_size(int set)
{
switch (set) {
case S390_HWCTR_BASIC:
return 6;
case S390_HWCTR_USER:
return (cfvn == 1) ? 6 : 2;
case S390_HWCTR_CRYPTO:
return (csvn <= 5) ? 16 : 20;
case S390_HWCTR_EXT:
switch (csvn) {
case 1: return 32;
case 2: return 48;
case 3:
case 4:
case 5: return 128;
}
return 160;
case S390_HWCTR_MT_DIAG:
switch (csvn) {
case 1:
case 2:
case 3: return 0;
}
return 48;
}
return 0;
}
/* Return counter set offset numbers */
static int ctrset_offset(int set)
{
switch (set) {
case S390_HWCTR_BASIC:
return 0;
case S390_HWCTR_USER:
return 32;
case S390_HWCTR_CRYPTO:
return 64;
case S390_HWCTR_EXT:
return 128;
case S390_HWCTR_MT_DIAG:
return 448;
}
return 0;
}
static bool set_and_size_ok(struct s390_hwctr_setdata *p)
{
switch (p->set) {
case S390_HWCTR_BASIC:
case S390_HWCTR_USER:
case S390_HWCTR_CRYPTO:
case S390_HWCTR_EXT:
case S390_HWCTR_MT_DIAG:
return p->no_cnts == ctrset_size(p->set);
}
return false;
}
static bool add_countervalue(size_t idx, unsigned int cpu, unsigned long value)
{
if (idx >= ARRAY_SIZE(ctrname)) {
warnx("Invalid counter number %zu", idx);
return false;
}
if (cpu >= max_possible_cpus) {
warnx("Invalid CPU number %d", cpu);
return false;
}
if (!ctrname[idx].ccv) /* Unknown counter */
ctrname[idx].ccv = calloc(max_possible_cpus,
sizeof(unsigned long));
if (ctrname[idx].ccv)
ctrname[idx].ccv[cpu] += value;
ctrname[idx].total += value;
ctrname[idx].hitcnt = true;
return true;
}
static int test_read(struct s390_hwctr_read *read)
{
void *base = &read->data;
size_t offset = 0;
/* Clear previous hit counters */
for (unsigned int i = 0; i < max_possible_cpus; ++i) {
check[i].sets_hit = 0;
check[i].cpu_hit = false;
}
/* Iterate over all CPUs */
for (unsigned int i = 0; i < read->no_cpus; ++i) {
struct s390_hwctr_cpudata *cp = base + offset;
check[cp->cpu_nr].cpu_hit = true;
check[cp->cpu_nr].sets_hit = 0;
offset += sizeof(cp->cpu_nr) + sizeof(cp->no_sets);
/* Iterate over all counter sets */
for (unsigned int j = 0; j < cp->no_sets; ++j) {
struct s390_hwctr_setdata *sp = base + offset;
check[cp->cpu_nr].sets_hit |= sp->set;
offset += sizeof(sp->set) + sizeof(sp->no_cnts);
if (!set_and_size_ok(sp)) {
warnx("CPU %d inconsistent set %d size %d",
cp->cpu_nr, sp->set, sp->no_cnts);
return -1;
}
/* Iterate over all counters in each set */
for (unsigned int k = 0; k < sp->no_cnts; ++k) {
__u64 value;
void *addr = base + offset;
size_t idx = ctrset_offset(sp->set) + k;
memcpy(&value, addr, sizeof(value));
offset += sizeof(value);
if (!add_countervalue(idx, cp->cpu_nr, value))
return -1;
}
}
}
show();
return 0;
}
static int do_open(void)
{
int fd = open(S390_HWCTR_DEVICE, O_RDWR);
if (fd < 0)
warn(S390_HWCTR_DEVICE);
return fd;
}
static int do_stop(int ioctlfd)
{
int rc = ioctl(ioctlfd, S390_HWCTR_STOP, 0);
if (rc < 0)
warn("ioctl S390_HWCTR_STOP");
return rc;
}
static int do_start(int ioctlfd, struct s390_hwctr_start *start)
{
int rc = ioctl(ioctlfd, S390_HWCTR_START, start);
if (rc < 0)
warn("ioctl S390_HWCTR_START");
return rc;
}
static int do_read(int ioctlfd)
{
size_t ioctlbuffer_len = PAGE_SIZE * max_possible_cpus +
sizeof(struct s390_hwctr_read);
struct s390_hwctr_read *read;
int rc;
if (!ioctlbuffer) {
ioctlbuffer = malloc(ioctlbuffer_len);
if (!ioctlbuffer) {
warn("ioctl S390_HWCTR_START");
return -ENOMEM;
}
}
read = (struct s390_hwctr_read *)ioctlbuffer;
rc = ioctl(ioctlfd, S390_HWCTR_READ, read);
if (!rc)
rc = test_read(read);
else
warn("ioctl S390_HWCTR_READ");
return rc;
}
static void do_sleep(void)
{
struct timespec req = {
.tv_sec = read_interval,
.tv_nsec = 0
};
nanosleep(&req, NULL);
}
/* Execute commands and report first error */
static int do_it(char *s)
{
struct s390_hwctr_start start;
int ioctlfd;
int rc;
memset(&start, 0, sizeof(start));
rc = max_possible_cpus / sizeof(__u64);
start.cpumask = alloca(max_possible_cpus / sizeof(__u64));
memset(start.cpumask, 0, rc);
parse_cpulist(s, &start);
errno = 0;
ioctlfd = do_open();
if (ioctlfd < 0)
return EXIT_FAILURE;
rc = do_start(ioctlfd, &start);
if (rc < 0) {
close(ioctlfd);
return EXIT_FAILURE;
}
for (unsigned long i = 0; !rc && i < loop_count; ++i) {
rc = do_read(ioctlfd);
if (rc) {
close(ioctlfd);
return EXIT_FAILURE;
}
if (read_interval && i + 1 < loop_count)
do_sleep();
}
rc = do_stop(ioctlfd);
close(ioctlfd);
return rc ? EXIT_FAILURE : EXIT_SUCCESS;
}
/* Read counter first and second version number */
static bool get_cvn(void)
{
char *linep = NULL;
bool good = false;
size_t line_sz;
ssize_t nbytes;
FILE *slp;
slp = fopen(SERVICELEVEL, "r");
if (!slp) {
warn(SERVICELEVEL);
return false;
}
while ((nbytes = getline(&linep, &line_sz, slp)) != EOF) {
if (!strncmp(linep, "CPU-MF: Counter facility:", 25)) {
int rc;
rc = sscanf(linep, "CPU-MF: Counter facility: version=%d.%d authorization=%x",
&cfvn, &csvn, &authorization);
good = rc == 3;
if (!good)
warnx("Cannot parse line %s", linep);
break;
}
}
fclose(slp);
free(linep);
return good;
}
static struct util_opt opt_vec[] = {
UTIL_OPT_SECTION("OPTIONS"),
{
.option = { "all", no_argument, NULL, 'a' },
.desc = "Displays all CPUs in output"
},
{
.option = { "loop", required_argument, NULL, 'l' },
.argument = "NUMBER",
.desc = "Specifies loop count for next read"
},
{
.option = { "interval", required_argument, NULL, 'i' },
.argument = "NUMBER",
.desc = "Specifies interval between read operations (seconds)"
},
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
static const struct util_prg prg = {
.desc = "Read CPU Measurement facility counter sets",
.copyright_vec = {
{
.owner = "IBM Corp.",
.pub_first = 2021,
.pub_last = 2021,
},
UTIL_PRG_COPYRIGHT_END
}
};
/* Check for hardware support and exit if not available */
static void have_support(void)
{
struct stat statbuf;
if (stat(S390_HWCTR_DEVICE, &statbuf) == -1)
errx(EXIT_FAILURE,
"No support for CPU Measurement Counter set facility");
}
int main(int argc, char **argv)
{
char *slash;
int ch;
util_prg_init(&prg);
util_opt_init(opt_vec, NULL);
while ((ch = util_opt_getopt_long(argc, argv)) != -1) {
switch (ch) {
default:
util_opt_print_parse_error(ch, argv);
return EXIT_FAILURE;
case 'h':
util_prg_print_help();
util_opt_print_help();
return EXIT_SUCCESS;
case 'v':
util_prg_print_version();
return EXIT_SUCCESS;
case 'l':
errno = 0;
loop_count = strtoul(optarg, &slash, 0);
if (errno || *slash)
errx(EXIT_FAILURE, "Invalid argument for -%c",
ch);
break;
case 'i':
errno = 0;
read_interval = (unsigned int)strtoul(optarg, &slash, 0);
if (errno || *slash)
errx(EXIT_FAILURE, "Invalid argument for -%c", ch);
break;
case 'a':
allcpu = true;
break;
}
}
have_support();
if (!get_cvn())
return EXIT_FAILURE;
if (!check_setpossible())
return EXIT_FAILURE;
if (!read_counternames()) {
free(check);
return EXIT_FAILURE;
}
if (optind >= argc) {
ch = do_it(NULL);
} else {
while (optind < argc) {
ch = do_it(argv[optind++]);
if (ch)
break;
}
}
free_counternames();
free(check);
return ch;
}
+92
View File
@@ -0,0 +1,92 @@
/* Copyright IBM Corp. 2021
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
/*
* CPU Measurement counter facility application for device driver.
*
* Ioctl system call definitions.
*/
#ifndef LSHWC_H
#define LSHWC_H
#include <sys/ioctl.h>
enum {
S390_HWCTR_BASIC = 0x2, /* BASIC counter set */
S390_HWCTR_USER = 0x4, /* Problem-State Counter Set */
S390_HWCTR_CRYPTO = 0x8, /* Crypto-Activity Counter Set */
S390_HWCTR_EXT = 0x1, /* Extended Counter Set */
S390_HWCTR_MT_DIAG = 0x20, /* MT-diagnostic Counter Set */
S390_HWCTR_ALL = S390_HWCTR_BASIC | S390_HWCTR_USER |
S390_HWCTR_CRYPTO | S390_HWCTR_EXT |
S390_HWCTR_MT_DIAG
};
/* The ioctl(..., S390_HWCTR_READ, ...) is the only subcommand which returns
* data. It requires member data_bytes to be positive and indicates the
* maximum amount of data available to store counter set data. The other
* ioctl() subcommands do not use this member and it should be set to zero.
*
* The cpuset data is flattened using the following scheme, stored in member
* data:
*
* 0x0 0x8 0xc 0x10 0x14 0x18 0x20 0x28 0xU-1
* +---------+-----+---------+-----+---------+-----+-----+------+------+
* | no_cpus | cpu | no_sets | set | no_cnts | cv1 | cv2 | .... | cv_n |
* +---------+-----+---------+-----+---------+-----+-----+------+------+
*
* 0xU 0xU+4 0xU+8 0xU+10 0xV-1
* +-----+---------+-----+-----+------+------+
* | set | no_cnts | cv1 | cv2 | .... | cv_n |
* +-----+---------+-----+-----+------+------+
*
* 0xV 0xV+4 0xV+8 0xV+c
* +-----+---------+-----+---------+-----+-----+------+------+
* | cpu | no_sets | set | no_cnts | cv1 | cv2 | .... | cv_n |
* +-----+---------+-----+---------+-----+-----+------+------+
*
* U and V denote arbitrary hexadezimal addresses.
* In fact the first int represents the number of CPUs data was extracted
* from. This is followed by CPU number and number of counter sets extracted.
* Both are two integer values. This is followed by the set number and number
* of counters extracted. Both are two integer values. This is followed by
* the counter values, each element is eight bytes in size.
*/
struct s390_hwctr_start { /* Set CPUs to operate on */
__u64 version; /* Version of interface */
__u64 data_bytes; /* # of bytes required */
__u64 cpumask_len; /* Length of CPU mask in bytes */
__u64 *cpumask; /* Pointer to CPU mask */
__u64 counter_sets; /* Bit mask of counter set to get */
};
struct s390_hwctr_setdata { /* Counter set data */
__u32 set; /* Counter set number */
__u32 no_cnts; /* # of counters stored in cv[] */
__u64 cv[0]; /* Counter values (variable length) */
};
struct s390_hwctr_cpudata { /* Counter set data per CPU */
__u32 cpu_nr; /* Counter set number */
__u32 no_sets; /* # of counters sets in data[] */
struct s390_hwctr_setdata data[0];
};
struct s390_hwctr_read { /* Structure to get all ctr sets */
__u64 no_cpus; /* Total # of CPUs data taken from */
struct s390_hwctr_cpudata data[0];
};
#define S390_HWCTR_MAGIC 'C' /* Random magic # for ioctls */
#define S390_HWCTR_START _IOWR(S390_HWCTR_MAGIC, 1, struct s390_hwctr_start)
#define S390_HWCTR_STOP _IO(S390_HWCTR_MAGIC, 2)
#define S390_HWCTR_READ _IOWR(S390_HWCTR_MAGIC, 3, struct s390_hwctr_read)
#define S390_HWCTR_START_VERSION 1 /* Version # s390_hwctr_start */
#define S390_HWCTR_DEVICE "/dev/hwctr" /* Device name */
#endif
+1
View File
@@ -20,6 +20,7 @@ chcpumf \- manage the CPU-measurement facilities support
.IR num_sdb ] .IR num_sdb ]
.RB [ \-x | \-\-max .RB [ \-x | \-\-max
.IR num_sdb ] .IR num_sdb ]
.RB [ \-V | \-\-verbose ]
.br .br
.B chcpumf .B chcpumf
.BR \-h | \-\-help .BR \-h | \-\-help
+20 -5
View File
@@ -1,11 +1,11 @@
\" lscpumf.1 \" lscpumf.1
.\" .\"
.\" .\"
.\" Copyright IBM Corp. 2014, 2017 .\" Copyright IBM Corp. 2014, 2020
.\" s390-tools is free software; you can redistribute it and/or modify .\" s390-tools is free software; you can redistribute it and/or modify
.\" it under the terms of the MIT license. See LICENSE for details. .\" 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 .ds c \fBlscpumf\fP
. .
@@ -19,9 +19,11 @@ lscpumf \- display information about CPU-measurement facilities
.RB [ \-i | \-\-info ] .RB [ \-i | \-\-info ]
.br .br
.B lscpumf .B lscpumf
.RB [ \-c | \-\-list\-counters ] .RB \-c | \-\-list\-counters | \-C | \-\-list\-all\-counters
.RB [ \-C | \-\-list\-all\-counters ] .RB [ \-n ]
.RB [ \-s | \-\-list\-sampling\-events ] .br
.B lscpumf
.RB \-s | \-\-list\-sampling\-events
.br .br
.B lscpumf .B lscpumf
.BR \-h | \-\-help .BR \-h | \-\-help
@@ -46,12 +48,25 @@ facilities.
Lists counters that are provided by the CPU-measurement facility, omitting Lists counters that are provided by the CPU-measurement facility, omitting
counters for which the LPAR is not authorized. For counter measurements with counters for which the LPAR is not authorized. For counter measurements with
the perf program, the raw event identifier is displayed. 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 .TP
.BR \-C ", " \-\-list\-all\-counters .BR \-C ", " \-\-list\-all\-counters
Lists all counters that are provided by the CPU-measurement counter facility, Lists all counters that are provided by the CPU-measurement counter facility,
regardless of LPAR authorization. To list only those counters for which the regardless of LPAR authorization. To list only those counters for which the
LPAR is authorized, use the -c option. 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 .TP
.BR \-s ", " \-\-list\-sampling\-events .BR \-s ", " \-\-list\-sampling\-events
+134
View File
@@ -0,0 +1,134 @@
.\" lshwc.1
.\"
.\"
.\" Copyright IBM Corp. 2021
.\" s390-tools is free software; you can redistribute it and/or modify
.\" it under the terms of the MIT license. See LICENSE for details.
.\" ----------------------------------------------------------------------
.ds c \fBlshwc\fP
.
.TH \*c "1" "February 2021" "s390-tools" "CPU-MF management programs"
.
.SH NAME
\*c \- extract CPU Measurement Facilities counter sets
.
.SH SYNOPSIS
\*c
.RB [ \-a ]
.RB [ \-l
.IR count ]
.RB [ \-i
.IR interval ]
\fR[\fIcpulist\fR][:\fIsets\fR]\fP
.br
\*c
.BR \-h | \-\-help
.br
\*c
.BR \-v | \-\-version
.
.
.SH DESCRIPTION
The \*c command extracts complete counter sets from the CPU
Measurement Facilities for Linux on Z.
Counter sets can be specified and extracted for individual CPUs.
The output is a comma-separated values file.
Each line starts with a timestamp and the CPU number,
followed by the extracted counter values.
.
.SH OPTIONS
.TP
.BR \-h ", " \-\-help
Displays help information, then exits.
.
.TP
.BR \-v ", " \-\-version
Displays version information, then exits.
.
.TP
.BR \-a ", " \-\-allcpu
Displays counter values from each CPU.
The default is a total summary line of all counters from all CPUs.
.
.TP
.BR \-i ", " \-\-interval \fI\ seconds\fP
Specifies a time interval, in seconds,
that the command waits between read operations.
The default is 60 seconds.
.
.TP
.BR \-l ", " \-\-loop \fI\ count\fP
Performs the specified number of read operations.
.
.TP
\fR[\fIcpulist\fR][:\fIsets\fR]\fP
A comma-separated list of CPUs.
Each CPU can optionally be followed by characters that specify the counter set.
See below for details.
.
.SS "CPU List and counter-set specification"
In the comma-separated list of CPUs,
each element is a CPU or a range of CPUs.
By default, \*c lists all CPUs.
.P
The CPU list can be followed by an optional list
of characters that specify the counter sets to be extracted,
preceded by a colon.
The characters can be upper or lower case.
By default, all counter sets are used.
.IP b
Include the basic counter set.
.IP c
Include the crypto counter set.
.IP e
Include the extended counter set.
.IP m
Include the MT_Diagnostic counter set.
.IP p|u
Include the problem counter set.
.IP a
Include all known counter sets (default).
.SH "Concurrency with perf tool"
The \*c tool and the linux
.B perf
tool use the same hardware and cannot be used concurrently.
Both tools print an error message and abort when they
detect this situation.
.SH "EXAMPLES"
The first example enables the basic and problem counter sets on CPU 0 and 1.
Two read operations are performed and a summary line is printed for each
read operation.
.sp 1
.nf
.ft CW
# lshwc -l2 0-1:BP
Date,Time,CPU,CPU_CYCLES(0),INSTRUCTIONS(1),L1I_DIR_WRITES(2),L1I_PENALTY_CYCLES(3),L1D_DIR_WRITES(4),
L1D_PENALTY_CYCLES(5),PROBLEM_STATE_CPU_CYCLES(32),PROBLEM_STATE_INSTRUCTIONS(33)
2021-04-01,11:50:32,Total,125422,39421,304,13953,454,
97489,0,0
2021-04-01,11:51:32,Total,68074231,16386850,194028,21382384,317227,
104503489,777383,14198
.ft
.fi
.sp 1
This example shows the counter values of the problem state counter set
per CPU. CPU 0 and CPU 1 is selected.
.nf
.ft CW
.sp 1
# lshwc -l3 -a 0-1:P
Date,Time,CPU,PROBLEM_STATE_CPU_CYCLES(32),PROBLEM_STATE_INSTRUCTIONS(33)
2021-04-01,11:54:47,CPU0,0,0
2021-04-01,11:54:47,CPU1,0,0
2021-04-01,11:54:47,Total,0,0
2021-04-01,11:55:47,CPU0,818775,14198
2021-04-01,11:55:47,CPU1,125689,1306
2021-04-01,11:55:47,Total,944464,15504
2021-04-01,11:56:47,CPU0,3207071426,1489122591
2021-04-01,11:56:47,CPU1,3225092021,1489278312
2021-04-01,11:56:47,Total,6432163447,2978400903
.ft
.fi
.SH "SEE ALSO"
.BR lscpumf (1)
.BR chcpumf (8)
+359 -391
View File
File diff suppressed because it is too large Load Diff
+26 -46
View File
@@ -41,6 +41,10 @@ static const char mode_str[3][10] = {
"Full", "Quick", "Expand" "Full", "Quick", "Expand"
}; };
/* Report error, free memory, and exit */
static void error(const char *format, ...)
__attribute__((__noreturn__, __format__(__printf__, 1, 2)));
#define DASD_PARTN_BITS 2 #define DASD_PARTN_BITS 2
#define PARTN_MASK ((1 << DASD_PARTN_BITS) - 1) #define PARTN_MASK ((1 << DASD_PARTN_BITS) - 1)
@@ -65,47 +69,24 @@ static const char mode_str[3][10] = {
"is in invalid format\n",prog_name);} "is in invalid format\n",prog_name);}
typedef struct bootstrap1 { typedef struct bootstrap1 {
u_int32_t key; u_int32_t key;
u_int32_t data[6]; u_int32_t data[6];
} __attribute__ ((packed)) bootstrap1_t; } __attribute__ ((packed)) bootstrap1_t;
typedef struct bootstrap2 { typedef struct bootstrap2 {
u_int32_t key; u_int32_t key;
u_int32_t data[36]; u_int32_t data[36];
} __attribute__ ((packed)) bootstrap2_t; } __attribute__ ((packed)) bootstrap2_t;
typedef struct dasdfmt_info {
dasd_information2_t dasd_info;
int verbosity;
int testmode;
int withoutprompt;
int print_progressbar;
int print_hashmarks, hashstep;
int print_percentage;
int force;
int writenolabel;
int labelspec;
int cdl_format;
int blksize_specified;
int reqsize_specified;
int keep_volser;
int force_host;
int layout_specified;
int check;
int mode_specified;
int ese;
int no_discard;
} dasdfmt_info_t;
/* /*
C9D7D3F1 000A0000 0000000F 03000000 00000001 00000000 00000000 C9D7D3F1 000A0000 0000000F 03000000 00000001 00000000 00000000
*/ */
static bootstrap1_t ipl1 = { static bootstrap1_t ipl1 = {
0xC9D7D3F1, { 0xC9D7D3F1, {
0x000A0000, 0x0000000F, 0x03000000, 0x000A0000, 0x0000000F, 0x03000000,
0x00000001, 0x00000000, 0x00000000 0x00000001, 0x00000000, 0x00000000
} }
}; };
/* /*
@@ -116,21 +97,20 @@ C9D7D3F2 07003AB8 40000006 31003ABE 40000005 08003AA0 00000000 06000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
*/ */
static bootstrap2_t ipl2 = { static bootstrap2_t ipl2 = {
0xC9D7D3F2, { 0xC9D7D3F2, {
0x07003AB8, 0x40000006, 0x31003ABE, 0x07003AB8, 0x40000006, 0x31003ABE,
0x40000005, 0x08003AA0, 0x00000000, 0x40000005, 0x08003AA0, 0x00000000,
0x06000000, 0x20000000, 0x00000000, 0x06000000, 0x20000000, 0x00000000,
0x00000000, 0x00000400, 0x00000000, 0x00000000, 0x00000400, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000 0x00000000, 0x00000000, 0x00000000
} }
}; };
#endif /* DASDFMT_H */ #endif /* DASDFMT_H */
+29 -4
View File
@@ -1,14 +1,39 @@
include ../common.mak include ../common.mak
ALL_CPPFLAGS += -DSYSFS
all: dasdview
libs = $(rootdir)/libdasd/libdasd.a \ libs = $(rootdir)/libdasd/libdasd.a \
$(rootdir)/libzds/libzds.a \ $(rootdir)/libzds/libzds.a \
$(rootdir)/libvtoc/libvtoc.a \ $(rootdir)/libvtoc/libvtoc.a \
$(rootdir)/libutil/libutil.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) dasdview: dasdview.o $(libs)
install: all install: all
+25
View File
@@ -0,0 +1,25 @@
# Example configuration for hsavmcore
# See hsavmcore.conf(8) for documentation
# 0 - ERROR
# 1 - WARN
# 2 - INFO
# 3 - DEBUG
# 4 - TRACE
#verbose = 0
#workdir = /var/crash
#mount_debugfs = 0
#use_hsa_mem = 0
#hsa_size = -1
#release_hsa = 1
#bind_mount_vmcore = 1
#swap = /dev/disk/by-uuid/3cf6630b-4c4d-49ac-a0ae-0f5484cb5721
#swap = /swap.img
#fuse_debug = 0
+145 -61
View File
@@ -225,7 +225,7 @@ function CheckDeviceString() {
fi fi
} }
setup_device() setup_ccw_device()
{ {
DEV="$(CheckDeviceString $DEVICE)" DEV="$(CheckDeviceString $DEVICE)"
if [ "$DEV" != "" ]; then if [ "$DEV" != "" ]; then
@@ -235,27 +235,37 @@ setup_device()
pr_error "ERROR: Invalid DEVICE '$DEVICE'." $ERRMSG pr_error "ERROR: Invalid DEVICE '$DEVICE'." $ERRMSG
return return
fi fi
if [ $2 == "fcp" ]; then }
echo $WWPN > $1/fcp/wwpn 2>/dev/null || RETVAL=1
if [ $RETVAL -eq 1 ]; then setup_fcp_device()
pr_error "ERROR: Invalid WWPN '$WWPN'." $ERRMSG {
return DEV="$(CheckDeviceString $DEVICE)"
fi if [ "$DEV" != "" ]; then
echo $LUN > $1/fcp/lun 2>/dev/null || RETVAL=1 echo $DEV > $1/$2/device
if [ $RETVAL -eq 1 ]; then else
pr_error "ERROR: Invalid LUN '$LUN'." $ERRMSG RETVAL=1
return pr_error "ERROR: Invalid DEVICE '$DEVICE'." $ERRMSG
fi return
echo $BOOTPROG > $1/fcp/bootprog 2>/dev/null || RETVAL=1 fi
if [ $RETVAL -eq 1 ]; then echo $WWPN > $1/fcp/wwpn 2>/dev/null || RETVAL=1
pr_error "ERROR: Invalid BOOTPROG '$BOOTPROG'." $ERRMSG if [ $RETVAL -eq 1 ]; then
return pr_error "ERROR: Invalid WWPN '$WWPN'." $ERRMSG
fi return
echo $BR_LBA > $1/fcp/br_lba 2>/dev/null || RETVAL=1 fi
if [ $RETVAL -eq 1 ]; then echo $LUN > $1/fcp/lun 2>/dev/null || RETVAL=1
pr_error "ERROR: Invalid BR_LBA '$BR_LBA'." $ERRMSG if [ $RETVAL -eq 1 ]; then
return pr_error "ERROR: Invalid LUN '$LUN'." $ERRMSG
fi 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 fi
} }
@@ -264,6 +274,30 @@ setup_nss_device()
echo $NSS_NAME > $1/nss/name || RETVAL=1 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() setup_reipl()
{ {
if [ "$REIPL_TYPE" == "" ]; then if [ "$REIPL_TYPE" == "" ]; then
@@ -271,15 +305,25 @@ setup_reipl()
return return
fi fi
if [ "$REIPL_TYPE" == "ccw" ] || [ "$REIPL_TYPE" == "fcp" ]; then case "$REIPL_TYPE" in
setup_device $REIPL_CONFIG_DIR $REIPL_TYPE ccw)
elif [ "$REIPL_TYPE" == "nss" ]; then setup_ccw_device $REIPL_CONFIG_DIR $REIPL_TYPE
setup_nss_device $REIPL_CONFIG_DIR ;;
else fcp)
pr_error "ERROR: Unknown reipl type '$REIPL_TYPE'." $ERRMSG setup_fcp_device $REIPL_CONFIG_DIR $REIPL_TYPE
RETVAL=1 ;;
return nvme)
fi 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 echo $REIPL_TYPE > $REIPL_CONFIG_DIR/reipl_type || RETVAL=1
@@ -292,13 +336,24 @@ setup_reipl()
setup_dump() setup_dump()
{ {
if [ "$DUMP_TYPE" == "ccw" ] || [ "$DUMP_TYPE" == "fcp" ]; then case "$DUMP_TYPE" in
setup_device $DUMP_CONFIG_DIR $DUMP_TYPE ccw)
elif [ "$DUMP_TYPE" != "none" ]; then setup_ccw_device $DUMP_CONFIG_DIR $DUMP_TYPE
pr_error "ERROR: Unknown dump type '$DUMP_TYPE'." $ERRMSG ;;
RETVAL=1 fcp)
return setup_fcp_device $DUMP_CONFIG_DIR $DUMP_TYPE
fi ;;
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 echo $DUMP_TYPE > $DUMP_CONFIG_DIR/dump_type || RETVAL=1
@@ -358,6 +413,18 @@ print_ccw_device()
pr_info "device..: $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() print_nss_name()
{ {
NAME=$(cat $1/nss/device) || RETVAL=1 NAME=$(cat $1/nss/device) || RETVAL=1
@@ -367,35 +434,52 @@ print_nss_name()
status_dump() status_dump()
{ {
CONF_DUMP_TYPE=$(cat $DUMP_CONFIG_DIR/dump_type) || RETVAL=1 CONF_DUMP_TYPE=$(cat $DUMP_CONFIG_DIR/dump_type) || RETVAL=1
if [ "$CONF_DUMP_TYPE" == "none" ]; then case "$CONF_DUMP_TYPE" in
pr_info "type....: no dump device configured" none)
elif [ "$CONF_DUMP_TYPE" == "ccw" ]; then pr_info "type....: no dump device configured"
pr_info "type....: ccw" ;;
print_ccw_device $DUMP_CONFIG_DIR ccw)
verify_ccw_dump_device $(cat $DUMP_CONFIG_DIR/ccw/device) pr_info "type....: ccw"
elif [ "$CONF_DUMP_TYPE" == "fcp" ]; then print_ccw_device $DUMP_CONFIG_DIR
pr_info "type....: fcp" verify_ccw_dump_device $(cat $DUMP_CONFIG_DIR/ccw/device)
print_fcp_device $DUMP_CONFIG_DIR ;;
else fcp)
pr_error "ERROR: Unknown dump device type '$CONF_DUMP_TYPE'!" pr_info "type....: fcp"
pr_error " Please check if you have the latest dumpconf package!" print_fcp_device $DUMP_CONFIG_DIR
fi ;;
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() status_reipl()
{ {
REIPL_TYPE=$(cat $REIPL_CONFIG_DIR/reipl_type) || RETVAL=1 REIPL_TYPE=$(cat $REIPL_CONFIG_DIR/reipl_type) || RETVAL=1
pr_info "type....: $REIPL_TYPE" pr_info "type....: $REIPL_TYPE"
if [ "$REIPL_TYPE" == "ccw" ]; then case "$REIPL_TYPE" in
print_ccw_device $REIPL_CONFIG_DIR ccw)
elif [ "$REIPL_TYPE" == "fcp" ]; then print_ccw_device $REIPL_CONFIG_DIR
print_fcp_device $REIPL_CONFIG_DIR ;;
elif [ "$REIPL_TYPE" == "nss" ]; then fcp)
print_nss_name $REIPL_CONFIG_DIR print_fcp_device $REIPL_CONFIG_DIR
else ;;
pr_error "ERROR: Unknown reipl device type '$REIPL_TYPE'!" nvme)
pr_error " Please check if you have the latest dumpconf package!" print_nvme_device $REIPL_CONFIG_DIR
fi ;;
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() status_dump_reipl()
+1 -1
View File
@@ -31,7 +31,7 @@ if [ -f $CONFIG_FILE ]; then
. $CONFIG_FILE . $CONFIG_FILE
fi fi
UDEVSETTLE=/sbin/udevadm UDEVSETTLE=/usr/bin/udevadm
if [ ! -e $UDEVSETTLE ] if [ ! -e $UDEVSETTLE ]
then then
UDEVSETTLE=/sbin/udevsettle UDEVSETTLE=/sbin/udevsettle
+10
View File
@@ -39,6 +39,16 @@
# BOOTPROG=0 # BOOTPROG=0
# BR_LBA=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 # Use VMDUMP
# #
+2 -2
View File
@@ -26,10 +26,10 @@ KERNEL=="dasd*[0-9]", ENV{ID_XUID}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env
LABEL="dasd_symlinks_end" LABEL="dasd_symlinks_end"
# on device add set request queue scheduler to deadline # on device add set request queue scheduler to none
SUBSYSTEM!="block", GOTO="sched_end" SUBSYSTEM!="block", GOTO="sched_end"
ACTION!="change", GOTO="sched_end" ACTION!="change", GOTO="sched_end"
KERNEL=="dasd*[!0-9]", TEST=="queue/scheduler", ATTR{queue/scheduler}="deadline" KERNEL=="dasd*[!0-9]", TEST=="queue/scheduler", ATTR{queue/scheduler}="none"
LABEL="sched_end" LABEL="sched_end"
+1 -1
View File
@@ -1232,7 +1232,7 @@ static void fdasd_reread_partition_table(fdasd_anchor_t *anc)
if (!anc->silent) if (!anc->silent)
printf("rereading partition table...\n"); printf("rereading partition table...\n");
if (dasd_reread_partition_table(options.device, 1) != 0) { if (dasd_reread_partition_table(options.device, 5) != 0) {
fdasd_error(anc, unable_to_ioctl, "Error while rereading " fdasd_error(anc, unable_to_ioctl, "Error while rereading "
"partition table.\nPlease reboot!"); "partition table.\nPlease reboot!");
} }
+1 -1
View File
@@ -21,7 +21,7 @@ clean: clean-recursive
$(RECURSIVE_TARGETS): $(RECURSIVE_TARGETS):
@target=`echo $@ |sed s/-recursive//`; \ @target=`echo $@ |sed s/-recursive//`; \
for d in $(SUBDIRS); do \ for d in $(SUBDIRS); do \
$(MAKE) -C $$d $$target; \ $(MAKE) -C $$d $$target || exit 1; \
done done
.PHONY: all install clean $(RECURSIVE_TARGETS) .PHONY: all install clean $(RECURSIVE_TARGETS)
+1 -1
View File
@@ -12,7 +12,7 @@ ALL_CFLAGS := $(NO_PIE_CFLAGS) -Os -g \
-DENABLE_SCLP_ASCII=1 \ -DENABLE_SCLP_ASCII=1 \
-DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \ -DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \
-fno-builtin -ffreestanding -fno-asynchronous-unwind-tables \ -fno-builtin -ffreestanding -fno-asynchronous-unwind-tables \
-fno-delete-null-pointer-checks \ -fno-delete-null-pointer-checks -fno-stack-protector \
-fexec-charset=IBM1047 -m64 -mpacked-stack \ -fexec-charset=IBM1047 -m64 -mpacked-stack \
-mstack-size=4096 -mstack-guard=128 -msoft-float \ -mstack-size=4096 -mstack-guard=128 -msoft-float \
-Wall -Wformat-security -Wextra -Werror -Wall -Wformat-security -Wextra -Werror
+4 -2
View File
@@ -1,5 +1,5 @@
/* /*
* Entry code for stage 3a boot loader * Entry code for stage 3a and stage 3b boot loader
* *
* Copyright IBM Corp. 2020 * Copyright IBM Corp. 2020
* *
@@ -24,6 +24,8 @@ _start:
sam64 sam64
/* Initialize stack */ /* Initialize stack */
lgfi %r15, STACK_ADDRESS + STACK_SIZE - STACK_FRAME_OVERHEAD basr %r13, 0
.Lbase: llgf %r15, .Lstack - .Lbase(%r13)
brasl %r14, initialize brasl %r14, initialize
.Lstack: .long STACK_ADDRESS + STACK_SIZE - STACK_FRAME_OVERHEAD
.previous .previous
+3 -1
View File
@@ -21,6 +21,8 @@ _init:
* kernel command line and the address and size of the * kernel command line and the address and size of the
* ramdisk. Simply ignore this by starting at 0x11000. * ramdisk. Simply ignore this by starting at 0x11000.
*/ */
lgfi %r1, STAGE3A_ENTRY basr %r13, 0
.Lbase: llgf %r1, .Lstage3a_entry - .Lbase(%r13)
br %r1 br %r1
.Lstage3a_entry: .long STAGE3A_ENTRY
.previous .previous
+5 -3
View File
@@ -31,12 +31,12 @@ stage3b_reloc_start:
sigp %r1, %r0, SIGP_SET_ARCHITECTURE sigp %r1, %r0, SIGP_SET_ARCHITECTURE
sam64 sam64
.copy_stage3b:
/* Location of stage3b in memory */ /* Location of stage3b in memory */
larl %r8, stage3b_start larl %r8, stage3b_start
/* Destination for stage3b */ /* Destination for stage3b */
lgfi %r9, STAGE3B_LOAD_ADDRESS basr %r13, 0
.Lbase: llgf %r9, .Lstage3b_load_address - .Lbase(%r13)
/* Size of stage3b */ /* Size of stage3b */
lghi %r11, stage3b_end - stage3b_start lghi %r11, stage3b_end - stage3b_start
@@ -45,8 +45,10 @@ stage3b_reloc_start:
MEMCPY %r9, %r8, %r11 MEMCPY %r9, %r8, %r11
/* Branch to STAGE3B_ENTRY */ /* Branch to STAGE3B_ENTRY */
lgfi %r9, STAGE3B_ENTRY llgf %r9, .Lstage3b_entry - .Lbase(%r13)
br %r9 br %r9
.Lstage3b_load_address: .long STAGE3B_LOAD_ADDRESS
.Lstage3b_entry: .long STAGE3B_ENTRY
stage3b_start: stage3b_start:
.incbin "stage3b.bin" .incbin "stage3b.bin"
stage3b_end: stage3b_end:
+46 -11
View File
@@ -2,7 +2,7 @@
.\" s390-tools is free software; you can redistribute it and/or modify .\" s390-tools is free software; you can redistribute it and/or modify
.\" it under the terms of the MIT license. See LICENSE for details. .\" it under the terms of the MIT license. See LICENSE for details.
.\" .\"
.TH GENPROTIMG 8 "March 2020" "s390-tools" .TH GENPROTIMG 8 "November 2020" "s390-tools"
.SH NAME .SH NAME
genprotimg \- Create a protected virtualization image genprotimg \- Create a protected virtualization image
@@ -10,6 +10,7 @@ genprotimg \- Create a protected virtualization image
.SY .SY
.B genprotimg .B genprotimg
\fB\-k\fR \fIHOST_KEY_DOCUMENT\fR... \fB\-k\fR \fIHOST_KEY_DOCUMENT\fR...
\fB\-C\fR \fICERTIFICATE\fR...
\fB\-i\fR \fIVMLINUZ\fR \fB\-i\fR \fIVMLINUZ\fR
[\fB\-r\fR \fIRAMDISK\fR] [\fB\-r\fR \fIRAMDISK\fR]
[\fB\-p\fR \fIPARMFILE\fR] [\fB\-p\fR \fIPARMFILE\fR]
@@ -21,15 +22,19 @@ genprotimg \- Create a protected virtualization image
.PP .PP
Use \fBgenprotimg\fR to generate a single bootable image file with Use \fBgenprotimg\fR to generate a single bootable image file with
encrypted and integrity-protected parts. The command requires a kernel encrypted and integrity-protected parts. The command requires a kernel
image, a host-key document, and an output file name. Optionally, image, a host-key document, certificates for the host-key document
specify an initial RAM filesystem, and a file containing the kernel verification, and an output file name. Optionally, specify an initial
parameters. Should special circumstances require it, you can RAM filesystem, and a file containing the kernel parameters. If the
command should be run offline, use the \fB\-\-offline\fR option and
specify the certificate revocation lists (CRLs) by using the
\fB\-\-crl\fR option. Should special circumstances require it, you can
optionally specify your own keys for the encryption by using the optionally specify your own keys for the encryption by using the
experimental options. In the resulting image file, a plain text boot experimental options. For all certificates, CRLs, and host-key
loader, the encrypted components for kernel, initial RAM disk, kernel documents, both the PEM and DER input formats are supported. In the
parameters, and the encrypted and integrity-protected header are resulting image file, a plain text boot loader, the encrypted
concatenated. The header contains metadata necessary for running the components for kernel, initial RAM disk, kernel parameters, and the
guest in protected mode. encrypted and integrity-protected header are concatenated. The header
contains metadata necessary for running the guest in protected mode.
.PP .PP
Use this image file as a kernel image for zipl or for a direct kernel Use this image file as a kernel image for zipl or for a direct kernel
boot using QEMU. boot using QEMU.
@@ -53,6 +58,12 @@ Specifies a host-key document. At least one is required. Specify this
option multiple times to enable the image to run on more than one option multiple times to enable the image to run on more than one
host. host.
.TP .TP
\fB\-C\fR, \fB\-\-cert\fR=\fI\,FILE\/\fR
Specifies the certificate that is used to establish a chain of trust
for the verification of the host-key documents. Specify this option
twice to specify the IBM Z signing key and the intermediate CA
certificate (signed by the root CA). Required.
.TP
\fB\-o\fR, \fB\-\-output\fR=\fI\,OUTPUT_FILE\/\fR \fB\-o\fR, \fB\-\-output\fR=\fI\,OUTPUT_FILE\/\fR
Specifies the output file. Required. Specifies the output file. Required.
.TP .TP
@@ -65,10 +76,32 @@ Specifies the RAM disk image. Optional.
\fB\-p\fR, \fB\-\-parmfile\fR=\fI\,PARMFILE\/\fR \fB\-p\fR, \fB\-\-parmfile\fR=\fI\,PARMFILE\/\fR
Specifies the kernel command line stored in \fI\,PARMFILE\/\fR. Optional. Specifies the kernel command line stored in \fI\,PARMFILE\/\fR. Optional.
.TP .TP
\fB\-\-crl\fR=\fI\,FILE\/\fR
Specifies the revocation list that is used to check whether a
certificate of the chain of trust is revoked. Specify this option
multiple times to use multiple CRLs. Optional.
.TP
\fB\-\-offline\fR
Specifies offline mode, in which no attempt is made to download
CRLs. Optional.
.TP
\fB\-\-root\-ca\fR=\fI\,FILE\/\fR
Specifies the root CA certificate for the verification. If omitted,
the DigiCert root CA certificate installed on the system is used. Use
this only if you trust the specified certificate. Optional.
.TP
\fB\-\-no-verify\fR \fB\-\-no-verify\fR
Do not require the host-key documents to be valid. For testing Do not require the host-key documents to be valid. For testing
purposes, do not use for a production image. Optional. purposes, do not use for a production image. Optional.
.TP .TP
\fB\-\-enable\-pckmo\fR
Enable the support for the DEA, TDEA, AES, and ECC PCKMO key encryption
functions. This is the default. Optional.
.TP
\fB\-\-disable\-pckmo\fR
Disable the support for the DEA, TDEA, AES, and ECC PCKMO key encryption
functions. Optional.
.TP
\fB\-v\fR, \fB\-\-version\fR \fB\-v\fR, \fB\-\-version\fR
Prints version information, then exits. Prints version information, then exits.
@@ -77,11 +110,13 @@ Prints version information, then exits.
Generate a protected virtualization image in Generate a protected virtualization image in
\fI\,/boot/vmlinuz.pv\/\fR, using the kernel file \fI\,vmlinuz\/\fR, \fI\,/boot/vmlinuz.pv\/\fR, using the kernel file \fI\,vmlinuz\/\fR,
the initrd in \fI\,initramfs\/\fR, the kernel parameters contained in the initrd in \fI\,initramfs\/\fR, the kernel parameters contained in
\fI\,parmfile\/\fR, and the host-key document in \fI\,host_key.crt\/\fR: \fI\,parmfile\/\fR, the intermediate CA in \fI\,DigiCertCA.crt\/\fR,
the IBM Z signing key in \fI\,ibm-z-host-key-signing.crt\/\fR, and the
host-key document in \fI\,host_key.crt\/\fR:
.PP .PP
.Vb 1 .Vb 1
.EX .EX
\& genprotimg \-i \fI\,vmlinuz\/\fR \-r \fI\,initramfs\/\fR \-p \fI\,parmfile\/\fR \-k \fI\,host_key.crt\/\fR \-o \fI\,/boot/vmlinuz.pv\/\fR \& genprotimg \-i \fI\,vmlinuz\/\fR \-r \fI\,initramfs\/\fR \-p \fI\,parmfile\/\fR \-k \fI\,host_key.crt\/\fR \-C \fI\,ibm-z-host-key-signing.crt\/\fR \-C \fI\,DigiCertCA.crt \-o \fI\,/boot/vmlinuz.pv\/\fR
.EE .EE
.Ve .Ve
.PP .PP
+4 -5
View File
@@ -6,11 +6,9 @@
# verifying the issuer, the validity date and the signature. # verifying the issuer, the validity date and the signature.
# Optionally verify the full trust chain using a CA certficate. # Optionally verify the full trust chain using a CA certficate.
# #
# Revocation list checking not yet implemented.
#
# Sample invocation: # 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 # Copyright IBM Corp. 2020
# #
@@ -37,8 +35,9 @@ cleanup()
trap cleanup EXIT trap cleanup EXIT
# Enhanced error checking for bash # Enhanced error checking for bash
if echo $SHELL | grep /bin/bash > /dev/null if [ -n "${BASH}" ]
then then
set -o posix
set -o pipefail set -o pipefail
set -o nounset set -o nounset
fi fi
@@ -101,7 +100,7 @@ extract_body()
verify_signature() 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 openssl sha512 -verify $1 -signature $2 $3
} }
+17 -5
View File
@@ -15,24 +15,25 @@ INCLUDE_PARMS = $(addprefix -I,$(INCLUDE_PATHS))
WARNINGS := -Wall -Wextra -Wshadow \ WARNINGS := -Wall -Wextra -Wshadow \
-Wcast-align -Wwrite-strings -Wmissing-prototypes \ -Wcast-align -Wwrite-strings -Wmissing-prototypes \
-Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline \ -Wmissing-declarations -Wredundant-decls -Wnested-externs \
-Wno-long-long -Wuninitialized -Wconversion -Wstrict-prototypes \ -Wno-long-long -Wuninitialized -Wconversion -Wstrict-prototypes \
-Wpointer-arith -Werror \ -Wpointer-arith -Werror -Wno-error=inline \
$(NULL) $(NULL)
$(bin_PROGRAM)_SRCS := $(bin_PROGRAM).c pv/pv_stage3.c pv/pv_image.c \ $(bin_PROGRAM)_SRCS := $(bin_PROGRAM).c pv/pv_stage3.c pv/pv_image.c \
pv/pv_comp.c pv/pv_hdr.c pv/pv_ipib.c utils/crypto.c utils/file_utils.c \ pv/pv_comp.c pv/pv_hdr.c pv/pv_ipib.c utils/crypto.c utils/file_utils.c \
pv/pv_args.c utils/buffer.c pv/pv_comps.c pv/pv_error.c \ pv/pv_args.c utils/buffer.c pv/pv_comps.c pv/pv_error.c \
pv/pv_opt_item.c \ pv/pv_opt_item.c utils/curl.c \
$(NULL) $(NULL)
$(bin_PROGRAM)_OBJS := $($(bin_PROGRAM)_SRCS:.c=.o) $(bin_PROGRAM)_OBJS := $($(bin_PROGRAM)_SRCS:.c=.o)
ALL_CFLAGS += -std=gnu11 -DPKGDATADIR=$(PKGDATADIR) \ ALL_CFLAGS += -std=gnu11 -DPKGDATADIR=$(PKGDATADIR) \
$(GLIB2_CFLAGS) $(LIBCRYPTO_CFLAGS) \ $(GLIB2_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBCURL_CFLAGS) \
-DOPENSSL_API_COMPAT=0x10100000L \
$(WARNINGS) \ $(WARNINGS) \
$(NULL) $(NULL)
ALL_CPPFLAGS += $(INCLUDE_PARMS) ALL_CPPFLAGS += $(INCLUDE_PARMS)
LDLIBS += $(GLIB2_LIBS) $(LIBCRYPTO_LIBS) LDLIBS += $(GLIB2_LIBS) $(LIBCRYPTO_LIBS) $(LIBCURL_LIBS)
ifneq ($(shell sh -c 'command -v pkg-config'),) ifneq ($(shell sh -c 'command -v pkg-config'),)
@@ -40,21 +41,27 @@ GLIB2_CFLAGS := $(shell pkg-config --silence-errors --cflags glib-2.0)
GLIB2_LIBS := $(shell pkg-config --silence-errors --libs glib-2.0) GLIB2_LIBS := $(shell pkg-config --silence-errors --libs glib-2.0)
LIBCRYPTO_CFLAGS := $(shell pkg-config --silence-errors --cflags libcrypto) LIBCRYPTO_CFLAGS := $(shell pkg-config --silence-errors --cflags libcrypto)
LIBCRYPTO_LIBS := $(shell pkg-config --silence-errors --libs libcrypto) LIBCRYPTO_LIBS := $(shell pkg-config --silence-errors --libs libcrypto)
LIBCURL_CFLAGS := $(shell pkg-config --silence-errors --cflags libcurl)
LIBCURL_LIBS := $(shell pkg-config --silence-errors --libs libcurl)
else else
GLIB2_CFLAGS := -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include GLIB2_CFLAGS := -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include
GLIB2_LIBS := -lglib-2.0 GLIB2_LIBS := -lglib-2.0
LIBCRYPTO_CFLAGS := LIBCRYPTO_CFLAGS :=
LIBCRYPTO_LIBS := -lcrypto LIBCRYPTO_LIBS := -lcrypto
LIBCURL_CFLAGS :=
LIBCURL_LIBS := -lcurl
endif endif
BUILD_TARGETS := skip-$(bin_PROGRAM) BUILD_TARGETS := skip-$(bin_PROGRAM)
INSTALL_TARGETS := skip-$(bin_PROGRAM) INSTALL_TARGETS := skip-$(bin_PROGRAM)
ifneq (${HAVE_OPENSSL},0) ifneq (${HAVE_OPENSSL},0)
ifneq (${HAVE_GLIB2},0) ifneq (${HAVE_GLIB2},0)
ifneq (${HAVE_LIBCURL},0)
BUILD_TARGETS := $(bin_PROGRAM) BUILD_TARGETS := $(bin_PROGRAM)
INSTALL_TARGETS := install-$(bin_PROGRAM) INSTALL_TARGETS := install-$(bin_PROGRAM)
endif endif
endif endif
endif
all: $(BUILD_TARGETS) all: $(BUILD_TARGETS)
@@ -98,4 +105,9 @@ $($(bin_PROGRAM)_OBJS): .check-dep-$(bin_PROGRAM)
"openssl-devel / libssl-dev version >= 1.1.0", \ "openssl-devel / libssl-dev version >= 1.1.0", \
"HAVE_OPENSSL=0", \ "HAVE_OPENSSL=0", \
"-I.") "-I.")
$(call check_dep, \
"$(bin_PROGRAM)", \
"curl/curl.h", \
"libcurl-devel", \
"HAVE_LIBCURL=0")
touch $@ touch $@
+19
View File
@@ -18,6 +18,8 @@
#include "common.h" #include "common.h"
#include "pv/pv_args.h" #include "pv/pv_args.h"
#include "pv/pv_image.h" #include "pv/pv_image.h"
#include "utils/crypto.h"
#include "utils/curl.h"
enum { enum {
LOG_LEVEL_CRITICAL = 0, LOG_LEVEL_CRITICAL = 0,
@@ -117,6 +119,8 @@ static void remove_signal_handler(const gint *signals, const gsize signals_n)
signal(signals[i], SIG_DFL); signal(signals[i], SIG_DFL);
} }
static void __attribute__((constructor)) __init(void);
static void __attribute__((destructor)) __cleanup(void);
gint main(gint argc, gchar *argv[]) gint main(gint argc, gchar *argv[])
{ {
g_autoptr(PvArgs) args = pv_args_new(); g_autoptr(PvArgs) args = pv_args_new();
@@ -177,5 +181,20 @@ error:
rmdir_recursive(tmp_dir, NULL); rmdir_recursive(tmp_dir, NULL);
remove_signal_handler(signals, G_N_ELEMENTS(signals)); remove_signal_handler(signals, G_N_ELEMENTS(signals));
g_free(tmp_dir); g_free(tmp_dir);
g_clear_pointer(&img, pv_img_free);
g_clear_pointer(&args, pv_args_free);
exit(ret); exit(ret);
} }
static void __init(void)
{
pv_crypto_init();
if (curl_init() != 0)
g_abort();
}
static void __cleanup(void)
{
curl_cleanup();
pv_crypto_cleanup();
}
+18
View File
@@ -14,6 +14,24 @@
#include "lib/zt_common.h" #include "lib/zt_common.h"
/* IBM signing key subject */
#define PV_IBM_Z_SUBJECT_COMMON_NAME "International Business Machines Corporation"
#define PV_IBM_Z_SUBJECT_COUNTRY_NAME "US"
#define PV_IBM_Z_SUBJECT_LOCALITY_NAME "Poughkeepsie"
#define PV_IBM_Z_SUBJECT_ORGANIZATIONONAL_UNIT_NAME_SUFFIX "Key Signing Service"
#define PV_IBM_Z_SUBJECT_ORGANIZATION_NAME "International Business Machines Corporation"
#define PV_IBM_Z_SUBJECT_STATE "New York"
#define PV_IMB_Z_SUBJECT_ENTRY_COUNT 6
/* Minimum security level for the keys/certificates used to establish a chain of
* trust (see https://www.openssl.org/docs/man1.1.1/man3/X509_VERIFY_PARAM_set_auth_level.html
* for details).
*/
#define PV_CERTS_SECURITY_LEVEL 2
/* SKID for DigiCert Assured ID Root CA */
#define DIGICERT_ASSURED_ID_ROOT_CA_SKID "45EBA2AFF492CB82312D518BA7A7219DF36DC80F"
union ecdh_pub_key { union ecdh_pub_key {
struct { struct {
uint8_t x[80]; uint8_t x[80];
+5 -2
View File
@@ -24,8 +24,11 @@
#define PV_MAGIC_NUMBER 0x49424d5365634578ULL #define PV_MAGIC_NUMBER 0x49424d5365634578ULL
#define PV_VERSION_1 0x00000100U #define PV_VERSION_1 0x00000100U
/* prevent Ultravisor decryption during unpack operation */ /* Plaintext control flags */
#define PV_CFLAG_NO_DECRYPTION 0x10000000ULL #define PV_PCF_PCKM_ECC (1ULL << 5) /* PCKMO encrypt-ECC-key functions allowed */
#define PV_PCF_PCKMO_AES (1ULL << 6) /* PCKMO encrypt-AES-key functions allowed */
#define PV_PCF_PCKMO_DEA_TDEA (1ULL << 7) /* PCKMO encrypt-DEA/TDEA-key functions allowed */
#define PV_PCF_NO_DECRYPTION (1ULL << 28) /* prevent Ultravisor decryption during unpack operation */
/* maxima for the PV version 1 */ /* maxima for the PV version 1 */
#define PV_V1_IPIB_MAX_SIZE PAGE_SIZE #define PV_V1_IPIB_MAX_SIZE PAGE_SIZE
+93 -7
View File
@@ -18,7 +18,9 @@
static gchar summary[] = static gchar summary[] =
"Use genprotimg to create a protected virtualization kernel image file,\n" "Use genprotimg to create a protected virtualization kernel image file,\n"
"which can be loaded using zipl or QEMU."; "which can be loaded using zipl or QEMU. For all certificates, revocation\n"
"lists, and host-key documents, both the PEM and DER input formats are\n"
"supported.";
static gint pv_arg_compare(gconstpointer arg_1, gconstpointer arg_2) static gint pv_arg_compare(gconstpointer arg_1, gconstpointer arg_2)
{ {
@@ -62,6 +64,13 @@ static gint pv_args_validate_options(PvArgs *args, GError **err)
{ {
PvComponentType KERNEL = PV_COMP_TYPE_KERNEL; PvComponentType KERNEL = PV_COMP_TYPE_KERNEL;
if (args->pcf && args->allow_pckmo != PV_NOT_SET) {
g_set_error(err, PV_PARSE_ERROR, PV_PARSE_ERROR_SYNTAX,
_("The '--x-pcf' and '--(enable|disable)-pckmo' options are mutually"
" exclusive.\nUse 'genprotimg --help' for more information"));
return -1;
}
if (args->unused_values->len > 0) { if (args->unused_values->len > 0) {
g_autofree gchar *unused = NULL; g_autofree gchar *unused = NULL;
@@ -97,9 +106,14 @@ static gint pv_args_validate_options(PvArgs *args, GError **err)
return -1; return -1;
} }
if (!args->no_verify) { if (!args->no_verify &&
g_set_error(err, PV_PARSE_ERROR, PR_PARSE_ERROR_MISSING_ARGUMENT, (!args->untrusted_cert_paths ||
_("Use the option '--no-verify' as the verification support is not available yet.")); g_strv_length(args->untrusted_cert_paths) == 0)) {
g_set_error(
err, PV_PARSE_ERROR, PR_PARSE_ERROR_MISSING_ARGUMENT,
_("Either specify the IBM Z signing key and (DigiCert) intermediate CA certificate\n"
"by using the '--cert' option, or use the '--no-verify' flag to disable the\n"
"host-key document verification completely (at your own risk)."));
return -1; return -1;
} }
@@ -141,6 +155,8 @@ static gboolean cb_set_string_option(const gchar *option, const gchar *value,
{ {
gchar **args_option = NULL; gchar **args_option = NULL;
if (g_str_equal(option, "--root-ca"))
args_option = &args->root_ca_path;
if (g_str_equal(option, "-o") || g_str_equal(option, "--output")) if (g_str_equal(option, "-o") || g_str_equal(option, "--output"))
args_option = &args->output_path; args_option = &args->output_path;
if (g_str_equal(option, "--x-comp-key")) if (g_str_equal(option, "--x-comp-key"))
@@ -172,6 +188,19 @@ static gboolean cb_set_string_option(const gchar *option, const gchar *value,
return TRUE; return TRUE;
} }
static gboolean cb_enable_disable_flag(const gchar *option, const gchar *value G_GNUC_UNUSED,
PvArgs *args, GError **err G_GNUC_UNUSED)
{
if (g_str_equal(option, "--enable-pckmo"))
args->allow_pckmo = PV_TRUE;
else if (g_str_equal(option, "--disable-pckmo"))
args->allow_pckmo = PV_FALSE;
else
g_assert_not_reached();
return TRUE;
}
static gboolean cb_set_log_level(const gchar *option G_GNUC_UNUSED, static gboolean cb_set_log_level(const gchar *option G_GNUC_UNUSED,
const gchar *value G_GNUC_UNUSED, PvArgs *args, const gchar *value G_GNUC_UNUSED, PvArgs *args,
GError **err G_GNUC_UNUSED) GError **err G_GNUC_UNUSED)
@@ -211,6 +240,18 @@ gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[],
_("FILE specifies a host-key document. At least\n" INDENT _("FILE specifies a host-key document. At least\n" INDENT
"one is required."), "one is required."),
.arg_description = _("FILE") }, .arg_description = _("FILE") },
{ .long_name = "cert",
.short_name = 'C',
.flags = G_OPTION_FLAG_NONE,
.arg = G_OPTION_ARG_FILENAME_ARRAY,
.arg_data = &args->untrusted_cert_paths,
.description = _(
"FILE contains a certificate that is used to\n" INDENT
"establish a chain of trust for the verification\n" INDENT
"of the host-key documents. The IBM Z signing\n" INDENT
"key and intermediate CA certificate (signed\n" INDENT
"by the root CA) are required."),
.arg_description = _("FILE") },
{ .long_name = "output", { .long_name = "output",
.short_name = 'o', .short_name = 'o',
.flags = G_OPTION_FLAG_FILENAME, .flags = G_OPTION_FLAG_FILENAME,
@@ -227,7 +268,7 @@ gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[],
.arg_description = _("IMAGE") }, .arg_description = _("IMAGE") },
{ .long_name = "ramdisk", { .long_name = "ramdisk",
.short_name = 'r', .short_name = 'r',
.flags = G_OPTION_FLAG_OPTIONAL_ARG | G_OPTION_FLAG_FILENAME, .flags = G_OPTION_FLAG_FILENAME,
.arg = G_OPTION_ARG_CALLBACK, .arg = G_OPTION_ARG_CALLBACK,
.arg_data = cb_add_component, .arg_data = cb_add_component,
.description = _("Use RAMDISK as the initial RAM disk\n" INDENT .description = _("Use RAMDISK as the initial RAM disk\n" INDENT
@@ -235,12 +276,52 @@ gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[],
.arg_description = _("RAMDISK") }, .arg_description = _("RAMDISK") },
{ .long_name = "parmfile", { .long_name = "parmfile",
.short_name = 'p', .short_name = 'p',
.flags = G_OPTION_FLAG_OPTIONAL_ARG | G_OPTION_FLAG_FILENAME, .flags = G_OPTION_FLAG_FILENAME,
.arg = G_OPTION_ARG_CALLBACK, .arg = G_OPTION_ARG_CALLBACK,
.arg_data = cb_add_component, .arg_data = cb_add_component,
.description = _("Use the kernel parameters stored in PARMFILE\n" INDENT .description = _("Use the kernel parameters stored in PARMFILE\n" INDENT
"(optional)."), "(optional)."),
.arg_description = _("PARMFILE") }, .arg_description = _("PARMFILE") },
{.long_name = "enable-pckmo",
.short_name = 0,
.flags = G_OPTION_FLAG_NO_ARG,
.arg = G_OPTION_ARG_CALLBACK,
.arg_data = cb_enable_disable_flag,
.description = _("Enable the support for the DEA, TDEA, AES, and\n" INDENT
"ECC PCKMO key encryption functions (default)\n" INDENT
"(optional).")},
{.long_name = "disable-pckmo",
.short_name = 0,
.flags = G_OPTION_FLAG_NO_ARG,
.arg = G_OPTION_ARG_CALLBACK,
.arg_data = cb_enable_disable_flag,
.description = _("Disable the support for the DEA, TDEA, AES, and\n" INDENT
"ECC PCKMO key encryption functions (optional).")},
{ .long_name = "crl",
.short_name = 0,
.flags = G_OPTION_FLAG_NONE,
.arg = G_OPTION_ARG_FILENAME_ARRAY,
.arg_data = &args->crl_paths,
.description = _(
"FILE contains a certificate revocation list\n" INDENT
"(optional)."),
.arg_description = _("FILE") },
{ .long_name = "offline",
.short_name = 0,
.flags = G_OPTION_FLAG_NONE,
.arg = G_OPTION_ARG_NONE,
.arg_data = &args->offline,
.description = _("Don't download CRLs (optional)."),
.arg_description = NULL },
{ .long_name = "root-ca",
.short_name = 0,
.flags = G_OPTION_FLAG_FILENAME,
.arg = G_OPTION_ARG_CALLBACK,
.arg_data = cb_set_string_option,
.description = _(
"Set FILE as the trusted root CA and don't use the\n" INDENT
"root CAs that are installed on the system (optional)."),
.arg_description = _("FILE") },
{ .long_name = "no-verify", { .long_name = "no-verify",
.short_name = 0, .short_name = 0,
.flags = G_OPTION_FLAG_NONE, .flags = G_OPTION_FLAG_NONE,
@@ -311,7 +392,8 @@ gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[],
.description = .description =
_("Specify the plaintext control flags\n" INDENT _("Specify the plaintext control flags\n" INDENT
"as a hexadecimal value.\n" INDENT "as a hexadecimal value.\n" INDENT
"Optional; default: '0x0'."), "Optional; mutually exclusive with\n" INDENT
"'--(enable|disable)-pckmo'; default: '0xe0'."),
.arg_description = _("VALUE") }, .arg_description = _("VALUE") },
{ .long_name = "x-psw", { .long_name = "x-psw",
.short_name = 0, .short_name = 0,
@@ -364,6 +446,7 @@ PvArgs *pv_args_new(void)
g_autoptr(PvArgs) args = g_new0(PvArgs, 1); g_autoptr(PvArgs) args = g_new0(PvArgs, 1);
args->unused_values = g_ptr_array_new_with_free_func(g_free); args->unused_values = g_ptr_array_new_with_free_func(g_free);
args->allow_pckmo = PV_NOT_SET;
return g_steal_pointer(&args); return g_steal_pointer(&args);
} }
@@ -378,6 +461,9 @@ void pv_args_free(PvArgs *args)
g_free(args->cust_root_key_path); g_free(args->cust_root_key_path);
g_free(args->cust_comm_key_path); g_free(args->cust_comm_key_path);
g_free(args->gcm_iv_path); g_free(args->gcm_iv_path);
g_free(args->root_ca_path);
g_strfreev(args->crl_paths);
g_strfreev(args->untrusted_cert_paths);
g_strfreev(args->host_keys); g_strfreev(args->host_keys);
g_free(args->xts_key_path); g_free(args->xts_key_path);
g_slist_free_full(args->comps, (GDestroyNotify)pv_arg_free); g_slist_free_full(args->comps, (GDestroyNotify)pv_arg_free);
+13
View File
@@ -22,11 +22,19 @@ typedef struct pv_arg {
PvArg *pv_arg_new(PvComponentType type, const gchar *path); PvArg *pv_arg_new(PvComponentType type, const gchar *path);
void pv_arg_free(PvArg *arg); void pv_arg_free(PvArg *arg);
typedef enum pv_tristate {
PV_NOT_SET = 0,
PV_TRUE,
PV_FALSE,
} PvTristate;
typedef struct { typedef struct {
gint log_level; gint log_level;
gint no_verify; gint no_verify;
gboolean offline;
gchar *pcf; gchar *pcf;
gchar *scf; gchar *scf;
PvTristate allow_pckmo;
gchar *psw_addr; /* PSW address which will be used for the start of gchar *psw_addr; /* PSW address which will be used for the start of
* the actual component (e.g. Linux kernel) * the actual component (e.g. Linux kernel)
*/ */
@@ -34,6 +42,11 @@ typedef struct {
gchar *cust_comm_key_path; gchar *cust_comm_key_path;
gchar *gcm_iv_path; gchar *gcm_iv_path;
gchar **host_keys; gchar **host_keys;
gchar *root_ca_path; /* Trusted root CA used for the verification of the
* chain of trust (if specified).
*/
gchar **untrusted_cert_paths;
gchar **crl_paths;
gchar *xts_key_path; gchar *xts_key_path;
GSList *comps; GSList *comps;
gchar *output_path; gchar *output_path;
+16 -13
View File
@@ -73,12 +73,12 @@ PvComponent *pv_component_new_file(PvComponentType type, const gchar *path,
return pv_component_new(type, size, DATA_FILE, (void **)&file, err); return pv_component_new(type, size, DATA_FILE, (void **)&file, err);
} }
PvComponent *pv_component_new_buf(PvComponentType type, const Buffer *buf, PvComponent *pv_component_new_buf(PvComponentType type, const PvBuffer *buf,
GError **err) GError **err)
{ {
g_assert(buf); g_assert(buf);
g_autoptr(Buffer) dup_buf = buffer_dup(buf, FALSE); g_autoptr(PvBuffer) dup_buf = pv_buffer_dup(buf, FALSE);
return pv_component_new(type, buf->size, DATA_BUFFER, (void **)&dup_buf, return pv_component_new(type, buf->size, DATA_BUFFER, (void **)&dup_buf,
err); err);
} }
@@ -90,7 +90,7 @@ void pv_component_free(PvComponent *component)
switch ((PvComponentDataType)component->d_type) { switch ((PvComponentDataType)component->d_type) {
case DATA_BUFFER: case DATA_BUFFER:
buffer_clear(&component->buf); pv_buffer_clear(&component->buf);
break; break;
case DATA_FILE: case DATA_FILE:
comp_file_free(component->file); comp_file_free(component->file);
@@ -162,21 +162,21 @@ gint pv_component_align_and_encrypt(PvComponent *component, const gchar *tmp_pat
switch ((PvComponentDataType)component->d_type) { switch ((PvComponentDataType)component->d_type) {
case DATA_BUFFER: { case DATA_BUFFER: {
g_autoptr(Buffer) enc_buf = NULL; g_autoptr(PvBuffer) enc_buf = NULL;
if (!(IS_PAGE_ALIGNED(pv_component_size(component)))) { if (!(IS_PAGE_ALIGNED(pv_component_size(component)))) {
g_autoptr(Buffer) new = NULL; g_autoptr(PvBuffer) new = NULL;
/* create a page aligned copy */ /* create a page aligned copy */
new = buffer_dup(component->buf, TRUE); new = pv_buffer_dup(component->buf, TRUE);
buffer_clear(&component->buf); pv_buffer_clear(&component->buf);
component->buf = g_steal_pointer(&new); component->buf = g_steal_pointer(&new);
} }
enc_buf = encrypt_buf(parms, component->buf, err); enc_buf = encrypt_buf(parms, component->buf, err);
if (!enc_buf) if (!enc_buf)
return -1; return -1;
buffer_clear(&component->buf); pv_buffer_clear(&component->buf);
component->buf = g_steal_pointer(&enc_buf); component->buf = g_steal_pointer(&enc_buf);
return 0; return 0;
} }
@@ -220,10 +220,10 @@ gint pv_component_align(PvComponent *component, const gchar *tmp_path,
switch (component->d_type) { switch (component->d_type) {
case DATA_BUFFER: { case DATA_BUFFER: {
g_autoptr(Buffer) buf = NULL; g_autoptr(PvBuffer) buf = NULL;
buf = buffer_dup(component->buf, TRUE); buf = pv_buffer_dup(component->buf, TRUE);
buffer_clear(&component->buf); pv_buffer_clear(&component->buf);
component->buf = g_steal_pointer(&buf); component->buf = g_steal_pointer(&buf);
return 0; return 0;
} break; } break;
@@ -301,7 +301,7 @@ int64_t pv_component_update_pld(const PvComponent *comp, EVP_MD_CTX *ctx,
switch (comp->d_type) { switch (comp->d_type) {
case DATA_BUFFER: { case DATA_BUFFER: {
const Buffer *buf = comp->buf; const PvBuffer *buf = comp->buf;
g_assert(buf->size <= INT64_MAX); g_assert(buf->size <= INT64_MAX);
g_assert(buf->size == size); g_assert(buf->size == size);
@@ -383,6 +383,7 @@ int64_t pv_component_update_tld(const PvComponent *comp, EVP_MD_CTX *ctx,
g_set_error(err, PV_CRYPTO_ERROR, g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL, PV_CRYPTO_ERROR_INTERNAL,
_("BN_bin2bn failed")); _("BN_bin2bn failed"));
return -1;
} }
for (uint64_t cur = 0; cur < size; cur += PAGE_SIZE) { for (uint64_t cur = 0; cur < size; cur += PAGE_SIZE) {
@@ -395,6 +396,7 @@ int64_t pv_component_update_tld(const PvComponent *comp, EVP_MD_CTX *ctx,
g_set_error(err, PV_CRYPTO_ERROR, g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL, PV_CRYPTO_ERROR_INTERNAL,
_("BN_bn2binpad failed")); _("BN_bn2binpad failed"));
return -1;
} }
if (EVP_DigestUpdate(ctx, tmp, sizeof(tmp)) != 1) { if (EVP_DigestUpdate(ctx, tmp, sizeof(tmp)) != 1) {
@@ -409,6 +411,7 @@ int64_t pv_component_update_tld(const PvComponent *comp, EVP_MD_CTX *ctx,
g_set_error(err, PV_CRYPTO_ERROR, g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL, PV_CRYPTO_ERROR_INTERNAL,
_("BN_add_word failed")); _("BN_add_word failed"));
return -1;
} }
nep++; nep++;
@@ -425,7 +428,7 @@ gint pv_component_write(const PvComponent *component, FILE *f, GError **err)
switch (component->d_type) { switch (component->d_type) {
case DATA_BUFFER: { case DATA_BUFFER: {
const Buffer *buf = component->buf; const PvBuffer *buf = component->buf;
if (seek_and_write_buffer(f, buf, offset, err) < 0) if (seek_and_write_buffer(f, buf, offset, err) < 0)
return -1; return -1;
+2 -2
View File
@@ -41,7 +41,7 @@ typedef struct {
gint d_type; /* PvComponentDataType */ gint d_type; /* PvComponentDataType */
union { union {
struct comp_file *file; struct comp_file *file;
Buffer *buf; PvBuffer *buf;
void *data; void *data;
}; };
uint64_t src_addr; uint64_t src_addr;
@@ -51,7 +51,7 @@ typedef struct {
PvComponent *pv_component_new_file(PvComponentType type, const gchar *path, PvComponent *pv_component_new_file(PvComponentType type, const gchar *path,
GError **err); GError **err);
PvComponent *pv_component_new_buf(PvComponentType type, const Buffer *buf, PvComponent *pv_component_new_buf(PvComponentType type, const PvBuffer *buf,
GError **err); GError **err);
void pv_component_free(PvComponent *component); void pv_component_free(PvComponent *component);
gint pv_component_type(const PvComponent *component); gint pv_component_type(const PvComponent *component);
+5 -5
View File
@@ -210,13 +210,13 @@ GSList *pv_img_comps_get_comps(const PvImgComps *comps)
return comps->comps; return comps->comps;
} }
gint pv_img_comps_finalize(PvImgComps *comps, Buffer **pld_digest, gint pv_img_comps_finalize(PvImgComps *comps, PvBuffer **pld_digest,
Buffer **ald_digest, Buffer **tld_digest, PvBuffer **ald_digest, PvBuffer **tld_digest,
uint64_t *nep, GError **err) uint64_t *nep, GError **err)
{ {
g_autoptr(Buffer) tmp_pld_digest = NULL; g_autoptr(PvBuffer) tmp_pld_digest = NULL;
g_autoptr(Buffer) tmp_ald_digest = NULL; g_autoptr(PvBuffer) tmp_ald_digest = NULL;
g_autoptr(Buffer) tmp_tld_digest = NULL; g_autoptr(PvBuffer) tmp_tld_digest = NULL;
comps->finalized = TRUE; comps->finalized = TRUE;
for (GSList *iterator = comps->comps; iterator; iterator = iterator->next) { for (GSList *iterator = comps->comps; iterator; iterator = iterator->next) {
+2 -2
View File
@@ -32,8 +32,8 @@ gint pv_img_comps_add_component(PvImgComps *comps, PvComponent **comp,
GError **err); GError **err);
PvComponent *pv_img_comps_get_nth_comp(PvImgComps *comps, guint n); PvComponent *pv_img_comps_get_nth_comp(PvImgComps *comps, guint n);
gint pv_img_comps_set_offset(PvImgComps *comps, gsize offset, GError **err); gint pv_img_comps_set_offset(PvImgComps *comps, gsize offset, GError **err);
gint pv_img_comps_finalize(PvImgComps *comps, Buffer **pld_digest, gint pv_img_comps_finalize(PvImgComps *comps, PvBuffer **pld_digest,
Buffer **ald_digest, Buffer **tld_digest, PvBuffer **ald_digest, PvBuffer **tld_digest,
uint64_t *nep, GError **err); uint64_t *nep, GError **err);
void pv_img_comps_free(PvImgComps *comps); void pv_img_comps_free(PvImgComps *comps);
+27
View File
@@ -28,6 +28,8 @@ typedef enum {
PV_ERROR_IPIB_SIZE, PV_ERROR_IPIB_SIZE,
PV_ERROR_PV_HDR_SIZE, PV_ERROR_PV_HDR_SIZE,
PV_ERROR_INTERNAL, PV_ERROR_INTERNAL,
PV_ERROR_CURL_INIT_FAILED,
PV_ERROR_DOWNLOAD_FAILED,
} PvErrors; } PvErrors;
typedef enum { typedef enum {
@@ -57,6 +59,31 @@ typedef enum {
PV_CRYPTO_ERROR_RANDOMIZATION, PV_CRYPTO_ERROR_RANDOMIZATION,
PV_CRYPTO_ERROR_INVALID_PARM, PV_CRYPTO_ERROR_INVALID_PARM,
PV_CRYPTO_ERROR_INVALID_KEY_SIZE, PV_CRYPTO_ERROR_INVALID_KEY_SIZE,
PV_CRYPTO_ERROR_INVALID_VALIDITY_PERIOD,
PV_CRYPTO_ERROR_EXPIRED,
PV_CRYPTO_ERROR_NOT_VALID_YET,
PV_CRYPTO_ERROR_LOAD_CRL,
PV_CRYPTO_ERROR_NO_PUBLIC_KEY,
PV_CRYPTO_ERROR_INVALID_SIGNATURE_ALGORITHM,
PV_CRYPTO_ERROR_SIGNATURE_ALGORITHM_MISMATCH,
PV_CRYPTO_ERROR_INVALID_URI,
PV_CRYPTO_ERROR_CRL_DOWNLOAD_FAILED,
PV_CRYPTO_ERROR_CERT_SIGNATURE_INVALID,
PV_CRYPTO_ERROR_CRL_SIGNATURE_INVALID,
PV_CRYPTO_ERROR_CERT_SUBJECT_ISSUER_MISMATCH,
PV_CRYPTO_ERROR_CRL_SUBJECT_ISSUER_MISMATCH,
PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY,
PV_CRYPTO_ERROR_MALFORMED_CERTIFICATE,
PV_CRYPTO_ERROR_NO_CRL,
PV_CRYPTO_ERROR_LOAD_ROOT_CA,
PV_CRYPTO_ERROR_LOAD_DEFAULT_CA,
PV_CRYPTO_ERROR_MALFORMED_ROOT_CA,
PV_CRYPTO_ERROR_WRONG_CA_USED,
PV_CRYPTO_ERROR_SKID_AKID_MISMATCH,
PV_CRYPTO_ERROR_NO_ISSUER_IBM_Z_FOUND,
PV_CRYPTO_ERROR_FAILED_DOWNLOAD_CRL,
PV_CRYPTO_ERROR_NO_CRLDP,
PV_CRYPTO_ERROR_CERT_REVOKED,
} PvCryptoErrors; } PvCryptoErrors;
#endif #endif
+13 -13
View File
@@ -41,7 +41,7 @@ uint32_t pv_hdr_size(const PvHdr *hdr)
gboolean pv_hdr_uses_encryption(const PvHdr *hdr) gboolean pv_hdr_uses_encryption(const PvHdr *hdr)
{ {
return !(GUINT64_FROM_BE(hdr->head.pcf) & PV_CFLAG_NO_DECRYPTION); return !(GUINT64_FROM_BE(hdr->head.pcf) & PV_PCF_NO_DECRYPTION);
} }
uint64_t pv_hdr_enc_size(const PvHdr *hdr) uint64_t pv_hdr_enc_size(const PvHdr *hdr)
@@ -76,17 +76,17 @@ uint64_t pv_hdr_get_nks(const PvHdr *hdr)
} }
/* In-place modification of ``buf`` */ /* In-place modification of ``buf`` */
static gint pv_hdr_encrypt(const PvHdr *hdr, const PvImage *img, Buffer *buf, static gint pv_hdr_encrypt(const PvHdr *hdr, const PvImage *img, PvBuffer *buf,
GError **err) GError **err)
{ {
uint32_t hdr_len = pv_hdr_size(hdr); uint32_t hdr_len = pv_hdr_size(hdr);
uint32_t aad_len = pv_hdr_aad_size(hdr); uint32_t aad_len = pv_hdr_aad_size(hdr);
guint tag_len = pv_hdr_tag_size(hdr); guint tag_len = pv_hdr_tag_size(hdr);
uint32_t enc_len = pv_hdr_enc_size_casted(hdr); uint32_t enc_len = pv_hdr_enc_size_casted(hdr);
const Buffer aad_part = { .data = buf->data, .size = aad_len }; const PvBuffer aad_part = { .data = buf->data, .size = aad_len };
Buffer enc_part = { .data = (uint8_t *)buf->data + aad_len, PvBuffer enc_part = { .data = (uint8_t *)buf->data + aad_len,
.size = enc_len }; .size = enc_len };
Buffer tag_part = { .data = (uint8_t *)buf->data + hdr_len - tag_len, PvBuffer tag_part = { .data = (uint8_t *)buf->data + hdr_len - tag_len,
.size = tag_len }; .size = tag_len };
struct cipher_parms parms; struct cipher_parms parms;
int64_t c_len; int64_t c_len;
@@ -119,9 +119,9 @@ static gint pv_hdr_aad_init(PvHdr *hdr, const PvImage *img, GError **err)
g_autofree union ecdh_pub_key *cust_pub_key = NULL; g_autofree union ecdh_pub_key *cust_pub_key = NULL;
struct pv_hdr_key_slot *hdr_slot = hdr->slots; struct pv_hdr_key_slot *hdr_slot = hdr->slots;
struct pv_hdr_head *head = &hdr->head; struct pv_hdr_head *head = &hdr->head;
g_autoptr(Buffer) pld = NULL; g_autoptr(PvBuffer) pld = NULL;
g_autoptr(Buffer) ald = NULL; g_autoptr(PvBuffer) ald = NULL;
g_autoptr(Buffer) tld = NULL; g_autoptr(PvBuffer) tld = NULL;
uint64_t nep = 0; uint64_t nep = 0;
g_assert(sizeof(head->iv) == img->gcm_iv->size); g_assert(sizeof(head->iv) == img->gcm_iv->size);
@@ -250,7 +250,7 @@ PvHdr *pv_hdr_new(const PvImage *img, GError **err)
return g_steal_pointer(&ret); return g_steal_pointer(&ret);
} }
static void pv_hdr_memcpy(const PvHdr *hdr, const Buffer *dst) static void pv_hdr_memcpy(const PvHdr *hdr, const PvBuffer *dst)
{ {
uint64_t nks = pv_hdr_get_nks(hdr); uint64_t nks = pv_hdr_get_nks(hdr);
uint8_t *data; uint8_t *data;
@@ -270,13 +270,13 @@ static void pv_hdr_memcpy(const PvHdr *hdr, const Buffer *dst)
} }
} }
Buffer *pv_hdr_serialize(const PvHdr *hdr, const PvImage *img, PvBuffer *pv_hdr_serialize(const PvHdr *hdr, const PvImage *img,
enum PvCryptoMode mode, GError **err) enum PvCryptoMode mode, GError **err)
{ {
uint32_t hdr_size = pv_hdr_size(hdr); uint32_t hdr_size = pv_hdr_size(hdr);
g_autoptr(Buffer) ret = NULL; g_autoptr(PvBuffer) ret = NULL;
ret = buffer_alloc(hdr_size); ret = pv_buffer_alloc(hdr_size);
pv_hdr_memcpy(hdr, ret); pv_hdr_memcpy(hdr, ret);
if (mode == PV_ENCRYPT) { if (mode == PV_ENCRYPT) {
+2 -2
View File
@@ -23,8 +23,8 @@
PvHdr *pv_hdr_new(const PvImage *img, GError **err); PvHdr *pv_hdr_new(const PvImage *img, GError **err);
void pv_hdr_free(PvHdr *hdr); void pv_hdr_free(PvHdr *hdr);
G_GNUC_UNUSED gboolean pv_hdr_uses_encryption(const PvHdr *hdr); G_GNUC_UNUSED gboolean pv_hdr_uses_encryption(const PvHdr *hdr);
Buffer *pv_hdr_serialize(const PvHdr *hdr, const PvImage *img, PvBuffer *pv_hdr_serialize(const PvHdr *hdr, const PvImage *img,
enum PvCryptoMode mode, GError **err); enum PvCryptoMode mode, GError **err);
uint32_t pv_hdr_size(const PvHdr *hdr); uint32_t pv_hdr_size(const PvHdr *hdr);
uint32_t pv_hdr_aad_size(const PvHdr *hdr); uint32_t pv_hdr_aad_size(const PvHdr *hdr);
uint64_t pv_hdr_enc_size(const PvHdr *hdr); uint64_t pv_hdr_enc_size(const PvHdr *hdr);
+235 -50
View File
@@ -10,6 +10,7 @@
#include <errno.h> #include <errno.h>
#include <glib.h> #include <glib.h>
#include <openssl/evp.h> #include <openssl/evp.h>
#include <openssl/x509.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -55,12 +56,12 @@ static gint pv_img_prepare_component(const PvImage *img, PvComponent *comp,
GError **err) GError **err)
{ {
struct cipher_parms parms = { 0 }; struct cipher_parms parms = { 0 };
g_autoptr(Buffer) tweak = NULL; g_autoptr(PvBuffer) tweak = NULL;
prepare_func func = NULL; prepare_func func = NULL;
void *opaque = NULL; void *opaque = NULL;
gint rc; gint rc;
if (img->pcf & PV_CFLAG_NO_DECRYPTION) { if (img->pcf & PV_PCF_NO_DECRYPTION) {
/* we only need to align the components */ /* we only need to align the components */
func = pv_component_align; func = pv_component_align;
opaque = NULL; opaque = NULL;
@@ -75,7 +76,7 @@ static gint pv_img_prepare_component(const PvImage *img, PvComponent *comp,
EVP_CIPHER_iv_length(cipher)); EVP_CIPHER_iv_length(cipher));
g_assert(img->xts_key->size <= UINT_MAX); g_assert(img->xts_key->size <= UINT_MAX);
tweak = buffer_alloc(sizeof(comp->tweak.data)); tweak = pv_buffer_alloc(sizeof(comp->tweak.data));
memcpy(tweak->data, comp->tweak.data, tweak->size); memcpy(tweak->data, comp->tweak.data, tweak->size);
func = pv_component_align_and_encrypt; func = pv_component_align_and_encrypt;
parms.cipher = cipher; parms.cipher = cipher;
@@ -92,11 +93,11 @@ static gint pv_img_prepare_component(const PvImage *img, PvComponent *comp,
return 0; return 0;
} }
static Buffer *pv_img_read_key(const gchar *path, guint key_size, static PvBuffer *pv_img_read_key(const gchar *path, guint key_size,
GError **err) GError **err)
{ {
g_autoptr(Buffer) tmp_ret = NULL; g_autoptr(PvBuffer) tmp_ret = NULL;
Buffer *ret = NULL; PvBuffer *ret = NULL;
gsize bytes_read; gsize bytes_read;
FILE *f = NULL; FILE *f = NULL;
gsize size; gsize size;
@@ -115,7 +116,7 @@ static Buffer *pv_img_read_key(const gchar *path, guint key_size,
if (!f) if (!f)
return NULL; return NULL;
tmp_ret = buffer_alloc(size); tmp_ret = pv_buffer_alloc(size);
if (file_read(f, tmp_ret->data, 1, tmp_ret->size, &bytes_read, err) < 0) if (file_read(f, tmp_ret->data, 1, tmp_ret->size, &bytes_read, err) < 0)
goto err; goto err;
@@ -138,22 +139,18 @@ static EVP_PKEY *pv_img_get_cust_pub_priv_key(gint nid, GError **err)
return generate_ec_key(nid, err); return generate_ec_key(nid, err);
} }
static HostKeyList *pv_img_get_host_keys(gchar **host_cert_paths, static HostKeyList *pv_img_get_host_keys(GSList *host_keys_with_path, gint nid,
X509_STORE *store, gint nid,
GError **err) GError **err)
{ {
g_autoslist(EVP_PKEY) ret = NULL; g_autoslist(EVP_PKEY) ret = NULL;
g_assert(host_cert_paths); for (GSList *iterator = host_keys_with_path; iterator;
iterator = iterator->next) {
for (gchar **iterator = host_cert_paths; iterator != NULL && *iterator != NULL; x509_with_path *cert_with_path = iterator->data;
iterator++) {
g_autoptr(EVP_PKEY) host_key = NULL; g_autoptr(EVP_PKEY) host_key = NULL;
const gchar *path = *iterator; X509 *cert = cert_with_path->cert;
g_assert(path); host_key = read_ec_pubkey_cert(cert, nid, err);
host_key = read_ec_pubkey_cert(store, nid, path, err);
if (!host_key) if (!host_key)
return NULL; return NULL;
@@ -163,8 +160,8 @@ static HostKeyList *pv_img_get_host_keys(gchar **host_cert_paths,
return g_steal_pointer(&ret); return g_steal_pointer(&ret);
} }
static Buffer *pv_img_get_key(const EVP_CIPHER *cipher, const gchar *path, static PvBuffer *pv_img_get_key(const EVP_CIPHER *cipher, const gchar *path,
GError **err) GError **err)
{ {
gint key_len = EVP_CIPHER_key_length(cipher); gint key_len = EVP_CIPHER_key_length(cipher);
@@ -176,8 +173,8 @@ static Buffer *pv_img_get_key(const EVP_CIPHER *cipher, const gchar *path,
return generate_aes_key((guint)key_len, err); return generate_aes_key((guint)key_len, err);
} }
static Buffer *pv_img_get_iv(const EVP_CIPHER *cipher, const gchar *path, static PvBuffer *pv_img_get_iv(const EVP_CIPHER *cipher, const gchar *path,
GError **err) GError **err)
{ {
gint iv_len = EVP_CIPHER_iv_length(cipher); gint iv_len = EVP_CIPHER_iv_length(cipher);
@@ -232,7 +229,7 @@ static gint pv_img_set_psw_addr(PvImage *img, const gchar *psw_addr_s,
} }
static gint pv_img_set_control_flags(PvImage *img, const gchar *pcf_s, static gint pv_img_set_control_flags(PvImage *img, const gchar *pcf_s,
const gchar *scf_s, GError **err) const gchar *scf_s, PvTristate allow_pckmo, GError **err)
{ {
uint64_t flags; uint64_t flags;
@@ -250,13 +247,180 @@ static gint pv_img_set_control_flags(PvImage *img, const gchar *pcf_s,
img->scf = flags; img->scf = flags;
} }
if (allow_pckmo == PV_TRUE)
img->pcf |= PV_PCF_PCKM_ECC | PV_PCF_PCKMO_AES | PV_PCF_PCKMO_DEA_TDEA;
else if (allow_pckmo == PV_FALSE)
img->pcf &= ~(PV_PCF_PCKM_ECC | PV_PCF_PCKMO_AES | PV_PCF_PCKMO_DEA_TDEA);
return 0; return 0;
} }
static gint pv_img_hostkey_verify(GSList *host_key_certs,
const gchar *root_ca_path,
const gchar *const *crl_paths,
const gchar *const *untrusted_cert_paths,
gboolean offline, GError **err)
{
g_autoslist(x509_with_path) untrusted_certs_with_path = NULL;
g_autoptr(STACK_OF_X509) ibm_signing_certs = NULL;
g_autoptr(STACK_OF_X509) untrusted_certs = NULL;
g_autoslist(x509_pair) ibm_z_pairs = NULL;
g_autoptr(X509_STORE) trusted = NULL;
gint ibm_signing_certs_count;
/* Load trusted root CAs of the system if and only if @root_ca_path is
* NULL, otherwise use the root CA specified by @root_ca_path.
*/
trusted = store_setup(root_ca_path, crl_paths, err);
if (!trusted)
goto error;
if (!offline) {
g_autoptr(STACK_OF_X509_CRL) downloaded_ibm_signing_crls = NULL;
/* Set up the download routine for the lookup of CRLs. */
store_setup_crl_download(trusted);
/* Try to download the CRLs of the IBM Z signing certificates
* specified in the host-key documents. Ignore download errors
* as it's still possible that a CRL is specified via command
* line.
*/
downloaded_ibm_signing_crls = try_load_crls_by_certs(host_key_certs);
/* Add the downloaded CRLs to the store so they can be used for
* the verification later.
*/
for (int i = 0; i < sk_X509_CRL_num(downloaded_ibm_signing_crls); i++) {
X509_CRL *crl = sk_X509_CRL_value(downloaded_ibm_signing_crls, i);
if (X509_STORE_add_crl(trusted, crl) != 1) {
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL,
_("failed to load CRL"));
goto error;
}
}
}
/* Load all untrusted certificates (e.g. IBM Z signing key and
* DigiCert intermediate CA) that are required to establish a chain of
* trust starting from the host-key document up to the root CA (if not
* otherwise specified that's the DigiCert Assured ID Root CA).
*/
untrusted_certs_with_path = load_certificates(untrusted_cert_paths, err);
if (!untrusted_certs_with_path)
goto error;
/* Convert to STACK_OF(X509) */
untrusted_certs = get_x509_stack(untrusted_certs_with_path);
/* Find all IBM Z signing keys and remove them from the chain as we
* have to verify that they're valid. The last step of the chain of
* trust verification must be done manually, as the IBM Z signing keys
* are not marked as (intermediate) CA and therefore the standard
* `X509_verify_cert` function of OpenSSL cannot be used to verify the
* actual host-key documents.
*/
ibm_signing_certs = delete_ibm_signing_certs(untrusted_certs);
ibm_signing_certs_count = sk_X509_num(ibm_signing_certs);
if (ibm_signing_certs_count < 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY,
_("please specify at least one IBM Z signing key"));
goto error;
} else if (ibm_signing_certs_count > 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY,
_("please specify only one IBM Z signing key"));
goto error;
}
if (store_set_verify_param(trusted, err) < 0)
goto error;
/* Verify that the IBM Z signing keys are trustable.
* For this we must check:
*
* 1. Can a chain of trust be established ending in a root CA
* 2. Is the correct root CA ued? It has either to be the
* 'DigiCert Assured ID Root CA' or the root CA specified via
* command line.
*/
for (gint i = 0; i < sk_X509_num(ibm_signing_certs); ++i) {
X509 *ibm_signing_cert = sk_X509_value(ibm_signing_certs, i);
g_autoptr(STACK_OF_X509_CRL) ibm_signing_crls = NULL;
g_autoptr(X509_STORE_CTX) ctx = NULL;
x509_pair *pair = NULL;
g_assert(ibm_signing_cert);
/* Create the verification context and set the trusted
* and chain parameters.
*/
ctx = create_store_ctx(trusted, untrusted_certs, err);
if (!ctx)
goto error;
/* Verify the IBM Z signing key */
if (verify_cert(ibm_signing_cert, ctx, err) < 0)
goto error;
/* Verify the build chain of trust chain. If the user passes a
* trusted root CA on the command line then the check for the
* Subject Key Identifier (SKID) is skipped, otherwise let's
* check if the SKID meets our expectation.
*/
if (!root_ca_path &&
check_chain_parameters(X509_STORE_CTX_get0_chain(ctx),
get_digicert_assured_id_root_ca_skid(),
err) < 0) {
goto error;
}
ibm_signing_crls = store_ctx_find_valid_crls(ctx, ibm_signing_cert, err);
if (!ibm_signing_crls) {
g_prefix_error(err, _("IBM Z signing key: "));
goto error;
}
/* Increment reference counter of @ibm_signing_cert as the
* certificate will now also be owned by @ibm_z_pairs.
*/
if (X509_up_ref(ibm_signing_cert) != 1)
g_abort();
pair = x509_pair_new(&ibm_signing_cert, &ibm_signing_crls);
ibm_z_pairs = g_slist_append(ibm_z_pairs, pair);
g_assert(!ibm_signing_cert);
g_assert(!ibm_signing_crls);
}
/* Verify host-key documents by using the IBM Z signing
* certificates and the corresponding certificate revocation
* lists.
*/
for (GSList *iterator = host_key_certs; iterator; iterator = iterator->next) {
x509_with_path *host_key_with_path = iterator->data;
const gchar *host_key_path = host_key_with_path->path;
X509 *host_key = host_key_with_path->cert;
gint flags = X509_V_FLAG_CRL_CHECK;
if (verify_host_key(host_key, ibm_z_pairs, flags,
PV_CERTS_SECURITY_LEVEL, err) < 0) {
g_prefix_error(err, "'%s': ", host_key_path);
goto error;
}
}
return 0;
error:
g_prefix_error(err, _("Failed to verify host-key document: "));
return -1;
}
/* read in the keys or auto-generate them */ /* read in the keys or auto-generate them */
static gint pv_img_set_keys(PvImage *img, const PvArgs *args, GError **err) static gint pv_img_set_keys(PvImage *img, const PvArgs *args, GError **err)
{ {
g_autoptr(X509_STORE) store = NULL; g_autoslist(x509_with_path) host_key_certs = NULL;
g_assert(img->xts_cipher); g_assert(img->xts_cipher);
g_assert(img->cust_comm_cipher); g_assert(img->cust_comm_cipher);
@@ -285,8 +449,25 @@ static gint pv_img_set_keys(PvImage *img, const PvArgs *args, GError **err)
if (!img->cust_pub_priv_key) if (!img->cust_pub_priv_key)
return -1; return -1;
/* Load all host-key documents specified on the command line */
host_key_certs = load_certificates((const gchar **)args->host_keys,
err);
if (!host_key_certs)
return -1;
if (!args->no_verify &&
pv_img_hostkey_verify(host_key_certs, args->root_ca_path,
(const gchar * const *)args->crl_paths,
(const gchar * const *)args->untrusted_cert_paths,
args->offline, err) < 0) {
return -1;
}
/* Loads the public keys stored in the host-key documents and verify
* that the correct elliptic curve is used.
*/
img->host_pub_keys = img->host_pub_keys =
pv_img_get_host_keys(args->host_keys, store, img->nid, err); pv_img_get_host_keys(host_key_certs, img->nid, err);
if (!img->host_pub_keys) if (!img->host_pub_keys)
return -1; return -1;
@@ -309,23 +490,23 @@ static void pv_hdr_key_slot_free(PvHdrKeySlot *slot)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(PvHdrKeySlot, pv_hdr_key_slot_free) WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(PvHdrKeySlot, pv_hdr_key_slot_free)
static PvHdrKeySlot *pv_hdr_key_slot_new(const EVP_CIPHER *gcm_cipher, static PvHdrKeySlot *pv_hdr_key_slot_new(const EVP_CIPHER *gcm_cipher,
const Buffer *cust_root_key, const PvBuffer *cust_root_key,
EVP_PKEY *cust_key, EVP_PKEY *host_key, EVP_PKEY *cust_key, EVP_PKEY *host_key,
GError **err) GError **err)
{ {
g_autoptr(PvHdrKeySlot) ret = g_new0(PvHdrKeySlot, 1); g_autoptr(PvHdrKeySlot) ret = g_new0(PvHdrKeySlot, 1);
g_autofree union ecdh_pub_key *pub = NULL; g_autofree union ecdh_pub_key *pub = NULL;
g_autoptr(Buffer) exchange_key = NULL; g_autoptr(PvBuffer) exchange_key = NULL;
g_autoptr(Buffer) digest_key = NULL; g_autoptr(PvBuffer) digest_key = NULL;
g_autoptr(Buffer) iv = NULL; g_autoptr(PvBuffer) iv = NULL;
Buffer pub_buf; PvBuffer pub_buf;
/* No AAD data is used */ /* No AAD data is used */
Buffer aad = { .data = NULL, .size = 0 }; PvBuffer aad = { .data = NULL, .size = 0 };
/* Set the output buffers for the encrypted data and the /* Set the output buffers for the encrypted data and the
* generated GCM tag * generated GCM tag
*/ */
Buffer enc = { .data = ret->wrapped_key, .size = sizeof(ret->wrapped_key) }; PvBuffer enc = { .data = ret->wrapped_key, .size = sizeof(ret->wrapped_key) };
Buffer tag = { .data = ret->tag, .size = sizeof(ret->tag) }; PvBuffer tag = { .data = ret->tag, .size = sizeof(ret->tag) };
struct cipher_parms parms; struct cipher_parms parms;
int64_t c_len = 0; int64_t c_len = 0;
@@ -354,7 +535,7 @@ static PvHdrKeySlot *pv_hdr_key_slot_new(const EVP_CIPHER *gcm_cipher,
g_assert(exchange_key->size == (guint)EVP_CIPHER_key_length(gcm_cipher)); g_assert(exchange_key->size == (guint)EVP_CIPHER_key_length(gcm_cipher));
/* create zero IV */ /* create zero IV */
iv = buffer_alloc((guint)EVP_CIPHER_iv_length(gcm_cipher)); iv = pv_buffer_alloc((guint)EVP_CIPHER_iv_length(gcm_cipher));
parms.iv_or_tweak = iv; parms.iv_or_tweak = iv;
parms.key = exchange_key; parms.key = exchange_key;
parms.cipher = gcm_cipher; parms.cipher = gcm_cipher;
@@ -406,10 +587,14 @@ PvImage *pv_img_new(PvArgs *args, const gchar *stage3a_path, GError **err)
if (args->no_verify) if (args->no_verify)
g_warning(_("host-key document verification is disabled. Your workload is not secured.")); g_warning(_("host-key document verification is disabled. Your workload is not secured."));
if (args->root_ca_path)
g_warning(_("A different root CA than the default DigiCert root CA is selected. Ensure that this root CA is trusted."));
ret->comps = pv_img_comps_new(EVP_sha512(), EVP_sha512(), EVP_sha512(), err); ret->comps = pv_img_comps_new(EVP_sha512(), EVP_sha512(), EVP_sha512(), err);
if (!ret->comps) if (!ret->comps)
return NULL; return NULL;
ret->pcf = PV_PCF_PCKMO_AES | PV_PCF_PCKMO_DEA_TDEA | PV_PCF_PCKM_ECC;
ret->cust_comm_cipher = EVP_aes_256_gcm(); ret->cust_comm_cipher = EVP_aes_256_gcm();
ret->gcm_cipher = EVP_aes_256_gcm(); ret->gcm_cipher = EVP_aes_256_gcm();
ret->initial_psw.addr = DEFAULT_INITIAL_PSW_ADDR; ret->initial_psw.addr = DEFAULT_INITIAL_PSW_ADDR;
@@ -423,7 +608,7 @@ PvImage *pv_img_new(PvArgs *args, const gchar *stage3a_path, GError **err)
return NULL; return NULL;
/* set the control flags: PCF and SCF */ /* set the control flags: PCF and SCF */
if (pv_img_set_control_flags(ret, args->pcf, args->scf, err) < 0) if (pv_img_set_control_flags(ret, args->pcf, args->scf, args->allow_pckmo, err) < 0)
return NULL; return NULL;
/* read in the keys */ /* read in the keys */
@@ -458,13 +643,13 @@ void pv_img_free(PvImage *img)
g_slist_free_full(img->key_slots, (GDestroyNotify)pv_hdr_key_slot_free); g_slist_free_full(img->key_slots, (GDestroyNotify)pv_hdr_key_slot_free);
g_slist_free_full(img->host_pub_keys, (GDestroyNotify)EVP_PKEY_free); g_slist_free_full(img->host_pub_keys, (GDestroyNotify)EVP_PKEY_free);
EVP_PKEY_free(img->cust_pub_priv_key); EVP_PKEY_free(img->cust_pub_priv_key);
buffer_clear(&img->stage3a); pv_buffer_clear(&img->stage3a);
pv_img_comps_free(img->comps); pv_img_comps_free(img->comps);
g_free(img->tmp_dir); g_free(img->tmp_dir);
buffer_free(img->xts_key); pv_buffer_free(img->xts_key);
buffer_free(img->cust_root_key); pv_buffer_free(img->cust_root_key);
buffer_free(img->gcm_iv); pv_buffer_free(img->gcm_iv);
buffer_free(img->cust_comm_key); pv_buffer_free(img->cust_comm_key);
g_free(img); g_free(img);
} }
@@ -505,13 +690,13 @@ gint pv_img_add_component(PvImage *img, const PvArg *arg, GError **err)
return 0; return 0;
} }
gint pv_img_calc_pld_ald_tld_nep(const PvImage *img, Buffer **pld, Buffer **ald, gint pv_img_calc_pld_ald_tld_nep(const PvImage *img, PvBuffer **pld, PvBuffer **ald,
Buffer **tld, uint64_t *nep, GError **err) PvBuffer **tld, uint64_t *nep, GError **err)
{ {
return pv_img_comps_finalize(img->comps, pld, ald, tld, nep, err); return pv_img_comps_finalize(img->comps, pld, ald, tld, nep, err);
} }
static gint pv_img_build_stage3b(PvImage *img, Buffer *stage3b, GError **err) static gint pv_img_build_stage3b(PvImage *img, PvBuffer *stage3b, GError **err)
{ {
g_autofree struct stage3b_args *args = NULL; g_autofree struct stage3b_args *args = NULL;
@@ -529,7 +714,7 @@ static gint pv_img_build_stage3b(PvImage *img, Buffer *stage3b, GError **err)
gint pv_img_add_stage3b_comp(PvImage *img, const gchar *path, GError **err) gint pv_img_add_stage3b_comp(PvImage *img, const gchar *path, GError **err)
{ {
g_autoptr(PvComponent) comp = NULL; g_autoptr(PvComponent) comp = NULL;
g_autoptr(Buffer) stage3b = NULL; g_autoptr(PvBuffer) stage3b = NULL;
stage3b = stage3b_getblob(path, err); stage3b = stage3b_getblob(path, err);
if (!stage3b) if (!stage3b)
@@ -646,7 +831,7 @@ static gint get_stage3a_data_size(const PvImage *img, gsize *data_size,
gint pv_img_load_and_set_stage3a(PvImage *img, const gchar *path, GError **err) gint pv_img_load_and_set_stage3a(PvImage *img, const gchar *path, GError **err)
{ {
g_autoptr(Buffer) stage3a = NULL; g_autoptr(PvBuffer) stage3a = NULL;
gsize bin_size, data_size = 0; gsize bin_size, data_size = 0;
if (get_stage3a_data_size(img, &data_size, err) < 0) if (get_stage3a_data_size(img, &data_size, err) < 0)
@@ -666,8 +851,8 @@ gint pv_img_load_and_set_stage3a(PvImage *img, const gchar *path, GError **err)
} }
/* Creates the PV IPIB and sets the stage3a arguments */ /* Creates the PV IPIB and sets the stage3a arguments */
static gint pv_img_build_stage3a(Buffer *stage3a, gsize stage3a_bin_size, static gint pv_img_build_stage3a(PvBuffer *stage3a, gsize stage3a_bin_size,
GSList *comps, const Buffer *hdr, GError **err) GSList *comps, const PvBuffer *hdr, GError **err)
{ {
g_autofree struct ipl_parameter_block *ipib = NULL; g_autofree struct ipl_parameter_block *ipib = NULL;
@@ -687,9 +872,9 @@ static gint pv_img_build_stage3a(Buffer *stage3a, gsize stage3a_bin_size,
} }
/* Creates the actual PV header (serialized and AES-GCM encrypted) */ /* Creates the actual PV header (serialized and AES-GCM encrypted) */
static Buffer *pv_img_create_pv_hdr(PvImage *img, GError **err) static PvBuffer *pv_img_create_pv_hdr(PvImage *img, GError **err)
{ {
g_autoptr(Buffer) hdr_buf = NULL; g_autoptr(PvBuffer) hdr_buf = NULL;
g_autoptr(PvHdr) hdr = NULL; g_autoptr(PvHdr) hdr = NULL;
hdr = pv_hdr_new(img, err); hdr = pv_hdr_new(img, err);
@@ -708,7 +893,7 @@ static Buffer *pv_img_create_pv_hdr(PvImage *img, GError **err)
*/ */
gint pv_img_finalize(PvImage *pv, const gchar *stage3b_path, GError **err) gint pv_img_finalize(PvImage *pv, const gchar *stage3b_path, GError **err)
{ {
g_autoptr(Buffer) hdr = NULL; g_autoptr(PvBuffer) hdr = NULL;
/* load stage3b template into memory and add it to the list of /* load stage3b template into memory and add it to the list of
* components. This must be done before calling * components. This must be done before calling
+7 -7
View File
@@ -25,7 +25,7 @@
typedef struct { typedef struct {
gchar *tmp_dir; /* directory used for temporary files */ gchar *tmp_dir; /* directory used for temporary files */
Buffer *stage3a; /* stage3a containing IPIB and PV header */ PvBuffer *stage3a; /* stage3a containing IPIB and PV header */
gsize stage3a_bin_size; /* size of stage3a.bin */ gsize stage3a_bin_size; /* size of stage3a.bin */
struct psw_t stage3a_psw; /* (short) PSW that is written to struct psw_t stage3a_psw; /* (short) PSW that is written to
* location 0 of the created image * location 0 of the created image
@@ -35,15 +35,15 @@ typedef struct {
GSList *host_pub_keys; /* public host keys */ GSList *host_pub_keys; /* public host keys */
gint nid; /* Elliptic Curve used for the key derivation */ gint nid; /* Elliptic Curve used for the key derivation */
/* keys and cipher used for the AES-GCM encryption */ /* keys and cipher used for the AES-GCM encryption */
Buffer *cust_root_key; PvBuffer *cust_root_key;
Buffer *gcm_iv; PvBuffer *gcm_iv;
const EVP_CIPHER *gcm_cipher; const EVP_CIPHER *gcm_cipher;
/* Information for the IPIB and PV header */ /* Information for the IPIB and PV header */
uint64_t pcf; uint64_t pcf;
uint64_t scf; uint64_t scf;
Buffer *cust_comm_key; PvBuffer *cust_comm_key;
const EVP_CIPHER *cust_comm_cipher; const EVP_CIPHER *cust_comm_cipher;
Buffer *xts_key; PvBuffer *xts_key;
const EVP_CIPHER *xts_cipher; const EVP_CIPHER *xts_cipher;
GSList *key_slots; GSList *key_slots;
GSList *optional_items; GSList *optional_items;
@@ -54,8 +54,8 @@ PvImage *pv_img_new(PvArgs *args, const gchar *stage3a_path, GError **err);
void pv_img_free(PvImage *img); void pv_img_free(PvImage *img);
gint pv_img_add_component(PvImage *img, const PvArg *arg, GError **err); gint pv_img_add_component(PvImage *img, const PvArg *arg, GError **err);
gint pv_img_finalize(PvImage *img, const gchar *stage3b_path, GError **err); gint pv_img_finalize(PvImage *img, const gchar *stage3b_path, GError **err);
gint pv_img_calc_pld_ald_tld_nep(const PvImage *img, Buffer **pld, Buffer **ald, gint pv_img_calc_pld_ald_tld_nep(const PvImage *img, PvBuffer **pld, PvBuffer **ald,
Buffer **tld, uint64_t *nep, GError **err); PvBuffer **tld, uint64_t *nep, GError **err);
gint pv_img_load_and_set_stage3a(PvImage *img, const gchar *path, GError **err); gint pv_img_load_and_set_stage3a(PvImage *img, const gchar *path, GError **err);
const PvComponent *pv_img_get_stage3b_comp(const PvImage *img, GError **err); const PvComponent *pv_img_get_stage3b_comp(const PvImage *img, GError **err);
gint pv_img_add_stage3b_comp(PvImage *img, const gchar *path, GError **err); gint pv_img_add_stage3b_comp(PvImage *img, const gchar *path, GError **err);
+2 -2
View File
@@ -35,7 +35,7 @@ uint64_t pv_ipib_get_size(uint32_t num_comp)
} }
static gint pv_ipib_init(IplParameterBlock *ipib, GSList *comps, static gint pv_ipib_init(IplParameterBlock *ipib, GSList *comps,
const Buffer *hdr) const PvBuffer *hdr)
{ {
g_assert(sizeof(struct ipl_pl_hdr) <= UINT32_MAX); g_assert(sizeof(struct ipl_pl_hdr) <= UINT32_MAX);
g_assert(sizeof(struct ipl_pb0_pv_comp) <= UINT32_MAX); g_assert(sizeof(struct ipl_pb0_pv_comp) <= UINT32_MAX);
@@ -100,7 +100,7 @@ static gint pv_ipib_init(IplParameterBlock *ipib, GSList *comps,
return 0; return 0;
} }
IplParameterBlock *pv_ipib_new(GSList *comps, const Buffer *hdr, GError **err) IplParameterBlock *pv_ipib_new(GSList *comps, const PvBuffer *hdr, GError **err)
{ {
uint64_t ipib_size = pv_ipib_get_size(g_slist_length(comps)); uint64_t ipib_size = pv_ipib_get_size(g_slist_length(comps));
g_autoptr(IplParameterBlock) ret = NULL; g_autoptr(IplParameterBlock) ret = NULL;
+1 -1
View File
@@ -19,7 +19,7 @@
typedef struct ipl_parameter_block IplParameterBlock; typedef struct ipl_parameter_block IplParameterBlock;
uint64_t pv_ipib_get_size(uint32_t num_comp); uint64_t pv_ipib_get_size(uint32_t num_comp);
IplParameterBlock *pv_ipib_new(GSList *comps, const Buffer *hdr, GError **err); IplParameterBlock *pv_ipib_new(GSList *comps, const PvBuffer *hdr, GError **err);
void pv_ipib_free(IplParameterBlock *ipib); void pv_ipib_free(IplParameterBlock *ipib);
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(IplParameterBlock, pv_ipib_free) WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(IplParameterBlock, pv_ipib_free)
+13 -13
View File
@@ -24,12 +24,12 @@
((struct stage3a_args *)((uint64_t)data_ptr + loader_size - \ ((struct stage3a_args *)((uint64_t)data_ptr + loader_size - \
sizeof(struct stage3a_args))) sizeof(struct stage3a_args)))
static Buffer *loader_getblob(const gchar *filename, gsize *loader_size, static PvBuffer *loader_getblob(const gchar *filename, gsize *loader_size,
gsize args_size, gsize data_size, gsize args_size, gsize data_size,
gboolean data_aligned, GError **err) gboolean data_aligned, GError **err)
{ {
g_autoptr(GMappedFile) mapped_file = NULL; g_autoptr(GMappedFile) mapped_file = NULL;
g_autoptr(Buffer) ret = NULL; g_autoptr(PvBuffer) ret = NULL;
gsize size, tmp_loader_size; gsize size, tmp_loader_size;
gchar *loader_data; gchar *loader_data;
@@ -60,7 +60,7 @@ static Buffer *loader_getblob(const gchar *filename, gsize *loader_size,
size = (data_aligned ? PAGE_ALIGN(tmp_loader_size) : tmp_loader_size) + size = (data_aligned ? PAGE_ALIGN(tmp_loader_size) : tmp_loader_size) +
data_size; data_size;
ret = buffer_alloc(size); ret = pv_buffer_alloc(size);
/* copy the loader "template" */ /* copy the loader "template" */
memcpy(ret->data, loader_data, tmp_loader_size); memcpy(ret->data, loader_data, tmp_loader_size);
@@ -71,8 +71,8 @@ static Buffer *loader_getblob(const gchar *filename, gsize *loader_size,
return g_steal_pointer(&ret); return g_steal_pointer(&ret);
} }
Buffer *stage3a_getblob(const gchar *filename, gsize *loader_size, PvBuffer *stage3a_getblob(const gchar *filename, gsize *loader_size,
gsize data_size, GError **err) gsize data_size, GError **err)
{ {
return loader_getblob(filename, loader_size, return loader_getblob(filename, loader_size,
sizeof(struct stage3a_args), data_size, TRUE, sizeof(struct stage3a_args), data_size, TRUE,
@@ -83,8 +83,8 @@ Buffer *stage3a_getblob(const gchar *filename, gsize *loader_size,
/* Set the right offsets and sizes in the stage3a template + add /* Set the right offsets and sizes in the stage3a template + add
* the IPIB block with the PV header * the IPIB block with the PV header
*/ */
static gint stage3a_set_data(Buffer *loader, gsize loader_size, static gint stage3a_set_data(PvBuffer *loader, gsize loader_size,
const Buffer *hdr, struct ipl_parameter_block *ipib, const PvBuffer *hdr, struct ipl_parameter_block *ipib,
GError **err) GError **err)
{ {
uint32_t ipib_size = GUINT32_FROM_BE(ipib->hdr.len); uint32_t ipib_size = GUINT32_FROM_BE(ipib->hdr.len);
@@ -126,15 +126,15 @@ static gint stage3a_set_data(Buffer *loader, gsize loader_size,
return 0; return 0;
} }
gint build_stage3a(Buffer *loader, gsize loader_size, const Buffer *hdr, gint build_stage3a(PvBuffer *loader, gsize loader_size, const PvBuffer *hdr,
struct ipl_parameter_block *ipib, GError **err) struct ipl_parameter_block *ipib, GError **err)
{ {
return stage3a_set_data(loader, loader_size, hdr, ipib, err); return stage3a_set_data(loader, loader_size, hdr, ipib, err);
} }
Buffer *stage3b_getblob(const gchar *filename, GError **err) PvBuffer *stage3b_getblob(const gchar *filename, GError **err)
{ {
g_autoptr(Buffer) ret = NULL; g_autoptr(PvBuffer) ret = NULL;
gsize rb_size; gsize rb_size;
ret = loader_getblob(filename, &rb_size, sizeof(struct stage3b_args), 0, ret = loader_getblob(filename, &rb_size, sizeof(struct stage3b_args), 0,
@@ -146,7 +146,7 @@ Buffer *stage3b_getblob(const gchar *filename, GError **err)
return g_steal_pointer(&ret); return g_steal_pointer(&ret);
} }
void build_stage3b(Buffer *stage3b, const struct stage3b_args *args) void build_stage3b(PvBuffer *stage3b, const struct stage3b_args *args)
{ {
g_assert(stage3b->size > sizeof(*args)); g_assert(stage3b->size > sizeof(*args));
+5 -5
View File
@@ -19,12 +19,12 @@
#include "boot/stage3b.h" #include "boot/stage3b.h"
#include "utils/buffer.h" #include "utils/buffer.h"
Buffer *stage3a_getblob(const gchar *filename, gsize *loader_size, PvBuffer *stage3a_getblob(const gchar *filename, gsize *loader_size,
gsize data_size, GError **err); gsize data_size, GError **err);
gint build_stage3a(Buffer *dc, gsize dc_size, const Buffer *hdr, gint build_stage3a(PvBuffer *dc, gsize dc_size, const PvBuffer *hdr,
struct ipl_parameter_block *ipib, GError **err); struct ipl_parameter_block *ipib, GError **err);
Buffer *stage3b_getblob(const gchar *filename, GError **err); PvBuffer *stage3b_getblob(const gchar *filename, GError **err);
void build_stage3b(Buffer *stage3b, const struct stage3b_args *args); void build_stage3b(PvBuffer *stage3b, const struct stage3b_args *args);
void memblob_init(struct memblob *arg, uint64_t src, uint64_t size); void memblob_init(struct memblob *arg, uint64_t src, uint64_t size);
#endif #endif
+9 -9
View File
@@ -17,18 +17,18 @@
#include "common.h" #include "common.h"
#include "file_utils.h" #include "file_utils.h"
Buffer *buffer_alloc(gsize size) PvBuffer *pv_buffer_alloc(gsize size)
{ {
Buffer *ret = g_new0(Buffer, 1); PvBuffer *ret = g_new0(PvBuffer, 1);
ret->data = g_malloc0(size); ret->data = g_malloc0(size);
ret->size = size; ret->size = size;
return ret; return ret;
} }
Buffer *buffer_dup(const Buffer *buf, gboolean page_aligned) PvBuffer *pv_buffer_dup(const PvBuffer *buf, gboolean page_aligned)
{ {
Buffer *ret; PvBuffer *ret;
gsize size; gsize size;
if (!buf) if (!buf)
@@ -38,19 +38,19 @@ Buffer *buffer_dup(const Buffer *buf, gboolean page_aligned)
if (page_aligned) if (page_aligned)
size = PAGE_ALIGN(size); size = PAGE_ALIGN(size);
ret = buffer_alloc(size); ret = pv_buffer_alloc(size);
/* content will be 0-right-padded */ /* content will be 0-right-padded */
memcpy(ret->data, buf->data, buf->size); memcpy(ret->data, buf->data, buf->size);
return ret; return ret;
} }
gint buffer_write(const Buffer *buf, FILE *file, GError **err) gint pv_buffer_write(const PvBuffer *buf, FILE *file, GError **err)
{ {
return file_write(file, buf->data, buf->size, 1, NULL, err); return file_write(file, buf->data, buf->size, 1, NULL, err);
} }
void buffer_free(Buffer *buf) void pv_buffer_free(PvBuffer *buf)
{ {
if (!buf) if (!buf)
return; return;
@@ -59,11 +59,11 @@ void buffer_free(Buffer *buf)
g_free(buf); g_free(buf);
} }
void buffer_clear(Buffer **buf) void pv_buffer_clear(PvBuffer **buf)
{ {
if (!buf || !*buf) if (!buf || !*buf)
return; return;
buffer_free(*buf); pv_buffer_free(*buf);
*buf = NULL; *buf = NULL;
} }
+8 -8
View File
@@ -15,17 +15,17 @@
#include "common.h" #include "common.h"
typedef struct Buffer { typedef struct PvBuffer {
void *data; void *data;
gsize size; /* in bytes */ gsize size; /* in bytes */
} Buffer; } PvBuffer;
Buffer *buffer_alloc(gsize size); PvBuffer *pv_buffer_alloc(gsize size);
void buffer_free(Buffer *buf); void pv_buffer_free(PvBuffer *buf);
void buffer_clear(Buffer **buf); void pv_buffer_clear(PvBuffer **buf);
gint buffer_write(const Buffer *buf, FILE *file, GError **err); gint pv_buffer_write(const PvBuffer *buf, FILE *file, GError **err);
Buffer *buffer_dup(const Buffer *buf, gboolean page_aligned); PvBuffer *pv_buffer_dup(const PvBuffer *buf, gboolean page_aligned);
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(Buffer, buffer_free) WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(PvBuffer, pv_buffer_free)
#endif #endif
File diff suppressed because it is too large Load Diff
+87 -16
View File
@@ -11,14 +11,18 @@
#define PV_UTILS_CRYPTO_H #define PV_UTILS_CRYPTO_H
#include <glib.h> #include <glib.h>
#include <openssl/asn1.h>
#include <openssl/bio.h> #include <openssl/bio.h>
#include <openssl/bn.h> #include <openssl/bn.h>
#include <openssl/ec.h> #include <openssl/ec.h>
#include <openssl/ecdh.h> #include <openssl/ecdh.h>
#include <openssl/evp.h> #include <openssl/evp.h>
#include <openssl/ossl_typ.h>
#include <openssl/rand.h> #include <openssl/rand.h>
#include <openssl/safestack.h>
#include <openssl/sha.h> #include <openssl/sha.h>
#include <openssl/x509.h> #include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <stdint.h> #include <stdint.h>
#include "common.h" #include "common.h"
@@ -33,6 +37,9 @@
#define AES_256_XTS_TWEAK_SIZE 16 #define AES_256_XTS_TWEAK_SIZE 16
#define AES_256_XTS_KEY_SIZE 64 #define AES_256_XTS_KEY_SIZE 64
#define CRL_DOWNLOAD_TIMEOUT_MS 3000
#define CRL_DOWNLOAD_MAX_SIZE (1024 * 1024) /* in bytes */
enum PvCryptoMode { enum PvCryptoMode {
PV_ENCRYPT, PV_ENCRYPT,
PV_DECRYPT, PV_DECRYPT,
@@ -40,7 +47,34 @@ enum PvCryptoMode {
typedef GSList HostKeyList; typedef GSList HostKeyList;
/* play nice with g_autoptr */
typedef STACK_OF(DIST_POINT) STACK_OF_DIST_POINT;
typedef STACK_OF(X509) STACK_OF_X509;
typedef STACK_OF(X509_CRL) STACK_OF_X509_CRL;
void STACK_OF_DIST_POINT_free(STACK_OF_DIST_POINT *stack);
void STACK_OF_X509_free(STACK_OF_X509 *stack);
void STACK_OF_X509_CRL_free(STACK_OF_X509_CRL *stack);
typedef struct {
X509 *cert;
const gchar *path;
} x509_with_path;
x509_with_path *x509_with_path_new(X509 *cert, const gchar *path);
void x509_with_path_free(x509_with_path *cert);
typedef struct {
X509 *cert;
STACK_OF_X509_CRL *crls;
} x509_pair;
x509_pair *x509_pair_new(X509 **cert, STACK_OF_X509_CRL **crls);
void x509_pair_free(x509_pair *pair);
/* Register auto cleanup functions */ /* Register auto cleanup functions */
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(ASN1_INTEGER, ASN1_INTEGER_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(ASN1_OCTET_STRING, ASN1_OCTET_STRING_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BIGNUM, BN_free) WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BIGNUM, BN_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BIO, BIO_free_all) WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BIO, BIO_free_all)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BN_CTX, BN_CTX_free) WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BN_CTX, BN_CTX_free)
@@ -51,10 +85,18 @@ WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_CIPHER_CTX, EVP_CIPHER_CTX_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_MD_CTX, EVP_MD_CTX_free) WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_MD_CTX, EVP_MD_CTX_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_PKEY, EVP_PKEY_free) WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_PKEY, EVP_PKEY_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_PKEY_CTX, EVP_PKEY_CTX_free) WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_PKEY_CTX, EVP_PKEY_CTX_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(STACK_OF_DIST_POINT, STACK_OF_DIST_POINT_free);
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(STACK_OF_X509, STACK_OF_X509_free);
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(STACK_OF_X509_CRL, STACK_OF_X509_CRL_free);
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509, X509_free) WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509, X509_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_CRL, X509_CRL_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_LOOKUP, X509_LOOKUP_free) WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_LOOKUP, X509_LOOKUP_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_NAME, X509_NAME_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(x509_pair, x509_pair_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_STORE, X509_STORE_free) WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_STORE, X509_STORE_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_STORE_CTX, X509_STORE_CTX_free) WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_STORE_CTX, X509_STORE_CTX_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_VERIFY_PARAM, X509_VERIFY_PARAM_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(x509_with_path, x509_with_path_free)
union cmp_index { union cmp_index {
struct { struct {
@@ -75,30 +117,59 @@ union tweak {
struct cipher_parms { struct cipher_parms {
const EVP_CIPHER *cipher; const EVP_CIPHER *cipher;
const Buffer *key; const PvBuffer *key;
const Buffer *iv_or_tweak; const PvBuffer *iv_or_tweak;
}; };
EVP_PKEY *read_ec_pubkey_cert(X509_STORE *store, gint nid, const gchar *path, int check_crl_valid_for_cert(X509_CRL *crl, X509 *cert,
GError **err); gint verify_flags, GError **err);
Buffer *compute_exchange_key(EVP_PKEY *cust, EVP_PKEY *host, GError **err); void pv_crypto_init(void);
Buffer *generate_aes_key(guint size, GError **err); void pv_crypto_cleanup(void);
Buffer *generate_aes_iv(guint size, GError **err); const ASN1_OCTET_STRING *get_digicert_assured_id_root_ca_skid(void);
gint verify_host_key(X509 *host_key, GSList *issuer_pairs,
gint verify_flags, int level, GError **err);
X509 *load_cert_from_file(const char *path, GError **err);
X509_CRL *load_crl_from_file(const gchar *path, GError **err);
GSList *load_certificates(const gchar *const *cert_paths, GError **err);
STACK_OF_X509 *get_x509_stack(const GSList *x509_with_path_list);
X509_STORE *store_setup(const gchar *root_ca_path,
const gchar * const *crl_paths,
GError **err);
int store_set_verify_param(X509_STORE *store, GError **err);
X509_CRL *load_crl_by_cert(X509 *cert, GError **err);
STACK_OF_X509_CRL *try_load_crls_by_certs(GSList *certs_with_path);
gint check_chain_parameters(const STACK_OF_X509 *chain,
const ASN1_OCTET_STRING *skid, GError **err);
X509_NAME *c2b_name(const X509_NAME *name);
STACK_OF_X509 *delete_ibm_signing_certs(STACK_OF_X509 *certs);
STACK_OF_X509_CRL *store_ctx_find_valid_crls(X509_STORE_CTX *ctx, X509 *cert,
GError **err);
X509_STORE_CTX *create_store_ctx(X509_STORE *trusted, STACK_OF_X509 *chain,
GError **err);
gint verify_cert(X509 *cert, X509_STORE_CTX *ctx, GError **err);
X509_CRL *get_first_valid_crl(X509_STORE_CTX *ctx, X509 *cert, GError **err);
void store_setup_crl_download(X509_STORE *st);
EVP_PKEY *read_ec_pubkey_cert(X509 *cert, gint nid, GError **err);
PvBuffer *compute_exchange_key(EVP_PKEY *cust, EVP_PKEY *host, GError **err);
PvBuffer *generate_aes_key(guint size, GError **err);
PvBuffer *generate_aes_iv(guint size, GError **err);
EVP_PKEY *generate_ec_key(gint nid, GError **err); EVP_PKEY *generate_ec_key(gint nid, GError **err);
gint generate_tweak(union tweak *tweak, uint16_t i, GError **err); gint generate_tweak(union tweak *tweak, uint16_t i, GError **err);
union ecdh_pub_key *evp_pkey_to_ecdh_pub_key(EVP_PKEY *key, GError **err); union ecdh_pub_key *evp_pkey_to_ecdh_pub_key(EVP_PKEY *key, GError **err);
EVP_MD_CTX *digest_ctx_new(const EVP_MD *md, GError **err); EVP_MD_CTX *digest_ctx_new(const EVP_MD *md, GError **err);
Buffer *digest_ctx_finalize(EVP_MD_CTX *ctx, GError **err); PvBuffer *digest_ctx_finalize(EVP_MD_CTX *ctx, GError **err);
Buffer *sha256_buffer(const Buffer *buf, GError **err); PvBuffer *sha256_buffer(const PvBuffer *buf, GError **err);
int64_t gcm_encrypt(const Buffer *in, const Buffer *aad, int64_t gcm_encrypt(const PvBuffer *in, const PvBuffer *aad,
const struct cipher_parms *parms, Buffer *out, const struct cipher_parms *parms, PvBuffer *out,
Buffer *tag, GError **err); PvBuffer *tag, GError **err);
gint encrypt_file(const struct cipher_parms *parms, const gchar *in_path, gint encrypt_file(const struct cipher_parms *parms, const gchar *in_path,
const gchar *path_out, gsize *in_size, gsize *out_size, const gchar *path_out, gsize *in_size, gsize *out_size,
GError **err); GError **err);
Buffer *encrypt_buf(const struct cipher_parms *parms, const Buffer *in, PvBuffer *encrypt_buf(const struct cipher_parms *parms, const PvBuffer *in,
GError **err); GError **err);
G_GNUC_UNUSED Buffer *decrypt_buf(const struct cipher_parms *parms, G_GNUC_UNUSED PvBuffer *decrypt_buf(const struct cipher_parms *parms,
const Buffer *in, GError **err); const PvBuffer *in, GError **err);
#endif #endif
+121
View File
@@ -0,0 +1,121 @@
/*
* Libcurl utils
*
* 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 <stdio.h>
#include <glib.h>
#include <glib/gtypes.h>
#include <curl/curl.h>
#include "lib/zt_common.h"
#include "pv/pv_error.h"
#include "curl.h"
struct UserData {
GByteArray *buffer;
guint max_size;
};
static size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
{
g_assert(userdata);
struct UserData *data = (struct UserData *)userdata;
GByteArray *buffer = data->buffer;
guint64 actual_size;
size_t err;
g_assert(buffer);
if (!g_uint64_checked_mul(&actual_size, size, nmemb))
g_abort();
/* Signal an error condition by returning a amount that differs
* from the amount passed to the callback. This results in a
* CURLE_WRITE_ERROR.
*/
err = actual_size + 1;
if (actual_size > G_MAXUINT)
return err;
data->buffer = g_byte_array_append(buffer, (guchar *)ptr, (guint)actual_size);
if (data->buffer->len > data->max_size)
return err;
return actual_size;
}
gint curl_init(void)
{
if (curl_global_init(CURL_GLOBAL_ALL) != 0)
return -1;
return 0;
}
void curl_cleanup(void)
{
curl_global_cleanup();
}
GByteArray *curl_download(const gchar *url, long timeout_ms, guint max_size,
GError **err)
{
g_autoptr(GByteArray) ret = NULL;
g_autoptr(CURL) handle = NULL;
g_autofree gchar *agent = NULL;
struct UserData userdata;
CURLcode rc;
/* set up curl session */
handle = curl_easy_init();
if (!handle)
g_abort();
/* follow redirection */
rc = curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1l);
if (rc != CURLE_OK)
goto curl_err;
rc = curl_easy_setopt(handle, CURLOPT_TIMEOUT_MS, timeout_ms);
if (rc != CURLE_OK)
goto curl_err;
rc = curl_easy_setopt(handle, CURLOPT_NOSIGNAL, 1l);
if (rc != CURLE_OK)
goto curl_err;
agent = g_strdup_printf("%s/%s", tool_name, RELEASE_STRING);
rc = curl_easy_setopt(handle, CURLOPT_USERAGENT, agent);
if (rc != CURLE_OK)
goto curl_err;
rc = curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_callback);
if (rc != CURLE_OK)
goto curl_err;
ret = g_byte_array_new();
userdata.buffer = ret;
userdata.max_size = max_size;
rc = curl_easy_setopt(handle, CURLOPT_WRITEDATA, (void *)&userdata);
if (rc != CURLE_OK)
goto curl_err;
rc = curl_easy_setopt(handle, CURLOPT_URL, url);
if (rc != CURLE_OK)
goto curl_err;
rc = curl_easy_perform(handle);
if (rc != CURLE_OK) {
g_set_error(err, PV_ERROR, PV_ERROR_DOWNLOAD_FAILED,
_("download failed: %s"), curl_easy_strerror(rc));
return NULL;
}
return g_steal_pointer(&ret);
curl_err:
g_set_error(err, PV_ERROR,
PV_ERROR_CURL_INIT_FAILED,
_("cURL initialization failed: %s"),
curl_easy_strerror(rc));
return NULL;
}
+25
View File
@@ -0,0 +1,25 @@
/*
* Libcurl utils
*
* 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 PV_UTILS_LIBCURL_H
#define PV_UTILS_LIBCURL_H
#include <glib.h>
#include <curl/curl.h>
#include "common.h"
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(CURL, curl_easy_cleanup)
GByteArray *curl_download(const gchar *url, long timeout_ms, guint max_size,
GError **err);
gint curl_init(void);
void curl_cleanup(void);
#endif /* PV_UTILS_LIBCURL_H */
+2 -2
View File
@@ -171,13 +171,13 @@ err:
return ret; return ret;
} }
gint seek_and_write_buffer(FILE *o, const Buffer *buf, uint64_t offset, gint seek_and_write_buffer(FILE *o, const PvBuffer *buf, uint64_t offset,
GError **err) GError **err)
{ {
if (file_seek(o, offset, err) < 0) if (file_seek(o, offset, err) < 0)
return -1; return -1;
if (buffer_write(buf, o, err) < 0) if (pv_buffer_write(buf, o, err) < 0)
return -1; return -1;
return 0; return 0;
+1 -1
View File
@@ -26,7 +26,7 @@ gint file_write(FILE *out, const void *ptr, gsize size, gsize count,
gsize *count_written, GError **err); gsize *count_written, GError **err);
gint pad_file_right(const gchar *path_out, const gchar *path_in, gint pad_file_right(const gchar *path_out, const gchar *path_in,
gsize *size_out, guint padding, GError **err); gsize *size_out, guint padding, GError **err);
gint seek_and_write_buffer(FILE *out, const Buffer *buf, uint64_t offset, gint seek_and_write_buffer(FILE *out, const PvBuffer *buf, uint64_t offset,
GError **err); GError **err);
gint seek_and_write_file(FILE *o, const CompFile *ifile, uint64_t offset, gint seek_and_write_file(FILE *o, const CompFile *ifile, uint64_t offset,
GError **err); GError **err);
+33
View File
@@ -0,0 +1,33 @@
/*
* OpenSSL compatibility utils
*
* Copyright IBM Corp. 2021
*
* 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 PV_UTILS_OPENSSL_COMPAT_H
#define PV_UTILS_OPENSSL_COMPAT_H
#include <openssl/opensslv.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
#if OPENSSL_VERSION_NUMBER < 0x30000000L
#define Pv_X509_STORE_CTX_get_current_cert(ctx) \
X509_STORE_CTX_get_current_cert((X509_STORE_CTX *)(ctx))
#define Pv_X509_STORE_CTX_get1_crls(ctx, nm) \
X509_STORE_CTX_get1_crls((X509_STORE_CTX *)(ctx), (X509_NAME *)(nm))
#define Pv_X509_STORE_set_lookup_crls(st, cb) \
X509_STORE_set_lookup_crls(st, (X509_STORE_CTX_lookup_crls_fn)(cb))
#else
#define Pv_X509_STORE_CTX_get_current_cert(ctx) \
X509_STORE_CTX_get_current_cert(ctx)
#define Pv_X509_STORE_CTX_get1_crls(ctx, nm) \
X509_STORE_CTX_get1_crls(ctx, nm)
#define Pv_X509_STORE_set_lookup_crls(st, cb) \
X509_STORE_set_lookup_crls(st, cb)
#endif
#endif
+86
View File
@@ -0,0 +1,86 @@
#
# Copyright IBM Corp. 2021
#
# 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 ../common.mak
ALL_CPPFLAGS += -D_FILE_OFFSET_BITS=64
ifeq (${HAVE_FUSE},0)
all:
$(SKIP) HAVE_FUSE=0
install:
$(SKIP) HAVE_FUSE=0
else # HAVE_FUSE
#
# FUSE
#
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)
else
FUSE_CFLAGS = -I/usr/include/fuse
FUSE_LDLIBS = -lfuse
endif
#
# systemd
#
ifneq (${HAVE_SYSTEMD},0)
ifeq ($(call check_header_prereq,"systemd/sd-daemon.h"),yes)
ifneq ($(shell sh -c 'command -v pkg-config'),)
SYSTEMD_CFLAGS = $(shell pkg-config --silence-errors --cflags libsystemd)
SYSTEMD_LDLIBS = $(shell pkg-config --silence-errors --libs libsystemd)
else
SYSTEMD_CFLAGS =
SYSTEMD_LDLIBS = -lsystemd
endif
ALL_CPPFLAGS += -DHAVE_SYSTEMD
else
$(warning "systemd support disabled")
endif
endif
ALL_CFLAGS += $(FUSE_CFLAGS) $(SYSTEMD_CFLAGS)
LDLIBS += $(FUSE_LDLIBS) $(SYSTEMD_LDLIBS) -lpthread
sources := $(wildcard *.c)
objects := $(patsubst %.c,%.o,$(sources))
libs = $(rootdir)/libutil/libutil.a
all: hsavmcore
hsavmcore: $(objects) $(libs)
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
overlay.o: check-dep-fuse overlay.c overlay.h
check-dep-fuse:
$(call check_dep, \
"hsavmcore", \
"fuse.h", \
"fuse-devel or libfuse-dev", \
"HAVE_FUSE=0")
install: all
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 hsavmcore \
$(DESTDIR)$(USRSBINDIR)
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 man/hsavmcore.8 \
$(DESTDIR)$(MANDIR)/man8
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 man/hsavmcore.conf.5 \
$(DESTDIR)$(MANDIR)/man5
endif # HAVE_FUSE
clean:
rm -f hsavmcore $(objects)
.PHONY: all install clean
+219
View File
@@ -0,0 +1,219 @@
/*
* Copyright IBM Corp. 2021
*
* 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 <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lib/zt_common.h"
#include "lib/util_opt.h"
#include "lib/util_prg.h"
#include "lib/util_log.h"
#include "cmdline_options.h"
static const struct util_prg prg = {
.desc = "hsavmcore is designed to make the dump process with kdump more "
"efficient. The HSA memory contains a part of the production "
"kernel's memory. Use hsavmcore to cache this information and "
"release HSA memory early in the process.",
.copyright_vec = {
{
.owner = "IBM Corp.",
.pub_first = 2021,
.pub_last = 2021,
},
UTIL_PRG_COPYRIGHT_END
}
};
static struct util_opt opt_vec[] = {
UTIL_OPT_SECTION("CONFIGURATION"),
{
.option = { "config", required_argument, NULL, 'c' },
.argument = "CONFIGFILE",
.desc = "Path to the configuration file.\n"
"Default: no configuration file is used",
},
{
.option = { "vmcore", required_argument, NULL, 'C' },
.argument = "VMCOREFILE",
.desc = "Path to the vmcore file.\n"
"Default: " PROC_VMCORE,
},
{
.option = { "hsa", required_argument, NULL, 'H' },
.argument = "ZCOREHSAFILE",
.desc = "Path to the zcore HSA file.\n"
"Default: " ZCORE_HSA,
},
{
.option = { "workdir", required_argument, NULL, 'W' },
.argument = "WORKDIR",
.desc = "Path to the work directory where temporary files can be "
"stored.\nDefault: " WORKDIR,
},
{
.option = { "bmvmcore", required_argument, NULL, 'B' },
.argument = "VMCOREFILE",
.desc = "Path to the target of the bind mount for the vmcore "
"replacement.\nDefault: " PROC_VMCORE,
},
{
.option = { "swap", required_argument, NULL, 'S' },
.argument = "PATH",
.desc = "Path to a swap device or file. The specified swap "
"device or file must exist and have the proper swap "
"format.\nDefault: no swap device or file is activated",
},
{
.option = { "hsasize", required_argument, NULL, 'T' },
.argument = "HSASIZE",
.desc = "HSA size in bytes.\n"
"Default: -1 (read from the zcore HSA file)",
},
{
.option = { "dbgfsmnt", no_argument, NULL, 'D' },
.desc = "Mount the debug file system.\n"
"Default: the debug file system is not mounted",
},
{
.option = { "hsamem", no_argument, NULL, 'F' },
.desc = "Cache the HSA memory in regular memory.\n"
"Default: the HSA memory is cached as a file within "
"WORKDIR",
},
{
.option = { "norelhsa", no_argument, NULL, 'R' },
.desc = "Do NOT release the HSA memory after caching.\n"
"Default: the HSA memory is released",
},
{
.option = { "nobindmnt", no_argument, NULL, 'N' },
.desc = "Do NOT replace the system's vmcore.\n"
"Default: the system's vmcore is replaced",
},
UTIL_OPT_SECTION("LOGGING"),
{
.option = { "verbose", no_argument, NULL, 'V' },
.desc = "Print verbose messages to stdout. Repeat this option "
"for increased verbosity from just error messages to "
"also include warning, information, debug, and trace "
"messages. This option is intended for debugging",
},
{
.option = { "fusedbg", no_argument, NULL, 'G' },
.desc = "Enable FUSE debugging.\n"
"Default: FUSE debugging is disabled",
},
UTIL_OPT_SECTION("GENERAL OPTIONS"),
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
void parse_cmdline_options(int argc, char *argv[], struct config *config)
{
int opt, ret;
util_prg_init(&prg);
util_opt_init(opt_vec, NULL);
/* Parse given command-line config */
while (1) {
opt = util_opt_getopt_long(argc, argv);
if (opt == -1)
break;
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 'V':
config->verbose++;
util_log_set_level(config->verbose);
break;
case 'c':
ret = update_config_from_file(optarg, config);
if (ret < 0)
exit(EXIT_FAILURE);
util_log_set_level(config->verbose);
break;
case 'C':
strncpy(config->vmcore_path, optarg,
sizeof(config->vmcore_path) - 1);
/* Ensure null termination */
config->vmcore_path[sizeof(config->vmcore_path) - 1] =
'\0';
break;
case 'H':
strncpy(config->zcore_hsa_path, optarg,
sizeof(config->zcore_hsa_path) - 1);
/* Ensure null termination */
config->zcore_hsa_path[sizeof(config->zcore_hsa_path) -
1] = '\0';
break;
case 'W':
strncpy(config->workdir_path, optarg,
sizeof(config->workdir_path) - 1);
/* Ensure null termination */
config->workdir_path[sizeof(config->workdir_path) - 1] =
'\0';
break;
case 'B':
strncpy(config->bind_mount_vmcore_path, optarg,
sizeof(config->bind_mount_vmcore_path) - 1);
/* Ensure null termination */
config->bind_mount_vmcore_path
[sizeof(config->bind_mount_vmcore_path) - 1] =
'\0';
break;
case 'S':
strncpy(config->swap, optarg, sizeof(config->swap) - 1);
/* Ensure null termination */
config->swap[sizeof(config->swap) - 1] = '\0';
break;
case 'T': {
char *endptr;
long hsa_size = strtol(optarg, &endptr, 0);
if (*endptr != '\0' || hsa_size < -1 ||
hsa_size > INT_MAX) {
fprintf(stderr,
"The given HSA size is invalid.\n");
exit(EXIT_FAILURE);
}
config->hsa_size = hsa_size;
break;
}
case 'D':
config->mount_debugfs = true;
break;
case 'F':
config->use_hsa_mem = true;
break;
case 'R':
config->release_hsa = false;
break;
case 'N':
config->bind_mount_vmcore = false;
break;
case 'G':
config->fuse_debug = true;
break;
case '?':
default:
util_opt_print_parse_error(opt, argv);
exit(EXIT_FAILURE);
}
}
}
+19
View File
@@ -0,0 +1,19 @@
/*
* Copyright IBM Corp. 2021
*
* 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 _HSAVMCORE_CMDLINE_OPTIONS_H
#define _HSAVMCORE_CMDLINE_OPTIONS_H
#include "config.h"
/*
* Parses the given command-line options and adjusts the application's
* configuration accordingly.
*/
void parse_cmdline_options(int argc, char *argv[], struct config *config);
#endif
+27
View File
@@ -0,0 +1,27 @@
/*
* Copyright IBM Corp. 2021
*
* 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 _HSAVMCORE_COMMON_H
#define _HSAVMCORE_COMMON_H
#define NAME "hsavmcore"
#define DEBUGFS_MOUNT_POINT "/sys/kernel/debug"
#define ZCORE_HSA DEBUGFS_MOUNT_POINT "/zcore/hsa"
#define VMCORE_FILE "vmcore"
#define PROC_VMCORE "/proc/" VMCORE_FILE
#define WORKDIR "/var/crash"
#define HSA_CACHE_FILE NAME "-hsa-cache.bin"
#define OVERLAY_MOUNT_POINT "/tmp/" NAME "-overlay/"
#endif
+242
View File
@@ -0,0 +1,242 @@
/*
* Copyright IBM Corp. 2021
*
* 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 <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "lib/util_libc.h"
#include "lib/util_log.h"
#include "config.h"
#define CONFIG_LINE_MAX_SIZE 1024
/*
* Supported configuration parameters
*/
#define CONFIG_VERBOSE "verbose"
#define CONFIG_WORKDIR "workdir"
#define CONFIG_HSA_SIZE "hsa_size"
#define CONFIG_MOUNT_DEBUGFS "mount_debugfs"
#define CONFIG_USE_HSA_MEM "use_hsa_mem"
#define CONFIG_RELEASE_HSA "release_hsa"
#define CONFIG_BIND_MOUNT_VMCORE "bind_mount_vmcore"
#define CONFIG_FUSE_DEBUG "fuse_debug"
#define CONFIG_SWAP "swap"
static char *get_value_str(char *line)
{
char *ptr = strchr(line, '=');
if (!ptr)
return NULL;
return util_strstrip(ptr + 1);
}
static int parse_bool(char *line, int linenum, const char *name, bool *value)
{
const char *value_str;
unsigned long value_num;
char *endptr;
value_str = get_value_str(line);
if (!value_str) {
util_log_print(UTIL_LOG_ERROR,
"config line %d: value expected for %s\n",
linenum, name);
return -1;
}
util_log_print(UTIL_LOG_DEBUG, "config parse bool: %s\n", value_str);
value_num = strtoul(value_str, &endptr, 0);
if (*endptr != '\0' || (value_num != 0 && value_num != 1)) {
util_log_print(UTIL_LOG_ERROR,
"config line %d: invalid value for %s\n",
linenum, name);
return -1;
}
*value = value_num;
return 0;
}
static int parse_int(char *line, int linenum, const char *name, int min_value,
int max_value, int *value)
{
const char *value_str;
long value_num;
char *endptr;
value_str = get_value_str(line);
if (!value_str) {
util_log_print(UTIL_LOG_ERROR,
"config line %d: value expected for %s\n",
linenum, name);
return -1;
}
util_log_print(UTIL_LOG_DEBUG, "config parse int: %s\n", value_str);
value_num = strtol(value_str, &endptr, 0);
if (*endptr != '\0' || value_num < min_value || value_num > max_value) {
util_log_print(UTIL_LOG_ERROR,
"config line %d: invalid value for %s\n",
linenum, name);
return -1;
}
*value = value_num;
return 0;
}
static int parse_str(char *line, int linenum, const char *name, int min_size,
int max_size, char *value)
{
const char *value_str;
int size;
value_str = get_value_str(line);
if (!value_str) {
util_log_print(UTIL_LOG_ERROR,
"config line %d: value expected for %s\n",
linenum, name);
return -1;
}
util_log_print(UTIL_LOG_DEBUG, "config parse string: %s\n", value_str);
size = strlen(value_str);
if ((min_size >= 0 && size < min_size) || size > max_size) {
util_log_print(UTIL_LOG_ERROR,
"config line %d: invalid value for %s\n",
linenum, name);
return -1;
}
strncpy(value, value_str, max_size);
/* Ensure null termination */
value[max_size] = '\0';
return 0;
}
static int parse_line(char *line, int linenum, struct config *config)
{
if (strncmp(line, CONFIG_VERBOSE, strlen(CONFIG_VERBOSE)) == 0) {
if (parse_int(line, linenum, CONFIG_VERBOSE, UTIL_LOG_ERROR,
UTIL_LOG_TRACE, &config->verbose))
return -1;
} else if (strncmp(line, CONFIG_WORKDIR, strlen(CONFIG_WORKDIR)) == 0) {
if (parse_str(line, linenum, CONFIG_WORKDIR, 0,
sizeof(config->workdir_path) - 1,
config->workdir_path))
return -1;
} else if (strncmp(line, CONFIG_HSA_SIZE, strlen(CONFIG_HSA_SIZE)) ==
0) {
if (parse_int(line, linenum, CONFIG_HSA_SIZE, -1, INT_MAX,
&config->hsa_size))
return -1;
} else if (strncmp(line, CONFIG_MOUNT_DEBUGFS,
strlen(CONFIG_MOUNT_DEBUGFS)) == 0) {
if (parse_bool(line, linenum, CONFIG_MOUNT_DEBUGFS,
&config->mount_debugfs))
return -1;
} else if (strncmp(line, CONFIG_USE_HSA_MEM,
strlen(CONFIG_USE_HSA_MEM)) == 0) {
if (parse_bool(line, linenum, CONFIG_USE_HSA_MEM,
&config->use_hsa_mem))
return -1;
} else if (strncmp(line, CONFIG_RELEASE_HSA,
strlen(CONFIG_RELEASE_HSA)) == 0) {
if (parse_bool(line, linenum, CONFIG_RELEASE_HSA,
&config->release_hsa))
return -1;
} else if (strncmp(line, CONFIG_BIND_MOUNT_VMCORE,
strlen(CONFIG_BIND_MOUNT_VMCORE)) == 0) {
if (parse_bool(line, linenum, CONFIG_BIND_MOUNT_VMCORE,
&config->bind_mount_vmcore))
return -1;
} else if (strncmp(line, CONFIG_FUSE_DEBUG,
strlen(CONFIG_FUSE_DEBUG)) == 0) {
if (parse_bool(line, linenum, CONFIG_FUSE_DEBUG,
&config->fuse_debug))
return -1;
} else if (strncmp(line, CONFIG_SWAP, strlen(CONFIG_SWAP)) == 0) {
if (parse_str(line, linenum, CONFIG_SWAP, 0,
sizeof(config->swap) - 1, config->swap))
return -1;
} else {
util_log_print(UTIL_LOG_ERROR,
"config line %d: unknown configuration '%s'\n",
linenum, line);
return -1;
}
return 0;
}
void init_config(struct config *config)
{
memset(config, 0, sizeof(struct config));
strncpy(config->vmcore_path, PROC_VMCORE,
sizeof(config->vmcore_path) - 1);
strncpy(config->zcore_hsa_path, ZCORE_HSA,
sizeof(config->zcore_hsa_path) - 1);
strncpy(config->workdir_path, WORKDIR,
sizeof(config->workdir_path) - 1);
strncpy(config->bind_mount_vmcore_path, PROC_VMCORE,
sizeof(config->bind_mount_vmcore_path) - 1);
config->hsa_size = -1;
config->mount_debugfs = false;
config->use_hsa_mem = false;
config->release_hsa = true;
config->bind_mount_vmcore = true;
config->fuse_debug = false;
}
int update_config_from_file(const char *config_path, struct config *config)
{
char line[CONFIG_LINE_MAX_SIZE], *ptr;
int ret = 0, linenum;
FILE *fp;
fp = fopen(config_path, "r");
if (!fp) {
util_log_print(UTIL_LOG_ERROR, "Couldn't open config file %s\n",
config_path);
return -1;
}
/* Read the given configuration file linewise and parse parameters */
linenum = 0;
while (fgets(line, sizeof(line), fp)) {
linenum++;
ptr = util_strstrip(line);
/* Skip empty or comment lines */
if (ptr[0] == '\0' || ptr[0] == '#')
continue;
util_log_print(UTIL_LOG_DEBUG, "config line %d: %s\n", linenum,
ptr);
ret = parse_line(ptr, linenum, config);
if (ret < 0)
break;
}
fclose(fp);
return ret;
}
+59
View File
@@ -0,0 +1,59 @@
/*
* Copyright IBM Corp. 2021
*
* 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 _HSAVMCORE_CONFIG_H
#define _HSAVMCORE_CONFIG_H
#include <limits.h>
#include <stdbool.h>
#include "common.h"
/*
* This represents the application's configuration.
*/
struct config {
/* Log message level */
int verbose;
/* Path to the system's vmcore file */
char vmcore_path[PATH_MAX];
/* Path to the system's zcore hsa file */
char zcore_hsa_path[PATH_MAX];
/*
* Path to a directory where the application could create temporary
* files.
*/
char workdir_path[PATH_MAX];
/* Path to a bind-mount target for vmcore Overlay */
char bind_mount_vmcore_path[PATH_MAX];
/* Path to a swap device/file */
char swap[PATH_MAX];
/* HSA memory size */
int hsa_size;
/* Indicates whether the debugfs shall be mounted */
bool mount_debugfs;
/* Indicates whether the HSA memory file reader shall be used */
bool use_hsa_mem;
/* Indicates whether the HSA memory shall be released after caching */
bool release_hsa;
/* Indicates whether a bind-mount of vmcore Proxy shall be enabled */
bool bind_mount_vmcore;
/* Indicates whether the FUSE debug messages shall be enabled */
bool fuse_debug;
};
/*
* Initializes the application's configuration to its default values.
*/
void init_config(struct config *config);
/*
* Updates the application's configuration from the given configuration file.
*/
int update_config_from_file(const char *config_path, struct config *config);
#endif
+172
View File
@@ -0,0 +1,172 @@
/*
* Copyright IBM Corp. 2021
*
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <elf.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "lib/util_file.h"
#include "lib/util_log.h"
#include "hsa.h"
long get_hsa_size(const char *zcore_hsa_path)
{
long size;
int ret;
util_log_print(UTIL_LOG_DEBUG, "Reading HSA memory size from %s\n",
zcore_hsa_path);
/* Read HSA size */
ret = util_file_read_l(&size, 16, zcore_hsa_path);
if (ret < 0) {
util_log_print(UTIL_LOG_ERROR, "File read failed (%s)\n",
strerror(errno));
return -1;
}
return size;
}
long get_hsa_vmcore_offset(const char *vmcore_path)
{
Elf64_Ehdr elf_hdr;
int fd = -1, n, i;
long offset = -1;
util_log_print(UTIL_LOG_DEBUG,
"Reading HSA memory offset from vmcore %s\n",
vmcore_path);
/* Open vmcore file */
fd = open(vmcore_path, O_RDONLY);
if (fd < 0) {
util_log_print(UTIL_LOG_ERROR, "open syscall failed (%s)\n",
strerror(errno));
goto fail;
}
util_log_print(UTIL_LOG_DEBUG, "Reading vmcore ELF header\n");
/* Read ELF header */
n = read(fd, &elf_hdr, sizeof(Elf64_Ehdr));
if (n < 0) {
util_log_print(UTIL_LOG_ERROR, "read syscall failed (%s)\n",
strerror(errno));
goto fail;
} else if (n != sizeof(Elf64_Ehdr)) {
util_log_print(UTIL_LOG_ERROR,
"read syscall read less data than expected (%s)\n",
strerror(errno));
goto fail;
}
/* Verify ELF header */
if ((memcmp(elf_hdr.e_ident, ELFMAG, SELFMAG) != 0) ||
elf_hdr.e_type != ET_CORE || elf_hdr.e_machine != EM_S390 ||
elf_hdr.e_ident[EI_CLASS] != ELFCLASS64) {
util_log_print(UTIL_LOG_ERROR, "Invalid vmcore ELF header\n");
goto fail;
}
util_log_print(UTIL_LOG_DEBUG,
"Reading vmcore ELF program header(s)\n");
/* Read ELF program header(s) */
n = lseek(fd, elf_hdr.e_phoff, SEEK_SET);
if (n < 0) {
util_log_print(UTIL_LOG_ERROR, "lseek syscall failed (%s)\n",
strerror(errno));
goto fail;
}
/*
* Go through all ELF program headers and find one
* that starts at physical/virtual address 0x0.
*/
for (i = 0; i < elf_hdr.e_phnum; i++) {
Elf64_Phdr elf_phdr;
util_log_print(UTIL_LOG_DEBUG,
"Reading vmcore ELF program header #%d\n", i);
n = read(fd, &elf_phdr, sizeof(Elf64_Phdr));
if (n < 0) {
util_log_print(UTIL_LOG_ERROR,
"read syscall failed (%s)\n",
strerror(errno));
goto fail;
} else if (n != sizeof(Elf64_Phdr)) {
util_log_print(UTIL_LOG_ERROR,
"read syscall read less data than expected (%s)\n",
strerror(errno));
goto fail;
}
util_log_print(UTIL_LOG_DEBUG,
"vmcore ELF program segment #%d: type=%lx vaddr=%lx paddr=%lx offset=%lx\n",
i, elf_phdr.p_type, elf_phdr.p_vaddr,
elf_phdr.p_paddr, elf_phdr.p_offset);
/* HSA memory starts at physical/virtual address 0x0 */
if (elf_phdr.p_type == PT_LOAD && elf_phdr.p_vaddr == 0 &&
elf_phdr.p_paddr == 0) {
offset = elf_phdr.p_offset;
break;
}
}
if (offset < 0) {
util_log_print(UTIL_LOG_ERROR,
"Couldn't find HSA memory offset in vmcore\n");
goto fail;
}
util_log_print(UTIL_LOG_DEBUG, "HSA memory vmcore offset %lx\n",
offset);
close(fd);
return offset;
fail:
if (fd >= 0)
close(fd);
return -1;
}
int release_hsa(const char *zcore_hsa_path)
{
int ret;
util_log_print(UTIL_LOG_INFO, "Release HSA memory via %s\n",
zcore_hsa_path);
/* Release HSA memory */
ret = util_file_write_s("0", zcore_hsa_path);
if (ret < 0) {
util_log_print(UTIL_LOG_ERROR, "File write failed (%s)\n",
strerror(errno));
return -1;
}
/* Verify that HSA memory has been released */
if (get_hsa_size(zcore_hsa_path) > 0) {
util_log_print(UTIL_LOG_ERROR, "HSA memory release failed\n");
return -1;
}
util_log_print(UTIL_LOG_INFO, "HSA memory successfully released\n");
return 0;
}
+75
View File
@@ -0,0 +1,75 @@
/*
* Copyright IBM Corp. 2021
*
* 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 _HSAVMCORE_HSA_H
#define _HSAVMCORE_HSA_H
#include <stddef.h>
/*
* The interface to a HSA memory reader.
* This interface must be implemented by a concrete HSA memory reader.
*/
struct hsa_reader {
/* Total HSA memory size */
long hsa_size;
/* Offset of HSA memory in /proc/vmcore */
long hsa_vmcore_offset;
/* Destroys a concrete HSA memory reader */
void (*destroy)(struct hsa_reader *self);
/* Reads a HSA memory block given by offset and size */
int (*read_at)(struct hsa_reader *self, long offset, void *buf,
int size);
};
static inline long hsa_get_size(struct hsa_reader *self)
{
return self->hsa_size;
}
static inline long hsa_get_vmcore_offset(struct hsa_reader *self)
{
return self->hsa_vmcore_offset;
}
static inline void destroy_hsa_reader(struct hsa_reader *self)
{
self->destroy(self);
}
static inline int read_hsa_at(struct hsa_reader *self, long offset, void *buf,
int size)
{
return self->read_at(self, offset, buf, size);
}
/*
* Reads total HSA memory size from /sys/kernel/debug/zcore/hsa.
*/
long get_hsa_size(const char *zcore_hsa_path);
/*
* Returns the offset of HSA memory in /proc/vmcore.
*/
long get_hsa_vmcore_offset(const char *vmcore_path);
/*
* Releases HSA memory.
*/
int release_hsa(const char *zcore_hsa_path);
/*
* Returns a pointer to the enclosing struct which contains
* the variable pointed to by the given pointer as a member.
*/
#define container_of(ptr, type, member) \
({ \
const typeof(((type *)NULL)->member) *mptr = (ptr); \
(type *)((char *)mptr - offsetof(type, member)); \
})
#endif
+236
View File
@@ -0,0 +1,236 @@
/*
* Copyright IBM Corp. 2021
*
* 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 <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "lib/zt_common.h"
#include "lib/util_log.h"
#include "common.h"
#include "hsa.h"
#include "hsa_file.h"
struct hsa_file_reader {
struct hsa_reader super;
/* Temporary file containing a copy of the HSA memory */
int fd;
};
static void destroy(struct hsa_reader *super)
{
struct hsa_file_reader *self =
container_of(super, struct hsa_file_reader, super);
close(self->fd);
free(self);
}
static int read_at(struct hsa_reader *super, long offset, void *buf, int size)
{
struct hsa_file_reader *self =
container_of(super, struct hsa_file_reader, super);
long n, nread = 0;
util_log_print(UTIL_LOG_DEBUG, "HSA file read: offset=%lx size=%x\n",
offset, size);
/* Validate given offset */
if (offset >= super->hsa_size)
return 0;
/* Validate given size */
size = MIN(super->hsa_size - offset, size);
n = lseek(self->fd, offset, SEEK_SET);
if (n < 0) {
util_log_print(UTIL_LOG_ERROR, "lseek syscall failed (%s)\n",
strerror(errno));
return -1;
}
while (size) {
n = read(self->fd, buf + nread, size);
if (n < 0) {
util_log_print(UTIL_LOG_ERROR,
"read syscall failed (%s)\n",
strerror(errno));
return -1;
} else if (n == 0) {
break;
}
nread += n;
size -= n;
}
return nread;
}
static int copy_hsa_to_file(const char *vmcore_path, const char *workdir_path,
long size, long offset)
{
int fd_in = -1, fd_out = -1;
char cache_file_path[PATH_MAX];
long n;
snprintf(cache_file_path, sizeof(cache_file_path), "%s/%s",
workdir_path, HSA_CACHE_FILE);
util_log_print(UTIL_LOG_DEBUG,
"Copy HSA memory from vmcore %s to cache file %s\n",
vmcore_path, cache_file_path);
/* Open vmcore file */
fd_in = open(vmcore_path, O_RDONLY);
if (fd_in < 0) {
util_log_print(UTIL_LOG_ERROR, "open syscall failed (%s)\n",
strerror(errno));
goto fail;
}
/* Open cache file */
fd_out = open(cache_file_path, O_RDWR | O_CREAT | O_TRUNC, 0644);
if (fd_out < 0) {
util_log_print(UTIL_LOG_ERROR, "open syscall failed (%s)\n",
strerror(errno));
goto fail;
}
/* Unlink cache file to auto-delete it on close */
n = unlink(cache_file_path);
if (n < 0) {
util_log_print(UTIL_LOG_ERROR, "unlink syscall failed (%s)\n",
strerror(errno));
goto fail;
}
/* Copy HSA memory to cache file */
n = lseek(fd_in, offset, SEEK_SET);
if (n < 0) {
util_log_print(UTIL_LOG_ERROR, "lseek syscall failed (%s)\n",
strerror(errno));
goto fail;
}
/* Copy HSA memory chunkwise to the temporary file */
while (size) {
char buf[1024];
long nread, nwrite;
/* Read a chunk from vmcore */
nread = MIN((long)sizeof(buf), size);
n = read(fd_in, buf, nread);
if (n < 0) {
util_log_print(UTIL_LOG_ERROR,
"read syscall failed (%s)\n",
strerror(errno));
goto fail;
} else if (n == 0) {
util_log_print(UTIL_LOG_ERROR,
"read syscall read less data than expected\n");
goto fail;
}
/* Write a chunk to cache file */
nwrite = n;
n = write(fd_out, buf, nwrite);
if (n < 0) {
util_log_print(UTIL_LOG_ERROR,
"write syscall failed (%s)\n",
strerror(errno));
goto fail;
} else if (n != nwrite) {
util_log_print(UTIL_LOG_ERROR,
"write syscall wrote less data than expected\n");
goto fail;
}
size -= n;
}
/* Reset cache file position */
n = lseek(fd_out, 0, SEEK_SET);
if (n < 0) {
util_log_print(UTIL_LOG_ERROR, "lseek syscall failed (%s)\n",
strerror(errno));
goto fail;
}
close(fd_in);
return fd_out;
fail:
if (fd_in >= 0)
close(fd_in);
if (fd_out >= 0)
close(fd_out);
return -1;
}
struct hsa_reader *make_hsa_file_reader(const char *zcore_hsa_path,
const char *vmcore_path,
const char *workdir_path, long hsa_size,
bool release_hsa_flag)
{
struct hsa_file_reader *self;
long hsa_vmcore_offset;
int fd;
/* Calculate HSA size if not given by user */
if (hsa_size < 0) {
hsa_size = get_hsa_size(zcore_hsa_path);
if (hsa_size <= 0)
return NULL;
}
hsa_vmcore_offset = get_hsa_vmcore_offset(vmcore_path);
if (hsa_vmcore_offset < 0)
return NULL;
util_log_print(UTIL_LOG_INFO, "HSA: size=%lx vmcore offset=%lx\n",
hsa_size, hsa_vmcore_offset);
/*
* Store the whole HSA memory from /proc/vmcore to a temporary file
* before releasing HSA.
*/
fd = copy_hsa_to_file(vmcore_path, workdir_path, hsa_size,
hsa_vmcore_offset);
if (fd < 0)
return NULL;
if (release_hsa_flag) {
if (release_hsa(zcore_hsa_path)) {
close(fd);
return NULL;
}
}
self = malloc(sizeof(struct hsa_file_reader));
if (!self) {
util_log_print(UTIL_LOG_ERROR, "malloc failed\n");
close(fd);
return NULL;
}
self->super.hsa_size = hsa_size;
self->super.hsa_vmcore_offset = hsa_vmcore_offset;
self->super.destroy = destroy;
self->super.read_at = read_at;
self->fd = fd;
return &self->super;
}
+27
View File
@@ -0,0 +1,27 @@
/*
* Copyright IBM Corp. 2021
*
* 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 _HSAVMCORE_HSA_FILE_H
#define _HSAVMCORE_HSA_FILE_H
#include <stdbool.h>
#include "hsa.h"
/*
* This concrete HSA memory reader copies the whole HSA memory from /proc/vmcore
* to a temporary file.
* In order for it to work, the system must provide enough file storage.
* The advantage of this reader is that it doesn't require extra memory for
* caching.
*/
struct hsa_reader *make_hsa_file_reader(const char *zcore_hsa_path,
const char *vmcore_path,
const char *workdir_path, long hsa_size,
bool release_hsa_flag);
#endif
+151
View File
@@ -0,0 +1,151 @@
/*
* Copyright IBM Corp. 2021
*
* 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 <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "lib/zt_common.h"
#include "lib/util_log.h"
#include "hsa.h"
#include "hsa_mem.h"
struct hsa_mem_reader {
struct hsa_reader super;
unsigned char cache[];
};
static void destroy(struct hsa_reader *super)
{
struct hsa_mem_reader *self =
container_of(super, struct hsa_mem_reader, super);
free(self);
}
static int read_at(struct hsa_reader *super, long offset, void *buf, int size)
{
struct hsa_mem_reader *self =
container_of(super, struct hsa_mem_reader, super);
util_log_print(UTIL_LOG_DEBUG, "HSA file read: offset=%lx size=%x\n",
offset, size);
/* Validate given offset */
if (offset >= super->hsa_size)
return 0;
/* Validate given size */
size = MIN(super->hsa_size - offset, size);
memcpy(buf, self->cache + offset, size);
return size;
}
static int read_hsa(const char *vmcore_path, long offset, void *buf, int size)
{
long n, nread = 0;
int fd = -1;
util_log_print(UTIL_LOG_DEBUG, "Read HSA memory from vmcore %s\n",
vmcore_path);
/* Open vmcore file */
fd = open(vmcore_path, O_RDONLY);
if (fd < 0) {
util_log_print(UTIL_LOG_ERROR, "open syscall failed (%s)\n",
strerror(errno));
goto fail;
}
n = lseek(fd, offset, SEEK_SET);
if (n < 0) {
util_log_print(UTIL_LOG_ERROR, "lseek syscall failed (%s)\n",
strerror(errno));
goto fail;
}
/* Read HSA memory */
while (size) {
n = read(fd, buf + nread, size);
if (n < 0) {
util_log_print(UTIL_LOG_ERROR,
"read syscall failed (%s)\n",
strerror(errno));
goto fail;
} else if (n == 0) {
util_log_print(UTIL_LOG_ERROR,
"read syscall read less data than expected\n");
goto fail;
}
nread += n;
size -= n;
}
close(fd);
return 0;
fail:
if (fd >= 0)
close(fd);
return -1;
}
struct hsa_reader *make_hsa_mem_reader(const char *zcore_hsa_path,
const char *vmcore_path, long hsa_size,
bool release_hsa_flag)
{
struct hsa_mem_reader *self;
long hsa_vmcore_offset;
/* Calculate HSA size if not given by user */
if (hsa_size < 0) {
hsa_size = get_hsa_size(zcore_hsa_path);
if (hsa_size <= 0)
return NULL;
}
hsa_vmcore_offset = get_hsa_vmcore_offset(vmcore_path);
if (hsa_vmcore_offset < 0)
return NULL;
util_log_print(UTIL_LOG_INFO, "HSA: size=%lx vmcore offset=%lx\n",
hsa_size, hsa_vmcore_offset);
self = malloc(sizeof(struct hsa_mem_reader) + hsa_size);
if (!self) {
util_log_print(UTIL_LOG_ERROR, "malloc failed\n");
return NULL;
}
/* Cache the whole HSA memory from /proc/vmcore before releasing HSA */
if (read_hsa(vmcore_path, hsa_vmcore_offset, self->cache, hsa_size)) {
free(self);
return NULL;
}
if (release_hsa_flag) {
if (release_hsa(zcore_hsa_path)) {
free(self);
return NULL;
}
}
self->super.hsa_size = hsa_size;
self->super.hsa_vmcore_offset = hsa_vmcore_offset;
self->super.destroy = destroy;
self->super.read_at = read_at;
return &self->super;
}
+24
View File
@@ -0,0 +1,24 @@
/*
* Copyright IBM Corp. 2021
*
* 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 _HSAVMCORE_HSA_MEM_H
#define _HSAVMCORE_HSA_MEM_H
#include <stdbool.h>
#include "hsa.h"
/*
* This concrete HSA memory reader reads the whole HSA memory from /proc/vmcore
* and caches it all in an internal memory buffer.
* In order for it to work, the system must provide enough memory or swap space.
*/
struct hsa_reader *make_hsa_mem_reader(const char *zcore_hsa_path,
const char *vmcore_path, long hsa_size,
bool release_hsa_flag);
#endif
+147
View File
@@ -0,0 +1,147 @@
# Setup
## Configure crashkernel
```shell
sudo grubby --args "crashkernel=512M" --update-kernel=ALL
sudo reboot
```
## Production kernel's root file system
- kdump mounts the production kernel's root file system under **/sysroot**.
## Dependencies
```shell
sudo dnf install -y fuse fuse-devel systemd-devel
```
## Build hsavmcore
```shell
make -C s390-tools/hsavmcore
```
## Install hsavmcore
```shell
sudo cp s390-tools/hsavmcore/hsavmcore /usr/sbin/
```
## Create swap file
```shell
sudo dd if=/dev/zero of=/var/crash/swap.img bs=1M count=1024
sudo mkswap /var/crash/swap.img
```
## Install hsavmcore.conf
### Test configuration
- Doesn't require HSA support
#### HSA cache in file
```shell
cat <<EOF | sudo tee /etc/hsavmcore.conf
verbose = 2
workdir = /sysroot/var/crash
use_hsa_mem = 0
mount_debugfs = 1
hsa_size = 0x1ffff000
release_hsa = 0
bind_mount_vmcore = 1
EOF
```
#### HSA cache in memory
```shell
cat <<EOF | sudo tee /etc/hsavmcore.conf
verbose = 2
workdir = /sysroot/var/crash
use_hsa_mem = 1
mount_debugfs = 1
hsa_size = 0x1ffff000
release_hsa = 0
bind_mount_vmcore = 1
swap = /sysroot/var/crash/swap.img
EOF
```
### Production configuration
- Works only on s390x
#### HSA cache in file
```shell
cat <<EOF | sudo tee /etc/hsavmcore.conf
verbose = 2
workdir = /sysroot/var/crash
use_hsa_mem = 0
mount_debugfs = 1
hsa_size = -1
release_hsa = 1
bind_mount_vmcore = 1
EOF
```
#### HSA cache in memory
```shell
cat <<EOF | sudo tee /etc/hsavmcore.conf
verbose = 2
workdir = /sysroot/var/crash
use_hsa_mem = 1
mount_debugfs = 1
hsa_size = -1
release_hsa = 1
bind_mount_vmcore = 1
swap = /sysroot/var/crash/swap.img
EOF
```
## Install new dracut module
```shell
sudo cp -r s390-tools/hsavmcore/initramfs/fedora-rhel/dracut/modules.d/99hsavmcore /lib/dracut/modules.d/
```
## Add the new dracut module as a dependency to the dracut module *kdumpbase*
```shell
sudo sed -e 's#local _dep="base shutdown"#local _dep="base shutdown hsavmcore"#' \
-i /lib/dracut/modules.d/99kdumpbase/module-setup.sh
```
## Rebuild kdump initramfs
```shell
sudo kdumpctl rebuild
```
## Enable swap LVM in kdump
- Required if you want to use a swap device in kdump
```shell
sudo sed -e 's#^KDUMP_COMMANDLINE_APPEND="\(.*\)"$#KDUMP_COMMANDLINE_APPEND="\1 rd.lvm.lv=rhel/swap"#' \
-i /etc/sysconfig/kdump
```
## Reload kdump
```shell
sudo kdumpctl reload
```
# Test
```shell
echo N | sudo tee /sys/module/kernel/parameters/crash_kexec_post_notifiers
echo c | sudo tee /proc/sysrq-trigger
```
@@ -0,0 +1,20 @@
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=hsavmcore Service
After=initrd.target initrd-parse-etc.service sysroot.mount
After=dracut-initqueue.service dracut-pre-mount.service dracut-mount.service dracut-pre-pivot.service
Before=kdump-capture.service
Before=initrd-cleanup.service
[Service]
Type=notify
ExecStart=/usr/sbin/hsavmcore -c /etc/hsavmcore.conf
StandardInput=null
StandardOutput=syslog
StandardError=syslog+console
@@ -0,0 +1,37 @@
#!/usr/bin/bash
. $dracutfunctions
if ! [[ -d "${initdir}/tmp" ]]; then
mkdir -p "${initdir}/tmp"
fi
check() {
[[ $debug ]] && set -x
#kdumpctl sets this explicitly
if [ -z "$IN_KDUMP" ]
then
return 1
fi
return 0
}
depends() {
local _dep="base shutdown"
echo $_dep
return 0
}
installkernel() {
hostonly='' instmods fuse
}
install() {
inst "/usr/sbin/hsavmcore" "/usr/sbin/hsavmcore"
inst "/etc/hsavmcore.conf" "/etc/hsavmcore.conf"
inst "$moddir/hsavmcore.service" "$systemdsystemunitdir/hsavmcore.service"
mkdir -p "$initdir/$systemdsystemunitdir/initrd.target.wants"
ln_r "$systemdsystemunitdir/hsavmcore.service" "$systemdsystemunitdir/initrd.target.wants/hsavmcore.service"
inst_hook pre-mount 30 "$moddir/setup-fuse.sh"
}
@@ -0,0 +1,3 @@
#!/bin/sh
modprobe fuse
+141
View File
@@ -0,0 +1,141 @@
# Setup
## Configure crashkernel
```shell
sudo vim /etc/default/grub
sudo sed -e 's/GRUB_CMDLINE_LINUX_DEFAULT="\(.*\)"/GRUB_CMDLINE_LINUX_DEFAULT="\1 crashkernel=512M"/' \
-i /etc/default/grub
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
sudo reboot
```
## Production kernel's root file system
- kdump mounts the production kernel's root file system under **/kdump/mnt1**.
## Dependencies
```shell
sudo zypper install -y fuse fuse-devel systemd-devel
```
## Build hsavmcore
```shell
make -C s390-tools/hsavmcore
```
## Install hsavmcore
```shell
sudo cp s390-tools/hsavmcore/hsavmcore /usr/sbin/
```
## Create swap file
```shell
sudo dd if=/dev/zero of=/var/crash/swap.img bs=1M count=1024
sudo mkswap /var/crash/swap.img
```
## Install hsavmcore.conf
### Test configuration
- Doesn't require HSA support
#### HSA cache in file
```shell
cat <<EOF | sudo tee /etc/hsavmcore.conf
verbose = 2
workdir = /kdump/mnt1/var/crash
use_hsa_mem = 0
mount_debugfs = 1
hsa_size = 0x1ffff000
release_hsa = 0
bind_mount_vmcore = 1
EOF
```
#### HSA cache in memory
```shell
cat <<EOF | sudo tee /etc/hsavmcore.conf
verbose = 2
workdir = /kdump/mnt1/var/crash
use_hsa_mem = 1
mount_debugfs = 1
hsa_size = 0x1ffff000
release_hsa = 0
bind_mount_vmcore = 1
swap = /kdump/mnt1/var/crash/swap.img
EOF
```
### Production configuration
- Works only on s390x
#### HSA cache in file
```shell
cat <<EOF | sudo tee /etc/hsavmcore.conf
verbose = 2
workdir = /kdump/mnt1/var/crash
use_hsa_mem = 0
mount_debugfs = 1
hsa_size = -1
release_hsa = 1
bind_mount_vmcore = 1
EOF
```
#### HSA cache in memory
```shell
cat <<EOF | sudo tee /etc/hsavmcore.conf
verbose = 2
workdir = /kdump/mnt1/var/crash
use_hsa_mem = 1
mount_debugfs = 1
hsa_size = -1
release_hsa = 1
bind_mount_vmcore = 1
swap = /kdump/mnt1/var/crash/swap.img
EOF
```
## Install new dracut module
```shell
sudo cp -r s390-tools/hsavmcore/initramfs/sles/dracut/modules.d/99hsavmcore /usr/lib/dracut/modules.d/
```
## Add the new dracut module as a dependency to the dracut module *kdump*
```shell
sudo sed -e 's/_modules\[drm\]=/_modules[drm]=\n _modules[hsavmcore]=/' \
-i /usr/lib/dracut/modules.d/99kdump/module-setup.sh
```
## Rebuild kdump initramfs
```shell
sudo mkdumprd -f
```
## Reload kdump
```shell
systemctl enable kdump
systemctl restart kdump
```
# Test
```shell
echo c | sudo tee /proc/sysrq-trigger
```

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