bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Use struct for time_value_t and define seconds as long_integer_t


From: Flavio Cruz
Subject: [PATCH] Use struct for time_value_t and define seconds as long_integer_t.
Date: Fri, 16 Dec 2022 21:06:25 -0500

On 64 bit kernels, seconds will be 64 bits long and won't suffer from
the 2038 problem. We also add a new type rpc_time_value_t to handle the
conversion between 32 bit userland and 64 bit kernel.
---
 i386/include/mach/i386/machine_types.defs | 16 ++++++++++++--
 i386/include/mach/i386/vm_types.h         |  8 +++++++
 include/mach/mach_types.defs              | 13 ++++++++++-
 include/mach/time_value.h                 | 27 ++++++++++++++++++++++-
 4 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/i386/include/mach/i386/machine_types.defs 
b/i386/include/mach/i386/machine_types.defs
index f3de1e44..d1b61be9 100755
--- a/i386/include/mach/i386/machine_types.defs
+++ b/i386/include/mach/i386/machine_types.defs
@@ -66,13 +66,25 @@ type long_natural_t = uint32_t;
 #endif /* __x86_64__ */
 
 /*
- * long_natural_t for kernel <-> userland interfaces as the size depends on the
- * architecture of both kernel and userland.
+ * Larger version of integer_t. Only used when we want to hold possibly larger
+ * values than what is possible with integer_t.
+ */
+#if defined(__x86_64__)
+type long_integer_t = int64_t;
+#else
+type long_integer_t = int32_t;
+#endif /* __x86_64__ */
+
+/*
+ * long_natural_t and long_integer_t for kernel <-> userland interfaces as the
+ * size depends on the architecture of both kernel and userland.
  */
 #if defined(KERNEL) && defined(USER32)
 type rpc_long_natural_t = uint32_t;
+type rpc_long_integer_t = int32_t;
 #else /* KERNEL and USER32 */
 type rpc_long_natural_t = long_natural_t;
+type rpc_long_integer_t = long_integer_t;
 #endif /* KERNEL_SERVER and USER32 */
 
 /*
diff --git a/i386/include/mach/i386/vm_types.h 
b/i386/include/mach/i386/vm_types.h
index 86e8563a..7e5857a5 100644
--- a/i386/include/mach/i386/vm_types.h
+++ b/i386/include/mach/i386/vm_types.h
@@ -68,6 +68,12 @@ typedef int          integer_t;
  */
 typedef unsigned long long_natural_t;
 
+/*
+ * Larger version of integer_t. Only used when we want to hold possibly larger
+ * values than what is possible with integer_t.
+ */
+typedef long long_integer_t;
+
 /*
  * A vm_offset_t is a type-neutral pointer,
  * e.g. an offset into a virtual memory space.
@@ -117,6 +123,7 @@ static inline __mach_uint32_t 
convert_vm_to_user(__mach_uint64_t kaddr)
     return (__mach_uint32_t)kaddr;
 }
 typedef __mach_uint32_t rpc_long_natural_t;
+typedef __mach_int32_t rpc_long_integer_t;
 #else /* MACH_KERNEL */
 typedef vm_offset_t    rpc_vm_address_t;
 typedef vm_offset_t    rpc_vm_offset_t;
@@ -124,6 +131,7 @@ typedef vm_size_t   rpc_vm_size_t;
 #define convert_vm_to_user null_conversion
 #define convert_vm_from_user null_conversion
 typedef long_natural_t rpc_long_natural_t;
+typedef long_integer_t rpc_long_integer_t;
 #endif /* MACH_KERNEL */
 
 #endif /* __ASSEMBLER__ */
diff --git a/include/mach/mach_types.defs b/include/mach/mach_types.defs
index 74b85232..da74a3f2 100644
--- a/include/mach/mach_types.defs
+++ b/include/mach/mach_types.defs
@@ -261,7 +261,18 @@ type kernel_version_t              = 
(MACH_MSG_TYPE_STRING, 512*8);
 
 type kernel_boot_info_t                = (MACH_MSG_TYPE_STRING, 4096*8);
 
-type time_value_t              = struct[2] of integer_t;
+type rpc_time_value_t          = struct {
+  rpc_long_integer_t seconds;
+  integer_t microseconds;
+};
+type time_value_t = rpc_time_value_t
+#if defined(KERNEL_SERVER)
+    intran: time_value_t convert_time_value_from_user(rpc_time_value_t)
+    outtran: rpc_time_value_t convert_time_value_to_user(time_value_t)
+#elif defined(KERNEL_USER)
+    ctype: rpc_time_value_t
+#endif
+    ;
 
 type emulation_vector_t                = ^array[] of vm_offset_t;
 
diff --git a/include/mach/time_value.h b/include/mach/time_value.h
index 3a9c384c..53692bcf 100644
--- a/include/mach/time_value.h
+++ b/include/mach/time_value.h
@@ -33,12 +33,37 @@
  *     Time value returned by kernel.
  */
 
+struct rpc_time_value {
+       /* TODO: this should be 64 bits regardless of the arch to be Y2038 
proof. */
+       rpc_long_integer_t seconds;
+       integer_t microseconds;
+};
+typedef struct rpc_time_value rpc_time_value_t;
+
+/*
+ *     Time value used by kernel.
+ */
 struct time_value {
-       integer_t       seconds;
+       long_integer_t  seconds;
        integer_t       microseconds;
 };
 typedef        struct time_value       time_value_t;
 
+/**
+ * Functions used by Mig to perform user to kernel conversion and vice-versa.
+ * We only do this because we may run a 64 bit kernel with a 32 bit user space.
+ */
+static inline rpc_time_value_t convert_time_value_to_user(time_value_t tv)
+{
+       rpc_time_value_t user = {.seconds = tv.seconds, .microseconds = 
tv.microseconds};
+       return user;
+}
+static inline time_value_t convert_time_value_from_user(rpc_time_value_t tv)
+{
+       time_value_t kernel = {.seconds = tv.seconds, .microseconds = 
tv.microseconds};
+       return kernel;
+}
+
 /*
  *     Macros to manipulate time values.  Assume that time values
  *     are normalized (microseconds <= 999999).
-- 
2.37.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]