From: "Michael S. Tsirkin" <mst@redhat.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
Cornelia Huck <cohuck@redhat.com>,
Eric Auger <eric.auger@redhat.com>,
Jean-Philippe Brucker <jean-philippe@linaro.org>
Subject: [PULL 22/45] virtio-iommu: Default to bypass during boot
Date: Fri, 4 Mar 2022 08:40:06 -0500 [thread overview]
Message-ID: <20220304133556.233983-23-mst@redhat.com> (raw)
In-Reply-To: <20220304133556.233983-1-mst@redhat.com>
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
Currently the virtio-iommu device must be programmed before it allows
DMA from any PCI device. This can make the VM entirely unusable when a
virtio-iommu driver isn't present, for example in a bootloader that
loads the OS from storage.
Similarly to the other vIOMMU implementations, default to DMA bypassing
the IOMMU during boot. Add a "boot-bypass" property, defaulting to true,
that lets users change this behavior.
Replace the VIRTIO_IOMMU_F_BYPASS feature, which didn't support bypass
before feature negotiation, with VIRTIO_IOMMU_F_BYPASS_CONFIG.
We add the bypass field to the migration stream without introducing
subsections, based on the assumption that this virtio-iommu device isn't
being used in production enough to require cross-version migration at
the moment (all previous version required workarounds since they didn't
support ACPI and boot-bypass).
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Message-Id: <20220214124356.872985-3-jean-philippe@linaro.org>
Acked-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Tested-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
include/hw/virtio/virtio-iommu.h | 1 +
hw/virtio/virtio-iommu.c | 60 +++++++++++++++++++++++++++-----
hw/virtio/trace-events | 4 ++-
3 files changed, 56 insertions(+), 9 deletions(-)
diff --git a/include/hw/virtio/virtio-iommu.h b/include/hw/virtio/virtio-iommu.h
index e2339e5b72..84391f8448 100644
--- a/include/hw/virtio/virtio-iommu.h
+++ b/include/hw/virtio/virtio-iommu.h
@@ -58,6 +58,7 @@ struct VirtIOIOMMU {
GTree *domains;
QemuMutex mutex;
GTree *endpoints;
+ bool boot_bypass;
};
#endif
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index aa9c16a17b..4ca36db4ac 100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -24,6 +24,7 @@
#include "hw/qdev-properties.h"
#include "hw/virtio/virtio.h"
#include "sysemu/kvm.h"
+#include "sysemu/reset.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "trace.h"
@@ -728,8 +729,7 @@ static IOMMUTLBEntry virtio_iommu_translate(IOMMUMemoryRegion *mr, hwaddr addr,
.perm = IOMMU_NONE,
};
- bypass_allowed = virtio_vdev_has_feature(&s->parent_obj,
- VIRTIO_IOMMU_F_BYPASS);
+ bypass_allowed = s->config.bypass;
sid = virtio_iommu_get_bdf(sdev);
@@ -831,13 +831,37 @@ static void virtio_iommu_get_config(VirtIODevice *vdev, uint8_t *config_data)
out_config->domain_range.start = cpu_to_le32(dev_config->domain_range.start);
out_config->domain_range.end = cpu_to_le32(dev_config->domain_range.end);
out_config->probe_size = cpu_to_le32(dev_config->probe_size);
+ out_config->bypass = dev_config->bypass;
trace_virtio_iommu_get_config(dev_config->page_size_mask,
dev_config->input_range.start,
dev_config->input_range.end,
dev_config->domain_range.start,
dev_config->domain_range.end,
- dev_config->probe_size);
+ dev_config->probe_size,
+ dev_config->bypass);
+}
+
+static void virtio_iommu_set_config(VirtIODevice *vdev,
+ const uint8_t *config_data)
+{
+ VirtIOIOMMU *dev = VIRTIO_IOMMU(vdev);
+ struct virtio_iommu_config *dev_config = &dev->config;
+ const struct virtio_iommu_config *in_config = (void *)config_data;
+
+ if (in_config->bypass != dev_config->bypass) {
+ if (!virtio_vdev_has_feature(vdev, VIRTIO_IOMMU_F_BYPASS_CONFIG)) {
+ virtio_error(vdev, "cannot set config.bypass");
+ return;
+ } else if (in_config->bypass != 0 && in_config->bypass != 1) {
+ virtio_error(vdev, "invalid config.bypass value '%u'",
+ in_config->bypass);
+ return;
+ }
+ dev_config->bypass = in_config->bypass;
+ }
+
+ trace_virtio_iommu_set_config(in_config->bypass);
}
static uint64_t virtio_iommu_get_features(VirtIODevice *vdev, uint64_t f,
@@ -963,6 +987,19 @@ static int virtio_iommu_set_page_size_mask(IOMMUMemoryRegion *mr,
return 0;
}
+static void virtio_iommu_system_reset(void *opaque)
+{
+ VirtIOIOMMU *s = opaque;
+
+ trace_virtio_iommu_system_reset();
+
+ /*
+ * config.bypass is sticky across device reset, but should be restored on
+ * system reset
+ */
+ s->config.bypass = s->boot_bypass;
+}
+
static void virtio_iommu_device_realize(DeviceState *dev, Error **errp)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
@@ -988,9 +1025,9 @@ static void virtio_iommu_device_realize(DeviceState *dev, Error **errp)
virtio_add_feature(&s->features, VIRTIO_IOMMU_F_INPUT_RANGE);
virtio_add_feature(&s->features, VIRTIO_IOMMU_F_DOMAIN_RANGE);
virtio_add_feature(&s->features, VIRTIO_IOMMU_F_MAP_UNMAP);
- virtio_add_feature(&s->features, VIRTIO_IOMMU_F_BYPASS);
virtio_add_feature(&s->features, VIRTIO_IOMMU_F_MMIO);
virtio_add_feature(&s->features, VIRTIO_IOMMU_F_PROBE);
+ virtio_add_feature(&s->features, VIRTIO_IOMMU_F_BYPASS_CONFIG);
qemu_mutex_init(&s->mutex);
@@ -1001,6 +1038,8 @@ static void virtio_iommu_device_realize(DeviceState *dev, Error **errp)
} else {
error_setg(errp, "VIRTIO-IOMMU is not attached to any PCI bus!");
}
+
+ qemu_register_reset(virtio_iommu_system_reset, s);
}
static void virtio_iommu_device_unrealize(DeviceState *dev)
@@ -1008,6 +1047,8 @@ static void virtio_iommu_device_unrealize(DeviceState *dev)
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VirtIOIOMMU *s = VIRTIO_IOMMU(dev);
+ qemu_unregister_reset(virtio_iommu_system_reset, s);
+
g_hash_table_destroy(s->as_by_busptr);
if (s->domains) {
g_tree_destroy(s->domains);
@@ -1141,21 +1182,22 @@ static int iommu_post_load(void *opaque, int version_id)
static const VMStateDescription vmstate_virtio_iommu_device = {
.name = "virtio-iommu-device",
- .minimum_version_id = 1,
- .version_id = 1,
+ .minimum_version_id = 2,
+ .version_id = 2,
.post_load = iommu_post_load,
.fields = (VMStateField[]) {
VMSTATE_GTREE_DIRECT_KEY_V(domains, VirtIOIOMMU, 1,
&vmstate_domain, VirtIOIOMMUDomain),
+ VMSTATE_UINT8_V(config.bypass, VirtIOIOMMU, 2),
VMSTATE_END_OF_LIST()
},
};
static const VMStateDescription vmstate_virtio_iommu = {
.name = "virtio-iommu",
- .minimum_version_id = 1,
+ .minimum_version_id = 2,
.priority = MIG_PRI_IOMMU,
- .version_id = 1,
+ .version_id = 2,
.fields = (VMStateField[]) {
VMSTATE_VIRTIO_DEVICE,
VMSTATE_END_OF_LIST()
@@ -1164,6 +1206,7 @@ static const VMStateDescription vmstate_virtio_iommu = {
static Property virtio_iommu_properties[] = {
DEFINE_PROP_LINK("primary-bus", VirtIOIOMMU, primary_bus, "PCI", PCIBus *),
+ DEFINE_PROP_BOOL("boot-bypass", VirtIOIOMMU, boot_bypass, true),
DEFINE_PROP_END_OF_LIST(),
};
@@ -1180,6 +1223,7 @@ static void virtio_iommu_class_init(ObjectClass *klass, void *data)
vdc->unrealize = virtio_iommu_device_unrealize;
vdc->reset = virtio_iommu_device_reset;
vdc->get_config = virtio_iommu_get_config;
+ vdc->set_config = virtio_iommu_set_config;
vdc->get_features = virtio_iommu_get_features;
vdc->set_status = virtio_iommu_set_status;
vdc->vmsd = &vmstate_virtio_iommu_device;
diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index f7ad6be5fb..a5102eac9e 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -89,9 +89,11 @@ virtio_mmio_setting_irq(int level) "virtio_mmio setting IRQ %d"
# virtio-iommu.c
virtio_iommu_device_reset(void) "reset!"
+virtio_iommu_system_reset(void) "system reset!"
virtio_iommu_get_features(uint64_t features) "device supports features=0x%"PRIx64
virtio_iommu_device_status(uint8_t status) "driver status = %d"
-virtio_iommu_get_config(uint64_t page_size_mask, uint64_t start, uint64_t end, uint32_t domain_start, uint32_t domain_end, uint32_t probe_size) "page_size_mask=0x%"PRIx64" input range start=0x%"PRIx64" input range end=0x%"PRIx64" domain range start=%d domain range end=%d probe_size=0x%x"
+virtio_iommu_get_config(uint64_t page_size_mask, uint64_t start, uint64_t end, uint32_t domain_start, uint32_t domain_end, uint32_t probe_size, uint8_t bypass) "page_size_mask=0x%"PRIx64" input range start=0x%"PRIx64" input range end=0x%"PRIx64" domain range start=%d domain range end=%d probe_size=0x%x bypass=0x%x"
+virtio_iommu_set_config(uint8_t bypass) "bypass=0x%x"
virtio_iommu_attach(uint32_t domain_id, uint32_t ep_id) "domain=%d endpoint=%d"
virtio_iommu_detach(uint32_t domain_id, uint32_t ep_id) "domain=%d endpoint=%d"
virtio_iommu_map(uint32_t domain_id, uint64_t virt_start, uint64_t virt_end, uint64_t phys_start, uint32_t flags) "domain=%d virt_start=0x%"PRIx64" virt_end=0x%"PRIx64 " phys_start=0x%"PRIx64" flags=%d"
--
MST
next prev parent reply other threads:[~2022-03-04 14:25 UTC|newest]
Thread overview: 52+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-04 13:36 [PULL 00/45] virtio,pc,pci: features, cleanups, fixes Michael S. Tsirkin
2022-03-04 13:37 ` [PULL 01/45] qom: assert integer does not overflow Michael S. Tsirkin
2022-03-04 13:37 ` [PULL 02/45] ACPI ERST: specification for ERST support Michael S. Tsirkin
2022-03-04 13:37 ` [PULL 03/45] MAINTAINERS: no need to add my name explicitly as a reviewer for VIOT tables Michael S. Tsirkin
2022-03-04 13:37 ` [PULL 04/45] docs/acpi/erst: add device id for ACPI ERST device in pci-ids.txt Michael S. Tsirkin
2022-03-04 13:37 ` [PULL 05/45] hw/acpi/erst: clean up unused IS_UEFI_CPER_RECORD macro Michael S. Tsirkin
2022-03-04 13:37 ` [PULL 06/45] hw/smbios: code cleanup - use macro definitions for table header handles Michael S. Tsirkin
2022-03-04 13:38 ` [PULL 07/45] hw/smbios: fix overlapping table handle numbers with large memory vms Michael S. Tsirkin
2022-03-04 13:38 ` [PULL 08/45] hw/smbios: add assertion to ensure handles of tables 19 and 32 do not collide Michael S. Tsirkin
2022-03-04 13:38 ` [PULL 09/45] vhost-user: remove VirtQ notifier restore Michael S. Tsirkin
2022-03-04 13:38 ` [PULL 10/45] vhost-user: fix VirtQ notifier cleanup Michael S. Tsirkin
2022-03-04 13:38 ` [PULL 11/45] virtio: fix the condition for iommu_platform not supported Michael S. Tsirkin
2022-03-04 13:38 ` [PULL 12/45] hw/vhost-user-i2c: Add support for VIRTIO_I2C_F_ZERO_LENGTH_REQUEST Michael S. Tsirkin
2022-03-04 13:39 ` [PULL 13/45] tests/qtest/libqos/pci: Introduce pio_limit Michael S. Tsirkin
2022-03-04 13:39 ` [PULL 14/45] tests/qtest/libqos: Skip hotplug tests if pci root bus is not hotpluggable Michael S. Tsirkin
2022-03-04 13:39 ` [PULL 15/45] tests/qtest/vhost-user-blk-test: Temporary hack to get tests passing on aarch64 Michael S. Tsirkin
2022-03-04 13:39 ` [PULL 16/45] tests/qtest/libqos: Add generic pci host bridge in arm-virt machine Michael S. Tsirkin
2022-03-07 10:02 ` Michael S. Tsirkin
2022-03-07 11:07 ` Eric Auger
2022-03-04 13:39 ` [PULL 17/45] hw/virtio: vdpa: Fix leak of host-notifier memory-region Michael S. Tsirkin
2022-03-04 13:39 ` [PULL 18/45] vhost-vdpa: make notifiers _init()/_uninit() symmetric Michael S. Tsirkin
2022-03-04 13:39 ` [PULL 19/45] intel_iommu: support snoop control Michael S. Tsirkin
2022-03-04 13:39 ` [PULL 20/45] hw/i386: Improve bounds checking in OVMF table parsing Michael S. Tsirkin
2022-03-04 13:40 ` [PULL 21/45] hw/i386: Replace magic number with field length calculation Michael S. Tsirkin
2022-03-04 13:40 ` Michael S. Tsirkin [this message]
2022-03-04 13:40 ` [PULL 23/45] virtio-iommu: Support bypass domain Michael S. Tsirkin
2022-03-04 13:40 ` [PULL 24/45] tests/qtest/virtio-iommu-test: Check bypass config Michael S. Tsirkin
2022-03-04 13:40 ` [PULL 25/45] hw/i386/pc_piix: Mark the machine types from version 1.4 to 1.7 as deprecated Michael S. Tsirkin
2022-03-04 13:40 ` [PULL 26/45] hw/pci-bridge/pxb: Fix missing swizzle Michael S. Tsirkin
2022-03-04 13:40 ` [PULL 27/45] virtio-net: Unlimit tx queue size if peer is vdpa Michael S. Tsirkin
2022-03-04 13:40 ` [PULL 28/45] pcie: Add support for Single Root I/O Virtualization (SR/IOV) Michael S. Tsirkin
2022-03-04 13:40 ` [PULL 29/45] pcie: Add some SR/IOV API documentation in docs/pcie_sriov.txt Michael S. Tsirkin
2022-03-04 13:40 ` [PULL 30/45] pcie: Add a helper to the SR/IOV API Michael S. Tsirkin
2022-03-04 13:41 ` [PULL 31/45] pcie: Add 1.2 version token for the Power Management Capability Michael S. Tsirkin
2022-03-04 13:41 ` [PULL 32/45] pci-bridge/xio3130_upstream: Fix error handling Michael S. Tsirkin
2022-03-04 13:41 ` [PULL 33/45] pci-bridge/xio3130_downstream: " Michael S. Tsirkin
2022-03-04 13:41 ` [PULL 34/45] headers: Add pvpanic.h Michael S. Tsirkin
2022-03-04 13:41 ` [PULL 35/45] hw/misc/pvpanic: Use standard headers instead Michael S. Tsirkin
2022-03-04 13:41 ` [PULL 36/45] pci: show id info when pci BDF conflict Michael S. Tsirkin
2022-03-04 13:42 ` [PULL 37/45] pci: expose TYPE_XIO3130_DOWNSTREAM name Michael S. Tsirkin
2022-03-04 13:42 ` [PULL 38/45] acpi: pcihp: pcie: set power on cap on parent slot Michael S. Tsirkin
2022-03-04 13:42 ` [PULL 39/45] pc: add option to disable PS/2 mouse/keyboard Michael S. Tsirkin
2022-03-04 13:42 ` [PULL 40/45] vhost-vsock: detach the virqueue element in case of error Michael S. Tsirkin
2022-03-04 13:42 ` [PULL 41/45] x86: cleanup unused compat_apic_id_mode Michael S. Tsirkin
2022-03-04 13:42 ` [PULL 42/45] event_notifier: add event_notifier_get_wfd() Michael S. Tsirkin
2022-03-04 13:42 ` [PULL 43/45] vhost: use wfd on functions setting vring call fd Michael S. Tsirkin
2022-03-04 13:42 ` [PULL 44/45] configure, meson: allow enabling vhost-user on all POSIX systems Michael S. Tsirkin
2022-03-04 13:42 ` [PULL 45/45] docs: vhost-user: add subsection for non-Linux platforms Michael S. Tsirkin
2022-03-04 22:13 ` [PULL 00/45] virtio,pc,pci: features, cleanups, fixes Peter Maydell
2022-03-06 10:37 ` Michael S. Tsirkin
2022-03-07 10:48 ` Eric Auger
2022-03-07 11:55 ` Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220304133556.233983-23-mst@redhat.com \
--to=mst@redhat.com \
--cc=cohuck@redhat.com \
--cc=eric.auger@redhat.com \
--cc=jean-philippe@linaro.org \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).