summaryrefslogtreecommitdiffstats
path: root/hw/s390x
diff options
context:
space:
mode:
authorYi Min Zhao <zyimin@linux.vnet.ibm.com>2015-12-14 16:50:44 +0800
committerTimothy Pearson <tpearson@raptorengineering.com>2019-11-29 19:28:23 -0600
commit59df88115d5781fc79f65dc48a0ebf6b63a2a4d5 (patch)
tree53aed2006ab31421f8bd58887f292aacbc0ea67f /hw/s390x
parentf370a9db053ea031a54018c9d0c8546a1e3d7f72 (diff)
downloadhqemu-59df88115d5781fc79f65dc48a0ebf6b63a2a4d5.zip
hqemu-59df88115d5781fc79f65dc48a0ebf6b63a2a4d5.tar.gz
s390x/pci: reject some operations to disabled PCI function
According to the s390 architecture, any mpcifc, pcilg, pcistg, pcistb and rpcit instructions issued to disabled PCI functions are rejected, and the instruction completes by setting condition code 3. In addition, any DMA and MSIX interruption operations are ignored. Signed-off-by: Yi Min Zhao <zyimin@linux.vnet.ibm.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Diffstat (limited to 'hw/s390x')
-rw-r--r--hw/s390x/s390-pci-bus.c6
-rw-r--r--hw/s390x/s390-pci-bus.h1
-rw-r--r--hw/s390x/s390-pci-inst.c11
3 files changed, 11 insertions, 7 deletions
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 8de35ff..132588b 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -317,7 +317,7 @@ static IOMMUTLBEntry s390_translate_iommu(MemoryRegion *iommu, hwaddr addr,
.perm = IOMMU_NONE,
};
- if (!pbdev->configured || !pbdev->pdev) {
+ if (!pbdev->configured || !pbdev->pdev || !(pbdev->fh & FH_ENABLED)) {
return ret;
}
@@ -428,6 +428,10 @@ static void s390_msi_ctrl_write(void *opaque, hwaddr addr, uint64_t data,
return;
}
+ if (!(pbdev->fh & FH_ENABLED)) {
+ return;
+ }
+
ind_bit = pbdev->routes.adapter.ind_offset;
sum_bit = pbdev->routes.adapter.summary_offset;
diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h
index 80345da..d8ddb77 100644
--- a/hw/s390x/s390-pci-bus.h
+++ b/hw/s390x/s390-pci-bus.h
@@ -23,6 +23,7 @@
#define TYPE_S390_PCI_HOST_BRIDGE "s390-pcihost"
#define FH_VIRT 0x00ff0000
#define ENABLE_BIT_OFFSET 31
+#define FH_ENABLED (1 << ENABLE_BIT_OFFSET)
#define S390_PCIPT_ADAPTER 2
#define S390_PCI_HOST_BRIDGE(obj) \
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 8c1dc82..df57a7d 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -313,7 +313,7 @@ int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
offset = env->regs[r2 + 1];
pbdev = s390_pci_find_dev_by_fh(fh);
- if (!pbdev) {
+ if (!pbdev || !(pbdev->fh & FH_ENABLED)) {
DPRINTF("pcilg no pci dev\n");
setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
return 0;
@@ -430,7 +430,7 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
offset = env->regs[r2 + 1];
pbdev = s390_pci_find_dev_by_fh(fh);
- if (!pbdev) {
+ if (!pbdev || !(pbdev->fh & FH_ENABLED)) {
DPRINTF("pcistg no pci dev\n");
setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
return 0;
@@ -521,8 +521,7 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
end = start + env->regs[r2 + 1];
pbdev = s390_pci_find_dev_by_fh(fh);
-
- if (!pbdev) {
+ if (!pbdev || !(pbdev->fh & FH_ENABLED)) {
DPRINTF("rpcit no pci dev\n");
setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
goto out;
@@ -586,7 +585,7 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
}
pbdev = s390_pci_find_dev_by_fh(fh);
- if (!pbdev) {
+ if (!pbdev || !(pbdev->fh & FH_ENABLED)) {
DPRINTF("pcistb no pci dev fh 0x%x\n", fh);
setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
return 0;
@@ -727,7 +726,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar)
}
pbdev = s390_pci_find_dev_by_fh(fh);
- if (!pbdev) {
+ if (!pbdev || !(pbdev->fh & FH_ENABLED)) {
DPRINTF("mpcifc no pci dev fh 0x%x\n", fh);
setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
return 0;
OpenPOWER on IntegriCloud