cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

vmx_close_while_nested_test.c (1881B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * vmx_close_while_nested
      4 *
      5 * Copyright (C) 2019, Red Hat, Inc.
      6 *
      7 * Verify that nothing bad happens if a KVM user exits with open
      8 * file descriptors while executing a nested guest.
      9 */
     10
     11#include "test_util.h"
     12#include "kvm_util.h"
     13#include "processor.h"
     14#include "vmx.h"
     15
     16#include <string.h>
     17#include <sys/ioctl.h>
     18
     19#include "kselftest.h"
     20
     21#define VCPU_ID		5
     22
     23enum {
     24	PORT_L0_EXIT = 0x2000,
     25};
     26
     27/* The virtual machine object. */
     28static struct kvm_vm *vm;
     29
     30static void l2_guest_code(void)
     31{
     32	/* Exit to L0 */
     33	asm volatile("inb %%dx, %%al"
     34		     : : [port] "d" (PORT_L0_EXIT) : "rax");
     35}
     36
     37static void l1_guest_code(struct vmx_pages *vmx_pages)
     38{
     39#define L2_GUEST_STACK_SIZE 64
     40	unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];
     41
     42	GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages));
     43	GUEST_ASSERT(load_vmcs(vmx_pages));
     44
     45	/* Prepare the VMCS for L2 execution. */
     46	prepare_vmcs(vmx_pages, l2_guest_code,
     47		     &l2_guest_stack[L2_GUEST_STACK_SIZE]);
     48
     49	GUEST_ASSERT(!vmlaunch());
     50	GUEST_ASSERT(0);
     51}
     52
     53int main(int argc, char *argv[])
     54{
     55	vm_vaddr_t vmx_pages_gva;
     56
     57	nested_vmx_check_supported();
     58
     59	vm = vm_create_default(VCPU_ID, 0, (void *) l1_guest_code);
     60
     61	/* Allocate VMX pages and shared descriptors (vmx_pages). */
     62	vcpu_alloc_vmx(vm, &vmx_pages_gva);
     63	vcpu_args_set(vm, VCPU_ID, 1, vmx_pages_gva);
     64
     65	for (;;) {
     66		volatile struct kvm_run *run = vcpu_state(vm, VCPU_ID);
     67		struct ucall uc;
     68
     69		vcpu_run(vm, VCPU_ID);
     70		TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
     71			    "Got exit_reason other than KVM_EXIT_IO: %u (%s)\n",
     72			    run->exit_reason,
     73			    exit_reason_str(run->exit_reason));
     74
     75		if (run->io.port == PORT_L0_EXIT)
     76			break;
     77
     78		switch (get_ucall(vm, VCPU_ID, &uc)) {
     79		case UCALL_ABORT:
     80			TEST_FAIL("%s", (const char *)uc.args[0]);
     81			/* NOT REACHED */
     82		default:
     83			TEST_FAIL("Unknown ucall %lu", uc.cmd);
     84		}
     85	}
     86}