VMM: Manually save/restore certain registers [1/2]
[akaros.git] / kern / arch / x86 / vmm / vmm.h
1 #pragma once
2
3 #include <ros/vmm.h>
4
5 static inline int cpu_has_vmx(void)
6 {
7         unsigned long ecx = cpuid_ecx(1);
8         return ecx & (1<<5); /* CPUID.1:ECX.VMX[bit 5] -> VT */
9 }
10
11 /* maybe someday, not today. */
12 static inline int cpu_has_svm(const char **msg)
13 {
14         return 0;
15 }
16
17 #define VMM_VMEXIT_NR_TYPES             65
18
19 struct guest_pcore {
20         int cpu;
21         struct proc *proc;
22         unsigned long *posted_irq_desc;
23         struct msr_autoload {
24                 unsigned nr;
25                 struct vmx_msr_entry guest[NR_AUTOLOAD_MSRS];
26                 struct vmx_msr_entry host[NR_AUTOLOAD_MSRS];
27         } msr_autoload;
28         struct vmcs *vmcs;
29         uint64_t xcr0;
30         uint64_t msr_kern_gs_base;
31         uint64_t msr_star;
32         uint64_t msr_lstar;
33         uint64_t msr_sfmask;
34 };
35
36 struct vmm {
37         spinlock_t lock;        /* protects guest_pcore assignment */
38         qlock_t qlock;
39         // always false.
40         int amd;
41         // true if this is a VMMCP.
42         bool vmmcp;
43
44         int flags;
45
46         // Number of cores in this VMMCP.
47         int nr_guest_pcores;
48
49         // The VMCS is intel-specific. But, maybe, someday, AMD will
50         // be back.  Just make this an anon union and we'll work it
51         // all out later. Again, remember, we're compiling in support
52         // for both architectures to ensure that we can correctly
53         // figure out at boot time what we're on and what we should
54         // do. This avoids the problem seen years ago with RH6 where
55         // you could install a kernel from the ISO, but the kernel it
56         // installed would GPF on a K7.
57         union {
58                 void *svm;
59                 struct guest_pcore **guest_pcores;
60         };
61         unsigned long vmexits[VMM_VMEXIT_NR_TYPES];
62 };
63
64 void vmm_init(void);
65 void vmm_pcpu_init(void);
66
67 int vmm_struct_init(struct proc *p, unsigned int nr_guest_pcores,
68                     struct vmm_gpcore_init *gpcis, int flags);
69 void __vmm_struct_cleanup(struct proc *p);
70 int vmm_poke_guest(struct proc *p, int guest_pcoreid);
71
72 int intel_vmx_start(int id);
73 int intel_vmx_setup(int nvmcs);
74
75 struct guest_pcore *create_guest_pcore(struct proc *p,
76                                        struct vmm_gpcore_init *gpci);
77 void destroy_guest_pcore(struct guest_pcore *vcpu);
78 uint64_t construct_eptp(physaddr_t root_hpa);
79 void ept_flush(uint64_t eptp);
80
81 struct guest_pcore *lookup_guest_pcore(struct proc *p, int guest_pcoreid);
82 struct guest_pcore *load_guest_pcore(struct proc *p, int guest_pcoreid);
83 void unload_guest_pcore(struct proc *p, int guest_pcoreid);
84
85 #define VMM_MSR_EMU_READ                1
86 #define VMM_MSR_EMU_WRITE               2
87 bool vmm_emulate_msr(uint64_t *rcx, uint64_t *rdx, uint64_t *rax, int op);