base: extend attach of vm_session

by offset, size, writeable and executable parameter

Issue #3111
This commit is contained in:
Alexander Boettcher
2018-11-14 14:57:45 +01:00
committed by Christian Helmuth
parent 17fda73ca1
commit 393643515c
14 changed files with 111 additions and 50 deletions

View File

@@ -31,7 +31,12 @@ class Genode::Page_table_registry
{
public:
class Mapping_cache_full : Exception { };
struct Mapping_cache_full : Exception
{
enum Type { MEMORY, CAPS } reason;
Mapping_cache_full(enum Type reason) : reason(reason) { };
};
private:
@@ -175,9 +180,9 @@ class Genode::Page_table_registry
break;
}
} catch (Genode::Allocator::Out_of_memory) {
throw Mapping_cache_full();
throw Mapping_cache_full(Mapping_cache_full::Type::MEMORY);
} catch (Genode::Out_of_caps) {
throw Mapping_cache_full();
throw Mapping_cache_full(Mapping_cache_full::Type::CAPS);
}
}

View File

@@ -83,7 +83,7 @@ class Genode::Vm_session_component
return nullptr;
}
void _attach_vm_memory(Dataspace_component &, addr_t, bool, bool);
void _attach_vm_memory(Dataspace_component &, addr_t, Attach_attr);
void _detach_vm_memory(addr_t, size_t);
protected:
@@ -116,7 +116,7 @@ class Genode::Vm_session_component
void _exception_handler(Signal_context_capability, Vcpu_id) {}
void _run(Vcpu_id) {}
void _pause(Vcpu_id);
void attach(Dataspace_capability, addr_t) override;
void attach(Dataspace_capability, addr_t, Attach_attr) override;
void attach_pic(addr_t) override {}
void detach(addr_t, size_t) override;
void _create_vcpu(Thread_capability);

View File

@@ -242,16 +242,45 @@ void Vm_session_component::_pause(Vcpu_id const vcpu_id)
void Vm_session_component::_attach_vm_memory(Dataspace_component &dsc,
addr_t const guest_phys,
bool const executable,
bool const writeable)
Attach_attr const attribute)
{
_vm_space.alloc_guest_page_tables(guest_phys, dsc.size());
Flexpage_iterator flex(dsc.phys_addr() + attribute.offset, attribute.size,
guest_phys, attribute.size, guest_phys);
enum { FLUSHABLE = true };
_vm_space.map_guest(dsc.phys_addr(), guest_phys, dsc.size() >> 12,
dsc.cacheability(),
dsc.writable() && writeable,
executable, FLUSHABLE);
Flexpage page = flex.page();
while (page.valid()) {
try {
_vm_space.alloc_guest_page_tables(page.hotspot, 1 << page.log2_order);
} catch (...) {
// Alloc_page_table_failed
Genode::error("alloc_guest_page_table exception");
return;
}
enum { NO_FLUSH = false, FLUSH = true };
try {
_vm_space.map_guest(page.addr, page.hotspot,
(1 << page.log2_order) / 4096,
dsc.cacheability(),
dsc.writable() && attribute.writeable,
attribute.executable, NO_FLUSH);
} catch (Page_table_registry::Mapping_cache_full full) {
if (full.reason == Page_table_registry::Mapping_cache_full::MEMORY)
throw Out_of_ram();
if (full.reason == Page_table_registry::Mapping_cache_full::CAPS)
throw Out_of_caps();
return;
} catch (Genode::Bit_allocator<4096u>::Out_of_indices) {
Genode::warning("run out of indices - flush all");
_vm_space.map_guest(page.addr, page.hotspot,
(1 << page.log2_order) / 4096,
dsc.cacheability(),
dsc.writable() && attribute.writeable,
attribute.executable, FLUSH);
}
page = flex.page();
}
}
void Vm_session_component::_detach_vm_memory(addr_t guest_phys, size_t size)