From: mark.rutland@arm.com (Mark Rutland)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 10/10] arm64: split thread_info from task stack
Date: Fri, 21 Oct 2016 16:59:02 +0100 [thread overview]
Message-ID: <20161021155701.GA17287@leverpostej> (raw)
In-Reply-To: <580A2B3A.7000300@arm.com>
Hi James,
On Fri, Oct 21, 2016 at 03:50:34PM +0100, James Morse wrote:
> > arch/arm64/kernel/entry.S | 4 ++--
>
> 4? That was too easy...
Indeed... ;)
> > diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> > index 2d4c83b..e781391 100644
> > --- a/arch/arm64/kernel/entry.S
> > +++ b/arch/arm64/kernel/entry.S
> > @@ -123,6 +123,7 @@
> > * Set sp_el0 to current thread_info.
> > */
> > .if \el == 0
> > + ldr_this_cpu tsk, __entry_task, x21
> > msr sp_el0, tsk
> > .endif
> >
> > @@ -674,8 +675,7 @@ ENTRY(cpu_switch_to)
> > ldp x29, x9, [x8], #16
> > ldr lr, [x8]
> > mov sp, x9
> > - and x9, x9, #~(THREAD_SIZE - 1)
> > - msr sp_el0, x9
> > + msr sp_el0, x1
> > ret
> > ENDPROC(cpu_switch_to)
> >
>
> So now tsk is current instead of current_thread_info(), but we still access it
> with TI_* offsets:
Yes; luckily thread_info is the first member of task_struct, so this
works (as offsetof(struct task_struct, thread_info) == 0). The core code
also relies on this, e.g. in <linux/thread_info.h>:
#ifdef CONFIG_THREAD_INFO_IN_TASK
#define current_thread_info() ((struct thread_info *)current)
#endif
... regardless, I should have commented that, mentioned it in the commit
message, and perhaps put a BUILD_BUG_ON()-style assert somewhere. I'll
need to double-check, but IIRC I can't update asm-offsets to base the
TI_* offsets on task_struct without introducing a potential circular
include dependency.
I could at least s/TI_/TSK_/, with a comment.
> The 're-entered irq stack' check is going to need re-thinking:
> entry.S:195
> > /*
> > * Compare sp with the current thread_info, if the top
> > * ~(THREAD_SIZE - 1) bits match, we are on a task stack, and
> > * should switch to the irq stack.
> > */
> > and x25, x19, #~(THREAD_SIZE - 1)
> > cmp x25, tsk
> > b.ne 9998f
>
> It was done like this as the irq stack isn't naturally aligned, so this check
> implicitly assumes tsk is on the stack. I will try and come up with an alternative.
Ouch; I clearly didn't vet this thoroughly enough.
If we can corrupt another register here, we can load task_struct::stack
to compare against instead.
> And there are a few other things like this:
> entry.S:431
> > ldr w24, [tsk, #TI_PREEMPT] // get preempt count
> > cbnz w24, 1f // preempt count != 0
> > ldr x0, [tsk, #TI_FLAGS] // get flags
> > tbz x0, #TIF_NEED_RESCHED, 1f // needs rescheduling?
> > bl el1_preempt
>
> (It may be worth renaming the register alias 'tsk' as it isn't really a
> struct_task. This would catch any missed users at build time, including
> any patches in flight...)
Entertainingly, with these patches 'tsk' *is* task_struct, whereas
before it wasn't.
> > diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> > index 2679722..cde25f4 100644
> > --- a/arch/arm64/kernel/smp.c
> > +++ b/arch/arm64/kernel/smp.c
> > @@ -149,6 +149,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
> > * We need to tell the secondary core where to find its stack and the
> > * page tables.
> > */
> > + secondary_data.task = idle;
> > secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
> > update_cpu_boot_status(CPU_MMU_OFF);
> > __flush_dcache_area(&secondary_data, sizeof(secondary_data));
> > @@ -173,6 +174,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
> > pr_err("CPU%u: failed to boot: %d\n", cpu, ret);
> > }
> >
> > + secondary_data.task = NULL;
> > secondary_data.stack = NULL;
> > status = READ_ONCE(secondary_data.status);
> > if (ret && status) {
> >
>
> Nit-territory: Something we should remember is that __entry_task isn't written
> on secondary startup, so its stale (CPU0s idle task) until the first
> __switch_to(). This isn't a problem as its only read on entry from EL0.
Good point. I think I can initialise this in the hotplug path, if
nothing else but to save us any surprises when debugging.
Thanks,
Mark.
next prev parent reply other threads:[~2016-10-21 15:59 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-10-19 19:10 [PATCH 00/10] arm64: move thread_info off of the task stack Mark Rutland
2016-10-19 19:10 ` [PATCH 01/10] arm64: thread_info remove stale items Mark Rutland
2016-10-19 19:10 ` [PATCH 02/10] arm64: asm-offsets: remove unused definitions Mark Rutland
2016-10-19 19:10 ` [PATCH 03/10] arm64: factor out current_stack_pointer Mark Rutland
2016-10-19 19:10 ` [PATCH 04/10] arm64: traps: simplify die() and __die() Mark Rutland
2016-10-19 19:10 ` [PATCH 05/10] arm64: prep stack walkers for THREAD_INFO_IN_TASK Mark Rutland
2016-10-19 19:10 ` [PATCH 06/10] arm64: move sp_el0 and tpidr_el1 into cpu_suspend_ctx Mark Rutland
2016-10-19 19:10 ` [PATCH 07/10] arm64: smp: prepare for smp_processor_id() rework Mark Rutland
2016-10-19 19:10 ` [PATCH 08/10] arm64: make cpu number a percpu variable Mark Rutland
2016-10-19 19:10 ` [PATCH 09/10] arm64: assembler: introduce ldr_this_cpu Mark Rutland
2016-10-19 19:10 ` [PATCH 10/10] arm64: split thread_info from task stack Mark Rutland
2016-10-21 14:50 ` James Morse
2016-10-21 15:59 ` Mark Rutland [this message]
2016-10-21 17:27 ` Mark Rutland
2016-10-21 16:20 ` Mark Rutland
2016-10-24 17:38 ` [PATCH 00/10] arm64: move thread_info off of the " Laura Abbott
2016-10-24 17:48 ` Mark Rutland
2016-10-24 17:58 ` Laura Abbott
2016-10-24 18:09 ` Mark Rutland
2016-10-24 18:15 ` Mark Rutland
2016-10-24 18:18 ` Kees Cook
2016-10-25 10:05 ` Mark Rutland
2016-10-26 0:46 ` Laura Abbott
2016-10-26 9:55 ` Mark Rutland
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20161021155701.GA17287@leverpostej \
--to=mark.rutland@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.