From: Matt Redfearn <matt.redfearn@imgtec.com>
To: Paul Burton <paul.burton@imgtec.com>, <linux-mips@linux-mips.org>,
Ralf Baechle <ralf@linux-mips.org>
Cc: Leonid Yegoshin <leonid.yegoshin@imgtec.com>,
Matthew Fortune <matthew.fortune@imgtec.com>,
Raghu Gandham <raghu.gandham@imgtec.com>
Subject: Re: [RFC PATCH v3 1/2] MIPS: use per-mm page to execute branch delay slot instructions
Date: Thu, 30 Jun 2016 11:40:11 +0100 [thread overview]
Message-ID: <5774F70B.2050300@imgtec.com> (raw)
In-Reply-To: <9c74a08a-afbb-68c6-e022-a4f01713f01c@imgtec.com>
On 30/06/16 11:17, Paul Burton wrote:
> On 30/06/16 10:01, Matt Redfearn wrote:
>> Hi Paul
>
> Hi Matt :)
>
>>> @@ -128,6 +129,11 @@ init_new_context(struct task_struct *tsk, struct
>>> mm_struct *mm)
>>> atomic_set(&mm->context.fp_mode_switching, 0);
>>> + mm->context.bd_emupage = 0;
>>> + mm->context.bd_emupage_allocmap = NULL;
>>> + mutex_init(&mm->context.bd_emupage_mutex);
>>> + init_waitqueue_head(&mm->context.bd_emupage_queue);
>>> +
>>
>> Should this be wrapped in a CONFIG? We're introducing overhead to every
>> tsk creation even if we won't be making use of the emulation.
>
> Since this is used by the FPU emulator, which we always include in the
> kernel, no I'd say not. The overhead here should be very small - all
> the actual memory allocation & book-keeping is left until a delay slot
> emulation is actually performed, we're effectively just setting some
> variables to sane & constant initial values here.
>
> In order to guarantee that we don't use this code we'd need to
> guarantee that we don't use the FPU emulator (or MIPSr2 emulation on a
> MIPSr6 system) and right now at least there is no way for us to do
> that. We could add an option to build the kernel without the emulator,
> but then we'd have issues even if we run on a system with an FPU that
> doesn't implement certain operations (eg. denormals), so in practice I
> think that would mean we'd be much better with an option to disable
> use of FP entirely. That is probably something it would be useful to
> have anyway for people who know their userland is entirely soft-float,
> but it's not something I think this patch should do.
>
>>> @@ -162,6 +168,7 @@ static inline void switch_mm(struct mm_struct
>>> *prev, struct mm_struct *next,
>>> */
>>> static inline void destroy_context(struct mm_struct *mm)
>>> {
>>> + dsemul_mm_cleanup(mm);
>> Ditto.
>
> Likewise.
>
>>> -#define STACK_TOP (TASK_SIZE & PAGE_MASK)
>>> +/*
>>> + * One page above the stack is used for branch delay slot "emulation".
>>> + * See dsemul.c for details.
>>> + */
>>> +#define STACK_TOP ((TASK_SIZE & PAGE_MASK) - PAGE_SIZE)
>>
>> Again, should this be dependent on config? Otherwise we waste a page for
>> every task.
>
> Likewise. Note that we don't actually use a page of memory for every
> process, we just reserve a page of its virtual address space. The
> actual memory allocation only occurs (in alloc_emuframe) if we perform
> a delay slot emulation.
>
>>> + /*
>>> + * If the PC is at the emul instruction, roll back to the
>>> branch. If
>>> + * PC is at the badinst (break) instruction, we've already
>>> emulated the
>>> + * instruction so progress to the continue PC. If it's anything
>>> else
>>> + * then something is amiss.
>>> + */
>>> + if (msk_isa16_mode(regs->cp0_epc) == (unsigned long)&fr->emul)
>>> + regs->cp0_epc = current->thread.bd_emu_branch_pc;
>>> + else if (msk_isa16_mode(regs->cp0_epc) == (unsigned
>>> long)&fr->badinst)
>>> + regs->cp0_epc = current->thread.bd_emu_cont_pc;
>>> + else
>>> + return false;
>> Would that lead to bd_emu_frame getting stuck?
>
> The only way I can think of this case possibly being hit would be if
> the user code tried to trick the kernel into thinking it was executing
> from a struct emuframe when it actually wasn't - ie. some time after
> executing an actual delay slot emulation & preventing the badinst
> break instruction being hit (either by a well timed signal or an
> exception & signal generating instruction) the user would need to
> either manually write to the page & jump into it, or jump to a frame
> that some other thread had set up (and either way another thread may
> clobber what it's executing at any moment). If it does try that then
> yes, the thread's actual frame might persist until the thread either
> requires another emulation or exits. Worst case scenario the process
> has one less frame available to it, which I don't see as being an
> issue. We probably could just free the allocated frame anyway in this
> case, but actually perhaps SIGKILL would be more suitable.
>
> BTW, a way to prevent one of the above scenarios would be ideal future
> work: it would be good for security if the user could only execute the
> page, and the kernel could only write it. That would probably involve
> having aliased mappings, but would be nice to add later.
>
OK cool, sounds good to me. BTW, there was an additional comment (which
I failed to space correctly) that asm/dsemul.h seems to be missing from
the patch?
Thanks,
Matt
> Thanks,
> Paul
WARNING: multiple messages have this Message-ID (diff)
From: Matt Redfearn <matt.redfearn@imgtec.com>
To: Paul Burton <paul.burton@imgtec.com>,
linux-mips@linux-mips.org, Ralf Baechle <ralf@linux-mips.org>
Cc: Leonid Yegoshin <leonid.yegoshin@imgtec.com>,
Matthew Fortune <matthew.fortune@imgtec.com>,
Raghu Gandham <raghu.gandham@imgtec.com>
Subject: Re: [RFC PATCH v3 1/2] MIPS: use per-mm page to execute branch delay slot instructions
Date: Thu, 30 Jun 2016 11:40:11 +0100 [thread overview]
Message-ID: <5774F70B.2050300@imgtec.com> (raw)
Message-ID: <20160630104011.Ft2GqYdDJR4N45WiSxpm9HXKDmn978PFXrb2TSACm-w@z> (raw)
In-Reply-To: <9c74a08a-afbb-68c6-e022-a4f01713f01c@imgtec.com>
On 30/06/16 11:17, Paul Burton wrote:
> On 30/06/16 10:01, Matt Redfearn wrote:
>> Hi Paul
>
> Hi Matt :)
>
>>> @@ -128,6 +129,11 @@ init_new_context(struct task_struct *tsk, struct
>>> mm_struct *mm)
>>> atomic_set(&mm->context.fp_mode_switching, 0);
>>> + mm->context.bd_emupage = 0;
>>> + mm->context.bd_emupage_allocmap = NULL;
>>> + mutex_init(&mm->context.bd_emupage_mutex);
>>> + init_waitqueue_head(&mm->context.bd_emupage_queue);
>>> +
>>
>> Should this be wrapped in a CONFIG? We're introducing overhead to every
>> tsk creation even if we won't be making use of the emulation.
>
> Since this is used by the FPU emulator, which we always include in the
> kernel, no I'd say not. The overhead here should be very small - all
> the actual memory allocation & book-keeping is left until a delay slot
> emulation is actually performed, we're effectively just setting some
> variables to sane & constant initial values here.
>
> In order to guarantee that we don't use this code we'd need to
> guarantee that we don't use the FPU emulator (or MIPSr2 emulation on a
> MIPSr6 system) and right now at least there is no way for us to do
> that. We could add an option to build the kernel without the emulator,
> but then we'd have issues even if we run on a system with an FPU that
> doesn't implement certain operations (eg. denormals), so in practice I
> think that would mean we'd be much better with an option to disable
> use of FP entirely. That is probably something it would be useful to
> have anyway for people who know their userland is entirely soft-float,
> but it's not something I think this patch should do.
>
>>> @@ -162,6 +168,7 @@ static inline void switch_mm(struct mm_struct
>>> *prev, struct mm_struct *next,
>>> */
>>> static inline void destroy_context(struct mm_struct *mm)
>>> {
>>> + dsemul_mm_cleanup(mm);
>> Ditto.
>
> Likewise.
>
>>> -#define STACK_TOP (TASK_SIZE & PAGE_MASK)
>>> +/*
>>> + * One page above the stack is used for branch delay slot "emulation".
>>> + * See dsemul.c for details.
>>> + */
>>> +#define STACK_TOP ((TASK_SIZE & PAGE_MASK) - PAGE_SIZE)
>>
>> Again, should this be dependent on config? Otherwise we waste a page for
>> every task.
>
> Likewise. Note that we don't actually use a page of memory for every
> process, we just reserve a page of its virtual address space. The
> actual memory allocation only occurs (in alloc_emuframe) if we perform
> a delay slot emulation.
>
>>> + /*
>>> + * If the PC is at the emul instruction, roll back to the
>>> branch. If
>>> + * PC is at the badinst (break) instruction, we've already
>>> emulated the
>>> + * instruction so progress to the continue PC. If it's anything
>>> else
>>> + * then something is amiss.
>>> + */
>>> + if (msk_isa16_mode(regs->cp0_epc) == (unsigned long)&fr->emul)
>>> + regs->cp0_epc = current->thread.bd_emu_branch_pc;
>>> + else if (msk_isa16_mode(regs->cp0_epc) == (unsigned
>>> long)&fr->badinst)
>>> + regs->cp0_epc = current->thread.bd_emu_cont_pc;
>>> + else
>>> + return false;
>> Would that lead to bd_emu_frame getting stuck?
>
> The only way I can think of this case possibly being hit would be if
> the user code tried to trick the kernel into thinking it was executing
> from a struct emuframe when it actually wasn't - ie. some time after
> executing an actual delay slot emulation & preventing the badinst
> break instruction being hit (either by a well timed signal or an
> exception & signal generating instruction) the user would need to
> either manually write to the page & jump into it, or jump to a frame
> that some other thread had set up (and either way another thread may
> clobber what it's executing at any moment). If it does try that then
> yes, the thread's actual frame might persist until the thread either
> requires another emulation or exits. Worst case scenario the process
> has one less frame available to it, which I don't see as being an
> issue. We probably could just free the allocated frame anyway in this
> case, but actually perhaps SIGKILL would be more suitable.
>
> BTW, a way to prevent one of the above scenarios would be ideal future
> work: it would be good for security if the user could only execute the
> page, and the kernel could only write it. That would probably involve
> having aliased mappings, but would be nice to add later.
>
OK cool, sounds good to me. BTW, there was an additional comment (which
I failed to space correctly) that asm/dsemul.h seems to be missing from
the patch?
Thanks,
Matt
> Thanks,
> Paul
next prev parent reply other threads:[~2016-06-30 10:40 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-06-29 14:38 [RFC PATCH v3 0/2] MIPS non-executable stack support Paul Burton
2016-06-29 14:38 ` Paul Burton
2016-06-29 14:38 ` [RFC PATCH v3 1/2] MIPS: use per-mm page to execute branch delay slot instructions Paul Burton
2016-06-29 14:38 ` Paul Burton
2016-06-30 9:01 ` Matt Redfearn
2016-06-30 9:01 ` Matt Redfearn
2016-06-30 10:17 ` Paul Burton
2016-06-30 10:17 ` Paul Burton
2016-06-30 10:40 ` Matt Redfearn [this message]
2016-06-30 10:40 ` Matt Redfearn
2016-06-30 10:49 ` Paul Burton
2016-06-30 10:49 ` Paul Burton
2016-06-29 14:38 ` [RFC PATCH v3 2/2] MIPS: non-exec stack & heap when non-exec PT_GNU_STACK is present Paul Burton
2016-06-29 14:38 ` Paul Burton
2016-06-30 9:25 ` Matthew Fortune
2016-06-30 10:34 ` Paul Burton
2016-06-30 12:04 ` Matthew Fortune
2016-06-30 16:25 ` Paul Burton
2016-06-30 17:40 ` Faraz Shahbazker
2016-06-30 18:48 ` Maciej W. Rozycki
2016-07-01 0:49 ` David Daney
2016-07-01 17:11 ` Paul Burton
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=5774F70B.2050300@imgtec.com \
--to=matt.redfearn@imgtec.com \
--cc=leonid.yegoshin@imgtec.com \
--cc=linux-mips@linux-mips.org \
--cc=matthew.fortune@imgtec.com \
--cc=paul.burton@imgtec.com \
--cc=raghu.gandham@imgtec.com \
--cc=ralf@linux-mips.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox