kselftest/arm64: signal: Support signal frames with SVE register data
authorMark Brown <broonie@kernel.org>
Thu, 19 Aug 2021 13:42:41 +0000 (14:42 +0100)
committerCatalin Marinas <catalin.marinas@arm.com>
Mon, 23 Aug 2021 10:11:04 +0000 (11:11 +0100)
A signal frame with SVE may validly either be a bare struct sve_context or
a struct sve_context followed by vector length dependent register data.
Support either in the generic helpers for the signal tests, and while we're
at it validate the SVE vector length reported.

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

index 61ebcdf638311e18858c0edfe106f32b963051f0..8c2a57fc2f9cccb3dfdb2047333a752c4e662bfb 100644 (file)
@@ -50,12 +50,38 @@ bool validate_extra_context(struct extra_context *extra, char **err)
        return true;
 }
 
+bool validate_sve_context(struct sve_context *sve, char **err)
+{
+       /* Size will be rounded up to a multiple of 16 bytes */
+       size_t regs_size
+               = ((SVE_SIG_CONTEXT_SIZE(sve_vq_from_vl(sve->vl)) + 15) / 16) * 16;
+
+       if (!sve || !err)
+               return false;
+
+       /* Either a bare sve_context or a sve_context followed by regs data */
+       if ((sve->head.size != sizeof(struct sve_context)) &&
+           (sve->head.size != regs_size)) {
+               *err = "bad size for SVE context";
+               return false;
+       }
+
+       if (!sve_vl_valid(sve->vl)) {
+               *err = "SVE VL invalid";
+
+               return false;
+       }
+
+       return true;
+}
+
 bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
 {
        bool terminated = false;
        size_t offs = 0;
        int flags = 0;
        struct extra_context *extra = NULL;
+       struct sve_context *sve = NULL;
        struct _aarch64_ctx *head =
                (struct _aarch64_ctx *)uc->uc_mcontext.__reserved;
 
@@ -90,9 +116,8 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
                case SVE_MAGIC:
                        if (flags & SVE_CTX)
                                *err = "Multiple SVE_MAGIC";
-                       else if (head->size !=
-                                sizeof(struct sve_context))
-                               *err = "Bad size for sve_context";
+                       /* Size is validated in validate_sve_context() */
+                       sve = (struct sve_context *)head;
                        flags |= SVE_CTX;
                        break;
                case EXTRA_MAGIC:
@@ -137,6 +162,9 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
                if (flags & EXTRA_CTX)
                        if (!validate_extra_context(extra, err))
                                return false;
+               if (flags & SVE_CTX)
+                       if (!validate_sve_context(sve, err))
+                               return false;
 
                head = GET_RESV_NEXT_HEAD(head);
        }