diff mbox series

[20/22] Implement shmctl(2)

Message ID 20230819094806.14965-21-kariem.taha2.7@gmail.com
State New
Headers show
Series Implement the mmap system call for FreeBSD. | expand

Commit Message

Karim Taha Aug. 19, 2023, 9:48 a.m. UTC
From: Stacey Son <sson@FreeBSD.org>

Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Karim Taha <kariem.taha2.7@gmail.com>
---
 bsd-user/bsd-mem.h            | 33 +++++++++++++++++++++++++++++++++
 bsd-user/freebsd/os-syscall.c |  4 ++++
 2 files changed, 37 insertions(+)

Comments

Warner Losh Aug. 20, 2023, 4:43 a.m. UTC | #1
On Sat, Aug 19, 2023 at 3:49 AM Karim Taha <kariem.taha2.7@gmail.com> wrote:

> From: Stacey Son <sson@FreeBSD.org>
>
> Signed-off-by: Stacey Son <sson@FreeBSD.org>
> Signed-off-by: Karim Taha <kariem.taha2.7@gmail.com>
> ---
>  bsd-user/bsd-mem.h            | 33 +++++++++++++++++++++++++++++++++
>  bsd-user/freebsd/os-syscall.c |  4 ++++
>  2 files changed, 37 insertions(+)
>

Reviewed-by: Warner Losh <imp@bsdimp.com>
Richard Henderson Aug. 20, 2023, 3:13 p.m. UTC | #2
On 8/19/23 02:48, Karim Taha wrote:
> +    switch (cmd) {
> +    case IPC_STAT:
> +    case IPC_SET:
> +        if (target_to_host_shmid_ds(&dsarg, buff)) {
> +            return -TARGET_EFAULT;
> +        }
> +        ret = get_errno(shmctl(shmid, cmd, &dsarg));
> +        if (host_to_target_shmid_ds(buff, &dsarg)) {
> +            return -TARGET_EFAULT;
> +        }
> +        break;

IPC_STAT treats buff as output, IPC_SET treats buff as input,
so these cases can't be combined.


r~
Karim Taha Sept. 9, 2023, 1:59 a.m. UTC | #3
Richard Henderson <richard.henderson@linaro.org> wrote:

> On 8/19/23 02:48, Karim Taha wrote:
>> +    switch (cmd) {
>> +    case IPC_STAT:
>> +    case IPC_SET:
>> +        if (target_to_host_shmid_ds(&dsarg, buff)) {
>> +            return -TARGET_EFAULT;
>> +        }
>> +        ret = get_errno(shmctl(shmid, cmd, &dsarg));
>> +        if (host_to_target_shmid_ds(buff, &dsarg)) {
>> +            return -TARGET_EFAULT;
>> +        }
>> +        break;
>
> IPC_STAT treats buff as output, IPC_SET treats buff as input,
> so these cases can't be combined.
>
>
> r~

I think they can be combined:
1- we marshal the struct `buff` from target to host
2- call `shmctl`
3- marshal the results back.

--
Karim Taha
Richard Henderson Sept. 9, 2023, 5:51 p.m. UTC | #4
On 9/8/23 18:59, Karim Taha wrote:
> Richard Henderson <richard.henderson@linaro.org> wrote:
> 
>> On 8/19/23 02:48, Karim Taha wrote:
>>> +    switch (cmd) {
>>> +    case IPC_STAT:
>>> +    case IPC_SET:
>>> +        if (target_to_host_shmid_ds(&dsarg, buff)) {
>>> +            return -TARGET_EFAULT;
>>> +        }
>>> +        ret = get_errno(shmctl(shmid, cmd, &dsarg));
>>> +        if (host_to_target_shmid_ds(buff, &dsarg)) {
>>> +            return -TARGET_EFAULT;
>>> +        }
>>> +        break;
>>
>> IPC_STAT treats buff as output, IPC_SET treats buff as input,
>> so these cases can't be combined.
>>
>>
>> r~
> 
> I think they can be combined:
> 1- we marshal the struct `buff` from target to host
> 2- call `shmctl`
> 3- marshal the results back.

No.  For IPC_SET, the target page need not be writable, as you assume here.


r~
diff mbox series

Patch

diff --git a/bsd-user/bsd-mem.h b/bsd-user/bsd-mem.h
index 3d91d3eb30..221ad76d8c 100644
--- a/bsd-user/bsd-mem.h
+++ b/bsd-user/bsd-mem.h
@@ -302,4 +302,37 @@  static inline abi_long do_bsd_shmget(abi_long arg1, abi_ulong arg2,
     return get_errno(shmget(arg1, arg2, arg3));
 }
 
+/* shmctl(2) */
+static inline abi_long do_bsd_shmctl(abi_long shmid, abi_long cmd,
+        abi_ulong buff)
+{
+    struct shmid_ds dsarg;
+    abi_long ret = -TARGET_EINVAL;
+
+    cmd &= 0xff;
+
+    switch (cmd) {
+    case IPC_STAT:
+    case IPC_SET:
+        if (target_to_host_shmid_ds(&dsarg, buff)) {
+            return -TARGET_EFAULT;
+        }
+        ret = get_errno(shmctl(shmid, cmd, &dsarg));
+        if (host_to_target_shmid_ds(buff, &dsarg)) {
+            return -TARGET_EFAULT;
+        }
+        break;
+
+    case IPC_RMID:
+        ret = get_errno(shmctl(shmid, cmd, NULL));
+        break;
+
+    default:
+        ret = -TARGET_EINVAL;
+        break;
+    }
+
+    return ret;
+}
+
 #endif /* BSD_USER_BSD_MEM_H */
diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c
index a7db78b9b4..9681c65ce9 100644
--- a/bsd-user/freebsd/os-syscall.c
+++ b/bsd-user/freebsd/os-syscall.c
@@ -555,6 +555,10 @@  static abi_long freebsd_syscall(void *cpu_env, int num, abi_long arg1,
         ret = do_bsd_shmget(arg1, arg2, arg3);
         break;
 
+    case TARGET_FREEBSD_NR_shmctl: /* shmctl(2) */
+        ret = do_bsd_shmctl(arg1, arg2, arg3);
+        break;
+
         /*
          * Misc
          */