Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=24ce0e96f2dea558762c994d054ea2f3c01fa95a
Commit:     24ce0e96f2dea558762c994d054ea2f3c01fa95a
Parent:     9b355897562fe2291248a7aec8e479c2c98cf117
Author:     Jan Beulich <[EMAIL PROTECTED]>
AuthorDate: Tue Feb 13 13:26:23 2007 +0100
Committer:  Andi Kleen <[EMAIL PROTECTED]>
CommitDate: Tue Feb 13 13:26:23 2007 +0100

    [PATCH] x86-64: Tighten mce_amd driver MSR reads
    
    while debugging an unrelated problem in Xen, I noticed odd reads from
    non-existent MSRs. Having now found time to look why these happen, I
    came up with below patch, which
    - prevents accessing MCi_MISCj with j > 0 when the block pointer in
    MCi_MISC0 is zero
    - accesses only contiguous MCi_MISCj until a non-implemented one is
    found
    - doesn't touch unimplemented blocks in mce_threshold_interrupt at all
    - gives names to two bits previously derived from MASK_VALID_HI (it
    took me some time to understand the code without this)
    
    The first three items, besides being apparently closer to the spec, should
    namely help cutting down on the time mce_threshold_interrupt() takes.
    
    Signed-off-by: Andi Kleen <[EMAIL PROTECTED]>
---
 arch/x86_64/kernel/mce_amd.c |   40 +++++++++++++++++++++++++---------------
 1 files changed, 25 insertions(+), 15 deletions(-)

diff --git a/arch/x86_64/kernel/mce_amd.c b/arch/x86_64/kernel/mce_amd.c
index 93c7072..cd8dbe5 100644
--- a/arch/x86_64/kernel/mce_amd.c
+++ b/arch/x86_64/kernel/mce_amd.c
@@ -37,6 +37,8 @@
 #define THRESHOLD_MAX     0xFFF
 #define INT_TYPE_APIC     0x00020000
 #define MASK_VALID_HI     0x80000000
+#define MASK_CNTP_HI      0x40000000
+#define MASK_LOCKED_HI    0x20000000
 #define MASK_LVTOFF_HI    0x00F00000
 #define MASK_COUNT_EN_HI  0x00080000
 #define MASK_INT_TYPE_HI  0x00060000
@@ -122,14 +124,17 @@ void __cpuinit mce_amd_feature_init(struct cpuinfo_x86 *c)
                for (block = 0; block < NR_BLOCKS; ++block) {
                        if (block == 0)
                                address = MSR_IA32_MC0_MISC + bank * 4;
-                       else if (block == 1)
-                               address = MCG_XBLK_ADDR
-                                       + ((low & MASK_BLKPTR_LO) >> 21);
+                       else if (block == 1) {
+                               address = (low & MASK_BLKPTR_LO) >> 21;
+                               if (!address)
+                                       break;
+                               address += MCG_XBLK_ADDR;
+                       }
                        else
                                ++address;
 
                        if (rdmsr_safe(address, &low, &high))
-                               continue;
+                               break;
 
                        if (!(high & MASK_VALID_HI)) {
                                if (block)
@@ -138,8 +143,8 @@ void __cpuinit mce_amd_feature_init(struct cpuinfo_x86 *c)
                                        break;
                        }
 
-                       if (!(high & MASK_VALID_HI >> 1)  ||
-                            (high & MASK_VALID_HI >> 2))
+                       if (!(high & MASK_CNTP_HI)  ||
+                            (high & MASK_LOCKED_HI))
                                continue;
 
                        if (!block)
@@ -187,17 +192,22 @@ asmlinkage void mce_threshold_interrupt(void)
 
        /* assume first bank caused it */
        for (bank = 0; bank < NR_BANKS; ++bank) {
+               if (!(per_cpu(bank_map, m.cpu) & (1 << bank)))
+                       continue;
                for (block = 0; block < NR_BLOCKS; ++block) {
                        if (block == 0)
                                address = MSR_IA32_MC0_MISC + bank * 4;
-                       else if (block == 1)
-                               address = MCG_XBLK_ADDR
-                                       + ((low & MASK_BLKPTR_LO) >> 21);
+                       else if (block == 1) {
+                               address = (low & MASK_BLKPTR_LO) >> 21;
+                               if (!address)
+                                       break;
+                               address += MCG_XBLK_ADDR;
+                       }
                        else
                                ++address;
 
                        if (rdmsr_safe(address, &low, &high))
-                               continue;
+                               break;
 
                        if (!(high & MASK_VALID_HI)) {
                                if (block)
@@ -206,8 +216,8 @@ asmlinkage void mce_threshold_interrupt(void)
                                        break;
                        }
 
-                       if (!(high & MASK_VALID_HI >> 1)  ||
-                            (high & MASK_VALID_HI >> 2))
+                       if (!(high & MASK_CNTP_HI)  ||
+                            (high & MASK_LOCKED_HI))
                                continue;
 
                        if (high & MASK_OVERFLOW_HI) {
@@ -385,7 +395,7 @@ static __cpuinit int allocate_threshold_blocks(unsigned int 
cpu,
                return 0;
 
        if (rdmsr_safe(address, &low, &high))
-               goto recurse;
+               return 0;
 
        if (!(high & MASK_VALID_HI)) {
                if (block)
@@ -394,8 +404,8 @@ static __cpuinit int allocate_threshold_blocks(unsigned int 
cpu,
                        return 0;
        }
 
-       if (!(high & MASK_VALID_HI >> 1)  ||
-            (high & MASK_VALID_HI >> 2))
+       if (!(high & MASK_CNTP_HI)  ||
+            (high & MASK_LOCKED_HI))
                goto recurse;
 
        b = kzalloc(sizeof(struct threshold_block), GFP_KERNEL);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to