# HG changeset patch # User yamahata@xxxxxxxxxxxxx # Date 1164001646 -32400 # Node ID 31dc19673a5b2902c78b77b201b81297dc5a334d # Parent 3597f7a520436519223459230f924c82272daa4b paraviatualize IA64 /dev/mem to use X. PATCHNAME: paravirtualize_dev_mem Signed-off-by: Isaku Yamahata diff -r 3597f7a52043 -r 31dc19673a5b linux-2.6-xen-sparse/arch/ia64/Kconfig --- a/linux-2.6-xen-sparse/arch/ia64/Kconfig Mon Nov 20 12:45:48 2006 +0900 +++ b/linux-2.6-xen-sparse/arch/ia64/Kconfig Mon Nov 20 14:47:26 2006 +0900 @@ -533,9 +533,6 @@ config XEN_SKBUFF config XEN_SKBUFF default y -config XEN_DEVMEM - default n - config XEN_REBOOT default y diff -r 3597f7a52043 -r 31dc19673a5b linux-2.6-xen-sparse/arch/ia64/xen/Makefile --- a/linux-2.6-xen-sparse/arch/ia64/xen/Makefile Mon Nov 20 12:45:48 2006 +0900 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/Makefile Mon Nov 20 14:47:26 2006 +0900 @@ -4,6 +4,6 @@ obj-y := hypercall.o xenivt.o xenentry.o xensetup.o xenpal.o xenhpski.o \ hypervisor.o pci-dma-xen.o util.o xencomm.o xcom_hcall.o \ - xcom_mini.o xcom_privcmd.o + xcom_mini.o xcom_privcmd.o mem.o pci-dma-xen-y := ../../i386/kernel/pci-dma-xen.o diff -r 3597f7a52043 -r 31dc19673a5b linux-2.6-xen-sparse/arch/ia64/xen/mem.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/mem.c Mon Nov 20 14:47:26 2006 +0900 @@ -0,0 +1,76 @@ +/* + * Originally from linux/drivers/char/mem.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + * + * Added devfs support. + * Jan-11-1998, C. Scott Ananian + * Shared /dev/zero mmaping support, Feb 2000, Kanoj Sarcar + */ +/* + * taken from + * linux/drivers/char/mem.c and linux-2.6-xen-sparse/drivers/xen/char/mem.c. + * adjusted for IA64 and made transparent. + * Copyright (c) 2006 Isaku Yamahata + * VA Linux Systems Japan K.K. + */ + +#include +#include +#include + +/* + * Architectures vary in how they handle caching for addresses + * outside of main memory. + * + */ +static inline int uncached_access(struct file *file, unsigned long addr) +{ + /* + * On ia64, we ignore O_SYNC because we cannot tolerate memory attribute aliases. + */ + return !(efi_mem_attributes(addr) & EFI_MEMORY_WB); +} + +int mmap_mem(struct file * file, struct vm_area_struct * vma) +{ + unsigned long addr = vma->vm_pgoff << PAGE_SHIFT; + size_t size = vma->vm_end - vma->vm_start; + + +#if 0 + /* + *XXX FIXME: linux-2.6.16.29, linux-2.6.17 + * valid_mmap_phys_addr_range() in linux/arch/ia64/kernel/efi.c + * fails checks. + * linux-2.6.18.1's returns always 1. + * Its comments says + * + * MMIO regions are often missing from the EFI memory map. + * We must allow mmap of them for programs like X, so we + * currently can't do any useful validation. + */ + if (!valid_mmap_phys_addr_range(addr, &size)) + return -EINVAL; + if (size < vma->vm_end - vma->vm_start) + return -EINVAL; +#endif + + if (is_running_on_xen()) { + unsigned long offset = HYPERVISOR_ioremap(addr, size); + if (IS_ERR_VALUE(offset)) + return offset; + } + + if (uncached_access(file, vma->vm_pgoff << PAGE_SHIFT)) + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */ + if (remap_pfn_range(vma, + vma->vm_start, + vma->vm_pgoff, + size, + vma->vm_page_prot)) + return -EAGAIN; + return 0; +} diff -r 3597f7a52043 -r 31dc19673a5b linux-2.6-xen-sparse/include/asm-ia64/io.h --- a/linux-2.6-xen-sparse/include/asm-ia64/io.h Mon Nov 20 12:45:48 2006 +0900 +++ b/linux-2.6-xen-sparse/include/asm-ia64/io.h Mon Nov 20 14:47:26 2006 +0900 @@ -129,6 +129,11 @@ extern int valid_mmap_phys_addr_range (u (((bvec_to_bus((vec1)) + (vec1)->bv_len) == bvec_to_bus((vec2))) && \ ((bvec_to_pseudophys((vec1)) + (vec1)->bv_len) == \ bvec_to_pseudophys((vec2)))) + +/* We will be supplying our own /dev/mem implementation */ +#define ARCH_HAS_DEV_MEM +#define ARCH_HAS_DEV_MEM_MMAP_MEM +int mmap_mem(struct file * file, struct vm_area_struct * vma); #endif /* CONFIG_XEN */ # endif /* KERNEL */ @@ -458,6 +463,8 @@ ioremap (unsigned long offset, unsigned ioremap (unsigned long offset, unsigned long size) { offset = HYPERVISOR_ioremap(offset, size); + if (IS_ERR_VALUE(offset)) + return (void __iomem*)offset; return (void __iomem *) (__IA64_UNCACHED_OFFSET | (offset)); } diff -r 3597f7a52043 -r 31dc19673a5b linux-2.6-xen-sparse/include/asm-ia64/uaccess.h --- a/linux-2.6-xen-sparse/include/asm-ia64/uaccess.h Mon Nov 20 12:45:48 2006 +0900 +++ b/linux-2.6-xen-sparse/include/asm-ia64/uaccess.h Mon Nov 20 14:47:26 2006 +0900 @@ -365,6 +365,7 @@ ia64_done_with_exception (struct pt_regs } #define ARCH_HAS_TRANSLATE_MEM_PTR 1 +#ifndef CONFIG_XEN static __inline__ char * xlate_dev_mem_ptr (unsigned long p) { @@ -379,6 +380,25 @@ xlate_dev_mem_ptr (unsigned long p) return ptr; } +#else +static __inline__ char * +xlate_dev_mem_ptr (unsigned long p, ssize_t sz) +{ + unsigned long pfn = p >> PAGE_SHIFT; + + if (pfn_valid(pfn) && !PageUncached(pfn_to_page(pfn))) + return __va(p); + + return ioremap(p, sz); +} + +static __inline__ void +xlate_dev_mem_ptr_unmap (char* v) +{ + if (REGION_NUMBER(v) == RGN_UNCACHED) + iounmap(v); +} +#endif /* * Convert a virtual cached kernel memory pointer to an uncached pointer