Re: [Qemu-devel] [PATCH v3 4/7] s390x/pci: rework PCI STORE BLOCK

2017-11-27 Thread Pierre Morel

On 23/11/2017 10:26, Thomas Huth wrote:

On 22.11.2017 23:05, Pierre Morel wrote:

Enhance the fault detection.

Fixup the precedence to check the destination path existance
before checking for the source accessibility.

Add the maxstbl entry to both the Query PCI Function Group
response and the PCIBusDevice structure.

Initialize the maxstbl to 128 per default until we get
the actual data from the hardware.

Signed-off-by: Pierre Morel 
Reviewed-by: Yi Min Zhao 
---
  hw/s390x/s390-pci-bus.h  |  1 +
  hw/s390x/s390-pci-inst.c | 63 ++--
  hw/s390x/s390-pci-inst.h |  2 +-
  3 files changed, 41 insertions(+), 25 deletions(-)

[...]

@@ -722,6 +733,10 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t 
r3, uint64_t gaddr,
  
  setcc(cpu, ZPCI_PCI_LS_OK);

  return 0;
+
+addressing_error:
+program_interrupt(env, PGM_SPECIFICATION, 6);


The label is called "addressing_error", but then you insert a
PGM_SPECIFICTATION ? According to the name of the label, I'd rather
expected a PGM_ADDRESSING here ... so maybe rename the label to
"spec_error" or something similar?


+return 0;
  }


  Thomas



I used this name because the error is really related to an addressing 
problem, alignment, crossing a boundary.

I agree, if no opinion against it I will change it to spec_error.

Thanks,

Pierre

--
Pierre Morel
Linux/KVM/QEMU in Böblingen - Germany




Re: [Qemu-devel] [PATCH v3 4/7] s390x/pci: rework PCI STORE BLOCK

2017-11-23 Thread Thomas Huth
On 22.11.2017 23:05, Pierre Morel wrote:
> Enhance the fault detection.
> 
> Fixup the precedence to check the destination path existance
> before checking for the source accessibility.
> 
> Add the maxstbl entry to both the Query PCI Function Group
> response and the PCIBusDevice structure.
> 
> Initialize the maxstbl to 128 per default until we get
> the actual data from the hardware.
> 
> Signed-off-by: Pierre Morel 
> Reviewed-by: Yi Min Zhao 
> ---
>  hw/s390x/s390-pci-bus.h  |  1 +
>  hw/s390x/s390-pci-inst.c | 63 
> ++--
>  hw/s390x/s390-pci-inst.h |  2 +-
>  3 files changed, 41 insertions(+), 25 deletions(-)
[...]
> @@ -722,6 +733,10 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, 
> uint8_t r3, uint64_t gaddr,
>  
>  setcc(cpu, ZPCI_PCI_LS_OK);
>  return 0;
> +
> +addressing_error:
> +program_interrupt(env, PGM_SPECIFICATION, 6);

The label is called "addressing_error", but then you insert a
PGM_SPECIFICTATION ? According to the name of the label, I'd rather
expected a PGM_ADDRESSING here ... so maybe rename the label to
"spec_error" or something similar?

> +return 0;
>  }

 Thomas



[Qemu-devel] [PATCH v3 4/7] s390x/pci: rework PCI STORE BLOCK

2017-11-22 Thread Pierre Morel
Enhance the fault detection.

Fixup the precedence to check the destination path existance
before checking for the source accessibility.

Add the maxstbl entry to both the Query PCI Function Group
response and the PCIBusDevice structure.

Initialize the maxstbl to 128 per default until we get
the actual data from the hardware.

Signed-off-by: Pierre Morel 
Reviewed-by: Yi Min Zhao 
---
 hw/s390x/s390-pci-bus.h  |  1 +
 hw/s390x/s390-pci-inst.c | 63 ++--
 hw/s390x/s390-pci-inst.h |  2 +-
 3 files changed, 41 insertions(+), 25 deletions(-)

diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h
index 560bd82..2993f0d 100644
--- a/hw/s390x/s390-pci-bus.h
+++ b/hw/s390x/s390-pci-bus.h
@@ -284,6 +284,7 @@ struct S390PCIBusDevice {
 uint64_t fmb_addr;
 uint8_t isc;
 uint16_t noi;
+uint16_t maxstbl;
 uint8_t sum;
 S390MsixInfo msix;
 AdapterRoutes routes;
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 2295412..fe6e042 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -294,6 +294,7 @@ int clp_service_call(S390CPU *cpu, uint8_t r2)
 stq_p(>msia, ZPCI_MSI_ADDR);
 stw_p(>mui, 0);
 stw_p(>i, 128);
+stw_p(>maxstbl, 128);
 resgrp->version = 0;
 
 stw_p(>hdr.rsp, CLP_RC_OK);
@@ -645,6 +646,7 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t 
r3, uint64_t gaddr,
 S390PCIBusDevice *pbdev;
 MemoryRegion *mr;
 MemTxResult result;
+uint64_t offset;
 int i;
 uint32_t fh;
 uint8_t pcias;
@@ -659,22 +661,10 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t 
r3, uint64_t gaddr,
 fh = env->regs[r1] >> 32;
 pcias = (env->regs[r1] >> 16) & 0xf;
 len = env->regs[r1] & 0xff;
+offset = env->regs[r3];
 
-if (pcias > 5) {
-DPRINTF("pcistb invalid space\n");
-setcc(cpu, ZPCI_PCI_LS_ERR);
-s390_set_status_code(env, r1, ZPCI_PCI_ST_INVAL_AS);
-return 0;
-}
-
-switch (len) {
-case 16:
-case 32:
-case 64:
-case 128:
-break;
-default:
-program_interrupt(env, PGM_SPECIFICATION, 6);
+if (!(fh & FH_MASK_ENABLE)) {
+setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
 return 0;
 }
 
@@ -686,12 +676,7 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t 
r3, uint64_t gaddr,
 }
 
 switch (pbdev->state) {
-case ZPCI_FS_RESERVED:
-case ZPCI_FS_STANDBY:
-case ZPCI_FS_DISABLED:
 case ZPCI_FS_PERMANENT_ERROR:
-setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
-return 0;
 case ZPCI_FS_ERROR:
 setcc(cpu, ZPCI_PCI_LS_ERR);
 s390_set_status_code(env, r1, ZPCI_PCI_ST_BLOCKED);
@@ -700,8 +685,34 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t 
r3, uint64_t gaddr,
 break;
 }
 
+if (pcias > 5) {
+DPRINTF("pcistb invalid space\n");
+setcc(cpu, ZPCI_PCI_LS_ERR);
+s390_set_status_code(env, r1, ZPCI_PCI_ST_INVAL_AS);
+return 0;
+}
+
+/* Verify the address, offset and length */
+/* offset must be a multiple of 8 */
+if (offset % 8) {
+goto addressing_error;
+}
+/* Length must be greater than 8, a multiple of 8 */
+/* and not greater than maxstbl */
+if ((len <= 8) || (len % 8) || (len > pbdev->maxstbl)) {
+goto addressing_error;
+}
+/* Do not cross a 4K-byte boundary */
+if (((offset & 0xfff) + len) > 0x1000) {
+goto addressing_error;
+}
+/* Guest address must be double word aligned */
+if (gaddr & 0x07UL) {
+goto addressing_error;
+}
+
 mr = pbdev->pdev->io_regions[pcias].memory;
-if (!memory_region_access_valid(mr, env->regs[r3], len, true)) {
+if (!memory_region_access_valid(mr, offset, len, true)) {
 program_interrupt(env, PGM_OPERAND, 6);
 return 0;
 }
@@ -711,9 +722,9 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t 
r3, uint64_t gaddr,
 }
 
 for (i = 0; i < len / 8; i++) {
-result = memory_region_dispatch_write(mr, env->regs[r3] + i * 8,
- ldq_p(buffer + i * 8), 8,
- MEMTXATTRS_UNSPECIFIED);
+result = memory_region_dispatch_write(mr, offset + i * 8,
+  ldq_p(buffer + i * 8), 8,
+  MEMTXATTRS_UNSPECIFIED);
 if (result != MEMTX_OK) {
 program_interrupt(env, PGM_OPERAND, 6);
 return 0;
@@ -722,6 +733,10 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t 
r3, uint64_t gaddr,
 
 setcc(cpu, ZPCI_PCI_LS_OK);
 return 0;
+
+addressing_error:
+program_interrupt(env, PGM_SPECIFICATION, 6);
+return 0;
 }
 
 static int reg_irqs(CPUS390XState *env, S390PCIBusDevice *pbdev, ZpciFib fib)
diff --git