All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size
@ 2017-02-16 21:54 ` Thomas Garnier
  0 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-16 21:54 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H . Peter Anvin, Jonathan Corbet,
	Thomas Garnier, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He Chen, Luis R . Rodriguez, Stanislaw Gruszka,
	Arnd Bergmann, Peter Zijlstra, Dave Hansen, Vitaly Kuznetsov,
	Paul Gortmaker, Josh Poimboeuf, Tim Chen, Andi Kleen, Jiri Olsa,
	Michael Ellerman, Joerg Roedel, Paolo Bonzini,
	Radim Krčmář,
	Andy Lutomirski
  Cc: x86, linux-kernel, linux-doc, linux-pm, linux-efi, xen-devel,
	lguest, kvm, kernel-hardening

This patch aligns MODULES_END to the beginning of the Fixmap section.
It optimizes the space available for both sections. The address is
pre-computed based on the number of pages required by the Fixmap
section.

It will allow GDT remapping in the Fixmap section. The current
MODULES_END static address does not provide enough space for the kernel
to support a large number of processors.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170213
---
 Documentation/x86/x86_64/mm.txt         | 5 ++++-
 arch/x86/include/asm/pgtable_64_types.h | 3 ++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/Documentation/x86/x86_64/mm.txt b/Documentation/x86/x86_64/mm.txt
index 5724092db811..ee3f9c30957c 100644
--- a/Documentation/x86/x86_64/mm.txt
+++ b/Documentation/x86/x86_64/mm.txt
@@ -19,7 +19,7 @@ ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks
 ffffffef00000000 - fffffffeffffffff (=64 GB) EFI region mapping space
 ... unused hole ...
 ffffffff80000000 - ffffffff9fffffff (=512 MB)  kernel text mapping, from phys 0
-ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space
+ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space (variable)
 ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls
 ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole
 
@@ -39,6 +39,9 @@ memory window (this size is arbitrary, it can be raised later if needed).
 The mappings are not part of any other kernel PGD and are only available
 during EFI runtime calls.
 
+The module mapping space size changes based on the CONFIG requirements for the
+following fixmap section.
+
 Note that if CONFIG_RANDOMIZE_MEMORY is enabled, the direct mapping of all
 physical memory, vmalloc/ioremap space and virtual memory map are randomized.
 Their order is preserved but their base will be offset early at boot time.
diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h
index 3a264200c62f..bb05e21cf3c7 100644
--- a/arch/x86/include/asm/pgtable_64_types.h
+++ b/arch/x86/include/asm/pgtable_64_types.h
@@ -67,7 +67,8 @@ typedef struct { pteval_t pte; } pte_t;
 #endif /* CONFIG_RANDOMIZE_MEMORY */
 #define VMALLOC_END	(VMALLOC_START + _AC((VMALLOC_SIZE_TB << 40) - 1, UL))
 #define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
-#define MODULES_END      _AC(0xffffffffff000000, UL)
+/* The module sections ends with the start of the fixmap */
+#define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
 #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
 #define ESPFIX_PGD_ENTRY _AC(-2, UL)
 #define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)
-- 
2.11.0.483.g087da7b7c-goog

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size
@ 2017-02-16 21:54 ` Thomas Garnier
  0 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-16 21:54 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H . Peter Anvin, Jonathan Corbet,
	Thomas Garnier, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He
  Cc: x86, linux-kernel, linux-doc, linux-pm, linux-efi, xen-devel,
	lguest, kvm, kernel-hardening

This patch aligns MODULES_END to the beginning of the Fixmap section.
It optimizes the space available for both sections. The address is
pre-computed based on the number of pages required by the Fixmap
section.

It will allow GDT remapping in the Fixmap section. The current
MODULES_END static address does not provide enough space for the kernel
to support a large number of processors.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170213
---
 Documentation/x86/x86_64/mm.txt         | 5 ++++-
 arch/x86/include/asm/pgtable_64_types.h | 3 ++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/Documentation/x86/x86_64/mm.txt b/Documentation/x86/x86_64/mm.txt
index 5724092db811..ee3f9c30957c 100644
--- a/Documentation/x86/x86_64/mm.txt
+++ b/Documentation/x86/x86_64/mm.txt
@@ -19,7 +19,7 @@ ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks
 ffffffef00000000 - fffffffeffffffff (=64 GB) EFI region mapping space
 ... unused hole ...
 ffffffff80000000 - ffffffff9fffffff (=512 MB)  kernel text mapping, from phys 0
-ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space
+ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space (variable)
 ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls
 ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole
 
@@ -39,6 +39,9 @@ memory window (this size is arbitrary, it can be raised later if needed).
 The mappings are not part of any other kernel PGD and are only available
 during EFI runtime calls.
 
+The module mapping space size changes based on the CONFIG requirements for the
+following fixmap section.
+
 Note that if CONFIG_RANDOMIZE_MEMORY is enabled, the direct mapping of all
 physical memory, vmalloc/ioremap space and virtual memory map are randomized.
 Their order is preserved but their base will be offset early at boot time.
diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h
index 3a264200c62f..bb05e21cf3c7 100644
--- a/arch/x86/include/asm/pgtable_64_types.h
+++ b/arch/x86/include/asm/pgtable_64_types.h
@@ -67,7 +67,8 @@ typedef struct { pteval_t pte; } pte_t;
 #endif /* CONFIG_RANDOMIZE_MEMORY */
 #define VMALLOC_END	(VMALLOC_START + _AC((VMALLOC_SIZE_TB << 40) - 1, UL))
 #define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
-#define MODULES_END      _AC(0xffffffffff000000, UL)
+/* The module sections ends with the start of the fixmap */
+#define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
 #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
 #define ESPFIX_PGD_ENTRY _AC(-2, UL)
 #define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)
-- 
2.11.0.483.g087da7b7c-goog

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size
@ 2017-02-16 21:54 ` Thomas Garnier
  0 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-16 21:54 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H . Peter Anvin, Jonathan Corbet,
	Thomas Garnier, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He
  Cc: x86, linux-kernel, linux-doc, linux-pm, linux-efi, xen-devel,
	lguest, kvm, kernel-hardening

This patch aligns MODULES_END to the beginning of the Fixmap section.
It optimizes the space available for both sections. The address is
pre-computed based on the number of pages required by the Fixmap
section.

It will allow GDT remapping in the Fixmap section. The current
MODULES_END static address does not provide enough space for the kernel
to support a large number of processors.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170213
---
 Documentation/x86/x86_64/mm.txt         | 5 ++++-
 arch/x86/include/asm/pgtable_64_types.h | 3 ++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/Documentation/x86/x86_64/mm.txt b/Documentation/x86/x86_64/mm.txt
index 5724092db811..ee3f9c30957c 100644
--- a/Documentation/x86/x86_64/mm.txt
+++ b/Documentation/x86/x86_64/mm.txt
@@ -19,7 +19,7 @@ ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks
 ffffffef00000000 - fffffffeffffffff (=64 GB) EFI region mapping space
 ... unused hole ...
 ffffffff80000000 - ffffffff9fffffff (=512 MB)  kernel text mapping, from phys 0
-ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space
+ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space (variable)
 ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls
 ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole
 
@@ -39,6 +39,9 @@ memory window (this size is arbitrary, it can be raised later if needed).
 The mappings are not part of any other kernel PGD and are only available
 during EFI runtime calls.
 
+The module mapping space size changes based on the CONFIG requirements for the
+following fixmap section.
+
 Note that if CONFIG_RANDOMIZE_MEMORY is enabled, the direct mapping of all
 physical memory, vmalloc/ioremap space and virtual memory map are randomized.
 Their order is preserved but their base will be offset early at boot time.
diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h
index 3a264200c62f..bb05e21cf3c7 100644
--- a/arch/x86/include/asm/pgtable_64_types.h
+++ b/arch/x86/include/asm/pgtable_64_types.h
@@ -67,7 +67,8 @@ typedef struct { pteval_t pte; } pte_t;
 #endif /* CONFIG_RANDOMIZE_MEMORY */
 #define VMALLOC_END	(VMALLOC_START + _AC((VMALLOC_SIZE_TB << 40) - 1, UL))
 #define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
-#define MODULES_END      _AC(0xffffffffff000000, UL)
+/* The module sections ends with the start of the fixmap */
+#define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
 #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
 #define ESPFIX_PGD_ENTRY _AC(-2, UL)
 #define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)
-- 
2.11.0.483.g087da7b7c-goog

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [kernel-hardening] [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size
@ 2017-02-16 21:54 ` Thomas Garnier
  0 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-16 21:54 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H . Peter Anvin, Jonathan Corbet,
	Thomas Garnier, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He Chen, Luis R . Rodriguez, Stanislaw Gruszka,
	Arnd Bergmann, Peter Zijlstra, Dave Hansen, Vitaly Kuznetsov,
	Paul Gortmaker, Josh Poimboeuf, Tim Chen, Andi Kleen, Jiri Olsa,
	Michael Ellerman, Joerg Roedel, Paolo Bonzini,
	Radim Krčmář,
	Andy Lutomirski
  Cc: x86, linux-kernel, linux-doc, linux-pm, linux-efi, xen-devel,
	lguest, kvm, kernel-hardening

This patch aligns MODULES_END to the beginning of the Fixmap section.
It optimizes the space available for both sections. The address is
pre-computed based on the number of pages required by the Fixmap
section.

It will allow GDT remapping in the Fixmap section. The current
MODULES_END static address does not provide enough space for the kernel
to support a large number of processors.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170213
---
 Documentation/x86/x86_64/mm.txt         | 5 ++++-
 arch/x86/include/asm/pgtable_64_types.h | 3 ++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/Documentation/x86/x86_64/mm.txt b/Documentation/x86/x86_64/mm.txt
index 5724092db811..ee3f9c30957c 100644
--- a/Documentation/x86/x86_64/mm.txt
+++ b/Documentation/x86/x86_64/mm.txt
@@ -19,7 +19,7 @@ ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks
 ffffffef00000000 - fffffffeffffffff (=64 GB) EFI region mapping space
 ... unused hole ...
 ffffffff80000000 - ffffffff9fffffff (=512 MB)  kernel text mapping, from phys 0
-ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space
+ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space (variable)
 ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls
 ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole
 
@@ -39,6 +39,9 @@ memory window (this size is arbitrary, it can be raised later if needed).
 The mappings are not part of any other kernel PGD and are only available
 during EFI runtime calls.
 
+The module mapping space size changes based on the CONFIG requirements for the
+following fixmap section.
+
 Note that if CONFIG_RANDOMIZE_MEMORY is enabled, the direct mapping of all
 physical memory, vmalloc/ioremap space and virtual memory map are randomized.
 Their order is preserved but their base will be offset early at boot time.
diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h
index 3a264200c62f..bb05e21cf3c7 100644
--- a/arch/x86/include/asm/pgtable_64_types.h
+++ b/arch/x86/include/asm/pgtable_64_types.h
@@ -67,7 +67,8 @@ typedef struct { pteval_t pte; } pte_t;
 #endif /* CONFIG_RANDOMIZE_MEMORY */
 #define VMALLOC_END	(VMALLOC_START + _AC((VMALLOC_SIZE_TB << 40) - 1, UL))
 #define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
-#define MODULES_END      _AC(0xffffffffff000000, UL)
+/* The module sections ends with the start of the fixmap */
+#define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
 #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
 #define ESPFIX_PGD_ENTRY _AC(-2, UL)
 #define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)
-- 
2.11.0.483.g087da7b7c-goog

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 2/4] x86: Remap GDT tables in the Fixmap section
  2017-02-16 21:54 ` Thomas Garnier
  (?)
  (?)
@ 2017-02-16 21:54   ` Thomas Garnier
  -1 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-16 21:54 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H . Peter Anvin, Jonathan Corbet,
	Thomas Garnier, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He Chen, Luis R . Rodriguez, Stanislaw Gruszka,
	Arnd Bergmann, Peter Zijlstra, Dave Hansen, Vitaly Kuznetsov,
	Paul Gortmaker, Josh Poimboeuf, Tim Chen, Andi Kleen, Jiri Olsa,
	Michael Ellerman, Joerg Roedel, Paolo Bonzini,
	Radim Krčmář,
	Andy Lutomirski
  Cc: x86, linux-kernel, linux-doc, linux-pm, linux-efi, xen-devel,
	lguest, kvm, kernel-hardening

Each processor holds a GDT in its per-cpu structure. The sgdt
instruction gives the base address of the current GDT. This address can
be used to bypass KASLR memory randomization. With another bug, an
attacker could target other per-cpu structures or deduce the base of
the main memory section (PAGE_OFFSET).

This patch relocates the GDT table for each processor inside the
Fixmap section. The space is reserved based on number of supported
processors.

For consistency, the remapping is done by default on 32 and 64-bit.

Each processor switches to its remapped GDT at the end of
initialization. For hibernation, the main processor returns with the
original GDT and switches back to the remapping at completion.

This patch was tested on both architectures. Hibernation and KVM were
both tested specially for their usage of the GDT.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170213
---
 arch/x86/entry/vdso/vma.c             |  2 +-
 arch/x86/include/asm/desc.h           | 33 +++++++++++++++++++++++++++++----
 arch/x86/include/asm/fixmap.h         |  4 ++++
 arch/x86/include/asm/processor.h      |  1 +
 arch/x86/include/asm/stackprotector.h |  2 +-
 arch/x86/kernel/acpi/sleep.c          |  2 +-
 arch/x86/kernel/apm_32.c              |  6 +++---
 arch/x86/kernel/cpu/common.c          | 26 ++++++++++++++++++++++++--
 arch/x86/kernel/setup_percpu.c        |  2 +-
 arch/x86/kernel/smpboot.c             |  2 +-
 arch/x86/platform/efi/efi_32.c        |  4 ++--
 arch/x86/power/cpu.c                  |  7 +++++--
 arch/x86/xen/enlighten.c              |  2 +-
 arch/x86/xen/smp.c                    |  2 +-
 drivers/lguest/x86/core.c             |  6 +++---
 drivers/pnp/pnpbios/bioscalls.c       | 10 +++++-----
 16 files changed, 83 insertions(+), 28 deletions(-)

diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
index 572cee3fccff..9c8bd4cfcc6e 100644
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -353,7 +353,7 @@ static void vgetcpu_cpu_init(void *arg)
 	d.p = 1;		/* Present */
 	d.d = 1;		/* 32-bit */
 
-	write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_PER_CPU, &d, DESCTYPE_S);
+	write_gdt_entry(get_cpu_gdt_rw(cpu), GDT_ENTRY_PER_CPU, &d, DESCTYPE_S);
 }
 
 static int vgetcpu_online(unsigned int cpu)
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
index 12080d87da3b..5d4ba1311737 100644
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -4,6 +4,7 @@
 #include <asm/desc_defs.h>
 #include <asm/ldt.h>
 #include <asm/mmu.h>
+#include <asm/fixmap.h>
 
 #include <linux/smp.h>
 #include <linux/percpu.h>
@@ -45,11 +46,35 @@ struct gdt_page {
 
 DECLARE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page);
 
-static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
+/* Provide the original GDT */
+static inline struct desc_struct *get_cpu_gdt_rw(unsigned int cpu)
 {
 	return per_cpu(gdt_page, cpu).gdt;
 }
 
+static inline unsigned long get_cpu_gdt_rw_vaddr(unsigned int cpu)
+{
+	return (unsigned long)get_cpu_gdt_rw(cpu);
+}
+
+/* Get the fixmap index for a specific processor */
+static inline unsigned int get_cpu_gdt_ro_index(int cpu)
+{
+	return FIX_GDT_REMAP_BEGIN + cpu;
+}
+
+/* Provide the fixmap address of the remapped GDT */
+static inline struct desc_struct *get_cpu_gdt_ro(int cpu)
+{
+	unsigned int idx = get_cpu_gdt_ro_index(cpu);
+	return (struct desc_struct *)__fix_to_virt(idx);
+}
+
+static inline unsigned long get_cpu_gdt_ro_vaddr(int cpu)
+{
+	return (unsigned long)get_cpu_gdt_ro(cpu);
+}
+
 #ifdef CONFIG_X86_64
 
 static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func,
@@ -174,7 +199,7 @@ static inline void set_tssldt_descriptor(void *d, unsigned long addr, unsigned t
 
 static inline void __set_tss_desc(unsigned cpu, unsigned int entry, void *addr)
 {
-	struct desc_struct *d = get_cpu_gdt_table(cpu);
+	struct desc_struct *d = get_cpu_gdt_rw(cpu);
 	tss_desc tss;
 
 	/*
@@ -202,7 +227,7 @@ static inline void native_set_ldt(const void *addr, unsigned int entries)
 
 		set_tssldt_descriptor(&ldt, (unsigned long)addr, DESC_LDT,
 				      entries * LDT_ENTRY_SIZE - 1);
-		write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT,
+		write_gdt_entry(get_cpu_gdt_rw(cpu), GDT_ENTRY_LDT,
 				&ldt, DESC_LDT);
 		asm volatile("lldt %w0"::"q" (GDT_ENTRY_LDT*8));
 	}
@@ -244,7 +269,7 @@ static inline unsigned long native_store_tr(void)
 
 static inline void native_load_tls(struct thread_struct *t, unsigned int cpu)
 {
-	struct desc_struct *gdt = get_cpu_gdt_table(cpu);
+	struct desc_struct *gdt = get_cpu_gdt_rw(cpu);
 	unsigned int i;
 
 	for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h
index 8554f960e21b..b65155cc3760 100644
--- a/arch/x86/include/asm/fixmap.h
+++ b/arch/x86/include/asm/fixmap.h
@@ -100,6 +100,10 @@ enum fixed_addresses {
 #ifdef	CONFIG_X86_INTEL_MID
 	FIX_LNW_VRTC,
 #endif
+	/* Fixmap entries to remap the GDTs, one per processor. */
+	FIX_GDT_REMAP_BEGIN,
+	FIX_GDT_REMAP_END = FIX_GDT_REMAP_BEGIN + NR_CPUS - 1,
+
 	__end_of_permanent_fixed_addresses,
 
 	/*
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index e6cfe7ba2d65..c441d1f7e275 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -706,6 +706,7 @@ extern struct desc_ptr		early_gdt_descr;
 
 extern void cpu_set_gdt(int);
 extern void switch_to_new_gdt(int);
+extern void load_fixmap_gdt(int);
 extern void load_percpu_segment(int);
 extern void cpu_init(void);
 
diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h
index 58505f01962f..dcbd9bcce714 100644
--- a/arch/x86/include/asm/stackprotector.h
+++ b/arch/x86/include/asm/stackprotector.h
@@ -87,7 +87,7 @@ static inline void setup_stack_canary_segment(int cpu)
 {
 #ifdef CONFIG_X86_32
 	unsigned long canary = (unsigned long)&per_cpu(stack_canary, cpu);
-	struct desc_struct *gdt_table = get_cpu_gdt_table(cpu);
+	struct desc_struct *gdt_table = get_cpu_gdt_rw(cpu);
 	struct desc_struct desc;
 
 	desc = gdt_table[GDT_ENTRY_STACK_CANARY];
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
index 48587335ede8..ed014814ea35 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -101,7 +101,7 @@ int x86_acpi_suspend_lowlevel(void)
 #ifdef CONFIG_SMP
 	initial_stack = (unsigned long)temp_stack + sizeof(temp_stack);
 	early_gdt_descr.address =
-			(unsigned long)get_cpu_gdt_table(smp_processor_id());
+			(unsigned long)get_cpu_gdt_rw(smp_processor_id());
 	initial_gs = per_cpu_offset(smp_processor_id());
 #endif
 	initial_code = (unsigned long)wakeup_long64;
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 45d44c173cf9..dc4e89d93a10 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -608,7 +608,7 @@ static long __apm_bios_call(void *_call)
 
 	cpu = get_cpu();
 	BUG_ON(cpu != 0);
-	gdt = get_cpu_gdt_table(cpu);
+	gdt = get_cpu_gdt_rw(cpu);
 	save_desc_40 = gdt[0x40 / 8];
 	gdt[0x40 / 8] = bad_bios_desc;
 
@@ -684,7 +684,7 @@ static long __apm_bios_call_simple(void *_call)
 
 	cpu = get_cpu();
 	BUG_ON(cpu != 0);
-	gdt = get_cpu_gdt_table(cpu);
+	gdt = get_cpu_gdt_rw(cpu);
 	save_desc_40 = gdt[0x40 / 8];
 	gdt[0x40 / 8] = bad_bios_desc;
 
@@ -2351,7 +2351,7 @@ static int __init apm_init(void)
 	 * Note we only set APM segments on CPU zero, since we pin the APM
 	 * code to that CPU.
 	 */
-	gdt = get_cpu_gdt_table(0);
+	gdt = get_cpu_gdt_rw(0);
 	set_desc_base(&gdt[APM_CS >> 3],
 		 (unsigned long)__va((unsigned long)apm_info.bios.cseg << 4));
 	set_desc_base(&gdt[APM_CS_16 >> 3],
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 1a4ee7082ad7..2853a42ded2d 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -444,6 +444,23 @@ void load_percpu_segment(int cpu)
 	load_stack_canary_segment();
 }
 
+/* Setup the fixmap mapping only once per-processor */
+static inline void setup_fixmap_gdt(int cpu)
+{
+	__set_fixmap(get_cpu_gdt_ro_index(cpu),
+		     __pa(get_cpu_gdt_rw(cpu)), PAGE_KERNEL);
+}
+
+/* Load a fixmap remapping of the per-cpu GDT */
+void load_fixmap_gdt(int cpu)
+{
+	struct desc_ptr gdt_descr;
+
+	gdt_descr.address = (long)get_cpu_gdt_ro(cpu);
+	gdt_descr.size = GDT_SIZE - 1;
+	load_gdt(&gdt_descr);
+}
+
 /*
  * Current gdt points %fs at the "master" per-cpu area: after this,
  * it's on the real one.
@@ -452,11 +469,10 @@ void switch_to_new_gdt(int cpu)
 {
 	struct desc_ptr gdt_descr;
 
-	gdt_descr.address = (long)get_cpu_gdt_table(cpu);
+	gdt_descr.address = (long)get_cpu_gdt_rw(cpu);
 	gdt_descr.size = GDT_SIZE - 1;
 	load_gdt(&gdt_descr);
 	/* Reload the per-cpu base */
-
 	load_percpu_segment(cpu);
 }
 
@@ -1524,6 +1540,9 @@ void cpu_init(void)
 
 	if (is_uv_system())
 		uv_cpu_init();
+
+	setup_fixmap_gdt(cpu);
+	load_fixmap_gdt(cpu);
 }
 
 #else
@@ -1579,6 +1598,9 @@ void cpu_init(void)
 	dbg_restore_debug_regs();
 
 	fpu__init_cpu();
+
+	setup_fixmap_gdt(cpu);
+	load_fixmap_gdt(cpu);
 }
 #endif
 
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index 9820d6d977c6..11338b0b3ad2 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -160,7 +160,7 @@ static inline void setup_percpu_segment(int cpu)
 	pack_descriptor(&gdt, per_cpu_offset(cpu), 0xFFFFF,
 			0x2 | DESCTYPE_S, 0x8);
 	gdt.s = 1;
-	write_gdt_entry(get_cpu_gdt_table(cpu),
+	write_gdt_entry(get_cpu_gdt_rw(cpu),
 			GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S);
 #endif
 }
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 99b920d0e516..2e61b4b6957b 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -980,7 +980,7 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
 	unsigned long timeout;
 
 	idle->thread.sp = (unsigned long)task_pt_regs(idle);
-	early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
+	early_gdt_descr.address = (unsigned long)get_cpu_gdt_rw(cpu);
 	initial_code = (unsigned long)start_secondary;
 	initial_stack  = idle->thread.sp;
 
diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c
index cef39b097649..950071171436 100644
--- a/arch/x86/platform/efi/efi_32.c
+++ b/arch/x86/platform/efi/efi_32.c
@@ -68,7 +68,7 @@ pgd_t * __init efi_call_phys_prolog(void)
 	load_cr3(initial_page_table);
 	__flush_tlb_all();
 
-	gdt_descr.address = __pa(get_cpu_gdt_table(0));
+	gdt_descr.address = __pa(get_cpu_gdt_rw(0));
 	gdt_descr.size = GDT_SIZE - 1;
 	load_gdt(&gdt_descr);
 
@@ -79,7 +79,7 @@ void __init efi_call_phys_epilog(pgd_t *save_pgd)
 {
 	struct desc_ptr gdt_descr;
 
-	gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
+	gdt_descr.address = (unsigned long)get_cpu_gdt_rw(0);
 	gdt_descr.size = GDT_SIZE - 1;
 	load_gdt(&gdt_descr);
 
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
index 66ade16c7693..6b05a9219ea2 100644
--- a/arch/x86/power/cpu.c
+++ b/arch/x86/power/cpu.c
@@ -95,7 +95,7 @@ static void __save_processor_state(struct saved_context *ctxt)
 	 * 'pmode_gdt' in wakeup_start.
 	 */
 	ctxt->gdt_desc.size = GDT_SIZE - 1;
-	ctxt->gdt_desc.address = (unsigned long)get_cpu_gdt_table(smp_processor_id());
+	ctxt->gdt_desc.address = (unsigned long)get_cpu_gdt_rw(smp_processor_id());
 
 	store_tr(ctxt->tr);
 
@@ -162,7 +162,7 @@ static void fix_processor_context(void)
 	int cpu = smp_processor_id();
 	struct tss_struct *t = &per_cpu(cpu_tss, cpu);
 #ifdef CONFIG_X86_64
-	struct desc_struct *desc = get_cpu_gdt_table(cpu);
+	struct desc_struct *desc = get_cpu_gdt_rw(cpu);
 	tss_desc tss;
 #endif
 	set_tss_desc(cpu, t);	/*
@@ -183,6 +183,9 @@ static void fix_processor_context(void)
 	load_mm_ldt(current->active_mm);	/* This does lldt */
 
 	fpu__resume_cpu();
+
+	/* The processor is back on the direct GDT, load back the fixmap */
+	load_fixmap_gdt(cpu);
 }
 
 /**
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index ec1d5c46e58f..4951fcf95143 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -710,7 +710,7 @@ static void load_TLS_descriptor(struct thread_struct *t,
 
 	*shadow = t->tls_array[i];
 
-	gdt = get_cpu_gdt_table(cpu);
+	gdt = get_cpu_gdt_rw(cpu);
 	maddr = arbitrary_virt_to_machine(&gdt[GDT_ENTRY_TLS_MIN+i]);
 	mc = __xen_mc_entry(0);
 
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 0dee6f59ea82..6399bab936cd 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -391,7 +391,7 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
 	if (ctxt == NULL)
 		return -ENOMEM;
 
-	gdt = get_cpu_gdt_table(cpu);
+	gdt = get_cpu_gdt_rw(cpu);
 
 #ifdef CONFIG_X86_32
 	ctxt->user_regs.fs = __KERNEL_PERCPU;
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index d71f6323ac00..b4f79b923aea 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -504,7 +504,7 @@ void __init lguest_arch_host_init(void)
 		 * byte, not the size, hence the "-1").
 		 */
 		state->host_gdt_desc.size = GDT_SIZE-1;
-		state->host_gdt_desc.address = (long)get_cpu_gdt_table(i);
+		state->host_gdt_desc.address = (long)get_cpu_gdt_rw(i);
 
 		/*
 		 * All CPUs on the Host use the same Interrupt Descriptor
@@ -554,8 +554,8 @@ void __init lguest_arch_host_init(void)
 		 * The Host needs to be able to use the LGUEST segments on this
 		 * CPU, too, so put them in the Host GDT.
 		 */
-		get_cpu_gdt_table(i)[GDT_ENTRY_LGUEST_CS] = FULL_EXEC_SEGMENT;
-		get_cpu_gdt_table(i)[GDT_ENTRY_LGUEST_DS] = FULL_SEGMENT;
+		get_cpu_gdt_rw(i)[GDT_ENTRY_LGUEST_CS] = FULL_EXEC_SEGMENT;
+		get_cpu_gdt_rw(i)[GDT_ENTRY_LGUEST_DS] = FULL_SEGMENT;
 	}
 
 	/*
diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c
index 438d4c72c7b3..ff563db025b3 100644
--- a/drivers/pnp/pnpbios/bioscalls.c
+++ b/drivers/pnp/pnpbios/bioscalls.c
@@ -54,7 +54,7 @@ __asm__(".text			\n"
 
 #define Q2_SET_SEL(cpu, selname, address, size) \
 do { \
-	struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \
+	struct desc_struct *gdt = get_cpu_gdt_rw((cpu)); \
 	set_desc_base(&gdt[(selname) >> 3], (u32)(address)); \
 	set_desc_limit(&gdt[(selname) >> 3], (size) - 1); \
 } while(0)
@@ -95,8 +95,8 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3,
 		return PNP_FUNCTION_NOT_SUPPORTED;
 
 	cpu = get_cpu();
-	save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
-	get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
+	save_desc_40 = get_cpu_gdt_rw(cpu)[0x40 / 8];
+	get_cpu_gdt_rw(cpu)[0x40 / 8] = bad_bios_desc;
 
 	/* On some boxes IRQ's during PnP BIOS calls are deadly.  */
 	spin_lock_irqsave(&pnp_bios_lock, flags);
@@ -134,7 +134,7 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3,
 			     :"memory");
 	spin_unlock_irqrestore(&pnp_bios_lock, flags);
 
-	get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
+	get_cpu_gdt_rw(cpu)[0x40 / 8] = save_desc_40;
 	put_cpu();
 
 	/* If we get here and this is set then the PnP BIOS faulted on us. */
