From 32e7ec7b9b4a412e6f3526954252a94648f0db4b Mon Sep 17 00:00:00 2001 From: Christian Prochaska Date: Tue, 27 Feb 2024 09:10:48 +0100 Subject: [PATCH] core: implement 'Vm_session_component::reserve_and_flush()' Issue #5069 --- .../src/core/include/vm_session_component.h | 1 + repos/base-hw/src/core/vm_session_component.h | 1 + .../src/core/include/vm_session_component.h | 1 + .../src/core/include/vm_session_component.h | 1 + repos/base/src/core/vm_session_common.cc | 49 ++++++++++++------- 5 files changed, 36 insertions(+), 17 deletions(-) diff --git a/repos/base-foc/src/core/include/vm_session_component.h b/repos/base-foc/src/core/include/vm_session_component.h index 6ee6c6ca1c..6df15ff0c1 100644 --- a/repos/base-foc/src/core/include/vm_session_component.h +++ b/repos/base-foc/src/core/include/vm_session_component.h @@ -93,6 +93,7 @@ class Core::Vm_session_component /* helpers for vm_session_common.cc */ void _attach_vm_memory(Dataspace_component &, addr_t, Attach_attr); void _detach_vm_memory(addr_t, size_t); + void _with_region(Region_map::Local_addr, auto const &); protected: diff --git a/repos/base-hw/src/core/vm_session_component.h b/repos/base-hw/src/core/vm_session_component.h index c9bc0d4f65..8b12f56917 100644 --- a/repos/base-hw/src/core/vm_session_component.h +++ b/repos/base-hw/src/core/vm_session_component.h @@ -101,6 +101,7 @@ class Core::Vm_session_component void _attach_vm_memory(Dataspace_component &, addr_t, Attach_attr); void _detach_vm_memory(addr_t, size_t); + void _with_region(Region_map::Local_addr, auto const &); protected: diff --git a/repos/base-nova/src/core/include/vm_session_component.h b/repos/base-nova/src/core/include/vm_session_component.h index b7d8b35821..08ef9b68ec 100644 --- a/repos/base-nova/src/core/include/vm_session_component.h +++ b/repos/base-nova/src/core/include/vm_session_component.h @@ -141,6 +141,7 @@ class Core::Vm_session_component /* helpers for vm_session_common.cc */ void _attach_vm_memory(Dataspace_component &, addr_t, Attach_attr); void _detach_vm_memory(addr_t, size_t); + void _with_region(Region_map::Local_addr, auto const &); protected: diff --git a/repos/base-sel4/src/core/include/vm_session_component.h b/repos/base-sel4/src/core/include/vm_session_component.h index 8b37dfd36f..6de6cc75d6 100644 --- a/repos/base-sel4/src/core/include/vm_session_component.h +++ b/repos/base-sel4/src/core/include/vm_session_component.h @@ -85,6 +85,7 @@ class Core::Vm_session_component /* helpers for vm_session_common.cc */ void _attach_vm_memory(Dataspace_component &, addr_t, Attach_attr); void _detach_vm_memory(addr_t, size_t); + void _with_region(Region_map::Local_addr, auto const &); protected: diff --git a/repos/base/src/core/vm_session_common.cc b/repos/base/src/core/vm_session_common.cc index 24e0c44e4f..e5c8290d81 100644 --- a/repos/base/src/core/vm_session_common.cc +++ b/repos/base/src/core/vm_session_common.cc @@ -149,14 +149,7 @@ void Vm_session_component::detach(addr_t guest_phys, size_t size) if (region) { iteration_size = region->size(); - - /* inform dataspace */ - region->with_dataspace([&] (Dataspace_component &dataspace) { - dataspace.detached_from(*region); - }); - - /* cleanup metadata */ - _map.free(reinterpret_cast(region->base())); + detach(region->base()); } if (addr >= guest_phys_end - (iteration_size - 1)) @@ -164,19 +157,30 @@ void Vm_session_component::detach(addr_t guest_phys, size_t size) addr += iteration_size; } while (true); +} - /* kernel specific code to detach memory from guest */ - _detach_vm_memory(guest_phys, size); + +void Vm_session_component::_with_region(Region_map::Local_addr addr, + auto const &fn) +{ + Rm_region *region = _map.metadata(addr); + if (region) + fn(*region); + else + error(__PRETTY_FUNCTION__, " unknown region"); } void Vm_session_component::detach(Region_map::Local_addr addr) { - Rm_region *region = _map.metadata(addr); - if (region) - detach(region->base(), region->size()); - else - error(__PRETTY_FUNCTION__, " unknown region"); + _with_region(addr, [&] (Rm_region ®ion) { + + if (!region.reserved()) + reserve_and_flush(addr); + + /* free the reserved region */ + _map.free(reinterpret_cast(region.base())); + }); } @@ -186,7 +190,18 @@ void Vm_session_component::unmap_region(addr_t base, size_t size) } -void Vm_session_component::reserve_and_flush(Region_map::Local_addr) +void Vm_session_component::reserve_and_flush(Region_map::Local_addr addr) { - error(__func__, " unimplemented"); + _with_region(addr, [&] (Rm_region ®ion) { + + /* inform dataspace */ + region.with_dataspace([&] (Dataspace_component &dataspace) { + dataspace.detached_from(region); + }); + + region.mark_as_reserved(); + + /* kernel specific code to detach memory from guest */ + _detach_vm_memory(region.base(), region.size()); + }); }