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