All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] NOMMU: add support for Memory Protection Units (MPU)
@ 2009-07-14 14:22 Mike Frysinger
  2009-07-14 16:14 ` Johannes Weiner
  2009-09-16 13:57 ` [PATCH] " Mike Frysinger
  0 siblings, 2 replies; 18+ messages in thread
From: Mike Frysinger @ 2009-07-14 14:22 UTC (permalink / raw)
  To: linux-kernel; +Cc: uclinux-dist-devel, Bernd Schmidt, Bryan Wu, David Howells

From: Bernd Schmidt <bernds_cb1@t-online.de>

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>
CC: David Howells <dhowells@redhat.com>
---
 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


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH] NOMMU: add support for Memory Protection Units (MPU)
  2009-07-14 14:22 [PATCH] NOMMU: add support for Memory Protection Units (MPU) Mike Frysinger
@ 2009-07-14 16:14 ` Johannes Weiner
  2009-07-14 16:19   ` Mike Frysinger
                     ` (2 more replies)
  2009-09-16 13:57 ` [PATCH] " Mike Frysinger
  1 sibling, 3 replies; 18+ messages in thread
From: Johannes Weiner @ 2009-07-14 16:14 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: linux-kernel, uclinux-dist-devel, Bernd Schmidt, Bryan Wu, David Howells

On Tue, Jul 14, 2009 at 10:22:20AM -0400, Mike Frysinger wrote:
> From: Bernd Schmidt <bernds_cb1@t-online.de>
> 
> 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>
> CC: David Howells <dhowells@redhat.com>
> ---
>  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.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] NOMMU: add support for Memory Protection Units (MPU)
  2009-07-14 16:14 ` Johannes Weiner
@ 2009-07-14 16:19   ` Mike Frysinger
  2009-07-14 17:14   ` [PATCH v2] " Mike Frysinger
  2009-07-14 17:22   ` David Howells
  2 siblings, 0 replies; 18+ messages in thread
From: Mike Frysinger @ 2009-07-14 16:19 UTC (permalink / raw)
  To: Johannes Weiner
  Cc: linux-kernel, uclinux-dist-devel, Bernd Schmidt, Bryan Wu, David Howells

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

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v2] NOMMU: add support for Memory Protection Units (MPU)
  2009-07-14 16:14 ` Johannes Weiner
  2009-07-14 16:19   ` Mike Frysinger
@ 2009-07-14 17:14   ` Mike Frysinger
  2009-09-14  3:52     ` Mike Frysinger
  2009-09-16 10:09     ` David Howells
  2009-07-14 17:22   ` David Howells
  2 siblings, 2 replies; 18+ messages in thread
From: Mike Frysinger @ 2009-07-14 17:14 UTC (permalink / raw)
  To: linux-kernel; +Cc: uclinux-dist-devel, Bernd Schmidt, Bryan Wu, David Howells

From: Bernd Schmidt <bernds_cb1@t-online.de>

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>
CC: David Howells <dhowells@redhat.com>
---
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


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH v2] NOMMU: add support for Memory Protection Units (MPU)
  2009-07-14 16:14 ` Johannes Weiner
  2009-07-14 16:19   ` Mike Frysinger
  2009-07-14 17:14   ` [PATCH v2] " Mike Frysinger
@ 2009-07-14 17:22   ` David Howells
  2009-07-14 21:59     ` Bernd Schmidt
                       ` (3 more replies)
  2 siblings, 4 replies; 18+ messages in thread
From: David Howells @ 2009-07-14 17:22 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: dhowells, linux-kernel, uclinux-dist-devel, Bernd Schmidt, Bryan Wu

Mike Frysinger <vapier@gentoo.org> 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

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v2] NOMMU: add support for Memory Protection Units (MPU)
  2009-07-14 17:22   ` David Howells
@ 2009-07-14 21:59     ` Bernd Schmidt
  2009-07-15  9:24     ` Paul Mundt
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 18+ messages in thread
From: Bernd Schmidt @ 2009-07-14 21:59 UTC (permalink / raw)
  To: David Howells; +Cc: Mike Frysinger, linux-kernel, uclinux-dist-devel, Bryan Wu

David Howells wrote:
> Mike Frysinger <vapier@gentoo.org> 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

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v2] NOMMU: add support for Memory Protection Units (MPU)
  2009-07-14 17:22   ` David Howells
  2009-07-14 21:59     ` Bernd Schmidt
@ 2009-07-15  9:24     ` Paul Mundt
  2009-07-15 10:31     ` David Howells
  2009-07-15 10:37     ` David Howells
  3 siblings, 0 replies; 18+ messages in thread