@@ -477,7 +477,7 @@ void pnpbios_calls_init(union pnp_bios_install_struct *header)
 	pnp_bios_callpoint.segment = PNP_CS16;
 
 	for_each_possible_cpu(i) {
-		struct desc_struct *gdt = get_cpu_gdt_table(i);
+		struct desc_struct *gdt = get_cpu_gdt_rw(i);
 		if (!gdt)
 			continue;
 		set_desc_base(&gdt[GDT_ENTRY_PNPBIOS_CS32],
-- 
2.11.0.483.g087da7b7c-goog

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 2/4] x86: Remap GDT tables in the Fixmap section
@ 2017-02-16 21:54   ` Thomas Garnier
  0 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-16 21:54 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H . Peter Anvin, Jonathan Corbet,
	Thomas Garnier, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He Chen, Luis R . Rodriguez, Stanislaw Gruszka
  Cc: x86, linux-kernel, linux-doc, linux-pm, linux-efi, xen-devel,
	lguest, kvm, kernel-hardening

Each processor holds a GDT in its per-cpu structure. The sgdt
instruction gives the base address of the current GDT. This address can
be used to bypass KASLR memory randomization. With another bug, an
attacker could target other per-cpu structures or deduce the base of
the main memory section (PAGE_OFFSET).

This patch relocates the GDT table for each processor inside the
Fixmap section. The space is reserved based on number of supported
processors.

For consistency, the remapping is done by default on 32 and 64-bit.

Each processor switches to its remapped GDT at the end of
initialization. For hibernation, the main processor returns with the
original GDT and switches back to the remapping at completion.

This patch was tested on both architectures. Hibernation and KVM were
both tested specially for their usage of the GDT.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170213
---
 arch/x86/entry/vdso/vma.c             |  2 +-
 arch/x86/include/asm/desc.h           | 33 +++++++++++++++++++++++++++++----
 arch/x86/include/asm/fixmap.h         |  4 ++++
 arch/x86/include/asm/processor.h      |  1 +
 arch/x86/include/asm/stackprotector.h |  2 +-
 arch/x86/kernel/acpi/sleep.c          |  2 +-
 arch/x86/kernel/apm_32.c              |  6 +++---
 arch/x86/kernel/cpu/common.c          | 26 ++++++++++++++++++++++++--
 arch/x86/kernel/setup_percpu.c        |  2 +-
 arch/x86/kernel/smpboot.c             |  2 +-
 arch/x86/platform/efi/efi_32.c        |  4 ++--
 arch/x86/power/cpu.c                  |  7 +++++--
 arch/x86/xen/enlighten.c              |  2 +-
 arch/x86/xen/smp.c                    |  2 +-
 drivers/lguest/x86/core.c             |  6 +++---
 drivers/pnp/pnpbios/bioscalls.c       | 10 +++++-----
 16 files changed, 83 insertions(+), 28 deletions(-)

diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
index 572cee3fccff..9c8bd4cfcc6e 100644
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -353,7 +353,7 @@ static void vgetcpu_cpu_init(void *arg)
 	d.p = 1;		/* Present */
 	d.d = 1;		/* 32-bit */
 
-	write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_PER_CPU, &d, DESCTYPE_S);
+	write_gdt_entry(get_cpu_gdt_rw(cpu), GDT_ENTRY_PER_CPU, &d, DESCTYPE_S);
 }
 
 static int vgetcpu_online(unsigned int cpu)
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
index 12080d87da3b..5d4ba1311737 100644
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -4,6 +4,7 @@
 #include <asm/desc_defs.h>
 #include <asm/ldt.h>
 #include <asm/mmu.h>
+#include <asm/fixmap.h>
 
 #include <linux/smp.h>
 #include <linux/percpu.h>
@@ -45,11 +46,35 @@ struct gdt_page {
 
 DECLARE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page);
 
-static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
+/* Provide the original GDT */
+static inline struct desc_struct *get_cpu_gdt_rw(unsigned int cpu)
 {
 	return per_cpu(gdt_page, cpu).gdt;
 }
 
+static inline unsigned long get_cpu_gdt_rw_vaddr(unsigned int cpu)
+{
+	return (unsigned long)get_cpu_gdt_rw(cpu);
+}
+
+/* Get the fixmap index for a specific processor */
+static inline unsigned int get_cpu_gdt_ro_index(int cpu)
+{
+	return FIX_GDT_REMAP_BEGIN + cpu;
+}
+
+/* Provide the fixmap address of the remapped GDT */
+static inline struct desc_struct *get_cpu_gdt_ro(int cpu)
+{
+	unsigned int idx = get_cpu_gdt_ro_index(cpu);
+	return (struct desc_struct *)__fix_to_virt(idx);
+}
+
+static inline unsigned long get_cpu_gdt_ro_vaddr(int cpu)
+{
+	return (unsigned long)get_cpu_gdt_ro(cpu);
+}
+
 #ifdef CONFIG_X86_64
 
 static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func,
@@ -174,7 +199,7 @@ static inline void set_tssldt_descriptor(void *d, unsigned long addr, unsigned t
 
 static inline void __set_tss_desc(unsigned cpu, unsigned int entry, void *addr)
 {
-	struct desc_struct *d = get_cpu_gdt_table(cpu);
+	struct desc_struct *d = get_cpu_gdt_rw(cpu);
 	tss_desc tss;
 
 	/*
@@ -202,7 +227,7 @@ static inline void native_set_ldt(const void *addr, unsigned int entries)
 
 		set_tssldt_descriptor(&ldt, (unsigned long)addr, DESC_LDT,
 				      entries * LDT_ENTRY_SIZE - 1);
-		write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT,
+		write_gdt_entry(get_cpu_gdt_rw(cpu), GDT_ENTRY_LDT,
 				&ldt, DESC_LDT);
 		asm volatile("lldt %w0"::"q" (GDT_ENTRY_LDT*8));
 	}
@@ -244,7 +269,7 @@ static inline unsigned long native_store_tr(void)
 
 static inline void native_load_tls(struct thread_struct *t, unsigned int cpu)
 {
-	struct desc_struct *gdt = get_cpu_gdt_table(cpu);
+	struct desc_struct *gdt = get_cpu_gdt_rw(cpu);
 	unsigned int i;
 
 	for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h
index 8554f960e21b..b65155cc3760 100644
--- a/arch/x86/include/asm/fixmap.h
+++ b/arch/x86/include/asm/fixmap.h
@@ -100,6 +100,10 @@ enum fixed_addresses {
 #ifdef	CONFIG_X86_INTEL_MID
 	FIX_LNW_VRTC,
 #endif
+	/* Fixmap entries to remap the GDTs, one per processor. */
+	FIX_GDT_REMAP_BEGIN,
+	FIX_GDT_REMAP_END = FIX_GDT_REMAP_BEGIN + NR_CPUS - 1,
+
 	__end_of_permanent_fixed_addresses,
 
 	/*
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index e6cfe7ba2d65..c441d1f7e275 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -706,6 +706,7 @@ extern struct desc_ptr		early_gdt_descr;
 
 extern void cpu_set_gdt(int);
 extern void switch_to_new_gdt(int);
+extern void load_fixmap_gdt(int);
 extern void load_percpu_segment(int);
 extern void cpu_init(void);
 
diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h
index 58505f01962f..dcbd9bcce714 100644
--- a/arch/x86/include/asm/stackprotector.h
+++ b/arch/x86/include/asm/stackprotector.h
@@ -87,7 +87,7 @@ static inline void setup_stack_canary_segment(int cpu)
 {
 #ifdef CONFIG_X86_32
 	unsigned long canary = (unsigned long)&per_cpu(stack_canary, cpu);
-	struct desc_struct *gdt_table = get_cpu_gdt_table(cpu);
+	struct desc_struct *gdt_table = get_cpu_gdt_rw(cpu);
 	struct desc_struct desc;
 
 	desc = gdt_table[GDT_ENTRY_STACK_CANARY];
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
index 48587335ede8..ed014814ea35 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -101,7 +101,7 @@ int x86_acpi_suspend_lowlevel(void)
 #ifdef CONFIG_SMP
 	initial_stack = (unsigned long)temp_stack + sizeof(temp_stack);
 	early_gdt_descr.address =
-			(unsigned long)get_cpu_gdt_table(smp_processor_id());
+			(unsigned long)get_cpu_gdt_rw(smp_processor_id());
 	initial_gs = per_cpu_offset(smp_processor_id());
 #endif
 	initial_code = (unsigned long)wakeup_long64;
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 45d44c173cf9..dc4e89d93a10 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -608,7 +608,7 @@ static long __apm_bios_call(void *_call)
 
 	cpu = get_cpu();
 	BUG_ON(cpu != 0);
-	gdt = get_cpu_gdt_table(cpu);
+	gdt = get_cpu_gdt_rw(cpu);
 	save_desc_40 = gdt[0x40 / 8];
 	gdt[0x40 / 8] = bad_bios_desc;
 
@@ -684,7 +684,7 @@ static long __apm_bios_call_simple(void *_call)
 
 	cpu = get_cpu();
 	BUG_ON(cpu != 0);
-	gdt = get_cpu_gdt_table(cpu);
+	gdt = get_cpu_gdt_rw(cpu);
 	save_desc_40 = gdt[0x40 / 8];
 	gdt[0x40 / 8] = bad_bios_desc;
 
@@ -2351,7 +2351,7 @@ static int __init apm_init(void)
 	 * Note we only set APM segments on CPU zero, since we pin the APM
 	 * code to that CPU.
 	 */
-	gdt = get_cpu_gdt_table(0);
+	gdt = get_cpu_gdt_rw(0);
 	set_desc_base(&gdt[APM_CS >> 3],
 		 (unsigned long)__va((unsigned long)apm_info.bios.cseg << 4));
 	set_desc_base(&gdt[APM_CS_16 >> 3],
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 1a4ee7082ad7..2853a42ded2d 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -444,6 +444,23 @@ void load_percpu_segment(int cpu)
 	load_stack_canary_segment();
 }
 
+/* Setup the fixmap mapping only once per-processor */
+static inline void setup_fixmap_gdt(int cpu)
+{
+	__set_fixmap(get_cpu_gdt_ro_index(cpu),
+		     __pa(get_cpu_gdt_rw(cpu)), PAGE_KERNEL);
+}
+
+/* Load a fixmap remapping of the per-cpu GDT */
+void load_fixmap_gdt(int cpu)
+{
+	struct desc_ptr gdt_descr;
+
+	gdt_descr.address = (long)get_cpu_gdt_ro(cpu);
+	gdt_descr.size = GDT_SIZE - 1;
+	load_gdt(&gdt_descr);
+}
+
 /*
  * Current gdt points %fs at the "master" per-cpu area: after this,
  * it's on the real one.
@@ -452,11 +469,10 @@ void switch_to_new_gdt(int cpu)
 {
 	struct desc_ptr gdt_descr;
 
-	gdt_descr.address = (long)get_cpu_gdt_table(cpu);
+	gdt_descr.address = (long)get_cpu_gdt_rw(cpu);
 	gdt_descr.size = GDT_SIZE - 1;
 	load_gdt(&gdt_descr);
 	/* Reload the per-cpu base */
-
 	load_percpu_segment(cpu);
 }
 
@@ -1524,6 +1540,9 @@ void cpu_init(void)
 
 	if (is_uv_system())
 		uv_cpu_init();
+
+	setup_fixmap_gdt(cpu);
+	load_fixmap_gdt(cpu);
 }
 
 #else
@@ -1579,6 +1598,9 @@ void cpu_init(void)
 	dbg_restore_debug_regs();
 
 	fpu__init_cpu();
+
+	setup_fixmap_gdt(cpu);
+	load_fixmap_gdt(cpu);
 }
 #endif
 
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index 9820d6d977c6..11338b0b3ad2 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -160,7 +160,7 @@ static inline void setup_percpu_segment(int cpu)
 	pack_descriptor(&gdt, per_cpu_offset(cpu), 0xFFFFF,
 			0x2 | DESCTYPE_S, 0x8);
 	gdt.s = 1;
-	write_gdt_entry(get_cpu_gdt_table(cpu),
+	write_gdt_entry(get_cpu_gdt_rw(cpu),
 			GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S);
 #endif
 }
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 99b920d0e516..2e61b4b6957b 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -980,7 +980,7 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
 	unsigned long timeout;
 
 	idle->thread.sp = (unsigned long)task_pt_regs(idle);
-	early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
+	early_gdt_descr.address = (unsigned long)get_cpu_gdt_rw(cpu);
 	initial_code = (unsigned long)start_secondary;
 	initial_stack  = idle->thread.sp;
 
diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c
index cef39b097649..950071171436 100644
--- a/arch/x86/platform/efi/efi_32.c
+++ b/arch/x86/platform/efi/efi_32.c
@@ -68,7 +68,7 @@ pgd_t * __init efi_call_phys_prolog(void)
 	load_cr3(initial_page_table);
 	__flush_tlb_all();
 
-	gdt_descr.address = __pa(get_cpu_gdt_table(0));
+	gdt_descr.address = __pa(get_cpu_gdt_rw(0));
 	gdt_descr.size = GDT_SIZE - 1;
 	load_gdt(&gdt_descr);
 
@@ -79,7 +79,7 @@ void __init efi_call_phys_epilog(pgd_t *save_pgd)
 {
 	struct desc_ptr gdt_descr;
 
-	gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
+	gdt_descr.address = (unsigned long)get_cpu_gdt_rw(0);
 	gdt_descr.size = GDT_SIZE - 1;
 	load_gdt(&gdt_descr);
 
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
index 66ade16c7693..6b05a9219ea2 100644
--- a/arch/x86/power/cpu.c
+++ b/arch/x86/power/cpu.c
@@ -95,7 +95,7 @@ static void __save_processor_state(struct saved_context *ctxt)
 	 * 'pmode_gdt' in wakeup_start.
 	 */
 	ctxt->gdt_desc.size = GDT_SIZE - 1;
-	ctxt->gdt_desc.address = (unsigned long)get_cpu_gdt_table(smp_processor_id());
+	ctxt->gdt_desc.address = (unsigned long)get_cpu_gdt_rw(smp_processor_id());
 
 	store_tr(ctxt->tr);
 
@@ -162,7 +162,7 @@ static void fix_processor_context(void)
 	int cpu = smp_processor_id();
 	struct tss_struct *t = &per_cpu(cpu_tss, cpu);
 #ifdef CONFIG_X86_64
-	struct desc_struct *desc = get_cpu_gdt_table(cpu);
+	struct desc_struct *desc = get_cpu_gdt_rw(cpu);
 	tss_desc tss;
 #endif
 	set_tss_desc(cpu, t);	/*
@@ -183,6 +183,9 @@ static void fix_processor_context(void)
 	load_mm_ldt(current->active_mm);	/* This does lldt */
 
 	fpu__resume_cpu();
+
+	/* The processor is back on the direct GDT, load back the fixmap */
+	load_fixmap_gdt(cpu);
 }
 
 /**
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index ec1d5c46e58f..4951fcf95143 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -710,7 +710,7 @@ static void load_TLS_descriptor(struct thread_struct *t,
 
 	*shadow = t->tls_array[i];
 
-	gdt = get_cpu_gdt_table(cpu);
+	gdt = get_cpu_gdt_rw(cpu);
 	maddr = arbitrary_virt_to_machine(&gdt[GDT_ENTRY_TLS_MIN+i]);
 	mc = __xen_mc_entry(0);
 
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 0dee6f59ea82..6399bab936cd 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -391,7 +391,7 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
 	if (ctxt == NULL)
 		return -ENOMEM;
 
-	gdt = get_cpu_gdt_table(cpu);
+	gdt = get_cpu_gdt_rw(cpu);
 
 #ifdef CONFIG_X86_32
 	ctxt->user_regs.fs = __KERNEL_PERCPU;
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index d71f6323ac00..b4f79b923aea 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -504,7 +504,7 @@ void __init lguest_arch_host_init(void)
 		 * byte, not the size, hence the "-1").
 		 */
 		state->host_gdt_desc.size = GDT_SIZE-1;
-		state->host_gdt_desc.address = (long)get_cpu_gdt_table(i);
+		state->host_gdt_desc.address = (long)get_cpu_gdt_rw(i);
 
 		/*
 		 * All CPUs on the Host use the same Interrupt Descriptor
@@ -554,8 +554,8 @@ void __init lguest_arch_host_init(void)
 		 * The Host needs to be able to use the LGUEST segments on this
 		 * CPU, too, so put them in the Host GDT.
 		 */
-		get_cpu_gdt_table(i)[GDT_ENTRY_LGUEST_CS] = FULL_EXEC_SEGMENT;
-		get_cpu_gdt_table(i)[GDT_ENTRY_LGUEST_DS] = FULL_SEGMENT;
+		get_cpu_gdt_rw(i)[GDT_ENTRY_LGUEST_CS] = FULL_EXEC_SEGMENT;
+		get_cpu_gdt_rw(i)[GDT_ENTRY_LGUEST_DS] = FULL_SEGMENT;
 	}
 
 	/*
diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c
index 438d4c72c7b3..ff563db025b3 100644
--- a/drivers/pnp/pnpbios/bioscalls.c
+++ b/drivers/pnp/pnpbios/bioscalls.c
@@ -54,7 +54,7 @@ __asm__(".text			\n"
 
 #define Q2_SET_SEL(cpu, selname, address, size) \
 do { \
-	struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \
+	struct desc_struct *gdt = get_cpu_gdt_rw((cpu)); \
 	set_desc_base(&gdt[(selname) >> 3], (u32)(address)); \
 	set_desc_limit(&gdt[(selname) >> 3], (size) - 1); \
 } while(0)
@@ -95,8 +95,8 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3,
 		return PNP_FUNCTION_NOT_SUPPORTED;
 
 	cpu = get_cpu();
-	save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
-	get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
+	save_desc_40 = get_cpu_gdt_rw(cpu)[0x40 / 8];
+	get_cpu_gdt_rw(cpu)[0x40 / 8] = bad_bios_desc;
 
 	/* On some boxes IRQ's during PnP BIOS calls are deadly.  */
 	spin_lock_irqsave(&pnp_bios_lock, flags);
@@ -134,7 +134,7 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3,
 			     :"memory");
 	spin_unlock_irqrestore(&pnp_bios_lock, flags);
 
-	get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
+	get_cpu_gdt_rw(cpu)[0x40 / 8] = save_desc_40;
 	put_cpu();
 
 	/* If we get here and this is set then the PnP BIOS faulted on us. */
@@ -477,7 +477,7 @@ void pnpbios_calls_init(union pnp_bios_install_struct *header)
 	pnp_bios_callpoint.segment = PNP_CS16;
 
 	for_each_possible_cpu(i) {
-		struct desc_struct *gdt = get_cpu_gdt_table(i);
+		struct desc_struct *gdt = get_cpu_gdt_rw(i);
 		if (!gdt)
 			continue;
 		set_desc_base(&gdt[GDT_ENTRY_PNPBIOS_CS32],
-- 
2.11.0.483.g087da7b7c-goog

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 2/4] x86: Remap GDT tables in the Fixmap section
@ 2017-02-16 21:54   ` Thomas Garnier
  0 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-16 21:54 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H . Peter Anvin, Jonathan Corbet,
	Thomas Garnier, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He Chen, Luis R . Rodriguez, Stanislaw Gruszka,
	Arnd Bergmann
  Cc: x86, linux-kernel, linux-doc, linux-pm, linux-efi, xen-devel,
	lguest, kvm, kernel-hardening

Each processor holds a GDT in its per-cpu structure. The sgdt
instruction gives the base address of the current GDT. This address can
be used to bypass KASLR memory randomization. With another bug, an
attacker could target other per-cpu structures or deduce the base of
the main memory section (PAGE_OFFSET).

This patch relocates the GDT table for each processor inside the
Fixmap section. The space is reserved based on number of supported
processors.

For consistency, the remapping is done by default on 32 and 64-bit.

Each processor switches to its remapped GDT at the end of
initialization. For hibernation, the main processor returns with the
original GDT and switches back to the remapping at completion.

This patch was tested on both architectures. Hibernation and KVM were
both tested specially for their usage of the GDT.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170213
---
 arch/x86/entry/vdso/vma.c             |  2 +-
 arch/x86/include/asm/desc.h           | 33 +++++++++++++++++++++++++++++----
 arch/x86/include/asm/fixmap.h         |  4 ++++
 arch/x86/include/asm/processor.h      |  1 +
 arch/x86/include/asm/stackprotector.h |  2 +-
 arch/x86/kernel/acpi/sleep.c          |  2 +-
 arch/x86/kernel/apm_32.c              |  6 +++---
 arch/x86/kernel/cpu/common.c          | 26 ++++++++++++++++++++++++--
 arch/x86/kernel/setup_percpu.c        |  2 +-
 arch/x86/kernel/smpboot.c             |  2 +-
 arch/x86/platform/efi/efi_32.c        |  4 ++--
 arch/x86/power/cpu.c                  |  7 +++++--
 arch/x86/xen/enlighten.c              |  2 +-
 arch/x86/xen/smp.c                    |  2 +-
 drivers/lguest/x86/core.c             |  6 +++---
 drivers/pnp/pnpbios/bioscalls.c       | 10 +++++-----
 16 files changed, 83 insertions(+), 28 deletions(-)

diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
index 572cee3fccff..9c8bd4cfcc6e 100644
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -353,7 +353,7 @@ static void vgetcpu_cpu_init(void *arg)
 	d.p = 1;		/* Present */
 	d.d = 1;		/* 32-bit */
 
-	write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_PER_CPU, &d, DESCTYPE_S);
+	write_gdt_entry(get_cpu_gdt_rw(cpu), GDT_ENTRY_PER_CPU, &d, DESCTYPE_S);
 }
 
 static int vgetcpu_online(unsigned int cpu)
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
index 12080d87da3b..5d4ba1311737 100644
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -4,6 +4,7 @@
 #include <asm/desc_defs.h>
 #include <asm/ldt.h>
 #include <asm/mmu.h>
+#include <asm/fixmap.h>
 
 #include <linux/smp.h>
 #include <linux/percpu.h>
@@ -45,11 +46,35 @@ struct gdt_page {
 
 DECLARE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page);
 
-static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
+/* Provide the original GDT */
+static inline struct desc_struct *get_cpu_gdt_rw(unsigned int cpu)
 {
 	return per_cpu(gdt_page, cpu).gdt;
 }
 
+static inline unsigned long get_cpu_gdt_rw_vaddr(unsigned int cpu)
+{
+	return (unsigned long)get_cpu_gdt_rw(cpu);
+}
+
+/* Get the fixmap index for a specific processor */
+static inline unsigned int get_cpu_gdt_ro_index(int cpu)
+{
+	return FIX_GDT_REMAP_BEGIN + cpu;
+}
+
+/* Provide the fixmap address of the remapped GDT */
+static inline struct desc_struct *get_cpu_gdt_ro(int cpu)
+{
+	unsigned int idx = get_cpu_gdt_ro_index(cpu);
+	return (struct desc_struct *)__fix_to_virt(idx);
+}
+
+static inline unsigned long get_cpu_gdt_ro_vaddr(int cpu)
+{
+	return (unsigned long)get_cpu_gdt_ro(cpu);
+}
+
 #ifdef CONFIG_X86_64
 
 static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func,
@@ -174,7 +199,7 @@ static inline void set_tssldt_descriptor(void *d, unsigned long addr, unsigned t
 
 static inline void __set_tss_desc(unsigned cpu, unsigned int entry, void *addr)
 {
-	struct desc_struct *d = get_cpu_gdt_table(cpu);
+	struct desc_struct *d = get_cpu_gdt_rw(cpu);
 	tss_desc tss;
 
 	/*
@@ -202,7 +227,7 @@ static inline void native_set_ldt(const void *addr, unsigned int entries)
 
 		set_tssldt_descriptor(&ldt, (unsigned long)addr, DESC_LDT,
 				      entries * LDT_ENTRY_SIZE - 1);
-		write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT,
+		write_gdt_entry(get_cpu_gdt_rw(cpu), GDT_ENTRY_LDT,
 				&ldt, DESC_LDT);
 		asm volatile("lldt %w0"::"q" (GDT_ENTRY_LDT*8));
 	}
@@ -244,7 +269,7 @@ static inline unsigned long native_store_tr(void)
 
 static inline void native_load_tls(struct thread_struct *t, unsigned int cpu)
 {
-	struct desc_struct *gdt = get_cpu_gdt_table(cpu);
+	struct desc_struct *gdt = get_cpu_gdt_rw(cpu);
 	unsigned int i;
 
 	for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h
index 8554f960e21b..b65155cc3760 100644
--- a/arch/x86/include/asm/fixmap.h
+++ b/arch/x86/include/asm/fixmap.h
@@ -100,6 +100,10 @@ enum fixed_addresses {
 #ifdef	CONFIG_X86_INTEL_MID
 	FIX_LNW_VRTC,
 #endif
+	/* Fixmap entries to remap the GDTs, one per processor. */
+	FIX_GDT_REMAP_BEGIN,
+	FIX_GDT_REMAP_END = FIX_GDT_REMAP_BEGIN + NR_CPUS - 1,
+
 	__end_of_permanent_fixed_addresses,
 
 	/*
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index e6cfe7ba2d65..c441d1f7e275 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -706,6 +706,7 @@ extern struct desc_ptr		early_gdt_descr;
 
 extern void cpu_set_gdt(int);
 extern void switch_to_new_gdt(int);
+extern void load_fixmap_gdt(int);
 extern void load_percpu_segment(int);
 extern void cpu_init(void);
 
diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h
index 58505f01962f..dcbd9bcce714 100644
--- a/arch/x86/include/asm/stackprotector.h
+++ b/arch/x86/include/asm/stackprotector.h
@@ -87,7 +87,7 @@ static inline void setup_stack_canary_segment(int cpu)
 {
 #ifdef CONFIG_X86_32
 	unsigned long canary = (unsigned long)&per_cpu(stack_canary, cpu);
-	struct desc_struct *gdt_table = get_cpu_gdt_table(cpu);
+	struct desc_struct *gdt_table = get_cpu_gdt_rw(cpu);
 	struct desc_struct desc;
 
 	desc = gdt_table[GDT_ENTRY_STACK_CANARY];
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
index 48587335ede8..ed014814ea35 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -101,7 +101,7 @@ int x86_acpi_suspend_lowlevel(void)
 #ifdef CONFIG_SMP
 	initial_stack = (unsigned long)temp_stack + sizeof(temp_stack);
 	early_gdt_descr.address =
-			(unsigned long)get_cpu_gdt_table(smp_processor_id());
+			(unsigned long)get_cpu_gdt_rw(smp_processor_id());
 	initial_gs = per_cpu_offset(smp_processor_id());
 #endif
 	initial_code = (unsigned long)wakeup_long64;
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 45d44c173cf9..dc4e89d93a10 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -608,7 +608,7 @@ static long __apm_bios_call(void *_call)
 
 	cpu = get_cpu();
 	BUG_ON(cpu != 0);
-	gdt = get_cpu_gdt_table(cpu);
+	gdt = get_cpu_gdt_rw(cpu);
 	save_desc_40 = gdt[0x40 / 8];
 	gdt[0x40 / 8] = bad_bios_desc;
 
@@ -684,7 +684,7 @@ static long __apm_bios_call_simple(void *_call)
 
 	cpu = get_cpu();
 	BUG_ON(cpu != 0);
-	gdt = get_cpu_gdt_table(cpu);
+	gdt = get_cpu_gdt_rw(cpu);
 	save_desc_40 = gdt[0x40 / 8];
 	gdt[0x40 / 8] = bad_bios_desc;
 
@@ -2351,7 +2351,7 @@ static int __init apm_init(void)
 	 * Note we only set APM segments on CPU zero, since we pin the APM
 	 * code to that CPU.
 	 */
-	gdt = get_cpu_gdt_table(0);
+	gdt = get_cpu_gdt_rw(0);
 	set_desc_base(&gdt[APM_CS >> 3],
 		 (unsigned long)__va((unsigned long)apm_info.bios.cseg << 4));
 	set_desc_base(&gdt[APM_CS_16 >> 3],
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 1a4ee7082ad7..2853a42ded2d 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -444,6 +444,23 @@ void load_percpu_segment(int cpu)
 	load_stack_canary_segment();
 }
 
+/* Setup the fixmap mapping only once per-processor */
+static inline void setup_fixmap_gdt(int cpu)
+{
+	__set_fixmap(get_cpu_gdt_ro_index(cpu),
+		     __pa(get_cpu_gdt_rw(cpu)), PAGE_KERNEL);
+}
+
+/* Load a fixmap remapping of the per-cpu GDT */
+void load_fixmap_gdt(int cpu)
+{
+	struct desc_ptr gdt_descr;
+
+	gdt_descr.address = (long)get_cpu_gdt_ro(cpu);
+	gdt_descr.size = GDT_SIZE - 1;
+	load_gdt(&gdt_descr);
+}
+
 /*
  * Current gdt points %fs at the "master" per-cpu area: after this,
  * it's on the real one.
@@ -452,11 +469,10 @@ void switch_to_new_gdt(int cpu)
 {
 	struct desc_ptr gdt_descr;
 
-	gdt_descr.address = (long)get_cpu_gdt_table(cpu);
+	gdt_descr.address = (long)get_cpu_gdt_rw(cpu);
 	gdt_descr.size = GDT_SIZE - 1;
 	load_gdt(&gdt_descr);
 	/* Reload the per-cpu base */
-
 	load_percpu_segment(cpu);
 }
 
@@ -1524,6 +1540,9 @@ void cpu_init(void)
 
 	if (is_uv_system())
 		uv_cpu_init();
+
+	setup_fixmap_gdt(cpu);
+	load_fixmap_gdt(cpu);
 }
 
 #else
@@ -1579,6 +1598,9 @@ void cpu_init(void)
 	dbg_restore_debug_regs();
 
 	fpu__init_cpu();
+
+	setup_fixmap_gdt(cpu);
+	load_fixmap_gdt(cpu);
 }
 #endif
 
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index 9820d6d977c6..11338b0b3ad2 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -160,7 +160,7 @@ static inline void setup_percpu_segment(int cpu)
 	pack_descriptor(&gdt, per_cpu_offset(cpu), 0xFFFFF,
 			0x2 | DESCTYPE_S, 0x8);
 	gdt.s = 1;
-	write_gdt_entry(get_cpu_gdt_table(cpu),
+	write_gdt_entry(get_cpu_gdt_rw(cpu),
 			GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S);
 #endif
 }
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 99b920d0e516..2e61b4b6957b 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -980,7 +980,7 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
 	unsigned long timeout;
 
 	idle->thread.sp = (unsigned long)task_pt_regs(idle);
-	early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
+	early_gdt_descr.address = (unsigned long)get_cpu_gdt_rw(cpu);
 	initial_code = (unsigned long)start_secondary;
 	initial_stack  = idle->thread.sp;
 
diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c
index cef39b097649..950071171436 100644
--- a/arch/x86/platform/efi/efi_32.c
+++ b/arch/x86/platform/efi/efi_32.c
@@ -68,7 +68,7 @@ pgd_t * __init efi_call_phys_prolog(void)
 	load_cr3(initial_page_table);
 	__flush_tlb_all();
 
-	gdt_descr.address = __pa(get_cpu_gdt_table(0));
+	gdt_descr.address = __pa(get_cpu_gdt_rw(0));
 	gdt_descr.size = GDT_SIZE - 1;
 	load_gdt(&gdt_descr);
 
@@ -79,7 +79,7 @@ void __init efi_call_phys_epilog(pgd_t *save_pgd)
 {
 	struct desc_ptr gdt_descr;
 
-	gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
+	gdt_descr.address = (unsigned long)get_cpu_gdt_rw(0);
 	gdt_descr.size = GDT_SIZE - 1;
 	load_gdt(&gdt_descr);
 
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
index 66ade16c7693..6b05a9219ea2 100644
--- a/arch/x86/power/cpu.c
+++ b/arch/x86/power/cpu.c
@@ -95,7 +95,7 @@ static void __save_processor_state(struct saved_context *ctxt)
 	 * 'pmode_gdt' in wakeup_start.
 	 */
 	ctxt->gdt_desc.size = GDT_SIZE - 1;
-	ctxt->gdt_desc.address = (unsigned long)get_cpu_gdt_table(smp_processor_id());
+	ctxt->gdt_desc.address = (unsigned long)get_cpu_gdt_rw(smp_processor_id());
 
 	store_tr(ctxt->tr);
 
@@ -162,7 +162,7 @@ static void fix_processor_context(void)
 	int cpu = smp_processor_id();
 	struct tss_struct *t = &per_cpu(cpu_tss, cpu);
 #ifdef CONFIG_X86_64
-	struct desc_struct *desc = get_cpu_gdt_table(cpu);
+	struct desc_struct *desc = get_cpu_gdt_rw(cpu);
 	tss_desc tss;
 #endif
 	set_tss_desc(cpu, t);	/*
@@ -183,6 +183,9 @@ static void fix_processor_context(void)
 	load_mm_ldt(current->active_mm);	/* This does lldt */
 
 	fpu__resume_cpu();
+
+	/* The processor is back on the direct GDT, load back the fixmap */
+	load_fixmap_gdt(cpu);
 }
 
 /**
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index ec1d5c46e58f..4951fcf95143 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -710,7 +710,7 @@ static void load_TLS_descriptor(struct thread_struct *t,
 
 	*shadow = t->tls_array[i];
 
-	gdt = get_cpu_gdt_table(cpu);
+	gdt = get_cpu_gdt_rw(cpu);
 	maddr = arbitrary_virt_to_machine(&gdt[GDT_ENTRY_TLS_MIN+i]);
 	mc = __xen_mc_entry(0);
 
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 0dee6f59ea82..6399bab936cd 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -391,7 +391,7 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
 	if (ctxt == NULL)
 		return -ENOMEM;
 
-	gdt = get_cpu_gdt_table(cpu);
+	gdt = get_cpu_gdt_rw(cpu);
 
 #ifdef CONFIG_X86_32
 	ctxt->user_regs.fs = __KERNEL_PERCPU;
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index d71f6323ac00..b4f79b923aea 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -504,7 +504,7 @@ void __init lguest_arch_host_init(void)
 		 * byte, not the size, hence the "-1").
 		 */
 		state->host_gdt_desc.size = GDT_SIZE-1;
-		state->host_gdt_desc.address = (long)get_cpu_gdt_table(i);
+		state->host_gdt_desc.address = (long)get_cpu_gdt_rw(i);
 
 		/*
 		 * All CPUs on the Host use the same Interrupt Descriptor
@@ -554,8 +554,8 @@ void __init lguest_arch_host_init(void)
 		 * The Host needs to be able to use the LGUEST segments on this
 		 * CPU, too, so put them in the Host GDT.
 		 */
-		get_cpu_gdt_table(i)[GDT_ENTRY_LGUEST_CS] = FULL_EXEC_SEGMENT;
-		get_cpu_gdt_table(i)[GDT_ENTRY_LGUEST_DS] = FULL_SEGMENT;
+		get_cpu_gdt_rw(i)[GDT_ENTRY_LGUEST_CS] = FULL_EXEC_SEGMENT;
+		get_cpu_gdt_rw(i)[GDT_ENTRY_LGUEST_DS] = FULL_SEGMENT;
 	}
 
 	/*
diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c
index 438d4c72c7b3..ff563db025b3 100644
--- a/drivers/pnp/pnpbios/bioscalls.c
+++ b/drivers/pnp/pnpbios/bioscalls.c
@@ -54,7 +54,7 @@ __asm__(".text			\n"
 
 #define Q2_SET_SEL(cpu, selname, address, size) \
 do { \
-	struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \
+	struct desc_struct *gdt = get_cpu_gdt_rw((cpu)); \
 	set_desc_base(&gdt[(selname) >> 3], (u32)(address)); \
 	set_desc_limit(&gdt[(selname) >> 3], (size) - 1); \
 } while(0)
@@ -95,8 +95,8 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3,
 		return PNP_FUNCTION_NOT_SUPPORTED;
 
 	cpu = get_cpu();
-	save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
-	get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
+	save_desc_40 = get_cpu_gdt_rw(cpu)[0x40 / 8];
+	get_cpu_gdt_rw(cpu)[0x40 / 8] = bad_bios_desc;
 
 	/* On some boxes IRQ's during PnP BIOS calls are deadly.  */
 	spin_lock_irqsave(&pnp_bios_lock, flags);
@@ -134,7 +134,7 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3,
 			     :"memory");
 	spin_unlock_irqrestore(&pnp_bios_lock, flags);
 
-	get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
+	get_cpu_gdt_rw(cpu)[0x40 / 8] = save_desc_40;
 	put_cpu();
 
 	/* If we get here and this is set then the PnP BIOS faulted on us. */
@@ -477,7 +477,7 @@ void pnpbios_calls_init(union pnp_bios_install_struct *header)
 	pnp_bios_callpoint.segment = PNP_CS16;
 
 	for_each_possible_cpu(i) {
-		struct desc_struct *gdt = get_cpu_gdt_table(i);
+		struct desc_struct *gdt = get_cpu_gdt_rw(i);
 		if (!gdt)
 			continue;
 		set_desc_base(&gdt[GDT_ENTRY_PNPBIOS_CS32],
-- 
2.11.0.483.g087da7b7c-goog

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [kernel-hardening] [PATCH v4 2/4] x86: Remap GDT tables in the Fixmap section
@ 2017-02-16 21:54   ` Thomas Garnier
  0 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-16 21:54 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H . Peter Anvin, Jonathan Corbet,
	Thomas Garnier, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He Chen, Luis R . Rodriguez, Stanislaw Gruszka,
	Arnd Bergmann, Peter Zijlstra, Dave Hansen, Vitaly Kuznetsov,
	Paul Gortmaker, Josh Poimboeuf, Tim Chen, Andi Kleen, Jiri Olsa,
	Michael Ellerman, Joerg Roedel, Paolo Bonzini,
	Radim Krčmář,
	Andy Lutomirski
  Cc: x86, linux-kernel, linux-doc, linux-pm, linux-efi, xen-devel,
	lguest, kvm, kernel-hardening

Each processor holds a GDT in its per-cpu structure. The sgdt
instruction gives the base address of the current GDT. This address can
be used to bypass KASLR memory randomization. With another bug, an
attacker could target other per-cpu structures or deduce the base of
the main memory section (PAGE_OFFSET).

This patch relocates the GDT table for each processor inside the
Fixmap section. The space is reserved based on number of supported
processors.

For consistency, the remapping is done by default on 32 and 64-bit.

Each processor switches to its remapped GDT at the end of
initialization. For hibernation, the main processor returns with the
original GDT and switches back to the remapping at completion.

This patch was tested on both architectures. Hibernation and KVM were
both tested specially for their usage of the GDT.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170213
---
 arch/x86/entry/vdso/vma.c             |  2 +-
 arch/x86/include/asm/desc.h           | 33 +++++++++++++++++++++++++++++----
 arch/x86/include/asm/fixmap.h         |  4 ++++
 arch/x86/include/asm/processor.h      |  1 +
 arch/x86/include/asm/stackprotector.h |  2 +-
 arch/x86/kernel/acpi/sleep.c          |  2 +-
 arch/x86/kernel/apm_32.c              |  6 +++---
 arch/x86/kernel/cpu/common.c          | 26 ++++++++++++++++++++++++--
 arch/x86/kernel/setup_percpu.c        |  2 +-
 arch/x86/kernel/smpboot.c             |  2 +-
 arch/x86/platform/efi/efi_32.c        |  4 ++--
 arch/x86/power/cpu.c                  |  7 +++++--
 arch/x86/xen/enlighten.c              |  2 +-
 arch/x86/xen/smp.c                    |  2 +-
 drivers/lguest/x86/core.c             |  6 +++---
 drivers/pnp/pnpbios/bioscalls.c       | 10 +++++-----
 16 files changed, 83 insertions(+), 28 deletions(-)

diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
index 572cee3fccff..9c8bd4cfcc6e 100644
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -353,7 +353,7 @@ static void vgetcpu_cpu_init(void *arg)
 	d.p = 1;		/* Present */
 	d.d = 1;		/* 32-bit */
 
-	write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_PER_CPU, &d, DESCTYPE_S);
+	write_gdt_entry(get_cpu_gdt_rw(cpu), GDT_ENTRY_PER_CPU, &d, DESCTYPE_S);
 }
 
 static int vgetcpu_online(unsigned int cpu)
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
index 12080d87da3b..5d4ba1311737 100644
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -4,6 +4,7 @@
 #include <asm/desc_defs.h>
 #include <asm/ldt.h>
 #include <asm/mmu.h>
+#include <asm/fixmap.h>
 
 #include <linux/smp.h>
 #include <linux/percpu.h>
@@ -45,11 +46,35 @@ struct gdt_page {
 
 DECLARE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page);
 
-static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
+/* Provide the original GDT */
+static inline struct desc_struct *get_cpu_gdt_rw(unsigned int cpu)
 {
 	return per_cpu(gdt_page, cpu).gdt;
 }
 
+static inline unsigned long get_cpu_gdt_rw_vaddr(unsigned int cpu)
+{
+	return (unsigned long)get_cpu_gdt_rw(cpu);
+}
+
+/* Get the fixmap index for a specific processor */
+static inline unsigned int get_cpu_gdt_ro_index(int cpu)
+{
+	return FIX_GDT_REMAP_BEGIN + cpu;
+}
+
+/* Provide the fixmap address of the remapped GDT */
+static inline struct desc_struct *get_cpu_gdt_ro(int cpu)
+{
+	unsigned int idx = get_cpu_gdt_ro_index(cpu);
+	return (struct desc_struct *)__fix_to_virt(idx);
+}
+
+static inline unsigned long get_cpu_gdt_ro_vaddr(int cpu)
+{
+	return (unsigned long)get_cpu_gdt_ro(cpu);
+}
+
 #ifdef CONFIG_X86_64
 
 static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func,
@@ -174,7 +199,7 @@ static inline void set_tssldt_descriptor(void *d, unsigned long addr, unsigned t
 
 static inline void __set_tss_desc(unsigned cpu, unsigned int entry, void *addr)
 {
-	struct desc_struct *d = get_cpu_gdt_table(cpu);
+	struct desc_struct *d = get_cpu_gdt_rw(cpu);
 	tss_desc tss;
 
 	/*
@@ -202,7 +227,7 @@ static inline void native_set_ldt(const void *addr, unsigned int entries)
 
 		set_tssldt_descriptor(&ldt, (unsigned long)addr, DESC_LDT,
 				      entries * LDT_ENTRY_SIZE - 1);
-		write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT,
+		write_gdt_entry(get_cpu_gdt_rw(cpu), GDT_ENTRY_LDT,
 				&ldt, DESC_LDT);
 		asm volatile("lldt %w0"::"q" (GDT_ENTRY_LDT*8));
 	}
@@ -244,7 +269,7 @@ static inline unsigned long native_store_tr(void)
 
 static inline void native_load_tls(struct thread_struct *t, unsigned int cpu)
 {
-	struct desc_struct *gdt = get_cpu_gdt_table(cpu);
+	struct desc_struct *gdt = get_cpu_gdt_rw(cpu);
 	unsigned int i;
 
 	for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h
index 8554f960e21b..b65155cc3760 100644
--- a/arch/x86/include/asm/fixmap.h
+++ b/arch/x86/include/asm/fixmap.h
@@ -100,6 +100,10 @@ enum fixed_addresses {
 #ifdef	CONFIG_X86_INTEL_MID
 	FIX_LNW_VRTC,
 #endif
+	/* Fixmap entries to remap the GDTs, one per processor. */
+	FIX_GDT_REMAP_BEGIN,
+	FIX_GDT_REMAP_END = FIX_GDT_REMAP_BEGIN + NR_CPUS - 1,
+
 	__end_of_permanent_fixed_addresses,
 
 	/*
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index e6cfe7ba2d65..c441d1f7e275 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -706,6 +706,7 @@ extern struct desc_ptr		early_gdt_descr;
 
 extern void cpu_set_gdt(int);
 extern void switch_to_new_gdt(int);
+extern void load_fixmap_gdt(int);
 extern void load_percpu_segment(int);
 extern void cpu_init(void);
 
diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h
index 58505f01962f..dcbd9bcce714 100644
--- a/arch/x86/include/asm/stackprotector.h
+++ b/arch/x86/include/asm/stackprotector.h
@@ -87,7 +87,7 @@ static inline void setup_stack_canary_segment(int cpu)
 {
 #ifdef CONFIG_X86_32
 	unsigned long canary = (unsigned long)&per_cpu(stack_canary, cpu);
-	struct desc_struct *gdt_table = get_cpu_gdt_table(cpu);
+	struct desc_struct *gdt_table = get_cpu_gdt_rw(cpu);
 	struct desc_struct desc;
 
 	desc = gdt_table[GDT_ENTRY_STACK_CANARY];
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
index 48587335ede8..ed014814ea35 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -101,7 +101,7 @@ int x86_acpi_suspend_lowlevel(void)
 #ifdef CONFIG_SMP
 	initial_stack = (unsigned long)temp_stack + sizeof(temp_stack);
 	early_gdt_descr.address =
-			(unsigned long)get_cpu_gdt_table(smp_processor_id());
+			(unsigned long)get_cpu_gdt_rw(smp_processor_id());
 	initial_gs = per_cpu_offset(smp_processor_id());
 #endif
 	initial_code = (unsigned long)wakeup_long64;
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 45d44c173cf9..dc4e89d93a10 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -608,7 +608,7 @@ static long __apm_bios_call(void *_call)
 
 	cpu = get_cpu();
 	BUG_ON(cpu != 0);
-	gdt = get_cpu_gdt_table(cpu);
+	gdt = get_cpu_gdt_rw(cpu);
 	save_desc_40 = gdt[0x40 / 8];
 	gdt[0x40 / 8] = bad_bios_desc;
 
@@ -684,7 +684,7 @@ static long __apm_bios_call_simple(void *_call)
 
 	cpu = get_cpu();
 	BUG_ON(cpu != 0);
-	gdt = get_cpu_gdt_table(cpu);
+	gdt = get_cpu_gdt_rw(cpu);
 	save_desc_40 = gdt[0x40 / 8];
 	gdt[0x40 / 8] = bad_bios_desc;
 
@@ -2351,7 +2351,7 @@ static int __init apm_init(void)
 	 * Note we only set APM segments on CPU zero, since we pin the APM
 	 * code to that CPU.
 	 */
-	gdt = get_cpu_gdt_table(0);
+	gdt = get_cpu_gdt_rw(0);
 	set_desc_base(&gdt[APM_CS >> 3],
 		 (unsigned long)__va((unsigned long)apm_info.bios.cseg << 4));
 	set_desc_base(&gdt[APM_CS_16 >> 3],
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 1a4ee7082ad7..2853a42ded2d 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -444,6 +444,23 @@ void load_percpu_segment(int cpu)
 	load_stack_canary_segment();
 }
 
+/* Setup the fixmap mapping only once per-processor */
+static inline void setup_fixmap_gdt(int cpu)
+{
+	__set_fixmap(get_cpu_gdt_ro_index(cpu),
+		     __pa(get_cpu_gdt_rw(cpu)), PAGE_KERNEL);
+}
+
+/* Load a fixmap remapping of the per-cpu GDT */
+void load_fixmap_gdt(int cpu)
+{
+	struct desc_ptr gdt_descr;
+
+	gdt_descr.address = (long)get_cpu_gdt_ro(cpu);
+	gdt_descr.size = GDT_SIZE - 1;
+	load_gdt(&gdt_descr);
+}
+
 /*
  * Current gdt points %fs at the "master" per-cpu area: after this,
  * it's on the real one.
@@ -452,11 +469,10 @@ void switch_to_new_gdt(int cpu)
 {
 	struct desc_ptr gdt_descr;
 
-	gdt_descr.address = (long)get_cpu_gdt_table(cpu);
+	gdt_descr.address = (long)get_cpu_gdt_rw(cpu);
 	gdt_descr.size = GDT_SIZE - 1;
 	load_gdt(&gdt_descr);
 	/* Reload the per-cpu base */
-
 	load_percpu_segment(cpu);
 }
 
@@ -1524,6 +1540,9 @@ void cpu_init(void)
 
 	if (is_uv_system())
 		uv_cpu_init();
+
+	setup_fixmap_gdt(cpu);
+	load_fixmap_gdt(cpu);
 }
 
 #else
@@ -1579,6 +1598,9 @@ void cpu_init(void)
 	dbg_restore_debug_regs();
 
 	fpu__init_cpu();
+
+	setup_fixmap_gdt(cpu);
+	load_fixmap_gdt(cpu);
 }
 #endif
 
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index 9820d6d977c6..11338b0b3ad2 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -160,7 +160,7 @@ static inline void setup_percpu_segment(int cpu)
 	pack_descriptor(&gdt, per_cpu_offset(cpu), 0xFFFFF,
 			0x2 | DESCTYPE_S, 0x8);
 	gdt.s = 1;
-	write_gdt_entry(get_cpu_gdt_table(cpu),
+	write_gdt_entry(get_cpu_gdt_rw(cpu),
 			GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S);
 #endif
 }
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 99b920d0e516..2e61b4b6957b 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -980,7 +980,7 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
 	unsigned long timeout;
 
 	idle->thread.sp = (unsigned long)task_pt_regs(idle);
-	early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
+	early_gdt_descr.address = (unsigned long)get_cpu_gdt_rw(cpu);
 	initial_code = (unsigned long)start_secondary;
 	initial_stack  = idle->thread.sp;
 
diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c
index cef39b097649..950071171436 100644
--- a/arch/x86/platform/efi/efi_32.c
+++ b/arch/x86/platform/efi/efi_32.c
@@ -68,7 +68,7 @@ pgd_t * __init efi_call_phys_prolog(void)
 	load_cr3(initial_page_table);
 	__flush_tlb_all();
 
-	gdt_descr.address = __pa(get_cpu_gdt_table(0));
+	gdt_descr.address = __pa(get_cpu_gdt_rw(0));
 	gdt_descr.size = GDT_SIZE - 1;
 	load_gdt(&gdt_descr);
 
@@ -79,7 +79,7 @@ void __init efi_call_phys_epilog(pgd_t *save_pgd)
 {
 	struct desc_ptr gdt_descr;
 
-	gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
+	gdt_descr.address = (unsigned long)get_cpu_gdt_rw(0);
 	gdt_descr.size = GDT_SIZE - 1;
 	load_gdt(&gdt_descr);
 
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
index 66ade16c7693..6b05a9219ea2 100644
--- a/arch/x86/power/cpu.c
+++ b/arch/x86/power/cpu.c
@@ -95,7 +95,7 @@ static void __save_processor_state(struct saved_context *ctxt)
 	 * 'pmode_gdt' in wakeup_start.
 	 */
 	ctxt->gdt_desc.size = GDT_SIZE - 1;
-	ctxt->gdt_desc.address = (unsigned long)get_cpu_gdt_table(smp_processor_id());
+	ctxt->gdt_desc.address = (unsigned long)get_cpu_gdt_rw(smp_processor_id());
 
 	store_tr(ctxt->tr);
 
@@ -162,7 +162,7 @@ static void fix_processor_context(void)
 	int cpu = smp_processor_id();
 	struct tss_struct *t = &per_cpu(cpu_tss, cpu);
 #ifdef CONFIG_X86_64
-	struct desc_struct *desc = get_cpu_gdt_table(cpu);
+	struct desc_struct *desc = get_cpu_gdt_rw(cpu);
 	tss_desc tss;
 #endif
 	set_tss_desc(cpu, t);	/*
@@ -183,6 +183,9 @@ static void fix_processor_context(void)
 	load_mm_ldt(current->active_mm);	/* This does lldt */
 
 	fpu__resume_cpu();
+
+	/* The processor is back on the direct GDT, load back the fixmap */
+	load_fixmap_gdt(cpu);
 }
 
 /**
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index ec1d5c46e58f..4951fcf95143 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -710,7 +710,7 @@ static void load_TLS_descriptor(struct thread_struct *t,
 
 	*shadow = t->tls_array[i];
 
-	gdt = get_cpu_gdt_table(cpu);
+	gdt = get_cpu_gdt_rw(cpu);
 	maddr = arbitrary_virt_to_machine(&gdt[GDT_ENTRY_TLS_MIN+i]);
 	mc = __xen_mc_entry(0);
 
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 0dee6f59ea82..6399bab936cd 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -391,7 +391,7 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
 	if (ctxt == NULL)
 		return -ENOMEM;
 
-	gdt = get_cpu_gdt_table(cpu);
+	gdt = get_cpu_gdt_rw(cpu);
 
 #ifdef CONFIG_X86_32
 	ctxt->user_regs.fs = __KERNEL_PERCPU;
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index d71f6323ac00..b4f79b923aea 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -504,7 +504,7 @@ void __init lguest_arch_host_init(void)
 		 * byte, not the size, hence the "-1").
 		 */
 		state->host_gdt_desc.size = GDT_SIZE-1;
-		state->host_gdt_desc.address = (long)get_cpu_gdt_table(i);
+		state->host_gdt_desc.address = (long)get_cpu_gdt_rw(i);
 
 		/*
 		 * All CPUs on the Host use the same Interrupt Descriptor
@@ -554,8 +554,8 @@ void __init lguest_arch_host_init(void)
 		 * The Host needs to be able to use the LGUEST segments on this
 		 * CPU, too, so put them in the Host GDT.
 		 */
-		get_cpu_gdt_table(i)[GDT_ENTRY_LGUEST_CS] = FULL_EXEC_SEGMENT;
-		get_cpu_gdt_table(i)[GDT_ENTRY_LGUEST_DS] = FULL_SEGMENT;
+		get_cpu_gdt_rw(i)[GDT_ENTRY_LGUEST_CS] = FULL_EXEC_SEGMENT;
+		get_cpu_gdt_rw(i)[GDT_ENTRY_LGUEST_DS] = FULL_SEGMENT;
 	}
 
 	/*
diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c
index 438d4c72c7b3..ff563db025b3 100644
--- a/drivers/pnp/pnpbios/bioscalls.c
+++ b/drivers/pnp/pnpbios/bioscalls.c
@@ -54,7 +54,7 @@ __asm__(".text			\n"
 
 #define Q2_SET_SEL(cpu, selname, address, size) \
 do { \
-	struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \
+	struct desc_struct *gdt = get_cpu_gdt_rw((cpu)); \
 	set_desc_base(&gdt[(selname) >> 3], (u32)(address)); \
 	set_desc_limit(&gdt[(selname) >> 3], (size) - 1); \
 } while(0)
@@ -95,8 +95,8 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3,
 		return PNP_FUNCTION_NOT_SUPPORTED;
 
 	cpu = get_cpu();
-	save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
-	get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
+	save_desc_40 = get_cpu_gdt_rw(cpu)[0x40 / 8];
+	get_cpu_gdt_rw(cpu)[0x40 / 8] = bad_bios_desc;
 
 	/* On some boxes IRQ's during PnP BIOS calls are deadly.  */
 	spin_lock_irqsave(&pnp_bios_lock, flags);
@@ -134,7 +134,7 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3,
 			     :"memory");
 	spin_unlock_irqrestore(&pnp_bios_lock, flags);
 
-	get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
+	get_cpu_gdt_rw(cpu)[0x40 / 8] = save_desc_40;
 	put_cpu();
 
 	/* If we get here and this is set then the PnP BIOS faulted on us. */
@@ -477,7 +477,7 @@ void pnpbios_calls_init(union pnp_bios_install_struct *header)
 	pnp_bios_callpoint.segment = PNP_CS16;
 
 	for_each_possible_cpu(i) {
-		struct desc_struct *gdt = get_cpu_gdt_table(i);
+		struct desc_struct *gdt = get_cpu_gdt_rw(i);
 		if (!gdt)
 			continue;
 		set_desc_base(&gdt[GDT_ENTRY_PNPBIOS_CS32],
-- 
2.11.0.483.g087da7b7c-goog

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 2/4] x86: Remap GDT tables in the Fixmap section
  2017-02-16 21:54 ` Thomas Garnier
                   ` (2 preceding siblings ...)
  (?)
@ 2017-02-16 21:54 ` Thomas Garnier
  -1 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-16 21:54 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H . Peter Anvin, Jonathan Corbet,
	Thomas Garnier, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He Chen, Luis R . Rodriguez, Stanislaw Gruszka,
	Arnd Bergmann
  Cc: linux-efi, kvm, linux-pm, x86, linux-doc, linux-kernel, lguest,
	kernel-hardening, xen-devel

Each processor holds a GDT in its per-cpu structure. The sgdt
instruction gives the base address of the current GDT. This address can
be used to bypass KASLR memory randomization. With another bug, an
attacker could target other per-cpu structures or deduce the base of
the main memory section (PAGE_OFFSET).

This patch relocates the GDT table for each processor inside the
Fixmap section. The space is reserved based on number of supported
processors.

For consistency, the remapping is done by default on 32 and 64-bit.

Each processor switches to its remapped GDT at the end of
initialization. For hibernation, the main processor returns with the
original GDT and switches back to the remapping at completion.

This patch was tested on both architectures. Hibernation and KVM were
both tested specially for their usage of the GDT.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170213
---
 arch/x86/entry/vdso/vma.c             |  2 +-
 arch/x86/include/asm/desc.h           | 33 +++++++++++++++++++++++++++++----
 arch/x86/include/asm/fixmap.h         |  4 ++++
 arch/x86/include/asm/processor.h      |  1 +
 arch/x86/include/asm/stackprotector.h |  2 +-
 arch/x86/kernel/acpi/sleep.c          |  2 +-
 arch/x86/kernel/apm_32.c              |  6 +++---
 arch/x86/kernel/cpu/common.c          | 26 ++++++++++++++++++++++++--
 arch/x86/kernel/setup_percpu.c        |  2 +-
 arch/x86/kernel/smpboot.c             |  2 +-
 arch/x86/platform/efi/efi_32.c        |  4 ++--
 arch/x86/power/cpu.c                  |  7 +++++--
 arch/x86/xen/enlighten.c              |  2 +-
 arch/x86/xen/smp.c                    |  2 +-
 drivers/lguest/x86/core.c             |  6 +++---
 drivers/pnp/pnpbios/bioscalls.c       | 10 +++++-----
 16 files changed, 83 insertions(+), 28 deletions(-)

diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
index 572cee3fccff..9c8bd4cfcc6e 100644
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -353,7 +353,7 @@ static void vgetcpu_cpu_init(void *arg)
 	d.p = 1;		/* Present */
 	d.d = 1;		/* 32-bit */
 
-	write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_PER_CPU, &d, DESCTYPE_S);
+	write_gdt_entry(get_cpu_gdt_rw(cpu), GDT_ENTRY_PER_CPU, &d, DESCTYPE_S);
 }
 
 static int vgetcpu_online(unsigned int cpu)
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
index 12080d87da3b..5d4ba1311737 100644
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -4,6 +4,7 @@
 #include <asm/desc_defs.h>
 #include <asm/ldt.h>
 #include <asm/mmu.h>
+#include <asm/fixmap.h>
 
 #include <linux/smp.h>
 #include <linux/percpu.h>
@@ -45,11 +46,35 @@ struct gdt_page {
 
 DECLARE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page);
 
-static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
+/* Provide the original GDT */
+static inline struct desc_struct *get_cpu_gdt_rw(unsigned int cpu)
 {
 	return per_cpu(gdt_page, cpu).gdt;
 }
 
+static inline unsigned long get_cpu_gdt_rw_vaddr(unsigned int cpu)
+{
+	return (unsigned long)get_cpu_gdt_rw(cpu);
+}
+
+/* Get the fixmap index for a specific processor */
+static inline unsigned int get_cpu_gdt_ro_index(int cpu)
+{
+	return FIX_GDT_REMAP_BEGIN + cpu;
+}
+
+/* Provide the fixmap address of the remapped GDT */
+static inline struct desc_struct *get_cpu_gdt_ro(int cpu)
+{
+	unsigned int idx = get_cpu_gdt_ro_index(cpu);
+	return (struct desc_struct *)__fix_to_virt(idx);
+}
+
+static inline unsigned long get_cpu_gdt_ro_vaddr(int cpu)
+{
+	return (unsigned long)get_cpu_gdt_ro(cpu);
+}
+
 #ifdef CONFIG_X86_64
 
 static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func,
@@ -174,7 +199,7 @@ static inline void set_tssldt_descriptor(void *d, unsigned long addr, unsigned t
 
 static inline void __set_tss_desc(unsigned cpu, unsigned int entry, void *addr)
 {
-	struct desc_struct *d = get_cpu_gdt_table(cpu);
+	struct desc_struct *d = get_cpu_gdt_rw(cpu);
 	tss_desc tss;
 
 	/*
@@ -202,7 +227,7 @@ static inline void native_set_ldt(const void *addr, unsigned int entries)
 
 		set_tssldt_descriptor(&ldt, (unsigned long)addr, DESC_LDT,
 				      entries * LDT_ENTRY_SIZE - 1);
-		write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT,
+		write_gdt_entry(get_cpu_gdt_rw(cpu), GDT_ENTRY_LDT,
 				&ldt, DESC_LDT);
 		asm volatile("lldt %w0"::"q" (GDT_ENTRY_LDT*8));
 	}
@@ -244,7 +269,7 @@ static inline unsigned long native_store_tr(void)
 
 static inline void native_load_tls(struct thread_struct *t, unsigned int cpu)
 {
-	struct desc_struct *gdt = get_cpu_gdt_table(cpu);
+	struct desc_struct *gdt = get_cpu_gdt_rw(cpu);
 	unsigned int i;
 
 	for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h
index 8554f960e21b..b65155cc3760 100644
--- a/arch/x86/include/asm/fixmap.h
+++ b/arch/x86/include/asm/fixmap.h
@@ -100,6 +100,10 @@ enum fixed_addresses {
 #ifdef	CONFIG_X86_INTEL_MID
 	FIX_LNW_VRTC,
 #endif
+	/* Fixmap entries to remap the GDTs, one per processor. */
+	FIX_GDT_REMAP_BEGIN,
+	FIX_GDT_REMAP_END = FIX_GDT_REMAP_BEGIN + NR_CPUS - 1,
+
 	__end_of_permanent_fixed_addresses,
 
 	/*
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index e6cfe7ba2d65..c441d1f7e275 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -706,6 +706,7 @@ extern struct desc_ptr		early_gdt_descr;
 
 extern void cpu_set_gdt(int);
 extern void switch_to_new_gdt(int);
+extern void load_fixmap_gdt(int);
 extern void load_percpu_segment(int);
 extern void cpu_init(void);
 
diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h
index 58505f01962f..dcbd9bcce714 100644
--- a/arch/x86/include/asm/stackprotector.h
+++ b/arch/x86/include/asm/stackprotector.h
@@ -87,7 +87,7 @@ static inline void setup_stack_canary_segment(int cpu)
 {
 #ifdef CONFIG_X86_32
 	unsigned long canary = (unsigned long)&per_cpu(stack_canary, cpu);
-	struct desc_struct *gdt_table = get_cpu_gdt_table(cpu);
+	struct desc_struct *gdt_table = get_cpu_gdt_rw(cpu);
 	struct desc_struct desc;
 
 	desc = gdt_table[GDT_ENTRY_STACK_CANARY];
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
index 48587335ede8..ed014814ea35 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -101,7 +101,7 @@ int x86_acpi_suspend_lowlevel(void)
 #ifdef CONFIG_SMP
 	initial_stack = (unsigned long)temp_stack + sizeof(temp_stack);
 	early_gdt_descr.address =
-			(unsigned long)get_cpu_gdt_table(smp_processor_id());
+			(unsigned long)get_cpu_gdt_rw(smp_processor_id());
 	initial_gs = per_cpu_offset(smp_processor_id());
 #endif
 	initial_code = (unsigned long)wakeup_long64;
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 45d44c173cf9..dc4e89d93a10 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -608,7 +608,7 @@ static long __apm_bios_call(void *_call)
 
 	cpu = get_cpu();
 	BUG_ON(cpu != 0);
-	gdt = get_cpu_gdt_table(cpu);
+	gdt = get_cpu_gdt_rw(cpu);
 	save_desc_40 = gdt[0x40 / 8];
 	gdt[0x40 / 8] = bad_bios_desc;
 
@@ -684,7 +684,7 @@ static long __apm_bios_call_simple(void *_call)
 
 	cpu = get_cpu();
 	BUG_ON(cpu != 0);
-	gdt = get_cpu_gdt_table(cpu);
+	gdt = get_cpu_gdt_rw(cpu);
 	save_desc_40 = gdt[0x40 / 8];
 	gdt[0x40 / 8] = bad_bios_desc;
 
@@ -2351,7 +2351,7 @@ static int __init apm_init(void)
 	 * Note we only set APM segments on CPU zero, since we pin the APM
 	 * code to that CPU.
 	 */
-	gdt = get_cpu_gdt_table(0);
+	gdt = get_cpu_gdt_rw(0);
 	set_desc_base(&gdt[APM_CS >> 3],
 		 (unsigned long)__va((unsigned long)apm_info.bios.cseg << 4));
 	set_desc_base(&gdt[APM_CS_16 >> 3],
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 1a4ee7082ad7..2853a42ded2d 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -444,6 +444,23 @@ void load_percpu_segment(int cpu)
 	load_stack_canary_segment();
 }
 
+/* Setup the fixmap mapping only once per-processor */
+static inline void setup_fixmap_gdt(int cpu)
+{
+	__set_fixmap(get_cpu_gdt_ro_index(cpu),
+		     __pa(get_cpu_gdt_rw(cpu)), PAGE_KERNEL);
+}
+
+/* Load a fixmap remapping of the per-cpu GDT */
+void load_fixmap_gdt(int cpu)
+{
+	struct desc_ptr gdt_descr;
+
+	gdt_descr.address = (long)get_cpu_gdt_ro(cpu);
+	gdt_descr.size = GDT_SIZE - 1;
+	load_gdt(&gdt_descr);
+}
+
 /*
  * Current gdt points %fs at the "master" per-cpu area: after this,
  * it's on the real one.
@@ -452,11 +469,10 @@ void switch_to_new_gdt(int cpu)
 {
 	struct desc_ptr gdt_descr;
 
-	gdt_descr.address = (long)get_cpu_gdt_table(cpu);
+	gdt_descr.address = (long)get_cpu_gdt_rw(cpu);
 	gdt_descr.size = GDT_SIZE - 1;
 	load_gdt(&gdt_descr);
 	/* Reload the per-cpu base */
-
 	load_percpu_segment(cpu);
 }
 
@@ -1524,6 +1540,9 @@ void cpu_init(void)
 
 	if (is_uv_system())
 		uv_cpu_init();
+
+	setup_fixmap_gdt(cpu);
+	load_fixmap_gdt(cpu);
 }
 
 #else
@@ -1579,6 +1598,9 @@ void cpu_init(void)
 	dbg_restore_debug_regs();
 
 	fpu__init_cpu();
+
+	setup_fixmap_gdt(cpu);
+	load_fixmap_gdt(cpu);
 }
 #endif
 
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index 9820d6d977c6..11338b0b3ad2 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -160,7 +160,7 @@ static inline void setup_percpu_segment(int cpu)
 	pack_descriptor(&gdt, per_cpu_offset(cpu), 0xFFFFF,
 			0x2 | DESCTYPE_S, 0x8);
 	gdt.s = 1;
-	write_gdt_entry(get_cpu_gdt_table(cpu),
+	write_gdt_entry(get_cpu_gdt_rw(cpu),
 			GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S);
 #endif
 }
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 99b920d0e516..2e61b4b6957b 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -980,7 +980,7 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
 	unsigned long timeout;
 
 	idle->thread.sp = (unsigned long)task_pt_regs(idle);
-	early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
+	early_gdt_descr.address = (unsigned long)get_cpu_gdt_rw(cpu);
 	initial_code = (unsigned long)start_secondary;
 	initial_stack  = idle->thread.sp;
 
diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c
index cef39b097649..950071171436 100644
--- a/arch/x86/platform/efi/efi_32.c
+++ b/arch/x86/platform/efi/efi_32.c
@@ -68,7 +68,7 @@ pgd_t * __init efi_call_phys_prolog(void)
 	load_cr3(initial_page_table);
 	__flush_tlb_all();
 
-	gdt_descr.address = __pa(get_cpu_gdt_table(0));
+	gdt_descr.address = __pa(get_cpu_gdt_rw(0));
 	gdt_descr.size = GDT_SIZE - 1;
 	load_gdt(&gdt_descr);
 
@@ -79,7 +79,7 @@ void __init efi_call_phys_epilog(pgd_t *save_pgd)
 {
 	struct desc_ptr gdt_descr;
 
-	gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
+	gdt_descr.address = (unsigned long)get_cpu_gdt_rw(0);
 	gdt_descr.size = GDT_SIZE - 1;
 	load_gdt(&gdt_descr);
 
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
index 66ade16c7693..6b05a9219ea2 100644
--- a/arch/x86/power/cpu.c
+++ b/arch/x86/power/cpu.c
@@ -95,7 +95,7 @@ static void __save_processor_state(struct saved_context *ctxt)
 	 * 'pmode_gdt' in wakeup_start.
 	 */
 	ctxt->gdt_desc.size = GDT_SIZE - 1;
-	ctxt->gdt_desc.address = (unsigned long)get_cpu_gdt_table(smp_processor_id());
+	ctxt->gdt_desc.address = (unsigned long)get_cpu_gdt_rw(smp_processor_id());
 
 	store_tr(ctxt->tr);
 
@@ -162,7 +162,7 @@ static void fix_processor_context(void)
 	int cpu = smp_processor_id();
 	struct tss_struct *t = &per_cpu(cpu_tss, cpu);
 #ifdef CONFIG_X86_64
-	struct desc_struct *desc = get_cpu_gdt_table(cpu);
+	struct desc_struct *desc = get_cpu_gdt_rw(cpu);
 	tss_desc tss;
 #endif
 	set_tss_desc(cpu, t);	/*
@@ -183,6 +183,9 @@ static void fix_processor_context(void)
 	load_mm_ldt(current->active_mm);	/* This does lldt */
 
 	fpu__resume_cpu();
+
+	/* The processor is back on the direct GDT, load back the fixmap */
+	load_fixmap_gdt(cpu);
 }
 
 /**
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index ec1d5c46e58f..4951fcf95143 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -710,7 +710,7 @@ static void load_TLS_descriptor(struct thread_struct *t,
 
 	*shadow = t->tls_array[i];
 
-	gdt = get_cpu_gdt_table(cpu);
+	gdt = get_cpu_gdt_rw(cpu);
 	maddr = arbitrary_virt_to_machine(&gdt[GDT_ENTRY_TLS_MIN+i]);
 	mc = __xen_mc_entry(0);
 
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 0dee6f59ea82..6399bab936cd 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -391,7 +391,7 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
 	if (ctxt == NULL)
 		return -ENOMEM;
 
-	gdt = get_cpu_gdt_table(cpu);
+	gdt = get_cpu_gdt_rw(cpu);
 
 #ifdef CONFIG_X86_32
 	ctxt->user_regs.fs = __KERNEL_PERCPU;
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index d71f6323ac00..b4f79b923aea 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -504,7 +504,7 @@ void __init lguest_arch_host_init(void)
 		 * byte, not the size, hence the "-1").
 		 */
 		state->host_gdt_desc.size = GDT_SIZE-1;
-		state->host_gdt_desc.address = (long)get_cpu_gdt_table(i);
+		state->host_gdt_desc.address = (long)get_cpu_gdt_rw(i);
 
 		/*
 		 * All CPUs on the Host use the same Interrupt Descriptor
@@ -554,8 +554,8 @@ void __init lguest_arch_host_init(void)
 		 * The Host needs to be able to use the LGUEST segments on this
 		 * CPU, too, so put them in the Host GDT.
 		 */
-		get_cpu_gdt_table(i)[GDT_ENTRY_LGUEST_CS] = FULL_EXEC_SEGMENT;
-		get_cpu_gdt_table(i)[GDT_ENTRY_LGUEST_DS] = FULL_SEGMENT;
+		get_cpu_gdt_rw(i)[GDT_ENTRY_LGUEST_CS] = FULL_EXEC_SEGMENT;
+		get_cpu_gdt_rw(i)[GDT_ENTRY_LGUEST_DS] = FULL_SEGMENT;
 	}
 
 	/*
diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c
index 438d4c72c7b3..ff563db025b3 100644
--- a/drivers/pnp/pnpbios/bioscalls.c
+++ b/drivers/pnp/pnpbios/bioscalls.c
@@ -54,7 +54,7 @@ __asm__(".text			\n"
 
 #define Q2_SET_SEL(cpu, selname, address, size) \
 do { \
-	struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \
+	struct desc_struct *gdt = get_cpu_gdt_rw((cpu)); \
 	set_desc_base(&gdt[(selname) >> 3], (u32)(address)); \
 	set_desc_limit(&gdt[(selname) >> 3], (size) - 1); \
 } while(0)
@@ -95,8 +95,8 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3,
 		return PNP_FUNCTION_NOT_SUPPORTED;
 
 	cpu = get_cpu();
-	save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
-	get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
+	save_desc_40 = get_cpu_gdt_rw(cpu)[0x40 / 8];
+	get_cpu_gdt_rw(cpu)[0x40 / 8] = bad_bios_desc;
 
 	/* On some boxes IRQ's during PnP BIOS calls are deadly.  */
 	spin_lock_irqsave(&pnp_bios_lock, flags);
@@ -134,7 +134,7 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3,
 			     :"memory");
 	spin_unlock_irqrestore(&pnp_bios_lock, flags);
 
-	get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
+	get_cpu_gdt_rw(cpu)[0x40 / 8] = save_desc_40;
 	put_cpu();
 
 	/* If we get here and this is set then the PnP BIOS faulted on us. */
@@ -477,7 +477,7 @@ void pnpbios_calls_init(union pnp_bios_install_struct *header)
 	pnp_bios_callpoint.segment = PNP_CS16;
 
 	for_each_possible_cpu(i) {
-		struct desc_struct *gdt = get_cpu_gdt_table(i);
+		struct desc_struct *gdt = get_cpu_gdt_rw(i);
 		if (!gdt)
 			continue;
 		set_desc_base(&gdt[GDT_ENTRY_PNPBIOS_CS32],
-- 
2.11.0.483.g087da7b7c-goog


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 3/4] x86: Make the GDT remapping read-only on 64-bit
  2017-02-16 21:54 ` Thomas Garnier
  (?)
  (?)
@ 2017-02-16 21:54   ` Thomas Garnier
  -1 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-16 21:54 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H . Peter Anvin, Jonathan Corbet,
	Thomas Garnier, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He Chen, Luis R . Rodriguez, Stanislaw Gruszka,
	Arnd Bergmann, Peter Zijlstra, Dave Hansen, Vitaly Kuznetsov,
	Paul Gortmaker, Josh Poimboeuf, Tim Chen, Andi Kleen, Jiri Olsa,
	Michael Ellerman, Joerg Roedel, Paolo Bonzini,
	Radim Krčmář,
	Andy Lutomirski
  Cc: x86, linux-kernel, linux-doc, linux-pm, linux-efi, xen-devel,
	lguest, kvm, kernel-hardening

This patch makes the GDT remapped pages read-only to prevent corruption.
This change is done only on 64-bit.

The native_load_tr_desc function was adapted to correctly handle a
read-only GDT. The LTR instruction always writes to the GDT TSS entry.
This generates a page fault if the GDT is read-only. This change checks
if the current GDT is a remap and swap GDTs as needed. This function was
tested by booting multiple machines and checking hibernation works
properly.

KVM SVM and VMX were adapted to use the writeable GDT. On VMX, the
per-cpu variable was removed for functions to fetch the original GDT.
Instead of reloading the previous GDT, VMX will reload the fixmap GDT as
expected. For testing, VMs were started and restored on multiple
configurations.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170213
---
 arch/x86/include/asm/desc.h      | 51 ++++++++++++++++++++++++++++++++++++----
 arch/x86/include/asm/processor.h |  1 +
 arch/x86/kernel/cpu/common.c     | 28 +++++++++++++++++-----
 arch/x86/kvm/svm.c               |  4 +---
 arch/x86/kvm/vmx.c               | 15 ++++--------
 5 files changed, 75 insertions(+), 24 deletions(-)

diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
index 5d4ba1311737..15b2a86c9267 100644
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -57,6 +57,17 @@ static inline unsigned long get_cpu_gdt_rw_vaddr(unsigned int cpu)
 	return (unsigned long)get_cpu_gdt_rw(cpu);
 }
 
+/* Provide the current original GDT */
+static inline struct desc_struct *get_current_gdt_rw(void)
+{
+	return this_cpu_ptr(&gdt_page)->gdt;
+}
+
+static inline unsigned long get_current_gdt_rw_vaddr(void)
+{
+	return (unsigned long)get_current_gdt_rw();
+}
+
 /* Get the fixmap index for a specific processor */
 static inline unsigned int get_cpu_gdt_ro_index(int cpu)
 {
@@ -233,11 +244,6 @@ static inline void native_set_ldt(const void *addr, unsigned int entries)
 	}
 }
 
-static inline void native_load_tr_desc(void)
-{
-	asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
-}
-
 static inline void native_load_gdt(const struct desc_ptr *dtr)
 {
 	asm volatile("lgdt %0"::"m" (*dtr));
@@ -258,6 +264,41 @@ static inline void native_store_idt(struct desc_ptr *dtr)
 	asm volatile("sidt %0":"=m" (*dtr));
 }
 
+/*
+ * The LTR instruction marks the TSS GDT entry as busy. On 64-bit, the GDT is
+ * a read-only remapping. To prevent a page fault, the GDT is switched to the
+ * original writeable version when needed.
+ */
+#ifdef CONFIG_X86_64
+static inline void native_load_tr_desc(void)
+{
+	struct desc_ptr gdt;
+	int cpu = raw_smp_processor_id();
+	bool restore = 0;
+	struct desc_struct *fixmap_gdt;
+
+	native_store_gdt(&gdt);
+	fixmap_gdt = get_cpu_gdt_ro(cpu);
+
+	/*
+	 * If the current GDT is the read-only fixmap, swap to the original
+	 * writeable version. Swap back at the end.
+	 */
+	if (gdt.address == (unsigned long)fixmap_gdt) {
+		load_direct_gdt(cpu);
+		restore = 1;
+	}
+	asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
+	if (restore)
+		load_fixmap_gdt(cpu);
+}
+#else
+static inline void native_load_tr_desc(void)
+{
+	asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
+}
+#endif
+
 static inline unsigned long native_store_tr(void)
 {
 	unsigned long tr;
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index c441d1f7e275..6ea9e419a856 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -706,6 +706,7 @@ extern struct desc_ptr		early_gdt_descr;
 
 extern void cpu_set_gdt(int);
 extern void switch_to_new_gdt(int);
+extern void load_direct_gdt(int);
 extern void load_fixmap_gdt(int);
 extern void load_percpu_segment(int);
 extern void cpu_init(void);
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 2853a42ded2d..bdf521383900 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -444,13 +444,31 @@ void load_percpu_segment(int cpu)
 	load_stack_canary_segment();
 }
 
+/* On 64-bit the GDT remapping is read-only */
+#ifdef CONFIG_X86_64
+#define PAGE_FIXMAP_GDT PAGE_KERNEL_RO
+#else
+#define PAGE_FIXMAP_GDT PAGE_KERNEL
+#endif
+
 /* Setup the fixmap mapping only once per-processor */
 static inline void setup_fixmap_gdt(int cpu)
 {
 	__set_fixmap(get_cpu_gdt_ro_index(cpu),
-		     __pa(get_cpu_gdt_rw(cpu)), PAGE_KERNEL);
+		     __pa(get_cpu_gdt_rw(cpu)), PAGE_FIXMAP_GDT);
 }
 
+/* Load the original GDT from the per-cpu structure */
+void load_direct_gdt(int cpu)
+{
+	struct desc_ptr gdt_descr;
+
+	gdt_descr.address = (long)get_cpu_gdt_rw(cpu);
+	gdt_descr.size = GDT_SIZE - 1;
+	load_gdt(&gdt_descr);
+}
+EXPORT_SYMBOL_GPL(load_direct_gdt);
+
 /* Load a fixmap remapping of the per-cpu GDT */
 void load_fixmap_gdt(int cpu)
 {
@@ -460,6 +478,7 @@ void load_fixmap_gdt(int cpu)
 	gdt_descr.size = GDT_SIZE - 1;
 	load_gdt(&gdt_descr);
 }
+EXPORT_SYMBOL_GPL(load_fixmap_gdt);
 
 /*
  * Current gdt points %fs at the "master" per-cpu area: after this,
@@ -467,11 +486,8 @@ void load_fixmap_gdt(int cpu)
  */
 void switch_to_new_gdt(int cpu)
 {
-	struct desc_ptr gdt_descr;
-
-	gdt_descr.address = (long)get_cpu_gdt_rw(cpu);
-	gdt_descr.size = GDT_SIZE - 1;
-	load_gdt(&gdt_descr);
+	/* Load the original GDT */
+	load_direct_gdt(cpu);
 	/* Reload the per-cpu base */
 	load_percpu_segment(cpu);
 }
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index d0414f054bdf..7b9a71e465b1 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -741,7 +741,6 @@ static int svm_hardware_enable(void)
 
 	struct svm_cpu_data *sd;
 	uint64_t efer;
-	struct desc_ptr gdt_descr;
 	struct desc_struct *gdt;
 	int me = raw_smp_processor_id();
 
@@ -763,8 +762,7 @@ static int svm_hardware_enable(void)
 	sd->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1;
 	sd->next_asid = sd->max_asid + 1;
 
-	native_store_gdt(&gdt_descr);
-	gdt = (struct desc_struct *)gdt_descr.address;
+	gdt = get_current_gdt_rw();
 	sd->tss_desc = (struct kvm_ldttss_desc *)(gdt + GDT_ENTRY_TSS);
 
 	wrmsrl(MSR_EFER, efer | EFER_SVME);
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 7c3e42623090..99167f20bc34 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -935,7 +935,6 @@ static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
  * when a CPU is brought down, and we need to VMCLEAR all VMCSs loaded on it.
  */
 static DEFINE_PER_CPU(struct list_head, loaded_vmcss_on_cpu);
-static DEFINE_PER_CPU(struct desc_ptr, host_gdt);
 
 /*
  * We maintian a per-CPU linked-list of vCPU, so in wakeup_handler() we
@@ -1997,10 +1996,9 @@ static void reload_tss(void)
 	/*
 	 * VT restores TR but not its size.  Useless.
 	 */
-	struct desc_ptr *gdt = this_cpu_ptr(&host_gdt);
 	struct desc_struct *descs;
 
-	descs = (void *)gdt->address;
+	descs = get_current_gdt_rw();
 	descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
 	load_TR_desc();
 }
