Hello, is it safe to call hvm_inject_page_fault() (with PFEC_user_mode set) in vmx_vmenter_helper()? A related question: is it OK to check that we''re in user mode there with "!guest_kernel_mode(current, guest_cpu_user_regs())"? Thanks.
>>> On 06.11.13 at 10:31, Razvan Cojocaru <rzvncj@gmail.com> wrote: > is it safe to call hvm_inject_page_fault() (with PFEC_user_mode set) > in vmx_vmenter_helper()?At a first glance I would say "no" here, ...> A related question: is it OK to check that we''re in user mode there > with "!guest_kernel_mode(current, guest_cpu_user_regs())"?... and yes here, pointing out that in both cases this is likely wrong anyway (as being too late in the process, and as being bogus, since there shouldn''t be anything [other than perhaps logging for debugging purposes] at this point that could possibly cause you to need to do either of the two). Jan
Razvan Cojocaru
2013-Nov-06 10:41 UTC
Fwd: Vmx_vmenter_helper() and hvm_inject_page_fault()
Thank you for your answer.> ... and yes here, pointing out that in both cases this is likely > wrong anyway (as being too late in the process, and as being > bogus, since there shouldn''t be anything [other than perhaps > logging for debugging purposes] at this point that could possibly > cause you to need to do either of the two).OK, let''s assume that I need it for debugging purposes. Should the call, assuming that I check for usermode as explained above before calling hvm_inject_page_fault(ec | PFEC_user_mode, address), work as advertised? If not, what would be a better place to put this page fault injection assuming I''d like to trigger it at VMENTER time? Thanks again.
(re-adding xen-devel)>>> On 06.11.13 at 11:00, Razvan Cojocaru <rzvncj@gmail.com> wrote: >> ... and yes here, pointing out that in both cases this is likely >> wrong anyway (as being too late in the process, and as being >> bogus, since there shouldn''t be anything [other than perhaps >> logging for debugging purposes] at this point that could possibly >> cause you to need to do either of the two). > > OK, let''s assume that I need it for debugging purposes. Should the > call, assuming that I check for usermode as explained above before > calling hvm_inject_page_fault(ec | PFEC_user_mode, address), work as > advertised?I''m not sure, which is why I''d recommend against it. As said, I could see you use the usermode check for debugging purposes, but I can''t see what use injection of a #PF there would have.> If not, what would be a better place to put this page > fault injection assuming I''d like to trigger it at VMENTER time?You ought to do all this in the context of handling the corresponding VMEXIT. Jan
Razvan Cojocaru
2013-Nov-06 15:09 UTC
Re: Vmx_vmenter_helper() and hvm_inject_page_fault()
>> OK, let''s assume that I need it for debugging purposes. Should the >> call, assuming that I check for usermode as explained above before >> calling hvm_inject_page_fault(ec | PFEC_user_mode, address), work as >> advertised? > > I''m not sure, which is why I''d recommend against it. As said, I > could see you use the usermode check for debugging purposes, > but I can''t see what use injection of a #PF there would have. > >> If not, what would be a better place to put this page >> fault injection assuming I''d like to trigger it at VMENTER time? > > You ought to do all this in the context of handling the > corresponding VMEXIT.Well, the scenario would be this (bear with me here): there''d be a hypercall setting up pagefault injection in the HV. This hypercall would be called from dom0 userspace as part as handing a mem_event. Now, when the guest gets control again, it would inject a page fault based on the information previously sent to the HV. The only obvious place (to me) where this could happen correctly would be somewhere in the VMENTRY code - it might be too late by the time the next VMEXIT is reached. So I''m looking for a safe and robust way to do that. Thanks.
At 17:09 +0200 on 06 Nov (1383754147), Razvan Cojocaru wrote:> >> OK, let''s assume that I need it for debugging purposes. Should the > >> call, assuming that I check for usermode as explained above before > >> calling hvm_inject_page_fault(ec | PFEC_user_mode, address), work as > >> advertised? > > > > I''m not sure, which is why I''d recommend against it. As said, I > > could see you use the usermode check for debugging purposes, > > but I can''t see what use injection of a #PF there would have. > > > >> If not, what would be a better place to put this page > >> fault injection assuming I''d like to trigger it at VMENTER time? > > > > You ought to do all this in the context of handling the > > corresponding VMEXIT. > > Well, the scenario would be this (bear with me here): there''d be a > hypercall setting up pagefault injection in the HV. This hypercall > would be called from dom0 userspace as part as handing a mem_event. > Now, when the guest gets control again, it would inject a page fault > based on the information previously sent to the HV. The only obvious > place (to me) where this could happen correctly would be somewhere in > the VMENTRY code - it might be too late by the time the next VMEXIT is > reached. So I''m looking for a safe and robust way to do that.If you need to get back into the vmexit handler you could deliberately set the VMCS to an invalid state, and detect/fix up in the vmexit handler routine. Or, even easier, just leave the EPT state that caused the mem_event in the first place -- if the guest retries the instruction it will exit again with the same fault and you can have some state in the EPT fault handler to say ''next time, inject a pagefault''. Cheers, Tim.
Razvan Cojocaru
2013-Nov-07 11:43 UTC
Re: Vmx_vmenter_helper() and hvm_inject_page_fault()
Hello Tim, thank you for your answer!> Or, even easier, just leave the EPT state that caused the mem_event in > the first place -- if the guest retries the instruction it will exit > again with the same fault and you can have some state in the EPT fault > handler to say ''next time, inject a pagefault''.Good suggestion, I''m exploring it as we speak. But, I would also like to know what the dangers of doing this in the VMENTRY helper function are. Is it that the VMCS information is not yet fully there? Is guest_cpu_user_regs() not reliable at that point? What exactly could go wrong there? Thanks.
At 13:43 +0200 on 07 Nov (1383828227), Razvan Cojocaru wrote:> Hello Tim, thank you for your answer! > > > Or, even easier, just leave the EPT state that caused the mem_event in > > the first place -- if the guest retries the instruction it will exit > > again with the same fault and you can have some state in the EPT fault > > handler to say ''next time, inject a pagefault''. > > Good suggestion, I''m exploring it as we speak. > > But, I would also like to know what the dangers of doing this in the > VMENTRY helper function are. Is it that the VMCS information is not yet > fully there? Is guest_cpu_user_regs() not reliable at that point? What > exactly could go wrong there?vmx_vmenter_helper() is called last thing on the VMENTER code path, after all the other checks that happen before guest entry. Injecting a trap can change vcpu state in ways that invalidate those checks (e.g. by causing a nested-hvm guest to do an emulated VMEXIT, or by triggering an emulated triple fault). It''s also called with interrupts disabled, though I don''t see a specific example where that would cause trouble. Tim.