Commit 0900d919 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Determine the available address space dynamically on ARM64.

parent def5e1a6
......@@ -162,23 +162,18 @@ static void *address_space_start = (void *)0x110000; /* keep DOS area clear */
#else
static void *address_space_start = (void *)0x10000;
#endif
#ifdef __aarch64__
static void *address_space_limit = (void *)0xffffffff0000; /* top of the total available address space */
#elif defined(_WIN64)
static void *address_space_limit = (void *)0x7fffffff0000;
#else
static void *address_space_limit = (void *)0xc0000000;
#endif
#ifdef _WIN64
static void *address_space_limit = (void *)0x7fffffff0000; /* top of the total available address space */
static void *user_space_limit = (void *)0x7fffffff0000; /* top of the user address space */
static void *working_set_limit = (void *)0x7fffffff0000; /* top of the current working set */
#else
static void *address_space_limit = (void *)0xc0000000;
static void *user_space_limit = (void *)0x7fff0000;
static void *working_set_limit = (void *)0x7fff0000;
#endif
static void *host_addr_space_limit; /* top of the host virtual address space */
static struct file_view *arm64ec_view;
ULONG_PTR user_space_wow_limit = 0;
......@@ -2009,6 +2004,7 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
if (is_beyond_limit( base, size, address_space_limit )) return STATUS_WORKING_SET_LIMIT_RANGE;
if (limit_low && base < (void *)limit_low) return STATUS_CONFLICTING_ADDRESSES;
if (limit_high && is_beyond_limit( base, size, (void *)limit_high )) return STATUS_CONFLICTING_ADDRESSES;
if (is_beyond_limit( base, size, host_addr_space_limit )) return STATUS_CONFLICTING_ADDRESSES;
if ((status = map_fixed_area( base, size, vprot ))) return status;
if (is_beyond_limit( base, size, working_set_limit )) working_set_limit = address_space_limit;
ptr = base;
......@@ -2016,7 +2012,7 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
else
{
void *start = address_space_start;
void *end = user_space_limit;
void *end = min( user_space_limit, host_addr_space_limit );
size_t view_size, unmap_size;
if (!align_mask) align_mask = granularity_mask;
......@@ -2031,7 +2027,7 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
goto done;
}
if (start > address_space_start || end < address_space_limit || top_down)
if (start > address_space_start || end < host_addr_space_limit || top_down)
{
if (!(ptr = map_free_area( start, end, size, top_down, get_unix_prot(vprot), align_mask )))
return STATUS_NO_MEMORY;
......@@ -2443,6 +2439,33 @@ static NTSTATUS map_pe_header( void *ptr, size_t size, int fd, BOOL *removable )
#ifdef __aarch64__
/***********************************************************************
* get_host_addr_space_limit
*/
static void *get_host_addr_space_limit(void)
{
unsigned int flags = MAP_PRIVATE | MAP_ANON;
UINT_PTR addr = (UINT_PTR)1 << 63;
#ifdef MAP_FIXED_NOREPLACE
flags |= MAP_FIXED_NOREPLACE;
#endif
while (addr >> 32)
{
void *ret = mmap( (void *)addr, page_size, PROT_NONE, flags, -1, 0 );
if (ret != MAP_FAILED)
{
munmap( ret, page_size );
if (ret >= (void *)addr) break;
}
else if (errno == EEXIST) break;
addr >>= 1;
}
return (void *)((addr << 1) - (granularity_mask + 1));
}
/***********************************************************************
* alloc_arm64ec_map
*/
static void alloc_arm64ec_map(void)
......@@ -3223,7 +3246,8 @@ static void *alloc_virtual_heap( SIZE_T size )
void *base = area->base;
void *end = (char *)base + area->size;
if (is_beyond_limit( base, area->size, address_space_limit )) address_space_limit = end;
if (is_beyond_limit( base, area->size, address_space_limit ))
address_space_limit = host_addr_space_limit = end;
if (is_win64 && base < (void *)0x80000000) break;
if (preload_reserve_end >= end)
{
......@@ -3261,6 +3285,13 @@ void virtual_init(void)
pthread_mutex_init( &virtual_mutex, &attr );
pthread_mutexattr_destroy( &attr );
#ifdef __aarch64__
host_addr_space_limit = get_host_addr_space_limit();
TRACE( "host addr space limit: %p\n", host_addr_space_limit );
#else
host_addr_space_limit = address_space_limit;
#endif
if (preload_info && *preload_info)
for (i = 0; (*preload_info)[i].size; i++)
mmap_add_reserved_area( (*preload_info)[i].addr, (*preload_info)[i].size );
......@@ -3282,7 +3313,7 @@ void virtual_init(void)
/* try to find space in a reserved area for the views and pages protection table */
#ifdef _WIN64
pages_vprot_size = ((size_t)address_space_limit >> page_shift >> pages_vprot_shift) + 1;
pages_vprot_size = ((size_t)host_addr_space_limit >> page_shift >> pages_vprot_shift) + 1;
size = 2 * view_block_size + pages_vprot_size * sizeof(*pages_vprot);
#else
size = 2 * view_block_size + (1U << (32 - page_shift));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment