@@ -6,6 +6,7 @@
Author: Michael S. Tsirkin <mst@mellanox.co.il>, Mellanox Technologies Ltd.
Based on: asm-xxx/mman.h
*/
+#include <asm-generic/hugetlb_encode.h>
#define PROT_READ 0x1 /* page can be read */
#define PROT_WRITE 0x2 /* page can be written */
@@ -80,4 +81,26 @@
#define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\
PKEY_DISABLE_WRITE)
+
+/*
+ * Huge page size encoding when MADV_HUGEPAGE is specified, and a huge page
+ * size other than the default is desired. See hugetlb_encode.h.
+ */
+#define MADV_HUGEPAGE_SHIFT HUGETLB_FLAG_ENCODE_SHIFT
+#define MADV_HUGEPAGE_MASK HUGETLB_FLAG_ENCODE_MASK
+#define MADV_BEHAVIOR_MASK ((1<<MADV_HUGEPAGE_SHIFT) - 1)
+
+#define MADV_HUGEPAGE_64KB HUGETLB_FLAG_ENCODE_64KB
+#define MADV_HUGEPAGE_512KB HUGETLB_FLAG_ENCODE_512KB
+#define MADV_HUGEPAGE_1MB HUGETLB_FLAG_ENCODE_1MB
+#define MADV_HUGEPAGE_2MB HUGETLB_FLAG_ENCODE_2MB
+#define MADV_HUGEPAGE_8MB HUGETLB_FLAG_ENCODE_8MB
+#define MADV_HUGEPAGE_16MB HUGETLB_FLAG_ENCODE_16MB
+#define MADV_HUGEPAGE_32MB HUGETLB_FLAG_ENCODE_32MB
+#define MADV_HUGEPAGE_256MB HUGETLB_FLAG_ENCODE_256MB
+#define MADV_HUGEPAGE_512MB HUGETLB_FLAG_ENCODE_512MB
+#define MADV_HUGEPAGE_1GB HUGETLB_FLAG_ENCODE_1GB
+#define MADV_HUGEPAGE_2GB HUGETLB_FLAG_ENCODE_2GB
+#define MADV_HUGEPAGE_16GB HUGETLB_FLAG_ENCODE_16GB
+
#endif /* __ASM_GENERIC_MMAN_COMMON_H */
@@ -345,6 +345,7 @@ struct attribute_group khugepaged_attr_group = {
int hugepage_madvise(struct vm_area_struct *vma,
unsigned long *vm_flags, int advice)
{
+ advice = advice & MADV_BEHAVIOR_MASK;
switch (advice) {
case MADV_HUGEPAGE:
#ifdef CONFIG_S390
@@ -40,6 +40,19 @@ struct madvise_walk_private {
bool pageout;
};
+static inline int get_behavior(int behavior)
+{
+ int behavior_no_flags = behavior & MADV_BEHAVIOR_MASK;
+ /*
+ * only MADV_HUGEPAGE and MADV_NOHUGEPAGE have extra huge page size
+ * flags
+ */
+ VM_BUG_ON(behavior_no_flags != MADV_HUGEPAGE &&
+ behavior_no_flags != MADV_NOHUGEPAGE &&
+ (behavior & (~MADV_BEHAVIOR_MASK)));
+ return behavior_no_flags;
+}
+
/*
* Any behaviour which results in changes to the vma->vm_flags needs to
* take mmap_lock for writing. Others, which simply traverse vmas, need
@@ -74,7 +87,7 @@ static long madvise_behavior(struct vm_area_struct *vma,
pgoff_t pgoff;
unsigned long new_flags = vma->vm_flags;
- switch (behavior) {
+ switch (get_behavior(behavior)) {
case MADV_NORMAL:
new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
break;
@@ -953,7 +966,7 @@ madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev,
static bool
madvise_behavior_valid(int behavior)
{
- switch (behavior) {
+ switch (get_behavior(behavior)) {
case MADV_DOFORK:
case MADV_DONTFORK:
case MADV_NORMAL: