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 ccb49b0aff5..be04c1e183b 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)  	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,31 @@ 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,7 +129,7 @@ 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;  |