On 9/11/2026 8:21 AM, Konstantin Shkolnyy wrote:
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         | 39 +++++++++++++++++++++-----------
  include/hw/s390x/s390-pci-inst.h |  2 ++
  2 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index f93db10c81..c7f96417cc 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -1024,29 +1024,42 @@ bool s390_pci_is_translation_enabled(uint64_t g_iota)
      return ((g_iota >> 11) & 0x1) != 0; /* "T" bit */
  }
+bool s390_pci_ioat_validate(S390PCIBusDevice *pbdev, uint64_t pba,
+                             uint64_t pal, uint64_t g_iota, bool report)
+{

Would it be better to pass Error **errp instead of report? I think QEMU that is the preferred QEMU style.


+    uint8_t dt = (g_iota >> 2) & 0x7;
+    bool t = s390_pci_is_translation_enabled(g_iota);
+
+    if (pba > pal || pba < pbdev->zpci_fn.sdma || pal > pbdev->zpci_fn.edma) {
+        return false;
+    }
+    /* currently we only support designation type 1 with translation */
+    if (t && dt != ZPCI_IOTA_RTTO) {
+        if (report) {
+            error_report("unsupported ioat dt %d t %d", dt, t);
+        }
+        return false;
+    }
+    if (!t && !pbdev->rtr_avail) {
+        if (report) {
+            error_report("relaxed translation not allowed");
+        }
+        return false;
+    }
+    return true;
+}
+
  static int reg_ioat(CPUS390XState *env, S390PCIBusDevice *pbdev, ZpciFib fib,
                      uintptr_t ra)
  {
      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;
-    }
-
-    /* currently we only support designation type 1 with translation */
-    if (t && dt != ZPCI_IOTA_RTTO) {
-        error_report("unsupported ioat dt %d t %d", dt, t);
-        s390_program_interrupt(env, PGM_OPERAND, ra);
-        return -EINVAL;
-    } else if (!t && !pbdev->rtr_avail) {
-        error_report("relaxed translation not allowed");
+    if (!s390_pci_ioat_validate(pbdev, pba, pal, g_iota, /*report=*/true)) {
          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..b53113ddbc 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, bool report);
  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);

Reply via email to