Signed-off-by: Jeff Moyer <jmoyer(a)redhat.com>
---
drivers/block/gen_nvm_volumes.c | 4 ++++
drivers/block/nvdimm_core.c | 36 ++++++++++++++++++++++++++++--------
2 files changed, 32 insertions(+), 8 deletions(-)
diff --git a/drivers/block/gen_nvm_volumes.c b/drivers/block/gen_nvm_volumes.c
index da80f0d..a9a643a 100644
--- a/drivers/block/gen_nvm_volumes.c
+++ b/drivers/block/gen_nvm_volumes.c
@@ -97,6 +97,10 @@ static struct extent_set *spa_rng_to_extent(struct fit_header
*fit_head,
kfree(mem_extent);
return ERR_PTR(-EFAULT);
}
+ if (!set_memory_x((unsigned long)mem_extent->virtaddr,
+ mem_extent->set_size >> PAGE_SHIFT))
+ printk(KERN_INFO
+ "Failed to set PM executable. XIP will not work.\n");
return mem_extent;
}
diff --git a/drivers/block/nvdimm_core.c b/drivers/block/nvdimm_core.c
index a3bb248..0e94ba6 100644
--- a/drivers/block/nvdimm_core.c
+++ b/drivers/block/nvdimm_core.c
@@ -520,21 +520,16 @@ release_mutex:
return ERR_PTR(ret);
}
-static const struct block_device_operations vol_dev_ops = {
-/* .getpmem = nvdimm_getpmem, */
- .owner = THIS_MODULE,
-};
-
static void noop_make_request(struct request_queue *q, struct bio *bio)
{
bio_endio(bio, -EIO);
}
static unsigned long long pmem_extent_lookup(struct nvm_volume *volume,
- struct bio *bio)
+ sector_t sector)
{
unsigned long long phys_mem = 0;
- pgoff_t io_start_offset = bio->bi_iter.bi_sector << 9;
+ pgoff_t io_start_offset = sector << 9;
struct extent_set *extent;
/* TODO: Handle I/O spanning extents */
@@ -560,7 +555,7 @@ static void pmem_make_request(struct request_queue *q, struct bio
*bio)
struct bvec_iter iter;
unsigned int transferred = 0;
- phys_mem = pmem_extent_lookup(volume, bio);
+ phys_mem = pmem_extent_lookup(volume, bio->bi_iter.bi_sector);
if (!phys_mem) {
bio_io_error(bio);
return;
@@ -587,6 +582,31 @@ static void pmem_make_request(struct request_queue *q, struct bio
*bio)
bio_endio(bio, 0);
}
+static int nvdimm_direct_access(struct block_device *bdev, sector_t sector,
+ void **kaddr, unsigned long *pfn)
+{
+ struct nvm_volume *volume = bdev->bd_disk->private_data;
+ loff_t offset;
+
+ offset = sector;
+ if (bdev->bd_part != NULL)
+ offset += bdev->bd_part->start_sect;
+ offset <<= 9;
+ if (offset >= (volume->block_size * volume->block_count))
+ return -ERANGE;
+
+ *kaddr = (void *)pmem_extent_lookup(volume, sector);
+ *pfn = virt_to_phys(kaddr) >> PAGE_SHIFT;
+
+ return 0;
+}
+
+static const struct block_device_operations vol_dev_ops = {
+/* .getpmem = nvdimm_getpmem, */
+ .owner = THIS_MODULE,
+ .direct_access = nvdimm_direct_access,
+};
+
static int pmem_alloc_disk(struct nvm_volume *volume)
{
int ret = 0;
--
1.8.3.1