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