[RFC] Add DMA_API support for Virtio devices earlier than VirtIO 1.0
From: Erdem Aktas
Date: Wed Oct 27 2021 - 19:28:52 EST
Enable DMA_API for any VirtIO device earlier than Virtio 1.0 which
is the only way for those devices to be configured correctly when
memory access is retricted.
Virtio devices can use DMA_API to translate guest phsical addresses to
device physical addresses if VIRTIO_F_ACCESS_PLATFORM feature is set
while the device is being initialized. VIRTIO_F_ACCESS_PLATFORM
feature is only supported in VirtIO 1.0 and later devices. This prevents
any device using an earlier VirtIO version than Virtio 1.0 to be
attached when memory access is restricted ie memory encryption features
(AMD SEV [ES/SNP], Intel TDX, etc..) are enabled.
Signed-off-by: Erdem Aktas <erdemaktas@xxxxxxxxxx>
---
I have tested the this patch using linux-stable.git head, 5.15.0-rc6
kernel and scsi disk with virtio 0.95 version with legacy VM and
Confidential VM (AMD SEV). I want to get feedback if
there is any risk or downside of enabling DMA_API on older virtio
drivers when memory encrytion is enabled.
drivers/virtio/virtio.c | 7 ++-----
include/linux/virtio_config.h | 22 ++++++++++++++--------
2 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index 236081afe9a2..71115ba85d07 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -179,11 +179,8 @@ int virtio_finalize_features(struct virtio_device *dev)
if (ret) {
if (!virtio_has_feature(dev, VIRTIO_F_VERSION_1)) {
dev_warn(&dev->dev,
- "device must provide VIRTIO_F_VERSION_1\n");
- return -ENODEV;
- }
-
- if (!virtio_has_feature(dev, VIRTIO_F_ACCESS_PLATFORM)) {
+ "device does not provide VIRTIO_F_VERSION_1 while restricted memory access is enabled!.\n");
+ } else if (!virtio_has_feature(dev, VIRTIO_F_ACCESS_PLATFORM)) {
dev_warn(&dev->dev,
"device must provide VIRTIO_F_ACCESS_PLATFORM\n");
return -ENODEV;
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index 8519b3ae5d52..6eacb4d43318 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -170,6 +170,15 @@ static inline bool virtio_has_feature(const struct virtio_device *vdev,
return __virtio_test_bit(vdev, fbit);
}
+#ifdef CONFIG_ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS
+int arch_has_restricted_virtio_memory_access(void);
+#else
+static inline int arch_has_restricted_virtio_memory_access(void)
+{
+ return 0;
+}
+#endif /* CONFIG_ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS */
+
/**
* virtio_has_dma_quirk - determine whether this device has the DMA quirk
* @vdev: the device
@@ -180,6 +189,11 @@ static inline bool virtio_has_dma_quirk(const struct virtio_device *vdev)
* Note the reverse polarity of the quirk feature (compared to most
* other features), this is for compatibility with legacy systems.
*/
+ if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1) &&
+ arch_has_restricted_virtio_memory_access())
+ return false;
+
+
return !virtio_has_feature(vdev, VIRTIO_F_ACCESS_PLATFORM);
}
@@ -558,13 +572,5 @@ static inline void virtio_cwrite64(struct virtio_device *vdev,
_r; \
})
-#ifdef CONFIG_ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS
-int arch_has_restricted_virtio_memory_access(void);
-#else
-static inline int arch_has_restricted_virtio_memory_access(void)
-{
- return 0;
-}
-#endif /* CONFIG_ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS */
#endif /* _LINUX_VIRTIO_CONFIG_H */
--
2.30.2