Mixing 32 and 64 bit userspace tasks (was: Re: [PATCH gnumach] Define rpc_vm_size_array_t and rpc_vm_offset_array_t)

2023-02-03 Thread Luca Dariz

Il 01/02/23 10:36, Sergey Bugaev ha scritto:

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.


Actually, yes, that's what I've been thinking about. Currently
vm_size_t & friends are conditionally (but statically) defined to
either MACH_MSG_TYPE_INTEGER_32 or MACH_MSG_TYPE_INTEGER_64. But what
if we also had MACH_MSG_TYPE_INTEGER_PTRSIZE (name TBD), which would
be equivalent to MACH_MSG_TYPE_INTEGER_{32,64} for {32,64}-bit tasks;
but the kernel would know about this and change its size accordingly
when transferring messages between 64- and 32-bit tasks. A value sent
as MACH_MSG_TYPE_INTEGER_32 is always received as
MACH_MSG_TYPE_INTEGER_32, no matter if the intent was to send a
pointer-sized value, whereas a 32-bit value sent by a 32-bit task as
MACH_MSG_TYPE_INTEGER_PTRSIZE would get received as a 64-bit value,
still MACH_MSG_TYPE_INTEGER_PTRSIZE, by a 64-bit task.


While this shouldn't be a problem for normal data transfers, where the 
kernel already copies the data from one task to the other adjusting the 
size of vm fields, I wonder if there are cases where the virtual address 
is not supposed to be translated between tasks, e.g. if we really need 
to send a task-specific virtual address. For example, are there cases 
where a task allocates memory on behalf of another task? (except for the 
exec task)




This would allow 32- and 64- bit tasks (including the kernel task) to
communicate transparently, without requiring separate rpc_* versions
of all the pointer-sized types. Possibly. Maybe. Uness there are a lot
of subtler details to this, which there of course are.
I think a more difficult case is the rpc_time_value_t type, but this 
case could be solved by adding yet another MACH_MSG_TYPE_TIME_VALUE value.


However the problem exists for any struct type (which are just int[] of 
fixed size in mig), because there could be differences due to both 
alignment and pointer-type fields. So either the kernel knows all the 
data structures exchanged by user-space tasks, or the task needs to 
handle a message differently depending if the sender is a 32 or 64 bit 
task. Maybe this could be handled by the mig stubs, I'm not sure. The 
information about the sending task could be encoded in one of the unused 
bits of the msg header.


Something similar to rpc_ types would still be needed for regular 
syscalls, but then they could be renamed to vm_offset_32_t and similar, 
since syscalls would have different entry points.



But I'm sure it has been a conscious decision to go with the current
design and not this way?


For the parts that I wrote, the choice was based on some information 
that I found in the wiki, on irc and to some extent it seemed faster to 
implement. Considering the above issue with struct, I'm not sure how 
much a new vm type would simplify message handling.



I'm also not arguing that mixing 32- and 64-bit tasks is worth
supporting. This was a hard requirement for OS X, since they had to be
able to run existing proprietary binaries unmodified. We build
everything from source, so just having all of the userland be 64-bit
(and fixing any issues we find on the way) sounds very viable. Using
32-bit win32 software via Wine has been the single reason to run
32-bit processes on my GNU/Linux system, but apparently that's now
changing too (WoW64). And I don't know how relevant using Wine on the
Hurd is anyway.


Maybe one advantage could be a reduced memory usage for 32-bit subhurds, 
if we want also 64-bit subhurds on the same machine.



Luca




Re: [PATCH gnumach] Define rpc_vm_size_array_t and rpc_vm_offset_array_t

2023-02-01 Thread Samuel Thibault
Flávio Cruz, le mer. 01 févr. 2023 03:40:38 -0500, a ecrit:
> One could imagine adding new RPCs with parameters that are compatible
> on both archs to avoid doing any translation.
> It might be less work than waiting for all userland to be 64 bit ready.

