Lines Matching +full:num +full:- +full:irqs

1 // SPDX-License-Identifier: GPL-2.0
3 * vgic_irq.c - Test userspace injection of IRQs
5 * This test validates the injection of IRQs from userspace using various
31 uint32_t nr_irqs; /* number of KVM supported IRQs. */
40 * 0x00 (highest priority) - 0xF8 (lowest priority), in steps of 8
48 #define LOWEST_PRIO (KVM_NUM_PRIOS - 1)
50 #define IRQ_DEFAULT_PRIO (LOWEST_PRIO - 1)
74 uint32_t num; member
81 uint32_t num, int level, bool expect_failure);
87 #define _KVM_INJECT_MULTI(cmd, intid, num, expect_failure) \ argument
88 kvm_inject_call(cmd, intid, num, -1 /* not used */, expect_failure)
90 #define KVM_INJECT_MULTI(cmd, intid, num) \ argument
91 _KVM_INJECT_MULTI(cmd, intid, num, false)
132 for ((f) = (t); (f)->cmd; (f)++)
136 if ((args)->kvm_supports_irqfd || (f)->cmd != KVM_INJECT_IRQFD)
199 uint32_t num, int level, bool expect_failure) in kvm_inject_call() argument
204 .num = num, in kvm_inject_call()
242 for (i = 0; i < args->nr_irqs; i++) in reset_priorities()
264 uint32_t first_intid, uint32_t num, in guest_inject() argument
272 for (i = first_intid; i < num + first_intid; i++) in guest_inject()
273 gic_set_priority(i, (i % (KVM_NUM_PRIOS - 1)) << 3); in guest_inject()
276 KVM_INJECT_MULTI(cmd, first_intid, num); in guest_inject()
278 while (irq_handled < num) { in guest_inject()
287 GUEST_ASSERT_EQ(irq_handled, num); in guest_inject()
288 for (i = first_intid; i < num + first_intid; i++) in guest_inject()
296 * Restore the active state of multiple concurrent IRQs (given by
297 * concurrent_irqs). This does what a live-migration would do on the
298 * destination side assuming there are some active IRQs that were not
302 uint32_t first_intid, uint32_t num, in guest_restore_active() argument
309 * Set the priorities of the first (KVM_NUM_PRIOS - 1) IRQs in guest_restore_active()
312 for (i = 0, prio = (num - 1) * 8; i < num; i++, prio -= 8) { in guest_restore_active()
322 for (i = 0; i < num; i++) { in guest_restore_active()
332 /* finish handling the IRQs starting with the highest priority one. */ in guest_restore_active()
333 for (i = 0; i < num; i++) { in guest_restore_active()
334 intid = num - i - 1 + first_intid; in guest_restore_active()
336 if (args->eoi_split) in guest_restore_active()
340 for (i = 0; i < num; i++) in guest_restore_active()
349 * This function should only be used in test_inject_preemption (with IRQs
365 * Inject multiple concurrent IRQs (num IRQs starting at first_intid) and
370 uint32_t first_intid, int num, in test_inject_preemption() argument
376 /* Set the priorities of the first (KVM_NUM_PRIOS - 1) IRQs in test_inject_preemption()
379 for (i = 0, prio = (num - 1) * step; i < num; i++, prio -= step) { in test_inject_preemption()
387 for (i = 0; i < num; i++) { in test_inject_preemption()
394 if (args->level_sensitive) in test_inject_preemption()
398 /* finish handling the IRQs starting with the highest priority one. */ in test_inject_preemption()
399 for (i = 0; i < num; i++) { in test_inject_preemption()
400 intid = num - i - 1 + first_intid; in test_inject_preemption()
402 if (args->eoi_split) in test_inject_preemption()
408 for (i = 0; i < num; i++) in test_inject_preemption()
418 uint32_t nr_irqs = args->nr_irqs; in test_injection()
420 if (f->sgi) { in test_injection()
421 guest_inject(args, MIN_SGI, 1, f->cmd); in test_injection()
422 guest_inject(args, 0, 16, f->cmd); in test_injection()
425 if (f->ppi) in test_injection()
426 guest_inject(args, MIN_PPI, 1, f->cmd); in test_injection()
428 if (f->spi) { in test_injection()
429 guest_inject(args, MIN_SPI, 1, f->cmd); in test_injection()
430 guest_inject(args, nr_irqs - 1, 1, f->cmd); in test_injection()
431 guest_inject(args, MIN_SPI, nr_irqs - MIN_SPI, f->cmd); in test_injection()
438 uint32_t bad_intid[] = { args->nr_irqs, 1020, 1024, 1120, 5120, ~0U, }; in test_injection_failure()
442 test_inject_fail(args, bad_intid[i], f->cmd); in test_injection_failure()
449 * currently implement the ability to have more than the number-of-LRs in test_preemption()
450 * number of concurrently active IRQs. The number of LRs implemented is in test_preemption()
453 if (f->sgi) in test_preemption()
454 test_inject_preemption(args, MIN_SGI, 4, f->cmd); in test_preemption()
456 if (f->ppi) in test_preemption()
457 test_inject_preemption(args, MIN_PPI, 4, f->cmd); in test_preemption()
459 if (f->spi) in test_preemption()
460 test_inject_preemption(args, MIN_SPI, 4, f->cmd); in test_preemption()
465 /* Test up to 4 active IRQs. Same reason as in test_preemption. */ in test_restore_active()
466 if (f->sgi) in test_restore_active()
467 guest_restore_active(args, MIN_SGI, 4, f->cmd); in test_restore_active()
469 if (f->ppi) in test_restore_active()
470 guest_restore_active(args, MIN_PPI, 4, f->cmd); in test_restore_active()
472 if (f->spi) in test_restore_active()
473 guest_restore_active(args, MIN_SPI, 4, f->cmd); in test_restore_active()
478 uint32_t i, nr_irqs = args->nr_irqs; in guest_code()
479 bool level_sensitive = args->level_sensitive; in guest_code()
490 gic_set_eoi_split(args->eoi_split); in guest_code()
508 * Restore the active state of IRQs. This would happen when live in guest_code()
509 * migrating IRQs in the middle of being handled. in guest_code()
545 * are not level-sensitive). It only checks for intid to not in kvm_irq_set_level_info_check()
561 uint32_t intid, uint32_t num, uint32_t kvm_max_routes, in kvm_set_gsi_routing_irqchip_check() argument
568 assert(num <= kvm_max_routes && kvm_max_routes <= KVM_MAX_IRQ_ROUTES); in kvm_set_gsi_routing_irqchip_check()
571 for (i = intid; i < (uint64_t)intid + num; i++) in kvm_set_gsi_routing_irqchip_check()
572 kvm_gsi_routing_irqchip_add(routing, i - MIN_SPI, i - MIN_SPI); in kvm_set_gsi_routing_irqchip_check()
578 /* The kernel only checks e->irqchip.pin >= KVM_IRQCHIP_NUM_PINS */ in kvm_set_gsi_routing_irqchip_check()
579 if (((uint64_t)intid + num - 1 - MIN_SPI) >= KVM_IRQCHIP_NUM_PINS) in kvm_set_gsi_routing_irqchip_check()
606 uint32_t intid, uint32_t num, uint32_t kvm_max_routes, in kvm_routing_and_irqfd_check() argument
622 kvm_set_gsi_routing_irqchip_check(vm, intid, num, in kvm_routing_and_irqfd_check()
631 for (f = 0, i = intid; i < (uint64_t)intid + num; i++, f++) { in kvm_routing_and_irqfd_check()
633 TEST_ASSERT(fd[f] != -1, __KVM_SYSCALL_ERROR("eventfd()", fd[f])); in kvm_routing_and_irqfd_check()
636 for (f = 0, i = intid; i < (uint64_t)intid + num; i++, f++) { in kvm_routing_and_irqfd_check()
639 .gsi = i - MIN_SPI, in kvm_routing_and_irqfd_check()
645 for (f = 0, i = intid; i < (uint64_t)intid + num; i++, f++) { in kvm_routing_and_irqfd_check()
652 for (f = 0, i = intid; i < (uint64_t)intid + num; i++, f++) in kvm_routing_and_irqfd_check()
656 /* handles the valid case: intid=0xffffffff num=1 */
657 #define for_each_intid(first, num, tmp, i) \ argument
659 (tmp) < (uint64_t)(first) + (uint64_t)(num); \
666 kvm_inject_cmd cmd = inject_args->cmd; in run_guest_cmd()
667 uint32_t intid = inject_args->first_intid; in run_guest_cmd()
668 uint32_t num = inject_args->num; in run_guest_cmd() local
669 int level = inject_args->level; in run_guest_cmd()
670 bool expect_failure = inject_args->expect_failure; in run_guest_cmd()
671 struct kvm_vm *vm = vcpu->vm; in run_guest_cmd()
675 /* handles the valid case: intid=0xffffffff num=1 */ in run_guest_cmd()
676 assert(intid < UINT_MAX - num || num == 1); in run_guest_cmd()
680 for_each_intid(intid, num, tmp, i) in run_guest_cmd()
683 for_each_intid(intid, num, tmp, i) in run_guest_cmd()
688 for_each_intid(intid, num, tmp, i) in run_guest_cmd()
693 for_each_intid(intid, num, tmp, i) in run_guest_cmd()
698 for_each_intid(intid, num, tmp, i) in run_guest_cmd()
703 kvm_routing_and_irqfd_check(vm, intid, num, in run_guest_cmd()
704 test_args->kvm_max_routes, in run_guest_cmd()
708 for (i = intid; i < intid + num; i++) in run_guest_cmd()
713 for (i = intid; i < intid + num; i++) in run_guest_cmd()
727 kvm_args_gva = uc->args[1]; in kvm_inject_get_call()
734 printf("nr-irqs=%d level-sensitive=%d eoi-split=%d\n", in print_args()
735 args->nr_irqs, args->level_sensitive, in print_args()
736 args->eoi_split); in print_args()
771 __TEST_REQUIRE(gic_fd >= 0, "Failed to create vgic-v3, skipping"); in test_vgic()
803 "usage: %s [-n num_irqs] [-e eoi_split] [-l level_sensitive]\n", name); in help()
804 printf(" -n: specify number of IRQs to setup the vgic with. " in help()
806 printf(" -e: if 1 then EOI is split into a write to DIR on top " in help()
808 printf(" -l: specify whether the IRQs are level-sensitive (1) or not (0)."); in help()
824 while ((opt = getopt(argc, argv, "hn:e:l:")) != -1) { in main()