foc: support more caps

by increasing the base-foc internal cap indices implementation from 16bit
size to 28 bit.

Issue #5406
This commit is contained in:
Alexander Boettcher 2025-01-20 19:18:25 +01:00 committed by Christian Helmuth
parent 02b7878229
commit 935681a7f4
7 changed files with 32 additions and 29 deletions

View File

@ -26,7 +26,7 @@ namespace Genode { struct Foc_thread_state; }
struct Genode::Foc_thread_state : Thread_state struct Genode::Foc_thread_state : Thread_state
{ {
Foc::l4_cap_idx_t kcap { Foc::L4_INVALID_CAP }; /* thread's gate cap in its PD */ Foc::l4_cap_idx_t kcap { Foc::L4_INVALID_CAP }; /* thread's gate cap in its PD */
uint16_t id { }; /* ID of gate capability */ uint32_t id { }; /* ID of gate capability */
addr_t utcb { }; /* thread's UTCB in its PD */ addr_t utcb { }; /* thread's UTCB in its PD */
}; };

View File

@ -30,17 +30,15 @@ class Core::Cap_id_allocator
{ {
public: public:
using id_t = uint16_t; using id_t = unsigned;
enum { ID_MASK = 0xffff };
private: private:
enum { enum {
CAP_ID_RANGE = ~0UL, CAP_ID_OFFSET = 1 << 2,
CAP_ID_MASK = ~3UL, CAP_ID_MASK = CAP_ID_OFFSET - 1,
CAP_ID_NUM_MAX = CAP_ID_MASK >> 2, CAP_ID_RANGE = 1u << 28,
CAP_ID_OFFSET = 1 << 2 ID_MASK = CAP_ID_RANGE - 1,
}; };
Synced_range_allocator<Allocator_avl> _id_alloc; Synced_range_allocator<Allocator_avl> _id_alloc;

View File

@ -209,7 +209,7 @@ Foc_thread_state Platform_thread::state()
s = _pager_obj->state.state; s = _pager_obj->state.state;
s.kcap = _gate.remote; s.kcap = _gate.remote;
s.id = (uint16_t)_gate.local.local_name(); s.id = Cap_index::id_t(_gate.local.local_name());
s.utcb = _utcb; s.utcb = _utcb;
return s; return s;

View File

@ -190,7 +190,7 @@ Cap_id_allocator::Cap_id_allocator(Allocator &alloc)
: :
_id_alloc(&alloc) _id_alloc(&alloc)
{ {
_id_alloc.add_range(CAP_ID_OFFSET, CAP_ID_RANGE); _id_alloc.add_range(CAP_ID_OFFSET, unsigned(CAP_ID_RANGE) - unsigned(CAP_ID_OFFSET));
} }
@ -213,7 +213,7 @@ void Cap_id_allocator::free(id_t id)
Mutex::Guard lock_guard(_mutex); Mutex::Guard lock_guard(_mutex);
if (id < CAP_ID_RANGE) if (id < CAP_ID_RANGE)
_id_alloc.free((void*)(id & CAP_ID_MASK), CAP_ID_OFFSET); _id_alloc.free((void*)(addr_t(id & CAP_ID_MASK)), CAP_ID_OFFSET);
} }

View File

