1 // SPDX-License-Identifier: GPL-2.0
3 * vgic init sequence tests
5 * Copyright (C) 2020, Red Hat, Inc.
8 #include <linux/kernel.h>
9 #include <sys/syscall.h>
11 #include <asm/kvm_para.h>
13 #include "test_util.h"
15 #include "processor.h"
20 #define REG_OFFSET(vcpu, offset) (((uint64_t)vcpu << 32) | offset)
22 #define GICR_TYPER 0x8
24 #define VGIC_DEV_IS_V2(_d) ((_d) == KVM_DEV_TYPE_ARM_VGIC_V2)
25 #define VGIC_DEV_IS_V3(_d) ((_d) == KVM_DEV_TYPE_ARM_VGIC_V3)
30 uint32_t gic_dev_type;
33 static uint64_t max_phys_size;
35 /* helper to access a redistributor register */
36 static int access_v3_redist_reg(int gicv3_fd, int vcpu, int offset,
37 uint32_t *val, bool write)
39 uint64_t attr = REG_OFFSET(vcpu, offset);
41 return _kvm_device_access(gicv3_fd, KVM_DEV_ARM_VGIC_GRP_REDIST_REGS,
45 /* dummy guest code */
46 static void guest_code(void)
54 /* we don't want to assert on run execution, hence that helper */
55 static int run_vcpu(struct kvm_vm *vm, uint32_t vcpuid)
58 int ret = __vcpu_ioctl(vm, vcpuid, KVM_RUN, NULL);
64 static struct vm_gic vm_gic_create_with_vcpus(uint32_t gic_dev_type, uint32_t nr_vcpus)
68 v.gic_dev_type = gic_dev_type;
69 v.vm = vm_create_default_with_vcpus(nr_vcpus, 0, 0, guest_code, NULL);
70 v.gic_fd = kvm_create_device(v.vm, gic_dev_type, false);
75 static void vm_gic_destroy(struct vm_gic *v)
81 struct vgic_region_attr {
87 struct vgic_region_attr gic_v3_dist_region = {
88 .attr = KVM_VGIC_V3_ADDR_TYPE_DIST,
93 struct vgic_region_attr gic_v3_redist_region = {
94 .attr = KVM_VGIC_V3_ADDR_TYPE_REDIST,
95 .size = NR_VCPUS * 0x20000,
99 struct vgic_region_attr gic_v2_dist_region = {
100 .attr = KVM_VGIC_V2_ADDR_TYPE_DIST,
105 struct vgic_region_attr gic_v2_cpu_region = {
106 .attr = KVM_VGIC_V2_ADDR_TYPE_CPU,
112 * Helper routine that performs KVM device tests in general. Eventually the
113 * ARM_VGIC (GICv2 or GICv3) device gets created with an overlapping
114 * DIST/REDIST (or DIST/CPUIF for GICv2). Assumption is 4 vcpus are going to be
115 * used hence the overlap. In the case of GICv3, A RDIST region is set at @0x0
116 * and a DIST region is set @0x70000. The GICv2 case sets a CPUIF @0x0 and a
117 * DIST region @0x1000.
119 static void subtest_dist_rdist(struct vm_gic *v)
123 struct vgic_region_attr rdist; /* CPU interface in GICv2*/
124 struct vgic_region_attr dist;
126 rdist = VGIC_DEV_IS_V3(v->gic_dev_type) ? gic_v3_redist_region
128 dist = VGIC_DEV_IS_V3(v->gic_dev_type) ? gic_v3_dist_region
129 : gic_v2_dist_region;
131 /* Check existing group/attributes */
132 kvm_device_check_attr(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
135 kvm_device_check_attr(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
138 /* check non existing attribute */
139 ret = _kvm_device_check_attr(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR, -1);
140 TEST_ASSERT(ret && errno == ENXIO, "attribute not supported");
142 /* misaligned DIST and REDIST address settings */
143 addr = dist.alignment / 0x10;
144 ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
145 dist.attr, &addr, true);
146 TEST_ASSERT(ret && errno == EINVAL, "GIC dist base not aligned");
148 addr = rdist.alignment / 0x10;
149 ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
150 rdist.attr, &addr, true);
151 TEST_ASSERT(ret && errno == EINVAL, "GIC redist/cpu base not aligned");
153 /* out of range address */
154 addr = max_phys_size;
155 ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
156 dist.attr, &addr, true);
157 TEST_ASSERT(ret && errno == E2BIG, "dist address beyond IPA limit");
159 ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
160 rdist.attr, &addr, true);
161 TEST_ASSERT(ret && errno == E2BIG, "redist address beyond IPA limit");
163 /* Space for half a rdist (a rdist is: 2 * rdist.alignment). */
164 addr = max_phys_size - dist.alignment;
165 ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
166 rdist.attr, &addr, true);
167 TEST_ASSERT(ret && errno == E2BIG,
168 "half of the redist is beyond IPA limit");
170 /* set REDIST base address @0x0*/
172 kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
173 rdist.attr, &addr, true);
175 /* Attempt to create a second legacy redistributor region */
177 ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
178 rdist.attr, &addr, true);
179 TEST_ASSERT(ret && errno == EEXIST, "GIC redist base set again");
181 ret = _kvm_device_check_attr(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
182 KVM_VGIC_V3_ADDR_TYPE_REDIST);
184 /* Attempt to mix legacy and new redistributor regions */
185 addr = REDIST_REGION_ATTR_ADDR(NR_VCPUS, 0x100000, 0, 0);
186 ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
187 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION,
189 TEST_ASSERT(ret && errno == EINVAL,
190 "attempt to mix GICv3 REDIST and REDIST_REGION");
194 * Set overlapping DIST / REDIST, cannot be detected here. Will be detected
195 * on first vcpu run instead.
197 addr = rdist.size - rdist.alignment;
198 kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
199 dist.attr, &addr, true);
202 /* Test the new REDIST region API */
203 static void subtest_v3_redist_regions(struct vm_gic *v)
205 uint64_t addr, expected_addr;
208 ret = kvm_device_check_attr(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
209 KVM_VGIC_V3_ADDR_TYPE_REDIST);
210 TEST_ASSERT(!ret, "Multiple redist regions advertised");
212 addr = REDIST_REGION_ATTR_ADDR(NR_VCPUS, 0x100000, 2, 0);
213 ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
214 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
215 TEST_ASSERT(ret && errno == EINVAL, "redist region attr value with flags != 0");
217 addr = REDIST_REGION_ATTR_ADDR(0, 0x100000, 0, 0);
218 ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
219 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
220 TEST_ASSERT(ret && errno == EINVAL, "redist region attr value with count== 0");
222 addr = REDIST_REGION_ATTR_ADDR(2, 0x200000, 0, 1);
223 ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
224 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
225 TEST_ASSERT(ret && errno == EINVAL,
226 "attempt to register the first rdist region with index != 0");
228 addr = REDIST_REGION_ATTR_ADDR(2, 0x201000, 0, 1);
229 ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
230 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
231 TEST_ASSERT(ret && errno == EINVAL, "rdist region with misaligned address");
233 addr = REDIST_REGION_ATTR_ADDR(2, 0x200000, 0, 0);
234 kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
235 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
237 addr = REDIST_REGION_ATTR_ADDR(2, 0x200000, 0, 1);
238 ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
239 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
240 TEST_ASSERT(ret && errno == EINVAL, "register an rdist region with already used index");
242 addr = REDIST_REGION_ATTR_ADDR(1, 0x210000, 0, 2);
243 ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
244 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
245 TEST_ASSERT(ret && errno == EINVAL,
246 "register an rdist region overlapping with another one");
248 addr = REDIST_REGION_ATTR_ADDR(1, 0x240000, 0, 2);
249 ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
250 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
251 TEST_ASSERT(ret && errno == EINVAL, "register redist region with index not +1");
253 addr = REDIST_REGION_ATTR_ADDR(1, 0x240000, 0, 1);
254 kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
255 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
257 addr = REDIST_REGION_ATTR_ADDR(1, max_phys_size, 0, 2);
258 ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
259 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
260 TEST_ASSERT(ret && errno == E2BIG,
261 "register redist region with base address beyond IPA range");
263 /* The last redist is above the pa range. */
264 addr = REDIST_REGION_ATTR_ADDR(2, max_phys_size - 0x30000, 0, 2);
265 ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
266 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
267 TEST_ASSERT(ret && errno == E2BIG,
268 "register redist region with top address beyond IPA range");
271 ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
272 KVM_VGIC_V3_ADDR_TYPE_REDIST, &addr, true);
273 TEST_ASSERT(ret && errno == EINVAL,
274 "Mix KVM_VGIC_V3_ADDR_TYPE_REDIST and REDIST_REGION");
277 * Now there are 2 redist regions:
278 * region 0 @ 0x200000 2 redists
279 * region 1 @ 0x240000 1 redist
280 * Attempt to read their characteristics
283 addr = REDIST_REGION_ATTR_ADDR(0, 0, 0, 0);
284 expected_addr = REDIST_REGION_ATTR_ADDR(2, 0x200000, 0, 0);
285 ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
286 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, false);
287 TEST_ASSERT(!ret && addr == expected_addr, "read characteristics of region #0");
289 addr = REDIST_REGION_ATTR_ADDR(0, 0, 0, 1);
290 expected_addr = REDIST_REGION_ATTR_ADDR(1, 0x240000, 0, 1);
291 ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
292 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, false);
293 TEST_ASSERT(!ret && addr == expected_addr, "read characteristics of region #1");
295 addr = REDIST_REGION_ATTR_ADDR(0, 0, 0, 2);
296 ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
297 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, false);
298 TEST_ASSERT(ret && errno == ENOENT, "read characteristics of non existing region");
301 kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
302 KVM_VGIC_V3_ADDR_TYPE_DIST, &addr, true);
304 addr = REDIST_REGION_ATTR_ADDR(1, 0x260000, 0, 2);
305 ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
306 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
307 TEST_ASSERT(ret && errno == EINVAL, "register redist region colliding with dist");
311 * VGIC KVM device is created and initialized before the secondary CPUs
314 static void test_vgic_then_vcpus(uint32_t gic_dev_type)
319 v = vm_gic_create_with_vcpus(gic_dev_type, 1);
321 subtest_dist_rdist(&v);
323 /* Add the rest of the VCPUs */
324 for (i = 1; i < NR_VCPUS; ++i)
325 vm_vcpu_add_default(v.vm, i, guest_code);
327 ret = run_vcpu(v.vm, 3);
328 TEST_ASSERT(ret == -EINVAL, "dist/rdist overlap detected on 1st vcpu run");
333 /* All the VCPUs are created before the VGIC KVM device gets initialized */
334 static void test_vcpus_then_vgic(uint32_t gic_dev_type)
339 v = vm_gic_create_with_vcpus(gic_dev_type, NR_VCPUS);
341 subtest_dist_rdist(&v);
343 ret = run_vcpu(v.vm, 3);
344 TEST_ASSERT(ret == -EINVAL, "dist/rdist overlap detected on 1st vcpu run");
349 static void test_v3_new_redist_regions(void)
356 v = vm_gic_create_with_vcpus(KVM_DEV_TYPE_ARM_VGIC_V3, NR_VCPUS);
357 subtest_v3_redist_regions(&v);
358 kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
359 KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true);
361 ret = run_vcpu(v.vm, 3);
362 TEST_ASSERT(ret == -ENXIO, "running without sufficient number of rdists");
367 v = vm_gic_create_with_vcpus(KVM_DEV_TYPE_ARM_VGIC_V3, NR_VCPUS);
368 subtest_v3_redist_regions(&v);
370 addr = REDIST_REGION_ATTR_ADDR(1, 0x280000, 0, 2);
371 kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
372 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
374 ret = run_vcpu(v.vm, 3);
375 TEST_ASSERT(ret == -EBUSY, "running without vgic explicit init");
381 v = vm_gic_create_with_vcpus(KVM_DEV_TYPE_ARM_VGIC_V3, NR_VCPUS);
382 subtest_v3_redist_regions(&v);
384 ret = _kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
385 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, dummy, true);
386 TEST_ASSERT(ret && errno == EFAULT,
387 "register a third region allowing to cover the 4 vcpus");
389 addr = REDIST_REGION_ATTR_ADDR(1, 0x280000, 0, 2);
390 kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
391 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
393 kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
394 KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true);
396 ret = run_vcpu(v.vm, 3);
397 TEST_ASSERT(!ret, "vcpu run");
402 static void test_v3_typer_accesses(void)
409 v.vm = vm_create_default(0, 0, guest_code);
411 v.gic_fd = kvm_create_device(v.vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);
413 vm_vcpu_add_default(v.vm, 3, guest_code);
415 ret = access_v3_redist_reg(v.gic_fd, 1, GICR_TYPER, &val, false);
416 TEST_ASSERT(ret && errno == EINVAL, "attempting to read GICR_TYPER of non created vcpu");
418 vm_vcpu_add_default(v.vm, 1, guest_code);
420 ret = access_v3_redist_reg(v.gic_fd, 1, GICR_TYPER, &val, false);
421 TEST_ASSERT(ret && errno == EBUSY, "read GICR_TYPER before GIC initialized");
423 vm_vcpu_add_default(v.vm, 2, guest_code);
425 kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
426 KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true);
428 for (i = 0; i < NR_VCPUS ; i++) {
429 ret = access_v3_redist_reg(v.gic_fd, i, GICR_TYPER, &val, false);
430 TEST_ASSERT(!ret && val == i * 0x100,
431 "read GICR_TYPER before rdist region setting");
434 addr = REDIST_REGION_ATTR_ADDR(2, 0x200000, 0, 0);
435 kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
436 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
438 /* The 2 first rdists should be put there (vcpu 0 and 3) */
439 ret = access_v3_redist_reg(v.gic_fd, 0, GICR_TYPER, &val, false);
440 TEST_ASSERT(!ret && !val, "read typer of rdist #0");
442 ret = access_v3_redist_reg(v.gic_fd, 3, GICR_TYPER, &val, false);
443 TEST_ASSERT(!ret && val == 0x310, "read typer of rdist #1");
445 addr = REDIST_REGION_ATTR_ADDR(10, 0x100000, 0, 1);
446 ret = _kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
447 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
448 TEST_ASSERT(ret && errno == EINVAL, "collision with previous rdist region");
450 ret = access_v3_redist_reg(v.gic_fd, 1, GICR_TYPER, &val, false);
451 TEST_ASSERT(!ret && val == 0x100,
452 "no redist region attached to vcpu #1 yet, last cannot be returned");
454 ret = access_v3_redist_reg(v.gic_fd, 2, GICR_TYPER, &val, false);
455 TEST_ASSERT(!ret && val == 0x200,
456 "no redist region attached to vcpu #2, last cannot be returned");
458 addr = REDIST_REGION_ATTR_ADDR(10, 0x20000, 0, 1);
459 kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
460 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
462 ret = access_v3_redist_reg(v.gic_fd, 1, GICR_TYPER, &val, false);
463 TEST_ASSERT(!ret && val == 0x100, "read typer of rdist #1");
465 ret = access_v3_redist_reg(v.gic_fd, 2, GICR_TYPER, &val, false);
466 TEST_ASSERT(!ret && val == 0x210,
467 "read typer of rdist #1, last properly returned");
473 * Test GICR_TYPER last bit with new redist regions
474 * rdist regions #1 and #2 are contiguous
475 * rdist region #0 @0x100000 2 rdist capacity
476 * rdists: 0, 3 (Last)
477 * rdist region #1 @0x240000 2 rdist capacity
478 * rdists: 5, 4 (Last)
479 * rdist region #2 @0x200000 2 rdist capacity
482 static void test_v3_last_bit_redist_regions(void)
484 uint32_t vcpuids[] = { 0, 3, 5, 4, 1, 2 };
490 v.vm = vm_create_default_with_vcpus(6, 0, 0, guest_code, vcpuids);
492 v.gic_fd = kvm_create_device(v.vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);
494 kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
495 KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true);
497 addr = REDIST_REGION_ATTR_ADDR(2, 0x100000, 0, 0);
498 kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
499 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
501 addr = REDIST_REGION_ATTR_ADDR(2, 0x240000, 0, 1);
502 kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
503 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
505 addr = REDIST_REGION_ATTR_ADDR(2, 0x200000, 0, 2);
506 kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
507 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
509 ret = access_v3_redist_reg(v.gic_fd, 0, GICR_TYPER, &val, false);
510 TEST_ASSERT(!ret && val == 0x000, "read typer of rdist #0");
512 ret = access_v3_redist_reg(v.gic_fd, 1, GICR_TYPER, &val, false);
513 TEST_ASSERT(!ret && val == 0x100, "read typer of rdist #1");
515 ret = access_v3_redist_reg(v.gic_fd, 2, GICR_TYPER, &val, false);
516 TEST_ASSERT(!ret && val == 0x200, "read typer of rdist #2");
518 ret = access_v3_redist_reg(v.gic_fd, 3, GICR_TYPER, &val, false);
519 TEST_ASSERT(!ret && val == 0x310, "read typer of rdist #3");
521 ret = access_v3_redist_reg(v.gic_fd, 5, GICR_TYPER, &val, false);
522 TEST_ASSERT(!ret && val == 0x500, "read typer of rdist #5");
524 ret = access_v3_redist_reg(v.gic_fd, 4, GICR_TYPER, &val, false);
525 TEST_ASSERT(!ret && val == 0x410, "read typer of rdist #4");
530 /* Test last bit with legacy region */
531 static void test_v3_last_bit_single_rdist(void)
533 uint32_t vcpuids[] = { 0, 3, 5, 4, 1, 2 };
539 v.vm = vm_create_default_with_vcpus(6, 0, 0, guest_code, vcpuids);
541 v.gic_fd = kvm_create_device(v.vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);
543 kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
544 KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true);
547 kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
548 KVM_VGIC_V3_ADDR_TYPE_REDIST, &addr, true);
550 ret = access_v3_redist_reg(v.gic_fd, 0, GICR_TYPER, &val, false);
551 TEST_ASSERT(!ret && val == 0x000, "read typer of rdist #0");
553 ret = access_v3_redist_reg(v.gic_fd, 3, GICR_TYPER, &val, false);
554 TEST_ASSERT(!ret && val == 0x300, "read typer of rdist #1");
556 ret = access_v3_redist_reg(v.gic_fd, 5, GICR_TYPER, &val, false);
557 TEST_ASSERT(!ret && val == 0x500, "read typer of rdist #2");
559 ret = access_v3_redist_reg(v.gic_fd, 1, GICR_TYPER, &val, false);
560 TEST_ASSERT(!ret && val == 0x100, "read typer of rdist #3");
562 ret = access_v3_redist_reg(v.gic_fd, 2, GICR_TYPER, &val, false);
563 TEST_ASSERT(!ret && val == 0x210, "read typer of rdist #3");
568 /* Uses the legacy REDIST region API. */
569 static void test_v3_redist_ipa_range_check_at_vcpu_run(void)
575 v = vm_gic_create_with_vcpus(KVM_DEV_TYPE_ARM_VGIC_V3, 1);
577 /* Set space for 3 redists, we have 1 vcpu, so this succeeds. */
578 addr = max_phys_size - (3 * 2 * 0x10000);
579 kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
580 KVM_VGIC_V3_ADDR_TYPE_REDIST, &addr, true);
583 kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
584 KVM_VGIC_V3_ADDR_TYPE_DIST, &addr, true);
586 /* Add the rest of the VCPUs */
587 for (i = 1; i < NR_VCPUS; ++i)
588 vm_vcpu_add_default(v.vm, i, guest_code);
590 kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
591 KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true);
593 /* Attempt to run a vcpu without enough redist space. */
594 ret = run_vcpu(v.vm, 2);
595 TEST_ASSERT(ret && errno == EINVAL,
596 "redist base+size above PA range detected on 1st vcpu run");
601 static void test_v3_its_region(void)
607 v = vm_gic_create_with_vcpus(KVM_DEV_TYPE_ARM_VGIC_V3, NR_VCPUS);
608 its_fd = kvm_create_device(v.vm, KVM_DEV_TYPE_ARM_VGIC_ITS, false);
611 ret = _kvm_device_access(its_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
612 KVM_VGIC_ITS_ADDR_TYPE, &addr, true);
613 TEST_ASSERT(ret && errno == EINVAL,
614 "ITS region with misaligned address");
616 addr = max_phys_size;
617 ret = _kvm_device_access(its_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
618 KVM_VGIC_ITS_ADDR_TYPE, &addr, true);
619 TEST_ASSERT(ret && errno == E2BIG,
620 "register ITS region with base address beyond IPA range");
622 addr = max_phys_size - 0x10000;
623 ret = _kvm_device_access(its_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
624 KVM_VGIC_ITS_ADDR_TYPE, &addr, true);
625 TEST_ASSERT(ret && errno == E2BIG,
626 "Half of ITS region is beyond IPA range");
628 /* This one succeeds setting the ITS base */
630 kvm_device_access(its_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
631 KVM_VGIC_ITS_ADDR_TYPE, &addr, true);
634 ret = _kvm_device_access(its_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
635 KVM_VGIC_ITS_ADDR_TYPE, &addr, true);
636 TEST_ASSERT(ret && errno == EEXIST, "ITS base set again");
643 * Returns 0 if it's possible to create GIC device of a given type (V2 or V3).
645 int test_kvm_device(uint32_t gic_dev_type)
651 v.vm = vm_create_default_with_vcpus(NR_VCPUS, 0, 0, guest_code, NULL);
653 /* try to create a non existing KVM device */
654 ret = _kvm_create_device(v.vm, 0, true, &fd);
655 TEST_ASSERT(ret && errno == ENODEV, "unsupported device");
658 ret = _kvm_create_device(v.vm, gic_dev_type, true, &fd);
661 v.gic_fd = kvm_create_device(v.vm, gic_dev_type, false);
663 ret = _kvm_create_device(v.vm, gic_dev_type, false, &fd);
664 TEST_ASSERT(ret && errno == EEXIST, "create GIC device twice");
666 kvm_create_device(v.vm, gic_dev_type, true);
668 /* try to create the other gic_dev_type */
669 other = VGIC_DEV_IS_V2(gic_dev_type) ? KVM_DEV_TYPE_ARM_VGIC_V3
670 : KVM_DEV_TYPE_ARM_VGIC_V2;
672 if (!_kvm_create_device(v.vm, other, true, &fd)) {
673 ret = _kvm_create_device(v.vm, other, false, &fd);
674 TEST_ASSERT(ret && errno == EINVAL,
675 "create GIC device while other version exists");
683 void run_tests(uint32_t gic_dev_type)
685 test_vcpus_then_vgic(gic_dev_type);
686 test_vgic_then_vcpus(gic_dev_type);
688 if (VGIC_DEV_IS_V3(gic_dev_type)) {
689 test_v3_new_redist_regions();
690 test_v3_typer_accesses();
691 test_v3_last_bit_redist_regions();
692 test_v3_last_bit_single_rdist();
693 test_v3_redist_ipa_range_check_at_vcpu_run();
694 test_v3_its_region();
698 int main(int ac, char **av)
703 pa_bits = vm_guest_mode_params[VM_MODE_DEFAULT].pa_bits;
704 max_phys_size = 1ULL << pa_bits;
706 ret = test_kvm_device(KVM_DEV_TYPE_ARM_VGIC_V3);
708 pr_info("Running GIC_v3 tests.\n");
709 run_tests(KVM_DEV_TYPE_ARM_VGIC_V3);
713 ret = test_kvm_device(KVM_DEV_TYPE_ARM_VGIC_V2);
715 pr_info("Running GIC_v2 tests.\n");
716 run_tests(KVM_DEV_TYPE_ARM_VGIC_V2);
720 print_skip("No GICv2 nor GICv3 support");