summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/arm/kvm/base_cpu.cc35
-rw-r--r--src/arch/arm/kvm/gic.cc4
-rw-r--r--src/cpu/kvm/vm.hh9
3 files changed, 36 insertions, 12 deletions
diff --git a/src/arch/arm/kvm/base_cpu.cc b/src/arch/arm/kvm/base_cpu.cc
index e25112cae..765965092 100644
--- a/src/arch/arm/kvm/base_cpu.cc
+++ b/src/arch/arm/kvm/base_cpu.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015 ARM Limited
+ * Copyright (c) 2012, 2015, 2017 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -88,20 +88,31 @@ BaseArmKvmCPU::startup()
Tick
BaseArmKvmCPU::kvmRun(Tick ticks)
{
- bool simFIQ(interrupts[0]->checkRaw(INT_FIQ));
- bool simIRQ(interrupts[0]->checkRaw(INT_IRQ));
+ const bool simFIQ(interrupts[0]->checkRaw(INT_FIQ));
+ const bool simIRQ(interrupts[0]->checkRaw(INT_IRQ));
- if (fiqAsserted != simFIQ) {
- fiqAsserted = simFIQ;
- DPRINTF(KvmInt, "KVM: Update FIQ state: %i\n", simFIQ);
- vm.setIRQLine(INTERRUPT_VCPU_FIQ(vcpuID), simFIQ);
- }
- if (irqAsserted != simIRQ) {
- irqAsserted = simIRQ;
- DPRINTF(KvmInt, "KVM: Update IRQ state: %i\n", simIRQ);
- vm.setIRQLine(INTERRUPT_VCPU_IRQ(vcpuID), simIRQ);
+ if (!vm.hasKernelIRQChip()) {
+ if (fiqAsserted != simFIQ) {
+ DPRINTF(KvmInt, "KVM: Update FIQ state: %i\n", simFIQ);
+ vm.setIRQLine(INTERRUPT_VCPU_FIQ(vcpuID), simFIQ);
+ }
+ if (irqAsserted != simIRQ) {
+ DPRINTF(KvmInt, "KVM: Update IRQ state: %i\n", simIRQ);
+ vm.setIRQLine(INTERRUPT_VCPU_IRQ(vcpuID), simIRQ);
+ }
+ } else {
+ warn_if(simFIQ && !fiqAsserted,
+ "FIQ raised by the simulated interrupt controller " \
+ "despite in-kernel GIC emulation. This is probably a bug.");
+
+ warn_if(simIRQ && !irqAsserted,
+ "IRQ raised by the simulated interrupt controller " \
+ "despite in-kernel GIC emulation. This is probably a bug.");
}
+ irqAsserted = simIRQ;
+ fiqAsserted = simFIQ;
+
return BaseKvmCPU::kvmRun(ticks);
}
diff --git a/src/arch/arm/kvm/gic.cc b/src/arch/arm/kvm/gic.cc
index 498b79faa..ce3baa558 100644
--- a/src/arch/arm/kvm/gic.cc
+++ b/src/arch/arm/kvm/gic.cc
@@ -54,6 +54,10 @@ KvmKernelGicV2::KvmKernelGicV2(KvmVM &_vm, Addr cpu_addr, Addr dist_addr,
vm(_vm),
kdev(vm.createDevice(KVM_DEV_TYPE_ARM_VGIC_V2))
{
+ // Tell the VM that we will emulate the GIC in the kernel. This
+ // disables IRQ and FIQ handling in the KVM CPU model.
+ vm.enableKernelIRQChip();
+
kdev.setAttr<uint64_t>(
KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V2_ADDR_TYPE_DIST, dist_addr);
kdev.setAttr<uint64_t>(
diff --git a/src/cpu/kvm/vm.hh b/src/cpu/kvm/vm.hh
index df2e4119a..e122bbf86 100644
--- a/src/cpu/kvm/vm.hh
+++ b/src/cpu/kvm/vm.hh
@@ -351,6 +351,15 @@ class KvmVM : public SimObject
* Is in-kernel IRQ chip emulation enabled?
*/
bool hasKernelIRQChip() const { return _hasKernelIRQChip; }
+
+ /**
+ * Tell the VM and VCPUs to use an in-kernel IRQ chip for
+ * interrupt delivery.
+ *
+ * @note This is set automatically if the IRQ chip is created
+ * using the KvmVM::createIRQChip() API.
+ */
+ void enableKernelIRQChip() { _hasKernelIRQChip = true; }
/** @} */
struct MemSlot