tech-kern archive

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

Re: [PATCH v3 2/2] Implement PT_GETXSTATE and PT_SETXSTATE



On Sun, 2019-06-09 at 13:17 +0200, Maxime Villard wrote:
> Le 09/06/2019 à 09:46, Michał Górny a écrit :
> > On Sun, 2019-06-09 at 09:08 +0200, Maxime Villard wrote:
> > > Le 07/06/2019 à 20:33, Michał Górny a écrit :
> > > > [...]
> > > > +int
> > > > +process_machdep_doxstate(struct lwp *curl, struct lwp *l, struct uio *uio)
> > > > +	/* curl:		 tracer */
> > > > +	/* l:			 traced */
> > > > +{
> > > > +	int error;
> > > > +	struct xstate r;
> > > > +	char *kv;
> > > > +	ssize_t kl;
> > > > +
> > > > +	kl = MIN(uio->uio_iov->iov_len, sizeof(r));
> > > > +	kv = (char *) &r;
> > > > +
> > > > +	kv += uio->uio_offset;
> > > > +	kl -= uio->uio_offset;
> > > > +	if (kl > uio->uio_resid)
> > > > +		kl = uio->uio_resid;
> > > > +
> > > > +	if (kl < 0)
> > > > +		error = EINVAL;
> > > > +	else
> > > > +		error = process_machdep_read_xstate(l, &r);
> > > > +	if (error == 0)
> > > > +		error = uiomove(kv, kl, uio);
> > > > +	if (error == 0 && uio->uio_rw == UIO_WRITE) {
> > > > +		if (l->l_proc->p_stat != SSTOP)
> > > > +			error = EBUSY;
> > > 
> > > Isn't it supposed to always be the case?
> > 
> > To be honest, I've followed suit with all other getter-setters there.
> > I can't say if it's fail-safe that's never supposed to fire or if there
> > could be some mistaken use possible that would trigger this.
> 
> I don't see other places that do that. If it was needed there would be a
> race, because it doesn't seem to me we lock the proc, so what if the proc
> goes != SSTOP after the check.

I've copied it from process_machdep_doxmmregs()
in sys/arch/i386/i386/process_machdep.c.  I can remove it.  Should I
also remove the original occurrence?

> 
> > > > +	/* Copy MXCSR if either SSE or AVX state is requested */
> > > > +	if (xstate->xs_xstate_bv & (XCR0_SSE|XCR0_YMM_Hi128)) {
> > > > +		memcpy(&fpu_save->sv_xmm.fx_mxcsr, &xstate->xs_fxsave.fx_mxcsr, 8);
> > > > +
> > > > +		/*
> > > > +		 * Invalid bits in mxcsr or mxcsr_mask will cause faults.
> > > > +		 */
> > > > +		fpu_save->sv_xmm.fx_mxcsr_mask &= x86_fpu_mxcsr_mask;
> > > > +		fpu_save->sv_xmm.fx_mxcsr &= fpu_save->sv_xmm.fx_mxcsr_mask;
> > > 
> > > Please use a simple assignment instead of memcpy, and also filter out 'xstate'
> > > and not 'fpu_save'.
> > 
> > Will do.  Actually, simple assignment means I can filter it out while
> > assigning.
> > 
> > > Also, it would be nice to clarify the use case here. On x86, mxcsr gets reloaded
> > > *regardless* of whether xstate_bv contains SSE|AVX. Should the ptrace api also
> > > reload mxcsr regardless of whether the user requested SSE|AVX in xstate_bv?
> > 
> > I was following the Intel programmer's manual.  XRSTOR uses mxcsr either
> > if SSE or AVX is requested via EAX.
> 
> Yes, but EAX is the RFBM, not XSTATE_BV.

I agree I could use a better term here.  The idea is that it is a field
stating which of the components in other fields are present.

> 
> > > > +	}
> > > > +
> > > > +	/* Copy SSE state if requested. */
> > > > +	if (xstate->xs_xstate_bv & XCR0_SSE) {
> > > > +		if (x86_fpu_save >= FPU_SAVE_XSAVE) {
> > > > +			KASSERT(fpu_save->sv_xsave_hdr.xsh_xstate_bv & XCR0_SSE);
> > > 
> > > Mmh, maybe it is possible that this KASSERT fires, if the LWP hasn't used SSE.
> > 
> > I don't think that can actually happen with XSAVE.  I wouldn't be sure
> > with XSAVEOPT but we're not using it.
> > 
> > > In fact, what is the purpose?
> > 
> > The exact purpose is to verify that a request to write unsupported
> > component didn't get through process_verify_xstate().  It's an assert,
> > so it means to check for something-we-really-don't-expect-to-happen.
> 
> The KASSERT is on 'fpu_save', not 'xstate', so process_verify_xstate() doesn't
> play any role here. My point was: if the traced proc never used SSE, then
> hardware.xstate_bv[SSE]=0 (which means, the "init" state). And the KASSERT
> fires.

Hmm, you are correct.  I wrongly assumed the 0 value is specific to
XRSTOR but now I see that it can happen with XSAVE too.  In that case,
I suppose I should be forcing it to 1.

> A few other things:
> 
>   * In process_machdep_doxstate(), need to add a memset(&r, 0, sizeof(r));

I don't think this is strictly necessary.  The function unconditionally
calls process_machdep_read_xstate() which will overwrite at least
the header field.  The data that is not present according to header can
be unset, I think.

> 
>   * In process_write_xstate(), need to OR the xstate_bv in 'fpu_save' with
>     the xstate_bv in 'xstate', otherwise the next XRSTOR of the traced proc
>     may not install the registers correctly

Will do.

> 
>   * Is there any urgency in adding support for XSTATE in ptrace? Because I am
>     currently rewriting the FPU code entirely

Depends on how you define 'urgency'.  I can keep the patches local for
now but I'd prefer to have them committed so I could start depending
on the API in LLDB.  I'd also like to avoid having to rebase them long-
term.

>   * I think it would be easier if you hosted your patches online, because the
>     repeated threads make it hard to follow what's going on

I'm pushing my updates to 'xstate' branch on my GitHub src fork:

https://github.com/mgorny/netbsd-src/commits/xstate

-- 
Best regards,
Michał Górny

Attachment: signature.asc
Description: This is a digitally signed message part



Home | Main Index | Thread Index | Old Index