diff mbox series

[v4,35/45] linux-user/aarch64: Add SM bit to SVE signal context

Message ID 20220628042117.368549-36-richard.henderson@linaro.org
State Superseded
Headers show
Series target/arm: Scalable Matrix Extension | expand

Commit Message

Richard Henderson June 28, 2022, 4:21 a.m. UTC
Make sure to zero the currently reserved fields.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/aarch64/signal.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

Comments

Peter Maydell July 4, 2022, 12:02 p.m. UTC | #1
On Tue, 28 Jun 2022 at 06:04, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Make sure to zero the currently reserved fields.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/aarch64/signal.c | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
> index 7da0e36c6d..3cef2f44cf 100644
> --- a/linux-user/aarch64/signal.c
> +++ b/linux-user/aarch64/signal.c
> @@ -78,7 +78,8 @@ struct target_extra_context {
>  struct target_sve_context {
>      struct target_aarch64_ctx head;
>      uint16_t vl;
> -    uint16_t reserved[3];
> +    uint16_t flags;
> +    uint16_t reserved[2];
>      /* The actual SVE data immediately follows.  It is laid out
>       * according to TARGET_SVE_SIG_{Z,P}REG_OFFSET, based off of
>       * the original struct pointer.
> @@ -101,6 +102,8 @@ struct target_sve_context {
>  #define TARGET_SVE_SIG_CONTEXT_SIZE(VQ) \
>      (TARGET_SVE_SIG_PREG_OFFSET(VQ, 17))
>
> +#define TARGET_SVE_SIG_FLAG_SM  1
> +
>  struct target_rt_sigframe {
>      struct target_siginfo info;
>      struct target_ucontext uc;
> @@ -177,9 +180,13 @@ static void target_setup_sve_record(struct target_sve_context *sve,
>  {
>      int i, j;
>
> +    memset(sve, 0, sizeof(*sve));
>      __put_user(TARGET_SVE_MAGIC, &sve->head.magic);
>      __put_user(size, &sve->head.size);
>      __put_user(vq * TARGET_SVE_VQ_BYTES, &sve->vl);
> +    if (FIELD_EX64(env->svcr, SVCR, SM)) {
> +        __put_user(TARGET_SVE_SIG_FLAG_SM, &sve->flags);
> +    }
>

The kernel documentation says that if this is set then the SVE
record contains the streaming vector length. Does that happen
automatically (ie vq is the right thing for both streaming
and non-streaming) or do we need to do something there?

I gather that the other half of handling this bit (allowing
it to be changed on signal-return) is in a later patch.

thanks
-- PMM
Richard Henderson July 5, 2022, 3:24 a.m. UTC | #2
On 7/4/22 17:32, Peter Maydell wrote:
>> @@ -177,9 +180,13 @@ static void target_setup_sve_record(struct target_sve_context *sve,
>>   {
>>       int i, j;
>>
>> +    memset(sve, 0, sizeof(*sve));
>>       __put_user(TARGET_SVE_MAGIC, &sve->head.magic);
>>       __put_user(size, &sve->head.size);
>>       __put_user(vq * TARGET_SVE_VQ_BYTES, &sve->vl);
>> +    if (FIELD_EX64(env->svcr, SVCR, SM)) {
>> +        __put_user(TARGET_SVE_SIG_FLAG_SM, &sve->flags);
>> +    }
>>
> 
> The kernel documentation says that if this is set then the SVE
> record contains the streaming vector length. Does that happen
> automatically (ie vq is the right thing for both streaming
> and non-streaming) or do we need to do something there?

It is automatically correct (modulo the typo you found in patch 40).  The two helpers we 
have are for VL and SVL, with no direct access to NVL.

> I gather that the other half of handling this bit (allowing
> it to be changed on signal-return) is in a later patch.

Yes.


r~
diff mbox series

Patch

diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
index 7da0e36c6d..3cef2f44cf 100644
--- a/linux-user/aarch64/signal.c
+++ b/linux-user/aarch64/signal.c
@@ -78,7 +78,8 @@  struct target_extra_context {
 struct target_sve_context {
     struct target_aarch64_ctx head;
     uint16_t vl;
-    uint16_t reserved[3];
+    uint16_t flags;
+    uint16_t reserved[2];
     /* The actual SVE data immediately follows.  It is laid out
      * according to TARGET_SVE_SIG_{Z,P}REG_OFFSET, based off of
      * the original struct pointer.
@@ -101,6 +102,8 @@  struct target_sve_context {
 #define TARGET_SVE_SIG_CONTEXT_SIZE(VQ) \
     (TARGET_SVE_SIG_PREG_OFFSET(VQ, 17))
 
+#define TARGET_SVE_SIG_FLAG_SM  1
+
 struct target_rt_sigframe {
     struct target_siginfo info;
     struct target_ucontext uc;
@@ -177,9 +180,13 @@  static void target_setup_sve_record(struct target_sve_context *sve,
 {
     int i, j;
 
+    memset(sve, 0, sizeof(*sve));
     __put_user(TARGET_SVE_MAGIC, &sve->head.magic);
     __put_user(size, &sve->head.size);
     __put_user(vq * TARGET_SVE_VQ_BYTES, &sve->vl);
+    if (FIELD_EX64(env->svcr, SVCR, SM)) {
+        __put_user(TARGET_SVE_SIG_FLAG_SM, &sve->flags);
+    }
 
     /* Note that SVE regs are stored as a byte stream, with each byte element
      * at a subsequent address.  This corresponds to a little-endian store