tools/testing/selftests/kvm/lib/x86/memstress.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/kvm/lib/x86/memstress.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/kvm/lib/x86/memstress.c
Extension
.c
Size
3149 bytes
Lines
130
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.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0
/*
 * x86-specific extensions to memstress.c.
 *
 * Copyright (C) 2022, Google, Inc.
 */
#include <stdio.h>
#include <stdlib.h>
#include <linux/bitmap.h>
#include <linux/bitops.h>

#include "test_util.h"
#include "kvm_util.h"
#include "memstress.h"
#include "processor.h"
#include "svm_util.h"
#include "vmx.h"

void memstress_l2_guest_code(u64 vcpu_id)
{
	memstress_guest_code(vcpu_id);
	vmcall();
}

extern char memstress_l2_guest_entry[];
__asm__(
"memstress_l2_guest_entry:"
"	mov (%rsp), %rdi;"
"	call memstress_l2_guest_code;"
"	ud2;"
);

#define L2_GUEST_STACK_SIZE 64

static void l1_vmx_code(struct vmx_pages *vmx, u64 vcpu_id)
{
	unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];
	unsigned long *rsp;

	GUEST_ASSERT(vmx->vmcs_gpa);
	GUEST_ASSERT(prepare_for_vmx_operation(vmx));
	GUEST_ASSERT(load_vmcs(vmx));
	GUEST_ASSERT(ept_1g_pages_supported());

	rsp = &l2_guest_stack[L2_GUEST_STACK_SIZE - 1];
	*rsp = vcpu_id;
	prepare_vmcs(vmx, memstress_l2_guest_entry, rsp);

	GUEST_ASSERT(!vmlaunch());
	GUEST_ASSERT_EQ(vmreadz(VM_EXIT_REASON), EXIT_REASON_VMCALL);
	GUEST_DONE();
}

static void l1_svm_code(struct svm_test_data *svm, u64 vcpu_id)
{
	unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];
	unsigned long *rsp;


	rsp = &l2_guest_stack[L2_GUEST_STACK_SIZE - 1];
	*rsp = vcpu_id;
	generic_svm_setup(svm, memstress_l2_guest_entry, rsp);

	run_guest(svm->vmcb, svm->vmcb_gpa);
	GUEST_ASSERT_EQ(svm->vmcb->control.exit_code, SVM_EXIT_VMMCALL);
	GUEST_DONE();
}


static void memstress_l1_guest_code(void *data, u64 vcpu_id)
{
	if (this_cpu_has(X86_FEATURE_VMX))
		l1_vmx_code(data, vcpu_id);
	else
		l1_svm_code(data, vcpu_id);
}

u64 memstress_nested_pages(int nr_vcpus)
{
	/*
	 * 513 page tables is enough to identity-map 256 TiB of L2 with 1G
	 * pages and 4-level paging, plus a few pages per-vCPU for data
	 * structures such as the VMCS.
	 */
	return 513 + 10 * nr_vcpus;
}

static void memstress_setup_ept_mappings(struct kvm_vm *vm)
{
	u64 start, end;

Annotation

Implementation Notes