diff options
author | Marc Zyngier <marc.zyngier@arm.com> | 2014-02-04 13:13:03 -0500 |
---|---|---|
committer | Christoffer Dall <christoffer.dall@linaro.org> | 2014-07-11 07:57:34 -0400 |
commit | 8f186d522c69bb18dd9b93a634da4953228c67d4 (patch) | |
tree | d3ed28a710860943ac7709b512bb35ca2b958955 /virt/kvm/arm | |
parent | ca85f623e37d096206e092ef037a145a60fa7f85 (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.c | 248 | ||||
-rw-r--r-- | virt/kvm/arm/vgic.c | 267 |
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 | |||
33 | static 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 | |||
55 | static 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 | |||
70 | static 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 | |||
77 | static 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 | |||
91 | static 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 | |||
105 | static 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 | |||
118 | static void vgic_v2_enable_underflow(struct kvm_vcpu *vcpu) | ||
119 | { | ||
120 | vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr |= GICH_HCR_UIE; | ||
121 | } | ||
122 | |||
123 | static void vgic_v2_disable_underflow(struct kvm_vcpu *vcpu) | ||
124 | { | ||
125 | vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr &= ~GICH_HCR_UIE; | ||
126 | } | ||
127 | |||
128 | static 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 | |||
138 | static 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 | |||
150 | static 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 | |||
163 | static 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 | |||
177 | static 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 | */ | ||
189 | int 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 | |||
243 | out_unmap: | ||
244 | iounmap(vgic->vctrl_base); | ||
245 | out: | ||
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); | |||
95 | static void vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); | 95 | static void vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); |
96 | static void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); | 96 | static void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); |
97 | 97 | ||
98 | static struct vgic_params vgic; | 98 | static const struct vgic_ops *vgic_ops; |
99 | static const struct vgic_params *vgic; | ||
99 | 100 | ||
100 | static u32 *vgic_bitmap_get_reg(struct vgic_bitmap *x, | 101 | static 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 | ||
974 | static 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 | |||
996 | static 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 | |||
1011 | static 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 | |||
1018 | static 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 | |||
1032 | static 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 | |||
1046 | static 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 | |||
1059 | static void vgic_v2_enable_underflow(struct kvm_vcpu *vcpu) | ||
1060 | { | ||
1061 | vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr |= GICH_HCR_UIE; | ||
1062 | } | ||
1063 | |||
1064 | static void vgic_v2_disable_underflow(struct kvm_vcpu *vcpu) | ||
1065 | { | ||
1066 | vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr &= ~GICH_HCR_UIE; | ||
1067 | } | ||
1068 | |||
1069 | static 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 | |||
1079 | static 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 | |||
1091 | static 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 | |||
1104 | static 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 | |||
1118 | static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr) | 975 | static 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 | ||
1123 | static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, | 980 | static 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 | ||
1129 | static void vgic_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr, | 986 | static 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 | ||
1135 | static inline u64 vgic_get_elrsr(struct kvm_vcpu *vcpu) | 992 | static 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 | ||
1140 | static inline u64 vgic_get_eisr(struct kvm_vcpu *vcpu) | 997 | static 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 | ||
1145 | static inline u32 vgic_get_interrupt_status(struct kvm_vcpu *vcpu) | 1002 | static 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 | ||
1150 | static inline void vgic_enable_underflow(struct kvm_vcpu *vcpu) | 1007 | static 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 | ||
1155 | static inline void vgic_disable_underflow(struct kvm_vcpu *vcpu) | 1012 | static 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 | ||
1160 | static inline void vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr) | 1017 | static 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 | ||
1165 | static void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr) | 1022 | static 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 | ||
1170 | static inline void vgic_enable(struct kvm_vcpu *vcpu) | 1027 | static inline void vgic_enable(struct kvm_vcpu *vcpu) |
1171 | { | 1028 | { |
1172 | vgic_ops.enable(vcpu); | 1029 | vgic_ops->enable(vcpu); |
1173 | } | 1030 | } |
1174 | 1031 | ||
1175 | static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu) | 1032 | static 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 | ||
1648 | static void vgic_init_maintenance_interrupt(void *info) | 1505 | static 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 | ||
1653 | static int vgic_cpu_notify(struct notifier_block *self, | 1510 | static 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 | ||
1531 | static const struct of_device_id vgic_ids[] = { | ||
1532 | { .compatible = "arm,cortex-a15-gic", .data = vgic_v2_probe, }, | ||
1533 | {}, | ||
1534 | }; | ||
1535 | |||
1674 | int kvm_vgic_hyp_init(void) | 1536 | int 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 | ||
1744 | out_unmap: | ||
1745 | iounmap(vgic.vctrl_base); | ||
1746 | out_free_irq: | 1573 | out_free_irq: |
1747 | free_percpu_irq(vgic.maint_irq, kvm_get_running_vcpus()); | 1574 | free_percpu_irq(vgic->maint_irq, kvm_get_running_vcpus()); |
1748 | out: | ||
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 | ||