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

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


On 2020-05-26 16:21:44 Tue, Alistair Popple wrote:
> Sorry, I meant to get to this earlier but Nick's idea seems worth 
> investigating. We could add ->inject_error and ->inject_error_list to the 
> struct pdbg_target which would allow us to add recipes for injecting errors on 
> any target that supports them which would be nice.

Yup I agree. I was on leave last week. I will take look and try to hook
this into target (struct pdbg_target ) itself.

Thanks,
-Mahesh.

> 
> - Alistair
> 
> On Tuesday, 26 May 2020 4:18:21 PM AEST Mahesh J Salgaonkar wrote:
> > 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