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