File Index
Files and directories
Sign in
FILE

dmabuf_iter.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/bpf/progs/dmabuf_iter.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (c) 2025 Google LLC */
  3#include <vmlinux.h>
  4#include <bpf/bpf_core_read.h>
  5#include <bpf/bpf_helpers.h>
  6
  7/* From uapi/linux/dma-buf.h */
  8#define DMA_BUF_NAME_LEN 32
  9
 10char _license[] SEC("license") = "GPL";
 11
 12struct {
 13	__uint(type, BPF_MAP_TYPE_HASH);
 14	__uint(key_size, DMA_BUF_NAME_LEN);
 15	__type(value, bool);
 16	__uint(max_entries, 5);
 17} testbuf_hash SEC(".maps");
 18
 19/*
 20 * Fields output by this iterator are delimited by newlines. Convert any
 21 * newlines in user-provided printed strings to spaces.
 22 */
 23static void sanitize_string(char *src, size_t size)
 24{
 25	for (char *c = src; (size_t)(c - src) < size && *c; ++c)
 26		if (*c == '\n')
 27			*c = ' ';
 28}
 29
 30SEC("iter/dmabuf")
 31int dmabuf_collector(struct bpf_iter__dmabuf *ctx)
 32{
 33	const struct dma_buf *dmabuf = ctx->dmabuf;
 34	struct seq_file *seq = ctx->meta->seq;
 35	unsigned long inode = 0;
 36	size_t size;
 37	const char *pname, *exporter;
 38	char name[DMA_BUF_NAME_LEN] = {'\0'};
 39
 40	if (!dmabuf)
 41		return 0;
 42
 43	if (BPF_CORE_READ_INTO(&inode, dmabuf, file, f_inode, i_ino) ||
 44	    bpf_core_read(&size, sizeof(size), &dmabuf->size) ||
 45	    bpf_core_read(&pname, sizeof(pname), &dmabuf->name) ||
 46	    bpf_core_read(&exporter, sizeof(exporter), &dmabuf->exp_name))
 47		return 1;
 48
 49	/* Buffers are not required to be named */
 50	if (pname) {
 51		if (bpf_probe_read_kernel_str(name, sizeof(name), pname) < 0)
 52			return 1;
 53
 54		/* Name strings can be provided by userspace */
 55		sanitize_string(name, sizeof(name));
 56	}
 57
 58	BPF_SEQ_PRINTF(seq, "%lu\n%llu\n%s\n%s\n", inode, size, name, exporter);
 59	return 0;
 60}
 61
 62SEC("syscall")
 63int iter_dmabuf_for_each(const void *ctx)
 64{
 65	struct dma_buf *d;
 66
 67	bpf_for_each(dmabuf, d) {
 68		char name[DMA_BUF_NAME_LEN];
 69		const char *pname;
 70		bool *found;
 71		long len;
 72		int i;
 73
 74		if (bpf_core_read(&pname, sizeof(pname), &d->name))
 75			return 1;
 76
 77		/* Buffers are not required to be named */
 78		if (!pname)
 79			continue;
 80
 81		len = bpf_probe_read_kernel_str(name, sizeof(name), pname);
 82		if (len < 0)
 83			return 1;
 84
 85		/*
 86		 * The entire name buffer is used as a map key.
 87		 * Zeroize any uninitialized trailing bytes after the NUL.
 88		 */
 89		bpf_for(i, len, DMA_BUF_NAME_LEN)
 90			name[i] = 0;
 91
 92		found = bpf_map_lookup_elem(&testbuf_hash, name);
 93		if (found) {
 94			bool t = true;
 95
 96			bpf_map_update_elem(&testbuf_hash, name, &t, BPF_EXIST);
 97		}
 98	}
 99
100	return 0;
101}
~/ Read-only file preview.