/* Is this a vmm specific thing? or generic? * * what do we do when we want to kill the vm? what are our other options? */ bool handle_vmexit(struct guest_thread *gth) { struct vm_trapframe *vm_tf = gth_to_vmtf(gth); switch (vm_tf->tf_exit_reason) { case EXIT_REASON_EPT_VIOLATION: return handle_ept_fault(gth); case EXIT_REASON_VMCALL: return handle_vmcall(gth); case EXIT_REASON_IO_INSTRUCTION: return handle_io(gth); case EXIT_REASON_MSR_WRITE: case EXIT_REASON_MSR_READ: return handle_msr(gth); case EXIT_REASON_APIC_ACCESS: return handle_apic_access(gth); case EXIT_REASON_HLT: return handle_halt(gth); case EXIT_REASON_MWAIT_INSTRUCTION: return handle_mwait(gth); case EXIT_REASON_EXTERNAL_INTERRUPT: case EXIT_REASON_APIC_WRITE: /* TODO: just ignore these? */ return TRUE; default: fprintf(stderr, "Don't know how to handle exit %d\n", vm_tf->tf_exit_reason); fprintf(stderr, "RIP %p, shutdown 0x%x\n", vm_tf->tf_rip, vm_tf->tf_exit_reason); return FALSE; } }
/* * System call handler * * retrieves system call number from user space * and invokes the requested method */ static void syscall_handler (struct intr_frame *f) { /* retrieve system call number and switch to corresponding method */ unsigned int syscall_number = *((unsigned int*) syscall_get_kernel_address(f->esp)); switch(syscall_number) { /* process system calls */ case SYS_HALT: handle_halt(f); break; case SYS_EXIT: handle_exit(f); break; case SYS_EXEC: handle_exec(f); break; case SYS_WAIT: handle_wait(f); break; /* file system calls */ case SYS_CREATE: handle_create(f); break; case SYS_REMOVE: handle_remove(f); break; case SYS_OPEN: handle_open(f); break; case SYS_FILESIZE: handle_filesize(f); break; case SYS_READ: handle_read(f); break; case SYS_WRITE: handle_write(f); break; case SYS_SEEK: handle_seek(f); break; case SYS_TELL: handle_tell(f); break; case SYS_CLOSE: handle_close(f); break; case SYS_CHDIR: handle_chdir(f); break; case SYS_MKDIR: handle_mkdir(f); break; case SYS_READDIR: handle_readdir(f); break; case SYS_ISDIR: handle_isdir(f); break; case SYS_INUMBER: handle_inumber(f); break; default: /* SYSCALL_ERROR: */ handle_no_such_syscall(f); break; } }
int kvm_run(kvm_context_t kvm, int vcpu) { int r; int fd = kvm->vcpu_fd[vcpu]; struct kvm_run *run = kvm->run[vcpu]; /*if (kvm_abi == 10) return kvm_run_abi10(kvm, vcpu);*/ again: // if (!kvm->irqchip_in_kernel) // run->request_interrupt_window = try_push_interrupts(kvm); //r = pre_kvm_run(kvm, vcpu); //if (r) // return r; r = ioctl(fd, KVM_RUN, 0); printf("here\n"); //post_kvm_run(kvm, vcpu); if (r == -1 && errno != EINTR && errno != EAGAIN) { r = -errno; printf("kvm_run: %m\n"); return r; } if (r == -1) { r = handle_io_window(kvm); goto more; } if (1) { switch (run->exit_reason) { case KVM_EXIT_UNKNOWN: fprintf(stderr, "unhandled vm exit: 0x%x\n", (unsigned)run->hw.hardware_exit_reason); kvm_show_regs(kvm, vcpu); abort(); break; case KVM_EXIT_FAIL_ENTRY: fprintf(stderr, "kvm_run: failed entry, reason %u\n", (unsigned)run->fail_entry.hardware_entry_failure_reason & 0xffff); return -ENOEXEC; break; case KVM_EXIT_EXCEPTION: fprintf(stderr, "exception %d (%x)\n", run->ex.exception, run->ex.error_code); kvm_show_regs(kvm, vcpu); kvm_show_code(kvm, vcpu); abort(); break; case KVM_EXIT_IO: r = handle_io(kvm, run, vcpu); break; case KVM_EXIT_DEBUG: r = handle_debug(kvm, vcpu); break; case KVM_EXIT_MMIO: r = handle_mmio(kvm, run); break; case KVM_EXIT_HLT: r = handle_halt(kvm, vcpu); break; case KVM_EXIT_IRQ_WINDOW_OPEN: break; case KVM_EXIT_SHUTDOWN: r = handle_shutdown(kvm, vcpu); break; case KVM_EXIT_SET_TPR: break; default: fprintf(stderr, "unhandled vm exit: 0x%x\n", run->exit_reason); kvm_show_regs(kvm, vcpu); abort(); break; } } more: if (!r) goto again; return r; }
int __cdecl kvm_run(kvm_context_t kvm, int vcpu) { int r = 0; int fd = kvm->vcpu_fd[vcpu]; struct kvm_run kvm_run; int retlen; BOOL ret = FALSE; kvm_run.emulated = 0; kvm_run.mmio_completed = 0; kvm_run.vcpu_fd = fd; again: kvm_run.request_interrupt_window = try_push_interrupts(kvm); pre_kvm_run(kvm, &kvm_run); /* r = ioctl(fd, KVM_RUN, &kvm_run); */ ret = DeviceIoControl( kvm->hnd, KVM_RUN, &kvm_run, sizeof(kvm_run), &kvm_run, sizeof(kvm_run), &retlen, NULL); if (retlen != sizeof(kvm_run)) { fprintf(stderr, "kvm_run: invalid return value\n"); return r; } post_kvm_run(kvm, &kvm_run); kvm_run.emulated = 0; kvm_run.mmio_completed = 0; if (!ret) { fprintf(stderr, "kvm_run: failed\n"); return -1; } if (kvm_run.ioctl_r == -1 && kvm_run._errno != EINTR) { r = -(kvm_run._errno); fprintf(stderr, "kvm_run: %d\n", kvm_run._errno); return r; } if (kvm_run.ioctl_r == -1) { r = handle_io_window(kvm, &kvm_run); goto more; } /* if (kvm_run.ioctl_r == -EINTR) { r = handle_io_window(kvm, &kvm_run); r = 1; goto more; } */ switch (kvm_run.exit_type) { case KVM_EXIT_TYPE_FAIL_ENTRY: fprintf(stderr, "kvm_run: failed entry, reason %u\n", kvm_run.exit_reason & 0xffff); return -ENOEXEC; break; case KVM_EXIT_TYPE_VM_EXIT: switch (kvm_run.exit_reason) { case KVM_EXIT_UNKNOWN: fprintf(stderr, "unhandled vm exit: 0x%x\n", kvm_run.hw.hardware_exit_reason); kvm_show_regs(kvm, vcpu); abort(); break; case KVM_EXIT_EXCEPTION: fprintf(stderr, "exception %d (%x)\n", kvm_run.ex.exception, kvm_run.ex.error_code); kvm_show_regs(kvm, vcpu); abort(); break; case KVM_EXIT_IO: r = handle_io(kvm, &kvm_run, vcpu); break; case KVM_EXIT_CPUID: r = handle_cpuid(kvm, &kvm_run, vcpu); break; case KVM_EXIT_DEBUG: r = handle_debug(kvm, &kvm_run, vcpu); break; case KVM_EXIT_MMIO: r = handle_mmio(kvm, &kvm_run); break; case KVM_EXIT_HLT: r = handle_halt(kvm, &kvm_run, vcpu); break; case KVM_EXIT_IRQ_WINDOW_OPEN: break; case KVM_EXIT_SHUTDOWN: r = handle_shutdown(kvm, &kvm_run, vcpu); break; default: fprintf(stderr, "unhandled vm exit: 0x%x\n", kvm_run.exit_reason); kvm_show_regs(kvm, vcpu); abort(); break; } } more: if (!r) goto again; return r; }