aboutsummaryrefslogtreecommitdiff
path: root/target-arm
diff options
context:
space:
mode:
authorRabin Vincent <rabin@rab.in>2010-03-20 02:28:03 +0530
committerAurelien Jarno <aurelien@aurel32.net>2010-03-27 14:14:34 +0100
commit3ad493fc5ea38c005670adc5933058a28ccabdd4 (patch)
tree2262de81513bd8dee6db9c8e635ab3f47d8a3507 /target-arm
parentca5a2a4b12bd44762a5106c9352eafd878bbd52f (diff)
target-arm: disable PAGE_EXEC for XN pages
Don't set PAGE_EXEC for XN pages, to avoid a bypass of XN protection checking if the page is already in the TLB. Signed-off-by: Rabin Vincent <rabin@rab.in> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Diffstat (limited to 'target-arm')
-rw-r--r--target-arm/helper.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 18e22b1afc..e092b2122e 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -979,6 +979,7 @@ static int get_phys_addr_v5(CPUState *env, uint32_t address, int access_type,
/* Access permission fault. */
goto do_fault;
}
+ *prot |= PAGE_EXEC;
*phys_ptr = phys_addr;
return 0;
do_fault:
@@ -1075,6 +1076,9 @@ static int get_phys_addr_v6(CPUState *env, uint32_t address, int access_type,
/* Access permission fault. */
goto do_fault;
}
+ if (!xn) {
+ *prot |= PAGE_EXEC;
+ }
*phys_ptr = phys_addr;
return 0;
do_fault:
@@ -1137,6 +1141,7 @@ static int get_phys_addr_mpu(CPUState *env, uint32_t address, int access_type,
/* Bad permission. */
return 1;
}
+ *prot |= PAGE_EXEC;
return 0;
}
@@ -1152,7 +1157,7 @@ static inline int get_phys_addr(CPUState *env, uint32_t address,
if ((env->cp15.c1_sys & 1) == 0) {
/* MMU/MPU disabled. */
*phys_ptr = address;
- *prot = PAGE_READ | PAGE_WRITE;
+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
*page_size = TARGET_PAGE_SIZE;
return 0;
} else if (arm_feature(env, ARM_FEATURE_MPU)) {
@@ -1183,8 +1188,7 @@ int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address,
/* Map a single [sub]page. */
phys_addr &= ~(uint32_t)0x3ff;
address &= ~(uint32_t)0x3ff;
- tlb_set_page (env, address, phys_addr, prot | PAGE_EXEC, mmu_idx,
- page_size);
+ tlb_set_page (env, address, phys_addr, prot, mmu_idx, page_size);
return 0;
}