Blame SOURCES/kvm-s390x-protvirt-Move-IO-control-structures-over-SIDA.patch

902636
From 8345b90f43b14435938fbbe0f3a510a60f5d0ded Mon Sep 17 00:00:00 2001
902636
From: Thomas Huth <thuth@redhat.com>
902636
Date: Fri, 29 May 2020 05:54:14 -0400
902636
Subject: [PATCH 32/42] s390x: protvirt: Move IO control structures over SIDA
902636
902636
RH-Author: Thomas Huth <thuth@redhat.com>
902636
Message-id: <20200529055420.16855-33-thuth@redhat.com>
902636
Patchwork-id: 97040
902636
O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 32/38] s390x: protvirt: Move IO control structures over SIDA
902636
Bugzilla: 1828317
902636
RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
902636
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
902636
RH-Acked-by: David Hildenbrand <david@redhat.com>
902636
902636
From: Janosch Frank <frankja@linux.ibm.com>
902636
902636
For protected guests, we need to put the IO emulation results into the
902636
SIDA, so SIE will write them into the guest at the next entry.
902636
902636
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
902636
Reviewed-by: David Hildenbrand <david@redhat.com>
902636
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
902636
Message-Id: <20200319131921.2367-14-frankja@linux.ibm.com>
902636
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
902636
(cherry picked from commit fcc10c1470d6e9460ebcf4c30f5bbd37b921a041)
902636
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
902636
---
902636
 target/s390x/ioinst.c | 61 +++++++++++++++++++++++++++++++------------
902636
 1 file changed, 45 insertions(+), 16 deletions(-)
902636
902636
diff --git a/target/s390x/ioinst.c b/target/s390x/ioinst.c
902636
index bbcccf6be2..f40c35c6ff 100644
902636
--- a/target/s390x/ioinst.c
902636
+++ b/target/s390x/ioinst.c
902636
@@ -138,7 +138,9 @@ void ioinst_handle_msch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
902636
         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
902636
         return;
902636
     }
902636
-    if (s390_cpu_virt_mem_read(cpu, addr, ar, &schib, sizeof(schib))) {
902636
+    if (s390_is_pv()) {
902636
+        s390_cpu_pv_mem_read(cpu, addr, &schib, sizeof(schib));
902636
+    } else if (s390_cpu_virt_mem_read(cpu, addr, ar, &schib, sizeof(schib))) {
902636
         s390_cpu_virt_mem_handle_exc(cpu, ra);
902636
         return;
902636
     }
902636
@@ -195,7 +197,9 @@ void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
902636
         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
902636
         return;
902636
     }
902636
-    if (s390_cpu_virt_mem_read(cpu, addr, ar, &orig_orb, sizeof(orb))) {
902636
+    if (s390_is_pv()) {
902636
+        s390_cpu_pv_mem_read(cpu, addr, &orig_orb, sizeof(orb));
902636
+    } else if (s390_cpu_virt_mem_read(cpu, addr, ar, &orig_orb, sizeof(orb))) {
902636
         s390_cpu_virt_mem_handle_exc(cpu, ra);
902636
         return;
902636
     }
902636
@@ -231,14 +235,19 @@ void ioinst_handle_stcrw(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
902636
     cc = css_do_stcrw(&crw;;
902636
     /* 0 - crw stored, 1 - zeroes stored */
902636
 
902636
-    if (s390_cpu_virt_mem_write(cpu, addr, ar, &crw, sizeof(crw)) == 0) {
902636
+    if (s390_is_pv()) {
902636
+        s390_cpu_pv_mem_write(cpu, addr, &crw, sizeof(crw));
902636
         setcc(cpu, cc);
902636
     } else {
902636
-        if (cc == 0) {
902636
-            /* Write failed: requeue CRW since STCRW is suppressing */
902636
-            css_undo_stcrw(&crw;;
902636
+        if (s390_cpu_virt_mem_write(cpu, addr, ar, &crw, sizeof(crw)) == 0) {
902636
+            setcc(cpu, cc);
902636
+        } else {
902636
+            if (cc == 0) {
902636
+                /* Write failed: requeue CRW since STCRW is suppressing */
902636
+                css_undo_stcrw(&crw;;
902636
+            }
902636
+            s390_cpu_virt_mem_handle_exc(cpu, ra);
902636
         }
902636
-        s390_cpu_virt_mem_handle_exc(cpu, ra);
902636
     }
902636
 }
902636
 
902636
@@ -260,6 +269,13 @@ void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb,
902636
     }
902636
 
902636
     if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
902636
+        /*
902636
+         * The Ultravisor checks schid bit 16 to be one and bits 0-12
902636
+         * to be 0 and injects a operand exception itself.
902636
+         *
902636
+         * Hence we should never end up here.
902636
+         */
902636
+        g_assert(!s390_is_pv());
902636
         /*
902636
          * As operand exceptions have a lower priority than access exceptions,
902636
          * we check whether the memory area is writeable (injecting the
902636
@@ -292,14 +308,17 @@ void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb,
902636
         }
902636
     }
902636
     if (cc != 3) {
902636
-        if (s390_cpu_virt_mem_write(cpu, addr, ar, &schib,
902636
-                                    sizeof(schib)) != 0) {
902636
+        if (s390_is_pv()) {
902636
+            s390_cpu_pv_mem_write(cpu, addr, &schib, sizeof(schib));
902636
+        } else if (s390_cpu_virt_mem_write(cpu, addr, ar, &schib,
902636
+                                           sizeof(schib)) != 0) {
902636
             s390_cpu_virt_mem_handle_exc(cpu, ra);
902636
             return;
902636
         }
902636
     } else {
902636
         /* Access exceptions have a higher priority than cc3 */
902636
-        if (s390_cpu_virt_mem_check_write(cpu, addr, ar, sizeof(schib)) != 0) {
902636
+        if (!s390_is_pv() &&
902636
+            s390_cpu_virt_mem_check_write(cpu, addr, ar, sizeof(schib)) != 0) {
902636
             s390_cpu_virt_mem_handle_exc(cpu, ra);
902636
             return;
902636
         }
902636
@@ -336,7 +355,9 @@ int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
902636
     }
902636
     /* 0 - status pending, 1 - not status pending, 3 - not operational */
902636
     if (cc != 3) {
902636
-        if (s390_cpu_virt_mem_write(cpu, addr, ar, &irb, irb_len) != 0) {
902636
+        if (s390_is_pv()) {
902636
+            s390_cpu_pv_mem_write(cpu, addr, &irb, irb_len);
902636
+        } else if (s390_cpu_virt_mem_write(cpu, addr, ar, &irb, irb_len) != 0) {
902636
             s390_cpu_virt_mem_handle_exc(cpu, ra);
902636
             return -EFAULT;
902636
         }
902636
@@ -344,7 +365,8 @@ int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
902636
     } else {
902636
         irb_len = sizeof(irb) - sizeof(irb.emw);
902636
         /* Access exceptions have a higher priority than cc3 */
902636
-        if (s390_cpu_virt_mem_check_write(cpu, addr, ar, irb_len) != 0) {
902636
+        if (!s390_is_pv() &&
902636
+            s390_cpu_virt_mem_check_write(cpu, addr, ar, irb_len) != 0) {
902636
             s390_cpu_virt_mem_handle_exc(cpu, ra);
902636
             return -EFAULT;
902636
         }
902636
@@ -642,7 +664,9 @@ void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
902636
      * present CHSC sub-handlers ... if we ever need more, we should take
902636
      * care of req->len here first.
902636
      */
902636
-    if (s390_cpu_virt_mem_read(cpu, addr, reg, buf, sizeof(ChscReq))) {
902636
+    if (s390_is_pv()) {
902636
+        s390_cpu_pv_mem_read(cpu, addr, buf, sizeof(ChscReq));
902636
+    } else if (s390_cpu_virt_mem_read(cpu, addr, reg, buf, sizeof(ChscReq))) {
902636
         s390_cpu_virt_mem_handle_exc(cpu, ra);
902636
         return;
902636
     }
902636
@@ -675,11 +699,16 @@ void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
902636
         break;
902636
     }
902636
 
902636
-    if (!s390_cpu_virt_mem_write(cpu, addr + len, reg, res,
902636
-                                 be16_to_cpu(res->len))) {
902636
+    if (s390_is_pv()) {
902636
+        s390_cpu_pv_mem_write(cpu, addr + len, res, be16_to_cpu(res->len));
902636
         setcc(cpu, 0);    /* Command execution complete */
902636
     } else {
902636
-        s390_cpu_virt_mem_handle_exc(cpu, ra);
902636
+        if (!s390_cpu_virt_mem_write(cpu, addr + len, reg, res,
902636
+                                     be16_to_cpu(res->len))) {
902636
+            setcc(cpu, 0);    /* Command execution complete */
902636
+        } else {
902636
+            s390_cpu_virt_mem_handle_exc(cpu, ra);
902636
+        }
902636
     }
902636
 }
902636
 
902636
-- 
902636
2.27.0
902636