yeahuh / rpms / qemu-kvm

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