Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:15.1:Rings:1-MinimalX
qclib
qclib-sles15-fix-mismatch-case-with-STHYI.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File qclib-sles15-fix-mismatch-case-with-STHYI.patch of Package qclib
commit 13d7aafb0cb8946880abbb73725b0340bec1cd3a Author: Stefan Raspl <stefan.raspl@de.ibm.com> Date: Fri Dec 8 22:11:29 2017 +0100 STHYI: Fix mismatch case with STHYI and /proc/sysinfo data Reported via Bz162324. Symptom was that qclib wouldn't work on a z/VM 5.4. Analysis revealed that although the STHYI instruction wasn't available, the newly added STHYI syscall would work, but (as intended) reported only layers up to LPAR. In contrast, /proc/sysinfo would report all layers, including the z/VM layer. Some detection logic kicked in and reported an error. The problem was rooted in a bizarr combination of multiple glitches: * An (unnecessary) extra handling for z/VM that was previously added would raise an error on mismatching layer counts in STHYI and /proc/sysinfo. This was to detect cases with more than 3 levels of nested virtualization. But the check just was for mismatching counts and didn't check for the 3 layers reported by STHYI at all. * Furthermore, the check mentioned above was unnecessary to begin with: When STHYI reports data for 3 VM layers, and /proc/sysinfo for more, then the extra layers will simply not get any data from STHYI - no harm done. * STHYI in KVM worked like a charm ever since, though it is supposed to fail with the same error as z/VM since STHYI in KVM (and likewise the syscall in LPARs) cannot report data beyond the LPAR layer - it should result in the same mismatch that z/VM experienced. However, the respective routines would only ever consider VM layers in z/VM and ignore the ones in KVM! Hence all layers beyond LPAR wouldn't be accounted for on KVM! To fix, we're ripping out the extra check, and rewrite the remaining code to handle z/VM and KVM alike. Furthermore, we rename "STHYI@VM" to "STHYI instruction", and "STHYI@LPAR" to "STHYI syscall" for improved clarity. diff --git a/query_capacity_sthyi.c b/query_capacity_sthyi.c index b3bd9e8..688062f 100644 --- a/query_capacity_sthyi.c +++ b/query_capacity_sthyi.c @@ -91,16 +91,16 @@ static int qc_sthyi_lpar(struct qc_handle *hdl, struct sthyi_priv *priv) { #ifdef __NR_s390_sthyi sthyi = __NR_s390_sthyi #endif - qc_debug(hdl, "Try STHYI@LPAR\n"); + qc_debug(hdl, "Try STHYI syscall\n"); if (syscall(sthyi, 0, priv->data, &cc, 0) || cc) { if (errno == ENOSYS) { - qc_debug(hdl, "STHYI@LPAR is not available\n"); + qc_debug(hdl, "STHYI syscall is not available\n"); return 0; } - qc_debug(hdl, "Error: STHYI@LPAR execution failed: errno='%s', cc=%" PRIu64 "\n", strerror(errno), cc); + qc_debug(hdl, "Error: STHYI syscall execution failed: errno='%s', cc=%" PRIu64 "\n", strerror(errno), cc); return -1; } - qc_debug(hdl, "STHYI@LPAR succeeded\n"); + qc_debug(hdl, "STHYI syscall succeeded\n"); priv->avail = STHYI_AVAILABLE; #endif @@ -281,25 +281,15 @@ static int qc_parse_sthyi_guest(struct qc_handle *gst, struct inf0gst *guest) { return 0; } -static int qc_get_num_vm_layers(struct qc_handle *hdl, int *rc) { - int i; - - for (hdl = hdl->root, i = 0; hdl != NULL; hdl = hdl->next) { - if (*(int *)(hdl->layer) == QC_LAYER_TYPE_ZVM_HYPERVISOR) - i++; - } - - return i; -} - /* Returns pointer to the n-th hypervisor handle. num starts at 0, and handles are returned in sequence from handle linked list */ static struct qc_handle *qc_get_HV_layer(struct qc_handle *hdl, int num) { struct qc_handle *h = hdl; - int i; + int i, type; for (hdl = hdl->root, i = 0, num++; hdl != NULL; hdl = hdl->next) { - if (*(int *)(hdl->layer) == QC_LAYER_TYPE_ZVM_HYPERVISOR && ++i == num) + type = *(int *)(hdl->layer); + if ((type == QC_LAYER_TYPE_ZVM_HYPERVISOR || type == QC_LAYER_TYPE_KVM_HYPERVISOR) && ++i == num) return hdl; } qc_debug(h, "Error: Couldn't find HV layer %d, only %d layer(s) found\n", num, i); @@ -309,7 +299,7 @@ static struct qc_handle *qc_get_HV_layer(struct qc_handle *hdl, int num) { static int qc_sthyi_process(struct qc_handle *hdl, char *buf) { struct sthyi_priv *priv = (struct sthyi_priv *)buf; - int no_hyp_gst, num_vm_layers, i, rc = 0; + int no_hyp_gst, i, rc = 0; struct inf0gst *guest[INF0YGMX]; struct inf0hyp *hv[INF0YGMX]; struct inf0par *partition; @@ -371,30 +361,14 @@ static int qc_sthyi_process(struct qc_handle *hdl, char *buf) { goto out; } - num_vm_layers = qc_get_num_vm_layers(hdl, &rc); - if (rc != 0) { - rc = -2; - goto out; - } - - if (num_vm_layers != no_hyp_gst) { - /* STHYI doesn't support more than 3rd level z/VM */ - qc_debug(hdl, "Error: /proc/sysinfo reported %d layers, but STHYI only " - "covers %d\n", num_vm_layers, no_hyp_gst); - rc = -6; - goto out; - } - for (i = 0; i < no_hyp_gst; i++) { if ((hdl = qc_get_HV_layer(hdl, i)) == NULL) { rc = -7; goto out; } - if (*(int *)(hdl->layer) == QC_LAYER_TYPE_ZVM_HYPERVISOR) { - if (qc_parse_sthyi_hypervisor(hdl, hv[i]) || qc_parse_sthyi_guest(hdl->next, guest[i])) { - rc = -9; - goto out; - } + if (qc_parse_sthyi_hypervisor(hdl, hv[i]) || qc_parse_sthyi_guest(hdl->next, guest[i])) { + rc = -9; + goto out; } } out: @@ -508,15 +482,15 @@ static int qc_sthyi_open(struct qc_handle *hdl, char **buf) { /* There is no way for us to check programmatically whether we're in an LPAR or in a VM, so we simply try out both */ if (qc_is_sthyi_available_vm(hdl)) { - qc_debug(hdl, "Executing STHYI@VM\n"); + qc_debug(hdl, "Executing STHYI instruction\n"); /* we assume we are not relocated at this spot, between STFLE and STHYI */ if (qc_sthyi_vm(priv)) { - qc_debug(hdl, "Error: STHYI@VM execution failed\n"); + qc_debug(hdl, "Error: STHYI instruction execution failed\n"); rc = -3; goto out; } } else { - qc_debug(hdl, "STHYI@VM is not available\n"); + qc_debug(hdl, "STHYI instruction is not available\n"); rc = qc_sthyi_lpar(hdl, priv); } }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor