]> git.hungrycats.org Git - linux/commitdiff
[PATCH] hugetlb: fix MAP_FIXED handling
authorAndrew Morton <akpm@digeo.com>
Sun, 2 Mar 2003 12:37:54 +0000 (04:37 -0800)
committerDavid S. Miller <davem@nuts.ninka.net>
Sun, 2 Mar 2003 12:37:54 +0000 (04:37 -0800)
Patch from Rohit Seth

ia64 reserves virtual address region 4 (any address which starts with 0x4)
for huge pages.

Apparently, for hardware reasons, we do not wish to allow mappings with
other page sizes to appear in that region.

This patch prevents the user from being able to place regular MAP_FIXED
mappings into region 4 on ia64.  It is a no-op for ia32.

include/asm-ia64/page.h
include/linux/hugetlb.h
mm/mmap.c

index 2c78c70ee4775d669fdd5a0b3662462ae9cb863c..d4f49876c301c46fa99f03503f3fd9093d78b4cd 100644 (file)
 # 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__
index e90a34367970552bec023f119f2f6fe1d1e9d194..74785731a8c5f21de84e82dd3018175921dd5412 100644 (file)
@@ -37,6 +37,10 @@ mark_mm_hugetlb(struct mm_struct *mm, struct vm_area_struct *vma)
                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)
@@ -58,6 +62,7 @@ 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 */
index 54565f6cbcbde692a42a0a1892403b47f7cb144c..929017ae386bb97e38f5801cf246e63667ba788b 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -797,17 +797,27 @@ get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
                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;
        }