From mboxrd@z Thu Jan 1 00:00:00 1970 From: Avi Kivity Subject: Re: [PATCH] When switching to a vm8086 task, load segments as 16-bit Date: Tue, 11 Aug 2009 19:35:31 +0300 Message-ID: <4A819DD3.4060308@redhat.com> References: <1249952431-7764-1-git-send-email-aliguori@us.ibm.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: kvm@vger.kernel.org, Gleb Natapov To: Anthony Liguori Return-path: Received: from mx2.redhat.com ([66.187.237.31]:55829 "EHLO mx2.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754209AbZHKQ3Q (ORCPT ); Tue, 11 Aug 2009 12:29:16 -0400 In-Reply-To: <1249952431-7764-1-git-send-email-aliguori@us.ibm.com> Sender: kvm-owner@vger.kernel.org List-ID: On 08/11/2009 04:00 AM, Anthony Liguori wrote: > According to 16.2.5 in the SDM, eflags.vm in the tss is consulted before loading > and new segments. If eflags.vm == 1, then the segments are treated as 16-bit > segments. > > This fixes an invalid vmentry failure in a custom OS that was happening after > a task switch into vm8086 mode. Since the segments were being mistakenly > treated as 32-bit, we loaded garbage state. > > Signed-off-by: Anthony Liguori > --- > arch/x86/kvm/x86.c | 23 +++++++++++++++++------ > 1 files changed, 17 insertions(+), 6 deletions(-) > > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c > index 6263991..48b1be9 100644 > --- a/arch/x86/kvm/x86.c > +++ b/arch/x86/kvm/x86.c > @@ -4050,6 +4050,16 @@ static void save_state_to_tss32(struct kvm_vcpu *vcpu, > tss->ldt_selector = get_segment_selector(vcpu, VCPU_SREG_LDTR); > } > > +static int load_seg_from_tss32(struct kvm_vcpu *vcpu, > + struct tss_segment_32 *tss, > + u16 selector, int type_bits, int seg) > +{ > + if ((tss->eflags& X86_EFLAGS_VM)) > + return kvm_load_realmode_segment(vcpu, selector, seg); > + > + return kvm_load_segment_descriptor(vcpu, selector, type_bits, seg); > +} > + > kvm_load_segment_descriptor() can already load plain segments: if (!(vcpu->arch.cr0 & X86_CR0_PE)) return kvm_load_realmode_segment(vcpu, selector, seg); so we can simplify the patch a bit by extending the check. -- error compiling committee.c: too many arguments to function