/* * KVM de-assigns based on eventfd *and* GSI, but requires unique eventfds when * assigning (the API isn't symmetrical). Abuse the oddity and use a per-task * GSI base to avoid false failures due to cross-task de-assign, i.e. so that * the secondary doesn't de-assign the primary's eventfd and cause assign to * unexpectedly succeed on the primary.
*/ #define GSI_BASE_PRIMARY 0x20 #define GSI_BASE_SECONDARY 0x30
staticvoid juggle_eventfd_secondary(struct kvm_vm *vm, int eventfd)
{ int r, i;
/* * The secondary task can encounter EBADF since the primary can close * the eventfd at any time. And because the primary can recreate the * eventfd, at the safe fd in the file table, the secondary can also * encounter "unexpected" success, e.g. if the close+recreate happens * between the first and second assignments. The secondary's role is * mostly to antagonize KVM, not to detect bugs.
*/ for (i = 0; i < 2; i++) {
r = __kvm_irqfd(vm, GSI_BASE_SECONDARY, eventfd, 0);
TEST_ASSERT(!r || errno == EBUSY || errno == EBADF, "Wanted success, EBUSY, or EBADF, r = %d, errno = %d",
r, errno);
/* De-assign should succeed unless the eventfd was closed. */
r = __kvm_irqfd(vm, GSI_BASE_SECONDARY + i, eventfd, KVM_IRQFD_FLAG_DEASSIGN);
TEST_ASSERT(!r || errno == EBADF, "De-assign should succeed unless the fd was closed");
}
}
staticvoid juggle_eventfd_primary(struct kvm_vm *vm, int eventfd)
{ int r1, r2;
/* * At least one of the assigns should fail. KVM disallows assigning a * single eventfd to multiple GSIs (or VMs), so it's possible that both * assignments can fail, too.
*/
r1 = __kvm_irqfd(vm, GSI_BASE_PRIMARY, eventfd, 0);
TEST_ASSERT(!r1 || errno == EBUSY, "Wanted success or EBUSY, r = %d, errno = %d", r1, errno);
/* * De-assign all eventfds, along with multiple eventfds that were never * assigned. KVM's ABI is that de-assign is allowed so long as the * eventfd itself is valid.
*/
kvm_irqfd(vm1, 11, READ_ONCE(__eventfd), KVM_IRQFD_FLAG_DEASSIGN);
kvm_irqfd(vm1, 12, READ_ONCE(__eventfd), KVM_IRQFD_FLAG_DEASSIGN);
kvm_irqfd(vm1, 13, READ_ONCE(__eventfd), KVM_IRQFD_FLAG_DEASSIGN);
kvm_irqfd(vm1, 14, READ_ONCE(__eventfd), KVM_IRQFD_FLAG_DEASSIGN);
kvm_irqfd(vm1, 10, READ_ONCE(__eventfd), KVM_IRQFD_FLAG_DEASSIGN);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.