aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/kvm_main.c
diff options
context:
space:
mode:
authorHe, Qing <qing.he@intel.com>2007-08-02 07:03:07 -0400
committerAvi Kivity <avi@qumranet.com>2007-10-13 04:18:25 -0400
commitc52fb35a8b5dada749d35fbe15ac1f9857b22896 (patch)
treef3df58816b72f208cbf5bc734d3754d9435a632a /drivers/kvm/kvm_main.c
parent6ceb9d791eeeb0a5493958f5d6d4dc7d91e59cf7 (diff)
KVM: Bypass irq_pending get/set when using in kernel irqchip
vcpu->irq_pending is saved in get/set_sreg IOCTL, but when in-kernel local APIC is used, doing this may occasionally overwrite vcpu->apic to an invalid value, as in the vm restore path. Signed-off-by: Qing He <qing.he@intel.com>
Diffstat (limited to 'drivers/kvm/kvm_main.c')
-rw-r--r--drivers/kvm/kvm_main.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 6e2c5f3f33fb..c270e4afd3fd 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -2145,8 +2145,12 @@ static int kvm_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
2145 sregs->efer = vcpu->shadow_efer; 2145 sregs->efer = vcpu->shadow_efer;
2146 sregs->apic_base = kvm_get_apic_base(vcpu); 2146 sregs->apic_base = kvm_get_apic_base(vcpu);
2147 2147
2148 memcpy(sregs->interrupt_bitmap, vcpu->irq_pending, 2148 if (irqchip_in_kernel(vcpu->kvm))
2149 sizeof sregs->interrupt_bitmap); 2149 memset(sregs->interrupt_bitmap, 0,
2150 sizeof sregs->interrupt_bitmap);
2151 else
2152 memcpy(sregs->interrupt_bitmap, vcpu->irq_pending,
2153 sizeof sregs->interrupt_bitmap);
2150 2154
2151 vcpu_put(vcpu); 2155 vcpu_put(vcpu);
2152 2156
@@ -2200,12 +2204,14 @@ static int kvm_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
2200 if (mmu_reset_needed) 2204 if (mmu_reset_needed)
2201 kvm_mmu_reset_context(vcpu); 2205 kvm_mmu_reset_context(vcpu);
2202 2206
2203 memcpy(vcpu->irq_pending, sregs->interrupt_bitmap, 2207 if (!irqchip_in_kernel(vcpu->kvm)) {
2204 sizeof vcpu->irq_pending); 2208 memcpy(vcpu->irq_pending, sregs->interrupt_bitmap,
2205 vcpu->irq_summary = 0; 2209 sizeof vcpu->irq_pending);
2206 for (i = 0; i < ARRAY_SIZE(vcpu->irq_pending); ++i) 2210 vcpu->irq_summary = 0;
2207 if (vcpu->irq_pending[i]) 2211 for (i = 0; i < ARRAY_SIZE(vcpu->irq_pending); ++i)
2208 __set_bit(i, &vcpu->irq_summary); 2212 if (vcpu->irq_pending[i])
2213 __set_bit(i, &vcpu->irq_summary);
2214 }
2209 2215
2210 set_segment(vcpu, &sregs->cs, VCPU_SREG_CS); 2216 set_segment(vcpu, &sregs->cs, VCPU_SREG_CS);
2211 set_segment(vcpu, &sregs->ds, VCPU_SREG_DS); 2217 set_segment(vcpu, &sregs->ds, VCPU_SREG_DS);