bug-hurd
[Top][All Lists]
Advanced

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

Re: [PATCH mig] Make MIG work for pure 64 bit kernel and userland.


From: Luca Dariz
Subject: Re: [PATCH mig] Make MIG work for pure 64 bit kernel and userland.
Date: Thu, 16 Feb 2023 22:19:27 +0100

Hi Sergey,

thanks a lot for the detailed explanation!

Il 12/02/23 19:16, Sergey Bugaev ha scritto:
But look at what Apple MIG does:

typedef struct {
     mach_msg_header_t Head;
     /* start of the kernel processed data */
     mach_msg_body_t msgh_body;
     mach_msg_port_descriptor_t port_arg;
     /* end of the kernel processed data */
     NDR_record_t NDR;
     int int_arg;
} Request

typedef struct {
     mach_msg_header_t Head;
     /* start of the kernel processed data */
     mach_msg_body_t msgh_body;
     mach_msg_port_descriptor_t out_port_arg;
     /* end of the kernel processed data */
     mach_msg_trailer_t trailer;
} Reply;

...

After the descriptors, we once again have an uninterpreted message
body where MIG puts all the data arguments into (here, NDR and the
int_arg).

With this layout alignment issues seem much simpler to solve, basically we can leave the compiler find the best combination for the second part of the message, and if the user/kernel archs are the same, the struct will have the same layout in the sending and receiving mig stubs.

One last thing though, we should still make sure that the struct starting address is correctly aligned, right? Otherwise this could blow up all the compiler's effort to find the correct alignment for the internal fields.

For example, if we have this struct on x86_64 (not using mig types for simplicity):

struct {
        int a;    // 4 bytes
        char *b;  // 8 bytes
};

and let's say that the compiler places an empty space of 4 bytes between the fields "a" and "b", so the "b" field is aligned to 8 bytes. This assumes that also the starting address (where "a" is stored) is aligned at least to 8 bytes.

If we declare a structure, e.g. as a local variable, the compiler will align also the starting address, but if we convert a buffer to a pointer of that struct, it's our responsibility to make sure that the buffer is properly aligned.

In gnumach, in particular the ipc_kmsg_* functions, thin means that the ipc_kmsg_t struct must have the ikm_header field at a correct alignment, which could be 16 bytes or more, because the message is copied here with copyinmsg(), and for rpcs handled by the kernel, this is passed to the mig stubs.

I see that a kmsg is allocated with kalloc, so I guess that we need somehow to make sure that kalloc returns a memory chunk with the correct alignment. But from what I can see from a quick look, it seems that no particular alignment is enforced (i.e. where available, align=0).

Is this correct? Or did I miss something?


Attaching: two PostScript documents that describe this in some more
detail. It's not very easy to find Mach documentation on the web
nowadays. You can spend hours searching Google for "Untyped MIG" and
still would not find much.

Indeed, I couldn't find much information about this topic without a deep search. Thanks!

Luca



reply via email to

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