1.1 --- a/libexec/lib/src/process_creating.cc Thu Mar 23 15:42:39 2023 +0100
1.2 +++ b/libexec/lib/src/process_creating.cc Fri Mar 24 00:46:26 2023 +0100
1.3 @@ -111,9 +111,26 @@
1.4 return L4_EOK;
1.5 }
1.6
1.7 +/* Initialise a resource to receive signals from the process. */
1.8 +
1.9 +long ProcessCreating::init_process_monitor(l4_cap_idx_t *monitor)
1.10 +{
1.11 + _monitor = new ProcessMonitor;
1.12 +
1.13 + /* Start the monitor in a separate thread. */
1.14 +
1.15 + long err = ResourceServer(_monitor).start_thread(monitor);
1.16 +
1.17 + if (err)
1.18 + return err;
1.19 +
1.20 + _exec_pager->set_monitor(_monitor);
1.21 + return L4_EOK;
1.22 +}
1.23 +
1.24 /* Configure the environment for the task. */
1.25
1.26 -long ProcessCreating::configure_task(l4_cap_idx_t pager)
1.27 +long ProcessCreating::configure_task()
1.28 {
1.29 l4_cap_idx_t task, mapped_task;
1.30 long err = _process.configure_task(&task, &mapped_task);
1.31 @@ -121,51 +138,32 @@
1.32 if (err)
1.33 return err;
1.34
1.35 - /* Record the task details in the pager for eventual resource deallocation. */
1.36 + /* Record the task details elsewhere for eventual resource deallocation. */
1.37
1.38 _exec_pager->set_task(task, mapped_task);
1.39 -
1.40 - /* Note the pager as the parent of the new task, recording its capability
1.41 - details in the new task. */
1.42 -
1.43 - l4_cap_idx_t mapped_parent;
1.44 - err = _process.set_parent(pager, &mapped_parent);
1.45 -
1.46 - if (err)
1.47 - return err;
1.48 -
1.49 - _exec_pager->set_parent(pager, mapped_parent);
1.50 + _monitor->set_task(task, mapped_task);
1.51 return L4_EOK;
1.52 }
1.53
1.54 -/* Create an unbound IPC gate for the region mapper and allocate it in the
1.55 - created process. */
1.56 +/* Create an unbound IPC gate for the internal pager/region mapper and allocate
1.57 + it in the created process. */
1.58
1.59 -long ProcessCreating::create_ipc_gate()
1.60 +long ProcessCreating::allocate_internal_pager()
1.61 {
1.62 - _ipc_gate_cap = _process.allocate_cap();
1.63 - _ipc_gate = ipc_cap_alloc();
1.64 + _mapped_internal_pager = _process.allocate_cap();
1.65 + _internal_pager = ipc_cap_alloc();
1.66
1.67 - if (l4_is_invalid_cap(_ipc_gate))
1.68 + if (l4_is_invalid_cap(_internal_pager))
1.69 return -L4_ENOMEM;
1.70
1.71 - long err = l4_error(l4_factory_create_gate(l4re_env()->factory, _ipc_gate, L4_INVALID_CAP, 0));
1.72 -
1.73 - if (err)
1.74 - return err;
1.75 -
1.76 - /* The gate is retained because even after being mapped to the new task,
1.77 - releasing it will cause it to be deallocated. */
1.78 -
1.79 - _exec_pager->set_gate(_ipc_gate);
1.80 - return L4_EOK;
1.81 + return l4_error(l4_factory_create_gate(l4re_env()->factory, _internal_pager, L4_INVALID_CAP, 0));
1.82 }
1.83
1.84 /* Initialise and assign a region in a list to the created process. */
1.85
1.86 void ProcessCreating::init_region(struct exec_region *regions,
1.87 - struct ipc_mapped_cap *mapped_caps,
1.88 - struct exec_region &r, unsigned int &index)
1.89 + struct ipc_mapped_cap *mapped_caps,
1.90 + struct exec_region &r, unsigned int &index)
1.91 {
1.92 l4_cap_idx_t mapped_cap = _process.allocate_cap();
1.93
1.94 @@ -217,9 +215,11 @@
1.95
1.96 rm_regions[rm_index] = (struct exec_region) {0, 0, 0, L4_INVALID_CAP};
1.97
1.98 - /* Introduce the server capability and terminate the capability array. */
1.99 + /* Introduce the internal pager capability and terminate the capability array. */
1.100
1.101 - rm_mapped_caps[rm_index++] = (struct ipc_mapped_cap) {_ipc_gate_cap, _ipc_gate, L4_CAP_FPAGE_RWS, L4_FPAGE_C_OBJ_RIGHTS};
1.102 + rm_mapped_caps[rm_index++] = (struct ipc_mapped_cap) {_mapped_internal_pager,
1.103 + _internal_pager, L4_CAP_FPAGE_RWS,
1.104 + L4_FPAGE_C_OBJ_RIGHTS};
1.105 rm_mapped_caps[rm_index] = (struct ipc_mapped_cap) {0, L4_INVALID_CAP, 0, 0};
1.106
1.107 /* Map these additional capabilities. */
1.108 @@ -234,7 +234,7 @@
1.109 mapping the capability and encoded in the entry below. */
1.110
1.111 l4re_env_cap_entry_t rm_init_caps[] = {
1.112 - l4re_env_cap_entry_t(ENV_INTERNAL_PAGER_NAME, _ipc_gate_cap, L4_CAP_FPAGE_RWS),
1.113 + l4re_env_cap_entry_t(ENV_INTERNAL_PAGER_NAME, _mapped_internal_pager, L4_CAP_FPAGE_RWS),
1.114 l4re_env_cap_entry_t()
1.115 };
1.116
1.117 @@ -246,13 +246,23 @@
1.118 exception handler plus region mapper). */
1.119
1.120 l4_cap_idx_t mapped_pager = L4_INVALID_CAP;
1.121 - err = _process.configure_thread(pager, &mapped_pager);
1.122 + err = _process.set_pager(pager, &mapped_pager);
1.123
1.124 if (err)
1.125 return err;
1.126
1.127 _exec_pager->set_pager(pager, mapped_pager);
1.128
1.129 + /* Note the pager as the parent of the new task, recording its capability
1.130 + details in the new task. */
1.131 +
1.132 + err = _process.set_parent(pager, &mapped_pager);
1.133 +
1.134 + if (err)
1.135 + return err;
1.136 +
1.137 + _exec_pager->set_parent(pager, mapped_pager);
1.138 +
1.139 /* Populate a thread stack with argument and environment details for the
1.140 region mapper, plus the initial server capability and region details. */
1.141
1.142 @@ -271,14 +281,14 @@
1.143 if (err)
1.144 return err;
1.145
1.146 - _exec_pager->add_thread(thread, mapped_thread);
1.147 + _exec_pager->set_thread(thread, mapped_thread);
1.148 return L4_EOK;
1.149 }
1.150
1.151 /* Configure a thread for a program, populate its stack, and start the
1.152 thread. */
1.153
1.154 -long ProcessCreating::start_program(int argc, const char *argv[])
1.155 +long ProcessCreating::start_program(l4_cap_idx_t monitor, int argc, const char *argv[])
1.156 {
1.157 /* NOTE: Environment vector is currently not defined. */
1.158
1.159 @@ -287,12 +297,25 @@
1.160 /* Configure the environment for the thread, specifying the pager (and
1.161 exception handler plus region mapper). */
1.162
1.163 - l4_cap_idx_t mapped_pager = _ipc_gate_cap;
1.164 - long err = _process.configure_thread(_ipc_gate, &mapped_pager);
1.165 + l4_cap_idx_t mapped_pager = _mapped_internal_pager;
1.166 + long err = _process.set_pager(_internal_pager, &mapped_pager);
1.167
1.168 if (err)
1.169 return err;
1.170
1.171 + _monitor->set_pager(_internal_pager, _mapped_internal_pager);
1.172 +
1.173 + /* Note the monitor as the parent of the new task, recording its capability
1.174 + details in the new task. */
1.175 +
1.176 + l4_cap_idx_t mapped_parent = L4_INVALID_CAP;
1.177 + err = _process.set_parent(monitor, &mapped_parent);
1.178 +
1.179 + if (err)
1.180 + return err;
1.181 +
1.182 + _monitor->set_parent(monitor, mapped_parent);
1.183 +
1.184 /* Obtain the filesystem capability for exporting to the task. */
1.185
1.186 l4_cap_idx_t fsserver_cap = _process.allocate_cap();
1.187 @@ -338,13 +361,13 @@
1.188 if (err)
1.189 return err;
1.190
1.191 - _exec_pager->add_thread(thread, mapped_thread);
1.192 + _monitor->set_thread(thread, mapped_thread);
1.193 return L4_EOK;
1.194 }
1.195
1.196 /* Start a new process for the payload indicated by the first of the given
1.197 - program arguments, returning a reference to the pager as an object for
1.198 - interacting with the process. */
1.199 + program arguments, returning a reference to the process monitor as an object
1.200 + for interacting with the process. */
1.201
1.202 long ProcessCreating::start(int argc, const char *argv[], l4_cap_idx_t *process)
1.203 {
1.204 @@ -368,6 +391,8 @@
1.205
1.206 /* Initialise the different elements of the process. */
1.207
1.208 + l4_cap_idx_t pager;
1.209 +
1.210 err = init_region_mapper();
1.211 if (err)
1.212 return err;
1.213 @@ -376,23 +401,27 @@
1.214 if (err)
1.215 return err;
1.216
1.217 - err = init_external_pager(process);
1.218 + err = init_external_pager(&pager);
1.219 if (err)
1.220 return err;
1.221
1.222 - err = configure_task(*process);
1.223 + err = init_process_monitor(process);
1.224 if (err)
1.225 return err;
1.226
1.227 - err = create_ipc_gate();
1.228 + err = configure_task();
1.229 if (err)
1.230 return err;
1.231
1.232 - err = start_region_mapper(*process);
1.233 + err = allocate_internal_pager();
1.234 if (err)
1.235 return err;
1.236
1.237 - err = start_program(argc, argv);
1.238 + err = start_region_mapper(pager);
1.239 + if (err)
1.240 + return err;
1.241 +
1.242 + err = start_program(*process, argc, argv);
1.243 if (err)
1.244 return err;
1.245