1.1 --- a/libexec/include/exec/external_pager.h Mon Mar 06 18:30:22 2023 +0100
1.2 +++ b/libexec/include/exec/external_pager.h Mon Mar 06 19:12:48 2023 +0100
1.3 @@ -23,7 +23,9 @@
1.4
1.5 #include <vector>
1.6
1.7 +#include <exec/elf.h>
1.8 #include <exec/pager.h>
1.9 +#include <exec/segment.h>
1.10 #include <fsserver/notification.h>
1.11 #include <fsserver/resource.h>
1.12
1.13 @@ -38,9 +40,20 @@
1.14 public NotificationSupport, public Resource
1.15 {
1.16 protected:
1.17 - l4_cap_idx_t _task, _mapped_task, _parent, _mapped_parent, _pager, _mapped_pager, _ipc_gate;
1.18 +
1.19 + /* Resources associated with the created process. */
1.20 +
1.21 + l4_cap_idx_t _task = L4_INVALID_CAP, _mapped_task = L4_INVALID_CAP,
1.22 + _parent = L4_INVALID_CAP, _mapped_parent = L4_INVALID_CAP,
1.23 + _pager = L4_INVALID_CAP, _mapped_pager = L4_INVALID_CAP,
1.24 + _ipc_gate = L4_INVALID_CAP;
1.25 std::vector<l4_cap_idx_t> _threads, _mapped_threads;
1.26
1.27 + /* Resources supporting the internal pager. */
1.28 +
1.29 + ExplicitSegment *_rm_stack = NULL;
1.30 + Payload *_rm_payload = NULL;
1.31 +
1.32 public:
1.33 explicit ExternalPager(address_t start = 0, address_t end = 0);
1.34
1.35 @@ -59,6 +72,11 @@
1.36 virtual void set_parent(l4_cap_idx_t cap, l4_cap_idx_t mapped_cap);
1.37 virtual void set_task(l4_cap_idx_t cap, l4_cap_idx_t mapped_cap);
1.38
1.39 + /* Internal pager resource management. */
1.40 +
1.41 + virtual void set_payload(Payload *payload);
1.42 + virtual void set_stack(ExplicitSegment *stack);
1.43 +
1.44 /* Resource methods. */
1.45
1.46 virtual void close();
2.1 --- a/libexec/include/exec/pager.h Mon Mar 06 18:30:22 2023 +0100
2.2 +++ b/libexec/include/exec/pager.h Mon Mar 06 19:12:48 2023 +0100
2.3 @@ -1,7 +1,7 @@
2.4 /*
2.5 * Common system pager functionality.
2.6 *
2.7 - * Copyright (C) 2022 Paul Boddie <paul@boddie.org.uk>
2.8 + * Copyright (C) 2022, 2023 Paul Boddie <paul@boddie.org.uk>
2.9 *
2.10 * This program is free software; you can redistribute it and/or
2.11 * modify it under the terms of the GNU General Public License as
2.12 @@ -56,6 +56,8 @@
2.13
2.14 virtual void add(MappedRegion ®ion);
2.15
2.16 + virtual void remove(MappedRegion ®ion);
2.17 +
2.18 /* Notification methods. */
2.19
2.20 virtual long exception(l4_exc_regs_t regs,
3.1 --- a/libexec/include/exec/segment.h Mon Mar 06 18:30:22 2023 +0100
3.2 +++ b/libexec/include/exec/segment.h Mon Mar 06 19:12:48 2023 +0100
3.3 @@ -99,6 +99,8 @@
3.4
3.5
3.6
3.7 +/* An explicitly created segment independent of any particular payload. */
3.8 +
3.9 class ExplicitSegment : public Segment
3.10 {
3.11 protected:
4.1 --- a/libexec/lib/src/external_pager.cc Mon Mar 06 18:30:22 2023 +0100
4.2 +++ b/libexec/lib/src/external_pager.cc Mon Mar 06 19:12:48 2023 +0100
4.3 @@ -60,7 +60,22 @@
4.4 {
4.5 printf("Pager closing...\n");
4.6
4.7 - /* Unmap all regions. */
4.8 + /* Remove pager regions to avoid unmapping them twice. */
4.9 +
4.10 + remove(_rm_stack->region());
4.11 +
4.12 + for (unsigned int i = 0; i < _rm_payload->segments(); i++)
4.13 + remove(_rm_payload->segment(i)->region());
4.14 +
4.15 + /* Delete the pager resources. */
4.16 +
4.17 + if (_rm_payload != NULL)
4.18 + delete _rm_payload;
4.19 +
4.20 + if (_rm_stack != NULL)
4.21 + delete _rm_stack;
4.22 +
4.23 + /* Unmap all remaining regions. */
4.24
4.25 MappedRegions::iterator it;
4.26
4.27 @@ -117,6 +132,20 @@
4.28
4.29
4.30
4.31 +/* Manage pager resources. */
4.32 +
4.33 +void ExternalPager::set_payload(Payload *payload)
4.34 +{
4.35 + _rm_payload = payload;
4.36 +}
4.37 +
4.38 +void ExternalPager::set_stack(ExplicitSegment *stack)
4.39 +{
4.40 + _rm_stack = stack;
4.41 +}
4.42 +
4.43 +
4.44 +
4.45 /* Handle a general exception. */
4.46
4.47 long ExternalPager::exception(l4_exc_regs_t regs, l4_snd_fpage_t *region)
5.1 --- a/libexec/lib/src/pager.cc Mon Mar 06 18:30:22 2023 +0100
5.2 +++ b/libexec/lib/src/pager.cc Mon Mar 06 19:12:48 2023 +0100
5.3 @@ -1,7 +1,7 @@
5.4 /*
5.5 * Common system pager functionality.
5.6 *
5.7 - * Copyright (C) 2022 Paul Boddie <paul@boddie.org.uk>
5.8 + * Copyright (C) 2022, 2023 Paul Boddie <paul@boddie.org.uk>
5.9 *
5.10 * This program is free software; you can redistribute it and/or
5.11 * modify it under the terms of the GNU General Public License as
5.12 @@ -41,6 +41,8 @@
5.13 {
5.14 }
5.15
5.16 +
5.17 +
5.18 /* Add a region to the pager. */
5.19
5.20 void ExecPager::add(MappedRegion ®ion)
5.21 @@ -48,6 +50,15 @@
5.22 _regions[region.start] = region;
5.23 }
5.24
5.25 +/* Remove a region from the pager. */
5.26 +
5.27 +void ExecPager::remove(MappedRegion ®ion)
5.28 +{
5.29 + _regions.erase(region.start);
5.30 +}
5.31 +
5.32 +
5.33 +
5.34 /* Attach a region for provision when page faults occur. */
5.35
5.36 long ExecPager::find(address_t *start, address_t *size, map_flags_t flags,
6.1 --- a/libexec/lib/src/process_creating.cc Mon Mar 06 18:30:22 2023 +0100
6.2 +++ b/libexec/lib/src/process_creating.cc Mon Mar 06 19:12:48 2023 +0100
6.3 @@ -42,8 +42,6 @@
6.4 ProcessCreating::ProcessCreating(const char *rm_filename)
6.5 : _rm_filename(rm_filename)
6.6 {
6.7 - _rm_stack = new ExplicitSegment(Utcb_area_start - initial_stack_size, initial_stack_size, L4_FPAGE_RW);
6.8 - _program_stack = new ExplicitSegment(Utcb_area_start - initial_stack_size * 2, initial_stack_size, L4_FPAGE_RW);
6.9 }
6.10
6.11 /* Initialise the memory segments of the region mapper. These are mapped into
6.12 @@ -57,6 +55,7 @@
6.13 if (err)
6.14 return err;
6.15
6.16 + _rm_stack = new ExplicitSegment(Utcb_area_start - initial_stack_size, initial_stack_size, L4_FPAGE_RW);
6.17 return _rm_stack->allocate(true);
6.18 }
6.19
6.20 @@ -71,6 +70,7 @@
6.21 if (err)
6.22 return err;
6.23
6.24 + _program_stack = new ExplicitSegment(Utcb_area_start - initial_stack_size * 2, initial_stack_size, L4_FPAGE_RW);
6.25 return _program_stack->allocate(true);
6.26 }
6.27
6.28 @@ -94,6 +94,8 @@
6.29 /* Include the region mapper's stack region. */
6.30
6.31 _exec_pager->add(_rm_stack->region());
6.32 + _exec_pager->set_payload(_rm_payload);
6.33 + _exec_pager->set_stack(_rm_stack);
6.34
6.35 /* Start the pager in a separate thread. */
6.36