@@ -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 ) \
@@ -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