tools/testing/selftests/kvm/x86/hyperv_ipi.c
Source file repositories/reference/linux-study-clean/tools/testing/selftests/kvm/x86/hyperv_ipi.c
File Facts
- System
- Linux kernel
- Corpus path
tools/testing/selftests/kvm/x86/hyperv_ipi.c- Extension
.c- Size
- 9338 bytes
- Lines
- 311
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
pthread.hinttypes.hkvm_util.hhyperv.htest_util.hvmx.h
Detected Declarations
struct hv_vpsetstruct hv_send_ipistruct hv_send_ipi_exenum HV_GENERIC_SET_FORMATfunction hv_initfunction receiver_codefunction guest_ipi_handlerfunction nop_loopfunction sender_guest_codefunction cancel_join_vcpu_threadfunction main
Annotated Snippet
struct hv_vpset {
u64 format;
u64 valid_bank_mask;
u64 bank_contents[2];
};
enum HV_GENERIC_SET_FORMAT {
HV_GENERIC_SET_SPARSE_4K,
HV_GENERIC_SET_ALL,
};
/* HvCallSendSyntheticClusterIpi hypercall */
struct hv_send_ipi {
u32 vector;
u32 reserved;
u64 cpu_mask;
};
/* HvCallSendSyntheticClusterIpiEx hypercall */
struct hv_send_ipi_ex {
u32 vector;
u32 reserved;
struct hv_vpset vp_set;
};
static inline void hv_init(gpa_t pgs_gpa)
{
wrmsr(HV_X64_MSR_GUEST_OS_ID, HYPERV_LINUX_OS_ID);
wrmsr(HV_X64_MSR_HYPERCALL, pgs_gpa);
}
static void receiver_code(void *hcall_page, gpa_t pgs_gpa)
{
u32 vcpu_id;
x2apic_enable();
hv_init(pgs_gpa);
vcpu_id = rdmsr(HV_X64_MSR_VP_INDEX);
/* Signal sender vCPU we're ready */
ipis_rcvd[vcpu_id] = (u64)-1;
for (;;) {
safe_halt();
cli();
}
}
static void guest_ipi_handler(struct ex_regs *regs)
{
u32 vcpu_id = rdmsr(HV_X64_MSR_VP_INDEX);
ipis_rcvd[vcpu_id]++;
wrmsr(HV_X64_MSR_EOI, 1);
}
static inline void nop_loop(void)
{
int i;
for (i = 0; i < 100000000; i++)
asm volatile("nop");
}
static void sender_guest_code(void *hcall_page, gpa_t pgs_gpa)
{
struct hv_send_ipi *ipi = (struct hv_send_ipi *)hcall_page;
struct hv_send_ipi_ex *ipi_ex = (struct hv_send_ipi_ex *)hcall_page;
int stage = 1, ipis_expected[2] = {0};
hv_init(pgs_gpa);
GUEST_SYNC(stage++);
/* Wait for receiver vCPUs to come up */
while (!ipis_rcvd[RECEIVER_VCPU_ID_1] || !ipis_rcvd[RECEIVER_VCPU_ID_2])
nop_loop();
ipis_rcvd[RECEIVER_VCPU_ID_1] = ipis_rcvd[RECEIVER_VCPU_ID_2] = 0;
/* 'Slow' HvCallSendSyntheticClusterIpi to RECEIVER_VCPU_ID_1 */
ipi->vector = IPI_VECTOR;
ipi->cpu_mask = 1 << RECEIVER_VCPU_ID_1;
hyperv_hypercall(HVCALL_SEND_IPI, pgs_gpa, pgs_gpa + PAGE_SIZE);
nop_loop();
GUEST_ASSERT(ipis_rcvd[RECEIVER_VCPU_ID_1] == ++ipis_expected[0]);
GUEST_ASSERT(ipis_rcvd[RECEIVER_VCPU_ID_2] == ipis_expected[1]);
GUEST_SYNC(stage++);
/* 'Fast' HvCallSendSyntheticClusterIpi to RECEIVER_VCPU_ID_1 */
hyperv_hypercall(HVCALL_SEND_IPI | HV_HYPERCALL_FAST_BIT,
IPI_VECTOR, 1 << RECEIVER_VCPU_ID_1);
Annotation
- Immediate include surface: `pthread.h`, `inttypes.h`, `kvm_util.h`, `hyperv.h`, `test_util.h`, `vmx.h`.
- Detected declarations: `struct hv_vpset`, `struct hv_send_ipi`, `struct hv_send_ipi_ex`, `enum HV_GENERIC_SET_FORMAT`, `function hv_init`, `function receiver_code`, `function guest_ipi_handler`, `function nop_loop`, `function sender_guest_code`, `function cancel_join_vcpu_thread`.
- 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.