linux/arch/x86/kernel/cpu/cpu_debug.c
<<
>>
Prefs
   1/*
   2 * CPU x86 architecture debug code
   3 *
   4 * Copyright(C) 2009 Jaswinder Singh Rajput
   5 *
   6 * For licencing details see kernel-base/COPYING
   7 */
   8
   9#include <linux/interrupt.h>
  10#include <linux/compiler.h>
  11#include <linux/seq_file.h>
  12#include <linux/debugfs.h>
  13#include <linux/kprobes.h>
  14#include <linux/uaccess.h>
  15#include <linux/kernel.h>
  16#include <linux/module.h>
  17#include <linux/percpu.h>
  18#include <linux/signal.h>
  19#include <linux/errno.h>
  20#include <linux/sched.h>
  21#include <linux/types.h>
  22#include <linux/init.h>
  23#include <linux/slab.h>
  24#include <linux/smp.h>
  25
  26#include <asm/cpu_debug.h>
  27#include <asm/paravirt.h>
  28#include <asm/system.h>
  29#include <asm/traps.h>
  30#include <asm/apic.h>
  31#include <asm/desc.h>
  32
  33static DEFINE_PER_CPU(struct cpu_cpuX_base [CPU_REG_ALL_BIT], cpu_arr);
  34static DEFINE_PER_CPU(struct cpu_private * [MAX_CPU_FILES], priv_arr);
  35static DEFINE_PER_CPU(int, cpu_priv_count);
  36
  37static DEFINE_MUTEX(cpu_debug_lock);
  38
  39static struct dentry *cpu_debugfs_dir;
  40
  41static struct cpu_debug_base cpu_base[] = {
  42        { "mc",         CPU_MC,         0       },
  43        { "monitor",    CPU_MONITOR,    0       },
  44        { "time",       CPU_TIME,       0       },
  45        { "pmc",        CPU_PMC,        1       },
  46        { "platform",   CPU_PLATFORM,   0       },
  47        { "apic",       CPU_APIC,       0       },
  48        { "poweron",    CPU_POWERON,    0       },
  49        { "control",    CPU_CONTROL,    0       },
  50        { "features",   CPU_FEATURES,   0       },
  51        { "lastbranch", CPU_LBRANCH,    0       },
  52        { "bios",       CPU_BIOS,       0       },
  53        { "freq",       CPU_FREQ,       0       },
  54        { "mtrr",       CPU_MTRR,       0       },
  55        { "perf",       CPU_PERF,       0       },
  56        { "cache",      CPU_CACHE,      0       },
  57        { "sysenter",   CPU_SYSENTER,   0       },
  58        { "therm",      CPU_THERM,      0       },
  59        { "misc",       CPU_MISC,       0       },
  60        { "debug",      CPU_DEBUG,      0       },
  61        { "pat",        CPU_PAT,        0       },
  62        { "vmx",        CPU_VMX,        0       },
  63        { "call",       CPU_CALL,       0       },
  64        { "base",       CPU_BASE,       0       },
  65        { "ver",        CPU_VER,        0       },
  66        { "conf",       CPU_CONF,       0       },
  67        { "smm",        CPU_SMM,        0       },
  68        { "svm",        CPU_SVM,        0       },
  69        { "osvm",       CPU_OSVM,       0       },
  70        { "tss",        CPU_TSS,        0       },
  71        { "cr",         CPU_CR,         0       },
  72        { "dt",         CPU_DT,         0       },
  73        { "registers",  CPU_REG_ALL,    0       },
  74};
  75
  76static struct cpu_file_base cpu_file[] = {
  77        { "index",      CPU_REG_ALL,    0       },
  78        { "value",      CPU_REG_ALL,    1       },
  79};
  80
  81/* CPU Registers Range */
  82static struct cpu_debug_range cpu_reg_range[] = {
  83        { 0x00000000, 0x00000001, CPU_MC,       },
  84        { 0x00000006, 0x00000007, CPU_MONITOR,  },
  85        { 0x00000010, 0x00000010, CPU_TIME,     },
  86        { 0x00000011, 0x00000013, CPU_PMC,      },
  87        { 0x00000017, 0x00000017, CPU_PLATFORM, },
  88        { 0x0000001B, 0x0000001B, CPU_APIC,     },
  89        { 0x0000002A, 0x0000002B, CPU_POWERON,  },
  90        { 0x0000002C, 0x0000002C, CPU_FREQ,     },
  91        { 0x0000003A, 0x0000003A, CPU_CONTROL,  },
  92        { 0x00000040, 0x00000047, CPU_LBRANCH,  },
  93        { 0x00000060, 0x00000067, CPU_LBRANCH,  },
  94        { 0x00000079, 0x00000079, CPU_BIOS,     },
  95        { 0x00000088, 0x0000008A, CPU_CACHE,    },
  96        { 0x0000008B, 0x0000008B, CPU_BIOS,     },
  97        { 0x0000009B, 0x0000009B, CPU_MONITOR,  },
  98        { 0x000000C1, 0x000000C4, CPU_PMC,      },
  99        { 0x000000CD, 0x000000CD, CPU_FREQ,     },
 100        { 0x000000E7, 0x000000E8, CPU_PERF,     },
 101        { 0x000000FE, 0x000000FE, CPU_MTRR,     },
 102
 103        { 0x00000116, 0x0000011E, CPU_CACHE,    },
 104        { 0x00000174, 0x00000176, CPU_SYSENTER, },
 105        { 0x00000179, 0x0000017B, CPU_MC,       },
 106        { 0x00000186, 0x00000189, CPU_PMC,      },
 107        { 0x00000198, 0x00000199, CPU_PERF,     },
 108        { 0x0000019A, 0x0000019A, CPU_TIME,     },
 109        { 0x0000019B, 0x0000019D, CPU_THERM,    },
 110        { 0x000001A0, 0x000001A0, CPU_MISC,     },
 111        { 0x000001C9, 0x000001C9, CPU_LBRANCH,  },
 112        { 0x000001D7, 0x000001D8, CPU_LBRANCH,  },
 113        { 0x000001D9, 0x000001D9, CPU_DEBUG,    },
 114        { 0x000001DA, 0x000001E0, CPU_LBRANCH,  },
 115
 116        { 0x00000200, 0x0000020F, CPU_MTRR,     },
 117        { 0x00000250, 0x00000250, CPU_MTRR,     },
 118        { 0x00000258, 0x00000259, CPU_MTRR,     },
 119        { 0x00000268, 0x0000026F, CPU_MTRR,     },
 120        { 0x00000277, 0x00000277, CPU_PAT,      },
 121        { 0x000002FF, 0x000002FF, CPU_MTRR,     },
 122
 123        { 0x00000300, 0x00000311, CPU_PMC,      },
 124        { 0x00000345, 0x00000345, CPU_PMC,      },
 125        { 0x00000360, 0x00000371, CPU_PMC,      },
 126        { 0x0000038D, 0x00000390, CPU_PMC,      },
 127        { 0x000003A0, 0x000003BE, CPU_PMC,      },
 128        { 0x000003C0, 0x000003CD, CPU_PMC,      },
 129        { 0x000003E0, 0x000003E1, CPU_PMC,      },
 130        { 0x000003F0, 0x000003F2, CPU_PMC,      },
 131
 132        { 0x00000400, 0x00000417, CPU_MC,       },
 133        { 0x00000480, 0x0000048B, CPU_VMX,      },
 134
 135        { 0x00000600, 0x00000600, CPU_DEBUG,    },
 136        { 0x00000680, 0x0000068F, CPU_LBRANCH,  },
 137        { 0x000006C0, 0x000006CF, CPU_LBRANCH,  },
 138
 139        { 0x000107CC, 0x000107D3, CPU_PMC,      },
 140
 141        { 0xC0000080, 0xC0000080, CPU_FEATURES, },
 142        { 0xC0000081, 0xC0000084, CPU_CALL,     },
 143        { 0xC0000100, 0xC0000102, CPU_BASE,     },
 144        { 0xC0000103, 0xC0000103, CPU_TIME,     },
 145
 146        { 0xC0010000, 0xC0010007, CPU_PMC,      },
 147        { 0xC0010010, 0xC0010010, CPU_CONF,     },
 148        { 0xC0010015, 0xC0010015, CPU_CONF,     },
 149        { 0xC0010016, 0xC001001A, CPU_MTRR,     },
 150        { 0xC001001D, 0xC001001D, CPU_MTRR,     },
 151        { 0xC001001F, 0xC001001F, CPU_CONF,     },
 152        { 0xC0010030, 0xC0010035, CPU_BIOS,     },
 153        { 0xC0010044, 0xC0010048, CPU_MC,       },
 154        { 0xC0010050, 0xC0010056, CPU_SMM,      },
 155        { 0xC0010058, 0xC0010058, CPU_CONF,     },
 156        { 0xC0010060, 0xC0010060, CPU_CACHE,    },
 157        { 0xC0010061, 0xC0010068, CPU_SMM,      },
 158        { 0xC0010069, 0xC001006B, CPU_SMM,      },
 159        { 0xC0010070, 0xC0010071, CPU_SMM,      },
 160        { 0xC0010111, 0xC0010113, CPU_SMM,      },
 161        { 0xC0010114, 0xC0010118, CPU_SVM,      },
 162        { 0xC0010140, 0xC0010141, CPU_OSVM,     },
 163        { 0xC0011022, 0xC0011023, CPU_CONF,     },
 164};
 165
 166static int is_typeflag_valid(unsigned cpu, unsigned flag)
 167{
 168        int i;
 169
 170        /* Standard Registers should be always valid */
 171        if (flag >= CPU_TSS)
 172                return 1;
 173
 174        for (i = 0; i < ARRAY_SIZE(cpu_reg_range); i++) {
 175                if (cpu_reg_range[i].flag == flag)
 176                        return 1;
 177        }
 178
 179        /* Invalid */
 180        return 0;
 181}
 182
 183static unsigned get_cpu_range(unsigned cpu, unsigned *min, unsigned *max,
 184                              int index, unsigned flag)
 185{
 186        if (cpu_reg_range[index].flag == flag) {
 187                *min = cpu_reg_range[index].min;
 188                *max = cpu_reg_range[index].max;
 189        } else
 190                *max = 0;
 191
 192        return *max;
 193}
 194
 195/* This function can also be called with seq = NULL for printk */
 196static void print_cpu_data(struct seq_file *seq, unsigned type,
 197                           u32 low, u32 high)
 198{
 199        struct cpu_private *priv;
 200        u64 val = high;
 201
 202        if (seq) {
 203                priv = seq->private;
 204                if (priv->file) {
 205                        val = (val << 32) | low;
 206                        seq_printf(seq, "0x%llx\n", val);
 207                } else
 208                        seq_printf(seq, " %08x: %08x_%08x\n",
 209                                   type, high, low);
 210        } else
 211                printk(KERN_INFO " %08x: %08x_%08x\n", type, high, low);
 212}
 213
 214/* This function can also be called with seq = NULL for printk */
 215static void print_msr(struct seq_file *seq, unsigned cpu, unsigned flag)
 216{
 217        unsigned msr, msr_min, msr_max;
 218        struct cpu_private *priv;
 219        u32 low, high;
 220        int i;
 221
 222        if (seq) {
 223                priv = seq->private;
 224                if (priv->file) {
 225                        if (!rdmsr_safe_on_cpu(priv->cpu, priv->reg,
 226                                               &low, &high))
 227                                print_cpu_data(seq, priv->reg, low, high);
 228                        return;
 229                }
 230        }
 231
 232        for (i = 0; i < ARRAY_SIZE(cpu_reg_range); i++) {
 233                if (!get_cpu_range(cpu, &msr_min, &msr_max, i, flag))
 234                        continue;
 235
 236                for (msr = msr_min; msr <= msr_max; msr++) {
 237                        if (rdmsr_safe_on_cpu(cpu, msr, &low, &high))
 238                                continue;
 239                        print_cpu_data(seq, msr, low, high);
 240                }
 241        }
 242}
 243
 244static void print_tss(void *arg)
 245{
 246        struct pt_regs *regs = task_pt_regs(current);
 247        struct seq_file *seq = arg;
 248        unsigned int seg;
 249
 250        seq_printf(seq, " RAX\t: %016lx\n", regs->ax);
 251        seq_printf(seq, " RBX\t: %016lx\n", regs->bx);
 252        seq_printf(seq, " RCX\t: %016lx\n", regs->cx);
 253        seq_printf(seq, " RDX\t: %016lx\n", regs->dx);
 254
 255        seq_printf(seq, " RSI\t: %016lx\n", regs->si);
 256        seq_printf(seq, " RDI\t: %016lx\n", regs->di);
 257        seq_printf(seq, " RBP\t: %016lx\n", regs->bp);
 258        seq_printf(seq, " ESP\t: %016lx\n", regs->sp);
 259
 260#ifdef CONFIG_X86_64
 261        seq_printf(seq, " R08\t: %016lx\n", regs->r8);
 262        seq_printf(seq, " R09\t: %016lx\n", regs->r9);
 263        seq_printf(seq, " R10\t: %016lx\n", regs->r10);
 264        seq_printf(seq, " R11\t: %016lx\n", regs->r11);
 265        seq_printf(seq, " R12\t: %016lx\n", regs->r12);
 266        seq_printf(seq, " R13\t: %016lx\n", regs->r13);
 267        seq_printf(seq, " R14\t: %016lx\n", regs->r14);
 268        seq_printf(seq, " R15\t: %016lx\n", regs->r15);
 269#endif
 270
 271        asm("movl %%cs,%0" : "=r" (seg));
 272        seq_printf(seq, " CS\t:             %04x\n", seg);
 273        asm("movl %%ds,%0" : "=r" (seg));
 274        seq_printf(seq, " DS\t:             %04x\n", seg);
 275        seq_printf(seq, " SS\t:             %04lx\n", regs->ss & 0xffff);
 276        asm("movl %%es,%0" : "=r" (seg));
 277        seq_printf(seq, " ES\t:             %04x\n", seg);
 278        asm("movl %%fs,%0" : "=r" (seg));
 279        seq_printf(seq, " FS\t:             %04x\n", seg);
 280        asm("movl %%gs,%0" : "=r" (seg));
 281        seq_printf(seq, " GS\t:             %04x\n", seg);
 282
 283        seq_printf(seq, " EFLAGS\t: %016lx\n", regs->flags);
 284
 285        seq_printf(seq, " EIP\t: %016lx\n", regs->ip);
 286}
 287
 288static void print_cr(void *arg)
 289{
 290        struct seq_file *seq = arg;
 291
 292        seq_printf(seq, " cr0\t: %016lx\n", read_cr0());
 293        seq_printf(seq, " cr2\t: %016lx\n", read_cr2());
 294        seq_printf(seq, " cr3\t: %016lx\n", read_cr3());
 295        seq_printf(seq, " cr4\t: %016lx\n", read_cr4_safe());
 296#ifdef CONFIG_X86_64
 297        seq_printf(seq, " cr8\t: %016lx\n", read_cr8());
 298#endif
 299}
 300
 301static void print_desc_ptr(char *str, struct seq_file *seq, struct desc_ptr dt)
 302{
 303        seq_printf(seq, " %s\t: %016llx\n", str, (u64)(dt.address | dt.size));
 304}
 305
 306static void print_dt(void *seq)
 307{
 308        struct desc_ptr dt;
 309        unsigned long ldt;
 310
 311        /* IDT */
 312        store_idt((struct desc_ptr *)&dt);
 313        print_desc_ptr("IDT", seq, dt);
 314
 315        /* GDT */
 316        store_gdt((struct desc_ptr *)&dt);
 317        print_desc_ptr("GDT", seq, dt);
 318
 319        /* LDT */
 320        store_ldt(ldt);
 321        seq_printf(seq, " LDT\t: %016lx\n", ldt);
 322
 323        /* TR */
 324        store_tr(ldt);
 325        seq_printf(seq, " TR\t: %016lx\n", ldt);
 326}
 327
 328static void print_dr(void *arg)
 329{
 330        struct seq_file *seq = arg;
 331        unsigned long dr;
 332        int i;
 333
 334        for (i = 0; i < 8; i++) {
 335                /* Ignore db4, db5 */
 336                if ((i == 4) || (i == 5))
 337                        continue;
 338                get_debugreg(dr, i);
 339                seq_printf(seq, " dr%d\t: %016lx\n", i, dr);
 340        }
 341
 342        seq_printf(seq, "\n MSR\t:\n");
 343}
 344
 345static void print_apic(void *arg)
 346{
 347        struct seq_file *seq = arg;
 348
 349#ifdef CONFIG_X86_LOCAL_APIC
 350        seq_printf(seq, " LAPIC\t:\n");
 351        seq_printf(seq, " ID\t\t: %08x\n",  apic_read(APIC_ID) >> 24);
 352        seq_printf(seq, " LVR\t\t: %08x\n",  apic_read(APIC_LVR));
 353        seq_printf(seq, " TASKPRI\t: %08x\n",  apic_read(APIC_TASKPRI));
 354        seq_printf(seq, " ARBPRI\t\t: %08x\n",  apic_read(APIC_ARBPRI));
 355        seq_printf(seq, " PROCPRI\t: %08x\n",  apic_read(APIC_PROCPRI));
 356        seq_printf(seq, " LDR\t\t: %08x\n",  apic_read(APIC_LDR));
 357        seq_printf(seq, " DFR\t\t: %08x\n",  apic_read(APIC_DFR));
 358        seq_printf(seq, " SPIV\t\t: %08x\n",  apic_read(APIC_SPIV));
 359        seq_printf(seq, " ISR\t\t: %08x\n",  apic_read(APIC_ISR));
 360        seq_printf(seq, " ESR\t\t: %08x\n",  apic_read(APIC_ESR));
 361        seq_printf(seq, " ICR\t\t: %08x\n",  apic_read(APIC_ICR));
 362        seq_printf(seq, " ICR2\t\t: %08x\n",  apic_read(APIC_ICR2));
 363        seq_printf(seq, " LVTT\t\t: %08x\n",  apic_read(APIC_LVTT));
 364        seq_printf(seq, " LVTTHMR\t: %08x\n",  apic_read(APIC_LVTTHMR));
 365        seq_printf(seq, " LVTPC\t\t: %08x\n",  apic_read(APIC_LVTPC));
 366        seq_printf(seq, " LVT0\t\t: %08x\n",  apic_read(APIC_LVT0));
 367        seq_printf(seq, " LVT1\t\t: %08x\n",  apic_read(APIC_LVT1));
 368        seq_printf(seq, " LVTERR\t\t: %08x\n",  apic_read(APIC_LVTERR));
 369        seq_printf(seq, " TMICT\t\t: %08x\n",  apic_read(APIC_TMICT));
 370        seq_printf(seq, " TMCCT\t\t: %08x\n",  apic_read(APIC_TMCCT));
 371        seq_printf(seq, " TDCR\t\t: %08x\n",  apic_read(APIC_TDCR));
 372        if (boot_cpu_has(X86_FEATURE_EXTAPIC)) {
 373                unsigned int i, v, maxeilvt;
 374
 375                v = apic_read(APIC_EFEAT);
 376                maxeilvt = (v >> 16) & 0xff;
 377                seq_printf(seq, " EFEAT\t\t: %08x\n", v);
 378                seq_printf(seq, " ECTRL\t\t: %08x\n", apic_read(APIC_ECTRL));
 379
 380                for (i = 0; i < maxeilvt; i++) {
 381                        v = apic_read(APIC_EILVTn(i));
 382                        seq_printf(seq, " EILVT%d\t\t: %08x\n", i, v);
 383                }
 384        }
 385#endif /* CONFIG_X86_LOCAL_APIC */
 386        seq_printf(seq, "\n MSR\t:\n");
 387}
 388
 389static int cpu_seq_show(struct seq_file *seq, void *v)
 390{
 391        struct cpu_private *priv = seq->private;
 392
 393        if (priv == NULL)
 394                return -EINVAL;
 395
 396        switch (cpu_base[priv->type].flag) {
 397        case CPU_TSS:
 398                smp_call_function_single(priv->cpu, print_tss, seq, 1);
 399                break;
 400        case CPU_CR:
 401                smp_call_function_single(priv->cpu, print_cr, seq, 1);
 402                break;
 403        case CPU_DT:
 404                smp_call_function_single(priv->cpu, print_dt, seq, 1);
 405                break;
 406        case CPU_DEBUG:
 407                if (priv->file == CPU_INDEX_BIT)
 408                        smp_call_function_single(priv->cpu, print_dr, seq, 1);
 409                print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
 410                break;
 411        case CPU_APIC:
 412                if (priv->file == CPU_INDEX_BIT)
 413                        smp_call_function_single(priv->cpu, print_apic, seq, 1);
 414                print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
 415                break;
 416
 417        default:
 418                print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
 419                break;
 420        }
 421        seq_printf(seq, "\n");
 422
 423        return 0;
 424}
 425
 426static void *cpu_seq_start(struct seq_file *seq, loff_t *pos)
 427{
 428        if (*pos == 0) /* One time is enough ;-) */
 429                return seq;
 430
 431        return NULL;
 432}
 433
 434static void *cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 435{
 436        (*pos)++;
 437
 438        return cpu_seq_start(seq, pos);
 439}
 440
 441static void cpu_seq_stop(struct seq_file *seq, void *v)
 442{
 443}
 444
 445static const struct seq_operations cpu_seq_ops = {
 446        .start          = cpu_seq_start,
 447        .next           = cpu_seq_next,
 448        .stop           = cpu_seq_stop,
 449        .show           = cpu_seq_show,
 450};
 451
 452static int cpu_seq_open(struct inode *inode, struct file *file)
 453{
 454        struct cpu_private *priv = inode->i_private;
 455        struct seq_file *seq;
 456        int err;
 457
 458        err = seq_open(file, &cpu_seq_ops);
 459        if (!err) {
 460                seq = file->private_data;
 461                seq->private = priv;
 462        }
 463
 464        return err;
 465}
 466
 467static int write_msr(struct cpu_private *priv, u64 val)
 468{
 469        u32 low, high;
 470
 471        high = (val >> 32) & 0xffffffff;
 472        low = val & 0xffffffff;
 473
 474        if (!wrmsr_safe_on_cpu(priv->cpu, priv->reg, low, high))
 475                return 0;
 476
 477        return -EPERM;
 478}
 479
 480static int write_cpu_register(struct cpu_private *priv, const char *buf)
 481{
 482        int ret = -EPERM;
 483        u64 val;
 484
 485        ret = strict_strtoull(buf, 0, &val);
 486        if (ret < 0)
 487                return ret;
 488
 489        /* Supporting only MSRs */
 490        if (priv->type < CPU_TSS_BIT)
 491                return write_msr(priv, val);
 492
 493        return ret;
 494}
 495
 496static ssize_t cpu_write(struct file *file, const char __user *ubuf,
 497                             size_t count, loff_t *off)
 498{
 499        struct seq_file *seq = file->private_data;
 500        struct cpu_private *priv = seq->private;
 501        char buf[19];
 502
 503        if ((priv == NULL) || (count >= sizeof(buf)))
 504                return -EINVAL;
 505
 506        if (copy_from_user(&buf, ubuf, count))
 507                return -EFAULT;
 508
 509        buf[count] = 0;
 510
 511        if ((cpu_base[priv->type].write) && (cpu_file[priv->file].write))
 512                if (!write_cpu_register(priv, buf))
 513                        return count;
 514
 515        return -EACCES;
 516}
 517
 518static const struct file_operations cpu_fops = {
 519        .owner          = THIS_MODULE,
 520        .open           = cpu_seq_open,
 521        .read           = seq_read,
 522        .write          = cpu_write,
 523        .llseek         = seq_lseek,
 524        .release        = seq_release,
 525};
 526
 527static int cpu_create_file(unsigned cpu, unsigned type, unsigned reg,
 528                           unsigned file, struct dentry *dentry)
 529{
 530        struct cpu_private *priv = NULL;
 531
 532        /* Already intialized */
 533        if (file == CPU_INDEX_BIT)
 534                if (per_cpu(cpu_arr[type].init, cpu))
 535                        return 0;
 536
 537        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 538        if (priv == NULL)
 539                return -ENOMEM;
 540
 541        priv->cpu = cpu;
 542        priv->type = type;
 543        priv->reg = reg;
 544        priv->file = file;
 545        mutex_lock(&cpu_debug_lock);
 546        per_cpu(priv_arr[type], cpu) = priv;
 547        per_cpu(cpu_priv_count, cpu)++;
 548        mutex_unlock(&cpu_debug_lock);
 549
 550        if (file)
 551                debugfs_create_file(cpu_file[file].name, S_IRUGO,
 552                                    dentry, (void *)priv, &cpu_fops);
 553        else {
 554                debugfs_create_file(cpu_base[type].name, S_IRUGO,
 555                                    per_cpu(cpu_arr[type].dentry, cpu),
 556                                    (void *)priv, &cpu_fops);
 557                mutex_lock(&cpu_debug_lock);
 558                per_cpu(cpu_arr[type].init, cpu) = 1;
 559                mutex_unlock(&cpu_debug_lock);
 560        }
 561
 562        return 0;
 563}
 564
 565static int cpu_init_regfiles(unsigned cpu, unsigned int type, unsigned reg,
 566                             struct dentry *dentry)
 567{
 568        unsigned file;
 569        int err = 0;
 570
 571        for (file = 0; file <  ARRAY_SIZE(cpu_file); file++) {
 572                err = cpu_create_file(cpu, type, reg, file, dentry);
 573                if (err)
 574                        return err;
 575        }
 576
 577        return err;
 578}
 579
 580static int cpu_init_msr(unsigned cpu, unsigned type, struct dentry *dentry)
 581{
 582        struct dentry *cpu_dentry = NULL;
 583        unsigned reg, reg_min, reg_max;
 584        int i, err = 0;
 585        char reg_dir[12];
 586        u32 low, high;
 587
 588        for (i = 0; i < ARRAY_SIZE(cpu_reg_range); i++) {
 589                if (!get_cpu_range(cpu, &reg_min, &reg_max, i,
 590                                   cpu_base[type].flag))
 591                        continue;
 592
 593                for (reg = reg_min; reg <= reg_max; reg++) {
 594                        if (rdmsr_safe_on_cpu(cpu, reg, &low, &high))
 595                                continue;
 596
 597                        sprintf(reg_dir, "0x%x", reg);
 598                        cpu_dentry = debugfs_create_dir(reg_dir, dentry);
 599                        err = cpu_init_regfiles(cpu, type, reg, cpu_dentry);
 600                        if (err)
 601                                return err;
 602                }
 603        }
 604
 605        return err;
 606}
 607
 608static int cpu_init_allreg(unsigned cpu, struct dentry *dentry)
 609{
 610        struct dentry *cpu_dentry = NULL;
 611        unsigned type;
 612        int err = 0;
 613
 614        for (type = 0; type <  ARRAY_SIZE(cpu_base) - 1; type++) {
 615                if (!is_typeflag_valid(cpu, cpu_base[type].flag))
 616                        continue;
 617                cpu_dentry = debugfs_create_dir(cpu_base[type].name, dentry);
 618                per_cpu(cpu_arr[type].dentry, cpu) = cpu_dentry;
 619
 620                if (type < CPU_TSS_BIT)
 621                        err = cpu_init_msr(cpu, type, cpu_dentry);
 622                else
 623                        err = cpu_create_file(cpu, type, 0, CPU_INDEX_BIT,
 624                                              cpu_dentry);
 625                if (err)
 626                        return err;
 627        }
 628
 629        return err;
 630}
 631
 632static int cpu_init_cpu(void)
 633{
 634        struct dentry *cpu_dentry = NULL;
 635        struct cpuinfo_x86 *cpui;
 636        char cpu_dir[12];
 637        unsigned cpu;
 638        int err = 0;
 639
 640        for (cpu = 0; cpu < nr_cpu_ids; cpu++) {
 641                cpui = &cpu_data(cpu);
 642                if (!cpu_has(cpui, X86_FEATURE_MSR))
 643                        continue;
 644
 645                sprintf(cpu_dir, "cpu%d", cpu);
 646                cpu_dentry = debugfs_create_dir(cpu_dir, cpu_debugfs_dir);
 647                err = cpu_init_allreg(cpu, cpu_dentry);
 648
 649                pr_info("cpu%d(%d) debug files %d\n",
 650                        cpu, nr_cpu_ids, per_cpu(cpu_priv_count, cpu));
 651                if (per_cpu(cpu_priv_count, cpu) > MAX_CPU_FILES) {
 652                        pr_err("Register files count %d exceeds limit %d\n",
 653                                per_cpu(cpu_priv_count, cpu), MAX_CPU_FILES);
 654                        per_cpu(cpu_priv_count, cpu) = MAX_CPU_FILES;
 655                        err = -ENFILE;
 656                }
 657                if (err)
 658                        return err;
 659        }
 660
 661        return err;
 662}
 663
 664static int __init cpu_debug_init(void)
 665{
 666        cpu_debugfs_dir = debugfs_create_dir("cpu", arch_debugfs_dir);
 667
 668        return cpu_init_cpu();
 669}
 670
 671static void __exit cpu_debug_exit(void)
 672{
 673        int i, cpu;
 674
 675        if (cpu_debugfs_dir)
 676                debugfs_remove_recursive(cpu_debugfs_dir);
 677
 678        for (cpu = 0; cpu <  nr_cpu_ids; cpu++)
 679                for (i = 0; i < per_cpu(cpu_priv_count, cpu); i++)
 680                        kfree(per_cpu(priv_arr[i], cpu));
 681}
 682
 683module_init(cpu_debug_init);
 684module_exit(cpu_debug_exit);
 685
 686MODULE_AUTHOR("Jaswinder Singh Rajput");
 687MODULE_DESCRIPTION("CPU Debug module");
 688MODULE_LICENSE("GPL");
 689