6b289a1423
This patch replaces the former prominent use of pointers by references wherever feasible. This has the following benefits: * The contract between caller and callee becomes more obvious. When passing a reference, the contract says that the argument cannot be a null pointer. The caller is responsible to ensure that. Therefore, the use of reference eliminates the need to add defensive null-pointer checks at the callee site, which sometimes merely exist to be on the safe side. The bottom line is that the code becomes easier to follow. * Reference members must be initialized via an object initializer, which promotes a programming style that avoids intermediate object- construction states. Within core, there are still a few pointers as member variables left though. E.g., caused by the late association of 'Platform_thread' objects with their 'Platform_pd' objects. * If no pointers are present as member variables, we don't need to manually provide declarations of a private copy constructor and an assignment operator to avoid -Weffc++ errors "class ... has pointer data members [-Werror=effc++]". This patch also changes a few system bindings on NOVA and Fiasco.OC, e.g., the return value of the global 'cap_map' accessor has become a reference. Hence, the patch touches a few places outside of core. Fixes #3135
207 lines
5.3 KiB
C++
207 lines
5.3 KiB
C++
/*
|
|
* \brief Instance of the core-local (Genode) capability space
|
|
* \author Norman Feske
|
|
* \date 2015-05-08
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2015-2017 Genode Labs GmbH
|
|
*
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
* under the terms of the GNU Affero General Public License version 3.
|
|
*/
|
|
|
|
/* base includes */
|
|
#include <base/capability.h>
|
|
|
|
/* base-internal includes */
|
|
#include <base/internal/capability_data.h>
|
|
#include <base/internal/capability_space_sel4.h>
|
|
|
|
/* core includes */
|
|
#include <core_capability_space.h>
|
|
#include <platform.h>
|
|
|
|
|
|
/**
|
|
* Core-specific supplement of the capability meta data
|
|
*/
|
|
class Genode::Native_capability::Data : public Capability_data
|
|
{
|
|
private:
|
|
|
|
Pd_session const *_pd_session = nullptr;
|
|
|
|
public:
|
|
|
|
Data(Pd_session const *pd_session, Rpc_obj_key key)
|
|
:
|
|
Capability_data(key), _pd_session(pd_session)
|
|
{ }
|
|
|
|
Data() { }
|
|
|
|
bool belongs_to(Pd_session const *session) const
|
|
{
|
|
return _pd_session == session;
|
|
}
|
|
};
|
|
|
|
|
|
using namespace Genode;
|
|
|
|
|
|
/**
|
|
* Singleton instance of core-specific capability space
|
|
*/
|
|
namespace {
|
|
|
|
struct Local_capability_space
|
|
:
|
|
Capability_space_sel4<1UL << Core_cspace::NUM_CORE_SEL_LOG2, 0UL,
|
|
Native_capability::Data>
|
|
{ };
|
|
|
|
static Local_capability_space &local_capability_space()
|
|
{
|
|
static Local_capability_space capability_space;
|
|
return capability_space;
|
|
}
|
|
}
|
|
|
|
|
|
/********************************************************************
|
|
** Implementation of the core-specific Capability_space interface **
|
|
********************************************************************/
|
|
|
|
Native_capability
|
|
Capability_space::create_rpc_obj_cap(Native_capability ep_cap,
|
|
Pd_session const *pd_session,
|
|
Rpc_obj_key rpc_obj_key)
|
|
{
|
|
/* allocate core-local selector for RPC object */
|
|
Cap_sel const rpc_obj_sel = platform_specific().core_sel_alloc().alloc();
|
|
|
|
/* create Genode capability */
|
|
Native_capability::Data &data =
|
|
local_capability_space().create_capability(rpc_obj_sel, pd_session,
|
|
rpc_obj_key);
|
|
|
|
ASSERT(ep_cap.valid());
|
|
|
|
Cap_sel const ep_sel(local_capability_space().sel(*ep_cap.data()));
|
|
|
|
/* mint endpoint capability into RPC object capability */
|
|
{
|
|
seL4_CNode const service = seL4_CapInitThreadCNode;
|
|
seL4_Word const dest_index = rpc_obj_sel.value();
|
|
uint8_t const dest_depth = 32;
|
|
seL4_CNode const src_root = seL4_CapInitThreadCNode;
|
|
seL4_Word const src_index = ep_sel.value();
|
|
uint8_t const src_depth = 32;
|
|
seL4_CapRights_t const rights = seL4_AllRights;
|
|
seL4_Word const badge = rpc_obj_key.value();
|
|
|
|
int const ret = seL4_CNode_Mint(service,
|
|
dest_index,
|
|
dest_depth,
|
|
src_root,
|
|
src_index,
|
|
src_depth,
|
|
rights,
|
|
badge);
|
|
ASSERT(ret == seL4_NoError);
|
|
}
|
|
|
|
return Native_capability(&data);
|
|
}
|
|
|
|
|
|
/******************************************************
|
|
** Implementation of the Capability_space interface **
|
|
******************************************************/
|
|
|
|
Native_capability Capability_space::create_ep_cap(Thread &ep_thread)
|
|
{
|
|
Cap_sel const ep_sel(ep_thread.native_thread().ep_sel);
|
|
|
|
/* entrypoint capabilities are not allocated from a PD session */
|
|
Pd_session const *pd_session = nullptr;
|
|
|
|
Native_capability::Data &data =
|
|
local_capability_space().create_capability(ep_sel, pd_session,
|
|
Rpc_obj_key());
|
|
|
|
return Native_capability(&data);
|
|
}
|
|
|
|
|
|
void Capability_space::dec_ref(Native_capability::Data &data)
|
|
{
|
|
local_capability_space().dec_ref(data);
|
|
}
|
|
|
|
|
|
void Capability_space::inc_ref(Native_capability::Data &data)
|
|
{
|
|
local_capability_space().inc_ref(data);
|
|
}
|
|
|
|
|
|
Rpc_obj_key Capability_space::rpc_obj_key(Native_capability::Data const &data)
|
|
{
|
|
return local_capability_space().rpc_obj_key(data);
|
|
}
|
|
|
|
|
|
Capability_space::Ipc_cap_data Capability_space::ipc_cap_data(Native_capability const &cap)
|
|
{
|
|
return local_capability_space().ipc_cap_data(*cap.data());
|
|
}
|
|
|
|
|
|
Native_capability Capability_space::lookup(Rpc_obj_key rpc_obj_key)
|
|
{
|
|
Native_capability::Data *data = local_capability_space().lookup(rpc_obj_key);
|
|
|
|
return data ? Native_capability(data) : Native_capability();
|
|
}
|
|
|
|
|
|
unsigned Capability_space::alloc_rcv_sel()
|
|
{
|
|
return platform_specific().alloc_core_rcv_sel();
|
|
}
|
|
|
|
|
|
void Capability_space::reset_sel(unsigned sel)
|
|
{
|
|
return platform_specific().reset_sel(sel);
|
|
}
|
|
|
|
|
|
Native_capability Capability_space::import(Ipc_cap_data ipc_cap_data)
|
|
{
|
|
/* imported capabilities are not associated with a PD session */
|
|
Pd_session const *pd_session = nullptr;
|
|
|
|
Native_capability::Data &data =
|
|
local_capability_space().create_capability(ipc_cap_data.sel, pd_session,
|
|
ipc_cap_data.rpc_obj_key);
|
|
|
|
return Native_capability(&data);
|
|
}
|
|
|
|
|
|
Native_capability
|
|
Capability_space::create_notification_cap(Cap_sel ¬ify_cap)
|
|
{
|
|
Pd_session const *pd_session = nullptr;
|
|
|
|
Native_capability::Data &data =
|
|
local_capability_space().create_capability(notify_cap, pd_session,
|
|
Rpc_obj_key());
|
|
|
|
return Native_capability(&data);
|
|
}
|