[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20211001223728.9309-13-chang.seok.bae@intel.com>
Date: Fri, 1 Oct 2021 15:37:11 -0700
From: "Chang S. Bae" <chang.seok.bae@...el.com>
To: bp@...e.de, luto@...nel.org, tglx@...utronix.de, mingo@...nel.org,
x86@...nel.org
Cc: len.brown@...el.com, lenb@...nel.org, dave.hansen@...el.com,
thiago.macieira@...el.com, jing2.liu@...el.com,
ravi.v.shankar@...el.com, linux-kernel@...r.kernel.org,
chang.seok.bae@...el.com
Subject: [PATCH v11 12/29] x86/fpu/xstate: Update the XSTATE context copy function to support dynamic states
ptrace() and signal return paths use XSTATE context copy functions. They
allow callers to read XSTATE values in the target's buffer. With dynamic
user states, a component's position in the buffer may vary and the init
fpstate is not always large enough to cover all the states.
Introduce a new helper to adjust to find the source address correctly.
Signed-off-by: Chang S. Bae <chang.seok.bae@...el.com>
Reviewed-by: Len Brown <len.brown@...el.com>
Cc: x86@...nel.org
Cc: linux-kernel@...r.kernel.org
---
Changes from v9:
* Refactor the new code in the loop. (Borislav Petkov)
* Move out the copy_uabi_to_xstate() changes (to Patch1,9). (Borislav
Petkov)
Changes from v5:
* Updated to ensure xstate_bv aligned with the target.
* Rewrote the xstate copy loop, for the ptrace() read path, in an open
code.
* Adjusted the changelog.
Changes from v3:
* Cleaned up the code change with more comments.
* Removed 'no functional change' in the changelog. (Borislav Petkov)
Changes from v2:
* Updated the changelog with task->fpu removed. (Borislav Petkov)
---
arch/x86/kernel/fpu/xstate.c | 29 +++++++++++++++++++++++++----
1 file changed, 25 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index 2cb0d8c2eeeb..34cd131f5476 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -1153,6 +1153,30 @@ static void copy_feature(bool from_xstate, struct membuf *to, void *xstate,
membuf_write(to, from_xstate ? xstate : init_xstate, size);
}
+static void copy_extended_feature(struct membuf *to, struct fpu *fpu,
+ struct xstate_header *hdr,
+ int feature_nr)
+{
+ unsigned int size = xstate_sizes[feature_nr];
+ u64 mask = BIT_ULL(feature_nr);
+ void *from = NULL;
+
+ /*
+ * Copy from the XSTATE buffer if available. Otherwise, write the
+ * init value as recorded for legacy states (FP and SSE) or as
+ * zeros for others.
+ */
+ if (hdr->xfeatures & mask) {
+ from = __raw_xsave_addr(fpu, feature_nr);
+ membuf_write(to, from, size);
+ } else if (XFEATURE_MASK_FPSSE & mask) {
+ from = __raw_xsave_addr(NULL, feature_nr);
+ membuf_write(to, from, size);
+ } else {
+ membuf_zero(to, size);
+ }
+}
+
/**
* copy_xstate_to_uabi_buf - Copy kernel saved xstate to a UABI buffer
* @to: membuf descriptor
@@ -1254,10 +1278,7 @@ void copy_xstate_to_uabi_buf(struct membuf to, struct task_struct *tsk,
pkru.pkru = tsk->thread.pkru;
membuf_write(&to, &pkru, sizeof(pkru));
} else {
- copy_feature(header.xfeatures & BIT_ULL(i), &to,
- __raw_xsave_addr(&tsk->thread.fpu, i),
- __raw_xsave_addr(NULL, i),
- xstate_sizes[i]);
+ copy_extended_feature(&to, &tsk->thread.fpu, &header, i);
}
/*
* Keep track of the last copied state in the non-compacted
--
2.17.1
Powered by blists - more mailing lists