mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-22 06:57:51 +00:00
base: invalidate entire range on VM-session detach
The requested guest-physical memory range may comprise multiple attached dataspace regions, which must all be detached. This is not required for the current vbox5 implementation, but for vbox6 as the current API suggests these semantics. This commit can be seen as intermediate fix as a real fix should change the API to prevent long-running detach loops in core that may lock out requests by other components.
This commit is contained in:
parent
7eb3da71b5
commit
13dab699b1
@ -123,26 +123,35 @@ void Vm_session_component::attach(Dataspace_capability const cap,
|
|||||||
|
|
||||||
void Vm_session_component::detach(addr_t guest_phys, size_t size)
|
void Vm_session_component::detach(addr_t guest_phys, size_t size)
|
||||||
{
|
{
|
||||||
if (guest_phys & 0xffful) {
|
if (!size || (guest_phys & 0xffful) || (size & 0xffful)) {
|
||||||
size += 0x1000 - (guest_phys & 0xffful);
|
warning("vm_session: skipping invalid memory detach addr=",
|
||||||
guest_phys &= ~0xffful;
|
(void *)guest_phys, " size=", (void *)size);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size & 0xffful)
|
addr_t const guest_phys_end = guest_phys + (size - 1);
|
||||||
size = align_addr(size, 12);
|
addr_t addr = guest_phys;
|
||||||
|
do {
|
||||||
|
Rm_region *region = _map.metadata((void *)addr);
|
||||||
|
|
||||||
if (!size)
|
/* walk region holes page-by-page */
|
||||||
return;
|
size_t iteration_size = 0x1000;
|
||||||
|
|
||||||
|
if (region) {
|
||||||
|
iteration_size = region->size();
|
||||||
|
|
||||||
{
|
|
||||||
Rm_region *region = _map.metadata(reinterpret_cast<void *>(guest_phys));
|
|
||||||
if (region && guest_phys == region->base() && region->size() <= size) {
|
|
||||||
/* inform dataspace */
|
/* inform dataspace */
|
||||||
region->dataspace().detached_from(*region);
|
region->dataspace().detached_from(*region);
|
||||||
|
|
||||||
/* cleanup metadata */
|
/* cleanup metadata */
|
||||||
_map.free(reinterpret_cast<void *>(region->base()));
|
_map.free(reinterpret_cast<void *>(region->base()));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if (addr >= guest_phys_end - (iteration_size - 1))
|
||||||
|
break;
|
||||||
|
|
||||||
|
addr += iteration_size;
|
||||||
|
} while (true);
|
||||||
|
|
||||||
/* kernel specific code to detach memory from guest */
|
/* kernel specific code to detach memory from guest */
|
||||||
_detach_vm_memory(guest_phys, size);
|
_detach_vm_memory(guest_phys, size);
|
||||||
|
Loading…
Reference in New Issue
Block a user