From: Paul Mundt @ 2009-07-15  9:24 UTC (permalink / raw)
  To: David Howells
  Cc: Mike Frysinger, linux-kernel, uclinux-dist-devel, Bernd Schmidt,
	Bryan Wu

On Tue, Jul 14, 2009 at 06:22:06PM +0100, David Howells wrote:
> Mike Frysinger <vapier@gentoo.org> 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.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v2] NOMMU: add support for Memory Protection Units (MPU)
  2009-07-14 17:22   ` David Howells
  2009-07-14 21:59     ` Bernd Schmidt
  2009-07-15  9:24     ` Paul Mundt
@ 2009-07-15 10:31     ` David Howells
  2009-07-15 11:18       ` [Uclinux-dist-devel] " Mike Frysinger
  2009-07-15 10:37     ` David Howells
  3 siblings, 1 reply; 18+ messages in thread
From: David Howells @ 2009-07-15 10:31 UTC (permalink / raw)
  To: Bernd Schmidt
  Cc: dhowells, Mike Frysinger, linux-kernel, uclinux-dist-devel, Bryan Wu

Bernd Schmidt <bernds_cb1@t-online.de> 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

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v2] NOMMU: add support for Memory Protection Units (MPU)
  2009-07-14 17:22   ` David Howells
                       ` (2 preceding siblings ...)
  2009-07-15 10:31     ` David Howells
@ 2009-07-15 10:37     ` David Howells
  2009-07-15 11:12       ` [Uclinux-dist-devel] " Mike Frysinger
  2009-07-15 11:45       ` David Howells
  3 siblings, 2 replies; 18+ messages in thread
From: David Howells @ 2009-07-15 10:37 UTC (permalink / raw)
  To: Bernd Schmidt
  Cc: dhowells, Mike Frysinger, linux-kernel, uclinux-dist-devel, Bryan Wu

Bernd Schmidt <bernds_cb1@t-online.de> 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

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Uclinux-dist-devel] [PATCH v2] NOMMU: add support for Memory  Protection Units (MPU)
  2009-07-15 10:37     ` David Howells
@ 2009-07-15 11:12       ` Mike Frysinger
  2009-07-15 11:45       ` David Howells
  1 sibling, 0 replies; 18+ messages in thread
From: Mike Frysinger @ 2009-07-15 11:12 UTC (permalink / raw)
  To: David Howells; +Cc: Bernd Schmidt, uclinux-dist-devel, linux-kernel

On Wed, Jul 15, 2009 at 06:37, David Howells wrote:
> Bernd Schmidt <bernds_cb1@t-online.de> 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

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Uclinux-dist-devel] [PATCH v2] NOMMU: add support for Memory  Protection Units (MPU)
  2009-07-15 10:31     ` David Howells
@ 2009-07-15 11:18       ` Mike Frysinger
  0 siblings, 0 replies; 18+ messages in thread
From: Mike Frysinger @ 2009-07-15 11:18 UTC (permalink / raw)
  To: David Howells; +Cc: Bernd Schmidt, uclinux-dist-devel, linux-kernel

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

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Uclinux-dist-devel] [PATCH v2] NOMMU: add support for Memory Protection Units (MPU)
  2009-07-15 10:37     ` David Howells
  2009-07-15 11:12       ` [Uclinux-dist-devel] " Mike Frysinger
@ 2009-07-15 11:45       ` David Howells
  2009-07-15 11:55         ` Mike Frysinger
  2009-07-15 12:25         ` David Howells
  1 sibling, 2 replies; 18+ messages in thread
From: David Howells @ 2009-07-15 11:45 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: dhowells, Bernd Schmidt, uclinux-dist-devel, linux-kernel

Mike Frysinger <vapier.adi@gmail.com> wrote:

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

So you have a separate bitmap per process?

