* [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).