]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/ia32/vm.cpp
Some minor fixes.
[l4.git] / kernel / fiasco / src / kern / ia32 / vm.cpp
1 INTERFACE:
2
3 #include "task.h"
4 #include "obj_space_phys_util.h"
5
6 class Vm : public Obj_space_phys_override<Task>
7 {
8 public:
9   explicit Vm(Ram_quota *q)
10   : Obj_space_phys_override<Task>(q, Caps::mem() | Caps::obj())
11   {}
12
13   int resume_vcpu(Context *, Vcpu_state *, bool) = 0;
14 };
15
16 // ------------------------------------------------------------------------
17 IMPLEMENTATION:
18 #include "cpu.h"
19
20 PUBLIC inline
21 Page_number
22 Vm::mem_space_map_max_address() const
23 { return Page_number(1UL << (MWORD_BITS - Mem_space::Page_shift)); }
24
25 PROTECTED static inline
26 void
27 Vm::force_kern_entry_vcpu_state(Vcpu_state *vcpu)
28 {
29   vcpu->state &= ~(Vcpu_state::F_traps | Vcpu_state::F_user_mode);
30 }
31
32 /*
33  * Sanitize and load a guest-provided xcr0 value.
34  *
35  * An invalid xcr0 value will cause a GP. Therefore we implement all the checks
36  * defined in the intel manual to ensure that no guest can cause a GP.
37  *
38  * This function is strict, and does not allow for "new" bits that come up in
39  * new CPUs and are advertised in cpuid. These new bits could come with new
40  * constraints that need to be checked here. Therefore even if those bits are
41  * enabled in the host, we do not allow them for the guest until we get the new
42  * manual and can implement the integrity checks accordingly.
43  */
44 PROTECTED static inline NEEDS["cpu.h"]
45 void
46 Vm::load_guest_xcr0(Unsigned64 host_xcr0, Unsigned64 guest_xcr0)
47 {
48   if (!Cpu::have_xsave() || !(host_xcr0 ^ guest_xcr0))
49     return;
50
51   enum : Unsigned64
52   {
53     Xstate_fp           = 1 << 0,
54     Xstate_sse          = 1 << 1,
55     Xstate_avx          = 1 << 2,
56     Xstate_defined_bits = 0x7,
57   };
58   guest_xcr0 &= Xstate_defined_bits; // allow only defined bits
59   guest_xcr0 |= Xstate_fp;           // fp must always be set
60   if (guest_xcr0 & Xstate_avx)       // if avx is set, sse must also be set
61     guest_xcr0 |= Xstate_sse;
62
63   guest_xcr0 &= host_xcr0; // only allow bits that are available on the CPU
64   Cpu::xsetbv(guest_xcr0, 0);
65 }
66
67 /*
68  * Load host xcr0.
69  */
70 PROTECTED static inline NEEDS["cpu.h"]
71 void
72 Vm::load_host_xcr0(Unsigned64 host_xcr0, Unsigned64 guest_xcr0)
73 {
74   if (!Cpu::have_xsave() || !(guest_xcr0 ^ host_xcr0))
75     return;
76   Cpu::xsetbv(host_xcr0, 0);
77 }
78
79 // ------------------------------------------------------------------------
80 IMPLEMENTATION [ia32]:
81
82 PROTECTED static inline
83 bool
84 Vm::is_64bit()
85 { return false; }
86
87 // ------------------------------------------------------------------------
88 IMPLEMENTATION [amd64]:
89
90 PROTECTED static inline
91 bool
92 Vm::is_64bit()
93 { return true; }