diff options
Diffstat (limited to 'virt/kvm/arm')
-rw-r--r-- | virt/kvm/arm/vgic.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c index 6dcc974fa2b4..1e857e6e66b5 100644 --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c | |||
@@ -1036,11 +1036,26 @@ static u64 vgic_v2_get_elrsr(const struct kvm_vcpu *vcpu) | |||
1036 | return val; | 1036 | return val; |
1037 | } | 1037 | } |
1038 | 1038 | ||
1039 | static u64 vgic_v2_get_eisr(const struct kvm_vcpu *vcpu) | ||
1040 | { | ||
1041 | u64 val; | ||
1042 | |||
1043 | #if BITS_PER_LONG == 64 | ||
1044 | val = vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr[1]; | ||
1045 | val <<= 32; | ||
1046 | val |= vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr[0]; | ||
1047 | #else | ||
1048 | val = *(u64 *)vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr; | ||
1049 | #endif | ||
1050 | return val; | ||
1051 | } | ||
1052 | |||
1039 | static const struct vgic_ops vgic_ops = { | 1053 | static const struct vgic_ops vgic_ops = { |
1040 | .get_lr = vgic_v2_get_lr, | 1054 | .get_lr = vgic_v2_get_lr, |
1041 | .set_lr = vgic_v2_set_lr, | 1055 | .set_lr = vgic_v2_set_lr, |
1042 | .sync_lr_elrsr = vgic_v2_sync_lr_elrsr, | 1056 | .sync_lr_elrsr = vgic_v2_sync_lr_elrsr, |
1043 | .get_elrsr = vgic_v2_get_elrsr, | 1057 | .get_elrsr = vgic_v2_get_elrsr, |
1058 | .get_eisr = vgic_v2_get_eisr, | ||
1044 | }; | 1059 | }; |
1045 | 1060 | ||
1046 | static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr) | 1061 | static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr) |
@@ -1065,6 +1080,11 @@ static inline u64 vgic_get_elrsr(struct kvm_vcpu *vcpu) | |||
1065 | return vgic_ops.get_elrsr(vcpu); | 1080 | return vgic_ops.get_elrsr(vcpu); |
1066 | } | 1081 | } |
1067 | 1082 | ||
1083 | static inline u64 vgic_get_eisr(struct kvm_vcpu *vcpu) | ||
1084 | { | ||
1085 | return vgic_ops.get_eisr(vcpu); | ||
1086 | } | ||
1087 | |||
1068 | static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu) | 1088 | static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu) |
1069 | { | 1089 | { |
1070 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; | 1090 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; |
@@ -1271,10 +1291,11 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) | |||
1271 | * Some level interrupts have been EOIed. Clear their | 1291 | * Some level interrupts have been EOIed. Clear their |
1272 | * active bit. | 1292 | * active bit. |
1273 | */ | 1293 | */ |
1294 | u64 eisr = vgic_get_eisr(vcpu); | ||
1295 | unsigned long *eisr_ptr = (unsigned long *)&eisr; | ||
1274 | int lr; | 1296 | int lr; |
1275 | 1297 | ||
1276 | for_each_set_bit(lr, (unsigned long *)vgic_cpu->vgic_v2.vgic_eisr, | 1298 | for_each_set_bit(lr, eisr_ptr, vgic_cpu->nr_lr) { |
1277 | vgic_cpu->nr_lr) { | ||
1278 | struct vgic_lr vlr = vgic_get_lr(vcpu, lr); | 1299 | struct vgic_lr vlr = vgic_get_lr(vcpu, lr); |
1279 | 1300 | ||
1280 | vgic_irq_clear_active(vcpu, vlr.irq); | 1301 | vgic_irq_clear_active(vcpu, vlr.irq); |