2022-03-19 19:48:11

by Jane Chu

[permalink] [raw]
Subject: [PATCH v6 2/6] x86/mce: relocate set{clear}_mce_nospec() functions

Relocate the twin mce functions to arch/x86/mm/pat/set_memory.c
file where they belong.

Signed-off-by: Jane Chu <[email protected]>
---
arch/x86/include/asm/set_memory.h | 52 -------------------------------
arch/x86/mm/pat/set_memory.c | 48 ++++++++++++++++++++++++++++
include/linux/set_memory.h | 9 +++---
3 files changed, 53 insertions(+), 56 deletions(-)

diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_memory.h
index ff0f2d90338a..648be0bd20df 100644
--- a/arch/x86/include/asm/set_memory.h
+++ b/arch/x86/include/asm/set_memory.h
@@ -88,56 +88,4 @@ void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc);

extern int kernel_set_to_readonly;

-#ifdef CONFIG_X86_64
-/*
- * Prevent speculative access to the page by either unmapping
- * it (if we do not require access to any part of the page) or
- * marking it uncacheable (if we want to try to retrieve data
- * from non-poisoned lines in the page).
- */
-static inline int set_mce_nospec(unsigned long pfn, bool unmap)
-{
- unsigned long decoy_addr;
- int rc;
-
- /* SGX pages are not in the 1:1 map */
- if (arch_is_platform_page(pfn << PAGE_SHIFT))
- return 0;
- /*
- * We would like to just call:
- * set_memory_XX((unsigned long)pfn_to_kaddr(pfn), 1);
- * but doing that would radically increase the odds of a
- * speculative access to the poison page because we'd have
- * the virtual address of the kernel 1:1 mapping sitting
- * around in registers.
- * Instead we get tricky. We create a non-canonical address
- * that looks just like the one we want, but has bit 63 flipped.
- * This relies on set_memory_XX() properly sanitizing any __pa()
- * results with __PHYSICAL_MASK or PTE_PFN_MASK.
- */
- decoy_addr = (pfn << PAGE_SHIFT) + (PAGE_OFFSET ^ BIT(63));
-
- if (unmap)
- rc = set_memory_np(decoy_addr, 1);
- else
- rc = set_memory_uc(decoy_addr, 1);
- if (rc)
- pr_warn("Could not invalidate pfn=0x%lx from 1:1 map\n", pfn);
- return rc;
-}
-#define set_mce_nospec set_mce_nospec
-
-/* Restore full speculative operation to the pfn. */
-static inline int clear_mce_nospec(unsigned long pfn)
-{
- return set_memory_wb((unsigned long) pfn_to_kaddr(pfn), 1);
-}
-#define clear_mce_nospec clear_mce_nospec
-#else
-/*
- * Few people would run a 32-bit kernel on a machine that supports
- * recoverable errors because they have too much memory to boot 32-bit.
- */
-#endif
-
#endif /* _ASM_X86_SET_MEMORY_H */
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index 042cfac6272b..9abc6077d768 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -1925,6 +1925,54 @@ int set_memory_wb(unsigned long addr, int numpages)
}
EXPORT_SYMBOL(set_memory_wb);

