1 #include "kvm/kvm-cpu.h" 2 3 #include "kvm/symbol.h" 4 #include "kvm/util.h" 5 #include "kvm/kvm.h" 6 7 #include <sys/ioctl.h> 8 #include <sys/mman.h> 9 #include <signal.h> 10 #include <stdlib.h> 11 #include <string.h> 12 #include <errno.h> 13 #include <stdio.h> 14 15 extern struct kvm_cpu *kvm_cpus[KVM_NR_CPUS]; 16 extern __thread struct kvm_cpu *current_kvm_cpu; 17 18 void kvm_cpu__enable_singlestep(struct kvm_cpu *vcpu) 19 { 20 struct kvm_guest_debug debug = { 21 .control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP, 22 }; 23 24 if (ioctl(vcpu->vcpu_fd, KVM_SET_GUEST_DEBUG, &debug) < 0) 25 pr_warning("KVM_SET_GUEST_DEBUG failed"); 26 } 27 28 void kvm_cpu__run(struct kvm_cpu *vcpu) 29 { 30 int err; 31 32 err = ioctl(vcpu->vcpu_fd, KVM_RUN, 0); 33 if (err < 0 && (errno != EINTR && errno != EAGAIN)) 34 die_perror("KVM_RUN failed"); 35 } 36 37 static void kvm_cpu_signal_handler(int signum) 38 { 39 if (signum == SIGKVMEXIT) { 40 if (current_kvm_cpu && current_kvm_cpu->is_running) { 41 current_kvm_cpu->is_running = false; 42 pthread_kill(pthread_self(), SIGKVMEXIT); 43 } 44 } else if (signum == SIGKVMPAUSE) { 45 current_kvm_cpu->paused = 1; 46 } 47 } 48 49 static void kvm_cpu__handle_coalesced_mmio(struct kvm_cpu *cpu) 50 { 51 if (cpu->ring) { 52 while (cpu->ring->first != cpu->ring->last) { 53 struct kvm_coalesced_mmio *m; 54 m = &cpu->ring->coalesced_mmio[cpu->ring->first]; 55 kvm__emulate_mmio(cpu->kvm, 56 m->phys_addr, 57 m->data, 58 m->len, 59 1); 60 cpu->ring->first = (cpu->ring->first + 1) % KVM_COALESCED_MMIO_MAX; 61 } 62 } 63 } 64 65 void kvm_cpu__reboot(void) 66 { 67 int i; 68 69 for (i = 0; i < KVM_NR_CPUS; i++) 70 if (kvm_cpus[i]) 71 pthread_kill(kvm_cpus[i]->thread, SIGKVMEXIT); 72 } 73 74 int kvm_cpu__start(struct kvm_cpu *cpu) 75 { 76 sigset_t sigset; 77 78 sigemptyset(&sigset); 79 sigaddset(&sigset, SIGALRM); 80 81 pthread_sigmask(SIG_BLOCK, &sigset, NULL); 82 83 signal(SIGKVMEXIT, kvm_cpu_signal_handler); 84 signal(SIGKVMPAUSE, kvm_cpu_signal_handler); 85 86 kvm_cpu__reset_vcpu(cpu); 87 88 if (cpu->kvm->single_step) 89 kvm_cpu__enable_singlestep(cpu); 90 91 while (cpu->is_running) { 92 if (cpu->paused) { 93 kvm__notify_paused(); 94 cpu->paused = 0; 95 } 96 97 if (cpu->needs_nmi) { 98 kvm_cpu__arch_nmi(cpu); 99 cpu->needs_nmi = 0; 100 } 101 102 kvm_cpu__run(cpu); 103 104 switch (cpu->kvm_run->exit_reason) { 105 case KVM_EXIT_UNKNOWN: 106 break; 107 case KVM_EXIT_DEBUG: 108 kvm_cpu__show_registers(cpu); 109 kvm_cpu__show_code(cpu); 110 break; 111 case KVM_EXIT_IO: { 112 bool ret; 113 114 ret = kvm__emulate_io(cpu->kvm, 115 cpu->kvm_run->io.port, 116 (u8 *)cpu->kvm_run + 117 cpu->kvm_run->io.data_offset, 118 cpu->kvm_run->io.direction, 119 cpu->kvm_run->io.size, 120 cpu->kvm_run->io.count); 121 122 if (!ret) 123 goto panic_kvm; 124 break; 125 } 126 case KVM_EXIT_MMIO: { 127 bool ret; 128 129 ret = kvm__emulate_mmio(cpu->kvm, 130 cpu->kvm_run->mmio.phys_addr, 131 cpu->kvm_run->mmio.data, 132 cpu->kvm_run->mmio.len, 133 cpu->kvm_run->mmio.is_write); 134 135 if (!ret) 136 goto panic_kvm; 137 break; 138 } 139 case KVM_EXIT_INTR: 140 if (cpu->is_running) 141 break; 142 goto exit_kvm; 143 case KVM_EXIT_SHUTDOWN: 144 goto exit_kvm; 145 default: { 146 bool ret; 147 148 ret = kvm_cpu__handle_exit(cpu); 149 if (!ret) 150 goto panic_kvm; 151 break; 152 } 153 } 154 kvm_cpu__handle_coalesced_mmio(cpu); 155 } 156 157 exit_kvm: 158 return 0; 159 160 panic_kvm: 161 return 1; 162 } 163