lightrec: must use MAP_FIXED_NOREPLACE
[pcsx_rearmed.git] / libpcsxcore / lightrec / mem.c
index 76608ea..efabdb0 100644 (file)
@@ -3,6 +3,9 @@
  * Copyright (C) 2022 Paul Cercueil <paul@crapouillou.net>
  */
 
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
 #include <errno.h>
 #include <fcntl.h>
 #include <stdbool.h>
@@ -11,6 +14,7 @@
 #include <sys/mman.h>
 #include <sys/shm.h>
 #include <sys/stat.h>
+#include <sys/syscall.h>
 #include <unistd.h>
 
 #include "../psxhw.h"
 #define MAP_FIXED_NOREPLACE 0x100000
 #endif
 
+#ifndef MFD_HUGETLB
+#define MFD_HUGETLB 0x0004
+#endif
+
 static const uintptr_t supported_io_bases[] = {
        0x0,
        0x10000000,
@@ -64,7 +72,8 @@ static int lightrec_mmap_ram(bool hugetlb)
        if (hugetlb)
                flags |= MFD_HUGETLB;
 
-       memfd = memfd_create("/lightrec_memfd", flags);
+        memfd = syscall(SYS_memfd_create, "/lightrec_memfd",
+                       flags);
        if (memfd < 0) {
                err = -errno;
                fprintf(stderr, "Failed to create memfd: %d\n", err);
@@ -84,7 +93,7 @@ static int lightrec_mmap_ram(bool hugetlb)
                for (j = 0; j < 4; j++) {
                        map = mmap_huge((void *)(base + j * 0x200000),
                                        0x200000, PROT_READ | PROT_WRITE,
-                                       MAP_SHARED | MAP_FIXED, memfd, 0);
+                                       MAP_SHARED | MAP_FIXED_NOREPLACE, memfd, 0);
                        if (map == MAP_FAILED)
                                break;
                }
@@ -120,9 +129,7 @@ int lightrec_init_mmap(void)
        unsigned int i;
        uintptr_t base;
        void *map;
-       int err;
-
-       err = lightrec_mmap_ram(true);
+       int err = lightrec_mmap_ram(true);
        if (err) {
                err = lightrec_mmap_ram(false);
                if (err) {
@@ -135,7 +142,7 @@ int lightrec_init_mmap(void)
 
        map = mmap((void *)(base + 0x1f000000), 0x10000,
                   PROT_READ | PROT_WRITE,
-                  MAP_PRIVATE | MAP_FIXED_NOREPLACE | MAP_ANONYMOUS, 0, 0);
+                  MAP_PRIVATE | MAP_FIXED_NOREPLACE | MAP_ANONYMOUS, -1, 0);
        if (map == MAP_FAILED) {
                err = -EINVAL;
                fprintf(stderr, "Unable to mmap parallel port\n");
@@ -146,7 +153,7 @@ int lightrec_init_mmap(void)
 
        map = mmap_huge((void *)(base + 0x1fc00000), 0x200000,
                        PROT_READ | PROT_WRITE,
-                       MAP_PRIVATE | MAP_FIXED_NOREPLACE | MAP_ANONYMOUS, 0, 0);
+                       MAP_PRIVATE | MAP_FIXED_NOREPLACE | MAP_ANONYMOUS, -1, 0);
        if (map == MAP_FAILED) {
                err = -EINVAL;
                fprintf(stderr, "Unable to mmap BIOS\n");
@@ -166,10 +173,24 @@ int lightrec_init_mmap(void)
 
        psxH = (s8 *)map;
 
+       map = mmap_huge((void *)(base + 0x800000), CODE_BUFFER_SIZE,
+                       PROT_EXEC | PROT_READ | PROT_WRITE,
+                       MAP_PRIVATE | MAP_FIXED_NOREPLACE | MAP_ANONYMOUS,
+                       -1, 0);
+       if (map == MAP_FAILED) {
+               err = -EINVAL;
+               fprintf(stderr, "Unable to mmap code buffer\n");
+               goto err_unmap_scratch;
+       }
+
+       code_buffer = map;
+
        return 0;
 
+err_unmap_scratch:
+       munmap(psxH, 0x10000);
 err_unmap_bios:
-       munmap(psxR, 0x80000);
+       munmap(psxR, 0x200000);
 err_unmap_parallel:
        munmap(psxP, 0x10000);
 err_unmap:
@@ -182,8 +203,9 @@ void lightrec_free_mmap(void)
 {
        unsigned int i;
 
+       munmap(code_buffer, CODE_BUFFER_SIZE);
        munmap(psxH, 0x10000);
-       munmap(psxR, 0x80000);
+       munmap(psxR, 0x200000);
        munmap(psxP, 0x10000);
        for (i = 0; i < 4; i++)
                munmap((void *)((uintptr_t)psxM + i * 0x200000), 0x200000);