xlat: Introduce function xlat_arch_tlbi_va_regime()
authorDouglas Raillard <douglas.raillard@arm.com>
Mon, 25 Sep 2017 14:23:22 +0000 (15:23 +0100)
committerAntonio Nino Diaz <antonio.ninodiaz@arm.com>
Thu, 5 Oct 2017 13:32:12 +0000 (14:32 +0100)
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>
include/lib/xlat_tables/xlat_tables_v2.h
lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
lib/xlat_tables_v2/xlat_tables_private.h

index a4f0efd3912800f34e31a1a16168498f6bf33bfc..2cc59f6d13c1792422e60ea3e4fd9bf6de897d90 100644 (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.
index e66b9275152ff0ec8132b69bc1446a50c6c303cf..30ad91e1a8d72bc082d6fa603e1e73e73a366ac6 100644 (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. */
index 81e035beb5a0562f0f9293064cd9ffe713db0e29..06bd4978552e3032ae05d0dfeaa89752e31b44ff 100644 (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)
index fbd9578a72ef623a9ddaf79e7b9017aafb01eac8..2730ab6c215086cda5209601ed1f7274b505a305 100644 (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