Linux Audio

Check our new training course

Loading...
v3.5.6
 
  1/*
  2 * APEI Error INJection support
  3 *
  4 * EINJ provides a hardware error injection mechanism, this is useful
  5 * for debugging and testing of other APEI and RAS features.
  6 *
  7 * For more information about EINJ, please refer to ACPI Specification
  8 * version 4.0, section 17.5.
  9 *
 10 * Copyright 2009-2010 Intel Corp.
 11 *   Author: Huang Ying <ying.huang@intel.com>
 12 *
 13 * This program is free software; you can redistribute it and/or
 14 * modify it under the terms of the GNU General Public License version
 15 * 2 as published by the Free Software Foundation.
 16 *
 17 * This program is distributed in the hope that it will be useful,
 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 20 * GNU General Public License for more details.
 21 *
 22 * You should have received a copy of the GNU General Public License
 23 * along with this program; if not, write to the Free Software
 24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 25 */
 26
 27#include <linux/kernel.h>
 28#include <linux/module.h>
 29#include <linux/init.h>
 30#include <linux/io.h>
 31#include <linux/debugfs.h>
 32#include <linux/seq_file.h>
 33#include <linux/nmi.h>
 34#include <linux/delay.h>
 35#include <acpi/acpi.h>
 
 36
 37#include "apei-internal.h"
 38
 39#define EINJ_PFX "EINJ: "
 
 40
 41#define SPIN_UNIT		100			/* 100ns */
 42/* Firmware should respond within 1 milliseconds */
 43#define FIRMWARE_TIMEOUT	(1 * NSEC_PER_MSEC)
 
 
 
 
 
 44
 45/*
 46 * ACPI version 5 provides a SET_ERROR_TYPE_WITH_ADDRESS action.
 47 */
 48static int acpi5;
 49
 50struct set_error_type_with_address {
 51	u32	type;
 52	u32	vendor_extension;
 53	u32	flags;
 54	u32	apicid;
 55	u64	memory_address;
 56	u64	memory_address_range;
 57	u32	pcie_sbdf;
 58};
 59enum {
 60	SETWA_FLAGS_APICID = 1,
 61	SETWA_FLAGS_MEM = 2,
 62	SETWA_FLAGS_PCIE_SBDF = 4,
 63};
 64
 65/*
 66 * Vendor extensions for platform specific operations
 67 */
 68struct vendor_error_type_extension {
 69	u32	length;
 70	u32	pcie_sbdf;
 71	u16	vendor_id;
 72	u16	device_id;
 73	u8	rev_id;
 74	u8	reserved[3];
 75};
 76
 77static u32 notrigger;
 78
 79static u32 vendor_flags;
 80static struct debugfs_blob_wrapper vendor_blob;
 
 81static char vendor_dev[64];
 82
 83/*
 84 * Some BIOSes allow parameters to the SET_ERROR_TYPE entries in the
 85 * EINJ table through an unpublished extension. Use with caution as
 86 * most will ignore the parameter and make their own choice of address
 87 * for error injection.  This extension is used only if
 88 * param_extension module parameter is specified.
 89 */
 90struct einj_parameter {
 91	u64 type;
 92	u64 reserved1;
 93	u64 reserved2;
 94	u64 param1;
 95	u64 param2;
 96};
 97
 98#define EINJ_OP_BUSY			0x1
 99#define EINJ_STATUS_SUCCESS		0x0
100#define EINJ_STATUS_FAIL		0x1
101#define EINJ_STATUS_INVAL		0x2
102
103#define EINJ_TAB_ENTRY(tab)						\
104	((struct acpi_whea_header *)((char *)(tab) +			\
105				    sizeof(struct acpi_table_einj)))
106
107static bool param_extension;
108module_param(param_extension, bool, 0);
109
110static struct acpi_table_einj *einj_tab;
111
112static struct apei_resources einj_resources;
113
114static struct apei_exec_ins_type einj_ins_type[] = {
115	[ACPI_EINJ_READ_REGISTER] = {
116		.flags = APEI_EXEC_INS_ACCESS_REGISTER,
117		.run   = apei_exec_read_register,
118	},
119	[ACPI_EINJ_READ_REGISTER_VALUE] = {
120		.flags = APEI_EXEC_INS_ACCESS_REGISTER,
121		.run   = apei_exec_read_register_value,
122	},
123	[ACPI_EINJ_WRITE_REGISTER] = {
124		.flags = APEI_EXEC_INS_ACCESS_REGISTER,
125		.run   = apei_exec_write_register,
126	},
127	[ACPI_EINJ_WRITE_REGISTER_VALUE] = {
128		.flags = APEI_EXEC_INS_ACCESS_REGISTER,
129		.run   = apei_exec_write_register_value,
130	},
131	[ACPI_EINJ_NOOP] = {
132		.flags = 0,
133		.run   = apei_exec_noop,
134	},
135};
136
137/*
138 * Prevent EINJ interpreter to run simultaneously, because the
139 * corresponding firmware implementation may not work properly when
140 * invoked simultaneously.
141 */
142static DEFINE_MUTEX(einj_mutex);
143
144static void *einj_param;
145
146static void einj_exec_ctx_init(struct apei_exec_context *ctx)
147{
148	apei_exec_ctx_init(ctx, einj_ins_type, ARRAY_SIZE(einj_ins_type),
149			   EINJ_TAB_ENTRY(einj_tab), einj_tab->entries);
150}
151
152static int __einj_get_available_error_type(u32 *type)
153{
154	struct apei_exec_context ctx;
155	int rc;
156
157	einj_exec_ctx_init(&ctx);
158	rc = apei_exec_run(&ctx, ACPI_EINJ_GET_ERROR_TYPE);
159	if (rc)
160		return rc;
161	*type = apei_exec_ctx_get_output(&ctx);
162
163	return 0;
164}
165
166/* Get error injection capabilities of the platform */
167static int einj_get_available_error_type(u32 *type)
168{
169	int rc;
170
171	mutex_lock(&einj_mutex);
172	rc = __einj_get_available_error_type(type);
173	mutex_unlock(&einj_mutex);
174
175	return rc;
176}
177
178static int einj_timedout(u64 *t)
179{
180	if ((s64)*t < SPIN_UNIT) {
181		pr_warning(FW_WARN EINJ_PFX
182			   "Firmware does not respond in time\n");
183		return 1;
184	}
185	*t -= SPIN_UNIT;
186	ndelay(SPIN_UNIT);
187	touch_nmi_watchdog();
188	return 0;
189}
190
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191static void check_vendor_extension(u64 paddr,
192				   struct set_error_type_with_address *v5param)
193{
194	int	offset = v5param->vendor_extension;
195	struct	vendor_error_type_extension *v;
196	u32	sbdf;
197
198	if (!offset)
199		return;
200	v = acpi_os_map_memory(paddr + offset, sizeof(*v));
201	if (!v)
202		return;
 
203	sbdf = v->pcie_sbdf;
204	sprintf(vendor_dev, "%x:%x:%x.%x vendor_id=%x device_id=%x rev_id=%x\n",
205		sbdf >> 24, (sbdf >> 16) & 0xff,
206		(sbdf >> 11) & 0x1f, (sbdf >> 8) & 0x7,
207		 v->vendor_id, v->device_id, v->rev_id);
208	acpi_os_unmap_memory(v, sizeof(*v));
209}
210
211static void *einj_get_parameter_address(void)
212{
213	int i;
214	u64 paddrv4 = 0, paddrv5 = 0;
215	struct acpi_whea_header *entry;
216
217	entry = EINJ_TAB_ENTRY(einj_tab);
218	for (i = 0; i < einj_tab->entries; i++) {
219		if (entry->action == ACPI_EINJ_SET_ERROR_TYPE &&
220		    entry->instruction == ACPI_EINJ_WRITE_REGISTER &&
221		    entry->register_region.space_id ==
222		    ACPI_ADR_SPACE_SYSTEM_MEMORY)
223			memcpy(&paddrv4, &entry->register_region.address,
224			       sizeof(paddrv4));
225		if (entry->action == ACPI_EINJ_SET_ERROR_TYPE_WITH_ADDRESS &&
226		    entry->instruction == ACPI_EINJ_WRITE_REGISTER &&
227		    entry->register_region.space_id ==
228		    ACPI_ADR_SPACE_SYSTEM_MEMORY)
229			memcpy(&paddrv5, &entry->register_region.address,
230			       sizeof(paddrv5));
231		entry++;
232	}
233	if (paddrv5) {
234		struct set_error_type_with_address *v5param;
235
236		v5param = acpi_os_map_memory(paddrv5, sizeof(*v5param));
237		if (v5param) {
238			acpi5 = 1;
239			check_vendor_extension(paddrv5, v5param);
240			return v5param;
241		}
242	}
243	if (param_extension && paddrv4) {
244		struct einj_parameter *v4param;
245
246		v4param = acpi_os_map_memory(paddrv4, sizeof(*v4param));
247		if (!v4param)
248			return NULL;
249		if (v4param->reserved1 || v4param->reserved2) {
250			acpi_os_unmap_memory(v4param, sizeof(*v4param));
251			return NULL;
252		}
253		return v4param;
254	}
255
256	return NULL;
257}
258
259/* do sanity check to trigger table */
260static int einj_check_trigger_header(struct acpi_einj_trigger *trigger_tab)
261{
262	if (trigger_tab->header_size != sizeof(struct acpi_einj_trigger))
263		return -EINVAL;
264	if (trigger_tab->table_size > PAGE_SIZE ||
265	    trigger_tab->table_size < trigger_tab->header_size)
266		return -EINVAL;
267	if (trigger_tab->entry_count !=
268	    (trigger_tab->table_size - trigger_tab->header_size) /
269	    sizeof(struct acpi_einj_entry))
270		return -EINVAL;
271
272	return 0;
273}
274
275static struct acpi_generic_address *einj_get_trigger_parameter_region(
276	struct acpi_einj_trigger *trigger_tab, u64 param1, u64 param2)
277{
278	int i;
279	struct acpi_whea_header *entry;
280
281	entry = (struct acpi_whea_header *)
282		((char *)trigger_tab + sizeof(struct acpi_einj_trigger));
283	for (i = 0; i < trigger_tab->entry_count; i++) {
284		if (entry->action == ACPI_EINJ_TRIGGER_ERROR &&
285		entry->instruction == ACPI_EINJ_WRITE_REGISTER_VALUE &&
286		entry->register_region.space_id ==
287			ACPI_ADR_SPACE_SYSTEM_MEMORY &&
288		(entry->register_region.address & param2) == (param1 & param2))
289			return &entry->register_region;
290		entry++;
291	}
292
293	return NULL;
294}
295/* Execute instructions in trigger error action table */
296static int __einj_error_trigger(u64 trigger_paddr, u32 type,
297				u64 param1, u64 param2)
298{
299	struct acpi_einj_trigger *trigger_tab = NULL;
300	struct apei_exec_context trigger_ctx;
301	struct apei_resources trigger_resources;
302	struct acpi_whea_header *trigger_entry;
303	struct resource *r;
304	u32 table_size;
305	int rc = -EIO;
306	struct acpi_generic_address *trigger_param_region = NULL;
307
308	r = request_mem_region(trigger_paddr, sizeof(*trigger_tab),
309			       "APEI EINJ Trigger Table");
310	if (!r) {
311		pr_err(EINJ_PFX
312	"Can not request [mem %#010llx-%#010llx] for Trigger table\n",
313		       (unsigned long long)trigger_paddr,
314		       (unsigned long long)trigger_paddr +
315			    sizeof(*trigger_tab) - 1);
316		goto out;
317	}
318	trigger_tab = ioremap_cache(trigger_paddr, sizeof(*trigger_tab));
319	if (!trigger_tab) {
320		pr_err(EINJ_PFX "Failed to map trigger table!\n");
321		goto out_rel_header;
322	}
323	rc = einj_check_trigger_header(trigger_tab);
324	if (rc) {
325		pr_warning(FW_BUG EINJ_PFX
326			   "The trigger error action table is invalid\n");
327		goto out_rel_header;
328	}
329
330	/* No action structures in the TRIGGER_ERROR table, nothing to do */
331	if (!trigger_tab->entry_count)
332		goto out_rel_header;
333
334	rc = -EIO;
335	table_size = trigger_tab->table_size;
336	r = request_mem_region(trigger_paddr + sizeof(*trigger_tab),
337			       table_size - sizeof(*trigger_tab),
338			       "APEI EINJ Trigger Table");
339	if (!r) {
340		pr_err(EINJ_PFX
341"Can not request [mem %#010llx-%#010llx] for Trigger Table Entry\n",
342		       (unsigned long long)trigger_paddr + sizeof(*trigger_tab),
343		       (unsigned long long)trigger_paddr + table_size - 1);
344		goto out_rel_header;
345	}
346	iounmap(trigger_tab);
347	trigger_tab = ioremap_cache(trigger_paddr, table_size);
348	if (!trigger_tab) {
349		pr_err(EINJ_PFX "Failed to map trigger table!\n");
350		goto out_rel_entry;
351	}
352	trigger_entry = (struct acpi_whea_header *)
353		((char *)trigger_tab + sizeof(struct acpi_einj_trigger));
354	apei_resources_init(&trigger_resources);
355	apei_exec_ctx_init(&trigger_ctx, einj_ins_type,
356			   ARRAY_SIZE(einj_ins_type),
357			   trigger_entry, trigger_tab->entry_count);
358	rc = apei_exec_collect_resources(&trigger_ctx, &trigger_resources);
359	if (rc)
360		goto out_fini;
361	rc = apei_resources_sub(&trigger_resources, &einj_resources);
362	if (rc)
363		goto out_fini;
364	/*
365	 * Some firmware will access target address specified in
366	 * param1 to trigger the error when injecting memory error.
367	 * This will cause resource conflict with regular memory.  So
368	 * remove it from trigger table resources.
369	 */
370	if (param_extension && (type & 0x0038) && param2) {
371		struct apei_resources addr_resources;
 
372		apei_resources_init(&addr_resources);
373		trigger_param_region = einj_get_trigger_parameter_region(
374			trigger_tab, param1, param2);
375		if (trigger_param_region) {
376			rc = apei_resources_add(&addr_resources,
377				trigger_param_region->address,
378				trigger_param_region->bit_width/8, true);
379			if (rc)
380				goto out_fini;
381			rc = apei_resources_sub(&trigger_resources,
382					&addr_resources);
383		}
384		apei_resources_fini(&addr_resources);
385		if (rc)
386			goto out_fini;
387	}
388	rc = apei_resources_request(&trigger_resources, "APEI EINJ Trigger");
389	if (rc)
390		goto out_fini;
391	rc = apei_exec_pre_map_gars(&trigger_ctx);
392	if (rc)
393		goto out_release;
394
395	rc = apei_exec_run(&trigger_ctx, ACPI_EINJ_TRIGGER_ERROR);
396
397	apei_exec_post_unmap_gars(&trigger_ctx);
398out_release:
399	apei_resources_release(&trigger_resources);
400out_fini:
401	apei_resources_fini(&trigger_resources);
402out_rel_entry:
403	release_mem_region(trigger_paddr + sizeof(*trigger_tab),
404			   table_size - sizeof(*trigger_tab));
405out_rel_header:
406	release_mem_region(trigger_paddr, sizeof(*trigger_tab));
407out:
408	if (trigger_tab)
409		iounmap(trigger_tab);
410
411	return rc;
412}
413
414static int __einj_error_inject(u32 type, u64 param1, u64 param2)
 
