linux/arch/x86/kernel/cpu/mce/inject.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Machine check injection support.
 * Copyright 2008 Intel Corporation.
 *
 * Authors:
 * Andi Kleen
 * Ying Huang
 *
 * The AMD part (from mce_amd_inj.c): a simple MCE injection facility
 * for testing different aspects of the RAS code. This driver should be
 * built as module so that it can be loaded on production kernels for
 * testing purposes.
 *
 * Copyright (c) 2010-17:  Borislav Petkov <[email protected]>
 *			   Advanced Micro Devices Inc.
 */

#include <linux/cpu.h>
#include <linux/debugfs.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/pci.h>
#include <linux/uaccess.h>

#include <asm/amd_nb.h>
#include <asm/apic.h>
#include <asm/irq_vectors.h>
#include <asm/mce.h>
#include <asm/nmi.h>
#include <asm/smp.h>

#include "internal.h"

static bool hw_injection_possible =;

/*
 * Collect all the MCi_XXX settings
 */
static struct mce i_mce;
static struct dentry *dfs_inj;

#define MAX_FLAG_OPT_SIZE
#define NBCFG

enum injection_type {};

static const char * const flags_options[] =;

/* Set default injection to SW_INJ */
static enum injection_type inj_type =;

#define MCE_INJECT_SET(reg)

MCE_INJECT_SET(status);
MCE_INJECT_SET(misc);
MCE_INJECT_SET(addr);
MCE_INJECT_SET(synd);

#define MCE_INJECT_GET(reg)

MCE_INJECT_GET(status);
MCE_INJECT_GET(misc);
MCE_INJECT_GET(addr);
MCE_INJECT_GET(synd);
MCE_INJECT_GET(ipid);

DEFINE_SIMPLE_ATTRIBUTE();
DEFINE_SIMPLE_ATTRIBUTE();
DEFINE_SIMPLE_ATTRIBUTE();
DEFINE_SIMPLE_ATTRIBUTE();

/* Use the user provided IPID value on a sw injection. */
static int inj_ipid_set(void *data, u64 val)
{}

DEFINE_SIMPLE_ATTRIBUTE();

static void setup_inj_struct(struct mce *m)
{}

/* Update fake mce registers on current CPU. */
static void inject_mce(struct mce *m)
{}

static void raise_poll(struct mce *m)
{}

static void raise_exception(struct mce *m, struct pt_regs *pregs)
{}

static cpumask_var_t mce_inject_cpumask;
static DEFINE_MUTEX(mce_inject_mutex);

static int mce_raise_notify(unsigned int cmd, struct pt_regs *regs)
{}

static void mce_irq_ipi(void *info)
{}

/* Inject mce on current CPU */
static int raise_local(void)
{}

static void __maybe_unused raise_mce(struct mce *m)
{}

static int mce_inject_raise(struct notifier_block *nb, unsigned long val,
			    void *data)
{}

static struct notifier_block inject_nb =;

/*
 * Caller needs to be make sure this cpu doesn't disappear
 * from under us, i.e.: get_cpu/put_cpu.
 */
static int toggle_hw_mce_inject(unsigned int cpu, bool enable)
{}

static int __set_inj(const char *buf)
{}

static ssize_t flags_read(struct file *filp, char __user *ubuf,
			  size_t cnt, loff_t *ppos)
{}

static ssize_t flags_write(struct file *filp, const char __user *ubuf,
			   size_t cnt, loff_t *ppos)
{}

static const struct file_operations flags_fops =;

/*
 * On which CPU to inject?
 */
MCE_INJECT_GET(extcpu);

static int inj_extcpu_set(void *data, u64 val)
{}

DEFINE_SIMPLE_ATTRIBUTE();

static void trigger_mce(void *info)
{}

static void trigger_dfr_int(void *info)
{}

static void trigger_thr_int(void *info)
{}

static u32 get_nbc_for_node(int node_id)
{}

static void toggle_nb_mca_mst_cpu(u16 nid)
{}

static void prepare_msrs(void *info)
{}

static void do_inject(void)
{}

/*
 * This denotes into which bank we're injecting and triggers
 * the injection, at the same time.
 */
static int inj_bank_set(void *data, u64 val)
{}

MCE_INJECT_GET(bank);

DEFINE_SIMPLE_ATTRIBUTE();

static const char readme_msg[] =;

static ssize_t
inj_readme_read(struct file *filp, char __user *ubuf,
		       size_t cnt, loff_t *ppos)
{}

static const struct file_operations readme_fops =;

static struct dfs_node {} dfs_fls[] =;

static void __init debugfs_init(void)
{}

static void check_hw_inj_possible(void)
{}

static int __init inject_init(void)
{}

static void __exit inject_exit(void)
{}

module_init();
module_exit(inject_exit);
MODULE_DESCRIPTION();
MODULE_LICENSE();