All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>,
	rkrcmar@redhat.com, joro@8bytes.org, bp@alien8.de,
	gleb@kernel.org, alex.williamson@redhat.com
Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
	wei@redhat.com, sherry.hurwitz@amd.com
Subject: Re: [PART1 RFC v3 07/12] svm: Add interrupt injection via AVIC
Date: Fri, 18 Mar 2016 11:22:54 +0100	[thread overview]
Message-ID: <56EBD6FE.2050807@redhat.com> (raw)
In-Reply-To: <1458281388-14452-8-git-send-email-Suravee.Suthikulpanit@amd.com>



On 18/03/2016 07:09, Suravee Suthikulpanit wrote:
> This patch introduces a new mechanism to inject interrupt using AVIC.
> Since VINTR is not supported when enable AVIC, we need to inject
> interrupt via APIC backing page instead.
> 
> This patch also adds support for AVIC doorbell, which is used by
> KVM to signal a running vcpu to check IRR for injected interrupts.
> 
> Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>

Looks good, but I think it breaks nested virtualization.  See below.

> ---
>  arch/x86/kvm/svm.c | 46 ++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 44 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
> index 621c948..8e31ad3 100644
> --- a/arch/x86/kvm/svm.c
> +++ b/arch/x86/kvm/svm.c
> @@ -71,6 +71,8 @@ MODULE_DEVICE_TABLE(x86cpu, svm_cpu_id);
>  #define SVM_FEATURE_DECODE_ASSIST  (1 <<  7)
>  #define SVM_FEATURE_PAUSE_FILTER   (1 << 10)
>  
> +#define SVM_AVIC_DOORBELL	0xc001011b
> +
>  #define NESTED_EXIT_HOST	0	/* Exit handled on host level */
>  #define NESTED_EXIT_DONE	1	/* Exit caused nested vmexit  */
>  #define NESTED_EXIT_CONTINUE	2	/* Further checks needed      */
> @@ -217,6 +219,8 @@ static bool npt_enabled = true;
>  static bool npt_enabled;
>  #endif
>  
> +static struct kvm_x86_ops svm_x86_ops;
> +
>  /* allow nested paging (virtualized MMU) for all guests */
>  static int npt = true;
>  module_param(npt, int, S_IRUGO);
> @@ -291,6 +295,18 @@ static inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu)
>  	return container_of(vcpu, struct vcpu_svm, vcpu);
>  }
>  
> +static inline bool avic_vcpu_is_running(struct kvm_vcpu *vcpu)
> +{
> +	struct vcpu_svm *svm = to_svm(vcpu);
> +	u64 *entry;
> +
> +	entry = svm->avic_phy_apic_id_cache;
> +	if (!entry)
> +		return false;
> +
> +	return (READ_ONCE(*entry) & AVIC_PHY_APIC_ID__IS_RUN_MSK);

AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK

> +}
> +
>  static void recalc_intercepts(struct vcpu_svm *svm)
>  {
>  	struct vmcb_control_area *c, *h;
> @@ -964,6 +980,8 @@ static __init int svm_hardware_setup(void)
>  
>  	if (avic) {
>  		printk(KERN_INFO "kvm: AVIC enabled\n");
> +	} else {
> +		svm_x86_ops.deliver_posted_interrupt = NULL;
>  	}
>  
>  	return 0;
> @@ -2877,8 +2895,10 @@ static int clgi_interception(struct vcpu_svm *svm)
>  	disable_gif(svm);
>  
>  	/* After a CLGI no interrupts should come */
> -	svm_clear_vintr(svm);
> -	svm->vmcb->control.int_ctl &= ~V_IRQ_MASK;
> +	if (!svm_vcpu_avic_enabled(svm)) {
> +		svm_clear_vintr(svm);
> +		svm->vmcb->control.int_ctl &= ~V_IRQ_MASK;
> +	}

This is for nested virtualization.  Unless you support nested AVIC, the
L2 guest should run without AVIC (i.e. IsRunning should be false) and
use the old VINTR mechanism.

>  	mark_dirty(svm->vmcb, VMCB_INTR);
>  
> @@ -3453,6 +3473,9 @@ static int msr_interception(struct vcpu_svm *svm)
>  
>  static int interrupt_window_interception(struct vcpu_svm *svm)
>  {
> +	if (svm_vcpu_avic_enabled(svm))
> +		BUG();

Please WARN and return, but I suspect this may also need some changes
for nested virtualization.

>  	kvm_make_request(KVM_REQ_EVENT, &svm->vcpu);
>  	svm_clear_vintr(svm);
>  	svm->vmcb->control.int_ctl &= ~V_IRQ_MASK;
> @@ -3767,6 +3790,7 @@ static inline void svm_inject_irq(struct vcpu_svm *svm, int irq)
>  {
>  	struct vmcb_control_area *control;
>  
> +	/* The following fields are ignored when AVIC is enabled */
>  	control = &svm->vmcb->control;
>  	control->int_vector = irq;
>  	control->int_ctl &= ~V_INTR_PRIO_MASK;
> @@ -3844,6 +3868,20 @@ static void svm_sync_pir_to_irr(struct kvm_vcpu *vcpu)
>  	return;
>  }
>  
> +static void svm_deliver_avic_intr(struct kvm_vcpu *vcpu, int vec)
> +{
> +	struct vcpu_svm *svm = to_svm(vcpu);
> +
> +	kvm_lapic_set_vector(vec, svm->vcpu.arch.apic->regs + APIC_IRR);
> +	smp_mb__after_atomic();
> +
> +	if (avic_vcpu_is_running(vcpu))
> +		wrmsrl(SVM_AVIC_DOORBELL,
> +		       __default_cpu_present_to_apicid(vcpu->cpu));
> +	else
> +		kvm_vcpu_wake_up(vcpu);
> +}
> +
>  static int svm_nmi_allowed(struct kvm_vcpu *vcpu)
>  {
>  	struct vcpu_svm *svm = to_svm(vcpu);
> @@ -3904,6 +3942,9 @@ static void enable_irq_window(struct kvm_vcpu *vcpu)
>  	 * get that intercept, this function will be called again though and
>  	 * we'll get the vintr intercept.
>  	 */
> +	if (svm_vcpu_avic_enabled(svm))
> +		return;

Same here.

>  	if (gif_set(svm) && nested_svm_intr(svm)) {
>  		svm_set_vintr(svm);
>  		svm_inject_irq(svm, 0x0);
> @@ -4638,6 +4679,7 @@ static struct kvm_x86_ops svm_x86_ops = {
>  	.sched_in = svm_sched_in,
>  
>  	.pmu_ops = &amd_pmu_ops,
> +	.deliver_posted_interrupt = svm_deliver_avic_intr,
>  };
>  
>  static int __init svm_init(void)
> 

  reply	other threads:[~2016-03-18 10:23 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-18  6:09 [PART1 RFC v3 00/12] KVM: x86: Introduce SVM AVIC support Suravee Suthikulpanit
2016-03-18  6:09 ` [PART1 RFC v3 01/12] KVM: x86: Misc LAPIC changes to expose helper functions Suravee Suthikulpanit
2016-03-18 11:16   ` Paolo Bonzini
2016-03-18  6:09 ` [PART1 RFC v3 02/12] KVM: x86: Introducing kvm_x86_ops VM init/uninit hooks Suravee Suthikulpanit
2016-03-18 10:11   ` Paolo Bonzini
2016-03-29  5:27     ` Suravee Suthikulpanit
2016-03-29 10:21       ` Paolo Bonzini
2016-03-29 11:47         ` Suravee Suthikulpanit
2016-03-30 10:00           ` Suravee Suthikulpanit
2016-03-30 12:07             ` Paolo Bonzini
2016-03-30 12:18               ` Suravee Suthikulpanit
2016-03-18  6:09 ` [PART1 RFC v3 03/12] KVM: x86: Introducing kvm_x86_ops VCPU blocking/unblocking hooks Suravee Suthikulpanit
2016-03-18 10:11   ` Paolo Bonzini
2016-03-18  6:09 ` [PART1 RFC v3 04/12] KVM: split kvm_vcpu_wake_up from kvm_vcpu_kick Suravee Suthikulpanit
2016-03-18 10:11   ` Paolo Bonzini
2016-03-18  6:09 ` [PART1 RFC v3 05/12] svm: Introduce new AVIC VMCB registers Suravee Suthikulpanit
2016-03-18 10:11   ` Paolo Bonzini
2016-03-18  6:09 ` [PART1 RFC v3 06/12] KVM: x86: Detect and Initialize AVIC support Suravee Suthikulpanit
2016-03-18 11:21   ` Paolo Bonzini
2016-03-18  6:09 ` [PART1 RFC v3 07/12] svm: Add interrupt injection via AVIC Suravee Suthikulpanit
2016-03-18 10:22   ` Paolo Bonzini [this message]
2016-04-05 13:26     ` Suravee Suthikulpanit
2016-04-05 15:56       ` Suravee Suthikulpanit
2016-03-18  6:09 ` [PART1 RFC v3 08/12] KVM: x86: Add trace events for AVIC Suravee Suthikulpanit
2016-03-18 10:24   ` Paolo Bonzini
2016-03-28 11:27     ` Suravee Suthikulpanit
2016-03-18  6:09 ` [PART1 RFC v3 09/12] svm: Add VMEXIT handlers " Suravee Suthikulpanit
2016-03-18 11:11   ` Paolo Bonzini
2016-03-18  6:09 ` [PART1 RFC v3 10/12] svm: Do not expose x2APIC when enable AVIC Suravee Suthikulpanit
2016-03-18 20:59   ` Radim Krčmář
2016-03-31  4:15     ` Suravee Suthikulpanit
2016-03-31 11:23       ` Paolo Bonzini
2016-04-05 10:14         ` Suravee Suthikulpanit
2016-03-18  6:09 ` [PART1 RFC v3 11/12] svm: Do not intercept CR8 " Suravee Suthikulpanit
2016-03-18 21:10   ` Radim Krčmář
2016-03-30 12:15     ` Suravee Suthikulpanit
2016-03-18  6:09 ` [PART1 RFC v3 12/12] svm: Manage vcpu load/unload " Suravee Suthikulpanit
2016-03-18 21:44   ` Radim Krčmář
2016-03-31  8:52     ` Suravee Suthikulpanit
2016-03-31 14:19       ` Radim Krčmář
2016-04-05 10:07         ` Suravee Suthikulpanit
2016-04-05 14:56           ` Radim Krčmář
2016-04-06  3:40             ` Suravee Suthikulpanit
2016-04-06 12:36               ` Radim Krčmář

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=56EBD6FE.2050807@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=Suravee.Suthikulpanit@amd.com \
    --cc=alex.williamson@redhat.com \
    --cc=bp@alien8.de \
    --cc=gleb@kernel.org \
    --cc=joro@8bytes.org \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rkrcmar@redhat.com \
    --cc=sherry.hurwitz@amd.com \
    --cc=wei@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.