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