1 /* 2 * Copyright 2008 IBM Corporation 3 * 2008 Red Hat, Inc. 4 * Copyright 2011 Intel Corporation 5 * Copyright 2016 Veertu, Inc. 6 * Copyright 2017 The Android Open Source Project 7 * 8 * QEMU Hypervisor.framework support 9 * 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of version 2 of the GNU General Public 12 * License as published by the Free Software Foundation. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, see <http://www.gnu.org/licenses/>. 21 * 22 * This file contain code under public domain from the hvdos project: 23 * https://github.com/mist64/hvdos 24 * 25 * Parts Copyright (c) 2011 NetApp, Inc. 26 * All rights reserved. 27 * 28 * Redistribution and use in source and binary forms, with or without 29 * modification, are permitted provided that the following conditions 30 * are met: 31 * 1. Redistributions of source code must retain the above copyright 32 * notice, this list of conditions and the following disclaimer. 33 * 2. Redistributions in binary form must reproduce the above copyright 34 * notice, this list of conditions and the following disclaimer in the 35 * documentation and/or other materials provided with the distribution. 36 * 37 * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 38 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 39 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 40 * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 41 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 42 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 43 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 45 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 47 * SUCH DAMAGE. 48 */ 49 50 #include "qemu/osdep.h" 51 #include "qemu/error-report.h" 52 #include "qemu/main-loop.h" 53 #include "exec/address-spaces.h" 54 #include "exec/exec-all.h" 55 #include "sysemu/cpus.h" 56 #include "sysemu/hvf.h" 57 #include "sysemu/hvf_int.h" 58 #include "sysemu/runstate.h" 59 #include "qemu/guest-random.h" 60 61 HVFState *hvf_state; 62 63 #ifdef __aarch64__ 64 #define HV_VM_DEFAULT NULL 65 #endif 66 67 /* Memory slots */ 68 69 hvf_slot *hvf_find_overlap_slot(uint64_t start, uint64_t size) 70 { 71 hvf_slot *slot; 72 int x; 73 for (x = 0; x < hvf_state->num_slots; ++x) { 74 slot = &hvf_state->slots[x]; 75 if (slot->size && start < (slot->start + slot->size) && 76 (start + size) > slot->start) { 77 return slot; 78 } 79 } 80 return NULL; 81 } 82 83 struct mac_slot { 84 int present; 85 uint64_t size; 86 uint64_t gpa_start; 87 uint64_t gva; 88 }; 89 90 struct mac_slot mac_slots[32]; 91 92 static int do_hvf_set_memory(hvf_slot *slot, hv_memory_flags_t flags) 93 { 94 struct mac_slot *macslot; 95 hv_return_t ret; 96 97 macslot = &mac_slots[slot->slot_id]; 98 99 if (macslot->present) { 100 if (macslot->size != slot->size) { 101 macslot->present = 0; 102 ret = hv_vm_unmap(macslot->gpa_start, macslot->size); 103 assert_hvf_ok(ret); 104 } 105 } 106 107 if (!slot->size) { 108 return 0; 109 } 110 111 macslot->present = 1; 112 macslot->gpa_start = slot->start; 113 macslot->size = slot->size; 114 ret = hv_vm_map(slot->mem, slot->start, slot->size, flags); 115 assert_hvf_ok(ret); 116 return 0; 117 } 118 119 static void hvf_set_phys_mem(MemoryRegionSection *section, bool add) 120 { 121 hvf_slot *mem; 122 MemoryRegion *area = section->mr; 123 bool writeable = !area->readonly && !area->rom_device; 124 hv_memory_flags_t flags; 125 126 if (!memory_region_is_ram(area)) { 127 if (writeable) { 128 return; 129 } else if (!memory_region_is_romd(area)) { 130 /* 131 * If the memory device is not in romd_mode, then we actually want 132 * to remove the hvf memory slot so all accesses will trap. 133 */ 134 add = false; 135 } 136 } 137 138 mem = hvf_find_overlap_slot( 139 section->offset_within_address_space, 140 int128_get64(section->size)); 141 142 if (mem && add) { 143 if (mem->size == int128_get64(section->size) && 144 mem->start == section->offset_within_address_space && 145 mem->mem == (memory_region_get_ram_ptr(area) + 146 section->offset_within_region)) { 147 return; /* Same region was attempted to register, go away. */ 148 } 149 } 150 151 /* Region needs to be reset. set the size to 0 and remap it. */ 152 if (mem) { 153 mem->size = 0; 154 if (do_hvf_set_memory(mem, 0)) { 155 error_report("Failed to reset overlapping slot"); 156 abort(); 157 } 158 } 159 160 if (!add) { 161 return; 162 } 163 164 if (area->readonly || 165 (!memory_region_is_ram(area) && memory_region_is_romd(area))) { 166 flags = HV_MEMORY_READ | HV_MEMORY_EXEC; 167 } else { 168 flags = HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC; 169 } 170 171 /* Now make a new slot. */ 172 int x; 173 174 for (x = 0; x < hvf_state->num_slots; ++x) { 175 mem = &hvf_state->slots[x]; 176 if (!mem->size) { 177 break; 178 } 179 } 180 181 if (x == hvf_state->num_slots) { 182 error_report("No free slots"); 183 abort(); 184 } 185 186 mem->size = int128_get64(section->size); 187 mem->mem = memory_region_get_ram_ptr(area) + section->offset_within_region; 188 mem->start = section->offset_within_address_space; 189 mem->region = area; 190 191 if (do_hvf_set_memory(mem, flags)) { 192 error_report("Error registering new memory slot"); 193 abort(); 194 } 195 } 196 197 static void do_hvf_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg) 198 { 199 if (!cpu->vcpu_dirty) { 200 hvf_get_registers(cpu); 201 cpu->vcpu_dirty = true; 202 } 203 } 204 205 static void hvf_cpu_synchronize_state(CPUState *cpu) 206 { 207 if (!cpu->vcpu_dirty) { 208 run_on_cpu(cpu, do_hvf_cpu_synchronize_state, RUN_ON_CPU_NULL); 209 } 210 } 211 212 static void do_hvf_cpu_synchronize_set_dirty(CPUState *cpu, 213 run_on_cpu_data arg) 214 { 215 /* QEMU state is the reference, push it to HVF now and on next entry */ 216 cpu->vcpu_dirty = true; 217 } 218 219 static void hvf_cpu_synchronize_post_reset(CPUState *cpu) 220 { 221 run_on_cpu(cpu, do_hvf_cpu_synchronize_set_dirty, RUN_ON_CPU_NULL); 222 } 223 224 static void hvf_cpu_synchronize_post_init(CPUState *cpu) 225 { 226 run_on_cpu(cpu, do_hvf_cpu_synchronize_set_dirty, RUN_ON_CPU_NULL); 227 } 228 229 static void hvf_cpu_synchronize_pre_loadvm(CPUState *cpu) 230 { 231 run_on_cpu(cpu, do_hvf_cpu_synchronize_set_dirty, RUN_ON_CPU_NULL); 232 } 233 234 static void hvf_set_dirty_tracking(MemoryRegionSection *section, bool on) 235 { 236 hvf_slot *slot; 237 238 slot = hvf_find_overlap_slot( 239 section->offset_within_address_space, 240 int128_get64(section->size)); 241 242 /* protect region against writes; begin tracking it */ 243 if (on) { 244 slot->flags |= HVF_SLOT_LOG; 245 hv_vm_protect((uintptr_t)slot->start, (size_t)slot->size, 246 HV_MEMORY_READ | HV_MEMORY_EXEC); 247 /* stop tracking region*/ 248 } else { 249 slot->flags &= ~HVF_SLOT_LOG; 250 hv_vm_protect((uintptr_t)slot->start, (size_t)slot->size, 251 HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC); 252 } 253 } 254 255 static void hvf_log_start(MemoryListener *listener, 256 MemoryRegionSection *section, int old, int new) 257 { 258 if (old != 0) { 259 return; 260 } 261 262 hvf_set_dirty_tracking(section, 1); 263 } 264 265 static void hvf_log_stop(MemoryListener *listener, 266 MemoryRegionSection *section, int old, int new) 267 { 268 if (new != 0) { 269 return; 270 } 271 272 hvf_set_dirty_tracking(section, 0); 273 } 274 275 static void hvf_log_sync(MemoryListener *listener, 276 MemoryRegionSection *section) 277 { 278 /* 279 * sync of dirty pages is handled elsewhere; just make sure we keep 280 * tracking the region. 281 */ 282 hvf_set_dirty_tracking(section, 1); 283 } 284 285 static void hvf_region_add(MemoryListener *listener, 286 MemoryRegionSection *section) 287 { 288 hvf_set_phys_mem(section, true); 289 } 290 291 static void hvf_region_del(MemoryListener *listener, 292 MemoryRegionSection *section) 293 { 294 hvf_set_phys_mem(section, false); 295 } 296 297 static MemoryListener hvf_memory_listener = { 298 .name = "hvf", 299 .priority = 10, 300 .region_add = hvf_region_add, 301 .region_del = hvf_region_del, 302 .log_start = hvf_log_start, 303 .log_stop = hvf_log_stop, 304 .log_sync = hvf_log_sync, 305 }; 306 307 static void dummy_signal(int sig) 308 { 309 } 310 311 bool hvf_allowed; 312 313 static int hvf_accel_init(MachineState *ms) 314 { 315 int x; 316 hv_return_t ret; 317 HVFState *s; 318 319 ret = hv_vm_create(HV_VM_DEFAULT); 320 assert_hvf_ok(ret); 321 322 s = g_new0(HVFState, 1); 323 324 s->num_slots = 32; 325 for (x = 0; x < s->num_slots; ++x) { 326 s->slots[x].size = 0; 327 s->slots[x].slot_id = x; 328 } 329 330 hvf_state = s; 331 memory_listener_register(&hvf_memory_listener, &address_space_memory); 332 333 return hvf_arch_init(); 334 } 335 336 static void hvf_accel_class_init(ObjectClass *oc, void *data) 337 { 338 AccelClass *ac = ACCEL_CLASS(oc); 339 ac->name = "HVF"; 340 ac->init_machine = hvf_accel_init; 341 ac->allowed = &hvf_allowed; 342 } 343 344 static const TypeInfo hvf_accel_type = { 345 .name = TYPE_HVF_ACCEL, 346 .parent = TYPE_ACCEL, 347 .class_init = hvf_accel_class_init, 348 }; 349 350 static void hvf_type_init(void) 351 { 352 type_register_static(&hvf_accel_type); 353 } 354 355 type_init(hvf_type_init); 356 357 static void hvf_vcpu_destroy(CPUState *cpu) 358 { 359 hv_return_t ret = hv_vcpu_destroy(cpu->hvf->fd); 360 assert_hvf_ok(ret); 361 362 hvf_arch_vcpu_destroy(cpu); 363 g_free(cpu->hvf); 364 cpu->hvf = NULL; 365 } 366 367 static int hvf_init_vcpu(CPUState *cpu) 368 { 369 int r; 370 371 cpu->hvf = g_malloc0(sizeof(*cpu->hvf)); 372 373 /* init cpu signals */ 374 struct sigaction sigact; 375 376 memset(&sigact, 0, sizeof(sigact)); 377 sigact.sa_handler = dummy_signal; 378 sigaction(SIG_IPI, &sigact, NULL); 379 380 pthread_sigmask(SIG_BLOCK, NULL, &cpu->hvf->unblock_ipi_mask); 381 sigdelset(&cpu->hvf->unblock_ipi_mask, SIG_IPI); 382 383 #ifdef __aarch64__ 384 r = hv_vcpu_create(&cpu->hvf->fd, (hv_vcpu_exit_t **)&cpu->hvf->exit, NULL); 385 #else 386 r = hv_vcpu_create((hv_vcpuid_t *)&cpu->hvf->fd, HV_VCPU_DEFAULT); 387 #endif 388 cpu->vcpu_dirty = 1; 389 assert_hvf_ok(r); 390 391 return hvf_arch_init_vcpu(cpu); 392 } 393 394 /* 395 * The HVF-specific vCPU thread function. This one should only run when the host 396 * CPU supports the VMX "unrestricted guest" feature. 397 */ 398 static void *hvf_cpu_thread_fn(void *arg) 399 { 400 CPUState *cpu = arg; 401 402 int r; 403 404 assert(hvf_enabled()); 405 406 rcu_register_thread(); 407 408 qemu_mutex_lock_iothread(); 409 qemu_thread_get_self(cpu->thread); 410 411 cpu->thread_id = qemu_get_thread_id(); 412 cpu->can_do_io = 1; 413 current_cpu = cpu; 414 415 hvf_init_vcpu(cpu); 416 417 /* signal CPU creation */ 418 cpu_thread_signal_created(cpu); 419 qemu_guest_random_seed_thread_part2(cpu->random_seed); 420 421 do { 422 if (cpu_can_run(cpu)) { 423 r = hvf_vcpu_exec(cpu); 424 if (r == EXCP_DEBUG) { 425 cpu_handle_guest_debug(cpu); 426 } 427 } 428 qemu_wait_io_event(cpu); 429 } while (!cpu->unplug || cpu_can_run(cpu)); 430 431 hvf_vcpu_destroy(cpu); 432 cpu_thread_signal_destroyed(cpu); 433 qemu_mutex_unlock_iothread(); 434 rcu_unregister_thread(); 435 return NULL; 436 } 437 438 static void hvf_start_vcpu_thread(CPUState *cpu) 439 { 440 char thread_name[VCPU_THREAD_NAME_SIZE]; 441 442 /* 443 * HVF currently does not support TCG, and only runs in 444 * unrestricted-guest mode. 445 */ 446 assert(hvf_enabled()); 447 448 cpu->thread = g_malloc0(sizeof(QemuThread)); 449 cpu->halt_cond = g_malloc0(sizeof(QemuCond)); 450 qemu_cond_init(cpu->halt_cond); 451 452 snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/HVF", 453 cpu->cpu_index); 454 qemu_thread_create(cpu->thread, thread_name, hvf_cpu_thread_fn, 455 cpu, QEMU_THREAD_JOINABLE); 456 } 457 458 static void hvf_accel_ops_class_init(ObjectClass *oc, void *data) 459 { 460 AccelOpsClass *ops = ACCEL_OPS_CLASS(oc); 461 462 ops->create_vcpu_thread = hvf_start_vcpu_thread; 463 ops->kick_vcpu_thread = hvf_kick_vcpu_thread; 464 465 ops->synchronize_post_reset = hvf_cpu_synchronize_post_reset; 466 ops->synchronize_post_init = hvf_cpu_synchronize_post_init; 467 ops->synchronize_state = hvf_cpu_synchronize_state; 468 ops->synchronize_pre_loadvm = hvf_cpu_synchronize_pre_loadvm; 469 }; 470 static const TypeInfo hvf_accel_ops_type = { 471 .name = ACCEL_OPS_NAME("hvf"), 472 473 .parent = TYPE_ACCEL_OPS, 474 .class_init = hvf_accel_ops_class_init, 475 .abstract = true, 476 }; 477 static void hvf_accel_ops_register_types(void) 478 { 479 type_register_static(&hvf_accel_ops_type); 480 } 481 type_init(hvf_accel_ops_register_types); 482