From: Greg KH <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: torvalds@linux-foundation.org, akpm@linux-foundation.org,
alan@lxorguk.ukuu.org.uk,
Borislav Petkov <borislav.petkov@amd.com>,
Robert Richter <robert.richter@amd.com>
Subject: [ 15/20] x86, MCE, AMD: Make APIC LVT thresholding interrupt optional
Date: Thu, 14 Jun 2012 16:56:59 -0700 [thread overview]
Message-ID: <20120614235645.580470128@linuxfoundation.org> (raw)
In-Reply-To: <20120614235648.GA6552@kroah.com>
3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Borislav Petkov <borislav.petkov@amd.com>
commit f227d4306cf30e1d5b6f231e8ef9006c34f3d186 upstream.
Currently, the APIC LVT interrupt for error thresholding is implicitly
enabled. However, there are models in the F15h range which do not enable
it. Make the code machinery which sets up the APIC interrupt support
an optional setting and add an ->interrupt_capable member to the bank
representation mirroring that capability and enable the interrupt offset
programming only if it is true.
Simplify code and fixup comment style while at it.
Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
Signed-off-by: Robert Richter <robert.richter@amd.com>
---
arch/x86/kernel/cpu/mcheck/mce_amd.c | 55 ++++++++++++++++++++++++++++-------
1 file changed, 44 insertions(+), 11 deletions(-)
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -52,6 +52,7 @@ struct threshold_block {
unsigned int cpu;
u32 address;
u16 interrupt_enable;
+ bool interrupt_capable;
u16 threshold_limit;
struct kobject kobj;
struct list_head miscj;
@@ -86,6 +87,21 @@ struct thresh_restart {
u16 old_limit;
};
+static bool lvt_interrupt_supported(unsigned int bank, u32 msr_high_bits)
+{
+ /*
+ * bank 4 supports APIC LVT interrupts implicitly since forever.
+ */
+ if (bank == 4)
+ return true;
+
+ /*
+ * IntP: interrupt present; if this bit is set, the thresholding
+ * bank can generate APIC LVT interrupts
+ */
+ return msr_high_bits & BIT(28);
+}
+
static int lvt_off_valid(struct threshold_block *b, int apic, u32 lo, u32 hi)
{
int msr = (hi & MASK_LVTOFF_HI) >> 20;
@@ -107,8 +123,10 @@ static int lvt_off_valid(struct threshol
return 1;
};
-/* must be called with correct cpu affinity */
-/* Called via smp_call_function_single() */
+/*
+ * Called via smp_call_function_single(), must be called with correct
+ * cpu affinity.
+ */
static void threshold_restart_bank(void *_tr)
{
struct thresh_restart *tr = _tr;
@@ -131,6 +149,12 @@ static void threshold_restart_bank(void
(new_count & THRESHOLD_MAX);
}
+ /* clear IntType */
+ hi &= ~MASK_INT_TYPE_HI;
+
+ if (!tr->b->interrupt_capable)
+ goto done;
+
if (tr->set_lvt_off) {
if (lvt_off_valid(tr->b, tr->lvt_off, lo, hi)) {
/* set new lvt offset */
@@ -139,9 +163,10 @@ static void threshold_restart_bank(void
}
}
- tr->b->interrupt_enable ?
- (hi = (hi & ~MASK_INT_TYPE_HI) | INT_TYPE_APIC) :
- (hi &= ~MASK_INT_TYPE_HI);
+ if (tr->b->interrupt_enable)
+ hi |= INT_TYPE_APIC;
+
+ done:
hi |= MASK_COUNT_EN_HI;
wrmsr(tr->b->address, lo, hi);
@@ -206,14 +231,18 @@ void mce_amd_feature_init(struct cpuinfo
if (shared_bank[bank] && c->cpu_core_id)
break;
#endif
- offset = setup_APIC_mce(offset,
- (high & MASK_LVTOFF_HI) >> 20);
memset(&b, 0, sizeof(b));
- b.cpu = cpu;
- b.bank = bank;
- b.block = block;
- b.address = address;
+ b.cpu = cpu;
+ b.bank = bank;
+ b.block = block;
+ b.address = address;
+ b.interrupt_capable = lvt_interrupt_supported(bank, high);
+
+ if (b.interrupt_capable) {
+ int new = (high & MASK_LVTOFF_HI) >> 20;
+ offset = setup_APIC_mce(offset, new);
+ }
mce_threshold_block_init(&b, offset);
mce_threshold_vector = amd_threshold_interrupt;
@@ -313,6 +342,9 @@ store_interrupt_enable(struct threshold_
struct thresh_restart tr;
unsigned long new;
+ if (!b->interrupt_capable)
+ return -EINVAL;
+
if (strict_strtoul(buf, 0, &new) < 0)
return -EINVAL;
@@ -471,6 +503,7 @@ static __cpuinit int allocate_threshold_
b->cpu = cpu;
b->address = address;
b->interrupt_enable = 0;
+ b->interrupt_capable = lvt_interrupt_supported(bank, high);
b->threshold_limit = THRESHOLD_MAX;
INIT_LIST_HEAD(&b->miscj);
next prev parent reply other threads:[~2012-06-14 23:56 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-06-14 23:56 [ 00/20] 3.0.35-stable review Greg KH
2012-06-14 23:56 ` [ 01/20] char/agp: add another Ironlake host bridge Greg KH
2012-06-14 23:56 ` [ 02/20] btree: fix tree corruption in btree_get_prev() Greg KH
2012-06-14 23:56 ` [ 03/20] powerpc: Fix kernel panic during kernel module load Greg KH
2012-06-14 23:56 ` [ 04/20] crypto: aesni-intel - fix unaligned cbc decrypt for x86-32 Greg KH
2012-06-14 23:56 ` [ 05/20] mac80211: clean up remain-on-channel on interface stop Greg KH
2012-06-14 23:56 ` [ 06/20] cfg80211: fix interface combinations check Greg KH
2012-06-14 23:56 ` [ 07/20] net: sierra_net: device IDs for Aircard 320U++ Greg KH
2012-06-14 23:56 ` [ 08/20] can: c_can: fix "BUG! echo_skb is occupied!" during transmit Greg KH
2012-06-14 23:56 ` [ 09/20] can: c_can: fix an interrupt thrash issue with c_can driver Greg KH
2012-06-14 23:56 ` [ 10/20] can: c_can: fix race condition in c_can_open() Greg KH
2012-06-14 23:56 ` [ 11/20] hwmon: (fam15h_power) Increase output resolution Greg KH
2012-06-14 23:56 ` [ 12/20] acpi_video: fix leaking PCI references Greg KH
2012-06-14 23:56 ` [ 13/20] sched: Fix the relax_domain_level boot parameter Greg KH
2012-06-14 23:56 ` [ 14/20] iwlwifi: dont mess up the SCD when removing a key Greg KH
2012-06-14 23:56 ` Greg KH [this message]
2012-06-14 23:57 ` [ 16/20] fuse: fix stat call on 32 bit platforms Greg KH
2012-06-14 23:57 ` [ 17/20] e1000: save skb counts in TX to avoid cache misses Greg KH
2012-06-14 23:57 ` [ 18/20] mm/vmalloc.c: change void* into explict vm_struct* Greg KH
2012-06-14 23:57 ` [ 19/20] mm: fix faulty initialization in vmalloc_init() Greg KH
2012-06-14 23:57 ` [ 20/20] hugetlb: fix resv_map leak in error path Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120614235645.580470128@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=akpm@linux-foundation.org \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=borislav.petkov@amd.com \
--cc=linux-kernel@vger.kernel.org \
--cc=robert.richter@amd.com \
--cc=stable@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).