lkml.org 
[lkml]   [2008]   [Jan]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 4/4] x86: PAT followup - use ioremap for devmem read of reserved regions
    map and unmap reserved regions, before accessing through /dev/mem read
    interface. This is for full compatibility with existing /dev/mem
    usages.
    For regions that are mapped in identity map, we use __va().

    Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
    Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>

    Index: linux-2.6.git/arch/x86/mm/ioremap.c
    ===================================================================
    --- linux-2.6.git.orig/arch/x86/mm/ioremap.c 2008-01-15 10:05:13.000000000 -0800
    +++ linux-2.6.git/arch/x86/mm/ioremap.c 2008-01-15 10:39:18.000000000 -0800
    @@ -32,6 +32,39 @@
    }
    EXPORT_SYMBOL(ioremap_wc);

    +/*
    + * Convert a physical pointer to a virtual kernel pointer for /dev/mem
    + * access
    + */
    +void *xlate_dev_mem_ptr(unsigned long phys)
    +{
    + void *addr;
    + unsigned long start = phys & PAGE_MASK;
    +
    + /*
    + * If any memory in PAGE_SIZE is valid, then we can use __va. Otherwise
    + * ioremap and unmap the memory.
    + */
    + if (is_memory_any_valid(start, start + PAGE_SIZE))
    + return __va(phys);
    +
    + addr = (void *)ioremap(start, PAGE_SIZE);
    + if (addr)
    + addr = (void *)((unsigned long)addr | (phys & ~PAGE_MASK));
    +
    + return addr;
    +}
    +
    +void unxlate_dev_mem_ptr(unsigned long phys, void *addr)
    +{
    + unsigned long start = phys & PAGE_MASK;
    + if (is_memory_any_valid(start, start + PAGE_SIZE))
    + return;
    +
    + iounmap((void __iomem *)((unsigned long)addr & PAGE_MASK));
    + return;
    +}
    +
    int valid_phys_addr_range(unsigned long addr, size_t count)
    {
    if (addr + count > __pa(high_memory))
    Index: linux-2.6.git/drivers/char/mem.c
    ===================================================================
    --- linux-2.6.git.orig/drivers/char/mem.c 2008-01-15 10:05:13.000000000 -0800
    +++ linux-2.6.git/drivers/char/mem.c 2008-01-15 10:05:51.000000000 -0800
    @@ -127,9 +127,14 @@
    * by the kernel or data corruption may occur
    */
    ptr = xlate_dev_mem_ptr(p);
    + if (!ptr)
    + return -EFAULT;

    if (copy_to_user(buf, ptr, sz))
    return -EFAULT;
    +
    + unxlate_dev_mem_ptr(p, ptr);
    +
    buf += sz;
    p += sz;
    count -= sz;
    @@ -184,6 +189,11 @@
    * by the kernel or data corruption may occur
    */
    ptr = xlate_dev_mem_ptr(p);
    + if (!ptr) {
    + if (written)
    + break;
    + return -EFAULT;
    + }

    copied = copy_from_user(ptr, buf, sz);
    if (copied) {
    @@ -192,6 +202,9 @@
    break;
    return -EFAULT;
    }
    +
    + unxlate_dev_mem_ptr(p, ptr);
    +
    buf += sz;
    p += sz;
    count -= sz;
    Index: linux-2.6.git/include/asm-generic/iomap.h
    ===================================================================
    --- linux-2.6.git.orig/include/asm-generic/iomap.h 2008-01-15 10:05:13.000000000 -0800
    +++ linux-2.6.git/include/asm-generic/iomap.h 2008-01-15 10:23:24.000000000 -0800
    @@ -69,4 +69,8 @@
    #define ioremap_wc ioremap_nocache
    #endif

    +#ifndef unxlate_dev_mem_ptr
    +static inline void unxlate_dev_mem_ptr(unsigned long phys, void *addr) {}
    +#endif
    +
    #endif
    Index: linux-2.6.git/include/asm-x86/io.h
    ===================================================================
    --- linux-2.6.git.orig/include/asm-x86/io.h 2008-01-15 10:05:13.000000000 -0800
    +++ linux-2.6.git/include/asm-x86/io.h 2008-01-15 10:21:42.000000000 -0800
    @@ -2,6 +2,7 @@
    #define _ASM_X86_IO_H

    #define ioremap_wc ioremap_wc
    +#define unxlate_dev_mem_ptr unxlate_dev_mem_ptr

    #ifdef CONFIG_X86_32
    # include "io_32.h"
    @@ -10,6 +11,8 @@
    #endif

    extern void __iomem * ioremap_wc(unsigned long offset, unsigned long size);
    +extern void *xlate_dev_mem_ptr(unsigned long phys);
    +extern void unxlate_dev_mem_ptr(unsigned long phys, void *addr);

    #define ARCH_HAS_VALID_PHYS_ADDR_RANGE

    Index: linux-2.6.git/include/asm-x86/io_32.h
    ===================================================================
    --- linux-2.6.git.orig/include/asm-x86/io_32.h 2008-01-15 10:05:13.000000000 -0800
    +++ linux-2.6.git/include/asm-x86/io_32.h 2008-01-15 10:05:51.000000000 -0800
    @@ -49,12 +49,6 @@
    #include <linux/vmalloc.h>

    /*
    - * Convert a physical pointer to a virtual kernel pointer for /dev/mem
    - * access
    - */
    -#define xlate_dev_mem_ptr(p) __va(p)
    -
    -/*
    * Convert a virtual cached pointer to an uncached pointer
    */
    #define xlate_dev_kmem_ptr(p) p
    Index: linux-2.6.git/include/asm-x86/io_64.h
    ===================================================================
    --- linux-2.6.git.orig/include/asm-x86/io_64.h 2008-01-15 10:05:13.000000000 -0800
    +++ linux-2.6.git/include/asm-x86/io_64.h 2008-01-15 10:05:51.000000000 -0800
    @@ -278,12 +278,6 @@
    #define BIO_VMERGE_BOUNDARY iommu_bio_merge

    /*
    - * Convert a physical pointer to a virtual kernel pointer for /dev/mem
    - * access
    - */
    -#define xlate_dev_mem_ptr(p) __va(p)
    -
    -/*
    * Convert a virtual cached pointer to an uncached pointer
    */
    #define xlate_dev_kmem_ptr(p) p
    --


    \
     
     \ /
      Last update: 2008-01-16 03:45    [W:3.921 / U:0.364 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site