Re: [PATCH] KVM: nVMX: Wake blocked vCPU in guest-mode if pending interrupt in virtual APICv

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Sep 4, 2018 at 12:57 AM Liran Alon <liran.alon@xxxxxxxxxx> wrote:
>
> In case L1 do not intercept L2 HLT or enter L2 in HLT activity-state,
> it is possible for a vCPU to be blocked while it is in guest-mode.
>
> According to Intel SDM 26.6.5 Interrupt-Window Exiting and
> Virtual-Interrupt Delivery: "These events wake the logical processor
> if it just entered the HLT state because of a VM entry".
> Therefore, if L1 enters L2 in HLT activity-state and L2 has a pending
> deliverable interrupt in vmcs12->guest_intr_status.RVI, then the vCPU
> should be waken from the HLT state and injected with the interrupt.
>
> In addition, if while the vCPU is blocked (while it is in guest-mode),
> it receives a nested posted-interrupt, then the vCPU should also be
> waken and injected with the posted interrupt.
>
> To handle these cases, this patch enhances kvm_vcpu_has_events() to also
> check if there is a pending interrupt in L2 virtual APICv provided by
> L1. That is, it evaluates if there is a pending virtual interrupt for L2
> by checking RVI[7:4] > VPPR[7:4] as specified in Intel SDM 29.2.1
> Evaluation of Pending Interrupts.
>
> Note that this also handles the case of nested posted-interrupt by the
> fact RVI is updated in vmx_complete_nested_posted_interrupt() which is
> called from kvm_vcpu_check_block() -> kvm_arch_vcpu_runnable() ->
> kvm_vcpu_running() -> vmx_check_nested_events() ->
> vmx_complete_nested_posted_interrupt().
>
> Reviewed-by: Nikita Leshenko <nikita.leshchenko@xxxxxxxxxx>
> Reviewed-by: Darren Kenny <darren.kenny@xxxxxxxxxx>
> Signed-off-by: Liran Alon <liran.alon@xxxxxxxxxx>
> ---
>  arch/x86/include/asm/kvm_host.h |  1 +
>  arch/x86/kvm/vmx.c              | 22 ++++++++++++++++++++++
>  arch/x86/kvm/x86.c              | 10 +++++++++-
>  3 files changed, 32 insertions(+), 1 deletion(-)
>
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index 00ddb0c9e612..456a3f9aa544 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -1022,6 +1022,7 @@ struct kvm_x86_ops {
>         void (*refresh_apicv_exec_ctrl)(struct kvm_vcpu *vcpu);
>         void (*hwapic_irr_update)(struct kvm_vcpu *vcpu, int max_irr);
>         void (*hwapic_isr_update)(struct kvm_vcpu *vcpu, int isr);
> +       bool (*guest_apic_has_interrupt)(struct kvm_vcpu *vcpu);
>         void (*load_eoi_exitmap)(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap);
>         void (*set_virtual_apic_mode)(struct kvm_vcpu *vcpu);
>         void (*set_apic_access_page_addr)(struct kvm_vcpu *vcpu, hpa_t hpa);
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index d687c20e7634..bed75118111c 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -6183,6 +6183,27 @@ static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
>         nested_mark_vmcs12_pages_dirty(vcpu);
>  }
>
> +static bool vmx_guest_apic_has_interrupt(struct kvm_vcpu *vcpu)
> +{
> +       struct vcpu_vmx *vmx = to_vmx(vcpu);
> +       void *vapic_page;
> +       u32 vppr;
> +       int rvi;
> +
> +       if (WARN_ON_ONCE(!is_guest_mode(vcpu)) ||
> +               !nested_cpu_has_vid(get_vmcs12(vcpu)) ||
> +               WARN_ON_ONCE(!vmx->nested.virtual_apic_page))
> +               return false;

Here I am, late to the party as usual...

Immediately after a live migration, is it possible that this code
might be called while KVM_REQ_GET_VMCS12_PAGES is still pending, and
vmx->nested.virtual_apic_page is NULL?



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux