From 85ecee29d94fcc3a409f4653442336b8139e0436 Mon Sep 17 00:00:00 2001 From: Andrea Bellandi Date: Thu, 14 May 2026 21:45:34 +0200 Subject: [PATCH 1/3] feat: exposes 3 maps with the same size --- uio-dummy.c | 49 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/uio-dummy.c b/uio-dummy.c index 4fd1364..e896b5e 100644 --- a/uio-dummy.c +++ b/uio-dummy.c @@ -23,7 +23,7 @@ * License, which you should have received with the source. * */ -/* +/* * The UIO API * * In order to write a user-space driver using the UIO API with a @@ -64,9 +64,9 @@ * * You'll need to fill in entries for at least name, irq, irq_flags * and handler, which should return IRQ_HANDLED. - * + * * The structure should be register and unregistered with: - * + * * int uio_register_device(struct device *parent, struct uio_info *info); * void uio_unregister_device(struct uio_info *info); * @@ -84,12 +84,18 @@ #include #include +#define UIO_DUMMY_NUM_MAPS 3 + static struct uio_info *info; static struct device *dev; -static unsigned long long mem_size = 2692759552 + 32; +static unsigned long long mem_sizes[UIO_DUMMY_NUM_MAPS] = { + 2692759552 + 32, + 2692759552 + 32, + 2692759552 + 32, +}; static bool irqs_enabled = false; -module_param(mem_size, ullong, S_IRUGO); +module_param_array(mem_sizes, ullong, NULL, S_IRUGO); static void my_release(struct device *dev) { @@ -98,8 +104,11 @@ static void my_release(struct device *dev) static int uio_dummy_proc_show(struct seq_file *m, void *v) { + int i; + seq_printf(m, "UIO Dummy driver v%s\n", UIO_DUMMY_VERSION); - seq_printf(m, " Allocated memory: %llu\n", mem_size); + for (i = 0; i < UIO_DUMMY_NUM_MAPS; i++) + seq_printf(m, " Allocated memory map%d: %llu\n", i, mem_sizes[i]); return 0; } @@ -152,7 +161,8 @@ static int uio_dummy_irq_control(struct uio_info *dev_info, s32 irq_on) static int __init uio_dummy_init(void) { - struct uio_mem *mem; + int i; + dev = kzalloc(sizeof(struct device), GFP_KERNEL); dev_set_name(dev, "uio_dummy_device"); dev->release = my_release; @@ -171,22 +181,25 @@ static int __init uio_dummy_init(void) info->irq = UIO_IRQ_CUSTOM; info->irqcontrol = uio_dummy_irq_control; - // Just allocate a slab of virtual memory to be exposed through mmap - mem = &info->mem[0]; - mem->memtype = UIO_MEM_VIRTUAL; - mem->addr = (phys_addr_t)vmalloc(mem_size); - mem->size = mem_size; - mem->name = "UIO dummy memory block"; + for (i = 0; i < UIO_DUMMY_NUM_MAPS; i++) { + info->mem[i].memtype = UIO_MEM_VIRTUAL; + info->mem[i].addr = (phys_addr_t)vzalloc(mem_sizes[i]); + info->mem[i].size = mem_sizes[i]; + info->mem[i].name = "UIO dummy memory block"; + } if (uio_register_device(dev, info) < 0) { - vfree((const void *)mem->addr); + for (i = 0; i < UIO_DUMMY_NUM_MAPS; i++) + vfree((const void *)info->mem[i].addr); device_unregister(dev); kfree(dev); kfree(info); printk(KERN_INFO "Failing to register uio device\n"); return -1; } - printk(KERN_INFO "Allocating %llu bytes for mem0", mem_size); + + for (i = 0; i < UIO_DUMMY_NUM_MAPS; i++) + printk(KERN_INFO "Allocating %llu bytes for mem%d", mem_sizes[i], i); proc_create_data("uio-dummy", 0666, NULL, &uio_dummy_proc_operations, dev); @@ -195,9 +208,11 @@ static int __init uio_dummy_init(void) static void __exit uio_dummy_exit(void) { - struct uio_mem *mem = &info->mem[0]; + int i; + uio_unregister_device(info); - vfree((const void *)mem->addr); + for (i = 0; i < UIO_DUMMY_NUM_MAPS; i++) + vfree((const void *)info->mem[i].addr); device_unregister(dev); remove_proc_entry("uio-dummy", NULL); printk(KERN_INFO "Un-Registered UIO handler\n"); From 1c3ba39aa0beb5f52f72167de342e90553f4b0cc Mon Sep 17 00:00:00 2001 From: Andrea Bellandi Date: Fri, 15 May 2026 17:16:22 +0200 Subject: [PATCH 2/3] feat: reduce memory consumption --- uio-dummy.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/uio-dummy.c b/uio-dummy.c index e896b5e..258bb7f 100644 --- a/uio-dummy.c +++ b/uio-dummy.c @@ -84,17 +84,17 @@ #include #include -#define UIO_DUMMY_NUM_MAPS 3 - static struct uio_info *info; static struct device *dev; -static unsigned long long mem_sizes[UIO_DUMMY_NUM_MAPS] = { - 2692759552 + 32, - 2692759552 + 32, - 2692759552 + 32, +static int num_maps = 3; +static unsigned long long mem_sizes[MAX_UIO_MAPS] = { + 81920, + 2684477440, + 81920, }; static bool irqs_enabled = false; +module_param(num_maps, int, S_IRUGO); module_param_array(mem_sizes, ullong, NULL, S_IRUGO); static void my_release(struct device *dev) From 681f7d4f68d1b2b9b6fbeeccaf28a8361d0d2adb Mon Sep 17 00:00:00 2001 From: Andrea Bellandi Date: Fri, 15 May 2026 18:18:09 +0200 Subject: [PATCH 3/3] feat: the number of maps is now a module parameter --- uio-dummy.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/uio-dummy.c b/uio-dummy.c index 258bb7f..4deb736 100644 --- a/uio-dummy.c +++ b/uio-dummy.c @@ -91,6 +91,8 @@ static unsigned long long mem_sizes[MAX_UIO_MAPS] = { 81920, 2684477440, 81920, + 81920, + 81920, }; static bool irqs_enabled = false; @@ -107,7 +109,7 @@ static int uio_dummy_proc_show(struct seq_file *m, void *v) int i; seq_printf(m, "UIO Dummy driver v%s\n", UIO_DUMMY_VERSION); - for (i = 0; i < UIO_DUMMY_NUM_MAPS; i++) + for (i = 0; i < num_maps; i++) seq_printf(m, " Allocated memory map%d: %llu\n", i, mem_sizes[i]); return 0; @@ -163,6 +165,12 @@ static int __init uio_dummy_init(void) { int i; + if (num_maps < 1 || num_maps > MAX_UIO_MAPS) { + printk(KERN_ERR "uio_dummy: num_maps must be between 1 and %d\n", + MAX_UIO_MAPS); + return -EINVAL; + } + dev = kzalloc(sizeof(struct device), GFP_KERNEL); dev_set_name(dev, "uio_dummy_device"); dev->release = my_release; @@ -181,7 +189,7 @@ static int __init uio_dummy_init(void) info->irq = UIO_IRQ_CUSTOM; info->irqcontrol = uio_dummy_irq_control; - for (i = 0; i < UIO_DUMMY_NUM_MAPS; i++) { + for (i = 0; i < num_maps; i++) { info->mem[i].memtype = UIO_MEM_VIRTUAL; info->mem[i].addr = (phys_addr_t)vzalloc(mem_sizes[i]); info->mem[i].size = mem_sizes[i]; @@ -189,7 +197,7 @@ static int __init uio_dummy_init(void) } if (uio_register_device(dev, info) < 0) { - for (i = 0; i < UIO_DUMMY_NUM_MAPS; i++) + for (i = 0; i < num_maps; i++) vfree((const void *)info->mem[i].addr); device_unregister(dev); kfree(dev); @@ -198,7 +206,7 @@ static int __init uio_dummy_init(void) return -1; } - for (i = 0; i < UIO_DUMMY_NUM_MAPS; i++) + for (i = 0; i < num_maps; i++) printk(KERN_INFO "Allocating %llu bytes for mem%d", mem_sizes[i], i); proc_create_data("uio-dummy", 0666, NULL, &uio_dummy_proc_operations, @@ -211,7 +219,7 @@ static void __exit uio_dummy_exit(void) int i; uio_unregister_device(info); - for (i = 0; i < UIO_DUMMY_NUM_MAPS; i++) + for (i = 0; i < num_maps; i++) vfree((const void *)info->mem[i].addr); device_unregister(dev); remove_proc_entry("uio-dummy", NULL);