From: Dave Hansen <dave@sr71.net>
To: linux-kernel@vger.kernel.org
Cc: x86@kernel.org, tglx@linutronix.de, Dave Hansen <dave@sr71.net>,
dave.hansen@linux.intel.com, oleg@redhat.com, bp@alien8.de,
riel@redhat.com, sbsiddha@gmail.com, luto@amacapital.net,
mingo@redhat.com, hpa@zytor.com, fenghua.yu@intel.com
Subject: [PATCH 03/19] x86, mpx: use new tsk_get_xsave_addr()
Date: Fri, 08 May 2015 11:59:49 -0700 [thread overview]
Message-ID: <20150508185949.3250100D@viggo.jf.intel.com> (raw)
In-Reply-To: <20150508185948.4C19F4B0@viggo.jf.intel.com>
From: Dave Hansen <dave.hansen@linux.intel.com>
The MPX registers (bndcsr/bndcfgu/bndstatus) are not directly
accessible via normal instructions. They essentially act as
if they were floating point registers and are saved/restored
along with those registers.
There are two main paths in the MPX code where we care about
the contents of these registers:
1. #BR (bounds) faults
2. the prctl() code where we are setting MPX up
Both of those paths _might_ be called without the FPU having
been used. That means that 'tsk->thread.fpu.state' might
never be allocated.
Also, fpu_save_init() is not preempt-safe. It was a bug to
call it without disabling preemption. The new
tsk_get_xsave_addr() calls unlazy_fpu() instead and properly
disables preemption.
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: bp@alien8.de
Cc: Rik van Riel <riel@redhat.com>
Cc: Suresh Siddha <sbsiddha@gmail.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: the arch/x86 maintainers <x86@kernel.org>
Cc: linux-kernel <linux-kernel@vger.kernel.org>
---
b/arch/x86/include/asm/mpx.h | 8 ++++----
b/arch/x86/kernel/traps.c | 15 +++++++--------
b/arch/x86/mm/mpx.c | 23 +++++++++++------------
3 files changed, 22 insertions(+), 24 deletions(-)
diff -puN arch/x86/include/asm/mpx.h~use-new-tsk_get_xsave_addr arch/x86/include/asm/mpx.h
--- a/arch/x86/include/asm/mpx.h~use-new-tsk_get_xsave_addr 2015-05-08 11:46:11.385599446 -0700
+++ b/arch/x86/include/asm/mpx.h 2015-05-08 11:46:11.392599762 -0700
@@ -60,8 +60,8 @@
#ifdef CONFIG_X86_INTEL_MPX
siginfo_t *mpx_generate_siginfo(struct pt_regs *regs,
- struct xsave_struct *xsave_buf);
-int mpx_handle_bd_fault(struct xsave_struct *xsave_buf);
+ struct task_struct *tsk);
+int mpx_handle_bd_fault(struct task_struct *tsk);
static inline int kernel_managing_mpx_tables(struct mm_struct *mm)
{
return (mm->bd_addr != MPX_INVALID_BOUNDS_DIR);
@@ -78,11 +78,11 @@ void mpx_notify_unmap(struct mm_struct *
unsigned long start, unsigned long end);
#else
static inline siginfo_t *mpx_generate_siginfo(struct pt_regs *regs,
- struct xsave_struct *xsave_buf)
+ struct task_struct *tsk)
{
return NULL;
}
-static inline int mpx_handle_bd_fault(struct xsave_struct *xsave_buf)
+static inline int mpx_handle_bd_fault(struct task_struct *tsk)
{
return -EINVAL;
}
diff -puN arch/x86/kernel/traps.c~use-new-tsk_get_xsave_addr arch/x86/kernel/traps.c
--- a/arch/x86/kernel/traps.c~use-new-tsk_get_xsave_addr 2015-05-08 11:46:11.387599536 -0700
+++ b/arch/x86/kernel/traps.c 2015-05-08 11:46:11.392599762 -0700
@@ -61,6 +61,7 @@
#include <asm/mach_traps.h>
#include <asm/alternative.h>
#include <asm/mpx.h>
+#include <asm/xsave.h>
#ifdef CONFIG_X86_64
#include <asm/x86_init.h>
@@ -372,7 +373,6 @@ dotraplinkage void do_double_fault(struc
dotraplinkage void do_bounds(struct pt_regs *regs, long error_code)
{
struct task_struct *tsk = current;
- struct xsave_struct *xsave_buf;
enum ctx_state prev_state;
struct bndcsr *bndcsr;
siginfo_t *info;
@@ -393,12 +393,11 @@ dotraplinkage void do_bounds(struct pt_r
/*
* We need to look at BNDSTATUS to resolve this exception.
- * It is not directly accessible, though, so we need to
- * do an xsave and then pull it out of the xsave buffer.
+ * A NULL here might mean that it is in its 'init state',
+ * which is all zeros which indicates MPX was not
+ * responsible for the exception.
*/
- fpu_save_init(&tsk->thread.fpu);
- xsave_buf = &(tsk->thread.fpu.state->xsave);
- bndcsr = get_xsave_addr(xsave_buf, XSTATE_BNDCSR);
+ bndcsr = get_xsave_field(XSTATE_BNDCSR);
if (!bndcsr)
goto exit_trap;
@@ -409,11 +408,11 @@ dotraplinkage void do_bounds(struct pt_r
*/
switch (bndcsr->bndstatus & MPX_BNDSTA_ERROR_CODE) {
case 2: /* Bound directory has invalid entry. */
- if (mpx_handle_bd_fault(xsave_buf))
+ if (mpx_handle_bd_fault(tsk))
goto exit_trap;
break; /* Success, it was handled */
case 1: /* Bound violation. */
- info = mpx_generate_siginfo(regs, xsave_buf);
+ info = mpx_generate_siginfo(regs, tsk);
if (IS_ERR(info)) {
/*
* We failed to decode the MPX instruction. Act as if
diff -puN arch/x86/mm/mpx.c~use-new-tsk_get_xsave_addr arch/x86/mm/mpx.c
--- a/arch/x86/mm/mpx.c~use-new-tsk_get_xsave_addr 2015-05-08 11:46:11.388599581 -0700
+++ b/arch/x86/mm/mpx.c 2015-05-08 11:46:11.393599807 -0700
@@ -273,7 +273,7 @@ bad_opcode:
* The caller is expected to kfree() the returned siginfo_t.
*/
siginfo_t *mpx_generate_siginfo(struct pt_regs *regs,
- struct xsave_struct *xsave_buf)
+ struct task_struct *tsk)
{
struct bndreg *bndregs, *bndreg;
siginfo_t *info = NULL;
@@ -295,8 +295,8 @@ siginfo_t *mpx_generate_siginfo(struct p
err = -EINVAL;
goto err_out;
}
- /* get the bndregs _area_ of the xsave structure */
- bndregs = get_xsave_addr(xsave_buf, XSTATE_BNDREGS);
+ /* get bndregs field from urrent task's xsave area */
+ bndregs = get_xsave_field(XSTATE_BNDREGS);
if (!bndregs) {
err = -EINVAL;
goto err_out;
@@ -358,8 +358,7 @@ static __user void *task_get_bounds_dir(
* The bounds directory pointer is stored in a register
* only accessible if we first do an xsave.
*/
- fpu_save_init(&tsk->thread.fpu);
- bndcsr = get_xsave_addr(&tsk->thread.fpu.state->xsave, XSTATE_BNDCSR);
+ bndcsr = get_xsave_field(XSTATE_BNDCSR);
if (!bndcsr)
return MPX_INVALID_BOUNDS_DIR;
@@ -390,9 +389,9 @@ int mpx_enable_management(struct task_st
* directory into XSAVE/XRSTOR Save Area and enable MPX through
* XRSTOR instruction.
*
- * fpu_xsave() is expected to be very expensive. Storing the bounds
- * directory here means that we do not have to do xsave in the unmap
- * path; we can just use mm->bd_addr instead.
+ * xsaves are expected to be very expensive. Storing the bounds
+ * directory here means that we do not have to do xsave in the
+ * unmap path; we can just use mm->bd_addr instead.
*/
bd_base = task_get_bounds_dir(tsk);
down_write(&mm->mmap_sem);
@@ -498,12 +497,12 @@ out_unmap:
* bound table is 16KB. With 64-bit mode, the size of BD is 2GB,
* and the size of each bound table is 4MB.
*/
-static int do_mpx_bt_fault(struct xsave_struct *xsave_buf)
+static int do_mpx_bt_fault(struct task_struct *tsk)
{
unsigned long bd_entry, bd_base;
struct bndcsr *bndcsr;
- bndcsr = get_xsave_addr(xsave_buf, XSTATE_BNDCSR);
+ bndcsr = get_xsave_field(XSTATE_BNDCSR);
if (!bndcsr)
return -EINVAL;
/*
@@ -526,7 +525,7 @@ static int do_mpx_bt_fault(struct xsave_
return allocate_bt((long __user *)bd_entry);
}
-int mpx_handle_bd_fault(struct xsave_struct *xsave_buf)
+int mpx_handle_bd_fault(struct task_struct *tsk)
{
/*
* Userspace never asked us to manage the bounds tables,
@@ -535,7 +534,7 @@ int mpx_handle_bd_fault(struct xsave_str
if (!kernel_managing_mpx_tables(current->mm))
return -EINVAL;
- if (do_mpx_bt_fault(xsave_buf)) {
+ if (do_mpx_bt_fault(tsk)) {
force_sig(SIGSEGV, current);
/*
* The force_sig() is essentially "handling" this
_
next prev parent reply other threads:[~2015-05-08 18:59 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-08 18:59 [PATCH 00/19] x86, mpx updates for 4.2 (take 6) Dave Hansen
2015-05-08 18:59 ` [PATCH 01/19] x86, mpx, xsave: fix up bad get_xsave_addr() assumptions Dave Hansen
2015-05-18 19:34 ` Thomas Gleixner
2015-05-08 18:59 ` Dave Hansen [this message]
2015-05-18 20:36 ` [PATCH 03/19] x86, mpx: use new tsk_get_xsave_addr() Thomas Gleixner
2015-05-19 0:01 ` Dave Hansen
2015-05-08 18:59 ` [PATCH 02/19] x86, fpu: wrap get_xsave_addr() to make it safer Dave Hansen
2015-05-18 19:38 ` Thomas Gleixner
2015-05-18 19:42 ` Thomas Gleixner
2015-05-08 18:59 ` [PATCH 05/19] x86, mpx: remove redundant MPX_BNDCFG_ADDR_MASK Dave Hansen
2015-05-18 20:38 ` Thomas Gleixner
2015-05-08 18:59 ` [PATCH 04/19] x86, mpx: cleanup: do not pass task around when unnecessary Dave Hansen
2015-05-18 20:38 ` Thomas Gleixner
2015-05-08 18:59 ` [PATCH 06/19] x86, mpx: we do not allocate the bounds directory Dave Hansen
2015-05-18 20:43 ` Thomas Gleixner
2015-05-08 18:59 ` [PATCH 07/19] x86, mpx: boot-time disable Dave Hansen
2015-05-18 20:45 ` Thomas Gleixner
2015-05-08 18:59 ` [PATCH 08/19] x86, mpx: trace #BR exceptions Dave Hansen
2015-05-18 21:00 ` Thomas Gleixner
2015-05-08 18:59 ` [PATCH 10/19] x86, mpx: trace ranged MPX operations Dave Hansen
2015-05-18 21:04 ` Thomas Gleixner
2015-05-08 18:59 ` [PATCH 09/19] x86, mpx: trace entry to bounds exception paths Dave Hansen
2015-05-18 20:58 ` Thomas Gleixner
2015-05-18 23:06 ` Dave Hansen
2015-05-18 23:35 ` Thomas Gleixner
2015-05-08 18:59 ` [PATCH 11/19] x86, mpx: trace allocation of new bounds tables Dave Hansen
2015-05-18 21:04 ` Thomas Gleixner
2015-05-08 18:59 ` [PATCH 12/19] x86: make is_64bit_mm() widely available Dave Hansen
2015-05-18 21:06 ` Thomas Gleixner
2015-05-08 18:59 ` [PATCH 14/19] x86, mpx: new directory entry to addr helper Dave Hansen
2015-05-18 21:10 ` Thomas Gleixner
2015-05-08 18:59 ` [PATCH 13/19] x86, mpx: Add temporary variable to reduce masking Dave Hansen
2015-05-18 21:07 ` Thomas Gleixner
2015-05-08 18:59 ` [PATCH 16/19] x86, mpx: support 32-bit binaries on 64-bit kernel Dave Hansen
2015-05-18 21:53 ` Thomas Gleixner
2015-05-18 23:29 ` Dave Hansen
2015-05-18 23:37 ` Thomas Gleixner
2015-05-08 18:59 ` [PATCH 15/19] x86, mpx: do 32-bit-only cmpxchg for 32-bit apps Dave Hansen
2015-05-18 21:22 ` Thomas Gleixner
2015-05-08 18:59 ` [PATCH 18/19] x86, mpx: do not count MPX VMAs as neighbors when unmapping Dave Hansen
2015-05-18 21:54 ` Thomas Gleixner
2015-05-08 18:59 ` [PATCH 17/19] x86, mpx: rewrite unmap code Dave Hansen
2015-05-18 21:55 ` Thomas Gleixner
2015-05-08 18:59 ` [PATCH 19/19] x86, mpx: allow mixed binaries again Dave Hansen
2015-05-18 21:55 ` Thomas Gleixner
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=20150508185949.3250100D@viggo.jf.intel.com \
--to=dave@sr71.net \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=fenghua.yu@intel.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@amacapital.net \
--cc=mingo@redhat.com \
--cc=oleg@redhat.com \
--cc=riel@redhat.com \
--cc=sbsiddha@gmail.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.