Extract the pba, pal and g_iota checks from reg_ioat() into a function.
Make it external so that it can also be used in a follow up change.

Signed-off-by: Konstantin Shkolnyy <[email protected]>
---
 hw/s390x/s390-pci-inst.c         | 52 ++++++++++++++++++++------------
 include/hw/s390x/s390-pci-inst.h |  2 ++
 2 files changed, 34 insertions(+), 20 deletions(-)

diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 98380526d1..b0af15ff15 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -1028,32 +1028,22 @@ bool s390_pci_is_translation_enabled(uint64_t g_iota)
     return ((g_iota >> 11) & 0x1) != 0; /* "T" bit */
 }
 
-static int reg_ioat(CPUS390XState *env, S390PCIBusDevice *pbdev, ZpciFib fib,
-                    uintptr_t ra)
+bool s390_pci_ioat_validate(S390PCIBusDevice *pbdev, uint64_t pba,
+                             uint64_t pal, uint64_t g_iota, Error **errp)
 {
-    uint64_t pba = ldq_be_p(&fib.pba);
-    uint64_t pal = ldq_be_p(&fib.pal);
-    uint64_t g_iota = ldq_be_p(&fib.iota);
     uint8_t dt = (g_iota >> 2) & 0x7;
     bool t = s390_pci_is_translation_enabled(g_iota);
 
-    pba &= ~0xfff;
-    pal |= 0xfff;
     if (pba > pal || pba < pbdev->zpci_fn.sdma || pal > pbdev->zpci_fn.edma) {
-        s390_program_interrupt(env, PGM_OPERAND, ra);
-        return -EINVAL;
+        return false;
     }
-
     /* currently we only support designation type 1 with translation */
     if (t && dt != ZPCI_IOTA_RTTO) {
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "unsupported ioat dt %d t %d\n", dt, t);
-        s390_program_interrupt(env, PGM_OPERAND, ra);
-        return -EINVAL;
+        error_setg(errp, "unsupported ioat dt %d t %d", dt, t);
+        return false;
     } else if (!t && !pbdev->rtr_avail) {
-        qemu_log_mask(LOG_GUEST_ERROR, "relaxed translation not allowed\n");
-        s390_program_interrupt(env, PGM_OPERAND, ra);
-        return -EINVAL;
+        error_setg(errp, "relaxed translation not allowed");
+        return false;
     }
 
     /*
@@ -1064,9 +1054,31 @@ static int reg_ioat(CPUS390XState *env, S390PCIBusDevice 
*pbdev, ZpciFib fib,
      * to QEMU for additional IOAT regions.
      */
     if (t && pal >= ZPCI_TABLE_SIZE_RT) {
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "ioat pal 0x%"PRIx64" exceeds max translatable 
address\n",
-                      pal);
+        error_setg(errp,
+                   "ioat pal 0x%"PRIx64" exceeds max translatable address",
+                   pal);
+        return false;
+    }
+    return true;
+}
+
+static int reg_ioat(CPUS390XState *env, S390PCIBusDevice *pbdev, ZpciFib fib,
+                    uintptr_t ra)
+{
+    Error *err = NULL;
+    uint64_t pba = ldq_be_p(&fib.pba);
+    uint64_t pal = ldq_be_p(&fib.pal);
+    uint64_t g_iota = ldq_be_p(&fib.iota);
+    bool t = s390_pci_is_translation_enabled(g_iota);
+
+    pba &= ~0xfff;
+    pal |= 0xfff;
+
+    if (!s390_pci_ioat_validate(pbdev, pba, pal, g_iota, &err)) {
+        if (err) {
+            qemu_log_mask(LOG_GUEST_ERROR, "%s\n", error_get_pretty(err));
+            error_free(err);
+        }
         s390_program_interrupt(env, PGM_OPERAND, ra);
         return -EINVAL;
     }
diff --git a/include/hw/s390x/s390-pci-inst.h b/include/hw/s390x/s390-pci-inst.h
index 38268c256e..3493d2ced0 100644
--- a/include/hw/s390x/s390-pci-inst.h
+++ b/include/hw/s390x/s390-pci-inst.h
@@ -100,6 +100,8 @@ typedef struct ZpciFib {
 
 int pci_dereg_irqs(S390PCIBusDevice *pbdev);
 void pci_dereg_ioat(S390PCIBusDevice *pbdev);
+bool s390_pci_ioat_validate(S390PCIBusDevice *pbdev, uint64_t pba,
+                             uint64_t pal, uint64_t g_iota, Error **errp);
 int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra);
 int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra);
 int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra);
-- 
2.34.1


Reply via email to