aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf
diff options
context:
space:
mode:
authorJiong Wang <jiong.wang@netronome.com>2018-01-16 19:05:19 -0500
committerDaniel Borkmann <daniel@iogearbox.net>2018-01-17 19:26:15 -0500
commitfcfb126defda3cee3f1d9460dbe9a2ccac4fbd21 (patch)
treea52763714b3c97f196838f3095b25f0bbb872bac /kernel/bpf
parent4f7d58517f461aa6e7b7509668f04021e089323d (diff)
bpf: add new jited info fields in bpf_dev_offload and bpf_prog_info
For host JIT, there are "jited_len"/"bpf_func" fields in struct bpf_prog used by all host JIT targets to get jited image and it's length. While for offload, targets are likely to have different offload mechanisms that these info are kept in device private data fields. Therefore, BPF_OBJ_GET_INFO_BY_FD syscall needs an unified way to get JIT length and contents info for offload targets. One way is to introduce new callback to parse device private data then fill those fields in bpf_prog_info. This might be a little heavy, the other way is to add generic fields which will be initialized by all offload targets. This patch follow the second approach to introduce two new fields in struct bpf_dev_offload and teach bpf_prog_get_info_by_fd about them to fill correct jited_prog_len and jited_prog_insns in bpf_prog_info. Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com> Signed-off-by: Jiong Wang <jiong.wang@netronome.com> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'kernel/bpf')
-rw-r--r--kernel/bpf/offload.c23
-rw-r--r--kernel/bpf/syscall.c31
2 files changed, 41 insertions, 13 deletions
diff --git a/kernel/bpf/offload.c b/kernel/bpf/offload.c
index a88cebf368bf..6c0baa1cf8f8 100644
--- a/kernel/bpf/offload.c
+++ b/kernel/bpf/offload.c
@@ -230,9 +230,12 @@ int bpf_prog_offload_info_fill(struct bpf_prog_info *info,
230 .prog = prog, 230 .prog = prog,
231 .info = info, 231 .info = info,
232 }; 232 };
233 struct bpf_prog_aux *aux = prog->aux;
233 struct inode *ns_inode; 234 struct inode *ns_inode;
234 struct path ns_path; 235 struct path ns_path;
236 char __user *uinsns;
235 void *res; 237 void *res;
238 u32 ulen;
236 239
237 res = ns_get_path_cb(&ns_path, bpf_prog_offload_info_fill_ns, &args); 240 res = ns_get_path_cb(&ns_path, bpf_prog_offload_info_fill_ns, &args);
238 if (IS_ERR(res)) { 241 if (IS_ERR(res)) {
@@ -241,6 +244,26 @@ int bpf_prog_offload_info_fill(struct bpf_prog_info *info,
241 return PTR_ERR(res); 244 return PTR_ERR(res);
242 } 245 }
243 246
247 down_read(&bpf_devs_lock);
248
249 if (!aux->offload) {
250 up_read(&bpf_devs_lock);
251 return -ENODEV;
252 }
253
254 ulen = info->jited_prog_len;
255 info->jited_prog_len = aux->offload->jited_len;
256 if (info->jited_prog_len & ulen) {
257 uinsns = u64_to_user_ptr(info->jited_prog_insns);
258 ulen = min_t(u32, info->jited_prog_len, ulen);
259 if (copy_to_user(uinsns, aux->offload->jited_image, ulen)) {
260 up_read(&bpf_devs_lock);
261 return -EFAULT;
262 }
263 }
264
265 up_read(&bpf_devs_lock);
266
244 ns_inode = ns_path.dentry->d_inode; 267 ns_inode = ns_path.dentry->d_inode;
245 info->netns_dev = new_encode_dev(ns_inode->i_sb->s_dev); 268 info->netns_dev = new_encode_dev(ns_inode->i_sb->s_dev);
246 info->netns_ino = ns_inode->i_ino; 269 info->netns_ino = ns_inode->i_ino;
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index c691b9e972e3..c28524483bf4 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -1724,19 +1724,6 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
1724 goto done; 1724 goto done;
1725 } 1725 }
1726 1726
1727 ulen = info.jited_prog_len;
1728 info.jited_prog_len = prog->jited_len;
1729 if (info.jited_prog_len && ulen) {
1730 if (bpf_dump_raw_ok()) {
1731 uinsns = u64_to_user_ptr(info.jited_prog_insns);
1732 ulen = min_t(u32, info.jited_prog_len, ulen);
1733 if (copy_to_user(uinsns, prog->bpf_func, ulen))
1734 return -EFAULT;
1735 } else {
1736 info.jited_prog_insns = 0;
1737 }
1738 }
1739
1740 ulen = info.xlated_prog_len; 1727 ulen = info.xlated_prog_len;
1741 info.xlated_prog_len = bpf_prog_insn_size(prog); 1728 info.xlated_prog_len = bpf_prog_insn_size(prog);
1742 if (info.xlated_prog_len && ulen) { 1729 if (info.xlated_prog_len && ulen) {
@@ -1762,6 +1749,24 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
1762 err = bpf_prog_offload_info_fill(&info, prog); 1749 err = bpf_prog_offload_info_fill(&info, prog);
1763 if (err) 1750 if (err)
1764 return err; 1751 return err;
1752 goto done;
1753 }
1754
1755 /* NOTE: the following code is supposed to be skipped for offload.
1756 * bpf_prog_offload_info_fill() is the place to fill similar fields
1757 * for offload.
1758 */
1759 ulen = info.jited_prog_len;
1760 info.jited_prog_len = prog->jited_len;
1761 if (info.jited_prog_len && ulen) {
1762 if (bpf_dump_raw_ok()) {
1763 uinsns = u64_to_user_ptr(info.jited_prog_insns);
1764 ulen = min_t(u32, info.jited_prog_len, ulen);
1765 if (copy_to_user(uinsns, prog->bpf_func, ulen))
1766 return -EFAULT;
1767 } else {
1768 info.jited_prog_insns = 0;
1769 }
1765 } 1770 }
1766 1771
1767done: 1772done: