To illustrate some points to consider when using virtual_copy suppose that you are writing a system call for a user process to get a copy of the kernel's mem_map struct for the process. That mem_map is in the process table at the entry for the user process.
You will need to write one system call from the user process to the process manager and then a task call from the process manager to the system task.
The user cannot send its endpoint value, but the process manager can get this value from the pm's process table. The process manager can then insert the user's endpoint value in a message used in the taskcall to the system task.
The user also needs to insert information in the message used in the system call for a struct mem_map declared in the user's address space to receive the kernel's copy. The virtual address of this struct is specified by the segment and by the offset within the segment. So this requires a bit of reflection. The user can clearly pass the address of its struct mem_map in the system call (i.e. it can be inserted into the message sent in the system call to the process manager). Is this the offset? Which segment is it? Data, Stack, or possibly even the Text segment?