mirror of
https://github.com/AsahiLinux/m1n1
synced 2024-11-14 03:17:05 +00:00
memory: Add separate mappings for EL0 data access
This unborks stack and constant pool accesses from el0_call. Signed-off-by: Hector Martin <marcan@marcan.st>
This commit is contained in:
parent
7685800b45
commit
3e1ea2d503
5 changed files with 41 additions and 8 deletions
|
@ -4,13 +4,14 @@
|
|||
#include "cpu_regs.h"
|
||||
#include "gxf.h"
|
||||
#include "iodev.h"
|
||||
#include "memory.h"
|
||||
#include "uart.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define EL0_STACK_SIZE 0x4000
|
||||
|
||||
u8 el0_stack[EL0_STACK_SIZE] ALIGNED(64);
|
||||
void *el0_stack_base = &el0_stack[EL0_STACK_SIZE];
|
||||
void *el0_stack_base = (void *)((u64)(&el0_stack[EL0_STACK_SIZE]) + REGION_RW_EL0);
|
||||
|
||||
extern char _vectors_start[0];
|
||||
extern char _el1_vectors_start[0];
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
#include "memory.h"
|
||||
|
||||
.globl exc_sync
|
||||
.globl exc_irq
|
||||
.globl exc_fiq
|
||||
|
@ -102,6 +104,9 @@ el0_call:
|
|||
ldr x5, =_el0_thunk
|
||||
msr elr_el1, x5
|
||||
|
||||
mov x5, #REGION_RWX_EL0
|
||||
orr x0, x0, x5
|
||||
|
||||
ldr x5, =el0_stack_base
|
||||
ldr x5, [x5]
|
||||
msr spsel, #0
|
||||
|
|
32
src/memory.c
32
src/memory.c
|
@ -57,10 +57,12 @@ static inline void write_sctlr(u64 val)
|
|||
|
||||
#define PERM_RO_EL0 PTE_AP_EL0 | PTE_AP_RO | PTE_PXN | PTE_UXN
|
||||
#define PERM_RW_EL0 PTE_AP_EL0 | PTE_PXN | PTE_UXN
|
||||
#define PERM_RX_EL0 PTE_AP_EL0 | PTE_AP_RO
|
||||
#define PERM_RWX_EL0 PTE_AP_EL0
|
||||
|
||||
#define PERM_RO PTE_AP_RO | PTE_PXN | PTE_UXN
|
||||
#define PERM_RW PTE_PXN | PTE_UXN
|
||||
#define PERM_RX PTE_AP_RO | PTE_UXN
|
||||
#define PERM_RWX 0
|
||||
|
||||
/*
|
||||
|
@ -245,7 +247,7 @@ static void mmu_add_mapping(uintptr_t from, uintptr_t to, size_t size, u8 attrib
|
|||
static void mmu_add_default_mappings(void)
|
||||
{
|
||||
/*
|
||||
* create MMIO mappings. PCIe has to be mapped as nGnRE while MMIO needs nGnRnE.
|
||||
* Create MMIO mappings. PCIe has to be mapped as nGnRE while MMIO needs nGnRnE.
|
||||
* see https://lore.kernel.org/linux-arm-kernel/c1bc2a087747c4d9@bloch.sibelius.xs4all.nl/
|
||||
*/
|
||||
mmu_add_mapping(0x0200000000, 0x0200000000, 0x0200000000, MAIR_IDX_DEVICE_nGnRnE, PERM_RW_EL0);
|
||||
|
@ -256,19 +258,35 @@ static void mmu_add_default_mappings(void)
|
|||
mmu_add_mapping(0x06a0000000, 0x06a0000000, 0x0060000000, MAIR_IDX_DEVICE_nGnRE, PERM_RW_EL0);
|
||||
|
||||
/*
|
||||
* create identity mapping for 16GB RAM from 0x08_0000_0000 to
|
||||
* 0x0c_0000_0000
|
||||
* Create identity mapping for 16GB RAM from 0x08_0000_0000 to 0x0c_0000_0000
|
||||
* With SPRR enabled, this becomes RW.
|
||||
*/
|
||||
mmu_add_mapping(0x0800000000, 0x0800000000, 0x0400000000, MAIR_IDX_NORMAL, PERM_RWX);
|
||||
|
||||
/*
|
||||
* create identity mapping for 16GB RAM from 0x88_0000_0000 to
|
||||
* 0x8c_0000_0000, writable by EL0 (but not executable by EL1)
|
||||
* Create mapping for 16GB RAM from 0x88_0000_0000 to 0x8c_0000_0000,
|
||||
* read/writable/exec by EL0 (but not executable by EL1)
|
||||
* With SPRR enabled, this becomes RX_EL0.
|
||||
*/
|
||||
mmu_add_mapping(0x8800000000, 0x0800000000, 0x0400000000, MAIR_IDX_NORMAL, PERM_RWX_EL0);
|
||||
mmu_add_mapping(0x0800000000 | REGION_RWX_EL0, 0x0800000000, 0x0400000000, MAIR_IDX_NORMAL,
|
||||
PERM_RWX_EL0);
|
||||
/*
|
||||
* Create mapping for 16GB RAM from 0x98_0000_0000 to 0x9c_0000_0000,
|
||||
* read/writable by EL0 (but not executable by EL1)
|
||||
* With SPRR enabled, this becomes RW_EL0.
|
||||
*/
|
||||
mmu_add_mapping(0x0800000000 | REGION_RW_EL0, 0x0800000000, 0x0400000000, MAIR_IDX_NORMAL,
|
||||
PERM_RW_EL0);
|
||||
/*
|
||||
* Create mapping for 16GB RAM from 0xa8_0000_0000 to 0xac_0000_0000,
|
||||
* read/executable by EL1
|
||||
* This allows executing from dynamic regions in EL1
|
||||
*/
|
||||
mmu_add_mapping(0x0800000000 | REGION_RX_EL1, 0x0800000000, 0x0400000000, MAIR_IDX_NORMAL,
|
||||
PERM_RX);
|
||||
|
||||
/*
|
||||
* create two seperate nGnRnE and nGnRE full mappings of MMIO space
|
||||
* Create two seperate nGnRnE and nGnRE full mappings of MMIO space
|
||||
*/
|
||||
mmu_add_mapping(0xe000000000, 0x0000000000, 0x0800000000, MAIR_IDX_DEVICE_nGnRnE, PERM_RW_EL0);
|
||||
mmu_add_mapping(0xf000000000, 0x0000000000, 0x0800000000, MAIR_IDX_DEVICE_nGnRE, PERM_RW_EL0);
|
||||
|
|
|
@ -5,6 +5,12 @@
|
|||
|
||||
#include "types.h"
|
||||
|
||||
#define REGION_RWX_EL0 0x8000000000
|
||||
#define REGION_RW_EL0 0x9000000000
|
||||
#define REGION_RX_EL1 0xa000000000
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
void ic_ivau_range(void *addr, size_t length);
|
||||
void dc_ivac_range(void *addr, size_t length);
|
||||
void dc_zva_range(void *addr, size_t length);
|
||||
|
@ -24,3 +30,5 @@ u64 mmu_disable(void);
|
|||
void mmu_restore(u64 state);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -319,6 +319,7 @@ static inline int is_primary_core(void)
|
|||
}
|
||||
|
||||
extern char _base[];
|
||||
extern char _rodata_end[];
|
||||
extern char _end[];
|
||||
extern char _payload_start[];
|
||||
extern char _payload_end[];
|
||||
|
|
Loading…
Reference in a new issue