43a44
> #include <csignal>
135a137,158
> /**
> *
> * @dot
> * digraph {
> * Idle;
> * Running;
> * RunningService;
> * RunningServiceCompletion;
> *
> * Idle -> Idle;
> * Idle -> Running [label="activateContext()", URL="\ref activateContext"];
> * Running -> Running [label="tick()", URL="\ref tick"];
> * Running -> RunningService [label="tick()", URL="\ref tick"];
> * Running -> Idle [label="suspendContext()", URL="\ref suspendContext"];
> * Running -> Idle [label="drain()", URL="\ref drain"];
> * Idle -> Running [label="drainResume()", URL="\ref drainResume"];
> * RunningService -> RunningServiceCompletion [label="handleKvmExit()", URL="\ref handleKvmExit"];
> * RunningServiceCompletion -> Running [label="tick()", URL="\ref tick"];
> * RunningServiceCompletion -> RunningService [label="tick()", URL="\ref tick"];
> * }
> * @enddot
> */
137c160,168
< /** Context not scheduled in KVM */
---
> /** Context not scheduled in KVM.
> *
> * The CPU generally enters this state when the guest execute
> * an instruction that halts the CPU (e.g., WFI on ARM or HLT
> * on X86) if KVM traps this instruction. Ticks are not
> * scheduled in this state.
> *
> * @see suspendContext()
> */
139c170,174
< /** Running normally */
---
> /** Running normally.
> *
> * This is the normal run state of the CPU. KVM will be
> * entered next time tick() is called.
> */
140a176,197
> /** Requiring service at the beginning of the next cycle.
> *
> * The virtual machine has exited and requires service, tick()
> * will call handleKvmExit() on the next cycle. The next state
> * after running service is determined in handleKvmExit() and
> * depends on what kind of service the guest requested:
> * <ul>
> * <li>IO/MMIO: RunningServiceCompletion
> * <li>Halt: Idle
> * <li>Others: Running
> * </ul>
> */
> RunningService,
> /** Service completion in progress.
> *
> * The VM has requested service that requires KVM to be
> * entered once in order to get to a consistent state. This
> * happens in handleKvmExit() or one of its friends after IO
> * exits. After executing tick(), the CPU will transition into
> * the Running or RunningService state.
> */
> RunningServiceCompletion,
149,152d205
< *
< * @note This method is virtual in order to allow implementations
< * to check for architecture specific events (e.g., interrupts)
< * before entering the VM.
154c207
< virtual void tick();
---
> void tick();
180c233,242
< * @param ticks Number of ticks to execute
---
> * @note This method is virtual in order to allow implementations
> * to check for architecture specific events (e.g., interrupts)
> * before entering the VM.
> *
> * @note It is the response of the caller (normally tick()) to
> * make sure that the KVM state is synchronized and that the TC is
> * invalidated after entering KVM.
> *
> * @param ticks Number of ticks to execute, set to 0 to exit
> * immediately after finishing pending operations.
183c245
< Tick kvmRun(Tick ticks);
---
> virtual Tick kvmRun(Tick ticks);
185a248,260
> * Request the CPU to run until draining completes.
> *
> * This function normally calls kvmRun(0) to make KVM finish
> * pending MMIO operations. Architecures implementing
> * archIsDrained() must override this method.
> *
> * @see BaseKvmCPU::archIsDrained()
> *
> * @return Number of ticks executed
> */
> virtual Tick kvmRunDrain();
>
> /**
387a463,480
> * Is the architecture specific code in a state that prevents
> * draining?
> *
> * This method should return false if there are any pending events
> * in the guest vCPU that won't be carried over to the gem5 state
> * and thus will prevent correct checkpointing or CPU handover. It
> * might, for example, check for pending interrupts that have been
> * passed to the vCPU but not acknowledged by the OS. Architecures
> * implementing this method <i>must</i> override
> * kvmRunDrain().
> *
> * @see BaseKvmCPU::kvmRunDrain()
> *
> * @return true if the vCPU is drained, false otherwise.
> */
> virtual bool archIsDrained() const { return true; }
>
> /**
397a491,505
> /** @{ */
> /**
> * Set the signal mask used in kvmRun()
> *
> * This method allows the signal mask of the thread executing
> * kvmRun() to be overridden inside the actual system call. This
> * allows us to mask timer signals used to force KVM exits while
> * in gem5.
> *
> * The signal mask can be disabled by setting it to NULL.
> *
> * @param mask Signals to mask
> */
> void setSignalMask(const sigset_t *mask);
> /** @} */
501a610,617
> /**
> * Discard a (potentially) pending signal.
> *
> * @param signum Signal to discard
> * @return true if the signal was pending, false otherwise.
> */
> bool discardPendingSignal(int signum) const;
>
504a621,626
> /** Try to drain the CPU if a drain is pending */
> bool tryDrain();
>
> /** Execute the KVM_RUN ioctl */
> void ioctlRun();
>
552a675,681
> /**
> * Drain manager to use when signaling drain completion
> *
> * This pointer is non-NULL when draining and NULL otherwise.
> */
> DrainManager *drainManager;
>