base.hh revision 11151:ca4ea9b5c052
112027Sjungma@eit.uni-kl.de/* 212027Sjungma@eit.uni-kl.de * Copyright (c) 2012 ARM Limited 312027Sjungma@eit.uni-kl.de * All rights reserved 412027Sjungma@eit.uni-kl.de * 512027Sjungma@eit.uni-kl.de * The license below extends only to copyright in the software and shall 612027Sjungma@eit.uni-kl.de * not be construed as granting a license to any other intellectual 712027Sjungma@eit.uni-kl.de * property including but not limited to intellectual property relating 812027Sjungma@eit.uni-kl.de * to a hardware implementation of the functionality of the software 912027Sjungma@eit.uni-kl.de * licensed hereunder. You may use the software subject to the license 1012027Sjungma@eit.uni-kl.de * terms below provided that you ensure that this notice is replicated 1112027Sjungma@eit.uni-kl.de * unmodified and in its entirety in all distributions of the software, 1212027Sjungma@eit.uni-kl.de * modified or unmodified, in source code or in binary form. 1312027Sjungma@eit.uni-kl.de * 1412027Sjungma@eit.uni-kl.de * Redistribution and use in source and binary forms, with or without 1512027Sjungma@eit.uni-kl.de * modification, are permitted provided that the following conditions are 1612027Sjungma@eit.uni-kl.de * met: redistributions of source code must retain the above copyright 1712027Sjungma@eit.uni-kl.de * notice, this list of conditions and the following disclaimer; 1812027Sjungma@eit.uni-kl.de * redistributions in binary form must reproduce the above copyright 1912027Sjungma@eit.uni-kl.de * notice, this list of conditions and the following disclaimer in the 2012027Sjungma@eit.uni-kl.de * documentation and/or other materials provided with the distribution; 2112027Sjungma@eit.uni-kl.de * neither the name of the copyright holders nor the names of its 2212027Sjungma@eit.uni-kl.de * contributors may be used to endorse or promote products derived from 2312027Sjungma@eit.uni-kl.de * this software without specific prior written permission. 2412027Sjungma@eit.uni-kl.de * 2512027Sjungma@eit.uni-kl.de * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2612027Sjungma@eit.uni-kl.de * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2712027Sjungma@eit.uni-kl.de * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2812027Sjungma@eit.uni-kl.de * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2912027Sjungma@eit.uni-kl.de * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3012027Sjungma@eit.uni-kl.de * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3112027Sjungma@eit.uni-kl.de * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3212027Sjungma@eit.uni-kl.de * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3312027Sjungma@eit.uni-kl.de * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3412027Sjungma@eit.uni-kl.de * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3512027Sjungma@eit.uni-kl.de * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3612027Sjungma@eit.uni-kl.de * 3712027Sjungma@eit.uni-kl.de * Authors: Andreas Sandberg 3812027Sjungma@eit.uni-kl.de */ 3912027Sjungma@eit.uni-kl.de 4012027Sjungma@eit.uni-kl.de#ifndef __CPU_KVM_BASE_HH__ 4112027Sjungma@eit.uni-kl.de#define __CPU_KVM_BASE_HH__ 4212027Sjungma@eit.uni-kl.de 4312027Sjungma@eit.uni-kl.de#include <pthread.h> 4412027Sjungma@eit.uni-kl.de 4512027Sjungma@eit.uni-kl.de#include <csignal> 4612027Sjungma@eit.uni-kl.de#include <memory> 4712027Sjungma@eit.uni-kl.de 4812027Sjungma@eit.uni-kl.de#include "base/statistics.hh" 4912027Sjungma@eit.uni-kl.de#include "cpu/kvm/perfevent.hh" 5012027Sjungma@eit.uni-kl.de#include "cpu/kvm/timer.hh" 5112027Sjungma@eit.uni-kl.de#include "cpu/kvm/vm.hh" 5212027Sjungma@eit.uni-kl.de#include "cpu/base.hh" 5312027Sjungma@eit.uni-kl.de#include "cpu/simple_thread.hh" 5412027Sjungma@eit.uni-kl.de 5512027Sjungma@eit.uni-kl.de/** Signal to use to trigger exits from KVM */ 5612027Sjungma@eit.uni-kl.de#define KVM_KICK_SIGNAL SIGRTMIN 5712027Sjungma@eit.uni-kl.de 5812027Sjungma@eit.uni-kl.de// forward declarations 5912027Sjungma@eit.uni-kl.declass ThreadContext; 6012027Sjungma@eit.uni-kl.destruct BaseKvmCPUParams; 6112027Sjungma@eit.uni-kl.de 6212027Sjungma@eit.uni-kl.de/** 6312027Sjungma@eit.uni-kl.de * Base class for KVM based CPU models 6412027Sjungma@eit.uni-kl.de * 6512027Sjungma@eit.uni-kl.de * All architecture specific KVM implementation should inherit from 6612027Sjungma@eit.uni-kl.de * this class. The most basic CPU models only need to override the 6712027Sjungma@eit.uni-kl.de * updateKvmState() and updateThreadContext() methods to implement 6812027Sjungma@eit.uni-kl.de * state synchronization between gem5 and KVM. 6912027Sjungma@eit.uni-kl.de * 7012027Sjungma@eit.uni-kl.de * The architecture specific implementation is also responsible for 7112027Sjungma@eit.uni-kl.de * delivering interrupts into the VM. This is typically done by 7212027Sjungma@eit.uni-kl.de * overriding tick() and checking the thread context before entering 7312027Sjungma@eit.uni-kl.de * into the VM. In order to deliver an interrupt, the implementation 7412027Sjungma@eit.uni-kl.de * then calls KvmVM::setIRQLine() or BaseKvmCPU::kvmInterrupt() 7512027Sjungma@eit.uni-kl.de * depending on the specifics of the underlying hardware/drivers. 7612027Sjungma@eit.uni-kl.de */ 7712027Sjungma@eit.uni-kl.declass BaseKvmCPU : public BaseCPU 7812027Sjungma@eit.uni-kl.de{ 7912027Sjungma@eit.uni-kl.de public: 8012027Sjungma@eit.uni-kl.de BaseKvmCPU(BaseKvmCPUParams *params); 8112027Sjungma@eit.uni-kl.de virtual ~BaseKvmCPU(); 8212027Sjungma@eit.uni-kl.de 8312027Sjungma@eit.uni-kl.de void init(); 8412027Sjungma@eit.uni-kl.de void startup(); 8512027Sjungma@eit.uni-kl.de void regStats(); 8612027Sjungma@eit.uni-kl.de 8712027Sjungma@eit.uni-kl.de void serializeThread(CheckpointOut &cp, 8812027Sjungma@eit.uni-kl.de ThreadID tid) const M5_ATTR_OVERRIDE; 8912027Sjungma@eit.uni-kl.de void unserializeThread(CheckpointIn &cp, 9012027Sjungma@eit.uni-kl.de ThreadID tid) M5_ATTR_OVERRIDE; 9112027Sjungma@eit.uni-kl.de 9212027Sjungma@eit.uni-kl.de DrainState drain() M5_ATTR_OVERRIDE; 9312027Sjungma@eit.uni-kl.de void drainResume() M5_ATTR_OVERRIDE; 9412027Sjungma@eit.uni-kl.de 9512027Sjungma@eit.uni-kl.de void switchOut(); 9612027Sjungma@eit.uni-kl.de void takeOverFrom(BaseCPU *cpu); 9712027Sjungma@eit.uni-kl.de 9812027Sjungma@eit.uni-kl.de void verifyMemoryMode() const; 9912027Sjungma@eit.uni-kl.de 10012027Sjungma@eit.uni-kl.de MasterPort &getDataPort() { return dataPort; } 10112027Sjungma@eit.uni-kl.de MasterPort &getInstPort() { return instPort; } 10212027Sjungma@eit.uni-kl.de 10312027Sjungma@eit.uni-kl.de void wakeup(ThreadID tid = 0) M5_ATTR_OVERRIDE; 10412027Sjungma@eit.uni-kl.de void activateContext(ThreadID thread_num); 10512027Sjungma@eit.uni-kl.de void suspendContext(ThreadID thread_num); 10612027Sjungma@eit.uni-kl.de void deallocateContext(ThreadID thread_num); 10712027Sjungma@eit.uni-kl.de void haltContext(ThreadID thread_num); 10812027Sjungma@eit.uni-kl.de 10912027Sjungma@eit.uni-kl.de ThreadContext *getContext(int tn); 11012027Sjungma@eit.uni-kl.de 11112027Sjungma@eit.uni-kl.de Counter totalInsts() const; 11212027Sjungma@eit.uni-kl.de Counter totalOps() const; 11312027Sjungma@eit.uni-kl.de 11412027Sjungma@eit.uni-kl.de /** Dump the internal state to the terminal. */ 11512027Sjungma@eit.uni-kl.de virtual void dump() const; 11612027Sjungma@eit.uni-kl.de 11712027Sjungma@eit.uni-kl.de /** 11812027Sjungma@eit.uni-kl.de * Force an exit from KVM. 11912027Sjungma@eit.uni-kl.de * 12012027Sjungma@eit.uni-kl.de * Send a signal to the thread owning this vCPU to get it to exit 12112027Sjungma@eit.uni-kl.de * from KVM. Ignored if the vCPU is not executing. 12212027Sjungma@eit.uni-kl.de */ 12312027Sjungma@eit.uni-kl.de void kick() const { pthread_kill(vcpuThread, KVM_KICK_SIGNAL); } 12412027Sjungma@eit.uni-kl.de 12512027Sjungma@eit.uni-kl.de /** 12612027Sjungma@eit.uni-kl.de * A cached copy of a thread's state in the form of a SimpleThread 12712027Sjungma@eit.uni-kl.de * object. 12812027Sjungma@eit.uni-kl.de * 12912027Sjungma@eit.uni-kl.de * Normally the actual thread state is stored in the KVM vCPU. If KVM has 13012027Sjungma@eit.uni-kl.de * been running this copy is will be out of date. If we recently handled 13112027Sjungma@eit.uni-kl.de * some events within gem5 that required state to be updated this could be 13212027Sjungma@eit.uni-kl.de * the most up-to-date copy. When getContext() or updateThreadContext() is 13312027Sjungma@eit.uni-kl.de * called this copy gets updated. The method syncThreadContext can 13412027Sjungma@eit.uni-kl.de * be used within a KVM CPU to update the thread context if the 13512027Sjungma@eit.uni-kl.de * KVM state is dirty (i.e., the vCPU has been run since the last 13612027Sjungma@eit.uni-kl.de * update). 13712027Sjungma@eit.uni-kl.de */ 13812027Sjungma@eit.uni-kl.de SimpleThread *thread; 13912027Sjungma@eit.uni-kl.de 14012027Sjungma@eit.uni-kl.de /** ThreadContext object, provides an interface for external 14112027Sjungma@eit.uni-kl.de * objects to modify this thread's state. 14212027Sjungma@eit.uni-kl.de */ 14312027Sjungma@eit.uni-kl.de ThreadContext *tc; 14412027Sjungma@eit.uni-kl.de 14512027Sjungma@eit.uni-kl.de KvmVM &vm; 14612027Sjungma@eit.uni-kl.de 14712027Sjungma@eit.uni-kl.de protected: 14812027Sjungma@eit.uni-kl.de /** 14912027Sjungma@eit.uni-kl.de * 15012027Sjungma@eit.uni-kl.de * @dot 15112027Sjungma@eit.uni-kl.de * digraph { 15212027Sjungma@eit.uni-kl.de * Idle; 15312027Sjungma@eit.uni-kl.de * Running; 15412027Sjungma@eit.uni-kl.de * RunningService; 15512027Sjungma@eit.uni-kl.de * RunningServiceCompletion; 15612027Sjungma@eit.uni-kl.de * 15712027Sjungma@eit.uni-kl.de * Idle -> Idle; 15812027Sjungma@eit.uni-kl.de * Idle -> Running [label="activateContext()", URL="\ref activateContext"]; 15912027Sjungma@eit.uni-kl.de * Running -> Running [label="tick()", URL="\ref tick"]; 16012027Sjungma@eit.uni-kl.de * Running -> RunningService [label="tick()", URL="\ref tick"]; 16112027Sjungma@eit.uni-kl.de * Running -> Idle [label="suspendContext()", URL="\ref suspendContext"]; 16212027Sjungma@eit.uni-kl.de * Running -> Idle [label="drain()", URL="\ref drain"]; 16312027Sjungma@eit.uni-kl.de * Idle -> Running [label="drainResume()", URL="\ref drainResume"]; 16412027Sjungma@eit.uni-kl.de * RunningService -> RunningServiceCompletion [label="handleKvmExit()", URL="\ref handleKvmExit"]; 16512027Sjungma@eit.uni-kl.de * RunningServiceCompletion -> Running [label="tick()", URL="\ref tick"]; 16612027Sjungma@eit.uni-kl.de * RunningServiceCompletion -> RunningService [label="tick()", URL="\ref tick"]; 16712027Sjungma@eit.uni-kl.de * } 16812027Sjungma@eit.uni-kl.de * @enddot 16912027Sjungma@eit.uni-kl.de */ 17012027Sjungma@eit.uni-kl.de enum Status { 17112027Sjungma@eit.uni-kl.de /** Context not scheduled in KVM. 17212027Sjungma@eit.uni-kl.de * 17312027Sjungma@eit.uni-kl.de * The CPU generally enters this state when the guest execute 17412027Sjungma@eit.uni-kl.de * an instruction that halts the CPU (e.g., WFI on ARM or HLT 17512027Sjungma@eit.uni-kl.de * on X86) if KVM traps this instruction. Ticks are not 17612027Sjungma@eit.uni-kl.de * scheduled in this state. 17712027Sjungma@eit.uni-kl.de * 17812027Sjungma@eit.uni-kl.de * @see suspendContext() 17912027Sjungma@eit.uni-kl.de */ 18012027Sjungma@eit.uni-kl.de Idle, 18112027Sjungma@eit.uni-kl.de /** Running normally. 18212027Sjungma@eit.uni-kl.de * 18312027Sjungma@eit.uni-kl.de * This is the normal run state of the CPU. KVM will be 18412027Sjungma@eit.uni-kl.de * entered next time tick() is called. 18512027Sjungma@eit.uni-kl.de */ 18612027Sjungma@eit.uni-kl.de Running, 18712027Sjungma@eit.uni-kl.de /** Requiring service at the beginning of the next cycle. 18812027Sjungma@eit.uni-kl.de * 18912027Sjungma@eit.uni-kl.de * The virtual machine has exited and requires service, tick() 19012027Sjungma@eit.uni-kl.de * will call handleKvmExit() on the next cycle. The next state 19112027Sjungma@eit.uni-kl.de * after running service is determined in handleKvmExit() and 19212027Sjungma@eit.uni-kl.de * depends on what kind of service the guest requested: 19312027Sjungma@eit.uni-kl.de * <ul> 19412027Sjungma@eit.uni-kl.de * <li>IO/MMIO: RunningServiceCompletion 19512027Sjungma@eit.uni-kl.de * <li>Halt: Idle 19612027Sjungma@eit.uni-kl.de * <li>Others: Running 19712027Sjungma@eit.uni-kl.de * </ul> 19812027Sjungma@eit.uni-kl.de */ 19912027Sjungma@eit.uni-kl.de RunningService, 20012027Sjungma@eit.uni-kl.de /** Service completion in progress. 20112027Sjungma@eit.uni-kl.de * 20212027Sjungma@eit.uni-kl.de * The VM has requested service that requires KVM to be 20312027Sjungma@eit.uni-kl.de * entered once in order to get to a consistent state. This 20412027Sjungma@eit.uni-kl.de * happens in handleKvmExit() or one of its friends after IO 20512027Sjungma@eit.uni-kl.de * exits. After executing tick(), the CPU will transition into 20612027Sjungma@eit.uni-kl.de * the Running or RunningService state. 20712027Sjungma@eit.uni-kl.de */ 20812027Sjungma@eit.uni-kl.de RunningServiceCompletion, 20912027Sjungma@eit.uni-kl.de }; 21012027Sjungma@eit.uni-kl.de 21112027Sjungma@eit.uni-kl.de /** CPU run state */ 21212027Sjungma@eit.uni-kl.de Status _status; 21312027Sjungma@eit.uni-kl.de 21412027Sjungma@eit.uni-kl.de /** 21512027Sjungma@eit.uni-kl.de * Execute the CPU until the next event in the main event queue or 21612027Sjungma@eit.uni-kl.de * until the guest needs service from gem5. 21712027Sjungma@eit.uni-kl.de */ 21812027Sjungma@eit.uni-kl.de void tick(); 21912027Sjungma@eit.uni-kl.de 22012027Sjungma@eit.uni-kl.de /** 22112027Sjungma@eit.uni-kl.de * Get the value of the hardware cycle counter in the guest. 22212027Sjungma@eit.uni-kl.de * 22312027Sjungma@eit.uni-kl.de * This method is supposed to return the total number of cycles 22412027Sjungma@eit.uni-kl.de * executed in hardware mode relative to some arbitrary point in 22512027Sjungma@eit.uni-kl.de * the past. It's mainly used when estimating the number of cycles 22612027Sjungma@eit.uni-kl.de * actually executed by the CPU in kvmRun(). The default behavior 22712027Sjungma@eit.uni-kl.de * of this method is to use the cycles performance counter, but 22812027Sjungma@eit.uni-kl.de * some architectures may want to use internal registers instead. 22912027Sjungma@eit.uni-kl.de * 23012027Sjungma@eit.uni-kl.de * @return Number of host cycles executed relative to an undefined 23112027Sjungma@eit.uni-kl.de * point in the past. 23212027Sjungma@eit.uni-kl.de */ 23312027Sjungma@eit.uni-kl.de virtual uint64_t getHostCycles() const; 23412027Sjungma@eit.uni-kl.de 23512027Sjungma@eit.uni-kl.de /** 23612027Sjungma@eit.uni-kl.de * Request KVM to run the guest for a given number of ticks. The 23712027Sjungma@eit.uni-kl.de * method returns the approximate number of ticks executed. 23812027Sjungma@eit.uni-kl.de * 23912027Sjungma@eit.uni-kl.de * @note The returned number of ticks can be both larger or 24012027Sjungma@eit.uni-kl.de * smaller than the requested number of ticks. A smaller number 24112027Sjungma@eit.uni-kl.de * can, for example, occur when the guest executes MMIO. A larger 24212027Sjungma@eit.uni-kl.de * number is typically due to performance counter inaccuracies. 24312027Sjungma@eit.uni-kl.de * 24412027Sjungma@eit.uni-kl.de * @note This method is virtual in order to allow implementations 24512027Sjungma@eit.uni-kl.de * to check for architecture specific events (e.g., interrupts) 24612027Sjungma@eit.uni-kl.de * before entering the VM. 24712027Sjungma@eit.uni-kl.de * 24812027Sjungma@eit.uni-kl.de * @note It is the response of the caller (normally tick()) to 24912027Sjungma@eit.uni-kl.de * make sure that the KVM state is synchronized and that the TC is 25012027Sjungma@eit.uni-kl.de * invalidated after entering KVM. 25112027Sjungma@eit.uni-kl.de * 25212027Sjungma@eit.uni-kl.de * @note This method does not normally cause any state 25312027Sjungma@eit.uni-kl.de * transitions. However, if it may suspend the CPU by suspending 25412027Sjungma@eit.uni-kl.de * the thread, which leads to a transition to the Idle state. In 25512027Sjungma@eit.uni-kl.de * such a case, kvm <i>must not</i> be entered. 25612027Sjungma@eit.uni-kl.de * 25712027Sjungma@eit.uni-kl.de * @param ticks Number of ticks to execute, set to 0 to exit 25812027Sjungma@eit.uni-kl.de * immediately after finishing pending operations. 25912027Sjungma@eit.uni-kl.de * @return Number of ticks executed (see note) 26012027Sjungma@eit.uni-kl.de */ 26112027Sjungma@eit.uni-kl.de virtual Tick kvmRun(Tick ticks); 26212027Sjungma@eit.uni-kl.de 26312027Sjungma@eit.uni-kl.de /** 26412027Sjungma@eit.uni-kl.de * Request the CPU to run until draining completes. 26512027Sjungma@eit.uni-kl.de * 26612027Sjungma@eit.uni-kl.de * This function normally calls kvmRun(0) to make KVM finish 26712027Sjungma@eit.uni-kl.de * pending MMIO operations. Architecures implementing 26812027Sjungma@eit.uni-kl.de * archIsDrained() must override this method. 26912027Sjungma@eit.uni-kl.de * 27012027Sjungma@eit.uni-kl.de * @see BaseKvmCPU::archIsDrained() 27112027Sjungma@eit.uni-kl.de * 27212027Sjungma@eit.uni-kl.de * @return Number of ticks executed 27312027Sjungma@eit.uni-kl.de */ 27412027Sjungma@eit.uni-kl.de virtual Tick kvmRunDrain(); 27512027Sjungma@eit.uni-kl.de 27612027Sjungma@eit.uni-kl.de /** 27712027Sjungma@eit.uni-kl.de * Get a pointer to the kvm_run structure containing all the input 27812027Sjungma@eit.uni-kl.de * and output parameters from kvmRun(). 27912027Sjungma@eit.uni-kl.de */ 28012027Sjungma@eit.uni-kl.de struct kvm_run *getKvmRunState() { return _kvmRun; }; 28112027Sjungma@eit.uni-kl.de 28212027Sjungma@eit.uni-kl.de /** 28312027Sjungma@eit.uni-kl.de * Retrieve a pointer to guest data stored at the end of the 28412027Sjungma@eit.uni-kl.de * kvm_run structure. This is mainly used for PIO operations 28512027Sjungma@eit.uni-kl.de * (KVM_EXIT_IO). 28612027Sjungma@eit.uni-kl.de * 28712027Sjungma@eit.uni-kl.de * @param offset Offset as specified by the kvm_run structure 28812027Sjungma@eit.uni-kl.de * @return Pointer to guest data 28912027Sjungma@eit.uni-kl.de */ 29012027Sjungma@eit.uni-kl.de uint8_t *getGuestData(uint64_t offset) const { 29112027Sjungma@eit.uni-kl.de return (uint8_t *)_kvmRun + offset; 29212027Sjungma@eit.uni-kl.de }; 29312027Sjungma@eit.uni-kl.de 29412027Sjungma@eit.uni-kl.de /** 29512027Sjungma@eit.uni-kl.de * @addtogroup KvmInterrupts 29612027Sjungma@eit.uni-kl.de * @{ 29712027Sjungma@eit.uni-kl.de */ 29812027Sjungma@eit.uni-kl.de /** 29912027Sjungma@eit.uni-kl.de * Send a non-maskable interrupt to the guest 30012027Sjungma@eit.uni-kl.de * 30112027Sjungma@eit.uni-kl.de * @note The presence of this call depends on Kvm::capUserNMI(). 30212027Sjungma@eit.uni-kl.de */ 30312027Sjungma@eit.uni-kl.de void kvmNonMaskableInterrupt(); 30412027Sjungma@eit.uni-kl.de 30512027Sjungma@eit.uni-kl.de /** 30612027Sjungma@eit.uni-kl.de * Send a normal interrupt to the guest 30712027Sjungma@eit.uni-kl.de * 30812027Sjungma@eit.uni-kl.de * @note Make sure that ready_for_interrupt_injection in kvm_run 30912027Sjungma@eit.uni-kl.de * is set prior to calling this function. If not, an interrupt 31012027Sjungma@eit.uni-kl.de * window must be requested by setting request_interrupt_window in 31112027Sjungma@eit.uni-kl.de * kvm_run to 1 and restarting the guest. 31212027Sjungma@eit.uni-kl.de * 31312027Sjungma@eit.uni-kl.de * @param interrupt Structure describing the interrupt to send 31412027Sjungma@eit.uni-kl.de */ 31512027Sjungma@eit.uni-kl.de void kvmInterrupt(const struct kvm_interrupt &interrupt); 31612027Sjungma@eit.uni-kl.de 31712027Sjungma@eit.uni-kl.de /** @} */ 31812027Sjungma@eit.uni-kl.de 31912027Sjungma@eit.uni-kl.de /** @{ */ 32012027Sjungma@eit.uni-kl.de /** 32112027Sjungma@eit.uni-kl.de * Get/Set the register state of the guest vCPU 32212027Sjungma@eit.uni-kl.de * 32312027Sjungma@eit.uni-kl.de * KVM has two different interfaces for accessing the state of the 32412027Sjungma@eit.uni-kl.de * guest CPU. One interface updates 'normal' registers and one 32512027Sjungma@eit.uni-kl.de * updates 'special' registers. The distinction between special 32612027Sjungma@eit.uni-kl.de * and normal registers isn't very clear and is architecture 32712027Sjungma@eit.uni-kl.de * dependent. 32812027Sjungma@eit.uni-kl.de */ 32912027Sjungma@eit.uni-kl.de void getRegisters(struct kvm_regs ®s) const; 33012027Sjungma@eit.uni-kl.de void setRegisters(const struct kvm_regs ®s); 33112027Sjungma@eit.uni-kl.de void getSpecialRegisters(struct kvm_sregs ®s) const; 33212027Sjungma@eit.uni-kl.de void setSpecialRegisters(const struct kvm_sregs ®s); 33312027Sjungma@eit.uni-kl.de /** @} */ 33412027Sjungma@eit.uni-kl.de 33512027Sjungma@eit.uni-kl.de /** @{ */ 33612027Sjungma@eit.uni-kl.de /** 33712027Sjungma@eit.uni-kl.de * Get/Set the guest FPU/vector state 33812027Sjungma@eit.uni-kl.de */ 33912027Sjungma@eit.uni-kl.de void getFPUState(struct kvm_fpu &state) const; 34012027Sjungma@eit.uni-kl.de void setFPUState(const struct kvm_fpu &state); 34112027Sjungma@eit.uni-kl.de /** @} */ 34212027Sjungma@eit.uni-kl.de 34312027Sjungma@eit.uni-kl.de /** @{ */ 34412027Sjungma@eit.uni-kl.de /** 34512027Sjungma@eit.uni-kl.de * Get/Set single register using the KVM_(SET|GET)_ONE_REG API. 34612027Sjungma@eit.uni-kl.de * 34712027Sjungma@eit.uni-kl.de * @note The presence of this call depends on Kvm::capOneReg(). 34812027Sjungma@eit.uni-kl.de */ 34912027Sjungma@eit.uni-kl.de void setOneReg(uint64_t id, const void *addr); 35012027Sjungma@eit.uni-kl.de void setOneReg(uint64_t id, uint64_t value) { setOneReg(id, &value); } 35112027Sjungma@eit.uni-kl.de void setOneReg(uint64_t id, uint32_t value) { setOneReg(id, &value); } 35212027Sjungma@eit.uni-kl.de void getOneReg(uint64_t id, void *addr) const; 35312027Sjungma@eit.uni-kl.de uint64_t getOneRegU64(uint64_t id) const { 35412027Sjungma@eit.uni-kl.de uint64_t value; 35512027Sjungma@eit.uni-kl.de getOneReg(id, &value); 35612027Sjungma@eit.uni-kl.de return value; 35712027Sjungma@eit.uni-kl.de } 35812027Sjungma@eit.uni-kl.de uint32_t getOneRegU32(uint64_t id) const { 35912027Sjungma@eit.uni-kl.de uint32_t value; 36012027Sjungma@eit.uni-kl.de getOneReg(id, &value); 36112027Sjungma@eit.uni-kl.de return value; 36212027Sjungma@eit.uni-kl.de } 36312027Sjungma@eit.uni-kl.de /** @} */ 36412027Sjungma@eit.uni-kl.de 36512027Sjungma@eit.uni-kl.de /** 36612027Sjungma@eit.uni-kl.de * Get and format one register for printout. 36712027Sjungma@eit.uni-kl.de * 36812027Sjungma@eit.uni-kl.de * This function call getOneReg() to retrieve the contents of one 36912027Sjungma@eit.uni-kl.de * register and automatically formats it for printing. 37012027Sjungma@eit.uni-kl.de * 37112027Sjungma@eit.uni-kl.de * @note The presence of this call depends on Kvm::capOneReg(). 37212027Sjungma@eit.uni-kl.de */ 37312027Sjungma@eit.uni-kl.de std::string getAndFormatOneReg(uint64_t id) const; 37412027Sjungma@eit.uni-kl.de 37512027Sjungma@eit.uni-kl.de /** @{ */ 37612027Sjungma@eit.uni-kl.de /** 37712027Sjungma@eit.uni-kl.de * Update the KVM state from the current thread context 37812027Sjungma@eit.uni-kl.de * 37912027Sjungma@eit.uni-kl.de * The base CPU calls this method before starting the guest CPU 38012027Sjungma@eit.uni-kl.de * when the contextDirty flag is set. The architecture dependent 38112027Sjungma@eit.uni-kl.de * CPU implementation is expected to update all guest state 38212027Sjungma@eit.uni-kl.de * (registers, special registers, and FPU state). 38312027Sjungma@eit.uni-kl.de */ 38412027Sjungma@eit.uni-kl.de virtual void updateKvmState() = 0; 38512027Sjungma@eit.uni-kl.de 38612027Sjungma@eit.uni-kl.de /** 38712027Sjungma@eit.uni-kl.de * Update the current thread context with the KVM state 38812027Sjungma@eit.uni-kl.de * 38912027Sjungma@eit.uni-kl.de * The base CPU after the guest updates any of the KVM state. In 39012027Sjungma@eit.uni-kl.de * practice, this happens after kvmRun is called. The architecture 39112027Sjungma@eit.uni-kl.de * dependent code is expected to read the state of the guest CPU 39212027Sjungma@eit.uni-kl.de * and update gem5's thread state. 39312027Sjungma@eit.uni-kl.de */ 39412027Sjungma@eit.uni-kl.de virtual void updateThreadContext() = 0; 39512027Sjungma@eit.uni-kl.de 39612027Sjungma@eit.uni-kl.de /** 39712027Sjungma@eit.uni-kl.de * Update a thread context if the KVM state is dirty with respect 39812027Sjungma@eit.uni-kl.de * to the cached thread context. 39912027Sjungma@eit.uni-kl.de */ 40012027Sjungma@eit.uni-kl.de void syncThreadContext(); 40112027Sjungma@eit.uni-kl.de 40212027Sjungma@eit.uni-kl.de /** 40312027Sjungma@eit.uni-kl.de * Update the KVM if the thread context is dirty. 40412027Sjungma@eit.uni-kl.de */ 40512027Sjungma@eit.uni-kl.de void syncKvmState(); 40612027Sjungma@eit.uni-kl.de /** @} */ 40712027Sjungma@eit.uni-kl.de 40812027Sjungma@eit.uni-kl.de /** @{ */ 40912027Sjungma@eit.uni-kl.de /** 41012027Sjungma@eit.uni-kl.de * Main kvmRun exit handler, calls the relevant handleKvmExit* 41112027Sjungma@eit.uni-kl.de * depending on exit type. 41212027Sjungma@eit.uni-kl.de * 41312027Sjungma@eit.uni-kl.de * @return Number of ticks spent servicing the exit request 41412027Sjungma@eit.uni-kl.de */ 41512027Sjungma@eit.uni-kl.de virtual Tick handleKvmExit(); 41612027Sjungma@eit.uni-kl.de 41712027Sjungma@eit.uni-kl.de /** 41812027Sjungma@eit.uni-kl.de * The guest performed a legacy IO request (out/inp on x86) 41912027Sjungma@eit.uni-kl.de * 42012027Sjungma@eit.uni-kl.de * @return Number of ticks spent servicing the IO request 42112027Sjungma@eit.uni-kl.de */ 42212027Sjungma@eit.uni-kl.de virtual Tick handleKvmExitIO(); 42312027Sjungma@eit.uni-kl.de 42412027Sjungma@eit.uni-kl.de /** 42512027Sjungma@eit.uni-kl.de * The guest requested a monitor service using a hypercall 42612027Sjungma@eit.uni-kl.de * 42712027Sjungma@eit.uni-kl.de * @return Number of ticks spent servicing the hypercall 42812027Sjungma@eit.uni-kl.de */ 42912027Sjungma@eit.uni-kl.de virtual Tick handleKvmExitHypercall(); 43012027Sjungma@eit.uni-kl.de 43112027Sjungma@eit.uni-kl.de /** 43212027Sjungma@eit.uni-kl.de * The guest exited because an interrupt window was requested 43312027Sjungma@eit.uni-kl.de * 43412027Sjungma@eit.uni-kl.de * The guest exited because an interrupt window was requested 43512027Sjungma@eit.uni-kl.de * (request_interrupt_window in the kvm_run structure was set to 1 43612027Sjungma@eit.uni-kl.de * before calling kvmRun) and it is now ready to receive 43712027Sjungma@eit.uni-kl.de * 43812027Sjungma@eit.uni-kl.de * @return Number of ticks spent servicing the IRQ 43912027Sjungma@eit.uni-kl.de */ 44012027Sjungma@eit.uni-kl.de virtual Tick handleKvmExitIRQWindowOpen(); 44112027Sjungma@eit.uni-kl.de 44212027Sjungma@eit.uni-kl.de /** 44312027Sjungma@eit.uni-kl.de * An unknown architecture dependent error occurred when starting 44412027Sjungma@eit.uni-kl.de * the vCPU 44512027Sjungma@eit.uni-kl.de * 44612027Sjungma@eit.uni-kl.de * The kvm_run data structure contains the hardware error 44712027Sjungma@eit.uni-kl.de * code. The defaults behavior of this method just prints the HW 44812027Sjungma@eit.uni-kl.de * error code and panics. Architecture dependent implementations 44912027Sjungma@eit.uni-kl.de * may want to override this method to provide better, 45012027Sjungma@eit.uni-kl.de * hardware-aware, error messages. 45112027Sjungma@eit.uni-kl.de * 45212027Sjungma@eit.uni-kl.de * @return Number of ticks delay the next CPU tick 45312027Sjungma@eit.uni-kl.de */ 45412027Sjungma@eit.uni-kl.de virtual Tick handleKvmExitUnknown(); 45512027Sjungma@eit.uni-kl.de 45612027Sjungma@eit.uni-kl.de /** 45712027Sjungma@eit.uni-kl.de * An unhandled virtualization exception occured 45812027Sjungma@eit.uni-kl.de * 45912027Sjungma@eit.uni-kl.de * Some KVM virtualization drivers return unhandled exceptions to 46012027Sjungma@eit.uni-kl.de * the user-space monitor. This interface is currently only used 46112027Sjungma@eit.uni-kl.de * by the Intel VMX KVM driver. 46212027Sjungma@eit.uni-kl.de * 46312027Sjungma@eit.uni-kl.de * @return Number of ticks delay the next CPU tick 46412027Sjungma@eit.uni-kl.de */ 46512027Sjungma@eit.uni-kl.de virtual Tick handleKvmExitException(); 46612027Sjungma@eit.uni-kl.de 46712027Sjungma@eit.uni-kl.de /** 46812027Sjungma@eit.uni-kl.de * KVM failed to start the virtualized CPU 46912027Sjungma@eit.uni-kl.de * 47012027Sjungma@eit.uni-kl.de * The kvm_run data structure contains the hardware-specific error 47112027Sjungma@eit.uni-kl.de * code. 47212027Sjungma@eit.uni-kl.de * 47312027Sjungma@eit.uni-kl.de * @return Number of ticks delay the next CPU tick 47412027Sjungma@eit.uni-kl.de */ 47512027Sjungma@eit.uni-kl.de virtual Tick handleKvmExitFailEntry(); 47612027Sjungma@eit.uni-kl.de /** @} */ 47712027Sjungma@eit.uni-kl.de 47812027Sjungma@eit.uni-kl.de /** 47912027Sjungma@eit.uni-kl.de * Is the architecture specific code in a state that prevents 48012027Sjungma@eit.uni-kl.de * draining? 48112027Sjungma@eit.uni-kl.de * 48212027Sjungma@eit.uni-kl.de * This method should return false if there are any pending events 48312027Sjungma@eit.uni-kl.de * in the guest vCPU that won't be carried over to the gem5 state 48412027Sjungma@eit.uni-kl.de * and thus will prevent correct checkpointing or CPU handover. It 48512027Sjungma@eit.uni-kl.de * might, for example, check for pending interrupts that have been 48612027Sjungma@eit.uni-kl.de * passed to the vCPU but not acknowledged by the OS. Architecures 48712027Sjungma@eit.uni-kl.de * implementing this method <i>must</i> override 48812027Sjungma@eit.uni-kl.de * kvmRunDrain(). 48912027Sjungma@eit.uni-kl.de * 49012027Sjungma@eit.uni-kl.de * @see BaseKvmCPU::kvmRunDrain() 49112027Sjungma@eit.uni-kl.de * 49212027Sjungma@eit.uni-kl.de * @return true if the vCPU is drained, false otherwise. 49312027Sjungma@eit.uni-kl.de */ 49412027Sjungma@eit.uni-kl.de virtual bool archIsDrained() const { return true; } 49512027Sjungma@eit.uni-kl.de 49612027Sjungma@eit.uni-kl.de /** 49712027Sjungma@eit.uni-kl.de * Inject a memory mapped IO request into gem5 49812027Sjungma@eit.uni-kl.de * 49912027Sjungma@eit.uni-kl.de * @param paddr Physical address 50012027Sjungma@eit.uni-kl.de * @param data Pointer to the source/destination buffer 50112027Sjungma@eit.uni-kl.de * @param size Memory access size 50212027Sjungma@eit.uni-kl.de * @param write True if write, False if read 50312027Sjungma@eit.uni-kl.de * @return Number of ticks spent servicing the memory access 50412027Sjungma@eit.uni-kl.de */ 50512027Sjungma@eit.uni-kl.de Tick doMMIOAccess(Addr paddr, void *data, int size, bool write); 50612027Sjungma@eit.uni-kl.de 50712027Sjungma@eit.uni-kl.de /** @{ */ 50812027Sjungma@eit.uni-kl.de /** 50912027Sjungma@eit.uni-kl.de * Set the signal mask used in kvmRun() 51012027Sjungma@eit.uni-kl.de * 51112027Sjungma@eit.uni-kl.de * This method allows the signal mask of the thread executing 51212027Sjungma@eit.uni-kl.de * kvmRun() to be overridden inside the actual system call. This 51312027Sjungma@eit.uni-kl.de * allows us to mask timer signals used to force KVM exits while 51412027Sjungma@eit.uni-kl.de * in gem5. 51512027Sjungma@eit.uni-kl.de * 51612027Sjungma@eit.uni-kl.de * The signal mask can be disabled by setting it to NULL. 51712027Sjungma@eit.uni-kl.de * 51812027Sjungma@eit.uni-kl.de * @param mask Signals to mask 51912027Sjungma@eit.uni-kl.de */ 52012027Sjungma@eit.uni-kl.de void setSignalMask(const sigset_t *mask); 52112027Sjungma@eit.uni-kl.de /** @} */ 52212027Sjungma@eit.uni-kl.de 52312027Sjungma@eit.uni-kl.de /** 52412027Sjungma@eit.uni-kl.de * @addtogroup KvmIoctl 52512027Sjungma@eit.uni-kl.de * @{ 52612027Sjungma@eit.uni-kl.de */ 52712027Sjungma@eit.uni-kl.de /** 52812027Sjungma@eit.uni-kl.de * vCPU ioctl interface. 52912027Sjungma@eit.uni-kl.de * 53012027Sjungma@eit.uni-kl.de * @param request KVM vCPU request 53112027Sjungma@eit.uni-kl.de * @param p1 Optional request parameter 53212027Sjungma@eit.uni-kl.de * 53312027Sjungma@eit.uni-kl.de * @return -1 on error (error number in errno), ioctl dependent 53412027Sjungma@eit.uni-kl.de * value otherwise. 53512027Sjungma@eit.uni-kl.de */ 53612027Sjungma@eit.uni-kl.de int ioctl(int request, long p1) const; 53712027Sjungma@eit.uni-kl.de int ioctl(int request, void *p1) const { 53812027Sjungma@eit.uni-kl.de return ioctl(request, (long)p1); 53912027Sjungma@eit.uni-kl.de } 54012027Sjungma@eit.uni-kl.de int ioctl(int request) const { 54112027Sjungma@eit.uni-kl.de return ioctl(request, 0L); 54212027Sjungma@eit.uni-kl.de } 54312027Sjungma@eit.uni-kl.de /** @} */ 54412027Sjungma@eit.uni-kl.de 54512027Sjungma@eit.uni-kl.de 54612027Sjungma@eit.uni-kl.de /** 54712027Sjungma@eit.uni-kl.de * KVM memory port. Uses the default MasterPort behavior, but 54812027Sjungma@eit.uni-kl.de * panics on timing accesses. 54912027Sjungma@eit.uni-kl.de */ 55012027Sjungma@eit.uni-kl.de class KVMCpuPort : public MasterPort 55112027Sjungma@eit.uni-kl.de { 55212027Sjungma@eit.uni-kl.de 55312027Sjungma@eit.uni-kl.de public: 55412027Sjungma@eit.uni-kl.de KVMCpuPort(const std::string &_name, BaseKvmCPU *_cpu) 55512027Sjungma@eit.uni-kl.de : MasterPort(_name, _cpu) 55612027Sjungma@eit.uni-kl.de { } 55712027Sjungma@eit.uni-kl.de 55812027Sjungma@eit.uni-kl.de protected: 55912027Sjungma@eit.uni-kl.de bool recvTimingResp(PacketPtr pkt) 56012027Sjungma@eit.uni-kl.de { 56112027Sjungma@eit.uni-kl.de panic("The KVM CPU doesn't expect recvTimingResp!\n"); 56212027Sjungma@eit.uni-kl.de return true; 56312027Sjungma@eit.uni-kl.de } 56412027Sjungma@eit.uni-kl.de 56512027Sjungma@eit.uni-kl.de void recvReqRetry() 56612027Sjungma@eit.uni-kl.de { 56712027Sjungma@eit.uni-kl.de panic("The KVM CPU doesn't expect recvReqRetry!\n"); 56812027Sjungma@eit.uni-kl.de } 56912027Sjungma@eit.uni-kl.de 57012027Sjungma@eit.uni-kl.de }; 57112027Sjungma@eit.uni-kl.de 57212027Sjungma@eit.uni-kl.de /** Port for data requests */ 57312027Sjungma@eit.uni-kl.de KVMCpuPort dataPort; 57412027Sjungma@eit.uni-kl.de 57512027Sjungma@eit.uni-kl.de /** Unused dummy port for the instruction interface */ 57612027Sjungma@eit.uni-kl.de KVMCpuPort instPort; 57712027Sjungma@eit.uni-kl.de 57812027Sjungma@eit.uni-kl.de /** 57912027Sjungma@eit.uni-kl.de * Is the gem5 context dirty? Set to true to force an update of 58012027Sjungma@eit.uni-kl.de * the KVM vCPU state upon the next call to kvmRun(). 58112027Sjungma@eit.uni-kl.de */ 58212027Sjungma@eit.uni-kl.de bool threadContextDirty; 58312027Sjungma@eit.uni-kl.de 58412027Sjungma@eit.uni-kl.de /** 58512027Sjungma@eit.uni-kl.de * Is the KVM state dirty? Set to true to force an update of 58612027Sjungma@eit.uni-kl.de * the KVM vCPU state upon the next call to kvmRun(). 58712027Sjungma@eit.uni-kl.de */ 58812027Sjungma@eit.uni-kl.de bool kvmStateDirty; 58912027Sjungma@eit.uni-kl.de 59012027Sjungma@eit.uni-kl.de /** KVM internal ID of the vCPU */ 59112027Sjungma@eit.uni-kl.de const long vcpuID; 59212027Sjungma@eit.uni-kl.de 59312027Sjungma@eit.uni-kl.de /** ID of the vCPU thread */ 59412027Sjungma@eit.uni-kl.de pthread_t vcpuThread; 59512027Sjungma@eit.uni-kl.de 59612027Sjungma@eit.uni-kl.de private: 59712027Sjungma@eit.uni-kl.de struct TickEvent : public Event 59812027Sjungma@eit.uni-kl.de { 59912027Sjungma@eit.uni-kl.de BaseKvmCPU &cpu; 60012027Sjungma@eit.uni-kl.de 60112027Sjungma@eit.uni-kl.de TickEvent(BaseKvmCPU &c) 60212027Sjungma@eit.uni-kl.de : Event(CPU_Tick_Pri), cpu(c) {} 60312027Sjungma@eit.uni-kl.de 60412027Sjungma@eit.uni-kl.de void process() { cpu.tick(); } 60512027Sjungma@eit.uni-kl.de 60612027Sjungma@eit.uni-kl.de const char *description() const { 60712027Sjungma@eit.uni-kl.de return "BaseKvmCPU tick"; 60812027Sjungma@eit.uni-kl.de } 60912027Sjungma@eit.uni-kl.de }; 61012027Sjungma@eit.uni-kl.de 61112027Sjungma@eit.uni-kl.de /** 61212027Sjungma@eit.uni-kl.de * Service MMIO requests in the mmioRing. 61312027Sjungma@eit.uni-kl.de * 61412027Sjungma@eit.uni-kl.de * 61512027Sjungma@eit.uni-kl.de * @return Number of ticks spent servicing the MMIO requests in 61612027Sjungma@eit.uni-kl.de * the MMIO ring buffer 61712027Sjungma@eit.uni-kl.de */ 61812027Sjungma@eit.uni-kl.de Tick flushCoalescedMMIO(); 61912027Sjungma@eit.uni-kl.de 62012027Sjungma@eit.uni-kl.de /** 62112027Sjungma@eit.uni-kl.de * Setup a signal handler to catch the timer signal used to 62212027Sjungma@eit.uni-kl.de * switch back to the monitor. 62312027Sjungma@eit.uni-kl.de */ 62412027Sjungma@eit.uni-kl.de void setupSignalHandler(); 62512027Sjungma@eit.uni-kl.de 62612027Sjungma@eit.uni-kl.de /** 62712027Sjungma@eit.uni-kl.de * Discard a (potentially) pending signal. 62812027Sjungma@eit.uni-kl.de * 62912027Sjungma@eit.uni-kl.de * @param signum Signal to discard 63012027Sjungma@eit.uni-kl.de * @return true if the signal was pending, false otherwise. 63112027Sjungma@eit.uni-kl.de */ 63212027Sjungma@eit.uni-kl.de bool discardPendingSignal(int signum) const; 63312027Sjungma@eit.uni-kl.de 63412027Sjungma@eit.uni-kl.de /** 63512027Sjungma@eit.uni-kl.de * Thread-specific initialization. 63612027Sjungma@eit.uni-kl.de * 63712027Sjungma@eit.uni-kl.de * Some KVM-related initialization requires us to know the TID of 63812027Sjungma@eit.uni-kl.de * the thread that is going to execute our event queue. For 63912027Sjungma@eit.uni-kl.de * example, when setting up timers, we need to know the TID of the 64012027Sjungma@eit.uni-kl.de * thread executing in KVM in order to deliver the timer signal to 64112027Sjungma@eit.uni-kl.de * that thread. This method is called as the first event in this 64212027Sjungma@eit.uni-kl.de * SimObject's event queue. 64312027Sjungma@eit.uni-kl.de * 64412027Sjungma@eit.uni-kl.de * @see startup 64512027Sjungma@eit.uni-kl.de */ 64612027Sjungma@eit.uni-kl.de void startupThread(); 64712027Sjungma@eit.uni-kl.de 64812027Sjungma@eit.uni-kl.de /** Try to drain the CPU if a drain is pending */ 64912027Sjungma@eit.uni-kl.de bool tryDrain(); 65012027Sjungma@eit.uni-kl.de 65112027Sjungma@eit.uni-kl.de /** Execute the KVM_RUN ioctl */ 65212027Sjungma@eit.uni-kl.de void ioctlRun(); 65312027Sjungma@eit.uni-kl.de 65412027Sjungma@eit.uni-kl.de /** KVM vCPU file descriptor */ 65512027Sjungma@eit.uni-kl.de int vcpuFD; 65612027Sjungma@eit.uni-kl.de /** Size of MMAPed kvm_run area */ 65712027Sjungma@eit.uni-kl.de int vcpuMMapSize; 65812027Sjungma@eit.uni-kl.de /** 65912027Sjungma@eit.uni-kl.de * Pointer to the kvm_run structure used to communicate parameters 66012027Sjungma@eit.uni-kl.de * with KVM. 66112027Sjungma@eit.uni-kl.de * 66212027Sjungma@eit.uni-kl.de * @note This is the base pointer of the MMAPed KVM region. The 66312027Sjungma@eit.uni-kl.de * first page contains the kvm_run structure. Subsequent pages may 66412027Sjungma@eit.uni-kl.de * contain other data such as the MMIO ring buffer. 66512027Sjungma@eit.uni-kl.de */ 66612027Sjungma@eit.uni-kl.de struct kvm_run *_kvmRun; 66712027Sjungma@eit.uni-kl.de /** 66812027Sjungma@eit.uni-kl.de * Coalesced MMIO ring buffer. NULL if coalesced MMIO is not 66912027Sjungma@eit.uni-kl.de * supported. 67012027Sjungma@eit.uni-kl.de */ 67112027Sjungma@eit.uni-kl.de struct kvm_coalesced_mmio_ring *mmioRing; 67212027Sjungma@eit.uni-kl.de /** Cached page size of the host */ 67312027Sjungma@eit.uni-kl.de const long pageSize; 67412027Sjungma@eit.uni-kl.de 67512027Sjungma@eit.uni-kl.de TickEvent tickEvent; 67612027Sjungma@eit.uni-kl.de 67712027Sjungma@eit.uni-kl.de /** 67812027Sjungma@eit.uni-kl.de * Setup an instruction break if there is one pending. 67912027Sjungma@eit.uni-kl.de * 68012027Sjungma@eit.uni-kl.de * Check if there are pending instruction breaks in the CPU's 68112027Sjungma@eit.uni-kl.de * instruction event queue and schedule an instruction break using 68212027Sjungma@eit.uni-kl.de * PerfEvent. 68312027Sjungma@eit.uni-kl.de * 68412027Sjungma@eit.uni-kl.de * @note This method doesn't currently handle the main system 68512027Sjungma@eit.uni-kl.de * instruction event queue. 68612027Sjungma@eit.uni-kl.de */ 68712027Sjungma@eit.uni-kl.de void setupInstStop(); 68812027Sjungma@eit.uni-kl.de 68912027Sjungma@eit.uni-kl.de /** @{ */ 69012027Sjungma@eit.uni-kl.de /** Setup hardware performance counters */ 69112027Sjungma@eit.uni-kl.de void setupCounters(); 69212027Sjungma@eit.uni-kl.de 69312027Sjungma@eit.uni-kl.de /** 69412027Sjungma@eit.uni-kl.de * Setup the guest instruction counter. 69512027Sjungma@eit.uni-kl.de * 69612027Sjungma@eit.uni-kl.de * Setup the guest instruction counter and optionally request a 69712027Sjungma@eit.uni-kl.de * signal every N instructions executed by the guest. This method 69812027Sjungma@eit.uni-kl.de * will re-attach the counter if the counter has already been 69912027Sjungma@eit.uni-kl.de * attached and its sampling settings have changed. 70012027Sjungma@eit.uni-kl.de * 70112027Sjungma@eit.uni-kl.de * @param period Signal period, set to 0 to disable signaling. 70212027Sjungma@eit.uni-kl.de */ 70312027Sjungma@eit.uni-kl.de void setupInstCounter(uint64_t period = 0); 70412027Sjungma@eit.uni-kl.de 70512027Sjungma@eit.uni-kl.de /** Currently active instruction count breakpoint */ 70612027Sjungma@eit.uni-kl.de uint64_t activeInstPeriod; 70712027Sjungma@eit.uni-kl.de 70812027Sjungma@eit.uni-kl.de /** 70912027Sjungma@eit.uni-kl.de * Guest cycle counter. 71012027Sjungma@eit.uni-kl.de * 71112027Sjungma@eit.uni-kl.de * This is the group leader of all performance counters measuring 71212027Sjungma@eit.uni-kl.de * the guest system. It can be used in conjunction with the 71312027Sjungma@eit.uni-kl.de * PerfKvmTimer (see perfControlledByTimer) to trigger exits from 71412027Sjungma@eit.uni-kl.de * KVM. 71512027Sjungma@eit.uni-kl.de */ 71612027Sjungma@eit.uni-kl.de PerfKvmCounter hwCycles; 71712027Sjungma@eit.uni-kl.de 71812027Sjungma@eit.uni-kl.de /** 71912027Sjungma@eit.uni-kl.de * Guest instruction counter. 72012027Sjungma@eit.uni-kl.de * 72112027Sjungma@eit.uni-kl.de * This counter is typically only used to measure the number of 72212027Sjungma@eit.uni-kl.de * instructions executed by the guest. However, it can also be 72312027Sjungma@eit.uni-kl.de * used to trigger exits from KVM if the configuration script 72412027Sjungma@eit.uni-kl.de * requests an exit after a certain number of instructions. 72512027Sjungma@eit.uni-kl.de * 72612027Sjungma@eit.uni-kl.de * @see setupInstBreak 72712027Sjungma@eit.uni-kl.de * @see scheduleInstStop 72812027Sjungma@eit.uni-kl.de */ 72912027Sjungma@eit.uni-kl.de PerfKvmCounter hwInstructions; 73012027Sjungma@eit.uni-kl.de 73112027Sjungma@eit.uni-kl.de /** 73212027Sjungma@eit.uni-kl.de * Does the runTimer control the performance counters? 73312027Sjungma@eit.uni-kl.de * 73412027Sjungma@eit.uni-kl.de * The run timer will automatically enable and disable performance 73512027Sjungma@eit.uni-kl.de * counters if a PerfEvent-based timer is used to control KVM 73612027Sjungma@eit.uni-kl.de * exits. 73712027Sjungma@eit.uni-kl.de */ 73812027Sjungma@eit.uni-kl.de bool perfControlledByTimer; 73912027Sjungma@eit.uni-kl.de /** @} */ 74012027Sjungma@eit.uni-kl.de 74112027Sjungma@eit.uni-kl.de /** 74212027Sjungma@eit.uni-kl.de * Timer used to force execution into the monitor after a 74312027Sjungma@eit.uni-kl.de * specified number of simulation tick equivalents have executed 74412027Sjungma@eit.uni-kl.de * in the guest. This counter generates the signal specified by 74512027Sjungma@eit.uni-kl.de * KVM_TIMER_SIGNAL. 74612027Sjungma@eit.uni-kl.de */ 74712027Sjungma@eit.uni-kl.de std::unique_ptr<BaseKvmTimer> runTimer; 74812027Sjungma@eit.uni-kl.de 74912027Sjungma@eit.uni-kl.de /** Host factor as specified in the configuration */ 75012027Sjungma@eit.uni-kl.de float hostFactor; 75112027Sjungma@eit.uni-kl.de 75212027Sjungma@eit.uni-kl.de public: 75312027Sjungma@eit.uni-kl.de /* @{ */ 75412027Sjungma@eit.uni-kl.de Stats::Scalar numInsts; 75512027Sjungma@eit.uni-kl.de Stats::Scalar numVMExits; 75612027Sjungma@eit.uni-kl.de Stats::Scalar numVMHalfEntries; 75712027Sjungma@eit.uni-kl.de Stats::Scalar numExitSignal; 75812027Sjungma@eit.uni-kl.de Stats::Scalar numMMIO; 75912027Sjungma@eit.uni-kl.de Stats::Scalar numCoalescedMMIO; 76012027Sjungma@eit.uni-kl.de Stats::Scalar numIO; 76112027Sjungma@eit.uni-kl.de Stats::Scalar numHalt; 76212027Sjungma@eit.uni-kl.de Stats::Scalar numInterrupts; 76312027Sjungma@eit.uni-kl.de Stats::Scalar numHypercalls; 76412027Sjungma@eit.uni-kl.de /* @} */ 76512027Sjungma@eit.uni-kl.de 76612027Sjungma@eit.uni-kl.de /** Number of instructions executed by the CPU */ 76712027Sjungma@eit.uni-kl.de Counter ctrInsts; 76812027Sjungma@eit.uni-kl.de}; 76912027Sjungma@eit.uni-kl.de 77012027Sjungma@eit.uni-kl.de#endif 77112027Sjungma@eit.uni-kl.de