[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 08/15] x86/hvm: Reposition the modification of raw segment data from the VMCB/VMCS
On 11/23/2016 10:38 AM, Andrew Cooper wrote: > Intel VT-x and AMD SVM provide access to the full segment descriptor cache via > fields in the VMCB/VMCS. However, the bits which are actually checked by > hardware and preserved across vmentry/exit are inconsistent, and the vendor > accessor functions perform inconsistent modification to the raw values. > > Convert {svm,vmx}_{get,set}_segment_register() into raw accessors, and alter > hvm_{get,set}_segment_register() to cook the values consistently. This allows > the common emulation code to better rely on finding architecturally-expected > values. > > This does cause some functional changes because of the modifications being > applied uniformly. A side effect of this fixes latent bugs where > vmx_set_segment_register() didn't correctly fix up .G for segments, and > inconsistent fixing up of the GDTR/IDTR limits. > > Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> > --- > CC: Jan Beulich <JBeulich@xxxxxxxx> > CC: Jun Nakajima <jun.nakajima@xxxxxxxxx> > CC: Kevin Tian <kevin.tian@xxxxxxxxx> > CC: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx> > CC: Suravee Suthikulpanit <suravee.suthikulpanit@xxxxxxx> > --- > xen/arch/x86/hvm/hvm.c | 151 > ++++++++++++++++++++++++++++++++++++++++++ > xen/arch/x86/hvm/svm/svm.c | 20 +----- > xen/arch/x86/hvm/vmx/vmx.c | 6 +- > xen/include/asm-x86/desc.h | 6 ++ > xen/include/asm-x86/hvm/hvm.h | 17 ++--- > 5 files changed, 164 insertions(+), 36 deletions(-) > > diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c > index ef83100..804cd88 100644 > --- a/xen/arch/x86/hvm/hvm.c > +++ b/xen/arch/x86/hvm/hvm.c > @@ -6051,6 +6051,157 @@ void hvm_domain_soft_reset(struct domain *d) > } > > /* > + * Segment caches in VMCB/VMCS are inconsistent about which bits are checked, > + * important, and preserved across vmentry/exit. Cook the values to make > them > + * closer to what is architecturally expected from entries in the segment > + * cache. > + */ > +void hvm_get_segment_register(struct vcpu *v, enum x86_segment seg, > + struct segment_register *reg) > +{ > + hvm_funcs.get_segment_register(v, seg, reg); > + > + switch ( seg ) > + { > + case x86_seg_ss: > + /* SVM may retain %ss.DB when %ss is loaded with a NULL selector. */ > + if ( !reg->attr.fields.p ) > + reg->attr.fields.db = 0; Removed SVM code relied on type being zero to indicate a NULL segment. Looking at P bit is the correct way and I think it's worth mentioning this in the commit message. > +} > + > +void hvm_set_segment_register(struct vcpu *v, enum x86_segment seg, > + struct segment_register *reg) > +{ > + /* Set G to match the limit field. VT-x cares, while SVM doesn't. */ > + if ( reg->attr.fields.p ) > + reg->attr.fields.g = !!(reg->limit >> 20); > + > + switch ( seg ) > + { > + case x86_seg_cs: > + ASSERT(reg->attr.fields.p); /* Usable. */ > + ASSERT(reg->attr.fields.s); /* User segment. */ > + ASSERT((reg->base >> 32) == 0); /* Upper bits clear. */ > + break; > + > + case x86_seg_ss: > + if ( reg->attr.fields.p ) > + { > + ASSERT(reg->attr.fields.s); /* User segment. */ > + ASSERT(!(reg->attr.fields.type & 0x8)); /* Data segment. */ > + ASSERT(reg->attr.fields.type & 0x2); /* Writeable. */ > + ASSERT((reg->base >> 32) == 0); /* Upper bits clear. */ > + } > + break; SVM requires attributes of any NULL segment to be zero. I don't know about Intel but if it's the same then should we ASSERT this as well? -boris _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |