|  | // SPDX-License-Identifier: GPL-2.0 | 
|  |  | 
|  | /* | 
|  | * Copyright (C) 2015 Intel Corporation | 
|  | * Author: Tony Luck | 
|  | * | 
|  | * This software may be redistributed and/or modified under the terms of | 
|  | * the GNU General Public License ("GPL") version 2 only as published by the | 
|  | * Free Software Foundation. | 
|  | */ | 
|  |  | 
|  | /* | 
|  | * Allocate memory - use EINJ to inject a bunch of soft errors, | 
|  | * then consume them all as fast a possible. | 
|  | */ | 
|  |  | 
|  | #include "einj.h" | 
|  |  | 
|  | extern unsigned long long vtop(unsigned long long addr, pid_t pid); | 
|  | volatile int trigger; | 
|  | char *progname; | 
|  | long pagesize; | 
|  | int Sflag; | 
|  |  | 
|  | #define	BUFSZ	(64 * 1024) | 
|  |  | 
|  | static void inject(int nerrors, double interval) | 
|  | { | 
|  | char	*b, *buf; | 
|  | long long paddr; | 
|  | int	i; | 
|  | unsigned long s, e; | 
|  | int	bufsz = nerrors * 4096; | 
|  | pid_t pid; | 
|  |  | 
|  | pid = getpid(); | 
|  | buf = malloc(bufsz); | 
|  | if (buf == NULL) { | 
|  | perror("malloc"); | 
|  | exit(1); | 
|  | } | 
|  | memset(buf, '*', bufsz); | 
|  |  | 
|  | for (i = 0; i < nerrors; i++) { | 
|  | b = buf + i * 4096; | 
|  | paddr = vtop((unsigned long long)b, pid); | 
|  |  | 
|  | printf("%d: vaddr = %p paddr = %llx\n", i, b, paddr); | 
|  | wfile(EINJ_ADDR, paddr); | 
|  | wfile(EINJ_DOIT, 1); | 
|  |  | 
|  | /* wait a bit to make sure SMI is all done on all cpus */ | 
|  | usleep((int)(interval * 1.0e6)); | 
|  | } | 
|  |  | 
|  |  | 
|  | /* Trigger error by reading from target location */ | 
|  | for (i = 0; i < bufsz; i++) | 
|  | trigger += *(buf + i); | 
|  |  | 
|  | /* wait a bit to allow CMCI handlers to complete */ | 
|  | usleep((int)(interval * 1.0e6)); | 
|  | } | 
|  |  | 
|  | int main(int argc, char **argv) | 
|  | { | 
|  | int nerrors = (argc > 1) ? atoi(argv[1]) : 20; | 
|  | double interval = (argc > 2) ? atof(argv[2]) : 1.0; | 
|  |  | 
|  | progname = argv[0]; | 
|  |  | 
|  | wfile(EINJ_ETYPE, 0x8); | 
|  | wfile(EINJ_MASK, ~0x0ul); | 
|  | wfile(EINJ_NOTRIGGER, 1); | 
|  |  | 
|  | inject(nerrors, interval); | 
|  |  | 
|  | return 0; | 
|  | } |