All of lore.kernel.org
 help / color / mirror / Atom feed
From: Juergen Gross <jgross@suse.com>
To: Borislav Petkov <bp@alien8.de>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	Andy Lutomirski <luto@amacapital.net>,
	arnd@arndb.de, Elliott@hp.com, hch@lst.de, hmh@hmh.eng.br,
	"H. Peter Anvin" <hpa@zytor.com>, Ingo Molnar <mingo@redhat.com>,
	konrad.wilk@oracle.com, linux-mm <linux-mm@kvack.org>,
	linux-nvdimm@lists.01.org, "Luis R. Rodriguez" <mcgrof@suse.com>,
	stefan.bader@canonical.com, Thomas Gleixner <tglx@linutronix.de>,
	Toshi Kani <toshi.kani@hp.com>, x86-ml <x86@kernel.org>,
	yigal@plexistor.com, lkml <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH 2/4] x86/pat: Merge pat_init_cache_modes() into its caller
Date: Sun, 31 May 2015 13:02:21 +0200	[thread overview]
Message-ID: <556AEA3D.4000502@suse.com> (raw)
In-Reply-To: <20150531102338.GB20440@pd.tnic>

On 05/31/2015 12:23 PM, Borislav Petkov wrote:
> On Sun, May 31, 2015 at 11:48:04AM +0200, Borislav Petkov wrote:
>> From: Borislav Petkov <bp@suse.de>
>>
>> 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?

Acked-by: Juergen Gross <jgross@suse.com>

>
> 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 <bp@suse.de>
> 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.
>
>      Signed-off-by: Borislav Petkov <bp@suse.de>
>      Cc: Andrew Morton <akpm@linux-foundation.org>
>      Cc: Andy Lutomirski <luto@amacapital.net>
>      Cc: arnd@arndb.de
>      Cc: Elliott@hp.com
>      Cc: hch@lst.de
>      Cc: hmh@hmh.eng.br
>      Cc: H. Peter Anvin <hpa@zytor.com>
>      Cc: Ingo Molnar <mingo@redhat.com>
>      Cc: jgross@suse.com
>      Cc: konrad.wilk@oracle.com
>      Cc: linux-mm <linux-mm@kvack.org>
>      Cc: linux-nvdimm@lists.01.org
>      Cc: Luis R. Rodriguez <mcgrof@suse.com>
>      Cc: stefan.bader@canonical.com
>      Cc: Thomas Gleixner <tglx@linutronix.de>
>      Cc: Toshi Kani <toshi.kani@hp.com>
>      Cc: x86-ml <x86@kernel.org>
>      Cc: yigal@plexistor.com
>
> diff --git a/arch/x86/include/asm/pat.h b/arch/x86/include/asm/pat.h
> index cdcff7f7f694..ca6c228d5e62 100644
> --- a/arch/x86/include/asm/pat.h
> +++ b/arch/x86/include/asm/pat.h
> @@ -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);
> diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
> index 1d553186c434..8533b46e6bee 100644
> --- a/arch/x86/mm/init.c
> +++ b/arch/x86/mm/init.c
> @@ -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,
>   };
> diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
> index 476d0780560f..6dc7826e4797 100644
> --- a/arch/x86/mm/pat.c
> +++ b/arch/x86/mm/pat.c
> @@ -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);
> diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
> index 46957ead3060..53233a9beea9 100644
> --- a/arch/x86/xen/enlighten.c
> +++ b/arch/x86/xen/enlighten.c
> @@ -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 */
>
>
>

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

WARNING: multiple messages have this Message-ID (diff)
From: Juergen Gross <jgross@suse.com>
To: Borislav Petkov <bp@alien8.de>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	Andy Lutomirski <luto@amacapital.net>,
	arnd@arndb.de, Elliott@hp.com, hch@lst.de, hmh@hmh.eng.br,
	"H. Peter Anvin" <hpa@zytor.com>, Ingo Molnar <mingo@redhat.com>,
	konrad.wilk@oracle.com, linux-mm <linux-mm@kvack.org>,
	linux-nvdimm@ml01.01.org, "Luis R. Rodriguez" <mcgrof@suse.com>,
	stefan.bader@canonical.com, Thomas Gleixner <tglx@linutronix.de>,
	Toshi Kani <toshi.kani@hp.com>, x86-ml <x86@kernel.org>,
	yigal@plexistor.com, lkml <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH 2/4] x86/pat: Merge pat_init_cache_modes() into its caller
