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

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