target/arm: Skip granule protection checks for AT instructions
GPC checks are not performed on the output address for AT instructions, as stated by ARM DDI 0487J in D8.12.2: When populating PAR_EL1 with the result of an address translation instruction, granule protection checks are not performed on the final output address of a successful translation. Rename get_phys_addr_with_secure(), since it's only used to handle AT instructions. Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20230809123706.1842548-4-jean-philippe@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
ceaa97465f
commit
f1269a98aa
@ -3365,8 +3365,12 @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
|
||||
ARMMMUFaultInfo fi = {};
|
||||
GetPhysAddrResult res = {};
|
||||
|
||||
ret = get_phys_addr_with_secure(env, value, access_type, mmu_idx,
|
||||
is_secure, &res, &fi);
|
||||
/*
|
||||
* I_MXTJT: Granule protection checks are not performed on the final address
|
||||
* of a successful translation.
|
||||
*/
|
||||
ret = get_phys_addr_with_secure_nogpc(env, value, access_type, mmu_idx,
|
||||
is_secure, &res, &fi);
|
||||
|
||||
/*
|
||||
* ATS operations only do S1 or S1+S2 translations, so we never
|
||||
|
@ -1190,12 +1190,11 @@ typedef struct GetPhysAddrResult {
|
||||
} GetPhysAddrResult;
|
||||
|
||||
/**
|
||||
* get_phys_addr_with_secure: get the physical address for a virtual address
|
||||
* get_phys_addr: get the physical address for a virtual address
|
||||
* @env: CPUARMState
|
||||
* @address: virtual address to get physical address for
|
||||
* @access_type: 0 for read, 1 for write, 2 for execute
|
||||
* @mmu_idx: MMU index indicating required translation regime
|
||||
* @is_secure: security state for the access
|
||||
* @result: set on translation success.
|
||||
* @fi: set to fault info if the translation fails
|
||||
*
|
||||
@ -1212,26 +1211,30 @@ typedef struct GetPhysAddrResult {
|
||||
* * for PSMAv5 based systems we don't bother to return a full FSR format
|
||||
* value.
|
||||
*/
|
||||
bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
|
||||
MMUAccessType access_type,
|
||||
ARMMMUIdx mmu_idx, bool is_secure,
|
||||
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
|
||||
bool get_phys_addr(CPUARMState *env, target_ulong address,
|
||||
MMUAccessType access_type, ARMMMUIdx mmu_idx,
|
||||
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
|
||||
__attribute__((nonnull));
|
||||
|
||||
/**
|
||||
* get_phys_addr: get the physical address for a virtual address
|
||||
* get_phys_addr_with_secure_nogpc: get the physical address for a virtual
|
||||
* address
|
||||
* @env: CPUARMState
|
||||
* @address: virtual address to get physical address for
|
||||
* @access_type: 0 for read, 1 for write, 2 for execute
|
||||
* @mmu_idx: MMU index indicating required translation regime
|
||||
* @is_secure: security state for the access
|
||||
* @result: set on translation success.
|
||||
* @fi: set to fault info if the translation fails
|
||||
*
|
||||
* Similarly, but use the security regime of @mmu_idx.
|
||||
* Similar to get_phys_addr, but use the given security regime and don't perform
|
||||
* a Granule Protection Check on the resulting address.
|
||||
*/
|
||||
bool get_phys_addr(CPUARMState *env, target_ulong address,
|
||||
MMUAccessType access_type, ARMMMUIdx mmu_idx,
|
||||
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
|
||||
bool get_phys_addr_with_secure_nogpc(CPUARMState *env, target_ulong address,
|
||||
MMUAccessType access_type,
|
||||
ARMMMUIdx mmu_idx, bool is_secure,
|
||||
GetPhysAddrResult *result,
|
||||
ARMMMUFaultInfo *fi)
|
||||
__attribute__((nonnull));
|
||||
|
||||
bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
|
||||
|
@ -3420,16 +3420,17 @@ static bool get_phys_addr_gpc(CPUARMState *env, S1Translate *ptw,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
|
||||
MMUAccessType access_type, ARMMMUIdx mmu_idx,
|
||||
bool is_secure, GetPhysAddrResult *result,
|
||||
ARMMMUFaultInfo *fi)
|
||||
bool get_phys_addr_with_secure_nogpc(CPUARMState *env, target_ulong address,
|
||||
MMUAccessType access_type,
|
||||
ARMMMUIdx mmu_idx, bool is_secure,
|
||||
GetPhysAddrResult *result,
|
||||
ARMMMUFaultInfo *fi)
|
||||
{
|
||||
S1Translate ptw = {
|
||||
.in_mmu_idx = mmu_idx,
|
||||
.in_space = arm_secure_to_space(is_secure),
|
||||
};
|
||||
return get_phys_addr_gpc(env, &ptw, address, access_type, result, fi);
|
||||
return get_phys_addr_nogpc(env, &ptw, address, access_type, result, fi);
|
||||
}
|
||||
|
||||
bool get_phys_addr(CPUARMState *env, target_ulong address,
|
||||
|
Loading…
Reference in New Issue
Block a user