From: "Dr. David Alan Gilbert" <dgilb...@redhat.com> Add a cache BAR into which files will be directly mapped. The size cacn be set with the cache-size= property, e.g. -device vhost-user-fs-pci,chardev=char0,tag=myfs,cache-size=16G
Signed-off-by: Dr. David Alan Gilbert <dgilb...@redhat.com> --- hw/virtio/vhost-user-fs.c | 16 ++++++++++++++++ hw/virtio/virtio-pci.c | 19 +++++++++++++++++++ hw/virtio/virtio-pci.h | 1 + include/hw/virtio/vhost-user-fs.h | 2 ++ include/standard-headers/linux/virtio_fs.h | 5 +++++ 5 files changed, 43 insertions(+) diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c index bc21beeac3..14ee922661 100644 --- a/hw/virtio/vhost-user-fs.c +++ b/hw/virtio/vhost-user-fs.c @@ -195,6 +195,21 @@ static void vuf_device_realize(DeviceState *dev, Error **errp) VIRTQUEUE_MAX_SIZE); return; } + if (!is_power_of_2(fs->conf.cache_size) || + fs->conf.cache_size < sysconf(_SC_PAGESIZE)) { + error_setg(errp, "cache-size property must be a power of 2 " + "no smaller than the page size"); + return; + } + /* We need a region with some host memory, 'ram' is the easiest */ + memory_region_init_ram_nomigrate(&fs->cache, OBJECT(vdev), + "virtio-fs-cache", + fs->conf.cache_size, NULL); + /* But we don't actually want anyone reading/writing the raw + * area with no cache data. + */ + mprotect(memory_region_get_ram_ptr(&fs->cache), fs->conf.cache_size, + PROT_NONE); fs->vhost_user = vhost_user_init(); if (!fs->vhost_user) { @@ -263,6 +278,7 @@ static Property vuf_properties[] = { DEFINE_PROP_UINT16("num-queues", VHostUserFS, conf.num_queues, 1), DEFINE_PROP_UINT16("queue-size", VHostUserFS, conf.queue_size, 128), DEFINE_PROP_STRING("vhostfd", VHostUserFS, conf.vhostfd), + DEFINE_PROP_SIZE("cache-size", VHostUserFS, conf.cache_size, 1ull << 30), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index d744f93655..e819a29fb1 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -18,6 +18,7 @@ #include "qemu/osdep.h" #include "standard-headers/linux/virtio_pci.h" +#include "standard-headers/linux/virtio_fs.h" #include "hw/virtio/virtio.h" #include "hw/virtio/virtio-blk.h" #include "hw/virtio/virtio-net.h" @@ -2678,9 +2679,27 @@ static void vhost_user_fs_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) { VHostUserFSPCI *dev = VHOST_USER_FS_PCI(vpci_dev); DeviceState *vdev = DEVICE(&dev->vdev); + uint64_t cachesize; qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus)); object_property_set_bool(OBJECT(vdev), true, "realized", errp); + cachesize = memory_region_size(&dev->vdev.cache); + + /* The bar starts with the data/DAX cache + * Others will be added later. + */ + memory_region_init(&dev->cachebar, OBJECT(vpci_dev), + "vhost-fs-pci-cachebar", cachesize); + memory_region_add_subregion(&dev->cachebar, 0, &dev->vdev.cache); + virtio_pci_add_shm_cap(vpci_dev, VIRTIO_FS_PCI_CACHE_BAR, 0, cachesize, + VIRTIO_FS_PCI_SHMCAP_ID_CACHE); + + /* After 'realized' so the memory region exists */ + pci_register_bar(&vpci_dev->pci_dev, VIRTIO_FS_PCI_CACHE_BAR, + PCI_BASE_ADDRESS_SPACE_MEMORY | + PCI_BASE_ADDRESS_MEM_PREFETCH | + PCI_BASE_ADDRESS_MEM_TYPE_64, + &dev->cachebar); } static void vhost_user_fs_pci_class_init(ObjectClass *klass, void *data) diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h index a635dc564c..53b87f245c 100644 --- a/hw/virtio/virtio-pci.h +++ b/hw/virtio/virtio-pci.h @@ -429,6 +429,7 @@ struct VirtIOCryptoPCI { struct VHostUserFSPCI { VirtIOPCIProxy parent_obj; VHostUserFS vdev; + MemoryRegion cachebar; }; #endif diff --git a/include/hw/virtio/vhost-user-fs.h b/include/hw/virtio/vhost-user-fs.h index 29629acc54..be153e1c7a 100644 --- a/include/hw/virtio/vhost-user-fs.h +++ b/include/hw/virtio/vhost-user-fs.h @@ -29,6 +29,7 @@ typedef struct { uint16_t num_queues; uint16_t queue_size; char *vhostfd; + size_t cache_size; } VHostUserFSConf; typedef struct { @@ -40,6 +41,7 @@ typedef struct { VhostUserState *vhost_user; /*< public >*/ + MemoryRegion cache; } VHostUserFS; #endif /* _QEMU_VHOST_USER_FS_H */ diff --git a/include/standard-headers/linux/virtio_fs.h b/include/standard-headers/linux/virtio_fs.h index 4f811a0b70..b5f137ca79 100644 --- a/include/standard-headers/linux/virtio_fs.h +++ b/include/standard-headers/linux/virtio_fs.h @@ -38,4 +38,9 @@ struct virtio_fs_config { uint32_t num_queues; } QEMU_PACKED; +#define VIRTIO_FS_PCI_CACHE_BAR 2 + +/* For the id field in virtio_pci_shm_cap */ +#define VIRTIO_FS_PCI_SHMCAP_ID_CACHE 0 + #endif /* _LINUX_VIRTIO_FS_H */ -- 2.19.2