Support Write-Through mapping on x86
Subsystems (19)
v11 cover Support Write-Through mapping on x86
This patchset adds support of Write-Through (WT) mapping on x86. The study below shows that using WT mapping may be useful for non-volatile memory.
http://www.hpl.hp.com/techreports/2012/HPL-2012-236.pdf
The patchset consists of the following changes.
- Patch 1/12 to 2/12 refactor !pat_enable paths
- Patch 3/12 to 8/12 add ioremap_wt()
- Patch 9/12 adds pgprot_writethrough()
- Patch 10/12 to 11/12 add set_memory_wt()
- Patch 12/12 changes the pmem driver to call ioremap_wt()
All new/modified interfaces have been tested.
---
v11:
- Reordered the refactor changes from patch 10-11 to 1-2. (Borislav Petkov)
- Changed BUG() to panic(). (Borislav Petkov)
- Rebased to tip/master and resolved conflicts.
v10:
- Removed ioremap_writethrough(). (Thomas Gleixner)
- Clarified and cleaned up multiple comments and functions. (Thomas Gleixner)
- Changed ioremap_change_attr() to accept the WT type.
v9:
- Changed to export the set_xxx_wt() interfaces with GPL. (Ingo Molnar)
- Changed is_new_memtype_allowed() to handle WT cases.
- Changed arch-specific io.h to define ioremap_wt().
- Changed the pmem driver to use ioremap_wt().
- Rebased to 4.1-rc3 and resolved minor conflicts.
v8:
- Rebased to 4.0-rc1 and resolved conflicts with 9d34cfdf4 in patch 5/7.
v7:
- Rebased to 3.19-rc3 as Juergen's patchset for the PAT management has been accepted.
v6:
- Dropped the patch moving [set|get]_page_memtype() to pat.c since the tip branch already has this change.
- Fixed an issue when CONFIG_X86_PAT is not defined.
v5:
- Clarified comment of why using slot 7. (Andy Lutomirski, Thomas Gleixner)
- Moved [set|get]_page_memtype() to pat.c. (Thomas Gleixner)
- Removed BUG() from set_page_memtype(). (Thomas Gleixner)
v4:
- Added set_memory_wt() by adding WT support of regular memory.
v3:
- Dropped the set_memory_wt() patch. (Andy Lutomirski)
- Refactored the !pat_enabled handling. (H. Peter Anvin, Andy Lutomirski)
- Added the picture of PTE encoding. (Konrad Rzeszutek Wilk)
v2:
- Changed WT to use slot 7 of the PAT MSR. (H. Peter Anvin, Andy Lutomirski)
- Changed to have conservative checks to exclude all Pentium 2, 3, M, and 4 families. (Ingo Molnar, Henrique de Moraes Holschuh, Andy Lutomirski)
- Updated documentation to cover WT interfaces and usages. (Andy Lutomirski, Yigal Korman)
---
Toshi Kani (12):
1/12 x86, mm, pat: Cleanup init flags in pat_init() 2/12 x86, mm, pat: Refactor !pat_enable handling 3/12 x86, mm, pat: Set WT to PA7 slot of PAT MSR 4/12 x86, mm, pat: Change reserve_memtype() for WT 5/12 x86, asm: Change is_new_memtype_allowed() for WT 6/12 x86, mm, asm-gen: Add ioremap_wt() for WT 7/12 arch/*/asm/io.h: Add ioremap_wt() to all architectures 8/12 video/fbdev, asm/io.h: Remove ioremap_writethrough() 9/12 x86, mm, pat: Add pgprot_writethrough() for WT
10/12 x86, mm, asm: Add WT support to set_page_memtype() 11/12 x86, mm: Add set_memory_wt() for WT
12/12 drivers/block/pmem: Map NVDIMM with ioremap_wt()
--- Documentation/x86/pat.txt | 13 +- arch/arc/include/asm/io.h | 1 + arch/arm/include/asm/io.h | 1 + arch/arm64/include/asm/io.h | 1 + arch/avr32/include/asm/io.h | 1 + arch/frv/include/asm/io.h | 4 +- arch/m32r/include/asm/io.h | 1 + arch/m68k/include/asm/io_mm.h | 4 +- arch/m68k/include/asm/io_no.h | 4 +- arch/metag/include/asm/io.h | 3 + arch/microblaze/include/asm/io.h | 2 +- arch/mn10300/include/asm/io.h | 1 + arch/nios2/include/asm/io.h | 1 + arch/s390/include/asm/io.h | 1 + arch/sparc/include/asm/io_32.h | 1 + arch/sparc/include/asm/io_64.h | 1 + arch/tile/include/asm/io.h | 2 +- arch/x86/include/asm/cacheflush.h | 6 +- arch/x86/include/asm/io.h | 2 + arch/x86/include/asm/pgtable.h | 8 +- arch/x86/include/asm/pgtable_types.h | 3 + arch/x86/mm/init.c | 6 +- arch/x86/mm/iomap_32.c | 12 +- arch/x86/mm/ioremap.c | 29 ++++- arch/x86/mm/pageattr.c | 65 +++++++--- arch/x86/mm/pat.c | 229 +++++++++++++++++++++++------------ arch/xtensa/include/asm/io.h | 1 + drivers/block/pmem.c | 4 +- drivers/video/fbdev/amifb.c | 4 +- drivers/video/fbdev/atafb.c | 3 +- drivers/video/fbdev/hpfb.c | 4 +- include/asm-generic/io.h | 9 ++ include/asm-generic/iomap.h | 4 + include/asm-generic/pgtable.h | 4 + 34 files changed, 310 insertions(+), 125 deletions(-)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH v11 1/12 x86, mm, pat: Cleanup init flags in pat_init()
From: Toshi Kani <[email protected]>
pat_init() uses two flags, 'boot_cpu' and 'boot_pat_state', for tracking the boot CPU's initialization status. 'boot_pat_state' is also overloaded to carry the boot PAT value.
This patch cleans this up by replacing them with a new single flag, 'boot_cpu_done', to track the boot CPU's initialization status. 'boot_pat_state' is only used to carry the boot PAT value as a result.
--- arch/x86/mm/pat.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-)
arch/x86/mm/pat.c +19 -21
@@ -197,24 +197,29 @@ void pat_init_cache_modes(void)void pat_init (void ) {u64 pat; -bool boot_cpu = !boot_pat_state; +static bool boot_cpu_done;if (!pat_enabled ())return ; -if (!cpu_has_pat) { -if (!boot_pat_state) { +if (!boot_cpu_done) { +if (!cpu_has_pat) {pat_disable ("PAT not supported by CPU." );return ; - }else { -/* -* If this happens we are on a secondary CPU, but -* switched to PAT on the boot CPU. We have no way to -* undo PAT. -*/ -pr_err ("x86/PAT: PAT enabled, but not supported by secondary CPU\n" ); -BUG (); } + +rdmsrl (MSR_IA32_CR_PAT , boot_pat_state); +if (!boot_pat_state) { +pat_disable ("PAT read returns always zero, disabled." ); +return ; + } + }else if (!cpu_has_pat) { +/* +* If this happens we are on a secondary CPU, but +* switched to PAT on the boot CPU. We have no way to +* undo PAT. +*/ +panic ("PAT enabled, but not supported by secondary CPU\n" ); }/* Set PWT to Write-Combining. All other bits stay the same */
@@ -233,19 +238,12 @@ void pat_init(void) pat =PAT (0 ,WB ) |PAT (1 ,WC ) |PAT (2 ,UC_MINUS ) |PAT (3 ,UC ) |PAT (4 ,WB ) |PAT (5 ,WC ) |PAT (6 ,UC_MINUS ) |PAT (7 ,UC ); -/* Boot CPU check */ -if (!boot_pat_state) { -rdmsrl (MSR_IA32_CR_PAT , boot_pat_state); -if (!boot_pat_state) { -pat_disable ("PAT read returns always zero, disabled." ); -return ; - } - } -wrmsrl (MSR_IA32_CR_PAT , pat); -if (boot_cpu) +if (!boot_cpu_done) {pat_init_cache_modes (); + boot_cpu_done = true; + } }#undef PAT
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH v11 2/12 x86, mm, pat: Refactor !pat_enabled handling
In reply to Toshi KaniFrom: Toshi Kani <[email protected]>
This patch refactors the !pat_enabled code paths and integrates them into the PAT abstraction code. The PAT table is emulated by corresponding to the two cache attribute bits, PWT (Write Through) and PCD (Cache Disable). The emulated PAT table is the same as the BIOS default setup when the system has PAT but the "nopat" boot option is specified. The emulated PAT table is also used when MSR_IA32_CR_PAT returns 0 -- 9d34cfdf4796 ("x86: Don't rely on VMWare emulating PAT MSR correctly").
--- arch/x86/mm/init.c | 6 ++- arch/x86/mm/iomap_32.c | 12 +++--- arch/x86/mm/ioremap.c | 5 +-- arch/x86/mm/pageattr.c | 3 -- arch/x86/mm/pat.c | 95 +++++++++++++++++++++++++++++------------------- 5 files changed, 67 insertions(+), 54 deletions(-)
arch/x86/mm/init.c +3 -3
@@ -40,7 +40,7 @@*/ uint16_t __cachemode2pte_tbl[_PAGE_CACHE_MODE_NUM] = { [_PAGE_CACHE_MODE_WB ] =0 |0 , - [_PAGE_CACHE_MODE_WC ] = _PAGE_PWT |0 , + [_PAGE_CACHE_MODE_WC ] =0 | _PAGE_PCD, [_PAGE_CACHE_MODE_UC_MINUS] =0 | _PAGE_PCD, [_PAGE_CACHE_MODE_UC ] = _PAGE_PWT | _PAGE_PCD, [_PAGE_CACHE_MODE_WT ] =0 | _PAGE_PCD,
@@ -50,11 +50,11 @@ EXPORT_SYMBOL(__cachemode2pte_tbl);uint8_t __pte2cachemode_tbl[8 ] = { [__pte2cm_idx (0 |0 |0 )] = _PAGE_CACHE_MODE_WB, - [__pte2cm_idx (_PAGE_PWT |0 |0 )] = _PAGE_CACHE_MODE_WC, + [__pte2cm_idx (_PAGE_PWT |0 |0 )] = _PAGE_CACHE_MODE_UC_MINUS, [__pte2cm_idx (0 | _PAGE_PCD |0 )] = _PAGE_CACHE_MODE_UC_MINUS, [__pte2cm_idx (_PAGE_PWT | _PAGE_PCD |0 )] = _PAGE_CACHE_MODE_UC, [__pte2cm_idx (0 |0 | _PAGE_PAT)] = _PAGE_CACHE_MODE_WB, - [__pte2cm_idx (_PAGE_PWT |0 | _PAGE_PAT)] = _PAGE_CACHE_MODE_WC, + [__pte2cm_idx (_PAGE_PWT |0 | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC_MINUS, [__pte2cm_idx (0 | _PAGE_PCD | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC_MINUS, [__pte2cm_idx (_PAGE_PWT | _PAGE_PCD | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC, };
arch/x86/mm/iomap_32.c +6 -6
@@ -78,13 +78,13 @@ void __iomem * iomap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot) {/* -* For non-PAT systems, promote PAGE_KERNEL_WC to PAGE_KERNEL_UC_MINUS. -* PAGE_KERNEL_WC maps to PWT, which translates to uncached if the -* MTRR is UC or WC. UC_MINUS gets the real intention, of the -* user, which is "WC if the MTRR is WC, UC if you can't do that." +* For non-PAT systems, translate non-WB request to UC- just in +* case the caller set the PWT bit to prot directly without using +* pgprot_writecombine(). UC- translates to uncached if the MTRR +* is UC or WC. UC- gets the real intention, of the user, which is +* "WC if the MTRR is WC, UC if you can't do that." */ -if (!pat_enabled () &&pgprot_val (prot) == - (__PAGE_KERNEL |cachemode2protval (_PAGE_CACHE_MODE_WC))) +if (!pat_enabled () &&pgprot2cachemode (prot) != _PAGE_CACHE_MODE_WB) prot =__pgprot (__PAGE_KERNEL |cachemode2protval (_PAGE_CACHE_MODE_UC_MINUS));
arch/x86/mm/ioremap.c +1 -4
@@ -292,11 +292,8 @@ EXPORT_SYMBOL_GPL(ioremap_uc);*/ void __iomem *ioremap_wc (resource_size_t phys_addr,unsigned long size) { -if (pat_enabled ()) -return __ioremap_caller (phys_addr, size, _PAGE_CACHE_MODE_WC, +return __ioremap_caller (phys_addr, size, _PAGE_CACHE_MODE_WC,__builtin_return_address (0 )); -else -return ioremap_nocache (phys_addr, size); }EXPORT_SYMBOL (ioremap_wc);
arch/x86/mm/pageattr.c +0 -3
@@ -1571,9 +1571,6 @@ int set_memory_wc(unsigned long addr, int numpages) {int ret; -if (!pat_enabled ()) -return set_memory_uc (addr, numpages); - ret =reserve_memtype (__pa (addr),__pa (addr) + numpages *PAGE_SIZE , _PAGE_CACHE_MODE_WC,NULL );if (ret)
arch/x86/mm/pat.c +57 -38
131 lines not on this page · raw message
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Borislav Petkov
maintainerRe: [PATCH v11 2/12] x86, mm, pat: Refactor !pat_enabled handling
Quoted 10 lines · Toshi Kani
From: Toshi Kani <[email protected]>
This patch refactors the !pat_enabled code paths and integrates them into the PAT abstraction code. The PAT table is emulated by corresponding to the two cache attribute bits, PWT (Write Through) and PCD (Cache Disable). The emulated PAT table is the same as the BIOS default setup when the system has PAT but the "nopat" boot option is specified. The emulated PAT table is also used when
MSR_IA32_CR_PATreturns 0 --9d34cfdf4796("x86: Don't rely on VMWare emulating PAT MSR correctly").
To be honest, I wasn't surprised when you sent me the same patch and ignored most of my comments. For the future, please let me know if I'm wasting my time with commenting on your stuff so that I can plan my work and not waste time and energy reviewing, ok?
Unfortunately, if you want something done right, you have to do it yourself.
So I did that, I split that ugly cleanup into something much more readable, patches as a reply to this message.
Feel free to base your work ontop of
git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git#tip-mm-2
Signature · 5 lines
Regards/Gruss,
Boris.
ECO tip #101: Trim your mails when you reply.
--Borislav Petkov
maintainerPATCH 1/4 x86/pat: Untangle pat_init()
From: Borislav Petkov <[email protected]>
Split it into a BSP and AP version which makes the PAT initialization path actually readable again.
--- arch/x86/mm/pat.c | 69 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 29 deletions(-)
arch/x86/mm/pat.c +40 -29
@@ -36,6 +36,8 @@#undef pr_fmt#define pr_fmt (fmt) "" fmt +static bool boot_cpu_done; +static int __read_mostly __pat_enabled =IS_ENABLED (CONFIG_X86_PAT );static inline void pat_disable (const char *reason)
@@ -194,31 +196,47 @@ void pat_init_cache_modes(void)#define PAT (x, y) ((u64)PAT_ ## y << ((x)*8)) -void pat_init (void ) +static void pat_bsp_init (u64 pat) { -u64 pat; -bool boot_cpu = !boot_pat_state; +if (!cpu_has_pat) { +pat_disable ("PAT not supported by CPU." ); +return ; + } -if (!pat_enabled ()) +rdmsrl (MSR_IA32_CR_PAT , boot_pat_state); +if (!boot_pat_state) { +pat_disable ("PAT MSR is 0, disabled." );return ; + } +wrmsrl (MSR_IA32_CR_PAT , pat); + +pat_init_cache_modes (); +} + +static void pat_ap_init (u64 pat) +{if (!cpu_has_pat) { -if (!boot_pat_state) { -pat_disable ("PAT not supported by CPU." ); -return ; - }else { -/* -* If this happens we are on a secondary CPU, but -* switched to PAT on the boot CPU. We have no way to -* undo PAT. -*/ -pr_err ("x86/PAT: PAT enabled, but not supported by secondary CPU\n" ); -BUG (); - } +/* +* If this happens we are on a secondary CPU, but switched to +* PAT on the boot CPU. We have no way to undo PAT. +*/ +panic ("x86/PAT: PAT enabled, but not supported by secondary CPU\n" ); } -/* Set PWT to Write-Combining. All other bits stay the same */ +wrmsrl (MSR_IA32_CR_PAT , pat); +} + +void pat_init (void ) +{ +u64 pat; + +if (!pat_enabled ()) +return ; +/* +* Set PWT to Write-Combining. All other bits stay the same: +* * PTE encoding used in Linux: * PAT * |PCD
@@ -233,19 +251,12 @@ void pat_init(void) pat =PAT (0 ,WB ) |PAT (1 ,WC ) |PAT (2 ,UC_MINUS ) |PAT (3 ,UC ) |PAT (4 ,WB ) |PAT (5 ,WC ) |PAT (6 ,UC_MINUS ) |PAT (7 ,UC ); -/* Boot CPU check */ -if (!boot_pat_state) { -rdmsrl (MSR_IA32_CR_PAT , boot_pat_state); -if (!boot_pat_state) { -pat_disable ("PAT read returns always zero, disabled." ); -return ; - } +if (!boot_cpu_done) { +pat_bsp_init (pat); + boot_cpu_done = true; + }else { +pat_ap_init (pat); } - -wrmsrl (MSR_IA32_CR_PAT , pat); - -if (boot_cpu) -pat_init_cache_modes (); }#undef PAT
Signature · 1 line
2.3.5
Borislav Petkov
maintainerPATCH 2/4 x86/pat: Merge pat_init_cache_modes() into its caller
From: Borislav Petkov <[email protected]>
This way we can pass pat MSR value directly.
No functionality change.
--- arch/x86/mm/pat.c | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-)
arch/x86/mm/pat.c +16 -23
@@ -172,32 +172,14 @@ static enum page_cache_mode pat_get_cache_mode(unsigned pat_val, char *msg)#undef CM -/* -* Update the cache mode to pgprot translation tables according to PAT -* configuration. -* Using lower indices is preferred, so we start with highest index. -*/ -void pat_init_cache_modes (void ) -{ -int i; -enum page_cache_mode cache; -char pat_msg[33 ]; -u64 pat; - -rdmsrl (MSR_IA32_CR_PAT , pat); - pat_msg[32 ] =0 ; -for (i =7 ; i >=0 ; i--) { - cache =pat_get_cache_mode ((pat >> (i *8 )) &7 , - pat_msg +4 * i); -update_cache_mode_entry (i, cache); - } -pr_info ("x86/PAT: Configuration [0-7]: %s\n" , pat_msg); -} -#define PAT (x, y) ((u64)PAT_ ## y << ((x)*8))static void pat_bsp_init (u64 pat) { +enum page_cache_mode cache; +char pat_msg[33 ]; +int i; +if (!cpu_has_pat) {pat_disable ("PAT not supported by CPU." );return ;
@@ -211,7 +193,18 @@ static void pat_bsp_init(u64 pat)wrmsrl (MSR_IA32_CR_PAT , pat); -pat_init_cache_modes (); + pat_msg[32 ] =0 ; + +/* +* Update the cache mode to pgprot translation tables according to PAT +* configuration. Using lower indices is preferred, so we start with +* highest index. +*/ +for (i =7 ; i >=0 ; i--) { + cache =pat_get_cache_mode ((pat >> (i *8 )) &7 , pat_msg +4 * i); +update_cache_mode_entry (i, cache); + } +pr_info ("x86/PAT: Configuration [0-7]: %s\n" , pat_msg); }static void pat_ap_init (u64 pat)
Signature · 1 line
2.3.5
Juergen Gross
maintainerRe: [PATCH 2/4] x86/pat: Merge pat_init_cache_modes() into its caller
Quoted 5 lines · Borislav Petkov
From: Borislav Petkov <[email protected]>
This way we can pass pat MSR value directly.
No functionality change.
You are breaking the Xen build with that change. pat_init_cache_modes() is called from arch/x86/xen/enlighten.c as well.
Juergen
Quoted 76 lines
Signed-off-by Borislav Petkov <[email protected]>Cc Andrew Morton <[email protected]>Cc Andy Lutomirski <[email protected]>Cc H. Peter Anvin <[email protected]>Cc Ingo Molnar <[email protected]>Cc linux-mm <[email protected]>Cc Luis R. Rodriguez <[email protected]>Cc Thomas Gleixner <[email protected]>Cc Toshi Kani <[email protected]>Cc x86-ml <[email protected]>--- arch/x86/mm/pat.c | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-)arch/x86/mm/pat.c +9
-23@@ -172,32 +172,14 @@ static enum page_cache_mode pat_get_cache_mode(unsigned pat_val, char *msg)#undef CM -/* -* Update the cache mode to pgprot translation tables according to PAT -* configuration. -* Using lower indices is preferred, so we start with highest index. -*/ -void pat_init_cache_modes (void ) -{ -int i; -enum page_cache_mode cache; -char pat_msg[33 ]; -u64 pat; - -rdmsrl (MSR_IA32_CR_PAT , pat); - pat_msg[32 ] =0 ; -for (i =7 ; i >=0 ; i--) { - cache =pat_get_cache_mode ((pat >> (i *8 )) &7 , - pat_msg +4 * i); -update_cache_mode_entry (i, cache); - } -pr_info ("x86/PAT: Configuration [0-7]: %s\n" , pat_msg); -} -#define PAT (x, y) ((u64)PAT_ ## y << ((x)*8))static void pat_bsp_init (u64 pat) { +enum page_cache_mode cache; +char pat_msg[33 ]; +int i; +if (!cpu_has_pat) {pat_disable ("PAT not supported by CPU." );return ;@@ -211,7 +193,18 @@ static void pat_bsp_init(u64 pat)wrmsrl (MSR_IA32_CR_PAT , pat); -pat_init_cache_modes (); + pat_msg[32 ] =0 ; + +/* +* Update the cache mode to pgprot translation tables according to PAT +* configuration. Using lower indices is preferred, so we start with
arch/x86/mm/pat.c static void pat_bsp_init(u64 pat) · line 210
Quoted 10 lines
arch/x86/mm/pat.c +7
-0+* highest index. +*/ +for (i =7 ; i >=0 ; i--) { + cache =pat_get_cache_mode ((pat >> (i *8 )) &7 , pat_msg +4 * i); +update_cache_mode_entry (i, cache); + } +pr_info ("x86/PAT: Configuration [0-7]: %s\n" , pat_msg); }static void pat_ap_init (u64 pat)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Borislav Petkov
maintainerRe: [PATCH 2/4] x86/pat: Merge pat_init_cache_modes() into its caller
Quoted 2 lines · Juergen Gross
You are breaking the Xen build with that change.
pat_init_cache_modes()is called fromarch/x86/xen/enlighten.cas well.
Yeah, build-robot just caught that. Can you please check the enlighten.c change in the other mail I just sent?
Thanks.
Signature · 5 lines
Regards/Gruss,
Boris.
ECO tip #101: Trim your mails when you reply.
--Borislav Petkov
maintainerRe: [PATCH 2/4] x86/pat: Merge pat_init_cache_modes() into its caller
In reply to Borislav PetkovQuoted 3 lines · Borislav Petkov
From: Borislav Petkov <[email protected]>
This way we can pass pat MSR value directly.
This breaks xen as that function is used there, doh. :-\
Jürgen,
can you check the enlighten.c changes below please?
I'm reading xen's PAT config from MSR_IA32_CR_PAT and handing it down to pat_init_cache_modes(). That shouldn't change current behavior AFAICT because pat_init_cache_modes() did it itself before.
Right?
Thanks.
---
Author: Borislav Petkov <[email protected]> Date: Sat May 30 13:09:55 2015 +0200
x86/pat: Emulate PAT when it is disabled
In the case when PAT is disabled on the command line with "nopat" or when virtualization doesn't support PAT (correctly) - see
9d34cfdf4796 ("x86: Don't rely on VMWare emulating PAT MSR correctly").
we emulate it using the PWT and PCD cache attribute bits. Get rid of boot_pat_state while at it.
Based on a conglomerate patch from Toshi Kani.
arch/x86/include/asm/pat.h +1 -1
@@ -6,7 +6,7 @@bool pat_enabled (void );extern void pat_init (void ); -void pat_init_cache_modes (void ); +void pat_init_cache_modes (u64 );extern int reserve_memtype (u64 start,u64 end,enum page_cache_mode req_pcm,enum page_cache_mode *ret_pcm);
arch/x86/mm/init.c +3 -3
@@ -40,7 +40,7 @@*/ uint16_t __cachemode2pte_tbl[_PAGE_CACHE_MODE_NUM] = { [_PAGE_CACHE_MODE_WB ] =0 |0 , - [_PAGE_CACHE_MODE_WC ] = _PAGE_PWT |0 , + [_PAGE_CACHE_MODE_WC ] =0 | _PAGE_PCD, [_PAGE_CACHE_MODE_UC_MINUS] =0 | _PAGE_PCD, [_PAGE_CACHE_MODE_UC ] = _PAGE_PWT | _PAGE_PCD, [_PAGE_CACHE_MODE_WT ] =0 | _PAGE_PCD,
@@ -50,11 +50,11 @@ EXPORT_SYMBOL(__cachemode2pte_tbl);uint8_t __pte2cachemode_tbl[8 ] = { [__pte2cm_idx (0 |0 |0 )] = _PAGE_CACHE_MODE_WB, - [__pte2cm_idx (_PAGE_PWT |0 |0 )] = _PAGE_CACHE_MODE_WC, + [__pte2cm_idx (_PAGE_PWT |0 |0 )] = _PAGE_CACHE_MODE_UC_MINUS, [__pte2cm_idx (0 | _PAGE_PCD |0 )] = _PAGE_CACHE_MODE_UC_MINUS, [__pte2cm_idx (_PAGE_PWT | _PAGE_PCD |0 )] = _PAGE_CACHE_MODE_UC, [__pte2cm_idx (0 |0 | _PAGE_PAT)] = _PAGE_CACHE_MODE_WB, - [__pte2cm_idx (_PAGE_PWT |0 | _PAGE_PAT)] = _PAGE_CACHE_MODE_WC, + [__pte2cm_idx (_PAGE_PWT |0 | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC_MINUS, [__pte2cm_idx (0 | _PAGE_PCD | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC_MINUS, [__pte2cm_idx (_PAGE_PWT | _PAGE_PCD | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC, };
arch/x86/mm/pat.c +53 -28
124 lines not on this page · raw message
arch/x86/xen/enlighten.c +3 -2
@@ -1467,6 +1467,7 @@ asmlinkage __visible void __init xen_start_kernel(void) {struct physdev_set_iopl set_iopl;unsigned long initrd_start =0 ; +u64 pat;int rc;if (!xen_start_info)
@@ -1574,8 +1575,8 @@ asmlinkage __visible void __init xen_start_kernel(void)* Modify the cache mode translation tables to match Xen's PAT * configuration. */ - -pat_init_cache_modes (); +rdmsrl (MSR_IA32_CR_PAT , pat); +pat_init_cache_modes (pat);/* keep using Xen gdt for now; no urgent need to change it */
Signature · 5 lines
Regards/Gruss,
Boris.
ECO tip #101: Trim your mails when you reply.
--Re: [PATCH 2/4] x86/pat: Merge pat_init_cache_modes() into its caller
Quoted 10 lines · Borislav Petkov
Quoted 3 lines · Borislav Petkov
From: Borislav Petkov <[email protected]>
This way we can pass pat MSR value directly.
This breaks xen as that function is used there, doh. :-\
Jürgen,
can you check the
enlighten.cchanges below please?
Quoted 232 lines
I'm reading xen's PAT config from
MSR_IA32_CR_PATand handing it down topat_init_cache_modes(). That shouldn't change current behavior AFAICT becausepat_init_cache_modes()did it itself before.Right?
Thanks.
---
Author: Borislav Petkov <[email protected]> Date: Sat May 30 13:09:55 2015 +0200x86/pat: Emulate PAT when it is disabled
In the case when PAT is disabled on the command line with "nopat" or when virtualization doesn't support PAT (correctly) - see
9d34cfdf4796("x86: Don't rely on VMWare emulating PAT MSR correctly").we emulate it using the PWT and PCD cache attribute bits. Get rid of
boot_pat_statewhile at it.Based on a conglomerate patch from Toshi Kani.
Signed-off-by Borislav Petkov <[email protected]>Cc Andrew Morton <[email protected]>Cc Andy Lutomirski <[email protected]>Cc H. Peter Anvin <[email protected]>Cc Ingo Molnar <[email protected]>Cc linux-mm <[email protected]>Cc Luis R. Rodriguez <[email protected]>Cc Thomas Gleixner <[email protected]>Cc Toshi Kani <[email protected]>Cc x86-ml <[email protected]>arch/x86/include/asm/pat.h +1
-1@@ -6,7 +6,7 @@bool pat_enabled (void );extern void pat_init (void ); -void pat_init_cache_modes (void ); +void pat_init_cache_modes (u64 );extern int reserve_memtype (u64 start,u64 end,enum page_cache_mode req_pcm,enum page_cache_mode *ret_pcm);arch/x86/mm/init.c +3
-3@@ -40,7 +40,7 @@*/ uint16_t __cachemode2pte_tbl[_PAGE_CACHE_MODE_NUM] = { [_PAGE_CACHE_MODE_WB ] =0 |0 , - [_PAGE_CACHE_MODE_WC ] = _PAGE_PWT |0 , + [_PAGE_CACHE_MODE_WC ] =0 | _PAGE_PCD, [_PAGE_CACHE_MODE_UC_MINUS] =0 | _PAGE_PCD, [_PAGE_CACHE_MODE_UC ] = _PAGE_PWT | _PAGE_PCD, [_PAGE_CACHE_MODE_WT ] =0 | _PAGE_PCD,@@ -50,11 +50,11 @@ EXPORT_SYMBOL(__cachemode2pte_tbl);uint8_t __pte2cachemode_tbl[8 ] = { [__pte2cm_idx (0 |0 |0 )] = _PAGE_CACHE_MODE_WB, - [__pte2cm_idx (_PAGE_PWT |0 |0 )] = _PAGE_CACHE_MODE_WC, + [__pte2cm_idx (_PAGE_PWT |0 |0 )] = _PAGE_CACHE_MODE_UC_MINUS, [__pte2cm_idx (0 | _PAGE_PCD |0 )] = _PAGE_CACHE_MODE_UC_MINUS, [__pte2cm_idx (_PAGE_PWT | _PAGE_PCD |0 )] = _PAGE_CACHE_MODE_UC, [__pte2cm_idx (0 |0 | _PAGE_PAT)] = _PAGE_CACHE_MODE_WB, - [__pte2cm_idx (_PAGE_PWT |0 | _PAGE_PAT)] = _PAGE_CACHE_MODE_WC, + [__pte2cm_idx (_PAGE_PWT |0 | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC_MINUS, [__pte2cm_idx (0 | _PAGE_PCD | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC_MINUS, [__pte2cm_idx (_PAGE_PWT | _PAGE_PCD | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC, };arch/x86/mm/pat.c +53
-28@@ -68,8 +68,6 @@ static int __init pat_debug_setup(char *str) }__setup ("debugpat" , pat_debug_setup); -static u64 __read_mostly boot_pat_state; -#ifdef CONFIG_X86_PAT /* * X86 PAT uses page flags WC and Uncached together to keep track of @@ -177,14 +175,12 @@ static enum page_cache_mode pat_get_cache_mode(unsigned pat_val, char *msg)* configuration. * Using lower indices is preferred, so we start with highest index. */ -void pat_init_cache_modes (void ) +void pat_init_cache_modes (u64 pat) { -int i;enum page_cache_mode cache;char pat_msg[33 ]; -u64 pat; +int i; -rdmsrl (MSR_IA32_CR_PAT , pat); pat_msg[32 ] =0 ;for (i =7 ; i >=0 ; i--) { cache = pat_get_cache_mode((pat >> (i * 8)) & 7,@@ -198,24 +194,33 @@ void pat_init_cache_modes(void)static void pat_bsp_init (u64 pat) { +u64 tmp_pat; +if (!cpu_has_pat) {pat_disable ("PAT not supported by CPU." );return ; } -rdmsrl (MSR_IA32_CR_PAT , boot_pat_state); -if (!boot_pat_state) { +if (!pat_enabled ()) + goto done; + +rdmsrl (MSR_IA32_CR_PAT , tmp_pat); +if (!tmp_pat) {pat_disable ("PAT MSR is 0, disabled." );return ; }wrmsrl (MSR_IA32_CR_PAT , pat); -pat_init_cache_modes (); +done: +pat_init_cache_modes (pat); }static void pat_ap_init (u64 pat) { +if (!pat_enabled ()) +return ; +if (!cpu_has_pat) {/* * If this happens we are on a secondary CPU, but switched to @@ -231,25 +236,45 @@ void pat_init(void) {u64 pat; -if (!pat_enabled ()) -return ; - -/* -* Set PWT to Write-Combining. All other bits stay the same: -* -* PTE encoding used in Linux: -* PAT -* |PCD -* ||PWT -* ||| -* 000 WB _PAGE_CACHE_WB -* 001 WC _PAGE_CACHE_WC -* 010 UC- _PAGE_CACHE_UC_MINUS -* 011 UC _PAGE_CACHE_UC -* PAT bit unused -*/ - pat =PAT (0 ,WB ) |PAT (1 ,WC ) |PAT (2 ,UC_MINUS ) |PAT (3 ,UC ) | -PAT (4 ,WB ) |PAT (5 ,WC ) |PAT (6 ,UC_MINUS ) |PAT (7 ,UC ); +if (!pat_enabled ()) { +/* +* No PAT. Emulate the PAT table that corresponds to the two +* cache bits, PWT (Write Through) and PCD (Cache Disable). This +* setup is the same as the BIOS default setup when the system +* has PAT but the "nopat" boot option has been specified. This +* emulated PAT table is used when MSR_IA32_CR_PAT returns 0. +* +* PTE encoding used: +* +* PCD +* |PWT PAT +* || slot +* 00 0 WB : _PAGE_CACHE_MODE_WB +* 01 1 WT : _PAGE_CACHE_MODE_WT +* 10 2 UC-: _PAGE_CACHE_MODE_UC_MINUS +* 11 3 UC : _PAGE_CACHE_MODE_UC +* +* NOTE: When WC or WP is used, it is redirected to UC- per +* the default setup in __cachemode2pte_tbl[]. +*/ + pat =PAT (0 ,WB ) |PAT (1 ,WT ) |PAT (2 ,UC_MINUS ) |PAT (3 ,UC ) | +PAT (4 ,WB ) |PAT (5 ,WT ) |PAT (6 ,UC_MINUS ) |PAT (7 ,UC ); + }else { +/* +* PTE encoding used in Linux: +* PAT +* |PCD +* ||PWT +* ||| +* 000 WB _PAGE_CACHE_WB +* 001 WC _PAGE_CACHE_WC +* 010 UC- _PAGE_CACHE_UC_MINUS +* 011 UC _PAGE_CACHE_UC +* PAT bit unused +*/ + pat =PAT (0 ,WB ) |PAT (1 ,WC ) |PAT (2 ,UC_MINUS ) |PAT (3 ,UC ) | +PAT (4 ,WB ) |PAT (5 ,WC ) |PAT (6 ,UC_MINUS ) |PAT (7 ,UC ); + }if (!boot_cpu_done) {pat_bsp_init (pat);arch/x86/xen/enlighten.c +1
-0@@ -1467,6 +1467,7 @@ asmlinkage __visible void __init xen_start_kernel(void) {struct physdev_set_iopl set_iopl;unsigned long initrd_start =0 ; +u64 pat;int rc;if (!xen_start_info)
arch/x86/xen/enlighten.c asmlinkage __visible void __init xen_start_kernel(void) · line 1582
Quoted 10 lines
arch/x86/xen/enlighten.c +2
-2@@ -1574,8 +1575,8 @@ asmlinkage __visible void __init xen_start_kernel(void)* Modify the cache mode translation tables to match Xen's PAT * configuration. */ - -pat_init_cache_modes (); +rdmsrl (MSR_IA32_CR_PAT , pat); +pat_init_cache_modes (pat);/* keep using Xen gdt for now; no urgent need to change it */
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Toshi Kani
Reviewed-byRe: [PATCH 2/4] x86/pat: Merge pat_init_cache_modes() into its caller
In reply to Borislav PetkovQuoted 28 lines · Borislav Petkov
Quoted 3 lines · Borislav Petkov
From: Borislav Petkov <[email protected]>
This way we can pass pat MSR value directly.
This breaks xen as that function is used there, doh. :-\
Jürgen,
can you check the
enlighten.cchanges below please?I'm reading xen's PAT config from
MSR_IA32_CR_PATand handing it down topat_init_cache_modes(). That shouldn't change current behavior AFAICT becausepat_init_cache_modes()did it itself before.Right?
Thanks.
---
Author: Borislav Petkov <[email protected]> Date: Sat May 30 13:09:55 2015 +0200x86/pat: Emulate PAT when it is disabled
In the case when PAT is disabled on the command line with "nopat" or when virtualization doesn't support PAT (correctly) - see
Quoted 8 lines
9d34cfdf4796("x86: Don't rely on VMWare emulating PAT MSR correctly").we emulate it using the PWT and PCD cache attribute bits. Get rid of
boot_pat_statewhile at it.Based on a conglomerate patch from Toshi Kani.
Signed-off-by Borislav Petkov <[email protected]>
Thanks,
-Toshi
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Borislav Petkov
maintainerPATCH 3/4 x86/pat: Emulate PAT when it is disabled
In reply to Borislav PetkovFrom: Borislav Petkov <[email protected]>
In the case when PAT is disabled on the command line with "nopat" or when virtualization doesn't support PAT (correctly) - see
9d34cfdf4796 ("x86: Don't rely on VMWare emulating PAT MSR correctly").
we emulate it using the PWT and PCD cache attribute bits. Get rid of boot_pat_state while at it.
Based on a conglomerate patch from Toshi Kani.
--- arch/x86/mm/init.c | 6 ++--- arch/x86/mm/pat.c | 72 +++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 52 insertions(+), 26 deletions(-)
arch/x86/mm/init.c +3 -3
@@ -40,7 +40,7 @@*/ uint16_t __cachemode2pte_tbl[_PAGE_CACHE_MODE_NUM] = { [_PAGE_CACHE_MODE_WB ] =0 |0 , - [_PAGE_CACHE_MODE_WC ] = _PAGE_PWT |0 , + [_PAGE_CACHE_MODE_WC ] =0 | _PAGE_PCD, [_PAGE_CACHE_MODE_UC_MINUS] =0 | _PAGE_PCD, [_PAGE_CACHE_MODE_UC ] = _PAGE_PWT | _PAGE_PCD, [_PAGE_CACHE_MODE_WT ] =0 | _PAGE_PCD,
@@ -50,11 +50,11 @@ EXPORT_SYMBOL(__cachemode2pte_tbl);uint8_t __pte2cachemode_tbl[8 ] = { [__pte2cm_idx (0 |0 |0 )] = _PAGE_CACHE_MODE_WB, - [__pte2cm_idx (_PAGE_PWT |0 |0 )] = _PAGE_CACHE_MODE_WC, + [__pte2cm_idx (_PAGE_PWT |0 |0 )] = _PAGE_CACHE_MODE_UC_MINUS, [__pte2cm_idx (0 | _PAGE_PCD |0 )] = _PAGE_CACHE_MODE_UC_MINUS, [__pte2cm_idx (_PAGE_PWT | _PAGE_PCD |0 )] = _PAGE_CACHE_MODE_UC, [__pte2cm_idx (0 |0 | _PAGE_PAT)] = _PAGE_CACHE_MODE_WB, - [__pte2cm_idx (_PAGE_PWT |0 | _PAGE_PAT)] = _PAGE_CACHE_MODE_WC, + [__pte2cm_idx (_PAGE_PWT |0 | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC_MINUS, [__pte2cm_idx (0 | _PAGE_PCD | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC_MINUS, [__pte2cm_idx (_PAGE_PWT | _PAGE_PCD | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC, };
arch/x86/mm/pat.c +49 -23
108 lines not on this page · raw message
Signature · 1 line
2.3.5
Borislav Petkov
maintainerPATCH 4/4 x86/pat: Remove pat_enabled() checks
In reply to Borislav PetkovFrom: Borislav Petkov <[email protected]>
Now that we emulate a PAT table when PAT is disabled, there's no need for those checks anymore as the PAT abstraction will handle those cases too.
Based on a conglomerate patch from Toshi Kani.
--- arch/x86/mm/iomap_32.c | 12 ++++++------ arch/x86/mm/ioremap.c | 5 +---- arch/x86/mm/pageattr.c | 3 --- arch/x86/mm/pat.c | 13 +++---------- 4 files changed, 10 insertions(+), 23 deletions(-)
arch/x86/mm/iomap_32.c +6 -6
@@ -77,13 +77,13 @@ void __iomem * iomap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot) {/* -* For non-PAT systems, promote PAGE_KERNEL_WC to PAGE_KERNEL_UC_MINUS. -* PAGE_KERNEL_WC maps to PWT, which translates to uncached if the -* MTRR is UC or WC. UC_MINUS gets the real intention, of the -* user, which is "WC if the MTRR is WC, UC if you can't do that." +* For non-PAT systems, translate non-WB request to UC- just in +* case the caller set the PWT bit to prot directly without using +* pgprot_writecombine(). UC- translates to uncached if the MTRR +* is UC or WC. UC- gets the real intention, of the user, which is +* "WC if the MTRR is WC, UC if you can't do that." */ -if (!pat_enabled () &&pgprot_val (prot) == - (__PAGE_KERNEL |cachemode2protval (_PAGE_CACHE_MODE_WC))) +if (!pat_enabled () &&pgprot2cachemode (prot) != _PAGE_CACHE_MODE_WB) prot =__pgprot (__PAGE_KERNEL |cachemode2protval (_PAGE_CACHE_MODE_UC_MINUS));
arch/x86/mm/ioremap.c +1 -4
@@ -292,11 +292,8 @@ EXPORT_SYMBOL_GPL(ioremap_uc);*/ void __iomem *ioremap_wc (resource_size_t phys_addr,unsigned long size) { -if (pat_enabled ()) -return __ioremap_caller (phys_addr, size, _PAGE_CACHE_MODE_WC, +return __ioremap_caller (phys_addr, size, _PAGE_CACHE_MODE_WC,__builtin_return_address (0 )); -else -return ioremap_nocache (phys_addr, size); }EXPORT_SYMBOL (ioremap_wc);
arch/x86/mm/pageattr.c +0 -3
@@ -1571,9 +1571,6 @@ int set_memory_wc(unsigned long addr, int numpages) {int ret; -if (!pat_enabled ()) -return set_memory_uc (addr, numpages); - ret =reserve_memtype (__pa (addr),__pa (addr) + numpages *PAGE_SIZE , _PAGE_CACHE_MODE_WC,NULL );if (ret)
arch/x86/mm/pat.c +3 -10
@@ -432,12 +432,8 @@ int reserve_memtype(u64 start, u64 end, enum page_cache_mode req_type,if (!pat_enabled ()) {/* This is identical to page table setting without PAT */ -if (new_type) { -if (req_type == _PAGE_CACHE_MODE_WC) - *new_type = _PAGE_CACHE_MODE_UC_MINUS; -else - *new_type = req_type; - } +if (new_type) + *new_type = req_type;return 0 ; }
@@ -941,11 +937,8 @@ void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn,pgprot_t pgprot_writecombine (pgprot_t prot) { -if (pat_enabled ()) -return __pgprot (pgprot_val (prot) | +return __pgprot (pgprot_val (prot) |cachemode2protval (_PAGE_CACHE_MODE_WC)); -else -return pgprot_noncached (prot); }EXPORT_SYMBOL_GPL (pgprot_writecombine);
Signature · 1 line
2.3.5
Re: [PATCH 4/4] x86/pat: Remove pat_enabled() checks
Quoted 9 lines · Borislav Petkov
From: Borislav Petkov <[email protected]>
Now that we emulate a PAT table when PAT is disabled, there's no need for those checks anymore as the PAT abstraction will handle those cases too.
Based on a conglomerate patch from Toshi Kani.
Signed-off-by Borislav Petkov <[email protected]>
I reviewed the 1/3-3/3 patchset in your "tip-mm-2" branch, which is different from this submitted patchset 1/4-4/4. So, my review-by applies to the 3 patches in the "tip-mm-2" branch.
Thanks,
-Toshi
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Borislav Petkov
maintainerRe: [PATCH 4/4] x86/pat: Remove pat_enabled() checks
Quoted 3 lines · Toshi Kani
I reviewed the 1/3-3/3 patchset in your "tip-mm-2" branch, which is different from this submitted patchset 1/4-4/4. So, my review-by applies to the 3 patches in the "tip-mm-2" branch.
That's fine, the 4 patches were broken due to xen using pat_init_cache_modes() too. So the 3 are the right ones.
Thanks.
Signature · 11 lines
Regards/Gruss,
Boris.
ECO tip #101: Trim your mails when you reply.
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>Re: [PATCH 1/4] x86/pat: Untangle pat_init()
In reply to Borislav PetkovQuoted 6 lines · Borislav Petkov
From: Borislav Petkov <[email protected]>
Split it into a BSP and AP version which makes the PAT initialization path actually readable again.
Signed-off-by Borislav Petkov <[email protected]>
Thanks,
-Toshi
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH v11 2/12] x86, mm, pat: Refactor !pat_enabled handling
In reply to Borislav PetkovQuoted 12 lines · Borislav Petkov
Quoted 10 lines · Toshi Kani
From: Toshi Kani <[email protected]>
This patch refactors the !pat_enabled code paths and integrates them into the PAT abstraction code. The PAT table is emulated by corresponding to the two cache attribute bits, PWT (Write Through) and PCD (Cache Disable). The emulated PAT table is the same as the BIOS default setup when the system has PAT but the "nopat" boot option is specified. The emulated PAT table is also used when
MSR_IA32_CR_PATreturns 0 --9d34cfdf4796("x86: Don't rely on VMWare emulating PAT MSR correctly").
Quoted 4 lines
To be honest, I wasn't surprised when you sent me the same patch and ignored most of my comments. For the future, please let me know if I'm wasting my time with commenting on your stuff so that I can plan my work and not waste time and energy reviewing, ok?
I apologize that I overlooked a comment requesting to divide this refactor patch into smaller patches.
Quoted 10 lines
Unfortunately, if you want something done right, you have to do it yourself.
So I did that, I split that ugly cleanup into something much more readable, patches as a reply to this message.
Feel free to base your work ontop of
git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git#tip-mm-2
I will look into your changes, and rebase the patchset.
Thanks,
-Toshi
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH v11 3/12 x86, mm, pat: Set WT to PA7 slot of PAT MSR
In reply to Toshi KaniFrom: Toshi Kani <[email protected]>
This patch sets WT to the PA7 slot in the PAT MSR when the processor is not affected by the PAT errata. The PA7 slot is chosen to improve robustness in the presence of errata that might cause the high PAT bit to be ignored. This way a buggy PA7 slot access will hit the PA3 slot, which is UC, so at worst we lose performance without causing a correctness issue.
The following Intel processors are affected by the PAT errata.
errata cpuid
----------------------------------------------------
Pentium 2, A52 family 0x6, model 0x5
Pentium 3, E27 family 0x6, model 0x7, 0x8
Pentium 3 Xenon, G26 family 0x6, model 0x7, 0x8, 0xa
Pentium M, Y26 family 0x6, model 0x9 Pentium M 90nm, X9 family 0x6, model 0xd Pentium 4, N46 family 0xf, model 0x0
Instead of making sharp boundary checks, this patch makes conservative checks to exclude all Pentium 2, 3, M and 4 family processors. For such processors, _PAGE_CACHE_MODE_WT is redirected to UC- per the default setup in __cachemode2pte_tbl[].
--- arch/x86/mm/pat.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 8 deletions(-)
arch/x86/mm/pat.c +49 -8
@@ -201,6 +201,7 @@ void pat_init_cache_modes(void)void pat_init (void ) {u64 pat; +struct cpuinfo_x86 *c = &boot_cpu_data;static bool boot_cpu_done;if (!boot_cpu_done) {
@@ -246,21 +247,61 @@ void pat_init(void)PAT (4 ,WB ) |PAT (5 ,WT ) |PAT (6 ,UC_MINUS ) |PAT (7 ,UC );if (!boot_pat_state) boot_pat_state = pat; - }else { + + }else if ((c->x86_vendor ==X86_VENDOR_INTEL ) && + (((c->x86 ==0x6 ) && (c->x86_model <=0xd )) || + ((c->x86 ==0xf ) && (c->x86_model <=0x6 )))) {/* -* PTE encoding used in Linux: +* PAT support with the lower four entries. Intel Pentium 2, +* 3, M, and 4 are affected by PAT errata, which makes the +* upper four entries unusable. We do not use the upper four +* entries for all the affected processor families for safe. +* +* PTE encoding used in Linux: * PAT * |PCD -* ||PWT -* ||| -* 000 WB _PAGE_CACHE_WB -* 001 WC _PAGE_CACHE_WC -* 010 UC- _PAGE_CACHE_UC_MINUS -* 011 UC _PAGE_CACHE_UC +* ||PWT PAT +* ||| slot +* 000 0 WB : _PAGE_CACHE_MODE_WB +* 001 1 WC : _PAGE_CACHE_MODE_WC +* 010 2 UC-: _PAGE_CACHE_MODE_UC_MINUS +* 011 3 UC : _PAGE_CACHE_MODE_UC * PAT bit unused +* +* NOTE: When WT or WP is used, it is redirected to UC- per +* the default setup in __cachemode2pte_tbl[]. */ pat =PAT (0 ,WB ) |PAT (1 ,WC ) |PAT (2 ,UC_MINUS ) |PAT (3 ,UC ) |PAT (4 ,WB ) |PAT (5 ,WC ) |PAT (6 ,UC_MINUS ) |PAT (7 ,UC ); + }else { +/* +* PAT full support. We put WT in slot 7 to improve +* robustness in the presence of errata that might cause +* the high PAT bit to be ignored. This way a buggy slot 7 +* access will hit slot 3, and slot 3 is UC, so at worst +* we lose performance without causing a correctness issue. +* Pentium 4 erratum N46 is an example of such an erratum, +* although we try not to use PAT at all on affected CPUs. +* +* PTE encoding used in Linux: +* PAT +* |PCD +* ||PWT PAT +* ||| slot +* 000 0 WB : _PAGE_CACHE_MODE_WB +* 001 1 WC : _PAGE_CACHE_MODE_WC +* 010 2 UC-: _PAGE_CACHE_MODE_UC_MINUS +* 011 3 UC : _PAGE_CACHE_MODE_UC +* 100 4 WB : Reserved +* 101 5 WC : Reserved +* 110 6 UC-: Reserved +* 111 7 WT : _PAGE_CACHE_MODE_WT +* +* The reserved slots are unused, but mapped to their +* corresponding types in the presence of PAT errata. +*/ + pat =PAT (0 ,WB ) |PAT (1 ,WC ) |PAT (2 ,UC_MINUS ) |PAT (3 ,UC ) | +PAT (4 ,WB ) |PAT (5 ,WC ) |PAT (6 ,UC_MINUS ) |PAT (7 ,WT ); }if (pat_enabled ())
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH v11 4/12 x86, mm, pat: Change reserve_memtype() for WT
In reply to Toshi KaniFrom: Toshi Kani <[email protected]>
When a RAM range is requested to reserve_memtype(), it calls reserve_ram_pages_type() to verify the requested type. reserve_ram_pages_type() is changed to fail WT and WP requests with -EINVAL since set_page_memtype() is limited to handle three types, WB, WC and UC-.
---
Patch 10/12 enhances set_page_memtype() to support WT.
--- arch/x86/mm/pat.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
arch/x86/mm/pat.c +10 -0
@@ -389,6 +389,8 @@ static int pat_pagerange_is_ram(resource_size_t start, resource_size_t end)/* * For RAM pages, we use page flags to mark the pages with appropriate type. +* The page flags are limited to three types, WB, WC and UC-. +* WT and WP requests fail with -EINVAL, and UC gets redirected to UC-. * Here we do two pass: * - Find the memtype of all the pages in the range, look for any conflicts * - In case of no conflicts, set the new memtype for pages in the range
@@ -400,6 +402,13 @@ static int reserve_ram_pages_type(u64 start, u64 end,struct page *page;u64 pfn; +if ((req_type == _PAGE_CACHE_MODE_WT) || + (req_type == _PAGE_CACHE_MODE_WP)) { +if (new_type) + *new_type = _PAGE_CACHE_MODE_UC_MINUS; +return -EINVAL ; + } +if (req_type == _PAGE_CACHE_MODE_UC) {/* We do not support strong UC */ WARN_ON_ONCE (1 );
@@ -449,6 +458,7 @@ static int free_ram_pages_type(u64 start, u64 end)* - _PAGE_CACHE_MODE_WC * - _PAGE_CACHE_MODE_UC_MINUS * - _PAGE_CACHE_MODE_UC +* - _PAGE_CACHE_MODE_WT * * If new_type is NULL, function will return an error if it cannot reserve the * region with req_type. If new_type is non-NULL, function will return
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH v11 5/12 x86, asm: Change is_new_memtype_allowed() for WT
In reply to Toshi KaniFrom: Toshi Kani <[email protected]>
__ioremap_caller() calls reserve_memtype() to set new_pcm (existing map type if any), and then calls is_new_memtype_allowed() to verify if converting to new_pcm is allowed when pcm (request type) is different from new_pcm.
When WT is requested, the caller expects that writes are ordered and uncached. Therefore, this patch changes is_new_memtype_allowed() to disallow the following cases.
- If the request is WT, mapping type cannot be WB
- If the request is WT, mapping type cannot be WC
--- arch/x86/include/asm/pgtable.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
arch/x86/include/asm/pgtable.h +7 -1
@@ -398,11 +398,17 @@ static inline int is_new_memtype_allowed(u64 paddr, unsigned long size,* requested memtype: * - request is uncached, return cannot be write-back * - request is write-combine, return cannot be write-back +* - request is write-through, return cannot be write-back +* - request is write-through, return cannot be write-combine */ if ((pcm == _PAGE_CACHE_MODE_UC_MINUS && new_pcm == _PAGE_CACHE_MODE_WB) || (pcm == _PAGE_CACHE_MODE_WC && - new_pcm == _PAGE_CACHE_MODE_WB)) { + new_pcm == _PAGE_CACHE_MODE_WB) || + (pcm == _PAGE_CACHE_MODE_WT && + new_pcm == _PAGE_CACHE_MODE_WB) || + (pcm == _PAGE_CACHE_MODE_WT && + new_pcm == _PAGE_CACHE_MODE_WC)) {return 0 ; }
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH v11 6/12 x86, mm, asm-gen: Add ioremap_wt() for WT
In reply to Toshi KaniFrom: Toshi Kani <[email protected]>
This patch adds ioremap_wt() for creating WT mapping on x86. It follows the same model as ioremap_wc() for multi-architecture support. ARCH_HAS_IOREMAP_WT is defined 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().
--- Documentation/x86/pat.txt | 4 +++- arch/x86/include/asm/io.h | 2 ++ arch/x86/mm/ioremap.c | 21 +++++++++++++++++++++ include/asm-generic/io.h | 9 +++++++++ include/asm-generic/iomap.h | 4 ++++ 5 files changed, 39 insertions(+), 1 deletion(-)
Documentation/x86/pat.txt +3 -1
@@ -12,7 +12,7 @@ virtual addresses. PAT allows for different types of memory attributes. The most commonly used 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
@@ -40,6 +40,8 @@ ioremap_nocache | -- | UC- | UC- | | | | | ioremap_wc | -- | -- | WC | | | | | +ioremap_wt | -- | -- | WT | + | | | | set_memory_uc | UC- | -- | -- | set_memory_wb | | | | | | | |
arch/x86/include/asm/io.h +2 -0
@@ -35,6 +35,7 @@*/ #define ARCH_HAS_IOREMAP_WC +#define ARCH_HAS_IOREMAP_WT #include <linux/string.h> #include <linux/compiler.h>
@@ -321,6 +322,7 @@ extern void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr);extern int ioremap_change_attr (unsigned long vaddr,unsigned long size,enum page_cache_mode pcm);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);
arch/x86/mm/ioremap.c +21 -0
@@ -172,6 +172,10 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr, prot =__pgprot (pgprot_val (prot) |cachemode2protval (_PAGE_CACHE_MODE_WC));break ; +case _PAGE_CACHE_MODE_WT: + prot =__pgprot (pgprot_val (prot) | +cachemode2protval (_PAGE_CACHE_MODE_WT)); +break ;case _PAGE_CACHE_MODE_WB:break ; }
@@ -297,6 +301,23 @@ void __iomem *ioremap_wc(resource_size_t phys_addr, unsigned long size) }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) { return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WB,
include/asm-generic/io.h +9 -0
@@ -785,8 +785,17 @@ static inline void __iomem *ioremap_wc(phys_addr_t offset, size_t size) }#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#define iounmap iounmap +static inline void iounmap (void __iomem *addr) { }
include/asm-generic/iomap.h +4 -0
@@ -66,6 +66,10 @@ extern void ioport_unmap(void __iomem *);#define ioremap_wc ioremap_nocache#endif +#ifndef ARCH_HAS_IOREMAP_WT +#define ioremap_wt ioremap_nocache +#endif +#ifdef CONFIG_PCI /* Destroy a virtual mapping cookie for a PCI BAR (memory or IO) */ struct pci_dev ;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Geert Uytterhoeven
maintainerRe: [PATCH v11 6/12] x86, mm, asm-gen: Add ioremap_wt() for WT
Quoted 25 lines · Toshi Kani
include/asm-generic/io.h +9
-0@@ -785,8 +785,17 @@ static inline void __iomem *ioremap_wc(phys_addr_t offset, size_t size) }#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#define iounmap iounmap +static inline void iounmap (void __iomem *addr) { }include/asm-generic/iomap.h +0
-0
include/asm-generic/iomap.h extern void ioport_unmap(void __iomem *); · line 71
Quoted 6 lines
include/asm-generic/iomap.h +3
-0@@ -66,6 +66,10 @@ extern void ioport_unmap(void __iomem *);#define ioremap_wc ioremap_nocache#endif +#ifndef ARCH_HAS_IOREMAP_WT +#define ioremap_wt ioremap_nocache +#endif
Defining ioremap_wt in two different places in asm-generic looks fishy to me.
If <asm/io.h> already provides it (either through asm-generic/io.h or arch/<arch>/include/asm/io.h), why does asm-generic/iomap.h need to define its own version?
I see this pattern already exists for ioremap_wc...
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH v11 6/12] x86, mm, asm-gen: Add ioremap_wt() for WT
Quoted 35 lines · Geert Uytterhoeven
Quoted 25 lines · Toshi Kani
include/asm-generic/io.h +9
-0@@ -785,8 +785,17 @@ static inline void __iomem *ioremap_wc(phys_addr_t offset, size_t size) }#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#define iounmap iounmap +static inline void iounmap (void __iomem *addr) { }include/asm-generic/iomap.h +0
-0include/asm-generic/iomap.h extern void ioport_unmap(void __iomem *); · line 71
Quoted 6 lines
include/asm-generic/iomap.h +3
-0@@ -66,6 +66,10 @@ extern void ioport_unmap(void __iomem *);#define ioremap_wc ioremap_nocache#endif +#ifndef ARCH_HAS_IOREMAP_WT +#define ioremap_wt ioremap_nocache +#endif Defining
ioremap_wtin two different places in asm-generic looks fishy to me.
Quoted 5 lines
If <
asm/io.h> already provides it (either throughasm-generic/io.hor arch/<arch>/include/asm/io.h), why doesasm-generic/iomap.hneed to define its own version?I see this pattern already exists for
ioremap_wc...
Yes, this patchset follows the model of ioremap_wc. This duplication was introduced by 9216efafc52 "asm-generic/io.h: Reconcile I/O accessor overrides", while the original ioremap_wc support changed asm-generic/iomap.h (1526a756fba). As described in patch 07, some architectures define ioremap_xxx() locally as well.
It is too risky to do everything in one short. I will look into the duplication issue as a separate item after this patchset is settled.
Thanks,
-Toshi
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH v11 7/12 arch/*/asm/io.h: Add ioremap_wt() to all architectures
In reply to Toshi KaniFrom: Toshi Kani <[email protected]>
This patch adds ioremap_wt() to all arch-specific asm/io.h which define ioremap_wc() locally. These arch-specific asm/io.h do not include <asm-generic/iomap.h>. Some of them include <asm-generic/io.h>, but ioremap_wt() is defined for consistency since they define all ioremap_xxx locally.
ioremap_wt() is defined indentical to ioremap_nocache() to all architectures without WT support.
frv and m68k already have ioremap_writethrough(). This patch implements ioremap_wt() indetical to ioremap_writethrough() and defines ARCH_HAS_IOREMAP_WT in both architectures.
This patch allows generic drivers to use ioremap_wt().
--- arch/arc/include/asm/io.h | 1 + arch/arm/include/asm/io.h | 1 + arch/arm64/include/asm/io.h | 1 + arch/avr32/include/asm/io.h | 1 + arch/frv/include/asm/io.h | 7 +++++++ arch/m32r/include/asm/io.h | 1 + arch/m68k/include/asm/io_mm.h | 7 +++++++ arch/m68k/include/asm/io_no.h | 6 ++++++ arch/metag/include/asm/io.h | 3 +++ arch/microblaze/include/asm/io.h | 1 + arch/mn10300/include/asm/io.h | 1 + arch/nios2/include/asm/io.h | 1 + arch/s390/include/asm/io.h | 1 + arch/sparc/include/asm/io_32.h | 1 + arch/sparc/include/asm/io_64.h | 1 + arch/tile/include/asm/io.h | 1 + arch/xtensa/include/asm/io.h | 1 + 17 files changed, 36 insertions(+)
arch/arc/include/asm/io.h +1 -0
@@ -20,6 +20,7 @@ extern void iounmap(const void __iomem *addr);#define ioremap_nocache (phy, sz) ioremap(phy, sz)#define ioremap_wc (phy, sz) ioremap(phy, sz) +#define ioremap_wt (phy, sz) ioremap(phy, sz)/* Change struct page to physical address */ #define page_to_phys (page) (page_to_pfn(page) << PAGE_SHIFT)
arch/arm/include/asm/io.h +1 -0
@@ -336,6 +336,7 @@ extern void _memset_io(volatile void __iomem *, int, size_t);#define ioremap_nocache (cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE)#define ioremap_cache (cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE_CACHED)#define ioremap_wc (cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE_WC) +#define ioremap_wt (cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE)#define iounmap __arm_iounmap/*
arch/arm64/include/asm/io.h +1 -0
@@ -170,6 +170,7 @@ extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);#define ioremap (addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))#define ioremap_nocache (addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))#define ioremap_wc (addr, size) __ioremap((addr), (size), __pgprot(PROT_NORMAL_NC)) +#define ioremap_wt (addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))#define iounmap __iounmap/*
arch/avr32/include/asm/io.h +1 -0
@@ -296,6 +296,7 @@ extern void __iounmap(void __iomem *addr); __iounmap(addr)#define ioremap_wc ioremap_nocache +#define ioremap_wt ioremap_nocache#define cached (addr) P1SEGADDR(addr)#define uncached (addr) P2SEGADDR(addr)
arch/frv/include/asm/io.h +7 -0
@@ -17,6 +17,8 @@#ifdef __KERNEL__ +#define ARCH_HAS_IOREMAP_WT +#include <linux/types.h> #include <asm/virtconvert.h> #include <asm/string.h>
@@ -270,6 +272,11 @@ static inline void __iomem *ioremap_writethrough(unsigned long physaddr, unsignereturn __ioremap (physaddr, size,IOMAP_WRITETHROUGH ); } +static inline void __iomem *ioremap_wt (unsigned long physaddr,unsigned long size) +{ +return __ioremap (physaddr, size,IOMAP_WRITETHROUGH ); +} +static inline void __iomem *ioremap_fullcache (unsigned long physaddr,unsigned long size) {return __ioremap (physaddr, size,IOMAP_FULL_CACHING );
arch/m32r/include/asm/io.h +1 -0
@@ -68,6 +68,7 @@ static inline void __iomem *ioremap(unsigned long offset, unsigned long size)extern void iounmap (volatile void __iomem *addr);#define ioremap_nocache (off,size) ioremap(off,size)#define ioremap_wc ioremap_nocache +#define ioremap_wt ioremap_nocache/* * IO bus memory addresses are also 1:1 with the physical address
arch/m68k/include/asm/io_mm.h +7 -0
@@ -20,6 +20,8 @@#ifdef __KERNEL__ +#define ARCH_HAS_IOREMAP_WT +#include <linux/compiler.h> #include <asm/raw_io.h> #include <asm/virtconvert.h>
@@ -470,6 +472,11 @@ static inline void __iomem *ioremap_writethrough(unsigned long physaddr, {return __ioremap (physaddr, size,IOMAP_WRITETHROUGH ); } +static inline void __iomem *ioremap_wt (unsigned long physaddr, +unsigned long size) +{ +return __ioremap (physaddr, size,IOMAP_WRITETHROUGH ); +}static inline void __iomem *ioremap_fullcache (unsigned long physaddr,unsigned long size) {
arch/m68k/include/asm/io_no.h +6 -0
@@ -3,6 +3,8 @@#ifdef __KERNEL__ +#define ARCH_HAS_IOREMAP_WT +#include <asm/virtconvert.h> #include <asm-generic/iomap.h>
@@ -157,6 +159,10 @@ static inline void *ioremap_writethrough(unsigned long physaddr, unsigned long s {return __ioremap (physaddr, size,IOMAP_WRITETHROUGH ); } +static inline void *ioremap_wt (unsigned long physaddr,unsigned long size) +{ +return __ioremap (physaddr, size,IOMAP_WRITETHROUGH ); +}static inline void *ioremap_fullcache (unsigned long physaddr,unsigned long size) {return __ioremap (physaddr, size,IOMAP_FULL_CACHING );
arch/metag/include/asm/io.h +3 -0
@@ -160,6 +160,9 @@ extern void __iounmap(void __iomem *addr);#define ioremap_wc (offset, size) \ __ioremap((offset), (size), _PAGE_WR_COMBINE) +#define ioremap_wt (offset, size) \ + __ioremap((offset), (size), 0) +#define iounmap (addr) \ __iounmap(addr)
arch/microblaze/include/asm/io.h +1 -0
@@ -43,6 +43,7 @@ extern void __iomem *ioremap(phys_addr_t address, unsigned long size);#define ioremap_nocache (addr, size) ioremap((addr), (size))#define ioremap_fullcache (addr, size) ioremap((addr), (size))#define ioremap_wc (addr, size) ioremap((addr), (size)) +#define ioremap_wt (addr, size) ioremap((addr), (size))#endif /* CONFIG_MMU */
arch/mn10300/include/asm/io.h +1 -0
@@ -282,6 +282,7 @@ static inline void __iomem *ioremap_nocache(unsigned long offset, unsigned long }#define ioremap_wc ioremap_nocache +#define ioremap_wt ioremap_nocachestatic inline void iounmap (void __iomem *addr) {
arch/nios2/include/asm/io.h +1 -0
@@ -46,6 +46,7 @@ static inline void iounmap(void __iomem *addr) }#define ioremap_wc ioremap_nocache +#define ioremap_wt ioremap_nocache/* Pages to physical address... */ #define page_to_phys (page) virt_to_phys(page_to_virt(page))
arch/s390/include/asm/io.h +1 -0
@@ -29,6 +29,7 @@ void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr);#define ioremap_nocache (addr, size) ioremap(addr, size)#define ioremap_wc ioremap_nocache +#define ioremap_wt ioremap_nocachestatic inline void __iomem *ioremap (unsigned long offset,unsigned long size) {
arch/sparc/include/asm/io_32.h +1 -0
@@ -129,6 +129,7 @@ static inline void sbus_memcpy_toio(volatile void __iomem *dst,void __iomem *ioremap (unsigned long offset,unsigned long size);#define ioremap_nocache (X ,Y ) ioremap((X),(Y))#define ioremap_wc (X ,Y ) ioremap((X),(Y)) +#define ioremap_wt (X ,Y ) ioremap((X),(Y))void iounmap (volatile void __iomem *addr);/* Create a virtual mapping cookie for an IO port range */
arch/sparc/include/asm/io_64.h +1 -0
@@ -402,6 +402,7 @@ static inline void __iomem *ioremap(unsigned long offset, unsigned long size)#define ioremap_nocache (X ,Y ) ioremap((X),(Y))#define ioremap_wc (X ,Y ) ioremap((X),(Y)) +#define ioremap_wt (X ,Y ) ioremap((X),(Y))static inline void iounmap (volatile void __iomem *addr) {
arch/tile/include/asm/io.h +1 -0
@@ -54,6 +54,7 @@ extern void iounmap(volatile void __iomem *addr);#define ioremap_nocache (physaddr, size) ioremap(physaddr, size)#define ioremap_wc (physaddr, size) ioremap(physaddr, size) +#define ioremap_wt (physaddr, size) ioremap(physaddr, size)#define ioremap_writethrough (physaddr, size) ioremap(physaddr, size)#define ioremap_fullcache (physaddr, size) ioremap(physaddr, size)
arch/xtensa/include/asm/io.h +1 -0
@@ -59,6 +59,7 @@ static inline void __iomem *ioremap_cache(unsigned long offset, }#define ioremap_wc ioremap_nocache +#define ioremap_wt ioremap_nocachestatic inline void __iomem *ioremap (unsigned long offset,unsigned long size) {
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH v11 8/12 video/fbdev, asm/io.h: Remove ioremap_writethrough()
In reply to Toshi KaniFrom: Toshi Kani <[email protected]>
This patch removes the callers of ioremap_writethrough() by replacing them with ioremap_wt() in three drivers under drivers/video/fbdev. It then removes ioremap_writethrough() defined in some architecture's asm/io.h, frv, m68k, microblaze, and tile.
--- arch/frv/include/asm/io.h | 5 ----- arch/m68k/include/asm/io_mm.h | 5 ----- arch/m68k/include/asm/io_no.h | 4 ---- arch/microblaze/include/asm/io.h | 1 - arch/tile/include/asm/io.h | 1 - drivers/video/fbdev/amifb.c | 4 ++-- drivers/video/fbdev/atafb.c | 3 +-- drivers/video/fbdev/hpfb.c | 4 ++-- 8 files changed, 5 insertions(+), 22 deletions(-)
arch/frv/include/asm/io.h +0 -5
@@ -267,11 +267,6 @@ static inline void __iomem *ioremap_nocache(unsigned long physaddr, unsigned lonreturn __ioremap (physaddr, size,IOMAP_NOCACHE_SER ); } -static inline void __iomem *ioremap_writethrough (unsigned long physaddr,unsigned long size) -{ -return __ioremap (physaddr, size,IOMAP_WRITETHROUGH ); -} -static inline void __iomem *ioremap_wt (unsigned long physaddr,unsigned long size) {return __ioremap (physaddr, size,IOMAP_WRITETHROUGH );
arch/m68k/include/asm/io_mm.h +0 -5
@@ -467,11 +467,6 @@ static inline void __iomem *ioremap_nocache(unsigned long physaddr, unsigned lon {return __ioremap (physaddr, size,IOMAP_NOCACHE_SER ); } -static inline void __iomem *ioremap_writethrough (unsigned long physaddr, -unsigned long size) -{ -return __ioremap (physaddr, size,IOMAP_WRITETHROUGH ); -}static inline void __iomem *ioremap_wt (unsigned long physaddr,unsigned long size) {
arch/m68k/include/asm/io_no.h +0 -4
@@ -155,10 +155,6 @@ static inline void *ioremap_nocache(unsigned long physaddr, unsigned long size) {return __ioremap (physaddr, size,IOMAP_NOCACHE_SER ); } -static inline void *ioremap_writethrough (unsigned long physaddr,unsigned long size) -{ -return __ioremap (physaddr, size,IOMAP_WRITETHROUGH ); -}static inline void *ioremap_wt (unsigned long physaddr,unsigned long size) {return __ioremap (physaddr, size,IOMAP_WRITETHROUGH );
arch/microblaze/include/asm/io.h +0 -1
@@ -39,7 +39,6 @@ extern resource_size_t isa_mem_base;extern void iounmap (void __iomem *addr);extern void __iomem *ioremap (phys_addr_t address,unsigned long size); -#define ioremap_writethrough (addr, size) ioremap((addr), (size))#define ioremap_nocache (addr, size) ioremap((addr), (size))#define ioremap_fullcache (addr, size) ioremap((addr), (size))#define ioremap_wc (addr, size) ioremap((addr), (size))
arch/tile/include/asm/io.h +0 -1
@@ -55,7 +55,6 @@ extern void iounmap(volatile void __iomem *addr);#define ioremap_nocache (physaddr, size) ioremap(physaddr, size)#define ioremap_wc (physaddr, size) ioremap(physaddr, size)#define ioremap_wt (physaddr, size) ioremap(physaddr, size) -#define ioremap_writethrough (physaddr, size) ioremap(physaddr, size)#define ioremap_fullcache (physaddr, size) ioremap(physaddr, size)#define mmiowb ()
drivers/video/fbdev/amifb.c +2 -2
@@ -3705,8 +3705,8 @@ default_chipset:* access the videomem with writethrough cache */ info->fix.smem_start = (u_long )ZTWO_PADDR (videomemory); - videomemory = (u_long )ioremap_writethrough (info->fix.smem_start, - info->fix.smem_len); + videomemory = (u_long )ioremap_wt (info->fix.smem_start, + info->fix.smem_len);if (!videomemory) {dev_warn (&pdev->dev,"Unable to map videomem cached writethrough\n" );
drivers/video/fbdev/atafb.c +1 -2
@@ -3185,8 +3185,7 @@ int __init atafb_init(void)/* Map the video memory (physical address given) to somewhere * in the kernel address space. */ - external_screen_base =ioremap_writethrough (external_addr, - external_len); + external_screen_base =ioremap_wt (external_addr, external_len);if (external_vgaiobase) external_vgaiobase = (unsigned long )ioremap (external_vgaiobase,0x10000 );
drivers/video/fbdev/hpfb.c +2 -2
@@ -241,8 +241,8 @@ static int hpfb_init_one(unsigned long phys_base, unsigned long virt_base) fb_info.fix.line_length = fb_width; fb_height = (in_8 (fb_regs +HPFB_FBHMSB ) <<8 ) |in_8 (fb_regs +HPFB_FBHLSB ); fb_info.fix.smem_len = fb_width * fb_height; - fb_start = (unsigned long )ioremap_writethrough (fb_info.fix.smem_start, - fb_info.fix.smem_len); + fb_start = (unsigned long )ioremap_wt (fb_info.fix.smem_start, + fb_info.fix.smem_len); hpfb_defined.xres = (in_8 (fb_regs +HPFB_DWMSB ) <<8 ) |in_8 (fb_regs +HPFB_DWLSB ); hpfb_defined.yres = (in_8 (fb_regs +HPFB_DHMSB ) <<8 ) |in_8 (fb_regs +HPFB_DHLSB ); hpfb_defined.xres_virtual = hpfb_defined.xres;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH v11 9/12 x86, mm, pat: Add pgprot_writethrough() for WT
In reply to Toshi KaniFrom: Toshi Kani <[email protected]>
This patch adds pgprot_writethrough() for setting WT to a given pgprot_t.
--- arch/x86/include/asm/pgtable_types.h | 3 +++ arch/x86/mm/pat.c | 7 +++++++ include/asm-generic/pgtable.h | 4 ++++ 3 files changed, 14 insertions(+)
arch/x86/include/asm/pgtable_types.h +3 -0
@@ -367,6 +367,9 @@ extern int nx_enabled;#define pgprot_writecombine pgprot_writecombineextern pgprot_t pgprot_writecombine (pgprot_t prot); +#define pgprot_writethrough pgprot_writethrough +extern pgprot_t pgprot_writethrough (pgprot_t prot); +/* Indicate that x86 has its own track and untrack pfn vma functions */ #define __HAVE_PFNMAP_TRACKING
arch/x86/mm/pat.c +7 -0
@@ -987,6 +987,13 @@ pgprot_t pgprot_writecombine(pgprot_t prot) }EXPORT_SYMBOL_GPL (pgprot_writecombine); +pgprot_t pgprot_writethrough (pgprot_t prot) +{ +return __pgprot (pgprot_val (prot) | +cachemode2protval (_PAGE_CACHE_MODE_WT)); +} +EXPORT_SYMBOL_GPL (pgprot_writethrough); +#if defined(CONFIG_DEBUG_FS ) && defined(CONFIG_X86_PAT )static struct memtype *memtype_get_idx (loff_t pos)
include/asm-generic/pgtable.h +4 -0
@@ -262,6 +262,10 @@ static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b)#define pgprot_writecombine pgprot_noncached#endif +#ifndef pgprot_writethrough +#define pgprot_writethrough pgprot_noncached +#endif +#ifndef pgprot_device#define pgprot_device pgprot_noncached#endif
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH v11 10/12 x86, mm, asm: Add WT support to set_page_memtype()
In reply to Toshi KaniFrom: Toshi Kani <[email protected]>
As set_memory_wb() calls free_ram_pages_type(), which then calls set_page_memtype() with -1, _PGMT_DEFAULT is used for tracking the WB type. _PGMT_WB is defined but unused. Hence, this patch renames _PGMT_DEFAULT to _PGMT_WB to clarify the usage, and releases the slot used by _PGMT_WB before. free_ram_pages_type() is changed to call set_page_memtype() with _PGMT_WB, and get_page_memtype() returns _PAGE_CACHE_MODE_WB for _PGMT_WB.
This patch then defines _PGMT_WT to the released slot. This enables set_page_memtype() to track the WT type.
--- arch/x86/mm/pat.c | 60 +++++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 30 deletions(-)
arch/x86/mm/pat.c +30 -30
@@ -70,18 +70,22 @@ static u64 __read_mostly boot_pat_state;#ifdef CONFIG_X86_PAT /* -* X86 PAT uses page flags WC and Uncached together to keep track of -* memory type of pages that have backing page struct. X86 PAT supports 3 -* different memory types, _PAGE_CACHE_MODE_WB, _PAGE_CACHE_MODE_WC and -* _PAGE_CACHE_MODE_UC_MINUS and fourth state where page's memory type has not -* been changed from its default (value of -1 used to denote this). -* Note we do not support _PAGE_CACHE_MODE_UC here. +* X86 PAT uses page flags arch_1 and uncached together to keep track of +* memory type of pages that have backing page struct. +* +* X86 PAT supports 4 different memory types: +* - _PAGE_CACHE_MODE_WB +* - _PAGE_CACHE_MODE_WC +* - _PAGE_CACHE_MODE_UC_MINUS +* - _PAGE_CACHE_MODE_WT +* +* _PAGE_CACHE_MODE_WB is the default type. */ -#define _PGMT_DEFAULT 0 +#define _PGMT_WB 0#define _PGMT_WC (1UL << PG_arch_1)#define _PGMT_UC_MINUS (1UL << PG_uncached) -#define _PGMT_WB (1UL << PG_uncached | 1UL << PG_arch_1) +#define _PGMT_WT (1UL << PG_uncached | 1UL << PG_arch_1)#define _PGMT_MASK (1UL << PG_uncached | 1UL << PG_arch_1)#define _PGMT_CLEAR_MASK (~_PGMT_MASK)
@@ -89,14 +93,14 @@ static inline enum page_cache_mode get_page_memtype(struct page *pg) {unsigned long pg_flags = pg->flags & _PGMT_MASK; -if (pg_flags == _PGMT_DEFAULT) -return -1 ; +if (pg_flags == _PGMT_WB) +return _PAGE_CACHE_MODE_WB;else if (pg_flags == _PGMT_WC)return _PAGE_CACHE_MODE_WC;else if (pg_flags == _PGMT_UC_MINUS)return _PAGE_CACHE_MODE_UC_MINUS;else -return _PAGE_CACHE_MODE_WB; +return _PAGE_CACHE_MODE_WT; } static inline void set_page_memtype(struct page *pg,
@@ -113,11 +117,12 @@ static inline void set_page_memtype(struct page *pg,case _PAGE_CACHE_MODE_UC_MINUS: memtype_flags = _PGMT_UC_MINUS;break ; -case _PAGE_CACHE_MODE_WB: - memtype_flags = _PGMT_WB; +case _PAGE_CACHE_MODE_WT: + memtype_flags = _PGMT_WT;break ; +case _PAGE_CACHE_MODE_WB:default : - memtype_flags = _PGMT_DEFAULT; + memtype_flags = _PGMT_WB;break ; }
@@ -389,8 +394,11 @@ static int pat_pagerange_is_ram(resource_size_t start, resource_size_t end)/* * For RAM pages, we use page flags to mark the pages with appropriate type. -* The page flags are limited to three types, WB, WC and UC-. -* WT and WP requests fail with -EINVAL, and UC gets redirected to UC-. +* The page flags are limited to four types, WB (default), WC, WT and UC-. +* WP request fails with -EINVAL, and UC gets redirected to UC-. Setting +* a new memory type is only allowed to a page mapped with the default WB +* type. +* * Here we do two pass: * - Find the memtype of all the pages in the range, look for any conflicts * - In case of no conflicts, set the new memtype for pages in the range
@@ -402,8 +410,7 @@ static int reserve_ram_pages_type(u64 start, u64 end,struct page *page;u64 pfn; -if ((req_type == _PAGE_CACHE_MODE_WT) || - (req_type == _PAGE_CACHE_MODE_WP)) { +if (req_type == _PAGE_CACHE_MODE_WP) {if (new_type) *new_type = _PAGE_CACHE_MODE_UC_MINUS;return -EINVAL ;
@@ -420,7 +427,7 @@ static int reserve_ram_pages_type(u64 start, u64 end, page =pfn_to_page (pfn); type =get_page_memtype (page); -if (type !=-1 ) { +if (type != _PAGE_CACHE_MODE_WB) {pr_info ("x86/PAT: reserve_ram_pages_type failed [mem %#010Lx-%#010Lx], track 0x%x, req 0x%x\n" , start, end -1 , type, req_type);if (new_type)
@@ -447,7 +454,7 @@ static int free_ram_pages_type(u64 start, u64 end)for (pfn = (start >>PAGE_SHIFT ); pfn < (end >>PAGE_SHIFT ); ++pfn) { page =pfn_to_page (pfn); -set_page_memtype (page,-1 ); +set_page_memtype (page, _PAGE_CACHE_MODE_WB); }return 0 ; }
@@ -588,7 +595,7 @@ int free_memtype(u64 start, u64 end)* Only to be called when PAT is enabled * * Returns _PAGE_CACHE_MODE_WB, _PAGE_CACHE_MODE_WC, _PAGE_CACHE_MODE_UC_MINUS -* or _PAGE_CACHE_MODE_UC +* or _PAGE_CACHE_MODE_WT. */ static enum page_cache_mode lookup_memtype (u64 paddr) {
@@ -600,16 +607,9 @@ static enum page_cache_mode lookup_memtype(u64 paddr)if (pat_pagerange_is_ram (paddr, paddr +PAGE_SIZE )) {struct page *page; - page =pfn_to_page (paddr >>PAGE_SHIFT ); - rettype =get_page_memtype (page); -/* -* -1 from get_page_memtype() implies RAM page is in its -* default state and not reserved, and hence of type WB -*/ -if (rettype ==-1 ) - rettype = _PAGE_CACHE_MODE_WB; -return rettype; + page =pfn_to_page (paddr >>PAGE_SHIFT ); +return get_page_memtype (page); }spin_lock (&memtype_lock);
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH v11 11/12 x86, mm: Add set_memory_wt() for WT
In reply to Toshi KaniFrom: Toshi Kani <[email protected]>
Now that reserve_ram_pages_type() accepts the WT type, this patch adds set_memory_wt(), set_memory_array_wt() and set_pages_array_wt() for setting the WT type to the regular memory.
ioremap_change_attr() is also extended to accept the WT type.
--- Documentation/x86/pat.txt | 9 ++++- arch/x86/include/asm/cacheflush.h | 6 +++- arch/x86/mm/ioremap.c | 3 ++ arch/x86/mm/pageattr.c | 62 +++++++++++++++++++++++++++++-------- 4 files changed, 63 insertions(+), 17 deletions(-)
Documentation/x86/pat.txt +6 -3
@@ -48,6 +48,9 @@ set_memory_uc | UC- | -- | -- | set_memory_wc | WC | -- | -- | set_memory_wb | | | | | | | | +set_memory_wt | WT | -- | -- | + set_memory_wb | | | | + | | | | pci sysfs resource | -- | -- | UC- | | | | | pci sysfs resource_wc | -- | -- | WC |
@@ -150,8 +153,8 @@ can be more restrictive, in case of any existing aliasing for that address. For example: If there is an existing uncached mapping, a new ioremap_wc can return uncached mapping in place of write-combine requested. -set_memory_[uc|wc] and set_memory_wb should be used in pairs, where driver will -first make a region uc or wc and switch it back to wb after use. +set_memory_[uc|wc|wt] and set_memory_wb should be used in pairs, where driver +will first make a region uc, wc or wt and switch it back to wb after use. Over time writes to /proc/mtrr will be deprecated in favor of using PAT based interfaces. Users writing to /proc/mtrr are suggested to use above interfaces.
@@ -159,7 +162,7 @@ interfaces. Users writing to /proc/mtrr are suggested to use above interfaces. Drivers should use ioremap_[uc|wc] to access PCI BARs with [uc|wc] access types. -Drivers should use set_memory_[uc|wc] to set access type for RAM ranges. +Drivers should use set_memory_[uc|wc|wt] to set access type for RAM ranges. PAT debugging
arch/x86/include/asm/cacheflush.h +5 -1
@@ -8,7 +8,7 @@/* * The set_memory_* API can be used to change various attributes of a virtual * address range. The attributes include: -* Cachability : UnCached, WriteCombining, WriteBack +* Cachability : UnCached, WriteCombining, WriteThrough, WriteBack * Executability : eXeutable, NoteXecutable * Read/Write : ReadOnly, ReadWrite * Presence : NotPresent
@@ -35,9 +35,11 @@int _set_memory_uc (unsigned long addr,int numpages);int _set_memory_wc (unsigned long addr,int numpages); +int _set_memory_wt (unsigned long addr,int numpages);int _set_memory_wb (unsigned long addr,int numpages);int set_memory_uc (unsigned long addr,int numpages);int set_memory_wc (unsigned long addr,int numpages); +int set_memory_wt (unsigned long addr,int numpages);int set_memory_wb (unsigned long addr,int numpages);int set_memory_x (unsigned long addr,int numpages);int set_memory_nx (unsigned long addr,int numpages);
@@ -48,10 +50,12 @@ int set_memory_4k(unsigned long addr, int numpages);int set_memory_array_uc (unsigned long *addr,int addrinarray);int set_memory_array_wc (unsigned long *addr,int addrinarray); +int set_memory_array_wt (unsigned long *addr,int addrinarray);int set_memory_array_wb (unsigned long *addr,int addrinarray);int set_pages_array_uc (struct page **pages,int addrinarray);int set_pages_array_wc (struct page **pages,int addrinarray); +int set_pages_array_wt (struct page **pages,int addrinarray);int set_pages_array_wb (struct page **pages,int addrinarray);/*
arch/x86/mm/ioremap.c +3 -0
@@ -42,6 +42,9 @@ int ioremap_change_attr(unsigned long vaddr, unsigned long size,case _PAGE_CACHE_MODE_WC: err =_set_memory_wc (vaddr, nrpages);break ; +case _PAGE_CACHE_MODE_WT: + err =_set_memory_wt (vaddr, nrpages); +break ;case _PAGE_CACHE_MODE_WB: err =_set_memory_wb (vaddr, nrpages);break ;
arch/x86/mm/pageattr.c +49 -13
117 lines not on this page · raw message
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH v11 12/12 drivers/block/pmem: Map NVDIMM with ioremap_wt()
In reply to Toshi KaniFrom: Toshi Kani <[email protected]>
The pmem driver maps NVDIMM with ioremap_nocache() as we cannot write back the contents of the CPU caches in case of a crash.
This patch changes to use ioremap_wt(), which provides uncached writes but cached reads, for improving read performance.
--- drivers/block/pmem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/block/pmem.c +2 -2
@@ -139,11 +139,11 @@ static struct pmem_device *pmem_alloc(struct device *dev, struct resource *res) }/* -* Map the memory as non-cachable, as we can't write back the contents +* Map the memory as write-through, as we can't write back the contents * of the CPU caches in case of a crash. */ err = -ENOMEM ; - pmem->virt_addr =ioremap_nocache (pmem->phys_addr, pmem->size); + pmem->virt_addr =ioremap_wt (pmem->phys_addr, pmem->size);if (!pmem->virt_addr) goto out_release_region;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH v11 12/12] drivers/block/pmem: Map NVDIMM with ioremap_wt()
Quoted 9 lines · Toshi Kani
From: Toshi Kani <[email protected]>
The pmem driver maps NVDIMM with
ioremap_nocache()as we cannot write back the contents of the CPU caches in case of a crash.This patch changes to use
ioremap_wt(), which provides uncached writes but cached reads, for improving read performance.Signed-off-by Toshi Kani <[email protected]>
...with the caveat that I'm going to follow in behind this series with generic ioremap_cache() enabling and converting pmem to use persistent_copy() / persistent_sync() when the arch/cpu has persistent memory synchronization instructions. After the conversion ioremap_wt() will still be there for the non-persistent_sync() capable case.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>