qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/2] s390/pci: add 2 more features
@ 2014-12-05  9:19 Frank Blaschka
  2014-12-05  9:19 ` [Qemu-devel] [PATCH 1/2] s390/pci: add error event support Frank Blaschka
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Frank Blaschka @ 2014-12-05  9:19 UTC (permalink / raw)
  To: cornelia.huck, borntraeger, agraf; +Cc: Frank Blaschka, qemu-devel

Coni, Alex, Christian,

here are 2 more s390/pci features on top of the base pci support.
Thx!

Frank

Frank Blaschka (2):
  s390/pci: add error event support
  s390/pci: implement stpcifc instruction

 hw/s390x/s390-pci-bus.c  |  50 ++++++++++++++--
 hw/s390x/s390-pci-bus.h  |  36 +++++++++++-
 hw/s390x/s390-pci-inst.c | 148 ++++++++++++++++++++++++++++++++++++++++++++---
 hw/s390x/s390-pci-inst.h |   1 +
 target-s390x/kvm.c       |   9 ++-
 5 files changed, 227 insertions(+), 17 deletions(-)

-- 
1.8.5.5

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PATCH 1/2] s390/pci: add error event support
  2014-12-05  9:19 [Qemu-devel] [PATCH 0/2] s390/pci: add 2 more features Frank Blaschka
@ 2014-12-05  9:19 ` Frank Blaschka
  2014-12-09 13:31   ` Cornelia Huck
  2014-12-05  9:19 ` [Qemu-devel] [PATCH 2/2] s390/pci: implement stpcifc instruction Frank Blaschka
  2014-12-09 13:31 ` [Qemu-devel] [PATCH 0/2] s390/pci: add 2 more features Cornelia Huck
  2 siblings, 1 reply; 7+ messages in thread
From: Frank Blaschka @ 2014-12-05  9:19 UTC (permalink / raw)
  To: cornelia.huck, borntraeger, agraf; +Cc: Frank Blaschka, qemu-devel

From: Frank Blaschka <frank.blaschka@de.ibm.com>

This patch adds support to generate s390 pci error events

Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
---
 hw/s390x/s390-pci-bus.c  | 50 +++++++++++++++++++++++++---
 hw/s390x/s390-pci-bus.h  | 35 +++++++++++++++++++-
 hw/s390x/s390-pci-inst.c | 86 ++++++++++++++++++++++++++++++++++++++++++------
 3 files changed, 155 insertions(+), 16 deletions(-)

diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 06d153a..c1b57d0 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -52,6 +52,9 @@ int chsc_sei_nt2_get_event(void *res)
             eccdf = (PciCcdfErr *)nt2_res->ccdf;
             eccdf->fid = cpu_to_be32(sei_cont->fid);
             eccdf->fh = cpu_to_be32(sei_cont->fh);
+            eccdf->e = cpu_to_be32(sei_cont->e);
+            eccdf->faddr = cpu_to_be64(sei_cont->faddr);
+            eccdf->pec = cpu_to_be16(sei_cont->pec);
             break;
         case 2: /* availability event */
             accdf = (PciCcdfAvail *)nt2_res->ccdf;
@@ -184,8 +187,8 @@ S390PCIBusDevice *s390_pci_find_dev_by_fh(uint32_t fh)
     return NULL;
 }
 
-static void s390_pci_generate_plug_event(uint16_t pec, uint32_t fh,
-                                         uint32_t fid)
+static void s390_pci_generate_event(uint8_t cc, uint16_t pec, uint32_t fh,
+                                    uint32_t fid, uint64_t faddr, uint32_t e)
 {
     SeiContainer *sei_cont = g_malloc0(sizeof(SeiContainer));
     S390pciState *s = S390_PCI_HOST_BRIDGE(
@@ -197,13 +200,28 @@ static void s390_pci_generate_plug_event(uint16_t pec, uint32_t fh,
 
     sei_cont->fh = fh;
     sei_cont->fid = fid;
-    sei_cont->cc = 2;
+    sei_cont->cc = cc;
     sei_cont->pec = pec;
+    sei_cont->faddr = faddr;
+    sei_cont->e = e;
 
     QTAILQ_INSERT_TAIL(&s->pending_sei, sei_cont, link);
     css_generate_css_crws(0);
 }
 
+static void s390_pci_generate_plug_event(uint16_t pec, uint32_t fh,
+                                         uint32_t fid)
+{
+    s390_pci_generate_event(2, pec, fh, fid, 0, 0);
+}
+
+static void s390_pci_generate_error_event(uint16_t pec, uint32_t fh,
+                                          uint32_t fid, uint64_t faddr,
+                                          uint32_t e)
+{
+    s390_pci_generate_event(1, pec, fh, fid, faddr, e);
+}
+
 static void s390_pci_set_irq(void *opaque, int irq, int level)
 {
     /* nothing to do */
@@ -313,10 +331,30 @@ static IOMMUTLBEntry s390_translate_iommu(MemoryRegion *iommu, hwaddr addr,
         return ret;
     }
 
+    if (!pbdev->g_iota) {
+        pbdev->error_state = true;
+        pbdev->lgstg_blocked = true;
+        s390_pci_generate_error_event(ERR_EVENT_INVALAS, pbdev->fh, pbdev->fid,
+                                      addr, 0);
+        return ret;
+    }
+
+    if (addr < pbdev->pba || addr > pbdev->pal) {
+        pbdev->error_state = true;
+        pbdev->lgstg_blocked = true;
+        s390_pci_generate_error_event(ERR_EVENT_OORANGE, pbdev->fh, pbdev->fid,
+                                      addr, 0);
+        return ret;
+    }
+
     pte = s390_guest_io_table_walk(s390_pci_get_table_origin(pbdev->g_iota),
                                    addr);
 
     if (!pte) {
+        pbdev->error_state = true;
+        pbdev->lgstg_blocked = true;
+        s390_pci_generate_error_event(ERR_EVENT_SERR, pbdev->fh, pbdev->fid,
+                                      addr, ERR_EVENT_Q_BIT);
         return ret;
     }
 
@@ -353,7 +391,7 @@ static uint8_t set_ind_atomic(uint64_t ind_loc, uint8_t to_be_set)
 
     ind_addr = cpu_physical_memory_map(ind_loc, &len, 1);
     if (!ind_addr) {
-        error_report("%s: unable to access indicator", __func__);
+        s390_pci_generate_error_event(ERR_EVENT_AIRERR, 0, 0, 0, 0);
         return -1;
     }
     do {
@@ -374,12 +412,14 @@ static void s390_msi_ctrl_write(void *opaque, hwaddr addr, uint64_t data,
     uint32_t vec = data & ZPCI_MSI_VEC_MASK;
     uint64_t ind_bit;
     uint32_t sum_bit;
+    uint32_t e = 0;
 
     DPRINTF("write_msix data 0x%lx fid %d vec 0x%x\n", data, fid, vec);
 
     pbdev = s390_pci_find_dev_by_fid(fid);
     if (!pbdev) {
-        DPRINTF("msix_notify no dev\n");
+        e |= (vec << ERR_EVENT_MVN_OFFSET);
+        s390_pci_generate_error_event(ERR_EVENT_NOMSI, 0, fid, addr, e);
         return;
     }
 
diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h
index fc567b7..2a9f735 100644
--- a/hw/s390x/s390-pci-bus.h
+++ b/hw/s390x/s390-pci-bus.h
@@ -33,6 +33,31 @@
 #define HP_EVENT_CONFIGURED_TO_STBRES 0x0304
 #define HP_EVENT_STANDBY_TO_RESERVED  0x0308
 
+#define ERR_EVENT_INVALAS 0x1
+#define ERR_EVENT_OORANGE 0x2
+#define ERR_EVENT_INVALTF 0x3
+#define ERR_EVENT_TPROTE  0x4
+#define ERR_EVENT_APROTE  0x5
+#define ERR_EVENT_KEYE    0x6
+#define ERR_EVENT_INVALTE 0x7
+#define ERR_EVENT_INVALTL 0x8
+#define ERR_EVENT_TT      0x9
+#define ERR_EVENT_INVALMS 0xa
+#define ERR_EVENT_SERR    0xb
+#define ERR_EVENT_NOMSI   0x10
+#define ERR_EVENT_INVALBV 0x11
+#define ERR_EVENT_AIBV    0x12
+#define ERR_EVENT_AIRERR  0x13
+#define ERR_EVENT_FMBA    0x2a
+#define ERR_EVENT_FMBUP   0x2b
+#define ERR_EVENT_FMBPRO  0x2c
+#define ERR_EVENT_CCONF   0x30
+#define ERR_EVENT_SERVAC  0x3a
+#define ERR_EVENT_PERMERR 0x3b
+
+#define ERR_EVENT_Q_BIT 0x2
+#define ERR_EVENT_MVN_OFFSET 16
+
 #define ZPCI_MSI_VEC_BITS 11
 #define ZPCI_MSI_VEC_MASK 0x7ff
 
@@ -130,13 +155,15 @@ typedef struct SeiContainer {
     uint32_t fh;
     uint8_t cc;
     uint16_t pec;
+    uint64_t faddr;
+    uint32_t e;
 } SeiContainer;
 
 typedef struct PciCcdfErr {
     uint32_t reserved1;
     uint32_t fh;
     uint32_t fid;
-    uint32_t reserved2;
+    uint32_t e;
     uint64_t faddr;
     uint32_t reserved3;
     uint16_t reserved4;
@@ -189,10 +216,16 @@ typedef struct S390MsixInfo {
 typedef struct S390PCIBusDevice {
     PCIDevice *pdev;
     bool configured;
+    bool error_state;
+    bool lgstg_blocked;
     uint32_t fh;
     uint32_t fid;
     uint64_t g_iota;
+    uint64_t pba;
+    uint64_t pal;
     uint8_t isc;
+    uint16_t noi;
+    uint8_t sum;
     S390MsixInfo msix;
     AdapterRoutes routes;
     AddressSpace as;
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index e233046..8648594 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -230,6 +230,8 @@ int clp_service_call(S390CPU *cpu, uint8_t r2)
             break;
         case CLP_SET_DISABLE_PCI_FN:
             pbdev->fh = pbdev->fh & ~(1 << ENABLE_BIT_OFFSET);
+            pbdev->error_state = false;
+            pbdev->lgstg_blocked = false;
             stl_p(&ressetpci->fh, pbdev->fh);
             stw_p(&ressetpci->hdr.rsp, CLP_RC_OK);
             break;
@@ -330,6 +332,12 @@ int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
         return 0;
     }
 
+    if (pbdev->lgstg_blocked) {
+        setcc(cpu, ZPCI_PCI_LS_ERR);
+        s390_set_status_code(env, r2, ZPCI_PCI_ST_BLOCKED);
+        return 0;
+    }
+
     if (pcias < 6) {
         if ((8 - (offset & 0x7)) < len) {
             program_interrupt(env, PGM_OPERAND, 4);
@@ -440,6 +448,12 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
         return 0;
     }
 
+    if (pbdev->lgstg_blocked) {
+        setcc(cpu, ZPCI_PCI_LS_ERR);
+        s390_set_status_code(env, r2, ZPCI_PCI_ST_BLOCKED);
+        return 0;
+    }
+
     data = env->regs[r1];
     if (pcias < 6) {
         if ((8 - (offset & 0x7)) < len) {
@@ -586,6 +600,12 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr)
         return 0;
     }
 
+    if (pbdev->lgstg_blocked) {
+        setcc(cpu, ZPCI_PCI_LS_ERR);
+        s390_set_status_code(env, r1, ZPCI_PCI_ST_BLOCKED);
+        return 0;
+    }
+
     mr = pbdev->pdev->io_regions[pcias].memory;
     if (!memory_region_access_valid(mr, env->regs[r3], len, true)) {
         program_interrupt(env, PGM_ADDRESSING, 6);
@@ -621,6 +641,9 @@ static int reg_irqs(CPUS390XState *env, S390PCIBusDevice *pbdev, ZpciFib fib)
     pbdev->routes.adapter.summary_offset = FIB_DATA_AISBO(ldl_p(&fib.data));
     pbdev->routes.adapter.ind_addr = ldq_p(&fib.aibv);
     pbdev->routes.adapter.ind_offset = FIB_DATA_AIBVO(ldl_p(&fib.data));
+    pbdev->isc = FIB_DATA_ISC(ldl_p(&fib.data));
+    pbdev->noi = FIB_DATA_NOI(ldl_p(&fib.data));
+    pbdev->sum = FIB_DATA_SUM(ldl_p(&fib.data));
 
     DPRINTF("reg_irqs adapter id %d\n", pbdev->routes.adapter.adapter_id);
     return 0;
@@ -638,11 +661,47 @@ static int dereg_irqs(S390PCIBusDevice *pbdev)
     pbdev->routes.adapter.summary_offset = 0;
     pbdev->routes.adapter.ind_addr = 0;
     pbdev->routes.adapter.ind_offset = 0;
+    pbdev->isc = 0;
+    pbdev->noi = 0;
+    pbdev->sum = 0;
 
     DPRINTF("dereg_irqs adapter id %d\n", pbdev->routes.adapter.adapter_id);
     return 0;
 }
 
+static int reg_ioat(CPUS390XState *env, S390PCIBusDevice *pbdev, ZpciFib fib)
+{
+    uint64_t pba = ldq_p(&fib.pba);
+    uint64_t pal = ldq_p(&fib.pal);
+    uint64_t g_iota = ldq_p(&fib.iota);
+    uint8_t dt = (g_iota >> 2) & 0x7;
+    uint8_t t = (g_iota >> 11) & 0x1;
+
+    if (pba > pal || pba < ZPCI_SDMA_ADDR || pal > ZPCI_EDMA_ADDR) {
+        program_interrupt(env, PGM_OPERAND, 6);
+        return -EINVAL;
+    }
+
+    /* currently we only support designation type 1 with translation */
+    if (!(dt == ZPCI_IOTA_RTTO && t)) {
+        error_report("unsupported ioat dt %d t %d", dt, t);
+        program_interrupt(env, PGM_OPERAND, 6);
+        return -EINVAL;
+    }
+
+    pbdev->pba = pba;
+    pbdev->pal = pal;
+    pbdev->g_iota = g_iota;
+    return 0;
+}
+
+static void dereg_ioat(S390PCIBusDevice *pbdev)
+{
+    pbdev->pba = 0;
+    pbdev->pal = 0;
+    pbdev->g_iota = 0;
+}
+
 int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
 {
     CPUS390XState *env = &cpu->env;
@@ -650,6 +709,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
     uint32_t fh;
     ZpciFib fib;
     S390PCIBusDevice *pbdev;
+    uint64_t cc = ZPCI_PCI_LS_OK;
 
     cpu_synchronize_state(CPU(cpu));
 
@@ -676,36 +736,42 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
     cpu_physical_memory_read(fiba, (uint8_t *)&fib, sizeof(fib));
 
     switch (oc) {
-    case ZPCI_MOD_FC_REG_INT: {
-        pbdev->isc = FIB_DATA_ISC(ldl_p(&fib.data));
-        reg_irqs(env, pbdev, fib);
+    case ZPCI_MOD_FC_REG_INT:
+        if (reg_irqs(env, pbdev, fib)) {
+            cc = ZPCI_PCI_LS_ERR;
+        }
         break;
-    }
     case ZPCI_MOD_FC_DEREG_INT:
         dereg_irqs(pbdev);
         break;
     case ZPCI_MOD_FC_REG_IOAT:
-        if (ldq_p(&fib.pba) > ldq_p(&fib.pal)) {
-            program_interrupt(&cpu->env, PGM_OPERAND, 6);
-            return 0;
+        if (reg_ioat(env, pbdev, fib)) {
+            cc = ZPCI_PCI_LS_ERR;
         }
-        pbdev->g_iota = ldq_p(&fib.iota);
         break;
     case ZPCI_MOD_FC_DEREG_IOAT:
+        dereg_ioat(pbdev);
         break;
     case ZPCI_MOD_FC_REREG_IOAT:
+        dereg_ioat(pbdev);
+        if (reg_ioat(env, pbdev, fib)) {
+            cc = ZPCI_PCI_LS_ERR;
+        }
         break;
     case ZPCI_MOD_FC_RESET_ERROR:
+        pbdev->error_state = false;
+        pbdev->lgstg_blocked = false;
         break;
     case ZPCI_MOD_FC_RESET_BLOCK:
+        pbdev->lgstg_blocked = false;
         break;
     case ZPCI_MOD_FC_SET_MEASURE:
         break;
     default:
         program_interrupt(&cpu->env, PGM_OPERAND, 6);
-        return 0;
+        cc = ZPCI_PCI_LS_ERR;
     }
 
-    setcc(cpu, ZPCI_PCI_LS_OK);
+    setcc(cpu, cc);
     return 0;
 }
-- 
1.8.5.5

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PATCH 2/2] s390/pci: implement stpcifc instruction
  2014-12-05  9:19 [Qemu-devel] [PATCH 0/2] s390/pci: add 2 more features Frank Blaschka
  2014-12-05  9:19 ` [Qemu-devel] [PATCH 1/2] s390/pci: add error event support Frank Blaschka
