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