Date: Sun, 31 May 2015 13:02:21 +0200	[thread overview]
Message-ID: <556AEA3D.4000502@suse.com> (raw)
In-Reply-To: <20150531102338.GB20440@pd.tnic>

On 05/31/2015 12:23 PM, Borislav Petkov wrote:
> On Sun, May 31, 2015 at 11:48:04AM +0200, Borislav Petkov wrote:
>> From: Borislav Petkov <bp@suse.de>
>>
>> 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?

Acked-by: Juergen Gross <jgross@suse.com>

>
> 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 <bp@suse.de>
> 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.
>
>      Signed-off-by: Borislav Petkov <bp@suse.de>
>      Cc: Andrew Morton <akpm@linux-foundation.org>
>      Cc: Andy Lutomirski <luto@amacapital.net>
>      Cc: arnd@arndb.de
>      Cc: Elliott@hp.com
>      Cc: hch@lst.de
>      Cc: hmh@hmh.eng.br
>      Cc: H. Peter Anvin <hpa@zytor.com>
>      Cc: Ingo Molnar <mingo@redhat.com>
>      Cc: jgross@suse.com
>      Cc: konrad.wilk@oracle.com
>      Cc: linux-mm <linux-mm@kvack.org>
>      Cc: linux-nvdimm@lists.01.org
>      Cc: Luis R. Rodriguez <mcgrof@suse.com>
>      Cc: stefan.bader@canonical.com
>      Cc: Thomas Gleixner <tglx@linutronix.de>
>      Cc: Toshi Kani <toshi.kani@hp.com>
>      Cc: x86-ml <x86@kernel.org>
>      Cc: yigal@plexistor.com
>
> diff --git a/arch/x86/include/asm/pat.h b/arch/x86/include/asm/pat.h
> index cdcff7f7f694..ca6c228d5e62 100644
> --- a/arch/x86/include/asm/pat.h
> +++ b/arch/x86/include/asm/pat.h
> @@ -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);
> diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
> index 1d553186c434..8533b46e6bee 100644
> --- a/arch/x86/mm/init.c
> +++ b/arch/x86/mm/init.c
> @@ -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,
>   };
> diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
> index 476d0780560f..6dc7826e4797 100644
> --- a/arch/x86/mm/pat.c
> +++ b/arch/x86/mm/pat.c
> @@ -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);
> diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
> index 46957ead3060..53233a9beea9 100644
> --- a/arch/x86/xen/enlighten.c
> +++ b/arch/x86/xen/enlighten.c
> @@ -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 */
>
>
>


WARNING: multiple messages have this Message-ID (diff)
From: Juergen Gross <jgross@suse.com>
To: Borislav Petkov <bp@alien8.de>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	Andy Lutomirski <luto@amacapital.net>,
	arnd@arndb.de, Elliott@hp.com, hch@lst.de, hmh@hmh.eng.br,
	"H. Peter Anvin" <hpa@zytor.com>, Ingo Molnar <mingo@redhat.com>,
	konrad.wilk@oracle.com, linux-mm <linux-mm@kvack.org>,
	linux-nvdimm@lists.01.org, "Luis R. Rodriguez" <mcgrof@suse.com>,
	stefan.bader@canonical.com, Thomas Gleixner <tglx@linutronix.de>,
	Toshi Kani <toshi.kani@hp.com>, x86-ml <x86@kernel.org>,
	yigal@plexistor.com, lkml <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH 2/4] x86/pat: Merge pat_init_cache_modes() into its caller
Date: Sun, 31 May 2015 13:02:21 +0200	[thread overview]
Message-ID: <556AEA3D.4000502@suse.com> (raw)
In-Reply-To: <20150531102338.GB20440@pd.tnic>