@@ -2061,7 +2059,6 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset)
 
 static unsigned long segment_base(u16 selector)
 {
-	struct desc_ptr *gdt = this_cpu_ptr(&host_gdt);
 	struct desc_struct *d;
 	unsigned long table_base;
 	unsigned long v;
@@ -2069,7 +2066,7 @@ static unsigned long segment_base(u16 selector)
 	if (!(selector & ~3))
 		return 0;
 
-	table_base = gdt->address;
+	table_base = get_current_gdt_rw_vaddr();
 
 	if (selector & 4) {           /* from ldt */
 		u16 ldt_selector = kvm_read_ldt();
@@ -2185,7 +2182,7 @@ static void __vmx_load_host_state(struct vcpu_vmx *vmx)
 #endif
 	if (vmx->host_state.msr_host_bndcfgs)
 		wrmsrl(MSR_IA32_BNDCFGS, vmx->host_state.msr_host_bndcfgs);
-	load_gdt(this_cpu_ptr(&host_gdt));
+	load_fixmap_gdt(raw_smp_processor_id());
 }
 
 static void vmx_load_host_state(struct vcpu_vmx *vmx)
@@ -2287,7 +2284,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 	}
 
 	if (!already_loaded) {
-		struct desc_ptr *gdt = this_cpu_ptr(&host_gdt);
+		unsigned long gdt = get_current_gdt_rw_vaddr();
 		unsigned long sysenter_esp;
 
 		kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
@@ -2297,7 +2294,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 		 * processors.
 		 */
 		vmcs_writel(HOST_TR_BASE, kvm_read_tr_base()); /* 22.2.4 */
-		vmcs_writel(HOST_GDTR_BASE, gdt->address);   /* 22.2.4 */
+		vmcs_writel(HOST_GDTR_BASE, gdt);   /* 22.2.4 */
 
 		rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp);
 		vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */
@@ -3523,8 +3520,6 @@ static int hardware_enable(void)
 		ept_sync_global();
 	}
 
-	native_store_gdt(this_cpu_ptr(&host_gdt));
-
 	return 0;
 }
 
-- 
2.11.0.483.g087da7b7c-goog

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 3/4] x86: Make the GDT remapping read-only on 64-bit
@ 2017-02-16 21:54   ` Thomas Garnier
  0 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-16 21:54 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H . Peter Anvin, Jonathan Corbet,
	Thomas Garnier, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He
  Cc: x86, linux-kernel, linux-doc, linux-pm, linux-efi, xen-devel,
	lguest, kvm, kernel-hardening

This patch makes the GDT remapped pages read-only to prevent corruption.
This change is done only on 64-bit.

The native_load_tr_desc function was adapted to correctly handle a
read-only GDT. The LTR instruction always writes to the GDT TSS entry.
This generates a page fault if the GDT is read-only. This change checks
if the current GDT is a remap and swap GDTs as needed. This function was
tested by booting multiple machines and checking hibernation works
properly.

KVM SVM and VMX were adapted to use the writeable GDT. On VMX, the
per-cpu variable was removed for functions to fetch the original GDT.
Instead of reloading the previous GDT, VMX will reload the fixmap GDT as
expected. For testing, VMs were started and restored on multiple
configurations.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170213
---
 arch/x86/include/asm/desc.h      | 51 ++++++++++++++++++++++++++++++++++++----
 arch/x86/include/asm/processor.h |  1 +
 arch/x86/kernel/cpu/common.c     | 28 +++++++++++++++++-----
 arch/x86/kvm/svm.c               |  4 +---
 arch/x86/kvm/vmx.c               | 15 ++++--------
 5 files changed, 75 insertions(+), 24 deletions(-)

diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
index 5d4ba1311737..15b2a86c9267 100644
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -57,6 +57,17 @@ static inline unsigned long get_cpu_gdt_rw_vaddr(unsigned int cpu)
 	return (unsigned long)get_cpu_gdt_rw(cpu);
 }
 
+/* Provide the current original GDT */
+static inline struct desc_struct *get_current_gdt_rw(void)
+{
+	return this_cpu_ptr(&gdt_page)->gdt;
+}
+
+static inline unsigned long get_current_gdt_rw_vaddr(void)
+{
+	return (unsigned long)get_current_gdt_rw();
+}
+
 /* Get the fixmap index for a specific processor */
 static inline unsigned int get_cpu_gdt_ro_index(int cpu)
 {
@@ -233,11 +244,6 @@ static inline void native_set_ldt(const void *addr, unsigned int entries)
 	}
 }
 
-static inline void native_load_tr_desc(void)
-{
-	asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
-}
-
 static inline void native_load_gdt(const struct desc_ptr *dtr)
 {
 	asm volatile("lgdt %0"::"m" (*dtr));
@@ -258,6 +264,41 @@ static inline void native_store_idt(struct desc_ptr *dtr)
 	asm volatile("sidt %0":"=m" (*dtr));
 }
 
+/*
+ * The LTR instruction marks the TSS GDT entry as busy. On 64-bit, the GDT is
+ * a read-only remapping. To prevent a page fault, the GDT is switched to the
+ * original writeable version when needed.
+ */
+#ifdef CONFIG_X86_64
+static inline void native_load_tr_desc(void)
+{
+	struct desc_ptr gdt;
+	int cpu = raw_smp_processor_id();
+	bool restore = 0;
+	struct desc_struct *fixmap_gdt;
+
+	native_store_gdt(&gdt);
+	fixmap_gdt = get_cpu_gdt_ro(cpu);
+
+	/*
+	 * If the current GDT is the read-only fixmap, swap to the original
+	 * writeable version. Swap back at the end.
+	 */
+	if (gdt.address == (unsigned long)fixmap_gdt) {
+		load_direct_gdt(cpu);
+		restore = 1;
+	}
+	asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
+	if (restore)
+		load_fixmap_gdt(cpu);
+}
+#else
+static inline void native_load_tr_desc(void)
+{
+	asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
+}
+#endif
+
 static inline unsigned long native_store_tr(void)
 {
 	unsigned long tr;
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index c441d1f7e275..6ea9e419a856 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -706,6 +706,7 @@ extern struct desc_ptr		early_gdt_descr;
 
 extern void cpu_set_gdt(int);
 extern void switch_to_new_gdt(int);
+extern void load_direct_gdt(int);
 extern void load_fixmap_gdt(int);
 extern void load_percpu_segment(int);
 extern void cpu_init(void);
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 2853a42ded2d..bdf521383900 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -444,13 +444,31 @@ void load_percpu_segment(int cpu)
 	load_stack_canary_segment();
 }
 
+/* On 64-bit the GDT remapping is read-only */
+#ifdef CONFIG_X86_64
+#define PAGE_FIXMAP_GDT PAGE_KERNEL_RO
+#else
+#define PAGE_FIXMAP_GDT PAGE_KERNEL
+#endif
+
 /* Setup the fixmap mapping only once per-processor */
 static inline void setup_fixmap_gdt(int cpu)
 {
 	__set_fixmap(get_cpu_gdt_ro_index(cpu),
-		     __pa(get_cpu_gdt_rw(cpu)), PAGE_KERNEL);
+		     __pa(get_cpu_gdt_rw(cpu)), PAGE_FIXMAP_GDT);
 }
 
+/* Load the original GDT from the per-cpu structure */
+void load_direct_gdt(int cpu)
+{
+	struct desc_ptr gdt_descr;
+
+	gdt_descr.address = (long)get_cpu_gdt_rw(cpu);
+	gdt_descr.size = GDT_SIZE - 1;
+	load_gdt(&gdt_descr);
+}
+EXPORT_SYMBOL_GPL(load_direct_gdt);
+
 /* Load a fixmap remapping of the per-cpu GDT */
 void load_fixmap_gdt(int cpu)
 {
@@ -460,6 +478,7 @@ void load_fixmap_gdt(int cpu)
 	gdt_descr.size = GDT_SIZE - 1;
 	load_gdt(&gdt_descr);
 }
+EXPORT_SYMBOL_GPL(load_fixmap_gdt);
 
 /*
  * Current gdt points %fs at the "master" per-cpu area: after this,
@@ -467,11 +486,8 @@ void load_fixmap_gdt(int cpu)
  */
 void switch_to_new_gdt(int cpu)
 {
-	struct desc_ptr gdt_descr;
-
-	gdt_descr.address = (long)get_cpu_gdt_rw(cpu);
-	gdt_descr.size = GDT_SIZE - 1;
-	load_gdt(&gdt_descr);
+	/* Load the original GDT */
+	load_direct_gdt(cpu);
 	/* Reload the per-cpu base */
 	load_percpu_segment(cpu);
 }
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index d0414f054bdf..7b9a71e465b1 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -741,7 +741,6 @@ static int svm_hardware_enable(void)
 
 	struct svm_cpu_data *sd;
 	uint64_t efer;
-	struct desc_ptr gdt_descr;
 	struct desc_struct *gdt;
 	int me = raw_smp_processor_id();
 
@@ -763,8 +762,7 @@ static int svm_hardware_enable(void)
 	sd->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1;
 	sd->next_asid = sd->max_asid + 1;
 
-	native_store_gdt(&gdt_descr);
-	gdt = (struct desc_struct *)gdt_descr.address;
+	gdt = get_current_gdt_rw();
 	sd->tss_desc = (struct kvm_ldttss_desc *)(gdt + GDT_ENTRY_TSS);
 
 	wrmsrl(MSR_EFER, efer | EFER_SVME);
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 7c3e42623090..99167f20bc34 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -935,7 +935,6 @@ static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
  * when a CPU is brought down, and we need to VMCLEAR all VMCSs loaded on it.
  */
 static DEFINE_PER_CPU(struct list_head, loaded_vmcss_on_cpu);
-static DEFINE_PER_CPU(struct desc_ptr, host_gdt);
 
 /*
  * We maintian a per-CPU linked-list of vCPU, so in wakeup_handler() we
@@ -1997,10 +1996,9 @@ static void reload_tss(void)
 	/*
 	 * VT restores TR but not its size.  Useless.
 	 */
-	struct desc_ptr *gdt = this_cpu_ptr(&host_gdt);
 	struct desc_struct *descs;
 
-	descs = (void *)gdt->address;
+	descs = get_current_gdt_rw();
 	descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
 	load_TR_desc();
 }
@@ -2061,7 +2059,6 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset)
 
 static unsigned long segment_base(u16 selector)
 {
-	struct desc_ptr *gdt = this_cpu_ptr(&host_gdt);
 	struct desc_struct *d;
 	unsigned long table_base;
 	unsigned long v;
@@ -2069,7 +2066,7 @@ static unsigned long segment_base(u16 selector)
 	if (!(selector & ~3))
 		return 0;
 
-	table_base = gdt->address;
+	table_base = get_current_gdt_rw_vaddr();
 
 	if (selector & 4) {           /* from ldt */
 		u16 ldt_selector = kvm_read_ldt();
@@ -2185,7 +2182,7 @@ static void __vmx_load_host_state(struct vcpu_vmx *vmx)
 #endif
 	if (vmx->host_state.msr_host_bndcfgs)
 		wrmsrl(MSR_IA32_BNDCFGS, vmx->host_state.msr_host_bndcfgs);
-	load_gdt(this_cpu_ptr(&host_gdt));
+	load_fixmap_gdt(raw_smp_processor_id());
 }
 
 static void vmx_load_host_state(struct vcpu_vmx *vmx)
@@ -2287,7 +2284,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 	}
 
 	if (!already_loaded) {
-		struct desc_ptr *gdt = this_cpu_ptr(&host_gdt);
+		unsigned long gdt = get_current_gdt_rw_vaddr();
 		unsigned long sysenter_esp;
 
 		kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
@@ -2297,7 +2294,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 		 * processors.
 		 */
 		vmcs_writel(HOST_TR_BASE, kvm_read_tr_base()); /* 22.2.4 */
-		vmcs_writel(HOST_GDTR_BASE, gdt->address);   /* 22.2.4 */
+		vmcs_writel(HOST_GDTR_BASE, gdt);   /* 22.2.4 */
 
 		rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp);
 		vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */
@@ -3523,8 +3520,6 @@ static int hardware_enable(void)
 		ept_sync_global();
 	}
 
-	native_store_gdt(this_cpu_ptr(&host_gdt));
-
 	return 0;
 }
 
-- 
2.11.0.483.g087da7b7c-goog


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 3/4] x86: Make the GDT remapping read-only on 64-bit
@ 2017-02-16 21:54   ` Thomas Garnier
  0 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-16 21:54 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H . Peter Anvin, Jonathan Corbet,
	Thomas Garnier, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He
  Cc: x86, linux-kernel, linux-doc, linux-pm, linux-efi, xen-devel,
	lguest, kvm, kernel-hardening

This patch makes the GDT remapped pages read-only to prevent corruption.
This change is done only on 64-bit.

The native_load_tr_desc function was adapted to correctly handle a
read-only GDT. The LTR instruction always writes to the GDT TSS entry.
This generates a page fault if the GDT is read-only. This change checks
if the current GDT is a remap and swap GDTs as needed. This function was
tested by booting multiple machines and checking hibernation works
properly.

KVM SVM and VMX were adapted to use the writeable GDT. On VMX, the
per-cpu variable was removed for functions to fetch the original GDT.
Instead of reloading the previous GDT, VMX will reload the fixmap GDT as
expected. For testing, VMs were started and restored on multiple
configurations.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170213
---
 arch/x86/include/asm/desc.h      | 51 ++++++++++++++++++++++++++++++++++++----
 arch/x86/include/asm/processor.h |  1 +
 arch/x86/kernel/cpu/common.c     | 28 +++++++++++++++++-----
 arch/x86/kvm/svm.c               |  4 +---
 arch/x86/kvm/vmx.c               | 15 ++++--------
 5 files changed, 75 insertions(+), 24 deletions(-)

diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
index 5d4ba1311737..15b2a86c9267 100644
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -57,6 +57,17 @@ static inline unsigned long get_cpu_gdt_rw_vaddr(unsigned int cpu)
 	return (unsigned long)get_cpu_gdt_rw(cpu);
 }
 
+/* Provide the current original GDT */
+static inline struct desc_struct *get_current_gdt_rw(void)
+{
+	return this_cpu_ptr(&gdt_page)->gdt;
+}
+
+static inline unsigned long get_current_gdt_rw_vaddr(void)
+{
+	return (unsigned long)get_current_gdt_rw();
+}
+
 /* Get the fixmap index for a specific processor */
 static inline unsigned int get_cpu_gdt_ro_index(int cpu)
 {
@@ -233,11 +244,6 @@ static inline void native_set_ldt(const void *addr, unsigned int entries)
 	}
 }
 
-static inline void native_load_tr_desc(void)
-{
-	asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
-}
-
 static inline void native_load_gdt(const struct desc_ptr *dtr)
 {
 	asm volatile("lgdt %0"::"m" (*dtr));
@@ -258,6 +264,41 @@ static inline void native_store_idt(struct desc_ptr *dtr)
 	asm volatile("sidt %0":"=m" (*dtr));
 }
 
+/*
+ * The LTR instruction marks the TSS GDT entry as busy. On 64-bit, the GDT is
+ * a read-only remapping. To prevent a page fault, the GDT is switched to the
+ * original writeable version when needed.
+ */
+#ifdef CONFIG_X86_64
+static inline void native_load_tr_desc(void)
+{
+	struct desc_ptr gdt;
+	int cpu = raw_smp_processor_id();
+	bool restore = 0;
+	struct desc_struct *fixmap_gdt;
+
+	native_store_gdt(&gdt);
+	fixmap_gdt = get_cpu_gdt_ro(cpu);
+
+	/*
+	 * If the current GDT is the read-only fixmap, swap to the original
+	 * writeable version. Swap back at the end.
+	 */
+	if (gdt.address == (unsigned long)fixmap_gdt) {
+		load_direct_gdt(cpu);
+		restore = 1;
+	}
+	asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
+	if (restore)
+		load_fixmap_gdt(cpu);
+}
+#else
+static inline void native_load_tr_desc(void)
+{
+	asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
+}
+#endif
+
 static inline unsigned long native_store_tr(void)
 {
 	unsigned long tr;
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index c441d1f7e275..6ea9e419a856 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -706,6 +706,7 @@ extern struct desc_ptr		early_gdt_descr;
 
 extern void cpu_set_gdt(int);
 extern void switch_to_new_gdt(int);
+extern void load_direct_gdt(int);
 extern void load_fixmap_gdt(int);
 extern void load_percpu_segment(int);
 extern void cpu_init(void);
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 2853a42ded2d..bdf521383900 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -444,13 +444,31 @@ void load_percpu_segment(int cpu)
 	load_stack_canary_segment();
 }
 
+/* On 64-bit the GDT remapping is read-only */
+#ifdef CONFIG_X86_64
+#define PAGE_FIXMAP_GDT PAGE_KERNEL_RO
+#else
+#define PAGE_FIXMAP_GDT PAGE_KERNEL
+#endif
+
 /* Setup the fixmap mapping only once per-processor */
 static inline void setup_fixmap_gdt(int cpu)
 {
 	__set_fixmap(get_cpu_gdt_ro_index(cpu),
-		     __pa(get_cpu_gdt_rw(cpu)), PAGE_KERNEL);
+		     __pa(get_cpu_gdt_rw(cpu)), PAGE_FIXMAP_GDT);
 }
 
+/* Load the original GDT from the per-cpu structure */
+void load_direct_gdt(int cpu)
+{
+	struct desc_ptr gdt_descr;
+
+	gdt_descr.address = (long)get_cpu_gdt_rw(cpu);
+	gdt_descr.size = GDT_SIZE - 1;
+	load_gdt(&gdt_descr);
+}
+EXPORT_SYMBOL_GPL(load_direct_gdt);
+
 /* Load a fixmap remapping of the per-cpu GDT */
 void load_fixmap_gdt(int cpu)
 {
@@ -460,6 +478,7 @@ void load_fixmap_gdt(int cpu)
 	gdt_descr.size = GDT_SIZE - 1;
 	load_gdt(&gdt_descr);
 }
+EXPORT_SYMBOL_GPL(load_fixmap_gdt);
 
 /*
  * Current gdt points %fs at the "master" per-cpu area: after this,
@@ -467,11 +486,8 @@ void load_fixmap_gdt(int cpu)
  */
 void switch_to_new_gdt(int cpu)
 {
-	struct desc_ptr gdt_descr;
-
-	gdt_descr.address = (long)get_cpu_gdt_rw(cpu);
-	gdt_descr.size = GDT_SIZE - 1;
-	load_gdt(&gdt_descr);
+	/* Load the original GDT */
+	load_direct_gdt(cpu);
 	/* Reload the per-cpu base */
 	load_percpu_segment(cpu);
 }
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index d0414f054bdf..7b9a71e465b1 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -741,7 +741,6 @@ static int svm_hardware_enable(void)
 
 	struct svm_cpu_data *sd;
 	uint64_t efer;
-	struct desc_ptr gdt_descr;
 	struct desc_struct *gdt;
 	int me = raw_smp_processor_id();
 
@@ -763,8 +762,7 @@ static int svm_hardware_enable(void)
 	sd->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1;
 	sd->next_asid = sd->max_asid + 1;
 
-	native_store_gdt(&gdt_descr);
-	gdt = (struct desc_struct *)gdt_descr.address;
+	gdt = get_current_gdt_rw();
 	sd->tss_desc = (struct kvm_ldttss_desc *)(gdt + GDT_ENTRY_TSS);
 
 	wrmsrl(MSR_EFER, efer | EFER_SVME);
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 7c3e42623090..99167f20bc34 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -935,7 +935,6 @@ static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
  * when a CPU is brought down, and we need to VMCLEAR all VMCSs loaded on it.
  */
 static DEFINE_PER_CPU(struct list_head, loaded_vmcss_on_cpu);
-static DEFINE_PER_CPU(struct desc_ptr, host_gdt);
 
 /*
  * We maintian a per-CPU linked-list of vCPU, so in wakeup_handler() we
@@ -1997,10 +1996,9 @@ static void reload_tss(void)
 	/*
 	 * VT restores TR but not its size.  Useless.
 	 */
-	struct desc_ptr *gdt = this_cpu_ptr(&host_gdt);
 	struct desc_struct *descs;
 
-	descs = (void *)gdt->address;
+	descs = get_current_gdt_rw();
 	descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
 	load_TR_desc();
 }
@@ -2061,7 +2059,6 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset)
 
 static unsigned long segment_base(u16 selector)
 {
-	struct desc_ptr *gdt = this_cpu_ptr(&host_gdt);
 	struct desc_struct *d;
 	unsigned long table_base;
 	unsigned long v;
@@ -2069,7 +2066,7 @@ static unsigned long segment_base(u16 selector)
 	if (!(selector & ~3))
 		return 0;
 
-	table_base = gdt->address;
+	table_base = get_current_gdt_rw_vaddr();
 
 	if (selector & 4) {           /* from ldt */
 		u16 ldt_selector = kvm_read_ldt();
@@ -2185,7 +2182,7 @@ static void __vmx_load_host_state(struct vcpu_vmx *vmx)
 #endif
 	if (vmx->host_state.msr_host_bndcfgs)
 		wrmsrl(MSR_IA32_BNDCFGS, vmx->host_state.msr_host_bndcfgs);
-	load_gdt(this_cpu_ptr(&host_gdt));
+	load_fixmap_gdt(raw_smp_processor_id());
 }
 
 static void vmx_load_host_state(struct vcpu_vmx *vmx)
@@ -2287,7 +2284,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 	}
 
 	if (!already_loaded) {
-		struct desc_ptr *gdt = this_cpu_ptr(&host_gdt);
+		unsigned long gdt = get_current_gdt_rw_vaddr();
 		unsigned long sysenter_esp;
 
 		kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
@@ -2297,7 +2294,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 		 * processors.
 		 */
 		vmcs_writel(HOST_TR_BASE, kvm_read_tr_base()); /* 22.2.4 */
-		vmcs_writel(HOST_GDTR_BASE, gdt->address);   /* 22.2.4 */
+		vmcs_writel(HOST_GDTR_BASE, gdt);   /* 22.2.4 */
 
 		rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp);
 		vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */
@@ -3523,8 +3520,6 @@ static int hardware_enable(void)
 		ept_sync_global();
 	}
 
-	native_store_gdt(this_cpu_ptr(&host_gdt));
-
 	return 0;
 }
 
-- 
2.11.0.483.g087da7b7c-goog


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [kernel-hardening] [PATCH v4 3/4] x86: Make the GDT remapping read-only on 64-bit
@ 2017-02-16 21:54   ` Thomas Garnier
  0 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-16 21:54 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H . Peter Anvin, Jonathan Corbet,
	Thomas Garnier, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He Chen, Luis R . Rodriguez, Stanislaw Gruszka,
	Arnd Bergmann, Peter Zijlstra, Dave Hansen, Vitaly Kuznetsov,
	Paul Gortmaker, Josh Poimboeuf, Tim Chen, Andi Kleen, Jiri Olsa,
	Michael Ellerman, Joerg Roedel, Paolo Bonzini,
	Radim Krčmář,
	Andy Lutomirski
  Cc: x86, linux-kernel, linux-doc, linux-pm, linux-efi, xen-devel,
	lguest, kvm, kernel-hardening

This patch makes the GDT remapped pages read-only to prevent corruption.
This change is done only on 64-bit.

The native_load_tr_desc function was adapted to correctly handle a
read-only GDT. The LTR instruction always writes to the GDT TSS entry.
This generates a page fault if the GDT is read-only. This change checks
if the current GDT is a remap and swap GDTs as needed. This function was
tested by booting multiple machines and checking hibernation works
properly.

KVM SVM and VMX were adapted to use the writeable GDT. On VMX, the
per-cpu variable was removed for functions to fetch the original GDT.
Instead of reloading the previous GDT, VMX will reload the fixmap GDT as
expected. For testing, VMs were started and restored on multiple
configurations.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170213
---
 arch/x86/include/asm/desc.h      | 51 ++++++++++++++++++++++++++++++++++++----
 arch/x86/include/asm/processor.h |  1 +
 arch/x86/kernel/cpu/common.c     | 28 +++++++++++++++++-----
 arch/x86/kvm/svm.c               |  4 +---
 arch/x86/kvm/vmx.c               | 15 ++++--------
 5 files changed, 75 insertions(+), 24 deletions(-)

diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
index 5d4ba1311737..15b2a86c9267 100644
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -57,6 +57,17 @@ static inline unsigned long get_cpu_gdt_rw_vaddr(unsigned int cpu)
 	return (unsigned long)get_cpu_gdt_rw(cpu);
 }
 
+/* Provide the current original GDT */
+static inline struct desc_struct *get_current_gdt_rw(void)
+{
+	return this_cpu_ptr(&gdt_page)->gdt;
+}
+
+static inline unsigned long get_current_gdt_rw_vaddr(void)
+{
+	return (unsigned long)get_current_gdt_rw();
+}
+
 /* Get the fixmap index for a specific processor */
 static inline unsigned int get_cpu_gdt_ro_index(int cpu)
 {
@@ -233,11 +244,6 @@ static inline void native_set_ldt(const void *addr, unsigned int entries)
 	}
 }
 
-static inline void native_load_tr_desc(void)
-{
-	asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
-}
-
 static inline void native_load_gdt(const struct desc_ptr *dtr)
 {
 	asm volatile("lgdt %0"::"m" (*dtr));
@@ -258,6 +264,41 @@ static inline void native_store_idt(struct desc_ptr *dtr)
 	asm volatile("sidt %0":"=m" (*dtr));
 }
 
+/*
+ * The LTR instruction marks the TSS GDT entry as busy. On 64-bit, the GDT is
+ * a read-only remapping. To prevent a page fault, the GDT is switched to the
+ * original writeable version when needed.
+ */
+#ifdef CONFIG_X86_64
+static inline void native_load_tr_desc(void)
+{
+	struct desc_ptr gdt;
+	int cpu = raw_smp_processor_id();
+	bool restore = 0;
+	struct desc_struct *fixmap_gdt;
+
+	native_store_gdt(&gdt);
+	fixmap_gdt = get_cpu_gdt_ro(cpu);
+
+	/*
+	 * If the current GDT is the read-only fixmap, swap to the original
+	 * writeable version. Swap back at the end.
+	 */
+	if (gdt.address == (unsigned long)fixmap_gdt) {
+		load_direct_gdt(cpu);
+		restore = 1;
+	}
+	asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
+	if (restore)
+		load_fixmap_gdt(cpu);
+}
+#else
+static inline void native_load_tr_desc(void)
+{
+	asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
+}
+#endif
+
 static inline unsigned long native_store_tr(void)
 {
 	unsigned long tr;
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index c441d1f7e275..6ea9e419a856 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -706,6 +706,7 @@ extern struct desc_ptr		early_gdt_descr;
 
 extern void cpu_set_gdt(int);
 extern void switch_to_new_gdt(int);
+extern void load_direct_gdt(int);
 extern void load_fixmap_gdt(int);
 extern void load_percpu_segment(int);
 extern void cpu_init(void);
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 2853a42ded2d..bdf521383900 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -444,13 +444,31 @@ void load_percpu_segment(int cpu)
 	load_stack_canary_segment();
 }
 
+/* On 64-bit the GDT remapping is read-only */
+#ifdef CONFIG_X86_64
+#define PAGE_FIXMAP_GDT PAGE_KERNEL_RO
+#else
+#define PAGE_FIXMAP_GDT PAGE_KERNEL
+#endif
+
 /* Setup the fixmap mapping only once per-processor */
 static inline void setup_fixmap_gdt(int cpu)
 {
 	__set_fixmap(get_cpu_gdt_ro_index(cpu),
-		     __pa(get_cpu_gdt_rw(cpu)), PAGE_KERNEL);
+		     __pa(get_cpu_gdt_rw(cpu)), PAGE_FIXMAP_GDT);
 }
 
+/* Load the original GDT from the per-cpu structure */
+void load_direct_gdt(int cpu)
+{
+	struct desc_ptr gdt_descr;
+
+	gdt_descr.address = (long)get_cpu_gdt_rw(cpu);
+	gdt_descr.size = GDT_SIZE - 1;
+	load_gdt(&gdt_descr);
+}
+EXPORT_SYMBOL_GPL(load_direct_gdt);
+
 /* Load a fixmap remapping of the per-cpu GDT */
 void load_fixmap_gdt(int cpu)
 {
@@ -460,6 +478,7 @@ void load_fixmap_gdt(int cpu)
 	gdt_descr.size = GDT_SIZE - 1;
 	load_gdt(&gdt_descr);
 }
+EXPORT_SYMBOL_GPL(load_fixmap_gdt);
 
 /*
  * Current gdt points %fs at the "master" per-cpu area: after this,
@@ -467,11 +486,8 @@ void load_fixmap_gdt(int cpu)
  */
 void switch_to_new_gdt(int cpu)
 {
-	struct desc_ptr gdt_descr;
-
-	gdt_descr.address = (long)get_cpu_gdt_rw(cpu);
-	gdt_descr.size = GDT_SIZE - 1;
-	load_gdt(&gdt_descr);
+	/* Load the original GDT */
+	load_direct_gdt(cpu);
 	/* Reload the per-cpu base */
 	load_percpu_segment(cpu);
 }
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index d0414f054bdf..7b9a71e465b1 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -741,7 +741,6 @@ static int svm_hardware_enable(void)
 
 	struct svm_cpu_data *sd;
 	uint64_t efer;
-	struct desc_ptr gdt_descr;
 	struct desc_struct *gdt;
 	int me = raw_smp_processor_id();
 
@@ -763,8 +762,7 @@ static int svm_hardware_enable(void)
 	sd->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1;
 	sd->next_asid = sd->max_asid + 1;
 
-	native_store_gdt(&gdt_descr);
-	gdt = (struct desc_struct *)gdt_descr.address;
+	gdt = get_current_gdt_rw();
 	sd->tss_desc = (struct kvm_ldttss_desc *)(gdt + GDT_ENTRY_TSS);
 
 	wrmsrl(MSR_EFER, efer | EFER_SVME);
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 7c3e42623090..99167f20bc34 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -935,7 +935,6 @@ static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
  * when a CPU is brought down, and we need to VMCLEAR all VMCSs loaded on it.
  */
 static DEFINE_PER_CPU(struct list_head, loaded_vmcss_on_cpu);
-static DEFINE_PER_CPU(struct desc_ptr, host_gdt);
 
 /*
  * We maintian a per-CPU linked-list of vCPU, so in wakeup_handler() we
@@ -1997,10 +1996,9 @@ static void reload_tss(void)
 	/*
 	 * VT restores TR but not its size.  Useless.
 	 */
-	struct desc_ptr *gdt = this_cpu_ptr(&host_gdt);
 	struct desc_struct *descs;
 
-	descs = (void *)gdt->address;
+	descs = get_current_gdt_rw();
 	descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
 	load_TR_desc();
 }
@@ -2061,7 +2059,6 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset)
 
 static unsigned long segment_base(u16 selector)
 {
-	struct desc_ptr *gdt = this_cpu_ptr(&host_gdt);
 	struct desc_struct *d;
 	unsigned long table_base;
 	unsigned long v;
@@ -2069,7 +2066,7 @@ static unsigned long segment_base(u16 selector)
 	if (!(selector & ~3))
 		return 0;
 
-	table_base = gdt->address;
+	table_base = get_current_gdt_rw_vaddr();
 
 	if (selector & 4) {           /* from ldt */
 		u16 ldt_selector = kvm_read_ldt();
@@ -2185,7 +2182,7 @@ static void __vmx_load_host_state(struct vcpu_vmx *vmx)
 #endif
 	if (vmx->host_state.msr_host_bndcfgs)
 		wrmsrl(MSR_IA32_BNDCFGS, vmx->host_state.msr_host_bndcfgs);
-	load_gdt(this_cpu_ptr(&host_gdt));
+	load_fixmap_gdt(raw_smp_processor_id());
 }
 
 static void vmx_load_host_state(struct vcpu_vmx *vmx)
@@ -2287,7 +2284,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 	}
 
 	if (!already_loaded) {
-		struct desc_ptr *gdt = this_cpu_ptr(&host_gdt);
+		unsigned long gdt = get_current_gdt_rw_vaddr();
 		unsigned long sysenter_esp;
 
 		kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
@@ -2297,7 +2294,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 		 * processors.
 		 */
 		vmcs_writel(HOST_TR_BASE, kvm_read_tr_base()); /* 22.2.4 */
-		vmcs_writel(HOST_GDTR_BASE, gdt->address);   /* 22.2.4 */
+		vmcs_writel(HOST_GDTR_BASE, gdt);   /* 22.2.4 */
 
 		rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp);
 		vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */
@@ -3523,8 +3520,6 @@ static int hardware_enable(void)
 		ept_sync_global();
 	}
 
-	native_store_gdt(this_cpu_ptr(&host_gdt));
-
 	return 0;
 }
 
-- 
2.11.0.483.g087da7b7c-goog

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 3/4] x86: Make the GDT remapping read-only on 64-bit
  2017-02-16 21:54 ` Thomas Garnier
                   ` (4 preceding siblings ...)
  (?)
@ 2017-02-16 21:54 ` Thomas Garnier
  -1 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-16 21:54 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H . Peter Anvin, Jonathan Corbet,
	Thomas Garnier, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He Chen, Luis R . Rodriguez, Stanislaw Gruszka,
	Arnd Bergmann
  Cc: linux-efi, kvm, linux-pm, x86, linux-doc, linux-kernel, lguest,
	kernel-hardening, xen-devel

This patch makes the GDT remapped pages read-only to prevent corruption.
This change is done only on 64-bit.

The native_load_tr_desc function was adapted to correctly handle a
read-only GDT. The LTR instruction always writes to the GDT TSS entry.
This generates a page fault if the GDT is read-only. This change checks
if the current GDT is a remap and swap GDTs as needed. This function was
tested by booting multiple machines and checking hibernation works
properly.

KVM SVM and VMX were adapted to use the writeable GDT. On VMX, the
per-cpu variable was removed for functions to fetch the original GDT.
Instead of reloading the previous GDT, VMX will reload the fixmap GDT as
expected. For testing, VMs were started and restored on multiple
configurations.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170213
---
 arch/x86/include/asm/desc.h      | 51 ++++++++++++++++++++++++++++++++++++----
 arch/x86/include/asm/processor.h |  1 +
 arch/x86/kernel/cpu/common.c     | 28 +++++++++++++++++-----
 arch/x86/kvm/svm.c               |  4 +---
 arch/x86/kvm/vmx.c               | 15 ++++--------
 5 files changed, 75 insertions(+), 24 deletions(-)

diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
index 5d4ba1311737..15b2a86c9267 100644
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -57,6 +57,17 @@ static inline unsigned long get_cpu_gdt_rw_vaddr(unsigned int cpu)
 	return (unsigned long)get_cpu_gdt_rw(cpu);
 }
 
+/* Provide the current original GDT */
+static inline struct desc_struct *get_current_gdt_rw(void)
+{
+	return this_cpu_ptr(&gdt_page)->gdt;
+}
+
+static inline unsigned long get_current_gdt_rw_vaddr(void)
+{
+	return (unsigned long)get_current_gdt_rw();
+}
+
 /* Get the fixmap index for a specific processor */
 static inline unsigned int get_cpu_gdt_ro_index(int cpu)
 {
@@ -233,11 +244,6 @@ static inline void native_set_ldt(const void *addr, unsigned int entries)
 	}
 }
 
-static inline void native_load_tr_desc(void)
-{
-	asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
-}
-
 static inline void native_load_gdt(const struct desc_ptr *dtr)
 {
 	asm volatile("lgdt %0"::"m" (*dtr));
@@ -258,6 +264,41 @@ static inline void native_store_idt(struct desc_ptr *dtr)
 	asm volatile("sidt %0":"=m" (*dtr));
 }
 
+/*
+ * The LTR instruction marks the TSS GDT entry as busy. On 64-bit, the GDT is
+ * a read-only remapping. To prevent a page fault, the GDT is switched to the
+ * original writeable version when needed.
+ */
+#ifdef CONFIG_X86_64
+static inline void native_load_tr_desc(void)
+{
+	struct desc_ptr gdt;
+	int cpu = raw_smp_processor_id();
+	bool restore = 0;
+	struct desc_struct *fixmap_gdt;
+
+	native_store_gdt(&gdt);
+	fixmap_gdt = get_cpu_gdt_ro(cpu);
+
+	/*
+	 * If the current GDT is the read-only fixmap, swap to the original
+	 * writeable version. Swap back at the end.
+	 */
+	if (gdt.address == (unsigned long)fixmap_gdt) {
+		load_direct_gdt(cpu);
+		restore = 1;
+	}
+	asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
+	if (restore)
+		load_fixmap_gdt(cpu);
+}
+#else
+static inline void native_load_tr_desc(void)
+{
+	asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
+}
+#endif
+
 static inline unsigned long native_store_tr(void)
 {
 	unsigned long tr;
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index c441d1f7e275..6ea9e419a856 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -706,6 +706,7 @@ extern struct desc_ptr		early_gdt_descr;
 
 extern void cpu_set_gdt(int);
 extern void switch_to_new_gdt(int);
+extern void load_direct_gdt(int);
 extern void load_fixmap_gdt(int);
 extern void load_percpu_segment(int);
 extern void cpu_init(void);
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 2853a42ded2d..bdf521383900 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -444,13 +444,31 @@ void load_percpu_segment(int cpu)
 	load_stack_canary_segment();
 }
 
+/* On 64-bit the GDT remapping is read-only */
+#ifdef CONFIG_X86_64
+#define PAGE_FIXMAP_GDT PAGE_KERNEL_RO
+#else
+#define PAGE_FIXMAP_GDT PAGE_KERNEL
+#endif
+
 /* Setup the fixmap mapping only once per-processor */
 static inline void setup_fixmap_gdt(int cpu)
 {
 	__set_fixmap(get_cpu_gdt_ro_index(cpu),
-		     __pa(get_cpu_gdt_rw(cpu)), PAGE_KERNEL);
+		     __pa(get_cpu_gdt_rw(cpu)), PAGE_FIXMAP_GDT);
 }
 
