aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-09-03 11:08:17 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-09-03 11:08:17 -0400
commitdd5cdb48edfd34401799056a9acf61078d773f90 (patch)
tree8e251fb4a4c196540fe9b6a6d8b13275f93a057c /kernel/trace
parent1e1a4e8f439113b7820bc7150569f685e1cc2b43 (diff)
parent62da98656b62a5ca57f22263705175af8ded5aa1 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: "Another merge window, another set of networking changes. I've heard rumblings that the lightweight tunnels infrastructure has been voted networking change of the year. But what do I know? 1) Add conntrack support to openvswitch, from Joe Stringer. 2) Initial support for VRF (Virtual Routing and Forwarding), which allows the segmentation of routing paths without using multiple devices. There are some semantic kinks to work out still, but this is a reasonably strong foundation. From David Ahern. 3) Remove spinlock fro act_bpf fast path, from Alexei Starovoitov. 4) Ignore route nexthops with a link down state in ipv6, just like ipv4. From Andy Gospodarek. 5) Remove spinlock from fast path of act_gact and act_mirred, from Eric Dumazet. 6) Document the DSA layer, from Florian Fainelli. 7) Add netconsole support to bcmgenet, systemport, and DSA. Also from Florian Fainelli. 8) Add Mellanox Switch Driver and core infrastructure, from Jiri Pirko. 9) Add support for "light weight tunnels", which allow for encapsulation and decapsulation without bearing the overhead of a full blown netdevice. From Thomas Graf, Jiri Benc, and a cast of others. 10) Add Identifier Locator Addressing support for ipv6, from Tom Herbert. 11) Support fragmented SKBs in iwlwifi, from Johannes Berg. 12) Allow perf PMUs to be accessed from eBPF programs, from Kaixu Xia. 13) Add BQL support to 3c59x driver, from Loganaden Velvindron. 14) Stop using a zero TX queue length to mean that a device shouldn't have a qdisc attached, use an explicit flag instead. From Phil Sutter. 15) Use generic geneve netdevice infrastructure in openvswitch, from Pravin B Shelar. 16) Add infrastructure to avoid re-forwarding a packet in software that was already forwarded by a hardware switch. From Scott Feldman. 17) Allow AF_PACKET fanout function to be implemented in a bpf program, from Willem de Bruijn" * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1458 commits) netfilter: nf_conntrack: make nf_ct_zone_dflt built-in netfilter: nf_dup{4, 6}: fix build error when nf_conntrack disabled net: fec: clear receive interrupts before processing a packet ipv6: fix exthdrs offload registration in out_rt path xen-netback: add support for multicast control bgmac: Update fixed_phy_register() sock, diag: fix panic in sock_diag_put_filterinfo flow_dissector: Use 'const' where possible. flow_dissector: Fix function argument ordering dependency ixgbe: Resolve "initialized field overwritten" warnings ixgbe: Remove bimodal SR-IOV disabling ixgbe: Add support for reporting 2.5G link speed ixgbe: fix bounds checking in ixgbe_setup_tc for 82598 ixgbe: support for ethtool set_rxfh ixgbe: Avoid needless PHY access on copper phys ixgbe: cleanup to use cached mask value ixgbe: Remove second instance of lan_id variable ixgbe: use kzalloc for allocating one thing flow: Move __get_hash_from_flowi{4,6} into flow_dissector.c ixgbe: Remove unused PCI bus types ...
Diffstat (limited to 'kernel/trace')
-rw-r--r--kernel/trace/bpf_trace.c63
-rw-r--r--kernel/trace/trace_kprobe.c20
2 files changed, 65 insertions, 18 deletions
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 88a041adee90..0fe96c7c8803 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -81,13 +81,16 @@ static const struct bpf_func_proto bpf_probe_read_proto = {
81 81
82/* 82/*
83 * limited trace_printk() 83 * limited trace_printk()
84 * only %d %u %x %ld %lu %lx %lld %llu %llx %p conversion specifiers allowed 84 * only %d %u %x %ld %lu %lx %lld %llu %llx %p %s conversion specifiers allowed
85 */ 85 */
86static u64 bpf_trace_printk(u64 r1, u64 fmt_size, u64 r3, u64 r4, u64 r5) 86static u64 bpf_trace_printk(u64 r1, u64 fmt_size, u64 r3, u64 r4, u64 r5)
87{ 87{
88 char *fmt = (char *) (long) r1; 88 char *fmt = (char *) (long) r1;
89 bool str_seen = false;
89 int mod[3] = {}; 90 int mod[3] = {};
90 int fmt_cnt = 0; 91 int fmt_cnt = 0;
92 u64 unsafe_addr;
93 char buf[64];
91 int i; 94 int i;
92 95
93 /* 96 /*
@@ -114,12 +117,37 @@ static u64 bpf_trace_printk(u64 r1, u64 fmt_size, u64 r3, u64 r4, u64 r5)
114 if (fmt[i] == 'l') { 117 if (fmt[i] == 'l') {
115 mod[fmt_cnt]++; 118 mod[fmt_cnt]++;
116 i++; 119 i++;
117 } else if (fmt[i] == 'p') { 120 } else if (fmt[i] == 'p' || fmt[i] == 's') {
118 mod[fmt_cnt]++; 121 mod[fmt_cnt]++;
119 i++; 122 i++;
120 if (!isspace(fmt[i]) && !ispunct(fmt[i]) && fmt[i] != 0) 123 if (!isspace(fmt[i]) && !ispunct(fmt[i]) && fmt[i] != 0)
121 return -EINVAL; 124 return -EINVAL;
122 fmt_cnt++; 125 fmt_cnt++;
126 if (fmt[i - 1] == 's') {
127 if (str_seen)
128 /* allow only one '%s' per fmt string */
129 return -EINVAL;
130 str_seen = true;
131
132 switch (fmt_cnt) {
133 case 1:
134 unsafe_addr = r3;
135 r3 = (long) buf;
136 break;
137 case 2:
138 unsafe_addr = r4;
139 r4 = (long) buf;
140 break;
141 case 3:
142 unsafe_addr = r5;
143 r5 = (long) buf;
144 break;
145 }
146 buf[0] = 0;
147 strncpy_from_unsafe(buf,
148 (void *) (long) unsafe_addr,
149 sizeof(buf));
150 }
123 continue; 151 continue;
124 } 152 }
125 153
@@ -158,6 +186,35 @@ const struct bpf_func_proto *bpf_get_trace_printk_proto(void)
158 return &bpf_trace_printk_proto; 186 return &bpf_trace_printk_proto;
159} 187}
160 188
189static u64 bpf_perf_event_read(u64 r1, u64 index, u64 r3, u64 r4, u64 r5)
190{
191 struct bpf_map *map = (struct bpf_map *) (unsigned long) r1;
192 struct bpf_array *array = container_of(map, struct bpf_array, map);
193 struct perf_event *event;
194
195 if (unlikely(index >= array->map.max_entries))
196 return -E2BIG;
197
198 event = (struct perf_event *)array->ptrs[index];
199 if (!event)
200 return -ENOENT;
201
202 /*
203 * we don't know if the function is run successfully by the
204 * return value. It can be judged in other places, such as
205 * eBPF programs.
206 */
207 return perf_event_read_local(event);
208}
209
210const struct bpf_func_proto bpf_perf_event_read_proto = {
211 .func = bpf_perf_event_read,
212 .gpl_only = false,
213 .ret_type = RET_INTEGER,
214 .arg1_type = ARG_CONST_MAP_PTR,
215 .arg2_type = ARG_ANYTHING,
216};
217
161static const struct bpf_func_proto *kprobe_prog_func_proto(enum bpf_func_id func_id) 218static const struct bpf_func_proto *kprobe_prog_func_proto(enum bpf_func_id func_id)
162{ 219{
163 switch (func_id) { 220 switch (func_id) {
@@ -183,6 +240,8 @@ static const struct bpf_func_proto *kprobe_prog_func_proto(enum bpf_func_id func
183 return bpf_get_trace_printk_proto(); 240 return bpf_get_trace_printk_proto();
184 case BPF_FUNC_get_smp_processor_id: 241 case BPF_FUNC_get_smp_processor_id:
185 return &bpf_get_smp_processor_id_proto; 242 return &bpf_get_smp_processor_id_proto;
243 case BPF_FUNC_perf_event_read:
244 return &bpf_perf_event_read_proto;
186 default: 245 default:
187 return NULL; 246 return NULL;
188 } 247 }
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index b7d0cdd9906c..c9956440d0e6 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -165,11 +165,9 @@ DEFINE_BASIC_FETCH_FUNCS(memory)
165static void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs, 165static void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs,
166 void *addr, void *dest) 166 void *addr, void *dest)
167{ 167{
168 long ret;
169 int maxlen = get_rloc_len(*(u32 *)dest); 168 int maxlen = get_rloc_len(*(u32 *)dest);
170 u8 *dst = get_rloc_data(dest); 169 u8 *dst = get_rloc_data(dest);
171 u8 *src = addr; 170 long ret;
172 mm_segment_t old_fs = get_fs();
173 171
174 if (!maxlen) 172 if (!maxlen)
175 return; 173 return;
@@ -178,23 +176,13 @@ static void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs,
178 * Try to get string again, since the string can be changed while 176 * Try to get string again, since the string can be changed while
179 * probing. 177 * probing.
180 */ 178 */
181 set_fs(KERNEL_DS); 179 ret = strncpy_from_unsafe(dst, addr, maxlen);
182 pagefault_disable();
183
184 do
185 ret = __copy_from_user_inatomic(dst++, src++, 1);
186 while (dst[-1] && ret == 0 && src - (u8 *)addr < maxlen);
187
188 dst[-1] = '\0';
189 pagefault_enable();
190 set_fs(old_fs);
191 180
192 if (ret < 0) { /* Failed to fetch string */ 181 if (ret < 0) { /* Failed to fetch string */
193 ((u8 *)get_rloc_data(dest))[0] = '\0'; 182 dst[0] = '\0';
194 *(u32 *)dest = make_data_rloc(0, get_rloc_offs(*(u32 *)dest)); 183 *(u32 *)dest = make_data_rloc(0, get_rloc_offs(*(u32 *)dest));
195 } else { 184 } else {
196 *(u32 *)dest = make_data_rloc(src - (u8 *)addr, 185 *(u32 *)dest = make_data_rloc(ret, get_rloc_offs(*(u32 *)dest));
197 get_rloc_offs(*(u32 *)dest));
198 } 186 }
199} 187}
200NOKPROBE_SYMBOL(FETCH_FUNC_NAME(memory, string)); 188NOKPROBE_SYMBOL(FETCH_FUNC_NAME(memory, string));