From: "Dr. David Alan Gilbert" <dgilb...@redhat.com>

Instead of assuming we had the fixed bar for the cache, use the
value from the capabilities.
Use the other capabilities to map their memory.

Signed-off-by: Dr. David Alan Gilbert <dgilb...@redhat.com>
---
 fs/fuse/virtio_fs.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 95 insertions(+)

diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
index c18f406b61cd..7d5b23455639 100644
--- a/fs/fuse/virtio_fs.c
+++ b/fs/fuse/virtio_fs.c
@@ -53,6 +53,16 @@ struct virtio_fs {
        void *window_kaddr;
        phys_addr_t window_phys_addr;
        size_t window_len;
+
+        /* Version table where version numbers can be read */
+       void *vertab_kaddr;
+       phys_addr_t vertab_phys_addr;
+       size_t vertab_len;
+
+        /* Journal */
+       void *journal_kaddr;
+       phys_addr_t journal_phys_addr;
+       size_t journal_len;
 };
 
 struct virtio_fs_forget {
@@ -684,6 +694,17 @@ static int virtio_fs_setup_dax(struct virtio_device *vdev, 
struct virtio_fs *fs)
        }
        phys_addr += cache_offset;
 
+       phys_addr = pci_resource_start(pci_dev, cache_bar);
+       bar_len = pci_resource_len(pci_dev, cache_bar);
+
+        if (cache_offset + cache_len > bar_len) {
+                dev_err(&vdev->dev,
+                        "%s: cache bar shorter than cap offset+len\n",
+                        __func__);
+                return -EINVAL;
+        }
+        phys_addr += cache_offset;
+
        /* Ideally we would directly use the PCI BAR resource but
         * devm_memremap_pages() wants its own copy in pgmap.  So
         * initialize a struct resource from scratch (only the start
@@ -710,6 +731,80 @@ static int virtio_fs_setup_dax(struct virtio_device *vdev, 
struct virtio_fs *fs)
        dev_dbg(&vdev->dev, "%s: cache kaddr 0x%px phys_addr 0x%llx len %llx\n",
                __func__, fs->window_kaddr, phys_addr, cache_len);
 
+       /*
+        * The journal and version table should be easier since DAX doesn't
+        * need them
+        */
+       if (have_journal) {
+               if (journal_bar != cache_bar) {
+                       ret = pci_request_region(pci_dev, journal_bar,
+                                                "virtio-fs-journal");
+                       if (ret < 0) {
+                               dev_err(&vdev->dev,
+                                       "%s: failed to request journal BAR\n",
+                                       __func__);
+                               return ret;
+                       }
+               }
+
+               phys_addr = pci_resource_start(pci_dev, journal_bar);
+               bar_len = pci_resource_len(pci_dev, journal_bar);
+
+               if (journal_offset + journal_len > bar_len) {
+                       dev_err(&vdev->dev,
+                               "%s: journal bar shorter than cap offset+len\n",
+                               __func__);
+                       return -EINVAL;
+               }
+               fs->journal_phys_addr = phys_addr + journal_offset;
+               fs->journal_len = journal_len;
+
+               fs->journal_kaddr = devm_memremap(&pci_dev->dev,
+                                                 fs->journal_phys_addr,
+                                                 journal_len, MEMREMAP_WB);
+               if (!fs->journal_kaddr) {
+                       dev_err(&vdev->dev, "%s: failed to remap journal\n",
+                               __func__);
+                       return -ENOMEM;
+               }
+               dev_notice(&vdev->dev, "%s: journal at %px\n", __func__,
+                          fs->journal_kaddr);
+       }
+
+       if (have_vertab) {
+               if (vertab_bar != cache_bar &&
+                   vertab_bar != journal_bar) {
+                       ret = pci_request_region(pci_dev, vertab_bar,
+                                                "virtio-fs-vertab");
+                       if (ret < 0) {
+                               dev_err(&vdev->dev, "%s: failed to request"
+                                       " vertab BAR\n", __func__);
+                               return ret;
+                       }
+               }
+
+               phys_addr = pci_resource_start(pci_dev, vertab_bar);
+               bar_len = pci_resource_len(pci_dev, vertab_bar);
+
+               if (vertab_offset + vertab_len > bar_len) {
+                       dev_err(&vdev->dev, "%s: version tab bar shorter than"
+                               " cap offset+len\n", __func__);
+                       return -EINVAL;
+               }
+               fs->vertab_phys_addr = phys_addr + vertab_offset;
+               fs->vertab_len = vertab_len;
+               fs->vertab_kaddr = devm_memremap(&pci_dev->dev,
+                                                fs->vertab_phys_addr,
+                                                vertab_len, MEMREMAP_WB);
+               if (!fs->vertab_kaddr) {
+                       dev_err(&vdev->dev, "%s: failed to remap version"
+                               " table\n", __func__);
+                       return -ENOMEM;
+               }
+               dev_notice(&vdev->dev, "%s: version table at %px\n",
+                               __func__, fs->vertab_kaddr);
+       }
+
        fs->dax_dev = alloc_dax(fs, NULL, &virtio_fs_dax_ops);
        if (!fs->dax_dev)
                return -ENOMEM;
-- 
2.13.6

Reply via email to