aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2015-11-24 13:34:40 -0500
committerPaolo Bonzini <pbonzini@redhat.com>2015-11-24 13:34:40 -0500
commit8bd142c01648cdb33e9bcafa0448ba2c20ed814c (patch)
tree9197c60d3f9d4036f38f281a183e94750ceea1d7 /virt/kvm
parentd792abacaf1a1a8dfea353fab699b97fa6251c2a (diff)
parentfbb4574ce9a37e15a9872860bf202f2be5bdf6c4 (diff)
Merge tag 'kvm-arm-for-v4.4-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into kvm-master
KVM/ARM Fixes for v4.4-rc3. Includes some timer fixes, properly unmapping PTEs, an errata fix, and two tweaks to the EL2 panic code.
Diffstat (limited to 'virt/kvm')
-rw-r--r--virt/kvm/arm/arch_timer.c28
-rw-r--r--virt/kvm/arm/vgic.c50
2 files changed, 41 insertions, 37 deletions
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 21a0ab2d8919..69bca185c471 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -221,17 +221,23 @@ void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
221 kvm_timer_update_state(vcpu); 221 kvm_timer_update_state(vcpu);
222 222
223 /* 223 /*
224 * If we enter the guest with the virtual input level to the VGIC 224 * If we enter the guest with the virtual input level to the VGIC
225 * asserted, then we have already told the VGIC what we need to, and 225 * asserted, then we have already told the VGIC what we need to, and
226 * we don't need to exit from the guest until the guest deactivates 226 * we don't need to exit from the guest until the guest deactivates
227 * the already injected interrupt, so therefore we should set the 227 * the already injected interrupt, so therefore we should set the
228 * hardware active state to prevent unnecessary exits from the guest. 228 * hardware active state to prevent unnecessary exits from the guest.
229 * 229 *
230 * Conversely, if the virtual input level is deasserted, then always 230 * Also, if we enter the guest with the virtual timer interrupt active,
231 * clear the hardware active state to ensure that hardware interrupts 231 * then it must be active on the physical distributor, because we set
232 * from the timer triggers a guest exit. 232 * the HW bit and the guest must be able to deactivate the virtual and
233 */ 233 * physical interrupt at the same time.
234 if (timer->irq.level) 234 *
235 * Conversely, if the virtual input level is deasserted and the virtual
236 * interrupt is not active, then always clear the hardware active state
237 * to ensure that hardware interrupts from the timer triggers a guest
238 * exit.
239 */
240 if (timer->irq.level || kvm_vgic_map_is_active(vcpu, timer->map))
235 phys_active = true; 241 phys_active = true;
236 else 242 else
237 phys_active = false; 243 phys_active = false;
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 533538385d5d..65461f821a75 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1096,6 +1096,27 @@ static void vgic_retire_lr(int lr_nr, struct kvm_vcpu *vcpu)
1096 vgic_set_lr(vcpu, lr_nr, vlr); 1096 vgic_set_lr(vcpu, lr_nr, vlr);
1097} 1097}
1098 1098
1099static bool dist_active_irq(struct kvm_vcpu *vcpu)
1100{
1101 struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
1102
1103 return test_bit(vcpu->vcpu_id, dist->irq_active_on_cpu);
1104}
1105
1106bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, struct irq_phys_map *map)
1107{
1108 int i;
1109
1110 for (i = 0; i < vcpu->arch.vgic_cpu.nr_lr; i++) {
1111 struct vgic_lr vlr = vgic_get_lr(vcpu, i);
1112
1113 if (vlr.irq == map->virt_irq && vlr.state & LR_STATE_ACTIVE)
1114 return true;
1115 }
1116
1117 return dist_active_irq(vcpu);
1118}
1119
1099/* 1120/*
1100 * An interrupt may have been disabled after being made pending on the 1121 * An interrupt may have been disabled after being made pending on the
1101 * CPU interface (the classic case is a timer running while we're 1122 * CPU interface (the classic case is a timer running while we're
@@ -1248,7 +1269,7 @@ static void __kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
1248 * may have been serviced from another vcpu. In all cases, 1269 * may have been serviced from another vcpu. In all cases,
1249 * move along. 1270 * move along.
1250 */ 1271 */
1251 if (!kvm_vgic_vcpu_pending_irq(vcpu) && !kvm_vgic_vcpu_active_irq(vcpu)) 1272 if (!kvm_vgic_vcpu_pending_irq(vcpu) && !dist_active_irq(vcpu))
1252 goto epilog; 1273 goto epilog;
1253 1274
1254 /* SGIs */ 1275 /* SGIs */
@@ -1396,25 +1417,13 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
1396static bool vgic_sync_hwirq(struct kvm_vcpu *vcpu, int lr, struct vgic_lr vlr) 1417static bool vgic_sync_hwirq(struct kvm_vcpu *vcpu, int lr, struct vgic_lr vlr)
1397{ 1418{
1398 struct vgic_dist *dist = &vcpu->kvm->arch.vgic; 1419 struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
1399 struct irq_phys_map *map;
1400 bool phys_active;
1401 bool level_pending; 1420 bool level_pending;
1402 int ret;
1403 1421
1404 if (!(vlr.state & LR_HW)) 1422 if (!(vlr.state & LR_HW))
1405 return false; 1423 return false;
1406 1424
1407 map = vgic_irq_map_search(vcpu, vlr.irq); 1425 if (vlr.state & LR_STATE_ACTIVE)
1408 BUG_ON(!map); 1426 return false;
1409
1410 ret = irq_get_irqchip_state(map->irq,
1411 IRQCHIP_STATE_ACTIVE,
1412 &phys_active);
1413
1414 WARN_ON(ret);
1415
1416 if (phys_active)
1417 return 0;
1418 1427
1419 spin_lock(&dist->lock); 1428 spin_lock(&dist->lock);
1420 level_pending = process_queued_irq(vcpu, lr, vlr); 1429 level_pending = process_queued_irq(vcpu, lr, vlr);
@@ -1479,17 +1488,6 @@ int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu)
1479 return test_bit(vcpu->vcpu_id, dist->irq_pending_on_cpu); 1488 return test_bit(vcpu->vcpu_id, dist->irq_pending_on_cpu);
1480} 1489}
1481 1490
1482int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu)
1483{
1484 struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
1485
1486 if (!irqchip_in_kernel(vcpu->kvm))
1487 return 0;
1488
1489 return test_bit(vcpu->vcpu_id, dist->irq_active_on_cpu);
1490}
1491
1492
1493void vgic_kick_vcpus(struct kvm *kvm) 1491void vgic_kick_vcpus(struct kvm *kvm)
1494{ 1492{
1495 struct kvm_vcpu *vcpu; 1493 struct kvm_vcpu *vcpu;