[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <2d9a04d8-c09e-49aa-95eb-32b4679f7eba@kili.mountain>
Date: Wed, 17 May 2023 22:30:29 +0300
From: Dan Carpenter <dan.carpenter@...aro.org>
To: Naresh Kamboju <naresh.kamboju@...aro.org>
Cc: "open list:KERNEL SELFTEST FRAMEWORK"
<linux-kselftest@...r.kernel.org>,
linux-stable <stable@...r.kernel.org>,
open list <linux-kernel@...r.kernel.org>,
lkft-triage@...ts.linaro.org, Mark Brown <broonie@...nel.org>,
Catalin Marinas <catalin.marinas@....com>,
Will Deacon <will@...nel.org>, Arnd Bergmann <arnd@...db.de>,
Shuah Khan <shuah@...nel.org>,
Anders Roxell <anders.roxell@...aro.org>
Subject: Re: arm64: fp-stress: BUG: KFENCE: memory corruption in
fpsimd_release_task
I don't know this code at all so probably this is dumb... I don't
undestand how vec_set_vector_length() ensures that sme_state_size()
stays in sync with the actual size allocated in sme_alloc()
arch/arm64/kernel/fpsimd.c
847 int vec_set_vector_length(struct task_struct *task, enum vec_type type,
848 unsigned long vl, unsigned long flags)
^^^
"vl" comes from the user and is 0-u16max.
849 {
850 if (flags & ~(unsigned long)(PR_SVE_VL_INHERIT |
851 PR_SVE_SET_VL_ONEXEC))
852 return -EINVAL;
853
854 if (!sve_vl_valid(vl))
valid values are '16-8192'
855 return -EINVAL;
856
857 /*
858 * Clamp to the maximum vector length that VL-agnostic code
859 * can work with. A flag may be assigned in the future to
860 * allow setting of larger vector lengths without confusing
861 * older software.
862 */
863 if (vl > VL_ARCH_MAX)
864 vl = VL_ARCH_MAX;
Now 16-256'
865
866 vl = find_supported_vector_length(type, vl);
type is ARM64_VEC_SVE. I've looked at this function for a while and
I don't see anything which ensures that "vl" is less than the current
value.
867
868 if (flags & (PR_SVE_VL_INHERIT |
869 PR_SVE_SET_VL_ONEXEC))
870 task_set_vl_onexec(task, type, vl);
871 else
872 /* Reset VL to system default on next exec: */
873 task_set_vl_onexec(task, type, 0);
874
875 /* Only actually set the VL if not deferred: */
876 if (flags & PR_SVE_SET_VL_ONEXEC)
Assume the PR_SVE_SET_VL_ONEXEC flag is not set.
877 goto out;
878
879 if (vl == task_get_vl(task, type))
This checks if the flag is == and if so we are done.
880 goto out;
881
882 /*
883 * To ensure the FPSIMD bits of the SVE vector registers are preserved,
884 * write any live register state back to task_struct, and convert to a
885 * regular FPSIMD thread.
886 */
887 if (task == current) {
888 get_cpu_fpsimd_context();
889
890 fpsimd_save();
891 }
892
893 fpsimd_flush_task_state(task);
894 if (test_and_clear_tsk_thread_flag(task, TIF_SVE) ||
895 thread_sm_enabled(&task->thread)) {
896 sve_to_fpsimd(task);
897 task->thread.fp_type = FP_STATE_FPSIMD;
898 }
899
900 if (system_supports_sme() && type == ARM64_VEC_SME) {
901 task->thread.svcr &= ~(SVCR_SM_MASK |
902 SVCR_ZA_MASK);
903 clear_thread_flag(TIF_SME);
904 }
905
906 if (task == current)
907 put_cpu_fpsimd_context();
908
909 /*
910 * Force reallocation of task SVE and SME state to the correct
911 * size on next use:
912 */
913 sve_free(task);
914 if (system_supports_sme() && type == ARM64_VEC_SME)
915 sme_free(task);
916
917 task_set_vl(task, type, vl);
"vl" is set here. This is fine if we are setting it to a smaller value,
but if we are setting it to a larger value then I think we need to
realloc the ->sme_state buffer.
When we call sme_alloc() it will say the buffer is already allocated
and just zero out what we need for "vl", but the existing buffer is too
small.
918
919 out:
920 update_tsk_thread_flag(task, vec_vl_inherit_flag(type),
922
923 return 0;
924 }
regards,
dan carpenter
Powered by blists - more mailing lists