From mboxrd@z Thu Jan 1 00:00:00 1970 From: Marcelo Tosatti Subject: KVM: PIT: fix pit_state copy in set_pit2/get_pit2 Date: Tue, 25 Aug 2009 09:29:21 -0300 Message-ID: <20090825122921.GA18813@amt.cnet> References: <0463F45F3606F4428ED35AC8C709F92E0897FE903F@pdsmsx502.ccr.corp.intel.com> <4A894A5B.2080901@redhat.com> <0463F45F3606F4428ED35AC8C709F92E0899F3DD99@pdsmsx502.ccr.corp.intel.com> <4A8BB304.6020202@redhat.com> <0463F45F3606F4428ED35AC8C709F92E0899F3E6E2@pdsmsx502.ccr.corp.intel.com> <4A93BADC.4090106@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: "Xu, Jiajun" , "'kvm-devel'" To: Avi Kivity Return-path: Received: from mx1.redhat.com ([209.132.183.28]:40031 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752819AbZHYM3f (ORCPT ); Tue, 25 Aug 2009 08:29:35 -0400 Content-Disposition: inline In-Reply-To: <4A93BADC.4090106@redhat.com> Sender: kvm-owner@vger.kernel.org List-ID: The kvm_pit_state2 structure contains extra space, so the memcpy in kvm_vm_ioctl_set_pit2 corrupts kvm->arch.vpit->pit_state. Fix it by memcpy'ing the channel information and assigning flags manually. Signed-off-by: Marcelo Tosatti diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 0f22f72..35e7fc5 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2095,7 +2095,9 @@ static int kvm_vm_ioctl_get_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps) int r = 0; mutex_lock(&kvm->arch.vpit->pit_state.lock); - memcpy(ps, &kvm->arch.vpit->pit_state, sizeof(struct kvm_pit_state2)); + memcpy(ps->channels, &kvm->arch.vpit->pit_state.channels, + sizeof(ps->channels)); + ps->flags = kvm->arch.vpit->pit_state.flags; mutex_unlock(&kvm->arch.vpit->pit_state.lock); return r; } @@ -2109,7 +2111,9 @@ static int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps) cur_legacy = ps->flags & KVM_PIT_FLAGS_HPET_LEGACY; if (!prev_legacy && cur_legacy) start = 1; - memcpy(&kvm->arch.vpit->pit_state, ps, sizeof(struct kvm_pit_state2)); + memcpy(&kvm->arch.vpit->pit_state.channels, &ps->channels, + sizeof(kvm->arch.vpit->pit_state.channels)); + kvm->arch.vpit->pit_state.flags = ps->flags; kvm_pit_load_count(kvm, 0, kvm->arch.vpit->pit_state.channels[0].count, start); mutex_unlock(&kvm->arch.vpit->pit_state.lock); return r;