提交 d76951b6 编写于 作者: A Andrew Jones 提交者: Peter Maydell

target-arm: fix get_phys_addr_v6/SCTLR_AFE access check

Introduce simple_ap_to_rw_prot(), which has the same behavior as
ap_to_rw_prot(), but takes the 2-bit simple AP[2:1] instead of
the 3-bit AP[2:0]. Use this in get_phys_addr_v6 when SCTLR_AFE
is set, as that bit indicates we should be using the simple AP
format.

It's unlikely this path is getting used. I don't see CR_AFE
getting used by Linux, so possibly not. If it had been, then
the check would have been wrong for all but AP[2:1] = 0b11.
Anyway, this should fix it up, in case it ever does get used.
Signed-off-by: NAndrew Jones <drjones@redhat.com>
Reviewed-by: NPeter Maydell <peter.maydell@linaro.org>
Message-id: 1426099139-14463-3-git-send-email-drjones@redhat.com
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
上级 0fbf5238
...@@ -4905,6 +4905,11 @@ static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx) ...@@ -4905,6 +4905,11 @@ static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)
/* Translate section/page access permissions to page /* Translate section/page access permissions to page
* R/W protection flags * R/W protection flags
*
* @env: CPUARMState
* @mmu_idx: MMU index indicating required translation regime
* @ap: The 3-bit access permissions (AP[2:0])
* @domain_prot: The 2-bit domain access permissions
*/ */
static inline int ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, static inline int ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx,
int ap, int domain_prot) int ap, int domain_prot)
...@@ -4954,6 +4959,32 @@ static inline int ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, ...@@ -4954,6 +4959,32 @@ static inline int ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx,
} }
} }
/* Translate section/page access permissions to page
* R/W protection flags.
*
* @env: CPUARMState
* @mmu_idx: MMU index indicating required translation regime
* @ap: The 2-bit simple AP (AP[2:1])
*/
static inline int
simple_ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, int ap)
{
bool is_user = regime_is_user(env, mmu_idx);
switch (ap) {
case 0:
return is_user ? 0 : PAGE_READ | PAGE_WRITE;
case 1:
return PAGE_READ | PAGE_WRITE;
case 2:
return is_user ? 0 : PAGE_READ;
case 3:
return PAGE_READ;
default:
g_assert_not_reached();
}
}
static bool get_level1_table_address(CPUARMState *env, ARMMMUIdx mmu_idx, static bool get_level1_table_address(CPUARMState *env, ARMMMUIdx mmu_idx,
uint32_t *table, uint32_t address) uint32_t *table, uint32_t address)
{ {
...@@ -5186,14 +5217,18 @@ static int get_phys_addr_v6(CPUARMState *env, uint32_t address, int access_type, ...@@ -5186,14 +5217,18 @@ static int get_phys_addr_v6(CPUARMState *env, uint32_t address, int access_type,
if (xn && access_type == 2) if (xn && access_type == 2)
goto do_fault; goto do_fault;
/* The simplified model uses AP[0] as an access control bit. */ if (arm_feature(env, ARM_FEATURE_V6K) &&
if ((regime_sctlr(env, mmu_idx) & SCTLR_AFE) (regime_sctlr(env, mmu_idx) & SCTLR_AFE)) {
&& (ap & 1) == 0) { /* The simplified model uses AP[0] as an access control bit. */
/* Access flag fault. */ if ((ap & 1) == 0) {
code = (code == 15) ? 6 : 3; /* Access flag fault. */
goto do_fault; code = (code == 15) ? 6 : 3;
goto do_fault;
}
*prot = simple_ap_to_rw_prot(env, mmu_idx, ap >> 1);
} else {
*prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
} }
*prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
if (*prot && !xn) { if (*prot && !xn) {
*prot |= PAGE_EXEC; *prot |= PAGE_EXEC;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册