diff mbox series

[v2,04/12] bsd-user: various helper routines for sysctl

Message ID 20230214002757.99240-5-imp@bsdimp.com
State New
Headers show
Series 2023 Q1 bsd-user upstreaming: bugfixes and sysctl | expand

Commit Message

Warner Losh Feb. 14, 2023, 12:27 a.m. UTC
cap_memory - Caps the memory to just below MAXINT
scale_to_target_pages - Account for difference in host / targe page size
h2t_long_sat - converts a int64_t to a int32_t, saturating at max / min values
h2t_ulong_sat - converts a uint64_t to a uint32_t, saturating at max value

Signed-off-by: Warner Losh <imp@bsdimp.com>
---
 bsd-user/freebsd/os-sys.c | 100 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 100 insertions(+)

Comments

Richard Henderson Feb. 14, 2023, 8:52 p.m. UTC | #1
On 2/13/23 14:27, Warner Losh wrote:
> +#ifdef TARGET_ABI32
> +/*
> + * Limit the amount of available memory to be most of the 32-bit address
> + * space. 0x100c000 was arrived at through trial and error as a good
> + * definition of 'most'.
> + */
> +static const abi_ulong target_max_mem = UINT32_MAX - 0x100c000 + 1;
> +
> +static abi_ulong G_GNUC_UNUSED cap_memory(uint64_t mem)
> +{
> +    if (((unsigned long)target_max_mem) < mem) {
> +        mem = target_max_mem;
> +    }
> +
> +    return mem;
> +}
> +#endif

Identity function for ABI64?

