aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/arm
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2014-02-04 13:13:03 -0500
committerChristoffer Dall <christoffer.dall@linaro.org>2014-07-11 07:57:34 -0400
commit8f186d522c69bb18dd9b93a634da4953228c67d4 (patch)
treed3ed28a710860943ac7709b512bb35ca2b958955 /virt/kvm/arm
parentca85f623e37d096206e092ef037a145a60fa7f85 (diff)
KVM: ARM: vgic: split GICv2 backend from the main vgic code
Brutally hack the innocent vgic code, and move the GICv2 specific code to its own file, using vgic_ops and vgic_params as a way to pass information between the two blocks. Acked-by: Catalin Marinas <catalin.marinas@arm.com> Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'virt/kvm/arm')
-rw-r--r--virt/kvm/arm/vgic-v2.c248
-rw-r--r--virt/kvm/arm/vgic.c267
2 files changed, 294 insertions, 221 deletions
diff --git a/virt/kvm/arm/vgic-v2.c b/virt/kvm/arm/vgic-v2.c
new file mode 100644
index 000000000000..940418ebd0d0
--- /dev/null
+++ b/virt/kvm/arm/vgic-v2.c
@@ -0,0 +1,248 @@
1/*
2 * Copyright (C) 2012,2013 ARM Limited, All Rights Reserved.
3 * Author: Marc Zyngier <marc.zyngier@arm.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include <linux/cpu.h>
19#include <linux/kvm.h>
20#include <linux/kvm_host.h>
21#include <linux/interrupt.h>
22#include <linux/io.h>
23#include <linux/of.h>
24#include <linux/of_address.h>
25#include <linux/of_irq.h>
26
27#include <linux/irqchip/arm-gic.h>
28
29#include <asm/kvm_emulate.h>
30#include <asm/kvm_arm.h>
31#include <asm/kvm_mmu.h>
32
33static struct vgic_lr vgic_v2_get_lr(const struct kvm_vcpu *vcpu, int lr)
34{
35 struct vgic_lr lr_desc;
36 u32 val = vcpu->arch.vgic_cpu.vgic_v2.vgic_lr[lr];
37
38 lr_desc.irq = val & GICH_LR_VIRTUALID;
39 if (lr_desc.irq <= 15)
40 lr_desc.source = (val >> GICH_LR_PHYSID_CPUID_SHIFT) & 0x7;
41 else
42 lr_desc.source = 0;
43 lr_desc.state = 0;
44
45 if (val & GICH_LR_PENDING_BIT)
46 lr_desc.state |= LR_STATE_PENDING;
47 if (val & GICH_LR_ACTIVE_BIT)
48 lr_desc.state |= LR_STATE_ACTIVE;
49 if (val & GICH_LR_EOI)
50 lr_desc.state |= LR_EOI_INT;
51
52 return lr_desc;
53}
54
55static void vgic_v2_set_lr(struct kvm_vcpu *vcpu, int lr,
56 struct vgic_lr lr_desc)
57{
58 u32 lr_val = (lr_desc.source << GICH_LR_PHYSID_CPUID_SHIFT) | lr_desc.irq;
59
60 if (lr_desc.state & LR_STATE_PENDING)
61 lr_val |= GICH_LR_PENDING_BIT;
62 if (lr_desc.state & LR_STATE_ACTIVE)
63 lr_val |= GICH_LR_ACTIVE_BIT;
64 if (lr_desc.state & LR_EOI_INT)
65 lr_val |= GICH_LR_EOI;
66
67 vcpu->arch.vgic_cpu.vgic_v2.vgic_lr[lr] = lr_val;
68}
69
70static void vgic_v2_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr,
71 struct vgic_lr lr_desc)
72{
73 if (!(lr_desc.state & LR_STATE_MASK))
74 set_bit(lr, (unsigned long *)vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr);
75}
76
77static u64 vgic_v2_get_elrsr(const struct kvm_vcpu *vcpu)
78{
79 u64 val;
80
81#if BITS_PER_LONG == 64
82 val = vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr[1];
83 val <<= 32;
84 val |= vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr[0];
85#else
86 val = *(u64 *)vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr;
87#endif
88 return val;
89}
90
91static u64 vgic_v2_get_eisr(const struct kvm_vcpu *vcpu)
92{
93 u64 val;
94
95#if BITS_PER_LONG == 64
96 val = vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr[1];
97 val <<= 32;
98 val |= vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr[0];
99#else
100 val = *(u64 *)vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr;
101#endif
102 return val;
103}
104
105static u32 vgic_v2_get_interrupt_status(const struct kvm_vcpu *vcpu)
106{
107 u32 misr = vcpu->arch.vgic_cpu.vgic_v2.vgic_misr;
108 u32 ret = 0;
109
110 if (misr & GICH_MISR_EOI)
111 ret |= INT_STATUS_EOI;
112 if (misr & GICH_MISR_U)
113 ret |= INT_STATUS_UNDERFLOW;
114
115 return ret;
116}
117
118static void vgic_v2_enable_underflow(struct kvm_vcpu *vcpu)
119{
120 vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr |= GICH_HCR_UIE;
121}
122
123static void vgic_v2_disable_underflow(struct kvm_vcpu *vcpu)
124{
125 vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr &= ~GICH_HCR_UIE;
126}
127
128static void vgic_v2_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp)
129{
130 u32 vmcr = vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr;
131
132 vmcrp->ctlr = (vmcr & GICH_VMCR_CTRL_MASK) >> GICH_VMCR_CTRL_SHIFT;
133 vmcrp->abpr = (vmcr & GICH_VMCR_ALIAS_BINPOINT_MASK) >> GICH_VMCR_ALIAS_BINPOINT_SHIFT;
134 vmcrp->bpr = (vmcr & GICH_VMCR_BINPOINT_MASK) >> GICH_VMCR_BINPOINT_SHIFT;
135 vmcrp->pmr = (vmcr & GICH_VMCR_PRIMASK_MASK) >> GICH_VMCR_PRIMASK_SHIFT;
136}
137
138static void vgic_v2_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp)
139{
140 u32 vmcr;
141
142 vmcr = (vmcrp->ctlr << GICH_VMCR_CTRL_SHIFT) & GICH_VMCR_CTRL_MASK;
143 vmcr |= (vmcrp->abpr << GICH_VMCR_ALIAS_BINPOINT_SHIFT) & GICH_VMCR_ALIAS_BINPOINT_MASK;
144 vmcr |= (vmcrp->bpr << GICH_VMCR_BINPOINT_SHIFT) & GICH_VMCR_BINPOINT_MASK;
145 vmcr |= (vmcrp->pmr << GICH_VMCR_PRIMASK_SHIFT) & GICH_VMCR_PRIMASK_MASK;
146
147 vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr = vmcr;
148}
149
150static void vgic_v2_enable(struct kvm_vcpu *vcpu)
151{
152 /*
153 * By forcing VMCR to zero, the GIC will restore the binary
154 * points to their reset values. Anything else resets to zero
155 * anyway.
156 */
157 vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr = 0;
158
159 /* Get the show on the road... */
160 vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr = GICH_HCR_EN;
161}
162
163static const struct vgic_ops vgic_v2_ops = {
164 .get_lr = vgic_v2_get_lr,
165 .set_lr = vgic_v2_set_lr,
166 .sync_lr_elrsr = vgic_v2_sync_lr_elrsr,
167 .get_elrsr = vgic_v2_get_elrsr,
168 .get_eisr = vgic_v2_get_eisr,
169 .get_interrupt_status = vgic_v2_get_interrupt_status,
170 .enable_underflow = vgic_v2_enable_underflow,
171 .disable_underflow = vgic_v2_disable_underflow,
172 .get_vmcr = vgic_v2_get_vmcr,
173 .set_vmcr = vgic_v2_set_vmcr,
174 .enable = vgic_v2_enable,
175};
176
177static struct vgic_params vgic_v2_params;
178
179/**
180 * vgic_v2_probe - probe for a GICv2 compatible interrupt controller in DT
181 * @node: pointer to the DT node
182 * @ops: address of a pointer to the GICv2 operations
183 * @params: address of a pointer to HW-specific parameters
184 *
185 * Returns 0 if a GICv2 has been found, with the low level operations
186 * in *ops and the HW parameters in *params. Returns an error code
187 * otherwise.
188 */
189int vgic_v2_probe(struct device_node *vgic_node,
190 const struct vgic_ops **ops,
191 const struct vgic_params **params)
192{
193 int ret;
194 struct resource vctrl_res;
195 struct resource vcpu_res;
196 struct vgic_params *vgic = &vgic_v2_params;
197
198 vgic->maint_irq = irq_of_parse_and_map(vgic_node, 0);
199 if (!vgic->maint_irq) {
200 kvm_err("error getting vgic maintenance irq from DT\n");
201 ret = -ENXIO;
202 goto out;
203 }
204
205 ret = of_address_to_resource(vgic_node, 2, &vctrl_res);
206 if (ret) {
207 kvm_err("Cannot obtain GICH resource\n");
208 goto out;
209 }
210
211 vgic->vctrl_base = of_iomap(vgic_node, 2);
212 if (!vgic->vctrl_base) {
213 kvm_err("Cannot ioremap GICH\n");
214 ret = -ENOMEM;
215 goto out;
216 }
217
218 vgic->nr_lr = readl_relaxed(vgic->vctrl_base + GICH_VTR);
219 vgic->nr_lr = (vgic->nr_lr & 0x3f) + 1;
220
221 ret = create_hyp_io_mappings(vgic->vctrl_base,
222 vgic->vctrl_base + resource_size(&vctrl_res),
223 vctrl_res.start);
224 if (ret) {
225 kvm_err("Cannot map VCTRL into hyp\n");
226 goto out_unmap;
227 }
228
229 if (of_address_to_resource(vgic_node, 3, &vcpu_res)) {
230 kvm_err("Cannot obtain GICV resource\n");
231 ret = -ENXIO;
232 goto out_unmap;
233 }
234 vgic->vcpu_base = vcpu_res.start;
235
236 kvm_info("%s@%llx IRQ%d\n", vgic_node->name,
237 vctrl_res.start, vgic->maint_irq);
238
239 *ops = &vgic_v2_ops;
240 *params = vgic;
241 goto out;
242
243out_unmap:
244 iounmap(vgic->vctrl_base);
245out:
246 of_node_put(vgic_node);
247 return ret;
248}
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index f3a996d0a100..e4b9cbbbee4c 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -95,7 +95,8 @@ static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr lr_desc);
95static void vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); 95static void vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr);
96static void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); 96static void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr);
97 97
98static struct vgic_params vgic; 98static const struct vgic_ops *vgic_ops;
99static const struct vgic_params *vgic;
99 100
100static u32 *vgic_bitmap_get_reg(struct vgic_bitmap *x, 101static u32 *vgic_bitmap_get_reg(struct vgic_bitmap *x,
101 int cpuid, u32 offset) 102 int cpuid, u32 offset)
@@ -971,205 +972,61 @@ static void vgic_update_state(struct kvm *kvm)
971 } 972 }
972} 973}
973 974
974static struct vgic_lr vgic_v2_get_lr(const struct kvm_vcpu *vcpu, int lr)
975{
976 struct vgic_lr lr_desc;
977 u32 val = vcpu->arch.vgic_cpu.vgic_v2.vgic_lr[lr];
978
979 lr_desc.irq = val & GICH_LR_VIRTUALID;
980 if (lr_desc.irq <= 15)
981 lr_desc.source = (val >> GICH_LR_PHYSID_CPUID_SHIFT) & 0x7;
982 else
983 lr_desc.source = 0;
984 lr_desc.state = 0;
985
986 if (val & GICH_LR_PENDING_BIT)
987 lr_desc.state |= LR_STATE_PENDING;
988 if (val & GICH_LR_ACTIVE_BIT)
989 lr_desc.state |= LR_STATE_ACTIVE;
990 if (val & GICH_LR_EOI)
991 lr_desc.state |= LR_EOI_INT;
992
993 return lr_desc;
994}
995
996static void vgic_v2_set_lr(struct kvm_vcpu *vcpu, int lr,
997 struct vgic_lr lr_desc)
998{
999 u32 lr_val = (lr_desc.source << GICH_LR_PHYSID_CPUID_SHIFT) | lr_desc.irq;
1000
1001 if (lr_desc.state & LR_STATE_PENDING)
1002 lr_val |= GICH_LR_PENDING_BIT;
1003 if (lr_desc.state & LR_STATE_ACTIVE)
1004 lr_val |= GICH_LR_ACTIVE_BIT;
1005 if (lr_desc.state & LR_EOI_INT)
1006 lr_val |= GICH_LR_EOI;
1007
1008 vcpu->arch.vgic_cpu.vgic_v2.vgic_lr[lr] = lr_val;
1009}
1010
1011static void vgic_v2_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr,
1012 struct vgic_lr lr_desc)
1013{
1014 if (!(lr_desc.state & LR_STATE_MASK))
1015 set_bit(lr, (unsigned long *)vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr);
1016}
1017
1018static u64 vgic_v2_get_elrsr(const struct kvm_vcpu *vcpu)
1019{
1020 u64 val;
1021
1022#if BITS_PER_LONG == 64
1023 val = vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr[1];
1024 val <<= 32;
1025 val |= vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr[0];
1026#else
1027 val = *(u64 *)vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr;
1028#endif
1029 return val;
1030}
1031
1032static u64 vgic_v2_get_eisr(const struct kvm_vcpu *vcpu)
1033{
1034 u64 val;
1035
1036#if BITS_PER_LONG == 64
1037 val = vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr[1];
1038 val <<= 32;
1039 val |= vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr[0];
1040#else
1041 val = *(u64 *)vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr;
1042#endif
1043 return val;
1044}
1045
1046static u32 vgic_v2_get_interrupt_status(const struct kvm_vcpu *vcpu)
1047{
1048 u32 misr = vcpu->arch.vgic_cpu.vgic_v2.vgic_misr;
1049 u32 ret = 0;
1050
1051 if (misr & GICH_MISR_EOI)
1052 ret |= INT_STATUS_EOI;
1053 if (misr & GICH_MISR_U)
1054 ret |= INT_STATUS_UNDERFLOW;
1055
1056 return ret;
1057}
1058
1059static void vgic_v2_enable_underflow(struct kvm_vcpu *vcpu)
1060{
1061 vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr |= GICH_HCR_UIE;
1062}
1063
1064static void vgic_v2_disable_underflow(struct kvm_vcpu *vcpu)
1065{
1066 vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr &= ~GICH_HCR_UIE;
1067}
1068
1069static void vgic_v2_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp)
1070{
1071 u32 vmcr = vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr;
1072
1073 vmcrp->ctlr = (vmcr & GICH_VMCR_CTRL_MASK) >> GICH_VMCR_CTRL_SHIFT;
1074 vmcrp->abpr = (vmcr & GICH_VMCR_ALIAS_BINPOINT_MASK) >> GICH_VMCR_ALIAS_BINPOINT_SHIFT;
1075 vmcrp->bpr = (vmcr & GICH_VMCR_BINPOINT_MASK) >> GICH_VMCR_BINPOINT_SHIFT;
1076 vmcrp->pmr = (vmcr & GICH_VMCR_PRIMASK_MASK) >> GICH_VMCR_PRIMASK_SHIFT;
1077}
1078
1079static void vgic_v2_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp)
1080{
1081 u32 vmcr;
1082
1083 vmcr = (vmcrp->ctlr << GICH_VMCR_CTRL_SHIFT) & GICH_VMCR_CTRL_MASK;
1084 vmcr |= (vmcrp->abpr << GICH_VMCR_ALIAS_BINPOINT_SHIFT) & GICH_VMCR_ALIAS_BINPOINT_MASK;
1085 vmcr |= (vmcrp->bpr << GICH_VMCR_BINPOINT_SHIFT) & GICH_VMCR_BINPOINT_MASK;
1086 vmcr |= (vmcrp->pmr << GICH_VMCR_PRIMASK_SHIFT) & GICH_VMCR_PRIMASK_MASK;
1087
1088 vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr = vmcr;
1089}
1090
1091static void vgic_v2_enable(struct kvm_vcpu *vcpu)
1092{
1093 /*
1094 * By forcing VMCR to zero, the GIC will restore the binary
1095 * points to their reset values. Anything else resets to zero
1096 * anyway.
1097 */
1098 vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr = 0;
1099
1100 /* Get the show on the road... */
1101 vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr = GICH_HCR_EN;
1102}
1103
1104static const struct vgic_ops vgic_ops = {
1105 .get_lr = vgic_v2_get_lr,
1106 .set_lr = vgic_v2_set_lr,
1107 .sync_lr_elrsr = vgic_v2_sync_lr_elrsr,
1108 .get_elrsr = vgic_v2_get_elrsr,
1109 .get_eisr = vgic_v2_get_eisr,
1110 .get_interrupt_status = vgic_v2_get_interrupt_status,
1111 .enable_underflow = vgic_v2_enable_underflow,
1112 .disable_underflow = vgic_v2_disable_underflow,
1113 .get_vmcr = vgic_v2_get_vmcr,
1114 .set_vmcr = vgic_v2_set_vmcr,
1115 .enable = vgic_v2_enable,
1116};
1117
1118static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr) 975static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr)
1119{ 976{
1120 return vgic_ops.get_lr(vcpu, lr); 977 return vgic_ops->get_lr(vcpu, lr);
1121} 978}
1122 979
1123static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, 980static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr,
1124 struct vgic_lr vlr) 981 struct vgic_lr vlr)
1125{ 982{
1126 vgic_ops.set_lr(vcpu, lr, vlr); 983 vgic_ops->set_lr(vcpu, lr, vlr);
1127} 984}
1128 985
1129static void vgic_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr, 986static void vgic_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr,
1130 struct vgic_lr vlr) 987 struct vgic_lr vlr)
1131{ 988{
1132 vgic_ops.sync_lr_elrsr(vcpu, lr, vlr); 989 vgic_ops->sync_lr_elrsr(vcpu, lr, vlr);
1133} 990}
1134 991
1135static inline u64 vgic_get_elrsr(struct kvm_vcpu *vcpu) 992static inline u64 vgic_get_elrsr(struct kvm_vcpu *vcpu)
1136{ 993{
1137 return vgic_ops.get_elrsr(vcpu); 994 return vgic_ops->get_elrsr(vcpu);
1138} 995}
1139 996
1140static inline u64 vgic_get_eisr(struct kvm_vcpu *vcpu) 997static inline u64 vgic_get_eisr(struct kvm_vcpu *vcpu)
1141{ 998{
1142 return vgic_ops.get_eisr(vcpu); 999 return vgic_ops->get_eisr(vcpu);
1143} 1000}
1144 1001
1145static inline u32 vgic_get_interrupt_status(struct kvm_vcpu *vcpu) 1002static inline u32 vgic_get_interrupt_status(struct kvm_vcpu *vcpu)
1146{ 1003{
1147 return vgic_ops.get_interrupt_status(vcpu); 1004 return vgic_ops->get_interrupt_status(vcpu);
1148} 1005}
1149 1006
1150static inline void vgic_enable_underflow(struct kvm_vcpu *vcpu) 1007static inline void vgic_enable_underflow(struct kvm_vcpu *vcpu)
1151{ 1008{
1152 vgic_ops.enable_underflow(vcpu); 1009 vgic_ops->enable_underflow(vcpu);
1153} 1010}
1154 1011
1155static inline void vgic_disable_underflow(struct kvm_vcpu *vcpu) 1012static inline void vgic_disable_underflow(struct kvm_vcpu *vcpu)
1156{ 1013{
1157 vgic_ops.disable_underflow(vcpu); 1014 vgic_ops->disable_underflow(vcpu);
1158} 1015}
1159 1016
1160static inline void vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr) 1017static inline void vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr)
1161{ 1018{
1162 vgic_ops.get_vmcr(vcpu, vmcr); 1019 vgic_ops->get_vmcr(vcpu, vmcr);
1163} 1020}
1164 1021
1165static void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr) 1022static void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr)
1166{ 1023{
1167 vgic_ops.set_vmcr(vcpu, vmcr); 1024 vgic_ops->set_vmcr(vcpu, vmcr);
1168} 1025}
1169 1026
1170static inline void vgic_enable(struct kvm_vcpu *vcpu) 1027static inline void vgic_enable(struct kvm_vcpu *vcpu)
1171{ 1028{
1172 vgic_ops.enable(vcpu); 1029 vgic_ops->enable(vcpu);
1173} 1030}
1174 1031
1175static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu) 1032static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu)
@@ -1197,7 +1054,7 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu)
1197 struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; 1054 struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
1198 int lr; 1055 int lr;
1199 1056
1200 for_each_set_bit(lr, vgic_cpu->lr_used, vgic.nr_lr) { 1057 for_each_set_bit(lr, vgic_cpu->lr_used, vgic->nr_lr) {
1201 struct vgic_lr vlr = vgic_get_lr(vcpu, lr); 1058 struct vgic_lr vlr = vgic_get_lr(vcpu, lr);
1202 1059
1203 if (!vgic_irq_is_enabled(vcpu, vlr.irq)) { 1060 if (!vgic_irq_is_enabled(vcpu, vlr.irq)) {
@@ -1241,8 +1098,8 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
1241 1098
1242 /* Try to use another LR for this interrupt */ 1099 /* Try to use another LR for this interrupt */
1243 lr = find_first_zero_bit((unsigned long *)vgic_cpu->lr_used, 1100 lr = find_first_zero_bit((unsigned long *)vgic_cpu->lr_used,
1244 vgic.nr_lr); 1101 vgic->nr_lr);
1245 if (lr >= vgic.nr_lr) 1102 if (lr >= vgic->nr_lr)
1246 return false; 1103 return false;
1247 1104
1248 kvm_debug("LR%d allocated for IRQ%d %x\n", lr, irq, sgi_source_id); 1105 kvm_debug("LR%d allocated for IRQ%d %x\n", lr, irq, sgi_source_id);
@@ -1382,7 +1239,7 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
1382 unsigned long *eisr_ptr = (unsigned long *)&eisr; 1239 unsigned long *eisr_ptr = (unsigned long *)&eisr;
1383 int lr; 1240 int lr;
1384 1241
1385 for_each_set_bit(lr, eisr_ptr, vgic.nr_lr) { 1242 for_each_set_bit(lr, eisr_ptr, vgic->nr_lr) {
1386 struct vgic_lr vlr = vgic_get_lr(vcpu, lr); 1243 struct vgic_lr vlr = vgic_get_lr(vcpu, lr);
1387 1244
1388 vgic_irq_clear_active(vcpu, vlr.irq); 1245 vgic_irq_clear_active(vcpu, vlr.irq);
@@ -1430,7 +1287,7 @@ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
1430 elrsr_ptr = (unsigned long *)&elrsr; 1287 elrsr_ptr = (unsigned long *)&elrsr;
1431 1288
1432 /* Clear mappings for empty LRs */ 1289 /* Clear mappings for empty LRs */
1433 for_each_set_bit(lr, elrsr_ptr, vgic.nr_lr) { 1290 for_each_set_bit(lr, elrsr_ptr, vgic->nr_lr) {
1434 struct vgic_lr vlr; 1291 struct vgic_lr vlr;
1435 1292
1436 if (!test_and_clear_bit(lr, vgic_cpu->lr_used)) 1293 if (!test_and_clear_bit(lr, vgic_cpu->lr_used))
@@ -1443,8 +1300,8 @@ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
1443 } 1300 }
1444 1301
1445 /* Check if we still have something up our sleeve... */ 1302 /* Check if we still have something up our sleeve... */
1446 pending = find_first_zero_bit(elrsr_ptr, vgic.nr_lr); 1303 pending = find_first_zero_bit(elrsr_ptr, vgic->nr_lr);
1447 if (level_pending || pending < vgic.nr_lr) 1304 if (level_pending || pending < vgic->nr_lr)
1448 set_bit(vcpu->vcpu_id, &dist->irq_pending_on_cpu); 1305 set_bit(vcpu->vcpu_id, &dist->irq_pending_on_cpu);
1449} 1306}
1450 1307
@@ -1638,7 +1495,7 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
1638 * all the way to the distributor structure to find out. Only 1495 * all the way to the distributor structure to find out. Only
1639 * assembly code should use this one. 1496 * assembly code should use this one.
1640 */ 1497 */
1641 vgic_cpu->nr_lr = vgic.nr_lr; 1498 vgic_cpu->nr_lr = vgic->nr_lr;
1642 1499
1643 vgic_enable(vcpu); 1500 vgic_enable(vcpu);
1644 1501
@@ -1647,7 +1504,7 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
1647 1504
1648static void vgic_init_maintenance_interrupt(void *info) 1505static void vgic_init_maintenance_interrupt(void *info)
1649{ 1506{
1650 enable_percpu_irq(vgic.maint_irq, 0); 1507 enable_percpu_irq(vgic->maint_irq, 0);
1651} 1508}
1652 1509
1653static int vgic_cpu_notify(struct notifier_block *self, 1510static int vgic_cpu_notify(struct notifier_block *self,
@@ -1660,7 +1517,7 @@ static int vgic_cpu_notify(struct notifier_block *self,
1660 break; 1517 break;
1661 case CPU_DYING: 1518 case CPU_DYING:
1662 case CPU_DYING_FROZEN: 1519 case CPU_DYING_FROZEN:
1663 disable_percpu_irq(vgic.maint_irq); 1520 disable_percpu_irq(vgic->maint_irq);
1664 break; 1521 break;
1665 } 1522 }
1666 1523
@@ -1671,31 +1528,36 @@ static struct notifier_block vgic_cpu_nb = {
1671 .notifier_call = vgic_cpu_notify, 1528 .notifier_call = vgic_cpu_notify,
1672}; 1529};
1673 1530
1531static const struct of_device_id vgic_ids[] = {
1532 { .compatible = "arm,cortex-a15-gic", .data = vgic_v2_probe, },
1533 {},
1534};
1535
1674int kvm_vgic_hyp_init(void) 1536int kvm_vgic_hyp_init(void)
1675{ 1537{
1676 int ret; 1538 const struct of_device_id *matched_id;
1677 struct resource vctrl_res; 1539 int (*vgic_probe)(struct device_node *,const struct vgic_ops **,
1678 struct resource vcpu_res; 1540 const struct vgic_params **);
1679 struct device_node *vgic_node; 1541 struct device_node *vgic_node;
1542 int ret;
1680 1543
1681 vgic_node = of_find_compatible_node(NULL, NULL, "arm,cortex-a15-gic"); 1544 vgic_node = of_find_matching_node_and_match(NULL,
1545 vgic_ids, &matched_id);
1682 if (!vgic_node) { 1546 if (!vgic_node) {
1683 kvm_err("error: no compatible vgic node in DT\n"); 1547 kvm_err("error: no compatible GIC node found\n");
1684 return -ENODEV; 1548 return -ENODEV;
1685 } 1549 }
1686 1550
1687 vgic.maint_irq = irq_of_parse_and_map(vgic_node, 0); 1551 vgic_probe = matched_id->data;
1688 if (!vgic.maint_irq) { 1552 ret = vgic_probe(vgic_node, &vgic_ops, &vgic);
1689 kvm_err("error getting vgic maintenance irq from DT\n"); 1553 if (ret)
1690 ret = -ENXIO; 1554 return ret;
1691 goto out;
1692 }
1693 1555
1694 ret = request_percpu_irq(vgic.maint_irq, vgic_maintenance_handler, 1556 ret = request_percpu_irq(vgic->maint_irq, vgic_maintenance_handler,
1695 "vgic", kvm_get_running_vcpus()); 1557 "vgic", kvm_get_running_vcpus());
1696 if (ret) { 1558 if (ret) {
1697 kvm_err("Cannot register interrupt %d\n", vgic.maint_irq); 1559 kvm_err("Cannot register interrupt %d\n", vgic->maint_irq);
1698 goto out; 1560 return ret;
1699 } 1561 }
1700 1562
1701 ret = __register_cpu_notifier(&vgic_cpu_nb); 1563 ret = __register_cpu_notifier(&vgic_cpu_nb);
@@ -1704,49 +1566,12 @@ int kvm_vgic_hyp_init(void)
1704 goto out_free_irq; 1566 goto out_free_irq;
1705 } 1567 }
1706 1568
1707 ret = of_address_to_resource(vgic_node, 2, &vctrl_res);
1708 if (ret) {
1709 kvm_err("Cannot obtain VCTRL resource\n");
1710 goto out_free_irq;
1711 }
1712
1713 vgic.vctrl_base = of_iomap(vgic_node, 2);
1714 if (!vgic.vctrl_base) {
1715 kvm_err("Cannot ioremap VCTRL\n");
1716 ret = -ENOMEM;
1717 goto out_free_irq;
1718 }
1719
1720 vgic.nr_lr = readl_relaxed(vgic.vctrl_base + GICH_VTR);
1721 vgic.nr_lr = (vgic.nr_lr & 0x3f) + 1;
1722
1723 ret = create_hyp_io_mappings(vgic.vctrl_base,
1724 vgic.vctrl_base + resource_size(&vctrl_res),
1725 vctrl_res.start);
1726 if (ret) {
1727 kvm_err("Cannot map VCTRL into hyp\n");
1728 goto out_unmap;
1729 }
1730
1731 kvm_info("%s@%llx IRQ%d\n", vgic_node->name,
1732 vctrl_res.start, vgic.maint_irq);
1733 on_each_cpu(vgic_init_maintenance_interrupt, NULL, 1); 1569 on_each_cpu(vgic_init_maintenance_interrupt, NULL, 1);
1734 1570
1735 if (of_address_to_resource(vgic_node, 3, &vcpu_res)) { 1571 return 0;
1736 kvm_err("Cannot obtain VCPU resource\n");
1737 ret = -ENXIO;
1738 goto out_unmap;
1739 }
1740 vgic.vcpu_base = vcpu_res.start;
1741
1742 goto out;
1743 1572
1744out_unmap:
1745 iounmap(vgic.vctrl_base);
1746out_free_irq: 1573out_free_irq:
1747 free_percpu_irq(vgic.maint_irq, kvm_get_running_vcpus()); 1574 free_percpu_irq(vgic->maint_irq, kvm_get_running_vcpus());
1748out:
1749 of_node_put(vgic_node);
1750 return ret; 1575 return ret;
1751} 1576}
1752 1577
@@ -1779,7 +1604,7 @@ int kvm_vgic_init(struct kvm *kvm)
1779 } 1604 }
1780 1605
1781 ret = kvm_phys_addr_ioremap(kvm, kvm->arch.vgic.vgic_cpu_base, 1606 ret = kvm_phys_addr_ioremap(kvm, kvm->arch.vgic.vgic_cpu_base,
1782 vgic.vcpu_base, KVM_VGIC_V2_CPU_SIZE); 1607 vgic->vcpu_base, KVM_VGIC_V2_CPU_SIZE);
1783 if (ret) { 1608 if (ret) {
1784 kvm_err("Unable to remap VGIC CPU to VCPU\n"); 1609 kvm_err("Unable to remap VGIC CPU to VCPU\n");
1785 goto out; 1610 goto out;
@@ -1825,7 +1650,7 @@ int kvm_vgic_create(struct kvm *kvm)
1825 } 1650 }
1826 1651
1827 spin_lock_init(&kvm->arch.vgic.lock); 1652 spin_lock_init(&kvm->arch.vgic.lock);
1828 kvm->arch.vgic.vctrl_base = vgic.vctrl_base; 1653 kvm->arch.vgic.vctrl_base = vgic->vctrl_base;
1829 kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF; 1654 kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF;
1830 kvm->arch.vgic.vgic_cpu_base = VGIC_ADDR_UNDEF; 1655 kvm->arch.vgic.vgic_cpu_base = VGIC_ADDR_UNDEF;
1831 1656