tools/testing/selftests/kvm/x86/fix_hypercall_test.c
Source file repositories/reference/linux-study-clean/tools/testing/selftests/kvm/x86/fix_hypercall_test.c
File Facts
- System
- Linux kernel
- Corpus path
tools/testing/selftests/kvm/x86/fix_hypercall_test.c- Extension
.c- Size
- 3395 bytes
- Lines
- 143
- 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
asm/kvm_para.hlinux/kvm_para.hlinux/stringify.hstdint.hkvm_test_harness.hapic.htest_util.hkvm_util.hprocessor.h
Detected Declarations
function guest_ud_handlerfunction do_sched_yieldfunction guest_mainfunction enter_guestfunction test_fix_hypercallfunction main
Annotated Snippet
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2020, Google LLC.
*
* Tests for KVM paravirtual feature disablement
*/
#include <asm/kvm_para.h>
#include <linux/kvm_para.h>
#include <linux/stringify.h>
#include <stdint.h>
#include "kvm_test_harness.h"
#include "apic.h"
#include "test_util.h"
#include "kvm_util.h"
#include "processor.h"
/* VMCALL and VMMCALL are both 3-byte opcodes. */
#define HYPERCALL_INSN_SIZE 3
static bool quirk_disabled;
static void guest_ud_handler(struct ex_regs *regs)
{
regs->rax = -EFAULT;
regs->rip += HYPERCALL_INSN_SIZE;
}
static const u8 vmx_vmcall[HYPERCALL_INSN_SIZE] = { 0x0f, 0x01, 0xc1 };
static const u8 svm_vmmcall[HYPERCALL_INSN_SIZE] = { 0x0f, 0x01, 0xd9 };
extern u8 hypercall_insn[HYPERCALL_INSN_SIZE];
static u64 do_sched_yield(u8 apic_id)
{
u64 ret;
asm volatile("hypercall_insn:\n\t"
".byte 0xcc,0xcc,0xcc\n\t"
: "=a"(ret)
: "a"((u64)KVM_HC_SCHED_YIELD), "b"((u64)apic_id)
: "memory");
return ret;
}
static void guest_main(void)
{
const u8 *native_hypercall_insn;
const u8 *other_hypercall_insn;
u64 ret;
if (host_cpu_is_intel) {
native_hypercall_insn = vmx_vmcall;
other_hypercall_insn = svm_vmmcall;
} else if (host_cpu_is_amd_compatible) {
native_hypercall_insn = svm_vmmcall;
other_hypercall_insn = vmx_vmcall;
} else {
GUEST_ASSERT(0);
/* unreachable */
return;
}
memcpy(hypercall_insn, other_hypercall_insn, HYPERCALL_INSN_SIZE);
ret = do_sched_yield(GET_APIC_ID_FIELD(xapic_read_reg(APIC_ID)));
/*
* If the quirk is disabled, verify that guest_ud_handler() "returned"
* -EFAULT and that KVM did NOT patch the hypercall. If the quirk is
* enabled, verify that the hypercall succeeded and that KVM patched in
* the "right" hypercall.
*/
if (quirk_disabled) {
GUEST_ASSERT(ret == (u64)-EFAULT);
GUEST_ASSERT(!memcmp(other_hypercall_insn, hypercall_insn,
HYPERCALL_INSN_SIZE));
} else {
GUEST_ASSERT(!ret);
GUEST_ASSERT(!memcmp(native_hypercall_insn, hypercall_insn,
HYPERCALL_INSN_SIZE));
}
GUEST_DONE();
}
KVM_ONE_VCPU_TEST_SUITE(fix_hypercall);
static void enter_guest(struct kvm_vcpu *vcpu)
{
Annotation
- Immediate include surface: `asm/kvm_para.h`, `linux/kvm_para.h`, `linux/stringify.h`, `stdint.h`, `kvm_test_harness.h`, `apic.h`, `test_util.h`, `kvm_util.h`.
- Detected declarations: `function guest_ud_handler`, `function do_sched_yield`, `function guest_main`, `function enter_guest`, `function test_fix_hypercall`, `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.