github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/cpvmm/vmm/vmx/vmx.c (about) 1 /* 2 * Copyright (c) 2013 Intel Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * Unless required by applicable law or agreed to in writing, software 9 * distributed under the License is distributed on an "AS IS" BASIS, 10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 * See the License for the specific language governing permissions and 12 * limitations under the License. 13 */ 14 15 #include "vmm_defs.h" 16 #include "hw_utils.h" 17 #include "hw_vmx_utils.h" 18 #ifdef JLMDEBUG 19 #include "jlmdebug.h" 20 #endif 21 22 23 int vmx_on(UINT64* ptr_to_vmcs_region) { 24 int ret= 0; 25 UINT64 address= *ptr_to_vmcs_region; 26 #ifdef JLMDEBUG 27 bprint("vmx_on %p %llx\n", ptr_to_vmcs_region, address); 28 #endif 29 __asm__ volatile( 30 "\tmovl $0, %[ret]\n" 31 "\tvmxon %[address]\n" 32 "\tjnc 1f\n" 33 "\tmovl $2, %[ret]\n" 34 "\tjmp 2f\n" 35 "1:\n" 36 "\tjnz 2f\n" 37 "\tmovl $1, %[ret]\n" 38 "2:\n" 39 : [ret]"=g" (ret) 40 :[address]"m" (address) 41 :); 42 return ret; 43 } 44 45 void vmx_off() { 46 #ifdef JLMDEBUG 47 bprint("vmx_off\n"); 48 #endif 49 __asm__ volatile( 50 "\tvmxoff\n" 51 :: :"cc"); 52 return; 53 } 54 55 56 int vmx_vmclear(UINT64* ptr_to_vmcs_region) { 57 int ret= 0; 58 UINT64 address= *ptr_to_vmcs_region; 59 #ifdef JLMDEBUG1 60 bprint("vmclear %p %llx\n", ptr_to_vmcs_region, address); 61 #endif 62 __asm__ volatile( 63 "\tmovl $0, %[ret]\n" 64 "\tvmclear %[address]\n" 65 "\tjnc 1f\n" 66 "\tmovl $2, %[ret]\n" 67 "\tjmp 2f\n" 68 "1:\n" 69 "\tjnz 2f\n" 70 "\tmovl $1, %[ret]\n" 71 "2:\n" 72 : [ret]"=g" (ret) 73 : [address]"m"(address) 74 :"memory"); 75 return ret; 76 } 77 78 int hw_vmx_flush_current_vmcs(UINT64 *address) { 79 return vmx_vmclear(address); 80 } 81 82 int vmx_vmlaunch() { 83 int ret= 0; 84 #ifdef JLMDEBUG 85 bprint("vmxlaunch\n"); 86 #endif 87 __asm__ volatile( 88 "\tmovl $0, %[ret]\n" 89 "\tvmlaunch\n" 90 "\tjnc 1f\n" 91 "\tmovl $2, %[ret]\n" 92 "\tjmp 2f\n" 93 "1:\n" 94 "\tjnz 2f\n" 95 "\tmovl $1, %[ret]\n" 96 "2:\n" 97 : [ret]"=g" (ret) 98 :: "memory"); 99 return ret; 100 } 101 102 int vmx_vmresume() { 103 int ret= 0; 104 #ifdef JLMDEBUG 105 bprint("vmresume\n"); 106 #endif 107 __asm__ volatile( 108 "\tmovl $0, %[ret]\n" 109 "\tvmresume\n" 110 "\tjnc 1f\n" 111 "\tmovl $2, %[ret]\n" 112 "\tjmp 2f\n" 113 "1:\n" 114 "\tjnz 2f\n" 115 "\tmovl $1, %[ret]\n" 116 "2:\n" 117 : [ret]"=g" (ret) 118 ::"cc", "memory"); 119 return ret; 120 } 121 122 123 int vmx_vmptrld(UINT64 *ptr_to_vmcs_region) { 124 int ret= 0; 125 UINT64 address= *ptr_to_vmcs_region; 126 #ifdef JLMDEBUG1 127 bprint("vmptrld %p %llx\n", ptr_to_vmcs_region, address); 128 #endif 129 __asm__ volatile( 130 "\tmovl $0, %[ret]\n" 131 "\tvmptrld %[address]\n" 132 "\tjnc 1f\n" 133 "\tmovl $2, %[ret]\n" 134 "\tjmp 2f\n" 135 "1:\n" 136 "\tjnz 2f\n" 137 "\tmovl $1, %[ret]\n" 138 "2:\n" 139 : [ret]"=g" (ret) 140 :[address] "m" (address) 141 :"memory"); 142 return ret; 143 } 144 145 void vmx_vmptrst(UINT64 *ptr_to_vmcs_region) { 146 UINT64 address= *ptr_to_vmcs_region; 147 #ifdef JLMDEBUG1 148 bprint("vmptrst %p %llx\n", ptr_to_vmcs_region, address); 149 #endif 150 __asm__ volatile( 151 "\tvmptrst %[address]\n" 152 ::[address] "m" (address) 153 :"memory"); 154 return; 155 } 156 157 158 int vmx_vmread(UINT64 index, UINT64 *value) { 159 int ret= 0; 160 #ifdef JLMDEBUG1 161 bprint("vmread, waiting %d, 0x%016lx\n", index, *value); 162 #endif 163 __asm__ volatile( 164 "\tmovq %[index], %%rax\n" 165 "\tmovl $0, %[ret]\n" 166 "\tvmread %%rax, %%rax\n" 167 "\tjnc 1f\n" 168 "\tmovl $2, %[ret]\n" 169 "\tjmp 3f\n" 170 "1:\n" 171 "\tjnz 2f\n" 172 "\tmovl $1, %[ret]\n" 173 "\tjmp 3f\n" 174 "2:\n" 175 "\tmovq %[value], %%rbx\n" 176 "\tmovq %%rax, (%%rbx)\n" 177 "3:\n" 178 : [ret]"=g" (ret) 179 : [value] "p"(value), [index] "g"(index) 180 :"%rax", "%rbx"); 181 #ifdef JLMDEBUG1 182 bprint("vmread, done 0x%016lx\n", *value); 183 #endif 184 return ret; 185 } 186 187 188 int vmx_vmwrite(UINT64 index, UINT64 value) { 189 int ret= 0; 190 #ifdef JLMDEBUG1 191 bprint("vmwrite, %p\n", value); 192 #endif 193 __asm__ volatile( 194 "\tmovq %[index], %%rax\n" 195 "\tmovq %[value], %%rbx\n" 196 "\tmovl $0, %[ret]\n" 197 // "\tvmwrite %%rax, %%rbx\n" 198 "\tvmwrite %%rbx, %%rax\n" 199 "\tjnc 1f\n" 200 "\tmovl $2, %[ret]\n" 201 "\tjmp 2f\n" 202 "1:\n" 203 "\tjnz 2f\n" 204 "\tmovl $1, %[ret]\n" 205 "2:\n" 206 : [ret] "=g" (ret) 207 : [index] "g"(index), [value] "g"(value) 208 :"%rbx", "%rax"); 209 #ifdef JLMDEBUG 210 if(ret!=0) 211 bprint("vmwrite failed\n"); 212 #endif 213 return ret; 214 } 215 216 217 int hw_vmx_write_current_vmcs(UINT64 field_id, UINT64 value) { 218 return vmx_vmwrite(field_id, value); 219 } 220 221 222 int hw_vmx_read_current_vmcs(UINT64 field_id, UINT64 *value) { 223 return vmx_vmread(field_id, value); 224 } 225