Add run support.
[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_ENTRY(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;
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, litevm_mmu_page) link;
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 //#warning "bitmap is u8. "
204         /*unsigned long*/uint8_t *dirty_bitmap;
205 };
206
207 struct litevm {
208         spinlock_t lock; /* protects everything except vcpus */
209         int nmemslots;
210         struct litevm_memory_slot memslots[LITEVM_MEMORY_SLOTS];
211         LIST_HEAD(active_mmu_pages, litevm_mmu_page) link;
212         //struct list_head active_mmu_pages;
213         struct litevm_vcpu vcpus[LITEVM_MAX_VCPUS];
214         int memory_config_version;
215         int busy;
216 };
217
218 struct litevm_stat {
219         uint32_t pf_fixed;
220         uint32_t pf_guest;
221         uint32_t tlb_flush;
222         uint32_t invlpg;
223
224         uint32_t exits;
225         uint32_t io_exits;
226         uint32_t mmio_exits;
227         uint32_t signal_exits;
228         uint32_t irq_exits;
229 };
230
231 extern struct litevm_stat litevm_stat;
232
233 #define litevm_printf(litevm, fmt ...) printd(fmt)
234 #define vcpu_printf(vcpu, fmt...) litevm_printf(vcpu->litevm, fmt)
235
236 void litevm_mmu_destroy(struct litevm_vcpu *vcpu);
237 int litevm_mmu_init(struct litevm_vcpu *vcpu);
238
239 int litevm_mmu_reset_context(struct litevm_vcpu *vcpu);
240 void litevm_mmu_slot_remove_write_access(struct litevm *litevm, int slot);
241
242 hpa_t gpa_to_hpa(struct litevm_vcpu *vcpu, gpa_t gpa);
243 #define HPA_MSB ((sizeof(hpa_t) * 8) - 1)
244 #define HPA_ERR_MASK ((hpa_t)1 << HPA_MSB)
245 static inline int is_error_hpa(hpa_t hpa) { return hpa >> HPA_MSB; }
246 hpa_t gva_to_hpa(struct litevm_vcpu *vcpu, gva_t gva);
247
248 extern hpa_t bad_page_address;
249
250 static inline struct page *gfn_to_page(struct litevm_memory_slot *slot, gfn_t gfn)
251 {
252         return slot->phys_mem[gfn - slot->base_gfn];
253 }
254
255 struct litevm_memory_slot *gfn_to_memslot(struct litevm *litevm, gfn_t gfn);
256 void mark_page_dirty(struct litevm *litevm, gfn_t gfn);
257
258 void realmode_lgdt(struct litevm_vcpu *vcpu, uint16_t size, unsigned long address);
259 void realmode_lidt(struct litevm_vcpu *vcpu, uint16_t size, unsigned long address);
260 void realmode_lmsw(struct litevm_vcpu *vcpu, unsigned long msw,
261                    unsigned long *rflags);
262
263 unsigned long realmode_get_cr(struct litevm_vcpu *vcpu, int cr);
264 void realmode_set_cr(struct litevm_vcpu *vcpu, int cr, unsigned long value,
265                      unsigned long *rflags);
266
267 int litevm_read_guest(struct litevm_vcpu *vcpu,
268                gva_t addr,
269                unsigned long size,
270                void *dest);
271
272 int litevm_write_guest(struct litevm_vcpu *vcpu,
273                 gva_t addr,
274                 unsigned long size,
275                 void *data);
276
277 void vmcs_writel(unsigned long field, unsigned long value);
278 unsigned long vmcs_readl(unsigned long field);
279
280 static inline uint16_t vmcs_read16(unsigned long field)
281 {
282         return vmcs_readl(field);
283 }
284
285 static inline uint32_t vmcs_read32(unsigned long field)
286 {
287         return vmcs_readl(field);
288 }
289
290 static inline uint64_t vmcs_read64(unsigned long field)
291 {
292 #ifdef __x86_64__
293         return vmcs_readl(field);
294 #else
295         return vmcs_readl(field) | ((uint64_t)vmcs_readl(field+1) << 32);
296 #endif
297 }
298
299 static inline void vmcs_write32(unsigned long field, uint32_t value)
300 {
301         vmcs_writel(field, value);
302 }
303
304 static inline int is_long_mode(void)
305 {
306         return vmcs_read32(VM_ENTRY_CONTROLS) & VM_ENTRY_CONTROLS_IA32E_MASK;
307 }
308
309 static inline unsigned long guest_cr4(void)
310 {
311         return (vmcs_readl(CR4_READ_SHADOW) & LITEVM_GUEST_CR4_MASK) |
312                 (vmcs_readl(GUEST_CR4) & ~LITEVM_GUEST_CR4_MASK);
313 }
314
315 static inline int is_pae(void)
316 {
317         return guest_cr4() & CR4_PAE_MASK;
318 }
319
320 static inline int is_pse(void)
321 {
322         return guest_cr4() & CR4_PSE_MASK;
323 }
324
325 static inline unsigned long guest_cr0(void)
326 {
327         return (vmcs_readl(CR0_READ_SHADOW) & LITEVM_GUEST_CR0_MASK) |
328                 (vmcs_readl(GUEST_CR0) & ~LITEVM_GUEST_CR0_MASK);
329 }
330
331 static inline unsigned guest_cpl(void)
332 {
333         return vmcs_read16(GUEST_CS_SELECTOR) & SELECTOR_RPL_MASK;
334 }
335
336 static inline int is_paging(void)
337 {
338         return guest_cr0() & CR0_PG_MASK;
339 }
340
341 static inline int is_page_fault(uint32_t intr_info)
342 {
343         return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
344                              INTR_INFO_VALID_MASK)) ==
345                 (INTR_TYPE_EXCEPTION | PF_VECTOR | INTR_INFO_VALID_MASK);
346 }
347
348 static inline int is_external_interrupt(uint32_t intr_info)
349 {
350         return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK))
351                 == (INTR_TYPE_EXT_INTR | INTR_INFO_VALID_MASK);
352 }
353
354 static inline void flush_guest_tlb(struct litevm_vcpu *vcpu)
355 {
356         vmcs_writel(GUEST_CR3, vmcs_readl(GUEST_CR3));
357 }
358
359 static inline int memslot_id(struct litevm *litevm, struct litevm_memory_slot *slot)
360 {
361         return slot - litevm->memslots;
362 }
363
364 static inline struct litevm_mmu_page *page_header(hpa_t shadow_page)
365 {
366         struct page *page = ppn2page(shadow_page >> PAGE_SHIFT);
367
368         return (struct litevm_mmu_page *)page->pg_private;
369 }
370
371 #ifdef __x86_64__
372
373 /*
374  * When emulating 32-bit mode, cr3 is only 32 bits even on x86_64.  Therefore
375  * we need to allocate shadow page tables in the first 4GB of memory, which
376  * happens to fit the DMA32 zone.
377  */
378 #define GFP_LITEVM_MMU (GFP_KERNEL | __GFP_DMA32)
379
380 #else
381
382 #define GFP_LITEVM_MMU GFP_KERNEL
383
384 #endif
385
386 /* just to get things to build ... include this stuff for now.
387  * at some point, this interface gets nuke to and made more plan 
388  * 9 like.
389  */
390
391 /* for LITEVM_CREATE_MEMORY_REGION */
392 struct litevm_memory_region {
393         uint32_t slot;
394         uint32_t flags;
395         uint64_t guest_phys_addr;
396         uint64_t memory_size; /* bytes */
397         void *init_data;
398 };
399
400 /* for litevm_memory_region::flags */
401 #define LITEVM_MEM_LOG_DIRTY_PAGES  1UL
402
403
404 #define LITEVM_EXIT_TYPE_FAIL_ENTRY 1
405 #define LITEVM_EXIT_TYPE_VM_EXIT    2
406
407 enum litevm_exit_reason {
408         LITEVM_EXIT_UNKNOWN,
409         LITEVM_EXIT_EXCEPTION,
410         LITEVM_EXIT_IO,
411         LITEVM_EXIT_CPUID,
412         LITEVM_EXIT_DEBUG,
413         LITEVM_EXIT_HLT,
414         LITEVM_EXIT_MMIO,
415 };
416
417 /* for LITEVM_RUN */
418 struct litevm_run {
419         /* in */
420         uint32_t vcpu;
421         uint32_t emulated;  /* skip current instruction */
422         uint32_t mmio_completed; /* mmio request completed */
423
424         /* out */
425         uint32_t exit_type;
426         uint32_t exit_reason;
427         uint32_t instruction_length;
428         union {
429                 /* LITEVM_EXIT_UNKNOWN */
430                 struct {
431                         uint32_t hardware_exit_reason;
432                 } hw;
433                 /* LITEVM_EXIT_EXCEPTION */
434                 struct {
435                         uint32_t exception;
436                         uint32_t error_code;
437                 } ex;
438                 /* LITEVM_EXIT_IO */
439                 struct {
440 #define LITEVM_EXIT_IO_IN  0
441 #define LITEVM_EXIT_IO_OUT 1
442                         uint8_t direction;
443                         uint8_t size; /* bytes */
444                         uint8_t string;
445                         uint8_t string_down;
446                         uint8_t rep;
447                         uint8_t pad;
448                         uint16_t port;
449                         uint64_t count;
450                         union {
451                                 uint64_t address;
452                                 uint32_t value;
453                         };
454                 } io;
455                 struct {
456                 } debug;
457                 /* LITEVM_EXIT_MMIO */
458                 struct {
459                         uint64_t phys_addr;
460                         uint8_t  data[8];
461                         uint32_t len;
462                         uint8_t  is_write;
463                 } mmio;
464         };
465 };
466
467 /* for LITEVM_GET_REGS and LITEVM_SET_REGS */
468 struct litevm_regs {
469         /* in */
470         uint32_t vcpu;
471         uint32_t padding;
472
473         /* out (LITEVM_GET_REGS) / in (LITEVM_SET_REGS) */
474         uint64_t rax, rbx, rcx, rdx;
475         uint64_t rsi, rdi, rsp, rbp;
476         uint64_t r8,  r9,  r10, r11;
477         uint64_t r12, r13, r14, r15;
478         uint64_t rip, rflags;
479 };
480
481 struct litevm_segment {
482         uint64_t base;
483         uint32_t limit;
484         uint16_t selector;
485         uint8_t  type;
486         uint8_t  present, dpl, db, s, l, g, avl;
487         uint8_t  unusable;
488         uint8_t  padding;
489 };
490
491 struct litevm_dtable {
492         uint64_t base;
493         uint16_t limit;
494         uint16_t padding[3];
495 };
496
497 /* for LITEVM_GET_SREGS and LITEVM_SET_SREGS */
498 struct litevm_sregs {
499         /* in */
500         uint32_t vcpu;
501         uint32_t padding;
502
503         /* out (LITEVM_GET_SREGS) / in (LITEVM_SET_SREGS) */
504         struct litevm_segment cs, ds, es, fs, gs, ss;
505         struct litevm_segment tr, ldt;
506         struct litevm_dtable gdt, idt;
507         uint64_t cr0, cr2, cr3, cr4, cr8;
508         uint64_t efer;
509         uint64_t apic_base;
510
511         /* out (LITEVM_GET_SREGS) */
512         uint32_t pending_int;
513         uint32_t padding2;
514 };
515
516 /* for LITEVM_TRANSLATE */
517 struct litevm_translation {
518         /* in */
519         uint64_t linear_address;
520         uint32_t vcpu;
521         uint32_t padding;
522
523         /* out */
524         uint64_t physical_address;
525         uint8_t  valid;
526         uint8_t  writeable;
527         uint8_t  usermode;
528 };
529
530 /* for LITEVM_INTERRUPT */
531 struct litevm_interrupt {
532         /* in */
533         uint32_t vcpu;
534         uint32_t irq;
535 };
536
537 struct litevm_breakpoint {
538         uint32_t enabled;
539         uint32_t padding;
540         uint64_t address;
541 };
542
543 /* for LITEVM_DEBUG_GUEST */
544 struct litevm_debug_guest {
545         /* int */
546         uint32_t vcpu;
547         uint32_t enabled;
548         struct litevm_breakpoint breakpoints[4];
549         uint32_t singlestep;
550 };
551
552 /* for LITEVM_GET_DIRTY_LOG */
553 struct litevm_dirty_log {
554         uint32_t slot;
555         uint32_t padding;
556         union {
557                 void *dirty_bitmap; /* one bit per page */
558                 uint64_t paddingw;
559         };
560 };
561
562 enum {
563         LITEVM_RUN = 1,
564         LITEVM_GET_REGS,
565         LITEVM_SET_REGS,
566         LITEVM_GET_SREGS,
567         LITEVM_SET_SREGS,
568         LITEVM_TRANSLATE,
569         LITEVM_INTERRUPT,
570         LITEVM_DEBUG_GUEST,
571         LITEVM_SET_MEMORY_REGION,
572         LITEVM_CREATE_VCPU,
573         LITEVM_GET_DIRTY_LOG,
574 };
575
576 struct litevm *vmx_open(void);
577 int vmx_create_vcpu(struct litevm *litevm, int n);
578 int vmx_init(void);
579 int vm_set_memory_region(struct litevm *litevm,
580                          struct litevm_memory_region *mem);
581 int vm_run(struct litevm *litevm, struct litevm_run *litevm_run);
582 #endif