]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 23 Jun 2025 09:14:07 +0000 (11:14 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 23 Jun 2025 09:14:07 +0000 (11:14 +0200)
added patches:
jbd2-fix-data-race-and-null-ptr-deref-in-jbd2_journal_dirty_metadata.patch
mm-huge_memory-fix-dereferencing-invalid-pmd-migration-entry.patch
rtc-improve-performance-of-rtc_time64_to_tm-.-add-tests.patch
rtc-make-rtc_time64_to_tm-support-dates-before-1970.patch

queue-5.4/jbd2-fix-data-race-and-null-ptr-deref-in-jbd2_journal_dirty_metadata.patch [new file with mode: 0644]
queue-5.4/mm-huge_memory-fix-dereferencing-invalid-pmd-migration-entry.patch [new file with mode: 0644]
queue-5.4/rtc-improve-performance-of-rtc_time64_to_tm-.-add-tests.patch [new file with mode: 0644]
queue-5.4/rtc-make-rtc_time64_to_tm-support-dates-before-1970.patch [new file with mode: 0644]
queue-5.4/series

diff --git a/queue-5.4/jbd2-fix-data-race-and-null-ptr-deref-in-jbd2_journal_dirty_metadata.patch b/queue-5.4/jbd2-fix-data-race-and-null-ptr-deref-in-jbd2_journal_dirty_metadata.patch
new file mode 100644 (file)
index 0000000..270870c
--- /dev/null
@@ -0,0 +1,73 @@
+From af98b0157adf6504fade79b3e6cb260c4ff68e37 Mon Sep 17 00:00:00 2001
+From: Jeongjun Park <aha310510@gmail.com>
+Date: Wed, 14 May 2025 22:08:55 +0900
+Subject: jbd2: fix data-race and null-ptr-deref in jbd2_journal_dirty_metadata()
+
+From: Jeongjun Park <aha310510@gmail.com>
+
+commit af98b0157adf6504fade79b3e6cb260c4ff68e37 upstream.
+
+Since handle->h_transaction may be a NULL pointer, so we should change it
+to call is_handle_aborted(handle) first before dereferencing it.
+
+And the following data-race was reported in my fuzzer:
+
+==================================================================
+BUG: KCSAN: data-race in jbd2_journal_dirty_metadata / jbd2_journal_dirty_metadata
+
+write to 0xffff888011024104 of 4 bytes by task 10881 on cpu 1:
+ jbd2_journal_dirty_metadata+0x2a5/0x770 fs/jbd2/transaction.c:1556
+ __ext4_handle_dirty_metadata+0xe7/0x4b0 fs/ext4/ext4_jbd2.c:358
+ ext4_do_update_inode fs/ext4/inode.c:5220 [inline]
+ ext4_mark_iloc_dirty+0x32c/0xd50 fs/ext4/inode.c:5869
+ __ext4_mark_inode_dirty+0xe1/0x450 fs/ext4/inode.c:6074
+ ext4_dirty_inode+0x98/0xc0 fs/ext4/inode.c:6103
+....
+
+read to 0xffff888011024104 of 4 bytes by task 10880 on cpu 0:
+ jbd2_journal_dirty_metadata+0xf2/0x770 fs/jbd2/transaction.c:1512
+ __ext4_handle_dirty_metadata+0xe7/0x4b0 fs/ext4/ext4_jbd2.c:358
+ ext4_do_update_inode fs/ext4/inode.c:5220 [inline]
+ ext4_mark_iloc_dirty+0x32c/0xd50 fs/ext4/inode.c:5869
+ __ext4_mark_inode_dirty+0xe1/0x450 fs/ext4/inode.c:6074
+ ext4_dirty_inode+0x98/0xc0 fs/ext4/inode.c:6103
+....
+
+value changed: 0x00000000 -> 0x00000001
+==================================================================
+
+This issue is caused by missing data-race annotation for jh->b_modified.
+Therefore, the missing annotation needs to be added.
+
+Reported-by: syzbot+de24c3fe3c4091051710@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=de24c3fe3c4091051710
+Fixes: 6e06ae88edae ("jbd2: speedup jbd2_journal_dirty_metadata()")
+Signed-off-by: Jeongjun Park <aha310510@gmail.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://patch.msgid.link/20250514130855.99010-1-aha310510@gmail.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/jbd2/transaction.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/jbd2/transaction.c
++++ b/fs/jbd2/transaction.c
+@@ -1419,7 +1419,6 @@ int jbd2_journal_dirty_metadata(handle_t
+               goto out;
+       }
+-      journal = transaction->t_journal;
+       jbd_lock_bh_state(bh);
+       if (is_handle_aborted(handle)) {
+@@ -1434,6 +1433,8 @@ int jbd2_journal_dirty_metadata(handle_t
+               goto out_unlock_bh;
+       }
++      journal = transaction->t_journal;
++
+       if (jh->b_modified == 0) {
+               /*
+                * This buffer's got modified and becoming part
diff --git a/queue-5.4/mm-huge_memory-fix-dereferencing-invalid-pmd-migration-entry.patch b/queue-5.4/mm-huge_memory-fix-dereferencing-invalid-pmd-migration-entry.patch
new file mode 100644 (file)
index 0000000..c70c13d
--- /dev/null
@@ -0,0 +1,76 @@
+From be6e843fc51a584672dfd9c4a6a24c8cb81d5fb7 Mon Sep 17 00:00:00 2001
+From: Gavin Guo <gavinguo@igalia.com>
+Date: Mon, 21 Apr 2025 19:35:36 +0800
+Subject: mm/huge_memory: fix dereferencing invalid pmd migration entry
+
+From: Gavin Guo <gavinguo@igalia.com>
+
+commit be6e843fc51a584672dfd9c4a6a24c8cb81d5fb7 upstream.
+
+When migrating a THP, concurrent access to the PMD migration entry during
+a deferred split scan can lead to an invalid address access, as
+illustrated below.  To prevent this invalid access, it is necessary to
+check the PMD migration entry and return early.  In this context, there is
+no need to use pmd_to_swp_entry and pfn_swap_entry_to_page to verify the
+equality of the target folio.  Since the PMD migration entry is locked, it
+cannot be served as the target.
+
+Mailing list discussion and explanation from Hugh Dickins: "An anon_vma
+lookup points to a location which may contain the folio of interest, but
+might instead contain another folio: and weeding out those other folios is
+precisely what the "folio != pmd_folio((*pmd)" check (and the "risk of
+replacing the wrong folio" comment a few lines above it) is for."
+
+BUG: unable to handle page fault for address: ffffea60001db008
+CPU: 0 UID: 0 PID: 2199114 Comm: tee Not tainted 6.14.0+ #4 NONE
+Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+RIP: 0010:split_huge_pmd_locked+0x3b5/0x2b60
+Call Trace:
+<TASK>
+try_to_migrate_one+0x28c/0x3730
+rmap_walk_anon+0x4f6/0x770
+unmap_folio+0x196/0x1f0
+split_huge_page_to_list_to_order+0x9f6/0x1560
+deferred_split_scan+0xac5/0x12a0
+shrinker_debugfs_scan_write+0x376/0x470
+full_proxy_write+0x15c/0x220
+vfs_write+0x2fc/0xcb0
+ksys_write+0x146/0x250
+do_syscall_64+0x6a/0x120
+entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+The bug is found by syzkaller on an internal kernel, then confirmed on
+upstream.
+
+Link: https://lkml.kernel.org/r/20250421113536.3682201-1-gavinguo@igalia.com
+Link: https://lore.kernel.org/all/20250414072737.1698513-1-gavinguo@igalia.com/
+Link: https://lore.kernel.org/all/20250418085802.2973519-1-gavinguo@igalia.com/
+Fixes: 84c3fc4e9c56 ("mm: thp: check pmd migration entry in common path")
+Signed-off-by: Gavin Guo <gavinguo@igalia.com>
+Acked-by: David Hildenbrand <david@redhat.com>
+Acked-by: Hugh Dickins <hughd@google.com>
+Acked-by: Zi Yan <ziy@nvidia.com>
+Reviewed-by: Gavin Shan <gshan@redhat.com>
+Cc: Florent Revest <revest@google.com>
+Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
+Cc: Miaohe Lin <linmiaohe@huawei.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+[gavin: backport the migration checking logic to __split_huge_pmd]
+Signed-off-by: Gavin Guo <gavinguo@igalia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/huge_memory.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/mm/huge_memory.c
++++ b/mm/huge_memory.c
+@@ -2334,7 +2334,7 @@ void __split_huge_pmd(struct vm_area_str
+       VM_BUG_ON(freeze && !page);
+       if (page) {
+               VM_WARN_ON_ONCE(!PageLocked(page));
+-              if (page != pmd_page(*pmd))
++              if (is_pmd_migration_entry(*pmd) || page != pmd_page(*pmd))
+                       goto out;
+       }
diff --git a/queue-5.4/rtc-improve-performance-of-rtc_time64_to_tm-.-add-tests.patch b/queue-5.4/rtc-improve-performance-of-rtc_time64_to_tm-.-add-tests.patch
new file mode 100644 (file)
index 0000000..aafe8d7
--- /dev/null
@@ -0,0 +1,288 @@
+From 1d1bb12a8b1805ddeef9793ebeb920179fb0fa38 Mon Sep 17 00:00:00 2001
+From: Cassio Neri <cassio.neri@gmail.com>
+Date: Thu, 24 Jun 2021 21:13:43 +0100
+Subject: rtc: Improve performance of rtc_time64_to_tm(). Add tests.
+
+From: Cassio Neri <cassio.neri@gmail.com>
+
+commit 1d1bb12a8b1805ddeef9793ebeb920179fb0fa38 upstream.
+
+The current implementation of rtc_time64_to_tm() contains unnecessary
+loops, branches and look-up tables. The new one uses an arithmetic-based
+algorithm appeared in [1] and is approximately 4.3 times faster (YMMV).
+
+The drawback is that the new code isn't intuitive and contains many 'magic
+numbers' (not unusual for this type of algorithm). However, [1] justifies
+all those numbers and, given this function's history, the code is unlikely
+to need much maintenance, if any at all.
+
+Add a KUnit test case that checks every day in a 160,000 years interval
+starting on 1970-01-01 against the expected result. Add a new config
+RTC_LIB_KUNIT_TEST symbol to give the option to run this test suite.
+
+[1] Neri, Schneider, "Euclidean Affine Functions and Applications to
+Calendar Algorithms". https://arxiv.org/abs/2102.06959
+
+Signed-off-by: Cassio Neri <cassio.neri@gmail.com>
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Link: https://lore.kernel.org/r/20210624201343.85441-1-cassio.neri@gmail.com
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/rtc/Kconfig    |   10 ++++
+ drivers/rtc/Makefile   |    1 
+ drivers/rtc/lib.c      |  107 ++++++++++++++++++++++++++++++++++++-------------
+ drivers/rtc/lib_test.c |   79 ++++++++++++++++++++++++++++++++++++
+ 4 files changed, 170 insertions(+), 27 deletions(-)
+ create mode 100644 drivers/rtc/lib_test.c
+
+--- a/drivers/rtc/Kconfig
++++ b/drivers/rtc/Kconfig
+@@ -10,6 +10,16 @@ config RTC_MC146818_LIB
+       bool
+       select RTC_LIB
++config RTC_LIB_KUNIT_TEST
++      tristate "KUnit test for RTC lib functions" if !KUNIT_ALL_TESTS
++      depends on KUNIT
++      default KUNIT_ALL_TESTS
++      select RTC_LIB
++      help
++        Enable this option to test RTC library functions.
++
++        If unsure, say N.
++
+ menuconfig RTC_CLASS
+       bool "Real Time Clock"
+       default n
+--- a/drivers/rtc/Makefile
++++ b/drivers/rtc/Makefile
+@@ -186,3 +186,4 @@ obj-$(CONFIG_RTC_DRV_WM8350)       += rtc-wm83
+ obj-$(CONFIG_RTC_DRV_X1205)   += rtc-x1205.o
+ obj-$(CONFIG_RTC_DRV_XGENE)   += rtc-xgene.o
+ obj-$(CONFIG_RTC_DRV_ZYNQMP)  += rtc-zynqmp.o
++obj-$(CONFIG_RTC_LIB_KUNIT_TEST)      += lib_test.o
+--- a/drivers/rtc/lib.c
++++ b/drivers/rtc/lib.c
+@@ -6,6 +6,8 @@
+  * Author: Alessandro Zummo <a.zummo@towertech.it>
+  *
+  * based on arch/arm/common/rtctime.c and other bits
++ *
++ * Author: Cassio Neri <cassio.neri@gmail.com> (rtc_time64_to_tm)
+  */
+ #include <linux/export.h>
+@@ -22,8 +24,6 @@ static const unsigned short rtc_ydays[2]
+       { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
+ };
+-#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
+-
+ /*
+  * The number of days in the month.
+  */
+@@ -42,42 +42,95 @@ int rtc_year_days(unsigned int day, unsi
+ }
+ EXPORT_SYMBOL(rtc_year_days);
+-/*
+- * rtc_time64_to_tm - Converts time64_t to rtc_time.
+- * Convert seconds since 01-01-1970 00:00:00 to Gregorian date.
++/**
++ * rtc_time64_to_tm - converts time64_t to rtc_time.
++ *
++ * @time:     The number of seconds since 01-01-1970 00:00:00.
++ *            (Must be positive.)
++ * @tm:               Pointer to the struct rtc_time.
+  */
+ void rtc_time64_to_tm(time64_t time, struct rtc_time *tm)
+ {
+-      unsigned int month, year, secs;
++      unsigned int secs;
+       int days;
++      u64 u64tmp;
++      u32 u32tmp, udays, century, day_of_century, year_of_century, year,
++              day_of_year, month, day;
++      bool is_Jan_or_Feb, is_leap_year;
++
+       /* time must be positive */
+       days = div_s64_rem(time, 86400, &secs);
+       /* day of the week, 1970-01-01 was a Thursday */
+       tm->tm_wday = (days + 4) % 7;
+-      year = 1970 + days / 365;
+-      days -= (year - 1970) * 365
+-              + LEAPS_THRU_END_OF(year - 1)
+-              - LEAPS_THRU_END_OF(1970 - 1);
+-      while (days < 0) {
+-              year -= 1;
+-              days += 365 + is_leap_year(year);
+-      }
+-      tm->tm_year = year - 1900;
+-      tm->tm_yday = days + 1;
+-
+-      for (month = 0; month < 11; month++) {
+-              int newdays;
+-
+-              newdays = days - rtc_month_days(month, year);
+-              if (newdays < 0)
+-                      break;
+-              days = newdays;
+-      }
+-      tm->tm_mon = month;
+-      tm->tm_mday = days + 1;
++      /*
++       * The following algorithm is, basically, Proposition 6.3 of Neri
++       * and Schneider [1]. In a few words: it works on the computational
++       * (fictitious) calendar where the year starts in March, month = 2
++       * (*), and finishes in February, month = 13. This calendar is
++       * mathematically convenient because the day of the year does not
++       * depend on whether the year is leap or not. For instance:
++       *
++       * March 1st            0-th day of the year;
++       * ...
++       * April 1st            31-st day of the year;
++       * ...
++       * January 1st          306-th day of the year; (Important!)
++       * ...
++       * February 28th        364-th day of the year;
++       * February 29th        365-th day of the year (if it exists).
++       *
++       * After having worked out the date in the computational calendar
++       * (using just arithmetics) it's easy to convert it to the
++       * corresponding date in the Gregorian calendar.
++       *
++       * [1] "Euclidean Affine Functions and Applications to Calendar
++       * Algorithms". https://arxiv.org/abs/2102.06959
++       *
++       * (*) The numbering of months follows rtc_time more closely and
++       * thus, is slightly different from [1].
++       */
++
++      udays           = ((u32) days) + 719468;
++
++      u32tmp          = 4 * udays + 3;
++      century         = u32tmp / 146097;
++      day_of_century  = u32tmp % 146097 / 4;
++
++      u32tmp          = 4 * day_of_century + 3;
++      u64tmp          = 2939745ULL * u32tmp;
++      year_of_century = upper_32_bits(u64tmp);
++      day_of_year     = lower_32_bits(u64tmp) / 2939745 / 4;
++
++      year            = 100 * century + year_of_century;
++      is_leap_year    = year_of_century != 0 ?
++              year_of_century % 4 == 0 : century % 4 == 0;
++
++      u32tmp          = 2141 * day_of_year + 132377;
++      month           = u32tmp >> 16;
++      day             = ((u16) u32tmp) / 2141;
++
++      /*
++       * Recall that January 01 is the 306-th day of the year in the
++       * computational (not Gregorian) calendar.
++       */
++      is_Jan_or_Feb   = day_of_year >= 306;
++
++      /* Converts to the Gregorian calendar. */
++      year            = year + is_Jan_or_Feb;
++      month           = is_Jan_or_Feb ? month - 12 : month;
++      day             = day + 1;
++
++      day_of_year     = is_Jan_or_Feb ?
++              day_of_year - 306 : day_of_year + 31 + 28 + is_leap_year;
++
++      /* Converts to rtc_time's format. */
++      tm->tm_year     = (int) (year - 1900);
++      tm->tm_mon      = (int) month;
++      tm->tm_mday     = (int) day;
++      tm->tm_yday     = (int) day_of_year + 1;
+       tm->tm_hour = secs / 3600;
+       secs -= tm->tm_hour * 3600;
+--- /dev/null
++++ b/drivers/rtc/lib_test.c
+@@ -0,0 +1,79 @@
++// SPDX-License-Identifier: LGPL-2.1+
++
++#include <kunit/test.h>
++#include <linux/rtc.h>
++
++/*
++ * Advance a date by one day.
++ */
++static void advance_date(int *year, int *month, int *mday, int *yday)
++{
++      if (*mday != rtc_month_days(*month - 1, *year)) {
++              ++*mday;
++              ++*yday;
++              return;
++      }
++
++      *mday = 1;
++      if (*month != 12) {
++              ++*month;
++              ++*yday;
++              return;
++      }
++
++      *month = 1;
++      *yday  = 1;
++      ++*year;
++}
++
++/*
++ * Checks every day in a 160000 years interval starting on 1970-01-01
++ * against the expected result.
++ */
++static void rtc_time64_to_tm_test_date_range(struct kunit *test)
++{
++      /*
++       * 160000 years = (160000 / 400) * 400 years
++       *              = (160000 / 400) * 146097 days
++       *              = (160000 / 400) * 146097 * 86400 seconds
++       */
++      time64_t total_secs = ((time64_t) 160000) / 400 * 146097 * 86400;
++
++      int year        = 1970;
++      int month       = 1;
++      int mday        = 1;
++      int yday        = 1;
++
++      struct rtc_time result;
++      time64_t secs;
++      s64 days;
++
++      for (secs = 0; secs <= total_secs; secs += 86400) {
++
++              rtc_time64_to_tm(secs, &result);
++
++              days = div_s64(secs, 86400);
++
++              #define FAIL_MSG "%d/%02d/%02d (%2d) : %ld", \
++                      year, month, mday, yday, days
++
++              KUNIT_ASSERT_EQ_MSG(test, year - 1900, result.tm_year, FAIL_MSG);
++              KUNIT_ASSERT_EQ_MSG(test, month - 1, result.tm_mon, FAIL_MSG);
++              KUNIT_ASSERT_EQ_MSG(test, mday, result.tm_mday, FAIL_MSG);
++              KUNIT_ASSERT_EQ_MSG(test, yday, result.tm_yday, FAIL_MSG);
++
++              advance_date(&year, &month, &mday, &yday);
++      }
++}
++
++static struct kunit_case rtc_lib_test_cases[] = {
++      KUNIT_CASE(rtc_time64_to_tm_test_date_range),
++      {}
++};
++
++static struct kunit_suite rtc_lib_test_suite = {
++      .name = "rtc_lib_test_cases",
++      .test_cases = rtc_lib_test_cases,
++};
++
++kunit_test_suite(rtc_lib_test_suite);
diff --git a/queue-5.4/rtc-make-rtc_time64_to_tm-support-dates-before-1970.patch b/queue-5.4/rtc-make-rtc_time64_to_tm-support-dates-before-1970.patch
new file mode 100644 (file)
index 0000000..b4a42d1
--- /dev/null
@@ -0,0 +1,85 @@
+From 7df4cfef8b351fec3156160bedfc7d6d29de4cce Mon Sep 17 00:00:00 2001
+From: Alexandre Mergnat <amergnat@baylibre.com>
+Date: Mon, 28 Apr 2025 12:06:47 +0200
+Subject: rtc: Make rtc_time64_to_tm() support dates before 1970
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alexandre Mergnat <amergnat@baylibre.com>
+
+commit 7df4cfef8b351fec3156160bedfc7d6d29de4cce upstream.
+
+Conversion of dates before 1970 is still relevant today because these
+dates are reused on some hardwares to store dates bigger than the
+maximal date that is representable in the device's native format.
+This prominently and very soon affects the hardware covered by the
+rtc-mt6397 driver that can only natively store dates in the interval
+1900-01-01 up to 2027-12-31. So to store the date 2028-01-01 00:00:00
+to such a device, rtc_time64_to_tm() must do the right thing for
+time=-2208988800.
+
+Signed-off-by: Alexandre Mergnat <amergnat@baylibre.com>
+Reviewed-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+Link: https://lore.kernel.org/r/20250428-enable-rtc-v4-1-2b2f7e3f9349@baylibre.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/rtc/lib.c |   24 +++++++++++++++++++-----
+ 1 file changed, 19 insertions(+), 5 deletions(-)
+
+--- a/drivers/rtc/lib.c
++++ b/drivers/rtc/lib.c
+@@ -46,24 +46,38 @@ EXPORT_SYMBOL(rtc_year_days);
+  * rtc_time64_to_tm - converts time64_t to rtc_time.
+  *
+  * @time:     The number of seconds since 01-01-1970 00:00:00.
+- *            (Must be positive.)
++ *            Works for values since at least 1900
+  * @tm:               Pointer to the struct rtc_time.
+  */
+ void rtc_time64_to_tm(time64_t time, struct rtc_time *tm)
+ {
+-      unsigned int secs;
+-      int days;
++      int days, secs;
+       u64 u64tmp;
+       u32 u32tmp, udays, century, day_of_century, year_of_century, year,
+               day_of_year, month, day;
+       bool is_Jan_or_Feb, is_leap_year;
+-      /* time must be positive */
++      /*
++       * Get days and seconds while preserving the sign to
++       * handle negative time values (dates before 1970-01-01)
++       */
+       days = div_s64_rem(time, 86400, &secs);
++      /*
++       * We need 0 <= secs < 86400 which isn't given for negative
++       * values of time. Fixup accordingly.
++       */
++      if (secs < 0) {
++              days -= 1;
++              secs += 86400;
++      }
++
+       /* day of the week, 1970-01-01 was a Thursday */
+       tm->tm_wday = (days + 4) % 7;
++      /* Ensure tm_wday is always positive */
++      if (tm->tm_wday < 0)
++              tm->tm_wday += 7;
+       /*
+        * The following algorithm is, basically, Proposition 6.3 of Neri
+@@ -93,7 +107,7 @@ void rtc_time64_to_tm(time64_t time, str
+        * thus, is slightly different from [1].
+        */
+-      udays           = ((u32) days) + 719468;
++      udays           = days + 719468;
+       u32tmp          = 4 * udays + 3;
+       century         = u32tmp / 146097;
index a818571711fc2327b150f9912315bccfbc0637b6..2f00bc360e7cc65bbb2dcc7ef276049c1b38076c 100644 (file)
@@ -215,3 +215,7 @@ arm-dts-am335x-bone-common-increase-mdio-reset-deassert-delay-to-50ms.patch
 posix-cpu-timers-fix-race-between-handle_posix_cpu_timers-and-posix_cpu_timer_del.patch
 xprtrdma-fix-pointer-derefs-in-error-cases-of-rpcrdma_ep_create.patch
 net-fix-checksum-update-for-ila-adj-transport.patch
+rtc-improve-performance-of-rtc_time64_to_tm-.-add-tests.patch
+rtc-make-rtc_time64_to_tm-support-dates-before-1970.patch
+mm-huge_memory-fix-dereferencing-invalid-pmd-migration-entry.patch
+jbd2-fix-data-race-and-null-ptr-deref-in-jbd2_journal_dirty_metadata.patch