Commit ace19b18 authored by Mark Brown's avatar Mark Brown Committed by Catalin Marinas

kselftest/arm64: signal: Support signal frames with SVE register data

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: default avatarMark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20210819134245.13935-3-broonie@kernel.orgSigned-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent d4e4dc4f
...@@ -50,12 +50,38 @@ bool validate_extra_context(struct extra_context *extra, char **err) ...@@ -50,12 +50,38 @@ bool validate_extra_context(struct extra_context *extra, char **err)
return true; 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 validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
{ {
bool terminated = false; bool terminated = false;
size_t offs = 0; size_t offs = 0;
int flags = 0; int flags = 0;
struct extra_context *extra = NULL; struct extra_context *extra = NULL;
struct sve_context *sve = NULL;
struct _aarch64_ctx *head = struct _aarch64_ctx *head =
(struct _aarch64_ctx *)uc->uc_mcontext.__reserved; (struct _aarch64_ctx *)uc->uc_mcontext.__reserved;
...@@ -90,9 +116,8 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err) ...@@ -90,9 +116,8 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
case SVE_MAGIC: case SVE_MAGIC:
if (flags & SVE_CTX) if (flags & SVE_CTX)
*err = "Multiple SVE_MAGIC"; *err = "Multiple SVE_MAGIC";
else if (head->size != /* Size is validated in validate_sve_context() */
sizeof(struct sve_context)) sve = (struct sve_context *)head;
*err = "Bad size for sve_context";
flags |= SVE_CTX; flags |= SVE_CTX;
break; break;
case EXTRA_MAGIC: case EXTRA_MAGIC:
...@@ -137,6 +162,9 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err) ...@@ -137,6 +162,9 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
if (flags & EXTRA_CTX) if (flags & EXTRA_CTX)
if (!validate_extra_context(extra, err)) if (!validate_extra_context(extra, err))
return false; return false;
if (flags & SVE_CTX)
if (!validate_sve_context(sve, err))
return false;
head = GET_RESV_NEXT_HEAD(head); head = GET_RESV_NEXT_HEAD(head);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment