Compare commits

..

40 Commits

Author SHA1 Message Date
Jan Höppner
a528bb41e0 New release s390-tools-2.14.0
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-08-21 12:12:02 +02:00
Jan Höppner
ed52031821 cpumf: Remove TESTS from Makefile
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-08-21 09:12:29 +02:00
Stefan Haberland
60f33fb2de zdsfs: add coordinated read access to man page
Add description for coordinated read access to man page as well as some
editorial changes after ID review.

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

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

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

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

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

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

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

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

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

This fixes the error on Ubuntu 20.04:

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

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

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

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

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

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

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

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

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

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

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

Fixes: #84

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

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

Closes: #76

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

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

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

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

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

Manpages adapted accordingly.

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

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

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

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

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

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

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

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

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

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

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

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

5
.gitignore vendored
View File

@@ -11,9 +11,8 @@
cmsfs-fuse/cmsfs-fuse
cpacfstats/cpacfstats
cpacfstats/cpacfstatsd
cpumf/bin/chcpumf
cpumf/bin/cpumf_helper
cpumf/bin/lscpumf
cpumf/chcpumf
cpumf/lscpumf
cpuplugd/cpuplugd
dasdfmt/dasdfmt
dasdinfo/dasdinfo

View File

@@ -1,6 +1,7 @@
List of all individuals having contributed content to s390-tools
----------------------------------------------------------------
- Alexander Egorenkov
- Alexey Ishchuk
- Andreas Herrmann
- Andre Wild
@@ -32,6 +33,7 @@ List of all individuals having contributed content to s390-tools
- Fritz Elfert
- Gerald Schaefer
- Gerhard Tonn
- Guevenc Guelce
- Hannes Reinecke
- Hans-Joachim Picht
- Hans Wippel
@@ -52,6 +54,7 @@ List of all individuals having contributed content to s390-tools
- Jean-Baptiste Joret
- Jens Remus
- Jochen Roehrig
- Juergen Christ
- Julian Wiedmann
- Karsten Graul
- Kittipon Meesompop

View File

@@ -1,5 +1,23 @@
Release history for s390-tools (MIT version)
--------------------------------------------
* __v2.14.0 (2020-08-21)__
For Linux kernel version: 5.7 / 5.8
Changes of existing tools:
- cpacfstats: Add ECC counters
- dbginfo: Added collection of /proc/softirqs
- ipl-tools: Add nvme device support to lsreipl/chreipl
- zdsfs: Add coordinated read access
- libzds: Add curl interface to access zosmf rest api
- util_opt: Change util_opt_init() to honor current command, if set
Bug Fixes:
- lsluns: Try harder to find udevadm
- mon_tools: Update udevadm location
- zipl: Fix NVMe partition and base device detection
- zipl/stage3: Correctly handle diag308 response code
- znetconf: Introduce better ways to locate udevadm
* __v2.13.0 (2020-05-06)__
For Linux kernel version: 5.5 / 5.6

View File

@@ -5,7 +5,7 @@ COMMON_INCLUDED = true
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
VERSION = 2
RELEASE = 13
RELEASE = 14
PATCHLEVEL = 0
DISTRELEASE = build-$(shell date +%Y%m%d)
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

214
cpumf/chcpumf.c Normal file
View File

