tools/testing/selftests/kvm/x86/svm_lbr_nested_state.c
Source file repositories/reference/linux-study-clean/tools/testing/selftests/kvm/x86/svm_lbr_nested_state.c
File Facts
- System
- Linux kernel
- Corpus path
tools/testing/selftests/kvm/x86/svm_lbr_nested_state.c- Extension
.c- Size
- 3778 bytes
- Lines
- 146
- 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.h
Detected Declarations
struct lbr_branchfunction l2_guest_codefunction l1_guest_codefunction test_lbrv_nested_statefunction main
Annotated Snippet
struct lbr_branch {
u64 from, to;
};
volatile struct lbr_branch l2_branch;
#define RECORD_AND_CHECK_BRANCH(b) \
do { \
wrmsr(MSR_IA32_DEBUGCTLMSR, DEBUGCTLMSR_LBR); \
DO_BRANCH(); \
(b)->from = rdmsr(MSR_IA32_LASTBRANCHFROMIP); \
(b)->to = rdmsr(MSR_IA32_LASTBRANCHTOIP); \
/* Disable LBR right after to avoid overriding the IPs */ \
wrmsr(MSR_IA32_DEBUGCTLMSR, 0); \
\
GUEST_ASSERT_NE((b)->from, 0); \
GUEST_ASSERT_NE((b)->to, 0); \
} while (0)
#define CHECK_BRANCH_MSRS(b) \
do { \
GUEST_ASSERT_EQ((b)->from, rdmsr(MSR_IA32_LASTBRANCHFROMIP)); \
GUEST_ASSERT_EQ((b)->to, rdmsr(MSR_IA32_LASTBRANCHTOIP)); \
} while (0)
#define CHECK_BRANCH_VMCB(b, vmcb) \
do { \
GUEST_ASSERT_EQ((b)->from, vmcb->save.br_from); \
GUEST_ASSERT_EQ((b)->to, vmcb->save.br_to); \
} while (0)
static void l2_guest_code(struct svm_test_data *svm)
{
/* Record a branch, trigger save/restore, and make sure LBRs are intact */
RECORD_AND_CHECK_BRANCH(&l2_branch);
GUEST_SYNC(true);
CHECK_BRANCH_MSRS(&l2_branch);
vmmcall();
}
static void l1_guest_code(struct svm_test_data *svm, bool nested_lbrv)
{
unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];
struct vmcb *vmcb = svm->vmcb;
struct lbr_branch l1_branch;
/* Record a branch, trigger save/restore, and make sure LBRs are intact */
RECORD_AND_CHECK_BRANCH(&l1_branch);
GUEST_SYNC(true);
CHECK_BRANCH_MSRS(&l1_branch);
/* Run L2, which will also do the same */
generic_svm_setup(svm, l2_guest_code,
&l2_guest_stack[L2_GUEST_STACK_SIZE]);
if (nested_lbrv)
vmcb->control.misc_ctl2 = SVM_MISC2_ENABLE_V_LBR;
else
vmcb->control.misc_ctl2 &= ~SVM_MISC2_ENABLE_V_LBR;
run_guest(vmcb, svm->vmcb_gpa);
GUEST_ASSERT(svm->vmcb->control.exit_code == SVM_EXIT_VMMCALL);
/* Trigger save/restore one more time before checking, just for kicks */
GUEST_SYNC(true);
/*
* If LBR_CTL_ENABLE is set, L1 and L2 should have separate LBR MSRs, so
* expect L1's LBRs to remain intact and L2 LBRs to be in the VMCB.
* Otherwise, the MSRs are shared between L1 & L2 so expect L2's LBRs.
*/
if (nested_lbrv) {
CHECK_BRANCH_MSRS(&l1_branch);
CHECK_BRANCH_VMCB(&l2_branch, vmcb);
} else {
CHECK_BRANCH_MSRS(&l2_branch);
}
GUEST_DONE();
}
void test_lbrv_nested_state(bool nested_lbrv)
{
struct kvm_x86_state *state = NULL;
struct kvm_vcpu *vcpu;
struct kvm_vm *vm;
struct ucall uc;
gva_t svm_gva;
pr_info("Testing with nested LBRV %s\n", nested_lbrv ? "enabled" : "disabled");
Annotation
- Immediate include surface: `test_util.h`, `kvm_util.h`, `processor.h`, `svm_util.h`.
- Detected declarations: `struct lbr_branch`, `function l2_guest_code`, `function l1_guest_code`, `function test_lbrv_nested_state`, `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.