tools/testing/selftests/kvm/irqfd_test.c
Source file repositories/reference/linux-study-clean/tools/testing/selftests/kvm/irqfd_test.c
File Facts
- System
- Linux kernel
- Corpus path
tools/testing/selftests/kvm/irqfd_test.c- Extension
.c- Size
- 4446 bytes
- Lines
- 144
- Domain
- Support Tooling And Documentation
- Bucket
- tools
- Inferred role
- Support Tooling And Documentation: implementation source
- Status
- source implementation candidate
Why This File Exists
Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
errno.hpthread.hstdio.hstdlib.hstring.hsignal.hstdint.hsys/sysinfo.hkvm_util.h
Detected Declarations
function assigningfunction juggle_eventfd_primaryfunction main
Annotated Snippet
// SPDX-License-Identifier: GPL-2.0-only
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <stdint.h>
#include <sys/sysinfo.h>
#include "kvm_util.h"
static struct kvm_vm *vm1;
static struct kvm_vm *vm2;
static int __eventfd;
static bool done;
/*
* 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
static void 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");
}
}
static void *secondary_irqfd_juggler(void *ign)
{
while (!READ_ONCE(done)) {
juggle_eventfd_secondary(vm1, READ_ONCE(__eventfd));
juggle_eventfd_secondary(vm2, READ_ONCE(__eventfd));
}
return NULL;
}
static void 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);
r2 = __kvm_irqfd(vm, GSI_BASE_PRIMARY + 1, eventfd, 0);
TEST_ASSERT(r1 || (r2 && errno == EBUSY),
"Wanted failure (EBUSY), r1 = %d, r2 = %d, errno = %d",
r1, r2, errno);
/*
* De-assign should always succeed, even if the corresponding assign
* failed.
*/
kvm_irqfd(vm, GSI_BASE_PRIMARY, eventfd, KVM_IRQFD_FLAG_DEASSIGN);
kvm_irqfd(vm, GSI_BASE_PRIMARY + 1, eventfd, KVM_IRQFD_FLAG_DEASSIGN);
}
int main(int argc, char *argv[])
{
Annotation
- Immediate include surface: `errno.h`, `pthread.h`, `stdio.h`, `stdlib.h`, `string.h`, `signal.h`, `stdint.h`, `sys/sysinfo.h`.
- Detected declarations: `function assigning`, `function juggle_eventfd_primary`, `function main`.
- Atlas domain: Support Tooling And Documentation / tools.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.