2016-07-11 05:11-0500, Suravee Suthikulpanit:
From: Suravee Suthikulpanit <Suravee.Suthikulpanit@xxxxxxx>
This patch adds AMD IOMMU guest virtual APIC log (GALOG) handler.
When IOMMU hardware receives an interrupt targeting a blocking vcpu,
it creates an entry in the GALOG, and generates an interrupt to notify
the AMD IOMMU driver.
At this point, the driver processes the log entry, and notify the SVM
driver via the registered iommu_ga_log_notifier function.
Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@xxxxxxx>
---
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
@@ -741,14 +741,101 @@ static void iommu_poll_ppr_log(struct amd_iommu *iommu)
+static void iommu_handle_ga_guest_nr_entry(struct amd_iommu *iommu,
+ u16 devid, u32 ga_tag)
+{
+ struct amd_ir_data *ir_data;
+ unsigned long flags;
+ int vec = 0;
+
+ if (!iommu_ga_log_notifier)
+ return;
+
+ spin_lock_irqsave(&iommu->ga_hash_lock, flags);
+ hash_for_each_possible(iommu->ga_hash, ir_data, hnode, ga_tag) {
+ struct irte_ga *entry = (struct irte_ga *)ir_data->entry;
if (ga_tag != entry->fields_vapic.ga_tag)
continue;
Multiple different ga_tags can map to the same bucket, so we need to
explicitly select the correct entry.
+
+ vec = entry->hi.fields.vector;
+ break;
+ }
+ spin_unlock_irqrestore(&iommu->ga_hash_lock, flags);
+
+ if (vec) {
+ pr_debug("AMD-Vi: %s: devid=%#x, ga_tag=%#x\n",
+ __func__, devid, ga_tag);
+
+ if (iommu_ga_log_notifier(GATAG_TO_AVICTAG(ga_tag),
+ GATAG_TO_VCPUID(ga_tag), vec) != 0)