+/* Load the original GDT from the per-cpu structure */
+void load_direct_gdt(int cpu)
+{
+	struct desc_ptr gdt_descr;
+
+	gdt_descr.address = (long)get_cpu_gdt_rw(cpu);
+	gdt_descr.size = GDT_SIZE - 1;
+	load_gdt(&gdt_descr);
+}
+EXPORT_SYMBOL_GPL(load_direct_gdt);
+
 /* Load a fixmap remapping of the per-cpu GDT */
 void load_fixmap_gdt(int cpu)
 {
@@ -460,6 +478,7 @@ void load_fixmap_gdt(int cpu)
 	gdt_descr.size = GDT_SIZE - 1;
 	load_gdt(&gdt_descr);
 }
+EXPORT_SYMBOL_GPL(load_fixmap_gdt);
 
 /*
  * Current gdt points %fs at the "master" per-cpu area: after this,
@@ -467,11 +486,8 @@ void load_fixmap_gdt(int cpu)
  */
 void switch_to_new_gdt(int cpu)
 {
-	struct desc_ptr gdt_descr;
-
-	gdt_descr.address = (long)get_cpu_gdt_rw(cpu);
-	gdt_descr.size = GDT_SIZE - 1;
-	load_gdt(&gdt_descr);
+	/* Load the original GDT */
+	load_direct_gdt(cpu);
 	/* Reload the per-cpu base */
 	load_percpu_segment(cpu);
 }
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index d0414f054bdf..7b9a71e465b1 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -741,7 +741,6 @@ static int svm_hardware_enable(void)
 
 	struct svm_cpu_data *sd;
 	uint64_t efer;
-	struct desc_ptr gdt_descr;
 	struct desc_struct *gdt;
 	int me = raw_smp_processor_id();
 
@@ -763,8 +762,7 @@ static int svm_hardware_enable(void)
 	sd->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1;
 	sd->next_asid = sd->max_asid + 1;
 
-	native_store_gdt(&gdt_descr);
-	gdt = (struct desc_struct *)gdt_descr.address;
+	gdt = get_current_gdt_rw();
 	sd->tss_desc = (struct kvm_ldttss_desc *)(gdt + GDT_ENTRY_TSS);
 
 	wrmsrl(MSR_EFER, efer | EFER_SVME);
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 7c3e42623090..99167f20bc34 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -935,7 +935,6 @@ static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
  * when a CPU is brought down, and we need to VMCLEAR all VMCSs loaded on it.
  */
 static DEFINE_PER_CPU(struct list_head, loaded_vmcss_on_cpu);
-static DEFINE_PER_CPU(struct desc_ptr, host_gdt);
 
 /*
  * We maintian a per-CPU linked-list of vCPU, so in wakeup_handler() we
@@ -1997,10 +1996,9 @@ static void reload_tss(void)
 	/*
 	 * VT restores TR but not its size.  Useless.
 	 */
-	struct desc_ptr *gdt = this_cpu_ptr(&host_gdt);
 	struct desc_struct *descs;
 
-	descs = (void *)gdt->address;
+	descs = get_current_gdt_rw();
 	descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
 	load_TR_desc();
 }
@@ -2061,7 +2059,6 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset)
 
 static unsigned long segment_base(u16 selector)
 {
-	struct desc_ptr *gdt = this_cpu_ptr(&host_gdt);
 	struct desc_struct *d;
 	unsigned long table_base;
 	unsigned long v;
@@ -2069,7 +2066,7 @@ static unsigned long segment_base(u16 selector)
 	if (!(selector & ~3))
 		return 0;
 
-	table_base = gdt->address;
+	table_base = get_current_gdt_rw_vaddr();
 
 	if (selector & 4) {           /* from ldt */
 		u16 ldt_selector = kvm_read_ldt();
@@ -2185,7 +2182,7 @@ static void __vmx_load_host_state(struct vcpu_vmx *vmx)
 #endif
 	if (vmx->host_state.msr_host_bndcfgs)
 		wrmsrl(MSR_IA32_BNDCFGS, vmx->host_state.msr_host_bndcfgs);
-	load_gdt(this_cpu_ptr(&host_gdt));
+	load_fixmap_gdt(raw_smp_processor_id());
 }
 
 static void vmx_load_host_state(struct vcpu_vmx *vmx)
@@ -2287,7 +2284,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 	}
 
 	if (!already_loaded) {
-		struct desc_ptr *gdt = this_cpu_ptr(&host_gdt);
+		unsigned long gdt = get_current_gdt_rw_vaddr();
 		unsigned long sysenter_esp;
 
 		kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
@@ -2297,7 +2294,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 		 * processors.
 		 */
 		vmcs_writel(HOST_TR_BASE, kvm_read_tr_base()); /* 22.2.4 */
-		vmcs_writel(HOST_GDTR_BASE, gdt->address);   /* 22.2.4 */
+		vmcs_writel(HOST_GDTR_BASE, gdt);   /* 22.2.4 */
 
 		rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp);
 		vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */
@@ -3523,8 +3520,6 @@ static int hardware_enable(void)
 		ept_sync_global();
 	}
 
-	native_store_gdt(this_cpu_ptr(&host_gdt));
-
 	return 0;
 }
 
-- 
2.11.0.483.g087da7b7c-goog


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 4/4] KVM: VMX: Simplify segment_base
  2017-02-16 21:54 ` Thomas Garnier
  (?)
  (?)
@ 2017-02-16 21:54   ` Thomas Garnier
  -1 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-16 21:54 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H . Peter Anvin, Jonathan Corbet,
	Thomas Garnier, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He Chen, Luis R . Rodriguez, Stanislaw Gruszka,
	Arnd Bergmann, Peter Zijlstra, Dave Hansen, Vitaly Kuznetsov,
	Paul Gortmaker, Josh Poimboeuf, Tim Chen, Andi Kleen, Jiri Olsa,
	Michael Ellerman, Joerg Roedel, Paolo Bonzini,
	Radim Krčmář,
	Andy Lutomirski
  Cc: x86, linux-kernel, linux-doc, linux-pm, linux-efi, xen-devel,
	lguest, kvm, kernel-hardening

The KVM segment_base function is confusing. This patch replaces integers
with appropriate flags, simplify constructs and add comments.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170213
---
 arch/x86/kvm/vmx.c | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 99167f20bc34..91e619269128 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2060,27 +2060,37 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset)
 static unsigned long segment_base(u16 selector)
 {
 	struct desc_struct *d;
-	unsigned long table_base;
+	struct desc_struct *table_base;
 	unsigned long v;
+	u32 high32;
 
-	if (!(selector & ~3))
+	if (!(selector & ~SEGMENT_RPL_MASK))
 		return 0;
 
-	table_base = get_current_gdt_rw_vaddr();
-
-	if (selector & 4) {           /* from ldt */
+	/* LDT selector */
+	if ((selector & SEGMENT_TI_MASK) == SEGMENT_LDT) {
 		u16 ldt_selector = kvm_read_ldt();
 
-		if (!(ldt_selector & ~3))
+		if (!(ldt_selector & ~SEGMENT_RPL_MASK))
 			return 0;
 
-		table_base = segment_base(ldt_selector);
+		table_base = (struct desc_struct *)segment_base(ldt_selector);
+	} else {
+		table_base = get_current_gdt_rw();
 	}
-	d = (struct desc_struct *)(table_base + (selector & ~7));
+
+	d = table_base + (selector >> 3);
 	v = get_desc_base(d);
 #ifdef CONFIG_X86_64
-       if (d->s == 0 && (d->type == 2 || d->type == 9 || d->type == 11))
-               v |= ((unsigned long)((struct ldttss_desc64 *)d)->base3) << 32;
+	/*
+	 * Extend the virtual address if we have a system descriptor entry for
+	 * LDT or TSS (available or busy).
+	 */
+	if (d->s == 0 && (d->type == DESC_LDT || d->type == DESC_TSS ||
+			  d->type == 11/*Busy TSS */)) {
+		high32 = ((struct ldttss_desc64 *)d)->base3;
+		v |= (u64)high32 << 32;
+	}
 #endif
 	return v;
 }
-- 
2.11.0.483.g087da7b7c-goog

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 4/4] KVM: VMX: Simplify segment_base
@ 2017-02-16 21:54   ` Thomas Garnier
  0 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-16 21:54 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H . Peter Anvin, Jonathan Corbet,
	Thomas Garnier, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He
  Cc: x86, linux-kernel, linux-doc, linux-pm, linux-efi, xen-devel,
	lguest, kvm, kernel-hardening

The KVM segment_base function is confusing. This patch replaces integers
with appropriate flags, simplify constructs and add comments.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170213
---
 arch/x86/kvm/vmx.c | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 99167f20bc34..91e619269128 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2060,27 +2060,37 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset)
 static unsigned long segment_base(u16 selector)
 {
 	struct desc_struct *d;
-	unsigned long table_base;
+	struct desc_struct *table_base;
 	unsigned long v;
+	u32 high32;
 
-	if (!(selector & ~3))
+	if (!(selector & ~SEGMENT_RPL_MASK))
 		return 0;
 
-	table_base = get_current_gdt_rw_vaddr();
-
-	if (selector & 4) {           /* from ldt */
+	/* LDT selector */
+	if ((selector & SEGMENT_TI_MASK) == SEGMENT_LDT) {
 		u16 ldt_selector = kvm_read_ldt();
 
-		if (!(ldt_selector & ~3))
+		if (!(ldt_selector & ~SEGMENT_RPL_MASK))
 			return 0;
 
-		table_base = segment_base(ldt_selector);
+		table_base = (struct desc_struct *)segment_base(ldt_selector);
+	} else {
+		table_base = get_current_gdt_rw();
 	}
-	d = (struct desc_struct *)(table_base + (selector & ~7));
+
+	d = table_base + (selector >> 3);
 	v = get_desc_base(d);
 #ifdef CONFIG_X86_64
-       if (d->s == 0 && (d->type == 2 || d->type == 9 || d->type == 11))
-               v |= ((unsigned long)((struct ldttss_desc64 *)d)->base3) << 32;
+	/*
+	 * Extend the virtual address if we have a system descriptor entry for
+	 * LDT or TSS (available or busy).
+	 */
+	if (d->s == 0 && (d->type == DESC_LDT || d->type == DESC_TSS ||
+			  d->type == 11/*Busy TSS */)) {
+		high32 = ((struct ldttss_desc64 *)d)->base3;
+		v |= (u64)high32 << 32;
+	}
 #endif
 	return v;
 }
-- 
2.11.0.483.g087da7b7c-goog

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 4/4] KVM: VMX: Simplify segment_base
@ 2017-02-16 21:54   ` Thomas Garnier
  0 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-16 21:54 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H . Peter Anvin, Jonathan Corbet,
	Thomas Garnier, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He
  Cc: x86, linux-kernel, linux-doc, linux-pm, linux-efi, xen-devel,
	lguest, kvm, kernel-hardening

