/* * Copyright Chen Yucong 2014 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License. */ #include #include #include #include #include #include #include #define MASK_OVERFLOW 0x0001000000000000 /* Update fake mce registers on current CPU. */ static void inject_mce(struct mce *m) { struct mce *i = &per_cpu(injectm, m->extcpu); /* Make sure no one reads partially written injectm */ i->finished = 0; mb(); m->finished = 0; /* First set the fields after finished */ i->extcpu = m->extcpu; mb(); /* Now write record in order, finished last (except above) */ memcpy(i, m, sizeof(struct mce)); /* Finally activate it */ mb(); i->finished = 1; } static void raise_mce(void) { struct mce m; mce_setup(&m); m.status = 0X8C00000000000000; m.misc = 0XC008000000000000 | MASK_OVERFLOW; //m.misc = 0XC008000000000000; m.bank = 4; m.addr = 0xabcdef; inject_mce(&m); raise_amd_threshold_event(); } static int __init amd_inject_init(void) { raise_mce(); pr_info("amd_inject module loaded ...\n"); return 0; } static void __exit amd_inject_exit(void) { pr_info("amd_inject module unloaded ...\n"); } module_init(amd_inject_init); module_exit(amd_inject_exit); /* * Cannot tolerate unloading currently because we cannot * guarantee all openers of mce_chrdev will get a reference to us. */ MODULE_LICENSE("GPL");