hv: vpci: restrict SOS access assigned PCI device

SOS should not access the physical PCI device which is assigned to other guest.

Tracked-On: #4371
Signed-off-by: Li Fei1 <fei1.li@intel.com>
This commit is contained in:
Li Fei1 2020-01-17 18:47:55 +08:00 committed by wenlingz
parent 9d3d9c3d1e
commit fbe57d9f0b
2 changed files with 34 additions and 32 deletions

View File

@ -194,43 +194,44 @@ int32_t vmsix_handle_table_mmio_access(struct io_request *io_req, void *handler_
void *hva; void *hva;
vdev = (struct pci_vdev *)handler_private_data; vdev = (struct pci_vdev *)handler_private_data;
/* This device is assigned to post-launched VM from SOS */ /* This device has not be assigned to other OS */
if (vdev->new_owner != NULL) { if (vdev->new_owner == NULL) {
vdev = vdev->new_owner; offset = mmio->address - vdev->msix.mmio_gpa;
}
offset = mmio->address - vdev->msix.mmio_gpa;
if (msixtable_access(vdev, (uint32_t)offset)) { if (msixtable_access(vdev, (uint32_t)offset)) {
rw_vmsix_table(vdev, mmio, (uint32_t)offset); rw_vmsix_table(vdev, mmio, (uint32_t)offset);
} else { } else {
hva = hpa2hva(vdev->msix.mmio_hpa + offset); hva = hpa2hva(vdev->msix.mmio_hpa + offset);
/* Only DWORD and QWORD are permitted */ /* Only DWORD and QWORD are permitted */
if ((mmio->size != 4U) && (mmio->size != 8U)) { if ((mmio->size == 4U) || (mmio->size == 8U)) {
pr_err("%s, Only DWORD and QWORD are permitted", __func__); if (hva != NULL) {
ret = -EINVAL; stac();
} else if (hva != NULL) { /* MSI-X PBA and Capability Table could be in the same range */
stac(); if (mmio->direction == REQUEST_READ) {
/* MSI-X PBA and Capability Table could be in the same range */ /* mmio->size is either 4U or 8U */
if (mmio->direction == REQUEST_READ) { if (mmio->size == 4U) {
/* mmio->size is either 4U or 8U */ mmio->value = (uint64_t)mmio_read32((const void *)hva);
if (mmio->size == 4U) { } else {
mmio->value = (uint64_t)mmio_read32((const void *)hva); mmio->value = mmio_read64((const void *)hva);
} else { }
mmio->value = mmio_read64((const void *)hva); } else {
/* mmio->size is either 4U or 8U */
if (mmio->size == 4U) {
mmio_write32((uint32_t)(mmio->value), (void *)hva);
} else {
mmio_write64(mmio->value, (void *)hva);
}
}
clac();
} }
} else { } else {
/* mmio->size is either 4U or 8U */ pr_err("%s, Only DWORD and QWORD are permitted", __func__);
if (mmio->size == 4U) { ret = -EINVAL;
mmio_write32((uint32_t)(mmio->value), (void *)hva);
} else {
mmio_write64(mmio->value, (void *)hva);
}
} }
clac();
} else {
/* No other state currently, do nothing */
} }
} else {
ret = -EFAULT;
} }
return ret; return ret;

View File

@ -341,7 +341,8 @@ static struct pci_vdev *find_vdev(struct acrn_vpci *vpci, union pci_bdf bdf)
struct pci_vdev *vdev = pci_find_vdev(vpci, bdf); struct pci_vdev *vdev = pci_find_vdev(vpci, bdf);
if ((vdev != NULL) && (vdev->vpci != vpci)) { if ((vdev != NULL) && (vdev->vpci != vpci)) {
vdev = vdev->new_owner; /* If the device is assigned to other guest, we could not access it */
vdev = NULL;
} }
return vdev; return vdev;