David

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Uclinux-dist-devel] [PATCH v2] NOMMU: add support for Memory  Protection Units (MPU)
  2009-07-15 11:45       ` David Howells
@ 2009-07-15 11:55         ` Mike Frysinger
  2009-07-15 12:25         ` David Howells
  1 sibling, 0 replies; 18+ messages in thread
From: Mike Frysinger @ 2009-07-15 11:55 UTC (permalink / raw)
  To: David Howells; +Cc: Bernd Schmidt, uclinux-dist-devel, linux-kernel

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

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Uclinux-dist-devel] [PATCH v2] NOMMU: add support for Memory Protection Units (MPU)
  2009-07-15 11:45       ` David Howells
  2009-07-15 11:55         ` Mike Frysinger
@ 2009-07-15 12:25         ` David Howells
  2009-07-15 12:52           ` Mike Frysinger
  1 sibling, 1 reply; 18+ messages in thread
From: David Howells @ 2009-07-15 12:25 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: dhowells, Bernd Schmidt, uclinux-dist-devel, linux-kernel

Mike Frysinger <vapier.adi@gmail.com> 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

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Uclinux-dist-devel] [PATCH v2] NOMMU: add support for Memory  Protection Units (MPU)
  2009-07-15 12:25         ` David Howells
@ 2009-07-15 12:52           ` Mike Frysinger
  0 siblings, 0 replies; 18+ messages in thread
From: Mike Frysinger @ 2009-07-15 12:52 UTC (permalink / raw)
  To: David Howells; +Cc: Bernd Schmidt, uclinux-dist-devel, linux-kernel

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

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v2] NOMMU: add support for Memory Protection Units (MPU)
  2009-07-14 17:14   ` [PATCH v2] " Mike Frysinger
@ 2009-09-14  3:52     ` Mike Frysinger
  2009-09-16 10:09     ` David Howells
  1 sibling, 0 replies; 18+ messages in thread
From: Mike Frysinger @ 2009-09-14  3:52 UTC (permalink / raw)
  To: David Howells; +Cc: linux-kernel, uclinux-dist-devel, Bernd Schmidt, Bryan Wu

On Tue, Jul 14, 2009 at 13:14, Mike Frysinger wrote:
> From: Bernd Schmidt <bernds_cb1@t-online.de>
>
> 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

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v2] NOMMU: add support for Memory Protection Units (MPU)
  2009-07-14 17:14   ` [PATCH v2] " Mike Frysinger
  2009-09-14  3:52     ` Mike Frysinger
@ 2009-09-16 10:09     ` David Howells
  1 sibling, 0 replies; 18+ messages in thread
From: David Howells @ 2009-09-16 10:09 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: dhowells, linux-kernel, uclinux-dist-devel, Bernd Schmidt, Bryan Wu

Mike Frysinger <vapier.adi@gmail.com> wrote:

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

Go for it, and add my Acked-by.

David

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH] NOMMU: add support for Memory Protection Units (MPU)
  2009-07-14 14:22 [PATCH] NOMMU: add support for Memory Protection Units (MPU) Mike Frysinger
  2009-07-14 16:14 ` Johannes Weiner
@ 2009-09-16 13:57 ` Mike Frysinger
  1 sibling, 0 replies; 18+ messages in thread
From: Mike Frysinger @ 2009-09-16 13:57 UTC (permalink / raw)
  To: Linus Torvalds, Andrew Morton
  Cc: linux-kernel, uclinux-dist-devel, David Howells, Bernd Schmidt, Bryan Wu

From: Bernd Schmidt <bernds_cb1@t-online.de>

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


^ permalink raw reply related	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2009-09-16 13:57 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-07-14 14:22 [PATCH] NOMMU: add support for Memory Protection Units (MPU) Mike Frysinger
2009-07-14 16:14 ` Johannes Weiner
2009-07-14 16:19   ` Mike Frysinger
2009-07-14 17:14   ` [PATCH v2] " Mike Frysinger
2009-09-14  3:52     ` Mike Frysinger
2009-09-16 10:09     ` David Howells
2009-07-14 17:22   ` David Howells
2009-07-14 21:59     ` Bernd Schmidt
2009-07-15  9:24     ` Paul Mundt
2009-07-15 10:31     ` David Howells
2009-07-15 11:18       ` [Uclinux-dist-devel] " Mike Frysinger
2009-07-15 10:37     ` David Howells
2009-07-15 11:12       ` [Uclinux-dist-devel] " Mike Frysinger
2009-07-15 11:45       ` David Howells
2009-07-15 11:55         ` Mike Frysinger
2009-07-15 12:25         ` David Howells
2009-07-15 12:52           ` Mike Frysinger
2009-09-16 13:57 ` [PATCH] " Mike Frysinger

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.