1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/ftrace.h> 3 #include <linux/init.h> 4 #include <linux/kernel.h> 5 #include <linux/module.h> 6 #include <linux/rv.h> 7 #include <linux/sched/deadline.h> 8 #include <linux/sched/rt.h> 9 #include <linux/tracepoint.h> 10 #include <rv/instrumentation.h> 11 12 #define MODULE_NAME "pagefault" 13 14 #include <rv_trace.h> 15 #include <trace/events/exceptions.h> 16 #include <monitors/rtapp/rtapp.h> 17 18 #include "pagefault.h" 19 #include <rv/ltl_monitor.h> 20 21 static void ltl_atoms_fetch(struct task_struct *task, struct ltl_monitor *mon) 22 { 23 /* 24 * This includes "actual" real-time tasks and also PI-boosted 25 * tasks. A task being PI-boosted means it is blocking an "actual" 26 * real-task, therefore it should also obey the monitor's rule, 27 * otherwise the "actual" real-task may be delayed. 28 */ 29 ltl_atom_set(mon, LTL_RT, rt_or_dl_task(task)); 30 } 31 32 static void ltl_atoms_init(struct task_struct *task, struct ltl_monitor *mon, bool task_creation) 33 { 34 if (task_creation) 35 ltl_atom_set(mon, LTL_PAGEFAULT, false); 36 } 37 38 static void handle_page_fault(void *data, unsigned long address, struct pt_regs *regs, 39 unsigned long error_code) 40 { 41 ltl_atom_pulse(current, LTL_PAGEFAULT, true); 42 } 43 44 static int enable_pagefault(void) 45 { 46 int retval; 47 48 retval = ltl_monitor_init(); 49 if (retval) 50 return retval; 51 52 rv_attach_trace_probe("rtapp_pagefault", page_fault_kernel, handle_page_fault); 53 rv_attach_trace_probe("rtapp_pagefault", page_fault_user, handle_page_fault); 54 55 return 0; 56 } 57 58 static void disable_pagefault(void) 59 { 60 rv_detach_trace_probe("rtapp_pagefault", page_fault_kernel, handle_page_fault); 61 rv_detach_trace_probe("rtapp_pagefault", page_fault_user, handle_page_fault); 62 63 ltl_monitor_destroy(); 64 } 65 66 static struct rv_monitor rv_pagefault = { 67 .name = "pagefault", 68 .description = "Monitor that RT tasks do not raise page faults", 69 .enable = enable_pagefault, 70 .disable = disable_pagefault, 71 }; 72 73 static int __init register_pagefault(void) 74 { 75 return rv_register_monitor(&rv_pagefault, &rv_rtapp); 76 } 77 78 static void __exit unregister_pagefault(void) 79 { 80 rv_unregister_monitor(&rv_pagefault); 81 } 82 83 module_init(register_pagefault); 84 module_exit(unregister_pagefault); 85 86 MODULE_LICENSE("GPL"); 87 MODULE_AUTHOR("Nam Cao <namcao@linutronix.de>"); 88 MODULE_DESCRIPTION("pagefault: Monitor that RT tasks do not raise page faults"); 89