diff options
author | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2010-12-23 16:25:29 -0500 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2011-03-14 11:17:12 -0400 |
commit | fc25151d9ac7d809239fe68de0a1490b504bb94a (patch) | |
tree | cd9ef4fdd796c49affe1c3d432a0fd9581c58d64 /arch/x86 | |
parent | 2222e71bd6eff7b2ad026d4ee663b6327c5a49f5 (diff) |
xen/debug: WARN_ON when identity PFN has no _PAGE_IOMAP flag set.
Only enabled if XEN_DEBUG is enabled. We print a warning
when:
pfn_to_mfn(pfn) == pfn, but no VM_IO (_PAGE_IOMAP) flag set
(and pfn is an identity mapped pfn)
pfn_to_mfn(pfn) != pfn, and VM_IO flag is set.
(ditto, pfn is an identity mapped pfn)
[v2: Make it dependent on CONFIG_XEN_DEBUG instead of ..DEBUG_FS]
[v3: Fix compiler warning]
Reviewed-by: Ian Campbell <ian.campbell@citrix.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/xen/Kconfig | 8 | ||||
-rw-r--r-- | arch/x86/xen/mmu.c | 38 |
2 files changed, 46 insertions, 0 deletions
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig index 5b54892e4bc3..e4343fe488ed 100644 --- a/arch/x86/xen/Kconfig +++ b/arch/x86/xen/Kconfig | |||
@@ -48,3 +48,11 @@ config XEN_DEBUG_FS | |||
48 | help | 48 | help |
49 | Enable statistics output and various tuning options in debugfs. | 49 | Enable statistics output and various tuning options in debugfs. |
50 | Enabling this option may incur a significant performance overhead. | 50 | Enabling this option may incur a significant performance overhead. |
51 | |||
52 | config XEN_DEBUG | ||
53 | bool "Enable Xen debug checks" | ||
54 | depends on XEN | ||
55 | default n | ||
56 | help | ||
57 | Enable various WARN_ON checks in the Xen MMU code. | ||
58 | Enabling this option WILL incur a significant performance overhead. | ||
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index b13b6ca9052a..0c376a2d9f98 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -547,6 +547,41 @@ pte_t xen_make_pte(pteval_t pte) | |||
547 | } | 547 | } |
548 | PV_CALLEE_SAVE_REGS_THUNK(xen_make_pte); | 548 | PV_CALLEE_SAVE_REGS_THUNK(xen_make_pte); |
549 | 549 | ||
550 | #ifdef CONFIG_XEN_DEBUG | ||
551 | pte_t xen_make_pte_debug(pteval_t pte) | ||
552 | { | ||
553 | phys_addr_t addr = (pte & PTE_PFN_MASK); | ||
554 | phys_addr_t other_addr; | ||
555 | bool io_page = false; | ||
556 | pte_t _pte; | ||
557 | |||
558 | if (pte & _PAGE_IOMAP) | ||
559 | io_page = true; | ||
560 | |||
561 | _pte = xen_make_pte(pte); | ||
562 | |||
563 | if (!addr) | ||
564 | return _pte; | ||
565 | |||
566 | if (io_page && | ||
567 | (xen_initial_domain() || addr >= ISA_END_ADDRESS)) { | ||
568 | other_addr = pfn_to_mfn(addr >> PAGE_SHIFT) << PAGE_SHIFT; | ||
569 | WARN(addr != other_addr, | ||
570 | "0x%lx is using VM_IO, but it is 0x%lx!\n", | ||
571 | (unsigned long)addr, (unsigned long)other_addr); | ||
572 | } else { | ||
573 | pteval_t iomap_set = (_pte.pte & PTE_FLAGS_MASK) & _PAGE_IOMAP; | ||
574 | other_addr = (_pte.pte & PTE_PFN_MASK); | ||
575 | WARN((addr == other_addr) && (!io_page) && (!iomap_set), | ||
576 | "0x%lx is missing VM_IO (and wasn't fixed)!\n", | ||
577 | (unsigned long)addr); | ||
578 | } | ||
579 | |||
580 | return _pte; | ||
581 | } | ||
582 | PV_CALLEE_SAVE_REGS_THUNK(xen_make_pte_debug); | ||
583 | #endif | ||
584 | |||
550 | pgd_t xen_make_pgd(pgdval_t pgd) | 585 | pgd_t xen_make_pgd(pgdval_t pgd) |
551 | { | 586 | { |
552 | pgd = pte_pfn_to_mfn(pgd); | 587 | pgd = pte_pfn_to_mfn(pgd); |
@@ -1957,6 +1992,9 @@ __init void xen_ident_map_ISA(void) | |||
1957 | 1992 | ||
1958 | static __init void xen_post_allocator_init(void) | 1993 | static __init void xen_post_allocator_init(void) |
1959 | { | 1994 | { |
1995 | #ifdef CONFIG_XEN_DEBUG | ||
1996 | pv_mmu_ops.make_pte = PV_CALLEE_SAVE(xen_make_pte_debug); | ||
1997 | #endif | ||
1960 | pv_mmu_ops.set_pte = xen_set_pte; | 1998 | pv_mmu_ops.set_pte = xen_set_pte; |
1961 | pv_mmu_ops.set_pmd = xen_set_pmd; | 1999 | pv_mmu_ops.set_pmd = xen_set_pmd; |
1962 | pv_mmu_ops.set_pud = xen_set_pud; | 2000 | pv_mmu_ops.set_pud = xen_set_pud; |