On 25/04/17 20:18, Borislav Petkov wrote: > On Tue, Apr 25, 2017 at 08:34:34PM +0200, Juergen Gross wrote: >> And what happens when there is a scheduling event right here? >> __switch_to() will see X86_BUG_SYSRET_SS_ATTRS set and take a wrong >> path. > So the whole thing we're doing right now is wrong: set bit and then > clear bit. > > We should not set the bit at all and there won't be any window to get it > wrong. > > So can we do something like this instead: > > if (!cpu_has(c, X86_FEATURE_XENPV)) > set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS); > > or is XENPV the wrong thing to test? >
X86_BUG_SYSRET_SS_ATTRS only actually causes a problem if you enter the kernel via an IDT vector (forcing %ss to NULL), then exiting the kernel via the optimistic sysret path, which on AMD loads the %ss selector, but apparently doesn't update the segment cache (and %ss.dpl in particular). The problem (for all ring-deprivileged virtuailsation; not just Xen PV), is that savesegment(ss, ss_sel); if (ss_sel != __KERNEL_DS) loadsegment(ss, __KERNEL_DS); tries to load %ss with an RPL of 0, and things blow up. ~Andrew