aboutsummaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2013-06-03 10:55:02 -0400
committerChristoffer Dall <christoffer.dall@linaro.org>2014-07-11 07:57:31 -0400
commit8d5c6b06a5d5f8ebcf40558e566781d572920740 (patch)
treefa9d9631b9336ae2f1c4c061c2bfd6d2b2615f45 /virt
parenteede821dbfd58df89edb072da64e006321eaef58 (diff)
KVM: ARM: vgic: introduce vgic_ops and LR manipulation primitives
In order to split the various register manipulation from the main vgic code, introduce a vgic_ops structure, and start by abstracting the LR manipulation code with a couple of accessors. Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/arm/vgic.c162
1 files changed, 110 insertions, 52 deletions
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 0ba1ab0721fd..11408fee600e 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -94,9 +94,12 @@ static struct device_node *vgic_node;
94#define ACCESS_WRITE_MASK(x) ((x) & (3 << 1)) 94#define ACCESS_WRITE_MASK(x) ((x) & (3 << 1))
95 95
96static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu); 96static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu);
97static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu);
97static void vgic_update_state(struct kvm *kvm); 98static void vgic_update_state(struct kvm *kvm);
98static void vgic_kick_vcpus(struct kvm *kvm); 99static void vgic_kick_vcpus(struct kvm *kvm);
99static void vgic_dispatch_sgi(struct kvm_vcpu *vcpu, u32 reg); 100static void vgic_dispatch_sgi(struct kvm_vcpu *vcpu, u32 reg);
101static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr);
102static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr lr_desc);
100static u32 vgic_nr_lr; 103static u32 vgic_nr_lr;
101 104
102static unsigned int vgic_maint_irq; 105static unsigned int vgic_maint_irq;
@@ -593,18 +596,6 @@ static bool handle_mmio_sgi_reg(struct kvm_vcpu *vcpu,
593 return false; 596 return false;
594} 597}
595 598
596#define LR_CPUID(lr) \
597 (((lr) & GICH_LR_PHYSID_CPUID) >> GICH_LR_PHYSID_CPUID_SHIFT)
598#define LR_IRQID(lr) \
599 ((lr) & GICH_LR_VIRTUALID)
600
601static void vgic_retire_lr(int lr_nr, int irq, struct vgic_cpu *vgic_cpu)
602{
603 clear_bit(lr_nr, vgic_cpu->lr_used);
604 vgic_cpu->vgic_v2.vgic_lr[lr_nr] &= ~GICH_LR_STATE;
605 vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY;
606}
607
608/** 599/**
609 * vgic_unqueue_irqs - move pending IRQs from LRs to the distributor 600 * vgic_unqueue_irqs - move pending IRQs from LRs to the distributor
610 * @vgic_cpu: Pointer to the vgic_cpu struct holding the LRs 601 * @vgic_cpu: Pointer to the vgic_cpu struct holding the LRs
@@ -622,13 +613,10 @@ static void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
622 struct vgic_dist *dist = &vcpu->kvm->arch.vgic; 613 struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
623 struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; 614 struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
624 int vcpu_id = vcpu->vcpu_id; 615 int vcpu_id = vcpu->vcpu_id;
625 int i, irq, source_cpu; 616 int i;
626 u32 *lr;
627 617
628 for_each_set_bit(i, vgic_cpu->lr_used, vgic_cpu->nr_lr) { 618 for_each_set_bit(i, vgic_cpu->lr_used, vgic_cpu->nr_lr) {
629 lr = &vgic_cpu->vgic_v2.vgic_lr[i]; 619 struct vgic_lr lr = vgic_get_lr(vcpu, i);
630 irq = LR_IRQID(*lr);
631 source_cpu = LR_CPUID(*lr);
632 620
633 /* 621 /*
634 * There are three options for the state bits: 622 * There are three options for the state bits:
@@ -640,7 +628,7 @@ static void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
640 * If the LR holds only an active interrupt (not pending) then 628 * If the LR holds only an active interrupt (not pending) then
641 * just leave it alone. 629 * just leave it alone.
642 */ 630 */
643 if ((*lr & GICH_LR_STATE) == GICH_LR_ACTIVE_BIT) 631 if ((lr.state & LR_STATE_MASK) == LR_STATE_ACTIVE)
644 continue; 632 continue;
645 633
646 /* 634 /*
@@ -649,18 +637,19 @@ static void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
649 * is fine, then we are only setting a few bits that were 637 * is fine, then we are only setting a few bits that were
650 * already set. 638 * already set.
651 */ 639 */
652 vgic_dist_irq_set(vcpu, irq); 640 vgic_dist_irq_set(vcpu, lr.irq);
653 if (irq < VGIC_NR_SGIS) 641 if (lr.irq < VGIC_NR_SGIS)
654 dist->irq_sgi_sources[vcpu_id][irq] |= 1 << source_cpu; 642 dist->irq_sgi_sources[vcpu_id][lr.irq] |= 1 << lr.source;
655 *lr &= ~GICH_LR_PENDING_BIT; 643 lr.state &= ~LR_STATE_PENDING;
644 vgic_set_lr(vcpu, i, lr);
656 645
657 /* 646 /*
658 * If there's no state left on the LR (it could still be 647 * If there's no state left on the LR (it could still be
659 * active), then the LR does not hold any useful info and can 648 * active), then the LR does not hold any useful info and can
660 * be marked as free for other use. 649 * be marked as free for other use.
661 */ 650 */
662 if (!(*lr & GICH_LR_STATE)) 651 if (!(lr.state & LR_STATE_MASK))
663 vgic_retire_lr(i, irq, vgic_cpu); 652 vgic_retire_lr(i, lr.irq, vcpu);
664 653
665 /* Finally update the VGIC state. */ 654 /* Finally update the VGIC state. */
666 vgic_update_state(vcpu->kvm); 655 vgic_update_state(vcpu->kvm);
@@ -989,8 +978,69 @@ static void vgic_update_state(struct kvm *kvm)
989 } 978 }
990} 979}
991 980
992#define MK_LR_PEND(src, irq) \ 981static struct vgic_lr vgic_v2_get_lr(const struct kvm_vcpu *vcpu, int lr)
993 (GICH_LR_PENDING_BIT | ((src) << GICH_LR_PHYSID_CPUID_SHIFT) | (irq)) 982{
983 struct vgic_lr lr_desc;
984 u32 val = vcpu->arch.vgic_cpu.vgic_v2.vgic_lr[lr];
985
986 lr_desc.irq = val & GICH_LR_VIRTUALID;
987 if (lr_desc.irq <= 15)
988 lr_desc.source = (val >> GICH_LR_PHYSID_CPUID_SHIFT) & 0x7;
989 else
990 lr_desc.source = 0;
991 lr_desc.state = 0;
992
993 if (val & GICH_LR_PENDING_BIT)
994 lr_desc.state |= LR_STATE_PENDING;
995 if (val & GICH_LR_ACTIVE_BIT)
996 lr_desc.state |= LR_STATE_ACTIVE;
997 if (val & GICH_LR_EOI)
998 lr_desc.state |= LR_EOI_INT;
999
1000 return lr_desc;
1001}
1002
1003static void vgic_v2_set_lr(struct kvm_vcpu *vcpu, int lr,
1004 struct vgic_lr lr_desc)
1005{
1006 u32 lr_val = (lr_desc.source << GICH_LR_PHYSID_CPUID_SHIFT) | lr_desc.irq;
1007
1008 if (lr_desc.state & LR_STATE_PENDING)
1009 lr_val |= GICH_LR_PENDING_BIT;
1010 if (lr_desc.state & LR_STATE_ACTIVE)
1011 lr_val |= GICH_LR_ACTIVE_BIT;
1012 if (lr_desc.state & LR_EOI_INT)
1013 lr_val |= GICH_LR_EOI;
1014
1015 vcpu->arch.vgic_cpu.vgic_v2.vgic_lr[lr] = lr_val;
1016}
1017
1018static const struct vgic_ops vgic_ops = {
1019 .get_lr = vgic_v2_get_lr,
1020 .set_lr = vgic_v2_set_lr,
1021};
1022
1023static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr)
1024{
1025 return vgic_ops.get_lr(vcpu, lr);
1026}
1027
1028static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr,
1029 struct vgic_lr vlr)
1030{
1031 vgic_ops.set_lr(vcpu, lr, vlr);
1032}
1033
1034static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu)
1035{
1036 struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
1037 struct vgic_lr vlr = vgic_get_lr(vcpu, lr_nr);
1038
1039 vlr.state = 0;
1040 vgic_set_lr(vcpu, lr_nr, vlr);
1041 clear_bit(lr_nr, vgic_cpu->lr_used);
1042 vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY;
1043}
994 1044
995/* 1045/*
996 * An interrupt may have been disabled after being made pending on the 1046 * An interrupt may have been disabled after being made pending on the
@@ -1007,12 +1057,12 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu)
1007 int lr; 1057 int lr;
1008 1058
1009 for_each_set_bit(lr, vgic_cpu->lr_used, vgic_cpu->nr_lr) { 1059 for_each_set_bit(lr, vgic_cpu->lr_used, vgic_cpu->nr_lr) {
1010 int irq = vgic_cpu->vgic_v2.vgic_lr[lr] & GICH_LR_VIRTUALID; 1060 struct vgic_lr vlr = vgic_get_lr(vcpu, lr);
1011 1061
1012 if (!vgic_irq_is_enabled(vcpu, irq)) { 1062 if (!vgic_irq_is_enabled(vcpu, vlr.irq)) {
1013 vgic_retire_lr(lr, irq, vgic_cpu); 1063 vgic_retire_lr(lr, vlr.irq, vcpu);
1014 if (vgic_irq_is_active(vcpu, irq)) 1064 if (vgic_irq_is_active(vcpu, vlr.irq))
1015 vgic_irq_clear_active(vcpu, irq); 1065 vgic_irq_clear_active(vcpu, vlr.irq);
1016 } 1066 }
1017 } 1067 }
1018} 1068}
@@ -1024,6 +1074,7 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu)
1024static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) 1074static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
1025{ 1075{
1026 struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; 1076 struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
1077 struct vgic_lr vlr;
1027 int lr; 1078 int lr;
1028 1079
1029 /* Sanitize the input... */ 1080 /* Sanitize the input... */
@@ -1036,13 +1087,15 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
1036 lr = vgic_cpu->vgic_irq_lr_map[irq]; 1087 lr = vgic_cpu->vgic_irq_lr_map[irq];
1037 1088
1038 /* Do we have an active interrupt for the same CPUID? */ 1089 /* Do we have an active interrupt for the same CPUID? */
1039 if (lr != LR_EMPTY && 1090 if (lr != LR_EMPTY) {
1040 (LR_CPUID(vgic_cpu->vgic_v2.vgic_lr[lr]) == sgi_source_id)) { 1091 vlr = vgic_get_lr(vcpu, lr);
1041 kvm_debug("LR%d piggyback for IRQ%d %x\n", 1092 if (vlr.source == sgi_source_id) {
1042 lr, irq, vgic_cpu->vgic_v2.vgic_lr[lr]); 1093 kvm_debug("LR%d piggyback for IRQ%d\n", lr, vlr.irq);
1043 BUG_ON(!test_bit(lr, vgic_cpu->lr_used)); 1094 BUG_ON(!test_bit(lr, vgic_cpu->lr_used));
1044 vgic_cpu->vgic_v2.vgic_lr[lr] |= GICH_LR_PENDING_BIT; 1095 vlr.state |= LR_STATE_PENDING;
1045 return true; 1096 vgic_set_lr(vcpu, lr, vlr);
1097 return true;
1098 }
1046 } 1099 }
1047 1100
1048 /* Try to use another LR for this interrupt */ 1101 /* Try to use another LR for this interrupt */
@@ -1052,12 +1105,16 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
1052 return false; 1105 return false;
1053 1106
1054 kvm_debug("LR%d allocated for IRQ%d %x\n", lr, irq, sgi_source_id); 1107 kvm_debug("LR%d allocated for IRQ%d %x\n", lr, irq, sgi_source_id);
1055 vgic_cpu->vgic_v2.vgic_lr[lr] = MK_LR_PEND(sgi_source_id, irq);
1056 vgic_cpu->vgic_irq_lr_map[irq] = lr; 1108 vgic_cpu->vgic_irq_lr_map[irq] = lr;
1057 set_bit(lr, vgic_cpu->lr_used); 1109 set_bit(lr, vgic_cpu->lr_used);
1058 1110
1111 vlr.irq = irq;
1112 vlr.source = sgi_source_id;
1113 vlr.state = LR_STATE_PENDING;
1059 if (!vgic_irq_is_edge(vcpu, irq)) 1114 if (!vgic_irq_is_edge(vcpu, irq))
1060 vgic_cpu->vgic_v2.vgic_lr[lr] |= GICH_LR_EOI; 1115 vlr.state |= LR_EOI_INT;
1116
1117 vgic_set_lr(vcpu, lr, vlr);
1061 1118
1062 return true; 1119 return true;
1063} 1120}
@@ -1180,21 +1237,23 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
1180 * Some level interrupts have been EOIed. Clear their 1237 * Some level interrupts have been EOIed. Clear their
1181 * active bit. 1238 * active bit.
1182 */ 1239 */
1183 int lr, irq; 1240 int lr;
1184 1241
1185 for_each_set_bit(lr, (unsigned long *)vgic_cpu->vgic_v2.vgic_eisr, 1242 for_each_set_bit(lr, (unsigned long *)vgic_cpu->vgic_v2.vgic_eisr,
1186 vgic_cpu->nr_lr) { 1243 vgic_cpu->nr_lr) {
1187 irq = vgic_cpu->vgic_v2.vgic_lr[lr] & GICH_LR_VIRTUALID; 1244 struct vgic_lr vlr = vgic_get_lr(vcpu, lr);
1188 1245
1189 vgic_irq_clear_active(vcpu, irq); 1246 vgic_irq_clear_active(vcpu, vlr.irq);
1190 vgic_cpu->vgic_v2.vgic_lr[lr] &= ~GICH_LR_EOI; 1247 WARN_ON(vlr.state & LR_STATE_MASK);
1248 vlr.state = 0;
1249 vgic_set_lr(vcpu, lr, vlr);
1191 1250
1192 /* Any additional pending interrupt? */ 1251 /* Any additional pending interrupt? */
1193 if (vgic_dist_irq_is_pending(vcpu, irq)) { 1252 if (vgic_dist_irq_is_pending(vcpu, vlr.irq)) {
1194 vgic_cpu_irq_set(vcpu, irq); 1253 vgic_cpu_irq_set(vcpu, vlr.irq);
1195 level_pending = true; 1254 level_pending = true;
1196 } else { 1255 } else {
1197 vgic_cpu_irq_clear(vcpu, irq); 1256 vgic_cpu_irq_clear(vcpu, vlr.irq);
1198 } 1257 }
1199 1258
1200 /* 1259 /*
@@ -1202,7 +1261,6 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
1202 * been marked as empty. 1261 * been marked as empty.
1203 */ 1262 */
1204 set_bit(lr, (unsigned long *)vgic_cpu->vgic_v2.vgic_elrsr); 1263 set_bit(lr, (unsigned long *)vgic_cpu->vgic_v2.vgic_elrsr);
1205 vgic_cpu->vgic_v2.vgic_lr[lr] &= ~GICH_LR_ACTIVE_BIT;
1206 } 1264 }
1207 } 1265 }
1208 1266
@@ -1228,15 +1286,15 @@ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
1228 /* Clear mappings for empty LRs */ 1286 /* Clear mappings for empty LRs */
1229 for_each_set_bit(lr, (unsigned long *)vgic_cpu->vgic_v2.vgic_elrsr, 1287 for_each_set_bit(lr, (unsigned long *)vgic_cpu->vgic_v2.vgic_elrsr,
1230 vgic_cpu->nr_lr) { 1288 vgic_cpu->nr_lr) {
1231 int irq; 1289 struct vgic_lr vlr;
1232 1290
1233 if (!test_and_clear_bit(lr, vgic_cpu->lr_used)) 1291 if (!test_and_clear_bit(lr, vgic_cpu->lr_used))
1234 continue; 1292 continue;
1235 1293
1236 irq = vgic_cpu->vgic_v2.vgic_lr[lr] & GICH_LR_VIRTUALID; 1294 vlr = vgic_get_lr(vcpu, lr);
1237 1295
1238 BUG_ON(irq >= VGIC_NR_IRQS); 1296 BUG_ON(vlr.irq >= VGIC_NR_IRQS);
1239 vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY; 1297 vgic_cpu->vgic_irq_lr_map[vlr.irq] = LR_EMPTY;
1240 } 1298 }
1241 1299
1242 /* Check if we still have something up our sleeve... */ 1300 /* Check if we still have something up our sleeve... */