next/master bisection: boot on qemu_i386
From: kernelci.org bot
Date: Fri Nov 15 2019 - 16:57:21 EST
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* This automated bisection report was sent to you on the basis *
* that you may be involved with the breaking commit it has *
* found. No manual investigation has been done to verify it, *
* and the root cause of the problem may be somewhere else. *
* *
* If you do send a fix, please include this trailer: *
* Reported-by: "kernelci.org bot" <bot@xxxxxxxxxxxx> *
* *
* Hope this helps! *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
next/master bisection: boot on qemu_i386
Summary:
Start: 5a6fcbeabe3e Add linux-next specific files for 20191115
Details: https://kernelci.org/boot/id/5dcebd0459b514519dcf54be
Plain log: https://storage.kernelci.org//next/master/next-20191115/i386/i386_defconfig/gcc-8/lab-baylibre/boot-qemu_i386.txt
HTML log: https://storage.kernelci.org//next/master/next-20191115/i386/i386_defconfig/gcc-8/lab-baylibre/boot-qemu_i386.html
Result: bc1aca4ab8e0 x86/process: Unify copy_thread_tls()
Checks:
revert: PASS
verify: PASS
Parameters:
Tree: next
URL: git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
Branch: master
Target: qemu_i386
CPU arch: i386
Lab: lab-baylibre
Compiler: gcc-8
Config: i386_defconfig
Test suite: boot
Breaking commit found:
-------------------------------------------------------------------------------
commit bc1aca4ab8e08c01678e14138bea2fc433cd8068
Author: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Date: Mon Nov 11 23:03:16 2019 +0100
x86/process: Unify copy_thread_tls()
While looking at the TSS io bitmap it turned out that any change in that
area would require identical changes to copy_thread_tls(). The 32 and 64
bit variants share sufficient code to consolidate them into a common
function to avoid duplication of upcoming modifications.
Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Acked-by: Andy Lutomirski <luto@xxxxxxxxxx>
diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h
index 332eb3525867..5057a8ed100b 100644
--- a/arch/x86/include/asm/ptrace.h
+++ b/arch/x86/include/asm/ptrace.h
@@ -361,5 +361,11 @@ extern int do_get_thread_area(struct task_struct *p, int idx,
extern int do_set_thread_area(struct task_struct *p, int idx,
struct user_desc __user *info, int can_allocate);
+#ifdef CONFIG_X86_64
+# define do_set_thread_area_64(p, s, t) do_arch_prctl_64(p, s, t)
+#else
+# define do_set_thread_area_64(p, s, t) (0)
+#endif
+
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_X86_PTRACE_H */
diff --git a/arch/x86/include/asm/switch_to.h b/arch/x86/include/asm/switch_to.h
index 18a4b6890fa8..0e059b73437b 100644
--- a/arch/x86/include/asm/switch_to.h
+++ b/arch/x86/include/asm/switch_to.h
@@ -103,7 +103,17 @@ static inline void update_task_stack(struct task_struct *task)
if (static_cpu_has(X86_FEATURE_XENPV))
load_sp0(task_top_of_stack(task));
#endif
+}
+static inline void kthread_frame_init(struct inactive_task_frame *frame,
+ unsigned long fun, unsigned long arg)
+{
+ frame->bx = fun;
+#ifdef CONFIG_X86_32
+ frame->di = arg;
+#else
+ frame->r12 = arg;
+#endif
}
#endif /* _ASM_X86_SWITCH_TO_H */
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 5e94c4354d4e..c09130a39954 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -132,6 +132,100 @@ void exit_thread(struct task_struct *tsk)
fpu__drop(fpu);
}
+static int set_new_tls(struct task_struct *p, unsigned long tls)
+{
+ struct user_desc __user *utls = (struct user_desc __user *)tls;
+
+ if (in_ia32_syscall())
+ return do_set_thread_area(p, -1, utls, 0);
+ else
+ return do_set_thread_area_64(p, ARCH_SET_FS, tls);
+}
+
+static inline int copy_io_bitmap(struct task_struct *tsk)
+{
+ if (likely(!test_tsk_thread_flag(current, TIF_IO_BITMAP)))
+ return 0;
+
+ tsk->thread.io_bitmap_ptr = kmemdup(current->thread.io_bitmap_ptr,
+ IO_BITMAP_BYTES, GFP_KERNEL);
+ if (!tsk->thread.io_bitmap_ptr) {
+ tsk->thread.io_bitmap_max = 0;
+ return -ENOMEM;
+ }
+ set_tsk_thread_flag(tsk, TIF_IO_BITMAP);
+ return 0;
+}
+
+static inline void free_io_bitmap(struct task_struct *tsk)
+{
+ if (tsk->thread.io_bitmap_ptr) {
+ kfree(tsk->thread.io_bitmap_ptr);
+ tsk->thread.io_bitmap_ptr = NULL;
+ tsk->thread.io_bitmap_max = 0;
+ }
+}
+
+int copy_thread_tls(unsigned long clone_flags, unsigned long sp,
+ unsigned long arg, struct task_struct *p, unsigned long tls)
+{
+ struct inactive_task_frame *frame;
+ struct fork_frame *fork_frame;
+ struct pt_regs *childregs;
+ int ret;
+
+ childregs = task_pt_regs(p);
+ fork_frame = container_of(childregs, struct fork_frame, regs);
+ frame = &fork_frame->frame;
+
+ frame->bp = 0;
+ frame->ret_addr = (unsigned long) ret_from_fork;
+ p->thread.sp = (unsigned long) fork_frame;
+ p->thread.io_bitmap_ptr = NULL;
+ memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
+
+#ifdef CONFIG_X86_64
+ savesegment(gs, p->thread.gsindex);
+ p->thread.gsbase = p->thread.gsindex ? 0 : current->thread.gsbase;
+ savesegment(fs, p->thread.fsindex);
+ p->thread.fsbase = p->thread.fsindex ? 0 : current->thread.fsbase;
+ savesegment(es, p->thread.es);
+ savesegment(ds, p->thread.ds);
+#else
+ /* Clear all status flags including IF and set fixed bit. */
+ frame->flags = X86_EFLAGS_FIXED;
+#endif
+
+ /* Kernel thread ? */
+ if (unlikely(p->flags & PF_KTHREAD)) {
+ memset(childregs, 0, sizeof(struct pt_regs));
+ kthread_frame_init(frame, sp, arg);
+ return 0;
+ }
+
+ frame->bx = 0;
+ *childregs = *current_pt_regs();
+ childregs->ax = 0;
+ if (sp)
+ childregs->sp = sp;
+
+#ifdef CONFIG_X86_32
+ task_user_gs(p) = get_user_gs(current_pt_regs());
+#endif
+
+ ret = copy_io_bitmap(p);
+ if (ret)
+ return ret;
+
+ /* Set a new TLS for the child thread? */
+ if (clone_flags & CLONE_SETTLS) {
+ ret = set_new_tls(p, tls);
+ if (ret)
+ free_io_bitmap(p);
+ }
+ return ret;
+}
+
void flush_thread(void)
{
struct task_struct *tsk = current;
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index b8ceec4974fe..6c7d90527156 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -112,74 +112,6 @@ void release_thread(struct task_struct *dead_task)
release_vm86_irqs(dead_task);
}
-int copy_thread_tls(unsigned long clone_flags, unsigned long sp,
- unsigned long arg, struct task_struct *p, unsigned long tls)
-{
- struct pt_regs *childregs = task_pt_regs(p);
- struct fork_frame *fork_frame = container_of(childregs, struct fork_frame, regs);
- struct inactive_task_frame *frame = &fork_frame->frame;
- struct task_struct *tsk;
- int err;
-
- /*
- * For a new task use the RESET flags value since there is no before.
- * All the status flags are zero; DF and all the system flags must also
- * be 0, specifically IF must be 0 because we context switch to the new
- * task with interrupts disabled.
- */
- frame->flags = X86_EFLAGS_FIXED;
- frame->bp = 0;
- frame->ret_addr = (unsigned long) ret_from_fork;
- p->thread.sp = (unsigned long) fork_frame;
- p->thread.sp0 = (unsigned long) (childregs+1);
- memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
-
- if (unlikely(p->flags & PF_KTHREAD)) {
- /* kernel thread */
- memset(childregs, 0, sizeof(struct pt_regs));
- frame->bx = sp; /* function */
- frame->di = arg;
- p->thread.io_bitmap_ptr = NULL;
- return 0;
- }
- frame->bx = 0;
- *childregs = *current_pt_regs();
- childregs->ax = 0;
- if (sp)
- childregs->sp = sp;
-
- task_user_gs(p) = get_user_gs(current_pt_regs());
-
- p->thread.io_bitmap_ptr = NULL;
- tsk = current;
- err = -ENOMEM;
-
- if (unlikely(test_tsk_thread_flag(tsk, TIF_IO_BITMAP))) {
- p->thread.io_bitmap_ptr = kmemdup(tsk->thread.io_bitmap_ptr,
- IO_BITMAP_BYTES, GFP_KERNEL);
- if (!p->thread.io_bitmap_ptr) {
- p->thread.io_bitmap_max = 0;
- return -ENOMEM;
- }
- set_tsk_thread_flag(p, TIF_IO_BITMAP);
- }
-
- err = 0;
-
- /*
- * Set a new TLS for the child thread?
- */
- if (clone_flags & CLONE_SETTLS)
- err = do_set_thread_area(p, -1,
- (struct user_desc __user *)tls, 0);
-
- if (err && p->thread.io_bitmap_ptr) {
- kfree(p->thread.io_bitmap_ptr);
- p->thread.io_bitmap_max = 0;
- }
- return err;
-}
-
void
start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
{
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index af64519b2695..e93a1b8fd7f9 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -371,81 +371,6 @@ void x86_gsbase_write_task(struct task_struct *task, unsigned long gsbase)
task->thread.gsbase = gsbase;
}
-int copy_thread_tls(unsigned long clone_flags, unsigned long sp,
- unsigned long arg, struct task_struct *p, unsigned long tls)
-{
- int err;
- struct pt_regs *childregs;
- struct fork_frame *fork_frame;
- struct inactive_task_frame *frame;
- struct task_struct *me = current;
-
- childregs = task_pt_regs(p);
- fork_frame = container_of(childregs, struct fork_frame, regs);
- frame = &fork_frame->frame;
-
- frame->bp = 0;
- frame->ret_addr = (unsigned long) ret_from_fork;
- p->thread.sp = (unsigned long) fork_frame;
- p->thread.io_bitmap_ptr = NULL;
-
- savesegment(gs, p->thread.gsindex);
- p->thread.gsbase = p->thread.gsindex ? 0 : me->thread.gsbase;
- savesegment(fs, p->thread.fsindex);
- p->thread.fsbase = p->thread.fsindex ? 0 : me->thread.fsbase;
- savesegment(es, p->thread.es);
- savesegment(ds, p->thread.ds);
- memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
-
- if (unlikely(p->flags & PF_KTHREAD)) {
- /* kernel thread */
- memset(childregs, 0, sizeof(struct pt_regs));
- frame->bx = sp; /* function */
- frame->r12 = arg;
- return 0;
- }
- frame->bx = 0;
- *childregs = *current_pt_regs();
-
- childregs->ax = 0;
- if (sp)
- childregs->sp = sp;
-
- err = -ENOMEM;
- if (unlikely(test_tsk_thread_flag(me, TIF_IO_BITMAP))) {
- p->thread.io_bitmap_ptr = kmemdup(me->thread.io_bitmap_ptr,
- IO_BITMAP_BYTES, GFP_KERNEL);
- if (!p->thread.io_bitmap_ptr) {
- p->thread.io_bitmap_max = 0;
- return -ENOMEM;
- }
- set_tsk_thread_flag(p, TIF_IO_BITMAP);
- }
-
- /*
- * Set a new TLS for the child thread?
- */
- if (clone_flags & CLONE_SETTLS) {
-#ifdef CONFIG_IA32_EMULATION
- if (in_ia32_syscall())
- err = do_set_thread_area(p, -1,
- (struct user_desc __user *)tls, 0);
- else
-#endif
- err = do_arch_prctl_64(p, ARCH_SET_FS, tls);
- if (err)
- goto out;
- }
- err = 0;
-out:
- if (err && p->thread.io_bitmap_ptr) {
- kfree(p->thread.io_bitmap_ptr);
- p->thread.io_bitmap_max = 0;
- }
-
- return err;
-}
-
static void
start_thread_common(struct pt_regs *regs, unsigned long new_ip,
unsigned long new_sp,
-------------------------------------------------------------------------------
Git bisection log:
-------------------------------------------------------------------------------
git bisect start
# good: [633739b2fedb6617d782ca252797b7a8ad754347] rbd: silence bogus uninitialized warning in rbd_object_map_update_finish()
git bisect good 633739b2fedb6617d782ca252797b7a8ad754347
# bad: [5a6fcbeabe3e20459ed8504690b2515dacc5246f] Add linux-next specific files for 20191115
git bisect bad 5a6fcbeabe3e20459ed8504690b2515dacc5246f
# good: [280c9e8802370ed562bf1360fb6906c91fd3c190] Merge remote-tracking branch 'crypto/master'
git bisect good 280c9e8802370ed562bf1360fb6906c91fd3c190
# good: [c49494c35c91edb2013a696c5ab335789c5d3df4] Merge remote-tracking branch 'devicetree/for-next'
git bisect good c49494c35c91edb2013a696c5ab335789c5d3df4
# bad: [518d37a6ac8907ce017751fd985a53fa8a354e6f] Merge remote-tracking branch 'char-misc/char-misc-next'
git bisect bad 518d37a6ac8907ce017751fd985a53fa8a354e6f
# bad: [3d75c03b3bf024c7f25d57da072e0ffacee52499] Merge remote-tracking branch 'edac/edac-for-next'
git bisect bad 3d75c03b3bf024c7f25d57da072e0ffacee52499
# good: [9dc21c69c61512356dc002266e5b10636f75e3f2] Merge branch 'x86/urgent'
git bisect good 9dc21c69c61512356dc002266e5b10636f75e3f2
# good: [8e970f74efde16ae67b33eead1d2f9b6c59b25a6] Merge branch 'efi/core'
git bisect good 8e970f74efde16ae67b33eead1d2f9b6c59b25a6
# good: [5eb263ef08b5014cfc2539a838f39d2fd3531423] spi: pxa2xx: Add missed security checks
git bisect good 5eb263ef08b5014cfc2539a838f39d2fd3531423
# bad: [3b0a842355f77f12dcf71a61b02b49b3cbc5ed1c] Merge branch 'locking/core'
git bisect bad 3b0a842355f77f12dcf71a61b02b49b3cbc5ed1c
# bad: [3e4d603f40ddaf797067dedfe07c07357c901386] selftests/x86/iopl: Extend test to cover IOPL emulation
git bisect bad 3e4d603f40ddaf797067dedfe07c07357c901386
# bad: [78a53d4aabebbda7328aadf6a2821cf75d8d089d] x86/ioperm: Move iobitmap data into a struct
git bisect bad 78a53d4aabebbda7328aadf6a2821cf75d8d089d
# bad: [f07d5e256894dc74266c7639f44e68dcfc961aa3] x86/iopl: Cleanup include maze
git bisect bad f07d5e256894dc74266c7639f44e68dcfc961aa3
# bad: [bc1aca4ab8e08c01678e14138bea2fc433cd8068] x86/process: Unify copy_thread_tls()
git bisect bad bc1aca4ab8e08c01678e14138bea2fc433cd8068
# good: [a66770766fb3152b38ef324b9ed5e98e6d9b89b2] x86/ptrace: Prevent truncation of bitmap size
git bisect good a66770766fb3152b38ef324b9ed5e98e6d9b89b2
# first bad commit: [bc1aca4ab8e08c01678e14138bea2fc433cd8068] x86/process: Unify copy_thread_tls()
-------------------------------------------------------------------------------