On 06/18/2014 02:44 AM, Qiaowei Ren wrote: > This patch adds one MPX specific mmap interface, which only handles > mpx related maps, including bounds table and bounds directory. > > In order to track MPX specific memory usage, this interface is added > to stick new vm_flag VM_MPX in the vma_area_struct when create a > bounds table or bounds directory. I imagine the linux-mm people would want to think about any new vm flag. Why is this needed? > > Signed-off-by: Qiaowei Ren <qiaowei.ren@xxxxxxxxx> > --- > arch/x86/Kconfig | 4 +++ > arch/x86/include/asm/mpx.h | 38 ++++++++++++++++++++++++++++ > arch/x86/mm/Makefile | 2 + > arch/x86/mm/mpx.c | 58 ++++++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 102 insertions(+), 0 deletions(-) > create mode 100644 arch/x86/include/asm/mpx.h > create mode 100644 arch/x86/mm/mpx.c > > diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig > index 25d2c6f..0194790 100644 > --- a/arch/x86/Kconfig > +++ b/arch/x86/Kconfig > @@ -237,6 +237,10 @@ config HAVE_INTEL_TXT > def_bool y > depends on INTEL_IOMMU && ACPI > > +config X86_INTEL_MPX > + def_bool y > + depends on CPU_SUP_INTEL > + > config X86_32_SMP > def_bool y > depends on X86_32 && SMP > diff --git a/arch/x86/include/asm/mpx.h b/arch/x86/include/asm/mpx.h > new file mode 100644 > index 0000000..5725ac4 > --- /dev/null > +++ b/arch/x86/include/asm/mpx.h > @@ -0,0 +1,38 @@ > +#ifndef _ASM_X86_MPX_H > +#define _ASM_X86_MPX_H > + > +#include <linux/types.h> > +#include <asm/ptrace.h> > + > +#ifdef CONFIG_X86_64 > + > +/* upper 28 bits [47:20] of the virtual address in 64-bit used to > + * index into bounds directory (BD). > + */ > +#define MPX_BD_ENTRY_OFFSET 28 > +#define MPX_BD_ENTRY_SHIFT 3 > +/* bits [19:3] of the virtual address in 64-bit used to index into > + * bounds table (BT). > + */ > +#define MPX_BT_ENTRY_OFFSET 17 > +#define MPX_BT_ENTRY_SHIFT 5 > +#define MPX_IGN_BITS 3 > + > +#else > + > +#define MPX_BD_ENTRY_OFFSET 20 > +#define MPX_BD_ENTRY_SHIFT 2 > +#define MPX_BT_ENTRY_OFFSET 10 > +#define MPX_BT_ENTRY_SHIFT 4 > +#define MPX_IGN_BITS 2 > + > +#endif > + > +#define MPX_BD_SIZE_BYTES (1UL<<(MPX_BD_ENTRY_OFFSET+MPX_BD_ENTRY_SHIFT)) > +#define MPX_BT_SIZE_BYTES (1UL<<(MPX_BT_ENTRY_OFFSET+MPX_BT_ENTRY_SHIFT)) > + > +#define MPX_BNDSTA_ERROR_CODE 0x3 > + > +unsigned long mpx_mmap(unsigned long len); > + > +#endif /* _ASM_X86_MPX_H */ > diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile > index 6a19ad9..ecfdc46 100644 > --- a/arch/x86/mm/Makefile > +++ b/arch/x86/mm/Makefile > @@ -30,3 +30,5 @@ obj-$(CONFIG_ACPI_NUMA) += srat.o > obj-$(CONFIG_NUMA_EMU) += numa_emulation.o > > obj-$(CONFIG_MEMTEST) += memtest.o > + > +obj-$(CONFIG_X86_INTEL_MPX) += mpx.o > diff --git a/arch/x86/mm/mpx.c b/arch/x86/mm/mpx.c > new file mode 100644 > index 0000000..546c5d1 > --- /dev/null > +++ b/arch/x86/mm/mpx.c > @@ -0,0 +1,58 @@ > +#include <linux/kernel.h> > +#include <linux/syscalls.h> > +#include <asm/mpx.h> > +#include <asm/mman.h> > +#include <linux/sched/sysctl.h> > + > +/* > + * this is really a simplified "vm_mmap". it only handles mpx > + * related maps, including bounds table and bounds directory. > + * > + * here we can stick new vm_flag VM_MPX in the vma_area_struct > + * when create a bounds table or bounds directory, in order to > + * track MPX specific memory. > + */ > +unsigned long mpx_mmap(unsigned long len) > +{ > + unsigned long ret; > + unsigned long addr, pgoff; > + struct mm_struct *mm = current->mm; > + vm_flags_t vm_flags; > + > + /* Only bounds table and bounds directory can be allocated here */ > + if (len != MPX_BD_SIZE_BYTES && len != MPX_BT_SIZE_BYTES) > + return -EINVAL; > + > + down_write(&mm->mmap_sem); > + > + /* Too many mappings? */ > + if (mm->map_count > sysctl_max_map_count) { > + ret = -ENOMEM; > + goto out; > + } > + > + /* Obtain the address to map to. we verify (or select) it and ensure > + * that it represents a valid section of the address space. > + */ > + addr = get_unmapped_area(NULL, 0, len, 0, MAP_ANONYMOUS | MAP_PRIVATE); > + if (addr & ~PAGE_MASK) { > + ret = addr; > + goto out; > + } > + > + vm_flags = VM_READ | VM_WRITE | VM_MPX | > + mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; > + > + /* Make bounds tables and bouds directory unlocked. */ > + if (vm_flags & VM_LOCKED) > + vm_flags &= ~VM_LOCKED; Why? I would expect MCL_FUTURE to lock these. --Andy -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>