From: Sasha Levin Date: Tue, 17 Mar 2026 01:31:52 +0000 (-0400) Subject: Fixes for all trees X-Git-Tag: v6.18.19~61^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c63decde926d572628fbaacd5c736f7c48ff5d19;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for all trees Signed-off-by: Sasha Levin --- diff --git a/queue-5.10/series b/queue-5.10/series index 856c9bb734..efd3a1226b 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -102,3 +102,5 @@ usb-class-cdc-wdm-fix-reordering-issue-in-read-code-path.patch usb-renesas_usbhs-fix-use-after-free-in-isr-during-device-removal.patch usb-mdc800-handle-signal-and-read-racing.patch usb-image-mdc800-kill-download-urb-on-timeout.patch +time-add-kernel-doc-in-time.c.patch +time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch diff --git a/queue-5.10/time-add-kernel-doc-in-time.c.patch b/queue-5.10/time-add-kernel-doc-in-time.c.patch new file mode 100644 index 0000000000..bcfa2fb4f0 --- /dev/null +++ b/queue-5.10/time-add-kernel-doc-in-time.c.patch @@ -0,0 +1,404 @@ +From b7d9fa4ee9490fd2f3e497fe4fa152cf19e85511 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Jul 2023 22:24:05 -0700 +Subject: time: add kernel-doc in time.c + +From: Randy Dunlap + +[ Upstream commit 67b3f564cb1e769ef8e45835129a4866152fcfdb ] + +Add kernel-doc for all APIs that do not already have it. + +Signed-off-by: Randy Dunlap +Cc: John Stultz +Cc: Thomas Gleixner +Cc: Stephen Boyd +Cc: Jonathan Corbet +Cc: linux-doc@vger.kernel.org +Acked-by: John Stultz +Signed-off-by: Jonathan Corbet +Link: https://lore.kernel.org/r/20230704052405.5089-3-rdunlap@infradead.org +Stable-dep-of: 755a648e78f1 ("time/jiffies: Mark jiffies_64_to_clock_t() notrace") +Signed-off-by: Sasha Levin +--- + kernel/time/time.c | 169 ++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 158 insertions(+), 11 deletions(-) + +diff --git a/kernel/time/time.c b/kernel/time/time.c +index 483f8a3e24d0c..6f81aead1856d 100644 +--- a/kernel/time/time.c ++++ b/kernel/time/time.c +@@ -365,11 +365,14 @@ SYSCALL_DEFINE1(adjtimex_time32, struct old_timex32 __user *, utp) + } + #endif + +-/* +- * Convert jiffies to milliseconds and back. ++/** ++ * jiffies_to_msecs - Convert jiffies to milliseconds ++ * @j: jiffies value + * + * Avoid unnecessary multiplications/divisions in the +- * two most common HZ cases: ++ * two most common HZ cases. ++ * ++ * Return: milliseconds value + */ + unsigned int jiffies_to_msecs(const unsigned long j) + { +@@ -388,6 +391,12 @@ unsigned int jiffies_to_msecs(const unsigned long j) + } + EXPORT_SYMBOL(jiffies_to_msecs); + ++/** ++ * jiffies_to_usecs - Convert jiffies to microseconds ++ * @j: jiffies value ++ * ++ * Return: microseconds value ++ */ + unsigned int jiffies_to_usecs(const unsigned long j) + { + /* +@@ -408,8 +417,15 @@ unsigned int jiffies_to_usecs(const unsigned long j) + } + EXPORT_SYMBOL(jiffies_to_usecs); + +-/* ++/** + * mktime64 - Converts date to seconds. ++ * @year0: year to convert ++ * @mon0: month to convert ++ * @day: day to convert ++ * @hour: hour to convert ++ * @min: minute to convert ++ * @sec: second to convert ++ * + * Converts Gregorian date to seconds since 1970-01-01 00:00:00. + * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 + * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. +@@ -427,6 +443,8 @@ EXPORT_SYMBOL(jiffies_to_usecs); + * + * An encoding of midnight at the end of the day as 24:00:00 - ie. midnight + * tomorrow - (allowable under ISO 8601) is supported. ++ * ++ * Return: seconds since the epoch time for the given input date + */ + time64_t mktime64(const unsigned int year0, const unsigned int mon0, + const unsigned int day, const unsigned int hour, +@@ -471,8 +489,7 @@ EXPORT_SYMBOL(ns_to_kernel_old_timeval); + * Set seconds and nanoseconds field of a timespec variable and + * normalize to the timespec storage format + * +- * Note: The tv_nsec part is always in the range of +- * 0 <= tv_nsec < NSEC_PER_SEC ++ * Note: The tv_nsec part is always in the range of 0 <= tv_nsec < NSEC_PER_SEC. + * For negative values only the tv_sec field is negative ! + */ + void set_normalized_timespec64(struct timespec64 *ts, time64_t sec, s64 nsec) +@@ -501,7 +518,7 @@ EXPORT_SYMBOL(set_normalized_timespec64); + * ns_to_timespec64 - Convert nanoseconds to timespec64 + * @nsec: the nanoseconds value to be converted + * +- * Returns the timespec64 representation of the nsec parameter. ++ * Return: the timespec64 representation of the nsec parameter. + */ + struct timespec64 ns_to_timespec64(const s64 nsec) + { +@@ -548,6 +565,8 @@ EXPORT_SYMBOL(ns_to_timespec64); + * runtime. + * the _msecs_to_jiffies helpers are the HZ dependent conversion + * routines found in include/linux/jiffies.h ++ * ++ * Return: jiffies value + */ + unsigned long __msecs_to_jiffies(const unsigned int m) + { +@@ -560,6 +579,12 @@ unsigned long __msecs_to_jiffies(const unsigned int m) + } + EXPORT_SYMBOL(__msecs_to_jiffies); + ++/** ++ * __usecs_to_jiffies: - convert microseconds to jiffies ++ * @u: time in milliseconds ++ * ++ * Return: jiffies value ++ */ + unsigned long __usecs_to_jiffies(const unsigned int u) + { + if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET)) +@@ -568,7 +593,10 @@ unsigned long __usecs_to_jiffies(const unsigned int u) + } + EXPORT_SYMBOL(__usecs_to_jiffies); + +-/* ++/** ++ * timespec64_to_jiffies - convert a timespec64 value to jiffies ++ * @value: pointer to &struct timespec64 ++ * + * The TICK_NSEC - 1 rounds up the value to the next resolution. Note + * that a remainder subtract here would not do the right thing as the + * resolution values don't fall on second boundries. I.e. the line: +@@ -582,8 +610,9 @@ EXPORT_SYMBOL(__usecs_to_jiffies); + * + * The >> (NSEC_JIFFIE_SC - SEC_JIFFIE_SC) converts the scaled nsec + * value to a scaled second value. ++ * ++ * Return: jiffies value + */ +- + unsigned long + timespec64_to_jiffies(const struct timespec64 *value) + { +@@ -601,6 +630,11 @@ timespec64_to_jiffies(const struct timespec64 *value) + } + EXPORT_SYMBOL(timespec64_to_jiffies); + ++/** ++ * jiffies_to_timespec64 - convert jiffies value to &struct timespec64 ++ * @jiffies: jiffies value ++ * @value: pointer to &struct timespec64 ++ */ + void + jiffies_to_timespec64(const unsigned long jiffies, struct timespec64 *value) + { +@@ -618,6 +652,13 @@ EXPORT_SYMBOL(jiffies_to_timespec64); + /* + * Convert jiffies/jiffies_64 to clock_t and back. + */ ++ ++/** ++ * jiffies_to_clock_t - Convert jiffies to clock_t ++ * @x: jiffies value ++ * ++ * Return: jiffies converted to clock_t (CLOCKS_PER_SEC) ++ */ + clock_t jiffies_to_clock_t(unsigned long x) + { + #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 +@@ -632,6 +673,12 @@ clock_t jiffies_to_clock_t(unsigned long x) + } + EXPORT_SYMBOL(jiffies_to_clock_t); + ++/** ++ * clock_t_to_jiffies - Convert clock_t to jiffies ++ * @x: clock_t value ++ * ++ * Return: clock_t value converted to jiffies ++ */ + unsigned long clock_t_to_jiffies(unsigned long x) + { + #if (HZ % USER_HZ)==0 +@@ -649,6 +696,12 @@ unsigned long clock_t_to_jiffies(unsigned long x) + } + EXPORT_SYMBOL(clock_t_to_jiffies); + ++/** ++ * jiffies_64_to_clock_t - Convert jiffies_64 to clock_t ++ * @x: jiffies_64 value ++ * ++ * Return: jiffies_64 value converted to 64-bit "clock_t" (CLOCKS_PER_SEC) ++ */ + u64 jiffies_64_to_clock_t(u64 x) + { + #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 +@@ -671,6 +724,12 @@ u64 jiffies_64_to_clock_t(u64 x) + } + EXPORT_SYMBOL(jiffies_64_to_clock_t); + ++/** ++ * nsec_to_clock_t - Convert nsec value to clock_t ++ * @x: nsec value ++ * ++ * Return: nsec value converted to 64-bit "clock_t" (CLOCKS_PER_SEC) ++ */ + u64 nsec_to_clock_t(u64 x) + { + #if (NSEC_PER_SEC % USER_HZ) == 0 +@@ -687,6 +746,12 @@ u64 nsec_to_clock_t(u64 x) + #endif + } + ++/** ++ * jiffies64_to_nsecs - Convert jiffies64 to nanoseconds ++ * @j: jiffies64 value ++ * ++ * Return: nanoseconds value ++ */ + u64 jiffies64_to_nsecs(u64 j) + { + #if !(NSEC_PER_SEC % HZ) +@@ -697,6 +762,12 @@ u64 jiffies64_to_nsecs(u64 j) + } + EXPORT_SYMBOL(jiffies64_to_nsecs); + ++/** ++ * jiffies64_to_msecs - Convert jiffies64 to milliseconds ++ * @j: jiffies64 value ++ * ++ * Return: milliseconds value ++ */ + u64 jiffies64_to_msecs(const u64 j) + { + #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) +@@ -719,6 +790,8 @@ EXPORT_SYMBOL(jiffies64_to_msecs); + * note: + * NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512) + * ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years ++ * ++ * Return: nsecs converted to jiffies64 value + */ + u64 nsecs_to_jiffies64(u64 n) + { +@@ -750,6 +823,8 @@ EXPORT_SYMBOL(nsecs_to_jiffies64); + * note: + * NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512) + * ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years ++ * ++ * Return: nsecs converted to jiffies value + */ + unsigned long nsecs_to_jiffies(u64 n) + { +@@ -757,10 +832,16 @@ unsigned long nsecs_to_jiffies(u64 n) + } + EXPORT_SYMBOL_GPL(nsecs_to_jiffies); + +-/* +- * Add two timespec64 values and do a safety check for overflow. ++/** ++ * timespec64_add_safe - Add two timespec64 values and do a safety check ++ * for overflow. ++ * @lhs: first (left) timespec64 to add ++ * @rhs: second (right) timespec64 to add ++ * + * It's assumed that both values are valid (>= 0). + * And, each timespec64 is in normalized form. ++ * ++ * Return: sum of @lhs + @rhs + */ + struct timespec64 timespec64_add_safe(const struct timespec64 lhs, + const struct timespec64 rhs) +@@ -778,6 +859,15 @@ struct timespec64 timespec64_add_safe(const struct timespec64 lhs, + return res; + } + ++/** ++ * get_timespec64 - get user's time value into kernel space ++ * @ts: destination &struct timespec64 ++ * @uts: user's time value as &struct __kernel_timespec ++ * ++ * Handles compat or 32-bit modes. ++ * ++ * Return: %0 on success or negative errno on error ++ */ + int get_timespec64(struct timespec64 *ts, + const struct __kernel_timespec __user *uts) + { +@@ -801,6 +891,14 @@ int get_timespec64(struct timespec64 *ts, + } + EXPORT_SYMBOL_GPL(get_timespec64); + ++/** ++ * put_timespec64 - convert timespec64 value to __kernel_timespec format and ++ * copy the latter to userspace ++ * @ts: input &struct timespec64 ++ * @uts: user's &struct __kernel_timespec ++ * ++ * Return: %0 on success or negative errno on error ++ */ + int put_timespec64(const struct timespec64 *ts, + struct __kernel_timespec __user *uts) + { +@@ -839,6 +937,15 @@ static int __put_old_timespec32(const struct timespec64 *ts64, + return copy_to_user(cts, &ts, sizeof(ts)) ? -EFAULT : 0; + } + ++/** ++ * get_old_timespec32 - get user's old-format time value into kernel space ++ * @ts: destination &struct timespec64 ++ * @uts: user's old-format time value (&struct old_timespec32) ++ * ++ * Handles X86_X32_ABI compatibility conversion. ++ * ++ * Return: %0 on success or negative errno on error ++ */ + int get_old_timespec32(struct timespec64 *ts, const void __user *uts) + { + if (COMPAT_USE_64BIT_TIME) +@@ -848,6 +955,16 @@ int get_old_timespec32(struct timespec64 *ts, const void __user *uts) + } + EXPORT_SYMBOL_GPL(get_old_timespec32); + ++/** ++ * put_old_timespec32 - convert timespec64 value to &struct old_timespec32 and ++ * copy the latter to userspace ++ * @ts: input &struct timespec64 ++ * @uts: user's &struct old_timespec32 ++ * ++ * Handles X86_X32_ABI compatibility conversion. ++ * ++ * Return: %0 on success or negative errno on error ++ */ + int put_old_timespec32(const struct timespec64 *ts, void __user *uts) + { + if (COMPAT_USE_64BIT_TIME) +@@ -857,6 +974,13 @@ int put_old_timespec32(const struct timespec64 *ts, void __user *uts) + } + EXPORT_SYMBOL_GPL(put_old_timespec32); + ++/** ++ * get_itimerspec64 - get user's &struct __kernel_itimerspec into kernel space ++ * @it: destination &struct itimerspec64 ++ * @uit: user's &struct __kernel_itimerspec ++ * ++ * Return: %0 on success or negative errno on error ++ */ + int get_itimerspec64(struct itimerspec64 *it, + const struct __kernel_itimerspec __user *uit) + { +@@ -872,6 +996,14 @@ int get_itimerspec64(struct itimerspec64 *it, + } + EXPORT_SYMBOL_GPL(get_itimerspec64); + ++/** ++ * put_itimerspec64 - convert &struct itimerspec64 to __kernel_itimerspec format ++ * and copy the latter to userspace ++ * @it: input &struct itimerspec64 ++ * @uit: user's &struct __kernel_itimerspec ++ * ++ * Return: %0 on success or negative errno on error ++ */ + int put_itimerspec64(const struct itimerspec64 *it, + struct __kernel_itimerspec __user *uit) + { +@@ -887,6 +1019,13 @@ int put_itimerspec64(const struct itimerspec64 *it, + } + EXPORT_SYMBOL_GPL(put_itimerspec64); + ++/** ++ * get_old_itimerspec32 - get user's &struct old_itimerspec32 into kernel space ++ * @its: destination &struct itimerspec64 ++ * @uits: user's &struct old_itimerspec32 ++ * ++ * Return: %0 on success or negative errno on error ++ */ + int get_old_itimerspec32(struct itimerspec64 *its, + const struct old_itimerspec32 __user *uits) + { +@@ -898,6 +1037,14 @@ int get_old_itimerspec32(struct itimerspec64 *its, + } + EXPORT_SYMBOL_GPL(get_old_itimerspec32); + ++/** ++ * put_old_itimerspec32 - convert &struct itimerspec64 to &struct ++ * old_itimerspec32 and copy the latter to userspace ++ * @its: input &struct itimerspec64 ++ * @uits: user's &struct old_itimerspec32 ++ * ++ * Return: %0 on success or negative errno on error ++ */ + int put_old_itimerspec32(const struct itimerspec64 *its, + struct old_itimerspec32 __user *uits) + { +-- +2.51.0 + diff --git a/queue-5.10/time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch b/queue-5.10/time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch new file mode 100644 index 0000000000..aa57dd8dd7 --- /dev/null +++ b/queue-5.10/time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch @@ -0,0 +1,39 @@ +From e767072424f5c63930f90b4555a940e34b050b41 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Mar 2026 21:24:03 -0500 +Subject: time/jiffies: Mark jiffies_64_to_clock_t() notrace + +From: Steven Rostedt + +[ Upstream commit 755a648e78f12574482d4698d877375793867fa1 ] + +The trace_clock_jiffies() function that handles the "uptime" clock for +tracing calls jiffies_64_to_clock_t(). This causes the function tracer to +constantly recurse when the tracing clock is set to "uptime". Mark it +notrace to prevent unnecessary recursion when using the "uptime" clock. + +Fixes: 58d4e21e50ff3 ("tracing: Fix wraparound problems in "uptime" trace clock") +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Thomas Gleixner +Link: https://patch.msgid.link/20260306212403.72270bb2@robin +Signed-off-by: Sasha Levin +--- + kernel/time/time.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/time/time.c b/kernel/time/time.c +index 6f81aead1856d..37c381607f372 100644 +--- a/kernel/time/time.c ++++ b/kernel/time/time.c +@@ -702,7 +702,7 @@ EXPORT_SYMBOL(clock_t_to_jiffies); + * + * Return: jiffies_64 value converted to 64-bit "clock_t" (CLOCKS_PER_SEC) + */ +-u64 jiffies_64_to_clock_t(u64 x) ++notrace u64 jiffies_64_to_clock_t(u64 x) + { + #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 + # if HZ < USER_HZ +-- +2.51.0 + diff --git a/queue-5.15/series b/queue-5.15/series index 36ee1a9e3c..60faf0add5 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -144,3 +144,5 @@ usb-class-cdc-wdm-fix-reordering-issue-in-read-code-path.patch usb-renesas_usbhs-fix-use-after-free-in-isr-during-device-removal.patch usb-mdc800-handle-signal-and-read-racing.patch usb-image-mdc800-kill-download-urb-on-timeout.patch +time-add-kernel-doc-in-time.c.patch +time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch diff --git a/queue-5.15/time-add-kernel-doc-in-time.c.patch b/queue-5.15/time-add-kernel-doc-in-time.c.patch new file mode 100644 index 0000000000..2273256268 --- /dev/null +++ b/queue-5.15/time-add-kernel-doc-in-time.c.patch @@ -0,0 +1,404 @@ +From fbcc7f534a757bff38652e9a2a0165b8aa78ad4e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Jul 2023 22:24:05 -0700 +Subject: time: add kernel-doc in time.c + +From: Randy Dunlap + +[ Upstream commit 67b3f564cb1e769ef8e45835129a4866152fcfdb ] + +Add kernel-doc for all APIs that do not already have it. + +Signed-off-by: Randy Dunlap +Cc: John Stultz +Cc: Thomas Gleixner +Cc: Stephen Boyd +Cc: Jonathan Corbet +Cc: linux-doc@vger.kernel.org +Acked-by: John Stultz +Signed-off-by: Jonathan Corbet +Link: https://lore.kernel.org/r/20230704052405.5089-3-rdunlap@infradead.org +Stable-dep-of: 755a648e78f1 ("time/jiffies: Mark jiffies_64_to_clock_t() notrace") +Signed-off-by: Sasha Levin +--- + kernel/time/time.c | 169 ++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 158 insertions(+), 11 deletions(-) + +diff --git a/kernel/time/time.c b/kernel/time/time.c +index a7fce68465a38..50390158e9d97 100644 +--- a/kernel/time/time.c ++++ b/kernel/time/time.c +@@ -365,11 +365,14 @@ SYSCALL_DEFINE1(adjtimex_time32, struct old_timex32 __user *, utp) + } + #endif + +-/* +- * Convert jiffies to milliseconds and back. ++/** ++ * jiffies_to_msecs - Convert jiffies to milliseconds ++ * @j: jiffies value + * + * Avoid unnecessary multiplications/divisions in the +- * two most common HZ cases: ++ * two most common HZ cases. ++ * ++ * Return: milliseconds value + */ + unsigned int jiffies_to_msecs(const unsigned long j) + { +@@ -388,6 +391,12 @@ unsigned int jiffies_to_msecs(const unsigned long j) + } + EXPORT_SYMBOL(jiffies_to_msecs); + ++/** ++ * jiffies_to_usecs - Convert jiffies to microseconds ++ * @j: jiffies value ++ * ++ * Return: microseconds value ++ */ + unsigned int jiffies_to_usecs(const unsigned long j) + { + /* +@@ -408,8 +417,15 @@ unsigned int jiffies_to_usecs(const unsigned long j) + } + EXPORT_SYMBOL(jiffies_to_usecs); + +-/* ++/** + * mktime64 - Converts date to seconds. ++ * @year0: year to convert ++ * @mon0: month to convert ++ * @day: day to convert ++ * @hour: hour to convert ++ * @min: minute to convert ++ * @sec: second to convert ++ * + * Converts Gregorian date to seconds since 1970-01-01 00:00:00. + * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 + * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. +@@ -427,6 +443,8 @@ EXPORT_SYMBOL(jiffies_to_usecs); + * + * An encoding of midnight at the end of the day as 24:00:00 - ie. midnight + * tomorrow - (allowable under ISO 8601) is supported. ++ * ++ * Return: seconds since the epoch time for the given input date + */ + time64_t mktime64(const unsigned int year0, const unsigned int mon0, + const unsigned int day, const unsigned int hour, +@@ -471,8 +489,7 @@ EXPORT_SYMBOL(ns_to_kernel_old_timeval); + * Set seconds and nanoseconds field of a timespec variable and + * normalize to the timespec storage format + * +- * Note: The tv_nsec part is always in the range of +- * 0 <= tv_nsec < NSEC_PER_SEC ++ * Note: The tv_nsec part is always in the range of 0 <= tv_nsec < NSEC_PER_SEC. + * For negative values only the tv_sec field is negative ! + */ + void set_normalized_timespec64(struct timespec64 *ts, time64_t sec, s64 nsec) +@@ -501,7 +518,7 @@ EXPORT_SYMBOL(set_normalized_timespec64); + * ns_to_timespec64 - Convert nanoseconds to timespec64 + * @nsec: the nanoseconds value to be converted + * +- * Returns the timespec64 representation of the nsec parameter. ++ * Return: the timespec64 representation of the nsec parameter. + */ + struct timespec64 ns_to_timespec64(const s64 nsec) + { +@@ -548,6 +565,8 @@ EXPORT_SYMBOL(ns_to_timespec64); + * runtime. + * the _msecs_to_jiffies helpers are the HZ dependent conversion + * routines found in include/linux/jiffies.h ++ * ++ * Return: jiffies value + */ + unsigned long __msecs_to_jiffies(const unsigned int m) + { +@@ -560,6 +579,12 @@ unsigned long __msecs_to_jiffies(const unsigned int m) + } + EXPORT_SYMBOL(__msecs_to_jiffies); + ++/** ++ * __usecs_to_jiffies: - convert microseconds to jiffies ++ * @u: time in milliseconds ++ * ++ * Return: jiffies value ++ */ + unsigned long __usecs_to_jiffies(const unsigned int u) + { + if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET)) +@@ -568,7 +593,10 @@ unsigned long __usecs_to_jiffies(const unsigned int u) + } + EXPORT_SYMBOL(__usecs_to_jiffies); + +-/* ++/** ++ * timespec64_to_jiffies - convert a timespec64 value to jiffies ++ * @value: pointer to &struct timespec64 ++ * + * The TICK_NSEC - 1 rounds up the value to the next resolution. Note + * that a remainder subtract here would not do the right thing as the + * resolution values don't fall on second boundaries. I.e. the line: +@@ -582,8 +610,9 @@ EXPORT_SYMBOL(__usecs_to_jiffies); + * + * The >> (NSEC_JIFFIE_SC - SEC_JIFFIE_SC) converts the scaled nsec + * value to a scaled second value. ++ * ++ * Return: jiffies value + */ +- + unsigned long + timespec64_to_jiffies(const struct timespec64 *value) + { +@@ -601,6 +630,11 @@ timespec64_to_jiffies(const struct timespec64 *value) + } + EXPORT_SYMBOL(timespec64_to_jiffies); + ++/** ++ * jiffies_to_timespec64 - convert jiffies value to &struct timespec64 ++ * @jiffies: jiffies value ++ * @value: pointer to &struct timespec64 ++ */ + void + jiffies_to_timespec64(const unsigned long jiffies, struct timespec64 *value) + { +@@ -618,6 +652,13 @@ EXPORT_SYMBOL(jiffies_to_timespec64); + /* + * Convert jiffies/jiffies_64 to clock_t and back. + */ ++ ++/** ++ * jiffies_to_clock_t - Convert jiffies to clock_t ++ * @x: jiffies value ++ * ++ * Return: jiffies converted to clock_t (CLOCKS_PER_SEC) ++ */ + clock_t jiffies_to_clock_t(unsigned long x) + { + #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 +@@ -632,6 +673,12 @@ clock_t jiffies_to_clock_t(unsigned long x) + } + EXPORT_SYMBOL(jiffies_to_clock_t); + ++/** ++ * clock_t_to_jiffies - Convert clock_t to jiffies ++ * @x: clock_t value ++ * ++ * Return: clock_t value converted to jiffies ++ */ + unsigned long clock_t_to_jiffies(unsigned long x) + { + #if (HZ % USER_HZ)==0 +@@ -649,6 +696,12 @@ unsigned long clock_t_to_jiffies(unsigned long x) + } + EXPORT_SYMBOL(clock_t_to_jiffies); + ++/** ++ * jiffies_64_to_clock_t - Convert jiffies_64 to clock_t ++ * @x: jiffies_64 value ++ * ++ * Return: jiffies_64 value converted to 64-bit "clock_t" (CLOCKS_PER_SEC) ++ */ + u64 jiffies_64_to_clock_t(u64 x) + { + #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 +@@ -671,6 +724,12 @@ u64 jiffies_64_to_clock_t(u64 x) + } + EXPORT_SYMBOL(jiffies_64_to_clock_t); + ++/** ++ * nsec_to_clock_t - Convert nsec value to clock_t ++ * @x: nsec value ++ * ++ * Return: nsec value converted to 64-bit "clock_t" (CLOCKS_PER_SEC) ++ */ + u64 nsec_to_clock_t(u64 x) + { + #if (NSEC_PER_SEC % USER_HZ) == 0 +@@ -687,6 +746,12 @@ u64 nsec_to_clock_t(u64 x) + #endif + } + ++/** ++ * jiffies64_to_nsecs - Convert jiffies64 to nanoseconds ++ * @j: jiffies64 value ++ * ++ * Return: nanoseconds value ++ */ + u64 jiffies64_to_nsecs(u64 j) + { + #if !(NSEC_PER_SEC % HZ) +@@ -697,6 +762,12 @@ u64 jiffies64_to_nsecs(u64 j) + } + EXPORT_SYMBOL(jiffies64_to_nsecs); + ++/** ++ * jiffies64_to_msecs - Convert jiffies64 to milliseconds ++ * @j: jiffies64 value ++ * ++ * Return: milliseconds value ++ */ + u64 jiffies64_to_msecs(const u64 j) + { + #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) +@@ -719,6 +790,8 @@ EXPORT_SYMBOL(jiffies64_to_msecs); + * note: + * NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512) + * ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years ++ * ++ * Return: nsecs converted to jiffies64 value + */ + u64 nsecs_to_jiffies64(u64 n) + { +@@ -750,6 +823,8 @@ EXPORT_SYMBOL(nsecs_to_jiffies64); + * note: + * NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512) + * ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years ++ * ++ * Return: nsecs converted to jiffies value + */ + unsigned long nsecs_to_jiffies(u64 n) + { +@@ -757,10 +832,16 @@ unsigned long nsecs_to_jiffies(u64 n) + } + EXPORT_SYMBOL_GPL(nsecs_to_jiffies); + +-/* +- * Add two timespec64 values and do a safety check for overflow. ++/** ++ * timespec64_add_safe - Add two timespec64 values and do a safety check ++ * for overflow. ++ * @lhs: first (left) timespec64 to add ++ * @rhs: second (right) timespec64 to add ++ * + * It's assumed that both values are valid (>= 0). + * And, each timespec64 is in normalized form. ++ * ++ * Return: sum of @lhs + @rhs + */ + struct timespec64 timespec64_add_safe(const struct timespec64 lhs, + const struct timespec64 rhs) +@@ -778,6 +859,15 @@ struct timespec64 timespec64_add_safe(const struct timespec64 lhs, + return res; + } + ++/** ++ * get_timespec64 - get user's time value into kernel space ++ * @ts: destination &struct timespec64 ++ * @uts: user's time value as &struct __kernel_timespec ++ * ++ * Handles compat or 32-bit modes. ++ * ++ * Return: %0 on success or negative errno on error ++ */ + int get_timespec64(struct timespec64 *ts, + const struct __kernel_timespec __user *uts) + { +@@ -801,6 +891,14 @@ int get_timespec64(struct timespec64 *ts, + } + EXPORT_SYMBOL_GPL(get_timespec64); + ++/** ++ * put_timespec64 - convert timespec64 value to __kernel_timespec format and ++ * copy the latter to userspace ++ * @ts: input &struct timespec64 ++ * @uts: user's &struct __kernel_timespec ++ * ++ * Return: %0 on success or negative errno on error ++ */ + int put_timespec64(const struct timespec64 *ts, + struct __kernel_timespec __user *uts) + { +@@ -839,6 +937,15 @@ static int __put_old_timespec32(const struct timespec64 *ts64, + return copy_to_user(cts, &ts, sizeof(ts)) ? -EFAULT : 0; + } + ++/** ++ * get_old_timespec32 - get user's old-format time value into kernel space ++ * @ts: destination &struct timespec64 ++ * @uts: user's old-format time value (&struct old_timespec32) ++ * ++ * Handles X86_X32_ABI compatibility conversion. ++ * ++ * Return: %0 on success or negative errno on error ++ */ + int get_old_timespec32(struct timespec64 *ts, const void __user *uts) + { + if (COMPAT_USE_64BIT_TIME) +@@ -848,6 +955,16 @@ int get_old_timespec32(struct timespec64 *ts, const void __user *uts) + } + EXPORT_SYMBOL_GPL(get_old_timespec32); + ++/** ++ * put_old_timespec32 - convert timespec64 value to &struct old_timespec32 and ++ * copy the latter to userspace ++ * @ts: input &struct timespec64 ++ * @uts: user's &struct old_timespec32 ++ * ++ * Handles X86_X32_ABI compatibility conversion. ++ * ++ * Return: %0 on success or negative errno on error ++ */ + int put_old_timespec32(const struct timespec64 *ts, void __user *uts) + { + if (COMPAT_USE_64BIT_TIME) +@@ -857,6 +974,13 @@ int put_old_timespec32(const struct timespec64 *ts, void __user *uts) + } + EXPORT_SYMBOL_GPL(put_old_timespec32); + ++/** ++ * get_itimerspec64 - get user's &struct __kernel_itimerspec into kernel space ++ * @it: destination &struct itimerspec64 ++ * @uit: user's &struct __kernel_itimerspec ++ * ++ * Return: %0 on success or negative errno on error ++ */ + int get_itimerspec64(struct itimerspec64 *it, + const struct __kernel_itimerspec __user *uit) + { +@@ -872,6 +996,14 @@ int get_itimerspec64(struct itimerspec64 *it, + } + EXPORT_SYMBOL_GPL(get_itimerspec64); + ++/** ++ * put_itimerspec64 - convert &struct itimerspec64 to __kernel_itimerspec format ++ * and copy the latter to userspace ++ * @it: input &struct itimerspec64 ++ * @uit: user's &struct __kernel_itimerspec ++ * ++ * Return: %0 on success or negative errno on error ++ */ + int put_itimerspec64(const struct itimerspec64 *it, + struct __kernel_itimerspec __user *uit) + { +@@ -887,6 +1019,13 @@ int put_itimerspec64(const struct itimerspec64 *it, + } + EXPORT_SYMBOL_GPL(put_itimerspec64); + ++/** ++ * get_old_itimerspec32 - get user's &struct old_itimerspec32 into kernel space ++ * @its: destination &struct itimerspec64 ++ * @uits: user's &struct old_itimerspec32 ++ * ++ * Return: %0 on success or negative errno on error ++ */ + int get_old_itimerspec32(struct itimerspec64 *its, + const struct old_itimerspec32 __user *uits) + { +@@ -898,6 +1037,14 @@ int get_old_itimerspec32(struct itimerspec64 *its, + } + EXPORT_SYMBOL_GPL(get_old_itimerspec32); + ++/** ++ * put_old_itimerspec32 - convert &struct itimerspec64 to &struct ++ * old_itimerspec32 and copy the latter to userspace ++ * @its: input &struct itimerspec64 ++ * @uits: user's &struct old_itimerspec32 ++ * ++ * Return: %0 on success or negative errno on error ++ */ + int put_old_itimerspec32(const struct itimerspec64 *its, + struct old_itimerspec32 __user *uits) + { +-- +2.51.0 + diff --git a/queue-5.15/time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch b/queue-5.15/time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch new file mode 100644 index 0000000000..855d9b7596 --- /dev/null +++ b/queue-5.15/time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch @@ -0,0 +1,39 @@ +From 90b489eacdab0834bb3dd356b255f7968f9743a1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Mar 2026 21:24:03 -0500 +Subject: time/jiffies: Mark jiffies_64_to_clock_t() notrace + +From: Steven Rostedt + +[ Upstream commit 755a648e78f12574482d4698d877375793867fa1 ] + +The trace_clock_jiffies() function that handles the "uptime" clock for +tracing calls jiffies_64_to_clock_t(). This causes the function tracer to +constantly recurse when the tracing clock is set to "uptime". Mark it +notrace to prevent unnecessary recursion when using the "uptime" clock. + +Fixes: 58d4e21e50ff3 ("tracing: Fix wraparound problems in "uptime" trace clock") +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Thomas Gleixner +Link: https://patch.msgid.link/20260306212403.72270bb2@robin +Signed-off-by: Sasha Levin +--- + kernel/time/time.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/time/time.c b/kernel/time/time.c +index 50390158e9d97..df582f24f0d7b 100644 +--- a/kernel/time/time.c ++++ b/kernel/time/time.c +@@ -702,7 +702,7 @@ EXPORT_SYMBOL(clock_t_to_jiffies); + * + * Return: jiffies_64 value converted to 64-bit "clock_t" (CLOCKS_PER_SEC) + */ +-u64 jiffies_64_to_clock_t(u64 x) ++notrace u64 jiffies_64_to_clock_t(u64 x) + { + #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 + # if HZ < USER_HZ +-- +2.51.0 + diff --git a/queue-6.1/series b/queue-6.1/series index 8bb20fa93b..69b4483ad5 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -216,3 +216,5 @@ usb-class-cdc-wdm-fix-reordering-issue-in-read-code-path.patch usb-renesas_usbhs-fix-use-after-free-in-isr-during-device-removal.patch usb-mdc800-handle-signal-and-read-racing.patch usb-image-mdc800-kill-download-urb-on-timeout.patch +time-add-kernel-doc-in-time.c.patch +time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch diff --git a/queue-6.1/time-add-kernel-doc-in-time.c.patch b/queue-6.1/time-add-kernel-doc-in-time.c.patch new file mode 100644 index 0000000000..a2e122b245 --- /dev/null +++ b/queue-6.1/time-add-kernel-doc-in-time.c.patch @@ -0,0 +1,404 @@ +From 9b44ed67dac711f5e7213dce50865713666a26d8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Jul 2023 22:24:05 -0700 +Subject: time: add kernel-doc in time.c + +From: Randy Dunlap + +[ Upstream commit 67b3f564cb1e769ef8e45835129a4866152fcfdb ] + +Add kernel-doc for all APIs that do not already have it. + +Signed-off-by: Randy Dunlap +Cc: John Stultz +Cc: Thomas Gleixner +Cc: Stephen Boyd +Cc: Jonathan Corbet +Cc: linux-doc@vger.kernel.org +Acked-by: John Stultz +Signed-off-by: Jonathan Corbet +Link: https://lore.kernel.org/r/20230704052405.5089-3-rdunlap@infradead.org +Stable-dep-of: 755a648e78f1 ("time/jiffies: Mark jiffies_64_to_clock_t() notrace") +Signed-off-by: Sasha Levin +--- + kernel/time/time.c | 169 ++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 158 insertions(+), 11 deletions(-) + +diff --git a/kernel/time/time.c b/kernel/time/time.c +index a92c7f3277ad6..be42ace51255c 100644 +--- a/kernel/time/time.c ++++ b/kernel/time/time.c +@@ -365,11 +365,14 @@ SYSCALL_DEFINE1(adjtimex_time32, struct old_timex32 __user *, utp) + } + #endif + +-/* +- * Convert jiffies to milliseconds and back. ++/** ++ * jiffies_to_msecs - Convert jiffies to milliseconds ++ * @j: jiffies value + * + * Avoid unnecessary multiplications/divisions in the +- * two most common HZ cases: ++ * two most common HZ cases. ++ * ++ * Return: milliseconds value + */ + unsigned int jiffies_to_msecs(const unsigned long j) + { +@@ -388,6 +391,12 @@ unsigned int jiffies_to_msecs(const unsigned long j) + } + EXPORT_SYMBOL(jiffies_to_msecs); + ++/** ++ * jiffies_to_usecs - Convert jiffies to microseconds ++ * @j: jiffies value ++ * ++ * Return: microseconds value ++ */ + unsigned int jiffies_to_usecs(const unsigned long j) + { + /* +@@ -408,8 +417,15 @@ unsigned int jiffies_to_usecs(const unsigned long j) + } + EXPORT_SYMBOL(jiffies_to_usecs); + +-/* ++/** + * mktime64 - Converts date to seconds. ++ * @year0: year to convert ++ * @mon0: month to convert ++ * @day: day to convert ++ * @hour: hour to convert ++ * @min: minute to convert ++ * @sec: second to convert ++ * + * Converts Gregorian date to seconds since 1970-01-01 00:00:00. + * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 + * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. +@@ -427,6 +443,8 @@ EXPORT_SYMBOL(jiffies_to_usecs); + * + * An encoding of midnight at the end of the day as 24:00:00 - ie. midnight + * tomorrow - (allowable under ISO 8601) is supported. ++ * ++ * Return: seconds since the epoch time for the given input date + */ + time64_t mktime64(const unsigned int year0, const unsigned int mon0, + const unsigned int day, const unsigned int hour, +@@ -471,8 +489,7 @@ EXPORT_SYMBOL(ns_to_kernel_old_timeval); + * Set seconds and nanoseconds field of a timespec variable and + * normalize to the timespec storage format + * +- * Note: The tv_nsec part is always in the range of +- * 0 <= tv_nsec < NSEC_PER_SEC ++ * Note: The tv_nsec part is always in the range of 0 <= tv_nsec < NSEC_PER_SEC. + * For negative values only the tv_sec field is negative ! + */ + void set_normalized_timespec64(struct timespec64 *ts, time64_t sec, s64 nsec) +@@ -501,7 +518,7 @@ EXPORT_SYMBOL(set_normalized_timespec64); + * ns_to_timespec64 - Convert nanoseconds to timespec64 + * @nsec: the nanoseconds value to be converted + * +- * Returns the timespec64 representation of the nsec parameter. ++ * Return: the timespec64 representation of the nsec parameter. + */ + struct timespec64 ns_to_timespec64(s64 nsec) + { +@@ -548,6 +565,8 @@ EXPORT_SYMBOL(ns_to_timespec64); + * runtime. + * the _msecs_to_jiffies helpers are the HZ dependent conversion + * routines found in include/linux/jiffies.h ++ * ++ * Return: jiffies value + */ + unsigned long __msecs_to_jiffies(const unsigned int m) + { +@@ -560,6 +579,12 @@ unsigned long __msecs_to_jiffies(const unsigned int m) + } + EXPORT_SYMBOL(__msecs_to_jiffies); + ++/** ++ * __usecs_to_jiffies: - convert microseconds to jiffies ++ * @u: time in milliseconds ++ * ++ * Return: jiffies value ++ */ + unsigned long __usecs_to_jiffies(const unsigned int u) + { + if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET)) +@@ -568,7 +593,10 @@ unsigned long __usecs_to_jiffies(const unsigned int u) + } + EXPORT_SYMBOL(__usecs_to_jiffies); + +-/* ++/** ++ * timespec64_to_jiffies - convert a timespec64 value to jiffies ++ * @value: pointer to &struct timespec64 ++ * + * The TICK_NSEC - 1 rounds up the value to the next resolution. Note + * that a remainder subtract here would not do the right thing as the + * resolution values don't fall on second boundaries. I.e. the line: +@@ -582,8 +610,9 @@ EXPORT_SYMBOL(__usecs_to_jiffies); + * + * The >> (NSEC_JIFFIE_SC - SEC_JIFFIE_SC) converts the scaled nsec + * value to a scaled second value. ++ * ++ * Return: jiffies value + */ +- + unsigned long + timespec64_to_jiffies(const struct timespec64 *value) + { +@@ -601,6 +630,11 @@ timespec64_to_jiffies(const struct timespec64 *value) + } + EXPORT_SYMBOL(timespec64_to_jiffies); + ++/** ++ * jiffies_to_timespec64 - convert jiffies value to &struct timespec64 ++ * @jiffies: jiffies value ++ * @value: pointer to &struct timespec64 ++ */ + void + jiffies_to_timespec64(const unsigned long jiffies, struct timespec64 *value) + { +@@ -618,6 +652,13 @@ EXPORT_SYMBOL(jiffies_to_timespec64); + /* + * Convert jiffies/jiffies_64 to clock_t and back. + */ ++ ++/** ++ * jiffies_to_clock_t - Convert jiffies to clock_t ++ * @x: jiffies value ++ * ++ * Return: jiffies converted to clock_t (CLOCKS_PER_SEC) ++ */ + clock_t jiffies_to_clock_t(unsigned long x) + { + #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 +@@ -632,6 +673,12 @@ clock_t jiffies_to_clock_t(unsigned long x) + } + EXPORT_SYMBOL(jiffies_to_clock_t); + ++/** ++ * clock_t_to_jiffies - Convert clock_t to jiffies ++ * @x: clock_t value ++ * ++ * Return: clock_t value converted to jiffies ++ */ + unsigned long clock_t_to_jiffies(unsigned long x) + { + #if (HZ % USER_HZ)==0 +@@ -649,6 +696,12 @@ unsigned long clock_t_to_jiffies(unsigned long x) + } + EXPORT_SYMBOL(clock_t_to_jiffies); + ++/** ++ * jiffies_64_to_clock_t - Convert jiffies_64 to clock_t ++ * @x: jiffies_64 value ++ * ++ * Return: jiffies_64 value converted to 64-bit "clock_t" (CLOCKS_PER_SEC) ++ */ + u64 jiffies_64_to_clock_t(u64 x) + { + #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 +@@ -671,6 +724,12 @@ u64 jiffies_64_to_clock_t(u64 x) + } + EXPORT_SYMBOL(jiffies_64_to_clock_t); + ++/** ++ * nsec_to_clock_t - Convert nsec value to clock_t ++ * @x: nsec value ++ * ++ * Return: nsec value converted to 64-bit "clock_t" (CLOCKS_PER_SEC) ++ */ + u64 nsec_to_clock_t(u64 x) + { + #if (NSEC_PER_SEC % USER_HZ) == 0 +@@ -687,6 +746,12 @@ u64 nsec_to_clock_t(u64 x) + #endif + } + ++/** ++ * jiffies64_to_nsecs - Convert jiffies64 to nanoseconds ++ * @j: jiffies64 value ++ * ++ * Return: nanoseconds value ++ */ + u64 jiffies64_to_nsecs(u64 j) + { + #if !(NSEC_PER_SEC % HZ) +@@ -697,6 +762,12 @@ u64 jiffies64_to_nsecs(u64 j) + } + EXPORT_SYMBOL(jiffies64_to_nsecs); + ++/** ++ * jiffies64_to_msecs - Convert jiffies64 to milliseconds ++ * @j: jiffies64 value ++ * ++ * Return: milliseconds value ++ */ + u64 jiffies64_to_msecs(const u64 j) + { + #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) +@@ -719,6 +790,8 @@ EXPORT_SYMBOL(jiffies64_to_msecs); + * note: + * NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512) + * ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years ++ * ++ * Return: nsecs converted to jiffies64 value + */ + u64 nsecs_to_jiffies64(u64 n) + { +@@ -750,6 +823,8 @@ EXPORT_SYMBOL(nsecs_to_jiffies64); + * note: + * NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512) + * ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years ++ * ++ * Return: nsecs converted to jiffies value + */ + unsigned long nsecs_to_jiffies(u64 n) + { +@@ -757,10 +832,16 @@ unsigned long nsecs_to_jiffies(u64 n) + } + EXPORT_SYMBOL_GPL(nsecs_to_jiffies); + +-/* +- * Add two timespec64 values and do a safety check for overflow. ++/** ++ * timespec64_add_safe - Add two timespec64 values and do a safety check ++ * for overflow. ++ * @lhs: first (left) timespec64 to add ++ * @rhs: second (right) timespec64 to add ++ * + * It's assumed that both values are valid (>= 0). + * And, each timespec64 is in normalized form. ++ * ++ * Return: sum of @lhs + @rhs + */ + struct timespec64 timespec64_add_safe(const struct timespec64 lhs, + const struct timespec64 rhs) +@@ -778,6 +859,15 @@ struct timespec64 timespec64_add_safe(const struct timespec64 lhs, + return res; + } + ++/** ++ * get_timespec64 - get user's time value into kernel space ++ * @ts: destination &struct timespec64 ++ * @uts: user's time value as &struct __kernel_timespec ++ * ++ * Handles compat or 32-bit modes. ++ * ++ * Return: %0 on success or negative errno on error ++ */ + int get_timespec64(struct timespec64 *ts, + const struct __kernel_timespec __user *uts) + { +@@ -801,6 +891,14 @@ int get_timespec64(struct timespec64 *ts, + } + EXPORT_SYMBOL_GPL(get_timespec64); + ++/** ++ * put_timespec64 - convert timespec64 value to __kernel_timespec format and ++ * copy the latter to userspace ++ * @ts: input &struct timespec64 ++ * @uts: user's &struct __kernel_timespec ++ * ++ * Return: %0 on success or negative errno on error ++ */ + int put_timespec64(const struct timespec64 *ts, + struct __kernel_timespec __user *uts) + { +@@ -839,6 +937,15 @@ static int __put_old_timespec32(const struct timespec64 *ts64, + return copy_to_user(cts, &ts, sizeof(ts)) ? -EFAULT : 0; + } + ++/** ++ * get_old_timespec32 - get user's old-format time value into kernel space ++ * @ts: destination &struct timespec64 ++ * @uts: user's old-format time value (&struct old_timespec32) ++ * ++ * Handles X86_X32_ABI compatibility conversion. ++ * ++ * Return: %0 on success or negative errno on error ++ */ + int get_old_timespec32(struct timespec64 *ts, const void __user *uts) + { + if (COMPAT_USE_64BIT_TIME) +@@ -848,6 +955,16 @@ int get_old_timespec32(struct timespec64 *ts, const void __user *uts) + } + EXPORT_SYMBOL_GPL(get_old_timespec32); + ++/** ++ * put_old_timespec32 - convert timespec64 value to &struct old_timespec32 and ++ * copy the latter to userspace ++ * @ts: input &struct timespec64 ++ * @uts: user's &struct old_timespec32 ++ * ++ * Handles X86_X32_ABI compatibility conversion. ++ * ++ * Return: %0 on success or negative errno on error ++ */ + int put_old_timespec32(const struct timespec64 *ts, void __user *uts) + { + if (COMPAT_USE_64BIT_TIME) +@@ -857,6 +974,13 @@ int put_old_timespec32(const struct timespec64 *ts, void __user *uts) + } + EXPORT_SYMBOL_GPL(put_old_timespec32); + ++/** ++ * get_itimerspec64 - get user's &struct __kernel_itimerspec into kernel space ++ * @it: destination &struct itimerspec64 ++ * @uit: user's &struct __kernel_itimerspec ++ * ++ * Return: %0 on success or negative errno on error ++ */ + int get_itimerspec64(struct itimerspec64 *it, + const struct __kernel_itimerspec __user *uit) + { +@@ -872,6 +996,14 @@ int get_itimerspec64(struct itimerspec64 *it, + } + EXPORT_SYMBOL_GPL(get_itimerspec64); + ++/** ++ * put_itimerspec64 - convert &struct itimerspec64 to __kernel_itimerspec format ++ * and copy the latter to userspace ++ * @it: input &struct itimerspec64 ++ * @uit: user's &struct __kernel_itimerspec ++ * ++ * Return: %0 on success or negative errno on error ++ */ + int put_itimerspec64(const struct itimerspec64 *it, + struct __kernel_itimerspec __user *uit) + { +@@ -887,6 +1019,13 @@ int put_itimerspec64(const struct itimerspec64 *it, + } + EXPORT_SYMBOL_GPL(put_itimerspec64); + ++/** ++ * get_old_itimerspec32 - get user's &struct old_itimerspec32 into kernel space ++ * @its: destination &struct itimerspec64 ++ * @uits: user's &struct old_itimerspec32 ++ * ++ * Return: %0 on success or negative errno on error ++ */ + int get_old_itimerspec32(struct itimerspec64 *its, + const struct old_itimerspec32 __user *uits) + { +@@ -898,6 +1037,14 @@ int get_old_itimerspec32(struct itimerspec64 *its, + } + EXPORT_SYMBOL_GPL(get_old_itimerspec32); + ++/** ++ * put_old_itimerspec32 - convert &struct itimerspec64 to &struct ++ * old_itimerspec32 and copy the latter to userspace ++ * @its: input &struct itimerspec64 ++ * @uits: user's &struct old_itimerspec32 ++ * ++ * Return: %0 on success or negative errno on error ++ */ + int put_old_itimerspec32(const struct itimerspec64 *its, + struct old_itimerspec32 __user *uits) + { +-- +2.51.0 + diff --git a/queue-6.1/time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch b/queue-6.1/time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch new file mode 100644 index 0000000000..98fc140a32 --- /dev/null +++ b/queue-6.1/time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch @@ -0,0 +1,39 @@ +From 83db8f72edc589ac56fb6cf6766cf9b16ec7af6d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Mar 2026 21:24:03 -0500 +Subject: time/jiffies: Mark jiffies_64_to_clock_t() notrace + +From: Steven Rostedt + +[ Upstream commit 755a648e78f12574482d4698d877375793867fa1 ] + +The trace_clock_jiffies() function that handles the "uptime" clock for +tracing calls jiffies_64_to_clock_t(). This causes the function tracer to +constantly recurse when the tracing clock is set to "uptime". Mark it +notrace to prevent unnecessary recursion when using the "uptime" clock. + +Fixes: 58d4e21e50ff3 ("tracing: Fix wraparound problems in "uptime" trace clock") +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Thomas Gleixner +Link: https://patch.msgid.link/20260306212403.72270bb2@robin +Signed-off-by: Sasha Levin +--- + kernel/time/time.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/time/time.c b/kernel/time/time.c +index be42ace51255c..170f1f8a0046c 100644 +--- a/kernel/time/time.c ++++ b/kernel/time/time.c +@@ -702,7 +702,7 @@ EXPORT_SYMBOL(clock_t_to_jiffies); + * + * Return: jiffies_64 value converted to 64-bit "clock_t" (CLOCKS_PER_SEC) + */ +-u64 jiffies_64_to_clock_t(u64 x) ++notrace u64 jiffies_64_to_clock_t(u64 x) + { + #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 + # if HZ < USER_HZ +-- +2.51.0 + diff --git a/queue-6.12/fix-cc_has_asm_goto_output-on-non-x86-architectures.patch b/queue-6.12/fix-cc_has_asm_goto_output-on-non-x86-architectures.patch new file mode 100644 index 0000000000..4da9d65c0e --- /dev/null +++ b/queue-6.12/fix-cc_has_asm_goto_output-on-non-x86-architectures.patch @@ -0,0 +1,50 @@ +From 3938f1902c2ae4fb37d304152b5902f8ec74014e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Sep 2025 08:54:12 -0700 +Subject: Fix CC_HAS_ASM_GOTO_OUTPUT on non-x86 architectures + +From: Linus Torvalds + +[ Upstream commit fde0ab43b9a30d08817adc5402b69fec83a61cb8 ] + +There's a silly problem with the CC_HAS_ASM_GOTO_OUTPUT test: even with +a working compiler it will fail on some architectures simply because it +uses the mnemonic "jmp" for testing the inline asm. + +And as reported by Geert, not all architectures use that mnemonic, so +the test fails spuriously on such platforms (including arm and riscv, +but also several other architectures). + +This issue avoided any obvious test failures because the build still +works thanks to falling back on the old non-asm-goto code, which just +generates worse code. + +Just use an empty asm statement instead. + +Reported-and-tested-by: Geert Uytterhoeven +Suggested-by: Peter Zijlstra +Fixes: e2ffa15b9baa ("kbuild: Disable CC_HAS_ASM_GOTO_OUTPUT on clang < 17") +Cc: Nathan Chancellor +Cc: Thomas Gleixner +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + init/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/init/Kconfig b/init/Kconfig +index 1a39330252c59..f4b91b1857bf8 100644 +--- a/init/Kconfig ++++ b/init/Kconfig +@@ -107,7 +107,7 @@ config CC_HAS_ASM_GOTO_OUTPUT + # Detect basic support + depends on $(success,echo 'int foo(int x) { asm goto ("": "=r"(x) ::: bar); return x; bar: return 0; }' | $(CC) -x c - -c -o /dev/null) + # Detect clang (< v17) scoped label issues +- depends on $(success,echo 'void b(void **);void* c(void);int f(void){{asm goto("jmp %l0"::::l0);return 0;l0:return 1;}void *x __attribute__((cleanup(b)))=c();{asm goto("jmp %l0"::::l1);return 2;l1:return 3;}}' | $(CC) -x c - -c -o /dev/null) ++ depends on $(success,echo 'void b(void **);void* c(void);int f(void){{asm goto(""::::l0);return 0;l0:return 1;}void *x __attribute__((cleanup(b)))=c();{asm goto(""::::l1);return 2;l1:return 3;}}' | $(CC) -x c - -c -o /dev/null) + + config CC_HAS_ASM_GOTO_TIED_OUTPUT + depends on CC_HAS_ASM_GOTO_OUTPUT +-- +2.51.0 + diff --git a/queue-6.12/i3c-dw-i3c-master-set-sir_reject-in-dat-on-device-at.patch b/queue-6.12/i3c-dw-i3c-master-set-sir_reject-in-dat-on-device-at.patch new file mode 100644 index 0000000000..9b33c3032e --- /dev/null +++ b/queue-6.12/i3c-dw-i3c-master-set-sir_reject-in-dat-on-device-at.patch @@ -0,0 +1,57 @@ +From d450c1368162d802a8c3fda3b939600d8275c1ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 14:00:48 +0800 +Subject: i3c: dw-i3c-master: Set SIR_REJECT in DAT on device attach and + reattach + +From: Adrian Ng Ho Yin + +[ Upstream commit f311a05784634febd299f03476b80f3f18489767 ] + +The DesignWare I3C master controller ACKs IBIs as soon as a valid +Device Address Table (DAT) entry is present. This can create a race +between device attachment (after DAA) and the point where the client +driver enables IBIs via i3c_device_enable_ibi(). + +Set DEV_ADDR_TABLE_SIR_REJECT in the DAT entry during +attach_i3c_dev() and reattach_i3c_dev() so that IBIs are rejected +by default. The bit is managed thereafter by the existing +dw_i3c_master_set_sir_enabled() function, which clears it in +enable_ibi() after ENEC is issued, and restores it in disable_ibi() +after DISEC. + +Fixes: 1dd728f5d4d4 ("i3c: master: Add driver for Synopsys DesignWare IP") +Signed-off-by: Adrian Ng Ho Yin +Reviewed-by: Frank Li +Link: https://patch.msgid.link/53f5b8cbdd8af789ec38b95b02873f32f9182dd6.1770962368.git.adrianhoyin.ng@altera.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master/dw-i3c-master.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c +index 4c019c746f231..e0853a6bde0a4 100644 +--- a/drivers/i3c/master/dw-i3c-master.c ++++ b/drivers/i3c/master/dw-i3c-master.c +@@ -1013,7 +1013,7 @@ static int dw_i3c_master_reattach_i3c_dev(struct i3c_dev_desc *dev, + master->free_pos &= ~BIT(pos); + } + +- writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(dev->info.dyn_addr), ++ writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(dev->info.dyn_addr) | DEV_ADDR_TABLE_SIR_REJECT, + master->regs + + DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); + +@@ -1042,7 +1042,7 @@ static int dw_i3c_master_attach_i3c_dev(struct i3c_dev_desc *dev) + master->free_pos &= ~BIT(pos); + i3c_dev_set_master_data(dev, data); + +- writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr), ++ writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr) | DEV_ADDR_TABLE_SIR_REJECT, + master->regs + + DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); + +-- +2.51.0 + diff --git a/queue-6.12/kbuild-disable-cc_has_asm_goto_output-on-clang-17.patch b/queue-6.12/kbuild-disable-cc_has_asm_goto_output-on-clang-17.patch new file mode 100644 index 0000000000..c25b16519e --- /dev/null +++ b/queue-6.12/kbuild-disable-cc_has_asm_goto_output-on-clang-17.patch @@ -0,0 +1,100 @@ +From 5246feb2235fdc49f04bc2309ca3ca92b25bf7fc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Sep 2025 15:21:51 +0200 +Subject: kbuild: Disable CC_HAS_ASM_GOTO_OUTPUT on clang < 17 + +From: Thomas Gleixner + +[ Upstream commit e2ffa15b9baa447e444d654ffd47123ba6443ae4 ] + +clang < 17 fails to use scope local labels with CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y: + + { + __label__ local_lbl; + ... + unsafe_get_user(uval, uaddr, local_lbl); + ... + return 0; + local_lbl: + return -EFAULT; + } + +when two such scopes exist in the same function: + + error: cannot jump from this asm goto statement to one of its possible targets + +There are other failure scenarios. Shuffling code around slightly makes it +worse and fail even with one instance. + +That issue prevents using local labels for a cleanup based user access +mechanism. + +After failed attempts to provide a simple enough test case for the 'depends +on' test in Kconfig, the initial cure was to mark ASM goto broken on clang +versions < 17 to get this road block out of the way. + +But Nathan pointed out that this is a known clang issue and indeed affects +clang < version 17 in combination with cleanup(). It's not even required to +use local labels for that. + +The clang issue tracker has a small enough test case, which can be used as +a test in the 'depends on' section of CC_HAS_ASM_GOTO_OUTPUT: + +void bar(void **); +void* baz(void); + +int foo (void) { + { + asm goto("jmp %l0"::::l0); + return 0; +l0: + return 1; + } + void *x __attribute__((cleanup(bar))) = baz(); + { + asm goto("jmp %l0"::::l1); + return 42; +l1: + return 0xff; + } +} + +Add another dependency to config CC_HAS_ASM_GOTO_OUTPUT for it and use the +clang issue tracker test case for detection by condensing it to obfuscated +C-code contest format. This reliably catches the problem on clang < 17 and +did not show any issues on the non broken GCC versions. + +That test might be sufficient to catch all issues and therefore could +replace the existing test, but keeping that around does no harm either. + +Thanks to Nathan for pointing to the relevant clang issue! + +Suggested-by: Nathan Chancellor +Signed-off-by: Thomas Gleixner +Cc: Nathan Chancellor +Reviewed-by: Nathan Chancellor +Link: https://github.com/ClangBuiltLinux/linux/issues/1886 +Link: https://github.com/llvm/llvm-project/commit/f023f5cdb2e6c19026f04a15b5a935c041835d14 +Signed-off-by: Sasha Levin +--- + init/Kconfig | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/init/Kconfig b/init/Kconfig +index 219ccdb0af732..1a39330252c59 100644 +--- a/init/Kconfig ++++ b/init/Kconfig +@@ -104,7 +104,10 @@ config GCC_ASM_GOTO_OUTPUT_BROKEN + config CC_HAS_ASM_GOTO_OUTPUT + def_bool y + depends on !GCC_ASM_GOTO_OUTPUT_BROKEN ++ # Detect basic support + depends on $(success,echo 'int foo(int x) { asm goto ("": "=r"(x) ::: bar); return x; bar: return 0; }' | $(CC) -x c - -c -o /dev/null) ++ # Detect clang (< v17) scoped label issues ++ depends on $(success,echo 'void b(void **);void* c(void);int f(void){{asm goto("jmp %l0"::::l0);return 0;l0:return 1;}void *x __attribute__((cleanup(b)))=c();{asm goto("jmp %l0"::::l1);return 2;l1:return 3;}}' | $(CC) -x c - -c -o /dev/null) + + config CC_HAS_ASM_GOTO_TIED_OUTPUT + depends on CC_HAS_ASM_GOTO_OUTPUT +-- +2.51.0 + diff --git a/queue-6.12/scsi-hisi_sas-add-time-interval-between-two-h2d-fis-.patch b/queue-6.12/scsi-hisi_sas-add-time-interval-between-two-h2d-fis-.patch new file mode 100644 index 0000000000..a58b079c52 --- /dev/null +++ b/queue-6.12/scsi-hisi_sas-add-time-interval-between-two-h2d-fis-.patch @@ -0,0 +1,38 @@ +From 7ecd0f88688ba719967c2a0fbfbc8b0eee993ff6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Oct 2024 10:18:19 +0800 +Subject: scsi: hisi_sas: Add time interval between two H2D FIS following soft + reset spec + +From: Xingui Yang + +[ Upstream commit 3c62791322e42d1afd65acfdb5b3a371bde21ede ] + +Spec says at least 5us between two H2D FIS when do soft reset, but be +generous and sleep for about 1ms. + +Signed-off-by: Xingui Yang +Link: https://lore.kernel.org/r/20241008021822.2617339-11-liyihang9@huawei.com +Reviewed-by: Yihang Li +Signed-off-by: Martin K. Petersen +Stable-dep-of: 8ddc0c269165 ("scsi: hisi_sas: Fix NULL pointer exception during user_scan()") +Signed-off-by: Sasha Levin +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index d9500b7306905..43d2ca4c6605f 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1341,6 +1341,7 @@ static int hisi_sas_softreset_ata_disk(struct domain_device *device) + } + + if (rc == TMF_RESP_FUNC_COMPLETE) { ++ usleep_range(900, 1000); + ata_for_each_link(link, ap, EDGE) { + int pmp = sata_srst_pmp(link); + +-- +2.51.0 + diff --git a/queue-6.12/scsi-hisi_sas-fix-null-pointer-exception-during-user.patch b/queue-6.12/scsi-hisi_sas-fix-null-pointer-exception-during-user.patch new file mode 100644 index 0000000000..e05bf8ae25 --- /dev/null +++ b/queue-6.12/scsi-hisi_sas-fix-null-pointer-exception-during-user.patch @@ -0,0 +1,113 @@ +From 259eb44cacf8a15d3a3c2a0838ddc93b2212d42e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Mar 2026 14:40:39 +0800 +Subject: scsi: hisi_sas: Fix NULL pointer exception during user_scan() + +From: Xingui Yang + +[ Upstream commit 8ddc0c26916574395447ebf4cff684314f6873a9 ] + +user_scan() invokes updated sas_user_scan() for channel 0, and if +successful, iteratively scans remaining channels (1 to shost->max_channel) +via scsi_scan_host_selected() in commit 37c4e72b0651 ("scsi: Fix +sas_user_scan() to handle wildcard and multi-channel scans"). However, +hisi_sas supports only one channel, and the current value of max_channel is +1. sas_user_scan() for channel 1 will trigger the following NULL pointer +exception: + +[ 441.554662] Unable to handle kernel NULL pointer dereference at virtual address 00000000000008b0 +[ 441.554699] Mem abort info: +[ 441.554710] ESR = 0x0000000096000004 +[ 441.554718] EC = 0x25: DABT (current EL), IL = 32 bits +[ 441.554723] SET = 0, FnV = 0 +[ 441.554726] EA = 0, S1PTW = 0 +[ 441.554730] FSC = 0x04: level 0 translation fault +[ 441.554735] Data abort info: +[ 441.554737] ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000 +[ 441.554742] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 +[ 441.554747] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 +[ 441.554752] user pgtable: 4k pages, 48-bit VAs, pgdp=00000828377a6000 +[ 441.554757] [00000000000008b0] pgd=0000000000000000, p4d=0000000000000000 +[ 441.554769] Internal error: Oops: 0000000096000004 [#1] SMP +[ 441.629589] Modules linked in: arm_spe_pmu arm_smmuv3_pmu tpm_tis_spi hisi_uncore_sllc_pmu hisi_uncore_pa_pmu hisi_uncore_l3c_pmu hisi_uncore_hha_pmu hisi_uncore_ddrc_pmu hisi_uncore_cpa_pmu hns3_pmu hisi_ptt hisi_pcie_pmu tpm_tis_core spidev spi_hisi_sfc_v3xx hisi_uncore_pmu spi_dw_mmio fuse hclge hclge_common hisi_sec2 hisi_hpre hisi_zip hisi_qm hns3 hisi_sas_v3_hw sm3_ce sbsa_gwdt hnae3 hisi_sas_main uacce hisi_dma i2c_hisi dm_mirror dm_region_hash dm_log dm_mod +[ 441.670819] CPU: 46 UID: 0 PID: 6994 Comm: bash Kdump: loaded Not tainted 7.0.0-rc2+ #84 PREEMPT +[ 441.691327] pstate: 81400009 (Nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--) +[ 441.698277] pc : sas_find_dev_by_rphy+0x44/0x118 +[ 441.702896] lr : sas_find_dev_by_rphy+0x3c/0x118 +[ 441.707502] sp : ffff80009abbba40 +[ 441.710805] x29: ffff80009abbba40 x28: ffff082819a40008 x27: ffff082810c37c08 +[ 441.717930] x26: ffff082810c37c28 x25: ffff082819a40290 x24: ffff082810c37c00 +[ 441.725054] x23: 0000000000000000 x22: 0000000000000001 x21: ffff082819a40000 +[ 441.732179] x20: ffff082819a40290 x19: 0000000000000000 x18: 0000000000000020 +[ 441.739304] x17: 0000000000000000 x16: ffffb5dad6bda690 x15: 00000000ffffffff +[ 441.746428] x14: ffff082814c3b26c x13: 00000000ffffffff x12: ffff082814c3b26a +[ 441.753553] x11: 00000000000000c0 x10: 000000000000003a x9 : ffffb5dad5ea94f4 +[ 441.760678] x8 : 000000000000003a x7 : ffff80009abbbab0 x6 : 0000000000000030 +[ 441.767802] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000 +[ 441.774926] x2 : ffff08280f35a300 x1 : ffffb5dad7127180 x0 : 0000000000000000 +[ 441.782053] Call trace: +[ 441.784488] sas_find_dev_by_rphy+0x44/0x118 (P) +[ 441.789095] sas_target_alloc+0x24/0xb0 +[ 441.792920] scsi_alloc_target+0x290/0x330 +[ 441.797010] __scsi_scan_target+0x88/0x258 +[ 441.801096] scsi_scan_channel+0x74/0xb8 +[ 441.805008] scsi_scan_host_selected+0x170/0x188 +[ 441.809615] sas_user_scan+0xfc/0x148 +[ 441.813267] store_scan+0x10c/0x180 +[ 441.816743] dev_attr_store+0x20/0x40 +[ 441.820398] sysfs_kf_write+0x84/0xa8 +[ 441.824054] kernfs_fop_write_iter+0x130/0x1c8 +[ 441.828487] vfs_write+0x2c0/0x370 +[ 441.831880] ksys_write+0x74/0x118 +[ 441.835271] __arm64_sys_write+0x24/0x38 +[ 441.839182] invoke_syscall+0x50/0x120 +[ 441.842919] el0_svc_common.constprop.0+0xc8/0xf0 +[ 441.847611] do_el0_svc+0x24/0x38 +[ 441.850913] el0_svc+0x38/0x158 +[ 441.854043] el0t_64_sync_handler+0xa0/0xe8 +[ 441.858214] el0t_64_sync+0x1ac/0x1b0 +[ 441.861865] Code: aa1303e0 97ff70a8 34ffff80 d10a4273 (f9445a75) +[ 441.867946] ---[ end trace 0000000000000000 ]--- + +Therefore, set max_channel to 0. + +Fixes: e21fe3a52692 ("scsi: hisi_sas: add initialisation for v3 pci-based controller") +Signed-off-by: Xingui Yang +Signed-off-by: Yihang Li +Link: https://patch.msgid.link/20260305064039.4096775-1-liyihang9@huawei.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 2 +- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 71d12b94ba5be..236e23620f21d 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -2544,7 +2544,7 @@ int hisi_sas_probe(struct platform_device *pdev, + shost->transportt = hisi_sas_stt; + shost->max_id = HISI_SAS_MAX_DEVICES; + shost->max_lun = ~0; +- shost->max_channel = 1; ++ shost->max_channel = 0; + shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN; + if (hisi_hba->hw->slot_index_alloc) { + shost->can_queue = HISI_SAS_MAX_COMMANDS; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index cf0df9b405b24..e958b588d078f 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -4959,7 +4959,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) + shost->transportt = hisi_sas_stt; + shost->max_id = HISI_SAS_MAX_DEVICES; + shost->max_lun = ~0; +- shost->max_channel = 1; ++ shost->max_channel = 0; + shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN; + shost->can_queue = HISI_SAS_UNRESERVED_IPTT; + shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT; +-- +2.51.0 + diff --git a/queue-6.12/scsi-hisi_sas-use-macro-instead-of-magic-number.patch b/queue-6.12/scsi-hisi_sas-use-macro-instead-of-magic-number.patch new file mode 100644 index 0000000000..0f2b64598b --- /dev/null +++ b/queue-6.12/scsi-hisi_sas-use-macro-instead-of-magic-number.patch @@ -0,0 +1,1048 @@ +From 020bbd183a44da003ef27d8902484b0854a92ae3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Apr 2025 16:08:42 +0800 +Subject: scsi: hisi_sas: Use macro instead of magic number + +From: Yihang Li + +[ Upstream commit 4ca7fe99fc8485fcd04b367f37dc7a48f1355419 ] + +The hisi_sas driver has a large number of magic numbers which makes for +unfriendly code reading. Use macro definitions instead. + +Signed-off-by: Yihang Li +Link: https://lore.kernel.org/r/20250414080845.1220997-2-liyihang9@huawei.com +Signed-off-by: Martin K. Petersen +Stable-dep-of: 8ddc0c269165 ("scsi: hisi_sas: Fix NULL pointer exception during user_scan()") +Signed-off-by: Sasha Levin +--- + drivers/scsi/hisi_sas/hisi_sas.h | 43 +++-- + drivers/scsi/hisi_sas/hisi_sas_main.c | 41 +++-- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 244 ++++++++++++++++--------- + 3 files changed, 213 insertions(+), 115 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 010479a354eee..3311f9b9eca6a 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -46,6 +46,13 @@ + #define HISI_SAS_IOST_ITCT_CACHE_DW_SZ 10 + #define HISI_SAS_FIFO_DATA_DW_SIZE 32 + ++#define HISI_SAS_REG_MEM_SIZE 4 ++#define HISI_SAS_MAX_CDB_LEN 16 ++#define HISI_SAS_BLK_QUEUE_DEPTH 64 ++ ++#define BYTE_TO_DW 4 ++#define BYTE_TO_DDW 8 ++ + #define HISI_SAS_STATUS_BUF_SZ (sizeof(struct hisi_sas_status_buffer)) + #define HISI_SAS_COMMAND_TABLE_SZ (sizeof(union hisi_sas_command_table)) + +@@ -92,6 +99,8 @@ + + #define HISI_SAS_WAIT_PHYUP_TIMEOUT (30 * HZ) + #define HISI_SAS_CLEAR_ITCT_TIMEOUT (20 * HZ) ++#define HISI_SAS_DELAY_FOR_PHY_DISABLE 100 ++#define NAME_BUF_SIZE 256 + + struct hisi_hba; + +@@ -167,6 +176,8 @@ struct hisi_sas_debugfs_fifo { + u32 rd_data[HISI_SAS_FIFO_DATA_DW_SIZE]; + }; + ++#define FRAME_RCVD_BUF 32 ++#define SAS_PHY_RESV_SIZE 2 + struct hisi_sas_phy { + struct work_struct works[HISI_PHYES_NUM]; + struct hisi_hba *hisi_hba; +@@ -178,10 +189,10 @@ struct hisi_sas_phy { + spinlock_t lock; + u64 port_id; /* from hw */ + u64 frame_rcvd_size; +- u8 frame_rcvd[32]; ++ u8 frame_rcvd[FRAME_RCVD_BUF]; + u8 phy_attached; + u8 in_reset; +- u8 reserved[2]; ++ u8 reserved[SAS_PHY_RESV_SIZE]; + u32 phy_type; + u32 code_violation_err_count; + enum sas_linkrate minimum_linkrate; +@@ -348,6 +359,7 @@ struct hisi_sas_hw { + }; + + #define HISI_SAS_MAX_DEBUGFS_DUMP (50) ++#define HISI_SAS_DEFAULT_DEBUGFS_DUMP 1 + + struct hisi_sas_debugfs_cq { + struct hisi_sas_cq *cq; +@@ -527,12 +539,13 @@ struct hisi_sas_cmd_hdr { + __le64 dif_prd_table_addr; + }; + ++#define ITCT_RESV_DDW 12 + struct hisi_sas_itct { + __le64 qw0; + __le64 sas_addr; + __le64 qw2; + __le64 qw3; +- __le64 qw4_15[12]; ++ __le64 qw4_15[ITCT_RESV_DDW]; + }; + + struct hisi_sas_iost { +@@ -542,22 +555,26 @@ struct hisi_sas_iost { + __le64 qw3; + }; + ++#define ERROR_RECORD_BUF_DW 4 + struct hisi_sas_err_record { +- u32 data[4]; ++ u32 data[ERROR_RECORD_BUF_DW]; + }; + ++#define FIS_RESV_DW 3 + struct hisi_sas_initial_fis { + struct hisi_sas_err_record err_record; + struct dev_to_host_fis fis; +- u32 rsvd[3]; ++ u32 rsvd[FIS_RESV_DW]; + }; + ++#define BREAKPOINT_DATA_SIZE 128 + struct hisi_sas_breakpoint { +- u8 data[128]; ++ u8 data[BREAKPOINT_DATA_SIZE]; + }; + ++#define BREAKPOINT_TAG_NUM 32 + struct hisi_sas_sata_breakpoint { +- struct hisi_sas_breakpoint tag[32]; ++ struct hisi_sas_breakpoint tag[BREAKPOINT_TAG_NUM]; + }; + + struct hisi_sas_sge { +@@ -568,13 +585,15 @@ struct hisi_sas_sge { + __le32 data_off; + }; + ++#define SMP_CMD_TABLE_SIZE 44 + struct hisi_sas_command_table_smp { +- u8 bytes[44]; ++ u8 bytes[SMP_CMD_TABLE_SIZE]; + }; + ++#define DUMMY_BUF_SIZE 12 + struct hisi_sas_command_table_stp { + struct host_to_dev_fis command_fis; +- u8 dummy[12]; ++ u8 dummy[DUMMY_BUF_SIZE]; + u8 atapi_cdb[ATAPI_CDB_LEN]; + }; + +@@ -588,12 +607,13 @@ struct hisi_sas_sge_dif_page { + struct hisi_sas_sge sge[HISI_SAS_SGE_DIF_PAGE_CNT]; + } __aligned(16); + ++#define PROT_BUF_SIZE 7 + struct hisi_sas_command_table_ssp { + struct ssp_frame_hdr hdr; + union { + struct { + struct ssp_command_iu task; +- u32 prot[7]; ++ u32 prot[PROT_BUF_SIZE]; + }; + struct ssp_tmf_iu ssp_task; + struct xfer_rdy_iu xfer_rdy; +@@ -607,9 +627,10 @@ union hisi_sas_command_table { + struct hisi_sas_command_table_stp stp; + } __aligned(16); + ++#define IU_BUF_SIZE 1024 + struct hisi_sas_status_buffer { + struct hisi_sas_err_record err; +- u8 iu[1024]; ++ u8 iu[IU_BUF_SIZE]; + } __aligned(16); + + struct hisi_sas_slot_buf_table { +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 43d2ca4c6605f..71d12b94ba5be 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -7,6 +7,16 @@ + #include "hisi_sas.h" + #define DRV_NAME "hisi_sas" + ++#define LINK_RATE_BIT_MASK 2 ++#define FIS_BUF_SIZE 20 ++#define WAIT_CMD_COMPLETE_DELAY 100 ++#define WAIT_CMD_COMPLETE_TMROUT 5000 ++#define DELAY_FOR_LINK_READY 2000 ++#define BLK_CNT_OPTIMIZE_MARK 64 ++#define HZ_TO_MHZ 1000000 ++#define DELAY_FOR_SOFTRESET_MAX 1000 ++#define DELAY_FOR_SOFTRESET_MIN 900 ++ + #define DEV_IS_GONE(dev) \ + ((!dev) || (dev->dev_type == SAS_PHY_UNUSED)) + +@@ -127,7 +137,7 @@ u8 hisi_sas_get_prog_phy_linkrate_mask(enum sas_linkrate max) + + max -= SAS_LINK_RATE_1_5_GBPS; + for (i = 0; i <= max; i++) +- rate |= 1 << (i * 2); ++ rate |= 1 << (i * LINK_RATE_BIT_MASK); + return rate; + } + EXPORT_SYMBOL_GPL(hisi_sas_get_prog_phy_linkrate_mask); +@@ -877,7 +887,7 @@ int hisi_sas_device_configure(struct scsi_device *sdev, + if (ret) + return ret; + if (!dev_is_sata(dev)) +- sas_change_queue_depth(sdev, 64); ++ sas_change_queue_depth(sdev, HISI_SAS_BLK_QUEUE_DEPTH); + + return 0; + } +@@ -1239,7 +1249,7 @@ static int hisi_sas_phy_set_linkrate(struct hisi_hba *hisi_hba, int phy_no, + sas_phy->phy->minimum_linkrate = min; + + hisi_sas_phy_enable(hisi_hba, phy_no, 0); +- msleep(100); ++ msleep(HISI_SAS_DELAY_FOR_PHY_DISABLE); + hisi_hba->hw->phy_set_linkrate(hisi_hba, phy_no, &_r); + hisi_sas_phy_enable(hisi_hba, phy_no, 1); + +@@ -1269,7 +1279,7 @@ static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func, + + case PHY_FUNC_LINK_RESET: + hisi_sas_phy_enable(hisi_hba, phy_no, 0); +- msleep(100); ++ msleep(HISI_SAS_DELAY_FOR_PHY_DISABLE); + hisi_sas_phy_enable(hisi_hba, phy_no, 1); + break; + +@@ -1324,7 +1334,7 @@ static void hisi_sas_fill_ata_reset_cmd(struct ata_device *dev, + + static int hisi_sas_softreset_ata_disk(struct domain_device *device) + { +- u8 fis[20] = {0}; ++ u8 fis[FIS_BUF_SIZE] = {0}; + struct ata_port *ap = device->sata_dev.ap; + struct ata_link *link; + int rc = TMF_RESP_FUNC_FAILED; +@@ -1341,7 +1351,7 @@ static int hisi_sas_softreset_ata_disk(struct domain_device *device) + } + + if (rc == TMF_RESP_FUNC_COMPLETE) { +- usleep_range(900, 1000); ++ usleep_range(DELAY_FOR_SOFTRESET_MIN, DELAY_FOR_SOFTRESET_MAX); + ata_for_each_link(link, ap, EDGE) { + int pmp = sata_srst_pmp(link); + +@@ -1460,7 +1470,7 @@ static void hisi_sas_send_ata_reset_each_phy(struct hisi_hba *hisi_hba, + struct device *dev = hisi_hba->dev; + int rc = TMF_RESP_FUNC_FAILED; + struct ata_link *link; +- u8 fis[20] = {0}; ++ u8 fis[FIS_BUF_SIZE] = {0}; + int i; + + for (i = 0; i < hisi_hba->n_phy; i++) { +@@ -1527,7 +1537,9 @@ void hisi_sas_controller_reset_prepare(struct hisi_hba *hisi_hba) + hisi_hba->phy_state = hisi_hba->hw->get_phys_state(hisi_hba); + + scsi_block_requests(shost); +- hisi_hba->hw->wait_cmds_complete_timeout(hisi_hba, 100, 5000); ++ hisi_hba->hw->wait_cmds_complete_timeout(hisi_hba, ++ WAIT_CMD_COMPLETE_DELAY, ++ WAIT_CMD_COMPLETE_TMROUT); + + /* + * hisi_hba->timer is only used for v1/v2 hw, and check hw->sht +@@ -1828,7 +1840,7 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device) + rc = ata_wait_after_reset(link, jiffies + HISI_SAS_WAIT_PHYUP_TIMEOUT, + smp_ata_check_ready_type); + } else { +- msleep(2000); ++ msleep(DELAY_FOR_LINK_READY); + } + + return rc; +@@ -2243,12 +2255,14 @@ int hisi_sas_alloc(struct hisi_hba *hisi_hba) + goto err_out; + + /* roundup to avoid overly large block size */ +- max_command_entries_ru = roundup(max_command_entries, 64); ++ max_command_entries_ru = roundup(max_command_entries, ++ BLK_CNT_OPTIMIZE_MARK); + if (hisi_hba->prot_mask & HISI_SAS_DIX_PROT_MASK) + sz_slot_buf_ru = sizeof(struct hisi_sas_slot_dif_buf_table); + else + sz_slot_buf_ru = sizeof(struct hisi_sas_slot_buf_table); +- sz_slot_buf_ru = roundup(sz_slot_buf_ru, 64); ++ ++ sz_slot_buf_ru = roundup(sz_slot_buf_ru, BLK_CNT_OPTIMIZE_MARK); + s = max(lcm(max_command_entries_ru, sz_slot_buf_ru), PAGE_SIZE); + blk_cnt = (max_command_entries_ru * sz_slot_buf_ru) / s; + slots_per_blk = s / sz_slot_buf_ru; +@@ -2413,7 +2427,8 @@ int hisi_sas_get_fw_info(struct hisi_hba *hisi_hba) + if (IS_ERR(refclk)) + dev_dbg(dev, "no ref clk property\n"); + else +- hisi_hba->refclk_frequency_mhz = clk_get_rate(refclk) / 1000000; ++ hisi_hba->refclk_frequency_mhz = clk_get_rate(refclk) / ++ HZ_TO_MHZ; + + if (device_property_read_u32(dev, "phy-count", &hisi_hba->n_phy)) { + dev_err(dev, "could not get property phy-count\n"); +@@ -2530,7 +2545,7 @@ int hisi_sas_probe(struct platform_device *pdev, + shost->max_id = HISI_SAS_MAX_DEVICES; + shost->max_lun = ~0; + shost->max_channel = 1; +- shost->max_cmd_len = 16; ++ shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN; + if (hisi_hba->hw->slot_index_alloc) { + shost->can_queue = HISI_SAS_MAX_COMMANDS; + shost->cmd_per_lun = HISI_SAS_MAX_COMMANDS; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 2b04556681a1a..cf0df9b405b24 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -465,6 +465,12 @@ + #define ITCT_HDR_RTOLT_OFF 48 + #define ITCT_HDR_RTOLT_MSK (0xffffULL << ITCT_HDR_RTOLT_OFF) + ++/*debugfs*/ ++#define TWO_PARA_PER_LINE 2 ++#define FOUR_PARA_PER_LINE 4 ++#define DUMP_BUF_SIZE 8 ++#define BIST_BUF_SIZE 16 ++ + struct hisi_sas_protect_iu_v3_hw { + u32 dw0; + u32 lbrtcv; +@@ -535,6 +541,43 @@ struct hisi_sas_err_record_v3 { + + #define BASE_VECTORS_V3_HW 16 + #define MIN_AFFINE_VECTORS_V3_HW (BASE_VECTORS_V3_HW + 1) ++#define IRQ_PHY_UP_DOWN_INDEX 1 ++#define IRQ_CHL_INDEX 2 ++#define IRQ_AXI_INDEX 11 ++ ++#define DELAY_FOR_RESET_HW 100 ++#define HDR_SG_MOD 0x2 ++#define LUN_SIZE 8 ++#define ATTR_PRIO_REGION 9 ++#define CDB_REGION 12 ++#define PRIO_OFF 3 ++#define TMF_REGION 10 ++#define TAG_MSB 12 ++#define TAG_LSB 13 ++#define SMP_FRAME_TYPE 2 ++#define SMP_CRC_SIZE 4 ++#define HDR_TAG_OFF 3 ++#define HOST_NO_OFF 6 ++#define PHY_NO_OFF 7 ++#define IDENTIFY_REG_READ 6 ++#define LINK_RESET_TIMEOUT_OFF 4 ++#define DECIMALISM_FLAG 10 ++#define WAIT_RETRY 100 ++#define WAIT_TMROUT 5000 ++ ++#define ID_DWORD0_INDEX 0 ++#define ID_DWORD1_INDEX 1 ++#define ID_DWORD2_INDEX 2 ++#define ID_DWORD3_INDEX 3 ++#define ID_DWORD4_INDEX 4 ++#define ID_DWORD5_INDEX 5 ++#define TICKS_BIT_INDEX 24 ++#define COUNT_BIT_INDEX 8 ++ ++#define PORT_REG_LENGTH 0x100 ++#define GLOBAL_REG_LENGTH 0x800 ++#define AXI_REG_LENGTH 0x61 ++#define RAS_REG_LENGTH 0x10 + + #define CHNL_INT_STS_MSK 0xeeeeeeee + #define CHNL_INT_STS_PHY_MSK 0xe +@@ -807,17 +850,17 @@ static void config_id_frame_v3_hw(struct hisi_hba *hisi_hba, int phy_no) + identify_buffer = (u32 *)(&identify_frame); + + hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD0, +- __swab32(identify_buffer[0])); ++ __swab32(identify_buffer[ID_DWORD0_INDEX])); + hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD1, +- __swab32(identify_buffer[1])); ++ __swab32(identify_buffer[ID_DWORD1_INDEX])); + hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD2, +- __swab32(identify_buffer[2])); ++ __swab32(identify_buffer[ID_DWORD2_INDEX])); + hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD3, +- __swab32(identify_buffer[3])); ++ __swab32(identify_buffer[ID_DWORD3_INDEX])); + hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD4, +- __swab32(identify_buffer[4])); ++ __swab32(identify_buffer[ID_DWORD4_INDEX])); + hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD5, +- __swab32(identify_buffer[5])); ++ __swab32(identify_buffer[ID_DWORD5_INDEX])); + } + + static void setup_itct_v3_hw(struct hisi_hba *hisi_hba, +@@ -937,7 +980,7 @@ static int reset_hw_v3_hw(struct hisi_hba *hisi_hba) + + /* Disable all of the PHYs */ + hisi_sas_stop_phys(hisi_hba); +- udelay(50); ++ udelay(HISI_SAS_DELAY_FOR_PHY_DISABLE); + + /* Ensure axi bus idle */ + ret = hisi_sas_read32_poll_timeout(AXI_CFG, val, !val, +@@ -977,7 +1020,7 @@ static int hw_init_v3_hw(struct hisi_hba *hisi_hba) + return rc; + } + +- msleep(100); ++ msleep(DELAY_FOR_RESET_HW); + init_reg_v3_hw(hisi_hba); + + if (guid_parse("D5918B4B-37AE-4E10-A99F-E5E8A6EF4C1F", &guid)) { +@@ -1026,7 +1069,7 @@ static void disable_phy_v3_hw(struct hisi_hba *hisi_hba, int phy_no) + cfg &= ~PHY_CFG_ENA_MSK; + hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg); + +- mdelay(50); ++ mdelay(HISI_SAS_DELAY_FOR_PHY_DISABLE); + + state = hisi_sas_read32(hisi_hba, PHY_STATE); + if (state & BIT(phy_no)) { +@@ -1062,7 +1105,7 @@ static void phy_hard_reset_v3_hw(struct hisi_hba *hisi_hba, int phy_no) + hisi_sas_phy_write32(hisi_hba, phy_no, TXID_AUTO, + txid_auto | TX_HARDRST_MSK); + } +- msleep(100); ++ msleep(HISI_SAS_DELAY_FOR_PHY_DISABLE); + hisi_sas_phy_enable(hisi_hba, phy_no, 1); + } + +@@ -1107,7 +1150,8 @@ static int get_wideport_bitmap_v3_hw(struct hisi_hba *hisi_hba, int port_id) + + for (i = 0; i < hisi_hba->n_phy; i++) + if (phy_state & BIT(i)) +- if (((phy_port_num_ma >> (i * 4)) & 0xf) == port_id) ++ if (((phy_port_num_ma >> (i * HISI_SAS_REG_MEM_SIZE)) & 0xf) == ++ port_id) + bitmap |= BIT(i); + + return bitmap; +@@ -1305,9 +1349,9 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba, + dw1 |= sas_dev->device_id << CMD_HDR_DEV_ID_OFF; + + dw2 = (((sizeof(struct ssp_command_iu) + sizeof(struct ssp_frame_hdr) +- + 3) / 4) << CMD_HDR_CFL_OFF) | +- ((HISI_SAS_MAX_SSP_RESP_SZ / 4) << CMD_HDR_MRFL_OFF) | +- (2 << CMD_HDR_SG_MOD_OFF); ++ + 3) / BYTE_TO_DW) << CMD_HDR_CFL_OFF) | ++ ((HISI_SAS_MAX_SSP_RESP_SZ / BYTE_TO_DW) << CMD_HDR_MRFL_OFF) | ++ (HDR_SG_MOD << CMD_HDR_SG_MOD_OFF); + hdr->dw2 = cpu_to_le32(dw2); + hdr->transfer_tags = cpu_to_le32(slot->idx); + +@@ -1327,18 +1371,19 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba, + buf_cmd = hisi_sas_cmd_hdr_addr_mem(slot) + + sizeof(struct ssp_frame_hdr); + +- memcpy(buf_cmd, &task->ssp_task.LUN, 8); ++ memcpy(buf_cmd, &task->ssp_task.LUN, LUN_SIZE); + if (!tmf) { +- buf_cmd[9] = ssp_task->task_attr; +- memcpy(buf_cmd + 12, scsi_cmnd->cmnd, scsi_cmnd->cmd_len); ++ buf_cmd[ATTR_PRIO_REGION] = ssp_task->task_attr; ++ memcpy(buf_cmd + CDB_REGION, scsi_cmnd->cmnd, ++ scsi_cmnd->cmd_len); + } else { +- buf_cmd[10] = tmf->tmf; ++ buf_cmd[TMF_REGION] = tmf->tmf; + switch (tmf->tmf) { + case TMF_ABORT_TASK: + case TMF_QUERY_TASK: +- buf_cmd[12] = ++ buf_cmd[TAG_MSB] = + (tmf->tag_of_task_to_be_managed >> 8) & 0xff; +- buf_cmd[13] = ++ buf_cmd[TAG_LSB] = + tmf->tag_of_task_to_be_managed & 0xff; + break; + default: +@@ -1371,7 +1416,8 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba, + unsigned int interval = scsi_prot_interval(scsi_cmnd); + unsigned int ilog2_interval = ilog2(interval); + +- len = (task->total_xfer_len >> ilog2_interval) * 8; ++ len = (task->total_xfer_len >> ilog2_interval) * ++ BYTE_TO_DDW; + } + } + +@@ -1391,6 +1437,7 @@ static void prep_smp_v3_hw(struct hisi_hba *hisi_hba, + struct hisi_sas_device *sas_dev = device->lldd_dev; + dma_addr_t req_dma_addr; + unsigned int req_len; ++ u32 cfl; + + /* req */ + sg_req = &task->smp_task.smp_req; +@@ -1401,7 +1448,7 @@ static void prep_smp_v3_hw(struct hisi_hba *hisi_hba, + /* dw0 */ + hdr->dw0 = cpu_to_le32((port->id << CMD_HDR_PORT_OFF) | + (1 << CMD_HDR_PRIORITY_OFF) | /* high pri */ +- (2 << CMD_HDR_CMD_OFF)); /* smp */ ++ (SMP_FRAME_TYPE << CMD_HDR_CMD_OFF)); /* smp */ + + /* map itct entry */ + hdr->dw1 = cpu_to_le32((sas_dev->device_id << CMD_HDR_DEV_ID_OFF) | +@@ -1409,8 +1456,9 @@ static void prep_smp_v3_hw(struct hisi_hba *hisi_hba, + (DIR_NO_DATA << CMD_HDR_DIR_OFF)); + + /* dw2 */ +- hdr->dw2 = cpu_to_le32((((req_len - 4) / 4) << CMD_HDR_CFL_OFF) | +- (HISI_SAS_MAX_SMP_RESP_SZ / 4 << ++ cfl = (req_len - SMP_CRC_SIZE) / BYTE_TO_DW; ++ hdr->dw2 = cpu_to_le32((cfl << CMD_HDR_CFL_OFF) | ++ (HISI_SAS_MAX_SMP_RESP_SZ / BYTE_TO_DW << + CMD_HDR_MRFL_OFF)); + + hdr->transfer_tags = cpu_to_le32(slot->idx << CMD_HDR_IPTT_OFF); +@@ -1477,12 +1525,13 @@ static void prep_ata_v3_hw(struct hisi_hba *hisi_hba, + struct ata_queued_cmd *qc = task->uldd_task; + + hdr_tag = qc->tag; +- task->ata_task.fis.sector_count |= (u8) (hdr_tag << 3); ++ task->ata_task.fis.sector_count |= ++ (u8)(hdr_tag << HDR_TAG_OFF); + dw2 |= hdr_tag << CMD_HDR_NCQ_TAG_OFF; + } + +- dw2 |= (HISI_SAS_MAX_STP_RESP_SZ / 4) << CMD_HDR_CFL_OFF | +- 2 << CMD_HDR_SG_MOD_OFF; ++ dw2 |= (HISI_SAS_MAX_STP_RESP_SZ / BYTE_TO_DW) << CMD_HDR_CFL_OFF | ++ HDR_SG_MOD << CMD_HDR_SG_MOD_OFF; + hdr->dw2 = cpu_to_le32(dw2); + + /* dw3 */ +@@ -1542,9 +1591,9 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) + hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 1); + + port_id = hisi_sas_read32(hisi_hba, PHY_PORT_NUM_MA); +- port_id = (port_id >> (4 * phy_no)) & 0xf; ++ port_id = (port_id >> (HISI_SAS_REG_MEM_SIZE * phy_no)) & 0xf; + link_rate = hisi_sas_read32(hisi_hba, PHY_CONN_RATE); +- link_rate = (link_rate >> (phy_no * 4)) & 0xf; ++ link_rate = (link_rate >> (phy_no * HISI_SAS_REG_MEM_SIZE)) & 0xf; + + if (port_id == 0xf) { + dev_err(dev, "phyup: phy%d invalid portid\n", phy_no); +@@ -1577,8 +1626,8 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) + + sas_phy->oob_mode = SATA_OOB_MODE; + attached_sas_addr[0] = 0x50; +- attached_sas_addr[6] = shost->host_no; +- attached_sas_addr[7] = phy_no; ++ attached_sas_addr[HOST_NO_OFF] = shost->host_no; ++ attached_sas_addr[PHY_NO_OFF] = phy_no; + memcpy(sas_phy->attached_sas_addr, + attached_sas_addr, + SAS_ADDR_SIZE); +@@ -1594,7 +1643,7 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) + (struct sas_identify_frame *)frame_rcvd; + + dev_info(dev, "phyup: phy%d link_rate=%d\n", phy_no, link_rate); +- for (i = 0; i < 6; i++) { ++ for (i = 0; i < IDENTIFY_REG_READ; i++) { + u32 idaf = hisi_sas_phy_read32(hisi_hba, phy_no, + RX_IDAF_DWORD0 + (i * 4)); + frame_rcvd[i] = __swab32(idaf); +@@ -1864,7 +1913,7 @@ static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no) + + dev_warn(dev, "phy%d stp link timeout (0x%x)\n", + phy_no, reg_value); +- if (reg_value & BIT(4)) ++ if (reg_value & BIT(LINK_RESET_TIMEOUT_OFF)) + hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET); + } + +@@ -2581,7 +2630,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) + struct pci_dev *pdev = hisi_hba->pci_dev; + int rc, i; + +- rc = devm_request_irq(dev, pci_irq_vector(pdev, 1), ++ rc = devm_request_irq(dev, pci_irq_vector(pdev, IRQ_PHY_UP_DOWN_INDEX), + int_phy_up_down_bcast_v3_hw, 0, + DRV_NAME " phy", hisi_hba); + if (rc) { +@@ -2589,7 +2638,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) + return -ENOENT; + } + +- rc = devm_request_irq(dev, pci_irq_vector(pdev, 2), ++ rc = devm_request_irq(dev, pci_irq_vector(pdev, IRQ_CHL_INDEX), + int_chnl_int_v3_hw, 0, + DRV_NAME " channel", hisi_hba); + if (rc) { +@@ -2597,7 +2646,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) + return -ENOENT; + } + +- rc = devm_request_irq(dev, pci_irq_vector(pdev, 11), ++ rc = devm_request_irq(dev, pci_irq_vector(pdev, IRQ_AXI_INDEX), + fatal_axi_int_v3_hw, 0, + DRV_NAME " fatal", hisi_hba); + if (rc) { +@@ -2610,7 +2659,8 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) + + for (i = 0; i < hisi_hba->cq_nvecs; i++) { + struct hisi_sas_cq *cq = &hisi_hba->cq[i]; +- int nr = hisi_sas_intr_conv ? 16 : 16 + i; ++ int nr = hisi_sas_intr_conv ? BASE_VECTORS_V3_HW : ++ BASE_VECTORS_V3_HW + i; + unsigned long irqflags = hisi_sas_intr_conv ? IRQF_SHARED : + IRQF_ONESHOT; + +@@ -2668,14 +2718,14 @@ static void interrupt_disable_v3_hw(struct hisi_hba *hisi_hba) + struct pci_dev *pdev = hisi_hba->pci_dev; + int i; + +- synchronize_irq(pci_irq_vector(pdev, 1)); +- synchronize_irq(pci_irq_vector(pdev, 2)); +- synchronize_irq(pci_irq_vector(pdev, 11)); ++ synchronize_irq(pci_irq_vector(pdev, IRQ_PHY_UP_DOWN_INDEX)); ++ synchronize_irq(pci_irq_vector(pdev, IRQ_CHL_INDEX)); ++ synchronize_irq(pci_irq_vector(pdev, IRQ_AXI_INDEX)); + for (i = 0; i < hisi_hba->queue_count; i++) + hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK + 0x4 * i, 0x1); + + for (i = 0; i < hisi_hba->cq_nvecs; i++) +- synchronize_irq(pci_irq_vector(pdev, i + 16)); ++ synchronize_irq(pci_irq_vector(pdev, i + BASE_VECTORS_V3_HW)); + + hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xffffffff); + hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0xffffffff); +@@ -2707,7 +2757,7 @@ static int disable_host_v3_hw(struct hisi_hba *hisi_hba) + + hisi_sas_stop_phys(hisi_hba); + +- mdelay(10); ++ mdelay(HISI_SAS_DELAY_FOR_PHY_DISABLE); + + reg_val = hisi_sas_read32(hisi_hba, AXI_MASTER_CFG_BASE + + AM_CTRL_GLOBAL); +@@ -2843,13 +2893,13 @@ static ssize_t intr_coal_ticks_v3_hw_store(struct device *dev, + u32 intr_coal_ticks; + int ret; + +- ret = kstrtou32(buf, 10, &intr_coal_ticks); ++ ret = kstrtou32(buf, DECIMALISM_FLAG, &intr_coal_ticks); + if (ret) { + dev_err(dev, "Input data of interrupt coalesce unmatch\n"); + return -EINVAL; + } + +- if (intr_coal_ticks >= BIT(24)) { ++ if (intr_coal_ticks >= BIT(TICKS_BIT_INDEX)) { + dev_err(dev, "intr_coal_ticks must be less than 2^24!\n"); + return -EINVAL; + } +@@ -2882,13 +2932,13 @@ static ssize_t intr_coal_count_v3_hw_store(struct device *dev, + u32 intr_coal_count; + int ret; + +- ret = kstrtou32(buf, 10, &intr_coal_count); ++ ret = kstrtou32(buf, DECIMALISM_FLAG, &intr_coal_count); + if (ret) { + dev_err(dev, "Input data of interrupt coalesce unmatch\n"); + return -EINVAL; + } + +- if (intr_coal_count >= BIT(8)) { ++ if (intr_coal_count >= BIT(COUNT_BIT_INDEX)) { + dev_err(dev, "intr_coal_count must be less than 2^8!\n"); + return -EINVAL; + } +@@ -3020,7 +3070,7 @@ static const struct hisi_sas_debugfs_reg_lu debugfs_port_reg_lu[] = { + + static const struct hisi_sas_debugfs_reg debugfs_port_reg = { + .lu = debugfs_port_reg_lu, +- .count = 0x100, ++ .count = PORT_REG_LENGTH, + .base_off = PORT_BASE, + }; + +@@ -3094,7 +3144,7 @@ static const struct hisi_sas_debugfs_reg_lu debugfs_global_reg_lu[] = { + + static const struct hisi_sas_debugfs_reg debugfs_global_reg = { + .lu = debugfs_global_reg_lu, +- .count = 0x800, ++ .count = GLOBAL_REG_LENGTH, + }; + + static const struct hisi_sas_debugfs_reg_lu debugfs_axi_reg_lu[] = { +@@ -3107,7 +3157,7 @@ static const struct hisi_sas_debugfs_reg_lu debugfs_axi_reg_lu[] = { + + static const struct hisi_sas_debugfs_reg debugfs_axi_reg = { + .lu = debugfs_axi_reg_lu, +- .count = 0x61, ++ .count = AXI_REG_LENGTH, + .base_off = AXI_MASTER_CFG_BASE, + }; + +@@ -3124,7 +3174,7 @@ static const struct hisi_sas_debugfs_reg_lu debugfs_ras_reg_lu[] = { + + static const struct hisi_sas_debugfs_reg debugfs_ras_reg = { + .lu = debugfs_ras_reg_lu, +- .count = 0x10, ++ .count = RAS_REG_LENGTH, + .base_off = RAS_BASE, + }; + +@@ -3133,7 +3183,7 @@ static void debugfs_snapshot_prepare_v3_hw(struct hisi_hba *hisi_hba) + struct Scsi_Host *shost = hisi_hba->shost; + + scsi_block_requests(shost); +- wait_cmds_complete_timeout_v3_hw(hisi_hba, 100, 5000); ++ wait_cmds_complete_timeout_v3_hw(hisi_hba, WAIT_RETRY, WAIT_TMROUT); + + set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); + hisi_sas_sync_cqs(hisi_hba); +@@ -3174,7 +3224,7 @@ static void read_iost_itct_cache_v3_hw(struct hisi_hba *hisi_hba, + return; + } + +- memset(buf, 0, cache_dw_size * 4); ++ memset(buf, 0, cache_dw_size * BYTE_TO_DW); + buf[0] = val; + + for (i = 1; i < cache_dw_size; i++) +@@ -3221,7 +3271,7 @@ static void hisi_sas_bist_test_restore_v3_hw(struct hisi_hba *hisi_hba) + reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, PROG_PHY_LINK_RATE); + /* init OOB link rate as 1.5 Gbits */ + reg_val &= ~CFG_PROG_OOB_PHY_LINK_RATE_MSK; +- reg_val |= (0x8 << CFG_PROG_OOB_PHY_LINK_RATE_OFF); ++ reg_val |= (SAS_LINK_RATE_1_5_GBPS << CFG_PROG_OOB_PHY_LINK_RATE_OFF); + hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE, reg_val); + + /* enable PHY */ +@@ -3230,6 +3280,9 @@ static void hisi_sas_bist_test_restore_v3_hw(struct hisi_hba *hisi_hba) + + #define SAS_PHY_BIST_CODE_INIT 0x1 + #define SAS_PHY_BIST_CODE1_INIT 0X80 ++#define SAS_PHY_BIST_INIT_DELAY 100 ++#define SAS_PHY_BIST_LOOP_TEST_0 1 ++#define SAS_PHY_BIST_LOOP_TEST_1 2 + static int debugfs_set_bist_v3_hw(struct hisi_hba *hisi_hba, bool enable) + { + u32 reg_val, mode_tmp; +@@ -3248,7 +3301,8 @@ static int debugfs_set_bist_v3_hw(struct hisi_hba *hisi_hba, bool enable) + ffe[FFE_SATA_1_5_GBPS], ffe[FFE_SATA_3_0_GBPS], + ffe[FFE_SATA_6_0_GBPS], fix_code[FIXED_CODE], + fix_code[FIXED_CODE_1]); +- mode_tmp = path_mode ? 2 : 1; ++ mode_tmp = path_mode ? SAS_PHY_BIST_LOOP_TEST_1 : ++ SAS_PHY_BIST_LOOP_TEST_0; + if (enable) { + /* some preparations before bist test */ + hisi_sas_bist_test_prep_v3_hw(hisi_hba); +@@ -3291,13 +3345,13 @@ static int debugfs_set_bist_v3_hw(struct hisi_hba *hisi_hba, bool enable) + SAS_PHY_BIST_CODE1_INIT); + } + +- mdelay(100); ++ mdelay(SAS_PHY_BIST_INIT_DELAY); + reg_val |= (CFG_RX_BIST_EN_MSK | CFG_TX_BIST_EN_MSK); + hisi_sas_phy_write32(hisi_hba, phy_no, SAS_PHY_BIST_CTRL, + reg_val); + + /* clear error bit */ +- mdelay(100); ++ mdelay(SAS_PHY_BIST_INIT_DELAY); + hisi_sas_phy_read32(hisi_hba, phy_no, SAS_BIST_ERR_CNT); + } else { + /* disable bist test and recover it */ +@@ -3473,7 +3527,7 @@ static void debugfs_snapshot_port_reg_v3_hw(struct hisi_hba *hisi_hba) + for (phy_cnt = 0; phy_cnt < hisi_hba->n_phy; phy_cnt++) { + databuf = hisi_hba->debugfs_port_reg[dump_index][phy_cnt].data; + for (i = 0; i < port->count; i++, databuf++) { +- offset = port->base_off + 4 * i; ++ offset = port->base_off + HISI_SAS_REG_MEM_SIZE * i; + *databuf = hisi_sas_phy_read32(hisi_hba, phy_cnt, + offset); + } +@@ -3487,7 +3541,8 @@ static void debugfs_snapshot_global_reg_v3_hw(struct hisi_hba *hisi_hba) + int i; + + for (i = 0; i < debugfs_global_reg.count; i++, databuf++) +- *databuf = hisi_sas_read32(hisi_hba, 4 * i); ++ *databuf = hisi_sas_read32(hisi_hba, ++ HISI_SAS_REG_MEM_SIZE * i); + } + + static void debugfs_snapshot_axi_reg_v3_hw(struct hisi_hba *hisi_hba) +@@ -3498,7 +3553,9 @@ static void debugfs_snapshot_axi_reg_v3_hw(struct hisi_hba *hisi_hba) + int i; + + for (i = 0; i < axi->count; i++, databuf++) +- *databuf = hisi_sas_read32(hisi_hba, 4 * i + axi->base_off); ++ *databuf = hisi_sas_read32(hisi_hba, ++ HISI_SAS_REG_MEM_SIZE * i + ++ axi->base_off); + } + + static void debugfs_snapshot_ras_reg_v3_hw(struct hisi_hba *hisi_hba) +@@ -3509,7 +3566,9 @@ static void debugfs_snapshot_ras_reg_v3_hw(struct hisi_hba *hisi_hba) + int i; + + for (i = 0; i < ras->count; i++, databuf++) +- *databuf = hisi_sas_read32(hisi_hba, 4 * i + ras->base_off); ++ *databuf = hisi_sas_read32(hisi_hba, ++ HISI_SAS_REG_MEM_SIZE * i + ++ ras->base_off); + } + + static void debugfs_snapshot_itct_reg_v3_hw(struct hisi_hba *hisi_hba) +@@ -3572,7 +3631,7 @@ static void debugfs_print_reg_v3_hw(u32 *regs_val, struct seq_file *s, + int i; + + for (i = 0; i < reg->count; i++) { +- int off = i * 4; ++ int off = i * HISI_SAS_REG_MEM_SIZE; + const char *name; + + name = debugfs_to_reg_name_v3_hw(off, reg->base_off, +@@ -3650,9 +3709,9 @@ static void debugfs_show_row_64_v3_hw(struct seq_file *s, int index, + + /* completion header size not fixed per HW version */ + seq_printf(s, "index %04d:\n\t", index); +- for (i = 1; i <= sz / 8; i++, ptr++) { ++ for (i = 1; i <= sz / BYTE_TO_DDW; i++, ptr++) { + seq_printf(s, " 0x%016llx", le64_to_cpu(*ptr)); +- if (!(i % 2)) ++ if (!(i % TWO_PARA_PER_LINE)) + seq_puts(s, "\n\t"); + } + +@@ -3666,9 +3725,9 @@ static void debugfs_show_row_32_v3_hw(struct seq_file *s, int index, + + /* completion header size not fixed per HW version */ + seq_printf(s, "index %04d:\n\t", index); +- for (i = 1; i <= sz / 4; i++, ptr++) { ++ for (i = 1; i <= sz / BYTE_TO_DW; i++, ptr++) { + seq_printf(s, " 0x%08x", le32_to_cpu(*ptr)); +- if (!(i % 4)) ++ if (!(i % FOUR_PARA_PER_LINE)) + seq_puts(s, "\n\t"); + } + seq_puts(s, "\n"); +@@ -3753,7 +3812,7 @@ static int debugfs_iost_cache_v3_hw_show(struct seq_file *s, void *p) + struct hisi_sas_debugfs_iost_cache *debugfs_iost_cache = s->private; + struct hisi_sas_iost_itct_cache *iost_cache = + debugfs_iost_cache->cache; +- u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * 4; ++ u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * BYTE_TO_DW; + int i, tab_idx; + __le64 *iost; + +@@ -3801,7 +3860,7 @@ static int debugfs_itct_cache_v3_hw_show(struct seq_file *s, void *p) + struct hisi_sas_debugfs_itct_cache *debugfs_itct_cache = s->private; + struct hisi_sas_iost_itct_cache *itct_cache = + debugfs_itct_cache->cache; +- u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * 4; ++ u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * BYTE_TO_DW; + int i, tab_idx; + __le64 *itct; + +@@ -3830,12 +3889,12 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba, int index) + u64 *debugfs_timestamp; + struct dentry *dump_dentry; + struct dentry *dentry; +- char name[256]; ++ char name[NAME_BUF_SIZE]; + int p; + int c; + int d; + +- snprintf(name, 256, "%d", index); ++ snprintf(name, NAME_BUF_SIZE, "%d", index); + + dump_dentry = debugfs_create_dir(name, hisi_hba->debugfs_dump_dentry); + +@@ -3851,7 +3910,7 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba, int index) + /* Create port dir and files */ + dentry = debugfs_create_dir("port", dump_dentry); + for (p = 0; p < hisi_hba->n_phy; p++) { +- snprintf(name, 256, "%d", p); ++ snprintf(name, NAME_BUF_SIZE, "%d", p); + + debugfs_create_file(name, 0400, dentry, + &hisi_hba->debugfs_port_reg[index][p], +@@ -3861,7 +3920,7 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba, int index) + /* Create CQ dir and files */ + dentry = debugfs_create_dir("cq", dump_dentry); + for (c = 0; c < hisi_hba->queue_count; c++) { +- snprintf(name, 256, "%d", c); ++ snprintf(name, NAME_BUF_SIZE, "%d", c); + + debugfs_create_file(name, 0400, dentry, + &hisi_hba->debugfs_cq[index][c], +@@ -3871,7 +3930,7 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba, int index) + /* Create DQ dir and files */ + dentry = debugfs_create_dir("dq", dump_dentry); + for (d = 0; d < hisi_hba->queue_count; d++) { +- snprintf(name, 256, "%d", d); ++ snprintf(name, NAME_BUF_SIZE, "%d", d); + + debugfs_create_file(name, 0400, dentry, + &hisi_hba->debugfs_dq[index][d], +@@ -3908,9 +3967,9 @@ static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file, + size_t count, loff_t *ppos) + { + struct hisi_hba *hisi_hba = file->f_inode->i_private; +- char buf[8]; ++ char buf[DUMP_BUF_SIZE]; + +- if (count > 8) ++ if (count > DUMP_BUF_SIZE) + return -EFAULT; + + if (copy_from_user(buf, user_buf, count)) +@@ -3974,7 +4033,7 @@ static ssize_t debugfs_bist_linkrate_v3_hw_write(struct file *filp, + { + struct seq_file *m = filp->private_data; + struct hisi_hba *hisi_hba = m->private; +- char kbuf[16] = {}, *pkbuf; ++ char kbuf[BIST_BUF_SIZE] = {}, *pkbuf; + bool found = false; + int i; + +@@ -3991,7 +4050,7 @@ static ssize_t debugfs_bist_linkrate_v3_hw_write(struct file *filp, + + for (i = 0; i < ARRAY_SIZE(debugfs_loop_linkrate_v3_hw); i++) { + if (!strncmp(debugfs_loop_linkrate_v3_hw[i].name, +- pkbuf, 16)) { ++ pkbuf, BIST_BUF_SIZE)) { + hisi_hba->debugfs_bist_linkrate = + debugfs_loop_linkrate_v3_hw[i].value; + found = true; +@@ -4049,7 +4108,7 @@ static ssize_t debugfs_bist_code_mode_v3_hw_write(struct file *filp, + { + struct seq_file *m = filp->private_data; + struct hisi_hba *hisi_hba = m->private; +- char kbuf[16] = {}, *pkbuf; ++ char kbuf[BIST_BUF_SIZE] = {}, *pkbuf; + bool found = false; + int i; + +@@ -4066,7 +4125,7 @@ static ssize_t debugfs_bist_code_mode_v3_hw_write(struct file *filp, + + for (i = 0; i < ARRAY_SIZE(debugfs_loop_code_mode_v3_hw); i++) { + if (!strncmp(debugfs_loop_code_mode_v3_hw[i].name, +- pkbuf, 16)) { ++ pkbuf, BIST_BUF_SIZE)) { + hisi_hba->debugfs_bist_code_mode = + debugfs_loop_code_mode_v3_hw[i].value; + found = true; +@@ -4181,7 +4240,7 @@ static ssize_t debugfs_bist_mode_v3_hw_write(struct file *filp, + { + struct seq_file *m = filp->private_data; + struct hisi_hba *hisi_hba = m->private; +- char kbuf[16] = {}, *pkbuf; ++ char kbuf[BIST_BUF_SIZE] = {}, *pkbuf; + bool found = false; + int i; + +@@ -4197,7 +4256,8 @@ static ssize_t debugfs_bist_mode_v3_hw_write(struct file *filp, + pkbuf = strstrip(kbuf); + + for (i = 0; i < ARRAY_SIZE(debugfs_loop_modes_v3_hw); i++) { +- if (!strncmp(debugfs_loop_modes_v3_hw[i].name, pkbuf, 16)) { ++ if (!strncmp(debugfs_loop_modes_v3_hw[i].name, pkbuf, ++ BIST_BUF_SIZE)) { + hisi_hba->debugfs_bist_mode = + debugfs_loop_modes_v3_hw[i].value; + found = true; +@@ -4476,8 +4536,9 @@ static int debugfs_fifo_data_v3_hw_show(struct seq_file *s, void *p) + + debugfs_read_fifo_data_v3_hw(phy); + +- debugfs_show_row_32_v3_hw(s, 0, HISI_SAS_FIFO_DATA_DW_SIZE * 4, +- (__le32 *)phy->fifo.rd_data); ++ debugfs_show_row_32_v3_hw(s, 0, ++ HISI_SAS_FIFO_DATA_DW_SIZE * HISI_SAS_REG_MEM_SIZE, ++ phy->fifo.rd_data); + + return 0; + } +@@ -4609,14 +4670,14 @@ static int debugfs_alloc_v3_hw(struct hisi_hba *hisi_hba, int dump_index) + struct hisi_sas_debugfs_regs *regs = + &hisi_hba->debugfs_regs[dump_index][r]; + +- sz = debugfs_reg_array_v3_hw[r]->count * 4; ++ sz = debugfs_reg_array_v3_hw[r]->count * HISI_SAS_REG_MEM_SIZE; + regs->data = devm_kmalloc(dev, sz, GFP_KERNEL); + if (!regs->data) + goto fail; + regs->hisi_hba = hisi_hba; + } + +- sz = debugfs_port_reg.count * 4; ++ sz = debugfs_port_reg.count * HISI_SAS_REG_MEM_SIZE; + for (p = 0; p < hisi_hba->n_phy; p++) { + struct hisi_sas_debugfs_port *port = + &hisi_hba->debugfs_port_reg[dump_index][p]; +@@ -4726,11 +4787,11 @@ static void debugfs_phy_down_cnt_init_v3_hw(struct hisi_hba *hisi_hba) + { + struct dentry *dir = debugfs_create_dir("phy_down_cnt", + hisi_hba->debugfs_dir); +- char name[16]; ++ char name[NAME_BUF_SIZE]; + int phy_no; + + for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) { +- snprintf(name, 16, "%d", phy_no); ++ snprintf(name, NAME_BUF_SIZE, "%d", phy_no); + debugfs_create_file(name, 0600, dir, + &hisi_hba->phy[phy_no], + &debugfs_phy_down_cnt_v3_hw_fops); +@@ -4899,7 +4960,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) + shost->max_id = HISI_SAS_MAX_DEVICES; + shost->max_lun = ~0; + shost->max_channel = 1; +- shost->max_cmd_len = 16; ++ shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN; + shost->can_queue = HISI_SAS_UNRESERVED_IPTT; + shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT; + if (hisi_hba->iopoll_q_cnt) +@@ -4981,12 +5042,13 @@ hisi_sas_v3_destroy_irqs(struct pci_dev *pdev, struct hisi_hba *hisi_hba) + { + int i; + +- devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 1), hisi_hba); +- devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 2), hisi_hba); +- devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 11), hisi_hba); ++ devm_free_irq(&pdev->dev, pci_irq_vector(pdev, IRQ_PHY_UP_DOWN_INDEX), hisi_hba); ++ devm_free_irq(&pdev->dev, pci_irq_vector(pdev, IRQ_CHL_INDEX), hisi_hba); ++ devm_free_irq(&pdev->dev, pci_irq_vector(pdev, IRQ_AXI_INDEX), hisi_hba); + for (i = 0; i < hisi_hba->cq_nvecs; i++) { + struct hisi_sas_cq *cq = &hisi_hba->cq[i]; +- int nr = hisi_sas_intr_conv ? 16 : 16 + i; ++ int nr = hisi_sas_intr_conv ? BASE_VECTORS_V3_HW : ++ BASE_VECTORS_V3_HW + i; + + devm_free_irq(&pdev->dev, pci_irq_vector(pdev, nr), cq); + } +-- +2.51.0 + diff --git a/queue-6.12/scsi-ufs-core-fix-serror-in-ufshcd_rtc_work-during-u.patch b/queue-6.12/scsi-ufs-core-fix-serror-in-ufshcd_rtc_work-during-u.patch new file mode 100644 index 0000000000..5b918dd461 --- /dev/null +++ b/queue-6.12/scsi-ufs-core-fix-serror-in-ufshcd_rtc_work-during-u.patch @@ -0,0 +1,85 @@ +From 1d37a98c22d1a1c00652376f5420f8dcc5b0eaa9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Mar 2026 11:51:28 +0800 +Subject: scsi: ufs: core: Fix SError in ufshcd_rtc_work() during UFS suspend + +From: Wang Shuaiwei + +[ Upstream commit b0bd84c39289ef6a6c3827dd52c875659291970a ] + +In __ufshcd_wl_suspend(), cancel_delayed_work_sync() is called to cancel +the UFS RTC work, but it is placed after ufshcd_vops_suspend(hba, pm_op, +POST_CHANGE). This creates a race condition where ufshcd_rtc_work() can +still be running while ufshcd_vops_suspend() is executing. When +UFSHCD_CAP_CLK_GATING is not supported, the condition +!hba->clk_gating.active_reqs is always true, causing ufshcd_update_rtc() +to be executed. Since ufshcd_vops_suspend() typically performs clock +gating operations, executing ufshcd_update_rtc() at that moment triggers +an SError. The kernel panic trace is as follows: + +Kernel panic - not syncing: Asynchronous SError Interrupt +Call trace: + dump_backtrace+0xec/0x128 + show_stack+0x18/0x28 + dump_stack_lvl+0x40/0xa0 + dump_stack+0x18/0x24 + panic+0x148/0x374 + nmi_panic+0x3c/0x8c + arm64_serror_panic+0x64/0x8c + do_serror+0xc4/0xc8 + el1h_64_error_handler+0x34/0x4c + el1h_64_error+0x68/0x6c + el1_interrupt+0x20/0x58 + el1h_64_irq_handler+0x18/0x24 + el1h_64_irq+0x68/0x6c + ktime_get+0xc4/0x12c + ufshcd_mcq_sq_stop+0x4c/0xec + ufshcd_mcq_sq_cleanup+0x64/0x1dc + ufshcd_clear_cmd+0x38/0x134 + ufshcd_issue_dev_cmd+0x298/0x4d0 + ufshcd_exec_dev_cmd+0x1a4/0x1c4 + ufshcd_query_attr+0xbc/0x19c + ufshcd_rtc_work+0x10c/0x1c8 + process_scheduled_works+0x1c4/0x45c + worker_thread+0x32c/0x3e8 + kthread+0x120/0x1d8 + ret_from_fork+0x10/0x20 + +Fix this by moving cancel_delayed_work_sync() before the call to +ufshcd_vops_suspend(hba, pm_op, PRE_CHANGE), ensuring the UFS RTC work is +fully completed or cancelled at that point. + +Cc: Bean Huo +Fixes: 6bf999e0eb41 ("scsi: ufs: core: Add UFS RTC support") +Reviewed-by: Bart Van Assche +Signed-off-by: Wang Shuaiwei +Link: https://patch.msgid.link/20260307035128.3419687-1-wangshuaiwei1@xiaomi.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/ufs/core/ufshcd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c +index ea6e7c18e35cd..22d3cb0ddbcaa 100644 +--- a/drivers/ufs/core/ufshcd.c ++++ b/drivers/ufs/core/ufshcd.c +@@ -9813,6 +9813,7 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) + } + + flush_work(&hba->eeh_work); ++ cancel_delayed_work_sync(&hba->ufs_rtc_update_work); + + ret = ufshcd_vops_suspend(hba, pm_op, PRE_CHANGE); + if (ret) +@@ -9867,7 +9868,6 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) + if (ret) + goto set_link_active; + +- cancel_delayed_work_sync(&hba->ufs_rtc_update_work); + goto out; + + set_link_active: +-- +2.51.0 + diff --git a/queue-6.12/series b/queue-6.12/series index 3f7a00157f..74868789e4 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -115,3 +115,11 @@ usb-renesas_usbhs-fix-use-after-free-in-isr-during-device-removal.patch usb-mdc800-handle-signal-and-read-racing.patch usb-image-mdc800-kill-download-urb-on-timeout.patch rust-kbuild-allow-unused_features.patch +time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch +i3c-dw-i3c-master-set-sir_reject-in-dat-on-device-at.patch +scsi-ufs-core-fix-serror-in-ufshcd_rtc_work-during-u.patch +scsi-hisi_sas-add-time-interval-between-two-h2d-fis-.patch +scsi-hisi_sas-use-macro-instead-of-magic-number.patch +scsi-hisi_sas-fix-null-pointer-exception-during-user.patch +kbuild-disable-cc_has_asm_goto_output-on-clang-17.patch +fix-cc_has_asm_goto_output-on-non-x86-architectures.patch diff --git a/queue-6.12/time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch b/queue-6.12/time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch new file mode 100644 index 0000000000..833a9de32e --- /dev/null +++ b/queue-6.12/time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch @@ -0,0 +1,39 @@ +From c9eb9faac6ea2dd1e0e60b23e2a46f552dafcd10 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Mar 2026 21:24:03 -0500 +Subject: time/jiffies: Mark jiffies_64_to_clock_t() notrace + +From: Steven Rostedt + +[ Upstream commit 755a648e78f12574482d4698d877375793867fa1 ] + +The trace_clock_jiffies() function that handles the "uptime" clock for +tracing calls jiffies_64_to_clock_t(). This causes the function tracer to +constantly recurse when the tracing clock is set to "uptime". Mark it +notrace to prevent unnecessary recursion when using the "uptime" clock. + +Fixes: 58d4e21e50ff3 ("tracing: Fix wraparound problems in "uptime" trace clock") +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Thomas Gleixner +Link: https://patch.msgid.link/20260306212403.72270bb2@robin +Signed-off-by: Sasha Levin +--- + kernel/time/time.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/time/time.c b/kernel/time/time.c +index 1ad88e97b4ebc..da7e8a02a0964 100644 +--- a/kernel/time/time.c ++++ b/kernel/time/time.c +@@ -702,7 +702,7 @@ EXPORT_SYMBOL(clock_t_to_jiffies); + * + * Return: jiffies_64 value converted to 64-bit "clock_t" (CLOCKS_PER_SEC) + */ +-u64 jiffies_64_to_clock_t(u64 x) ++notrace u64 jiffies_64_to_clock_t(u64 x) + { + #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 + # if HZ < USER_HZ +-- +2.51.0 + diff --git a/queue-6.18/alsa-usb-audio-improve-focusrite-sample-rate-filteri.patch b/queue-6.18/alsa-usb-audio-improve-focusrite-sample-rate-filteri.patch new file mode 100644 index 0000000000..841def0066 --- /dev/null +++ b/queue-6.18/alsa-usb-audio-improve-focusrite-sample-rate-filteri.patch @@ -0,0 +1,149 @@ +From be346e0a68c71fc84da0b592b91f3ed1f82d9d59 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 21 Feb 2026 02:33:45 +1030 +Subject: ALSA: usb-audio: Improve Focusrite sample rate filtering + +From: Geoffrey D. Bennett + +[ Upstream commit 24d2d3c5f94007a5a0554065ab7349bb69e28bcb ] + +Replace the bLength == 10 max_rate check in +focusrite_valid_sample_rate() with filtering that also examines the +bmControls VAL_ALT_SETTINGS bit. + +When VAL_ALT_SETTINGS is readable, the device uses strict +per-altsetting rate filtering (only the highest rate pair for that +altsetting is valid). When it is not readable, all rates up to +max_rate are valid. + +For devices without the bLength == 10 Format Type descriptor extension +but with VAL_ALT_SETTINGS readable and multiple altsettings (only seen +in Scarlett 18i8 3rd Gen playback), fall back to the Focusrite +convention: alt 1 = 48kHz, alt 2 = 96kHz, alt 3 = 192kHz. + +This produces correct rate tables for all tested Focusrite devices +(all Scarlett 2nd, 3rd, and 4th Gen, Clarett+, and Vocaster) using +only USB descriptors, allowing QUIRK_FLAG_VALIDATE_RATES to be removed +for Focusrite in the next commit. + +Signed-off-by: Geoffrey D. Bennett +Signed-off-by: Takashi Iwai +Link: https://patch.msgid.link/7e18c1f393a6ecb6fc75dd867a2c4dbe135e3e22.1771594828.git.g@b4.vu +Signed-off-by: Sasha Levin +--- + sound/usb/format.c | 70 ++++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 65 insertions(+), 5 deletions(-) + +diff --git a/sound/usb/format.c b/sound/usb/format.c +index ec95a063beb10..53b5dc5453b78 100644 +--- a/sound/usb/format.c ++++ b/sound/usb/format.c +@@ -302,17 +302,48 @@ static bool s1810c_valid_sample_rate(struct audioformat *fp, + } + + /* +- * Many Focusrite devices supports a limited set of sampling rates per +- * altsetting. Maximum rate is exposed in the last 4 bytes of Format Type +- * descriptor which has a non-standard bLength = 10. ++ * Focusrite devices use rate pairs: 44100/48000, 88200/96000, and ++ * 176400/192000. Return true if rate is in the pair for max_rate. ++ */ ++static bool focusrite_rate_pair(unsigned int rate, ++ unsigned int max_rate) ++{ ++ switch (max_rate) { ++ case 48000: return rate == 44100 || rate == 48000; ++ case 96000: return rate == 88200 || rate == 96000; ++ case 192000: return rate == 176400 || rate == 192000; ++ default: return true; ++ } ++} ++ ++/* ++ * Focusrite devices report all supported rates in a single clock ++ * source but only a subset is valid per altsetting. ++ * ++ * Detection uses two descriptor features: ++ * ++ * 1. Format Type descriptor bLength == 10: non-standard extension ++ * with max sample rate in bytes 6..9. ++ * ++ * 2. bmControls VAL_ALT_SETTINGS readable bit: when set, the device ++ * only supports the highest rate pair for that altsetting, and when ++ * clear, all rates up to max_rate are valid. ++ * ++ * For devices without the bLength == 10 extension but with ++ * VAL_ALT_SETTINGS readable and multiple altsettings (only seen in ++ * Scarlett 18i8 3rd Gen playback), fall back to the Focusrite ++ * convention: alt 1 = 48kHz, alt 2 = 96kHz, alt 3 = 192kHz. + */ + static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip, + struct audioformat *fp, + unsigned int rate) + { ++ struct usb_interface *iface; + struct usb_host_interface *alts; ++ struct uac2_as_header_descriptor *as; + unsigned char *fmt; + unsigned int max_rate; ++ bool val_alt; + + alts = snd_usb_get_host_interface(chip, fp->iface, fp->altsetting); + if (!alts) +@@ -323,9 +354,21 @@ static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip, + if (!fmt) + return true; + ++ as = snd_usb_find_csint_desc(alts->extra, alts->extralen, ++ NULL, UAC_AS_GENERAL); ++ if (!as) ++ return true; ++ ++ val_alt = uac_v2v3_control_is_readable(as->bmControls, ++ UAC2_AS_VAL_ALT_SETTINGS); ++ + if (fmt[0] == 10) { /* bLength */ + max_rate = combine_quad(&fmt[6]); + ++ if (val_alt) ++ return focusrite_rate_pair(rate, max_rate); ++ ++ /* No val_alt: rates fall through from higher */ + switch (max_rate) { + case 192000: + if (rate == 176400 || rate == 192000) +@@ -341,12 +384,29 @@ static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip, + usb_audio_info(chip, + "%u:%d : unexpected max rate: %u\n", + fp->iface, fp->altsetting, max_rate); +- + return true; + } + } + +- return true; ++ if (!val_alt) ++ return true; ++ ++ /* Multi-altsetting device with val_alt but no max_rate ++ * in the format descriptor. Use Focusrite convention: ++ * alt 1 = 48kHz, alt 2 = 96kHz, alt 3 = 192kHz. ++ */ ++ iface = usb_ifnum_to_if(chip->dev, fp->iface); ++ if (!iface || iface->num_altsetting <= 2) ++ return true; ++ ++ switch (fp->altsetting) { ++ case 1: max_rate = 48000; break; ++ case 2: max_rate = 96000; break; ++ case 3: max_rate = 192000; break; ++ default: return true; ++ } ++ ++ return focusrite_rate_pair(rate, max_rate); + } + + /* +-- +2.51.0 + diff --git a/queue-6.18/i3c-dw-i3c-master-set-sir_reject-in-dat-on-device-at.patch b/queue-6.18/i3c-dw-i3c-master-set-sir_reject-in-dat-on-device-at.patch new file mode 100644 index 0000000000..292b9db16f --- /dev/null +++ b/queue-6.18/i3c-dw-i3c-master-set-sir_reject-in-dat-on-device-at.patch @@ -0,0 +1,57 @@ +From ce114ab0f21499a962658c9de10b46f231236276 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 14:00:48 +0800 +Subject: i3c: dw-i3c-master: Set SIR_REJECT in DAT on device attach and + reattach + +From: Adrian Ng Ho Yin + +[ Upstream commit f311a05784634febd299f03476b80f3f18489767 ] + +The DesignWare I3C master controller ACKs IBIs as soon as a valid +Device Address Table (DAT) entry is present. This can create a race +between device attachment (after DAA) and the point where the client +driver enables IBIs via i3c_device_enable_ibi(). + +Set DEV_ADDR_TABLE_SIR_REJECT in the DAT entry during +attach_i3c_dev() and reattach_i3c_dev() so that IBIs are rejected +by default. The bit is managed thereafter by the existing +dw_i3c_master_set_sir_enabled() function, which clears it in +enable_ibi() after ENEC is issued, and restores it in disable_ibi() +after DISEC. + +Fixes: 1dd728f5d4d4 ("i3c: master: Add driver for Synopsys DesignWare IP") +Signed-off-by: Adrian Ng Ho Yin +Reviewed-by: Frank Li +Link: https://patch.msgid.link/53f5b8cbdd8af789ec38b95b02873f32f9182dd6.1770962368.git.adrianhoyin.ng@altera.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master/dw-i3c-master.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c +index c06595cb74010..41ddac1d49d5e 100644 +--- a/drivers/i3c/master/dw-i3c-master.c ++++ b/drivers/i3c/master/dw-i3c-master.c +@@ -1005,7 +1005,7 @@ static int dw_i3c_master_reattach_i3c_dev(struct i3c_dev_desc *dev, + master->free_pos &= ~BIT(pos); + } + +- writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(dev->info.dyn_addr), ++ writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(dev->info.dyn_addr) | DEV_ADDR_TABLE_SIR_REJECT, + master->regs + + DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); + +@@ -1034,7 +1034,7 @@ static int dw_i3c_master_attach_i3c_dev(struct i3c_dev_desc *dev) + master->free_pos &= ~BIT(pos); + i3c_dev_set_master_data(dev, data); + +- writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr), ++ writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr) | DEV_ADDR_TABLE_SIR_REJECT, + master->regs + + DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); + +-- +2.51.0 + diff --git a/queue-6.18/powerpc-perf-check-that-current-mm-is-alive-before-g.patch b/queue-6.18/powerpc-perf-check-that-current-mm-is-alive-before-g.patch new file mode 100644 index 0000000000..77709f0bc1 --- /dev/null +++ b/queue-6.18/powerpc-perf-check-that-current-mm-is-alive-before-g.patch @@ -0,0 +1,92 @@ +From f55428b73ee65e49b9eff30d6c2bbdc7b79ab6c4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Mar 2026 15:40:45 +0100 +Subject: powerpc, perf: Check that current->mm is alive before getting user + callchain + +From: Viktor Malik + +[ Upstream commit e9bbfb4bfa86c6b5515b868d6982ac60505d7e39 ] + +It may happen that mm is already released, which leads to kernel panic. +This adds the NULL check for current->mm, similarly to +commit 20afc60f892d ("x86, perf: Check that current->mm is alive before getting user callchain"). + +I was getting this panic when running a profiling BPF program +(profile.py from bcc-tools): + + [26215.051935] Kernel attempted to read user page (588) - exploit attempt? (uid: 0) + [26215.051950] BUG: Kernel NULL pointer dereference on read at 0x00000588 + [26215.051952] Faulting instruction address: 0xc00000000020fac0 + [26215.051957] Oops: Kernel access of bad area, sig: 11 [#1] + [...] + [26215.052049] Call Trace: + [26215.052050] [c000000061da6d30] [c00000000020fc10] perf_callchain_user_64+0x2d0/0x490 (unreliable) + [26215.052054] [c000000061da6dc0] [c00000000020f92c] perf_callchain_user+0x1c/0x30 + [26215.052057] [c000000061da6de0] [c0000000005ab2a0] get_perf_callchain+0x100/0x360 + [26215.052063] [c000000061da6e70] [c000000000573bc8] bpf_get_stackid+0x88/0xf0 + [26215.052067] [c000000061da6ea0] [c008000000042258] bpf_prog_16d4ab9ab662f669_do_perf_event+0xf8/0x274 + [...] + +In addition, move storing the top-level stack entry to generic +perf_callchain_user to make sure the top-evel entry is always captured, +even if current->mm is NULL. + +Fixes: 20002ded4d93 ("perf_counter: powerpc: Add callchain support") +Signed-off-by: Viktor Malik +Tested-by: Qiao Zhao +Tested-by: Venkat Rao Bagalkote +Reviewed-by: Saket Kumar Bhaskar +[Maddy: fixed message to avoid checkpatch format style error] +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/20260309144045.169427-1-vmalik@redhat.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/perf/callchain.c | 5 +++++ + arch/powerpc/perf/callchain_32.c | 1 - + arch/powerpc/perf/callchain_64.c | 1 - + 3 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c +index 26aa26482c9ac..992cc5c982144 100644 +--- a/arch/powerpc/perf/callchain.c ++++ b/arch/powerpc/perf/callchain.c +@@ -103,6 +103,11 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re + void + perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) + { ++ perf_callchain_store(entry, perf_arch_instruction_pointer(regs)); ++ ++ if (!current->mm) ++ return; ++ + if (!is_32bit_task()) + perf_callchain_user_64(entry, regs); + else +diff --git a/arch/powerpc/perf/callchain_32.c b/arch/powerpc/perf/callchain_32.c +index ddcc2d8aa64a5..0de21c5d272c2 100644 +--- a/arch/powerpc/perf/callchain_32.c ++++ b/arch/powerpc/perf/callchain_32.c +@@ -142,7 +142,6 @@ void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry, + next_ip = perf_arch_instruction_pointer(regs); + lr = regs->link; + sp = regs->gpr[1]; +- perf_callchain_store(entry, next_ip); + + while (entry->nr < entry->max_stack) { + fp = (unsigned int __user *) (unsigned long) sp; +diff --git a/arch/powerpc/perf/callchain_64.c b/arch/powerpc/perf/callchain_64.c +index 115d1c105e8a8..30fb61c5f0cb0 100644 +--- a/arch/powerpc/perf/callchain_64.c ++++ b/arch/powerpc/perf/callchain_64.c +@@ -77,7 +77,6 @@ void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry, + next_ip = perf_arch_instruction_pointer(regs); + lr = regs->link; + sp = regs->gpr[1]; +- perf_callchain_store(entry, next_ip); + + while (entry->nr < entry->max_stack) { + fp = (unsigned long __user *) sp; +-- +2.51.0 + diff --git a/queue-6.18/scsi-hisi_sas-fix-null-pointer-exception-during-user.patch b/queue-6.18/scsi-hisi_sas-fix-null-pointer-exception-during-user.patch new file mode 100644 index 0000000000..d618fec3dc --- /dev/null +++ b/queue-6.18/scsi-hisi_sas-fix-null-pointer-exception-during-user.patch @@ -0,0 +1,113 @@ +From 0fa858029bf19e72107c0ce74dbe84c0a53ec026 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Mar 2026 14:40:39 +0800 +Subject: scsi: hisi_sas: Fix NULL pointer exception during user_scan() + +From: Xingui Yang + +[ Upstream commit 8ddc0c26916574395447ebf4cff684314f6873a9 ] + +user_scan() invokes updated sas_user_scan() for channel 0, and if +successful, iteratively scans remaining channels (1 to shost->max_channel) +via scsi_scan_host_selected() in commit 37c4e72b0651 ("scsi: Fix +sas_user_scan() to handle wildcard and multi-channel scans"). However, +hisi_sas supports only one channel, and the current value of max_channel is +1. sas_user_scan() for channel 1 will trigger the following NULL pointer +exception: + +[ 441.554662] Unable to handle kernel NULL pointer dereference at virtual address 00000000000008b0 +[ 441.554699] Mem abort info: +[ 441.554710] ESR = 0x0000000096000004 +[ 441.554718] EC = 0x25: DABT (current EL), IL = 32 bits +[ 441.554723] SET = 0, FnV = 0 +[ 441.554726] EA = 0, S1PTW = 0 +[ 441.554730] FSC = 0x04: level 0 translation fault +[ 441.554735] Data abort info: +[ 441.554737] ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000 +[ 441.554742] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 +[ 441.554747] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 +[ 441.554752] user pgtable: 4k pages, 48-bit VAs, pgdp=00000828377a6000 +[ 441.554757] [00000000000008b0] pgd=0000000000000000, p4d=0000000000000000 +[ 441.554769] Internal error: Oops: 0000000096000004 [#1] SMP +[ 441.629589] Modules linked in: arm_spe_pmu arm_smmuv3_pmu tpm_tis_spi hisi_uncore_sllc_pmu hisi_uncore_pa_pmu hisi_uncore_l3c_pmu hisi_uncore_hha_pmu hisi_uncore_ddrc_pmu hisi_uncore_cpa_pmu hns3_pmu hisi_ptt hisi_pcie_pmu tpm_tis_core spidev spi_hisi_sfc_v3xx hisi_uncore_pmu spi_dw_mmio fuse hclge hclge_common hisi_sec2 hisi_hpre hisi_zip hisi_qm hns3 hisi_sas_v3_hw sm3_ce sbsa_gwdt hnae3 hisi_sas_main uacce hisi_dma i2c_hisi dm_mirror dm_region_hash dm_log dm_mod +[ 441.670819] CPU: 46 UID: 0 PID: 6994 Comm: bash Kdump: loaded Not tainted 7.0.0-rc2+ #84 PREEMPT +[ 441.691327] pstate: 81400009 (Nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--) +[ 441.698277] pc : sas_find_dev_by_rphy+0x44/0x118 +[ 441.702896] lr : sas_find_dev_by_rphy+0x3c/0x118 +[ 441.707502] sp : ffff80009abbba40 +[ 441.710805] x29: ffff80009abbba40 x28: ffff082819a40008 x27: ffff082810c37c08 +[ 441.717930] x26: ffff082810c37c28 x25: ffff082819a40290 x24: ffff082810c37c00 +[ 441.725054] x23: 0000000000000000 x22: 0000000000000001 x21: ffff082819a40000 +[ 441.732179] x20: ffff082819a40290 x19: 0000000000000000 x18: 0000000000000020 +[ 441.739304] x17: 0000000000000000 x16: ffffb5dad6bda690 x15: 00000000ffffffff +[ 441.746428] x14: ffff082814c3b26c x13: 00000000ffffffff x12: ffff082814c3b26a +[ 441.753553] x11: 00000000000000c0 x10: 000000000000003a x9 : ffffb5dad5ea94f4 +[ 441.760678] x8 : 000000000000003a x7 : ffff80009abbbab0 x6 : 0000000000000030 +[ 441.767802] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000 +[ 441.774926] x2 : ffff08280f35a300 x1 : ffffb5dad7127180 x0 : 0000000000000000 +[ 441.782053] Call trace: +[ 441.784488] sas_find_dev_by_rphy+0x44/0x118 (P) +[ 441.789095] sas_target_alloc+0x24/0xb0 +[ 441.792920] scsi_alloc_target+0x290/0x330 +[ 441.797010] __scsi_scan_target+0x88/0x258 +[ 441.801096] scsi_scan_channel+0x74/0xb8 +[ 441.805008] scsi_scan_host_selected+0x170/0x188 +[ 441.809615] sas_user_scan+0xfc/0x148 +[ 441.813267] store_scan+0x10c/0x180 +[ 441.816743] dev_attr_store+0x20/0x40 +[ 441.820398] sysfs_kf_write+0x84/0xa8 +[ 441.824054] kernfs_fop_write_iter+0x130/0x1c8 +[ 441.828487] vfs_write+0x2c0/0x370 +[ 441.831880] ksys_write+0x74/0x118 +[ 441.835271] __arm64_sys_write+0x24/0x38 +[ 441.839182] invoke_syscall+0x50/0x120 +[ 441.842919] el0_svc_common.constprop.0+0xc8/0xf0 +[ 441.847611] do_el0_svc+0x24/0x38 +[ 441.850913] el0_svc+0x38/0x158 +[ 441.854043] el0t_64_sync_handler+0xa0/0xe8 +[ 441.858214] el0t_64_sync+0x1ac/0x1b0 +[ 441.861865] Code: aa1303e0 97ff70a8 34ffff80 d10a4273 (f9445a75) +[ 441.867946] ---[ end trace 0000000000000000 ]--- + +Therefore, set max_channel to 0. + +Fixes: e21fe3a52692 ("scsi: hisi_sas: add initialisation for v3 pci-based controller") +Signed-off-by: Xingui Yang +Signed-off-by: Yihang Li +Link: https://patch.msgid.link/20260305064039.4096775-1-liyihang9@huawei.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 2 +- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 30a9c66126513..c2b082f1252c3 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -2578,7 +2578,7 @@ int hisi_sas_probe(struct platform_device *pdev, + shost->transportt = hisi_sas_stt; + shost->max_id = HISI_SAS_MAX_DEVICES; + shost->max_lun = ~0; +- shost->max_channel = 1; ++ shost->max_channel = 0; + shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN; + if (hisi_hba->hw->slot_index_alloc) { + shost->can_queue = HISI_SAS_MAX_COMMANDS; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 2f9e01717ef38..f69efc6494b8e 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -4993,7 +4993,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) + shost->transportt = hisi_sas_stt; + shost->max_id = HISI_SAS_MAX_DEVICES; + shost->max_lun = ~0; +- shost->max_channel = 1; ++ shost->max_channel = 0; + shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN; + shost->can_queue = HISI_SAS_UNRESERVED_IPTT; + shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT; +-- +2.51.0 + diff --git a/queue-6.18/scsi-ufs-core-fix-serror-in-ufshcd_rtc_work-during-u.patch b/queue-6.18/scsi-ufs-core-fix-serror-in-ufshcd_rtc_work-during-u.patch new file mode 100644 index 0000000000..c24725baa4 --- /dev/null +++ b/queue-6.18/scsi-ufs-core-fix-serror-in-ufshcd_rtc_work-during-u.patch @@ -0,0 +1,85 @@ +From b74eb1f39aa1d3bcc48c5c76844fcf59fcdd56b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Mar 2026 11:51:28 +0800 +Subject: scsi: ufs: core: Fix SError in ufshcd_rtc_work() during UFS suspend + +From: Wang Shuaiwei + +[ Upstream commit b0bd84c39289ef6a6c3827dd52c875659291970a ] + +In __ufshcd_wl_suspend(), cancel_delayed_work_sync() is called to cancel +the UFS RTC work, but it is placed after ufshcd_vops_suspend(hba, pm_op, +POST_CHANGE). This creates a race condition where ufshcd_rtc_work() can +still be running while ufshcd_vops_suspend() is executing. When +UFSHCD_CAP_CLK_GATING is not supported, the condition +!hba->clk_gating.active_reqs is always true, causing ufshcd_update_rtc() +to be executed. Since ufshcd_vops_suspend() typically performs clock +gating operations, executing ufshcd_update_rtc() at that moment triggers +an SError. The kernel panic trace is as follows: + +Kernel panic - not syncing: Asynchronous SError Interrupt +Call trace: + dump_backtrace+0xec/0x128 + show_stack+0x18/0x28 + dump_stack_lvl+0x40/0xa0 + dump_stack+0x18/0x24 + panic+0x148/0x374 + nmi_panic+0x3c/0x8c + arm64_serror_panic+0x64/0x8c + do_serror+0xc4/0xc8 + el1h_64_error_handler+0x34/0x4c + el1h_64_error+0x68/0x6c + el1_interrupt+0x20/0x58 + el1h_64_irq_handler+0x18/0x24 + el1h_64_irq+0x68/0x6c + ktime_get+0xc4/0x12c + ufshcd_mcq_sq_stop+0x4c/0xec + ufshcd_mcq_sq_cleanup+0x64/0x1dc + ufshcd_clear_cmd+0x38/0x134 + ufshcd_issue_dev_cmd+0x298/0x4d0 + ufshcd_exec_dev_cmd+0x1a4/0x1c4 + ufshcd_query_attr+0xbc/0x19c + ufshcd_rtc_work+0x10c/0x1c8 + process_scheduled_works+0x1c4/0x45c + worker_thread+0x32c/0x3e8 + kthread+0x120/0x1d8 + ret_from_fork+0x10/0x20 + +Fix this by moving cancel_delayed_work_sync() before the call to +ufshcd_vops_suspend(hba, pm_op, PRE_CHANGE), ensuring the UFS RTC work is +fully completed or cancelled at that point. + +Cc: Bean Huo +Fixes: 6bf999e0eb41 ("scsi: ufs: core: Add UFS RTC support") +Reviewed-by: Bart Van Assche +Signed-off-by: Wang Shuaiwei +Link: https://patch.msgid.link/20260307035128.3419687-1-wangshuaiwei1@xiaomi.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/ufs/core/ufshcd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c +index fe1425ea6718f..5371f173e28b9 100644 +--- a/drivers/ufs/core/ufshcd.c ++++ b/drivers/ufs/core/ufshcd.c +@@ -9925,6 +9925,7 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) + } + + flush_work(&hba->eeh_work); ++ cancel_delayed_work_sync(&hba->ufs_rtc_update_work); + + ret = ufshcd_vops_suspend(hba, pm_op, PRE_CHANGE); + if (ret) +@@ -9979,7 +9980,6 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) + if (ret) + goto set_link_active; + +- cancel_delayed_work_sync(&hba->ufs_rtc_update_work); + goto out; + + set_link_active: +-- +2.51.0 + diff --git a/queue-6.18/series b/queue-6.18/series index 3c60999982..724f4e4494 100644 --- a/queue-6.18/series +++ b/queue-6.18/series @@ -153,3 +153,9 @@ revert-usb-gadget-u_ether-add-auto-cleanup-helper-for-freeing-net_device.patch revert-usb-gadget-f_ncm-align-net_device-lifecycle-with-bind-unbind.patch revert-usb-gadget-u_ether-add-gether_opts-for-config-caching.patch usb-gadget-f_ncm-fix-net_device-lifecycle-with-device_move.patch +alsa-usb-audio-improve-focusrite-sample-rate-filteri.patch +time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch +i3c-dw-i3c-master-set-sir_reject-in-dat-on-device-at.patch +powerpc-perf-check-that-current-mm-is-alive-before-g.patch +scsi-ufs-core-fix-serror-in-ufshcd_rtc_work-during-u.patch +scsi-hisi_sas-fix-null-pointer-exception-during-user.patch diff --git a/queue-6.18/time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch b/queue-6.18/time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch new file mode 100644 index 0000000000..3bf8cc1156 --- /dev/null +++ b/queue-6.18/time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch @@ -0,0 +1,39 @@ +From b35d9dd7d18c6e1460331e2dec2f88f9572f49be Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Mar 2026 21:24:03 -0500 +Subject: time/jiffies: Mark jiffies_64_to_clock_t() notrace + +From: Steven Rostedt + +[ Upstream commit 755a648e78f12574482d4698d877375793867fa1 ] + +The trace_clock_jiffies() function that handles the "uptime" clock for +tracing calls jiffies_64_to_clock_t(). This causes the function tracer to +constantly recurse when the tracing clock is set to "uptime". Mark it +notrace to prevent unnecessary recursion when using the "uptime" clock. + +Fixes: 58d4e21e50ff3 ("tracing: Fix wraparound problems in "uptime" trace clock") +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Thomas Gleixner +Link: https://patch.msgid.link/20260306212403.72270bb2@robin +Signed-off-by: Sasha Levin +--- + kernel/time/time.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/time/time.c b/kernel/time/time.c +index 0ba8e3c50d625..155cf7def9146 100644 +--- a/kernel/time/time.c ++++ b/kernel/time/time.c +@@ -702,7 +702,7 @@ EXPORT_SYMBOL(clock_t_to_jiffies); + * + * Return: jiffies_64 value converted to 64-bit "clock_t" (CLOCKS_PER_SEC) + */ +-u64 jiffies_64_to_clock_t(u64 x) ++notrace u64 jiffies_64_to_clock_t(u64 x) + { + #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 + # if HZ < USER_HZ +-- +2.51.0 + diff --git a/queue-6.19/alsa-usb-audio-improve-focusrite-sample-rate-filteri.patch b/queue-6.19/alsa-usb-audio-improve-focusrite-sample-rate-filteri.patch new file mode 100644 index 0000000000..d8f5525ca4 --- /dev/null +++ b/queue-6.19/alsa-usb-audio-improve-focusrite-sample-rate-filteri.patch @@ -0,0 +1,149 @@ +From 46ec6adcab5355d772539dcda12710e3c217b7d0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 21 Feb 2026 02:33:45 +1030 +Subject: ALSA: usb-audio: Improve Focusrite sample rate filtering + +From: Geoffrey D. Bennett + +[ Upstream commit 24d2d3c5f94007a5a0554065ab7349bb69e28bcb ] + +Replace the bLength == 10 max_rate check in +focusrite_valid_sample_rate() with filtering that also examines the +bmControls VAL_ALT_SETTINGS bit. + +When VAL_ALT_SETTINGS is readable, the device uses strict +per-altsetting rate filtering (only the highest rate pair for that +altsetting is valid). When it is not readable, all rates up to +max_rate are valid. + +For devices without the bLength == 10 Format Type descriptor extension +but with VAL_ALT_SETTINGS readable and multiple altsettings (only seen +in Scarlett 18i8 3rd Gen playback), fall back to the Focusrite +convention: alt 1 = 48kHz, alt 2 = 96kHz, alt 3 = 192kHz. + +This produces correct rate tables for all tested Focusrite devices +(all Scarlett 2nd, 3rd, and 4th Gen, Clarett+, and Vocaster) using +only USB descriptors, allowing QUIRK_FLAG_VALIDATE_RATES to be removed +for Focusrite in the next commit. + +Signed-off-by: Geoffrey D. Bennett +Signed-off-by: Takashi Iwai +Link: https://patch.msgid.link/7e18c1f393a6ecb6fc75dd867a2c4dbe135e3e22.1771594828.git.g@b4.vu +Signed-off-by: Sasha Levin +--- + sound/usb/format.c | 70 ++++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 65 insertions(+), 5 deletions(-) + +diff --git a/sound/usb/format.c b/sound/usb/format.c +index 64cfe4a9d8cdf..1207c507882ad 100644 +--- a/sound/usb/format.c ++++ b/sound/usb/format.c +@@ -305,17 +305,48 @@ static bool s1810c_valid_sample_rate(struct audioformat *fp, + } + + /* +- * Many Focusrite devices supports a limited set of sampling rates per +- * altsetting. Maximum rate is exposed in the last 4 bytes of Format Type +- * descriptor which has a non-standard bLength = 10. ++ * Focusrite devices use rate pairs: 44100/48000, 88200/96000, and ++ * 176400/192000. Return true if rate is in the pair for max_rate. ++ */ ++static bool focusrite_rate_pair(unsigned int rate, ++ unsigned int max_rate) ++{ ++ switch (max_rate) { ++ case 48000: return rate == 44100 || rate == 48000; ++ case 96000: return rate == 88200 || rate == 96000; ++ case 192000: return rate == 176400 || rate == 192000; ++ default: return true; ++ } ++} ++ ++/* ++ * Focusrite devices report all supported rates in a single clock ++ * source but only a subset is valid per altsetting. ++ * ++ * Detection uses two descriptor features: ++ * ++ * 1. Format Type descriptor bLength == 10: non-standard extension ++ * with max sample rate in bytes 6..9. ++ * ++ * 2. bmControls VAL_ALT_SETTINGS readable bit: when set, the device ++ * only supports the highest rate pair for that altsetting, and when ++ * clear, all rates up to max_rate are valid. ++ * ++ * For devices without the bLength == 10 extension but with ++ * VAL_ALT_SETTINGS readable and multiple altsettings (only seen in ++ * Scarlett 18i8 3rd Gen playback), fall back to the Focusrite ++ * convention: alt 1 = 48kHz, alt 2 = 96kHz, alt 3 = 192kHz. + */ + static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip, + struct audioformat *fp, + unsigned int rate) + { ++ struct usb_interface *iface; + struct usb_host_interface *alts; ++ struct uac2_as_header_descriptor *as; + unsigned char *fmt; + unsigned int max_rate; ++ bool val_alt; + + alts = snd_usb_get_host_interface(chip, fp->iface, fp->altsetting); + if (!alts) +@@ -326,9 +357,21 @@ static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip, + if (!fmt) + return true; + ++ as = snd_usb_find_csint_desc(alts->extra, alts->extralen, ++ NULL, UAC_AS_GENERAL); ++ if (!as) ++ return true; ++ ++ val_alt = uac_v2v3_control_is_readable(as->bmControls, ++ UAC2_AS_VAL_ALT_SETTINGS); ++ + if (fmt[0] == 10) { /* bLength */ + max_rate = combine_quad(&fmt[6]); + ++ if (val_alt) ++ return focusrite_rate_pair(rate, max_rate); ++ ++ /* No val_alt: rates fall through from higher */ + switch (max_rate) { + case 192000: + if (rate == 176400 || rate == 192000) +@@ -344,12 +387,29 @@ static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip, + usb_audio_info(chip, + "%u:%d : unexpected max rate: %u\n", + fp->iface, fp->altsetting, max_rate); +- + return true; + } + } + +- return true; ++ if (!val_alt) ++ return true; ++ ++ /* Multi-altsetting device with val_alt but no max_rate ++ * in the format descriptor. Use Focusrite convention: ++ * alt 1 = 48kHz, alt 2 = 96kHz, alt 3 = 192kHz. ++ */ ++ iface = usb_ifnum_to_if(chip->dev, fp->iface); ++ if (!iface || iface->num_altsetting <= 2) ++ return true; ++ ++ switch (fp->altsetting) { ++ case 1: max_rate = 48000; break; ++ case 2: max_rate = 96000; break; ++ case 3: max_rate = 192000; break; ++ default: return true; ++ } ++ ++ return focusrite_rate_pair(rate, max_rate); + } + + /* +-- +2.51.0 + diff --git a/queue-6.19/i3c-dw-i3c-master-set-sir_reject-in-dat-on-device-at.patch b/queue-6.19/i3c-dw-i3c-master-set-sir_reject-in-dat-on-device-at.patch new file mode 100644 index 0000000000..422785dd85 --- /dev/null +++ b/queue-6.19/i3c-dw-i3c-master-set-sir_reject-in-dat-on-device-at.patch @@ -0,0 +1,57 @@ +From 8a6c793c597555a97c6110094c13f2b20c502e17 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 14:00:48 +0800 +Subject: i3c: dw-i3c-master: Set SIR_REJECT in DAT on device attach and + reattach + +From: Adrian Ng Ho Yin + +[ Upstream commit f311a05784634febd299f03476b80f3f18489767 ] + +The DesignWare I3C master controller ACKs IBIs as soon as a valid +Device Address Table (DAT) entry is present. This can create a race +between device attachment (after DAA) and the point where the client +driver enables IBIs via i3c_device_enable_ibi(). + +Set DEV_ADDR_TABLE_SIR_REJECT in the DAT entry during +attach_i3c_dev() and reattach_i3c_dev() so that IBIs are rejected +by default. The bit is managed thereafter by the existing +dw_i3c_master_set_sir_enabled() function, which clears it in +enable_ibi() after ENEC is issued, and restores it in disable_ibi() +after DISEC. + +Fixes: 1dd728f5d4d4 ("i3c: master: Add driver for Synopsys DesignWare IP") +Signed-off-by: Adrian Ng Ho Yin +Reviewed-by: Frank Li +Link: https://patch.msgid.link/53f5b8cbdd8af789ec38b95b02873f32f9182dd6.1770962368.git.adrianhoyin.ng@altera.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master/dw-i3c-master.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c +index 4033bc16677ff..f9b981abd10c5 100644 +--- a/drivers/i3c/master/dw-i3c-master.c ++++ b/drivers/i3c/master/dw-i3c-master.c +@@ -1010,7 +1010,7 @@ static int dw_i3c_master_reattach_i3c_dev(struct i3c_dev_desc *dev, + master->free_pos &= ~BIT(pos); + } + +- writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(dev->info.dyn_addr), ++ writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(dev->info.dyn_addr) | DEV_ADDR_TABLE_SIR_REJECT, + master->regs + + DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); + +@@ -1039,7 +1039,7 @@ static int dw_i3c_master_attach_i3c_dev(struct i3c_dev_desc *dev) + master->free_pos &= ~BIT(pos); + i3c_dev_set_master_data(dev, data); + +- writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr), ++ writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr) | DEV_ADDR_TABLE_SIR_REJECT, + master->regs + + DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); + +-- +2.51.0 + diff --git a/queue-6.19/irqchip-riscv-aplic-do-not-clear-acpi-dependencies-o.patch b/queue-6.19/irqchip-riscv-aplic-do-not-clear-acpi-dependencies-o.patch new file mode 100644 index 0000000000..647a1e1c8a --- /dev/null +++ b/queue-6.19/irqchip-riscv-aplic-do-not-clear-acpi-dependencies-o.patch @@ -0,0 +1,61 @@ +From be9314253d9c7bb0f74022f63e0bcecbcc4e0688 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Mar 2026 14:16:00 +0800 +Subject: irqchip/riscv-aplic: Do not clear ACPI dependencies on probe failure + +From: Jessica Liu + +[ Upstream commit 620b6ded72a7f0f77be6ec44d0462bb85729ab7a ] + +aplic_probe() calls acpi_dev_clear_dependencies() unconditionally at the +end, even when the preceding setup (MSI or direct mode) has failed. This is +incorrect because if the device failed to probe, it should not be +considered as active and should not clear dependencies for other devices +waiting on it. + +Fix this by returning immediately when the setup fails, skipping the ACPI +dependency cleanup. Also, explicitly return 0 on success instead of relying +on the value of 'rc' to make the success path clear. + +Fixes: 5122e380c23b ("irqchip/riscv-aplic: Add ACPI support") +Signed-off-by: Jessica Liu +Signed-off-by: Thomas Gleixner +Link: https://patch.msgid.link/20260310141600411Fu8H8-GXOOgKISU48Tjgx@zte.com.cn +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-riscv-aplic-main.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/drivers/irqchip/irq-riscv-aplic-main.c b/drivers/irqchip/irq-riscv-aplic-main.c +index 4495ca26abf57..8775f188ea4fc 100644 +--- a/drivers/irqchip/irq-riscv-aplic-main.c ++++ b/drivers/irqchip/irq-riscv-aplic-main.c +@@ -372,18 +372,21 @@ static int aplic_probe(struct platform_device *pdev) + rc = aplic_msi_setup(dev, regs); + else + rc = aplic_direct_setup(dev, regs); +- if (rc) ++ ++ if (rc) { + dev_err_probe(dev, rc, "failed to setup APLIC in %s mode\n", + msi_mode ? "MSI" : "direct"); +- else +- register_syscore(&aplic_syscore); ++ return rc; ++ } ++ ++ register_syscore(&aplic_syscore); + + #ifdef CONFIG_ACPI + if (!acpi_disabled) + acpi_dev_clear_dependencies(ACPI_COMPANION(dev)); + #endif + +- return rc; ++ return 0; + } + + static const struct of_device_id aplic_match[] = { +-- +2.51.0 + diff --git a/queue-6.19/irqchip-riscv-aplic-preserve-aplic-states-across-sus.patch b/queue-6.19/irqchip-riscv-aplic-preserve-aplic-states-across-sus.patch new file mode 100644 index 0000000000..2436c09162 --- /dev/null +++ b/queue-6.19/irqchip-riscv-aplic-preserve-aplic-states-across-sus.patch @@ -0,0 +1,328 @@ +From c120aae874b512314c1113a31e45124fbccbc0b7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Dec 2025 14:07:41 +0800 +Subject: irqchip/riscv-aplic: Preserve APLIC states across suspend/resume + +From: Nick Hu + +[ Upstream commit 95a8ddde36601d0a645475fb080ed118db59c8c3 ] + +The APLIC states might be reset when the platform enters a low power +state, but the register states are not being preserved and restored, +which prevents interrupt delivery after the platform resumes. +Solve this by adding a syscore ops and a power management notifier to +preserve and restore the APLIC states on suspend and resume. + +[ tglx: Folded the build fix provided by Geert ] + +Signed-off-by: Nick Hu +Signed-off-by: Thomas Gleixner +Reviewed-by: Yong-Xuan Wang +Reviewed-by: Cyan Yang +Reviewed-by: Nutty Liu +Reviewed-by: Anup Patel +Link: https://patch.msgid.link/20251202-preserve-aplic-imsic-v3-2-1844fbf1fe92@sifive.com +Stable-dep-of: 620b6ded72a7 ("irqchip/riscv-aplic: Do not clear ACPI dependencies on probe failure") +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-riscv-aplic-direct.c | 10 ++ + drivers/irqchip/irq-riscv-aplic-main.c | 170 ++++++++++++++++++++++- + drivers/irqchip/irq-riscv-aplic-main.h | 19 +++ + 3 files changed, 198 insertions(+), 1 deletion(-) + +diff --git a/drivers/irqchip/irq-riscv-aplic-direct.c b/drivers/irqchip/irq-riscv-aplic-direct.c +index c2a75bf3d20c6..5a9650225dd80 100644 +--- a/drivers/irqchip/irq-riscv-aplic-direct.c ++++ b/drivers/irqchip/irq-riscv-aplic-direct.c +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -171,6 +172,15 @@ static void aplic_idc_set_delivery(struct aplic_idc *idc, bool en) + writel(de, idc->regs + APLIC_IDC_IDELIVERY); + } + ++void aplic_direct_restore_states(struct aplic_priv *priv) ++{ ++ struct aplic_direct *direct = container_of(priv, struct aplic_direct, priv); ++ int cpu; ++ ++ for_each_cpu(cpu, &direct->lmask) ++ aplic_idc_set_delivery(per_cpu_ptr(&aplic_idcs, cpu), true); ++} ++ + static int aplic_direct_dying_cpu(unsigned int cpu) + { + if (aplic_direct_parent_irq) +diff --git a/drivers/irqchip/irq-riscv-aplic-main.c b/drivers/irqchip/irq-riscv-aplic-main.c +index 93e7c51f944ab..4495ca26abf57 100644 +--- a/drivers/irqchip/irq-riscv-aplic-main.c ++++ b/drivers/irqchip/irq-riscv-aplic-main.c +@@ -12,10 +12,169 @@ + #include + #include + #include ++#include ++#include + #include ++#include + + #include "irq-riscv-aplic-main.h" + ++static LIST_HEAD(aplics); ++ ++static void aplic_restore_states(struct aplic_priv *priv) ++{ ++ struct aplic_saved_regs *saved_regs = &priv->saved_hw_regs; ++ struct aplic_src_ctrl *srcs; ++ void __iomem *regs; ++ u32 nr_irqs, i; ++ ++ regs = priv->regs; ++ writel(saved_regs->domaincfg, regs + APLIC_DOMAINCFG); ++#ifdef CONFIG_RISCV_M_MODE ++ writel(saved_regs->msiaddr, regs + APLIC_xMSICFGADDR); ++ writel(saved_regs->msiaddrh, regs + APLIC_xMSICFGADDRH); ++#endif ++ /* ++ * The sourcecfg[i] has to be restored prior to the target[i], interrupt-pending and ++ * interrupt-enable bits. The AIA specification states that "Whenever interrupt source i is ++ * inactive in an interrupt domain, the corresponding interrupt-pending and interrupt-enable ++ * bits within the domain are read-only zeros, and register target[i] is also read-only ++ * zero." ++ */ ++ nr_irqs = priv->nr_irqs; ++ for (i = 0; i < nr_irqs; i++) { ++ srcs = &priv->saved_hw_regs.srcs[i]; ++ writel(srcs->sourcecfg, regs + APLIC_SOURCECFG_BASE + i * sizeof(u32)); ++ writel(srcs->target, regs + APLIC_TARGET_BASE + i * sizeof(u32)); ++ } ++ ++ for (i = 0; i <= nr_irqs; i += 32) { ++ srcs = &priv->saved_hw_regs.srcs[i]; ++ writel(-1U, regs + APLIC_CLRIE_BASE + (i / 32) * sizeof(u32)); ++ writel(srcs->ie, regs + APLIC_SETIE_BASE + (i / 32) * sizeof(u32)); ++ ++ /* Re-trigger the interrupts if it forwards interrupts to target harts by MSIs */ ++ if (!priv->nr_idcs) ++ writel(readl(regs + APLIC_CLRIP_BASE + (i / 32) * sizeof(u32)), ++ regs + APLIC_SETIP_BASE + (i / 32) * sizeof(u32)); ++ } ++ ++ if (priv->nr_idcs) ++ aplic_direct_restore_states(priv); ++} ++ ++static void aplic_save_states(struct aplic_priv *priv) ++{ ++ struct aplic_src_ctrl *srcs; ++ void __iomem *regs; ++ u32 i, nr_irqs; ++ ++ regs = priv->regs; ++ nr_irqs = priv->nr_irqs; ++ /* The valid interrupt source IDs range from 1 to N, where N is priv->nr_irqs */ ++ for (i = 0; i < nr_irqs; i++) { ++ srcs = &priv->saved_hw_regs.srcs[i]; ++ srcs->target = readl(regs + APLIC_TARGET_BASE + i * sizeof(u32)); ++ ++ if (i % 32) ++ continue; ++ ++ srcs->ie = readl(regs + APLIC_SETIE_BASE + (i / 32) * sizeof(u32)); ++ } ++ ++ /* Save the nr_irqs bit if needed */ ++ if (!(nr_irqs % 32)) { ++ srcs = &priv->saved_hw_regs.srcs[nr_irqs]; ++ srcs->ie = readl(regs + APLIC_SETIE_BASE + (nr_irqs / 32) * sizeof(u32)); ++ } ++} ++ ++static int aplic_syscore_suspend(void *data) ++{ ++ struct aplic_priv *priv; ++ ++ list_for_each_entry(priv, &aplics, head) ++ aplic_save_states(priv); ++ ++ return 0; ++} ++ ++static void aplic_syscore_resume(void *data) ++{ ++ struct aplic_priv *priv; ++ ++ list_for_each_entry(priv, &aplics, head) ++ aplic_restore_states(priv); ++} ++ ++static struct syscore_ops aplic_syscore_ops = { ++ .suspend = aplic_syscore_suspend, ++ .resume = aplic_syscore_resume, ++}; ++ ++static struct syscore aplic_syscore = { ++ .ops = &aplic_syscore_ops, ++}; ++ ++static int aplic_pm_notifier(struct notifier_block *nb, unsigned long action, void *data) ++{ ++ struct aplic_priv *priv = container_of(nb, struct aplic_priv, genpd_nb); ++ ++ switch (action) { ++ case GENPD_NOTIFY_PRE_OFF: ++ aplic_save_states(priv); ++ break; ++ case GENPD_NOTIFY_ON: ++ aplic_restore_states(priv); ++ break; ++ default: ++ break; ++ } ++ ++ return 0; ++} ++ ++static void aplic_pm_remove(void *data) ++{ ++ struct aplic_priv *priv = data; ++ struct device *dev = priv->dev; ++ ++ list_del(&priv->head); ++ if (dev->pm_domain) ++ dev_pm_genpd_remove_notifier(dev); ++} ++ ++static int aplic_pm_add(struct device *dev, struct aplic_priv *priv) ++{ ++ struct aplic_src_ctrl *srcs; ++ int ret; ++ ++ srcs = devm_kzalloc(dev, (priv->nr_irqs + 1) * sizeof(*srcs), GFP_KERNEL); ++ if (!srcs) ++ return -ENOMEM; ++ ++ priv->saved_hw_regs.srcs = srcs; ++ list_add(&priv->head, &aplics); ++ if (dev->pm_domain) { ++ priv->genpd_nb.notifier_call = aplic_pm_notifier; ++ ret = dev_pm_genpd_add_notifier(dev, &priv->genpd_nb); ++ if (ret) ++ goto remove_head; ++ ++ ret = devm_pm_runtime_enable(dev); ++ if (ret) ++ goto remove_notifier; ++ } ++ ++ return devm_add_action_or_reset(dev, aplic_pm_remove, priv); ++ ++remove_notifier: ++ dev_pm_genpd_remove_notifier(dev); ++remove_head: ++ list_del(&priv->head); ++ return ret; ++} ++ + void aplic_irq_unmask(struct irq_data *d) + { + struct aplic_priv *priv = irq_data_get_irq_chip_data(d); +@@ -60,6 +219,8 @@ int aplic_irq_set_type(struct irq_data *d, unsigned int type) + sourcecfg += (d->hwirq - 1) * sizeof(u32); + writel(val, sourcecfg); + ++ priv->saved_hw_regs.srcs[d->hwirq - 1].sourcecfg = val; ++ + return 0; + } + +@@ -82,6 +243,7 @@ int aplic_irqdomain_translate(struct irq_fwspec *fwspec, u32 gsi_base, + + void aplic_init_hw_global(struct aplic_priv *priv, bool msi_mode) + { ++ struct aplic_saved_regs *saved_regs = &priv->saved_hw_regs; + u32 val; + #ifdef CONFIG_RISCV_M_MODE + u32 valh; +@@ -95,6 +257,8 @@ void aplic_init_hw_global(struct aplic_priv *priv, bool msi_mode) + valh |= FIELD_PREP(APLIC_xMSICFGADDRH_HHXS, priv->msicfg.hhxs); + writel(val, priv->regs + APLIC_xMSICFGADDR); + writel(valh, priv->regs + APLIC_xMSICFGADDRH); ++ saved_regs->msiaddr = val; ++ saved_regs->msiaddrh = valh; + } + #endif + +@@ -106,6 +270,8 @@ void aplic_init_hw_global(struct aplic_priv *priv, bool msi_mode) + writel(val, priv->regs + APLIC_DOMAINCFG); + if (readl(priv->regs + APLIC_DOMAINCFG) != val) + dev_warn(priv->dev, "unable to write 0x%x in domaincfg\n", val); ++ ++ saved_regs->domaincfg = val; + } + + static void aplic_init_hw_irqs(struct aplic_priv *priv) +@@ -176,7 +342,7 @@ int aplic_setup_priv(struct aplic_priv *priv, struct device *dev, void __iomem * + /* Setup initial state APLIC interrupts */ + aplic_init_hw_irqs(priv); + +- return 0; ++ return aplic_pm_add(dev, priv); + } + + static int aplic_probe(struct platform_device *pdev) +@@ -209,6 +375,8 @@ static int aplic_probe(struct platform_device *pdev) + if (rc) + dev_err_probe(dev, rc, "failed to setup APLIC in %s mode\n", + msi_mode ? "MSI" : "direct"); ++ else ++ register_syscore(&aplic_syscore); + + #ifdef CONFIG_ACPI + if (!acpi_disabled) +diff --git a/drivers/irqchip/irq-riscv-aplic-main.h b/drivers/irqchip/irq-riscv-aplic-main.h +index b0ad8cde69b13..2d8ad7138541a 100644 +--- a/drivers/irqchip/irq-riscv-aplic-main.h ++++ b/drivers/irqchip/irq-riscv-aplic-main.h +@@ -23,7 +23,25 @@ struct aplic_msicfg { + u32 lhxw; + }; + ++struct aplic_src_ctrl { ++ u32 sourcecfg; ++ u32 target; ++ u32 ie; ++}; ++ ++struct aplic_saved_regs { ++ u32 domaincfg; ++#ifdef CONFIG_RISCV_M_MODE ++ u32 msiaddr; ++ u32 msiaddrh; ++#endif ++ struct aplic_src_ctrl *srcs; ++}; ++ + struct aplic_priv { ++ struct list_head head; ++ struct notifier_block genpd_nb; ++ struct aplic_saved_regs saved_hw_regs; + struct device *dev; + u32 gsi_base; + u32 nr_irqs; +@@ -40,6 +58,7 @@ int aplic_irqdomain_translate(struct irq_fwspec *fwspec, u32 gsi_base, + unsigned long *hwirq, unsigned int *type); + void aplic_init_hw_global(struct aplic_priv *priv, bool msi_mode); + int aplic_setup_priv(struct aplic_priv *priv, struct device *dev, void __iomem *regs); ++void aplic_direct_restore_states(struct aplic_priv *priv); + int aplic_direct_setup(struct device *dev, void __iomem *regs); + #ifdef CONFIG_RISCV_APLIC_MSI + int aplic_msi_setup(struct device *dev, void __iomem *regs); +-- +2.51.0 + diff --git a/queue-6.19/irqchip-riscv-aplic-register-syscore-operations-only.patch b/queue-6.19/irqchip-riscv-aplic-register-syscore-operations-only.patch new file mode 100644 index 0000000000..ae95d97f68 --- /dev/null +++ b/queue-6.19/irqchip-riscv-aplic-register-syscore-operations-only.patch @@ -0,0 +1,67 @@ +From 02d1c38f978b50cc6d5bec66825dd931f9177fcc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Mar 2026 14:17:31 +0800 +Subject: irqchip/riscv-aplic: Register syscore operations only once + +From: Jessica Liu + +[ Upstream commit b330fbfd34d7624bec62b99ad88dba2614326a19 ] + +Since commit 95a8ddde3660 ("irqchip/riscv-aplic: Preserve APLIC +states across suspend/resume"), when multiple NUMA nodes exist +and AIA is not configured as "none", aplic_probe() is called +multiple times. This leads to register_syscore(&aplic_syscore) +being invoked repeatedly, causing the following Oops: + + list_add double add: new=ffffffffb91461f0, prev=ffffffffb91461f0, next=ffffffffb915c408. + [] __list_add_valid_or_report+0x60/0xc0 + [] register_syscore+0x3e/0x70 + [] aplic_probe+0xc6/0x112 + +Fix this by registering syscore operations only once, using a static +variable aplic_syscore_registered to track registration. + +[ tglx: Trim backtrace properly ] + +Fixes: 95a8ddde3660 ("irqchip/riscv-aplic: Preserve APLIC states across suspend/resume") +Signed-off-by: Jessica Liu +Signed-off-by: Thomas Gleixner +Link: https://patch.msgid.link/20260310141731145xMwLsyvXl9Gw-m6A4VRYj@zte.com.cn +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-riscv-aplic-main.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/drivers/irqchip/irq-riscv-aplic-main.c b/drivers/irqchip/irq-riscv-aplic-main.c +index 8775f188ea4fc..9f53979b69625 100644 +--- a/drivers/irqchip/irq-riscv-aplic-main.c ++++ b/drivers/irqchip/irq-riscv-aplic-main.c +@@ -116,6 +116,16 @@ static struct syscore aplic_syscore = { + .ops = &aplic_syscore_ops, + }; + ++static bool aplic_syscore_registered __ro_after_init; ++ ++static void aplic_syscore_init(void) ++{ ++ if (!aplic_syscore_registered) { ++ register_syscore(&aplic_syscore); ++ aplic_syscore_registered = true; ++ } ++} ++ + static int aplic_pm_notifier(struct notifier_block *nb, unsigned long action, void *data) + { + struct aplic_priv *priv = container_of(nb, struct aplic_priv, genpd_nb); +@@ -379,7 +389,7 @@ static int aplic_probe(struct platform_device *pdev) + return rc; + } + +- register_syscore(&aplic_syscore); ++ aplic_syscore_init(); + + #ifdef CONFIG_ACPI + if (!acpi_disabled) +-- +2.51.0 + diff --git a/queue-6.19/objtool-fix-another-stack-overflow-in-validate_branc.patch b/queue-6.19/objtool-fix-another-stack-overflow-in-validate_branc.patch new file mode 100644 index 0000000000..86421d8063 --- /dev/null +++ b/queue-6.19/objtool-fix-another-stack-overflow-in-validate_branc.patch @@ -0,0 +1,79 @@ +From eb7be45480144dea4b2bb966847ad5c90b2c8918 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Mar 2026 10:28:14 -0800 +Subject: objtool: Fix another stack overflow in validate_branch() + +From: Josh Poimboeuf + +[ Upstream commit 9a73f085dc91980ab7fcc5e9716f4449424b3b59 ] + +The insn state is getting saved on the stack twice for each recursive +iteration. No need for that, once is enough. + +Fixes the following reported stack overflow: + + drivers/scsi/qla2xxx/qla_dbg.o: error: SIGSEGV: objtool stack overflow! + Segmentation fault + +Fixes: 70589843b36f ("objtool: Add option to trace function validation") +Reported-by: Arnd Bergmann +Closes: https://lore.kernel.org/90956545-2066-46e3-b547-10c884582eb0@app.fastmail.com +Link: https://patch.msgid.link/8b97f62d083457f3b0a29a424275f7957dd3372f.1772821683.git.jpoimboe@kernel.org +Signed-off-by: Josh Poimboeuf +Signed-off-by: Sasha Levin +--- + tools/objtool/check.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/tools/objtool/check.c b/tools/objtool/check.c +index 37ec0d757e9b1..eba35bb8c0bdf 100644 +--- a/tools/objtool/check.c ++++ b/tools/objtool/check.c +@@ -3694,7 +3694,7 @@ static void checksum_update_insn(struct objtool_file *file, struct symbol *func, + static int validate_branch(struct objtool_file *file, struct symbol *func, + struct instruction *insn, struct insn_state state); + static int do_validate_branch(struct objtool_file *file, struct symbol *func, +- struct instruction *insn, struct insn_state state); ++ struct instruction *insn, struct insn_state *state); + + static int validate_insn(struct objtool_file *file, struct symbol *func, + struct instruction *insn, struct insn_state *statep, +@@ -3959,7 +3959,7 @@ static int validate_insn(struct objtool_file *file, struct symbol *func, + * tools/objtool/Documentation/objtool.txt. + */ + static int do_validate_branch(struct objtool_file *file, struct symbol *func, +- struct instruction *insn, struct insn_state state) ++ struct instruction *insn, struct insn_state *state) + { + struct instruction *next_insn, *prev_insn = NULL; + bool dead_end; +@@ -3990,7 +3990,7 @@ static int do_validate_branch(struct objtool_file *file, struct symbol *func, + return 1; + } + +- ret = validate_insn(file, func, insn, &state, prev_insn, next_insn, ++ ret = validate_insn(file, func, insn, state, prev_insn, next_insn, + &dead_end); + + if (!insn->trace) { +@@ -4001,7 +4001,7 @@ static int do_validate_branch(struct objtool_file *file, struct symbol *func, + } + + if (!dead_end && !next_insn) { +- if (state.cfi.cfa.base == CFI_UNDEFINED) ++ if (state->cfi.cfa.base == CFI_UNDEFINED) + return 0; + if (file->ignore_unreachables) + return 0; +@@ -4026,7 +4026,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, + int ret; + + trace_depth_inc(); +- ret = do_validate_branch(file, func, insn, state); ++ ret = do_validate_branch(file, func, insn, &state); + trace_depth_dec(); + + return ret; +-- +2.51.0 + diff --git a/queue-6.19/objtool-fix-data-alignment-in-elf_add_data.patch b/queue-6.19/objtool-fix-data-alignment-in-elf_add_data.patch new file mode 100644 index 0000000000..c00498dad3 --- /dev/null +++ b/queue-6.19/objtool-fix-data-alignment-in-elf_add_data.patch @@ -0,0 +1,37 @@ +From 80c5fd8ce09e6154b9494ed6cfc984253eee1871 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Mar 2026 19:31:20 -0800 +Subject: objtool: Fix data alignment in elf_add_data() + +From: Josh Poimboeuf + +[ Upstream commit 356e4b2f5b80f757965f3f4d0219c81fca91b6f2 ] + +Any data added to a section needs to be aligned in accordance with the +section's sh_addralign value. Particularly strings added to a .str1.8 +section. Otherwise you may get some funky strings. + +Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffing object files") +Link: https://patch.msgid.link/d962fc0ca24fa0825cca8dad71932dccdd9312a9.1772681234.git.jpoimboe@kernel.org +Signed-off-by: Josh Poimboeuf +Signed-off-by: Sasha Levin +--- + tools/objtool/elf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c +index 2c02c7b492658..3da90686350d7 100644 +--- a/tools/objtool/elf.c ++++ b/tools/objtool/elf.c +@@ -1375,7 +1375,7 @@ void *elf_add_data(struct elf *elf, struct section *sec, const void *data, size_ + memcpy(sec->data->d_buf, data, size); + + sec->data->d_size = size; +- sec->data->d_align = 1; ++ sec->data->d_align = sec->sh.sh_addralign; + + offset = ALIGN(sec->sh.sh_size, sec->sh.sh_addralign); + sec->sh.sh_size = offset + size; +-- +2.51.0 + diff --git a/queue-6.19/objtool-klp-fix-detection-of-corrupt-static-branch-c.patch b/queue-6.19/objtool-klp-fix-detection-of-corrupt-static-branch-c.patch new file mode 100644 index 0000000000..0384e46351 --- /dev/null +++ b/queue-6.19/objtool-klp-fix-detection-of-corrupt-static-branch-c.patch @@ -0,0 +1,58 @@ +From 40168c3f0a3ab2aab1b2ec8e0c51ce4307cfcec9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 13:50:09 -0800 +Subject: objtool/klp: Fix detection of corrupt static branch/call entries + +From: Josh Poimboeuf + +[ Upstream commit f9fb44b0ecefc1f218db56661ed66d4e8d67317d ] + +Patching a function which references a static key living in a kernel +module is unsupported due to ordering issues inherent to late module +patching: + + 1) Load a livepatch module which has a __jump_table entry which needs + a klp reloc to reference static key K which lives in module M. + + 2) The __jump_table klp reloc does *not* get resolved because module M + is not yet loaded. + + 3) jump_label_add_module() corrupts memory (or causes a panic) when + dereferencing the uninitialized pointer to key K. + +validate_special_section_klp_reloc() intends to prevent that from ever +happening by catching it at build time. However, it incorrectly assumes +the special section entry's reloc symbol references have already been +converted from section symbols to object symbols, causing the validation +to miss corruption in extracted static branch/call table entries. + +Make sure the references have been properly converted before doing the +validation. + +Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffing object files") +Reported-by: Song Liu +Reviewed-and-tested-by: Song Liu +Link: https://patch.msgid.link/124ad747b751df0df1725eff89de8332e3fb26d6.1770759954.git.jpoimboe@kernel.org +Signed-off-by: Josh Poimboeuf +Signed-off-by: Sasha Levin +--- + tools/objtool/klp-diff.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c +index 9f1f4011eb9cd..d94632e809558 100644 +--- a/tools/objtool/klp-diff.c ++++ b/tools/objtool/klp-diff.c +@@ -1364,6 +1364,9 @@ static int validate_special_section_klp_reloc(struct elfs *e, struct symbol *sym + const char *sym_modname; + struct export *export; + ++ if (convert_reloc_sym(e->patched, reloc)) ++ continue; ++ + /* Static branch/call keys are always STT_OBJECT */ + if (reloc->sym->type != STT_OBJECT) { + +-- +2.51.0 + diff --git a/queue-6.19/powerpc-perf-check-that-current-mm-is-alive-before-g.patch b/queue-6.19/powerpc-perf-check-that-current-mm-is-alive-before-g.patch new file mode 100644 index 0000000000..ad11c43e3a --- /dev/null +++ b/queue-6.19/powerpc-perf-check-that-current-mm-is-alive-before-g.patch @@ -0,0 +1,92 @@ +From 0c151a5aca7c98c8ac34bd5e3fa6ee4408646a57 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Mar 2026 15:40:45 +0100 +Subject: powerpc, perf: Check that current->mm is alive before getting user + callchain + +From: Viktor Malik + +[ Upstream commit e9bbfb4bfa86c6b5515b868d6982ac60505d7e39 ] + +It may happen that mm is already released, which leads to kernel panic. +This adds the NULL check for current->mm, similarly to +commit 20afc60f892d ("x86, perf: Check that current->mm is alive before getting user callchain"). + +I was getting this panic when running a profiling BPF program +(profile.py from bcc-tools): + + [26215.051935] Kernel attempted to read user page (588) - exploit attempt? (uid: 0) + [26215.051950] BUG: Kernel NULL pointer dereference on read at 0x00000588 + [26215.051952] Faulting instruction address: 0xc00000000020fac0 + [26215.051957] Oops: Kernel access of bad area, sig: 11 [#1] + [...] + [26215.052049] Call Trace: + [26215.052050] [c000000061da6d30] [c00000000020fc10] perf_callchain_user_64+0x2d0/0x490 (unreliable) + [26215.052054] [c000000061da6dc0] [c00000000020f92c] perf_callchain_user+0x1c/0x30 + [26215.052057] [c000000061da6de0] [c0000000005ab2a0] get_perf_callchain+0x100/0x360 + [26215.052063] [c000000061da6e70] [c000000000573bc8] bpf_get_stackid+0x88/0xf0 + [26215.052067] [c000000061da6ea0] [c008000000042258] bpf_prog_16d4ab9ab662f669_do_perf_event+0xf8/0x274 + [...] + +In addition, move storing the top-level stack entry to generic +perf_callchain_user to make sure the top-evel entry is always captured, +even if current->mm is NULL. + +Fixes: 20002ded4d93 ("perf_counter: powerpc: Add callchain support") +Signed-off-by: Viktor Malik +Tested-by: Qiao Zhao +Tested-by: Venkat Rao Bagalkote +Reviewed-by: Saket Kumar Bhaskar +[Maddy: fixed message to avoid checkpatch format style error] +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/20260309144045.169427-1-vmalik@redhat.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/perf/callchain.c | 5 +++++ + arch/powerpc/perf/callchain_32.c | 1 - + arch/powerpc/perf/callchain_64.c | 1 - + 3 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c +index 26aa26482c9ac..992cc5c982144 100644 +--- a/arch/powerpc/perf/callchain.c ++++ b/arch/powerpc/perf/callchain.c +@@ -103,6 +103,11 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re + void + perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) + { ++ perf_callchain_store(entry, perf_arch_instruction_pointer(regs)); ++ ++ if (!current->mm) ++ return; ++ + if (!is_32bit_task()) + perf_callchain_user_64(entry, regs); + else +diff --git a/arch/powerpc/perf/callchain_32.c b/arch/powerpc/perf/callchain_32.c +index ddcc2d8aa64a5..0de21c5d272c2 100644 +--- a/arch/powerpc/perf/callchain_32.c ++++ b/arch/powerpc/perf/callchain_32.c +@@ -142,7 +142,6 @@ void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry, + next_ip = perf_arch_instruction_pointer(regs); + lr = regs->link; + sp = regs->gpr[1]; +- perf_callchain_store(entry, next_ip); + + while (entry->nr < entry->max_stack) { + fp = (unsigned int __user *) (unsigned long) sp; +diff --git a/arch/powerpc/perf/callchain_64.c b/arch/powerpc/perf/callchain_64.c +index 115d1c105e8a8..30fb61c5f0cb0 100644 +--- a/arch/powerpc/perf/callchain_64.c ++++ b/arch/powerpc/perf/callchain_64.c +@@ -77,7 +77,6 @@ void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry, + next_ip = perf_arch_instruction_pointer(regs); + lr = regs->link; + sp = regs->gpr[1]; +- perf_callchain_store(entry, next_ip); + + while (entry->nr < entry->max_stack) { + fp = (unsigned long __user *) sp; +-- +2.51.0 + diff --git a/queue-6.19/sched-mmcid-avoid-full-tasklist-walks.patch b/queue-6.19/sched-mmcid-avoid-full-tasklist-walks.patch new file mode 100644 index 0000000000..deddb6a753 --- /dev/null +++ b/queue-6.19/sched-mmcid-avoid-full-tasklist-walks.patch @@ -0,0 +1,187 @@ +From 798ce24d9929b6c81d2623a47aee25034c6dfd5d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Mar 2026 21:29:09 +0100 +Subject: sched/mmcid: Avoid full tasklist walks + +From: Thomas Gleixner + +[ Upstream commit 192d852129b1b7c4f0ddbab95d0de1efd5ee1405 ] + +Chasing vfork()'ed tasks on a CID ownership mode switch requires a full +task list walk, which is obviously expensive on large systems. + +Avoid that by keeping a list of tasks using a mm MMCID entity in mm::mm_cid +and walk this list instead. This removes the proven to be flaky counting +logic and avoids a full task list walk in the case of vfork()'ed tasks. + +Fixes: fbd0e71dc370 ("sched/mmcid: Provide CID ownership mode fixup functions") +Signed-off-by: Thomas Gleixner +Signed-off-by: Peter Zijlstra (Intel) +Tested-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20260310202526.183824481@kernel.org +Signed-off-by: Sasha Levin +--- + include/linux/rseq_types.h | 6 ++++- + kernel/fork.c | 1 + + kernel/sched/core.c | 54 +++++++++----------------------------- + 3 files changed, 18 insertions(+), 43 deletions(-) + +diff --git a/include/linux/rseq_types.h b/include/linux/rseq_types.h +index ef0811379c540..a612959c5b17f 100644 +--- a/include/linux/rseq_types.h ++++ b/include/linux/rseq_types.h +@@ -103,10 +103,12 @@ struct rseq_data { }; + * @active: MM CID is active for the task + * @cid: The CID associated to the task either permanently or + * borrowed from the CPU ++ * @node: Queued in the per MM MMCID list + */ + struct sched_mm_cid { + unsigned int active; + unsigned int cid; ++ struct hlist_node node; + }; + + /** +@@ -127,6 +129,7 @@ struct mm_cid_pcpu { + * @work: Regular work to handle the affinity mode change case + * @lock: Spinlock to protect against affinity setting which can't take @mutex + * @mutex: Mutex to serialize forks and exits related to this mm ++ * @user_list: List of the MM CID users of a MM + * @nr_cpus_allowed: The number of CPUs in the per MM allowed CPUs map. The map + * is growth only. + * @users: The number of tasks sharing this MM. Separate from mm::mm_users +@@ -147,13 +150,14 @@ struct mm_mm_cid { + + raw_spinlock_t lock; + struct mutex mutex; ++ struct hlist_head user_list; + + /* Low frequency modified */ + unsigned int nr_cpus_allowed; + unsigned int users; + unsigned int pcpu_thrs; + unsigned int update_deferred; +-}____cacheline_aligned_in_smp; ++} ____cacheline_aligned; + #else /* CONFIG_SCHED_MM_CID */ + struct mm_mm_cid { }; + struct sched_mm_cid { }; +diff --git a/kernel/fork.c b/kernel/fork.c +index 2d79096e0fecb..5b45887435dcc 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -999,6 +999,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node) + #ifdef CONFIG_SCHED_MM_CID + tsk->mm_cid.cid = MM_CID_UNSET; + tsk->mm_cid.active = 0; ++ INIT_HLIST_NODE(&tsk->mm_cid.node); + #endif + return tsk; + +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index c80076fcd78f2..011fe1b2ae911 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -10568,13 +10568,10 @@ static inline void mm_cid_transit_to_cpu(struct task_struct *t, struct mm_cid_pc + } + } + +-static bool mm_cid_fixup_task_to_cpu(struct task_struct *t, struct mm_struct *mm) ++static void mm_cid_fixup_task_to_cpu(struct task_struct *t, struct mm_struct *mm) + { + /* Remote access to mm::mm_cid::pcpu requires rq_lock */ + guard(task_rq_lock)(t); +- /* If the task is not active it is not in the users count */ +- if (!t->mm_cid.active) +- return false; + if (cid_on_task(t->mm_cid.cid)) { + /* If running on the CPU, put the CID in transit mode, otherwise drop it */ + if (task_rq(t)->curr == t) +@@ -10582,51 +10579,21 @@ static bool mm_cid_fixup_task_to_cpu(struct task_struct *t, struct mm_struct *mm + else + mm_unset_cid_on_task(t); + } +- return true; + } + +-static void mm_cid_do_fixup_tasks_to_cpus(struct mm_struct *mm) ++static void mm_cid_fixup_tasks_to_cpus(void) + { +- struct task_struct *p, *t; +- unsigned int users; +- +- /* +- * This can obviously race with a concurrent affinity change, which +- * increases the number of allowed CPUs for this mm, but that does +- * not affect the mode and only changes the CID constraints. A +- * possible switch back to per task mode happens either in the +- * deferred handler function or in the next fork()/exit(). +- * +- * The caller has already transferred so remove it from the users +- * count. The incoming task is already visible and has mm_cid.active, +- * but has task::mm_cid::cid == UNSET. Still it needs to be accounted +- * for. Concurrent fork()s might add more threads, but all of them have +- * task::mm_cid::active = 0, so they don't affect the accounting here. +- */ +- users = mm->mm_cid.users - 1; +- +- guard(rcu)(); +- for_other_threads(current, t) { +- if (mm_cid_fixup_task_to_cpu(t, mm)) +- users--; +- } ++ struct mm_struct *mm = current->mm; ++ struct task_struct *t; + +- if (!users) +- return; ++ lockdep_assert_held(&mm->mm_cid.mutex); + +- /* Happens only for VM_CLONE processes. */ +- for_each_process_thread(p, t) { +- if (t == current || t->mm != mm) +- continue; +- mm_cid_fixup_task_to_cpu(t, mm); ++ hlist_for_each_entry(t, &mm->mm_cid.user_list, mm_cid.node) { ++ /* Current has already transferred before invoking the fixup. */ ++ if (t != current) ++ mm_cid_fixup_task_to_cpu(t, mm); + } +-} +- +-static void mm_cid_fixup_tasks_to_cpus(void) +-{ +- struct mm_struct *mm = current->mm; + +- mm_cid_do_fixup_tasks_to_cpus(mm); + mm_cid_complete_transit(mm, MM_CID_ONCPU); + } + +@@ -10635,6 +10602,7 @@ static bool sched_mm_cid_add_user(struct task_struct *t, struct mm_struct *mm) + lockdep_assert_held(&mm->mm_cid.lock); + + t->mm_cid.active = 1; ++ hlist_add_head(&t->mm_cid.node, &mm->mm_cid.user_list); + mm->mm_cid.users++; + return mm_update_max_cids(mm); + } +@@ -10692,6 +10660,7 @@ static bool sched_mm_cid_remove_user(struct task_struct *t) + /* Clear the transition bit */ + t->mm_cid.cid = cid_from_transit_cid(t->mm_cid.cid); + mm_unset_cid_on_task(t); ++ hlist_del_init(&t->mm_cid.node); + t->mm->mm_cid.users--; + return mm_update_max_cids(t->mm); + } +@@ -10834,6 +10803,7 @@ void mm_init_cid(struct mm_struct *mm, struct task_struct *p) + mutex_init(&mm->mm_cid.mutex); + mm->mm_cid.irq_work = IRQ_WORK_INIT_HARD(mm_cid_irq_work); + INIT_WORK(&mm->mm_cid.work, mm_cid_work_fn); ++ INIT_HLIST_HEAD(&mm->mm_cid.user_list); + cpumask_copy(mm_cpus_allowed(mm), &p->cpus_mask); + bitmap_zero(mm_cidmask(mm), num_possible_cpus()); + } +-- +2.51.0 + diff --git a/queue-6.19/sched-mmcid-handle-vfork-clone_vm-correctly.patch b/queue-6.19/sched-mmcid-handle-vfork-clone_vm-correctly.patch new file mode 100644 index 0000000000..c8ffccae88 --- /dev/null +++ b/queue-6.19/sched-mmcid-handle-vfork-clone_vm-correctly.patch @@ -0,0 +1,58 @@ +From 674b0ac7110459b7f7f4c6e400f630828336872e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Mar 2026 21:28:58 +0100 +Subject: sched/mmcid: Handle vfork()/CLONE_VM correctly + +From: Thomas Gleixner + +[ Upstream commit 28b5a1395036d6c7a6c8034d85ad3d7d365f192c ] + +Matthieu and Jiri reported stalls where a task endlessly loops in +mm_get_cid() when scheduling in. + +It turned out that the logic which handles vfork()'ed tasks is broken. It +is invoked when the number of tasks associated to a process is smaller than +the number of MMCID users. It then walks the task list to find the +vfork()'ed task, but accounts all the already processed tasks as well. + +If that double processing brings the number of to be handled tasks to 0, +the walk stops and the vfork()'ed task's CID is not fixed up. As a +consequence a subsequent schedule in fails to acquire a (transitional) CID +and the machine stalls. + +Cure this by removing the accounting condition and make the fixup always +walk the full task list if it could not find the exact number of users in +the process' thread list. + +Fixes: fbd0e71dc370 ("sched/mmcid: Provide CID ownership mode fixup functions") +Closes: https://lore.kernel.org/b24ffcb3-09d5-4e48-9070-0b69bc654281@kernel.org +Reported-by: Matthieu Baerts +Reported-by: Jiri Slaby +Signed-off-by: Thomas Gleixner +Signed-off-by: Peter Zijlstra (Intel) +Tested-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20260310202526.048657665@kernel.org +Signed-off-by: Sasha Levin +--- + kernel/sched/core.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index ca6e6e4b17eaf..24d607c78f119 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -10618,10 +10618,7 @@ static void mm_cid_do_fixup_tasks_to_cpus(struct mm_struct *mm) + for_each_process_thread(p, t) { + if (t == current || t->mm != mm) + continue; +- if (mm_cid_fixup_task_to_cpu(t, mm)) { +- if (--users == 0) +- return; +- } ++ mm_cid_fixup_task_to_cpu(t, mm); + } + } + +-- +2.51.0 + diff --git a/queue-6.19/sched-mmcid-prevent-cid-stalls-due-to-concurrent-for.patch b/queue-6.19/sched-mmcid-prevent-cid-stalls-due-to-concurrent-for.patch new file mode 100644 index 0000000000..de7af582e0 --- /dev/null +++ b/queue-6.19/sched-mmcid-prevent-cid-stalls-due-to-concurrent-for.patch @@ -0,0 +1,153 @@ +From 1b9ebba6db21b21e5cecb13b667a01680849d673 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Mar 2026 21:28:53 +0100 +Subject: sched/mmcid: Prevent CID stalls due to concurrent forks + +From: Thomas Gleixner + +[ Upstream commit b2e48c429ec54715d16fefa719dd2fbded2e65be ] + +A newly forked task is accounted as MMCID user before the task is visible +in the process' thread list and the global task list. This creates the +following problem: + + CPU1 CPU2 + fork() + sched_mm_cid_fork(tnew1) + tnew1->mm.mm_cid_users++; + tnew1->mm_cid.cid = getcid() +-> preemption + fork() + sched_mm_cid_fork(tnew2) + tnew2->mm.mm_cid_users++; + // Reaches the per CPU threshold + mm_cid_fixup_tasks_to_cpus() + for_each_other(current, p) + .... + +As tnew1 is not visible yet, this fails to fix up the already allocated CID +of tnew1. As a consequence a subsequent schedule in might fail to acquire a +(transitional) CID and the machine stalls. + +Move the invocation of sched_mm_cid_fork() after the new task becomes +visible in the thread and the task list to prevent this. + +This also makes it symmetrical vs. exit() where the task is removed as CID +user before the task is removed from the thread and task lists. + +Fixes: fbd0e71dc370 ("sched/mmcid: Provide CID ownership mode fixup functions") +Signed-off-by: Thomas Gleixner +Signed-off-by: Peter Zijlstra (Intel) +Tested-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20260310202525.969061974@kernel.org +Signed-off-by: Sasha Levin +--- + include/linux/sched.h | 2 -- + kernel/fork.c | 2 -- + kernel/sched/core.c | 22 +++++++++++++++------- + 3 files changed, 15 insertions(+), 11 deletions(-) + +diff --git a/include/linux/sched.h b/include/linux/sched.h +index eb1c4c347a5cf..0719862970a28 100644 +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -2313,7 +2313,6 @@ static __always_inline void alloc_tag_restore(struct alloc_tag *tag, struct allo + #ifdef CONFIG_SCHED_MM_CID + void sched_mm_cid_before_execve(struct task_struct *t); + void sched_mm_cid_after_execve(struct task_struct *t); +-void sched_mm_cid_fork(struct task_struct *t); + void sched_mm_cid_exit(struct task_struct *t); + static __always_inline int task_mm_cid(struct task_struct *t) + { +@@ -2322,7 +2321,6 @@ static __always_inline int task_mm_cid(struct task_struct *t) + #else + static inline void sched_mm_cid_before_execve(struct task_struct *t) { } + static inline void sched_mm_cid_after_execve(struct task_struct *t) { } +-static inline void sched_mm_cid_fork(struct task_struct *t) { } + static inline void sched_mm_cid_exit(struct task_struct *t) { } + static __always_inline int task_mm_cid(struct task_struct *t) + { +diff --git a/kernel/fork.c b/kernel/fork.c +index 68ccbaea7398a..2d79096e0fecb 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -1585,7 +1585,6 @@ static int copy_mm(u64 clone_flags, struct task_struct *tsk) + + tsk->mm = mm; + tsk->active_mm = mm; +- sched_mm_cid_fork(tsk); + return 0; + } + +@@ -2496,7 +2495,6 @@ __latent_entropy struct task_struct *copy_process( + exit_nsproxy_namespaces(p); + bad_fork_cleanup_mm: + if (p->mm) { +- sched_mm_cid_exit(p); + mm_clear_owner(p->mm, p); + mmput(p->mm); + } +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index dbf4e32a063f7..ca6e6e4b17eaf 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -4708,8 +4708,11 @@ void sched_cancel_fork(struct task_struct *p) + scx_cancel_fork(p); + } + ++static void sched_mm_cid_fork(struct task_struct *t); ++ + void sched_post_fork(struct task_struct *p) + { ++ sched_mm_cid_fork(p); + uclamp_post_fork(p); + scx_post_fork(p); + } +@@ -10594,12 +10597,13 @@ static void mm_cid_do_fixup_tasks_to_cpus(struct mm_struct *mm) + * possible switch back to per task mode happens either in the + * deferred handler function or in the next fork()/exit(). + * +- * The caller has already transferred. The newly incoming task is +- * already accounted for, but not yet visible. ++ * The caller has already transferred so remove it from the users ++ * count. The incoming task is already visible and has mm_cid.active, ++ * but has task::mm_cid::cid == UNSET. Still it needs to be accounted ++ * for. Concurrent fork()s might add more threads, but all of them have ++ * task::mm_cid::active = 0, so they don't affect the accounting here. + */ +- users = mm->mm_cid.users - 2; +- if (!users) +- return; ++ users = mm->mm_cid.users - 1; + + guard(rcu)(); + for_other_threads(current, t) { +@@ -10636,12 +10640,15 @@ static bool sched_mm_cid_add_user(struct task_struct *t, struct mm_struct *mm) + return mm_update_max_cids(mm); + } + +-void sched_mm_cid_fork(struct task_struct *t) ++static void sched_mm_cid_fork(struct task_struct *t) + { + struct mm_struct *mm = t->mm; + bool percpu; + +- WARN_ON_ONCE(!mm || t->mm_cid.cid != MM_CID_UNSET); ++ if (!mm) ++ return; ++ ++ WARN_ON_ONCE(t->mm_cid.cid != MM_CID_UNSET); + + guard(mutex)(&mm->mm_cid.mutex); + scoped_guard(raw_spinlock_irq, &mm->mm_cid.lock) { +@@ -10833,6 +10840,7 @@ void mm_init_cid(struct mm_struct *mm, struct task_struct *p) + } + #else /* CONFIG_SCHED_MM_CID */ + static inline void mm_update_cpus_allowed(struct mm_struct *mm, const struct cpumask *affmsk) { } ++static inline void sched_mm_cid_fork(struct task_struct *t) { } + #endif /* !CONFIG_SCHED_MM_CID */ + + static DEFINE_PER_CPU(struct sched_change_ctx, sched_change_ctx); +-- +2.51.0 + diff --git a/queue-6.19/sched-mmcid-remove-pointless-preempt-guard.patch b/queue-6.19/sched-mmcid-remove-pointless-preempt-guard.patch new file mode 100644 index 0000000000..870cdc95f6 --- /dev/null +++ b/queue-6.19/sched-mmcid-remove-pointless-preempt-guard.patch @@ -0,0 +1,58 @@ +From 44bbf4781d379165568fe9e618f11ecd83f7a546 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Mar 2026 21:29:04 +0100 +Subject: sched/mmcid: Remove pointless preempt guard + +From: Thomas Gleixner + +[ Upstream commit 7574ac6e49789ddee1b1be9b2afb42b4a1b4b1f4 ] + +This is a leftover from the early versions of this function where it could +be invoked without mm::mm_cid::lock held. + +Remove it and add lockdep asserts instead. + +Fixes: 653fda7ae73d ("sched/mmcid: Switch over to the new mechanism") +Signed-off-by: Thomas Gleixner +Signed-off-by: Peter Zijlstra (Intel) +Tested-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20260310202526.116363613@kernel.org +Signed-off-by: Sasha Levin +--- + kernel/sched/core.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index 24d607c78f119..c80076fcd78f2 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -10632,6 +10632,8 @@ static void mm_cid_fixup_tasks_to_cpus(void) + + static bool sched_mm_cid_add_user(struct task_struct *t, struct mm_struct *mm) + { ++ lockdep_assert_held(&mm->mm_cid.lock); ++ + t->mm_cid.active = 1; + mm->mm_cid.users++; + return mm_update_max_cids(mm); +@@ -10684,12 +10686,12 @@ static void sched_mm_cid_fork(struct task_struct *t) + + static bool sched_mm_cid_remove_user(struct task_struct *t) + { ++ lockdep_assert_held(&t->mm->mm_cid.lock); ++ + t->mm_cid.active = 0; +- scoped_guard(preempt) { +- /* Clear the transition bit */ +- t->mm_cid.cid = cid_from_transit_cid(t->mm_cid.cid); +- mm_unset_cid_on_task(t); +- } ++ /* Clear the transition bit */ ++ t->mm_cid.cid = cid_from_transit_cid(t->mm_cid.cid); ++ mm_unset_cid_on_task(t); + t->mm->mm_cid.users--; + return mm_update_max_cids(t->mm); + } +-- +2.51.0 + diff --git a/queue-6.19/scsi-hisi_sas-fix-null-pointer-exception-during-user.patch b/queue-6.19/scsi-hisi_sas-fix-null-pointer-exception-during-user.patch new file mode 100644 index 0000000000..1d1a992a12 --- /dev/null +++ b/queue-6.19/scsi-hisi_sas-fix-null-pointer-exception-during-user.patch @@ -0,0 +1,113 @@ +From 759717aaef23f60a28ead15ab487ddcf07dd0f87 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Mar 2026 14:40:39 +0800 +Subject: scsi: hisi_sas: Fix NULL pointer exception during user_scan() + +From: Xingui Yang + +[ Upstream commit 8ddc0c26916574395447ebf4cff684314f6873a9 ] + +user_scan() invokes updated sas_user_scan() for channel 0, and if +successful, iteratively scans remaining channels (1 to shost->max_channel) +via scsi_scan_host_selected() in commit 37c4e72b0651 ("scsi: Fix +sas_user_scan() to handle wildcard and multi-channel scans"). However, +hisi_sas supports only one channel, and the current value of max_channel is +1. sas_user_scan() for channel 1 will trigger the following NULL pointer +exception: + +[ 441.554662] Unable to handle kernel NULL pointer dereference at virtual address 00000000000008b0 +[ 441.554699] Mem abort info: +[ 441.554710] ESR = 0x0000000096000004 +[ 441.554718] EC = 0x25: DABT (current EL), IL = 32 bits +[ 441.554723] SET = 0, FnV = 0 +[ 441.554726] EA = 0, S1PTW = 0 +[ 441.554730] FSC = 0x04: level 0 translation fault +[ 441.554735] Data abort info: +[ 441.554737] ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000 +[ 441.554742] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 +[ 441.554747] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 +[ 441.554752] user pgtable: 4k pages, 48-bit VAs, pgdp=00000828377a6000 +[ 441.554757] [00000000000008b0] pgd=0000000000000000, p4d=0000000000000000 +[ 441.554769] Internal error: Oops: 0000000096000004 [#1] SMP +[ 441.629589] Modules linked in: arm_spe_pmu arm_smmuv3_pmu tpm_tis_spi hisi_uncore_sllc_pmu hisi_uncore_pa_pmu hisi_uncore_l3c_pmu hisi_uncore_hha_pmu hisi_uncore_ddrc_pmu hisi_uncore_cpa_pmu hns3_pmu hisi_ptt hisi_pcie_pmu tpm_tis_core spidev spi_hisi_sfc_v3xx hisi_uncore_pmu spi_dw_mmio fuse hclge hclge_common hisi_sec2 hisi_hpre hisi_zip hisi_qm hns3 hisi_sas_v3_hw sm3_ce sbsa_gwdt hnae3 hisi_sas_main uacce hisi_dma i2c_hisi dm_mirror dm_region_hash dm_log dm_mod +[ 441.670819] CPU: 46 UID: 0 PID: 6994 Comm: bash Kdump: loaded Not tainted 7.0.0-rc2+ #84 PREEMPT +[ 441.691327] pstate: 81400009 (Nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--) +[ 441.698277] pc : sas_find_dev_by_rphy+0x44/0x118 +[ 441.702896] lr : sas_find_dev_by_rphy+0x3c/0x118 +[ 441.707502] sp : ffff80009abbba40 +[ 441.710805] x29: ffff80009abbba40 x28: ffff082819a40008 x27: ffff082810c37c08 +[ 441.717930] x26: ffff082810c37c28 x25: ffff082819a40290 x24: ffff082810c37c00 +[ 441.725054] x23: 0000000000000000 x22: 0000000000000001 x21: ffff082819a40000 +[ 441.732179] x20: ffff082819a40290 x19: 0000000000000000 x18: 0000000000000020 +[ 441.739304] x17: 0000000000000000 x16: ffffb5dad6bda690 x15: 00000000ffffffff +[ 441.746428] x14: ffff082814c3b26c x13: 00000000ffffffff x12: ffff082814c3b26a +[ 441.753553] x11: 00000000000000c0 x10: 000000000000003a x9 : ffffb5dad5ea94f4 +[ 441.760678] x8 : 000000000000003a x7 : ffff80009abbbab0 x6 : 0000000000000030 +[ 441.767802] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000 +[ 441.774926] x2 : ffff08280f35a300 x1 : ffffb5dad7127180 x0 : 0000000000000000 +[ 441.782053] Call trace: +[ 441.784488] sas_find_dev_by_rphy+0x44/0x118 (P) +[ 441.789095] sas_target_alloc+0x24/0xb0 +[ 441.792920] scsi_alloc_target+0x290/0x330 +[ 441.797010] __scsi_scan_target+0x88/0x258 +[ 441.801096] scsi_scan_channel+0x74/0xb8 +[ 441.805008] scsi_scan_host_selected+0x170/0x188 +[ 441.809615] sas_user_scan+0xfc/0x148 +[ 441.813267] store_scan+0x10c/0x180 +[ 441.816743] dev_attr_store+0x20/0x40 +[ 441.820398] sysfs_kf_write+0x84/0xa8 +[ 441.824054] kernfs_fop_write_iter+0x130/0x1c8 +[ 441.828487] vfs_write+0x2c0/0x370 +[ 441.831880] ksys_write+0x74/0x118 +[ 441.835271] __arm64_sys_write+0x24/0x38 +[ 441.839182] invoke_syscall+0x50/0x120 +[ 441.842919] el0_svc_common.constprop.0+0xc8/0xf0 +[ 441.847611] do_el0_svc+0x24/0x38 +[ 441.850913] el0_svc+0x38/0x158 +[ 441.854043] el0t_64_sync_handler+0xa0/0xe8 +[ 441.858214] el0t_64_sync+0x1ac/0x1b0 +[ 441.861865] Code: aa1303e0 97ff70a8 34ffff80 d10a4273 (f9445a75) +[ 441.867946] ---[ end trace 0000000000000000 ]--- + +Therefore, set max_channel to 0. + +Fixes: e21fe3a52692 ("scsi: hisi_sas: add initialisation for v3 pci-based controller") +Signed-off-by: Xingui Yang +Signed-off-by: Yihang Li +Link: https://patch.msgid.link/20260305064039.4096775-1-liyihang9@huawei.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 2 +- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 30a9c66126513..c2b082f1252c3 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -2578,7 +2578,7 @@ int hisi_sas_probe(struct platform_device *pdev, + shost->transportt = hisi_sas_stt; + shost->max_id = HISI_SAS_MAX_DEVICES; + shost->max_lun = ~0; +- shost->max_channel = 1; ++ shost->max_channel = 0; + shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN; + if (hisi_hba->hw->slot_index_alloc) { + shost->can_queue = HISI_SAS_MAX_COMMANDS; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 2f9e01717ef38..f69efc6494b8e 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -4993,7 +4993,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) + shost->transportt = hisi_sas_stt; + shost->max_id = HISI_SAS_MAX_DEVICES; + shost->max_lun = ~0; +- shost->max_channel = 1; ++ shost->max_channel = 0; + shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN; + shost->can_queue = HISI_SAS_UNRESERVED_IPTT; + shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT; +-- +2.51.0 + diff --git a/queue-6.19/scsi-qla2xxx-completely-fix-fcport-double-free.patch b/queue-6.19/scsi-qla2xxx-completely-fix-fcport-double-free.patch new file mode 100644 index 0000000000..a18cf087d2 --- /dev/null +++ b/queue-6.19/scsi-qla2xxx-completely-fix-fcport-double-free.patch @@ -0,0 +1,50 @@ +From 20de38ca93d783dda287fb818ee11630fea0a525 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Feb 2026 11:08:22 +0100 +Subject: scsi: qla2xxx: Completely fix fcport double free + +From: Vladimir Riabchun + +[ Upstream commit c0b7da13a04bd70ef6070bfb9ea85f582294560a ] + +In qla24xx_els_dcmd_iocb() sp->free is set to qla2x00_els_dcmd_sp_free(). +When an error happens, this function is called by qla2x00_sp_release(), +when kref_put() releases the first and the last reference. + +qla2x00_els_dcmd_sp_free() frees fcport by calling qla2x00_free_fcport(). +Doing it one more time after kref_put() is a bad idea. + +Fixes: 82f522ae0d97 ("scsi: qla2xxx: Fix double free of fcport") +Fixes: 4895009c4bb7 ("scsi: qla2xxx: Prevent command send on chip reset") +Signed-off-by: Vladimir Riabchun +Signed-off-by: Farhat Abbas +Link: https://patch.msgid.link/aYsDln9NFQQsPDgg@vova-pc +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/qla2xxx/qla_iocb.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c +index 3224044f17753..0de015de7eb59 100644 +--- a/drivers/scsi/qla2xxx/qla_iocb.c ++++ b/drivers/scsi/qla2xxx/qla_iocb.c +@@ -2751,7 +2751,6 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode, + if (!elsio->u.els_logo.els_logo_pyld) { + /* ref: INIT */ + kref_put(&sp->cmd_kref, qla2x00_sp_release); +- qla2x00_free_fcport(fcport); + return QLA_FUNCTION_FAILED; + } + +@@ -2776,7 +2775,6 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode, + if (rval != QLA_SUCCESS) { + /* ref: INIT */ + kref_put(&sp->cmd_kref, qla2x00_sp_release); +- qla2x00_free_fcport(fcport); + return QLA_FUNCTION_FAILED; + } + +-- +2.51.0 + diff --git a/queue-6.19/scsi-ufs-core-fix-serror-in-ufshcd_rtc_work-during-u.patch b/queue-6.19/scsi-ufs-core-fix-serror-in-ufshcd_rtc_work-during-u.patch new file mode 100644 index 0000000000..e3c02e3983 --- /dev/null +++ b/queue-6.19/scsi-ufs-core-fix-serror-in-ufshcd_rtc_work-during-u.patch @@ -0,0 +1,85 @@ +From c7725982793d91ef11a541d604b9f1e9cc98c334 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Mar 2026 11:51:28 +0800 +Subject: scsi: ufs: core: Fix SError in ufshcd_rtc_work() during UFS suspend + +From: Wang Shuaiwei + +[ Upstream commit b0bd84c39289ef6a6c3827dd52c875659291970a ] + +In __ufshcd_wl_suspend(), cancel_delayed_work_sync() is called to cancel +the UFS RTC work, but it is placed after ufshcd_vops_suspend(hba, pm_op, +POST_CHANGE). This creates a race condition where ufshcd_rtc_work() can +still be running while ufshcd_vops_suspend() is executing. When +UFSHCD_CAP_CLK_GATING is not supported, the condition +!hba->clk_gating.active_reqs is always true, causing ufshcd_update_rtc() +to be executed. Since ufshcd_vops_suspend() typically performs clock +gating operations, executing ufshcd_update_rtc() at that moment triggers +an SError. The kernel panic trace is as follows: + +Kernel panic - not syncing: Asynchronous SError Interrupt +Call trace: + dump_backtrace+0xec/0x128 + show_stack+0x18/0x28 + dump_stack_lvl+0x40/0xa0 + dump_stack+0x18/0x24 + panic+0x148/0x374 + nmi_panic+0x3c/0x8c + arm64_serror_panic+0x64/0x8c + do_serror+0xc4/0xc8 + el1h_64_error_handler+0x34/0x4c + el1h_64_error+0x68/0x6c + el1_interrupt+0x20/0x58 + el1h_64_irq_handler+0x18/0x24 + el1h_64_irq+0x68/0x6c + ktime_get+0xc4/0x12c + ufshcd_mcq_sq_stop+0x4c/0xec + ufshcd_mcq_sq_cleanup+0x64/0x1dc + ufshcd_clear_cmd+0x38/0x134 + ufshcd_issue_dev_cmd+0x298/0x4d0 + ufshcd_exec_dev_cmd+0x1a4/0x1c4 + ufshcd_query_attr+0xbc/0x19c + ufshcd_rtc_work+0x10c/0x1c8 + process_scheduled_works+0x1c4/0x45c + worker_thread+0x32c/0x3e8 + kthread+0x120/0x1d8 + ret_from_fork+0x10/0x20 + +Fix this by moving cancel_delayed_work_sync() before the call to +ufshcd_vops_suspend(hba, pm_op, PRE_CHANGE), ensuring the UFS RTC work is +fully completed or cancelled at that point. + +Cc: Bean Huo +Fixes: 6bf999e0eb41 ("scsi: ufs: core: Add UFS RTC support") +Reviewed-by: Bart Van Assche +Signed-off-by: Wang Shuaiwei +Link: https://patch.msgid.link/20260307035128.3419687-1-wangshuaiwei1@xiaomi.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/ufs/core/ufshcd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c +index 2048ebc86590e..5038b8428fc30 100644 +--- a/drivers/ufs/core/ufshcd.c ++++ b/drivers/ufs/core/ufshcd.c +@@ -10061,6 +10061,7 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) + } + + flush_work(&hba->eeh_work); ++ cancel_delayed_work_sync(&hba->ufs_rtc_update_work); + + ret = ufshcd_vops_suspend(hba, pm_op, PRE_CHANGE); + if (ret) +@@ -10115,7 +10116,6 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) + if (ret) + goto set_link_active; + +- cancel_delayed_work_sync(&hba->ufs_rtc_update_work); + goto out; + + set_link_active: +-- +2.51.0 + diff --git a/queue-6.19/series b/queue-6.19/series index 6d48d513e6..494422060b 100644 --- a/queue-6.19/series +++ b/queue-6.19/series @@ -170,3 +170,20 @@ revert-usb-gadget-u_ether-add-auto-cleanup-helper-for-freeing-net_device.patch revert-usb-gadget-f_ncm-align-net_device-lifecycle-with-bind-unbind.patch revert-usb-gadget-u_ether-add-gether_opts-for-config-caching.patch usb-gadget-f_ncm-fix-net_device-lifecycle-with-device_move.patch +alsa-usb-audio-improve-focusrite-sample-rate-filteri.patch +objtool-klp-fix-detection-of-corrupt-static-branch-c.patch +objtool-fix-data-alignment-in-elf_add_data.patch +objtool-fix-another-stack-overflow-in-validate_branc.patch +irqchip-riscv-aplic-preserve-aplic-states-across-sus.patch +irqchip-riscv-aplic-do-not-clear-acpi-dependencies-o.patch +irqchip-riscv-aplic-register-syscore-operations-only.patch +time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch +sched-mmcid-prevent-cid-stalls-due-to-concurrent-for.patch +sched-mmcid-handle-vfork-clone_vm-correctly.patch +sched-mmcid-remove-pointless-preempt-guard.patch +sched-mmcid-avoid-full-tasklist-walks.patch +i3c-dw-i3c-master-set-sir_reject-in-dat-on-device-at.patch +powerpc-perf-check-that-current-mm-is-alive-before-g.patch +scsi-ufs-core-fix-serror-in-ufshcd_rtc_work-during-u.patch +scsi-qla2xxx-completely-fix-fcport-double-free.patch +scsi-hisi_sas-fix-null-pointer-exception-during-user.patch diff --git a/queue-6.19/time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch b/queue-6.19/time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch new file mode 100644 index 0000000000..9d616ad47b --- /dev/null +++ b/queue-6.19/time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch @@ -0,0 +1,39 @@ +From 3d9f364df7dadaac18f32ea60836afd8ed7945e9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Mar 2026 21:24:03 -0500 +Subject: time/jiffies: Mark jiffies_64_to_clock_t() notrace + +From: Steven Rostedt + +[ Upstream commit 755a648e78f12574482d4698d877375793867fa1 ] + +The trace_clock_jiffies() function that handles the "uptime" clock for +tracing calls jiffies_64_to_clock_t(). This causes the function tracer to +constantly recurse when the tracing clock is set to "uptime". Mark it +notrace to prevent unnecessary recursion when using the "uptime" clock. + +Fixes: 58d4e21e50ff3 ("tracing: Fix wraparound problems in "uptime" trace clock") +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Thomas Gleixner +Link: https://patch.msgid.link/20260306212403.72270bb2@robin +Signed-off-by: Sasha Levin +--- + kernel/time/time.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/time/time.c b/kernel/time/time.c +index 0ba8e3c50d625..155cf7def9146 100644 +--- a/kernel/time/time.c ++++ b/kernel/time/time.c +@@ -702,7 +702,7 @@ EXPORT_SYMBOL(clock_t_to_jiffies); + * + * Return: jiffies_64 value converted to 64-bit "clock_t" (CLOCKS_PER_SEC) + */ +-u64 jiffies_64_to_clock_t(u64 x) ++notrace u64 jiffies_64_to_clock_t(u64 x) + { + #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 + # if HZ < USER_HZ +-- +2.51.0 + diff --git a/queue-6.6/i3c-dw-i3c-master-set-sir_reject-in-dat-on-device-at.patch b/queue-6.6/i3c-dw-i3c-master-set-sir_reject-in-dat-on-device-at.patch new file mode 100644 index 0000000000..2ebbee9a0b --- /dev/null +++ b/queue-6.6/i3c-dw-i3c-master-set-sir_reject-in-dat-on-device-at.patch @@ -0,0 +1,57 @@ +From d571c940d9021d45c44da3fd30f312acbe3f9f0b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Feb 2026 14:00:48 +0800 +Subject: i3c: dw-i3c-master: Set SIR_REJECT in DAT on device attach and + reattach + +From: Adrian Ng Ho Yin + +[ Upstream commit f311a05784634febd299f03476b80f3f18489767 ] + +The DesignWare I3C master controller ACKs IBIs as soon as a valid +Device Address Table (DAT) entry is present. This can create a race +between device attachment (after DAA) and the point where the client +driver enables IBIs via i3c_device_enable_ibi(). + +Set DEV_ADDR_TABLE_SIR_REJECT in the DAT entry during +attach_i3c_dev() and reattach_i3c_dev() so that IBIs are rejected +by default. The bit is managed thereafter by the existing +dw_i3c_master_set_sir_enabled() function, which clears it in +enable_ibi() after ENEC is issued, and restores it in disable_ibi() +after DISEC. + +Fixes: 1dd728f5d4d4 ("i3c: master: Add driver for Synopsys DesignWare IP") +Signed-off-by: Adrian Ng Ho Yin +Reviewed-by: Frank Li +Link: https://patch.msgid.link/53f5b8cbdd8af789ec38b95b02873f32f9182dd6.1770962368.git.adrianhoyin.ng@altera.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master/dw-i3c-master.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c +index cee2805fccd0f..ccb521bcb73e3 100644 +--- a/drivers/i3c/master/dw-i3c-master.c ++++ b/drivers/i3c/master/dw-i3c-master.c +@@ -941,7 +941,7 @@ static int dw_i3c_master_reattach_i3c_dev(struct i3c_dev_desc *dev, + master->free_pos &= ~BIT(pos); + } + +- writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(dev->info.dyn_addr), ++ writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(dev->info.dyn_addr) | DEV_ADDR_TABLE_SIR_REJECT, + master->regs + + DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); + +@@ -970,7 +970,7 @@ static int dw_i3c_master_attach_i3c_dev(struct i3c_dev_desc *dev) + master->free_pos &= ~BIT(pos); + i3c_dev_set_master_data(dev, data); + +- writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr), ++ writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr) | DEV_ADDR_TABLE_SIR_REJECT, + master->regs + + DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); + +-- +2.51.0 + diff --git a/queue-6.6/scsi-hisi_sas-add-time-interval-between-two-h2d-fis-.patch b/queue-6.6/scsi-hisi_sas-add-time-interval-between-two-h2d-fis-.patch new file mode 100644 index 0000000000..17b685d0eb --- /dev/null +++ b/queue-6.6/scsi-hisi_sas-add-time-interval-between-two-h2d-fis-.patch @@ -0,0 +1,38 @@ +From ea20d3e808eef3d31db19c43b9e59ac8fd21ddcd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Oct 2024 10:18:19 +0800 +Subject: scsi: hisi_sas: Add time interval between two H2D FIS following soft + reset spec + +From: Xingui Yang + +[ Upstream commit 3c62791322e42d1afd65acfdb5b3a371bde21ede ] + +Spec says at least 5us between two H2D FIS when do soft reset, but be +generous and sleep for about 1ms. + +Signed-off-by: Xingui Yang +Link: https://lore.kernel.org/r/20241008021822.2617339-11-liyihang9@huawei.com +Reviewed-by: Yihang Li +Signed-off-by: Martin K. Petersen +Stable-dep-of: 8ddc0c269165 ("scsi: hisi_sas: Fix NULL pointer exception during user_scan()") +Signed-off-by: Sasha Levin +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 3ad58250bf6b2..17189703454a2 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1340,6 +1340,7 @@ static int hisi_sas_softreset_ata_disk(struct domain_device *device) + } + + if (rc == TMF_RESP_FUNC_COMPLETE) { ++ usleep_range(900, 1000); + ata_for_each_link(link, ap, EDGE) { + int pmp = sata_srst_pmp(link); + +-- +2.51.0 + diff --git a/queue-6.6/scsi-hisi_sas-fix-null-pointer-exception-during-user.patch b/queue-6.6/scsi-hisi_sas-fix-null-pointer-exception-during-user.patch new file mode 100644 index 0000000000..d843c4e936 --- /dev/null +++ b/queue-6.6/scsi-hisi_sas-fix-null-pointer-exception-during-user.patch @@ -0,0 +1,113 @@ +From a5ef8fb404ef6cae13e0f16e704e1d4442860bfe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Mar 2026 14:40:39 +0800 +Subject: scsi: hisi_sas: Fix NULL pointer exception during user_scan() + +From: Xingui Yang + +[ Upstream commit 8ddc0c26916574395447ebf4cff684314f6873a9 ] + +user_scan() invokes updated sas_user_scan() for channel 0, and if +successful, iteratively scans remaining channels (1 to shost->max_channel) +via scsi_scan_host_selected() in commit 37c4e72b0651 ("scsi: Fix +sas_user_scan() to handle wildcard and multi-channel scans"). However, +hisi_sas supports only one channel, and the current value of max_channel is +1. sas_user_scan() for channel 1 will trigger the following NULL pointer +exception: + +[ 441.554662] Unable to handle kernel NULL pointer dereference at virtual address 00000000000008b0 +[ 441.554699] Mem abort info: +[ 441.554710] ESR = 0x0000000096000004 +[ 441.554718] EC = 0x25: DABT (current EL), IL = 32 bits +[ 441.554723] SET = 0, FnV = 0 +[ 441.554726] EA = 0, S1PTW = 0 +[ 441.554730] FSC = 0x04: level 0 translation fault +[ 441.554735] Data abort info: +[ 441.554737] ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000 +[ 441.554742] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 +[ 441.554747] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 +[ 441.554752] user pgtable: 4k pages, 48-bit VAs, pgdp=00000828377a6000 +[ 441.554757] [00000000000008b0] pgd=0000000000000000, p4d=0000000000000000 +[ 441.554769] Internal error: Oops: 0000000096000004 [#1] SMP +[ 441.629589] Modules linked in: arm_spe_pmu arm_smmuv3_pmu tpm_tis_spi hisi_uncore_sllc_pmu hisi_uncore_pa_pmu hisi_uncore_l3c_pmu hisi_uncore_hha_pmu hisi_uncore_ddrc_pmu hisi_uncore_cpa_pmu hns3_pmu hisi_ptt hisi_pcie_pmu tpm_tis_core spidev spi_hisi_sfc_v3xx hisi_uncore_pmu spi_dw_mmio fuse hclge hclge_common hisi_sec2 hisi_hpre hisi_zip hisi_qm hns3 hisi_sas_v3_hw sm3_ce sbsa_gwdt hnae3 hisi_sas_main uacce hisi_dma i2c_hisi dm_mirror dm_region_hash dm_log dm_mod +[ 441.670819] CPU: 46 UID: 0 PID: 6994 Comm: bash Kdump: loaded Not tainted 7.0.0-rc2+ #84 PREEMPT +[ 441.691327] pstate: 81400009 (Nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--) +[ 441.698277] pc : sas_find_dev_by_rphy+0x44/0x118 +[ 441.702896] lr : sas_find_dev_by_rphy+0x3c/0x118 +[ 441.707502] sp : ffff80009abbba40 +[ 441.710805] x29: ffff80009abbba40 x28: ffff082819a40008 x27: ffff082810c37c08 +[ 441.717930] x26: ffff082810c37c28 x25: ffff082819a40290 x24: ffff082810c37c00 +[ 441.725054] x23: 0000000000000000 x22: 0000000000000001 x21: ffff082819a40000 +[ 441.732179] x20: ffff082819a40290 x19: 0000000000000000 x18: 0000000000000020 +[ 441.739304] x17: 0000000000000000 x16: ffffb5dad6bda690 x15: 00000000ffffffff +[ 441.746428] x14: ffff082814c3b26c x13: 00000000ffffffff x12: ffff082814c3b26a +[ 441.753553] x11: 00000000000000c0 x10: 000000000000003a x9 : ffffb5dad5ea94f4 +[ 441.760678] x8 : 000000000000003a x7 : ffff80009abbbab0 x6 : 0000000000000030 +[ 441.767802] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000 +[ 441.774926] x2 : ffff08280f35a300 x1 : ffffb5dad7127180 x0 : 0000000000000000 +[ 441.782053] Call trace: +[ 441.784488] sas_find_dev_by_rphy+0x44/0x118 (P) +[ 441.789095] sas_target_alloc+0x24/0xb0 +[ 441.792920] scsi_alloc_target+0x290/0x330 +[ 441.797010] __scsi_scan_target+0x88/0x258 +[ 441.801096] scsi_scan_channel+0x74/0xb8 +[ 441.805008] scsi_scan_host_selected+0x170/0x188 +[ 441.809615] sas_user_scan+0xfc/0x148 +[ 441.813267] store_scan+0x10c/0x180 +[ 441.816743] dev_attr_store+0x20/0x40 +[ 441.820398] sysfs_kf_write+0x84/0xa8 +[ 441.824054] kernfs_fop_write_iter+0x130/0x1c8 +[ 441.828487] vfs_write+0x2c0/0x370 +[ 441.831880] ksys_write+0x74/0x118 +[ 441.835271] __arm64_sys_write+0x24/0x38 +[ 441.839182] invoke_syscall+0x50/0x120 +[ 441.842919] el0_svc_common.constprop.0+0xc8/0xf0 +[ 441.847611] do_el0_svc+0x24/0x38 +[ 441.850913] el0_svc+0x38/0x158 +[ 441.854043] el0t_64_sync_handler+0xa0/0xe8 +[ 441.858214] el0t_64_sync+0x1ac/0x1b0 +[ 441.861865] Code: aa1303e0 97ff70a8 34ffff80 d10a4273 (f9445a75) +[ 441.867946] ---[ end trace 0000000000000000 ]--- + +Therefore, set max_channel to 0. + +Fixes: e21fe3a52692 ("scsi: hisi_sas: add initialisation for v3 pci-based controller") +Signed-off-by: Xingui Yang +Signed-off-by: Yihang Li +Link: https://patch.msgid.link/20260305064039.4096775-1-liyihang9@huawei.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 2 +- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 0a52e7ba504cb..578f7c6117d3d 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -2537,7 +2537,7 @@ int hisi_sas_probe(struct platform_device *pdev, + shost->transportt = hisi_sas_stt; + shost->max_id = HISI_SAS_MAX_DEVICES; + shost->max_lun = ~0; +- shost->max_channel = 1; ++ shost->max_channel = 0; + shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN; + if (hisi_hba->hw->slot_index_alloc) { + shost->can_queue = HISI_SAS_MAX_COMMANDS; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index e8f5a8023a1af..7075dde4584db 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -5087,7 +5087,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) + shost->transportt = hisi_sas_stt; + shost->max_id = HISI_SAS_MAX_DEVICES; + shost->max_lun = ~0; +- shost->max_channel = 1; ++ shost->max_channel = 0; + shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN; + shost->can_queue = HISI_SAS_UNRESERVED_IPTT; + shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT; +-- +2.51.0 + diff --git a/queue-6.6/scsi-hisi_sas-use-macro-instead-of-magic-number.patch b/queue-6.6/scsi-hisi_sas-use-macro-instead-of-magic-number.patch new file mode 100644 index 0000000000..10c40bd778 --- /dev/null +++ b/queue-6.6/scsi-hisi_sas-use-macro-instead-of-magic-number.patch @@ -0,0 +1,1048 @@ +From 4f804a36ff98dc07f27a806ca9cab80f706adcbe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Apr 2025 16:08:42 +0800 +Subject: scsi: hisi_sas: Use macro instead of magic number + +From: Yihang Li + +[ Upstream commit 4ca7fe99fc8485fcd04b367f37dc7a48f1355419 ] + +The hisi_sas driver has a large number of magic numbers which makes for +unfriendly code reading. Use macro definitions instead. + +Signed-off-by: Yihang Li +Link: https://lore.kernel.org/r/20250414080845.1220997-2-liyihang9@huawei.com +Signed-off-by: Martin K. Petersen +Stable-dep-of: 8ddc0c269165 ("scsi: hisi_sas: Fix NULL pointer exception during user_scan()") +Signed-off-by: Sasha Levin +--- + drivers/scsi/hisi_sas/hisi_sas.h | 43 +++-- + drivers/scsi/hisi_sas/hisi_sas_main.c | 41 +++-- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 244 ++++++++++++++++--------- + 3 files changed, 213 insertions(+), 115 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 1e4550156b735..4e905c9bec28e 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -47,6 +47,13 @@ + #define HISI_SAS_IOST_ITCT_CACHE_DW_SZ 10 + #define HISI_SAS_FIFO_DATA_DW_SIZE 32 + ++#define HISI_SAS_REG_MEM_SIZE 4 ++#define HISI_SAS_MAX_CDB_LEN 16 ++#define HISI_SAS_BLK_QUEUE_DEPTH 64 ++ ++#define BYTE_TO_DW 4 ++#define BYTE_TO_DDW 8 ++ + #define HISI_SAS_STATUS_BUF_SZ (sizeof(struct hisi_sas_status_buffer)) + #define HISI_SAS_COMMAND_TABLE_SZ (sizeof(union hisi_sas_command_table)) + +@@ -93,6 +100,8 @@ + + #define HISI_SAS_WAIT_PHYUP_TIMEOUT (30 * HZ) + #define HISI_SAS_CLEAR_ITCT_TIMEOUT (20 * HZ) ++#define HISI_SAS_DELAY_FOR_PHY_DISABLE 100 ++#define NAME_BUF_SIZE 256 + + struct hisi_hba; + +@@ -168,6 +177,8 @@ struct hisi_sas_debugfs_fifo { + u32 rd_data[HISI_SAS_FIFO_DATA_DW_SIZE]; + }; + ++#define FRAME_RCVD_BUF 32 ++#define SAS_PHY_RESV_SIZE 2 + struct hisi_sas_phy { + struct work_struct works[HISI_PHYES_NUM]; + struct hisi_hba *hisi_hba; +@@ -179,10 +190,10 @@ struct hisi_sas_phy { + spinlock_t lock; + u64 port_id; /* from hw */ + u64 frame_rcvd_size; +- u8 frame_rcvd[32]; ++ u8 frame_rcvd[FRAME_RCVD_BUF]; + u8 phy_attached; + u8 in_reset; +- u8 reserved[2]; ++ u8 reserved[SAS_PHY_RESV_SIZE]; + u32 phy_type; + u32 code_violation_err_count; + enum sas_linkrate minimum_linkrate; +@@ -349,6 +360,7 @@ struct hisi_sas_hw { + }; + + #define HISI_SAS_MAX_DEBUGFS_DUMP (50) ++#define HISI_SAS_DEFAULT_DEBUGFS_DUMP 1 + + struct hisi_sas_debugfs_cq { + struct hisi_sas_cq *cq; +@@ -528,12 +540,13 @@ struct hisi_sas_cmd_hdr { + __le64 dif_prd_table_addr; + }; + ++#define ITCT_RESV_DDW 12 + struct hisi_sas_itct { + __le64 qw0; + __le64 sas_addr; + __le64 qw2; + __le64 qw3; +- __le64 qw4_15[12]; ++ __le64 qw4_15[ITCT_RESV_DDW]; + }; + + struct hisi_sas_iost { +@@ -543,22 +556,26 @@ struct hisi_sas_iost { + __le64 qw3; + }; + ++#define ERROR_RECORD_BUF_DW 4 + struct hisi_sas_err_record { +- u32 data[4]; ++ u32 data[ERROR_RECORD_BUF_DW]; + }; + ++#define FIS_RESV_DW 3 + struct hisi_sas_initial_fis { + struct hisi_sas_err_record err_record; + struct dev_to_host_fis fis; +- u32 rsvd[3]; ++ u32 rsvd[FIS_RESV_DW]; + }; + ++#define BREAKPOINT_DATA_SIZE 128 + struct hisi_sas_breakpoint { +- u8 data[128]; ++ u8 data[BREAKPOINT_DATA_SIZE]; + }; + ++#define BREAKPOINT_TAG_NUM 32 + struct hisi_sas_sata_breakpoint { +- struct hisi_sas_breakpoint tag[32]; ++ struct hisi_sas_breakpoint tag[BREAKPOINT_TAG_NUM]; + }; + + struct hisi_sas_sge { +@@ -569,13 +586,15 @@ struct hisi_sas_sge { + __le32 data_off; + }; + ++#define SMP_CMD_TABLE_SIZE 44 + struct hisi_sas_command_table_smp { +- u8 bytes[44]; ++ u8 bytes[SMP_CMD_TABLE_SIZE]; + }; + ++#define DUMMY_BUF_SIZE 12 + struct hisi_sas_command_table_stp { + struct host_to_dev_fis command_fis; +- u8 dummy[12]; ++ u8 dummy[DUMMY_BUF_SIZE]; + u8 atapi_cdb[ATAPI_CDB_LEN]; + }; + +@@ -589,12 +608,13 @@ struct hisi_sas_sge_dif_page { + struct hisi_sas_sge sge[HISI_SAS_SGE_DIF_PAGE_CNT]; + } __aligned(16); + ++#define PROT_BUF_SIZE 7 + struct hisi_sas_command_table_ssp { + struct ssp_frame_hdr hdr; + union { + struct { + struct ssp_command_iu task; +- u32 prot[7]; ++ u32 prot[PROT_BUF_SIZE]; + }; + struct ssp_tmf_iu ssp_task; + struct xfer_rdy_iu xfer_rdy; +@@ -608,9 +628,10 @@ union hisi_sas_command_table { + struct hisi_sas_command_table_stp stp; + } __aligned(16); + ++#define IU_BUF_SIZE 1024 + struct hisi_sas_status_buffer { + struct hisi_sas_err_record err; +- u8 iu[1024]; ++ u8 iu[IU_BUF_SIZE]; + } __aligned(16); + + struct hisi_sas_slot_buf_table { +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 17189703454a2..0a52e7ba504cb 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -7,6 +7,16 @@ + #include "hisi_sas.h" + #define DRV_NAME "hisi_sas" + ++#define LINK_RATE_BIT_MASK 2 ++#define FIS_BUF_SIZE 20 ++#define WAIT_CMD_COMPLETE_DELAY 100 ++#define WAIT_CMD_COMPLETE_TMROUT 5000 ++#define DELAY_FOR_LINK_READY 2000 ++#define BLK_CNT_OPTIMIZE_MARK 64 ++#define HZ_TO_MHZ 1000000 ++#define DELAY_FOR_SOFTRESET_MAX 1000 ++#define DELAY_FOR_SOFTRESET_MIN 900 ++ + #define DEV_IS_GONE(dev) \ + ((!dev) || (dev->dev_type == SAS_PHY_UNUSED)) + +@@ -127,7 +137,7 @@ u8 hisi_sas_get_prog_phy_linkrate_mask(enum sas_linkrate max) + + max -= SAS_LINK_RATE_1_5_GBPS; + for (i = 0; i <= max; i++) +- rate |= 1 << (i * 2); ++ rate |= 1 << (i * LINK_RATE_BIT_MASK); + return rate; + } + EXPORT_SYMBOL_GPL(hisi_sas_get_prog_phy_linkrate_mask); +@@ -876,7 +886,7 @@ int hisi_sas_slave_configure(struct scsi_device *sdev) + if (ret) + return ret; + if (!dev_is_sata(dev)) +- sas_change_queue_depth(sdev, 64); ++ sas_change_queue_depth(sdev, HISI_SAS_BLK_QUEUE_DEPTH); + + return 0; + } +@@ -1238,7 +1248,7 @@ static int hisi_sas_phy_set_linkrate(struct hisi_hba *hisi_hba, int phy_no, + sas_phy->phy->minimum_linkrate = min; + + hisi_sas_phy_enable(hisi_hba, phy_no, 0); +- msleep(100); ++ msleep(HISI_SAS_DELAY_FOR_PHY_DISABLE); + hisi_hba->hw->phy_set_linkrate(hisi_hba, phy_no, &_r); + hisi_sas_phy_enable(hisi_hba, phy_no, 1); + +@@ -1268,7 +1278,7 @@ static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func, + + case PHY_FUNC_LINK_RESET: + hisi_sas_phy_enable(hisi_hba, phy_no, 0); +- msleep(100); ++ msleep(HISI_SAS_DELAY_FOR_PHY_DISABLE); + hisi_sas_phy_enable(hisi_hba, phy_no, 1); + break; + +@@ -1323,7 +1333,7 @@ static void hisi_sas_fill_ata_reset_cmd(struct ata_device *dev, + + static int hisi_sas_softreset_ata_disk(struct domain_device *device) + { +- u8 fis[20] = {0}; ++ u8 fis[FIS_BUF_SIZE] = {0}; + struct ata_port *ap = device->sata_dev.ap; + struct ata_link *link; + int rc = TMF_RESP_FUNC_FAILED; +@@ -1340,7 +1350,7 @@ static int hisi_sas_softreset_ata_disk(struct domain_device *device) + } + + if (rc == TMF_RESP_FUNC_COMPLETE) { +- usleep_range(900, 1000); ++ usleep_range(DELAY_FOR_SOFTRESET_MIN, DELAY_FOR_SOFTRESET_MAX); + ata_for_each_link(link, ap, EDGE) { + int pmp = sata_srst_pmp(link); + +@@ -1459,7 +1469,7 @@ static void hisi_sas_send_ata_reset_each_phy(struct hisi_hba *hisi_hba, + struct device *dev = hisi_hba->dev; + int rc = TMF_RESP_FUNC_FAILED; + struct ata_link *link; +- u8 fis[20] = {0}; ++ u8 fis[FIS_BUF_SIZE] = {0}; + int i; + + for (i = 0; i < hisi_hba->n_phy; i++) { +@@ -1526,7 +1536,9 @@ void hisi_sas_controller_reset_prepare(struct hisi_hba *hisi_hba) + hisi_hba->phy_state = hisi_hba->hw->get_phys_state(hisi_hba); + + scsi_block_requests(shost); +- hisi_hba->hw->wait_cmds_complete_timeout(hisi_hba, 100, 5000); ++ hisi_hba->hw->wait_cmds_complete_timeout(hisi_hba, ++ WAIT_CMD_COMPLETE_DELAY, ++ WAIT_CMD_COMPLETE_TMROUT); + + del_timer_sync(&hisi_hba->timer); + +@@ -1822,7 +1834,7 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device) + rc = ata_wait_after_reset(link, jiffies + HISI_SAS_WAIT_PHYUP_TIMEOUT, + smp_ata_check_ready_type); + } else { +- msleep(2000); ++ msleep(DELAY_FOR_LINK_READY); + } + + return rc; +@@ -2237,12 +2249,14 @@ int hisi_sas_alloc(struct hisi_hba *hisi_hba) + goto err_out; + + /* roundup to avoid overly large block size */ +- max_command_entries_ru = roundup(max_command_entries, 64); ++ max_command_entries_ru = roundup(max_command_entries, ++ BLK_CNT_OPTIMIZE_MARK); + if (hisi_hba->prot_mask & HISI_SAS_DIX_PROT_MASK) + sz_slot_buf_ru = sizeof(struct hisi_sas_slot_dif_buf_table); + else + sz_slot_buf_ru = sizeof(struct hisi_sas_slot_buf_table); +- sz_slot_buf_ru = roundup(sz_slot_buf_ru, 64); ++ ++ sz_slot_buf_ru = roundup(sz_slot_buf_ru, BLK_CNT_OPTIMIZE_MARK); + s = max(lcm(max_command_entries_ru, sz_slot_buf_ru), PAGE_SIZE); + blk_cnt = (max_command_entries_ru * sz_slot_buf_ru) / s; + slots_per_blk = s / sz_slot_buf_ru; +@@ -2406,7 +2420,8 @@ int hisi_sas_get_fw_info(struct hisi_hba *hisi_hba) + if (IS_ERR(refclk)) + dev_dbg(dev, "no ref clk property\n"); + else +- hisi_hba->refclk_frequency_mhz = clk_get_rate(refclk) / 1000000; ++ hisi_hba->refclk_frequency_mhz = clk_get_rate(refclk) / ++ HZ_TO_MHZ; + + if (device_property_read_u32(dev, "phy-count", &hisi_hba->n_phy)) { + dev_err(dev, "could not get property phy-count\n"); +@@ -2523,7 +2538,7 @@ int hisi_sas_probe(struct platform_device *pdev, + shost->max_id = HISI_SAS_MAX_DEVICES; + shost->max_lun = ~0; + shost->max_channel = 1; +- shost->max_cmd_len = 16; ++ shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN; + if (hisi_hba->hw->slot_index_alloc) { + shost->can_queue = HISI_SAS_MAX_COMMANDS; + shost->cmd_per_lun = HISI_SAS_MAX_COMMANDS; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 596b5426d9953..e8f5a8023a1af 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -465,6 +465,12 @@ + #define ITCT_HDR_RTOLT_OFF 48 + #define ITCT_HDR_RTOLT_MSK (0xffffULL << ITCT_HDR_RTOLT_OFF) + ++/*debugfs*/ ++#define TWO_PARA_PER_LINE 2 ++#define FOUR_PARA_PER_LINE 4 ++#define DUMP_BUF_SIZE 8 ++#define BIST_BUF_SIZE 16 ++ + struct hisi_sas_protect_iu_v3_hw { + u32 dw0; + u32 lbrtcv; +@@ -535,6 +541,43 @@ struct hisi_sas_err_record_v3 { + + #define BASE_VECTORS_V3_HW 16 + #define MIN_AFFINE_VECTORS_V3_HW (BASE_VECTORS_V3_HW + 1) ++#define IRQ_PHY_UP_DOWN_INDEX 1 ++#define IRQ_CHL_INDEX 2 ++#define IRQ_AXI_INDEX 11 ++ ++#define DELAY_FOR_RESET_HW 100 ++#define HDR_SG_MOD 0x2 ++#define LUN_SIZE 8 ++#define ATTR_PRIO_REGION 9 ++#define CDB_REGION 12 ++#define PRIO_OFF 3 ++#define TMF_REGION 10 ++#define TAG_MSB 12 ++#define TAG_LSB 13 ++#define SMP_FRAME_TYPE 2 ++#define SMP_CRC_SIZE 4 ++#define HDR_TAG_OFF 3 ++#define HOST_NO_OFF 6 ++#define PHY_NO_OFF 7 ++#define IDENTIFY_REG_READ 6 ++#define LINK_RESET_TIMEOUT_OFF 4 ++#define DECIMALISM_FLAG 10 ++#define WAIT_RETRY 100 ++#define WAIT_TMROUT 5000 ++ ++#define ID_DWORD0_INDEX 0 ++#define ID_DWORD1_INDEX 1 ++#define ID_DWORD2_INDEX 2 ++#define ID_DWORD3_INDEX 3 ++#define ID_DWORD4_INDEX 4 ++#define ID_DWORD5_INDEX 5 ++#define TICKS_BIT_INDEX 24 ++#define COUNT_BIT_INDEX 8 ++ ++#define PORT_REG_LENGTH 0x100 ++#define GLOBAL_REG_LENGTH 0x800 ++#define AXI_REG_LENGTH 0x61 ++#define RAS_REG_LENGTH 0x10 + + #define CHNL_INT_STS_MSK 0xeeeeeeee + #define CHNL_INT_STS_PHY_MSK 0xe +@@ -807,17 +850,17 @@ static void config_id_frame_v3_hw(struct hisi_hba *hisi_hba, int phy_no) + identify_buffer = (u32 *)(&identify_frame); + + hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD0, +- __swab32(identify_buffer[0])); ++ __swab32(identify_buffer[ID_DWORD0_INDEX])); + hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD1, +- __swab32(identify_buffer[1])); ++ __swab32(identify_buffer[ID_DWORD1_INDEX])); + hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD2, +- __swab32(identify_buffer[2])); ++ __swab32(identify_buffer[ID_DWORD2_INDEX])); + hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD3, +- __swab32(identify_buffer[3])); ++ __swab32(identify_buffer[ID_DWORD3_INDEX])); + hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD4, +- __swab32(identify_buffer[4])); ++ __swab32(identify_buffer[ID_DWORD4_INDEX])); + hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD5, +- __swab32(identify_buffer[5])); ++ __swab32(identify_buffer[ID_DWORD5_INDEX])); + } + + static void setup_itct_v3_hw(struct hisi_hba *hisi_hba, +@@ -937,7 +980,7 @@ static int reset_hw_v3_hw(struct hisi_hba *hisi_hba) + + /* Disable all of the PHYs */ + hisi_sas_stop_phys(hisi_hba); +- udelay(50); ++ udelay(HISI_SAS_DELAY_FOR_PHY_DISABLE); + + /* Ensure axi bus idle */ + ret = hisi_sas_read32_poll_timeout(AXI_CFG, val, !val, +@@ -977,7 +1020,7 @@ static int hw_init_v3_hw(struct hisi_hba *hisi_hba) + return rc; + } + +- msleep(100); ++ msleep(DELAY_FOR_RESET_HW); + init_reg_v3_hw(hisi_hba); + + if (guid_parse("D5918B4B-37AE-4E10-A99F-E5E8A6EF4C1F", &guid)) { +@@ -1026,7 +1069,7 @@ static void disable_phy_v3_hw(struct hisi_hba *hisi_hba, int phy_no) + cfg &= ~PHY_CFG_ENA_MSK; + hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg); + +- mdelay(50); ++ mdelay(HISI_SAS_DELAY_FOR_PHY_DISABLE); + + state = hisi_sas_read32(hisi_hba, PHY_STATE); + if (state & BIT(phy_no)) { +@@ -1062,7 +1105,7 @@ static void phy_hard_reset_v3_hw(struct hisi_hba *hisi_hba, int phy_no) + hisi_sas_phy_write32(hisi_hba, phy_no, TXID_AUTO, + txid_auto | TX_HARDRST_MSK); + } +- msleep(100); ++ msleep(HISI_SAS_DELAY_FOR_PHY_DISABLE); + hisi_sas_phy_enable(hisi_hba, phy_no, 1); + } + +@@ -1107,7 +1150,8 @@ static int get_wideport_bitmap_v3_hw(struct hisi_hba *hisi_hba, int port_id) + + for (i = 0; i < hisi_hba->n_phy; i++) + if (phy_state & BIT(i)) +- if (((phy_port_num_ma >> (i * 4)) & 0xf) == port_id) ++ if (((phy_port_num_ma >> (i * HISI_SAS_REG_MEM_SIZE)) & 0xf) == ++ port_id) + bitmap |= BIT(i); + + return bitmap; +@@ -1305,9 +1349,9 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba, + dw1 |= sas_dev->device_id << CMD_HDR_DEV_ID_OFF; + + dw2 = (((sizeof(struct ssp_command_iu) + sizeof(struct ssp_frame_hdr) +- + 3) / 4) << CMD_HDR_CFL_OFF) | +- ((HISI_SAS_MAX_SSP_RESP_SZ / 4) << CMD_HDR_MRFL_OFF) | +- (2 << CMD_HDR_SG_MOD_OFF); ++ + 3) / BYTE_TO_DW) << CMD_HDR_CFL_OFF) | ++ ((HISI_SAS_MAX_SSP_RESP_SZ / BYTE_TO_DW) << CMD_HDR_MRFL_OFF) | ++ (HDR_SG_MOD << CMD_HDR_SG_MOD_OFF); + hdr->dw2 = cpu_to_le32(dw2); + hdr->transfer_tags = cpu_to_le32(slot->idx); + +@@ -1327,18 +1371,19 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba, + buf_cmd = hisi_sas_cmd_hdr_addr_mem(slot) + + sizeof(struct ssp_frame_hdr); + +- memcpy(buf_cmd, &task->ssp_task.LUN, 8); ++ memcpy(buf_cmd, &task->ssp_task.LUN, LUN_SIZE); + if (!tmf) { +- buf_cmd[9] = ssp_task->task_attr; +- memcpy(buf_cmd + 12, scsi_cmnd->cmnd, scsi_cmnd->cmd_len); ++ buf_cmd[ATTR_PRIO_REGION] = ssp_task->task_attr; ++ memcpy(buf_cmd + CDB_REGION, scsi_cmnd->cmnd, ++ scsi_cmnd->cmd_len); + } else { +- buf_cmd[10] = tmf->tmf; ++ buf_cmd[TMF_REGION] = tmf->tmf; + switch (tmf->tmf) { + case TMF_ABORT_TASK: + case TMF_QUERY_TASK: +- buf_cmd[12] = ++ buf_cmd[TAG_MSB] = + (tmf->tag_of_task_to_be_managed >> 8) & 0xff; +- buf_cmd[13] = ++ buf_cmd[TAG_LSB] = + tmf->tag_of_task_to_be_managed & 0xff; + break; + default: +@@ -1371,7 +1416,8 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba, + unsigned int interval = scsi_prot_interval(scsi_cmnd); + unsigned int ilog2_interval = ilog2(interval); + +- len = (task->total_xfer_len >> ilog2_interval) * 8; ++ len = (task->total_xfer_len >> ilog2_interval) * ++ BYTE_TO_DDW; + } + } + +@@ -1391,6 +1437,7 @@ static void prep_smp_v3_hw(struct hisi_hba *hisi_hba, + struct hisi_sas_device *sas_dev = device->lldd_dev; + dma_addr_t req_dma_addr; + unsigned int req_len; ++ u32 cfl; + + /* req */ + sg_req = &task->smp_task.smp_req; +@@ -1401,7 +1448,7 @@ static void prep_smp_v3_hw(struct hisi_hba *hisi_hba, + /* dw0 */ + hdr->dw0 = cpu_to_le32((port->id << CMD_HDR_PORT_OFF) | + (1 << CMD_HDR_PRIORITY_OFF) | /* high pri */ +- (2 << CMD_HDR_CMD_OFF)); /* smp */ ++ (SMP_FRAME_TYPE << CMD_HDR_CMD_OFF)); /* smp */ + + /* map itct entry */ + hdr->dw1 = cpu_to_le32((sas_dev->device_id << CMD_HDR_DEV_ID_OFF) | +@@ -1409,8 +1456,9 @@ static void prep_smp_v3_hw(struct hisi_hba *hisi_hba, + (DIR_NO_DATA << CMD_HDR_DIR_OFF)); + + /* dw2 */ +- hdr->dw2 = cpu_to_le32((((req_len - 4) / 4) << CMD_HDR_CFL_OFF) | +- (HISI_SAS_MAX_SMP_RESP_SZ / 4 << ++ cfl = (req_len - SMP_CRC_SIZE) / BYTE_TO_DW; ++ hdr->dw2 = cpu_to_le32((cfl << CMD_HDR_CFL_OFF) | ++ (HISI_SAS_MAX_SMP_RESP_SZ / BYTE_TO_DW << + CMD_HDR_MRFL_OFF)); + + hdr->transfer_tags = cpu_to_le32(slot->idx << CMD_HDR_IPTT_OFF); +@@ -1477,12 +1525,13 @@ static void prep_ata_v3_hw(struct hisi_hba *hisi_hba, + struct ata_queued_cmd *qc = task->uldd_task; + + hdr_tag = qc->tag; +- task->ata_task.fis.sector_count |= (u8) (hdr_tag << 3); ++ task->ata_task.fis.sector_count |= ++ (u8)(hdr_tag << HDR_TAG_OFF); + dw2 |= hdr_tag << CMD_HDR_NCQ_TAG_OFF; + } + +- dw2 |= (HISI_SAS_MAX_STP_RESP_SZ / 4) << CMD_HDR_CFL_OFF | +- 2 << CMD_HDR_SG_MOD_OFF; ++ dw2 |= (HISI_SAS_MAX_STP_RESP_SZ / BYTE_TO_DW) << CMD_HDR_CFL_OFF | ++ HDR_SG_MOD << CMD_HDR_SG_MOD_OFF; + hdr->dw2 = cpu_to_le32(dw2); + + /* dw3 */ +@@ -1542,9 +1591,9 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) + hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 1); + + port_id = hisi_sas_read32(hisi_hba, PHY_PORT_NUM_MA); +- port_id = (port_id >> (4 * phy_no)) & 0xf; ++ port_id = (port_id >> (HISI_SAS_REG_MEM_SIZE * phy_no)) & 0xf; + link_rate = hisi_sas_read32(hisi_hba, PHY_CONN_RATE); +- link_rate = (link_rate >> (phy_no * 4)) & 0xf; ++ link_rate = (link_rate >> (phy_no * HISI_SAS_REG_MEM_SIZE)) & 0xf; + + if (port_id == 0xf) { + dev_err(dev, "phyup: phy%d invalid portid\n", phy_no); +@@ -1577,8 +1626,8 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) + + sas_phy->oob_mode = SATA_OOB_MODE; + attached_sas_addr[0] = 0x50; +- attached_sas_addr[6] = shost->host_no; +- attached_sas_addr[7] = phy_no; ++ attached_sas_addr[HOST_NO_OFF] = shost->host_no; ++ attached_sas_addr[PHY_NO_OFF] = phy_no; + memcpy(sas_phy->attached_sas_addr, + attached_sas_addr, + SAS_ADDR_SIZE); +@@ -1594,7 +1643,7 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) + (struct sas_identify_frame *)frame_rcvd; + + dev_info(dev, "phyup: phy%d link_rate=%d\n", phy_no, link_rate); +- for (i = 0; i < 6; i++) { ++ for (i = 0; i < IDENTIFY_REG_READ; i++) { + u32 idaf = hisi_sas_phy_read32(hisi_hba, phy_no, + RX_IDAF_DWORD0 + (i * 4)); + frame_rcvd[i] = __swab32(idaf); +@@ -1864,7 +1913,7 @@ static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no) + + dev_warn(dev, "phy%d stp link timeout (0x%x)\n", + phy_no, reg_value); +- if (reg_value & BIT(4)) ++ if (reg_value & BIT(LINK_RESET_TIMEOUT_OFF)) + hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET); + } + +@@ -2581,7 +2630,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) + struct pci_dev *pdev = hisi_hba->pci_dev; + int rc, i; + +- rc = devm_request_irq(dev, pci_irq_vector(pdev, 1), ++ rc = devm_request_irq(dev, pci_irq_vector(pdev, IRQ_PHY_UP_DOWN_INDEX), + int_phy_up_down_bcast_v3_hw, 0, + DRV_NAME " phy", hisi_hba); + if (rc) { +@@ -2589,7 +2638,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) + return -ENOENT; + } + +- rc = devm_request_irq(dev, pci_irq_vector(pdev, 2), ++ rc = devm_request_irq(dev, pci_irq_vector(pdev, IRQ_CHL_INDEX), + int_chnl_int_v3_hw, 0, + DRV_NAME " channel", hisi_hba); + if (rc) { +@@ -2597,7 +2646,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) + return -ENOENT; + } + +- rc = devm_request_irq(dev, pci_irq_vector(pdev, 11), ++ rc = devm_request_irq(dev, pci_irq_vector(pdev, IRQ_AXI_INDEX), + fatal_axi_int_v3_hw, 0, + DRV_NAME " fatal", hisi_hba); + if (rc) { +@@ -2610,7 +2659,8 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) + + for (i = 0; i < hisi_hba->cq_nvecs; i++) { + struct hisi_sas_cq *cq = &hisi_hba->cq[i]; +- int nr = hisi_sas_intr_conv ? 16 : 16 + i; ++ int nr = hisi_sas_intr_conv ? BASE_VECTORS_V3_HW : ++ BASE_VECTORS_V3_HW + i; + unsigned long irqflags = hisi_sas_intr_conv ? IRQF_SHARED : + IRQF_ONESHOT; + +@@ -2668,14 +2718,14 @@ static void interrupt_disable_v3_hw(struct hisi_hba *hisi_hba) + struct pci_dev *pdev = hisi_hba->pci_dev; + int i; + +- synchronize_irq(pci_irq_vector(pdev, 1)); +- synchronize_irq(pci_irq_vector(pdev, 2)); +- synchronize_irq(pci_irq_vector(pdev, 11)); ++ synchronize_irq(pci_irq_vector(pdev, IRQ_PHY_UP_DOWN_INDEX)); ++ synchronize_irq(pci_irq_vector(pdev, IRQ_CHL_INDEX)); ++ synchronize_irq(pci_irq_vector(pdev, IRQ_AXI_INDEX)); + for (i = 0; i < hisi_hba->queue_count; i++) + hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK + 0x4 * i, 0x1); + + for (i = 0; i < hisi_hba->cq_nvecs; i++) +- synchronize_irq(pci_irq_vector(pdev, i + 16)); ++ synchronize_irq(pci_irq_vector(pdev, i + BASE_VECTORS_V3_HW)); + + hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xffffffff); + hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0xffffffff); +@@ -2707,7 +2757,7 @@ static int disable_host_v3_hw(struct hisi_hba *hisi_hba) + + hisi_sas_stop_phys(hisi_hba); + +- mdelay(10); ++ mdelay(HISI_SAS_DELAY_FOR_PHY_DISABLE); + + reg_val = hisi_sas_read32(hisi_hba, AXI_MASTER_CFG_BASE + + AM_CTRL_GLOBAL); +@@ -2843,13 +2893,13 @@ static ssize_t intr_coal_ticks_v3_hw_store(struct device *dev, + u32 intr_coal_ticks; + int ret; + +- ret = kstrtou32(buf, 10, &intr_coal_ticks); ++ ret = kstrtou32(buf, DECIMALISM_FLAG, &intr_coal_ticks); + if (ret) { + dev_err(dev, "Input data of interrupt coalesce unmatch\n"); + return -EINVAL; + } + +- if (intr_coal_ticks >= BIT(24)) { ++ if (intr_coal_ticks >= BIT(TICKS_BIT_INDEX)) { + dev_err(dev, "intr_coal_ticks must be less than 2^24!\n"); + return -EINVAL; + } +@@ -2882,13 +2932,13 @@ static ssize_t intr_coal_count_v3_hw_store(struct device *dev, + u32 intr_coal_count; + int ret; + +- ret = kstrtou32(buf, 10, &intr_coal_count); ++ ret = kstrtou32(buf, DECIMALISM_FLAG, &intr_coal_count); + if (ret) { + dev_err(dev, "Input data of interrupt coalesce unmatch\n"); + return -EINVAL; + } + +- if (intr_coal_count >= BIT(8)) { ++ if (intr_coal_count >= BIT(COUNT_BIT_INDEX)) { + dev_err(dev, "intr_coal_count must be less than 2^8!\n"); + return -EINVAL; + } +@@ -3014,7 +3064,7 @@ static const struct hisi_sas_debugfs_reg_lu debugfs_port_reg_lu[] = { + + static const struct hisi_sas_debugfs_reg debugfs_port_reg = { + .lu = debugfs_port_reg_lu, +- .count = 0x100, ++ .count = PORT_REG_LENGTH, + .base_off = PORT_BASE, + }; + +@@ -3088,7 +3138,7 @@ static const struct hisi_sas_debugfs_reg_lu debugfs_global_reg_lu[] = { + + static const struct hisi_sas_debugfs_reg debugfs_global_reg = { + .lu = debugfs_global_reg_lu, +- .count = 0x800, ++ .count = GLOBAL_REG_LENGTH, + }; + + static const struct hisi_sas_debugfs_reg_lu debugfs_axi_reg_lu[] = { +@@ -3101,7 +3151,7 @@ static const struct hisi_sas_debugfs_reg_lu debugfs_axi_reg_lu[] = { + + static const struct hisi_sas_debugfs_reg debugfs_axi_reg = { + .lu = debugfs_axi_reg_lu, +- .count = 0x61, ++ .count = AXI_REG_LENGTH, + .base_off = AXI_MASTER_CFG_BASE, + }; + +@@ -3118,7 +3168,7 @@ static const struct hisi_sas_debugfs_reg_lu debugfs_ras_reg_lu[] = { + + static const struct hisi_sas_debugfs_reg debugfs_ras_reg = { + .lu = debugfs_ras_reg_lu, +- .count = 0x10, ++ .count = RAS_REG_LENGTH, + .base_off = RAS_BASE, + }; + +@@ -3127,7 +3177,7 @@ static void debugfs_snapshot_prepare_v3_hw(struct hisi_hba *hisi_hba) + struct Scsi_Host *shost = hisi_hba->shost; + + scsi_block_requests(shost); +- wait_cmds_complete_timeout_v3_hw(hisi_hba, 100, 5000); ++ wait_cmds_complete_timeout_v3_hw(hisi_hba, WAIT_RETRY, WAIT_TMROUT); + + set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); + hisi_sas_sync_cqs(hisi_hba); +@@ -3168,7 +3218,7 @@ static void read_iost_itct_cache_v3_hw(struct hisi_hba *hisi_hba, + return; + } + +- memset(buf, 0, cache_dw_size * 4); ++ memset(buf, 0, cache_dw_size * BYTE_TO_DW); + buf[0] = val; + + for (i = 1; i < cache_dw_size; i++) +@@ -3215,7 +3265,7 @@ static void hisi_sas_bist_test_restore_v3_hw(struct hisi_hba *hisi_hba) + reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, PROG_PHY_LINK_RATE); + /* init OOB link rate as 1.5 Gbits */ + reg_val &= ~CFG_PROG_OOB_PHY_LINK_RATE_MSK; +- reg_val |= (0x8 << CFG_PROG_OOB_PHY_LINK_RATE_OFF); ++ reg_val |= (SAS_LINK_RATE_1_5_GBPS << CFG_PROG_OOB_PHY_LINK_RATE_OFF); + hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE, reg_val); + + /* enable PHY */ +@@ -3224,6 +3274,9 @@ static void hisi_sas_bist_test_restore_v3_hw(struct hisi_hba *hisi_hba) + + #define SAS_PHY_BIST_CODE_INIT 0x1 + #define SAS_PHY_BIST_CODE1_INIT 0X80 ++#define SAS_PHY_BIST_INIT_DELAY 100 ++#define SAS_PHY_BIST_LOOP_TEST_0 1 ++#define SAS_PHY_BIST_LOOP_TEST_1 2 + static int debugfs_set_bist_v3_hw(struct hisi_hba *hisi_hba, bool enable) + { + u32 reg_val, mode_tmp; +@@ -3242,7 +3295,8 @@ static int debugfs_set_bist_v3_hw(struct hisi_hba *hisi_hba, bool enable) + ffe[FFE_SATA_1_5_GBPS], ffe[FFE_SATA_3_0_GBPS], + ffe[FFE_SATA_6_0_GBPS], fix_code[FIXED_CODE], + fix_code[FIXED_CODE_1]); +- mode_tmp = path_mode ? 2 : 1; ++ mode_tmp = path_mode ? SAS_PHY_BIST_LOOP_TEST_1 : ++ SAS_PHY_BIST_LOOP_TEST_0; + if (enable) { + /* some preparations before bist test */ + hisi_sas_bist_test_prep_v3_hw(hisi_hba); +@@ -3285,13 +3339,13 @@ static int debugfs_set_bist_v3_hw(struct hisi_hba *hisi_hba, bool enable) + SAS_PHY_BIST_CODE1_INIT); + } + +- mdelay(100); ++ mdelay(SAS_PHY_BIST_INIT_DELAY); + reg_val |= (CFG_RX_BIST_EN_MSK | CFG_TX_BIST_EN_MSK); + hisi_sas_phy_write32(hisi_hba, phy_no, SAS_PHY_BIST_CTRL, + reg_val); + + /* clear error bit */ +- mdelay(100); ++ mdelay(SAS_PHY_BIST_INIT_DELAY); + hisi_sas_phy_read32(hisi_hba, phy_no, SAS_BIST_ERR_CNT); + } else { + /* disable bist test and recover it */ +@@ -3482,7 +3536,7 @@ static void debugfs_snapshot_port_reg_v3_hw(struct hisi_hba *hisi_hba) + for (phy_cnt = 0; phy_cnt < hisi_hba->n_phy; phy_cnt++) { + databuf = hisi_hba->debugfs_port_reg[dump_index][phy_cnt].data; + for (i = 0; i < port->count; i++, databuf++) { +- offset = port->base_off + 4 * i; ++ offset = port->base_off + HISI_SAS_REG_MEM_SIZE * i; + *databuf = hisi_sas_phy_read32(hisi_hba, phy_cnt, + offset); + } +@@ -3496,7 +3550,8 @@ static void debugfs_snapshot_global_reg_v3_hw(struct hisi_hba *hisi_hba) + int i; + + for (i = 0; i < debugfs_global_reg.count; i++, databuf++) +- *databuf = hisi_sas_read32(hisi_hba, 4 * i); ++ *databuf = hisi_sas_read32(hisi_hba, ++ HISI_SAS_REG_MEM_SIZE * i); + } + + static void debugfs_snapshot_axi_reg_v3_hw(struct hisi_hba *hisi_hba) +@@ -3507,7 +3562,9 @@ static void debugfs_snapshot_axi_reg_v3_hw(struct hisi_hba *hisi_hba) + int i; + + for (i = 0; i < axi->count; i++, databuf++) +- *databuf = hisi_sas_read32(hisi_hba, 4 * i + axi->base_off); ++ *databuf = hisi_sas_read32(hisi_hba, ++ HISI_SAS_REG_MEM_SIZE * i + ++ axi->base_off); + } + + static void debugfs_snapshot_ras_reg_v3_hw(struct hisi_hba *hisi_hba) +@@ -3518,7 +3575,9 @@ static void debugfs_snapshot_ras_reg_v3_hw(struct hisi_hba *hisi_hba) + int i; + + for (i = 0; i < ras->count; i++, databuf++) +- *databuf = hisi_sas_read32(hisi_hba, 4 * i + ras->base_off); ++ *databuf = hisi_sas_read32(hisi_hba, ++ HISI_SAS_REG_MEM_SIZE * i + ++ ras->base_off); + } + + static void debugfs_snapshot_itct_reg_v3_hw(struct hisi_hba *hisi_hba) +@@ -3581,7 +3640,7 @@ static void debugfs_print_reg_v3_hw(u32 *regs_val, struct seq_file *s, + int i; + + for (i = 0; i < reg->count; i++) { +- int off = i * 4; ++ int off = i * HISI_SAS_REG_MEM_SIZE; + const char *name; + + name = debugfs_to_reg_name_v3_hw(off, reg->base_off, +@@ -3659,9 +3718,9 @@ static void debugfs_show_row_64_v3_hw(struct seq_file *s, int index, + + /* completion header size not fixed per HW version */ + seq_printf(s, "index %04d:\n\t", index); +- for (i = 1; i <= sz / 8; i++, ptr++) { ++ for (i = 1; i <= sz / BYTE_TO_DDW; i++, ptr++) { + seq_printf(s, " 0x%016llx", le64_to_cpu(*ptr)); +- if (!(i % 2)) ++ if (!(i % TWO_PARA_PER_LINE)) + seq_puts(s, "\n\t"); + } + +@@ -3675,9 +3734,9 @@ static void debugfs_show_row_32_v3_hw(struct seq_file *s, int index, + + /* completion header size not fixed per HW version */ + seq_printf(s, "index %04d:\n\t", index); +- for (i = 1; i <= sz / 4; i++, ptr++) { ++ for (i = 1; i <= sz / BYTE_TO_DW; i++, ptr++) { + seq_printf(s, " 0x%08x", le32_to_cpu(*ptr)); +- if (!(i % 4)) ++ if (!(i % FOUR_PARA_PER_LINE)) + seq_puts(s, "\n\t"); + } + seq_puts(s, "\n"); +@@ -3762,7 +3821,7 @@ static int debugfs_iost_cache_v3_hw_show(struct seq_file *s, void *p) + struct hisi_sas_debugfs_iost_cache *debugfs_iost_cache = s->private; + struct hisi_sas_iost_itct_cache *iost_cache = + debugfs_iost_cache->cache; +- u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * 4; ++ u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * BYTE_TO_DW; + int i, tab_idx; + __le64 *iost; + +@@ -3810,7 +3869,7 @@ static int debugfs_itct_cache_v3_hw_show(struct seq_file *s, void *p) + struct hisi_sas_debugfs_itct_cache *debugfs_itct_cache = s->private; + struct hisi_sas_iost_itct_cache *itct_cache = + debugfs_itct_cache->cache; +- u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * 4; ++ u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * BYTE_TO_DW; + int i, tab_idx; + __le64 *itct; + +@@ -3839,12 +3898,12 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba, int index) + u64 *debugfs_timestamp; + struct dentry *dump_dentry; + struct dentry *dentry; +- char name[256]; ++ char name[NAME_BUF_SIZE]; + int p; + int c; + int d; + +- snprintf(name, 256, "%d", index); ++ snprintf(name, NAME_BUF_SIZE, "%d", index); + + dump_dentry = debugfs_create_dir(name, hisi_hba->debugfs_dump_dentry); + +@@ -3860,7 +3919,7 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba, int index) + /* Create port dir and files */ + dentry = debugfs_create_dir("port", dump_dentry); + for (p = 0; p < hisi_hba->n_phy; p++) { +- snprintf(name, 256, "%d", p); ++ snprintf(name, NAME_BUF_SIZE, "%d", p); + + debugfs_create_file(name, 0400, dentry, + &hisi_hba->debugfs_port_reg[index][p], +@@ -3870,7 +3929,7 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba, int index) + /* Create CQ dir and files */ + dentry = debugfs_create_dir("cq", dump_dentry); + for (c = 0; c < hisi_hba->queue_count; c++) { +- snprintf(name, 256, "%d", c); ++ snprintf(name, NAME_BUF_SIZE, "%d", c); + + debugfs_create_file(name, 0400, dentry, + &hisi_hba->debugfs_cq[index][c], +@@ -3880,7 +3939,7 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba, int index) + /* Create DQ dir and files */ + dentry = debugfs_create_dir("dq", dump_dentry); + for (d = 0; d < hisi_hba->queue_count; d++) { +- snprintf(name, 256, "%d", d); ++ snprintf(name, NAME_BUF_SIZE, "%d", d); + + debugfs_create_file(name, 0400, dentry, + &hisi_hba->debugfs_dq[index][d], +@@ -3917,9 +3976,9 @@ static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file, + size_t count, loff_t *ppos) + { + struct hisi_hba *hisi_hba = file->f_inode->i_private; +- char buf[8]; ++ char buf[DUMP_BUF_SIZE]; + +- if (count > 8) ++ if (count > DUMP_BUF_SIZE) + return -EFAULT; + + if (copy_from_user(buf, user_buf, count)) +@@ -3983,7 +4042,7 @@ static ssize_t debugfs_bist_linkrate_v3_hw_write(struct file *filp, + { + struct seq_file *m = filp->private_data; + struct hisi_hba *hisi_hba = m->private; +- char kbuf[16] = {}, *pkbuf; ++ char kbuf[BIST_BUF_SIZE] = {}, *pkbuf; + bool found = false; + int i; + +@@ -4000,7 +4059,7 @@ static ssize_t debugfs_bist_linkrate_v3_hw_write(struct file *filp, + + for (i = 0; i < ARRAY_SIZE(debugfs_loop_linkrate_v3_hw); i++) { + if (!strncmp(debugfs_loop_linkrate_v3_hw[i].name, +- pkbuf, 16)) { ++ pkbuf, BIST_BUF_SIZE)) { + hisi_hba->debugfs_bist_linkrate = + debugfs_loop_linkrate_v3_hw[i].value; + found = true; +@@ -4073,7 +4132,7 @@ static ssize_t debugfs_bist_code_mode_v3_hw_write(struct file *filp, + { + struct seq_file *m = filp->private_data; + struct hisi_hba *hisi_hba = m->private; +- char kbuf[16] = {}, *pkbuf; ++ char kbuf[BIST_BUF_SIZE] = {}, *pkbuf; + bool found = false; + int i; + +@@ -4090,7 +4149,7 @@ static ssize_t debugfs_bist_code_mode_v3_hw_write(struct file *filp, + + for (i = 0; i < ARRAY_SIZE(debugfs_loop_code_mode_v3_hw); i++) { + if (!strncmp(debugfs_loop_code_mode_v3_hw[i].name, +- pkbuf, 16)) { ++ pkbuf, BIST_BUF_SIZE)) { + hisi_hba->debugfs_bist_code_mode = + debugfs_loop_code_mode_v3_hw[i].value; + found = true; +@@ -4250,7 +4309,7 @@ static ssize_t debugfs_bist_mode_v3_hw_write(struct file *filp, + { + struct seq_file *m = filp->private_data; + struct hisi_hba *hisi_hba = m->private; +- char kbuf[16] = {}, *pkbuf; ++ char kbuf[BIST_BUF_SIZE] = {}, *pkbuf; + bool found = false; + int i; + +@@ -4266,7 +4325,8 @@ static ssize_t debugfs_bist_mode_v3_hw_write(struct file *filp, + pkbuf = strstrip(kbuf); + + for (i = 0; i < ARRAY_SIZE(debugfs_loop_modes_v3_hw); i++) { +- if (!strncmp(debugfs_loop_modes_v3_hw[i].name, pkbuf, 16)) { ++ if (!strncmp(debugfs_loop_modes_v3_hw[i].name, pkbuf, ++ BIST_BUF_SIZE)) { + hisi_hba->debugfs_bist_mode = + debugfs_loop_modes_v3_hw[i].value; + found = true; +@@ -4604,8 +4664,9 @@ static int debugfs_fifo_data_v3_hw_show(struct seq_file *s, void *p) + + debugfs_read_fifo_data_v3_hw(phy); + +- debugfs_show_row_32_v3_hw(s, 0, HISI_SAS_FIFO_DATA_DW_SIZE * 4, +- (__le32 *)phy->fifo.rd_data); ++ debugfs_show_row_32_v3_hw(s, 0, ++ HISI_SAS_FIFO_DATA_DW_SIZE * HISI_SAS_REG_MEM_SIZE, ++ phy->fifo.rd_data); + + return 0; + } +@@ -4737,14 +4798,14 @@ static int debugfs_alloc_v3_hw(struct hisi_hba *hisi_hba, int dump_index) + struct hisi_sas_debugfs_regs *regs = + &hisi_hba->debugfs_regs[dump_index][r]; + +- sz = debugfs_reg_array_v3_hw[r]->count * 4; ++ sz = debugfs_reg_array_v3_hw[r]->count * HISI_SAS_REG_MEM_SIZE; + regs->data = devm_kmalloc(dev, sz, GFP_KERNEL); + if (!regs->data) + goto fail; + regs->hisi_hba = hisi_hba; + } + +- sz = debugfs_port_reg.count * 4; ++ sz = debugfs_port_reg.count * HISI_SAS_REG_MEM_SIZE; + for (p = 0; p < hisi_hba->n_phy; p++) { + struct hisi_sas_debugfs_port *port = + &hisi_hba->debugfs_port_reg[dump_index][p]; +@@ -4854,11 +4915,11 @@ static void debugfs_phy_down_cnt_init_v3_hw(struct hisi_hba *hisi_hba) + { + struct dentry *dir = debugfs_create_dir("phy_down_cnt", + hisi_hba->debugfs_dir); +- char name[16]; ++ char name[NAME_BUF_SIZE]; + int phy_no; + + for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) { +- snprintf(name, 16, "%d", phy_no); ++ snprintf(name, NAME_BUF_SIZE, "%d", phy_no); + debugfs_create_file(name, 0600, dir, + &hisi_hba->phy[phy_no], + &debugfs_phy_down_cnt_v3_hw_fops); +@@ -5027,7 +5088,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) + shost->max_id = HISI_SAS_MAX_DEVICES; + shost->max_lun = ~0; + shost->max_channel = 1; +- shost->max_cmd_len = 16; ++ shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN; + shost->can_queue = HISI_SAS_UNRESERVED_IPTT; + shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT; + if (hisi_hba->iopoll_q_cnt) +@@ -5108,12 +5169,13 @@ hisi_sas_v3_destroy_irqs(struct pci_dev *pdev, struct hisi_hba *hisi_hba) + { + int i; + +- devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 1), hisi_hba); +- devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 2), hisi_hba); +- devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 11), hisi_hba); ++ devm_free_irq(&pdev->dev, pci_irq_vector(pdev, IRQ_PHY_UP_DOWN_INDEX), hisi_hba); ++ devm_free_irq(&pdev->dev, pci_irq_vector(pdev, IRQ_CHL_INDEX), hisi_hba); ++ devm_free_irq(&pdev->dev, pci_irq_vector(pdev, IRQ_AXI_INDEX), hisi_hba); + for (i = 0; i < hisi_hba->cq_nvecs; i++) { + struct hisi_sas_cq *cq = &hisi_hba->cq[i]; +- int nr = hisi_sas_intr_conv ? 16 : 16 + i; ++ int nr = hisi_sas_intr_conv ? BASE_VECTORS_V3_HW : ++ BASE_VECTORS_V3_HW + i; + + devm_free_irq(&pdev->dev, pci_irq_vector(pdev, nr), cq); + } +-- +2.51.0 + diff --git a/queue-6.6/scsi-ufs-core-fix-serror-in-ufshcd_rtc_work-during-u.patch b/queue-6.6/scsi-ufs-core-fix-serror-in-ufshcd_rtc_work-during-u.patch new file mode 100644 index 0000000000..f4f238462e --- /dev/null +++ b/queue-6.6/scsi-ufs-core-fix-serror-in-ufshcd_rtc_work-during-u.patch @@ -0,0 +1,85 @@ +From 64d98e7f0c51c57e674f411bc62f2157463da830 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Mar 2026 11:51:28 +0800 +Subject: scsi: ufs: core: Fix SError in ufshcd_rtc_work() during UFS suspend + +From: Wang Shuaiwei + +[ Upstream commit b0bd84c39289ef6a6c3827dd52c875659291970a ] + +In __ufshcd_wl_suspend(), cancel_delayed_work_sync() is called to cancel +the UFS RTC work, but it is placed after ufshcd_vops_suspend(hba, pm_op, +POST_CHANGE). This creates a race condition where ufshcd_rtc_work() can +still be running while ufshcd_vops_suspend() is executing. When +UFSHCD_CAP_CLK_GATING is not supported, the condition +!hba->clk_gating.active_reqs is always true, causing ufshcd_update_rtc() +to be executed. Since ufshcd_vops_suspend() typically performs clock +gating operations, executing ufshcd_update_rtc() at that moment triggers +an SError. The kernel panic trace is as follows: + +Kernel panic - not syncing: Asynchronous SError Interrupt +Call trace: + dump_backtrace+0xec/0x128 + show_stack+0x18/0x28 + dump_stack_lvl+0x40/0xa0 + dump_stack+0x18/0x24 + panic+0x148/0x374 + nmi_panic+0x3c/0x8c + arm64_serror_panic+0x64/0x8c + do_serror+0xc4/0xc8 + el1h_64_error_handler+0x34/0x4c + el1h_64_error+0x68/0x6c + el1_interrupt+0x20/0x58 + el1h_64_irq_handler+0x18/0x24 + el1h_64_irq+0x68/0x6c + ktime_get+0xc4/0x12c + ufshcd_mcq_sq_stop+0x4c/0xec + ufshcd_mcq_sq_cleanup+0x64/0x1dc + ufshcd_clear_cmd+0x38/0x134 + ufshcd_issue_dev_cmd+0x298/0x4d0 + ufshcd_exec_dev_cmd+0x1a4/0x1c4 + ufshcd_query_attr+0xbc/0x19c + ufshcd_rtc_work+0x10c/0x1c8 + process_scheduled_works+0x1c4/0x45c + worker_thread+0x32c/0x3e8 + kthread+0x120/0x1d8 + ret_from_fork+0x10/0x20 + +Fix this by moving cancel_delayed_work_sync() before the call to +ufshcd_vops_suspend(hba, pm_op, PRE_CHANGE), ensuring the UFS RTC work is +fully completed or cancelled at that point. + +Cc: Bean Huo +Fixes: 6bf999e0eb41 ("scsi: ufs: core: Add UFS RTC support") +Reviewed-by: Bart Van Assche +Signed-off-by: Wang Shuaiwei +Link: https://patch.msgid.link/20260307035128.3419687-1-wangshuaiwei1@xiaomi.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/ufs/core/ufshcd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c +index d109a0c8f75ff..2dcb0146c17e3 100644 +--- a/drivers/ufs/core/ufshcd.c ++++ b/drivers/ufs/core/ufshcd.c +@@ -9882,6 +9882,7 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) + } + + flush_work(&hba->eeh_work); ++ cancel_delayed_work_sync(&hba->ufs_rtc_update_work); + + ret = ufshcd_vops_suspend(hba, pm_op, PRE_CHANGE); + if (ret) +@@ -9936,7 +9937,6 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) + if (ret) + goto set_link_active; + +- cancel_delayed_work_sync(&hba->ufs_rtc_update_work); + goto out; + + set_link_active: +-- +2.51.0 + diff --git a/queue-6.6/series b/queue-6.6/series index 0e882198e3..bd019aee8f 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -284,3 +284,9 @@ usb-class-cdc-wdm-fix-reordering-issue-in-read-code-path.patch usb-renesas_usbhs-fix-use-after-free-in-isr-during-device-removal.patch usb-mdc800-handle-signal-and-read-racing.patch usb-image-mdc800-kill-download-urb-on-timeout.patch +time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch +i3c-dw-i3c-master-set-sir_reject-in-dat-on-device-at.patch +scsi-ufs-core-fix-serror-in-ufshcd_rtc_work-during-u.patch +scsi-hisi_sas-add-time-interval-between-two-h2d-fis-.patch +scsi-hisi_sas-use-macro-instead-of-magic-number.patch +scsi-hisi_sas-fix-null-pointer-exception-during-user.patch diff --git a/queue-6.6/time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch b/queue-6.6/time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch new file mode 100644 index 0000000000..5d7eaa86d1 --- /dev/null +++ b/queue-6.6/time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch @@ -0,0 +1,39 @@ +From 2592d03504af1e88ed820de84a571e5e45997605 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Mar 2026 21:24:03 -0500 +Subject: time/jiffies: Mark jiffies_64_to_clock_t() notrace + +From: Steven Rostedt + +[ Upstream commit 755a648e78f12574482d4698d877375793867fa1 ] + +The trace_clock_jiffies() function that handles the "uptime" clock for +tracing calls jiffies_64_to_clock_t(). This causes the function tracer to +constantly recurse when the tracing clock is set to "uptime". Mark it +notrace to prevent unnecessary recursion when using the "uptime" clock. + +Fixes: 58d4e21e50ff3 ("tracing: Fix wraparound problems in "uptime" trace clock") +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Thomas Gleixner +Link: https://patch.msgid.link/20260306212403.72270bb2@robin +Signed-off-by: Sasha Levin +--- + kernel/time/time.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/time/time.c b/kernel/time/time.c +index 1ad88e97b4ebc..da7e8a02a0964 100644 +--- a/kernel/time/time.c ++++ b/kernel/time/time.c +@@ -702,7 +702,7 @@ EXPORT_SYMBOL(clock_t_to_jiffies); + * + * Return: jiffies_64 value converted to 64-bit "clock_t" (CLOCKS_PER_SEC) + */ +-u64 jiffies_64_to_clock_t(u64 x) ++notrace u64 jiffies_64_to_clock_t(u64 x) + { + #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 + # if HZ < USER_HZ +-- +2.51.0 +