From: Paul Burton <paul.burton@imgtec.com>
To: David Daney <ddaney.cavm@gmail.com>
Cc: <linux-mips@linux-mips.org>
Subject: Re: [PATCH 5/6] mips: use per-mm page to execute FP branch delay slots
Date: Fri, 8 Nov 2013 12:07:31 +0000 [thread overview]
Message-ID: <527CD403.8040407@imgtec.com> (raw)
In-Reply-To: <527BD537.4040903@gmail.com>
On 07/11/13 18:00, David Daney wrote:
> Nice work...
>
> On 11/07/2013 04:48 AM, Paul Burton wrote:
> [...]
>> - * Algorithmics used a system call instruction, and
>> - * borrowed that vector. MIPS/Linux version is a bit
>> - * more heavyweight in the interests of portability and
>> - * multiprocessor support. For Linux we generate a
>> - * an unaligned access and force an address error exception.
>> + * 1) Be a bug in the userland code, because it has a
>> branch/jump in
>> + * a branch delay slot. So if we run out of emuframes and the
>> + * userland code hangs it's not exactly the kernels fault.
>
> s/kernels/kernel's/
>
Yup, thanks.
>
>> *
>> - * For embedded systems (stand-alone) we prefer to use a
>> - * non-existing CP1 instruction. This prevents us from emulating
>> - * branches, but gives us a cleaner interface to the exception
>> - * handler (single entry point).
>> + * 2) Only affect that userland process, since emuframes are
>> allocated
>> + * per-mm and kernel threads don't use them at all.
>> */
>> + if (!get_isa16_mode(regs->cp0_epc)) {
>> + if (!ir) {
>> + /* typical NOP encoding: sll r0, r0, r0 */
>> +is_nop:
>> + regs->cp0_epc = cpc;
>> + regs->cp0_cause &= ~CAUSEF_BD;
>> + return 0;
>> + }
>>
>> - /* Ensure that the two instructions are in the same cache line */
>> - fr = (struct emuframe __user *)
>> - ((regs->regs[29] - sizeof(struct emuframe)) & ~0x7);
>> + switch (inst.j_format.opcode) {
>> + case bcond_op:
>> + switch (inst.i_format.rt) {
>> + case bltz_op:
>> + case bgez_op:
>> + case bltzl_op:
>> + case bgezl_op:
>> + case bltzal_op:
>> + case bgezal_op:
>> + case bltzall_op:
>> + case bgezall_op:
>> + goto is_branch;
>> + }
>> + break;
>
> Is there any way to use the support in arch/mips/kernel/branch.c instead
> of duplicating the code here?
>
> It may require some refactoring to make it work, but I think it would be
> worth it.
>
Ah (how had I not spotted that code?) :)
It may fit better with the (mm_)isBranchInstr functions in
arch/mips/math-emu/cp1emu.c since they already return a value specifying
whether or not the instruction is a branch. The microMIPS variant is
already used elsewhere too. I'll take a look at it.
Thanks,
Paul
>>
>> - /* Verify that the stack pointer is not competely insane */
>> - if (unlikely(!access_ok(VERIFY_WRITE, fr, sizeof(struct emuframe))))
>> + case cop1_op:
>> + switch (inst.i_format.rs) {
>> + case bc_op:
>> + goto is_branch;
>> + }
>> + break;
>> +
>> + case j_op:
>> + case jal_op:
>> + case beq_op:
>> + case bne_op:
>> + case blez_op:
>> + case bgtz_op:
>> + case beql_op:
>> + case bnel_op:
>> + case blezl_op:
>> + case bgtzl_op:
>> + case jalx_op:
>> +is_branch:
>> + pr_warn("PID %d has a branch in an FP branch delay slot
>> at 0x%08lx\n",
>> + current->pid, regs->cp0_epc);
>> + goto is_nop;
>> + }
>> + } else {
>> + if ((ir >> 16) == MM_NOP16)
>> + goto is_nop;
>> +
>> + switch (inst.mm_i_format.opcode) {
>> + case mm_beqz16_op:
>> + case mm_beq32_op:
>> + case mm_bnez16_op:
>> + case mm_bne32_op:
>> + case mm_b16_op:
>> + case mm_j32_op:
>> + case mm_jalx32_op:
>> + case mm_jal32_op:
>> + goto is_branch;
>> +
>> + case mm_pool32i_op:
>> + switch (inst.mm_i_format.rt) {
>> + case mm_bltz_op:
>> + case mm_bltzal_op:
>> + case mm_bgez_op:
>> + case mm_bgezal_op:
>> + case mm_blez_op:
>> + case mm_bnezc_op:
>> + case mm_bgtz_op:
>> + case mm_beqzc_op:
>> + case mm_bltzals_op:
>> + case mm_bgezals_op:
>> + case mm_bc2f_op:
>> + case mm_bc2t_op:
>> + case mm_bc1f_op:
>> + case mm_bc1t_op:
>> + goto is_branch;
>> + }
>> + break;
>> +
>> + case mm_pool16c_op:
>> + switch (inst.mm16_r5_format.rt) {
>> + case mm_jr16_op:
>> + case mm_jrc_op:
>> + case mm_jalr16_op:
>> + case mm_jalrs16_op:
>> + case mm_jraddiusp_op:
>> + goto is_branch;
>> + }
>> + break;
>> + }
>> + }
>> +
>>
WARNING: multiple messages have this Message-ID (diff)
From: Paul Burton <paul.burton@imgtec.com>
To: David Daney <ddaney.cavm@gmail.com>
Cc: linux-mips@linux-mips.org
Subject: Re: [PATCH 5/6] mips: use per-mm page to execute FP branch delay slots
Date: Fri, 8 Nov 2013 12:07:31 +0000 [thread overview]
Message-ID: <527CD403.8040407@imgtec.com> (raw)
Message-ID: <20131108120731.UJmP-MENYkocrIMQ3gkxbtZibeEnjQJjBKy9UGsE7j8@z> (raw)
In-Reply-To: <527BD537.4040903@gmail.com>
On 07/11/13 18:00, David Daney wrote:
> Nice work...
>
> On 11/07/2013 04:48 AM, Paul Burton wrote:
> [...]
>> - * Algorithmics used a system call instruction, and
>> - * borrowed that vector. MIPS/Linux version is a bit
>> - * more heavyweight in the interests of portability and
>> - * multiprocessor support. For Linux we generate a
>> - * an unaligned access and force an address error exception.
>> + * 1) Be a bug in the userland code, because it has a
>> branch/jump in
>> + * a branch delay slot. So if we run out of emuframes and the
>> + * userland code hangs it's not exactly the kernels fault.
>
> s/kernels/kernel's/
>
Yup, thanks.
>
>> *
>> - * For embedded systems (stand-alone) we prefer to use a
>> - * non-existing CP1 instruction. This prevents us from emulating
>> - * branches, but gives us a cleaner interface to the exception
>> - * handler (single entry point).
>> + * 2) Only affect that userland process, since emuframes are
>> allocated
>> + * per-mm and kernel threads don't use them at all.
>> */
>> + if (!get_isa16_mode(regs->cp0_epc)) {
>> + if (!ir) {
>> + /* typical NOP encoding: sll r0, r0, r0 */
>> +is_nop:
>> + regs->cp0_epc = cpc;
>> + regs->cp0_cause &= ~CAUSEF_BD;
>> + return 0;
>> + }
>>
>> - /* Ensure that the two instructions are in the same cache line */
>> - fr = (struct emuframe __user *)
>> - ((regs->regs[29] - sizeof(struct emuframe)) & ~0x7);
>> + switch (inst.j_format.opcode) {
>> + case bcond_op:
>> + switch (inst.i_format.rt) {
>> + case bltz_op:
>> + case bgez_op:
>> + case bltzl_op:
>> + case bgezl_op:
>> + case bltzal_op:
>> + case bgezal_op:
>> + case bltzall_op:
>> + case bgezall_op:
>> + goto is_branch;
>> + }
>> + break;
>
> Is there any way to use the support in arch/mips/kernel/branch.c instead
> of duplicating the code here?
>
> It may require some refactoring to make it work, but I think it would be
> worth it.
>
Ah (how had I not spotted that code?) :)
It may fit better with the (mm_)isBranchInstr functions in
arch/mips/math-emu/cp1emu.c since they already return a value specifying
whether or not the instruction is a branch. The microMIPS variant is
already used elsewhere too. I'll take a look at it.
Thanks,
Paul
>>
>> - /* Verify that the stack pointer is not competely insane */
>> - if (unlikely(!access_ok(VERIFY_WRITE, fr, sizeof(struct emuframe))))
>> + case cop1_op:
>> + switch (inst.i_format.rs) {
>> + case bc_op:
>> + goto is_branch;
>> + }
>> + break;
>> +
>> + case j_op:
>> + case jal_op:
>> + case beq_op:
>> + case bne_op:
>> + case blez_op:
>> + case bgtz_op:
>> + case beql_op:
>> + case bnel_op:
>> + case blezl_op:
>> + case bgtzl_op:
>> + case jalx_op:
>> +is_branch:
>> + pr_warn("PID %d has a branch in an FP branch delay slot
>> at 0x%08lx\n",
>> + current->pid, regs->cp0_epc);
>> + goto is_nop;
>> + }
>> + } else {
>> + if ((ir >> 16) == MM_NOP16)
>> + goto is_nop;
>> +
>> + switch (inst.mm_i_format.opcode) {
>> + case mm_beqz16_op:
>> + case mm_beq32_op:
>> + case mm_bnez16_op:
>> + case mm_bne32_op:
>> + case mm_b16_op:
>> + case mm_j32_op:
>> + case mm_jalx32_op:
>> + case mm_jal32_op:
>> + goto is_branch;
>> +
>> + case mm_pool32i_op:
>> + switch (inst.mm_i_format.rt) {
>> + case mm_bltz_op:
>> + case mm_bltzal_op:
>> + case mm_bgez_op:
>> + case mm_bgezal_op:
>> + case mm_blez_op:
>> + case mm_bnezc_op:
>> + case mm_bgtz_op:
>> + case mm_beqzc_op:
>> + case mm_bltzals_op:
>> + case mm_bgezals_op:
>> + case mm_bc2f_op:
>> + case mm_bc2t_op:
>> + case mm_bc1f_op:
>> + case mm_bc1t_op:
>> + goto is_branch;
>> + }
>> + break;
>> +
>> + case mm_pool16c_op:
>> + switch (inst.mm16_r5_format.rt) {
>> + case mm_jr16_op:
>> + case mm_jrc_op:
>> + case mm_jalr16_op:
>> + case mm_jalrs16_op:
>> + case mm_jraddiusp_op:
>> + goto is_branch;
>> + }
>> + break;
>> + }
>> + }
>> +
>>
next prev parent reply other threads:[~2013-11-08 12:08 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-11-07 12:48 [PATCH 0/6] FP improvements Paul Burton
2013-11-07 12:48 ` Paul Burton
2013-11-07 12:48 ` [PATCH 1/6] mips: mfhc1 & mthc1 support for the FPU emulator Paul Burton
2013-11-07 12:48 ` Paul Burton
2013-11-07 12:48 ` [PATCH 2/6] mips: microMIPS: " Paul Burton
2013-11-07 12:48 ` Paul Burton
2013-11-07 12:48 ` [PATCH 3/6] mips: remove unused {en,dis}able_fpu macros Paul Burton
2013-11-07 12:48 ` Paul Burton
2013-11-07 12:48 ` [PATCH 4/6] mips: support for 64-bit FP with O32 binaries Paul Burton
2013-11-07 12:48 ` Paul Burton
2013-11-15 12:35 ` [PATCH v2 " Paul Burton
2013-11-15 12:35 ` Paul Burton
2013-11-22 13:12 ` [PATCH v3 " Paul Burton
2013-11-22 13:12 ` Paul Burton
2013-11-07 12:48 ` [PATCH 5/6] mips: use per-mm page to execute FP branch delay slots Paul Burton
2013-11-07 12:48 ` Paul Burton
2013-11-07 18:00 ` David Daney
2013-11-08 12:07 ` Paul Burton [this message]
2013-11-08 12:07 ` Paul Burton
2013-11-08 14:50 ` [PATCH v2 " Paul Burton
2013-11-08 14:50 ` Paul Burton
2013-11-21 16:48 ` Paul Burton
2013-11-21 16:48 ` Paul Burton
2013-11-07 12:48 ` [PATCH 6/6] mips: non-exec stack & heap when non-exec PT_GNU_STACK is present Paul Burton
2013-11-07 12:48 ` Paul Burton
2013-11-07 13:57 ` [PATCH 0/6] FP improvements Ralf Baechle
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=527CD403.8040407@imgtec.com \
--to=paul.burton@imgtec.com \
--cc=ddaney.cavm@gmail.com \
--cc=linux-mips@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