yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone

Blame SOURCES/kvm-s390-sclp-add-extended-length-sccb-support-for-kvm-g.patch

c687bc
From e1a3684f9b08fa9db35331b5c5ad11879f512e90 Mon Sep 17 00:00:00 2001
c687bc
From: Thomas Huth <thuth@redhat.com>
c687bc
Date: Wed, 11 Nov 2020 12:03:11 -0500
c687bc
Subject: [PATCH 11/18] s390/sclp: add extended-length sccb support for kvm
c687bc
 guest
c687bc
c687bc
RH-Author: Thomas Huth <thuth@redhat.com>
c687bc
Message-id: <20201111120316.707489-8-thuth@redhat.com>
c687bc
Patchwork-id: 99504
c687bc
O-Subject: [RHEL-8.4.0 qemu-kvm PATCH v2 07/12] s390/sclp: add extended-length sccb support for kvm guest
c687bc
Bugzilla: 1798506
c687bc
RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
c687bc
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
c687bc
RH-Acked-by: David Hildenbrand <david@redhat.com>
c687bc
c687bc
From: Collin Walling <walling@linux.ibm.com>
c687bc
c687bc
As more features and facilities are added to the Read SCP Info (RSCPI)
c687bc
response, more space is required to store them. The space used to store
c687bc
these new features intrudes on the space originally used to store CPU
c687bc
entries. This means as more features and facilities are added to the
c687bc
RSCPI response, less space can be used to store CPU entries.
c687bc
c687bc
With the Extended-Length SCCB (ELS) facility, a KVM guest can execute
c687bc
the RSCPI command and determine if the SCCB is large enough to store a
c687bc
complete reponse. If it is not large enough, then the required length
c687bc
will be set in the SCCB header.
c687bc
c687bc
The caller of the SCLP command is responsible for creating a
c687bc
large-enough SCCB to store a complete response. Proper checking should
c687bc
be in place, and the caller should execute the command once-more with
c687bc
the large-enough SCCB.
c687bc
c687bc
This facility also enables an extended SCCB for the Read CPU Info
c687bc
(RCPUI) command.
c687bc
c687bc
When this facility is enabled, the boundary violation response cannot
c687bc
be a result from the RSCPI, RSCPI Forced, or RCPUI commands.
c687bc
c687bc
In order to tolerate kernels that do not yet have full support for this
c687bc
feature, a "fixed" offset to the start of the CPU Entries within the
c687bc
Read SCP Info struct is set to allow for the original 248 max entries
c687bc
when this feature is disabled.
c687bc
c687bc
Additionally, this is introduced as a CPU feature to protect the guest
c687bc
from migrating to a machine that does not support storing an extended
c687bc
SCCB. This could otherwise hinder the VM from being able to read all
c687bc
available CPU entries after migration (such as during re-ipl).
c687bc
c687bc
Signed-off-by: Collin Walling <walling@linux.ibm.com>
c687bc
Reviewed-by: Thomas Huth <thuth@redhat.com>
c687bc
Acked-by: Cornelia Huck <cohuck@redhat.com>
c687bc
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
c687bc
Message-Id: <20200915194416.107460-7-walling@linux.ibm.com>
c687bc
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
c687bc
(cherry picked from commit 1ecd6078f587cfadda8edc93d45b5072e35f2d17)
c687bc
Signed-off-by: Thomas Huth <thuth@redhat.com>
c687bc
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
c687bc
---
c687bc
 hw/s390x/sclp.c                     | 43 +++++++++++++++++++++++++----
c687bc
 include/hw/s390x/sclp.h             |  1 +
c687bc
 target/s390x/cpu_features_def.inc.h |  1 +
c687bc
 target/s390x/gen-features.c         |  1 +
c687bc
 target/s390x/kvm.c                  |  8 ++++++
c687bc
 5 files changed, 48 insertions(+), 6 deletions(-)
c687bc
c687bc
diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
c687bc
index 017989b3888..8d111628e04 100644
c687bc
--- a/hw/s390x/sclp.c
c687bc
+++ b/hw/s390x/sclp.c
c687bc
@@ -49,13 +49,30 @@ static inline bool sclp_command_code_valid(uint32_t code)
c687bc
     return false;
c687bc
 }
c687bc
 
c687bc
-static bool sccb_verify_boundary(uint64_t sccb_addr, uint16_t sccb_len)
c687bc
+static bool sccb_verify_boundary(uint64_t sccb_addr, uint16_t sccb_len,
c687bc
+                                 uint32_t code)
c687bc
 {
c687bc
     uint64_t sccb_max_addr = sccb_addr + sccb_len - 1;
c687bc
     uint64_t sccb_boundary = (sccb_addr & PAGE_MASK) + PAGE_SIZE;
c687bc
 
c687bc
-    if (sccb_max_addr < sccb_boundary) {
c687bc
-        return true;
c687bc
+    switch (code & SCLP_CMD_CODE_MASK) {
c687bc
+    case SCLP_CMDW_READ_SCP_INFO:
c687bc
+    case SCLP_CMDW_READ_SCP_INFO_FORCED:
c687bc
+    case SCLP_CMDW_READ_CPU_INFO:
c687bc
+        /*
c687bc
+         * An extended-length SCCB is only allowed for Read SCP/CPU Info and
c687bc
+         * is allowed to exceed the 4k boundary. The respective commands will
c687bc
+         * set the length field to the required length if an insufficient
c687bc
+         * SCCB length is provided.
c687bc
+         */
c687bc
+        if (s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB)) {
c687bc
+            return true;
c687bc
+        }
c687bc
+        /* fallthrough */
c687bc
+    default:
c687bc
+        if (sccb_max_addr < sccb_boundary) {
c687bc
+            return true;
c687bc
+        }
c687bc
     }
c687bc
 
c687bc
     return false;
c687bc
@@ -80,6 +97,12 @@ static void prepare_cpu_entries(MachineState *ms, CPUEntry *entry, int *count)
c687bc
 
c687bc
 #define SCCB_REQ_LEN(s, max_cpus) (sizeof(s) + max_cpus * sizeof(CPUEntry))
c687bc
 
c687bc
+static inline bool ext_len_sccb_supported(SCCBHeader header)
c687bc
+{
c687bc
+    return s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB) &&
c687bc
+           header.control_mask[2] & SCLP_VARIABLE_LENGTH_RESPONSE;
c687bc
+}
c687bc
+
c687bc
 /* Provide information about the configuration, CPUs and storage */
c687bc
 static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
c687bc
 {
c687bc
@@ -89,10 +112,15 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
c687bc
     int rnsize, rnmax;
c687bc
     IplParameterBlock *ipib = s390_ipl_get_iplb();
c687bc
     int required_len = SCCB_REQ_LEN(ReadInfo, machine->possible_cpus->len);
c687bc
-    int offset_cpu = offsetof(ReadInfo, entries);
c687bc
+    int offset_cpu = s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB) ?
c687bc
+                     offsetof(ReadInfo, entries) :
c687bc
+                     SCLP_READ_SCP_INFO_FIXED_CPU_OFFSET;
c687bc
     CPUEntry *entries_start = (void *)sccb + offset_cpu;
c687bc
 
c687bc
     if (be16_to_cpu(sccb->h.length) < required_len) {
c687bc
+        if (ext_len_sccb_supported(sccb->h)) {
c687bc
+            sccb->h.length = cpu_to_be16(required_len);
c687bc
+        }
c687bc
         sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
c687bc
         return;
c687bc
     }
c687bc
@@ -153,6 +181,9 @@ static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB *sccb)
c687bc
     int required_len = SCCB_REQ_LEN(ReadCpuInfo, machine->possible_cpus->len);
c687bc
 
c687bc
     if (be16_to_cpu(sccb->h.length) < required_len) {
c687bc
+        if (ext_len_sccb_supported(sccb->h)) {
c687bc
+            sccb->h.length = cpu_to_be16(required_len);
c687bc
+        }
c687bc
         sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
c687bc
         return;
c687bc
     }
c687bc
@@ -249,7 +280,7 @@ int sclp_service_call_protected(CPUS390XState *env, uint64_t sccb,
c687bc
         goto out_write;
c687bc
     }
c687bc
 
c687bc
-    if (!sccb_verify_boundary(sccb, be16_to_cpu(work_sccb->h.length))) {
c687bc
+    if (!sccb_verify_boundary(sccb, be16_to_cpu(work_sccb->h.length), code)) {
c687bc
         work_sccb->h.response_code = cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
c687bc
         goto out_write;
c687bc
     }
c687bc
@@ -302,7 +333,7 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code)
c687bc
         goto out_write;
c687bc
     }
c687bc
 
