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