tools/testing/selftests/kvm/x86/svm_int_ctl_test.c
Source file repositories/reference/linux-study-clean/tools/testing/selftests/kvm/x86/svm_int_ctl_test.c
File Facts
- System
- Linux kernel
- Corpus path
tools/testing/selftests/kvm/x86/svm_int_ctl_test.c- Extension
.c- Size
- 2685 bytes
- Lines
- 116
- 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
test_util.hkvm_util.hprocessor.hsvm_util.hapic.h
Detected Declarations
function vintr_irq_handlerfunction intr_irq_handlerfunction l2_guest_codefunction l1_guest_codefunction main
Annotated Snippet
// SPDX-License-Identifier: GPL-2.0-only
/*
* svm_int_ctl_test
*
* Copyright (C) 2021, Red Hat, Inc.
*
* Nested SVM testing: test simultaneous use of V_IRQ from L1 and L0.
*/
#include "test_util.h"
#include "kvm_util.h"
#include "processor.h"
#include "svm_util.h"
#include "apic.h"
bool vintr_irq_called;
bool intr_irq_called;
#define VINTR_IRQ_NUMBER 0x20
#define INTR_IRQ_NUMBER 0x30
static void vintr_irq_handler(struct ex_regs *regs)
{
vintr_irq_called = true;
}
static void intr_irq_handler(struct ex_regs *regs)
{
x2apic_write_reg(APIC_EOI, 0x00);
intr_irq_called = true;
}
static void l2_guest_code(struct svm_test_data *svm)
{
/* This code raises interrupt INTR_IRQ_NUMBER in the L1's LAPIC,
* and since L1 didn't enable virtual interrupt masking,
* L2 should receive it and not L1.
*
* L2 also has virtual interrupt 'VINTR_IRQ_NUMBER' pending in V_IRQ
* so it should also receive it after the following 'sti'.
*/
x2apic_write_reg(APIC_ICR,
APIC_DEST_SELF | APIC_INT_ASSERT | INTR_IRQ_NUMBER);
sti_nop();
GUEST_ASSERT(vintr_irq_called);
GUEST_ASSERT(intr_irq_called);
__asm__ __volatile__(
"vmcall\n"
);
}
static void l1_guest_code(struct svm_test_data *svm)
{
#define L2_GUEST_STACK_SIZE 64
unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];
struct vmcb *vmcb = svm->vmcb;
x2apic_enable();
/* Prepare for L2 execution. */
generic_svm_setup(svm, l2_guest_code,
&l2_guest_stack[L2_GUEST_STACK_SIZE]);
/* No virtual interrupt masking */
vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK;
/* No intercepts for real and virtual interrupts */
vmcb->control.intercept &= ~(BIT(INTERCEPT_INTR) | BIT(INTERCEPT_VINTR));
/* Make a virtual interrupt VINTR_IRQ_NUMBER pending */
vmcb->control.int_ctl |= V_IRQ_MASK | (0x1 << V_INTR_PRIO_SHIFT);
vmcb->control.int_vector = VINTR_IRQ_NUMBER;
run_guest(vmcb, svm->vmcb_gpa);
GUEST_ASSERT(vmcb->control.exit_code == SVM_EXIT_VMMCALL);
GUEST_DONE();
}
int main(int argc, char *argv[])
{
struct kvm_vcpu *vcpu;
gva_t svm_gva;
struct kvm_vm *vm;
struct ucall uc;
TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SVM));
Annotation
- Immediate include surface: `test_util.h`, `kvm_util.h`, `processor.h`, `svm_util.h`, `apic.h`.
- Detected declarations: `function vintr_irq_handler`, `function intr_irq_handler`, `function l2_guest_code`, `function l1_guest_code`, `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.