diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index c997b53..77752fe 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -123,6 +123,7 @@
 #include <asm/fixmap.h>
 #include <asm/io_apic.h>
 #include <asm/pci.h>
+#include <xen/console.h>
 
 /* Mapping of the fixmap space needed early. */
 l1_pgentry_t __section(".bss.page_aligned") l1_fixmap[L1_PAGETABLE_ENTRIES];
@@ -5635,6 +5636,20 @@ int map_pages_to_xen(
     l1_pgentry_t *pl1e, ol1e;
     unsigned int  i;
 
+    if ( XEN_VIRT_START >= virt &&
+         XEN_VIRT_START <= (virt + (nr_mfns * PAGE_SIZE)) )
+    {
+        console_start_sync();
+
+        printk("*** %s(%p, %p, %p, %#x)\n",
+               __func__, _p(virt), _p(mfn), _p(nr_mfns), flags);
+        printk("*** Called from %p %pS\n",
+               __builtin_return_address(0),
+               __builtin_return_address(0));
+
+        console_end_sync();
+    }
+
 #define flush_flags(oldf) do {                 \
     unsigned int o_ = (oldf);                  \
     if ( (o_) & _PAGE_GLOBAL )                 \
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 564a107..8381138 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -4124,6 +4124,154 @@ void asm_domain_crash_synchronous(unsigned long addr)
     __domain_crash_synchronous();
 }
 
+static const char *pte_flags_decode(unsigned int flags)
+{
+    static char buf[24];
+
+    snprintf(buf, sizeof buf, "%s%s%s%s%s%s",
+             flags & _PAGE_NX_BIT  ? "NX"   : "X",
+             flags & _PAGE_GLOBAL  ? " Gl"  : "",
+             flags & _PAGE_PSE     ? " +"   : "",
+             flags & _PAGE_USER    ? " U"   : " S",
+             flags & _PAGE_RW      ? " RW"  : " RO",
+             flags & _PAGE_PRESENT ? " P"   : ""
+        );
+    return buf;
+}
+
+void dump_xen_mappings(bool_t dump_l1)
+{
+    unsigned long cr3 = read_cr3();
+
+    unsigned int i4 = l4_table_offset(XEN_VIRT_START);
+    l4_pgentry_t *l4 = &idle_pg_table[i4];
+    unsigned int l4ef = l4e_get_flags(*l4);
+
+    unsigned int i3 = l3_table_offset(XEN_VIRT_START);
+    l3_pgentry_t *l3 = l4e_to_l3e(*l4);
+    unsigned int l3ef = l3e_get_flags(l3[i3]);
+
+    unsigned int i2;
+    l2_pgentry_t *l2 = l3e_to_l2e(l3[i3]);
+
+    printk("*** Dumping Xen text/data/bss mappings from %p\n",
+           _p(XEN_VIRT_START));
+
+    printk("cr3 %p, idle_pg_table %p, pa %p\n",
+           _p(cr3), idle_pg_table, _p(__pa(idle_pg_table)));
+
+    printk("l2_xenmap: %p, pa %p\n", l2_xenmap, _p(__pa(l2_xenmap)));
+
+    printk(" L4[%03u] = %"PRIpte" %s\n",
+           i4, l4e_get_intpte(*l4), pte_flags_decode(l4ef));
+
+    printk("  L3[%03u] = %"PRIpte" %s\n",
+           i3, l3e_get_intpte(l3[i3]), pte_flags_decode(l3ef));
+
+    if ( l3e_get_paddr(l3[i3]) != __pa(l2_xenmap) )
+        printk("** Unexpected - l3e not pointing at l2_xenmap\n");
+
+    for ( i2 = 0; i2 < L2_PAGETABLE_ENTRIES; ++i2 )
+    {
+        unsigned int l2ef = l2e_get_flags(l2[i2]), i1;
+        l1_pgentry_t *l1;
+
+        if ( !(l2ef & _PAGE_PRESENT) )
+            continue;
+
+        printk("   L2[%03u] = %"PRIpte" %s\n",
+               i2, l2e_get_intpte(l2[i2]), pte_flags_decode(l2ef));
+
+        if ( l2ef & _PAGE_PSE )
+            continue;
+
+        if ( !dump_l1 )
+        {
+            printk("    L1 abbr\n");
+            continue;
+        }
+
+        l1 = l2e_to_l1e(l2[i2]);
+
+        for ( i1 = 0; i1 < L1_PAGETABLE_ENTRIES; ++i1 )
+        {
+            unsigned int l1ef = l1e_get_flags(l1[i1]);
+
+            if ( !(l1ef & _PAGE_PRESENT) )
+                continue;
+
+            printk("    L1[%03u] = %"PRIpte" %s\n",
+                   i1, l1e_get_intpte(l1[i1]), pte_flags_decode(l1ef));
+        }
+    }
+}
+
+static void read_idle(void)
+{
+    l4_pgentry_t *l4 = idle_pg_table;
+    unsigned int i4;
+
+    for ( i4 = 0; i4 < L4_PAGETABLE_ENTRIES; ++i4 )
+    {
+        unsigned int l4ef = l4e_get_flags(l4[i4]);
+
+        if ( !(l4ef & _PAGE_PRESENT) )
+            continue;
+
+        printk(" L4[%03u] = %"PRIpte" %s\n",
+               i4, l4e_get_intpte(l4[i4]), pte_flags_decode(l4ef));
+    }
+}
+
+#include <xen/keyhandler.h>
+#include <asm/setup.h>
+
+static void dump_offsets(const char *name, unsigned long addr)
+{
+    printk("  %-15s: %lu %lu %lu %lu\n", name, l4_table_offset(addr),
+           l3_table_offset(addr), l2_table_offset(addr), l1_table_offset(addr));
+}
+#define DUMP(x) dump_offsets(#x, (unsigned long)&(x))
+
+static void do_extreme_debug(unsigned char key, struct cpu_user_regs *regs)
+{
+    printk("'%c' pressed -> Extreme debugging in progress...\n", key);
+
+    switch ( key )
+    {
+    case '1':
+        dump_xen_mappings(0);
+        break;
+
+    case '2':
+        dump_xen_mappings(1);
+        break;
+
+    case '3':
+        read_idle();
+        break;
+
+    case '4':
+        DUMP(_stext);
+        DUMP(_etext);
+        DUMP(__2M_rodata_start);
+        DUMP(__2M_rodata_end);
+        DUMP(__2M_rwdata_start);
+        DUMP(__2M_rwdata_end);
+        break;
+    }
+}
+
+static int __init extreme_debug_keyhandler_init(void)
+{
+    register_irq_keyhandler('1', &do_extreme_debug, "Extreme debugging 1", 0);
+    register_irq_keyhandler('2', &do_extreme_debug, "Extreme debugging 2", 0);
+    register_irq_keyhandler('3', &do_extreme_debug, "Extreme debugging 3", 0);
+    register_irq_keyhandler('4', &do_extreme_debug, "Extreme debugging 3", 0);
+    return 0;
+}
+__initcall(extreme_debug_keyhandler_init);
+
 /*
  * Local variables:
  * mode: C
