[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] Bisected Xen-unstable: "Segment register inaccessible for d1v0" when starting HVM guest on intel

> -----Original Message-----
> From: Jan Beulich [mailto:JBeulich@xxxxxxxx]
> Sent: Tuesday, July 01, 2014 3:02 PM
> To: Wu, Feng
> Cc: Andrew Cooper; Sander Eikelenboom; xen-devel@xxxxxxxxxxxxxxxxxxxx
> Subject: RE: [Xen-devel] Bisected Xen-unstable: "Segment register inaccessible
> for d1v0" when starting HVM guest on intel
> >>> On 01.07.14 at 07:05, <feng.wu@xxxxxxxxx> wrote:
> >> From: Andrew Cooper [mailto:andrew.cooper3@xxxxxxxxxx]
> >> During a context switch (where the vmcs is unavailable), we try to
> >> update the the runstate area.
> >>
> >> Following the identified changeset, we unconditionally try to read ss
> >> for an hvm vcpu supervisor access, but in this case we don't actually
> >> have a pagefault.
> >>
> >> I think there might need to be a distinction between "Xen is walking the
> >> guest pagetables because of a fault", and "Xen is walking the guest
> >> pagetables in an attempt to copy_to/from_guest".  Neither SMEP or SMAP
> >> have any business being checked for a Xen accesses; the current vcpu
> >> operating mode has no bearing on whether Xen should be able to update
> >> the runstate info.
> >
> > Seems we cannot get the guest SS here by hvm_get_segment_register(),
> since
> > in this case this function will be called between setting 'current' and
> > vmx_do_resume(). Is the following solution okay to solve this issue:
> >
> > 1. Store GUEST_SS to regs->ss in vmx_vmexit_handler() just like what has
> been
> > 2. Get the guest SS from struct cpu_user_regs in guest_walk_tables()
> I think you originally (and wrongly) did this via looking at the RPL;
> this won't all of the sudden become right now. DPL is the only
> thing you can use for the judgment, and that can't be read
> without calling hvm_get_segment_register() (unless we latched
> that while scheduling a vCPU out). But as Andrew validly said,
> for the purposes of out of context Xen writes the guest execution
> mode doesn't matter anyway, these ought to always assume

So according to you and Andrew's comments, maybe we can add a
parameter for guest_walk_tables() to distinguish "Xen is walking the
guest pagetables because of a fault", and "Xen is walking the guest
pagetables in an attempt to copy_to/from_guest". We only do the
SMAP/SMEP check for the guest fault case?

> supervisor mode. That points out another problem here: Accesses
> like the setting of a segment descriptor's accessed bit or the A/D
> bit in a page table entry also need to be done as if in supervisor
> mode, i.e. we need some kind of mode override also for other
> purposes. Yet I don't think that's going to be too intrusive a
> change: Everything here happens on "current", i.e. we can set
> and clear a mode override on the respective call paths.

I am sorry, I don't quite understand about the problem you mentioned here,
Could you please elaborate a bit more on it? Thanks a lot!

> But then again - why do we need to determine CPL here anyway?
> PFEC_user_mode clear already tells us the access was a kernel
> mode one. And the SMEP check doesn't look at CPL, only the SMAP
> one does.

I think we need to check CPL here. PFEC_user_mode clear only means
the fault happens on supervisor-mode accesses. But from Intel SDM
supervisor-mode accesses can occurs when CPL =3, please refer to:

"Every access to a linear address is either a supervisor-mode access
or a user-mode access. All accesses performed while the current
privilege level (CPL) is less than 3 are supervisor-mode accesses.
If CPL = 3, accesses are generally user-mode accesses. However, some
operations implicitly access system data structures, and the resulting
accesses to those data structures are supervisor-mode accesses regardless
of CPL. Examples of such implicit supervisor accesses include the following:
accesses to the global descriptor table (GDT) or local descriptor table
(LDT) to load a segment descriptor; accesses to the interrupt descriptor
table (IDT) when delivering an interrupt or exception; and accesses to the
task-state segment (TSS) as part of a task switch or change of CPL."

Also, for SMAP hardware behaves differently between CPL=3 and CPL<3,

" If CPL < 3, SMAP protections are disabled if EFLAGS.AC = 1. If CPL = 3, 
SMAP applies to all supervisor-mode data accesses (these are implicit
supervisor accesses) regardless of the value of EFLAGS.AC."


> Jan

Xen-devel mailing list



Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.