Skip to content

Commit

Permalink
elfloader: Set Exec-Never for Device Memory
Browse files Browse the repository at this point in the history
Type PTE.

The ARM spec (ARM DDI 0487J.a) says on page B2-216

 ("Aarch64
Application Level Memory Model"):

"Hardware does not prevent speculative instruction fetches from a
memory location with any of the Device memory attributes unless
the memory location is also marked as execute-never for all
Exception levels."

and

"Failure to mark a memory location with any Device memory
attribute as execute-never for all Exception levels is a
programming error."

Similar statements can be found in the chapter about the Aarch32
Application Level Memory Model for aarch32 mode.

Signed-off-by: Andy Bui <andy.bui@nio.io>
  • Loading branch information
mro-github-12345 authored and Andy Bui committed Feb 25, 2024
1 parent 0e0a99d commit 16ea8ef
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 5 deletions.
2 changes: 2 additions & 0 deletions elfloader-tool/include/arch-arm/64/mode/aarch64.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,5 @@
#define MT_NORMAL 4
#define MT_NORMAL_WT 5
#define MAIR(_attr, _mt) ((_attr) << ((_mt) * 8))

#define IS_DEV_MEM_INDEX(_idx) ((_idx) <= MT_DEVICE_GRE)
2 changes: 1 addition & 1 deletion elfloader-tool/include/elfloader_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ typedef uintptr_t vaddr_t;

#define PAGE_BITS 12

#define BIT(x) (1 << (x))
#define BIT(x) (1ul << (x))
#define MASK(n) (BIT(n) - 1)
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define IS_ALIGNED(n, b) (!((n) & MASK(b)))
Expand Down
13 changes: 9 additions & 4 deletions elfloader-tool/src/arch-arm/64/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,14 +142,19 @@ static inline uint64_t make_pde_from_ptr(pte_t *pagetable_target)
return make_pde(va_to_pa((uintptr_t)pagetable_target));
}

/* ARM DDI 0487I.a, section D8.5.2 */
/* ARM DDI 0487J.a, section D8.5.2 */
#define INNER_SHAREABLE 3
static inline uint64_t make_pte(paddr_t pa, uint8_t mem_attr_index)
{
/* Note: As per R_PYFVQ from the ARM spec, we can always safely set the
* shareability to inner, even for device-type memory.
/* As per R_PYFVQ from the ARM spec, we can always safely set the shareability
* to inner, even for Device memory type.
* For exec-never bit(s), see Table D8-46 for EL2 translation regime (TR)
* and Table D8-45 for all others.
* PXN (bit 53) is RES0 for EL2 TR (Figure D8-16), so we simply always set it.
*/
return mask_pa(pa)
uint64_t xn = (IS_DEV_MEM_INDEX(mem_attr_index)) ? (BIT(54) | BIT(53)) : 0;
return xn
| mask_pa(pa)
| BIT(10) /* access flag */
#if CONFIG_MAX_NUM_NODES > 1
| (INNER_SHAREABLE << 8)
Expand Down

0 comments on commit 16ea8ef

Please sign in to comment.