2009-07-14 14:22:28

by Mike Frysinger

[permalink] [raw]
Subject: [PATCH] NOMMU: add support for Memory Protection Units (MPU)

From: Bernd Schmidt <[email protected]>

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 <[email protected]>
Signed-off-by: Bryan Wu <[email protected]>
Signed-off-by: Mike Frysinger <[email protected]>
CC: David Howells <[email protected]>
---
kernel/module.c | 5 +++++
mm/nommu.c | 25 +++++++++++++++++++++++++
2 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/kernel/module.c b/kernel/module.c
index 0a04983..e1a3dfc 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -47,6 +47,7 @@
#include <linux/rculist.h>
#include <asm/uaccess.h>
#include <asm/cacheflush.h>
+#include <asm/mmu_context.h>
#include <linux/license.h>
#include <asm/sections.h>
#include <linux/tracepoint.h>
@@ -1519,6 +1520,10 @@ static void free_module(struct module *mod)

/* Finally, free the core (containing the module structure) */
module_free(mod, mod->module_core);
+
+#ifdef CONFIG_MPU
+ update_protections(current->mm);
+#endif
}

void *__symbol_get(const char *symbol)
diff --git a/mm/nommu.c b/mm/nommu.c
index 53cab10..a0269e5 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -33,6 +33,7 @@
#include <asm/uaccess.h>
#include <asm/tlb.h>
#include <asm/tlbflush.h>
+#include <asm/mmu_context.h>
#include "internal.h"

static inline __attribute__((format(printf, 1, 2)))
@@ -640,11 +641,23 @@ static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma)
struct vm_area_struct *pvma, **pp;
struct address_space *mapping;
struct rb_node **p, *parent;
+#ifdef CONFIG_MPU
+ long start;
+#endif

kenter(",%p", vma);

BUG_ON(!vma->vm_region);

+#ifdef CONFIG_MPU
+ start = vma->vm_start & PAGE_MASK;
+ while (start < vma->vm_end) {
+ protect_page(mm, start, vma->vm_flags);
+ start += PAGE_SIZE;
+ }
+ update_protections(mm);
+#endif
+
mm->map_count++;
vma->vm_mm = mm;

@@ -707,9 +720,21 @@ static void delete_vma_from_mm(struct vm_area_struct *vma)
struct vm_area_struct **pp;
struct address_space *mapping;
struct mm_struct *mm = vma->vm_mm;
+#ifdef CONFIG_MPU
+ long start;
+#endif

kenter("%p", vma);

+#ifdef CONFIG_MPU
+ start = vma->vm_start & PAGE_MASK;
+ while (start < vma->vm_end) {
+ protect_page(mm, start, 0);
+ start += PAGE_SIZE;
+ }
+ update_protections(mm);
+#endif
+
mm->map_count--;
if (mm->mmap_cache == vma)
mm->mmap_cache = NULL;
--
1.6.3.3


2009-07-14 16:14:53

by Johannes Weiner

[permalink] [raw]
Subject: Re: [PATCH] NOMMU: add support for Memory Protection Units (MPU)

On Tue, Jul 14, 2009 at 10:22:20AM -0400, Mike Frysinger wrote:
> From: Bernd Schmidt <[email protected]>
>
> 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 <[email protected]>
> Signed-off-by: Bryan Wu <[email protected]>
> Signed-off-by: Mike Frysinger <[email protected]>
> CC: David Howells <[email protected]>
> ---
> kernel/module.c | 5 +++++
> mm/nommu.c | 25 +++++++++++++++++++++++++
> 2 files changed, 30 insertions(+), 0 deletions(-)
>
> diff --git a/kernel/module.c b/kernel/module.c
> index 0a04983..e1a3dfc 100644
> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -47,6 +47,7 @@
> #include <linux/rculist.h>
> #include <asm/uaccess.h>
> #include <asm/cacheflush.h>
> +#include <asm/mmu_context.h>
> #include <linux/license.h>
> #include <asm/sections.h>
> #include <linux/tracepoint.h>
> @@ -1519,6 +1520,10 @@ static void free_module(struct module *mod)
>
> /* Finally, free the core (containing the module structure) */
> module_free(mod, mod->module_core);
> +
> +#ifdef CONFIG_MPU
> + update_protections(current->mm);
> +#endif
> }
>
> void *__symbol_get(const char *symbol)
> diff --git a/mm/nommu.c b/mm/nommu.c
> index 53cab10..a0269e5 100644
> --- a/mm/nommu.c
> +++ b/mm/nommu.c
> @@ -33,6 +33,7 @@
> #include <asm/uaccess.h>
> #include <asm/tlb.h>
> #include <asm/tlbflush.h>
> +#include <asm/mmu_context.h>
> #include "internal.h"
>
> static inline __attribute__((format(printf, 1, 2)))
> @@ -640,11 +641,23 @@ static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma)
> struct vm_area_struct *pvma, **pp;
> struct address_space *mapping;
> struct rb_node **p, *parent;
> +#ifdef CONFIG_MPU
> + long start;
> +#endif
>
> kenter(",%p", vma);
>
> BUG_ON(!vma->vm_region);
>
> +#ifdef CONFIG_MPU
> + start = vma->vm_start & PAGE_MASK;
> + while (start < vma->vm_end) {
> + protect_page(mm, start, vma->vm_flags);
> + start += PAGE_SIZE;
> + }
> + update_protections(mm);
> +#endif
> +
> mm->map_count++;
> vma->vm_mm = mm;
>
> @@ -707,9 +720,21 @@ static void delete_vma_from_mm(struct vm_area_struct *vma)
> struct vm_area_struct **pp;
> struct address_space *mapping;
> struct mm_struct *mm = vma->vm_mm;
> +#ifdef CONFIG_MPU
> + long start;
> +#endif
>
> kenter("%p", vma);
>
> +#ifdef CONFIG_MPU
> + start = vma->vm_start & PAGE_MASK;
> + while (start < vma->vm_end) {
> + protect_page(mm, start, 0);
> + start += PAGE_SIZE;
> + }
> + update_protections(mm);
> +#endif

How about refactoring that into one function? Saves all but one
#ifdef.

2009-07-14 16:48:18

by Mike Frysinger

[permalink] [raw]
Subject: Re: [PATCH] NOMMU: add support for Memory Protection Units (MPU)

On Tue, Jul 14, 2009 at 12:14, Johannes Weiner wrote:
> On Tue, Jul 14, 2009 at 10:22:20AM -0400, Mike Frysinger wrote:
>> --- a/mm/nommu.c
>> +++ b/mm/nommu.c
>> @@ -640,11 +641,23 @@ static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma)
>>       struct vm_area_struct *pvma, **pp;
>>       struct address_space *mapping;
>>       struct rb_node **p, *parent;
>> +#ifdef CONFIG_MPU
>> +     long start;
>> +#endif
>>
>>       kenter(",%p", vma);
>>
>>       BUG_ON(!vma->vm_region);
>>
>> +#ifdef CONFIG_MPU
>> +     start = vma->vm_start & PAGE_MASK;
>> +     while (start < vma->vm_end) {
>> +             protect_page(mm, start, vma->vm_flags);
>> +             start += PAGE_SIZE;
>> +     }
>> +     update_protections(mm);
>> +#endif
>> +
>>       mm->map_count++;
>>       vma->vm_mm = mm;
>>
>> @@ -707,9 +720,21 @@ static void delete_vma_from_mm(struct vm_area_struct *vma)
>>       struct vm_area_struct **pp;
>>       struct address_space *mapping;
>>       struct mm_struct *mm = vma->vm_mm;
>> +#ifdef CONFIG_MPU
>> +     long start;
>> +#endif
>>
>>       kenter("%p", vma);
>>
>> +#ifdef CONFIG_MPU
>> +     start = vma->vm_start & PAGE_MASK;
>> +     while (start < vma->vm_end) {
>> +             protect_page(mm, start, 0);
>> +             start += PAGE_SIZE;
>> +     }
>> +     update_protections(mm);
>> +#endif
>
> How about refactoring that into one function?  Saves all but one
> #ifdef.

makes sense to me, thanks
-mike

2009-07-14 17:14:28

by Mike Frysinger

[permalink] [raw]
Subject: [PATCH v2] NOMMU: add support for Memory Protection Units (MPU)

From: Bernd Schmidt <[email protected]>

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 <[email protected]>
Signed-off-by: Bryan Wu <[email protected]>
Signed-off-by: Mike Frysinger <[email protected]>
CC: David Howells <[email protected]>
---
v2
- unify mpu code in nommu.c to simplify things

kernel/module.c | 5 +++++
mm/nommu.c | 21 +++++++++++++++++++++
2 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/kernel/module.c b/kernel/module.c
index e797812..80036bc 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -46,6 +46,7 @@
#include <linux/rculist.h>
#include <asm/uaccess.h>
#include <asm/cacheflush.h>
+#include <asm/mmu_context.h>
#include <linux/license.h>
#include <asm/sections.h>
#include <linux/tracepoint.h>
@@ -1506,6 +1507,10 @@ static void free_module(struct module *mod)

