2023-04-28 12:05:44

by Alexandre Ghiti

[permalink] [raw]
Subject: [PATCH -fixes 1/2] riscv: Fix huge_ptep_set_wrprotect when PTE is a NAPOT

We need to avoid inconsistencies across the PTEs that form a NAPOT
region, so when we write protect such a region, we should clear and flush
all the PTEs to make sure that any of those PTEs is not cached which would
result in such inconsistencies (arm64 does the same).

Fixes: f2aeb0118ddd ("riscv: mm: support Svnapot in hugetlb page")
Signed-off-by: Alexandre Ghiti <[email protected]>
---
arch/riscv/mm/hugetlbpage.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c
index a163a3e0f0d4..238d00bdac14 100644
--- a/arch/riscv/mm/hugetlbpage.c
+++ b/arch/riscv/mm/hugetlbpage.c
@@ -218,6 +218,7 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm,
{
pte_t pte = ptep_get(ptep);
unsigned long order;
+ pte_t orig_pte;
int i, pte_num;

if (!pte_napot(pte)) {
@@ -228,9 +229,12 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm,
order = napot_cont_order(pte);
pte_num = napot_pte_num(order);
ptep = huge_pte_offset(mm, addr, napot_cont_size(order));
+ orig_pte = get_clear_contig_flush(mm, addr, ptep, pte_num);
+
+ orig_pte = pte_wrprotect(orig_pte);

for (i = 0; i < pte_num; i++, addr += PAGE_SIZE, ptep++)
- ptep_set_wrprotect(mm, addr, ptep);
+ set_pte_at(mm, addr, ptep, orig_pte);
}

pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
--
2.37.2


2023-04-28 12:06:02

by Alexandre Ghiti

[permalink] [raw]
Subject: [PATCH -fixes 2/2] riscv: Implement missing huge_ptep_get

huge_ptep_get must be reimplemented in order to go through all the PTEs
of a NAPOT region: this is needed because the HW can update the A/D bits
of any of the PTE that constitutes the NAPOT region.

Fixes: f2aeb0118ddd ("riscv: mm: support Svnapot in hugetlb page")
Signed-off-by: Alexandre Ghiti <[email protected]>
---
arch/riscv/include/asm/hugetlb.h | 3 +++
arch/riscv/mm/hugetlbpage.c | 24 ++++++++++++++++++++++++
2 files changed, 27 insertions(+)

diff --git a/arch/riscv/include/asm/hugetlb.h b/arch/riscv/include/asm/hugetlb.h
index fe6f23006641..ce1ebda1a49a 100644
--- a/arch/riscv/include/asm/hugetlb.h
+++ b/arch/riscv/include/asm/hugetlb.h
@@ -36,6 +36,9 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep,
pte_t pte, int dirty);

+#define __HAVE_ARCH_HUGE_PTEP_GET
+pte_t huge_ptep_get(pte_t *ptep);
+
pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags);
#define arch_make_huge_pte arch_make_huge_pte

diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c
index 238d00bdac14..e0ef56dc57b9 100644
--- a/arch/riscv/mm/hugetlbpage.c
+++ b/arch/riscv/mm/hugetlbpage.c
@@ -3,6 +3,30 @@
#include <linux/err.h>