@ 2014-12-05  9:19 ` Frank Blaschka
  2014-12-05 13:15   ` Thomas Huth
  2014-12-09 13:31 ` [Qemu-devel] [PATCH 0/2] s390/pci: add 2 more features Cornelia Huck
  2 siblings, 1 reply; 7+ messages in thread
From: Frank Blaschka @ 2014-12-05  9:19 UTC (permalink / raw)
  To: cornelia.huck, borntraeger, agraf; +Cc: Frank Blaschka, qemu-devel

From: Frank Blaschka <frank.blaschka@de.ibm.com>

This patch implements the last remaining s390 pci instruction
to query the function information block.

Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
---
 hw/s390x/s390-pci-bus.h  |  1 +
 hw/s390x/s390-pci-inst.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++
 hw/s390x/s390-pci-inst.h |  1 +
 target-s390x/kvm.c       |  9 +++++--
 4 files changed, 73 insertions(+), 2 deletions(-)

diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h
index 2a9f735..35f4da5 100644
--- a/hw/s390x/s390-pci-bus.h
+++ b/hw/s390x/s390-pci-bus.h
@@ -223,6 +223,7 @@ typedef struct S390PCIBusDevice {
     uint64_t g_iota;
     uint64_t pba;
     uint64_t pal;
+    uint64_t fmb_addr;
     uint8_t isc;
     uint16_t noi;
     uint8_t sum;
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 8648594..f503665 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -766,6 +766,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
         pbdev->lgstg_blocked = false;
         break;
     case ZPCI_MOD_FC_SET_MEASURE:
+        pbdev->fmb_addr = ldq_p(&fib.fmb_addr);
         break;
     default:
         program_interrupt(&cpu->env, PGM_OPERAND, 6);
@@ -775,3 +776,66 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
     setcc(cpu, cc);
     return 0;
 }
+
+int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
+{
+    CPUS390XState *env = &cpu->env;
+    uint32_t fh;
+    ZpciFib fib;
+    S390PCIBusDevice *pbdev;
+    uint32_t data;
+    uint64_t cc = ZPCI_PCI_LS_OK;
+
+    cpu_synchronize_state(CPU(cpu));
+
+    if (env->psw.mask & PSW_MASK_PSTATE) {
+        program_interrupt(env, PGM_PRIVILEGED, 6);
+        return 0;
+    }
+
+    fh = env->regs[r1] >> 32;
+
+    if (fiba & 0x7) {
+        program_interrupt(env, PGM_SPECIFICATION, 6);
+        return 0;
+    }
+
+    pbdev = s390_pci_find_dev_by_fh(fh);
+    if (!pbdev) {
+        setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
+        return 0;
+    }
+
+    memset(&fib, 0, sizeof(fib));
+    stq_p(&fib.pba, pbdev->pba);
+    stq_p(&fib.pal, pbdev->pal);
+    stq_p(&fib.iota, pbdev->g_iota);
+    stq_p(&fib.aibv, pbdev->routes.adapter.ind_addr);
+    stq_p(&fib.aisb, pbdev->routes.adapter.summary_addr);
+    stq_p(&fib.fmb_addr, pbdev->fmb_addr);
+
+    data = (pbdev->isc << 28) | (pbdev->noi << 16) |
+           (pbdev->routes.adapter.ind_offset << 8) | (pbdev->sum << 7) |
+           pbdev->routes.adapter.summary_offset;
+    stw_p(&fib.data, data);
+
+    if (pbdev->fh >> ENABLE_BIT_OFFSET) {
+        fib.fc |= 0x80;
+    }
+
+    if (pbdev->error_state) {
+        fib.fc |= 0x40;
+    }
+
+    if (pbdev->lgstg_blocked) {
+        fib.fc |= 0x20;
+    }
+
+    if (pbdev->g_iota) {
+        fib.fc |= 0x10;
+    }
+
+    cpu_physical_memory_write(fiba, (uint8_t *)&fib, sizeof(fib));
+    setcc(cpu, cc);
+    return 0;
+}
diff --git a/hw/s390x/s390-pci-inst.h b/hw/s390x/s390-pci-inst.h
index 609e3e0..1c2f458 100644
--- a/hw/s390x/s390-pci-inst.h
+++ b/hw/s390x/s390-pci-inst.h
@@ -283,5 +283,6 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2);
 int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2);
 int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr);
 int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba);
+int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba);
 
 #endif
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 32af46b..b70d482 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -876,8 +876,13 @@ static int kvm_pcistg_service_call(S390CPU *cpu, struct kvm_run *run)
 
 static int kvm_stpcifc_service_call(S390CPU *cpu, struct kvm_run *run)
 {
-    qemu_log_mask(LOG_UNIMP, "STPCIFC missing\n");
-    return 0;
+    uint8_t r1 = (run->s390_sieic.ipa & 0x00f0) >> 4;
+    uint64_t fiba;
+
+    cpu_synchronize_state(CPU(cpu));
+    fiba = get_base_disp_rxy(cpu, run);
+
+    return stpcifc_service_call(cpu, r1, fiba);
 }
 
 static int kvm_sic_service_call(S390CPU *cpu, struct kvm_run *run)
-- 
1.8.5.5

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH 2/2] s390/pci: implement stpcifc instruction
  2014-12-05  9:19 ` [Qemu-devel] [PATCH 2/2] s390/pci: implement stpcifc instruction Frank Blaschka
@ 2014-12-05 13:15   ` Thomas Huth
  2014-12-08  8:00     ` Frank Blaschka
  0 siblings, 1 reply; 7+ messages in thread
From: Thomas Huth @ 2014-12-05 13:15 UTC (permalink / raw)
  To: Frank Blaschka
  Cc: cornelia.huck, borntraeger, Frank Blaschka, agraf, qemu-devel


 Hi Frank,

On Fri,  5 Dec 2014 10:19:59 +0100
Frank Blaschka <blaschka@linux.vnet.ibm.com> wrote:

> From: Frank Blaschka <frank.blaschka@de.ibm.com>
> 
> This patch implements the last remaining s390 pci instruction
> to query the function information block.
> 
> Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
> ---
>  hw/s390x/s390-pci-bus.h  |  1 +
>  hw/s390x/s390-pci-inst.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++
>  hw/s390x/s390-pci-inst.h |  1 +
>  target-s390x/kvm.c       |  9 +++++--
>  4 files changed, 73 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h
> index 2a9f735..35f4da5 100644
> --- a/hw/s390x/s390-pci-bus.h
> +++ b/hw/s390x/s390-pci-bus.h
> @@ -223,6 +223,7 @@ typedef struct S390PCIBusDevice {
>      uint64_t g_iota;
>      uint64_t pba;
>      uint64_t pal;
> +    uint64_t fmb_addr;
>      uint8_t isc;
>      uint16_t noi;
>      uint8_t sum;
> diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
> index 8648594..f503665 100644
> --- a/hw/s390x/s390-pci-inst.c
> +++ b/hw/s390x/s390-pci-inst.c
> @@ -766,6 +766,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
>          pbdev->lgstg_blocked = false;
>          break;
>      case ZPCI_MOD_FC_SET_MEASURE:
> +        pbdev->fmb_addr = ldq_p(&fib.fmb_addr);
>          break;
>      default:
>          program_interrupt(&cpu->env, PGM_OPERAND, 6);
> @@ -775,3 +776,66 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
>      setcc(cpu, cc);
>      return 0;
>  }
> +
> +int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
> +{
> +    CPUS390XState *env = &cpu->env;
> +    uint32_t fh;
> +    ZpciFib fib;
> +    S390PCIBusDevice *pbdev;
> +    uint32_t data;
> +    uint64_t cc = ZPCI_PCI_LS_OK;
> +
> +    cpu_synchronize_state(CPU(cpu));

You're calling cpu_synchronize_state twice, one time in
kvm_stpcifc_service_call() already and one time here. So I think
you could remove the call here.

> +    if (env->psw.mask & PSW_MASK_PSTATE) {
> +        program_interrupt(env, PGM_PRIVILEGED, 6);
> +        return 0;
> +    }
> +
> +    fh = env->regs[r1] >> 32;
> +
> +    if (fiba & 0x7) {
> +        program_interrupt(env, PGM_SPECIFICATION, 6);
> +        return 0;
> +    }
> +
> +    pbdev = s390_pci_find_dev_by_fh(fh);
> +    if (!pbdev) {
> +        setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
> +        return 0;
> +    }
> +
> +    memset(&fib, 0, sizeof(fib));
> +    stq_p(&fib.pba, pbdev->pba);
> +    stq_p(&fib.pal, pbdev->pal);
> +    stq_p(&fib.iota, pbdev->g_iota);
> +    stq_p(&fib.aibv, pbdev->routes.adapter.ind_addr);
> +    stq_p(&fib.aisb, pbdev->routes.adapter.summary_addr);
> +    stq_p(&fib.fmb_addr, pbdev->fmb_addr);
> +
> +    data = (pbdev->isc << 28) | (pbdev->noi << 16) |
> +           (pbdev->routes.adapter.ind_offset << 8) | (pbdev->sum << 7) |
> +           pbdev->routes.adapter.summary_offset;
> +    stw_p(&fib.data, data);
> +
> +    if (pbdev->fh >> ENABLE_BIT_OFFSET) {
> +        fib.fc |= 0x80;
> +    }
> +
> +    if (pbdev->error_state) {
> +        fib.fc |= 0x40;
> +    }
> +
> +    if (pbdev->lgstg_blocked) {
> +        fib.fc |= 0x20;
> +    }
> +
> +    if (pbdev->g_iota) {
> +        fib.fc |= 0x10;
> +    }
> +
> +    cpu_physical_memory_write(fiba, (uint8_t *)&fib, sizeof(fib));
> +    setcc(cpu, cc);
> +    return 0;
> +}
> diff --git a/hw/s390x/s390-pci-inst.h b/hw/s390x/s390-pci-inst.h
> index 609e3e0..1c2f458 100644
> --- a/hw/s390x/s390-pci-inst.h
> +++ b/hw/s390x/s390-pci-inst.h
> @@ -283,5 +283,6 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2);
>  int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2);
>  int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr);
>  int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba);
> +int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba);
> 
>  #endif
> diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
> index 32af46b..b70d482 100644
> --- a/target-s390x/kvm.c
> +++ b/target-s390x/kvm.c
> @@ -876,8 +876,13 @@ static int kvm_pcistg_service_call(S390CPU *cpu, struct kvm_run *run)
> 
>  static int kvm_stpcifc_service_call(S390CPU *cpu, struct kvm_run *run)
>  {
> -    qemu_log_mask(LOG_UNIMP, "STPCIFC missing\n");
> -    return 0;
> +    uint8_t r1 = (run->s390_sieic.ipa & 0x00f0) >> 4;
> +    uint64_t fiba;
> +
> +    cpu_synchronize_state(CPU(cpu));
> +    fiba = get_base_disp_rxy(cpu, run);
> +
> +    return stpcifc_service_call(cpu, r1, fiba);
>  }
> 
>  static int kvm_sic_service_call(S390CPU *cpu, struct kvm_run *run)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH 2/2] s390/pci: implement stpcifc instruction
  2014-12-05 13:15   ` Thomas Huth
@ 2014-12-08  8:00     ` Frank Blaschka
  0 siblings, 0 replies; 7+ messages in thread
From: Frank Blaschka @ 2014-12-08  8:00 UTC (permalink / raw)
  To: Thomas Huth; +Cc: cornelia.huck, borntraeger, Frank Blaschka, agraf, qemu-devel

On Fri, Dec 05, 2014 at 02:15:07PM +0100, Thomas Huth wrote:
> 
>  Hi Frank,
> 
> On Fri,  5 Dec 2014 10:19:59 +0100
> Frank Blaschka <blaschka@linux.vnet.ibm.com> wrote:
> 
> > From: Frank Blaschka <frank.blaschka@de.ibm.com>
> > 
> > This patch implements the last remaining s390 pci instruction
> > to query the function information block.
> > 
> > Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
> > ---
> >  hw/s390x/s390-pci-bus.h  |  1 +
> >  hw/s390x/s390-pci-inst.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++
> >  hw/s390x/s390-pci-inst.h |  1 +
> >  target-s390x/kvm.c       |  9 +++++--
> >  4 files changed, 73 insertions(+), 2 deletions(-)
> > 
> > diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h
> > index 2a9f735..35f4da5 100644
> > --- a/hw/s390x/s390-pci-bus.h
> > +++ b/hw/s390x/s390-pci-bus.h
> > @@ -223,6 +223,7 @@ typedef struct S390PCIBusDevice {
> >      uint64_t g_iota;
> >      uint64_t pba;
> >      uint64_t pal;
> > +    uint64_t fmb_addr;
> >      uint8_t isc;
> >      uint16_t noi;
> >      uint8_t sum;
> > diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
> > index 8648594..f503665 100644
> > --- a/hw/s390x/s390-pci-inst.c
> > +++ b/hw/s390x/s390-pci-inst.c
> > @@ -766,6 +766,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
> >          pbdev->lgstg_blocked = false;
> >          break;
> >      case ZPCI_MOD_FC_SET_MEASURE:
> > +        pbdev->fmb_addr = ldq_p(&fib.fmb_addr);
> >          break;
> >      default:
> >          program_interrupt(&cpu->env, PGM_OPERAND, 6);
> > @@ -775,3 +776,66 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
> >      setcc(cpu, cc);
> >      return 0;
> >  }
> > +
> > +int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
> > +{
> > +    CPUS390XState *env = &cpu->env;
> > +    uint32_t fh;
> > +    ZpciFib fib;
> > +    S390PCIBusDevice *pbdev;
> > +    uint32_t data;
> > +    uint64_t cc = ZPCI_PCI_LS_OK;
> > +
> > +    cpu_synchronize_state(CPU(cpu));
> 
> You're calling cpu_synchronize_state twice, one time in
> kvm_stpcifc_service_call() already and one time here. So I think
> you could remove the call here.
>

Hi Thomas,

looks like this is not the only duplicate cpu_synchronize_state.
Will create an add on patch to remove all unnecessary calls to
cpu_synchronize_state. Thx for the finding.

Frank

> > +    if (env->psw.mask & PSW_MASK_PSTATE) {
> > +        program_interrupt(env, PGM_PRIVILEGED, 6);
> > +        return 0;
> > +    }
> > +
> > +    fh = env->regs[r1] >> 32;
> > +
> > +    if (fiba & 0x7) {
> > +        program_interrupt(env, PGM_SPECIFICATION, 6);
> > +        return 0;
> > +    }
> > +
> > +    pbdev = s390_pci_find_dev_by_fh(fh);
> > +    if (!pbdev) {
> > +        setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
> > +        return 0;
> > +    }
> > +
> > +    memset(&fib, 0, sizeof(fib));
> > +    stq_p(&fib.pba, pbdev->pba);
> > +    stq_p(&fib.pal, pbdev->pal);
> > +    stq_p(&fib.iota, pbdev->g_iota);
> > +    stq_p(&fib.aibv, pbdev->routes.adapter.ind_addr);
> > +    stq_p(&fib.aisb, pbdev->routes.adapter.summary_addr);
> > +    stq_p(&fib.fmb_addr, pbdev->fmb_addr);
> > +
> > +    data = (pbdev->isc << 28) | (pbdev->noi << 16) |
> > +           (pbdev->routes.adapter.ind_offset << 8) | (pbdev->sum << 7) |
> > +           pbdev->routes.adapter.summary_offset;
> > +    stw_p(&fib.data, data);
> > +
> > +    if (pbdev->fh >> ENABLE_BIT_OFFSET) {
> > +        fib.fc |= 0x80;
> > +    }
> > +
> > +    if (pbdev->error_state) {
> > +        fib.fc |= 0x40;
> > +    }
> > +
> > +    if (pbdev->lgstg_blocked) {
> > +        fib.fc |= 0x20;
> > +    }
> > +
> > +    if (pbdev->g_iota) {
> > +        fib.fc |= 0x10;
> > +    }
> > +
> > +    cpu_physical_memory_write(fiba, (uint8_t *)&fib, sizeof(fib));
> > +    setcc(cpu, cc);
> > +    return 0;
> > +}
> > diff --git a/hw/s390x/s390-pci-inst.h b/hw/s390x/s390-pci-inst.h
> > index 609e3e0..1c2f458 100644
> > --- a/hw/s390x/s390-pci-inst.h
> > +++ b/hw/s390x/s390-pci-inst.h
> > @@ -283,5 +283,6 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2);
> >  int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2);
> >  int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr);
> >  int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba);
> > +int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba);
> > 
> >  #endif
> > diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
> > index 32af46b..b70d482 100644
> > --- a/target-s390x/kvm.c
> > +++ b/target-s390x/kvm.c
> > @@ -876,8 +876,13 @@ static int kvm_pcistg_service_call(S390CPU *cpu, struct kvm_run *run)
> > 
> >  static int kvm_stpcifc_service_call(S390CPU *cpu, struct kvm_run *run)
> >  {
> > -    qemu_log_mask(LOG_UNIMP, "STPCIFC missing\n");
> > -    return 0;
> > +    uint8_t r1 = (run->s390_sieic.ipa & 0x00f0) >> 4;
> > +    uint64_t fiba;
> > +
> > +    cpu_synchronize_state(CPU(cpu));
> > +    fiba = get_base_disp_rxy(cpu, run);
> > +
> > +    return stpcifc_service_call(cpu, r1, fiba);
> >  }
> > 
> >  static int kvm_sic_service_call(S390CPU *cpu, struct kvm_run *run)
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH 1/2] s390/pci: add error event support
  2014-12-05  9:19 ` [Qemu-devel] [PATCH 1/2] s390/pci: add error event support Frank Blaschka
@ 2014-12-09 13:31   ` Cornelia Huck
  0 siblings, 0 replies; 7+ messages in thread
