1 /* 2 ** Copyright (c) 2011, Intel Corporation 3 ** 4 ** This software is licensed under the terms of the GNU General Public 5 ** License version 2, as published by the Free Software Foundation, and 6 ** may be copied, distributed, and modified under those terms. 7 ** 8 ** This program is distributed in the hope that it will be useful, 9 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 10 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 ** GNU General Public License for more details. 12 */ 13 14 #include "target-i386/hax-i386.h" 15 16 /* 17 * return 0 upon success, -1 when the driver is not loaded, 18 * other negative value for other failures 19 */ 20 static int hax_open_device(hax_fd *fd) 21 { 22 uint32_t errNum = 0; 23 HANDLE hDevice; 24 25 if (!fd) 26 return -2; 27 28 hDevice = CreateFile( "\\\\.\\HAX", 29 GENERIC_READ | GENERIC_WRITE, 30 0, 31 NULL, 32 CREATE_ALWAYS, 33 FILE_ATTRIBUTE_NORMAL, 34 NULL); 35 36 if (hDevice == INVALID_HANDLE_VALUE) 37 { 38 dprint("Failed to open the HAX device!\n"); 39 errNum = GetLastError(); 40 if (errNum == ERROR_FILE_NOT_FOUND) 41 return -1; 42 return -2; 43 } 44 *fd = hDevice; 45 dprint("device fd:%d\n", *fd); 46 return 0; 47 } 48 49 50 hax_fd hax_mod_open(void) 51 { 52 int ret; 53 hax_fd fd = INVALID_HANDLE_VALUE; 54 55 ret = hax_open_device(&fd); 56 if (ret != 0) { 57 dprint("Open HAX device failed\n"); 58 return INVALID_HANDLE_VALUE; 59 } 60 61 return fd; 62 } 63 64 int hax_populate_ram(uint64_t va, uint32_t size) 65 { 66 int ret; 67 struct hax_alloc_ram_info info; 68 HANDLE hDeviceVM; 69 DWORD dSize = 0; 70 71 if (!hax_global.vm || !hax_global.vm->fd) 72 { 73 dprint("Allocate memory before vm create?\n"); 74 return -EINVAL; 75 } 76 77 info.size = size; 78 info.va = va; 79 80 hDeviceVM = hax_global.vm->fd; 81 82 ret = DeviceIoControl(hDeviceVM, 83 HAX_VM_IOCTL_ALLOC_RAM, 84 &info, sizeof(info), 85 NULL, 0, 86 &dSize, 87 (LPOVERLAPPED) NULL); 88 89 if (!ret) { 90 dprint("HAX: Failed to allocate %x memory (address %llx)\n", 91 size, (unsigned long long)va); 92 return -1; 93 } 94 95 return 0; 96 } 97 98 99 int hax_set_phys_mem(hwaddr start_addr, ram_addr_t size, ram_addr_t phys_offset) 100 { 101 struct hax_set_ram_info info, *pinfo = &info; 102 ram_addr_t flags = phys_offset & ~TARGET_PAGE_MASK; 103 HANDLE hDeviceVM; 104 DWORD dSize = 0; 105 int ret = 0; 106 107 /* We look for the RAM and ROM only */ 108 if (flags >= IO_MEM_UNASSIGNED) 109 return 0; 110 111 if ( (start_addr & ~TARGET_PAGE_MASK) || (size & ~TARGET_PAGE_MASK)) 112 { 113 dprint( 114 "set_phys_mem %x %lx requires page aligned addr and size\n", 115 start_addr, size); 116 return -1; 117 } 118 119 info.pa_start = start_addr; 120 info.size = size; 121 info.va = (uint64_t)(uintptr_t)qemu_get_ram_ptr(phys_offset); 122 info.flags = (flags & IO_MEM_ROM) ? 1 : 0; 123 124 hDeviceVM = hax_global.vm->fd; 125 126 ret = DeviceIoControl(hDeviceVM, 127 HAX_VM_IOCTL_SET_RAM, 128 pinfo, sizeof(*pinfo), 129 NULL, 0, 130 &dSize, 131 (LPOVERLAPPED) NULL); 132 133 if (!ret) 134 return -EFAULT; 135 else 136 return 0; 137 } 138 139 int hax_capability(struct hax_state *hax, struct hax_capabilityinfo *cap) 140 { 141 int ret; 142 HANDLE hDevice = hax->fd; //handle to hax module 143 DWORD dSize = 0; 144 DWORD err = 0; 145 146 if (hax_invalid_fd(hDevice)) { 147 dprint("Invalid fd for hax device!\n"); 148 return -ENODEV; 149 } 150 151 ret = DeviceIoControl(hDevice, 152 HAX_IOCTL_CAPABILITY, 153 NULL, 0, 154 cap, sizeof(*cap), 155 &dSize, 156 (LPOVERLAPPED) NULL); 157 158 if (!ret) { 159 err = GetLastError(); 160 if (err == ERROR_INSUFFICIENT_BUFFER || 161 err == ERROR_MORE_DATA) 162 dprint("hax capability is too long to hold.\n"); 163 dprint("Failed to get Hax capability:%d\n", err); 164 return -EFAULT; 165 } else 166 return 0; 167 } 168 169 int hax_mod_version(struct hax_state *hax, struct hax_module_version *version) 170 { 171 int ret; 172 HANDLE hDevice = hax->fd; //handle to hax module 173 DWORD dSize = 0; 174 DWORD err = 0; 175 176 if (hax_invalid_fd(hDevice)) { 177 dprint("Invalid fd for hax device!\n"); 178 return -ENODEV; 179 } 180 181 ret = DeviceIoControl(hDevice, 182 HAX_IOCTL_VERSION, 183 NULL, 0, 184 version, sizeof(*version), 185 &dSize, 186 (LPOVERLAPPED) NULL); 187 188 if (!ret) { 189 err = GetLastError(); 190 if (err == ERROR_INSUFFICIENT_BUFFER || 191 err == ERROR_MORE_DATA) 192 dprint("HAX module is too large.\n"); 193 dprint("Failed to get Hax module version:%d\n", err); 194 return -EFAULT; 195 } else 196 return 0; 197 } 198 199 static char *hax_vm_devfs_string(int vm_id) 200 { 201 char *name; 202 203 if (vm_id > MAX_VM_ID) 204 { 205 dprint("Too big VM id\n"); 206 return NULL; 207 } 208 209 name = g_strdup("\\\\.\\hax_vmxx"); 210 if (!name) 211 return NULL; 212 sprintf(name, "\\\\.\\hax_vm%02d", vm_id); 213 214 return name; 215 } 216 217 static char *hax_vcpu_devfs_string(int vm_id, int vcpu_id) 218 { 219 char *name; 220 221 if (vm_id > MAX_VM_ID || vcpu_id > MAX_VCPU_ID) 222 { 223 dprint("Too big vm id %x or vcpu id %x\n", vm_id, vcpu_id); 224 return NULL; 225 } 226 name = g_strdup("\\\\.\\hax_vmxx_vcpuxx"); 227 if (!name) 228 return NULL; 229 sprintf(name, "\\\\.\\hax_vm%02d_vcpu%02d", vm_id, vcpu_id); 230 231 return name; 232 } 233 234 int hax_host_create_vm(struct hax_state *hax, int *vmid) 235 { 236 int ret; 237 int vm_id = 0; 238 DWORD dSize = 0; 239 240 if (hax_invalid_fd(hax->fd)) 241 return -EINVAL; 242 243 if (hax->vm) 244 return 0; 245 246 ret = DeviceIoControl(hax->fd, 247 HAX_IOCTL_CREATE_VM, 248 NULL, 0, 249 &vm_id, sizeof(vm_id), 250 &dSize, 251 (LPOVERLAPPED) NULL); 252 if (!ret) { 253 dprint("error code:%d", GetLastError()); 254 return -1; 255 } 256 *vmid = vm_id; 257 return 0; 258 } 259 260 hax_fd hax_host_open_vm(struct hax_state *hax, int vm_id) 261 { 262 char *vm_name = NULL; 263 hax_fd hDeviceVM; 264 265 vm_name = hax_vm_devfs_string(vm_id); 266 if (!vm_name) { 267 dprint("Incorrect name\n"); 268 return INVALID_HANDLE_VALUE; 269 } 270 271 hDeviceVM = CreateFile(vm_name, 272 GENERIC_READ | GENERIC_WRITE, 273 0, 274 NULL, 275 CREATE_ALWAYS, 276 FILE_ATTRIBUTE_NORMAL, 277 NULL); 278 if (hDeviceVM == INVALID_HANDLE_VALUE) 279 dprint("Open the vm devcie error:%s, ec:%d\n", vm_name, GetLastError()); 280 281 g_free(vm_name); 282 return hDeviceVM; 283 } 284 285 int hax_notify_qemu_version(hax_fd vm_fd, struct hax_qemu_version *qversion) 286 { 287 int ret; 288 DWORD dSize = 0; 289 290 if (hax_invalid_fd(vm_fd)) 291 return -EINVAL; 292 293 ret = DeviceIoControl(vm_fd, 294 HAX_VM_IOCTL_NOTIFY_QEMU_VERSION, 295 qversion, sizeof(struct hax_qemu_version), 296 NULL, 0, 297 &dSize, 298 (LPOVERLAPPED) NULL); 299 if (!ret) 300 { 301 dprint("Failed to notify qemu API version\n"); 302 return -1; 303 } 304 305 return 0; 306 } 307 308 int hax_host_create_vcpu(hax_fd vm_fd, int vcpuid) 309 { 310 int ret; 311 DWORD dSize = 0; 312 313 ret = DeviceIoControl(vm_fd, 314 HAX_VM_IOCTL_VCPU_CREATE, 315 &vcpuid, sizeof(vcpuid), 316 NULL, 0, 317 &dSize, 318 (LPOVERLAPPED) NULL); 319 if (!ret) 320 { 321 dprint("Failed to create vcpu %x\n", vcpuid); 322 return -1; 323 } 324 325 return 0; 326 } 327 328 hax_fd hax_host_open_vcpu(int vmid, int vcpuid) 329 { 330 char *devfs_path = NULL; 331 hax_fd hDeviceVCPU; 332 333 devfs_path = hax_vcpu_devfs_string(vmid, vcpuid); 334 if (!devfs_path) 335 { 336 dprint("Failed to get the devfs\n"); 337 return INVALID_HANDLE_VALUE; 338 } 339 340 hDeviceVCPU = CreateFile( devfs_path, 341 GENERIC_READ | GENERIC_WRITE, 342 0, 343 NULL, 344 CREATE_ALWAYS, 345 FILE_ATTRIBUTE_NORMAL, 346 NULL); 347 348 if (hDeviceVCPU == INVALID_HANDLE_VALUE) 349 dprint("Failed to open the vcpu devfs\n"); 350 g_free(devfs_path); 351 return hDeviceVCPU; 352 } 353 354 int hax_host_setup_vcpu_channel(struct hax_vcpu_state *vcpu) 355 { 356 hax_fd hDeviceVCPU = vcpu->fd; 357 int ret; 358 struct hax_tunnel_info info; 359 DWORD dSize = 0; 360 361 ret = DeviceIoControl(hDeviceVCPU, 362 HAX_VCPU_IOCTL_SETUP_TUNNEL, 363 NULL, 0, 364 &info, sizeof(info), 365 &dSize, 366 (LPOVERLAPPED) NULL); 367 if (!ret) 368 { 369 dprint("Failed to setup the hax tunnel\n"); 370 return -1; 371 } 372 373 if (!valid_hax_tunnel_size(info.size)) 374 { 375 dprint("Invalid hax tunnel size %x\n", info.size); 376 ret = -EINVAL; 377 return ret; 378 } 379 vcpu->tunnel = (struct hax_tunnel *)(uintptr_t)(info.va); 380 vcpu->iobuf = (unsigned char *)(uintptr_t)(info.io_va); 381 return 0; 382 } 383 384 int hax_vcpu_run(struct hax_vcpu_state* vcpu) 385 { 386 int ret; 387 HANDLE hDeviceVCPU = vcpu->fd; 388 DWORD dSize = 0; 389 390 ret = DeviceIoControl(hDeviceVCPU, 391 HAX_VCPU_IOCTL_RUN, 392 NULL, 0, 393 NULL, 0, 394 &dSize, 395 (LPOVERLAPPED) NULL); 396 if (!ret) 397 return -EFAULT; 398 else 399 return 0; 400 } 401 402 int hax_sync_fpu(CPUState *cpu, struct fx_layout *fl, int set) 403 { 404 int ret; 405 hax_fd fd; 406 HANDLE hDeviceVCPU; 407 DWORD dSize = 0; 408 409 fd = hax_vcpu_get_fd(cpu); 410 if (hax_invalid_fd(fd)) 411 return -1; 412 413 hDeviceVCPU = fd; 414 415 if (set) 416 ret = DeviceIoControl(hDeviceVCPU, 417 HAX_VCPU_IOCTL_SET_FPU, 418 fl, sizeof(*fl), 419 NULL, 0, 420 &dSize, 421 (LPOVERLAPPED) NULL); 422 else 423 ret = DeviceIoControl(hDeviceVCPU, 424 HAX_VCPU_IOCTL_GET_FPU, 425 NULL, 0, 426 fl, sizeof(*fl), 427 &dSize, 428 (LPOVERLAPPED) NULL); 429 if (!ret) 430 return -EFAULT; 431 else 432 return 0; 433 } 434 435 int hax_sync_msr(CPUState *cpu, struct hax_msr_data *msrs, int set) 436 { 437 int ret; 438 hax_fd fd; 439 HANDLE hDeviceVCPU; 440 DWORD dSize = 0; 441 442 fd = hax_vcpu_get_fd(cpu); 443 if (hax_invalid_fd(fd)) 444 return -1; 445 hDeviceVCPU = fd; 446 447 if (set) 448 ret = DeviceIoControl(hDeviceVCPU, 449 HAX_VCPU_IOCTL_SET_MSRS, 450 msrs, sizeof(*msrs), 451 msrs, sizeof(*msrs), 452 &dSize, 453 (LPOVERLAPPED) NULL); 454 else 455 ret = DeviceIoControl(hDeviceVCPU, 456 HAX_VCPU_IOCTL_GET_MSRS, 457 msrs, sizeof(*msrs), 458 msrs, sizeof(*msrs), 459 &dSize, 460 (LPOVERLAPPED) NULL); 461 if (!ret) 462 return -EFAULT; 463 else 464 return 0; 465 } 466 467 int hax_sync_vcpu_state(CPUState *cpu, struct vcpu_state_t *state, int set) 468 { 469 int ret; 470 hax_fd fd; 471 HANDLE hDeviceVCPU; 472 DWORD dSize; 473 474 fd = hax_vcpu_get_fd(cpu); 475 if (hax_invalid_fd(fd)) 476 return -1; 477 478 hDeviceVCPU = fd; 479 480 if (set) 481 ret = DeviceIoControl(hDeviceVCPU, 482 HAX_VCPU_SET_REGS, 483 state, sizeof(*state), 484 NULL, 0, 485 &dSize, 486 (LPOVERLAPPED) NULL); 487 else 488 ret = DeviceIoControl(hDeviceVCPU, 489 HAX_VCPU_GET_REGS, 490 NULL, 0, 491 state, sizeof(*state), 492 &dSize, 493 (LPOVERLAPPED) NULL); 494 if (!ret) 495 return -EFAULT; 496 else 497 return 0; 498 } 499 500 int hax_inject_interrupt(CPUState *cpu, int vector) 501 { 502 int ret; 503 hax_fd fd; 504 HANDLE hDeviceVCPU; 505 DWORD dSize; 506 507 fd = hax_vcpu_get_fd(cpu); 508 if (hax_invalid_fd(fd)) 509 return -1; 510 511 hDeviceVCPU = fd; 512 513 ret = DeviceIoControl(hDeviceVCPU, 514 HAX_VCPU_IOCTL_INTERRUPT, 515 &vector, sizeof(vector), 516 NULL, 0, 517 &dSize, 518 (LPOVERLAPPED) NULL); 519 if (!ret) 520 return -EFAULT; 521 else 522 return 0; 523 } 524