@@ -0,0 +1,214 @@
/*
* 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
}
};
/* Parse tool parameters. Fill in global variables keep_case, buffersize and
* command according to parameters. Return VMCP_OK on success, VMCP_OPT
* in case of parameter errors. In case of --help or --version, print
* respective text to stdout and exit. */
static long parse_buffersize(char *string)
{
char *suffix;
long bytes;
bytes = strtol(string, &suffix, 10);
if (strlen(suffix) > 1)
return -1;
switch (*suffix) {
case 'k':
case 'K':
bytes *= 1024;
break;
case 'm':
case 'M':
bytes *= 1048576;
break;
case '\0':
break;
default:
return 0;
}
return bytes;
}
static int read_sfb(unsigned long *min, unsigned long *max)
{
int rc = EXIT_SUCCESS;
FILE *fp;
fp = fopen(PERF_SFB_SIZE, "r");
if (fp == NULL) {
linux_error(PERF_SFB_SIZE);
return EXIT_FAILURE;
}
if (fscanf(fp, "%ld,%ld", min, max) != 2) {
fprintf(stderr, "Error: Can not parse file " PERF_SFB_SIZE);
rc = EXIT_FAILURE;
}
fclose(fp);
return rc;
}
static int write_sfb(unsigned long min, unsigned long max)
{
int rc = EXIT_SUCCESS;
char text[64];
size_t len;
FILE *fp;
fp = fopen(PERF_SFB_SIZE, "w");
if (fp == NULL) {
linux_error(PERF_SFB_SIZE);
return EXIT_FAILURE;
}
snprintf(text, sizeof text, "%ld,%ld", min, max);
len = strlen(text) + 1;
if (fwrite(text, 1, len, fp) != len) {
linux_error(PERF_SFB_SIZE);
rc = EXIT_FAILURE;
}
if (fclose(fp)) {
linux_error(PERF_SFB_SIZE);
rc = EXIT_FAILURE;
}
if (verbose && rc != EXIT_FAILURE)
fprintf(stderr, "Sampling buffer sizes:\n"
" Minimum:%7ld sample-data-blocks\n"
" Maximum:%7ld sample-data-blocks\n",
min, max);
return rc;
}
static int parse_args(int argc, char **argv)
{
int opt, action = 0;
long new;
while ((opt = util_opt_getopt_long(argc, argv)) != -1) {
switch (opt) {
case 'h':
util_prg_print_help();
util_opt_print_help();
exit(EXIT_SUCCESS);
case 'v':
util_prg_print_version();
exit(EXIT_SUCCESS);
case 'x':
new = parse_buffersize(optarg);
if (new < 1) {
fprintf(stderr, "The specified number(s)"
" are not valid\n");
exit(EXIT_FAILURE);
}
max_sdb = new;
action = 1;
break;
case 'm':
new = parse_buffersize(optarg);
if (new < 1) {
fprintf(stderr, "The specified number(s)"
" are not valid\n");
exit(EXIT_FAILURE);
}
min_sdb = new;
action = 1;
break;
case 'V':
verbose = 1;
break;
case '?':
fprintf(stderr, "One or more options are not valid\n");
fprintf(stderr, "Try 'chcpumf --help' for more"
" information\n");
exit(EXIT_FAILURE);
}
}
if (!action) {
fprintf(stderr, "You must specify a valid option\n");
exit(EXIT_FAILURE);
}
return action;
}
int main(int argc, char **argv)
{
int ret = EXIT_FAILURE;
struct stat sbuf;
util_prg_init(&prg);
util_opt_init(opt_vec, NULL);
if (stat(PERF_PATH PERF_SF, &sbuf) != 0) {
fprintf(stderr,
"No CPU-measurement sampling facility detected\n");
return ret;
}
if (read_sfb(&min_sdb, &max_sdb))
return ret;
/* Overwrite min_sdb and/or max_sdb */
parse_args(argc, argv);
if (min_sdb >= max_sdb) {
fprintf(stderr, "The specified maximum must be greater "
"than the minimum\n");
return ret;
}
return write_sfb(min_sdb, max_sdb);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

23
cpumf/defines.h Normal file
View File

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

3120
cpumf/lscpumf.c Normal file

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

169
ipl_tools/nvme.c Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1567,15 +1567,17 @@ scan_check(struct scan_token* scan)
/*
* Check if kernel and initrd image paths provided by BLS files are readable.
* If not, add value of 'scan_keyword_target' into search path and silently
* update scan list.
* update scan list if the file exists.
* In case neither path works the scan_check code will correctly handle missing
* files
*/
int
scan_check_bls(struct scan_token *scan)
void scan_update_bls_path(struct scan_token *scan)
{
int i, rc;
char *target_value = NULL;
char *img_value = NULL;
char *buffer = NULL;
char *file = NULL;
char *tmp, *value;
int i;
/*
* In the BLS case, each BLS section heading inherits a keyword
* assignment target= from zipl.conf, and they are all the same.
@@ -1589,38 +1591,46 @@ scan_check_bls(struct scan_token *scan)
}
}
if (!target_value)
return -1;
return;
for (i = 0 ; scan[i].id != scan_id_empty; i++) {
if (scan[i].id != scan_id_keyword_assignment)
continue;
if (scan[i].content.keyword.keyword == scan_keyword_image ||
scan[i].content.keyword.keyword == scan_keyword_ramdisk) {
rc = misc_check_readable_file(
scan[i].content.keyword.value);
if (rc) {
value = scan[i].content.keyword.value;
/*
* put the filename only into the file var before
* checking its presence
*/
if (contains_address(value)) {
tmp = strrchr(value, ',');
file = strndup(value, tmp - value);
} else {
file = value;
}
if (misc_check_readable_file(file)) {
misc_asprintf(&img_value, "%s%s",
target_value,
scan[i].content.keyword.value);
rc = misc_check_readable_file(img_value);
if (rc) {
error_text(
"Image file '%s' is not accessible",
scan[i].content.keyword.value);
return rc;
target_value, file);
if (misc_check_readable_file(img_value))
continue;
/*
* when file has stripped the load address part,
* do generate a prefixed value
*/
if (file != value) {
free(file);
free(img_value);
misc_asprintf(&img_value, "%s%s",
target_value, value);
}
buffer = (char *)
misc_malloc(strlen(img_value) + 1);
if (buffer == NULL)
return -1;
memcpy(buffer, img_value, strlen(img_value));
buffer[strlen(img_value)] = 0;
free(scan[i].content.keyword.value);
scan[i].content.keyword.value = buffer;
scan[i].content.keyword.value = img_value;
}
}
}
return 0;
return;
}
static int

