[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1432699544-17444-4-git-send-email-feng.wu@intel.com>
Date: Wed, 27 May 2015 12:05:38 +0800
From: Feng Wu <feng.wu@...el.com>
To: joro@...tes.org, dwmw2@...radead.org
Cc: tglx@...utronix.de, jiang.liu@...ux.intel.com,
iommu@...ts.linux-foundation.org, linux-kernel@...r.kernel.org,
Feng Wu <feng.wu@...el.com>
Subject: [v8 3/9] iommu, x86: Implement irq_set_vcpu_affinity for intel_ir_chip
Implement irq_set_vcpu_affinity for intel_ir_chip.
Signed-off-by: Feng Wu <feng.wu@...el.com>
Reviewed-by: Jiang Liu <jiang.liu@...ux.intel.com>
Acked-by: David Woodhouse <David.Woodhouse@...el.com>
---
arch/x86/include/asm/irq_remapping.h | 5 ++++
drivers/iommu/intel_irq_remapping.c | 46 ++++++++++++++++++++++++++++++++++++
2 files changed, 51 insertions(+)
diff --git a/arch/x86/include/asm/irq_remapping.h b/arch/x86/include/asm/irq_remapping.h
index 0953723..202e040 100644
--- a/arch/x86/include/asm/irq_remapping.h
+++ b/arch/x86/include/asm/irq_remapping.h
@@ -57,6 +57,11 @@ static inline struct irq_domain *arch_get_ir_parent_domain(void)
return x86_vector_domain;
}
+struct vcpu_data {
+ u64 pi_desc_addr; /* Physical address of PI Descriptor */
+ u32 vector; /* Guest vector of the interrupt */
+};
+
#else /* CONFIG_IRQ_REMAP */
static inline void set_irq_remapping_broken(void) { }
diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c
index 8fad71c..1955b09 100644
--- a/drivers/iommu/intel_irq_remapping.c
+++ b/drivers/iommu/intel_irq_remapping.c
@@ -42,6 +42,7 @@ struct irq_2_iommu {
struct intel_ir_data {
struct irq_2_iommu irq_2_iommu;
struct irte irte_entry;
+ struct irte irte_pi_entry;
union {
struct msi_msg msi_entry;
};
@@ -1013,10 +1014,55 @@ static void intel_ir_compose_msi_msg(struct irq_data *irq_data,
*msg = ir_data->msi_entry;
}
+static int intel_ir_set_vcpu_affinity(struct irq_data *data, void *vcpu_info)
+{
+ struct intel_ir_data *ir_data = data->chip_data;
+ struct irte *irte_pi = &ir_data->irte_pi_entry;
+ struct vcpu_data *vcpu_pi_info;
+
+ /* stop posting interrupts, back to remapping mode */
+ if (!vcpu_info) {
+ modify_irte(&ir_data->irq_2_iommu, &ir_data->irte_entry);
+ } else {
+ vcpu_pi_info = (struct vcpu_data *)vcpu_info;
+
+ /*
+ * "ir_data->irte_entry" saves the remapped format of IRTE,
+ * which being a cached irte is still updated when setting
+ * the affinity even when we are in posted mode. So this make
+ * it possible to switch back to remapped mode from posted mode,
+ * we can just set "ir_data->irte_entry" to hardware for that
+ * purpose. Here we store the posted format of IRTE in another
+ * new member "ir_data->irte_pi_entry" to not corrupt
+ * "ir_data->irte_entry".
+ */
+ memcpy(irte_pi, &ir_data->irte_entry, sizeof(struct irte));
+
+ irte_pi->p_urgent = 0;
+ irte_pi->p_vector = vcpu_pi_info->vector;
+ irte_pi->pda_l = (vcpu_pi_info->pi_desc_addr >>
+ (32 - PDA_LOW_BIT)) & ~(-1UL << PDA_LOW_BIT);
+ irte_pi->pda_h = (vcpu_pi_info->pi_desc_addr >> 32) &
+ ~(-1UL << PDA_HIGH_BIT);
+
+ irte_pi->p_res0 = 0;
+ irte_pi->p_res1 = 0;
+ irte_pi->p_res2 = 0;
+ irte_pi->p_res3 = 0;
+
+ irte_pi->p_pst = 1;
+
+ modify_irte(&ir_data->irq_2_iommu, irte_pi);
+ }
+
+ return 0;
+}
+
static struct irq_chip intel_ir_chip = {
.irq_ack = ir_ack_apic_edge,
.irq_set_affinity = intel_ir_set_affinity,
.irq_compose_msi_msg = intel_ir_compose_msi_msg,
+ .irq_set_vcpu_affinity = intel_ir_set_vcpu_affinity,
};
static void intel_irq_remapping_prepare_irte(struct intel_ir_data *data,
--
2.1.0
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists