From 3787148758071e875aefda3fe44a551d9c2ed4a2 Mon Sep 17 00:00:00 2001 From: Peter Grehan Date: Mon, 9 Jun 2014 21:02:48 +0000 Subject: [PATCH] Temporary fix for guest idle detection. Handle ExtINT injection for SVM. The HPET emulation will inject a legacy interrupt at startup, and if this isn't handled, will result in the HLT-exit code assuming there are outstanding ExtINTs and return without sleeping. svm_inj_interrupts() needs more changes to bring it up to date with the VT-x version: these are forthcoming. Reviewed by: neel --- sys/amd64/vmm/amd/svm.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/sys/amd64/vmm/amd/svm.c b/sys/amd64/vmm/amd/svm.c index b478bbf9f3e2..dd76ceddea78 100644 --- a/sys/amd64/vmm/amd/svm.c +++ b/sys/amd64/vmm/amd/svm.c @@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$"); #include "vmm_stat.h" #include "vmm_ktr.h" #include "vmm_ioport.h" +#include "vatpic.h" #include "vlapic.h" #include "vlapic_priv.h" @@ -952,6 +953,7 @@ svm_inj_interrupts(struct svm_softc *svm_sc, int vcpu, struct vlapic *vlapic) struct vmcb_ctrl *ctrl; struct vmcb_state *state; struct vm_exception exc; + int extint_pending; int vector; KASSERT(vcpu < svm_sc->vcpu_cnt, ("Guest doesn't have VCPU%d", vcpu)); @@ -988,10 +990,17 @@ svm_inj_interrupts(struct svm_softc *svm_sc, int vcpu, struct vlapic *vlapic) return; } - /* Ask the local apic for a vector to inject */ - if (!vlapic_pending_intr(vlapic, &vector)) - return; - + extint_pending = vm_extint_pending(svm_sc->vm, vcpu); + + if (!extint_pending) { + /* Ask the local apic for a vector to inject */ + if (!vlapic_pending_intr(vlapic, &vector)) + return; + } else { + /* Ask the legacy pic for a vector to inject */ + vatpic_pending_intr(svm_sc->vm, &vector); + } + if (vector < 32 || vector > 255) { VCPU_CTR1(svm_sc->vm, vcpu, "SVM_ERR:Event injection" "invalid vector=%d.\n", vector); @@ -1010,8 +1019,18 @@ svm_inj_interrupts(struct svm_softc *svm_sc, int vcpu, struct vlapic *vlapic) return; } - /* Acknowledge that event is accepted.*/ - vlapic_intr_accepted(vlapic, vector); + if (!extint_pending) { + /* Update the Local APIC ISR */ + vlapic_intr_accepted(vlapic, vector); + } else { + vm_extint_clear(svm_sc->vm, vcpu); + vatpic_intr_accepted(svm_sc->vm, vector); + + /* + * XXX need to recheck exting_pending ala VT-x + */ + } + VCPU_CTR1(svm_sc->vm, vcpu, "SVM:event injected,vector=%d.\n", vector); }