From patchwork Mon Jul 6 20:12:51 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Glauber Costa X-Patchwork-Id: 34306 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n66KD6W1007212 for ; Mon, 6 Jul 2009 20:13:06 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753898AbZGFUM6 (ORCPT ); Mon, 6 Jul 2009 16:12:58 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753679AbZGFUM6 (ORCPT ); Mon, 6 Jul 2009 16:12:58 -0400 Received: from mx2.redhat.com ([66.187.237.31]:59238 "EHLO mx2.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753216AbZGFUMv (ORCPT ); Mon, 6 Jul 2009 16:12:51 -0400 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n66KCtHZ016530 for ; Mon, 6 Jul 2009 16:12:55 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id n66KCsYk031466; Mon, 6 Jul 2009 16:12:55 -0400 Received: from localhost.localdomain (virtlab1.virt.bos.redhat.com [10.16.72.21]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id n66KCrSW031854; Mon, 6 Jul 2009 16:12:54 -0400 From: Glauber Costa To: kvm@vger.kernel.org Cc: avi@redhat.com Subject: [PATCH v3 4/5] remove callbacks structure Date: Mon, 6 Jul 2009 16:12:51 -0400 Message-Id: <1246911172-5869-5-git-send-email-glommer@redhat.com> In-Reply-To: <1246911172-5869-4-git-send-email-glommer@redhat.com> References: <1246911172-5869-1-git-send-email-glommer@redhat.com> <1246911172-5869-2-git-send-email-glommer@redhat.com> <1246911172-5869-3-git-send-email-glommer@redhat.com> <1246911172-5869-4-git-send-email-glommer@redhat.com> X-Scanned-By: MIMEDefang 2.58 on 172.16.27.26 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org 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 --- 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 #include #include +#include #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 - -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;