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

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