2013-02-11 11:44:04 +01:00
|
|
|
/*
|
|
|
|
* \brief Extension of core implementation of the PD session interface
|
|
|
|
* \author Alexander Boettcher
|
|
|
|
* \date 2013-01-11
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2017-02-20 13:23:52 +01:00
|
|
|
* Copyright (C) 2013-2017 Genode Labs GmbH
|
2013-02-11 11:44:04 +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.
|
2013-02-11 11:44:04 +01:00
|
|
|
*/
|
|
|
|
|
base/core: use references instead of pointers
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
2019-01-24 22:00:01 +01:00
|
|
|
/* core */
|
2013-02-11 11:44:04 +01:00
|
|
|
#include <pd_session_component.h>
|
base/core: use references instead of pointers
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
2019-01-24 22:00:01 +01:00
|
|
|
#include <assertion.h>
|
2013-02-11 11:44:04 +01:00
|
|
|
|
|
|
|
using namespace Genode;
|
|
|
|
|
|
|
|
|
2016-01-08 16:21:48 +01:00
|
|
|
bool Pd_session_component::assign_pci(addr_t pci_config_memory, uint16_t bdf)
|
2013-02-11 11:44:04 +01:00
|
|
|
{
|
2016-11-28 10:54:06 +01:00
|
|
|
uint8_t res = Nova::NOVA_PD_OOM;
|
|
|
|
do {
|
2017-05-11 20:03:28 +02:00
|
|
|
res = Nova::assign_pci(_pd->pd_sel(), pci_config_memory, bdf);
|
2016-11-28 10:54:06 +01:00
|
|
|
} while (res == Nova::NOVA_PD_OOM &&
|
|
|
|
Nova::NOVA_OK == Pager_object::handle_oom(Pager_object::SRC_CORE_PD,
|
2017-05-11 20:03:28 +02:00
|
|
|
_pd->pd_sel(),
|
2016-11-28 10:54:06 +01:00
|
|
|
"core", "ep",
|
|
|
|
Pager_object::Policy::UPGRADE_CORE_TO_DST));
|
|
|
|
|
2013-02-11 11:44:04 +01:00
|
|
|
return res == Nova::NOVA_OK;
|
|
|
|
}
|
2017-08-02 17:30:49 +02:00
|
|
|
|
|
|
|
|
2017-08-02 14:41:51 +02:00
|
|
|
void Pd_session_component::map(addr_t virt, addr_t size)
|
|
|
|
{
|
base/core: use references instead of pointers
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
2019-01-24 22:00:01 +01:00
|
|
|
Genode::addr_t const pd_core = platform_specific().core_pd_sel();
|
2017-08-02 14:41:51 +02:00
|
|
|
Platform_pd &target_pd = *_pd;
|
|
|
|
Genode::addr_t const pd_dst = target_pd.pd_sel();
|
base/core: use references instead of pointers
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
2019-01-24 22:00:01 +01:00
|
|
|
Nova::Utcb &utcb = *reinterpret_cast<Nova::Utcb *>(Thread::myself()->utcb());
|
2017-08-02 14:41:51 +02:00
|
|
|
|
|
|
|
auto lambda = [&] (Region_map_component *region_map,
|
|
|
|
Rm_region *region,
|
2018-05-25 18:57:38 +02:00
|
|
|
addr_t const ds_offset,
|
|
|
|
addr_t const region_offset,
|
|
|
|
addr_t const dst_region_size) -> addr_t
|
2017-08-02 14:41:51 +02:00
|
|
|
{
|
base/core: use references instead of pointers
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
2019-01-24 22:00:01 +01:00
|
|
|
Dataspace_component * dsc = region ? ®ion->dataspace() : nullptr;
|
2017-12-13 15:47:17 +01:00
|
|
|
if (!dsc) {
|
|
|
|
struct No_dataspace{};
|
|
|
|
throw No_dataspace();
|
|
|
|
}
|
base/core: use references instead of pointers
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
2019-01-24 22:00:01 +01:00
|
|
|
if (!region_map) {
|
|
|
|
ASSERT_NEVER_CALLED;
|
|
|
|
}
|
2017-08-02 14:41:51 +02:00
|
|
|
|
|
|
|
Mapping mapping = Region_map_component::create_map_item(region_map,
|
base/core: use references instead of pointers
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
2019-01-24 22:00:01 +01:00
|
|
|
*region,
|
2017-08-02 14:41:51 +02:00
|
|
|
ds_offset,
|
|
|
|
region_offset,
|
base/core: use references instead of pointers
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
2019-01-24 22:00:01 +01:00
|
|
|
*dsc, virt,
|
2018-05-25 18:57:38 +02:00
|
|
|
dst_region_size);
|
2017-08-02 14:41:51 +02:00
|
|
|
|
|
|
|
/* asynchronously map memory */
|
|
|
|
uint8_t err = Nova::NOVA_PD_OOM;
|
|
|
|
do {
|
base/core: use references instead of pointers
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
2019-01-24 22:00:01 +01:00
|
|
|
utcb.set_msg_word(0);
|
|
|
|
bool res = utcb.append_item(mapping.mem_crd(), 0, true, false,
|
|
|
|
false, mapping.dma(),
|
|
|
|
mapping.write_combined());
|
2017-08-02 14:41:51 +02:00
|
|
|
/* one item ever fits on the UTCB */
|
|
|
|
(void)res;
|
|
|
|
|
2018-05-08 11:21:10 +02:00
|
|
|
Nova::Rights const map_rights (true,
|
|
|
|
region->write() && dsc->writable(),
|
|
|
|
region->executable());
|
|
|
|
|
2017-08-02 14:41:51 +02:00
|
|
|
/* receive window in destination pd */
|
|
|
|
Nova::Mem_crd crd_mem(mapping.dst_addr() >> 12,
|
2018-05-08 11:21:10 +02:00
|
|
|
mapping.mem_crd().order(), map_rights);
|
2017-08-02 14:41:51 +02:00
|
|
|
|
|
|
|
err = Nova::delegate(pd_core, pd_dst, crd_mem);
|
|
|
|
} while (err == Nova::NOVA_PD_OOM &&
|
|
|
|
Nova::NOVA_OK == Pager_object::handle_oom(Pager_object::SRC_CORE_PD,
|
|
|
|
_pd->pd_sel(),
|
|
|
|
"core", "ep",
|
|
|
|
Pager_object::Policy::UPGRADE_CORE_TO_DST));
|
|
|
|
|
|
|
|
addr_t const map_crd_size = 1UL << (mapping.mem_crd().order() + 12);
|
|
|
|
addr_t const mapped = mapping.dst_addr() + map_crd_size - virt;
|
|
|
|
|
|
|
|
if (err != Nova::NOVA_OK)
|
|
|
|
error("could not map memory ",
|
|
|
|
Hex_range<addr_t>(mapping.dst_addr(), map_crd_size) , " "
|
|
|
|
"eagerly error=", err);
|
|
|
|
|
|
|
|
return mapped;
|
|
|
|
};
|
|
|
|
|
2017-12-13 15:47:17 +01:00
|
|
|
try {
|
|
|
|
while (size) {
|
|
|
|
addr_t mapped = _address_space.apply_to_dataspace(virt, lambda);
|
|
|
|
virt += mapped;
|
|
|
|
size = size < mapped ? size : size - mapped;
|
|
|
|
}
|
|
|
|
} catch (...) {
|
|
|
|
error(__func__, " failed ", Hex(virt), "+", Hex(size));
|
2017-08-02 14:41:51 +02:00
|
|
|
}
|
|
|
|
}
|