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);