Re: [Qemu-devel] BUG: soft lockup detected on CPU#0!
Hi, Answering 1. Am I instrumenting all stores if I instrument the OPROTOs in ops_mem.h? Do you consider all updates to memory as stores? e.g. add %ebx, (%eax), will also write to the memory and void OPPROTO glue(glue(op_stl, MEMSUFFIX), _T0_A0)(void) or one of its variant will be called. If you are interested in all the memory updates, then your approach is correct. If you are only interested in store instructions then your approach is not correct. Atif On 5/17/07, Shashidhar Mysore [EMAIL PROTECTED] wrote: Hi, I want to instrument all store instructions, and for this I wrote a helper function (in helper.c) which prints out some information every time a store is executed. I call this helper function from within every store OPROTO in ops_mem.h for example: void OPPROTO glue(glue(op_stl, MEMSUFFIX), _T0_A0)(void) { glue(stl, MEMSUFFIX)(A0, T0); helper_print_info(A0); // MY HELPER FUNCTION FORCE_RET(); } This works just fine for me for some time, but after a while when the frequency of calls to helper_print_info increases, QEMU just hangs throwing out some information on the QEMU console. I have typed in the error message in parts below - (If you need more information, please let me know - I included a subset just because I do not yet know how to copy-paste text from QEMU console to the host machine console) *** BUG: soft lockup detected on CPU#0! Pid: 0, comm: swapper EIP: 0060:[c027adfb] CPU: 0 EIP is at serio_interrupt+0x7f/0x18f EFLAGS: 0286 ... [c02c1b2d] cdrom_pc_intr+0x90/0x21a ... [c0105b1d] do_IRQ+0x4a/0x82 === ... [c04242fe] unknown_bootoption+0x0/0x1cd QEMU hangs after throwing out the above error. However, if I switch to the Monitor and disable my helper function, QEMU resumes back and works fine. Can somebody tell me - 1. Am I instrumenting all stores if I instrument the OPROTOs in ops_mem.h? 2. From my above example, am I instrumenting the stores with my helper function in the right way? 3. Can you please tell me why BUG: soft lockup detected... error shows up freezing QEMU? Looking forward to your help. Thanks in advance. -Shashi.
Re: [Qemu-devel] BUG: soft lockup detected on CPU#0!
Hi Shashi, I think it is sufficient to add your intercept code in ops_mem.h. I am not sure about the writes from the I/O though. Regards, Atif On 5/17/07, Shashidhar Mysore [EMAIL PROTECTED] wrote: Hi Atif, Thanks for the quick reply. Yes, you are right, I want to consider all updates to memory. Can you tell me if it is sufficient enough to instrument just those in ops_mem.h? I want to make sure I am not missing any form of write to the memory (even it is from IO devices, which I think is taken care of). Thanks, -Shashi. On 5/17/07, Atif Hashmi [EMAIL PROTECTED] wrote: Hi, Answering 1. Am I instrumenting all stores if I instrument the OPROTOs in ops_mem.h? Do you consider all updates to memory as stores? e.g. add %ebx, (%eax), will also write to the memory and void OPPROTO glue(glue(op_stl, MEMSUFFIX), _T0_A0)(void) or one of its variant will be called. If you are interested in all the memory updates, then your approach is correct. If you are only interested in store instructions then your approach is not correct. Atif On 5/17/07, Shashidhar Mysore [EMAIL PROTECTED] wrote: Hi, I want to instrument all store instructions, and for this I wrote a helper function (in helper.c) which prints out some information every time a store is executed. I call this helper function from within every store OPROTO in ops_mem.h for example: void OPPROTO glue(glue(op_stl, MEMSUFFIX), _T0_A0)(void) { glue(stl, MEMSUFFIX)(A0, T0); helper_print_info(A0); // MY HELPER FUNCTION FORCE_RET(); } This works just fine for me for some time, but after a while when the frequency of calls to helper_print_info increases, QEMU just hangs throwing out some information on the QEMU console. I have typed in the error message in parts below - (If you need more information, please let me know - I included a subset just because I do not yet know how to copy-paste text from QEMU console to the host machine console) *** BUG: soft lockup detected on CPU#0! Pid: 0, comm: swapper EIP: 0060:[c027adfb] CPU: 0 EIP is at serio_interrupt+0x7f/0x18f EFLAGS: 0286 ... [c02c1b2d] cdrom_pc_intr+0x90/0x21a ... [c0105b1d] do_IRQ+0x4a/0x82 === ... [c04242fe] unknown_bootoption+0x0/0x1cd QEMU hangs after throwing out the above error. However, if I switch to the Monitor and disable my helper function, QEMU resumes back and works fine. Can somebody tell me - 1. Am I instrumenting all stores if I instrument the OPROTOs in ops_mem.h? 2. From my above example, am I instrumenting the stores with my helper function in the right way? 3. Can you please tell me why BUG: soft lockup detected... error shows up freezing QEMU? Looking forward to your help. Thanks in advance. -Shashi.
Re: [Qemu-devel] Re: Detecting an assembly instruction in QEMU
Hi Eduardo, Is it possible to identify context switches inside QEMU. In order to support transactional memory in QEMU, we have added target_ulong tm_abort_eip; int inTransaction; to CPUX86State structure. tm_abort_eip is the EIP to jump to when a transaction fails i.e. start of the Transactional Block while inTransaction tells us whether a transaction has started so that we can log the memory references. As far as I understand, env variable will be modified at a context switch. At a context switch, we need to update tm_abort_eip as well as inTransaction based on the status of the new thread being loaded. We can store these two variables inside DisasContext which I believe is unique for each translated block. But when and where should we modify the env variable so that for each thread it contains the correct values for tm_abort_eip and inTransaction. I will appreciate your help. Thanks, Atif On 4/27/07, Eduardo Felipe [EMAIL PROTECTED] wrote: I think I could not explain my question regarding addl %ebx, (%eax). What I wanted to ask was that this instruction also accesses the memory and I also need to intercept it within a transaction. Incase of addl %ebx, (%eax), Are the functions under /* CPU memory access without any memory or io remapping */ called in case of this instruction. Yes. Just look how the instruction is translated into opcodes and you'll see how it works. You can use the -d switch for this. Secondly, there is a function in exec.c called cpu_physical_memory_rw. Is it easier to hack into this fuction to intercept the memory references. That function is used by emulated hardware devices to interact with memory ( e.g. DMA to write and read memory chunks). Translated guest code does not use it. Regards, Eduardo
Re: [Qemu-devel] Re: Detecting an assembly instruction in QEMU
Hi Eduardo, I think I could not explain my question regarding addl %ebx, (%eax). What I wanted to ask was that this instruction also accesses the memory and I also need to intercept it within a transaction. Incase of addl %ebx, (%eax), Are the functions under /* CPU memory access without any memory or io remapping */ called in case of this instruction. Secondly, there is a function in exec.c called cpu_physical_memory_rw. Is it easier to hack into this fuction to intercept the memory references. Thanks, Atif On 4/26/07, Eduardo Felipe [EMAIL PROTECTED] wrote: 2007/4/25, Atif Hashmi [EMAIL PROTECTED]: Instructions like addl %ebx, (%eax) are also considered to be memory refernce instructions. Do these type of instructions also refer to the functions that you mentioned. No. You are using __asm_volatile(mov %al %al) to mark the start of your transaction and __asm_volatile(mov %bl %bl) to mark the end. What I meant is that your compiler could generate mov %al,%al or mov %bl,%bl in any other place for whatever reason when it compiles C code. Also your guest OS or any other program running in it can use these two instructions too. Both cases would affect in what you intend to do. Secondly, what is the purpose of undef ASM_SOFTMMU If ASM_SOFTMMU is defined, pure assembly memory access routines are used (faster). If it is not defined, alternative C routines are used, which are slower but easier to modify. Regards, Eduardo
Re: [Qemu-devel] Re: Detecting an assembly instruction in QEMU
Hi Eduardo, Thanks for pointing me to the file. Could you please clarify one more thing. Instructions like addl %ebx, (%eax) are also considered to be memory refernce instructions. Do these type of instructions also refer to the functions that you mentioned. Secondly, what is the purpose of undef ASM_SOFTMMU Thanks, Atif On 4/25/07, Atif Hashmi [EMAIL PROTECTED] wrote: Hi Eduardo, Thanks for pointing me to the file. Could you please clarify one more thing. Instructions like addl %ebx, (%eax) are also considered to be assembly instructions. Do these type of instructions also refer to the functions that you mentioned. Thanks, Atif On 4/24/07, Eduardo Felipe [EMAIL PROTECTED] wrote: Hi, You have a description of memory access instruction format in cpu-all.h, under /* CPU memory access without any memory or io remapping */ These instructions are defined in softmmu_header.h. If you don't care too much about performance it will be easier to modify the code written in C (undef ASM_SOFTMMU in op.c). Regards, Eduardo
Re: [Qemu-devel] Re: Detecting an assembly instruction in QEMU
Hi Eduardo, I have finished implementing the implementing the roll-back functionality for transactional memory. There is one thing that I wanted to ask you. In order to roll-back, I need to log all the memory references. So that in that case when a transaction fails and roll-back occurs, memory state can also be rolled back. I will really apprecaite if you could direct me to the piece of code in QEMU for i386, where I can intercept the memory references. Thanks, Atif On 4/22/07, Eduardo Felipe [EMAIL PROTECTED] wrote: Hi Atif, Your code seems quite ok to me. Just try including stored_eip inside the DisasContext, otherwise you'll lose its value between calls to disas_insn function. Also make sure that the instructions you are using as markers are not executed elsewhere, as your compiler could generate them inside regular code or they could already exist in your OS. Regards, Eduardo
Re: [Qemu-devel] Re: Detecting an assembly instruction in QEMU
HI Eduardo, Thanks for you reply. I have update target-i386/translate.c as follows if(modrm==0xC0) { stored_eip = pc_start - s-cs_base; gen_op_movl_AL_AL(); } else if(modrm==0xDB) { gen_op_movl_BL_BL(stored_eip); gen_eob(s); } target-i386/op.c contains the following. void OPPROTO op_movl_AL_AL() { helper_StartTransaction(); } void OPPROTO op_movl_BL_BL() { if(helper_CommitTransaction()) { EIP = PARAM1; } } and helper.c looks like void helper_StartTransaction() { printf(StartTransaction Called\n); } unsigned char helper_CommitTransaction() { static int i=0; printf(CommitTransaction Called\n); return 1; } Essentially, if we have a program like int main() { __asm_volatile(mov %al %al); //is detected in translation.c and helper_StartTransaction is called printf(middle); __asm_volatile(mov %bl %bl); //is detected in translation.c and helper_CommitTransaction is called } We should continuously print middle on the QEMU screen while StartTransaction Called and End Transaction Called for infinite amount of time. But I get the following behaviour. On QEMU screen, middle is printed once, and I get the following on the xterm StartTransaction Called CommitTransaction Called StartTransaction Called After that I get the QEMU prompt back and the program finishes. I still have not been able to figure it out why after calling helper_StartTransaction() for the seconds time the program does not continue? Is their anything else that we have not considered. I will really appreciate your help. Regards, Atif On 4/17/07, Eduardo Felipe [EMAIL PROTECTED] wrote: Hi 2007/4/17, Atif Hashmi [EMAIL PROTECTED]: But this prints Transaction restart once and then the program finishes. This means that commit transaction is not called the second time. Could you please tell me what am I doing wrong? Helper functions are outside the translated opcode stream and are invoked by call/ret: .--. | | | ---+-- helper_StartTransaction() | --+---/ | | | | | ---+-- helper_CommitTransaction() | --+---/ | | '--' When you longjmp from helper_CommitTransaction to helper_StartTransaction it's probable that you return back to the point where helper_CommitTransaction should have returned to, as it is the last address stored in the stack. Anyway, guest code between the start and the end of the transaction should not be rerun without updating guest machine state (eip, flags, etc.). You should better forget about using setjmp/longjmp. Maybe something like this could do the trick: when translating mov %al,%al: { ... ... store the address (eip) of mov %al,%al instruction somewhere gen_op_start_transaction(); } when translating mov %bl, %bl: { ... ... gen_op_commit_transaction(stored_eip); gen_eob(s); // Stop translation to force guest state updating } op_commit_transaction should look like: { if ( helper_CommitTransaction() ) // helper should return !=0 on error EIP = PARAM1; } Regards, Eduardo
Re: [Qemu-devel] Re: Detecting an assembly instruction in QEMU
Hi, I have another small question. Actually, I am implementing hardware transactional memory support in QEMU. I have implemented the following two helper functions functions in targer-i386/helper.c void helper_StartTransaction() void helper_CommitTransaction(); My application looks as follows. int main() { __asm_volatile(mov %al %al); //is detected in translation.c and helper_StartTransaction is called } In case a transaction fails, I detect it inside the code for helper_CommitTransaction(), now I need to jump back to the place where On 4/8/07, Eduardo Felipe [EMAIL PROTECTED] wrote: I recommend: http://fabrice.bellard.free.fr/qemu/user-doc.html Regards, Eduardo
Re: [Qemu-devel] Re: Detecting an assembly instruction in QEMU
Sorry for my previous incomplete email Hi, I have another small question. Actually, I am implementing hardware transactional memory support in QEMU. I have implemented the following two helper functions functions in targer-i386/helper.c void helper_StartTransaction() void helper_CommitTransaction(); My application looks as follows. int main() { __asm_volatile(mov %al %al); //is detected in translation.c and helper_StartTransaction is called //add the code here __asm_volatile(mov %bl %bl); //is detected in translation.c and helper_CommitTransaction is called } In case a transaction fails, I detect it inside the code for helper_CommitTransaction(), now I need to jump back to the start of transaction. I do it by using setjmp inside helper_StartTransaction and calling longjmp inside CommitTransaction, Code for the two helper functions is as follows void helper_StartTransaction() { printf(StartTransaction Called\n); if(setjmp(env-tm_jmp)) { printf(Transaction restart\); } } void helper_CommitTransaction() { printf(CommitTransaction Called\n); longjmp(env-tm_jmp, 0); } But this prints Transaction restart once and then the program finishes. This means that commit transaction is not called the second time. Could you please tell me what am I doing wrong? Regards, Atif On 4/16/07, Atif Hashmi [EMAIL PROTECTED] wrote: On 4/8/07, Eduardo Felipe [EMAIL PROTECTED] wrote: I recommend: http://fabrice.bellard.free.fr/qemu/user-doc.html Regards, Eduardo
Re: [Qemu-devel] Re: Detecting an assembly instruction in QEMU
Hi Eduardo, Thanks a lot for your help. I really appreciate it. I have added the functionality that I wanted. By the way, Is there any documentation that can help me better understand the QEMU source code? Regards, Atif On 4/8/07, Eduardo Felipe [EMAIL PROTECTED] wrote: Hi Atif, In target-i386/translate.c, there are many variants of mov i.e. case 0x89: /* mov Gv, Ev */ case 0xc7: /* mov Ev, Iv */ case 0x8b: /* mov Ev, Gv */ case 0x8e: /* mov seg, Gv */ That's true. I forgot the fact that mov %eax,%eax can be both: 0x89 0xC0 0x8B 0xC0 It's up to the compiler to choose which one to use. which one do you think will be called when mov %eax, %eax instruction is translated. I printed the value of modrm inside the case 0x89 but the value remains the same whether I use %eax or %ebx. Secondly, How can I extract the source and destination registers from modrm. modrm is the byte following the 0x89 or 0x8B opcode. After modrm = ldub_code(s-pc++); you can decode it this way (in binary): XXYYYZZZ XX -- Indexing mode YYY -- Destination register ZZZ -- Source register 0xC0 is the value you are looking for 11 000 000 -- (no indexing)(%eax)(%eax). You can find more information here: http://pdos.csail.mit.edu/6.828/2005/readings/i386/s17_02.htm One more thing: you may want to check operand size. It's on ot variable, and its meaning (from translate.c): enum { OT_BYTE = 0, OT_WORD, OT_LONG, OT_QUAD, }; being 8, 16, 32 and 64 bits respectively. Regards, Eduardo
Re: [Qemu-devel] Re: Detecting an assembly instruction in QEMU
Hi Eduardo, I really appreciate your help but there is a small think that I need to ask you. In target-i386/translate.c, there are many variants of mov i.e. case 0x89: /* mov Gv, Ev */ case 0xc7: /* mov Ev, Iv */ case 0x8b: /* mov Ev, Gv */ case 0x8e: /* mov seg, Gv */ which one do you think will be called when mov %eax, %eax instruction is translated. I printed the value of modrm inside the case 0x89 but the value remains the same whether I use %eax or %ebx. Secondly, How can I extract the source and destination registers from modrm. I will really appreciate your help. Thanks, Atif On 4/6/07, Eduardo Felipe [EMAIL PROTECTED] wrote: Hi, Your should create a new helper function in \target-i386\helper.c to perform whatever you want QEMU to do when movl %eax,%eax is found. To invoke that function create a new opcode in \target-i386\op.c. That opcode should only call your helper function. Finally, modify \target-i386\translate.c to generate your opcode when movl %eax,%eax is translated. Look for the string 0x89, you can find out target and source registers of the move operation from variable modrm, so only %eax is considered. Regards, Eduardo
[Qemu-devel] Re: Detecting an assembly instruction in QEMU
Hi All, Adding another note to my previous email. Is this even possible to do what I am mentioned in my last email? (See Below) Regards, Atif On 4/3/07, Atif Hashmi [EMAIL PROTECTED] wrote: Hi All, I am inserting movl %eax, %eax instruction within the assembly code of a program and I am running the code on QEMU which is configured for i386 and is running linux-0.2.img. I want to detect this assembly instruction within the QEMU code in order to perform a specific operation e.g. when ever QEMU finds this instruction a specific function is called. Could anyone please tell me which QEMU files should I modify in order to add this functionality. I looked through almost all the C files but was unable to figure it out. I will really appreciate any help. Thanks, Atif
[Qemu-devel] Detecting an assembly instruction in QEMU
Hi All, I am inserting movl %eax, %eax instruction within the assembly code of a program and I am running the code on QEMU which is configured for i386 and is running linux-0.2.img. I want to detect this assembly instruction within the QEMU code in order to perform a specific operation e.g. when ever QEMU finds this instruction a specific function is called. Could anyone please tell me which QEMU files should I modify in order to add this functionality. I looked through almost all the C files but was unable to figure it out. I will really appreciate any help. Thanks, Atif