2018-04-17 21:18:22

by Dave Hansen

[permalink] [raw]
Subject: [PATCH 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.

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]>
Cc: [email protected]
---

b/arch/x86/mm/pageattr.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff -puN arch/x86/mm/pageattr.c~pti-glb-boot-problem-fix arch/x86/mm/pageattr.c
--- a/arch/x86/mm/pageattr.c~pti-glb-boot-problem-fix 2018-04-17 14:10:13.553395577 -0700
+++ b/arch/x86/mm/pageattr.c 2018-04-17 14:10:13.559395577 -0700
@@ -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 lon
unsigned 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);

_


2018-04-17 21:19:33

by Dave Hansen

[permalink] [raw]
Subject: [PATCH 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.

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]>
Cc: [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-inpageattr arch/x86/mm/pageattr.c
--- a/arch/x86/mm/pageattr.c~pti-glb-warning-inpageattr 2018-04-17 14:10:22.695395554 -0700
+++ b/arch/x86/mm/pageattr.c 2018-04-17 14:10:22.721395554 -0700
@@ -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;
_

2018-04-17 21:58:31

by Mariusz Ceier

[permalink] [raw]
Subject: Re: [PATCH 2/2] x86, pti: fix boot warning from Global-bit setting

On 17 April 2018 at 23:13, Dave Hansen <[email protected]> wrote:
>
> 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.
>
> 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]>
> Cc: [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-inpageattr arch/x86/mm/pageattr.c
> --- a/arch/x86/mm/pageattr.c~pti-glb-warning-inpageattr 2018-04-17 14:10:22.695395554 -0700
> +++ b/arch/x86/mm/pageattr.c 2018-04-17 14:10:22.721395554 -0700
> @@ -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;
> _


I confirm that these 2 patches fix the BUG for me in kernel 4.17.0-rc1.

Thanks

2018-04-18 11:08:00

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH 2/2] x86, pti: fix boot warning from Global-bit setting

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_pfn
cc1: 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


Attachments:
(No filename) (1.77 kB)
.config.gz (27.46 kB)
Download all attachments

2018-04-18 12:27:54

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH 2/2] x86, pti: fix boot warning from Global-bit setting

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


Attachments:
(No filename) (1.60 kB)
.config.gz (30.25 kB)
Download all attachments

2018-04-20 10:18:22

by Thomas Gleixner

[permalink] [raw]
Subject: Re: [PATCH 2/2] x86, pti: fix boot warning from Global-bit setting

On Tue, 17 Apr 2018, Dave Hansen wrote:

>
> 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.

Bah. Changelogs should tell the WHY and not the WHAT

> The proximate cause of these warnings was most likely an __init area
> that spanned a 2MB page boundary that resulted in a "zero" PMD.

This doesn't make any sense at all.

Thanks,

tglx

2018-04-20 19:48:48

by Dave Hansen

[permalink] [raw]
Subject: Re: [PATCH 2/2] x86, pti: fix boot warning from Global-bit setting

On 04/20/2018 03:16 AM, Thomas Gleixner wrote:
>> 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.
> Bah. Changelogs should tell the WHY and not the WHAT
>
>> The proximate cause of these warnings was most likely an __init area
>> 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.