seL4/include/object/reply.h
Anna Lyons f103ac223d mcs: Refactor replies to solve revoke problems
Before this change, we set the replyObject in the thread state on recv
with no back pointer such that stray pointers would be left in the
thread state when a reply object was completed.

The new semantics are clearer and fix this problem by doing the
following:

- tcb->tcbReply is removed and the thread state field is always used,
  this was unneccessary duplication previously
- the thread state value is set to the reply object only when the thread
  is in BlockedOnReply or BlockedOnRecv
- the reply contains a back pointer, replyTCB, which points to that
  thread
- if a thread has its reply removed, it must be set to
  ThreadState_Inactive.
- deletion is easy in the blockedOnRecv case, we just unlink the reply
  and the tcb.
- deletion is complicated for blockedOnReply. If we are deleing a tcb,
  we remove the actual reply object and the call chain is broken. If we
  are deleting a reply, we maintain the call chain by moving the tcb to
  the next reply.
- we refactor the reply object interface to solve the above.
    * reply_clear: removes the reply from any connections (tcb, sc)
    * reply_unlink: just unlinks the tcb and reply, and sets the thread
      state to inactive
    * reply_remove: removes the reply from the call chain
    * reply_remove_tcb: removes the exact reply that a tcb is bound to,
      as we are removing that tcb. Breaks the call chain.
2019-08-22 11:22:39 +10:00

43 lines
1.5 KiB
C

/*
* Copyright 2019, Data61
* Commonwealth Scientific and Industrial Research Organisation (CSIRO)
* ABN 41 687 119 230.
*
* This software may be distributed and modified according to the terms of
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
* See "LICENSE_GPLv2.txt" for details.
*
* @TAG(DATA61_GPL)
*/
#ifndef __OBJECT_REPLY_H
#define __OBJECT_REPLY_H
#include <types.h>
#include <api/failures.h>
#include <object/structures.h>
/* Unlink a reply from its tcb */
static inline void reply_unlink(reply_t *reply)
{
/* check the tcb and reply are linked correctly */
assert(thread_state_get_replyObject(reply->replyTCB->tcbState) == REPLY_REF(reply));
tcb_t *tcb = reply->replyTCB;
thread_state_ptr_set_replyObject(&tcb->tcbState, REPLY_REF(0));
reply->replyTCB = NULL;
setThreadState(tcb, ThreadState_Inactive);
}
/* Push a reply object onto the call stack */
void reply_push(tcb_t *tcb_caller, tcb_t *tcb_callee, reply_t *reply, bool_t canDonate);
/* Pop the head reply from the call stack */
void reply_pop(reply_t *reply);
/* Remove a reply from the call stack - replyTCB must be in ThreadState_BlockedOnReply */
void reply_remove(reply_t *reply);
/* Remove a specific tcb, and the reply it is blocking on, from the call stack */
void reply_remove_tcb(tcb_t *tcb);
/* clear a reply object, either for deletion or reuse. Will not be
* linked to a tcb or in a call stack after this */
void reply_clear(reply_t *reply);
#endif /* __OBJECT_REPLY_H */