tools/testing/selftests/drivers/net/hw/ncdevmem.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/drivers/net/hw/ncdevmem.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/drivers/net/hw/ncdevmem.c
Extension
.c
Size
34891 bytes
Lines
1545
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct memory_buffer {
	int fd;
	size_t size;

	int devfd;
	int memfd;
	char *buf_mem;
};

struct memory_provider {
	struct memory_buffer *(*alloc)(size_t size);
	void (*free)(struct memory_buffer *ctx);
	void (*memcpy_to_device)(struct memory_buffer *dst, size_t off,
				 void *src, int n);
	void (*memcpy_from_device)(void *dst, struct memory_buffer *src,
				   size_t off, int n);
};

static void pr_err(const char *fmt, ...)
{
	va_list args;

	fprintf(stderr, "%s: ", TEST_PREFIX);

	va_start(args, fmt);
	vfprintf(stderr, fmt, args);
	va_end(args);

	if (errno != 0)
		fprintf(stderr, ": %s", strerror(errno));
	fprintf(stderr, "\n");
}

static struct memory_buffer *udmabuf_alloc(size_t size)
{
	struct udmabuf_create create;
	struct memory_buffer *ctx;
	int ret;

	ctx = malloc(sizeof(*ctx));
	if (!ctx)
		return NULL;

	ctx->size = size;

	ctx->devfd = open("/dev/udmabuf", O_RDWR);
	if (ctx->devfd < 0) {
		pr_err("[skip,no-udmabuf: Unable to access DMA buffer device file]");
		goto err_free_ctx;
	}

	ctx->memfd = memfd_create("udmabuf-test", MFD_ALLOW_SEALING);
	if (ctx->memfd < 0) {
		pr_err("[skip,no-memfd]");
		goto err_close_dev;
	}

	ret = fcntl(ctx->memfd, F_ADD_SEALS, F_SEAL_SHRINK);
	if (ret < 0) {
		pr_err("[skip,fcntl-add-seals]");
		goto err_close_memfd;
	}

	ret = ftruncate(ctx->memfd, size);
	if (ret == -1) {
		pr_err("[FAIL,memfd-truncate]");
		goto err_close_memfd;
	}

	memset(&create, 0, sizeof(create));

	create.memfd = ctx->memfd;
	create.offset = 0;
	create.size = size;
	ctx->fd = ioctl(ctx->devfd, UDMABUF_CREATE, &create);
	if (ctx->fd < 0) {
		pr_err("[FAIL, create udmabuf]");
		goto err_close_fd;
	}

	ctx->buf_mem = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
			    ctx->fd, 0);
	if (ctx->buf_mem == MAP_FAILED) {
		pr_err("[FAIL, map udmabuf]");
		goto err_close_fd;
	}

	return ctx;

err_close_fd:

Annotation

Implementation Notes