mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-18 23:28:29 +00:00
committed by
Christian Helmuth
parent
20606bc6de
commit
0aaed47652
@ -41,6 +41,9 @@ struct Vcpu {
|
|||||||
void *_ep_handler { nullptr };
|
void *_ep_handler { nullptr };
|
||||||
void *_dispatching { nullptr };
|
void *_dispatching { nullptr };
|
||||||
bool _block { true };
|
bool _block { true };
|
||||||
|
bool _use_guest_fpu { false };
|
||||||
|
|
||||||
|
uint8_t _fpu_ep[512] __attribute__((aligned(0x10)));
|
||||||
|
|
||||||
enum Remote_state_requested {
|
enum Remote_state_requested {
|
||||||
NONE = 0,
|
NONE = 0,
|
||||||
@ -48,7 +51,7 @@ struct Vcpu {
|
|||||||
RUN = 2
|
RUN = 2
|
||||||
} _remote { NONE };
|
} _remote { NONE };
|
||||||
|
|
||||||
static void _read_nova_state(Nova::Utcb &utcb, Vm_state &state,
|
void _read_nova_state(Nova::Utcb &utcb, Vm_state &state,
|
||||||
unsigned exit_reason)
|
unsigned exit_reason)
|
||||||
{
|
{
|
||||||
typedef Genode::Vm_state::Segment Segment;
|
typedef Genode::Vm_state::Segment Segment;
|
||||||
@ -59,10 +62,12 @@ struct Vcpu {
|
|||||||
|
|
||||||
if (utcb.mtd & Nova::Mtd::FPU) {
|
if (utcb.mtd & Nova::Mtd::FPU) {
|
||||||
state.fpu.value([&] (uint8_t *fpu, size_t const) {
|
state.fpu.value([&] (uint8_t *fpu, size_t const) {
|
||||||
asm volatile ("fxsave %0" : "=m" (*fpu));
|
asm volatile ("fxsave %0" : "=m" (*fpu) :: "memory");
|
||||||
});
|
});
|
||||||
|
asm volatile ("fxrstor %0" : : "m" (*_fpu_ep) : "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (utcb.mtd & Nova::Mtd::ACDB) {
|
if (utcb.mtd & Nova::Mtd::ACDB) {
|
||||||
state.ax.value(utcb.ax);
|
state.ax.value(utcb.ax);
|
||||||
state.cx.value(utcb.cx);
|
state.cx.value(utcb.cx);
|
||||||
@ -197,7 +202,7 @@ struct Vcpu {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _write_nova_state(Nova::Utcb &utcb, Vm_state &state)
|
void _write_nova_state(Nova::Utcb &utcb, Vm_state &state)
|
||||||
{
|
{
|
||||||
utcb.items = 0;
|
utcb.items = 0;
|
||||||
utcb.mtd = 0;
|
utcb.mtd = 0;
|
||||||
@ -394,9 +399,13 @@ struct Vcpu {
|
|||||||
utcb.write_tpr_threshold(state.tpr_threshold.value());
|
utcb.write_tpr_threshold(state.tpr_threshold.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (_use_guest_fpu || state.fpu.valid())
|
||||||
|
asm volatile ("fxsave %0" : "=m" (*_fpu_ep) :: "memory");
|
||||||
|
|
||||||
if (state.fpu.valid()) {
|
if (state.fpu.valid()) {
|
||||||
state.fpu.value([&] (uint8_t *fpu, size_t const) {
|
state.fpu.value([&] (uint8_t *fpu, size_t const) {
|
||||||
asm volatile ("fxrstor %0" : : "m" (*fpu));
|
asm volatile ("fxrstor %0" : : "m" (*fpu) : "memory");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -471,7 +480,7 @@ struct Vcpu {
|
|||||||
Vm_state &state = *reinterpret_cast<Vm_state *>(vcpu->_state);
|
Vm_state &state = *reinterpret_cast<Vm_state *>(vcpu->_state);
|
||||||
/* transform state from NOVA to Genode */
|
/* transform state from NOVA to Genode */
|
||||||
if (exit_reason != VM_EXIT_RECALL || !previous_blocked)
|
if (exit_reason != VM_EXIT_RECALL || !previous_blocked)
|
||||||
_read_nova_state(utcb, state, exit_reason);
|
vcpu->_read_nova_state(utcb, state, exit_reason);
|
||||||
|
|
||||||
if (exit_reason == VM_EXIT_RECALL) {
|
if (exit_reason == VM_EXIT_RECALL) {
|
||||||
if (previous_blocked)
|
if (previous_blocked)
|
||||||
@ -498,7 +507,7 @@ struct Vcpu {
|
|||||||
if (previous_blocked) {
|
if (previous_blocked) {
|
||||||
/* resume vCPU - with vCPU state update */
|
/* resume vCPU - with vCPU state update */
|
||||||
vcpu->_block = false;
|
vcpu->_block = false;
|
||||||
_write_nova_state(utcb, state);
|
vcpu->_write_nova_state(utcb, state);
|
||||||
Nova::reply(myself.stack_top());
|
Nova::reply(myself.stack_top());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -514,7 +523,7 @@ struct Vcpu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* reply to NOVA and transfer vCPU state */
|
/* reply to NOVA and transfer vCPU state */
|
||||||
_write_nova_state(utcb, state);
|
vcpu->_write_nova_state(utcb, state);
|
||||||
Nova::reply(myself.stack_top());
|
Nova::reply(myself.stack_top());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -671,8 +680,10 @@ struct Vcpu {
|
|||||||
if (state.qual_primary.valid() || state.qual_secondary.valid())
|
if (state.qual_primary.valid() || state.qual_secondary.valid())
|
||||||
mtd |= Nova::Mtd::QUAL;
|
mtd |= Nova::Mtd::QUAL;
|
||||||
|
|
||||||
if (state.fpu.valid())
|
if (state.fpu.valid()) {
|
||||||
|
_use_guest_fpu = true;
|
||||||
mtd |= Nova::Mtd::FPU;
|
mtd |= Nova::Mtd::FPU;
|
||||||
|
}
|
||||||
|
|
||||||
state = Vm_state {};
|
state = Vm_state {};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user