From: Vibhav Pant vibhavp@gmail.com
--- dlls/ntdll/unix/sync.c | 13 ++++++++++++ dlls/ntdll/unix/virtual.c | 42 +++++++++++++++++++++++++++++++++++---- 2 files changed, 51 insertions(+), 4 deletions(-)
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c index 4b2d7c1ccbc..81931931d9c 100644 --- a/dlls/ntdll/unix/sync.c +++ b/dlls/ntdll/unix/sync.c @@ -2058,6 +2058,19 @@ NTSTATUS WINAPI NtCreateSection( HANDLE *handle, ACCESS_MASK access, const OBJEC
*handle = 0;
+ if (sec_flags & SEC_LARGE_PAGES) + { + SIZE_T min_size = user_shared_data->LargePageMinimum; + if (file != NULL || size == NULL) + { + return STATUS_INVALID_PARAMETER; + } + + if (min_size == 0 || size->QuadPart % min_size != 0) + { + return STATUS_INVALID_PARAMETER; + } + } switch (protect & 0xff) { case PAGE_READONLY: diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index 4b23d9954df..93d576b79ac 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -2082,10 +2082,17 @@ static NTSTATUS map_file_into_view( struct file_view *view, int fd, size_t start prot |= PROT_EXEC; }
+#ifdef MAP_LOCKED + if (vprot & SEC_LARGE_PAGES) + { + flags |= MAP_LOCKED; + } +#endif /* only try mmap if media is not removable (or if we require write access) */ if (!removable || (flags & MAP_SHARED)) { - if (mmap( (char *)view->base + start, size, prot, flags, fd, offset ) != MAP_FAILED) + ptr = mmap( (char *)view->base + start, size, prot, flags, fd, offset ); + if (ptr != MAP_FAILED) goto done;
switch (errno) @@ -2118,8 +2125,14 @@ static NTSTATUS map_file_into_view( struct file_view *view, int fd, size_t start }
/* Reserve the memory with an anonymous mmap */ - ptr = anon_mmap_fixed( (char *)view->base + start, size, PROT_READ | PROT_WRITE, 0 ); - if (ptr == MAP_FAILED) + ptr = anon_mmap_fixed( (char *)view->base + start, size, PROT_READ | PROT_WRITE, +#ifdef MAP_LOCKED + vprot & SEC_LARGE_PAGES ? MAP_LOCKED : 0 +#else + 0 +#endif + ); + if ( ptr == MAP_FAILED ) { ERR( "anon mmap error %s, range %p-%p\n", strerror(errno), (char *)view->base + start, (char *)view->base + start + size ); @@ -2130,6 +2143,16 @@ static NTSTATUS map_file_into_view( struct file_view *view, int fd, size_t start if (prot != (PROT_READ|PROT_WRITE)) mprotect( ptr, size, prot ); /* Set the right protection */ done: set_page_vprot( (char *)view->base + start, size, vprot ); + if ( vprot & SEC_LARGE_PAGES && mlock( ptr, size ) != 0 ) + { + switch (errno) + { + case EPERM: + return STATUS_ACCESS_DENIED; + default: + return STATUS_NO_MEMORY; + } + } return STATUS_SUCCESS; }
@@ -3179,6 +3202,16 @@ static unsigned int virtual_map_section( HANDLE handle, PVOID *addr_ptr, ULONG_P base = *addr_ptr; offset.QuadPart = offset_ptr ? offset_ptr->QuadPart : 0; if (offset.QuadPart >= full_size) return STATUS_INVALID_PARAMETER; + + if (sec_flags & SEC_LARGE_PAGES) + { + if (!*size_ptr || user_shared_data->LargePageMinimum == 0 || + *size_ptr % user_shared_data->LargePageMinimum != 0) + return STATUS_INVALID_PARAMETER; + if (base && ((UINT_PTR)base % user_shared_data->LargePageMinimum != 0)) + return STATUS_INVALID_PARAMETER; + } + if (*size_ptr) { size = *size_ptr; @@ -3204,7 +3237,8 @@ static unsigned int virtual_map_section( HANDLE handle, PVOID *addr_ptr, ULONG_P
server_enter_uninterrupted_section( &virtual_mutex, &sigset );
- res = map_view( &view, base, size, alloc_type, vprot, limit_low, limit_high, 0 ); + res = map_view( &view, base, size, alloc_type, vprot, limit_low, limit_high, + sec_flags & SEC_LARGE_PAGES ? ( user_shared_data->LargePageMinimum - 1 ) : 0 ); if (res) goto done;
TRACE( "handle=%p size=%lx offset=%s\n", handle, size, wine_dbgstr_longlong(offset.QuadPart) );