Re: [Qemu-devel] [Bug] [Patch] MIPS code fails at branch instruction
On Sun, Mar 25, 2007 at 03:43:16AM +0200, Aurelien Jarno wrote: Thiemo Seufer a écrit : [...] - Execute the second branch's delay slot instruction. Increment PC. [...] I'm surprised that this step would be there -- I would have expected it to be simpler to execute the target of the first branch in place of the second branch's delay slot. Yep I confirm that, it is clearly explained starting at the page 54 of the SPARC v8 manual. To avoid this behaviour it is possible to cancel the delay slot instruction by having a=1. SPARC doesn't have the execute the second branch's delay slot step. From the table on page 56, it seems to execute: branch1 branch2 target of branch1 (one instruction only) target of branch2 (continuing) PA-RISC has the same requirement (PA-RISC 2.0 manual, pages 4-5 and 4-6, and PA-RISC 1.1 manual, page 4-10). -- Stuart Brady ___ Qemu-devel mailing list Qemu-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/qemu-devel
Re: [Qemu-devel] [Bug] [Patch] MIPS code fails at branch instruction
Stuart Brady wrote: On Sun, Mar 25, 2007 at 03:43:16AM +0200, Aurelien Jarno wrote: Thiemo Seufer a écrit : [...] - Execute the second branch's delay slot instruction. Increment PC. [...] I'm surprised that this step would be there -- I would have expected it to be simpler to execute the target of the first branch in place of the second branch's delay slot. Maybe you are right. It depends on how many cycles of delay the branch incurs. Thiemo
Re: [Qemu-devel] [Bug] [Patch] MIPS code fails at branch instruction
Stefan Weil wrote: Hi, here is the patch which adds a 4KEcR1 CPU (a 4KEc, processor revision 2.2, with MIPS32 Release 1 (!) instruction set is the heart of the AR7 SoC). See also include/asm-mips/cpu.h in the Linux kernel sources: ./include/asm-mips/cpu.h:#define PRID_IMP_4KEC 0x8400 ./include/asm-mips/cpu.h:#define PRID_IMP_4KECR20x9000 This was the bit which prompted to to ask The People Who Know[TM]. Indeed the early 4KEc were MIPS32R1 only. About the branch-in-delay-slot I got the following information: Very simple pipelines with branch delay slots tend to behave like this (when both branches are taken): - Execute the first branch, that is, calculate the target of the branch. This has no effect until it ran far enough through the pipeline. Increment PC. - Execute the second branch. This changes the branch target value again. Increment PC. - Execute the second branch's delay slot instruction. Increment PC. - Now the PC is overridden by the first branch's target. A single instruction from that place is executed. - The PC is overridden again by the second branch's target. Normal execution resumes from there. Apparently the SPARC architecture _requires_ this behaviour for all CPUs. Can you check if this is the behaviour you see on an AR7? Thiemo ___ Qemu-devel mailing list Qemu-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/qemu-devel
Re: [Qemu-devel] [Bug] [Patch] MIPS code fails at branch instruction
Thiemo Seufer a écrit : Stefan Weil wrote: Hi, here is the patch which adds a 4KEcR1 CPU (a 4KEc, processor revision 2.2, with MIPS32 Release 1 (!) instruction set is the heart of the AR7 SoC). See also include/asm-mips/cpu.h in the Linux kernel sources: ./include/asm-mips/cpu.h:#define PRID_IMP_4KEC 0x8400 ./include/asm-mips/cpu.h:#define PRID_IMP_4KECR20x9000 This was the bit which prompted to to ask The People Who Know[TM]. Indeed the early 4KEc were MIPS32R1 only. About the branch-in-delay-slot I got the following information: Very simple pipelines with branch delay slots tend to behave like this (when both branches are taken): - Execute the first branch, that is, calculate the target of the branch. This has no effect until it ran far enough through the pipeline. Increment PC. - Execute the second branch. This changes the branch target value again. Increment PC. - Execute the second branch's delay slot instruction. Increment PC. - Now the PC is overridden by the first branch's target. A single instruction from that place is executed. - The PC is overridden again by the second branch's target. Normal execution resumes from there. Apparently the SPARC architecture _requires_ this behaviour for all CPUs. Yep I confirm that, it is clearly explained starting at the page 54 of the SPARC v8 manual. To avoid this behaviour it is possible to cancel the delay slot instruction by having a=1. -- .''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' [EMAIL PROTECTED] | [EMAIL PROTECTED] `-people.debian.org/~aurel32 | www.aurel32.net ___ Qemu-devel mailing list Qemu-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/qemu-devel
Re: [Qemu-devel] [Bug] [Patch] MIPS code fails at branch instruction
Thiemo Seufer [EMAIL PROTECTED] wrote: For the AR7 case, could you - add AR7 as a CPU type - handle the interesting cases for AR7 only, after verifying the cornercase behaviour of qemu and real hardware is consistent. AFAIK, Texas Instrument AR7 isn't a CPU. It's a SoC which combines well-known MIPS 4KEc synthesizable *core* and ADSL stuff. http://www.linux-mips.org/wiki/AR7 -- -=AV=- ___ Qemu-devel mailing list Qemu-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/qemu-devel
Re: [Qemu-devel] [Bug] [Patch] MIPS code fails at branch instruction
Alexander Voropay wrote: Thiemo Seufer [EMAIL PROTECTED] wrote: For the AR7 case, could you - add AR7 as a CPU type - handle the interesting cases for AR7 only, after verifying the cornercase behaviour of qemu and real hardware is consistent. AFAIK, Texas Instrument AR7 isn't a CPU. It's a SoC which combines well-known MIPS 4KEc synthesizable *core* and ADSL stuff. Other 4KEc behave differently (probably due to differences in the synthesizing technology used), so I figure AR7 becomes a special CPU for qemu's purposes. Thiemo ___ Qemu-devel mailing list Qemu-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/qemu-devel
Re: [Qemu-devel] [Bug] [Patch] MIPS code fails at branch instruction
Hi, here is the patch which adds a 4KEcR1 CPU (a 4KEc, processor revision 2.2, with MIPS32 Release 1 (!) instruction set is the heart of the AR7 SoC). See also include/asm-mips/cpu.h in the Linux kernel sources: ./include/asm-mips/cpu.h:#define PRID_IMP_4KEC 0x8400 ./include/asm-mips/cpu.h:#define PRID_IMP_4KECR20x9000 Stefan PS. Did anybody run my branch test code on other MIPS CPUs? What was the result? Sorry, because of trouble with the Savannah CVS server, the patch is not against CVS. --- ../branches/head/target-mips/translate_init.c 2007-03-18 01:30:29.0 +0100 +++ target-mips/translate_init.c2007-03-20 18:47:59.0 +0100 @@ -44,6 +44,12 @@ .CP0_Config1 = MIPS_CONFIG1, }, { +.name = 4KEcR1, +.CP0_PRid = 0x00018448, +.CP0_Config0 = MIPS_CONFIG0, +.CP0_Config1 = MIPS_CONFIG1, +}, +{ .name = 24Kf, .CP0_PRid = 0x00019300, .CP0_Config0 = MIPS_CONFIG0 | (0x1 CP0C0_AR), Thiemo Seufer schrieb: Thiemo Seufer wrote: [snip] I committed something which cover the rest of your patch, and throws now a RI exception for branch-in-branch-delay-slot. For the AR7 case, could you - add AR7 as a CPU type - handle the interesting cases for AR7 only, after verifying the cornercase behaviour of qemu and real hardware is consistent. The cornercases which come to mind: - conditional vs. unconditional branches - the various condition types - taken vs. non-taken branches - linked vs. non-linked branches - likely vs. non-likely branches - the side effects of j / jal in the delayslot - the value of PC/ra (if it changes) I don't ask for an exhaustive analysis, I just want to see the cases of interest covered, so we can be reasonably sure the qemu results will be useful for other AR7 users as well. Thiemo ___ Qemu-devel mailing list Qemu-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/qemu-devel
Re: [Qemu-devel] [Bug] [Patch] MIPS code fails at branch instruction
Thank you, Paul, for your explanation which clarified Thiemo's statement. I now checked how my published test code could contribute to a DoS attack. Current QEMU HEAD: * The code hangs as I wrote before. This is from a user's point of view. Hanging means, that the test process runs in an infinite loop using any CPU time it can get in the virtual machine. QEMU uses all available CPU time from the host CPU. With single stepping enabled or in the debugger, the test code won't hang but give a random result. Patched QEMU HEAD (see appended patch file): * The code works in a well defined way. An optional message in the log file will show the faulty statement. It won't amount to a DoS because it is disabled by default. Using single stepping, the test code's result remains the same. So the patch improves the situation. Although it does not model the real behaviour of an AR7 cpu, it solved my problem with a Zyxel firmware. Maybe you can apply at least part of it or even improve and extend it to other branch operations. Thank you Stefan Details of the patch * show optional message when any branch bits in hflags are already set before a branch instruction is generated (so we have a branch in the delay slot) * mask branch bits before setting new ones (implemented only for the jr statement because this was the one I needed and examined) - this part could be improved * make gen_intermediate_code_internal static (might improve compiler optimizations and is completely unrelated to the other two changes) Paul Brook wrote: So an emulation has several options: 1. Show undefined behaviour (this is what it does today). 2. Emulate the behaviour of existing CPUs as far as possible. As different CPUs behave different, this must depend on the current CPU. 3. Display an error message. (3) is bad, as it amounts to a DoS. DoS = Denial of Service? Then (1) is some kind of DoS, because QEMU hangs with code which works on real hardware. I don't understand why an error message (something printed to stdout or stderr like other boot messages of QEMU) amounts to a DoS. It's not the same thing at all. In both cases buggy code crashes. I expect this could also happen on a fair proportion of real MIPS hardware. It may even happen on AR7 hardware is a interrupt or fault happens to trigger at the wrong time. With (1) the buggy program crashes, and the rest of the machine keeps going. With (3) an unprivileged user can effectively bring the whole machine down just by executing invalid code sequences. Paul Index: target-mips/translate.c === RCS file: /sources/qemu/qemu/target-mips/translate.c,v retrieving revision 1.37 diff -u -b -B -u -r1.37 translate.c --- target-mips/translate.c 18 Mar 2007 00:30:29 - 1.37 +++ target-mips/translate.c 19 Mar 2007 20:26:31 - @@ -1371,6 +1371,13 @@ target_ulong btarget; int blink, bcond; +if (ctx-hflags MIPS_HFLAG_BMASK) { +if (loglevel CPU_LOG_TB_IN_ASM) { +fprintf(logfile, +undefined branch in delay slot at pc 0x%08x\n, ctx-pc); +} +} + btarget = -1; blink = 0; bcond = 0; @@ -1480,7 +1487,7 @@ MIPS_DEBUG(jal %08x, btarget); break; case OPC_JR: -ctx-hflags |= MIPS_HFLAG_BR; +ctx-hflags = ((ctx-hflags ~MIPS_HFLAG_BMASK) | MIPS_HFLAG_BR); MIPS_DEBUG(jr %s, regnames[rs]); break; case OPC_JALR: @@ -4999,7 +5006,7 @@ } } -int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, +static int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, int search_pc) { DisasContext ctx, *ctxp = ctx; ___ Qemu-devel mailing list Qemu-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/qemu-devel
Re: [Qemu-devel] [Bug] [Patch] MIPS code fails at branch instruction
Stefan Weil wrote: Thank you, Paul, for your explanation which clarified Thiemo's statement. I now checked how my published test code could contribute to a DoS attack. Current QEMU HEAD: * The code hangs as I wrote before. This is from a user's point of view. Hanging means, that the test process runs in an infinite loop using any CPU time it can get in the virtual machine. QEMU uses all available CPU time from the host CPU. This is a bug in qemu, since it doesn't match CPU behaviour. While the architecture spec claims UNPREDICTABLE, such a code sequence shouldn't impede other processes on the same CPU. Throwing an RI exception should suffice for the general case (i.e. not AR7). With single stepping enabled or in the debugger, the test code won't hang but give a random result. Patched QEMU HEAD (see appended patch file): * The code works in a well defined way. An optional message in the log file will show the faulty statement. It won't amount to a DoS because it is disabled by default. Sorry, but I missed the well defined. What does the jump in the branch delay slot exactly _do_ now? Where does the PC point to when it was a conditional branch which wasn't taken? [snip] * show optional message when any branch bits in hflags are already set before a branch instruction is generated (so we have a branch in the delay slot) Agreed on that, since it is debug output which is only written when asked for. Thiemo ___ Qemu-devel mailing list Qemu-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/qemu-devel
Re: [Qemu-devel] [Bug] [Patch] MIPS code fails at branch instruction
Thiemo Seufer wrote: [snip] Patched QEMU HEAD (see appended patch file): * The code works in a well defined way. An optional message in the log file will show the faulty statement. It won't amount to a DoS because it is disabled by default. Sorry, but I missed the well defined. What does the jump in the branch delay slot exactly _do_ now? Where does the PC point to when it was a conditional branch which wasn't taken? I committed something which cover the rest of your patch, and throws now a RI exception for branch-in-branch-delay-slot. For the AR7 case, could you - add AR7 as a CPU type - handle the interesting cases for AR7 only, after verifying the cornercase behaviour of qemu and real hardware is consistent. The cornercases which come to mind: - conditional vs. unconditional branches - the various condition types - taken vs. non-taken branches - linked vs. non-linked branches - likely vs. non-likely branches - the side effects of j / jal in the delayslot - the value of PC/ra (if it changes) I don't ask for an exhaustive analysis, I just want to see the cases of interest covered, so we can be reasonably sure the qemu results will be useful for other AR7 users as well. Thiemo ___ Qemu-devel mailing list Qemu-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/qemu-devel