20template<
typename DERIVED,
typename Dbg>
24 DERIVED *rm() {
return static_cast<DERIVED*
>(
this); }
25 DERIVED
const *rm()
const {
return static_cast<DERIVED
const *
>(
this); }
33 unsigned long size, Rm::Flags flags,
34 L4::Ipc::Snd_fpage ds_cap, L4Re::Rm::Offset offs,
36 L4::Ipc::String<> name, L4Re::Rm::Offset backing_offset)
38 typename DERIVED::Dataspace ds;
40 constexpr auto Known_flags =
49 if (flags & ~Known_flags)
54 if (
l4_ret_t r = rm()->validate_ds(ds_cap, flags.region_flags(), &ds))
61 constexpr unsigned Max_align =
sizeof(
l4_addr_t) * 8 - 1;
63 || align > Max_align))
68 if (size == 0 || start + size - 1 < start)
71 Rm::Region_flags r_flags = flags.region_flags();
72 Rm::Attach_flags a_flags = flags.attach_flags();
74 typename DERIVED::Region_handler handler(ds, client_cap_idx, offs, r_flags);
75 if (
int err = handler.init(rm(), size); err < 0)
78 start =
l4_addr_t(rm()->attach(
reinterpret_cast<void*
>(start), size,
79 handler, a_flags, align,
82 name.length ? name.length - 1 : 0,
97 if (!rm()->detach_area(start))
107 L4Re::Rm::Flags &flags, L4Re::Rm::Offset &offset,
110 if (!DERIVED::Have_find)
116 Rm::Flags flag_area { 0 };
118 typename DERIVED::Node r = rm()->find(Region(addr, addr + size -1));
121 r = rm()->area_find(Region(addr, addr + size - 1));
127 addr = r->first.start();
128 size = r->first.end() + 1 - addr;
130 flags = r->second.flags() | flag_area;
131 offset = r->second.offset();
132 m = r->second.client_cap_idx();
140 unsigned long size,
unsigned flags,
148 if (flags & ~Known_flags)
156 if (size == 0 || aligned_addr + size - 1 < aligned_addr)
160 typename DERIVED::Region_handler h;
161 int err = rm()->detach(
reinterpret_cast<void*
>(aligned_addr), size, flags,
171 mem_cap = h.client_cap_idx();
179 L4Re::Rm::Flags flags,
unsigned char align)
183 if (flags & ~Known_flags)
186 if (size == 0 || start + size - 1 < start)
189 constexpr unsigned Max_align =
sizeof(
l4_addr_t) * 8 - 1;
193 start = rm()->attach_area(start, size, flags, align);
204 L4::Ipc::Array_ref<L4Re::Rm::Region> ®ions)
206 typename DERIVED::Node r;
207 unsigned limit = regions.length;
210 while ((r = rm()->lower_bound(Region(addr))))
212 Rm::Region &x = regions.data[regions.length];
213 x.start = r->first.start();
214 x.end = r->first.end();
215 x.flags = r->second.flags();
217 if (++regions.length >= limit)
220 if (x.end >= rm()->max_addr())
225 return regions.length;
232 L4::Ipc::Array_ref<L4Re::Rm::Area> &areas)
234 typename DERIVED::Node r;
235 unsigned limit = areas.length;
238 while ((r = rm()->lower_bound_area(Region(addr))))
240 Rm::Area &x = areas.data[areas.length];
241 x.start = r->first.start();
242 x.end = r->first.end();
243 x.flags = r->second.flags();
245 if (++areas.length >= limit)
248 if (x.end >= rm()->max_addr())
263 return rm()->add_rescue_jump(pc_begin, pc_end, rescue_pc);
271 return rm()->remove_rescue_jump(pc);
278 L4Re::Rm::Region_flags rights, L4::Ipc::Snd_fpage &fp,
289 typename DERIVED::Region_handler::Map_result map_res;
290 l4_ret_t res = rm()->page_in(min_addr, max_addr, rights, &map_res);
292 pager_set_result(&fp, map_res);
298 static void pager_set_result(L4::Ipc::Opt<L4::Ipc::Snd_fpage> *fp,
299 L4::Ipc::Snd_fpage
const &f)
302 static void pager_set_result(L4::Ipc::Snd_fpage *fp,
303 L4::Ipc::Snd_fpage
const &f)
306 static void pager_set_result(L4::Ipc::Opt<L4::Ipc::Snd_fpage> *, ...)
315 L4::Ipc::Opt<L4::Ipc::Snd_fpage> &)
322 L4::Ipc::Opt<L4::Ipc::Snd_fpage> &fp)
324 Dbg(Dbg::Server).printf(
"page fault: %lx pc=%lx\n", addr, pc);
326 bool need_w = addr & 2;
327 bool need_x = addr & 4;
329 typename DERIVED::Node n = rm()->find(addr);
333 Dbg(Dbg::Warn,
"rm").printf(
"unhandled %s page fault at 0x%lx pc=0x%lx\n",
335 need_x ?
"instruction" :
"read", addr, pc);
342 Dbg(Dbg::Warn,
"rm").printf(
"write page fault in readonly region at 0x%lx pc=0x%lx\n",
350 Dbg(Dbg::Warn,
"rm").printf(
"instruction page fault in non-exec region at 0x%lx pc=0x%lx\n",
361 Dbg(Dbg::Warn,
"rm").printf(
"page fault handling in kernel-memory provided region or reserved region at 0x%lx pc=0x%lx\n",
367 typename DERIVED::Region_handler::Map_result map_res;
368 if (
int err = n->second.map(addr, n->first, need_w, &map_res))
370 Dbg(Dbg::Warn,
"rm").printf(
"mapping for page fault failed with error %d at 0x%lx pc=0x%lx\n",
376 pager_set_result(&fp, map_res);
380 long op_get_info(L4Re::Rm::Rights,
l4_addr_t addr,
381 L4::Ipc::String<char> &name, L4Re::Rm::Offset &backing_offset)
383#ifdef CONFIG_L4RE_REGION_INFO
384 typename DERIVED::Node r = rm()->find(Region(addr));
387 backing_offset = r->first.backing_offset();
389 char const *src = r->first.name();
390 unsigned src_len = r->first.name_len();
391 for (i = 0; i < src_len && i < name.length - 1; ++i)
392 name.data[i] = src[i];
399 (void)backing_offset;
l4_ret_t(* page_in_fn)(l4_addr_t min_addr, l4_addr_t max_addr, Region_flags rights)
In-thread eager paging function.
@ Detach_overlap
Do an unmap of all overlapping regions.
@ Detach_exact
Do an unmap of the exact region given.
unsigned long l4_umword_t
Unsigned machine word.
unsigned long l4_addr_t
Address type.
unsigned long l4_cap_idx_t
Capability selector type.
#define L4_INVALID_CAP
Invalid capability selector; see l4_cap_idx_t.
@ L4_ENOENT
No such entity.
@ L4_EACCESS
Permission denied.
@ L4_EINVAL
Invalid argument.
@ L4_ENODEV
No such thing.
@ L4_EADDRNOTAVAIL
Address not available.
l4_addr_t l4_trunc_page(l4_addr_t address) L4_NOTHROW
Round an address down to the next lower page boundary.
l4_addr_t l4_round_page(l4_addr_t address) L4_NOTHROW
Round address up to the next page.
#define L4_PAGESHIFT
Size of a page, log2-based.
@ L4_INVALID_ADDR
Invalid address.
Common L4 ABI Data Types.
l4_int16_t l4_ret_t
Return value of an IPC call as well as an RPC call.
Documentation of the L4 Runtime Environment utility functionality in C++.
@ Private
Attach the dataspace privately with copy-on-write semantics.
@ Reserved
Region is reserved (blocked).
@ Pager
Region has a pager.
@ RWX
Readable, writable and executable region.
@ Anonymous
Attach anonymous memory in the region.
@ Caching_mask
Mask of all Rm cache bits.
@ Kernel
Kernel-provided memory (KUMEM).
@ Search_addr
Search for a suitable address range.
@ No_eager_map
Prevent eager mapping of the attached data space.
@ Eager_map
Eagerly map the attached data space in.
@ In_area
Search only in area, or map into area.