Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Linux: Kernel

UML fails to locate address space

 

 

Linux kernel RSS feed   Index | Next | Previous | View Threaded


tspink at gmail

May 20, 2008, 4:08 AM

Post #1 of 22 (7811 views)
Permalink
UML fails to locate address space

Hi,

I've just recently pulled the latest GIT and compiled UML, however,
when I run it a message appears saying "Locating the top of the
address space... Address 0x0 no good?" and the program exits.

After some digging, it appears that page_ok is returning false when
checking 'bottom', in os_get_task_size
(arch/um/os-Linux/sys-i386/task_size.c:96). After running through
GDB, it seems that in line 31 of that file is where the segfault
occurs:

n = *address;

i.e. when trying to read from the address space (at address zero).

Here is GDB's output:

Program received signal SIGSEGV, Segmentation fault.
0x0806d993 in page_ok (page=0) at arch/um/os-Linux/sys-i386/task_size.c:31
31 n = *address;
(gdb) bt
#0 0x0806d993 in page_ok (page=0) at arch/um/os-Linux/sys-i386/task_size.c:31
#1 0x0806daf8 in os_get_task_size () at
arch/um/os-Linux/sys-i386/task_size.c:96
#2 0x0804ac7f in linux_main (argc=5, argv=0xbfe438a4) at
arch/um/kernel/um_arch.c:277
#3 0x0804b82f in main (argc=5, argv=0xbfe438a4, envp=0xbfe438bc) at
arch/um/os-Linux/main.c:150

As I mentioned, this is the latest git, running on a 32-bit x86 with
Ubuntu stock kernel 2.6.24-17. As a quick hack, I manually got the
function to return ~3Gb, and UML continued to boot. Any ideas, or any
more information you need?

(I've CCed Jeff Dike, as I saw it was his patch that introduced this code)

--
Regards,
Tom Spink
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


jdike at addtoit

May 20, 2008, 6:52 AM

Post #2 of 22 (7742 views)
Permalink
Re: UML fails to locate address space [In reply to]

On Tue, May 20, 2008 at 12:08:24PM +0100, Tom Spink wrote:
> I've just recently pulled the latest GIT and compiled UML, however,
> when I run it a message appears saying "Locating the top of the
> address space... Address 0x0 no good?" and the program exits.

Can you strace it and send me the output?

> After some digging, it appears that page_ok is returning false when
> checking 'bottom', in os_get_task_size
> (arch/um/os-Linux/sys-i386/task_size.c:96). After running through
> GDB, it seems that in line 31 of that file is where the segfault
> occurs:
>
> n = *address;
>
> i.e. when trying to read from the address space (at address zero).

The segfaults are on purpose - it will trap SIGSEGV and longjmp out of
the handler and mark the affected address as not-usable.

Jeff

--
Work email - jdike at linux dot intel dot com
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


tspink at gmail

May 20, 2008, 6:59 AM

Post #3 of 22 (7740 views)
Permalink
Re: UML fails to locate address space [In reply to]

2008/5/20 Jeff Dike <jdike [at] addtoit>:
> On Tue, May 20, 2008 at 12:08:24PM +0100, Tom Spink wrote:
>> I've just recently pulled the latest GIT and compiled UML, however,
>> when I run it a message appears saying "Locating the top of the
>> address space... Address 0x0 no good?" and the program exits.
>
> Can you strace it and send me the output?

Attached. I guess the line of interest is:

mmap2(NULL, 4096, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = -1 EACCES (Permission
denied)

>
>> After some digging, it appears that page_ok is returning false when
>> checking 'bottom', in os_get_task_size
>> (arch/um/os-Linux/sys-i386/task_size.c:96). After running through
>> GDB, it seems that in line 31 of that file is where the segfault
>> occurs:
>>
>> n = *address;
>>
>> i.e. when trying to read from the address space (at address zero).
>
> The segfaults are on purpose - it will trap SIGSEGV and longjmp out of
> the handler and mark the affected address as not-usable.

I gathered that much - I was just letting you know which test it was
that was failing.

>
> Jeff
>

Thanks!

--
Tom Spink
Attachments: uml-strace (2.91 KB)


linux-os at analogic

May 20, 2008, 8:22 AM

Post #4 of 22 (7724 views)
Permalink
Re: UML fails to locate address space [In reply to]

On Tue, 20 May 2008, Jeff Dike wrote:

> On Tue, May 20, 2008 at 12:08:24PM +0100, Tom Spink wrote:
>> I've just recently pulled the latest GIT and compiled UML, however,
>> when I run it a message appears saying "Locating the top of the
>> address space... Address 0x0 no good?" and the program exits.
>
> Can you strace it and send me the output?
>
>> After some digging, it appears that page_ok is returning false when
>> checking 'bottom', in os_get_task_size
>> (arch/um/os-Linux/sys-i386/task_size.c:96). After running through
>> GDB, it seems that in line 31 of that file is where the segfault
>> occurs:
>>
>> n = *address;
>>
>> i.e. when trying to read from the address space (at address zero).
>
> The segfaults are on purpose - it will trap SIGSEGV and longjmp out of
> the handler and mark the affected address as not-usable.
>
> Jeff

Does this mean that I cannot mmap() address zero in the kernel
anymore? I should be able (in the kernel) read anything, and
then mmap() it to something usable in user-space. If address
zero is now artifically trapped there are problems being created
for no good reason at all.


Cheers,
Dick Johnson
Penguin : Linux version 2.6.22.1 on an i686 machine (5588.29 BogoMips).
My book : http://www.AbominableFirebug.com/
_


****************************************************************
The information transmitted in this message is confidential and may be privileged. Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited. If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors [at] analogic - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


jdike at addtoit

May 20, 2008, 9:10 AM

Post #5 of 22 (7746 views)
Permalink
Re: UML fails to locate address space [In reply to]

On Tue, May 20, 2008 at 02:59:14PM +0100, Tom Spink wrote:
> Attached. I guess the line of interest is:
>
> mmap2(NULL, 4096, PROT_READ|PROT_WRITE,
> MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = -1 EACCES (Permission
> denied)

Yup.

Can you try three things:
check the maps file for any arbitrary process
(i.e. /proc/$$/maps) and see if there's anything mapped at 0
gdb UML, stop it at that mmap, check its maps file and see if
there's anything mapped at 0
send me a pointer to the patches that Ubuntu has applied on
top of the stock kernel - I'm suspicious that they special-cased page
zero in order to ensure that NULL pointer dereferences cause faults.

You can test this last theory by initializing bottom to 4096 instead
of 0.

Jeff

--
Work email - jdike at linux dot intel dot com
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


tspink at gmail

May 20, 2008, 9:43 AM

Post #6 of 22 (7754 views)
Permalink
Re: UML fails to locate address space [In reply to]

2008/5/20 Jeff Dike <jdike [at] addtoit>:
> On Tue, May 20, 2008 at 02:59:14PM +0100, Tom Spink wrote:
>> Attached. I guess the line of interest is:
>>
>> mmap2(NULL, 4096, PROT_READ|PROT_WRITE,
>> MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = -1 EACCES (Permission
>> denied)
>
> Yup.
>
> Can you try three things:
> check the maps file for any arbitrary process
> (i.e. /proc/$$/maps) and see if there's anything mapped at 0

Nothing.

> gdb UML, stop it at that mmap, check its maps file and see if
> there's anything mapped at 0

Nope.

> send me a pointer to the patches that Ubuntu has applied on
> top of the stock kernel - I'm suspicious that they special-cased page
> zero in order to ensure that NULL pointer dereferences cause faults.
>
> You can test this last theory by initializing bottom to 4096 instead
> of 0.

I suspected this type of foul-play, and tried altering bottom to 1,
but this didn't work. So, I took out the page_ok test, and it
continued booting. So I went back, put the test back in and
incremented bottom until I got to 16. It worked at 16. :-)

Is this something that can be fixed, or would a config option be appropriate?

I am willing to blame Ubuntu, but unfortunately, I can't find an
online resource of their patches.

> Jeff
>
> --
> Work email - jdike at linux dot intel dot com
>

--
Tom Spink
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


jdike at addtoit

May 20, 2008, 10:35 AM

Post #7 of 22 (7731 views)
Permalink
Re: UML fails to locate address space [In reply to]

On Tue, May 20, 2008 at 11:22:08AM -0400, linux-os (Dick Johnson) wrote:
> Does this mean that I cannot mmap() address zero in the kernel
> anymore? I should be able (in the kernel) read anything, and
> then mmap() it to something usable in user-space. If address
> zero is now artifically trapped there are problems being created
> for no good reason at all.

We're operating from userspace here.

In any case, this hasn't happened with any kernel I've seen, but I'm
suspicious that Ubuntu has started treating page zero specially.

Jeff

--
Work email - jdike at linux dot intel dot com
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


jdike at addtoit

May 20, 2008, 10:56 AM

Post #8 of 22 (7725 views)
Permalink
Re: UML fails to locate address space [In reply to]

On Tue, May 20, 2008 at 05:43:17PM +0100, Tom Spink wrote:
> I suspected this type of foul-play, and tried altering bottom to 1,
> but this didn't work. So, I took out the page_ok test, and it
> continued booting. So I went back, put the test back in and
> incremented bottom until I got to 16. It worked at 16. :-)

Heh, I guess they were also worried about up to 64K offsets off a NULL
pointer too.

> Is this something that can be fixed, or would a config option be
> appropriate?

This was done in order to remove config options. It might be
reasonable to effectively do what you did, and search for the lowest
address at which mmap works and start from there.

> I am willing to blame Ubuntu, but unfortunately, I can't find an
> online resource of their patches.

https://wiki.ubuntu.com/KernelGitGuide lists a bunch of git repos.
Tell me which one applies to you and I'll take a look.

Jeff


--
Work email - jdike at linux dot intel dot com
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


tspink at gmail

May 20, 2008, 11:01 AM

Post #9 of 22 (7727 views)
Permalink
Re: UML fails to locate address space [In reply to]

2008/5/20 Jeff Dike <jdike [at] addtoit>:
> On Tue, May 20, 2008 at 05:43:17PM +0100, Tom Spink wrote:
>> I suspected this type of foul-play, and tried altering bottom to 1,
>> but this didn't work. So, I took out the page_ok test, and it
>> continued booting. So I went back, put the test back in and
>> incremented bottom until I got to 16. It worked at 16. :-)
>
> Heh, I guess they were also worried about up to 64K offsets off a NULL
> pointer too.

<g>

>
>> Is this something that can be fixed, or would a config option be
>> appropriate?
>
> This was done in order to remove config options. It might be
> reasonable to effectively do what you did, and search for the lowest
> address at which mmap works and start from there.

Cool, and nice work BTW. I just for-looped up the way, from 0.

>
>> I am willing to blame Ubuntu, but unfortunately, I can't find an
>> online resource of their patches.
>
> https://wiki.ubuntu.com/KernelGitGuide lists a bunch of git repos.
> Tell me which one applies to you and I'll take a look.
>

I'm a hardy. I bet it's 893f802872c3.

http://kernel.ubuntu.com/git?p=ubuntu/ubuntu-hardy.git;a=commitdiff;h=893f802872c3e3c6e4bb40c3be4845784b81b934

> Jeff

--
Tom Spink
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


jdike at addtoit

May 20, 2008, 12:24 PM

Post #10 of 22 (7738 views)
Permalink
Re: UML fails to locate address space [In reply to]

On Tue, May 20, 2008 at 07:01:02PM +0100, Tom Spink wrote:
> I'm a hardy. I bet it's 893f802872c3.
>
> http://kernel.ubuntu.com/git?p=ubuntu/ubuntu-hardy.git;a=commitdiff;h=893f802872c3e3c6e4bb40c3be4845784b81b934

Looks right, and mmap_min_addr is in mainline, just with a value of
zero. So, it looks like the right thing to do is read the value of
/proc/sys/vm/mmap_min_addr and start bottom there.

Jeff

--
Work email - jdike at linux dot intel dot com
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


tspink at gmail

May 20, 2008, 12:42 PM

Post #11 of 22 (7730 views)
Permalink
Re: UML fails to locate address space [In reply to]

2008/5/20 Jeff Dike <jdike [at] addtoit>:
> On Tue, May 20, 2008 at 07:01:02PM +0100, Tom Spink wrote:
>> I'm a hardy. I bet it's 893f802872c3.
>>
>> http://kernel.ubuntu.com/git?p=ubuntu/ubuntu-hardy.git;a=commitdiff;h=893f802872c3e3c6e4bb40c3be4845784b81b934
>
> Looks right, and mmap_min_addr is in mainline, just with a value of
> zero. So, it looks like the right thing to do is read the value of
> /proc/sys/vm/mmap_min_addr and start bottom there.
>
> Jeff
>
> --
> Work email - jdike at linux dot intel dot com
>

Wuhoo.

tom [at] holl:~$ cat /proc/sys/vm/mmap_min_addr
65536

And this is what I did:

diff --git a/arch/um/os-Linux/sys-i386/task_size.c
b/arch/um/os-Linux/sys-i386/task_size.c
index ccb49b0..f5ece4b 100644
--- a/arch/um/os-Linux/sys-i386/task_size.c
+++ b/arch/um/os-Linux/sys-i386/task_size.c
@@ -1,10 +1,14 @@
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
+#include <fcntl.h>
+#include <unistd.h>
#include <sys/mman.h>
#include "longjmp.h"
#include "kern_constants.h"

+#define PROC_MMAP_MIN_ADDR "/proc/sys/vm/mmap_min_addr"
+
static jmp_buf buf;

static void segfault(int sig)
@@ -63,10 +67,34 @@ static int page_ok(unsigned long page)
return ok;
}

+static unsigned long get_mmap_min_addr(void)
+{
+ unsigned long ret = 0;
+ char mmap_min_addr[8];
+ int fd;
+ struct stat s;
+
+ /* Determine the minimum mmap address. */
+ if (stat(PROC_MMAP_MIN_ADDR, &s) == 0) {
+ /* Open the proc file, and read in the value. */
+ fd = open(PROC_MMAP_MIN_ADDR, O_RDONLY);
+ if (fd < 0)
+ return ret;
+
+ read(fd, mmap_min_addr, sizeof(mmap_min_addr));
+ close(fd);
+
+ /* Determine the address. */
+ ret = strtoul(mmap_min_addr, NULL, 0) >> UM_KERN_PAGE_SHIFT;
+ }
+
+ return ret;
+}
+
unsigned long os_get_task_size(void)
{
struct sigaction sa, old;
- unsigned long bottom = 0;
+ unsigned long bottom;
/*
* A 32-bit UML on a 64-bit host gets confused about the VDSO at
* 0xffffe000. It is mapped, is readable, can be reprotected writeable
@@ -78,6 +106,10 @@ unsigned long os_get_task_size(void)
unsigned long top = 0xffffd000 >> UM_KERN_PAGE_SHIFT;
unsigned long test;

+ printf("Determining the bottom of the address space ... ");
+ bottom = get_mmap_min_addr();
+ printf("0x%x\n", bottom);
+
printf("Locating the top of the address space ... ");
fflush(stdout);
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


jdike at addtoit

May 20, 2008, 2:27 PM

Post #12 of 22 (7722 views)
Permalink
Re: UML fails to locate address space [In reply to]

On Tue, May 20, 2008 at 08:42:54PM +0100, Tom Spink wrote:
> And this is what I did:

Looks OK, but I need a Signed-off-by.

Some style comments, which I can take care of if you don't feel like it:
there's only one use of PROC_MMAP_MIN_ADDR, so you might as
well inline the filename
the stat is unnecessary - open failing will tell you what you
need to know
the strtoul needs some error checking
I'd change the mmap_min_addr[8] to [sizeof("12345678")] to
make it clear what's expected to fit into it

On a less-stylistic note, this thing does have to work in the absence
of /proc since UML is commonly run inside chroot. So, I'm thinking we
still need the loop looking for the bottom of the address space in
this case. And, if you have it, you might as well use it, as that's
less code, and it makes sure the loop is exercised. That grieves me a
little, as I'd like to just read mmap_min_addr and be done with it in
the normal case.

Jeff

--
Work email - jdike at linux dot intel dot com
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


linux-os at analogic

May 20, 2008, 2:54 PM

Post #13 of 22 (7736 views)
Permalink
Re: UML fails to locate address space [In reply to]

On Tue, 20 May 2008, Jeff Dike wrote:

> On Tue, May 20, 2008 at 11:22:08AM -0400, linux-os (Dick Johnson) wrote:
>> Does this mean that I cannot mmap() address zero in the kernel
>> anymore? I should be able (in the kernel) read anything, and
>> then mmap() it to something usable in user-space. If address
>> zero is now artifically trapped there are problems being created
>> for no good reason at all.
>
> We're operating from userspace here.
>
> In any case, this hasn't happened with any kernel I've seen, but I'm
> suspicious that Ubuntu has started treating page zero specially.
>
> Jeff

Okay, then instead of putting a NULL in the "hint" to mmap() try
something else (0x1000?). That may help.



Cheers,
Dick Johnson
Penguin : Linux version 2.6.22.1 on an i686 machine (5588.29 BogoMips).
My book : http://www.AbominableFirebug.com/
_


****************************************************************
The information transmitted in this message is confidential and may be privileged. Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited. If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors [at] analogic - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


linux-os at analogic

May 20, 2008, 2:58 PM

Post #14 of 22 (7730 views)
Permalink
Re: UML fails to locate address space [In reply to]

On Tue, 20 May 2008, Jeff Dike wrote:

> On Tue, May 20, 2008 at 11:22:08AM -0400, linux-os (Dick Johnson) wrote:
>> Does this mean that I cannot mmap() address zero in the kernel
>> anymore? I should be able (in the kernel) read anything, and
>> then mmap() it to something usable in user-space. If address
>> zero is now artifically trapped there are problems being created
>> for no good reason at all.
>
> We're operating from userspace here.
>
> In any case, this hasn't happened with any kernel I've seen, but I'm
> suspicious that Ubuntu has started treating page zero specially.
>
> Jeff
>

Yes, shouldn't be.


Cheers,
Dick Johnson
Penguin : Linux version 2.6.22.1 on an i686 machine (5588.29 BogoMips).
My book : http://www.AbominableFirebug.com/
_


****************************************************************
The information transmitted in this message is confidential and may be privileged. Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited. If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors [at] analogic - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


tspink at gmail

May 20, 2008, 3:03 PM

Post #15 of 22 (7725 views)
Permalink
Re: UML fails to locate address space [In reply to]

2008/5/20 Jeff Dike <jdike [at] addtoit>:
> On Tue, May 20, 2008 at 08:42:54PM +0100, Tom Spink wrote:
>> And this is what I did:
>
> Looks OK, but I need a Signed-off-by.
>
> Some style comments, which I can take care of if you don't feel like it:
> there's only one use of PROC_MMAP_MIN_ADDR, so you might as
> well inline the filename
> the stat is unnecessary - open failing will tell you what you
> need to know
> the strtoul needs some error checking
> I'd change the mmap_min_addr[8] to [sizeof("12345678")] to
> make it clear what's expected to fit into it
>
> On a less-stylistic note, this thing does have to work in the absence
> of /proc since UML is commonly run inside chroot. So, I'm thinking we
> still need the loop looking for the bottom of the address space in
> this case. And, if you have it, you might as well use it, as that's
> less code, and it makes sure the loop is exercised. That grieves me a
> little, as I'd like to just read mmap_min_addr and be done with it in
> the normal case.
>
> Jeff
>
> --
> Work email - jdike at linux dot intel dot com
>

I was re-writing the patch, but after reading over the function, is
the return value correct? I did a quick run through on paper about
what would happen if the (real) bottom = 5 and the (real) top = 15,
and the (initial) top = 20. So this is a size of 10 pages, which is
what the function should return... but:

top = 20, bottom = 5
test = 12
bottom = 12
(top - bottom) = 8

top = 20, bottom = 12
test = 16
top = 16
(top - bottom) = 4

top = 16, bottom = 12
test = 14
bottom = 14
(top - bottom) = 2

top = 16, bottom = 14
test = 15
bottom = 15
(top - bottom) = 1

<loop exits>

return 16 << UM_KERN_PAGE_SHIFT;

Hmm. Are my calculations wrong?

--
Tom Spink
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


tspink at gmail

May 20, 2008, 4:57 PM

Post #16 of 22 (7714 views)
Permalink
Re: UML fails to locate address space [In reply to]

2008/5/20 Tom Spink <tspink [at] gmail>:
> 2008/5/20 Jeff Dike <jdike [at] addtoit>:
>> On Tue, May 20, 2008 at 08:42:54PM +0100, Tom Spink wrote:
>>> And this is what I did:
>>
>> Looks OK, but I need a Signed-off-by.
>>
>> Some style comments, which I can take care of if you don't feel like it:
>> there's only one use of PROC_MMAP_MIN_ADDR, so you might as
>> well inline the filename
>> the stat is unnecessary - open failing will tell you what you
>> need to know
>> the strtoul needs some error checking
>> I'd change the mmap_min_addr[8] to [sizeof("12345678")] to
>> make it clear what's expected to fit into it
>>
>> On a less-stylistic note, this thing does have to work in the absence
>> of /proc since UML is commonly run inside chroot. So, I'm thinking we
>> still need the loop looking for the bottom of the address space in
>> this case. And, if you have it, you might as well use it, as that's
>> less code, and it makes sure the loop is exercised. That grieves me a
>> little, as I'd like to just read mmap_min_addr and be done with it in
>> the normal case.
>>
>> Jeff
>>
>> --
>> Work email - jdike at linux dot intel dot com
>>
>
> I was re-writing the patch, but after reading over the function, is
> the return value correct? I did a quick run through on paper about
> what would happen if the (real) bottom = 5 and the (real) top = 15,
> and the (initial) top = 20. So this is a size of 10 pages, which is
> what the function should return... but:
>

Here's the new patch, with that size correction in. Does this look okay?

---

From: Tom Spink <tspink [at] gmail>
Date: Wed, 21 May 2008 00:53:54 +0100
Subject: [PATCH] Read the minimum mmap address from proc

This patch makes os_get_task_size read the minimum mmap address from the proc
entry on the host system, if available. If not, it resorts to manually
searching for the minimum mmap address by incrementally testing pages from
zero onwards.

Because the bottom of the address space may not be zero, it's not sufficient
to assume the top of the address space is the size of the address space. The
size is the difference between the top address and bottom address.

Signed-off-by: Tom Spink <tspink [at] gmail>
---
arch/um/os-Linux/sys-i386/task_size.c | 63 ++++++++++++++++++++++++++++-----
1 files changed, 54 insertions(+), 9 deletions(-)

diff --git a/arch/um/os-Linux/sys-i386/task_size.c
b/arch/um/os-Linux/sys-i386/task_size.c
index ccb49b0..66811ae 100644
--- a/arch/um/os-Linux/sys-i386/task_size.c
+++ b/arch/um/os-Linux/sys-i386/task_size.c
@@ -1,6 +1,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
+#include <fcntl.h>
+#include <unistd.h>
#include <sys/mman.h>
#include "longjmp.h"
#include "kern_constants.h"
@@ -63,6 +65,28 @@ static int page_ok(unsigned long page)
return ok;
}

+static unsigned long get_mmap_min_addr(void)
+{
+ unsigned long mmap_min_addr;
+ int fd;
+ char ma_buffer[sizeof("12345678")];
+
+ /* Open the proc entry for mmap_min_addr. */
+ fd = open("/proc/sys/vm/mmap_min_addr", O_RDONLY);
+ if (fd < 0)
+ return 0;
+
+ read(fd, ma_buffer, sizeof(ma_buffer));
+ close(fd);
+
+ /* Determine the reported minimum address. */
+ mmap_min_addr = strtoul(ma_buffer, NULL, 0);
+ if (mmap_min_addr < 0)
+ return 0;
+
+ return mmap_min_addr >> UM_KERN_PAGE_SHIFT;
+}
+
unsigned long os_get_task_size(void)
{
struct sigaction sa, old;
@@ -76,11 +100,16 @@ unsigned long os_get_task_size(void)
* hosts, but shouldn't hurt otherwise.
*/
unsigned long top = 0xffffd000 >> UM_KERN_PAGE_SHIFT;
- unsigned long test;
+ unsigned long test, original;

- printf("Locating the top of the address space ... ");
+ printf("Locating the bottom of the address space ... ");
fflush(stdout);

+ /* Use our function to try and read the minimum mmap address
+ * from proc.
+ */
+ bottom = get_mmap_min_addr();
+
/*
* We're going to be longjmping out of the signal handler, so
* SA_DEFER needs to be set.
@@ -93,13 +122,30 @@ unsigned long os_get_task_size(void)
exit(1);
}

- if (!page_ok(bottom)) {
- fprintf(stderr, "Address 0x%x no good?\n",
- bottom << UM_KERN_PAGE_SHIFT);
- exit(1);
+ /* If the page from get_mmap_min_addr was okay, then continue. */
+ if (page_ok(bottom))
+ goto found_bottom;
+
+ /* This might happen if UML is running in a chroot, i.e. we
+ * can't access proc. So, let's just manually scan until we
+ * get a valid page (or run out of them).
+ */
+ for (bottom = 0; bottom < top; bottom++) {
+ if (page_ok(bottom))
+ goto found_bottom;
}

+ /* If we've got this far, we ran out of pages. */
+ fprintf(stderr, "Unable to determine bottom of address space.\n");
+ exit(1);
+
+found_bottom:
+ printf("0x%x\n", bottom << UM_KERN_PAGE_SHIFT);
+ printf("Locating the top of the address space ... ");
+ fflush(stdout);
+
/* This could happen with a 4G/4G split */
+ original = bottom;
if (page_ok(top))
goto out;

@@ -117,8 +163,7 @@ out:
perror("os_get_task_size");
exit(1);
}
- top <<= UM_KERN_PAGE_SHIFT;
- printf("0x%x\n", top);
+ printf("0x%x\n", top << UM_KERN_PAGE_SHIFT);

- return top;
+ return (top - original) << UM_KERN_PAGE_SHIFT;
}
--
1.5.4.3
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


jdike at addtoit

May 20, 2008, 6:58 PM

Post #17 of 22 (7735 views)
Permalink
Re: UML fails to locate address space [In reply to]

On Wed, May 21, 2008 at 12:57:21AM +0100, Tom Spink wrote:
> Here's the new patch, with that size correction in. Does this look okay?

Actually, since the search for the lowest valid page needs to be there
anyway, I think we should just always use it, and not bother with
/proc/sys/vm/mmap_min_addr at all. Less code, and the new code is
more heavily exercised this way.

Jeff

--
Work email - jdike at linux dot intel dot com
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


jdike at addtoit

May 20, 2008, 7:15 PM

Post #18 of 22 (7723 views)
Permalink
Re: UML fails to locate address space [In reply to]

On Tue, May 20, 2008 at 05:54:34PM -0400, linux-os (Dick Johnson) wrote:
> Okay, then instead of putting a NULL in the "hint" to mmap() try
> something else (0x1000?). That may help.

You don't seem to have followed the thread. For UML, the address
isn't a hint - it's a requirement. Tossing random numbers into your
code until a particular test works isn't really the way to go. In
this case, we are looking at mmap_min_addr being set at 0x10000, but
which may be set to 0x20000 someplace else.

