mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-18 13:26:27 +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;
|
||||
|
||||
|
||||
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() { }
|
||||
|
||||
|
||||
@ -37,21 +110,6 @@ Weak_ptr<Address_space>& Platform_thread::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)
|
||||
{
|
||||
_quota = (unsigned)quota;
|
||||
@ -64,26 +122,10 @@ Platform_thread::Platform_thread(Label const &label, Native_utcb &utcb)
|
||||
_label(label),
|
||||
_pd(_kernel_main_get_core_platform_pd()),
|
||||
_pager(nullptr),
|
||||
_utcb_core_addr(&utcb),
|
||||
_utcb_pd_addr(&utcb),
|
||||
_utcb((addr_t)&utcb, true),
|
||||
_main_thread(false),
|
||||
_location(Affinity::Location()),
|
||||
_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();
|
||||
}
|
||||
);
|
||||
}
|
||||
_kobj(_kobj.CALLED_FROM_CORE, _label.string()) { }
|
||||
|
||||
|
||||
Platform_thread::Platform_thread(Platform_pd &pd,
|
||||
@ -96,33 +138,39 @@ Platform_thread::Platform_thread(Platform_pd &pd,
|
||||
_label(label),
|
||||
_pd(pd),
|
||||
_pager(nullptr),
|
||||
_utcb_pd_addr((Native_utcb *)utcb),
|
||||
_utcb(utcb, false),
|
||||
_priority(_scale_priority(virt_prio)),
|
||||
_quota((unsigned)quota),
|
||||
_main_thread(!pd.has_any_thread),
|
||||
_location(location),
|
||||
_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();
|
||||
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 &)
|
||||
{
|
||||
/* 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");
|
||||
return -1;
|
||||
};
|
||||
_utcb_pd_addr = (Native_utcb *)user_utcb_main_thread();
|
||||
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)) {
|
||||
error("failed to attach UTCB");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
if (core_env().entrypoint().apply(_utcb, lambda))
|
||||
if (core_env().entrypoint().apply(_utcb._ds, lambda))
|
||||
return;
|
||||
}
|
||||
|
||||
@ -174,9 +221,9 @@ void Platform_thread::start(void * const ip, void * const sp)
|
||||
utcb.cap_add(Capability_space::capid(_kobj.cap()));
|
||||
if (_main_thread) {
|
||||
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>;
|
||||
|
||||
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;
|
||||
Platform_pd &_pd;
|
||||
Weak_ptr<Address_space> _address_space { };
|
||||
Pager_object * _pager;
|
||||
Native_utcb * _utcb_core_addr { }; /* UTCB addr in core */
|
||||
Native_utcb * _utcb_pd_addr; /* UTCB addr in pd */
|
||||
Ram_dataspace_capability _utcb { }; /* UTCB dataspace */
|
||||
Utcb _utcb;
|
||||
unsigned _priority {0};
|
||||
unsigned _quota {0};
|
||||
|
||||
@ -241,7 +252,7 @@ class Core::Platform_thread : Noncopyable
|
||||
|
||||
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_ */
|
||||
|
Loading…
Reference in New Issue
Block a user