mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-20 06:07:59 +00:00
hw_x86_64_muen: Use timed events for guest preemption
Write tick count of next kernel timer to the guest timed events page if present. This causes the guest VM to be preempted at the requested tick count and ensures that the guest VM can not monopolize the CPU if no traps occur. The base-hw kernel expects a configured switch-event from the guest VM to base-hw with ID 30 and target vector 32 to be present in the system policy. Issue #2016
This commit is contained in:
parent
7d00763861
commit
68bab6a411
@ -19,10 +19,13 @@ namespace Genode
|
|||||||
struct Board
|
struct Board
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
TIMER_BASE_ADDR = 0xe00010000,
|
TIMER_BASE_ADDR = 0xe00010000,
|
||||||
TIMER_SIZE = 0x1000,
|
TIMER_SIZE = 0x1000,
|
||||||
|
TIMER_PREEMPT_BASE_ADDR = 0xe00011000,
|
||||||
|
TIMER_PREEMPT_SIZE = 0x1000,
|
||||||
|
|
||||||
VECTOR_REMAP_BASE = 48,
|
VECTOR_REMAP_BASE = 48,
|
||||||
|
TIMER_EVENT_PREEMPT = 30,
|
||||||
TIMER_EVENT_KERNEL = 31,
|
TIMER_EVENT_KERNEL = 31,
|
||||||
TIMER_VECTOR_KERNEL = 32,
|
TIMER_VECTOR_KERNEL = 32,
|
||||||
TIMER_VECTOR_USER = 50,
|
TIMER_VECTOR_USER = 50,
|
||||||
|
@ -46,7 +46,8 @@ class Genode::Timer
|
|||||||
uint8_t event_nr :5;
|
uint8_t event_nr :5;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct Subject_timed_event * _event_page;
|
struct Subject_timed_event * _event_page = 0;
|
||||||
|
struct Subject_timed_event * _guest_event_page = 0;
|
||||||
|
|
||||||
|
|
||||||
inline uint64_t rdtsc()
|
inline uint64_t rdtsc()
|
||||||
@ -75,15 +76,27 @@ class Genode::Timer
|
|||||||
|
|
||||||
_event_page = (Subject_timed_event *)region.address;
|
_event_page = (Subject_timed_event *)region.address;
|
||||||
_event_page->event_nr = Board::TIMER_EVENT_KERNEL;
|
_event_page->event_nr = Board::TIMER_EVENT_KERNEL;
|
||||||
PINF("muen-timer: page @0x%llx, frequency %llu kHz, event %u",
|
PINF("muen-timer: Page @0x%llx, frequency %llu kHz, event %u",
|
||||||
region.address, _tics_per_ms, _event_page->event_nr);
|
region.address, _tics_per_ms, _event_page->event_nr);
|
||||||
|
|
||||||
|
if (sinfo()->get_memregion_info("monitor_timed_event", ®ion)) {
|
||||||
|
PINF("muen-timer: Found guest timed event page @0x%llx"
|
||||||
|
" -> enabling preemption", region.address);
|
||||||
|
_guest_event_page = (Subject_timed_event *)region.address;
|
||||||
|
_guest_event_page->event_nr = Board::TIMER_EVENT_PREEMPT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned interrupt_id(int) {
|
static unsigned interrupt_id(int) {
|
||||||
return Board::TIMER_VECTOR_KERNEL; }
|
return Board::TIMER_VECTOR_KERNEL; }
|
||||||
|
|
||||||
inline void start_one_shot(time_t const tics, unsigned) {
|
inline void start_one_shot(time_t const tics, unsigned)
|
||||||
_event_page->tsc_trigger = rdtsc() + tics; }
|
{
|
||||||
|
const uint64_t t = rdtsc() + tics;
|
||||||
|
_event_page->tsc_trigger = t;
|
||||||
|
|
||||||
|
if (_guest_event_page)
|
||||||
|
_guest_event_page->tsc_trigger = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t tics_to_us(time_t const tics) const {
|
time_t tics_to_us(time_t const tics) const {
|
||||||
|
@ -65,6 +65,8 @@ Native_region * Platform::_core_only_mmio_regions(unsigned const i)
|
|||||||
{ Sinfo::PHYSICAL_BASE_ADDR, Sinfo::SIZE },
|
{ Sinfo::PHYSICAL_BASE_ADDR, Sinfo::SIZE },
|
||||||
/* Timer page */
|
/* Timer page */
|
||||||
{ Board::TIMER_BASE_ADDR, Board::TIMER_SIZE },
|
{ Board::TIMER_BASE_ADDR, Board::TIMER_SIZE },
|
||||||
|
/* Optional guest timed event page for preemption */
|
||||||
|
{ Board::TIMER_PREEMPT_BASE_ADDR, Board::TIMER_PREEMPT_SIZE },
|
||||||
};
|
};
|
||||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user