diff options
Diffstat (limited to 'drivers/connector/cn_proc.c')
-rw-r--r-- | drivers/connector/cn_proc.c | 43 |
1 files changed, 22 insertions, 21 deletions
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c index 15d06fcf0b50..b02f9c606e0b 100644 --- a/drivers/connector/cn_proc.c +++ b/drivers/connector/cn_proc.c | |||
@@ -56,11 +56,21 @@ static struct cb_id cn_proc_event_id = { CN_IDX_PROC, CN_VAL_PROC }; | |||
56 | /* proc_event_counts is used as the sequence number of the netlink message */ | 56 | /* proc_event_counts is used as the sequence number of the netlink message */ |
57 | static DEFINE_PER_CPU(__u32, proc_event_counts) = { 0 }; | 57 | static DEFINE_PER_CPU(__u32, proc_event_counts) = { 0 }; |
58 | 58 | ||
59 | static inline void get_seq(__u32 *ts, int *cpu) | 59 | static inline void send_msg(struct cn_msg *msg) |
60 | { | 60 | { |
61 | preempt_disable(); | 61 | preempt_disable(); |
62 | *ts = __this_cpu_inc_return(proc_event_counts) - 1; | 62 | |
63 | *cpu = smp_processor_id(); | 63 | msg->seq = __this_cpu_inc_return(proc_event_counts) - 1; |
64 | ((struct proc_event *)msg->data)->cpu = smp_processor_id(); | ||
65 | |||
66 | /* | ||
67 | * Preemption remains disabled during send to ensure the messages are | ||
68 | * ordered according to their sequence numbers. | ||
69 | * | ||
70 | * If cn_netlink_send() fails, the data is not sent. | ||
71 | */ | ||
72 | cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_NOWAIT); | ||
73 | |||
64 | preempt_enable(); | 74 | preempt_enable(); |
65 | } | 75 | } |
66 | 76 | ||
@@ -77,7 +87,6 @@ void proc_fork_connector(struct task_struct *task) | |||
77 | msg = buffer_to_cn_msg(buffer); | 87 | msg = buffer_to_cn_msg(buffer); |
78 | ev = (struct proc_event *)msg->data; | 88 | ev = (struct proc_event *)msg->data; |
79 | memset(&ev->event_data, 0, sizeof(ev->event_data)); | 89 | memset(&ev->event_data, 0, sizeof(ev->event_data)); |
80 | get_seq(&msg->seq, &ev->cpu); | ||
81 | ev->timestamp_ns = ktime_get_ns(); | 90 | ev->timestamp_ns = ktime_get_ns(); |
82 | ev->what = PROC_EVENT_FORK; | 91 | ev->what = PROC_EVENT_FORK; |
83 | rcu_read_lock(); | 92 | rcu_read_lock(); |
@@ -92,8 +101,7 @@ void proc_fork_connector(struct task_struct *task) | |||
92 | msg->ack = 0; /* not used */ | 101 | msg->ack = 0; /* not used */ |
93 | msg->len = sizeof(*ev); | 102 | msg->len = sizeof(*ev); |
94 | msg->flags = 0; /* not used */ | 103 | msg->flags = 0; /* not used */ |
95 | /* If cn_netlink_send() failed, the data is not sent */ | 104 | send_msg(msg); |
96 | cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL); | ||
97 | } | 105 | } |
98 | 106 | ||
99 | void proc_exec_connector(struct task_struct *task) | 107 | void proc_exec_connector(struct task_struct *task) |
@@ -108,7 +116,6 @@ void proc_exec_connector(struct task_struct *task) | |||
108 | msg = buffer_to_cn_msg(buffer); | 116 | msg = buffer_to_cn_msg(buffer); |
109 | ev = (struct proc_event *)msg->data; | 117 | ev = (struct proc_event *)msg->data; |
110 | memset(&ev->event_data, 0, sizeof(ev->event_data)); | 118 | memset(&ev->event_data, 0, sizeof(ev->event_data)); |
111 | get_seq(&msg->seq, &ev->cpu); | ||
112 | ev->timestamp_ns = ktime_get_ns(); | 119 | ev->timestamp_ns = ktime_get_ns(); |
113 | ev->what = PROC_EVENT_EXEC; | 120 | ev->what = PROC_EVENT_EXEC; |
114 | ev->event_data.exec.process_pid = task->pid; | 121 | ev->event_data.exec.process_pid = task->pid; |
@@ -118,7 +125,7 @@ void proc_exec_connector(struct task_struct *task) | |||
118 | msg->ack = 0; /* not used */ | 125 | msg->ack = 0; /* not used */ |
119 | msg->len = sizeof(*ev); | 126 | msg->len = sizeof(*ev); |
120 | msg->flags = 0; /* not used */ | 127 | msg->flags = 0; /* not used */ |
121 | cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL); | 128 | send_msg(msg); |
122 | } | 129 | } |
123 | 130 | ||
124 | void proc_id_connector(struct task_struct *task, int which_id) | 131 | void proc_id_connector(struct task_struct *task, int which_id) |
@@ -150,14 +157,13 @@ void proc_id_connector(struct task_struct *task, int which_id) | |||
150 | return; | 157 | return; |
151 | } | 158 | } |
152 | rcu_read_unlock(); | 159 | rcu_read_unlock(); |
153 | get_seq(&msg->seq, &ev->cpu); | ||
154 | ev->timestamp_ns = ktime_get_ns(); | 160 | ev->timestamp_ns = ktime_get_ns(); |
155 | 161 | ||
156 | memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); | 162 | memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); |
157 | msg->ack = 0; /* not used */ | 163 | msg->ack = 0; /* not used */ |
158 | msg->len = sizeof(*ev); | 164 | msg->len = sizeof(*ev); |
159 | msg->flags = 0; /* not used */ | 165 | msg->flags = 0; /* not used */ |
160 | cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL); | 166 | send_msg(msg); |
161 | } | 167 | } |
162 | 168 | ||
163 | void proc_sid_connector(struct task_struct *task) | 169 | void proc_sid_connector(struct task_struct *task) |
@@ -172,7 +178,6 @@ void proc_sid_connector(struct task_struct *task) | |||
172 | msg = buffer_to_cn_msg(buffer); | 178 | msg = buffer_to_cn_msg(buffer); |
173 | ev = (struct proc_event *)msg->data; | 179 | ev = (struct proc_event *)msg->data; |
174 | memset(&ev->event_data, 0, sizeof(ev->event_data)); | 180 | memset(&ev->event_data, 0, sizeof(ev->event_data)); |
175 | get_seq(&msg->seq, &ev->cpu); | ||
176 | ev->timestamp_ns = ktime_get_ns(); | 181 | ev->timestamp_ns = ktime_get_ns(); |
177 | ev->what = PROC_EVENT_SID; | 182 | ev->what = PROC_EVENT_SID; |
178 | ev->event_data.sid.process_pid = task->pid; | 183 | ev->event_data.sid.process_pid = task->pid; |
@@ -182,7 +187,7 @@ void proc_sid_connector(struct task_struct *task) | |||
182 | msg->ack = 0; /* not used */ | 187 | msg->ack = 0; /* not used */ |
183 | msg->len = sizeof(*ev); | 188 | msg->len = sizeof(*ev); |
184 | msg->flags = 0; /* not used */ | 189 | msg->flags = 0; /* not used */ |
185 | cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL); | 190 | send_msg(msg); |
186 | } | 191 | } |
187 | 192 | ||
188 | void proc_ptrace_connector(struct task_struct *task, int ptrace_id) | 193 | void proc_ptrace_connector(struct task_struct *task, int ptrace_id) |
@@ -197,7 +202,6 @@ void proc_ptrace_connector(struct task_struct *task, int ptrace_id) | |||
197 | msg = buffer_to_cn_msg(buffer); | 202 | msg = buffer_to_cn_msg(buffer); |
198 | ev = (struct proc_event *)msg->data; | 203 | ev = (struct proc_event *)msg->data; |
199 | memset(&ev->event_data, 0, sizeof(ev->event_data)); | 204 | memset(&ev->event_data, 0, sizeof(ev->event_data)); |
200 | get_seq(&msg->seq, &ev->cpu); | ||
201 | ev->timestamp_ns = ktime_get_ns(); | 205 | ev->timestamp_ns = ktime_get_ns(); |
202 | ev->what = PROC_EVENT_PTRACE; | 206 | ev->what = PROC_EVENT_PTRACE; |
203 | ev->event_data.ptrace.process_pid = task->pid; | 207 | ev->event_data.ptrace.process_pid = task->pid; |
@@ -215,7 +219,7 @@ void proc_ptrace_connector(struct task_struct *task, int ptrace_id) | |||
215 | msg->ack = 0; /* not used */ | 219 | msg->ack = 0; /* not used */ |
216 | msg->len = sizeof(*ev); | 220 | msg->len = sizeof(*ev); |
217 | msg->flags = 0; /* not used */ | 221 | msg->flags = 0; /* not used */ |
218 | cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL); | 222 | send_msg(msg); |
219 | } | 223 | } |
220 | 224 | ||
221 | void proc_comm_connector(struct task_struct *task) | 225 | void proc_comm_connector(struct task_struct *task) |
@@ -230,7 +234,6 @@ void proc_comm_connector(struct task_struct *task) | |||
230 | msg = buffer_to_cn_msg(buffer); | 234 | msg = buffer_to_cn_msg(buffer); |
231 | ev = (struct proc_event *)msg->data; | 235 | ev = (struct proc_event *)msg->data; |
232 | memset(&ev->event_data, 0, sizeof(ev->event_data)); | 236 | memset(&ev->event_data, 0, sizeof(ev->event_data)); |
233 | get_seq(&msg->seq, &ev->cpu); | ||
234 | ev->timestamp_ns = ktime_get_ns(); | 237 | ev->timestamp_ns = ktime_get_ns(); |
235 | ev->what = PROC_EVENT_COMM; | 238 | ev->what = PROC_EVENT_COMM; |
236 | ev->event_data.comm.process_pid = task->pid; | 239 | ev->event_data.comm.process_pid = task->pid; |
@@ -241,7 +244,7 @@ void proc_comm_connector(struct task_struct *task) | |||
241 | msg->ack = 0; /* not used */ | 244 | msg->ack = 0; /* not used */ |
242 | msg->len = sizeof(*ev); | 245 | msg->len = sizeof(*ev); |
243 | msg->flags = 0; /* not used */ | 246 | msg->flags = 0; /* not used */ |
244 | cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL); | 247 | send_msg(msg); |
245 | } | 248 | } |
246 | 249 | ||
247 | void proc_coredump_connector(struct task_struct *task) | 250 | void proc_coredump_connector(struct task_struct *task) |
@@ -256,7 +259,6 @@ void proc_coredump_connector(struct task_struct *task) | |||
256 | msg = buffer_to_cn_msg(buffer); | 259 | msg = buffer_to_cn_msg(buffer); |
257 | ev = (struct proc_event *)msg->data; | 260 | ev = (struct proc_event *)msg->data; |
258 | memset(&ev->event_data, 0, sizeof(ev->event_data)); | 261 | memset(&ev->event_data, 0, sizeof(ev->event_data)); |
259 | get_seq(&msg->seq, &ev->cpu); | ||
260 | ev->timestamp_ns = ktime_get_ns(); | 262 | ev->timestamp_ns = ktime_get_ns(); |
261 | ev->what = PROC_EVENT_COREDUMP; | 263 | ev->what = PROC_EVENT_COREDUMP; |
262 | ev->event_data.coredump.process_pid = task->pid; | 264 | ev->event_data.coredump.process_pid = task->pid; |
@@ -266,7 +268,7 @@ void proc_coredump_connector(struct task_struct *task) | |||
266 | msg->ack = 0; /* not used */ | 268 | msg->ack = 0; /* not used */ |
267 | msg->len = sizeof(*ev); | 269 | msg->len = sizeof(*ev); |
268 | msg->flags = 0; /* not used */ | 270 | msg->flags = 0; /* not used */ |
269 | cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL); | 271 | send_msg(msg); |
270 | } | 272 | } |
271 | 273 | ||
272 | void proc_exit_connector(struct task_struct *task) | 274 | void proc_exit_connector(struct task_struct *task) |
@@ -281,7 +283,6 @@ void proc_exit_connector(struct task_struct *task) | |||
281 | msg = buffer_to_cn_msg(buffer); | 283 | msg = buffer_to_cn_msg(buffer); |
282 | ev = (struct proc_event *)msg->data; | 284 | ev = (struct proc_event *)msg->data; |
283 | memset(&ev->event_data, 0, sizeof(ev->event_data)); | 285 | memset(&ev->event_data, 0, sizeof(ev->event_data)); |
284 | get_seq(&msg->seq, &ev->cpu); | ||
285 | ev->timestamp_ns = ktime_get_ns(); | 286 | ev->timestamp_ns = ktime_get_ns(); |
286 | ev->what = PROC_EVENT_EXIT; | 287 | ev->what = PROC_EVENT_EXIT; |
287 | ev->event_data.exit.process_pid = task->pid; | 288 | ev->event_data.exit.process_pid = task->pid; |
@@ -293,7 +294,7 @@ void proc_exit_connector(struct task_struct *task) | |||
293 | msg->ack = 0; /* not used */ | 294 | msg->ack = 0; /* not used */ |
294 | msg->len = sizeof(*ev); | 295 | msg->len = sizeof(*ev); |
295 | msg->flags = 0; /* not used */ | 296 | msg->flags = 0; /* not used */ |
296 | cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL); | 297 | send_msg(msg); |
297 | } | 298 | } |
298 | 299 | ||
299 | /* | 300 | /* |
@@ -325,7 +326,7 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack) | |||
325 | msg->ack = rcvd_ack + 1; | 326 | msg->ack = rcvd_ack + 1; |
326 | msg->len = sizeof(*ev); | 327 | msg->len = sizeof(*ev); |
327 | msg->flags = 0; /* not used */ | 328 | msg->flags = 0; /* not used */ |
328 | cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL); | 329 | send_msg(msg); |
329 | } | 330 | } |
330 | 331 | ||
331 | /** | 332 | /** |