diff --git a/src/arch/arm/kvm/gic.cc b/src/arch/arm/kvm/gic.cc index ce3baa5588..d490265b88 100644 --- a/src/arch/arm/kvm/gic.cc +++ b/src/arch/arm/kvm/gic.cc @@ -291,6 +291,17 @@ MuxingKvmGic::clearPPInt(uint32_t num, uint32_t cpu) kernelGic->clearPPI(cpu, num); } +void +MuxingKvmGic::updateIntState(int hint) +{ + // During Kvm->Pl390 state transfer, writes to the Pl390 will call + // updateIntState() which can post an interrupt. Since we're only + // using the Pl390 model for holding state in this circumstance, we + // short-circuit this behavior, as the Pl390 is not actually active. + if (!usingKvm) + return Pl390::updateIntState(hint); +} + void MuxingKvmGic::copyDistRegister(BaseGicRegisters* from, BaseGicRegisters* to, ContextID ctx, Addr daddr) diff --git a/src/arch/arm/kvm/gic.hh b/src/arch/arm/kvm/gic.hh index ee04088d37..5447e6a92a 100644 --- a/src/arch/arm/kvm/gic.hh +++ b/src/arch/arm/kvm/gic.hh @@ -194,6 +194,9 @@ class MuxingKvmGic : public Pl390 void sendPPInt(uint32_t num, uint32_t cpu) override; void clearPPInt(uint32_t num, uint32_t cpu) override; + protected: // Pl390 + void updateIntState(int hint) override; + protected: /** System this interrupt controller belongs to */ System &system; diff --git a/src/dev/arm/gic_pl390.cc b/src/dev/arm/gic_pl390.cc index 7b63306c39..93aaf5c45c 100644 --- a/src/dev/arm/gic_pl390.cc +++ b/src/dev/arm/gic_pl390.cc @@ -871,6 +871,14 @@ Pl390::drain() } } + +void +Pl390::drainResume() +{ + // There may be pending interrupts if checkpointed from Kvm; post them. + updateIntState(-1); +} + void Pl390::serialize(CheckpointOut &cp) const { diff --git a/src/dev/arm/gic_pl390.hh b/src/dev/arm/gic_pl390.hh index 5c8a71222f..3b35b59fb0 100644 --- a/src/dev/arm/gic_pl390.hh +++ b/src/dev/arm/gic_pl390.hh @@ -318,7 +318,7 @@ class Pl390 : public BaseGic, public BaseGicRegisters /** See if some processor interrupt flags need to be enabled/disabled * @param hint which set of interrupts needs to be checked */ - void updateIntState(int hint); + virtual void updateIntState(int hint); /** Update the register that records priority of the highest priority * active interrupt*/ @@ -368,6 +368,7 @@ class Pl390 : public BaseGic, public BaseGicRegisters ~Pl390(); DrainState drain() override; + void drainResume() override; void serialize(CheckpointOut &cp) const override; void unserialize(CheckpointIn &cp) override;