mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* Re: Fixing /proc/kcore
       [not found] <39B5C4829263D411AA93009027AE9EBB1EF28F7B@fmsmsx35.fm.intel.com.suse.lists.linux.kernel>
@ 2002-10-25 18:00 ` Andi Kleen
  0 siblings, 0 replies; 4+ messages in thread
From: Andi Kleen @ 2002-10-25 18:00 UTC (permalink / raw)
  To: Luck, Tony
  Cc: 'Mario Smarduch',
	IA64 Linux Mail Group, Linux Kernel Mailing List

"Luck, Tony" <tony.luck@intel.com> writes:

> This message is in MIME format. Since your mail reader does not understand
> this format, some or all of this message may not be legible.
> 
> ------_=_NextPart_000_01C27C4E.CD496DB0
> Content-Type: text/plain;
> 	charset="utf-7"
> 
> /proc/kcore is what you need, but it is broken on ia64 (and
> has been since the dawn of time for access to region 5) because
> it assumes that all kernel virtual addresses are above PAGE+AF8-OFFSET.
> This isn't true on ia64, VMALLOC+AF8-START is smaller than PAGE+AF8-OFFSET.

I recently fixed a similar problem on x86-64. There the modules are outside
the vmalloc area, but also not in the direct mapping. I just changed
the module mapping and the kernel mapping to put themselves into the vmlist.
kcore checks vmlist first and then afterwards tries direct addresses.

Also the kernel addresses are negative, which needed some more changes
in seek.

Here is the 2.4.19 patch which should to 2.5 too.

I think it's a bit cleaner than yours and will probably help you too.
Just put everything special into vmlist too.

-Andi

Index: linux/fs/proc/inode.c
===================================================================
RCS file: /home/cvs/Repository/linux/fs/proc/inode.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -u -r1.4 -r1.5
--- linux/fs/proc/inode.c	2002/01/15 10:09:21	1.4
--- linux/fs/proc/inode.c	2002/10/17 13:02:13	1.5
@@ -186,6 +186,7 @@
 	s->s_blocksize_bits = 10;
 	s->s_magic = PROC_SUPER_MAGIC;
 	s->s_op = &proc_sops;
+	s->s_maxbytes = ~0ULL;
 	
 	root_inode = proc_get_inode(s, PROC_ROOT_INO, &proc_root);
 	if (!root_inode)
Index: linux/fs/proc/kcore.c
===================================================================
RCS file: /home/cvs/Repository/linux/fs/proc/kcore.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -u -r1.3 -r1.4
--- linux/fs/proc/kcore.c	2002/03/21 11:54:59	1.3
--- linux/fs/proc/kcore.c	2002/10/17 13:02:13	1.4
@@ -27,11 +27,14 @@
 	return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
 }
 
+static loff_t lseek_kcore(struct file * file, loff_t offset, int origin);
+
 static ssize_t read_kcore(struct file *, char *, size_t, loff_t *);
 
 struct file_operations proc_kcore_operations = {
 	read:		read_kcore,
 	open:		open_kcore,
+	lseek:		lseek_kcore,
 };
 
 #ifdef CONFIG_KCORE_AOUT
@@ -112,9 +115,9 @@
 
 extern char saved_command_line[];
 
-static size_t get_kcore_size(int *num_vma, size_t *elf_buflen)
+static unsigned long get_kcore_size(int *num_vma, size_t *elf_buflen)
 {
-	size_t try, size;
+	unsigned long try, size;
 	struct vm_struct *m;
 
 	*num_vma = 0;
@@ -125,7 +128,7 @@
 	}
 
 	for (m=vmlist; m; m=m->next) {
-		try = (size_t)m->addr + m->size;
+		try = (unsigned long)m->addr + m->size;
 		if (try > size)
 			size = try;
 		*num_vma = *num_vma + 1;
@@ -313,14 +316,14 @@
 static ssize_t read_kcore(struct file *file, char *buffer, size_t buflen, loff_t *fpos)
 {
 	ssize_t acc = 0;
-	size_t size, tsz;
+	unsigned long size, tsz;
 	size_t elf_buflen;
 	int num_vma;
 	unsigned long start;
 
 	read_lock(&vmlist_lock);
 	proc_root_kcore->size = size = get_kcore_size(&num_vma, &elf_buflen);
-	if (buflen == 0 || *fpos >= size) {
+	if (buflen == 0 || (unsigned long long)*fpos >= size) {
 		read_unlock(&vmlist_lock);
 		return 0;
 	}
@@ -390,9 +393,16 @@
 	start = PAGE_OFFSET + (*fpos - elf_buflen);
 	if ((tsz = (PAGE_SIZE - (start & ~PAGE_MASK))) > buflen)
 		tsz = buflen;
-		
 	while (buflen) {
-		if ((start >= VMALLOC_START) && (start < VMALLOC_END)) {
+		int err; 
+	
+		if ((start > PAGE_OFFSET) && (start < (unsigned long)high_memory)) {
+			if (kern_addr_valid(start)) {
+				err = copy_to_user(buffer, (char *)start, tsz);
+			} else {
+				err = clear_user(buffer, tsz);
+			}
+		} else {
 			char * elf_buf;
 			struct vm_struct *m;
 			unsigned long curstart = start;
@@ -432,24 +442,11 @@
 					(char *)vmstart, vmsize);
 			}
 			read_unlock(&vmlist_lock);
-			if (copy_to_user(buffer, elf_buf, tsz)) {
-				kfree(elf_buf);
-				return -EFAULT;
-			}
+			err = copy_to_user(buffer, elf_buf, tsz); 
 			kfree(elf_buf);
-		} else if ((start > PAGE_OFFSET) && (start < 
-						(unsigned long)high_memory)) {
-			if (kern_addr_valid(start)) {
-				if (copy_to_user(buffer, (char *)start, tsz))
-					return -EFAULT;
-			} else {
-				if (clear_user(buffer, tsz))
-					return -EFAULT;
-			}
-		} else {
-			if (clear_user(buffer, tsz))
-				return -EFAULT;
-		}
+		} 	
+		if (err)
+			return -EFAULT; 
 		buflen -= tsz;
 		*fpos += tsz;
 		buffer += tsz;
@@ -461,3 +458,19 @@
 	return acc;
 }
 #endif /* CONFIG_KCORE_AOUT */
+
+static loff_t lseek_kcore(struct file * file, loff_t offset, int origin)
+{
+	long long retval;
+
+	switch (origin) {
+		case 2:
+			offset += file->f_dentry->d_inode->i_size;
+			break;
+		case 1:
+			offset += file->f_pos;
+	}
+	/* RED-PEN user can fake an error here by setting offset to >=-4095 && <0  */
+	file->f_pos = offset;
+	return offset;
+}

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Fixing /proc/kcore
  2002-10-28 19:03 Luck, Tony
@ 2002-10-28 19:10 ` Andi Kleen
  0 siblings, 0 replies; 4+ messages in thread
From: Andi Kleen @ 2002-10-28 19:10 UTC (permalink / raw)
  To: Luck, Tony; +Cc: Andi Kleen, IA64 Linux Mail Group, Linux Kernel Mailing List

On Mon, Oct 28, 2002 at 11:03:42AM -0800, Luck, Tony wrote:
> What about a combined approach ... architecture dependent code
> should add all the interesting stuff to the vmlist, so kcore just
> needs to walk the list to cover everything.  We could also keep the

Works for me. You just have to make sure to keep vmlist ordered
and make sure all users of vmlist check for their correct address
range (vmalloc.c does, but some arch specific code may not)

> KCORE_BASE concept from my patch, but turn it into a variable that
> the architecture dependent code can set to some suitable offset to
> keep all the offsets in /proc/kcore positive.  This will avoid
> having to fixup binutils (at least until someone comes up with an
> architecture where kernel space scatters across a wide enough range
> that we can't keep the offsets positive).

x86-64 is such an architecture, so binutils will need to be fixed anyways.

-andi

^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: Fixing /proc/kcore
@ 2002-10-28 19:03 Luck, Tony
  2002-10-28 19:10 ` Andi Kleen
  0 siblings, 1 reply; 4+ messages in thread
From: Luck, Tony @ 2002-10-28 19:03 UTC (permalink / raw)
  To: Andi Kleen; +Cc: IA64 Linux Mail Group, Linux Kernel Mailing List

Andi Kleen wrote:
> On Fri, Oct 25, 2002 at 02:14:44PM -0700, Luck, Tony wrote:
> > Putting everything into the vmlist looks to be a good idea.  Perhaps
> > there should be an entry for the "direct addresses" too?
> 
> Yes that would make sense.
> 
> > 
> > So what does:
> > 
> > 	# objdump -p /proc/kcore
> > 
> > look like for you?
> 
> Very messy because of the negative addresses and still some sign problems
> in binutils :-)

Oops, I didn't mean to take this discussion off the mailing list.

What about a combined approach ... architecture dependent code
should add all the interesting stuff to the vmlist, so kcore just
needs to walk the list to cover everything.  We could also keep the
KCORE_BASE concept from my patch, but turn it into a variable that
the architecture dependent code can set to some suitable offset to
keep all the offsets in /proc/kcore positive.  This will avoid
having to fixup binutils (at least until someone comes up with an
architecture where kernel space scatters across a wide enough range
that we can't keep the offsets positive).

-Tony

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Fixing /proc/kcore
@ 2002-10-25 17:49 Luck, Tony
  0 siblings, 0 replies; 4+ messages in thread
From: Luck, Tony @ 2002-10-25 17:49 UTC (permalink / raw)
  To: 'Mario Smarduch', IA64 Linux Mail Group; +Cc: Linux Kernel Mailing List

[-- Attachment #1: Type: text/plain, Size: 1170 bytes --]

/proc/kcore is what you need, but it is broken on ia64 (and
has been since the dawn of time for access to region 5) because
it assumes that all kernel virtual addresses are above PAGE_OFFSET.
This isn't true on ia64, VMALLOC_START is smaller than PAGE_OFFSET.

Attached is a patch (applies to 2.4.19 and to 2.5.39) that fixes the
assumption.  After applying you'll be able to use:

	# gdb vmlinux /proc/kcore

and happily ask gdb to examine addresses in region 5.

-Tony Luck



-----Original Message-----
From: Mario Smarduch [mailto:cms063@email.mot.com]
Sent: Friday, October 25, 2002 7:36 AM
To: IA64 Linux Mail Group
Subject: [Linux-ia64] Debugger/Analysis tool for IA64 Kernel Reg 5


Hi,
    I'm wondering if there is a tool available (gdb or some crash
analysis
tool) that can be used to disassemble/dump region 5 pages? We recently
have ported LiS and OpenSS7 stacks to IA-64 and it was painful without
being able to debug the Reg 5 memory, but we'll still be doing more
work.
We currently just have a crude tool that gets the reg 7 address from a
reg 5 address and then we use gdb, this is pretty cumbersome.....

- Mario.


[-- Attachment #2: kcore.patch --]
[-- Type: application/octet-stream, Size: 2357 bytes --]

diff -ru ../../REF/linux-2.5.39-ia64-020928/fs/proc/kcore.c aegl-kcore/fs/proc/kcore.c
--- ../../REF/linux-2.5.39-ia64-020928/fs/proc/kcore.c	Fri Sep 27 14:48:35 2002
+++ aegl-kcore/fs/proc/kcore.c	Fri Oct 25 08:25:31 2002
@@ -99,6 +99,12 @@
 }
 #else /* CONFIG_KCORE_AOUT */
 
+#if VMALLOC_START < PAGE_OFFSET
+#define	KCORE_BASE	VMALLOC_START
+#else
+#define	KCORE_BASE	PAGE_OFFSET
+#endif
+
 #define roundup(x, y)  ((((x)+((y)-1))/(y))*(y))
 
 /* An ELF note in memory */
@@ -118,7 +124,7 @@
 	struct vm_struct *m;
 
 	*num_vma = 0;
-	size = ((size_t)high_memory - PAGE_OFFSET + PAGE_SIZE);
+	size = ((size_t)high_memory - KCORE_BASE + PAGE_SIZE);
 	if (!vmlist) {
 		*elf_buflen = PAGE_SIZE;
 		return (size);
@@ -126,15 +132,15 @@
 
 	for (m=vmlist; m; m=m->next) {
 		try = (size_t)m->addr + m->size;
-		if (try > size)
-			size = try;
+		if (try > KCORE_BASE + size)
+			size = try - KCORE_BASE;
 		*num_vma = *num_vma + 1;
 	}
 	*elf_buflen =	sizeof(struct elfhdr) + 
 			(*num_vma + 2)*sizeof(struct elf_phdr) + 
 			3 * sizeof(struct memelfnote);
 	*elf_buflen = PAGE_ALIGN(*elf_buflen);
-	return (size - PAGE_OFFSET + *elf_buflen);
+	return size + *elf_buflen;
 }
 
 
@@ -237,7 +243,7 @@
 	offset += sizeof(struct elf_phdr);
 	phdr->p_type	= PT_LOAD;
 	phdr->p_flags	= PF_R|PF_W|PF_X;
-	phdr->p_offset	= dataoff;
+	phdr->p_offset	= PAGE_OFFSET - KCORE_BASE + dataoff;
 	phdr->p_vaddr	= PAGE_OFFSET;
 	phdr->p_paddr	= __pa(PAGE_OFFSET);
 	phdr->p_filesz	= phdr->p_memsz = ((unsigned long)high_memory - PAGE_OFFSET);
@@ -254,7 +260,7 @@
 
 		phdr->p_type	= PT_LOAD;
 		phdr->p_flags	= PF_R|PF_W|PF_X;
-		phdr->p_offset	= (size_t)m->addr - PAGE_OFFSET + dataoff;
+		phdr->p_offset	= (size_t)m->addr - KCORE_BASE + dataoff;
 		phdr->p_vaddr	= (size_t)m->addr;
 		phdr->p_paddr	= __pa(m->addr);
 		phdr->p_filesz	= phdr->p_memsz	= m->size;
@@ -385,9 +391,9 @@
 	/*
 	 * Fill the remainder of the buffer from kernel VM space.
 	 * We said in the ELF header that the data which starts
-	 * at 'elf_buflen' is virtual address PAGE_OFFSET. --rmk
+	 * at 'elf_buflen' is virtual address KCORE_BASE. --rmk
 	 */
-	start = PAGE_OFFSET + (*fpos - elf_buflen);
+	start = KCORE_BASE + (*fpos - elf_buflen);
 	if ((tsz = (PAGE_SIZE - (start & ~PAGE_MASK))) > buflen)
 		tsz = buflen;
 		

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2002-10-28 19:07 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <39B5C4829263D411AA93009027AE9EBB1EF28F7B@fmsmsx35.fm.intel.com.suse.lists.linux.kernel>
2002-10-25 18:00 ` Fixing /proc/kcore Andi Kleen
2002-10-28 19:03 Luck, Tony
2002-10-28 19:10 ` Andi Kleen
  -- strict thread matches above, loose matches on Subject: below --
2002-10-25 17:49 Luck, Tony

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome