irqfd_test.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. #include <errno.h>
  3. #include <pthread.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <signal.h>
  8. #include <stdint.h>
  9. #include <sys/sysinfo.h>
  10. #include "kvm_util.h"
  11. static struct kvm_vm *vm1;
  12. static struct kvm_vm *vm2;
  13. static int __eventfd;
  14. static bool done;
  15. /*
  16. * KVM de-assigns based on eventfd *and* GSI, but requires unique eventfds when
  17. * assigning (the API isn't symmetrical). Abuse the oddity and use a per-task
  18. * GSI base to avoid false failures due to cross-task de-assign, i.e. so that
  19. * the secondary doesn't de-assign the primary's eventfd and cause assign to
  20. * unexpectedly succeed on the primary.
  21. */
  22. #define GSI_BASE_PRIMARY 0x20
  23. #define GSI_BASE_SECONDARY 0x30
  24. static void juggle_eventfd_secondary(struct kvm_vm *vm, int eventfd)
  25. {
  26. int r, i;
  27. /*
  28. * The secondary task can encounter EBADF since the primary can close
  29. * the eventfd at any time. And because the primary can recreate the
  30. * eventfd, at the safe fd in the file table, the secondary can also
  31. * encounter "unexpected" success, e.g. if the close+recreate happens
  32. * between the first and second assignments. The secondary's role is
  33. * mostly to antagonize KVM, not to detect bugs.
  34. */
  35. for (i = 0; i < 2; i++) {
  36. r = __kvm_irqfd(vm, GSI_BASE_SECONDARY, eventfd, 0);
  37. TEST_ASSERT(!r || errno == EBUSY || errno == EBADF,
  38. "Wanted success, EBUSY, or EBADF, r = %d, errno = %d",
  39. r, errno);
  40. /* De-assign should succeed unless the eventfd was closed. */
  41. r = __kvm_irqfd(vm, GSI_BASE_SECONDARY + i, eventfd, KVM_IRQFD_FLAG_DEASSIGN);
  42. TEST_ASSERT(!r || errno == EBADF,
  43. "De-assign should succeed unless the fd was closed");
  44. }
  45. }
  46. static void *secondary_irqfd_juggler(void *ign)
  47. {
  48. while (!READ_ONCE(done)) {
  49. juggle_eventfd_secondary(vm1, READ_ONCE(__eventfd));
  50. juggle_eventfd_secondary(vm2, READ_ONCE(__eventfd));
  51. }
  52. return NULL;
  53. }
  54. static void juggle_eventfd_primary(struct kvm_vm *vm, int eventfd)
  55. {
  56. int r1, r2;
  57. /*
  58. * At least one of the assigns should fail. KVM disallows assigning a
  59. * single eventfd to multiple GSIs (or VMs), so it's possible that both
  60. * assignments can fail, too.
  61. */
  62. r1 = __kvm_irqfd(vm, GSI_BASE_PRIMARY, eventfd, 0);
  63. TEST_ASSERT(!r1 || errno == EBUSY,
  64. "Wanted success or EBUSY, r = %d, errno = %d", r1, errno);
  65. r2 = __kvm_irqfd(vm, GSI_BASE_PRIMARY + 1, eventfd, 0);
  66. TEST_ASSERT(r1 || (r2 && errno == EBUSY),
  67. "Wanted failure (EBUSY), r1 = %d, r2 = %d, errno = %d",
  68. r1, r2, errno);
  69. /*
  70. * De-assign should always succeed, even if the corresponding assign
  71. * failed.
  72. */
  73. kvm_irqfd(vm, GSI_BASE_PRIMARY, eventfd, KVM_IRQFD_FLAG_DEASSIGN);
  74. kvm_irqfd(vm, GSI_BASE_PRIMARY + 1, eventfd, KVM_IRQFD_FLAG_DEASSIGN);
  75. }
  76. int main(int argc, char *argv[])
  77. {
  78. pthread_t racing_thread;
  79. struct kvm_vcpu *unused;
  80. int r, i;
  81. TEST_REQUIRE(kvm_arch_has_default_irqchip());
  82. /*
  83. * Create "full" VMs, as KVM_IRQFD requires an in-kernel IRQ chip. Also
  84. * create an unused vCPU as certain architectures (like arm64) need to
  85. * complete IRQ chip initialization after all possible vCPUs for a VM
  86. * have been created.
  87. */
  88. vm1 = vm_create_with_one_vcpu(&unused, NULL);
  89. vm2 = vm_create_with_one_vcpu(&unused, NULL);
  90. WRITE_ONCE(__eventfd, kvm_new_eventfd());
  91. kvm_irqfd(vm1, 10, __eventfd, 0);
  92. r = __kvm_irqfd(vm1, 11, __eventfd, 0);
  93. TEST_ASSERT(r && errno == EBUSY,
  94. "Wanted EBUSY, r = %d, errno = %d", r, errno);
  95. r = __kvm_irqfd(vm2, 12, __eventfd, 0);
  96. TEST_ASSERT(r && errno == EBUSY,
  97. "Wanted EBUSY, r = %d, errno = %d", r, errno);
  98. /*
  99. * De-assign all eventfds, along with multiple eventfds that were never
  100. * assigned. KVM's ABI is that de-assign is allowed so long as the
  101. * eventfd itself is valid.
  102. */
  103. kvm_irqfd(vm1, 11, READ_ONCE(__eventfd), KVM_IRQFD_FLAG_DEASSIGN);
  104. kvm_irqfd(vm1, 12, READ_ONCE(__eventfd), KVM_IRQFD_FLAG_DEASSIGN);
  105. kvm_irqfd(vm1, 13, READ_ONCE(__eventfd), KVM_IRQFD_FLAG_DEASSIGN);
  106. kvm_irqfd(vm1, 14, READ_ONCE(__eventfd), KVM_IRQFD_FLAG_DEASSIGN);
  107. kvm_irqfd(vm1, 10, READ_ONCE(__eventfd), KVM_IRQFD_FLAG_DEASSIGN);
  108. close(__eventfd);
  109. pthread_create(&racing_thread, NULL, secondary_irqfd_juggler, vm2);
  110. for (i = 0; i < 10000; i++) {
  111. WRITE_ONCE(__eventfd, kvm_new_eventfd());
  112. juggle_eventfd_primary(vm1, __eventfd);
  113. juggle_eventfd_primary(vm2, __eventfd);
  114. close(__eventfd);
  115. }
  116. WRITE_ONCE(done, true);
  117. pthread_join(racing_thread, NULL);
  118. }