Jeff

--
Work email - jdike at linux dot intel dot com
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


tspink at gmail

May 21, 2008, 5:02 AM

Post #19 of 22 (7719 views)
Permalink
Re: UML fails to locate address space [In reply to]

2008/5/21 Jeff Dike <jdike [at] addtoit>:
> On Tue, May 20, 2008 at 05:54:34PM -0400, linux-os (Dick Johnson) wrote:
>> Okay, then instead of putting a NULL in the "hint" to mmap() try
>> something else (0x1000?). That may help.
>
> You don't seem to have followed the thread. For UML, the address
> isn't a hint - it's a requirement. Tossing random numbers into your
> code until a particular test works isn't really the way to go. In
> this case, we are looking at mmap_min_addr being set at 0x10000, but
> which may be set to 0x20000 someplace else.
>
> Jeff
>

Hi Jeff,

Here is the revised version - I cheered Dijkstra up by getting rid of that goto.

-- Tom

--

From: Tom Spink <tspink [at] gmail>
Date: Wed, 21 May 2008 00:53:54 +0100
Subject: [PATCH] Locate the bottom of the address space

This patch makes os_get_task_size locate the bottom of the address space,
as well as the top. This is for systems which put a lower limit on mmap
addresses. It works by manually scanning pages from zero onwards until a
valid page is found.

