Hi Luca, Spent some time doing more testing on this patch since initially I had only tested it on basic programs. After "copyinmsg: allow for the last message element to have msgt_number = 0." <https://git.savannah.gnu.org/cgit/hurd/gnumach.git/commit/?id=2e6b257f39ab90938ac9d425629cdf0897a47e48> it can boot a basic system up to the bash shell. I haven't seen any other issues so far.
On Mon, Jun 5, 2023 at 1:28 PM Luca <l...@orpolo.org> wrote: > Hi, > > Il 17/05/23 05:03, Flavio Cruz ha scritto: > > * Make full use of the 8 bytes available in mach_msg_type_t by moving > > into the unused 4 bytes. This allows us to use 32bits for > > mach_msg_type_number_t whether we use the longform or not. > > * Make mach_msg_type_long_t exactly the same as mach_msg_type_t. I'm not > > changing any of the code but keeping the same interface using macros. > > Updating MiG is strongly encouraged since it will generate better code > > to handle this new format. > > > > After this change, any compatibility with compiled binaries for Hurd > x86_64 > > will break since the message format is different. However, the new > > schema simplifies the overall ABI, without having "holes" and also > > avoids the need to have a 16 byte mach_msg_type_long_t. > > > > Tested with simple programs on pure 64 bit and 64/32 bit combinations > > > --- > > Not too thrilled about the use of the macros for msgtl_name/size/number > > but happy to hear about other alternatives. Potentially we could > > introduce accessors and update all the calls to use them. > > > > Note that the follow up MiG patch is necessary to make this work. > > > > include/mach/message.h | 37 +++++++++++++-- > > ipc/ipc_kmsg.c | 4 ++ > > x86_64/copy_user.c | 100 ++++++++++++++++++++++++++++++++--------- > > 3 files changed, 115 insertions(+), 26 deletions(-) > > > > diff --git a/include/mach/message.h b/include/mach/message.h > > index 0eab9d41..d1783715 100644 > > --- a/include/mach/message.h > > +++ b/include/mach/message.h > > @@ -222,6 +222,30 @@ typedef unsigned int mach_msg_type_size_t; > > typedef natural_t mach_msg_type_number_t; > > > > typedef struct { > > +#ifdef __x86_64__ > > + /* > > + * For 64 bits, this struct is 8 bytes long so we > > + * can pack the same amount of information as mach_msg_type_long_t. > > + * Note that for 64 bit userland, msgt_size only needs to be 8 bits > long > > + * but for kernel compatibility with 32 bit userland we allow it to > be > > + * 16 bits long. > > + * > > + * Effectively, we don't need mach_msg_type_long_t but we are > keeping it > > + * for a while to make the code similar between 32 and 64 bits. > > + * > > + * We also keep the msgt_longform bit around simply because it > makes it > > + * very easy to convert messages from a 32 bit userland into a 64 > bit > > + * kernel. Otherwise, we would have to replicate some of the MiG > logic > > + * internally in the kernel. > > + */ > > + unsigned int msgt_inline : 1, > > + msgt_longform : 1, > > + msgt_deallocate : 1, > > + msgt_name : 8, > > + msgt_size : 16, > > + msgt_unused : 5; > > + mach_msg_type_number_t msgt_number; > > +#else > > unsigned int msgt_name : 8, > > msgt_size : 8, > > msgt_number : 12, > > @@ -229,18 +253,23 @@ typedef struct { > > msgt_longform : 1, > > msgt_deallocate : 1, > > msgt_unused : 1; > > -#ifdef __x86_64__ > > - /* TODO: We want to eventually use this in favor of > mach_msg_type_long_t > > - * as it makes the mach_msg protocol require only mach_msg_type_t. > */ > > - mach_msg_type_number_t unused_msgtl_number; > > #endif > > } __attribute__ ((aligned (__alignof__ (uintptr_t)))) mach_msg_type_t; > > Maybe the user/kernel variants of mach_msg_type_t and > mach_msg_type_long_t should also be moved here from copy_user.c, just as > the header struct (or all the user variants to a kernel-specific header) > Yes, that makes sense, but maybe we can do it in a separate patch? > > +/* On x86_64 this is equivalent to mach_msg_type_t. */ > > typedef struct { > > mach_msg_type_t msgtl_header; > > +#ifdef __x86_64__ > > +/* Since we don't have these separate fields, we remap them > > + * into the fields from mach_msg_type_t. */ > > +#define msgtl_name msgtl_header.msgt_name > > +#define msgtl_size msgtl_header.msgt_size > > +#define msgtl_number msgtl_header.msgt_number > > +#else > > unsigned short msgtl_name; > > unsigned short msgtl_size; > > natural_t msgtl_number; > > +#endif > > } __attribute__ ((aligned (__alignof__ (uintptr_t)))) > mach_msg_type_long_t; > > one alternative to the #defines could be something similar to > > typedef union { > mach_msg_type_t msgtl_header; > struct { > unsigned int msgt_unused1 : 3, > msgt_name : 8, > msgt_size : 16, > msgt_unused2 : 5; > mach_msg_type_number_t msgt_number; > }; > } __attribute__ ((aligned (__alignof__ (uintptr_t)))) > mach_msg_type_long_t; > > This would replicate the definition of the bitfields, but IMHO it would > be more readable than another level of macro. I guess we can ensure both > definitions are consistent with some static asserts. > Thanks, I feel this is better than using macros. Sent version 2. > > Luca > >