* [PATCH v4 0/4] VIRTIO-IOMMU: Introduce an aw-bits option
@ 2024-02-13 18:28 Eric Auger
2024-02-13 18:28 ` [PATCH v4 1/4] virtio-iommu: Add an option to define the input range width Eric Auger
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Eric Auger @ 2024-02-13 18:28 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, jean-philippe,
mst, peter.maydell, clg, zhenzhong.duan, yanghliu
Cc: alex.williamson, jasowang
In [1] and [2] we attempted to fix a case where a VFIO-PCI device
protected with a virtio-iommu is assigned to an x86 guest. On x86
the physical IOMMU may have an address width (gaw) of 39 or 48 bits
whereas the virtio-iommu exposes a 64b input address space by default.
Hence the guest may try to use the full 64b space and DMA MAP
failures may be encountered. To work around this issue we endeavoured
to pass usable host IOVA regions (excluding the out of range space) from
VFIO to the virtio-iommu device so that the virtio-iommu driver can
query those latter during the probe request and let the guest iommu
kernel subsystem carve them out.
However if there are several devices in the same iommu group,
only the reserved regions of the first one are taken into
account by the iommu subsystem of the guest. This generally
works on baremetal because devices are not going to
expose different reserved regions. However in our case, this
may prevent from taking into account the host iommu geometry.
So the simplest solution to this problem looks to introduce an
input address width option, aw-bits, which matches what is
done on the intel-iommu. By default, from now on it is set
to 39 bits with pc_q35 and 48 with arm virt. This replaces the
previous default value of 64b. So we need to introduce a compat
for machines older than 9.0 to behave similarly. We use
hw_compat_8_2 to acheive that goal.
Outstanding series [2] remains useful to let resv regions beeing
communicated on time before the probe request.
[1] [PATCH v4 00/12] VIRTIO-IOMMU/VFIO: Don't assume 64b IOVA space
https://lore.kernel.org/all/20231019134651.842175-1-eric.auger@redhat.com/
- This is merged -
[2] [RFC 0/7] VIRTIO-IOMMU/VFIO: Fix host iommu geometry handling for hotplugged devices
https://lore.kernel.org/all/20240117080414.316890-1-eric.auger@redhat.com/
- This is pending for review on the ML -
This series can be found at:
https://github.com/eauger/qemu/tree/virtio-iommu-aw-bits-v4
previous
https://github.com/eauger/qemu/tree/virtio-iommu-aw-bits-v3
History:
v3 -> v4:
- remove dependency on
[PATCH v2] virtio-iommu: Use qemu_real_host_page_mask as default page_size_mask
- Fix qtest error [Michael]
- add doc entry in qemu-options.hx
v2 -> v3:
- Collected Zhenzhong and Cédric's R-b + Yanghang's T-b
- use &error_abort instead of NULL error handle
on object_property_get_uint() call (Cédric)
- use VTD_HOST_AW_39BIT (Cédric)
v1 -> v2
- Limit aw to 48b on ARM
- Check aw is within [32,64]
- Use hw_compat_8_2
Eric Auger (4):
virtio-iommu: Add an option to define the input range width
virtio-iommu: Trace domain range limits as unsigned int
hw: Set virtio-iommu aw-bits default value on pc_q35 and arm virt
qemu-options.hx: Add an entry for virtio-iommu-pci and document
aw-bits
include/hw/virtio/virtio-iommu.h | 1 +
hw/arm/virt.c | 6 ++++++
hw/core/machine.c | 5 ++++-
hw/i386/pc.c | 6 ++++++
hw/virtio/virtio-iommu.c | 7 ++++++-
tests/qtest/virtio-iommu-test.c | 2 +-
hw/virtio/trace-events | 2 +-
qemu-options.hx | 8 ++++++++
8 files changed, 33 insertions(+), 4 deletions(-)
--
2.41.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v4 1/4] virtio-iommu: Add an option to define the input range width
2024-02-13 18:28 [PATCH v4 0/4] VIRTIO-IOMMU: Introduce an aw-bits option Eric Auger
@ 2024-02-13 18:28 ` Eric Auger
2024-02-13 18:28 ` [PATCH v4 2/4] virtio-iommu: Trace domain range limits as unsigned int Eric Auger
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Eric Auger @ 2024-02-13 18:28 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, jean-philippe,
mst, peter.maydell, clg, zhenzhong.duan, yanghliu
Cc: alex.williamson, jasowang
aw-bits is a new option that allows to set the bit width of
the input address range. This value will be used as a default for
the device config input_range.end. By default it is set to 64 bits
which is the current value.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
---
v1 -> v2:
- Check the aw-bits value is within [32,64]
---
include/hw/virtio/virtio-iommu.h | 1 +
hw/virtio/virtio-iommu.c | 7 ++++++-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/include/hw/virtio/virtio-iommu.h b/include/hw/virtio/virtio-iommu.h
index 781ebaea8f..5fbe4677c2 100644
--- a/include/hw/virtio/virtio-iommu.h
+++ b/include/hw/virtio/virtio-iommu.h
@@ -66,6 +66,7 @@ struct VirtIOIOMMU {
bool boot_bypass;
Notifier machine_done;
bool granule_frozen;
+ uint8_t aw_bits;
};
#endif
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index 8a4bd933c6..666c41fe64 100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -1314,7 +1314,11 @@ static void virtio_iommu_device_realize(DeviceState *dev, Error **errp)
*/
s->config.bypass = s->boot_bypass;
s->config.page_size_mask = qemu_target_page_mask();
- s->config.input_range.end = UINT64_MAX;
+ if (s->aw_bits < 32 || s->aw_bits > 64) {
+ error_setg(errp, "aw-bits must be within [32,64]");
+ }
+ s->config.input_range.end =
+ s->aw_bits == 64 ? UINT64_MAX : BIT_ULL(s->aw_bits) - 1;
s->config.domain_range.end = UINT32_MAX;
s->config.probe_size = VIOMMU_PROBE_SIZE;
@@ -1522,6 +1526,7 @@ static Property virtio_iommu_properties[] = {
DEFINE_PROP_LINK("primary-bus", VirtIOIOMMU, primary_bus,
TYPE_PCI_BUS, PCIBus *),
DEFINE_PROP_BOOL("boot-bypass", VirtIOIOMMU, boot_bypass, true),
+ DEFINE_PROP_UINT8("aw-bits", VirtIOIOMMU, aw_bits, 64),
DEFINE_PROP_END_OF_LIST(),
};
--
2.41.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v4 2/4] virtio-iommu: Trace domain range limits as unsigned int
2024-02-13 18:28 [PATCH v4 0/4] VIRTIO-IOMMU: Introduce an aw-bits option Eric Auger
2024-02-13 18:28 ` [PATCH v4 1/4] virtio-iommu: Add an option to define the input range width Eric Auger
@ 2024-02-13 18:28 ` Eric Auger
2024-02-13 18:28 ` [PATCH v4 3/4] hw: Set virtio-iommu aw-bits default value on pc_q35 and arm virt Eric Auger
2024-02-13 18:28 ` [PATCH v4 4/4] qemu-options.hx: Add an entry for virtio-iommu-pci and document aw-bits Eric Auger
3 siblings, 0 replies; 6+ messages in thread
From: Eric Auger @ 2024-02-13 18:28 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, jean-philippe,
mst, peter.maydell, clg, zhenzhong.duan, yanghliu
Cc: alex.williamson, jasowang
Use %u format to trace domain_range limits.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
---
hw/virtio/trace-events | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index 77905d1994..2350849fbd 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -111,7 +111,7 @@ 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, 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_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=%u domain range end=%u 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"
--
2.41.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v4 3/4] hw: Set virtio-iommu aw-bits default value on pc_q35 and arm virt
2024-02-13 18:28 [PATCH v4 0/4] VIRTIO-IOMMU: Introduce an aw-bits option Eric Auger
2024-02-13 18:28 ` [PATCH v4 1/4] virtio-iommu: Add an option to define the input range width Eric Auger
2024-02-13 18:28 ` [PATCH v4 2/4] virtio-iommu: Trace domain range limits as unsigned int Eric Auger
@ 2024-02-13 18:28 ` Eric Auger
2024-02-13 18:28 ` [PATCH v4 4/4] qemu-options.hx: Add an entry for virtio-iommu-pci and document aw-bits Eric Auger
3 siblings, 0 replies; 6+ messages in thread
From: Eric Auger @ 2024-02-13 18:28 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, jean-philippe,
mst, peter.maydell, clg, zhenzhong.duan, yanghliu
Cc: alex.williamson, jasowang
Currently the default input range can extend to 64 bits. On x86,
when the virtio-iommu protects vfio devices, the physical iommu
may support only 39 bits. Let's set the default to 39, as done
for the intel-iommu. On ARM we set 48b as a default (matching
SMMUv3 SMMU_IDR5.VAX == 0).
We use hw_compat_8_2 to handle the compatibility for machines
before 9.0 which used to have a virtio-iommu default input range
of 64 bits.
Of course if aw-bits is set from the command line, the default
is overriden.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Tested-by: Yanghang Liu<yanghliu@redhat.com>
---
v3 -> v4:
- update the qos test to relax the check on the max input IOVA
v2 -> v3:
- collected Zhenzhong's R-b
- use &error_abort instead of NULL error handle
on object_property_get_uint() call (Cédric)
- use VTD_HOST_AW_39BIT (Cédric)
v1 -> v2:
- set aw-bits to 48b on ARM
- use hw_compat_8_2 to handle the compat for older machines
which used 64b as a default
---
hw/arm/virt.c | 6 ++++++
hw/core/machine.c | 5 ++++-
hw/i386/pc.c | 6 ++++++
hw/virtio/virtio-iommu.c | 2 +-
tests/qtest/virtio-iommu-test.c | 2 +-
5 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 368c2a415a..0994f2a560 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -2716,10 +2716,16 @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) {
virtio_md_pci_pre_plug(VIRTIO_MD_PCI(dev), MACHINE(hotplug_dev), errp);
} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
+ uint8_t aw_bits = object_property_get_uint(OBJECT(dev),
+ "aw-bits", &error_abort);
hwaddr db_start = 0, db_end = 0;
QList *reserved_regions;
char *resv_prop_str;
+ if (!aw_bits) {
+ qdev_prop_set_uint8(dev, "aw-bits", 48);
+ }
+
if (vms->iommu != VIRT_IOMMU_NONE) {
error_setg(errp, "virt machine does not support multiple IOMMUs");
return;
diff --git a/hw/core/machine.c b/hw/core/machine.c
index fb5afdcae4..70ac96954c 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -30,9 +30,12 @@
#include "exec/confidential-guest-support.h"
#include "hw/virtio/virtio-pci.h"
#include "hw/virtio/virtio-net.h"
+#include "hw/virtio/virtio-iommu.h"
#include "audio/audio.h"
-GlobalProperty hw_compat_8_2[] = {};
+GlobalProperty hw_compat_8_2[] = {
+ { TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "64" },
+};
const size_t hw_compat_8_2_len = G_N_ELEMENTS(hw_compat_8_2);
GlobalProperty hw_compat_8_1[] = {
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 196827531a..ee2d379c90 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1456,6 +1456,8 @@ static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) {
virtio_md_pci_pre_plug(VIRTIO_MD_PCI(dev), MACHINE(hotplug_dev), errp);
} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
+ uint8_t aw_bits = object_property_get_uint(OBJECT(dev),
+ "aw-bits", &error_abort);
/* Declare the APIC range as the reserved MSI region */
char *resv_prop_str = g_strdup_printf("0xfee00000:0xfeefffff:%d",
VIRTIO_IOMMU_RESV_MEM_T_MSI);
@@ -1464,6 +1466,10 @@ static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
qlist_append_str(reserved_regions, resv_prop_str);
qdev_prop_set_array(dev, "reserved-regions", reserved_regions);
+ if (!aw_bits) {
+ qdev_prop_set_uint8(dev, "aw-bits", VTD_HOST_AW_39BIT);
+ }
+
g_free(resv_prop_str);
}
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index 666c41fe64..a4daf7285a 100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -1526,7 +1526,7 @@ static Property virtio_iommu_properties[] = {
DEFINE_PROP_LINK("primary-bus", VirtIOIOMMU, primary_bus,
TYPE_PCI_BUS, PCIBus *),
DEFINE_PROP_BOOL("boot-bypass", VirtIOIOMMU, boot_bypass, true),
- DEFINE_PROP_UINT8("aw-bits", VirtIOIOMMU, aw_bits, 64),
+ DEFINE_PROP_UINT8("aw-bits", VirtIOIOMMU, aw_bits, 0),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/tests/qtest/virtio-iommu-test.c b/tests/qtest/virtio-iommu-test.c
index 068e7a9e6c..0f36381acb 100644
--- a/tests/qtest/virtio-iommu-test.c
+++ b/tests/qtest/virtio-iommu-test.c
@@ -34,7 +34,7 @@ static void pci_config(void *obj, void *data, QGuestAllocator *t_alloc)
uint8_t bypass = qvirtio_config_readb(dev, 36);
g_assert_cmpint(input_range_start, ==, 0);
- g_assert_cmphex(input_range_end, ==, UINT64_MAX);
+ g_assert_cmphex(input_range_end, >=, 32);
g_assert_cmpint(domain_range_start, ==, 0);
g_assert_cmpint(domain_range_end, ==, UINT32_MAX);
g_assert_cmpint(bypass, ==, 1);
--
2.41.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v4 4/4] qemu-options.hx: Add an entry for virtio-iommu-pci and document aw-bits
2024-02-13 18:28 [PATCH v4 0/4] VIRTIO-IOMMU: Introduce an aw-bits option Eric Auger
` (2 preceding siblings ...)
2024-02-13 18:28 ` [PATCH v4 3/4] hw: Set virtio-iommu aw-bits default value on pc_q35 and arm virt Eric Auger
@ 2024-02-13 18:28 ` Eric Auger
2024-02-14 7:47 ` Cédric Le Goater
3 siblings, 1 reply; 6+ messages in thread
From: Eric Auger @ 2024-02-13 18:28 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, jean-philippe,
mst, peter.maydell, clg, zhenzhong.duan, yanghliu
Cc: alex.williamson, jasowang
We are missing an entry for the virtio-iommu-pci device. Add the
information on which machine it is currently supported and document
the new aw-bits option.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
qemu-options.hx | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/qemu-options.hx b/qemu-options.hx
index 8547254dbf..6a8c970640 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1172,6 +1172,14 @@ SRST
Please also refer to the wiki page for general scenarios of VT-d
emulation in QEMU: https://wiki.qemu.org/Features/VT-d.
+``-device virtio-iommu-pci[,option=...]``
+ This is only supported by ``-machine q35`` and ``-machine virt``.
+ It supports below options:
+
+ ``aw-bits=val`` (val between 32 and 64, default depends on machine)
+ This decides the address width of IOVA address space. With
+ q35 it defaults to 39 bits. On arm virt it defaults to 48 bits.
+
ERST
DEF("name", HAS_ARG, QEMU_OPTION_name,
--
2.41.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v4 4/4] qemu-options.hx: Add an entry for virtio-iommu-pci and document aw-bits
2024-02-13 18:28 ` [PATCH v4 4/4] qemu-options.hx: Add an entry for virtio-iommu-pci and document aw-bits Eric Auger
@ 2024-02-14 7:47 ` Cédric Le Goater
0 siblings, 0 replies; 6+ messages in thread
From: Cédric Le Goater @ 2024-02-14 7:47 UTC (permalink / raw)
To: Eric Auger, eric.auger.pro, qemu-devel, qemu-arm, jean-philippe,
mst, peter.maydell, zhenzhong.duan, yanghliu
Cc: alex.williamson, jasowang
On 2/13/24 19:28, Eric Auger wrote:
> We are missing an entry for the virtio-iommu-pci device. Add the
> information on which machine it is currently supported and document
> the new aw-bits option.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> ---
> qemu-options.hx | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 8547254dbf..6a8c970640 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -1172,6 +1172,14 @@ SRST
> Please also refer to the wiki page for general scenarios of VT-d
> emulation in QEMU: https://wiki.qemu.org/Features/VT-d.
>
> +``-device virtio-iommu-pci[,option=...]``
> + This is only supported by ``-machine q35`` and ``-machine virt``.
> + It supports below options:
> +
> + ``aw-bits=val`` (val between 32 and 64, default depends on machine)
> + This decides the address width of IOVA address space. With
> + q35 it defaults to 39 bits. On arm virt it defaults to 48 bits.
Minor improvement :
"It defaults to 39 bits on q35 machines and 48 bits on ARM virt machines."
Anyhow,
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Thanks,
C.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2024-02-14 7:47 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-02-13 18:28 [PATCH v4 0/4] VIRTIO-IOMMU: Introduce an aw-bits option Eric Auger
2024-02-13 18:28 ` [PATCH v4 1/4] virtio-iommu: Add an option to define the input range width Eric Auger
2024-02-13 18:28 ` [PATCH v4 2/4] virtio-iommu: Trace domain range limits as unsigned int Eric Auger
2024-02-13 18:28 ` [PATCH v4 3/4] hw: Set virtio-iommu aw-bits default value on pc_q35 and arm virt Eric Auger
2024-02-13 18:28 ` [PATCH v4 4/4] qemu-options.hx: Add an entry for virtio-iommu-pci and document aw-bits Eric Auger
2024-02-14 7:47 ` Cédric Le Goater
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).