unsigned int cpu;
u32 address;
u16 interrupt_enable;
- bool interrupt_capable;
u16 threshold_limit;
struct kobject kobj;
struct list_head miscj;
};
static DEFINE_PER_CPU(struct threshold_bank * [NR_BANKS], threshold_banks);
+#ifdef CONFIG_SMP
static unsigned char shared_bank[NR_BANKS] = {
0, 0, 0, 0, 1
};
+#endif
static DEFINE_PER_CPU(unsigned char, bank_map); /* see which banks are on */
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;
return 1;
};
-/*
- * Called via smp_call_function_single(), must be called with correct
- * cpu affinity.
- */
+/* must be called with correct cpu affinity */
+/* Called via smp_call_function_single() */
static void threshold_restart_bank(void *_tr)
{
struct thresh_restart *tr = _tr;
(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 */
}
}
- if (tr->b->interrupt_enable)
- hi |= INT_TYPE_APIC;
-
- done:
+ tr->b->interrupt_enable ?
+ (hi = (hi & ~MASK_INT_TYPE_HI) | INT_TYPE_APIC) :
+ (hi &= ~MASK_INT_TYPE_HI);
hi |= MASK_COUNT_EN_HI;
wrmsr(tr->b->address, lo, hi);
if (!block)
per_cpu(bank_map, cpu) |= (1 << bank);
-
+#ifdef CONFIG_SMP
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.interrupt_capable = lvt_interrupt_supported(bank, high);
-
- if (b.interrupt_capable) {
- int new = (high & MASK_LVTOFF_HI) >> 20;
- offset = setup_APIC_mce(offset, new);
- }
+ b.cpu = cpu;
+ b.bank = bank;
+ b.block = block;
+ b.address = address;
mce_threshold_block_init(&b, offset);
mce_threshold_vector = amd_threshold_interrupt;
struct thresh_restart tr;
unsigned long new;
- if (!b->interrupt_capable)
- return -EINVAL;
-
if (strict_strtoul(buf, 0, &new) < 0)
return -EINVAL;
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);