1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * vgic init sequence tests
4 *
5 * Copyright (C) 2020, Red Hat, Inc.
6 */
7 #define _GNU_SOURCE
8 #include <linux/kernel.h>
9 #include <linux/bitfield.h>
10 #include <sys/syscall.h>
11 #include <asm/kvm.h>
12 #include <asm/kvm_para.h>
13
14 #include "test_util.h"
15 #include "kvm_util.h"
16 #include "processor.h"
17 #include "vgic.h"
18
19 #define NR_VCPUS 4
20
21 #define REG_OFFSET(vcpu, offset) (((uint64_t)vcpu << 32) | offset)
22
23 #define GICR_TYPER 0x8
24
25 #define VGIC_DEV_IS_V2(_d) ((_d) == KVM_DEV_TYPE_ARM_VGIC_V2)
26 #define VGIC_DEV_IS_V3(_d) ((_d) == KVM_DEV_TYPE_ARM_VGIC_V3)
27
28 struct vm_gic {
29 struct kvm_vm *vm;
30 int gic_fd;
31 uint32_t gic_dev_type;
32 };
33
34 static uint64_t max_phys_size;
35
36 /*
37 * Helpers to access a redistributor register and verify the ioctl() failed or
38 * succeeded as expected, and provided the correct value on success.
39 */
v3_redist_reg_get_errno(int gicv3_fd,int vcpu,int offset,int want,const char * msg)40 static void v3_redist_reg_get_errno(int gicv3_fd, int vcpu, int offset,
41 int want, const char *msg)
42 {
43 uint32_t ignored_val;
44 int ret = __kvm_device_attr_get(gicv3_fd, KVM_DEV_ARM_VGIC_GRP_REDIST_REGS,
45 REG_OFFSET(vcpu, offset), &ignored_val);
46
47 TEST_ASSERT(ret && errno == want, "%s; want errno = %d", msg, want);
48 }
49
v3_redist_reg_get(int gicv3_fd,int vcpu,int offset,uint32_t want,const char * msg)50 static void v3_redist_reg_get(int gicv3_fd, int vcpu, int offset, uint32_t want,
51 const char *msg)
52 {
53 uint32_t val;
54
55 kvm_device_attr_get(gicv3_fd, KVM_DEV_ARM_VGIC_GRP_REDIST_REGS,
56 REG_OFFSET(vcpu, offset), &val);
57 TEST_ASSERT(val == want, "%s; want '0x%x', got '0x%x'", msg, want, val);
58 }
59
60 /* dummy guest code */
guest_code(void)61 static void guest_code(void)
62 {
63 GUEST_SYNC(0);
64 GUEST_SYNC(1);
65 GUEST_SYNC(2);
66 GUEST_DONE();
67 }
68
69 /* we don't want to assert on run execution, hence that helper */
run_vcpu(struct kvm_vcpu * vcpu)70 static int run_vcpu(struct kvm_vcpu *vcpu)
71 {
72 return __vcpu_run(vcpu) ? -errno : 0;
73 }
74
vm_gic_create_with_vcpus(uint32_t gic_dev_type,uint32_t nr_vcpus,struct kvm_vcpu * vcpus[])75 static struct vm_gic vm_gic_create_with_vcpus(uint32_t gic_dev_type,
76 uint32_t nr_vcpus,
77 struct kvm_vcpu *vcpus[])
78 {
79 struct vm_gic v;
80
81 v.gic_dev_type = gic_dev_type;
82 v.vm = vm_create_with_vcpus(nr_vcpus, guest_code, vcpus);
83 v.gic_fd = kvm_create_device(v.vm, gic_dev_type);
84
85 return v;
86 }
87
vm_gic_create_barebones(uint32_t gic_dev_type)88 static struct vm_gic vm_gic_create_barebones(uint32_t gic_dev_type)
89 {
90 struct vm_gic v;
91
92 v.gic_dev_type = gic_dev_type;
93 v.vm = vm_create_barebones();
94 v.gic_fd = kvm_create_device(v.vm, gic_dev_type);
95
96 return v;
97 }
98
99
vm_gic_destroy(struct vm_gic * v)100 static void vm_gic_destroy(struct vm_gic *v)
101 {
102 close(v->gic_fd);
103 kvm_vm_free(v->vm);
104 }
105
106 struct vgic_region_attr {
107 uint64_t attr;
108 uint64_t size;
109 uint64_t alignment;
110 };
111
112 struct vgic_region_attr gic_v3_dist_region = {
113 .attr = KVM_VGIC_V3_ADDR_TYPE_DIST,
114 .size = 0x10000,
115 .alignment = 0x10000,
116 };
117
118 struct vgic_region_attr gic_v3_redist_region = {
119 .attr = KVM_VGIC_V3_ADDR_TYPE_REDIST,
120 .size = NR_VCPUS * 0x20000,
121 .alignment = 0x10000,
122 };
123
124 struct vgic_region_attr gic_v2_dist_region = {
125 .attr = KVM_VGIC_V2_ADDR_TYPE_DIST,
126 .size = 0x1000,
127 .alignment = 0x1000,
128 };
129
130 struct vgic_region_attr gic_v2_cpu_region = {
131 .attr = KVM_VGIC_V2_ADDR_TYPE_CPU,
132 .size = 0x2000,
133 .alignment = 0x1000,
134 };
135
136 /**
137 * Helper routine that performs KVM device tests in general. Eventually the
138 * ARM_VGIC (GICv2 or GICv3) device gets created with an overlapping
139 * DIST/REDIST (or DIST/CPUIF for GICv2). Assumption is 4 vcpus are going to be
140 * used hence the overlap. In the case of GICv3, A RDIST region is set at @0x0
141 * and a DIST region is set @0x70000. The GICv2 case sets a CPUIF @0x0 and a
142 * DIST region @0x1000.
143 */
subtest_dist_rdist(struct vm_gic * v)144 static void subtest_dist_rdist(struct vm_gic *v)
145 {
146 int ret;
147 uint64_t addr;
148 struct vgic_region_attr rdist; /* CPU interface in GICv2*/
149 struct vgic_region_attr dist;
150
151 rdist = VGIC_DEV_IS_V3(v->gic_dev_type) ? gic_v3_redist_region
152 : gic_v2_cpu_region;
153 dist = VGIC_DEV_IS_V3(v->gic_dev_type) ? gic_v3_dist_region
154 : gic_v2_dist_region;
155
156 /* Check existing group/attributes */
157 kvm_has_device_attr(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR, dist.attr);
158
159 kvm_has_device_attr(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR, rdist.attr);
160
161 /* check non existing attribute */
162 ret = __kvm_has_device_attr(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR, -1);
163 TEST_ASSERT(ret && errno == ENXIO, "attribute not supported");
164
165 /* misaligned DIST and REDIST address settings */
166 addr = dist.alignment / 0x10;
167 ret = __kvm_device_attr_set(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
168 dist.attr, &addr);
169 TEST_ASSERT(ret && errno == EINVAL, "GIC dist base not aligned");
170
171 addr = rdist.alignment / 0x10;
172 ret = __kvm_device_attr_set(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
173 rdist.attr, &addr);
174 TEST_ASSERT(ret && errno == EINVAL, "GIC redist/cpu base not aligned");
175
176 /* out of range address */
177 addr = max_phys_size;
178 ret = __kvm_device_attr_set(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
179 dist.attr, &addr);
180 TEST_ASSERT(ret && errno == E2BIG, "dist address beyond IPA limit");
181
182 ret = __kvm_device_attr_set(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
183 rdist.attr, &addr);
184 TEST_ASSERT(ret && errno == E2BIG, "redist address beyond IPA limit");
185
186 /* Space for half a rdist (a rdist is: 2 * rdist.alignment). */
187 addr = max_phys_size - dist.alignment;
188 ret = __kvm_device_attr_set(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
189 rdist.attr, &addr);
190 TEST_ASSERT(ret && errno == E2BIG,
191 "half of the redist is beyond IPA limit");
192
193 /* set REDIST base address @0x0*/
194 addr = 0x00000;
195 kvm_device_attr_set(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
196 rdist.attr, &addr);
197
198 /* Attempt to create a second legacy redistributor region */
199 addr = 0xE0000;
200 ret = __kvm_device_attr_set(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
201 rdist.attr, &addr);
202 TEST_ASSERT(ret && errno == EEXIST, "GIC redist base set again");
203
204 ret = __kvm_has_device_attr(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
205 KVM_VGIC_V3_ADDR_TYPE_REDIST);
206 if (!ret) {
207 /* Attempt to mix legacy and new redistributor regions */
208 addr = REDIST_REGION_ATTR_ADDR(NR_VCPUS, 0x100000, 0, 0);
209 ret = __kvm_device_attr_set(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
210 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr);
211 TEST_ASSERT(ret && errno == EINVAL,
212 "attempt to mix GICv3 REDIST and REDIST_REGION");
213 }
214
215 /*
216 * Set overlapping DIST / REDIST, cannot be detected here. Will be detected
217 * on first vcpu run instead.
218 */
219 addr = rdist.size - rdist.alignment;
220 kvm_device_attr_set(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
221 dist.attr, &addr);
222 }
223
224 /* Test the new REDIST region API */
subtest_v3_redist_regions(struct vm_gic * v)225 static void subtest_v3_redist_regions(struct vm_gic *v)
226 {
227 uint64_t addr, expected_addr;
228 int ret;
229
230 ret = __kvm_has_device_attr(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
231 KVM_VGIC_V3_ADDR_TYPE_REDIST);
232 TEST_ASSERT(!ret, "Multiple redist regions advertised");
233
234 addr = REDIST_REGION_ATTR_ADDR(NR_VCPUS, 0x100000, 2, 0);
235 ret = __kvm_device_attr_set(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
236 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr);
237 TEST_ASSERT(ret && errno == EINVAL, "redist region attr value with flags != 0");
238
239 addr = REDIST_REGION_ATTR_ADDR(0, 0x100000, 0, 0);
240 ret = __kvm_device_attr_set(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
241 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr);
242 TEST_ASSERT(ret && errno == EINVAL, "redist region attr value with count== 0");
243
244 addr = REDIST_REGION_ATTR_ADDR(2, 0x200000, 0, 1);
245 ret = __kvm_device_attr_set(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
246 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr);
247 TEST_ASSERT(ret && errno == EINVAL,
248 "attempt to register the first rdist region with index != 0");
249
250 addr = REDIST_REGION_ATTR_ADDR(2, 0x201000, 0, 1);
251 ret = __kvm_device_attr_set(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
252 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr);
253 TEST_ASSERT(ret && errno == EINVAL, "rdist region with misaligned address");
254
255 addr = REDIST_REGION_ATTR_ADDR(2, 0x200000, 0, 0);
256 kvm_device_attr_set(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
257 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr);
258
259 addr = REDIST_REGION_ATTR_ADDR(2, 0x200000, 0, 1);
260 ret = __kvm_device_attr_set(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
261 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr);
262 TEST_ASSERT(ret && errno == EINVAL, "register an rdist region with already used index");
263
264 addr = REDIST_REGION_ATTR_ADDR(1, 0x210000, 0, 2);
265 ret = __kvm_device_attr_set(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
266 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr);
267 TEST_ASSERT(ret && errno == EINVAL,
268 "register an rdist region overlapping with another one");
269
270 addr = REDIST_REGION_ATTR_ADDR(1, 0x240000, 0, 2);
271 ret = __kvm_device_attr_set(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
272 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr);
273 TEST_ASSERT(ret && errno == EINVAL, "register redist region with index not +1");
274
275 addr = REDIST_REGION_ATTR_ADDR(1, 0x240000, 0, 1);
276 kvm_device_attr_set(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
277 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr);
278
279 addr = REDIST_REGION_ATTR_ADDR(1, max_phys_size, 0, 2);
280 ret = __kvm_device_attr_set(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
281 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr);
282 TEST_ASSERT(ret && errno == E2BIG,
283 "register redist region with base address beyond IPA range");
284
285 /* The last redist is above the pa range. */
286 addr = REDIST_REGION_ATTR_ADDR(2, max_phys_size - 0x30000, 0, 2);
287 ret = __kvm_device_attr_set(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
288 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr);
289 TEST_ASSERT(ret && errno == E2BIG,
290 "register redist region with top address beyond IPA range");
291
292 addr = 0x260000;
293 ret = __kvm_device_attr_set(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
294 KVM_VGIC_V3_ADDR_TYPE_REDIST, &addr);
295 TEST_ASSERT(ret && errno == EINVAL,
296 "Mix KVM_VGIC_V3_ADDR_TYPE_REDIST and REDIST_REGION");
297
298 /*
299 * Now there are 2 redist regions:
300 * region 0 @ 0x200000 2 redists
301 * region 1 @ 0x240000 1 redist
302 * Attempt to read their characteristics
303 */
304
305 addr = REDIST_REGION_ATTR_ADDR(0, 0, 0, 0);
306 expected_addr = REDIST_REGION_ATTR_ADDR(2, 0x200000, 0, 0);
307 ret = __kvm_device_attr_get(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
308 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr);
309 TEST_ASSERT(!ret && addr == expected_addr, "read characteristics of region #0");
310
311 addr = REDIST_REGION_ATTR_ADDR(0, 0, 0, 1);
312 expected_addr = REDIST_REGION_ATTR_ADDR(1, 0x240000, 0, 1);
313 ret = __kvm_device_attr_get(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
314 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr);
315 TEST_ASSERT(!ret && addr == expected_addr, "read characteristics of region #1");
316
317 addr = REDIST_REGION_ATTR_ADDR(0, 0, 0, 2);
318 ret = __kvm_device_attr_get(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
319 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr);
320 TEST_ASSERT(ret && errno == ENOENT, "read characteristics of non existing region");
321
322 addr = 0x260000;
323 kvm_device_attr_set(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
324 KVM_VGIC_V3_ADDR_TYPE_DIST, &addr);
325
326 addr = REDIST_REGION_ATTR_ADDR(1, 0x260000, 0, 2);
327 ret = __kvm_device_attr_set(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
328 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr);
329 TEST_ASSERT(ret && errno == EINVAL, "register redist region colliding with dist");
330 }
331
332 /*
333 * VGIC KVM device is created and initialized before the secondary CPUs
334 * get created
335 */
test_vgic_then_vcpus(uint32_t gic_dev_type)336 static void test_vgic_then_vcpus(uint32_t gic_dev_type)
337 {
338 struct kvm_vcpu *vcpus[NR_VCPUS];
339 struct vm_gic v;
340 int ret, i;
341
342 v = vm_gic_create_with_vcpus(gic_dev_type, 1, vcpus);
343
344 subtest_dist_rdist(&v);
345
346 /* Add the rest of the VCPUs */
347 for (i = 1; i < NR_VCPUS; ++i)
348 vcpus[i] = vm_vcpu_add(v.vm, i, guest_code);
349
350 ret = run_vcpu(vcpus[3]);
351 TEST_ASSERT(ret == -EINVAL, "dist/rdist overlap detected on 1st vcpu run");
352
353 vm_gic_destroy(&v);
354 }
355
356 /* All the VCPUs are created before the VGIC KVM device gets initialized */
test_vcpus_then_vgic(uint32_t gic_dev_type)357 static void test_vcpus_then_vgic(uint32_t gic_dev_type)
358 {
359 struct kvm_vcpu *vcpus[NR_VCPUS];
360 struct vm_gic v;
361 int ret;
362
363 v = vm_gic_create_with_vcpus(gic_dev_type, NR_VCPUS, vcpus);
364
365 subtest_dist_rdist(&v);
366
367 ret = run_vcpu(vcpus[3]);
368 TEST_ASSERT(ret == -EINVAL, "dist/rdist overlap detected on 1st vcpu run");
369
370 vm_gic_destroy(&v);
371 }
372
373 #define KVM_VGIC_V2_ATTR(offset, cpu) \
374 (FIELD_PREP(KVM_DEV_ARM_VGIC_OFFSET_MASK, offset) | \
375 FIELD_PREP(KVM_DEV_ARM_VGIC_CPUID_MASK, cpu))
376
377 #define GIC_CPU_CTRL 0x00
378
test_v2_uaccess_cpuif_no_vcpus(void)379 static void test_v2_uaccess_cpuif_no_vcpus(void)
380 {
381 struct vm_gic v;
382 u64 val = 0;
383 int ret;
384
385 v = vm_gic_create_barebones(KVM_DEV_TYPE_ARM_VGIC_V2);
386 subtest_dist_rdist(&v);
387
388 ret = __kvm_has_device_attr(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_CPU_REGS,
389 KVM_VGIC_V2_ATTR(GIC_CPU_CTRL, 0));
390 TEST_ASSERT(ret && errno == EINVAL,
391 "accessed non-existent CPU interface, want errno: %i",
392 EINVAL);
393 ret = __kvm_device_attr_get(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_CPU_REGS,
394 KVM_VGIC_V2_ATTR(GIC_CPU_CTRL, 0), &val);
395 TEST_ASSERT(ret && errno == EINVAL,
396 "accessed non-existent CPU interface, want errno: %i",
397 EINVAL);
398 ret = __kvm_device_attr_set(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_CPU_REGS,
399 KVM_VGIC_V2_ATTR(GIC_CPU_CTRL, 0), &val);
400 TEST_ASSERT(ret && errno == EINVAL,
401 "accessed non-existent CPU interface, want errno: %i",
402 EINVAL);
403
404 vm_gic_destroy(&v);
405 }
406
test_v3_new_redist_regions(void)407 static void test_v3_new_redist_regions(void)
408 {
409 struct kvm_vcpu *vcpus[NR_VCPUS];
410 void *dummy = NULL;
411 struct vm_gic v;
412 uint64_t addr;
413 int ret;
414
415 v = vm_gic_create_with_vcpus(KVM_DEV_TYPE_ARM_VGIC_V3, NR_VCPUS, vcpus);
416 subtest_v3_redist_regions(&v);
417 kvm_device_attr_set(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
418 KVM_DEV_ARM_VGIC_CTRL_INIT, NULL);
419
420 ret = run_vcpu(vcpus[3]);
421 TEST_ASSERT(ret == -ENXIO, "running without sufficient number of rdists");
422 vm_gic_destroy(&v);
423
424 /* step2 */
425
426 v = vm_gic_create_with_vcpus(KVM_DEV_TYPE_ARM_VGIC_V3, NR_VCPUS, vcpus);
427 subtest_v3_redist_regions(&v);
428
429 addr = REDIST_REGION_ATTR_ADDR(1, 0x280000, 0, 2);
430 kvm_device_attr_set(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
431 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr);
432
433 ret = run_vcpu(vcpus[3]);
434 TEST_ASSERT(ret == -EBUSY, "running without vgic explicit init");
435
436 vm_gic_destroy(&v);
437
438 /* step 3 */
439
440 v = vm_gic_create_with_vcpus(KVM_DEV_TYPE_ARM_VGIC_V3, NR_VCPUS, vcpus);
441 subtest_v3_redist_regions(&v);
442
443 ret = __kvm_device_attr_set(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
444 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, dummy);
445 TEST_ASSERT(ret && errno == EFAULT,
446 "register a third region allowing to cover the 4 vcpus");
447
448 addr = REDIST_REGION_ATTR_ADDR(1, 0x280000, 0, 2);
449 kvm_device_attr_set(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
450 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr);
451
452 kvm_device_attr_set(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
453 KVM_DEV_ARM_VGIC_CTRL_INIT, NULL);
454
455 ret = run_vcpu(vcpus[3]);
456 TEST_ASSERT(!ret, "vcpu run");
457
458 vm_gic_destroy(&v);
459 }
460
test_v3_typer_accesses(void)461 static void test_v3_typer_accesses(void)
462 {
463 struct vm_gic v;
464 uint64_t addr;
465 int ret, i;
466
467 v.vm = vm_create(NR_VCPUS);
468 (void)vm_vcpu_add(v.vm, 0, guest_code);
469
470 v.gic_fd = kvm_create_device(v.vm, KVM_DEV_TYPE_ARM_VGIC_V3);
471
472 (void)vm_vcpu_add(v.vm, 3, guest_code);
473
474 v3_redist_reg_get_errno(v.gic_fd, 1, GICR_TYPER, EINVAL,
475 "attempting to read GICR_TYPER of non created vcpu");
476
477 (void)vm_vcpu_add(v.vm, 1, guest_code);
478
479 v3_redist_reg_get_errno(v.gic_fd, 1, GICR_TYPER, EBUSY,
480 "read GICR_TYPER before GIC initialized");
481
482 (void)vm_vcpu_add(v.vm, 2, guest_code);
483
484 kvm_device_attr_set(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
485 KVM_DEV_ARM_VGIC_CTRL_INIT, NULL);
486
487 for (i = 0; i < NR_VCPUS ; i++) {
488 v3_redist_reg_get(v.gic_fd, i, GICR_TYPER, i * 0x100,
489 "read GICR_TYPER before rdist region setting");
490 }
491
492 addr = REDIST_REGION_ATTR_ADDR(2, 0x200000, 0, 0);
493 kvm_device_attr_set(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
494 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr);
495
496 /* The 2 first rdists should be put there (vcpu 0 and 3) */
497 v3_redist_reg_get(v.gic_fd, 0, GICR_TYPER, 0x0, "read typer of rdist #0");
498 v3_redist_reg_get(v.gic_fd, 3, GICR_TYPER, 0x310, "read typer of rdist #1");
499
500 addr = REDIST_REGION_ATTR_ADDR(10, 0x100000, 0, 1);
501 ret = __kvm_device_attr_set(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
502 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr);
503 TEST_ASSERT(ret && errno == EINVAL, "collision with previous rdist region");
504
505 v3_redist_reg_get(v.gic_fd, 1, GICR_TYPER, 0x100,
506 "no redist region attached to vcpu #1 yet, last cannot be returned");
507 v3_redist_reg_get(v.gic_fd, 2, GICR_TYPER, 0x200,
508 "no redist region attached to vcpu #2, last cannot be returned");
509
510 addr = REDIST_REGION_ATTR_ADDR(10, 0x20000, 0, 1);
511 kvm_device_attr_set(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
512 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr);
513
514 v3_redist_reg_get(v.gic_fd, 1, GICR_TYPER, 0x100, "read typer of rdist #1");
515 v3_redist_reg_get(v.gic_fd, 2, GICR_TYPER, 0x210,
516 "read typer of rdist #1, last properly returned");
517
518 vm_gic_destroy(&v);
519 }
520
vm_gic_v3_create_with_vcpuids(int nr_vcpus,uint32_t vcpuids[])521 static struct vm_gic vm_gic_v3_create_with_vcpuids(int nr_vcpus,
522 uint32_t vcpuids[])
523 {
524 struct vm_gic v;
525 int i;
526
527 v.vm = vm_create(nr_vcpus);
528 for (i = 0; i < nr_vcpus; i++)
529 vm_vcpu_add(v.vm, vcpuids[i], guest_code);
530
531 v.gic_fd = kvm_create_device(v.vm, KVM_DEV_TYPE_ARM_VGIC_V3);
532
533 return v;
534 }
535
536 /**
537 * Test GICR_TYPER last bit with new redist regions
538 * rdist regions #1 and #2 are contiguous
539 * rdist region #0 @0x100000 2 rdist capacity
540 * rdists: 0, 3 (Last)
541 * rdist region #1 @0x240000 2 rdist capacity
542 * rdists: 5, 4 (Last)
543 * rdist region #2 @0x200000 2 rdist capacity
544 * rdists: 1, 2
545 */
test_v3_last_bit_redist_regions(void)546 static void test_v3_last_bit_redist_regions(void)
547 {
548 uint32_t vcpuids[] = { 0, 3, 5, 4, 1, 2 };
549 struct vm_gic v;
550 uint64_t addr;
551
552 v = vm_gic_v3_create_with_vcpuids(ARRAY_SIZE(vcpuids), vcpuids);
553
554 kvm_device_attr_set(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
555 KVM_DEV_ARM_VGIC_CTRL_INIT, NULL);
556
557 addr = REDIST_REGION_ATTR_ADDR(2, 0x100000, 0, 0);
558 kvm_device_attr_set(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
559 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr);
560
561 addr = REDIST_REGION_ATTR_ADDR(2, 0x240000, 0, 1);
562 kvm_device_attr_set(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
563 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr);
564
565 addr = REDIST_REGION_ATTR_ADDR(2, 0x200000, 0, 2);
566 kvm_device_attr_set(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
567 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr);
568
569 v3_redist_reg_get(v.gic_fd, 0, GICR_TYPER, 0x000, "read typer of rdist #0");
570 v3_redist_reg_get(v.gic_fd, 1, GICR_TYPER, 0x100, "read typer of rdist #1");
571 v3_redist_reg_get(v.gic_fd, 2, GICR_TYPER, 0x200, "read typer of rdist #2");
572 v3_redist_reg_get(v.gic_fd, 3, GICR_TYPER, 0x310, "read typer of rdist #3");
573 v3_redist_reg_get(v.gic_fd, 5, GICR_TYPER, 0x500, "read typer of rdist #5");
574 v3_redist_reg_get(v.gic_fd, 4, GICR_TYPER, 0x410, "read typer of rdist #4");
575
576 vm_gic_destroy(&v);
577 }
578
579 /* Test last bit with legacy region */
test_v3_last_bit_single_rdist(void)580 static void test_v3_last_bit_single_rdist(void)
581 {
582 uint32_t vcpuids[] = { 0, 3, 5, 4, 1, 2 };
583 struct vm_gic v;
584 uint64_t addr;
585
586 v = vm_gic_v3_create_with_vcpuids(ARRAY_SIZE(vcpuids), vcpuids);
587
588 kvm_device_attr_set(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
589 KVM_DEV_ARM_VGIC_CTRL_INIT, NULL);
590
591 addr = 0x10000;
592 kvm_device_attr_set(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
593 KVM_VGIC_V3_ADDR_TYPE_REDIST, &addr);
594
595 v3_redist_reg_get(v.gic_fd, 0, GICR_TYPER, 0x000, "read typer of rdist #0");
596 v3_redist_reg_get(v.gic_fd, 3, GICR_TYPER, 0x300, "read typer of rdist #1");
597 v3_redist_reg_get(v.gic_fd, 5, GICR_TYPER, 0x500, "read typer of rdist #2");
598 v3_redist_reg_get(v.gic_fd, 1, GICR_TYPER, 0x100, "read typer of rdist #3");
599 v3_redist_reg_get(v.gic_fd, 2, GICR_TYPER, 0x210, "read typer of rdist #3");
600
601 vm_gic_destroy(&v);
602 }
603
604 /* Uses the legacy REDIST region API. */
test_v3_redist_ipa_range_check_at_vcpu_run(void)605 static void test_v3_redist_ipa_range_check_at_vcpu_run(void)
606 {
607 struct kvm_vcpu *vcpus[NR_VCPUS];
608 struct vm_gic v;
609 int ret, i;
610 uint64_t addr;
611
612 v = vm_gic_create_with_vcpus(KVM_DEV_TYPE_ARM_VGIC_V3, 1, vcpus);
613
614 /* Set space for 3 redists, we have 1 vcpu, so this succeeds. */
615 addr = max_phys_size - (3 * 2 * 0x10000);
616 kvm_device_attr_set(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
617 KVM_VGIC_V3_ADDR_TYPE_REDIST, &addr);
618
619 addr = 0x00000;
620 kvm_device_attr_set(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
621 KVM_VGIC_V3_ADDR_TYPE_DIST, &addr);
622
623 /* Add the rest of the VCPUs */
624 for (i = 1; i < NR_VCPUS; ++i)
625 vcpus[i] = vm_vcpu_add(v.vm, i, guest_code);
626
627 kvm_device_attr_set(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
628 KVM_DEV_ARM_VGIC_CTRL_INIT, NULL);
629
630 /* Attempt to run a vcpu without enough redist space. */
631 ret = run_vcpu(vcpus[2]);
632 TEST_ASSERT(ret && errno == EINVAL,
633 "redist base+size above PA range detected on 1st vcpu run");
634
635 vm_gic_destroy(&v);
636 }
637
test_v3_its_region(void)638 static void test_v3_its_region(void)
639 {
640 struct kvm_vcpu *vcpus[NR_VCPUS];
641 struct vm_gic v;
642 uint64_t addr;
643 int its_fd, ret;
644
645 v = vm_gic_create_with_vcpus(KVM_DEV_TYPE_ARM_VGIC_V3, NR_VCPUS, vcpus);
646 its_fd = kvm_create_device(v.vm, KVM_DEV_TYPE_ARM_VGIC_ITS);
647
648 addr = 0x401000;
649 ret = __kvm_device_attr_set(its_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
650 KVM_VGIC_ITS_ADDR_TYPE, &addr);
651 TEST_ASSERT(ret && errno == EINVAL,
652 "ITS region with misaligned address");
653
654 addr = max_phys_size;
655 ret = __kvm_device_attr_set(its_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
656 KVM_VGIC_ITS_ADDR_TYPE, &addr);
657 TEST_ASSERT(ret && errno == E2BIG,
658 "register ITS region with base address beyond IPA range");
659
660 addr = max_phys_size - 0x10000;
661 ret = __kvm_device_attr_set(its_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
662 KVM_VGIC_ITS_ADDR_TYPE, &addr);
663 TEST_ASSERT(ret && errno == E2BIG,
664 "Half of ITS region is beyond IPA range");
665
666 /* This one succeeds setting the ITS base */
667 addr = 0x400000;
668 kvm_device_attr_set(its_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
669 KVM_VGIC_ITS_ADDR_TYPE, &addr);
670
671 addr = 0x300000;
672 ret = __kvm_device_attr_set(its_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
673 KVM_VGIC_ITS_ADDR_TYPE, &addr);
674 TEST_ASSERT(ret && errno == EEXIST, "ITS base set again");
675
676 close(its_fd);
677 vm_gic_destroy(&v);
678 }
679
680 /*
681 * Returns 0 if it's possible to create GIC device of a given type (V2 or V3).
682 */
test_kvm_device(uint32_t gic_dev_type)683 int test_kvm_device(uint32_t gic_dev_type)
684 {
685 struct kvm_vcpu *vcpus[NR_VCPUS];
686 struct vm_gic v;
687 uint32_t other;
688 int ret;
689
690 v.vm = vm_create_with_vcpus(NR_VCPUS, guest_code, vcpus);
691
692 /* try to create a non existing KVM device */
693 ret = __kvm_test_create_device(v.vm, 0);
694 TEST_ASSERT(ret && errno == ENODEV, "unsupported device");
695
696 /* trial mode */
697 ret = __kvm_test_create_device(v.vm, gic_dev_type);
698 if (ret)
699 return ret;
700 v.gic_fd = kvm_create_device(v.vm, gic_dev_type);
701
702 ret = __kvm_create_device(v.vm, gic_dev_type);
703 TEST_ASSERT(ret < 0 && errno == EEXIST, "create GIC device twice");
704
705 /* try to create the other gic_dev_type */
706 other = VGIC_DEV_IS_V2(gic_dev_type) ? KVM_DEV_TYPE_ARM_VGIC_V3
707 : KVM_DEV_TYPE_ARM_VGIC_V2;
708
709 if (!__kvm_test_create_device(v.vm, other)) {
710 ret = __kvm_create_device(v.vm, other);
711 TEST_ASSERT(ret < 0 && (errno == EINVAL || errno == EEXIST),
712 "create GIC device while other version exists");
713 }
714
715 vm_gic_destroy(&v);
716
717 return 0;
718 }
719
run_tests(uint32_t gic_dev_type)720 void run_tests(uint32_t gic_dev_type)
721 {
722 test_vcpus_then_vgic(gic_dev_type);
723 test_vgic_then_vcpus(gic_dev_type);
724
725 if (VGIC_DEV_IS_V2(gic_dev_type))
726 test_v2_uaccess_cpuif_no_vcpus();
727
728 if (VGIC_DEV_IS_V3(gic_dev_type)) {
729 test_v3_new_redist_regions();
730 test_v3_typer_accesses();
731 test_v3_last_bit_redist_regions();
732 test_v3_last_bit_single_rdist();
733 test_v3_redist_ipa_range_check_at_vcpu_run();
734 test_v3_its_region();
735 }
736 }
737
main(int ac,char ** av)738 int main(int ac, char **av)
739 {
740 int ret;
741 int pa_bits;
742 int cnt_impl = 0;
743
744 pa_bits = vm_guest_mode_params[VM_MODE_DEFAULT].pa_bits;
745 max_phys_size = 1ULL << pa_bits;
746
747 ret = test_kvm_device(KVM_DEV_TYPE_ARM_VGIC_V3);
748 if (!ret) {
749 pr_info("Running GIC_v3 tests.\n");
750 run_tests(KVM_DEV_TYPE_ARM_VGIC_V3);
751 cnt_impl++;
752 }
753
754 ret = test_kvm_device(KVM_DEV_TYPE_ARM_VGIC_V2);
755 if (!ret) {
756 pr_info("Running GIC_v2 tests.\n");
757 run_tests(KVM_DEV_TYPE_ARM_VGIC_V2);
758 cnt_impl++;
759 }
760
761 if (!cnt_impl) {
762 print_skip("No GICv2 nor GICv3 support");
763 exit(KSFT_SKIP);
764 }
765 return 0;
766 }
767