aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-03-09 10:32:53 +0000
committerPeter Maydell <peter.maydell@linaro.org>2020-03-09 10:32:53 +0000
commit7a5853cec479a448edae0fb2aaf4e2f78c9c774d (patch)
tree1a43b58ded6129084fda0047909f563bbc5ed2b7
parent67f17e23baca5dd545fe98b01169cc351a70fe35 (diff)
parenta6f65f4fc217713ee2c78b99baae1cc31c761778 (diff)
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
virtio, pci, pc: fixes, cleanups, features Bugfixes, cleanups all over the place. Ability to disable hotplug for pci express ports. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Sun 08 Mar 2020 13:27:54 GMT # gpg: using RSA key 5D09FD0871C8F85B94CA8A0D281F0DB8D28D5469 # gpg: issuer "mst@redhat.com" # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" [full] # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" [full] # Primary key fingerprint: 0270 606B 6F3C DF3D 0B17 0970 C350 3912 AFBE 8E67 # Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA 8A0D 281F 0DB8 D28D 5469 * remotes/mst/tags/for_upstream: hw/i386/intel_iommu: Simplify vtd_find_as_from_bus_num() logic vhost-vsock: fix error message output vhost: correctly turn on VIRTIO_F_IOMMU_PLATFORM pcie_root_port: Add hotplug disabling option Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/i386/intel_iommu.c32
-rw-r--r--hw/pci-bridge/pcie_root_port.c2
-rw-r--r--hw/pci-bridge/xio3130_downstream.c2
-rw-r--r--hw/pci/pcie.c11
-rw-r--r--hw/pci/pcie_port.c1
-rw-r--r--hw/virtio/vhost-vsock.c2
-rw-r--r--hw/virtio/vhost.c12
-rw-r--r--include/hw/pci/pcie.h2
-rw-r--r--include/hw/pci/pcie_port.h3
9 files changed, 43 insertions, 24 deletions
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 6258c58ac9..204b6841ec 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -987,24 +987,26 @@ static bool vtd_slpte_nonzero_rsvd(uint64_t slpte, uint32_t level)
static VTDBus *vtd_find_as_from_bus_num(IntelIOMMUState *s, uint8_t bus_num)
{
VTDBus *vtd_bus = s->vtd_as_by_bus_num[bus_num];
- if (!vtd_bus) {
- /*
- * Iterate over the registered buses to find the one which
- * currently hold this bus number, and update the bus_num
- * lookup table:
- */
- GHashTableIter iter;
+ GHashTableIter iter;
- g_hash_table_iter_init(&iter, s->vtd_as_by_busptr);
- while (g_hash_table_iter_next(&iter, NULL, (void **)&vtd_bus)) {
- if (pci_bus_num(vtd_bus->bus) == bus_num) {
- s->vtd_as_by_bus_num[bus_num] = vtd_bus;
- return vtd_bus;
- }
+ if (vtd_bus) {
+ return vtd_bus;
+ }
+
+ /*
+ * Iterate over the registered buses to find the one which
+ * currently holds this bus number and update the bus_num
+ * lookup table.
+ */
+ g_hash_table_iter_init(&iter, s->vtd_as_by_busptr);
+ while (g_hash_table_iter_next(&iter, NULL, (void **)&vtd_bus)) {
+ if (pci_bus_num(vtd_bus->bus) == bus_num) {
+ s->vtd_as_by_bus_num[bus_num] = vtd_bus;
+ return vtd_bus;
}
- vtd_bus = NULL;
}
- return vtd_bus;
+
+ return NULL;
}
/* Given the @iova, get relevant @slptep. @slpte_level will be the last level
diff --git a/hw/pci-bridge/pcie_root_port.c b/hw/pci-bridge/pcie_root_port.c
index 0ba4e4dea4..f1cfe9d14a 100644
--- a/hw/pci-bridge/pcie_root_port.c
+++ b/hw/pci-bridge/pcie_root_port.c
@@ -94,7 +94,7 @@ static void rp_realize(PCIDevice *d, Error **errp)
pcie_cap_arifwd_init(d);
pcie_cap_deverr_init(d);
- pcie_cap_slot_init(d, s->slot);
+ pcie_cap_slot_init(d, s);
pcie_cap_root_init(d);
pcie_chassis_create(s->chassis);
diff --git a/hw/pci-bridge/xio3130_downstream.c b/hw/pci-bridge/xio3130_downstream.c
index 153a4acad2..04aae72cd6 100644
--- a/hw/pci-bridge/xio3130_downstream.c
+++ b/hw/pci-bridge/xio3130_downstream.c
@@ -94,7 +94,7 @@ static void xio3130_downstream_realize(PCIDevice *d, Error **errp)
}
pcie_cap_flr_init(d);
pcie_cap_deverr_init(d);
- pcie_cap_slot_init(d, s->slot);
+ pcie_cap_slot_init(d, s);
pcie_cap_arifwd_init(d);
pcie_chassis_create(s->chassis);
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 08718188bb..0eb3a2a5d2 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -495,7 +495,7 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
/* pci express slot for pci express root/downstream port
PCI express capability slot registers */
-void pcie_cap_slot_init(PCIDevice *dev, uint16_t slot)
+void pcie_cap_slot_init(PCIDevice *dev, PCIESlot *s)
{
uint32_t pos = dev->exp.exp_cap;
@@ -505,13 +505,16 @@ void pcie_cap_slot_init(PCIDevice *dev, uint16_t slot)
pci_long_test_and_clear_mask(dev->config + pos + PCI_EXP_SLTCAP,
~PCI_EXP_SLTCAP_PSN);
pci_long_test_and_set_mask(dev->config + pos + PCI_EXP_SLTCAP,
- (slot << PCI_EXP_SLTCAP_PSN_SHIFT) |
+ (s->slot << PCI_EXP_SLTCAP_PSN_SHIFT) |
PCI_EXP_SLTCAP_EIP |
- PCI_EXP_SLTCAP_HPS |
- PCI_EXP_SLTCAP_HPC |
PCI_EXP_SLTCAP_PIP |
PCI_EXP_SLTCAP_AIP |
PCI_EXP_SLTCAP_ABP);
+ if (s->hotplug) {
+ pci_long_test_and_set_mask(dev->config + pos + PCI_EXP_SLTCAP,
+ PCI_EXP_SLTCAP_HPS |
+ PCI_EXP_SLTCAP_HPC);
+ }
if (dev->cap_present & QEMU_PCIE_SLTCAP_PCP) {
pci_long_test_and_set_mask(dev->config + pos + PCI_EXP_SLTCAP,
diff --git a/hw/pci/pcie_port.c b/hw/pci/pcie_port.c
index f8263cb306..eb563ad435 100644
--- a/hw/pci/pcie_port.c
+++ b/hw/pci/pcie_port.c
@@ -147,6 +147,7 @@ static const TypeInfo pcie_port_type_info = {
static Property pcie_slot_props[] = {
DEFINE_PROP_UINT8("chassis", PCIESlot, chassis, 0),
DEFINE_PROP_UINT16("slot", PCIESlot, slot, 0),
+ DEFINE_PROP_BOOL("hotplug", PCIESlot, hotplug, true),
DEFINE_PROP_END_OF_LIST()
};
diff --git a/hw/virtio/vhost-vsock.c b/hw/virtio/vhost-vsock.c
index 66da96583b..9f9093e196 100644
--- a/hw/virtio/vhost-vsock.c
+++ b/hw/virtio/vhost-vsock.c
@@ -325,7 +325,7 @@ static void vhost_vsock_device_realize(DeviceState *dev, Error **errp)
} else {
vhostfd = open("/dev/vhost-vsock", O_RDWR);
if (vhostfd < 0) {
- error_setg_errno(errp, -errno,
+ error_setg_errno(errp, errno,
"vhost-vsock: failed to open vhost device");
return;
}
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 0d226dae10..01ebe12f28 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -290,7 +290,14 @@ static int vhost_dev_has_iommu(struct vhost_dev *dev)
{
VirtIODevice *vdev = dev->vdev;
- return virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
+ /*
+ * For vhost, VIRTIO_F_IOMMU_PLATFORM means the backend support
+ * incremental memory mapping API via IOTLB API. For platform that
+ * does not have IOMMU, there's no need to enable this feature
+ * which may cause unnecessary IOTLB miss/update trnasactions.
+ */
+ return vdev->dma_as != &address_space_memory &&
+ virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
}
static void *vhost_memory_map(struct vhost_dev *dev, hwaddr addr,
@@ -765,6 +772,9 @@ static int vhost_dev_set_features(struct vhost_dev *dev,
if (enable_log) {
features |= 0x1ULL << VHOST_F_LOG_ALL;
}
+ if (!vhost_dev_has_iommu(dev)) {
+ features &= ~(0x1ULL << VIRTIO_F_IOMMU_PLATFORM);
+ }
r = dev->vhost_ops->vhost_set_features(dev, features);
if (r < 0) {
VHOST_OPS_DEBUG("vhost_set_features failed");
diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
index 7064875835..14c58ebdb6 100644
--- a/include/hw/pci/pcie.h
+++ b/include/hw/pci/pcie.h
@@ -104,7 +104,7 @@ void pcie_cap_deverr_reset(PCIDevice *dev);
void pcie_cap_lnkctl_init(PCIDevice *dev);
void pcie_cap_lnkctl_reset(PCIDevice *dev);
-void pcie_cap_slot_init(PCIDevice *dev, uint16_t slot);
+void pcie_cap_slot_init(PCIDevice *dev, PCIESlot *s);
void pcie_cap_slot_reset(PCIDevice *dev);
void pcie_cap_slot_get(PCIDevice *dev, uint16_t *slt_ctl, uint16_t *slt_sta);
void pcie_cap_slot_write_config(PCIDevice *dev,
diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h
index 4b3d254b08..caae57573b 100644
--- a/include/hw/pci/pcie_port.h
+++ b/include/hw/pci/pcie_port.h
@@ -55,6 +55,9 @@ struct PCIESlot {
/* Disable ACS (really for a pcie_root_port) */
bool disable_acs;
+
+ /* Indicates whether hot-plug is enabled on the slot */
+ bool hotplug;
QLIST_ENTRY(PCIESlot) next;
};