[PATCH 5/5] misc: fix /dev/mem size

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The size of /dev/mem was limited to the lower half of the 64bit address
range. This is unfortunate since on some architectures (MIPS64, namely)
the upper half contains meaningful addresses. We can't just set /dev/mem
to its real size since that's bigger than the maximum loff_t. Set the
DEVFS_IS_CHARACTER_DEV flag instead for /dev/mem which will cause the
size checks in lseek and friends to be bypassed.
Also fix the size the memory device is registered with. We used to set
the size to ~0, but the real size is one higher. To do this explicitly
register the device with specifying the end address rather than the
size. This will make /dev/mem appear with filesize 0, but so does
/dev/zero already.

Signed-off-by: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx>
---
 drivers/misc/mem.c | 35 ++++++++++++++++++++++++++++++++---
 1 file changed, 32 insertions(+), 3 deletions(-)

diff --git a/drivers/misc/mem.c b/drivers/misc/mem.c
index 60981a3e98..6dd7f687c9 100644
--- a/drivers/misc/mem.c
+++ b/drivers/misc/mem.c
@@ -21,8 +21,18 @@ static int mem_probe(struct device_d *dev)
 	dev->priv = cdev;
 
 	cdev->name = (char*)dev->resource[0].name;
-	cdev->size = min_t(unsigned long long, resource_size(&dev->resource[0]),
-			   S64_MAX);
+	if (dev->resource[0].start == 0 && dev->resource[0].end == ~0) {
+		/*
+		 * Special case for /dev/mem. We can't express it's size as it's
+		 * outside of our address range. Set DEVFS_IS_CHARACTER_DEV to
+		 * bypass size checks.
+		 */
+		cdev->size = 0;
+		cdev->flags = DEVFS_IS_CHARACTER_DEV;
+	} else {
+		cdev->size = resource_size(&dev->resource[0]);
+	}
+
 	cdev->ops = &memops;
 	cdev->dev = dev;
 
@@ -38,7 +48,26 @@ static struct driver_d mem_drv = {
 
 static int mem_init(void)
 {
-	add_mem_device("mem", 0, ~0, IORESOURCE_MEM_WRITEABLE);
+	struct device_d *dev;
+	struct resource res = {
+		.start = 0,
+		.end = ~0,
+		.flags = IORESOURCE_MEM,
+		.name = "mem",
+	};
+	int ret;
+
+	dev = device_alloc("mem", DEVICE_ID_DYNAMIC);
+	if (!dev)
+		return -ENOMEM;
+
+	dev->resource = xmemdup(&res, sizeof(res));
+	dev->num_resources = 1;
+
+	ret = platform_device_register(dev);
+	if (ret)
+		return ret;
+
 	return platform_driver_register(&mem_drv);
 }
 device_initcall(mem_init);
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/barebox



[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux