This series addresses some generic fixes that I found while working
on UEFI series. These patches are completely independent from UEFI
implementation and can be merged sooner that UEFI.
Some of the patches were already part of the UEFI series [1]. I will
remove them from next UEFI series (v3).
Patch1 moves set up the exception vector earlier while all other patches
are mm related fixes.
[1] http://lists.infradead.org/pipermail/linux-riscv/2020-July/000942.html
Atish Patra (4):
RISC-V: Setup exception vector early
RISC-V: Set maximum number of mapped pages correctly
RISC-V: Do not rely on initrd_start/end computed during early dt
parsing
riscv: Parse all memory blocks to remove unusable memory
arch/riscv/kernel/head.S | 10 ++++--
arch/riscv/kernel/smpboot.c | 1 -
arch/riscv/kernel/traps.c | 8 +----
arch/riscv/mm/init.c | 66 +++++++++++++++++++++++++------------
4 files changed, 54 insertions(+), 31 deletions(-)
--
2.24.0
Currently, maximum physical memory allowed is equal to -PAGE_OFFSET.
That's why we remove any memory blocks spanning beyond that size. However,
it is done only for memblock containing linux kernel which will not work
if there are multiple memblocks.
Process all memory blocks to figure out how much memory needs to be removed
and remove at the end instead of updating the memblock list in place.
Signed-off-by: Atish Patra <[email protected]>
---
arch/riscv/mm/init.c | 31 +++++++++++++++++--------------
1 file changed, 17 insertions(+), 14 deletions(-)
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index f818a47a72d1..79e9d55bdf1a 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -147,26 +147,29 @@ void __init setup_bootmem(void)
{
struct memblock_region *reg;
phys_addr_t mem_size = 0;
+ phys_addr_t total_mem = 0;
+ phys_addr_t mem_start, end = 0;
phys_addr_t vmlinux_end = __pa_symbol(&_end);
phys_addr_t vmlinux_start = __pa_symbol(&_start);
/* Find the memory region containing the kernel */
for_each_memblock(memory, reg) {
- phys_addr_t end = reg->base + reg->size;
-
- if (reg->base <= vmlinux_start && vmlinux_end <= end) {
- mem_size = min(reg->size, (phys_addr_t)-PAGE_OFFSET);
-
- /*
- * Remove memblock from the end of usable area to the
- * end of region
- */
- if (reg->base + mem_size < end)
- memblock_remove(reg->base + mem_size,
- end - reg->base - mem_size);
- }
+ end = reg->base + reg->size;
+ if (!total_mem)
+ mem_start = reg->base;
+ if (reg->base <= vmlinux_start && vmlinux_end <= end)
+ BUG_ON(reg->size == 0);
+ total_mem = total_mem + reg->size;
}
- BUG_ON(mem_size == 0);
+
+ /*
+ * Remove memblock from the end of usable area to the
+ * end of region
+ */
+ mem_size = min(total_mem, (phys_addr_t)-PAGE_OFFSET);
+ if (mem_start + mem_size < end)
+ memblock_remove(mem_start + mem_size,
+ end - mem_start - mem_size);
/* Reserve from the start of the kernel to the end of the kernel */
memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start);
--
2.24.0
The trap vector is set only in trap_init which may be too late in some
cases. Early ioremap/efi spits many warning messages which may be useful.
Setup the trap vector early so that any warning/bug can be handled before
generic code invokes trap_init.
Signed-off-by: Atish Patra <[email protected]>
---
arch/riscv/kernel/head.S | 10 ++++++++--
arch/riscv/kernel/smpboot.c | 1 -
arch/riscv/kernel/traps.c | 8 +-------
3 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index 7ed1b22950fd..d0c5c316e9bb 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -77,10 +77,16 @@ relocate:
csrw CSR_SATP, a0
.align 2
1:
- /* Set trap vector to spin forever to help debug */
- la a0, .Lsecondary_park
+ /* Set trap vector to exception handler */
+ la a0, handle_exception
csrw CSR_TVEC, a0
+ /*
+ * Set sup0 scratch register to 0, indicating to exception vector that
+ * we are presently executing in kernel.
+ */
+ csrw CSR_SCRATCH, zero
+
/* Reload the global pointer */
.option push
.option norelax
diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c
index 4e9922790f6e..5a9c127a380e 100644
--- a/arch/riscv/kernel/smpboot.c
+++ b/arch/riscv/kernel/smpboot.c
@@ -154,7 +154,6 @@ asmlinkage __visible void smp_callin(void)
mmgrab(mm);
current->active_mm = mm;
- trap_init();
notify_cpu_starting(smp_processor_id());
update_siblings_masks(smp_processor_id());
set_cpu_online(smp_processor_id(), 1);
diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index 7d95cce5e47c..ad14f4466d92 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -174,13 +174,7 @@ int is_valid_bugaddr(unsigned long pc)
}
#endif /* CONFIG_GENERIC_BUG */
+/* stvec & scratch is already set from head.S */
void trap_init(void)
{
- /*
- * Set sup0 scratch register to 0, indicating to exception vector
- * that we are presently executing in the kernel
- */
- csr_write(CSR_SCRATCH, 0);
- /* Set the exception vector address */
- csr_write(CSR_TVEC, &handle_exception);
}
--
2.24.0
On Wed, 15 Jul 2020 16:30:09 PDT (-0700), Atish Patra wrote:
> Currently, maximum physical memory allowed is equal to -PAGE_OFFSET.
> That's why we remove any memory blocks spanning beyond that size. However,
> it is done only for memblock containing linux kernel which will not work
> if there are multiple memblocks.
>
> Process all memory blocks to figure out how much memory needs to be removed
> and remove at the end instead of updating the memblock list in place.
>
> Signed-off-by: Atish Patra <[email protected]>
> ---
> arch/riscv/mm/init.c | 31 +++++++++++++++++--------------
> 1 file changed, 17 insertions(+), 14 deletions(-)
>
> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> index f818a47a72d1..79e9d55bdf1a 100644
> --- a/arch/riscv/mm/init.c
> +++ b/arch/riscv/mm/init.c
> @@ -147,26 +147,29 @@ void __init setup_bootmem(void)
> {
> struct memblock_region *reg;
> phys_addr_t mem_size = 0;
> + phys_addr_t total_mem = 0;
> + phys_addr_t mem_start, end = 0;
> phys_addr_t vmlinux_end = __pa_symbol(&_end);
> phys_addr_t vmlinux_start = __pa_symbol(&_start);
>
> /* Find the memory region containing the kernel */
> for_each_memblock(memory, reg) {
> - phys_addr_t end = reg->base + reg->size;
> -
> - if (reg->base <= vmlinux_start && vmlinux_end <= end) {
> - mem_size = min(reg->size, (phys_addr_t)-PAGE_OFFSET);
> -
> - /*
> - * Remove memblock from the end of usable area to the
> - * end of region
> - */
> - if (reg->base + mem_size < end)
> - memblock_remove(reg->base + mem_size,
> - end - reg->base - mem_size);
> - }
> + end = reg->base + reg->size;
> + if (!total_mem)
> + mem_start = reg->base;
> + if (reg->base <= vmlinux_start && vmlinux_end <= end)
> + BUG_ON(reg->size == 0);
> + total_mem = total_mem + reg->size;
> }
> - BUG_ON(mem_size == 0);
> +
> + /*
> + * Remove memblock from the end of usable area to the
> + * end of region
> + */
> + mem_size = min(total_mem, (phys_addr_t)-PAGE_OFFSET);
> + if (mem_start + mem_size < end)
> + memblock_remove(mem_start + mem_size,
> + end - mem_start - mem_size);
>
> /* Reserve from the start of the kernel to the end of the kernel */
> memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start);
Thanks, this one is also on fixes.
On Wed, 15 Jul 2020 16:30:06 PDT (-0700), Atish Patra wrote:
> The trap vector is set only in trap_init which may be too late in some
> cases. Early ioremap/efi spits many warning messages which may be useful.
>
> Setup the trap vector early so that any warning/bug can be handled before
> generic code invokes trap_init.
>
> Signed-off-by: Atish Patra <[email protected]>
> ---
> arch/riscv/kernel/head.S | 10 ++++++++--
> arch/riscv/kernel/smpboot.c | 1 -
> arch/riscv/kernel/traps.c | 8 +-------
> 3 files changed, 9 insertions(+), 10 deletions(-)
>
> diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
> index 7ed1b22950fd..d0c5c316e9bb 100644
> --- a/arch/riscv/kernel/head.S
> +++ b/arch/riscv/kernel/head.S
> @@ -77,10 +77,16 @@ relocate:
> csrw CSR_SATP, a0
> .align 2
> 1:
> - /* Set trap vector to spin forever to help debug */
> - la a0, .Lsecondary_park
> + /* Set trap vector to exception handler */
> + la a0, handle_exception
> csrw CSR_TVEC, a0
>
> + /*
> + * Set sup0 scratch register to 0, indicating to exception vector that
> + * we are presently executing in kernel.
> + */
> + csrw CSR_SCRATCH, zero
> +
> /* Reload the global pointer */
> .option push
> .option norelax
> diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c
> index 4e9922790f6e..5a9c127a380e 100644
> --- a/arch/riscv/kernel/smpboot.c
> +++ b/arch/riscv/kernel/smpboot.c
> @@ -154,7 +154,6 @@ asmlinkage __visible void smp_callin(void)
> mmgrab(mm);
> current->active_mm = mm;
>
> - trap_init();
> notify_cpu_starting(smp_processor_id());
> update_siblings_masks(smp_processor_id());
> set_cpu_online(smp_processor_id(), 1);
> diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
> index 7d95cce5e47c..ad14f4466d92 100644
> --- a/arch/riscv/kernel/traps.c
> +++ b/arch/riscv/kernel/traps.c
> @@ -174,13 +174,7 @@ int is_valid_bugaddr(unsigned long pc)
> }
> #endif /* CONFIG_GENERIC_BUG */
>
> +/* stvec & scratch is already set from head.S */
> void trap_init(void)
> {
> - /*
> - * Set sup0 scratch register to 0, indicating to exception vector
> - * that we are presently executing in the kernel
> - */
> - csr_write(CSR_SCRATCH, 0);
> - /* Set the exception vector address */
> - csr_write(CSR_TVEC, &handle_exception);
> }
While I think these are all actual fixes, it's pretty late in the cycle here so
I'm going to a bit on the careful side and only take the patches that actually
manifest as bugs in the current port. Assuming this doesn't manifest until
early_ioremap is enabled (and we don't do that yet), I've put it on for-next.
LMK if I'm wrong about this, or the following ones.
Thanks!
On Fri, Jul 24, 2020 at 10:12 PM Palmer Dabbelt <[email protected]> wrote:
>
> On Wed, 15 Jul 2020 16:30:06 PDT (-0700), Atish Patra wrote:
> > The trap vector is set only in trap_init which may be too late in some
> > cases. Early ioremap/efi spits many warning messages which may be useful.
> >
> > Setup the trap vector early so that any warning/bug can be handled before
> > generic code invokes trap_init.
> >
> > Signed-off-by: Atish Patra <[email protected]>
> > ---
> > arch/riscv/kernel/head.S | 10 ++++++++--
> > arch/riscv/kernel/smpboot.c | 1 -
> > arch/riscv/kernel/traps.c | 8 +-------
> > 3 files changed, 9 insertions(+), 10 deletions(-)
> >
> > diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
> > index 7ed1b22950fd..d0c5c316e9bb 100644
> > --- a/arch/riscv/kernel/head.S
> > +++ b/arch/riscv/kernel/head.S
> > @@ -77,10 +77,16 @@ relocate:
> > csrw CSR_SATP, a0
> > .align 2
> > 1:
> > - /* Set trap vector to spin forever to help debug */
> > - la a0, .Lsecondary_park
> > + /* Set trap vector to exception handler */
> > + la a0, handle_exception
> > csrw CSR_TVEC, a0
> >
> > + /*
> > + * Set sup0 scratch register to 0, indicating to exception vector that
> > + * we are presently executing in kernel.
> > + */
> > + csrw CSR_SCRATCH, zero
> > +
> > /* Reload the global pointer */
> > .option push
> > .option norelax
> > diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c
> > index 4e9922790f6e..5a9c127a380e 100644
> > --- a/arch/riscv/kernel/smpboot.c
> > +++ b/arch/riscv/kernel/smpboot.c
> > @@ -154,7 +154,6 @@ asmlinkage __visible void smp_callin(void)
> > mmgrab(mm);
> > current->active_mm = mm;
> >
> > - trap_init();
> > notify_cpu_starting(smp_processor_id());
> > update_siblings_masks(smp_processor_id());
> > set_cpu_online(smp_processor_id(), 1);
> > diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
> > index 7d95cce5e47c..ad14f4466d92 100644
> > --- a/arch/riscv/kernel/traps.c
> > +++ b/arch/riscv/kernel/traps.c
> > @@ -174,13 +174,7 @@ int is_valid_bugaddr(unsigned long pc)
> > }
> > #endif /* CONFIG_GENERIC_BUG */
> >
> > +/* stvec & scratch is already set from head.S */
> > void trap_init(void)
> > {
> > - /*
> > - * Set sup0 scratch register to 0, indicating to exception vector
> > - * that we are presently executing in the kernel
> > - */
> > - csr_write(CSR_SCRATCH, 0);
> > - /* Set the exception vector address */
> > - csr_write(CSR_TVEC, &handle_exception);
> > }
>
> While I think these are all actual fixes, it's pretty late in the cycle here so
> I'm going to a bit on the careful side and only take the patches that actually
> manifest as bugs in the current port. Assuming this doesn't manifest until
> early_ioremap is enabled (and we don't do that yet), I've put it on for-next.
>
Yeah. early_ioremap is part of the UEFI series. So this can go into for-next.
Thanks.
> LMK if I'm wrong about this, or the following ones.
>
> Thanks!
>
> _______________________________________________
> linux-riscv mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-riscv
--
Regards,
Atish