/* Finally, free the core (containing the module structure) */
module_free(mod, mod->module_core);
+
+#ifdef CONFIG_MPU
+ update_protections(current->mm);
+#endif
}

void *__symbol_get(const char *symbol)
diff --git a/mm/nommu.c b/mm/nommu.c
index b571ef7..e7c3bbe 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -33,6 +33,7 @@
#include <asm/uaccess.h>
#include <asm/tlb.h>
#include <asm/tlbflush.h>
+#include <asm/mmu_context.h>
#include "internal.h"

static inline __attribute__((format(printf, 1, 2)))
@@ -608,6 +609,22 @@ static void put_nommu_region(struct vm_region *region)
}

/*
+ * update protection on a vma
+ */
+static void protect_vma(struct vm_area_struct *vma, unsigned long flags)
+{
+#ifdef CONFIG_MPU
+ struct mm_struct *mm = vma->vm_mm;
+ long start = vma->vm_start & PAGE_MASK;
+ while (start < vma->vm_end) {
+ protect_page(mm, start, flags);
+ start += PAGE_SIZE;
+ }
+ update_protections(mm);
+#endif
+}
+
+/*
* add a VMA into a process's mm_struct in the appropriate place in the list
* and tree and add to the address space's page tree also if not an anonymous
* page
@@ -626,6 +643,8 @@ static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma)
mm->map_count++;
vma->vm_mm = mm;

+ protect_vma(vma, vma->vm_flags);
+
/* add the VMA to the mapping */
if (vma->vm_file) {
mapping = vma->vm_file->f_mapping;
@@ -688,6 +707,8 @@ static void delete_vma_from_mm(struct vm_area_struct *vma)

kenter("%p", vma);

+ protect_vma(vma, 0);
+
mm->map_count--;
if (mm->mmap_cache == vma)
mm->mmap_cache = NULL;
--
1.6.3.3

2009-07-14 17:31:34

by David Howells

[permalink] [raw]
Subject: Re: [PATCH v2] NOMMU: add support for Memory Protection Units (MPU)

Mike Frysinger <[email protected]> wrote:

> 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.

It occurs to me that I could probably test this on FRV by using the MMU in a
limited way. How do you actually keep track of the protections applied? Do
you have a single global page table that is managed by the mmap code on a
per-VMA basis?

David

2009-07-14 21:00:36

by Bernd Schmidt

[permalink] [raw]
Subject: Re: [PATCH v2] NOMMU: add support for Memory Protection Units (MPU)

David Howells wrote:
> Mike Frysinger <[email protected]> wrote:
>
>> 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.
>
> It occurs to me that I could probably test this on FRV by using the MMU in a
> limited way. How do you actually keep track of the protections applied? Do
> you have a single global page table that is managed by the mmap code on a
> per-VMA basis?

No page table, just three bitmaps (r/w/x), with one bit per page, per mm.


Bernd
--
This footer brought to you by insane German lawmakers.
Analog Devices GmbH Wilhelm-Wagenfeld-Str. 6 80807 Muenchen
Sitz der Gesellschaft Muenchen, Registergericht Muenchen HRB 40368
Geschaeftsfuehrer Thomas Wessel, William A. Martin, Margaret Seif

2009-07-15 09:25:16

by Paul Mundt

[permalink] [raw]
Subject: Re: [PATCH v2] NOMMU: add support for Memory Protection Units (MPU)

On Tue, Jul 14, 2009 at 06:22:06PM +0100, David Howells wrote:
> Mike Frysinger <[email protected]> wrote:
>
> > 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.
>
> It occurs to me that I could probably test this on FRV by using the MMU in a
> limited way. How do you actually keep track of the protections applied? Do
> you have a single global page table that is managed by the mmap code on a
> per-VMA basis?
>
SH can do this as well for the single-address-space mode in the MMU, but
in that case I would still use a global page table.

2009-07-15 10:34:00

by David Howells

[permalink] [raw]
Subject: Re: [PATCH v2] NOMMU: add support for Memory Protection Units (MPU)

Bernd Schmidt <[email protected]> wrote:

> No page table, just three bitmaps (r/w/x), with one bit per page, per mm.

That sounds a bit inefficient as you have to make three accesses per page. I
suppose it depends on how your MPU works.

David

2009-07-15 10:39:57

by David Howells

[permalink] [raw]
Subject: Re: [PATCH v2] NOMMU: add support for Memory Protection Units (MPU)

Bernd Schmidt <[email protected]> wrote:

> No page table, just three bitmaps (r/w/x), with one bit per page, per mm.

I presume that all you do is maintain a distinction between
userspace-accessible areas and kernel-only areas, and don't prevent userspace
processes from destroying each other.

David

2009-07-15 11:12:42

by Mike Frysinger

[permalink] [raw]
Subject: Re: [Uclinux-dist-devel] [PATCH v2] NOMMU: add support for Memory Protection Units (MPU)

On Wed, Jul 15, 2009 at 06:37, David Howells wrote:
> Bernd Schmidt <[email protected]> wrote:
>> No page table, just three bitmaps (r/w/x), with one bit per page, per mm.
>
> I presume that all you do is maintain a distinction between
> userspace-accessible areas and kernel-only areas, and don't prevent userspace
> processes from destroying each other.

there is full 4k page protection between processes and between the
kernel and processes.
-mike

2009-07-15 11:19:03

by Mike Frysinger

[permalink] [raw]
Subject: Re: [Uclinux-dist-devel] [PATCH v2] NOMMU: add support for Memory Protection Units (MPU)

On Wed, Jul 15, 2009 at 06:31, David Howells wrote:
> Bernd Schmidt wrote:
>> No page table, just three bitmaps (r/w/x), with one bit per page, per mm.
>
> That sounds a bit inefficient as you have to make three accesses per page.  I
> suppose it depends on how your MPU works.

there isnt any hardware assistance in terms of speeding up misses.
they're treated like any other hardware exception. it does
differentiate between inst and data misses though, so the software
replacement algorithm doesnt have to check all three.

the code for handling CPLB (effectively the same thing as a TLB for
this discussion) is contained in
arch/blackfin/kernel/cplb-mpu/cplbmgr.c. it's a pretty small file --
the entry point is cplb_hdr() and that calls the relevant function to
handle inst or data misses.
-mike

2009-07-15 11:46:35

by David Howells

[permalink] [raw]
Subject: Re: [Uclinux-dist-devel] [PATCH v2] NOMMU: add support for Memory Protection Units (MPU)

Mike Frysinger <[email protected]> wrote:

> there is full 4k page protection between processes and between the
> kernel and processes.

So you have a separate bitmap per process?

David

2009-07-15 11:55:40

by Mike Frysinger

[permalink] [raw]
Subject: Re: [Uclinux-dist-devel] [PATCH v2] NOMMU: add support for Memory Protection Units (MPU)

On Wed, Jul 15, 2009 at 07:45, David Howells wrote:
> Mike Frysinger wrote:
>> there is full 4k page protection between processes and between the
>> kernel and processes.
>
> So you have a separate bitmap per process?

yes, you can see page_rwx_mask in our mmu.h's mm_context_t. this is
what the protect_page/update_protections operate on. we have a global
current_rwx_mask that gets updated during context changes and the CPLB
miss handler uses that to keep things simple.
-mike

2009-07-15 12:27:14

by David Howells

[permalink] [raw]
Subject: Re: [Uclinux-dist-devel] [PATCH v2] NOMMU: add support for Memory Protection Units (MPU)

Mike Frysinger <[email protected]> wrote:

> yes, you can see page_rwx_mask in our mmu.h's mm_context_t. this is
> what the protect_page/update_protections operate on. we have a global
> current_rwx_mask that gets updated during context changes and the CPLB
> miss handler uses that to keep things simple.

Interesting.

Since FRV does not really allow separate execute permissions (it has a very
few separate static I and D protection/mapping registers and a shared TLB), I
could do it with just pairs of bits.

Also, how do you deal with mappable devices that lie outside of RAM? I'm
guessing from the code that you don't cover those with the bitmap, but rather
just grant userspace RW access.

David

2009-07-15 12:52:45

by Mike Frysinger

[permalink] [raw]
Subject: Re: [Uclinux-dist-devel] [PATCH v2] NOMMU: add support for Memory Protection Units (MPU)

On Wed, Jul 15, 2009 at 08:25, David Howells wrote:
> Mike Frysinger wrote:
>> yes, you can see page_rwx_mask in our mmu.h's mm_context_t.  this is
>> what the protect_page/update_protections operate on.  we have a global
>> current_rwx_mask that gets updated during context changes and the CPLB
>> miss handler uses that to keep things simple.
>
> Interesting.
>
> Since FRV does not really allow separate execute permissions (it has a very
> few separate static I and D protection/mapping registers and a shared TLB), I
> could do it with just pairs of bits.
>
> Also, how do you deal with mappable devices that lie outside of RAM?  I'm
> guessing from the code that you don't cover those with the bitmap, but rather
> just grant userspace RW access.

yes, there are really only three such regions on Blackfin systems:
- on-chip rom
- async memory banks
- on-chip sram

since the first is read-only, letting random things execute/read there
isnt going to cause a problem. any supervisor-only
accesses/instructions would be caught anyways if userspace attempted
it.

the second could (should?) be restricted like normal (granting access
via ioremap/mmap), but right now we just grant full access to
everyone. the banks are largely used for drivers only
(usb/eth/flash/fpga/etc...), so having protection for that region
doesnt gain us too much. perhaps down the line we'll look into it.

the on-chip srams are so small that 4k (or even 1k -- the smallest
page we can handle) would waste most resources. so we either lock a
CPLB entry for full access (L1), or always grant it (L2). and again,
experience has shown that it is largely used by drivers only, so
protection here wouldnt gain much as there is so rarely bad behavior
going on.
-mike

2009-09-14 04:00:27

by Mike Frysinger

[permalink] [raw]
Subject: Re: [PATCH v2] NOMMU: add support for Memory Protection Units (MPU)

On Tue, Jul 14, 2009 at 13:14, Mike Frysinger wrote:
> From: Bernd Schmidt <[email protected]>
>
> 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.

David: anything else need to be done here or can we merge things ?
-mike

2009-09-16 10:13:12

by David Howells

[permalink] [raw]
Subject: Re: [PATCH v2] NOMMU: add support for Memory Protection Units (MPU)

Mike Frysinger <[email protected]> wrote:

> David: anything else need to be done here or can we merge things ?

Go for it, and add my Acked-by.

David

2009-09-16 13:57:26

by Mike Frysinger

[permalink] [raw]
Subject: [PATCH] NOMMU: add support for Memory Protection Units (MPU)

From: Bernd Schmidt <[email protected]>

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 <[email protected]>
Signed-off-by: Bryan Wu <[email protected]>
Signed-off-by: Mike Frysinger <[email protected]>
Acked-by: David Howells <[email protected]>
---
kernel/module.c | 5 +++++
mm/nommu.c | 21 +++++++++++++++++++++
2 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/kernel/module.c b/kernel/module.c
index 05ce49c..90af6a1 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -47,6 +47,7 @@
#include <linux/rculist.h>
#include <asm/uaccess.h>
#include <asm/cacheflush.h>
+#include <asm/mmu_context.h>
#include <linux/license.h>
#include <asm/sections.h>
#include <linux/tracepoint.h>
@@ -1535,6 +1536,10 @@ static void free_module(struct module *mod)

/* Finally, free the core (containing the module structure) */
module_free(mod, mod->module_core);
+
+#ifdef CONFIG_MPU
+ update_protections(current->mm);
+#endif
}

