1/*
2 * entry.S: VMX architecture-specific entry/exit handling.
3 * Copyright (c) 2004, Intel Corporation.
4 * Copyright (c) 2008, Citrix Systems, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; If not, see <http://www.gnu.org/licenses/>.
17 */
18
19        .file "vmx/entry.S"
20
21#include <xen/errno.h>
22#include <xen/softirq.h>
23#include <asm/types.h>
24#include <asm/asm_defns.h>
25#include <asm/apicdef.h>
26#include <asm/page.h>
27#include <public/xen.h>
28
29#define VMRESUME     .byte 0x0f,0x01,0xc3
30#define VMLAUNCH     .byte 0x0f,0x01,0xc2
31
32ENTRY(vmx_asm_vmexit_handler)
33        push %rdi
34        push %rsi
35        push %rdx
36        push %rcx
37        push %rax
38        mov  %cr2,%rax
39        push %r8
40        push %r9
41        push %r10
42        push %r11
43        push %rbx
44        GET_CURRENT(bx)
45        push %rbp
46        push %r12
47        push %r13
48        push %r14
49        push %r15
50
51        movb $1,VCPU_vmx_launched(%rbx)
52        mov  %rax,VCPU_hvm_guest_cr2(%rbx)
53
54        mov  %rsp,%rdi
55        call vmx_vmexit_handler
56
57.Lvmx_do_vmentry:
58        call vmx_intr_assist
59        call nvmx_switch_guest
60        ASSERT_NOT_IN_ATOMIC
61
62        mov  VCPU_processor(%rbx),%eax
63        lea  irq_stat+IRQSTAT_softirq_pending(%rip),%rdx
64        xor  %ecx,%ecx
65        shl  $IRQSTAT_shift,%eax
66        cli
67        cmp  %ecx,(%rdx,%rax,1)
68        jnz  .Lvmx_process_softirqs
69
70        cmp  %cl,VCPU_vmx_emulate(%rbx)
71        jne .Lvmx_goto_emulator
72        cmp  %cl,VCPU_vmx_realmode(%rbx)
73UNLIKELY_START(ne, realmode)
74        cmp  %cx,VCPU_vm86_seg_mask(%rbx)
75        jnz .Lvmx_goto_emulator
76        mov  %rsp,%rdi
77        call vmx_enter_realmode
78UNLIKELY_END(realmode)
79
80        mov  %rsp,%rdi
81        call vmx_vmenter_helper
82        test %al, %al
83        jz .Lvmx_vmentry_restart
84        mov  VCPU_hvm_guest_cr2(%rbx),%rax
85
86        pop  %r15
87        pop  %r14
88        pop  %r13
89        pop  %r12
90        pop  %rbp
91        mov  %rax,%cr2
92        cmpb $0,VCPU_vmx_launched(%rbx)
93        pop  %rbx
94        pop  %r11
95        pop  %r10
96        pop  %r9
97        pop  %r8
98        pop  %rax
99        pop  %rcx
100        pop  %rdx
101        pop  %rsi
102        pop  %rdi
103        je   .Lvmx_launch
104
105/*.Lvmx_resume:*/
106        VMRESUME
107        jmp  .Lvmx_vmentry_fail
108
109.Lvmx_launch:
110        VMLAUNCH
111
112.Lvmx_vmentry_fail:
113        sti
114        SAVE_ALL
115        call vmx_vmentry_failure
116        BUG  /* vmx_vmentry_failure() shouldn't return. */
117
118ENTRY(vmx_asm_do_vmentry)
119        GET_CURRENT(bx)
120        jmp  .Lvmx_do_vmentry
121
122.Lvmx_vmentry_restart:
123        sti
124        jmp  .Lvmx_do_vmentry
125
126.Lvmx_goto_emulator:
127        sti
128        mov  %rsp,%rdi
129        call vmx_realmode
130        jmp  .Lvmx_do_vmentry
131
132.Lvmx_process_softirqs:
133        sti
134        call do_softirq
135        jmp  .Lvmx_do_vmentry
136