mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-18 21:27:56 +00:00
parent
5673c163fb
commit
ab6315d6b4
@ -87,7 +87,7 @@ Vcpu::Vcpu(Constrained_ram_allocator &ram_alloc,
|
||||
{
|
||||
try {
|
||||
/* create ds for vCPU state */
|
||||
_ds_cap = _ram_alloc.alloc(4096, Cache_attribute::CACHED);
|
||||
_ds_cap = _ram_alloc.alloc(0x1000, Cache_attribute::CACHED);
|
||||
} catch (...) {
|
||||
throw;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
/* Base includes */
|
||||
#include <base/cache.h>
|
||||
#include <cpu/vm_state.h>
|
||||
#include <util/list.h>
|
||||
#include <util/flex_iterator.h>
|
||||
|
||||
@ -65,7 +66,8 @@ Vm_session_component::Vcpu::Vcpu(Constrained_ram_allocator &ram_alloc,
|
||||
|
||||
try {
|
||||
/* create ds for vCPU state */
|
||||
_ds_cap = _ram_alloc.alloc(4096, Cache_attribute::CACHED);
|
||||
_ds_cap = _ram_alloc.alloc(align_addr(sizeof(Genode::Vm_state), 12),
|
||||
Cache_attribute::CACHED);
|
||||
} catch (...) {
|
||||
_cap_alloc.replenish(Cap_quota{CAP_RANGE});
|
||||
cap_map().remove(_sel_sm_ec_sc, CAP_RANGE_LOG2);
|
||||
|
@ -58,6 +58,12 @@ struct Vcpu {
|
||||
state = Vm_state {};
|
||||
state.exit_reason = exit_reason;
|
||||
|
||||
if (utcb.mtd & Nova::Mtd::FPU) {
|
||||
state.fpu.value([&] (uint8_t *fpu, size_t const) {
|
||||
asm volatile ("fxsave %0" : "=m" (*fpu));
|
||||
});
|
||||
}
|
||||
|
||||
if (utcb.mtd & Nova::Mtd::ACDB) {
|
||||
state.ax.value(utcb.ax);
|
||||
state.cx.value(utcb.cx);
|
||||
@ -190,7 +196,6 @@ struct Vcpu {
|
||||
state.tpr_threshold.value(utcb.read_tpr_threshold());
|
||||
}
|
||||
|
||||
/* XXX FPU state missing */
|
||||
}
|
||||
|
||||
static void _write_nova_state(Nova::Utcb &utcb, Vm_state &state)
|
||||
@ -389,6 +394,12 @@ struct Vcpu {
|
||||
utcb.write_tpr(state.tpr.value());
|
||||
utcb.write_tpr_threshold(state.tpr_threshold.value());
|
||||
}
|
||||
|
||||
if (state.fpu.valid()) {
|
||||
state.fpu.value([&] (uint8_t *fpu, size_t const) {
|
||||
asm volatile ("fxrstor %0" : : "m" (*fpu));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void _dispatch()
|
||||
@ -655,7 +666,8 @@ struct Vcpu {
|
||||
if (state.qual_primary.valid() || state.qual_secondary.valid())
|
||||
mtd |= Nova::Mtd::QUAL;
|
||||
|
||||
/* XXX FPU missing */
|
||||
if (state.fpu.valid())
|
||||
mtd |= Nova::Mtd::FPU;
|
||||
|
||||
state = Vm_state {};
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
/* base includes */
|
||||
#include <util/flex_iterator.h>
|
||||
#include <cpu/vm_state.h>
|
||||
|
||||
/* core includes */
|
||||
#include <core_env.h>
|
||||
@ -45,7 +46,8 @@ Vm_session_component::Vcpu::Vcpu(Constrained_ram_allocator &ram_alloc,
|
||||
seL4_Untyped const service)
|
||||
:
|
||||
_ram_alloc(ram_alloc),
|
||||
_ds_cap (_ram_alloc.alloc(4096, Cache_attribute::CACHED)),
|
||||
_ds_cap (_ram_alloc.alloc(align_addr(sizeof(Genode::Vm_state), 12),
|
||||
Cache_attribute::CACHED)),
|
||||
_vcpu_id(vcpu_id)
|
||||
{
|
||||
try {
|
||||
|
@ -141,6 +141,30 @@ struct Genode::Vm_state
|
||||
Register<uint32_t> tpr_threshold;
|
||||
|
||||
unsigned exit_reason;
|
||||
|
||||
class Fpu {
|
||||
private :
|
||||
|
||||
uint8_t _value[512] { };
|
||||
bool _valid { false };
|
||||
|
||||
public:
|
||||
|
||||
bool valid() const { return _valid; }
|
||||
void invalid() { _valid = false; }
|
||||
|
||||
template <typename FUNC>
|
||||
void value(FUNC const &fn) {
|
||||
_valid = true;
|
||||
fn(_value, sizeof(_value));
|
||||
};
|
||||
|
||||
Fpu &operator = (Fpu const &)
|
||||
{
|
||||
_valid = false;
|
||||
return *this;
|
||||
}
|
||||
} fpu __attribute__((aligned(16)));
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__SPEC__X86__CPU__VM_STATE_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user