kselftest/arm64: Teach the generic signal context validation about ZT
authorMark Brown <broonie@kernel.org>
Mon, 16 Jan 2023 16:04:52 +0000 (16:04 +0000)
committerCatalin Marinas <catalin.marinas@arm.com>
Fri, 20 Jan 2023 12:23:08 +0000 (12:23 +0000)
Add ZT to the set of signal contexts that the shared code understands and
validates the form of.

Signed-off-by: Mark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20221208-arm64-sme2-v4-17-f2fa0aef982f@kernel.org
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
tools/testing/selftests/arm64/signal/testcases/testcases.c
tools/testing/selftests/arm64/signal/testcases/testcases.h

index d2eda7b5de26cdb74d1cf2ad6623d02534d9f057..27d495fa52f8e0645abdee606eaa0fc52b5acec6 100644 (file)
@@ -108,6 +108,26 @@ bool validate_za_context(struct za_context *za, char **err)
        return true;
 }
 
+bool validate_zt_context(struct zt_context *zt, char **err)
+{
+       if (!zt || !err)
+               return false;
+
+       /* If the context is present there should be at least one register */
+       if (zt->nregs == 0) {
+               *err = "no registers";
+               return false;
+       }
+
+       /* Size should agree with the number of registers */
+       if (zt->head.size != ZT_SIG_CONTEXT_SIZE(zt->nregs)) {
+               *err = "register count does not match size";
+               return false;
+       }
+
+       return true;
+}
+
 bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
 {
        bool terminated = false;
@@ -117,6 +137,7 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
        struct extra_context *extra = NULL;
        struct sve_context *sve = NULL;
        struct za_context *za = NULL;
+       struct zt_context *zt = NULL;
        struct _aarch64_ctx *head =
                (struct _aarch64_ctx *)uc->uc_mcontext.__reserved;
        void *extra_data = NULL;
@@ -177,6 +198,13 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
                        za = (struct za_context *)head;
                        new_flags |= ZA_CTX;
                        break;
+               case ZT_MAGIC:
+                       if (flags & ZT_CTX)
+                               *err = "Multiple ZT_MAGIC";
+                       /* Size is validated in validate_za_context() */
+                       zt = (struct zt_context *)head;
+                       new_flags |= ZT_CTX;
+                       break;
                case EXTRA_MAGIC:
                        if (flags & EXTRA_CTX)
                                *err = "Multiple EXTRA_MAGIC";
@@ -234,6 +262,9 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
                if (new_flags & ZA_CTX)
                        if (!validate_za_context(za, err))
                                return false;
+               if (new_flags & ZT_CTX)
+                       if (!validate_zt_context(zt, err))
+                               return false;
 
                flags |= new_flags;
 
@@ -245,6 +276,11 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
                return false;
        }
 
+       if (terminated && (flags & ZT_CTX) && !(flags & ZA_CTX)) {
+               *err = "ZT context but no ZA context";
+               return false;
+       }
+
        return true;
 }
 
index 040afded0b76eaf8a22e2fd665a74ae4be6dc030..a08ab0d6207a3ef7b49402c8a0faad856f484b53 100644 (file)
@@ -18,6 +18,7 @@
 #define SVE_CTX                (1 << 1)
 #define ZA_CTX         (1 << 2)
 #define EXTRA_CTX      (1 << 3)
+#define ZT_CTX         (1 << 4)
 
 #define KSFT_BAD_MAGIC 0xdeadbeef