diff options
Diffstat (limited to 'arch/x86/kernel/cpu')
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 84 |
1 files changed, 83 insertions, 1 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index e8b893e880ed..4b62443b6e72 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
@@ -1626,6 +1626,26 @@ static void mce_restart(void) | |||
1626 | on_each_cpu(mce_cpu_restart, NULL, 1); | 1626 | on_each_cpu(mce_cpu_restart, NULL, 1); |
1627 | } | 1627 | } |
1628 | 1628 | ||
1629 | /* Toggle features for corrected errors */ | ||
1630 | static void mce_disable_ce(void *all) | ||
1631 | { | ||
1632 | if (!mce_available(¤t_cpu_data)) | ||
1633 | return; | ||
1634 | if (all) | ||
1635 | del_timer_sync(&__get_cpu_var(mce_timer)); | ||
1636 | cmci_clear(); | ||
1637 | } | ||
1638 | |||
1639 | static void mce_enable_ce(void *all) | ||
1640 | { | ||
1641 | if (!mce_available(¤t_cpu_data)) | ||
1642 | return; | ||
1643 | cmci_reenable(); | ||
1644 | cmci_recheck(); | ||
1645 | if (all) | ||
1646 | mce_init_timer(); | ||
1647 | } | ||
1648 | |||
1629 | static struct sysdev_class mce_sysclass = { | 1649 | static struct sysdev_class mce_sysclass = { |
1630 | .suspend = mce_suspend, | 1650 | .suspend = mce_suspend, |
1631 | .shutdown = mce_shutdown, | 1651 | .shutdown = mce_shutdown, |
@@ -1687,6 +1707,52 @@ static ssize_t set_trigger(struct sys_device *s, struct sysdev_attribute *attr, | |||
1687 | return len; | 1707 | return len; |
1688 | } | 1708 | } |
1689 | 1709 | ||
1710 | static ssize_t set_ignore_ce(struct sys_device *s, | ||
1711 | struct sysdev_attribute *attr, | ||
1712 | const char *buf, size_t size) | ||
1713 | { | ||
1714 | u64 new; | ||
1715 | |||
1716 | if (strict_strtoull(buf, 0, &new) < 0) | ||
1717 | return -EINVAL; | ||
1718 | |||
1719 | if (mce_ignore_ce ^ !!new) { | ||
1720 | if (new) { | ||
1721 | /* disable ce features */ | ||
1722 | on_each_cpu(mce_disable_ce, (void *)1, 1); | ||
1723 | mce_ignore_ce = 1; | ||
1724 | } else { | ||
1725 | /* enable ce features */ | ||
1726 | mce_ignore_ce = 0; | ||
1727 | on_each_cpu(mce_enable_ce, (void *)1, 1); | ||
1728 | } | ||
1729 | } | ||
1730 | return size; | ||
1731 | } | ||
1732 | |||
1733 | static ssize_t set_cmci_disabled(struct sys_device *s, | ||
1734 | struct sysdev_attribute *attr, | ||
1735 | const char *buf, size_t size) | ||
1736 | { | ||
1737 | u64 new; | ||
1738 | |||
1739 | if (strict_strtoull(buf, 0, &new) < 0) | ||
1740 | return -EINVAL; | ||
1741 | |||
1742 | if (mce_cmci_disabled ^ !!new) { | ||
1743 | if (new) { | ||
1744 | /* disable cmci */ | ||
1745 | on_each_cpu(mce_disable_ce, NULL, 1); | ||
1746 | mce_cmci_disabled = 1; | ||
1747 | } else { | ||
1748 | /* enable cmci */ | ||
1749 | mce_cmci_disabled = 0; | ||
1750 | on_each_cpu(mce_enable_ce, NULL, 1); | ||
1751 | } | ||
1752 | } | ||
1753 | return size; | ||
1754 | } | ||
1755 | |||
1690 | static ssize_t store_int_with_restart(struct sys_device *s, | 1756 | static ssize_t store_int_with_restart(struct sys_device *s, |
1691 | struct sysdev_attribute *attr, | 1757 | struct sysdev_attribute *attr, |
1692 | const char *buf, size_t size) | 1758 | const char *buf, size_t size) |
@@ -1699,6 +1765,7 @@ static ssize_t store_int_with_restart(struct sys_device *s, | |||
1699 | static SYSDEV_ATTR(trigger, 0644, show_trigger, set_trigger); | 1765 | static SYSDEV_ATTR(trigger, 0644, show_trigger, set_trigger); |
1700 | static SYSDEV_INT_ATTR(tolerant, 0644, tolerant); | 1766 | static SYSDEV_INT_ATTR(tolerant, 0644, tolerant); |
1701 | static SYSDEV_INT_ATTR(monarch_timeout, 0644, monarch_timeout); | 1767 | static SYSDEV_INT_ATTR(monarch_timeout, 0644, monarch_timeout); |
1768 | static SYSDEV_INT_ATTR(dont_log_ce, 0644, mce_dont_log_ce); | ||
1702 | 1769 | ||
1703 | static struct sysdev_ext_attribute attr_check_interval = { | 1770 | static struct sysdev_ext_attribute attr_check_interval = { |
1704 | _SYSDEV_ATTR(check_interval, 0644, sysdev_show_int, | 1771 | _SYSDEV_ATTR(check_interval, 0644, sysdev_show_int, |
@@ -1706,9 +1773,24 @@ static struct sysdev_ext_attribute attr_check_interval = { | |||
1706 | &check_interval | 1773 | &check_interval |
1707 | }; | 1774 | }; |
1708 | 1775 | ||
1776 | static struct sysdev_ext_attribute attr_ignore_ce = { | ||
1777 | _SYSDEV_ATTR(ignore_ce, 0644, sysdev_show_int, set_ignore_ce), | ||
1778 | &mce_ignore_ce | ||
1779 | }; | ||
1780 | |||
1781 | static struct sysdev_ext_attribute attr_cmci_disabled = { | ||
1782 | _SYSDEV_ATTR(ignore_ce, 0644, sysdev_show_int, set_cmci_disabled), | ||
1783 | &mce_cmci_disabled | ||
1784 | }; | ||
1785 | |||
1709 | static struct sysdev_attribute *mce_attrs[] = { | 1786 | static struct sysdev_attribute *mce_attrs[] = { |
1710 | &attr_tolerant.attr, &attr_check_interval.attr, &attr_trigger, | 1787 | &attr_tolerant.attr, |
1788 | &attr_check_interval.attr, | ||
1789 | &attr_trigger, | ||
1711 | &attr_monarch_timeout.attr, | 1790 | &attr_monarch_timeout.attr, |
1791 | &attr_dont_log_ce.attr, | ||
1792 | &attr_ignore_ce.attr, | ||
1793 | &attr_cmci_disabled.attr, | ||
1712 | NULL | 1794 | NULL |
1713 | }; | 1795 | }; |
1714 | 1796 | ||