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