Skip to contentSkip to conversation

kho: misc fixes

PATCH Applied Pratyush Yadav 3 participants 8 messages Nov 3, 2025 – Nov 5, 2025

Subsystems (4)
lore
Share & tools
lore

Pratyush Yadav

author maintainer
#0 lore raw

cover kho: misc fixes

This series has a couple of misc fixes for KHO I discovered during code review and testing.

The series is based on top of [0] which has another fix for the function touched by patch 1. I spotted these two after sending the patch. If that one needs a reroll, I can combine the three into a series.

[0] https://lore.kernel.org/linux-mm/[email protected]/

Pratyush Yadav (2):
kho: fix unpreservation of higher-order vmalloc preservations
kho: warn and exit when unpreserved page wasn't preserved

 kernel/kexec_handover.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

base-commit: dcb6fa37fd7bc9c3d2b066329b0d27dedf8becaa
prerequisite-patch-id: fce7dcea45c85bac06a559d06f038e9c0cb38b17

Signature · 1 line
2.47.3
author maintainer
#1 lore raw

PATCH 1/2 kho: fix unpreservation of higher-order vmalloc preservations

kho_vmalloc_unpreserve_chunk() calls __kho_unpreserve() with end_pfn as pfn + 1. This happens to work for 0-order pages, but leaks higher order pages.

For example, say order 2 pages back the allocation. During preservation, they get preserved in the order 2 bitmaps, but kho_vmalloc_unpreserve_chunk() would try to unpreserve them from the order 0 bitmaps, which should not have these bits set anyway, leaving the order 2 bitmaps untouched. This results in the pages being carried over to the next kernel. Nothing will free those pages in the next boot, leaking them.

Fix this by taking the order into account when calculating the end PFN for __kho_unpreserve().

Fixes a667300bd53f2 ("kho: add support for preserving vmalloc allocations")

---

Notes:
When Pasha's patch [0] to add kho_unpreserve_pages() is merged, maybe it would be a better idea to use kho_unpreserve_pages() here? But that is something for later I suppose.

[0] https://lore.kernel.org/linux-mm/[email protected]/

 kernel/kexec_handover.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
kernel/kexec_handover.c +4 -3
index cc5aaa738bc50..c2bcbb10918ce 100644
@@ -862,7 +862,8 @@ static struct kho_vmalloc_chunk *new_vmalloc_chunk(struct kho_vmalloc_chunk *cur
 	return NULL;
 }
 
-static void kho_vmalloc_unpreserve_chunk(struct kho_vmalloc_chunk *chunk)
+static void kho_vmalloc_unpreserve_chunk(struct kho_vmalloc_chunk *chunk,
+					 unsigned short order)
 {
 	struct kho_mem_track *track = &kho_out.ser.track;
 	unsigned long pfn = PHYS_PFN(virt_to_phys(chunk));
@@ -871,7 +872,7 @@ static void kho_vmalloc_unpreserve_chunk(struct kho_vmalloc_chunk *chunk)
 
 	for (int i = 0; i < ARRAY_SIZE(chunk->phys) && chunk->phys[i]; i++) {
 		pfn = PHYS_PFN(chunk->phys[i]);
-		__kho_unpreserve(track, pfn, pfn + 1);
+		__kho_unpreserve(track, pfn, pfn + (1 << order));
 	}
 }
 
@@ -882,7 +883,7 @@ static void kho_vmalloc_free_chunks(struct kho_vmalloc *kho_vmalloc)
 	while (chunk) {
 		struct kho_vmalloc_chunk *tmp = chunk;
 
-		kho_vmalloc_unpreserve_chunk(chunk);
+		kho_vmalloc_unpreserve_chunk(chunk, kho_vmalloc->order);
 
 		chunk = KHOSER_LOAD_PTR(chunk->hdr.next);
 		free_page((unsigned long)tmp);
Signature · 1 line
2.47.3
maintainer Reviewed-by on v1 1/2
#2 lore raw

Re: [PATCH 1/2] kho: fix unpreservation of higher-order vmalloc preservations

Quoted 12 lines · Pratyush Yadav

kho_vmalloc_unpreserve_chunk() calls __kho_unpreserve() with end_pfn as pfn + 1. This happens to work for 0-order pages, but leaks higher order pages.

For example, say order 2 pages back the allocation. During preservation, they get preserved in the order 2 bitmaps, but kho_vmalloc_unpreserve_chunk() would try to unpreserve them from the order 0 bitmaps, which should not have these bits set anyway, leaving the order 2 bitmaps untouched. This results in the pages being carried over to the next kernel. Nothing will free those pages in the next boot, leaking them.

Quoted 5 lines

Fix this by taking the order into account when calculating the end PFN for __kho_unpreserve().

Fixes a667300bd53f2 ("kho: add support for preserving vmalloc allocations")
Quoted 47 lines

---

Notes:
When Pasha's patch [0] to add kho_unpreserve_pages() is merged, maybe it would be a better idea to use kho_unpreserve_pages() here? But that is something for later I suppose.

[0] https://lore.kernel.org/linux-mm/[email protected]/

 kernel/kexec_handover.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
kernel/kexec_handover.c +4 -3
index cc5aaa738bc50..c2bcbb10918ce 100644
@@ -862,7 +862,8 @@ static struct kho_vmalloc_chunk *new_vmalloc_chunk(struct kho_vmalloc_chunk *cur
 	return NULL;
 }
 
-static void kho_vmalloc_unpreserve_chunk(struct kho_vmalloc_chunk *chunk)
+static void kho_vmalloc_unpreserve_chunk(struct kho_vmalloc_chunk *chunk,
+					 unsigned short order)
 {
 	struct kho_mem_track *track = &kho_out.ser.track;
 	unsigned long pfn = PHYS_PFN(virt_to_phys(chunk));
@@ -871,7 +872,7 @@ static void kho_vmalloc_unpreserve_chunk(struct kho_vmalloc_chunk *chunk)
 
 	for (int i = 0; i < ARRAY_SIZE(chunk->phys) && chunk->phys[i]; i++) {
 		pfn = PHYS_PFN(chunk->phys[i]);
-		__kho_unpreserve(track, pfn, pfn + 1);
+		__kho_unpreserve(track, pfn, pfn + (1 << order));
 	}
 }
 
@@ -882,7 +883,7 @@ static void kho_vmalloc_free_chunks(struct kho_vmalloc *kho_vmalloc)
 	while (chunk) {
 		struct kho_vmalloc_chunk *tmp = chunk;
 
-		kho_vmalloc_unpreserve_chunk(chunk);
+		kho_vmalloc_unpreserve_chunk(chunk, kho_vmalloc->order);
 
 		chunk = KHOSER_LOAD_PTR(chunk->hdr.next);
 		free_page((unsigned long)tmp);
Signature · 1 line
2.47.3
Signature · 2 lines
Sincerely yours,
Mike.
author maintainer
#3 lore raw

PATCH 2/2 kho: warn and exit when unpreserved page wasn't preserved

In reply to Pratyush Yadav

Calling __kho_unpreserve() on a pair of (pfn, end_pfn) that wasn't preserved is a bug. Currently, if that is done, the physxa or bits can be NULL. This results in a soft lockup since a NULL physxa or bits results in redoing the loop without ever making any progress.

Return when physxa or bits are not found, but WARN first to loudly indicate invalid behaviour.

Fixes fc33e4b44b271 ("kexec: enable KHO support for memory preservation")
---
 kernel/kexec_handover.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
kernel/kexec_handover.c +4 -4
index c2bcbb10918ce..e5fd833726226 100644
@@ -167,12 +167,12 @@ static void __kho_unpreserve(struct kho_mem_track *track, unsigned long pfn,
 		const unsigned long pfn_high = pfn >> order;
 
 		physxa = xa_load(&track->orders, order);
-		if (!physxa)
-			continue;
+		if (WARN_ON_ONCE(!physxa))
+			return;
 
 		bits = xa_load(&physxa->phys_bits, pfn_high / PRESERVE_BITS);
-		if (!bits)
-			continue;
+		if (WARN_ON_ONCE(!bits))
+			return;
 
 		clear_bit(pfn_high % PRESERVE_BITS, bits->preserve);
 
Signature · 1 line
2.47.3
maintainer Reviewed-by on v1 2/2
#4 lore raw

Re: [PATCH 2/2] kho: warn and exit when unpreserved page wasn't preserved

Quoted 10 lines · Pratyush Yadav

Calling __kho_unpreserve() on a pair of (pfn, end_pfn) that wasn't preserved is a bug. Currently, if that is done, the physxa or bits can be NULL. This results in a soft lockup since a NULL physxa or bits results in redoing the loop without ever making any progress.

Return when physxa or bits are not found, but WARN first to loudly indicate invalid behaviour.

Fixes fc33e4b44b271 ("kexec: enable KHO support for memory preservation")
Quoted 28 lines
---
 kernel/kexec_handover.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
kernel/kexec_handover.c +4 -4
index c2bcbb10918ce..e5fd833726226 100644
@@ -167,12 +167,12 @@ static void __kho_unpreserve(struct kho_mem_track *track, unsigned long pfn,
 		const unsigned long pfn_high = pfn >> order;
 
 		physxa = xa_load(&track->orders, order);
-		if (!physxa)
-			continue;
+		if (WARN_ON_ONCE(!physxa))
+			return;
 
 		bits = xa_load(&physxa->phys_bits, pfn_high / PRESERVE_BITS);
-		if (!bits)
-			continue;
+		if (WARN_ON_ONCE(!bits))
+			return;
 
 		clear_bit(pfn_high % PRESERVE_BITS, bits->preserve);
 
Signature · 1 line
2.47.3
Signature · 2 lines
Sincerely yours,
Mike.
maintainer
#5 lore raw
In reply to Pratyush Yadav
Quoted 7 lines · On Mon, 3 Nov 2025 19:02:30 +0100 Pratyush Yadav <[email protected]> wrote:

This series has a couple of misc fixes for KHO I discovered during code review and testing.

The series is based on top of [0] which has another fix for the function touched by patch 1. I spotted these two after sending the patch. If that one needs a reroll, I can combine the three into a series.

Things appear to be misordered here.

[1/2] "kho: fix unpreservation of higher-order vmalloc preservations"

	fixes a667300bd53f2, so it's wanted in 6.18-rcX

[2/2] "kho: warn and exit when unpreserved page wasn't preserved"

	fixes fc33e4b44b271, so it's wanted in 6.16+

So can we please have [2/2] as a standalone fix against latest -linus, with a cc:stable?

And then [1/2] as a standalone fix against latest -linus without a cc:stable.

Once I have those merged up we can then take a look at what to do about the 6.19 material which is presently queued in mm-unstable.

Thanks.

maintainer
#6 lore raw
Quoted 15 lines · On Mon, 3 Nov 2025 16:20:20 -0800 Andrew Morton <[email protected]>…
Quoted 7 lines · On Mon, 3 Nov 2025 19:02:30 +0100 Pratyush Yadav <[email protected]> wrote:

This series has a couple of misc fixes for KHO I discovered during code review and testing.

The series is based on top of [0] which has another fix for the function touched by patch 1. I spotted these two after sending the patch. If that one needs a reroll, I can combine the three into a series.

Things appear to be misordered here.

[1/2] "kho: fix unpreservation of higher-order vmalloc preservations"

	fixes a667300bd53f2, so it's wanted in 6.18-rcX
Quoted 9 lines

[2/2] "kho: warn and exit when unpreserved page wasn't preserved"

	fixes fc33e4b44b271, so it's wanted in 6.16+

So can we please have [2/2] as a standalone fix against latest -linus, with a cc:stable?

And then [1/2] as a standalone fix against latest -linus without a cc:stable.

OK, I think I figured it out.

In mm-hotfixes-unstable I have

kho-fix-out-of-bounds-access-of-vmalloc-chunk.patch kho-fix-unpreservation-of-higher-order-vmalloc-preservations.patch kho-warn-and-exit-when-unpreserved-page-wasnt-preserved.patch

The first two are applicable to 6.18-rcX and the third is applicable to 6.18-rcX, with a cc:stable for backporting.

author maintainer
#7 lore raw
Quoted 29 lines · Andrew Morton
Quoted 15 lines · On Mon, 3 Nov 2025 16:20:20 -0800 Andrew Morton <[email protected]>…
Quoted 7 lines · On Mon, 3 Nov 2025 19:02:30 +0100 Pratyush Yadav <[email protected]> wrote:

This series has a couple of misc fixes for KHO I discovered during code review and testing.

The series is based on top of [0] which has another fix for the function touched by patch 1. I spotted these two after sending the patch. If that one needs a reroll, I can combine the three into a series.

Things appear to be misordered here.

[1/2] "kho: fix unpreservation of higher-order vmalloc preservations"

	fixes a667300bd53f2, so it's wanted in 6.18-rcX
Quoted 9 lines

[2/2] "kho: warn and exit when unpreserved page wasn't preserved"

	fixes fc33e4b44b271, so it's wanted in 6.16+

So can we please have [2/2] as a standalone fix against latest -linus, with a cc:stable?

And then [1/2] as a standalone fix against latest -linus without a cc:stable.

OK, I think I figured it out.

Quoted 8 lines

In mm-hotfixes-unstable I have

kho-fix-out-of-bounds-access-of-vmalloc-chunk.patch kho-fix-unpreservation-of-higher-order-vmalloc-preservations.patch kho-warn-and-exit-when-unpreserved-page-wasnt-preserved.patch

The first two are applicable to 6.18-rcX and the third is applicable to 6.18-rcX, with a cc:stable for backporting.

Right. Sorry for the confusion. I see that on mm-hotfixes-unstable you already updated the third patch with Cc: stable. Thanks.

Signature · 2 lines
Regards,
Pratyush Yadav