mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-11 03:41:43 +00:00
parent
4be8c2daa4
commit
66e9ca12b5
@ -35,7 +35,7 @@ install_config $config
|
|||||||
|
|
||||||
build_boot_image "core init test-platform"
|
build_boot_image "core init test-platform"
|
||||||
|
|
||||||
append qemu_args "-nographic -m 128"
|
append qemu_args "-nographic -m 128 -smp 2"
|
||||||
|
|
||||||
run_genode_until {Test finished} 150
|
run_genode_until {Test finished} 150
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 Genode Labs GmbH
|
* Copyright (C) 2015-2016 Genode Labs GmbH
|
||||||
*
|
*
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
@ -25,7 +25,9 @@
|
|||||||
#include <os/config.h>
|
#include <os/config.h>
|
||||||
|
|
||||||
#include <trace/timestamp.h>
|
#include <trace/timestamp.h>
|
||||||
|
|
||||||
#include <nova/native_thread.h>
|
#include <nova/native_thread.h>
|
||||||
|
#include <nova_native_pd/client.h>
|
||||||
|
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
@ -412,6 +414,154 @@ void test_server_oom(Genode::Env &env)
|
|||||||
ep.dissolve(&component);
|
ep.dissolve(&component);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Pager : private Genode::Thread {
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Native_capability _call_to_map;
|
||||||
|
Ram_dataspace_capability _ds;
|
||||||
|
static addr_t _ds_mem;
|
||||||
|
|
||||||
|
void entry() { }
|
||||||
|
|
||||||
|
static void page_fault()
|
||||||
|
{
|
||||||
|
Thread * myself = Thread::myself();
|
||||||
|
Nova::Utcb * utcb = reinterpret_cast<Nova::Utcb *>(myself->utcb());
|
||||||
|
|
||||||
|
if (utcb->msg_words() != 1) {
|
||||||
|
Genode::error("unexpected");
|
||||||
|
while (1) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
Genode::addr_t map_from = utcb->msg[0];
|
||||||
|
// Genode::error("pager: got map request ", Genode::Hex(map_from));
|
||||||
|
|
||||||
|
utcb->set_msg_word(0);
|
||||||
|
utcb->mtd = 0;
|
||||||
|
|
||||||
|
Nova::Mem_crd crd_map(map_from >> 12, 0, Nova::Rights(true, true, true));
|
||||||
|
bool res = utcb->append_item(crd_map, 0);
|
||||||
|
(void)res;
|
||||||
|
|
||||||
|
Nova::reply(myself->stack_top());
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Pager(Genode::Env &env, Location location)
|
||||||
|
:
|
||||||
|
Thread(env, "pager", 0x1000, location, Weight(), env.cpu()),
|
||||||
|
_ds(env.ram().alloc (4096))
|
||||||
|
{
|
||||||
|
_ds_mem = env.rm().attach(_ds);
|
||||||
|
touch_read(reinterpret_cast<unsigned char *>(_ds_mem));
|
||||||
|
|
||||||
|
/* request creation of a 'local' EC */
|
||||||
|
Thread::native_thread().ec_sel = Native_thread::INVALID_INDEX - 1;
|
||||||
|
Thread::start();
|
||||||
|
|
||||||
|
Genode::warning("pager: created");
|
||||||
|
|
||||||
|
Native_capability thread_cap =
|
||||||
|
Capability_space::import(Thread::native_thread().ec_sel);
|
||||||
|
|
||||||
|
Genode::Nova_native_pd_client native_pd(env.pd().native_pd());
|
||||||
|
Nova::Mtd mtd (Nova::Mtd::QUAL | Nova::Mtd::EIP | Nova::Mtd::ESP);
|
||||||
|
Genode::addr_t entry = reinterpret_cast<Genode::addr_t>(page_fault);
|
||||||
|
|
||||||
|
_call_to_map = native_pd.alloc_rpc_cap(thread_cap, entry,
|
||||||
|
mtd.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
Native_capability call_to_map() { return _call_to_map; }
|
||||||
|
addr_t mem_st() { return _ds_mem; }
|
||||||
|
};
|
||||||
|
|
||||||
|
addr_t Pager::_ds_mem;
|
||||||
|
|
||||||
|
class Cause_mapping : public Genode::Thread {
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Native_capability _call_to_map;
|
||||||
|
Rm_connection _rm;
|
||||||
|
Region_map_client _sub_rm;
|
||||||
|
addr_t _mem_nd;
|
||||||
|
addr_t _mem_st;
|
||||||
|
Nova::Rights const _mapping_rwx = {true, true, true};
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
unsigned volatile called = 0;
|
||||||
|
|
||||||
|
Cause_mapping(Genode::Env &env, Native_capability call_to_map,
|
||||||
|
Genode::addr_t mem_st, Location location)
|
||||||
|
:
|
||||||
|
Thread(env, "mapper", 0x1000, location, Weight(), env.cpu()),
|
||||||
|
_call_to_map(call_to_map),
|
||||||
|
_rm(env),
|
||||||
|
_sub_rm(_rm.create(0x2000)),
|
||||||
|
_mem_nd(env.rm().attach(_sub_rm.dataspace())),
|
||||||
|
_mem_st(mem_st)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void entry() {
|
||||||
|
|
||||||
|
log("mapper: hello");
|
||||||
|
|
||||||
|
Nova::Utcb * nova_utcb = reinterpret_cast<Nova::Utcb *>(utcb());
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
called ++;
|
||||||
|
// log("mapper: request mapping ", Hex(_mem_nd), " ", called);
|
||||||
|
|
||||||
|
Nova::Crd old = nova_utcb->crd_rcv;
|
||||||
|
|
||||||
|
// touch_read((unsigned char *)_mem_st);
|
||||||
|
|
||||||
|
nova_utcb->msg[0] = _mem_st;
|
||||||
|
nova_utcb->set_msg_word(1);
|
||||||
|
nova_utcb->crd_rcv = Nova::Mem_crd(_mem_nd >> 12, 0,
|
||||||
|
_mapping_rwx);
|
||||||
|
Nova::call(_call_to_map.local_name());
|
||||||
|
//touch_read((unsigned char *)_mem_nd);
|
||||||
|
|
||||||
|
nova_utcb->msg[0] = _mem_nd;
|
||||||
|
nova_utcb->set_msg_word(1);
|
||||||
|
nova_utcb->crd_rcv = Nova::Mem_crd((_mem_nd + 0x1000) >> 12, 0,
|
||||||
|
_mapping_rwx);
|
||||||
|
Nova::call(_call_to_map.local_name());
|
||||||
|
// touch_read((unsigned char *)_mem_nd + 0x1000);
|
||||||
|
|
||||||
|
nova_utcb->crd_rcv = old;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void revoke_remote()
|
||||||
|
{
|
||||||
|
Nova::revoke(Nova::Mem_crd(_mem_nd >> 12, 0, _mapping_rwx), true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void test_delegate_revoke_smp(Genode::Env &env)
|
||||||
|
{
|
||||||
|
Affinity::Space cpus = env.cpu().affinity_space();
|
||||||
|
Genode::log("detected ", cpus.width(), "x", cpus.height(), " "
|
||||||
|
"CPU", cpus.total() > 1 ? "s." : ".");
|
||||||
|
|
||||||
|
Pager pager(env, cpus.location_of_index(1));
|
||||||
|
Cause_mapping mapper(env, pager.call_to_map(), pager.mem_st(),
|
||||||
|
cpus.location_of_index(1));
|
||||||
|
mapper.start();
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < 2000; i++) {
|
||||||
|
mapper.revoke_remote();
|
||||||
|
if (i % 1000 == 0)
|
||||||
|
Genode::log("main ", i, " ", mapper.called);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class Greedy : public Genode::Thread {
|
class Greedy : public Genode::Thread {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -557,6 +707,8 @@ Main::Main(Env &env) : env(env)
|
|||||||
check(res, "pt_ctrl %2u", i);
|
check(res, "pt_ctrl %2u", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test_delegate_revoke_smp(env);
|
||||||
|
|
||||||
/* test PAT kernel feature */
|
/* test PAT kernel feature */
|
||||||
test_pat(env);
|
test_pat(env);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user