Merge tag 'io_uring-5.15-2021-09-11' of git://git.kernel.dk/linux-block
[linux-2.6-microblaze.git] / tools / testing / selftests / kvm / aarch64 / vgic_init.c
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 */
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 */
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 */
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
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
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  */
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 */
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  */
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 */
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
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
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  */
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 */
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
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
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 }