kvm: Add a helper method to access device event queues
authorAndreas Sandberg <andreas.sandberg@arm.com>
Thu, 27 Jul 2017 09:24:22 +0000 (09:24 +0000)
committerAndreas Sandberg <andreas.sandberg@arm.com>
Tue, 1 Aug 2017 16:20:24 +0000 (16:20 +0000)
The VM's event queue is normally used for devices in multi-core KVM
mode. Add a helper method, BaseKvmCPU::deviceEventQueue(), to access
this queue. This makes the intention of code migrating to device event
queues clearer.

Change-Id: Ifb10f553a6d7445c8d562f658cf9d0b1f4c577ff
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/4287
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
src/cpu/kvm/base.cc
src/cpu/kvm/base.hh
src/cpu/kvm/x86_cpu.cc

index 6ea99ce4a9fcf5ebbe7d5b597279136ba1d5ded2..d0f7515de02def9935c94aaf392f2d9510369c72 100644 (file)
@@ -1147,10 +1147,9 @@ BaseKvmCPU::doMMIOAccess(Addr paddr, void *data, int size, bool write)
         delete pkt;
         return clockPeriod() * ipr_delay;
     } else {
-        // Temporarily lock and migrate to the event queue of the
-        // VM. This queue is assumed to "own" all devices we need to
-        // access if running in multi-core mode.
-        EventQueue::ScopedMigration migrate(vm.eventQueue());
+        // Temporarily lock and migrate to the device event queue to
+        // prevent races in multi-core mode.
+        EventQueue::ScopedMigration migrate(deviceEventQueue());
 
         return dataPort.submitIO(pkt);
     }
index 29872e7447b8433cc4af16d3c7ce67b005d21345..a22637f9835b9af274f3f98d02497b56215f4618 100644 (file)
@@ -418,6 +418,16 @@ class BaseKvmCPU : public BaseCPU
      */
     void syncThreadContext();
 
+    /**
+     * Get a pointer to the event queue owning devices.
+     *
+     * Devices always live in a separate device event queue when
+     * running in multi-core mode. We need to temporarily migrate to
+     * this queue when accessing devices. By convention, devices and
+     * the VM use the same event queue.
+     */
+    EventQueue *deviceEventQueue() { return vm.eventQueue(); }
+
     /**
      * Update the KVM if the thread context is dirty.
      */
index bdbdadf71a1498480ba24f80b7c5c4f1ba6b0da6..467e1baaf609ccc45ebe99bff701caf4acf6697d 100644 (file)
@@ -1346,10 +1346,9 @@ X86KvmCPU::handleKvmExitIO()
     }
 
     const MemCmd cmd(isWrite ? MemCmd::WriteReq : MemCmd::ReadReq);
-    // Temporarily lock and migrate to the event queue of the
-    // VM. This queue is assumed to "own" all devices we need to
-    // access if running in multi-core mode.
-    EventQueue::ScopedMigration migrate(vm.eventQueue());
+    // Temporarily lock and migrate to the device event queue to
+    // prevent races in multi-core mode.
+    EventQueue::ScopedMigration migrate(deviceEventQueue());
     for (int i = 0; i < count; ++i) {
         RequestPtr io_req = new Request(pAddr, kvm_run.io.size,
                                         Request::UNCACHEABLE, dataMasterId());