Commit 9c37c9d8 authored by Robert Richter's avatar Robert Richter Committed by Ingo Molnar

mce, amd: Implement mce_threshold_block_init() helper function

This patch adds a helper function for the initial setup of an
mce threshold block. The LVT offset is passed as argument. Also
making variable threshold_defaults local as it is only used in
function mce_amd_feature_init(). Function
threshold_restart_bank() is extended to setup the LVT offset,
the change is backward compatible. Thus, now there is only a
single wrmsrl() to setup the block.
Signed-off-by: default avatarRobert Richter <robert.richter@amd.com>
Acked-by: default avatarBorislav Petkov <borislav.petkov@amd.com>
LKML-Reference: <1288015419-29543-2-git-send-email-robert.richter@amd.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 229aebb8
...@@ -59,12 +59,6 @@ struct threshold_block { ...@@ -59,12 +59,6 @@ struct threshold_block {
struct list_head miscj; struct list_head miscj;
}; };
/* defaults used early on boot */
static struct threshold_block threshold_defaults = {
.interrupt_enable = 0,
.threshold_limit = THRESHOLD_MAX,
};
struct threshold_bank { struct threshold_bank {
struct kobject *kobj; struct kobject *kobj;
struct threshold_block *blocks; struct threshold_block *blocks;
...@@ -89,6 +83,8 @@ static void amd_threshold_interrupt(void); ...@@ -89,6 +83,8 @@ static void amd_threshold_interrupt(void);
struct thresh_restart { struct thresh_restart {
struct threshold_block *b; struct threshold_block *b;
int reset; int reset;
int set_lvt_off;
int lvt_off;
u16 old_limit; u16 old_limit;
}; };
...@@ -116,6 +112,12 @@ static void threshold_restart_bank(void *_tr) ...@@ -116,6 +112,12 @@ static void threshold_restart_bank(void *_tr)
(new_count & THRESHOLD_MAX); (new_count & THRESHOLD_MAX);
} }
if (tr->set_lvt_off) {
/* set new lvt offset */
mci_misc_hi &= ~MASK_LVTOFF_HI;
mci_misc_hi |= tr->lvt_off << 20;
}
tr->b->interrupt_enable ? tr->b->interrupt_enable ?
(mci_misc_hi = (mci_misc_hi & ~MASK_INT_TYPE_HI) | INT_TYPE_APIC) : (mci_misc_hi = (mci_misc_hi & ~MASK_INT_TYPE_HI) | INT_TYPE_APIC) :
(mci_misc_hi &= ~MASK_INT_TYPE_HI); (mci_misc_hi &= ~MASK_INT_TYPE_HI);
...@@ -124,13 +126,25 @@ static void threshold_restart_bank(void *_tr) ...@@ -124,13 +126,25 @@ static void threshold_restart_bank(void *_tr)
wrmsr(tr->b->address, mci_misc_lo, mci_misc_hi); wrmsr(tr->b->address, mci_misc_lo, mci_misc_hi);
} }
static void mce_threshold_block_init(struct threshold_block *b, int offset)
{
struct thresh_restart tr = {
.b = b,
.set_lvt_off = 1,
.lvt_off = offset,
};
b->threshold_limit = THRESHOLD_MAX;
threshold_restart_bank(&tr);
};
/* cpu init entry point, called from mce.c with preempt off */ /* cpu init entry point, called from mce.c with preempt off */
void mce_amd_feature_init(struct cpuinfo_x86 *c) void mce_amd_feature_init(struct cpuinfo_x86 *c)
{ {
struct threshold_block b;
unsigned int cpu = smp_processor_id(); unsigned int cpu = smp_processor_id();
u32 low = 0, high = 0, address = 0; u32 low = 0, high = 0, address = 0;
unsigned int bank, block; unsigned int bank, block;
struct thresh_restart tr;
int lvt_off = -1; int lvt_off = -1;
u8 offset; u8 offset;
...@@ -186,16 +200,13 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c) ...@@ -186,16 +200,13 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)
continue; continue;
} }
high &= ~MASK_LVTOFF_HI; memset(&b, 0, sizeof(b));
high |= lvt_off << 20; b.cpu = cpu;
wrmsr(address, low, high); b.bank = bank;
b.block = block;
threshold_defaults.address = address; b.address = address;
tr.b = &threshold_defaults;
tr.reset = 0;
tr.old_limit = 0;
threshold_restart_bank(&tr);
mce_threshold_block_init(&b, offset);
mce_threshold_vector = amd_threshold_interrupt; mce_threshold_vector = amd_threshold_interrupt;
} }
} }
...@@ -298,9 +309,8 @@ store_interrupt_enable(struct threshold_block *b, const char *buf, size_t size) ...@@ -298,9 +309,8 @@ store_interrupt_enable(struct threshold_block *b, const char *buf, size_t size)
b->interrupt_enable = !!new; b->interrupt_enable = !!new;
memset(&tr, 0, sizeof(tr));
tr.b = b; tr.b = b;
tr.reset = 0;
tr.old_limit = 0;
smp_call_function_single(b->cpu, threshold_restart_bank, &tr, 1); smp_call_function_single(b->cpu, threshold_restart_bank, &tr, 1);
...@@ -321,10 +331,10 @@ store_threshold_limit(struct threshold_block *b, const char *buf, size_t size) ...@@ -321,10 +331,10 @@ store_threshold_limit(struct threshold_block *b, const char *buf, size_t size)
if (new < 1) if (new < 1)
new = 1; new = 1;
memset(&tr, 0, sizeof(tr));
tr.old_limit = b->threshold_limit; tr.old_limit = b->threshold_limit;
b->threshold_limit = new; b->threshold_limit = new;
tr.b = b; tr.b = b;
tr.reset = 0;
smp_call_function_single(b->cpu, threshold_restart_bank, &tr, 1); smp_call_function_single(b->cpu, threshold_restart_bank, &tr, 1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment