Misc GDT fixes and a cleanup
Subsystems (7)
Andy Lutomirski
maintainercover Misc GDT fixes and a cleanup
Hi all-
This applies to tip:x86/mm. For ease of testing, the series is here, too:
https://git.kernel.org/pub/scm/linux/kernel/git/luto/linux.git/tag/?h=review_20170322_gdt_and_wp
This fixes a few issues, most of which appear to be rather old. For whatever reason, Thomas' GDT series unearthed them. (And one is a genuine bug in Thomas' code but, in his defense, he might have cut-and-pasted it verbatim from the identical bug in the EFI code.)
The last three patches are cleanups I did while tracking these down.
Boris, any chance you could test this series on Xen? The 64-bit case works for me, but I'm having issues testing on 32-bit right now.
Ingo, the first patch should address your concerns from the earlier version.
Andy Lutomirski (7):
selftests/x86/ldt_gdt_32: Work around a glibc sigaction bug x86/gdt: Fix setup_fixmap_gdt() to use the correct PA x86/efi/32: Fix EFI on systems where the percpu GDT is virtually
mapped
x86/boot/32: Defer resyncing initial_page_table until percpu is set up x86/gdt: Get rid of the get_*_gdt_*_vaddr() helpers x86/xen/gdt: Use X86_FEATURE_XENPV instead of globals for the GDT
fixup
x86/boot/32: Rewrite test_wp_bit()
arch/x86/include/asm/desc.h | 21 +++------------- arch/x86/include/asm/processor.h | 2 -- arch/x86/kernel/cpu/common.c | 28 ++++++++++++--------- arch/x86/kernel/cpu/proc.c | 5 ++-- arch/x86/kernel/setup.c | 17 ------------- arch/x86/kernel/setup_percpu.c | 21 ++++++++++++++++ arch/x86/kvm/vmx.c | 4 +-- arch/x86/mm/init_32.c | 44 +++++++-------------------------- arch/x86/platform/efi/efi_32.c | 2 +- arch/x86/xen/enlighten.c | 4 --- tools/testing/selftests/x86/ldt_gdt.c | 46 +++++++++++++++++++++++++++++++++++ 11 files changed, 101 insertions(+), 93 deletions(-)
Signature · 1 line
2.9.3
Andy Lutomirski
maintainerPATCH 1/7 selftests/x86/ldt_gdt_32: Work around a glibc sigaction bug
i386 glibc is buggy and calls the sigaction syscall incorrectly. This is asymptomatic for normal programs, but it blows up on programs that do evil things with segmentation. ldt_gdt an example of such an evil program.
This doesn't appear to be a regression -- I think I just got lucky with the uninitialized memory that glibc threw at the kernel when I wrote the test.
This hackish fix manually issues sigaction(2) syscalls to undo the damage. Without the fix, ldt_gdt_32 segfaults; with the fix, it passes for me.
See https://sourceware.org/bugzilla/show_bug.cgi?id=21269
--- tools/testing/selftests/x86/ldt_gdt.c | 46 +++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+)
tools/testing/selftests/x86/ldt_gdt.c +46 -0
@@ -409,6 +409,51 @@ static void *threadproc(void *ctx) } } +#ifdef __i386__ + +#ifndef SA_RESTORE +#define SA_RESTORER 0x04000000 +#endif + +/* +* The UAPI header calls this 'struct sigaction', which conflicts with +* glibc. Sigh. +*/ +struct fake_ksigaction { +void *handler;/* the real type is nasty */ +unsigned long sa_flags; +void (*sa_restorer)(void ); +unsigned char sigset[8 ]; +}; + +static void fix_sa_restorer (int sig) +{ +struct fake_ksigaction ksa; + +if (syscall (SYS_rt_sigaction, sig,NULL , &ksa,8 ) ==0 ) { +/* +* glibc has a nasty bug: it sometimes writes garbage to +* sa_restorer. This interacts quite badly with anything +* that fiddles with SS because it can trigger legacy +* stack switching. Patch it up. See: +* +* https://sourceware.org/bugzilla/show_bug.cgi?id=21269 +*/ +if (!(ksa.sa_flags &SA_RESTORER ) && ksa.sa_restorer) { + ksa.sa_restorer =NULL ; +if (syscall (SYS_rt_sigaction, sig, &ksa,NULL , +sizeof (ksa.sigset)) !=0 ) +err (1 ,"rt_sigaction" ); + } + } +} +#else +static void fix_sa_restorer (int sig) +{ +/* 64-bit glibc works fine. */ +} +#endif +static void sethandler (int sig,void (*handler)(int ,siginfo_t *,void *),int flags) {
@@ -420,6 +465,7 @@ static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),if (sigaction (sig, &sa,0 ))err (1 ,"sigaction" ); +fix_sa_restorer (sig); }static jmp_buf jmpbuf;
Signature · 1 line
2.9.3
tip-bot for Andy Lutomirski
merge bot[tip:x86/mm] selftests/x86/ldt_gdt_32: Work around a glibc sigaction() bug
selftests/x86/ldt_gdt_32: Work around a glibc sigaction() bug
Commit-ID: 65973dd3fd31151823f4b8c289eebbb3fb7e6bc0 Gitweb: http://git.kernel.org/tip/65973dd3fd31151823f4b8c289eebbb3fb7e6bc0 Author: Andy Lutomirski <[email protected]> AuthorDate: Wed, 22 Mar 2017 14:32:29 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Thu, 23 Mar 2017 08:25:07 +0100
selftests/x86/ldt_gdt_32: Work around a glibc sigaction() bug
i386 glibc is buggy and calls the sigaction syscall incorrectly.
This is asymptomatic for normal programs, but it blows up on programs that do evil things with segmentation. The ldt_gdt self-test is an example of such an evil program.
This doesn't appear to be a regression -- I think I just got lucky with the uninitialized memory that glibc threw at the kernel when I wrote the test.
This hackish fix manually issues sigaction(2) syscalls to undo the damage. Without the fix, ldt_gdt_32 segfaults; with the fix, it passes for me.
See: https://sourceware.org/bugzilla/show_bug.cgi?id=21269
--- tools/testing/selftests/x86/ldt_gdt.c | 46 +++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+)
tools/testing/selftests/x86/ldt_gdt.c +46 -0
@@ -409,6 +409,51 @@ static void *threadproc(void *ctx) } } +#ifdef __i386__ + +#ifndef SA_RESTORE +#define SA_RESTORER 0x04000000 +#endif + +/* +* The UAPI header calls this 'struct sigaction', which conflicts with +* glibc. Sigh. +*/ +struct fake_ksigaction { +void *handler;/* the real type is nasty */ +unsigned long sa_flags; +void (*sa_restorer)(void ); +unsigned char sigset[8 ]; +}; + +static void fix_sa_restorer (int sig) +{ +struct fake_ksigaction ksa; + +if (syscall (SYS_rt_sigaction, sig,NULL , &ksa,8 ) ==0 ) { +/* +* glibc has a nasty bug: it sometimes writes garbage to +* sa_restorer. This interacts quite badly with anything +* that fiddles with SS because it can trigger legacy +* stack switching. Patch it up. See: +* +* https://sourceware.org/bugzilla/show_bug.cgi?id=21269 +*/ +if (!(ksa.sa_flags &SA_RESTORER ) && ksa.sa_restorer) { + ksa.sa_restorer =NULL ; +if (syscall (SYS_rt_sigaction, sig, &ksa,NULL , +sizeof (ksa.sigset)) !=0 ) +err (1 ,"rt_sigaction" ); + } + } +} +#else +static void fix_sa_restorer (int sig) +{ +/* 64-bit glibc works fine. */ +} +#endif +static void sethandler (int sig,void (*handler)(int ,siginfo_t *,void *),int flags) {
@@ -420,6 +465,7 @@ static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),if (sigaction (sig, &sa,0 ))err (1 ,"sigaction" ); +fix_sa_restorer (sig); }static jmp_buf jmpbuf;
Andy Lutomirski
maintainerPATCH 2/7 x86/gdt: Fix setup_fixmap_gdt() to use the correct PA
In reply to Andy Lutomirski__pa() cannot be used on percpu pointers because they may be virtually mapped. Use per_cpu_ptr_to_phys() instead.
This fixes a boot crash on a some 32-bit configurations. I assume this is related to which allocation strategy is chosen by the percpu core.
--- arch/x86/include/asm/desc.h | 6 ++++++ arch/x86/kernel/cpu/common.c | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-)
arch/x86/include/asm/desc.h +6 -0
@@ -98,6 +98,12 @@ static inline unsigned long get_current_gdt_ro_vaddr(void)return (unsigned long )get_current_gdt_ro (); } +/* Provide the physical address of the GDT page. */ +static inline phys_addr_t get_cpu_gdt_paddr (unsigned int cpu) +{ +return per_cpu_ptr_to_phys (get_cpu_gdt_rw (cpu)); +} +#ifdef CONFIG_X86_64 static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func,
arch/x86/kernel/cpu/common.c +2 -2
@@ -461,8 +461,8 @@ pgprot_t pg_fixmap_gdt_flags = PAGE_KERNEL;/* 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)), pg_fixmap_gdt_flags); +__set_fixmap (get_cpu_gdt_ro_index (cpu),get_cpu_gdt_paddr (cpu), + pg_fixmap_gdt_flags); }/* Load the original GDT from the per-cpu structure */
Signature · 1 line
2.9.3
tip-bot for Andy Lutomirski
merge bot[tip:x86/mm] x86/gdt: Fix setup_fixmap_gdt() to use the correct PA
x86/gdt: Fix setup_fixmap_gdt() to use the correct PA
Commit-ID: aa4ea675528f3fa11e9663e5a32f55a81c34dcac Gitweb: http://git.kernel.org/tip/aa4ea675528f3fa11e9663e5a32f55a81c34dcac Author: Andy Lutomirski <[email protected]> AuthorDate: Wed, 22 Mar 2017 14:32:30 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Thu, 23 Mar 2017 08:25:07 +0100
x86/gdt: Fix setup_fixmap_gdt() to use the correct PA
__pa() cannot be used on percpu pointers because they may be virtually mapped. Use per_cpu_ptr_to_phys() instead.
This fixes a boot crash on a some 32-bit configurations. I assume this is related to which allocation strategy is chosen by the percpu core.
--- arch/x86/include/asm/desc.h | 6 ++++++ arch/x86/kernel/cpu/common.c | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-)
arch/x86/include/asm/desc.h +6 -0
@@ -98,6 +98,12 @@ static inline unsigned long get_current_gdt_ro_vaddr(void)return (unsigned long )get_current_gdt_ro (); } +/* Provide the physical address of the GDT page. */ +static inline phys_addr_t get_cpu_gdt_paddr (unsigned int cpu) +{ +return per_cpu_ptr_to_phys (get_cpu_gdt_rw (cpu)); +} +#ifdef CONFIG_X86_64 static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func,
arch/x86/kernel/cpu/common.c +2 -2
@@ -461,8 +461,8 @@ pgprot_t pg_fixmap_gdt_flags = PAGE_KERNEL;/* 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)), pg_fixmap_gdt_flags); +__set_fixmap (get_cpu_gdt_ro_index (cpu),get_cpu_gdt_paddr (cpu), + pg_fixmap_gdt_flags); }/* Load the original GDT from the per-cpu structure */
Andy Lutomirski
maintainerPATCH 3/7 x86/efi/32: Fix EFI on systems where the percpu GDT is virtually mapped
In reply to Andy Lutomirski__pa on a percpu pointer is invalid. This bug appears to go *waaay* back, and I guess it's just never been triggered.
--- arch/x86/platform/efi/efi_32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/platform/efi/efi_32.c +1 -1
@@ -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_rw (0 )); + gdt_descr.address =get_cpu_gdt_paddr (0 ); gdt_descr.size =GDT_SIZE -1 ;load_gdt (&gdt_descr);
Signature · 1 line
2.9.3
tip-bot for Andy Lutomirski
merge bot[tip:x86/mm] x86/efi/32: Fix EFI on systems where the per-cpu GDT is virtually mapped
x86/efi/32: Fix EFI on systems where the per-cpu GDT is virtually mapped
Commit-ID: 3fa1cabbc3b61224ef33d3ca4a1a96998529bc68 Gitweb: http://git.kernel.org/tip/3fa1cabbc3b61224ef33d3ca4a1a96998529bc68 Author: Andy Lutomirski <[email protected]> AuthorDate: Wed, 22 Mar 2017 14:32:31 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Thu, 23 Mar 2017 08:25:07 +0100
x86/efi/32: Fix EFI on systems where the per-cpu GDT is virtually mapped
__pa() on a per-cpu pointer is invalid. This bug appears to go *waaay* back, and I guess it's just never been triggered.
--- arch/x86/platform/efi/efi_32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/platform/efi/efi_32.c +1 -1
@@ -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_rw (0 )); + gdt_descr.address =get_cpu_gdt_paddr (0 ); gdt_descr.size =GDT_SIZE -1 ;load_gdt (&gdt_descr);
Andy Lutomirski
maintainerPATCH 4/7 x86/boot/32: Defer resyncing initial_page_table until percpu is set up
In reply to Andy LutomirskiThe x86 smpboot trampoline expects initial_page_table to have the GDT mapped. If the GDT ends up in a virtually mapped percpu page, then it won't be in the page tables at all until percpu areas are set up. The result will be a triple fault the first time that the CPU attempts to access the GDT after LGDT loads the percpu GDT.
This appears to be an old bug, but somehow the GDT fixmap rework is triggering it. This seems to have something to do with the memory layout.
--- arch/x86/kernel/setup.c | 15 --------------- arch/x86/kernel/setup_percpu.c | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 15 deletions(-)
arch/x86/kernel/setup.c +0 -15
@@ -1226,21 +1226,6 @@ void __init setup_arch(char **cmdline_p)kasan_init (); -#ifdef CONFIG_X86_32 -/* sync back kernel address range */ -clone_pgd_range (initial_page_table +KERNEL_PGD_BOUNDARY , - swapper_pg_dir +KERNEL_PGD_BOUNDARY , -KERNEL_PGD_PTRS ); - -/* -* sync back low identity map too. It is used for example -* in the 32-bit EFI stub. -*/ -clone_pgd_range (initial_page_table, - swapper_pg_dir +KERNEL_PGD_BOUNDARY , -min (KERNEL_PGD_PTRS ,KERNEL_PGD_BOUNDARY )); -#endif -tboot_probe ();map_vsyscall ();
arch/x86/kernel/setup_percpu.c +21 -0
@@ -288,4 +288,25 @@ void __init setup_per_cpu_areas(void)/* Setup cpu initialized, callin, callout masks */ setup_cpu_local_masks (); + +#ifdef CONFIG_X86_32 +/* +* Sync back kernel address range. We want to make sure that +* all kernel mappings, including percpu mappings, are available +* in the smpboot asm. We can't reliably pick up percpu +* mappings using vmalloc_fault(), because exception dispatch +* needs percpu data. +*/ +clone_pgd_range (initial_page_table +KERNEL_PGD_BOUNDARY , + swapper_pg_dir +KERNEL_PGD_BOUNDARY , +KERNEL_PGD_PTRS ); + +/* +* sync back low identity map too. It is used for example +* in the 32-bit EFI stub. +*/ +clone_pgd_range (initial_page_table, + swapper_pg_dir +KERNEL_PGD_BOUNDARY , +min (KERNEL_PGD_PTRS ,KERNEL_PGD_BOUNDARY )); +#endif }
Signature · 1 line
2.9.3
tip-bot for Andy Lutomirski
merge bot[tip:x86/mm] x86/boot/32: Defer resyncing initial_page_table until per-cpu is set up
x86/boot/32: Defer resyncing initial_page_table until per-cpu is set up
Commit-ID: 23b2a4ddebdd17fad265b4bb77256c2e4ec37dee Gitweb: http://git.kernel.org/tip/23b2a4ddebdd17fad265b4bb77256c2e4ec37dee Author: Andy Lutomirski <[email protected]> AuthorDate: Wed, 22 Mar 2017 14:32:32 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Thu, 23 Mar 2017 08:25:08 +0100
x86/boot/32: Defer resyncing initial_page_table until per-cpu is set up
The x86 smpboot trampoline expects initial_page_table to have the GDT mapped. If the GDT ends up in a virtually mapped per-cpu page, then it won't be in the page tables at all until perc-pu areas are set up. The result will be a triple fault the first time that the CPU attempts to access the GDT after LGDT loads the perc-pu GDT.
This appears to be an old bug, but somehow the GDT fixmap rework is triggering it. This seems to have something to do with the memory layout.
--- arch/x86/kernel/setup.c | 15 --------------- arch/x86/kernel/setup_percpu.c | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 15 deletions(-)
arch/x86/kernel/setup.c +0 -15
@@ -1226,21 +1226,6 @@ void __init setup_arch(char **cmdline_p)kasan_init (); -#ifdef CONFIG_X86_32 -/* sync back kernel address range */ -clone_pgd_range (initial_page_table +KERNEL_PGD_BOUNDARY , - swapper_pg_dir +KERNEL_PGD_BOUNDARY , -KERNEL_PGD_PTRS ); - -/* -* sync back low identity map too. It is used for example -* in the 32-bit EFI stub. -*/ -clone_pgd_range (initial_page_table, - swapper_pg_dir +KERNEL_PGD_BOUNDARY , -min (KERNEL_PGD_PTRS ,KERNEL_PGD_BOUNDARY )); -#endif -tboot_probe ();map_vsyscall ();
arch/x86/kernel/setup_percpu.c +21 -0
@@ -288,4 +288,25 @@ void __init setup_per_cpu_areas(void)/* Setup cpu initialized, callin, callout masks */ setup_cpu_local_masks (); + +#ifdef CONFIG_X86_32 +/* +* Sync back kernel address range. We want to make sure that +* all kernel mappings, including percpu mappings, are available +* in the smpboot asm. We can't reliably pick up percpu +* mappings using vmalloc_fault(), because exception dispatch +* needs percpu data. +*/ +clone_pgd_range (initial_page_table +KERNEL_PGD_BOUNDARY , + swapper_pg_dir +KERNEL_PGD_BOUNDARY , +KERNEL_PGD_PTRS ); + +/* +* sync back low identity map too. It is used for example +* in the 32-bit EFI stub. +*/ +clone_pgd_range (initial_page_table, + swapper_pg_dir +KERNEL_PGD_BOUNDARY , +min (KERNEL_PGD_PTRS ,KERNEL_PGD_BOUNDARY )); +#endif }
Re: [tip:x86/mm] x86/boot/32: Defer resyncing initial_page_table until per-cpu is set up
Quoted 79 lines · tip-bot for Andy Lutomirski
The x86 smpboot trampoline expects
initial_page_tableto have the GDT mapped. If the GDT ends up in a virtually mapped per-cpu page, then it won't be in the page tables at all until perc-pu areas are set up. The result will be a triple fault the first time that the CPU attempts to access the GDT after LGDT loads the perc-pu GDT.This appears to be an old bug, but somehow the GDT fixmap rework is triggering it. This seems to have something to do with the memory layout.
Signed-off-by Andy Lutomirski <[email protected]>Cc Ard Biesheuvel <[email protected]>Cc Boris Ostrovsky <[email protected]>Cc Borislav Petkov <[email protected]>Cc Brian Gerst <[email protected]>Cc Denys Vlasenko <[email protected]>Cc H. Peter Anvin <[email protected]>Cc Josh Poimboeuf <[email protected]>Cc Juergen Gross <jgross-IBi9RG/[email protected]>Cc Linus Torvalds <torvalds-de/[email protected]>Cc Matt Fleming <matt-mF/unelCI9GS6iBeEJttW/[email protected]>Cc Peter Zijlstra <[email protected]>Cc Thomas Garnier <[email protected]>Cc Thomas Gleixner <[email protected]>Link http://lkml.kernel.org/r/a553264a5972c6a86f9b5caac237470a0c74a720.1490218061.git.luto-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org open hereSigned-off-by Ingo Molnar <[email protected]>--- arch/x86/kernel/setup.c | 15 --------------- arch/x86/kernel/setup_percpu.c | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 15 deletions(-)arch/x86/kernel/setup.c +0
-15@@ -1226,21 +1226,6 @@ void __init setup_arch(char **cmdline_p)kasan_init (); -#ifdef CONFIG_X86_32 -/* sync back kernel address range */ -clone_pgd_range (initial_page_table +KERNEL_PGD_BOUNDARY , - swapper_pg_dir +KERNEL_PGD_BOUNDARY , -KERNEL_PGD_PTRS ); - -/* -* sync back low identity map too. It is used for example -* in the 32-bit EFI stub. -*/ -clone_pgd_range (initial_page_table, - swapper_pg_dir +KERNEL_PGD_BOUNDARY , -min (KERNEL_PGD_PTRS ,KERNEL_PGD_BOUNDARY )); -#endif -tboot_probe ();map_vsyscall ();arch/x86/kernel/setup_percpu.c +12
-0@@ -288,4 +288,25 @@ void __init setup_per_cpu_areas(void)/* Setup cpu initialized, callin, callout masks */ setup_cpu_local_masks (); + +#ifdef CONFIG_X86_32 +/* +* Sync back kernel address range. We want to make sure that +* all kernel mappings, including percpu mappings, are available +* in the smpboot asm. We can't reliably pick up percpu +* mappings using vmalloc_fault(), because exception dispatch +* needs percpu data. +*/ +clone_pgd_range (initial_page_table +KERNEL_PGD_BOUNDARY , + swapper_pg_dir +KERNEL_PGD_BOUNDARY , +KERNEL_PGD_PTRS );
arch/x86/kernel/setup_percpu.c void __init setup_per_cpu_areas(void) · line 312
Quoted 10 lines
arch/x86/kernel/setup_percpu.c +9
-0+ +/* +* sync back low identity map too. It is used for example +* in the 32-bit EFI stub. +*/ +clone_pgd_range (initial_page_table, + swapper_pg_dir +KERNEL_PGD_BOUNDARY , +min (KERNEL_PGD_PTRS ,KERNEL_PGD_BOUNDARY )); +#endif }
This breaks the boot on our Intel Quark platform (IOT2000, similar to Galileo Gen2). Reverting it over master makes it work again. Any idea what goes wrong? Let me know how I can help debugging this.
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT RDA ITP SES-DE Corporate Competence Center Embedded Linux
Re: [tip:x86/mm] x86/boot/32: Defer resyncing initial_page_table until per-cpu is set up
Quoted 7 lines · Jan Kiszka
Quoted 6 lines · tip-bot for Andy Lutomirski
The x86 smpboot trampoline expects
initial_page_tableto have the GDT mapped. If the GDT ends up in a virtually mapped per-cpu page, then it won't be in the page tables at all until perc-pu areas are set up. The result will be a triple fault the first time that the CPU attempts to access the GDT after LGDT loads the perc-pu GDT.
Quoted 7 lines
Quoted 3 lines
This appears to be an old bug, but somehow the GDT fixmap rework is triggering it. This seems to have something to do with the memory layout.
This breaks the boot on our Intel Quark platform (IOT2000, similar to Galileo Gen2). Reverting it over master makes it work again. Any idea what goes wrong? Let me know how I can help debugging this.
JFYI: As of today linux-next when _kexec:ed_ works fine to me
Perhaps I can test this later with direct boot from SD card.
Signature · 2 lines
With Best Regards, Andy Shevchenko
Andy Lutomirski
maintainerRe: [tip:x86/mm] x86/boot/32: Defer resyncing initial_page_table until per-cpu is set up
Quoted 12 lines · Andy Shevchenko
Quoted 10 lines · Jan Kiszka
Quoted 9 lines · tip-bot for Andy Lutomirski
The x86 smpboot trampoline expects
initial_page_tableto have the GDT mapped. If the GDT ends up in a virtually mapped per-cpu page, then it won't be in the page tables at all until perc-pu areas are set up. The result will be a triple fault the first time that the CPU attempts to access the GDT after LGDT loads the perc-pu GDT.This appears to be an old bug, but somehow the GDT fixmap rework is triggering it. This seems to have something to do with the memory layout.
Quoted 8 lines
Quoted 3 lines
This breaks the boot on our Intel Quark platform (IOT2000, similar to Galileo Gen2). Reverting it over master makes it work again. Any idea what goes wrong? Let me know how I can help debugging this.
JFYI: As of today linux-next when _kexec:ed_ works fine to me
Perhaps I can test this later with direct boot from SD card.
The most likely explanation is that there's some code that needs the page table synced and runs before setup_per_cpu_areas(). The relevant init code is:
setup_arch(&command_line);
mm_init_cpumask(&init_mm);
setup_command_line(command_line);
setup_nr_cpu_ids();
setup_per_cpu_areas();so I didn't move it very far. It would be awesome if we could get a backtrace when the failure happens, but it's likely to be a triple fault. Is this an EFI boot? I bet the failure is in efi_init().
Could you try reverting just the deletions in the patch? I.e. try a kernel with both the old and the new copies of the code I moved.
--Andy
Re: [tip:x86/mm] x86/boot/32: Defer resyncing initial_page_table until per-cpu is set up
Quoted 33 lines · Andy Lutomirski
Quoted 12 lines · Andy Shevchenko
Quoted 10 lines · Jan Kiszka
Quoted 9 lines · tip-bot for Andy Lutomirski
The x86 smpboot trampoline expects
initial_page_tableto have the GDT mapped. If the GDT ends up in a virtually mapped per-cpu page, then it won't be in the page tables at all until perc-pu areas are set up. The result will be a triple fault the first time that the CPU attempts to access the GDT after LGDT loads the perc-pu GDT.This appears to be an old bug, but somehow the GDT fixmap rework is triggering it. This seems to have something to do with the memory layout.
Quoted 8 lines
Quoted 3 lines
This breaks the boot on our Intel Quark platform (IOT2000, similar to Galileo Gen2). Reverting it over master makes it work again. Any idea what goes wrong? Let me know how I can help debugging this.
JFYI: As of today linux-next when _kexec:ed_ works fine to me
Perhaps I can test this later with direct boot from SD card.
The most likely explanation is that there's some code that needs the page table synced and runs before
setup_per_cpu_areas(). The relevant init code is:setup_arch(&command_line); mm_init_cpumask(&init_mm); setup_command_line(command_line); setup_nr_cpu_ids(); setup_per_cpu_areas();
Quoted 3 lines
so I didn't move it very far. It would be awesome if we could get a backtrace when the failure happens, but it's likely to be a triple fault. Is this an EFI boot? I bet the failure is in
efi_init().
Yes, it's an EFI thing. Unfortunately, I didn't make earlycon/earlyprintk work yet.
Quoted 3 lines
Could you try reverting just the deletions in the patch? I.e. try a kernel with both the old and the new copies of the code I moved.
Let me try that later. I can also move the new code around to nail down the dependency.
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT RDA ITP SES-DE Corporate Competence Center Embedded Linux
Re: [tip:x86/mm] x86/boot/32: Defer resyncing initial_page_table until per-cpu is set up
Quoted 4 lines · Jan Kiszka
On 2017-05-08 13:21, Andy Lutomirski wrote:
Yes, it's an EFI thing. Unfortunately, I didn't make earlycon/earlyprintk work yet.
Quark does use HS UART for the console and we have no support for such in x86/earlyprintk. earlycon should work if you add proper parameters to the command line (including port base address, no ttySx), though I don't remember if it makes really "early".
Signature · 2 lines
With Best Regards, Andy Shevchenko
Re: [tip:x86/mm] x86/boot/32: Defer resyncing initial_page_table until per-cpu is set up
Quoted 10 lines · Andy Shevchenko
Quoted 4 lines · Jan Kiszka
On 2017-05-08 13:21, Andy Lutomirski wrote:
Yes, it's an EFI thing. Unfortunately, I didn't make earlycon/earlyprintk work yet.
Quark does use HS UART for the console and we have no support for such in x86/earlyprintk. earlycon should work if you add proper parameters to the command line (including port base address, no ttySx), though I don't remember if it makes really "early".
Ah, that explains it. I've tried earlycon, also with the apparently correct params, but it didn't print anything in this case. And earlyprintk=efi seems to use a framebuffer, while our devices are headless...
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT RDA ITP SES-DE Corporate Competence Center Embedded Linux
Re: [tip:x86/mm] x86/boot/32: Defer resyncing initial_page_table until per-cpu is set up
In reply to Jan KiszkaQuoted 42 lines · Jan Kiszka
Quoted 33 lines · Andy Lutomirski
Quoted 12 lines · Andy Shevchenko
Quoted 10 lines · Jan Kiszka
Quoted 9 lines · tip-bot for Andy Lutomirski
The x86 smpboot trampoline expects
initial_page_tableto have the GDT mapped. If the GDT ends up in a virtually mapped per-cpu page, then it won't be in the page tables at all until perc-pu areas are set up. The result will be a triple fault the first time that the CPU attempts to access the GDT after LGDT loads the perc-pu GDT.This appears to be an old bug, but somehow the GDT fixmap rework is triggering it. This seems to have something to do with the memory layout.
Quoted 8 lines
Quoted 3 lines
This breaks the boot on our Intel Quark platform (IOT2000, similar to Galileo Gen2). Reverting it over master makes it work again. Any idea what goes wrong? Let me know how I can help debugging this.
JFYI: As of today linux-next when _kexec:ed_ works fine to me
Perhaps I can test this later with direct boot from SD card.
The most likely explanation is that there's some code that needs the page table synced and runs before
setup_per_cpu_areas(). The relevant init code is:setup_arch(&command_line); mm_init_cpumask(&init_mm); setup_command_line(command_line); setup_nr_cpu_ids(); setup_per_cpu_areas();Quoted 3 lines
so I didn't move it very far. It would be awesome if we could get a backtrace when the failure happens, but it's likely to be a triple fault. Is this an EFI boot? I bet the failure is in
efi_init().Yes, it's an EFI thing. Unfortunately, I didn't make earlycon/earlyprintk work yet.
Quoted 1 line
Quoted 6 lines
Quoted 2 lines
Could you try reverting just the deletions in the patch? I.e. try a kernel with both the old and the new copies of the code I moved.
Let me try that later. I can also move the new code around to nail down the dependency.
I found the reason: your patch is very discriminating! Not the whole world is multicore yet. ;)
setup_per_cpu_areas() is taken from mm/percpu.c in case of !CONFIG_SMP. So the new home for the resync is not even built.
Any suggestions how to refactor things instead?
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT RDA ITP SES-DE Corporate Competence Center Embedded Linux
Andy Lutomirski
maintainerRe: [tip:x86/mm] x86/boot/32: Defer resyncing initial_page_table until per-cpu is set up
Quoted 50 lines · Jan Kiszka
Quoted 42 lines · Jan Kiszka
Quoted 33 lines · Andy Lutomirski
Quoted 12 lines · Andy Shevchenko
Quoted 10 lines · Jan Kiszka
Quoted 9 lines · tip-bot for Andy Lutomirski
The x86 smpboot trampoline expects
initial_page_tableto have the GDT mapped. If the GDT ends up in a virtually mapped per-cpu page, then it won't be in the page tables at all until perc-pu areas are set up. The result will be a triple fault the first time that the CPU attempts to access the GDT after LGDT loads the perc-pu GDT.This appears to be an old bug, but somehow the GDT fixmap rework is triggering it. This seems to have something to do with the memory layout.
Quoted 8 lines
Quoted 3 lines
This breaks the boot on our Intel Quark platform (IOT2000, similar to Galileo Gen2). Reverting it over master makes it work again. Any idea what goes wrong? Let me know how I can help debugging this.
JFYI: As of today linux-next when _kexec:ed_ works fine to me
Perhaps I can test this later with direct boot from SD card.
The most likely explanation is that there's some code that needs the page table synced and runs before
setup_per_cpu_areas(). The relevant init code is:setup_arch(&command_line); mm_init_cpumask(&init_mm); setup_command_line(command_line); setup_nr_cpu_ids(); setup_per_cpu_areas();Quoted 3 lines
so I didn't move it very far. It would be awesome if we could get a backtrace when the failure happens, but it's likely to be a triple fault. Is this an EFI boot? I bet the failure is in
efi_init().Yes, it's an EFI thing. Unfortunately, I didn't make earlycon/earlyprintk work yet.
Quoted 1 line
Quoted 6 lines
Quoted 2 lines
Could you try reverting just the deletions in the patch? I.e. try a kernel with both the old and the new copies of the code I moved.
Let me try that later. I can also move the new code around to nail down the dependency.
Quoted 5 lines
I found the reason: your patch is very discriminating! Not the whole world is multicore yet. ;)
setup_per_cpu_areas()is taken frommm/percpu.cin case of !CONFIG_SMP. So the new home for the resync is not even built.
D'oh!
Quoted 2 lines
Any suggestions how to refactor things instead?
efi_init() seems okay, but it makes me nervous. I think the partial revert is the right fix. Patch coming.
Quoted 6 lines
Jan
--
Siemens AG, Corporate Technology, CT RDA ITP SES-DE Corporate Competence Center Embedded Linux
Andy Lutomirski
maintainerPATCH 5/7 x86/gdt: Get rid of the get_*_gdt_*_vaddr() helpers
In reply to Andy LutomirskiThere's a single caller that is only there because it's passing a pointer into a function (vmcs_writel()) that takes an unsigned long. Let's just cast it in place rather than having a bunch of trivial helpers.
--- arch/x86/include/asm/desc.h | 20 -------------------- arch/x86/kvm/vmx.c | 4 ++-- 2 files changed, 2 insertions(+), 22 deletions(-)
arch/x86/include/asm/desc.h +0 -20
@@ -53,22 +53,12 @@ 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); -} -/* 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) {
@@ -82,22 +72,12 @@ static inline struct desc_struct *get_cpu_gdt_ro(int 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); -} -/* Provide the current read-only GDT */ static inline struct desc_struct *get_current_gdt_ro (void ) {return get_cpu_gdt_ro (smp_processor_id ()); } -static inline unsigned long get_current_gdt_ro_vaddr (void ) -{ -return (unsigned long )get_current_gdt_ro (); -} -/* Provide the physical address of the GDT page. */ static inline phys_addr_t get_cpu_gdt_paddr (unsigned int cpu) {
arch/x86/kvm/vmx.c +2 -2
@@ -2264,7 +2264,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) }if (!already_loaded) { -unsigned long gdt =get_current_gdt_ro_vaddr (); +void *gdt =get_current_gdt_ro ();unsigned long sysenter_esp;kvm_make_request (KVM_REQ_TLB_FLUSH , vcpu);
@@ -2275,7 +2275,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)*/ vmcs_writel (HOST_TR_BASE , (unsigned long )this_cpu_ptr (&cpu_tss)); -vmcs_writel (HOST_GDTR_BASE , gdt);/* 22.2.4 */ +vmcs_writel (HOST_GDTR_BASE , (unsigned long )gdt);/* 22.2.4 */ /* * VM exits change the host TR limit to 0x67 after a VM
Signature · 1 line
2.9.3
tip-bot for Andy Lutomirski
merge bot[tip:x86/mm] x86/gdt: Get rid of the get_*_gdt_*_vaddr() helpers
x86/gdt: Get rid of the get_*_gdt_*_vaddr() helpers
Commit-ID: 59c58ceb29d0f030eddb36a3a9dbadcc499786a6 Gitweb: http://git.kernel.org/tip/59c58ceb29d0f030eddb36a3a9dbadcc499786a6 Author: Andy Lutomirski <[email protected]> AuthorDate: Wed, 22 Mar 2017 14:32:33 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Thu, 23 Mar 2017 08:25:08 +0100
x86/gdt: Get rid of the get_*_gdt_*_vaddr() helpers
There's a single caller that is only there because it's passing a pointer into a function (vmcs_writel()) that takes an unsigned long. Let's just cast it in place rather than having a bunch of trivial helpers.
--- arch/x86/include/asm/desc.h | 20 -------------------- arch/x86/kvm/vmx.c | 4 ++-- 2 files changed, 2 insertions(+), 22 deletions(-)
arch/x86/include/asm/desc.h +0 -20
@@ -53,22 +53,12 @@ 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); -} -/* 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) {
@@ -82,22 +72,12 @@ static inline struct desc_struct *get_cpu_gdt_ro(int 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); -} -/* Provide the current read-only GDT */ static inline struct desc_struct *get_current_gdt_ro (void ) {return get_cpu_gdt_ro (smp_processor_id ()); } -static inline unsigned long get_current_gdt_ro_vaddr (void ) -{ -return (unsigned long )get_current_gdt_ro (); -} -/* Provide the physical address of the GDT page. */ static inline phys_addr_t get_cpu_gdt_paddr (unsigned int cpu) {
arch/x86/kvm/vmx.c +2 -2
@@ -2264,7 +2264,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) }if (!already_loaded) { -unsigned long gdt =get_current_gdt_ro_vaddr (); +void *gdt =get_current_gdt_ro ();unsigned long sysenter_esp;kvm_make_request (KVM_REQ_TLB_FLUSH , vcpu);
@@ -2275,7 +2275,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)*/ vmcs_writel (HOST_TR_BASE , (unsigned long )this_cpu_ptr (&cpu_tss)); -vmcs_writel (HOST_GDTR_BASE , gdt);/* 22.2.4 */ +vmcs_writel (HOST_GDTR_BASE , (unsigned long )gdt);/* 22.2.4 */ /* * VM exits change the host TR limit to 0x67 after a VM
Andy Lutomirski
maintainerPATCH 6/7 x86/xen/gdt: Use X86_FEATURE_XENPV instead of globals for the GDT fixup
In reply to Andy LutomirskiXen imposes special requirements on the GDT. Rather than using a global variable for the pgprot, just use an explicit special case for Xen -- this makes it clearer what's going on. It also debloats 64-bit kernels very slightly.
--- arch/x86/include/asm/desc.h | 1 - arch/x86/kernel/cpu/common.c | 28 +++++++++++++++++----------- arch/x86/xen/enlighten.c | 3 --- 3 files changed, 17 insertions(+), 15 deletions(-)
arch/x86/include/asm/desc.h +0 -1
@@ -39,7 +39,6 @@ extern struct desc_ptr idt_descr;extern gate_desc idt_table[];extern const struct desc_ptr debug_idt_descr;extern gate_desc debug_idt_table[]; -extern pgprot_t pg_fixmap_gdt_flags;struct gdt_page {struct desc_struct gdt[GDT_ENTRIES ];
arch/x86/kernel/cpu/common.c +17 -11
@@ -448,21 +448,27 @@ void load_percpu_segment(int cpu)load_stack_canary_segment (); } -/* -* On 64-bit the GDT remapping is read-only. -* A global is used for Xen to change the default when required. -*/ +/* Setup the fixmap mapping only once per-processor */ +static inline void setup_fixmap_gdt (int cpu) +{#ifdef CONFIG_X86_64 -pgprot_t pg_fixmap_gdt_flags =PAGE_KERNEL_RO ; +/* On 64-bit systems, we use a read-only fixmap GDT. */ +pgprot_t prot =PAGE_KERNEL_RO ;#else -pgprot_t pg_fixmap_gdt_flags =PAGE_KERNEL ; +/* +* On native 32-bit systems, the GDT cannot be read-only because +* our double fault handler uses a task gate, and entering through +* a task gate needs to change an available TSS to busy. If the GDT +* is read-only, that will triple fault. +* +* On Xen PV, the GDT must be read-only because the hypervisor requires +* it. +*/ +pgprot_t prot =boot_cpu_has (X86_FEATURE_XENPV ) ? +PAGE_KERNEL_RO :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),get_cpu_gdt_paddr (cpu), - pg_fixmap_gdt_flags); +__set_fixmap (get_cpu_gdt_ro_index (cpu),get_cpu_gdt_paddr (cpu), prot); }/* Load the original GDT from the per-cpu structure */
arch/x86/xen/enlighten.c +0 -3
@@ -1545,9 +1545,6 @@ asmlinkage __visible void __init xen_start_kernel(void)*/ xen_initial_gdt = &per_cpu (gdt_page,0 ); -/* GDT can only be remapped RO */ - pg_fixmap_gdt_flags =PAGE_KERNEL_RO ; -xen_smp_init ();#ifdef CONFIG_ACPI_NUMA
Signature · 1 line
2.9.3
tip-bot for Andy Lutomirski
merge bot[tip:x86/mm] x86/xen/gdt: Use X86_FEATURE_XENPV instead of globals for the GDT fixup
x86/xen/gdt: Use X86_FEATURE_XENPV instead of globals for the GDT fixup
Commit-ID: b23adb7d3f7d1d7cce03db9704de67a99ceeda38 Gitweb: http://git.kernel.org/tip/b23adb7d3f7d1d7cce03db9704de67a99ceeda38 Author: Andy Lutomirski <[email protected]> AuthorDate: Wed, 22 Mar 2017 14:32:34 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Thu, 23 Mar 2017 08:25:08 +0100
x86/xen/gdt: Use X86_FEATURE_XENPV instead of globals for the GDT fixup
Xen imposes special requirements on the GDT. Rather than using a global variable for the pgprot, just use an explicit special case for Xen -- this makes it clearer what's going on. It also debloats 64-bit kernels very slightly.
--- arch/x86/include/asm/desc.h | 1 - arch/x86/kernel/cpu/common.c | 28 +++++++++++++++++----------- arch/x86/xen/enlighten.c | 3 --- 3 files changed, 17 insertions(+), 15 deletions(-)
arch/x86/include/asm/desc.h +0 -1
@@ -39,7 +39,6 @@ extern struct desc_ptr idt_descr;extern gate_desc idt_table[];extern const struct desc_ptr debug_idt_descr;extern gate_desc debug_idt_table[]; -extern pgprot_t pg_fixmap_gdt_flags;struct gdt_page {struct desc_struct gdt[GDT_ENTRIES ];
arch/x86/kernel/cpu/common.c +17 -11
@@ -448,21 +448,27 @@ void load_percpu_segment(int cpu)load_stack_canary_segment (); } -/* -* On 64-bit the GDT remapping is read-only. -* A global is used for Xen to change the default when required. -*/ +/* Setup the fixmap mapping only once per-processor */ +static inline void setup_fixmap_gdt (int cpu) +{#ifdef CONFIG_X86_64 -pgprot_t pg_fixmap_gdt_flags =PAGE_KERNEL_RO ; +/* On 64-bit systems, we use a read-only fixmap GDT. */ +pgprot_t prot =PAGE_KERNEL_RO ;#else -pgprot_t pg_fixmap_gdt_flags =PAGE_KERNEL ; +/* +* On native 32-bit systems, the GDT cannot be read-only because +* our double fault handler uses a task gate, and entering through +* a task gate needs to change an available TSS to busy. If the GDT +* is read-only, that will triple fault. +* +* On Xen PV, the GDT must be read-only because the hypervisor requires +* it. +*/ +pgprot_t prot =boot_cpu_has (X86_FEATURE_XENPV ) ? +PAGE_KERNEL_RO :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),get_cpu_gdt_paddr (cpu), - pg_fixmap_gdt_flags); +__set_fixmap (get_cpu_gdt_ro_index (cpu),get_cpu_gdt_paddr (cpu), prot); }/* Load the original GDT from the per-cpu structure */
arch/x86/xen/enlighten.c +0 -3
@@ -1545,9 +1545,6 @@ asmlinkage __visible void __init xen_start_kernel(void)*/ xen_initial_gdt = &per_cpu (gdt_page,0 ); -/* GDT can only be remapped RO */ - pg_fixmap_gdt_flags =PAGE_KERNEL_RO ; -xen_smp_init ();#ifdef CONFIG_ACPI_NUMA
Andy Lutomirski
maintainerPATCH 7/7 x86/boot/32: Rewrite test_wp_bit()
In reply to Andy LutomirskiThis code seems to be very old and has gotten only minor updates. Nowadays we have a shiny function probe_kernel_write() that does more or less exactly what we need. Use it.
While we're at it, remove cpuinfo_x86::wp_works_ok, since we panic on kernels where wp doesn't work okay.
--- arch/x86/include/asm/processor.h | 2 -- arch/x86/kernel/cpu/proc.c | 5 ++--- arch/x86/kernel/setup.c | 2 -- arch/x86/mm/init_32.c | 44 ++++++++-------------------------------- arch/x86/xen/enlighten.c | 1 - 5 files changed, 11 insertions(+), 43 deletions(-)
arch/x86/include/asm/processor.h +0 -2
@@ -90,8 +90,6 @@ struct cpuinfo_x86 {__u8 x86_model;__u8 x86_mask;#ifdef CONFIG_X86_32 -char wp_works_ok;/* It doesn't on 386's */ -/* Problems on some 486Dx4's and old 386's: */ char rfu;char pad0;
arch/x86/kernel/cpu/proc.c +2 -3
@@ -31,14 +31,13 @@ static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c)"fpu\t\t: %s\n" "fpu_exception\t: %s\n" "cpuid level\t: %d\n" -"wp\t\t: %s\n" , +"wp\t\t: yes\n" ,static_cpu_has_bug (X86_BUG_FDIV ) ?"yes" :"no" ,static_cpu_has_bug (X86_BUG_F00F ) ?"yes" :"no" ,static_cpu_has_bug (X86_BUG_COMA ) ?"yes" :"no" ,static_cpu_has (X86_FEATURE_FPU ) ?"yes" :"no" ,static_cpu_has (X86_FEATURE_FPU ) ?"yes" :"no" , - c->cpuid_level, - c->wp_works_ok ? "yes" : "no"); + c->cpuid_level); }#else static void show_cpuinfo_misc (struct seq_file *m,struct cpuinfo_x86 *c)
arch/x86/kernel/setup.c +0 -2
@@ -175,11 +175,9 @@ static struct resource bss_resource = {#ifdef CONFIG_X86_32 /* cpu data as detected by the assembly code in head.S */ struct cpuinfo_x86 new_cpu_data = { - .wp_works_ok =-1 , };/* common cpu data for all cpus */ struct cpuinfo_x86 boot_cpu_data__read_mostly = { - .wp_works_ok =-1 , };EXPORT_SYMBOL (boot_cpu_data);
arch/x86/mm/init_32.c +9 -35
75 lines not on this page · raw message
arch/x86/xen/enlighten.c +0 -1
@@ -1595,7 +1595,6 @@ asmlinkage __visible void __init xen_start_kernel(void)/* set up basic CPUID stuff */ cpu_detect (&new_cpu_data);set_cpu_cap (&new_cpu_data,X86_FEATURE_FPU ); - new_cpu_data.wp_works_ok =1 ; new_cpu_data.x86_capability[CPUID_1_EDX ] =cpuid_edx (1 );#endif
Signature · 1 line
2.9.3
Quoted 20 lines · Andy Lutomirski
Hi all-
This applies to tip:x86/mm. For ease of testing, the series is here, too:
https://git.kernel.org/pub/scm/linux/kernel/git/luto/linux.git/tag/?h=review_20170322_gdt_and_wp
This fixes a few issues, most of which appear to be rather old. For whatever reason, Thomas' GDT series unearthed them. (And one is a genuine bug in Thomas' code but, in his defense, he might have cut-and-pasted it verbatim from the identical bug in the EFI code.)
The last three patches are cleanups I did while tracking these down.
Boris, any chance you could test this series on Xen? The 64-bit case works for me, but I'm having issues testing on 32-bit right now.
Ingo, the first patch should address your concerns from the earlier version.
Quoted 10 lines
Andy Lutomirski (7):
selftests/x86/ldt_gdt_32: Work around a glibc sigaction bug x86/gdt: Fixsetup_fixmap_gdt()to use the correct PA x86/efi/32: Fix EFI on systems where the percpu GDT is virtually
mapped
x86/boot/32: Defer resyncinginitial_page_tableuntil percpu is set up x86/gdt: Get rid of the get_*_gdt_*_vaddr() helpers x86/xen/gdt: UseX86_FEATURE_XENPVinstead of globals for the GDT
fixup
x86/boot/32: Rewritetest_wp_bit()
Ok, looks mostly good to me and I've applied the first 6 patches to tip:x86/mm and will push them out if everything tests out fine.
Regarding patch #7: could you please split the last patch into two, and rebase the wp_works_ok removal on the very latest tip:x86/mm tree? There's some pending changes in tip:x86/process that conflict badly, so I've merged it into tip:x86/mm for a conflict-free base. That patch is better split in two anyway, as it does two only marginally related things.
Thanks,
Ingo
Boris Ostrovsky
reviewerQuoted 11 lines · Andy Lutomirski
Hi all-
This applies to tip:x86/mm. For ease of testing, the series is here, too:
https://git.kernel.org/pub/scm/linux/kernel/git/luto/linux.git/tag/?h=review_20170322_gdt_and_wp
This fixes a few issues, most of which appear to be rather old. For whatever reason, Thomas' GDT series unearthed them. (And one is a genuine bug in Thomas' code but, in his defense, he might have cut-and-pasted it verbatim from the identical bug in the EFI code.)
Quoted 5 lines
The last three patches are cleanups I did while tracking these down.
Boris, any chance you could test this series on Xen? The 64-bit case works for me, but I'm having issues testing on 32-bit right now.
Yes, this is all good. Tests passed.
-boris