File Index
Files and directories
Sign in
FILE

nested_close_kvm_test.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/kvm/x86/nested_close_kvm_test.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright (C) 2019, Red Hat, Inc.
  4 *
  5 * Verify that nothing bad happens if a KVM user exits with open
  6 * file descriptors while executing a nested guest.
  7 */
  8
  9#include "test_util.h"
 10#include "kvm_util.h"
 11#include "processor.h"
 12#include "vmx.h"
 13#include "svm_util.h"
 14
 15#include <string.h>
 16#include <sys/ioctl.h>
 17
 18#include "kselftest.h"
 19
 20enum {
 21	PORT_L0_EXIT = 0x2000,
 22};
 23
 24#define L2_GUEST_STACK_SIZE 64
 25
 26static void l2_guest_code(void)
 27{
 28	/* Exit to L0 */
 29	asm volatile("inb %%dx, %%al"
 30		     : : [port] "d" (PORT_L0_EXIT) : "rax");
 31}
 32
 33static void l1_vmx_code(struct vmx_pages *vmx_pages)
 34{
 35	unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];
 36
 37	GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages));
 38	GUEST_ASSERT(load_vmcs(vmx_pages));
 39
 40	/* Prepare the VMCS for L2 execution. */
 41	prepare_vmcs(vmx_pages, l2_guest_code,
 42		     &l2_guest_stack[L2_GUEST_STACK_SIZE]);
 43
 44	GUEST_ASSERT(!vmlaunch());
 45	GUEST_ASSERT(0);
 46}
 47
 48static void l1_svm_code(struct svm_test_data *svm)
 49{
 50	unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];
 51
 52	/* Prepare the VMCB for L2 execution. */
 53	generic_svm_setup(svm, l2_guest_code,
 54			  &l2_guest_stack[L2_GUEST_STACK_SIZE]);
 55
 56	run_guest(svm->vmcb, svm->vmcb_gpa);
 57	GUEST_ASSERT(0);
 58}
 59
 60static void l1_guest_code(void *data)
 61{
 62	if (this_cpu_has(X86_FEATURE_VMX))
 63		l1_vmx_code(data);
 64	else
 65		l1_svm_code(data);
 66}
 67
 68int main(int argc, char *argv[])
 69{
 70	vm_vaddr_t guest_gva;
 71	struct kvm_vcpu *vcpu;
 72	struct kvm_vm *vm;
 73
 74	TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX) ||
 75		     kvm_cpu_has(X86_FEATURE_SVM));
 76
 77	vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code);
 78
 79	if (kvm_cpu_has(X86_FEATURE_VMX))
 80		vcpu_alloc_vmx(vm, &guest_gva);
 81	else
 82		vcpu_alloc_svm(vm, &guest_gva);
 83
 84	vcpu_args_set(vcpu, 1, guest_gva);
 85
 86	for (;;) {
 87		volatile struct kvm_run *run = vcpu->run;
 88		struct ucall uc;
 89
 90		vcpu_run(vcpu);
 91		TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
 92
 93		if (run->io.port == PORT_L0_EXIT)
 94			break;
 95
 96		switch (get_ucall(vcpu, &uc)) {
 97		case UCALL_ABORT:
 98			REPORT_GUEST_ASSERT(uc);
 99			/* NOT REACHED */
100		default:
101			TEST_FAIL("Unknown ucall %lu", uc.cmd);
102		}
103	}
104}
~/ Read-only file preview.