diff options
Diffstat (limited to 'virt/kvm/arm/vgic.c')
-rw-r--r-- | virt/kvm/arm/vgic.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c index 0cc6ab6005a0..c9f60f524588 100644 --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c | |||
@@ -883,6 +883,11 @@ static inline u64 vgic_get_eisr(struct kvm_vcpu *vcpu) | |||
883 | return vgic_ops->get_eisr(vcpu); | 883 | return vgic_ops->get_eisr(vcpu); |
884 | } | 884 | } |
885 | 885 | ||
886 | static inline void vgic_clear_eisr(struct kvm_vcpu *vcpu) | ||
887 | { | ||
888 | vgic_ops->clear_eisr(vcpu); | ||
889 | } | ||
890 | |||
886 | static inline u32 vgic_get_interrupt_status(struct kvm_vcpu *vcpu) | 891 | static inline u32 vgic_get_interrupt_status(struct kvm_vcpu *vcpu) |
887 | { | 892 | { |
888 | return vgic_ops->get_interrupt_status(vcpu); | 893 | return vgic_ops->get_interrupt_status(vcpu); |
@@ -922,6 +927,7 @@ static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu) | |||
922 | vgic_set_lr(vcpu, lr_nr, vlr); | 927 | vgic_set_lr(vcpu, lr_nr, vlr); |
923 | clear_bit(lr_nr, vgic_cpu->lr_used); | 928 | clear_bit(lr_nr, vgic_cpu->lr_used); |
924 | vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY; | 929 | vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY; |
930 | vgic_sync_lr_elrsr(vcpu, lr_nr, vlr); | ||
925 | } | 931 | } |
926 | 932 | ||
927 | /* | 933 | /* |
@@ -978,6 +984,7 @@ bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) | |||
978 | BUG_ON(!test_bit(lr, vgic_cpu->lr_used)); | 984 | BUG_ON(!test_bit(lr, vgic_cpu->lr_used)); |
979 | vlr.state |= LR_STATE_PENDING; | 985 | vlr.state |= LR_STATE_PENDING; |
980 | vgic_set_lr(vcpu, lr, vlr); | 986 | vgic_set_lr(vcpu, lr, vlr); |
987 | vgic_sync_lr_elrsr(vcpu, lr, vlr); | ||
981 | return true; | 988 | return true; |
982 | } | 989 | } |
983 | } | 990 | } |
@@ -999,6 +1006,7 @@ bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) | |||
999 | vlr.state |= LR_EOI_INT; | 1006 | vlr.state |= LR_EOI_INT; |
1000 | 1007 | ||
1001 | vgic_set_lr(vcpu, lr, vlr); | 1008 | vgic_set_lr(vcpu, lr, vlr); |
1009 | vgic_sync_lr_elrsr(vcpu, lr, vlr); | ||
1002 | 1010 | ||
1003 | return true; | 1011 | return true; |
1004 | } | 1012 | } |
@@ -1136,6 +1144,14 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) | |||
1136 | if (status & INT_STATUS_UNDERFLOW) | 1144 | if (status & INT_STATUS_UNDERFLOW) |
1137 | vgic_disable_underflow(vcpu); | 1145 | vgic_disable_underflow(vcpu); |
1138 | 1146 | ||
1147 | /* | ||
1148 | * In the next iterations of the vcpu loop, if we sync the vgic state | ||
1149 | * after flushing it, but before entering the guest (this happens for | ||
1150 | * pending signals and vmid rollovers), then make sure we don't pick | ||
1151 | * up any old maintenance interrupts here. | ||
1152 | */ | ||
1153 | vgic_clear_eisr(vcpu); | ||
1154 | |||
1139 | return level_pending; | 1155 | return level_pending; |
1140 | } | 1156 | } |
1141 | 1157 | ||
@@ -1583,8 +1599,10 @@ int kvm_vgic_create(struct kvm *kvm, u32 type) | |||
1583 | * emulation. So check this here again. KVM_CREATE_DEVICE does | 1599 | * emulation. So check this here again. KVM_CREATE_DEVICE does |
1584 | * the proper checks already. | 1600 | * the proper checks already. |
1585 | */ | 1601 | */ |
1586 | if (type == KVM_DEV_TYPE_ARM_VGIC_V2 && !vgic->can_emulate_gicv2) | 1602 | if (type == KVM_DEV_TYPE_ARM_VGIC_V2 && !vgic->can_emulate_gicv2) { |
1587 | return -ENODEV; | 1603 | ret = -ENODEV; |
1604 | goto out; | ||
1605 | } | ||
1588 | 1606 | ||
1589 | /* | 1607 | /* |
1590 | * Any time a vcpu is run, vcpu_load is called which tries to grab the | 1608 | * Any time a vcpu is run, vcpu_load is called which tries to grab the |