From patchwork Thu Jan 28 19:03:02 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcelo Tosatti X-Patchwork-Id: 75605 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o0SJ6vQw018470 for ; Thu, 28 Jan 2010 19:06:57 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754135Ab0A1TGw (ORCPT ); Thu, 28 Jan 2010 14:06:52 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754152Ab0A1TGv (ORCPT ); Thu, 28 Jan 2010 14:06:51 -0500 Received: from mx1.redhat.com ([209.132.183.28]:30085 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753869Ab0A1TGt (ORCPT ); Thu, 28 Jan 2010 14:06:49 -0500 Received: from int-mx05.intmail.prod.int.phx2.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.18]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o0SJ6nYd027222 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 28 Jan 2010 14:06:49 -0500 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx05.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o0SJ6n1c005665; Thu, 28 Jan 2010 14:06:49 -0500 Received: from amt.cnet (vpn-8-142.rdu.redhat.com [10.11.8.142]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id o0SJ6l7b024787; Thu, 28 Jan 2010 14:06:47 -0500 Received: from amt.cnet (amt.cnet [127.0.0.1]) by amt.cnet (Postfix) with ESMTP id 38CF46520F0; Thu, 28 Jan 2010 17:06:41 -0200 (BRST) Received: (from marcelo@localhost) by amt.cnet (8.14.3/8.14.3/Submit) id o0SJ6dUT018464; Thu, 28 Jan 2010 17:06:39 -0200 Message-Id: <20100128190411.561703648@redhat.com> User-Agent: quilt/0.47-1 Date: Thu, 28 Jan 2010 17:03:02 -0200 From: Marcelo Tosatti To: kvm@vger.kernel.org Cc: quintela@redhat.com, Marcelo Tosatti Subject: [patch 2/3] uqmaster: save/restore pio state References: <20100128190300.414710338@redhat.com> Content-Disposition: inline; filename=kvm-get-put-pio X-Scanned-By: MIMEDefang 2.67 on 10.5.11.18 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Thu, 28 Jan 2010 19:06:58 +0000 (UTC) Index: qemu-kvm/target-i386/cpu.h =================================================================== --- qemu-kvm.orig/target-i386/cpu.h +++ qemu-kvm/target-i386/cpu.h @@ -570,6 +570,18 @@ typedef struct { uint64_t mask; } MTRRVar; +typedef struct { + uint64_t guest_gva; + uint32_t count; + uint32_t cur_count; + uint16_t port; + uint8_t size; + uint8_t in; + uint8_t string; + uint8_t down; + uint8_t rep; +} KVMPIOState; + #define CPU_NB_REGS64 16 #define CPU_NB_REGS32 8 @@ -702,7 +714,9 @@ typedef struct CPUX86State { uint8_t has_error_code; uint32_t sipi_vector; uint32_t cpuid_kvm_features; - + + KVMPIOState kvm_pio; + /* in order to simplify APIC support, we leave this pointer to the user */ struct APICState *apic_state; Index: qemu-kvm/target-i386/kvm.c =================================================================== --- qemu-kvm.orig/target-i386/kvm.c +++ qemu-kvm/target-i386/kvm.c @@ -289,6 +289,7 @@ void kvm_arch_reset_vcpu(CPUState *env) env->interrupt_injected = -1; env->nmi_injected = 0; env->nmi_pending = 0; + memset(&env->kvm_pio, 0, sizeof(KVMPIOState)); } static int kvm_has_msr_star(CPUState *env) @@ -837,6 +838,57 @@ static int kvm_get_vcpu_events(CPUState return 0; } +static int kvm_put_pio(CPUState *env) +{ +#ifdef KVM_CAP_PIO + struct kvm_pio_request pio; + + if (!kvm_has_vcpu_pio()) + return 0; + + pio.count = env->kvm_pio.count; + pio.cur_count = env->kvm_pio.cur_count; + pio.guest_gva = env->kvm_pio.guest_gva; + pio.in = env->kvm_pio.in; + pio.port = env->kvm_pio.port; + pio.size = env->kvm_pio.size; + pio.string = env->kvm_pio.string; + pio.down = env->kvm_pio.down; + pio.rep = env->kvm_pio.rep; + + return kvm_vcpu_ioctl(env, KVM_SET_VCPU_PIO, &pio); +#else + return 0; +#endif +} + +static int kvm_get_pio(CPUState *env) +{ +#ifdef KVM_CAP_PIO + struct kvm_pio_request pio; + int ret; + + if (!kvm_has_vcpu_pio()) + return 0; + + ret = kvm_vcpu_ioctl(env, KVM_GET_VCPU_PIO, &pio); + if (ret < 0) + return ret; + + env->kvm_pio.count = pio.count; + env->kvm_pio.cur_count = pio.cur_count; + env->kvm_pio.guest_gva = pio.guest_gva; + env->kvm_pio.in = pio.in; + env->kvm_pio.port = pio.port; + env->kvm_pio.size = pio.size; + env->kvm_pio.string = pio.string; + env->kvm_pio.down = pio.down; + env->kvm_pio.rep = pio.rep; +#endif + + return 0; +} + int kvm_arch_put_registers(CPUState *env) { int ret; @@ -865,6 +917,10 @@ int kvm_arch_put_registers(CPUState *env if (ret < 0) return ret; + ret = kvm_put_pio(env); + if (ret < 0) + return ret; + return 0; } @@ -896,6 +952,10 @@ int kvm_arch_get_registers(CPUState *env if (ret < 0) return ret; + ret = kvm_get_pio(env); + if (ret < 0) + return ret; + return 0; } Index: qemu-kvm/target-i386/machine.c =================================================================== --- qemu-kvm.orig/target-i386/machine.c +++ qemu-kvm/target-i386/machine.c @@ -62,6 +62,34 @@ static const VMStateDescription vmstate_ #define VMSTATE_MTRR_VARS(_field, _state, _n, _v) \ VMSTATE_STRUCT_ARRAY(_field, _state, _n, _v, vmstate_mtrr_var, MTRRVar) +static const VMStateDescription vmstate_kvm_pio = { + .name = "kvm_pio", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField []) { + VMSTATE_UINT64(guest_gva, KVMPIOState), + VMSTATE_UINT32(count, KVMPIOState), + VMSTATE_UINT32(cur_count, KVMPIOState), + VMSTATE_UINT8(in, KVMPIOState), + VMSTATE_UINT16(port, KVMPIOState), + VMSTATE_UINT8(size, KVMPIOState), + VMSTATE_UINT8(string, KVMPIOState), + VMSTATE_UINT8(down, KVMPIOState), + VMSTATE_UINT8(rep, KVMPIOState), + VMSTATE_END_OF_LIST() + } +}; + +#define VMSTATE_KVM_PIO(_field, _state, _version) { \ + .name = (stringify(_field)), \ + .version_id = _version, \ + .size = sizeof(KVMPIOState), \ + .vmsd = &vmstate_kvm_pio, \ + .flags = VMS_STRUCT, \ + .offset = vmstate_offset_value(_state, _field, KVMPIOState),\ +} + static void put_fpreg_error(QEMUFile *f, void *opaque, size_t size) { fprintf(stderr, "call put_fpreg() with invalid arguments\n"); @@ -464,6 +492,9 @@ static const VMStateDescription vmstate_ /* KVM pvclock msr */ VMSTATE_UINT64_V(system_time_msr, CPUState, 11), VMSTATE_UINT64_V(wall_clock_msr, CPUState, 11), + + VMSTATE_KVM_PIO(kvm_pio, CPUState, 11), + VMSTATE_END_OF_LIST() /* The above list is not sorted /wrt version numbers, watch out! */ } Index: qemu-kvm/kvm.h =================================================================== --- qemu-kvm.orig/kvm.h +++ qemu-kvm/kvm.h @@ -48,6 +48,7 @@ int kvm_set_migration_log(int enable); int kvm_has_sync_mmu(void); int kvm_has_vcpu_events(void); +int kvm_has_vcpu_pio(void); void kvm_setup_guest_memory(void *start, size_t size); Index: qemu-kvm/kvm-all.c =================================================================== --- qemu-kvm.orig/kvm-all.c +++ qemu-kvm/kvm-all.c @@ -881,6 +881,17 @@ int kvm_has_sync_mmu(void) #endif } +int kvm_has_vcpu_pio(void) +{ +#ifdef KVM_CAP_PIO + KVMState *s = kvm_state; + + return kvm_check_extension(s, KVM_CAP_PIO); +#else + return 0; +#endif +} + int kvm_has_vcpu_events(void) { return kvm_state->vcpu_events;