L4Re Operating System Framework
Interface and Usage Documentation
Loading...
Searching...
No Matches
capability.h
1
2#pragma once
3
4#include <l4/sys/consts.h>
5#include <l4/sys/types.h>
6#include <l4/sys/task.h>
7
8namespace L4 {
9
10class Task;
11class Kobject;
12
13template< typename T > class L4_EXPORT Cap;
14
26{
27public:
30 {
35 };
36
44
49 l4_cap_idx_t cap() const noexcept { return _c; }
50
57 bool is_valid() const noexcept { return !(_c & L4_INVALID_CAP_BIT); }
58
62 int invalid_cap_error() const noexcept { return _c & ~L4_INVALID_CAP_BIT; }
63
64 explicit operator bool () const noexcept
65 { return !(_c & L4_INVALID_CAP_BIT); }
66
74 l4_fpage_t fpage(unsigned rights = L4_CAP_FPAGE_RWS) const noexcept
75 { return l4_obj_fpage(_c, 0, rights); }
76
87 l4_cap_idx_t base = L4_INVALID_CAP) const noexcept
88 {
89 if (base == L4_INVALID_CAP)
90 base = _c;
91 return l4_map_obj_control(base, grant);
92 }
93
94
98 bool operator == (Cap_base const &o) const noexcept
99 { return _c == o._c; }
100
104 bool operator != (Cap_base const &o) const noexcept
105 { return _c != o._c; }
106
120 inline l4_msgtag_t validate(l4_utcb_t *u = l4_utcb()) const noexcept;
121
136 inline l4_msgtag_t validate(Cap<Task> task,
137 l4_utcb_t *u = l4_utcb()) const noexcept;
138
142 void invalidate() noexcept { _c = L4_INVALID_CAP; }
143protected:
149 explicit Cap_base(l4_cap_idx_t c) noexcept : _c(c) {}
153 explicit Cap_base(Cap_type cap) noexcept : _c(cap) {}
154
160 explicit Cap_base(l4_default_caps_t cap) noexcept : _c(cap) {}
161
165 explicit Cap_base() noexcept {}
166
176 bool move(Cap_base const &src) const noexcept
177 {
178 if (!is_valid() || !src.is_valid())
179 return false;
180
181 l4_msgtag_t res
183 src.fpage(L4_CAP_FPAGE_RWSD),
185 return l4_error(res) >= 0;
186 }
187
195 bool copy(Cap_base const &src) const noexcept
196 {
197 if (!is_valid() || !src.is_valid())
198 return false;
199
201 src.fpage(L4_CAP_FPAGE_RWSD),
203 return l4_error(res) >= 0;
204 }
205
215 bool is_equal(Cap_base const &other) const noexcept
216 {
217 if (!is_valid())
218 return !other.is_valid();
219
220 if (other.is_valid())
221 return l4_task_cap_equal(L4_BASE_TASK_CAP, _c, other._c).label() > 0;
222 else
223 return false;
224 }
225
229};
230
231
247template< typename T >
248class L4_EXPORT Cap : public Cap_base
249{
250private:
251 friend class L4::Kobject;
252
264 explicit Cap(T const *p) noexcept
265 : Cap_base(reinterpret_cast<l4_cap_idx_t>(p)) {}
266
267public:
268
275 template< typename From >
276 static void check_convertible_from() noexcept
277 {
278 using To = T;
279 [[maybe_unused]] To* t = static_cast<From*>(nullptr);
280 }
281
288 template< typename From >
289 static void check_castable_from() noexcept
290 {
291 using To = T;
292 [[maybe_unused]] To *t = static_cast<To *>(static_cast<From *>(nullptr));
293 }
294
299 template< typename O >
300 Cap(Cap<O> const &o) noexcept : Cap_base(o.cap())
302
307 Cap(Cap_type cap) noexcept : Cap_base(cap) {}
308
314
319 explicit Cap(l4_cap_idx_t idx = L4_INVALID_CAP) noexcept : Cap_base(idx) {}
320
324 explicit Cap(No_init_type) noexcept {}
325
329 bool move(Cap const &src) const noexcept
330 { return Cap_base::move(src); }
331
335 bool copy(Cap const &src) const noexcept
336 { return Cap_base::copy(src); }
337
341 bool is_equal(Cap const &other) const noexcept
342 { return Cap_base::is_equal(other); }
343
347 T *operator -> () const noexcept
348 {
349 static_assert(sizeof(_c) <= sizeof(T*));
350 return reinterpret_cast<T*>(_c);
351 }
352};
353
354
365template<>
366class L4_EXPORT Cap<void> : public Cap_base
367{
368public:
369
370 explicit Cap(void const *p) noexcept
371 : Cap_base(reinterpret_cast<l4_cap_idx_t>(p)) {}
372
376 Cap(Cap_type cap) noexcept : Cap_base(cap) {}
377
382 Cap(l4_default_caps_t cap) noexcept : Cap_base(cap) {}
383
388 explicit Cap(l4_cap_idx_t idx = L4_INVALID_CAP) noexcept : Cap_base(idx) {}
389 explicit Cap(No_init_type) noexcept {}
390
391 template< typename From >
392 static void check_convertible_from() noexcept {}
393
394 template< typename From >
395 static void check_castable_from() noexcept {}
396
400 bool move(Cap const &src) const noexcept
401 { return Cap_base::move(src); }
402
406 bool copy(Cap const &src) const noexcept
407 { return Cap_base::copy(src); }
408
412 bool is_equal(Cap const &other) const noexcept
413 { return Cap_base::is_equal(other); }
414
415 template< typename T >
416 Cap(Cap<T> const &o) noexcept : Cap_base(o.cap()) {}
417};
418
435template< typename T, typename F >
436inline
437Cap<T> cap_cast(Cap<F> const &c) noexcept
438{
439 Cap<T>::template check_castable_from<F>();
440 return Cap<T>(c.cap());
441}
442
443// gracefully deal with L4::Kobject ambiguity
444template< typename T >
445inline
446Cap<T> cap_cast(Cap<L4::Kobject> const &c) noexcept
447{
448 return Cap<T>(c.cap());
449}
450
466template< typename T, typename F >
467inline
469{
470 return Cap<T>(c.cap());
471}
472
476class Reply_cap_idx
477{
478 l4_cap_idx_t _i;
479
480public:
481 constexpr explicit Reply_cap_idx() noexcept : _i(L4_INVALID_CAP) {}
482 constexpr explicit Reply_cap_idx(l4_cap_idx_t i) noexcept
483 : _i(i) {}
484
485 constexpr l4_cap_idx_t cap() const noexcept
486 { return _i; }
487
488 explicit constexpr operator l4_cap_idx_t() const noexcept
489 { return _i; }
490
491 explicit constexpr operator bool() const noexcept
492 { return !(_i & L4_INVALID_CAP_BIT); }
493
494 constexpr bool operator==(Reply_cap_idx o) const noexcept
495 { return _i == o._i; }
496
497 constexpr bool operator!=(Reply_cap_idx o) const noexcept
498 { return _i != o._i; }
499};
500
501class Reply_cap;
502
506class Reply_cap_alloc
507{
508 friend class Reply_cap;
509
510public:
511 constexpr Reply_cap_alloc() = default;
512
513 // Attention: do *not* define a destructor! We must keep the class trivially
514 // destructible so that no global destructor is created for
515 // L4Re::Util::reply_cap_alloc.
516 // virtual ~Reply_cap_alloc() = default;
517
518 Reply_cap_alloc(Reply_cap_alloc const &) = delete;
519 Reply_cap_alloc &operator = (Reply_cap_alloc const &) = delete;
520
526 virtual Reply_cap alloc() noexcept = 0;
527
528protected:
536 virtual void free(Reply_cap_idx cap) noexcept = 0;
537};
538
548{
549public:
551 constexpr Reply_cap() noexcept = default;
552
563 : _cap(cap), _alloc(alloc)
564 {}
565
573 { reset(); }
574
575 // not copyable
576 Reply_cap(Reply_cap const &) = delete;
577 Reply_cap &operator=(Reply_cap const &) = delete;
578
579 constexpr Reply_cap(Reply_cap &&o) noexcept
580 : _cap(o._cap), _alloc(o._alloc)
581 {
582 o._cap = Reply_cap_idx();
583 o._alloc = nullptr;
584 }
585
586 Reply_cap &operator=(Reply_cap &&o) noexcept
587 {
588 reset(o._cap, o._alloc);
589 o._cap = Reply_cap_idx();
590 o._alloc = nullptr;
591 return *this;
592 }
593
607 l4_ret_t reply(l4_msgtag_t tag, l4_utcb_t *utcb = l4_utcb()) noexcept
608 {
610 if (is_valid()) [[likely]]
611 {
612 err = l4_ipc_error(l4_ipc_reply(_cap.cap(), utcb, tag,
613 L4_IPC_BOTH_TIMEOUT_0), utcb);
614 _alloc->free(_cap);
615 _cap = Reply_cap_idx();
616 }
617
618 if (err) [[unlikely]]
619 return l4_ipc_to_errno(err);
620 else
621 return 0;
622 }
623
630 constexpr Reply_cap_idx get() const noexcept
631 { return _cap; }
632
633 constexpr bool is_valid() const noexcept
634 { return static_cast<bool>(_cap); }
635
636 explicit constexpr operator bool () const noexcept
637 { return is_valid(); }
638
639 constexpr bool operator==(Reply_cap const &o) const noexcept
640 { return _cap == o._cap; }
641
642 constexpr bool operator==(Reply_cap_idx o) const noexcept
643 { return _cap == o; }
644
645 constexpr bool operator!=(Reply_cap const &o) const noexcept
646 { return _cap != o._cap; }
647
648 constexpr bool operator!=(Reply_cap_idx o) const noexcept
649 { return _cap != o; }
650
658 Reply_cap_alloc *alloc = nullptr) noexcept
659 {
660 if (is_valid()) [[unlikely]]
661 {
662 // If the reply cap is still valid, reply to the caller that we've
663 // dropped the reply. Should not happen in a well behaved server.
664 auto tag = l4_msgtag(-L4_EDROPREPLY, 0, 0, 0);
665 l4_ipc_reply(_cap.cap(), l4_utcb(), tag, L4_IPC_BOTH_TIMEOUT_0);
666 _alloc->free(_cap);
667 }
668
669 _cap = cap;
670 _alloc = alloc;
671 }
672
673private:
675 Reply_cap_alloc *_alloc = nullptr;
676};
677
678}
bool copy(Cap_base const &src) const noexcept
Copy a capability.
Definition capability.h:195
Cap_base(l4_default_caps_t cap) noexcept
Initialize capability with one of the default capabilities.
Definition capability.h:160
void invalidate() noexcept
Set this capability to invalid (L4_INVALID_CAP).
Definition capability.h:142
Cap_base(Cap_type cap) noexcept
Constructor to create an invalid capability.
Definition capability.h:153
l4_fpage_t fpage(unsigned rights=L4_CAP_FPAGE_RWS) const noexcept
Return flexpage for the capability.
Definition capability.h:74
bool move(Cap_base const &src) const noexcept
Replace this capability with the contents of src.
Definition capability.h:176
l4_cap_idx_t _c
The C representation of a capability selector.
Definition capability.h:228
l4_cap_idx_t cap() const noexcept
Return capability selector.
Definition capability.h:49
bool is_valid() const noexcept
Test whether the capability is a valid capability index (i.e., not L4_INVALID_CAP).
Definition capability.h:57
Cap_type
Invalid capability type.
Definition capability.h:41
@ Invalid
Invalid capability selector.
Definition capability.h:42
int invalid_cap_error() const noexcept
Return the transported error code in an invalid capability index.
Definition capability.h:62
No_init_type
Special value for uninitialized capability objects.
Definition capability.h:30
@ No_init
Special value for constructing uninitialized Cap objects.
Definition capability.h:34
Cap_base(l4_cap_idx_t c) noexcept
Generate a capability from its C representation.
Definition capability.h:149
Cap_base() noexcept
Create an uninitialized instance.
Definition capability.h:165
l4_umword_t snd_base(unsigned grant=L4_MAP_ITEM_MAP, l4_cap_idx_t base=L4_INVALID_CAP) const noexcept
Return send base.
Definition capability.h:86
bool is_equal(Cap_base const &other) const noexcept
Test whether this capability points to the same object with the same permissions as other.
Definition capability.h:215
C++ interface for capabilities.
Definition capability.h:249
bool move(Cap const &src) const noexcept
Replace this capability with the contents of src.
Definition capability.h:329
Cap(l4_cap_idx_t idx=L4_INVALID_CAP) noexcept
Initialize capability, defaults to the invalid capability selector.
Definition capability.h:319
Cap(No_init_type) noexcept
Create an uninitialized cap selector.
Definition capability.h:324
Cap(Cap_type cap) noexcept
Constructor to create an invalid capability selector.
Definition capability.h:307
static void check_castable_from() noexcept
Perform the type conversion that needs to compile in order for a capability of type From te be castab...
Definition capability.h:289
bool is_equal(Cap const &other) const noexcept
Test whether this capability points to the same object with the same permissions as other.
Definition capability.h:341
Cap(l4_default_caps_t cap) noexcept
Initialize capability with one of the default capability selectors.
Definition capability.h:313
Cap(Cap< O > const &o) noexcept
Create a copy from o, supporting implicit type casting.
Definition capability.h:300
bool copy(Cap const &src) const noexcept
Copy a capability.
Definition capability.h:335
static void check_convertible_from() noexcept
Perform the type conversion that needs to compile in order for a capability of type From to be conver...
Definition capability.h:276
Base class for all kinds of kernel objects and remote objects, referenced by capabilities.
Definition kobject:37
Interface to a reply capability allocator.
Definition capability.h:507
virtual void free(Reply_cap_idx cap) noexcept=0
Free reply capability slot.
virtual Reply_cap alloc() noexcept=0
Allocate new reply capability slot.
Value class for a reply capability index.
Definition capability.h:477
An explicit reply capability.
Definition capability.h:548
l4_ret_t reply(l4_msgtag_t tag, l4_utcb_t *utcb=l4_utcb()) noexcept
Reply with this reply capability.
Definition capability.h:607
constexpr Reply_cap_idx get() const noexcept
Get reply capability index.
Definition capability.h:630
~Reply_cap()
Destroy reply capability.
Definition capability.h:572
void reset(Reply_cap_idx cap=Reply_cap_idx(), Reply_cap_alloc *alloc=nullptr) noexcept
Replace reply capability.
Definition capability.h:657
constexpr Reply_cap() noexcept=default
Construct an invalid reply capability.
C++ interface of the Task kernel object, see Task for the C interface.
Definition task:36
#define L4_FPAGE_C_OBJ_RIGHTS
All Object-type specific right bits.
Definition __l4_fpage.h:281
unsigned long l4_umword_t
Unsigned machine word.
Definition l4int.h:40
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_default_caps_t
Default capabilities setup for the initial tasks.
Definition consts.h:336
@ L4_BASE_TASK_CAP
Capability selector for the current task.
Definition consts.h:338
@ L4_EDROPREPLY
Server dropped reply capability.
Definition err.h:62
L4_CONSTEXPR l4_fpage_t l4_obj_fpage(l4_cap_idx_t obj, unsigned int order, unsigned char rights) L4_NOTHROW
Create a kernel-object flexpage.
Definition __l4_fpage.h:731
@ L4_CAP_FPAGE_RWSD
Full rights for capability flexpages.
Definition __l4_fpage.h:212
@ L4_CAP_FPAGE_RWS
Read, interface specific 'W', and 'S' rights for capability flexpages.
Definition __l4_fpage.h:206
l4_msgtag_t l4_ipc_reply(l4_cap_idx_t reply_cap, l4_utcb_t *utcb, l4_msgtag_t tag, l4_timeout_t timeout) L4_NOTHROW
Reply operation (uses a reply capability).
Definition ipc.h:605
l4_ret_t l4_error(l4_msgtag_t tag) L4_NOTHROW
Get IPC error code if any or message tag label otherwise for an IPC call.
Definition ipc.h:687
l4_umword_t l4_ipc_error(l4_msgtag_t tag, l4_utcb_t *utcb) L4_NOTHROW
Get the IPC error code for an IPC operation.
Definition ipc.h:670
@ L4_IPC_ENOT_EXISTENT
Non-existing destination or source.
Definition ipc.h:86
L4_CONSTEXPR l4_umword_t l4_map_obj_control(l4_umword_t spot, unsigned grant) L4_NOTHROW
Create the first word for a map item that is a send item for the object space.
Definition __l4_fpage.h:765
@ L4_MAP_ITEM_GRANT
Flag as grant instead of map operation.
Definition consts.h:256
@ L4_MAP_ITEM_MAP
Flag as usual map operation.
Definition consts.h:258
l4_msgtag_t l4_msgtag(long label, unsigned words, unsigned items, unsigned flags) L4_NOTHROW
Create a message tag from the specified values.
Definition types.h:441
l4_msgtag_t l4_task_cap_equal(l4_cap_idx_t task, l4_cap_idx_t cap_a, l4_cap_idx_t cap_b) L4_NOTHROW
Test whether two capabilities point to the same object with the same permissions (only considering se...
Definition task.h:490
l4_msgtag_t l4_task_map(l4_cap_idx_t dst_task, l4_cap_idx_t src_task, l4_fpage_t snd_fpage, l4_umword_t snd_base) L4_NOTHROW
Map resources available in the source task to a destination task.
Definition task.h:433
#define L4_IPC_BOTH_TIMEOUT_0
0 receive and send timeout
Definition __timeout.h:79
struct l4_utcb_t l4_utcb_t
Opaque type for the UTCB.
Definition utcb.h:56
l4_utcb_t * l4_utcb(void) L4_NOTHROW L4_PURE
Get the UTCB address.
Definition utcb.h:369
#define L4_EXPORT
Attribute to mark functions, variables, and data types as being exported from a library.
Definition compiler.h:220
Common constants.
L4_CONSTEXPR l4_ret_t l4_ipc_to_errno(unsigned long ipc_error_code) L4_NOTHROW
Get a negative error code for the given IPC error code.
Definition ipc.h:594
Common task related definitions.
Common L4 ABI Data Types.
l4_int16_t l4_ret_t
Return value of an IPC call as well as an RPC call.
Definition types.h:29
L4 low-level kernel interface.
Cap< T > cap_reinterpret_cast(Cap< F > const &c) noexcept
reinterpret_cast for capabilities.
Definition capability.h:468
Cap< T > cap_cast(Cap< F > const &c) noexcept
static_cast for capabilities.
Definition capability.h:437
Message tag data structure.
Definition types.h:269
long label() const L4_NOTHROW
Get the protocol value.
Definition types.h:273
L4 flexpage type.
Definition __l4_fpage.h:76