# HG changeset patch # User Jerone Young <[EMAIL PROTECTED]> # Date 1194027873 18000 # Node ID 0ade452df6c708a2b44696a23e733d59c8906aea # Parent 01b86b564fb9e751295ff8eddf5f38cfb24e1e34 Move abi 10 functions to libkvm-x86.c
Move handle_io_abi_10 to libkvm-x86.c Move handle_mmio_abi10 to libkvm-x86.c Move kvm_run_abi10 to libkvm-x86.c Move kvm_show_code to libkvm-x86.c Signed-off-by: Jerone Young <[EMAIL PROTECTED]> diff --git a/libkvm/kvm-x86.h b/libkvm/kvm-x86.h --- a/libkvm/kvm-x86.h +++ b/libkvm/kvm-x86.h @@ -38,4 +38,8 @@ void *kvm_create_kernel_phys_mem(kvm_con void *kvm_create_kernel_phys_mem(kvm_context_t kvm, unsigned long phys_start, unsigned long len, int log, int writable); +int kvm_run_abi10(kvm_context_t kvm, int vcpu); + +void kvm_show_code(kvm_context_t kvm, int vcpu); + #endif diff --git a/libkvm/libkvm-x86.c b/libkvm/libkvm-x86.c --- a/libkvm/libkvm-x86.c +++ b/libkvm/libkvm-x86.c @@ -1,5 +1,6 @@ #include "libkvm.h" #include "kvm-x86.h" +#include "kvm-abi-10.h" #include <errno.h> #include <sys/ioctl.h> #include <string.h> @@ -11,6 +12,7 @@ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> +#include <stdlib.h> int kvm_alloc_kernel_memory(kvm_context_t kvm, unsigned long memory, void **vm_mem) @@ -407,4 +409,224 @@ int kvm_set_lapic(kvm_context_t kvm, int #endif - +static int handle_io_abi10(kvm_context_t kvm, struct kvm_run_abi10 *run, + int vcpu) +{ + uint16_t addr = run->io.port; + int r; + int i; + void *p = (void *)run + run->io.data_offset; + + for (i = 0; i < run->io.count; ++i) { + switch (run->io.direction) { + case KVM_EXIT_IO_IN: + switch (run->io.size) { + case 1: + r = kvm->callbacks->inb(kvm->opaque, addr, p); + break; + case 2: + r = kvm->callbacks->inw(kvm->opaque, addr, p); + break; + case 4: + r = kvm->callbacks->inl(kvm->opaque, addr, p); + break; + default: + fprintf(stderr, "bad I/O size %d\n", run->io.size); + return -EMSGSIZE; + } + break; + case KVM_EXIT_IO_OUT: + switch (run->io.size) { + case 1: + r = kvm->callbacks->outb(kvm->opaque, addr, + *(uint8_t *)p); + break; + case 2: + r = kvm->callbacks->outw(kvm->opaque, addr, + *(uint16_t *)p); + break; + case 4: + r = kvm->callbacks->outl(kvm->opaque, addr, + *(uint32_t *)p); + break; + default: + fprintf(stderr, "bad I/O size %d\n", run->io.size); + return -EMSGSIZE; + } + break; + default: + fprintf(stderr, "bad I/O direction %d\n", run->io.direction); + return -EPROTO; + } + + p += run->io.size; + } + run->io_completed = 1; + + return 0; +} + +static int handle_mmio_abi10(kvm_context_t kvm, struct kvm_run_abi10 *kvm_run) +{ + unsigned long addr = kvm_run->mmio.phys_addr; + void *data = kvm_run->mmio.data; + int r = -1; + + if (kvm_run->mmio.is_write) { + switch (kvm_run->mmio.len) { + case 1: + r = kvm->callbacks->writeb(kvm->opaque, addr, + *(uint8_t *)data); + break; + case 2: + r = kvm->callbacks->writew(kvm->opaque, addr, + *(uint16_t *)data); + break; + case 4: + r = kvm->callbacks->writel(kvm->opaque, addr, + *(uint32_t *)data); + break; + case 8: + r = kvm->callbacks->writeq(kvm->opaque, addr, + *(uint64_t *)data); + break; + } + } else { + switch (kvm_run->mmio.len) { + case 1: + r = kvm->callbacks->readb(kvm->opaque, addr, + (uint8_t *)data); + break; + case 2: + r = kvm->callbacks->readw(kvm->opaque, addr, + (uint16_t *)data); + break; + case 4: + r = kvm->callbacks->readl(kvm->opaque, addr, + (uint32_t *)data); + break; + case 8: + r = kvm->callbacks->readq(kvm->opaque, addr, + (uint64_t *)data); + break; + } + kvm_run->io_completed = 1; + } + return r; +} + +int kvm_run_abi10(kvm_context_t kvm, int vcpu) +{ + int r; + int fd = kvm->vcpu_fd[vcpu]; + struct kvm_run_abi10 *run = (struct kvm_run_abi10 *)kvm->run[vcpu]; + +again: + run->request_interrupt_window = try_push_interrupts(kvm); + r = pre_kvm_run(kvm, vcpu); + if (r) + return r; + r = ioctl(fd, KVM_RUN, 0); + post_kvm_run(kvm, vcpu); + + run->io_completed = 0; + if (r == -1 && errno != EINTR) { + 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 vcpu_id %d\n", + (unsigned)run->hw.hardware_exit_reason, vcpu); + 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_abi10(kvm, run, vcpu); + break; + case KVM_EXIT_DEBUG: + r = handle_debug(kvm, vcpu); + break; + case KVM_EXIT_MMIO: + r = handle_mmio_abi10(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; + 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; +} + + +void kvm_show_code(kvm_context_t kvm, int vcpu) +{ +#define CR0_PE_MASK (1ULL<<0) + int fd = kvm->vcpu_fd[vcpu]; + struct kvm_regs regs; + struct kvm_sregs sregs; + int r; + unsigned char code[50]; + int back_offset; + char code_str[sizeof(code) * 3 + 1]; + unsigned long rip; + + r = ioctl(fd, KVM_GET_SREGS, &sregs); + if (r == -1) { + perror("KVM_GET_SREGS"); + return; + } + if (sregs.cr0 & CR0_PE_MASK) + return; + + r = ioctl(fd, KVM_GET_REGS, ®s); + if (r == -1) { + perror("KVM_GET_REGS"); + return; + } + rip = sregs.cs.base + regs.rip; + back_offset = regs.rip; + if (back_offset > 20) + back_offset = 20; + memcpy(code, kvm->physical_memory + rip - back_offset, sizeof code); + *code_str = 0; + for (r = 0; r < sizeof code; ++r) { + if (r == back_offset) + strcat(code_str, " -->"); + sprintf(code_str + strlen(code_str), " %02x", code[r]); + } + fprintf(stderr, "code:%s\n", code_str); +} + diff --git a/libkvm/libkvm.c b/libkvm/libkvm.c --- a/libkvm/libkvm.c +++ b/libkvm/libkvm.c @@ -545,8 +545,7 @@ int kvm_set_irqchip(kvm_context_t kvm, s #endif -static int handle_io_abi10(kvm_context_t kvm, struct kvm_run_abi10 *run, - int vcpu) +static int handle_io(kvm_context_t kvm, struct kvm_run *run, int vcpu) { uint16_t addr = run->io.port; int r; @@ -597,62 +596,6 @@ static int handle_io_abi10(kvm_context_t p += run->io.size; } - run->io_completed = 1; - - return 0; -} - -static int handle_io(kvm_context_t kvm, struct kvm_run *run, int vcpu) -{ - uint16_t addr = run->io.port; - int r; - int i; - void *p = (void *)run + run->io.data_offset; - - for (i = 0; i < run->io.count; ++i) { - switch (run->io.direction) { - case KVM_EXIT_IO_IN: - switch (run->io.size) { - case 1: - r = kvm->callbacks->inb(kvm->opaque, addr, p); - break; - case 2: - r = kvm->callbacks->inw(kvm->opaque, addr, p); - break; - case 4: - r = kvm->callbacks->inl(kvm->opaque, addr, p); - break; - default: - fprintf(stderr, "bad I/O size %d\n", run->io.size); - return -EMSGSIZE; - } - break; - case KVM_EXIT_IO_OUT: - switch (run->io.size) { - case 1: - r = kvm->callbacks->outb(kvm->opaque, addr, - *(uint8_t *)p); - break; - case 2: - r = kvm->callbacks->outw(kvm->opaque, addr, - *(uint16_t *)p); - break; - case 4: - r = kvm->callbacks->outl(kvm->opaque, addr, - *(uint32_t *)p); - break; - default: - fprintf(stderr, "bad I/O size %d\n", run->io.size); - return -EMSGSIZE; - } - break; - default: - fprintf(stderr, "bad I/O direction %d\n", run->io.direction); - return -EPROTO; - } - - p += run->io.size; - } return 0; } @@ -818,50 +761,15 @@ void kvm_show_regs(kvm_context_t kvm, in sregs.efer); } -static void kvm_show_code(kvm_context_t kvm, int vcpu) -{ -#define CR0_PE_MASK (1ULL<<0) - int fd = kvm->vcpu_fd[vcpu]; - struct kvm_regs regs; - struct kvm_sregs sregs; - int r; - unsigned char code[50]; - int back_offset; - char code_str[sizeof(code) * 3 + 1]; - unsigned long rip; - - r = ioctl(fd, KVM_GET_SREGS, &sregs); - if (r == -1) { - perror("KVM_GET_SREGS"); - return; - } - if (sregs.cr0 & CR0_PE_MASK) - return; - - r = ioctl(fd, KVM_GET_REGS, ®s); - if (r == -1) { - perror("KVM_GET_REGS"); - return; - } - rip = sregs.cs.base + regs.rip; - back_offset = regs.rip; - if (back_offset > 20) - back_offset = 20; - memcpy(code, kvm->physical_memory + rip - back_offset, sizeof code); - *code_str = 0; - for (r = 0; r < sizeof code; ++r) { - if (r == back_offset) - strcat(code_str, " -->"); - sprintf(code_str + strlen(code_str), " %02x", code[r]); - } - fprintf(stderr, "code:%s\n", code_str); -} - -static int handle_mmio_abi10(kvm_context_t kvm, struct kvm_run_abi10 *kvm_run) +static int handle_mmio(kvm_context_t kvm, struct kvm_run *kvm_run) { unsigned long addr = kvm_run->mmio.phys_addr; void *data = kvm_run->mmio.data; int r = -1; + + /* hack: Red Hat 7.1 generates these wierd accesses. */ + if (addr == 0xa0000 && kvm_run->mmio.len == 3) + return 0; if (kvm_run->mmio.is_write) { switch (kvm_run->mmio.len) { @@ -893,51 +801,6 @@ static int handle_mmio_abi10(kvm_context r = kvm->callbacks->readq(kvm->opaque, addr, (uint64_t *)data); break; } - kvm_run->io_completed = 1; - } - return r; -} - -static int handle_mmio(kvm_context_t kvm, struct kvm_run *kvm_run) -{ - unsigned long addr = kvm_run->mmio.phys_addr; - void *data = kvm_run->mmio.data; - int r = -1; - - /* hack: Red Hat 7.1 generates these wierd accesses. */ - if (addr == 0xa0000 && kvm_run->mmio.len == 3) - return 0; - - if (kvm_run->mmio.is_write) { - switch (kvm_run->mmio.len) { - case 1: - r = kvm->callbacks->writeb(kvm->opaque, addr, *(uint8_t *)data); - break; - case 2: - r = kvm->callbacks->writew(kvm->opaque, addr, *(uint16_t *)data); - break; - case 4: - r = kvm->callbacks->writel(kvm->opaque, addr, *(uint32_t *)data); - break; - case 8: - r = kvm->callbacks->writeq(kvm->opaque, addr, *(uint64_t *)data); - break; - } - } else { - switch (kvm_run->mmio.len) { - case 1: - r = kvm->callbacks->readb(kvm->opaque, addr, (uint8_t *)data); - break; - case 2: - r = kvm->callbacks->readw(kvm->opaque, addr, (uint16_t *)data); - break; - case 4: - r = kvm->callbacks->readl(kvm->opaque, addr, (uint32_t *)data); - break; - case 8: - r = kvm->callbacks->readq(kvm->opaque, addr, (uint64_t *)data); - break; - } } return r; } @@ -1013,81 +876,6 @@ __u64 kvm_get_cr8(kvm_context_t kvm, int __u64 kvm_get_cr8(kvm_context_t kvm, int vcpu) { return kvm->run[vcpu]->cr8; -} - -static int kvm_run_abi10(kvm_context_t kvm, int vcpu) -{ - int r; - int fd = kvm->vcpu_fd[vcpu]; - struct kvm_run_abi10 *run = (struct kvm_run_abi10 *)kvm->run[vcpu]; - -again: - run->request_interrupt_window = try_push_interrupts(kvm); - r = pre_kvm_run(kvm, vcpu); - if (r) - return r; - r = ioctl(fd, KVM_RUN, 0); - post_kvm_run(kvm, vcpu); - - run->io_completed = 0; - if (r == -1 && errno != EINTR) { - 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 vcpu_id %d\n", - (unsigned)run->hw.hardware_exit_reason, vcpu); - 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_abi10(kvm, run, vcpu); - break; - case KVM_EXIT_DEBUG: - r = handle_debug(kvm, vcpu); - break; - case KVM_EXIT_MMIO: - r = handle_mmio_abi10(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; - 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 kvm_run(kvm_context_t kvm, int vcpu) ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel