aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-11-19 10:36:53 +0000
committerPeter Maydell <peter.maydell@linaro.org>2020-11-19 10:36:53 +0000
commitff85db769ffd431f86d263d5e954e809a83be92f (patch)
tree75d41b69bc370adc1c1b102fb23bc11e09d676e6
parent3d275bd17c7bdf5acd4e4f58fa7b8b9114bb7484 (diff)
parenta4e2fff1b104f2b235ea2673968d0b0383f541dc (diff)
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20201119' into staging
s390x fixes: - fix propagation and reset for the new diag318 call - fix hot-unplug for vfio-pci devices - fix endianness issues in zPCI (regression fix) # gpg: Signature made Thu 19 Nov 2020 10:15:58 GMT # gpg: using RSA key C3D0D66DC3624FF6A8C018CEDECF6B93C6F02FAF # gpg: issuer "cohuck@redhat.com" # gpg: Good signature from "Cornelia Huck <conny@cornelia-huck.de>" [unknown] # gpg: aka "Cornelia Huck <huckc@linux.vnet.ibm.com>" [full] # gpg: aka "Cornelia Huck <cornelia.huck@de.ibm.com>" [full] # gpg: aka "Cornelia Huck <cohuck@kernel.org>" [unknown] # gpg: aka "Cornelia Huck <cohuck@redhat.com>" [unknown] # Primary key fingerprint: C3D0 D66D C362 4FF6 A8C0 18CE DECF 6B93 C6F0 2FAF * remotes/cohuck/tags/s390x-20201119: s390x/pci: fix endianness issues s390x/pci: Unregister listeners before destroying IOMMU address space s390/kvm: fix diag318 propagation and reset functionality Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/s390x/s390-pci-bus.c17
-rw-r--r--hw/s390x/s390-pci-inst.c16
-rw-r--r--hw/s390x/s390-pci-vfio.c12
-rw-r--r--hw/s390x/s390-virtio-ccw.c4
-rw-r--r--include/hw/s390x/s390-pci-clp.h8
-rw-r--r--target/s390x/cpu.c7
-rw-r--r--target/s390x/cpu.h1
-rw-r--r--target/s390x/kvm-stub.c4
-rw-r--r--target/s390x/kvm.c22
-rw-r--r--target/s390x/kvm_s390x.h1
10 files changed, 70 insertions, 22 deletions
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 48a3be802f..05f7460aec 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -732,6 +732,13 @@ static void s390_pci_iommu_free(S390pciState *s, PCIBus *bus, int32_t devfn)
table->iommu[PCI_SLOT(devfn)] = NULL;
g_hash_table_destroy(iommu->iotlb);
+ /*
+ * An attached PCI device may have memory listeners, eg. VFIO PCI.
+ * The associated subregion will already have been unmapped in
+ * s390_pci_iommu_disable in response to the guest deconfigure request.
+ * Remove the listeners now before destroying the address space.
+ */
+ address_space_remove_listeners(&iommu->as);
address_space_destroy(&iommu->as);
object_unparent(OBJECT(&iommu->mr));
object_unparent(OBJECT(iommu));
@@ -770,11 +777,11 @@ static void s390_pci_init_default_group(void)
group = s390_group_create(ZPCI_DEFAULT_FN_GRP);
resgrp = &group->zpci_group;
resgrp->fr = 1;
- stq_p(&resgrp->dasm, 0);
- stq_p(&resgrp->msia, ZPCI_MSI_ADDR);
- stw_p(&resgrp->mui, DEFAULT_MUI);
- stw_p(&resgrp->i, 128);
- stw_p(&resgrp->maxstbl, 128);
+ resgrp->dasm = 0;
+ resgrp->msia = ZPCI_MSI_ADDR;
+ resgrp->mui = DEFAULT_MUI;
+ resgrp->i = 128;
+ resgrp->maxstbl = 128;
resgrp->version = 0;
}
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 58cd041d17..70bfd91bf7 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -281,7 +281,13 @@ int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra)
goto out;
}
- memcpy(resquery, &pbdev->zpci_fn, sizeof(*resquery));
+ stq_p(&resquery->sdma, pbdev->zpci_fn.sdma);
+ stq_p(&resquery->edma, pbdev->zpci_fn.edma);
+ stw_p(&resquery->pchid, pbdev->zpci_fn.pchid);
+ resquery->flags = pbdev->zpci_fn.flags;
+ resquery->pfgid = pbdev->zpci_fn.pfgid;
+ stl_p(&resquery->fid, pbdev->zpci_fn.fid);
+ stl_p(&resquery->uid, pbdev->zpci_fn.uid);
for (i = 0; i < PCI_BAR_COUNT; i++) {
uint32_t data = pci_get_long(pbdev->pdev->config +
@@ -312,7 +318,13 @@ int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra)
stw_p(&resgrp->hdr.rsp, CLP_RC_QUERYPCIFG_PFGID);
goto out;
}
- memcpy(resgrp, &group->zpci_group, sizeof(ClpRspQueryPciGrp));
+ resgrp->fr = group->zpci_group.fr;
+ stq_p(&resgrp->dasm, group->zpci_group.dasm);
+ stq_p(&resgrp->msia, group->zpci_group.msia);
+ stw_p(&resgrp->mui, group->zpci_group.mui);
+ stw_p(&resgrp->i, group->zpci_group.i);
+ stw_p(&resgrp->maxstbl, group->zpci_group.maxstbl);
+ resgrp->version = group->zpci_group.version;
stw_p(&resgrp->hdr.rsp, CLP_RC_OK);
break;
}
diff --git a/hw/s390x/s390-pci-vfio.c b/hw/s390x/s390-pci-vfio.c
index d5c78063b5..9296e1bb6e 100644
--- a/hw/s390x/s390-pci-vfio.c
+++ b/hw/s390x/s390-pci-vfio.c
@@ -156,12 +156,12 @@ static void s390_pci_read_group(S390PCIBusDevice *pbdev,
if (cap->flags & VFIO_DEVICE_INFO_ZPCI_FLAG_REFRESH) {
resgrp->fr = 1;
}
- stq_p(&resgrp->dasm, cap->dasm);
- stq_p(&resgrp->msia, cap->msi_addr);
- stw_p(&resgrp->mui, cap->mui);
- stw_p(&resgrp->i, cap->noi);
- stw_p(&resgrp->maxstbl, cap->maxstbl);
- stb_p(&resgrp->version, cap->version);
+ resgrp->dasm = cap->dasm;
+ resgrp->msia = cap->msi_addr;
+ resgrp->mui = cap->mui;
+ resgrp->i = cap->noi;
+ resgrp->maxstbl = cap->maxstbl;
+ resgrp->version = cap->version;
}
}
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 22222c4fd5..4e140bbead 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -486,6 +486,10 @@ static void s390_machine_reset(MachineState *machine)
default:
g_assert_not_reached();
}
+
+ CPU_FOREACH(t) {
+ run_on_cpu(t, s390_do_cpu_set_diag318, RUN_ON_CPU_HOST_ULONG(0));
+ }
s390_ipl_clear_reset_request();
}
diff --git a/include/hw/s390x/s390-pci-clp.h b/include/hw/s390x/s390-pci-clp.h
index ea2b1378cd..96b8e3f133 100644
--- a/include/hw/s390x/s390-pci-clp.h
+++ b/include/hw/s390x/s390-pci-clp.h
@@ -144,10 +144,10 @@ typedef struct ClpReqQueryPciGrp {
ClpReqHdr hdr;
uint32_t fmt;
uint64_t reserved1;
-#define CLP_REQ_QPCIG_MASK_PFGID 0xff
- uint32_t g;
- uint32_t reserved2;
- uint64_t reserved3;
+ uint8_t reserved2[3];
+ uint8_t g;
+ uint32_t reserved3;
+ uint64_t reserved4;
} QEMU_PACKED ClpReqQueryPciGrp;
/* Query PCI function group response */
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 66f5942b53..7b66718c44 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -447,6 +447,13 @@ void s390_enable_css_support(S390CPU *cpu)
kvm_s390_enable_css_support(cpu);
}
}
+
+void s390_do_cpu_set_diag318(CPUState *cs, run_on_cpu_data arg)
+{
+ if (kvm_enabled()) {
+ kvm_s390_set_diag318(cs, arg.host_ulong);
+ }
+}
#endif
static gchar *s390_gdb_arch_name(CPUState *cs)
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index f875ebf0f4..60d434d5ed 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -769,6 +769,7 @@ int s390_set_memory_limit(uint64_t new_limit, uint64_t *hw_limit);
void s390_set_max_pagesize(uint64_t pagesize, Error **errp);
void s390_cmma_reset(void);
void s390_enable_css_support(S390CPU *cpu);
+void s390_do_cpu_set_diag318(CPUState *cs, run_on_cpu_data arg);
int s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch_id,
int vq, bool assign);
#ifndef CONFIG_USER_ONLY
diff --git a/target/s390x/kvm-stub.c b/target/s390x/kvm-stub.c
index aa185017a2..9970b5a8c7 100644
--- a/target/s390x/kvm-stub.c
+++ b/target/s390x/kvm-stub.c
@@ -120,3 +120,7 @@ void kvm_s390_stop_interrupt(S390CPU *cpu)
void kvm_s390_restart_interrupt(S390CPU *cpu)
{
}
+
+void kvm_s390_set_diag318(CPUState *cs, uint64_t diag318_info)
+{
+}
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index baa070fdf7..b8385e6b95 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -1611,10 +1611,23 @@ static int handle_sw_breakpoint(S390CPU *cpu, struct kvm_run *run)
return -ENOENT;
}
+void kvm_s390_set_diag318(CPUState *cs, uint64_t diag318_info)
+{
+ CPUS390XState *env = &S390_CPU(cs)->env;
+
+ /* Feat bit is set only if KVM supports sync for diag318 */
+ if (s390_has_feat(S390_FEAT_DIAG_318)) {
+ env->diag318_info = diag318_info;
+ cs->kvm_run->s.regs.diag318 = diag318_info;
+ cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_DIAG318;
+ }
+}
+
static void handle_diag_318(S390CPU *cpu, struct kvm_run *run)
{
uint64_t reg = (run->s390_sieic.ipa & 0x00f0) >> 4;
uint64_t diag318_info = run->s.regs.gprs[reg];
+ CPUState *t;
/*
* DIAG 318 can only be enabled with KVM support. As such, let's
@@ -1622,13 +1635,12 @@ static void handle_diag_318(S390CPU *cpu, struct kvm_run *run)
*/
if (!s390_has_feat(S390_FEAT_DIAG_318)) {
kvm_s390_program_interrupt(cpu, PGM_SPECIFICATION);
+ return;
}
- cpu->env.diag318_info = diag318_info;
-
- if (can_sync_regs(CPU(cpu), KVM_SYNC_DIAG318)) {
- run->s.regs.diag318 = diag318_info;
- run->kvm_dirty_regs |= KVM_SYNC_DIAG318;
+ CPU_FOREACH(t) {
+ run_on_cpu(t, s390_do_cpu_set_diag318,
+ RUN_ON_CPU_HOST_ULONG(diag318_info));
}
}
diff --git a/target/s390x/kvm_s390x.h b/target/s390x/kvm_s390x.h
index 6ab17c81b7..25bbe98b25 100644
--- a/target/s390x/kvm_s390x.h
+++ b/target/s390x/kvm_s390x.h
@@ -45,5 +45,6 @@ void kvm_s390_set_max_pagesize(uint64_t pagesize, Error **errp);
void kvm_s390_crypto_reset(void);
void kvm_s390_restart_interrupt(S390CPU *cpu);
void kvm_s390_stop_interrupt(S390CPU *cpu);
+void kvm_s390_set_diag318(CPUState *cs, uint64_t diag318_info);
#endif /* KVM_S390X_H */