From patchwork Thu Nov 8 14:45:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Colin Ian King X-Patchwork-Id: 994920 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=fwts-devel-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42rR0F2vmcz9sBh; Fri, 9 Nov 2018 01:45:17 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1gKlYY-0002Cw-T9; Thu, 08 Nov 2018 14:45:14 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1gKlYX-0002CN-1P for fwts-devel@lists.ubuntu.com; Thu, 08 Nov 2018 14:45:13 +0000 Received: from 1.general.cking.uk.vpn ([10.172.193.212] helo=localhost) by youngberry.canonical.com with esmtpsa (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.76) (envelope-from ) id 1gKlYW-00063e-Jq; Thu, 08 Nov 2018 14:45:12 +0000 From: Colin King To: fwts-devel@lists.ubuntu.com Subject: [PATCH 1/3] src/lib: add module probing helper functions Date: Thu, 8 Nov 2018 14:45:09 +0000 Message-Id: <20181108144511.12678-2-colin.king@canonical.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181108144511.12678-1-colin.king@canonical.com> References: <20181108144511.12678-1-colin.king@canonical.com> MIME-Version: 1.0 X-BeenThere: fwts-devel@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Firmware Test Suite Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: fwts-devel-bounces@lists.ubuntu.com Sender: "fwts-devel" From: Colin Ian King Rather than load/unload modules with modrobe instead use direct system calls to perform these actions. This allows us to have finer control of the error handling and it is faster too. Signed-off-by: Colin Ian King Acked-by: Alex Hung Acked-by: Ivan Hu --- src/lib/include/fwts.h | 1 + src/lib/include/fwts_modprobe.h | 29 ++++ src/lib/src/Makefile.am | 1 + src/lib/src/fwts_modprobe.c | 235 ++++++++++++++++++++++++++++++++ 4 files changed, 266 insertions(+) create mode 100644 src/lib/include/fwts_modprobe.h create mode 100644 src/lib/src/fwts_modprobe.c diff --git a/src/lib/include/fwts.h b/src/lib/include/fwts.h index 62834ec3..3f343ef2 100644 --- a/src/lib/include/fwts.h +++ b/src/lib/include/fwts.h @@ -203,5 +203,6 @@ #include "fwts_safe_mem.h" #include "fwts_devicetree.h" #include "fwts_pm_debug.h" +#include "fwts_modprobe.h" #endif diff --git a/src/lib/include/fwts_modprobe.h b/src/lib/include/fwts_modprobe.h new file mode 100644 index 00000000..5a1c6e27 --- /dev/null +++ b/src/lib/include/fwts_modprobe.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2018 Canonical + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef __FWTS_MODPROBE_H__ +#define __FWTS_MODPROBE_H__ + +#include "fwts_framework.h" + +int fwts_module_loaded(fwts_framework *fw, const char *module, bool *loaded); +int fwts_module_load(fwts_framework *fw, const char *module); +int fwts_module_unload(fwts_framework *fw, const char *module); + +#endif diff --git a/src/lib/src/Makefile.am b/src/lib/src/Makefile.am index 54de7f44..9858d04c 100644 --- a/src/lib/src/Makefile.am +++ b/src/lib/src/Makefile.am @@ -92,6 +92,7 @@ libfwts_la_SOURCES = \ fwts_log_xml.c \ fwts_memorymap.c \ fwts_mmap.c \ + fwts_modprobe.c \ fwts_multiproc.c \ fwts_oops.c \ fwts_pci.c \ diff --git a/src/lib/src/fwts_modprobe.c b/src/lib/src/fwts_modprobe.c new file mode 100644 index 00000000..03e3a5f1 --- /dev/null +++ b/src/lib/src/fwts_modprobe.c @@ -0,0 +1,235 @@ +/* + * Copyright (C) 2018 Canonical + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fwts.h" + +/* + * fwts_module_find() + * recursively search for module from the basepath start + * and return false if not found, and true if found. If + * found, the full path of the module is set in the string + * path. + */ +static bool fwts_module_find( + const char *module, + const char *basepath, + char *path, + const size_t path_len) +{ + DIR *dir; + struct dirent *de; + + dir = opendir(basepath); + if (!dir) + return false; + + while ((de = readdir(dir)) != NULL) { + char newpath[PATH_MAX]; + + if (de->d_name[0] == '.') + continue; + + switch (de->d_type) { + case DT_DIR: + (void)snprintf(newpath, sizeof(newpath), "%s/%s", + basepath, de->d_name); + if (fwts_module_find(module, newpath, path, path_len)) { + (void)closedir(dir); + return true; + } + break; + case DT_REG: + if (!strcmp(de->d_name, module)) { + (void)snprintf(path, path_len, "%s/%s", basepath, module); + (void)closedir(dir); + return true; + } + break; + default: + break; + } + } + + (void)closedir(dir); + return false; +} + +/* + * sys_finit_module() + * system call wrapper for finit_module + */ +static inline int sys_finit_module( + int fd, + const char *param_values, + int flags) +{ + errno = 0; + return syscall(__NR_finit_module, fd, param_values, flags); +} + +/* + * sys_delete_module() + * system call wrapper for delete_module + */ +static inline int sys_delete_module( + const char *name, + int flags) +{ + errno = 0; + return syscall(__NR_delete_module, name, flags); +} + +/* + * fwts_module_loaded() + * check if module is loaded, the name (without .ko suffix) is + * provided in string module. Boolean loaded is set to true if + * the module is loaded, false otherwise. Returns FWTS_OK if + * all went OK, FWTS_ERROR if something went wrong. + */ +int fwts_module_loaded(fwts_framework *fw, const char *module, bool *loaded) +{ + FILE *fp; + char buffer[1024]; + + *loaded = false; + fp = fopen("/proc/modules", "r"); + if (!fp) { + fwts_log_error(fw, "Cannot open /proc/modules, errno=%d (%s)\n", + errno, strerror(errno)); + return FWTS_ERROR; + } + + (void)memset(buffer, 0, sizeof(buffer)); + while (fgets(buffer, sizeof(buffer) - 1, fp) != NULL) { + char *ptr = strchr(buffer, ' '); + + if (*ptr) + *ptr = '\0'; + + if (!strcmp(buffer, module)) { + *loaded = true; + break; + } + } + (void)fclose(fp); + + return FWTS_OK; +} + +/* + * fwts_module_load() + * load a module. The module name (without the .ko) suffix + * is to provided in string module. Returns FWTS_OK if + * succeeded (or the module is already loaded) and FWTS_ERROR + * if the load failed. + */ +int fwts_module_load(fwts_framework *fw, const char *module) +{ + struct utsname u; + const size_t modlen = strlen(module); + char module_ko[modlen + 4]; + char path[PATH_MAX]; + char modpath[PATH_MAX]; + const char *params = ""; + int fd; + bool loaded = false; + + /* + * No need to unload if it's not already loaded + */ + if (fwts_module_loaded(fw, module, &loaded) == FWTS_OK) { + if (loaded) + return FWTS_OK; + } + + /* + * Set up module root path and try to find the named module + */ + if (uname(&u) < 0) { + fwts_log_error(fw, "Call to uname failed, errno=%d (%s)\n", + errno, strerror(errno)); + return FWTS_ERROR; + } + (void)snprintf(module_ko, sizeof(module_ko), "%s.ko", module); + (void)snprintf(modpath, sizeof(modpath), "/lib/modules/%s", u.release); + if (!fwts_module_find(module_ko, modpath, path, sizeof(path))) { + fwts_log_error(fw, "Cannot find module %s\n", module); + return FWTS_ERROR; + } + + /* + * We've found it, now try and load it + */ + fd = open(path, O_RDONLY); + if (fd < 0) { + fwts_log_error(fw, "Cannot open module %s, errno=%d (%s)\n", + path, errno, strerror(errno)); + return FWTS_ERROR; + } + if (sys_finit_module(fd, params, 0) < 0) { + fwts_log_error(fw, "Cannot load module %s, errno=%d (%s)\n", + path, errno, strerror(errno)); + (void)close(fd); + return FWTS_ERROR; + } + (void)close(fd); + + return FWTS_OK; +} + +/* + * fwts_module_unload() + * unload a module. The module name (without the .ko) suffix + * is to provided in string module. Returns FWTS_OK if + * succeeded (or the module is not previously loaded) and + * FWTS_ERROR if the unload failed. + */ +int fwts_module_unload(fwts_framework *fw, const char *module) +{ + bool loaded = false; + int ret; + + /* + * No need to unload if it's not already loaded + */ + if (fwts_module_loaded(fw, module, &loaded) == FWTS_OK) { + if (!loaded) + return FWTS_OK; + } + + ret = sys_delete_module(module, O_NONBLOCK); + if (ret < 0) { + fwts_log_error(fw, "Cannot unload module %s, errno=%d (%s)\n", + module, errno, strerror(errno)); + return FWTS_ERROR; + } + return FWTS_OK; +} From patchwork Thu Nov 8 14:45:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Colin Ian King X-Patchwork-Id: 994922 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=fwts-devel-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42rR0H3W7Mz9sBk; Fri, 9 Nov 2018 01:45:19 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1gKlYb-0002Dp-0b; Thu, 08 Nov 2018 14:45:17 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1gKlYX-0002CU-M5 for fwts-devel@lists.ubuntu.com; Thu, 08 Nov 2018 14:45:13 +0000 Received: from 1.general.cking.uk.vpn ([10.172.193.212] helo=localhost) by youngberry.canonical.com with esmtpsa (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.76) (envelope-from ) id 1gKlYX-00063i-7z; Thu, 08 Nov 2018 14:45:13 +0000 From: Colin King To: fwts-devel@lists.ubuntu.com Subject: [PATCH 2/3] lib: fwts_efi_module: use the new module loading helper functions Date: Thu, 8 Nov 2018 14:45:10 +0000 Message-Id: <20181108144511.12678-3-colin.king@canonical.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181108144511.12678-1-colin.king@canonical.com> References: <20181108144511.12678-1-colin.king@canonical.com> MIME-Version: 1.0 X-BeenThere: fwts-devel@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Firmware Test Suite Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: fwts-devel-bounces@lists.ubuntu.com Sender: "fwts-devel" From: Colin Ian King Signed-off-by: Colin Ian King Acked-by: Alex Hung Acked-by: Ivan Hu --- src/lib/src/fwts_efi_module.c | 55 +++++------------------------------ 1 file changed, 7 insertions(+), 48 deletions(-) diff --git a/src/lib/src/fwts_efi_module.c b/src/lib/src/fwts_efi_module.c index c44f05a8..698d4bd6 100644 --- a/src/lib/src/fwts_efi_module.c +++ b/src/lib/src/fwts_efi_module.c @@ -29,36 +29,6 @@ static char *efi_dev_name = NULL; static char *module_name = NULL; -/* - * check_module_loaded() - * check if a given module is loaded - */ -static int check_module_loaded( - fwts_framework *fw, - char *module, - bool *loaded) -{ - FILE *fp; - - *loaded = false; - - if ((fp = fopen("/proc/modules", "r")) != NULL) { - char buffer[1024]; - - while (fgets(buffer, sizeof(buffer), fp) != NULL) { - if (strstr(buffer, module)) { - *loaded = true; - break; - } - } - (void)fclose(fp); - return FWTS_OK; - } - fwts_log_error(fw, "Could not open /proc/modules to check if efi module '%s' is loaded.", module); - - return FWTS_ERROR; -} - /* * check_module_loaded_no_dev() * sanity check - we don't have a device so we definitely should @@ -70,7 +40,7 @@ static int check_module_loaded_no_dev( { bool loaded; - if (check_module_loaded(fw, module, &loaded) != FWTS_OK) + if (fwts_module_loaded(fw, module, &loaded) != FWTS_OK) return FWTS_ERROR; if (loaded) { fwts_log_error(fw, "Module '%s' is already loaded, but device not available.", module); @@ -106,16 +76,12 @@ static int load_module( char *module, char *devname) { - int status; - char cmd[80]; bool loaded; - snprintf(cmd, sizeof(cmd), "modprobe %s", module); - - if (fwts_exec(cmd, &status) != FWTS_OK) + if (fwts_module_load(fw, module) != FWTS_OK) return FWTS_ERROR; - if (check_module_loaded(fw, module, &loaded) != FWTS_OK) + if (fwts_module_loaded(fw, module, &loaded) != FWTS_OK) return FWTS_ERROR; if (!loaded) @@ -170,8 +136,7 @@ int fwts_lib_efi_runtime_load_module(fwts_framework *fw) int fwts_lib_efi_runtime_unload_module(fwts_framework *fw) { bool loaded; - int status; - char cmd[80], *tmp_name = module_name; + char *tmp_name = module_name; efi_dev_name = NULL; @@ -181,20 +146,14 @@ int fwts_lib_efi_runtime_unload_module(fwts_framework *fw) module_name = NULL; - /* If it is not loaded, no need to unload it */ - if (check_module_loaded(fw, tmp_name, &loaded) != FWTS_OK) - return FWTS_ERROR; - if (!loaded) - return FWTS_OK; - - snprintf(cmd, sizeof(cmd), "modprobe -r %s", tmp_name); - if (fwts_exec(cmd, &status) != FWTS_OK) { + /* Unload module */ + if (fwts_module_unload(fw, tmp_name) != FWTS_OK) { fwts_log_error(fw, "Failed to unload module '%s'.", tmp_name); return FWTS_ERROR; } /* Module should not be loaded at this point */ - if (check_module_loaded(fw, tmp_name, &loaded) != FWTS_OK) + if (fwts_module_loaded(fw, tmp_name, &loaded) != FWTS_OK) return FWTS_ERROR; if (loaded) { fwts_log_error(fw, "Failed to unload module '%s'.", tmp_name); From patchwork Thu Nov 8 14:45:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Colin Ian King X-Patchwork-Id: 994921 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=fwts-devel-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42rR0G4tBmz9sC7; Fri, 9 Nov 2018 01:45:18 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1gKlYZ-0002DQ-V8; Thu, 08 Nov 2018 14:45:15 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1gKlYY-0002Cj-5s for fwts-devel@lists.ubuntu.com; Thu, 08 Nov 2018 14:45:14 +0000 Received: from 1.general.cking.uk.vpn ([10.172.193.212] helo=localhost) by youngberry.canonical.com with esmtpsa (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.76) (envelope-from ) id 1gKlYX-00063p-Sm; Thu, 08 Nov 2018 14:45:13 +0000 From: Colin King To: fwts-devel@lists.ubuntu.com Subject: [PATCH 3/3] lib/fwts_cpu: use new use the new module loading helper functions Date: Thu, 8 Nov 2018 14:45:11 +0000 Message-Id: <20181108144511.12678-4-colin.king@canonical.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181108144511.12678-1-colin.king@canonical.com> References: <20181108144511.12678-1-colin.king@canonical.com> MIME-Version: 1.0 X-BeenThere: fwts-devel@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Firmware Test Suite Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: fwts-devel-bounces@lists.ubuntu.com Sender: "fwts-devel" From: Colin Ian King Make the msr library helper now use the new module loading functions. This involves adding an extra fw parameter which means msr releated tests need modifying too. Signed-off-by: Colin Ian King Acked-by: Alex Hung Acked-by: Ivan Hu --- src/bios/mtrr/mtrr.c | 7 ++++--- src/cpu/msr/msr.c | 14 ++++++++------ src/cpu/nx/nx.c | 2 +- src/cpu/virt/virt_svm.c | 6 +++--- src/cpu/virt/virt_vmx.c | 6 +++--- src/lib/include/fwts_cpu.h | 2 +- src/lib/src/fwts_cpu.c | 22 ++++++++++++++++------ 7 files changed, 36 insertions(+), 23 deletions(-) diff --git a/src/bios/mtrr/mtrr.c b/src/bios/mtrr/mtrr.c index 5dfb4a60..4948b55a 100644 --- a/src/bios/mtrr/mtrr.c +++ b/src/bios/mtrr/mtrr.c @@ -182,8 +182,9 @@ static int get_mtrrs(void) return FWTS_OK; } -static int get_default_mtrr(void) { - if (fwts_cpu_readmsr(0, MTRR_DEF_TYPE_MSR, &mtrr_default) == FWTS_OK) { +static int get_default_mtrr(fwts_framework *fw) +{ + if (fwts_cpu_readmsr(fw, 0, MTRR_DEF_TYPE_MSR, &mtrr_default) == FWTS_OK) { switch (mtrr_default & 0xFF) { case 0: mtrr_default = UNCACHED; @@ -408,7 +409,7 @@ static int validate_iomem(fwts_framework *fw) if ((file = fopen("/proc/iomem", "r")) == NULL) return FWTS_ERROR; - if (get_default_mtrr() != FWTS_OK) + if (get_default_mtrr(fw) != FWTS_OK) mtrr_default = UNKNOWN; while (!feof(file)) { diff --git a/src/cpu/msr/msr.c b/src/cpu/msr/msr.c index 70d89650..a9dfd40c 100644 --- a/src/cpu/msr/msr.c +++ b/src/cpu/msr/msr.c @@ -77,7 +77,9 @@ static int msr_deinit(fwts_framework *fw) return FWTS_OK; } -static int msr_consistent(const uint32_t msr, +static int msr_consistent( + fwts_framework *fw, + const uint32_t msr, const int shift, const uint64_t mask, uint64_t *const vals, @@ -90,7 +92,7 @@ static int msr_consistent(const uint32_t msr, for (cpu = 0; cpu < ncpus; cpu++) { uint64_t val; - if (fwts_cpu_readmsr(cpu, msr, &val) != FWTS_OK) { + if (fwts_cpu_readmsr(fw, cpu, msr, &val) != FWTS_OK) { return FWTS_ERROR; } val >>= shift; @@ -130,7 +132,7 @@ static int msr_consistent_check(fwts_framework *fw, free(vals); return FWTS_ERROR; } - if (msr_consistent(msr, shift, mask, + if (msr_consistent(fw, msr, shift, mask, vals, &inconsistent_count, inconsistent) != FWTS_OK) { free(inconsistent); free(vals); @@ -197,7 +199,7 @@ static int msr_smrr(fwts_framework *fw) uint64_t val; if (intel_cpu) { - if (fwts_cpu_readmsr(0, 0xfe, &val) != FWTS_OK) { + if (fwts_cpu_readmsr(fw, 0, 0xfe, &val) != FWTS_OK) { fwts_skipped(fw, "Cannot read MSR 0xfe."); return FWTS_ERROR; } @@ -210,7 +212,7 @@ static int msr_smrr(fwts_framework *fw) msr_consistent_check(fw, LOG_LEVEL_HIGH, "SMRR_PHYSMASK", 0x1f3, 12, 0xfffff, NULL); msr_consistent_check(fw, LOG_LEVEL_HIGH, "SMRR_VALID", 0x1f3, 11, 0x1, NULL); - if (fwts_cpu_readmsr(0, 0x1f2, &val) == FWTS_OK) { + if (fwts_cpu_readmsr(fw, 0, 0x1f2, &val) == FWTS_OK) { uint64_t physbase = val & 0xfffff000; uint64_t type = val & 7; if ((physbase & 0xfff) != 0) @@ -221,7 +223,7 @@ static int msr_smrr(fwts_framework *fw) fwts_failed(fw, LOG_LEVEL_HIGH, "MSRSMRR_TYPE", "SMRR: SMRR_TYPE is 0x%" PRIx64 ", should be 0x6 (Write-Back).", type); } - if (fwts_cpu_readmsr(0, 0x1f3, &val) == FWTS_OK) { + if (fwts_cpu_readmsr(fw, 0, 0x1f3, &val) == FWTS_OK) { uint64_t physmask = val & 0xfffff000; uint64_t valid = (val >> 11) & 1; diff --git a/src/cpu/nx/nx.c b/src/cpu/nx/nx.c index 66a7b6f1..5caf0c6c 100644 --- a/src/cpu/nx/nx.c +++ b/src/cpu/nx/nx.c @@ -169,7 +169,7 @@ static int nx_test3(fwts_framework *fw) fwts_cpu_free_info(fwts_nx_cpuinfo); return FWTS_OK; } - if (fwts_cpu_readmsr(i, 0x1a0, &val) != FWTS_OK) { + if (fwts_cpu_readmsr(fw, i, 0x1a0, &val) != FWTS_OK) { fwts_log_error(fw, "Cannot read msr 0x1a0 on CPU%d", i); fwts_cpu_free_info(fwts_nx_cpuinfo); return FWTS_ERROR; diff --git a/src/cpu/virt/virt_svm.c b/src/cpu/virt/virt_svm.c index 8cf85305..59ebb83f 100644 --- a/src/cpu/virt/virt_svm.c +++ b/src/cpu/virt/virt_svm.c @@ -52,14 +52,14 @@ static int can_lock_with_msr(void) return (fwts_virt_cpuinfo->x86 & 0x10); } -static int vt_locked_by_bios(void) +static int vt_locked_by_bios(fwts_framework *fw) { uint64_t msr; if (!can_lock_with_msr()) return 0; - if (fwts_cpu_readmsr(0, MSR_FEATURE_CONTROL, &msr)) + if (fwts_cpu_readmsr(fw, 0, MSR_FEATURE_CONTROL, &msr)) return -1; return ((msr & 0x1000) == 0x1000); /* SVM capable but locked by bios*/ @@ -72,7 +72,7 @@ void virt_check_svm(fwts_framework *fw) if (!cpu_has_svm()) fwts_skipped(fw, "Processor does not support Virtualization extensions, won't test BIOS configuration, skipping test."); else { - int ret = vt_locked_by_bios(); + int ret = vt_locked_by_bios(fw); switch (ret) { case 0: fwts_passed(fw, "Virtualization extensions supported and enabled by BIOS."); diff --git a/src/cpu/virt/virt_vmx.c b/src/cpu/virt/virt_vmx.c index 307424e7..c4cfb6ab 100644 --- a/src/cpu/virt/virt_vmx.c +++ b/src/cpu/virt/virt_vmx.c @@ -55,11 +55,11 @@ static int cpu_has_vmx(void) return (strstr(fwts_virt_cpuinfo->flags, "vmx") != NULL); } -static int vt_locked_by_bios(void) +static int vt_locked_by_bios(fwts_framework *fw) { uint64_t msr; - if (fwts_cpu_readmsr(0, MSR_FEATURE_CONTROL, &msr)) + if (fwts_cpu_readmsr(fw, 0, MSR_FEATURE_CONTROL, &msr)) return -1; return (msr & 5) == 1; /* VT capable but locked by bios*/ @@ -72,7 +72,7 @@ void virt_check_vmx(fwts_framework *fw) if (!cpu_has_vmx()) fwts_skipped(fw, "Processor does not support Virtualization extensions, won't test BIOS configuration, skipping test."); else { - int ret = vt_locked_by_bios(); + int ret = vt_locked_by_bios(fw); switch (ret) { case 0: fwts_passed(fw, "Virtualization extensions supported and enabled by BIOS."); diff --git a/src/lib/include/fwts_cpu.h b/src/lib/include/fwts_cpu.h index 5aa92984..4192e571 100644 --- a/src/lib/include/fwts_cpu.h +++ b/src/lib/include/fwts_cpu.h @@ -57,7 +57,7 @@ typedef struct cpu_benchmark_result { uint64_t cycles; } fwts_cpu_benchmark_result; -int fwts_cpu_readmsr(const int cpu, const uint32_t reg, uint64_t *val); +int fwts_cpu_readmsr(fwts_framework *fw, const int cpu, const uint32_t reg, uint64_t *val); int fwts_cpu_is_Intel(bool *is_intel); int fwts_cpu_is_AMD(bool *is_amd); diff --git a/src/lib/src/fwts_cpu.c b/src/lib/src/fwts_cpu.c index 18ff7823..a3c1638a 100644 --- a/src/lib/src/fwts_cpu.c +++ b/src/lib/src/fwts_cpu.c @@ -53,7 +53,11 @@ static pid_t *fwts_cpu_pids; * fwts_cpu_readmsr() * Read a given msr on a specificied CPU */ -int fwts_cpu_readmsr(const int cpu, const uint32_t reg, uint64_t *val) +int fwts_cpu_readmsr( + fwts_framework *fw, + const int cpu, + const uint32_t reg, + uint64_t *val) { char buffer[PATH_MAX]; uint64_t value = 0; @@ -62,12 +66,18 @@ int fwts_cpu_readmsr(const int cpu, const uint32_t reg, uint64_t *val) snprintf(buffer, sizeof(buffer), "/dev/cpu/%d/msr", cpu); if ((fd = open(buffer, O_RDONLY)) < 0) { - /* Hrm, msr not there, so force modprobe msr and see what happens */ - pid_t pid; - if (fwts_pipe_open_ro("modprobe msr", &pid, &fd) < 0) - return FWTS_ERROR; - fwts_pipe_close(fd, pid); + bool loaded = false; + /* + * msr not there, so force a load of the msr + * module and retry + */ + if (fwts_module_load(fw, "msr") != FWTS_OK) + return FWTS_ERROR; + if (fwts_module_loaded(fw, "msr", &loaded) != FWTS_OK) + return FWTS_ERROR; + if (!loaded) + return FWTS_ERROR; if ((fd = open(buffer, O_RDONLY)) < 0) return FWTS_ERROR; /* Really failed */ }