The KVM segment_base function is confusing. This patch replaces integers
with appropriate flags, simplify constructs and add comments.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170213
---
 arch/x86/kvm/vmx.c | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 99167f20bc34..91e619269128 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2060,27 +2060,37 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset)
 static unsigned long segment_base(u16 selector)
 {
 	struct desc_struct *d;
-	unsigned long table_base;
+	struct desc_struct *table_base;
 	unsigned long v;
+	u32 high32;
 
-	if (!(selector & ~3))
+	if (!(selector & ~SEGMENT_RPL_MASK))
 		return 0;
 
-	table_base = get_current_gdt_rw_vaddr();
-
-	if (selector & 4) {           /* from ldt */
+	/* LDT selector */
+	if ((selector & SEGMENT_TI_MASK) == SEGMENT_LDT) {
 		u16 ldt_selector = kvm_read_ldt();
 
-		if (!(ldt_selector & ~3))
+		if (!(ldt_selector & ~SEGMENT_RPL_MASK))
 			return 0;
 
-		table_base = segment_base(ldt_selector);
+		table_base = (struct desc_struct *)segment_base(ldt_selector);
+	} else {
+		table_base = get_current_gdt_rw();
 	}
-	d = (struct desc_struct *)(table_base + (selector & ~7));
+
+	d = table_base + (selector >> 3);
 	v = get_desc_base(d);
 #ifdef CONFIG_X86_64
-       if (d->s == 0 && (d->type == 2 || d->type == 9 || d->type == 11))
-               v |= ((unsigned long)((struct ldttss_desc64 *)d)->base3) << 32;
+	/*
+	 * Extend the virtual address if we have a system descriptor entry for
+	 * LDT or TSS (available or busy).
+	 */
+	if (d->s == 0 && (d->type == DESC_LDT || d->type == DESC_TSS ||
+			  d->type == 11/*Busy TSS */)) {
+		high32 = ((struct ldttss_desc64 *)d)->base3;
+		v |= (u64)high32 << 32;
+	}
 #endif
 	return v;
 }
-- 
2.11.0.483.g087da7b7c-goog

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [kernel-hardening] [PATCH v4 4/4] KVM: VMX: Simplify segment_base
@ 2017-02-16 21:54   ` Thomas Garnier
  0 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-16 21:54 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H . Peter Anvin, Jonathan Corbet,
	Thomas Garnier, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He Chen, Luis R . Rodriguez, Stanislaw Gruszka,
	Arnd Bergmann, Peter Zijlstra, Dave Hansen, Vitaly Kuznetsov,
	Paul Gortmaker, Josh Poimboeuf, Tim Chen, Andi Kleen, Jiri Olsa,
	Michael Ellerman, Joerg Roedel, Paolo Bonzini,
	Radim Krčmář,
	Andy Lutomirski
  Cc: x86, linux-kernel, linux-doc, linux-pm, linux-efi, xen-devel,
	lguest, kvm, kernel-hardening

The KVM segment_base function is confusing. This patch replaces integers
with appropriate flags, simplify constructs and add comments.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170213
---
 arch/x86/kvm/vmx.c | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 99167f20bc34..91e619269128 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2060,27 +2060,37 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset)
 static unsigned long segment_base(u16 selector)
 {
 	struct desc_struct *d;
-	unsigned long table_base;
+	struct desc_struct *table_base;
 	unsigned long v;
+	u32 high32;
 
-	if (!(selector & ~3))
+	if (!(selector & ~SEGMENT_RPL_MASK))
 		return 0;
 
-	table_base = get_current_gdt_rw_vaddr();
-
-	if (selector & 4) {           /* from ldt */
+	/* LDT selector */
+	if ((selector & SEGMENT_TI_MASK) == SEGMENT_LDT) {
 		u16 ldt_selector = kvm_read_ldt();
 
-		if (!(ldt_selector & ~3))
+		if (!(ldt_selector & ~SEGMENT_RPL_MASK))
 			return 0;
 
-		table_base = segment_base(ldt_selector);
+		table_base = (struct desc_struct *)segment_base(ldt_selector);
+	} else {
+		table_base = get_current_gdt_rw();
 	}
-	d = (struct desc_struct *)(table_base + (selector & ~7));
+
+	d = table_base + (selector >> 3);
 	v = get_desc_base(d);
 #ifdef CONFIG_X86_64
-       if (d->s == 0 && (d->type == 2 || d->type == 9 || d->type == 11))
-               v |= ((unsigned long)((struct ldttss_desc64 *)d)->base3) << 32;
+	/*
+	 * Extend the virtual address if we have a system descriptor entry for
+	 * LDT or TSS (available or busy).
+	 */
+	if (d->s == 0 && (d->type == DESC_LDT || d->type == DESC_TSS ||
+			  d->type == 11/*Busy TSS */)) {
+		high32 = ((struct ldttss_desc64 *)d)->base3;
+		v |= (u64)high32 << 32;
+	}
 #endif
 	return v;
 }
-- 
2.11.0.483.g087da7b7c-goog

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 4/4] KVM: VMX: Simplify segment_base
  2017-02-16 21:54 ` Thomas Garnier
                   ` (6 preceding siblings ...)
  (?)
@ 2017-02-16 21:54 ` Thomas Garnier
  -1 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-16 21:54 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H . Peter Anvin, Jonathan Corbet,
	Thomas Garnier, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He Chen, Luis R . Rodriguez, Stanislaw Gruszka,
	Arnd Bergmann
  Cc: linux-efi, kvm, linux-pm, x86, linux-doc, linux-kernel, lguest,
	kernel-hardening, xen-devel

The KVM segment_base function is confusing. This patch replaces integers
with appropriate flags, simplify constructs and add comments.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170213
---
 arch/x86/kvm/vmx.c | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 99167f20bc34..91e619269128 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2060,27 +2060,37 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset)
 static unsigned long segment_base(u16 selector)
 {
 	struct desc_struct *d;
-	unsigned long table_base;
+	struct desc_struct *table_base;
 	unsigned long v;
+	u32 high32;
 
-	if (!(selector & ~3))
+	if (!(selector & ~SEGMENT_RPL_MASK))
 		return 0;
 
-	table_base = get_current_gdt_rw_vaddr();
-
-	if (selector & 4) {           /* from ldt */
+	/* LDT selector */
+	if ((selector & SEGMENT_TI_MASK) == SEGMENT_LDT) {
 		u16 ldt_selector = kvm_read_ldt();
 
-		if (!(ldt_selector & ~3))
+		if (!(ldt_selector & ~SEGMENT_RPL_MASK))
 			return 0;
 
-		table_base = segment_base(ldt_selector);
+		table_base = (struct desc_struct *)segment_base(ldt_selector);
+	} else {
+		table_base = get_current_gdt_rw();
 	}
-	d = (struct desc_struct *)(table_base + (selector & ~7));
+
+	d = table_base + (selector >> 3);
 	v = get_desc_base(d);
 #ifdef CONFIG_X86_64
-       if (d->s == 0 && (d->type == 2 || d->type == 9 || d->type == 11))
-               v |= ((unsigned long)((struct ldttss_desc64 *)d)->base3) << 32;
+	/*
+	 * Extend the virtual address if we have a system descriptor entry for
+	 * LDT or TSS (available or busy).
+	 */
+	if (d->s == 0 && (d->type == DESC_LDT || d->type == DESC_TSS ||
+			  d->type == 11/*Busy TSS */)) {
+		high32 = ((struct ldttss_desc64 *)d)->base3;
+		v |= (u64)high32 << 32;
+	}
 #endif
 	return v;
 }
-- 
2.11.0.483.g087da7b7c-goog


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size
  2017-02-16 21:54 ` Thomas Garnier
  (?)
  (?)
@ 2017-02-17  0:37   ` kbuild test robot
  -1 siblings, 0 replies; 39+ messages in thread
From: kbuild test robot @ 2017-02-17  0:37 UTC (permalink / raw)
  To: Thomas Garnier
  Cc: kbuild-all, Thomas Gleixner, Ingo Molnar, H . Peter Anvin,
	Jonathan Corbet, Thomas Garnier, Kees Cook, Lorenzo Stoakes,
	Juergen Gross, Andy Lutomirski, Rafael J . Wysocki, Len Brown,
	Pavel Machek, Jiri Kosina, Matt Fleming, Ard Biesheuvel,
	Boris Ostrovsky, Rusty Russell, Borislav Petkov,
	Christian Borntraeger, Brian Gerst, He Chen, Luis R . Rodriguez,
	Stanislaw Gruszka, Arnd Bergmann, Peter Zijlstra, Dave Hansen,
	Vitaly Kuznetsov, Paul Gortmaker, Josh Poimboeuf, Tim Chen,
	Andi Kleen, Jiri Olsa, Michael Ellerman, Joerg Roedel,
	Paolo Bonzini, Radim Krčmář,
	Andy Lutomirski, x86, linux-kernel, linux-doc, linux-pm,
	linux-efi, xen-devel, lguest, kvm, kernel-hardening

[-- Attachment #1: Type: text/plain, Size: 8138 bytes --]

Hi Thomas,

[auto build test ERROR on next-20170216]
[also build test ERROR on v4.10-rc8]
[cannot apply to tip/x86/core kvm/linux-next tip/auto-latest v4.9-rc8 v4.9-rc7 v4.9-rc6]
[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/Thomas-Garnier/x86-mm-Adapt-MODULES_END-based-on-Fixmap-section-size/20170217-072759
config: x86_64-randconfig-h0-02170640 (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=x86_64 

All error/warnings (new ones prefixed by >>):

>> arch/x86/mm/dump_pagetables.c:87:2: error: implicit declaration of function '__fix_to_virt' [-Werror=implicit-function-declaration]
     { MODULES_END,          "End Modules" },
     ^
   In file included from arch/x86/include/asm/pgtable_types.h:240:0,
                    from arch/x86/include/asm/paravirt_types.h:44,
                    from arch/x86/include/asm/ptrace.h:71,
                    from arch/x86/include/asm/math_emu.h:4,
                    from arch/x86/include/asm/processor.h:11,
                    from arch/x86/include/asm/cpufeature.h:4,
                    from arch/x86/include/asm/thread_info.h:52,
                    from include/linux/thread_info.h:25,
                    from arch/x86/include/asm/preempt.h:6,
                    from include/linux/preempt.h:59,
                    from include/linux/spinlock.h:50,
                    from include/linux/wait.h:8,
                    from include/linux/fs.h:5,
                    from include/linux/debugfs.h:18,
                    from arch/x86/mm/dump_pagetables.c:15:
>> arch/x86/include/asm/pgtable_64_types.h:71:37: error: '__end_of_fixed_addresses' undeclared here (not in a function)
    #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
                                        ^
>> arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro 'MODULES_END'
     { MODULES_END,          "End Modules" },
       ^
   cc1: some warnings being treated as errors

vim +/__fix_to_virt +87 arch/x86/mm/dump_pagetables.c

926e5392b Arjan van de Ven 2008-04-17   9   * This program is free software; you can redistribute it and/or
926e5392b Arjan van de Ven 2008-04-17  10   * modify it under the terms of the GNU General Public License
926e5392b Arjan van de Ven 2008-04-17  11   * as published by the Free Software Foundation; version 2
926e5392b Arjan van de Ven 2008-04-17  12   * of the License.
926e5392b Arjan van de Ven 2008-04-17  13   */
926e5392b Arjan van de Ven 2008-04-17  14  
fe770bf03 H. Peter Anvin   2008-04-17 @15  #include <linux/debugfs.h>
fe770bf03 H. Peter Anvin   2008-04-17  16  #include <linux/mm.h>
84e629b66 Paul Gortmaker   2016-07-13  17  #include <linux/init.h>
146fbb766 Andrey Ryabinin  2017-02-10  18  #include <linux/sched.h>
926e5392b Arjan van de Ven 2008-04-17  19  #include <linux/seq_file.h>
926e5392b Arjan van de Ven 2008-04-17  20  
926e5392b Arjan van de Ven 2008-04-17  21  #include <asm/pgtable.h>
926e5392b Arjan van de Ven 2008-04-17  22  
926e5392b Arjan van de Ven 2008-04-17  23  /*
926e5392b Arjan van de Ven 2008-04-17  24   * The dumper groups pagetable entries of the same type into one, and for
926e5392b Arjan van de Ven 2008-04-17  25   * that it needs to keep some state when walking, and flush this state
926e5392b Arjan van de Ven 2008-04-17  26   * when a "break" in the continuity is found.
926e5392b Arjan van de Ven 2008-04-17  27   */
926e5392b Arjan van de Ven 2008-04-17  28  struct pg_state {
926e5392b Arjan van de Ven 2008-04-17  29  	int level;
926e5392b Arjan van de Ven 2008-04-17  30  	pgprot_t current_prot;
926e5392b Arjan van de Ven 2008-04-17  31  	unsigned long start_address;
926e5392b Arjan van de Ven 2008-04-17  32  	unsigned long current_address;
fe770bf03 H. Peter Anvin   2008-04-17  33  	const struct addr_marker *marker;
3891a04aa H. Peter Anvin   2014-04-29  34  	unsigned long lines;
ef6bea6dd Borislav Petkov  2014-01-18  35  	bool to_dmesg;
e1a58320a Stephen Smalley  2015-10-05  36  	bool check_wx;
e1a58320a Stephen Smalley  2015-10-05  37  	unsigned long wx_pages;
926e5392b Arjan van de Ven 2008-04-17  38  };
926e5392b Arjan van de Ven 2008-04-17  39  
fe770bf03 H. Peter Anvin   2008-04-17  40  struct addr_marker {
fe770bf03 H. Peter Anvin   2008-04-17  41  	unsigned long start_address;
fe770bf03 H. Peter Anvin   2008-04-17  42  	const char *name;
3891a04aa H. Peter Anvin   2014-04-29  43  	unsigned long max_lines;
fe770bf03 H. Peter Anvin   2008-04-17  44  };
926e5392b Arjan van de Ven 2008-04-17  45  
92851e2fc Andres Salomon   2010-07-20  46  /* indices for address_markers; keep sync'd w/ address_markers below */
92851e2fc Andres Salomon   2010-07-20  47  enum address_markers_idx {
92851e2fc Andres Salomon   2010-07-20  48  	USER_SPACE_NR = 0,
92851e2fc Andres Salomon   2010-07-20  49  #ifdef CONFIG_X86_64
92851e2fc Andres Salomon   2010-07-20  50  	KERNEL_SPACE_NR,
92851e2fc Andres Salomon   2010-07-20  51  	LOW_KERNEL_NR,
92851e2fc Andres Salomon   2010-07-20  52  	VMALLOC_START_NR,
92851e2fc Andres Salomon   2010-07-20  53  	VMEMMAP_START_NR,
8a5a5d153 Mathias Krause   2014-09-07  54  # ifdef CONFIG_X86_ESPFIX64
3891a04aa H. Peter Anvin   2014-04-29  55  	ESPFIX_START_NR,
8a5a5d153 Mathias Krause   2014-09-07  56  # endif
92851e2fc Andres Salomon   2010-07-20  57  	HIGH_KERNEL_NR,
92851e2fc Andres Salomon   2010-07-20  58  	MODULES_VADDR_NR,
92851e2fc Andres Salomon   2010-07-20  59  	MODULES_END_NR,
92851e2fc Andres Salomon   2010-07-20  60  #else
92851e2fc Andres Salomon   2010-07-20  61  	KERNEL_SPACE_NR,
92851e2fc Andres Salomon   2010-07-20  62  	VMALLOC_START_NR,
92851e2fc Andres Salomon   2010-07-20  63  	VMALLOC_END_NR,
92851e2fc Andres Salomon   2010-07-20  64  # ifdef CONFIG_HIGHMEM
92851e2fc Andres Salomon   2010-07-20  65  	PKMAP_BASE_NR,
92851e2fc Andres Salomon   2010-07-20  66  # endif
92851e2fc Andres Salomon   2010-07-20  67  	FIXADDR_START_NR,
92851e2fc Andres Salomon   2010-07-20  68  #endif
92851e2fc Andres Salomon   2010-07-20  69  };
92851e2fc Andres Salomon   2010-07-20  70  
fe770bf03 H. Peter Anvin   2008-04-17  71  /* Address space markers hints */
fe770bf03 H. Peter Anvin   2008-04-17  72  static struct addr_marker address_markers[] = {
fe770bf03 H. Peter Anvin   2008-04-17  73  	{ 0, "User Space" },
fe770bf03 H. Peter Anvin   2008-04-17  74  #ifdef CONFIG_X86_64
fe770bf03 H. Peter Anvin   2008-04-17  75  	{ 0x8000000000000000UL, "Kernel Space" },
0483e1fa6 Thomas Garnier   2016-06-21  76  	{ 0/* PAGE_OFFSET */,   "Low Kernel Mapping" },
0483e1fa6 Thomas Garnier   2016-06-21  77  	{ 0/* VMALLOC_START */, "vmalloc() Area" },
0483e1fa6 Thomas Garnier   2016-06-21  78  	{ 0/* VMEMMAP_START */, "Vmemmap" },
8a5a5d153 Mathias Krause   2014-09-07  79  # ifdef CONFIG_X86_ESPFIX64
3891a04aa H. Peter Anvin   2014-04-29  80  	{ ESPFIX_BASE_ADDR,	"ESPfix Area", 16 },
8a5a5d153 Mathias Krause   2014-09-07  81  # endif
8266e31ed Mathias Krause   2014-09-21  82  # ifdef CONFIG_EFI
8266e31ed Mathias Krause   2014-09-21  83  	{ EFI_VA_END,		"EFI Runtime Services" },
8266e31ed Mathias Krause   2014-09-21  84  # endif
fe770bf03 H. Peter Anvin   2008-04-17  85  	{ __START_KERNEL_map,   "High Kernel Mapping" },
9a79cf9c1 Yinghai Lu       2008-03-07  86  	{ MODULES_VADDR,        "Modules" },
9a79cf9c1 Yinghai Lu       2008-03-07 @87  	{ MODULES_END,          "End Modules" },
fe770bf03 H. Peter Anvin   2008-04-17  88  #else
fe770bf03 H. Peter Anvin   2008-04-17  89  	{ PAGE_OFFSET,          "Kernel Mapping" },
fe770bf03 H. Peter Anvin   2008-04-17  90  	{ 0/* VMALLOC_START */, "vmalloc() Area" },

:::::: The code at line 87 was first introduced by commit
:::::: 9a79cf9c1aa671325fa5ba37576c2cee23823d04 x86: sort address_markers for dump_pagetables

:::::: TO: Yinghai Lu <yhlu.kernel@gmail.com>
:::::: CC: Ingo Molnar <mingo@elte.hu>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 25184 bytes --]

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size
@ 2017-02-17  0:37   ` kbuild test robot
  0 siblings, 0 replies; 39+ messages in thread
From: kbuild test robot @ 2017-02-17  0:37 UTC (permalink / raw)
  Cc: kbuild-all, Thomas Gleixner, Ingo Molnar, H . Peter Anvin,
	Jonathan Corbet, Thomas Garnier, Kees Cook, Lorenzo Stoakes,
	Juergen Gross, Andy Lutomirski, Rafael J . Wysocki, Len Brown,
	Pavel Machek, Jiri Kosina, Matt Fleming, Ard Biesheuvel,
	Boris Ostrovsky, Rusty Russell, Borislav Petkov,
	Christian Borntraeger, Brian Gerst

[-- Attachment #1: Type: text/plain, Size: 8138 bytes --]

Hi Thomas,

[auto build test ERROR on next-20170216]
[also build test ERROR on v4.10-rc8]
[cannot apply to tip/x86/core kvm/linux-next tip/auto-latest v4.9-rc8 v4.9-rc7 v4.9-rc6]
[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/Thomas-Garnier/x86-mm-Adapt-MODULES_END-based-on-Fixmap-section-size/20170217-072759
config: x86_64-randconfig-h0-02170640 (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=x86_64 

All error/warnings (new ones prefixed by >>):

>> arch/x86/mm/dump_pagetables.c:87:2: error: implicit declaration of function '__fix_to_virt' [-Werror=implicit-function-declaration]
     { MODULES_END,          "End Modules" },
     ^
   In file included from arch/x86/include/asm/pgtable_types.h:240:0,
                    from arch/x86/include/asm/paravirt_types.h:44,
                    from arch/x86/include/asm/ptrace.h:71,
                    from arch/x86/include/asm/math_emu.h:4,
                    from arch/x86/include/asm/processor.h:11,
                    from arch/x86/include/asm/cpufeature.h:4,
                    from arch/x86/include/asm/thread_info.h:52,
                    from include/linux/thread_info.h:25,
                    from arch/x86/include/asm/preempt.h:6,
                    from include/linux/preempt.h:59,
                    from include/linux/spinlock.h:50,
                    from include/linux/wait.h:8,
                    from include/linux/fs.h:5,
                    from include/linux/debugfs.h:18,
                    from arch/x86/mm/dump_pagetables.c:15:
>> arch/x86/include/asm/pgtable_64_types.h:71:37: error: '__end_of_fixed_addresses' undeclared here (not in a function)
    #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
                                        ^
>> arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro 'MODULES_END'
     { MODULES_END,          "End Modules" },
       ^
   cc1: some warnings being treated as errors

vim +/__fix_to_virt +87 arch/x86/mm/dump_pagetables.c

926e5392b Arjan van de Ven 2008-04-17   9   * This program is free software; you can redistribute it and/or
926e5392b Arjan van de Ven 2008-04-17  10   * modify it under the terms of the GNU General Public License
926e5392b Arjan van de Ven 2008-04-17  11   * as published by the Free Software Foundation; version 2
926e5392b Arjan van de Ven 2008-04-17  12   * of the License.
926e5392b Arjan van de Ven 2008-04-17  13   */
926e5392b Arjan van de Ven 2008-04-17  14  
fe770bf03 H. Peter Anvin   2008-04-17 @15  #include <linux/debugfs.h>
fe770bf03 H. Peter Anvin   2008-04-17  16  #include <linux/mm.h>
84e629b66 Paul Gortmaker   2016-07-13  17  #include <linux/init.h>
146fbb766 Andrey Ryabinin  2017-02-10  18  #include <linux/sched.h>
926e5392b Arjan van de Ven 2008-04-17  19  #include <linux/seq_file.h>
926e5392b Arjan van de Ven 2008-04-17  20  
926e5392b Arjan van de Ven 2008-04-17  21  #include <asm/pgtable.h>
926e5392b Arjan van de Ven 2008-04-17  22  
926e5392b Arjan van de Ven 2008-04-17  23  /*
926e5392b Arjan van de Ven 2008-04-17  24   * The dumper groups pagetable entries of the same type into one, and for
926e5392b Arjan van de Ven 2008-04-17  25   * that it needs to keep some state when walking, and flush this state
926e5392b Arjan van de Ven 2008-04-17  26   * when a "break" in the continuity is found.
926e5392b Arjan van de Ven 2008-04-17  27   */
926e5392b Arjan van de Ven 2008-04-17  28  struct pg_state {
926e5392b Arjan van de Ven 2008-04-17  29  	int level;
926e5392b Arjan van de Ven 2008-04-17  30  	pgprot_t current_prot;
926e5392b Arjan van de Ven 2008-04-17  31  	unsigned long start_address;
926e5392b Arjan van de Ven 2008-04-17  32  	unsigned long current_address;
fe770bf03 H. Peter Anvin   2008-04-17  33  	const struct addr_marker *marker;
3891a04aa H. Peter Anvin   2014-04-29  34  	unsigned long lines;
ef6bea6dd Borislav Petkov  2014-01-18  35  	bool to_dmesg;
e1a58320a Stephen Smalley  2015-10-05  36  	bool check_wx;
e1a58320a Stephen Smalley  2015-10-05  37  	unsigned long wx_pages;
926e5392b Arjan van de Ven 2008-04-17  38  };
926e5392b Arjan van de Ven 2008-04-17  39  
fe770bf03 H. Peter Anvin   2008-04-17  40  struct addr_marker {
fe770bf03 H. Peter Anvin   2008-04-17  41  	unsigned long start_address;
fe770bf03 H. Peter Anvin   2008-04-17  42  	const char *name;
3891a04aa H. Peter Anvin   2014-04-29  43  	unsigned long max_lines;
fe770bf03 H. Peter Anvin   2008-04-17  44  };
926e5392b Arjan van de Ven 2008-04-17  45  
92851e2fc Andres Salomon   2010-07-20  46  /* indices for address_markers; keep sync'd w/ address_markers below */
92851e2fc Andres Salomon   2010-07-20  47  enum address_markers_idx {
92851e2fc Andres Salomon   2010-07-20  48  	USER_SPACE_NR = 0,
92851e2fc Andres Salomon   2010-07-20  49  #ifdef CONFIG_X86_64
92851e2fc Andres Salomon   2010-07-20  50  	KERNEL_SPACE_NR,
92851e2fc Andres Salomon   2010-07-20  51  	LOW_KERNEL_NR,
92851e2fc Andres Salomon   2010-07-20  52  	VMALLOC_START_NR,
92851e2fc Andres Salomon   2010-07-20  53  	VMEMMAP_START_NR,
8a5a5d153 Mathias Krause   2014-09-07  54  # ifdef CONFIG_X86_ESPFIX64
3891a04aa H. Peter Anvin   2014-04-29  55  	ESPFIX_START_NR,
8a5a5d153 Mathias Krause   2014-09-07  56  # endif
92851e2fc Andres Salomon   2010-07-20  57  	HIGH_KERNEL_NR,
92851e2fc Andres Salomon   2010-07-20  58  	MODULES_VADDR_NR,
92851e2fc Andres Salomon   2010-07-20  59  	MODULES_END_NR,
92851e2fc Andres Salomon   2010-07-20  60  #else
92851e2fc Andres Salomon   2010-07-20  61  	KERNEL_SPACE_NR,
92851e2fc Andres Salomon   2010-07-20  62  	VMALLOC_START_NR,
92851e2fc Andres Salomon   2010-07-20  63  	VMALLOC_END_NR,
92851e2fc Andres Salomon   2010-07-20  64  # ifdef CONFIG_HIGHMEM
92851e2fc Andres Salomon   2010-07-20  65  	PKMAP_BASE_NR,
92851e2fc Andres Salomon   2010-07-20  66  # endif
92851e2fc Andres Salomon   2010-07-20  67  	FIXADDR_START_NR,
92851e2fc Andres Salomon   2010-07-20  68  #endif
92851e2fc Andres Salomon   2010-07-20  69  };
92851e2fc Andres Salomon   2010-07-20  70  
fe770bf03 H. Peter Anvin   2008-04-17  71  /* Address space markers hints */
fe770bf03 H. Peter Anvin   2008-04-17  72  static struct addr_marker address_markers[] = {
fe770bf03 H. Peter Anvin   2008-04-17  73  	{ 0, "User Space" },
fe770bf03 H. Peter Anvin   2008-04-17  74  #ifdef CONFIG_X86_64
fe770bf03 H. Peter Anvin   2008-04-17  75  	{ 0x8000000000000000UL, "Kernel Space" },
0483e1fa6 Thomas Garnier   2016-06-21  76  	{ 0/* PAGE_OFFSET */,   "Low Kernel Mapping" },
0483e1fa6 Thomas Garnier   2016-06-21  77  	{ 0/* VMALLOC_START */, "vmalloc() Area" },
0483e1fa6 Thomas Garnier   2016-06-21  78  	{ 0/* VMEMMAP_START */, "Vmemmap" },
8a5a5d153 Mathias Krause   2014-09-07  79  # ifdef CONFIG_X86_ESPFIX64
3891a04aa H. Peter Anvin   2014-04-29  80  	{ ESPFIX_BASE_ADDR,	"ESPfix Area", 16 },
8a5a5d153 Mathias Krause   2014-09-07  81  # endif
8266e31ed Mathias Krause   2014-09-21  82  # ifdef CONFIG_EFI
8266e31ed Mathias Krause   2014-09-21  83  	{ EFI_VA_END,		"EFI Runtime Services" },
8266e31ed Mathias Krause   2014-09-21  84  # endif
fe770bf03 H. Peter Anvin   2008-04-17  85  	{ __START_KERNEL_map,   "High Kernel Mapping" },
9a79cf9c1 Yinghai Lu       2008-03-07  86  	{ MODULES_VADDR,        "Modules" },
9a79cf9c1 Yinghai Lu       2008-03-07 @87  	{ MODULES_END,          "End Modules" },
fe770bf03 H. Peter Anvin   2008-04-17  88  #else
fe770bf03 H. Peter Anvin   2008-04-17  89  	{ PAGE_OFFSET,          "Kernel Mapping" },
fe770bf03 H. Peter Anvin   2008-04-17  90  	{ 0/* VMALLOC_START */, "vmalloc() Area" },

:::::: The code at line 87 was first introduced by commit
:::::: 9a79cf9c1aa671325fa5ba37576c2cee23823d04 x86: sort address_markers for dump_pagetables

:::::: TO: Yinghai Lu <yhlu.kernel@gmail.com>
:::::: CC: Ingo Molnar <mingo@elte.hu>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 25184 bytes --]

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size
@ 2017-02-17  0:37   ` kbuild test robot
  0 siblings, 0 replies; 39+ messages in thread
From: kbuild test robot @ 2017-02-17  0:37 UTC (permalink / raw)
  To: Thomas Garnier
  Cc: kbuild-all, Thomas Gleixner, Ingo Molnar, H . Peter Anvin,
	Jonathan Corbet, Thomas Garnier, Kees Cook, Lorenzo Stoakes,
	Juergen Gross, Andy Lutomirski, Rafael J . Wysocki, Len Brown,
	Pavel Machek, Jiri Kosina, Matt Fleming, Ard Biesheuvel,
	Boris Ostrovsky, Rusty Russell, Borislav Petkov,
	Christian Borntraeger, Brian Gerst

[-- Attachment #1: Type: text/plain, Size: 8138 bytes --]

Hi Thomas,

[auto build test ERROR on next-20170216]
[also build test ERROR on v4.10-rc8]
[cannot apply to tip/x86/core kvm/linux-next tip/auto-latest v4.9-rc8 v4.9-rc7 v4.9-rc6]
[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/Thomas-Garnier/x86-mm-Adapt-MODULES_END-based-on-Fixmap-section-size/20170217-072759
config: x86_64-randconfig-h0-02170640 (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=x86_64 

All error/warnings (new ones prefixed by >>):

>> arch/x86/mm/dump_pagetables.c:87:2: error: implicit declaration of function '__fix_to_virt' [-Werror=implicit-function-declaration]
     { MODULES_END,          "End Modules" },
     ^
   In file included from arch/x86/include/asm/pgtable_types.h:240:0,
                    from arch/x86/include/asm/paravirt_types.h:44,
                    from arch/x86/include/asm/ptrace.h:71,
                    from arch/x86/include/asm/math_emu.h:4,
                    from arch/x86/include/asm/processor.h:11,
                    from arch/x86/include/asm/cpufeature.h:4,
                    from arch/x86/include/asm/thread_info.h:52,
                    from include/linux/thread_info.h:25,
                    from arch/x86/include/asm/preempt.h:6,
                    from include/linux/preempt.h:59,
                    from include/linux/spinlock.h:50,
                    from include/linux/wait.h:8,
                    from include/linux/fs.h:5,
                    from include/linux/debugfs.h:18,
                    from arch/x86/mm/dump_pagetables.c:15:
>> arch/x86/include/asm/pgtable_64_types.h:71:37: error: '__end_of_fixed_addresses' undeclared here (not in a function)
    #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
                                        ^
>> arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro 'MODULES_END'
     { MODULES_END,          "End Modules" },
       ^
   cc1: some warnings being treated as errors

vim +/__fix_to_virt +87 arch/x86/mm/dump_pagetables.c

926e5392b Arjan van de Ven 2008-04-17   9   * This program is free software; you can redistribute it and/or
926e5392b Arjan van de Ven 2008-04-17  10   * modify it under the terms of the GNU General Public License
926e5392b Arjan van de Ven 2008-04-17  11   * as published by the Free Software Foundation; version 2
926e5392b Arjan van de Ven 2008-04-17  12   * of the License.
926e5392b Arjan van de Ven 2008-04-17  13   */
926e5392b Arjan van de Ven 2008-04-17  14  
fe770bf03 H. Peter Anvin   2008-04-17 @15  #include <linux/debugfs.h>
fe770bf03 H. Peter Anvin   2008-04-17  16  #include <linux/mm.h>
84e629b66 Paul Gortmaker   2016-07-13  17  #include <linux/init.h>
146fbb766 Andrey Ryabinin  2017-02-10  18  #include <linux/sched.h>
926e5392b Arjan van de Ven 2008-04-17  19  #include <linux/seq_file.h>
926e5392b Arjan van de Ven 2008-04-17  20  
926e5392b Arjan van de Ven 2008-04-17  21  #include <asm/pgtable.h>
926e5392b Arjan van de Ven 2008-04-17  22  
926e5392b Arjan van de Ven 2008-04-17  23  /*
926e5392b Arjan van de Ven 2008-04-17  24   * The dumper groups pagetable entries of the same type into one, and for
926e5392b Arjan van de Ven 2008-04-17  25   * that it needs to keep some state when walking, and flush this state
926e5392b Arjan van de Ven 2008-04-17  26   * when a "break" in the continuity is found.
926e5392b Arjan van de Ven 2008-04-17  27   */
926e5392b Arjan van de Ven 2008-04-17  28  struct pg_state {
926e5392b Arjan van de Ven 2008-04-17  29  	int level;
926e5392b Arjan van de Ven 2008-04-17  30  	pgprot_t current_prot;
926e5392b Arjan van de Ven 2008-04-17  31  	unsigned long start_address;
926e5392b Arjan van de Ven 2008-04-17  32  	unsigned long current_address;
fe770bf03 H. Peter Anvin   2008-04-17  33  	const struct addr_marker *marker;
3891a04aa H. Peter Anvin   2014-04-29  34  	unsigned long lines;
ef6bea6dd Borislav Petkov  2014-01-18  35  	bool to_dmesg;
e1a58320a Stephen Smalley  2015-10-05  36  	bool check_wx;
e1a58320a Stephen Smalley  2015-10-05  37  	unsigned long wx_pages;
926e5392b Arjan van de Ven 2008-04-17  38  };
926e5392b Arjan van de Ven 2008-04-17  39  
fe770bf03 H. Peter Anvin   2008-04-17  40  struct addr_marker {
fe770bf03 H. Peter Anvin   2008-04-17  41  	unsigned long start_address;
fe770bf03 H. Peter Anvin   2008-04-17  42  	const char *name;
3891a04aa H. Peter Anvin   2014-04-29  43  	unsigned long max_lines;
fe770bf03 H. Peter Anvin   2008-04-17  44  };
926e5392b Arjan van de Ven 2008-04-17  45  
92851e2fc Andres Salomon   2010-07-20  46  /* indices for address_markers; keep sync'd w/ address_markers below */
92851e2fc Andres Salomon   2010-07-20  47  enum address_markers_idx {
92851e2fc Andres Salomon   2010-07-20  48  	USER_SPACE_NR = 0,
92851e2fc Andres Salomon   2010-07-20  49  #ifdef CONFIG_X86_64
92851e2fc Andres Salomon   2010-07-20  50  	KERNEL_SPACE_NR,
92851e2fc Andres Salomon   2010-07-20  51  	LOW_KERNEL_NR,
92851e2fc Andres Salomon   2010-07-20  52  	VMALLOC_START_NR,
92851e2fc Andres Salomon   2010-07-20  53  	VMEMMAP_START_NR,
8a5a5d153 Mathias Krause   2014-09-07  54  # ifdef CONFIG_X86_ESPFIX64
3891a04aa H. Peter Anvin   2014-04-29  55  	ESPFIX_START_NR,
8a5a5d153 Mathias Krause   2014-09-07  56  # endif
92851e2fc Andres Salomon   2010-07-20  57  	HIGH_KERNEL_NR,
92851e2fc Andres Salomon   2010-07-20  58  	MODULES_VADDR_NR,
92851e2fc Andres Salomon   2010-07-20  59  	MODULES_END_NR,
92851e2fc Andres Salomon   2010-07-20  60  #else
92851e2fc Andres Salomon   2010-07-20  61  	KERNEL_SPACE_NR,
92851e2fc Andres Salomon   2010-07-20  62  	VMALLOC_START_NR,
92851e2fc Andres Salomon   2010-07-20  63  	VMALLOC_END_NR,
92851e2fc Andres Salomon   2010-07-20  64  # ifdef CONFIG_HIGHMEM
92851e2fc Andres Salomon   2010-07-20  65  	PKMAP_BASE_NR,
92851e2fc Andres Salomon   2010-07-20  66  # endif
92851e2fc Andres Salomon   2010-07-20  67  	FIXADDR_START_NR,
92851e2fc Andres Salomon   2010-07-20  68  #endif
92851e2fc Andres Salomon   2010-07-20  69  };
92851e2fc Andres Salomon   2010-07-20  70  
fe770bf03 H. Peter Anvin   2008-04-17  71  /* Address space markers hints */
fe770bf03 H. Peter Anvin   2008-04-17  72  static struct addr_marker address_markers[] = {
fe770bf03 H. Peter Anvin   2008-04-17  73  	{ 0, "User Space" },
fe770bf03 H. Peter Anvin   2008-04-17  74  #ifdef CONFIG_X86_64
fe770bf03 H. Peter Anvin   2008-04-17  75  	{ 0x8000000000000000UL, "Kernel Space" },
0483e1fa6 Thomas Garnier   2016-06-21  76  	{ 0/* PAGE_OFFSET */,   "Low Kernel Mapping" },
0483e1fa6 Thomas Garnier   2016-06-21  77  	{ 0/* VMALLOC_START */, "vmalloc() Area" },
0483e1fa6 Thomas Garnier   2016-06-21  78  	{ 0/* VMEMMAP_START */, "Vmemmap" },
8a5a5d153 Mathias Krause   2014-09-07  79  # ifdef CONFIG_X86_ESPFIX64
3891a04aa H. Peter Anvin   2014-04-29  80  	{ ESPFIX_BASE_ADDR,	"ESPfix Area", 16 },
8a5a5d153 Mathias Krause   2014-09-07  81  # endif
8266e31ed Mathias Krause   2014-09-21  82  # ifdef CONFIG_EFI
8266e31ed Mathias Krause   2014-09-21  83  	{ EFI_VA_END,		"EFI Runtime Services" },
8266e31ed Mathias Krause   2014-09-21  84  # endif
fe770bf03 H. Peter Anvin   2008-04-17  85  	{ __START_KERNEL_map,   "High Kernel Mapping" },
9a79cf9c1 Yinghai Lu       2008-03-07  86  	{ MODULES_VADDR,        "Modules" },
9a79cf9c1 Yinghai Lu       2008-03-07 @87  	{ MODULES_END,          "End Modules" },
fe770bf03 H. Peter Anvin   2008-04-17  88  #else
fe770bf03 H. Peter Anvin   2008-04-17  89  	{ PAGE_OFFSET,          "Kernel Mapping" },
fe770bf03 H. Peter Anvin   2008-04-17  90  	{ 0/* VMALLOC_START */, "vmalloc() Area" },

:::::: The code at line 87 was first introduced by commit
:::::: 9a79cf9c1aa671325fa5ba37576c2cee23823d04 x86: sort address_markers for dump_pagetables

:::::: TO: Yinghai Lu <yhlu.kernel@gmail.com>
:::::: CC: Ingo Molnar <mingo@elte.hu>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 25184 bytes --]

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [kernel-hardening] Re: [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size
@ 2017-02-17  0:37   ` kbuild test robot
  0 siblings, 0 replies; 39+ messages in thread
From: kbuild test robot @ 2017-02-17  0:37 UTC (permalink / raw)
  To: Thomas Garnier
  Cc: kbuild-all, Thomas Gleixner, Ingo Molnar, H . Peter Anvin,
	Jonathan Corbet, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He Chen, Luis R . Rodriguez, Stanislaw Gruszka,
	Arnd Bergmann, Peter Zijlstra, Dave Hansen, Vitaly Kuznetsov,
	Paul Gortmaker, Josh Poimboeuf, Tim Chen, Andi Kleen, Jiri Olsa,
	Michael Ellerman, Joerg Roedel, Paolo Bonzini,
	Radim Krčmář,
	Andy Lutomirski, x86, linux-kernel, linux-doc, linux-pm,
	linux-efi, xen-devel, lguest, kvm, kernel-hardening

[-- Attachment #1: Type: text/plain, Size: 8138 bytes --]

Hi Thomas,

[auto build test ERROR on next-20170216]
[also build test ERROR on v4.10-rc8]
[cannot apply to tip/x86/core kvm/linux-next tip/auto-latest v4.9-rc8 v4.9-rc7 v4.9-rc6]
[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/Thomas-Garnier/x86-mm-Adapt-MODULES_END-based-on-Fixmap-section-size/20170217-072759
config: x86_64-randconfig-h0-02170640 (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=x86_64 

All error/warnings (new ones prefixed by >>):

>> arch/x86/mm/dump_pagetables.c:87:2: error: implicit declaration of function '__fix_to_virt' [-Werror=implicit-function-declaration]
     { MODULES_END,          "End Modules" },
     ^
   In file included from arch/x86/include/asm/pgtable_types.h:240:0,
                    from arch/x86/include/asm/paravirt_types.h:44,
                    from arch/x86/include/asm/ptrace.h:71,
                    from arch/x86/include/asm/math_emu.h:4,
                    from arch/x86/include/asm/processor.h:11,
                    from arch/x86/include/asm/cpufeature.h:4,
                    from arch/x86/include/asm/thread_info.h:52,
                    from include/linux/thread_info.h:25,
                    from arch/x86/include/asm/preempt.h:6,
                    from include/linux/preempt.h:59,
                    from include/linux/spinlock.h:50,
                    from include/linux/wait.h:8,
                    from include/linux/fs.h:5,
                    from include/linux/debugfs.h:18,
                    from arch/x86/mm/dump_pagetables.c:15:
>> arch/x86/include/asm/pgtable_64_types.h:71:37: error: '__end_of_fixed_addresses' undeclared here (not in a function)
    #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
                                        ^
>> arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro 'MODULES_END'
     { MODULES_END,          "End Modules" },
       ^
   cc1: some warnings being treated as errors

vim +/__fix_to_virt +87 arch/x86/mm/dump_pagetables.c

926e5392b Arjan van de Ven 2008-04-17   9   * This program is free software; you can redistribute it and/or
926e5392b Arjan van de Ven 2008-04-17  10   * modify it under the terms of the GNU General Public License
926e5392b Arjan van de Ven 2008-04-17  11   * as published by the Free Software Foundation; version 2
926e5392b Arjan van de Ven 2008-04-17  12   * of the License.
926e5392b Arjan van de Ven 2008-04-17  13   */
926e5392b Arjan van de Ven 2008-04-17  14  
fe770bf03 H. Peter Anvin   2008-04-17 @15  #include <linux/debugfs.h>
fe770bf03 H. Peter Anvin   2008-04-17  16  #include <linux/mm.h>
84e629b66 Paul Gortmaker   2016-07-13  17  #include <linux/init.h>
146fbb766 Andrey Ryabinin  2017-02-10  18  #include <linux/sched.h>
926e5392b Arjan van de Ven 2008-04-17  19  #include <linux/seq_file.h>
926e5392b Arjan van de Ven 2008-04-17  20  
926e5392b Arjan van de Ven 2008-04-17  21  #include <asm/pgtable.h>
926e5392b Arjan van de Ven 2008-04-17  22  
926e5392b Arjan van de Ven 2008-04-17  23  /*
926e5392b Arjan van de Ven 2008-04-17  24   * The dumper groups pagetable entries of the same type into one, and for
926e5392b Arjan van de Ven 2008-04-17  25   * that it needs to keep some state when walking, and flush this state
926e5392b Arjan van de Ven 2008-04-17  26   * when a "break" in the continuity is found.
926e5392b Arjan van de Ven 2008-04-17  27   */
926e5392b Arjan van de Ven 2008-04-17  28  struct pg_state {
926e5392b Arjan van de Ven 2008-04-17  29  	int level;
926e5392b Arjan van de Ven 2008-04-17  30  	pgprot_t current_prot;
926e5392b Arjan van de Ven 2008-04-17  31  	unsigned long start_address;
926e5392b Arjan van de Ven 2008-04-17  32  	unsigned long current_address;
fe770bf03 H. Peter Anvin   2008-04-17  33  	const struct addr_marker *marker;
3891a04aa H. Peter Anvin   2014-04-29  34  	unsigned long lines;
ef6bea6dd Borislav Petkov  2014-01-18  35  	bool to_dmesg;
e1a58320a Stephen Smalley  2015-10-05  36  	bool check_wx;
e1a58320a Stephen Smalley  2015-10-05  37  	unsigned long wx_pages;
926e5392b Arjan van de Ven 2008-04-17  38  };
926e5392b Arjan van de Ven 2008-04-17  39  
fe770bf03 H. Peter Anvin   2008-04-17  40  struct addr_marker {
fe770bf03 H. Peter Anvin   2008-04-17  41  	unsigned long start_address;
fe770bf03 H. Peter Anvin   2008-04-17  42  	const char *name;
3891a04aa H. Peter Anvin   2014-04-29  43  	unsigned long max_lines;
fe770bf03 H. Peter Anvin   2008-04-17  44  };
926e5392b Arjan van de Ven 2008-04-17  45  
92851e2fc Andres Salomon   2010-07-20  46  /* indices for address_markers; keep sync'd w/ address_markers below */
92851e2fc Andres Salomon   2010-07-20  47  enum address_markers_idx {
92851e2fc Andres Salomon   2010-07-20  48  	USER_SPACE_NR = 0,
92851e2fc Andres Salomon   2010-07-20  49  #ifdef CONFIG_X86_64
92851e2fc Andres Salomon   2010-07-20  50  	KERNEL_SPACE_NR,
92851e2fc Andres Salomon   2010-07-20  51  	LOW_KERNEL_NR,
92851e2fc Andres Salomon   2010-07-20  52  	VMALLOC_START_NR,
92851e2fc Andres Salomon   2010-07-20  53  	VMEMMAP_START_NR,
8a5a5d153 Mathias Krause   2014-09-07  54  # ifdef CONFIG_X86_ESPFIX64
3891a04aa H. Peter Anvin   2014-04-29  55  	ESPFIX_START_NR,
8a5a5d153 Mathias Krause   2014-09-07  56  # endif
92851e2fc Andres Salomon   2010-07-20  57  	HIGH_KERNEL_NR,
92851e2fc Andres Salomon   2010-07-20  58  	MODULES_VADDR_NR,
92851e2fc Andres Salomon   2010-07-20  59  	MODULES_END_NR,
92851e2fc Andres Salomon   2010-07-20  60  #else
92851e2fc Andres Salomon   2010-07-20  61  	KERNEL_SPACE_NR,
92851e2fc Andres Salomon   2010-07-20  62  	VMALLOC_START_NR,
92851e2fc Andres Salomon   2010-07-20  63  	VMALLOC_END_NR,
92851e2fc Andres Salomon   2010-07-20  64  # ifdef CONFIG_HIGHMEM
92851e2fc Andres Salomon   2010-07-20  65  	PKMAP_BASE_NR,
92851e2fc Andres Salomon   2010-07-20  66  # endif
92851e2fc Andres Salomon   2010-07-20  67  	FIXADDR_START_NR,
92851e2fc Andres Salomon   2010-07-20  68  #endif
92851e2fc Andres Salomon   2010-07-20  69  };
92851e2fc Andres Salomon   2010-07-20  70  
fe770bf03 H. Peter Anvin   2008-04-17  71  /* Address space markers hints */
fe770bf03 H. Peter Anvin   2008-04-17  72  static struct addr_marker address_markers[] = {
fe770bf03 H. Peter Anvin   2008-04-17  73  	{ 0, "User Space" },
fe770bf03 H. Peter Anvin   2008-04-17  74  #ifdef CONFIG_X86_64
fe770bf03 H. Peter Anvin   2008-04-17  75  	{ 0x8000000000000000UL, "Kernel Space" },
0483e1fa6 Thomas Garnier   2016-06-21  76  	{ 0/* PAGE_OFFSET */,   "Low Kernel Mapping" },
0483e1fa6 Thomas Garnier   2016-06-21  77  	{ 0/* VMALLOC_START */, "vmalloc() Area" },
0483e1fa6 Thomas Garnier   2016-06-21  78  	{ 0/* VMEMMAP_START */, "Vmemmap" },
8a5a5d153 Mathias Krause   2014-09-07  79  # ifdef CONFIG_X86_ESPFIX64
3891a04aa H. Peter Anvin   2014-04-29  80  	{ ESPFIX_BASE_ADDR,	"ESPfix Area", 16 },
8a5a5d153 Mathias Krause   2014-09-07  81  # endif
8266e31ed Mathias Krause   2014-09-21  82  # ifdef CONFIG_EFI
8266e31ed Mathias Krause   2014-09-21  83  	{ EFI_VA_END,		"EFI Runtime Services" },
8266e31ed Mathias Krause   2014-09-21  84  # endif
fe770bf03 H. Peter Anvin   2008-04-17  85  	{ __START_KERNEL_map,   "High Kernel Mapping" },
9a79cf9c1 Yinghai Lu       2008-03-07  86  	{ MODULES_VADDR,        "Modules" },
9a79cf9c1 Yinghai Lu       2008-03-07 @87  	{ MODULES_END,          "End Modules" },
fe770bf03 H. Peter Anvin   2008-04-17  88  #else
fe770bf03 H. Peter Anvin   2008-04-17  89  	{ PAGE_OFFSET,          "Kernel Mapping" },
fe770bf03 H. Peter Anvin   2008-04-17  90  	{ 0/* VMALLOC_START */, "vmalloc() Area" },

:::::: The code at line 87 was first introduced by commit
:::::: 9a79cf9c1aa671325fa5ba37576c2cee23823d04 x86: sort address_markers for dump_pagetables

:::::: TO: Yinghai Lu <yhlu.kernel@gmail.com>
:::::: CC: Ingo Molnar <mingo@elte.hu>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 25184 bytes --]

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size
  2017-02-16 21:54 ` Thomas Garnier
                   ` (8 preceding siblings ...)
  (?)
@ 2017-02-17  0:37 ` kbuild test robot
  -1 siblings, 0 replies; 39+ messages in thread
From: kbuild test robot @ 2017-02-17  0:37 UTC (permalink / raw)
  To: Thomas Garnier
  Cc: linux-efi, Stanislaw Gruszka, linux-doc, kvm,
	Radim Krčmář,
	Matt Fleming, Dave Hansen, Pavel Machek, H . Peter Anvin,
	kernel-hardening, Jiri Olsa, Thomas Gleixner, Andi Kleen,
	Jonathan Corbet, Michael Ellerman, Joerg Roedel, x86,
	Paul Gortmaker, Christian Borntraeger, Ingo Molnar, xen-devel,
	Borislav Petkov, Len Brown, Jiri Kosina, Kees Cook,
	Arnd Bergmann

[-- Attachment #1: Type: text/plain, Size: 8138 bytes --]

Hi Thomas,

[auto build test ERROR on next-20170216]
[also build test ERROR on v4.10-rc8]
[cannot apply to tip/x86/core kvm/linux-next tip/auto-latest v4.9-rc8 v4.9-rc7 v4.9-rc6]
[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/Thomas-Garnier/x86-mm-Adapt-MODULES_END-based-on-Fixmap-section-size/20170217-072759
config: x86_64-randconfig-h0-02170640 (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=x86_64 

All error/warnings (new ones prefixed by >>):

>> arch/x86/mm/dump_pagetables.c:87:2: error: implicit declaration of function '__fix_to_virt' [-Werror=implicit-function-declaration]
     { MODULES_END,          "End Modules" },
     ^
   In file included from arch/x86/include/asm/pgtable_types.h:240:0,
                    from arch/x86/include/asm/paravirt_types.h:44,
                    from arch/x86/include/asm/ptrace.h:71,
                    from arch/x86/include/asm/math_emu.h:4,
                    from arch/x86/include/asm/processor.h:11,
                    from arch/x86/include/asm/cpufeature.h:4,
                    from arch/x86/include/asm/thread_info.h:52,
                    from include/linux/thread_info.h:25,
                    from arch/x86/include/asm/preempt.h:6,
                    from include/linux/preempt.h:59,
                    from include/linux/spinlock.h:50,
                    from include/linux/wait.h:8,
                    from include/linux/fs.h:5,
                    from include/linux/debugfs.h:18,
                    from arch/x86/mm/dump_pagetables.c:15:
>> arch/x86/include/asm/pgtable_64_types.h:71:37: error: '__end_of_fixed_addresses' undeclared here (not in a function)
    #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
                                        ^
>> arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro 'MODULES_END'
     { MODULES_END,          "End Modules" },
       ^
   cc1: some warnings being treated as errors

vim +/__fix_to_virt +87 arch/x86/mm/dump_pagetables.c

926e5392b Arjan van de Ven 2008-04-17   9   * This program is free software; you can redistribute it and/or
926e5392b Arjan van de Ven 2008-04-17  10   * modify it under the terms of the GNU General Public License
926e5392b Arjan van de Ven 2008-04-17  11   * as published by the Free Software Foundation; version 2
926e5392b Arjan van de Ven 2008-04-17  12   * of the License.
926e5392b Arjan van de Ven 2008-04-17  13   */
926e5392b Arjan van de Ven 2008-04-17  14  
fe770bf03 H. Peter Anvin   2008-04-17 @15  #include <linux/debugfs.h>
fe770bf03 H. Peter Anvin   2008-04-17  16  #include <linux/mm.h>
84e629b66 Paul Gortmaker   2016-07-13  17  #include <linux/init.h>
146fbb766 Andrey Ryabinin  2017-02-10  18  #include <linux/sched.h>
926e5392b Arjan van de Ven 2008-04-17  19  #include <linux/seq_file.h>
926e5392b Arjan van de Ven 2008-04-17  20  
926e5392b Arjan van de Ven 2008-04-17  21  #include <asm/pgtable.h>
926e5392b Arjan van de Ven 2008-04-17  22  
926e5392b Arjan van de Ven 2008-04-17  23  /*
926e5392b Arjan van de Ven 2008-04-17  24   * The dumper groups pagetable entries of the same type into one, and for
926e5392b Arjan van de Ven 2008-04-17  25   * that it needs to keep some state when walking, and flush this state
926e5392b Arjan van de Ven 2008-04-17  26   * when a "break" in the continuity is found.
926e5392b Arjan van de Ven 2008-04-17  27   */
926e5392b Arjan van de Ven 2008-04-17  28  struct pg_state {
926e5392b Arjan van de Ven 2008-04-17  29  	int level;
926e5392b Arjan van de Ven 2008-04-17  30  	pgprot_t current_prot;
926e5392b Arjan van de Ven 2008-04-17  31  	unsigned long start_address;
926e5392b Arjan van de Ven 2008-04-17  32  	unsigned long current_address;
fe770bf03 H. Peter Anvin   2008-04-17  33  	const struct addr_marker *marker;
3891a04aa H. Peter Anvin   2014-04-29  34  	unsigned long lines;
ef6bea6dd Borislav Petkov  2014-01-18  35  	bool to_dmesg;
e1a58320a Stephen Smalley  2015-10-05  36  	bool check_wx;
e1a58320a Stephen Smalley  2015-10-05  37  	unsigned long wx_pages;
926e5392b Arjan van de Ven 2008-04-17  38  };
926e5392b Arjan van de Ven 2008-04-17  39  
fe770bf03 H. Peter Anvin   2008-04-17  40  struct addr_marker {
fe770bf03 H. Peter Anvin   2008-04-17  41  	unsigned long start_address;
fe770bf03 H. Peter Anvin   2008-04-17  42  	const char *name;
3891a04aa H. Peter Anvin   2014-04-29  43  	unsigned long max_lines;
fe770bf03 H. Peter Anvin   2008-04-17  44  };
926e5392b Arjan van de Ven 2008-04-17  45  
92851e2fc Andres Salomon   2010-07-20  46  /* indices for address_markers; keep sync'd w/ address_markers below */
92851e2fc Andres Salomon   2010-07-20  47  enum address_markers_idx {
92851e2fc Andres Salomon   2010-07-20  48  	USER_SPACE_NR = 0,
92851e2fc Andres Salomon   2010-07-20  49  #ifdef CONFIG_X86_64
92851e2fc Andres Salomon   2010-07-20  50  	KERNEL_SPACE_NR,
92851e2fc Andres Salomon   2010-07-20  51  	LOW_KERNEL_NR,
92851e2fc Andres Salomon   2010-07-20  52  	VMALLOC_START_NR,
92851e2fc Andres Salomon   2010-07-20  53  	VMEMMAP_START_NR,
8a5a5d153 Mathias Krause   2014-09-07  54  # ifdef CONFIG_X86_ESPFIX64
3891a04aa H. Peter Anvin   2014-04-29  55  	ESPFIX_START_NR,
8a5a5d153 Mathias Krause   2014-09-07  56  # endif
92851e2fc Andres Salomon   2010-07-20  57  	HIGH_KERNEL_NR,
92851e2fc Andres Salomon   2010-07-20  58  	MODULES_VADDR_NR,
92851e2fc Andres Salomon   2010-07-20  59  	MODULES_END_NR,
92851e2fc Andres Salomon   2010-07-20  60  #else
92851e2fc Andres Salomon   2010-07-20  61  	KERNEL_SPACE_NR,
92851e2fc Andres Salomon   2010-07-20  62  	VMALLOC_START_NR,
92851e2fc Andres Salomon   2010-07-20  63  	VMALLOC_END_NR,
92851e2fc Andres Salomon   2010-07-20  64  # ifdef CONFIG_HIGHMEM
92851e2fc Andres Salomon   2010-07-20  65  	PKMAP_BASE_NR,
92851e2fc Andres Salomon   2010-07-20  66  # endif
92851e2fc Andres Salomon   2010-07-20  67  	FIXADDR_START_NR,
92851e2fc Andres Salomon   2010-07-20  68  #endif
92851e2fc Andres Salomon   2010-07-20  69  };
92851e2fc Andres Salomon   2010-07-20  70  
fe770bf03 H. Peter Anvin   2008-04-17  71  /* Address space markers hints */
fe770bf03 H. Peter Anvin   2008-04-17  72  static struct addr_marker address_markers[] = {
fe770bf03 H. Peter Anvin   2008-04-17  73  	{ 0, "User Space" },
fe770bf03 H. Peter Anvin   2008-04-17  74  #ifdef CONFIG_X86_64
fe770bf03 H. Peter Anvin   2008-04-17  75  	{ 0x8000000000000000UL, "Kernel Space" },
0483e1fa6 Thomas Garnier   2016-06-21  76  	{ 0/* PAGE_OFFSET */,   "Low Kernel Mapping" },
0483e1fa6 Thomas Garnier   2016-06-21  77  	{ 0/* VMALLOC_START */, "vmalloc() Area" },
0483e1fa6 Thomas Garnier   2016-06-21  78  	{ 0/* VMEMMAP_START */, "Vmemmap" },
8a5a5d153 Mathias Krause   2014-09-07  79  # ifdef CONFIG_X86_ESPFIX64
3891a04aa H. Peter Anvin   2014-04-29  80  	{ ESPFIX_BASE_ADDR,	"ESPfix Area", 16 },
8a5a5d153 Mathias Krause   2014-09-07  81  # endif
8266e31ed Mathias Krause   2014-09-21  82  # ifdef CONFIG_EFI
8266e31ed Mathias Krause   2014-09-21  83  	{ EFI_VA_END,		"EFI Runtime Services" },
8266e31ed Mathias Krause   2014-09-21  84  # endif
fe770bf03 H. Peter Anvin   2008-04-17  85  	{ __START_KERNEL_map,   "High Kernel Mapping" },
9a79cf9c1 Yinghai Lu       2008-03-07  86  	{ MODULES_VADDR,        "Modules" },
9a79cf9c1 Yinghai Lu       2008-03-07 @87  	{ MODULES_END,          "End Modules" },
fe770bf03 H. Peter Anvin   2008-04-17  88  #else
fe770bf03 H. Peter Anvin   2008-04-17  89  	{ PAGE_OFFSET,          "Kernel Mapping" },
fe770bf03 H. Peter Anvin   2008-04-17  90  	{ 0/* VMALLOC_START */, "vmalloc() Area" },

:::::: The code at line 87 was first introduced by commit
:::::: 9a79cf9c1aa671325fa5ba37576c2cee23823d04 x86: sort address_markers for dump_pagetables

:::::: TO: Yinghai Lu <yhlu.kernel@gmail.com>
:::::: CC: Ingo Molnar <mingo@elte.hu>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 25184 bytes --]

[-- Attachment #3: Type: text/plain, Size: 127 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size
  2017-02-16 21:54 ` Thomas Garnier
  (?)
  (?)
@ 2017-02-17  0:45   ` kbuild test robot
  -1 siblings, 0 replies; 39+ messages in thread
From: kbuild test robot @ 2017-02-17  0:45 UTC (permalink / raw)
  To: Thomas Garnier
  Cc: kbuild-all, Thomas Gleixner, Ingo Molnar, H . Peter Anvin,
	Jonathan Corbet, Thomas Garnier, Kees Cook, Lorenzo Stoakes,
	Juergen Gross, Andy Lutomirski, Rafael J . Wysocki, Len Brown,
	Pavel Machek, Jiri Kosina, Matt Fleming, Ard Biesheuvel,
	Boris Ostrovsky, Rusty Russell, Borislav Petkov,
	Christian Borntraeger, Brian Gerst, He Chen, Luis R . Rodriguez,
	Stanislaw Gruszka, Arnd Bergmann, Peter Zijlstra, Dave Hansen,
	Vitaly Kuznetsov, Paul Gortmaker, Josh Poimboeuf, Tim Chen,
	Andi Kleen, Jiri Olsa, Michael Ellerman, Joerg Roedel,
	Paolo Bonzini, Radim Krčmář,
	Andy Lutomirski, x86, linux-kernel, linux-doc, linux-pm,
	linux-efi, xen-devel, lguest, kvm, kernel-hardening

[-- Attachment #1: Type: text/plain, Size: 3165 bytes --]

Hi Thomas,

[auto build test ERROR on next-20170216]
[also build test ERROR on v4.10-rc8]
[cannot apply to tip/x86/core kvm/linux-next tip/auto-latest v4.9-rc8 v4.9-rc7 v4.9-rc6]
[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/Thomas-Garnier/x86-mm-Adapt-MODULES_END-based-on-Fixmap-section-size/20170217-072759
config: x86_64-randconfig-s4-02170325 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   In file included from arch/x86/include/asm/pgtable_types.h:240:0,
                    from arch/x86/include/asm/paravirt_types.h:44,
                    from arch/x86/include/asm/ptrace.h:71,
                    from arch/x86/include/asm/math_emu.h:4,
                    from arch/x86/include/asm/processor.h:11,
                    from arch/x86/include/asm/cpufeature.h:4,
                    from arch/x86/include/asm/thread_info.h:52,
                    from include/linux/thread_info.h:25,
                    from arch/x86/include/asm/preempt.h:6,
                    from include/linux/preempt.h:59,
                    from include/linux/spinlock.h:50,
                    from include/linux/wait.h:8,
                    from include/linux/fs.h:5,
                    from include/linux/debugfs.h:18,
                    from arch/x86/mm/dump_pagetables.c:15:
>> arch/x86/include/asm/pgtable_64_types.h:71:23: error: implicit declaration of function '__fix_to_virt' [-Werror=implicit-function-declaration]
    #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
                          ^
   arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro 'MODULES_END'
     { MODULES_END,          "End Modules" },
       ^~~~~~~~~~~
   arch/x86/include/asm/pgtable_64_types.h:71:37: error: '__end_of_fixed_addresses' undeclared here (not in a function)
    #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
                                        ^
   arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro 'MODULES_END'
     { MODULES_END,          "End Modules" },
       ^~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +/__fix_to_virt +71 arch/x86/include/asm/pgtable_64_types.h

    65	#define VMALLOC_START	__VMALLOC_BASE
    66	#define VMEMMAP_START	__VMEMMAP_BASE
    67	#endif /* CONFIG_RANDOMIZE_MEMORY */
    68	#define VMALLOC_END	(VMALLOC_START + _AC((VMALLOC_SIZE_TB << 40) - 1, UL))
    69	#define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
    70	/* The module sections ends with the start of the fixmap */
  > 71	#define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
    72	#define MODULES_LEN   (MODULES_END - MODULES_VADDR)
    73	#define ESPFIX_PGD_ENTRY _AC(-2, UL)
    74	#define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 28755 bytes --]

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size
@ 2017-02-17  0:45   ` kbuild test robot
  0 siblings, 0 replies; 39+ messages in thread
From: kbuild test robot @ 2017-02-17  0:45 UTC (permalink / raw)
  Cc: kbuild-all, Thomas Gleixner, Ingo Molnar, H . Peter Anvin,
	Jonathan Corbet, Thomas Garnier, Kees Cook, Lorenzo Stoakes,
	Juergen Gross, Andy Lutomirski, Rafael J . Wysocki, Len Brown,
	Pavel Machek, Jiri Kosina, Matt Fleming, Ard Biesheuvel,
	Boris Ostrovsky, Rusty Russell, Borislav Petkov,
	Christian Borntraeger, Brian Gerst

[-- Attachment #1: Type: text/plain, Size: 3165 bytes --]

Hi Thomas,

[auto build test ERROR on next-20170216]
[also build test ERROR on v4.10-rc8]
[cannot apply to tip/x86/core kvm/linux-next tip/auto-latest v4.9-rc8 v4.9-rc7 v4.9-rc6]
[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/Thomas-Garnier/x86-mm-Adapt-MODULES_END-based-on-Fixmap-section-size/20170217-072759
config: x86_64-randconfig-s4-02170325 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   In file included from arch/x86/include/asm/pgtable_types.h:240:0,
                    from arch/x86/include/asm/paravirt_types.h:44,
                    from arch/x86/include/asm/ptrace.h:71,
                    from arch/x86/include/asm/math_emu.h:4,
                    from arch/x86/include/asm/processor.h:11,
                    from arch/x86/include/asm/cpufeature.h:4,
                    from arch/x86/include/asm/thread_info.h:52,
                    from include/linux/thread_info.h:25,
                    from arch/x86/include/asm/preempt.h:6,
                    from include/linux/preempt.h:59,
                    from include/linux/spinlock.h:50,
                    from include/linux/wait.h:8,
                    from include/linux/fs.h:5,
                    from include/linux/debugfs.h:18,
                    from arch/x86/mm/dump_pagetables.c:15:
>> arch/x86/include/asm/pgtable_64_types.h:71:23: error: implicit declaration of function '__fix_to_virt' [-Werror=implicit-function-declaration]
    #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
                          ^
   arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro 'MODULES_END'
     { MODULES_END,          "End Modules" },
       ^~~~~~~~~~~
   arch/x86/include/asm/pgtable_64_types.h:71:37: error: '__end_of_fixed_addresses' undeclared here (not in a function)
    #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
                                        ^
   arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro 'MODULES_END'
     { MODULES_END,          "End Modules" },
       ^~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +/__fix_to_virt +71 arch/x86/include/asm/pgtable_64_types.h

    65	#define VMALLOC_START	__VMALLOC_BASE
    66	#define VMEMMAP_START	__VMEMMAP_BASE
    67	#endif /* CONFIG_RANDOMIZE_MEMORY */
    68	#define VMALLOC_END	(VMALLOC_START + _AC((VMALLOC_SIZE_TB << 40) - 1, UL))
    69	#define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
    70	/* The module sections ends with the start of the fixmap */
  > 71	#define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
    72	#define MODULES_LEN   (MODULES_END - MODULES_VADDR)
    73	#define ESPFIX_PGD_ENTRY _AC(-2, UL)
    74	#define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 28755 bytes --]

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size
@ 2017-02-17  0:45   ` kbuild test robot
  0 siblings, 0 replies; 39+ messages in thread
From: kbuild test robot @ 2017-02-17  0:45 UTC (permalink / raw)
  To: Thomas Garnier
  Cc: kbuild-all, Thomas Gleixner, Ingo Molnar, H . Peter Anvin,
	Jonathan Corbet, Thomas Garnier, Kees Cook, Lorenzo Stoakes,
	Juergen Gross, Andy Lutomirski, Rafael J . Wysocki, Len Brown,
	Pavel Machek, Jiri Kosina, Matt Fleming, Ard Biesheuvel,
	Boris Ostrovsky, Rusty Russell, Borislav Petkov,
	Christian Borntraeger, Brian Gerst

[-- Attachment #1: Type: text/plain, Size: 3165 bytes --]

Hi Thomas,

[auto build test ERROR on next-20170216]
[also build test ERROR on v4.10-rc8]
[cannot apply to tip/x86/core kvm/linux-next tip/auto-latest v4.9-rc8 v4.9-rc7 v4.9-rc6]
[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/Thomas-Garnier/x86-mm-Adapt-MODULES_END-based-on-Fixmap-section-size/20170217-072759
config: x86_64-randconfig-s4-02170325 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   In file included from arch/x86/include/asm/pgtable_types.h:240:0,
                    from arch/x86/include/asm/paravirt_types.h:44,
                    from arch/x86/include/asm/ptrace.h:71,
                    from arch/x86/include/asm/math_emu.h:4,
                    from arch/x86/include/asm/processor.h:11,
                    from arch/x86/include/asm/cpufeature.h:4,
                    from arch/x86/include/asm/thread_info.h:52,
                    from include/linux/thread_info.h:25,
                    from arch/x86/include/asm/preempt.h:6,
                    from include/linux/preempt.h:59,
                    from include/linux/spinlock.h:50,
                    from include/linux/wait.h:8,
                    from include/linux/fs.h:5,
                    from include/linux/debugfs.h:18,
                    from arch/x86/mm/dump_pagetables.c:15:
>> arch/x86/include/asm/pgtable_64_types.h:71:23: error: implicit declaration of function '__fix_to_virt' [-Werror=implicit-function-declaration]
    #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
                          ^
   arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro 'MODULES_END'
     { MODULES_END,          "End Modules" },
       ^~~~~~~~~~~
   arch/x86/include/asm/pgtable_64_types.h:71:37: error: '__end_of_fixed_addresses' undeclared here (not in a function)
    #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
                                        ^
   arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro 'MODULES_END'
     { MODULES_END,          "End Modules" },
       ^~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +/__fix_to_virt +71 arch/x86/include/asm/pgtable_64_types.h

    65	#define VMALLOC_START	__VMALLOC_BASE
    66	#define VMEMMAP_START	__VMEMMAP_BASE
    67	#endif /* CONFIG_RANDOMIZE_MEMORY */
    68	#define VMALLOC_END	(VMALLOC_START + _AC((VMALLOC_SIZE_TB << 40) - 1, UL))
    69	#define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
    70	/* The module sections ends with the start of the fixmap */
  > 71	#define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
    72	#define MODULES_LEN   (MODULES_END - MODULES_VADDR)
    73	#define ESPFIX_PGD_ENTRY _AC(-2, UL)
    74	#define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 28755 bytes --]

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [kernel-hardening] Re: [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size
@ 2017-02-17  0:45   ` kbuild test robot
  0 siblings, 0 replies; 39+ messages in thread
From: kbuild test robot @ 2017-02-17  0:45 UTC (permalink / raw)
  To: Thomas Garnier
  Cc: kbuild-all, Thomas Gleixner, Ingo Molnar, H . Peter Anvin,
	Jonathan Corbet, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He Chen, Luis R . Rodriguez, Stanislaw Gruszka,
	Arnd Bergmann, Peter Zijlstra, Dave Hansen, Vitaly Kuznetsov,
	Paul Gortmaker, Josh Poimboeuf, Tim Chen, Andi Kleen, Jiri Olsa,
	Michael Ellerman, Joerg Roedel, Paolo Bonzini,
	Radim Krčmář,
	Andy Lutomirski, x86, linux-kernel, linux-doc, linux-pm,
	linux-efi, xen-devel, lguest, kvm, kernel-hardening

[-- Attachment #1: Type: text/plain, Size: 3165 bytes --]

Hi Thomas,

[auto build test ERROR on next-20170216]
[also build test ERROR on v4.10-rc8]
[cannot apply to tip/x86/core kvm/linux-next tip/auto-latest v4.9-rc8 v4.9-rc7 v4.9-rc6]
[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/Thomas-Garnier/x86-mm-Adapt-MODULES_END-based-on-Fixmap-section-size/20170217-072759
config: x86_64-randconfig-s4-02170325 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   In file included from arch/x86/include/asm/pgtable_types.h:240:0,
                    from arch/x86/include/asm/paravirt_types.h:44,
                    from arch/x86/include/asm/ptrace.h:71,
                    from arch/x86/include/asm/math_emu.h:4,
                    from arch/x86/include/asm/processor.h:11,
                    from arch/x86/include/asm/cpufeature.h:4,
                    from arch/x86/include/asm/thread_info.h:52,
                    from include/linux/thread_info.h:25,
                    from arch/x86/include/asm/preempt.h:6,
                    from include/linux/preempt.h:59,
                    from include/linux/spinlock.h:50,
                    from include/linux/wait.h:8,
                    from include/linux/fs.h:5,
                    from include/linux/debugfs.h:18,
                    from arch/x86/mm/dump_pagetables.c:15:
>> arch/x86/include/asm/pgtable_64_types.h:71:23: error: implicit declaration of function '__fix_to_virt' [-Werror=implicit-function-declaration]
    #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
                          ^
   arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro 'MODULES_END'
     { MODULES_END,          "End Modules" },
       ^~~~~~~~~~~
   arch/x86/include/asm/pgtable_64_types.h:71:37: error: '__end_of_fixed_addresses' undeclared here (not in a function)
    #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
                                        ^
   arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro 'MODULES_END'
     { MODULES_END,          "End Modules" },
       ^~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +/__fix_to_virt +71 arch/x86/include/asm/pgtable_64_types.h

    65	#define VMALLOC_START	__VMALLOC_BASE
    66	#define VMEMMAP_START	__VMEMMAP_BASE
    67	#endif /* CONFIG_RANDOMIZE_MEMORY */
    68	#define VMALLOC_END	(VMALLOC_START + _AC((VMALLOC_SIZE_TB << 40) - 1, UL))
    69	#define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
    70	/* The module sections ends with the start of the fixmap */
  > 71	#define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
    72	#define MODULES_LEN   (MODULES_END - MODULES_VADDR)
    73	#define ESPFIX_PGD_ENTRY _AC(-2, UL)
    74	#define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 28755 bytes --]

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size
  2017-02-16 21:54 ` Thomas Garnier
                   ` (10 preceding siblings ...)
  (?)
@ 2017-02-17  0:45 ` kbuild test robot
  -1 siblings, 0 replies; 39+ messages in thread
From: kbuild test robot @ 2017-02-17  0:45 UTC (permalink / raw)
  To: Thomas Garnier
  Cc: linux-efi, Stanislaw Gruszka, linux-doc, kvm,
	Radim Krčmář,
	Matt Fleming, Dave Hansen, Pavel Machek, H . Peter Anvin,
	kernel-hardening, Jiri Olsa, Thomas Gleixner, Andi Kleen,
	Jonathan Corbet, Michael Ellerman, Joerg Roedel, x86,
	Paul Gortmaker, Christian Borntraeger, Ingo Molnar, xen-devel,
	Borislav Petkov, Len Brown, Jiri Kosina, Kees Cook,
	Arnd Bergmann

[-- Attachment #1: Type: text/plain, Size: 3165 bytes --]

Hi Thomas,

[auto build test ERROR on next-20170216]
[also build test ERROR on v4.10-rc8]
[cannot apply to tip/x86/core kvm/linux-next tip/auto-latest v4.9-rc8 v4.9-rc7 v4.9-rc6]
[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/Thomas-Garnier/x86-mm-Adapt-MODULES_END-based-on-Fixmap-section-size/20170217-072759
config: x86_64-randconfig-s4-02170325 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   In file included from arch/x86/include/asm/pgtable_types.h:240:0,
                    from arch/x86/include/asm/paravirt_types.h:44,
                    from arch/x86/include/asm/ptrace.h:71,
                    from arch/x86/include/asm/math_emu.h:4,
                    from arch/x86/include/asm/processor.h:11,
                    from arch/x86/include/asm/cpufeature.h:4,
                    from arch/x86/include/asm/thread_info.h:52,
                    from include/linux/thread_info.h:25,
                    from arch/x86/include/asm/preempt.h:6,
                    from include/linux/preempt.h:59,
                    from include/linux/spinlock.h:50,
                    from include/linux/wait.h:8,
                    from include/linux/fs.h:5,
                    from include/linux/debugfs.h:18,
                    from arch/x86/mm/dump_pagetables.c:15:
>> arch/x86/include/asm/pgtable_64_types.h:71:23: error: implicit declaration of function '__fix_to_virt' [-Werror=implicit-function-declaration]
    #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
                          ^
   arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro 'MODULES_END'
     { MODULES_END,          "End Modules" },
       ^~~~~~~~~~~
   arch/x86/include/asm/pgtable_64_types.h:71:37: error: '__end_of_fixed_addresses' undeclared here (not in a function)
    #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
                                        ^
   arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro 'MODULES_END'
     { MODULES_END,          "End Modules" },
       ^~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +/__fix_to_virt +71 arch/x86/include/asm/pgtable_64_types.h

    65	#define VMALLOC_START	__VMALLOC_BASE
    66	#define VMEMMAP_START	__VMEMMAP_BASE
    67	#endif /* CONFIG_RANDOMIZE_MEMORY */
    68	#define VMALLOC_END	(VMALLOC_START + _AC((VMALLOC_SIZE_TB << 40) - 1, UL))
    69	#define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
    70	/* The module sections ends with the start of the fixmap */
  > 71	#define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
    72	#define MODULES_LEN   (MODULES_END - MODULES_VADDR)
    73	#define ESPFIX_PGD_ENTRY _AC(-2, UL)
    74	#define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 28755 bytes --]

[-- Attachment #3: Type: text/plain, Size: 127 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size
  2017-02-17  0:45   ` kbuild test robot
  (?)
@ 2017-02-17 16:00     ` Thomas Garnier
  -1 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-17 16:00 UTC (permalink / raw)
  To: kbuild test robot
  Cc: kbuild-all, Thomas Gleixner, Ingo Molnar, H . Peter Anvin,
	Jonathan Corbet, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He Chen, Luis R . Rodriguez, Stanislaw Gruszka,
	Arnd Bergmann

[-- Attachment #1: Type: text/plain, Size: 3488 bytes --]

I will send an update patch on this thread to fix the fixmap dependencies.

On Thu, Feb 16, 2017 at 4:45 PM, kbuild test robot <lkp@intel.com> wrote:

> Hi Thomas,
>
> [auto build test ERROR on next-20170216]
> [also build test ERROR on v4.10-rc8]
> [cannot apply to tip/x86/core kvm/linux-next tip/auto-latest v4.9-rc8
> v4.9-rc7 v4.9-rc6]
> [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/Thomas-Garnier/
> x86-mm-Adapt-MODULES_END-based-on-Fixmap-section-size/20170217-072759
> config: x86_64-randconfig-s4-02170325 (attached as .config)
> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=x86_64
>
> All errors (new ones prefixed by >>):
>
>    In file included from arch/x86/include/asm/pgtable_types.h:240:0,
>                     from arch/x86/include/asm/paravirt_types.h:44,
>                     from arch/x86/include/asm/ptrace.h:71,
>                     from arch/x86/include/asm/math_emu.h:4,
>                     from arch/x86/include/asm/processor.h:11,
>                     from arch/x86/include/asm/cpufeature.h:4,
>                     from arch/x86/include/asm/thread_info.h:52,
>                     from include/linux/thread_info.h:25,
>                     from arch/x86/include/asm/preempt.h:6,
>                     from include/linux/preempt.h:59,
>                     from include/linux/spinlock.h:50,
>                     from include/linux/wait.h:8,
>                     from include/linux/fs.h:5,
>                     from include/linux/debugfs.h:18,
>                     from arch/x86/mm/dump_pagetables.c:15:
> >> arch/x86/include/asm/pgtable_64_types.h:71:23: error: implicit
> declaration of function '__fix_to_virt' [-Werror=implicit-function-
> declaration]
>     #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>                           ^
>    arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro
> 'MODULES_END'
>      { MODULES_END,          "End Modules" },
>        ^~~~~~~~~~~
>    arch/x86/include/asm/pgtable_64_types.h:71:37: error:
> '__end_of_fixed_addresses' undeclared here (not in a function)
>     #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>                                         ^
>    arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro
> 'MODULES_END'
>      { MODULES_END,          "End Modules" },
>        ^~~~~~~~~~~
>    cc1: some warnings being treated as errors
>
> vim +/__fix_to_virt +71 arch/x86/include/asm/pgtable_64_types.h
>
>     65  #define VMALLOC_START   __VMALLOC_BASE
>     66  #define VMEMMAP_START   __VMEMMAP_BASE
>     67  #endif /* CONFIG_RANDOMIZE_MEMORY */
>     68  #define VMALLOC_END     (VMALLOC_START + _AC((VMALLOC_SIZE_TB <<
> 40) - 1, UL))
>     69  #define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
>     70  /* The module sections ends with the start of the fixmap */
>   > 71  #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>     72  #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
>     73  #define ESPFIX_PGD_ENTRY _AC(-2, UL)
>     74  #define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)
>
> ---
> 0-DAY kernel test infrastructure                Open Source Technology
> Center
> https://lists.01.org/pipermail/kbuild-all                   Intel
> Corporation
>



-- 
Thomas

[-- Attachment #2: Type: text/html, Size: 4966 bytes --]

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size
@ 2017-02-17 16:00     ` Thomas Garnier
  0 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-17 16:00 UTC (permalink / raw)
  To: kbuild test robot
  Cc: kbuild-all, Thomas Gleixner, Ingo Molnar, H . Peter Anvin,
	Jonathan Corbet, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He Chen, Luis R . Rodriguez, Stanislaw Gruszka,
	Arnd Bergmann, Peter

[-- Attachment #1: Type: text/plain, Size: 3488 bytes --]

I will send an update patch on this thread to fix the fixmap dependencies.

On Thu, Feb 16, 2017 at 4:45 PM, kbuild test robot <lkp@intel.com> wrote:

> Hi Thomas,
>
> [auto build test ERROR on next-20170216]
> [also build test ERROR on v4.10-rc8]
> [cannot apply to tip/x86/core kvm/linux-next tip/auto-latest v4.9-rc8
> v4.9-rc7 v4.9-rc6]
> [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/Thomas-Garnier/
> x86-mm-Adapt-MODULES_END-based-on-Fixmap-section-size/20170217-072759
> config: x86_64-randconfig-s4-02170325 (attached as .config)
> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=x86_64
>
> All errors (new ones prefixed by >>):
>
>    In file included from arch/x86/include/asm/pgtable_types.h:240:0,
>                     from arch/x86/include/asm/paravirt_types.h:44,
>                     from arch/x86/include/asm/ptrace.h:71,
>                     from arch/x86/include/asm/math_emu.h:4,
>                     from arch/x86/include/asm/processor.h:11,
>                     from arch/x86/include/asm/cpufeature.h:4,
>                     from arch/x86/include/asm/thread_info.h:52,
>                     from include/linux/thread_info.h:25,
>                     from arch/x86/include/asm/preempt.h:6,
>                     from include/linux/preempt.h:59,
>                     from include/linux/spinlock.h:50,
>                     from include/linux/wait.h:8,
>                     from include/linux/fs.h:5,
>                     from include/linux/debugfs.h:18,
>                     from arch/x86/mm/dump_pagetables.c:15:
> >> arch/x86/include/asm/pgtable_64_types.h:71:23: error: implicit
> declaration of function '__fix_to_virt' [-Werror=implicit-function-
> declaration]
>     #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>                           ^
>    arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro
> 'MODULES_END'
>      { MODULES_END,          "End Modules" },
>        ^~~~~~~~~~~
>    arch/x86/include/asm/pgtable_64_types.h:71:37: error:
> '__end_of_fixed_addresses' undeclared here (not in a function)
>     #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>                                         ^
>    arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro
> 'MODULES_END'
>      { MODULES_END,          "End Modules" },
>        ^~~~~~~~~~~
>    cc1: some warnings being treated as errors
>
> vim +/__fix_to_virt +71 arch/x86/include/asm/pgtable_64_types.h
>
>     65  #define VMALLOC_START   __VMALLOC_BASE
>     66  #define VMEMMAP_START   __VMEMMAP_BASE
>     67  #endif /* CONFIG_RANDOMIZE_MEMORY */
>     68  #define VMALLOC_END     (VMALLOC_START + _AC((VMALLOC_SIZE_TB <<
> 40) - 1, UL))
>     69  #define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
>     70  /* The module sections ends with the start of the fixmap */
>   > 71  #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>     72  #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
>     73  #define ESPFIX_PGD_ENTRY _AC(-2, UL)
>     74  #define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)
>
> ---
> 0-DAY kernel test infrastructure                Open Source Technology
> Center
> https://lists.01.org/pipermail/kbuild-all                   Intel
> Corporation
>



-- 
Thomas

[-- Attachment #2: Type: text/html, Size: 4966 bytes --]

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [kernel-hardening] Re: [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size
@ 2017-02-17 16:00     ` Thomas Garnier
  0 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-17 16:00 UTC (permalink / raw)
  To: kbuild test robot
  Cc: kbuild-all, Thomas Gleixner, Ingo Molnar, H . Peter Anvin,
	Jonathan Corbet, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He Chen, Luis R . Rodriguez, Stanislaw Gruszka,
	Arnd Bergmann, Peter Zijlstra, Dave Hansen, Vitaly Kuznetsov,
	Paul Gortmaker, Josh Poimboeuf, Tim Chen, Andi Kleen, Jiri Olsa,
	Michael Ellerman, Joerg Roedel, Paolo Bonzini,
	Radim Krčmář,
	Andy Lutomirski, the arch/x86 maintainers, LKML, linux-doc,
	Linux PM list, linux-efi, xen-devel, lguest, kvm list,
	Kernel Hardening

[-- Attachment #1: Type: text/plain, Size: 3488 bytes --]

I will send an update patch on this thread to fix the fixmap dependencies.

On Thu, Feb 16, 2017 at 4:45 PM, kbuild test robot <lkp@intel.com> wrote:

> Hi Thomas,
>
> [auto build test ERROR on next-20170216]
> [also build test ERROR on v4.10-rc8]
> [cannot apply to tip/x86/core kvm/linux-next tip/auto-latest v4.9-rc8
> v4.9-rc7 v4.9-rc6]
> [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/Thomas-Garnier/
> x86-mm-Adapt-MODULES_END-based-on-Fixmap-section-size/20170217-072759
> config: x86_64-randconfig-s4-02170325 (attached as .config)
> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=x86_64
>
> All errors (new ones prefixed by >>):
>
>    In file included from arch/x86/include/asm/pgtable_types.h:240:0,
>                     from arch/x86/include/asm/paravirt_types.h:44,
>                     from arch/x86/include/asm/ptrace.h:71,
>                     from arch/x86/include/asm/math_emu.h:4,
>                     from arch/x86/include/asm/processor.h:11,
>                     from arch/x86/include/asm/cpufeature.h:4,
>                     from arch/x86/include/asm/thread_info.h:52,
>                     from include/linux/thread_info.h:25,
>                     from arch/x86/include/asm/preempt.h:6,
>                     from include/linux/preempt.h:59,
>                     from include/linux/spinlock.h:50,
>                     from include/linux/wait.h:8,
>                     from include/linux/fs.h:5,
>                     from include/linux/debugfs.h:18,
>                     from arch/x86/mm/dump_pagetables.c:15:
> >> arch/x86/include/asm/pgtable_64_types.h:71:23: error: implicit
> declaration of function '__fix_to_virt' [-Werror=implicit-function-
> declaration]
>     #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>                           ^
>    arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro
> 'MODULES_END'
>      { MODULES_END,          "End Modules" },
>        ^~~~~~~~~~~
>    arch/x86/include/asm/pgtable_64_types.h:71:37: error:
> '__end_of_fixed_addresses' undeclared here (not in a function)
>     #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>                                         ^
>    arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro
> 'MODULES_END'
>      { MODULES_END,          "End Modules" },
>        ^~~~~~~~~~~
>    cc1: some warnings being treated as errors
>
> vim +/__fix_to_virt +71 arch/x86/include/asm/pgtable_64_types.h
>
>     65  #define VMALLOC_START   __VMALLOC_BASE
>     66  #define VMEMMAP_START   __VMEMMAP_BASE
>     67  #endif /* CONFIG_RANDOMIZE_MEMORY */
>     68  #define VMALLOC_END     (VMALLOC_START + _AC((VMALLOC_SIZE_TB <<
> 40) - 1, UL))
>     69  #define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
>     70  /* The module sections ends with the start of the fixmap */
>   > 71  #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>     72  #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
>     73  #define ESPFIX_PGD_ENTRY _AC(-2, UL)
>     74  #define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)
>
> ---
> 0-DAY kernel test infrastructure                Open Source Technology
> Center
> https://lists.01.org/pipermail/kbuild-all                   Intel
> Corporation
>



-- 
Thomas

[-- Attachment #2: Type: text/html, Size: 4966 bytes --]

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size
  2017-02-17  0:45   ` kbuild test robot
                     ` (2 preceding siblings ...)
  (?)
@ 2017-02-17 16:00   ` Thomas Garnier
  -1 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-17 16:00 UTC (permalink / raw)
  To: kbuild test robot
  Cc: linux-efi, Stanislaw Gruszka, linux-doc, kvm list,
	Radim Krčmář,
	Matt Fleming, Dave Hansen, Pavel Machek, H . Peter Anvin,
	Kernel Hardening, Jiri Olsa, Boris Ostrovsky, Andi Kleen,
	Jonathan Corbet, Michael Ellerman, Joerg Roedel,
	the arch/x86 maintainers, Paul Gortmaker, Christian Borntraeger,
	Ingo Molnar, xen-devel, Borislav Petkov, Len Brown, Jiri Kosina


[-- Attachment #1.1: Type: text/plain, Size: 3488 bytes --]

I will send an update patch on this thread to fix the fixmap dependencies.

On Thu, Feb 16, 2017 at 4:45 PM, kbuild test robot <lkp@intel.com> wrote:

> Hi Thomas,
>
> [auto build test ERROR on next-20170216]
> [also build test ERROR on v4.10-rc8]
> [cannot apply to tip/x86/core kvm/linux-next tip/auto-latest v4.9-rc8
> v4.9-rc7 v4.9-rc6]
> [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/Thomas-Garnier/
> x86-mm-Adapt-MODULES_END-based-on-Fixmap-section-size/20170217-072759
> config: x86_64-randconfig-s4-02170325 (attached as .config)
> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=x86_64
>
> All errors (new ones prefixed by >>):
>
>    In file included from arch/x86/include/asm/pgtable_types.h:240:0,
>                     from arch/x86/include/asm/paravirt_types.h:44,
>                     from arch/x86/include/asm/ptrace.h:71,
>                     from arch/x86/include/asm/math_emu.h:4,
>                     from arch/x86/include/asm/processor.h:11,
>                     from arch/x86/include/asm/cpufeature.h:4,
>                     from arch/x86/include/asm/thread_info.h:52,
>                     from include/linux/thread_info.h:25,
>                     from arch/x86/include/asm/preempt.h:6,
>                     from include/linux/preempt.h:59,
>                     from include/linux/spinlock.h:50,
>                     from include/linux/wait.h:8,
>                     from include/linux/fs.h:5,
>                     from include/linux/debugfs.h:18,
>                     from arch/x86/mm/dump_pagetables.c:15:
> >> arch/x86/include/asm/pgtable_64_types.h:71:23: error: implicit
> declaration of function '__fix_to_virt' [-Werror=implicit-function-
> declaration]
>     #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>                           ^
>    arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro
> 'MODULES_END'
>      { MODULES_END,          "End Modules" },
>        ^~~~~~~~~~~
>    arch/x86/include/asm/pgtable_64_types.h:71:37: error:
> '__end_of_fixed_addresses' undeclared here (not in a function)
>     #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>                                         ^
>    arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro
> 'MODULES_END'
>      { MODULES_END,          "End Modules" },
>        ^~~~~~~~~~~
>    cc1: some warnings being treated as errors
>
> vim +/__fix_to_virt +71 arch/x86/include/asm/pgtable_64_types.h
>
>     65  #define VMALLOC_START   __VMALLOC_BASE
>     66  #define VMEMMAP_START   __VMEMMAP_BASE
>     67  #endif /* CONFIG_RANDOMIZE_MEMORY */
>     68  #define VMALLOC_END     (VMALLOC_START + _AC((VMALLOC_SIZE_TB <<
> 40) - 1, UL))
>     69  #define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
>     70  /* The module sections ends with the start of the fixmap */
>   > 71  #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>     72  #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
>     73  #define ESPFIX_PGD_ENTRY _AC(-2, UL)
>     74  #define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)
>
> ---
> 0-DAY kernel test infrastructure                Open Source Technology
> Center
> https://lists.01.org/pipermail/kbuild-all                   Intel
> Corporation
>



-- 
Thomas

[-- Attachment #1.2: Type: text/html, Size: 4966 bytes --]

[-- Attachment #2: Type: text/plain, Size: 127 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size
  2017-02-17 16:00     ` Thomas Garnier
  (?)
  (?)
@ 2017-02-17 20:52       ` Thomas Garnier
  -1 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-17 20:52 UTC (permalink / raw)
  To: kbuild test robot
  Cc: kbuild-all, Thomas Gleixner, Ingo Molnar, H . Peter Anvin,
	Jonathan Corbet, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He Chen, Luis R . Rodriguez, Stanislaw Gruszka,
	Arnd Bergmann, Peter Zijlstra, Dave Hansen, Vitaly Kuznetsov,
	Paul Gortmaker, Josh Poimboeuf, Tim Chen, Andi Kleen, Jiri Olsa,
	Michael Ellerman, Joerg Roedel, Paolo Bonzini,
	Radim Krčmář,
	Andy Lutomirski, the arch/x86 maintainers, LKML, linux-doc,
	Linux PM list, linux-efi, xen-devel, lguest, kvm list,
	Kernel Hardening

This patch aligns MODULES_END to the beginning of the Fixmap section.
It optimizes the space available for both sections. The address is
pre-computed based on the number of pages required by the Fixmap
section.

It will allow GDT remapping in the Fixmap section. The current
MODULES_END static address does not provide enough space for the kernel
to support a large number of processors.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170213
Fixed fixmap dependencies on random configurations.
---
 Documentation/x86/x86_64/mm.txt         | 5 ++++-
 arch/x86/include/asm/pgtable_64_types.h | 3 ++-
 arch/x86/kernel/module.c                | 1 +
 arch/x86/mm/dump_pagetables.c           | 1 +
 arch/x86/mm/kasan_init_64.c             | 1 +
 mm/vmalloc.c                            | 1 +
 6 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/Documentation/x86/x86_64/mm.txt b/Documentation/x86/x86_64/mm.txt
index 5724092db811..ee3f9c30957c 100644
--- a/Documentation/x86/x86_64/mm.txt
+++ b/Documentation/x86/x86_64/mm.txt
@@ -19,7 +19,7 @@ ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp
fixup stacks
 ffffffef00000000 - fffffffeffffffff (=64 GB) EFI region mapping space
 ... unused hole ...
 ffffffff80000000 - ffffffff9fffffff (=512 MB)  kernel text mapping, from phys 0
-ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space
+ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space (variable)
 ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls
 ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole

@@ -39,6 +39,9 @@ memory window (this size is arbitrary, it can be
raised later if needed).
 The mappings are not part of any other kernel PGD and are only available
 during EFI runtime calls.

+The module mapping space size changes based on the CONFIG requirements for the
+following fixmap section.
+
 Note that if CONFIG_RANDOMIZE_MEMORY is enabled, the direct mapping of all
 physical memory, vmalloc/ioremap space and virtual memory map are randomized.
 Their order is preserved but their base will be offset early at boot time.
diff --git a/arch/x86/include/asm/pgtable_64_types.h
b/arch/x86/include/asm/pgtable_64_types.h
index 3a264200c62f..bb05e21cf3c7 100644
--- a/arch/x86/include/asm/pgtable_64_types.h
+++ b/arch/x86/include/asm/pgtable_64_types.h
@@ -67,7 +67,8 @@ typedef struct { pteval_t pte; } pte_t;
 #endif /* CONFIG_RANDOMIZE_MEMORY */
 #define VMALLOC_END (VMALLOC_START + _AC((VMALLOC_SIZE_TB << 40) - 1, UL))
 #define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
-#define MODULES_END      _AC(0xffffffffff000000, UL)
+/* The module sections ends with the start of the fixmap */
+#define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
 #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
 #define ESPFIX_PGD_ENTRY _AC(-2, UL)
 #define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
index 477ae806c2fa..fad61caac75e 100644
--- a/arch/x86/kernel/module.c
+++ b/arch/x86/kernel/module.c
@@ -35,6 +35,7 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/setup.h>
+#include <asm/fixmap.h>

 #if 0
 #define DEBUGP(fmt, ...) \
diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
index 8aa6bea1cd6c..90170415f08a 100644
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -19,6 +19,7 @@
 #include <linux/seq_file.h>

 #include <asm/pgtable.h>
+#include <asm/fixmap.h>

 /*
  * The dumper groups pagetable entries of the same type into one, and for
diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c
index 0493c17b8a51..34f167cf3316 100644
--- a/arch/x86/mm/kasan_init_64.c
+++ b/arch/x86/mm/kasan_init_64.c
@@ -8,6 +8,7 @@

 #include <asm/tlbflush.h>
 #include <asm/sections.h>
+#include <asm/fixmap.h>

 extern pgd_t early_level4_pgt[PTRS_PER_PGD];
 extern struct range pfn_mapped[E820_X_MAX];
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 011b446f8758..84e637f2fa49 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -35,6 +35,7 @@
 #include <linux/uaccess.h>
 #include <asm/tlbflush.h>
 #include <asm/shmparam.h>
+#include <asm/fixmap.h>

 #include "internal.h"

-- 
2.11.0.483.g087da7b7c-goog

On Fri, Feb 17, 2017 at 8:00 AM, Thomas Garnier <thgarnie@google.com> wrote:
> I will send an update patch on this thread to fix the fixmap dependencies.
>
> On Thu, Feb 16, 2017 at 4:45 PM, kbuild test robot <lkp@intel.com> wrote:
>>
>> Hi Thomas,
>>
>> [auto build test ERROR on next-20170216]
>> [also build test ERROR on v4.10-rc8]
>> [cannot apply to tip/x86/core kvm/linux-next tip/auto-latest v4.9-rc8
>> v4.9-rc7 v4.9-rc6]
>> [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/Thomas-Garnier/x86-mm-Adapt-MODULES_END-based-on-Fixmap-section-size/20170217-072759
>> config: x86_64-randconfig-s4-02170325 (attached as .config)
>> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
>> reproduce:
>>         # save the attached .config to linux build tree
>>         make ARCH=x86_64
>>
>> All errors (new ones prefixed by >>):
>>
>>    In file included from arch/x86/include/asm/pgtable_types.h:240:0,
>>                     from arch/x86/include/asm/paravirt_types.h:44,
>>                     from arch/x86/include/asm/ptrace.h:71,
>>                     from arch/x86/include/asm/math_emu.h:4,
>>                     from arch/x86/include/asm/processor.h:11,
>>                     from arch/x86/include/asm/cpufeature.h:4,
>>                     from arch/x86/include/asm/thread_info.h:52,
>>                     from include/linux/thread_info.h:25,
>>                     from arch/x86/include/asm/preempt.h:6,
>>                     from include/linux/preempt.h:59,
>>                     from include/linux/spinlock.h:50,
>>                     from include/linux/wait.h:8,
>>                     from include/linux/fs.h:5,
>>                     from include/linux/debugfs.h:18,
>>                     from arch/x86/mm/dump_pagetables.c:15:
>> >> arch/x86/include/asm/pgtable_64_types.h:71:23: error: implicit
>> >> declaration of function '__fix_to_virt'
>> >> [-Werror=implicit-function-declaration]
>>     #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>>                           ^
>>    arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro
>> 'MODULES_END'
>>      { MODULES_END,          "End Modules" },
>>        ^~~~~~~~~~~
>>    arch/x86/include/asm/pgtable_64_types.h:71:37: error:
>> '__end_of_fixed_addresses' undeclared here (not in a function)
>>     #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>>                                         ^
>>    arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro
>> 'MODULES_END'
>>      { MODULES_END,          "End Modules" },
>>        ^~~~~~~~~~~
>>    cc1: some warnings being treated as errors
>>
>> vim +/__fix_to_virt +71 arch/x86/include/asm/pgtable_64_types.h
>>
>>     65  #define VMALLOC_START   __VMALLOC_BASE
>>     66  #define VMEMMAP_START   __VMEMMAP_BASE
>>     67  #endif /* CONFIG_RANDOMIZE_MEMORY */
>>     68  #define VMALLOC_END     (VMALLOC_START + _AC((VMALLOC_SIZE_TB <<
>> 40) - 1, UL))
>>     69  #define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
>>     70  /* The module sections ends with the start of the fixmap */
>>   > 71  #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>>     72  #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
>>     73  #define ESPFIX_PGD_ENTRY _AC(-2, UL)
>>     74  #define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)
>>
>> ---
>> 0-DAY kernel test infrastructure                Open Source Technology
>> Center
>> https://lists.01.org/pipermail/kbuild-all                   Intel
>> Corporation
>
>
>
>
> --
> Thomas



-- 
Thomas

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size
@ 2017-02-17 20:52       ` Thomas Garnier
  0 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-17 20:52 UTC (permalink / raw)
  To: kbuild test robot
  Cc: kbuild-all, Thomas Gleixner, Ingo Molnar, H . Peter Anvin,
	Jonathan Corbet, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He Chen

This patch aligns MODULES_END to the beginning of the Fixmap section.
It optimizes the space available for both sections. The address is
pre-computed based on the number of pages required by the Fixmap
section.

It will allow GDT remapping in the Fixmap section. The current
MODULES_END static address does not provide enough space for the kernel
to support a large number of processors.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170213
Fixed fixmap dependencies on random configurations.
---
 Documentation/x86/x86_64/mm.txt         | 5 ++++-
 arch/x86/include/asm/pgtable_64_types.h | 3 ++-
 arch/x86/kernel/module.c                | 1 +
 arch/x86/mm/dump_pagetables.c           | 1 +
 arch/x86/mm/kasan_init_64.c             | 1 +
 mm/vmalloc.c                            | 1 +
 6 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/Documentation/x86/x86_64/mm.txt b/Documentation/x86/x86_64/mm.txt
index 5724092db811..ee3f9c30957c 100644
--- a/Documentation/x86/x86_64/mm.txt
+++ b/Documentation/x86/x86_64/mm.txt
@@ -19,7 +19,7 @@ ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp
fixup stacks
 ffffffef00000000 - fffffffeffffffff (=64 GB) EFI region mapping space
 ... unused hole ...
 ffffffff80000000 - ffffffff9fffffff (=512 MB)  kernel text mapping, from phys 0
-ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space
+ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space (variable)
 ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls
 ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole

@@ -39,6 +39,9 @@ memory window (this size is arbitrary, it can be
raised later if needed).
 The mappings are not part of any other kernel PGD and are only available
 during EFI runtime calls.

+The module mapping space size changes based on the CONFIG requirements for the
+following fixmap section.
+
 Note that if CONFIG_RANDOMIZE_MEMORY is enabled, the direct mapping of all
 physical memory, vmalloc/ioremap space and virtual memory map are randomized.
 Their order is preserved but their base will be offset early at boot time.
diff --git a/arch/x86/include/asm/pgtable_64_types.h
b/arch/x86/include/asm/pgtable_64_types.h
index 3a264200c62f..bb05e21cf3c7 100644
--- a/arch/x86/include/asm/pgtable_64_types.h
+++ b/arch/x86/include/asm/pgtable_64_types.h
@@ -67,7 +67,8 @@ typedef struct { pteval_t pte; } pte_t;
 #endif /* CONFIG_RANDOMIZE_MEMORY */
 #define VMALLOC_END (VMALLOC_START + _AC((VMALLOC_SIZE_TB << 40) - 1, UL))
 #define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
-#define MODULES_END      _AC(0xffffffffff000000, UL)
+/* The module sections ends with the start of the fixmap */
+#define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
 #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
 #define ESPFIX_PGD_ENTRY _AC(-2, UL)
 #define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
index 477ae806c2fa..fad61caac75e 100644
--- a/arch/x86/kernel/module.c
+++ b/arch/x86/kernel/module.c
@@ -35,6 +35,7 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/setup.h>
+#include <asm/fixmap.h>

 #if 0
 #define DEBUGP(fmt, ...) \
diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
index 8aa6bea1cd6c..90170415f08a 100644
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -19,6 +19,7 @@
 #include <linux/seq_file.h>

 #include <asm/pgtable.h>
+#include <asm/fixmap.h>

 /*
  * The dumper groups pagetable entries of the same type into one, and for
diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c
index 0493c17b8a51..34f167cf3316 100644
--- a/arch/x86/mm/kasan_init_64.c
+++ b/arch/x86/mm/kasan_init_64.c
@@ -8,6 +8,7 @@

 #include <asm/tlbflush.h>
 #include <asm/sections.h>
+#include <asm/fixmap.h>

 extern pgd_t early_level4_pgt[PTRS_PER_PGD];
 extern struct range pfn_mapped[E820_X_MAX];
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 011b446f8758..84e637f2fa49 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -35,6 +35,7 @@
 #include <linux/uaccess.h>
 #include <asm/tlbflush.h>
 #include <asm/shmparam.h>
+#include <asm/fixmap.h>

 #include "internal.h"

-- 
2.11.0.483.g087da7b7c-goog

On Fri, Feb 17, 2017 at 8:00 AM, Thomas Garnier <thgarnie@google.com> wrote:
> I will send an update patch on this thread to fix the fixmap dependencies.
>
> On Thu, Feb 16, 2017 at 4:45 PM, kbuild test robot <lkp@intel.com> wrote:
>>
>> Hi Thomas,
>>
>> [auto build test ERROR on next-20170216]
>> [also build test ERROR on v4.10-rc8]
>> [cannot apply to tip/x86/core kvm/linux-next tip/auto-latest v4.9-rc8
>> v4.9-rc7 v4.9-rc6]
>> [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/Thomas-Garnier/x86-mm-Adapt-MODULES_END-based-on-Fixmap-section-size/20170217-072759
>> config: x86_64-randconfig-s4-02170325 (attached as .config)
>> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
>> reproduce:
>>         # save the attached .config to linux build tree
>>         make ARCH=x86_64
>>
>> All errors (new ones prefixed by >>):
>>
>>    In file included from arch/x86/include/asm/pgtable_types.h:240:0,
>>                     from arch/x86/include/asm/paravirt_types.h:44,
>>                     from arch/x86/include/asm/ptrace.h:71,
>>                     from arch/x86/include/asm/math_emu.h:4,
>>                     from arch/x86/include/asm/processor.h:11,
>>                     from arch/x86/include/asm/cpufeature.h:4,
>>                     from arch/x86/include/asm/thread_info.h:52,
>>                     from include/linux/thread_info.h:25,
>>                     from arch/x86/include/asm/preempt.h:6,
>>                     from include/linux/preempt.h:59,
>>                     from include/linux/spinlock.h:50,
>>                     from include/linux/wait.h:8,
>>                     from include/linux/fs.h:5,
>>                     from include/linux/debugfs.h:18,
>>                     from arch/x86/mm/dump_pagetables.c:15:
>> >> arch/x86/include/asm/pgtable_64_types.h:71:23: error: implicit
>> >> declaration of function '__fix_to_virt'
>> >> [-Werror=implicit-function-declaration]
>>     #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>>                           ^
>>    arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro
>> 'MODULES_END'
>>      { MODULES_END,          "End Modules" },
>>        ^~~~~~~~~~~
>>    arch/x86/include/asm/pgtable_64_types.h:71:37: error:
>> '__end_of_fixed_addresses' undeclared here (not in a function)
>>     #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>>                                         ^
>>    arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro
>> 'MODULES_END'
>>      { MODULES_END,          "End Modules" },
>>        ^~~~~~~~~~~
>>    cc1: some warnings being treated as errors
>>
>> vim +/__fix_to_virt +71 arch/x86/include/asm/pgtable_64_types.h
>>
>>     65  #define VMALLOC_START   __VMALLOC_BASE
>>     66  #define VMEMMAP_START   __VMEMMAP_BASE
>>     67  #endif /* CONFIG_RANDOMIZE_MEMORY */
>>     68  #define VMALLOC_END     (VMALLOC_START + _AC((VMALLOC_SIZE_TB <<
>> 40) - 1, UL))
>>     69  #define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
>>     70  /* The module sections ends with the start of the fixmap */
>>   > 71  #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>>     72  #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
>>     73  #define ESPFIX_PGD_ENTRY _AC(-2, UL)
>>     74  #define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)
>>
>> ---
>> 0-DAY kernel test infrastructure                Open Source Technology
>> Center
>> https://lists.01.org/pipermail/kbuild-all                   Intel
>> Corporation
>
>
>
>
> --
> Thomas



-- 
Thomas

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size
@ 2017-02-17 20:52       ` Thomas Garnier
  0 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-17 20:52 UTC (permalink / raw)
  To: kbuild test robot
  Cc: kbuild-all, Thomas Gleixner, Ingo Molnar, H . Peter Anvin,
	Jonathan Corbet, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He Chen

This patch aligns MODULES_END to the beginning of the Fixmap section.
It optimizes the space available for both sections. The address is
pre-computed based on the number of pages required by the Fixmap
section.

It will allow GDT remapping in the Fixmap section. The current
MODULES_END static address does not provide enough space for the kernel
to support a large number of processors.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170213
Fixed fixmap dependencies on random configurations.
---
 Documentation/x86/x86_64/mm.txt         | 5 ++++-
 arch/x86/include/asm/pgtable_64_types.h | 3 ++-
 arch/x86/kernel/module.c                | 1 +
 arch/x86/mm/dump_pagetables.c           | 1 +
 arch/x86/mm/kasan_init_64.c             | 1 +
 mm/vmalloc.c                            | 1 +
 6 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/Documentation/x86/x86_64/mm.txt b/Documentation/x86/x86_64/mm.txt
index 5724092db811..ee3f9c30957c 100644
--- a/Documentation/x86/x86_64/mm.txt
+++ b/Documentation/x86/x86_64/mm.txt
@@ -19,7 +19,7 @@ ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp
fixup stacks
 ffffffef00000000 - fffffffeffffffff (=64 GB) EFI region mapping space
 ... unused hole ...
 ffffffff80000000 - ffffffff9fffffff (=512 MB)  kernel text mapping, from phys 0
-ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space
+ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space (variable)
 ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls
 ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole

@@ -39,6 +39,9 @@ memory window (this size is arbitrary, it can be
raised later if needed).
 The mappings are not part of any other kernel PGD and are only available
 during EFI runtime calls.

+The module mapping space size changes based on the CONFIG requirements for the
+following fixmap section.
+
 Note that if CONFIG_RANDOMIZE_MEMORY is enabled, the direct mapping of all
 physical memory, vmalloc/ioremap space and virtual memory map are randomized.
 Their order is preserved but their base will be offset early at boot time.
diff --git a/arch/x86/include/asm/pgtable_64_types.h
b/arch/x86/include/asm/pgtable_64_types.h
index 3a264200c62f..bb05e21cf3c7 100644
--- a/arch/x86/include/asm/pgtable_64_types.h
+++ b/arch/x86/include/asm/pgtable_64_types.h
@@ -67,7 +67,8 @@ typedef struct { pteval_t pte; } pte_t;
 #endif /* CONFIG_RANDOMIZE_MEMORY */
 #define VMALLOC_END (VMALLOC_START + _AC((VMALLOC_SIZE_TB << 40) - 1, UL))
 #define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
-#define MODULES_END      _AC(0xffffffffff000000, UL)
+/* The module sections ends with the start of the fixmap */
+#define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
 #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
 #define ESPFIX_PGD_ENTRY _AC(-2, UL)
 #define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
index 477ae806c2fa..fad61caac75e 100644
--- a/arch/x86/kernel/module.c
+++ b/arch/x86/kernel/module.c
@@ -35,6 +35,7 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/setup.h>
+#include <asm/fixmap.h>

 #if 0
 #define DEBUGP(fmt, ...) \
diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
index 8aa6bea1cd6c..90170415f08a 100644
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -19,6 +19,7 @@
 #include <linux/seq_file.h>

 #include <asm/pgtable.h>
+#include <asm/fixmap.h>

 /*
  * The dumper groups pagetable entries of the same type into one, and for
diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c
index 0493c17b8a51..34f167cf3316 100644
--- a/arch/x86/mm/kasan_init_64.c
+++ b/arch/x86/mm/kasan_init_64.c
@@ -8,6 +8,7 @@

 #include <asm/tlbflush.h>
 #include <asm/sections.h>
+#include <asm/fixmap.h>

 extern pgd_t early_level4_pgt[PTRS_PER_PGD];
 extern struct range pfn_mapped[E820_X_MAX];
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 011b446f8758..84e637f2fa49 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -35,6 +35,7 @@
 #include <linux/uaccess.h>
 #include <asm/tlbflush.h>
 #include <asm/shmparam.h>
+#include <asm/fixmap.h>

 #include "internal.h"

-- 
2.11.0.483.g087da7b7c-goog

On Fri, Feb 17, 2017 at 8:00 AM, Thomas Garnier <thgarnie@google.com> wrote:
> I will send an update patch on this thread to fix the fixmap dependencies.
>
> On Thu, Feb 16, 2017 at 4:45 PM, kbuild test robot <lkp@intel.com> wrote:
>>
>> Hi Thomas,
>>
>> [auto build test ERROR on next-20170216]
>> [also build test ERROR on v4.10-rc8]
>> [cannot apply to tip/x86/core kvm/linux-next tip/auto-latest v4.9-rc8
>> v4.9-rc7 v4.9-rc6]
>> [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/Thomas-Garnier/x86-mm-Adapt-MODULES_END-based-on-Fixmap-section-size/20170217-072759
>> config: x86_64-randconfig-s4-02170325 (attached as .config)
>> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
>> reproduce:
>>         # save the attached .config to linux build tree
>>         make ARCH=x86_64
>>
>> All errors (new ones prefixed by >>):
>>
>>    In file included from arch/x86/include/asm/pgtable_types.h:240:0,
>>                     from arch/x86/include/asm/paravirt_types.h:44,
>>                     from arch/x86/include/asm/ptrace.h:71,
>>                     from arch/x86/include/asm/math_emu.h:4,
>>                     from arch/x86/include/asm/processor.h:11,
>>                     from arch/x86/include/asm/cpufeature.h:4,
>>                     from arch/x86/include/asm/thread_info.h:52,
>>                     from include/linux/thread_info.h:25,
>>                     from arch/x86/include/asm/preempt.h:6,
>>                     from include/linux/preempt.h:59,
>>                     from include/linux/spinlock.h:50,
>>                     from include/linux/wait.h:8,
>>                     from include/linux/fs.h:5,
>>                     from include/linux/debugfs.h:18,
>>                     from arch/x86/mm/dump_pagetables.c:15:
>> >> arch/x86/include/asm/pgtable_64_types.h:71:23: error: implicit
>> >> declaration of function '__fix_to_virt'
>> >> [-Werror=implicit-function-declaration]
>>     #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>>                           ^
>>    arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro
>> 'MODULES_END'
>>      { MODULES_END,          "End Modules" },
>>        ^~~~~~~~~~~
>>    arch/x86/include/asm/pgtable_64_types.h:71:37: error:
>> '__end_of_fixed_addresses' undeclared here (not in a function)
>>     #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>>                                         ^
>>    arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro
>> 'MODULES_END'
>>      { MODULES_END,          "End Modules" },
>>        ^~~~~~~~~~~
>>    cc1: some warnings being treated as errors
>>
>> vim +/__fix_to_virt +71 arch/x86/include/asm/pgtable_64_types.h
>>
>>     65  #define VMALLOC_START   __VMALLOC_BASE
>>     66  #define VMEMMAP_START   __VMEMMAP_BASE
>>     67  #endif /* CONFIG_RANDOMIZE_MEMORY */
>>     68  #define VMALLOC_END     (VMALLOC_START + _AC((VMALLOC_SIZE_TB <<
>> 40) - 1, UL))
>>     69  #define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
>>     70  /* The module sections ends with the start of the fixmap */
>>   > 71  #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>>     72  #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
>>     73  #define ESPFIX_PGD_ENTRY _AC(-2, UL)
>>     74  #define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)
>>
>> ---
>> 0-DAY kernel test infrastructure                Open Source Technology
>> Center
>> https://lists.01.org/pipermail/kbuild-all                   Intel
>> Corporation
>
>
>
>
> --
> Thomas



-- 
Thomas

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [kernel-hardening] Re: [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size
@ 2017-02-17 20:52       ` Thomas Garnier
  0 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-17 20:52 UTC (permalink / raw)
  To: kbuild test robot
  Cc: kbuild-all, Thomas Gleixner, Ingo Molnar, H . Peter Anvin,
	Jonathan Corbet, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He Chen, Luis R . Rodriguez, Stanislaw Gruszka,
	Arnd Bergmann, Peter Zijlstra, Dave Hansen, Vitaly Kuznetsov,
	Paul Gortmaker, Josh Poimboeuf, Tim Chen, Andi Kleen, Jiri Olsa,
	Michael Ellerman, Joerg Roedel, Paolo Bonzini,
	Radim Krčmář,
	Andy Lutomirski, the arch/x86 maintainers, LKML, linux-doc,
	Linux PM list, linux-efi, xen-devel, lguest, kvm list,
	Kernel Hardening

This patch aligns MODULES_END to the beginning of the Fixmap section.
It optimizes the space available for both sections. The address is
pre-computed based on the number of pages required by the Fixmap
section.

It will allow GDT remapping in the Fixmap section. The current
MODULES_END static address does not provide enough space for the kernel
to support a large number of processors.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170213
Fixed fixmap dependencies on random configurations.
---
 Documentation/x86/x86_64/mm.txt         | 5 ++++-
 arch/x86/include/asm/pgtable_64_types.h | 3 ++-
 arch/x86/kernel/module.c                | 1 +
 arch/x86/mm/dump_pagetables.c           | 1 +
 arch/x86/mm/kasan_init_64.c             | 1 +
 mm/vmalloc.c                            | 1 +
 6 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/Documentation/x86/x86_64/mm.txt b/Documentation/x86/x86_64/mm.txt
index 5724092db811..ee3f9c30957c 100644
--- a/Documentation/x86/x86_64/mm.txt
+++ b/Documentation/x86/x86_64/mm.txt
@@ -19,7 +19,7 @@ ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp
fixup stacks
 ffffffef00000000 - fffffffeffffffff (=64 GB) EFI region mapping space
 ... unused hole ...
 ffffffff80000000 - ffffffff9fffffff (=512 MB)  kernel text mapping, from phys 0
-ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space
+ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space (variable)
 ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls
 ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole

@@ -39,6 +39,9 @@ memory window (this size is arbitrary, it can be
raised later if needed).
 The mappings are not part of any other kernel PGD and are only available
 during EFI runtime calls.

+The module mapping space size changes based on the CONFIG requirements for the
+following fixmap section.
+
 Note that if CONFIG_RANDOMIZE_MEMORY is enabled, the direct mapping of all
 physical memory, vmalloc/ioremap space and virtual memory map are randomized.
 Their order is preserved but their base will be offset early at boot time.
diff --git a/arch/x86/include/asm/pgtable_64_types.h
b/arch/x86/include/asm/pgtable_64_types.h
index 3a264200c62f..bb05e21cf3c7 100644
--- a/arch/x86/include/asm/pgtable_64_types.h
+++ b/arch/x86/include/asm/pgtable_64_types.h
@@ -67,7 +67,8 @@ typedef struct { pteval_t pte; } pte_t;
 #endif /* CONFIG_RANDOMIZE_MEMORY */
 #define VMALLOC_END (VMALLOC_START + _AC((VMALLOC_SIZE_TB << 40) - 1, UL))
 #define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
-#define MODULES_END      _AC(0xffffffffff000000, UL)
+/* The module sections ends with the start of the fixmap */
+#define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
 #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
 #define ESPFIX_PGD_ENTRY _AC(-2, UL)
 #define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
index 477ae806c2fa..fad61caac75e 100644
--- a/arch/x86/kernel/module.c
+++ b/arch/x86/kernel/module.c
@@ -35,6 +35,7 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/setup.h>
+#include <asm/fixmap.h>

 #if 0
 #define DEBUGP(fmt, ...) \
diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
index 8aa6bea1cd6c..90170415f08a 100644
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -19,6 +19,7 @@
 #include <linux/seq_file.h>

 #include <asm/pgtable.h>
+#include <asm/fixmap.h>

 /*
  * The dumper groups pagetable entries of the same type into one, and for
diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c
index 0493c17b8a51..34f167cf3316 100644
--- a/arch/x86/mm/kasan_init_64.c
+++ b/arch/x86/mm/kasan_init_64.c
@@ -8,6 +8,7 @@

 #include <asm/tlbflush.h>
 #include <asm/sections.h>
+#include <asm/fixmap.h>

 extern pgd_t early_level4_pgt[PTRS_PER_PGD];
 extern struct range pfn_mapped[E820_X_MAX];
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 011b446f8758..84e637f2fa49 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -35,6 +35,7 @@
 #include <linux/uaccess.h>
 #include <asm/tlbflush.h>
 #include <asm/shmparam.h>
+#include <asm/fixmap.h>

 #include "internal.h"

-- 
2.11.0.483.g087da7b7c-goog

On Fri, Feb 17, 2017 at 8:00 AM, Thomas Garnier <thgarnie@google.com> wrote:
> I will send an update patch on this thread to fix the fixmap dependencies.
>
> On Thu, Feb 16, 2017 at 4:45 PM, kbuild test robot <lkp@intel.com> wrote:
>>
>> Hi Thomas,
>>
>> [auto build test ERROR on next-20170216]
>> [also build test ERROR on v4.10-rc8]
>> [cannot apply to tip/x86/core kvm/linux-next tip/auto-latest v4.9-rc8
>> v4.9-rc7 v4.9-rc6]
>> [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/Thomas-Garnier/x86-mm-Adapt-MODULES_END-based-on-Fixmap-section-size/20170217-072759
>> config: x86_64-randconfig-s4-02170325 (attached as .config)
>> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
>> reproduce:
>>         # save the attached .config to linux build tree
>>         make ARCH=x86_64
>>
>> All errors (new ones prefixed by >>):
>>
>>    In file included from arch/x86/include/asm/pgtable_types.h:240:0,
>>                     from arch/x86/include/asm/paravirt_types.h:44,
>>                     from arch/x86/include/asm/ptrace.h:71,
>>                     from arch/x86/include/asm/math_emu.h:4,
>>                     from arch/x86/include/asm/processor.h:11,
>>                     from arch/x86/include/asm/cpufeature.h:4,
>>                     from arch/x86/include/asm/thread_info.h:52,
>>                     from include/linux/thread_info.h:25,
>>                     from arch/x86/include/asm/preempt.h:6,
>>                     from include/linux/preempt.h:59,
>>                     from include/linux/spinlock.h:50,
>>                     from include/linux/wait.h:8,
>>                     from include/linux/fs.h:5,
>>                     from include/linux/debugfs.h:18,
>>                     from arch/x86/mm/dump_pagetables.c:15:
>> >> arch/x86/include/asm/pgtable_64_types.h:71:23: error: implicit
>> >> declaration of function '__fix_to_virt'
>> >> [-Werror=implicit-function-declaration]
>>     #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>>                           ^
>>    arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro
>> 'MODULES_END'
>>      { MODULES_END,          "End Modules" },
>>        ^~~~~~~~~~~
>>    arch/x86/include/asm/pgtable_64_types.h:71:37: error:
>> '__end_of_fixed_addresses' undeclared here (not in a function)
>>     #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>>                                         ^
>>    arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro
>> 'MODULES_END'
>>      { MODULES_END,          "End Modules" },
>>        ^~~~~~~~~~~
>>    cc1: some warnings being treated as errors
>>
>> vim +/__fix_to_virt +71 arch/x86/include/asm/pgtable_64_types.h
>>
>>     65  #define VMALLOC_START   __VMALLOC_BASE
>>     66  #define VMEMMAP_START   __VMEMMAP_BASE
>>     67  #endif /* CONFIG_RANDOMIZE_MEMORY */
>>     68  #define VMALLOC_END     (VMALLOC_START + _AC((VMALLOC_SIZE_TB <<
>> 40) - 1, UL))
>>     69  #define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
>>     70  /* The module sections ends with the start of the fixmap */
>>   > 71  #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>>     72  #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
>>     73  #define ESPFIX_PGD_ENTRY _AC(-2, UL)
>>     74  #define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)
>>
>> ---
>> 0-DAY kernel test infrastructure                Open Source Technology
>> Center
>> https://lists.01.org/pipermail/kbuild-all                   Intel
>> Corporation
>
>
>
>
> --
> Thomas



-- 
Thomas

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size
  2017-02-17 16:00     ` Thomas Garnier
                       ` (2 preceding siblings ...)
  (?)
@ 2017-02-17 20:52     ` Thomas Garnier
  -1 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-17 20:52 UTC (permalink / raw)
  To: kbuild test robot
  Cc: linux-efi, Stanislaw Gruszka, linux-doc, kvm list,
	Radim Krčmář,
	Matt Fleming, Dave Hansen, Pavel Machek, H . Peter Anvin,
	Kernel Hardening, Jiri Olsa, Boris Ostrovsky, Andi Kleen,
	Jonathan Corbet, Michael Ellerman, Joerg Roedel,
	the arch/x86 maintainers, Paul Gortmaker, Christian Borntraeger,
	Ingo Molnar, xen-devel, Borislav Petkov, Len Brown, Jiri Kosina

This patch aligns MODULES_END to the beginning of the Fixmap section.
It optimizes the space available for both sections. The address is
pre-computed based on the number of pages required by the Fixmap
section.

It will allow GDT remapping in the Fixmap section. The current
MODULES_END static address does not provide enough space for the kernel
to support a large number of processors.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170213
Fixed fixmap dependencies on random configurations.
---
 Documentation/x86/x86_64/mm.txt         | 5 ++++-
 arch/x86/include/asm/pgtable_64_types.h | 3 ++-
 arch/x86/kernel/module.c                | 1 +
 arch/x86/mm/dump_pagetables.c           | 1 +
 arch/x86/mm/kasan_init_64.c             | 1 +
 mm/vmalloc.c                            | 1 +
 6 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/Documentation/x86/x86_64/mm.txt b/Documentation/x86/x86_64/mm.txt
index 5724092db811..ee3f9c30957c 100644
--- a/Documentation/x86/x86_64/mm.txt
+++ b/Documentation/x86/x86_64/mm.txt
@@ -19,7 +19,7 @@ ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp
fixup stacks
 ffffffef00000000 - fffffffeffffffff (=64 GB) EFI region mapping space
 ... unused hole ...
 ffffffff80000000 - ffffffff9fffffff (=512 MB)  kernel text mapping, from phys 0
-ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space
+ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space (variable)
 ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls
 ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole

@@ -39,6 +39,9 @@ memory window (this size is arbitrary, it can be
raised later if needed).
 The mappings are not part of any other kernel PGD and are only available
 during EFI runtime calls.

+The module mapping space size changes based on the CONFIG requirements for the
+following fixmap section.
+
 Note that if CONFIG_RANDOMIZE_MEMORY is enabled, the direct mapping of all
 physical memory, vmalloc/ioremap space and virtual memory map are randomized.
 Their order is preserved but their base will be offset early at boot time.
diff --git a/arch/x86/include/asm/pgtable_64_types.h
b/arch/x86/include/asm/pgtable_64_types.h
index 3a264200c62f..bb05e21cf3c7 100644
--- a/arch/x86/include/asm/pgtable_64_types.h
+++ b/arch/x86/include/asm/pgtable_64_types.h
@@ -67,7 +67,8 @@ typedef struct { pteval_t pte; } pte_t;
 #endif /* CONFIG_RANDOMIZE_MEMORY */
 #define VMALLOC_END (VMALLOC_START + _AC((VMALLOC_SIZE_TB << 40) - 1, UL))
 #define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
-#define MODULES_END      _AC(0xffffffffff000000, UL)
+/* The module sections ends with the start of the fixmap */
+#define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
 #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
 #define ESPFIX_PGD_ENTRY _AC(-2, UL)
 #define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
index 477ae806c2fa..fad61caac75e 100644
--- a/arch/x86/kernel/module.c
+++ b/arch/x86/kernel/module.c
@@ -35,6 +35,7 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/setup.h>
+#include <asm/fixmap.h>

 #if 0
 #define DEBUGP(fmt, ...) \
diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
index 8aa6bea1cd6c..90170415f08a 100644
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -19,6 +19,7 @@
 #include <linux/seq_file.h>

 #include <asm/pgtable.h>
+#include <asm/fixmap.h>

 /*
  * The dumper groups pagetable entries of the same type into one, and for
diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c
index 0493c17b8a51..34f167cf3316 100644
--- a/arch/x86/mm/kasan_init_64.c
+++ b/arch/x86/mm/kasan_init_64.c
@@ -8,6 +8,7 @@

 #include <asm/tlbflush.h>
 #include <asm/sections.h>
+#include <asm/fixmap.h>

 extern pgd_t early_level4_pgt[PTRS_PER_PGD];
 extern struct range pfn_mapped[E820_X_MAX];
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 011b446f8758..84e637f2fa49 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -35,6 +35,7 @@
 #include <linux/uaccess.h>
 #include <asm/tlbflush.h>
 #include <asm/shmparam.h>
+#include <asm/fixmap.h>

 #include "internal.h"

-- 
2.11.0.483.g087da7b7c-goog

On Fri, Feb 17, 2017 at 8:00 AM, Thomas Garnier <thgarnie@google.com> wrote:
> I will send an update patch on this thread to fix the fixmap dependencies.
>
> On Thu, Feb 16, 2017 at 4:45 PM, kbuild test robot <lkp@intel.com> wrote:
>>
>> Hi Thomas,
>>
>> [auto build test ERROR on next-20170216]
>> [also build test ERROR on v4.10-rc8]
>> [cannot apply to tip/x86/core kvm/linux-next tip/auto-latest v4.9-rc8
>> v4.9-rc7 v4.9-rc6]
>> [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/Thomas-Garnier/x86-mm-Adapt-MODULES_END-based-on-Fixmap-section-size/20170217-072759
>> config: x86_64-randconfig-s4-02170325 (attached as .config)
>> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
>> reproduce:
>>         # save the attached .config to linux build tree
>>         make ARCH=x86_64
>>
>> All errors (new ones prefixed by >>):
>>
>>    In file included from arch/x86/include/asm/pgtable_types.h:240:0,
>>                     from arch/x86/include/asm/paravirt_types.h:44,
>>                     from arch/x86/include/asm/ptrace.h:71,
>>                     from arch/x86/include/asm/math_emu.h:4,
>>                     from arch/x86/include/asm/processor.h:11,
>>                     from arch/x86/include/asm/cpufeature.h:4,
>>                     from arch/x86/include/asm/thread_info.h:52,
>>                     from include/linux/thread_info.h:25,
>>                     from arch/x86/include/asm/preempt.h:6,
>>                     from include/linux/preempt.h:59,
>>                     from include/linux/spinlock.h:50,
>>                     from include/linux/wait.h:8,
>>                     from include/linux/fs.h:5,
>>                     from include/linux/debugfs.h:18,
>>                     from arch/x86/mm/dump_pagetables.c:15:
>> >> arch/x86/include/asm/pgtable_64_types.h:71:23: error: implicit
>> >> declaration of function '__fix_to_virt'
>> >> [-Werror=implicit-function-declaration]
>>     #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>>                           ^
>>    arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro
>> 'MODULES_END'
>>      { MODULES_END,          "End Modules" },
>>        ^~~~~~~~~~~
>>    arch/x86/include/asm/pgtable_64_types.h:71:37: error:
>> '__end_of_fixed_addresses' undeclared here (not in a function)
>>     #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>>                                         ^
>>    arch/x86/mm/dump_pagetables.c:87:4: note: in expansion of macro
>> 'MODULES_END'
>>      { MODULES_END,          "End Modules" },
>>        ^~~~~~~~~~~
>>    cc1: some warnings being treated as errors
>>
>> vim +/__fix_to_virt +71 arch/x86/include/asm/pgtable_64_types.h
>>
>>     65  #define VMALLOC_START   __VMALLOC_BASE
>>     66  #define VMEMMAP_START   __VMEMMAP_BASE
>>     67  #endif /* CONFIG_RANDOMIZE_MEMORY */
>>     68  #define VMALLOC_END     (VMALLOC_START + _AC((VMALLOC_SIZE_TB <<
>> 40) - 1, UL))
>>     69  #define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
>>     70  /* The module sections ends with the start of the fixmap */
>>   > 71  #define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
>>     72  #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
>>     73  #define ESPFIX_PGD_ENTRY _AC(-2, UL)
>>     74  #define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)
>>
>> ---
>> 0-DAY kernel test infrastructure                Open Source Technology
>> Center
>> https://lists.01.org/pipermail/kbuild-all                   Intel
>> Corporation
>
>
>
>
> --
> Thomas



-- 
Thomas

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size
@ 2017-02-16 21:54 Thomas Garnier
  0 siblings, 0 replies; 39+ messages in thread
From: Thomas Garnier @ 2017-02-16 21:54 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H . Peter Anvin, Jonathan Corbet,
	Thomas Garnier, Kees Cook, Lorenzo Stoakes, Juergen Gross,
	Andy Lutomirski, Rafael J . Wysocki, Len Brown, Pavel Machek,
	Jiri Kosina, Matt Fleming, Ard Biesheuvel, Boris Ostrovsky,
	Rusty Russell, Borislav Petkov, Christian Borntraeger,
	Brian Gerst, He Chen, Luis R . Rodriguez, Stanislaw Gruszka,
	Arnd Bergmann
  Cc: linux-efi, kvm, linux-pm, x86, linux-doc, linux-kernel, lguest,
	kernel-hardening, xen-devel

This patch aligns MODULES_END to the beginning of the Fixmap section.
It optimizes the space available for both sections. The address is
pre-computed based on the number of pages required by the Fixmap
section.

It will allow GDT remapping in the Fixmap section. The current
MODULES_END static address does not provide enough space for the kernel
to support a large number of processors.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170213
---
 Documentation/x86/x86_64/mm.txt         | 5 ++++-
 arch/x86/include/asm/pgtable_64_types.h | 3 ++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/Documentation/x86/x86_64/mm.txt b/Documentation/x86/x86_64/mm.txt
index 5724092db811..ee3f9c30957c 100644
--- a/Documentation/x86/x86_64/mm.txt
+++ b/Documentation/x86/x86_64/mm.txt
@@ -19,7 +19,7 @@ ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks
 ffffffef00000000 - fffffffeffffffff (=64 GB) EFI region mapping space
 ... unused hole ...
 ffffffff80000000 - ffffffff9fffffff (=512 MB)  kernel text mapping, from phys 0
-ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space
+ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space (variable)
 ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls
 ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole
 
@@ -39,6 +39,9 @@ memory window (this size is arbitrary, it can be raised later if needed).
 The mappings are not part of any other kernel PGD and are only available
 during EFI runtime calls.
 
+The module mapping space size changes based on the CONFIG requirements for the
+following fixmap section.
+
 Note that if CONFIG_RANDOMIZE_MEMORY is enabled, the direct mapping of all
 physical memory, vmalloc/ioremap space and virtual memory map are randomized.
 Their order is preserved but their base will be offset early at boot time.
diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h
index 3a264200c62f..bb05e21cf3c7 100644
--- a/arch/x86/include/asm/pgtable_64_types.h
+++ b/arch/x86/include/asm/pgtable_64_types.h
@@ -67,7 +67,8 @@ typedef struct { pteval_t pte; } pte_t;
 #endif /* CONFIG_RANDOMIZE_MEMORY */
 #define VMALLOC_END	(VMALLOC_START + _AC((VMALLOC_SIZE_TB << 40) - 1, UL))
 #define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
-#define MODULES_END      _AC(0xffffffffff000000, UL)
+/* The module sections ends with the start of the fixmap */
+#define MODULES_END   __fix_to_virt(__end_of_fixed_addresses + 1)
 #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
 #define ESPFIX_PGD_ENTRY _AC(-2, UL)
 #define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)
-- 
2.11.0.483.g087da7b7c-goog


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 39+ messages in thread

end of thread, other threads:[~2017-02-17 20:53 UTC | newest]

Thread overview: 39+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-16 21:54 [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size Thomas Garnier
2017-02-16 21:54 ` [kernel-hardening] " Thomas Garnier
2017-02-16 21:54 ` Thomas Garnier
2017-02-16 21:54 ` Thomas Garnier
2017-02-16 21:54 ` [PATCH v4 2/4] x86: Remap GDT tables in the Fixmap section Thomas Garnier
2017-02-16 21:54 ` Thomas Garnier
2017-02-16 21:54   ` [kernel-hardening] " Thomas Garnier
2017-02-16 21:54   ` Thomas Garnier
2017-02-16 21:54   ` Thomas Garnier
2017-02-16 21:54 ` [PATCH v4 3/4] x86: Make the GDT remapping read-only on 64-bit Thomas Garnier
2017-02-16 21:54 ` Thomas Garnier
2017-02-16 21:54   ` [kernel-hardening] " Thomas Garnier
2017-02-16 21:54   ` Thomas Garnier
2017-02-16 21:54   ` Thomas Garnier
2017-02-16 21:54 ` [PATCH v4 4/4] KVM: VMX: Simplify segment_base Thomas Garnier
2017-02-16 21:54 ` Thomas Garnier
2017-02-16 21:54   ` [kernel-hardening] " Thomas Garnier
2017-02-16 21:54   ` Thomas Garnier
2017-02-16 21:54   ` Thomas Garnier
2017-02-17  0:37 ` [PATCH v4 1/4] x86/mm: Adapt MODULES_END based on Fixmap section size kbuild test robot
2017-02-17  0:37 ` kbuild test robot
2017-02-17  0:37   ` [kernel-hardening] " kbuild test robot
2017-02-17  0:37   ` kbuild test robot
2017-02-17  0:37   ` kbuild test robot
2017-02-17  0:45 ` kbuild test robot
2017-02-17  0:45 ` kbuild test robot
2017-02-17  0:45   ` [kernel-hardening] " kbuild test robot
2017-02-17  0:45   ` kbuild test robot
2017-02-17  0:45   ` kbuild test robot
2017-02-17 16:00   ` Thomas Garnier
2017-02-17 16:00   ` Thomas Garnier
2017-02-17 16:00     ` [kernel-hardening] " Thomas Garnier
2017-02-17 16:00     ` Thomas Garnier
2017-02-17 20:52     ` Thomas Garnier
2017-02-17 20:52       ` [kernel-hardening] " Thomas Garnier
2017-02-17 20:52       ` Thomas Garnier
2017-02-17 20:52       ` Thomas Garnier
2017-02-17 20:52     ` Thomas Garnier
  -- strict thread matches above, loose matches on Subject: below --
2017-02-16 21:54 Thomas Garnier

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.