2020-03-16 12:38:56

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 16/46] powerpc/mm: Allocate static page tables for fixmap

Allocate static page tables for the fixmap area. This allows
setting mappings through page tables before memblock is ready.
That's needed to use early_ioremap() early and to use standard
page mappings with fixmap.

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/include/asm/fixmap.h | 4 ++++
arch/powerpc/kernel/setup_32.c | 2 +-
arch/powerpc/mm/pgtable_32.c | 16 ++++++++++++++++
3 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/fixmap.h b/arch/powerpc/include/asm/fixmap.h
index 2ef155a3c821..ccbe2e83c950 100644
--- a/arch/powerpc/include/asm/fixmap.h
+++ b/arch/powerpc/include/asm/fixmap.h
@@ -86,6 +86,10 @@ enum fixed_addresses {
#define __FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
#define FIXADDR_START (FIXADDR_TOP - __FIXADDR_SIZE)

+#define FIXMAP_ALIGNED_SIZE (ALIGN(FIXADDR_TOP, PGDIR_SIZE) - \
+ ALIGN_DOWN(FIXADDR_START, PGDIR_SIZE))
+#define FIXMAP_PTE_SIZE (FIXMAP_ALIGNED_SIZE / PGDIR_SIZE * PTE_TABLE_SIZE)
+
#define FIXMAP_PAGE_NOCACHE PAGE_KERNEL_NCG
#define FIXMAP_PAGE_IO PAGE_KERNEL_NCG

diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 5b49b26eb154..3f1e1c0b328a 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -81,7 +81,7 @@ notrace void __init machine_init(u64 dt_ptr)
/* Configure static keys first, now that we're relocated. */
setup_feature_keys();

- early_ioremap_setup();
+ early_ioremap_init();

/* Enable early debugging if any specified (see udbg.h) */
udbg_early_init();
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index f62de06e3d07..9934659cb871 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -29,11 +29,27 @@
#include <asm/fixmap.h>
#include <asm/setup.h>
#include <asm/sections.h>
+#include <asm/early_ioremap.h>

#include <mm/mmu_decl.h>

extern char etext[], _stext[], _sinittext[], _einittext[];

