-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
bpf: Introduce bpfptr_t user/kernel pointer.
Similar to sockptr_t introduce bpfptr_t with few additions: make_bpfptr() creates new user/kernel pointer in the same address space as existing user/kernel pointer. bpfptr_add() advances the user/kernel pointer. Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/bpf/20210514003623.28033-3-alexei.starovoitov@gmail.com
- Loading branch information
Alexei Starovoitov
authored and
Daniel Borkmann
committed
May 18, 2021
1 parent
79a7f8b
commit cdf7fb0
Showing
1 changed file
with
75 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
/* SPDX-License-Identifier: GPL-2.0-only */ | ||
/* A pointer that can point to either kernel or userspace memory. */ | ||
#ifndef _LINUX_BPFPTR_H | ||
#define _LINUX_BPFPTR_H | ||
|
||
#include <linux/sockptr.h> | ||
|
||
typedef sockptr_t bpfptr_t; | ||
|
||
static inline bool bpfptr_is_kernel(bpfptr_t bpfptr) | ||
{ | ||
return bpfptr.is_kernel; | ||
} | ||
|
||
static inline bpfptr_t KERNEL_BPFPTR(void *p) | ||
{ | ||
return (bpfptr_t) { .kernel = p, .is_kernel = true }; | ||
} | ||
|
||
static inline bpfptr_t USER_BPFPTR(void __user *p) | ||
{ | ||
return (bpfptr_t) { .user = p }; | ||
} | ||
|
||
static inline bpfptr_t make_bpfptr(u64 addr, bool is_kernel) | ||
{ | ||
if (is_kernel) | ||
return KERNEL_BPFPTR((void*) (uintptr_t) addr); | ||
else | ||
return USER_BPFPTR(u64_to_user_ptr(addr)); | ||
} | ||
|
||
static inline bool bpfptr_is_null(bpfptr_t bpfptr) | ||
{ | ||
if (bpfptr_is_kernel(bpfptr)) | ||
return !bpfptr.kernel; | ||
return !bpfptr.user; | ||
} | ||
|
||
static inline void bpfptr_add(bpfptr_t *bpfptr, size_t val) | ||
{ | ||
if (bpfptr_is_kernel(*bpfptr)) | ||
bpfptr->kernel += val; | ||
else | ||
bpfptr->user += val; | ||
} | ||
|
||
static inline int copy_from_bpfptr_offset(void *dst, bpfptr_t src, | ||
size_t offset, size_t size) | ||
{ | ||
return copy_from_sockptr_offset(dst, (sockptr_t) src, offset, size); | ||
} | ||
|
||
static inline int copy_from_bpfptr(void *dst, bpfptr_t src, size_t size) | ||
{ | ||
return copy_from_bpfptr_offset(dst, src, 0, size); | ||
} | ||
|
||
static inline int copy_to_bpfptr_offset(bpfptr_t dst, size_t offset, | ||
const void *src, size_t size) | ||
{ | ||
return copy_to_sockptr_offset((sockptr_t) dst, offset, src, size); | ||
} | ||
|
||
static inline void *memdup_bpfptr(bpfptr_t src, size_t len) | ||
{ | ||
return memdup_sockptr((sockptr_t) src, len); | ||
} | ||
|
||
static inline long strncpy_from_bpfptr(char *dst, bpfptr_t src, size_t count) | ||
{ | ||
return strncpy_from_sockptr(dst, (sockptr_t) src, count); | ||
} | ||
|
||
#endif /* _LINUX_BPFPTR_H */ |