return errors;
 }
 
+#define SVE_Z_SHARED_BYTES (128 / 8)
+
 static uint8_t z_zero[__SVE_ZREG_SIZE(SVE_VQ_MAX)];
 uint8_t z_in[SVE_NUM_ZREGS * __SVE_ZREG_SIZE(SVE_VQ_MAX)];
 uint8_t z_out[SVE_NUM_ZREGS * __SVE_ZREG_SIZE(SVE_VQ_MAX)];
        if (!sve_vl)
                return 0;
 
-       /*
-        * After a syscall the low 128 bits of the Z registers should
-        * be preserved and the rest be zeroed or preserved, except if
-        * we were in streaming mode in which case the low 128 bits may
-        * also be cleared by the transition out of streaming mode.
-        */
        for (i = 0; i < SVE_NUM_ZREGS; i++) {
-               void *in = &z_in[reg_size * i];
-               void *out = &z_out[reg_size * i];
-
-               if ((memcmp(in, out, SVE_VQ_BYTES) != 0) &&
-                   !((svcr & SVCR_SM_MASK) &&
-                     memcmp(z_zero, out, SVE_VQ_BYTES) == 0)) {
-                       ksft_print_msg("%s SVE VL %d Z%d low 128 bits changed\n",
-                                      cfg->name, sve_vl, i);
-                       errors++;
+               uint8_t *in = &z_in[reg_size * i];
+               uint8_t *out = &z_out[reg_size * i];
+
+               if (svcr & SVCR_SM_MASK) {
+                       /*
+                        * In streaming mode the whole register should
+                        * be cleared by the transition out of
+                        * streaming mode.
+                        */
+                       if (memcmp(z_zero, out, reg_size) != 0) {
+                               ksft_print_msg("%s SVE VL %d Z%d non-zero\n",
+                                              cfg->name, sve_vl, i);
+                               errors++;
+                       }
+               } else {
+                       /*
+                        * For standard SVE the low 128 bits should be
+                        * preserved and any additional bits cleared.
+                        */
+                       if (memcmp(in, out, SVE_Z_SHARED_BYTES) != 0) {
+                               ksft_print_msg("%s SVE VL %d Z%d low 128 bits changed\n",
+                                              cfg->name, sve_vl, i);
+                               errors++;
+                       }
+
+                       if (reg_size > SVE_Z_SHARED_BYTES &&
+                           (memcmp(z_zero, out + SVE_Z_SHARED_BYTES,
+                                   reg_size - SVE_Z_SHARED_BYTES) != 0)) {
+                               ksft_print_msg("%s SVE VL %d Z%d high bits non-zero\n",
+                                              cfg->name, sve_vl, i);
+                               errors++;
+                       }
                }
        }
 
        if (!sve_vl)
                return 0;
 
-       /* After a syscall the P registers should be preserved or zeroed */
+       /* After a syscall the P registers should be zeroed */
        for (i = 0; i < SVE_NUM_PREGS * reg_size; i++)
-               if (p_out[i] && (p_in[i] != p_out[i]))
+               if (p_out[i])
                        errors++;
        if (errors)
                ksft_print_msg("%s SVE VL %d predicate registers non-zero\n",
            !(getauxval(AT_HWCAP2) & HWCAP2_SME_FA64))
                return 0;
 
-       /* After a syscall the P registers should be preserved or zeroed */
+       /* After a syscall FFR should be zeroed */
        for (i = 0; i < reg_size; i++)
-               if (ffr_out[i] && (ffr_in[i] != ffr_out[i]))
+               if (ffr_out[i])
                        errors++;
        if (errors)
                ksft_print_msg("%s SVE VL %d FFR non-zero\n",