On 05/31/2015 12:23 PM, Borislav Petkov wrote:
> On Sun, May 31, 2015 at 11:48:04AM +0200, Borislav Petkov wrote:
>> From: Borislav Petkov <bp@suse.de>
>>
>> This way we can pass pat MSR value directly.
>
> This breaks xen as that function is used there, doh. :-\
>
> JA 1/4 rgen,
>
> can you check the enlighten.c changes below please?

Acked-by: Juergen Gross <jgross@suse.com>

>
> 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 <bp@suse.de>
> 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.
>
>      Signed-off-by: Borislav Petkov <bp@suse.de>
>      Cc: Andrew Morton <akpm@linux-foundation.org>
>      Cc: Andy Lutomirski <luto@amacapital.net>
>      Cc: arnd@arndb.de
>      Cc: Elliott@hp.com
>      Cc: hch@lst.de
>      Cc: hmh@hmh.eng.br
>      Cc: H. Peter Anvin <hpa@zytor.com>
>      Cc: Ingo Molnar <mingo@redhat.com>
>      Cc: jgross@suse.com
>      Cc: konrad.wilk@oracle.com
>      Cc: linux-mm <linux-mm@kvack.org>
>      Cc: linux-nvdimm@lists.01.org
>      Cc: Luis R. Rodriguez <mcgrof@suse.com>
>      Cc: stefan.bader@canonical.com
>      Cc: Thomas Gleixner <tglx@linutronix.de>
>      Cc: Toshi Kani <toshi.kani@hp.com>
>      Cc: x86-ml <x86@kernel.org>
>      Cc: yigal@plexistor.com
>
> diff --git a/arch/x86/include/asm/pat.h b/arch/x86/include/asm/pat.h
> index cdcff7f7f694..ca6c228d5e62 100644
> --- a/arch/x86/include/asm/pat.h
> +++ b/arch/x86/include/asm/pat.h
> @@ -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);
> diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
> index 1d553186c434..8533b46e6bee 100644
> --- a/arch/x86/mm/init.c
> +++ b/arch/x86/mm/init.c
> @@ -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,
>   };
> diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
> index 476d0780560f..6dc7826e4797 100644
> --- a/arch/x86/mm/pat.c
> +++ b/arch/x86/mm/pat.c
> @@ -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);
> diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
> index 46957ead3060..53233a9beea9 100644
> --- a/arch/x86/xen/enlighten.c
> +++ b/arch/x86/xen/enlighten.c
> @@ -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 */
>
>
>

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

  reply	other threads:[~2015-05-31 11:02 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-29 22:58 [PATCH v11 0/12] Support Write-Through mapping on x86 Toshi Kani
2015-05-29 22:58 ` Toshi Kani
2015-05-29 22:58 ` [PATCH v11 1/12] x86, mm, pat: Cleanup init flags in pat_init() Toshi Kani
2015-05-29 22:58   ` Toshi Kani
2015-05-29 22:59 ` [PATCH v11 2/12] x86, mm, pat: Refactor !pat_enabled handling Toshi Kani
2015-05-29 22:59   ` Toshi Kani
2015-05-31  9:46   ` Borislav Petkov
2015-05-31  9:46     ` Borislav Petkov
2015-05-31  9:48     ` [PATCH 1/4] x86/pat: Untangle pat_init() Borislav Petkov
2015-05-31  9:48       ` Borislav Petkov
2015-05-31  9:48       ` [PATCH 2/4] x86/pat: Merge pat_init_cache_modes() into its caller Borislav Petkov
2015-05-31  9:48         ` Borislav Petkov
2015-05-31 10:15         ` Juergen Gross
2015-05-31 10:15           ` Juergen Gross
2015-05-31 10:24           ` Borislav Petkov
2015-05-31 10:24             ` Borislav Petkov
2015-05-31 10:23         ` Borislav Petkov
2015-05-31 10:23           ` Borislav Petkov
2015-05-31 10:23           ` Borislav Petkov
2015-05-31 11:02           ` Juergen Gross [this message]
2015-05-31 11:02             ` Juergen Gross
2015-05-31 11:02             ` Juergen Gross
2015-06-01 18:15           ` Toshi Kani
2015-06-01 18:15             ` Toshi Kani
2015-06-01 18:15             ` Toshi Kani
2015-05-31  9:48       ` [PATCH 3/4] x86/pat: Emulate PAT when it is disabled Borislav Petkov
2015-05-31  9:48         ` Borislav Petkov
2015-05-31  9:48       ` [PATCH 4/4] x86/pat: Remove pat_enabled() checks Borislav Petkov
2015-05-31  9:48         ` Borislav Petkov
2015-06-01 18:26         ` Toshi Kani
2015-06-01 18:26           ` Toshi Kani
2015-06-01 18:51           ` Borislav Petkov
2015-06-01 18:51             ` Borislav Petkov
2015-06-01 16:17       ` [PATCH 1/4] x86/pat: Untangle pat_init() Toshi Kani
2015-06-01 16:17         ` Toshi Kani
2015-06-01 15:50     ` [PATCH v11 2/12] x86, mm, pat: Refactor !pat_enabled handling Toshi Kani
2015-06-01 15:50       ` Toshi Kani
2015-05-29 22:59 ` [PATCH v11 3/12] x86, mm, pat: Set WT to PA7 slot of PAT MSR Toshi Kani
2015-05-29 22:59   ` Toshi Kani
2015-05-29 22:59 ` [PATCH v11 4/12] x86, mm, pat: Change reserve_memtype() for WT Toshi Kani
2015-05-29 22:59   ` Toshi Kani
2015-05-29 22:59 ` [PATCH v11 5/12] x86, asm: Change is_new_memtype_allowed() " Toshi Kani
2015-05-29 22:59   ` Toshi Kani
2015-05-29 22:59 ` [PATCH v11 6/12] x86, mm, asm-gen: Add ioremap_wt() " Toshi Kani
2015-05-29 22:59   ` Toshi Kani
2015-05-30  9:18   ` Geert Uytterhoeven
2015-05-30  9:18     ` Geert Uytterhoeven
2015-05-31  0:58     ` Toshi Kani
2015-05-31  0:58       ` Toshi Kani
2015-05-29 22:59 ` [PATCH v11 7/12] arch/*/asm/io.h: Add ioremap_wt() to all architectures Toshi Kani
2015-05-29 22:59   ` Toshi Kani
2015-05-29 22:59 ` [PATCH v11 8/12] video/fbdev, asm/io.h: Remove ioremap_writethrough() Toshi Kani
2015-05-29 22:59   ` Toshi Kani
2015-05-29 22:59 ` [PATCH v11 9/12] x86, mm, pat: Add pgprot_writethrough() for WT Toshi Kani
2015-05-29 22:59   ` Toshi Kani
2015-05-29 22:59 ` [PATCH v11 10/12] x86, mm, asm: Add WT support to set_page_memtype() Toshi Kani
2015-05-29 22:59   ` Toshi Kani
2015-05-29 22:59 ` [PATCH v11 11/12] x86, mm: Add set_memory_wt() for WT Toshi Kani
2015-05-29 22:59   ` Toshi Kani
2015-05-29 22:59 ` [PATCH v11 12/12] drivers/block/pmem: Map NVDIMM with ioremap_wt() Toshi Kani
2015-05-29 22:59   ` Toshi Kani
2015-05-30  1:18   ` Dan Williams
2015-05-30  1:18     ` Dan Williams

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=556AEA3D.4000502@suse.com \
    --to=jgross@suse.com \
    --cc=Elliott@hp.com \
    --cc=akpm@linux-foundation.org \
    --cc=arnd@arndb.de \
    --cc=bp@alien8.de \
    --cc=hch@lst.de \
    --cc=hmh@hmh.eng.br \
    --cc=hpa@zytor.com \
    --cc=konrad.wilk@oracle.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=linux-nvdimm@lists.01.org \
    --cc=luto@amacapital.net \
    --cc=mcgrof@suse.com \
    --cc=mingo@redhat.com \
    --cc=stefan.bader@canonical.com \
    --cc=tglx@linutronix.de \
    --cc=toshi.kani@hp.com \
    --cc=x86@kernel.org \
    --cc=yigal@plexistor.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.