brintos

brintos / linux-shallow public Read only

0
0
Text · 1.5 KiB · 624dc72 Raw
86 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * CR4 and CPUID sync test4 *5 * Copyright 2018, Red Hat, Inc. and/or its affiliates.6 *7 * Author:8 *   Wei Huang <wei@redhat.com>9 */10 11#include <fcntl.h>12#include <stdio.h>13#include <stdlib.h>14#include <string.h>15#include <sys/ioctl.h>16 17#include "test_util.h"18 19#include "kvm_util.h"20#include "processor.h"21 22static inline bool cr4_cpuid_is_sync(void)23{24	uint64_t cr4 = get_cr4();25 26	return (this_cpu_has(X86_FEATURE_OSXSAVE) == !!(cr4 & X86_CR4_OSXSAVE));27}28 29static void guest_code(void)30{31	uint64_t cr4;32 33	/* turn on CR4.OSXSAVE */34	cr4 = get_cr4();35	cr4 |= X86_CR4_OSXSAVE;36	set_cr4(cr4);37 38	/* verify CR4.OSXSAVE == CPUID.OSXSAVE */39	GUEST_ASSERT(cr4_cpuid_is_sync());40 41	/* notify hypervisor to change CR4 */42	GUEST_SYNC(0);43 44	/* check again */45	GUEST_ASSERT(cr4_cpuid_is_sync());46 47	GUEST_DONE();48}49 50int main(int argc, char *argv[])51{52	struct kvm_vcpu *vcpu;53	struct kvm_vm *vm;54	struct kvm_sregs sregs;55	struct ucall uc;56 57	TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_XSAVE));58 59	vm = vm_create_with_one_vcpu(&vcpu, guest_code);60 61	while (1) {62		vcpu_run(vcpu);63		TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);64 65		switch (get_ucall(vcpu, &uc)) {66		case UCALL_SYNC:67			/* emulate hypervisor clearing CR4.OSXSAVE */68			vcpu_sregs_get(vcpu, &sregs);69			sregs.cr4 &= ~X86_CR4_OSXSAVE;70			vcpu_sregs_set(vcpu, &sregs);71			break;72		case UCALL_ABORT:73			REPORT_GUEST_ASSERT(uc);74			break;75		case UCALL_DONE:76			goto done;77		default:78			TEST_FAIL("Unknown ucall %lu", uc.cmd);79		}80	}81 82done:83	kvm_vm_free(vm);84	return 0;85}86