2
* entry.S: VMX architecture-specific entry/exit handling.
3
* Copyright (c) 2004, Intel Corporation.
4
* Copyright (c) 2008, Citrix Systems, Inc.
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.
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
15
* You should have received a copy of the GNU General Public License along with
16
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17
* Place - Suite 330, Boston, MA 02111-1307 USA.
20
#include <xen/config.h>
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>
27
#include <public/xen.h>
29
#define VMRESUME .byte 0x0f,0x01,0xc3
30
#define VMLAUNCH .byte 0x0f,0x01,0xc2
31
#define VMREAD(off) .byte 0x0f,0x78,0x47,((off)-UREGS_rip)
32
#define VMWRITE(off) .byte 0x0f,0x79,0x47,((off)-UREGS_rip)
34
/* VMCS field encodings */
35
#define GUEST_RSP 0x681c
36
#define GUEST_RIP 0x681e
37
#define GUEST_RFLAGS 0x6820
39
#define get_current(reg) \
40
mov $STACK_SIZE-BYTES_PER_LONG, r(reg); \
42
and $~(BYTES_PER_LONG-1),r(reg); \
45
#if defined(__x86_64__)
46
#define r(reg) %r##reg
47
#define addr_of(lbl) lbl(%rip)
48
#define call_with_regs(fn) \
51
#else /* defined(__i386__) */
52
#define r(reg) %e##reg
53
#define addr_of(lbl) lbl
54
#define UREGS_rip UREGS_eip
55
#define UREGS_rsp UREGS_esp
56
#define call_with_regs(fn) \
64
.globl vmx_asm_vmexit_handler
65
vmx_asm_vmexit_handler:
66
#if defined(__x86_64__)
82
#else /* defined(__i386__) */
94
movb $1,VCPU_vmx_launched(r(bx))
96
lea UREGS_rip(r(sp)),r(di)
99
.byte 0x0f,0x78,0x07 /* vmread r(ax),(r(di)) */
102
mov $GUEST_RFLAGS,%eax
106
mov r(ax),VCPU_hvm_guest_cr2(r(bx))
110
mov %ax,UREGS_error_code(r(sp))
111
mov %ax,UREGS_entry_vector(r(sp))
112
mov %ax,UREGS_saved_upcall_mask(r(sp))
113
mov %ax,UREGS_cs(r(sp))
114
mov %ax,UREGS_ds(r(sp))
115
mov %ax,UREGS_es(r(sp))
116
mov %ax,UREGS_fs(r(sp))
117
mov %ax,UREGS_gs(r(sp))
118
mov %ax,UREGS_ss(r(sp))
121
call_with_regs(vmx_vmexit_handler)
123
.globl vmx_asm_do_vmentry
130
mov VCPU_processor(r(bx)),%eax
131
shl $IRQSTAT_shift,r(ax)
132
lea addr_of(irq_stat),r(dx)
133
cmpl $0,(r(dx),r(ax),1)
134
jnz .Lvmx_process_softirqs
136
testb $0xff,VCPU_vmx_emulate(r(bx))
137
jnz .Lvmx_goto_emulator
138
testb $0xff,VCPU_vmx_realmode(r(bx))
139
jz .Lvmx_not_realmode
140
cmpw $0,VCPU_vm86_seg_mask(r(bx))
141
jnz .Lvmx_goto_emulator
142
call_with_regs(vmx_enter_realmode)
145
call vmx_vmenter_helper
146
mov VCPU_hvm_guest_cr2(r(bx)),r(ax)
149
lea UREGS_rip(r(sp)),r(di)
151
/*VMWRITE(UREGS_rip)*/
152
.byte 0x0f,0x79,0x07 /* vmwrite (r(di)),r(ax) */
155
mov $GUEST_RFLAGS,%eax
156
VMWRITE(UREGS_eflags)
158
cmpb $0,VCPU_vmx_launched(r(bx))
159
#if defined(__x86_64__)
175
#else /* defined(__i386__) */
200
call_with_regs(vmx_realmode)
201
jmp vmx_asm_do_vmentry
203
.Lvmx_process_softirqs:
206
jmp vmx_asm_do_vmentry