/* * Copyright (C) 2006, Intel Corp * Copyright (C) 2007, AMD Inc * * This file is part of the Linux-ready Firmware Developer Kit * * This program file is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation;version 2.1 of the License. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program in a file named COPYING; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */ /* * This test checks if the SVM-setup is done correctly by the BIOS */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "virt.h" static unsigned long long readmsr(int cpu, unsigned long offset) { char buffer[PATH_MAX]; FILE *file; int fd; unsigned long long msr_value=0xffffffff; unsigned char *msr_value_buf; int ret; msr_value_buf = (unsigned char *)&msr_value; sprintf(buffer, "/dev/cpu/%i/msr", cpu); file = fopen(buffer, "r"); if (!file) { printf("Error: fopen failed \n"); return -1; } fd = fileno(file); ret = pread(fd, msr_value_buf, 8, offset); fclose(file); if (ret<0) { printf("Error: pread failed %d\n, errno=%d", ret, errno); return -2; } return msr_value; } static int cpu_has_svm(void) { char line[4096]; int hasit = 0; int family = 0xF; char *ptr; FILE *file; file = fopen("/proc/cpuinfo", "r"); if (!file) return 0; while (!feof(file)) { memset(line, 0, 4096); fgets(line, 4095, file); if (strstr(line,"flags") && strstr(line," svm")) hasit = 1; } fclose(file); return hasit; } #define CPUID_FAM_REV 0x1 static int can_lock_with_msr(void) { int family = 0xF; cpu_registers regs; exec_cpuid(CURRENT_CPU, CPUID_FAM_REV, ®s); family = (regs.eax>>8 & 0xF) + (regs.eax>>20 & 0xFF); return (family & 0x10); } #define MSR_FEATURE_CONTROL 0xC0000080 static int vt_locked_by_bios(void) { uint64_t msr; if (!can_lock_with_msr()) return 0; msr = readmsr(0, MSR_FEATURE_CONTROL); return (msr & 0x1000) == 1; /* SVM capable but locked by bios*/ } int do_virt_check_svm() { FILE *file; start_test("virt", "SVM Virtualization extensions", "This test checks if SVM is set up correctly"); if (!cpu_has_svm()) report_result("virt", INFO, "Processor does not support Virtualization extensions", NULL, NULL); else if (vt_locked_by_bios()) report_result("virt", FAIL, "Virtualization extensions supported but disabled by BIOS", NULL, NULL); finish_test("virt"); return EXIT_SUCCESS; }