x86-64, espfix: Don't leak bits 31:16 of %esp returning to 16-bit stack
[pandora-kernel.git] / arch / x86 / mm / dump_pagetables.c
index 0002a3a..e04e677 100644 (file)
@@ -30,11 +30,13 @@ struct pg_state {
        unsigned long start_address;
        unsigned long current_address;
        const struct addr_marker *marker;
+       unsigned long lines;
 };
 
 struct addr_marker {
        unsigned long start_address;
        const char *name;
+       unsigned long max_lines;
 };
 
 /* indices for address_markers; keep sync'd w/ address_markers below */
@@ -45,6 +47,7 @@ enum address_markers_idx {
        LOW_KERNEL_NR,
        VMALLOC_START_NR,
        VMEMMAP_START_NR,
+       ESPFIX_START_NR,
        HIGH_KERNEL_NR,
        MODULES_VADDR_NR,
        MODULES_END_NR,
@@ -67,6 +70,7 @@ static struct addr_marker address_markers[] = {
        { PAGE_OFFSET,          "Low Kernel Mapping" },
        { VMALLOC_START,        "vmalloc() Area" },
        { VMEMMAP_START,        "Vmemmap" },
+       { ESPFIX_BASE_ADDR,     "ESPfix Area", 16 },
        { __START_KERNEL_map,   "High Kernel Mapping" },
        { MODULES_VADDR,        "Modules" },
        { MODULES_END,          "End Modules" },
@@ -163,7 +167,7 @@ static void note_page(struct seq_file *m, struct pg_state *st,
                      pgprot_t new_prot, int level)
 {
        pgprotval_t prot, cur;
-       static const char units[] = "KMGTPE";
+       static const char units[] = "BKMGTPE";
 
        /*
         * If we have a "break" in the series, we need to flush the state that
@@ -178,6 +182,7 @@ static void note_page(struct seq_file *m, struct pg_state *st,
                st->current_prot = new_prot;
                st->level = level;
                st->marker = address_markers;
+               st->lines = 0;
                seq_printf(m, "---[ %s ]---\n", st->marker->name);
        } else if (prot != cur || level != st->level ||
                   st->current_address >= st->marker[1].start_address) {
@@ -188,17 +193,21 @@ static void note_page(struct seq_file *m, struct pg_state *st,
                /*
                 * Now print the actual finished series
                 */
-               seq_printf(m, "0x%0*lx-0x%0*lx   ",
-                          width, st->start_address,
-                          width, st->current_address);
-
-               delta = (st->current_address - st->start_address) >> 10;
-               while (!(delta & 1023) && unit[1]) {
-                       delta >>= 10;
-                       unit++;
+               if (!st->marker->max_lines ||
+                   st->lines < st->marker->max_lines) {
+                       seq_printf(m, "0x%0*lx-0x%0*lx   ",
+                                  width, st->start_address,
+                                  width, st->current_address);
+
+                       delta = (st->current_address - st->start_address);
+                       while (!(delta & 1023) && unit[1]) {
+                               delta >>= 10;
+                               unit++;
+                       }
+                       seq_printf(m, "%9lu%c ", delta, *unit);
+                       printk_prot(m, st->current_prot, st->level);
                }
-               seq_printf(m, "%9lu%c ", delta, *unit);
-               printk_prot(m, st->current_prot, st->level);
+               st->lines++;
 
                /*
                 * We print markers for special areas of address space,
@@ -206,7 +215,15 @@ static void note_page(struct seq_file *m, struct pg_state *st,
                 * This helps in the interpretation.
                 */
                if (st->current_address >= st->marker[1].start_address) {
+                       if (st->marker->max_lines &&
+                           st->lines > st->marker->max_lines) {
+                               unsigned long nskip =
+                                       st->lines - st->marker->max_lines;
+                               seq_printf(m, "... %lu entr%s skipped ... \n",
+                                          nskip, nskip == 1 ? "y" : "ies");
+                       }
                        st->marker++;
+                       st->lines = 0;
                        seq_printf(m, "---[ %s ]---\n", st->marker->name);
                }