Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux

Pull arm64 fixes from Catalin Marinas:

- A set of fixes for FPSIMD/SVE/SME state management (around signal
handling and ptrace) where a task can be placed in an invalid state

- __nocfi added to swsusp_arch_resume() to avoid a data abort on
resuming from hibernate

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
arm64: Set __nocfi on swsusp_arch_resume()
arm64/fpsimd: signal: Fix restoration of SVE context
arm64/fpsimd: signal: Allocate SSVE storage when restoring ZA
arm64/fpsimd: ptrace: Fix SVE writes on !SME systems

+33 -21
+1 -1
arch/arm64/kernel/hibernate.c
··· 402 * Memory allocated by get_safe_page() will be dealt with by the hibernate code, 403 * we don't need to free it here. 404 */ 405 - int swsusp_arch_resume(void) 406 { 407 int rc; 408 void *zero_page;
··· 402 * Memory allocated by get_safe_page() will be dealt with by the hibernate code, 403 * we don't need to free it here. 404 */ 405 + int __nocfi swsusp_arch_resume(void) 406 { 407 int rc; 408 void *zero_page;
+12 -14
arch/arm64/kernel/ptrace.c
··· 968 vq = sve_vq_from_vl(task_get_vl(target, type)); 969 970 /* Enter/exit streaming mode */ 971 - if (system_supports_sme()) { 972 - switch (type) { 973 - case ARM64_VEC_SVE: 974 - target->thread.svcr &= ~SVCR_SM_MASK; 975 - set_tsk_thread_flag(target, TIF_SVE); 976 - break; 977 - case ARM64_VEC_SME: 978 - target->thread.svcr |= SVCR_SM_MASK; 979 - set_tsk_thread_flag(target, TIF_SME); 980 - break; 981 - default: 982 - WARN_ON_ONCE(1); 983 - return -EINVAL; 984 - } 985 } 986 987 /* Always zero V regs, FPSR, and FPCR */
··· 968 vq = sve_vq_from_vl(task_get_vl(target, type)); 969 970 /* Enter/exit streaming mode */ 971 + switch (type) { 972 + case ARM64_VEC_SVE: 973 + target->thread.svcr &= ~SVCR_SM_MASK; 974 + set_tsk_thread_flag(target, TIF_SVE); 975 + break; 976 + case ARM64_VEC_SME: 977 + target->thread.svcr |= SVCR_SM_MASK; 978 + set_tsk_thread_flag(target, TIF_SME); 979 + break; 980 + default: 981 + WARN_ON_ONCE(1); 982 + return -EINVAL; 983 } 984 985 /* Always zero V regs, FPSR, and FPCR */
+20 -6
arch/arm64/kernel/signal.c
··· 449 if (user->sve_size < SVE_SIG_CONTEXT_SIZE(vq)) 450 return -EINVAL; 451 452 sve_alloc(current, true); 453 if (!current->thread.sve_state) { 454 clear_thread_flag(TIF_SVE); 455 return -ENOMEM; 456 } 457 458 err = __copy_from_user(current->thread.sve_state, 459 (char __user const *)user->sve + ··· 477 SVE_SIG_REGS_SIZE(vq)); 478 if (err) 479 return -EFAULT; 480 - 481 - if (flags & SVE_SIG_FLAG_SM) 482 - current->thread.svcr |= SVCR_SM_MASK; 483 - else 484 - set_thread_flag(TIF_SVE); 485 - current->thread.fp_type = FP_STATE_SVE; 486 487 err = read_fpsimd_context(&fpsimd, user); 488 if (err) ··· 585 586 if (user->za_size < ZA_SIG_CONTEXT_SIZE(vq)) 587 return -EINVAL; 588 589 sme_alloc(current, true); 590 if (!current->thread.sme_state) {
··· 449 if (user->sve_size < SVE_SIG_CONTEXT_SIZE(vq)) 450 return -EINVAL; 451 452 + if (sm) { 453 + sme_alloc(current, false); 454 + if (!current->thread.sme_state) 455 + return -ENOMEM; 456 + } 457 + 458 sve_alloc(current, true); 459 if (!current->thread.sve_state) { 460 clear_thread_flag(TIF_SVE); 461 return -ENOMEM; 462 } 463 + 464 + if (sm) { 465 + current->thread.svcr |= SVCR_SM_MASK; 466 + set_thread_flag(TIF_SME); 467 + } else { 468 + current->thread.svcr &= ~SVCR_SM_MASK; 469 + set_thread_flag(TIF_SVE); 470 + } 471 + 472 + current->thread.fp_type = FP_STATE_SVE; 473 474 err = __copy_from_user(current->thread.sve_state, 475 (char __user const *)user->sve + ··· 461 SVE_SIG_REGS_SIZE(vq)); 462 if (err) 463 return -EFAULT; 464 465 err = read_fpsimd_context(&fpsimd, user); 466 if (err) ··· 575 576 if (user->za_size < ZA_SIG_CONTEXT_SIZE(vq)) 577 return -EINVAL; 578 + 579 + sve_alloc(current, false); 580 + if (!current->thread.sve_state) 581 + return -ENOMEM; 582 583 sme_alloc(current, true); 584 if (!current->thread.sme_state) {