415{
416	struct apei_exec_context ctx;
417	u64 val, trigger_paddr, timeout = FIRMWARE_TIMEOUT;
418	int rc;
419
420	einj_exec_ctx_init(&ctx);
421
422	rc = apei_exec_run_optional(&ctx, ACPI_EINJ_BEGIN_OPERATION);
423	if (rc)
424		return rc;
425	apei_exec_ctx_set_input(&ctx, type);
426	if (acpi5) {
427		struct set_error_type_with_address *v5param = einj_param;
428
429		v5param->type = type;
430		if (type & 0x80000000) {
431			switch (vendor_flags) {
432			case SETWA_FLAGS_APICID:
433				v5param->apicid = param1;
434				break;
435			case SETWA_FLAGS_MEM:
436				v5param->memory_address = param1;
437				v5param->memory_address_range = param2;
438				break;
439			case SETWA_FLAGS_PCIE_SBDF:
440				v5param->pcie_sbdf = param1;
441				break;
442			}
443			v5param->flags = vendor_flags;
 
 
 
 
 
 
444		} else {
445			switch (type) {
446			case ACPI_EINJ_PROCESSOR_CORRECTABLE:
447			case ACPI_EINJ_PROCESSOR_UNCORRECTABLE:
448			case ACPI_EINJ_PROCESSOR_FATAL:
449				v5param->apicid = param1;
450				v5param->flags = SETWA_FLAGS_APICID;
451				break;
452			case ACPI_EINJ_MEMORY_CORRECTABLE:
453			case ACPI_EINJ_MEMORY_UNCORRECTABLE:
454			case ACPI_EINJ_MEMORY_FATAL:
455				v5param->memory_address = param1;
456				v5param->memory_address_range = param2;
457				v5param->flags = SETWA_FLAGS_MEM;
458				break;
459			case ACPI_EINJ_PCIX_CORRECTABLE:
460			case ACPI_EINJ_PCIX_UNCORRECTABLE:
461			case ACPI_EINJ_PCIX_FATAL:
462				v5param->pcie_sbdf = param1;
463				v5param->flags = SETWA_FLAGS_PCIE_SBDF;
464				break;
465			}
466		}
467	} else {
468		rc = apei_exec_run(&ctx, ACPI_EINJ_SET_ERROR_TYPE);
469		if (rc)
470			return rc;
471		if (einj_param) {
472			struct einj_parameter *v4param = einj_param;
 
473			v4param->param1 = param1;
474			v4param->param2 = param2;
475		}
476	}
477	rc = apei_exec_run(&ctx, ACPI_EINJ_EXECUTE_OPERATION);
478	if (rc)
479		return rc;
480	for (;;) {
481		rc = apei_exec_run(&ctx, ACPI_EINJ_CHECK_BUSY_STATUS);
482		if (rc)
483			return rc;
484		val = apei_exec_ctx_get_output(&ctx);
485		if (!(val & EINJ_OP_BUSY))
486			break;
487		if (einj_timedout(&timeout))
488			return -EIO;
489	}
490	rc = apei_exec_run(&ctx, ACPI_EINJ_GET_COMMAND_STATUS);
491	if (rc)
492		return rc;
493	val = apei_exec_ctx_get_output(&ctx);
494	if (val != EINJ_STATUS_SUCCESS)
495		return -EBUSY;
 
 
496
 
 
 
 
497	rc = apei_exec_run(&ctx, ACPI_EINJ_GET_TRIGGER_TABLE);
498	if (rc)
499		return rc;
500	trigger_paddr = apei_exec_ctx_get_output(&ctx);
501	if (notrigger == 0) {
502		rc = __einj_error_trigger(trigger_paddr, type, param1, param2);
503		if (rc)
504			return rc;
505	}
506	rc = apei_exec_run_optional(&ctx, ACPI_EINJ_END_OPERATION);
507
508	return rc;
509}
510
511/* Inject the specified hardware error */
512static int einj_error_inject(u32 type, u64 param1, u64 param2)
 
513{
514	int rc;
 
515
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
516	mutex_lock(&einj_mutex);
517	rc = __einj_error_inject(type, param1, param2);
518	mutex_unlock(&einj_mutex);
519
520	return rc;
521}
522
523static u32 error_type;
 
524static u64 error_param1;
525static u64 error_param2;
 
 
526static struct dentry *einj_debug_dir;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
527
528static int available_error_type_show(struct seq_file *m, void *v)
529{
530	int rc;
531	u32 available_error_type = 0;
532
533	rc = einj_get_available_error_type(&available_error_type);
534	if (rc)
535		return rc;
536	if (available_error_type & 0x0001)
537		seq_printf(m, "0x00000001\tProcessor Correctable\n");
538	if (available_error_type & 0x0002)
539		seq_printf(m, "0x00000002\tProcessor Uncorrectable non-fatal\n");
540	if (available_error_type & 0x0004)
541		seq_printf(m, "0x00000004\tProcessor Uncorrectable fatal\n");
542	if (available_error_type & 0x0008)
543		seq_printf(m, "0x00000008\tMemory Correctable\n");
544	if (available_error_type & 0x0010)
545		seq_printf(m, "0x00000010\tMemory Uncorrectable non-fatal\n");
546	if (available_error_type & 0x0020)
547		seq_printf(m, "0x00000020\tMemory Uncorrectable fatal\n");
548	if (available_error_type & 0x0040)
549		seq_printf(m, "0x00000040\tPCI Express Correctable\n");
550	if (available_error_type & 0x0080)
551		seq_printf(m, "0x00000080\tPCI Express Uncorrectable non-fatal\n");
552	if (available_error_type & 0x0100)
553		seq_printf(m, "0x00000100\tPCI Express Uncorrectable fatal\n");
554	if (available_error_type & 0x0200)
555		seq_printf(m, "0x00000200\tPlatform Correctable\n");
556	if (available_error_type & 0x0400)
557		seq_printf(m, "0x00000400\tPlatform Uncorrectable non-fatal\n");
558	if (available_error_type & 0x0800)
559		seq_printf(m, "0x00000800\tPlatform Uncorrectable fatal\n");
560
561	return 0;
562}
563
564static int available_error_type_open(struct inode *inode, struct file *file)
565{
566	return single_open(file, available_error_type_show, NULL);
567}
568
569static const struct file_operations available_error_type_fops = {
570	.open		= available_error_type_open,
571	.read		= seq_read,
572	.llseek		= seq_lseek,
573	.release	= single_release,
574};
575
576static int error_type_get(void *data, u64 *val)
577{
578	*val = error_type;
579
580	return 0;
581}
582
583static int error_type_set(void *data, u64 val)
584{
585	int rc;
586	u32 available_error_type = 0;
587	u32 tval, vendor;
588
 
 
 
 
589	/*
590	 * Vendor defined types have 0x80000000 bit set, and
591	 * are not enumerated by ACPI_EINJ_GET_ERROR_TYPE
592	 */
593	vendor = val & 0x80000000;
594	tval = val & 0x7fffffff;
595
596	/* Only one error type can be specified */
597	if (tval & (tval - 1))
598		return -EINVAL;
599	if (!vendor) {
600		rc = einj_get_available_error_type(&available_error_type);
601		if (rc)
602			return rc;
603		if (!(val & available_error_type))
604			return -EINVAL;
605	}
606	error_type = val;
607
608	return 0;
609}
610
611DEFINE_SIMPLE_ATTRIBUTE(error_type_fops, error_type_get,
612			error_type_set, "0x%llx\n");
613
614static int error_inject_set(void *data, u64 val)
615{
616	if (!error_type)
617		return -EINVAL;
618
619	return einj_error_inject(error_type, error_param1, error_param2);
 
620}
621
622DEFINE_SIMPLE_ATTRIBUTE(error_inject_fops, NULL,
623			error_inject_set, "%llu\n");
624
625static int einj_check_table(struct acpi_table_einj *einj_tab)
626{
627	if ((einj_tab->header_length !=
628	     (sizeof(struct acpi_table_einj) - sizeof(einj_tab->header)))
629	    && (einj_tab->header_length != sizeof(struct acpi_table_einj)))
630		return -EINVAL;
631	if (einj_tab->header.length < sizeof(struct acpi_table_einj))
632		return -EINVAL;
633	if (einj_tab->entries !=
634	    (einj_tab->header.length - sizeof(struct acpi_table_einj)) /
635	    sizeof(struct acpi_einj_entry))
636		return -EINVAL;
637
638	return 0;
639}
640
641static int __init einj_init(void)
642{
643	int rc;
644	acpi_status status;
645	struct dentry *fentry;
646	struct apei_exec_context ctx;
647
648	if (acpi_disabled)
 
649		return -ENODEV;
 
650
651	status = acpi_get_table(ACPI_SIG_EINJ, 0,
652				(struct acpi_table_header **)&einj_tab);
653	if (status == AE_NOT_FOUND)
 
654		return -ENODEV;
655	else if (ACPI_FAILURE(status)) {
656		const char *msg = acpi_format_exception(status);
657		pr_err(EINJ_PFX "Failed to get table, %s\n", msg);
658		return -EINVAL;
659	}
660
661	rc = einj_check_table(einj_tab);
662	if (rc) {
663		pr_warning(FW_BUG EINJ_PFX "EINJ table is invalid\n");
664		return -EINVAL;
665	}
666
667	rc = -ENOMEM;
668	einj_debug_dir = debugfs_create_dir("einj", apei_get_debugfs_dir());
669	if (!einj_debug_dir)
670		goto err_cleanup;
671	fentry = debugfs_create_file("available_error_type", S_IRUSR,
672				     einj_debug_dir, NULL,
673				     &available_error_type_fops);
674	if (!fentry)
675		goto err_cleanup;
676	fentry = debugfs_create_file("error_type", S_IRUSR | S_IWUSR,
677				     einj_debug_dir, NULL, &error_type_fops);
678	if (!fentry)
679		goto err_cleanup;
680	fentry = debugfs_create_file("error_inject", S_IWUSR,
681				     einj_debug_dir, NULL, &error_inject_fops);
682	if (!fentry)
683		goto err_cleanup;
684
685	apei_resources_init(&einj_resources);
686	einj_exec_ctx_init(&ctx);
687	rc = apei_exec_collect_resources(&ctx, &einj_resources);
688	if (rc)
 
689		goto err_fini;
 
 
690	rc = apei_resources_request(&einj_resources, "APEI EINJ");
691	if (rc)
 
692		goto err_fini;
 
 
693	rc = apei_exec_pre_map_gars(&ctx);
694	if (rc)
 
695		goto err_release;
 
696
697	einj_param = einj_get_parameter_address();
698	if ((param_extension || acpi5) && einj_param) {
699		fentry = debugfs_create_x64("param1", S_IRUSR | S_IWUSR,
700					    einj_debug_dir, &error_param1);
701		if (!fentry)
702			goto err_unmap;
703		fentry = debugfs_create_x64("param2", S_IRUSR | S_IWUSR,
704					    einj_debug_dir, &error_param2);
705		if (!fentry)
706			goto err_unmap;
707
708		fentry = debugfs_create_x32("notrigger", S_IRUSR | S_IWUSR,
709					    einj_debug_dir, &notrigger);
710		if (!fentry)
711			goto err_unmap;
712	}
713
714	if (vendor_dev[0]) {
715		vendor_blob.data = vendor_dev;
716		vendor_blob.size = strlen(vendor_dev);
717		fentry = debugfs_create_blob("vendor", S_IRUSR,
718					     einj_debug_dir, &vendor_blob);
719		if (!fentry)
720			goto err_unmap;
721		fentry = debugfs_create_x32("vendor_flags", S_IRUSR | S_IWUSR,
722					    einj_debug_dir, &vendor_flags);
723		if (!fentry)
724			goto err_unmap;
725	}
726
727	pr_info(EINJ_PFX "Error INJection is initialized.\n");
 
 
728
729	return 0;
730
731err_unmap:
732	if (einj_param) {
733		acpi_size size = (acpi5) ?
734			sizeof(struct set_error_type_with_address) :
735			sizeof(struct einj_parameter);
736
737		acpi_os_unmap_memory(einj_param, size);
738	}
739	apei_exec_post_unmap_gars(&ctx);
740err_release:
741	apei_resources_release(&einj_resources);
742err_fini:
743	apei_resources_fini(&einj_resources);
744err_cleanup:
745	debugfs_remove_recursive(einj_debug_dir);
 
 
746
747	return rc;
748}
749
750static void __exit einj_exit(void)
751{
752	struct apei_exec_context ctx;
753
754	if (einj_param) {
755		acpi_size size = (acpi5) ?
756			sizeof(struct set_error_type_with_address) :
757			sizeof(struct einj_parameter);
758
759		acpi_os_unmap_memory(einj_param, size);
 
 
760	}
761	einj_exec_ctx_init(&ctx);
762	apei_exec_post_unmap_gars(&ctx);
763	apei_resources_release(&einj_resources);
764	apei_resources_fini(&einj_resources);
765	debugfs_remove_recursive(einj_debug_dir);
 
766}
767
768module_init(einj_init);
769module_exit(einj_exit);
770
771MODULE_AUTHOR("Huang Ying");
772MODULE_DESCRIPTION("APEI Error INJection support");
773MODULE_LICENSE("GPL");
v6.8
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * APEI Error INJection support
  4 *
  5 * EINJ provides a hardware error injection mechanism, this is useful
  6 * for debugging and testing of other APEI and RAS features.
  7 *
  8 * For more information about EINJ, please refer to ACPI Specification
  9 * version 4.0, section 17.5.
 10 *
 11 * Copyright 2009-2010 Intel Corp.
 12 *   Author: Huang Ying <ying.huang@intel.com>
 
 
 
 
 
 
 
 
 
 
 
 
 
 13 */
 14
 15#include <linux/kernel.h>
 16#include <linux/module.h>
 17#include <linux/init.h>
 18#include <linux/io.h>
 19#include <linux/debugfs.h>
 20#include <linux/seq_file.h>
 21#include <linux/nmi.h>
 22#include <linux/delay.h>
 23#include <linux/mm.h>
 24#include <asm/unaligned.h>
 25
 26#include "apei-internal.h"
 27
 28#undef pr_fmt
 29#define pr_fmt(fmt) "EINJ: " fmt
 30
 31#define SLEEP_UNIT_MIN		1000			/* 1ms */
 32#define SLEEP_UNIT_MAX		5000			/* 5ms */
 33/* Firmware should respond within 1 seconds */
 34#define FIRMWARE_TIMEOUT	(1 * USEC_PER_SEC)
 35#define ACPI5_VENDOR_BIT	BIT(31)
 36#define MEM_ERROR_MASK		(ACPI_EINJ_MEMORY_CORRECTABLE | \
 37				ACPI_EINJ_MEMORY_UNCORRECTABLE | \
 38				ACPI_EINJ_MEMORY_FATAL)
 39
 40/*
 41 * ACPI version 5 provides a SET_ERROR_TYPE_WITH_ADDRESS action.
 42 */
 43static int acpi5;
 44
 45struct set_error_type_with_address {
 46	u32	type;
 47	u32	vendor_extension;
 48	u32	flags;
 49	u32	apicid;
 50	u64	memory_address;
 51	u64	memory_address_range;
 52	u32	pcie_sbdf;
 53};
 54enum {
 55	SETWA_FLAGS_APICID = 1,
 56	SETWA_FLAGS_MEM = 2,
 57	SETWA_FLAGS_PCIE_SBDF = 4,
 58};
 59
 60/*
 61 * Vendor extensions for platform specific operations
 62 */
 63struct vendor_error_type_extension {
 64	u32	length;
 65	u32	pcie_sbdf;
 66	u16	vendor_id;
 67	u16	device_id;
 68	u8	rev_id;
 69	u8	reserved[3];
 70};
 71
 72static u32 notrigger;
 73
 74static u32 vendor_flags;
 75static struct debugfs_blob_wrapper vendor_blob;
 76static struct debugfs_blob_wrapper vendor_errors;
 77static char vendor_dev[64];
 78
 79/*
 80 * Some BIOSes allow parameters to the SET_ERROR_TYPE entries in the
 81 * EINJ table through an unpublished extension. Use with caution as
 82 * most will ignore the parameter and make their own choice of address
 83 * for error injection.  This extension is used only if
 84 * param_extension module parameter is specified.
 85 */
 86struct einj_parameter {
 87	u64 type;
 88	u64 reserved1;
 89	u64 reserved2;
 90	u64 param1;
 91	u64 param2;
 92};
 93
 94#define EINJ_OP_BUSY			0x1
 95#define EINJ_STATUS_SUCCESS		0x0
 96#define EINJ_STATUS_FAIL		0x1
 97#define EINJ_STATUS_INVAL		0x2
 98
 99#define EINJ_TAB_ENTRY(tab)						\