64bit userland won't be that much work actually. There is some work in
glibc, but it's really not very invasive, and we can just extend a lot
of the 32bit code.

Samuel



Re: [PATCH gnumach] Define rpc_vm_size_array_t and rpc_vm_offset_array_t

2023-02-01 Thread Sergey Bugaev
On Tue, Jan 31, 2023 at 10:54 PM Luca  wrote:
> 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).
>
> 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.

Actually, yes, that's what I've been thinking about. Currently
vm_size_t & friends are conditionally (but statically) defined to
either MACH_MSG_TYPE_INTEGER_32 or MACH_MSG_TYPE_INTEGER_64. But what
if we also had MACH_MSG_TYPE_INTEGER_PTRSIZE (name TBD), which would
be equivalent to MACH_MSG_TYPE_INTEGER_{32,64} for {32,64}-bit tasks;
but the kernel would know about this and change its size accordingly
when transferring messages between 64- and 32-bit tasks. A value sent
as MACH_MSG_TYPE_INTEGER_32 is always received as
MACH_MSG_TYPE_INTEGER_32, no matter if the intent was to send a
pointer-sized value, whereas a 32-bit value sent by a 32-bit task as
MACH_MSG_TYPE_INTEGER_PTRSIZE would get received as a 64-bit value,
still MACH_MSG_TYPE_INTEGER_PTRSIZE, by a 64-bit task.

This would allow 32- and 64- bit tasks (including the kernel task) to
communicate transparently, without requiring separate rpc_* versions
of all the pointer-sized types. Possibly. Maybe. Uness there are a lot
of subtler details to this, which there of course are.

But I'm sure it has been a conscious decision to go with the current
design and not this way?

I'm also not arguing that mixing 32- and 64-bit tasks is worth
supporting. This was a hard requirement for OS X, since they had to be
able to run existing proprietary binaries unmodified. We build
everything from source, so just having all of the userland be 64-bit
(and fixing any issues we find on the way) sounds very viable. Using
32-bit win32 software via Wine has been the single reason to run
32-bit processes on my GNU/Linux system, but apparently that's now
changing too (WoW64). And I don't know how relevant using Wine on the
Hurd is anyway.

Thoughts?

Sergey



Re: [PATCH gnumach] Define rpc_vm_size_array_t and rpc_vm_offset_array_t

2023-02-01 Thread Flávio Cruz
On Tue, Jan 31, 2023 at 2:54 PM Luca  wrote:

> 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).
>

I think mixing different user space servers built for 32 bits and 64 bits
together would
require a similar translation (and we do have some types that are
incompatible).
One could imagine adding new RPCs with parameters that are compatible
on both archs to avoid doing any translation.
It might be less work than waiting for all userland to be 64 bit ready.


> >> 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
>
>


Re: [PATCH gnumach] Define rpc_vm_size_array_t and rpc_vm_offset_array_t

2023-01-31 Thread Samuel Thibault
Applied, thanks!

