From: Ahmad Fatoum <a.fatoum@pengutronix.de>
To: barebox@lists.infradead.org
Cc: Ahmad Fatoum <a.fatoum@pengutronix.de>
Subject: [PATCH 15/21] block: add lightweight ramdisk support
Date: Thu, 5 Jun 2025 13:35:24 +0200 [thread overview]
Message-ID: <20250605113530.2076990-16-a.fatoum@pengutronix.de> (raw)
In-Reply-To: <20250605113530.2076990-1-a.fatoum@pengutronix.de>
The partitions code in barebox expects a block device to operate on and
not raw memory buffers. Add an abstraction that wraps a raw memory
buffer as block device in a very lightweight manner as not to impede
fuzzing speed.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
drivers/block/Kconfig | 6 ++
drivers/block/Makefile | 1 +
drivers/block/ramdisk.c | 178 ++++++++++++++++++++++++++++++++++++++++
include/ramdisk.h | 24 ++++++
4 files changed, 209 insertions(+)
create mode 100644 drivers/block/ramdisk.c
create mode 100644 include/ramdisk.h
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index bf8dfdbd5c12..5b1b7789171c 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -26,3 +26,9 @@ config EFI_BLK_SEPARATE_USBDISK
for your disk and checking against it with
devlookup -v $bootguid /dev/disk$bootsource_instance guid
+
+config RAMDISK_BLK
+ bool
+ help
+ This symbol is selected by testing code that requires lightweight
+ creation of anonymous block devices backed fully by memory buffers.
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index a4e14a559cf7..6066b35c313e 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_EFI_BLK) += efi-block-io.o
obj-$(CONFIG_VIRTIO_BLK) += virtio_blk.o
+obj-$(CONFIG_RAMDISK_BLK) += ramdisk.o
diff --git a/drivers/block/ramdisk.c b/drivers/block/ramdisk.c
new file mode 100644
index 000000000000..6f3c9348058a
--- /dev/null
+++ b/drivers/block/ramdisk.c
@@ -0,0 +1,178 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// lightweight anonymous block device wrapper around memory buffers
+
+#include <ramdisk.h>
+#include <block.h>
+#include <driver.h>
+#include <fs.h>
+#include <string.h>
+#include <xfuncs.h>
+#include <linux/align.h>
+#include <linux/log2.h>
+
+struct ramdisk {
+ struct block_device blk;
+ struct device dev;
+ union {
+ void *base_rw;
+ const void *base_ro;
+ };
+ size_t size;
+ bool ro;
+};
+
+static int ramdisk_check_read(const struct ramdisk *ramdisk)
+{
+ return ramdisk->base_ro ? 1 : 0;
+}
+
+static ssize_t ramdisk_read(struct cdev *cdev, void *buf, size_t count,
+ loff_t offset, unsigned long flags)
+{
+ struct ramdisk *ramdisk = cdev->priv;
+ size_t cpy_count, pad_count;
+ int ret;
+
+ ret = ramdisk_check_read(ramdisk);
+ if (ret < 1)
+ return ret;
+
+ if (size_add(offset, count) > ramdisk->size)
+ return -ENXIO;
+
+ cpy_count = min_t(size_t, count, ramdisk->size - offset);
+ buf = mempcpy(buf, ramdisk->base_ro + offset, cpy_count);
+
+ pad_count = min_t(size_t, count, cdev->size - offset) - cpy_count;
+
+ memset(buf, 0x00, pad_count);
+
+ pr_vdebug("read %zu bytes\n", cpy_count + pad_count);
+
+ return cpy_count + pad_count;
+}
+
+static int ramdisk_check_write(const struct ramdisk *ramdisk)
+{
+ if (!ramdisk->base_rw)
+ return -EPERM;
+ if (ramdisk->ro)
+ return -EACCES;
+ return 1;
+}
+
+static ssize_t ramdisk_write(struct cdev *cdev, const void *buf, size_t count,
+ loff_t offset, unsigned long flags)
+{
+ struct ramdisk *ramdisk = cdev->priv;
+ int ret;
+
+ ret = ramdisk_check_write(ramdisk);
+ if (ret < 1)
+ return ret;
+ if (size_add(offset, count) > ramdisk->size)
+ return -ENXIO;
+
+ memcpy(ramdisk->base_rw + offset, buf,
+ min_t(size_t, count, ramdisk->size - offset));
+
+ return count;
+}
+
+static int ramdisk_memmap(struct cdev *cdev, void **map, int flags)
+{
+ struct ramdisk *ramdisk = cdev->priv;
+ int ret;
+
+ ret = flags & PROT_WRITE ? ramdisk_check_write(ramdisk)
+ : ramdisk_check_read(ramdisk);
+ if (ret < 1)
+ return ret;
+
+ *map = ramdisk->base_rw;
+ return 0;
+}
+
+static struct cdev_operations ramdisk_ops = {
+ .read = ramdisk_read,
+ .write = ramdisk_write,
+ .memmap = ramdisk_memmap,
+};
+
+struct ramdisk *ramdisk_init(int sector_size)
+{
+ struct ramdisk *ramdisk;
+ struct block_device *blk;
+ int ret;
+
+ ramdisk = xzalloc(sizeof(*ramdisk));
+
+ dev_set_name(&ramdisk->dev, "ramdisk");
+ ramdisk->dev.id = DEVICE_ID_DYNAMIC;
+
+ ret = register_device(&ramdisk->dev);
+ if (ret)
+ return NULL;
+
+ blk = &ramdisk->blk;
+ blk->dev = &ramdisk->dev;
+ blk->type = BLK_TYPE_VIRTUAL;
+
+ blk->cdev.size = 0;
+ blk->cdev.name = xstrdup(dev_name(&ramdisk->dev));
+ blk->cdev.dev = blk->dev;
+ blk->cdev.ops = &ramdisk_ops;
+ blk->cdev.priv = ramdisk;
+ blk->cdev.flags |= DEVFS_IS_BLOCK_DEV;
+ blk->blockbits = ilog2(sector_size);
+
+ ret = devfs_create(&blk->cdev);
+ if (ret)
+ return NULL;
+
+ INIT_LIST_HEAD(&blk->buffered_blocks);
+ INIT_LIST_HEAD(&blk->idle_blocks);
+
+ return ramdisk;
+}
+
+struct block_device *ramdisk_get_block_device(struct ramdisk *ramdisk)
+{
+ return &ramdisk->blk;
+}
+
+void ramdisk_free(struct ramdisk *ramdisk)
+{
+ devfs_remove(&ramdisk->blk.cdev);
+ unregister_device(&ramdisk->dev);
+ free(ramdisk);
+}
+
+static void ramdisk_setup_size(struct ramdisk *ramdisk, size_t size)
+{
+ ramdisk->size = size;
+ ramdisk->blk.cdev.size = ALIGN(size, 1 << ramdisk->blk.blockbits);
+}
+
+void ramdisk_setup_ro(struct ramdisk *ramdisk, const void *data, size_t size)
+{
+ ramdisk->ro = true;
+ ramdisk->base_ro = data;
+ ramdisk_setup_size(ramdisk, size);
+}
+
+const void *ramdisk_mmap(struct ramdisk *ramdisk, loff_t offset,
+ size_t size)
+{
+ if (size_add(offset, size) > ramdisk->size)
+ return NULL;
+
+ return ramdisk->base_ro + offset;
+}
+
+void ramdisk_setup_rw(struct ramdisk *ramdisk, void *data, size_t size)
+{
+ ramdisk->ro = false;
+ ramdisk->base_rw = data;
+ ramdisk_setup_size(ramdisk, size);
+}
diff --git a/include/ramdisk.h b/include/ramdisk.h
new file mode 100644
index 000000000000..b256a9c12ca7
--- /dev/null
+++ b/include/ramdisk.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __RAMDISK_H_
+#define __RAMDISK_H_
+
+#include <linux/types.h>
+
+struct ramdisk;
+struct block_device;
+
+struct ramdisk *ramdisk_init(int sector_size);
+void ramdisk_free(struct ramdisk *ramdisk);
+
+struct block_device *ramdisk_get_block_device(struct ramdisk *ramdisk);
+
+void ramdisk_setup_ro(struct ramdisk *ramdisk, const void *data, size_t size);
+void ramdisk_setup_rw(struct ramdisk *ramdisk, void *data, size_t size);
+
+const void *ramdisk_mmap(struct ramdisk *ramdisk, loff_t offset, size_t size);
+static inline void ramdisk_munmap(struct ramdisk *ramdisk,
+ void *ptr, loff_t offset,
+ size_t size) {}
+
+#endif
--
2.39.5
next prev parent reply other threads:[~2025-06-05 11:39 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-05 11:35 [PATCH 00/21] sandbox: add libfuzzer-based fuzzing Ahmad Fatoum
2025-06-05 11:35 ` [PATCH 01/21] pbl: add provision for architectures without piggy loader Ahmad Fatoum
2025-06-05 11:35 ` [PATCH 02/21] firmware: make Layerscape FMan firmware proper-only Ahmad Fatoum
2025-06-05 11:35 ` [PATCH 03/21] mci: sdhci: support compiling common SDHCI code for sandbox PBL Ahmad Fatoum
2025-06-05 11:35 ` [PATCH 04/21] kbuild: define and use more generic symlink command Ahmad Fatoum
2025-06-05 11:35 ` [PATCH 05/21] kbuild: collect compatibility symlink creation in symlink-y Ahmad Fatoum
2025-06-05 11:35 ` [PATCH 06/21] kbuild: allow customizing barebox proper binary Ahmad Fatoum
2025-06-05 11:35 ` [PATCH 07/21] sandbox: make available all CONFIG_ symbols to OS glue code Ahmad Fatoum
2025-06-05 11:35 ` [PATCH 08/21] sandbox: switch to using PBL Ahmad Fatoum
2025-06-05 11:35 ` [PATCH 09/21] kbuild: populate non-host CXX variables Ahmad Fatoum
2025-06-05 11:35 ` [PATCH 10/21] string: add fortify source support Ahmad Fatoum
2025-06-05 11:35 ` [PATCH 11/21] sandbox: populate UNAME_M variable Ahmad Fatoum
2025-06-05 11:35 ` [PATCH 12/21] Add fuzzing infrastructure Ahmad Fatoum
2025-06-05 11:35 ` [PATCH 13/21] filetype: add fuzz target Ahmad Fatoum
2025-06-05 11:35 ` [PATCH 14/21] block: mark underlying cdev with DEVFS_IS_BLOCK_DEV Ahmad Fatoum
2025-06-05 11:35 ` Ahmad Fatoum [this message]
2025-06-05 11:35 ` [PATCH 16/21] fuzz: add support for passing fuzz data as r/o ramdisk Ahmad Fatoum
2025-06-05 11:35 ` [PATCH 17/21] partitions: add partition table parser fuzz target Ahmad Fatoum
2025-06-05 11:35 ` [PATCH 18/21] fdt: add fuzz test Ahmad Fatoum
2025-06-05 11:35 ` [PATCH 19/21] fit: " Ahmad Fatoum
2025-06-05 11:35 ` [PATCH 20/21] Documentation: add LLVM libfuzzer documentation Ahmad Fatoum
2025-06-05 11:35 ` [PATCH 21/21] sandbox: add support for coverage info generation Ahmad Fatoum
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250605113530.2076990-16-a.fatoum@pengutronix.de \
--to=a.fatoum@pengutronix.de \
--cc=barebox@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox