diff options
Diffstat (limited to 'src/cpu/kvm/base.hh')
-rw-r--r-- | src/cpu/kvm/base.hh | 56 |
1 files changed, 43 insertions, 13 deletions
diff --git a/src/cpu/kvm/base.hh b/src/cpu/kvm/base.hh index 7ff0cab5c..ef500974f 100644 --- a/src/cpu/kvm/base.hh +++ b/src/cpu/kvm/base.hh @@ -44,6 +44,7 @@ #include <csignal> #include <memory> +#include <queue> #include "base/statistics.hh" #include "cpu/kvm/perfevent.hh" @@ -110,6 +111,12 @@ class BaseKvmCPU : public BaseCPU Counter totalInsts() const override; Counter totalOps() const override; + /** + * Callback from KvmCPUPort to transition the CPU out of RunningMMIOPending + * when all timing requests have completed. + */ + void finishMMIOPending(); + /** Dump the internal state to the terminal. */ virtual void dump() const; @@ -152,6 +159,7 @@ class BaseKvmCPU : public BaseCPU * Running; * RunningService; * RunningServiceCompletion; + * RunningMMIOPending; * * Idle -> Idle; * Idle -> Running [label="activateContext()", URL="\ref activateContext"]; @@ -161,6 +169,8 @@ class BaseKvmCPU : public BaseCPU * Running -> Idle [label="drain()", URL="\ref drain"]; * Idle -> Running [label="drainResume()", URL="\ref drainResume"]; * RunningService -> RunningServiceCompletion [label="handleKvmExit()", URL="\ref handleKvmExit"]; + * RunningService -> RunningMMIOPending [label="handleKvmExit()", URL="\ref handleKvmExit"]; + * RunningMMIOPending -> RunningServiceCompletion [label="finishMMIOPending()", URL="\ref finishMMIOPending"]; * RunningServiceCompletion -> Running [label="tick()", URL="\ref tick"]; * RunningServiceCompletion -> RunningService [label="tick()", URL="\ref tick"]; * } @@ -190,12 +200,21 @@ class BaseKvmCPU : public BaseCPU * after running service is determined in handleKvmExit() and * depends on what kind of service the guest requested: * <ul> - * <li>IO/MMIO: RunningServiceCompletion + * <li>IO/MMIO (Atomic): RunningServiceCompletion + * <li>IO/MMIO (Timing): RunningMMIOPending * <li>Halt: Idle * <li>Others: Running * </ul> */ RunningService, + /** Timing MMIO request in flight or stalled. + * + * The VM has requested IO/MMIO and we are in timing mode. A timing + * request is either stalled (and will be retried with recvReqRetry()) + * or it is in flight. After the timing request is complete, the CPU + * will transition to the RunningServiceCompletion state. + */ + RunningMMIOPending, /** Service completion in progress. * * The VM has requested service that requires KVM to be @@ -543,28 +562,39 @@ class BaseKvmCPU : public BaseCPU /** - * KVM memory port. Uses the default MasterPort behavior, but - * panics on timing accesses. + * KVM memory port. Uses default MasterPort behavior and provides an + * interface for KVM to transparently submit atomic or timing requests. */ class KVMCpuPort : public MasterPort { public: KVMCpuPort(const std::string &_name, BaseKvmCPU *_cpu) - : MasterPort(_name, _cpu) + : MasterPort(_name, _cpu), cpu(_cpu), activeMMIOReqs(0) { } + /** + * Interface to send Atomic or Timing IO request. Assumes that the pkt + * and corresponding req have been dynamically allocated and deletes + * them both if the system is in atomic mode. + */ + Tick submitIO(PacketPtr pkt); + + /** Returns next valid state after one or more IO accesses */ + Status nextIOState() const; protected: - bool recvTimingResp(PacketPtr pkt) - { - panic("The KVM CPU doesn't expect recvTimingResp!\n"); - return true; - } + /** KVM cpu pointer for finishMMIOPending() callback */ + BaseKvmCPU *cpu; - void recvReqRetry() - { - panic("The KVM CPU doesn't expect recvReqRetry!\n"); - } + /** Pending MMIO packets */ + std::queue<PacketPtr> pendingMMIOPkts; + + /** Number of MMIO requests in flight */ + unsigned int activeMMIOReqs; + + bool recvTimingResp(PacketPtr pkt) override; + + void recvReqRetry() override; }; |