From e256969489520775ce1210fb5737ecfb9d7cece9 Mon Sep 17 00:00:00 2001 From: Johannes Schlatow Date: Wed, 17 Nov 2021 15:26:20 +0100 Subject: [PATCH] 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 --- repos/os/src/drivers/platform/spec/arm/main.cc | 9 ++++++++- .../src/drivers/platform/spec/arm/session_component.cc | 3 +++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/repos/os/src/drivers/platform/spec/arm/main.cc b/repos/os/src/drivers/platform/spec/arm/main.cc index 6a04c2885b..eaa5189383 100644 --- a/repos/os/src/drivers/platform/spec/arm/main.cc +++ b/repos/os/src/drivers/platform/spec/arm/main.cc @@ -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) { diff --git a/repos/os/src/drivers/platform/spec/arm/session_component.cc b/repos/os/src/drivers/platform/spec/arm/session_component.cc index e383b757fd..d23d722ee9 100644 --- a/repos/os/src/drivers/platform/spec/arm/session_component.cc +++ b/repos/os/src/drivers/platform/spec/arm/session_component.cc @@ -110,6 +110,8 @@ Session_component::acquire_single_device() void Session_component::release_device(Capability 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()); }