libretro / beetle-psx-libretro

Standalone port/fork of Mednafen PSX to the Libretro API.
GNU General Public License v2.0
309 stars 131 forks source link

Fix computing Lightrec base address for macOS. #908

Closed kozharskyad closed 1 week ago

kozharskyad commented 2 weeks ago

Previously, without this fix, RetroArch randomly (90% chance) crash on game load. The root problem was the specific virtual address mmap handling on Mach kernel specially on arm64 processors (M1/M2/M3) causes mmap to throw an SIGBUS process exception. Sorry for my bad english :)

With this fix game loading stable.

ZachCook commented 2 weeks ago

Looks good, thanks for fixing that.

My original logic was to attempt all possible addresses and handle errors returned from mmap, but clearly my way was not a safe way to go about it.

I would very much appreciate any more details you can give me on the exact error or any documentation you know of so I don't break this in the future (I'm currently working again on a lightrec update that has some changes in the mmap code)

kozharskyad commented 2 weeks ago

Hi, Zach! Your logic is right, but Mach kernel have not stable mechanisms about mmap errors. In POSIX specification we can see, that mmap function must return MMAP_FAILED when it fails, but Mach kernel handles this fails different, asynchronously. The original error is "Bus error: 10" and throws during mmap call. Below the list of links, what I googled yesterday:

But I can't find any information from official Apple resources about virtual memory management and limits :(

PS: My fix solves problem with crash when game loaded with standard beetle interpreter. Lightrec on Apple Silicon crash Retroarch if it explicitly choosed as dynamic recompilator. If say simple - it's fast fix for Apple Silicon users and optimization under macOS.

ZachCook commented 1 week ago

Was originally going to let someone else merge this, since I don't usually do merges even though I have access, and then with #909 trying to fix the same thing it seemed like this was needing correcting sooner rather than later.

ZachCook commented 1 week ago

Looks like this patch does need more work: https://git.libretro.com/libretro/beetle-psx-libretro/-/pipelines/300169/failures

`libretro.cpp:59:10: fatal error: 'mach/shared_region.h' file not found

include <mach/shared_region.h>

     ^~~~~~~~~~~~~~~~~~~~~~

1 error generated. make: *** [libretro.o] Error 1`

ZachCook commented 1 week ago

@LibretroAdmin I'm not completely sure what the process is here, just revert the merge for now? Sorry, I should have ping'ed you earlier instead of merging it

ZachCook commented 1 week ago

Looks like the shared region stuff needs

#ifdef _MACH_SHARED_REGION_H_

Is that part actually needed to run properly or can you just avoid certain mmap address blocks instead?

kozharskyad commented 1 week ago

Hmm we can avoid shared region VM shift on all devices, except macOS.

And we can not to include headers, but it's not so clear solution, because OS defines may change on later versions of OS.

kozharskyad commented 1 week ago

Created another pull request - https://github.com/libretro/beetle-psx-libretro/pull/911

ZachCook commented 1 week ago

Okay hopefully that PR fixes the other builds,

the normal mapping is something like Lightrec map addresses: M=0x40000000, P=0x..., R=0x5fc00000, H=0x5f800000

So all the mmap addresses might not stay within the shared region on arm (0x10000000 in size) with the R and H always being +1F800000 further in, so are we actually trying to mmap into it or just find a spot after it that wont interfere?

kozharskyad commented 1 week ago

In fact we just trying to find spot after macOS arm64 shared_region+512MB, because mmap have 90% chance to throw SIGBUS kernel exception, if we try to map virtual memory on macOS arm64 shared_region and before it.