c687bc
-    if (!sccb_verify_boundary(sccb, be16_to_cpu(work_sccb->h.length))) {
c687bc
+    if (!sccb_verify_boundary(sccb, be16_to_cpu(work_sccb->h.length), code)) {
c687bc
         work_sccb->h.response_code = cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
c687bc
         goto out_write;
c687bc
     }
c687bc
diff --git a/include/hw/s390x/sclp.h b/include/hw/s390x/sclp.h
c687bc
index 55f53a46540..df2fa4169b0 100644
c687bc
--- a/include/hw/s390x/sclp.h
c687bc
+++ b/include/hw/s390x/sclp.h
c687bc
@@ -110,6 +110,7 @@ typedef struct CPUEntry {
c687bc
     uint8_t reserved1;
c687bc
 } QEMU_PACKED CPUEntry;
c687bc
 
c687bc
+#define SCLP_READ_SCP_INFO_FIXED_CPU_OFFSET     128
c687bc
 typedef struct ReadInfo {
c687bc
     SCCBHeader h;
c687bc
     uint16_t rnmax;
c687bc
diff --git a/target/s390x/cpu_features_def.inc.h b/target/s390x/cpu_features_def.inc.h
c687bc
index 60db28351d0..3548d65a69a 100644
c687bc
--- a/target/s390x/cpu_features_def.inc.h
c687bc
+++ b/target/s390x/cpu_features_def.inc.h
c687bc
@@ -97,6 +97,7 @@ DEF_FEAT(GUARDED_STORAGE, "gs", STFL, 133, "Guarded-storage facility")
c687bc
 DEF_FEAT(VECTOR_PACKED_DECIMAL, "vxpd", STFL, 134, "Vector packed decimal facility")
c687bc
 DEF_FEAT(VECTOR_ENH, "vxeh", STFL, 135, "Vector enhancements facility")
c687bc
 DEF_FEAT(MULTIPLE_EPOCH, "mepoch", STFL, 139, "Multiple-epoch facility")
c687bc
+DEF_FEAT(EXTENDED_LENGTH_SCCB, "els", STFL, 140, "Extended-length SCCB facility")
c687bc
 DEF_FEAT(TEST_PENDING_EXT_INTERRUPTION, "tpei", STFL, 144, "Test-pending-external-interruption facility")
c687bc
 DEF_FEAT(INSERT_REFERENCE_BITS_MULT, "irbm", STFL, 145, "Insert-reference-bits-multiple facility")
c687bc
 DEF_FEAT(MSA_EXT_8, "msa8-base", STFL, 146, "Message-security-assist-extension-8 facility (excluding subfunctions)")
c687bc
diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c
c687bc
index 8ddeebc5441..6857f657fba 100644
c687bc
--- a/target/s390x/gen-features.c
c687bc
+++ b/target/s390x/gen-features.c
c687bc
@@ -522,6 +522,7 @@ static uint16_t full_GEN12_GA1[] = {
c687bc
     S390_FEAT_AP_QUEUE_INTERRUPT_CONTROL,
c687bc
     S390_FEAT_AP_FACILITIES_TEST,
c687bc
     S390_FEAT_AP,
c687bc
+    S390_FEAT_EXTENDED_LENGTH_SCCB,
c687bc
 };
c687bc
 
c687bc
 static uint16_t full_GEN12_GA2[] = {
c687bc
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
c687bc
index 0bbf8f81b09..ef437acb5c1 100644
c687bc
--- a/target/s390x/kvm.c
c687bc
+++ b/target/s390x/kvm.c
c687bc
@@ -2441,6 +2441,14 @@ void kvm_s390_get_host_cpu_model(S390CPUModel *model, Error **errp)
c687bc
         KVM_S390_VM_CRYPTO_ENABLE_APIE)) {
c687bc
         set_bit(S390_FEAT_AP, model->features);
c687bc
     }
c687bc
+
c687bc
+    /*
c687bc
+     * Extended-Length SCCB is handled entirely within QEMU.
c687bc
+     * For PV guests this is completely fenced by the Ultravisor, as Service
c687bc
+     * Call error checking and STFLE interpretation are handled via SIE.
c687bc
+     */
c687bc
+    set_bit(S390_FEAT_EXTENDED_LENGTH_SCCB, model->features);
c687bc
+
c687bc
     /* strip of features that are not part of the maximum model */
c687bc
     bitmap_and(model->features, model->features, model->def->full_feat,
c687bc
                S390_FEAT_MAX);
c687bc
-- 
c687bc
2.27.0
c687bc