x86/mm, asm-generic: Add ioremap_wt() for creating Write-Through mappings

Add ioremap_wt() for creating Write-Through mappings on x86. It
follows the same model as ioremap_wc() for multi-arch support.
Define ARCH_HAS_IOREMAP_WT in the x86 version of io.h to
indicate that ioremap_wt() is implemented on x86.

Also update the PAT documentation file to cover ioremap_wt().

Signed-off-by: Toshi Kani <toshi.kani@hp.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Elliott@hp.com
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Luis R. Rodriguez <mcgrof@suse.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: arnd@arndb.de
Cc: hch@lst.de
Cc: hmh@hmh.eng.br
Cc: jgross@suse.com
Cc: konrad.wilk@oracle.com
Cc: linux-mm <linux-mm@kvack.org>
Cc: linux-nvdimm@lists.01.org
Cc: stefan.bader@canonical.com
Cc: yigal@plexistor.com
Link: http://lkml.kernel.org/r/1433436928-31903-8-git-send-email-bp@alien8.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
Toshi Kani 2015-06-04 18:55:15 +02:00 committed by Ingo Molnar
parent ecb2febaaa
commit d838270e25
5 changed files with 39 additions and 1 deletions

View File

@ -12,7 +12,7 @@ virtual addresses.
PAT allows for different types of memory attributes. The most commonly used PAT allows for different types of memory attributes. The most commonly used
ones that will be supported at this time are Write-back, Uncached, ones that will be supported at this time are Write-back, Uncached,
Write-combined and Uncached Minus. Write-combined, Write-through and Uncached Minus.
PAT APIs PAT APIs
@ -40,6 +40,8 @@ ioremap_nocache | -- | UC- | UC- |
| | | | | | | |
ioremap_wc | -- | -- | WC | ioremap_wc | -- | -- | WC |
| | | | | | | |
ioremap_wt | -- | -- | WT |
| | | |
set_memory_uc | UC- | -- | -- | set_memory_uc | UC- | -- | -- |
set_memory_wb | | | | set_memory_wb | | | |
| | | | | | | |

View File

@ -35,6 +35,7 @@
*/ */
#define ARCH_HAS_IOREMAP_WC #define ARCH_HAS_IOREMAP_WC
#define ARCH_HAS_IOREMAP_WT
#include <linux/string.h> #include <linux/string.h>
#include <linux/compiler.h> #include <linux/compiler.h>
@ -320,6 +321,7 @@ extern void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr);
extern int ioremap_change_attr(unsigned long vaddr, unsigned long size, extern int ioremap_change_attr(unsigned long vaddr, unsigned long size,
enum page_cache_mode pcm); enum page_cache_mode pcm);
extern void __iomem *ioremap_wc(resource_size_t offset, unsigned long size); extern void __iomem *ioremap_wc(resource_size_t offset, unsigned long size);
extern void __iomem *ioremap_wt(resource_size_t offset, unsigned long size);
extern bool is_early_ioremap_ptep(pte_t *ptep); extern bool is_early_ioremap_ptep(pte_t *ptep);

View File

@ -172,6 +172,10 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
prot = __pgprot(pgprot_val(prot) | prot = __pgprot(pgprot_val(prot) |
cachemode2protval(_PAGE_CACHE_MODE_WC)); cachemode2protval(_PAGE_CACHE_MODE_WC));
break; break;
case _PAGE_CACHE_MODE_WT:
prot = __pgprot(pgprot_val(prot) |
cachemode2protval(_PAGE_CACHE_MODE_WT));
break;
case _PAGE_CACHE_MODE_WB: case _PAGE_CACHE_MODE_WB:
break; break;
} }
@ -297,6 +301,23 @@ void __iomem *ioremap_wc(resource_size_t phys_addr, unsigned long size)
} }
EXPORT_SYMBOL(ioremap_wc); EXPORT_SYMBOL(ioremap_wc);
/**
* ioremap_wt - map memory into CPU space write through
* @phys_addr: bus address of the memory
* @size: size of the resource to map
*
* This version of ioremap ensures that the memory is marked write through.
* Write through stores data into memory while keeping the cache up-to-date.
*
* Must be freed with iounmap.
*/
void __iomem *ioremap_wt(resource_size_t phys_addr, unsigned long size)
{
return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WT,
__builtin_return_address(0));
}
EXPORT_SYMBOL(ioremap_wt);
void __iomem *ioremap_cache(resource_size_t phys_addr, unsigned long size) void __iomem *ioremap_cache(resource_size_t phys_addr, unsigned long size)
{ {
return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WB, return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WB,

View File

@ -785,8 +785,17 @@ static inline void __iomem *ioremap_wc(phys_addr_t offset, size_t size)
} }
#endif #endif
#ifndef ioremap_wt
#define ioremap_wt ioremap_wt
static inline void __iomem *ioremap_wt(phys_addr_t offset, size_t size)
{
return ioremap_nocache(offset, size);
}
#endif
#ifndef iounmap #ifndef iounmap
#define iounmap iounmap #define iounmap iounmap
static inline void iounmap(void __iomem *addr) static inline void iounmap(void __iomem *addr)
{ {
} }

View File

@ -66,6 +66,10 @@ extern void ioport_unmap(void __iomem *);
#define ioremap_wc ioremap_nocache #define ioremap_wc ioremap_nocache
#endif #endif
#ifndef ARCH_HAS_IOREMAP_WT
#define ioremap_wt ioremap_nocache
#endif
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
/* Destroy a virtual mapping cookie for a PCI BAR (memory or IO) */ /* Destroy a virtual mapping cookie for a PCI BAR (memory or IO) */
struct pci_dev; struct pci_dev;