Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1727985 > unrolled thread

[PATCH v2 RESEND 0/2] x86/mm/KASLR: Do not adapt the size of the direct mapping section for SGI UV system

Started byBaoquan He <bhe@redhat.com>
First post2017-09-07 09:50 +0200
Last post2017-09-07 09:50 +0200
Articles 3 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [PATCH v2 RESEND 0/2] x86/mm/KASLR: Do not adapt the size of the direct mapping section for SGI UV system Baoquan He <bhe@redhat.com> - 2017-09-07 09:50 +0200
    [PATCH v2 RESEND 2/2] x86/mm/KASLR: Do not adapt the size of the direct mapping section for SGI UV system Baoquan He <bhe@redhat.com> - 2017-09-07 09:50 +0200
    [PATCH v2 RESEND 1/2] x86/UV: Introduce a helper function to check UV system at earlier stage Baoquan He <bhe@redhat.com> - 2017-09-07 09:50 +0200

#1727985 — [PATCH v2 RESEND 0/2] x86/mm/KASLR: Do not adapt the size of the direct mapping section for SGI UV system

FromBaoquan He <bhe@redhat.com>
Date2017-09-07 09:50 +0200
Subject[PATCH v2 RESEND 0/2] x86/mm/KASLR: Do not adapt the size of the direct mapping section for SGI UV system
Message-ID<umZJw-5lZ-13@gated-at.bofh.it>
This is v2 post RESEND. Add Mike's Acked-by to patch 2/2 as he suggested
in private mail. And update patches log slightly.

This patchset is trying to fix a bug that SGI UV system casually hang
during boot with KASLR enabled. The root cause is that mm KASLR adapts
size of the direct mapping section only based on the system RAM size.
Then later when map SGI UV MMIOH region into the direct mapping during
rest_init() invocation, it might go beyond of the directing mapping
section and step into VMALLOC or VMEMMAP area, then BUG_ON triggered.

The fix is adding a helper function is_early_uv_system to check UV system
earlier, then call the helper function in kernel_randomize_memory() to
check if it's a SGI UV system, if yes, we keep the size of direct mapping
section to be 64TB just as nokslr.

With this fix, SGI UV system can have 64TB direct mapping size always,
and the starting address of direct mapping/vmalloc/vmemmap and the padding
between them can still be randomized to enhance the system security.

v1->v2:
    1. Mike suggested making is_early_uv_system() an inline function and be
    put in include/asm/uv/uv.h so that they can adjust them easier in the
    future.

    2. Split the v1 code into uv part and mm KASLR part as Mike suggested.

Baoquan He (2):
  x86/UV: Introduce a helper function to check UV system at earlier
    stage
  x86/mm/KASLR: Do not adapt the size of the direct mapping section for
    SGI UV system

 arch/x86/include/asm/uv/uv.h | 6 ++++++
 arch/x86/mm/kaslr.c          | 3 ++-
 2 files changed, 8 insertions(+), 1 deletion(-)

-- 
2.5.5

[toc] | [next] | [standalone]


#1727986 — [PATCH v2 RESEND 2/2] x86/mm/KASLR: Do not adapt the size of the direct mapping section for SGI UV system

FromBaoquan He <bhe@redhat.com>
Date2017-09-07 09:50 +0200
Subject[PATCH v2 RESEND 2/2] x86/mm/KASLR: Do not adapt the size of the direct mapping section for SGI UV system
Message-ID<umZJx-5lZ-19@gated-at.bofh.it>
In reply to#1727985
On SGI UV system, kernel often hangs when KASLR is enabled. Disabling
KASLR makes kernel work well.

The back trace is:

