aboutsummaryrefslogtreecommitdiff
path: root/testcases/kernel/kvm/bootstrap_x86_64.S
diff options
context:
space:
mode:
Diffstat (limited to 'testcases/kernel/kvm/bootstrap_x86_64.S')
-rw-r--r--testcases/kernel/kvm/bootstrap_x86_64.S110
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