From: Dave Hansen <dave@linux.vnet.ibm.com>
To: linux-kernel@vger.kernel.org
Cc: linux-mm@kvack.org, Gleb Natapov <gleb@redhat.com>,
Avi Kivity <avi@redhat.com>,
Dave Hansen <dave@linux.vnet.ibm.com>
Subject: [RFCv2][PATCH 3/3] make DEBUG_VIRTUAL work earlier in boot
Date: Fri, 07 Dec 2012 16:30:25 -0500 [thread overview]
Message-ID: <20121207213025.53E4BD1B@kernel.stglabs.ibm.com> (raw)
In-Reply-To: <20121207213023.AA3AFF11@kernel.stglabs.ibm.com>
The KVM code has some repeated bugs in it around use of __pa() on
per-cpu data. Those data are not in an area on which __pa() is
valid. However, they are also called early enough in boot that
__vmalloc_start_set is not set, and thus the CONFIG_DEBUG_VIRTUAL
debugging does not catch them.
This adds a check to also verify them against max_low_pfn, which
we can use earler in boot than is_vmalloc_addr(). However, if
we are super-early in boot, max_low_pfn=0 and this will trip
on every call, so also make sure that max_low_pfn is set.
With this patch applied, CONFIG_DEBUG_VIRTUAL will actually
catch the bug I was chasing.
I'd love to find a generic way so that any __pa() call on percpu
areas could do a BUG_ON(), but there don't appear to be any nice
and easy ways to check if an address is a percpu one. Anybody
have ideas on a way to do this?
---
linux-2.6.git-dave/arch/x86/mm/numa.c | 2 +-
linux-2.6.git-dave/arch/x86/mm/pat.c | 4 ++--
linux-2.6.git-dave/arch/x86/mm/physaddr.c | 10 ++++++++--
3 files changed, 11 insertions(+), 5 deletions(-)
diff -puN arch/x86/mm/physaddr.c~make-DEBUG_VIRTUAL-work-earlier-in-boot arch/x86/mm/physaddr.c
--- linux-2.6.git/arch/x86/mm/physaddr.c~make-DEBUG_VIRTUAL-work-earlier-in-boot 2012-11-30 16:18:44.522847232 -0500
+++ linux-2.6.git-dave/arch/x86/mm/physaddr.c 2012-11-30 16:18:44.530847298 -0500
@@ -1,3 +1,4 @@
+#include <linux/bootmem.h>
#include <linux/mmdebug.h>
#include <linux/module.h>
#include <linux/mm.h>
@@ -41,16 +42,21 @@ bool __virt_addr_valid(unsigned long x)
return pfn_valid(x >> PAGE_SHIFT);
}
EXPORT_SYMBOL(__virt_addr_valid);
-
#else
#ifdef CONFIG_DEBUG_VIRTUAL
unsigned long __phys_addr(unsigned long x)
{
+ unsigned long phys_addr = x - PAGE_OFFSET;
/* VMALLOC_* aren't constants */
VIRTUAL_BUG_ON(x < PAGE_OFFSET);
VIRTUAL_BUG_ON(__vmalloc_start_set && is_vmalloc_addr((void *) x));
- return x - PAGE_OFFSET;
+ /* max_low_pfn is set early, but not _that_ early */
+ if (max_low_pfn) {
+ VIRTUAL_BUG_ON((phys_addr >> PAGE_SHIFT) > max_low_pfn);
+ BUG_ON(slow_virt_to_phys((void *)x) != phys_addr);
+ }
+ return phys_addr;
}
EXPORT_SYMBOL(__phys_addr);
#endif
diff -puN arch/x86/kernel/kvmclock.c~make-DEBUG_VIRTUAL-work-earlier-in-boot arch/x86/kernel/kvmclock.c
diff -L sr -puN /dev/null /dev/null
diff -puN arch/x86/include/asm/page_32.h~make-DEBUG_VIRTUAL-work-earlier-in-boot arch/x86/include/asm/page_32.h
diff -puN arch/x86/mm/numa.c~make-DEBUG_VIRTUAL-work-earlier-in-boot arch/x86/mm/numa.c
--- linux-2.6.git/arch/x86/mm/numa.c~make-DEBUG_VIRTUAL-work-earlier-in-boot 2012-11-30 16:18:44.526847265 -0500
+++ linux-2.6.git-dave/arch/x86/mm/numa.c 2012-11-30 16:18:44.534847331 -0500
@@ -219,7 +219,7 @@ static void __init setup_node_data(int n
*/
nd = alloc_remap(nid, nd_size);
if (nd) {
- nd_pa = __pa(nd);
+ nd_pa = __phys_addr_nodebug(nd);
remapped = true;
} else {
nd_pa = memblock_alloc_nid(nd_size, SMP_CACHE_BYTES, nid);
diff -puN arch/x86/mm/pat.c~make-DEBUG_VIRTUAL-work-earlier-in-boot arch/x86/mm/pat.c
--- linux-2.6.git/arch/x86/mm/pat.c~make-DEBUG_VIRTUAL-work-earlier-in-boot 2012-11-30 16:19:34.371258739 -0500
+++ linux-2.6.git-dave/arch/x86/mm/pat.c 2012-11-30 16:22:38.528778740 -0500
@@ -560,10 +560,10 @@ int kernel_map_sync_memtype(u64 base, un
{
unsigned long id_sz;
- if (base >= __pa(high_memory))
+ if (base > __pa(high_memory-1))
return 0;
- id_sz = (__pa(high_memory) < base + size) ?
+ id_sz = (__pa(high_memory-1) <= base + size) ?
__pa(high_memory) - base :
size;
_
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
WARNING: multiple messages have this Message-ID (diff)
From: Dave Hansen <dave@linux.vnet.ibm.com>
To: linux-kernel@vger.kernel.org
Cc: linux-mm@kvack.org, Gleb Natapov <gleb@redhat.com>,
Avi Kivity <avi@redhat.com>,
Dave Hansen <dave@linux.vnet.ibm.com>
Subject: [RFCv2][PATCH 3/3] make DEBUG_VIRTUAL work earlier in boot
Date: Fri, 07 Dec 2012 16:30:25 -0500 [thread overview]
Message-ID: <20121207213025.53E4BD1B@kernel.stglabs.ibm.com> (raw)
In-Reply-To: <20121207213023.AA3AFF11@kernel.stglabs.ibm.com>
The KVM code has some repeated bugs in it around use of __pa() on
per-cpu data. Those data are not in an area on which __pa() is
valid. However, they are also called early enough in boot that
__vmalloc_start_set is not set, and thus the CONFIG_DEBUG_VIRTUAL
debugging does not catch them.
This adds a check to also verify them against max_low_pfn, which
we can use earler in boot than is_vmalloc_addr(). However, if
we are super-early in boot, max_low_pfn=0 and this will trip
on every call, so also make sure that max_low_pfn is set.
With this patch applied, CONFIG_DEBUG_VIRTUAL will actually
catch the bug I was chasing.
I'd love to find a generic way so that any __pa() call on percpu
areas could do a BUG_ON(), but there don't appear to be any nice
and easy ways to check if an address is a percpu one. Anybody
have ideas on a way to do this?
---
linux-2.6.git-dave/arch/x86/mm/numa.c | 2 +-
linux-2.6.git-dave/arch/x86/mm/pat.c | 4 ++--
linux-2.6.git-dave/arch/x86/mm/physaddr.c | 10 ++++++++--
3 files changed, 11 insertions(+), 5 deletions(-)
diff -puN arch/x86/mm/physaddr.c~make-DEBUG_VIRTUAL-work-earlier-in-boot arch/x86/mm/physaddr.c
--- linux-2.6.git/arch/x86/mm/physaddr.c~make-DEBUG_VIRTUAL-work-earlier-in-boot 2012-11-30 16:18:44.522847232 -0500
+++ linux-2.6.git-dave/arch/x86/mm/physaddr.c 2012-11-30 16:18:44.530847298 -0500
@@ -1,3 +1,4 @@
+#include <linux/bootmem.h>
#include <linux/mmdebug.h>
#include <linux/module.h>
#include <linux/mm.h>
@@ -41,16 +42,21 @@ bool __virt_addr_valid(unsigned long x)
return pfn_valid(x >> PAGE_SHIFT);
}
EXPORT_SYMBOL(__virt_addr_valid);
-
#else
#ifdef CONFIG_DEBUG_VIRTUAL
unsigned long __phys_addr(unsigned long x)
{
+ unsigned long phys_addr = x - PAGE_OFFSET;
/* VMALLOC_* aren't constants */
VIRTUAL_BUG_ON(x < PAGE_OFFSET);
VIRTUAL_BUG_ON(__vmalloc_start_set && is_vmalloc_addr((void *) x));
- return x - PAGE_OFFSET;
+ /* max_low_pfn is set early, but not _that_ early */
+ if (max_low_pfn) {
+ VIRTUAL_BUG_ON((phys_addr >> PAGE_SHIFT) > max_low_pfn);
+ BUG_ON(slow_virt_to_phys((void *)x) != phys_addr);
+ }
+ return phys_addr;
}
EXPORT_SYMBOL(__phys_addr);
#endif
diff -puN arch/x86/kernel/kvmclock.c~make-DEBUG_VIRTUAL-work-earlier-in-boot arch/x86/kernel/kvmclock.c
diff -L sr -puN /dev/null /dev/null
diff -puN arch/x86/include/asm/page_32.h~make-DEBUG_VIRTUAL-work-earlier-in-boot arch/x86/include/asm/page_32.h
diff -puN arch/x86/mm/numa.c~make-DEBUG_VIRTUAL-work-earlier-in-boot arch/x86/mm/numa.c
--- linux-2.6.git/arch/x86/mm/numa.c~make-DEBUG_VIRTUAL-work-earlier-in-boot 2012-11-30 16:18:44.526847265 -0500
+++ linux-2.6.git-dave/arch/x86/mm/numa.c 2012-11-30 16:18:44.534847331 -0500
@@ -219,7 +219,7 @@ static void __init setup_node_data(int n
*/
nd = alloc_remap(nid, nd_size);
if (nd) {
- nd_pa = __pa(nd);
+ nd_pa = __phys_addr_nodebug(nd);
remapped = true;
} else {
nd_pa = memblock_alloc_nid(nd_size, SMP_CACHE_BYTES, nid);
diff -puN arch/x86/mm/pat.c~make-DEBUG_VIRTUAL-work-earlier-in-boot arch/x86/mm/pat.c
--- linux-2.6.git/arch/x86/mm/pat.c~make-DEBUG_VIRTUAL-work-earlier-in-boot 2012-11-30 16:19:34.371258739 -0500
+++ linux-2.6.git-dave/arch/x86/mm/pat.c 2012-11-30 16:22:38.528778740 -0500
@@ -560,10 +560,10 @@ int kernel_map_sync_memtype(u64 base, un
{
unsigned long id_sz;
- if (base >= __pa(high_memory))
+ if (base > __pa(high_memory-1))
return 0;
- id_sz = (__pa(high_memory) < base + size) ?
+ id_sz = (__pa(high_memory-1) <= base + size) ?
__pa(high_memory) - base :
size;
_
next prev parent reply other threads:[~2012-12-07 21:30 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-12-07 21:30 [RFCv2][PATCH 1/3] create slow_virt_to_phys() Dave Hansen
2012-12-07 21:30 ` Dave Hansen
2012-12-07 21:30 ` [RFCv2][PATCH 2/3] fix kvm's use of __pa() on percpu areas Dave Hansen
2012-12-07 21:30 ` Dave Hansen
2012-12-07 21:30 ` Dave Hansen [this message]
2012-12-07 21:30 ` [RFCv2][PATCH 3/3] make DEBUG_VIRTUAL work earlier in boot Dave Hansen
2012-12-09 14:06 ` [RFCv2][PATCH 1/3] create slow_virt_to_phys() Gleb Natapov
2012-12-09 14:06 ` Gleb Natapov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20121207213025.53E4BD1B@kernel.stglabs.ibm.com \
--to=dave@linux.vnet.ibm.com \
--cc=avi@redhat.com \
--cc=gleb@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.