This MR adds support for creating file mapping objects backed by large pages on Linux, by making the following changes:
## wineserver
* On Linux, `create_temp_file` will first attempt to use memfds as the backing fd. If it fails, it'll return to the current codepath, creating a temporary file in either the server or config directory.
* The created memfd will be sealed against writes, if the caller requesting the appropriate page protection flags.
* This removes the requirement that FDs be only created on filesystems/directories that aren't `noexec`.
* In the server method `create_mapping` , if large pages have been requested by the caller, hold that the calling thread's token holds `SeLockMemoryPrivilege` .
* Additionally, add `SeLockMemoryPrivilege` to the list of privileges enabled for the Administrator.
## `ntdll`
* Add `virtual_get_min_large_page_size` and its exported wrapper `wine_unix_get_min_large_page_size`.
* On Linux, the minimum page size is determined by going through `/sys/kernel/mm/hugepages`. If hugepage support was not detected, `STATUS_NOT_SUPPORTED` is returned instead. On other platforms, the older hard-coded value of 2\*1024\*1024 is returned instead.
* `NtCreateSection` will validate certain parameters if large pages are requested. Specifically, it will return STATUS_INVALID_PARAMETER if the requested mapping is not anonymous/unnamed, or the size is not a multiple of the minimum supported page size.
## `kernelbase`
* `GetLargePageMinimum` will use `wine_unix_get_min_large_page_size`.
## `kernel32/tests`
* Add new test test_large_page_file_mapping, which validates privilege enforcements and parameter validation while creating large pages backed file mapping obejcts. The tests are skipped if `GetLargePageMinimum` returns 0.
--
v13: kernel32: Add tests for large page mapping support.
ntdll: Validate parameters to NtCreateSection if large pages are requested.
server: Use memfd to back anonymous mappings on Linux.
kernelbase: Implement GetLargePageMinimum by returning the value of LargePageMinimum in _KUSER_SHARED_DATA.
server: Set LargePageMinimum in _KUSER_SHARED_DATA on Linux.
server: Require SeLockMemoryPrivilege to create large page mappings.
https://gitlab.winehq.org/wine/wine/-/merge_requests/5769
On Wed Jun 5 21:57:54 2024 +0000, Jacek Caban wrote:
> > But it was still ambiguous as I explained.
> If you mean the "zoom" example, I'd appreciate for some details. That
> one should already use `IHTMLCSSStyleDeclaration` interface, not
> `IHTMLStyle*` ones.
> > But since we pass the mshtml-internal tid (called iid in args) which
> is opaque to jscript, I don't really see why this is better than passing
> the `func_info_t` directly? Well IMO passing the pair is already more
> complex and requires more lookups, more args, etc, but that's just me.
> `get_dispex_from_this` is one thing, going through the interface take
> cares of that. For that part, you could just replace the argument in my branch.
> But we should also somehow make sure that the hook is safe to call. By
> binding function info to the exact object instance, we guarantee that
> it's safe to call `impl_from_*` from hooks. If you accept any function
> info as an input, you need to somehow validate that it's safe to call
> it. Something like moving QI earlier would only partially mitigate that.
> I'm open to other approaches, but unless I'm missing something, there is
> no such validation in your current branch.
> It seems to me that things like 1ffeaa446613 come from some variation of
> solution to that problem. Maybe it was needed in earlier version, but it
> shouldn't be needed with "this" being resolved on jscript side. It's no
> longer arbitrary when it's used for a `IJSDispatchHost` call. I would
> suggest to try removing it.
Yeah, I forgot to validate it in my branch. In BuiltinFuncCall,
something like this would work:
```c
if(func->hook) {
hres =
IWineJSDispatchHost_QueryInterface(&This->IWineJSDispatchHost_iface,
tid_ids[func->tid], (void**)&unk);
if(FAILED(hres))
return hres;
IUnknown_Release(unk);
hres = func->hook(This, setter ? DISPATCH_PROPERTYPUT :
DISPATCH_PROPERTYGET, dp, ret, ei, caller);
if(hres != S_FALSE)
return hres;
}
```
Alternatively, we can pass around `func_info_t` instead of dispid and
tid, but still look it up like in your branch. We can obtain the dispid
and tid from `func_info_t` so that's all that's needed. I'm not sure if
that's an improvement over my approach, but I think it's definitely a
simplification over yours. What do you think?
BTW for `zoom`, the assignment should fail as it does on native (as the
test does), are you sure it's supposed to be using
`IHTMLCSSStyleDeclaration` which doesn't fail? I mean the test will
simply start failing if it picks `IHTMLCSSStyleDeclaration` because the
assignment does not throw exception anymore (when it should be!).
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5444#note_72586
This MR adds support for creating file mapping objects backed by large pages on Linux, by making the following changes:
## wineserver
* On Linux, `create_temp_file` will first attempt to use memfds as the backing fd. If it fails, it'll return to the current codepath, creating a temporary file in either the server or config directory.
* The created memfd will be sealed against writes, if the caller requesting the appropriate page protection flags.
* This removes the requirement that FDs be only created on filesystems/directories that aren't `noexec`.
* In the server method `create_mapping` , if large pages have been requested by the caller, hold that the calling thread's token holds `SeLockMemoryPrivilege` .
* Additionally, add `SeLockMemoryPrivilege` to the list of privileges enabled for the Administrator.
## `ntdll`
* Add `virtual_get_min_large_page_size` and its exported wrapper `wine_unix_get_min_large_page_size`.
* On Linux, the minimum page size is determined by going through `/sys/kernel/mm/hugepages`. If hugepage support was not detected, `STATUS_NOT_SUPPORTED` is returned instead. On other platforms, the older hard-coded value of 2\*1024\*1024 is returned instead.
* `NtCreateSection` will validate certain parameters if large pages are requested. Specifically, it will return STATUS_INVALID_PARAMETER if the requested mapping is not anonymous/unnamed, or the size is not a multiple of the minimum supported page size.
## `kernelbase`
* `GetLargePageMinimum` will use `wine_unix_get_min_large_page_size`.
## `kernel32/tests`
* Add new test test_large_page_file_mapping, which validates privilege enforcements and parameter validation while creating large pages backed file mapping obejcts. The tests are skipped if `GetLargePageMinimum` returns 0.
--
v12: kernel32: Add tests for large page mapping support.
ntdll: Validate parameters to NtCreateSection if large pages are requested.
server: Use memfd to back anonymous mappings on Linux.
kernelbase: Implement GetLargePageMinimum by returning the value of LargePageMinimum in _KUSER_SHARED_DATA.
server: Set LargePageMinimum in _KUSER_SHARED_DATA on Linux.
server: Require SeLockMemoryPrivilege to create large page mappings.
https://gitlab.winehq.org/wine/wine/-/merge_requests/5769
I have a .Net application that during handling of WM_NCPAINT for one of its windows
genarates exception "Arithmetic operation resulted in an overflow.". This happens
only in a 64-bit prefix and only for WPARAM that contains an HRGN handle with value
over than 0x7fffffff.
The application does the following:
public static IntPtr GetNativeDC(Message m, IntPtr handle)
{
if (m.Msg != 0x85) // WM_NCPAINT
{
return NUser32.GetWindowDC(handle);
}
int num = 0x200013; // DCX_VALIDATE | DCX_CLIPSIBLINGS | DCX_CACHE | DCX_WINDOW
IntPtr intPtr = IntPtr.Zero;
IntPtr wParam = m.WParam;
if (wParam.ToInt32() != 1)
{
num |= 0x80; // DCX_INTERSECTRGN
intPtr = CreateRectRgn(0, 0, 1, 1);
CombineRgn(intPtr, wParam, IntPtr.Zero, 5); // RGN_COPY
}
return NUser32.GetDCEx(handle, intPtr, num);
}
The exception is generated by wParam.ToInt32(). MSDN description for ToInt32()
https://learn.microsoft.com/en-us/dotnet/api/system.intptr.toint32?view=net…
states
Exceptions
OverflowException
In a 64-bit process, the value of this instance is too large or too small
to represent as a 32-bit signed integer.
MSDN also has a reference to ToInt32() source:
https://github.com/dotnet/runtime/blob/5535e31a712343a63f5d7d796cd874e563e5…
public int ToInt32()
{
#if TARGET_64BIT
return checked((int)_value);
#else
return (int)_value;
#endif
}
It's not clear why a sign extension may lead to an overflow exception.
This patch fixes the problem, and provides a test case that confirms that
entry.Generation field of a GDI32 object is limited by 127 on a 64-bit
platform, while 32-bit Windows doesn't have such a limitation.
--
v2: win32u: Limit GDI object generation by 128.
https://gitlab.winehq.org/wine/wine/-/merge_requests/5777
[test_WaitForInputIdle.tar.bz2](/uploads/a20c5b119741cd7b0b4813488854a992/test_WaitForInputIdle.tar.bz2)
Attached test replicates the problem. Basically the application does
process = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());
ret = WaitForInputIdle(process, 0x7fffffff);
assert(ret == 0);
With current wine.git WaitForInputIdle() returns WAIT_FAILED because the server call
get_process_idle_event() refuses to return idle_event for the current process. If that
limitation is removed then wineserver crashes, and other parts of the patch fix the crash.
--
v2: server: Remove limitation for waiting on idle_event of the current process.
https://gitlab.winehq.org/wine/wine/-/merge_requests/5789
Instead of accessing the surface with macdrv_get_surface_display_image.
--
v2: winemac: Remove now unnecessary cocoa window surface pointer.
winemac: Push window surface image updates to the main thread.
winemac: Create window surface CGImageRef on surface flush.
winemac: Create a provider for the surface and a HBITMAP wrapping it.
winemac: Remove unused macdrv_get_surface_display_image copy_data parameter.
https://gitlab.winehq.org/wine/wine/-/merge_requests/5798