Get the vm support to compile
[akaros.git] / kern / arch / x86 / vm.h
1 #ifndef __LITEVM_H
2 #define __LITEVM_H
3 #include <page_alloc.h>
4 #include <sys/queue.h>
5 #include <pmap.h>
6 #include "vmx.h"
7
8 #define CR0_PE_MASK (1ULL << 0)
9 #define CR0_TS_MASK (1ULL << 3)
10 #define CR0_NE_MASK (1ULL << 5)
11 #define CR0_WP_MASK (1ULL << 16)
12 #define CR0_NW_MASK (1ULL << 29)
13 #define CR0_CD_MASK (1ULL << 30)
14 #define CR0_PG_MASK (1ULL << 31)
15
16 #define CR3_WPT_MASK (1ULL << 3)
17 #define CR3_PCD_MASK (1ULL << 4)
18
19 #define CR3_RESEVED_BITS 0x07ULL
20 #define CR3_L_MODE_RESEVED_BITS (~((1ULL << 40) - 1) | 0x0fe7ULL)
21 #define CR3_FLAGS_MASK ((1ULL << 5) - 1)
22
23 #define CR4_VME_MASK (1ULL << 0)
24 #define CR4_PSE_MASK (1ULL << 4)
25 #define CR4_PAE_MASK (1ULL << 5)
26 #define CR4_PGE_MASK (1ULL << 7)
27 #define CR4_VMXE_MASK (1ULL << 13)
28
29 #define LITEVM_GUEST_CR0_MASK \
30         (CR0_PG_MASK | CR0_PE_MASK | CR0_WP_MASK | CR0_NE_MASK)
31 #define LITEVM_VM_CR0_ALWAYS_ON LITEVM_GUEST_CR0_MASK
32
33 #define LITEVM_GUEST_CR4_MASK \
34         (CR4_PSE_MASK | CR4_PAE_MASK | CR4_PGE_MASK | CR4_VMXE_MASK | CR4_VME_MASK)
35 #define LITEVM_PMODE_VM_CR4_ALWAYS_ON (CR4_VMXE_MASK | CR4_PAE_MASK)
36 #define LITEVM_RMODE_VM_CR4_ALWAYS_ON (CR4_VMXE_MASK | CR4_PAE_MASK | CR4_VME_MASK)
37
38 #define INVALID_PAGE (~(hpa_t)0)
39 #define UNMAPPED_GVA (~(gpa_t)0)
40
41 #define LITEVM_MAX_VCPUS 1
42 #define LITEVM_MEMORY_SLOTS 4
43 #define LITEVM_NUM_MMU_PAGES 256
44
45 #define FX_IMAGE_SIZE 512
46 #define FX_IMAGE_ALIGN 16
47 #define FX_BUF_SIZE (2 * FX_IMAGE_SIZE + FX_IMAGE_ALIGN)
48
49 #define DE_VECTOR 0
50 #define DF_VECTOR 8
51 #define TS_VECTOR 10
52 #define NP_VECTOR 11
53 #define SS_VECTOR 12
54 #define GP_VECTOR 13
55 #define PF_VECTOR 14
56
57 #define SELECTOR_TI_MASK (1 << 2)
58 #define SELECTOR_RPL_MASK 0x03
59
60 #define IOPL_SHIFT 12
61
62 /*
63  * Address types:
64  *
65  *  gva - guest virtual address
66  *  gpa - guest physical address
67  *  gfn - guest frame number
68  *  hva - host virtual address
69  *  hpa - host physical address
70  *  hfn - host frame number
71  */
72
73 typedef unsigned long  gva_t;
74 typedef uint64_t            gpa_t;
75 typedef unsigned long  gfn_t;
76
77 typedef unsigned long  hva_t;
78 typedef uint64_t            hpa_t;
79 typedef unsigned long  hfn_t;
80
81 struct litevm_mmu_page {
82         LIST_HEAD(link, litevm_mmu_page) link;
83         hpa_t page_hpa;
84         unsigned long slot_bitmap; /* One bit set per slot which has memory
85                                     * in this shadow page.
86                                     */
87         int global;              /* Set if all ptes in this page are global */
88         uint64_t *parent_pte;
89 };
90
91 struct vmcs {
92         uint32_t revision_id;
93         uint32_t abort;
94         char data[0];
95 };
96
97 struct vmx_msr_entry {
98         uint32_t index;
99         uint32_t reserved;
100         uint64_t data;
101 };
102
103 struct litevm_vcpu;
104
105 /*
106  * x86 supports 3 paging modes (4-level 64-bit, 3-level 64-bit, and 2-level
107  * 32-bit).  The litevm_mmu structure abstracts the details of the current mmu
108  * mode.
109  */
110 struct litevm_mmu {
111         void (*new_cr3)(struct litevm_vcpu *vcpu);
112         int (*page_fault)(struct litevm_vcpu *vcpu, gva_t gva, uint32_t err);
113         void (*inval_page)(struct litevm_vcpu *vcpu, gva_t gva);
114         void (*free)(struct litevm_vcpu *vcpu);
115         gpa_t (*gva_to_gpa)(struct litevm_vcpu *vcpu, gva_t gva);
116         hpa_t root_hpa;
117         int root_level;
118         int shadow_root_level;
119 };
120
121 struct litevm_guest_debug {
122         int enabled;
123         unsigned long bp[4];
124         int singlestep;
125 };
126
127 enum {
128         VCPU_REGS_RAX = 0,
129         VCPU_REGS_RCX = 1,
130         VCPU_REGS_RDX = 2,
131         VCPU_REGS_RBX = 3,
132         VCPU_REGS_RSP = 4,
133         VCPU_REGS_RBP = 5,
134         VCPU_REGS_RSI = 6,
135         VCPU_REGS_RDI = 7,
136 #ifdef __x86_64__
137         VCPU_REGS_R8 = 8,
138         VCPU_REGS_R9 = 9,
139         VCPU_REGS_R10 = 10,
140         VCPU_REGS_R11 = 11,
141         VCPU_REGS_R12 = 12,
142         VCPU_REGS_R13 = 13,
143         VCPU_REGS_R14 = 14,
144         VCPU_REGS_R15 = 15,
145 #endif
146         NR_VCPU_REGS
147 };
148
149 struct litevm_vcpu {
150         struct litevm *litevm;
151         struct vmcs *vmcs;
152         qlock_t mutex; //struct mutex mutex;
153         int   cpu;
154         int   launched;
155         unsigned long irq_summary; /* bit vector: 1 per word in irq_pending */
156 #define NR_IRQ_WORDS (256 / BITS_PER_LONG)
157         unsigned long irq_pending[NR_IRQ_WORDS];
158         unsigned long regs[NR_VCPU_REGS]; /* for rsp: vcpu_load_rsp_rip() */
159         unsigned long rip;      /* needs vcpu_load_rsp_rip() */
160
161         unsigned long cr2;
162         unsigned long cr3;
163         unsigned long cr8;
164         uint64_t shadow_efer;
165         uint64_t apic_base;
166         int nmsrs;
167         struct vmx_msr_entry *guest_msrs;
168         struct vmx_msr_entry *host_msrs;
169         LIST_HEAD(free_pages, free_pages) free_pages;
170         //struct list_head free_pages;
171         struct litevm_mmu_page page_header_buf[LITEVM_NUM_MMU_PAGES];
172         struct litevm_mmu mmu;
173
174         struct litevm_guest_debug guest_debug;
175
176         char fx_buf[FX_BUF_SIZE];
177         char *host_fx_image;
178         char *guest_fx_image;
179
180         int mmio_needed;
181         int mmio_read_completed;
182         int mmio_is_write;
183         int mmio_size;
184         unsigned char mmio_data[8];
185         gpa_t mmio_phys_addr;
186
187         struct{
188                 int active;
189                 uint8_t save_iopl;
190                 struct {
191                         unsigned long base;
192                         uint32_t limit;
193                         uint32_t ar;
194                 } tr;
195         } rmode;
196 };
197
198 struct litevm_memory_slot {
199         gfn_t base_gfn;
200         unsigned long npages;
201         unsigned long flags;
202         struct page **phys_mem;
203         unsigned long *dirty_bitmap;
204 };
205
206 struct litevm {
207         spinlock_t lock; /* protects everything except vcpus */
208         int nmemslots;
209         struct litevm_memory_slot memslots[LITEVM_MEMORY_SLOTS];
210         LIST_HEAD(active_mmu_pages, active_mmu_pages) active_mmu_pages;
211         //struct list_head active_mmu_pages;
212         struct litevm_vcpu vcpus[LITEVM_MAX_VCPUS];
213         int memory_config_version;
214         int busy;
215 };
216
217 struct litevm_stat {
218         uint32_t pf_fixed;
219         uint32_t pf_guest;
220         uint32_t tlb_flush;
221         uint32_t invlpg;
222
223         uint32_t exits;
224         uint32_t io_exits;
225         uint32_t mmio_exits;
226         uint32_t signal_exits;
227         uint32_t irq_exits;
228 };
229
230 extern struct litevm_stat litevm_stat;
231
232 #define litevm_printf(litevm, fmt ...) printd(fmt)
233 #define vcpu_printf(vcpu, fmt...) litevm_printf(vcpu->litevm, fmt)
234
235 void litevm_mmu_destroy(struct litevm_vcpu *vcpu);
236 int litevm_mmu_init(struct litevm_vcpu *vcpu);
237
238 int litevm_mmu_reset_context(struct litevm_vcpu *vcpu);
239 void litevm_mmu_slot_remove_write_access(struct litevm *litevm, int slot);
240
241 hpa_t gpa_to_hpa(struct litevm_vcpu *vcpu, gpa_t gpa);
242 #define HPA_MSB ((sizeof(hpa_t) * 8) - 1)
243 #define HPA_ERR_MASK ((hpa_t)1 << HPA_MSB)
244 static inline int is_error_hpa(hpa_t hpa) { return hpa >> HPA_MSB; }
245 hpa_t gva_to_hpa(struct litevm_vcpu *vcpu, gva_t gva);
246
247 extern hpa_t bad_page_address;
248
249 static inline struct page *gfn_to_page(struct litevm_memory_slot *slot, gfn_t gfn)
250 {
251         return slot->phys_mem[gfn - slot->base_gfn];
252 }
253
254 struct litevm_memory_slot *gfn_to_memslot(struct litevm *litevm, gfn_t gfn);
255 void mark_page_dirty(struct litevm *litevm, gfn_t gfn);
256
257 void realmode_lgdt(struct litevm_vcpu *vcpu, uint16_t size, unsigned long address);
258 void realmode_lidt(struct litevm_vcpu *vcpu, uint16_t size, unsigned long address);
259 void realmode_lmsw(struct litevm_vcpu *vcpu, unsigned long msw,
260                    unsigned long *rflags);
261
262 unsigned long realmode_get_cr(struct litevm_vcpu *vcpu, int cr);
263 void realmode_set_cr(struct litevm_vcpu *vcpu, int cr, unsigned long value,
264                      unsigned long *rflags);
265
266 int litevm_read_guest(struct litevm_vcpu *vcpu,
267                gva_t addr,
268                unsigned long size,
269                void *dest);
270
271 int litevm_write_guest(struct litevm_vcpu *vcpu,
272                 gva_t addr,
273                 unsigned long size,
274                 void *data);
275
276 void vmcs_writel(unsigned long field, unsigned long value);
277 unsigned long vmcs_readl(unsigned long field);
278
279 static inline uint16_t vmcs_read16(unsigned long field)
280 {
281         return vmcs_readl(field);
282 }
283
284 static inline uint32_t vmcs_read32(unsigned long field)
285 {
286         return vmcs_readl(field);
287 }
288
289 static inline uint64_t vmcs_read64(unsigned long field)
290 {
291 #ifdef __x86_64__
292         return vmcs_readl(field);
293 #else
294         return vmcs_readl(field) | ((uint64_t)vmcs_readl(field+1) << 32);
295 #endif
296 }
297
298 static inline void vmcs_write32(unsigned long field, uint32_t value)
299 {
300         vmcs_writel(field, value);
301 }
302
303 static inline int is_long_mode(void)
304 {
305         return vmcs_read32(VM_ENTRY_CONTROLS) & VM_ENTRY_CONTROLS_IA32E_MASK;
306 }
307
308 static inline unsigned long guest_cr4(void)
309 {
310         return (vmcs_readl(CR4_READ_SHADOW) & LITEVM_GUEST_CR4_MASK) |
311                 (vmcs_readl(GUEST_CR4) & ~LITEVM_GUEST_CR4_MASK);
312 }
313
314 static inline int is_pae(void)
315 {
316         return guest_cr4() & CR4_PAE_MASK;
317 }
318
319 static inline int is_pse(void)
320 {
321         return guest_cr4() & CR4_PSE_MASK;
322 }
323
324 static inline unsigned long guest_cr0(void)
325 {
326         return (vmcs_readl(CR0_READ_SHADOW) & LITEVM_GUEST_CR0_MASK) |
327                 (vmcs_readl(GUEST_CR0) & ~LITEVM_GUEST_CR0_MASK);
328 }
329
330 static inline unsigned guest_cpl(void)
331 {
332         return vmcs_read16(GUEST_CS_SELECTOR) & SELECTOR_RPL_MASK;
333 }
334
335 static inline int is_paging(void)
336 {
337         return guest_cr0() & CR0_PG_MASK;
338 }
339
340 static inline int is_page_fault(uint32_t intr_info)
341 {
342         return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
343                              INTR_INFO_VALID_MASK)) ==
344                 (INTR_TYPE_EXCEPTION | PF_VECTOR | INTR_INFO_VALID_MASK);
345 }
346
347 static inline int is_external_interrupt(uint32_t intr_info)
348 {
349         return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK))
350                 == (INTR_TYPE_EXT_INTR | INTR_INFO_VALID_MASK);
351 }
352
353 static inline void flush_guest_tlb(struct litevm_vcpu *vcpu)
354 {
355         vmcs_writel(GUEST_CR3, vmcs_readl(GUEST_CR3));
356 }
357
358 static inline int memslot_id(struct litevm *litevm, struct litevm_memory_slot *slot)
359 {
360         return slot - litevm->memslots;
361 }
362
363 static inline struct litevm_mmu_page *page_header(hpa_t shadow_page)
364 {
365         struct page *page = ppn2page(shadow_page >> PAGE_SHIFT);
366
367         return (struct litevm_mmu_page *)page->pg_private;
368 }
369
370 #ifdef __x86_64__
371
372 /*
373  * When emulating 32-bit mode, cr3 is only 32 bits even on x86_64.  Therefore
374  * we need to allocate shadow page tables in the first 4GB of memory, which
375  * happens to fit the DMA32 zone.
376  */
377 #define GFP_LITEVM_MMU (GFP_KERNEL | __GFP_DMA32)
378
379 #else
380
381 #define GFP_LITEVM_MMU GFP_KERNEL
382
383 #endif
384
385 /* just to get things to build ... include this stuff for now.
386  * at some point, this interface gets nuke to and made more plan 
387  * 9 like.
388  */
389
390 /* for LITEVM_CREATE_MEMORY_REGION */
391 struct litevm_memory_region {
392         uint32_t slot;
393         uint32_t flags;
394         uint64_t guest_phys_addr;
395         uint64_t memory_size; /* bytes */
396 };
397
398 /* for litevm_memory_region::flags */
399 #define LITEVM_MEM_LOG_DIRTY_PAGES  1UL
400
401
402 #define LITEVM_EXIT_TYPE_FAIL_ENTRY 1
403 #define LITEVM_EXIT_TYPE_VM_EXIT    2
404
405 enum litevm_exit_reason {
406         LITEVM_EXIT_UNKNOWN,
407         LITEVM_EXIT_EXCEPTION,
408         LITEVM_EXIT_IO,
409         LITEVM_EXIT_CPUID,
410         LITEVM_EXIT_DEBUG,
411         LITEVM_EXIT_HLT,
412         LITEVM_EXIT_MMIO,
413 };
414
415 /* for LITEVM_RUN */
416 struct litevm_run {
417         /* in */
418         uint32_t vcpu;
419         uint32_t emulated;  /* skip current instruction */
420         uint32_t mmio_completed; /* mmio request completed */
421
422         /* out */
423         uint32_t exit_type;
424         uint32_t exit_reason;
425         uint32_t instruction_length;
426         union {
427                 /* LITEVM_EXIT_UNKNOWN */
428                 struct {
429                         uint32_t hardware_exit_reason;
430                 } hw;
431                 /* LITEVM_EXIT_EXCEPTION */
432                 struct {
433                         uint32_t exception;
434                         uint32_t error_code;
435                 } ex;
436                 /* LITEVM_EXIT_IO */
437                 struct {
438 #define LITEVM_EXIT_IO_IN  0
439 #define LITEVM_EXIT_IO_OUT 1
440                         uint8_t direction;
441                         uint8_t size; /* bytes */
442                         uint8_t string;
443                         uint8_t string_down;
444                         uint8_t rep;
445                         uint8_t pad;
446                         uint16_t port;
447                         uint64_t count;
448                         union {
449                                 uint64_t address;
450                                 uint32_t value;
451                         };
452                 } io;
453                 struct {
454                 } debug;
455                 /* LITEVM_EXIT_MMIO */
456                 struct {
457                         uint64_t phys_addr;
458                         uint8_t  data[8];
459                         uint32_t len;
460                         uint8_t  is_write;
461                 } mmio;
462         };
463 };
464
465 /* for LITEVM_GET_REGS and LITEVM_SET_REGS */
466 struct litevm_regs {
467         /* in */
468         uint32_t vcpu;
469         uint32_t padding;
470
471         /* out (LITEVM_GET_REGS) / in (LITEVM_SET_REGS) */
472         uint64_t rax, rbx, rcx, rdx;
473         uint64_t rsi, rdi, rsp, rbp;
474         uint64_t r8,  r9,  r10, r11;
475         uint64_t r12, r13, r14, r15;
476         uint64_t rip, rflags;
477 };
478
479 struct litevm_segment {
480         uint64_t base;
481         uint32_t limit;
482         uint16_t selector;
483         uint8_t  type;
484         uint8_t  present, dpl, db, s, l, g, avl;
485         uint8_t  unusable;
486         uint8_t  padding;
487 };
488
489 struct litevm_dtable {
490         uint64_t base;
491         uint16_t limit;
492         uint16_t padding[3];
493 };
494
495 /* for LITEVM_GET_SREGS and LITEVM_SET_SREGS */
496 struct litevm_sregs {
497         /* in */
498         uint32_t vcpu;
499         uint32_t padding;
500
501         /* out (LITEVM_GET_SREGS) / in (LITEVM_SET_SREGS) */
502         struct litevm_segment cs, ds, es, fs, gs, ss;
503         struct litevm_segment tr, ldt;
504         struct litevm_dtable gdt, idt;
505         uint64_t cr0, cr2, cr3, cr4, cr8;
506         uint64_t efer;
507         uint64_t apic_base;
508
509         /* out (LITEVM_GET_SREGS) */
510         uint32_t pending_int;
511         uint32_t padding2;
512 };
513
514 /* for LITEVM_TRANSLATE */
515 struct litevm_translation {
516         /* in */
517         uint64_t linear_address;
518         uint32_t vcpu;
519         uint32_t padding;
520
521         /* out */
522         uint64_t physical_address;
523         uint8_t  valid;
524         uint8_t  writeable;
525         uint8_t  usermode;
526 };
527
528 /* for LITEVM_INTERRUPT */
529 struct litevm_interrupt {
530         /* in */
531         uint32_t vcpu;
532         uint32_t irq;
533 };
534
535 struct litevm_breakpoint {
536         uint32_t enabled;
537         uint32_t padding;
538         uint64_t address;
539 };
540
541 /* for LITEVM_DEBUG_GUEST */
542 struct litevm_debug_guest {
543         /* int */
544         uint32_t vcpu;
545         uint32_t enabled;
546         struct litevm_breakpoint breakpoints[4];
547         uint32_t singlestep;
548 };
549
550 /* for LITEVM_GET_DIRTY_LOG */
551 struct litevm_dirty_log {
552         uint32_t slot;
553         uint32_t padding;
554         union {
555                 void *dirty_bitmap; /* one bit per page */
556                 uint64_t paddingw;
557         };
558 };
559
560 enum {
561         LITEVM_RUN = 1,
562         LITEVM_GET_REGS,
563         LITEVM_SET_REGS,
564         LITEVM_GET_SREGS,
565         LITEVM_SET_SREGS,
566         LITEVM_TRANSLATE,
567         LITEVM_INTERRUPT,
568         LITEVM_DEBUG_GUEST,
569         LITEVM_SET_MEMORY_REGION,
570         LITEVM_CREATE_VCPU,
571         LITEVM_GET_DIRTY_LOG,
572 };
573 #endif