aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2022-12-03 20:18:36 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2022-12-03 20:18:36 +0100
commit45afcc68979b700bdef1dc0e27ba79e0822b1c18 (patch)
treeeb095c4f47b97996618589d9b9c4859c1a124155
parent9518a5e29e6774fb66821140c916522abb985eaf (diff)
downloadgnumach-45afcc68979b700bdef1dc0e27ba79e0822b1c18.tar.gz
gnumach-45afcc68979b700bdef1dc0e27ba79e0822b1c18.tar.bz2
gnumach-45afcc68979b700bdef1dc0e27ba79e0822b1c18.zip
task: Add task_set_essential
Whenever a Hurd essential task crashes, startup just reboots the system since there's not much that can be done at that point. When we have a kernel debugger, however, we could at least get crashing information, so let's let Hurd's startup tell the kernel which tasks are essential, and trigger the debugger whenever they crash.
-rw-r--r--doc/mach.texi11
-rw-r--r--i386/i386/trap.c5
-rw-r--r--include/mach/gnumach.defs8
-rw-r--r--kern/task.c16
-rw-r--r--kern/task.h3
5 files changed, 40 insertions, 3 deletions
diff --git a/doc/mach.texi b/doc/mach.texi
index 4abafe1a..fecd097b 100644
--- a/doc/mach.texi
+++ b/doc/mach.texi
@@ -5100,6 +5100,17 @@ printed by the kernel.
The function returns @code{KERN_SUCCESS} if the call succeeded.
@end deftypefun
+@deftypefun kern_return_t task_set_essential (@w{task_t @var{target_task}}, @w{boolean_t @var{essential}})
+
+The function @code{task_set_essential} sets whether @var{target_task} is
+essential for the system, i.e. the system will completely crash and reboot if
+that task crashes. This means that when the debugger is enabled, it should be
+triggered on the crash, so as to get the opportunity to debug the issue instead
+of just rebooting.
+
+The function returns @code{KERN_SUCCESS} if the call succeeded.
+@end deftypefun
+
@node Task Execution
@subsection Task Execution
diff --git a/i386/i386/trap.c b/i386/i386/trap.c
index eef9432f..6e446ab0 100644
--- a/i386/i386/trap.c
+++ b/i386/i386/trap.c
@@ -565,11 +565,12 @@ int user_trap(struct i386_saved_state *regs)
}
#if MACH_TTD
- if (debug_all_traps_with_kttd && kttd_trap(type, regs->err, regs))
+ if ((debug_all_traps_with_kttd || thread->task->essential) &&
+ kttd_trap(type, regs->err, regs))
return 0;
#endif /* MACH_TTD */
#if MACH_KDB
- if (debug_all_traps_with_kdb &&
+ if ((debug_all_traps_with_kdb || thread->task->essential) &&
kdb_trap(type, regs->err, regs))
return 0;
#endif /* MACH_KDB */
diff --git a/include/mach/gnumach.defs b/include/mach/gnumach.defs
index 531b5d4d..05101a48 100644
--- a/include/mach/gnumach.defs
+++ b/include/mach/gnumach.defs
@@ -189,3 +189,11 @@ routine vm_allocate_contiguous(
pmin : rpc_phys_addr_t;
pmax : rpc_phys_addr_t;
palign : rpc_phys_addr_t);
+
+/*
+ * Set whether TASK is an essential task, i.e. the whole system will crash
+ * if this task crashes.
+ */
+simpleroutine task_set_essential(
+ task : task_t;
+ essential : boolean_t);
diff --git a/kern/task.c b/kern/task.c
index e91c192b..e9158c73 100644
--- a/kern/task.c
+++ b/kern/task.c
@@ -178,6 +178,7 @@ task_create_kernel(
new_task->may_assign = TRUE;
new_task->assign_active = FALSE;
+ new_task->essential = FALSE;
#if MACH_PCSAMPLE
new_task->pc_sample.buffer = 0;
@@ -1157,6 +1158,21 @@ task_set_name(
}
/*
+ * task_set_essential
+ *
+ * Set whether TASK is an essential task, i.e. the whole system will crash
+ * if this task crashes.
+ */
+kern_return_t
+task_set_essential(
+ task_t task,
+ boolean_t essential)
+{
+ task->essential = !!essential;
+ return KERN_SUCCESS;
+}
+
+/*
* task_collect_scan:
*
* Attempt to free resources owned by tasks.
diff --git a/kern/task.h b/kern/task.h
index 52eb8324..6251317c 100644
--- a/kern/task.h
+++ b/kern/task.h
@@ -64,7 +64,8 @@ struct task {
/* Flags */
unsigned int active:1, /* Task has not been terminated */
/* boolean_t */ may_assign:1, /* can assigned pset be changed? */
- assign_active:1; /* waiting for may_assign */
+ assign_active:1, /* waiting for may_assign */
+ essential:1; /* Is this task essential for the system? */
/* Miscellaneous */
vm_map_t map; /* Address space description */