diff mbox series

[v11,07/22] riscv: mm: Add p?d_leaf() definitions

Message ID 20191007153822.16518-8-steven.price@arm.com
State New, archived
Headers show
Series Generic page walk and ptdump | expand

Commit Message

Steven Price Oct. 7, 2019, 3:38 p.m. UTC
walk_page_range() is going to be allowed to walk page tables other than
those of user space. For this it needs to know when it has reached a
'leaf' entry in the page tables. This information is provided by the
p?d_leaf() functions/macros.

For riscv a page is a leaf page when it has a read, write or execute bit
set on it.

CC: Palmer Dabbelt <palmer@sifive.com>
CC: Albert Ou <aou@eecs.berkeley.edu>
CC: linux-riscv@lists.infradead.org
Signed-off-by: Steven Price <steven.price@arm.com>
---
 arch/riscv/include/asm/pgtable-64.h | 7 +++++++
 arch/riscv/include/asm/pgtable.h    | 7 +++++++
 2 files changed, 14 insertions(+)

Comments

Alex Ghiti Oct. 8, 2019, 11:31 a.m. UTC | #1
On 10/7/19 11:38 AM, Steven Price wrote:
> walk_page_range() is going to be allowed to walk page tables other than
> those of user space. For this it needs to know when it has reached a
> 'leaf' entry in the page tables. This information is provided by the
> p?d_leaf() functions/macros.
>
> For riscv a page is a leaf page when it has a read, write or execute bit
> set on it.
>
> CC: Palmer Dabbelt <palmer@sifive.com>
> CC: Albert Ou <aou@eecs.berkeley.edu>
> CC: linux-riscv@lists.infradead.org
> Signed-off-by: Steven Price <steven.price@arm.com>
> ---
>   arch/riscv/include/asm/pgtable-64.h | 7 +++++++
>   arch/riscv/include/asm/pgtable.h    | 7 +++++++
>   2 files changed, 14 insertions(+)
>
> diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h
> index 74630989006d..e88a8e8acbdf 100644
> --- a/arch/riscv/include/asm/pgtable-64.h
> +++ b/arch/riscv/include/asm/pgtable-64.h
> @@ -43,6 +43,13 @@ static inline int pud_bad(pud_t pud)
>   	return !pud_present(pud);
>   }
>   
> +#define pud_leaf	pud_leaf
> +static inline int pud_leaf(pud_t pud)
> +{
> +	return pud_present(pud)
> +		&& (pud_val(pud) & (_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC));
> +}
> +
>   static inline void set_pud(pud_t *pudp, pud_t pud)
>   {
>   	*pudp = pud;
> diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
> index 7255f2d8395b..b9a679153265 100644
> --- a/arch/riscv/include/asm/pgtable.h
> +++ b/arch/riscv/include/asm/pgtable.h
> @@ -130,6 +130,13 @@ static inline int pmd_bad(pmd_t pmd)
>   	return !pmd_present(pmd);
>   }
>   
> +#define pmd_leaf	pmd_leaf
> +static inline int pmd_leaf(pmd_t pmd)
> +{
> +	return pmd_present(pmd)
> +		&& (pmd_val(pmd) & (_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC));
> +}
> +
>   static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
>   {
>   	*pmdp = pmd;

Hi Steven,

The way you check leaf entries is correct: we do the same for hugepages. 
So is
there a reason you did not use the pmd/pud_huge functions that are 
defined in
arch/riscv/mm/hugetlbpage.c ?

Anyway, FWIW:

Reviewed-by: Alexandre Ghiti <alex@ghiti.fr>

Thanks,

Alex
Paul Walmsley Oct. 8, 2019, 9:33 p.m. UTC | #2
On Mon, 7 Oct 2019, Steven Price wrote:

> walk_page_range() is going to be allowed to walk page tables other than
> those of user space. For this it needs to know when it has reached a
> 'leaf' entry in the page tables. This information is provided by the
> p?d_leaf() functions/macros.
> 
> For riscv a page is a leaf page when it has a read, write or execute bit
> set on it.
> 
> CC: Palmer Dabbelt <palmer@sifive.com>
> CC: Albert Ou <aou@eecs.berkeley.edu>
> CC: linux-riscv@lists.infradead.org
> Signed-off-by: Steven Price <steven.price@arm.com>

Acked-by: Paul Walmsley <paul.walmsley@sifive.com> # for arch/riscv  

Alex has a good point, but probably the right thing to do is to replace 
the contents of the arch/riscv/mm/hugetlbpage.c p{u,m}d_huge() functions 
with calls to Steven's new static inline functions.


- Paul
Steven Price Oct. 9, 2019, 10:55 a.m. UTC | #3
On 08/10/2019 22:33, Paul Walmsley wrote:
> On Mon, 7 Oct 2019, Steven Price wrote:
> 
>> walk_page_range() is going to be allowed to walk page tables other than
>> those of user space. For this it needs to know when it has reached a
>> 'leaf' entry in the page tables. This information is provided by the
>> p?d_leaf() functions/macros.
>>
>> For riscv a page is a leaf page when it has a read, write or execute bit
>> set on it.
>>
>> CC: Palmer Dabbelt <palmer@sifive.com>
>> CC: Albert Ou <aou@eecs.berkeley.edu>
>> CC: linux-riscv@lists.infradead.org
>> Signed-off-by: Steven Price <steven.price@arm.com>
> 
> Acked-by: Paul Walmsley <paul.walmsley@sifive.com> # for arch/riscv  
> 
> Alex has a good point, but probably the right thing to do is to replace 
> the contents of the arch/riscv/mm/hugetlbpage.c p{u,m}d_huge() functions 
> with calls to Steven's new static inline functions.

The intention is to create new functions that are not dependent on
hugepage support in user space. hugetlbpage.c is only built if
CONFIG_HUGETLB_PAGE is defined.

As you say - the p{u,m}d_huge() functions can be reimplemented using the
new static inline functions if desired.

Thanks for the review.

Steve

> 
> - Paul
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
diff mbox series

Patch

diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h
index 74630989006d..e88a8e8acbdf 100644
--- a/arch/riscv/include/asm/pgtable-64.h
+++ b/arch/riscv/include/asm/pgtable-64.h
@@ -43,6 +43,13 @@  static inline int pud_bad(pud_t pud)
 	return !pud_present(pud);
 }
 
+#define pud_leaf	pud_leaf
+static inline int pud_leaf(pud_t pud)
+{
+	return pud_present(pud)
+		&& (pud_val(pud) & (_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC));
+}
+
 static inline void set_pud(pud_t *pudp, pud_t pud)
 {
 	*pudp = pud;
diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index 7255f2d8395b..b9a679153265 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -130,6 +130,13 @@  static inline int pmd_bad(pmd_t pmd)
 	return !pmd_present(pmd);
 }
 
+#define pmd_leaf	pmd_leaf
+static inline int pmd_leaf(pmd_t pmd)
+{
+	return pmd_present(pmd)
+		&& (pmd_val(pmd) & (_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC));
+}
+
 static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
 {
 	*pmdp = pmd;