⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 err_inject.txt

📁 linux 内核源代码
💻 TXT
📖 第 1 页 / 共 2 页
字号:
	sprintf(fn, "%s/status", path);	if (rd("status", (u64*)&status)<0) {		perror("status reading error.\n");		return -1;	}	printf("status=%d\n", status);	sprintf(fn, "%s/capabilities", path);	if (rd(fn,&capabilities)<0) {		perror("capabilities reading error.\n");		return -1;	}	printf("capabilities=%lx\n", capabilities);	sprintf(fn, "%s/resources", path);	if (rd(fn, &resources)<0) {		perror("resources reading error.\n");		return -1;	}	printf("resources=%lx\n", resources);	return 0;}int query_capabilities(char *path, err_type_info_t err_type_info,			u64 *capabilities){	char fn[MAX_FN_SIZE];	err_struct_info_t err_struct_info;	err_data_buffer_t err_data_buffer;	err_struct_info.err_struct_info=0;	memset(err_data_buffer.err_data_buffer, -1, ERR_DATA_BUFFER_SIZE*8);	sprintf(fn, "%s/err_type_info", path);	wr(fn, err_type_info.err_type_info);	sprintf(fn, "%s/err_struct_info", path);	wr(fn, 0x0);	sprintf(fn, "%s/err_data_buffer", path);	wr_multi(fn, err_data_buffer.err_data_buffer, ERR_DATA_BUFFER_SIZE);	// Fire pal_mc_error_inject procedure.	sprintf(fn, "%s/call_start", path);	wr(fn, mode);	if (rd_capabilities(path, capabilities)<0)		return -1;	return 0;}int query_all_capabilities(){	int status;	err_type_info_t err_type_info;	int err_sev, err_struct, struct_hier;	int cap=0;	u64 capabilities;	char path[MAX_FN_SIZE];	err_type_info.err_type_info=0;			// Initial	err_type_info.err_type_info_u.mode=0;		// Query mode;	err_type_info.err_type_info_u.err_inj=0;	printf("All capabilities implemented in pal_mc_error_inject:\n");	sprintf(path, PATH_FORMAT ,0);	for (err_sev=0;err_sev<3;err_sev++)		for (err_struct=0;err_struct<5;err_struct++)			for (struct_hier=0;struct_hier<5;struct_hier++)	{		status=-1;		capabilities=0;		err_type_info.err_type_info_u.err_sev=err_sev;		err_type_info.err_type_info_u.err_struct=err_struct;		err_type_info.err_type_info_u.struct_hier=struct_hier;		if (query_capabilities(path, err_type_info, &capabilities)<0)			continue;		if (rd_status(path, &status)<0)			continue;		if (status==0) {			cap=1;			printf("For err_sev=%d, err_struct=%d, struct_hier=%d: ",				err_sev, err_struct, struct_hier);			printf("capabilities 0x%lx\n", capabilities);		}	}	if (!cap) {		printf("No capabilities supported.\n");		return 0;	}	return 0;}int err_inject(int cpu, char *path, err_type_info_t err_type_info,		err_struct_info_t err_struct_info,		err_data_buffer_t err_data_buffer){	int status;	char fn[MAX_FN_SIZE];	log_info(cpu, "err_type_info=%lx, err_struct_info=%lx, ",		err_type_info.err_type_info,		err_struct_info.err_struct_info);	log_info(cpu,"err_data_buffer=[%lx,%lx,%lx]\n",		err_data_buffer.err_data_buffer[0],		err_data_buffer.err_data_buffer[1],		err_data_buffer.err_data_buffer[2]);	sprintf(fn, "%s/err_type_info", path);	wr(fn, err_type_info.err_type_info);	sprintf(fn, "%s/err_struct_info", path);	wr(fn, err_struct_info.err_struct_info);	sprintf(fn, "%s/err_data_buffer", path);	wr_multi(fn, err_data_buffer.err_data_buffer, ERR_DATA_BUFFER_SIZE);	// Fire pal_mc_error_inject procedure.	sprintf(fn, "%s/call_start", path);	wr(fn,mode);	if (rd_status(path, &status)<0) {		vbprintf("fail: read status\n");		return -100;	}	if (status!=0) {		log_info(cpu, "fail: status=%d\n", status);		return status;	}	return status;}static int construct_data_buf(char *path, err_type_info_t err_type_info,		err_struct_info_t err_struct_info,		err_data_buffer_t *err_data_buffer,		void *va1){	char fn[MAX_FN_SIZE];	u64 virt_addr=0, phys_addr=0;	vbprintf("va1=%lx\n", (u64)va1);	memset(&err_data_buffer->err_data_buffer_cache, 0, ERR_DATA_BUFFER_SIZE*8);	switch (err_type_info.err_type_info_u.err_struct) {		case 1: // Cache			switch (err_struct_info.err_struct_info_cache.cl_id) {				case 1: //Virtual addr					err_data_buffer->err_data_buffer_cache.inj_addr=(u64)va1;					break;				case 2: //Phys addr					sprintf(fn, "%s/virtual_to_phys", path);					virt_addr=(u64)va1;					if (wr(fn,virt_addr)<0)						return -1;					rd(fn, &phys_addr);					err_data_buffer->err_data_buffer_cache.inj_addr=phys_addr;					break;				default:					printf("Not supported cl_id\n");					break;			}			break;		case 2: //  TLB			break;		case 3: //  Register file			break;		case 4: //  Bus/system interconnect		default:			printf("Not supported err_struct\n");			break;	}	return 0;}typedef struct {	u64 cpu;	u64 loop;	u64 interval;	u64 err_type_info;	u64 err_struct_info;	u64 err_data_buffer[ERR_DATA_BUFFER_SIZE];} parameters_t;parameters_t line_para;int para;static int empty_data_buffer(u64 *err_data_buffer){	int empty=1;	int i;	for (i=0;i<ERR_DATA_BUFFER_SIZE; i++)	   if (err_data_buffer[i]!=-1)		empty=0;	return empty;}int err_inj(){	err_type_info_t err_type_info;	err_struct_info_t err_struct_info;	err_data_buffer_t err_data_buffer;	int count;	FILE *fp;	unsigned long cpu, loop, interval, err_type_info_conf, err_struct_info_conf;	u64 err_data_buffer_conf[ERR_DATA_BUFFER_SIZE];	int num;	int i;	char path[MAX_FN_SIZE];	parameters_t parameters[MAX_TASK_NUM]={};	pid_t child_pid[MAX_TASK_NUM];	time_t current_time;	int status;	if (!para) {	    fp=fopen("err.conf", "r");	    if (fp==NULL) {		perror("Error open err.conf");		return -1;	    }	    num=0;	    while (!feof(fp)) {		char buf[256];		memset(buf,0,256);		fgets(buf, 256, fp);		count=sscanf(buf, "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx\n",				&cpu, &loop, &interval,&err_type_info_conf,				&err_struct_info_conf,				&err_data_buffer_conf[0],				&err_data_buffer_conf[1],				&err_data_buffer_conf[2]);		if (count!=PARA_FIELD_NUM+3) {			err_data_buffer_conf[0]=-1;			err_data_buffer_conf[1]=-1;			err_data_buffer_conf[2]=-1;			count=sscanf(buf, "%lx, %lx, %lx, %lx, %lx\n",				&cpu, &loop, &interval,&err_type_info_conf,				&err_struct_info_conf);			if (count!=PARA_FIELD_NUM)				continue;		}		parameters[num].cpu=cpu;		parameters[num].loop=loop;		parameters[num].interval= interval>MIN_INTERVAL					  ?interval:MIN_INTERVAL;		parameters[num].err_type_info=err_type_info_conf;		parameters[num].err_struct_info=err_struct_info_conf;		memcpy(parameters[num++].err_data_buffer,			err_data_buffer_conf,ERR_DATA_BUFFER_SIZE*8) ;		if (num>=MAX_TASK_NUM)			break;	    }	}	else {		parameters[0].cpu=line_para.cpu;		parameters[0].loop=line_para.loop;		parameters[0].interval= line_para.interval>MIN_INTERVAL					  ?line_para.interval:MIN_INTERVAL;		parameters[0].err_type_info=line_para.err_type_info;		parameters[0].err_struct_info=line_para.err_struct_info;		memcpy(parameters[0].err_data_buffer,			line_para.err_data_buffer,ERR_DATA_BUFFER_SIZE*8) ;		num=1;	}	/* Create semaphore: If one_lock, one semaphore for all processors.	   Otherwise, one semaphore for each processor. */	if (one_lock) {		if (create_sem(0)) {			printf("Can not create semaphore...exit\n");			free_sem(0);			return -1;		}	}	else {		for (i=0;i<num;i++) {		   if (create_sem(parameters[i].cpu)) {			printf("Can not create semaphore for cpu%d...exit\n",i);			free_sem(parameters[num].cpu);			return -1;		   }		}	}	/* Create a shm segment which will be used to inject/consume errors on.*/	if (create_shm()==-1) {		printf("Error to create shm...exit\n");		return -1;	}	for (i=0;i<num;i++) {		pid_t pid;		current_time=time(NULL);		log_info(parameters[i].cpu, "\nBegine at %s", ctime(&current_time));		log_info(parameters[i].cpu, "Configurations:\n");		log_info(parameters[i].cpu,"On cpu%ld: loop=%lx, interval=%lx(s)",			parameters[i].cpu,			parameters[i].loop,			parameters[i].interval);		log_info(parameters[i].cpu," err_type_info=%lx,err_struct_info=%lx\n",			parameters[i].err_type_info,			parameters[i].err_struct_info);		sprintf(path, PATH_FORMAT, (int)parameters[i].cpu);		err_type_info.err_type_info=parameters[i].err_type_info;		err_struct_info.err_struct_info=parameters[i].err_struct_info;		memcpy(err_data_buffer.err_data_buffer,			parameters[i].err_data_buffer,			ERR_DATA_BUFFER_SIZE*8);		pid=fork();		if (pid==0) {			unsigned long mask[MASK_SIZE];			int j, k;			void *va1, *va2;			/* Allocate two memory areas va1 and va2 in shm */			va1=shmaddr+parameters[i].cpu*PAGE_SIZE;			va2=shmaddr+parameters[i].cpu*PAGE_SIZE+PAGE_SIZE;			vbprintf("va1=%lx, va2=%lx\n", (u64)va1, (u64)va2);			memset(va1, 0x1, PAGE_SIZE);			memset(va2, 0x2, PAGE_SIZE);			if (empty_data_buffer(err_data_buffer.err_data_buffer))				/* If not specified yet, construct data buffer				 * with va1				 */				construct_data_buf(path, err_type_info,					err_struct_info, &err_data_buffer,va1);			for (j=0;j<MASK_SIZE;j++)				mask[j]=0;			cpu=parameters[i].cpu;			k = cpu%64;			j = cpu/64;			mask[j]=1<<k;			if (sched_setaffinity(0, MASK_SIZE*8, mask)==-1) {				perror("Error sched_setaffinity:");				return -1;			}			for (j=0; j<parameters[i].loop; j++) {				log_info(parameters[i].cpu,"Injection ");				log_info(parameters[i].cpu,"on cpu%ld: #%d/%ld ",					parameters[i].cpu,j+1, parameters[i].loop);				/* Hold the lock */				if (one_lock)					lock(0);				else				/* Hold lock on this cpu */					lock(parameters[i].cpu);				if ((status=err_inject(parameters[i].cpu,					   path, err_type_info,					   err_struct_info, err_data_buffer))					   ==0) {					/* consume the error for "inject only"*/					memcpy(va2, va1, PAGE_SIZE);					memcpy(va1, va2, PAGE_SIZE);					log_info(parameters[i].cpu,						"successful\n");				}				else {					log_info(parameters[i].cpu,"fail:");					log_info(parameters[i].cpu,						"status=%d\n", status);					unlock(parameters[i].cpu);					break;				}				if (one_lock)				/* Release the lock */					unlock(0);				/* Release lock on this cpu */				else					unlock(parameters[i].cpu);				if (j < parameters[i].loop-1)					sleep(parameters[i].interval);			}			current_time=time(NULL);			log_info(parameters[i].cpu, "Done at %s", ctime(&current_time));			return 0;		}		else if (pid<0) {			perror("Error fork:");			continue;		}		child_pid[i]=pid;	}	for (i=0;i<num;i++)		waitpid(child_pid[i], NULL, 0);	if (one_lock)		free_sem(0);	else		for (i=0;i<num;i++)			free_sem(parameters[i].cpu);	printf("All done.\n");	return 0;}void help(){	printf("err_inject_tool:\n");	printf("\t-q: query all capabilities. default: off\n");	printf("\t-m: procedure mode. 1: physical 2: virtual. default: 1\n");	printf("\t-i: inject errors. default: off\n");	printf("\t-l: one lock per cpu. default: one lock for all\n");	printf("\t-e: error parameters:\n");	printf("\t\tcpu,loop,interval,err_type_info,err_struct_info[,err_data_buffer[0],err_data_buffer[1],err_data_buffer[2]]\n");	printf("\t\t   cpu: logical cpu number the error will be inject in.\n");	printf("\t\t   loop: times the error will be injected.\n");	printf("\t\t   interval: In second. every so often one error is injected.\n");	printf("\t\t   err_type_info, err_struct_info: PAL parameters.\n");	printf("\t\t   err_data_buffer: PAL parameter. Optional. If not present,\n");	printf("\t\t                    it's constructed by tool automatically. Be\n");	printf("\t\t                    careful to provide err_data_buffer and make\n");	printf("\t\t                    sure it's working with the environment.\n");	printf("\t    Note:no space between error parameters.\n");	printf("\t    default: Take error parameters from err.conf instead of command line.\n");	printf("\t-v: verbose. default: off\n");	printf("\t-h: help\n\n");	printf("The tool will take err.conf file as ");	printf("input to inject single or multiple errors ");	printf("on one or multiple cpus in parallel.\n");}int main(int argc, char **argv){	char c;	int do_err_inj=0;	int do_query_all=0;	int count;	u32 m;	/* Default one lock for all cpu's */	one_lock=1;	while ((c = getopt(argc, argv, "m:iqvhle:")) != EOF)		switch (c) {			case 'm':	/* Procedure mode. 1: phys 2: virt */				count=sscanf(optarg, "%x", &m);				if (count!=1 || (m!=1 && m!=2)) {					printf("Wrong mode number.\n");					help();					return -1;				}				mode=m;				break;			case 'i':	/* Inject errors */				do_err_inj=1;				break;			case 'q':	/* Query */				do_query_all=1;				break;			case 'v':	/* Verbose */				verbose=1;				break;			case 'l':	/* One lock per cpu */				one_lock=0;				break;			case 'e':	/* error arguments */				/* Take parameters:				 * #cpu, loop, interval, err_type_info, err_struct_info[, err_data_buffer]				 * err_data_buffer is optional. Recommend not to specify				 * err_data_buffer. Better to use tool to generate it.				 */				count=sscanf(optarg,					"%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx\n",					&line_para.cpu,					&line_para.loop,					&line_para.interval,					&line_para.err_type_info,					&line_para.err_struct_info,					&line_para.err_data_buffer[0],					&line_para.err_data_buffer[1],					&line_para.err_data_buffer[2]);				if (count!=PARA_FIELD_NUM+3) {				    line_para.err_data_buffer[0]=-1,				    line_para.err_data_buffer[1]=-1,			 	    line_para.err_data_buffer[2]=-1;				    count=sscanf(optarg, "%lx, %lx, %lx, %lx, %lx\n",						&line_para.cpu,						&line_para.loop,						&line_para.interval,						&line_para.err_type_info,						&line_para.err_struct_info);				    if (count!=PARA_FIELD_NUM) {					printf("Wrong error arguments.\n");					help();					return -1;				    }				}				para=1;				break;			continue;				break;			case 'h':				help();				return 0;			default:				break;		}	if (do_query_all)		query_all_capabilities();	if (do_err_inj)		err_inj();	if (!do_query_all &&  !do_err_inj)		help();	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -