cec.c (ead5d1f4d877e92c051e1a1ade623d0d30e71619) cec.c (4bd442e9a8388e8ec4ba7cf23a4774989d93b78e)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2017-2019 Borislav Petkov, SUSE Labs.
4 */
5#include <linux/mm.h>
6#include <linux/gfp.h>
7#include <linux/ras.h>
8#include <linux/kernel.h>

--- 421 unchanged lines hidden (view full) ---

430 action_threshold = val;
431
432 return 0;
433}
434DEFINE_DEBUGFS_ATTRIBUTE(action_threshold_ops, u64_get, action_threshold_set, "%lld\n");
435
436static const char * const bins[] = { "00", "01", "10", "11" };
437
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2017-2019 Borislav Petkov, SUSE Labs.
4 */
5#include <linux/mm.h>
6#include <linux/gfp.h>
7#include <linux/ras.h>
8#include <linux/kernel.h>

--- 421 unchanged lines hidden (view full) ---

430 action_threshold = val;
431
432 return 0;
433}
434DEFINE_DEBUGFS_ATTRIBUTE(action_threshold_ops, u64_get, action_threshold_set, "%lld\n");
435
436static const char * const bins[] = { "00", "01", "10", "11" };
437
438static int array_dump(struct seq_file *m, void *v)
438static int array_show(struct seq_file *m, void *v)
439{
440 struct ce_array *ca = &ce_arr;
441 int i;
442
443 mutex_lock(&ce_mutex);
444
445 seq_printf(m, "{ n: %d\n", ca->n);
446 for (i = 0; i < ca->n; i++) {

--- 15 unchanged lines hidden (view full) ---

462
463 seq_printf(m, "Action threshold: %lld\n", action_threshold);
464
465 mutex_unlock(&ce_mutex);
466
467 return 0;
468}
469
439{
440 struct ce_array *ca = &ce_arr;
441 int i;
442
443 mutex_lock(&ce_mutex);
444
445 seq_printf(m, "{ n: %d\n", ca->n);
446 for (i = 0; i < ca->n; i++) {

--- 15 unchanged lines hidden (view full) ---

462
463 seq_printf(m, "Action threshold: %lld\n", action_threshold);
464
465 mutex_unlock(&ce_mutex);
466
467 return 0;
468}
469
470static int array_open(struct inode *inode, struct file *filp)
471{
472 return single_open(filp, array_dump, NULL);
473}
470DEFINE_SHOW_ATTRIBUTE(array);
474
471
475static const struct file_operations array_ops = {
476 .owner = THIS_MODULE,
477 .open = array_open,
478 .read = seq_read,
479 .llseek = seq_lseek,
480 .release = single_release,
481};
482
483static int __init create_debugfs_nodes(void)
484{
485 struct dentry *d, *pfn, *decay, *count, *array;
486
487 d = debugfs_create_dir("cec", ras_debugfs_dir);
488 if (!d) {
489 pr_warn("Error creating cec debugfs node!\n");
490 return -1;

--- 17 unchanged lines hidden (view full) ---

508 return 0;
509
510 pfn = debugfs_create_file("pfn", S_IRUSR | S_IWUSR, d, &dfs_pfn, &pfn_ops);
511 if (!pfn) {
512 pr_warn("Error creating pfn debugfs node!\n");
513 goto err;
514 }
515
472static int __init create_debugfs_nodes(void)
473{
474 struct dentry *d, *pfn, *decay, *count, *array;
475
476 d = debugfs_create_dir("cec", ras_debugfs_dir);
477 if (!d) {
478 pr_warn("Error creating cec debugfs node!\n");
479 return -1;

--- 17 unchanged lines hidden (view full) ---

497 return 0;
498
499 pfn = debugfs_create_file("pfn", S_IRUSR | S_IWUSR, d, &dfs_pfn, &pfn_ops);
500 if (!pfn) {
501 pr_warn("Error creating pfn debugfs node!\n");
502 goto err;
503 }
504
516 array = debugfs_create_file("array", S_IRUSR, d, NULL, &array_ops);
505 array = debugfs_create_file("array", S_IRUSR, d, NULL, &array_fops);
517 if (!array) {
518 pr_warn("Error creating array debugfs node!\n");
519 goto err;
520 }
521
522 return 0;
523
524err:

--- 23 unchanged lines hidden (view full) ---

548 return NOTIFY_DONE;
549}
550
551static struct notifier_block cec_nb = {
552 .notifier_call = cec_notifier,
553 .priority = MCE_PRIO_CEC,
554};
555
506 if (!array) {
507 pr_warn("Error creating array debugfs node!\n");
508 goto err;
509 }
510
511 return 0;
512
513err:

--- 23 unchanged lines hidden (view full) ---

537 return NOTIFY_DONE;
538}
539
540static struct notifier_block cec_nb = {
541 .notifier_call = cec_notifier,
542 .priority = MCE_PRIO_CEC,
543};
544
556static void __init cec_init(void)
545static int __init cec_init(void)
557{
558 if (ce_arr.disabled)
546{
547 if (ce_arr.disabled)
559 return;
548 return -ENODEV;
560
561 ce_arr.array = (void *)get_zeroed_page(GFP_KERNEL);
562 if (!ce_arr.array) {
563 pr_err("Error allocating CE array page!\n");
549
550 ce_arr.array = (void *)get_zeroed_page(GFP_KERNEL);
551 if (!ce_arr.array) {
552 pr_err("Error allocating CE array page!\n");
564 return;
553 return -ENOMEM;
565 }
566
567 if (create_debugfs_nodes()) {
568 free_page((unsigned long)ce_arr.array);
554 }
555
556 if (create_debugfs_nodes()) {
557 free_page((unsigned long)ce_arr.array);
569 return;
558 return -ENOMEM;
570 }
571
572 INIT_DELAYED_WORK(&cec_work, cec_work_fn);
573 schedule_delayed_work(&cec_work, CEC_DECAY_DEFAULT_INTERVAL);
574
575 mce_register_decode_chain(&cec_nb);
576
577 pr_info("Correctable Errors collector initialized.\n");
559 }
560
561 INIT_DELAYED_WORK(&cec_work, cec_work_fn);
562 schedule_delayed_work(&cec_work, CEC_DECAY_DEFAULT_INTERVAL);
563
564 mce_register_decode_chain(&cec_nb);
565
566 pr_info("Correctable Errors collector initialized.\n");
567 return 0;
578}
579late_initcall(cec_init);
580
581int __init parse_cec_param(char *str)
582{
583 if (!str)
584 return 0;
585
586 if (*str == '=')
587 str++;
588
589 if (!strcmp(str, "cec_disable"))
590 ce_arr.disabled = 1;
591 else
592 return 0;
593
594 return 1;
595}
568}
569late_initcall(cec_init);
570
571int __init parse_cec_param(char *str)
572{
573 if (!str)
574 return 0;
575
576 if (*str == '=')
577 str++;
578
579 if (!strcmp(str, "cec_disable"))
580 ce_arr.disabled = 1;
581 else
582 return 0;
583
584 return 1;
585}