From: Cornelia Huck @ 2014-12-09 13:31 UTC (permalink / raw)
  To: Frank Blaschka; +Cc: borntraeger, Frank Blaschka, agraf, qemu-devel

On Fri,  5 Dec 2014 10:19:58 +0100
Frank Blaschka <blaschka@linux.vnet.ibm.com> wrote:

> From: Frank Blaschka <frank.blaschka@de.ibm.com>
> 
> This patch adds support to generate s390 pci error events

It also uses the new infrastructure for iota error handling (which
confused me when I read this), so I modified the patch description to
read:

"This patch adds support to generate s390 pci error events and makes
use of it to support iota error handling."

> 
> Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
> ---
>  hw/s390x/s390-pci-bus.c  | 50 +++++++++++++++++++++++++---
>  hw/s390x/s390-pci-bus.h  | 35 +++++++++++++++++++-
>  hw/s390x/s390-pci-inst.c | 86 ++++++++++++++++++++++++++++++++++++++++++------
>  3 files changed, 155 insertions(+), 16 deletions(-)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH 0/2] s390/pci: add 2 more features
  2014-12-05  9:19 [Qemu-devel] [PATCH 0/2] s390/pci: add 2 more features Frank Blaschka
  2014-12-05  9:19 ` [Qemu-devel] [PATCH 1/2] s390/pci: add error event support Frank Blaschka
  2014-12-05  9:19 ` [Qemu-devel] [PATCH 2/2] s390/pci: implement stpcifc instruction Frank Blaschka
