mail archive of the barebox mailing list
 help / color / mirror / Atom feed
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




  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