test_klp_callbacks_busy.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // SPDX-License-Identifier: GPL-2.0
  2. // Copyright (C) 2018 Joe Lawrence <[email protected]>
  3. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  4. #include <linux/module.h>
  5. #include <linux/kernel.h>
  6. #include <linux/sched.h>
  7. #include <linux/workqueue.h>
  8. #include <linux/delay.h>
  9. /* load/run-time control from sysfs writer */
  10. static bool block_transition;
  11. module_param(block_transition, bool, 0644);
  12. MODULE_PARM_DESC(block_transition, "block_transition (default=false)");
  13. static void busymod_work_func(struct work_struct *work);
  14. static DECLARE_WORK(work, busymod_work_func);
  15. static DECLARE_COMPLETION(busymod_work_started);
  16. static void busymod_work_func(struct work_struct *work)
  17. {
  18. pr_info("%s enter\n", __func__);
  19. complete(&busymod_work_started);
  20. while (READ_ONCE(block_transition)) {
  21. /*
  22. * Busy-wait until the sysfs writer has acknowledged a
  23. * blocked transition and clears the flag.
  24. */
  25. msleep(20);
  26. }
  27. pr_info("%s exit\n", __func__);
  28. }
  29. static int test_klp_callbacks_busy_init(void)
  30. {
  31. pr_info("%s\n", __func__);
  32. schedule_work(&work);
  33. /*
  34. * To synchronize kernel messages, hold the init function from
  35. * exiting until the work function's entry message has printed.
  36. */
  37. wait_for_completion(&busymod_work_started);
  38. if (!block_transition) {
  39. /*
  40. * Serialize output: print all messages from the work
  41. * function before returning from init().
  42. */
  43. flush_work(&work);
  44. }
  45. return 0;
  46. }
  47. static void test_klp_callbacks_busy_exit(void)
  48. {
  49. WRITE_ONCE(block_transition, false);
  50. flush_work(&work);
  51. pr_info("%s\n", __func__);
  52. }
  53. module_init(test_klp_callbacks_busy_init);
  54. module_exit(test_klp_callbacks_busy_exit);
  55. MODULE_LICENSE("GPL");
  56. MODULE_AUTHOR("Joe Lawrence <[email protected]>");
  57. MODULE_DESCRIPTION("Livepatch test: busy target module");