memremap: validate the pagemap type passed to devm_memremap_pages
Most pgmap types are only supported when certain config options are enabled. Check for a type that is valid for the current configuration before setting up the pagemap. For this the usage of the 0 type for device dax gets replaced with an explicit MEMORY_DEVICE_DEVDAX type. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Ira Weiny <ira.weiny@intel.com> Reviewed-by: Dan Williams <dan.j.williams@intel.com> Tested-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
This commit is contained in:
parent
0092908d16
commit
3ed2dcdf54
|
@ -468,6 +468,7 @@ int dev_dax_probe(struct device *dev)
|
||||||
dev_dax->pgmap.ref = &dev_dax->ref;
|
dev_dax->pgmap.ref = &dev_dax->ref;
|
||||||
dev_dax->pgmap.kill = dev_dax_percpu_kill;
|
dev_dax->pgmap.kill = dev_dax_percpu_kill;
|
||||||
dev_dax->pgmap.cleanup = dev_dax_percpu_exit;
|
dev_dax->pgmap.cleanup = dev_dax_percpu_exit;
|
||||||
|
dev_dax->pgmap.type = MEMORY_DEVICE_DEVDAX;
|
||||||
addr = devm_memremap_pages(dev, &dev_dax->pgmap);
|
addr = devm_memremap_pages(dev, &dev_dax->pgmap);
|
||||||
if (IS_ERR(addr))
|
if (IS_ERR(addr))
|
||||||
return PTR_ERR(addr);
|
return PTR_ERR(addr);
|
||||||
|
|
|
@ -45,13 +45,21 @@ struct vmem_altmap {
|
||||||
* wakeup is used to coordinate physical address space management (ex:
|
* wakeup is used to coordinate physical address space management (ex:
|
||||||
* fs truncate/hole punch) vs pinned pages (ex: device dma).
|
* fs truncate/hole punch) vs pinned pages (ex: device dma).
|
||||||
*
|
*
|
||||||
|
* MEMORY_DEVICE_DEVDAX:
|
||||||
|
* Host memory that has similar access semantics as System RAM i.e. DMA
|
||||||
|
* coherent and supports page pinning. In contrast to
|
||||||
|
* MEMORY_DEVICE_FS_DAX, this memory is access via a device-dax
|
||||||
|
* character device.
|
||||||
|
*
|
||||||
* MEMORY_DEVICE_PCI_P2PDMA:
|
* MEMORY_DEVICE_PCI_P2PDMA:
|
||||||
* Device memory residing in a PCI BAR intended for use with Peer-to-Peer
|
* Device memory residing in a PCI BAR intended for use with Peer-to-Peer
|
||||||
* transactions.
|
* transactions.
|
||||||
*/
|
*/
|
||||||
enum memory_type {
|
enum memory_type {
|
||||||
|
/* 0 is reserved to catch uninitialized type fields */
|
||||||
MEMORY_DEVICE_PRIVATE = 1,
|
MEMORY_DEVICE_PRIVATE = 1,
|
||||||
MEMORY_DEVICE_FS_DAX,
|
MEMORY_DEVICE_FS_DAX,
|
||||||
|
MEMORY_DEVICE_DEVDAX,
|
||||||
MEMORY_DEVICE_PCI_P2PDMA,
|
MEMORY_DEVICE_PCI_P2PDMA,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -157,6 +157,28 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
|
||||||
pgprot_t pgprot = PAGE_KERNEL;
|
pgprot_t pgprot = PAGE_KERNEL;
|
||||||
int error, nid, is_ram;
|
int error, nid, is_ram;
|
||||||
|
|
||||||
|
switch (pgmap->type) {
|
||||||
|
case MEMORY_DEVICE_PRIVATE:
|
||||||
|
if (!IS_ENABLED(CONFIG_DEVICE_PRIVATE)) {
|
||||||
|
WARN(1, "Device private memory not supported\n");
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MEMORY_DEVICE_FS_DAX:
|
||||||
|
if (!IS_ENABLED(CONFIG_ZONE_DEVICE) ||
|
||||||
|
IS_ENABLED(CONFIG_FS_DAX_LIMITED)) {
|
||||||
|
WARN(1, "File system DAX not supported\n");
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MEMORY_DEVICE_DEVDAX:
|
||||||
|
case MEMORY_DEVICE_PCI_P2PDMA:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
WARN(1, "Invalid pgmap type %d\n", pgmap->type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (!pgmap->ref || !pgmap->kill || !pgmap->cleanup) {
|
if (!pgmap->ref || !pgmap->kill || !pgmap->cleanup) {
|
||||||
WARN(1, "Missing reference count teardown definition\n");
|
WARN(1, "Missing reference count teardown definition\n");
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
Loading…
Reference in New Issue