void *__symbol_get(const char *symbol)
diff --git a/mm/nommu.c b/mm/nommu.c
index 66e81e7..b73f4be 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -33,6 +33,7 @@
#include <asm/uaccess.h>
#include <asm/tlb.h>
#include <asm/tlbflush.h>
+#include <asm/mmu_context.h>
#include "internal.h"

static inline __attribute__((format(printf, 1, 2)))
@@ -627,6 +628,22 @@ static void put_nommu_region(struct vm_region *region)
}

/*
+ * update protection on a vma
+ */
+static void protect_vma(struct vm_area_struct *vma, unsigned long flags)
+{
+#ifdef CONFIG_MPU
+ struct mm_struct *mm = vma->vm_mm;
+ long start = vma->vm_start & PAGE_MASK;
+ while (start < vma->vm_end) {
+ protect_page(mm, start, flags);
+ start += PAGE_SIZE;
+ }
+ update_protections(mm);
+#endif
+}
+
+/*
* add a VMA into a process's mm_struct in the appropriate place in the list
* and tree and add to the address space's page tree also if not an anonymous
* page
@@ -645,6 +662,8 @@ static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma)
mm->map_count++;
vma->vm_mm = mm;

+ protect_vma(vma, vma->vm_flags);
+
/* add the VMA to the mapping */
if (vma->vm_file) {
mapping = vma->vm_file->f_mapping;
@@ -707,6 +726,8 @@ static void delete_vma_from_mm(struct vm_area_struct *vma)

kenter("%p", vma);

+ protect_vma(vma, 0);
+
mm->map_count--;
if (mm->mmap_cache == vma)
mm->mmap_cache = NULL;
--
1.6.5.rc1