* [Qemu-devel] SVM emulation: EVENTINJ marked valid when a pagefault happens while issuing a software interrupt @ 2010-05-27 15:26 Erik van der Kouwe 2010-05-27 18:53 ` [Qemu-devel] " Jan Kiszka 0 siblings, 1 reply; 17+ messages in thread From: Erik van der Kouwe @ 2010-05-27 15:26 UTC (permalink / raw) To: qemu-devel Dear all, I have been experiencing problems with duplicate delivery of software interrupts when running a VMM inside QEMU with SVM emulation. I believe QEMU's behaviour deviates from the SVM specification in "AMD64 Architecture Programmer’s Manual Volume 2 System Programming" but I am not entirely certain because this specification isn't very clear. I would like to hear your views on this. My set-up is as follows: Host: Linux 2.6.31-21-generic-pae (Ubuntu 9.10) VMM running on host: QEMU 0.12.3 (compiled from source) Outer guest: MINIX 3.1.7 (from SVN, see http://www.minix3.org/) VMM running on outer guest: Palacios 1.2.0 32-bit (from git, see http://www.v3vee.org/palacios/) Inner guest: MINIX 3.1.7 (from SVN, see http://www.minix3.org/) The issue is the following: whenever an software interrupt instruction (INT n, used in this case to perform a system call) in the inner guest triggers a page fault (used for shadow paging by Palacios, not a real guest page fault), QEMU sets the EVENTINV field of the guest VMCB to the exit information that the software interrupt would produce and marks it as valid. Palacios does not overwrite the EVENTINJ field, so after the page fault is handled a software interrupt event is injected. After the IRET of the interrupt handler, control returns to the original INT n instruction which once again triggers the interrupt. This issue is easy to work around by clearing the EVENTINJ field on each #VMEXIT (and I have submitted a patch to that effect to the Palacios people) and this approach is also found in KVM. However, I haven't been able to find information in the AMD documentation that mentions that the CPU sets the valid bit in the EVENTINJ field so, unless I am mistaken here, I believe this behaviour is incorrect. QEMU stores interrupt information in both EVENTINJ and EXITINTINFO while I believe it should be only in the latter. Unfortunately I don't have a physical AMD available to verify its behaviour. The relevant code is in target-i386/op_helper.c. The "handle_even_inj" function sets the EVENTINJ field (called event_inf in the QEMU code) and the helper_vmexit function copies that field into EXITINTINFO (exit_int_info in the QEMU code). I believe (but once again, am not certain) that the SVM documentation only says that this information should be stored in EXITINTINFO. Thanks in advance for any information, Erik van der Kouwe ^ permalink raw reply [flat|nested] 17+ messages in thread
* [Qemu-devel] Re: SVM emulation: EVENTINJ marked valid when a pagefault happens while issuing a software interrupt 2010-05-27 15:26 [Qemu-devel] SVM emulation: EVENTINJ marked valid when a pagefault happens while issuing a software interrupt Erik van der Kouwe @ 2010-05-27 18:53 ` Jan Kiszka 2010-05-27 19:49 ` Erik van der Kouwe 2010-05-28 7:24 ` Roedel, Joerg 0 siblings, 2 replies; 17+ messages in thread From: Jan Kiszka @ 2010-05-27 18:53 UTC (permalink / raw) To: Erik van der Kouwe; +Cc: Joerg Roedel, qemu-devel, Gleb Natapov [-- Attachment #1: Type: text/plain, Size: 3475 bytes --] Erik van der Kouwe wrote: > Dear all, > > I have been experiencing problems with duplicate delivery of software > interrupts when running a VMM inside QEMU with SVM emulation. I believe Be warned: Though my experience is already more than a year old, the SVM emulation in QEMU is most probably not yet rock-stable. Always check suspicious behavior against real hardware and/or the spec. [ As real hardware is everywhere, nesting works with KVM+SVM and is much faster, motivation to improve QEMU in this area is unfortunately limited. ] > QEMU's behaviour deviates from the SVM specification in "AMD64 > Architecture Programmer’s Manual Volume 2 System Programming" but I am > not entirely certain because this specification isn't very clear. I > would like to hear your views on this. > > My set-up is as follows: > Host: Linux 2.6.31-21-generic-pae (Ubuntu 9.10) > VMM running on host: QEMU 0.12.3 (compiled from source) > Outer guest: MINIX 3.1.7 (from SVN, see http://www.minix3.org/) > VMM running on outer guest: Palacios 1.2.0 32-bit (from git, see > http://www.v3vee.org/palacios/) > Inner guest: MINIX 3.1.7 (from SVN, see http://www.minix3.org/) > > The issue is the following: whenever an software interrupt instruction > (INT n, used in this case to perform a system call) in the inner guest > triggers a page fault (used for shadow paging by Palacios, not a real > guest page fault), QEMU sets the EVENTINV field of the guest VMCB to the > exit information that the software interrupt would produce and marks it > as valid. Palacios does not overwrite the EVENTINJ field, so after the > page fault is handled a software interrupt event is injected. After the > IRET of the interrupt handler, control returns to the original INT n > instruction which once again triggers the interrupt. > > This issue is easy to work around by clearing the EVENTINJ field on each > #VMEXIT (and I have submitted a patch to that effect to the Palacios > people) and this approach is also found in KVM. /me does not find such clearing in KVM - what line(s) are you looking at? > > However, I haven't been able to find information in the AMD > documentation that mentions that the CPU sets the valid bit in the > EVENTINJ field so, unless I am mistaken here, I believe this behaviour > is incorrect. QEMU stores interrupt information in both EVENTINJ and > EXITINTINFO while I believe it should be only in the latter. > Unfortunately I don't have a physical AMD available to verify its > behaviour. Based on the KVM code (which is known to work perfectly :) ), I think you are right: SVM apparently clears the valid bit in EVENTINJ during VMRUN once it starts processing the injection, not after it as it's the case in current QEMU. But better ask the experts: Jörg, Gleb? > > The relevant code is in target-i386/op_helper.c. The "handle_even_inj" > function sets the EVENTINJ field (called event_inf in the QEMU code) and > the helper_vmexit function copies that field into EXITINTINFO > (exit_int_info in the QEMU code). I believe (but once again, am not > certain) that the SVM documentation only says that this information > should be stored in EXITINTINFO. Yes, this also looks suspicious. handle_even_inj should not push the real (level 1) event to be injected into event_inj[_err] but into exit_int_info[_err] or some temporary fields from which the exit info is then loaded later on. Jan [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 257 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* [Qemu-devel] Re: SVM emulation: EVENTINJ marked valid when a pagefault happens while issuing a software interrupt 2010-05-27 18:53 ` [Qemu-devel] " Jan Kiszka @ 2010-05-27 19:49 ` Erik van der Kouwe 2010-05-27 22:20 ` Jan Kiszka 2010-05-28 7:24 ` Roedel, Joerg 1 sibling, 1 reply; 17+ messages in thread From: Erik van der Kouwe @ 2010-05-27 19:49 UTC (permalink / raw) To: Jan Kiszka; +Cc: Joerg Roedel, qemu-devel, Gleb Natapov Hi, > Be warned: Though my experience is already more than a year old, the SVM > emulation in QEMU is most probably not yet rock-stable. Always check > suspicious behavior against real hardware and/or the spec. [ As real > hardware is everywhere, nesting works with KVM+SVM and is much faster, > motivation to improve QEMU in this area is unfortunately limited. ] Problem is: I'm compiling in Linux and testing in MINIX. Testing on the real hardware would require a reboot everytime. Moreover, it might screw up my system if I make bad mistakes (the MINIX filesystem is easily corrupted). That said, I do aim to eventually test the real hardware. Plenty of virtualization capable hardware where I work, although unfortunately all Intel. >> This issue is easy to work around by clearing the EVENTINJ field on each >> #VMEXIT (and I have submitted a patch to that effect to the Palacios >> people) and this approach is also found in KVM. > > /me does not find such clearing in KVM - what line(s) are you looking at? Linux source tree (2.6.31-ubuntu), arch/x86/kvm/svm.c, end of function nested_svm_vmrun. Here event_inj and event_inj_err are copied from a different VMCB, effectively clearing the value set by the CPU. Maybe this isn't were I should have been looking though? >> The relevant code is in target-i386/op_helper.c. The "handle_even_inj" >> function sets the EVENTINJ field (called event_inf in the QEMU code) and >> the helper_vmexit function copies that field into EXITINTINFO >> (exit_int_info in the QEMU code). I believe (but once again, am not >> certain) that the SVM documentation only says that this information >> should be stored in EXITINTINFO. > > Yes, this also looks suspicious. handle_even_inj should not push the > real (level 1) event to be injected into event_inj[_err] but into > exit_int_info[_err] or some temporary fields from which the exit info is > then loaded later on. Yes, if this is indeed incorrect behaviour then this is what I would expect a fix to be like. Thanks again, Erik ^ permalink raw reply [flat|nested] 17+ messages in thread
* [Qemu-devel] Re: SVM emulation: EVENTINJ marked valid when a pagefault happens while issuing a software interrupt 2010-05-27 19:49 ` Erik van der Kouwe @ 2010-05-27 22:20 ` Jan Kiszka 2010-05-28 5:13 ` Erik van der Kouwe 2010-05-28 7:33 ` Roedel, Joerg 0 siblings, 2 replies; 17+ messages in thread From: Jan Kiszka @ 2010-05-27 22:20 UTC (permalink / raw) To: Erik van der Kouwe; +Cc: Joerg Roedel, qemu-devel, Gleb Natapov [-- Attachment #1: Type: text/plain, Size: 2576 bytes --] Erik van der Kouwe wrote: > Hi, > >> Be warned: Though my experience is already more than a year old, the SVM >> emulation in QEMU is most probably not yet rock-stable. Always check >> suspicious behavior against real hardware and/or the spec. [ As real >> hardware is everywhere, nesting works with KVM+SVM and is much faster, >> motivation to improve QEMU in this area is unfortunately limited. ] > > Problem is: I'm compiling in Linux and testing in MINIX. Testing on the > real hardware would require a reboot everytime. Moreover, it might screw > up my system if I make bad mistakes (the MINIX filesystem is easily > corrupted). Use Linux+KVM as host OS, it can also run VMMs as guests (aka nested SVM). And you could even debug those guests just like when you would run QEMU in emulation mode. In contrast to SVM emulation, nesting is fairly stable AFAIK. And it is faster. > > That said, I do aim to eventually test the real hardware. Plenty of > virtualization capable hardware where I work, although unfortunately all > Intel. > >>> This issue is easy to work around by clearing the EVENTINJ field on each >>> #VMEXIT (and I have submitted a patch to that effect to the Palacios >>> people) and this approach is also found in KVM. >> >> /me does not find such clearing in KVM - what line(s) are you looking at? > > Linux source tree (2.6.31-ubuntu), arch/x86/kvm/svm.c, end of function > nested_svm_vmrun. Here event_inj and event_inj_err are copied from a > different VMCB, effectively clearing the value set by the CPU. Maybe > this isn't were I should have been looking though? Yep. This is the path taken for injecting events when switching from level-1 to level-2 guests, i.e. you are running some VMM inside KVM. > >>> The relevant code is in target-i386/op_helper.c. The "handle_even_inj" >>> function sets the EVENTINJ field (called event_inf in the QEMU code) and >>> the helper_vmexit function copies that field into EXITINTINFO >>> (exit_int_info in the QEMU code). I believe (but once again, am not >>> certain) that the SVM documentation only says that this information >>> should be stored in EXITINTINFO. >> >> Yes, this also looks suspicious. handle_even_inj should not push the >> real (level 1) event to be injected into event_inj[_err] but into >> exit_int_info[_err] or some temporary fields from which the exit info is >> then loaded later on. > > Yes, if this is indeed incorrect behaviour then this is what I would > expect a fix to be like. > > Thanks again, > Erik Jan [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 257 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* [Qemu-devel] Re: SVM emulation: EVENTINJ marked valid when a pagefault happens while issuing a software interrupt 2010-05-27 22:20 ` Jan Kiszka @ 2010-05-28 5:13 ` Erik van der Kouwe 2010-05-28 6:10 ` Jan Kiszka 2010-05-28 7:33 ` Roedel, Joerg 1 sibling, 1 reply; 17+ messages in thread From: Erik van der Kouwe @ 2010-05-28 5:13 UTC (permalink / raw) To: Jan Kiszka; +Cc: Joerg Roedel, qemu-devel, Gleb Natapov Hi, > Use Linux+KVM as host OS, it can also run VMMs as guests (aka nested > SVM). And you could even debug those guests just like when you would run > QEMU in emulation mode. In contrast to SVM emulation, nesting is fairly > stable AFAIK. And it is faster. In my experience, if I provide the -enable-kvm switch then the guest VMM never detects the presence of virtualization support. Does this only work on AMD hardware? Or do I need to supply some additional parameter to make it work? With kind regards, Erik ^ permalink raw reply [flat|nested] 17+ messages in thread
* [Qemu-devel] Re: SVM emulation: EVENTINJ marked valid when a pagefault happens while issuing a software interrupt 2010-05-28 5:13 ` Erik van der Kouwe @ 2010-05-28 6:10 ` Jan Kiszka 2010-05-28 7:35 ` Roedel, Joerg 0 siblings, 1 reply; 17+ messages in thread From: Jan Kiszka @ 2010-05-28 6:10 UTC (permalink / raw) To: Erik van der Kouwe; +Cc: Joerg Roedel, qemu-devel, Gleb Natapov [-- Attachment #1: Type: text/plain, Size: 669 bytes --] Erik van der Kouwe wrote: > Hi, > >> Use Linux+KVM as host OS, it can also run VMMs as guests (aka nested >> SVM). And you could even debug those guests just like when you would run >> QEMU in emulation mode. In contrast to SVM emulation, nesting is fairly >> stable AFAIK. And it is faster. > > In my experience, if I provide the -enable-kvm switch then the guest VMM > never detects the presence of virtualization support. Does this only > work on AMD hardware? Or do I need to supply some additional parameter > to make it work? Yes, forgot to mention: -enable-nesting, and you need qemu-kvm. This feature hasn't been merged upstream yet. Jan [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 257 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* [Qemu-devel] Re: SVM emulation: EVENTINJ marked valid when a pagefault happens while issuing a software interrupt 2010-05-28 6:10 ` Jan Kiszka @ 2010-05-28 7:35 ` Roedel, Joerg 2010-05-28 13:20 ` Jamie Lokier 0 siblings, 1 reply; 17+ messages in thread From: Roedel, Joerg @ 2010-05-28 7:35 UTC (permalink / raw) To: Jan Kiszka; +Cc: Gleb Natapov, qemu-devel@nongnu.org, Erik van der Kouwe On Fri, May 28, 2010 at 02:10:59AM -0400, Jan Kiszka wrote: > Erik van der Kouwe wrote: > > In my experience, if I provide the -enable-kvm switch then the guest VMM > > never detects the presence of virtualization support. Does this only > > work on AMD hardware? Or do I need to supply some additional parameter > > to make it work? > > Yes, forgot to mention: -enable-nesting, and you need qemu-kvm. This > feature hasn't been merged upstream yet. And the svm-emulation is only available on AMD hardware. Joerg ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] Re: SVM emulation: EVENTINJ marked valid when a pagefault happens while issuing a software interrupt 2010-05-28 7:35 ` Roedel, Joerg @ 2010-05-28 13:20 ` Jamie Lokier 2010-05-28 13:30 ` Erik van der Kouwe 2010-05-28 13:32 ` Roedel, Joerg 0 siblings, 2 replies; 17+ messages in thread From: Jamie Lokier @ 2010-05-28 13:20 UTC (permalink / raw) To: Roedel, Joerg Cc: Erik van der Kouwe, Jan Kiszka, qemu-devel@nongnu.org, Gleb Natapov Roedel, Joerg wrote: > On Fri, May 28, 2010 at 02:10:59AM -0400, Jan Kiszka wrote: > > Erik van der Kouwe wrote: > > > > In my experience, if I provide the -enable-kvm switch then the guest VMM > > > never detects the presence of virtualization support. Does this only > > > work on AMD hardware? Or do I need to supply some additional parameter > > > to make it work? > > > > Yes, forgot to mention: -enable-nesting, and you need qemu-kvm. This > > feature hasn't been merged upstream yet. > > And the svm-emulation is only available on AMD hardware. I assume you mean nested SVM emulation in a KVM guest is only available on real AMD hardware? Is this due to something inherent, or just a limitation of the KVM code not handling all the necessary traps in kvm-intel? Thanks, -- Jamie ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] Re: SVM emulation: EVENTINJ marked valid when a pagefault happens while issuing a software interrupt 2010-05-28 13:20 ` Jamie Lokier @ 2010-05-28 13:30 ` Erik van der Kouwe 2010-05-28 13:44 ` Roedel, Joerg 2010-05-28 13:32 ` Roedel, Joerg 1 sibling, 1 reply; 17+ messages in thread From: Erik van der Kouwe @ 2010-05-28 13:30 UTC (permalink / raw) To: Jamie Lokier Cc: Roedel, Joerg, Jan Kiszka, qemu-devel@nongnu.org, Gleb Natapov Hi, >> And the svm-emulation is only available on AMD hardware. > > I assume you mean nested SVM emulation in a KVM guest is only > available on real AMD hardware? > > Is this due to something inherent, or just a limitation of the KVM > code not handling all the necessary traps in kvm-intel? I don't think you could hardware-emulate a CPU from a different brand. AMD instructions would probably trap on Intel, but might also just do something completely different without a #VMEXIT. Same problem would exist vice versa. Would be nice to have nested VMX support though, given that Intel CPUs are so much more common than AMDs. I've been searching on the Dell website (in the Netherlands) for a laptop recently and I couldn't find a single AMD model. With kind regards, Erik ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] Re: SVM emulation: EVENTINJ marked valid when a pagefault happens while issuing a software interrupt 2010-05-28 13:30 ` Erik van der Kouwe @ 2010-05-28 13:44 ` Roedel, Joerg 2010-05-28 13:52 ` Erik van der Kouwe 0 siblings, 1 reply; 17+ messages in thread From: Roedel, Joerg @ 2010-05-28 13:44 UTC (permalink / raw) To: Erik van der Kouwe; +Cc: Jan Kiszka, qemu-devel@nongnu.org, Gleb Natapov On Fri, May 28, 2010 at 09:30:19AM -0400, Erik van der Kouwe wrote: > Would be nice to have nested VMX support though, given that Intel CPUs > are so much more common than AMDs. I've been searching on the Dell > website (in the Netherlands) for a laptop recently and I couldn't find a > single AMD model. That doesn't mean they are uncommon ;-) There are many vendors that offer notebooks with AMD processors. Joerg ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] Re: SVM emulation: EVENTINJ marked valid when a pagefault happens while issuing a software interrupt 2010-05-28 13:44 ` Roedel, Joerg @ 2010-05-28 13:52 ` Erik van der Kouwe 0 siblings, 0 replies; 17+ messages in thread From: Erik van der Kouwe @ 2010-05-28 13:52 UTC (permalink / raw) To: Roedel, Joerg; +Cc: Jan Kiszka, qemu-devel@nongnu.org, Gleb Natapov Hi, >> Would be nice to have nested VMX support though, given that Intel CPUs >> are so much more common than AMDs. I've been searching on the Dell >> website (in the Netherlands) for a laptop recently and I couldn't find a >> single AMD model. > > That doesn't mean they are uncommon ;-) There are many vendors that > offer notebooks with AMD processors. In theory that is true but in practice it means that my next laptop probably won't have an AMD chip in it (which is pity because I really like my current AMD Dell except that it doesn't have SVM). It surprised me though because I thought Dell was also involved in the anti-trust suits against Intel. With kind regards, Erik ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] Re: SVM emulation: EVENTINJ marked valid when a pagefault happens while issuing a software interrupt 2010-05-28 13:20 ` Jamie Lokier 2010-05-28 13:30 ` Erik van der Kouwe @ 2010-05-28 13:32 ` Roedel, Joerg 1 sibling, 0 replies; 17+ messages in thread From: Roedel, Joerg @ 2010-05-28 13:32 UTC (permalink / raw) To: Jamie Lokier Cc: Erik van der Kouwe, Jan Kiszka, qemu-devel@nongnu.org, Gleb Natapov On Fri, May 28, 2010 at 09:20:31AM -0400, Jamie Lokier wrote: > Roedel, Joerg wrote: > > On Fri, May 28, 2010 at 02:10:59AM -0400, Jan Kiszka wrote: > > > Erik van der Kouwe wrote: > > > > > > In my experience, if I provide the -enable-kvm switch then the guest VMM > > > > never detects the presence of virtualization support. Does this only > > > > work on AMD hardware? Or do I need to supply some additional parameter > > > > to make it work? > > > > > > Yes, forgot to mention: -enable-nesting, and you need qemu-kvm. This > > > feature hasn't been merged upstream yet. > > > > And the svm-emulation is only available on AMD hardware. > > I assume you mean nested SVM emulation in a KVM guest is only > available on real AMD hardware? Right. > Is this due to something inherent, or just a limitation of the KVM > code not handling all the necessary traps in kvm-intel? The SVM and VMX extensions are architecturally very different in many details. This makes it very hard to emulate VMX on SVM or vice verca. I am not even sure if it is possible at all to emulate one extension in an architectural complete way using the other extension. Joerg ^ permalink raw reply [flat|nested] 17+ messages in thread
* [Qemu-devel] Re: SVM emulation: EVENTINJ marked valid when a pagefault happens while issuing a software interrupt 2010-05-27 22:20 ` Jan Kiszka 2010-05-28 5:13 ` Erik van der Kouwe @ 2010-05-28 7:33 ` Roedel, Joerg 2010-05-28 7:47 ` Jan Kiszka 1 sibling, 1 reply; 17+ messages in thread From: Roedel, Joerg @ 2010-05-28 7:33 UTC (permalink / raw) To: Jan Kiszka; +Cc: Gleb Natapov, qemu-devel@nongnu.org, Erik van der Kouwe On Thu, May 27, 2010 at 06:20:00PM -0400, Jan Kiszka wrote: > Erik van der Kouwe wrote: > > Problem is: I'm compiling in Linux and testing in MINIX. Testing on the > > real hardware would require a reboot everytime. Moreover, it might screw > > up my system if I make bad mistakes (the MINIX filesystem is easily > > corrupted). > > Use Linux+KVM as host OS, it can also run VMMs as guests (aka nested > SVM). And you could even debug those guests just like when you would run > QEMU in emulation mode. In contrast to SVM emulation, nesting is fairly > stable AFAIK. And it is faster. At least it is more stable than any other nested-svm implementation I know of ;-) There are issues with kvmclock when you run kvm-on-kvm and you should not expect windows-based hypervisors to run without problems. Beside that, for running kvm-on-kvm and xen-on-kvm it is indeed fairly stable :-) > > Linux source tree (2.6.31-ubuntu), arch/x86/kvm/svm.c, end of function > > nested_svm_vmrun. Here event_inj and event_inj_err are copied from a > > different VMCB, effectively clearing the value set by the CPU. Maybe > > this isn't were I should have been looking though? The interesting part is in nested_svm_vmexit. There you have this piece of code: /* * If we emulate a VMRUN/#VMEXIT in the same host #vmexit cycle we have * to make sure that we do not lose injected events. So check event_inj * here and copy it to exit_int_info if it is valid. * Exit_int_info and event_inj can't be both valid because the case * below only happens on a VMRUN instruction intercept which has * no valid exit_int_info set. */ if (vmcb->control.event_inj & SVM_EVTINJ_VALID) { struct vmcb_control_area *nc = &nested_vmcb->control; nc->exit_int_info = vmcb->control.event_inj; nc->exit_int_info_err = vmcb->control.event_inj_err; } and a few lines later: nested_vmcb->control.event_inj = 0; nested_vmcb->control.event_inj_err = 0; ... which takes care of this situation. The vmcb.eventinf field is _defined_ to be zero on a #vmexit. Joerg ^ permalink raw reply [flat|nested] 17+ messages in thread
* [Qemu-devel] Re: SVM emulation: EVENTINJ marked valid when a pagefault happens while issuing a software interrupt 2010-05-28 7:33 ` Roedel, Joerg @ 2010-05-28 7:47 ` Jan Kiszka 0 siblings, 0 replies; 17+ messages in thread From: Jan Kiszka @ 2010-05-28 7:47 UTC (permalink / raw) To: Roedel, Joerg; +Cc: Gleb Natapov, qemu-devel@nongnu.org, Erik van der Kouwe [-- Attachment #1: Type: text/plain, Size: 3671 bytes --] Roedel, Joerg wrote: > On Thu, May 27, 2010 at 06:20:00PM -0400, Jan Kiszka wrote: >> Erik van der Kouwe wrote: >>> Problem is: I'm compiling in Linux and testing in MINIX. Testing on the >>> real hardware would require a reboot everytime. Moreover, it might screw >>> up my system if I make bad mistakes (the MINIX filesystem is easily >>> corrupted). >> Use Linux+KVM as host OS, it can also run VMMs as guests (aka nested >> SVM). And you could even debug those guests just like when you would run >> QEMU in emulation mode. In contrast to SVM emulation, nesting is fairly >> stable AFAIK. And it is faster. > > At least it is more stable than any other nested-svm implementation I > know of ;-) > There are issues with kvmclock when you run kvm-on-kvm and you should > not expect windows-based hypervisors to run without problems. Beside > that, for running kvm-on-kvm and xen-on-kvm it is indeed fairly > stable :-) > >>> Linux source tree (2.6.31-ubuntu), arch/x86/kvm/svm.c, end of function >>> nested_svm_vmrun. Here event_inj and event_inj_err are copied from a >>> different VMCB, effectively clearing the value set by the CPU. Maybe >>> this isn't were I should have been looking though? > > The interesting part is in nested_svm_vmexit. There you have this piece > of code: > > /* > * If we emulate a VMRUN/#VMEXIT in the same host #vmexit cycle we have > * to make sure that we do not lose injected events. So check event_inj > * here and copy it to exit_int_info if it is valid. > * Exit_int_info and event_inj can't be both valid because the case > * below only happens on a VMRUN instruction intercept which has > * no valid exit_int_info set. > */ > if (vmcb->control.event_inj & SVM_EVTINJ_VALID) { > struct vmcb_control_area *nc = &nested_vmcb->control; > > nc->exit_int_info = vmcb->control.event_inj; > nc->exit_int_info_err = vmcb->control.event_inj_err; > } > > and a few lines later: > > nested_vmcb->control.event_inj = 0; > nested_vmcb->control.event_inj_err = 0; > > ... which takes care of this situation. The vmcb.eventinf field is _defined_ to > be zero on a #vmexit. (Hmm, must have missed that line in the spec.) In that case something like diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c index dcbdfe7..caabdb4 100644 --- a/target-i386/op_helper.c +++ b/target-i386/op_helper.c @@ -1263,13 +1263,6 @@ void do_interrupt(int intno, int is_int, int error_code, #endif do_interrupt_real(intno, is_int, error_code, next_eip); } - -#if !defined(CONFIG_USER_ONLY) - if (env->hflags & HF_SVMI_MASK) { - uint32_t event_inj = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj)); - stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj), event_inj & ~SVM_EVTINJ_VALID); - } -#endif } /* This should come from sysemu.h - if we could include it here... */ @@ -5388,6 +5381,7 @@ void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1) ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj))); stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_int_info_err), ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj_err))); + stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj), 0); env->hflags2 &= ~HF2_GIF_MASK; /* FIXME: Resets the current ASID register to zero (host ASID). */ should resolve the QEMU issue, right? Jan [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 257 bytes --] ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] Re: SVM emulation: EVENTINJ marked valid when a pagefault happens while issuing a software interrupt 2010-05-27 18:53 ` [Qemu-devel] " Jan Kiszka 2010-05-27 19:49 ` Erik van der Kouwe @ 2010-05-28 7:24 ` Roedel, Joerg 2010-05-28 7:45 ` Erik van der Kouwe 1 sibling, 1 reply; 17+ messages in thread From: Roedel, Joerg @ 2010-05-28 7:24 UTC (permalink / raw) To: Jan Kiszka; +Cc: Gleb Natapov, qemu-devel@nongnu.org, Erik van der Kouwe On Thu, May 27, 2010 at 02:53:18PM -0400, Jan Kiszka wrote: > Based on the KVM code (which is known to work perfectly :) ), I think > you are right: SVM apparently clears the valid bit in EVENTINJ during > VMRUN once it starts processing the injection, not after it as it's the > case in current QEMU. But better ask the experts: Jörg, Gleb? SVM always clears the vmcb.eventinj on vmrun because every exception is injected right after vmrun finished and cpu is in guest mode. It can happen (for example if taking the exception causes a page fault) that the vmcb.eventinj field is copied to vmcb.exit_int_info. Also note that at this point there is a difference between hardware svm and the nested-svm implementation in kvm. The hardware always takes the exception first before checking for any other intercept condition. This basically means that exit_int_info is only set when the injected event could not be delivered due to other conditions in the guest (page fault, nested page-fault, ...). In nested-svm you can get a valid exit_int_info when an interrupt or nmi is pending too. In the software implementation these intercepts are taken before the event is delivered and you find the event in vmcb.exit_int_info. This is not forbidden in the svm architecture and I have not found a hypervisor that has a problem with this different behavior. I have a patch here which changes this in nested-svm, but it introduces more problems than it fixes. Joerg ^ permalink raw reply [flat|nested] 17+ messages in thread
* [Qemu-devel] Re: SVM emulation: EVENTINJ marked valid when a pagefault happens while issuing a software interrupt 2010-05-28 7:24 ` Roedel, Joerg @ 2010-05-28 7:45 ` Erik van der Kouwe 2010-05-28 9:12 ` Roedel, Joerg 0 siblings, 1 reply; 17+ messages in thread From: Erik van der Kouwe @ 2010-05-28 7:45 UTC (permalink / raw) To: Roedel, Joerg; +Cc: Jan Kiszka, qemu-devel@nongnu.org, Gleb Natapov Hi, Thankss for your answer. > SVM always clears the vmcb.eventinj on vmrun because every exception is > injected right after vmrun finished and cpu is in guest mode. It can > happen (for example if taking the exception causes a page fault) that > the vmcb.eventinj field is copied to vmcb.exit_int_info. Yes, this s what I have been experiencing. > In nested-svm you can get a valid exit_int_info when an interrupt or nmi > is pending too. In the software implementation these intercepts are > taken before the event is delivered and you find the event in > vmcb.exit_int_info. > This is not forbidden in the svm architecture and I have not found a > hypervisor that has a problem with this different behavior. I have a > patch here which changes this in nested-svm, but it introduces more > problems than it fixes. This is a ok, the problem is the event_inj field rather than the exit_int_info field. From what I've seen the SVM specification neither specifies that the CPU writes to this field nor does it explicitly forbid it. Given the unclarity of the specification it may safest to deal with this in the same way as the hardware does (although I don't know which way this is, it seems inuitively unlikely that the hardware would set event_inj to valid). With kind regards, Erik ^ permalink raw reply [flat|nested] 17+ messages in thread
* [Qemu-devel] Re: SVM emulation: EVENTINJ marked valid when a pagefault happens while issuing a software interrupt 2010-05-28 7:45 ` Erik van der Kouwe @ 2010-05-28 9:12 ` Roedel, Joerg 0 siblings, 0 replies; 17+ messages in thread From: Roedel, Joerg @ 2010-05-28 9:12 UTC (permalink / raw) To: Erik van der Kouwe; +Cc: Jan Kiszka, qemu-devel@nongnu.org, Gleb Natapov On Fri, May 28, 2010 at 03:45:09AM -0400, Erik van der Kouwe wrote: > This is a ok, the problem is the event_inj field rather than the > exit_int_info field. From what I've seen the SVM specification neither > specifies that the CPU writes to this field nor does it explicitly > forbid it. Given the unclarity of the specification it may safest to > deal with this in the same way as the hardware does (although I don't > know which way this is, it seems inuitively unlikely that the hardware > would set event_inj to valid). The "AMD64 Architecture Programmer's Manual Volume 2" states in section 15.19: When an event is injected by means of this mechanism, the VMRUN instruction causes the guest to unconditionally take the specified exception or interrupt before executing the first guest instruction. Which implicitly means that. But it could be documented more explicitly, thats right :) Joerg ^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2010-05-28 13:53 UTC | newest] Thread overview: 17+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-05-27 15:26 [Qemu-devel] SVM emulation: EVENTINJ marked valid when a pagefault happens while issuing a software interrupt Erik van der Kouwe 2010-05-27 18:53 ` [Qemu-devel] " Jan Kiszka 2010-05-27 19:49 ` Erik van der Kouwe 2010-05-27 22:20 ` Jan Kiszka 2010-05-28 5:13 ` Erik van der Kouwe 2010-05-28 6:10 ` Jan Kiszka 2010-05-28 7:35 ` Roedel, Joerg 2010-05-28 13:20 ` Jamie Lokier 2010-05-28 13:30 ` Erik van der Kouwe 2010-05-28 13:44 ` Roedel, Joerg 2010-05-28 13:52 ` Erik van der Kouwe 2010-05-28 13:32 ` Roedel, Joerg 2010-05-28 7:33 ` Roedel, Joerg 2010-05-28 7:47 ` Jan Kiszka 2010-05-28 7:24 ` Roedel, Joerg 2010-05-28 7:45 ` Erik van der Kouwe 2010-05-28 9:12 ` Roedel, Joerg
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).