This is a backport of the following upstream commit:
commit 4404368 Author: WANG Chao chaowang@redhat.com Date: Wed Dec 18 22:34:43 2013 +0900
[PATCH] memset() in cyclic bitmap initialization introduce segment fault.
We are using memset() to improve performance when creating 1st and 2nd bitmap. After doing round up the pfn_start and round down pfn_end, it's possible that pfn_start_roundup is greater than pfn_end_round. A segment fault could happen in that case because memset is taking roughly the value of (pfn_end_round << 3 - pfn_start_roundup << 3 ), which is negative, as its third argument.
So we can skip the memset if start is greater than end. It's safe because we will set bit for the round up part and also round down part.
Actually this happens on my EFI virtual machine:
cat /proc/iomem: 00000000-00000fff : reserved 00001000-0009ffff : System RAM 000a0000-000bffff : PCI Bus 0000:00 000f0000-000fffff : System ROM 00100000-3d162017 : System RAM 01000000-015cab9b : Kernel code 015cab9c-019beb3f : Kernel data 01b4f000-01da9fff : Kernel bss 30000000-37ffffff : Crash kernel 3d162018-3d171e57 : System RAM 3d171e58-3d172017 : System RAM 3d172018-3d17ae57 : System RAM 3d17ae58-3dc10fff : System RAM 3dc11000-3dc18fff : reserved 3dc19000-3dc41fff : System RAM 3dc42000-3ddcefff : reserved 3ddcf000-3f7fefff : System RAM 3f7ff000-3f856fff : reserved [..]
gdb ./makedumpfile core (gdb) bt full [..] #1 0x000000000042775d in create_1st_bitmap_cyclic () at makedumpfile.c:4543 i = 0x5 pfn = 0x3d190 phys_start = 0x3d18ee58 phys_end = 0x3d18f018 pfn_start = 0x3d18e pfn_end = 0x3d18f pfn_start_roundup = 0x3d190 pfn_end_round = 0x3d188 pfn_start_byte = 0x7a32 pfn_end_byte = 0x7a31 [..] (gdb) list makedumpfile.c:4543 4538 return FALSE; 4539 4540 pfn_start_byte = (pfn_start_roundup - info->cyclic_start_pfn) >> 3; 4541 pfn_end_byte = (pfn_end_round - info->cyclic_start_pfn) >> 3; 4542 4543 memset(info->partial_bitmap2 + pfn_start_byte, 4544 0xff, 4545 pfn_end_byte - pfn_start_byte); 4546 4547 for (pfn = pfn_end_round; pfn < pfn_end; ++pfn)
Signed-off-by: WANG Chao chaowang@redhat.com
This patch fixes segment fault issues on the systems with very small memory map range (less than 8 pages).
Signed-off-by: WANG Chao chaowang@redhat.com ---
The regression is introduced in makedumpfile-1.5.5. So this patch is for rawhide/f21 only.
...t-in-cyclic-bitmap-initialization-introdu.patch | 112 +++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 kexec-tools-2.0.4-makedumpfile-memset-in-cyclic-bitmap-initialization-introdu.patch
diff --git a/kexec-tools-2.0.4-makedumpfile-memset-in-cyclic-bitmap-initialization-introdu.patch b/kexec-tools-2.0.4-makedumpfile-memset-in-cyclic-bitmap-initialization-introdu.patch new file mode 100644 index 0000000..60939b8 --- /dev/null +++ b/kexec-tools-2.0.4-makedumpfile-memset-in-cyclic-bitmap-initialization-introdu.patch @@ -0,0 +1,112 @@ +From 4404368a0860e3b6c845eb41782e97a9bf7593b8 Mon Sep 17 00:00:00 2001 +From: WANG Chao chaowang@redhat.com +Date: Wed, 18 Dec 2013 22:34:43 +0900 +Subject: [PATCH] [PATCH] memset() in cyclic bitmap initialization introduce + segment fault. + +We are using memset() to improve performance when creating 1st and 2nd +bitmap. After doing round up the pfn_start and round down pfn_end, it's +possible that pfn_start_roundup is greater than pfn_end_round. A segment +fault could happen in that case because memset is taking roughly the +value of (pfn_end_round << 3 - pfn_start_roundup << 3 ), which is +negative, as its third argument. + +So we can skip the memset if start is greater than end. It's safe +because we will set bit for the round up part and also round down part. + +Actually this happens on my EFI virtual machine: + +cat /proc/iomem: +00000000-00000fff : reserved +00001000-0009ffff : System RAM +000a0000-000bffff : PCI Bus 0000:00 +000f0000-000fffff : System ROM +00100000-3d162017 : System RAM + 01000000-015cab9b : Kernel code + 015cab9c-019beb3f : Kernel data + 01b4f000-01da9fff : Kernel bss + 30000000-37ffffff : Crash kernel +3d162018-3d171e57 : System RAM +3d171e58-3d172017 : System RAM +3d172018-3d17ae57 : System RAM +3d17ae58-3dc10fff : System RAM +3dc11000-3dc18fff : reserved +3dc19000-3dc41fff : System RAM +3dc42000-3ddcefff : reserved +3ddcf000-3f7fefff : System RAM +3f7ff000-3f856fff : reserved +[..] + +gdb ./makedumpfile core +(gdb) bt full +[..] + #1 0x000000000042775d in create_1st_bitmap_cyclic () at makedumpfile.c:4543 + i = 0x5 + pfn = 0x3d190 + phys_start = 0x3d18ee58 + phys_end = 0x3d18f018 + pfn_start = 0x3d18e + pfn_end = 0x3d18f + pfn_start_roundup = 0x3d190 + pfn_end_round = 0x3d188 + pfn_start_byte = 0x7a32 + pfn_end_byte = 0x7a31 +[..] +(gdb) list makedumpfile.c:4543 +4538 return FALSE; +4539 +4540 pfn_start_byte = (pfn_start_roundup - info->cyclic_start_pfn) >> +3; +4541 pfn_end_byte = (pfn_end_round - info->cyclic_start_pfn) >> 3; +4542 +4543 memset(info->partial_bitmap2 + pfn_start_byte, +4544 0xff, +4545 pfn_end_byte - pfn_start_byte); +4546 +4547 for (pfn = pfn_end_round; pfn < pfn_end; ++pfn) + +Signed-off-by: WANG Chao chaowang@redhat.com +--- + makedumpfile.c | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +diff --git a/makedumpfile.c b/makedumpfile.c +index 23251a1..ef08d91 100644 +--- a/makedumpfile.c ++++ b/makedumpfile.c +@@ -4435,11 +4435,13 @@ create_1st_bitmap_cyclic() + pfn_start_byte = (pfn_start_roundup - info->cyclic_start_pfn) >> 3; + pfn_end_byte = (pfn_end_round - info->cyclic_start_pfn) >> 3; + +- memset(info->partial_bitmap1 + pfn_start_byte, +- 0xff, +- pfn_end_byte - pfn_start_byte); ++ if (pfn_start_byte < pfn_end_byte) { ++ memset(info->partial_bitmap1 + pfn_start_byte, ++ 0xff, ++ pfn_end_byte - pfn_start_byte); + +- pfn_bitmap1 += (pfn_end_byte - pfn_start_byte) * BITPERBYTE; ++ pfn_bitmap1 += (pfn_end_byte - pfn_start_byte) * BITPERBYTE; ++ } + + for (pfn = pfn_end_round; pfn < pfn_end; pfn++) { + if (set_bit_on_1st_bitmap(pfn)) +@@ -4540,9 +4542,11 @@ initialize_2nd_bitmap_cyclic(void) + pfn_start_byte = (pfn_start_roundup - info->cyclic_start_pfn) >> 3; + pfn_end_byte = (pfn_end_round - info->cyclic_start_pfn) >> 3; + +- memset(info->partial_bitmap2 + pfn_start_byte, +- 0xff, +- pfn_end_byte - pfn_start_byte); ++ if (pfn_start_byte < pfn_end_byte) { ++ memset(info->partial_bitmap2 + pfn_start_byte, ++ 0xff, ++ pfn_end_byte - pfn_start_byte); ++ } + + for (pfn = pfn_end_round; pfn < pfn_end; ++pfn) + if (!set_bit_on_2nd_bitmap_for_kernel(pfn)) +-- +1.8.5.3 +
On Tue, Jan 28, 2014 at 01:26:12PM +0800, WANG Chao wrote:
This is a backport of the following upstream commit:
commit 4404368 Author: WANG Chao chaowang@redhat.com Date: Wed Dec 18 22:34:43 2013 +0900
Acked-by: Vivek Goyal vgoyal@redhat.com
Vivek
[PATCH] memset() in cyclic bitmap initialization introduce segment fault. We are using memset() to improve performance when creating 1st and 2nd bitmap. After doing round up the pfn_start and round down pfn_end, it's possible that pfn_start_roundup is greater than pfn_end_round. A segment fault could happen in that case because memset is taking roughly the value of (pfn_end_round << 3 - pfn_start_roundup << 3 ), which is negative, as its third argument. So we can skip the memset if start is greater than end. It's safe because we will set bit for the round up part and also round down part. Actually this happens on my EFI virtual machine: cat /proc/iomem: 00000000-00000fff : reserved 00001000-0009ffff : System RAM 000a0000-000bffff : PCI Bus 0000:00 000f0000-000fffff : System ROM 00100000-3d162017 : System RAM 01000000-015cab9b : Kernel code 015cab9c-019beb3f : Kernel data 01b4f000-01da9fff : Kernel bss 30000000-37ffffff : Crash kernel 3d162018-3d171e57 : System RAM 3d171e58-3d172017 : System RAM 3d172018-3d17ae57 : System RAM 3d17ae58-3dc10fff : System RAM 3dc11000-3dc18fff : reserved 3dc19000-3dc41fff : System RAM 3dc42000-3ddcefff : reserved 3ddcf000-3f7fefff : System RAM 3f7ff000-3f856fff : reserved [..] gdb ./makedumpfile core (gdb) bt full [..] #1 0x000000000042775d in create_1st_bitmap_cyclic () at makedumpfile.c:4543 i = 0x5 pfn = 0x3d190 phys_start = 0x3d18ee58 phys_end = 0x3d18f018 pfn_start = 0x3d18e pfn_end = 0x3d18f pfn_start_roundup = 0x3d190 pfn_end_round = 0x3d188 pfn_start_byte = 0x7a32 pfn_end_byte = 0x7a31 [..] (gdb) list makedumpfile.c:4543 4538 return FALSE; 4539 4540 pfn_start_byte = (pfn_start_roundup - info->cyclic_start_pfn) >> 3; 4541 pfn_end_byte = (pfn_end_round - info->cyclic_start_pfn) >> 3; 4542 4543 memset(info->partial_bitmap2 + pfn_start_byte, 4544 0xff, 4545 pfn_end_byte - pfn_start_byte); 4546 4547 for (pfn = pfn_end_round; pfn < pfn_end; ++pfn) Signed-off-by: WANG Chao <chaowang@redhat.com>
This patch fixes segment fault issues on the systems with very small memory map range (less than 8 pages).
Signed-off-by: WANG Chao chaowang@redhat.com
The regression is introduced in makedumpfile-1.5.5. So this patch is for rawhide/f21 only.
...t-in-cyclic-bitmap-initialization-introdu.patch | 112 +++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 kexec-tools-2.0.4-makedumpfile-memset-in-cyclic-bitmap-initialization-introdu.patch
diff --git a/kexec-tools-2.0.4-makedumpfile-memset-in-cyclic-bitmap-initialization-introdu.patch b/kexec-tools-2.0.4-makedumpfile-memset-in-cyclic-bitmap-initialization-introdu.patch new file mode 100644 index 0000000..60939b8 --- /dev/null +++ b/kexec-tools-2.0.4-makedumpfile-memset-in-cyclic-bitmap-initialization-introdu.patch @@ -0,0 +1,112 @@ +From 4404368a0860e3b6c845eb41782e97a9bf7593b8 Mon Sep 17 00:00:00 2001 +From: WANG Chao chaowang@redhat.com +Date: Wed, 18 Dec 2013 22:34:43 +0900 +Subject: [PATCH] [PATCH] memset() in cyclic bitmap initialization introduce
- segment fault.
+We are using memset() to improve performance when creating 1st and 2nd +bitmap. After doing round up the pfn_start and round down pfn_end, it's +possible that pfn_start_roundup is greater than pfn_end_round. A segment +fault could happen in that case because memset is taking roughly the +value of (pfn_end_round << 3 - pfn_start_roundup << 3 ), which is +negative, as its third argument.
+So we can skip the memset if start is greater than end. It's safe +because we will set bit for the round up part and also round down part.
+Actually this happens on my EFI virtual machine:
+cat /proc/iomem: +00000000-00000fff : reserved +00001000-0009ffff : System RAM +000a0000-000bffff : PCI Bus 0000:00 +000f0000-000fffff : System ROM +00100000-3d162017 : System RAM
- 01000000-015cab9b : Kernel code
- 015cab9c-019beb3f : Kernel data
- 01b4f000-01da9fff : Kernel bss
- 30000000-37ffffff : Crash kernel
+3d162018-3d171e57 : System RAM +3d171e58-3d172017 : System RAM +3d172018-3d17ae57 : System RAM +3d17ae58-3dc10fff : System RAM +3dc11000-3dc18fff : reserved +3dc19000-3dc41fff : System RAM +3dc42000-3ddcefff : reserved +3ddcf000-3f7fefff : System RAM +3f7ff000-3f856fff : reserved +[..]
+gdb ./makedumpfile core +(gdb) bt full +[..]
- #1 0x000000000042775d in create_1st_bitmap_cyclic () at makedumpfile.c:4543
i = 0x5
pfn = 0x3d190
phys_start = 0x3d18ee58
phys_end = 0x3d18f018
pfn_start = 0x3d18e
pfn_end = 0x3d18f
pfn_start_roundup = 0x3d190
pfn_end_round = 0x3d188
pfn_start_byte = 0x7a32
pfn_end_byte = 0x7a31
+[..] +(gdb) list makedumpfile.c:4543 +4538 return FALSE; +4539 +4540 pfn_start_byte = (pfn_start_roundup - info->cyclic_start_pfn) >> +3; +4541 pfn_end_byte = (pfn_end_round - info->cyclic_start_pfn) >> 3; +4542 +4543 memset(info->partial_bitmap2 + pfn_start_byte, +4544 0xff, +4545 pfn_end_byte - pfn_start_byte); +4546 +4547 for (pfn = pfn_end_round; pfn < pfn_end; ++pfn)
+Signed-off-by: WANG Chao chaowang@redhat.com +---
- makedumpfile.c | 18 +++++++++++-------
- 1 file changed, 11 insertions(+), 7 deletions(-)
+diff --git a/makedumpfile.c b/makedumpfile.c +index 23251a1..ef08d91 100644 +--- a/makedumpfile.c ++++ b/makedumpfile.c +@@ -4435,11 +4435,13 @@ create_1st_bitmap_cyclic()
pfn_start_byte = (pfn_start_roundup - info->cyclic_start_pfn) >> 3;
pfn_end_byte = (pfn_end_round - info->cyclic_start_pfn) >> 3;
+- memset(info->partial_bitmap1 + pfn_start_byte, +- 0xff, +- pfn_end_byte - pfn_start_byte); ++ if (pfn_start_byte < pfn_end_byte) { ++ memset(info->partial_bitmap1 + pfn_start_byte, ++ 0xff, ++ pfn_end_byte - pfn_start_byte);
+- pfn_bitmap1 += (pfn_end_byte - pfn_start_byte) * BITPERBYTE; ++ pfn_bitmap1 += (pfn_end_byte - pfn_start_byte) * BITPERBYTE; ++ }
for (pfn = pfn_end_round; pfn < pfn_end; pfn++) {
if (set_bit_on_1st_bitmap(pfn))
+@@ -4540,9 +4542,11 @@ initialize_2nd_bitmap_cyclic(void)
pfn_start_byte = (pfn_start_roundup - info->cyclic_start_pfn) >> 3;
pfn_end_byte = (pfn_end_round - info->cyclic_start_pfn) >> 3;
+- memset(info->partial_bitmap2 + pfn_start_byte, +- 0xff, +- pfn_end_byte - pfn_start_byte); ++ if (pfn_start_byte < pfn_end_byte) { ++ memset(info->partial_bitmap2 + pfn_start_byte, ++ 0xff, ++ pfn_end_byte - pfn_start_byte); ++ }
for (pfn = pfn_end_round; pfn < pfn_end; ++pfn)
if (!set_bit_on_2nd_bitmap_for_kernel(pfn))
+-- +1.8.5.3
-- 1.8.5.3
kexec mailing list kexec@lists.fedoraproject.org https://lists.fedoraproject.org/mailman/listinfo/kexec