hammer2 - Merge Mihai Carabas's VKERNEL/VMM GSOC project into the main tree
[dragonfly.git] / sys / platform / pc64 / vmm / vmx_instr.h
1 /*
2  * Copyright (c) 2003-2013 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Mihai Carabas <mihai.carabas@gmail.com>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34
35 #ifndef _VMM_VMX_INSTR_H_
36 #define _VMM_VMX_INSTR_H_
37
38 #include <vm/pmap.h>
39
40 /*
41  * Chapter 30 VMX Instruction Reference
42  * Section 30.3 "Conventions"
43  * from Intel Architecture Manual 3C.
44  */
45 #define VM_SUCCEED              0
46 #define VM_FAIL_INVALID         1
47 #define VM_FAIL_VALID           2
48 #define VM_EXIT                 3
49
50 #define GET_ERROR_CODE                          \
51         "               jnc 1f;"                \
52         "               mov $1, %[err];"        \
53         "               jmp 4f;"                \
54         "1:             jnz 3f;"                \
55         "               mov $2, %[err];"        \
56         "               jmp 4f;"                \
57         "3:             mov $0, %[err];"        \
58         "4:"
59
60 static inline int
61 vmxon(char *vmx_region)
62 {
63         int err;
64         uint64_t paddr;
65
66         paddr = vtophys(vmx_region);
67         __asm __volatile("vmxon %[paddr];"
68                          GET_ERROR_CODE
69                          : [err] "=r" (err)
70                          : [paddr] "m" (paddr)
71                          : "memory");
72
73         return err;
74 }
75
76 static inline void
77 vmxoff(void)
78 {
79
80         __asm __volatile("vmxoff");
81 }
82
83 static inline int
84 vmclear(char *vmcs_region)
85 {
86         int err;
87         uint64_t paddr;
88
89         paddr = vtophys(vmcs_region);
90         __asm __volatile("vmclear %[paddr];"
91                          GET_ERROR_CODE
92                          : [err] "=r" (err)
93                          : [paddr] "m" (paddr)
94                          : "memory");
95         return err;
96 }
97
98 static inline void
99 vmptrst(uint64_t *addr)
100 {
101
102         __asm __volatile("vmptrst %[addr]"
103                         :
104                         : [addr] "m" (*addr)
105                         : "memory");
106 }
107
108 static inline int
109 vmptrld(char *vmcs)
110 {
111         int err;
112         uint64_t paddr;
113
114         paddr = vtophys(vmcs);
115         __asm __volatile("vmptrld %[paddr];"
116                          GET_ERROR_CODE
117                          : [err] "=r" (err)
118                          : [paddr] "m" (paddr)
119                          : "memory");
120         return err;
121 }
122
123 static inline int
124 vmwrite(uint64_t reg, uint64_t val)
125 {
126         int err;
127
128         __asm __volatile("vmwrite %[val], %[reg];"
129                          GET_ERROR_CODE
130                          : [err] "=r" (err)
131                          : [val] "r" (val), [reg] "r" (reg)
132                          : "memory");
133
134         return err;
135 }
136
137 static inline int
138 vmread(uint64_t reg, uint64_t *addr)
139 {
140         int err;
141
142         __asm __volatile("vmread %[reg], %[addr];"
143                          GET_ERROR_CODE
144                          : [err] "=r" (err)
145                          : [reg] "r" (reg), [addr] "m" (*addr)
146                          : "memory");
147
148         return err;
149 }
150
151 static inline int
152 invept(uint64_t type, uint64_t *desc_addr)
153 {
154         int err;
155
156         __asm __volatile("invept %[desc_addr], %[type];"
157                          GET_ERROR_CODE
158                          : [err] "=r" (err)
159                          : [desc_addr] "m" (*desc_addr), [type] "r" (type)
160                          : "memory");
161         return err;
162 }
163
164 #endif