mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-18 17:00:26 +00:00
vancouver: Improve locking scheme
This patch replaces the error-prone manual locking with the use of the 'Synced_interface' for the motherboard and the VCPU dispatcher. It also removes all globally visible locks. Locks are now explicitly passed to subsystems when needed.
This commit is contained in:
parent
c48a7aa27f
commit
89d0e68983
@ -33,7 +33,6 @@
|
||||
extern char _binary_mono_tff_start;
|
||||
Font default_font(&_binary_mono_tff_start);
|
||||
|
||||
extern Genode::Lock global_lock;
|
||||
|
||||
using Genode::env;
|
||||
using Genode::Dataspace_client;
|
||||
@ -154,12 +153,6 @@ void Vancouver_console::entry()
|
||||
{
|
||||
Logging::printf("Hello, this is VancouverConsole.\n");
|
||||
|
||||
/* register host operations */
|
||||
_mb.bus_console.add(this, receive_static<MessageConsole>);
|
||||
_mb.bus_memregion.add(this, receive_static<MessageMemRegion>);
|
||||
|
||||
/* create environment for input/output */
|
||||
|
||||
/*
|
||||
* Init sessions to the required external services
|
||||
*/
|
||||
@ -187,7 +180,7 @@ void Vancouver_console::entry()
|
||||
*/
|
||||
unsigned long count = 0;
|
||||
bool revoked = false;
|
||||
Vancouver_keyboard vkeyb(_mb);
|
||||
Vancouver_keyboard vkeyb(_motherboard);
|
||||
|
||||
Genode::uint64_t checksum1 = 0;
|
||||
Genode::uint64_t checksum2 = 0;
|
||||
@ -234,15 +227,13 @@ void Vancouver_console::entry()
|
||||
/* if we copy the same data 10 times, unmap the text buffer from guest */
|
||||
if (unchanged == 10) {
|
||||
|
||||
/* protect against thread interference */
|
||||
global_lock.lock();
|
||||
Genode::Lock::Guard guard(_console_lock);
|
||||
|
||||
env()->rm_session()->detach((void *)_guest_fb);
|
||||
env()->rm_session()->attach_at(_fb_ds, (Genode::addr_t)_guest_fb);
|
||||
unchanged = 0;
|
||||
fb_active = false;
|
||||
|
||||
global_lock.unlock();
|
||||
Logging::printf("Deactivated text buffer loop.\n");
|
||||
}
|
||||
} else unchanged = 0;
|
||||
@ -252,8 +243,7 @@ void Vancouver_console::entry()
|
||||
|
||||
if (!revoked) {
|
||||
|
||||
/* protect against thread interference */
|
||||
global_lock.lock();
|
||||
Genode::Lock::Guard guard(_console_lock);
|
||||
|
||||
env()->rm_session()->detach((void *)_guest_fb);
|
||||
env()->rm_session()->attach_at(framebuffer.dataspace(),
|
||||
@ -269,13 +259,11 @@ void Vancouver_console::entry()
|
||||
}
|
||||
|
||||
revoked = true;
|
||||
|
||||
global_lock.unlock();
|
||||
}
|
||||
}
|
||||
framebuffer.refresh(0, 0, _fb_mode.width(), _fb_mode.height());
|
||||
|
||||
timer.msleep(10);
|
||||
timer.msleep(100);
|
||||
}
|
||||
|
||||
for (int i = 0, num_ev = input.flush(); i < num_ev; i++) {
|
||||
@ -284,7 +272,7 @@ void Vancouver_console::entry()
|
||||
/* update mouse model (PS2) */
|
||||
unsigned mouse = mouse_value(ev);
|
||||
MessageInput msg(0x10001, mouse);
|
||||
_mb.bus_input.send(msg);
|
||||
_motherboard()->bus_input.send(msg);
|
||||
|
||||
if (ev->type() == Input::Event::PRESS) {
|
||||
if (ev->code() <= 0xee) {
|
||||
@ -301,11 +289,21 @@ void Vancouver_console::entry()
|
||||
}
|
||||
|
||||
|
||||
Vancouver_console::Vancouver_console(Motherboard &mb, Genode::size_t vm_fb_size,
|
||||
void Vancouver_console::register_host_operations(Motherboard &motherboard)
|
||||
{
|
||||
motherboard.bus_console. add(this, receive_static<MessageConsole>);
|
||||
motherboard.bus_memregion.add(this, receive_static<MessageMemRegion>);
|
||||
}
|
||||
|
||||
|
||||
Vancouver_console::Vancouver_console(Synced_motherboard &mb,
|
||||
Genode::Lock &console_lock,
|
||||
Genode::size_t vm_fb_size,
|
||||
Genode::Dataspace_capability fb_ds)
|
||||
:
|
||||
_startup_lock(Genode::Lock::LOCKED),
|
||||
_vm_fb_size(vm_fb_size), _mb(mb), _fb_size(0), _pixels(0), _guest_fb(0),
|
||||
_vm_fb_size(vm_fb_size), _motherboard(mb), _console_lock(console_lock),
|
||||
_fb_size(0), _pixels(0), _guest_fb(0),
|
||||
_regs(0), _fb_ds(fb_ds)
|
||||
{
|
||||
start();
|
||||
|
@ -29,8 +29,8 @@
|
||||
#include <timer_session/connection.h>
|
||||
#include <dataspace/client.h>
|
||||
|
||||
/* NOVA userland includes */
|
||||
#include <nul/motherboard.h>
|
||||
/* local includes */
|
||||
#include <synced_motherboard.h>
|
||||
|
||||
/* includes for I/O */
|
||||
#include <base/env.h>
|
||||
@ -47,13 +47,14 @@ class Vancouver_console : public Thread<8192>, public StaticReceiver<Vancouver_c
|
||||
private:
|
||||
|
||||
Genode::Lock _startup_lock;
|
||||
Motherboard &_mb;
|
||||
short *_pixels;
|
||||
char *_guest_fb;
|
||||
Synced_motherboard &_motherboard;
|
||||
Genode::Lock &_console_lock;
|
||||
short *_pixels;
|
||||
char *_guest_fb;
|
||||
unsigned long _fb_size;
|
||||
Genode::Dataspace_capability _fb_ds;
|
||||
Genode::size_t _vm_fb_size;
|
||||
VgaRegs *_regs;
|
||||
VgaRegs *_regs;
|
||||
Framebuffer::Mode _fb_mode;
|
||||
|
||||
public:
|
||||
@ -62,13 +63,17 @@ class Vancouver_console : public Thread<8192>, public StaticReceiver<Vancouver_c
|
||||
bool receive(MessageConsole &msg);
|
||||
bool receive(MessageMemRegion &msg);
|
||||
|
||||
void register_host_operations(Motherboard &);
|
||||
|
||||
/* initialisation */
|
||||
void entry();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Vancouver_console(Motherboard &mb, Genode::size_t vm_fb_size,
|
||||
Vancouver_console(Synced_motherboard &,
|
||||
Genode::Lock &console_lock,
|
||||
Genode::size_t vm_fb_size,
|
||||
Genode::Dataspace_capability fb_ds);
|
||||
};
|
||||
|
||||
|
@ -31,15 +31,13 @@
|
||||
|
||||
static Genode::Native_utcb utcb_backup;
|
||||
|
||||
extern Genode::Lock timeouts_lock;
|
||||
|
||||
|
||||
Vancouver_disk::Vancouver_disk(Motherboard &mb,
|
||||
Vancouver_disk::Vancouver_disk(Synced_motherboard &mb,
|
||||
char * backing_store_base,
|
||||
char * backing_store_fb_base)
|
||||
:
|
||||
_startup_lock(Genode::Lock::LOCKED),
|
||||
_mb(mb), _backing_store_base(backing_store_base),
|
||||
_motherboard(mb), _backing_store_base(backing_store_base),
|
||||
_backing_store_fb_base(backing_store_fb_base)
|
||||
{
|
||||
/* initialize struct with 0 size */
|
||||
@ -53,13 +51,16 @@ Vancouver_disk::Vancouver_disk(Motherboard &mb,
|
||||
}
|
||||
|
||||
|
||||
void Vancouver_disk::register_host_operations(Motherboard &motherboard)
|
||||
{
|
||||
motherboard.bus_disk.add(this, receive_static<MessageDisk>);
|
||||
}
|
||||
|
||||
|
||||
void Vancouver_disk::entry()
|
||||
{
|
||||
Logging::printf("Hello, this is Vancouver_disk.\n");
|
||||
|
||||
/* attach to disk bus */
|
||||
_mb.bus_disk.add(this, receive_static<MessageDisk>);
|
||||
|
||||
_startup_lock.unlock();
|
||||
}
|
||||
|
||||
@ -124,7 +125,7 @@ bool Vancouver_disk::receive(MessageDisk &msg)
|
||||
if (!read && !_diskcon[msg.disknr].ops.supported(Block::Packet_descriptor::WRITE)) {
|
||||
MessageDiskCommit ro(msg.disknr, msg.usertag,
|
||||
MessageDisk::DISK_STATUS_DEVICE);
|
||||
_mb.bus_diskcommit.send(ro);
|
||||
_motherboard()->bus_diskcommit.send(ro);
|
||||
*Genode::Thread_base::myself()->utcb() = utcb_backup;
|
||||
return true;
|
||||
}
|
||||
@ -177,29 +178,26 @@ bool Vancouver_disk::receive(MessageDisk &msg)
|
||||
if (!p.succeeded()) {
|
||||
Logging::printf("Operation failed.\n");
|
||||
{
|
||||
Genode::Lock::Guard guard(timeouts_lock);
|
||||
MessageDiskCommit commit(msg.disknr, msg.usertag,
|
||||
MessageDisk::DISK_STATUS_DEVICE);
|
||||
_mb.bus_diskcommit.send(commit);
|
||||
_motherboard()->bus_diskcommit.send(commit);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Genode::Lock::Guard guard(timeouts_lock);
|
||||
MessageDiskCommit commit(msg.disknr, msg.usertag,
|
||||
MessageDisk::DISK_OK);
|
||||
_mb.bus_diskcommit.send(commit);
|
||||
_motherboard()->bus_diskcommit.send(commit);
|
||||
}
|
||||
} else {
|
||||
|
||||
Logging::printf("Operation failed.\n");
|
||||
{
|
||||
Genode::Lock::Guard guard(timeouts_lock);
|
||||
MessageDiskCommit commit(msg.disknr, msg.usertag,
|
||||
MessageDisk::DISK_STATUS_DEVICE);
|
||||
_mb.bus_diskcommit.send(commit);
|
||||
_motherboard()->bus_diskcommit.send(commit);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,8 +29,10 @@
|
||||
#include <block_session/connection.h>
|
||||
#include <util/string.h>
|
||||
|
||||
/* local includes */
|
||||
#include <synced_motherboard.h>
|
||||
|
||||
/* NOVA userland includes */
|
||||
#include <nul/motherboard.h>
|
||||
#include <host/dma.h>
|
||||
|
||||
static const bool read_only = false;
|
||||
@ -48,17 +50,17 @@ class Vancouver_disk : public Genode::Thread<8192>, public StaticReceiver<Vancou
|
||||
Genode::size_t blk_cnt;
|
||||
} _diskcon[MAX_DISKS];
|
||||
|
||||
Genode::Lock _startup_lock;
|
||||
Motherboard &_mb;
|
||||
char *_backing_store_base;
|
||||
char *_backing_store_fb_base;
|
||||
Genode::Lock _startup_lock;
|
||||
Synced_motherboard &_motherboard;
|
||||
char *_backing_store_base;
|
||||
char *_backing_store_fb_base;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Vancouver_disk(Motherboard &mb,
|
||||
Vancouver_disk(Synced_motherboard &,
|
||||
char * backing_store_base,
|
||||
char * backing_store_fb_base);
|
||||
|
||||
@ -67,6 +69,8 @@ class Vancouver_disk : public Genode::Thread<8192>, public StaticReceiver<Vancou
|
||||
void entry();
|
||||
|
||||
bool receive(MessageDisk &msg);
|
||||
|
||||
void register_host_operations(Motherboard &);
|
||||
};
|
||||
|
||||
#endif /* _DISK_H_ */
|
||||
|
@ -25,11 +25,9 @@
|
||||
#include <host/keyboard.h>
|
||||
#include <nul/vcpu.h>
|
||||
|
||||
extern Genode::Lock global_lock;
|
||||
|
||||
|
||||
Vancouver_keyboard::Vancouver_keyboard(Motherboard &mb)
|
||||
: _mb(mb), _flags(0) { }
|
||||
Vancouver_keyboard::Vancouver_keyboard(Synced_motherboard &mb)
|
||||
: _motherboard(mb), _flags(0) { }
|
||||
|
||||
|
||||
void Vancouver_keyboard::handle_keycode_press(unsigned keycode)
|
||||
@ -93,19 +91,18 @@ void Vancouver_keyboard::handle_keycode_press(unsigned keycode)
|
||||
|
||||
/* we send an empty event */
|
||||
CpuEvent msg(VCpu::EVENT_DEBUG);
|
||||
for (VCpu *vcpu = _mb.last_vcpu; vcpu; vcpu=vcpu->get_last())
|
||||
for (VCpu *vcpu = _motherboard()->last_vcpu; vcpu; vcpu=vcpu->get_last())
|
||||
vcpu->bus_event.send(msg);
|
||||
}
|
||||
|
||||
/* reset */
|
||||
else if ((_flags & KBFLAG_LWIN) && orig_keycode == Input::KEY_END) {
|
||||
Genode::Lock::Guard guard(global_lock);
|
||||
Logging::printf("Reset VM\n");
|
||||
MessageLegacy msg2(MessageLegacy::RESET, 0);
|
||||
_mb.bus_legacy.send_fifo(msg2);
|
||||
_motherboard()->bus_legacy.send_fifo(msg2);
|
||||
}
|
||||
|
||||
else _mb.bus_input.send(msg);
|
||||
else _motherboard()->bus_input.send(msg);
|
||||
|
||||
_flags &= ~(KBFLAG_EXTEND0 | KBFLAG_RELEASE | KBFLAG_EXTEND1);
|
||||
}
|
||||
@ -165,7 +162,7 @@ void Vancouver_keyboard::handle_keycode_release(unsigned keycode)
|
||||
}
|
||||
|
||||
MessageInput msg(0x10000, _flags | keycode);
|
||||
_mb.bus_input.send(msg);
|
||||
_motherboard()->bus_input.send(msg);
|
||||
|
||||
_flags &= ~(KBFLAG_EXTEND0 | KBFLAG_RELEASE | KBFLAG_EXTEND1);
|
||||
}
|
||||
|
@ -21,8 +21,8 @@
|
||||
#ifndef _KEYBOARD_H_
|
||||
#define _KEYBOARD_H_
|
||||
|
||||
/* NOVA userland includes */
|
||||
#include <nul/motherboard.h>
|
||||
/* local includes */
|
||||
#include <synced_motherboard.h>
|
||||
|
||||
/* includes for I/O */
|
||||
#include <base/env.h>
|
||||
@ -33,15 +33,15 @@ class Vancouver_keyboard
|
||||
{
|
||||
private:
|
||||
|
||||
Motherboard &_mb;
|
||||
unsigned _flags;
|
||||
Synced_motherboard &_motherboard;
|
||||
unsigned _flags;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Vancouver_keyboard(Motherboard &mb);
|
||||
Vancouver_keyboard(Synced_motherboard &);
|
||||
|
||||
void handle_keycode_press(unsigned keycode);
|
||||
void handle_keycode_release(unsigned keycode);
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include <nic_session/connection.h>
|
||||
#include <os/config.h>
|
||||
#include <os/alarm.h>
|
||||
#include <os/synced_interface.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <nova_cpu_session/connection.h>
|
||||
#include <rtc_session/connection.h>
|
||||
@ -60,6 +61,7 @@
|
||||
#include <sys/hip.h>
|
||||
|
||||
/* local includes */
|
||||
#include <synced_motherboard.h>
|
||||
#include <device_model_registry.h>
|
||||
#include <boot_module_provider.h>
|
||||
#include <console.h>
|
||||
@ -84,29 +86,23 @@ Genode::Lock *utcb_lock()
|
||||
return &inst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Semaphore used as global lock
|
||||
*
|
||||
* Used for startup synchronization and coarse-grained locking.
|
||||
*/
|
||||
Genode::Lock global_lock(Genode::Lock::LOCKED);
|
||||
Genode::Lock timeouts_lock(Genode::Lock::UNLOCKED);
|
||||
|
||||
|
||||
/* timer service */
|
||||
using Genode::Thread;
|
||||
using Genode::Alarm_scheduler;
|
||||
using Genode::Alarm;
|
||||
|
||||
typedef Genode::Synced_interface<TimeoutList<32, void> > Synced_timeout_list;
|
||||
|
||||
class Alarm_thread : Thread<4096>, public Alarm_scheduler
|
||||
{
|
||||
private:
|
||||
|
||||
Timer::Connection _timer;
|
||||
Alarm::Time _curr_time; /* jiffies value */
|
||||
Timer::Connection _timer;
|
||||
Alarm::Time _curr_time; /* jiffies value */
|
||||
|
||||
Motherboard &_motherboard;
|
||||
TimeoutList<32, void> &_timeouts;
|
||||
Synced_motherboard &_motherboard;
|
||||
Synced_timeout_list &_timeouts;
|
||||
|
||||
/**
|
||||
* Thread entry function
|
||||
@ -114,27 +110,19 @@ class Alarm_thread : Thread<4096>, public Alarm_scheduler
|
||||
void entry()
|
||||
{
|
||||
while (true) {
|
||||
unsigned long long now = _motherboard.clock()->time();
|
||||
unsigned long long now = _motherboard()->clock()->time();
|
||||
unsigned nr;
|
||||
|
||||
timeouts_lock.lock();
|
||||
while ((nr = _timeouts()->trigger(now))) {
|
||||
|
||||
while ((nr = _timeouts.trigger(now))) {
|
||||
MessageTimeout msg(nr, _timeouts()->timeout());
|
||||
|
||||
MessageTimeout msg(nr, _timeouts.timeout());
|
||||
|
||||
if (_timeouts.cancel(nr) < 0)
|
||||
if (_timeouts()->cancel(nr) < 0)
|
||||
Logging::printf("Timeout not cancelled.\n");
|
||||
|
||||
timeouts_lock.unlock();
|
||||
|
||||
_motherboard.bus_timeout.send(msg);
|
||||
|
||||
timeouts_lock.lock();
|
||||
_motherboard()->bus_timeout.send(msg);
|
||||
}
|
||||
|
||||
timeouts_lock.unlock();
|
||||
|
||||
_timer.usleep(1000);
|
||||
}
|
||||
}
|
||||
@ -144,11 +132,11 @@ class Alarm_thread : Thread<4096>, public Alarm_scheduler
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Alarm_thread(Motherboard &mb, TimeoutList<32, void> &timeouts)
|
||||
Alarm_thread(Synced_motherboard &mb, Synced_timeout_list &timeouts)
|
||||
: _curr_time(0), _motherboard(mb), _timeouts(timeouts) { start(); }
|
||||
|
||||
Alarm::Time curr_time() { return _curr_time; }
|
||||
unsigned long long curr_time_long() { return _motherboard.clock()->time(); }
|
||||
unsigned long long curr_time_long() { return _motherboard()->clock()->time(); }
|
||||
};
|
||||
|
||||
|
||||
@ -354,7 +342,7 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
|
||||
/**
|
||||
* Pointer to corresponding VCPU model
|
||||
*/
|
||||
VCpu * const _vcpu;
|
||||
Genode::Synced_interface<VCpu> _vcpu;
|
||||
|
||||
Vcpu_thread _vcpu_thread;
|
||||
|
||||
@ -366,7 +354,7 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
|
||||
/**
|
||||
* Motherboard representing the inter-connections of all device models
|
||||
*/
|
||||
Motherboard &_motherboard;
|
||||
Synced_motherboard &_motherboard;
|
||||
|
||||
|
||||
/***************
|
||||
@ -413,12 +401,10 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
|
||||
if (skip == SKIP)
|
||||
_skip_instruction(msg);
|
||||
|
||||
Genode::Lock::Guard guard(global_lock);
|
||||
|
||||
/**
|
||||
* Send the message to the VCpu.
|
||||
*/
|
||||
if (!_vcpu->executor.send(msg, true))
|
||||
if (!_vcpu()->executor.send(msg, true))
|
||||
Logging::panic("nobody to execute %s at %x:%x\n",
|
||||
__func__, msg.cpu->cs.sel, msg.cpu->eip);
|
||||
|
||||
@ -427,7 +413,7 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
|
||||
*/
|
||||
if (msg.mtr_in & MTD_INJ && msg.type != CpuMessage::TYPE_CHECK_IRQ) {
|
||||
msg.type = CpuMessage::TYPE_CHECK_IRQ;
|
||||
if (!_vcpu->executor.send(msg, true))
|
||||
if (!_vcpu()->executor.send(msg, true))
|
||||
Logging::panic("nobody to execute %s at %x:%x\n",
|
||||
__func__, msg.cpu->cs.sel, msg.cpu->eip);
|
||||
}
|
||||
@ -437,7 +423,7 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
|
||||
*/
|
||||
if (msg.mtr_out & MTD_INJ) {
|
||||
msg.type = CpuMessage::TYPE_CALC_IRQWINDOW;
|
||||
if (!_vcpu->executor.send(msg, true))
|
||||
if (!_vcpu()->executor.send(msg, true))
|
||||
Logging::panic("nobody to execute %s at %x:%x\n",
|
||||
__func__, msg.cpu->cs.sel, msg.cpu->eip);
|
||||
}
|
||||
@ -510,7 +496,7 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
|
||||
|
||||
MessageMemRegion mem_region(vm_fault_addr >> PAGE_SIZE_LOG2);
|
||||
|
||||
if (!_motherboard.bus_memregion.send(mem_region, false) ||
|
||||
if (!_motherboard()->bus_memregion.send(mem_region, false) ||
|
||||
!mem_region.ptr)
|
||||
return false;
|
||||
|
||||
@ -564,7 +550,7 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
|
||||
CpuMessage _win(CpuMessage::TYPE_CALC_IRQWINDOW,
|
||||
static_cast<CpuState *>(utcb), utcb->mtd);
|
||||
_win.mtr_out = MTD_INJ;
|
||||
if (!_vcpu->executor.send(_win, true))
|
||||
if (!_vcpu()->executor.send(_win, true))
|
||||
Logging::panic("nobody to execute %s at %x:%x\n",
|
||||
__func__, utcb->cs.sel, utcb->eip);
|
||||
}
|
||||
@ -588,8 +574,7 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
|
||||
port, &utcb->eax, utcb->mtd);
|
||||
_skip_instruction(msg);
|
||||
{
|
||||
Genode::Lock::Guard l(global_lock);
|
||||
if (!_vcpu->executor.send(msg, true))
|
||||
if (!_vcpu()->executor.send(msg, true))
|
||||
Logging::panic("nobody to execute %s at %x:%x\n",
|
||||
__func__, msg.cpu->cs.sel, msg.cpu->eip);
|
||||
}
|
||||
@ -812,13 +797,14 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
|
||||
|
||||
public:
|
||||
|
||||
Vcpu_dispatcher(VCpu *vcpu,
|
||||
Vcpu_dispatcher(Genode::Lock &vcpu_lock,
|
||||
VCpu *unsynchronized_vcpu,
|
||||
Guest_memory &guest_memory,
|
||||
Motherboard &motherboard,
|
||||
Synced_motherboard &motherboard,
|
||||
bool has_svm,
|
||||
bool has_vmx)
|
||||
:
|
||||
_vcpu(vcpu),
|
||||
_vcpu(vcpu_lock, unsynchronized_vcpu),
|
||||
_vcpu_thread("vCPU thread"),
|
||||
_guest_memory(guest_memory),
|
||||
_motherboard(motherboard)
|
||||
@ -949,7 +935,7 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
|
||||
_vcpu_thread.start(sel_sm_ec() + 1);
|
||||
|
||||
/* handle cpuid overrides */
|
||||
vcpu->executor.add(this, receive_static<CpuMessage>);
|
||||
unsynchronized_vcpu->executor.add(this, receive_static<CpuMessage>);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1029,8 +1015,12 @@ class Machine : public StaticReceiver<Machine>
|
||||
Genode::Rom_connection _hip_rom;
|
||||
Hip * const _hip;
|
||||
Clock _clock;
|
||||
Motherboard _motherboard;
|
||||
TimeoutList<32, void> _timeouts;
|
||||
Genode::Lock _motherboard_lock;
|
||||
Motherboard _unsynchronized_motherboard;
|
||||
Synced_motherboard _motherboard;
|
||||
Genode::Lock _timeouts_lock;
|
||||
TimeoutList<32, void> _unsynchronized_timeouts;
|
||||
Synced_timeout_list _timeouts;
|
||||
Guest_memory &_guest_memory;
|
||||
Boot_module_provider &_boot_modules;
|
||||
Alarm_thread *_alarm_thread;
|
||||
@ -1111,7 +1101,8 @@ class Machine : public StaticReceiver<Machine>
|
||||
Logging::printf("OP_VCPU_CREATE_BACKEND\n");
|
||||
|
||||
Vcpu_dispatcher *vcpu_dispatcher =
|
||||
new Vcpu_dispatcher(msg.vcpu, _guest_memory,
|
||||
new Vcpu_dispatcher(_motherboard_lock, msg.vcpu,
|
||||
_guest_memory,
|
||||
_motherboard,
|
||||
_hip->has_feature_svm(), _hip->has_feature_vmx());
|
||||
|
||||
@ -1137,11 +1128,11 @@ class Machine : public StaticReceiver<Machine>
|
||||
if (verbose_debug)
|
||||
Logging::printf("OP_VCPU_BLOCK\n");
|
||||
|
||||
global_lock.unlock();
|
||||
_motherboard_lock.unlock();
|
||||
bool res = (Nova::sm_ctrl(msg.value, Nova::SEMAPHORE_DOWN) == 0);
|
||||
if (verbose_debug)
|
||||
Logging::printf("woke up from vcpu sem, block on global_lock\n");
|
||||
global_lock.lock();
|
||||
_motherboard_lock.lock();
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -1271,20 +1262,15 @@ class Machine : public StaticReceiver<Machine>
|
||||
_alarm_thread = new Alarm_thread(_motherboard, _timeouts);
|
||||
}
|
||||
|
||||
timeouts_lock.lock();
|
||||
msg.nr = _timeouts.alloc();
|
||||
timeouts_lock.unlock();
|
||||
msg.nr = _timeouts()->alloc();
|
||||
|
||||
return true;
|
||||
|
||||
case MessageTimer::TIMER_REQUEST_TIMEOUT:
|
||||
timeouts_lock.lock();
|
||||
|
||||
if (_timeouts.request(msg.nr, msg.abstime) < 0)
|
||||
if (_timeouts()->request(msg.nr, msg.abstime) < 0)
|
||||
Logging::printf("Could not program timeout.\n");
|
||||
|
||||
timeouts_lock.unlock();
|
||||
|
||||
return true;
|
||||
|
||||
default:
|
||||
@ -1304,14 +1290,14 @@ class Machine : public StaticReceiver<Machine>
|
||||
Logging::printf("No RTC present, returning dummy time.\n");
|
||||
msg.wallclocktime = msg.timestamp = 0;
|
||||
|
||||
*Genode::Thread_base::myself()->utcb() = utcb_backup;
|
||||
*Genode::Thread_base::myself()->utcb() = utcb_backup;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
msg.wallclocktime = _rtc->get_current_time();
|
||||
Logging::printf("Got time %llx\n", msg.wallclocktime);
|
||||
msg.timestamp = _motherboard.clock()->clock(1000000U);
|
||||
msg.timestamp = _unsynchronized_motherboard.clock()->clock(1000000U);
|
||||
|
||||
*Genode::Thread_base::myself()->utcb() = utcb_backup;
|
||||
|
||||
@ -1394,21 +1380,24 @@ class Machine : public StaticReceiver<Machine>
|
||||
_hip_rom("hypervisor_info_page"),
|
||||
_hip(Genode::env()->rm_session()->attach(_hip_rom.dataspace())),
|
||||
_clock(_hip->tsc_freq*1000),
|
||||
_motherboard(&_clock, _hip),
|
||||
_motherboard_lock(Genode::Lock::LOCKED),
|
||||
_unsynchronized_motherboard(&_clock, _hip),
|
||||
_motherboard(_motherboard_lock, &_unsynchronized_motherboard),
|
||||
_timeouts(_timeouts_lock, &_unsynchronized_timeouts),
|
||||
_guest_memory(guest_memory),
|
||||
_boot_modules(boot_modules)
|
||||
{
|
||||
_timeouts.init();
|
||||
_timeouts()->init();
|
||||
|
||||
/* register host operations, called back by the VMM */
|
||||
_motherboard.bus_hostop.add (this, receive_static<MessageHostOp>);
|
||||
_motherboard.bus_disk.add (this, receive_static<MessageDisk>);
|
||||
_motherboard.bus_timer.add (this, receive_static<MessageTimer>);
|
||||
_motherboard.bus_time.add (this, receive_static<MessageTime>);
|
||||
_motherboard.bus_network.add (this, receive_static<MessageNetwork>);
|
||||
_motherboard.bus_hwpcicfg.add(this, receive_static<MessageHwPciConfig>);
|
||||
_motherboard.bus_acpi.add (this, receive_static<MessageAcpi>);
|
||||
_motherboard.bus_legacy.add (this, receive_static<MessageLegacy>);
|
||||
_unsynchronized_motherboard.bus_hostop.add (this, receive_static<MessageHostOp>);
|
||||
_unsynchronized_motherboard.bus_disk.add (this, receive_static<MessageDisk>);
|
||||
_unsynchronized_motherboard.bus_timer.add (this, receive_static<MessageTimer>);
|
||||
_unsynchronized_motherboard.bus_time.add (this, receive_static<MessageTime>);
|
||||
_unsynchronized_motherboard.bus_network.add (this, receive_static<MessageNetwork>);
|
||||
_unsynchronized_motherboard.bus_hwpcicfg.add(this, receive_static<MessageHwPciConfig>);
|
||||
_unsynchronized_motherboard.bus_acpi.add (this, receive_static<MessageAcpi>);
|
||||
_unsynchronized_motherboard.bus_legacy.add (this, receive_static<MessageLegacy>);
|
||||
}
|
||||
|
||||
|
||||
@ -1472,7 +1461,7 @@ class Machine : public StaticReceiver<Machine>
|
||||
* We never pass any argument string to a device model because
|
||||
* it is not examined by the existing device models.
|
||||
*/
|
||||
dmi->create(_motherboard, argv, "", 0);
|
||||
dmi->create(_unsynchronized_motherboard, argv, "", 0);
|
||||
|
||||
if (node.is_last())
|
||||
break;
|
||||
@ -1485,7 +1474,7 @@ class Machine : public StaticReceiver<Machine>
|
||||
void boot()
|
||||
{
|
||||
/* init VCPUs */
|
||||
for (VCpu *vcpu = _motherboard.last_vcpu; vcpu; vcpu = vcpu->get_last()) {
|
||||
for (VCpu *vcpu = _unsynchronized_motherboard.last_vcpu; vcpu; vcpu = vcpu->get_last()) {
|
||||
|
||||
/* init CPU strings */
|
||||
const char *short_name = "NOVA microHV";
|
||||
@ -1512,13 +1501,18 @@ class Machine : public StaticReceiver<Machine>
|
||||
|
||||
Logging::printf("RESET device state\n");
|
||||
MessageLegacy msg2(MessageLegacy::RESET, 0);
|
||||
_motherboard.bus_legacy.send_fifo(msg2);
|
||||
_unsynchronized_motherboard.bus_legacy.send_fifo(msg2);
|
||||
|
||||
global_lock.unlock();
|
||||
Logging::printf("INIT done\n");
|
||||
|
||||
_motherboard_lock.unlock();
|
||||
}
|
||||
|
||||
Motherboard& get_mb() { return _motherboard; }
|
||||
Synced_motherboard &motherboard() { return _motherboard; }
|
||||
|
||||
Motherboard &unsynchronized_motherboard() { return _unsynchronized_motherboard; }
|
||||
|
||||
Genode::Lock &motherboard_lock() { return _motherboard_lock; }
|
||||
|
||||
~Machine()
|
||||
{
|
||||
@ -1611,14 +1605,22 @@ int main(int argc, char **argv)
|
||||
|
||||
static Machine machine(boot_modules, guest_memory);
|
||||
|
||||
Genode::Lock fb_lock;
|
||||
|
||||
/* create console thread */
|
||||
Vancouver_console vcon(machine.get_mb(), fb_size, guest_memory.fb_ds());
|
||||
Vancouver_console vcon(machine.motherboard(),
|
||||
fb_lock,
|
||||
fb_size, guest_memory.fb_ds());
|
||||
|
||||
vcon.register_host_operations(machine.unsynchronized_motherboard());
|
||||
|
||||
/* create disk thread */
|
||||
Vancouver_disk vdisk(machine.get_mb(),
|
||||
Vancouver_disk vdisk(machine.motherboard(),
|
||||
guest_memory.backing_store_local_base(),
|
||||
guest_memory.backing_store_fb_local_base());
|
||||
|
||||
vdisk.register_host_operations(machine.unsynchronized_motherboard());
|
||||
|
||||
machine.setup_devices(Genode::config()->xml_node().sub_node("machine"));
|
||||
|
||||
Genode::printf("\n--- Booting VM ---\n");
|
||||
|
@ -24,8 +24,8 @@
|
||||
extern const void * _forward_pkt;
|
||||
|
||||
|
||||
Vancouver_network::Vancouver_network(Motherboard &mb, Nic::Session * nic)
|
||||
: _mb(mb), _nic(nic)
|
||||
Vancouver_network::Vancouver_network(Synced_motherboard &mb, Nic::Session *nic)
|
||||
: _motherboard(mb), _nic(nic)
|
||||
{
|
||||
start();
|
||||
}
|
||||
@ -42,7 +42,7 @@ void Vancouver_network::entry()
|
||||
char * rx_content = _nic->rx()->packet_content(rx_packet);
|
||||
_forward_pkt = rx_content;
|
||||
MessageNetwork msg((unsigned char *)rx_content, rx_packet.size(), 0);
|
||||
_mb.bus_network.send(msg);
|
||||
_motherboard()->bus_network.send(msg);
|
||||
_forward_pkt = 0;
|
||||
|
||||
/* acknowledge received packet */
|
||||
|
@ -24,8 +24,8 @@
|
||||
/* Genode includes */
|
||||
#include <nic_session/connection.h>
|
||||
|
||||
/* NOVA userland includes */
|
||||
#include <nul/motherboard.h>
|
||||
/* local includes */
|
||||
#include <synced_motherboard.h>
|
||||
|
||||
using Genode::List;
|
||||
using Genode::Thread;
|
||||
@ -34,8 +34,8 @@ class Vancouver_network : public Thread<4096>
|
||||
{
|
||||
private:
|
||||
|
||||
Motherboard &_mb;
|
||||
Nic::Session *_nic;
|
||||
Synced_motherboard &_motherboard;
|
||||
Nic::Session *_nic;
|
||||
|
||||
public:
|
||||
|
||||
@ -45,7 +45,7 @@ class Vancouver_network : public Thread<4096>
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Vancouver_network(Motherboard &mb, Nic::Session *nic);
|
||||
Vancouver_network(Synced_motherboard &, Nic::Session *);
|
||||
};
|
||||
|
||||
#endif /* _NETWORK_H_ */
|
||||
|
22
ports/src/vancouver/synced_motherboard.h
Normal file
22
ports/src/vancouver/synced_motherboard.h
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* \brief Synchronized access to Vancouver motherboard
|
||||
* \author Norman Feske
|
||||
* \date 2013-05-16
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013 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.
|
||||
*/
|
||||
|
||||
#ifndef _SYNCED_MOTHERBOARD_H_
|
||||
#define _SYNCED_MOTHERBOARD_H_
|
||||
|
||||
#include <nul/motherboard.h>
|
||||
#include <os/synced_interface.h>
|
||||
|
||||
typedef Genode::Synced_interface<Motherboard> Synced_motherboard;
|
||||
|
||||
#endif /* _SYNCED_MOTHERBOARD_H_ */
|
Loading…
x
Reference in New Issue
Block a user