100	((struct acpi_whea_header *)((char *)(tab) +			\
101				    sizeof(struct acpi_table_einj)))
102
103static bool param_extension;
104module_param(param_extension, bool, 0);
105
106static struct acpi_table_einj *einj_tab;
107
108static struct apei_resources einj_resources;
109
110static struct apei_exec_ins_type einj_ins_type[] = {
111	[ACPI_EINJ_READ_REGISTER] = {
112		.flags = APEI_EXEC_INS_ACCESS_REGISTER,
113		.run   = apei_exec_read_register,
114	},
115	[ACPI_EINJ_READ_REGISTER_VALUE] = {
116		.flags = APEI_EXEC_INS_ACCESS_REGISTER,
117		.run   = apei_exec_read_register_value,
118	},
119	[ACPI_EINJ_WRITE_REGISTER] = {
120		.flags = APEI_EXEC_INS_ACCESS_REGISTER,
121		.run   = apei_exec_write_register,
122	},
123	[ACPI_EINJ_WRITE_REGISTER_VALUE] = {
124		.flags = APEI_EXEC_INS_ACCESS_REGISTER,
125		.run   = apei_exec_write_register_value,
126	},
127	[ACPI_EINJ_NOOP] = {
128		.flags = 0,
129		.run   = apei_exec_noop,
130	},
131};
132
133/*
134 * Prevent EINJ interpreter to run simultaneously, because the
135 * corresponding firmware implementation may not work properly when
136 * invoked simultaneously.
137 */
138static DEFINE_MUTEX(einj_mutex);
139
140static void *einj_param;
141
142static void einj_exec_ctx_init(struct apei_exec_context *ctx)
143{
144	apei_exec_ctx_init(ctx, einj_ins_type, ARRAY_SIZE(einj_ins_type),
145			   EINJ_TAB_ENTRY(einj_tab), einj_tab->entries);
146}
147
148static int __einj_get_available_error_type(u32 *type)
149{
150	struct apei_exec_context ctx;
151	int rc;
152
153	einj_exec_ctx_init(&ctx);
154	rc = apei_exec_run(&ctx, ACPI_EINJ_GET_ERROR_TYPE);
155	if (rc)
156		return rc;
157	*type = apei_exec_ctx_get_output(&ctx);
158
159	return 0;
160}
161
162/* Get error injection capabilities of the platform */
163static int einj_get_available_error_type(u32 *type)
164{
165	int rc;
166
167	mutex_lock(&einj_mutex);
168	rc = __einj_get_available_error_type(type);
169	mutex_unlock(&einj_mutex);
170
171	return rc;
172}
173
174static int einj_timedout(u64 *t)
175{
176	if ((s64)*t < SLEEP_UNIT_MIN) {
177		pr_warn(FW_WARN "Firmware does not respond in time\n");
 
178		return 1;
179	}
180	*t -= SLEEP_UNIT_MIN;
181	usleep_range(SLEEP_UNIT_MIN, SLEEP_UNIT_MAX);
182
183	return 0;
184}
185
186static void get_oem_vendor_struct(u64 paddr, int offset,
187				  struct vendor_error_type_extension *v)
188{
189	unsigned long vendor_size;
190	u64 target_pa = paddr + offset + sizeof(struct vendor_error_type_extension);
191
192	vendor_size = v->length - sizeof(struct vendor_error_type_extension);
193
194	if (vendor_size)
195		vendor_errors.data = acpi_os_map_memory(target_pa, vendor_size);
196
197	if (vendor_errors.data)
198		vendor_errors.size = vendor_size;
199}
200
201static void check_vendor_extension(u64 paddr,
202				   struct set_error_type_with_address *v5param)
203{
204	int	offset = v5param->vendor_extension;
205	struct	vendor_error_type_extension *v;
206	u32	sbdf;
207
208	if (!offset)
209		return;
210	v = acpi_os_map_iomem(paddr + offset, sizeof(*v));
211	if (!v)
212		return;
213	get_oem_vendor_struct(paddr, offset, v);
214	sbdf = v->pcie_sbdf;
215	sprintf(vendor_dev, "%x:%x:%x.%x vendor_id=%x device_id=%x rev_id=%x\n",
216		sbdf >> 24, (sbdf >> 16) & 0xff,
217		(sbdf >> 11) & 0x1f, (sbdf >> 8) & 0x7,
218		 v->vendor_id, v->device_id, v->rev_id);
219	acpi_os_unmap_iomem(v, sizeof(*v));
220}
221
222static void *einj_get_parameter_address(void)
223{
224	int i;
225	u64 pa_v4 = 0, pa_v5 = 0;
226	struct acpi_whea_header *entry;
227
228	entry = EINJ_TAB_ENTRY(einj_tab);
229	for (i = 0; i < einj_tab->entries; i++) {
230		if (entry->action == ACPI_EINJ_SET_ERROR_TYPE &&
231		    entry->instruction == ACPI_EINJ_WRITE_REGISTER &&
232		    entry->register_region.space_id ==
233		    ACPI_ADR_SPACE_SYSTEM_MEMORY)
234			pa_v4 = get_unaligned(&entry->register_region.address);
 
235		if (entry->action == ACPI_EINJ_SET_ERROR_TYPE_WITH_ADDRESS &&
236		    entry->instruction == ACPI_EINJ_WRITE_REGISTER &&
237		    entry->register_region.space_id ==
238		    ACPI_ADR_SPACE_SYSTEM_MEMORY)
239			pa_v5 = get_unaligned(&entry->register_region.address);
 
240		entry++;
241	}
242	if (pa_v5) {
243		struct set_error_type_with_address *v5param;
244
245		v5param = acpi_os_map_iomem(pa_v5, sizeof(*v5param));
246		if (v5param) {
247			acpi5 = 1;
248			check_vendor_extension(pa_v5, v5param);
249			return v5param;
250		}
251	}
252	if (param_extension && pa_v4) {
253		struct einj_parameter *v4param;
254
255		v4param = acpi_os_map_iomem(pa_v4, sizeof(*v4param));
256		if (!v4param)
257			return NULL;
258		if (v4param->reserved1 || v4param->reserved2) {
259			acpi_os_unmap_iomem(v4param, sizeof(*v4param));
260			return NULL;
261		}
262		return v4param;
263	}
264
265	return NULL;
266}
267
268/* do sanity check to trigger table */
269static int einj_check_trigger_header(struct acpi_einj_trigger *trigger_tab)
270{
271	if (trigger_tab->header_size != sizeof(struct acpi_einj_trigger))
272		return -EINVAL;
273	if (trigger_tab->table_size > PAGE_SIZE ||
274	    trigger_tab->table_size < trigger_tab->header_size)
275		return -EINVAL;
276	if (trigger_tab->entry_count !=
277	    (trigger_tab->table_size - trigger_tab->header_size) /
278	    sizeof(struct acpi_einj_entry))
279		return -EINVAL;
280
281	return 0;
282}
283
284static struct acpi_generic_address *einj_get_trigger_parameter_region(
285	struct acpi_einj_trigger *trigger_tab, u64 param1, u64 param2)
286{
287	int i;
288	struct acpi_whea_header *entry;
289
290	entry = (struct acpi_whea_header *)
291		((char *)trigger_tab + sizeof(struct acpi_einj_trigger));
292	for (i = 0; i < trigger_tab->entry_count; i++) {
293		if (entry->action == ACPI_EINJ_TRIGGER_ERROR &&
294		entry->instruction <= ACPI_EINJ_WRITE_REGISTER_VALUE &&
295		entry->register_region.space_id ==
296			ACPI_ADR_SPACE_SYSTEM_MEMORY &&
297		(entry->register_region.address & param2) == (param1 & param2))
298			return &entry->register_region;
299		entry++;
300	}
301
302	return NULL;
303}
304/* Execute instructions in trigger error action table */
305static int __einj_error_trigger(u64 trigger_paddr, u32 type,
306				u64 param1, u64 param2)
307{
308	struct acpi_einj_trigger *trigger_tab = NULL;
309	struct apei_exec_context trigger_ctx;
310	struct apei_resources trigger_resources;
311	struct acpi_whea_header *trigger_entry;
312	struct resource *r;
313	u32 table_size;
314	int rc = -EIO;
315	struct acpi_generic_address *trigger_param_region = NULL;
316
317	r = request_mem_region(trigger_paddr, sizeof(*trigger_tab),
318			       "APEI EINJ Trigger Table");
319	if (!r) {
320		pr_err("Can not request [mem %#010llx-%#010llx] for Trigger table\n",
 
321		       (unsigned long long)trigger_paddr,
322		       (unsigned long long)trigger_paddr +
323			    sizeof(*trigger_tab) - 1);
324		goto out;
325	}
326	trigger_tab = ioremap_cache(trigger_paddr, sizeof(*trigger_tab));
327	if (!trigger_tab) {
328		pr_err("Failed to map trigger table!\n");
329		goto out_rel_header;
330	}
331	rc = einj_check_trigger_header(trigger_tab);
332	if (rc) {
333		pr_warn(FW_BUG "Invalid trigger error action table.\n");
 
334		goto out_rel_header;
335	}
336
337	/* No action structures in the TRIGGER_ERROR table, nothing to do */
338	if (!trigger_tab->entry_count)
339		goto out_rel_header;
340
341	rc = -EIO;
342	table_size = trigger_tab->table_size;
343	r = request_mem_region(trigger_paddr + sizeof(*trigger_tab),
344			       table_size - sizeof(*trigger_tab),
345			       "APEI EINJ Trigger Table");
346	if (!r) {
347		pr_err("Can not request [mem %#010llx-%#010llx] for Trigger Table Entry\n",
 
348		       (unsigned long long)trigger_paddr + sizeof(*trigger_tab),
349		       (unsigned long long)trigger_paddr + table_size - 1);
350		goto out_rel_header;
351	}
352	iounmap(trigger_tab);
353	trigger_tab = ioremap_cache(trigger_paddr, table_size);
354	if (!trigger_tab) {
355		pr_err("Failed to map trigger table!\n");
356		goto out_rel_entry;
357	}
358	trigger_entry = (struct acpi_whea_header *)
359		((char *)trigger_tab + sizeof(struct acpi_einj_trigger));
360	apei_resources_init(&trigger_resources);
361	apei_exec_ctx_init(&trigger_ctx, einj_ins_type,
362			   ARRAY_SIZE(einj_ins_type),
363			   trigger_entry, trigger_tab->entry_count);
364	rc = apei_exec_collect_resources(&trigger_ctx, &trigger_resources);
365	if (rc)
366		goto out_fini;
367	rc = apei_resources_sub(&trigger_resources, &einj_resources);
368	if (rc)
369		goto out_fini;
370	/*
371	 * Some firmware will access target address specified in
372	 * param1 to trigger the error when injecting memory error.
373	 * This will cause resource conflict with regular memory.  So
374	 * remove it from trigger table resources.
375	 */
376	if ((param_extension || acpi5) && (type & MEM_ERROR_MASK) && param2) {
377		struct apei_resources addr_resources;
378
379		apei_resources_init(&addr_resources);
380		trigger_param_region = einj_get_trigger_parameter_region(
381			trigger_tab, param1, param2);
382		if (trigger_param_region) {
383			rc = apei_resources_add(&addr_resources,
384				trigger_param_region->address,
385				trigger_param_region->bit_width/8, true);
386			if (rc)
387				goto out_fini;
388			rc = apei_resources_sub(&trigger_resources,
389					&addr_resources);
390		}
391		apei_resources_fini(&addr_resources);
392		if (rc)
393			goto out_fini;
394	}
395	rc = apei_resources_request(&trigger_resources, "APEI EINJ Trigger");
396	if (rc)
397		goto out_fini;
398	rc = apei_exec_pre_map_gars(&trigger_ctx);
399	if (rc)
400		goto out_release;
401
402	rc = apei_exec_run(&trigger_ctx, ACPI_EINJ_TRIGGER_ERROR);
403
404	apei_exec_post_unmap_gars(&trigger_ctx);
405out_release:
406	apei_resources_release(&trigger_resources);
407out_fini:
408	apei_resources_fini(&trigger_resources);
409out_rel_entry:
410	release_mem_region(trigger_paddr + sizeof(*trigger_tab),
411			   table_size - sizeof(*trigger_tab));
412out_rel_header:
413	release_mem_region(trigger_paddr, sizeof(*trigger_tab));
414out:
415	if (trigger_tab)
416		iounmap(trigger_tab);
417
418	return rc;
419}
420
421static int __einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2,
422			       u64 param3, u64 param4)
423{
424	struct apei_exec_context ctx;
425	u64 val, trigger_paddr, timeout = FIRMWARE_TIMEOUT;
426	int rc;
427
428	einj_exec_ctx_init(&ctx);
429
430	rc = apei_exec_run_optional(&ctx, ACPI_EINJ_BEGIN_OPERATION);
431	if (rc)
432		return rc;
433	apei_exec_ctx_set_input(&ctx, type);
434	if (acpi5) {
435		struct set_error_type_with_address *v5param = einj_param;
436
437		v5param->type = type;
438		if (type & ACPI5_VENDOR_BIT) {
439			switch (vendor_flags) {
440			case SETWA_FLAGS_APICID:
441				v5param->apicid = param1;
442				break;
443			case SETWA_FLAGS_MEM:
444				v5param->memory_address = param1;
445				v5param->memory_address_range = param2;
446				break;
447			case SETWA_FLAGS_PCIE_SBDF:
448				v5param->pcie_sbdf = param1;
449				break;
450			}
451			v5param->flags = vendor_flags;
452		} else if (flags) {
453			v5param->flags = flags;
454			v5param->memory_address = param1;
455			v5param->memory_address_range = param2;
456			v5param->apicid = param3;
457			v5param->pcie_sbdf = param4;
458		} else {
459			switch (type) {
460			case ACPI_EINJ_PROCESSOR_CORRECTABLE:
461			case ACPI_EINJ_PROCESSOR_UNCORRECTABLE:
462			case ACPI_EINJ_PROCESSOR_FATAL:
463				v5param->apicid = param1;
464				v5param->flags = SETWA_FLAGS_APICID;
465				break;
466			case ACPI_EINJ_MEMORY_CORRECTABLE:
467			case ACPI_EINJ_MEMORY_UNCORRECTABLE:
468			case ACPI_EINJ_MEMORY_FATAL:
469				v5param->memory_address = param1;
470				v5param->memory_address_range = param2;
471				v5param->flags = SETWA_FLAGS_MEM;
472				break;
473			case ACPI_EINJ_PCIX_CORRECTABLE:
474			case ACPI_EINJ_PCIX_UNCORRECTABLE:
475			case ACPI_EINJ_PCIX_FATAL:
476				v5param->pcie_sbdf = param1;
477				v5param->flags = SETWA_FLAGS_PCIE_SBDF;
478				break;
479			}
480		}
481	} else {
482		rc = apei_exec_run(&ctx, ACPI_EINJ_SET_ERROR_TYPE);
483		if (rc)
484			return rc;
485		if (einj_param) {
486			struct einj_parameter *v4param = einj_param;
487
488			v4param->param1 = param1;
489			v4param->param2 = param2;
490		}
491	}
492	rc = apei_exec_run(&ctx, ACPI_EINJ_EXECUTE_OPERATION);
493	if (rc)
494		return rc;
495	for (;;) {
496		rc = apei_exec_run(&ctx, ACPI_EINJ_CHECK_BUSY_STATUS);
497		if (rc)
498			return rc;
499		val = apei_exec_ctx_get_output(&ctx);
500		if (!(val & EINJ_OP_BUSY))
501			break;
502		if (einj_timedout(&timeout))
503			return -EIO;
504	}
505	rc = apei_exec_run(&ctx, ACPI_EINJ_GET_COMMAND_STATUS);
506	if (rc)
507		return rc;
508	val = apei_exec_ctx_get_output(&ctx);
509	if (val == EINJ_STATUS_FAIL)
510		return -EBUSY;
511	else if (val == EINJ_STATUS_INVAL)
512		return -EINVAL;
513
514	/*
515	 * The error is injected into the platform successfully, then it needs
516	 * to trigger the error.
517	 */
518	rc = apei_exec_run(&ctx, ACPI_EINJ_GET_TRIGGER_TABLE);
519	if (rc)
520		return rc;
521	trigger_paddr = apei_exec_ctx_get_output(&ctx);
522	if (notrigger == 0) {
523		rc = __einj_error_trigger(trigger_paddr, type, param1, param2);
524		if (rc)
525			return rc;
526	}
527	rc = apei_exec_run_optional(&ctx, ACPI_EINJ_END_OPERATION);
528
529	return rc;
530}
531
532/* Inject the specified hardware error */
533static int einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2,
534			     u64 param3, u64 param4)
535{
536	int rc;
537	u64 base_addr, size;
538
539	/* If user manually set "flags", make sure it is legal */
540	if (flags && (flags &
541		~(SETWA_FLAGS_APICID|SETWA_FLAGS_MEM|SETWA_FLAGS_PCIE_SBDF)))
542		return -EINVAL;
543
544	/*
545	 * We need extra sanity checks for memory errors.
546	 * Other types leap directly to injection.
547	 */
548
549	/* ensure param1/param2 existed */
550	if (!(param_extension || acpi5))
551		goto inject;
552
553	/* ensure injection is memory related */
554	if (type & ACPI5_VENDOR_BIT) {
555		if (vendor_flags != SETWA_FLAGS_MEM)
556			goto inject;
557	} else if (!(type & MEM_ERROR_MASK) && !(flags & SETWA_FLAGS_MEM))
558		goto inject;
559
560	/*
561	 * Disallow crazy address masks that give BIOS leeway to pick
562	 * injection address almost anywhere. Insist on page or
563	 * better granularity and that target address is normal RAM or
564	 * NVDIMM.
565	 */
566	base_addr = param1 & param2;
567	size = ~param2 + 1;
568
569	if (((param2 & PAGE_MASK) != PAGE_MASK) ||
570	    ((region_intersects(base_addr, size, IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE)
571				!= REGION_INTERSECTS) &&
572	     (region_intersects(base_addr, size, IORESOURCE_MEM, IORES_DESC_PERSISTENT_MEMORY)
573				!= REGION_INTERSECTS) &&
574	     (region_intersects(base_addr, size, IORESOURCE_MEM, IORES_DESC_SOFT_RESERVED)
575				!= REGION_INTERSECTS) &&
576	     !arch_is_platform_page(base_addr)))
577		return -EINVAL;
578
579	if (is_zero_pfn(base_addr >> PAGE_SHIFT))
580		return -EADDRINUSE;
581
582inject:
583	mutex_lock(&einj_mutex);
584	rc = __einj_error_inject(type, flags, param1, param2, param3, param4);
585	mutex_unlock(&einj_mutex);
586
587	return rc;
588}
589
590static u32 error_type;
591static u32 error_flags;
592static u64 error_param1;
593static u64 error_param2;
594static u64 error_param3;
595static u64 error_param4;
596static struct dentry *einj_debug_dir;
597static struct { u32 mask; const char *str; } const einj_error_type_string[] = {
598	{ BIT(0), "Processor Correctable" },
599	{ BIT(1), "Processor Uncorrectable non-fatal" },
600	{ BIT(2), "Processor Uncorrectable fatal" },
601	{ BIT(3), "Memory Correctable" },
602	{ BIT(4), "Memory Uncorrectable non-fatal" },
603	{ BIT(5), "Memory Uncorrectable fatal" },
604	{ BIT(6), "PCI Express Correctable" },
605	{ BIT(7), "PCI Express Uncorrectable non-fatal" },
606	{ BIT(8), "PCI Express Uncorrectable fatal" },
607	{ BIT(9), "Platform Correctable" },
608	{ BIT(10), "Platform Uncorrectable non-fatal" },
609	{ BIT(11), "Platform Uncorrectable fatal"},
610	{ BIT(12), "CXL.cache Protocol Correctable" },
611	{ BIT(13), "CXL.cache Protocol Uncorrectable non-fatal" },
612	{ BIT(14), "CXL.cache Protocol Uncorrectable fatal" },
613	{ BIT(15), "CXL.mem Protocol Correctable" },
614	{ BIT(16), "CXL.mem Protocol Uncorrectable non-fatal" },
615	{ BIT(17), "CXL.mem Protocol Uncorrectable fatal" },
616	{ BIT(31), "Vendor Defined Error Types" },
617};
618
619static int available_error_type_show(struct seq_file *m, void *v)
620{
621	int rc;
622	u32 error_type = 0;
623
624	rc = einj_get_available_error_type(&error_type);
625	if (rc)
626		return rc;
627	for (int pos = 0; pos < ARRAY_SIZE(einj_error_type_string); pos++)
628		if (error_type & einj_error_type_string[pos].mask)
629			seq_printf(m, "0x%08x\t%s\n", einj_error_type_string[pos].mask,
630				   einj_error_type_string[pos].str);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
631
632	return 0;
633}
634
635DEFINE_SHOW_ATTRIBUTE(available_error_type);
 
 
 
 
 
 
 
 
 
 
636
637static int error_type_get(void *data, u64 *val)
638{
639	*val = error_type;
640
641	return 0;
642}
643
644static int error_type_set(void *data, u64 val)
645{
646	int rc;
647	u32 available_error_type = 0;
648	u32 tval, vendor;
649
650	/* Only low 32 bits for error type are valid */
651	if (val & GENMASK_ULL(63, 32))
652		return -EINVAL;
653
654	/*
655	 * Vendor defined types have 0x80000000 bit set, and
656	 * are not enumerated by ACPI_EINJ_GET_ERROR_TYPE
657	 */
658	vendor = val & ACPI5_VENDOR_BIT;
659	tval = val & 0x7fffffff;
660
661	/* Only one error type can be specified */
662	if (tval & (tval - 1))
663		return -EINVAL;
664	if (!vendor) {
665		rc = einj_get_available_error_type(&available_error_type);
666		if (rc)
667			return rc;
668		if (!(val & available_error_type))
669			return -EINVAL;
670	}
671	error_type = val;
672
673	return 0;
674}
675
676DEFINE_DEBUGFS_ATTRIBUTE(error_type_fops, error_type_get, error_type_set,
677			 "0x%llx\n");
678
679static int error_inject_set(void *data, u64 val)
680{
681	if (!error_type)
682		return -EINVAL;
683
684	return einj_error_inject(error_type, error_flags, error_param1, error_param2,
685		error_param3, error_param4);
686}
687
688DEFINE_DEBUGFS_ATTRIBUTE(error_inject_fops, NULL, error_inject_set, "%llu\n");
 
