Blame SOURCES/kvm-s390x-protvirt-Disable-address-checks-for-PV-guest-I.patch

ddf19c
From 1cfcff169f392179258e4535e60d4ef9cabae3c6 Mon Sep 17 00:00:00 2001
ddf19c
From: Thomas Huth <thuth@redhat.com>
ddf19c
Date: Fri, 29 May 2020 05:54:13 -0400
ddf19c
Subject: [PATCH 31/42] s390x: protvirt: Disable address checks for PV guest IO
ddf19c
 emulation
ddf19c
ddf19c
RH-Author: Thomas Huth <thuth@redhat.com>
ddf19c
Message-id: <20200529055420.16855-32-thuth@redhat.com>
ddf19c
Patchwork-id: 97044
ddf19c
O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 31/38] s390x: protvirt: Disable address checks for PV guest IO emulation
ddf19c
Bugzilla: 1828317
ddf19c
RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
ddf19c
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
ddf19c
RH-Acked-by: David Hildenbrand <david@redhat.com>
ddf19c
ddf19c
From: Janosch Frank <frankja@linux.ibm.com>
ddf19c
ddf19c
IO instruction data is routed through SIDAD for protected guests, so
ddf19c
adresses do not need to be checked, as this is kernel memory which is
ddf19c
always available.
ddf19c
ddf19c
Also the instruction data always starts at offset 0 of the SIDAD.
ddf19c
ddf19c
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
ddf19c
Reviewed-by: Thomas Huth <thuth@redhat.com>
ddf19c
Reviewed-by: David Hildenbrand <david@redhat.com>
ddf19c
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
ddf19c
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
ddf19c
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
ddf19c
Message-Id: <20200319131921.2367-13-frankja@linux.ibm.com>
ddf19c
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
ddf19c
(cherry picked from commit c10b708752e5264a85b5c3afa0a0ccfcf6503ddf)
ddf19c
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
ddf19c
---
ddf19c
 target/s390x/ioinst.c | 35 ++++++++++++++++++++++++++++-------
ddf19c
 1 file changed, 28 insertions(+), 7 deletions(-)
ddf19c
ddf19c
diff --git a/target/s390x/ioinst.c b/target/s390x/ioinst.c
ddf19c
index c437a1d8c6..bbcccf6be2 100644
ddf19c
--- a/target/s390x/ioinst.c
ddf19c
+++ b/target/s390x/ioinst.c
ddf19c
@@ -16,6 +16,25 @@
ddf19c
 #include "hw/s390x/ioinst.h"
ddf19c
 #include "trace.h"
ddf19c
 #include "hw/s390x/s390-pci-bus.h"
ddf19c
+#include "hw/s390x/pv.h"
ddf19c
+
ddf19c
+/* All I/O instructions but chsc use the s format */
ddf19c
+static uint64_t get_address_from_regs(CPUS390XState *env, uint32_t ipb,
ddf19c
+                                      uint8_t *ar)
ddf19c
+{
ddf19c
+    /*
ddf19c
+     * Addresses for protected guests are all offsets into the
ddf19c
+     * satellite block which holds the IO control structures. Those
ddf19c
+     * control structures are always starting at offset 0 and are
ddf19c
+     * always aligned and accessible. So we can return 0 here which
ddf19c
+     * will pass the following address checks.
ddf19c
+     */
ddf19c
+    if (s390_is_pv()) {
ddf19c
+        *ar = 0;
ddf19c
+        return 0;
ddf19c
+    }
ddf19c
+    return decode_basedisp_s(env, ipb, ar);
ddf19c
+}
ddf19c
 
ddf19c
 int ioinst_disassemble_sch_ident(uint32_t value, int *m, int *cssid, int *ssid,
ddf19c
                                  int *schid)
ddf19c
@@ -114,7 +133,7 @@ void ioinst_handle_msch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
ddf19c
     CPUS390XState *env = &cpu->env;
ddf19c
     uint8_t ar;
ddf19c
 
ddf19c
-    addr = decode_basedisp_s(env, ipb, &ar);
ddf19c
+    addr = get_address_from_regs(env, ipb, &ar);
ddf19c
     if (addr & 3) {
ddf19c
         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
ddf19c
         return;
ddf19c
@@ -171,7 +190,7 @@ void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
ddf19c
     CPUS390XState *env = &cpu->env;
ddf19c
     uint8_t ar;
ddf19c
 
ddf19c
-    addr = decode_basedisp_s(env, ipb, &ar);
ddf19c
+    addr = get_address_from_regs(env, ipb, &ar);
ddf19c
     if (addr & 3) {
ddf19c
         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
ddf19c
         return;
ddf19c
@@ -203,7 +222,7 @@ void ioinst_handle_stcrw(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
ddf19c
     CPUS390XState *env = &cpu->env;
ddf19c
     uint8_t ar;
ddf19c
 
ddf19c
-    addr = decode_basedisp_s(env, ipb, &ar);
ddf19c
+    addr = get_address_from_regs(env, ipb, &ar);
ddf19c
     if (addr & 3) {
ddf19c
         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
ddf19c
         return;
ddf19c
@@ -234,7 +253,7 @@ void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb,
ddf19c
     CPUS390XState *env = &cpu->env;
ddf19c
     uint8_t ar;
ddf19c
 
ddf19c
-    addr = decode_basedisp_s(env, ipb, &ar);
ddf19c
+    addr = get_address_from_regs(env, ipb, &ar);
ddf19c
     if (addr & 3) {
ddf19c
         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
ddf19c
         return;
ddf19c
@@ -303,7 +322,7 @@ int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
ddf19c
         return -EIO;
ddf19c
     }
ddf19c
     trace_ioinst_sch_id("tsch", cssid, ssid, schid);
ddf19c
-    addr = decode_basedisp_s(env, ipb, &ar);
ddf19c
+    addr = get_address_from_regs(env, ipb, &ar);
ddf19c
     if (addr & 3) {
ddf19c
         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
ddf19c
         return -EIO;
ddf19c
@@ -601,7 +620,7 @@ void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
ddf19c
 {
ddf19c
     ChscReq *req;
ddf19c
     ChscResp *res;
ddf19c
-    uint64_t addr;
ddf19c
+    uint64_t addr = 0;
ddf19c
     int reg;
ddf19c
     uint16_t len;
ddf19c
     uint16_t command;
ddf19c
@@ -610,7 +629,9 @@ void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
ddf19c
 
ddf19c
     trace_ioinst("chsc");
ddf19c
     reg = (ipb >> 20) & 0x00f;
ddf19c
-    addr = env->regs[reg];
ddf19c
+    if (!s390_is_pv()) {
ddf19c
+        addr = env->regs[reg];
ddf19c
+    }
ddf19c
     /* Page boundary? */
ddf19c
     if (addr & 0xfff) {
ddf19c
         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
ddf19c
-- 
ddf19c
2.27.0
ddf19c