2 * mpx.c - Memory Protection eXtensions
4 * Copyright (c) 2014, Intel Corporation.
5 * Qiaowei Ren <qiaowei.ren@intel.com>
6 * Dave Hansen <dave.hansen@intel.com>
8 #include <linux/kernel.h>
9 #include <linux/syscalls.h>
10 #include <linux/sched/sysctl.h>
15 static const char *mpx_mapping_name(struct vm_area_struct
*vma
)
20 static struct vm_operations_struct mpx_vma_ops
= {
21 .name
= mpx_mapping_name
,
25 * This is really a simplified "vm_mmap". it only handles MPX
26 * bounds tables (the bounds directory is user-allocated).
28 * Later on, we use the vma->vm_ops to uniquely identify these
31 static unsigned long mpx_mmap(unsigned long len
)
34 unsigned long addr
, pgoff
;
35 struct mm_struct
*mm
= current
->mm
;
37 struct vm_area_struct
*vma
;
39 /* Only bounds table and bounds directory can be allocated here */
40 if (len
!= MPX_BD_SIZE_BYTES
&& len
!= MPX_BT_SIZE_BYTES
)
43 down_write(&mm
->mmap_sem
);
45 /* Too many mappings? */
46 if (mm
->map_count
> sysctl_max_map_count
) {
51 /* Obtain the address to map to. we verify (or select) it and ensure
52 * that it represents a valid section of the address space.
54 addr
= get_unmapped_area(NULL
, 0, len
, 0, MAP_ANONYMOUS
| MAP_PRIVATE
);
55 if (addr
& ~PAGE_MASK
) {
60 vm_flags
= VM_READ
| VM_WRITE
| VM_MPX
|
61 mm
->def_flags
| VM_MAYREAD
| VM_MAYWRITE
| VM_MAYEXEC
;
63 /* Set pgoff according to addr for anon_vma */
64 pgoff
= addr
>> PAGE_SHIFT
;
66 ret
= mmap_region(NULL
, addr
, len
, vm_flags
, pgoff
);
67 if (IS_ERR_VALUE(ret
))
70 vma
= find_vma(mm
, ret
);
75 vma
->vm_ops
= &mpx_vma_ops
;
77 if (vm_flags
& VM_LOCKED
) {
78 up_write(&mm
->mmap_sem
);
79 mm_populate(ret
, len
);
84 up_write(&mm
->mmap_sem
);