Ack. Justus Winter, le Thu 18 Sep 2014 15:22:47 +0200, a écrit : > * ipc/ipc_kmsg.c (ipc_kmsg_copyout_header): If a protected payload is > set for the destination port, provide it in msgh_protected_payload. > * ipc/mach_msg.c (mach_msg_trap): Likewise in the fast paths. > * doc/mach.texi (Message Receive): Document message semantics with > protected payloads. > --- > doc/mach.texi | 19 +++++++++++++++++++ > ipc/ipc_kmsg.c | 58 > +++++++++++++++++++++++++++++++++++++++++++++------------- > ipc/mach_msg.c | 53 ++++++++++++++++++++++++++++++++++++++++------------- > 3 files changed, 104 insertions(+), 26 deletions(-) > > diff --git a/doc/mach.texi b/doc/mach.texi > index b187888..c57e607 100644 > --- a/doc/mach.texi > +++ b/doc/mach.texi > @@ -1949,6 +1949,25 @@ loses the receive right after the message was dequeued > from it, then > right still exists, but isn't held by the caller, then > @code{msgh_local_port} specifies @code{MACH_PORT_NULL}. > > +Servers usually associate some state with a receive right. To that > +end, they might use a hash table to look up the state for the port a > +message was sent to. To optimize this, a task may associate an opaque > +@var{payload} with a receive right using the > +@code{mach_port_set_protected_payload} function. Once this is done, > +the kernel will set the @code{msgh_protected_payload} field to > +@var{payload} when delivering a message to this right and indicate > +this by setting the local part of @code{msgh_bits} to > +@code{MACH_MSG_TYPE_PROTECTED_PAYLOAD}. > + > +The support for protected payloads was added to GNU Mach. To preserve > +binary compatibility, the @code{msgh_local_port} and > +@code{msgh_local_port} share the same location. This makes it > +possible to add the payload information without increasing the size of > +@code{mach_msg_header_t}. This is an implementation detail. Which > +field is valid is determined by the local part of the > +@code{msgh_bits}. Existing software is not affected. When a receive > +right is transferred to another task, its payload is cleared. > + > Received messages are stamped with a sequence number, taken from the > port from which the message was received. (Messages received from a > port set are stamped with a sequence number from the appropriate member > diff --git a/ipc/ipc_kmsg.c b/ipc/ipc_kmsg.c > index 06cec72..71a0d74 100644 > --- a/ipc/ipc_kmsg.c > +++ b/ipc/ipc_kmsg.c > @@ -1799,9 +1799,17 @@ ipc_kmsg_copyout_header( > } else > ip_unlock(dest); > > - msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) | > - MACH_MSGH_BITS(0, MACH_MSG_TYPE_PORT_SEND)); > - msg->msgh_local_port = dest_name; > + if (! ipc_port_flag_protected_payload(dest)) { > + msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) | > + MACH_MSGH_BITS(0, MACH_MSG_TYPE_PORT_SEND)); > + msg->msgh_local_port = dest_name; > + } else { > + msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) | > + MACH_MSGH_BITS( > + 0, MACH_MSG_TYPE_PROTECTED_PAYLOAD)); > + msg->msgh_protected_payload = > + dest->ip_protected_payload; > + } > msg->msgh_remote_port = MACH_PORT_NULL; > return MACH_MSG_SUCCESS; > } > @@ -1897,10 +1905,18 @@ ipc_kmsg_copyout_header( > } else > ip_unlock(dest); > > - msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) | > - MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, > - MACH_MSG_TYPE_PORT_SEND)); > - msg->msgh_local_port = dest_name; > + if (! ipc_port_flag_protected_payload(dest)) { > + msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) | > + MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, > + MACH_MSG_TYPE_PORT_SEND)); > + msg->msgh_local_port = dest_name; > + } else { > + msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) | > + MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, > + MACH_MSG_TYPE_PROTECTED_PAYLOAD)); > + msg->msgh_protected_payload = > + dest->ip_protected_payload; > + } > msg->msgh_remote_port = reply_name; > return MACH_MSG_SUCCESS; > } > @@ -1932,9 +1948,18 @@ ipc_kmsg_copyout_header( > dest_name = MACH_PORT_NULL; > } > > - msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) | > - MACH_MSGH_BITS(0, MACH_MSG_TYPE_PORT_SEND_ONCE)); > - msg->msgh_local_port = dest_name; > + if (! ipc_port_flag_protected_payload(dest)) { > + msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) | > + MACH_MSGH_BITS(0, > + MACH_MSG_TYPE_PORT_SEND_ONCE)); > + msg->msgh_local_port = dest_name; > + } else { > + msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) | > + MACH_MSGH_BITS(0, > + MACH_MSG_TYPE_PROTECTED_PAYLOAD)); > + msg->msgh_protected_payload = > + dest->ip_protected_payload; > + } > msg->msgh_remote_port = MACH_PORT_NULL; > return MACH_MSG_SUCCESS; > } > @@ -2224,9 +2249,16 @@ ipc_kmsg_copyout_header( > if (IP_VALID(reply)) > ipc_port_release(reply); > > - msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) | > - MACH_MSGH_BITS(reply_type, dest_type)); > - msg->msgh_local_port = dest_name; > + if (! ipc_port_flag_protected_payload(dest)) { > + msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) | > + MACH_MSGH_BITS(reply_type, dest_type)); > + msg->msgh_local_port = dest_name; > + } else { > + msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) | > + MACH_MSGH_BITS(reply_type, > + MACH_MSG_TYPE_PROTECTED_PAYLOAD)); > + msg->msgh_protected_payload = dest->ip_protected_payload; > + } > msg->msgh_remote_port = reply_name; > } > > diff --git a/ipc/mach_msg.c b/ipc/mach_msg.c > index 01d974b..1e122c7 100644 > --- a/ipc/mach_msg.c > +++ b/ipc/mach_msg.c > @@ -1132,11 +1132,19 @@ mach_msg_trap( > } else > ip_unlock(dest_port); > > - kmsg->ikm_header.msgh_bits = > - MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, > - MACH_MSG_TYPE_PORT_SEND); > + if (! ipc_port_flag_protected_payload(dest_port)) { > + kmsg->ikm_header.msgh_bits = MACH_MSGH_BITS( > + MACH_MSG_TYPE_PORT_SEND_ONCE, > + MACH_MSG_TYPE_PORT_SEND); > + kmsg->ikm_header.msgh_local_port = dest_name; > + } else { > + kmsg->ikm_header.msgh_bits = MACH_MSGH_BITS( > + MACH_MSG_TYPE_PORT_SEND_ONCE, > + MACH_MSG_TYPE_PROTECTED_PAYLOAD); > + kmsg->ikm_header.msgh_protected_payload = > + dest_port->ip_protected_payload; > + } > kmsg->ikm_header.msgh_remote_port = reply_name; > - kmsg->ikm_header.msgh_local_port = dest_name; > goto fast_put; > > abort_request_copyout: > @@ -1170,11 +1178,19 @@ mach_msg_trap( > dest_name = MACH_PORT_NULL; > } > > - kmsg->ikm_header.msgh_bits = > - MACH_MSGH_BITS(0, > - MACH_MSG_TYPE_PORT_SEND_ONCE); > + if (! ipc_port_flag_protected_payload(dest_port)) { > + kmsg->ikm_header.msgh_bits = MACH_MSGH_BITS( > + 0, > + MACH_MSG_TYPE_PORT_SEND_ONCE); > + kmsg->ikm_header.msgh_local_port = dest_name; > + } else { > + kmsg->ikm_header.msgh_bits = MACH_MSGH_BITS( > + 0, > + MACH_MSG_TYPE_PROTECTED_PAYLOAD); > + kmsg->ikm_header.msgh_protected_payload = > + dest_port->ip_protected_payload; > + } > kmsg->ikm_header.msgh_remote_port = MACH_PORT_NULL; > - kmsg->ikm_header.msgh_local_port = dest_name; > goto fast_put; > } > > @@ -1204,12 +1220,23 @@ mach_msg_trap( > dest_name = MACH_PORT_NULL; > } > > - kmsg->ikm_header.msgh_bits = > - MACH_MSGH_BITS_COMPLEX | > - MACH_MSGH_BITS(0, > - MACH_MSG_TYPE_PORT_SEND_ONCE); > + if (! ipc_port_flag_protected_payload(dest_port)) { > + kmsg->ikm_header.msgh_bits = > + MACH_MSGH_BITS_COMPLEX > + | MACH_MSGH_BITS( > + 0, > + MACH_MSG_TYPE_PORT_SEND_ONCE); > + kmsg->ikm_header.msgh_local_port = dest_name; > + } else { > + kmsg->ikm_header.msgh_bits = > + MACH_MSGH_BITS_COMPLEX > + | MACH_MSGH_BITS( > + 0, > + MACH_MSG_TYPE_PROTECTED_PAYLOAD); > + kmsg->ikm_header.msgh_protected_payload = > + dest_port->ip_protected_payload; > + } > kmsg->ikm_header.msgh_remote_port = MACH_PORT_NULL; > - kmsg->ikm_header.msgh_local_port = dest_name; > > mr = ipc_kmsg_copyout_body( > (vm_offset_t) (&kmsg->ikm_header + 1), > -- > 2.1.0 >
-- Samuel > C'est vrai. FreeBSD pourrait être bien s'il avait une licence > correcte. Oh, mon troll-ô-meter vient d'exploser... -+- OR in Guide du linuxien pervers - "Bien regler son troll-ô-meter"