aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/pci
diff options
context:
space:
mode:
authorBjorn Helgaas <bjorn.helgaas@hp.com>2006-05-05 19:19:50 -0400
committerTony Luck <tony.luck@intel.com>2006-05-08 19:32:05 -0400
commit32e62c636a728cb39c0b3bd191286f2ca65d4028 (patch)
tree656454a01e720819103c172daae15b5f2fd85d68 /arch/ia64/pci
parent6810b548b25114607e0814612d84125abccc0a4f (diff)
[IA64] rework memory attribute aliasing
This closes a couple holes in our attribute aliasing avoidance scheme: - The current kernel fails mmaps of some /dev/mem MMIO regions because they don't appear in the EFI memory map. This keeps X from working on the Intel Tiger box. - The current kernel allows UC mmap of the 0-1MB region of /sys/.../legacy_mem even when the chipset doesn't support UC access. This causes an MCA when starting X on HP rx7620 and rx8620 boxes in the default configuration. There's more detail in the Documentation/ia64/aliasing.txt file this adds, but the general idea is that if a region might be covered by a granule-sized kernel identity mapping, any access via /dev/mem or mmap must use the same attribute as the identity mapping. Otherwise, we fall back to using an attribute that is supported according to the EFI memory map, or to using UC if the EFI memory map doesn't mention the region. Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64/pci')
-rw-r--r--arch/ia64/pci/pci.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index ab829a22f8a4..30d148f34042 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -645,18 +645,31 @@ char *ia64_pci_get_legacy_mem(struct pci_bus *bus)
645int 645int
646pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma) 646pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma)
647{ 647{
648 unsigned long size = vma->vm_end - vma->vm_start;
649 pgprot_t prot;
648 char *addr; 650 char *addr;
649 651
652 /*
653 * Avoid attribute aliasing. See Documentation/ia64/aliasing.txt
654 * for more details.
655 */
656 if (!valid_mmap_phys_addr_range(vma->vm_pgoff << PAGE_SHIFT, size))
657 return -EINVAL;
658 prot = phys_mem_access_prot(NULL, vma->vm_pgoff, size,
659 vma->vm_page_prot);
660 if (pgprot_val(prot) != pgprot_val(pgprot_noncached(vma->vm_page_prot)))
661 return -EINVAL;
662
650 addr = pci_get_legacy_mem(bus); 663 addr = pci_get_legacy_mem(bus);
651 if (IS_ERR(addr)) 664 if (IS_ERR(addr))
652 return PTR_ERR(addr); 665 return PTR_ERR(addr);
653 666
654 vma->vm_pgoff += (unsigned long)addr >> PAGE_SHIFT; 667 vma->vm_pgoff += (unsigned long)addr >> PAGE_SHIFT;
655 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 668 vma->vm_page_prot = prot;
656 vma->vm_flags |= (VM_SHM | VM_RESERVED | VM_IO); 669 vma->vm_flags |= (VM_SHM | VM_RESERVED | VM_IO);
657 670
658 if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, 671 if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
659 vma->vm_end - vma->vm_start, vma->vm_page_prot)) 672 size, vma->vm_page_prot))
660 return -EAGAIN; 673 return -EAGAIN;
661 674
662 return 0; 675 return 0;