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