Flavio Cruz, le mar. 31 janv. 2023 01:08:09 -0500, a ecrit:
> When generating stubs, Mig will will take the vm_size_array_t and define the
> input request struct using rpc_vm_size_t since the size is variable. This 
> will turn cause a mismatch
> between types (vm_size_t* vs rpc_vm_size_t*). We could also ask Mig to produce
> a prototype by using rpc_vm_size_t*, however we would need to change the 
> implementation
> of the RPC to use rpc_* types anyway since we want to avoid another allocation
> of the array.
> ---
>  i386/include/mach/i386/vm_types.h |  3 +++
>  include/mach/mach4.defs   |  8 +---
>  vm/memory_object_proxy.c  |  6 +++---
>  vm/memory_object_proxy.h  |  8 
>  vm/vm_map.c   | 13 +++--
>  5 files changed, 18 insertions(+), 20 deletions(-)
> 
> diff --git a/i386/include/mach/i386/vm_types.h 
> b/i386/include/mach/i386/vm_types.h
> index 663f920a..bd07ef26 100644
> --- a/i386/include/mach/i386/vm_types.h
> +++ b/i386/include/mach/i386/vm_types.h
> @@ -158,6 +158,9 @@ typedef long_integer_t rpc_long_integer_t;
>  #define convert_long_natural_to_user convert_vm_to_user
>  #define convert_long_natural_from_user convert_vm_from_user
>  
> +typedef  rpc_vm_size_t * rpc_vm_size_array_t;
> +typedef  rpc_vm_offset_t *   rpc_vm_offset_array_t;
> +
>  #endif   /* __ASSEMBLER__ */
>  
>  /*
> diff --git a/include/mach/mach4.defs b/include/mach/mach4.defs
> index 53cca7d3..d63d6f77 100644
> --- a/include/mach/mach4.defs
> +++ b/include/mach/mach4.defs
> @@ -108,14 +108,16 @@ skip/* pc_sampling reserved 4*/;
> protection MAX_PROTECTION and return it in *PORT.  */
>  type vm_offset_array_t = array[*:1024] of vm_offset_t;
>  type vm_size_array_t = array[*:1024] of vm_size_t;
> +type rpc_vm_size_array_t = array[*:1024] of rpc_vm_size_t;
> +type rpc_vm_offset_array_t = array[*:1024] of rpc_vm_offset_t;
>  routine memory_object_create_proxy(
>   task: ipc_space_t;
>   max_protection  : vm_prot_t;
>   object  : memory_object_array_t =
> array[*:1024] of mach_port_send_t;
> - offset  : vm_offset_array_t;
> - start   : vm_offset_array_t;
> - len : vm_size_array_t;
> + offset  : rpc_vm_offset_array_t;
> + start   : rpc_vm_offset_array_t;
> + len : rpc_vm_size_array_t;
>   out proxy   : mach_port_t);
>  
>  /* Gets a proxy to the region that ADDRESS belongs to, starting at the region
> diff --git a/vm/memory_object_proxy.c b/vm/memory_object_proxy.c
> index 46a57932..0f1e75e5 100644
> --- a/vm/memory_object_proxy.c
> +++ b/vm/memory_object_proxy.c
> @@ -133,9 +133,9 @@ memory_object_proxy_notify (mach_msg_header_t *msg)
>  kern_return_t
>  memory_object_create_proxy (ipc_space_t space, vm_prot_t max_protection,
>   ipc_port_t *object, natural_t object_count,
> - vm_offset_t *offset, natural_t offset_count,
> - vm_offset_t *start, natural_t start_count,
> - vm_size_t *len, natural_t len_count,
> + rpc_vm_offset_t *offset, natural_t offset_count,
> + rpc_vm_offset_t *start, natural_t start_count,
> + rpc_vm_size_t *len, natural_t len_count,
>   ipc_port_t *port)
>  {
>memory_object_proxy_t proxy;
> diff --git a/vm/memory_object_proxy.h b/vm/memory_object_proxy.h
> index 97f20b36..8b3f2025 100644
> --- a/vm/memory_object_proxy.h
> +++ b/vm/memory_object_proxy.h
> @@ -36,12 +36,4 @@ extern kern_return_t memory_object_proxy_lookup 
> (ipc_port_t port,
>   vm_offset_t *start,
>   vm_offset_t *len);
>  
> -extern kern_return_t
> -memory_object_create_proxy (ipc_space_t space, vm_prot_t max_protection,
> - ipc_port_t *object, natural_t object_count,
> - vm_offset_t *offset, natural_t offset_count,
> - vm_offset_t *start, natural_t start_count,
> - vm_size_t *len, natural_t len_count,
> - ipc_port_t *port);
> -
>  #endif /* _VM_MEMORY_OBJECT_PROXY_H_ */
> diff --git a/vm/vm_map.c b/vm/vm_map.c
> index bea84a4d..23c4c296 100644
> --- a/vm/vm_map.c
> +++ b/vm/vm_map.c
> @@ -4804,7 +4804,8 @@ vm_region_create_proxy (task_t task, vm_address_t 
> address,
>kern_return_t ret;
>vm_map_entry_t entry, tmp_entry;
>vm_object_t object;
> -  vm_offset_t offset, start;
> +  rpc_vm_offset_t rpc_offset, rpc_start;
> +  rpc_vm_size_t rpc_len = (rpc_vm_size_t) len;
>ipc_port_t pager;
>  
>if (task == TASK_NULL)
> @@ -4840,16 +4841,16 @@ vm_region_create_proxy (task_t task, vm_address_t 

Re: [PATCH gnumach] Define rpc_vm_size_array_t and rpc_vm_offset_array_t

2023-01-31 Thread Luca

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



Re: [PATCH gnumach] Define rpc_vm_size_array_t and rpc_vm_offset_array_t

2023-01-31 Thread Sergey Bugaev
Replying to myself after looking at the definition:

On Tue, Jan 31, 2023 at 12:06 PM Sergey Bugaev  wrote:
>
> 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.

> 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".

> 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.

Did I get it right?

Sergey



Re: [PATCH gnumach] Define rpc_vm_size_array_t and rpc_vm_offset_array_t

2023-01-31 Thread Sergey Bugaev
On Tue, Jan 31, 2023 at 9:08 AM Flavio Cruz  wrote:
>
> When generating stubs, Mig will will take the vm_size_array_t and define the
> input request struct using rpc_vm_size_t since the size is variable. This 
> will turn cause a mismatch
> between types (vm_size_t* vs rpc_vm_size_t*). We could also ask Mig to produce
> a prototype by using rpc_vm_size_t*, however we would need to change the 
> implementation
> of the RPC to use rpc_* types anyway since we want to avoid another allocation
> of the array.

For someone as uninitiated as myself, could you please explain the
deal with these rpc_* types? (Or point me to some docs, if they
exist...)

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?). But how are they different to
plain vm_size_t etc, 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?

Thanks,
Sergey



[PATCH gnumach] Define rpc_vm_size_array_t and rpc_vm_offset_array_t

2023-01-30 Thread Flavio Cruz
When generating stubs, Mig will will take the vm_size_array_t and define the
input request struct using rpc_vm_size_t since the size is variable. This will 
turn cause a mismatch
between types (vm_size_t* vs rpc_vm_size_t*). We could also ask Mig to produce
a prototype by using rpc_vm_size_t*, however we would need to change the 
implementation
of the RPC to use rpc_* types anyway since we want to avoid another allocation
of the array.
---
 i386/include/mach/i386/vm_types.h |  3 +++
 include/mach/mach4.defs   |  8 +---
 vm/memory_object_proxy.c  |  6 +++---
 vm/memory_object_proxy.h  |  8 
 vm/vm_map.c   | 13 +++--
 5 files changed, 18 insertions(+), 20 deletions(-)

diff --git a/i386/include/mach/i386/vm_types.h 
b/i386/include/mach/i386/vm_types.h
index 663f920a..bd07ef26 100644
--- a/i386/include/mach/i386/vm_types.h
+++ b/i386/include/mach/i386/vm_types.h
@@ -158,6 +158,9 @@ typedef long_integer_t rpc_long_integer_t;
 #define convert_long_natural_to_user convert_vm_to_user
 #define convert_long_natural_from_user convert_vm_from_user
 
+typedefrpc_vm_size_t * rpc_vm_size_array_t;
+typedefrpc_vm_offset_t *   rpc_vm_offset_array_t;
+
 #endif /* __ASSEMBLER__ */
 
 /*
diff --git a/include/mach/mach4.defs b/include/mach/mach4.defs
index 53cca7d3..d63d6f77 100644
--- a/include/mach/mach4.defs
+++ b/include/mach/mach4.defs
@@ -108,14 +108,16 @@ skip  /* pc_sampling reserved 4*/;
protection MAX_PROTECTION and return it in *PORT.  */
 type vm_offset_array_t = array[*:1024] of vm_offset_t;
 type vm_size_array_t = array[*:1024] of vm_size_t;
+type rpc_vm_size_array_t = array[*:1024] of rpc_vm_size_t;
+type rpc_vm_offset_array_t = array[*:1024] of rpc_vm_offset_t;
 routine memory_object_create_proxy(
task: ipc_space_t;
max_protection  : vm_prot_t;
object  : memory_object_array_t =
  array[*:1024] of mach_port_send_t;
-   offset  : vm_offset_array_t;
-   start   : vm_offset_array_t;
-   len : vm_size_array_t;
+   offset  : rpc_vm_offset_array_t;
+   start   : rpc_vm_offset_array_t;
+   len : rpc_vm_size_array_t;
out proxy   : mach_port_t);
 
 /* Gets a proxy to the region that ADDRESS belongs to, starting at the region
diff --git a/vm/memory_object_proxy.c b/vm/memory_object_proxy.c
index 46a57932..0f1e75e5 100644
--- a/vm/memory_object_proxy.c
+++ b/vm/memory_object_proxy.c
@@ -133,9 +133,9 @@ memory_object_proxy_notify (mach_msg_header_t *msg)
 kern_return_t
 memory_object_create_proxy (ipc_space_t space, vm_prot_t max_protection,
ipc_port_t *object, natural_t object_count,
-   vm_offset_t *offset, natural_t offset_count,
-   vm_offset_t *start, natural_t start_count,
-   vm_size_t *len, natural_t len_count,
+   rpc_vm_offset_t *offset, natural_t offset_count,
+   rpc_vm_offset_t *start, natural_t start_count,
+   rpc_vm_size_t *len, natural_t len_count,
ipc_port_t *port)
 {
   memory_object_proxy_t proxy;
diff --git a/vm/memory_object_proxy.h b/vm/memory_object_proxy.h
index 97f20b36..8b3f2025 100644
--- a/vm/memory_object_proxy.h
+++ b/vm/memory_object_proxy.h
@@ -36,12 +36,4 @@ extern kern_return_t memory_object_proxy_lookup (ipc_port_t 
port,
  vm_offset_t *start,
  vm_offset_t *len);
 
-extern kern_return_t
-memory_object_create_proxy (ipc_space_t space, vm_prot_t max_protection,
-   ipc_port_t *object, natural_t object_count,
-   vm_offset_t *offset, natural_t offset_count,
-   vm_offset_t *start, natural_t start_count,
-   vm_size_t *len, natural_t len_count,
-   ipc_port_t *port);
-
 #endif /* _VM_MEMORY_OBJECT_PROXY_H_ */
diff --git a/vm/vm_map.c b/vm/vm_map.c
index bea84a4d..23c4c296 100644
--- a/vm/vm_map.c
+++ b/vm/vm_map.c
@@ -4804,7 +4804,8 @@ vm_region_create_proxy (task_t task, vm_address_t address,
   kern_return_t ret;
   vm_map_entry_t entry, tmp_entry;
   vm_object_t object;
-  vm_offset_t offset, start;
+  rpc_vm_offset_t rpc_offset, rpc_start;
+  rpc_vm_size_t rpc_len = (rpc_vm_size_t) len;
   ipc_port_t pager;
 
   if (task == TASK_NULL)
@@ -4840,16 +4841,16 @@ vm_region_create_proxy (task_t task, vm_address_t 
address,
   pager = ipc_port_copy_send(object->pager);
   vm_object_unlock(object);
 
-  start = (address - entry->vme_start) + entry->offset;
-  offset = 0;
+  rpc_start = (address - entry->vme_start) + entry->offset;
+  rpc_offset = 0;