bsd-user: Implement shmat(2) and shmdt(2)
Use `WITH_MMAP_LOCK_GUARD` instead of mmap_lock() and mmap_unlock(), to match linux-user implementation, according to the following commits:69fa2708a2
linux-user: Use WITH_MMAP_LOCK_GUARD in target_{shmat,shmdt}ceda5688b6
linux-user: Fix shmdt Signed-off-by: Stacey Son <sson@FreeBSD.org> Signed-off-by: Karim Taha <kariem.taha2.7@gmail.com> Message-Id: <20230925182709.4834-23-kariem.taha2.7@gmail.com>
This commit is contained in:
parent
f9bbe3cf28
commit
4e00b7d85d
@ -344,4 +344,91 @@ static inline abi_long do_bsd_shmctl(abi_long shmid, abi_long cmd,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* shmat(2) */
|
||||
static inline abi_long do_bsd_shmat(int shmid, abi_ulong shmaddr, int shmflg)
|
||||
{
|
||||
abi_ulong raddr;
|
||||
abi_long ret;
|
||||
struct shmid_ds shm_info;
|
||||
|
||||
/* Find out the length of the shared memory segment. */
|
||||
ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
|
||||
if (is_error(ret)) {
|
||||
/* Can't get the length */
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!guest_range_valid_untagged(shmaddr, shm_info.shm_segsz)) {
|
||||
return -TARGET_EINVAL;
|
||||
}
|
||||
|
||||
WITH_MMAP_LOCK_GUARD() {
|
||||
void *host_raddr;
|
||||
|
||||
if (shmaddr) {
|
||||
host_raddr = shmat(shmid, (void *)g2h_untagged(shmaddr), shmflg);
|
||||
} else {
|
||||
abi_ulong mmap_start;
|
||||
|
||||
mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
|
||||
|
||||
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_BSD_SHM_REGIONS; i++) {
|
||||
if (bsd_shm_regions[i].start == 0) {
|
||||
bsd_shm_regions[i].start = raddr;
|
||||
bsd_shm_regions[i].size = shm_info.shm_segsz;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return raddr;
|
||||
}
|
||||
|
||||
/* shmdt(2) */
|
||||
static inline abi_long do_bsd_shmdt(abi_ulong shmaddr)
|
||||
{
|
||||
abi_long ret;
|
||||
|
||||
WITH_MMAP_LOCK_GUARD() {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < N_BSD_SHM_REGIONS; ++i) {
|
||||
if (bsd_shm_regions[i].start == shmaddr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == N_BSD_SHM_REGIONS) {
|
||||
return -TARGET_EINVAL;
|
||||
}
|
||||
|
||||
ret = get_errno(shmdt(g2h_untagged(shmaddr)));
|
||||
if (ret == 0) {
|
||||
abi_ulong size = bsd_shm_regions[i].size;
|
||||
|
||||
bsd_shm_regions[i].start = 0;
|
||||
page_set_flags(shmaddr, shmaddr + size - 1, 0);
|
||||
mmap_reserve(shmaddr, size);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* BSD_USER_BSD_MEM_H */
|
||||
|
@ -871,6 +871,14 @@ static abi_long freebsd_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
ret = do_bsd_shmctl(arg1, arg2, arg3);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_shmat: /* shmat(2) */
|
||||
ret = do_bsd_shmat(arg1, arg2, arg3);
|
||||
break;
|
||||
|
||||
case TARGET_FREEBSD_NR_shmdt: /* shmdt(2) */
|
||||
ret = do_bsd_shmdt(arg1);
|
||||
break;
|
||||
|
||||
/*
|
||||
* Misc
|
||||
*/
|
||||
|
@ -636,7 +636,7 @@ fail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void mmap_reserve(abi_ulong start, abi_ulong size)
|
||||
void mmap_reserve(abi_ulong start, abi_ulong size)
|
||||
{
|
||||
abi_ulong real_start;
|
||||
abi_ulong real_end;
|
||||
|
@ -233,6 +233,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
|
||||
int target_msync(abi_ulong start, abi_ulong len, int flags);
|
||||
extern abi_ulong mmap_next_start;
|
||||
abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size);
|
||||
void mmap_reserve(abi_ulong start, abi_ulong size);
|
||||
void TSA_NO_TSA mmap_fork_start(void);
|
||||
void TSA_NO_TSA mmap_fork_end(int child);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user