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