kernel BUG at arch/x86/mm/init_64.c:311!
invalid opcode: 0000 [#1] SMP
[...]
RIP: 0010:__init_extra_mapping+0x188/0x196
[...]
Call Trace:
 init_extra_mapping_uc+0x13/0x15
 map_high+0x67/0x75
 map_mmioh_high_uv3+0x20a/0x219
 uv_system_init_hub+0x12d9/0x1496
 uv_system_init+0x27/0x29
 native_smp_prepare_cpus+0x28d/0x2d8
 kernel_init_freeable+0xdd/0x253
 ? rest_init+0x80/0x80
 kernel_init+0xe/0x110
 ret_from_fork+0x2c/0x40

This is because the SGI UV system need map its MMIOH region to the direct
mapping section, and the mapping happens in rest_init() which is much
later than the calling of kernel_randomize_memory() to do mm KASLR. So
mm KASLR can't count in the size of the MMIOH region when caculate the
needed size of address space for the direct mapping section.

When KASLR is disabled, there are 64TB address space for both system RAM
and the MMIOH regions to share. When KASLR is enabled, the current code
of mm KASLR only reserves the actual size of system RAM plus extra 10TB
for the direct mapping. Thus later the MMIOH mapping could go beyond
the upper bound of the direct mapping to step into VMALLOC or VMEMMAP area.
Then BUG_ON() in __init_extra_mapping() will be triggered.

E.g on the SGI UV3 machine where this bug is reported , there are two MMIOH
regions:

[    1.519001] UV: Map MMIOH0_HI 0xffc00000000 - 0x100000000000
[    1.523001] UV: Map MMIOH1_HI 0x100000000000 - 0x200000000000

They are [16TB-16G, 16TB) and [16TB, 32TB). On this machine, 512G RAM are
spread out to 1TB regions. Then above two SGI MMIOH regions also will be
mapped into the direct mapping section.

To fix it, we need check if it's SGI UV system by calling is_early_uv_system()
in kernel_randomize_memory(). If yes, do not adapt the size of the direct
mapping section, just keep it as 64TB.

Signed-off-by: Baoquan He <bhe@redhat.com>
Reviewed-by: Thomas Garnier <thgarnie@google.com>
Acked-by: Mike Travis <travis@sgi.com> 
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
Cc: Thomas Garnier <thgarnie@google.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
---
 arch/x86/mm/kaslr.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/x86/mm/kaslr.c b/arch/x86/mm/kaslr.c
index af599167fe3c..4d68c08df82d 100644
--- a/arch/x86/mm/kaslr.c
+++ b/arch/x86/mm/kaslr.c
@@ -27,6 +27,7 @@
 #include <asm/pgtable.h>
 #include <asm/setup.h>
 #include <asm/kaslr.h>
+#include <asm/uv/uv.h>
 
 #include "mm_internal.h"
 
@@ -123,7 +124,7 @@ void __init kernel_randomize_memory(void)
 		CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING;
 
 	/* Adapt phyiscal memory region size based on available memory */
-	if (memory_tb < kaslr_regions[0].size_tb)
+	if (memory_tb < kaslr_regions[0].size_tb && !is_early_uv_system())
 		kaslr_regions[0].size_tb = memory_tb;
 
 	/* Calculate entropy available between regions */
-- 
2.5.5

[toc] | [prev] | [next] | [standalone]


#1727992 — [PATCH v2 RESEND 1/2] x86/UV: Introduce a helper function to check UV system at earlier stage

FromBaoquan He <bhe@redhat.com>
Date2017-09-07 09:50 +0200
Subject[PATCH v2 RESEND 1/2] x86/UV: Introduce a helper function to check UV system at earlier stage
Message-ID<umZJy-5lZ-37@gated-at.bofh.it>
In reply to#1727985
The BIOS on SGI UV system will report a UV system table which describes
specific firmware capabilities available to the Linux kernel at runtime.
This UV system table only exists on SGI UV system. And it's detected
in efi_init() which is at very early stage.

So introduce a new helper function is_early_uv_system() to identify if
a system is UV system. Later we will use it to check if the running
system is UV system in mm KASLR code.

Signed-off-by: Baoquan He <bhe@redhat.com>
Acked-by: Mike Travis <travis@sgi.com>
---
 arch/x86/include/asm/uv/uv.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/x86/include/asm/uv/uv.h b/arch/x86/include/asm/uv/uv.h
index b5a32231abd8..93d7ad8763ba 100644
--- a/arch/x86/include/asm/uv/uv.h
+++ b/arch/x86/include/asm/uv/uv.h
@@ -18,6 +18,11 @@ extern void uv_nmi_init(void);
 extern void uv_system_init(void);
 extern const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
 						 const struct flush_tlb_info *info);
+#include <linux/efi.h>
+static inline int is_early_uv_system(void)
+{
+	return !((efi.uv_systab == EFI_INVALID_TABLE_ADDR) || !efi.uv_systab);
+}
 
 #else	/* X86_UV */
 
@@ -30,6 +35,7 @@ static inline const struct cpumask *
 uv_flush_tlb_others(const struct cpumask *cpumask,
 		    const struct flush_tlb_info *info)
 { return cpumask; }
+static inline int is_early_uv_system(void)	{ return 0; }
 
 #endif	/* X86_UV */
 
-- 
2.5.5

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web