L4Re Operating System Framework
Interface and Usage Documentation
Loading...
Searching...
No Matches
rm_impl.h
Go to the documentation of this file.
1
5/*
6 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
7 * Alexander Warg <warg@os.inf.tu-dresden.de>
8 * economic rights: Technische Universität Dresden (Germany)
9 *
10 * License: see LICENSE.spdx (in this directory or the directories above)
11 */
12
13#include <l4/bid_config.h>
14#include <l4/re/rm>
15#include <l4/re/dataspace>
16
17#include <l4/sys/cxx/consts>
18#include <l4/sys/cxx/ipc_client>
19
20#include <l4/sys/task>
21#include <l4/sys/err.h>
22
33
34namespace L4Re
35{
36
38Rm::attach(l4_addr_t *start, unsigned long size, Rm::Flags flags,
39 L4::Ipc::Cap<Dataspace> mem, Rm::Offset offs,
40 unsigned char align, L4::Cap<L4::Task> const task,
41 char const *name, Rm::Offset backing_offset) const noexcept
42{
43 if ((flags & F::Rights_mask) == Flags(0)
44 || (flags & (F::Reserved | F::Kernel)))
46
47 char const n = '\0';
48 l4_ret_t e = attach_t::call(c(), start, size, flags, mem, offs, align,
49 mem.cap().cap(), name ? name : &n, backing_offset);
50 if (e < 0)
51 return e;
52
53#ifdef CONFIG_MMU
54 if ((flags & (F::Eager_map | F::No_eager_map)) == F::Eager_map)
55#else
56 if (!(flags & F::No_eager_map) && mem.is_valid())
57#endif
58 page_in(*start, size, flags.region_flags() & F::RWX, task);
59
60 return 0;
61}
62
64Rm::detach(l4_addr_t start, unsigned long size, L4::Cap<Dataspace> *mem,
65 L4::Cap<L4::Task> task, unsigned flags) const noexcept
66{
67 l4_addr_t rstart = 0, rsize = 0;
69 l4_ret_t e = detach_t::call(c(), start, size, flags, rstart, rsize, mem_cap);
70 if (L4_UNLIKELY(e < 0))
71 return e;
72
73 if (mem)
74 *mem = L4::Cap<L4Re::Dataspace>(mem_cap);
75
76 if (e & Unmapped_range)
77 // Hide Unmapped_range bit. Some callers incorrectly treat anything except
78 // zero as failure.
79 return e & ~Unmapped_range;
80
81 if (!task.is_valid())
82 return e;
83
84 rsize = l4_round_page(rsize);
85 unsigned order = L4_LOG2_PAGESIZE;
86 unsigned long sz = (1UL << order);
87 for (unsigned long p = rstart; rsize; p += sz, rsize -= sz)
88 {
89 while (sz > rsize)
90 {
91 --order;
92 sz >>= 1;
93 }
94
95 for (;;)
96 {
97 unsigned long m = sz << 1;
98 if (m > rsize)
99 break;
100
101 if (p & (m - 1))
102 break;
103
104 ++order;
105 sz <<= 1;
106 }
107
108 task->unmap(l4_fpage(p, order, L4_FPAGE_RWX),
110 }
111
112 return e;
113}
114
116Rm::page_in(l4_addr_t start, unsigned long size, Rm::Region_flags rights,
117 L4::Cap<L4::Task> dst) const noexcept
118{
119 if (rights & ~F::RWX)
120 return -L4_EINVAL;
121
122 if (size == 0 || !(rights & F::R))
123 return 0;
124
125 if (start + size - 1 < start)
126 return -L4_EINVAL;
127
128 auto rwin = L4::Ipc::Rcv_fpage::mem(0, L4_WHOLE_ADDRESS_SPACE, 0, dst);
129
130 l4_addr_t min_addr = L4::trunc_page(start);
131 l4_addr_t max_addr = L4::round_page(start + size) - 1;
132
133 while (min_addr < max_addr)
134 {
136 page_in_fn helper = nullptr;
137 if (l4_ret_t err = page_in_t::call(c(), min_addr, max_addr, rights, rwin,
138 fp, &helper);
139 err < 0)
140 return err;
141
142 // ITAS, which is in the same task, will let us jump to the handler. That
143 // way, the thread itself will do the work. The helper is supposed to
144 // handle the full range...
145 if (helper)
146 {
147 // The ITAS only pages the current task. Trying to page for a foreign
148 // task is not supported.
149 if (dst)
150 return -L4_EINVAL;
151
152 return helper(min_addr, max_addr, rights);
153 }
154
155 min_addr += l4_addr_t{1} << fp.rcv_order();
156 }
157
158 return 0;
159}
160
161}
l4_ret_t get_regions(l4_addr_t start, L4::Ipc::Array_ref< Region > &regions)
Return the list of regions whose starting addresses are higher or equal to start in the address space...
l4_ret_t add_rescue_jump(l4_addr_t pc_begin, l4_addr_t pc_end, l4_addr_t rescue_pc)
Register a rescue jump for a range of program counters.
l4_ret_t free_area(l4_addr_t addr)
Free an area from the region map.
l4_ret_t page_in(l4_addr_t start, unsigned long size, Region_flags rights, L4::Cap< L4::Task > dst=L4::Cap< L4::Task >::Invalid) const noexcept
Allocate and map pages for the given region.
Definition rm_impl.h:116
l4_ret_t reserve_area(l4_addr_t *start, unsigned long size, Flags flags=Flags(0), unsigned char align=L4_PAGESHIFT) const noexcept
Reserve the given area in the region map.
Definition rm:275
long get_areas(l4_addr_t start, L4::Ipc::Array_ref< Area > &areas)
Return the list of areas whose starting addresses are higher or equal to start in the address space m...
l4_ret_t(* page_in_fn)(l4_addr_t min_addr, l4_addr_t max_addr, Region_flags rights)
In-thread eager paging function.
Definition rm:847
l4_ret_t find(l4_addr_t *addr, unsigned long *size, Offset *offset, L4Re::Rm::Flags *flags, L4::Cap< Dataspace > *m) noexcept
Find a region given an address and size.
Definition rm:671
l4_ret_t detach(l4_addr_t addr, L4::Cap< Dataspace > *mem, L4::Cap< L4::Task > const &task=This_task) const noexcept
Detach and unmap a region from the address space.
Definition rm:886
l4_ret_t get_info(l4_addr_t addr, L4::Ipc::String< char > &name, Offset &backing_offset)
Return auxiliary information of a region.
l4_ret_t remove_rescue_jump(l4_addr_t pc)
Remove a previously registered rescue jump.
l4_ret_t attach(l4_addr_t *start, unsigned long size, Flags flags, L4::Ipc::Cap< Dataspace > mem, Offset offs=0, unsigned char align=L4_PAGESHIFT, L4::Cap< L4::Task > const task=L4::Cap< L4::Task >::Invalid, char const *name=nullptr, Offset backing_offset=0) const noexcept
Attach a data space to a region.
Definition rm_impl.h:38
C++ interface for capabilities.
Definition capability.h:249
Capability type for RPC interfaces (see L4::Cap<T>).
Definition ipc_types:725
static Rcv_fpage mem(l4_addr_t base, int order, l4_addr_t snd_base=0, L4::Cap< void > rcv_task=L4::Cap< void >::Invalid) noexcept
Construct a receive item for the memory space.
Definition ipc_types:581
Send item or return item.
Definition ipc_types:300
unsigned rcv_order() const noexcept
(Defined for return items only.) Get logâ‚‚ size.
Definition ipc_types:441
Dataspace interface.
Error codes.
unsigned long l4_addr_t
Address type.
Definition l4int.h:34
unsigned long l4_cap_idx_t
Capability selector type.
Definition types.h:372
#define L4_INVALID_CAP
Invalid capability selector; see l4_cap_idx_t.
Definition consts.h:165
@ L4_EINVAL
Invalid argument.
Definition err.h:47
L4_CONSTEXPR l4_fpage_t l4_fpage(l4_addr_t address, unsigned int order, unsigned char rights) L4_NOTHROW
Create a memory flexpage.
Definition __l4_fpage.h:719
@ L4_FPAGE_RWX
Read-write-execute flexpage.
Definition __l4_fpage.h:125
@ L4_WHOLE_ADDRESS_SPACE
Whole address space size.
Definition __l4_fpage.h:92
l4_addr_t l4_round_page(l4_addr_t address) L4_NOTHROW
Round address up to the next page.
Definition consts.h:484
#define L4_LOG2_PAGESIZE
Number of bits used for page offset.
Definition consts.h:420
#define L4_UNLIKELY(x)
Expression is unlikely to execute.
Definition compiler.h:295
#define L4_RPC_DEF(name)
Generate the definition of an RPC stub.
Definition ipc_client:32
l4_int16_t l4_ret_t
Return value of an IPC call as well as an RPC call.
Definition types.h:29
L4Re C++ Interfaces.
Definition cmd_control:14
@ L4_FP_ALL_SPACES
Flag to tell the unmap operation to revoke permissions from all child mappings including the mapping ...
Definition consts.h:194
Region mapper interface.
@ Rights_mask
Region rights.
Definition rm:133
@ Reserved
Region is reserved (blocked).
Definition rm:153
@ RWX
Readable, writable and executable region.
Definition rm:145
@ R
Readable region.
Definition rm:135
@ Kernel
Kernel-provided memory (KUMEM).
Definition rm:148
@ No_eager_map
Prevent eager mapping of the attached data space.
Definition rm:121
@ Eager_map
Eagerly map the attached data space in.
Definition rm:119
Common task related definitions.