2016-04-08 07:49-0500, Suravee Suthikulpanit:
> From: Suravee Suthikulpanit <suravee.suthikulpa...@amd.com>
> 
> This patch introduces a new IOMMU interface, amd_iommu_update_ga(),
> which allows KVM (SVM) to update existing posted interrupt IOMMU IRTE when
> load/unload vcpu.
> 
> Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpa...@amd.com>
> ---
> diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
> @@ -4330,4 +4330,74 @@ int amd_iommu_create_irq_domain(struct amd_iommu 
> *iommu)
> +int amd_iommu_update_ga(u32 vcpu_id, u32 cpu, u32 ga_tag,

It'd be nicer to generate the tag on SVM side and pass it whole -- IOMMU
doesn't have to care how hypervisors use the tag.

> +                     u64 base, bool is_run)
> +{
> +     unsigned long flags;
> +     struct amd_iommu *iommu;
> +
> +     if (amd_iommu_guest_ir < AMD_IOMMU_GUEST_IR_GA)
> +             return 0;
> +
> +     for_each_iommu(iommu) {
> +             struct amd_ir_data *ir_data;
> +
> +             spin_lock_irqsave(&iommu->ga_hash_lock, flags);
> +
> +             hash_for_each_possible(iommu->ga_hash, ir_data, hnode,
> +                                    AMD_IOMMU_GATAG(ga_tag, vcpu_id)) {

All tags can map into the same bucket.  Code below doesn't check that
the ir_data belongs to the tag and will modify unrelated IRTEs.

Have you considered a per-VCPU list of IRTEs on the SVM side?

> +                     struct iommu_dev_data *dev_data;
> +                     if (!ir_data)

(ir_data can't be NULL.)

> +                             break;
> +
> +                     dev_data = search_dev_data(ir_data->irq_2_irte.devid);
> +
> +                     if (!dev_data || !dev_data->guest_mode)
> +                             continue;

(guest_mode can be also read from the irte.)

> +                     set_irte_ga(iommu, ir_data->irq_2_irte.devid,
> +                                 base, cpu, is_run);

set_irte_ga() is pretty expensive -- do we need to invalidate the irt
when changing cpu and is_run?

2.2.5.2 Interrupt Virtualization Tables with Guest Virtual APIC Enabled,
point 9, bullet 5 says that IRTE is read from memory before considering
IsRun, GATag and Destination, which makes me think that avoiding races
can be faster in the common case.

Reply via email to