Because the bottom of the address space may not be zero, it's not sufficient
to assume the top of the address space is the size of the address space. The
size is the difference between the top address and bottom address.

Signed-off-by: Tom Spink <tspink [at] gmail>
---
arch/um/os-Linux/sys-i386/task_size.c | 30 ++++++++++++++++++++++--------
1 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/arch/um/os-Linux/sys-i386/task_size.c
b/arch/um/os-Linux/sys-i386/task_size.c
index ccb49b0..d1e3604 100644
--- a/arch/um/os-Linux/sys-i386/task_size.c
+++ b/arch/um/os-Linux/sys-i386/task_size.c
@@ -1,6 +1,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
+#include <fcntl.h>
+#include <unistd.h>
#include <sys/mman.h>
#include "longjmp.h"
#include "kern_constants.h"
@@ -76,9 +78,9 @@ unsigned long os_get_task_size(void)
* hosts, but shouldn't hurt otherwise.
*/
unsigned long top = 0xffffd000 >> UM_KERN_PAGE_SHIFT;
- unsigned long test;
+ unsigned long test, original;

- printf("Locating the top of the address space ... ");
+ printf("Locating the bottom of the address space ... ");
fflush(stdout);

/*
@@ -93,13 +95,26 @@ unsigned long os_get_task_size(void)
exit(1);
}

- if (!page_ok(bottom)) {
- fprintf(stderr, "Address 0x%x no good?\n",
- bottom << UM_KERN_PAGE_SHIFT);
+ /* Manually scan the address space, bottom-up, until we find
+ * the first valid page (or run out of them).
+ */
+ for (bottom = 0; bottom < top; bottom++) {
+ if (page_ok(bottom))
+ break;
+ }
+
+ /* If we've got this far, we ran out of pages. */
+ if (bottom == top) {
+ fprintf(stderr, "Unable to determine bottom of address space.\n");
exit(1);
}
+
+ printf("0x%x\n", bottom << UM_KERN_PAGE_SHIFT);
+ printf("Locating the top of the address space ... ");
+ fflush(stdout);

/* This could happen with a 4G/4G split */
+ original = bottom;
if (page_ok(top))
goto out;

@@ -117,8 +132,7 @@ out:
perror("os_get_task_size");
exit(1);
}
- top <<= UM_KERN_PAGE_SHIFT;
- printf("0x%x\n", top);
+ printf("0x%x\n", top << UM_KERN_PAGE_SHIFT);

- return top;
+ return (top - original) << UM_KERN_PAGE_SHIFT;
}
--
1.5.4.3
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


tspink at gmail

May 21, 2008, 5:04 AM

Post #20 of 22 (7709 views)
Permalink
Re: UML fails to locate address space [In reply to]

2008/5/21 Tom Spink <tspink [at] gmail>:
> 2008/5/21 Jeff Dike <jdike [at] addtoit>:
>> On Tue, May 20, 2008 at 05:54:34PM -0400, linux-os (Dick Johnson) wrote:
>>> Okay, then instead of putting a NULL in the "hint" to mmap() try
>>> something else (0x1000?). That may help.
>>
>> You don't seem to have followed the thread. For UML, the address
>> isn't a hint - it's a requirement. Tossing random numbers into your
>> code until a particular test works isn't really the way to go. In
>> this case, we are looking at mmap_min_addr being set at 0x10000, but
>> which may be set to 0x20000 someplace else.
>>
>> Jeff
>>
>
> Hi Jeff,
>
> Here is the revised version - I cheered Dijkstra up by getting rid of that goto.
>
> -- Tom
>

Oh No! I forgot to get rid of those nasty includes.... Take 2....

-- Tom

--

From: Tom Spink <tspink [at] gmail>
Date: Wed, 21 May 2008 00:53:54 +0100
Subject: [PATCH] Locate the bottom of the address space

This patch makes os_get_task_size locate the bottom of the address space,
as well as the top. This is for systems which put a lower limit on mmap
addresses. It works by manually scanning pages from zero onwards until a
valid page is found.

Because the bottom of the address space may not be zero, it's not sufficient
to assume the top of the address space is the size of the address space. The
size is the difference between the top address and bottom address.

Signed-off-by: Tom Spink <tspink [at] gmail>
---
arch/um/os-Linux/sys-i386/task_size.c | 28 ++++++++++++++++++++--------
1 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/arch/um/os-Linux/sys-i386/task_size.c
b/arch/um/os-Linux/sys-i386/task_size.c
index ccb49b0..13db95a 100644
--- a/arch/um/os-Linux/sys-i386/task_size.c
+++ b/arch/um/os-Linux/sys-i386/task_size.c
@@ -76,9 +76,9 @@ unsigned long os_get_task_size(void)
* hosts, but shouldn't hurt otherwise.
*/
unsigned long top = 0xffffd000 >> UM_KERN_PAGE_SHIFT;
- unsigned long test;
+ unsigned long test, original;

- printf("Locating the top of the address space ... ");
+ printf("Locating the bottom of the address space ... ");
fflush(stdout);

/*
@@ -93,13 +93,26 @@ unsigned long os_get_task_size(void)
exit(1);
}

- if (!page_ok(bottom)) {
- fprintf(stderr, "Address 0x%x no good?\n",
- bottom << UM_KERN_PAGE_SHIFT);
+ /* Manually scan the address space, bottom-up, until we find
+ * the first valid page (or run out of them).
+ */
+ for (bottom = 0; bottom < top; bottom++) {
+ if (page_ok(bottom))
+ break;
+ }
+
+ /* If we've got this far, we ran out of pages. */
+ if (bottom == top) {
+ fprintf(stderr, "Unable to determine bottom of address space.\n");
exit(1);
}
+
+ printf("0x%x\n", bottom << UM_KERN_PAGE_SHIFT);
+ printf("Locating the top of the address space ... ");
+ fflush(stdout);

/* This could happen with a 4G/4G split */
+ original = bottom;
if (page_ok(top))
goto out;

@@ -117,8 +130,7 @@ out:
perror("os_get_task_size");
exit(1);
}
- top <<= UM_KERN_PAGE_SHIFT;
- printf("0x%x\n", top);
+ printf("0x%x\n", top << UM_KERN_PAGE_SHIFT);

- return top;
+ return (top - original) << UM_KERN_PAGE_SHIFT;
}
--
1.5.4.3
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


jdike at addtoit

May 21, 2008, 10:58 AM

Post #21 of 22 (7713 views)
Permalink
Re: UML fails to locate address space [In reply to]

On Wed, May 21, 2008 at 01:04:21PM +0100, Tom Spink wrote:
> Oh No! I forgot to get rid of those nasty includes.... Take 2....

This is actually supposed to return the address space top, not the
size, so I changed the name and return value accordingly.

Other than that, this is fine. The final result is below...

Jeff

--
Work email - jdike at linux dot intel dot com

From: Tom Spink <tspink [at] gmail>

This patch makes os_get_task_size locate the bottom of the address space,
as well as the top. This is for systems which put a lower limit on mmap
addresses. It works by manually scanning pages from zero onwards until a
valid page is found.

Because the bottom of the address space may not be zero, it's not sufficient
to assume the top of the address space is the size of the address space. The
size is the difference between the top address and bottom address.

[. jdike [at] addtoit - Changed the name to reflect that this function
is supposed to return the top of the process address space, not its
size and changed the return value to reflect that. Also some minor
formatting changes ]

Signed-off-by: Tom Spink <tspink [at] gmail>
Signed-off-by: Jeff Dike <jdike [at] linux>
---
arch/um/include/os.h | 2 -
arch/um/kernel/um_arch.c | 2 -
arch/um/os-Linux/sys-i386/task_size.c | 35 +++++++++++++++++++++-----------
arch/um/os-Linux/sys-x86_64/task_size.c | 2 -
4 files changed, 27 insertions(+), 14 deletions(-)

