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 = {};
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

View File

@ -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,

View File

@ -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,