mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-22 23:12:24 +00:00
base-linux: revised region management
Revised region management detects region conflicts by using _soft_ mappings per default. Overmapping is activated for population of managed dataspaces only. For more information see header documentation of base-linux/src/base/env/rm_session_mmap.cc. Fixes #883.
This commit is contained in:
parent
f763e5ec2a
commit
385b7cdd31
81
base-linux/run/lx_rmap.inc
Normal file
81
base-linux/run/lx_rmap.inc
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
#
|
||||||
|
# \brief Test for Linux-specific region map
|
||||||
|
# \author Christian Helmuth
|
||||||
|
# \date 2013-09-06
|
||||||
|
#
|
||||||
|
|
||||||
|
assert_spec linux
|
||||||
|
|
||||||
|
if {[have_spec always_hybrid]} {
|
||||||
|
puts "\nTest does not support always_hybrid mode."
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build
|
||||||
|
#
|
||||||
|
|
||||||
|
set build_components { core init }
|
||||||
|
|
||||||
|
lappend_if [expr {$test_type eq "static"}] build_components test/lx_rmap/static
|
||||||
|
lappend_if [expr {$test_type eq "dynamic"}] build_components test/lx_rmap/dynamic
|
||||||
|
|
||||||
|
build $build_components
|
||||||
|
|
||||||
|
create_boot_directory
|
||||||
|
|
||||||
|
#
|
||||||
|
# Config
|
||||||
|
#
|
||||||
|
|
||||||
|
set config {
|
||||||
|
<config>
|
||||||
|
<parent-provides>
|
||||||
|
<service name="ROM"/>
|
||||||
|
<service name="RM"/>
|
||||||
|
<service name="CAP"/>
|
||||||
|
<service name="LOG"/>
|
||||||
|
<service name="IO_PORT"/>
|
||||||
|
<service name="IO_MEM"/>
|
||||||
|
<service name="IRQ"/>
|
||||||
|
<service name="CPU"/>
|
||||||
|
<service name="SIGNAL"/>
|
||||||
|
</parent-provides>
|
||||||
|
<default-route>
|
||||||
|
<any-service> <parent/> <any-child/> </any-service>
|
||||||
|
</default-route>}
|
||||||
|
|
||||||
|
append_if [expr {$test_type eq "static"}] config {
|
||||||
|
<start name="test-lx_rmap_static">}
|
||||||
|
append_if [expr {$test_type eq "dynamic"}] config {
|
||||||
|
<start name="test-lx_rmap_dynamic">}
|
||||||
|
|
||||||
|
append config {
|
||||||
|
<resource name="RAM" quantum="8M"/>
|
||||||
|
</start>
|
||||||
|
</config>}
|
||||||
|
|
||||||
|
install_config $config
|
||||||
|
|
||||||
|
#
|
||||||
|
# Boot modules
|
||||||
|
#
|
||||||
|
|
||||||
|
set boot_modules { core init}
|
||||||
|
|
||||||
|
lappend_if [expr {$test_type eq "static"}] boot_modules test-lx_rmap_static
|
||||||
|
lappend_if [expr {$test_type eq "dynamic"}] boot_modules test-lx_rmap_dynamic
|
||||||
|
lappend_if [expr {$test_type eq "dynamic"}] boot_modules ld.lib.so
|
||||||
|
lappend_if [expr {$test_type eq "dynamic"}] boot_modules libc.lib.so
|
||||||
|
lappend_if [expr {$test_type eq "dynamic"}] boot_modules libc_log.lib.so
|
||||||
|
lappend_if [expr {$test_type eq "dynamic"}] boot_modules libm.lib.so
|
||||||
|
|
||||||
|
build_boot_image $boot_modules
|
||||||
|
|
||||||
|
#
|
||||||
|
# Execute test
|
||||||
|
#
|
||||||
|
|
||||||
|
run_genode_until forever
|
||||||
|
|
||||||
|
# vi: set ft=tcl :
|
11
base-linux/run/lx_rmap_dynamic.run
Normal file
11
base-linux/run/lx_rmap_dynamic.run
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#
|
||||||
|
# \brief Test for Linux-specific region map (dynamic binary)
|
||||||
|
# \author Christian Helmuth
|
||||||
|
# \date 2013-09-06
|
||||||
|
#
|
||||||
|
|
||||||
|
set test_type "dynamic"
|
||||||
|
|
||||||
|
source ${genode_dir}/base-linux/run/lx_rmap.inc
|
||||||
|
|
||||||
|
# vi: set ft=tcl :
|
11
base-linux/run/lx_rmap_static.run
Normal file
11
base-linux/run/lx_rmap_static.run
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#
|
||||||
|
# \brief Test for Linux-specific region map (static binary)
|
||||||
|
# \author Christian Helmuth
|
||||||
|
# \date 2013-09-06
|
||||||
|
#
|
||||||
|
|
||||||
|
set test_type "static"
|
||||||
|
|
||||||
|
source ${genode_dir}/base-linux/run/lx_rmap.inc
|
||||||
|
|
||||||
|
# vi: set ft=tcl :
|
10
base-linux/src/base/env/platform_env.h
vendored
10
base-linux/src/base/env/platform_env.h
vendored
@ -196,6 +196,13 @@ namespace Genode {
|
|||||||
|
|
||||||
void _add_to_rmap(Region const &);
|
void _add_to_rmap(Region const &);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reserve VM region for sub-rm dataspace
|
||||||
|
*/
|
||||||
|
addr_t _reserve_local(bool use_local_addr,
|
||||||
|
addr_t local_addr,
|
||||||
|
Genode::size_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map dataspace into local address space
|
* Map dataspace into local address space
|
||||||
*/
|
*/
|
||||||
@ -204,7 +211,8 @@ namespace Genode {
|
|||||||
addr_t offset,
|
addr_t offset,
|
||||||
bool use_local_addr,
|
bool use_local_addr,
|
||||||
addr_t local_addr,
|
addr_t local_addr,
|
||||||
bool executable);
|
bool executable,
|
||||||
|
bool overmap = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine size of dataspace
|
* Determine size of dataspace
|
||||||
|
116
base-linux/src/base/env/rm_session_mmap.cc
vendored
116
base-linux/src/base/env/rm_session_mmap.cc
vendored
@ -2,6 +2,27 @@
|
|||||||
* \brief Implementation of Linux-specific local region manager
|
* \brief Implementation of Linux-specific local region manager
|
||||||
* \author Norman Feske
|
* \author Norman Feske
|
||||||
* \date 2008-10-22
|
* \date 2008-10-22
|
||||||
|
*
|
||||||
|
* Under Linux, region management happens at the mercy of the Linux kernel. So,
|
||||||
|
* all we can do in user land is 1) keep track of regions and (managed)
|
||||||
|
* dataspaces and 2) get the kernel to manage VM regions as we intent.
|
||||||
|
*
|
||||||
|
* The kernel sets up mappings for the binary on execve(), which are text and
|
||||||
|
* data segments, the context area and special regions (stack, vdso, vsyscall).
|
||||||
|
* Later mappings are done by the Genode program itself, which knows nothing
|
||||||
|
* about these initial mappings. Therefore, most mmap() operations are _soft_
|
||||||
|
* to detect region conflicts with existing mappings or let the kernel find
|
||||||
|
* some empty VM area (as core does on other platforms). The only _hard_
|
||||||
|
* overmaps happen on attachment and population of managed dataspaces. Mapped,
|
||||||
|
* but not populated dataspaces are "holes" in the Linux VM space represented
|
||||||
|
* by PROT_NONE mappings (see _reserve_local()).
|
||||||
|
*
|
||||||
|
* The context area is a managed dataspace as on other platforms, which is
|
||||||
|
* created and attached during program launch. The managed dataspace replaces
|
||||||
|
* the inital reserved area, which is therefore flushed beforehand. Hybrid
|
||||||
|
* programs have no context area.
|
||||||
|
*
|
||||||
|
* Note, we do not support nesting of managed dataspaces.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -15,6 +36,7 @@
|
|||||||
#include <base/thread.h>
|
#include <base/thread.h>
|
||||||
#include <linux_dataspace/client.h>
|
#include <linux_dataspace/client.h>
|
||||||
#include <linux_syscalls.h>
|
#include <linux_syscalls.h>
|
||||||
|
#include <context_area.h>
|
||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
#include <platform_env.h>
|
#include <platform_env.h>
|
||||||
@ -31,18 +53,66 @@ static bool is_sub_rm_session(Dataspace_capability ds)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
addr_t Platform_env_base::Rm_session_mmap::_reserve_local(bool use_local_addr,
|
||||||
|
addr_t local_addr,
|
||||||
|
Genode::size_t size)
|
||||||
|
{
|
||||||
|
/* special handling for context area */
|
||||||
|
if (use_local_addr
|
||||||
|
&& local_addr == Native_config::context_area_virtual_base()
|
||||||
|
&& size == Native_config::context_area_virtual_size()) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On the first request to reserve the context area, we flush the
|
||||||
|
* initial mapping preserved in linker script and apply the actual
|
||||||
|
* reservation. Subsequent requests are just ignored.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static struct Context
|
||||||
|
{
|
||||||
|
Context()
|
||||||
|
{
|
||||||
|
flush_context_area();
|
||||||
|
reserve_context_area();
|
||||||
|
}
|
||||||
|
} inst;
|
||||||
|
|
||||||
|
return local_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int const flags = MAP_ANONYMOUS | MAP_PRIVATE;
|
||||||
|
int const prot = PROT_NONE;
|
||||||
|
void * const addr_in = use_local_addr ? (void *)local_addr : 0;
|
||||||
|
void * const addr_out = lx_mmap(addr_in, size, prot, flags, -1, 0);
|
||||||
|
|
||||||
|
/* reserve at local address failed - unmap incorrect mapping */
|
||||||
|
if (use_local_addr && addr_in != addr_out)
|
||||||
|
lx_munmap((void *)addr_out, size);
|
||||||
|
|
||||||
|
if ((use_local_addr && addr_in != addr_out)
|
||||||
|
|| (((long)addr_out < 0) && ((long)addr_out > -4095))) {
|
||||||
|
PERR("_reserve_local: lx_mmap failed (addr_in=%p,addr_out=%p/%ld)",
|
||||||
|
addr_in, addr_out, (long)addr_out);
|
||||||
|
throw Rm_session::Region_conflict();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (addr_t) addr_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void *
|
void *
|
||||||
Platform_env_base::Rm_session_mmap::_map_local(Dataspace_capability ds,
|
Platform_env_base::Rm_session_mmap::_map_local(Dataspace_capability ds,
|
||||||
Genode::size_t size,
|
Genode::size_t size,
|
||||||
addr_t offset,
|
addr_t offset,
|
||||||
bool use_local_addr,
|
bool use_local_addr,
|
||||||
addr_t local_addr,
|
addr_t local_addr,
|
||||||
bool executable)
|
bool executable,
|
||||||
|
bool overmap)
|
||||||
{
|
{
|
||||||
int const fd = _dataspace_fd(ds);
|
int const fd = _dataspace_fd(ds);
|
||||||
bool const writable = _dataspace_writable(ds);
|
bool const writable = _dataspace_writable(ds);
|
||||||
|
|
||||||
int const flags = MAP_SHARED | (use_local_addr ? MAP_FIXED : 0);
|
int const flags = MAP_SHARED | (overmap ? MAP_FIXED : 0);
|
||||||
int const prot = PROT_READ
|
int const prot = PROT_READ
|
||||||
| (writable ? PROT_WRITE : 0)
|
| (writable ? PROT_WRITE : 0)
|
||||||
| (executable ? PROT_EXEC : 0);
|
| (executable ? PROT_EXEC : 0);
|
||||||
@ -57,8 +127,14 @@ Platform_env_base::Rm_session_mmap::_map_local(Dataspace_capability ds,
|
|||||||
*/
|
*/
|
||||||
lx_close(fd);
|
lx_close(fd);
|
||||||
|
|
||||||
if (((long)addr_out < 0) && ((long)addr_out > -4095)) {
|
/* attach at local address failed - unmap incorrect mapping */
|
||||||
PERR("_map_local: return value of mmap is %ld", (long)addr_out);
|
if (use_local_addr && addr_in != addr_out)
|
||||||
|
lx_munmap((void *)addr_out, size);
|
||||||
|
|
||||||
|
if ((use_local_addr && addr_in != addr_out)
|
||||||
|
|| (((long)addr_out < 0) && ((long)addr_out > -4095))) {
|
||||||
|
PERR("_map_local: lx_mmap failed (addr_in=%p,addr_out=%p/%ld) overmap=%d",
|
||||||
|
addr_in, addr_out, (long)addr_out, overmap);
|
||||||
throw Rm_session::Region_conflict();
|
throw Rm_session::Region_conflict();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,11 +218,12 @@ Platform_env::Rm_session_mmap::attach(Dataspace_capability ds,
|
|||||||
* Case 3.1
|
* Case 3.1
|
||||||
*
|
*
|
||||||
* This RM session is a sub RM session. If the sub RM session is
|
* This RM session is a sub RM session. If the sub RM session is
|
||||||
* attached (_base > 0), add its attachement offset to the local base
|
* attached (_base > 0), add its attachment offset to the local base
|
||||||
* and map it.
|
* and map it. We have to enforce the mapping via the 'overmap'
|
||||||
|
* argument as the region was reserved by a PROT_NONE mapping.
|
||||||
*/
|
*/
|
||||||
if (_is_attached())
|
if (_is_attached())
|
||||||
_map_local(ds, region_size, offset, true, _base + (addr_t)local_addr, executable);
|
_map_local(ds, region_size, offset, true, _base + (addr_t)local_addr, executable, true);
|
||||||
|
|
||||||
return (void *)local_addr;
|
return (void *)local_addr;
|
||||||
|
|
||||||
@ -171,20 +248,19 @@ Platform_env::Rm_session_mmap::attach(Dataspace_capability ds,
|
|||||||
throw Out_of_metadata();
|
throw Out_of_metadata();
|
||||||
}
|
}
|
||||||
|
|
||||||
_add_to_rmap(Region(local_addr, offset, ds, region_size));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate local address range that can hold the entire sub RM
|
* Reserve local address range that can hold the entire sub RM
|
||||||
* session.
|
* session.
|
||||||
*/
|
*/
|
||||||
rm->_base = lx_vm_reserve(use_local_addr ? (addr_t)local_addr : 0,
|
rm->_base = _reserve_local(use_local_addr, local_addr, region_size);
|
||||||
region_size);
|
|
||||||
|
_add_to_rmap(Region(rm->_base, offset, ds, region_size));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cases 2.2, 3.2
|
* Cases 2.2, 3.2
|
||||||
*
|
*
|
||||||
* The sub rm session was not attached until now but it may have
|
* The sub rm session was not attached until now but it may have
|
||||||
* been populated with dataspaces. Go through all regions an map
|
* been populated with dataspaces. Go through all regions and map
|
||||||
* each of them.
|
* each of them.
|
||||||
*/
|
*/
|
||||||
for (int i = 0; i < Region_map::MAX_REGIONS; i++) {
|
for (int i = 0; i < Region_map::MAX_REGIONS; i++) {
|
||||||
@ -192,9 +268,13 @@ Platform_env::Rm_session_mmap::attach(Dataspace_capability ds,
|
|||||||
if (!region.used())
|
if (!region.used())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We have to enforce the mapping via the 'overmap' argument as
|
||||||
|
* the region was reserved by a PROT_NONE mapping.
|
||||||
|
*/
|
||||||
_map_local(region.dataspace(), region.size(), region.offset(),
|
_map_local(region.dataspace(), region.size(), region.offset(),
|
||||||
true, rm->_base + region.start() + region.offset(),
|
true, rm->_base + region.start() + region.offset(),
|
||||||
executable);
|
executable, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rm->_base;
|
return rm->_base;
|
||||||
@ -205,6 +285,7 @@ Platform_env::Rm_session_mmap::attach(Dataspace_capability ds,
|
|||||||
* Case 1
|
* Case 1
|
||||||
*
|
*
|
||||||
* Boring, a plain dataspace is attached to a root RM session.
|
* Boring, a plain dataspace is attached to a root RM session.
|
||||||
|
* Note, we do not overmap.
|
||||||
*/
|
*/
|
||||||
void *addr = _map_local(ds, region_size, offset, use_local_addr,
|
void *addr = _map_local(ds, region_size, offset, use_local_addr,
|
||||||
local_addr, executable);
|
local_addr, executable);
|
||||||
@ -252,8 +333,10 @@ void Platform_env::Rm_session_mmap::detach(Rm_session::Local_addr local_addr)
|
|||||||
* If we are not attached, no local address-space manipulation is
|
* If we are not attached, no local address-space manipulation is
|
||||||
* needed.
|
* needed.
|
||||||
*/
|
*/
|
||||||
if (_is_attached())
|
if (_is_attached()) {
|
||||||
lx_vm_reserve((addr_t)local_addr + _base, region.size());
|
lx_munmap((void *)((addr_t)local_addr + _base), region.size());
|
||||||
|
_reserve_local(true, (addr_t)local_addr + _base, region.size());
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -277,5 +360,4 @@ void Platform_env::Rm_session_mmap::detach(Rm_session::Local_addr local_addr)
|
|||||||
if (rm)
|
if (rm)
|
||||||
rm->_base = 0;
|
rm->_base = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,7 @@
|
|||||||
#include <base/printf.h>
|
#include <base/printf.h>
|
||||||
#include <base/thread.h>
|
#include <base/thread.h>
|
||||||
|
|
||||||
/* Linux includes */
|
#include <context_area.h>
|
||||||
#include <linux_syscalls.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -34,6 +32,12 @@ class Context_area_rm_session : public Genode::Rm_session
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
Context_area_rm_session()
|
||||||
|
{
|
||||||
|
flush_context_area();
|
||||||
|
reserve_context_area();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attach backing store to thread-context area
|
* Attach backing store to thread-context area
|
||||||
*/
|
*/
|
||||||
|
64
base-linux/src/platform/context_area.h
Normal file
64
base-linux/src/platform/context_area.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* \brief Linux-specific utilities for context area
|
||||||
|
* \author Christian Helmuth
|
||||||
|
* \date 2013-09-26
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2010-2013 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU General Public License version 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PLATFORM__CONTEXT_AREA_H_
|
||||||
|
#define _PLATFORM__CONTEXT_AREA_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <base/thread.h>
|
||||||
|
#include <rm_session/rm_session.h>
|
||||||
|
|
||||||
|
#include <linux_syscalls.h>
|
||||||
|
|
||||||
|
/* Linux includes */
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
|
||||||
|
static inline void flush_context_area()
|
||||||
|
{
|
||||||
|
using namespace Genode;
|
||||||
|
|
||||||
|
void * const base = (void *) Native_config::context_area_virtual_base();
|
||||||
|
size_t const size = Native_config::context_area_virtual_size();
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
if ((ret = lx_munmap(base, size)) < 0) {
|
||||||
|
PERR("%s: failed ret=%d", __func__, ret);
|
||||||
|
throw Rm_session::Region_conflict();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline Genode::addr_t reserve_context_area()
|
||||||
|
{
|
||||||
|
using namespace Genode;
|
||||||
|
|
||||||
|
int const flags = MAP_ANONYMOUS | MAP_PRIVATE;
|
||||||
|
int const prot = PROT_NONE;
|
||||||
|
size_t const size = Native_config::context_area_virtual_size();
|
||||||
|
void * const addr_in = (void *)Native_config::context_area_virtual_base();
|
||||||
|
void * const addr_out = lx_mmap(addr_in, size, prot, flags, -1, 0);
|
||||||
|
|
||||||
|
/* reserve at local address failed - unmap incorrect mapping */
|
||||||
|
if (addr_in != addr_out) {
|
||||||
|
lx_munmap((void *)addr_out, size);
|
||||||
|
|
||||||
|
PERR("%s: failed addr_in=%p addr_out=%p ret=%ld)", __func__,
|
||||||
|
addr_in, addr_out, (long)addr_out);
|
||||||
|
throw Rm_session::Region_conflict();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (addr_t) addr_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _PLATFORM__CONTEXT_AREA_H_ */
|
@ -203,36 +203,6 @@ inline int lx_munmap(void *addr, size_t length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exclude local virtual memory area from being used by mmap
|
|
||||||
*
|
|
||||||
* \param base base address of area to reserve
|
|
||||||
* \param size number of bytes to reserve
|
|
||||||
*
|
|
||||||
* \return start of allocated reserved area, or ~0 on failure
|
|
||||||
*/
|
|
||||||
inline Genode::addr_t lx_vm_reserve(Genode::addr_t base, Genode::size_t size)
|
|
||||||
{
|
|
||||||
/* we cannot include sys/mman.h from here */
|
|
||||||
enum {
|
|
||||||
LX_MAP_PRIVATE = 0x02,
|
|
||||||
LX_MAP_FIXED = 0x10,
|
|
||||||
LX_MAP_ANONYMOUS = 0x20,
|
|
||||||
LX_PROT_NONE = 0x0
|
|
||||||
};
|
|
||||||
|
|
||||||
int const flags = LX_MAP_ANONYMOUS | LX_MAP_PRIVATE
|
|
||||||
| (base ? LX_MAP_FIXED : 0);
|
|
||||||
|
|
||||||
void * const res = lx_mmap((void *)base, size, LX_PROT_NONE, flags, -1, 0);
|
|
||||||
|
|
||||||
if (base)
|
|
||||||
return ((Genode::addr_t)res == base) ? base : ~0;
|
|
||||||
else
|
|
||||||
return (Genode::addr_t)res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
** Functions used by thread lib and core's cancel-blocking mechanism **
|
** Functions used by thread lib and core's cancel-blocking mechanism **
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
@ -56,16 +56,6 @@ void Genode::platform_main_bootstrap()
|
|||||||
* __initial_sp[3] = environ
|
* __initial_sp[3] = environ
|
||||||
*/
|
*/
|
||||||
lx_environ = (char**)&__initial_sp[3];
|
lx_environ = (char**)&__initial_sp[3];
|
||||||
|
|
||||||
/*
|
|
||||||
* Free context area preserved in linker script
|
|
||||||
*/
|
|
||||||
addr_t base = Native_config::context_area_virtual_base();
|
|
||||||
Genode::size_t size = Native_config::context_area_virtual_size();
|
|
||||||
int ret;
|
|
||||||
if ((ret = lx_munmap((void *)base, size)) < 0)
|
|
||||||
PERR("flushing of context area [%lx,%lx) failed (ret=%d)",
|
|
||||||
(unsigned long) base, (unsigned long) base + size, ret);
|
|
||||||
}
|
}
|
||||||
} bootstrap;
|
} bootstrap;
|
||||||
}
|
}
|
||||||
|
5
base-linux/src/test/lx_rmap/dynamic/target.mk
Normal file
5
base-linux/src/test/lx_rmap/dynamic/target.mk
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
TARGET = test-lx_rmap_dynamic
|
||||||
|
SRC_CC = main.cc
|
||||||
|
LIBS = base libc
|
||||||
|
|
||||||
|
vpath main.cc $(PRG_DIR)/..
|
89
base-linux/src/test/lx_rmap/main.cc
Normal file
89
base-linux/src/test/lx_rmap/main.cc
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* \brief Linux region-map test
|
||||||
|
* \author Christian Helmuth
|
||||||
|
* \date 2013-09-06
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2006-2013 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU General Public License version 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <base/printf.h>
|
||||||
|
#include <base/env.h>
|
||||||
|
#include <base/crt0.h>
|
||||||
|
#include <base/sleep.h>
|
||||||
|
#include <base/thread.h>
|
||||||
|
#include <util/misc_math.h>
|
||||||
|
#include <rm_session/connection.h>
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" void wait_for_continue();
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
using namespace Genode;
|
||||||
|
|
||||||
|
/* activate for early printf in Rm_session_mmap::attach() etc. */
|
||||||
|
if (0) Thread_base::trace("FOO");
|
||||||
|
|
||||||
|
/* induce initial heap expansion to remove RM noise */
|
||||||
|
if (1) {
|
||||||
|
void *addr(env()->heap()->alloc(0x100000));
|
||||||
|
env()->heap()->free(addr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
addr_t beg((addr_t)&_prog_img_beg);
|
||||||
|
addr_t end(align_addr((addr_t)&_prog_img_end, 12));
|
||||||
|
|
||||||
|
size_t size(end - beg);
|
||||||
|
|
||||||
|
PLOG("program-image region [%016lx,%016lx) size=%zx", beg, end, size);
|
||||||
|
|
||||||
|
/* RAM dataspace attachment overlapping binary */
|
||||||
|
try {
|
||||||
|
Ram_dataspace_capability ds(env()->ram_session()->alloc(size));
|
||||||
|
|
||||||
|
PLOG("before RAM dataspace attach");
|
||||||
|
env()->rm_session()->attach_at(ds, beg);
|
||||||
|
PERR("after RAM dataspace attach -- ERROR");
|
||||||
|
} catch (Rm_session::Region_conflict) {
|
||||||
|
PLOG("OK caught Region_conflict exception");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* empty managed dataspace overlapping binary */
|
||||||
|
try {
|
||||||
|
Rm_connection rm(0, size);
|
||||||
|
Dataspace_capability ds(rm.dataspace());
|
||||||
|
|
||||||
|
PLOG("before sub-RM dataspace attach");
|
||||||
|
env()->rm_session()->attach_at(ds, beg);
|
||||||
|
PERR("after sub-RM dataspace attach -- ERROR");
|
||||||
|
} catch (Rm_session::Region_conflict) {
|
||||||
|
PLOG("OK caught Region_conflict exception");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sparsely populated managed dataspace in free VM area */
|
||||||
|
try {
|
||||||
|
Rm_connection rm(0, 0x100000);
|
||||||
|
|
||||||
|
rm.attach_at(env()->ram_session()->alloc(0x1000), 0x1000);
|
||||||
|
|
||||||
|
Dataspace_capability ds(rm.dataspace());
|
||||||
|
|
||||||
|
PLOG("before populated sub-RM dataspace attach");
|
||||||
|
char *addr = (char *)env()->rm_session()->attach(ds) + 0x1000;
|
||||||
|
PLOG("after populated sub-RM dataspace attach / before touch");
|
||||||
|
char const val = *addr;
|
||||||
|
*addr = 0x55;
|
||||||
|
PLOG("after touch (%x/%x)", val, *addr);
|
||||||
|
} catch (Rm_session::Region_conflict) {
|
||||||
|
PLOG("OK caught Region_conflict exception -- ERROR");
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep_forever();
|
||||||
|
}
|
5
base-linux/src/test/lx_rmap/static/target.mk
Normal file
5
base-linux/src/test/lx_rmap/static/target.mk
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
TARGET = test-lx_rmap_static
|
||||||
|
SRC_CC = main.cc
|
||||||
|
LIBS = base
|
||||||
|
|
||||||
|
vpath main.cc $(PRG_DIR)/..
|
Loading…
Reference in New Issue
Block a user