diff options
author | Juha Riihimäki <juha.riihimaki@nokia.com> | 2010-12-08 13:15:16 +0200 |
---|---|---|
committer | Aurelien Jarno <aurelien@aurel32.net> | 2010-12-27 21:21:16 +0100 |
commit | c0034328090880621ad8f33e03ae03599e353865 (patch) | |
tree | be2b9d9716bd1a88888af024a61c0b98fa191eac /target-arm | |
parent | a5d88f3e030f9f83e63b0cb3c09a3293d8057f4a (diff) | |
download | qemu-c0034328090880621ad8f33e03ae03599e353865.zip qemu-c0034328090880621ad8f33e03ae03599e353865.tar.gz qemu-c0034328090880621ad8f33e03ae03599e353865.tar.bz2 |
target-arm: fix vmsav6 access control
Override access control checks (including execute) for mmu translation
table descriptors assigned to manager domains.
Signed-off-by: Juha Riihimäki <juha.riihimaki@nokia.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Diffstat (limited to 'target-arm')
-rw-r--r-- | target-arm/helper.c | 34 |
1 files changed, 19 insertions, 15 deletions
diff --git a/target-arm/helper.c b/target-arm/helper.c index 9ba2f4f..409a6c0 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -1084,22 +1084,26 @@ static int get_phys_addr_v6(CPUState *env, uint32_t address, int access_type, } code = 15; } - if (xn && access_type == 2) - goto do_fault; + if (domain == 3) { + *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; + } else { + if (xn && access_type == 2) + goto do_fault; - /* The simplified model uses AP[0] as an access control bit. */ - if ((env->cp15.c1_sys & (1 << 29)) && (ap & 1) == 0) { - /* Access flag fault. */ - code = (code == 15) ? 6 : 3; - goto do_fault; - } - *prot = check_ap(env, ap, domain, access_type, is_user); - if (!*prot) { - /* Access permission fault. */ - goto do_fault; - } - if (!xn) { - *prot |= PAGE_EXEC; + /* The simplified model uses AP[0] as an access control bit. */ + if ((env->cp15.c1_sys & (1 << 29)) && (ap & 1) == 0) { + /* Access flag fault. */ + code = (code == 15) ? 6 : 3; + goto do_fault; + } + *prot = check_ap(env, ap, domain, access_type, is_user); + if (!*prot) { + /* Access permission fault. */ + goto do_fault; + } + if (!xn) { + *prot |= PAGE_EXEC; + } } *phys_ptr = phys_addr; return 0; |