diff mbox

[WIP,4/4] ARM: remove compile time vector base for CP15 case

Message ID 20170107172228.6451-1-afzal.mohd.ma@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

afzal mohammed Jan. 7, 2017, 5:22 p.m. UTC
vectors base is now dynamically updated for Hivecs as well as for
REMAP_VECTORS_TO_RAM case to DRAM_START. Hence remove these CP15
cases.

TODO:
Kill off VECTORS_BASE completely - this would require to handle MMU
 case as well as ARM_MPU scenario dynamically.

Signed-off-by: afzal mohammed <afzal.mohd.ma@gmail.com>
---
 arch/arm/Kconfig | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

Comments

Russell King (Oracle) Jan. 7, 2017, 5:38 p.m. UTC | #1
On Sat, Jan 07, 2017 at 10:52:28PM +0530, afzal mohammed wrote:
> vectors base is now dynamically updated for Hivecs as well as for
> REMAP_VECTORS_TO_RAM case to DRAM_START. Hence remove these CP15
> cases.
> 
> TODO:
> Kill off VECTORS_BASE completely - this would require to handle MMU
>  case as well as ARM_MPU scenario dynamically.

Why do you think MMU doesn't already handle it?

>  config VECTORS_BASE
>  	hex
> -	default 0xffff0000 if MMU || CPU_HIGH_VECTOR
> -	default DRAM_BASE if REMAP_VECTORS_TO_RAM
> +	default 0xffff0000 if MMU
>  	default 0x00000000

When MMU=y, the resulting VECTORS_BASE is always 0xffff0000.  The only
case where this ends up zero after your change is when MMU=n.

In any case here's the places it's used:

For nommu:
arch/arm/kernel/head-nommu.S:       mov     r0, #CONFIG_VECTORS_BASE   @ Cover from VECTORS_BASE
arch/arm/kernel/head-nommu.S:       setup_region r0, r5, r6, MPU_DATA_SIDE  @ VECTORS_BASE, PL0 NA, enabled
arch/arm/kernel/head-nommu.S:       setup_region r0, r5, r6, MPU_INSTR_SIDE @ VECTORS_BASE, PL0 NA, enabled
arch/arm/mm/nommu.c:        memblock_reserve(CONFIG_VECTORS_BASE, 2 * PAGE_SIZE);
arch/arm/mm/nommu.c:        early_trap_init((void *)CONFIG_VECTORS_BASE);

To intercept the reset vector for secondary CPUs (because we hide it
away from platforms, so platforms end up hacking around to get at it.)
arch/arm/mach-berlin/platsmp.c:     vectors_base = ioremap(CONFIG_VECTORS_BASE, SZ_32K);

