• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 #define NR_VCPUS		4
18 
19 #define REDIST_REGION_ATTR_ADDR(count, base, flags, index) (((uint64_t)(count) << 52) | \
20 	((uint64_t)((base) >> 16) << 16) | ((uint64_t)(flags) << 12) | index)
21 #define REG_OFFSET(vcpu, offset) (((uint64_t)vcpu << 32) | offset)
22 
23 #define GICR_TYPER 0x8
24 
25 struct vm_gic {
26 	struct kvm_vm *vm;
27 	int gic_fd;
28 };
29 
30 static int max_ipa_bits;
31 
32 /* helper to access a redistributor register */
access_redist_reg(int gicv3_fd,int vcpu,int offset,uint32_t * val,bool write)33 static int access_redist_reg(int gicv3_fd, int vcpu, int offset,
34 			     uint32_t *val, bool write)
35 {
36 	uint64_t attr = REG_OFFSET(vcpu, offset);
37 
38 	return _kvm_device_access(gicv3_fd, KVM_DEV_ARM_VGIC_GRP_REDIST_REGS,
39 				  attr, val, write);
40 }
41 
42 /* dummy guest code */
guest_code(void)43 static void guest_code(void)
44 {
45 	GUEST_SYNC(0);
46 	GUEST_SYNC(1);
47 	GUEST_SYNC(2);
48 	GUEST_DONE();
49 }
50 
51 /* we don't want to assert on run execution, hence that helper */
run_vcpu(struct kvm_vm * vm,uint32_t vcpuid)52 static int run_vcpu(struct kvm_vm *vm, uint32_t vcpuid)
53 {
54 	ucall_init(vm, NULL);
55 	int ret = _vcpu_ioctl(vm, vcpuid, KVM_RUN, NULL);
56 	if (ret)
57 		return -errno;
58 	return 0;
59 }
60 
vm_gic_create(void)61 static struct vm_gic vm_gic_create(void)
62 {
63 	struct vm_gic v;
64 
65 	v.vm = vm_create_default_with_vcpus(NR_VCPUS, 0, 0, guest_code, NULL);
66 	v.gic_fd = kvm_create_device(v.vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);
67 
68 	return v;
69 }
70 
vm_gic_destroy(struct vm_gic * v)71 static void vm_gic_destroy(struct vm_gic *v)
72 {
73 	close(v->gic_fd);
74 	kvm_vm_free(v->vm);
75 }
76 
77 /**
78  * Helper routine that performs KVM device tests in general and
79  * especially ARM_VGIC_V3 ones. Eventually the ARM_VGIC_V3
80  * device gets created, a legacy RDIST region is set at @0x0
81  * and a DIST region is set @0x60000
82  */
subtest_dist_rdist(struct vm_gic * v)83 static void subtest_dist_rdist(struct vm_gic *v)
84 {
85 	int ret;
86 	uint64_t addr;
87 
88 	/* Check existing group/attributes */
89 	kvm_device_check_attr(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
90 			      KVM_VGIC_V3_ADDR_TYPE_DIST);
91 
92 	kvm_device_check_attr(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
93 			      KVM_VGIC_V3_ADDR_TYPE_REDIST);
94 
95 	/* check non existing attribute */
96 	ret = _kvm_device_check_attr(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR, 0);
97 	TEST_ASSERT(ret && errno == ENXIO, "attribute not supported");
98 
99 	/* misaligned DIST and REDIST address settings */
100 	addr = 0x1000;
101 	ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
102 				 KVM_VGIC_V3_ADDR_TYPE_DIST, &addr, true);
103 	TEST_ASSERT(ret && errno == EINVAL, "GICv3 dist base not 64kB aligned");
104 
105 	ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
106 				 KVM_VGIC_V3_ADDR_TYPE_REDIST, &addr, true);
107 	TEST_ASSERT(ret && errno == EINVAL, "GICv3 redist base not 64kB aligned");
108 
109 	/* out of range address */
110 	if (max_ipa_bits) {
111 		addr = 1ULL << max_ipa_bits;
112 		ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
113 					 KVM_VGIC_V3_ADDR_TYPE_DIST, &addr, true);
114 		TEST_ASSERT(ret && errno == E2BIG, "dist address beyond IPA limit");
115 
116 		ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
117 					 KVM_VGIC_V3_ADDR_TYPE_REDIST, &addr, true);
118 		TEST_ASSERT(ret && errno == E2BIG, "redist address beyond IPA limit");
119 	}
120 
121 	/* set REDIST base address @0x0*/
122 	addr = 0x00000;
123 	kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
124 			  KVM_VGIC_V3_ADDR_TYPE_REDIST, &addr, true);
125 
126 	/* Attempt to create a second legacy redistributor region */
127 	addr = 0xE0000;
128 	ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
129 				 KVM_VGIC_V3_ADDR_TYPE_REDIST, &addr, true);
130 	TEST_ASSERT(ret && errno == EEXIST, "GICv3 redist base set again");
131 
132 	/* Attempt to mix legacy and new redistributor regions */
133 	addr = REDIST_REGION_ATTR_ADDR(NR_VCPUS, 0x100000, 0, 0);
134 	ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
135 				 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
136 	TEST_ASSERT(ret && errno == EINVAL, "attempt to mix GICv3 REDIST and REDIST_REGION");
137 
138 	/*
139 	 * Set overlapping DIST / REDIST, cannot be detected here. Will be detected
140 	 * on first vcpu run instead.
141 	 */
142 	addr = 3 * 2 * 0x10000;
143 	kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V3_ADDR_TYPE_DIST,
144 			  &addr, true);
145 }
146 
147 /* Test the new REDIST region API */
subtest_redist_regions(struct vm_gic * v)148 static void subtest_redist_regions(struct vm_gic *v)
149 {
150 	uint64_t addr, expected_addr;
151 	int ret;
152 
153 	ret = kvm_device_check_attr(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
154 				     KVM_VGIC_V3_ADDR_TYPE_REDIST);
155 	TEST_ASSERT(!ret, "Multiple redist regions advertised");
156 
157 	addr = REDIST_REGION_ATTR_ADDR(NR_VCPUS, 0x100000, 2, 0);
158 	ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
159 				 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
160 	TEST_ASSERT(ret && errno == EINVAL, "redist region attr value with flags != 0");
161 
162 	addr = REDIST_REGION_ATTR_ADDR(0, 0x100000, 0, 0);
163 	ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
164 				 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
165 	TEST_ASSERT(ret && errno == EINVAL, "redist region attr value with count== 0");
166 
167 	addr = REDIST_REGION_ATTR_ADDR(2, 0x200000, 0, 1);
168 	ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
169 				 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
170 	TEST_ASSERT(ret && errno == EINVAL,
171 		    "attempt to register the first rdist region with index != 0");
172 
173 	addr = REDIST_REGION_ATTR_ADDR(2, 0x201000, 0, 1);
174 	ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
175 				 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
176 	TEST_ASSERT(ret && errno == EINVAL, "rdist region with misaligned address");
177 
178 	addr = REDIST_REGION_ATTR_ADDR(2, 0x200000, 0, 0);
179 	kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
180 			  KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
181 
182 	addr = REDIST_REGION_ATTR_ADDR(2, 0x200000, 0, 1);
183 	ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
184 				 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
185 	TEST_ASSERT(ret && errno == EINVAL, "register an rdist region with already used index");
186 
187 	addr = REDIST_REGION_ATTR_ADDR(1, 0x210000, 0, 2);
188 	ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
189 				 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
190 	TEST_ASSERT(ret && errno == EINVAL,
191 		    "register an rdist region overlapping with another one");
192 
193 	addr = REDIST_REGION_ATTR_ADDR(1, 0x240000, 0, 2);
194 	ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
195 				 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
196 	TEST_ASSERT(ret && errno == EINVAL, "register redist region with index not +1");
197 
198 	addr = REDIST_REGION_ATTR_ADDR(1, 0x240000, 0, 1);
199 	kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
200 			  KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
201 
202 	addr = REDIST_REGION_ATTR_ADDR(1, 1ULL << max_ipa_bits, 0, 2);
203 	ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
204 				 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
205 	TEST_ASSERT(ret && errno == E2BIG,
206 		    "register redist region with base address beyond IPA range");
207 
208 	addr = 0x260000;
209 	ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
210 				 KVM_VGIC_V3_ADDR_TYPE_REDIST, &addr, true);
211 	TEST_ASSERT(ret && errno == EINVAL,
212 		    "Mix KVM_VGIC_V3_ADDR_TYPE_REDIST and REDIST_REGION");
213 
214 	/*
215 	 * Now there are 2 redist regions:
216 	 * region 0 @ 0x200000 2 redists
217 	 * region 1 @ 0x240000 1 redist
218 	 * Attempt to read their characteristics
219 	 */
220 
221 	addr = REDIST_REGION_ATTR_ADDR(0, 0, 0, 0);
222 	expected_addr = REDIST_REGION_ATTR_ADDR(2, 0x200000, 0, 0);
223 	ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
224 				 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, false);
225 	TEST_ASSERT(!ret && addr == expected_addr, "read characteristics of region #0");
226 
227 	addr = REDIST_REGION_ATTR_ADDR(0, 0, 0, 1);
228 	expected_addr = REDIST_REGION_ATTR_ADDR(1, 0x240000, 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, false);
231 	TEST_ASSERT(!ret && addr == expected_addr, "read characteristics of region #1");
232 
233 	addr = REDIST_REGION_ATTR_ADDR(0, 0, 0, 2);
234 	ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
235 				 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, false);
236 	TEST_ASSERT(ret && errno == ENOENT, "read characteristics of non existing region");
237 
238 	addr = 0x260000;
239 	kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
240 			  KVM_VGIC_V3_ADDR_TYPE_DIST, &addr, true);
241 
242 	addr = REDIST_REGION_ATTR_ADDR(1, 0x260000, 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, "register redist region colliding with dist");
246 }
247 
248 /*
249  * VGIC KVM device is created and initialized before the secondary CPUs
250  * get created
251  */
test_vgic_then_vcpus(void)252 static void test_vgic_then_vcpus(void)
253 {
254 	struct vm_gic v;
255 	int ret, i;
256 
257 	v.vm = vm_create_default(0, 0, guest_code);
258 	v.gic_fd = kvm_create_device(v.vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);
259 
260 	subtest_dist_rdist(&v);
261 
262 	/* Add the rest of the VCPUs */
263 	for (i = 1; i < NR_VCPUS; ++i)
264 		vm_vcpu_add_default(v.vm, i, guest_code);
265 
266 	ret = run_vcpu(v.vm, 3);
267 	TEST_ASSERT(ret == -EINVAL, "dist/rdist overlap detected on 1st vcpu run");
268 
269 	vm_gic_destroy(&v);
270 }
271 
272 /* All the VCPUs are created before the VGIC KVM device gets initialized */
test_vcpus_then_vgic(void)273 static void test_vcpus_then_vgic(void)
274 {
275 	struct vm_gic v;
276 	int ret;
277 
278 	v = vm_gic_create();
279 
280 	subtest_dist_rdist(&v);
281 
282 	ret = run_vcpu(v.vm, 3);
283 	TEST_ASSERT(ret == -EINVAL, "dist/rdist overlap detected on 1st vcpu run");
284 
285 	vm_gic_destroy(&v);
286 }
287 
test_new_redist_regions(void)288 static void test_new_redist_regions(void)
289 {
290 	void *dummy = NULL;
291 	struct vm_gic v;
292 	uint64_t addr;
293 	int ret;
294 
295 	v = vm_gic_create();
296 	subtest_redist_regions(&v);
297 	kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
298 			  KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true);
299 
300 	ret = run_vcpu(v.vm, 3);
301 	TEST_ASSERT(ret == -ENXIO, "running without sufficient number of rdists");
302 	vm_gic_destroy(&v);
303 
304 	/* step2 */
305 
306 	v = vm_gic_create();
307 	subtest_redist_regions(&v);
308 
309 	addr = REDIST_REGION_ATTR_ADDR(1, 0x280000, 0, 2);
310 	kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
311 			  KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
312 
313 	ret = run_vcpu(v.vm, 3);
314 	TEST_ASSERT(ret == -EBUSY, "running without vgic explicit init");
315 
316 	vm_gic_destroy(&v);
317 
318 	/* step 3 */
319 
320 	v = vm_gic_create();
321 	subtest_redist_regions(&v);
322 
323 	_kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
324 			  KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, dummy, true);
325 	TEST_ASSERT(ret && errno == EFAULT,
326 		    "register a third region allowing to cover the 4 vcpus");
327 
328 	addr = REDIST_REGION_ATTR_ADDR(1, 0x280000, 0, 2);
329 	kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
330 			  KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
331 
332 	kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
333 			  KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true);
334 
335 	ret = run_vcpu(v.vm, 3);
336 	TEST_ASSERT(!ret, "vcpu run");
337 
338 	vm_gic_destroy(&v);
339 }
340 
test_typer_accesses(void)341 static void test_typer_accesses(void)
342 {
343 	struct vm_gic v;
344 	uint64_t addr;
345 	uint32_t val;
346 	int ret, i;
347 
348 	v.vm = vm_create_default(0, 0, guest_code);
349 
350 	v.gic_fd = kvm_create_device(v.vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);
351 
352 	vm_vcpu_add_default(v.vm, 3, guest_code);
353 
354 	ret = access_redist_reg(v.gic_fd, 1, GICR_TYPER, &val, false);
355 	TEST_ASSERT(ret && errno == EINVAL, "attempting to read GICR_TYPER of non created vcpu");
356 
357 	vm_vcpu_add_default(v.vm, 1, guest_code);
358 
359 	ret = access_redist_reg(v.gic_fd, 1, GICR_TYPER, &val, false);
360 	TEST_ASSERT(ret && errno == EBUSY, "read GICR_TYPER before GIC initialized");
361 
362 	vm_vcpu_add_default(v.vm, 2, guest_code);
363 
364 	kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
365 			  KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true);
366 
367 	for (i = 0; i < NR_VCPUS ; i++) {
368 		ret = access_redist_reg(v.gic_fd, 0, GICR_TYPER, &val, false);
369 		TEST_ASSERT(!ret && !val, "read GICR_TYPER before rdist region setting");
370 	}
371 
372 	addr = REDIST_REGION_ATTR_ADDR(2, 0x200000, 0, 0);
373 	kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
374 			  KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
375 
376 	/* The 2 first rdists should be put there (vcpu 0 and 3) */
377 	ret = access_redist_reg(v.gic_fd, 0, GICR_TYPER, &val, false);
378 	TEST_ASSERT(!ret && !val, "read typer of rdist #0");
379 
380 	ret = access_redist_reg(v.gic_fd, 3, GICR_TYPER, &val, false);
381 	TEST_ASSERT(!ret && val == 0x310, "read typer of rdist #1");
382 
383 	addr = REDIST_REGION_ATTR_ADDR(10, 0x100000, 0, 1);
384 	ret = _kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
385 				 KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
386 	TEST_ASSERT(ret && errno == EINVAL, "collision with previous rdist region");
387 
388 	ret = access_redist_reg(v.gic_fd, 1, GICR_TYPER, &val, false);
389 	TEST_ASSERT(!ret && val == 0x100,
390 		    "no redist region attached to vcpu #1 yet, last cannot be returned");
391 
392 	ret = access_redist_reg(v.gic_fd, 2, GICR_TYPER, &val, false);
393 	TEST_ASSERT(!ret && val == 0x200,
394 		    "no redist region attached to vcpu #2, last cannot be returned");
395 
396 	addr = REDIST_REGION_ATTR_ADDR(10, 0x20000, 0, 1);
397 	kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
398 			  KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
399 
400 	ret = access_redist_reg(v.gic_fd, 1, GICR_TYPER, &val, false);
401 	TEST_ASSERT(!ret && val == 0x100, "read typer of rdist #1");
402 
403 	ret = access_redist_reg(v.gic_fd, 2, GICR_TYPER, &val, false);
404 	TEST_ASSERT(!ret && val == 0x210,
405 		    "read typer of rdist #1, last properly returned");
406 
407 	vm_gic_destroy(&v);
408 }
409 
410 /**
411  * Test GICR_TYPER last bit with new redist regions
412  * rdist regions #1 and #2 are contiguous
413  * rdist region #0 @0x100000 2 rdist capacity
414  *     rdists: 0, 3 (Last)
415  * rdist region #1 @0x240000 2 rdist capacity
416  *     rdists:  5, 4 (Last)
417  * rdist region #2 @0x200000 2 rdist capacity
418  *     rdists: 1, 2
419  */
test_last_bit_redist_regions(void)420 static void test_last_bit_redist_regions(void)
421 {
422 	uint32_t vcpuids[] = { 0, 3, 5, 4, 1, 2 };
423 	struct vm_gic v;
424 	uint64_t addr;
425 	uint32_t val;
426 	int ret;
427 
428 	v.vm = vm_create_default_with_vcpus(6, 0, 0, guest_code, vcpuids);
429 
430 	v.gic_fd = kvm_create_device(v.vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);
431 
432 	kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
433 			  KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true);
434 
435 	addr = REDIST_REGION_ATTR_ADDR(2, 0x100000, 0, 0);
436 	kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
437 			  KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
438 
439 	addr = REDIST_REGION_ATTR_ADDR(2, 0x240000, 0, 1);
440 	kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
441 			  KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
442 
443 	addr = REDIST_REGION_ATTR_ADDR(2, 0x200000, 0, 2);
444 	kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
445 			  KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
446 
447 	ret = access_redist_reg(v.gic_fd, 0, GICR_TYPER, &val, false);
448 	TEST_ASSERT(!ret && val == 0x000, "read typer of rdist #0");
449 
450 	ret = access_redist_reg(v.gic_fd, 1, GICR_TYPER, &val, false);
451 	TEST_ASSERT(!ret && val == 0x100, "read typer of rdist #1");
452 
453 	ret = access_redist_reg(v.gic_fd, 2, GICR_TYPER, &val, false);
454 	TEST_ASSERT(!ret && val == 0x200, "read typer of rdist #2");
455 
456 	ret = access_redist_reg(v.gic_fd, 3, GICR_TYPER, &val, false);
457 	TEST_ASSERT(!ret && val == 0x310, "read typer of rdist #3");
458 
459 	ret = access_redist_reg(v.gic_fd, 5, GICR_TYPER, &val, false);
460 	TEST_ASSERT(!ret && val == 0x500, "read typer of rdist #5");
461 
462 	ret = access_redist_reg(v.gic_fd, 4, GICR_TYPER, &val, false);
463 	TEST_ASSERT(!ret && val == 0x410, "read typer of rdist #4");
464 
465 	vm_gic_destroy(&v);
466 }
467 
468 /* Test last bit with legacy region */
test_last_bit_single_rdist(void)469 static void test_last_bit_single_rdist(void)
470 {
471 	uint32_t vcpuids[] = { 0, 3, 5, 4, 1, 2 };
472 	struct vm_gic v;
473 	uint64_t addr;
474 	uint32_t val;
475 	int ret;
476 
477 	v.vm = vm_create_default_with_vcpus(6, 0, 0, guest_code, vcpuids);
478 
479 	v.gic_fd = kvm_create_device(v.vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);
480 
481 	kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
482 			  KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true);
483 
484 	addr = 0x10000;
485 	kvm_device_access(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
486 			  KVM_VGIC_V3_ADDR_TYPE_REDIST, &addr, true);
487 
488 	ret = access_redist_reg(v.gic_fd, 0, GICR_TYPER, &val, false);
489 	TEST_ASSERT(!ret && val == 0x000, "read typer of rdist #0");
490 
491 	ret = access_redist_reg(v.gic_fd, 3, GICR_TYPER, &val, false);
492 	TEST_ASSERT(!ret && val == 0x300, "read typer of rdist #1");
493 
494 	ret = access_redist_reg(v.gic_fd, 5, GICR_TYPER, &val, false);
495 	TEST_ASSERT(!ret && val == 0x500, "read typer of rdist #2");
496 
497 	ret = access_redist_reg(v.gic_fd, 1, GICR_TYPER, &val, false);
498 	TEST_ASSERT(!ret && val == 0x100, "read typer of rdist #3");
499 
500 	ret = access_redist_reg(v.gic_fd, 2, GICR_TYPER, &val, false);
501 	TEST_ASSERT(!ret && val == 0x210, "read typer of rdist #3");
502 
503 	vm_gic_destroy(&v);
504 }
505 
test_kvm_device(void)506 void test_kvm_device(void)
507 {
508 	struct vm_gic v;
509 	int ret, fd;
510 
511 	v.vm = vm_create_default_with_vcpus(NR_VCPUS, 0, 0, guest_code, NULL);
512 
513 	/* try to create a non existing KVM device */
514 	ret = _kvm_create_device(v.vm, 0, true, &fd);
515 	TEST_ASSERT(ret && errno == ENODEV, "unsupported device");
516 
517 	/* trial mode with VGIC_V3 device */
518 	ret = _kvm_create_device(v.vm, KVM_DEV_TYPE_ARM_VGIC_V3, true, &fd);
519 	if (ret) {
520 		print_skip("GICv3 not supported");
521 		exit(KSFT_SKIP);
522 	}
523 	v.gic_fd = kvm_create_device(v.vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);
524 
525 	ret = _kvm_create_device(v.vm, KVM_DEV_TYPE_ARM_VGIC_V3, false, &fd);
526 	TEST_ASSERT(ret && errno == EEXIST, "create GICv3 device twice");
527 
528 	kvm_create_device(v.vm, KVM_DEV_TYPE_ARM_VGIC_V3, true);
529 
530 	if (!_kvm_create_device(v.vm, KVM_DEV_TYPE_ARM_VGIC_V2, true, &fd)) {
531 		ret = _kvm_create_device(v.vm, KVM_DEV_TYPE_ARM_VGIC_V2, false, &fd);
532 		TEST_ASSERT(ret && errno == EINVAL, "create GICv2 while v3 exists");
533 	}
534 
535 	vm_gic_destroy(&v);
536 }
537 
main(int ac,char ** av)538 int main(int ac, char **av)
539 {
540 	max_ipa_bits = kvm_check_cap(KVM_CAP_ARM_VM_IPA_SIZE);
541 
542 	test_kvm_device();
543 	test_vcpus_then_vgic();
544 	test_vgic_then_vcpus();
545 	test_new_redist_regions();
546 	test_typer_accesses();
547 	test_last_bit_redist_regions();
548 	test_last_bit_single_rdist();
549 
550 	return 0;
551 }
552