On 25.04.22 04:18, Derek Lesho wrote:
Hi All,
In the wake of the new WOW64 implementation (recent explanation [1]), there has been discussion in informal channels about how to we are going to handle pointers to mapped graphics resource memory which we receive from the graphics API, as the possibility exists that it will fall outside of the 32-bit address space.
Over time, a few creative solutions have been proposed and discussed, with a common theme being that we need changes in either the kernel or the graphics drivers to do this properly. As we already know the requirements for a solution to this problem, I think it would be responsible to hash this out now and then work with the relevant project maintainers earlier as to avoid blocking work on the wine side too long and to possibly allow more users to test the new path earlier.
The solutions which I've seen laid out so far:
- Use the mremap(2) interface, allowing us to duplicate the mapping we
receive into the 32-bit address space. This solution would match what is already done for Crossover Mac's 32on64 support using Mac's mach_vm_remap functionality [2]. However, right now it is not possible to use the MREMAP_DONTUNMAP flag with mappings that aren't private and anonymous, which rules out there use on mapped FDs from libdrm. Due to this, a kernel change would be necessary.
Pro: A uniform solution across all APIs, which could help in the future with any unforeseen need to access host-allocated memory in 32-bit windows code.
Cons: Requires a kernel change, which of all the options may take the longest to get up-streamed and in the hands of users.
If we can be sure this works for every possible situation this seems like the best idea that came up. Maybe even the only feasible outside of reserving all non 32bit address space like zf suggested.
If we can't be sure then this isn't much better than the third idea, we shouldn't make assumptions about what drivers are doing.
- Work with Khronos to introduce extensions into the relevant APIs
enabling us to tell drivers where in the address space we want resources mapped.
Pro: Wouldn't require going around the backs of the driver, resulting in a more hardened solution. (Out there, but what if a creative driver returns a mapping without read or write permission and handles accesses through a page fault handler?)
I'm not sure if relying on page faults is something drivers can even do, I don't think we should worry much about this hypothetical case.
Cons: The extension would have to be implemented by each individual vendor for every relevant API. This would implicitly drop support for those with cards whose graphics drivers are no longer being updated.
Another downside of this approach is that I'm not sure if you can even get a new cross vendor extension for OpenGL these days. And what about other APIs like OpenCL or cuda?
Also, not sure if going through Khronos is really faster than the kernel idea. And how many Khronos vendors even care about an extension that's only useful for Wine? It's also unclear how much work in the drivers this requires, maybe those with a custom mapping mechanism might even need kernel changes.
- Hook the driver's mmap call when we invoke memory mappings function,
overriding the address to something in the 32-bit address space.
Pro: Unlike the other solutions, this wouldn't require any changes to other projects, and shares the advantage of the first solution.
Cons: Susceptible to breakage if the driver uses their own mapping mechanism separate from mmap. (Custom IOCTL, CPU driver returning something from the heap)
I don't like this idea, we shouldn't guess what the drivers are doing. This will only cause issues in the future if driver behavior changes.
1: https://www.winehq.org/pipermail/wine-devel/2022-April/213677.html
2: https://www.codeweavers.com/crossover/source - see function `remap_memory` in `wine/dlls/winemac.drv/opengl.c`