Hi,
While working on the RHEL 4 kernel (based on 2.6.9), i encountered a BUG()
in mm/memory.c:get_user_pages() at the line: BUG_ON(pte_none(*pte));
Seems like in_gate_area() returns true, but there is no pte to map the
page. That is, the in_gate_area() covers a larger range than what is
actually mapped.
I'm not sure if this is a problem in 2.6.11, as i didn't get a chance to
build and test a kernel based on 2.6.11.
The patch below fixed the problem i was seeing by simply restricting
in_gate_area(). Although as i look at this now it may be incorrect based
on the HAVE_BUGGY_SERGEL #define. I'll fix that up if this patch makes
sense to others...
thanks,
-Jason
--- linux/include/asm-ia64/page.h.bak 2005-04-22 12:30:29.000000000 -0400
+++ linux/include/asm-ia64/page.h 2005-04-22 13:50:26.000000000 -0400
@@ -195,4 +195,15 @@
#define devmem_is_allowed(x) 1
+#define CONFIG_ARCH_GATE_AREA 1
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+struct task_struct;
+struct vm_area_struct *get_gate_vma(struct task_struct *tsk);
+int in_gate_area(struct task_struct *task, unsigned long addr);
+#endif
+#endif
+
+
#endif /* _ASM_IA64_PAGE_H */
--- linux/arch/ia64/mm/init.c.bak 2005-04-22 12:33:15.000000000 -0400
+++ linux/arch/ia64/mm/init.c 2005-04-22 14:43:02.000000000 -0400
@@ -691,3 +691,26 @@
ia32_mem_init();
#endif
}
+
+static struct vm_area_struct gate_vma = {
+ .vm_mm = NULL,
+ .vm_start = FIXADDR_USER_START,
+ .vm_end = FIXADDR_USER_END,
+ .vm_page_prot = PAGE_READONLY,
+ .vm_flags = 0
+};
+
+struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
+{
+ return &gate_vma;
+}
+
+int in_gate_area(struct task_struct *task, unsigned long addr)
+{
+ if ((addr >= FIXADDR_USER_START) && (addr < FIXADDR_USER_START +
PAGE_SIZE))
+ return 1;
+ if ((addr >= FIXADDR_USER_START + PERCPU_PAGE_SIZE) && (addr <
FIXADDR_USER_START + PERCPU_PAGE_SIZE + PAGE_SIZE))
+ return 1;
+ return 0;
+}
+
#include <sys/ptrace.h>
#include <sys/types.h>
#include <unistd.h>
int main() {
pid_t pid;
int ret;
long val;
pid = fork();
if (pid == 0) {
//spin
while(1);
} else {
ret = ptrace(PTRACE_ATTACH, pid, NULL, NULL);
if(ret) {
perror("attach error");
exit(1);
}
val = ptrace(PTRACE_PEEKDATA, pid, 0xa000000000004000,
NULL);
printf("val is: %i\n", val);
}
}
-
To unsubscribe from this list: send the line "unsubscribe linux-ia64" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html