Messages in this thread Patch in this message | | | From | "Chang S. Bae" <> | Subject | [PATCH v2 15/22] x86/fpu/xstate: Support ptracer-induced xstate area expansion | Date | Thu, 19 Nov 2020 15:32:50 -0800 |
| |
ptrace() may request an update to task->fpu that has not yet been allocated. Detect this case and allocate task->fpu to support the request. Also, disable the (now unnecessary) associated first-use fault.
No functional change until the kernel supports dynamic user states.
Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com> Reviewed-by: Len Brown <len.brown@intel.com> Cc: x86@kernel.org Cc: linux-kernel@vger.kernel.org --- arch/x86/kernel/fpu/regset.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
diff --git a/arch/x86/kernel/fpu/regset.c b/arch/x86/kernel/fpu/regset.c index 8d863240b9c6..6b9d0c0a266d 100644 --- a/arch/x86/kernel/fpu/regset.c +++ b/arch/x86/kernel/fpu/regset.c @@ -125,6 +125,35 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset, xsave = __xsave(fpu); + /* + * When a ptracer attempts to write any state in task->fpu but not allocated, + * it dynamically expands the xstate area of fpu->state_ptr. + */ + if (count > get_xstate_size(fpu->state_mask)) { + unsigned int offset, size; + struct xstate_header hdr; + u64 mask; + + offset = offsetof(struct xregs_state, header); + size = sizeof(hdr); + + /* Retrieve XSTATE_BV */ + if (kbuf) { + memcpy(&hdr, kbuf + offset, size); + } else { + ret = __copy_from_user(&hdr, ubuf + offset, size); + if (ret) + return ret; + } + + mask = hdr.xfeatures & xfeatures_mask_user_dynamic; + if (!mask) { + ret = alloc_xstate_area(fpu, mask, NULL); + if (ret) + return ret; + } + } + fpu__prepare_write(fpu); if (using_compacted_format()) { -- 2.17.1
| |