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