aboutsummaryrefslogtreecommitdiff
path: root/bsd-user
diff options
context:
space:
mode:
authorWarner Losh <imp@bsdimp.com>2023-02-13 16:02:03 -0700
committerWarner Losh <imp@bsdimp.com>2023-03-01 11:09:18 -0700
commit0867507857f7e305ec3ade01c6b28c32edf593c1 (patch)
treee41a04ee5bd03eb2b2f4c12040ce11478c313a01 /bsd-user
parentfb96f5dfed8a45f44356899c92d6fcba0e7658a5 (diff)
bsd-user: various helper routines for sysctl
cap_memory - Caps the memory to just below MAXINT scale_to_guest_pages - Account for difference in host / guest page size h2g_long_sat - converts a int64_t to a int32_t, saturating at max / min values h2g_ulong_sat - converts a uint64_t to a uint32_t, saturating at max value Signed-off-by: Warner Losh <imp@bsdimp.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'bsd-user')
-rw-r--r--bsd-user/freebsd/os-sys.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/bsd-user/freebsd/os-sys.c b/bsd-user/freebsd/os-sys.c
index 1676ec10f8..a4f3fd8091 100644
--- a/bsd-user/freebsd/os-sys.c
+++ b/bsd-user/freebsd/os-sys.c
@@ -21,6 +21,92 @@
#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 guest_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 guest_max_mem = UINT32_MAX - 0x100c000 + 1;
+
+static abi_ulong G_GNUC_UNUSED cap_memory(uint64_t mem)
+{
+ return MIN(guest_max_mem, mem);
+}
+#endif
+
+static abi_ulong G_GNUC_UNUSED scale_to_guest_pages(uint64_t pages)
+{
+ /* Scale pages from host to guest */
+ pages = muldiv64(pages, qemu_real_host_page_size(), TARGET_PAGE_SIZE);
+#ifdef TARGET_ABI32
+ /* cap pages if need be */
+ pages = MIN(pages, guest_max_mem / (abi_ulong)TARGET_PAGE_SIZE);
+#endif
+ return pages;
+}
+
+#ifdef TARGET_ABI32
+/* Used only for TARGET_ABI32 */
+static abi_long G_GNUC_UNUSED h2g_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 h2g_ulong_sat(u_long ul)
+{
+ return MIN(ul, UINT32_MAX);
+}
+#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)
{