diff options
| -rw-r--r-- | arch/x86/kernel/process_32.c | 11 | ||||
| -rw-r--r-- | arch/x86/kernel/process_64.c | 9 | ||||
| -rw-r--r-- | arch/x86/kernel/tboot.c | 73 | ||||
| -rw-r--r-- | arch/x86/kernel/traps.c | 2 |
4 files changed, 90 insertions, 5 deletions
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 0339f5c14bf9..f8adefca71dc 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
| @@ -110,11 +110,16 @@ void __show_regs(struct pt_regs *regs, int all) | |||
| 110 | get_debugreg(d1, 1); | 110 | get_debugreg(d1, 1); |
| 111 | get_debugreg(d2, 2); | 111 | get_debugreg(d2, 2); |
| 112 | get_debugreg(d3, 3); | 112 | get_debugreg(d3, 3); |
| 113 | printk(KERN_DEFAULT "DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n", | ||
| 114 | d0, d1, d2, d3); | ||
| 115 | |||
| 116 | get_debugreg(d6, 6); | 113 | get_debugreg(d6, 6); |
| 117 | get_debugreg(d7, 7); | 114 | get_debugreg(d7, 7); |
| 115 | |||
| 116 | /* Only print out debug registers if they are in their non-default state. */ | ||
| 117 | if ((d0 == 0) && (d1 == 0) && (d2 == 0) && (d3 == 0) && | ||
| 118 | (d6 == DR6_RESERVED) && (d7 == 0x400)) | ||
| 119 | return; | ||
| 120 | |||
| 121 | printk(KERN_DEFAULT "DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n", | ||
| 122 | d0, d1, d2, d3); | ||
| 118 | printk(KERN_DEFAULT "DR6: %08lx DR7: %08lx\n", | 123 | printk(KERN_DEFAULT "DR6: %08lx DR7: %08lx\n", |
| 119 | d6, d7); | 124 | d6, d7); |
| 120 | } | 125 | } |
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index f99a242730e9..05646bab4ca6 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
| @@ -105,11 +105,18 @@ void __show_regs(struct pt_regs *regs, int all) | |||
| 105 | get_debugreg(d0, 0); | 105 | get_debugreg(d0, 0); |
| 106 | get_debugreg(d1, 1); | 106 | get_debugreg(d1, 1); |
| 107 | get_debugreg(d2, 2); | 107 | get_debugreg(d2, 2); |
| 108 | printk(KERN_DEFAULT "DR0: %016lx DR1: %016lx DR2: %016lx\n", d0, d1, d2); | ||
| 109 | get_debugreg(d3, 3); | 108 | get_debugreg(d3, 3); |
| 110 | get_debugreg(d6, 6); | 109 | get_debugreg(d6, 6); |
| 111 | get_debugreg(d7, 7); | 110 | get_debugreg(d7, 7); |
| 111 | |||
| 112 | /* Only print out debug registers if they are in their non-default state. */ | ||
| 113 | if ((d0 == 0) && (d1 == 0) && (d2 == 0) && (d3 == 0) && | ||
| 114 | (d6 == DR6_RESERVED) && (d7 == 0x400)) | ||
| 115 | return; | ||
| 116 | |||
| 117 | printk(KERN_DEFAULT "DR0: %016lx DR1: %016lx DR2: %016lx\n", d0, d1, d2); | ||
| 112 | printk(KERN_DEFAULT "DR3: %016lx DR6: %016lx DR7: %016lx\n", d3, d6, d7); | 118 | printk(KERN_DEFAULT "DR3: %016lx DR6: %016lx DR7: %016lx\n", d3, d6, d7); |
| 119 | |||
| 113 | } | 120 | } |
| 114 | 121 | ||
| 115 | void release_thread(struct task_struct *dead_task) | 122 | void release_thread(struct task_struct *dead_task) |
diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c index f84fe00fad48..3ff42d2f046d 100644 --- a/arch/x86/kernel/tboot.c +++ b/arch/x86/kernel/tboot.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <linux/pfn.h> | 31 | #include <linux/pfn.h> |
| 32 | #include <linux/mm.h> | 32 | #include <linux/mm.h> |
| 33 | #include <linux/tboot.h> | 33 | #include <linux/tboot.h> |
| 34 | #include <linux/debugfs.h> | ||
| 34 | 35 | ||
| 35 | #include <asm/realmode.h> | 36 | #include <asm/realmode.h> |
| 36 | #include <asm/processor.h> | 37 | #include <asm/processor.h> |
| @@ -338,6 +339,73 @@ static struct notifier_block tboot_cpu_notifier __cpuinitdata = | |||
| 338 | .notifier_call = tboot_cpu_callback, | 339 | .notifier_call = tboot_cpu_callback, |
| 339 | }; | 340 | }; |
| 340 | 341 | ||
| 342 | #ifdef CONFIG_DEBUG_FS | ||
| 343 | |||
| 344 | #define TBOOT_LOG_UUID { 0x26, 0x25, 0x19, 0xc0, 0x30, 0x6b, 0xb4, 0x4d, \ | ||
| 345 | 0x4c, 0x84, 0xa3, 0xe9, 0x53, 0xb8, 0x81, 0x74 } | ||
| 346 | |||
| 347 | #define TBOOT_SERIAL_LOG_ADDR 0x60000 | ||
| 348 | #define TBOOT_SERIAL_LOG_SIZE 0x08000 | ||
| 349 | #define LOG_MAX_SIZE_OFF 16 | ||
| 350 | #define LOG_BUF_OFF 24 | ||
| 351 | |||
| 352 | static uint8_t tboot_log_uuid[16] = TBOOT_LOG_UUID; | ||
| 353 | |||
| 354 | static ssize_t tboot_log_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) | ||
| 355 | { | ||
| 356 | void __iomem *log_base; | ||
| 357 | u8 log_uuid[16]; | ||
| 358 | u32 max_size; | ||
| 359 | void *kbuf; | ||
| 360 | int ret = -EFAULT; | ||
| 361 | |||
| 362 | log_base = ioremap_nocache(TBOOT_SERIAL_LOG_ADDR, TBOOT_SERIAL_LOG_SIZE); | ||
| 363 | if (!log_base) | ||
| 364 | return ret; | ||
| 365 | |||
| 366 | memcpy_fromio(log_uuid, log_base, sizeof(log_uuid)); | ||
| 367 | if (memcmp(&tboot_log_uuid, log_uuid, sizeof(log_uuid))) | ||
| 368 | goto err_iounmap; | ||
| 369 | |||
| 370 | max_size = readl(log_base + LOG_MAX_SIZE_OFF); | ||
| 371 | if (*ppos >= max_size) { | ||
| 372 | ret = 0; | ||
| 373 | goto err_iounmap; | ||
| 374 | } | ||
| 375 | |||
| 376 | if (*ppos + count > max_size) | ||
| 377 | count = max_size - *ppos; | ||
| 378 | |||
| 379 | kbuf = kmalloc(count, GFP_KERNEL); | ||
| 380 | if (!kbuf) { | ||
| 381 | ret = -ENOMEM; | ||
| 382 | goto err_iounmap; | ||
| 383 | } | ||
| 384 | |||
| 385 | memcpy_fromio(kbuf, log_base + LOG_BUF_OFF + *ppos, count); | ||
| 386 | if (copy_to_user(user_buf, kbuf, count)) | ||
| 387 | goto err_kfree; | ||
| 388 | |||
| 389 | *ppos += count; | ||
| 390 | |||
| 391 | ret = count; | ||
| 392 | |||
| 393 | err_kfree: | ||
| 394 | kfree(kbuf); | ||
| 395 | |||
| 396 | err_iounmap: | ||
| 397 | iounmap(log_base); | ||
| 398 | |||
| 399 | return ret; | ||
| 400 | } | ||
| 401 | |||
| 402 | static const struct file_operations tboot_log_fops = { | ||
| 403 | .read = tboot_log_read, | ||
| 404 | .llseek = default_llseek, | ||
| 405 | }; | ||
| 406 | |||
| 407 | #endif /* CONFIG_DEBUG_FS */ | ||
| 408 | |||
| 341 | static __init int tboot_late_init(void) | 409 | static __init int tboot_late_init(void) |
| 342 | { | 410 | { |
| 343 | if (!tboot_enabled()) | 411 | if (!tboot_enabled()) |
| @@ -348,6 +416,11 @@ static __init int tboot_late_init(void) | |||
| 348 | atomic_set(&ap_wfs_count, 0); | 416 | atomic_set(&ap_wfs_count, 0); |
| 349 | register_hotcpu_notifier(&tboot_cpu_notifier); | 417 | register_hotcpu_notifier(&tboot_cpu_notifier); |
| 350 | 418 | ||
| 419 | #ifdef CONFIG_DEBUG_FS | ||
| 420 | debugfs_create_file("tboot_log", S_IRUSR, | ||
| 421 | arch_debugfs_dir, NULL, &tboot_log_fops); | ||
| 422 | #endif | ||
| 423 | |||
| 351 | acpi_os_set_prepare_sleep(&tboot_sleep); | 424 | acpi_os_set_prepare_sleep(&tboot_sleep); |
| 352 | return 0; | 425 | return 0; |
| 353 | } | 426 | } |
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 167d481c5fd3..ee3d8e510504 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
| @@ -440,7 +440,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) | |||
| 440 | /* Store the virtualized DR6 value */ | 440 | /* Store the virtualized DR6 value */ |
| 441 | tsk->thread.debugreg6 = dr6; | 441 | tsk->thread.debugreg6 = dr6; |
| 442 | 442 | ||
| 443 | if (notify_die(DIE_DEBUG, "debug", regs, PTR_ERR(&dr6), error_code, | 443 | if (notify_die(DIE_DEBUG, "debug", regs, (long)&dr6, error_code, |
| 444 | SIGTRAP) == NOTIFY_STOP) | 444 | SIGTRAP) == NOTIFY_STOP) |
| 445 | goto exit; | 445 | goto exit; |
| 446 | 446 | ||
