This patch introduces the new memory accessor for vringh. It is able to use vringh to virtio rings located on iomemory region. Signed-off-by: Shunsuke Mie <mie@xxxxxxxxxx> --- drivers/vhost/Kconfig | 6 ++++ drivers/vhost/vringh.c | 76 ++++++++++++++++++++++++++++++++++++++++++ include/linux/vringh.h | 8 +++++ 3 files changed, 90 insertions(+) diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig index 587fbae06182..a79a4efbc817 100644 --- a/drivers/vhost/Kconfig +++ b/drivers/vhost/Kconfig @@ -6,6 +6,12 @@ config VHOST_IOTLB This option is selected by any driver which needs to support an IOMMU in software. +config VHOST_IOMEM + tristate + select VHOST_RING + help + Generic IOMEM implementation for vhost and vringh. + config VHOST_RING tristate select VHOST_IOTLB diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c index 46fb315483ed..e3d9c7281ad0 100644 --- a/drivers/vhost/vringh.c +++ b/drivers/vhost/vringh.c @@ -18,6 +18,9 @@ #include <linux/highmem.h> #include <linux/vhost_iotlb.h> #endif +#if IS_REACHABLE(CONFIG_VHOST_IOMEM) +#include <linux/io.h> +#endif #include <uapi/linux/virtio_config.h> static __printf(1,2) __cold void vringh_bad(const char *fmt, ...) @@ -1165,4 +1168,77 @@ EXPORT_SYMBOL(vringh_set_iotlb); #endif +#if IS_REACHABLE(CONFIG_VHOST_IOMEM) + +/* io-memory space access helpers. */ +static int getu16_iomem(const struct vringh *vrh, u16 *val, const __virtio16 *p) +{ + *val = vringh16_to_cpu(vrh, ioread16(p)); + return 0; +} + +static int putu16_iomem(const struct vringh *vrh, __virtio16 *p, u16 val) +{ + iowrite16(cpu_to_vringh16(vrh, val), p); + return 0; +} + +static int copydesc_iomem(const struct vringh *vrh, void *dst, const void *src, + size_t len) +{ + memcpy_fromio(dst, src, len); + return 0; +} + +static int putused_iomem(const struct vringh *vrh, struct vring_used_elem *dst, + const struct vring_used_elem *src, unsigned int num) +{ + memcpy_toio(dst, src, num * sizeof(*dst)); + return 0; +} + +static int xfer_from_iomem(const struct vringh *vrh, void *src, void *dst, + size_t len) +{ + memcpy_fromio(dst, src, len); + return 0; +} + +static int xfer_to_iomem(const struct vringh *vrh, void *dst, void *src, + size_t len) +{ + memcpy_toio(dst, src, len); + return 0; +} + +static struct vringh_ops iomem_vringh_ops = { + .getu16 = getu16_iomem, + .putu16 = putu16_iomem, + .xfer_from = xfer_from_iomem, + .xfer_to = xfer_to_iomem, + .putused = putused_iomem, + .copydesc = copydesc_iomem, + .range_check = no_range_check, + .getrange = NULL, +}; + +int vringh_init_iomem(struct vringh *vrh, u64 features, unsigned int num, + bool weak_barriers, gfp_t gfp, struct vring_desc *desc, + struct vring_avail *avail, struct vring_used *used) +{ + int err; + + err = __vringh_init(vrh, features, num, weak_barriers, gfp, desc, avail, + used); + if (err) + return err; + + memcpy(&vrh->ops, &iomem_vringh_ops, sizeof(iomem_vringh_ops)); + + return 0; +} +EXPORT_SYMBOL(vringh_init_iomem); + +#endif + MODULE_LICENSE("GPL"); diff --git a/include/linux/vringh.h b/include/linux/vringh.h index 89c73605c85f..420c2d0ed398 100644 --- a/include/linux/vringh.h +++ b/include/linux/vringh.h @@ -265,4 +265,12 @@ int vringh_init_iotlb(struct vringh *vrh, u64 features, #endif /* CONFIG_VHOST_IOTLB */ +#if IS_REACHABLE(CONFIG_VHOST_IOMEM) + +int vringh_init_iomem(struct vringh *vrh, u64 features, unsigned int num, + bool weak_barriers, gfp_t gfp, struct vring_desc *desc, + struct vring_avail *avail, struct vring_used *used); + +#endif /* CONFIG_VHOST_IOMEM */ + #endif /* _LINUX_VRINGH_H */ -- 2.25.1 _______________________________________________ Virtualization mailing list Virtualization@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linuxfoundation.org/mailman/listinfo/virtualization