The purpose of that was only to allow the user of libkvm to register functions pointers that corresponded to possible actions. We don't need that anymore. Signed-off-by: Glauber Costa <glommer@xxxxxxxxxx> --- libkvm-all.h | 4 +- qemu-kvm-x86.c | 16 +-- qemu-kvm.c | 370 ++++++++++++++++++++++++++------------------------------ qemu-kvm.h | 3 + 4 files changed, 179 insertions(+), 214 deletions(-) diff --git a/libkvm-all.h b/libkvm-all.h index f348e69..6964b7a 100644 --- a/libkvm-all.h +++ b/libkvm-all.h @@ -175,12 +175,10 @@ struct kvm_callbacks { * holds information about the KVM instance that gets created by this call.\n * This should always be your first call to KVM. * - * \param callbacks Pointer to a valid kvm_callbacks structure * \param opaque Not used * \return NULL on failure */ -kvm_context_t kvm_init(struct kvm_callbacks *callbacks, - void *opaque); +kvm_context_t kvm_init(void *opaque); /*! * \brief Cleanup the KVM context diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c index e528acb..0620c14 100644 --- a/qemu-kvm-x86.c +++ b/qemu-kvm-x86.c @@ -121,9 +121,10 @@ int kvm_arch_create(kvm_context_t kvm, unsigned long phys_mem_bytes, static int kvm_handle_tpr_access(kvm_vcpu_context_t vcpu) { struct kvm_run *run = vcpu->run; - return vcpu->kvm->callbacks->tpr_access(vcpu->kvm->opaque, vcpu, - run->tpr_access.rip, - run->tpr_access.is_write); + kvm_tpr_access_report(cpu_single_env, + run->tpr_access.rip, + run->tpr_access.is_write); + return 0; } @@ -326,7 +327,7 @@ void kvm_show_code(kvm_vcpu_context_t vcpu) for (n = -back_offset; n < SHOW_CODE_LEN-back_offset; ++n) { if (n == 0) strcat(code_str, " -->"); - r = kvm->callbacks->mmio_read(kvm->opaque, rip + n, &code, 1); + r = kvm_mmio_read(kvm->opaque, rip + n, &code, 1); if (r < 0) { strcat(code_str, " xx"); continue; @@ -1344,13 +1345,6 @@ void kvm_arch_update_regs_for_sipi(CPUState *env) kvm_arch_load_regs(env); } -int handle_tpr_access(void *opaque, kvm_vcpu_context_t vcpu, - uint64_t rip, int is_write) -{ - kvm_tpr_access_report(cpu_single_env, rip, is_write); - return 0; -} - void kvm_arch_cpu_reset(CPUState *env) { kvm_arch_load_regs(env); diff --git a/qemu-kvm.c b/qemu-kvm.c index 3b5326e..40d59a7 100644 --- a/qemu-kvm.c +++ b/qemu-kvm.c @@ -27,6 +27,7 @@ #include <sys/syscall.h> #include <sys/mman.h> #include <sys/ioctl.h> +#include <signal.h> #define false 0 #define true 1 @@ -79,6 +80,129 @@ static LIST_HEAD(, ioperm_data) ioperm_head; int kvm_abi = EXPECTED_KVM_API_VERSION; int kvm_page_size; +#ifdef KVM_CAP_SET_GUEST_DEBUG +static int kvm_debug(void *opaque, void *data, + struct kvm_debug_exit_arch *arch_info) +{ + int handle = kvm_arch_debug(arch_info); + CPUState *env = data; + + if (handle) { + kvm_debug_cpu_requested = env; + env->kvm_cpu_state.stopped = 1; + } + return handle; +} +#endif + +static int kvm_inb(void *opaque, uint16_t addr, uint8_t *data) +{ + *data = cpu_inb(0, addr); + return 0; +} + +static int kvm_inw(void *opaque, uint16_t addr, uint16_t *data) +{ + *data = cpu_inw(0, addr); + return 0; +} + +static int kvm_inl(void *opaque, uint16_t addr, uint32_t *data) +{ + *data = cpu_inl(0, addr); + return 0; +} + +#define PM_IO_BASE 0xb000 + +static int kvm_outb(void *opaque, uint16_t addr, uint8_t data) +{ + if (addr == 0xb2) { + switch (data) { + case 0: { + cpu_outb(0, 0xb3, 0); + break; + } + case 0xf0: { + unsigned x; + + /* enable acpi */ + x = cpu_inw(0, PM_IO_BASE + 4); + x &= ~1; + cpu_outw(0, PM_IO_BASE + 4, x); + break; + } + case 0xf1: { + unsigned x; + + /* enable acpi */ + x = cpu_inw(0, PM_IO_BASE + 4); + x |= 1; + cpu_outw(0, PM_IO_BASE + 4, x); + break; + } + default: + break; + } + return 0; + } + cpu_outb(0, addr, data); + return 0; +} + +static int kvm_outw(void *opaque, uint16_t addr, uint16_t data) +{ + cpu_outw(0, addr, data); + return 0; +} + +static int kvm_outl(void *opaque, uint16_t addr, uint32_t data) +{ + cpu_outl(0, addr, data); + return 0; +} + +int kvm_mmio_read(void *opaque, uint64_t addr, uint8_t *data, int len) +{ + cpu_physical_memory_rw(addr, data, len, 0); + return 0; +} + +int kvm_mmio_write(void *opaque, uint64_t addr, uint8_t *data, int len) +{ + cpu_physical_memory_rw(addr, data, len, 1); + return 0; +} + +static int kvm_io_window(void *opaque) +{ + return 1; +} + +static int kvm_halt(void *opaque, kvm_vcpu_context_t vcpu) +{ + return kvm_arch_halt(opaque, vcpu); +} + +static int kvm_shutdown(void *opaque, void *data) +{ + CPUState *env = (CPUState *)data; + + /* stop the current vcpu from going back to guest mode */ + env->kvm_cpu_state.stopped = 1; + + qemu_system_reset_request(); + return 1; +} + +static int handle_unhandled(kvm_context_t kvm, kvm_vcpu_context_t vcpu, + uint64_t reason) +{ + fprintf(stderr, "kvm: unhandled exit %"PRIx64"\n", reason); + return -EINVAL; +} + + static inline void set_gsi(kvm_context_t kvm, unsigned int gsi) { uint32_t *bitmap = kvm->used_gsi_bitmap; @@ -314,8 +438,7 @@ int kvm_dirty_pages_log_reset(kvm_context_t kvm) } -kvm_context_t kvm_init(struct kvm_callbacks *callbacks, - void *opaque) +kvm_context_t kvm_init(void *opaque) { int fd; kvm_context_t kvm; @@ -351,7 +474,6 @@ kvm_context_t kvm_init(struct kvm_callbacks *callbacks, memset(kvm, 0, sizeof(*kvm)); kvm->fd = fd; kvm->vm_fd = -1; - kvm->callbacks = callbacks; kvm->opaque = opaque; kvm->dirty_pages_log_all = 0; kvm->no_irqchip_creation = 0; @@ -741,13 +863,13 @@ static int handle_io(kvm_vcpu_context_t vcpu) case KVM_EXIT_IO_IN: switch (run->io.size) { case 1: - r = kvm->callbacks->inb(kvm->opaque, addr, p); + r = kvm_inb(kvm->opaque, addr, p); break; case 2: - r = kvm->callbacks->inw(kvm->opaque, addr, p); + r = kvm_inw(kvm->opaque, addr, p); break; case 4: - r = kvm->callbacks->inl(kvm->opaque, addr, p); + r = kvm_inl(kvm->opaque, addr, p); break; default: fprintf(stderr, "bad I/O size %d\n", run->io.size); @@ -757,15 +879,15 @@ static int handle_io(kvm_vcpu_context_t vcpu) case KVM_EXIT_IO_OUT: switch (run->io.size) { case 1: - r = kvm->callbacks->outb(kvm->opaque, addr, + r = kvm_outb(kvm->opaque, addr, *(uint8_t *)p); break; case 2: - r = kvm->callbacks->outw(kvm->opaque, addr, + r = kvm_outw(kvm->opaque, addr, *(uint16_t *)p); break; case 4: - r = kvm->callbacks->outl(kvm->opaque, addr, + r = kvm_outl(kvm->opaque, addr, *(uint32_t *)p); break; default: @@ -790,7 +912,7 @@ int handle_debug(kvm_vcpu_context_t vcpu, void *env) struct kvm_run *run = vcpu->run; kvm_context_t kvm = vcpu->kvm; - return kvm->callbacks->debug(kvm->opaque, env, &run->debug.arch); + return kvm_debug(kvm->opaque, env, &run->debug.arch); #else return 0; #endif @@ -860,48 +982,71 @@ static int handle_mmio(kvm_vcpu_context_t vcpu) return 0; if (kvm_run->mmio.is_write) - return kvm->callbacks->mmio_write(kvm->opaque, addr, data, + return kvm_mmio_write(kvm->opaque, addr, data, kvm_run->mmio.len); else - return kvm->callbacks->mmio_read(kvm->opaque, addr, data, + return kvm_mmio_read(kvm->opaque, addr, data, kvm_run->mmio.len); } int handle_io_window(kvm_context_t kvm) { - return kvm->callbacks->io_window(kvm->opaque); + return kvm_io_window(kvm->opaque); } int handle_halt(kvm_vcpu_context_t vcpu) { - return vcpu->kvm->callbacks->halt(vcpu->kvm->opaque, vcpu); + return kvm_halt(vcpu->kvm->opaque, vcpu); } int handle_shutdown(kvm_context_t kvm, void *env) { - return kvm->callbacks->shutdown(kvm->opaque, env); + return kvm_shutdown(kvm->opaque, env); +} + +static int kvm_try_push_interrupts(void *opaque) +{ + return kvm_arch_try_push_interrupts(opaque); +} + +static void kvm_post_run(void *opaque, void *data) +{ + CPUState *env = (CPUState *)data; + + pthread_mutex_lock(&qemu_mutex); + kvm_arch_post_kvm_run(opaque, env); +} + +static int kvm_pre_run(void *opaque, void *data) +{ + CPUState *env = (CPUState *)data; + + kvm_arch_pre_kvm_run(opaque, env); + + pthread_mutex_unlock(&qemu_mutex); + return 0; } int try_push_interrupts(kvm_context_t kvm) { - return kvm->callbacks->try_push_interrupts(kvm->opaque); + return kvm_try_push_interrupts(kvm->opaque); } static inline void push_nmi(kvm_context_t kvm) { #ifdef KVM_CAP_USER_NMI - kvm->callbacks->push_nmi(kvm->opaque); + kvm_arch_push_nmi(kvm->opaque); #endif /* KVM_CAP_USER_NMI */ } void post_kvm_run(kvm_context_t kvm, void *env) { - kvm->callbacks->post_kvm_run(kvm->opaque, env); + kvm_post_run(kvm->opaque, env); } int pre_kvm_run(kvm_context_t kvm, void *env) { - return kvm->callbacks->pre_kvm_run(kvm->opaque, env); + return kvm_pre_run(kvm->opaque, env); } int kvm_get_interrupt_flag(kvm_vcpu_context_t vcpu) @@ -946,7 +1091,7 @@ again: struct kvm_coalesced_mmio_ring *ring = (void *)run + kvm->coalesced_mmio * PAGE_SIZE; while (ring->first != ring->last) { - kvm->callbacks->mmio_write(kvm->opaque, + kvm_mmio_write(kvm->opaque, ring->coalesced_mmio[ring->first].phys_addr, &ring->coalesced_mmio[ring->first].data[0], ring->coalesced_mmio[ring->first].len); @@ -966,11 +1111,11 @@ again: if (1) { switch (run->exit_reason) { case KVM_EXIT_UNKNOWN: - r = kvm->callbacks->unhandled(kvm, vcpu, + r = handle_unhandled(kvm, vcpu, run->hw.hardware_exit_reason); break; case KVM_EXIT_FAIL_ENTRY: - r = kvm->callbacks->unhandled(kvm, vcpu, + r = handle_unhandled(kvm, vcpu, run->fail_entry.hardware_entry_failure_reason); break; case KVM_EXIT_EXCEPTION: @@ -1000,11 +1145,11 @@ again: break; #if defined(__s390__) case KVM_EXIT_S390_SIEIC: - r = kvm->callbacks->s390_handle_intercept(kvm, vcpu, + r = kvm_s390_handle_intercept(kvm, vcpu, run); break; case KVM_EXIT_S390_RESET: - r = kvm->callbacks->s390_handle_reset(kvm, vcpu, run); + r = kvm_s390_handle_reset(kvm, vcpu, run); break; #endif default: @@ -1603,31 +1748,6 @@ void kvm_update_interrupt_request(CPUState *env) } } -#include <signal.h> - -static int kvm_try_push_interrupts(void *opaque) -{ - return kvm_arch_try_push_interrupts(opaque); -} - -static void kvm_post_run(void *opaque, void *data) -{ - CPUState *env = (CPUState *)data; - - pthread_mutex_lock(&qemu_mutex); - kvm_arch_post_kvm_run(opaque, env); -} - -static int kvm_pre_run(void *opaque, void *data) -{ - CPUState *env = (CPUState *)data; - - kvm_arch_pre_kvm_run(opaque, env); - - pthread_mutex_unlock(&qemu_mutex); - return 0; -} - static void kvm_do_load_registers(void *_env) { CPUState *env = _env; @@ -2077,160 +2197,10 @@ int kvm_main_loop(void) return 0; } -#ifdef KVM_CAP_SET_GUEST_DEBUG -static int kvm_debug(void *opaque, void *data, - struct kvm_debug_exit_arch *arch_info) -{ - int handle = kvm_arch_debug(arch_info); - CPUState *env = data; - - if (handle) { - kvm_debug_cpu_requested = env; - env->kvm_cpu_state.stopped = 1; - } - return handle; -} -#endif - -static int kvm_inb(void *opaque, uint16_t addr, uint8_t *data) -{ - *data = cpu_inb(0, addr); - return 0; -} - -static int kvm_inw(void *opaque, uint16_t addr, uint16_t *data) -{ - *data = cpu_inw(0, addr); - return 0; -} - -static int kvm_inl(void *opaque, uint16_t addr, uint32_t *data) -{ - *data = cpu_inl(0, addr); - return 0; -} - -#define PM_IO_BASE 0xb000 - -static int kvm_outb(void *opaque, uint16_t addr, uint8_t data) -{ - if (addr == 0xb2) { - switch (data) { - case 0: { - cpu_outb(0, 0xb3, 0); - break; - } - case 0xf0: { - unsigned x; - - /* enable acpi */ - x = cpu_inw(0, PM_IO_BASE + 4); - x &= ~1; - cpu_outw(0, PM_IO_BASE + 4, x); - break; - } - case 0xf1: { - unsigned x; - - /* enable acpi */ - x = cpu_inw(0, PM_IO_BASE + 4); - x |= 1; - cpu_outw(0, PM_IO_BASE + 4, x); - break; - } - default: - break; - } - return 0; - } - cpu_outb(0, addr, data); - return 0; -} - -static int kvm_outw(void *opaque, uint16_t addr, uint16_t data) -{ - cpu_outw(0, addr, data); - return 0; -} - -static int kvm_outl(void *opaque, uint16_t addr, uint32_t data) -{ - cpu_outl(0, addr, data); - return 0; -} - -static int kvm_mmio_read(void *opaque, uint64_t addr, uint8_t *data, int len) -{ - cpu_physical_memory_rw(addr, data, len, 0); - return 0; -} - -static int kvm_mmio_write(void *opaque, uint64_t addr, uint8_t *data, int len) -{ - cpu_physical_memory_rw(addr, data, len, 1); - return 0; -} - -static int kvm_io_window(void *opaque) -{ - return 1; -} - - -static int kvm_halt(void *opaque, kvm_vcpu_context_t vcpu) -{ - return kvm_arch_halt(opaque, vcpu); -} - -static int kvm_shutdown(void *opaque, void *data) -{ - CPUState *env = (CPUState *)data; - - /* stop the current vcpu from going back to guest mode */ - env->kvm_cpu_state.stopped = 1; - - qemu_system_reset_request(); - return 1; -} - -static int handle_unhandled(kvm_context_t kvm, kvm_vcpu_context_t vcpu, - uint64_t reason) -{ - fprintf(stderr, "kvm: unhandled exit %"PRIx64"\n", reason); - return -EINVAL; -} - -static struct kvm_callbacks qemu_kvm_ops = { -#ifdef KVM_CAP_SET_GUEST_DEBUG - .debug = kvm_debug, -#endif - .inb = kvm_inb, - .inw = kvm_inw, - .inl = kvm_inl, - .outb = kvm_outb, - .outw = kvm_outw, - .outl = kvm_outl, - .mmio_read = kvm_mmio_read, - .mmio_write = kvm_mmio_write, - .halt = kvm_halt, - .shutdown = kvm_shutdown, - .io_window = kvm_io_window, - .try_push_interrupts = kvm_try_push_interrupts, -#ifdef KVM_CAP_USER_NMI - .push_nmi = kvm_arch_push_nmi, -#endif - .post_kvm_run = kvm_post_run, - .pre_kvm_run = kvm_pre_run, -#ifdef TARGET_I386 - .tpr_access = handle_tpr_access, -#endif - .unhandled = handle_unhandled, -}; - int kvm_qemu_init() { /* Try to initialize kvm */ - kvm_context = kvm_init(&qemu_kvm_ops, cpu_single_env); + kvm_context = kvm_init(cpu_single_env); if (!kvm_context) { return -1; } diff --git a/qemu-kvm.h b/qemu-kvm.h index 10f0a80..87c84d6 100644 --- a/qemu-kvm.h +++ b/qemu-kvm.h @@ -120,6 +120,9 @@ int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size); int kvm_arch_init_irq_routing(void); +int kvm_mmio_read(void *opaque, uint64_t addr, uint8_t *data, int len); +int kvm_mmio_write(void *opaque, uint64_t addr, uint8_t *data, int len); + #ifdef USE_KVM_DEVICE_ASSIGNMENT struct ioperm_data; -- 1.6.2.2 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html