2011-12-22 16:19:25 +01:00
|
|
|
/*
|
|
|
|
* \brief Support for the Linux-specific environment
|
|
|
|
* \author Norman Feske
|
|
|
|
* \date 2008-12-12
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2017-02-20 13:23:52 +01:00
|
|
|
* Copyright (C) 2008-2017 Genode Labs GmbH
|
2011-12-22 16:19:25 +01:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
2017-02-20 13:23:52 +01:00
|
|
|
* under the terms of the GNU Affero General Public License version 3.
|
2011-12-22 16:19:25 +01:00
|
|
|
*/
|
|
|
|
|
2013-02-13 21:46:19 +01:00
|
|
|
/* Genode includes */
|
2011-12-22 16:19:25 +01:00
|
|
|
#include <util/arg_string.h>
|
2012-08-09 16:52:47 +02:00
|
|
|
#include <base/thread.h>
|
2012-12-04 16:51:24 +01:00
|
|
|
#include <linux_dataspace/client.h>
|
2012-11-15 12:53:32 +01:00
|
|
|
#include <linux_syscalls.h>
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2016-01-20 18:27:18 +01:00
|
|
|
/* base-internal includes */
|
|
|
|
#include <base/internal/platform_env.h>
|
2016-03-18 22:53:25 +01:00
|
|
|
#include <base/internal/native_thread.h>
|
2016-04-29 22:58:59 +02:00
|
|
|
#include <base/internal/globals.h>
|
2016-06-13 13:53:58 +02:00
|
|
|
#include <base/internal/parent_socket_handle.h>
|
2016-06-15 15:04:54 +02:00
|
|
|
#include <base/internal/capability_space_tpl.h>
|
2013-01-03 16:23:11 +01:00
|
|
|
|
2013-02-13 21:46:19 +01:00
|
|
|
using namespace Genode;
|
2013-01-03 16:23:11 +01:00
|
|
|
|
|
|
|
|
2012-12-04 16:51:24 +01:00
|
|
|
/****************************************************
|
|
|
|
** Support for Platform_env_base::Rm_session_mmap **
|
|
|
|
****************************************************/
|
|
|
|
|
2016-04-29 22:58:59 +02:00
|
|
|
size_t Region_map_mmap::_dataspace_size(Dataspace_capability ds)
|
2012-12-04 16:51:24 +01:00
|
|
|
{
|
2016-06-15 15:04:54 +02:00
|
|
|
if (local(ds))
|
|
|
|
return Local_capability<Dataspace>::deref(ds)->size();
|
|
|
|
|
|
|
|
return Dataspace_client(ds).size();
|
2012-12-04 16:51:24 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-04-29 22:58:59 +02:00
|
|
|
int Region_map_mmap::_dataspace_fd(Dataspace_capability ds)
|
2012-12-04 16:51:24 +01:00
|
|
|
{
|
2016-06-15 15:04:54 +02:00
|
|
|
Untyped_capability fd_cap = Linux_dataspace_client(ds).fd();
|
|
|
|
return Capability_space::ipc_cap_data(fd_cap).dst.socket;
|
2012-12-04 16:51:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-04-29 22:58:59 +02:00
|
|
|
bool Region_map_mmap::_dataspace_writable(Dataspace_capability ds)
|
2012-12-04 16:51:24 +01:00
|
|
|
{
|
|
|
|
return Dataspace_client(ds).writable();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-04-15 15:19:22 +02:00
|
|
|
|
2016-04-29 22:58:59 +02:00
|
|
|
/******************
|
|
|
|
** Local_parent **
|
|
|
|
******************/
|
2013-11-12 19:55:05 +01:00
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
Session_capability Local_parent::session(Parent::Client::Id id,
|
|
|
|
Service_name const &service_name,
|
2016-04-29 22:58:59 +02:00
|
|
|
Session_args const &args,
|
|
|
|
Affinity const &affinity)
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
2016-11-06 14:26:34 +01:00
|
|
|
if (strcmp(service_name.string(), Rm_session::service_name()) == 0) {
|
|
|
|
|
|
|
|
Local_rm_session *local_rm_session = new (_alloc)
|
|
|
|
Local_rm_session(_alloc, _local_sessions_id_space, id);
|
2013-11-12 19:55:05 +01:00
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
return local_rm_session->local_session_cap();
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
return Expanding_parent_client::session(id, service_name, args, affinity);
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
Parent::Close_result Local_parent::close(Client::Id id)
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
2016-11-06 14:26:34 +01:00
|
|
|
auto close_local_fn = [&] (Local_session &local_session)
|
|
|
|
{
|
|
|
|
Capability<Rm_session> rm =
|
|
|
|
static_cap_cast<Rm_session>(local_session.local_session_cap());
|
|
|
|
destroy(_alloc, Local_capability<Rm_session>::deref(rm));
|
|
|
|
};
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
/*
|
2016-11-06 14:26:34 +01:00
|
|
|
* Local RM sessions are present in the '_local_sessions_id_space'. If the
|
|
|
|
* apply succeeds, 'id' referred to the local session. Otherwise, we
|
|
|
|
* forward the request to the parent.
|
2011-12-22 16:19:25 +01:00
|
|
|
*/
|
2016-11-06 14:26:34 +01:00
|
|
|
try {
|
|
|
|
_local_sessions_id_space.apply<Local_session>(id, close_local_fn);
|
|
|
|
return CLOSE_DONE;
|
|
|
|
}
|
|
|
|
catch (Id_space<Client>::Unknown_id) { }
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
return Parent_client::close(id);
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-04-29 22:58:59 +02:00
|
|
|
Local_parent::Local_parent(Parent_capability parent_cap,
|
|
|
|
Emergency_ram_reserve &reserve,
|
|
|
|
Allocator &alloc)
|
2015-12-23 15:22:33 +01:00
|
|
|
:
|
|
|
|
Expanding_parent_client(parent_cap, reserve), _alloc(alloc)
|
2013-09-25 17:59:17 +02:00
|
|
|
{ }
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
|
|
|
|
/******************
|
|
|
|
** Platform_env **
|
|
|
|
******************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* List of Unix environment variables, initialized by the startup code
|
|
|
|
*/
|
|
|
|
extern char **lx_environ;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Read environment variable as long value
|
|
|
|
*/
|
2012-12-04 16:51:24 +01:00
|
|
|
static unsigned long get_env_ulong(const char *key)
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
|
|
|
for (char **curr = lx_environ; curr && *curr; curr++) {
|
|
|
|
|
|
|
|
Arg arg = Arg_string::find_arg(*curr, key);
|
|
|
|
if (arg.valid())
|
|
|
|
return arg.ulong_value(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2012-08-09 16:52:47 +02:00
|
|
|
|
|
|
|
|
2012-12-04 16:51:24 +01:00
|
|
|
static Parent_capability obtain_parent_cap()
|
|
|
|
{
|
2016-06-15 15:04:54 +02:00
|
|
|
long const local_name = get_env_ulong("parent_local_name");
|
|
|
|
|
|
|
|
Untyped_capability parent_cap =
|
|
|
|
Capability_space::import(Rpc_destination(PARENT_SOCKET_HANDLE),
|
|
|
|
Rpc_obj_key(local_name));
|
2012-12-04 16:51:24 +01:00
|
|
|
|
2016-06-15 15:04:54 +02:00
|
|
|
return reinterpret_cap_cast<Parent>(parent_cap);
|
2012-12-04 16:51:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-04-29 22:58:59 +02:00
|
|
|
Local_parent &Platform_env::_parent()
|
2012-12-04 16:51:24 +01:00
|
|
|
{
|
2015-12-23 15:22:33 +01:00
|
|
|
static Local_parent local_parent(obtain_parent_cap(), *this, _heap);
|
2012-12-04 16:51:24 +01:00
|
|
|
return local_parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-01-03 16:23:11 +01:00
|
|
|
Platform_env::Platform_env()
|
|
|
|
:
|
2016-11-06 14:26:34 +01:00
|
|
|
Platform_env_base(static_cap_cast<Ram_session>(_parent().session_cap(Parent::Env::ram())),
|
|
|
|
static_cap_cast<Cpu_session>(_parent().session_cap(Parent::Env::cpu())),
|
|
|
|
static_cap_cast<Pd_session> (_parent().session_cap(Parent::Env::pd()))),
|
2013-09-25 17:59:17 +02:00
|
|
|
_heap(Platform_env_base::ram_session(), Platform_env_base::rm_session()),
|
|
|
|
_emergency_ram_ds(ram_session()->alloc(_emergency_ram_size()))
|
2013-01-03 16:23:11 +01:00
|
|
|
{
|
2016-07-06 18:10:23 +02:00
|
|
|
_attach_stack_area();
|
2016-04-15 15:19:22 +02:00
|
|
|
|
2017-05-11 19:39:46 +02:00
|
|
|
env_stack_area_region_map = &_local_pd_session._stack_area;
|
|
|
|
env_stack_area_ram_allocator = ram_session();
|
2015-12-23 15:22:33 +01:00
|
|
|
|
2013-01-03 16:23:11 +01:00
|
|
|
/* register TID and PID of the main thread at core */
|
2016-03-30 15:34:37 +02:00
|
|
|
Linux_native_cpu_client native_cpu(cpu_session()->native_cpu());
|
|
|
|
native_cpu.thread_id(parent()->main_thread_cap(), lx_getpid(), lx_gettid());
|
2013-01-03 16:23:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-08-09 16:52:47 +02:00
|
|
|
/*****************************
|
|
|
|
** Support for IPC library **
|
|
|
|
*****************************/
|
|
|
|
|
|
|
|
namespace Genode {
|
|
|
|
|
2016-03-18 22:53:25 +01:00
|
|
|
Socket_pair server_socket_pair()
|
2012-08-09 16:52:47 +02:00
|
|
|
{
|
2017-01-09 15:18:49 +01:00
|
|
|
Linux_native_cpu_client native_cpu(env_deprecated()->cpu_session()->native_cpu());
|
2012-08-09 16:52:47 +02:00
|
|
|
|
2016-03-18 22:53:25 +01:00
|
|
|
Socket_pair socket_pair;
|
2012-08-09 16:52:47 +02:00
|
|
|
|
2016-05-04 12:27:17 +02:00
|
|
|
Thread *thread = Thread::myself();
|
2012-08-09 16:52:47 +02:00
|
|
|
if (thread) {
|
2016-06-15 15:04:54 +02:00
|
|
|
Untyped_capability server_cap = native_cpu.server_sd(thread->cap());
|
|
|
|
Untyped_capability client_cap = native_cpu.client_sd(thread->cap());
|
|
|
|
socket_pair.server_sd = Capability_space::ipc_cap_data(server_cap).dst.socket;
|
|
|
|
socket_pair.client_sd = Capability_space::ipc_cap_data(client_cap).dst.socket;
|
2016-03-18 22:53:25 +01:00
|
|
|
thread->native_thread().socket_pair = socket_pair;
|
2012-08-09 16:52:47 +02:00
|
|
|
}
|
2016-03-18 22:53:25 +01:00
|
|
|
return socket_pair;
|
2012-08-09 16:52:47 +02:00
|
|
|
}
|
2012-11-15 12:53:32 +01:00
|
|
|
|
2016-03-18 22:53:25 +01:00
|
|
|
void destroy_server_socket_pair(Socket_pair socket_pair)
|
2012-11-15 12:53:32 +01:00
|
|
|
{
|
|
|
|
/* close local file descriptor if it is valid */
|
2016-03-18 22:53:25 +01:00
|
|
|
if (socket_pair.server_sd != -1) lx_close(socket_pair.server_sd);
|
|
|
|
if (socket_pair.client_sd != -1) lx_close(socket_pair.client_sd);
|
2012-11-15 12:53:32 +01:00
|
|
|
}
|
2012-08-09 16:52:47 +02:00
|
|
|
}
|