tools/testing/selftests/kvm/coalesced_io_test.c
Source file repositories/reference/linux-study-clean/tools/testing/selftests/kvm/coalesced_io_test.c
File Facts
- System
- Linux kernel
- Corpus path
tools/testing/selftests/kvm/coalesced_io_test.c- Extension
.c- Size
- 7253 bytes
- Lines
- 237
- 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
signal.hstdio.hstdlib.hstring.hsys/ioctl.hlinux/sizes.hkvm_util.hprocessor.hucall_common.h
Detected Declarations
struct kvm_coalesced_iofunction guest_codefunction vcpu_run_and_verify_io_exitfunction vcpu_run_and_verify_coalesced_iofunction test_coalesced_iofunction main
Annotated Snippet
struct kvm_coalesced_io {
struct kvm_coalesced_mmio_ring *ring;
u32 ring_size;
u64 mmio_gpa;
u64 *mmio;
/*
* x86-only, but define pio_port for all architectures to minimize the
* amount of #ifdeffery and complexity, without having to sacrifice
* verbose error messages.
*/
u8 pio_port;
};
static struct kvm_coalesced_io kvm_builtin_io_ring;
#ifdef __x86_64__
static const int has_pio = 1;
#else
static const int has_pio = 0;
#endif
static void guest_code(struct kvm_coalesced_io *io)
{
int i, j;
for (;;) {
for (j = 0; j < 1 + has_pio; j++) {
/*
* KVM always leaves one free entry, i.e. exits to
* userspace before the last entry is filled.
*/
for (i = 0; i < io->ring_size - 1; i++) {
#ifdef __x86_64__
if (i & 1)
outl(io->pio_port, io->pio_port + i);
else
#endif
WRITE_ONCE(*io->mmio, io->mmio_gpa + i);
}
#ifdef __x86_64__
if (j & 1)
outl(io->pio_port, io->pio_port + i);
else
#endif
WRITE_ONCE(*io->mmio, io->mmio_gpa + i);
}
GUEST_SYNC(0);
WRITE_ONCE(*io->mmio, io->mmio_gpa + i);
#ifdef __x86_64__
outl(io->pio_port, io->pio_port + i);
#endif
}
}
static void vcpu_run_and_verify_io_exit(struct kvm_vcpu *vcpu,
struct kvm_coalesced_io *io,
u32 ring_start,
u32 expected_exit)
{
const bool want_pio = expected_exit == KVM_EXIT_IO;
struct kvm_coalesced_mmio_ring *ring = io->ring;
struct kvm_run *run = vcpu->run;
u32 pio_value;
WRITE_ONCE(ring->first, ring_start);
WRITE_ONCE(ring->last, ring_start);
vcpu_run(vcpu);
/*
* Annoyingly, reading PIO data is safe only for PIO exits, otherwise
* data_offset is garbage, e.g. an MMIO gpa.
*/
if (run->exit_reason == KVM_EXIT_IO)
pio_value = *(u32 *)((void *)run + run->io.data_offset);
else
pio_value = 0;
TEST_ASSERT((!want_pio && (run->exit_reason == KVM_EXIT_MMIO && run->mmio.is_write &&
run->mmio.phys_addr == io->mmio_gpa && run->mmio.len == 8 &&
*(u64 *)run->mmio.data == io->mmio_gpa + io->ring_size - 1)) ||
(want_pio && (run->exit_reason == KVM_EXIT_IO && run->io.port == io->pio_port &&
run->io.direction == KVM_EXIT_IO_OUT && run->io.count == 1 &&
pio_value == io->pio_port + io->ring_size - 1)),
"For start = %u, expected exit on %u-byte %s write 0x%llx = %lx, got exit_reason = %u (%s)\n "
"(MMIO addr = 0x%llx, write = %u, len = %u, data = %lx)\n "
"(PIO port = 0x%x, write = %u, len = %u, count = %u, data = %x",
ring_start, want_pio ? 4 : 8, want_pio ? "PIO" : "MMIO",
Annotation
- Immediate include surface: `signal.h`, `stdio.h`, `stdlib.h`, `string.h`, `sys/ioctl.h`, `linux/sizes.h`, `kvm_util.h`, `processor.h`.
- Detected declarations: `struct kvm_coalesced_io`, `function guest_code`, `function vcpu_run_and_verify_io_exit`, `function vcpu_run_and_verify_coalesced_io`, `function test_coalesced_io`, `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.