platform_drv(arm): fix destruction order

The Session_component must be destroyed before updating the device
model because the Session_component must also release all previously
acquired devices. If the device model is updated before, the devices
might have been removed.

Issue #4330
This commit is contained in:
Johannes Schlatow 2021-11-17 15:26:20 +01:00 committed by Christian Helmuth
parent 7a2826a2fe
commit e256969489
2 changed files with 11 additions and 1 deletions

View File

@ -39,8 +39,15 @@ struct Driver::Main
void Driver::Main::update_config()
{
env.config.update();
env.devices.update(env.config.xml());
/**
* We must perform the policy update before updating the devices since
* the former may need to release devices and its corresponding Io_mem
* and Irq connections when closing a session that is no longer supposed
* to exist. For doing so, it must access the old device model.
*/
root.update_policy();
env.devices.update(env.config.xml());
}
void Component::construct(Genode::Env &env) {

View File

@ -110,6 +110,8 @@ Session_component::acquire_single_device()
void Session_component::release_device(Capability<Platform::Device_interface> device_cap)
{
_env.env.ep().rpc_ep().apply(device_cap, [&] (Device_component * dc) {
if (!dc)
return;
_env.env.ep().rpc_ep().dissolve(dc);
_cap_quota_guard().replenish(Cap_quota{1});
dc->release();
@ -199,6 +201,7 @@ Session_component::~Session_component()
{
while (_device_list.first()) {
Device_list_element * e = _device_list.first();
release_device(e->object()->cap());
_device_list.remove(e);
destroy(_md_alloc, e->object());
}