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:
Jean-Philippe Brucker 2023-08-22 17:31:12 +01:00 committed by Peter Maydell
parent ceaa97465f
commit f1269a98aa
3 changed files with 26 additions and 18 deletions

View File

@ -3365,8 +3365,12 @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
ARMMMUFaultInfo fi = {}; ARMMMUFaultInfo fi = {};
GetPhysAddrResult res = {}; 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 * ATS operations only do S1 or S1+S2 translations, so we never

View File

@ -1190,12 +1190,11 @@ typedef struct GetPhysAddrResult {
} 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 * @env: CPUARMState
* @address: virtual address to get physical address for * @address: virtual address to get physical address for
* @access_type: 0 for read, 1 for write, 2 for execute * @access_type: 0 for read, 1 for write, 2 for execute
* @mmu_idx: MMU index indicating required translation regime * @mmu_idx: MMU index indicating required translation regime
* @is_secure: security state for the access
* @result: set on translation success. * @result: set on translation success.
* @fi: set to fault info if the translation fails * @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 * * for PSMAv5 based systems we don't bother to return a full FSR format
* value. * value.
*/ */
bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address, bool get_phys_addr(CPUARMState *env, target_ulong address,
MMUAccessType access_type, MMUAccessType access_type, ARMMMUIdx mmu_idx,
ARMMMUIdx mmu_idx, bool is_secure, GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
__attribute__((nonnull)); __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 * @env: CPUARMState
* @address: virtual address to get physical address for * @address: virtual address to get physical address for
* @access_type: 0 for read, 1 for write, 2 for execute * @access_type: 0 for read, 1 for write, 2 for execute
* @mmu_idx: MMU index indicating required translation regime * @mmu_idx: MMU index indicating required translation regime
* @is_secure: security state for the access
* @result: set on translation success. * @result: set on translation success.
* @fi: set to fault info if the translation fails * @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, bool get_phys_addr_with_secure_nogpc(CPUARMState *env, target_ulong address,
MMUAccessType access_type, ARMMMUIdx mmu_idx, MMUAccessType access_type,
GetPhysAddrResult *result, ARMMMUFaultInfo *fi) ARMMMUIdx mmu_idx, bool is_secure,
GetPhysAddrResult *result,
ARMMMUFaultInfo *fi)
__attribute__((nonnull)); __attribute__((nonnull));
bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address, bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,

View File

@ -3420,16 +3420,17 @@ static bool get_phys_addr_gpc(CPUARMState *env, S1Translate *ptw,
return false; return false;
} }
bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address, bool get_phys_addr_with_secure_nogpc(CPUARMState *env, target_ulong address,
MMUAccessType access_type, ARMMMUIdx mmu_idx, MMUAccessType access_type,
bool is_secure, GetPhysAddrResult *result, ARMMMUIdx mmu_idx, bool is_secure,
ARMMMUFaultInfo *fi) GetPhysAddrResult *result,
ARMMMUFaultInfo *fi)
{ {
S1Translate ptw = { S1Translate ptw = {
.in_mmu_idx = mmu_idx, .in_mmu_idx = mmu_idx,
.in_space = arm_secure_to_space(is_secure), .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, bool get_phys_addr(CPUARMState *env, target_ulong address,