cpu_debug.c 17 KB

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