#ifdef CONFIG_RISCV_ISA_SVNAPOT
+pte_t huge_ptep_get(pte_t *ptep)
+{
+ unsigned long pte_num;
+ int i;
+ pte_t orig_pte = ptep_get(ptep);
+
+ if (!pte_present(orig_pte) || !pte_napot(orig_pte))
+ return orig_pte;
+
+ pte_num = napot_pte_num(napot_cont_order(orig_pte));
+
+ for (i = 0; i < pte_num; i++, ptep++) {
+ pte_t pte = ptep_get(ptep);
+
+ if (pte_dirty(pte))
+ orig_pte = pte_mkdirty(orig_pte);
+
+ if (pte_young(pte))
+ orig_pte = pte_mkyoung(orig_pte);
+ }
+
+ return orig_pte;
+}
+
pte_t *huge_pte_alloc(struct mm_struct *mm,
struct vm_area_struct *vma,
unsigned long addr,
--
2.37.2

2023-04-28 12:41:57

by Andrew Jones

[permalink] [raw]
Subject: Re: [PATCH -fixes 1/2] riscv: Fix huge_ptep_set_wrprotect when PTE is a NAPOT

On Fri, Apr 28, 2023 at 02:01:19PM +0200, Alexandre Ghiti wrote:
> We need to avoid inconsistencies across the PTEs that form a NAPOT
> region, so when we write protect such a region, we should clear and flush
> all the PTEs to make sure that any of those PTEs is not cached which would
> result in such inconsistencies (arm64 does the same).
>
> Fixes: f2aeb0118ddd ("riscv: mm: support Svnapot in hugetlb page")
> Signed-off-by: Alexandre Ghiti <[email protected]>
> ---
> arch/riscv/mm/hugetlbpage.c | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c
> index a163a3e0f0d4..238d00bdac14 100644
> --- a/arch/riscv/mm/hugetlbpage.c
> +++ b/arch/riscv/mm/hugetlbpage.c
> @@ -218,6 +218,7 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm,
> {
> pte_t pte = ptep_get(ptep);
> unsigned long order;
> + pte_t orig_pte;
> int i, pte_num;
>
> if (!pte_napot(pte)) {
> @@ -228,9 +229,12 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm,
> order = napot_cont_order(pte);
> pte_num = napot_pte_num(order);
> ptep = huge_pte_offset(mm, addr, napot_cont_size(order));
> + orig_pte = get_clear_contig_flush(mm, addr, ptep, pte_num);
> +
> + orig_pte = pte_wrprotect(orig_pte);
>
> for (i = 0; i < pte_num; i++, addr += PAGE_SIZE, ptep++)
> - ptep_set_wrprotect(mm, addr, ptep);
> + set_pte_at(mm, addr, ptep, orig_pte);
> }
>
> pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
> --
> 2.37.2
>

Reviewed-by: Andrew Jones <[email protected]>

2023-04-28 12:41:57

by Andrew Jones

[permalink] [raw]
Subject: Re: [PATCH -fixes 2/2] riscv: Implement missing huge_ptep_get

On Fri, Apr 28, 2023 at 02:01:20PM +0200, Alexandre Ghiti wrote:
> huge_ptep_get must be reimplemented in order to go through all the PTEs
> of a NAPOT region: this is needed because the HW can update the A/D bits
> of any of the PTE that constitutes the NAPOT region.
>
> Fixes: f2aeb0118ddd ("riscv: mm: support Svnapot in hugetlb page")
> Signed-off-by: Alexandre Ghiti <[email protected]>
> ---
> arch/riscv/include/asm/hugetlb.h | 3 +++
> arch/riscv/mm/hugetlbpage.c | 24 ++++++++++++++++++++++++
> 2 files changed, 27 insertions(+)
>
> diff --git a/arch/riscv/include/asm/hugetlb.h b/arch/riscv/include/asm/hugetlb.h
> index fe6f23006641..ce1ebda1a49a 100644
> --- a/arch/riscv/include/asm/hugetlb.h
> +++ b/arch/riscv/include/asm/hugetlb.h
> @@ -36,6 +36,9 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
> unsigned long addr, pte_t *ptep,
> pte_t pte, int dirty);
>
> +#define __HAVE_ARCH_HUGE_PTEP_GET
> +pte_t huge_ptep_get(pte_t *ptep);
> +
> pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags);
> #define arch_make_huge_pte arch_make_huge_pte
>
> diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c
> index 238d00bdac14..e0ef56dc57b9 100644
> --- a/arch/riscv/mm/hugetlbpage.c
> +++ b/arch/riscv/mm/hugetlbpage.c
> @@ -3,6 +3,30 @@
> #include <linux/err.h>
>
> #ifdef CONFIG_RISCV_ISA_SVNAPOT
> +pte_t huge_ptep_get(pte_t *ptep)
> +{
> + unsigned long pte_num;
> + int i;
> + pte_t orig_pte = ptep_get(ptep);
> +
> + if (!pte_present(orig_pte) || !pte_napot(orig_pte))
> + return orig_pte;
> +
> + pte_num = napot_pte_num(napot_cont_order(orig_pte));
> +
> + for (i = 0; i < pte_num; i++, ptep++) {
> + pte_t pte = ptep_get(ptep);
> +
> + if (pte_dirty(pte))
> + orig_pte = pte_mkdirty(orig_pte);
> +
> + if (pte_young(pte))
> + orig_pte = pte_mkyoung(orig_pte);
> + }
> +
> + return orig_pte;
> +}
> +
> pte_t *huge_pte_alloc(struct mm_struct *mm,
> struct vm_area_struct *vma,
> unsigned long addr,
> --
> 2.37.2
>

Reviewed-by: Andrew Jones <[email protected]>

2023-04-28 20:50:27

by Conor Dooley

[permalink] [raw]
Subject: Re: [PATCH -fixes 1/2] riscv: Fix huge_ptep_set_wrprotect when PTE is a NAPOT

On Fri, Apr 28, 2023 at 02:01:19PM +0200, Alexandre Ghiti wrote:
> We need to avoid inconsistencies across the PTEs that form a NAPOT
> region, so when we write protect such a region, we should clear and flush
> all the PTEs to make sure that any of those PTEs is not cached which would
> result in such inconsistencies (arm64 does the same).
>
> Fixes: f2aeb0118ddd ("riscv: mm: support Svnapot in hugetlb page")

For both patches I get:
Commit: 0146c955ff59 ("riscv: Fix huge_ptep_set_wrprotect when PTE is a NAPOT")
Fixes tag: Fixes: f2aeb0118ddd ("riscv: mm: support Svnapot in hugetlb page")
Has these problem(s):
- Target SHA1 does not exist

This particular one is 82a1a1f3bfb6 in riscv/for-next.

Cheers,
Conor.


Attachments:
(No filename) (743.00 B)
signature.asc (235.00 B)
Download all attachments

2023-06-01 20:19:32

by Palmer Dabbelt

[permalink] [raw]
Subject: Re: [PATCH -fixes 1/2] riscv: Fix huge_ptep_set_wrprotect when PTE is a NAPOT


On Fri, 28 Apr 2023 14:01:19 +0200, Alexandre Ghiti wrote:
> We need to avoid inconsistencies across the PTEs that form a NAPOT
> region, so when we write protect such a region, we should clear and flush
> all the PTEs to make sure that any of those PTEs is not cached which would
> result in such inconsistencies (arm64 does the same).
>
>

Applied, thanks!

[1/2] riscv: Fix huge_ptep_set_wrprotect when PTE is a NAPOT
https://git.kernel.org/palmer/c/d22ce4f4137a
[2/2] riscv: Implement missing huge_ptep_get
https://git.kernel.org/palmer/c/640ad2677d56

Best regards,
--
Palmer Dabbelt <[email protected]>