mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-23 02:32:44 +00:00
parent
ff5d28822c
commit
57949c2bbb
@ -339,6 +339,13 @@ namespace Nova {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ALWAYS_INLINE
|
||||||
|
inline uint8_t delegate(mword_t pd_snd, mword_t pd_dst, Crd crd_dst)
|
||||||
|
{
|
||||||
|
return syscall_2(NOVA_LOOKUP, 1, pd_snd, crd_dst.value(), pd_dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ALWAYS_INLINE
|
ALWAYS_INLINE
|
||||||
inline uint8_t sm_ctrl(unsigned sm, Sem_op op, unsigned long long timeout = 0)
|
inline uint8_t sm_ctrl(unsigned sm, Sem_op op, unsigned long long timeout = 0)
|
||||||
{
|
{
|
||||||
|
@ -292,6 +292,13 @@ namespace Nova {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ALWAYS_INLINE
|
||||||
|
inline uint8_t delegate(mword_t pd_snd, mword_t pd_dst, Crd crd_dst)
|
||||||
|
{
|
||||||
|
return syscall_2(NOVA_LOOKUP, 1, pd_snd, crd_dst.value(), pd_dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ALWAYS_INLINE
|
ALWAYS_INLINE
|
||||||
inline uint8_t sm_ctrl(mword_t sm, Sem_op op, unsigned long long timeout = 0)
|
inline uint8_t sm_ctrl(mword_t sm, Sem_op op, unsigned long long timeout = 0)
|
||||||
{
|
{
|
||||||
|
@ -1 +1 @@
|
|||||||
931c26a24d490daae7df7ebbb03274366088adf0
|
6f91bce10f8f9faa2a0f57b9d135559a1ce499a7
|
||||||
|
@ -4,7 +4,7 @@ DOWNLOADS := nova.git
|
|||||||
|
|
||||||
# r9 branch - use r9_debug for more verbose kernel messages
|
# r9 branch - use r9_debug for more verbose kernel messages
|
||||||
URL(nova) := https://github.com/alex-ab/NOVA.git
|
URL(nova) := https://github.com/alex-ab/NOVA.git
|
||||||
REV(nova) := 4d6f04dd02d8099a20766025457be0afd0eae534
|
REV(nova) := b493eef81a1313f1cd420b4ed4310ef154c79c04
|
||||||
DIR(nova) := src/kernel/nova
|
DIR(nova) := src/kernel/nova
|
||||||
|
|
||||||
PATCHES := $(wildcard $(REP_DIR)/patches/*.patch)
|
PATCHES := $(wildcard $(REP_DIR)/patches/*.patch)
|
||||||
|
@ -37,6 +37,6 @@ build_boot_image "core init test-platform"
|
|||||||
|
|
||||||
append qemu_args "-nographic -m 128 -smp 2"
|
append qemu_args "-nographic -m 128 -smp 2"
|
||||||
|
|
||||||
run_genode_until {Test finished} 150
|
run_genode_until {Test finished} 200
|
||||||
|
|
||||||
puts "\nTest succeeded"
|
puts "\nTest succeeded"
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Core includes */
|
/* core-local includes */
|
||||||
#include <platform_pd.h>
|
#include <platform.h>
|
||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
#include <echo.h>
|
#include <echo.h>
|
||||||
@ -69,9 +69,12 @@ Echo::Echo(Genode::addr_t utcb_addr)
|
|||||||
{
|
{
|
||||||
using namespace Nova;
|
using namespace Nova;
|
||||||
|
|
||||||
|
extern Genode::addr_t __initial_sp;
|
||||||
|
Hip const * const hip = reinterpret_cast<Hip *>(__initial_sp);
|
||||||
|
|
||||||
/* create echo EC */
|
/* create echo EC */
|
||||||
Genode::addr_t pd_sel = Genode::Platform_pd::pd_core_sel();
|
Genode::addr_t const core_pd_sel = hip->sel_exc;
|
||||||
uint8_t res = create_ec(_ec_sel, pd_sel, boot_cpu(), utcb_addr,
|
uint8_t res = create_ec(_ec_sel, core_pd_sel, boot_cpu(), utcb_addr,
|
||||||
reinterpret_cast<mword_t>(echo_stack_top()),
|
reinterpret_cast<mword_t>(echo_stack_top()),
|
||||||
ECHO_EXC_BASE, ECHO_GLOBAL);
|
ECHO_EXC_BASE, ECHO_GLOBAL);
|
||||||
|
|
||||||
@ -79,7 +82,7 @@ Echo::Echo(Genode::addr_t utcb_addr)
|
|||||||
if (res != Nova::NOVA_OK) { *reinterpret_cast<unsigned *>(0) = 0xdead; }
|
if (res != Nova::NOVA_OK) { *reinterpret_cast<unsigned *>(0) = 0xdead; }
|
||||||
|
|
||||||
/* set up echo portal to ourself */
|
/* set up echo portal to ourself */
|
||||||
res = create_pt(_pt_sel, pd_sel, _ec_sel, Mtd(0), (mword_t)echo_reply);
|
res = create_pt(_pt_sel, core_pd_sel, _ec_sel, Mtd(0), (mword_t)echo_reply);
|
||||||
if (res != Nova::NOVA_OK) { *reinterpret_cast<unsigned *>(0) = 0xdead; }
|
if (res != Nova::NOVA_OK) { *reinterpret_cast<unsigned *>(0) = 0xdead; }
|
||||||
revoke(Obj_crd(_pt_sel, 0, Obj_crd::RIGHT_PT_CTRL));
|
revoke(Obj_crd(_pt_sel, 0, Obj_crd::RIGHT_PT_CTRL));
|
||||||
|
|
||||||
|
@ -75,12 +75,19 @@ namespace Genode {
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
addr_t _pd_dst;
|
||||||
|
addr_t _pd_core;
|
||||||
addr_t _fault_ip;
|
addr_t _fault_ip;
|
||||||
addr_t _fault_addr;
|
addr_t _fault_addr;
|
||||||
|
addr_t _sp;
|
||||||
uint8_t _fault_type;
|
uint8_t _fault_type;
|
||||||
|
uint8_t _syscall_res;
|
||||||
|
uint8_t _normal_ipc;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
Ipc_pager (Nova::Utcb *, addr_t pd_dst, addr_t pd_core);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Intel manual: 6.15 EXCEPTION AND INTERRUPT REFERENCE
|
* Intel manual: 6.15 EXCEPTION AND INTERRUPT REFERENCE
|
||||||
* Interrupt 14—Page-Fault Exception (#PF)
|
* Interrupt 14—Page-Fault Exception (#PF)
|
||||||
@ -93,18 +100,10 @@ namespace Genode {
|
|||||||
ERR_P = 1 << 0,
|
ERR_P = 1 << 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Wait for page-fault info
|
|
||||||
*
|
|
||||||
* After returning from this call, 'fault_ip' and 'fault_addr'
|
|
||||||
* have a defined state.
|
|
||||||
*/
|
|
||||||
void wait_for_fault();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Answer current page fault
|
* Answer current page fault
|
||||||
*/
|
*/
|
||||||
void reply_and_wait_for_fault(unsigned sm = 0);
|
void reply_and_wait_for_fault(addr_t sm = 0UL);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request instruction pointer of current fault
|
* Request instruction pointer of current fault
|
||||||
@ -136,6 +135,23 @@ namespace Genode {
|
|||||||
*/
|
*/
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return result of delegate syscall
|
||||||
|
*/
|
||||||
|
uint8_t syscall_result() const { return _syscall_res; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return low level fault type info
|
||||||
|
* Intel manual: 6.15 EXCEPTION AND INTERRUPT REFERENCE
|
||||||
|
* Interrupt 14—Page-Fault Exception (#PF)
|
||||||
|
*/
|
||||||
|
addr_t fault_type() { return _fault_type; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return stack pointer address valid during page-fault
|
||||||
|
*/
|
||||||
|
addr_t sp() { return _sp; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,8 @@ namespace Genode {
|
|||||||
Phys_allocator _io_port_alloc; /* I/O port allocator */
|
Phys_allocator _io_port_alloc; /* I/O port allocator */
|
||||||
Phys_allocator _irq_alloc; /* IRQ allocator */
|
Phys_allocator _irq_alloc; /* IRQ allocator */
|
||||||
Rom_fs _rom_fs; /* ROM file system */
|
Rom_fs _rom_fs; /* ROM file system */
|
||||||
int _gsi_base_sel; /* cap selector of 1st IRQ */
|
unsigned _gsi_base_sel; /* cap selector of 1st IRQ */
|
||||||
|
unsigned _core_pd_sel; /* cap selector of root PD */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Virtual address range usable by non-core processes
|
* Virtual address range usable by non-core processes
|
||||||
@ -100,6 +101,11 @@ namespace Genode {
|
|||||||
* Return kernel CPU ID for given Genode CPU
|
* Return kernel CPU ID for given Genode CPU
|
||||||
*/
|
*/
|
||||||
unsigned kernel_cpu_id(unsigned genode_cpu_id);
|
unsigned kernel_cpu_id(unsigned genode_cpu_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PD kernel capability selector of core
|
||||||
|
*/
|
||||||
|
unsigned core_pd_sel() const { return _core_pd_sel; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,11 +18,6 @@
|
|||||||
#include <platform_thread.h>
|
#include <platform_thread.h>
|
||||||
#include <address_space.h>
|
#include <address_space.h>
|
||||||
|
|
||||||
/*
|
|
||||||
* Must be initialized by the startup code,
|
|
||||||
* only valid in core
|
|
||||||
*/
|
|
||||||
extern Genode::addr_t __core_pd_sel;
|
|
||||||
|
|
||||||
namespace Genode {
|
namespace Genode {
|
||||||
|
|
||||||
@ -83,14 +78,6 @@ namespace Genode {
|
|||||||
*/
|
*/
|
||||||
addr_t pd_sel() const { return _pd_sel; }
|
addr_t pd_sel() const { return _pd_sel; }
|
||||||
|
|
||||||
/**
|
|
||||||
* Capability selector of core protection domain
|
|
||||||
*
|
|
||||||
* \return PD selector
|
|
||||||
*/
|
|
||||||
static addr_t pd_core_sel() { return __core_pd_sel; }
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Label of this protection domain
|
* Label of this protection domain
|
||||||
*
|
*
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <nova/capability_space.h>
|
#include <nova/capability_space.h>
|
||||||
|
|
||||||
/* core-local includes */
|
/* core-local includes */
|
||||||
|
#include <platform.h>
|
||||||
#include <signal_source_component.h>
|
#include <signal_source_component.h>
|
||||||
#include <signal_source/capability.h>
|
#include <signal_source/capability.h>
|
||||||
|
|
||||||
@ -91,8 +92,9 @@ class Genode::Signal_broker
|
|||||||
Native_capability si = Capability_space::import(cap_map()->insert());
|
Native_capability si = Capability_space::import(cap_map()->insert());
|
||||||
Signal_context_capability cap = reinterpret_cap_cast<Signal_context>(si);
|
Signal_context_capability cap = reinterpret_cap_cast<Signal_context>(si);
|
||||||
|
|
||||||
uint8_t res = Nova::create_si(cap.local_name(), __core_pd_sel, imprint,
|
uint8_t res = Nova::create_si(cap.local_name(),
|
||||||
sm.local_name());
|
platform_specific()->core_pd_sel(),
|
||||||
|
imprint, sm.local_name());
|
||||||
if (res != Nova::NOVA_OK) {
|
if (res != Nova::NOVA_OK) {
|
||||||
warning("creating signal failed - error ", res);
|
warning("creating signal failed - error ", res);
|
||||||
return Signal_context_capability();
|
return Signal_context_capability();
|
||||||
|
@ -23,17 +23,24 @@
|
|||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
void Ipc_pager::wait_for_fault()
|
Ipc_pager::Ipc_pager(Nova::Utcb * utcb, addr_t pd_dst, addr_t pd_core)
|
||||||
|
:
|
||||||
|
_pd_dst(pd_dst),
|
||||||
|
_pd_core(pd_core),
|
||||||
|
_fault_ip(utcb->ip),
|
||||||
|
_fault_addr(utcb->qual[1]),
|
||||||
|
_sp(utcb->sp),
|
||||||
|
_fault_type(utcb->qual[0]),
|
||||||
|
_syscall_res(Nova::NOVA_OK),
|
||||||
|
_normal_ipc((((addr_t)&utcb->qual[2] - (addr_t)utcb->msg) / sizeof(addr_t))
|
||||||
|
== utcb->msg_words())
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When this function is called from the page-fault handler EC, a page
|
* When this function is called from the page-fault handler EC, a page
|
||||||
* fault already occurred. So we never wait but immediately read the
|
* fault already occurred. So we never wait but immediately read the
|
||||||
* page-fault information from our UTCB.
|
* page-fault information from our UTCB.
|
||||||
*/
|
*/
|
||||||
Nova::Utcb *utcb = (Nova::Utcb *)Thread::myself()->utcb();
|
|
||||||
_fault_type = utcb->qual[0];
|
|
||||||
_fault_addr = utcb->qual[1];
|
|
||||||
_fault_ip = utcb->ip;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -41,14 +48,31 @@ void Ipc_pager::set_reply_mapping(Mapping m)
|
|||||||
{
|
{
|
||||||
Nova::Utcb *utcb = (Nova::Utcb *)Thread::myself()->utcb();
|
Nova::Utcb *utcb = (Nova::Utcb *)Thread::myself()->utcb();
|
||||||
utcb->set_msg_word(0);
|
utcb->set_msg_word(0);
|
||||||
bool res = utcb->append_item(m.mem_crd(), m.dst_addr(), true, false,
|
bool res = utcb->append_item(m.mem_crd(), 0, true, false,
|
||||||
false, m.dma(), m.write_combined());
|
false, m.dma(), m.write_combined());
|
||||||
/* one item ever fits on the UTCB */
|
/* one item ever fits on the UTCB */
|
||||||
(void)res;
|
(void)res;
|
||||||
|
|
||||||
|
/* receive window in destination pd */
|
||||||
|
Nova::Mem_crd crd_mem(m.dst_addr() >> 12, m.mem_crd().order(),
|
||||||
|
Nova::Rights(true, true, true));
|
||||||
|
/* asynchronously map memory */
|
||||||
|
_syscall_res = Nova::delegate(_pd_core, _pd_dst, crd_mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Ipc_pager::reply_and_wait_for_fault(unsigned sm)
|
void Ipc_pager::reply_and_wait_for_fault(addr_t sm)
|
||||||
{
|
{
|
||||||
Nova::reply(Thread::myself()->stack_top(), sm);
|
Thread * myself = Thread::myself();
|
||||||
|
Nova::Utcb * utcb = reinterpret_cast<Nova::Utcb *>(myself->utcb());
|
||||||
|
|
||||||
|
utcb->mtd = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If it was a normal IPC and the mapping failed, caller may re-try.
|
||||||
|
* Otherwise nothing left to be delegated - done asynchronously beforehand.
|
||||||
|
*/
|
||||||
|
utcb->set_msg_word((_normal_ipc && _syscall_res != Nova::NOVA_OK) ? 1 : 0);
|
||||||
|
|
||||||
|
Nova::reply(myself->stack_top(), sm);
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,6 @@ static bool verbose_oom = false;
|
|||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
using namespace Nova;
|
using namespace Nova;
|
||||||
|
|
||||||
extern Genode::addr_t __core_pd_sel;
|
|
||||||
|
|
||||||
static Nova::Hip * kernel_hip()
|
static Nova::Hip * kernel_hip()
|
||||||
{
|
{
|
||||||
@ -79,11 +78,13 @@ struct Page_fault_info
|
|||||||
char const * const pd;
|
char const * const pd;
|
||||||
char const * const thread;
|
char const * const thread;
|
||||||
unsigned const cpu;
|
unsigned const cpu;
|
||||||
addr_t const ip, addr;
|
addr_t const ip, addr, sp;
|
||||||
|
uint8_t const pf_type;
|
||||||
|
|
||||||
Page_fault_info(char const *pd, char const *thread, unsigned cpu,
|
Page_fault_info(char const *pd, char const *thread, unsigned cpu,
|
||||||
addr_t ip, addr_t addr)
|
addr_t ip, addr_t addr, addr_t sp, unsigned type)
|
||||||
: pd(pd), thread(thread), cpu(cpu), ip(ip), addr(addr) { }
|
: pd(pd), thread(thread), cpu(cpu), ip(ip), addr(addr),
|
||||||
|
sp(sp), pf_type(type) { }
|
||||||
|
|
||||||
void print(Genode::Output &out) const
|
void print(Genode::Output &out) const
|
||||||
{
|
{
|
||||||
@ -91,32 +92,57 @@ struct Page_fault_info
|
|||||||
"thread='", thread, "' "
|
"thread='", thread, "' "
|
||||||
"cpu=", cpu, " "
|
"cpu=", cpu, " "
|
||||||
"ip=", Hex(ip), " "
|
"ip=", Hex(ip), " "
|
||||||
"address=", Hex(addr));
|
"address=", Hex(addr), " "
|
||||||
|
"stack pointer=", Hex(sp), " "
|
||||||
|
"qualifiers=", Hex(pf_type), " ",
|
||||||
|
pf_type & Ipc_pager::ERR_I ? "I" : "i",
|
||||||
|
pf_type & Ipc_pager::ERR_R ? "R" : "r",
|
||||||
|
pf_type & Ipc_pager::ERR_U ? "U" : "u",
|
||||||
|
pf_type & Ipc_pager::ERR_W ? "W" : "w",
|
||||||
|
pf_type & Ipc_pager::ERR_P ? "P" : "p");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void Pager_object::_page_fault_handler(addr_t pager_obj)
|
void Pager_object::_page_fault_handler(addr_t pager_obj)
|
||||||
{
|
{
|
||||||
Ipc_pager ipc_pager;
|
|
||||||
ipc_pager.wait_for_fault();
|
|
||||||
|
|
||||||
Thread * myself = Thread::myself();
|
Thread * myself = Thread::myself();
|
||||||
Pager_object * obj = reinterpret_cast<Pager_object *>(pager_obj);
|
Pager_object * obj = reinterpret_cast<Pager_object *>(pager_obj);
|
||||||
Utcb * utcb = reinterpret_cast<Utcb *>(myself->utcb());
|
Utcb * utcb = reinterpret_cast<Utcb *>(myself->utcb());
|
||||||
|
|
||||||
|
Ipc_pager ipc_pager(reinterpret_cast<Nova::Utcb *>(utcb), obj->pd_sel(),
|
||||||
|
platform_specific()->core_pd_sel());
|
||||||
|
|
||||||
Pager_activation_base * pager_thread = static_cast<Pager_activation_base *>(myself);
|
Pager_activation_base * pager_thread = static_cast<Pager_activation_base *>(myself);
|
||||||
|
|
||||||
/* lookup fault address and decide what to do */
|
/* lookup fault address and decide what to do */
|
||||||
int ret = obj->pager(ipc_pager);
|
int error = obj->pager(ipc_pager);
|
||||||
|
|
||||||
/* don't open receive window for pager threads */
|
/* don't open receive window for pager threads */
|
||||||
if (utcb->crd_rcv.value())
|
if (utcb->crd_rcv.value())
|
||||||
nova_die();
|
nova_die();
|
||||||
|
|
||||||
|
if (!error && ipc_pager.syscall_result() != Nova::NOVA_OK) {
|
||||||
|
/* something went wrong - by default don't answer the page fault */
|
||||||
|
error = 4;
|
||||||
|
|
||||||
|
/* dst pd has not enough kernel quota ? - try to recover */
|
||||||
|
if (ipc_pager.syscall_result() == Nova::NOVA_PD_OOM) {
|
||||||
|
uint8_t res = obj->handle_oom();
|
||||||
|
if (res == Nova::NOVA_PD_OOM)
|
||||||
|
/* block until revoke is due */
|
||||||
|
ipc_pager.reply_and_wait_for_fault(obj->sel_sm_block_oom());
|
||||||
|
else if (res == Nova::NOVA_OK)
|
||||||
|
/* succeeded to recover - continue normally */
|
||||||
|
error = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* good case - found a valid region which is mappable */
|
/* good case - found a valid region which is mappable */
|
||||||
if (!ret)
|
if (!error)
|
||||||
ipc_pager.reply_and_wait_for_fault();
|
ipc_pager.reply_and_wait_for_fault();
|
||||||
|
|
||||||
|
|
||||||
obj->_state_lock.lock();
|
obj->_state_lock.lock();
|
||||||
|
|
||||||
obj->_state.thread.ip = ipc_pager.fault_ip();
|
obj->_state.thread.ip = ipc_pager.fault_ip();
|
||||||
@ -132,35 +158,18 @@ void Pager_object::_page_fault_handler(addr_t pager_obj)
|
|||||||
|
|
||||||
Page_fault_info const fault_info(client_pd, client_thread,
|
Page_fault_info const fault_info(client_pd, client_thread,
|
||||||
which_cpu(pager_thread),
|
which_cpu(pager_thread),
|
||||||
ipc_pager.fault_ip(), ipc_pager.fault_addr());
|
ipc_pager.fault_ip(),
|
||||||
|
ipc_pager.fault_addr(),
|
||||||
|
ipc_pager.sp(),
|
||||||
|
ipc_pager.fault_type());
|
||||||
|
|
||||||
/* region manager fault - to be handled */
|
/* region manager fault - to be handled */
|
||||||
if (ret == 1) {
|
log("page fault, ", fault_info, " reason=", error);
|
||||||
log("page fault, ", fault_info);
|
|
||||||
|
|
||||||
utcb->set_msg_word(0);
|
|
||||||
utcb->mtd = 0;
|
|
||||||
|
|
||||||
/* block the faulting thread until region manager is done */
|
/* block the faulting thread until region manager is done */
|
||||||
ipc_pager.reply_and_wait_for_fault(obj->sel_sm_block_pause());
|
ipc_pager.reply_and_wait_for_fault(obj->sel_sm_block_pause());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unhandled case */
|
|
||||||
obj->_state.mark_dead();
|
|
||||||
|
|
||||||
warning("unresolvable page fault, ", fault_info, " ret=", ret);
|
|
||||||
|
|
||||||
Native_capability pager_cap = obj->Object_pool<Pager_object>::Entry::cap();
|
|
||||||
|
|
||||||
revoke(Capability_space::crd(pager_cap).base());
|
|
||||||
|
|
||||||
revoke(Obj_crd(obj->exc_pt_sel_client(), NUM_INITIAL_PT_LOG2));
|
|
||||||
|
|
||||||
utcb->set_msg_word(0);
|
|
||||||
utcb->mtd = 0;
|
|
||||||
ipc_pager.reply_and_wait_for_fault();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Pager_object::exception(uint8_t exit_id)
|
void Pager_object::exception(uint8_t exit_id)
|
||||||
{
|
{
|
||||||
@ -364,7 +373,7 @@ void Pager_object::_invoke_handler(addr_t pager_obj)
|
|||||||
revoke(Obj_crd(obj->exc_pt_sel_client() + PT_SEL_STARTUP, 0));
|
revoke(Obj_crd(obj->exc_pt_sel_client() + PT_SEL_STARTUP, 0));
|
||||||
|
|
||||||
bool res = Nova::create_sm(obj->exc_pt_sel_client() + PT_SEL_STARTUP,
|
bool res = Nova::create_sm(obj->exc_pt_sel_client() + PT_SEL_STARTUP,
|
||||||
__core_pd_sel, 0);
|
platform_specific()->core_pd_sel(), 0);
|
||||||
if (res != Nova::NOVA_OK)
|
if (res != Nova::NOVA_OK)
|
||||||
reply(myself->stack_top());
|
reply(myself->stack_top());
|
||||||
|
|
||||||
@ -524,7 +533,7 @@ void Exception_handlers::register_handler(Pager_object *obj, Mtd mtd,
|
|||||||
/* compiler generates instance of exception entry if not specified */
|
/* compiler generates instance of exception entry if not specified */
|
||||||
addr_t entry = func ? (addr_t)func : (addr_t)(&_handler<EV>);
|
addr_t entry = func ? (addr_t)func : (addr_t)(&_handler<EV>);
|
||||||
uint8_t res = create_portal(obj->exc_pt_sel_client() + EV,
|
uint8_t res = create_portal(obj->exc_pt_sel_client() + EV,
|
||||||
__core_pd_sel, ec_sel, mtd, entry, obj);
|
platform_specific()->core_pd_sel(), ec_sel, mtd, entry, obj);
|
||||||
if (res != Nova::NOVA_OK)
|
if (res != Nova::NOVA_OK)
|
||||||
throw Region_map::Invalid_thread();
|
throw Region_map::Invalid_thread();
|
||||||
}
|
}
|
||||||
@ -589,7 +598,7 @@ Pager_object::Pager_object(Cpu_session_capability cpu_session_cap,
|
|||||||
{
|
{
|
||||||
uint8_t res;
|
uint8_t res;
|
||||||
|
|
||||||
addr_t pd_sel = __core_pd_sel;
|
addr_t const pd_sel = platform_specific()->core_pd_sel();
|
||||||
_state._status = 0;
|
_state._status = 0;
|
||||||
_state.modified = false;
|
_state.modified = false;
|
||||||
_state.sel_client_ec = Native_thread::INVALID_INDEX;
|
_state.sel_client_ec = Native_thread::INVALID_INDEX;
|
||||||
@ -685,13 +694,14 @@ uint8_t Pager_object::handle_oom(addr_t transfer_from,
|
|||||||
char const * src_pd, char const * src_thread,
|
char const * src_pd, char const * src_thread,
|
||||||
enum Pager_object::Policy policy)
|
enum Pager_object::Policy policy)
|
||||||
{
|
{
|
||||||
const char * dst_pd = client_pd();
|
char const * dst_pd = client_pd();
|
||||||
const char * dst_thread = client_thread();
|
char const * dst_thread = client_thread();
|
||||||
|
addr_t const core_pd_sel = platform_specific()->core_pd_sel();
|
||||||
|
|
||||||
enum { QUOTA_TRANSFER_PAGES = 2 };
|
enum { QUOTA_TRANSFER_PAGES = 2 };
|
||||||
|
|
||||||
if (transfer_from == SRC_CORE_PD)
|
if (transfer_from == SRC_CORE_PD)
|
||||||
transfer_from = __core_pd_sel;
|
transfer_from = core_pd_sel;
|
||||||
|
|
||||||
/* request current kernel quota usage of target pd */
|
/* request current kernel quota usage of target pd */
|
||||||
addr_t limit_before = 0, usage_before = 0;
|
addr_t limit_before = 0, usage_before = 0;
|
||||||
@ -721,8 +731,8 @@ uint8_t Pager_object::handle_oom(addr_t transfer_from,
|
|||||||
|
|
||||||
/* retry upgrade using core quota if policy permits */
|
/* retry upgrade using core quota if policy permits */
|
||||||
if (policy == UPGRADE_PREFER_SRC_TO_DST) {
|
if (policy == UPGRADE_PREFER_SRC_TO_DST) {
|
||||||
if (transfer_from != __core_pd_sel) {
|
if (transfer_from != core_pd_sel) {
|
||||||
res = Nova::pd_ctrl(__core_pd_sel, Pd_op::TRANSFER_QUOTA,
|
res = Nova::pd_ctrl(core_pd_sel, Pd_op::TRANSFER_QUOTA,
|
||||||
pd_sel(), QUOTA_TRANSFER_PAGES);
|
pd_sel(), QUOTA_TRANSFER_PAGES);
|
||||||
if (res == Nova::NOVA_OK)
|
if (res == Nova::NOVA_OK)
|
||||||
return res;
|
return res;
|
||||||
@ -836,14 +846,14 @@ void Pager_object::_oom_handler(addr_t pager_dst, addr_t pager_src,
|
|||||||
utcb->set_msg_word(0);
|
utcb->set_msg_word(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
transfer_from = __core_pd_sel;
|
transfer_from = platform_specific()->core_pd_sel();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* non core PD -> non core PD */
|
/* non core PD -> non core PD */
|
||||||
utcb->set_msg_word(0);
|
utcb->set_msg_word(0);
|
||||||
|
|
||||||
if (pager_src == pager_dst || policy == UPGRADE_CORE_TO_DST)
|
if (pager_src == pager_dst || policy == UPGRADE_CORE_TO_DST)
|
||||||
transfer_from = __core_pd_sel;
|
transfer_from = platform_specific()->core_pd_sel();
|
||||||
else {
|
else {
|
||||||
/* delegation of items between different PDs */
|
/* delegation of items between different PDs */
|
||||||
src_pd = obj_src->client_pd();
|
src_pd = obj_src->client_pd();
|
||||||
@ -877,12 +887,13 @@ addr_t Pager_object::get_oom_portal()
|
|||||||
addr_t const pt_oom = sel_oom_portal();
|
addr_t const pt_oom = sel_oom_portal();
|
||||||
unsigned const genode_cpu_id = _location.xpos();
|
unsigned const genode_cpu_id = _location.xpos();
|
||||||
unsigned const kernel_cpu_id = platform_specific()->kernel_cpu_id(genode_cpu_id);
|
unsigned const kernel_cpu_id = platform_specific()->kernel_cpu_id(genode_cpu_id);
|
||||||
|
addr_t const core_pd_sel = platform_specific()->core_pd_sel();
|
||||||
|
|
||||||
if (kernel_hip()->is_cpu_enabled(kernel_cpu_id) &&
|
if (kernel_hip()->is_cpu_enabled(kernel_cpu_id) &&
|
||||||
pager_threads[genode_cpu_id]) {
|
pager_threads[genode_cpu_id]) {
|
||||||
|
|
||||||
addr_t const ec_sel = pager_threads[genode_cpu_id]->native_thread().ec_sel;
|
addr_t const ec_sel = pager_threads[genode_cpu_id]->native_thread().ec_sel;
|
||||||
uint8_t res = create_portal(pt_oom, __core_pd_sel, ec_sel, Mtd(0),
|
uint8_t res = create_portal(pt_oom, core_pd_sel, ec_sel, Mtd(0),
|
||||||
reinterpret_cast<addr_t>(_oom_handler),
|
reinterpret_cast<addr_t>(_oom_handler),
|
||||||
this);
|
this);
|
||||||
if (res == Nova::NOVA_OK)
|
if (res == Nova::NOVA_OK)
|
||||||
|
@ -63,11 +63,6 @@ Utcb *__main_thread_utcb;
|
|||||||
*/
|
*/
|
||||||
extern unsigned _prog_img_beg, _prog_img_end;
|
extern unsigned _prog_img_beg, _prog_img_end;
|
||||||
|
|
||||||
/**
|
|
||||||
* Capability selector of root PD
|
|
||||||
*/
|
|
||||||
addr_t __core_pd_sel;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map preserved physical pages core-exclusive
|
* Map preserved physical pages core-exclusive
|
||||||
@ -218,7 +213,7 @@ static void startup_handler()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void init_core_page_fault_handler()
|
static void init_core_page_fault_handler(addr_t const core_pd_sel)
|
||||||
{
|
{
|
||||||
/* create echo EC */
|
/* create echo EC */
|
||||||
enum {
|
enum {
|
||||||
@ -228,20 +223,20 @@ static void init_core_page_fault_handler()
|
|||||||
|
|
||||||
addr_t ec_sel = cap_map()->insert(1);
|
addr_t ec_sel = cap_map()->insert(1);
|
||||||
|
|
||||||
uint8_t ret = create_ec(ec_sel, __core_pd_sel, boot_cpu(),
|
uint8_t ret = create_ec(ec_sel, core_pd_sel, boot_cpu(),
|
||||||
CORE_PAGER_UTCB_ADDR, core_pager_stack_top(),
|
CORE_PAGER_UTCB_ADDR, core_pager_stack_top(),
|
||||||
EXC_BASE, GLOBAL);
|
EXC_BASE, GLOBAL);
|
||||||
if (ret)
|
if (ret)
|
||||||
log(__func__, ": create_ec returned ", ret);
|
log(__func__, ": create_ec returned ", ret);
|
||||||
|
|
||||||
/* set up page-fault portal */
|
/* set up page-fault portal */
|
||||||
create_pt(PT_SEL_PAGE_FAULT, __core_pd_sel, ec_sel,
|
create_pt(PT_SEL_PAGE_FAULT, core_pd_sel, ec_sel,
|
||||||
Mtd(Mtd::QUAL | Mtd::ESP | Mtd::EIP),
|
Mtd(Mtd::QUAL | Mtd::ESP | Mtd::EIP),
|
||||||
(addr_t)page_fault_handler);
|
(addr_t)page_fault_handler);
|
||||||
revoke(Obj_crd(PT_SEL_PAGE_FAULT, 0, Obj_crd::RIGHT_PT_CTRL));
|
revoke(Obj_crd(PT_SEL_PAGE_FAULT, 0, Obj_crd::RIGHT_PT_CTRL));
|
||||||
|
|
||||||
/* startup portal for global core threads */
|
/* startup portal for global core threads */
|
||||||
create_pt(PT_SEL_STARTUP, __core_pd_sel, ec_sel,
|
create_pt(PT_SEL_STARTUP, core_pd_sel, ec_sel,
|
||||||
Mtd(Mtd::EIP | Mtd::ESP),
|
Mtd(Mtd::EIP | Mtd::ESP),
|
||||||
(addr_t)startup_handler);
|
(addr_t)startup_handler);
|
||||||
revoke(Obj_crd(PT_SEL_STARTUP, 0, Obj_crd::RIGHT_PT_CTRL));
|
revoke(Obj_crd(PT_SEL_STARTUP, 0, Obj_crd::RIGHT_PT_CTRL));
|
||||||
@ -291,10 +286,10 @@ Platform::Platform() :
|
|||||||
__main_thread_utcb = (Utcb *)(__initial_sp - get_page_size());
|
__main_thread_utcb = (Utcb *)(__initial_sp - get_page_size());
|
||||||
|
|
||||||
/* set core pd selector */
|
/* set core pd selector */
|
||||||
__core_pd_sel = hip->sel_exc;
|
_core_pd_sel = hip->sel_exc;
|
||||||
|
|
||||||
/* create lock used by capability allocator */
|
/* create lock used by capability allocator */
|
||||||
Nova::create_sm(Nova::SM_SEL_EC, __core_pd_sel, 0);
|
Nova::create_sm(Nova::SM_SEL_EC, core_pd_sel(), 0);
|
||||||
|
|
||||||
/* locally map the whole I/O port range */
|
/* locally map the whole I/O port range */
|
||||||
enum { ORDER_64K = 16 };
|
enum { ORDER_64K = 16 };
|
||||||
@ -380,7 +375,7 @@ Platform::Platform() :
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* set up page fault handler for core - for debugging */
|
/* set up page fault handler for core - for debugging */
|
||||||
init_core_page_fault_handler();
|
init_core_page_fault_handler(core_pd_sel());
|
||||||
|
|
||||||
if (verbose_boot_info) {
|
if (verbose_boot_info) {
|
||||||
if (hip->has_feature_vmx())
|
if (hip->has_feature_vmx())
|
||||||
|
@ -109,7 +109,6 @@ int Platform_thread::start(void *ip, void *sp)
|
|||||||
return -5;
|
return -5;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr_t pd_core_sel = Platform_pd::pd_core_sel();
|
|
||||||
addr_t pd_utcb = 0;
|
addr_t pd_utcb = 0;
|
||||||
_sel_exc_base = vcpu() ? _pager->exc_pt_vcpu() : _pager->exc_pt_sel_client();
|
_sel_exc_base = vcpu() ? _pager->exc_pt_vcpu() : _pager->exc_pt_sel_client();
|
||||||
|
|
||||||
@ -138,7 +137,8 @@ int Platform_thread::start(void *ip, void *sp)
|
|||||||
|
|
||||||
enum { KEEP_FREE_PAGES_NOT_AVAILABLE_FOR_UPGRADE = 2, UPPER_LIMIT_PAGES = 32 };
|
enum { KEEP_FREE_PAGES_NOT_AVAILABLE_FOR_UPGRADE = 2, UPPER_LIMIT_PAGES = 32 };
|
||||||
Obj_crd initial_pts(_sel_exc_base, pts, rights);
|
Obj_crd initial_pts(_sel_exc_base, pts, rights);
|
||||||
uint8_t res = create_pd(pd_sel, pd_core_sel, initial_pts,
|
uint8_t res = create_pd(pd_sel, platform_specific()->core_pd_sel(),
|
||||||
|
initial_pts,
|
||||||
KEEP_FREE_PAGES_NOT_AVAILABLE_FOR_UPGRADE, UPPER_LIMIT_PAGES);
|
KEEP_FREE_PAGES_NOT_AVAILABLE_FOR_UPGRADE, UPPER_LIMIT_PAGES);
|
||||||
if (res != NOVA_OK) {
|
if (res != NOVA_OK) {
|
||||||
error("create_pd returned ", res);
|
error("create_pd returned ", res);
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
/* core-local includes */
|
/* core-local includes */
|
||||||
#include <rpc_cap_factory.h>
|
#include <rpc_cap_factory.h>
|
||||||
#include <platform_pd.h>
|
#include <platform.h>
|
||||||
|
|
||||||
/* NOVA includes */
|
/* NOVA includes */
|
||||||
#include <nova/capability_space.h>
|
#include <nova/capability_space.h>
|
||||||
@ -23,9 +23,9 @@ using namespace Genode;
|
|||||||
|
|
||||||
Native_capability Rpc_cap_factory::alloc(Native_capability ep, addr_t entry, addr_t mtd)
|
Native_capability Rpc_cap_factory::alloc(Native_capability ep, addr_t entry, addr_t mtd)
|
||||||
{
|
{
|
||||||
addr_t pt_sel = cap_map()->insert();
|
addr_t const pt_sel = cap_map()->insert();
|
||||||
addr_t pd_sel = Platform_pd::pd_core_sel();
|
addr_t const pd_sel = platform_specific()->core_pd_sel();
|
||||||
addr_t ec_sel = ep.local_name();
|
addr_t const ec_sel = ep.local_name();
|
||||||
|
|
||||||
using namespace Nova;
|
using namespace Nova;
|
||||||
|
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
/* core includes */
|
/* core includes */
|
||||||
#include <nova_util.h>
|
#include <nova_util.h>
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
#include <platform_pd.h>
|
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
@ -43,7 +42,7 @@ void Thread::_init_platform_thread(size_t, Type type)
|
|||||||
if (type == MAIN)
|
if (type == MAIN)
|
||||||
{
|
{
|
||||||
/* set EC selector according to NOVA spec */
|
/* set EC selector according to NOVA spec */
|
||||||
native_thread().ec_sel = Platform_pd::pd_core_sel() + 1;
|
native_thread().ec_sel = platform_specific()->core_pd_sel() + 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Exception base of first thread in core is 0. We have to set
|
* Exception base of first thread in core is 0. We have to set
|
||||||
@ -56,11 +55,10 @@ void Thread::_init_platform_thread(size_t, Type type)
|
|||||||
}
|
}
|
||||||
native_thread().ec_sel = cap_map()->insert(1);
|
native_thread().ec_sel = cap_map()->insert(1);
|
||||||
native_thread().exc_pt_sel = cap_map()->insert(NUM_INITIAL_PT_LOG2);
|
native_thread().exc_pt_sel = cap_map()->insert(NUM_INITIAL_PT_LOG2);
|
||||||
addr_t pd_sel = Platform_pd::pd_core_sel();
|
|
||||||
|
|
||||||
/* create running semaphore required for locking */
|
/* create running semaphore required for locking */
|
||||||
addr_t rs_sel =native_thread().exc_pt_sel + SM_SEL_EC;
|
addr_t rs_sel =native_thread().exc_pt_sel + SM_SEL_EC;
|
||||||
uint8_t res = create_sm(rs_sel, pd_sel, 0);
|
uint8_t res = create_sm(rs_sel, platform_specific()->core_pd_sel(), 0);
|
||||||
if (res != NOVA_OK) {
|
if (res != NOVA_OK) {
|
||||||
error("create_sm returned ", res);
|
error("create_sm returned ", res);
|
||||||
throw Cpu_session::Thread_creation_failed();
|
throw Cpu_session::Thread_creation_failed();
|
||||||
@ -94,7 +92,6 @@ void Thread::start()
|
|||||||
addr_t sp = _stack->top();
|
addr_t sp = _stack->top();
|
||||||
addr_t utcb = reinterpret_cast<addr_t>(&_stack->utcb());
|
addr_t utcb = reinterpret_cast<addr_t>(&_stack->utcb());
|
||||||
Utcb * utcb_obj = reinterpret_cast<Utcb *>(&_stack->utcb());
|
Utcb * utcb_obj = reinterpret_cast<Utcb *>(&_stack->utcb());
|
||||||
addr_t pd_sel = Platform_pd::pd_core_sel();
|
|
||||||
|
|
||||||
Affinity::Location location = _affinity;
|
Affinity::Location location = _affinity;
|
||||||
|
|
||||||
@ -104,7 +101,8 @@ void Thread::start()
|
|||||||
/* create local EC */
|
/* create local EC */
|
||||||
enum { LOCAL_THREAD = false };
|
enum { LOCAL_THREAD = false };
|
||||||
unsigned const kernel_cpu_id = platform_specific()->kernel_cpu_id(location.xpos());
|
unsigned const kernel_cpu_id = platform_specific()->kernel_cpu_id(location.xpos());
|
||||||
uint8_t res = create_ec(native_thread().ec_sel, pd_sel, kernel_cpu_id,
|
uint8_t res = create_ec(native_thread().ec_sel,
|
||||||
|
platform_specific()->core_pd_sel(), kernel_cpu_id,
|
||||||
utcb, sp, native_thread().exc_pt_sel, LOCAL_THREAD);
|
utcb, sp, native_thread().exc_pt_sel, LOCAL_THREAD);
|
||||||
if (res != NOVA_OK) {
|
if (res != NOVA_OK) {
|
||||||
error("create_ec returned ", res, " cpu=", location.xpos());
|
error("create_ec returned ", res, " cpu=", location.xpos());
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include <base/snprintf.h>
|
#include <base/snprintf.h>
|
||||||
|
|
||||||
#include <util/touch.h>
|
#include <util/touch.h>
|
||||||
|
#include <util/retry.h>
|
||||||
#include <rm_session/connection.h>
|
#include <rm_session/connection.h>
|
||||||
#include <region_map/client.h>
|
#include <region_map/client.h>
|
||||||
|
|
||||||
@ -580,42 +581,27 @@ class Greedy : public Genode::Thread {
|
|||||||
{
|
{
|
||||||
log("starting");
|
log("starting");
|
||||||
|
|
||||||
enum { SUB_RM_SIZE = 2UL * 1024 * 1024 * 1024 };
|
enum { SUB_RM_SIZE = 1280 * 1024 * 1024 };
|
||||||
|
|
||||||
Genode::Rm_connection rm(_env);
|
Genode::Ram_dataspace_capability ds = _env.ram().alloc(4096);
|
||||||
Genode::Region_map_client sub_rm(rm.create(SUB_RM_SIZE));
|
|
||||||
addr_t const mem = _env.rm().attach(sub_rm.dataspace());
|
|
||||||
|
|
||||||
Nova::Utcb * nova_utcb = reinterpret_cast<Nova::Utcb *>(utcb());
|
|
||||||
Nova::Rights const mapping_rwx(true, true, true);
|
Nova::Rights const mapping_rwx(true, true, true);
|
||||||
|
|
||||||
addr_t const page_fault_portal = native_thread().exc_pt_sel + 14;
|
log("cause mappings");
|
||||||
|
|
||||||
log("cause mappings in range ",
|
for (unsigned i = 0; i < SUB_RM_SIZE / 4096; i++) {
|
||||||
Hex_range<addr_t>(mem, SUB_RM_SIZE), " ", &mem);
|
|
||||||
|
|
||||||
for (addr_t map_to = mem; map_to < mem + SUB_RM_SIZE; map_to += 4096) {
|
addr_t map_to = _env.rm().attach(ds);
|
||||||
|
|
||||||
/* setup faked page fault information */
|
|
||||||
nova_utcb->items = ((addr_t)&nova_utcb->qual[2] - (addr_t)nova_utcb->msg) / sizeof(addr_t);
|
|
||||||
nova_utcb->ip = 0xbadaffe;
|
|
||||||
nova_utcb->qual[1] = (addr_t)&mem;
|
|
||||||
nova_utcb->crd_rcv = Nova::Mem_crd(map_to >> 12, 0, mapping_rwx);
|
|
||||||
|
|
||||||
/* trigger faked page fault */
|
|
||||||
Genode::uint8_t res = Nova::call(page_fault_portal);
|
|
||||||
if (res != Nova::NOVA_OK) {
|
|
||||||
log("call result=", res);
|
|
||||||
failed++;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check that we really got the mapping */
|
/* check that we really got the mapping */
|
||||||
touch_read(reinterpret_cast<unsigned char *>(map_to));
|
touch_read(reinterpret_cast<unsigned char *>(map_to));
|
||||||
|
|
||||||
/* print status information in interval of 32M */
|
/* print status information in interval of 32M */
|
||||||
if (!(map_to & (32UL * 1024 * 1024 - 1))) {
|
if (i % 8192 == 0) {
|
||||||
log(Hex(map_to));
|
/* transfer some quota to avoid tons of upgrade messages */
|
||||||
|
char const * const buf = "ram_quota=1280K";
|
||||||
|
_env.parent().upgrade(_env.pd_session_cap(), buf);
|
||||||
|
log(Hex(i * 4096));
|
||||||
/* trigger some work to see quota in kernel decreasing */
|
/* trigger some work to see quota in kernel decreasing */
|
||||||
// Nova::Rights rwx(true, true, true);
|
// Nova::Rights rwx(true, true, true);
|
||||||
// Nova::revoke(Nova::Mem_crd((map_to - 32 * 1024 * 1024) >> 12, 12, rwx));
|
// Nova::revoke(Nova::Mem_crd((map_to - 32 * 1024 * 1024) >> 12, 12, rwx));
|
||||||
|
@ -83,15 +83,21 @@ static bool map_eager(Genode::addr_t const page, unsigned log2_order)
|
|||||||
|
|
||||||
addr_t const page_fault_portal = myself->native_thread().exc_pt_sel + 14;
|
addr_t const page_fault_portal = myself->native_thread().exc_pt_sel + 14;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
/* setup faked page fault information */
|
/* setup faked page fault information */
|
||||||
utcb->set_msg_word(((addr_t)&utcb->qual[2] - (addr_t)utcb->msg) / sizeof(addr_t));
|
utcb->set_msg_word(((addr_t)&utcb->qual[2] - (addr_t)utcb->msg) /
|
||||||
|
sizeof(addr_t));
|
||||||
utcb->ip = reinterpret_cast<addr_t>(map_eager);
|
utcb->ip = reinterpret_cast<addr_t>(map_eager);
|
||||||
utcb->qual[1] = page;
|
utcb->qual[1] = page;
|
||||||
utcb->crd_rcv = Nova::Mem_crd(page >> 12, log2_order - 12, mapping_rw);
|
utcb->crd_rcv = Nova::Mem_crd(page >> 12, log2_order - 12, mapping_rw);
|
||||||
|
|
||||||
/* trigger faked page fault */
|
/* trigger faked page fault */
|
||||||
Genode::uint8_t res = Nova::call(page_fault_portal);
|
Genode::uint8_t res = Nova::call(page_fault_portal);
|
||||||
|
|
||||||
|
bool const retry = utcb->msg_words();
|
||||||
|
if (res != Nova::NOVA_OK || !retry)
|
||||||
return res == Nova::NOVA_OK;
|
return res == Nova::NOVA_OK;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -174,7 +180,7 @@ void Platform::Device_pd_component::assign_pci(Genode::Io_mem_dataspace_capabili
|
|||||||
"phys=", Genode::Hex(ds_client.phys_addr()), " "
|
"phys=", Genode::Hex(ds_client.phys_addr()), " "
|
||||||
"virt=", Genode::Hex(page));
|
"virt=", Genode::Hex(page));
|
||||||
else
|
else
|
||||||
Genode::log("assignment of ", rid, " succeeded");
|
Genode::log("assignment of PCI device ", Rid(rid), " succeeded");
|
||||||
|
|
||||||
/* we don't need the mapping anymore */
|
/* we don't need the mapping anymore */
|
||||||
_address_space.detach(page);
|
_address_space.detach(page);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user