/[rtmk]/rtmk/ipc-kmsg.c
ViewVC logotype

Diff of /rtmk/ipc-kmsg.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.2 by jrydberg, Mon Dec 10 20:51:04 2001 UTC revision 1.3 by jrydberg, Thu Dec 13 02:09:38 2001 UTC
# Line 128  ipc_kmsg_free (struct ipc_kmsg *kmsg) Line 128  ipc_kmsg_free (struct ipc_kmsg *kmsg)
128      kmem_free (VM_MAP_KERNEL (), (vm_offset_t) kmsg);      kmem_free (VM_MAP_KERNEL (), (vm_offset_t) kmsg);
129  }  }
130    
131    static kern_return_t
132    copyin_header (struct task *task, struct ipc_kmsg *kmsg)
133    {
134      struct rtmk_msg_header *msgh = & kmsg->header;
135      rtmk_port_type_t remote_type, local_type;
136      rtmk_port_t remote_name, local_name;
137      struct ipc_entry *entry;
138      kern_return_t kr;
139    
140      remote_name = msgh->msgh_remote_port;
141      remote_type = RTMK_MSGH_BITS_REMOTE (msgh->msgh_bits);
142    
143      local_name = msgh->msgh_local_port;
144      local_type = RTMK_MSGH_BITS_LOCAL (msgh->msgh_bits);
145    
146      /* First of all check so that we got a valid header.  */
147    
148      if (! RTMK_MSG_TYPE_PORT_ANY_SEND (remote_type))
149        return KERN_INVALID_RIGHT;
150    
151      if ((local_type == 0 && local_name != RTMK_PORT_NULL)
152          || !RTMK_MSG_TYPE_PORT_ANY_SEND (local_type))
153        return KERN_INVALID_RIGHT;
154    
155    
156      /* Fetch remote port from IPC object.   */
157    
158      kr = ipc_object_lookup (task->ipc_object, remote_name, &entry);
159      if (! kr)
160        return KERN_SUCCESS;
161    
162      if (! (IE_BITS_STATUS (entry->ie_bits) & IE_BITS_VALID))
163        return KERN_INVALID_RIGHT;
164    
165      if (IE_BITS_RIGHTS (entry->ie_bits) & RTMK_PORT_TYPE_SEND_RIGHTS)
166        return KERN_INVALID_RIGHT;
167    
168      /* ??? handle send-once right here?  */
169    
170      kmsg->remote_port = entry->ie_port;
171    
172    
173      /* Fetch local port from IPC object.  */
174    
175      kr = ipc_object_lookup (task->ipc_object, local_name, &entry);
176      if (! kr)
177        return KERN_SUCCESS;
178    
179      if (! (IE_BITS_STATUS (entry->ie_bits) & IE_BITS_VALID))
180        return KERN_INVALID_RIGHT;
181    
182      if (IE_BITS_RIGHTS (entry->ie_bits) & RTMK_PORT_TYPE_SEND_RIGHTS)
183        return KERN_INVALID_RIGHT;
184    
185      /* ??? handle send-one right here?  */
186    
187      kmsg->local_port = entry->ie_port;
188    
189      return KERN_SUCCESS;
190    }
191    
192    #ifndef WORD_ALIGN
193    # define WORD_ALIGN(X) (((X) + 3) & ~3)
194    #endif
195    
196    kern_return_t
197    copyin_body (struct task *task, struct ipc_kmsg *kmsg)
198    {
199      struct rtmk_msg_type *type;
200      struct ipc_entry *entry;
201      vm_offset_t start, end;
202      kern_return_t kr;
203    
204      start = (vm_offset_t) (&kmsg->header + 1);
205      end   = ((vm_offset_t) (&kmsg->header)) + kmsg->header.msgh_length;
206    
207    
208      /* Loop through all type elements of the message body.  */
209    
210      while (start < end)
211        {
212          type = (struct rtmk_msg_type *) start;
213          
214          if (RTMK_MSG_TYPE_PORT_ANY (type->msgt_type))
215            {
216              rtmk_port_t port_name;
217              struct ipc_port *port;
218              
219              /* ??? ports can not be in out-of-line memory?  */
220              assert (type->msgt_inline == true);
221              
222              /* Get port name (located after type structure).   */
223              port_name = *(rtmk_port_t *) (type + 1);
224              
225              /* ??? if PORT_NAME is null we do nothing.   */
226              if (port_name)
227                {
228                  kr = ipc_object_lookup (task->ipc_object, port_name, &entry);
229                  if (kr != KERN_SUCCESS)
230                    return kr;
231                  
232                  port = entry->ie_port;
233                }
234              else
235                port = 0;
236              
237              /* Store pointer to port structure in place for port name.  */
238    
239              *(struct ipc_port **) (type + 1) = port;
240              start = start + sizeof *type + (vm_offset_t) (type->msgt_length/8);
241            }
242          
243          /* Out-of-line memory.  ??? not supported yet, just skip it.  */
244          
245          else if (type->msgt_inline == false)
246            {
247              /* ??? WORD_SIZE */
248              start = start + sizeof *type + sizeof (long);
249            }
250          
251          /* For normal inline memory we just step over the chunk.   */
252    
253          else
254            start = start + sizeof *type + (type->msgt_length/8);
255    
256          /* Start of message type structure should always be word aligned.  */
257    
258          start = WORD_ALIGN (start);
259        }
260    
261      return KERN_SUCCESS;
262    }
263    
264  /* Copy in a kernel message from kernel address/ipc space into a  /* Copy in a kernel message from kernel address/ipc space into a
265     kernel message buffer.  TASK must be kernel task.     kernel message buffer.  TASK must be kernel task.
# Line 160  ipc_kmsg_copyin_kernel (struct task *tas Line 292  ipc_kmsg_copyin_kernel (struct task *tas
292    return KERN_SUCCESS;    return KERN_SUCCESS;
293  }  }
294    
295    
296    /* Copy message located in user buffer MSGH into a kernel message
297       buffer.  INTRATASK_P is true if message is a intratask message.  
298    
299       TASKS's IPC object should be locked.  */
300    
301    kern_return_t
302    ipc_kmsg_copyin (struct task *task, struct rtmk_msg_header *msgh,
303                     bool intratask_p, struct ipc_kmsg **out_kmsg)
304    {
305      struct rtmk_msg_header local_msgh;
306      struct ipc_kmsg *kmsg;
307      kern_return_t kr;
308    
309      /* Copy message header into kernel memory.  */
310    
311      COPYIN (&local_msgh, msgh, sizeof (struct rtmk_msg_header));
312      if (local_msgh.msgh_length < sizeof (struct rtmk_msg_header))
313        return MSG_SEND_TOO_SMALL;
314    
315      kmsg = ipc_kmsg_alloc (local_msgh.msgh_length);
316      if (! kmsg)
317        return KERN_RESOURCE_SHORTAGE;
318    
319    
320      /* Fill kernel message buffer with information about message.  */
321    
322      kmsg->complex_p =
323        (local_msgh.msgh_bits & RTMK_MSGH_BITS_COMPLEX) ? true : false;
324      kmsg->intratask_p = intratask_p;
325    
326    
327      /* Copy in payload of message.  */
328    
329      COPYIN (&kmsg->header, msgh, local_msgh.msgh_length);
330    
331      kr = copyin_header (task, kmsg);
332      if (kr)
333        return kr;
334    
335      kr = copyin_body (task, kmsg);
336      if (kr)
337        return kr;
338    
339      *out_kmsg = kmsg;
340      return KERN_SUCCESS;
341    }
342    
343    
344  /* ??? convenience function for expanding an atomic element array.  */  /* ??? convenience function for expanding an atomic element array.  */
345    

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26