689
690static int einj_check_table(struct acpi_table_einj *einj_tab)
691{
692	if ((einj_tab->header_length !=
693	     (sizeof(struct acpi_table_einj) - sizeof(einj_tab->header)))
694	    && (einj_tab->header_length != sizeof(struct acpi_table_einj)))
695		return -EINVAL;
696	if (einj_tab->header.length < sizeof(struct acpi_table_einj))
697		return -EINVAL;
698	if (einj_tab->entries !=
699	    (einj_tab->header.length - sizeof(struct acpi_table_einj)) /
700	    sizeof(struct acpi_einj_entry))
701		return -EINVAL;
702
703	return 0;
704}
705
706static int __init einj_init(void)
707{
708	int rc;
709	acpi_status status;
 
710	struct apei_exec_context ctx;
711
712	if (acpi_disabled) {
713		pr_info("ACPI disabled.\n");
714		return -ENODEV;
715	}
716
717	status = acpi_get_table(ACPI_SIG_EINJ, 0,
718				(struct acpi_table_header **)&einj_tab);
719	if (status == AE_NOT_FOUND) {
720		pr_warn("EINJ table not found.\n");
721		return -ENODEV;
722	} else if (ACPI_FAILURE(status)) {
723		pr_err("Failed to get EINJ table: %s\n",
724				acpi_format_exception(status));
725		return -EINVAL;
726	}
727
728	rc = einj_check_table(einj_tab);
729	if (rc) {
730		pr_warn(FW_BUG "Invalid EINJ table.\n");
731		goto err_put_table;
732	}
733
734	rc = -ENOMEM;
735	einj_debug_dir = debugfs_create_dir("einj", apei_get_debugfs_dir());
736
737	debugfs_create_file("available_error_type", S_IRUSR, einj_debug_dir,
738			    NULL, &available_error_type_fops);
739	debugfs_create_file_unsafe("error_type", 0600, einj_debug_dir,
740				   NULL, &error_type_fops);
741	debugfs_create_file_unsafe("error_inject", 0200, einj_debug_dir,
742				   NULL, &error_inject_fops);
 
 
 
 
 
 
 
 
743
744	apei_resources_init(&einj_resources);
745	einj_exec_ctx_init(&ctx);
746	rc = apei_exec_collect_resources(&ctx, &einj_resources);
747	if (rc) {
748		pr_err("Error collecting EINJ resources.\n");
749		goto err_fini;
750	}
751
752	rc = apei_resources_request(&einj_resources, "APEI EINJ");
753	if (rc) {
754		pr_err("Error requesting memory/port resources.\n");
755		goto err_fini;
756	}
757
758	rc = apei_exec_pre_map_gars(&ctx);
759	if (rc) {
760		pr_err("Error pre-mapping GARs.\n");
761		goto err_release;
762	}
763
764	einj_param = einj_get_parameter_address();
765	if ((param_extension || acpi5) && einj_param) {
766		debugfs_create_x32("flags", S_IRUSR | S_IWUSR, einj_debug_dir,
767				   &error_flags);
768		debugfs_create_x64("param1", S_IRUSR | S_IWUSR, einj_debug_dir,
769				   &error_param1);
770		debugfs_create_x64("param2", S_IRUSR | S_IWUSR, einj_debug_dir,
771				   &error_param2);
772		debugfs_create_x64("param3", S_IRUSR | S_IWUSR, einj_debug_dir,
773				   &error_param3);
774		debugfs_create_x64("param4", S_IRUSR | S_IWUSR, einj_debug_dir,
775				   &error_param4);
776		debugfs_create_x32("notrigger", S_IRUSR | S_IWUSR,
777				   einj_debug_dir, &notrigger);
 
778	}
779
780	if (vendor_dev[0]) {
781		vendor_blob.data = vendor_dev;
782		vendor_blob.size = strlen(vendor_dev);
783		debugfs_create_blob("vendor", S_IRUSR, einj_debug_dir,
784				    &vendor_blob);
785		debugfs_create_x32("vendor_flags", S_IRUSR | S_IWUSR,
786				   einj_debug_dir, &vendor_flags);
 
 
 
 
787	}
788
789	if (vendor_errors.size)
790		debugfs_create_blob("oem_error", 0600, einj_debug_dir,
791				    &vendor_errors);
792
793	pr_info("Error INJection is initialized.\n");
794
795	return 0;
 
 
 
 
796
 
 
 
797err_release:
798	apei_resources_release(&einj_resources);
799err_fini:
800	apei_resources_fini(&einj_resources);
 
801	debugfs_remove_recursive(einj_debug_dir);
802err_put_table:
803	acpi_put_table((struct acpi_table_header *)einj_tab);
804
805	return rc;
806}
807
808static void __exit einj_exit(void)
809{
810	struct apei_exec_context ctx;
811
812	if (einj_param) {
813		acpi_size size = (acpi5) ?
814			sizeof(struct set_error_type_with_address) :
815			sizeof(struct einj_parameter);
816
817		acpi_os_unmap_iomem(einj_param, size);
818		if (vendor_errors.size)
819			acpi_os_unmap_memory(vendor_errors.data, vendor_errors.size);
820	}
821	einj_exec_ctx_init(&ctx);
822	apei_exec_post_unmap_gars(&ctx);
823	apei_resources_release(&einj_resources);
824	apei_resources_fini(&einj_resources);
825	debugfs_remove_recursive(einj_debug_dir);
826	acpi_put_table((struct acpi_table_header *)einj_tab);
827}
828
829module_init(einj_init);
830module_exit(einj_exit);
831
832MODULE_AUTHOR("Huang Ying");
833MODULE_DESCRIPTION("APEI Error INJection support");
834MODULE_LICENSE("GPL");