projects/linux·blob master · refs

602 lines · 14.0 KiB

1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (C) 2023 Google Corporation
4 */
5
6#include <linux/devcoredump.h>
7
8#include <linux/unaligned.h>
9#include <net/bluetooth/bluetooth.h>
10#include <net/bluetooth/hci_core.h>
11
12enum hci_devcoredump_pkt_type {
13 HCI_DEVCOREDUMP_PKT_INIT,
14 HCI_DEVCOREDUMP_PKT_SKB,
15 HCI_DEVCOREDUMP_PKT_PATTERN,
16 HCI_DEVCOREDUMP_PKT_COMPLETE,
17 HCI_DEVCOREDUMP_PKT_ABORT,
18};
19
20struct hci_devcoredump_skb_cb {
21 u16 pkt_type;
22};
23
24struct hci_devcoredump_skb_pattern {
25 u8 pattern;
26 u32 len;
27} __packed;
28
29#define hci_dmp_cb(skb) ((struct hci_devcoredump_skb_cb *)((skb)->cb))
30
31#define DBG_UNEXPECTED_STATE() \
32 bt_dev_dbg(hdev, \
33 "Unexpected packet (%d) for state %s.", \
34 hci_dmp_cb(skb)->pkt_type, \
35 hci_devcd_state_name(hdev->dump.state))
36
37static int hci_devcd_update_hdr_state(char *buf, size_t size, int state)
38{
39 int len = 0;
40
41 if (!buf)
42 return 0;
43
44 len = scnprintf(buf, size, "Bluetooth devcoredump\nState: %d\n", state);
45
46 return len + 1; /* scnprintf adds \0 at the end upon state rewrite */
47}
48
49/* Call with hci_dev_lock only. */
50static int hci_devcd_update_state(struct hci_dev *hdev, int state)
51{
52 bt_dev_dbg(hdev, "Updating devcoredump state from %s to %s.",
53 hci_devcd_state_name(hdev->dump.state),
54 hci_devcd_state_name(state));
55
56 hdev->dump.state = state;
57
58 return hci_devcd_update_hdr_state(hdev->dump.head,
59 hdev->dump.alloc_size, state);
60}
61
62static int hci_devcd_mkheader(struct hci_dev *hdev, struct sk_buff *skb)
63{
64 char hdr[80];
65 int hdr_len;
66
67 hdr_len = hci_devcd_update_hdr_state(hdr, sizeof(hdr),
68 HCI_DEVCOREDUMP_IDLE);
69 skb_put_data(skb, hdr, hdr_len);
70
71 if (hdev->dump.dmp_hdr)
72 hdev->dump.dmp_hdr(hdev, skb);
73
74 skb_put_data(skb, HCI_DEVCD_HDR_END_MARKER, strlen(HCI_DEVCD_HDR_END_MARKER));
75
76 return skb->len;
77}
78
79/* Do not call with hci_dev_lock since this calls driver code. */
80static void hci_devcd_notify(struct hci_dev *hdev, int state)
81{
82 if (hdev->dump.notify_change)
83 hdev->dump.notify_change(hdev, state);
84}
85
86/* Call with hci_dev_lock only. */
87void hci_devcd_reset(struct hci_dev *hdev)
88{
89 hdev->dump.head = NULL;
90 hdev->dump.tail = NULL;
91 hdev->dump.alloc_size = 0;
92
93 hci_devcd_update_state(hdev, HCI_DEVCOREDUMP_IDLE);
94
95 cancel_delayed_work(&hdev->dump.dump_timeout);
96 skb_queue_purge(&hdev->dump.dump_q);
97}
98
99/* Call with hci_dev_lock only. */
100static void hci_devcd_free(struct hci_dev *hdev)
101{
102 vfree(hdev->dump.head);
103
104 hci_devcd_reset(hdev);
105}
106
107void hci_devcd_shutdown(struct hci_dev *hdev)
108{
109 unsigned long flags;
110
111 spin_lock_irqsave(&hdev->dump.dump_q.lock, flags);
112 hdev->dump.supported = false;
113 spin_unlock_irqrestore(&hdev->dump.dump_q.lock, flags);
114
115 disable_work_sync(&hdev->dump.dump_rx);
116 disable_delayed_work_sync(&hdev->dump.dump_timeout);
117
118 hci_dev_lock(hdev);
119 hci_devcd_free(hdev);
120 hci_dev_unlock(hdev);
121}
122
123/* Call with hci_dev_lock only. */
124static int hci_devcd_alloc(struct hci_dev *hdev, u32 size)
125{
126 hdev->dump.head = vmalloc(size);
127 if (!hdev->dump.head)
128 return -ENOMEM;
129
130 hdev->dump.alloc_size = size;
131 hdev->dump.tail = hdev->dump.head;
132 hdev->dump.end = hdev->dump.head + size;
133
134 hci_devcd_update_state(hdev, HCI_DEVCOREDUMP_IDLE);
135
136 return 0;
137}
138
139/* Call with hci_dev_lock only. */
140static bool hci_devcd_copy(struct hci_dev *hdev, char *buf, u32 size)
141{
142 if (hdev->dump.tail + size > hdev->dump.end)
143 return false;
144
145 memcpy(hdev->dump.tail, buf, size);
146 hdev->dump.tail += size;
147
148 return true;
149}
150
151/* Call with hci_dev_lock only. */
152static bool hci_devcd_memset(struct hci_dev *hdev, u8 pattern, u32 len)
153{
154 if (hdev->dump.tail + len > hdev->dump.end)
155 return false;
156
157 memset(hdev->dump.tail, pattern, len);
158 hdev->dump.tail += len;
159
160 return true;
161}
162
163/* Call with hci_dev_lock only. */
164static int hci_devcd_prepare(struct hci_dev *hdev, u32 dump_size)
165{
166 struct sk_buff *skb;
167 int dump_hdr_size;
168 int err = 0;
169
170 skb = alloc_skb(HCI_DEVCD_HDR_SIZE_MAX, GFP_ATOMIC);
171 if (!skb)
172 return -ENOMEM;
173
174 dump_hdr_size = hci_devcd_mkheader(hdev, skb);
175
176 if (hci_devcd_alloc(hdev, dump_hdr_size + dump_size)) {
177 err = -ENOMEM;
178 goto hdr_free;
179 }
180
181 /* Insert the device header */
182 if (!hci_devcd_copy(hdev, skb->data, skb->len)) {
183 bt_dev_err(hdev, "Failed to insert header");
184 hci_devcd_free(hdev);
185
186 err = -ENOMEM;
187 goto hdr_free;
188 }
189
190hdr_free:
191 kfree_skb(skb);
192
193 return err;
194}
195
196static void hci_devcd_handle_pkt_init(struct hci_dev *hdev, struct sk_buff *skb)
197{
198 u32 dump_size;
199
200 if (hdev->dump.state != HCI_DEVCOREDUMP_IDLE) {
201 DBG_UNEXPECTED_STATE();
202 return;
203 }
204
205 if (skb->len != sizeof(dump_size)) {
206 bt_dev_dbg(hdev, "Invalid dump init pkt");
207 return;
208 }
209
210 dump_size = get_unaligned_le32(skb_pull_data(skb, 4));
211 if (!dump_size) {
212 bt_dev_err(hdev, "Zero size dump init pkt");
213 return;
214 }
215
216 if (hci_devcd_prepare(hdev, dump_size)) {
217 bt_dev_err(hdev, "Failed to prepare for dump");
218 return;
219 }
220
221 hci_devcd_update_state(hdev, HCI_DEVCOREDUMP_ACTIVE);
222 queue_delayed_work(hdev->workqueue, &hdev->dump.dump_timeout,
223 hdev->dump.timeout);
224}
225
226static void hci_devcd_handle_pkt_skb(struct hci_dev *hdev, struct sk_buff *skb)
227{
228 if (hdev->dump.state != HCI_DEVCOREDUMP_ACTIVE) {
229 DBG_UNEXPECTED_STATE();
230 return;
231 }
232
233 if (!hci_devcd_copy(hdev, skb->data, skb->len))
234 bt_dev_dbg(hdev, "Failed to insert skb");
235}
236
237static void hci_devcd_handle_pkt_pattern(struct hci_dev *hdev,
238 struct sk_buff *skb)
239{
240 struct hci_devcoredump_skb_pattern *pattern;
241
242 if (hdev->dump.state != HCI_DEVCOREDUMP_ACTIVE) {
243 DBG_UNEXPECTED_STATE();
244 return;
245 }
246
247 if (skb->len != sizeof(*pattern)) {
248 bt_dev_dbg(hdev, "Invalid pattern skb");
249 return;
250 }
251
252 pattern = skb_pull_data(skb, sizeof(*pattern));
253
254 if (!hci_devcd_memset(hdev, pattern->pattern, pattern->len))
255 bt_dev_dbg(hdev, "Failed to set pattern");
256}
257
258static void hci_devcd_dump(struct hci_dev *hdev)
259{
260 struct sk_buff *skb;
261 u32 size;
262
263 bt_dev_dbg(hdev, "state %s", hci_devcd_state_name(hdev->dump.state));
264
265 size = hdev->dump.tail - hdev->dump.head;
266
267 /* Send a copy to monitor as a diagnostic packet */
268 skb = bt_skb_alloc(size, GFP_ATOMIC);
269 if (skb) {
270 skb_put_data(skb, hdev->dump.head, size);
271 hci_recv_diag(hdev, skb);
272 }
273
274 /* Emit a devcoredump with the available data */
275 dev_coredumpv(&hdev->dev, hdev->dump.head, size, GFP_KERNEL);
276}
277
278static void hci_devcd_handle_pkt_complete(struct hci_dev *hdev,
279 struct sk_buff *skb)
280{
281 u32 dump_size;
282
283 if (hdev->dump.state != HCI_DEVCOREDUMP_ACTIVE) {
284 DBG_UNEXPECTED_STATE();
285 return;
286 }
287
288 hci_devcd_update_state(hdev, HCI_DEVCOREDUMP_DONE);
289 dump_size = hdev->dump.tail - hdev->dump.head;
290
291 bt_dev_dbg(hdev, "complete with size %u (expect %zu)", dump_size,
292 hdev->dump.alloc_size);
293
294 hci_devcd_dump(hdev);
295}
296
297static void hci_devcd_handle_pkt_abort(struct hci_dev *hdev,
298 struct sk_buff *skb)
299{
300 u32 dump_size;
301
302 if (hdev->dump.state != HCI_DEVCOREDUMP_ACTIVE) {
303 DBG_UNEXPECTED_STATE();
304 return;
305 }
306
307 hci_devcd_update_state(hdev, HCI_DEVCOREDUMP_ABORT);
308 dump_size = hdev->dump.tail - hdev->dump.head;
309
310 bt_dev_dbg(hdev, "aborted with size %u (expect %zu)", dump_size,
311 hdev->dump.alloc_size);
312
313 hci_devcd_dump(hdev);
314}
315
316/* Bluetooth devcoredump state machine.
317 *
318 * Devcoredump states:
319 *
320 * HCI_DEVCOREDUMP_IDLE: The default state.
321 *
322 * HCI_DEVCOREDUMP_ACTIVE: A devcoredump will be in this state once it has
323 * been initialized using hci_devcd_init(). Once active, the driver
324 * can append data using hci_devcd_append() or insert a pattern
325 * using hci_devcd_append_pattern().
326 *
327 * HCI_DEVCOREDUMP_DONE: Once the dump collection is complete, the drive
328 * can signal the completion using hci_devcd_complete(). A
329 * devcoredump is generated indicating the completion event and
330 * then the state machine is reset to the default state.
331 *
332 * HCI_DEVCOREDUMP_ABORT: The driver can cancel ongoing dump collection in
333 * case of any error using hci_devcd_abort(). A devcoredump is
334 * still generated with the available data indicating the abort
335 * event and then the state machine is reset to the default state.
336 *
337 * HCI_DEVCOREDUMP_TIMEOUT: A timeout timer for HCI_DEVCOREDUMP_TIMEOUT sec
338 * is started during devcoredump initialization. Once the timeout
339 * occurs, the driver is notified, a devcoredump is generated with
340 * the available data indicating the timeout event and then the
341 * state machine is reset to the default state.
342 *
343 * The driver must register using hci_devcd_register() before using the hci
344 * devcoredump APIs.
345 */
346void hci_devcd_rx(struct work_struct *work)
347{
348 struct hci_dev *hdev = container_of(work, struct hci_dev, dump.dump_rx);
349 struct sk_buff *skb;
350 int start_state;
351
352 while ((skb = skb_dequeue(&hdev->dump.dump_q))) {
353 /* Return if timeout occurs. The timeout handler function
354 * hci_devcd_timeout() will report the available dump data.
355 */
356 if (hdev->dump.state == HCI_DEVCOREDUMP_TIMEOUT) {
357 kfree_skb(skb);
358 return;
359 }
360
361 hci_dev_lock(hdev);
362 start_state = hdev->dump.state;
363
364 switch (hci_dmp_cb(skb)->pkt_type) {
365 case HCI_DEVCOREDUMP_PKT_INIT:
366 hci_devcd_handle_pkt_init(hdev, skb);
367 break;
368
369 case HCI_DEVCOREDUMP_PKT_SKB:
370 hci_devcd_handle_pkt_skb(hdev, skb);
371 break;
372
373 case HCI_DEVCOREDUMP_PKT_PATTERN:
374 hci_devcd_handle_pkt_pattern(hdev, skb);
375 break;
376
377 case HCI_DEVCOREDUMP_PKT_COMPLETE:
378 hci_devcd_handle_pkt_complete(hdev, skb);
379 break;
380
381 case HCI_DEVCOREDUMP_PKT_ABORT:
382 hci_devcd_handle_pkt_abort(hdev, skb);
383 break;
384
385 default:
386 bt_dev_dbg(hdev, "Unknown packet (%d) for state %s.",
387 hci_dmp_cb(skb)->pkt_type,
388 hci_devcd_state_name(hdev->dump.state));
389 break;
390 }
391
392 hci_dev_unlock(hdev);
393 kfree_skb(skb);
394
395 /* Notify the driver about any state changes before resetting
396 * the state machine
397 */
398 if (start_state != hdev->dump.state)
399 hci_devcd_notify(hdev, hdev->dump.state);
400
401 /* Reset the state machine if the devcoredump is complete */
402 hci_dev_lock(hdev);
403 if (hdev->dump.state == HCI_DEVCOREDUMP_DONE ||
404 hdev->dump.state == HCI_DEVCOREDUMP_ABORT)
405 hci_devcd_reset(hdev);
406 hci_dev_unlock(hdev);
407 }
408}
409
410void hci_devcd_timeout(struct work_struct *work)
411{
412 struct hci_dev *hdev = container_of(work, struct hci_dev,
413 dump.dump_timeout.work);
414 u32 dump_size;
415
416 hci_devcd_notify(hdev, HCI_DEVCOREDUMP_TIMEOUT);
417
418 hci_dev_lock(hdev);
419
420 cancel_work(&hdev->dump.dump_rx);
421
422 hci_devcd_update_state(hdev, HCI_DEVCOREDUMP_TIMEOUT);
423
424 dump_size = hdev->dump.tail - hdev->dump.head;
425 bt_dev_dbg(hdev, "timeout with size %u (expect %zu)", dump_size,
426 hdev->dump.alloc_size);
427
428 hci_devcd_dump(hdev);
429
430 hci_devcd_reset(hdev);
431
432 hci_dev_unlock(hdev);
433}
434
435int hci_devcd_register(struct hci_dev *hdev, coredump_t coredump,
436 dmp_hdr_t dmp_hdr, notify_change_t notify_change)
437{
438 /* Driver must implement coredump() and dmp_hdr() functions for
439 * bluetooth devcoredump. The coredump() should trigger a coredump
440 * event on the controller when the device's coredump sysfs entry is
441 * written to. The dmp_hdr() should create a dump header to identify
442 * the controller/fw/driver info.
443 */
444 if (!coredump || !dmp_hdr)
445 return -EINVAL;
446
447 hci_dev_lock(hdev);
448 hdev->dump.coredump = coredump;
449 hdev->dump.dmp_hdr = dmp_hdr;
450 hdev->dump.notify_change = notify_change;
451 hdev->dump.supported = true;
452 hdev->dump.timeout = DEVCOREDUMP_TIMEOUT;
453 hci_dev_unlock(hdev);
454
455 return 0;
456}
457EXPORT_SYMBOL(hci_devcd_register);
458
459static inline bool hci_devcd_enabled(struct hci_dev *hdev)
460{
461 return READ_ONCE(hdev->dump.supported);
462}
463
464static int hci_devcd_queue(struct hci_dev *hdev, struct sk_buff *skb)
465{
466 unsigned long flags;
467 int err = 0;
468
469 spin_lock_irqsave(&hdev->dump.dump_q.lock, flags);
470 if (!hdev->dump.supported)
471 err = -EOPNOTSUPP;
472 else
473 __skb_queue_tail(&hdev->dump.dump_q, skb);
474 spin_unlock_irqrestore(&hdev->dump.dump_q.lock, flags);
475
476 if (err) {
477 kfree_skb(skb);
478 return err;
479 }
480
481 queue_work(hdev->workqueue, &hdev->dump.dump_rx);
482
483 return 0;
484}
485
486int hci_devcd_init(struct hci_dev *hdev, u32 dump_size)
487{
488 struct sk_buff *skb;
489
490 if (!hci_devcd_enabled(hdev))
491 return -EOPNOTSUPP;
492
493 skb = alloc_skb(sizeof(dump_size), GFP_ATOMIC);
494 if (!skb)
495 return -ENOMEM;
496
497 hci_dmp_cb(skb)->pkt_type = HCI_DEVCOREDUMP_PKT_INIT;
498 put_unaligned_le32(dump_size, skb_put(skb, 4));
499
500 return hci_devcd_queue(hdev, skb);
501}
502EXPORT_SYMBOL(hci_devcd_init);
503
504int hci_devcd_append(struct hci_dev *hdev, struct sk_buff *skb)
505{
506 if (!skb)
507 return -ENOMEM;
508
509 if (!hci_devcd_enabled(hdev)) {
510 kfree_skb(skb);
511 return -EOPNOTSUPP;
512 }
513
514 hci_dmp_cb(skb)->pkt_type = HCI_DEVCOREDUMP_PKT_SKB;
515
516 return hci_devcd_queue(hdev, skb);
517}
518EXPORT_SYMBOL(hci_devcd_append);
519
520int hci_devcd_append_pattern(struct hci_dev *hdev, u8 pattern, u32 len)
521{
522 struct hci_devcoredump_skb_pattern p;
523 struct sk_buff *skb;
524
525 if (!hci_devcd_enabled(hdev))
526 return -EOPNOTSUPP;
527
528 skb = alloc_skb(sizeof(p), GFP_ATOMIC);
529 if (!skb)
530 return -ENOMEM;
531
532 p.pattern = pattern;
533 p.len = len;
534
535 hci_dmp_cb(skb)->pkt_type = HCI_DEVCOREDUMP_PKT_PATTERN;
536 skb_put_data(skb, &p, sizeof(p));
537
538 return hci_devcd_queue(hdev, skb);
539}
540EXPORT_SYMBOL(hci_devcd_append_pattern);
541
542int hci_devcd_complete(struct hci_dev *hdev)
543{
544 struct sk_buff *skb;
545
546 if (!hci_devcd_enabled(hdev))
547 return -EOPNOTSUPP;
548
549 skb = alloc_skb(0, GFP_ATOMIC);
550 if (!skb)
551 return -ENOMEM;
552
553 hci_dmp_cb(skb)->pkt_type = HCI_DEVCOREDUMP_PKT_COMPLETE;
554
555 return hci_devcd_queue(hdev, skb);
556}
557EXPORT_SYMBOL(hci_devcd_complete);
558
559int hci_devcd_abort(struct hci_dev *hdev)
560{
561 struct sk_buff *skb;
562
563 if (!hci_devcd_enabled(hdev))
564 return -EOPNOTSUPP;
565
566 skb = alloc_skb(0, GFP_ATOMIC);
567 if (!skb)
568 return -ENOMEM;
569
570 hci_dmp_cb(skb)->pkt_type = HCI_DEVCOREDUMP_PKT_ABORT;
571
572 return hci_devcd_queue(hdev, skb);
573}
574EXPORT_SYMBOL(hci_devcd_abort);
575
576const char *hci_devcd_state_name(enum devcoredump_state state)
577{
578 const char *state_name = "Unknown";
579
580 switch (state) {
581 case HCI_DEVCOREDUMP_IDLE:
582 state_name = "IDLE";
583 break;
584 case HCI_DEVCOREDUMP_ACTIVE:
585 state_name = "ACTIVE";
586 break;
587 case HCI_DEVCOREDUMP_DONE:
588 state_name = "DONE";
589 break;
590 case HCI_DEVCOREDUMP_ABORT:
591 state_name = "ABORT";
592 break;
593 case HCI_DEVCOREDUMP_TIMEOUT:
594 state_name = "TIMEOUT";
595 break;
596 default:
597 break;
598 }
599
600 return state_name;
601}
602EXPORT_SYMBOL(hci_devcd_state_name);