diff options
Diffstat (limited to 'arch/um/os-Linux/sys-i386/task_size.c')
-rw-r--r-- | arch/um/os-Linux/sys-i386/task_size.c | 31 |
1 files changed, 23 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 ccb49b0aff59..be04c1e183bf 100644 --- a/arch/um/os-Linux/sys-i386/task_size.c +++ b/arch/um/os-Linux/sys-i386/task_size.c | |||
@@ -63,7 +63,7 @@ static int page_ok(unsigned long page) | |||
63 | return ok; | 63 | return ok; |
64 | } | 64 | } |
65 | 65 | ||
66 | unsigned long os_get_task_size(void) | 66 | unsigned long os_get_top_address(void) |
67 | { | 67 | { |
68 | struct sigaction sa, old; | 68 | struct sigaction sa, old; |
69 | unsigned long bottom = 0; | 69 | unsigned long bottom = 0; |
@@ -76,9 +76,9 @@ unsigned long os_get_task_size(void) | |||
76 | * hosts, but shouldn't hurt otherwise. | 76 | * hosts, but shouldn't hurt otherwise. |
77 | */ | 77 | */ |
78 | unsigned long top = 0xffffd000 >> UM_KERN_PAGE_SHIFT; | 78 | unsigned long top = 0xffffd000 >> UM_KERN_PAGE_SHIFT; |
79 | unsigned long test; | 79 | unsigned long test, original; |
80 | 80 | ||
81 | printf("Locating the top of the address space ... "); | 81 | printf("Locating the bottom of the address space ... "); |
82 | fflush(stdout); | 82 | fflush(stdout); |
83 | 83 | ||
84 | /* | 84 | /* |
@@ -89,16 +89,31 @@ unsigned long os_get_task_size(void) | |||
89 | sigemptyset(&sa.sa_mask); | 89 | sigemptyset(&sa.sa_mask); |
90 | sa.sa_flags = SA_NODEFER; | 90 | sa.sa_flags = SA_NODEFER; |
91 | if (sigaction(SIGSEGV, &sa, &old)) { | 91 | if (sigaction(SIGSEGV, &sa, &old)) { |
92 | perror("os_get_task_size"); | 92 | perror("os_get_top_address"); |
93 | exit(1); | 93 | exit(1); |
94 | } | 94 | } |
95 | 95 | ||
96 | if (!page_ok(bottom)) { | 96 | /* Manually scan the address space, bottom-up, until we find |
97 | fprintf(stderr, "Address 0x%x no good?\n", | 97 | * the first valid page (or run out of them). |
98 | bottom << UM_KERN_PAGE_SHIFT); | 98 | */ |
99 | for (bottom = 0; bottom < top; bottom++) { | ||
100 | if (page_ok(bottom)) | ||
101 | break; | ||
102 | } | ||
103 | |||
104 | /* If we've got this far, we ran out of pages. */ | ||
105 | if (bottom == top) { | ||
106 | fprintf(stderr, "Unable to determine bottom of address " | ||
107 | "space.\n"); | ||
99 | exit(1); | 108 | exit(1); |
100 | } | 109 | } |
101 | 110 | ||
111 | printf("0x%x\n", bottom << UM_KERN_PAGE_SHIFT); | ||
112 | printf("Locating the top of the address space ... "); | ||
113 | fflush(stdout); | ||
114 | |||
115 | original = bottom; | ||
116 | |||
102 | /* This could happen with a 4G/4G split */ | 117 | /* This could happen with a 4G/4G split */ |
103 | if (page_ok(top)) | 118 | if (page_ok(top)) |
104 | goto out; | 119 | goto out; |
@@ -114,7 +129,7 @@ unsigned long os_get_task_size(void) | |||
114 | out: | 129 | out: |
115 | /* Restore the old SIGSEGV handling */ | 130 | /* Restore the old SIGSEGV handling */ |
116 | if (sigaction(SIGSEGV, &old, NULL)) { | 131 | if (sigaction(SIGSEGV, &old, NULL)) { |
117 | perror("os_get_task_size"); | 132 | perror("os_get_top_address"); |
118 | exit(1); | 133 | exit(1); |
119 | } | 134 | } |
120 | top <<= UM_KERN_PAGE_SHIFT; | 135 | top <<= UM_KERN_PAGE_SHIFT; |