| From 27bd59502702fe51d9eb00450a75b727ec6bfcb4 Mon Sep 17 00:00:00 2001 |
| From: Yazen Ghannam <yazen.ghannam@amd.com> |
| Date: Wed, 21 Feb 2018 11:18:59 +0100 |
| Subject: x86/mce/AMD: Get address from already initialized block |
| |
| From: Yazen Ghannam <yazen.ghannam@amd.com> |
| |
| commit 27bd59502702fe51d9eb00450a75b727ec6bfcb4 upstream. |
| |
| The block address is saved after the block is initialized when |
| threshold_init_device() is called. |
| |
| Use the saved block address, if available, rather than trying to |
| rediscover it. |
| |
| This will avoid a call trace, when resuming from suspend, due to the |
| rdmsr_safe_on_cpu() call in get_block_address(). The rdmsr_safe_on_cpu() |
| call issues an IPI but we're running with interrupts disabled. This |
| triggers: |
| |
| WARNING: CPU: 0 PID: 11523 at kernel/smp.c:291 smp_call_function_single+0xdc/0xe0 |
| |
| Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com> |
| Signed-off-by: Borislav Petkov <bp@suse.de> |
| Cc: <stable@vger.kernel.org> # 4.14.x |
| Cc: Borislav Petkov <bp@alien8.de> |
| Cc: Linus Torvalds <torvalds@linux-foundation.org> |
| Cc: Peter Zijlstra <peterz@infradead.org> |
| Cc: Thomas Gleixner <tglx@linutronix.de> |
| Cc: Tony Luck <tony.luck@intel.com> |
| Cc: linux-edac <linux-edac@vger.kernel.org> |
| Link: http://lkml.kernel.org/r/20180221101900.10326-8-bp@alien8.de |
| Signed-off-by: Ingo Molnar <mingo@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/x86/kernel/cpu/mcheck/mce_amd.c | 15 +++++++++++++++ |
| 1 file changed, 15 insertions(+) |
| |
| --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c |
| +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c |
| @@ -434,6 +434,21 @@ static u32 get_block_address(unsigned in |
| { |
| u32 addr = 0, offset = 0; |
| |
| + if ((bank >= mca_cfg.banks) || (block >= NR_BLOCKS)) |
| + return addr; |
| + |
| + /* Get address from already initialized block. */ |
| + if (per_cpu(threshold_banks, cpu)) { |
| + struct threshold_bank *bankp = per_cpu(threshold_banks, cpu)[bank]; |
| + |
| + if (bankp && bankp->blocks) { |
| + struct threshold_block *blockp = &bankp->blocks[block]; |
| + |
| + if (blockp) |
| + return blockp->address; |
| + } |
| + } |
| + |
| if (mce_flags.smca) { |
| if (smca_get_bank_type(bank) == SMCA_RESERVED) |
| return addr; |