diff options
Diffstat (limited to 'arch/x86/mm/pat.c')
| -rw-r--r-- | arch/x86/mm/pat.c | 94 |
1 files changed, 91 insertions, 3 deletions
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index d4585077977..2fe30916d4b 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c | |||
| @@ -12,6 +12,8 @@ | |||
| 12 | #include <linux/gfp.h> | 12 | #include <linux/gfp.h> |
| 13 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
| 14 | #include <linux/bootmem.h> | 14 | #include <linux/bootmem.h> |
| 15 | #include <linux/debugfs.h> | ||
| 16 | #include <linux/seq_file.h> | ||
| 15 | 17 | ||
| 16 | #include <asm/msr.h> | 18 | #include <asm/msr.h> |
| 17 | #include <asm/tlbflush.h> | 19 | #include <asm/tlbflush.h> |
| @@ -373,8 +375,8 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, | |||
| 373 | return vma_prot; | 375 | return vma_prot; |
| 374 | } | 376 | } |
| 375 | 377 | ||
| 376 | #ifdef CONFIG_NONPROMISC_DEVMEM | 378 | #ifdef CONFIG_STRICT_DEVMEM |
| 377 | /* This check is done in drivers/char/mem.c in case of NONPROMISC_DEVMEM*/ | 379 | /* This check is done in drivers/char/mem.c in case of STRICT_DEVMEM*/ |
| 378 | static inline int range_is_allowed(unsigned long pfn, unsigned long size) | 380 | static inline int range_is_allowed(unsigned long pfn, unsigned long size) |
| 379 | { | 381 | { |
| 380 | return 1; | 382 | return 1; |
| @@ -398,7 +400,7 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size) | |||
| 398 | } | 400 | } |
| 399 | return 1; | 401 | return 1; |
| 400 | } | 402 | } |
| 401 | #endif /* CONFIG_NONPROMISC_DEVMEM */ | 403 | #endif /* CONFIG_STRICT_DEVMEM */ |
| 402 | 404 | ||
| 403 | int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, | 405 | int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, |
| 404 | unsigned long size, pgprot_t *vma_prot) | 406 | unsigned long size, pgprot_t *vma_prot) |
| @@ -489,3 +491,89 @@ void unmap_devmem(unsigned long pfn, unsigned long size, pgprot_t vma_prot) | |||
| 489 | 491 | ||
| 490 | free_memtype(addr, addr + size); | 492 | free_memtype(addr, addr + size); |
| 491 | } | 493 | } |
| 494 | |||
| 495 | #if defined(CONFIG_DEBUG_FS) | ||
| 496 | |||
| 497 | /* get Nth element of the linked list */ | ||
| 498 | static struct memtype *memtype_get_idx(loff_t pos) | ||
| 499 | { | ||
| 500 | struct memtype *list_node, *print_entry; | ||
| 501 | int i = 1; | ||
| 502 | |||
| 503 | print_entry = kmalloc(sizeof(struct memtype), GFP_KERNEL); | ||
| 504 | if (!print_entry) | ||
| 505 | return NULL; | ||
| 506 | |||
| 507 | spin_lock(&memtype_lock); | ||
| 508 | list_for_each_entry(list_node, &memtype_list, nd) { | ||
| 509 | if (pos == i) { | ||
| 510 | *print_entry = *list_node; | ||
| 511 | spin_unlock(&memtype_lock); | ||
| 512 | return print_entry; | ||
| 513 | } | ||
| 514 | ++i; | ||
| 515 | } | ||
| 516 | spin_unlock(&memtype_lock); | ||
| 517 | kfree(print_entry); | ||
| 518 | return NULL; | ||
| 519 | } | ||
| 520 | |||
| 521 | static void *memtype_seq_start(struct seq_file *seq, loff_t *pos) | ||
| 522 | { | ||
| 523 | if (*pos == 0) { | ||
| 524 | ++*pos; | ||
| 525 | seq_printf(seq, "PAT memtype list:\n"); | ||
| 526 | } | ||
| 527 | |||
| 528 | return memtype_get_idx(*pos); | ||
| 529 | } | ||
| 530 | |||
| 531 | static void *memtype_seq_next(struct seq_file *seq, void *v, loff_t *pos) | ||
| 532 | { | ||
| 533 | ++*pos; | ||
| 534 | return memtype_get_idx(*pos); | ||
| 535 | } | ||
| 536 | |||
| 537 | static void memtype_seq_stop(struct seq_file *seq, void *v) | ||
| 538 | { | ||
| 539 | } | ||
| 540 | |||
| 541 | static int memtype_seq_show(struct seq_file *seq, void *v) | ||
| 542 | { | ||
| 543 | struct memtype *print_entry = (struct memtype *)v; | ||
| 544 | |||
| 545 | seq_printf(seq, "%s @ 0x%Lx-0x%Lx\n", cattr_name(print_entry->type), | ||
| 546 | print_entry->start, print_entry->end); | ||
| 547 | kfree(print_entry); | ||
| 548 | return 0; | ||
| 549 | } | ||
| 550 | |||
| 551 | static struct seq_operations memtype_seq_ops = { | ||
| 552 | .start = memtype_seq_start, | ||
| 553 | .next = memtype_seq_next, | ||
| 554 | .stop = memtype_seq_stop, | ||
| 555 | .show = memtype_seq_show, | ||
| 556 | }; | ||
| 557 | |||
| 558 | static int memtype_seq_open(struct inode *inode, struct file *file) | ||
| 559 | { | ||
| 560 | return seq_open(file, &memtype_seq_ops); | ||
| 561 | } | ||
| 562 | |||
| 563 | static const struct file_operations memtype_fops = { | ||
| 564 | .open = memtype_seq_open, | ||
| 565 | .read = seq_read, | ||
| 566 | .llseek = seq_lseek, | ||
| 567 | .release = seq_release, | ||
| 568 | }; | ||
| 569 | |||
| 570 | static int __init pat_memtype_list_init(void) | ||
| 571 | { | ||
| 572 | debugfs_create_file("pat_memtype_list", S_IRUSR, arch_debugfs_dir, | ||
| 573 | NULL, &memtype_fops); | ||
| 574 | return 0; | ||
| 575 | } | ||
| 576 | |||
| 577 | late_initcall(pat_memtype_list_init); | ||
| 578 | |||
| 579 | #endif /* CONFIG_DEBUG_FS */ | ||
