Message ID | 20210309050612.345348-1-alex.hung@canonical.com |
---|---|
State | Accepted |
Headers | show |
Series | bios: smm: add a test to check SMM lock bits | expand |
On 09/03/2021 05:06, Alex Hung wrote: > Signed-off-by: Alex Hung <alex.hung@canonical.com> > --- > src/Makefile.am | 1 + > src/bios/smm/smm.c | 115 +++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 116 insertions(+) > create mode 100644 src/bios/smm/smm.c > > diff --git a/src/Makefile.am b/src/Makefile.am > index b7f3f7db..b447e357 100644 > --- a/src/Makefile.am > +++ b/src/Makefile.am > @@ -162,6 +162,7 @@ fwts_SOURCES = main.c \ > bios/pnp/pnp.c \ > bios/romdump/romdump.c \ > bios/s0idle/s0idle.c \ > + bios/smm/smm.c \ > cmos/cmosdump/cmosdump.c \ > coreboot/clog/clog.c \ > cpu/virt/virt.c \ > diff --git a/src/bios/smm/smm.c b/src/bios/smm/smm.c > new file mode 100644 > index 00000000..990c7bd4 > --- /dev/null > +++ b/src/bios/smm/smm.c > @@ -0,0 +1,115 @@ > +/* > + * Copyright (C) 2021 Canonical > + * > + * This code was originally part of the Linux-ready Firmware Developer Kit > + * > + * 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. > + * > + */ > +#include "fwts.h" > + > +#ifdef FWTS_ARCH_INTEL > + > +#include <stdlib.h> > +#include <stdio.h> > +#include <fcntl.h> > + > +#define FWTS_INTEL_HOST_PATH "/sys/bus/pci/devices/0000:00:00.0/config" > + > +#define FWTS_GGC 0x50 > +#define FWTS_TSEGMB 0xB8 > +#define FWTS_TOLUD 0xBC > +#define FWTS_LOCK_FIELD 0x01 > + > +static int smm_init(fwts_framework *fw) > +{ > + bool intel; > + > + if (fwts_cpu_is_Intel(&intel) != FWTS_OK) { > + fwts_log_error(fw, "Cannot determine processor type."); > + return FWTS_ERROR; > + } > + > + if (!intel) { > + fwts_log_info(fw, "The SMM test currently only supports Intel platforms."); > + return FWTS_SKIP; > + } > + > + return FWTS_OK; > +} > + > +static int smm_deinit(fwts_framework *fw) > +{ > + FWTS_UNUSED(fw); > + return FWTS_OK; > +} > + > +static int smm_test0(fwts_framework *fw) > +{ > + uint8_t config[256]; > + bool passed = true; > + ssize_t n; > + int fd; > + > + if ((fd = open(FWTS_INTEL_HOST_PATH, O_RDONLY)) < 0) { > + fwts_log_warning(fw, "Could not open PCI HOST bridge config data\n"); > + return FWTS_ERROR; > + } > + if ((n = read(fd, config, sizeof(config))) < 0) { > + fwts_log_warning(fw, "Could not read PCI HOST bridge config data\n"); > + (void)close(fd); > + return FWTS_ERROR; > + } > + (void)close(fd); > + > + if ((config[FWTS_GGC] & FWTS_LOCK_FIELD) != 1) { > + fwts_failed(fw, LOG_LEVEL_HIGH, "SMMGGCNotLocked", > + "Graphics Control register is not locked (GGCLCK != 1)."); > + passed = false; > + } > + > + if ((config[FWTS_TSEGMB] & FWTS_LOCK_FIELD) != 1) { > + fwts_failed(fw, LOG_LEVEL_HIGH, "SMMTSEGNotLocked", > + "TSEG Memory Base register is not locked."); > + passed = false; > + } > + > + if ((config[FWTS_TOLUD] & FWTS_LOCK_FIELD) != 1) { > + fwts_failed(fw, LOG_LEVEL_HIGH, "SMMTOLUDNotLocked", > + "Top of Low Usable DRAM (TOLUD) register is not locked."); > + passed = false; > + } > + > + if (passed) > + fwts_passed(fw, "No issues found in SMM locks."); > + > + return FWTS_OK; > +} > + > +static fwts_framework_minor_test smm_tests[] = { > + { smm_test0, "Validate the System management mode (SMM) locks." }, > + { NULL, NULL } > +}; > + > +static fwts_framework_ops smm_ops = { > + .description = "SMM tests.", > + .init = smm_init, > + .deinit = smm_deinit, > + .minor_tests = smm_tests > +}; > + > +FWTS_REGISTER("smm", &smm_ops, FWTS_TEST_ANYTIME, FWTS_FLAG_BATCH | FWTS_FLAG_ROOT_PRIV) > + > +#endif > Works for me, Coverity checks are good. Acked-by: Colin Ian King <colin.king@canonical.com>
On 3/9/21 1:06 PM, Alex Hung wrote: > Signed-off-by: Alex Hung <alex.hung@canonical.com> > --- > src/Makefile.am | 1 + > src/bios/smm/smm.c | 115 +++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 116 insertions(+) > create mode 100644 src/bios/smm/smm.c > > diff --git a/src/Makefile.am b/src/Makefile.am > index b7f3f7db..b447e357 100644 > --- a/src/Makefile.am > +++ b/src/Makefile.am > @@ -162,6 +162,7 @@ fwts_SOURCES = main.c \ > bios/pnp/pnp.c \ > bios/romdump/romdump.c \ > bios/s0idle/s0idle.c \ > + bios/smm/smm.c \ > cmos/cmosdump/cmosdump.c \ > coreboot/clog/clog.c \ > cpu/virt/virt.c \ > diff --git a/src/bios/smm/smm.c b/src/bios/smm/smm.c > new file mode 100644 > index 00000000..990c7bd4 > --- /dev/null > +++ b/src/bios/smm/smm.c > @@ -0,0 +1,115 @@ > +/* > + * Copyright (C) 2021 Canonical > + * > + * This code was originally part of the Linux-ready Firmware Developer Kit > + * > + * 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. > + * > + */ > +#include "fwts.h" > + > +#ifdef FWTS_ARCH_INTEL > + > +#include <stdlib.h> > +#include <stdio.h> > +#include <fcntl.h> > + > +#define FWTS_INTEL_HOST_PATH "/sys/bus/pci/devices/0000:00:00.0/config" > + > +#define FWTS_GGC 0x50 > +#define FWTS_TSEGMB 0xB8 > +#define FWTS_TOLUD 0xBC > +#define FWTS_LOCK_FIELD 0x01 > + > +static int smm_init(fwts_framework *fw) > +{ > + bool intel; > + > + if (fwts_cpu_is_Intel(&intel) != FWTS_OK) { > + fwts_log_error(fw, "Cannot determine processor type."); > + return FWTS_ERROR; > + } > + > + if (!intel) { > + fwts_log_info(fw, "The SMM test currently only supports Intel platforms."); > + return FWTS_SKIP; > + } > + > + return FWTS_OK; > +} > + > +static int smm_deinit(fwts_framework *fw) > +{ > + FWTS_UNUSED(fw); > + return FWTS_OK; > +} > + > +static int smm_test0(fwts_framework *fw) > +{ > + uint8_t config[256]; > + bool passed = true; > + ssize_t n; > + int fd; > + > + if ((fd = open(FWTS_INTEL_HOST_PATH, O_RDONLY)) < 0) { > + fwts_log_warning(fw, "Could not open PCI HOST bridge config data\n"); > + return FWTS_ERROR; > + } > + if ((n = read(fd, config, sizeof(config))) < 0) { > + fwts_log_warning(fw, "Could not read PCI HOST bridge config data\n"); > + (void)close(fd); > + return FWTS_ERROR; > + } > + (void)close(fd); > + > + if ((config[FWTS_GGC] & FWTS_LOCK_FIELD) != 1) { > + fwts_failed(fw, LOG_LEVEL_HIGH, "SMMGGCNotLocked", > + "Graphics Control register is not locked (GGCLCK != 1)."); > + passed = false; > + } > + > + if ((config[FWTS_TSEGMB] & FWTS_LOCK_FIELD) != 1) { > + fwts_failed(fw, LOG_LEVEL_HIGH, "SMMTSEGNotLocked", > + "TSEG Memory Base register is not locked."); > + passed = false; > + } > + > + if ((config[FWTS_TOLUD] & FWTS_LOCK_FIELD) != 1) { > + fwts_failed(fw, LOG_LEVEL_HIGH, "SMMTOLUDNotLocked", > + "Top of Low Usable DRAM (TOLUD) register is not locked."); > + passed = false; > + } > + > + if (passed) > + fwts_passed(fw, "No issues found in SMM locks."); > + > + return FWTS_OK; > +} > + > +static fwts_framework_minor_test smm_tests[] = { > + { smm_test0, "Validate the System management mode (SMM) locks." }, > + { NULL, NULL } > +}; > + > +static fwts_framework_ops smm_ops = { > + .description = "SMM tests.", > + .init = smm_init, > + .deinit = smm_deinit, > + .minor_tests = smm_tests > +}; > + > +FWTS_REGISTER("smm", &smm_ops, FWTS_TEST_ANYTIME, FWTS_FLAG_BATCH | FWTS_FLAG_ROOT_PRIV) > + > +#endif > Acked-by: Ivan Hu <ivan.hu@canonical.com>
diff --git a/src/Makefile.am b/src/Makefile.am index b7f3f7db..b447e357 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -162,6 +162,7 @@ fwts_SOURCES = main.c \ bios/pnp/pnp.c \ bios/romdump/romdump.c \ bios/s0idle/s0idle.c \ + bios/smm/smm.c \ cmos/cmosdump/cmosdump.c \ coreboot/clog/clog.c \ cpu/virt/virt.c \ diff --git a/src/bios/smm/smm.c b/src/bios/smm/smm.c new file mode 100644 index 00000000..990c7bd4 --- /dev/null +++ b/src/bios/smm/smm.c @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2021 Canonical + * + * This code was originally part of the Linux-ready Firmware Developer Kit + * + * 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. + * + */ +#include "fwts.h" + +#ifdef FWTS_ARCH_INTEL + +#include <stdlib.h> +#include <stdio.h> +#include <fcntl.h> + +#define FWTS_INTEL_HOST_PATH "/sys/bus/pci/devices/0000:00:00.0/config" + +#define FWTS_GGC 0x50 +#define FWTS_TSEGMB 0xB8 +#define FWTS_TOLUD 0xBC +#define FWTS_LOCK_FIELD 0x01 + +static int smm_init(fwts_framework *fw) +{ + bool intel; + + if (fwts_cpu_is_Intel(&intel) != FWTS_OK) { + fwts_log_error(fw, "Cannot determine processor type."); + return FWTS_ERROR; + } + + if (!intel) { + fwts_log_info(fw, "The SMM test currently only supports Intel platforms."); + return FWTS_SKIP; + } + + return FWTS_OK; +} + +static int smm_deinit(fwts_framework *fw) +{ + FWTS_UNUSED(fw); + return FWTS_OK; +} + +static int smm_test0(fwts_framework *fw) +{ + uint8_t config[256]; + bool passed = true; + ssize_t n; + int fd; + + if ((fd = open(FWTS_INTEL_HOST_PATH, O_RDONLY)) < 0) { + fwts_log_warning(fw, "Could not open PCI HOST bridge config data\n"); + return FWTS_ERROR; + } + if ((n = read(fd, config, sizeof(config))) < 0) { + fwts_log_warning(fw, "Could not read PCI HOST bridge config data\n"); + (void)close(fd); + return FWTS_ERROR; + } + (void)close(fd); + + if ((config[FWTS_GGC] & FWTS_LOCK_FIELD) != 1) { + fwts_failed(fw, LOG_LEVEL_HIGH, "SMMGGCNotLocked", + "Graphics Control register is not locked (GGCLCK != 1)."); + passed = false; + } + + if ((config[FWTS_TSEGMB] & FWTS_LOCK_FIELD) != 1) { + fwts_failed(fw, LOG_LEVEL_HIGH, "SMMTSEGNotLocked", + "TSEG Memory Base register is not locked."); + passed = false; + } + + if ((config[FWTS_TOLUD] & FWTS_LOCK_FIELD) != 1) { + fwts_failed(fw, LOG_LEVEL_HIGH, "SMMTOLUDNotLocked", + "Top of Low Usable DRAM (TOLUD) register is not locked."); + passed = false; + } + + if (passed) + fwts_passed(fw, "No issues found in SMM locks."); + + return FWTS_OK; +} + +static fwts_framework_minor_test smm_tests[] = { + { smm_test0, "Validate the System management mode (SMM) locks." }, + { NULL, NULL } +}; + +static fwts_framework_ops smm_ops = { + .description = "SMM tests.", + .init = smm_init, + .deinit = smm_deinit, + .minor_tests = smm_tests +}; + +FWTS_REGISTER("smm", &smm_ops, FWTS_TEST_ANYTIME, FWTS_FLAG_BATCH | FWTS_FLAG_ROOT_PRIV) + +#endif
Signed-off-by: Alex Hung <alex.hung@canonical.com> --- src/Makefile.am | 1 + src/bios/smm/smm.c | 115 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 src/bios/smm/smm.c