linux/tools/testing/selftests/kvm/aarch64/vgic_init.c
<<
>>
Prefs
   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
  25struct vm_gic {
  26        struct kvm_vm *vm;
  27        int gic_fd;
  28};
  29
  30static int max_ipa_bits;
  31
  32/* helper to access a redistributor register */
  33static 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 */
  43static 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 */
  52static 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
  61static 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
  71static 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 */
  83static 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 */
 148static 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 */
 252static 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 */
 273static 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
 288static 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
 341static 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 */
 420static 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 */
 469static 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
 506void 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
 538int 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