Index: linux-2.6.22/arch/um/include/os.h
===================================================================
--- linux-2.6.22.orig/arch/um/include/os.h 2008-05-21 13:48:23.000000000 -0400
+++ linux-2.6.22/arch/um/include/os.h 2008-05-21 13:48:47.000000000 -0400
@@ -299,6 +299,6 @@ extern int os_arch_prctl(int pid, int co
extern int get_pty(void);

/* sys-$ARCH/task_size.c */
-extern unsigned long os_get_task_size(void);
+extern unsigned long os_get_top_address(void);

#endif
Index: linux-2.6.22/arch/um/kernel/um_arch.c
===================================================================
--- linux-2.6.22.orig/arch/um/kernel/um_arch.c 2008-04-24 13:22:09.000000000 -0400
+++ linux-2.6.22/arch/um/kernel/um_arch.c 2008-05-21 13:46:56.000000000 -0400
@@ -274,7 +274,7 @@ int __init linux_main(int argc, char **a
if (have_root == 0)
add_arg(DEFAULT_COMMAND_LINE);

- host_task_size = os_get_task_size();
+ host_task_size = os_get_top_address();
/*
* TASK_SIZE needs to be PGDIR_SIZE aligned or else exit_mmap craps
* out
Index: linux-2.6.22/arch/um/os-Linux/sys-i386/task_size.c
===================================================================
--- linux-2.6.22.orig/arch/um/os-Linux/sys-i386/task_size.c 2008-04-23 13:07:23.000000000 -0400
+++ linux-2.6.22/arch/um/os-Linux/sys-i386/task_size.c 2008-05-21 13:54:47.000000000 -0400
@@ -63,7 +63,7 @@ static int page_ok(unsigned long page)
return ok;
}

-unsigned long os_get_task_size(void)
+unsigned long os_get_top_address(void)
{
struct sigaction sa, old;
unsigned long bottom = 0;
@@ -76,9 +76,9 @@ unsigned long os_get_task_size(void)
* hosts, but shouldn't hurt otherwise.
*/
unsigned long top = 0xffffd000 >> UM_KERN_PAGE_SHIFT;
- unsigned long test;
+ unsigned long test, original;

- printf("Locating the top of the address space ... ");
+ printf("Locating the bottom of the address space ... ");
fflush(stdout);

/*
@@ -89,16 +89,30 @@ unsigned long os_get_task_size(void)
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_NODEFER;
if (sigaction(SIGSEGV, &sa, &old)) {
- perror("os_get_task_size");
+ perror("os_get_top_address");
exit(1);
}

- if (!page_ok(bottom)) {
- fprintf(stderr, "Address 0x%x no good?\n",
- bottom << UM_KERN_PAGE_SHIFT);
+ /* Manually scan the address space, bottom-up, until we find
+ * the first valid page (or run out of them).
+ */
+ for (bottom = 0; bottom < top; bottom++) {
+ if (page_ok(bottom))
+ break;
+ }
+
+ /* If we've got this far, we ran out of pages. */
+ if (bottom == top) {
+ fprintf(stderr, "Unable to determine bottom of address "
+ "space.\n");
exit(1);
}

+ printf("0x%x\n", bottom << UM_KERN_PAGE_SHIFT);
+ printf("Locating the top of the address space ... ");
+ fflush(stdout);
+
+ original = bottom;
/* This could happen with a 4G/4G split */
if (page_ok(top))
goto out;
@@ -114,11 +128,10 @@ unsigned long os_get_task_size(void)
out:
/* Restore the old SIGSEGV handling */
if (sigaction(SIGSEGV, &old, NULL)) {
- perror("os_get_task_size");
+ perror("os_get_top_address");
exit(1);
}
- top <<= UM_KERN_PAGE_SHIFT;
- printf("0x%x\n", top);
+ printf("0x%x\n", top << UM_KERN_PAGE_SHIFT);

- return top;
+ return top << UM_KERN_PAGE_SHIFT;
}
Index: linux-2.6.22/arch/um/os-Linux/sys-x86_64/task_size.c
===================================================================
--- linux-2.6.22.orig/arch/um/os-Linux/sys-x86_64/task_size.c 2008-02-18 11:53:51.000000000 -0500
+++ linux-2.6.22/arch/um/os-Linux/sys-x86_64/task_size.c 2008-05-21 13:49:59.000000000 -0400
@@ -1,4 +1,4 @@
-unsigned long os_get_task_size(unsigned long shift)
+unsigned long os_get_top_address(unsigned long shift)
{
/* The old value of CONFIG_TOP_ADDR */
return 0x7fc0000000;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


tspink at gmail

May 21, 2008, 12:01 PM

Post #22 of 22 (7717 views)
Permalink
Re: UML fails to locate address space [In reply to]

2008/5/21 Jeff Dike <jdike [at] addtoit>:
> On Wed, May 21, 2008 at 01:04:21PM +0100, Tom Spink wrote:
>> Oh No! I forgot to get rid of those nasty includes.... Take 2....
>
> This is actually supposed to return the address space top, not the
> size, so I changed the name and return value accordingly.
>
> Other than that, this is fine. The final result is below...
>
> Jeff
>

Awesome! Thanks for your help, Jeff.

--
Tom Spink
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

Linux kernel RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.