From: Borislav Petkov <bp@suse.de>
To: Thomas Gleixner <tglx@linutronix.de>
Cc: LKML <linux-kernel@vger.kernel.org>,
Andy Lutomirski <luto@kernel.org>,
Dave Hansen <dave.hansen@linux.intel.com>,
Fenghua Yu <fenghua.yu@intel.com>,
Tony Luck <tony.luck@intel.com>,
Yu-cheng Yu <yu-cheng.yu@intel.com>,
Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
Peter Zijlstra <peterz@infradead.org>,
Kan Liang <kan.liang@linux.intel.com>
Subject: Re: [patch V2 02/52] x86/fpu: Fix copy_xstate_to_kernel() gap handling
Date: Tue, 15 Jun 2021 13:07:55 +0200 [thread overview]
Message-ID: <YMiKC09GUaG5vZta@zn.tnic> (raw)
In-Reply-To: <20210614155353.825709513@linutronix.de>
On Mon, Jun 14, 2021 at 05:44:10PM +0200, Thomas Gleixner wrote:
> 2) Keeping track of the last copied state in the target buffer and
> explicitely zero it when there is a feature or alignment gap.
WARNING: 'explicitely' may be misspelled - perhaps 'explicitly'?
#93:
explicitely zero it when there is a feature or alignment gap.
^^^^^^^^^^^
> -static void fill_gap(struct membuf *to, unsigned *last, unsigned offset)
> +static void copy_feature(bool from_xstate, struct membuf *to, void *xstate,
> + void *init_xstate, unsigned int size)
> {
> - if (*last >= offset)
> - return;
> - membuf_write(to, (void *)&init_fpstate.xsave + *last, offset - *last);
> - *last = offset;
> -}
> -
> -static void copy_part(struct membuf *to, unsigned *last, unsigned offset,
> - unsigned size, void *from)
> -{
> - fill_gap(to, last, offset);
> - membuf_write(to, from, size);
> - *last = offset + size;
> + membuf_write(to, from_xstate ? xstate : init_xstate, size);
I wonder - since we're making this code more robust anyway - whether
we should add an additional assertion here to check whether that
membuf.left is < size and warn.
It is cheap and having an additional check here would probably catch
some ptrace insanity or so, who knows...
> @@ -1120,41 +1110,68 @@ void copy_xstate_to_kernel(struct membuf
> header.xfeatures = xsave->header.xfeatures;
> header.xfeatures &= xfeatures_mask_user();
>
> - if (header.xfeatures & XFEATURE_MASK_FP)
> - copy_part(&to, &last, 0, off_mxcsr, &xsave->i387);
> - if (header.xfeatures & (XFEATURE_MASK_SSE | XFEATURE_MASK_YMM))
> - copy_part(&to, &last, off_mxcsr,
> - MXCSR_AND_FLAGS_SIZE, &xsave->i387.mxcsr);
> - if (header.xfeatures & XFEATURE_MASK_FP)
> - copy_part(&to, &last, offsetof(struct fxregs_state, st_space),
> - 128, &xsave->i387.st_space);
> - if (header.xfeatures & XFEATURE_MASK_SSE)
> - copy_part(&to, &last, xstate_offsets[XFEATURE_SSE],
> - 256, &xsave->i387.xmm_space);
> - /*
> - * Fill xsave->i387.sw_reserved value for ptrace frame:
> - */
> - copy_part(&to, &last, offsetof(struct fxregs_state, sw_reserved),
> - 48, xstate_fx_sw_bytes);
> - /*
> - * Copy xregs_state->header:
> - */
> - copy_part(&to, &last, offsetof(struct xregs_state, header),
> - sizeof(header), &header);
> + /* Copy FP state up to MXCSR */
> + copy_feature(header.xfeatures & XFEATURE_MASK_FP, &to, &xsave->i387,
> + &xinit->i387, off_mxcsr);
> +
> + /* Copy MXCSR when SSE or YMM are set in the feature mask */
> + copy_feature(header.xfeatures & (XFEATURE_MASK_SSE | XFEATURE_MASK_YMM),
> + &to, &xsave->i387.mxcsr, &xinit->i387.mxcsr,
> + MXCSR_AND_FLAGS_SIZE);
Yah, this copies a whopping 8 bytes:
u32 mxcsr; /* MXCSR Register State */
u32 mxcsr_mask; /* MXCSR Mask */
I know, I know, it was like that before but dammit, that's obscure.
> + /* Copy the remaining FP state */
> + copy_feature(header.xfeatures & XFEATURE_MASK_FP,
> + &to, &xsave->i387.st_space, &xinit->i387.st_space,
> + sizeof(xsave->i387.st_space));
> +
> + /* Copy the SSE state - shared with YMM */
> + copy_feature(header.xfeatures & (XFEATURE_MASK_SSE | XFEATURE_MASK_YMM),
> + &to, &xsave->i387.xmm_space, &xinit->i387.xmm_space,
> + 16 * 16);
Why not
sizeof(xsave->i387.xmm_space)
?
> +
> + /* Zero the padding area */
> + membuf_zero(&to, sizeof(xsave->i387.padding));
> +
> + /* Copy xsave->i387.sw_reserved */
> + membuf_write(&to, xstate_fx_sw_bytes, sizeof(xsave->i387.sw_reserved));
> +
> + /* Copy the user space relevant state of @xsave->header */
> + membuf_write(&to, &header, sizeof(header));
> +
> + zerofrom = offsetof(struct xregs_state, extended_state_area);
>
> for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
> /*
> - * Copy only in-use xstates:
> + * The ptrace buffer is XSAVE format which is non-compacted.
... "is in XSAVE, non-compacted format."
> + * In non-compacted format disabled features still occupy
^ ^
the ,
> + * state space, but there is no state to copy from in the
> + * compacted init_fpstate. The gap tracking will zero this
> + * later.
> + */
> + if (!(xfeatures_mask_user() & BIT_ULL(i)))
> + continue;
> +
> + /*
> + * If there was a feature or alignment gap, zero the space
> + * in the destination buffer.
> */
> - if ((header.xfeatures >> i) & 1) {
> - void *src = __raw_xsave_addr(xsave, i);
> + if (zerofrom < xstate_offsets[i])
> + membuf_zero(&to, xstate_offsets[i] - zerofrom);
>
> - copy_part(&to, &last, xstate_offsets[i],
> - xstate_sizes[i], src);
> - }
> + copy_feature(header.xfeatures & BIT_ULL(i), &to,
> + __raw_xsave_addr(xsave, i),
> + __raw_xsave_addr(xinit, i),
> + xstate_sizes[i]);
>
> + /*
> + * Keep track of the last copied state in the non-compacted
> + * target buffer for gap zeroing.
> + */
> + zerofrom = xstate_offsets[i] + xstate_sizes[i];
> }
> - fill_gap(&to, &last, size);
> +
> + if (to.left)
> + membuf_zero(&to, to.left);
> }
Yah, I can certainly follow what's going on here but, mapping that
compacted buffer to the uncompacted, XSAVE one is certainly making my
head spin.
Yah, FPU state handling is nasty.
--
Regards/Gruss,
Boris.
SUSE Software Solutions Germany GmbH, GF: Felix Imendörffer, HRB 36809, AG Nürnberg
next prev parent reply other threads:[~2021-06-15 11:09 UTC|newest]
Thread overview: 87+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-06-14 15:44 [patch V2 00/52] x86/fpu: Spring cleaning and PKRU sanitizing Thomas Gleixner
2021-06-14 15:44 ` [patch V2 01/52] x86/fpu: Make init_fpstate correct with optimized XSAVE Thomas Gleixner
2021-06-14 19:15 ` Borislav Petkov
2021-06-14 15:44 ` [patch V2 02/52] x86/fpu: Fix copy_xstate_to_kernel() gap handling Thomas Gleixner
2021-06-15 11:07 ` Borislav Petkov [this message]
2021-06-15 12:47 ` Thomas Gleixner
2021-06-15 12:59 ` Borislav Petkov
2021-06-16 22:02 ` Thomas Gleixner
2021-06-14 15:44 ` [patch V2 03/52] x86/pkeys: Revert a5eff7259790 ("x86/pkeys: Add PKRU value to init_fpstate") Thomas Gleixner
2021-06-15 13:15 ` Borislav Petkov
2021-06-14 15:44 ` [patch V2 04/52] x86/fpu: Mark various FPU states __ro_after_init Thomas Gleixner
2021-06-14 15:44 ` [patch V2 05/52] x86/fpu: Remove unused get_xsave_field_ptr() Thomas Gleixner
2021-06-14 15:44 ` [patch V2 06/52] x86/fpu: Move inlines where they belong Thomas Gleixner
2021-06-14 15:44 ` [patch V2 07/52] x86/fpu: Limit xstate copy size in xstateregs_set() Thomas Gleixner
2021-06-14 15:44 ` [patch V2 08/52] x86/fpu: Sanitize xstateregs_set() Thomas Gleixner
2021-06-15 17:40 ` Borislav Petkov
2021-06-15 21:32 ` Thomas Gleixner
2021-06-14 15:44 ` [patch V2 09/52] x86/fpu: Reject invalid MXCSR values in copy_kernel_to_xstate() Thomas Gleixner
2021-06-16 15:02 ` Borislav Petkov
2021-06-16 23:51 ` Thomas Gleixner
2021-06-14 15:44 ` [patch V2 10/52] x86/fpu: Simplify PTRACE_GETREGS code Thomas Gleixner
2021-06-14 15:44 ` [patch V2 11/52] x86/fpu: Rewrite xfpregs_set() Thomas Gleixner
2021-06-16 15:22 ` Borislav Petkov
2021-06-14 15:44 ` [patch V2 12/52] x86/fpu: Fail ptrace() requests that try to set invalid MXCSR values Thomas Gleixner
2021-06-16 15:31 ` Borislav Petkov
2021-06-14 15:44 ` [patch V2 13/52] x86/fpu: Clean up fpregs_set() Thomas Gleixner
2021-06-16 15:42 ` Borislav Petkov
2021-06-14 15:44 ` [patch V2 14/52] x86/fpu: Make copy_xstate_to_kernel() usable for [x]fpregs_get() Thomas Gleixner
2021-06-16 16:13 ` Borislav Petkov
2021-06-17 12:42 ` Thomas Gleixner
2021-06-14 15:44 ` [patch V2 15/52] x86/fpu: Use copy_uabi_xstate_to_membuf() in xfpregs_get() Thomas Gleixner
2021-06-17 8:59 ` Borislav Petkov
2021-06-18 11:19 ` Borislav Petkov
2021-06-18 13:25 ` [PATCH] selftests/x86/ptrace_syscall: Add a PTRACE_GETFPREGS test Borislav Petkov
2021-06-14 15:44 ` [patch V2 16/52] x86/fpu: Use copy_uabi_xstate_to_membuf() in fpregs_get() Thomas Gleixner
2021-06-17 11:50 ` Borislav Petkov
2021-06-17 12:43 ` Thomas Gleixner
2021-06-14 15:44 ` [patch V2 17/52] x86/fpu: Remove fpstate_sanitize_xstate() Thomas Gleixner
2021-06-14 15:44 ` [patch V2 18/52] x86/fpu: Get rid of using_compacted_format() Thomas Gleixner
2021-06-17 11:59 ` Borislav Petkov
2021-06-14 15:44 ` [patch V2 19/52] x86/kvm: Avoid looking up PKRU in XSAVE buffer Thomas Gleixner
2021-06-17 12:09 ` Borislav Petkov
2021-06-14 15:44 ` [patch V2 20/52] x86/fpu: Cleanup arch_set_user_pkey_access() Thomas Gleixner
2021-06-17 12:22 ` Borislav Petkov
2021-06-17 12:49 ` Thomas Gleixner
2021-06-14 15:44 ` [patch V2 21/52] x86/fpu: Get rid of copy_supervisor_to_kernel() Thomas Gleixner
2021-06-17 12:41 ` Borislav Petkov
2021-06-14 15:44 ` [patch V2 22/52] x86/fpu: Rename copy_xregs_to_kernel() and copy_kernel_to_xregs() Thomas Gleixner
2021-06-17 12:48 ` Borislav Petkov
2021-06-14 15:44 ` [patch V2 23/52] x86/fpu: Rename copy_user_to_xregs() and copy_xregs_to_user() Thomas Gleixner
2021-06-14 15:44 ` [patch V2 24/52] x86/fpu: Rename fxregs related copy functions Thomas Gleixner
2021-06-14 15:44 ` [patch V2 25/52] x86/fpu: Rename fregs " Thomas Gleixner
2021-06-14 15:44 ` [patch V2 26/52] x86/fpu: Rename xstate copy functions which are related to UABI Thomas Gleixner
2021-06-14 15:44 ` [patch V2 27/52] x86/fpu: Deduplicate copy_uabi_from_user/kernel_to_xstate() Thomas Gleixner
2021-06-14 15:44 ` [patch V2 28/52] x86/fpu: Rename copy_fpregs_to_fpstate() to save_fpregs_to_fpstate() Thomas Gleixner
2021-06-14 15:44 ` [patch V2 29/52] x86/fpu: Rename copy_kernel_to_fpregs() to restore_fpregs_from_kernel() Thomas Gleixner
2021-06-14 15:44 ` [patch V2 30/52] x86/fpu: Rename initstate copy functions Thomas Gleixner
2021-06-14 15:44 ` [patch V2 31/52] x86/fpu: Rename "dynamic" XSTATEs to "independent" Thomas Gleixner
2021-06-14 15:44 ` [patch V2 32/52] x86/fpu/xstate: Sanitize handling of independent features Thomas Gleixner
2021-06-16 20:04 ` Liang, Kan
2021-06-17 7:15 ` Thomas Gleixner
2021-06-14 15:44 ` [patch V2 33/52] x86/pkeys: Move read_pkru() and write_pkru() Thomas Gleixner
2021-06-14 15:44 ` [patch V2 34/52] x86/fpu: Differentiate "copy" versus "move" of fpregs Thomas Gleixner
2021-06-18 12:21 ` Thomas Gleixner
2021-06-14 15:44 ` [patch V2 35/52] x86/cpu: Sanitize X86_FEATURE_OSPKE Thomas Gleixner
2021-06-14 15:44 ` [patch V2 36/52] x86/pkru: Provide pkru_get_init_value() Thomas Gleixner
2021-06-14 15:44 ` [patch V2 37/52] x86/pkru: Provide pkru_write_default() Thomas Gleixner
2021-06-14 15:44 ` [patch V2 38/52] x86/cpu: Write the default PKRU value when enabling PKE Thomas Gleixner
2021-06-14 15:44 ` [patch V2 39/52] x86/fpu: Use pkru_write_default() in copy_init_fpstate_to_fpregs() Thomas Gleixner
2021-06-14 15:44 ` [patch V2 40/52] x86/fpu: Rename fpu__clear_all() to fpu_flush_thread() Thomas Gleixner
2021-06-14 15:44 ` [patch V2 41/52] x86/fpu: Clean up the fpu__clear() variants Thomas Gleixner
2021-06-14 15:44 ` [patch V2 42/52] x86/fpu: Rename __fpregs_load_activate() to fpregs_restore_userregs() Thomas Gleixner
2021-06-14 15:44 ` [patch V2 43/52] x86/fpu: Move FXSAVE_LEAK quirk info __copy_kernel_to_fpregs() Thomas Gleixner
2021-06-14 15:44 ` [patch V2 44/52] x86/fpu: Rename xfeatures_mask_user() to xfeatures_mask_uabi() Thomas Gleixner
2021-06-14 15:44 ` [patch V2 45/52] x86/fpu: Dont restore PKRU in fpregs_restore_userspace() Thomas Gleixner
2021-06-16 0:52 ` Yu, Yu-cheng
2021-06-16 8:56 ` Thomas Gleixner
2021-06-14 15:44 ` [patch V2 46/52] x86/fpu: Add PKRU storage outside of task XSAVE buffer Thomas Gleixner
2021-06-14 15:44 ` [patch V2 47/52] x86/fpu: Hook up PKRU into ptrace() Thomas Gleixner
2021-06-14 19:29 ` [patch V2-A " Thomas Gleixner
2021-06-14 15:44 ` [patch V2 48/52] x86/fpu: Mask PKRU from kernel XRSTOR[S] operations Thomas Gleixner
2021-06-14 15:44 ` [patch V2 49/52] x86/fpu: Remove PKRU handling from switch_fpu_finish() Thomas Gleixner
2021-06-14 15:44 ` [patch V2 50/52] x86/fpu: Dont store PKRU in xstate in fpu_reset_fpstate() Thomas Gleixner
2021-06-14 15:44 ` [patch V2 51/52] x86/pkru: Remove xstate fiddling from write_pkru() Thomas Gleixner
2021-06-14 15:45 ` [patch V2 52/52] x86/fpu: Mark init_fpstate __ro_after_init Thomas Gleixner
2021-06-14 20:15 ` [patch] x86/fpu: x86/fpu: Preserve supervisor states in sanitize_restored_user_xstate() Thomas Gleixner
2021-06-16 0:50 ` [patch V2 00/52] x86/fpu: Spring cleaning and PKRU sanitizing Yu, Yu-cheng
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=YMiKC09GUaG5vZta@zn.tnic \
--to=bp@suse.de \
--cc=bigeasy@linutronix.de \
--cc=dave.hansen@linux.intel.com \
--cc=fenghua.yu@intel.com \
--cc=kan.liang@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
--cc=tony.luck@intel.com \
--cc=yu-cheng.yu@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox