diff for duplicates of <20111215194341.GG32002@google.com> diff --git a/a/1.txt b/N1/1.txt index 8b13789..c8ae1ca 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -1 +1,74 @@ +>From 9f57bd4d6dc69a4e3bf43044fa00fcd24dd363e3 Mon Sep 17 00:00:00 2001 +From: Eugene Surovegin <ebs@ebshome.net> +Date: Thu, 15 Dec 2011 11:25:59 -0800 +per_cpu_ptr_to_phys() incorrectly rounds up its result for non-kmalloc +case to the page boundary, which is bogus for any non-page-aligned +address. + +This affects the only in-tree user of this function - sysfs handler +for per-cpu 'crash_notes' physical address. The trouble is that the +crash_notes per-cpu variable is not page-aligned: + +crash_notes = 0xc08e8ed4 +PER-CPU OFFSET VALUES: + CPU 0: 3711f000 + CPU 1: 37129000 + CPU 2: 37133000 + CPU 3: 3713d000 + +So, the per-cpu addresses are: + crash_notes on CPU 0: f7a07ed4 => phys 36b57ed4 + crash_notes on CPU 1: f7a11ed4 => phys 36b4ded4 + crash_notes on CPU 2: f7a1bed4 => phys 36b43ed4 + crash_notes on CPU 3: f7a25ed4 => phys 36b39ed4 + +However, /sys/devices/system/cpu/cpu*/crash_notes says: + /sys/devices/system/cpu/cpu0/crash_notes: 36b57000 + /sys/devices/system/cpu/cpu1/crash_notes: 36b4d000 + /sys/devices/system/cpu/cpu2/crash_notes: 36b43000 + /sys/devices/system/cpu/cpu3/crash_notes: 36b39000 + +As you can see, all values are rounded down to a page +boundary. Consequently, this is where kexec sets up the NOTE segments, +and thus where the secondary kernel is looking for them. However, when +the first kernel crashes, it saves the notes to the unaligned +addresses, where they are not found. + +Fix it by adding offset_in_page() to the translated page address. + +-tj: Combined Eugene's and Petr's commit messages. + +Signed-off-by: Eugene Surovegin <ebs@ebshome.net> +Signed-off-by: Tejun Heo <tj@kernel.org> +Reported-by: Petr Tesarik <ptesarik@suse.cz> +Cc: stable@kernel.org +--- +I combined Petr's explanation into patch description and committed it +into percpu/for-3.2-fixes. Will push it to Linus in a few days. + +Thank you. + + mm/percpu.c | 6 ++++-- + 1 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/mm/percpu.c b/mm/percpu.c +index 3bb810a..716eb4a 100644 +--- a/mm/percpu.c ++++ b/mm/percpu.c +@@ -1023,9 +1023,11 @@ phys_addr_t per_cpu_ptr_to_phys(void *addr) + if (!is_vmalloc_addr(addr)) + return __pa(addr); + else +- return page_to_phys(vmalloc_to_page(addr)); ++ return page_to_phys(vmalloc_to_page(addr)) + ++ offset_in_page(addr); + } else +- return page_to_phys(pcpu_addr_to_page(addr)); ++ return page_to_phys(pcpu_addr_to_page(addr)) + ++ offset_in_page(addr); + } + + /** +-- +1.7.3.1 diff --git a/a/content_digest b/N1/content_digest index 1f25df8..26e4560 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -10,5 +10,79 @@ " vgoyal@redhat.com\0" "\00:1\0" "b\0" + ">From 9f57bd4d6dc69a4e3bf43044fa00fcd24dd363e3 Mon Sep 17 00:00:00 2001\n" + "From: Eugene Surovegin <ebs@ebshome.net>\n" + "Date: Thu, 15 Dec 2011 11:25:59 -0800\n" + "\n" + "per_cpu_ptr_to_phys() incorrectly rounds up its result for non-kmalloc\n" + "case to the page boundary, which is bogus for any non-page-aligned\n" + "address.\n" + "\n" + "This affects the only in-tree user of this function - sysfs handler\n" + "for per-cpu 'crash_notes' physical address. The trouble is that the\n" + "crash_notes per-cpu variable is not page-aligned:\n" + "\n" + "crash_notes = 0xc08e8ed4\n" + "PER-CPU OFFSET VALUES:\n" + " CPU 0: 3711f000\n" + " CPU 1: 37129000\n" + " CPU 2: 37133000\n" + " CPU 3: 3713d000\n" + "\n" + "So, the per-cpu addresses are:\n" + " crash_notes on CPU 0: f7a07ed4 => phys 36b57ed4\n" + " crash_notes on CPU 1: f7a11ed4 => phys 36b4ded4\n" + " crash_notes on CPU 2: f7a1bed4 => phys 36b43ed4\n" + " crash_notes on CPU 3: f7a25ed4 => phys 36b39ed4\n" + "\n" + "However, /sys/devices/system/cpu/cpu*/crash_notes says:\n" + " /sys/devices/system/cpu/cpu0/crash_notes: 36b57000\n" + " /sys/devices/system/cpu/cpu1/crash_notes: 36b4d000\n" + " /sys/devices/system/cpu/cpu2/crash_notes: 36b43000\n" + " /sys/devices/system/cpu/cpu3/crash_notes: 36b39000\n" + "\n" + "As you can see, all values are rounded down to a page\n" + "boundary. Consequently, this is where kexec sets up the NOTE segments,\n" + "and thus where the secondary kernel is looking for them. However, when\n" + "the first kernel crashes, it saves the notes to the unaligned\n" + "addresses, where they are not found.\n" + "\n" + "Fix it by adding offset_in_page() to the translated page address.\n" + "\n" + "-tj: Combined Eugene's and Petr's commit messages.\n" + "\n" + "Signed-off-by: Eugene Surovegin <ebs@ebshome.net>\n" + "Signed-off-by: Tejun Heo <tj@kernel.org>\n" + "Reported-by: Petr Tesarik <ptesarik@suse.cz>\n" + "Cc: stable@kernel.org\n" + "---\n" + "I combined Petr's explanation into patch description and committed it\n" + "into percpu/for-3.2-fixes. Will push it to Linus in a few days.\n" + "\n" + "Thank you.\n" + "\n" + " mm/percpu.c | 6 ++++--\n" + " 1 files changed, 4 insertions(+), 2 deletions(-)\n" + "\n" + "diff --git a/mm/percpu.c b/mm/percpu.c\n" + "index 3bb810a..716eb4a 100644\n" + "--- a/mm/percpu.c\n" + "+++ b/mm/percpu.c\n" + "@@ -1023,9 +1023,11 @@ phys_addr_t per_cpu_ptr_to_phys(void *addr)\n" + " \t\tif (!is_vmalloc_addr(addr))\n" + " \t\t\treturn __pa(addr);\n" + " \t\telse\n" + "-\t\t\treturn page_to_phys(vmalloc_to_page(addr));\n" + "+\t\t\treturn page_to_phys(vmalloc_to_page(addr)) +\n" + "+\t\t\t offset_in_page(addr);\n" + " \t} else\n" + "-\t\treturn page_to_phys(pcpu_addr_to_page(addr));\n" + "+\t\treturn page_to_phys(pcpu_addr_to_page(addr)) +\n" + "+\t\t offset_in_page(addr);\n" + " }\n" + " \n" + " /**\n" + "-- \n" + 1.7.3.1 -c1a1b6d06155cce1cb29a230a688b571241bfb5ceaec6740c5710fcf90755f79 +64ebb5fb137c86e292d58deac69f0becc4b8777b2f9515657621d9338b4e162a
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.