diff options
Diffstat (limited to 'drivers/kvm/kvm_main.c')
-rw-r--r-- | drivers/kvm/kvm_main.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index a012d70d9eff..d56964a6eb80 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c | |||
@@ -2126,6 +2126,7 @@ static int kvm_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, | |||
2126 | struct kvm_sregs *sregs) | 2126 | struct kvm_sregs *sregs) |
2127 | { | 2127 | { |
2128 | struct descriptor_table dt; | 2128 | struct descriptor_table dt; |
2129 | int pending_vec; | ||
2129 | 2130 | ||
2130 | vcpu_load(vcpu); | 2131 | vcpu_load(vcpu); |
2131 | 2132 | ||
@@ -2155,10 +2156,13 @@ static int kvm_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, | |||
2155 | sregs->efer = vcpu->shadow_efer; | 2156 | sregs->efer = vcpu->shadow_efer; |
2156 | sregs->apic_base = kvm_get_apic_base(vcpu); | 2157 | sregs->apic_base = kvm_get_apic_base(vcpu); |
2157 | 2158 | ||
2158 | if (irqchip_in_kernel(vcpu->kvm)) | 2159 | if (irqchip_in_kernel(vcpu->kvm)) { |
2159 | memset(sregs->interrupt_bitmap, 0, | 2160 | memset(sregs->interrupt_bitmap, 0, |
2160 | sizeof sregs->interrupt_bitmap); | 2161 | sizeof sregs->interrupt_bitmap); |
2161 | else | 2162 | pending_vec = kvm_arch_ops->get_irq(vcpu); |
2163 | if (pending_vec >= 0) | ||
2164 | set_bit(pending_vec, (unsigned long *)sregs->interrupt_bitmap); | ||
2165 | } else | ||
2162 | memcpy(sregs->interrupt_bitmap, vcpu->irq_pending, | 2166 | memcpy(sregs->interrupt_bitmap, vcpu->irq_pending, |
2163 | sizeof sregs->interrupt_bitmap); | 2167 | sizeof sregs->interrupt_bitmap); |
2164 | 2168 | ||
@@ -2177,7 +2181,7 @@ static int kvm_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, | |||
2177 | struct kvm_sregs *sregs) | 2181 | struct kvm_sregs *sregs) |
2178 | { | 2182 | { |
2179 | int mmu_reset_needed = 0; | 2183 | int mmu_reset_needed = 0; |
2180 | int i; | 2184 | int i, pending_vec, max_bits; |
2181 | struct descriptor_table dt; | 2185 | struct descriptor_table dt; |
2182 | 2186 | ||
2183 | vcpu_load(vcpu); | 2187 | vcpu_load(vcpu); |
@@ -2221,6 +2225,16 @@ static int kvm_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, | |||
2221 | for (i = 0; i < ARRAY_SIZE(vcpu->irq_pending); ++i) | 2225 | for (i = 0; i < ARRAY_SIZE(vcpu->irq_pending); ++i) |
2222 | if (vcpu->irq_pending[i]) | 2226 | if (vcpu->irq_pending[i]) |
2223 | __set_bit(i, &vcpu->irq_summary); | 2227 | __set_bit(i, &vcpu->irq_summary); |
2228 | } else { | ||
2229 | max_bits = (sizeof sregs->interrupt_bitmap) << 3; | ||
2230 | pending_vec = find_first_bit( | ||
2231 | (const unsigned long *)sregs->interrupt_bitmap, | ||
2232 | max_bits); | ||
2233 | /* Only pending external irq is handled here */ | ||
2234 | if (pending_vec < max_bits) { | ||
2235 | kvm_arch_ops->set_irq(vcpu, pending_vec); | ||
2236 | printk("Set back pending irq %d\n", pending_vec); | ||
2237 | } | ||
2224 | } | 2238 | } |
2225 | 2239 | ||
2226 | set_segment(vcpu, &sregs->cs, VCPU_SREG_CS); | 2240 | set_segment(vcpu, &sregs->cs, VCPU_SREG_CS); |