diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/arm/kvm/base_cpu.cc | 35 | ||||
-rw-r--r-- | src/arch/arm/kvm/gic.cc | 4 | ||||
-rw-r--r-- | src/cpu/kvm/vm.hh | 9 |
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 |