Hi Sergey,

Il 31/01/23 14:30, Sergey Bugaev ha scritto:
I understand they are related to the x64 bringup, and possibly to
running 32-bit userland on a 64-bit kernel (or to support for 32-bit
tasks communicating with 64-bit tasks?).

It's hust for running 32-bit userland on 64-bit kernel (USER32).
Mixing 32- and 64-bit tasks on the same system does not seem to be
supported at all, and in fact you must build the Mach with USER32
either defined or not, you cannot have it both ways. Unlike in XNU.

That's right, USER32 is just a simple way to isolate the code specific for 32-bit userland (mainly size conversions for pointers and vm_* types). I think it would be possible to handle both a 32-bit and a 64-bit userspace at the same time, as in XNU, but we'd need also user-space support if we want to integrate 32-bit and 64-bit tasks, and this seems a bit more complicated to me (although I have to admit, so far I know better the kernel part).

But how are they different to
plain vm_size_t etc,

When running in full/native 64- (or 32-) bit mode, both rpc_vm_size_t
and vm_size_t will be of the same, well, size. But with USER32,
vm_size_t will be 64-bits wide, while rpc_vm_size_t will be 32-bits
wide. In other words, rpc_vm_size_t is "the userspace's idea of
vm_size_t".

yes, in the kernel we need to make such distinction, mainly to be able to use the current 32-bit userspace on a 64-bit kernel. The difference for the rpc_* types is only about the size and placement in memory, not the content (except for the cases where conversion would not be possible, but this would be a bug).

and when am I supposed to use one vs the other?
Does this only concern kernel land (i.e. GNU Mach) or the userland
too?

In userland, always use the regular variants. In MIG defs, use the
rpc_*variants. For the most part, MIG will handle the conversion
automatically (intran: vm_address_t
convert_vm_from_user(rpc_vm_address_t) and the like), so the
KernelServer routines can use the regular types already. That is,
except for particular cases like this one, where we have an array of
offsets/sizes which of course cannot be just converted in-place.

I think there is no need to use the rpc_* types in userspace, they can be ignored since the rpc_* variant should be always the same as the corresponding regular type. The kernel will handle the conversion, if needed, eventually with mig.

The array case is a bit special, as mig doesn't allow to handle the conversion in the same way as vm_offset_t and similar, and I think it's the reason for using the rpc_* types directly in the .defs files. I have the impression it would not be simple to add it, but fortunately this feature doesn't seem to be used a lot, at least in the kernel rpc. The only uses should be for memory objects (as in this patch) and syscall emulation (which seems unused in hurd and glibc)).

Note that another way to handle the size conversion between rpc_* and regular types would be to add some new VM types to include/mach/message.h; in this case, the shrink/expand would happen in copyinmsg()/copyoutmsg() instead of the mig-generated code (as for mach ports), but this approach would require to plan for a staged introduction of this change.

Luca

Reply via email to