ACK: [PATCH 3/4] opal: cpu_info: Add OPAL CPU Info validation

Alex Hung alex.hung at canonical.com
Wed Nov 16 19:38:03 UTC 2016


On 2016-11-10 08:02 PM, Deb McLemore wrote:
> Check that the CPU devices are properly setup in the device tree.
>
> Signed-off-by: Deb McLemore <debmc at linux.vnet.ibm.com>
> ---
>  src/Makefile.am     |   3 +
>  src/opal/cpu_info.c | 276 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 279 insertions(+)
>  create mode 100644 src/opal/cpu_info.c
>
> diff --git a/src/Makefile.am b/src/Makefile.am
> index 9c2975b..c1eb285 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -26,6 +26,8 @@ dt_tests = \
>  	devicetree/dt_sysinfo/dt_sysinfo.c
>  mem_tests = \
>  	opal/mem_info.c
> +cpu_tests = \
> +	opal/cpu_info.c
>  endif
>
>  if HAVE_LIBFDT
> @@ -161,6 +163,7 @@ fwts_SOURCES = main.c 				\
>  	uefi/esrt/esrt.c			\
>  	$(pci_tests)				\
>  	$(mem_tests)				\
> +	$(cpu_tests)				\
>  	$(dt_tests)
>
>  fwts_LDFLAGS = -lm `pkg-config --libs glib-2.0 gio-2.0`
> diff --git a/src/opal/cpu_info.c b/src/opal/cpu_info.c
> new file mode 100644
> index 0000000..9953c90
> --- /dev/null
> +++ b/src/opal/cpu_info.c
> @@ -0,0 +1,276 @@
> +/*
> + * Copyright (C) 2010-2016 Canonical
> + * Some of this work - Copyright (C) 2016 IBM
> + *
> + * 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 /* added for asprintf */
> +#include <fcntl.h>
> +#include <sys/ioctl.h>
> +#include <stdio.h>
> +
> +#include "fwts.h"
> +
> +#include <libfdt.h>
> +
> +static int get_xscom_property(fwts_framework *fw,
> +			char *my_path,
> +			bool hex,
> +			char *property)
> +{
> +	int node, prop_len, failures = 0;
> +	const char *prop_buf;
> +	char *prop_string = NULL;
> +
> +	prop_string = strstr(my_path, "/xscom");
> +	if (prop_string) {
> +		node = fdt_path_offset(fw->fdt, prop_string);
> +		if (node >= 0) {
> +			prop_buf = fdt_getprop(fw->fdt, node,
> +					property,
> +					&prop_len);
> +			if ((prop_len > 0) && (prop_buf)) {
> +				fwts_log_nl(fw);
> +				if ((hex) && (prop_len == 4)) {
> +					fwts_passed(fw,
> +						"OPAL CPU Info Property of"
> +						"\"%s\" for \"%s\" is "
> +						"\"0x%02X%02X%02X%02X\".",
> +						property,
> +						my_path,
> +						prop_buf[0],
> +						prop_buf[1],
> +						prop_buf[2],
> +						prop_buf[3]);
> +				} else if (!hex) {
> +					if (check_property_printable(fw,
> +						property,
> +						prop_buf,
> +						prop_len)) {
> +							failures ++;
> +					}
> +					fwts_passed(fw,
> +						"OPAL CPU Info Property of"
> +						" \"%s\" for \"%s\" "
> +						"is \"%s\".",
> +						property,
> +						my_path,
> +						prop_buf);
> +				} else {
> +					failures ++;
> +					fwts_log_nl(fw);
> +					fwts_failed(fw,
> +						LOG_LEVEL_CRITICAL,
> +						"OPAL CPU Info",
> +						"Property of "
> +						"\"%s\" for \"%s\" is not"
> +						" properly formatted."
> +						" Check your installation"
> +						" for proper device tree "
> +						"nodes.",
> +						property,
> +						my_path);
> +				}
> +			} else {
> +				failures ++;
> +				fwts_log_nl(fw);
> +				fwts_failed(fw,
> +					LOG_LEVEL_CRITICAL,
> +					"OPAL CPU Info",
> +					"Property of \"%s\" for \"%s\" was"
> +					" not able to be retrieved. Check the"
> +					" installation for the CPU device"
> +					" config for missing nodes in the"
> +					" device tree if you expect CPU"
> +					" devices.",
> +					property,
> +					my_path);
> +			}
> +		} else {
> +			failures ++;
> +			fwts_log_nl(fw);
> +			fwts_failed(fw, LOG_LEVEL_CRITICAL,
> +				"OPAL CPU Info",
> +				"Failed to get node for xscom"
> +				" \"%s/%s\", please check the system for"
> +				" setup issues.",
> +				my_path, property);
> +		}
> +	} else {
> +		failures ++;
> +		fwts_log_nl(fw);
> +		fwts_failed(fw, LOG_LEVEL_CRITICAL,
> +			"OPAL CPU Info",
> +			"Internal processing problem at strstr"
> +			" my_path of \"%s\" for \"%s\", please check the"
> +			" system for setup issues.",
> +			my_path,
> +			property);
> +	}
> +	if (failures) {
> +		return FWTS_ERROR;
> +	} else {
> +		return FWTS_OK;
> +	}
> +}
> +
> +static int get_linux_xscom_devices(fwts_framework *fw)
> +{
> +	int count, i, failures = 0;
> +	struct dirent **namelist;
> +	bool found = false;
> +
> +	count = scandir(DT_FS_PATH, &namelist, NULL, alphasort);
> +	if (count < 0) {
> +		fwts_failed(fw, LOG_LEVEL_CRITICAL,
> +			"OPAL CPU Info",
> +			"Scan for CPU devices in '%s' is unable to find any"
> +			" candidates. Check the installation for the CPU"
> +			" device config for missing nodes in the device tree"
> +			" (xscom at X) if you expect CPU devices.",
> +			DT_FS_PATH);
> +		return FWTS_ERROR;
> +	}
> +
> +	fwts_log_nl(fw);
> +	fwts_log_info(fw, "STARTING checks of CPU'S");
> +
> +	for (i = 0; i < count; i++) {
> +		struct dirent *dirent;
> +		char *cpus;
> +		char *xscom_path;
> +
> +		dirent = namelist[i];
> +
> +		if (dirent->d_name[0] == '.' ||
> +			asprintf(&cpus,
> +				"%s",
> +				dirent->d_name) < 0) {
> +			/* asprintf must be last condition so when it */
> +			/* evaluates cpus gets allocated */
> +			free(namelist[i]);
> +			continue;
> +		}
> +
> +		if (strstr(cpus, "xscom")) {
> +			found = true;
> +			if (asprintf(&xscom_path,
> +				"%s/%s",
> +				DT_FS_PATH,
> +				cpus) < 0 ) {
> +				fwts_log_nl(fw);
> +				fwts_failed(fw, LOG_LEVEL_CRITICAL,
> +					"OPAL CPU Info",
> +					"Internal processing problem at"
> +					" cpus \"%s\", please"
> +					" check the system for"
> +					" setup issues.",
> +					cpus);
> +				free(cpus);
> +				free(namelist[i]);
> +				continue;
> +			}
> +			if (get_xscom_property(fw, xscom_path, false,
> +						DT_PROPERTY_OPAL_SLOT_LOC)) {
> +				failures ++;
> +			}
> +
> +			if (get_xscom_property(fw, xscom_path, false,
> +						DT_PROPERTY_OPAL_PART_NUM)) {
> +				failures ++;
> +			}
> +
> +			if (get_xscom_property(fw, xscom_path, false,
> +						DT_PROPERTY_OPAL_SERIAL_NUM)) {
> +				failures ++;
> +			}
> +
> +			if (get_xscom_property(fw, xscom_path, false,
> +						DT_PROPERTY_OPAL_VENDOR)) {
> +				failures ++;
> +			}
> +
> +			if (get_xscom_property(fw, xscom_path, false,
> +						DT_PROPERTY_OPAL_BOARD_INFO)) {
> +				failures ++;
> +			}
> +			fwts_log_nl(fw);
> +			free(cpus);
> +			free(namelist[i]);
> +		}
> +	}
> +	free(namelist);
> +
> +	fwts_log_nl(fw);
> +	fwts_log_info(fw, "ENDING checks of CPU's");
> +	fwts_log_nl(fw);
> +
> +	if (!found) {
> +		failures ++;
> +		fwts_failed(fw, LOG_LEVEL_CRITICAL,
> +			"OPAL CPU Info",
> +			"No CPU devices (xscom at X) were found in \"%s\"."
> +			" Check the system for setup issues.",
> +			DT_FS_PATH);
> +	}
> +
> +	if (failures) {
> +		return FWTS_ERROR;
> +	} else {
> +		return FWTS_OK;
> +	}
> +
> +}
> +
> +static int cpu_info_test1(fwts_framework *fw)
> +{
> +	if (get_linux_xscom_devices(fw)) {
> +
> +		/* errors logged earlier */
> +		return FWTS_ERROR;
> +	} else {
> +		return FWTS_OK;
> +	}
> +}
> +
> +static int cpu_info_init(fwts_framework *fw)
> +{
> +	if (fw->firmware_type != FWTS_FIRMWARE_OPAL) {
> +		fwts_skipped(fw,
> +			"The firmware type detected was not set"
> +			" to OPAL so skipping the OPAL CPU Info"
> +			" checks.");
> +		return FWTS_SKIP;
> +	} else {
> +		return FWTS_OK;
> +	}
> +}
> +
> +static fwts_framework_minor_test cpu_info_tests[] = {
> +	{ cpu_info_test1, "OPAL CPU Info" },
> +	{ NULL, NULL }
> +};
> +
> +static fwts_framework_ops cpu_info_ops = {
> +	.description = "OPAL CPU Info",
> +	.init        = cpu_info_init,
> +	.minor_tests = cpu_info_tests
> +};
> +
> +FWTS_REGISTER_FEATURES("cpu_info", &cpu_info_ops, FWTS_TEST_ANYTIME,
> +		FWTS_FLAG_BATCH | FWTS_FLAG_ROOT_PRIV,
> +		FWTS_FW_FEATURE_DEVICETREE);
>


Acked-by: Alex Hung <alex.hung at canonical.com>



More information about the fwts-devel mailing list