-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
remove rawinput stuff until it's finished, haven't had time to work on it build with LLVM polly (placebo) more changes to hopefully improve stability performance, including build fixes for clang testing keyboard input regression revert Revert-win32u-Simplify-the-logic-for-driver-messages.patch some other things...
- Loading branch information
Showing
116 changed files
with
3,181 additions
and
6,268 deletions.
There are no files selected for viewing
48 changes: 0 additions & 48 deletions
48
...hutdown/0001-mfmediaengine-Be-a-bit-more-conservative-with-locks-in-engine-Shutdown.patch
This file was deleted.
Oops, something went wrong.
203 changes: 203 additions & 0 deletions
203
...ate-vprot-entries-until-commit/0001-ntdll-Don-t-allocate-vprot-entries-until-commit.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
From 9b4099ed8b9ac0670396bdc50dbfa6f5bb435784 Mon Sep 17 00:00:00 2001 | ||
From: Evan Tang <[email protected]> | ||
Date: Mon, 30 Oct 2023 11:40:41 -0500 | ||
Subject: [PATCH] ntdll: Don't allocate vprot entries until commit. | ||
|
||
Reservations only consume address space, which can be much larger than | ||
the amount of ram in the system, so allocating even one byte per page | ||
can result in huge amounts of ram used. | ||
--- | ||
dlls/ntdll/unix/virtual.c | 87 ++++++++++++++++++++++++++++++++------- | ||
1 file changed, 73 insertions(+), 14 deletions(-) | ||
|
||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c | ||
index b2e1be9f53f..2e2d5ce2345 100644 | ||
--- a/dlls/ntdll/unix/virtual.c | ||
+++ b/dlls/ntdll/unix/virtual.c | ||
@@ -908,8 +908,7 @@ static BYTE get_page_vprot( const void *addr ) | ||
* Return the size of the region with equal masked vprot byte. | ||
* Also return the protections for the first page. | ||
* The function assumes that base and size are page aligned, | ||
- * base + size does not wrap around and the range is within view so | ||
- * vprot bytes are allocated for the range. */ | ||
+ * base + size does not wrap around, and the range is within view. */ | ||
static SIZE_T get_vprot_range_size( char *base, SIZE_T size, BYTE mask, BYTE *vprot ) | ||
{ | ||
static const UINT_PTR word_from_byte = (UINT_PTR)0x101010101010101; | ||
@@ -927,11 +926,24 @@ static SIZE_T get_vprot_range_size( char *base, SIZE_T size, BYTE mask, BYTE *vp | ||
if (aligned_start_idx > end_idx) aligned_start_idx = end_idx; | ||
|
||
#ifdef _WIN64 | ||
- vprot_ptr = pages_vprot[curr_idx >> pages_vprot_shift] + (curr_idx & pages_vprot_mask); | ||
+ if (pages_vprot[curr_idx >> pages_vprot_shift]) | ||
+ { | ||
+ vprot_ptr = pages_vprot[curr_idx >> pages_vprot_shift] + (curr_idx & pages_vprot_mask); | ||
+ *vprot = *vprot_ptr; | ||
+ } | ||
+ else | ||
+ { | ||
+ *vprot = 0; | ||
+ curr_idx = (curr_idx + pages_vprot_mask + 1) & ~pages_vprot_mask; | ||
+ if (curr_idx > end_idx) | ||
+ return size; | ||
+ vprot_ptr = pages_vprot[curr_idx >> pages_vprot_shift]; | ||
+ assert(curr_idx >= aligned_start_idx); | ||
+ } | ||
#else | ||
vprot_ptr = pages_vprot + curr_idx; | ||
-#endif | ||
*vprot = *vprot_ptr; | ||
+#endif | ||
|
||
/* Page count page table is at least the multiples of sizeof(UINT_PTR) | ||
* so we don't have to worry about crossing the boundary on unaligned idx values. */ | ||
@@ -944,7 +956,17 @@ static SIZE_T get_vprot_range_size( char *base, SIZE_T size, BYTE mask, BYTE *vp | ||
for (; curr_idx < end_idx; curr_idx += sizeof(UINT_PTR), vprot_ptr += sizeof(UINT_PTR)) | ||
{ | ||
#ifdef _WIN64 | ||
- if (!(curr_idx & pages_vprot_mask)) vprot_ptr = pages_vprot[curr_idx >> pages_vprot_shift]; | ||
+ if (!(curr_idx & pages_vprot_mask)) | ||
+ { | ||
+ while (!(vprot_ptr = pages_vprot[curr_idx >> pages_vprot_shift])) | ||
+ { | ||
+ if (!(vprot_word & mask_word)) | ||
+ return (curr_idx - start_idx) << page_shift; | ||
+ curr_idx += pages_vprot_mask + 1; | ||
+ if (curr_idx >= end_idx) | ||
+ return size; | ||
+ } | ||
+ } | ||
#endif | ||
if ((vprot_word ^ *(UINT_PTR *)vprot_ptr) & mask_word) | ||
{ | ||
@@ -956,6 +978,21 @@ static SIZE_T get_vprot_range_size( char *base, SIZE_T size, BYTE mask, BYTE *vp | ||
return size; | ||
} | ||
|
||
+#ifdef _WIN64 | ||
+/*********************************************************************** | ||
+ * set_page_vprot_internal | ||
+ * | ||
+ * Helper function for set_page_vprot | ||
+ */ | ||
+static void set_pages_vprot_internal( size_t idx, BYTE vprot, size_t len ) | ||
+{ | ||
+ if (pages_vprot[idx >> pages_vprot_shift]) | ||
+ memset(pages_vprot[idx >> pages_vprot_shift] + (idx & pages_vprot_mask), vprot, len); | ||
+ else if (vprot) | ||
+ ERR("vprot table missing entry at %x!\n", (unsigned int)(idx >> pages_vprot_shift)); | ||
+} | ||
+#endif | ||
+ | ||
/*********************************************************************** | ||
* set_page_vprot | ||
* | ||
@@ -970,10 +1007,10 @@ static void set_page_vprot( const void *addr, size_t size, BYTE vprot ) | ||
while (idx >> pages_vprot_shift != end >> pages_vprot_shift) | ||
{ | ||
size_t dir_size = pages_vprot_mask + 1 - (idx & pages_vprot_mask); | ||
- memset( pages_vprot[idx >> pages_vprot_shift] + (idx & pages_vprot_mask), vprot, dir_size ); | ||
+ set_pages_vprot_internal(idx, vprot, dir_size); | ||
idx += dir_size; | ||
} | ||
- memset( pages_vprot[idx >> pages_vprot_shift] + (idx & pages_vprot_mask), vprot, end - idx ); | ||
+ set_pages_vprot_internal(idx, vprot, end - idx); | ||
#else | ||
memset( pages_vprot + idx, vprot, end - idx ); | ||
#endif | ||
@@ -991,10 +1028,22 @@ static void set_page_vprot_bits( const void *addr, size_t size, BYTE set, BYTE c | ||
size_t end = ((size_t)addr + size + page_mask) >> page_shift; | ||
|
||
#ifdef _WIN64 | ||
- for ( ; idx < end; idx++) | ||
+ while (idx < end) | ||
{ | ||
- BYTE *ptr = pages_vprot[idx >> pages_vprot_shift] + (idx & pages_vprot_mask); | ||
- *ptr = (*ptr & ~clear) | set; | ||
+ size_t next = (idx + pages_vprot_mask + 1) & ~pages_vprot_mask; | ||
+ BYTE *ptr = pages_vprot[idx >> pages_vprot_shift]; | ||
+ if (ptr) | ||
+ { | ||
+ size_t i = idx & pages_vprot_mask; | ||
+ size_t table_end = min(next, end) - (idx & ~pages_vprot_mask); | ||
+ for (; i < table_end; i++) | ||
+ ptr[i] = (ptr[i] & ~clear) | set; | ||
+ } | ||
+ else if (set) | ||
+ { | ||
+ ERR("vprot table missing entry at %x!\n", (unsigned)(idx >> pages_vprot_shift)); | ||
+ } | ||
+ idx = next; | ||
} | ||
#else | ||
for ( ; idx < end; idx++) pages_vprot[idx] = (pages_vprot[idx] & ~clear) | set; | ||
@@ -1482,6 +1531,10 @@ static void register_view( struct file_view *view ) | ||
static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t size, unsigned int vprot ) | ||
{ | ||
struct file_view *view; | ||
+ /* If uncommitted, delay allocation until commit so we don't make vprot tables for reservations, | ||
+ * which can be as large as the address space allows (128TB). | ||
+ * WRITEWATCH doesn't yet support allocating on commit, so make an exception for that. */ | ||
+ BOOL write_vprot = !!(vprot & (VPROT_COMMITTED | VPROT_WRITEWATCH)); | ||
int unix_prot = get_unix_prot( vprot ); | ||
|
||
assert( !((UINT_PTR)base & page_mask) ); | ||
@@ -1499,7 +1552,7 @@ static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t siz | ||
delete_view( view ); | ||
} | ||
|
||
- if (!alloc_pages_vprot( base, size )) return STATUS_NO_MEMORY; | ||
+ if (write_vprot && !alloc_pages_vprot( base, size )) return STATUS_NO_MEMORY; | ||
|
||
/* Create the view structure */ | ||
|
||
@@ -1512,7 +1565,7 @@ static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t siz | ||
view->base = base; | ||
view->size = size; | ||
view->protect = vprot; | ||
- set_page_vprot( base, size, vprot ); | ||
+ set_page_vprot( base, size, write_vprot ? vprot : 0 ); | ||
|
||
register_view( view ); | ||
|
||
@@ -1649,6 +1702,8 @@ static BOOL set_vprot( struct file_view *view, void *base, size_t size, BYTE vpr | ||
} | ||
if (enable_write_exceptions && is_vprot_exec_write( vprot )) vprot |= VPROT_WRITEWATCH; | ||
if (mprotect_exec( base, size, get_unix_prot(vprot) )) return FALSE; | ||
+ /* Reserved pages may not have table entries yet, make those now */ | ||
+ if (vprot && !alloc_pages_vprot( base, size )) return FALSE; | ||
set_page_vprot( base, size, vprot ); | ||
return TRUE; | ||
} | ||
@@ -2176,6 +2231,7 @@ done: | ||
static SIZE_T get_committed_size( struct file_view *view, void *base, size_t max_size, BYTE *vprot, BYTE vprot_mask ) | ||
{ | ||
SIZE_T offset, size; | ||
+ BYTE extra = 0; | ||
|
||
base = ROUND_ADDR( base, page_mask ); | ||
offset = (char *)base - (char *)view->base; | ||
@@ -2196,7 +2252,8 @@ static SIZE_T get_committed_size( struct file_view *view, void *base, size_t max | ||
if (reply->committed) | ||
{ | ||
*vprot |= VPROT_COMMITTED; | ||
- set_page_vprot_bits( base, size, VPROT_COMMITTED, 0 ); | ||
+ extra = VPROT_COMMITTED; | ||
+ vprot_mask &= ~VPROT_COMMITTED; | ||
} | ||
} | ||
} | ||
@@ -2206,7 +2263,9 @@ static SIZE_T get_committed_size( struct file_view *view, void *base, size_t max | ||
} | ||
else size = min( view->size - offset, max_size ); | ||
|
||
- return get_vprot_range_size( base, size, vprot_mask, vprot ); | ||
+ size = get_vprot_range_size( base, size, vprot_mask, vprot ); | ||
+ *vprot |= extra; | ||
+ return size; | ||
} | ||
|
||
|
||
-- | ||
GitLab | ||
|
55 changes: 55 additions & 0 deletions
55
...ries-until-commit/0002-ntdll-tests-Add-test-for-reserving-massive-amounts-of-memory.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
From e9d146653d292d5c05675a1c9d7f53473af3a95c Mon Sep 17 00:00:00 2001 | ||
From: Evan Tang <[email protected]> | ||
Date: Mon, 30 Oct 2023 14:34:03 -0500 | ||
Subject: [PATCH] ntdll/tests: Add test for reserving massive amounts of | ||
memory. | ||
|
||
--- | ||
dlls/ntdll/tests/virtual.c | 26 ++++++++++++++++++++++++++ | ||
1 file changed, 26 insertions(+) | ||
|
||
diff --git a/dlls/ntdll/tests/virtual.c b/dlls/ntdll/tests/virtual.c | ||
index a9dec1b5a8a..808b67b9b27 100644 | ||
--- a/dlls/ntdll/tests/virtual.c | ||
+++ b/dlls/ntdll/tests/virtual.c | ||
@@ -2676,6 +2676,31 @@ static void test_query_image_information(void) | ||
NtClose( file ); | ||
} | ||
|
||
+static void test_massive_memory_reservation(void) | ||
+{ | ||
+ /* Test to make sure large address space reservations don't use more ram than the system has. | ||
+ * Most failures here will be the test getting killed by the OOM killer. */ | ||
+ int i; | ||
+ for (i = 12; i < sizeof(void*) * 8; i++) | ||
+ { | ||
+ void* ptr; | ||
+ BOOL is_ok; | ||
+ SetLastError(0xdeadbeef); | ||
+ ptr = VirtualAlloc(NULL, 1ull << i, MEM_RESERVE, PAGE_NOACCESS); | ||
+ if (i < 40 && sizeof(void*) == 8) /* These should succeed */ | ||
+ is_ok = GetLastError() == 0xdeadbeef; | ||
+ else if (i < 47) /* These might run out of address space */ | ||
+ is_ok = GetLastError() == 0xdeadbeef || GetLastError() == ERROR_NOT_ENOUGH_MEMORY; | ||
+ else | ||
+ is_ok = GetLastError() == ERROR_INVALID_PARAMETER; | ||
+ ok(is_ok, "Unexpected error allocating 1 << %d: %lx.\n", i, GetLastError()); | ||
+ if (ptr) | ||
+ VirtualFree(ptr, 1ull << i, MEM_RELEASE); | ||
+ ptr = malloc(1ull << i); | ||
+ free(ptr); | ||
+ } | ||
+} | ||
+ | ||
START_TEST(virtual) | ||
{ | ||
HMODULE mod; | ||
@@ -2726,4 +2751,5 @@ START_TEST(virtual) | ||
test_query_region_information(); | ||
test_query_image_information(); | ||
test_exec_memory_writes(); | ||
+ test_massive_memory_reservation(); | ||
} | ||
-- | ||
GitLab | ||
|
49 changes: 49 additions & 0 deletions
49
...ike-in-Win10/0001-kernelbase-Add-test-case-for-LoadLibraryEx-when-hFile-is-non-NULL.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
From b7333394d1a0dc94a02f7fd722914dce343f10c6 Mon Sep 17 00:00:00 2001 | ||
From: =?UTF-8?q?D=C4=81vis=20Mos=C4=81ns?= <[email protected]> | ||
Date: Mon, 4 Dec 2023 02:38:19 +0200 | ||
Subject: [PATCH] kernelbase: Add test case for LoadLibraryEx() when hFile is | ||
non-NULL | ||
|
||
When hFile is non-NULL then LoadLibraryEx() should return NULL | ||
with LastError set as ERROR_INVALID_PARAMETER | ||
--- | ||
dlls/kernelbase/tests/file.c | 18 ++++++++++++++++++ | ||
1 file changed, 18 insertions(+) | ||
|
||
diff --git a/dlls/kernelbase/tests/file.c b/dlls/kernelbase/tests/file.c | ||
index 18dff0a32ab..b19360c8998 100644 | ||
--- a/dlls/kernelbase/tests/file.c | ||
+++ b/dlls/kernelbase/tests/file.c | ||
@@ -46,6 +46,23 @@ static void test_ioring_caps(void) | ||
todo_wine ok(hr == S_OK, "got %#lx.\n", hr); | ||
} | ||
|
||
+static void test_load_library_ex_flags(void) | ||
+{ | ||
+ HMODULE hmod; | ||
+ DWORD last_error; | ||
+ | ||
+ SetLastError(0x33); | ||
+ | ||
+ /* Test if LoadLibraryEx can load a dll */ | ||
+ hmod = LoadLibraryExW(L"kernelbase.dll", NULL /* hFile */, LOAD_LIBRARY_SEARCH_SYSTEM32 /* dwFlags */); | ||
+ ok(hmod != NULL, "LoadLibraryEx returned %p with LastError: %#lx.\n", hmod, GetLastError()); | ||
+ | ||
+ /* When hFile is non-NULL LoadLibraryEx should return NULL and set LastError to ERROR_INVALID_PARAMETER */ | ||
+ hmod = LoadLibraryExW(L"kernelbase.dll", (HANDLE)0x000003A0 /* random hFile */, 0 /* dwFlags */); | ||
+ last_error = GetLastError(); | ||
+ ok(hmod == NULL && last_error == ERROR_INVALID_PARAMETER, "LoadLibraryEx returned %p with LastError: %#lx.\n", hmod, last_error); | ||
+} | ||
+ | ||
START_TEST(file) | ||
{ | ||
HMODULE hmod; | ||
@@ -54,4 +71,5 @@ START_TEST(file) | ||
pQueryIoRingCapabilities = (void *)GetProcAddress(hmod, "QueryIoRingCapabilities"); | ||
|
||
test_ioring_caps(); | ||
+ test_load_library_ex_flags(); | ||
} | ||
-- | ||
GitLab | ||
|
37 changes: 37 additions & 0 deletions
37
...to-work-like-in-Win10/0002-kernelbase-LoadLibraryEx-enforce-valid-flag-combinations.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
From db34272389cc9d7b4ef7bdfc6708bc477ab37ff7 Mon Sep 17 00:00:00 2001 | ||
From: =?UTF-8?q?D=C4=81vis=20Mos=C4=81ns?= <[email protected]> | ||
Date: Fri, 1 Dec 2023 04:32:32 +0200 | ||
Subject: [PATCH] kernelbase: LoadLibraryEx enforce valid flag combinations | ||
|
||
--- | ||
dlls/kernelbase/loader.c | 9 ++++++++- | ||
1 file changed, 8 insertions(+), 1 deletion(-) | ||
|
||
diff --git a/dlls/kernelbase/loader.c b/dlls/kernelbase/loader.c | ||
index 59b91596f13..8f40286b880 100644 | ||
--- a/dlls/kernelbase/loader.c | ||
+++ b/dlls/kernelbase/loader.c | ||
@@ -530,12 +530,19 @@ HMODULE WINAPI DECLSPEC_HOTPATCH LoadLibraryExW( LPCWSTR name, HANDLE file, DWOR | ||
{ | ||
UNICODE_STRING str; | ||
HMODULE module; | ||
+ BOOL invalid_parameter; | ||
|
||
- if (!name) | ||
+ invalid_parameter = !name || | ||
+ file || | ||
+ ((flags & LOAD_LIBRARY_AS_DATAFILE) && (flags & LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)) || | ||
+ ((flags & LOAD_LIBRARY_SEARCH_DEFAULT_DIRS) && (flags & LOAD_WITH_ALTERED_SEARCH_PATH)); | ||
+ | ||
+ if (invalid_parameter) | ||
{ | ||
SetLastError( ERROR_INVALID_PARAMETER ); | ||
return 0; | ||
} | ||
+ | ||
RtlInitUnicodeString( &str, name ); | ||
if (str.Buffer[str.Length/sizeof(WCHAR) - 1] != ' ') return load_library( &str, flags ); | ||
|
||
-- | ||
GitLab | ||
|
Oops, something went wrong.