diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2023-08-20 10:08:44 -0700 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2023-09-01 13:35:07 -0700 |
commit | 69fa2708a216df715ba5102a0f98468b540a464e (patch) | |
tree | 6b88465989f6c415a1cc58d4b8e54ccc56668877 /linux-user/mmap.c | |
parent | 225a206c4474f8344c8f0c13b735c414d0f170c7 (diff) |
linux-user: Use WITH_MMAP_LOCK_GUARD in target_{shmat,shmdt}
Move the CF_PARALLEL setting outside of the mmap lock.
Tested-by: Helge Deller <deller@gmx.de>
Reviewed-by: Helge Deller <deller@gmx.de>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'linux-user/mmap.c')
-rw-r--r-- | linux-user/mmap.c | 98 |
1 files changed, 46 insertions, 52 deletions
diff --git a/linux-user/mmap.c b/linux-user/mmap.c index 3aeacd1ecd..f45b2d307c 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -1017,9 +1017,8 @@ abi_ulong target_shmat(CPUArchState *cpu_env, int shmid, { CPUState *cpu = env_cpu(cpu_env); abi_ulong raddr; - void *host_raddr; struct shmid_ds shm_info; - int i, ret; + int ret; abi_ulong shmlba; /* shmat pointers are always untagged */ @@ -1044,7 +1043,43 @@ abi_ulong target_shmat(CPUArchState *cpu_env, int shmid, return -TARGET_EINVAL; } - mmap_lock(); + WITH_MMAP_LOCK_GUARD() { + void *host_raddr; + + if (shmaddr) { + host_raddr = shmat(shmid, (void *)g2h_untagged(shmaddr), shmflg); + } else { + abi_ulong mmap_start; + + /* In order to use the host shmat, we need to honor host SHMLBA. */ + mmap_start = mmap_find_vma(0, shm_info.shm_segsz, + MAX(SHMLBA, shmlba)); + + if (mmap_start == -1) { + return -TARGET_ENOMEM; + } + host_raddr = shmat(shmid, g2h_untagged(mmap_start), + shmflg | SHM_REMAP); + } + + if (host_raddr == (void *)-1) { + return get_errno(-1); + } + raddr = h2g(host_raddr); + + page_set_flags(raddr, raddr + shm_info.shm_segsz - 1, + PAGE_VALID | PAGE_RESET | PAGE_READ | + (shmflg & SHM_RDONLY ? 0 : PAGE_WRITE)); + + for (int i = 0; i < N_SHM_REGIONS; i++) { + if (!shm_regions[i].in_use) { + shm_regions[i].in_use = true; + shm_regions[i].start = raddr; + shm_regions[i].size = shm_info.shm_segsz; + break; + } + } + } /* * We're mapping shared memory, so ensure we generate code for parallel @@ -1057,65 +1092,24 @@ abi_ulong target_shmat(CPUArchState *cpu_env, int shmid, tb_flush(cpu); } - if (shmaddr) { - host_raddr = shmat(shmid, (void *)g2h_untagged(shmaddr), shmflg); - } else { - abi_ulong mmap_start; - - /* In order to use the host shmat, we need to honor host SHMLBA. */ - mmap_start = mmap_find_vma(0, shm_info.shm_segsz, MAX(SHMLBA, shmlba)); - - if (mmap_start == -1) { - errno = ENOMEM; - host_raddr = (void *)-1; - } else { - host_raddr = shmat(shmid, g2h_untagged(mmap_start), - shmflg | SHM_REMAP); - } - } - - if (host_raddr == (void *)-1) { - mmap_unlock(); - return get_errno((intptr_t)host_raddr); - } - raddr = h2g((uintptr_t)host_raddr); - - page_set_flags(raddr, raddr + shm_info.shm_segsz - 1, - PAGE_VALID | PAGE_RESET | PAGE_READ | - (shmflg & SHM_RDONLY ? 0 : PAGE_WRITE)); - - for (i = 0; i < N_SHM_REGIONS; i++) { - if (!shm_regions[i].in_use) { - shm_regions[i].in_use = true; - shm_regions[i].start = raddr; - shm_regions[i].size = shm_info.shm_segsz; - break; - } - } - - mmap_unlock(); return raddr; } abi_long target_shmdt(abi_ulong shmaddr) { - int i; abi_long rv; /* shmdt pointers are always untagged */ - mmap_lock(); - - for (i = 0; i < N_SHM_REGIONS; ++i) { - if (shm_regions[i].in_use && shm_regions[i].start == shmaddr) { - shm_regions[i].in_use = false; - page_set_flags(shmaddr, shmaddr + shm_regions[i].size - 1, 0); - break; + WITH_MMAP_LOCK_GUARD() { + for (int i = 0; i < N_SHM_REGIONS; ++i) { + if (shm_regions[i].in_use && shm_regions[i].start == shmaddr) { + shm_regions[i].in_use = false; + page_set_flags(shmaddr, shmaddr + shm_regions[i].size - 1, 0); + break; + } } + rv = get_errno(shmdt(g2h_untagged(shmaddr))); } - rv = get_errno(shmdt(g2h_untagged(shmaddr))); - - mmap_unlock(); - return rv; } |