@ -30,12 +30,13 @@ class Genode::Native_capability::Data : public Avl_node<Data>
{ {
public: public:
using id_t = uint16_t; using id_t = unsigned;
constexpr static id_t INVALID_ID = ~0u;
private: private:
constexpr static uint16_t INVALID_ID = ~0; constexpr static id_t UNUSED = 0;
constexpr static uint16_t UNUSED = 0;
uint8_t _ref_cnt; /* reference counter */ uint8_t _ref_cnt; /* reference counter */
id_t _id; /* global capability id */ id_t _id; /* global capability id */
@ -46,8 +47,8 @@ class Genode::Native_capability::Data : public Avl_node<Data>
bool valid() const { return _id != INVALID_ID; } bool valid() const { return _id != INVALID_ID; }
bool used() const { return _id != UNUSED; } bool used() const { return _id != UNUSED; }
uint16_t id() const { return _id; } id_t id() const { return _id; }
void id(uint16_t id) { _id = id; } void id(id_t id) { _id = id; }
uint8_t inc(); uint8_t inc();
uint8_t dec(); uint8_t dec();
addr_t kcap() const; addr_t kcap() const;

View File

@ -3,11 +3,11 @@
* \author Stefan Kalkowski * \author Stefan Kalkowski
* \date 2010-12-06 * \date 2010-12-06
* *
* This is a Fiasco.OC-specific addition to the process enviroment. * This is a Fiasco.OC-specific addition to the process environment.
*/ */
/* /*
* Copyright (C) 2010-2017 Genode Labs GmbH * Copyright (C) 2010-2025 Genode Labs GmbH
* *
* This file is part of the Genode OS framework, which is distributed * This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3. * under the terms of the GNU Affero General Public License version 3.
@ -59,7 +59,7 @@ static volatile int _cap_index_spinlock = SPINLOCK_UNLOCKED;
bool Cap_index::higher(Cap_index *n) { return n->_id > _id; } bool Cap_index::higher(Cap_index *n) { return n->_id > _id; }
Cap_index* Cap_index::find_by_id(uint16_t id) Cap_index* Cap_index::find_by_id(id_t id)
{ {
if (_id == id) return this; if (_id == id) return this;
@ -116,8 +116,8 @@ Cap_index* Capability_map::insert(Cap_index::id_t id)
{ {
Spin_lock::Guard guard(_lock); Spin_lock::Guard guard(_lock);
ASSERT(!_tree.first() || !_tree.first()->find_by_id(id), if (_tree.first() && _tree.first()->find_by_id(id))
"Double insertion in cap_map()!"); return { };
Cap_index * const i = cap_idx_alloc().alloc_range(1); Cap_index * const i = cap_idx_alloc().alloc_range(1);
if (i) { if (i) {
@ -184,9 +184,16 @@ Cap_index* Capability_map::insert_map(Cap_index::id_t id, addr_t kcap)
_tree.insert(i); _tree.insert(i);
/* map the given cap to our registry entry */ /* map the given cap to our registry entry */
l4_task_map(L4_BASE_TASK_CAP, L4_BASE_TASK_CAP, auto const msg = l4_task_map(L4_BASE_TASK_CAP, L4_BASE_TASK_CAP,
l4_obj_fpage(kcap, 0, L4_FPAGE_RWX), l4_obj_fpage(kcap, 0, L4_FPAGE_RWX),
i->kcap() | L4_ITEM_MAP | L4_MAP_ITEM_GRANT); i->kcap() | L4_ITEM_MAP | L4_MAP_ITEM_GRANT);
if (l4_error(msg)) {
_tree.remove(i);
cap_idx_alloc().free(i, 1);
return 0;
}
return i; return i;
} }

View File

@ -55,9 +55,6 @@ static inline bool ipc_error(l4_msgtag_t tag, bool print)
} }
static constexpr Cap_index::id_t INVALID_BADGE = 0xffff;
/** /**
* Representation of a capability during UTCB marshalling/unmarshalling * Representation of a capability during UTCB marshalling/unmarshalling
*/ */
@ -116,7 +113,7 @@ static int extract_msg_from_utcb(l4_msgtag_t tag,
Cap_index::id_t const badge = (Cap_index::id_t)(*msg_words++); Cap_index::id_t const badge = (Cap_index::id_t)(*msg_words++);
if (badge == INVALID_BADGE) if (badge == Cap_index::INVALID_ID)
continue; continue;
/* received a delegated capability */ /* received a delegated capability */
@ -227,7 +224,7 @@ static l4_msgtag_t copy_msgbuf_to_utcb(Msgbuf_base &snd_msg,
for (unsigned i = 0; i < num_caps; i++) { for (unsigned i = 0; i < num_caps; i++) {
/* store badge as normal message word */ /* store badge as normal message word */
*msg_words++ = caps[i].valid ? caps[i].badge : INVALID_BADGE; *msg_words++ = caps[i].valid ? caps[i].badge : Cap_index::INVALID_ID;
/* setup flexpage for valid capability to delegate */ /* setup flexpage for valid capability to delegate */
if (caps[i].valid) { if (caps[i].valid) {