diff --git a/arch/metag/include/asm/processor.h b/arch/metag/include/asm/processor.h index b7e25289f3a36b9ab3bd4315241d318500522226..9b029a7911c3034166e0df77ac6c40c418aff344 100644 --- a/arch/metag/include/asm/processor.h +++ b/arch/metag/include/asm/processor.h @@ -154,7 +154,7 @@ unsigned long get_wchan(struct task_struct *p); #define cpu_relax() barrier() -extern void setup_txprivext(void); +extern void setup_priv(void); static inline unsigned int hard_processor_id(void) { diff --git a/arch/metag/kernel/setup.c b/arch/metag/kernel/setup.c index dcb1d6d51ce49ac4ef732be5d7991b73667c4a23..9803ca4f651038d0e1a2d0b5044d16947f881cb7 100644 --- a/arch/metag/kernel/setup.c +++ b/arch/metag/kernel/setup.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -75,6 +76,32 @@ META2_PRIV | \ UNALIGNED_PRIV) +/* + * Protect access to: + * 0x06000000-0x07ffffff Direct mapped region + * 0x05000000-0x05ffffff MMU table region (Meta1) + * 0x04400000-0x047fffff Cache flush region + * 0x84000000-0x87ffffff Core cache memory region (Meta2) + * + * Allow access to: + * 0x80000000-0x81ffffff Core code memory region (Meta2) + */ +#ifdef CONFIG_METAG_META12 +#define PRIVSYSR_BITS TXPRIVSYSR_ALL_BITS +#else +#define PRIVSYSR_BITS (TXPRIVSYSR_ALL_BITS & ~TXPRIVSYSR_CORECODE_BIT) +#endif + +/* Protect all 0x02xxxxxx and 0x048xxxxx. */ +#define PIOREG_BITS 0xffffffff + +/* + * Protect all 0x04000xx0 (system events) + * except write combiner flush and write fence (system events 4 and 5). + */ +#define PSYREG_BITS 0xfffffffb + + extern char _heap_start[]; #ifdef CONFIG_METAG_BUILTIN_DTB @@ -371,7 +398,7 @@ void __init setup_arch(char **cmdline_p) paging_init(heap_end); - setup_txprivext(); + setup_priv(); /* Setup the boot cpu's mapping. The rest will be setup below. */ cpu_2_hwthread_id[smp_processor_id()] = hard_processor_id(); @@ -531,13 +558,21 @@ void __init metag_start_kernel(char *args) start_kernel(); } -/* - * Setup TXPRIVEXT register to be prevent userland from touching our - * precious registers. +/** + * setup_priv() - Set up privilege protection registers. + * + * Set up privilege protection registers such as TXPRIVEXT to prevent userland + * from touching our precious registers and sensitive memory areas. */ -void setup_txprivext(void) +void setup_priv(void) { + unsigned int offset = hard_processor_id() << TXPRIVREG_STRIDE_S; + __core_reg_set(TXPRIVEXT, PRIV_BITS); + + metag_out32(PRIVSYSR_BITS, T0PRIVSYSR + offset); + metag_out32(PIOREG_BITS, T0PIOREG + offset); + metag_out32(PSYREG_BITS, T0PSYREG + offset); } PTBI pTBI_get(unsigned int cpu) diff --git a/arch/metag/kernel/smp.c b/arch/metag/kernel/smp.c index d1163127eb68b42d809451f950164c59c42acb5e..4b6d1f14df32dcdeff8f26eaa550f4b8a5f43e3a 100644 --- a/arch/metag/kernel/smp.c +++ b/arch/metag/kernel/smp.c @@ -268,7 +268,7 @@ asmlinkage void secondary_start_kernel(void) preempt_disable(); - setup_txprivext(); + setup_priv(); /* * Enable local interrupts.