core: implement 'Vm_session_component::reserve_and_flush()'

Issue #5069
This commit is contained in:
Christian Prochaska 2024-02-27 09:10:48 +01:00 committed by Christian Helmuth
parent 9a65e4f607
commit 32e7ec7b9b
5 changed files with 36 additions and 17 deletions

View File

@ -93,6 +93,7 @@ class Core::Vm_session_component
/* helpers for vm_session_common.cc */ /* helpers for vm_session_common.cc */
void _attach_vm_memory(Dataspace_component &, addr_t, Attach_attr); void _attach_vm_memory(Dataspace_component &, addr_t, Attach_attr);
void _detach_vm_memory(addr_t, size_t); void _detach_vm_memory(addr_t, size_t);
void _with_region(Region_map::Local_addr, auto const &);
protected: protected:

View File

@ -101,6 +101,7 @@ class Core::Vm_session_component
void _attach_vm_memory(Dataspace_component &, addr_t, void _attach_vm_memory(Dataspace_component &, addr_t,
Attach_attr); Attach_attr);
void _detach_vm_memory(addr_t, size_t); void _detach_vm_memory(addr_t, size_t);
void _with_region(Region_map::Local_addr, auto const &);
protected: protected:

View File

@ -141,6 +141,7 @@ class Core::Vm_session_component
/* helpers for vm_session_common.cc */ /* helpers for vm_session_common.cc */
void _attach_vm_memory(Dataspace_component &, addr_t, Attach_attr); void _attach_vm_memory(Dataspace_component &, addr_t, Attach_attr);
void _detach_vm_memory(addr_t, size_t); void _detach_vm_memory(addr_t, size_t);
void _with_region(Region_map::Local_addr, auto const &);
protected: protected:

View File

@ -85,6 +85,7 @@ class Core::Vm_session_component
/* helpers for vm_session_common.cc */ /* helpers for vm_session_common.cc */
void _attach_vm_memory(Dataspace_component &, addr_t, Attach_attr); void _attach_vm_memory(Dataspace_component &, addr_t, Attach_attr);
void _detach_vm_memory(addr_t, size_t); void _detach_vm_memory(addr_t, size_t);
void _with_region(Region_map::Local_addr, auto const &);
protected: protected:

View File

@ -149,14 +149,7 @@ void Vm_session_component::detach(addr_t guest_phys, size_t size)
if (region) { if (region) {
iteration_size = region->size(); iteration_size = region->size();
detach(region->base());
/* inform dataspace */
region->with_dataspace([&] (Dataspace_component &dataspace) {
dataspace.detached_from(*region);
});
/* cleanup metadata */
_map.free(reinterpret_cast<void *>(region->base()));
} }
if (addr >= guest_phys_end - (iteration_size - 1)) 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; addr += iteration_size;
} while (true); } 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) void Vm_session_component::detach(Region_map::Local_addr addr)
{ {
Rm_region *region = _map.metadata(addr); _with_region(addr, [&] (Rm_region &region) {
if (region)
detach(region->base(), region->size()); if (!region.reserved())
else reserve_and_flush(addr);
error(__PRETTY_FUNCTION__, " unknown region");
/* free the reserved region */
_map.free(reinterpret_cast<void *>(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 &region) {
/* 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());
});
} }