--- /dev/null
+From a89652769470d12cd484ee3d3f7bde0742be8d96 Mon Sep 17 00:00:00 2001
+From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
+Date: Mon, 20 Jul 2015 14:29:58 -0700
+Subject: x86/mpx: Do not set ->vm_ops on MPX VMAs
+
+From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
+
+commit a89652769470d12cd484ee3d3f7bde0742be8d96 upstream.
+
+MPX setups private anonymous mapping, but uses vma->vm_ops too.
+This can confuse core VM, as it relies on vm->vm_ops to
+distinguish file VMAs from anonymous.
+
+As result we will get SIGBUS, because handle_pte_fault() thinks
+it's file VMA without vm_ops->fault and it doesn't know how to
+handle the situation properly.
+
+Let's fix that by not setting ->vm_ops.
+
+We don't really need ->vm_ops here: MPX VMA can be detected with
+VM_MPX flag. And vma_merge() will not merge MPX VMA with non-MPX
+VMA, because ->vm_flags won't match.
+
+The only thing left is name of VMA. I'm not sure if it's part of
+ABI, or we can just drop it. The patch keep it by providing
+arch_vma_name() on x86.
+
+Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Cc: Andy Lutomirski <luto@amacapital.net>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: dave@sr71.net
+Link: http://lkml.kernel.org/r/20150720212958.305CC3E9@viggo.jf.intel.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ arch/x86/mm/mmap.c | 7 +++++++
+ arch/x86/mm/mpx.c | 20 +-------------------
+ 2 files changed, 8 insertions(+), 19 deletions(-)
+
+--- a/arch/x86/mm/mmap.c
++++ b/arch/x86/mm/mmap.c
+@@ -126,3 +126,10 @@ void arch_pick_mmap_layout(struct mm_str
+ mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+ }
+ }
++
++const char *arch_vma_name(struct vm_area_struct *vma)
++{
++ if (vma->vm_flags & VM_MPX)
++ return "[mpx]";
++ return NULL;
++}
+--- a/arch/x86/mm/mpx.c
++++ b/arch/x86/mm/mpx.c
+@@ -18,26 +18,9 @@
+ #include <asm/processor.h>
+ #include <asm/fpu-internal.h>
+
+-static const char *mpx_mapping_name(struct vm_area_struct *vma)
+-{
+- return "[mpx]";
+-}
+-
+-static struct vm_operations_struct mpx_vma_ops = {
+- .name = mpx_mapping_name,
+-};
+-
+-static int is_mpx_vma(struct vm_area_struct *vma)
+-{
+- return (vma->vm_ops == &mpx_vma_ops);
+-}
+-
+ /*
+ * This is really a simplified "vm_mmap". it only handles MPX
+ * bounds tables (the bounds directory is user-allocated).
+- *
+- * Later on, we use the vma->vm_ops to uniquely identify these
+- * VMAs.
+ */
+ static unsigned long mpx_mmap(unsigned long len)
+ {
+@@ -83,7 +66,6 @@ static unsigned long mpx_mmap(unsigned l
+ ret = -ENOMEM;
+ goto out;
+ }
+- vma->vm_ops = &mpx_vma_ops;
+
+ if (vm_flags & VM_LOCKED) {
+ up_write(&mm->mmap_sem);
+@@ -661,7 +643,7 @@ static int zap_bt_entries(struct mm_stru
+ * so stop immediately and return an error. This
+ * probably results in a SIGSEGV.
+ */
+- if (!is_mpx_vma(vma))
++ if (!(vma->vm_flags & VM_MPX))
+ return -EINVAL;
+
+ len = min(vma->vm_end, end) - addr;