[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC v3 0/5] Handling aliased guest memory maps in vhost-vDPA SVQs
From: |
Jonah Palmer |
Subject: |
[RFC v3 0/5] Handling aliased guest memory maps in vhost-vDPA SVQs |
Date: |
Fri, 10 Jan 2025 12:08:29 -0500 |
An issue arises from aliased memory mappings in the guest, where
different GPAs map to the same HVA. For example:
- GPA1->HVA1
- GPA2->HVA1
When these mappings exist in the IOVA->HVA tree, a lookup by an HVA
backed by guest memory results in ambiguities because the same HVA could
correspond to multiple GPAs. This duplication causes issues in managing
IOVA trees for SVQs in vDPA, leading to incorrect behavior.
For example, consider these mapped guest memory regions:
HVA GPA IOVA
------------------------------- ---------------------------
----------------------------
[0x7f7903e00000, 0x7f7983e00000) [0x0, 0x80000000) [0x1000,
0x80000000)
[0x7f7983e00000, 0x7f9903e00000) [0x100000000, 0x2080000000) [0x80001000,
0x2000001000)
[0x7f7903ea0000, 0x7f7903ec0000) [0xfeda0000, 0xfedc0000) [0x2000001000,
0x2000021000)
The last HVA range [0x7f7903ea0000, 0x7f7903ec0000) is contained within
the first HVA range [0x7f7903e00000, 0x7f7983e00000). Despite this, the
GPA ranges for the first and third mappings do not overlap, so the guest
sees them as distinct physical memory regions.
Now consider an operation to unmap the mapping associated with HVA
0x7f7903eb0000. This HVA fits into both the first and third HVA ranges.
When searching the HVA->IOVA tree, the search stops at the first
matching HVA range [0x7f7903e00000, 0x7f7983e00000) due to the behavior
of the red-black tree (GTree). However, the correct mapping to remove is
the third mappings, as the HVA translate to GPA 0xfedb0000, which only
fits in the third mapping's GPA range.
To address this, we implement a GPA->IOVA tree and use the GPAs of
descriptors backed by guest memory when translating to IOVA.
When a descriptor's GPA is used for translation, the GPA->IOVA tree
ensures that each GPA maps to exactly one IOVA, regardless of any
overlapping HVAs. This guarantees that operations such as unmapping or
accessing a descriptor correctly targets the intended memory region in
the guest's address space.
For descriptors not backed by guest memory, the existing IOVA->HVA tree
is still used.
GPAs are unique and non-overlapping within the guest's address space. By
translating GPAs to IOVAs, the ambiguity caused by multiple GPAs mapping
to the same HVA is avoided.
--------
This series is a different approach of [1] and is based off of [2],
where this issue was originally discovered.
RFC v3:
-------
* Decouple the IOVA allocator to support a SVQ IOVA->HVA tree for
host-only mappings.
* Move range check for IOVA allocator to its own patch.
* Implement a GPA->IOVA tree alongside the SVQ IOVA->HVA & IOVA-only
trees.
* Add in_xlat_addr & out_xlat_addr VirtQueueElement members to hold the
GPAs of an element's input/output descriptors (to be used during
translation).
RFC v2:
-------
* Don't decouple IOVA allocator.
* Build a IOVA->GPA tree (instead of GPA->IOVA tree).
* Remove IOVA-only tree and keep the full IOVA->HVA tree.
* Only search through RAMBlocks when we know the HVA is backed by
guest memory.
* Slight rewording of function names.
RFC v1:
-------
* Alternative approach of [1].
* First attempt to address this issue found in [2].
[1]
https://lore.kernel.org/qemu-devel/20240410100345.389462-1-eperezma@redhat.com
[2]
https://lore.kernel.org/qemu-devel/20240201180924.487579-1-eperezma@redhat.com
Jonah Palmer (5):
vhost-vdpa: Decouple the IOVA allocator
vhost-iova-tree: Remove range check for IOVA allocator
vhost-vdpa: Implement the GPA->IOVA tree
virtio: add in_xlat_addr & out_xlat_addr VirtQueueElement members
svq: Support translations via GPAs in vhost_svq_translate_addr
hw/display/virtio-gpu.c | 5 +-
hw/hyperv/vmbus.c | 8 ++-
hw/ide/ahci.c | 7 ++-
hw/usb/libhw.c | 2 +-
hw/virtio/vhost-iova-tree.c | 88 ++++++++++++++++++++++++++++--
hw/virtio/vhost-iova-tree.h | 5 ++
hw/virtio/vhost-shadow-virtqueue.c | 49 +++++++++++++----
hw/virtio/vhost-vdpa.c | 43 ++++++++++-----
hw/virtio/virtio.c | 50 ++++++++++++-----
include/hw/pci/pci_device.h | 2 +-
include/hw/virtio/virtio.h | 2 +
include/qemu/iova-tree.h | 22 ++++++++
include/system/dma.h | 25 ++++++++-
net/vhost-vdpa.c | 13 ++++-
system/dma-helpers.c | 2 +-
util/iova-tree.c | 46 ++++++++++++++++
16 files changed, 310 insertions(+), 59 deletions(-)
--
2.43.5
- [RFC v3 0/5] Handling aliased guest memory maps in vhost-vDPA SVQs,
Jonah Palmer <=
- [RFC v3 2/5] vhost-iova-tree: Remove range check for IOVA allocator, Jonah Palmer, 2025/01/10
- [RFC v3 3/5] vhost-vdpa: Implement the GPA->IOVA tree, Jonah Palmer, 2025/01/10
- [RFC v3 4/5] virtio: add in_xlat_addr & out_xlat_addr VirtQueueElement members, Jonah Palmer, 2025/01/10
- [RFC v3 5/5] svq: Support translations via GPAs in vhost_svq_translate_addr, Jonah Palmer, 2025/01/10
- [RFC v3 1/5] vhost-vdpa: Decouple the IOVA allocator, Jonah Palmer, 2025/01/10