Hi Gleb,

Thanks for your reply.

2009/7/26 Gleb Natapov <g...@redhat.com>:
> On Sat, Jul 25, 2009 at 10:46:39PM +0200, Jiaqing Du wrote:
>> Hi list,
>>
>> I'm trying to extend OProfile to support guest profiling. One step of
>> my work is to push an NMI to the guest(s) when a performance counter
>> overflows. Please correct me if the following is not correct:
>>
>> counter overflow --> NMI to host --> VM exit --> "int $2" to handle
>> NMI on host --> ...   --> VM entry --> NMI to guest
>>
> Correct except the last step (--> NMI to guest). Host nmi is not
> propagated to guests.

Yes. I need to add some code to propagate host NMI to guests.
>
>> On the path between VM-exit and VM-entry, I want to push an NMI to the
>> guest. I tried to put the following code on the path, but never
>> succeeded. Various wired things happened, such as KVM hangs, guest
>> kernel oops, and host hangs. I tried both code with Linux 2.6.30 and
>> version 88.
>>
>> if (vmx_nmi_allowed())  { vmx_inject_nmi(); }
>>
>> Any suggestions? Where is the right place to push an NMI and what are
>> the necessary checks?
> Call kvm_inject_nmi(vcpu). And don't forget to vcpu_load(vcpu) before
> doing it. See kvm_vcpu_ioctl_nmi().

Based on the code with Linux 2.6.30, what kvm_inject_nmi(vcpu) does is
just set vcpu->arch.nmi_pending to 1. kvm_vcpu_ioctl_nmi() puts
vcpu_load() before the setting and vcpu_put() after it.

I need to push host NMI to guests between a VM-exit and a VM-entry
after that. The VM-exit is due to an NMI caused by performance counter
overflow. The following code with vcpu_enter_guest(), which is
surrounded by a vcpu_load() and vcpu_put(), checks this
vcpu->arch.nmi_pending and other related flags to decide whether an
NMI should be pushed to guests.

        if (vcpu->arch.exception.pending)
                __queue_exception(vcpu);
        else if (irqchip_in_kernel(vcpu->kvm))
                kvm_x86_ops->inject_pending_irq(vcpu);
        else
                kvm_x86_ops->inject_pending_vectors(vcpu, kvm_run);

What I did is given below:

3097 static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
3098 {
               ... ...

3156         if (kvm_vm_exit_on_cnt_overflow) {
3157                 vcpu->arch.nmi_pending = 1;
3158         }
3159
3160         if (vcpu->arch.exception.pending)
3161                 __queue_exception(vcpu);
3162         else if (irqchip_in_kernel(vcpu->kvm))
3163                 kvm_x86_ops->inject_pending_irq(vcpu);
3164         else
3165                 kvm_x86_ops->inject_pending_vectors(vcpu, kvm_run);

              ... ....
3236 }

In vcpu_enter_guest(), before this part of code is reached,
vcpu->arch.nmi_pending is set to 1 if the VM-exit is due to
performance counter overflow. Still, no NMIs are seen by the guests. I
also tried to put this "vcpu->arch.nmi_pending = 1;" somewhere else on
the path between a VM-exit and VM-entry, it does not seem to work
neither. Only vmx_inject_nmi() manages to push NMIs to guests, but
without right sanity checks, it causes various wired host and guest
behaviors.

To inject NMIs on the path between a VM-exit and VM-entry, what's to try next?

>
> --
>                        Gleb.
>

Thanks,
Jiaqing
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to