s390x/pci: fix stpcifc_service_call

Firstly the function misses dmaas checking. This patch adds it.

Secondly the function uses s390_pci_find_dev_by_fh() to look up the
zpci device. This may fail if the guest provides a valid and disabled
fh but fh of the associated zpci device is enabled. Thus we use
s390_pci_find_dev_by_idx() instead.

Signed-off-by: Yi Min Zhao <zyimin@linux.vnet.ibm.com>
Reviewed-by: Pierre Morel <pmorel@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
This commit is contained in:
Yi Min Zhao 2016-06-15 17:09:10 +08:00 committed by Cornelia Huck
parent 4e3bfc167d
commit 0a608a6e13

View File

@ -944,6 +944,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar)
int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar)
{
CPUS390XState *env = &cpu->env;
uint8_t dmaas;
uint32_t fh;
ZpciFib fib;
S390PCIBusDevice *pbdev;
@ -956,13 +957,20 @@ int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar)
}
fh = env->regs[r1] >> 32;
dmaas = (env->regs[r1] >> 16) & 0xff;
if (dmaas) {
setcc(cpu, ZPCI_PCI_LS_ERR);
s390_set_status_code(env, r1, ZPCI_STPCIFC_ST_INVAL_DMAAS);
return 0;
}
if (fiba & 0x7) {
program_interrupt(env, PGM_SPECIFICATION, 6);
return 0;
}
pbdev = s390_pci_find_dev_by_fh(fh);
pbdev = s390_pci_find_dev_by_idx(fh & FH_MASK_INDEX);
if (!pbdev) {
setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
return 0;