# define REGION_SHIFT 61
# define HPAGE_SIZE (__IA64_UL_CONST(1) << HPAGE_SHIFT)
# define HPAGE_MASK (~(HPAGE_SIZE - 1))
+static inline int
+check_valid_hugepage_range(unsigned long addr, unsigned long len)
+{
+ if (REGION_NUMBER(addr) == REGION_HPAGE)
+ return -EINVAL;
+ if (REGION_NUMBER(addr+len) == REGION_HPAGE)
+ return -EINVAL;
+ return 0;
+}
+#define ARCH_HAS_VALID_HUGEPAGE_RANGE
#endif /* CONFIG_HUGETLB_PAGE */
#ifdef __ASSEMBLY__
mm->used_hugetlb = 1;
}
+#ifndef ARCH_HAS_VALID_HUGEPAGE_RANGE
+#define check_valid_hugepage_range(addr, len) 0
+#endif
+
#else /* !CONFIG_HUGETLB_PAGE */
static inline int is_vm_hugetlb_page(struct vm_area_struct *vma)
#define follow_huge_pmd(mm, addr, pmd, write) 0
#define is_aligned_hugepage_range(addr, len) 0
#define pmd_huge(x) 0
+#define check_valid_hugepage_range(addr, len) 0
#ifndef HPAGE_MASK
#define HPAGE_MASK 0 /* Keep the compiler happy */
unsigned long pgoff, unsigned long flags)
{
if (flags & MAP_FIXED) {
+ unsigned long ret;
+
if (addr > TASK_SIZE - len)
return -ENOMEM;
if (addr & ~PAGE_MASK)
return -EINVAL;
- if (file && is_file_hugepages(file)) {
- unsigned long ret;
-
+ if (file && is_file_hugepages(file)) {
+ /*
+ * Make sure that addr and length are properly aligned.
+ */
ret = is_aligned_hugepage_range(addr, len);
- if (ret)
- return ret;
+ } else {
+ /*
+ * Ensure that a normal request is not falling in a
+ * reserved hugepage range. For some archs like IA-64,
+ * there is a separate region for hugepages.
+ */
+ ret = check_valid_hugepage_range(addr, len);
}
+ if (ret)
+ return ret;
return addr;
}