xlat: Introduce function xlat_arch_tlbi_va_regime()

Introduce a variant of the TLB invalidation helper function that
allows the targeted translation regime to be specified, rather than
defaulting to the current one.

This new function is useful in the context of EL3 software managing
translation tables for the S-EL1&0 translation regime, as then it
might need to invalidate S-EL1&0 TLB entries rather than EL3 ones.

Define a new enumeration to be able to represent translation regimes in
the xlat tables library.

Change-Id: Ibe4438dbea2d7a6e7470bfb68ff805d8bf6b07e5
Co-authored-by: Sandrine Bailleux <sandrine.bailleux@arm.com>
Co-authored-by: Douglas Raillard <douglas.raillard@arm.com>
Co-authored-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
This commit is contained in:
Douglas Raillard 2017-09-25 15:23:22 +01:00 committed by Antonio Nino Diaz
parent f301da44fa
commit b4ae615bd7
4 changed files with 58 additions and 10 deletions

View File

@ -106,6 +106,14 @@ typedef struct mmap_region {
size_t granularity;
} mmap_region_t;
/*
* Translation regimes supported by this library.
*/
typedef enum xlat_regime {
EL1_EL0_REGIME,
EL3_REGIME,
} xlat_regime_t;
/*
* Declare the translation context type.
* Its definition is private.

View File

@ -40,6 +40,17 @@ void xlat_arch_tlbi_va(uintptr_t va)
tlbimvaais(TLBI_ADDR(va));
}
void xlat_arch_tlbi_va_regime(uintptr_t va, xlat_regime_t xlat_regime __unused)
{
/*
* Ensure the translation table write has drained into memory before
* invalidating the TLB entry.
*/
dsbishst();
tlbimvaais(TLBI_ADDR(va));
}
void xlat_arch_tlbi_va_sync(void)
{
/* Invalidate all entries from branch predictors. */

View File

@ -82,6 +82,17 @@ int is_mmu_enabled(void)
}
void xlat_arch_tlbi_va(uintptr_t va)
{
#if IMAGE_EL == 1
assert(IS_IN_EL(1));
xlat_arch_tlbi_va_regime(va, EL1_EL0_REGIME);
#elif IMAGE_EL == 3
assert(IS_IN_EL(3));
xlat_arch_tlbi_va_regime(va, EL3_REGIME);
#endif
}
void xlat_arch_tlbi_va_regime(uintptr_t va, xlat_regime_t xlat_regime)
{
/*
* Ensure the translation table write has drained into memory before
@ -89,13 +100,21 @@ void xlat_arch_tlbi_va(uintptr_t va)
*/
dsbishst();
#if IMAGE_EL == 1
assert(IS_IN_EL(1));
tlbivaae1is(TLBI_ADDR(va));
#elif IMAGE_EL == 3
assert(IS_IN_EL(3));
tlbivae3is(TLBI_ADDR(va));
#endif
/*
* This function only supports invalidation of TLB entries for the EL3
* and EL1&0 translation regimes.
*
* Also, it is architecturally UNDEFINED to invalidate TLBs of a higher
* exception level (see section D4.9.2 of the ARM ARM rev B.a).
*/
if (xlat_regime == EL1_EL0_REGIME) {
assert(xlat_arch_current_el() >= 1);
tlbivaae1is(TLBI_ADDR(va));
} else {
assert(xlat_regime == EL3_REGIME);
assert(xlat_arch_current_el() >= 3);
tlbivae3is(TLBI_ADDR(va));
}
}
void xlat_arch_tlbi_va_sync(void)

View File

@ -37,11 +37,21 @@ typedef enum {
#endif /* PLAT_XLAT_TABLES_DYNAMIC */
/*
* Function used to invalidate all levels of the translation walk for a given
* virtual address. It must be called for every translation table entry that is
* modified.
* Invalidate all TLB entries that match the given virtual address. This
* operation applies to all PEs in the same Inner Shareable domain as the PE
* that executes this function. This functions must be called for every
* translation table entry that is modified.
*
* xlat_arch_tlbi_va() applies the invalidation to the exception level of the
* current translation regime, whereas xlat_arch_tlbi_va_regime() applies it to
* the given translation regime.
*
* Note, however, that it is architecturally UNDEFINED to invalidate TLB entries
* pertaining to a higher exception level, e.g. invalidating EL3 entries from
* S-EL1.
*/
void xlat_arch_tlbi_va(uintptr_t va);
void xlat_arch_tlbi_va_regime(uintptr_t va, xlat_regime_t xlat_regime);
/*
* This function has to be called at the end of any code that uses the function