mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 17:52:52 +00:00
parent
4be8c2daa4
commit
66e9ca12b5
@ -35,7 +35,7 @@ install_config $config
|
||||
|
||||
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
|
||||
|
||||
|
@ -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
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -25,7 +25,9 @@
|
||||
#include <os/config.h>
|
||||
|
||||
#include <trace/timestamp.h>
|
||||
|
||||
#include <nova/native_thread.h>
|
||||
#include <nova_native_pd/client.h>
|
||||
|
||||
#include "server.h"
|
||||
|
||||
@ -412,6 +414,154 @@ void test_server_oom(Genode::Env &env)
|
||||
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 {
|
||||
|
||||
private:
|
||||
@ -557,6 +707,8 @@ Main::Main(Env &env) : env(env)
|
||||
check(res, "pt_ctrl %2u", i);
|
||||
}
|
||||
|
||||
test_delegate_revoke_smp(env);
|
||||
|
||||
/* test PAT kernel feature */
|
||||
test_pat(env);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user