> +static unsigned long host_page_size;
> +
> +static abi_ulong G_GNUC_UNUSED scale_to_target_pages(uint64_t pages)
> +{
> +    if (host_page_size == 0) {
> +        host_page_size = getpagesize();
> +    }

qemu_real_host_page_size()


> +
> +    pages = muldiv64(pages, host_page_size, TARGET_PAGE_SIZE);
> +#ifdef TARGET_ABI32
> +    abi_ulong maxpages = target_max_mem / (abi_ulong)TARGET_PAGE_SIZE;
> +
> +    if (((unsigned long)maxpages) < pages) {
> +        pages = maxpages;
> +    }
> +#endif

No need for either cast.  Just use MIN().

> +#ifdef TARGET_ABI32
> +static abi_long G_GNUC_UNUSED h2t_long_sat(long l)

h2g.

> +{
> +    if (l > INT32_MAX) {
> +        l = INT32_MAX;
> +    } else if (l < INT32_MIN) {
> +        l = INT32_MIN;
> +    }
> +    return l;
> +}
> +
> +static abi_ulong G_GNUC_UNUSED h2t_ulong_sat(u_long ul)
> +{
> +    if (ul > UINT32_MAX) {
> +        ul = UINT32_MAX;
> +    }
> +    return ul;
> +}
> +#endif

Anyway, identity functions for ABI64?


r~
Warner Losh Feb. 14, 2023, 9:31 p.m. UTC | #2
On Tue, Feb 14, 2023 at 1:52 PM Richard Henderson <
richard.henderson@linaro.org> wrote:

> On 2/13/23 14:27, Warner Losh wrote:
> > +#ifdef TARGET_ABI32
> > +/*
> > + * Limit the amount of available memory to be most of the 32-bit address
> > + * space. 0x100c000 was arrived at through trial and error as a good
> > + * definition of 'most'.
> > + */
> > +static const abi_ulong target_max_mem = UINT32_MAX - 0x100c000 + 1;
> > +
> > +static abi_ulong G_GNUC_UNUSED cap_memory(uint64_t mem)
> > +{
> > +    if (((unsigned long)target_max_mem) < mem) {
> > +        mem = target_max_mem;
> > +    }
> > +
> > +    return mem;
> > +}
> > +#endif
>
> Identity function for ABI64?
>

Indirectly, yes. For ABI64 we simply don't intercept these sysctl nodes.


> > +static unsigned long host_page_size;
> > +
> > +static abi_ulong G_GNUC_UNUSED scale_to_target_pages(uint64_t pages)
> > +{
> > +    if (host_page_size == 0) {
> > +        host_page_size = getpagesize();
> > +    }
>
> qemu_real_host_page_size()
>

OK. Easy enough. That was a warning from checkpatch anyway that had slipped
my mind.


> > +
> > +    pages = muldiv64(pages, host_page_size, TARGET_PAGE_SIZE);
> > +#ifdef TARGET_ABI32
> > +    abi_ulong maxpages = target_max_mem / (abi_ulong)TARGET_PAGE_SIZE;
> > +
> > +    if (((unsigned long)maxpages) < pages) {
> > +        pages = maxpages;
> > +    }
> > +#endif
>
> No need for either cast.  Just use MIN().
>

Gotcha.


> > +#ifdef TARGET_ABI32
> > +static abi_long G_GNUC_UNUSED h2t_long_sat(long l)
>
> h2g.
>

OK.


> > +{
> > +    if (l > INT32_MAX) {
> > +        l = INT32_MAX;
> > +    } else if (l < INT32_MIN) {
> > +        l = INT32_MIN;
> > +    }
> > +    return l;
> > +}
> > +
> > +static abi_ulong G_GNUC_UNUSED h2t_ulong_sat(u_long ul)
> > +{
> > +    if (ul > UINT32_MAX) {
> > +        ul = UINT32_MAX;
> > +    }
> > +    return ul;
> > +}
> > +#endif
>
> Anyway, identity functions for ABI64?
>

Right now they aren't used at all for ABI64...  But that's in later
patches...  We only do
special things for  LONG or ULONG on ABI32... Otherwise, the normal paths
wouldn't
call these at all.

Warner
Richard Henderson Feb. 14, 2023, 9:39 p.m. UTC | #3
On 2/14/23 11:31, Warner Losh wrote:
> Right now they aren't used at all for ABI64...  But that's in later patches...  We only do
> special things for  LONG or ULONG on ABI32... Otherwise, the normal paths wouldn't
> call these at all.

Yes, I've just seen patch 9, and agree they aren't needed for abi64.


r~
diff mbox series

Patch

diff --git a/bsd-user/freebsd/os-sys.c b/bsd-user/freebsd/os-sys.c
index 1676ec10f83..cfbc4148a5c 100644
--- a/bsd-user/freebsd/os-sys.c
+++ b/bsd-user/freebsd/os-sys.c
@@ -21,6 +21,106 @@ 
 #include "qemu.h"
 #include "target_arch_sysarch.h"
 
+#include <sys/sysctl.h>
+
+/*
+ * Length for the fixed length types.
+ * 0 means variable length for strings and structures
+ * Compare with sys/kern_sysctl.c ctl_size
+ * Note: Not all types appear to be used in-tree.
+ */
+static const int G_GNUC_UNUSED target_ctl_size[CTLTYPE+1] = {
+	[CTLTYPE_INT] = sizeof(abi_int),
+	[CTLTYPE_UINT] = sizeof(abi_uint),
+	[CTLTYPE_LONG] = sizeof(abi_long),
+	[CTLTYPE_ULONG] = sizeof(abi_ulong),
+	[CTLTYPE_S8] = sizeof(int8_t),
+	[CTLTYPE_S16] = sizeof(int16_t),
+	[CTLTYPE_S32] = sizeof(int32_t),
+	[CTLTYPE_S64] = sizeof(int64_t),
+	[CTLTYPE_U8] = sizeof(uint8_t),
+	[CTLTYPE_U16] = sizeof(uint16_t),
+	[CTLTYPE_U32] = sizeof(uint32_t),
+	[CTLTYPE_U64] = sizeof(uint64_t),
+};
+
+static const int G_GNUC_UNUSED host_ctl_size[CTLTYPE+1] = {
+	[CTLTYPE_INT] = sizeof(int),
+	[CTLTYPE_UINT] = sizeof(u_int),
+	[CTLTYPE_LONG] = sizeof(long),
+	[CTLTYPE_ULONG] = sizeof(u_long),
+	[CTLTYPE_S8] = sizeof(int8_t),
+	[CTLTYPE_S16] = sizeof(int16_t),
+	[CTLTYPE_S32] = sizeof(int32_t),
+	[CTLTYPE_S64] = sizeof(int64_t),
+	[CTLTYPE_U8] = sizeof(uint8_t),
+	[CTLTYPE_U16] = sizeof(uint16_t),
+	[CTLTYPE_U32] = sizeof(uint32_t),
+	[CTLTYPE_U64] = sizeof(uint64_t),
+};
+
+#ifdef TARGET_ABI32
+/*
+ * Limit the amount of available memory to be most of the 32-bit address
+ * space. 0x100c000 was arrived at through trial and error as a good
+ * definition of 'most'.
+ */
+static const abi_ulong target_max_mem = UINT32_MAX - 0x100c000 + 1;
+
+static abi_ulong G_GNUC_UNUSED cap_memory(uint64_t mem)
+{
+    if (((unsigned long)target_max_mem) < mem) {
+        mem = target_max_mem;
+    }
+
+    return mem;
+}
+#endif
+
+static unsigned long host_page_size;
+
+static abi_ulong G_GNUC_UNUSED scale_to_target_pages(uint64_t pages)
+{
+    if (host_page_size == 0) {
+        host_page_size = getpagesize();
+    }
+
+    pages = muldiv64(pages, host_page_size, TARGET_PAGE_SIZE);
+#ifdef TARGET_ABI32
+    abi_ulong maxpages = target_max_mem / (abi_ulong)TARGET_PAGE_SIZE;
+
+    if (((unsigned long)maxpages) < pages) {
+        pages = maxpages;
+    }
+#endif
+    return pages;
+}
+
+#ifdef TARGET_ABI32
+static abi_long G_GNUC_UNUSED h2t_long_sat(long l)
+{
+    if (l > INT32_MAX) {
+        l = INT32_MAX;
+    } else if (l < INT32_MIN) {
+        l = INT32_MIN;
+    }
+    return l;
+}
+
+static abi_ulong G_GNUC_UNUSED h2t_ulong_sat(u_long ul)
+{
+    if (ul > UINT32_MAX) {
+        ul = UINT32_MAX;
+    }
+    return ul;
+}
+#endif
+
+/*
+ * placeholder until bsd-user downstream upstreams this with its thread support
+ */
+#define bsd_get_ncpu() 1
+
 /* sysarch() is architecture dependent. */
 abi_long do_freebsd_sysarch(void *cpu_env, abi_long arg1, abi_long arg2)
 {