Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

virtio: replace restricted mem access flag with callback

Instead of having a global flag to require restricted memory access
for all virtio devices, introduce a callback which can select that
requirement on a per-device basis.

For convenience add a common function returning always true, which can
be used for use cases like SEV.

Per default use a callback always returning false.

As the callback needs to be set in early init code already, add a
virtio anchor which is builtin in case virtio is enabled.

Signed-off-by: Juergen Gross <jgross@suse.com>
Tested-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com> # Arm64 guest using Xen
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Link: https://lore.kernel.org/r/20220622063838.8854-2-jgross@suse.com
Signed-off-by: Juergen Gross <jgross@suse.com>

+51 -13
+2 -2
arch/s390/mm/init.c
··· 31 31 #include <linux/cma.h> 32 32 #include <linux/gfp.h> 33 33 #include <linux/dma-direct.h> 34 - #include <linux/platform-feature.h> 35 34 #include <asm/processor.h> 36 35 #include <linux/uaccess.h> 37 36 #include <asm/pgalloc.h> ··· 47 48 #include <asm/kasan.h> 48 49 #include <asm/dma-mapping.h> 49 50 #include <asm/uv.h> 51 + #include <linux/virtio_anchor.h> 50 52 #include <linux/virtio_config.h> 51 53 52 54 pgd_t swapper_pg_dir[PTRS_PER_PGD] __section(".bss..swapper_pg_dir"); ··· 175 175 if (!is_prot_virt_guest()) 176 176 return; 177 177 178 - platform_set(PLATFORM_VIRTIO_RESTRICTED_MEM_ACCESS); 178 + virtio_set_mem_acc_cb(virtio_require_restricted_mem_acc); 179 179 180 180 /* make sure bounce buffers are shared */ 181 181 swiotlb_init(true, SWIOTLB_FORCE | SWIOTLB_VERBOSE);
+2 -2
arch/x86/mm/mem_encrypt_amd.c
··· 20 20 #include <linux/bitops.h> 21 21 #include <linux/dma-mapping.h> 22 22 #include <linux/virtio_config.h> 23 + #include <linux/virtio_anchor.h> 23 24 #include <linux/cc_platform.h> 24 - #include <linux/platform-feature.h> 25 25 26 26 #include <asm/tlbflush.h> 27 27 #include <asm/fixmap.h> ··· 245 245 swiotlb_adjust_size(size); 246 246 247 247 /* Set restricted memory access for virtio. */ 248 - platform_set(PLATFORM_VIRTIO_RESTRICTED_MEM_ACCESS); 248 + virtio_set_mem_acc_cb(virtio_require_restricted_mem_acc); 249 249 } 250 250 251 251 static unsigned long pg_level_to_pfn(int level, pte_t *kpte, pgprot_t *ret_prot)
+4
drivers/virtio/Kconfig
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 + config VIRTIO_ANCHOR 3 + bool 4 + 2 5 config VIRTIO 3 6 tristate 7 + select VIRTIO_ANCHOR 4 8 help 5 9 This option is selected by any driver which implements the virtio 6 10 bus, such as CONFIG_VIRTIO_PCI, CONFIG_VIRTIO_MMIO, CONFIG_RPMSG
+1
drivers/virtio/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 obj-$(CONFIG_VIRTIO) += virtio.o virtio_ring.o 3 + obj-$(CONFIG_VIRTIO_ANCHOR) += virtio_anchor.o 3 4 obj-$(CONFIG_VIRTIO_PCI_LIB) += virtio_pci_modern_dev.o 4 5 obj-$(CONFIG_VIRTIO_PCI_LIB_LEGACY) += virtio_pci_legacy_dev.o 5 6 obj-$(CONFIG_VIRTIO_MMIO) += virtio_mmio.o
+2 -2
drivers/virtio/virtio.c
··· 2 2 #include <linux/virtio.h> 3 3 #include <linux/spinlock.h> 4 4 #include <linux/virtio_config.h> 5 + #include <linux/virtio_anchor.h> 5 6 #include <linux/module.h> 6 7 #include <linux/idr.h> 7 8 #include <linux/of.h> 8 - #include <linux/platform-feature.h> 9 9 #include <uapi/linux/virtio_ids.h> 10 10 11 11 /* Unique numbering for virtio devices. */ ··· 174 174 175 175 might_sleep(); 176 176 177 - if (platform_has(PLATFORM_VIRTIO_RESTRICTED_MEM_ACCESS)) { 177 + if (virtio_check_mem_acc_cb(dev)) { 178 178 if (!virtio_has_feature(dev, VIRTIO_F_VERSION_1)) { 179 179 dev_warn(&dev->dev, 180 180 "device must provide VIRTIO_F_VERSION_1\n");
+18
drivers/virtio/virtio_anchor.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + #include <linux/virtio.h> 3 + #include <linux/virtio_anchor.h> 4 + 5 + bool virtio_require_restricted_mem_acc(struct virtio_device *dev) 6 + { 7 + return true; 8 + } 9 + EXPORT_SYMBOL_GPL(virtio_require_restricted_mem_acc); 10 + 11 + static bool virtio_no_restricted_mem_acc(struct virtio_device *dev) 12 + { 13 + return false; 14 + } 15 + 16 + bool (*virtio_check_mem_acc_cb)(struct virtio_device *dev) = 17 + virtio_no_restricted_mem_acc; 18 + EXPORT_SYMBOL_GPL(virtio_check_mem_acc_cb);
+1 -5
include/linux/platform-feature.h
··· 6 6 #include <asm/platform-feature.h> 7 7 8 8 /* The platform features are starting with the architecture specific ones. */ 9 - 10 - /* Used to enable platform specific DMA handling for virtio devices. */ 11 - #define PLATFORM_VIRTIO_RESTRICTED_MEM_ACCESS (0 + PLATFORM_ARCH_FEAT_N) 12 - 13 - #define PLATFORM_FEAT_N (1 + PLATFORM_ARCH_FEAT_N) 9 + #define PLATFORM_FEAT_N (0 + PLATFORM_ARCH_FEAT_N) 14 10 15 11 void platform_set(unsigned int feature); 16 12 void platform_clear(unsigned int feature);
+19
include/linux/virtio_anchor.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef _LINUX_VIRTIO_ANCHOR_H 3 + #define _LINUX_VIRTIO_ANCHOR_H 4 + 5 + #ifdef CONFIG_VIRTIO_ANCHOR 6 + struct virtio_device; 7 + 8 + bool virtio_require_restricted_mem_acc(struct virtio_device *dev); 9 + extern bool (*virtio_check_mem_acc_cb)(struct virtio_device *dev); 10 + 11 + static inline void virtio_set_mem_acc_cb(bool (*func)(struct virtio_device *)) 12 + { 13 + virtio_check_mem_acc_cb = func; 14 + } 15 + #else 16 + #define virtio_set_mem_acc_cb(func) do { } while (0) 17 + #endif 18 + 19 + #endif /* _LINUX_VIRTIO_ANCHOR_H */
+2 -2
include/xen/xen.h
··· 52 52 extern u64 xen_saved_max_mem_size; 53 53 #endif 54 54 55 - #include <linux/platform-feature.h> 55 + #include <linux/virtio_anchor.h> 56 56 57 57 static inline void xen_set_restricted_virtio_memory_access(void) 58 58 { 59 59 if (IS_ENABLED(CONFIG_XEN_VIRTIO) && xen_domain()) 60 - platform_set(PLATFORM_VIRTIO_RESTRICTED_MEM_ACCESS); 60 + virtio_set_mem_acc_cb(virtio_require_restricted_mem_acc); 61 61 } 62 62 63 63 #ifdef CONFIG_XEN_UNPOPULATED_ALLOC