Skip to content

Commit 712ebae

Browse files
mro-github-12345Andy Bui
authored and
Andy Bui
committed
elfloader: Set Exec-Never for Device Memory
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>
1 parent 496065a commit 712ebae

File tree

3 files changed

+12
-5
lines changed

3 files changed

+12
-5
lines changed

elfloader-tool/include/arch-arm/64/mode/aarch64.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,5 @@
6363
#define MT_NORMAL 4
6464
#define MT_NORMAL_WT 5
6565
#define MAIR(_attr, _mt) ((_attr) << ((_mt) * 8))
66+
67+
#define IS_DEV_MEM_INDEX(_idx) ((_idx) <= MT_DEVICE_GRE)

elfloader-tool/include/elfloader_common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ typedef uintptr_t vaddr_t;
1414

1515
#define PAGE_BITS 12
1616

17-
#define BIT(x) (1 << (x))
17+
#define BIT(x) (1ul << (x))
1818
#define MASK(n) (BIT(n) - 1)
1919
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
2020
#define IS_ALIGNED(n, b) (!((n) & MASK(b)))

elfloader-tool/src/arch-arm/64/mmu.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,14 +142,19 @@ static inline uint64_t make_pde_from_ptr(pte_t *pagetable_target)
142142
return make_pde(va_to_pa((uintptr_t)pagetable_target));
143143
}
144144

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

0 commit comments

Comments
 (0)