linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Radim Krčmář" <rkrcmar@redhat.com>
To: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
Cc: joro@8bytes.org, pbonzini@redhat.com, alex.williamson@redhat.com,
	kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
	sherry.hurwitz@amd.com
Subject: Re: [PART2 PATCH v6 12/12] svm: Implements update_pi_irte hook to setup posted interrupt
Date: Fri, 19 Aug 2016 16:49:08 +0200	[thread overview]
Message-ID: <20160819144907.GB1885@potion> (raw)
In-Reply-To: <1471549364-6672-13-git-send-email-Suravee.Suthikulpanit@amd.com>

2016-08-18 14:42-0500, Suravee Suthikulpanit:
> This patch implements update_pi_irte function hook to allow SVM
> communicate to IOMMU driver regarding how to set up IRTE for handling
> posted interrupt.
> 
> In case AVIC is enabled, during vcpu_load/unload, SVM needs to update
> IOMMU IRTE with appropriate host physical APIC ID. Also, when
> vcpu_blocking/unblocking, SVM needs to update the is-running bit in
> the IOMMU IRTE. Both are achieved via calling amd_iommu_update_ga().
> 
> However, if GA mode is not enabled for the pass-through device,
> IOMMU driver will simply just return when calling amd_iommu_update_ga.
> 
> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
> ---
> diff --git a/include/linux/amd-iommu.h b/include/linux/amd-iommu.h
> @@ -34,6 +34,7 @@ struct amd_ir_data {
>  	struct msi_msg msi_entry;
>  	void *entry;    /* Pointer to union irte or struct irte_ga */
>  	void *ref;      /* Pointer to the actual irte */
> +	struct list_head node;	/* Used by SVM for per-vcpu ir_list */

Putting a list_head here requires all users of amd-iommu to cooperate,
which is dangerous, but it allows simpler SVM code.  The alternative is
to force wrappers in SVM, which would also allow IOMMU to keep struct
amd_ir_data as incomplete in public headers.

 struct struct amd_ir_data_wrapper {
 	struct list_head node;
 	struct amd_ir_data *ir_data;
 }

(The rant continues below.)

> +static int svm_update_pi_irte(struct kvm *kvm, unsigned int host_irq,
> +			      uint32_t guest_irq, bool set)
> +{
> +	struct kvm_kernel_irq_routing_entry *e;
> +	struct kvm_irq_routing_table *irq_rt;
[...]
> +	hlist_for_each_entry(e, &irq_rt->map[guest_irq], link) {
> +		struct kvm_lapic_irq irq;
> +		struct vcpu_data vcpu_info;
[...]
> +		kvm_set_msi_irq(e, &irq);
> +		if (kvm_intr_is_single_vcpu(kvm, &irq, &vcpu)) {
> +			svm = to_svm(vcpu);
> +			vcpu_info.pi_desc_addr = page_to_phys(svm->avic_backing_page);
> +			vcpu_info.vector = irq.vector;
[...]
> +			struct amd_iommu_pi_data pi;
> +
> +			/* Try to enable guest_mode in IRTE */
> +			pi.ga_tag = AVIC_GATAG(kvm->arch.avic_vm_id,
> +						     vcpu->vcpu_id);
> +			pi.is_guest_mode = true;
> +			pi.vcpu_data = &vcpu_info;
> +			ret = irq_set_vcpu_affinity(host_irq, &pi);
> +			if (!ret && pi.is_guest_mode)
> +				svm_ir_list_add(svm, pi.ir_data);

I missed a bug here the last time:

If ir_data is already inside some VCPU list and the VCPU changes, then
we don't remove ir_data from the previous list and just add it to a new
one.  This was not as bad when we only had wrappers (only resulted in
duplication), but now we break the removed list ...

The problem with wrappers is that we don't know what list we should
remove the "struct amd_ir_data" from;  we would need to add another
tracking structure or go through all VCPUs.

Having "struct list_head" in "struct amd_ir_data" would allow us to know
the current list and remove it from there:
One "struct amd_ir_data" should never be used by more than one caller of
amd_iommu_update_ga(), because they would have to be cooperating anyway,
which would mean a single mediator, so we can add a "struct list_head"
into "struct amd_ir_data".

  Minor design note:
  To make the usage of "struct amd_ir_data" safer, we could pass "struct
  list_head" into irq_set_vcpu_affinity(), instead of returning "struct
  amd_ir_data *".

  irq_set_vcpu_affinity() would add "struct amd_ir_data" to the list only
  if ir_data was not already in some list and report whether the list
  was modified.

I think that adding "struct list_head" into "struct amd_ir_data" is
nicer than having wrappers.

Joerg, Paolo, what do you think?

Thanks.

> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
> @@ -4366,6 +4399,177 @@ static void svm_deliver_avic_intr(struct kvm_vcpu *vcpu, int vec)
> +static int svm_ir_list_add(struct vcpu_svm *svm, struct amd_ir_data *ir)
> +{
> +	spin_lock_irqsave(&svm->ir_list_lock, flags);
> +	list_for_each_entry(cur, &svm->ir_list, node) {
> +		if (cur != ir)
> +			continue;
> +		found = true;
> +		break;
> +	}

If we're using ir->node, then this can ask !list_empty(ir->node),
because we should never add it to a new list otherwise.

> +	spin_unlock_irqrestore(&svm->ir_list_lock, flags);
> +
> +	if (found)
> +		return 0;
> +
> +	spin_lock_irqsave(&svm->ir_list_lock, flags);
> +	list_add(&ir->node, &svm->ir_list);
> +	spin_unlock_irqrestore(&svm->ir_list_lock, flags);
> +	return 0;
> +}

  reply	other threads:[~2016-08-19 14:49 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-08-18 19:42 [PART2 PATCH v6 00/12] iommu/AMD: Introduce IOMMU AVIC support Suravee Suthikulpanit
2016-08-18 19:42 ` [PART2 PATCH v6 01/12] iommu/amd: Detect and enable guest vAPIC support Suravee Suthikulpanit
2016-08-18 19:42 ` [PART2 PATCH v6 02/12] iommu/amd: Move and introduce new IRTE-related unions and structures Suravee Suthikulpanit
2016-08-18 19:42 ` [PART2 PATCH v6 03/12] iommu/amd: Introduce interrupt remapping ops structure Suravee Suthikulpanit
2016-08-18 19:42 ` [PART2 PATCH v6 04/12] iommu/amd: Add support for multiple IRTE formats Suravee Suthikulpanit
2016-08-18 19:42 ` [PART2 PATCH v6 05/12] iommu/amd: Detect and initialize guest vAPIC log Suravee Suthikulpanit
2016-08-18 19:42 ` [PART2 PATCH v6 06/12] iommu/amd: Adding GALOG interrupt handler Suravee Suthikulpanit
2016-08-18 19:42 ` [PART2 PATCH v6 07/12] iommu/amd: Introduce amd_iommu_update_ga() Suravee Suthikulpanit
2016-08-22  5:50   ` kbuild test robot
2016-08-18 19:42 ` [PART2 PATCH v6 08/12] iommu/amd: Implements irq_set_vcpu_affinity() hook to setup vapic mode for pass-through devices Suravee Suthikulpanit
2016-08-18 19:42 ` [PART2 PATCH v6 09/12] iommu/amd: Enable vAPIC interrupt remapping mode by default Suravee Suthikulpanit
2016-08-18 19:42 ` [PART2 PATCH v6 10/12] svm: Introduces AVIC per-VM ID Suravee Suthikulpanit
2016-08-19 13:26   ` Radim Krčmář
2016-08-18 19:42 ` [PART2 PATCH v6 11/12] svm: Introduce AMD IOMMU avic_ga_log_notifier Suravee Suthikulpanit
2016-08-18 19:42 ` [PART2 PATCH v6 12/12] svm: Implements update_pi_irte hook to setup posted interrupt Suravee Suthikulpanit
2016-08-19 14:49   ` Radim Krčmář [this message]
2016-08-19 15:04     ` Radim Krčmář
2016-08-22  9:19     ` Suravee Suthikulpanit
2016-08-22 10:09       ` Suravee Suthikulpanit
2016-08-22 15:16         ` Radim Krčmář
2016-08-23 10:51   ` kbuild test robot

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=20160819144907.GB1885@potion \
    --to=rkrcmar@redhat.com \
    --cc=Suravee.Suthikulpanit@amd.com \
    --cc=alex.williamson@redhat.com \
    --cc=joro@8bytes.org \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=sherry.hurwitz@amd.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 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).