kernel: Handle IPC properly at live update time.
Change-Id: I2dfc6c6cf4d2bfe198e159d3e4b7c50d0bb499c8
This commit is contained in:
		
							parent
							
								
									56e56d2af2
								
							
						
					
					
						commit
						062400c0e2
					
				@ -30,6 +30,7 @@ struct priv {
 | 
			
		||||
  size_t s_asynsize;		/* number of elements in table. 0 when not in
 | 
			
		||||
				 * use
 | 
			
		||||
				 */
 | 
			
		||||
  endpoint_t s_asynendpoint;    /* the endpoint the asyn table belongs to. */
 | 
			
		||||
 | 
			
		||||
  short s_trap_mask;		/* allowed system call traps */
 | 
			
		||||
  sys_map_t s_ipc_to;		/* allowed destination processes */
 | 
			
		||||
 | 
			
		||||
@ -1153,6 +1153,7 @@ int try_deliver_senda(struct proc *caller_ptr,
 | 
			
		||||
  /* Clear table */
 | 
			
		||||
  privp->s_asyntab = -1;
 | 
			
		||||
  privp->s_asynsize = 0;
 | 
			
		||||
  privp->s_asynendpoint = caller_ptr->p_endpoint;
 | 
			
		||||
 | 
			
		||||
  if (size == 0) return(OK);  /* Nothing to do, just return */
 | 
			
		||||
 | 
			
		||||
@ -1346,6 +1347,7 @@ static int try_one(endpoint_t receive_e, struct proc *src_ptr,
 | 
			
		||||
  unset_sys_bit(priv(dst_ptr)->s_asyn_pending, privp->s_id);
 | 
			
		||||
 | 
			
		||||
  if (size == 0) return(EAGAIN);
 | 
			
		||||
  if (privp->s_asynendpoint != src_ptr->p_endpoint) return EAGAIN;
 | 
			
		||||
  if (!may_asynsend_to(src_ptr, proc_nr(dst_ptr))) return (ECALLDENIED);
 | 
			
		||||
 | 
			
		||||
  caller_ptr = src_ptr;	/* Needed for A_ macros later on */
 | 
			
		||||
 | 
			
		||||
@ -126,6 +126,7 @@ int do_privctl(struct proc * caller, message * m_ptr)
 | 
			
		||||
	reset_kernel_timer(&priv(rp)->s_alarm_timer);	/* - alarm */
 | 
			
		||||
	priv(rp)->s_asyntab= -1;			/* - asynsends */
 | 
			
		||||
	priv(rp)->s_asynsize= 0;
 | 
			
		||||
	priv(rp)->s_asynendpoint = rp->p_endpoint;
 | 
			
		||||
	priv(rp)->s_diag_sig = FALSE;		/* no request for diag sigs */
 | 
			
		||||
 | 
			
		||||
	/* Set defaults for privilege bitmaps. */
 | 
			
		||||
 | 
			
		||||
@ -23,9 +23,11 @@
 | 
			
		||||
static int inherit_priv_irq(struct proc *src_rp, struct proc *dst_rp);
 | 
			
		||||
static int inherit_priv_io(struct proc *src_rp, struct proc *dst_rp);
 | 
			
		||||
static int inherit_priv_mem(struct proc *src_rp, struct proc *dst_rp);
 | 
			
		||||
static void abort_proc_ipc_send(struct proc *rp);
 | 
			
		||||
static void adjust_proc_slot(struct proc *rp, struct proc *from_rp);
 | 
			
		||||
static void adjust_priv_slot(struct priv *privp, struct priv
 | 
			
		||||
	*from_privp);
 | 
			
		||||
static void adjust_asyn_table(struct priv *src_privp, struct priv *dst_privp);
 | 
			
		||||
static void swap_proc_slot_pointer(struct proc **rpp, struct proc
 | 
			
		||||
	*src_rp, struct proc *dst_rp);
 | 
			
		||||
 | 
			
		||||
@ -38,7 +40,7 @@ int do_update(struct proc * caller, message * m_ptr)
 | 
			
		||||
 * slots.
 | 
			
		||||
 */
 | 
			
		||||
  endpoint_t src_e, dst_e;
 | 
			
		||||
  int src_p, dst_p;
 | 
			
		||||
  int src_p, dst_p, flags;
 | 
			
		||||
  struct proc *src_rp, *dst_rp;
 | 
			
		||||
  struct priv *src_privp, *dst_privp;
 | 
			
		||||
  struct proc orig_src_proc;
 | 
			
		||||
@ -48,6 +50,7 @@ int do_update(struct proc * caller, message * m_ptr)
 | 
			
		||||
  int i, r;
 | 
			
		||||
 | 
			
		||||
  /* Lookup slots for source and destination process. */
 | 
			
		||||
  flags = m_ptr->SYS_UPD_FLAGS;
 | 
			
		||||
  src_e = m_ptr->SYS_UPD_SRC_ENDPT;
 | 
			
		||||
  if(!isokendpt(src_e, &src_p)) {
 | 
			
		||||
      return EINVAL;
 | 
			
		||||
@ -112,6 +115,15 @@ int do_update(struct proc * caller, message * m_ptr)
 | 
			
		||||
  orig_dst_proc = *dst_rp;
 | 
			
		||||
  orig_dst_priv = *(priv(dst_rp));
 | 
			
		||||
 | 
			
		||||
  /* Adjust asyn tables. */
 | 
			
		||||
  adjust_asyn_table(priv(src_rp), priv(dst_rp));
 | 
			
		||||
  adjust_asyn_table(priv(dst_rp), priv(src_rp));
 | 
			
		||||
 | 
			
		||||
  /* Abort any pending send() on rollback. */
 | 
			
		||||
  if(flags & SYS_UPD_ROLLBACK) {
 | 
			
		||||
      abort_proc_ipc_send(src_rp);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Swap slots. */
 | 
			
		||||
  *src_rp = orig_dst_proc;
 | 
			
		||||
  *src_privp = orig_dst_priv;
 | 
			
		||||
@ -195,6 +207,27 @@ int inherit_priv_mem(struct proc *src_rp, struct proc *dst_rp)
 | 
			
		||||
  return OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*===========================================================================*
 | 
			
		||||
 *			    abort_proc_ipc_send				     *
 | 
			
		||||
 *===========================================================================*/
 | 
			
		||||
void abort_proc_ipc_send(struct proc *rp)
 | 
			
		||||
{
 | 
			
		||||
  if(RTS_ISSET(rp, RTS_SENDING)) {
 | 
			
		||||
      struct proc **xpp;
 | 
			
		||||
      RTS_UNSET(rp, RTS_SENDING);
 | 
			
		||||
      rp->p_misc_flags &= ~MF_SENDING_FROM_KERNEL;
 | 
			
		||||
      xpp = &(proc_addr(_ENDPOINT_P(rp->p_sendto_e))->p_caller_q);
 | 
			
		||||
      while (*xpp) {
 | 
			
		||||
          if(*xpp == rp) {
 | 
			
		||||
              *xpp = rp->p_q_link;
 | 
			
		||||
              rp->p_q_link = NULL;
 | 
			
		||||
              break;
 | 
			
		||||
          }
 | 
			
		||||
          xpp = &(*xpp)->p_q_link;
 | 
			
		||||
      }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*===========================================================================*
 | 
			
		||||
 *			     adjust_proc_slot				     *
 | 
			
		||||
 *===========================================================================*/
 | 
			
		||||
@ -205,6 +238,7 @@ static void adjust_proc_slot(struct proc *rp, struct proc *from_rp)
 | 
			
		||||
  rp->p_nr = from_rp->p_nr;
 | 
			
		||||
  rp->p_priv = from_rp->p_priv;
 | 
			
		||||
  priv(rp)->s_proc_nr = from_rp->p_nr;
 | 
			
		||||
 | 
			
		||||
  rp->p_caller_q = from_rp->p_caller_q;
 | 
			
		||||
 | 
			
		||||
  /* preserve scheduling */
 | 
			
		||||
@ -216,6 +250,27 @@ static void adjust_proc_slot(struct proc *rp, struct proc *from_rp)
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*===========================================================================*
 | 
			
		||||
 *			     adjust_asyn_table				     *
 | 
			
		||||
 *===========================================================================*/
 | 
			
		||||
static void adjust_asyn_table(struct priv *src_privp, struct priv *dst_privp)
 | 
			
		||||
{
 | 
			
		||||
  /* Transfer the asyn table if source's table belongs to the destination. */
 | 
			
		||||
  endpoint_t src_e = proc_addr(src_privp->s_proc_nr)->p_endpoint;
 | 
			
		||||
  endpoint_t dst_e = proc_addr(dst_privp->s_proc_nr)->p_endpoint;
 | 
			
		||||
 | 
			
		||||
  if(src_privp->s_asynsize > 0 && dst_privp->s_asynsize > 0 && src_privp->s_asynendpoint == dst_e) {
 | 
			
		||||
      if(data_copy(src_e, src_privp->s_asyntab, dst_e, dst_privp->s_asyntab,
 | 
			
		||||
	  src_privp->s_asynsize*sizeof(asynmsg_t)) != OK) {
 | 
			
		||||
	  printf("Warning: unable to transfer asyn table from ep %d to ep %d\n",
 | 
			
		||||
	      src_e, dst_e);
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
          dst_privp->s_asynsize = src_privp->s_asynsize;
 | 
			
		||||
      }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*===========================================================================*
 | 
			
		||||
 *			     adjust_priv_slot				     *
 | 
			
		||||
 *===========================================================================*/
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user