aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel
diff options
context:
space:
mode:
authorTony Luck <tony.luck@intel.com>2007-04-30 16:56:17 -0400
committerTony Luck <tony.luck@intel.com>2007-04-30 16:56:17 -0400
commitd29182534c5f39ff899763d1e0982d8f33791d6f (patch)
tree69fd6a52145b22650799493b54e8795e988a89af /arch/ia64/kernel
parentb643b0fdbc59cf6bbb086974b29d2571e9e9f646 (diff)
parentddd83eff58888928115b3e225a46d3c686e64594 (diff)
Pull mem-attribute into release branch
Diffstat (limited to 'arch/ia64/kernel')
-rw-r--r--arch/ia64/kernel/efi.c46
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
663static int
664efi_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
663u32 686u32
664efi_mem_type (unsigned long phys_addr) 687efi_mem_type (unsigned long phys_addr)
665{ 688{
@@ -766,11 +789,28 @@ valid_phys_addr_range (unsigned long phys_addr, unsigned long size)
766int 789int
767valid_mmap_phys_addr_range (unsigned long pfn, unsigned long size) 790valid_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