@ 2014-12-09 13:31 ` Cornelia Huck
  2 siblings, 0 replies; 7+ messages in thread
From: Cornelia Huck @ 2014-12-09 13:31 UTC (permalink / raw)
  To: Frank Blaschka; +Cc: borntraeger, agraf, qemu-devel

On Fri,  5 Dec 2014 10:19:57 +0100
Frank Blaschka <blaschka@linux.vnet.ibm.com> wrote:

> Coni, Alex, Christian,
> 
> here are 2 more s390/pci features on top of the base pci support.
> Thx!
> 
> Frank
> 
> Frank Blaschka (2):
>   s390/pci: add error event support
>   s390/pci: implement stpcifc instruction
> 
>  hw/s390x/s390-pci-bus.c  |  50 ++++++++++++++--
>  hw/s390x/s390-pci-bus.h  |  36 +++++++++++-
>  hw/s390x/s390-pci-inst.c | 148 ++++++++++++++++++++++++++++++++++++++++++++---
>  hw/s390x/s390-pci-inst.h |   1 +
>  target-s390x/kvm.c       |   9 ++-
>  5 files changed, 227 insertions(+), 17 deletions(-)
> 

Applied 1-2 (patch 1 with slightly modified description) to s390-next.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2014-12-09 13:32 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-12-05  9:19 [Qemu-devel] [PATCH 0/2] s390/pci: add 2 more features Frank Blaschka
2014-12-05  9:19 ` [Qemu-devel] [PATCH 1/2] s390/pci: add error event support Frank Blaschka
2014-12-09 13:31   ` Cornelia Huck
2014-12-05  9:19 ` [Qemu-devel] [PATCH 2/2] s390/pci: implement stpcifc instruction Frank Blaschka
2014-12-05 13:15   ` Thomas Huth
2014-12-08  8:00     ` Frank Blaschka
2014-12-09 13:31 ` [Qemu-devel] [PATCH 0/2] s390/pci: add 2 more features Cornelia Huck

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).