aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/xen/p2m.c
diff options
context:
space:
mode:
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2010-12-22 08:57:30 -0500
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2011-03-14 11:17:11 -0400
commit2222e71bd6eff7b2ad026d4ee663b6327c5a49f5 (patch)
tree4c6f6c29e0d879ea0222a7294fa8c03b6af8ce24 /arch/x86/xen/p2m.c
parent68df0da7f42be6ae017fe9f48ac414c43a7b9d32 (diff)
xen/debugfs: Add 'p2m' file for printing out the P2M layout.
We walk over the whole P2M tree and construct a simplified view of which PFN regions belong to what level and what type they are. Only enabled if CONFIG_XEN_DEBUG_FS is set. [v2: UNKN->UNKNOWN, use uninitialized_var] [v3: Rebased on top of mmu->p2m code split] [v4: Fixed the else if] Reviewed-by: Ian Campbell <Ian.Campbell@eu.citrix.com> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'arch/x86/xen/p2m.c')
-rw-r--r--arch/x86/xen/p2m.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c
index 4631cf99e71..65f21f4b396 100644
--- a/arch/x86/xen/p2m.c
+++ b/arch/x86/xen/p2m.c
@@ -153,6 +153,7 @@
153#include <linux/list.h> 153#include <linux/list.h>
154#include <linux/hash.h> 154#include <linux/hash.h>
155#include <linux/sched.h> 155#include <linux/sched.h>
156#include <linux/seq_file.h>
156 157
157#include <asm/cache.h> 158#include <asm/cache.h>
158#include <asm/setup.h> 159#include <asm/setup.h>
@@ -758,3 +759,80 @@ unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn)
758 return ret; 759 return ret;
759} 760}
760EXPORT_SYMBOL_GPL(m2p_find_override_pfn); 761EXPORT_SYMBOL_GPL(m2p_find_override_pfn);
762
763#ifdef CONFIG_XEN_DEBUG_FS
764
765int p2m_dump_show(struct seq_file *m, void *v)
766{
767 static const char * const level_name[] = { "top", "middle",
768 "entry", "abnormal" };
769 static const char * const type_name[] = { "identity", "missing",
770 "pfn", "abnormal"};
771#define TYPE_IDENTITY 0
772#define TYPE_MISSING 1
773#define TYPE_PFN 2
774#define TYPE_UNKNOWN 3
775 unsigned long pfn, prev_pfn_type = 0, prev_pfn_level = 0;
776 unsigned int uninitialized_var(prev_level);
777 unsigned int uninitialized_var(prev_type);
778
779 if (!p2m_top)
780 return 0;
781
782 for (pfn = 0; pfn < MAX_DOMAIN_PAGES; pfn++) {
783 unsigned topidx = p2m_top_index(pfn);
784 unsigned mididx = p2m_mid_index(pfn);
785 unsigned idx = p2m_index(pfn);
786 unsigned lvl, type;
787
788 lvl = 4;
789 type = TYPE_UNKNOWN;
790 if (p2m_top[topidx] == p2m_mid_missing) {
791 lvl = 0; type = TYPE_MISSING;
792 } else if (p2m_top[topidx] == NULL) {
793 lvl = 0; type = TYPE_UNKNOWN;
794 } else if (p2m_top[topidx][mididx] == NULL) {
795 lvl = 1; type = TYPE_UNKNOWN;
796 } else if (p2m_top[topidx][mididx] == p2m_identity) {
797 lvl = 1; type = TYPE_IDENTITY;
798 } else if (p2m_top[topidx][mididx] == p2m_missing) {
799 lvl = 1; type = TYPE_MISSING;
800 } else if (p2m_top[topidx][mididx][idx] == 0) {
801 lvl = 2; type = TYPE_UNKNOWN;
802 } else if (p2m_top[topidx][mididx][idx] == IDENTITY_FRAME(pfn)) {
803 lvl = 2; type = TYPE_IDENTITY;
804 } else if (p2m_top[topidx][mididx][idx] == INVALID_P2M_ENTRY) {
805 lvl = 2; type = TYPE_MISSING;
806 } else if (p2m_top[topidx][mididx][idx] == pfn) {
807 lvl = 2; type = TYPE_PFN;
808 } else if (p2m_top[topidx][mididx][idx] != pfn) {
809 lvl = 2; type = TYPE_PFN;
810 }
811 if (pfn == 0) {
812 prev_level = lvl;
813 prev_type = type;
814 }
815 if (pfn == MAX_DOMAIN_PAGES-1) {
816 lvl = 3;
817 type = TYPE_UNKNOWN;
818 }
819 if (prev_type != type) {
820 seq_printf(m, " [0x%lx->0x%lx] %s\n",
821 prev_pfn_type, pfn, type_name[prev_type]);
822 prev_pfn_type = pfn;
823 prev_type = type;
824 }
825 if (prev_level != lvl) {
826 seq_printf(m, " [0x%lx->0x%lx] level %s\n",
827 prev_pfn_level, pfn, level_name[prev_level]);
828 prev_pfn_level = pfn;
829 prev_level = lvl;
830 }
831 }
832 return 0;
833#undef TYPE_IDENTITY
834#undef TYPE_MISSING
835#undef TYPE_PFN
836#undef TYPE_UNKNOWN
837}
838#endif