diff options
Diffstat (limited to 'testcases/kernel/kvm/bootstrap_x86_64.S')
-rw-r--r-- | testcases/kernel/kvm/bootstrap_x86_64.S | 110 |
1 files changed, 108 insertions, 2 deletions
diff --git a/testcases/kernel/kvm/bootstrap_x86_64.S b/testcases/kernel/kvm/bootstrap_x86_64.S index 9ddbd17ed..b02dd4d92 100644 --- a/testcases/kernel/kvm/bootstrap_x86_64.S +++ b/testcases/kernel/kvm/bootstrap_x86_64.S @@ -8,6 +8,9 @@ .set KVM_TCONF, 32 .set KVM_TEXIT, 0xff .set RESULT_ADDRESS, 0xfffff000 +.set KVM_GDT_SIZE, 32 + +.set MSR_VM_HSAVE_PA, 0xc0010117 /* * This section will be allocated at address 0x1000 and @@ -32,7 +35,7 @@ protected_mode_entry: mov %eax, %es jmp init_memlayout -.section .data.gdt32, "a", @progbits +.section .init.gdt32, "a", @progbits .macro gdt32_entry type:req l=0 d=0 dpl=0 limit=0xfffff g=1 p=1 .4byte \limit & 0xffff @@ -302,6 +305,22 @@ kvm_read_cregs: mov %rax, 24(%rdi) retq +.global kvm_read_sregs +kvm_read_sregs: + mov %cs, %ax + movw %ax, (%rdi) + mov %ds, %ax + movw %ax, 2(%rdi) + mov %es, %ax + movw %ax, 4(%rdi) + mov %fs, %ax + movw %ax, 6(%rdi) + mov %gs, %ax + movw %ax, 8(%rdi) + mov %ss, %ax + movw %ax, 10(%rdi) + retq + handle_interrupt: /* push CPU state */ push %rbp @@ -457,6 +476,93 @@ kvm_yield: hlt ret +.global kvm_svm_guest_entry +kvm_svm_guest_entry: + call *%rax +1: hlt + jmp 1b + +.global kvm_svm_vmrun +kvm_svm_vmrun: + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + + clgi + + /* Save full host state */ + movq $MSR_VM_HSAVE_PA, %rcx + rdmsr + shlq $32, %rdx + orq %rdx, %rax + vmsave + pushq %rax + + /* Load guest registers */ + pushq %rdi + movq (%rdi), %rax + /* %rax is loaded by vmrun from VMCB */ + movq 0x10(%rdi), %rbx + movq 0x18(%rdi), %rcx + movq 0x20(%rdi), %rdx + movq 0x30(%rdi), %rsi + movq 0x38(%rdi), %rbp + /* %rsp is loaded by vmrun from VMCB */ + movq 0x48(%rdi), %r8 + movq 0x50(%rdi), %r9 + movq 0x58(%rdi), %r10 + movq 0x60(%rdi), %r11 + movq 0x68(%rdi), %r12 + movq 0x70(%rdi), %r13 + movq 0x78(%rdi), %r14 + movq 0x80(%rdi), %r15 + movq 0x28(%rdi), %rdi + + vmload + vmrun + vmsave + + /* Save guest registers */ + movq %rdi, %rax + popq %rdi + movq %rbx, 0x10(%rdi) + movq %rcx, 0x18(%rdi) + movq %rdx, 0x20(%rdi) + /* %rax contains guest %rdi */ + movq %rax, 0x28(%rdi) + movq %rsi, 0x30(%rdi) + movq %rbp, 0x38(%rdi) + movq %r8, 0x48(%rdi) + movq %r9, 0x50(%rdi) + movq %r10, 0x58(%rdi) + movq %r11, 0x60(%rdi) + movq %r12, 0x68(%rdi) + movq %r13, 0x70(%rdi) + movq %r14, 0x78(%rdi) + movq %r15, 0x80(%rdi) + /* copy guest %rax and %rsp from VMCB*/ + movq (%rdi), %rsi + movq 0x5f8(%rsi), %rax + movq %rax, 0x08(%rdi) + movq 0x5d8(%rsi), %rax + movq %rax, 0x40(%rdi) + + /* Reload host state */ + popq %rax + vmload + + stgi + + popq %r15 + popq %r14 + popq %r13 + popq %r12 + popq %rbp + popq %rbx + retq .section .bss.pgtables, "aw", @nobits .global kvm_pagetable @@ -478,7 +584,7 @@ kvm_pgtable_l4: kvm_gdt: .8byte 0 gdt32_entry type=0x1a l=1 limit=0 g=0 /* Code segment long mode */ - .skip 16 /* TSS segment descriptor */ + .skip (KVM_GDT_SIZE-2)*8 /* TSS and other segment descriptors */ .Lgdt_end: .global kvm_gdt_desc |