diff options
author | Tony Luck <tony.luck@intel.com> | 2007-04-30 16:56:17 -0400 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2007-04-30 16:56:17 -0400 |
commit | d29182534c5f39ff899763d1e0982d8f33791d6f (patch) | |
tree | 69fd6a52145b22650799493b54e8795e988a89af /arch/ia64/kernel | |
parent | b643b0fdbc59cf6bbb086974b29d2571e9e9f646 (diff) | |
parent | ddd83eff58888928115b3e225a46d3c686e64594 (diff) |
Pull mem-attribute into release branch
Diffstat (limited to 'arch/ia64/kernel')
-rw-r--r-- | arch/ia64/kernel/efi.c | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index f45f91d38cab..78d29b79947d 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c | |||
@@ -660,6 +660,29 @@ efi_memory_descriptor (unsigned long phys_addr) | |||
660 | return NULL; | 660 | return NULL; |
661 | } | 661 | } |
662 | 662 | ||
663 | static int | ||
664 | efi_memmap_intersects (unsigned long phys_addr, unsigned long size) | ||
665 | { | ||
666 | void *efi_map_start, *efi_map_end, *p; | ||
667 | efi_memory_desc_t *md; | ||
668 | u64 efi_desc_size; | ||
669 | unsigned long end; | ||
670 | |||
671 | efi_map_start = __va(ia64_boot_param->efi_memmap); | ||
672 | efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; | ||
673 | efi_desc_size = ia64_boot_param->efi_memdesc_size; | ||
674 | |||
675 | end = phys_addr + size; | ||
676 | |||
677 | for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { | ||
678 | md = p; | ||
679 | |||
680 | if (md->phys_addr < end && efi_md_end(md) > phys_addr) | ||
681 | return 1; | ||
682 | } | ||
683 | return 0; | ||
684 | } | ||
685 | |||
663 | u32 | 686 | u32 |
664 | efi_mem_type (unsigned long phys_addr) | 687 | efi_mem_type (unsigned long phys_addr) |
665 | { | 688 | { |
@@ -766,11 +789,28 @@ valid_phys_addr_range (unsigned long phys_addr, unsigned long size) | |||
766 | int | 789 | int |
767 | valid_mmap_phys_addr_range (unsigned long pfn, unsigned long size) | 790 | valid_mmap_phys_addr_range (unsigned long pfn, unsigned long size) |
768 | { | 791 | { |
792 | unsigned long phys_addr = pfn << PAGE_SHIFT; | ||
793 | u64 attr; | ||
794 | |||
795 | attr = efi_mem_attribute(phys_addr, size); | ||
796 | |||
769 | /* | 797 | /* |
770 | * MMIO regions are often missing from the EFI memory map. | 798 | * /dev/mem mmap uses normal user pages, so we don't need the entire |
771 | * We must allow mmap of them for programs like X, so we | 799 | * granule, but the entire region we're mapping must support the same |
772 | * currently can't do any useful validation. | 800 | * attribute. |
773 | */ | 801 | */ |
802 | if (attr & EFI_MEMORY_WB || attr & EFI_MEMORY_UC) | ||
803 | return 1; | ||
804 | |||
805 | /* | ||
806 | * Intel firmware doesn't tell us about all the MMIO regions, so | ||
807 | * in general we have to allow mmap requests. But if EFI *does* | ||
808 | * tell us about anything inside this region, we should deny it. | ||
809 | * The user can always map a smaller region to avoid the overlap. | ||
810 | */ | ||
811 | if (efi_memmap_intersects(phys_addr, size)) | ||
812 | return 0; | ||
813 | |||
774 | return 1; | 814 | return 1; |
775 | } | 815 | } |
776 | 816 | ||