diff mbox series

[v2,09/12] bsd-user: Start translation of arch-specific sysctls

Message ID 20230214002757.99240-10-imp@bsdimp.com (mailing list archive)
State New, archived
Headers show
Series 2023 Q1 bsd-user upstreaming: bugfixes and sysctl | expand

Commit Message

Warner Losh Feb. 14, 2023, 12:27 a.m. UTC
From: Juergen Lock <nox@jelal.kn-bremen.de>

Intercept some syscalls that we need to translate (like the archiecture
we're running on) and translate them. These are only the simplest ones
so far.

Signed-off-by: Juergen Lock <nox@jelal.kn-bremen.de>
Co-Authored-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Stacey Son <sson@FreeBSD.org>
Co-Authored-by: Warner Losh <imp@bsdimp.com>
Signed-off-by: Warner Losh <imp@bsdimp.com>
---
 bsd-user/freebsd/os-sys.c | 145 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 143 insertions(+), 2 deletions(-)

Comments

Richard Henderson Feb. 14, 2023, 9:36 p.m. UTC | #1
On 2/13/23 14:27, Warner Losh wrote:
> +        case HW_NCPU:
> +            if (oldlen) {
> +                (*(int32_t *)holdp) = tswap32(bsd_get_ncpu());
> +            }
> +            holdlen = sizeof(int32_t);
> +            ret = 0;
> +            goto out;

Anything using SYSCTL_INT should use abi_int.

> +#if defined(TARGET_ARM)
> +        case HW_FLOATINGPT:
> +            if (oldlen) {
> +                ARMCPU *cpu = env_archcpu(env);
> +                *(abi_int *)holdp = cpu_isar_feature(aa32_vfp, cpu);
> +            }
> +            holdlen = sizeof(int32_t);

abi_int for consistency.

Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~
Warner Losh Feb. 16, 2023, 10:57 p.m. UTC | #2
On Tue, Feb 14, 2023 at 2:36 PM Richard Henderson <
richard.henderson@linaro.org> wrote:

> On 2/13/23 14:27, Warner Losh wrote:
> > +        case HW_NCPU:
> > +            if (oldlen) {
> > +                (*(int32_t *)holdp) = tswap32(bsd_get_ncpu());
> > +            }
> > +            holdlen = sizeof(int32_t);
> > +            ret = 0;
> > +            goto out;
>
> Anything using SYSCTL_INT should use abi_int.
>
> > +#if defined(TARGET_ARM)
> > +        case HW_FLOATINGPT:
> > +            if (oldlen) {
> > +                ARMCPU *cpu = env_archcpu(env);
> > +                *(abi_int *)holdp = cpu_isar_feature(aa32_vfp, cpu);
> > +            }
> > +            holdlen = sizeof(int32_t);
>
> abi_int for consistency.
>
> Otherwise,
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
>

Makes sense.. Thanks!

Warner
diff mbox series

Patch

diff --git a/bsd-user/freebsd/os-sys.c b/bsd-user/freebsd/os-sys.c
index e847404af66..cbaa70958b9 100644
--- a/bsd-user/freebsd/os-sys.c
+++ b/bsd-user/freebsd/os-sys.c
@@ -67,7 +67,7 @@  static const int host_ctl_size[CTLTYPE+1] = {
  */
 static const abi_ulong target_max_mem = UINT32_MAX - 0x100c000 + 1;
 
-static abi_ulong G_GNUC_UNUSED cap_memory(uint64_t mem)
+static abi_ulong cap_memory(uint64_t mem)
 {
     if (((unsigned long)target_max_mem) < mem) {
         mem = target_max_mem;
@@ -79,7 +79,7 @@  static abi_ulong G_GNUC_UNUSED cap_memory(uint64_t mem)
 
 static unsigned long host_page_size;
 
-static abi_ulong G_GNUC_UNUSED scale_to_target_pages(uint64_t pages)
+static abi_ulong scale_to_target_pages(uint64_t pages)
 {
     if (host_page_size == 0) {
         host_page_size = getpagesize();
@@ -273,6 +273,146 @@  static abi_long G_GNUC_UNUSED do_freebsd_sysctl_oid(CPUArchState *env, int32_t *
     oidfmt(snamep, namelen, NULL, &kind);
 
     /* Handle some arch/emulator dependent sysctl()'s here. */
+    switch (snamep[0]) {
+    case CTL_KERN:
+        switch (snamep[1]) {
+        case KERN_USRSTACK:
+            if (oldlen) {
+                (*(abi_ulong *)holdp) = tswapal(TARGET_USRSTACK);
+            }
+            holdlen = sizeof(abi_ulong);
+            ret = 0;
+            goto out;
+
+        case KERN_PS_STRINGS:
+            if (oldlen) {
+                (*(abi_ulong *)holdp) = tswapal(TARGET_PS_STRINGS);
+            }
+            holdlen = sizeof(abi_ulong);
+            ret = 0;
+            goto out;
+
+        default:
+            break;
+        }
+        break;
+
+    case CTL_HW:
+        switch (snamep[1]) {
+        case HW_MACHINE:
+            holdlen = sizeof(TARGET_HW_MACHINE);
+            if (holdp) {
+                strlcpy(holdp, TARGET_HW_MACHINE, oldlen);
+            }
+            ret = 0;
+            goto out;
+
+        case HW_MACHINE_ARCH:
+        {
+            holdlen = sizeof(TARGET_HW_MACHINE_ARCH);
+            if (holdp) {
+                strlcpy(holdp, TARGET_HW_MACHINE_ARCH, oldlen);
+            }
+            ret = 0;
+            goto out;
+        }
+        case HW_NCPU:
+            if (oldlen) {
+                (*(int32_t *)holdp) = tswap32(bsd_get_ncpu());
+            }
+            holdlen = sizeof(int32_t);
+            ret = 0;
+            goto out;
+#if defined(TARGET_ARM)
+        case HW_FLOATINGPT:
+            if (oldlen) {
+                ARMCPU *cpu = env_archcpu(env);
+                *(abi_int *)holdp = cpu_isar_feature(aa32_vfp, cpu);
+            }
+            holdlen = sizeof(int32_t);
+            ret = 0;
+            goto out;
+#endif
+
+
+#ifdef TARGET_ABI32
+        case HW_PHYSMEM:
+        case HW_USERMEM:
+        case HW_REALMEM:
+            holdlen = sizeof(abi_ulong);
+            ret = 0;
+
+            if (oldlen) {
+                int mib[2] = {snamep[0], snamep[1]};
+                unsigned long lvalue;
+                size_t len = sizeof(lvalue);
+
+                if (sysctl(mib, 2, &lvalue, &len, NULL, 0) == -1) {
+                    ret = -1;
+                } else {
+                    lvalue = cap_memory(lvalue);
+                    (*(abi_ulong *)holdp) = tswapal((abi_ulong)lvalue);
+                }
+            }
+            goto out;
+#endif
+
+        default:
+        {
+            static int oid_hw_availpages;
+            static int oid_hw_pagesizes;
+
+            if (!oid_hw_availpages) {
+                int real_oid[CTL_MAXNAME + 2];
+                size_t len = sizeof(real_oid) / sizeof(int);
+
+                if (sysctlnametomib("hw.availpages", real_oid, &len) >= 0) {
+                    oid_hw_availpages = real_oid[1];
+                }
+            }
+            if (!oid_hw_pagesizes) {
+                int real_oid[CTL_MAXNAME + 2];
+                size_t len = sizeof(real_oid) / sizeof(int);
+
+                if (sysctlnametomib("hw.pagesizes", real_oid, &len) >= 0) {
+                    oid_hw_pagesizes = real_oid[1];
+                }
+            }
+
+            if (oid_hw_availpages && snamep[1] == oid_hw_availpages) {
+                long lvalue;
+                size_t len = sizeof(lvalue);
+
+                if (sysctlbyname("hw.availpages", &lvalue, &len, NULL, 0) == -1) {
+                    ret = -1;
+                } else {
+                    if (oldlen) {
+                        lvalue = scale_to_target_pages(lvalue);
+                        (*(abi_ulong *)holdp) = tswapal((abi_ulong)lvalue);
+                    }
+                    holdlen = sizeof(abi_ulong);
+                    ret = 0;
+                }
+                goto out;
+            }
+
+            if (oid_hw_pagesizes && snamep[1] == oid_hw_pagesizes) {
+                if (oldlen) {
+                    (*(abi_ulong *)holdp) = tswapal((abi_ulong)getpagesize());
+                    ((abi_ulong *)holdp)[1] = 0;
+                }
+                holdlen = sizeof(abi_ulong) * 2;
+                ret = 0;
+                goto out;
+            }
+            break;
+        }
+        }
+        break;
+
+    default:
+        break;
+    }
 
 #ifdef TARGET_ABI32
     /*
@@ -336,6 +476,7 @@  static abi_long G_GNUC_UNUSED do_freebsd_sysctl_oid(CPUArchState *env, int32_t *
         }
     }
 
+out:
     *holdlenp = holdlen;
     return ret;
 }