|
@@ -272,9 +272,9 @@ bad_opcode:
|
|
|
* The caller is expected to kfree() the returned siginfo_t.
|
|
|
*/
|
|
|
siginfo_t *mpx_generate_siginfo(struct pt_regs *regs,
|
|
|
- struct xregs_state *xsave_buf)
|
|
|
+ struct task_struct *tsk)
|
|
|
{
|
|
|
- struct bndreg *bndregs, *bndreg;
|
|
|
+ const struct bndreg *bndregs, *bndreg;
|
|
|
siginfo_t *info = NULL;
|
|
|
struct insn insn;
|
|
|
uint8_t bndregno;
|
|
@@ -294,8 +294,8 @@ siginfo_t *mpx_generate_siginfo(struct pt_regs *regs,
|
|
|
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 current task's xsave area */
|
|
|
+ bndregs = get_xsave_field_ptr(XSTATE_BNDREGS);
|
|
|
if (!bndregs) {
|
|
|
err = -EINVAL;
|
|
|
goto err_out;
|
|
@@ -342,7 +342,7 @@ err_out:
|
|
|
|
|
|
static __user void *task_get_bounds_dir(struct task_struct *tsk)
|
|
|
{
|
|
|
- struct bndcsr *bndcsr;
|
|
|
+ const struct bndcsr *bndcsr;
|
|
|
|
|
|
if (!cpu_feature_enabled(X86_FEATURE_MPX))
|
|
|
return MPX_INVALID_BOUNDS_DIR;
|
|
@@ -357,8 +357,7 @@ static __user void *task_get_bounds_dir(struct task_struct *tsk)
|
|
|
* The bounds directory pointer is stored in a register
|
|
|
* only accessible if we first do an xsave.
|
|
|
*/
|
|
|
- copy_fpregs_to_fpstate(&tsk->thread.fpu);
|
|
|
- bndcsr = get_xsave_addr(&tsk->thread.fpu.state.xsave, XSTATE_BNDCSR);
|
|
|
+ bndcsr = get_xsave_field_ptr(XSTATE_BNDCSR);
|
|
|
if (!bndcsr)
|
|
|
return MPX_INVALID_BOUNDS_DIR;
|
|
|
|
|
@@ -389,9 +388,10 @@ int mpx_enable_management(struct task_struct *tsk)
|
|
|
* directory into XSAVE/XRSTOR Save Area and enable MPX through
|
|
|
* XRSTOR instruction.
|
|
|
*
|
|
|
- * copy_xregs_to_kernel() 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.
|
|
|
+ * The copy_xregs_to_kernel() beneath get_xsave_field_ptr() is
|
|
|
+ * expected to be relatively 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);
|
|
@@ -497,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 xregs_state *xsave_buf)
|
|
|
+static int do_mpx_bt_fault(struct task_struct *tsk)
|
|
|
{
|
|
|
unsigned long bd_entry, bd_base;
|
|
|
- struct bndcsr *bndcsr;
|
|
|
+ const struct bndcsr *bndcsr;
|
|
|
|
|
|
- bndcsr = get_xsave_addr(xsave_buf, XSTATE_BNDCSR);
|
|
|
+ bndcsr = get_xsave_field_ptr(XSTATE_BNDCSR);
|
|
|
if (!bndcsr)
|
|
|
return -EINVAL;
|
|
|
/*
|
|
@@ -525,7 +525,7 @@ static int do_mpx_bt_fault(struct xregs_state *xsave_buf)
|
|
|
return allocate_bt((long __user *)bd_entry);
|
|
|
}
|
|
|
|
|
|
-int mpx_handle_bd_fault(struct xregs_state *xsave_buf)
|
|
|
+int mpx_handle_bd_fault(struct task_struct *tsk)
|
|
|
{
|
|
|
/*
|
|
|
* Userspace never asked us to manage the bounds tables,
|
|
@@ -534,7 +534,7 @@ int mpx_handle_bd_fault(struct xregs_state *xsave_buf)
|
|
|
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
|