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) +{ + 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); -- 2.34.1
