aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Hansen <dave.hansen@linux.intel.com>2015-06-07 14:37:04 -0400
committerIngo Molnar <mingo@kernel.org>2015-06-09 06:24:33 -0400
commit54587653904c552c56b9dec153d7a89063394b09 (patch)
tree4de02a9b75978d004e1dd800c1d37be6f3d5c499
parenta1149fc83a1f97612e72ec24a0bdbabff7b85e77 (diff)
x86/mpx: Introduce new 'directory entry' to 'addr' helper function
Currently, to get from a bounds directory entry to the virtual address of a bounds table, we simply mask off a few low bits. However, the set of bits we mask off is different for 32-bit and 64-bit binaries. This breaks the operation out in to a helper function and also adds a temporary variable to store the result until we are sure we are returning one. Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Reviewed-by: Thomas Gleixner <tglx@linutronix.de> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Dave Hansen <dave@sr71.net> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/20150607183704.007686CE@viggo.jf.intel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/include/asm/mpx.h1
-rw-r--r--arch/x86/mm/mpx.c41
2 files changed, 34 insertions, 8 deletions
diff --git a/arch/x86/include/asm/mpx.h b/arch/x86/include/asm/mpx.h
index 871e5e5b0499..99d374eb7b08 100644
--- a/arch/x86/include/asm/mpx.h
+++ b/arch/x86/include/asm/mpx.h
@@ -45,7 +45,6 @@
45#define MPX_BNDSTA_TAIL 2 45#define MPX_BNDSTA_TAIL 2
46#define MPX_BNDCFG_TAIL 12 46#define MPX_BNDCFG_TAIL 12
47#define MPX_BNDSTA_ADDR_MASK (~((1UL<<MPX_BNDSTA_TAIL)-1)) 47#define MPX_BNDSTA_ADDR_MASK (~((1UL<<MPX_BNDSTA_TAIL)-1))
48#define MPX_BT_ADDR_MASK (~((1UL<<MPX_BD_ENTRY_TAIL)-1))
49 48
50#define MPX_BNDCFG_ADDR_MASK (~((1UL<<MPX_BNDCFG_TAIL)-1)) 49#define MPX_BNDCFG_ADDR_MASK (~((1UL<<MPX_BNDCFG_TAIL)-1))
51#define MPX_BNDSTA_ERROR_CODE 0x3 50#define MPX_BNDSTA_ERROR_CODE 0x3
diff --git a/arch/x86/mm/mpx.c b/arch/x86/mm/mpx.c
index 4f7fb7c233cc..8cc793479039 100644
--- a/arch/x86/mm/mpx.c
+++ b/arch/x86/mm/mpx.c
@@ -576,29 +576,55 @@ static int mpx_resolve_fault(long __user *addr, int write)
576 return 0; 576 return 0;
577} 577}
578 578
579static unsigned long mpx_bd_entry_to_bt_addr(struct mm_struct *mm,
580 unsigned long bd_entry)
581{
582 unsigned long bt_addr = bd_entry;
583 int align_to_bytes;
584 /*
585 * Bit 0 in a bt_entry is always the valid bit.
586 */
587 bt_addr &= ~MPX_BD_ENTRY_VALID_FLAG;
588 /*
589 * Tables are naturally aligned at 8-byte boundaries
590 * on 64-bit and 4-byte boundaries on 32-bit. The
591 * documentation makes it appear that the low bits
592 * are ignored by the hardware, so we do the same.
593 */
594 if (is_64bit_mm(mm))
595 align_to_bytes = 8;
596 else
597 align_to_bytes = 4;
598 bt_addr &= ~(align_to_bytes-1);
599 return bt_addr;
600}
601
579/* 602/*
580 * Get the base of bounds tables pointed by specific bounds 603 * Get the base of bounds tables pointed by specific bounds
581 * directory entry. 604 * directory entry.
582 */ 605 */
583static int get_bt_addr(struct mm_struct *mm, 606static int get_bt_addr(struct mm_struct *mm,
584 long __user *bd_entry, unsigned long *bt_addr) 607 long __user *bd_entry_ptr,
608 unsigned long *bt_addr_result)
585{ 609{
586 int ret; 610 int ret;
587 int valid_bit; 611 int valid_bit;
612 unsigned long bd_entry;
613 unsigned long bt_addr;
588 614
589 if (!access_ok(VERIFY_READ, (bd_entry), sizeof(*bd_entry))) 615 if (!access_ok(VERIFY_READ, (bd_entry_ptr), sizeof(*bd_entry_ptr)))
590 return -EFAULT; 616 return -EFAULT;
591 617
592 while (1) { 618 while (1) {
593 int need_write = 0; 619 int need_write = 0;
594 620
595 pagefault_disable(); 621 pagefault_disable();
596 ret = get_user(*bt_addr, bd_entry); 622 ret = get_user(bd_entry, bd_entry_ptr);
597 pagefault_enable(); 623 pagefault_enable();
598 if (!ret) 624 if (!ret)
599 break; 625 break;
600 if (ret == -EFAULT) 626 if (ret == -EFAULT)
601 ret = mpx_resolve_fault(bd_entry, need_write); 627 ret = mpx_resolve_fault(bd_entry_ptr, need_write);
602 /* 628 /*
603 * If we could not resolve the fault, consider it 629 * If we could not resolve the fault, consider it
604 * userspace's fault and error out. 630 * userspace's fault and error out.
@@ -607,8 +633,8 @@ static int get_bt_addr(struct mm_struct *mm,
607 return ret; 633 return ret;
608 } 634 }
609 635
610 valid_bit = *bt_addr & MPX_BD_ENTRY_VALID_FLAG; 636 valid_bit = bd_entry & MPX_BD_ENTRY_VALID_FLAG;
611 *bt_addr &= MPX_BT_ADDR_MASK; 637 bt_addr = mpx_bd_entry_to_bt_addr(mm, bd_entry);
612 638
613 /* 639 /*
614 * When the kernel is managing bounds tables, a bounds directory 640 * When the kernel is managing bounds tables, a bounds directory
@@ -617,7 +643,7 @@ static int get_bt_addr(struct mm_struct *mm,
617 * data in the address field, we know something is wrong. This 643 * data in the address field, we know something is wrong. This
618 * -EINVAL return will cause a SIGSEGV. 644 * -EINVAL return will cause a SIGSEGV.
619 */ 645 */
620 if (!valid_bit && *bt_addr) 646 if (!valid_bit && bt_addr)
621 return -EINVAL; 647 return -EINVAL;
622 /* 648 /*
623 * Do we have an completely zeroed bt entry? That is OK. It 649 * Do we have an completely zeroed bt entry? That is OK. It
@@ -628,6 +654,7 @@ static int get_bt_addr(struct mm_struct *mm,
628 if (!valid_bit) 654 if (!valid_bit)
629 return -ENOENT; 655 return -ENOENT;
630 656
657 *bt_addr_result = bt_addr;
631 return 0; 658 return 0;
632} 659}
633 660