Re: [PATCH 09/17] powerpc: make __ioremap_caller() common to PPC32 and PPC64

2018-05-16 Thread Christophe LEROY



Le 08/05/2018 à 11:56, Aneesh Kumar K.V a écrit :

Christophe Leroy  writes:


Signed-off-by: Christophe Leroy 
---
  arch/powerpc/include/asm/book3s/64/pgtable.h |   1 +
  arch/powerpc/mm/ioremap.c| 126 +++
  2 files changed, 34 insertions(+), 93 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h 
b/arch/powerpc/include/asm/book3s/64/pgtable.h
index c5c6ead06bfb..2bebdd8302cb 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -18,6 +18,7 @@
  #define _PAGE_RO  0
  #define _PAGE_USER0
  #define _PAGE_HWWRITE 0
+#define _PAGE_COHERENT 0


This is something I was trying to avoid when I split the headers. We do
support _PAGE_USER it is !_PAGE_PRIVILEGED. It gets really confusing
when we have these conflicting names because we are trying to make code
common across platforms.


Euh ... Here patch adds _PAGE_COHERENT

_PAGE_USER was added some time ago.

Well, we have three cases:

BOOK3S64 and NOHASH32/8xx has _PAGE_PRIVILEGED and no _PAGE_USER
BOOKE has both _PAGE_PRIVILEGED and _PAGE_USER
Others have _PAGE_USER and no _PAGE_PRIVILEGED

So when giving user rights to a page, some will set _PAGE_USER, some 
will unset _PAGE_PRIVILEGED and some will do both.


_PAGE_USER and _PAGE_PRIVILEGED being used outside of the subarch headers,
- either we have to add uggly ifdefs
- or we can just make sure unused flags are set as 0, then  (x | 0) and 
(x & ~0) will do nothing and will be eliminated by the compiler.


Today, this is done in asm/pte-common.h. Unfortunately, all headers 
except book3s64 do include pte-common.


Another solution would be to make sure _PAGE_xxx flags are not used 
outside of subarch specific headers. That would mean having specific 
helpers defined in each subarch header, but is it really worth it ?





Lets take the exemple of an even more tricky one :
- Some subarchs have _PAGE_RW, others have _PAGE_RO instead. In 
addition, the 8xx has _PAGE_NA

- Book3s64 has _PAGE_READ and _PAGE_WRITE.
- In some places, _PAGE_RW has been redefined has _PAGE_READ | _PAGE_WRITE

It has really become pretty complex. Why having defined new flags 
instead of using _PAGE_RO for _PAGE_READ and _PAGE_RW for _PAGE_READ | 
_PAGE_WRITE ? Does it make any sense to have the possibility to set 
_PAGE_WRITE without _PAGE_READ ?



I feel like having simple generic code like:

flags = (flags & ~_PAGE_PRIVILEGED) | _PAGE_USER;

is better than having almost same code duplicated in several places or 
ugly ifdefs like:


#if defined(CONFIG_BOOK3S64) || defined(CONFIG_PPC_8xx) || defined 
(CONFIG_BOOKE)

flags &= ~_PAGE_PRIVILEGED;
#endif
#if !defined(CONFIG_BOOK3S64) && !defined(CONFIG_PPC_8xx)
flags |= _PAGE_USER;
#endif


It looks to me that patch 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=812fadcb941a81d1f3948b10a95a4dce663da3e4 
allowed a nice code simplification, don't you feel the same ?


Christophe




  
  #define _PAGE_EXEC		0x1 /* execute permission */

  #define _PAGE_WRITE   0x2 /* write access allowed */
diff --git a/arch/powerpc/mm/ioremap.c b/arch/powerpc/mm/ioremap.c
index 65d611d44d38..59be5dfcb3e9 100644
--- a/arch/powerpc/mm/ioremap.c
+++ b/arch/powerpc/mm/ioremap.c
@@ -33,95 +33,6 @@ unsigned long ioremap_bot;
  unsigned long ioremap_bot = IOREMAP_BASE;
  #endif
  
-#ifdef CONFIG_PPC32

-
-void __iomem *
-__ioremap_caller(phys_addr_t addr, unsigned long size, unsigned long flags,
-void *caller)
-{
-   unsigned long v, i;
-   phys_addr_t p;
-   int err;
-
-   /* Make sure we have the base flags */
-   if ((flags & _PAGE_PRESENT) == 0)
-   flags |= pgprot_val(PAGE_KERNEL);
-
-   /* Non-cacheable page cannot be coherent */
-   if (flags & _PAGE_NO_CACHE)
-   flags &= ~_PAGE_COHERENT;
-
-   /*
-* Choose an address to map it to.
-* Once the vmalloc system is running, we use it.
-* Before then, we use space going up from IOREMAP_BASE
-* (ioremap_bot records where we're up to).
-*/
-   p = addr & PAGE_MASK;
-   size = PAGE_ALIGN(addr + size) - p;
-
-   /*
-* If the address lies within the first 16 MB, assume it's in ISA
-* memory space
-*/
-   if (p < 16*1024*1024)
-   p += _ISA_MEM_BASE;
-
-#ifndef CONFIG_CRASH_DUMP
-   /*
-* Don't allow anybody to remap normal RAM that we're using.
-* mem_init() sets high_memory so only do the check after that.
-*/
-   if (slab_is_available() && (p < virt_to_phys(high_memory)) &&
-   page_is_ram(__phys_to_pfn(p))) {
-   printk("__ioremap(): phys addr 0x%llx is RAM lr %ps\n",
-  (unsigned long long)p, __builtin_return_address(0));
-   return NULL;
-   }
-#endif
-
-   if (size == 0)
-  

Re: [PATCH 09/17] powerpc: make __ioremap_caller() common to PPC32 and PPC64

2018-05-08 Thread Aneesh Kumar K.V
Christophe Leroy  writes:

> Signed-off-by: Christophe Leroy 
> ---
>  arch/powerpc/include/asm/book3s/64/pgtable.h |   1 +
>  arch/powerpc/mm/ioremap.c| 126 
> +++
>  2 files changed, 34 insertions(+), 93 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h 
> b/arch/powerpc/include/asm/book3s/64/pgtable.h
> index c5c6ead06bfb..2bebdd8302cb 100644
> --- a/arch/powerpc/include/asm/book3s/64/pgtable.h
> +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
> @@ -18,6 +18,7 @@
>  #define _PAGE_RO 0
>  #define _PAGE_USER   0
>  #define _PAGE_HWWRITE0
> +#define _PAGE_COHERENT   0

This is something I was trying to avoid when I split the headers. We do
support _PAGE_USER it is !_PAGE_PRIVILEGED. It gets really confusing
when we have these conflicting names because we are trying to make code
common across platforms.


>  
>  #define _PAGE_EXEC   0x1 /* execute permission */
>  #define _PAGE_WRITE  0x2 /* write access allowed */
> diff --git a/arch/powerpc/mm/ioremap.c b/arch/powerpc/mm/ioremap.c
> index 65d611d44d38..59be5dfcb3e9 100644
> --- a/arch/powerpc/mm/ioremap.c
> +++ b/arch/powerpc/mm/ioremap.c
> @@ -33,95 +33,6 @@ unsigned long ioremap_bot;
>  unsigned long ioremap_bot = IOREMAP_BASE;
>  #endif
>  
> -#ifdef CONFIG_PPC32
> -
> -void __iomem *
> -__ioremap_caller(phys_addr_t addr, unsigned long size, unsigned long flags,
> -  void *caller)
> -{
> - unsigned long v, i;
> - phys_addr_t p;
> - int err;
> -
> - /* Make sure we have the base flags */
> - if ((flags & _PAGE_PRESENT) == 0)
> - flags |= pgprot_val(PAGE_KERNEL);
> -
> - /* Non-cacheable page cannot be coherent */
> - if (flags & _PAGE_NO_CACHE)
> - flags &= ~_PAGE_COHERENT;
> -
> - /*
> -  * Choose an address to map it to.
> -  * Once the vmalloc system is running, we use it.
> -  * Before then, we use space going up from IOREMAP_BASE
> -  * (ioremap_bot records where we're up to).
> -  */
> - p = addr & PAGE_MASK;
> - size = PAGE_ALIGN(addr + size) - p;
> -
> - /*
> -  * If the address lies within the first 16 MB, assume it's in ISA
> -  * memory space
> -  */
> - if (p < 16*1024*1024)
> - p += _ISA_MEM_BASE;
> -
> -#ifndef CONFIG_CRASH_DUMP
> - /*
> -  * Don't allow anybody to remap normal RAM that we're using.
> -  * mem_init() sets high_memory so only do the check after that.
> -  */
> - if (slab_is_available() && (p < virt_to_phys(high_memory)) &&
> - page_is_ram(__phys_to_pfn(p))) {
> - printk("__ioremap(): phys addr 0x%llx is RAM lr %ps\n",
> -(unsigned long long)p, __builtin_return_address(0));
> - return NULL;
> - }
> -#endif
> -
> - if (size == 0)
> - return NULL;
> -
> - /*
> -  * Is it already mapped?  Perhaps overlapped by a previous
> -  * mapping.
> -  */
> - v = p_block_mapped(p);
> - if (v)
> - goto out;
> -
> - if (slab_is_available()) {
> - struct vm_struct *area;
> - area = get_vm_area_caller(size, VM_IOREMAP, caller);
> - if (area == 0)
> - return NULL;
> - area->phys_addr = p;
> - v = (unsigned long) area->addr;
> - } else {
> - v = ioremap_bot;
> - ioremap_bot += size;
> - }
> -
> - /*
> -  * Should check if it is a candidate for a BAT mapping
> -  */
> -
> - err = 0;
> - for (i = 0; i < size && err == 0; i += PAGE_SIZE)
> - err = map_kernel_page(v+i, p+i, flags);
> - if (err) {
> - if (slab_is_available())
> - vunmap((void *)v);
> - return NULL;
> - }
> -
> -out:
> - return (void __iomem *) (v + ((unsigned long)addr & ~PAGE_MASK));
> -}
> -
> -#else
> -
>  /**
>   * __ioremap_at - Low level function to establish the page tables
>   *for an IO mapping
> @@ -135,6 +46,10 @@ void __iomem * __ioremap_at(phys_addr_t pa, void *ea, 
> unsigned long size,
>   if ((flags & _PAGE_PRESENT) == 0)
>   flags |= pgprot_val(PAGE_KERNEL);
>  
> + /* Non-cacheable page cannot be coherent */
> + if (flags & _PAGE_NO_CACHE)
> + flags &= ~_PAGE_COHERENT;
> +
>   /* We don't support the 4K PFN hack with ioremap */
>   if (flags & H_PAGE_4K_PFN)
>   return NULL;
> @@ -187,6 +102,33 @@ void __iomem * __ioremap_caller(phys_addr_t addr, 
> unsigned long size,
>   if ((size == 0) || (paligned == 0))
>   return NULL;
>  
> + /*
> +  * If the address lies within the first 16 MB, assume it's in ISA
> +  * memory space
> +  */
> + if (IS_ENABLED(CONFIG_PPC32) && paligned < 16*1024*1024)
> + paligned += _ISA_MEM_BASE;
> +
> + /*
> +  * Don't a

[PATCH 09/17] powerpc: make __ioremap_caller() common to PPC32 and PPC64

2018-05-04 Thread Christophe Leroy
Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/book3s/64/pgtable.h |   1 +
 arch/powerpc/mm/ioremap.c| 126 +++
 2 files changed, 34 insertions(+), 93 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h 
b/arch/powerpc/include/asm/book3s/64/pgtable.h
index c5c6ead06bfb..2bebdd8302cb 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -18,6 +18,7 @@
 #define _PAGE_RO   0
 #define _PAGE_USER 0
 #define _PAGE_HWWRITE  0
+#define _PAGE_COHERENT 0
 
 #define _PAGE_EXEC 0x1 /* execute permission */
 #define _PAGE_WRITE0x2 /* write access allowed */
diff --git a/arch/powerpc/mm/ioremap.c b/arch/powerpc/mm/ioremap.c
index 65d611d44d38..59be5dfcb3e9 100644
--- a/arch/powerpc/mm/ioremap.c
+++ b/arch/powerpc/mm/ioremap.c
@@ -33,95 +33,6 @@ unsigned long ioremap_bot;
 unsigned long ioremap_bot = IOREMAP_BASE;
 #endif
 
-#ifdef CONFIG_PPC32
-
-void __iomem *
-__ioremap_caller(phys_addr_t addr, unsigned long size, unsigned long flags,
-void *caller)
-{
-   unsigned long v, i;
-   phys_addr_t p;
-   int err;
-
-   /* Make sure we have the base flags */
-   if ((flags & _PAGE_PRESENT) == 0)
-   flags |= pgprot_val(PAGE_KERNEL);
-
-   /* Non-cacheable page cannot be coherent */
-   if (flags & _PAGE_NO_CACHE)
-   flags &= ~_PAGE_COHERENT;
-
-   /*
-* Choose an address to map it to.
-* Once the vmalloc system is running, we use it.
-* Before then, we use space going up from IOREMAP_BASE
-* (ioremap_bot records where we're up to).
-*/
-   p = addr & PAGE_MASK;
-   size = PAGE_ALIGN(addr + size) - p;
-
-   /*
-* If the address lies within the first 16 MB, assume it's in ISA
-* memory space
-*/
-   if (p < 16*1024*1024)
-   p += _ISA_MEM_BASE;
-
-#ifndef CONFIG_CRASH_DUMP
-   /*
-* Don't allow anybody to remap normal RAM that we're using.
-* mem_init() sets high_memory so only do the check after that.
-*/
-   if (slab_is_available() && (p < virt_to_phys(high_memory)) &&
-   page_is_ram(__phys_to_pfn(p))) {
-   printk("__ioremap(): phys addr 0x%llx is RAM lr %ps\n",
-  (unsigned long long)p, __builtin_return_address(0));
-   return NULL;
-   }
-#endif
-
-   if (size == 0)
-   return NULL;
-
-   /*
-* Is it already mapped?  Perhaps overlapped by a previous
-* mapping.
-*/
-   v = p_block_mapped(p);
-   if (v)
-   goto out;
-
-   if (slab_is_available()) {
-   struct vm_struct *area;
-   area = get_vm_area_caller(size, VM_IOREMAP, caller);
-   if (area == 0)
-   return NULL;
-   area->phys_addr = p;
-   v = (unsigned long) area->addr;
-   } else {
-   v = ioremap_bot;
-   ioremap_bot += size;
-   }
-
-   /*
-* Should check if it is a candidate for a BAT mapping
-*/
-
-   err = 0;
-   for (i = 0; i < size && err == 0; i += PAGE_SIZE)
-   err = map_kernel_page(v+i, p+i, flags);
-   if (err) {
-   if (slab_is_available())
-   vunmap((void *)v);
-   return NULL;
-   }
-
-out:
-   return (void __iomem *) (v + ((unsigned long)addr & ~PAGE_MASK));
-}
-
-#else
-
 /**
  * __ioremap_at - Low level function to establish the page tables
  *for an IO mapping
@@ -135,6 +46,10 @@ void __iomem * __ioremap_at(phys_addr_t pa, void *ea, 
unsigned long size,
if ((flags & _PAGE_PRESENT) == 0)
flags |= pgprot_val(PAGE_KERNEL);
 
+   /* Non-cacheable page cannot be coherent */
+   if (flags & _PAGE_NO_CACHE)
+   flags &= ~_PAGE_COHERENT;
+
/* We don't support the 4K PFN hack with ioremap */
if (flags & H_PAGE_4K_PFN)
return NULL;
@@ -187,6 +102,33 @@ void __iomem * __ioremap_caller(phys_addr_t addr, unsigned 
long size,
if ((size == 0) || (paligned == 0))
return NULL;
 
+   /*
+* If the address lies within the first 16 MB, assume it's in ISA
+* memory space
+*/
+   if (IS_ENABLED(CONFIG_PPC32) && paligned < 16*1024*1024)
+   paligned += _ISA_MEM_BASE;
+
+   /*
+* Don't allow anybody to remap normal RAM that we're using.
+* mem_init() sets high_memory so only do the check after that.
+*/
+   if (!IS_ENABLED(CONFIG_CRASH_DUMP) &&
+   slab_is_available() && (paligned < virt_to_phys(high_memory)) &&
+   page_is_ram(__phys_to_pfn(paligned))) {
+   printk("__ioremap(): phys addr 0x%llx is RAM lr %ps\n",
+