@@ -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;