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