Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 59191
b: refs/heads/master
c: 012b710
h: refs/heads/master
i:
  59189: 56c69c0
  59187: 831d79d
  59183: d0cf9ed
v: v3
  • Loading branch information
Alex Chiang authored and Tony Luck committed Jul 11, 2007
1 parent 289a4a2 commit 87921d5
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 13 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9e121327b37b751ef66e6f57e2d02dd568955148
refs/heads/master: 012b7105cc816fb797eb1c161cdfc0052b5c3f53
26 changes: 19 additions & 7 deletions trunk/Documentation/ia64/aliasing-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/pci.h>

int sum;

Expand All @@ -34,13 +35,19 @@ int map_mem(char *path, off_t offset, size_t length, int touch)
return -1;
}

if (fnmatch("/proc/bus/pci/*", path, 0) == 0) {
rc = ioctl(fd, PCIIOC_MMAP_IS_MEM);
if (rc == -1)
perror("PCIIOC_MMAP_IS_MEM ioctl");
}

addr = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset);
if (addr == MAP_FAILED)
return 1;

if (touch) {
c = (int *) addr;
while (c < (int *) (offset + length))
while (c < (int *) (addr + length))
sum += *c++;
}

Expand All @@ -54,7 +61,7 @@ int map_mem(char *path, off_t offset, size_t length, int touch)
return 0;
}

int scan_sysfs(char *path, char *file, off_t offset, size_t length, int touch)
int scan_tree(char *path, char *file, off_t offset, size_t length, int touch)
{
struct dirent **namelist;
char *name, *path2;
Expand Down Expand Up @@ -93,7 +100,7 @@ int scan_sysfs(char *path, char *file, off_t offset, size_t length, int touch)
} else {
r = lstat(path2, &buf);
if (r == 0 && S_ISDIR(buf.st_mode)) {
rc = scan_sysfs(path2, file, offset, length, touch);
rc = scan_tree(path2, file, offset, length, touch);
if (rc < 0)
return rc;
}
Expand Down Expand Up @@ -238,10 +245,15 @@ int main()
else
fprintf(stderr, "FAIL: /dev/mem 0x0-0x100000 not accessible\n");

scan_sysfs("/sys/class/pci_bus", "legacy_mem", 0, 0xA0000, 1);
scan_sysfs("/sys/class/pci_bus", "legacy_mem", 0xA0000, 0x20000, 0);
scan_sysfs("/sys/class/pci_bus", "legacy_mem", 0xC0000, 0x40000, 1);
scan_sysfs("/sys/class/pci_bus", "legacy_mem", 0, 1024*1024, 0);
scan_tree("/sys/class/pci_bus", "legacy_mem", 0, 0xA0000, 1);
scan_tree("/sys/class/pci_bus", "legacy_mem", 0xA0000, 0x20000, 0);
scan_tree("/sys/class/pci_bus", "legacy_mem", 0xC0000, 0x40000, 1);
scan_tree("/sys/class/pci_bus", "legacy_mem", 0, 1024*1024, 0);

scan_rom("/sys/devices", "rom");

scan_tree("/proc/bus/pci", "??.?", 0, 0xA0000, 1);
scan_tree("/proc/bus/pci", "??.?", 0xA0000, 0x20000, 0);
scan_tree("/proc/bus/pci", "??.?", 0xC0000, 0x40000, 1);
scan_tree("/proc/bus/pci", "??.?", 0, 1024*1024, 0);
}
12 changes: 12 additions & 0 deletions trunk/Documentation/ia64/aliasing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,18 @@ POTENTIAL ATTRIBUTE ALIASING CASES

The /dev/mem mmap constraints apply.

mmap of /proc/bus/pci/.../??.?

This is an MMIO mmap of PCI functions, which additionally may or
may not be requested as using the WC attribute.

If WC is requested, and the region in kern_memmap is either WC
or UC, and the EFI memory map designates the region as WC, then
the WC mapping is allowed.

Otherwise, the user mapping must use the same attribute as the
kernel mapping.

read/write of /dev/mem

This uses copy_from_user(), which implicitly uses a kernel
Expand Down
22 changes: 17 additions & 5 deletions trunk/arch/ia64/pci/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,9 @@ int
pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma,
enum pci_mmap_state mmap_state, int write_combine)
{
unsigned long size = vma->vm_end - vma->vm_start;
pgprot_t prot;

/*
* I/O space cannot be accessed via normal processor loads and
* stores on this platform.
Expand All @@ -604,15 +607,24 @@ pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma,
*/
return -EINVAL;

if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size))
return -EINVAL;

prot = phys_mem_access_prot(NULL, vma->vm_pgoff, size,
vma->vm_page_prot);

/*
* Leave vm_pgoff as-is, the PCI space address is the physical
* address on this platform.
* If the user requested WC, the kernel uses UC or WC for this region,
* and the chipset supports WC, we can use WC. Otherwise, we have to
* use the same attribute the kernel uses.
*/
if (write_combine && efi_range_is_wc(vma->vm_start,
vma->vm_end - vma->vm_start))
if (write_combine &&
((pgprot_val(prot) & _PAGE_MA_MASK) == _PAGE_MA_UC ||
(pgprot_val(prot) & _PAGE_MA_MASK) == _PAGE_MA_WC) &&
efi_range_is_wc(vma->vm_start, vma->vm_end - vma->vm_start))
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
else
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
vma->vm_page_prot = prot;

if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
vma->vm_end - vma->vm_start, vma->vm_page_prot))
Expand Down

0 comments on commit 87921d5

Please sign in to comment.