sel4: invalidate ram if used uncached later on

Fixes #2665
This commit is contained in:
Alexander Boettcher 2018-03-28 14:06:18 +02:00 committed by Christian Helmuth
parent c8fcaf007e
commit 0b7e2a1642
5 changed files with 38 additions and 5 deletions

View File

@ -53,11 +53,12 @@ namespace Genode {
/**
* Flush memory mappings from core-local virtual address range
*/
inline bool unmap_local(addr_t virt_addr, size_t num_pages,
Platform * platform = nullptr)
inline bool unmap_local(addr_t const virt_addr, size_t const num_pages,
Platform * platform = nullptr,
bool const invalidate = false)
{
platform = platform ? platform : platform_specific();
return platform->core_vm_space().unmap(virt_addr, num_pages);
return platform->core_vm_space().unmap(virt_addr, num_pages, invalidate);
}
}

View File

@ -245,6 +245,8 @@ class Genode::Vm_space
Cache_attribute const cacheability, bool const write,
bool const writable);
long _unmap_page(Genode::Cap_sel const &idx);
long _invalidate_page(Genode::Cap_sel const &, seL4_Word const,
seL4_Word const);
class Alloc_page_table_failed : Exception { };
@ -392,7 +394,8 @@ class Genode::Vm_space
}
}
bool unmap(addr_t virt, size_t num_pages)
bool unmap(addr_t const virt, size_t const num_pages,
bool const invalidate = false)
{
bool unmap_success = true;
@ -403,6 +406,14 @@ class Genode::Vm_space
_page_table_registry.flush_page(virt + offset, [&] (Cap_sel const &idx, addr_t) {
if (invalidate) {
long result = _invalidate_page(idx, virt + offset,
virt + offset + 4096);
if (result != seL4_NoError)
error("invalidating ", Hex(virt + offset),
" failed, idx=", idx, " result=", result);
}
long result = _unmap_page(idx);
if (result != seL4_NoError) {
error("unmap ", Hex(virt + offset), " failed, idx=",

View File

@ -67,7 +67,7 @@ void Ram_dataspace_factory::_clear_ds (Dataspace_component *ds)
*dst++ = 0;
/* unmap cleared page from core */
unmap_local(virt_addr, ONE_PAGE);
unmap_local(virt_addr, ONE_PAGE, nullptr, ds->cacheability() != CACHED);
}
/* free core's virtual address space */

View File

@ -47,6 +47,21 @@ long Genode::Vm_space::_unmap_page(Genode::Cap_sel const &idx)
return seL4_ARM_Page_Unmap(service);
}
long Genode::Vm_space::_invalidate_page(Genode::Cap_sel const &idx,
seL4_Word const start,
seL4_Word const end)
{
seL4_ARM_Page const service = _idx_to_sel(idx.value());
long error = seL4_ARM_Page_CleanInvalidate_Data(service, 0, end - start);
if (error == seL4_NoError) {
seL4_ARM_PageDirectory const pd = _pd_sel.value();
error = seL4_ARM_PageDirectory_CleanInvalidate_Data(pd, start, end);
}
return error;
}
void Genode::Vm_space::unsynchronized_alloc_page_tables(addr_t const start,
addr_t const size)
{

View File

@ -39,3 +39,9 @@ long Genode::Vm_space::_unmap_page(Genode::Cap_sel const &idx)
seL4_X86_Page const service = _idx_to_sel(idx.value());
return seL4_X86_Page_Unmap(service);
}
long Genode::Vm_space::_invalidate_page(Genode::Cap_sel const &,
seL4_Word const, seL4_Word const)
{
return seL4_NoError;
}