[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] Use struct for time_value_t and define seconds as long_integ
From: |
Samuel Thibault |
Subject: |
Re: [PATCH] Use struct for time_value_t and define seconds as long_integer_t. |
Date: |
Sat, 17 Dec 2022 03:24:52 +0100 |
User-agent: |
NeoMutt/20170609 (1.8.3) |
Applied, thanks!
Flavio Cruz, le ven. 16 déc. 2022 21:06:25 -0500, a ecrit:
> 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.
Yes, I was thinking that we'd just switch to 64bit time with the 64bit
kernel.
We have the same issue with the device_read/write operations, for which
we'd want to make the offset 64bit.
Samuel
> ---
> 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
>
>
--
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.