|
@@ -1970,13 +1970,44 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
|
|
|
* for offload.
|
|
|
*/
|
|
|
ulen = info.jited_prog_len;
|
|
|
- info.jited_prog_len = prog->jited_len;
|
|
|
+ if (prog->aux->func_cnt) {
|
|
|
+ u32 i;
|
|
|
+
|
|
|
+ info.jited_prog_len = 0;
|
|
|
+ for (i = 0; i < prog->aux->func_cnt; i++)
|
|
|
+ info.jited_prog_len += prog->aux->func[i]->jited_len;
|
|
|
+ } else {
|
|
|
+ info.jited_prog_len = prog->jited_len;
|
|
|
+ }
|
|
|
+
|
|
|
if (info.jited_prog_len && ulen) {
|
|
|
if (bpf_dump_raw_ok()) {
|
|
|
uinsns = u64_to_user_ptr(info.jited_prog_insns);
|
|
|
ulen = min_t(u32, info.jited_prog_len, ulen);
|
|
|
- if (copy_to_user(uinsns, prog->bpf_func, ulen))
|
|
|
- return -EFAULT;
|
|
|
+
|
|
|
+ /* for multi-function programs, copy the JITed
|
|
|
+ * instructions for all the functions
|
|
|
+ */
|
|
|
+ if (prog->aux->func_cnt) {
|
|
|
+ u32 len, free, i;
|
|
|
+ u8 *img;
|
|
|
+
|
|
|
+ free = ulen;
|
|
|
+ for (i = 0; i < prog->aux->func_cnt; i++) {
|
|
|
+ len = prog->aux->func[i]->jited_len;
|
|
|
+ len = min_t(u32, len, free);
|
|
|
+ img = (u8 *) prog->aux->func[i]->bpf_func;
|
|
|
+ if (copy_to_user(uinsns, img, len))
|
|
|
+ return -EFAULT;
|
|
|
+ uinsns += len;
|
|
|
+ free -= len;
|
|
|
+ if (!free)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (copy_to_user(uinsns, prog->bpf_func, ulen))
|
|
|
+ return -EFAULT;
|
|
|
+ }
|
|
|
} else {
|
|
|
info.jited_prog_insns = 0;
|
|
|
}
|