aboutsummaryrefslogtreecommitdiffstats
path: root/mm/nommu.c
diff options
context:
space:
mode:
authorBernd Schmidt <bernds_cb1@t-online.de>2009-09-21 20:03:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-22 10:17:43 -0400
commiteb8cdec4a984fde123a91250dcc9e0bddf5eafdc (patch)
tree9f97b5949e6e63ae947363149b62ed224dad5ab9 /mm/nommu.c
parent02e87d1a934c70e3599eb7a29db783806d329e17 (diff)
nommu: add support for Memory Protection Units (MPU)
Some architectures (like the Blackfin arch) implement some of the "simpler" features that one would expect out of a MMU such as memory protection. In our case, we actually get read/write/exec protection down to the page boundary so processes can't stomp on each other let alone the kernel. There is a performance decrease (which depends greatly on the workload) however as the hardware/software interaction was not optimized at design time. Signed-off-by: Bernd Schmidt <bernds_cb1@t-online.de> Signed-off-by: Bryan Wu <cooloney@kernel.org> Signed-off-by: Mike Frysinger <vapier@gentoo.org> Acked-by: David Howells <dhowells@redhat.com> Acked-by: Greg Ungerer <gerg@snapgear.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/nommu.c')
-rw-r--r--mm/nommu.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/mm/nommu.c b/mm/nommu.c
index 2d02ca17ce18..1a4473faac48 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -33,6 +33,7 @@
33#include <asm/uaccess.h> 33#include <asm/uaccess.h>
34#include <asm/tlb.h> 34#include <asm/tlb.h>
35#include <asm/tlbflush.h> 35#include <asm/tlbflush.h>
36#include <asm/mmu_context.h>
36#include "internal.h" 37#include "internal.h"
37 38
38static inline __attribute__((format(printf, 1, 2))) 39static inline __attribute__((format(printf, 1, 2)))
@@ -623,6 +624,22 @@ static void put_nommu_region(struct vm_region *region)
623} 624}
624 625
625/* 626/*
627 * update protection on a vma
628 */
629static void protect_vma(struct vm_area_struct *vma, unsigned long flags)
630{
631#ifdef CONFIG_MPU
632 struct mm_struct *mm = vma->vm_mm;
633 long start = vma->vm_start & PAGE_MASK;
634 while (start < vma->vm_end) {
635 protect_page(mm, start, flags);
636 start += PAGE_SIZE;
637 }
638 update_protections(mm);
639#endif
640}
641
642/*
626 * add a VMA into a process's mm_struct in the appropriate place in the list 643 * add a VMA into a process's mm_struct in the appropriate place in the list
627 * and tree and add to the address space's page tree also if not an anonymous 644 * and tree and add to the address space's page tree also if not an anonymous
628 * page 645 * page
@@ -641,6 +658,8 @@ static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma)
641 mm->map_count++; 658 mm->map_count++;
642 vma->vm_mm = mm; 659 vma->vm_mm = mm;
643 660
661 protect_vma(vma, vma->vm_flags);
662
644 /* add the VMA to the mapping */ 663 /* add the VMA to the mapping */
645 if (vma->vm_file) { 664 if (vma->vm_file) {
646 mapping = vma->vm_file->f_mapping; 665 mapping = vma->vm_file->f_mapping;
@@ -703,6 +722,8 @@ static void delete_vma_from_mm(struct vm_area_struct *vma)
703 722
704 kenter("%p", vma); 723 kenter("%p", vma);
705 724
725 protect_vma(vma, 0);
726
706 mm->map_count--; 727 mm->map_count--;
707 if (mm->mmap_cache == vma) 728 if (mm->mmap_cache == vma)
708 mm->mmap_cache = NULL; 729 mm->mmap_cache = NULL;