mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7770b7a2c0 | |||
| 2ef6f64b1d | |||
| de013d2f04 | |||
| ed94cf9839 | |||
| 2fec7688b0 | |||
| 3c1834f0fc | |||
| f6e78d3ecd | |||
| dad7fce7a1 | |||
| 8058921f58 | |||
| bb8e0e1047 | |||
| 5dcac6d2e3 | |||
| 552772d2a9 | |||
| 42611a787d | |||
| 743788d02f | |||
| 6028300366 | |||
| 70cb25766b | |||
| 36eede8f31 | |||
| ec0dcdb685 | |||
| 2a1a821bb3 | |||
| 09c01e580a | |||
| 27902c9106 | |||
| a8d328bba2 | |||
| 917d611883 | |||
| 94e0b644a7 | |||
| 10f8565e32 | |||
| 22bce41dd7 | |||
| e35e73d2a3 | |||
| f821f31a51 | |||
| 493af760ed | |||
| 3287bb9613 |
@@ -1,6 +1,25 @@
|
|||||||
Release history for s390-tools (MIT version)
|
Release history for s390-tools (MIT version)
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
|
||||||
|
* __v2.28.0 (2023-07-11)__
|
||||||
|
|
||||||
|
For Linux kernel version: 6.4
|
||||||
|
|
||||||
|
Changes of existing tools:
|
||||||
|
- chzcrypt: Support for SE AP pass-through support
|
||||||
|
- genprotimg: Add support for non-s390x architectures
|
||||||
|
- lszcrypt: Support for SE AP pass-through support
|
||||||
|
- zdev: Add support for autoquiesce related sysfs attributes
|
||||||
|
|
||||||
|
Bug Fixes:
|
||||||
|
- ap_tools/ap-check: Handle missing 'matrix' and 'control_domains' attrs
|
||||||
|
- ap_tools/ap-check: Hold ap config file lock over get attributes
|
||||||
|
- s390-tools: Fix build for ppc64le
|
||||||
|
- zdev: Add missing label in the udev-rules
|
||||||
|
- zdev: Add proper value input for the ZDEV_SITE_ID key
|
||||||
|
- zdev: Use rename-file to avoid any symlinks created
|
||||||
|
- zipl/dump: fix ngdump dracut helper script
|
||||||
|
|
||||||
* __v2.27.0 (2023-05-30)__
|
* __v2.27.0 (2023-05-30)__
|
||||||
|
|
||||||
For Linux kernel version: 6.3
|
For Linux kernel version: 6.3
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
|
|||||||
else
|
else
|
||||||
BASELIB_DIRS =
|
BASELIB_DIRS =
|
||||||
LIB_DIRS = libpv
|
LIB_DIRS = libpv
|
||||||
TOOL_DIRS = pvattest
|
TOOL_DIRS = genprotimg pvattest
|
||||||
endif
|
endif
|
||||||
|
|
||||||
SUB_DIRS = $(BASELIB_DIRS) $(LIB_DIRS) $(TOOL_DIRS)
|
SUB_DIRS = $(BASELIB_DIRS) $(LIB_DIRS) $(TOOL_DIRS)
|
||||||
|
|||||||
+31
-4
@@ -434,14 +434,23 @@ static int check_other_mdev_sysfs_cb(const char *path, const char *filename,
|
|||||||
strcasecmp(filename, cbdata->uuid) == 0)
|
strcasecmp(filename, cbdata->uuid) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
dev2 = vfio_ap_device_new();
|
/*
|
||||||
|
* Read the 'matrix' attribute to get the list of queues for the active
|
||||||
|
* device. If the sysfs attribute is unreadable, assume the device is
|
||||||
|
* being destroyed and skip it.
|
||||||
|
*/
|
||||||
matrix_path = path_get_vfio_ap_attr(filename, "matrix");
|
matrix_path = path_get_vfio_ap_attr(filename, "matrix");
|
||||||
f = fopen(matrix_path, "r");
|
f = fopen(matrix_path, "r");
|
||||||
|
free(matrix_path);
|
||||||
|
if (!f)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
dev2 = vfio_ap_device_new();
|
||||||
|
|
||||||
while (fgets(buf, sizeof(buf), f))
|
while (fgets(buf, sizeof(buf), f))
|
||||||
vfio_ap_parse_matrix(dev2, buf);
|
vfio_ap_parse_matrix(dev2, buf);
|
||||||
vfio_ap_sort_matrix_results(dev2);
|
vfio_ap_sort_matrix_results(dev2);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
free(matrix_path);
|
|
||||||
|
|
||||||
/* Look for conflicts between target device and this device */
|
/* Look for conflicts between target device and this device */
|
||||||
rc = find_apqn_conflicts(filename, dev->adapters, dev->domains,
|
rc = find_apqn_conflicts(filename, dev->adapters, dev->domains,
|
||||||
@@ -787,21 +796,39 @@ static int ap_check_handle_get_attributes(struct ap_check_anchor *anc)
|
|||||||
char buf[80];
|
char buf[80];
|
||||||
char *path;
|
char *path;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = ap_get_lock_callout();
|
||||||
|
if (rc) {
|
||||||
|
fprintf(stderr, "Failed to acquire configuration lock %d\n", rc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
anc->cleanup_lock = true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read the 'matrix' and 'control_domains' attributes to get the
|
||||||
|
* current attributes of the active device. If either of these sysfs
|
||||||
|
* attributes is unreadable, assume the device is being destroyed
|
||||||
|
* and return nothing.
|
||||||
|
*/
|
||||||
path = path_get_vfio_ap_attr(anc->uuid, "matrix");
|
path = path_get_vfio_ap_attr(anc->uuid, "matrix");
|
||||||
f = fopen(path, "r");
|
f = fopen(path, "r");
|
||||||
|
free(path);
|
||||||
|
if (!f)
|
||||||
|
return 0;
|
||||||
while (fgets(buf, sizeof(buf), f))
|
while (fgets(buf, sizeof(buf), f))
|
||||||
vfio_ap_parse_matrix(dev, buf);
|
vfio_ap_parse_matrix(dev, buf);
|
||||||
vfio_ap_sort_matrix_results(dev);
|
vfio_ap_sort_matrix_results(dev);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
free(path);
|
|
||||||
|
|
||||||
path = path_get_vfio_ap_attr(anc->uuid, "control_domains");
|
path = path_get_vfio_ap_attr(anc->uuid, "control_domains");
|
||||||
f = fopen(path, "r");
|
f = fopen(path, "r");
|
||||||
|
free(path);
|
||||||
|
if (!f)
|
||||||
|
return 0;
|
||||||
while (fgets(buf, sizeof(buf), f))
|
while (fgets(buf, sizeof(buf), f))
|
||||||
vfio_ap_parse_control(dev, buf);
|
vfio_ap_parse_control(dev, buf);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
free(path);
|
|
||||||
|
|
||||||
printf("[{");
|
printf("[{");
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -28,7 +28,7 @@ endif
|
|||||||
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
|
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
|
||||||
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
|
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
|
||||||
VERSION = 2
|
VERSION = 2
|
||||||
RELEASE = 27
|
RELEASE = 28
|
||||||
PATCHLEVEL = 0
|
PATCHLEVEL = 0
|
||||||
DISTRELEASE = build-$(shell date +%Y%m%d)
|
DISTRELEASE = build-$(shell date +%Y%m%d)
|
||||||
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
|
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
|
||||||
@@ -211,8 +211,8 @@ fi
|
|||||||
# Returns the linker option if available and nothing otherwise
|
# Returns the linker option if available and nothing otherwise
|
||||||
#
|
#
|
||||||
define test_linker_flag
|
define test_linker_flag
|
||||||
$(shell printf "int main(void) {return 0;}\n" | \
|
$(shell printf ".globl _start\n_start:\nnop\n" | \
|
||||||
( $(CC) "-Wl,$1" -o /dev/null -x c - ) >/dev/null 2>&1 && printf -- '-Wl,%s' "$1")
|
( $(LINK) "-Wl,$1" -o /dev/null -nostdlib -x assembler -) >/dev/null 2>&1 && printf -- '-Wl,%s' "$1")
|
||||||
endef
|
endef
|
||||||
|
|
||||||
NO_WARN_RWX_SEGMENTS_LDFLAGS := $(call test_linker_flag,"--no-warn-rwx-segments")
|
NO_WARN_RWX_SEGMENTS_LDFLAGS := $(call test_linker_flag,"--no-warn-rwx-segments")
|
||||||
|
|||||||
@@ -323,7 +323,7 @@ static void json_print_virtual_counter_answer(int s, int ctr,
|
|||||||
pai_str[paictr], space, paictr + 1);
|
pai_str[paictr], space, paictr + 1);
|
||||||
if (paistate < 0) {
|
if (paistate < 0) {
|
||||||
printf("\"error\":%d}", paistate);
|
printf("\"error\":%d}", paistate);
|
||||||
/* Protocol does not send furter counters. */
|
/* Protocol does not send further counters. */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
printf("\"value\":%"PRIu64"}", paivalue);
|
printf("\"value\":%"PRIu64"}", paivalue);
|
||||||
|
|||||||
@@ -45,9 +45,8 @@ counter set authorization control" checkbox.
|
|||||||
- The daemon requires root privileges to interact with the performance
|
- The daemon requires root privileges to interact with the performance
|
||||||
ioctls of the kernel.
|
ioctls of the kernel.
|
||||||
|
|
||||||
CPU hotplug is not recognized by the daemon. When adding or removing a CPU,
|
CPU hotplug is recognized by the daemon. When adding or removing a CPU,
|
||||||
restart the daemon to ensure correct summing of the per-CPU performance
|
the daemon ensures correct summing of the per-CPU performance counters.
|
||||||
counters.
|
|
||||||
|
|
||||||
The starting daemon first checks for any stale pid file
|
The starting daemon first checks for any stale pid file
|
||||||
\%/run/cpacfstatsd.pid. If this file exists, and the process ID in the
|
\%/run/cpacfstatsd.pid. If this file exists, and the process ID in the
|
||||||
|
|||||||
+56
-17
@@ -252,20 +252,26 @@ static int do_print(int s, enum ctr_e ctr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int become_daemon(void)
|
static int become_daemon(int *startup_pipe)
|
||||||
{
|
{
|
||||||
|
int child_initialized = 0, fd;
|
||||||
|
int pipefds[2];
|
||||||
FILE *f;
|
FILE *f;
|
||||||
int fd;
|
|
||||||
|
|
||||||
/* syslog */
|
/* syslog */
|
||||||
openlog("cpacfstatsd", 0, LOG_DAEMON);
|
openlog("cpacfstatsd", 0, LOG_DAEMON);
|
||||||
|
|
||||||
|
if (pipe(pipefds) != 0) {
|
||||||
|
eprint("pipe() failed, errno=%d [%s]\n", errno, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fork and terminate parent
|
* fork and terminate parent
|
||||||
* Reasons:
|
* Reasons:
|
||||||
* - opens new command line prompt
|
* - opens new command line prompt
|
||||||
* - the child process is guaranteed not to be the process group leader
|
* - the child process is guaranteed not to be the process group leader
|
||||||
* nessecarry for setsid.
|
* necessary for setsid.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
switch (fork()) {
|
switch (fork()) {
|
||||||
@@ -276,9 +282,23 @@ static int become_daemon(void)
|
|||||||
case 0: /* child */
|
case 0: /* child */
|
||||||
break;
|
break;
|
||||||
default: /* parent */
|
default: /* parent */
|
||||||
|
(void)close(pipefds[1]);
|
||||||
|
if (read(pipefds[0], &child_initialized, sizeof(child_initialized)) !=
|
||||||
|
sizeof(child_initialized)) {
|
||||||
|
eprint("Couldn't read from PIPE, errno=%d [%s]\n", errno, strerror(errno));
|
||||||
|
(void)close(pipefds[0]);
|
||||||
|
_exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
(void)close(pipefds[0]);
|
||||||
|
if (!child_initialized)
|
||||||
|
_exit(EXIT_FAILURE);
|
||||||
_exit(0);
|
_exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Executed within the child context only */
|
||||||
|
(void)close(pipefds[0]);
|
||||||
|
*startup_pipe = pipefds[1];
|
||||||
|
|
||||||
if (chdir("/") != 0) {
|
if (chdir("/") != 0) {
|
||||||
eprint("Chdir('/') failed, errno=%d [%s]\n",
|
eprint("Chdir('/') failed, errno=%d [%s]\n",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
@@ -418,7 +438,7 @@ int eprint(const char *format, ...)
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int rc, sfd, foreground = 0;
|
int rc, sfd, foreground = 0, startup_pipe = -1, initialized = 0;
|
||||||
struct sigaction act;
|
struct sigaction act;
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@@ -454,27 +474,27 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (check_pidfile() != 0) {
|
if (check_pidfile() != 0) {
|
||||||
eprint("Stalled pid file or daemon allready running, terminating\n");
|
eprint("Stalled pid file or daemon already running, terminating\n");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!foreground) {
|
if (!foreground) {
|
||||||
if (become_daemon() != 0) {
|
if (become_daemon(&startup_pipe) != 0) {
|
||||||
eprint("Couldn't daemonize\n");
|
eprint("Couldn't daemonize\n");
|
||||||
return EXIT_FAILURE;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (perf_init() != 0) {
|
if (perf_init() != 0) {
|
||||||
eprint("Couldn't initialize perf lib\n");
|
eprint("Couldn't initialize perf lib\n");
|
||||||
return EXIT_FAILURE;
|
goto error;
|
||||||
}
|
}
|
||||||
atexit(perf_close);
|
atexit(perf_close);
|
||||||
|
|
||||||
sfd = open_socket(SERVER);
|
sfd = open_socket(SERVER);
|
||||||
if (sfd < 0) {
|
if (sfd < 0) {
|
||||||
eprint("Couldn't initialize server socket\n");
|
eprint("Couldn't initialize server socket\n");
|
||||||
return EXIT_FAILURE;
|
goto error;
|
||||||
}
|
}
|
||||||
atexit(remove_sock);
|
atexit(remove_sock);
|
||||||
|
|
||||||
@@ -484,17 +504,27 @@ int main(int argc, char *argv[])
|
|||||||
if (sigaction(SIGINT, &act, 0) != 0) {
|
if (sigaction(SIGINT, &act, 0) != 0) {
|
||||||
eprint("Couldn't establish signal handler for SIGINT, errno=%d [%s]\n",
|
eprint("Couldn't establish signal handler for SIGINT, errno=%d [%s]\n",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
return EXIT_FAILURE;
|
goto error;
|
||||||
}
|
}
|
||||||
if (sigaction(SIGTERM, &act, 0) != 0) {
|
if (sigaction(SIGTERM, &act, 0) != 0) {
|
||||||
eprint("Couldn't establish signal handler for SIGTERM, errno=%d [%s]\n",
|
eprint("Couldn't establish signal handler for SIGTERM, errno=%d [%s]\n",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
return EXIT_FAILURE;
|
goto error;
|
||||||
}
|
}
|
||||||
/* Ignore SIGPIPE such that we see EPIPE as return from write. */
|
/* Ignore SIGPIPE such that we see EPIPE as return from write. */
|
||||||
signal(SIGPIPE, SIG_IGN);
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
|
||||||
eprint("Running\n");
|
eprint("Running\n");
|
||||||
|
initialized = 1;
|
||||||
|
/* `startup_pipe` has been initialized, so we know we are
|
||||||
|
* running in daemon mode. Let's write to the pipe so that the
|
||||||
|
* parent knows that the initialization is complete.
|
||||||
|
*/
|
||||||
|
if (startup_pipe != -1 &&
|
||||||
|
write(startup_pipe, &initialized, sizeof(initialized)) != sizeof(initialized))
|
||||||
|
goto error;
|
||||||
|
(void)close(startup_pipe);
|
||||||
|
startup_pipe = -1;
|
||||||
|
|
||||||
while (!stopsig) {
|
while (!stopsig) {
|
||||||
enum ctr_e ctr;
|
enum ctr_e ctr;
|
||||||
@@ -507,13 +537,14 @@ int main(int argc, char *argv[])
|
|||||||
continue;
|
continue;
|
||||||
eprint("Accept() failure, errno=%d [%s]\n",
|
eprint("Accept() failure, errno=%d [%s]\n",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
return EXIT_FAILURE;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = recv_query(s, &ctr, &cmd);
|
rc = recv_query(s, &ctr, &cmd);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
eprint("Recv_query() failed, ignoring\n");
|
eprint("Recv_query() failed, ignoring\n");
|
||||||
goto cleanup;
|
close(s);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd == ENABLE)
|
if (cmd == ENABLE)
|
||||||
@@ -527,11 +558,9 @@ int main(int argc, char *argv[])
|
|||||||
else {
|
else {
|
||||||
eprint("Received unknown command %d, ignoring\n",
|
eprint("Received unknown command %d, ignoring\n",
|
||||||
(int) cmd);
|
(int) cmd);
|
||||||
goto cleanup;
|
close(s);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
|
||||||
close(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stopsig == SIGTERM)
|
if (stopsig == SIGTERM)
|
||||||
@@ -543,4 +572,14 @@ cleanup:
|
|||||||
remove_pidfile();
|
remove_pidfile();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (startup_pipe != -1) {
|
||||||
|
/* Notify the parent process that there was an error */
|
||||||
|
if (write(startup_pipe, &initialized, sizeof(initialized)) != sizeof(initialized))
|
||||||
|
eprint("Couldn't write to PIPE, errno=%d [%s]\n", errno, strerror(errno));
|
||||||
|
(void)close(startup_pipe);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -496,10 +496,8 @@ int perf_init(void)
|
|||||||
num -= 2;
|
num -= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num == 0) {
|
if (num == 0)
|
||||||
eprint("No crypto counters supported!\n");
|
eprint("No crypto counters supported!\n");
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (perf_load_counter_data())
|
if (perf_load_counter_data())
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
+3
-10
@@ -276,9 +276,7 @@ static bool check_setpossible(void)
|
|||||||
if (!get_cpus(CPUS_KERNELMAX, cpubuf, sizeof(cpubuf)))
|
if (!get_cpus(CPUS_KERNELMAX, cpubuf, sizeof(cpubuf)))
|
||||||
return false;
|
return false;
|
||||||
max_possible_cpus = getnumber(cpubuf, '\0') + 1;
|
max_possible_cpus = getnumber(cpubuf, '\0') + 1;
|
||||||
check = calloc(max_possible_cpus, sizeof(*check));
|
check = util_zalloc(max_possible_cpus * sizeof(*check));
|
||||||
if (!check)
|
|
||||||
err(EXIT_FAILURE, "Maximum CPUs %u", max_possible_cpus);
|
|
||||||
if (!get_cpus(CPUS_POSSIBLE, cpubuf, sizeof(cpubuf))) {
|
if (!get_cpus(CPUS_POSSIBLE, cpubuf, sizeof(cpubuf))) {
|
||||||
free(check);
|
free(check);
|
||||||
return false;
|
return false;
|
||||||
@@ -533,13 +531,8 @@ static int do_read(int ioctlfd)
|
|||||||
struct s390_hwctr_read *read;
|
struct s390_hwctr_read *read;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (!ioctlbuffer) {
|
if (!ioctlbuffer)
|
||||||
ioctlbuffer = malloc(ioctlbuffer_len);
|
ioctlbuffer = util_malloc(ioctlbuffer_len);
|
||||||
if (!ioctlbuffer) {
|
|
||||||
warn("ioctl S390_HWCTR_START");
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
read = (struct s390_hwctr_read *)ioctlbuffer;
|
read = (struct s390_hwctr_read *)ioctlbuffer;
|
||||||
rc = ioctl(ioctlfd, S390_HWCTR_READ, read);
|
rc = ioctl(ioctlfd, S390_HWCTR_READ, read);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ all: all-recursive
|
|||||||
|
|
||||||
install: all install-recursive
|
install: all install-recursive
|
||||||
$(INSTALL) -d -m 755 "$(PKGDATADIR)"
|
$(INSTALL) -d -m 755 "$(PKGDATADIR)"
|
||||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 boot/stage3a.bin "$(PKGDATADIR)"
|
|
||||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 boot/stage3b_reloc.bin "$(PKGDATADIR)"
|
|
||||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 samples/check_hostkeydoc "$(PKGDATADIR)"
|
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 samples/check_hostkeydoc "$(PKGDATADIR)"
|
||||||
|
|
||||||
clean: clean-recursive
|
clean: clean-recursive
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
# Common definitions
|
# Common definitions
|
||||||
include ../../common.mak
|
include ../../common.mak
|
||||||
|
|
||||||
|
FILES := stage3a.bin stage3b.bin stage3b_reloc.bin
|
||||||
|
|
||||||
|
ifeq ($(HOST_ARCH),s390x)
|
||||||
ZIPL_DIR := $(rootdir)/zipl
|
ZIPL_DIR := $(rootdir)/zipl
|
||||||
ZIPL_BOOT_DIR := $(ZIPL_DIR)/boot
|
ZIPL_BOOT_DIR := $(ZIPL_DIR)/boot
|
||||||
|
PKGDATADIR := $(DESTDIR)$(TOOLS_DATADIR)/genprotimg
|
||||||
|
|
||||||
INCLUDE_PATHS := $(ZIPL_BOOT_DIR) $(ZIPL_DIR)/include $(rootdir)/include
|
INCLUDE_PATHS := $(ZIPL_BOOT_DIR) $(ZIPL_DIR)/include $(rootdir)/include
|
||||||
INCLUDE_PARMS := $(addprefix -I,$(INCLUDE_PATHS))
|
INCLUDE_PARMS := $(addprefix -I,$(INCLUDE_PATHS))
|
||||||
@@ -18,8 +22,6 @@ ALL_CFLAGS := $(NO_PIE_CFLAGS) -Os -g \
|
|||||||
-Wall -Wformat-security -Wextra \
|
-Wall -Wformat-security -Wextra \
|
||||||
-Wno-array-bounds
|
-Wno-array-bounds
|
||||||
|
|
||||||
FILES := stage3a.bin stage3b.bin stage3b_reloc.bin
|
|
||||||
|
|
||||||
ZIPL_SRCS_C := libc.c ebcdic.c ebcdic_conv.c sclp.c
|
ZIPL_SRCS_C := libc.c ebcdic.c ebcdic_conv.c sclp.c
|
||||||
ZIPL_SRCS_ASM := entry.S
|
ZIPL_SRCS_ASM := entry.S
|
||||||
|
|
||||||
@@ -27,9 +29,6 @@ ZIPL_OBJS_C := $(ZIPL_SRCS_C:%.c=%.o)
|
|||||||
ZIPL_OBJS_ASM := $(ZIPL_SRCS_ASM:%.S=%.o)
|
ZIPL_OBJS_ASM := $(ZIPL_SRCS_ASM:%.S=%.o)
|
||||||
ZIPL_OBJS := $(ZIPL_OBJS_C) $(ZIPL_OBJS_ASM)
|
ZIPL_OBJS := $(ZIPL_OBJS_C) $(ZIPL_OBJS_ASM)
|
||||||
|
|
||||||
|
|
||||||
all: $(FILES)
|
|
||||||
|
|
||||||
# Prevent make from using some default rules...
|
# Prevent make from using some default rules...
|
||||||
%: %.S
|
%: %.S
|
||||||
|
|
||||||
@@ -80,6 +79,26 @@ stage3b.elf: head.o $(ZIPL_OBJS)
|
|||||||
$(OBJCOPY) -O binary $< $@
|
$(OBJCOPY) -O binary $< $@
|
||||||
@chmod a-x $@
|
@chmod a-x $@
|
||||||
|
|
||||||
|
install: stage3a.bin stage3b_reloc.bin
|
||||||
|
$(INSTALL) -d -m 755 "$(PKGDATADIR)"
|
||||||
|
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 stage3a.bin "$(PKGDATADIR)"
|
||||||
|
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 stage3b_reloc.bin "$(PKGDATADIR)"
|
||||||
|
|
||||||
|
else
|
||||||
|
# Don't generate the dependency files (see `common.mak` for the
|
||||||
|
# `-include $(dependencies_c)` statement).
|
||||||
|
.PHONY: $(dependencies_c)
|
||||||
|
|
||||||
|
$(FILES):
|
||||||
|
echo " SKIP $@ due to HOST_ARCH != s390x"
|
||||||
|
|
||||||
|
install:
|
||||||
|
echo " SKIP Bootloader installation due to HOST_ARCH != s390x"
|
||||||
|
endif
|
||||||
|
|
||||||
|
.DEFAULT_GOAL := all
|
||||||
|
all: $(FILES)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o *.elf *.bin *.map .*.d *.lds
|
rm -f *.o *.elf *.bin *.map .*.d *.lds
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
#include "stage3a.h"
|
#include "stage3a.h"
|
||||||
|
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
#include "boot/s390.h"
|
|
||||||
#include "boot/ipl.h"
|
#include "boot/ipl.h"
|
||||||
#include "sclp.h"
|
#include "sclp.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
#include "stage3b.h"
|
#include "stage3b.h"
|
||||||
|
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
#include "boot/s390.h"
|
#include "boot/psw.h"
|
||||||
#include "boot/linux_layout.h"
|
#include "boot/linux_layout.h"
|
||||||
#include "boot/loaders_layout.h"
|
#include "boot/loaders_layout.h"
|
||||||
#include "sclp.h"
|
#include "sclp.h"
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "boot/s390.h"
|
#include "boot/psw.h"
|
||||||
|
|
||||||
/* Must not have any padding included */
|
/* Must not have any padding included */
|
||||||
struct memblob {
|
struct memblob {
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
|
|
||||||
#include "boot/linux_layout.h"
|
#include "boot/linux_layout.h"
|
||||||
#include "boot/s390.h"
|
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
|
|
||||||
static const gchar tool_name[] = "genprotimg";
|
static const gchar tool_name[] = "genprotimg";
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
|
|
||||||
#include "boot/s390.h"
|
#include "boot/psw.h"
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
#include "utils/crypto.h"
|
#include "utils/crypto.h"
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "boot/s390.h"
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "utils/align.h"
|
#include "utils/align.h"
|
||||||
#include "utils/buffer.h"
|
#include "utils/buffer.h"
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "boot/s390.h"
|
#include "boot/psw.h"
|
||||||
#include "boot/stage3b.h"
|
#include "boot/stage3b.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "utils/align.h"
|
#include "utils/align.h"
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "boot/s390.h"
|
#include "boot/psw.h"
|
||||||
#include "boot/stage3b.h"
|
#include "boot/stage3b.h"
|
||||||
#include "utils/buffer.h"
|
#include "utils/buffer.h"
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "boot/s390.h"
|
#include "boot/psw.h"
|
||||||
#include "include/pv_crypto_def.h"
|
#include "include/pv_crypto_def.h"
|
||||||
#include "utils/buffer.h"
|
#include "utils/buffer.h"
|
||||||
#include "utils/crypto.h"
|
#include "utils/crypto.h"
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "boot/s390.h"
|
|
||||||
#include "include/pv_hdr_def.h"
|
#include "include/pv_hdr_def.h"
|
||||||
#include "utils/crypto.h"
|
#include "utils/crypto.h"
|
||||||
#include "utils/buffer.h"
|
#include "utils/buffer.h"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "boot/s390.h"
|
#include "boot/psw.h"
|
||||||
#include "boot/stage3a.h"
|
#include "boot/stage3a.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "include/pv_crypto_def.h"
|
#include "include/pv_crypto_def.h"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "boot/s390.h"
|
#include "boot/psw.h"
|
||||||
#include "utils/buffer.h"
|
#include "utils/buffer.h"
|
||||||
|
|
||||||
#include "pv_args.h"
|
#include "pv_args.h"
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "boot/ipl.h"
|
#include "boot/ipl.h"
|
||||||
#include "boot/s390.h"
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "include/pv_hdr_def.h"
|
#include "include/pv_hdr_def.h"
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "boot/ipl.h"
|
#include "boot/ipl.h"
|
||||||
#include "boot/s390.h"
|
|
||||||
#include "boot/stage3b.h"
|
#include "boot/stage3b.h"
|
||||||
#include "utils/buffer.h"
|
#include "utils/buffer.h"
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,8 @@
|
|||||||
#ifndef PV_UTILS_ALIGN_H
|
#ifndef PV_UTILS_ALIGN_H
|
||||||
#define PV_UTILS_ALIGN_H
|
#define PV_UTILS_ALIGN_H
|
||||||
|
|
||||||
#include "boot/s390.h"
|
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
|
#include "boot/page.h"
|
||||||
|
|
||||||
#define IS_ALIGNED(addr, size) (!(addr & (size - 1)))
|
#define IS_ALIGNED(addr, size) (!(addr & (size - 1)))
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "boot/s390.h"
|
#include "boot/page.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "include/pv_crypto_def.h"
|
#include "include/pv_crypto_def.h"
|
||||||
#include "pv/pv_error.h"
|
#include "pv/pv_error.h"
|
||||||
|
|||||||
@@ -195,15 +195,25 @@ struct boot_info_bp_dump {
|
|||||||
uint8_t unused[16];
|
uint8_t unused[16];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
/* This represents on-disk pointer to a block on disk */
|
||||||
|
union disk_blockptr {
|
||||||
|
struct eckd_blockptr_legacy eckd_legacy;
|
||||||
|
struct eckd_blockptr eckd;
|
||||||
|
struct linear_blockptr linear;
|
||||||
|
};
|
||||||
|
|
||||||
struct boot_info_bp_ipl {
|
struct boot_info_bp_ipl {
|
||||||
union {
|
union disk_blockptr bm_ptr;
|
||||||
struct eckd_blockptr_legacy eckd_legacy;
|
|
||||||
struct eckd_blockptr eckd;
|
|
||||||
struct linear_blockptr lin;
|
|
||||||
} bm_ptr;
|
|
||||||
uint8_t unused[16];
|
uint8_t unused[16];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
struct disk_program_table {
|
||||||
|
uint32_t magic;
|
||||||
|
uint32_t version;
|
||||||
|
uint64_t unused;
|
||||||
|
union disk_blockptr component_table[0];
|
||||||
|
} __packed;
|
||||||
|
|
||||||
struct boot_info {
|
struct boot_info {
|
||||||
char magic[4];
|
char magic[4];
|
||||||
uint8_t version;
|
uint8_t version;
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@
|
|||||||
#define IPL_H
|
#define IPL_H
|
||||||
|
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
#include "s390.h"
|
#include "page.h"
|
||||||
|
|
||||||
#define IPL_FLAG_SECURE 0x40
|
#define IPL_FLAG_SECURE 0x40
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Page related definitions and functions.
|
||||||
|
*
|
||||||
|
* Copyright IBM Corp. 2023
|
||||||
|
*
|
||||||
|
* 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 BOOT_PAGE_H
|
||||||
|
#define BOOT_PAGE_H
|
||||||
|
#include "lib/zt_common.h"
|
||||||
|
|
||||||
|
#define PAGE_SIZE _AC(4096, UL)
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Program Status Word related definitions and functions.
|
||||||
|
*
|
||||||
|
* Copyright IBM Corp. 2023
|
||||||
|
*
|
||||||
|
* 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 BOOT_PSW_H
|
||||||
|
#define BOOT_PSW_H
|
||||||
|
|
||||||
|
#include "lib/zt_common.h"
|
||||||
|
|
||||||
|
#define PSW32_ADDR_MASK _AC(0x000000007fffffff, UL)
|
||||||
|
#define PSW_MASK_BA _AC(0x0000000080000000, UL)
|
||||||
|
#define PSW_MASK_EA _AC(0x0000000100000000, UL)
|
||||||
|
#define PSW_MASK_BIT_12 _AC(0x0008000000000000, UL)
|
||||||
|
#define PSW_LOAD _AC(0x0008000080000000, UL)
|
||||||
|
#define PSW_DISABLED_WAIT _AC(0x000a000000000000, UL)
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLER__
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct psw_t {
|
||||||
|
uint64_t mask;
|
||||||
|
uint64_t addr;
|
||||||
|
} __aligned(8);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
+5
-23
@@ -1,7 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* s390 related definitions and functions.
|
* s390 related definitions and functions.
|
||||||
|
* Should only be used for code targeting s390 (bootloader code)
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2013, 2020
|
* Copyright IBM Corp. 2013, 2023
|
||||||
*
|
*
|
||||||
* s390-tools is free software; you can redistribute it and/or modify
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -12,29 +13,22 @@
|
|||||||
|
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
#include "boot/sigp.h"
|
#include "boot/sigp.h"
|
||||||
|
#include "boot/psw.h"
|
||||||
|
#include "boot/page.h"
|
||||||
|
|
||||||
#define __LC_IPLDEV 0x0c6c
|
#define __LC_IPLDEV 0x0c6c
|
||||||
#define __LC_OS_INFO 0x0e18
|
#define __LC_OS_INFO 0x0e18
|
||||||
|
|
||||||
#define LOWCORE_SIZE _AC(0x2000, UL)
|
#define LOWCORE_SIZE _AC(0x2000, UL)
|
||||||
|
|
||||||
#define PAGE_SIZE _AC(4096, UL)
|
|
||||||
|
|
||||||
/* Minimum size of a stack frame in bytes */
|
/* Minimum size of a stack frame in bytes */
|
||||||
#define STACK_FRAME_OVERHEAD _AC(160, U)
|
#define STACK_FRAME_OVERHEAD _AC(160, U)
|
||||||
|
|
||||||
/* Facilities */
|
/* Facilities */
|
||||||
#define UNPACK_FACILITY _AC(161, U)
|
#define UNPACK_FACILITY _AC(161, U)
|
||||||
|
|
||||||
#define PSW32_ADDR_MASK _AC(0x000000007fffffff, UL)
|
|
||||||
#define PSW_MASK_BA _AC(0x0000000080000000, UL)
|
|
||||||
#define PSW_MASK_EA _AC(0x0000000100000000, UL)
|
|
||||||
#define PSW_MASK_BIT_12 _AC(0x0008000000000000, UL)
|
|
||||||
#define PSW_LOAD _AC(0x0008000080000000, UL)
|
|
||||||
#define PSW_DISABLED_WAIT _AC(0x000a000000000000, UL)
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLER__
|
#ifndef __ASSEMBLER__
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper macro for exception table entries
|
* Helper macro for exception table entries
|
||||||
@@ -46,18 +40,6 @@
|
|||||||
".long (" #_target ")\n" \
|
".long (" #_target ")\n" \
|
||||||
".previous\n"
|
".previous\n"
|
||||||
|
|
||||||
struct psw_t {
|
|
||||||
uint64_t mask;
|
|
||||||
uint64_t addr;
|
|
||||||
} __aligned(8);
|
|
||||||
|
|
||||||
struct psw32_t {
|
|
||||||
uint32_t mask;
|
|
||||||
uint32_t addr;
|
|
||||||
} __aligned(8);
|
|
||||||
|
|
||||||
void load_wait_psw(uint64_t, struct psw_t *);
|
|
||||||
|
|
||||||
struct subchannel_id {
|
struct subchannel_id {
|
||||||
uint32_t cssid:8;
|
uint32_t cssid:8;
|
||||||
uint32_t:4;
|
uint32_t:4;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
|
|
||||||
#include "boot/s390.h"
|
#include "boot/psw.h"
|
||||||
#include "libpv/crypto.h"
|
#include "libpv/crypto.h"
|
||||||
#include "libpv/macros.h"
|
#include "libpv/macros.h"
|
||||||
|
|
||||||
|
|||||||
+50
-22
@@ -1,10 +1,16 @@
|
|||||||
.\" chzcrypt.8
|
.\" chzcrypt.8
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright 2020 IBM Corp.
|
.\" Copyright 2020, 2023 IBM Corp.
|
||||||
.\" s390-tools is free software; you can redistribute it and/or modify
|
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||||
.\"
|
.\"
|
||||||
.TH CHZCRYPT 8 "OCT 2020" "s390-tools"
|
.\" use
|
||||||
|
.\" groff -man -Tutf8 chzcrypt.8
|
||||||
|
.\" or
|
||||||
|
.\" nroff -man chzcrypt.8
|
||||||
|
.\" to process this source
|
||||||
|
.\"
|
||||||
|
.TH CHZCRYPT 8 "MAY 2023" "s390-tools"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
chzcrypt \- modify zcrypt configuration
|
chzcrypt \- modify zcrypt configuration
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -46,8 +52,8 @@ chzcrypt \- modify zcrypt configuration
|
|||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
.B chzcrypt
|
.B chzcrypt
|
||||||
command is used to configure cryptographic devices managed by zcrypt and
|
command is used to configure cryptographic devices managed by zcrypt
|
||||||
modify zcrypt's AP bus attributes.
|
and modify zcrypt's AP bus attributes.
|
||||||
|
|
||||||
Attributes may vary depending on the kernel
|
Attributes may vary depending on the kernel
|
||||||
version.
|
version.
|
||||||
@@ -70,19 +76,6 @@ Set the given cryptographic card device(s) config on ('configured').
|
|||||||
.B --config-off
|
.B --config-off
|
||||||
Set the given cryptographic card device(s) config off ('deconfigured').
|
Set the given cryptographic card device(s) config off ('deconfigured').
|
||||||
.TP 8
|
.TP 8
|
||||||
.B <device id>
|
|
||||||
Specifies a cryptographic device which will be set either online or
|
|
||||||
offline or configured on or off. For online and offline the device can
|
|
||||||
either be a card device or a queue device. A queue device can only get
|
|
||||||
switched online when the providing card is online.
|
|
||||||
.br
|
|
||||||
For config on/off the device needs to be a card device. A card or
|
|
||||||
queue device cannot get switched online if the card is in deconfigured
|
|
||||||
state.
|
|
||||||
.br
|
|
||||||
Please note that the card device and queue device representation are both
|
|
||||||
in hexadecimal notation.
|
|
||||||
.TP 8
|
|
||||||
.B -p, --poll-thread-enable
|
.B -p, --poll-thread-enable
|
||||||
Enable zcrypt's poll thread.
|
Enable zcrypt's poll thread.
|
||||||
.TP 8
|
.TP 8
|
||||||
@@ -94,15 +87,28 @@ Set configuration timer for re-scanning the AP bus to
|
|||||||
.I <timeout>
|
.I <timeout>
|
||||||
seconds.
|
seconds.
|
||||||
.TP 8
|
.TP 8
|
||||||
|
.B --se-associate <association-index> <queue-device>
|
||||||
|
Associate the given queue device with the given association
|
||||||
|
index. This command is only valid within an Secure Execution guest
|
||||||
|
with AP pass-through support enabled.
|
||||||
|
.TP 8
|
||||||
|
.B --se-bind <queue-device>
|
||||||
|
Bind the given queue device. This command is only valid within an
|
||||||
|
Secure Execution guest with AP pass-through support enabled.
|
||||||
|
.TP 8
|
||||||
|
.B --se-unbind <queue-device>
|
||||||
|
Unbind the given queue device. This command is only valid within an
|
||||||
|
Secure Execution guest with AP pass-through support enabled.
|
||||||
|
.TP 8
|
||||||
.BI "-t, --poll-timeout" " <poll_timeout>"
|
.BI "-t, --poll-timeout" " <poll_timeout>"
|
||||||
Set poll timer to run poll tasklet all
|
Set poll timer to run poll tasklet all
|
||||||
.I <poll_timeout>
|
.I <poll_timeout>
|
||||||
nanoseconds.
|
nanoseconds.
|
||||||
.TP 8
|
.TP 8
|
||||||
.BI "-q, --default-domain" " <domain>"
|
.BI "-q, --default-domain" " <domain>"
|
||||||
Set the new default domain of the AP bus to <domain>.
|
Set the new default domain of the AP bus to <domain>. The number of
|
||||||
The number of available domains can be retrieved with the lszcrypt
|
available domains can be retrieved with the lszcrypt command ('-d'
|
||||||
command ('-d' option).
|
option).
|
||||||
.TP 8
|
.TP 8
|
||||||
.B -V, --verbose
|
.B -V, --verbose
|
||||||
Print verbose messages.
|
Print verbose messages.
|
||||||
@@ -112,6 +118,22 @@ Print help text and exit.
|
|||||||
.TP 8
|
.TP 8
|
||||||
.B -v, --version
|
.B -v, --version
|
||||||
Print version information and exit.
|
Print version information and exit.
|
||||||
|
.TP 8
|
||||||
|
.B <device id>
|
||||||
|
Specifies a cryptographic device which will be set either online or
|
||||||
|
offline or configured on or off. For online and offline the device can
|
||||||
|
either be a card device or a queue device. A queue device can only get
|
||||||
|
switched online when the providing card is online.
|
||||||
|
.br
|
||||||
|
For config on/off the device needs to be a card device. A card or
|
||||||
|
queue device cannot get switched online if the card is in deconfigured
|
||||||
|
state.
|
||||||
|
.br
|
||||||
|
Please note that the card device and queue device representation are
|
||||||
|
both in hexadecimal notation.
|
||||||
|
.TP 8
|
||||||
|
.B <queue-device>
|
||||||
|
An APQN queue device given as xy.abcd as it is listed by lszcrypt -V.
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
.TP
|
.TP
|
||||||
.B chzcrypt -e 0 1 12
|
.B chzcrypt -e 0 1 12
|
||||||
@@ -131,8 +153,8 @@ Set all available crypto cards to config on, be verbose.
|
|||||||
Switch the two crypto cards 1 and 3 to deconfigured, be verbose.
|
Switch the two crypto cards 1 and 3 to deconfigured, be verbose.
|
||||||
.TP
|
.TP
|
||||||
.B chzcrypt -c 60 -n
|
.B chzcrypt -c 60 -n
|
||||||
Will set configuration timer for re-scanning the AP bus to 60 seconds and
|
Will set configuration timer for re-scanning the AP bus to 60 seconds
|
||||||
disable zcrypt's poll thread.
|
and disable zcrypt's poll thread.
|
||||||
.TP
|
.TP
|
||||||
.B chzcrypt -q 67
|
.B chzcrypt -q 67
|
||||||
Will set the default domain to 67.
|
Will set the default domain to 67.
|
||||||
@@ -144,5 +166,11 @@ chzcrypt exits with an appropriate message. Even more config on/off
|
|||||||
may require support from a hypervisor like KVM or zVM and may fail if
|
may require support from a hypervisor like KVM or zVM and may fail if
|
||||||
the Linux kernel is unable to perform the SCLP command. Check syslog
|
the Linux kernel is unable to perform the SCLP command. Check syslog
|
||||||
on failure.
|
on failure.
|
||||||
|
.TP
|
||||||
|
Bind, associate and unbind command on an queue device are only
|
||||||
|
available and valid within an Secure Execution environment with AP
|
||||||
|
pass-through enabled and a Linux kernel providing the low level sysfs
|
||||||
|
API. If these conditions are not fulfilled, the command will fail with
|
||||||
|
an appropriate error messages.
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
\fBlszcrypt\fR(8)
|
\fBlszcrypt\fR(8)
|
||||||
|
|||||||
+260
-18
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* chzcrypt - Tool to modify zcrypt configuration
|
* chzcrypt - Tool to modify zcrypt configuration
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2008, 2020
|
* Copyright IBM Corp. 2008, 2023
|
||||||
*
|
*
|
||||||
* s390-tools is free software; you can redistribute it and/or modify
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -28,6 +28,12 @@
|
|||||||
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
|
||||||
|
/* max seconds the se-association command will wait for completion */
|
||||||
|
#define MAX_ASSOC_POLL_TIME_IN_S 30
|
||||||
|
|
||||||
|
/* max seconds the se-unbind command will wait for unbind complete */
|
||||||
|
#define MAX_UNBIND_POLL_TIME_IN_S 30
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Private data
|
* Private data
|
||||||
*/
|
*/
|
||||||
@@ -45,7 +51,7 @@ static const struct util_prg prg = {
|
|||||||
{
|
{
|
||||||
.owner = "IBM Corp.",
|
.owner = "IBM Corp.",
|
||||||
.pub_first = 2008,
|
.pub_first = 2008,
|
||||||
.pub_last = 2020,
|
.pub_last = 2023,
|
||||||
},
|
},
|
||||||
UTIL_PRG_COPYRIGHT_END
|
UTIL_PRG_COPYRIGHT_END
|
||||||
}
|
}
|
||||||
@@ -57,6 +63,9 @@ static const struct util_prg prg = {
|
|||||||
|
|
||||||
#define OPT_CONFIG_ON 0x80
|
#define OPT_CONFIG_ON 0x80
|
||||||
#define OPT_CONFIG_OFF 0x81
|
#define OPT_CONFIG_OFF 0x81
|
||||||
|
#define OPT_SE_ASSOC 0x82
|
||||||
|
#define OPT_SE_BIND 0x83
|
||||||
|
#define OPT_SE_UNBIND 0x84
|
||||||
|
|
||||||
static struct util_opt opt_vec[] = {
|
static struct util_opt opt_vec[] = {
|
||||||
{
|
{
|
||||||
@@ -116,6 +125,22 @@ static struct util_opt opt_vec[] = {
|
|||||||
.option = { "verbose", no_argument, NULL, 'V'},
|
.option = { "verbose", no_argument, NULL, 'V'},
|
||||||
.desc = "Print verbose messages",
|
.desc = "Print verbose messages",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.option = { "se-associate", required_argument, NULL, OPT_SE_ASSOC},
|
||||||
|
.argument = "assoc_idx",
|
||||||
|
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||||
|
.desc = "SE guest with AP support only: Associate the given queue device",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.option = { "se-bind", no_argument, NULL, OPT_SE_BIND},
|
||||||
|
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||||
|
.desc = "SE guest with AP support only: Bind the given queue device",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.option = { "se-unbind", no_argument, NULL, OPT_SE_UNBIND},
|
||||||
|
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||||
|
.desc = "SE guest with AP support only: Unbind the given queue device",
|
||||||
|
},
|
||||||
UTIL_OPT_HELP,
|
UTIL_OPT_HELP,
|
||||||
UTIL_OPT_VERSION,
|
UTIL_OPT_VERSION,
|
||||||
UTIL_OPT_END
|
UTIL_OPT_END
|
||||||
@@ -336,6 +361,186 @@ next:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void se_assoc(const char *assoc_idx, const char *dev)
|
||||||
|
{
|
||||||
|
int i, idx, rc, ap, dom, loop;
|
||||||
|
char *dev_path, *attr;
|
||||||
|
char buf[256];
|
||||||
|
|
||||||
|
if (!ap_bus_has_SB_support())
|
||||||
|
errx(EXIT_FAILURE, "Error - AP bus: SE bind support is not available.");
|
||||||
|
|
||||||
|
if (sscanf(dev, "%02x.%04x", &ap, &dom) != 2)
|
||||||
|
errx(EXIT_FAILURE, "Error - Can't parse queue device '%s' as xy.abcd.",
|
||||||
|
dev);
|
||||||
|
dev_path = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x",
|
||||||
|
ap, ap, dom);
|
||||||
|
if (!util_path_is_dir(dev_path))
|
||||||
|
errx(EXIT_FAILURE, "Error - Queue device %s does not exist.",
|
||||||
|
dev);
|
||||||
|
|
||||||
|
if (sscanf(assoc_idx, "%i", &idx) != 1)
|
||||||
|
errx(EXIT_FAILURE, "Error - Can't parse association index '%s' as number.",
|
||||||
|
assoc_idx);
|
||||||
|
if (idx < 0 || idx > 0xFFFF)
|
||||||
|
errx(EXIT_FAILURE, "Error - Association index needs to be in range [0...%d].",
|
||||||
|
0xffff);
|
||||||
|
|
||||||
|
attr = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x/se_associate",
|
||||||
|
ap, ap, dom);
|
||||||
|
if (!util_path_is_writable(attr))
|
||||||
|
errx(EXIT_FAILURE, "Error - Can't write to %s (errno '%s').",
|
||||||
|
attr, strerror(errno));
|
||||||
|
|
||||||
|
/* read se_associate attribute and check for 'unassociated' */
|
||||||
|
rc = util_file_read_line(buf, sizeof(buf), attr);
|
||||||
|
if (rc)
|
||||||
|
errx(EXIT_FAILURE, "Error - Failure reading from %s (errno '%s').",
|
||||||
|
attr, strerror(errno));
|
||||||
|
if (strcmp(buf, "unassociated"))
|
||||||
|
errx(EXIT_FAILURE,
|
||||||
|
"Error - Queue device %s is NOT in 'unassociated' state (state '%s' found).",
|
||||||
|
dev, buf);
|
||||||
|
|
||||||
|
/* write assocition index to the se_associate attribute */
|
||||||
|
rc = util_file_write_l(idx, 10, attr);
|
||||||
|
if (rc)
|
||||||
|
errx(EXIT_FAILURE, "Error - Failure writing to %s (errno '%s').",
|
||||||
|
attr, strerror(errno));
|
||||||
|
|
||||||
|
/* loop up to MAX_ASSOC_POLL_TIME_IN_S seconds for completion */
|
||||||
|
for (loop = 0; loop < 2 * MAX_ASSOC_POLL_TIME_IN_S; usleep(500000), loop++) {
|
||||||
|
rc = util_file_read_line(buf, sizeof(buf), attr);
|
||||||
|
if (rc)
|
||||||
|
errx(EXIT_FAILURE, "Error - Failure reading from %s (errno '%s').",
|
||||||
|
attr, strerror(errno));
|
||||||
|
if (!strncmp(buf, "associated", strlen("associated")))
|
||||||
|
break;
|
||||||
|
if (!strcmp(buf, "unassociated"))
|
||||||
|
errx(EXIT_FAILURE,
|
||||||
|
"Error - Failure associating queue device %s (state '%s' found).",
|
||||||
|
dev, buf);
|
||||||
|
}
|
||||||
|
if (loop >= 2 * MAX_ASSOC_POLL_TIME_IN_S)
|
||||||
|
errx(EXIT_FAILURE,
|
||||||
|
"Error - Failure associating queue device %s (timeout after %d s).",
|
||||||
|
dev, MAX_ASSOC_POLL_TIME_IN_S);
|
||||||
|
|
||||||
|
if (sscanf(buf, "associated %d", &i) != 1 || idx != i)
|
||||||
|
errx(EXIT_FAILURE,
|
||||||
|
"Error - Failure associating queue device %s (state '%s' found).",
|
||||||
|
dev, buf);
|
||||||
|
|
||||||
|
verbose("Queue device %s successful associated with index %d.\n",
|
||||||
|
dev, idx);
|
||||||
|
|
||||||
|
free(dev_path);
|
||||||
|
free(attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void se_bind(const char *dev)
|
||||||
|
{
|
||||||
|
char *dev_path, *attr;
|
||||||
|
int rc, ap, dom;
|
||||||
|
char buf[256];
|
||||||
|
|
||||||
|
if (!ap_bus_has_SB_support())
|
||||||
|
errx(EXIT_FAILURE, "Error - AP bus: SE bind support is not available.");
|
||||||
|
|
||||||
|
if (sscanf(dev, "%02x.%04x", &ap, &dom) != 2)
|
||||||
|
errx(EXIT_FAILURE, "Error - Can't parse queue device '%s' as xy.abcd.",
|
||||||
|
dev);
|
||||||
|
dev_path = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x",
|
||||||
|
ap, ap, dom);
|
||||||
|
if (!util_path_is_dir(dev_path))
|
||||||
|
errx(EXIT_FAILURE, "Error - Queue device %s does not exist.",
|
||||||
|
dev);
|
||||||
|
|
||||||
|
attr = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x/se_bind",
|
||||||
|
ap, ap, dom);
|
||||||
|
if (!util_path_is_writable(attr))
|
||||||
|
errx(EXIT_FAILURE, "Error - Can't write to %s (errno '%s').",
|
||||||
|
attr, strerror(errno));
|
||||||
|
|
||||||
|
/* read se_bind attribute and check for 'unboud' */
|
||||||
|
rc = util_file_read_line(buf, sizeof(buf), attr);
|
||||||
|
if (rc)
|
||||||
|
errx(EXIT_FAILURE, "Error - Failure reading from %s (errno '%s').",
|
||||||
|
attr, strerror(errno));
|
||||||
|
if (strcmp(buf, "unbound"))
|
||||||
|
errx(EXIT_FAILURE,
|
||||||
|
"Error - Queue device %s is NOT in 'unbound' state (state '%s' found).",
|
||||||
|
dev, buf);
|
||||||
|
|
||||||
|
/* write se_bind attribute, check for 'bound' afterwards */
|
||||||
|
rc = util_file_write_l(1, 10, attr);
|
||||||
|
if (rc)
|
||||||
|
errx(EXIT_FAILURE, "Error - Failure writing to %s (errno '%s').",
|
||||||
|
attr, strerror(errno));
|
||||||
|
rc = util_file_read_line(buf, sizeof(buf), attr);
|
||||||
|
if (rc)
|
||||||
|
errx(EXIT_FAILURE, "Error - Failure reading from %s (errno '%s').",
|
||||||
|
attr, strerror(errno));
|
||||||
|
if (strcmp(buf, "bound"))
|
||||||
|
errx(EXIT_FAILURE, "Error - Failure binding queue device %s (state '%s' found).",
|
||||||
|
dev, buf);
|
||||||
|
|
||||||
|
verbose("Queue device %s successful bound.\n", dev);
|
||||||
|
|
||||||
|
free(dev_path);
|
||||||
|
free(attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void se_unbind(const char *dev)
|
||||||
|
{
|
||||||
|
int rc, ap, dom, loop;
|
||||||
|
char *dev_path, *attr;
|
||||||
|
char buf[256];
|
||||||
|
|
||||||
|
if (!ap_bus_has_SB_support())
|
||||||
|
errx(EXIT_FAILURE, "Error - AP bus: SE bind support is not available.");
|
||||||
|
|
||||||
|
if (sscanf(dev, "%02x.%04x", &ap, &dom) != 2)
|
||||||
|
errx(EXIT_FAILURE, "Error - Can't parse queue device '%s' as xy.abcd.",
|
||||||
|
dev);
|
||||||
|
dev_path = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x",
|
||||||
|
ap, ap, dom);
|
||||||
|
if (!util_path_is_dir(dev_path))
|
||||||
|
errx(EXIT_FAILURE, "Error - Queue device %s does not exist.",
|
||||||
|
dev);
|
||||||
|
|
||||||
|
attr = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x/se_bind",
|
||||||
|
ap, ap, dom);
|
||||||
|
if (!util_path_is_writable(attr))
|
||||||
|
errx(EXIT_FAILURE, "Error - Can't write to %s (errno '%s').",
|
||||||
|
attr, strerror(errno));
|
||||||
|
|
||||||
|
/* write se_bind attribute */
|
||||||
|
rc = util_file_write_l(0, 10, attr);
|
||||||
|
if (rc)
|
||||||
|
errx(EXIT_FAILURE, "Error - Failure writing to %s (errno '%s').",
|
||||||
|
attr, strerror(errno));
|
||||||
|
|
||||||
|
/* loop up to MAX_UNBIND_POLL_TIME_IN_S seconds for completion */
|
||||||
|
for (loop = 0; loop < 2 * MAX_UNBIND_POLL_TIME_IN_S; usleep(500000), loop++) {
|
||||||
|
rc = util_file_read_line(buf, sizeof(buf), attr);
|
||||||
|
if (rc)
|
||||||
|
errx(EXIT_FAILURE, "Error - Failure reading from %s (errno '%s').",
|
||||||
|
attr, strerror(errno));
|
||||||
|
if (!strcmp(buf, "unbound"))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (loop >= 2 * MAX_UNBIND_POLL_TIME_IN_S)
|
||||||
|
errx(EXIT_FAILURE,
|
||||||
|
"Error - Failure unbinding queue device %s (timeout after %d s).",
|
||||||
|
dev, MAX_UNBIND_POLL_TIME_IN_S);
|
||||||
|
|
||||||
|
verbose("Queue device %s successful unbound.\n", dev);
|
||||||
|
|
||||||
|
free(dev_path);
|
||||||
|
free(attr);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print invalid commandline error message and then exit with error code
|
* Print invalid commandline error message and then exit with error code
|
||||||
*/
|
*/
|
||||||
@@ -389,10 +594,10 @@ static void print_adapter_id_help(void)
|
|||||||
printf("DEVICE_IDS\n");
|
printf("DEVICE_IDS\n");
|
||||||
printf(" List of cryptographic device ids separated by blanks which will be set\n");
|
printf(" List of cryptographic device ids separated by blanks which will be set\n");
|
||||||
printf(" online/offline. Must be used in conjunction with the enable or disable option.\n");
|
printf(" online/offline. Must be used in conjunction with the enable or disable option.\n");
|
||||||
|
|
||||||
printf(" DEVICE_ID could either be card device id ('<card-id>') or queue device id\n");
|
printf(" DEVICE_ID could either be card device id ('<card-id>') or queue device id\n");
|
||||||
printf(" '<card-id>.<domain-id>').\n");
|
printf(" '<card-id>.<domain-id>').\n\n");
|
||||||
printf(" \n");
|
printf("QUEUE_DEVICE:\n");
|
||||||
|
printf(" An APQN queue device given as xy.abcd as it is listed by lszcrypt -V.\n\n");
|
||||||
printf("EXAMPLE:\n");
|
printf("EXAMPLE:\n");
|
||||||
printf(" Disable the cryptographic device with card id '02' (inclusive all queues).\n");
|
printf(" Disable the cryptographic device with card id '02' (inclusive all queues).\n");
|
||||||
printf(" #>chzcrypt -d 02\n");
|
printf(" #>chzcrypt -d 02\n");
|
||||||
@@ -407,13 +612,14 @@ static void print_adapter_id_help(void)
|
|||||||
*/
|
*/
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
const char *default_domain = NULL, *config = NULL, *config_text = NULL;
|
||||||
const char *online = NULL, *online_text = NULL, *poll_thread = NULL;
|
const char *online = NULL, *online_text = NULL, *poll_thread = NULL;
|
||||||
const char *config_time = NULL, *poll_timeout = NULL;
|
const char *config_time = NULL, *poll_timeout = NULL;
|
||||||
const char *default_domain = NULL, *config = NULL, *config_text = NULL;
|
const char *queue_device = NULL, *assoc_idx = NULL;
|
||||||
|
int c, i, j, action = 0;
|
||||||
char *path, *dev_list;
|
char *path, *dev_list;
|
||||||
bool all = false, actionset = false;
|
bool all = false;
|
||||||
size_t len;
|
size_t len;
|
||||||
int c, i, j;
|
|
||||||
|
|
||||||
for (i=0; i < argc; i++)
|
for (i=0; i < argc; i++)
|
||||||
for (j=2; j < (int) strlen(argv[i]); j++)
|
for (j=2; j < (int) strlen(argv[i]); j++)
|
||||||
@@ -428,12 +634,12 @@ int main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'e':
|
case 'e':
|
||||||
actionset = true;
|
action = c;
|
||||||
online = "1";
|
online = "1";
|
||||||
online_text = "online";
|
online_text = "online";
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
actionset = true;
|
action = c;
|
||||||
online = "0";
|
online = "0";
|
||||||
online_text = "offline";
|
online_text = "offline";
|
||||||
break;
|
break;
|
||||||
@@ -441,23 +647,23 @@ int main(int argc, char *argv[])
|
|||||||
all = true;
|
all = true;
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
actionset = true;
|
action = c;
|
||||||
poll_thread = "1";
|
poll_thread = "1";
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
actionset = true;
|
action = c;
|
||||||
poll_thread = "0";
|
poll_thread = "0";
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
actionset = true;
|
action = c;
|
||||||
config_time = optarg;
|
config_time = optarg;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
actionset = true;
|
action = c;
|
||||||
poll_timeout = optarg;
|
poll_timeout = optarg;
|
||||||
break;
|
break;
|
||||||
case 'q':
|
case 'q':
|
||||||
actionset = true;
|
action = c;
|
||||||
default_domain = optarg;
|
default_domain = optarg;
|
||||||
break;
|
break;
|
||||||
case 'V':
|
case 'V':
|
||||||
@@ -472,21 +678,31 @@ int main(int argc, char *argv[])
|
|||||||
util_prg_print_version();
|
util_prg_print_version();
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
case OPT_CONFIG_ON:
|
case OPT_CONFIG_ON:
|
||||||
actionset = true;
|
action = c;
|
||||||
config = "1";
|
config = "1";
|
||||||
config_text = "config on";
|
config_text = "config on";
|
||||||
break;
|
break;
|
||||||
case OPT_CONFIG_OFF:
|
case OPT_CONFIG_OFF:
|
||||||
actionset = true;
|
action = c;
|
||||||
config = "0";
|
config = "0";
|
||||||
config_text = "config off";
|
config_text = "config off";
|
||||||
break;
|
break;
|
||||||
|
case OPT_SE_ASSOC:
|
||||||
|
action = c;
|
||||||
|
assoc_idx = optarg;
|
||||||
|
break;
|
||||||
|
case OPT_SE_BIND:
|
||||||
|
action = c;
|
||||||
|
break;
|
||||||
|
case OPT_SE_UNBIND:
|
||||||
|
action = c;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
util_opt_print_parse_error(c, argv);
|
util_opt_print_parse_error(c, argv);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!actionset)
|
if (!action)
|
||||||
invalid_cmdline_exit("Error - missing argument.\n");
|
invalid_cmdline_exit("Error - missing argument.\n");
|
||||||
path = util_path_sysfs("bus/ap");
|
path = util_path_sysfs("bus/ap");
|
||||||
if (!util_path_is_dir(path))
|
if (!util_path_is_dir(path))
|
||||||
@@ -508,6 +724,32 @@ int main(int argc, char *argv[])
|
|||||||
default_domain_set(default_domain);
|
default_domain_set(default_domain);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (action == OPT_SE_ASSOC) {
|
||||||
|
if (optind >= argc)
|
||||||
|
errx(EXIT_FAILURE,
|
||||||
|
"Error - The --se-associate needs a queue device given.");
|
||||||
|
queue_device = argv[optind];
|
||||||
|
se_assoc(assoc_idx, queue_device);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
if (action == OPT_SE_BIND) {
|
||||||
|
if (optind >= argc)
|
||||||
|
errx(EXIT_FAILURE,
|
||||||
|
"Error - The --se-bind needs a queue device given.");
|
||||||
|
queue_device = argv[optind];
|
||||||
|
se_bind(queue_device);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
if (action == OPT_SE_UNBIND) {
|
||||||
|
if (optind >= argc)
|
||||||
|
errx(EXIT_FAILURE,
|
||||||
|
"Error - The --se-unbind needs a queue device given.");
|
||||||
|
queue_device = argv[optind];
|
||||||
|
se_unbind(queue_device);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
if (all)
|
if (all)
|
||||||
dev_list_all(&dev_list, &len);
|
dev_list_all(&dev_list, &len);
|
||||||
else
|
else
|
||||||
|
|||||||
+121
-74
@@ -1,6 +1,6 @@
|
|||||||
.\" lszcrypt.8
|
.\" lszcrypt.8
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright IBM Corp. 2019, 2022
|
.\" Copyright IBM Corp. 2019, 2023
|
||||||
.\" s390-tools is free software; you can redistribute it and/or modify
|
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||||
.\"
|
.\"
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
.\" nroff -man lszcrypt.8
|
.\" nroff -man lszcrypt.8
|
||||||
.\" to process this source
|
.\" to process this source
|
||||||
.\"
|
.\"
|
||||||
.TH LSZCRYPT 8 "FEB 2022" "s390-tools"
|
.TH LSZCRYPT 8 "MAY 2023" "s390-tools"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
lszcrypt \- display zcrypt device and configuration information
|
lszcrypt \- display zcrypt device and configuration information
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -24,7 +24,7 @@ lszcrypt \- display zcrypt device and configuration information
|
|||||||
.TP
|
.TP
|
||||||
.B lszcrypt
|
.B lszcrypt
|
||||||
.B -c
|
.B -c
|
||||||
<card-id>
|
<device-id>
|
||||||
.TP
|
.TP
|
||||||
.B lszcrypt -b
|
.B lszcrypt -b
|
||||||
.TP
|
.TP
|
||||||
@@ -41,43 +41,60 @@ lszcrypt \- display zcrypt device and configuration information
|
|||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
.B lszcrypt
|
.B lszcrypt
|
||||||
command is used to display information about cryptographic devices managed by
|
command is used to display information about cryptographic devices
|
||||||
zcrypt and the AP bus attributes of zcrypt. Displayed information depends on the
|
managed by zcrypt and the AP bus attributes of zcrypt. Displayed
|
||||||
kernel version.
|
information depends on the kernel version.
|
||||||
.B lszcrypt
|
.B lszcrypt
|
||||||
requires that sysfs is mounted.
|
requires that sysfs is mounted.
|
||||||
.P
|
.P
|
||||||
The following information can be displayed for each cryptographic
|
The following information can be displayed for each cryptographic
|
||||||
device: card ID, domain ID, card type (symbolic), mode, online status,
|
device: card ID, domain ID, card type (symbolic), mode, online status,
|
||||||
hardware card type (numeric), installed function facilities, card capability,
|
hardware card type (numeric), installed function facilities, card
|
||||||
hardware queue depth, request count, number of requests in hardware queue, and
|
capability, hardware queue depth, request count, number of requests in
|
||||||
the number of outstanding requests.
|
hardware queue, and the number of outstanding requests. The following
|
||||||
The following AP bus attributes can be displayed: AP domain, Max AP domain,
|
AP bus attributes can be displayed: AP domain, Max AP domain,
|
||||||
configuration timer, poll thread status, poll timeout, and AP interrupt
|
configuration timer, poll thread status, poll timeout, and AP
|
||||||
status.
|
interrupt status.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP 8
|
.TP 8
|
||||||
.B -V, --verbose
|
.B -V, --verbose
|
||||||
The verbose level for cryptographic device information.
|
The verbose level for cryptographic device information. With this
|
||||||
With this verbose level additional information like hardware card type,
|
verbose level additional information like hardware card type, hardware
|
||||||
hardware queue depth, pending requests count, installed function
|
queue depth, pending requests count, installed function facilities and
|
||||||
facilities and driver binding is displayed.
|
driver binding is displayed.
|
||||||
.TP 8
|
.TP 8
|
||||||
.B <device-id>
|
.B <device-id>
|
||||||
Specifies a cryptographic device to display. A cryptographic device can be
|
Specifies a cryptographic device to display. A cryptographic device
|
||||||
either a card device or a queue device. If no devices are specified information
|
can be either a card device or a queue device. If no devices are
|
||||||
about all available devices is displayed.
|
specified information about all available devices is displayed.
|
||||||
Please note that the card device representation and the queue device
|
Please note that the card device representation and the queue device
|
||||||
are both in hexadecimal notation.
|
are both in hexadecimal notation.
|
||||||
.TP 8
|
.TP 8
|
||||||
.B -b, --bus
|
.B -b, --bus
|
||||||
Displays the AP bus attributes and exits.
|
Displays the AP bus attributes and exits.
|
||||||
|
|
||||||
|
There is also a list of AP bus features shown here:
|
||||||
|
.RS
|
||||||
|
.IP "o" 3
|
||||||
|
APSC - Extended TAPQ (Test AP Queue) support.
|
||||||
|
.IP "o"
|
||||||
|
APXA - Support for more than 16 domains per card.
|
||||||
|
.IP "o"
|
||||||
|
QACT - QACT support for toleration of new unknown crypto cards.
|
||||||
|
.IP "o"
|
||||||
|
RC8A - Firmware reports 0x8A instead of 0x42 on some error conditions.
|
||||||
|
.IP "o"
|
||||||
|
APSB - AP bus has Secure Execution AP pass-through support.
|
||||||
|
.RE
|
||||||
.TP 8
|
.TP 8
|
||||||
.B -c, --capability <card-id>
|
.B -c, --capability <device-id>
|
||||||
Shows the capabilities of a cryptographic card device of hardware type 6 or
|
Shows the capabilities of a cryptographic card or queue device of
|
||||||
higher. The card device id value may be given as decimal or hex value (with
|
hardware type 6 or higher. A card device id value may be given as
|
||||||
a leading 0x). The capabilities of a cryptographic card device depend on
|
decimal or hex value (with a leading 0x), a queue device needs to be
|
||||||
the card type and the installed function facilities. A cryptographic card
|
given as xy.abcd (as it is displayed by lszcrypt).
|
||||||
|
|
||||||
|
The capabilities of a cryptographic card device depend on the card
|
||||||
|
type and the installed function facilities. A cryptographic card
|
||||||
device can provide one or more of the following capabilities:
|
device can provide one or more of the following capabilities:
|
||||||
.RS
|
.RS
|
||||||
.IP "o" 3
|
.IP "o" 3
|
||||||
@@ -94,14 +111,25 @@ Long RNG
|
|||||||
|
|
||||||
.RS 8
|
.RS 8
|
||||||
The CCA Secure Key capability may be limited by a hypervisor
|
The CCA Secure Key capability may be limited by a hypervisor
|
||||||
layer. The remarks 'full function set' or 'restricted function set' may
|
layer. The remarks 'full function set' or 'restricted function set'
|
||||||
reflect this. For details about these limitations please check the
|
may reflect this. For details about these limitations please check the
|
||||||
hypervisor documentation.
|
hypervisor documentation.
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
|
.RS 8
|
||||||
|
The capabilities of a cryptographic queue device may vary depending
|
||||||
|
on some state or environment. However if a queue device is given here,
|
||||||
|
and the runtime environment is a KVM guest in Secure Execution mode
|
||||||
|
with AP pass-through support, then the AP queue bind state and AP
|
||||||
|
queue association state is shown here. Furthermore the state(s) and
|
||||||
|
mkvp(s) (Master Key Verification Pattern) of the current master WK
|
||||||
|
(Wrapping Key - EP11 mode) or current master AES, APKA and ASYM (CCA
|
||||||
|
mode) are shown here.
|
||||||
|
.RE
|
||||||
.TP 8
|
.TP 8
|
||||||
.B -d, --domains
|
.B -d, --domains
|
||||||
Shows the usage and control domains of the cryptographic devices.
|
Shows the usage and control domains of the cryptographic devices. The
|
||||||
The displayed domains of the cryptographic device depends on the initial
|
displayed domains of the cryptographic device depends on the initial
|
||||||
cryptographic configuration.
|
cryptographic configuration.
|
||||||
.RS
|
.RS
|
||||||
.IP "o" 3
|
.IP "o" 3
|
||||||
@@ -140,18 +168,20 @@ Here is an explanation of the columns displayed. Please note that some
|
|||||||
of the columns show up in verbose mode only.
|
of the columns show up in verbose mode only.
|
||||||
.TP
|
.TP
|
||||||
.B CARD.DOM
|
.B CARD.DOM
|
||||||
The crypto card number in hexadecimal for a crypto card line or
|
The crypto card number in hexadecimal for a crypto card line or the
|
||||||
the crypto card number and the domain id both in hex separated by a single
|
crypto card number and the domain id both in hex separated by a single
|
||||||
dot for a queue line.
|
dot for a queue line.
|
||||||
.TP
|
.TP
|
||||||
.B TYPE and HWTYPE
|
.B TYPE and HWTYPE
|
||||||
The HWTYPE is a numeric value showing which type of hardware the zcrypt
|
The HWTYPE is a numeric value showing which type of hardware the
|
||||||
device driver presumes that this crypto card is. The currently known values
|
zcrypt device driver presumes that this crypto card is. The currently
|
||||||
are 7=CEX3C, 8=CEX3A, 10=CEX4, 11=CEX5, 12=CEX6, 13=CEX7 and 14=CEX8.
|
known values are 7=CEX3C, 8=CEX3A, 10=CEX4, 11=CEX5, 12=CEX6, 13=CEX7
|
||||||
|
and 14=CEX8.
|
||||||
.br
|
.br
|
||||||
The TYPE is a human readable value showing the hardware type and the basic
|
The TYPE is a human readable value showing the hardware type and the
|
||||||
function type (A=Accelerator, C=CCA Coprocessor, P=EP11 Coprocessor). So
|
basic function type (A=Accelerator, C=CCA Coprocessor, P=EP11
|
||||||
for example CEX6P means a CEX6 card in EP11 Coprocessor mode.
|
Coprocessor). So for example CEX6P means a CEX6 card in EP11
|
||||||
|
Coprocessor mode.
|
||||||
.TP
|
.TP
|
||||||
.B MODE
|
.B MODE
|
||||||
A crypto card can be configured to run into one of 3 modes:
|
A crypto card can be configured to run into one of 3 modes:
|
||||||
@@ -170,13 +200,13 @@ online/offline state is kept by the zcrypt device driver and can be
|
|||||||
switched on or off with the help of the chzcrypt application.
|
switched on or off with the help of the chzcrypt application.
|
||||||
.br
|
.br
|
||||||
A crypto card can also be 'configured' or 'deconfigured'. This state
|
A crypto card can also be 'configured' or 'deconfigured'. This state
|
||||||
may be adjusted on the HMC or SE. The chzcrypt application can also
|
may be adjusted on the HMC. The chzcrypt application can also trigger
|
||||||
trigger this state with the --config-on and --config-off options.
|
this state with the --config-on and --config-off options.
|
||||||
.br
|
.br
|
||||||
lszcrypt shows 'online' when a card or queue is available for
|
lszcrypt shows 'online' when a card or queue is available for
|
||||||
cryptographic operations. 'offline' is displayed when a card or queue
|
cryptographic operations. 'offline' is displayed when a card or queue
|
||||||
is switched to (software) offline. If a card is 'deconfigured' via
|
is switched to (software) offline. If a card is 'deconfigured' via
|
||||||
HMC, SE or chzcrypt the field shows 'deconfig'.
|
HMC or chzcrypt the field shows 'deconfig'.
|
||||||
.br
|
.br
|
||||||
A crypto card may also reach a 'checkstopped' state. lszcrypt shows
|
A crypto card may also reach a 'checkstopped' state. lszcrypt shows
|
||||||
this as 'chkstop'.
|
this as 'chkstop'.
|
||||||
@@ -184,21 +214,22 @@ this as 'chkstop'.
|
|||||||
If a queue is not bound to a device driver there is no detailed
|
If a queue is not bound to a device driver there is no detailed
|
||||||
information available and thus the status shows only '-'.
|
information available and thus the status shows only '-'.
|
||||||
.br
|
.br
|
||||||
If a queue is bound to the vfio-ap device driver it is up to this driver
|
If a queue is bound to the vfio-ap device driver it is up to this
|
||||||
to give some status information and what exactly this means. So lszcrypt
|
driver to give some status information and what exactly this means. So
|
||||||
shows the text retrieved from the underlying sysfs attribute here.
|
lszcrypt shows the text retrieved from the underlying sysfs attribute
|
||||||
|
here.
|
||||||
.TP
|
.TP
|
||||||
.B REQUESTS
|
.B REQUESTS
|
||||||
This is the counter value of successful processed requests on card or queue
|
This is the counter value of successful processed requests on card or
|
||||||
level. Successful here means the request was processed without any failure
|
queue level. Successful here means the request was processed without
|
||||||
in the whole processing chain.
|
any failure in the whole processing chain.
|
||||||
.TP
|
.TP
|
||||||
.B PENDING
|
.B PENDING
|
||||||
The underlying firmware and hardware layer usually provide some queuing
|
The underlying firmware and hardware layer usually provide some
|
||||||
space for requests. When this queue is already filled up, the zcrypt device
|
queuing space for requests. When this queue is already filled up, the
|
||||||
driver maintains a software queue of pending requests. The sum of these
|
zcrypt device driver maintains a software queue of pending
|
||||||
both values is displayed here and shows the amount of requests waiting for
|
requests. The sum of these both values is displayed here and shows the
|
||||||
processing on card or queue level.
|
amount of requests waiting for processing on card or queue level.
|
||||||
.TP
|
.TP
|
||||||
.B FUNCTIONS
|
.B FUNCTIONS
|
||||||
This column shows firmware and hardware function details:
|
This column shows firmware and hardware function details:
|
||||||
@@ -224,48 +255,64 @@ F - Full function support (opposed to restricted function support, see below).
|
|||||||
.br
|
.br
|
||||||
R - Restricted function support. The F and R flag both reflect if a
|
R - Restricted function support. The F and R flag both reflect if a
|
||||||
hypervisor is somehow restricting this crypto resource in a virtual
|
hypervisor is somehow restricting this crypto resource in a virtual
|
||||||
environment. Dependent on the hypervisor configuration the crypto requests
|
environment. Dependent on the hypervisor configuration the crypto
|
||||||
may be filtered by the hypervisor to allow only a subset of functions
|
requests may be filtered by the hypervisor to allow only a subset of
|
||||||
within the virtual runtime environment. For example a shared CCA
|
functions within the virtual runtime environment. For example a shared
|
||||||
Coprocessor may be restricted by the hypervisor to allow only clear key
|
CCA Coprocessor may be restricted by the hypervisor to allow only
|
||||||
operations within the guests.
|
clear key operations within the guests.
|
||||||
.TP
|
.TP
|
||||||
.B DRIVER
|
.B DRIVER
|
||||||
.br
|
.br
|
||||||
Shows which card or queue device driver currently handles this crypto
|
Shows which card or queue device driver currently handles this crypto
|
||||||
resource. Currently known drivers are cex4card/cex4queue (CEX4-CEX8
|
resource. Currently known drivers are cex4card/cex4queue (CEX4-CEX8
|
||||||
hardware), cex2card/cex2cqueue (CEX2C and CEX3C hardware),
|
hardware), cex2card/cex2cqueue (CEX2C and CEX3C hardware),
|
||||||
cex2acard/cex2aqueue (CEX2A and CEX3A hardware) and vfio_ap (queue reserved
|
cex2acard/cex2aqueue (CEX2A and CEX3A hardware) and vfio_ap (queue
|
||||||
for use by kvm hypervisor for kvm guests and not accessible to host
|
reserved for use by KVM hypervisor for KVM guests and not accessible
|
||||||
applications). It is also valid to have no driver handling a queue which is
|
to host applications). It is also valid to have no driver handling a
|
||||||
shown as a -no-driver- entry.
|
queue which is shown as a -no-driver- entry.
|
||||||
|
.TP
|
||||||
|
.B SESTAT
|
||||||
|
.br
|
||||||
|
Shows the state of the BS bits associated with every AP queue within a
|
||||||
|
Secure Execution guest when AP Pass-through support is available:
|
||||||
|
.br
|
||||||
|
usable - AP queue is usable for crypto load.
|
||||||
|
.br
|
||||||
|
bound - AP queue is bound but not yet associated.
|
||||||
|
.br
|
||||||
|
unbound - AP queue is unbound and needs to get bound to this Secure
|
||||||
|
Execution guest.
|
||||||
|
.br
|
||||||
|
illicit - AP queue is not available for this Secure Execution guest.
|
||||||
.SH NOTES
|
.SH NOTES
|
||||||
Use only one of the mode filtering options --accelonly, --ccaonly, --ep11only.
|
Use only one of the mode filtering options --accelonly, --ccaonly,
|
||||||
Same with card/queue filtering: Use only one of --cardonly, --queueonly.
|
--ep11only. Same with card/queue filtering: Use only one of
|
||||||
However, one of the mode filtering options and one of the card/queue filtering
|
--cardonly, --queueonly. However, one of the mode filtering options
|
||||||
can be combined.
|
and one of the card/queue filtering can be combined.
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
.TP
|
.TP
|
||||||
.B lszcrypt
|
.B lszcrypt
|
||||||
Displays the card/domain ID, card type (short name), mode (long name), online
|
Displays the card/domain ID, card type (short name), mode (long name),
|
||||||
status and request count of all available cryptographic devices.
|
online status and request count of all available cryptographic
|
||||||
|
devices.
|
||||||
.TP
|
.TP
|
||||||
.B lszcrypt 1 3 5
|
.B lszcrypt 1 3 5
|
||||||
Displays the card/domain ID, card type, mode, online status and request count
|
Displays the card/domain ID, card type, mode, online status and
|
||||||
for cryptographic devices 1, 3, and 5.
|
request count for cryptographic devices 1, 3, and 5.
|
||||||
.TP
|
.TP
|
||||||
.B lszcrypt -V 3 7 11
|
.B lszcrypt -V 3 7 11
|
||||||
Displays the card/domain ID, card type, mode, online status, request count,
|
Displays the card/domain ID, card type, mode, online status, request
|
||||||
number of requests in the hardware queue, number of outstanding requests and
|
count, number of requests in the hardware queue, number of outstanding
|
||||||
installed function facilities for cryptographic devices 3, 7 and 17 (0x11).
|
requests and installed function facilities for cryptographic devices
|
||||||
|
3, 7 and 17 (0x11).
|
||||||
.TP
|
.TP
|
||||||
.B lszcrypt 10.0038
|
.B lszcrypt 10.0038
|
||||||
Displays information of the cryptographic device '10.0038' respectively card
|
Displays information of the cryptographic device '10.0038'
|
||||||
id 16 (0x10) with domain 56 (0x38).
|
respectively card id 16 (0x10) with domain 56 (0x38).
|
||||||
.TP
|
.TP
|
||||||
.B lszcrypt .0038
|
.B lszcrypt .0038
|
||||||
Displays information of all available queue devices (potentially multiple
|
Displays information of all available queue devices (potentially
|
||||||
adapters) with domain 56 (0x38).
|
multiple adapters) with domain 56 (0x38).
|
||||||
.TP
|
.TP
|
||||||
.B lszcrypt -b
|
.B lszcrypt -b
|
||||||
Displays AP bus information.
|
Displays AP bus information.
|
||||||
|
|||||||
+118
-18
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* lszcrypt - Display zcrypt devices and configuration settings
|
* lszcrypt - Display zcrypt devices and configuration settings
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2008, 2022
|
* Copyright IBM Corp. 2008, 2023
|
||||||
*
|
*
|
||||||
* s390-tools is free software; you can redistribute it and/or modify
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -55,7 +55,7 @@ static struct lszcrypt_l {
|
|||||||
#define MASK_COPRO 0x10000000
|
#define MASK_COPRO 0x10000000
|
||||||
#define MASK_ACCEL 0x08000000
|
#define MASK_ACCEL 0x08000000
|
||||||
#define MASK_EP11 0x04000000
|
#define MASK_EP11 0x04000000
|
||||||
#define MASK_HSL 0x01000000
|
#define MASK_HSL 0x01000000
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Classification
|
* Classification
|
||||||
@@ -85,6 +85,8 @@ static struct fac_bits_s {
|
|||||||
{ 0x00400000, 'R' }, /* bit 9, restricted function set */
|
{ 0x00400000, 'R' }, /* bit 9, restricted function set */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define EXTRACT_BS_BITS(f) (((f) & 0x0000c000UL) >> 14)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Program configuration
|
* Program configuration
|
||||||
*/
|
*/
|
||||||
@@ -95,7 +97,7 @@ static const struct util_prg prg = {
|
|||||||
{
|
{
|
||||||
.owner = "IBM Corp.",
|
.owner = "IBM Corp.",
|
||||||
.pub_first = 2008,
|
.pub_first = 2008,
|
||||||
.pub_last = 2020,
|
.pub_last = 2023,
|
||||||
},
|
},
|
||||||
UTIL_PRG_COPYRIGHT_END
|
UTIL_PRG_COPYRIGHT_END
|
||||||
}
|
}
|
||||||
@@ -169,8 +171,9 @@ static struct util_opt opt_vec[] = {
|
|||||||
static void show_bus(void)
|
static void show_bus(void)
|
||||||
{
|
{
|
||||||
long domain, max_domain, config_time, value;
|
long domain, max_domain, config_time, value;
|
||||||
unsigned long long poll_timeout;
|
|
||||||
const char *poll_thread, *ap_interrupts;
|
const char *poll_thread, *ap_interrupts;
|
||||||
|
unsigned long long poll_timeout;
|
||||||
|
char features[256];
|
||||||
char *ap;
|
char *ap;
|
||||||
|
|
||||||
/* check if ap driver is available */
|
/* check if ap driver is available */
|
||||||
@@ -178,6 +181,10 @@ static void show_bus(void)
|
|||||||
if (!util_path_is_dir(ap))
|
if (!util_path_is_dir(ap))
|
||||||
errx(EXIT_FAILURE, "Crypto device driver not available.");
|
errx(EXIT_FAILURE, "Crypto device driver not available.");
|
||||||
|
|
||||||
|
if (util_path_is_readable("%s/features", ap))
|
||||||
|
util_file_read_line(features, sizeof(features), "%s/features", ap);
|
||||||
|
else
|
||||||
|
features[0] = '\0';
|
||||||
util_file_read_l(&domain, 10, "%s/ap_domain", ap);
|
util_file_read_l(&domain, 10, "%s/ap_domain", ap);
|
||||||
util_file_read_l(&max_domain, 10, "%s/ap_max_domain_id", ap);
|
util_file_read_l(&max_domain, 10, "%s/ap_max_domain_id", ap);
|
||||||
util_file_read_l(&config_time, 10, "%s/config_time", ap);
|
util_file_read_l(&config_time, 10, "%s/config_time", ap);
|
||||||
@@ -192,6 +199,8 @@ static void show_bus(void)
|
|||||||
ap_interrupts = "enabled";
|
ap_interrupts = "enabled";
|
||||||
else
|
else
|
||||||
ap_interrupts = "disabled";
|
ap_interrupts = "disabled";
|
||||||
|
if (features[0])
|
||||||
|
printf("features: %s\n", features);
|
||||||
printf("ap_domain=0x%lx\n", domain);
|
printf("ap_domain=0x%lx\n", domain);
|
||||||
printf("ap_max_domain_id=0x%lx\n", max_domain);
|
printf("ap_max_domain_id=0x%lx\n", max_domain);
|
||||||
if (util_path_is_reg_file("%s/ap_interrupts", ap))
|
if (util_path_is_reg_file("%s/ap_interrupts", ap))
|
||||||
@@ -374,23 +383,15 @@ next:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Show capability
|
* Show card capability
|
||||||
*/
|
*/
|
||||||
static void show_capability(const char *id_str)
|
static void show_card_capability(int id)
|
||||||
{
|
{
|
||||||
unsigned long func_val;
|
unsigned long func_val;
|
||||||
long hwtype, id, max_msg_size;
|
long hwtype, max_msg_size;
|
||||||
char *p, *ap, *dev, card[16], cbuf[256];
|
char *dev, card[16], cbuf[256];
|
||||||
|
|
||||||
/* check if ap driver is available */
|
snprintf(card, sizeof(card), "card%02x", id);
|
||||||
ap = util_path_sysfs("bus/ap");
|
|
||||||
if (!util_path_is_dir(ap))
|
|
||||||
errx(EXIT_FAILURE, "Crypto device driver not available.");
|
|
||||||
|
|
||||||
id = strtol(id_str, &p, 0);
|
|
||||||
if (id < 0 || id > 255 || p == id_str || *p != '\0')
|
|
||||||
errx(EXIT_FAILURE, "Error - '%s' is an invalid cryptographic device id.", id_str);
|
|
||||||
snprintf(card, sizeof(card), "card%02lx", id);
|
|
||||||
dev = util_path_sysfs("devices/ap/%s", card);
|
dev = util_path_sysfs("devices/ap/%s", card);
|
||||||
if (!util_path_is_dir(dev))
|
if (!util_path_is_dir(dev))
|
||||||
errx(EXIT_FAILURE, "Error - cryptographic device %s does not exist.", card);
|
errx(EXIT_FAILURE, "Error - cryptographic device %s does not exist.", card);
|
||||||
@@ -464,6 +465,78 @@ static void show_capability(const char *id_str)
|
|||||||
card, hwtype);
|
card, hwtype);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Show queue capability
|
||||||
|
*/
|
||||||
|
static void show_queue_capability(int id, int dom)
|
||||||
|
{
|
||||||
|
char *dev, card[16], queue[16], buf[256];
|
||||||
|
|
||||||
|
snprintf(card, sizeof(card), "card%02x", id);
|
||||||
|
snprintf(queue, sizeof(queue), "%02x.%04x", id, dom);
|
||||||
|
dev = util_path_sysfs("devices/ap/%s/%s", card, queue);
|
||||||
|
if (!util_path_is_dir(dev))
|
||||||
|
errx(EXIT_FAILURE, "Error - cryptographic queue device %02x.%04x does not exist.",
|
||||||
|
id, dom);
|
||||||
|
|
||||||
|
printf("queue %02x.%04x capabilities:\n", id, dom);
|
||||||
|
|
||||||
|
if (util_path_is_reg_file("%s/se_bind", dev)) {
|
||||||
|
util_file_read_line(buf, sizeof(buf), "%s/se_bind", dev);
|
||||||
|
printf("SE bind state: %s\n", buf);
|
||||||
|
}
|
||||||
|
if (util_path_is_reg_file("%s/se_associate", dev)) {
|
||||||
|
util_file_read_line(buf, sizeof(buf), "%s/se_associate", dev);
|
||||||
|
printf("SE association state: %s\n", buf);
|
||||||
|
}
|
||||||
|
if (util_path_is_reg_file("%s/mkvps", dev)) {
|
||||||
|
char *mkvps = util_path_sysfs("devices/ap/%s/%s/mkvps", card, queue);
|
||||||
|
FILE *f = fopen(mkvps, "r");
|
||||||
|
|
||||||
|
if (!f)
|
||||||
|
errx(EXIT_FAILURE, "Error - failed to open sysfs file %s.",
|
||||||
|
mkvps);
|
||||||
|
while (fgets(buf, sizeof(buf), f)) {
|
||||||
|
if (strstr(buf, "WK CUR") ||
|
||||||
|
strstr(buf, "AES CUR") ||
|
||||||
|
strstr(buf, "APKA CUR") ||
|
||||||
|
strstr(buf, "ASYM CUR"))
|
||||||
|
printf("MK %s", buf); /* no newline here */
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
free(mkvps);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Show capability
|
||||||
|
*/
|
||||||
|
static void show_capability(const char *id_str)
|
||||||
|
{
|
||||||
|
char *p, *ap;
|
||||||
|
int id, dom;
|
||||||
|
|
||||||
|
/* check if ap driver is available */
|
||||||
|
ap = util_path_sysfs("bus/ap");
|
||||||
|
if (!util_path_is_dir(ap))
|
||||||
|
errx(EXIT_FAILURE, "Crypto device driver not available.");
|
||||||
|
|
||||||
|
if (sscanf(id_str, "%x.%x", &id, &dom) == 2) {
|
||||||
|
show_queue_capability(id, dom);
|
||||||
|
} else {
|
||||||
|
id = strtol(id_str, &p, 0);
|
||||||
|
if (id < 0 || id > 255 || p == id_str || *p != '\0')
|
||||||
|
errx(EXIT_FAILURE,
|
||||||
|
"Error - '%s' is an invalid cryptographic device id.",
|
||||||
|
id_str);
|
||||||
|
show_card_capability(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -601,11 +674,33 @@ static void read_subdev_rec_verbose(struct util_rec *rec, const char *grp_dev,
|
|||||||
util_file_read_l(&depth, 10, "%s/depth", grp_dev);
|
util_file_read_l(&depth, 10, "%s/depth", grp_dev);
|
||||||
util_rec_set(rec, "depth", "%02d", depth + 1);
|
util_rec_set(rec, "depth", "%02d", depth + 1);
|
||||||
|
|
||||||
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
if (util_path_is_readable("%s/%s/ap_functions", grp_dev, sub_dev))
|
||||||
|
util_file_read_ul(&facility, 16, "%s/%s/ap_functions", grp_dev, sub_dev);
|
||||||
|
else
|
||||||
|
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
||||||
for (i = 0; i < MAX_FAC_BITS; i++)
|
for (i = 0; i < MAX_FAC_BITS; i++)
|
||||||
buf[i] = facility & fac_bits[i].mask ? fac_bits[i].c : '-';
|
buf[i] = facility & fac_bits[i].mask ? fac_bits[i].c : '-';
|
||||||
buf[i] = '\0';
|
buf[i] = '\0';
|
||||||
util_rec_set(rec, "facility", buf);
|
util_rec_set(rec, "facility", buf);
|
||||||
|
|
||||||
|
if (ap_bus_has_SB_support()) {
|
||||||
|
switch (EXTRACT_BS_BITS(facility)) {
|
||||||
|
case 0:
|
||||||
|
util_rec_set(rec, "sestat", "usable");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
util_rec_set(rec, "sestat", "bound");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
util_rec_set(rec, "sestat", "unbound");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
util_rec_set(rec, "sestat", "illicit");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
util_rec_set(rec, "sestat", "-");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -750,6 +845,9 @@ static void read_rec_verbose(struct util_rec *rec, const char *grp_dev)
|
|||||||
|
|
||||||
i = read_driver(grp_dev, NULL, buf, sizeof(buf));
|
i = read_driver(grp_dev, NULL, buf, sizeof(buf));
|
||||||
util_rec_set(rec, "driver", i > 0 ? buf : "-no-driver-");
|
util_rec_set(rec, "driver", i > 0 ? buf : "-no-driver-");
|
||||||
|
|
||||||
|
if (ap_bus_has_SB_support())
|
||||||
|
util_rec_set(rec, "sestat", "-");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -818,6 +916,8 @@ static void define_rec_verbose(struct util_rec *rec)
|
|||||||
util_rec_def(rec, "depth", UTIL_REC_ALIGN_RIGHT, 6, "QDEPTH");
|
util_rec_def(rec, "depth", UTIL_REC_ALIGN_RIGHT, 6, "QDEPTH");
|
||||||
util_rec_def(rec, "facility", UTIL_REC_ALIGN_LEFT, 10, "FUNCTIONS");
|
util_rec_def(rec, "facility", UTIL_REC_ALIGN_LEFT, 10, "FUNCTIONS");
|
||||||
util_rec_def(rec, "driver", UTIL_REC_ALIGN_LEFT, 11, "DRIVER");
|
util_rec_def(rec, "driver", UTIL_REC_ALIGN_LEFT, 11, "DRIVER");
|
||||||
|
if (ap_bus_has_SB_support())
|
||||||
|
util_rec_def(rec, "sestat", UTIL_REC_ALIGN_LEFT, 11, "SESTAT");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+37
-1
@@ -1,16 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
* Misc - Local helper functions
|
* Misc - Local helper functions
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2016, 2017
|
* Copyright IBM Corp. 2016, 2023
|
||||||
*
|
*
|
||||||
* s390-tools is free software; you can redistribute it and/or modify
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
|
#include <string.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "lib/util_base.h"
|
||||||
|
#include "lib/util_file.h"
|
||||||
#include "lib/util_panic.h"
|
#include "lib/util_panic.h"
|
||||||
|
#include "lib/util_path.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -35,3 +39,35 @@ bool misc_regex_match(const char *str, const char *regex)
|
|||||||
regfree(&preg);
|
regfree(&preg);
|
||||||
return rc == 0 ? true : false;
|
return rc == 0 ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test if AP bus has SB support available.
|
||||||
|
*
|
||||||
|
* @returns true Yes, SB support is available
|
||||||
|
* false No
|
||||||
|
*/
|
||||||
|
bool ap_bus_has_SB_support(void)
|
||||||
|
{
|
||||||
|
static int sb_support = -1;
|
||||||
|
|
||||||
|
if (sb_support < 0) {
|
||||||
|
char *ap, buf[256];
|
||||||
|
|
||||||
|
ap = util_path_sysfs("bus/ap");
|
||||||
|
if (!util_path_is_dir(ap)) {
|
||||||
|
sb_support = 0;
|
||||||
|
} else {
|
||||||
|
if (!util_path_is_readable("%s/features", ap)) {
|
||||||
|
sb_support = 0;
|
||||||
|
} else {
|
||||||
|
util_file_read_line(buf, sizeof(buf),
|
||||||
|
"%s/features", ap);
|
||||||
|
if (strstr(buf, "APSB"))
|
||||||
|
sb_support = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb_support > 0 ? true : false;
|
||||||
|
}
|
||||||
|
|||||||
+2
-1
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* misc - Local helper functions
|
* misc - Local helper functions
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2016, 2017
|
* Copyright IBM Corp. 2016, 2023
|
||||||
*
|
*
|
||||||
* s390-tools is free software; you can redistribute it and/or modify
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -13,5 +13,6 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
bool misc_regex_match(const char *str, const char *regex);
|
bool misc_regex_match(const char *str, const char *regex);
|
||||||
|
bool ap_bus_has_SB_support(void);
|
||||||
|
|
||||||
#endif /* MISC_H */
|
#endif /* MISC_H */
|
||||||
|
|||||||
@@ -344,6 +344,68 @@ static struct attrib dasd_attr_fc_security = {
|
|||||||
.readonly = 1,
|
.readonly = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct attrib dasd_attr_aq_mask = {
|
||||||
|
.name = "aq_mask",
|
||||||
|
.title = "Specify autoquiesce triggers",
|
||||||
|
.desc =
|
||||||
|
"Use the aq_mask attribute to automatically quiesce a device and block\n"
|
||||||
|
"new I/O after certain events.\n"
|
||||||
|
"\n"
|
||||||
|
"The value is a bitmask in decimal or hexadecimal format where each set bit\n"
|
||||||
|
"indicates that the associated event shown in the table below triggers an\n"
|
||||||
|
"autoquiesce.\n"
|
||||||
|
" Bit 0 is not used.\n"
|
||||||
|
" 1 - 0x02 - A terminal I/O error occurred\n"
|
||||||
|
" 2 - 0x04 - No active channel paths remain for the device\n"
|
||||||
|
" 3 - 0x08 - A state change interrupt occurred\n"
|
||||||
|
" 4 - 0x10 - The device is PPRC suspended\n"
|
||||||
|
" 5 - 0x20 - No space is left on an ESE device\n"
|
||||||
|
" 6 - 0x40 – The number of timeouts specified in aq_timeouts is reached\n"
|
||||||
|
" 7 - 0x80 - I/O was not started because of an error in the start function\n"
|
||||||
|
"\n"
|
||||||
|
"For example bits 1,3 and 5 set (0010 1010) lead to an integer value of 42\n"
|
||||||
|
"or 0x2A.\n"
|
||||||
|
"An integer value of 0 turns off the autoquiesce function.\n",
|
||||||
|
.order_cmp = ccw_online_only_order_cmp,
|
||||||
|
.check = ccw_online_only_check,
|
||||||
|
.defval = "0",
|
||||||
|
/*
|
||||||
|
* Currently only 8 bits are defined and the max value is 255.
|
||||||
|
* This needs to be adjusted if more bits are defined.
|
||||||
|
*/
|
||||||
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 255)),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct attrib dasd_attr_aq_requeue = {
|
||||||
|
.name = "aq_requeue",
|
||||||
|
.title = "Control I/O requeing during autoquiesce",
|
||||||
|
.desc =
|
||||||
|
"Use the aq_requeue attribute to control whether outstanding I/O\n"
|
||||||
|
"operations to the blocklayer should be automatically requeued after\n"
|
||||||
|
"an autoquiesce event.\n"
|
||||||
|
"Valid values are 1 for requeuing, or 0 for no requeueing.\n"
|
||||||
|
"Requeing the I/O requests to the blocklayer might benefit I/O\n"
|
||||||
|
"in case of a copy_pair swap operation.\n",
|
||||||
|
.order_cmp = ccw_online_only_order_cmp,
|
||||||
|
.check = ccw_online_only_check,
|
||||||
|
.defval = "0",
|
||||||
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct attrib dasd_attr_aq_timeouts = {
|
||||||
|
.name = "aq_timeouts",
|
||||||
|
.title = "Specify timeout retry threshold",
|
||||||
|
.desc =
|
||||||
|
"Specify the number of sequential timeout events for an I/O operation\n"
|
||||||
|
"before an autoquiesce is triggered on a device.\n"
|
||||||
|
"This requires that the corresponding trigger bit 6 is set\n"
|
||||||
|
"in the aq_mask attribute.\n",
|
||||||
|
.order_cmp = ccw_online_only_order_cmp,
|
||||||
|
.check = ccw_online_only_check,
|
||||||
|
.defval = "32768",
|
||||||
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 32768)),
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DASD subtype methods.
|
* DASD subtype methods.
|
||||||
*/
|
*/
|
||||||
@@ -725,6 +787,9 @@ struct subtype dasd_subtype_eckd = {
|
|||||||
&dasd_attr_safe_offline,
|
&dasd_attr_safe_offline,
|
||||||
&dasd_attr_fc_security,
|
&dasd_attr_fc_security,
|
||||||
&dasd_attr_copy_pair,
|
&dasd_attr_copy_pair,
|
||||||
|
&dasd_attr_aq_mask,
|
||||||
|
&dasd_attr_aq_requeue,
|
||||||
|
&dasd_attr_aq_timeouts,
|
||||||
&internal_attr_early,
|
&internal_attr_early,
|
||||||
),
|
),
|
||||||
.unknown_dev_attribs = 1,
|
.unknown_dev_attribs = 1,
|
||||||
|
|||||||
+4
-1
@@ -11,6 +11,8 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "lib/util_path.h"
|
||||||
|
|
||||||
#include "devnode.h"
|
#include "devnode.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
@@ -55,7 +57,8 @@ static bool add_devnodes_from_link(struct util_list *list,
|
|||||||
cb_data.prefix_len = strlen(prefix);
|
cb_data.prefix_len = strlen(prefix);
|
||||||
cb_data.result = false;
|
cb_data.result = false;
|
||||||
path = path_get_sys_class("net", devnode->name);
|
path = path_get_sys_class("net", devnode->name);
|
||||||
path_for_each(path, add_linked_cb, &cb_data);
|
if (util_path_exists(path))
|
||||||
|
path_for_each(path, add_linked_cb, &cb_data);
|
||||||
free(path);
|
free(path);
|
||||||
|
|
||||||
return cb_data.result;
|
return cb_data.result;
|
||||||
|
|||||||
+1
-1
@@ -603,7 +603,7 @@ exit_code_t select_by_node(struct select_opts *select,
|
|||||||
|
|
||||||
devnode = devnode_from_node(path, err);
|
devnode = devnode_from_node(path, err);
|
||||||
if (!devnode)
|
if (!devnode)
|
||||||
return EXIT_RUNTIME_ERROR;
|
return EXIT_DEVICE_NOT_FOUND;
|
||||||
|
|
||||||
rc = select_by_devnode(select, selected, config, scope, only_dt,
|
rc = select_by_devnode(select, selected, config, scope, only_dt,
|
||||||
only_st, devnode, path, err);
|
only_st, devnode, path, err);
|
||||||
|
|||||||
@@ -295,6 +295,7 @@ static exit_code_t udev_ccw_write_device_legacy(struct device *dev, bool autocon
|
|||||||
}
|
}
|
||||||
fprintf(fd, "GOTO=\"%s\"\n", end_label);
|
fprintf(fd, "GOTO=\"%s\"\n", end_label);
|
||||||
fprintf(fd, "\n");
|
fprintf(fd, "\n");
|
||||||
|
fprintf(fd, "LABEL=\"%s\"\n", cfg_label);
|
||||||
|
|
||||||
write_attr_to_file(fd, state, id);
|
write_attr_to_file(fd, state, id);
|
||||||
|
|
||||||
|
|||||||
+33
-8
@@ -213,16 +213,41 @@ out:
|
|||||||
static void write_zdev_site_id(int site_id)
|
static void write_zdev_site_id(int site_id)
|
||||||
{
|
{
|
||||||
FILE *fd;
|
FILE *fd;
|
||||||
|
int tmpfd, rc;
|
||||||
|
const char zdev_id_file[] = ZDEV_SITE_ID_FILE;
|
||||||
|
char zdev_id_tmpfile[] = ZDEV_SITE_ID_FILE "-XXXXXX";
|
||||||
|
|
||||||
fd = fopen(ZDEV_SITE_ID_FILE, "w");
|
tmpfd = mkstemp(zdev_id_tmpfile);
|
||||||
|
if (tmpfd == -1)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* Open the temp file to use with fprintf */
|
||||||
|
fd = fdopen(tmpfd, "w");
|
||||||
if (!fd)
|
if (!fd)
|
||||||
err(1, "Could not write to zdev_site_id file");
|
goto err;
|
||||||
if (site_id == SITE_FALLBACK)
|
|
||||||
fprintf(fd, "ZDEV_SITE_ID=\n");
|
|
||||||
else
|
|
||||||
fprintf(fd, "ZDEV_SITE_ID=%d\n", site_id);
|
|
||||||
|
|
||||||
fclose(fd);
|
if (site_id == SITE_FALLBACK)
|
||||||
|
rc = fprintf(fd, "ZDEV_SITE_ID=\"\"\n");
|
||||||
|
else
|
||||||
|
rc = fprintf(fd, "ZDEV_SITE_ID=%d\n", site_id);
|
||||||
|
|
||||||
|
if (rc < 0) {
|
||||||
|
fclose(fd);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fclose(fd))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* Rename the temporary file to ZDEV_SITE_ID_FILE*/
|
||||||
|
if (rename(zdev_id_tmpfile, zdev_id_file) == -1) {
|
||||||
|
remove(zdev_id_tmpfile);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
err:
|
||||||
|
err(1, "Could not write to zdev_site_id file");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the loadparm and extract the current site_id.
|
/* Read the loadparm and extract the current site_id.
|
||||||
@@ -265,7 +290,7 @@ static void process_loadparm(const char *filename)
|
|||||||
out:
|
out:
|
||||||
write_zdev_site_id(site_id);
|
write_zdev_site_id(site_id);
|
||||||
if (site_id == SITE_FALLBACK)
|
if (site_id == SITE_FALLBACK)
|
||||||
printf("ZDEV_SITE_ID=\n");
|
printf("ZDEV_SITE_ID=\"\"\n");
|
||||||
else
|
else
|
||||||
printf("ZDEV_SITE_ID=%d\n", site_id);
|
printf("ZDEV_SITE_ID=%d\n", site_id);
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -29,10 +29,10 @@ int is_zero_block(void *data)
|
|||||||
return blockptr->cyl || blockptr->head || blockptr->sec;
|
return blockptr->cyl || blockptr->head || blockptr->sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
void * load_direct(disk_blockptr_t *data, struct subchannel_id subchannel_id,
|
void *load_direct(union disk_blockptr *data, struct subchannel_id subchannel_id,
|
||||||
void *load_addr)
|
void *load_addr)
|
||||||
{
|
{
|
||||||
struct eckd_blockptr_legacy *blockptr = &data->eckd;
|
struct eckd_blockptr_legacy *blockptr = &data->eckd_legacy;
|
||||||
struct ccw1 *ccws;
|
struct ccw1 *ccws;
|
||||||
unsigned long record_size;
|
unsigned long record_size;
|
||||||
struct seek_arg seek_addr;
|
struct seek_arg seek_addr;
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ int is_zero_block(void *data) {
|
|||||||
return blockptr->blockno;
|
return blockptr->blockno;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *load_direct(disk_blockptr_t *data, struct subchannel_id subchannel_id,
|
void *load_direct(union disk_blockptr *data, struct subchannel_id subchannel_id,
|
||||||
void *load_addr)
|
void *load_addr)
|
||||||
{
|
{
|
||||||
struct linear_blockptr *blockptr = &data->linear;
|
struct linear_blockptr *blockptr = &data->linear;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
|
#include "boot/psw.h"
|
||||||
|
|
||||||
#define EPERM 1 /* Operation not permitted */
|
#define EPERM 1 /* Operation not permitted */
|
||||||
#define ENOENT 2 /* No such file or directory */
|
#define ENOENT 2 /* No such file or directory */
|
||||||
@@ -65,6 +66,7 @@ void __noreturn start(void);
|
|||||||
void pgm_check_handler(void);
|
void pgm_check_handler(void);
|
||||||
void pgm_check_handler_fn(void);
|
void pgm_check_handler_fn(void);
|
||||||
void panic_notify(unsigned long reason);
|
void panic_notify(unsigned long reason);
|
||||||
|
void load_wait_psw(uint64_t, struct psw_t *);
|
||||||
|
|
||||||
#define panic(reason, ...) \
|
#define panic(reason, ...) \
|
||||||
do { \
|
do { \
|
||||||
|
|||||||
+8
-9
@@ -18,7 +18,7 @@
|
|||||||
#include "boot/loaders_layout.h"
|
#include "boot/loaders_layout.h"
|
||||||
#include "stage2.h"
|
#include "stage2.h"
|
||||||
|
|
||||||
static int is_null_descriptor(disk_blockptr_t *address)
|
static int is_null_descriptor(union disk_blockptr *address)
|
||||||
{
|
{
|
||||||
unsigned long long *value = (unsigned long long *)address;
|
unsigned long long *value = (unsigned long long *)address;
|
||||||
|
|
||||||
@@ -28,13 +28,12 @@ static int is_null_descriptor(disk_blockptr_t *address)
|
|||||||
static void *load_blocklist(struct component_entry *descriptor_address,
|
static void *load_blocklist(struct component_entry *descriptor_address,
|
||||||
struct subchannel_id subchannel_id, void *load_address)
|
struct subchannel_id subchannel_id, void *load_address)
|
||||||
{
|
{
|
||||||
disk_blockptr_t *indirect_blocks, *indirect_blockspace,
|
union disk_blockptr *indirect_blocks, *indirect_blockspace, *start_addr;
|
||||||
*start_addr;
|
|
||||||
unsigned long length;
|
unsigned long length;
|
||||||
long long nr_descr;
|
long long nr_descr;
|
||||||
|
|
||||||
/* start address to load first indirect blocks */
|
/* start address to load first indirect blocks */
|
||||||
start_addr = (disk_blockptr_t *)&descriptor_address->data;
|
start_addr = (union disk_blockptr *)&descriptor_address->data;
|
||||||
/* get a free page to store indirect blocks in */
|
/* get a free page to store indirect blocks in */
|
||||||
indirect_blockspace = (void *)get_zeroed_page();
|
indirect_blockspace = (void *)get_zeroed_page();
|
||||||
|
|
||||||
@@ -90,7 +89,7 @@ void __noreturn start(void)
|
|||||||
struct subchannel_id subchannel_id;
|
struct subchannel_id subchannel_id;
|
||||||
void *load_address;
|
void *load_address;
|
||||||
struct component_entry *entry;
|
struct component_entry *entry;
|
||||||
disk_blockptr_t *blockptr;
|
union disk_blockptr *blockptr;
|
||||||
uint64_t load_psw;
|
uint64_t load_psw;
|
||||||
void *load_page;
|
void *load_page;
|
||||||
int config_nr;
|
int config_nr;
|
||||||
@@ -106,14 +105,14 @@ void __noreturn start(void)
|
|||||||
set_device(subchannel_id, ENABLED);
|
set_device(subchannel_id, ENABLED);
|
||||||
|
|
||||||
load_page = (void *)get_zeroed_page();
|
load_page = (void *)get_zeroed_page();
|
||||||
load_address = (disk_blockptr_t *) load_page;
|
load_address = (union disk_blockptr *) load_page;
|
||||||
|
|
||||||
/* load blockpointer list to load address */
|
/* load blockpointer list to load address */
|
||||||
load_direct((disk_blockptr_t *)&stage2_descr, subchannel_id,
|
load_direct((union disk_blockptr *)&stage2_descr, subchannel_id,
|
||||||
load_address);
|
load_address);
|
||||||
|
|
||||||
blockptr = (disk_blockptr_t *)(load_address +
|
blockptr = (union disk_blockptr *)(load_address +
|
||||||
sizeof(disk_blockptr_t));
|
sizeof(union disk_blockptr));
|
||||||
|
|
||||||
load_direct(&blockptr[config_nr], subchannel_id, load_address);
|
load_direct(&blockptr[config_nr], subchannel_id, load_address);
|
||||||
|
|
||||||
|
|||||||
+2
-6
@@ -26,16 +26,12 @@
|
|||||||
#include "cio.h"
|
#include "cio.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
|
||||||
typedef union {
|
|
||||||
struct eckd_blockptr_legacy eckd;
|
|
||||||
struct linear_blockptr linear;
|
|
||||||
} disk_blockptr_t;
|
|
||||||
|
|
||||||
struct stage2_descr {
|
struct stage2_descr {
|
||||||
uint8_t reserved[16];
|
uint8_t reserved[16];
|
||||||
} __packed __aligned(8);
|
} __packed __aligned(8);
|
||||||
|
|
||||||
void *load_direct(disk_blockptr_t *, struct subchannel_id , void *);
|
void *load_direct(union disk_blockptr *data, struct subchannel_id sid,
|
||||||
|
void *load_addr);
|
||||||
int extract_length(void *);
|
int extract_length(void *);
|
||||||
int is_zero_block(void *);
|
int is_zero_block(void *);
|
||||||
void kdump_stage2(unsigned long);
|
void kdump_stage2(unsigned long);
|
||||||
|
|||||||
@@ -31,11 +31,6 @@ function create_dumpfs()
|
|||||||
echo "$disk_path"
|
echo "$disk_path"
|
||||||
}
|
}
|
||||||
|
|
||||||
device=$(readlink -f $1)
|
|
||||||
disk_path=/dev/disk/by-partuuid/$(blkid -o value -s PARTUUID "$device")
|
|
||||||
|
|
||||||
[ -e "$disk_path" ] || { echo "Couldn't find disk by PARTUUID." >&2; exit 1; }
|
|
||||||
|
|
||||||
function get_kernel_version()
|
function get_kernel_version()
|
||||||
{
|
{
|
||||||
local version=$(uname -r)
|
local version=$(uname -r)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#define BOOTMAP_HEADER_VERSION 1
|
#define BOOTMAP_HEADER_VERSION 1
|
||||||
|
|
||||||
|
#define PROGRAM_TABLE_BLOCK_SIZE 512
|
||||||
#define SIGNATURE_MAGIC "~Module signature appended~\n"
|
#define SIGNATURE_MAGIC "~Module signature appended~\n"
|
||||||
#define PKCS7_FORMAT 0x01
|
#define PKCS7_FORMAT 0x01
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -38,7 +38,7 @@ struct disk_blockptr_linear {
|
|||||||
int blockct;
|
int blockct;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Pointer to a block on disk */
|
/* This represents in-memory pointer to a block on disk */
|
||||||
typedef union {
|
typedef union {
|
||||||
struct disk_blockptr_chs chs;
|
struct disk_blockptr_chs chs;
|
||||||
struct disk_blockptr_linear linear;
|
struct disk_blockptr_linear linear;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include "boot/s390.h" /* for PAGE_SIZE */
|
#include "boot/page.h"
|
||||||
|
|
||||||
#define ZIPL_ENVBLK_SIGNATURE "# zIPL Environment Block\n"
|
#define ZIPL_ENVBLK_SIGNATURE "# zIPL Environment Block\n"
|
||||||
#define ENVBLK_DEFAULT_IMPORT_SOURCE "/etc/ziplenv"
|
#define ENVBLK_DEFAULT_IMPORT_SOURCE "/etc/ziplenv"
|
||||||
|
|||||||
@@ -35,6 +35,14 @@ enum program_component_id {
|
|||||||
NR_PROGRAM_COMPONENTS
|
NR_PROGRAM_COMPONENTS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Types of SCSI disk layouts */
|
||||||
|
enum scsi_layout {
|
||||||
|
scsi_layout_pcbios,
|
||||||
|
scsi_layout_sun,
|
||||||
|
scsi_layout_sgi,
|
||||||
|
scsi_layout_unknown
|
||||||
|
};
|
||||||
|
|
||||||
struct component_loc {
|
struct component_loc {
|
||||||
address_t addr;
|
address_t addr;
|
||||||
size_t size;
|
size_t size;
|
||||||
@@ -76,6 +84,19 @@ struct install_set {
|
|||||||
|
|
||||||
extern struct component_footer component_footers[NR_PROGRAM_COMPONENTS];
|
extern struct component_footer component_footers[NR_PROGRAM_COMPONENTS];
|
||||||
|
|
||||||
|
/* Determine SCSI disk layout from the specified BOOTBLOCK. */
|
||||||
|
static inline enum scsi_layout get_scsi_layout(unsigned char *bootblock)
|
||||||
|
{
|
||||||
|
if ((bootblock[510] == 0x55) && (bootblock[511] == 0xaa))
|
||||||
|
return scsi_layout_pcbios;
|
||||||
|
else if ((bootblock[508] == 0xda) && (bootblock[509] == 0xbe))
|
||||||
|
return scsi_layout_sun;
|
||||||
|
else if ((bootblock[0] == 0x0b) && (bootblock[1] == 0xe5) &&
|
||||||
|
(bootblock[2] == 0xa9) && (bootblock[3] == 0x41))
|
||||||
|
return scsi_layout_sgi;
|
||||||
|
return scsi_layout_unknown;
|
||||||
|
}
|
||||||
|
|
||||||
static inline component_type component_type_by_id(enum program_component_id id)
|
static inline component_type component_type_by_id(enum program_component_id id)
|
||||||
{
|
{
|
||||||
return component_footers[id].type;
|
return component_footers[id].type;
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
#include "lib/util_libc.h"
|
#include "lib/util_libc.h"
|
||||||
#include "lib/util_part.h"
|
#include "lib/util_part.h"
|
||||||
#include "lib/util_path.h"
|
#include "lib/util_path.h"
|
||||||
#include "boot/s390.h"
|
|
||||||
#include "stage3.h"
|
#include "stage3.h"
|
||||||
|
|
||||||
#include "boot.h"
|
#include "boot.h"
|
||||||
@@ -119,8 +118,6 @@ void bootmap_store_blockptr(void *buffer, disk_blockptr_t *ptr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PROGRAM_TABLE_BLOCK_SIZE 512
|
|
||||||
|
|
||||||
/* Calculate the maximum number of entries in the program table. INFO
|
/* Calculate the maximum number of entries in the program table. INFO
|
||||||
* specifies the type of disk. */
|
* specifies the type of disk. */
|
||||||
static int
|
static int
|
||||||
|
|||||||
@@ -45,32 +45,9 @@ static inline unsigned long blk_cnt(int size, struct disk_info *info)
|
|||||||
return (size + info->phy_block_size - 1) / info->phy_block_size;
|
return (size + info->phy_block_size - 1) / info->phy_block_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Types of SCSI disk layouts */
|
|
||||||
enum scsi_layout {
|
|
||||||
scsi_layout_pcbios,
|
|
||||||
scsi_layout_sun,
|
|
||||||
scsi_layout_sgi,
|
|
||||||
scsi_layout_unknown
|
|
||||||
};
|
|
||||||
|
|
||||||
/* From linux/fs.h */
|
/* From linux/fs.h */
|
||||||
#define BLKFLSBUF _IO(0x12, 97)
|
#define BLKFLSBUF _IO(0x12, 97)
|
||||||
|
|
||||||
|
|
||||||
/* Determine SCSI disk layout from the specified BOOTBLOCK. */
|
|
||||||
static enum scsi_layout
|
|
||||||
get_scsi_layout(unsigned char* bootblock)
|
|
||||||
{
|
|
||||||
if ((bootblock[510] == 0x55) && (bootblock[511] == 0xaa))
|
|
||||||
return scsi_layout_pcbios;
|
|
||||||
else if ((bootblock[508] == 0xda) && (bootblock[509] == 0xbe))
|
|
||||||
return scsi_layout_sun;
|
|
||||||
else if ((bootblock[0] == 0x0b) && (bootblock[1] == 0xe5) &&
|
|
||||||
(bootblock[2] == 0xa9) && (bootblock[3] == 0x41))
|
|
||||||
return scsi_layout_sgi;
|
|
||||||
return scsi_layout_unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
overwrite_partition_start(int fd, struct disk_info* info, int mv_dump_magic);
|
overwrite_partition_start(int fd, struct disk_info* info, int mv_dump_magic);
|
||||||
|
|
||||||
|
|||||||
@@ -788,6 +788,8 @@ check_common_ipl_data(struct job_common_ipl_data *common, const char *section,
|
|||||||
rc = 0;
|
rc = 0;
|
||||||
goto skip_image;
|
goto skip_image;
|
||||||
}
|
}
|
||||||
|
fprintf(stderr, "Section '%s': Could not read image file '%s'\n",
|
||||||
|
section, common->image);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
if (size < MAX_COMMAND_LINE_SIZE + sizeof(uint64_t)) {
|
if (size < MAX_COMMAND_LINE_SIZE + sizeof(uint64_t)) {
|
||||||
@@ -822,6 +824,8 @@ skip_image:
|
|||||||
common->ignore = true;
|
common->ignore = true;
|
||||||
rc = 0;
|
rc = 0;
|
||||||
} else {
|
} else {
|
||||||
|
fprintf(stderr, "Section '%s': Missing ramdisk file '%s'\n",
|
||||||
|
section, common->ramdisk);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user