[Pdbg] [PATCH RFC 3/4] pdbg: add timeer facility TB error injections.

Mahesh J Salgaonkar mahesh at linux.ibm.com
Tue May 26 16:18:21 AEST 2020


On 2020-05-13 15:04:31 Wed, Nicholas Piggin wrote:
> Hey Mahesh,
> 
> Very nice, I'm assuming adding various MCE injection should be quite 
> easy when the framework is in place.
> 
> I'm handwaving a bit here because I haven't looked at pdbg's targeting 
> for so long maybe it doesn't quite work so well, but what I had hoped is 
> that targets would implement an ->inject_error and ->inject_error_list
> that core code knows nothing about but calls directly.

I followed the getscom/putscom way.. Let me see if I can hook this up
into target itself.

Thanks,
-Mahesh.

> 
> Then the targets would be able to advertise exactly what they implement
> and common code doesn't have these target specifics.
> 
> Thanks,
> Nick
> 
> Excerpts from Mahesh Salgaonkar's message of May 11, 2020 6:41 pm:
> > # ./pdbg -p0 -c3 -t3 inject
> > Usage: pdbg inject <component> <error>
> >  <component>:
> >     ?          Show component list
> >     tb
> > # ./pdbg -p0 -c3 -t3 inject tb ?
> > Usage: pdbg inject tb <error>:
> >  <error>:
> >     ?               Show error list
> >     tfmr_parity     TFMR parity error
> >     hdec_parity     HDEC parity error
> >     tb_residue      TB parity/residue error
> >     purr_parity     PURR parity error
> >     spurr_parity    SPURR parity error
> >     dec_parity      DEC parity error
> > 
> > # ./pdbg -p0 -c1 -t3  inject tb dec_parity
> > p0:c1:t3: 0x20010a84 = 0x001e000000000000
> > #
> > # ./pdbg -p0 -c1,2  inject tb hdec_parity
> > p0:c1: 0x20010a84 = 0x0002000000000000
> > p0:c2: 0x20010a84 = 0x0002000000000000
> > #
> > 
> > Signed-off-by: Mahesh Salgaonkar <mahesh at linux.ibm.com>
> > ---
> >  Makefile.am         |    3 +
> >  src/err_inject.c    |   46 +++++++++++++++++++++
> >  src/err_inject.h    |   43 +++++++++++++++++++
> >  src/timefac_error.c |  114 +++++++++++++++++++++++++++++++++++++++++++++++++++
> >  4 files changed, 205 insertions(+), 1 deletion(-)
> >  create mode 100644 src/timefac_error.c
> > 
> > diff --git a/Makefile.am b/Makefile.am
> > index 05522cf..ed97505 100644
> > --- a/Makefile.am
> > +++ b/Makefile.am
> > @@ -122,7 +122,8 @@ pdbg_SOURCES = \
> >  	src/util.c \
> >  	src/util.h \
> >  	src/err_inject.c \
> > -	src/err_inject.h
> > +	src/err_inject.h \
> > +	src/timefac_error.c
> >  
> >  pdbg_CFLAGS = -I$(top_srcdir)/libpdbg -Wall -Werror -DGIT_SHA1=\"${GIT_SHA1}\" \
> >  	      $(ARCH_FLAGS)
> > diff --git a/src/err_inject.c b/src/err_inject.c
> > index ef6bc97..c059ef8 100644
> > --- a/src/err_inject.c
> > +++ b/src/err_inject.c
> > @@ -22,6 +22,7 @@
> >  
> >  #include <libpdbg.h>
> >  #include <ccan/list/list.h>
> > +#include <bitutils.h>
> >  
> >  #include "main.h"
> >  #include "optcmd.h"
> > @@ -162,9 +163,54 @@ static void inject_errors(char *component, char *error)
> >  	}
> >  }
> >  
> > +static char *target_short_path(struct pdbg_target *target)
> > +{
> > +	char result[255];
> > +	char *bufp = result;
> > +	int proc_index = -1, chip_index = -1, thread_index = -1;
> > +	int n = 0;
> > +
> > +	if (get_target_type(target) == TARGET_TYPE_THREAD) {
> > +		thread_index = pdbg_target_index(target);
> > +		target = pdbg_target_parent("core", target);
> > +	}
> > +	if (get_target_type(target) == TARGET_TYPE_CORE) {
> > +		chip_index = pdbg_target_index(target);
> > +		target = pdbg_target_parent("pib", target);
> > +	}
> > +	if (get_target_type(target) == TARGET_TYPE_PROC)
> > +		proc_index = pdbg_target_index(target);
> > +
> > +	if (proc_index >= 0)
> > +		n += sprintf(bufp + n, "p%d:", proc_index);
> > +	if (chip_index >= 0)
> > +		n += sprintf(bufp + n, "c%d:", chip_index);
> > +	if (thread_index >= 0)
> > +		n += sprintf(bufp + n, "t%d:", thread_index);
> > +
> > +	return strdup(result);
> > +}
> > +
> > +int target_inject_error(struct pdbg_target *target, uint32_t scom_addr,
> > +							uint64_t val)
> > +{
> > +	char *short_path;
> > +	int rc;
> > +
> > +	rc = pib_write(target, scom_addr, val);
> > +	if (rc)
> > +		return rc;
> > +
> > +	short_path = target_short_path(target);
> > +	printf("%s 0x%x = 0x%016llx\n", short_path, scom_addr, val);
> > +	free(short_path);
> > +	return 0;
> > +}
> > +
> >  static void error_inject_init(void)
> >  {
> >  	/* Call error inject init routines. */
> > +	timefac_err_init();
> >  }
> >  
> >  static int inject(char *component, char *error)
> > diff --git a/src/err_inject.h b/src/err_inject.h
> > index 76acee7..d295470 100644
> > --- a/src/err_inject.h
> > +++ b/src/err_inject.h
> > @@ -3,6 +3,12 @@
> >  
> >  #include <stdint.h>
> >  #include <stdbool.h>
> > +#include <libpdbg.h>
> > +
> > +/* Target types */
> > +#define TARGET_TYPE_PROC	1
> > +#define TARGET_TYPE_CORE	2
> > +#define TARGET_TYPE_THREAD	3
> >  
> >  typedef int (*inject_error_t)(struct pdbg_target *target, void *data);
> >  
> > @@ -17,4 +23,41 @@ typedef int (*inject_error_t)(struct pdbg_target *target, void *data);
> >   */
> >  extern int register_error_inject(char *component, char *error,
> >  			char *error_desc, inject_error_t func, void *data);
> > +
> > +/* Get target type */
> > +static inline int get_target_type(struct pdbg_target *target)
> > +{
> > +	const char *classname;
> > +
> > +	classname = pdbg_target_class_name(target);
> > +	if (!strcmp(classname, "pib"))
> > +		return TARGET_TYPE_PROC;
> > +
> > +	if (!strcmp(classname, "core"))
> > +		return TARGET_TYPE_CORE;
> > +
> > +	if (!strcmp(classname, "thread"))
> > +		return TARGET_TYPE_THREAD;
> > +
> > +	return 0;
> > +}
> > +
> > +/**
> > + * @brief Inject an error on specified target using scom addr/value.
> > + * @param[in] target     pdbg target where error to be injected.
> > + * @param[in] scom_adddr SCOM address to use.
> > + * @param[in] val        Value to set for a given scom address.
> > + *
> > + * This function uses pib_write() to write to scom address and on
> > + * successfull injection it prints out target short path along with
> > + * scom address and data written.
> > + * e.g.
> > + *	p0:c1:t3: 0x20010a84 = 0x001e000000000000
> > + */
> > +int target_inject_error(struct pdbg_target *target, uint32_t scom_addr,
> > +							uint64_t val);
> > +
> > +/* Error inject init functions */
> > +extern void timefac_err_init(void);
> > +
> >  #endif
> > diff --git a/src/timefac_error.c b/src/timefac_error.c
> > new file mode 100644
> > index 0000000..cb6c9ac
> > --- /dev/null
> > +++ b/src/timefac_error.c
> > @@ -0,0 +1,114 @@
> > +/* Copyright 2020 IBM Corp.
> > + *
> > + * Licensed under the Apache License, Version 2.0 (the "License");
> > + * you may not use this file except in compliance with the License.
> > + * You may obtain a copy of the License at
> > + *
> > + *	http://www.apache.org/licenses/LICENSE-2.0
> > + *
> > + * Unless required by applicable law or agreed to in writing, software
> > + * distributed under the License is distributed on an "AS IS" BASIS,
> > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> > + * implied.
> > + * See the License for the specific language governing permissions and
> > + * limitations under the License.
> > + */
> > +#include <errno.h>
> > +#include <inttypes.h>
> > +#include <stdio.h>
> > +#include <stdlib.h>
> > +#include <string.h>
> > +#include <assert.h>
> > +
> > +#include <libpdbg.h>
> > +#include <ccan/list/list.h>
> > +#include <ccan/array_size/array_size.h>
> > +#include <bitutils.h>
> > +
> > +#include "main.h"
> > +#include "optcmd.h"
> > +#include "path.h"
> > +#include "err_inject.h"
> > +
> > +/* SPR_MODE scom address */
> > +#define P9_SCOM_SPR_MODE	0x20010A84
> > +
> > +/* TB Errors */
> > +#define TB_ERROR_MASK		PPC_BITMASK(10, 15)
> > +/* Core level TB errors */
> > +#define TB_ERROR_TFMR_PARITY	0x1
> > +#define TB_ERROR_HDEC_PARITY	0x2
> > +#define TB_ERROR_TB_PARITY	0x3
> > +/* Thread level TB errors */
> > +#define TB_ERROR_PURR_PARITY	0x4
> > +#define TB_ERROR_SPURR_PARITY	0x5
> > +#define TB_ERROR_DEC_PARITY	0x6
> > +
> > +typedef struct error_type {
> > +	char *name;
> > +	char *desc;
> > +	uint64_t error;
> > +} error_type_t;
> > +
> > +static error_type_t tb_error_type[] = {
> > +	{ "tfmr_parity", "TFMR parity error", TB_ERROR_TFMR_PARITY },
> > +	{ "hdec_parity", "HDEC parity error", TB_ERROR_HDEC_PARITY },
> > +	{ "tb_residue", "TB parity/residue error", TB_ERROR_TB_PARITY },
> > +	{ "purr_parity", "PURR parity error", TB_ERROR_PURR_PARITY },
> > +	{ "spurr_parity", "SPURR parity error", TB_ERROR_SPURR_PARITY },
> > +	{ "dec_parity", "DEC parity error", TB_ERROR_DEC_PARITY },
> > +};
> > +
> > +static int timefac_inject_tb_error(struct pdbg_target *target, void *data)
> > +{
> > +	int target_type = 0;
> > +	uint64_t err_type;
> > +	uint64_t val;
> > +	uint64_t tindex;
> > +	int rc;
> > +
> > +	err_type = *((uint64_t *)data);
> > +	if (err_type < TB_ERROR_PURR_PARITY)
> > +		target_type = TARGET_TYPE_CORE;
> > +	else
> > +		target_type = TARGET_TYPE_THREAD;
> > +
> > +	if (target_type != get_target_type(target))
> > +		return -EINVAL;
> > +
> > +	/*
> > +	 * TODO: Add a check for proc type p8/p9/p10 and then use scom
> > +	 *       address appropriately.
> > +	 */
> > +	rc = pib_read(target, P9_SCOM_SPR_MODE, &val);
> > +	if (rc) {
> > +		/* just print the error message and continue. */
> > +		printf("Failed to read scom addr: %x\n", P9_SCOM_SPR_MODE);
> > +		val = 0;
> > +	}
> > +
> > +	/* set the error type and thread index where error to be injected */
> > +	if (target_type == TARGET_TYPE_THREAD) {
> > +		tindex = pdbg_target_index(target);
> > +		err_type |= (tindex << 3);
> > +	}
> > +	val = SETFIELD(TB_ERROR_MASK, val, err_type);
> > +
> > +	rc = target_inject_error(target, P9_SCOM_SPR_MODE, val);
> > +	if (rc) {
> > +		printf("Failed to inject\n");
> > +	}
> > +	return rc;
> > +}
> > +
> > +void timefac_err_init(void)
> > +{
> > +	int i;
> > +
> > +	/* Register Tb error injects. */
> > +	for (i = 0; i < ARRAY_SIZE(tb_error_type); i++)
> > +		register_error_inject("tb", tb_error_type[i].name,
> > +				tb_error_type[i].desc, timefac_inject_tb_error,
> > +				&tb_error_type[i].error);
> > +
> > +}
> > 
> > 

-- 
Mahesh J Salgaonkar


More information about the Pdbg mailing list