mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 21:57:55 +00:00
hw: detach UTCB from core PD in thread destruction
Ref genodelabs/genode#5380
This commit is contained in:
parent
9a7fe5e775
commit
7dbc9129db
@ -30,6 +30,79 @@
|
|||||||
using namespace Core;
|
using namespace Core;
|
||||||
|
|
||||||
|
|
||||||
|
Ram_dataspace_capability Platform_thread::Utcb::_allocate_utcb(bool core_thread)
|
||||||
|
{
|
||||||
|
Ram_dataspace_capability ds;
|
||||||
|
|
||||||
|
if (core_thread)
|
||||||
|
return ds;
|
||||||
|
|
||||||
|
try {
|
||||||
|
ds = core_env().pd_session()->alloc(sizeof(Native_utcb), CACHED);
|
||||||
|
} catch (...) {
|
||||||
|
error("failed to allocate UTCB");
|
||||||
|
throw Out_of_ram();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ds;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
addr_t Platform_thread::Utcb::_core_local_address(addr_t utcb_addr,
|
||||||
|
bool core_thread)
|
||||||
|
{
|
||||||
|
if (core_thread)
|
||||||
|
return utcb_addr;
|
||||||
|
|
||||||
|
addr_t ret = 0;
|
||||||
|
|
||||||
|
Region_map::Attr attr { };
|
||||||
|
attr.writeable = true;
|
||||||
|
core_env().rm_session()->attach(_ds, attr).with_result(
|
||||||
|
[&] (Region_map::Range range) {
|
||||||
|
ret = range.start; },
|
||||||
|
[&] (Region_map::Attach_error) {
|
||||||
|
error("failed to attach UTCB of new thread within core"); });
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Platform_thread::Utcb::Utcb(addr_t pd_addr, bool core_thread)
|
||||||
|
:
|
||||||
|
_ds(_allocate_utcb(core_thread)),
|
||||||
|
_core_addr(_core_local_address(pd_addr, core_thread))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* All non-core threads use the typical dataspace/rm_session
|
||||||
|
* mechanisms to allocate and attach its UTCB.
|
||||||
|
* But for the very first core threads, we need to use plain
|
||||||
|
* physical and virtual memory allocators to create/attach its
|
||||||
|
* UTCBs. Therefore, we've to allocate and map those here.
|
||||||
|
*/
|
||||||
|
if (core_thread) {
|
||||||
|
platform().ram_alloc().try_alloc(sizeof(Native_utcb)).with_result(
|
||||||
|
|
||||||
|
[&] (void *utcb_phys) {
|
||||||
|
map_local((addr_t)utcb_phys, _core_addr,
|
||||||
|
sizeof(Native_utcb) / get_page_size());
|
||||||
|
},
|
||||||
|
[&] (Range_allocator::Alloc_error) {
|
||||||
|
error("failed to allocate UTCB for core/kernel thread!");
|
||||||
|
throw Out_of_ram();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Platform_thread::Utcb::~Utcb()
|
||||||
|
{
|
||||||
|
/* detach UTCB from core/kernel */
|
||||||
|
core_env().rm_session()->detach((addr_t)_core_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Platform_thread::_init() { }
|
void Platform_thread::_init() { }
|
||||||
|
|
||||||
|
|
||||||
@ -37,21 +110,6 @@ Weak_ptr<Address_space>& Platform_thread::address_space() {
|
|||||||
return _address_space; }
|
return _address_space; }
|
||||||
|
|
||||||
|
|
||||||
Platform_thread::~Platform_thread()
|
|
||||||
{
|
|
||||||
/* detach UTCB of main threads */
|
|
||||||
if (_main_thread) {
|
|
||||||
Locked_ptr<Address_space> locked_ptr(_address_space);
|
|
||||||
if (locked_ptr.valid())
|
|
||||||
locked_ptr->flush((addr_t)_utcb_pd_addr, sizeof(Native_utcb),
|
|
||||||
Address_space::Core_local_addr{0});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* free UTCB */
|
|
||||||
core_env().pd_session()->free(_utcb);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Platform_thread::quota(size_t const quota)
|
void Platform_thread::quota(size_t const quota)
|
||||||
{
|
{
|
||||||
_quota = (unsigned)quota;
|
_quota = (unsigned)quota;
|
||||||
@ -64,26 +122,10 @@ Platform_thread::Platform_thread(Label const &label, Native_utcb &utcb)
|
|||||||
_label(label),
|
_label(label),
|
||||||
_pd(_kernel_main_get_core_platform_pd()),
|
_pd(_kernel_main_get_core_platform_pd()),
|
||||||
_pager(nullptr),
|
_pager(nullptr),
|
||||||
_utcb_core_addr(&utcb),
|
_utcb((addr_t)&utcb, true),
|
||||||
_utcb_pd_addr(&utcb),
|
|
||||||
_main_thread(false),
|
_main_thread(false),
|
||||||
_location(Affinity::Location()),
|
_location(Affinity::Location()),
|
||||||
_kobj(_kobj.CALLED_FROM_CORE, _label.string())
|
_kobj(_kobj.CALLED_FROM_CORE, _label.string()) { }
|
||||||
{
|
|
||||||
/* create UTCB for a core thread */
|
|
||||||
platform().ram_alloc().try_alloc(sizeof(Native_utcb)).with_result(
|
|
||||||
|
|
||||||
[&] (void *utcb_phys) {
|
|
||||||
map_local((addr_t)utcb_phys, (addr_t)_utcb_core_addr,
|
|
||||||
sizeof(Native_utcb) / get_page_size());
|
|
||||||
},
|
|
||||||
[&] (Range_allocator::Alloc_error) {
|
|
||||||
error("failed to allocate UTCB");
|
|
||||||
/* XXX distinguish error conditions */
|
|
||||||
throw Out_of_ram();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Platform_thread::Platform_thread(Platform_pd &pd,
|
Platform_thread::Platform_thread(Platform_pd &pd,
|
||||||
@ -96,33 +138,39 @@ Platform_thread::Platform_thread(Platform_pd &pd,
|
|||||||
_label(label),
|
_label(label),
|
||||||
_pd(pd),
|
_pd(pd),
|
||||||
_pager(nullptr),
|
_pager(nullptr),
|
||||||
_utcb_pd_addr((Native_utcb *)utcb),
|
_utcb(utcb, false),
|
||||||
_priority(_scale_priority(virt_prio)),
|
_priority(_scale_priority(virt_prio)),
|
||||||
_quota((unsigned)quota),
|
_quota((unsigned)quota),
|
||||||
_main_thread(!pd.has_any_thread),
|
_main_thread(!pd.has_any_thread),
|
||||||
_location(location),
|
_location(location),
|
||||||
_kobj(_kobj.CALLED_FROM_CORE, _priority, _quota, _label.string())
|
_kobj(_kobj.CALLED_FROM_CORE, _priority, _quota, _label.string())
|
||||||
{
|
{
|
||||||
try {
|
|
||||||
_utcb = core_env().pd_session()->alloc(sizeof(Native_utcb), CACHED);
|
|
||||||
} catch (...) {
|
|
||||||
error("failed to allocate UTCB");
|
|
||||||
throw Out_of_ram();
|
|
||||||
}
|
|
||||||
|
|
||||||
Region_map::Attr attr { };
|
|
||||||
attr.writeable = true;
|
|
||||||
core_env().rm_session()->attach(_utcb, attr).with_result(
|
|
||||||
[&] (Region_map::Range range) {
|
|
||||||
_utcb_core_addr = (Native_utcb *)range.start; },
|
|
||||||
[&] (Region_map::Attach_error) {
|
|
||||||
error("failed to attach UTCB of new thread within core"); });
|
|
||||||
|
|
||||||
_address_space = pd.weak_ptr();
|
_address_space = pd.weak_ptr();
|
||||||
pd.has_any_thread = true;
|
pd.has_any_thread = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Platform_thread::~Platform_thread()
|
||||||
|
{
|
||||||
|
/* core/kernel threads have no dataspace, but plain memory as UTCB */
|
||||||
|
if (!_utcb._ds.valid()) {
|
||||||
|
error("UTCB of core/kernel thread gets destructed!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* detach UTCB of main threads */
|
||||||
|
if (_main_thread) {
|
||||||
|
Locked_ptr<Address_space> locked_ptr(_address_space);
|
||||||
|
if (locked_ptr.valid())
|
||||||
|
locked_ptr->flush(user_utcb_main_thread(), sizeof(Native_utcb),
|
||||||
|
Address_space::Core_local_addr{0});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free UTCB */
|
||||||
|
core_env().pd_session()->free(_utcb._ds);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Platform_thread::affinity(Affinity::Location const &)
|
void Platform_thread::affinity(Affinity::Location const &)
|
||||||
{
|
{
|
||||||
/* yet no migration support, don't claim wrong location, e.g. for tracing */
|
/* yet no migration support, don't claim wrong location, e.g. for tracing */
|
||||||
@ -147,16 +195,15 @@ void Platform_thread::start(void * const ip, void * const sp)
|
|||||||
error("invalid RM client");
|
error("invalid RM client");
|
||||||
return -1;
|
return -1;
|
||||||
};
|
};
|
||||||
_utcb_pd_addr = (Native_utcb *)user_utcb_main_thread();
|
|
||||||
Hw::Address_space * as = static_cast<Hw::Address_space*>(&*locked_ptr);
|
Hw::Address_space * as = static_cast<Hw::Address_space*>(&*locked_ptr);
|
||||||
if (!as->insert_translation((addr_t)_utcb_pd_addr, dsc->phys_addr(),
|
if (!as->insert_translation(user_utcb_main_thread(), dsc->phys_addr(),
|
||||||
sizeof(Native_utcb), Hw::PAGE_FLAGS_UTCB)) {
|
sizeof(Native_utcb), Hw::PAGE_FLAGS_UTCB)) {
|
||||||
error("failed to attach UTCB");
|
error("failed to attach UTCB");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
if (core_env().entrypoint().apply(_utcb, lambda))
|
if (core_env().entrypoint().apply(_utcb._ds, lambda))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,9 +221,9 @@ void Platform_thread::start(void * const ip, void * const sp)
|
|||||||
utcb.cap_add(Capability_space::capid(_kobj.cap()));
|
utcb.cap_add(Capability_space::capid(_kobj.cap()));
|
||||||
if (_main_thread) {
|
if (_main_thread) {
|
||||||
utcb.cap_add(Capability_space::capid(_pd.parent()));
|
utcb.cap_add(Capability_space::capid(_pd.parent()));
|
||||||
utcb.cap_add(Capability_space::capid(_utcb));
|
utcb.cap_add(Capability_space::capid(_utcb._ds));
|
||||||
}
|
}
|
||||||
Kernel::start_thread(*_kobj, cpu, _pd.kernel_pd(), *_utcb_core_addr);
|
Kernel::start_thread(*_kobj, cpu, _pd.kernel_pd(), *(Native_utcb*)_utcb._core_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,13 +55,24 @@ class Core::Platform_thread : Noncopyable
|
|||||||
|
|
||||||
using Label = String<32>;
|
using Label = String<32>;
|
||||||
|
|
||||||
|
struct Utcb
|
||||||
|
{
|
||||||
|
Ram_dataspace_capability _ds { }; /* UTCB ds of non-core threads */
|
||||||
|
|
||||||
|
addr_t const _core_addr; /* UTCB address within core/kernel */
|
||||||
|
|
||||||
|
Ram_dataspace_capability _allocate_utcb(bool core_thread);
|
||||||
|
addr_t _core_local_address(addr_t utcb_addr, bool core_thread);
|
||||||
|
|
||||||
|
Utcb(addr_t pd_addr, bool core_thread);
|
||||||
|
~Utcb();
|
||||||
|
};
|
||||||
|
|
||||||
Label const _label;
|
Label const _label;
|
||||||
Platform_pd &_pd;
|
Platform_pd &_pd;
|
||||||
Weak_ptr<Address_space> _address_space { };
|
Weak_ptr<Address_space> _address_space { };
|
||||||
Pager_object * _pager;
|
Pager_object * _pager;
|
||||||
Native_utcb * _utcb_core_addr { }; /* UTCB addr in core */
|
Utcb _utcb;
|
||||||
Native_utcb * _utcb_pd_addr; /* UTCB addr in pd */
|
|
||||||
Ram_dataspace_capability _utcb { }; /* UTCB dataspace */
|
|
||||||
unsigned _priority {0};
|
unsigned _priority {0};
|
||||||
unsigned _quota {0};
|
unsigned _quota {0};
|
||||||
|
|
||||||
@ -241,7 +252,7 @@ class Core::Platform_thread : Noncopyable
|
|||||||
|
|
||||||
Platform_pd &pd() const { return _pd; }
|
Platform_pd &pd() const { return _pd; }
|
||||||
|
|
||||||
Ram_dataspace_capability utcb() const { return _utcb; }
|
Ram_dataspace_capability utcb() const { return _utcb._ds; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _CORE__PLATFORM_THREAD_H_ */
|
#endif /* _CORE__PLATFORM_THREAD_H_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user