Home | History | Annotate | Download | only in executor
      1 // Copyright 2017 syzkaller project authors. All rights reserved.
      2 // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
      3 
      4 // kvm_gen.cc generates machine code from this file and saves it into kvm.S.h.
      5 
      6 // +build
      7 
      8 #include "kvm.h"
      9 
     10 .global kvm_asm64_enable_long, kvm_asm64_enable_long_end
     11 kvm_asm64_enable_long:
     12 .code32
     13 	mov %cr0, %eax
     14 	or $0x80000000, %eax
     15 	mov %eax, %cr0
     16 	ljmp $SEL_CS64, NEXT_INSN
     17 .code64
     18 	mov $SEL_TSS64, %rax
     19 	ltr %ax
     20 kvm_asm64_enable_long_end:
     21 	nop
     22 
     23 .global kvm_asm32_paged, kvm_asm32_paged_end
     24 kvm_asm32_paged:
     25 .code32
     26 	mov %cr0, %eax
     27 	or $0x80000000, %eax
     28 	mov %eax, %cr0
     29 kvm_asm32_paged_end:
     30 	nop
     31 
     32 .global kvm_asm32_vm86, kvm_asm32_vm86_end
     33 kvm_asm32_vm86:
     34 .code32
     35 	mov $SEL_TSS32, %ax
     36 	ltr %ax
     37 	ljmp $SEL_TSS32_VM86, $0
     38 kvm_asm32_vm86_end:
     39 	nop
     40 
     41 .global kvm_asm32_paged_vm86, kvm_asm32_paged_vm86_end
     42 kvm_asm32_paged_vm86:
     43 .code32
     44 	mov %cr0, %eax
     45 	or $0x80000000, %eax
     46 	mov %eax, %cr0
     47 	mov $SEL_TSS32, %ax
     48 	ltr %ax
     49 	ljmp $SEL_TSS32_VM86, $0
     50 kvm_asm32_paged_vm86_end:
     51 	nop
     52 
     53 .global kvm_asm64_vm86, kvm_asm64_vm86_end
     54 kvm_asm64_vm86:
     55 .code32
     56 	mov %cr0, %eax
     57 	or $0x80000000, %eax
     58 	mov %eax, %cr0
     59 	mov $SEL_TSS32, %ax
     60 	ltr %ax
     61 	ljmp $SEL_TSS32_VM86, $0
     62 kvm_asm64_vm86_end:
     63 	nop
     64 
     65 .global kvm_asm16_cpl3, kvm_asm16_cpl3_end
     66 kvm_asm16_cpl3:
     67 .code16
     68 	mov %cr0, %eax
     69 	or $1, %eax
     70 	mov %eax, %cr0
     71 	mov $SEL_TSS16, %ax
     72 	ltr %ax
     73 	mov $SEL_DS16_CPL3, %ax
     74 	mov %ax, %ds
     75 	mov %ax, %es
     76 	mov %ax, %fs
     77 	mov %ax, %gs
     78 	mov $0x100, %sp
     79 	movw $PREFIX_SIZE, 0x100
     80 	movw $SEL_CS16_CPL3, 0x102
     81 	movw $0x100, 0x104
     82 	movw $SEL_DS16_CPL3, 0x106
     83 	lret
     84 kvm_asm16_cpl3_end:
     85 	nop
     86 
     87 .global kvm_asm64_cpl3, kvm_asm64_cpl3_end
     88 kvm_asm64_cpl3:
     89 .code32
     90 	mov %cr0, %eax
     91 	or $0x80000000, %eax
     92 	mov %eax, %cr0
     93 	ljmp $SEL_CS64, NEXT_INSN
     94 .code64
     95 	mov $SEL_TSS64, %rax
     96 	ltr %ax
     97 	mov $SEL_DS64_CPL3, %rax
     98 	mov %ax, %ds
     99 	mov %ax, %es
    100 	mov %ax, %fs
    101 	mov %ax, %gs
    102 	mov $ADDR_STACK0, %rsp
    103 	movq $PREFIX_SIZE, 0(%rsp)
    104 	movq $SEL_CS64_CPL3, 4(%rsp)
    105 	movq $ADDR_STACK0, 8(%rsp)
    106 	movq $SEL_DS64_CPL3, 12(%rsp)
    107 	lret
    108 kvm_asm64_cpl3_end:
    109 	nop
    110 
    111 .global kvm_asm64_init_vm, kvm_asm64_init_vm_end
    112 kvm_asm64_init_vm:
    113 .code32
    114 	// CR0.PG = 1
    115 	mov %cr0, %eax
    116 	or $0x80000000, %eax
    117 	mov %eax, %cr0
    118 	ljmp $SEL_CS64, NEXT_INSN
    119 .code64
    120 	mov $SEL_TSS64, %rax
    121 	ltr %ax
    122 
    123 	// Enable and lock non-SMM VM
    124 	mov $MSR_IA32_FEATURE_CONTROL, %rcx
    125 	rdmsr
    126 	or $0x5, %rax
    127 	wrmsr
    128 
    129 	// CR4.VMXE = 1
    130 	mov %cr4, %rax
    131 	or $0x2000, %rax
    132 	mov %rax, %cr4
    133 
    134 	// Write VMCS revision into VMXON and VMCS regions
    135 	mov $MSR_IA32_VMX_BASIC, %rcx
    136 	rdmsr
    137 	mov $ADDR_VAR_VMXON, %rdx
    138 	mov %eax, (%rdx)
    139 	mov $ADDR_VAR_VMCS, %rdx
    140 	mov %eax, (%rdx)
    141 
    142 	mov $ADDR_VAR_VMXON_PTR, %rax
    143 	vmxon (%rax)
    144 	mov $ADDR_VAR_VMCS_PTR, %rax
    145 	vmclear (%rax)
    146 	vmptrld (%rax)
    147 
    148 #define VMSET(FIELD, VAL)	\
    149 	mov $FIELD, %rdx;	\
    150 	mov VAL, %rax;		\
    151 	vmwrite %rax, %rdx;	\
    152 	/**/
    153 
    154 #define VMSET_LIMITED(FIELD, VAL, MSR)	\
    155 	mov $MSR, %rcx;		\
    156 	rdmsr;			\
    157 	or VAL, %rax;		\
    158 	and %rdx, %rax;		\
    159 	mov $FIELD, %rdx;	\
    160 	vmwrite %rax, %rdx;	\
    161 	/**/
    162 
    163 	VMSET_LIMITED(0x00004000, $0x3f, 0x481) // Pin-based VM-execution controls
    164 	//VMSET_LIMITED(0x00004002, $0x61999e84, 0x482) // Primary processor-based VM-execution controls
    165 	VMSET(0x00004002, $0xf3999e84)
    166 	VMSET(0x0000401E, $((1<<0) | (1<<7))) // Secondary processor-based VM-execution controls
    167 	VMSET_LIMITED(0x0000400C, $0x36fff, 0x483) // VM-exit controls (F6FFF)
    168 	VMSET_LIMITED(0x00004012, $0x17ff, 0x484) // VM-entry controls (51FF)
    169 
    170 	VMSET(0x00002C04, $0) // Host IA32_PERF_GLOBAL_CTR
    171 	VMSET(0x00002800, $0xffffffffffffffff) // VMCS link pointer
    172 
    173 	VMSET(0x00000C02, $SEL_CS64) // host CS
    174 
    175 	mov $SEL_DS64, %rax
    176 	mov $0x00000C00, %rdx // host ES
    177 	vmwrite %rax, %rdx
    178 	mov $0x00000C04, %rdx // host SS
    179 	vmwrite %rax, %rdx
    180 	mov $0x00000C06, %rdx // host DS
    181 	vmwrite %rax, %rdx
    182 	mov $0x00000C08, %rdx // host FS
    183 	vmwrite %rax, %rdx
    184 	mov $0x00000C0A, %rdx // host GS
    185 	vmwrite %rax, %rdx
    186 	mov $SEL_TSS64, %rax
    187 	mov $0x00000C0C, %rdx // host TR
    188 	vmwrite %rax, %rdx
    189 
    190 	VMSET(0x00002C02, $0x500) // host EFER
    191 
    192 	VMSET(0x00004C00, $SEL_CS64) // Host IA32_SYSENTER_CS
    193 	VMSET(0x00006C10, $0) // Host IA32_SYSENTER_ESP
    194 	VMSET(0x00006C12, $0) // Host IA32_SYSENTER_EIP
    195 
    196 	mov %cr0, %rax
    197 	VMSET(0x00006C00, %rax) // host CR0
    198 	mov %cr3, %rax
    199 	VMSET(0x00006C02, %rax) // host CR3
    200 	mov %cr4, %rax
    201 	VMSET(0x00006C04, %rax) // host CR4
    202 
    203 	VMSET(0x00006C06, $0) // host FS base
    204 	VMSET(0x00006C08, $0) // host GS base
    205 	VMSET(0x00006C0A, $ADDR_VAR_TSS64) // host TR base
    206 
    207 	VMSET(0x00006C0C, $ADDR_GDT) // host GDTR base
    208 	VMSET(0x00006C0E, $ADDR_VAR_IDT) // host IDTR base
    209 
    210 	VMSET(0x00006C14, $0) // host RSP
    211 	VMSET(0x00006C16, ADDR_VAR_VMEXIT_PTR) // host RIP
    212 
    213 	VMSET(0x00000000, $1) // VPID
    214 	VMSET(0x00000002, $0) // Posted-interrupt notification vector
    215 	//VMSET(0x00000004, $0) // EPTP index
    216 
    217 	VMSET(0x00002000, $0) // Address of I/O bitmap A
    218 	VMSET(0x00002002, $0) // Address of I/O bitmap B
    219 	VMSET(0x00002004, $0) // Address of MSR bitmaps
    220 	VMSET(0x00002006, $0) // VM-exit MSR-store address
    221 
    222 	mov $0x277, %rcx
    223 	rdmsr
    224 	shl $32, %rdx
    225 	or %rdx, %rax
    226 	VMSET(0x00002C00, %rax) // Host IA32_PAT
    227 
    228 	VMSET(0x00004004, $0) // Exception bitmap
    229 	VMSET(0x0000400A, $0) // CR3-target count
    230 	VMSET(0x0000400E, $0) // VM-exit MSR-store count
    231 	VMSET(0x00004010, $0) // VM-exit MSR-load count
    232 	VMSET(0x00004016, $0) // VM-entry interruption-information field
    233 	VMSET(0x00004014, $0) // VM-entry MSR-load count
    234 
    235 	VMSET(0x00006000, $0xffffffffffffffff) // CR0 guest/host mask
    236 	VMSET(0x00006002, $0xffffffffffffffff) // CR4 guest/host mask
    237 
    238 	VMSET(0x0000201C, $0) // EOI-exit bitmap 0
    239 	VMSET(0x0000201E, $0) // EOI-exit bitmap 1
    240 	VMSET(0x00002020, $0) // EOI-exit bitmap 2
    241 	VMSET(0x00002022, $0) // EOI-exit bitmap 3
    242 
    243 	VMSET(0x00000800, $SEL_DS64) // Guest ES selector
    244 	VMSET(0x00000802, $SEL_CS64) // Guest CS selector
    245 	VMSET(0x00000804, $SEL_DS64) // Guest SS selector
    246 	VMSET(0x00000806, $SEL_DS64) // Guest DS selector
    247 	VMSET(0x00000808, $SEL_DS64) // Guest FS selector
    248 	VMSET(0x0000080A, $SEL_DS64) // Guest GS selector
    249 	VMSET(0x0000080C, $0) // Guest LDTR selector
    250 	VMSET(0x0000080E, $SEL_TSS64) // Guest TR selector
    251 
    252 	VMSET(0x00006812, $0) // Guest LDTR base
    253 	VMSET(0x00006814, $ADDR_VAR_TSS64) // Guest TR base
    254 	VMSET(0x00006816, $ADDR_GDT) // Guest GDTR base
    255 	VMSET(0x00006818, $ADDR_VAR_IDT) // Guest IDTR base
    256 
    257 	VMSET(0x00004800, $0xfffff) // Guest ES limit
    258 	VMSET(0x00004802, $0xfffff) // Guest CS limit
    259 	VMSET(0x00004804, $0xfffff) // Guest SS limit
    260 	VMSET(0x00004806, $0xfffff) // Guest DS limit
    261 	VMSET(0x00004808, $0xfffff) // Guest FS limit
    262 	VMSET(0x0000480A, $0xfffff) // Guest GS limit
    263 	VMSET(0x0000480C, $0) // Guest LDTR limit
    264 	VMSET(0x0000480E, $0x1fff) // Guest TR limit
    265 	VMSET(0x00004810, $0x1fff) // Guest GDTR limit
    266 	VMSET(0x00004812, $0x1fff) // Guest IDTR limit
    267 
    268 	VMSET(0x00004814, $0x4093) // Guest ES access rights
    269 	VMSET(0x00004816, $0x209b) // Guest CS access rights
    270 	VMSET(0x00004818, $0x4093) // Guest SS access rights
    271 	VMSET(0x0000481A, $0x4093) // Guest DS access rights
    272 	VMSET(0x0000481C, $0x4093) // Guest FS access rights
    273 	VMSET(0x0000481E, $0x4093) // Guest GS access rights
    274 	VMSET(0x00004820, $0x82) // Guest LDTR access rights
    275 	VMSET(0x00004822, $0x8b) // Guest TR access rights
    276 
    277 	VMSET(0x0000681C, $0) // Guest RSP
    278 	VMSET(0x0000681E, $ADDR_VAR_USER_CODE) // Guest RIP
    279 	VMSET(0x00006820, $((1<<1))) // Guest RFLAGS
    280 	VMSET(0x00002806, $0x500) // Guest IA32_EFER
    281 	VMSET(0x0000280A, $0) // Guest PDPTE0
    282 	VMSET(0x0000280C, $0) // Guest PDPTE1
    283 	VMSET(0x0000280E, $0) // Guest PDPTE2
    284 	VMSET(0x00002810, $0) // Guest PDPTE3
    285 
    286 	mov %cr0, %rax
    287 	VMSET(0x00006800, %rax) // Guest CR0
    288 	mov %cr3, %rax
    289 	VMSET(0x00006802, %rax) // Guest CR3
    290 	mov %cr4, %rax
    291 	VMSET(0x00006804, %rax) // Guest CR4
    292 
    293 	// Write 1 additional random field.
    294 	mov $ADDR_VAR_VMWRITE_FLD, %rax
    295 	mov (%rax), %rdx
    296 	mov $ADDR_VAR_VMWRITE_VAL, %rax
    297 	mov (%rax), %rcx
    298 	xor %rax, %rax
    299 	vmread %rdx, %rax
    300 	xor %rcx, %rax
    301 	vmwrite %rax, %rdx
    302 
    303 	vmlaunch
    304 
    305 	mov $0x00004400, %rdx
    306 	vmread %rdx, %rax
    307 	hlt
    308 kvm_asm64_init_vm_end:
    309 	nop
    310 
    311 .global kvm_asm64_vm_exit, kvm_asm64_vm_exit_end
    312 kvm_asm64_vm_exit:
    313 .code64
    314 	//vmresume
    315 	mov $0x00004400, %rbx // VM-instruction error
    316 	vmread %rbx, %rdx
    317 	mov $0x00004402, %rbx // Exit reason
    318 	vmread %rbx, %rcx
    319 	mov $0x00006400, %rax // Exit qualification
    320 	vmread %rax, %rax
    321 	mov $0x0000681E, %rbx // Guest RIP
    322 	vmread %rbx, %rbx
    323 	hlt
    324 kvm_asm64_vm_exit_end:
    325 	nop
    326