x86_cpu.hh revision 9883
12SN/A/* 21762SN/A * Copyright (c) 2013 Andreas Sandberg 32SN/A * All rights reserved 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Andreas Sandberg 292SN/A */ 302SN/A 3111793Sbrandon.potter@amd.com#ifndef __CPU_KVM_X86_CPU_HH__ 3211793Sbrandon.potter@amd.com#define __CPU_KVM_X86_CPU_HH__ 338869SAli.Saidi@ARM.com 348869SAli.Saidi@ARM.com#include "cpu/kvm/base.hh" 352SN/A#include "cpu/kvm/vm.hh" 367840Snate@binkert.org#include "params/X86KvmCPU.hh" 372SN/A 3812334Sgabeblack@google.com/** 397840Snate@binkert.org * x86 implementation of a KVM-based hardware virtualized CPU. 407862Sgblack@eecs.umich.edu */ 417870Sgblack@eecs.umich.educlass X86KvmCPU : public BaseKvmCPU 422SN/A{ 432SN/A public: 442SN/A X86KvmCPU(X86KvmCPUParams *params); 457840Snate@binkert.org virtual ~X86KvmCPU(); 467840Snate@binkert.org 472SN/A void startup(); 487840Snate@binkert.org 497840Snate@binkert.org /** @{ */ 507840Snate@binkert.org void dump(); 51400SN/A void dumpFpuRegs() const; 527840Snate@binkert.org void dumpIntRegs() const; 537840Snate@binkert.org void dumpSpecRegs() const; 547840Snate@binkert.org void dumpDebugRegs() const; 55400SN/A void dumpXCRs() const; 56400SN/A void dumpXSave() const; 577862Sgblack@eecs.umich.edu void dumpVCpuEvents() const; 587862Sgblack@eecs.umich.edu void dumpMSRs() const; 597862Sgblack@eecs.umich.edu /** @} */ 607862Sgblack@eecs.umich.edu 617862Sgblack@eecs.umich.edu protected: 627862Sgblack@eecs.umich.edu typedef std::vector<struct kvm_msr_entry> KvmMSRVector; 637862Sgblack@eecs.umich.edu 647862Sgblack@eecs.umich.edu Tick kvmRun(Tick ticks); 657862Sgblack@eecs.umich.edu 667862Sgblack@eecs.umich.edu /** 677862Sgblack@eecs.umich.edu * Run the virtual CPU until draining completes. 687862Sgblack@eecs.umich.edu * 697862Sgblack@eecs.umich.edu * In addition to the base functionality provided by 70400SN/A * BaseKvmCPU::kvmRunDrain(), this method handles x86-specific 717840Snate@binkert.org * cases where there are pending interrupt events in the virtual 72400SN/A * CPU. These are handled by requesting an interrupt window if 737840Snate@binkert.org * interrupts are pending (causing the vCPU to execute until 74400SN/A * interrupts can be delivered again). 75400SN/A * 76400SN/A * @see BaseKvmCPU::kvmRunDrain() 773918Ssaidi@eecs.umich.edu * @see archIsDrained() 787840Snate@binkert.org * 793918Ssaidi@eecs.umich.edu * @return Number of ticks executed 80400SN/A */ 813918Ssaidi@eecs.umich.edu Tick kvmRunDrain(); 82400SN/A 83400SN/A /** Wrapper that synchronizes state in kvm_run */ 842SN/A Tick kvmRunWrapper(Tick ticks); 852SN/A 86400SN/A uint64_t getHostCycles() const; 87400SN/A 88400SN/A /** 89400SN/A * Methods to access CPUID information using the extended 902SN/A * API. Only available if Kvm::capExtendedCPUID() is true. 917840Snate@binkert.org * 927840Snate@binkert.org * @{ 93400SN/A */ 947840Snate@binkert.org void setCPUID(const struct kvm_cpuid2 &cpuid); 957840Snate@binkert.org void setCPUID(const Kvm::CPUIDVector &cpuid); 967840Snate@binkert.org /** @} */ 977840Snate@binkert.org 987840Snate@binkert.org /** 997840Snate@binkert.org * Methods to access MSRs in the guest. 1007840Snate@binkert.org * 1017840Snate@binkert.org * @{ 1027840Snate@binkert.org */ 1037840Snate@binkert.org void setMSRs(const struct kvm_msrs &msrs); 1047840Snate@binkert.org void setMSRs(const KvmMSRVector &msrs); 1057840Snate@binkert.org void getMSRs(struct kvm_msrs &msrs) const; 1067840Snate@binkert.org void setMSR(uint32_t index, uint64_t value); 1077840Snate@binkert.org uint64_t getMSR(uint32_t index) const; 1087840Snate@binkert.org /** @} */ 1097840Snate@binkert.org 1107840Snate@binkert.org /** 1117840Snate@binkert.org * Get a list of MSRs supported by both gem5 and KVM. 1127840Snate@binkert.org * 1137840Snate@binkert.org * @note This method uses an internal cache and only generates the 1147840Snate@binkert.org * MSR list once. 1157840Snate@binkert.org * 1167840Snate@binkert.org * @return reference to a list of msr indices 1177840Snate@binkert.org */ 1187840Snate@binkert.org const Kvm::MSRIndexVector &getMsrIntersection() const; 119400SN/A 1202SN/A /** 1217840Snate@binkert.org * Wrappers around KVM's state transfer methods. 12210905Sandreas.sandberg@arm.com * 1237870Sgblack@eecs.umich.edu * @{ 12410905Sandreas.sandberg@arm.com */ 12510905Sandreas.sandberg@arm.com void getDebugRegisters(struct kvm_debugregs ®s) const; 1267870Sgblack@eecs.umich.edu void setDebugRegisters(const struct kvm_debugregs ®s); 1277870Sgblack@eecs.umich.edu void getXCRs(struct kvm_xcrs ®s) const; 1287870Sgblack@eecs.umich.edu void setXCRs(const struct kvm_xcrs ®s); 12910905Sandreas.sandberg@arm.com void getXSave(struct kvm_xsave &xsave) const; 1307870Sgblack@eecs.umich.edu void setXSave(const struct kvm_xsave &xsave); 1317870Sgblack@eecs.umich.edu void getVCpuEvents(struct kvm_vcpu_events &events) const; 1327870Sgblack@eecs.umich.edu void setVCpuEvents(const struct kvm_vcpu_events &events); 13310905Sandreas.sandberg@arm.com /** @} */ 13410905Sandreas.sandberg@arm.com 1357870Sgblack@eecs.umich.edu void updateKvmState(); 1367870Sgblack@eecs.umich.edu void updateThreadContext(); 1377870Sgblack@eecs.umich.edu 1387870Sgblack@eecs.umich.edu /** 1397870Sgblack@eecs.umich.edu * Inject pending interrupts from gem5 into the virtual CPU. 1407840Snate@binkert.org */ 141400SN/A void deliverInterrupts(); 1427840Snate@binkert.org 1437840Snate@binkert.org /** 1447840Snate@binkert.org * Handle x86 legacy IO (in/out) 1457840Snate@binkert.org */ 1467840Snate@binkert.org Tick handleKvmExitIO(); 1477840Snate@binkert.org 1487840Snate@binkert.org Tick handleKvmExitIRQWindowOpen(); 149400SN/A 1508869SAli.Saidi@ARM.com /** 1518869SAli.Saidi@ARM.com * Check if there are pending events in the vCPU that prevents it 1528869SAli.Saidi@ARM.com * from being drained. 1538869SAli.Saidi@ARM.com * 15410531Sandreas.hansson@arm.com * There are cases after interrupt injection where the interrupt 15510531Sandreas.hansson@arm.com * is still pending in the guest. This method detects such cases 15610531Sandreas.hansson@arm.com * and requests additional draining. 15710531Sandreas.hansson@arm.com * 15810531Sandreas.hansson@arm.com * @return False if there are pending events in the guest, True 15910531Sandreas.hansson@arm.com * otherwise. 16010531Sandreas.hansson@arm.com */ 16110531Sandreas.hansson@arm.com bool archIsDrained() const; 16210531Sandreas.hansson@arm.com 16310531Sandreas.hansson@arm.com private: 16410531Sandreas.hansson@arm.com /** 16510531Sandreas.hansson@arm.com * Support routines to update the state of the KVM CPU from gem5's 16610531Sandreas.hansson@arm.com * state representation. 16710531Sandreas.hansson@arm.com * 16810531Sandreas.hansson@arm.com * @{ 16910531Sandreas.hansson@arm.com */ 17010531Sandreas.hansson@arm.com /** Update integer registers */ 17110531Sandreas.hansson@arm.com void updateKvmStateRegs(); 17210531Sandreas.hansson@arm.com /** Update control registers (CRx, segments, etc.) */ 17310531Sandreas.hansson@arm.com void updateKvmStateSRegs(); 17410531Sandreas.hansson@arm.com /** Update FPU and SIMD registers */ 17510531Sandreas.hansson@arm.com void updateKvmStateFPU(); 17610531Sandreas.hansson@arm.com /** Update MSR registers */ 17710531Sandreas.hansson@arm.com void updateKvmStateMSRs(); 17810531Sandreas.hansson@arm.com /** @} */ 17910531Sandreas.hansson@arm.com 18010531Sandreas.hansson@arm.com /** 1818869SAli.Saidi@ARM.com * Support routines to update the state of gem5's thread context from 1828869SAli.Saidi@ARM.com * KVM's state representation. 183 * 184 * @{ 185 */ 186 /** Update integer registers */ 187 void updateThreadContextRegs(); 188 /** Update control registers (CRx, segments, etc.) */ 189 void updateThreadContextSRegs(); 190 /** Update FPU and SIMD registers */ 191 void updateThreadContextFPU(); 192 /** Update MSR registers */ 193 void updateThreadContextMSRs(); 194 /** @} */ 195 196 /** Transfer gem5's CPUID values into the virtual CPU. */ 197 void updateCPUID(); 198 199 /** 200 * Handle a 32-bit IO access that should be mapped to a MiscReg. 201 * 202 * @note This method can only be called on when handling IO after 203 * a KVM_EXIT_IO. 204 * 205 * @param miscreg Register to map the current IO access to. 206 */ 207 void handleIOMiscReg32(int miscreg); 208 209 /** Reusable IO request */ 210 Request io_req; 211 212 /** Cached intersection of supported MSRs */ 213 mutable Kvm::MSRIndexVector cachedMsrIntersection; 214 215 /** @{ */ 216 /** Kvm::capDebugRegs() available? */ 217 bool haveDebugRegs; 218 /** Kvm::capXSave() available? */ 219 bool haveXSave; 220 /** Kvm::capXCRs() available? */ 221 bool haveXCRs; 222 /** @} */ 223}; 224 225#endif 226