bug-hurd
[Top][All Lists]
Advanced

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

[PATCH 5/8] ipc: provide the protected payload in ipc_kmsg_copyout_heade


From: Justus Winter
Subject: [PATCH 5/8] ipc: provide the protected payload in ipc_kmsg_copyout_header
Date: Thu, 18 Sep 2014 15:22:47 +0200

* 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




reply via email to

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