+static u8 early_fixmap_pagetable[FIXMAP_PTE_SIZE] __page_aligned_data;
+
+notrace void __init early_ioremap_init(void)
+{
+ unsigned long addr = ALIGN_DOWN(FIXADDR_START, PGDIR_SIZE);
+ pte_t *ptep = (pte_t *)early_fixmap_pagetable;
+ pmd_t *pmdp = pmd_ptr_k(addr);
+
+ for (; (s32)(FIXADDR_TOP - addr) > 0;
+ addr += PGDIR_SIZE, ptep += PTRS_PER_PTE, pmdp++)
+ pmd_populate_kernel(&init_mm, pmdp, ptep);
+
+ early_ioremap_setup();
+}
+
static void __init *early_alloc_pgtable(unsigned long size)
{
void *ptr = memblock_alloc(size, size);
--
2.25.0


2020-03-17 14:40:02

by Christophe Leroy

[permalink] [raw]
Subject: Re: [PATCH v1 16/46] powerpc/mm: Allocate static page tables for fixmap



Le 16/03/2020 à 13:36, Christophe Leroy a écrit :
> Allocate static page tables for the fixmap area. This allows
> setting mappings through page tables before memblock is ready.
> That's needed to use early_ioremap() early and to use standard
> page mappings with fixmap.
>
> Signed-off-by: Christophe Leroy <[email protected]>
> ---
> arch/powerpc/include/asm/fixmap.h | 4 ++++
> arch/powerpc/kernel/setup_32.c | 2 +-
> arch/powerpc/mm/pgtable_32.c | 16 ++++++++++++++++
> 3 files changed, 21 insertions(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/include/asm/fixmap.h b/arch/powerpc/include/asm/fixmap.h
> index 2ef155a3c821..ccbe2e83c950 100644
> --- a/arch/powerpc/include/asm/fixmap.h
> +++ b/arch/powerpc/include/asm/fixmap.h
> @@ -86,6 +86,10 @@ enum fixed_addresses {
> #define __FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
> #define FIXADDR_START (FIXADDR_TOP - __FIXADDR_SIZE)
>
> +#define FIXMAP_ALIGNED_SIZE (ALIGN(FIXADDR_TOP, PGDIR_SIZE) - \
> + ALIGN_DOWN(FIXADDR_START, PGDIR_SIZE))
> +#define FIXMAP_PTE_SIZE (FIXMAP_ALIGNED_SIZE / PGDIR_SIZE * PTE_TABLE_SIZE)
> +
> #define FIXMAP_PAGE_NOCACHE PAGE_KERNEL_NCG
> #define FIXMAP_PAGE_IO PAGE_KERNEL_NCG
>
> diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
> index 5b49b26eb154..3f1e1c0b328a 100644
> --- a/arch/powerpc/kernel/setup_32.c
> +++ b/arch/powerpc/kernel/setup_32.c
> @@ -81,7 +81,7 @@ notrace void __init machine_init(u64 dt_ptr)
> /* Configure static keys first, now that we're relocated. */
> setup_feature_keys();
>
> - early_ioremap_setup();
> + early_ioremap_init();
>
> /* Enable early debugging if any specified (see udbg.h) */
> udbg_early_init();
> diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
> index f62de06e3d07..9934659cb871 100644
> --- a/arch/powerpc/mm/pgtable_32.c
> +++ b/arch/powerpc/mm/pgtable_32.c
> @@ -29,11 +29,27 @@
> #include <asm/fixmap.h>
> #include <asm/setup.h>
> #include <asm/sections.h>
> +#include <asm/early_ioremap.h>
>
> #include <mm/mmu_decl.h>
>
> extern char etext[], _stext[], _sinittext[], _einittext[];
>
> +static u8 early_fixmap_pagetable[FIXMAP_PTE_SIZE] __page_aligned_data;

Sparse reports this as a variable size array. This is definitely not.
Gcc properly sees it is an 8k table (2 pages).

Christophe


> +
> +notrace void __init early_ioremap_init(void)
> +{
> + unsigned long addr = ALIGN_DOWN(FIXADDR_START, PGDIR_SIZE);
> + pte_t *ptep = (pte_t *)early_fixmap_pagetable;
> + pmd_t *pmdp = pmd_ptr_k(addr);
> +
> + for (; (s32)(FIXADDR_TOP - addr) > 0;
> + addr += PGDIR_SIZE, ptep += PTRS_PER_PTE, pmdp++)
> + pmd_populate_kernel(&init_mm, pmdp, ptep);
> +
> + early_ioremap_setup();
> +}
> +
> static void __init *early_alloc_pgtable(unsigned long size)
> {
> void *ptr = memblock_alloc(size, size);
>

Christophe

2020-03-17 16:01:41

by Luc Van Oostenryck

[permalink] [raw]
Subject: Re: [PATCH v1 16/46] powerpc/mm: Allocate static page tables for fixmap

On Tue, Mar 17, 2020 at 03:38:46PM +0100, Christophe Leroy wrote:
> > diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
> > index f62de06e3d07..9934659cb871 100644
> > --- a/arch/powerpc/mm/pgtable_32.c
> > +++ b/arch/powerpc/mm/pgtable_32.c
> > @@ -29,11 +29,27 @@
> > #include <asm/fixmap.h>
> > #include <asm/setup.h>
> > #include <asm/sections.h>
> > +#include <asm/early_ioremap.h>
> > #include <mm/mmu_decl.h>
> > extern char etext[], _stext[], _sinittext[], _einittext[];
> > +static u8 early_fixmap_pagetable[FIXMAP_PTE_SIZE] __page_aligned_data;
>
> Sparse reports this as a variable size array. This is definitely not. Gcc
> properly sees it is an 8k table (2 pages).

Yes, thing is that FIXMAP_PTE_SIZE is not that constant since it uses
__builtin_ffs() (via PTE_SHIFT / PTE_T_LOG2).
Nevertheless, since Sparse v0.6.1 (released in October) accepts these
in constant expressions, like GCC does.

-- Luc