+#ifdef CONFIG_X86_64
+/*
+ * Prevent speculative access to the page by either unmapping
+ * it (if we do not require access to any part of the page) or
+ * marking it uncacheable (if we want to try to retrieve data
+ * from non-poisoned lines in the page).
+ */
+int set_mce_nospec(unsigned long pfn, bool unmap)
+{
+ unsigned long decoy_addr;
+ int rc;
+
+ /* SGX pages are not in the 1:1 map */
+ if (arch_is_platform_page(pfn << PAGE_SHIFT))
+ return 0;
+ /*
+ * We would like to just call:
+ * set_memory_XX((unsigned long)pfn_to_kaddr(pfn), 1);
+ * but doing that would radically increase the odds of a
+ * speculative access to the poison page because we'd have
+ * the virtual address of the kernel 1:1 mapping sitting
+ * around in registers.
+ * Instead we get tricky. We create a non-canonical address
+ * that looks just like the one we want, but has bit 63 flipped.
+ * This relies on set_memory_XX() properly sanitizing any __pa()
+ * results with __PHYSICAL_MASK or PTE_PFN_MASK.
+ */
+ decoy_addr = (pfn << PAGE_SHIFT) + (PAGE_OFFSET ^ BIT(63));
+
+ if (unmap)
+ rc = set_memory_np(decoy_addr, 1);
+ else
+ rc = set_memory_uc(decoy_addr, 1);
+ if (rc)
+ pr_warn("Could not invalidate pfn=0x%lx from 1:1 map\n", pfn);
+ return rc;
+}
+EXPORT_SYMBOL(set_mce_nospec);
+
+/* Restore full speculative operation to the pfn. */
+int clear_mce_nospec(unsigned long pfn)
+{
+ return set_memory_wb((unsigned long) pfn_to_kaddr(pfn), 1);
+}
+EXPORT_SYMBOL(clear_mce_nospec);
+
+#endif
+
int set_memory_x(unsigned long addr, int numpages)
{
if (!(__supported_pte_mask & _PAGE_NX))
diff --git a/include/linux/set_memory.h b/include/linux/set_memory.h
index f36be5166c19..d6263d7afb55 100644
--- a/include/linux/set_memory.h
+++ b/include/linux/set_memory.h
@@ -42,20 +42,21 @@ static inline bool can_set_direct_map(void)
#endif
#endif /* CONFIG_ARCH_HAS_SET_DIRECT_MAP */

-#ifndef set_mce_nospec
+#ifdef CONFIG_X86_64
+int set_mce_nospec(unsigned long pfn, bool unmap);
+int clear_mce_nospec(unsigned long pfn);
+#else
static inline int set_mce_nospec(unsigned long pfn, bool unmap)
{
return 0;
}
-#endif
-
-#ifndef clear_mce_nospec
static inline int clear_mce_nospec(unsigned long pfn)
{
return 0;
}
#endif

+
#ifndef CONFIG_ARCH_HAS_MEM_ENCRYPT
static inline int set_memory_encrypted(unsigned long addr, int numpages)
{
--
2.18.4


2022-03-19 20:36:29

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v6 2/6] x86/mce: relocate set{clear}_mce_nospec() functions

Hi Jane,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on nvdimm/libnvdimm-for-next]
[also build test WARNING on device-mapper-dm/for-next linus/master v5.17-rc8 next-20220318]
[cannot apply to tip/x86/mm]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Jane-Chu/DAX-poison-recovery/20220319-143144
base: https://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm.git libnvdimm-for-next
config: x86_64-randconfig-a015 (https://download.01.org/0day-ci/archive/20220319/[email protected]/config)
compiler: gcc-9 (Ubuntu 9.4.0-1ubuntu1~20.04) 9.4.0
reproduce (this is a W=1 build):
# https://github.com/0day-ci/linux/commit/71b9b09529b207ce15667c1f5fba4b727b6754e6
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Jane-Chu/DAX-poison-recovery/20220319-143144
git checkout 71b9b09529b207ce15667c1f5fba4b727b6754e6
# save the config file to linux build tree
mkdir build_dir
make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash arch/x86/mm/pat/ fs/fuse/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>

All warnings (new ones prefixed by >>):

>> arch/x86/mm/pat/set_memory.c:1935:5: warning: no previous prototype for 'set_mce_nospec' [-Wmissing-prototypes]
1935 | int set_mce_nospec(unsigned long pfn, bool unmap)
| ^~~~~~~~~~~~~~
>> arch/x86/mm/pat/set_memory.c:1968:5: warning: no previous prototype for 'clear_mce_nospec' [-Wmissing-prototypes]
1968 | int clear_mce_nospec(unsigned long pfn)
| ^~~~~~~~~~~~~~~~


vim +/set_mce_nospec +1935 arch/x86/mm/pat/set_memory.c

1927
1928 #ifdef CONFIG_X86_64
1929 /*
1930 * Prevent speculative access to the page by either unmapping
1931 * it (if we do not require access to any part of the page) or
1932 * marking it uncacheable (if we want to try to retrieve data
1933 * from non-poisoned lines in the page).
1934 */
> 1935 int set_mce_nospec(unsigned long pfn, bool unmap)
1936 {
1937 unsigned long decoy_addr;
1938 int rc;
1939
1940 /* SGX pages are not in the 1:1 map */
1941 if (arch_is_platform_page(pfn << PAGE_SHIFT))
1942 return 0;
1943 /*
1944 * We would like to just call:
1945 * set_memory_XX((unsigned long)pfn_to_kaddr(pfn), 1);
1946 * but doing that would radically increase the odds of a
1947 * speculative access to the poison page because we'd have
1948 * the virtual address of the kernel 1:1 mapping sitting
1949 * around in registers.
1950 * Instead we get tricky. We create a non-canonical address
1951 * that looks just like the one we want, but has bit 63 flipped.
1952 * This relies on set_memory_XX() properly sanitizing any __pa()
1953 * results with __PHYSICAL_MASK or PTE_PFN_MASK.
1954 */
1955 decoy_addr = (pfn << PAGE_SHIFT) + (PAGE_OFFSET ^ BIT(63));
1956
1957 if (unmap)
1958 rc = set_memory_np(decoy_addr, 1);
1959 else
1960 rc = set_memory_uc(decoy_addr, 1);
1961 if (rc)
1962 pr_warn("Could not invalidate pfn=0x%lx from 1:1 map\n", pfn);
1963 return rc;
1964 }
1965 EXPORT_SYMBOL(set_mce_nospec);
1966
1967 /* Restore full speculative operation to the pfn. */
> 1968 int clear_mce_nospec(unsigned long pfn)
1969 {
1970 return set_memory_wb((unsigned long) pfn_to_kaddr(pfn), 1);
1971 }
1972 EXPORT_SYMBOL(clear_mce_nospec);
1973

---
0-DAY CI Kernel Test Service
https://lists.01.org/hyperkitty/list/[email protected]

2022-03-21 19:04:31

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v6 2/6] x86/mce: relocate set{clear}_mce_nospec() functions

Hi Jane,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on nvdimm/libnvdimm-for-next]
[also build test WARNING on device-mapper-dm/for-next linus/master v5.17-rc8 next-20220318]
[cannot apply to tip/x86/mm]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Jane-Chu/DAX-poison-recovery/20220319-143144
base: https://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm.git libnvdimm-for-next
config: x86_64-randconfig-a012 (https://download.01.org/0day-ci/archive/20220319/[email protected]/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project a6e70e4056dff962ec634c5bd4f2f4105a0bef71)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/71b9b09529b207ce15667c1f5fba4b727b6754e6
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Jane-Chu/DAX-poison-recovery/20220319-143144
git checkout 71b9b09529b207ce15667c1f5fba4b727b6754e6
# save the config file to linux build tree
mkdir build_dir
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash arch/x86/mm/pat/ fs/fuse/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>

All warnings (new ones prefixed by >>):

>> arch/x86/mm/pat/set_memory.c:1935:5: warning: no previous prototype for function 'set_mce_nospec' [-Wmissing-prototypes]
int set_mce_nospec(unsigned long pfn, bool unmap)
^
arch/x86/mm/pat/set_memory.c:1935:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
int set_mce_nospec(unsigned long pfn, bool unmap)
^
static
>> arch/x86/mm/pat/set_memory.c:1968:5: warning: no previous prototype for function 'clear_mce_nospec' [-Wmissing-prototypes]
int clear_mce_nospec(unsigned long pfn)
^
arch/x86/mm/pat/set_memory.c:1968:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
int clear_mce_nospec(unsigned long pfn)
^
static
2 warnings generated.


vim +/set_mce_nospec +1935 arch/x86/mm/pat/set_memory.c

1927
1928 #ifdef CONFIG_X86_64
1929 /*
1930 * Prevent speculative access to the page by either unmapping
1931 * it (if we do not require access to any part of the page) or
1932 * marking it uncacheable (if we want to try to retrieve data
1933 * from non-poisoned lines in the page).
1934 */
> 1935 int set_mce_nospec(unsigned long pfn, bool unmap)
1936 {
1937 unsigned long decoy_addr;
1938 int rc;
1939
1940 /* SGX pages are not in the 1:1 map */
1941 if (arch_is_platform_page(pfn << PAGE_SHIFT))
1942 return 0;
1943 /*
1944 * We would like to just call:
1945 * set_memory_XX((unsigned long)pfn_to_kaddr(pfn), 1);
1946 * but doing that would radically increase the odds of a
1947 * speculative access to the poison page because we'd have
1948 * the virtual address of the kernel 1:1 mapping sitting
1949 * around in registers.
1950 * Instead we get tricky. We create a non-canonical address
1951 * that looks just like the one we want, but has bit 63 flipped.
1952 * This relies on set_memory_XX() properly sanitizing any __pa()
1953 * results with __PHYSICAL_MASK or PTE_PFN_MASK.
1954 */
1955 decoy_addr = (pfn << PAGE_SHIFT) + (PAGE_OFFSET ^ BIT(63));
1956
1957 if (unmap)
1958 rc = set_memory_np(decoy_addr, 1);
1959 else
1960 rc = set_memory_uc(decoy_addr, 1);
1961 if (rc)
1962 pr_warn("Could not invalidate pfn=0x%lx from 1:1 map\n", pfn);
1963 return rc;
1964 }
1965 EXPORT_SYMBOL(set_mce_nospec);
1966
1967 /* Restore full speculative operation to the pfn. */
> 1968 int clear_mce_nospec(unsigned long pfn)
1969 {
1970 return set_memory_wb((unsigned long) pfn_to_kaddr(pfn), 1);
1971 }
1972 EXPORT_SYMBOL(clear_mce_nospec);
1973

---
0-DAY CI Kernel Test Service
https://lists.01.org/hyperkitty/list/[email protected]

2022-03-22 10:51:28

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH v6 2/6] x86/mce: relocate set{clear}_mce_nospec() functions

> +EXPORT_SYMBOL(set_mce_nospec);

No need for this export at all.

> +
> +/* Restore full speculative operation to the pfn. */
> +int clear_mce_nospec(unsigned long pfn)
> +{
> + return set_memory_wb((unsigned long) pfn_to_kaddr(pfn), 1);
> +}
> +EXPORT_SYMBOL(clear_mce_nospec);

And this should be EXPORT_SYMBOL_GPL.

2022-03-23 23:44:09

by Jane Chu

[permalink] [raw]
Subject: Re: [PATCH v6 2/6] x86/mce: relocate set{clear}_mce_nospec() functions

On 3/22/2022 3:41 PM, Borislav Petkov wrote:
> On Sat, Mar 19, 2022 at 12:28:29AM -0600, Jane Chu wrote:
>> Relocate the twin mce functions to arch/x86/mm/pat/set_memory.c
>> file where they belong.
>>
>> Signed-off-by: Jane Chu <[email protected]>
>> ---
>> arch/x86/include/asm/set_memory.h | 52 -------------------------------
>> arch/x86/mm/pat/set_memory.c | 48 ++++++++++++++++++++++++++++
>> include/linux/set_memory.h | 9 +++---
>> 3 files changed, 53 insertions(+), 56 deletions(-)
>
> For the future, please use get_maintainers.pl so that you know who to Cc
> on patches. In this particular case, patches touching arch/x86/ should
> Cc [email protected]

Sure, thank you!

-jane

>
> Thx.
>

2022-03-24 02:10:22

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v6 2/6] x86/mce: relocate set{clear}_mce_nospec() functions

On Sat, Mar 19, 2022 at 12:28:29AM -0600, Jane Chu wrote:
> Relocate the twin mce functions to arch/x86/mm/pat/set_memory.c
> file where they belong.
>
> Signed-off-by: Jane Chu <[email protected]>
> ---
> arch/x86/include/asm/set_memory.h | 52 -------------------------------
> arch/x86/mm/pat/set_memory.c | 48 ++++++++++++++++++++++++++++
> include/linux/set_memory.h | 9 +++---
> 3 files changed, 53 insertions(+), 56 deletions(-)

For the future, please use get_maintainers.pl so that you know who to Cc
on patches. In this particular case, patches touching arch/x86/ should
Cc [email protected]

Thx.

--
Regards/Gruss,
Boris.

https://people.kernel.org/tglx/notes-about-netiquette

2022-03-25 19:37:31

by Jane Chu

[permalink] [raw]
Subject: Re: [PATCH v6 2/6] x86/mce: relocate set{clear}_mce_nospec() functions

On 3/22/2022 1:42 AM, Christoph Hellwig wrote:
>> +EXPORT_SYMBOL(set_mce_nospec);
>
> No need for this export at all.

Indeed, my bad, will remove it.

>
>> +
>> +/* Restore full speculative operation to the pfn. */
>> +int clear_mce_nospec(unsigned long pfn)
>> +{
>> + return set_memory_wb((unsigned long) pfn_to_kaddr(pfn), 1);
>> +}
>> +EXPORT_SYMBOL(clear_mce_nospec);
>
> And this should be EXPORT_SYMBOL_GPL.

Yes.

Thanks!
-jane