linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Zwane Mwaikambo <zwane@arm.linux.org.uk>
To: Linus Torvalds <torvalds@osdl.org>
Cc: Linux Kernel <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] Boottime allocated GDTs and doublefault handler
Date: Mon, 20 Dec 2004 08:12:24 -0700 (MST)	[thread overview]
Message-ID: <Pine.LNX.4.61.0412200806060.17024@montezuma.fsmlabs.com> (raw)
In-Reply-To: <Pine.LNX.4.61.0412192307490.18310@montezuma.fsmlabs.com>

On Mon, 20 Dec 2004, Zwane Mwaikambo wrote:

> Ok =), i've added the page table walker and some basic code to fish out 
> 'current' and dump a few words of its stack. Sorry about the noise in the 
> patch but the nested if()s were beginning to go too far.

William Irwin pointed out my faulty highmem page check;

 arch/i386/kernel/doublefault.c |   89 +++++++++++++++++++++++++++++++----------
 arch/i386/kernel/traps.c       |    6 --
 include/asm-i386/thread_info.h |    6 ++
 3 files changed, 75 insertions(+), 26 deletions(-)

===== arch/i386/kernel/doublefault.c 1.4 vs edited =====
--- 1.4/arch/i386/kernel/doublefault.c	2004-08-24 03:08:41 -06:00
+++ edited/arch/i386/kernel/doublefault.c	2004-12-20 08:08:40 -07:00
@@ -3,6 +3,7 @@
 #include <linux/init.h>
 #include <linux/init_task.h>
 #include <linux/fs.h>
+#include <linux/highmem.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -13,37 +14,85 @@
 static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
 #define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
 
-#define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + 0x1000000)
+static int ptr_ok(unsigned long vaddr)
+{
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t pte;
+
+	__asm__ __volatile__("movl %%cr3, %0" : "=r"(pgd));
+	pgd = __va(pgd);
+	pgd += pgd_index(vaddr);
+	pmd = pmd_offset(pgd, vaddr);
+	if (pmd_none(*pmd))
+		return 0;
+	else if (pmd_large(*pmd))
+		return 1;
+#ifdef CONFIG_HIGHMEM
+	else if ((pmd_val(*pmd) >> PAGE_SHIFT) > page_to_pfn(highmem_start_page))
+		return 0;
+#endif
+	pte = *pte_offset_kernel(pmd, vaddr);
+	if (!pte_present(pte))
+		return 0;
+
+	return 1;
+}
 
 static void doublefault_fn(void)
 {
 	struct Xgt_desc_struct gdt_desc = {0, 0};
-	unsigned long gdt, tss;
+	struct tss_struct *t;
+	struct thread_info *ti;
+	struct task_struct *tsk;
+	unsigned long gdt, tss, *esp;
+	int r = 0;
 
 	__asm__ __volatile__("sgdt %0": "=m" (gdt_desc): :"memory");
 	gdt = gdt_desc.address;
 
 	printk("double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
 
-	if (ptr_ok(gdt)) {
-		gdt += GDT_ENTRY_TSS << 3;
-		tss = *(u16 *)(gdt+2);
-		tss += *(u8 *)(gdt+4) << 16;
-		tss += *(u8 *)(gdt+7) << 24;
-		printk("double fault, tss at %08lx\n", tss);
-
-		if (ptr_ok(tss)) {
-			struct tss_struct *t = (struct tss_struct *)tss;
-
-			printk("eip = %08lx, esp = %08lx\n", t->eip, t->esp);
-
-			printk("eax = %08lx, ebx = %08lx, ecx = %08lx, edx = %08lx\n",
-				t->eax, t->ebx, t->ecx, t->edx);
-			printk("esi = %08lx, edi = %08lx\n",
-				t->esi, t->edi);
-		}
-	}
+	if (!ptr_ok(gdt))
+		goto done;
+
+	gdt += GDT_ENTRY_TSS << 3;
+	tss = *(u16 *)(gdt+2);
+	tss += *(u8 *)(gdt+4) << 16;
+	tss += *(u8 *)(gdt+7) << 24;
+	printk("double fault, tss at %08lx\n", tss);
+
+	if (!ptr_ok(tss))
+		goto done;
+
+	t = (struct tss_struct *)tss;
+	printk("eip = %08lx, esp = %08lx\n", t->eip, t->esp);
+	printk("eax = %08lx, ebx = %08lx, ecx = %08lx, edx = %08lx\n",
+		t->eax, t->ebx, t->ecx, t->edx);
+	printk("esi = %08lx, edi = %08lx\n",
+		t->esi, t->edi);
+
+	if (!ptr_ok(t->esp))
+		goto done;
+
+	ti = (struct thread_info *)(t->esp & ~(THREAD_SIZE - 1));
+	tsk = ti->task;
+	if (!ptr_ok((unsigned long)tsk))
+		goto done;
+
+	esp = (unsigned long *)t->esp;
+	printk("task: %p (%s) stack:\n", tsk, tsk->comm);
+#if 0
+	show_stack(tsk, esp);
+#else
+	while (ptr_ok((unsigned long)esp) && valid_stack_ptr(ti, esp)) {
+		printk("%08lx ", *esp++);
+		if (!(++r % 8))
+			printk("\n");
+        }
+#endif
 
+done:
 	for (;;) /* nothing */;
 }
 
===== arch/i386/kernel/traps.c 1.91 vs edited =====
--- 1.91/arch/i386/kernel/traps.c	2004-11-23 17:47:27 -07:00
+++ edited/arch/i386/kernel/traps.c	2004-12-20 00:04:38 -07:00
@@ -105,12 +105,6 @@ int register_die_notifier(struct notifie
 	return err;
 }
 
-static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
-{
-	return	p > (void *)tinfo &&
-		p < (void *)tinfo + THREAD_SIZE - 3;
-}
-
 static inline unsigned long print_context_stack(struct thread_info *tinfo,
 				unsigned long *stack, unsigned long ebp)
 {
===== include/asm-i386/thread_info.h 1.23 vs edited =====
--- 1.23/include/asm-i386/thread_info.h	2004-11-19 00:03:11 -07:00
+++ edited/include/asm-i386/thread_info.h	2004-12-20 00:09:19 -07:00
@@ -95,6 +95,12 @@ static inline struct thread_info *curren
 /* how to get the current stack pointer from C */
 register unsigned long current_stack_pointer asm("esp") __attribute_used__;
 
+static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
+{
+        return  p > (void *)tinfo &&
+                p < (void *)tinfo + THREAD_SIZE - 3;
+}
+
 /* thread information allocation */
 #ifdef CONFIG_DEBUG_STACK_USAGE
 #define alloc_thread_info(tsk)					\

  reply	other threads:[~2004-12-20 15:21 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-12-20  0:48 [PATCH] Boottime allocated GDTs and doublefault handler Zwane Mwaikambo
2004-12-20  2:28 ` Linus Torvalds
2004-12-20  7:21   ` Zwane Mwaikambo
2004-12-20 15:12     ` Zwane Mwaikambo [this message]
2005-01-09  4:55       ` Zwane Mwaikambo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Pine.LNX.4.61.0412200806060.17024@montezuma.fsmlabs.com \
    --to=zwane@arm.linux.org.uk \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@osdl.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).