View File

@@ -2454,7 +2454,6 @@ static int _keystore_display_apqn_status(struct keystore *keystore,
if (apqns == NULL)
return 0;
apqns = properties_get(properties, PROP_NAME_APQNS);
key_type = properties_get(properties, PROP_NAME_KEY_TYPE);
rc = cross_check_apqns(apqns, mkvp,
get_min_card_level_for_keytype(key_type),
@@ -2867,8 +2866,7 @@ static int _keystore_process_reencipher(struct keystore *keystore,
rc = _keystore_perform_reencipher(keystore, name, info->lib,
&params, secure_key,
secure_key_size, is_old_mk,
properties_get(properties,
PROP_NAME_APQNS));
apqns);
if (rc < 0)
goto out;
if (rc > 0) {

View File

@@ -221,7 +221,7 @@ function used to encrypt the volume key in the LUKS key slots is of less
relevance.
.PP
.B Note:
The \fBreencipher\fP command requires the CCA host library (libcsulcca.so, for)
The \fBreencipher\fP command requires the CCA host library (libcsulcca.so)
for secure volume keys of type CCA-AESDATA or CCA-AESCIPHER, or the IBM Z
Enterprise PKCS #11 (EP11) Support Program (EP11 host library) for secure volume
keys of type EP11-AES to be installed. For the supported environments and

View File

@@ -650,10 +650,10 @@ static int get_password_file(char **pwd, size_t *pwd_size, const char *key_file,
size_t file_read_size;
int regular_file = 0;
int char_to_read = 0;
size_t buflen = 0, i;
int fd, rc, newline;
char *pass = NULL;
int char_read = 0;
size_t buflen, i;
struct stat sb;
fd = key_file ? open(key_file, O_RDONLY) : STDIN_FILENO;
@@ -712,6 +712,7 @@ static int get_password_file(char **pwd, size_t *pwd_size, const char *key_file,
if (keyfile_offset && keyfile_seek(fd, keyfile_offset) < 0) {
warnx("Cannot seek to requested key file offset %lu",
keyfile_offset);
rc = -EIO;
goto out_err;
}

View File

@@ -36,7 +36,7 @@ location. Keys stored in a secure key repository inherit the permissions from
the repository directory (except write access for other users, which is always
denied). The default repository location \fB/etc/zkey/repository\fP is created
with group \fBzkeyadm\fP as owner and mode \fB770\fP. Thus all secure keys
created in that repository are owned by group \fBzkeyadm\fP. Anyone that
created in that repository are owned by group \fBzkeyadm\fP. Anyone who
is supposed to access secure keys in the secure key repository must be part of
group \fBzkeyadm\fP.
.PP
@@ -50,11 +50,12 @@ volume association also contains the device-mapper name, separated by a colon,
used with dm-crypt. A specific volume can only be associated with one secure
key.
.PP
The generated secure key is saved in a file with a size of 64 or 128 bytes.
The file contains an AES key with a length of 128, 192, or 256 bits. The key is
enciphered with the master key of the CCA or EP11 cryptographic adapter.
Secure keys that are used for the XTS cipher mode can be 128 or 256 bits
in size.
The generated secure key is saved in a file, and contains an AES secure key with
a length of 128, 192, or 256 bits, or two concatenated AES secure keys with a
length of 128, or 256 bits each, for keys that are used for the XTS cipher mode.
Note that the file size is not related to the key bit size, but is specific for
the secure key type. The key is enciphered with the master key of the CCA or
EP11 cryptographic adapter.
.
.
.