For printing:
arch/arm/mm/init.c:                 MLK(UL(CONFIG_VECTORS_BASE), UL(CONFIG_VECTORS_BASE) +

For dumping the page tables (but since this is only built for MMU=y,
we know what CONFIG_VECTORS_BASE is here.)
arch/arm/mm/dump.c: { CONFIG_VECTORS_BASE,     "Vectors" },
arch/arm/mm/dump.c: { CONFIG_VECTORS_BASE + PAGE_SIZE * 2, "Vectors End" },

For the Berlin and mm/dump code, we could very easily just have a
#define VECTORS_BASE 0xffff0000 in a header file and drop the CONFIG_
prefix.

The MMU case does have to cater for CPUs wanting vectors at 0xffff0000
and at 0x00000000, and this is handled via the page tables - but this
has nothing to do with CONFIG_VECTORS_BASE.  CONFIG_VECTORS_BASE
exists primarily for noMMU.
afzal mohammed Jan. 7, 2017, 6:02 p.m. UTC | #2
Hi,

On Sat, Jan 07, 2017 at 05:38:32PM +0000, Russell King - ARM Linux wrote:
> On Sat, Jan 07, 2017 at 10:52:28PM +0530, afzal mohammed wrote:

> > TODO:
> > Kill off VECTORS_BASE completely - this would require to handle MMU
> >  case as well as ARM_MPU scenario dynamically.

> Why do you think MMU doesn't already handle it?

i meant here w.r.t displaying vector base address in
arch/arm/mm/init.c, i.e. dynamically get it based on Hivecs setting as
either 0xffff0000 or 0x00000000
> 
> >  config VECTORS_BASE
> >  	hex
> > -	default 0xffff0000 if MMU || CPU_HIGH_VECTOR
> > -	default DRAM_BASE if REMAP_VECTORS_TO_RAM
> > +	default 0xffff0000 if MMU
> >  	default 0x00000000
> 
> When MMU=y, the resulting VECTORS_BASE is always 0xffff0000.  The only
> case where this ends up zero after your change is when MMU=n.

> The MMU case does have to cater for CPUs wanting vectors at 0xffff0000
> and at 0x00000000, and this is handled via the page tables - but this
> has nothing to do with CONFIG_VECTORS_BASE.  CONFIG_VECTORS_BASE
> exists primarily for noMMU.

i had thought that for MMU case if Hivecs is not enabled,
CONFIG_VECTOR_BASE has to be considered as 0x00000000 at least for the
purpose of displaying exception base address.

One thing i have not yet understood is how CPU can take exception with
it base address as 0x00000000 (for Hivecs not enabled case) virtual
address as it is below Kernel memory map.

> For the Berlin and mm/dump code, we could very easily just have a
> #define VECTORS_BASE 0xffff0000 in a header file and drop the CONFIG_
> prefix.

Okay, thanks for the tip.

Regards
afzal
afzal mohammed Jan. 7, 2017, 6:07 p.m. UTC | #3
Hi,

On Sat, Jan 07, 2017 at 11:32:27PM +0530, Afzal Mohammed wrote:

> i had thought that for MMU case if Hivecs is not enabled,
> CONFIG_VECTOR_BASE has to be considered as 0x00000000 at least for the

s/CONFIG_VECTOR_BASE/exception base address

> purpose of displaying exception base address.

Regards
afzal
Russell King (Oracle) Jan. 7, 2017, 6:24 p.m. UTC | #4
On Sat, Jan 07, 2017 at 11:32:27PM +0530, Afzal Mohammed wrote:
> Hi,
> 
> On Sat, Jan 07, 2017 at 05:38:32PM +0000, Russell King - ARM Linux wrote:
> > On Sat, Jan 07, 2017 at 10:52:28PM +0530, afzal mohammed wrote:
> 
> > > TODO:
> > > Kill off VECTORS_BASE completely - this would require to handle MMU
> > >  case as well as ARM_MPU scenario dynamically.
> 
> > Why do you think MMU doesn't already handle it?
> 
> i meant here w.r.t displaying vector base address in
> arch/arm/mm/init.c, i.e. dynamically get it based on Hivecs setting as
> either 0xffff0000 or 0x00000000

You mean:

        pr_notice("Virtual kernel memory layout:\n"
                        "    vector  : 0x%08lx - 0x%08lx   (%4ld kB)\n"
...
                        MLK(UL(CONFIG_VECTORS_BASE), UL(CONFIG_VECTORS_BASE) +
                                (PAGE_SIZE)),

As I've said, CONFIG_VECTORS_BASE is _always_ 0xffff0000 on MMU, so
this always displays 0xffff0000 - 0xffff1000 here.

> i had thought that for MMU case if Hivecs is not enabled,
> CONFIG_VECTOR_BASE has to be considered as 0x00000000 at least for the
> purpose of displaying exception base address.
> 
> One thing i have not yet understood is how CPU can take exception with
> it base address as 0x00000000 (for Hivecs not enabled case) virtual
> address as it is below Kernel memory map.

Older ARM CPUs without the V bit (ARMv3 and early ARMv4) expect the
vectors to be at virtual address zero.

Most of these systems place ROM at physical address 0, so when the CPU
starts from reset (with the MMU off) it starts executing from ROM.  Once
the MMU is initialised, RAM can be placed there and the ROM vectors
replaced.  The side effect of this is that NULL pointer dereferences
are not always caught... of course, it makes sense that the page at
address 0 is write protected even from the kernel, so a NULL pointer
write dereference doesn't corrupt the vectors.

How we handle it in Linux is that we always map the page for the vectors
at 0xffff0000, and then only map that same page at 0x00000000 if we have
a CPU that needs it there.
afzal mohammed Jan. 8, 2017, 9:58 a.m. UTC | #5
Hi,

On Sat, Jan 07, 2017 at 06:24:15PM +0000, Russell King - ARM Linux wrote:

> As I've said, CONFIG_VECTORS_BASE is _always_ 0xffff0000 on MMU, so
> this always displays 0xffff0000 - 0xffff1000 here.

> Older ARM CPUs without the V bit (ARMv3 and early ARMv4) expect the
> vectors to be at virtual address zero.
> 
> Most of these systems place ROM at physical address 0, so when the CPU
> starts from reset (with the MMU off) it starts executing from ROM.  Once
> the MMU is initialised, RAM can be placed there and the ROM vectors
> replaced.  The side effect of this is that NULL pointer dereferences
> are not always caught... of course, it makes sense that the page at
> address 0 is write protected even from the kernel, so a NULL pointer
> write dereference doesn't corrupt the vectors.
> 
> How we handle it in Linux is that we always map the page for the vectors
> at 0xffff0000, and then only map that same page at 0x00000000 if we have
> a CPU that needs it there.

Thanks for the information, i was not aware, seems that simplifies MMU
case handling.

arch/arm/mm/mmu.c:

	if (!vectors_high()) {
		map.virtual = 0;
		map.length = PAGE_SIZE * 2;
		map.type = MT_LOW_VECTORS;
		create_mapping(&map);
	}



arch/arm/include/asm/cp15.h:

#if __LINUX_ARM_ARCH__ >= 4
#define vectors_high()	(get_cr() & CR_V)
#else
#define vectors_high()	(0)
#endif

Deducing from your reply & above code snippets that for
__LINUX_ARM_ARCH__ >= 4, in all practical cases, vector_high() returns
true

Regards
afzal
diff mbox

Patch

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index bc6f4065840e..720ee62b4955 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -232,8 +232,7 @@  config ARCH_MTD_XIP
 
 config VECTORS_BASE
 	hex
-	default 0xffff0000 if MMU || CPU_HIGH_VECTOR
-	default DRAM_BASE if REMAP_VECTORS_TO_RAM
+	default 0xffff0000 if MMU
 	default 0x00000000
 	help
 	  The base address of exception vectors.  This must be two pages