1/* 2 * Copyright (c) 2012 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions are 16 * met: redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer; 18 * redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution; 21 * neither the name of the copyright holders nor the names of its 22 * contributors may be used to endorse or promote products derived from 23 * this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * Authors: Andreas Sandberg 38 */ 39 40#include <linux/kvm.h> 41#include <sys/ioctl.h> 42#include <sys/mman.h> 43#include <unistd.h> 44 45#include <cerrno> 46#include <csignal> 47#include <ostream> 48 49#include "arch/utility.hh" 50#include "cpu/kvm/base.hh" 51#include "debug/Checkpoint.hh"
| 1/* 2 * Copyright (c) 2012 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions are 16 * met: redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer; 18 * redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution; 21 * neither the name of the copyright holders nor the names of its 22 * contributors may be used to endorse or promote products derived from 23 * this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * Authors: Andreas Sandberg 38 */ 39 40#include <linux/kvm.h> 41#include <sys/ioctl.h> 42#include <sys/mman.h> 43#include <unistd.h> 44 45#include <cerrno> 46#include <csignal> 47#include <ostream> 48 49#include "arch/utility.hh" 50#include "cpu/kvm/base.hh" 51#include "debug/Checkpoint.hh"
|
| 52#include "debug/Drain.hh"
|
52#include "debug/Kvm.hh" 53#include "debug/KvmIO.hh" 54#include "debug/KvmRun.hh" 55#include "params/BaseKvmCPU.hh" 56#include "sim/process.hh" 57#include "sim/system.hh" 58
| 53#include "debug/Kvm.hh" 54#include "debug/KvmIO.hh" 55#include "debug/KvmRun.hh" 56#include "params/BaseKvmCPU.hh" 57#include "sim/process.hh" 58#include "sim/system.hh" 59
|
| 60#include <signal.h> 61
|
59/* Used by some KVM macros */ 60#define PAGE_SIZE pageSize 61 62volatile bool timerOverflowed = false; 63 64static void 65onTimerOverflow(int signo, siginfo_t *si, void *data) 66{ 67 timerOverflowed = true; 68} 69 70BaseKvmCPU::BaseKvmCPU(BaseKvmCPUParams *params) 71 : BaseCPU(params), 72 vm(*params->kvmVM), 73 _status(Idle), 74 dataPort(name() + ".dcache_port", this), 75 instPort(name() + ".icache_port", this), 76 threadContextDirty(true), 77 kvmStateDirty(false), 78 vcpuID(vm.allocVCPUID()), vcpuFD(-1), vcpuMMapSize(0), 79 _kvmRun(NULL), mmioRing(NULL), 80 pageSize(sysconf(_SC_PAGE_SIZE)), 81 tickEvent(*this), 82 perfControlledByTimer(params->usePerfOverflow), 83 hostFactor(params->hostFactor),
| 62/* Used by some KVM macros */ 63#define PAGE_SIZE pageSize 64 65volatile bool timerOverflowed = false; 66 67static void 68onTimerOverflow(int signo, siginfo_t *si, void *data) 69{ 70 timerOverflowed = true; 71} 72 73BaseKvmCPU::BaseKvmCPU(BaseKvmCPUParams *params) 74 : BaseCPU(params), 75 vm(*params->kvmVM), 76 _status(Idle), 77 dataPort(name() + ".dcache_port", this), 78 instPort(name() + ".icache_port", this), 79 threadContextDirty(true), 80 kvmStateDirty(false), 81 vcpuID(vm.allocVCPUID()), vcpuFD(-1), vcpuMMapSize(0), 82 _kvmRun(NULL), mmioRing(NULL), 83 pageSize(sysconf(_SC_PAGE_SIZE)), 84 tickEvent(*this), 85 perfControlledByTimer(params->usePerfOverflow), 86 hostFactor(params->hostFactor),
|
| 87 drainManager(NULL),
|
84 ctrInsts(0) 85{ 86 if (pageSize == -1) 87 panic("KVM: Failed to determine host page size (%i)\n", 88 errno); 89 90 thread = new SimpleThread(this, 0, params->system, 91 params->itb, params->dtb, params->isa[0]); 92 thread->setStatus(ThreadContext::Halted); 93 tc = thread->getTC(); 94 threadContexts.push_back(tc); 95 96 setupCounters();
| 88 ctrInsts(0) 89{ 90 if (pageSize == -1) 91 panic("KVM: Failed to determine host page size (%i)\n", 92 errno); 93 94 thread = new SimpleThread(this, 0, params->system, 95 params->itb, params->dtb, params->isa[0]); 96 thread->setStatus(ThreadContext::Halted); 97 tc = thread->getTC(); 98 threadContexts.push_back(tc); 99 100 setupCounters();
|
97 setupSignalHandler();
| |
98 99 if (params->usePerfOverflow) 100 runTimer.reset(new PerfKvmTimer(hwCycles, 101 KVM_TIMER_SIGNAL, 102 params->hostFactor, 103 params->clock)); 104 else 105 runTimer.reset(new PosixKvmTimer(KVM_TIMER_SIGNAL, CLOCK_MONOTONIC, 106 params->hostFactor, 107 params->clock)); 108} 109 110BaseKvmCPU::~BaseKvmCPU() 111{ 112 if (_kvmRun) 113 munmap(_kvmRun, vcpuMMapSize); 114 close(vcpuFD); 115} 116 117void 118BaseKvmCPU::init() 119{ 120 BaseCPU::init(); 121 122 if (numThreads != 1) 123 fatal("KVM: Multithreading not supported"); 124 125 tc->initMemProxies(tc); 126 127 // initialize CPU, including PC 128 if (FullSystem && !switchedOut()) 129 TheISA::initCPU(tc, tc->contextId()); 130 131 mmio_req.setThreadContext(tc->contextId(), 0); 132} 133 134void 135BaseKvmCPU::startup() 136{ 137 const BaseKvmCPUParams * const p( 138 dynamic_cast<const BaseKvmCPUParams *>(params())); 139 140 Kvm &kvm(vm.kvm); 141 142 BaseCPU::startup(); 143 144 assert(vcpuFD == -1); 145 146 // Tell the VM that a CPU is about to start. 147 vm.cpuStartup(); 148 149 // We can't initialize KVM CPUs in BaseKvmCPU::init() since we are 150 // not guaranteed that the parent KVM VM has initialized at that 151 // point. Initialize virtual CPUs here instead. 152 vcpuFD = vm.createVCPU(vcpuID); 153
| 101 102 if (params->usePerfOverflow) 103 runTimer.reset(new PerfKvmTimer(hwCycles, 104 KVM_TIMER_SIGNAL, 105 params->hostFactor, 106 params->clock)); 107 else 108 runTimer.reset(new PosixKvmTimer(KVM_TIMER_SIGNAL, CLOCK_MONOTONIC, 109 params->hostFactor, 110 params->clock)); 111} 112 113BaseKvmCPU::~BaseKvmCPU() 114{ 115 if (_kvmRun) 116 munmap(_kvmRun, vcpuMMapSize); 117 close(vcpuFD); 118} 119 120void 121BaseKvmCPU::init() 122{ 123 BaseCPU::init(); 124 125 if (numThreads != 1) 126 fatal("KVM: Multithreading not supported"); 127 128 tc->initMemProxies(tc); 129 130 // initialize CPU, including PC 131 if (FullSystem && !switchedOut()) 132 TheISA::initCPU(tc, tc->contextId()); 133 134 mmio_req.setThreadContext(tc->contextId(), 0); 135} 136 137void 138BaseKvmCPU::startup() 139{ 140 const BaseKvmCPUParams * const p( 141 dynamic_cast<const BaseKvmCPUParams *>(params())); 142 143 Kvm &kvm(vm.kvm); 144 145 BaseCPU::startup(); 146 147 assert(vcpuFD == -1); 148 149 // Tell the VM that a CPU is about to start. 150 vm.cpuStartup(); 151 152 // We can't initialize KVM CPUs in BaseKvmCPU::init() since we are 153 // not guaranteed that the parent KVM VM has initialized at that 154 // point. Initialize virtual CPUs here instead. 155 vcpuFD = vm.createVCPU(vcpuID); 156
|
| 157 // Setup signal handlers. This has to be done after the vCPU is 158 // created since it manipulates the vCPU signal mask. 159 setupSignalHandler(); 160
|
154 // Map the KVM run structure */ 155 vcpuMMapSize = kvm.getVCPUMMapSize(); 156 _kvmRun = (struct kvm_run *)mmap(0, vcpuMMapSize, 157 PROT_READ | PROT_WRITE, MAP_SHARED, 158 vcpuFD, 0); 159 if (_kvmRun == MAP_FAILED) 160 panic("KVM: Failed to map run data structure\n"); 161 162 // Setup a pointer to the MMIO ring buffer if coalesced MMIO is 163 // available. The offset into the KVM's communication page is 164 // provided by the coalesced MMIO capability. 165 int mmioOffset(kvm.capCoalescedMMIO()); 166 if (!p->useCoalescedMMIO) { 167 inform("KVM: Coalesced MMIO disabled by config.\n"); 168 } else if (mmioOffset) { 169 inform("KVM: Coalesced IO available\n"); 170 mmioRing = (struct kvm_coalesced_mmio_ring *)( 171 (char *)_kvmRun + (mmioOffset * pageSize)); 172 } else { 173 inform("KVM: Coalesced not supported by host OS\n"); 174 } 175 176 thread->startup(); 177} 178 179void 180BaseKvmCPU::regStats() 181{ 182 using namespace Stats; 183 184 BaseCPU::regStats(); 185 186 numInsts 187 .name(name() + ".committedInsts") 188 .desc("Number of instructions committed") 189 ; 190 191 numVMExits 192 .name(name() + ".numVMExits") 193 .desc("total number of KVM exits") 194 ; 195 196 numMMIO 197 .name(name() + ".numMMIO") 198 .desc("number of VM exits due to memory mapped IO") 199 ; 200 201 numCoalescedMMIO 202 .name(name() + ".numCoalescedMMIO") 203 .desc("number of coalesced memory mapped IO requests") 204 ; 205 206 numIO 207 .name(name() + ".numIO") 208 .desc("number of VM exits due to legacy IO") 209 ; 210 211 numHalt 212 .name(name() + ".numHalt") 213 .desc("number of VM exits due to wait for interrupt instructions") 214 ; 215 216 numInterrupts 217 .name(name() + ".numInterrupts") 218 .desc("number of interrupts delivered") 219 ; 220 221 numHypercalls 222 .name(name() + ".numHypercalls") 223 .desc("number of hypercalls") 224 ; 225} 226 227void 228BaseKvmCPU::serializeThread(std::ostream &os, ThreadID tid) 229{ 230 if (DTRACE(Checkpoint)) { 231 DPRINTF(Checkpoint, "KVM: Serializing thread %i:\n", tid); 232 dump(); 233 } 234
| 161 // Map the KVM run structure */ 162 vcpuMMapSize = kvm.getVCPUMMapSize(); 163 _kvmRun = (struct kvm_run *)mmap(0, vcpuMMapSize, 164 PROT_READ | PROT_WRITE, MAP_SHARED, 165 vcpuFD, 0); 166 if (_kvmRun == MAP_FAILED) 167 panic("KVM: Failed to map run data structure\n"); 168 169 // Setup a pointer to the MMIO ring buffer if coalesced MMIO is 170 // available. The offset into the KVM's communication page is 171 // provided by the coalesced MMIO capability. 172 int mmioOffset(kvm.capCoalescedMMIO()); 173 if (!p->useCoalescedMMIO) { 174 inform("KVM: Coalesced MMIO disabled by config.\n"); 175 } else if (mmioOffset) { 176 inform("KVM: Coalesced IO available\n"); 177 mmioRing = (struct kvm_coalesced_mmio_ring *)( 178 (char *)_kvmRun + (mmioOffset * pageSize)); 179 } else { 180 inform("KVM: Coalesced not supported by host OS\n"); 181 } 182 183 thread->startup(); 184} 185 186void 187BaseKvmCPU::regStats() 188{ 189 using namespace Stats; 190 191 BaseCPU::regStats(); 192 193 numInsts 194 .name(name() + ".committedInsts") 195 .desc("Number of instructions committed") 196 ; 197 198 numVMExits 199 .name(name() + ".numVMExits") 200 .desc("total number of KVM exits") 201 ; 202 203 numMMIO 204 .name(name() + ".numMMIO") 205 .desc("number of VM exits due to memory mapped IO") 206 ; 207 208 numCoalescedMMIO 209 .name(name() + ".numCoalescedMMIO") 210 .desc("number of coalesced memory mapped IO requests") 211 ; 212 213 numIO 214 .name(name() + ".numIO") 215 .desc("number of VM exits due to legacy IO") 216 ; 217 218 numHalt 219 .name(name() + ".numHalt") 220 .desc("number of VM exits due to wait for interrupt instructions") 221 ; 222 223 numInterrupts 224 .name(name() + ".numInterrupts") 225 .desc("number of interrupts delivered") 226 ; 227 228 numHypercalls 229 .name(name() + ".numHypercalls") 230 .desc("number of hypercalls") 231 ; 232} 233 234void 235BaseKvmCPU::serializeThread(std::ostream &os, ThreadID tid) 236{ 237 if (DTRACE(Checkpoint)) { 238 DPRINTF(Checkpoint, "KVM: Serializing thread %i:\n", tid); 239 dump(); 240 } 241
|
235 // Update the thread context so we have something to serialize. 236 syncThreadContext(); 237
| |
238 assert(tid == 0); 239 assert(_status == Idle); 240 thread->serialize(os); 241} 242 243void 244BaseKvmCPU::unserializeThread(Checkpoint *cp, const std::string §ion, 245 ThreadID tid) 246{ 247 DPRINTF(Checkpoint, "KVM: Unserialize thread %i:\n", tid); 248 249 assert(tid == 0); 250 assert(_status == Idle); 251 thread->unserialize(cp, section); 252 threadContextDirty = true; 253} 254 255unsigned int 256BaseKvmCPU::drain(DrainManager *dm) 257{ 258 if (switchedOut()) 259 return 0; 260
| 242 assert(tid == 0); 243 assert(_status == Idle); 244 thread->serialize(os); 245} 246 247void 248BaseKvmCPU::unserializeThread(Checkpoint *cp, const std::string §ion, 249 ThreadID tid) 250{ 251 DPRINTF(Checkpoint, "KVM: Unserialize thread %i:\n", tid); 252 253 assert(tid == 0); 254 assert(_status == Idle); 255 thread->unserialize(cp, section); 256 threadContextDirty = true; 257} 258 259unsigned int 260BaseKvmCPU::drain(DrainManager *dm) 261{ 262 if (switchedOut()) 263 return 0; 264
|
261 DPRINTF(Kvm, "drain\n");
| 265 DPRINTF(Drain, "BaseKvmCPU::drain\n"); 266 switch (_status) { 267 case Running: 268 // The base KVM code is normally ready when it is in the 269 // Running state, but the architecture specific code might be 270 // of a different opinion. This may happen when the CPU been 271 // notified of an event that hasn't been accepted by the vCPU 272 // yet. 273 if (!archIsDrained()) { 274 drainManager = dm; 275 return 1; 276 }
|
262
| 277
|
263 // De-schedule the tick event so we don't insert any more MMIOs 264 // into the system while it is draining. 265 if (tickEvent.scheduled()) 266 deschedule(tickEvent);
| 278 // The state of the CPU is consistent, so we don't need to do 279 // anything special to drain it. We simply de-schedule the 280 // tick event and enter the Idle state to prevent nasty things 281 // like MMIOs from happening. 282 if (tickEvent.scheduled()) 283 deschedule(tickEvent); 284 _status = Idle;
|
267
| 285
|
268 _status = Idle; 269 return 0;
| 286 /** FALLTHROUGH */ 287 case Idle: 288 // Idle, no need to drain 289 assert(!tickEvent.scheduled()); 290 291 // Sync the thread context here since we'll need it when we 292 // switch CPUs or checkpoint the CPU. 293 syncThreadContext(); 294 295 return 0; 296 297 case RunningServiceCompletion: 298 // The CPU has just requested a service that was handled in 299 // the RunningService state, but the results have still not 300 // been reported to the CPU. Now, we /could/ probably just 301 // update the register state ourselves instead of letting KVM 302 // handle it, but that would be tricky. Instead, we enter KVM 303 // and let it do its stuff. 304 drainManager = dm; 305 306 DPRINTF(Drain, "KVM CPU is waiting for service completion, " 307 "requesting drain.\n"); 308 return 1; 309 310 case RunningService: 311 // We need to drain since the CPU is waiting for service (e.g., MMIOs) 312 drainManager = dm; 313 314 DPRINTF(Drain, "KVM CPU is waiting for service, requesting drain.\n"); 315 return 1; 316 317 default: 318 panic("KVM: Unhandled CPU state in drain()\n"); 319 return 0; 320 }
|
270} 271 272void 273BaseKvmCPU::drainResume() 274{ 275 assert(!tickEvent.scheduled()); 276 277 // We might have been switched out. In that case, we don't need to 278 // do anything. 279 if (switchedOut()) 280 return; 281 282 DPRINTF(Kvm, "drainResume\n"); 283 verifyMemoryMode(); 284 285 // The tick event is de-scheduled as a part of the draining 286 // process. Re-schedule it if the thread context is active. 287 if (tc->status() == ThreadContext::Active) { 288 schedule(tickEvent, nextCycle()); 289 _status = Running; 290 } else { 291 _status = Idle; 292 } 293} 294 295void 296BaseKvmCPU::switchOut() 297{ 298 DPRINTF(Kvm, "switchOut\n"); 299
| 321} 322 323void 324BaseKvmCPU::drainResume() 325{ 326 assert(!tickEvent.scheduled()); 327 328 // We might have been switched out. In that case, we don't need to 329 // do anything. 330 if (switchedOut()) 331 return; 332 333 DPRINTF(Kvm, "drainResume\n"); 334 verifyMemoryMode(); 335 336 // The tick event is de-scheduled as a part of the draining 337 // process. Re-schedule it if the thread context is active. 338 if (tc->status() == ThreadContext::Active) { 339 schedule(tickEvent, nextCycle()); 340 _status = Running; 341 } else { 342 _status = Idle; 343 } 344} 345 346void 347BaseKvmCPU::switchOut() 348{ 349 DPRINTF(Kvm, "switchOut\n"); 350
|
300 // Make sure to update the thread context in case, the new CPU 301 // will need to access it. 302 syncThreadContext(); 303
| |
304 BaseCPU::switchOut(); 305 306 // We should have drained prior to executing a switchOut, which 307 // means that the tick event shouldn't be scheduled and the CPU is 308 // idle. 309 assert(!tickEvent.scheduled()); 310 assert(_status == Idle); 311} 312 313void 314BaseKvmCPU::takeOverFrom(BaseCPU *cpu) 315{ 316 DPRINTF(Kvm, "takeOverFrom\n"); 317 318 BaseCPU::takeOverFrom(cpu); 319 320 // We should have drained prior to executing a switchOut, which 321 // means that the tick event shouldn't be scheduled and the CPU is 322 // idle. 323 assert(!tickEvent.scheduled()); 324 assert(_status == Idle); 325 assert(threadContexts.size() == 1); 326
| 351 BaseCPU::switchOut(); 352 353 // We should have drained prior to executing a switchOut, which 354 // means that the tick event shouldn't be scheduled and the CPU is 355 // idle. 356 assert(!tickEvent.scheduled()); 357 assert(_status == Idle); 358} 359 360void 361BaseKvmCPU::takeOverFrom(BaseCPU *cpu) 362{ 363 DPRINTF(Kvm, "takeOverFrom\n"); 364 365 BaseCPU::takeOverFrom(cpu); 366 367 // We should have drained prior to executing a switchOut, which 368 // means that the tick event shouldn't be scheduled and the CPU is 369 // idle. 370 assert(!tickEvent.scheduled()); 371 assert(_status == Idle); 372 assert(threadContexts.size() == 1); 373
|
327 // The BaseCPU updated the thread context, make sure that we 328 // synchronize next time we enter start the CPU. 329 threadContextDirty = true;
| 374 // Force an update of the KVM state here instead of flagging the 375 // TC as dirty. This is not ideal from a performance point of 376 // view, but it makes debugging easier as it allows meaningful KVM 377 // state to be dumped before and after a takeover. 378 updateKvmState(); 379 threadContextDirty = false;
|
330} 331 332void 333BaseKvmCPU::verifyMemoryMode() const 334{ 335 if (!(system->isAtomicMode() && system->bypassCaches())) { 336 fatal("The KVM-based CPUs requires the memory system to be in the " 337 "'atomic_noncaching' mode.\n"); 338 } 339} 340 341void 342BaseKvmCPU::wakeup() 343{ 344 DPRINTF(Kvm, "wakeup()\n"); 345 346 if (thread->status() != ThreadContext::Suspended) 347 return; 348 349 thread->activate(); 350} 351 352void 353BaseKvmCPU::activateContext(ThreadID thread_num, Cycles delay) 354{ 355 DPRINTF(Kvm, "ActivateContext %d (%d cycles)\n", thread_num, delay); 356 357 assert(thread_num == 0); 358 assert(thread); 359 360 assert(_status == Idle); 361 assert(!tickEvent.scheduled()); 362 363 numCycles += ticksToCycles(thread->lastActivate - thread->lastSuspend) 364 * hostFactor; 365 366 schedule(tickEvent, clockEdge(delay)); 367 _status = Running; 368} 369 370 371void 372BaseKvmCPU::suspendContext(ThreadID thread_num) 373{ 374 DPRINTF(Kvm, "SuspendContext %d\n", thread_num); 375 376 assert(thread_num == 0); 377 assert(thread); 378 379 if (_status == Idle) 380 return; 381 382 assert(_status == Running); 383 384 // The tick event may no be scheduled if the quest has requested 385 // the monitor to wait for interrupts. The normal CPU models can 386 // get their tick events descheduled by quiesce instructions, but 387 // that can't happen here. 388 if (tickEvent.scheduled()) 389 deschedule(tickEvent); 390 391 _status = Idle; 392} 393 394void 395BaseKvmCPU::deallocateContext(ThreadID thread_num) 396{ 397 // for now, these are equivalent 398 suspendContext(thread_num); 399} 400 401void 402BaseKvmCPU::haltContext(ThreadID thread_num) 403{ 404 // for now, these are equivalent 405 suspendContext(thread_num); 406} 407 408ThreadContext * 409BaseKvmCPU::getContext(int tn) 410{ 411 assert(tn == 0); 412 syncThreadContext(); 413 return tc; 414} 415 416 417Counter 418BaseKvmCPU::totalInsts() const 419{ 420 return ctrInsts; 421} 422 423Counter 424BaseKvmCPU::totalOps() const 425{ 426 hack_once("Pretending totalOps is equivalent to totalInsts()\n"); 427 return ctrInsts; 428} 429 430void 431BaseKvmCPU::dump() 432{ 433 inform("State dumping not implemented."); 434} 435 436void 437BaseKvmCPU::tick() 438{
| 380} 381 382void 383BaseKvmCPU::verifyMemoryMode() const 384{ 385 if (!(system->isAtomicMode() && system->bypassCaches())) { 386 fatal("The KVM-based CPUs requires the memory system to be in the " 387 "'atomic_noncaching' mode.\n"); 388 } 389} 390 391void 392BaseKvmCPU::wakeup() 393{ 394 DPRINTF(Kvm, "wakeup()\n"); 395 396 if (thread->status() != ThreadContext::Suspended) 397 return; 398 399 thread->activate(); 400} 401 402void 403BaseKvmCPU::activateContext(ThreadID thread_num, Cycles delay) 404{ 405 DPRINTF(Kvm, "ActivateContext %d (%d cycles)\n", thread_num, delay); 406 407 assert(thread_num == 0); 408 assert(thread); 409 410 assert(_status == Idle); 411 assert(!tickEvent.scheduled()); 412 413 numCycles += ticksToCycles(thread->lastActivate - thread->lastSuspend) 414 * hostFactor; 415 416 schedule(tickEvent, clockEdge(delay)); 417 _status = Running; 418} 419 420 421void 422BaseKvmCPU::suspendContext(ThreadID thread_num) 423{ 424 DPRINTF(Kvm, "SuspendContext %d\n", thread_num); 425 426 assert(thread_num == 0); 427 assert(thread); 428 429 if (_status == Idle) 430 return; 431 432 assert(_status == Running); 433 434 // The tick event may no be scheduled if the quest has requested 435 // the monitor to wait for interrupts. The normal CPU models can 436 // get their tick events descheduled by quiesce instructions, but 437 // that can't happen here. 438 if (tickEvent.scheduled()) 439 deschedule(tickEvent); 440 441 _status = Idle; 442} 443 444void 445BaseKvmCPU::deallocateContext(ThreadID thread_num) 446{ 447 // for now, these are equivalent 448 suspendContext(thread_num); 449} 450 451void 452BaseKvmCPU::haltContext(ThreadID thread_num) 453{ 454 // for now, these are equivalent 455 suspendContext(thread_num); 456} 457 458ThreadContext * 459BaseKvmCPU::getContext(int tn) 460{ 461 assert(tn == 0); 462 syncThreadContext(); 463 return tc; 464} 465 466 467Counter 468BaseKvmCPU::totalInsts() const 469{ 470 return ctrInsts; 471} 472 473Counter 474BaseKvmCPU::totalOps() const 475{ 476 hack_once("Pretending totalOps is equivalent to totalInsts()\n"); 477 return ctrInsts; 478} 479 480void 481BaseKvmCPU::dump() 482{ 483 inform("State dumping not implemented."); 484} 485 486void 487BaseKvmCPU::tick() 488{
|
439 assert(_status == Running);
| 489 Tick delay(0); 490 assert(_status != Idle);
|
440
| 491
|
441 DPRINTF(KvmRun, "Entering KVM...\n");
| 492 switch (_status) { 493 case RunningService: 494 // handleKvmExit() will determine the next state of the CPU 495 delay = handleKvmExit();
|
442
| 496
|
443 Tick ticksToExecute(mainEventQueue.nextTick() - curTick()); 444 Tick ticksExecuted(kvmRun(ticksToExecute));
| 497 if (tryDrain()) 498 _status = Idle; 499 break;
|
445
| 500
|
446 Tick delay(ticksExecuted + handleKvmExit());
| 501 case RunningServiceCompletion: 502 case Running: { 503 Tick ticksToExecute(mainEventQueue.nextTick() - curTick());
|
447
| 504
|
448 switch (_status) { 449 case Running: 450 schedule(tickEvent, clockEdge(ticksToCycles(delay))); 451 break;
| 505 // We might need to update the KVM state. 506 syncKvmState();
|
452
| 507
|
| 508 DPRINTF(KvmRun, "Entering KVM...\n"); 509 if (drainManager) { 510 // Force an immediate exit from KVM after completing 511 // pending operations. The architecture-specific code 512 // takes care to run until it is in a state where it can 513 // safely be drained. 514 delay = kvmRunDrain(); 515 } else { 516 delay = kvmRun(ticksToExecute); 517 } 518 519 // Entering into KVM implies that we'll have to reload the thread 520 // context from KVM if we want to access it. Flag the KVM state as 521 // dirty with respect to the cached thread context. 522 kvmStateDirty = true; 523 524 // Enter into the RunningService state unless the 525 // simulation was stopped by a timer. 526 if (_kvmRun->exit_reason != KVM_EXIT_INTR) 527 _status = RunningService; 528 else 529 _status = Running; 530 531 if (tryDrain()) 532 _status = Idle; 533 } break; 534
|
453 default:
| 535 default:
|
454 /* The CPU is halted or waiting for an interrupt from a 455 * device. Don't start it. */ 456 break;
| 536 panic("BaseKvmCPU entered tick() in an illegal state (%i)\n", 537 _status);
|
457 }
| 538 }
|
| 539 540 // Schedule a new tick if we are still running 541 if (_status != Idle) 542 schedule(tickEvent, clockEdge(ticksToCycles(delay)));
|
458} 459
| 543} 544
|
| 545Tick 546BaseKvmCPU::kvmRunDrain() 547{ 548 // By default, the only thing we need to drain is a pending IO 549 // operation which assumes that we are in the 550 // RunningServiceCompletion state. 551 assert(_status == RunningServiceCompletion); 552 553 // Deliver the data from the pending IO operation and immediately 554 // exit. 555 return kvmRun(0); 556} 557
|
460uint64_t 461BaseKvmCPU::getHostCycles() const 462{ 463 return hwCycles.read(); 464} 465 466Tick 467BaseKvmCPU::kvmRun(Tick ticks) 468{
| 558uint64_t 559BaseKvmCPU::getHostCycles() const 560{ 561 return hwCycles.read(); 562} 563 564Tick 565BaseKvmCPU::kvmRun(Tick ticks) 566{
|
469 // We might need to update the KVM state. 470 syncKvmState(); 471 // Entering into KVM implies that we'll have to reload the thread 472 // context from KVM if we want to access it. Flag the KVM state as 473 // dirty with respect to the cached thread context. 474 kvmStateDirty = true; 475 476 if (ticks < runTimer->resolution()) { 477 DPRINTF(KvmRun, "KVM: Adjusting tick count (%i -> %i)\n", 478 ticks, runTimer->resolution()); 479 ticks = runTimer->resolution(); 480 } 481
| 567 Tick ticksExecuted;
|
482 DPRINTF(KvmRun, "KVM: Executing for %i ticks\n", ticks); 483 timerOverflowed = false; 484
| 568 DPRINTF(KvmRun, "KVM: Executing for %i ticks\n", ticks); 569 timerOverflowed = false; 570
|
485 // Get hardware statistics after synchronizing contexts. The KVM 486 // state update might affect guest cycle counters. 487 uint64_t baseCycles(getHostCycles()); 488 uint64_t baseInstrs(hwInstructions.read());
| 571 if (ticks == 0) { 572 // Settings ticks == 0 is a special case which causes an entry 573 // into KVM that finishes pending operations (e.g., IO) and 574 // then immediately exits. 575 DPRINTF(KvmRun, "KVM: Delivering IO without full guest entry\n");
|
489
| 576
|
490 // Arm the run timer and start the cycle timer if it isn't 491 // controlled by the overflow timer. Starting/stopping the cycle 492 // timer automatically starts the other perf timers as they are in 493 // the same counter group. 494 runTimer->arm(ticks); 495 if (!perfControlledByTimer) 496 hwCycles.start();
| 577 // This signal is always masked while we are executing in gem5 578 // and gets unmasked temporarily as soon as we enter into 579 // KVM. See setSignalMask() and setupSignalHandler(). 580 raise(KVM_TIMER_SIGNAL);
|
497
| 581
|
498 if (ioctl(KVM_RUN) == -1) { 499 if (errno != EINTR) 500 panic("KVM: Failed to start virtual CPU (errno: %i)\n", 501 errno); 502 }
| 582 // Enter into KVM. KVM will check for signals after completing 583 // pending operations (IO). Since the KVM_TIMER_SIGNAL is 584 // pending, this forces an immediate exit into gem5 again. We 585 // don't bother to setup timers since this shouldn't actually 586 // execute any code in the guest. 587 ioctlRun();
|
503
| 588
|
504 runTimer->disarm(); 505 if (!perfControlledByTimer) 506 hwCycles.stop();
| 589 // We always execute at least one cycle to prevent the 590 // BaseKvmCPU::tick() to be rescheduled on the same tick 591 // twice. 592 ticksExecuted = clockPeriod(); 593 } else { 594 if (ticks < runTimer->resolution()) { 595 DPRINTF(KvmRun, "KVM: Adjusting tick count (%i -> %i)\n", 596 ticks, runTimer->resolution()); 597 ticks = runTimer->resolution(); 598 }
|
507
| 599
|
| 600 // Get hardware statistics after synchronizing contexts. The KVM 601 // state update might affect guest cycle counters. 602 uint64_t baseCycles(getHostCycles()); 603 uint64_t baseInstrs(hwInstructions.read());
|
508
| 604
|
509 const uint64_t hostCyclesExecuted(getHostCycles() - baseCycles); 510 const uint64_t simCyclesExecuted(hostCyclesExecuted * hostFactor); 511 const uint64_t instsExecuted(hwInstructions.read() - baseInstrs); 512 const Tick ticksExecuted(runTimer->ticksFromHostCycles(hostCyclesExecuted));
| 605 // Arm the run timer and start the cycle timer if it isn't 606 // controlled by the overflow timer. Starting/stopping the cycle 607 // timer automatically starts the other perf timers as they are in 608 // the same counter group. 609 runTimer->arm(ticks); 610 if (!perfControlledByTimer) 611 hwCycles.start();
|
513
| 612
|
514 if (ticksExecuted < ticks && 515 timerOverflowed && 516 _kvmRun->exit_reason == KVM_EXIT_INTR) { 517 // TODO: We should probably do something clever here... 518 warn("KVM: Early timer event, requested %i ticks but got %i ticks.\n", 519 ticks, ticksExecuted);
| 613 ioctlRun(); 614 615 runTimer->disarm(); 616 if (!perfControlledByTimer) 617 hwCycles.stop(); 618 619 // The timer signal may have been delivered after we exited 620 // from KVM. It will be pending in that case since it is 621 // masked when we aren't executing in KVM. Discard it to make 622 // sure we don't deliver it immediately next time we try to 623 // enter into KVM. 624 discardPendingSignal(KVM_TIMER_SIGNAL); 625 626 const uint64_t hostCyclesExecuted(getHostCycles() - baseCycles); 627 const uint64_t simCyclesExecuted(hostCyclesExecuted * hostFactor); 628 const uint64_t instsExecuted(hwInstructions.read() - baseInstrs); 629 ticksExecuted = runTimer->ticksFromHostCycles(hostCyclesExecuted); 630 631 if (ticksExecuted < ticks && 632 timerOverflowed && 633 _kvmRun->exit_reason == KVM_EXIT_INTR) { 634 // TODO: We should probably do something clever here... 635 warn("KVM: Early timer event, requested %i ticks but got %i ticks.\n", 636 ticks, ticksExecuted); 637 } 638 639 /* Update statistics */ 640 numCycles += simCyclesExecuted;; 641 numInsts += instsExecuted; 642 ctrInsts += instsExecuted; 643 system->totalNumInsts += instsExecuted; 644 645 DPRINTF(KvmRun, 646 "KVM: Executed %i instructions in %i cycles " 647 "(%i ticks, sim cycles: %i).\n", 648 instsExecuted, hostCyclesExecuted, ticksExecuted, simCyclesExecuted);
|
520 } 521
| 649 } 650
|
522 /* Update statistics */ 523 numCycles += simCyclesExecuted;;
| |
524 ++numVMExits;
| 651 ++numVMExits;
|
525 numInsts += instsExecuted; 526 ctrInsts += instsExecuted; 527 system->totalNumInsts += instsExecuted;
| |
528
| 652
|
529 DPRINTF(KvmRun, "KVM: Executed %i instructions in %i cycles (%i ticks, sim cycles: %i).\n", 530 instsExecuted, hostCyclesExecuted, ticksExecuted, simCyclesExecuted); 531
| |
532 return ticksExecuted + flushCoalescedMMIO(); 533} 534 535void 536BaseKvmCPU::kvmNonMaskableInterrupt() 537{ 538 ++numInterrupts; 539 if (ioctl(KVM_NMI) == -1) 540 panic("KVM: Failed to deliver NMI to virtual CPU\n"); 541} 542 543void 544BaseKvmCPU::kvmInterrupt(const struct kvm_interrupt &interrupt) 545{ 546 ++numInterrupts; 547 if (ioctl(KVM_INTERRUPT, (void *)&interrupt) == -1) 548 panic("KVM: Failed to deliver interrupt to virtual CPU\n"); 549} 550 551void 552BaseKvmCPU::getRegisters(struct kvm_regs ®s) const 553{ 554 if (ioctl(KVM_GET_REGS, ®s) == -1) 555 panic("KVM: Failed to get guest registers\n"); 556} 557 558void 559BaseKvmCPU::setRegisters(const struct kvm_regs ®s) 560{ 561 if (ioctl(KVM_SET_REGS, (void *)®s) == -1) 562 panic("KVM: Failed to set guest registers\n"); 563} 564 565void 566BaseKvmCPU::getSpecialRegisters(struct kvm_sregs ®s) const 567{ 568 if (ioctl(KVM_GET_SREGS, ®s) == -1) 569 panic("KVM: Failed to get guest special registers\n"); 570} 571 572void 573BaseKvmCPU::setSpecialRegisters(const struct kvm_sregs ®s) 574{ 575 if (ioctl(KVM_SET_SREGS, (void *)®s) == -1) 576 panic("KVM: Failed to set guest special registers\n"); 577} 578 579void 580BaseKvmCPU::getFPUState(struct kvm_fpu &state) const 581{ 582 if (ioctl(KVM_GET_FPU, &state) == -1) 583 panic("KVM: Failed to get guest FPU state\n"); 584} 585 586void 587BaseKvmCPU::setFPUState(const struct kvm_fpu &state) 588{ 589 if (ioctl(KVM_SET_FPU, (void *)&state) == -1) 590 panic("KVM: Failed to set guest FPU state\n"); 591} 592 593 594void 595BaseKvmCPU::setOneReg(uint64_t id, const void *addr) 596{ 597#ifdef KVM_SET_ONE_REG 598 struct kvm_one_reg reg; 599 reg.id = id; 600 reg.addr = (uint64_t)addr; 601 602 if (ioctl(KVM_SET_ONE_REG, ®) == -1) { 603 panic("KVM: Failed to set register (0x%x) value (errno: %i)\n", 604 id, errno); 605 } 606#else 607 panic("KVM_SET_ONE_REG is unsupported on this platform.\n"); 608#endif 609} 610 611void 612BaseKvmCPU::getOneReg(uint64_t id, void *addr) const 613{ 614#ifdef KVM_GET_ONE_REG 615 struct kvm_one_reg reg; 616 reg.id = id; 617 reg.addr = (uint64_t)addr; 618 619 if (ioctl(KVM_GET_ONE_REG, ®) == -1) { 620 panic("KVM: Failed to get register (0x%x) value (errno: %i)\n", 621 id, errno); 622 } 623#else 624 panic("KVM_GET_ONE_REG is unsupported on this platform.\n"); 625#endif 626} 627 628std::string 629BaseKvmCPU::getAndFormatOneReg(uint64_t id) const 630{ 631#ifdef KVM_GET_ONE_REG 632 std::ostringstream ss; 633 634 ss.setf(std::ios::hex, std::ios::basefield); 635 ss.setf(std::ios::showbase); 636#define HANDLE_INTTYPE(len) \ 637 case KVM_REG_SIZE_U ## len: { \ 638 uint ## len ## _t value; \ 639 getOneReg(id, &value); \ 640 ss << value; \ 641 } break 642 643#define HANDLE_ARRAY(len) \ 644 case KVM_REG_SIZE_U ## len: { \ 645 uint8_t value[len / 8]; \ 646 getOneReg(id, value); \ 647 ss << "[" << value[0]; \ 648 for (int i = 1; i < len / 8; ++i) \ 649 ss << ", " << value[i]; \ 650 ss << "]"; \ 651 } break 652 653 switch (id & KVM_REG_SIZE_MASK) { 654 HANDLE_INTTYPE(8); 655 HANDLE_INTTYPE(16); 656 HANDLE_INTTYPE(32); 657 HANDLE_INTTYPE(64); 658 HANDLE_ARRAY(128); 659 HANDLE_ARRAY(256); 660 HANDLE_ARRAY(512); 661 HANDLE_ARRAY(1024); 662 default: 663 ss << "??"; 664 } 665 666#undef HANDLE_INTTYPE 667#undef HANDLE_ARRAY 668 669 return ss.str(); 670#else 671 panic("KVM_GET_ONE_REG is unsupported on this platform.\n"); 672#endif 673} 674 675void 676BaseKvmCPU::syncThreadContext() 677{ 678 if (!kvmStateDirty) 679 return; 680 681 assert(!threadContextDirty); 682 683 updateThreadContext(); 684 kvmStateDirty = false; 685} 686 687void 688BaseKvmCPU::syncKvmState() 689{ 690 if (!threadContextDirty) 691 return; 692 693 assert(!kvmStateDirty); 694 695 updateKvmState(); 696 threadContextDirty = false; 697} 698 699Tick 700BaseKvmCPU::handleKvmExit() 701{ 702 DPRINTF(KvmRun, "handleKvmExit (exit_reason: %i)\n", _kvmRun->exit_reason);
| 653 return ticksExecuted + flushCoalescedMMIO(); 654} 655 656void 657BaseKvmCPU::kvmNonMaskableInterrupt() 658{ 659 ++numInterrupts; 660 if (ioctl(KVM_NMI) == -1) 661 panic("KVM: Failed to deliver NMI to virtual CPU\n"); 662} 663 664void 665BaseKvmCPU::kvmInterrupt(const struct kvm_interrupt &interrupt) 666{ 667 ++numInterrupts; 668 if (ioctl(KVM_INTERRUPT, (void *)&interrupt) == -1) 669 panic("KVM: Failed to deliver interrupt to virtual CPU\n"); 670} 671 672void 673BaseKvmCPU::getRegisters(struct kvm_regs ®s) const 674{ 675 if (ioctl(KVM_GET_REGS, ®s) == -1) 676 panic("KVM: Failed to get guest registers\n"); 677} 678 679void 680BaseKvmCPU::setRegisters(const struct kvm_regs ®s) 681{ 682 if (ioctl(KVM_SET_REGS, (void *)®s) == -1) 683 panic("KVM: Failed to set guest registers\n"); 684} 685 686void 687BaseKvmCPU::getSpecialRegisters(struct kvm_sregs ®s) const 688{ 689 if (ioctl(KVM_GET_SREGS, ®s) == -1) 690 panic("KVM: Failed to get guest special registers\n"); 691} 692 693void 694BaseKvmCPU::setSpecialRegisters(const struct kvm_sregs ®s) 695{ 696 if (ioctl(KVM_SET_SREGS, (void *)®s) == -1) 697 panic("KVM: Failed to set guest special registers\n"); 698} 699 700void 701BaseKvmCPU::getFPUState(struct kvm_fpu &state) const 702{ 703 if (ioctl(KVM_GET_FPU, &state) == -1) 704 panic("KVM: Failed to get guest FPU state\n"); 705} 706 707void 708BaseKvmCPU::setFPUState(const struct kvm_fpu &state) 709{ 710 if (ioctl(KVM_SET_FPU, (void *)&state) == -1) 711 panic("KVM: Failed to set guest FPU state\n"); 712} 713 714 715void 716BaseKvmCPU::setOneReg(uint64_t id, const void *addr) 717{ 718#ifdef KVM_SET_ONE_REG 719 struct kvm_one_reg reg; 720 reg.id = id; 721 reg.addr = (uint64_t)addr; 722 723 if (ioctl(KVM_SET_ONE_REG, ®) == -1) { 724 panic("KVM: Failed to set register (0x%x) value (errno: %i)\n", 725 id, errno); 726 } 727#else 728 panic("KVM_SET_ONE_REG is unsupported on this platform.\n"); 729#endif 730} 731 732void 733BaseKvmCPU::getOneReg(uint64_t id, void *addr) const 734{ 735#ifdef KVM_GET_ONE_REG 736 struct kvm_one_reg reg; 737 reg.id = id; 738 reg.addr = (uint64_t)addr; 739 740 if (ioctl(KVM_GET_ONE_REG, ®) == -1) { 741 panic("KVM: Failed to get register (0x%x) value (errno: %i)\n", 742 id, errno); 743 } 744#else 745 panic("KVM_GET_ONE_REG is unsupported on this platform.\n"); 746#endif 747} 748 749std::string 750BaseKvmCPU::getAndFormatOneReg(uint64_t id) const 751{ 752#ifdef KVM_GET_ONE_REG 753 std::ostringstream ss; 754 755 ss.setf(std::ios::hex, std::ios::basefield); 756 ss.setf(std::ios::showbase); 757#define HANDLE_INTTYPE(len) \ 758 case KVM_REG_SIZE_U ## len: { \ 759 uint ## len ## _t value; \ 760 getOneReg(id, &value); \ 761 ss << value; \ 762 } break 763 764#define HANDLE_ARRAY(len) \ 765 case KVM_REG_SIZE_U ## len: { \ 766 uint8_t value[len / 8]; \ 767 getOneReg(id, value); \ 768 ss << "[" << value[0]; \ 769 for (int i = 1; i < len / 8; ++i) \ 770 ss << ", " << value[i]; \ 771 ss << "]"; \ 772 } break 773 774 switch (id & KVM_REG_SIZE_MASK) { 775 HANDLE_INTTYPE(8); 776 HANDLE_INTTYPE(16); 777 HANDLE_INTTYPE(32); 778 HANDLE_INTTYPE(64); 779 HANDLE_ARRAY(128); 780 HANDLE_ARRAY(256); 781 HANDLE_ARRAY(512); 782 HANDLE_ARRAY(1024); 783 default: 784 ss << "??"; 785 } 786 787#undef HANDLE_INTTYPE 788#undef HANDLE_ARRAY 789 790 return ss.str(); 791#else 792 panic("KVM_GET_ONE_REG is unsupported on this platform.\n"); 793#endif 794} 795 796void 797BaseKvmCPU::syncThreadContext() 798{ 799 if (!kvmStateDirty) 800 return; 801 802 assert(!threadContextDirty); 803 804 updateThreadContext(); 805 kvmStateDirty = false; 806} 807 808void 809BaseKvmCPU::syncKvmState() 810{ 811 if (!threadContextDirty) 812 return; 813 814 assert(!kvmStateDirty); 815 816 updateKvmState(); 817 threadContextDirty = false; 818} 819 820Tick 821BaseKvmCPU::handleKvmExit() 822{ 823 DPRINTF(KvmRun, "handleKvmExit (exit_reason: %i)\n", _kvmRun->exit_reason);
|
| 824 assert(_status == RunningService);
|
703
| 825
|
| 826 // Switch into the running state by default. Individual handlers 827 // can override this. 828 _status = Running;
|
704 switch (_kvmRun->exit_reason) { 705 case KVM_EXIT_UNKNOWN: 706 return handleKvmExitUnknown(); 707 708 case KVM_EXIT_EXCEPTION: 709 return handleKvmExitException(); 710 711 case KVM_EXIT_IO:
| 829 switch (_kvmRun->exit_reason) { 830 case KVM_EXIT_UNKNOWN: 831 return handleKvmExitUnknown(); 832 833 case KVM_EXIT_EXCEPTION: 834 return handleKvmExitException(); 835 836 case KVM_EXIT_IO:
|
| 837 _status = RunningServiceCompletion;
|
712 ++numIO; 713 return handleKvmExitIO(); 714 715 case KVM_EXIT_HYPERCALL: 716 ++numHypercalls; 717 return handleKvmExitHypercall(); 718 719 case KVM_EXIT_HLT: 720 /* The guest has halted and is waiting for interrupts */ 721 DPRINTF(Kvm, "handleKvmExitHalt\n"); 722 ++numHalt; 723 724 // Suspend the thread until the next interrupt arrives 725 thread->suspend(); 726 727 // This is actually ignored since the thread is suspended. 728 return 0; 729 730 case KVM_EXIT_MMIO:
| 838 ++numIO; 839 return handleKvmExitIO(); 840 841 case KVM_EXIT_HYPERCALL: 842 ++numHypercalls; 843 return handleKvmExitHypercall(); 844 845 case KVM_EXIT_HLT: 846 /* The guest has halted and is waiting for interrupts */ 847 DPRINTF(Kvm, "handleKvmExitHalt\n"); 848 ++numHalt; 849 850 // Suspend the thread until the next interrupt arrives 851 thread->suspend(); 852 853 // This is actually ignored since the thread is suspended. 854 return 0; 855 856 case KVM_EXIT_MMIO:
|
| 857 _status = RunningServiceCompletion;
|
731 /* Service memory mapped IO requests */ 732 DPRINTF(KvmIO, "KVM: Handling MMIO (w: %u, addr: 0x%x, len: %u)\n", 733 _kvmRun->mmio.is_write, 734 _kvmRun->mmio.phys_addr, _kvmRun->mmio.len); 735 736 ++numMMIO; 737 return doMMIOAccess(_kvmRun->mmio.phys_addr, _kvmRun->mmio.data, 738 _kvmRun->mmio.len, _kvmRun->mmio.is_write); 739 740 case KVM_EXIT_IRQ_WINDOW_OPEN: 741 return handleKvmExitIRQWindowOpen(); 742 743 case KVM_EXIT_FAIL_ENTRY: 744 return handleKvmExitFailEntry(); 745 746 case KVM_EXIT_INTR: 747 /* KVM was interrupted by a signal, restart it in the next 748 * tick. */ 749 return 0; 750 751 case KVM_EXIT_INTERNAL_ERROR: 752 panic("KVM: Internal error (suberror: %u)\n", 753 _kvmRun->internal.suberror); 754 755 default: 756 dump(); 757 panic("KVM: Unexpected exit (exit_reason: %u)\n", _kvmRun->exit_reason); 758 } 759} 760 761Tick 762BaseKvmCPU::handleKvmExitIO() 763{ 764 panic("KVM: Unhandled guest IO (dir: %i, size: %i, port: 0x%x, count: %i)\n", 765 _kvmRun->io.direction, _kvmRun->io.size, 766 _kvmRun->io.port, _kvmRun->io.count); 767} 768 769Tick 770BaseKvmCPU::handleKvmExitHypercall() 771{ 772 panic("KVM: Unhandled hypercall\n"); 773} 774 775Tick 776BaseKvmCPU::handleKvmExitIRQWindowOpen() 777{ 778 warn("KVM: Unhandled IRQ window.\n"); 779 return 0; 780} 781 782 783Tick 784BaseKvmCPU::handleKvmExitUnknown() 785{ 786 dump(); 787 panic("KVM: Unknown error when starting vCPU (hw reason: 0x%llx)\n", 788 _kvmRun->hw.hardware_exit_reason); 789} 790 791Tick 792BaseKvmCPU::handleKvmExitException() 793{ 794 dump(); 795 panic("KVM: Got exception when starting vCPU " 796 "(exception: %u, error_code: %u)\n", 797 _kvmRun->ex.exception, _kvmRun->ex.error_code); 798} 799 800Tick 801BaseKvmCPU::handleKvmExitFailEntry() 802{ 803 dump(); 804 panic("KVM: Failed to enter virtualized mode (hw reason: 0x%llx)\n", 805 _kvmRun->fail_entry.hardware_entry_failure_reason); 806} 807 808Tick 809BaseKvmCPU::doMMIOAccess(Addr paddr, void *data, int size, bool write) 810{ 811 mmio_req.setPhys(paddr, size, Request::UNCACHEABLE, dataMasterId()); 812 813 const MemCmd cmd(write ? MemCmd::WriteReq : MemCmd::ReadReq); 814 Packet pkt(&mmio_req, cmd); 815 pkt.dataStatic(data); 816 return dataPort.sendAtomic(&pkt); 817} 818
| 858 /* Service memory mapped IO requests */ 859 DPRINTF(KvmIO, "KVM: Handling MMIO (w: %u, addr: 0x%x, len: %u)\n", 860 _kvmRun->mmio.is_write, 861 _kvmRun->mmio.phys_addr, _kvmRun->mmio.len); 862 863 ++numMMIO; 864 return doMMIOAccess(_kvmRun->mmio.phys_addr, _kvmRun->mmio.data, 865 _kvmRun->mmio.len, _kvmRun->mmio.is_write); 866 867 case KVM_EXIT_IRQ_WINDOW_OPEN: 868 return handleKvmExitIRQWindowOpen(); 869 870 case KVM_EXIT_FAIL_ENTRY: 871 return handleKvmExitFailEntry(); 872 873 case KVM_EXIT_INTR: 874 /* KVM was interrupted by a signal, restart it in the next 875 * tick. */ 876 return 0; 877 878 case KVM_EXIT_INTERNAL_ERROR: 879 panic("KVM: Internal error (suberror: %u)\n", 880 _kvmRun->internal.suberror); 881 882 default: 883 dump(); 884 panic("KVM: Unexpected exit (exit_reason: %u)\n", _kvmRun->exit_reason); 885 } 886} 887 888Tick 889BaseKvmCPU::handleKvmExitIO() 890{ 891 panic("KVM: Unhandled guest IO (dir: %i, size: %i, port: 0x%x, count: %i)\n", 892 _kvmRun->io.direction, _kvmRun->io.size, 893 _kvmRun->io.port, _kvmRun->io.count); 894} 895 896Tick 897BaseKvmCPU::handleKvmExitHypercall() 898{ 899 panic("KVM: Unhandled hypercall\n"); 900} 901 902Tick 903BaseKvmCPU::handleKvmExitIRQWindowOpen() 904{ 905 warn("KVM: Unhandled IRQ window.\n"); 906 return 0; 907} 908 909 910Tick 911BaseKvmCPU::handleKvmExitUnknown() 912{ 913 dump(); 914 panic("KVM: Unknown error when starting vCPU (hw reason: 0x%llx)\n", 915 _kvmRun->hw.hardware_exit_reason); 916} 917 918Tick 919BaseKvmCPU::handleKvmExitException() 920{ 921 dump(); 922 panic("KVM: Got exception when starting vCPU " 923 "(exception: %u, error_code: %u)\n", 924 _kvmRun->ex.exception, _kvmRun->ex.error_code); 925} 926 927Tick 928BaseKvmCPU::handleKvmExitFailEntry() 929{ 930 dump(); 931 panic("KVM: Failed to enter virtualized mode (hw reason: 0x%llx)\n", 932 _kvmRun->fail_entry.hardware_entry_failure_reason); 933} 934 935Tick 936BaseKvmCPU::doMMIOAccess(Addr paddr, void *data, int size, bool write) 937{ 938 mmio_req.setPhys(paddr, size, Request::UNCACHEABLE, dataMasterId()); 939 940 const MemCmd cmd(write ? MemCmd::WriteReq : MemCmd::ReadReq); 941 Packet pkt(&mmio_req, cmd); 942 pkt.dataStatic(data); 943 return dataPort.sendAtomic(&pkt); 944} 945
|
| 946void 947BaseKvmCPU::setSignalMask(const sigset_t *mask) 948{ 949 std::unique_ptr<struct kvm_signal_mask> kvm_mask; 950 951 if (mask) { 952 kvm_mask.reset((struct kvm_signal_mask *)operator new( 953 sizeof(struct kvm_signal_mask) + sizeof(*mask))); 954 // The kernel and the user-space headers have different ideas 955 // about the size of sigset_t. This seems like a massive hack, 956 // but is actually what qemu does. 957 assert(sizeof(*mask) >= 8); 958 kvm_mask->len = 8; 959 memcpy(kvm_mask->sigset, mask, kvm_mask->len); 960 } 961 962 if (ioctl(KVM_SET_SIGNAL_MASK, (void *)kvm_mask.get()) == -1) 963 panic("KVM: Failed to set vCPU signal mask (errno: %i)\n", 964 errno); 965} 966
|
819int 820BaseKvmCPU::ioctl(int request, long p1) const 821{ 822 if (vcpuFD == -1) 823 panic("KVM: CPU ioctl called before initialization\n"); 824 825 return ::ioctl(vcpuFD, request, p1); 826} 827 828Tick 829BaseKvmCPU::flushCoalescedMMIO() 830{ 831 if (!mmioRing) 832 return 0; 833 834 DPRINTF(KvmIO, "KVM: Flushing the coalesced MMIO ring buffer\n"); 835 836 // TODO: We might need to do synchronization when we start to 837 // support multiple CPUs 838 Tick ticks(0); 839 while (mmioRing->first != mmioRing->last) { 840 struct kvm_coalesced_mmio &ent( 841 mmioRing->coalesced_mmio[mmioRing->first]); 842 843 DPRINTF(KvmIO, "KVM: Handling coalesced MMIO (addr: 0x%x, len: %u)\n", 844 ent.phys_addr, ent.len); 845 846 ++numCoalescedMMIO; 847 ticks += doMMIOAccess(ent.phys_addr, ent.data, ent.len, true); 848 849 mmioRing->first = (mmioRing->first + 1) % KVM_COALESCED_MMIO_MAX; 850 } 851 852 return ticks; 853} 854 855void 856BaseKvmCPU::setupSignalHandler() 857{ 858 struct sigaction sa; 859 860 memset(&sa, 0, sizeof(sa)); 861 sa.sa_sigaction = onTimerOverflow; 862 sa.sa_flags = SA_SIGINFO | SA_RESTART; 863 if (sigaction(KVM_TIMER_SIGNAL, &sa, NULL) == -1) 864 panic("KVM: Failed to setup vCPU signal handler\n");
| 967int 968BaseKvmCPU::ioctl(int request, long p1) const 969{ 970 if (vcpuFD == -1) 971 panic("KVM: CPU ioctl called before initialization\n"); 972 973 return ::ioctl(vcpuFD, request, p1); 974} 975 976Tick 977BaseKvmCPU::flushCoalescedMMIO() 978{ 979 if (!mmioRing) 980 return 0; 981 982 DPRINTF(KvmIO, "KVM: Flushing the coalesced MMIO ring buffer\n"); 983 984 // TODO: We might need to do synchronization when we start to 985 // support multiple CPUs 986 Tick ticks(0); 987 while (mmioRing->first != mmioRing->last) { 988 struct kvm_coalesced_mmio &ent( 989 mmioRing->coalesced_mmio[mmioRing->first]); 990 991 DPRINTF(KvmIO, "KVM: Handling coalesced MMIO (addr: 0x%x, len: %u)\n", 992 ent.phys_addr, ent.len); 993 994 ++numCoalescedMMIO; 995 ticks += doMMIOAccess(ent.phys_addr, ent.data, ent.len, true); 996 997 mmioRing->first = (mmioRing->first + 1) % KVM_COALESCED_MMIO_MAX; 998 } 999 1000 return ticks; 1001} 1002 1003void 1004BaseKvmCPU::setupSignalHandler() 1005{ 1006 struct sigaction sa; 1007 1008 memset(&sa, 0, sizeof(sa)); 1009 sa.sa_sigaction = onTimerOverflow; 1010 sa.sa_flags = SA_SIGINFO | SA_RESTART; 1011 if (sigaction(KVM_TIMER_SIGNAL, &sa, NULL) == -1) 1012 panic("KVM: Failed to setup vCPU signal handler\n");
|
| 1013 1014 sigset_t sigset; 1015 if (sigprocmask(SIG_BLOCK, NULL, &sigset) == -1) 1016 panic("KVM: Failed get signal mask\n"); 1017 1018 // Request KVM to setup the same signal mask as we're currently 1019 // running with. We'll sometimes need to mask the KVM_TIMER_SIGNAL 1020 // to cause immediate exits from KVM after servicing IO 1021 // requests. See kvmRun(). 1022 setSignalMask(&sigset); 1023 1024 // Mask the KVM_TIMER_SIGNAL so it isn't delivered unless we're 1025 // actually executing inside KVM. 1026 sigaddset(&sigset, KVM_TIMER_SIGNAL); 1027 if (sigprocmask(SIG_SETMASK, &sigset, NULL) == -1) 1028 panic("KVM: Failed mask the KVM timer signal\n");
|
865} 866
| 1029} 1030
|
| 1031bool 1032BaseKvmCPU::discardPendingSignal(int signum) const 1033{ 1034 int discardedSignal; 1035 1036 // Setting the timeout to zero causes sigtimedwait to return 1037 // immediately. 1038 struct timespec timeout; 1039 timeout.tv_sec = 0; 1040 timeout.tv_nsec = 0; 1041 1042 sigset_t sigset; 1043 sigemptyset(&sigset); 1044 sigaddset(&sigset, signum); 1045 1046 do { 1047 discardedSignal = sigtimedwait(&sigset, NULL, &timeout); 1048 } while (discardedSignal == -1 && errno == EINTR); 1049 1050 if (discardedSignal == signum) 1051 return true; 1052 else if (discardedSignal == -1 && errno == EAGAIN) 1053 return false; 1054 else 1055 panic("Unexpected return value from sigtimedwait: %i (errno: %i)\n", 1056 discardedSignal, errno); 1057} 1058
|
867void 868BaseKvmCPU::setupCounters() 869{ 870 DPRINTF(Kvm, "Attaching cycle counter...\n"); 871 PerfKvmCounterConfig cfgCycles(PERF_TYPE_HARDWARE, 872 PERF_COUNT_HW_CPU_CYCLES); 873 cfgCycles.disabled(true) 874 .pinned(true); 875 876 if (perfControlledByTimer) { 877 // We need to configure the cycles counter to send overflows 878 // since we are going to use it to trigger timer signals that 879 // trap back into m5 from KVM. In practice, this means that we 880 // need to set some non-zero sample period that gets 881 // overridden when the timer is armed. 882 cfgCycles.wakeupEvents(1) 883 .samplePeriod(42); 884 } 885 886 hwCycles.attach(cfgCycles, 887 0); // TID (0 => currentThread) 888 889 DPRINTF(Kvm, "Attaching instruction counter...\n"); 890 PerfKvmCounterConfig cfgInstructions(PERF_TYPE_HARDWARE, 891 PERF_COUNT_HW_INSTRUCTIONS); 892 hwInstructions.attach(cfgInstructions, 893 0, // TID (0 => currentThread) 894 hwCycles); 895}
| 1059void 1060BaseKvmCPU::setupCounters() 1061{ 1062 DPRINTF(Kvm, "Attaching cycle counter...\n"); 1063 PerfKvmCounterConfig cfgCycles(PERF_TYPE_HARDWARE, 1064 PERF_COUNT_HW_CPU_CYCLES); 1065 cfgCycles.disabled(true) 1066 .pinned(true); 1067 1068 if (perfControlledByTimer) { 1069 // We need to configure the cycles counter to send overflows 1070 // since we are going to use it to trigger timer signals that 1071 // trap back into m5 from KVM. In practice, this means that we 1072 // need to set some non-zero sample period that gets 1073 // overridden when the timer is armed. 1074 cfgCycles.wakeupEvents(1) 1075 .samplePeriod(42); 1076 } 1077 1078 hwCycles.attach(cfgCycles, 1079 0); // TID (0 => currentThread) 1080 1081 DPRINTF(Kvm, "Attaching instruction counter...\n"); 1082 PerfKvmCounterConfig cfgInstructions(PERF_TYPE_HARDWARE, 1083 PERF_COUNT_HW_INSTRUCTIONS); 1084 hwInstructions.attach(cfgInstructions, 1085 0, // TID (0 => currentThread) 1086 hwCycles); 1087}
|
| 1088 1089bool 1090BaseKvmCPU::tryDrain() 1091{ 1092 if (!drainManager) 1093 return false; 1094 1095 if (!archIsDrained()) { 1096 DPRINTF(Drain, "tryDrain: Architecture code is not ready.\n"); 1097 return false; 1098 } 1099 1100 if (_status == Idle || _status == Running) { 1101 DPRINTF(Drain, 1102 "tryDrain: CPU transitioned into the Idle state, drain done\n"); 1103 drainManager->signalDrainDone(); 1104 drainManager = NULL; 1105 return true; 1106 } else { 1107 DPRINTF(Drain, "tryDrain: CPU not ready.\n"); 1108 return false; 1109 } 1110} 1111 1112void 1113BaseKvmCPU::ioctlRun() 1114{ 1115 if (ioctl(KVM_RUN) == -1) { 1116 if (errno != EINTR) 1117 panic("KVM: Failed to start virtual CPU (errno: %i)\n", 1118 errno); 1119 } 1120}
|
| |