x86, pti: fix boot problems from Global-bit setting
Subsystems (3)
Dave Hansen
maintainerPATCH 1/2 x86, pti: fix boot problems from Global-bit setting
These are _very_ lightly tested. I'm throwing them out there for folks are looking for a fix.
---
From: Dave Hansen <[email protected]>
Part of the global bit _setting_ patches also includes clearing the Global bit when we do not want it. That is done with set_memory_nonglobal(), which uses change_page_attr_clear() in pageattr.c under the covers. However, it's pretty clear that change_page_attr_clear() has not been heavily used early in boot, or on kernel text.
It has checks like BUG_ON(irqs_disabled()), looking for interrupt disabling but that also trip in early boot on certain preempt configurations. Just copy the existing BUG_ON() sequence to check for early boot.
---
b/arch/x86/mm/pageattr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/mm/pageattr.c renamed from arch/x86/mm/pageattr.c~pti-glb-boot-problem-fix +2 -2
@@ -172,7 +172,7 @@ static void __cpa_flush_all(void *arg)static void cpa_flush_all (unsigned long cache) { -BUG_ON (irqs_disabled ()); +BUG_ON (irqs_disabled () && !early_boot_irqs_disabled);on_each_cpu (__cpa_flush_all, (void *) cache,1 ); }
@@ -236,7 +236,7 @@ static void cpa_flush_array(unsigned lonunsigned long do_wbinvd = cache && numpages >=1024 ;/* 4M threshold */ #endif -BUG_ON (irqs_disabled ()); +BUG_ON (irqs_disabled () && !early_boot_irqs_disabled);on_each_cpu (__cpa_flush_all, (void *) do_wbinvd,1 );
_
Dave Hansen
maintainerPATCH 2/2 x86, pti: fix boot warning from Global-bit setting
These are _very_ lightly tested. I'm throwing them out there for folks are looking for a fix.
---
From: Dave Hansen <[email protected]>
pageattr.c is not friendly when it encounters empty (zero) PTEs. The kernel linear map is exempt from these checks, but kernel text is not. This patch adds the code to also exempt kernel text from these checks. The proximate cause of these warnings was most likely an __init area that spanned a 2MB page boundary that resulted in a "zero" PMD.
---
b/arch/x86/mm/pageattr.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
arch/x86/mm/pageattr.c renamed from arch/x86/mm/pageattr.c~pti-glb-warning-inpageattr +15 -2
@@ -1151,6 +1151,16 @@ static int populate_pgd(struct cpa_datareturn 0 ; } +bool __cpa_pfn_in_highmap (unsigned long pfn) +{ +/* +* Kernel text has an alias mapping at a high address, known +* here as "highmap". +*/ +return within_inclusive (pfn,highmap_start_pfn (), +highmap_end_pfn ()); +} +static int __cpa_process_fault (struct cpa_data *cpa,unsigned long vaddr,int primary) {
@@ -1183,6 +1193,10 @@ static int __cpa_process_fault(struct cp cpa->numpages =1 ; cpa->pfn =__pa (vaddr) >>PAGE_SHIFT ;return 0 ; + + }else if (__cpa_pfn_in_highmap (cpa->pfn)) { +/* Faults in the highmap are OK, so do not warn: */ +return -EFAULT ; }else { WARN(1, KERN_WARNING "CPA: called for zero pte. " "vaddr = %lx cpa->vaddr = %lx\n", vaddr,
@@ -1335,8 +1349,7 @@ static int cpa_process_alias(struct cpa_* to touch the high mapped kernel as well: */ if (!within (vaddr, (unsigned long )_text, _brk_end) && -within_inclusive (cpa->pfn,highmap_start_pfn (), -highmap_end_pfn ())) { +__cpa_pfn_in_highmap (cpa->pfn)) {unsigned long temp_cpa_vaddr = (cpa->pfn <<PAGE_SHIFT ) + __START_KERNEL_map - phys_base; alias_cpa = *cpa;
_
Re: [PATCH 2/2] x86, pti: fix boot warning from Global-bit setting
Quoted 80 lines · Dave Hansen
These are _very_ lightly tested. I'm throwing them out there for folks are looking for a fix.
---
From: Dave Hansen <[email protected]>
pageattr.cis not friendly when it encounters empty (zero) PTEs. The kernel linear map is exempt from these checks, but kernel text is not. This patch adds the code to also exempt kernel text from these checks. The proximate cause of these warnings was most likely an__initarea that spanned a 2MB page boundary that resulted in a "zero" PMD.Signed-off-by Dave Hansen <[email protected]>Fixes 39114b7a7 (x86/pti: Never implicitly clear _PAGE_GLOBAL for kernel image)Reported-by Mariusz Ceier <[email protected]>Reported-by Aaro Koskinen <[email protected]>Cc Andrea Arcangeli <[email protected]>Cc Andy Lutomirski <[email protected]>Cc Arjan van de Ven <[email protected]>Cc Borislav Petkov <[email protected]>Cc Dan Williams <[email protected]>Cc David Woodhouse <[email protected]>Cc Greg Kroah-Hartman <[email protected]>Cc Hugh Dickins <[email protected]>Cc Josh Poimboeuf <[email protected]>Cc Juergen Gross <[email protected]>Cc Kees Cook <[email protected]>Cc Linus Torvalds <[email protected]>Cc Nadav Amit <[email protected]>Cc Peter Zijlstra <[email protected]>Cc Thomas Gleixner <[email protected]>---
b/arch/x86/mm/pageattr.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)diff -puN
arch/x86/mm/pageattr.c~pti-glb-warning-inpageattrarch/x86/mm/pageattr.carch/x86/mm/pageattr.c 2018-04-17 14:10:22.721395554 -0700 renamed from arch/x86/mm/pageattr.c~pti-glb-warning-inpageattr 2018-04-17 14:10:22.695395554 -0700 +15
-2@@ -1151,6 +1151,16 @@ static int populate_pgd(struct cpa_data return 0; } +bool __cpa_pfn_in_highmap(unsigned long pfn) +{ + /* + * Kernel text has an alias mapping at a high address, known + * here as "highmap". + */ + return within_inclusive(pfn, highmap_start_pfn(), + highmap_end_pfn()); +} + static int __cpa_process_fault(struct cpa_data *cpa, unsigned long vaddr, int primary) {@@ -1183,6 +1193,10 @@ static int __cpa_process_fault(struct cp cpa->numpages = 1; cpa->pfn = __pa(vaddr) >> PAGE_SHIFT; return 0; + + } else if (__cpa_pfn_in_highmap(cpa->pfn)) { + /* Faults in the highmap are OK, so do not warn: */ + return -EFAULT; } else { WARN(1, KERN_WARNING "CPA: called for zero pte. " "vaddr = %lx cpa->vaddr = %lx\n", vaddr,@@ -1335,8 +1349,7 @@ static int cpa_process_alias(struct cpa_ * to touch the high mapped kernel as well: */ if (!within(vaddr, (unsigned long)_text, _brk_end) && - within_inclusive(cpa->pfn, highmap_start_pfn(), - highmap_end_pfn())) { + __cpa_pfn_in_highmap(cpa->pfn)) { unsigned long temp_cpa_vaddr = (cpa->pfn << PAGE_SHIFT) + __START_KERNEL_map - phys_base; alias_cpa = *cpa;
Quoted 1 line
_
I confirm that these 2 patches fix the BUG for me in kernel 4.17.0-rc1.
Thanks
kbuild test robot
build botRe: [PATCH 2/2] x86, pti: fix boot warning from Global-bit setting
In reply to Dave HansenThank you for the patch! Yet something to improve:
Hi Dave,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on tip/x86/core]
[also build test ERROR on v4.17-rc1 next-20180418]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Dave-Hansen/x86-pti-fix-boot-problems-from-Global-bit-setting/20180418-181719
config: i386-randconfig-x000-201815 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0 reproduce:
# save the attached .config to linux build tree
make ARCH=i386 All errors (new ones prefixed by >>):
arch/x86/mm/pageattr.c: In function '__cpa_pfn_in_highmap':
>> arch/x86/mm/pageattr.c:1161:31: error: implicit declaration of function 'highmap_start_pfn'; did you mean 'node_start_pfn'? [-Werror=implicit-function-declaration]
return within_inclusive(pfn, highmap_start_pfn(),
^~~~~~~~~~~~~~~~~
node_start_pfn
>> arch/x86/mm/pageattr.c:1162:4: error: implicit declaration of function 'highmap_end_pfn'; did you mean 'pgdat_end_pfn'? [-Werror=implicit-function-declaration]
highmap_end_pfn());
^~~~~~~~~~~~~~~
pgdat_end_pfncc1: some warnings being treated as errors
vim +1161 arch/x86/mm/pageattr.c
1154
1155 bool __cpa_pfn_in_highmap(unsigned long pfn)
1156 {
1157 /*
1158 * Kernel text has an alias mapping at a high address, known
1159 * here as "highmap".
1160 */
> 1161 return within_inclusive(pfn, highmap_start_pfn(), > 1162 highmap_end_pfn());
1163 }
1164
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
kbuild test robot
build botRe: [PATCH 2/2] x86, pti: fix boot warning from Global-bit setting
In reply to Dave HansenThank you for the patch! Yet something to improve:
Hi Dave,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on tip/x86/core]
[also build test ERROR on v4.17-rc1 next-20180418]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Dave-Hansen/x86-pti-fix-boot-problems-from-Global-bit-setting/20180418-181719
config: i386-randconfig-a0-201815 (attached as .config)
compiler: gcc-4.9 (Debian 4.9.4-2) 4.9.4 reproduce:
# save the attached .config to linux build tree
make ARCH=i386 All errors (new ones prefixed by >>):
arch/x86/mm/pageattr.c: In function '__cpa_pfn_in_highmap':
arch/x86/mm/pageattr.c:1161:2: error: implicit declaration of function 'highmap_start_pfn' [-Werror=implicit-function-declaration]
return within_inclusive(pfn, highmap_start_pfn(),
^
>> arch/x86/mm/pageattr.c:1162:4: error: implicit declaration of function 'highmap_end_pfn' [-Werror=implicit-function-declaration]
highmap_end_pfn());
^cc1: some warnings being treated as errors
vim +/highmap_end_pfn +1162 arch/x86/mm/pageattr.c
1154
1155 bool __cpa_pfn_in_highmap(unsigned long pfn)
1156 {
1157 /*
1158 * Kernel text has an alias mapping at a high address, known
1159 * here as "highmap".
1160 */
> 1161 return within_inclusive(pfn, highmap_start_pfn(), > 1162 highmap_end_pfn());
1163 }
1164
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
Re: [PATCH 2/2] x86, pti: fix boot warning from Global-bit setting
In reply to Dave HansenQuoted 11 lines · Dave Hansen
These are _very_ lightly tested. I'm throwing them out there for folks are looking for a fix.
---
From: Dave Hansen <[email protected]>
pageattr.cis not friendly when it encounters empty (zero) PTEs. The kernel linear map is exempt from these checks, but kernel text is not. This patch adds the code to also exempt kernel text from these checks.
Bah. Changelogs should tell the WHY and not the WHAT
Quoted 2 lines
The proximate cause of these warnings was most likely an
__initarea that spanned a 2MB page boundary that resulted in a "zero" PMD.
This doesn't make any sense at all.
Thanks,
tglx
Dave Hansen
maintainerRe: [PATCH 2/2] x86, pti: fix boot warning from Global-bit setting
Quoted 8 lines · Thomas Gleixner
Quoted 3 lines
pageattr.cis not friendly when it encounters empty (zero) PTEs. The kernel linear map is exempt from these checks, but kernel text is not. This patch adds the code to also exempt kernel text from these checks.Bah. Changelogs should tell the WHY and not the WHAT
Quoted 2 lines
The proximate cause of these warnings was most likely an
__initarea that spanned a 2MB page boundary that resulted in a "zero" PMD.This doesn't make any sense at all.
I've rewritten these changelogs and added some more fixes for this set. I'll be sending it shortly.