-------- Original Message --------
If irq table exists in old kernel create a new one and copy the content
of old irq table to the newly created.
Signed-off-by: Baoquan He <[email protected]>
---
drivers/iommu/amd_iommu.c | 2 +-
drivers/iommu/amd_iommu_init.c | 43 +++++++++++++++++++++++++++++++++++++++++
drivers/iommu/amd_iommu_proto.h | 1 +
3 files changed, 45 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index aeae07a..63f4c6b 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -3628,7 +3628,7 @@ struct amd_ir_data {
static struct irq_chip amd_ir_chip;
-static void set_dte_irq_entry(u16 devid, struct irq_remap_table *table)
+void set_dte_irq_entry(u16 devid, struct irq_remap_table *table)
{
u64 dte;
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 91659d8..450adad 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -660,6 +660,49 @@ static int get_dev_entry_bit(u16 devid, u8 bit)
return (amd_iommu_dev_table[devid].data[i] & (1UL << _bit)) >> _bit;
}
+static void copy_irq_table(u16 devid)
+{
+ struct irq_remap_table *table = NULL;
+ u16 alias;
+ u64 dte;
+ u64 *old_intr_virt;
+
+ alias = amd_iommu_alias_table[devid];
+ table = irq_lookup_table[alias];
+ if (table) {
+ irq_lookup_table[devid] = table;
+ set_dte_irq_entry(devid, table);
+ return;
+ }
+ dte = amd_iommu_dev_table[devid].data[2];
+ dte &= DTE_IRQ_PHYS_ADDR_MASK;
+ if( (!dte&DTE_IRQ_REMAP_ENABLE) || ( dte == 0) )
+ return;
+
here: dte&DTE_IRQ_REMAP_ENABLE
style?
dte & DTE_IRQ_REMAP_ENABLE
+ table = kzalloc(sizeof(*table), GFP_ATOMIC);
+ if (!table){
+ pr_warn("AMD-Vi: amd irq table allocation failed\n");
+ return;
+ }
+
+ table->table = kmem_cache_alloc(amd_iommu_irq_cache, GFP_ATOMIC);
+ if (!table->table) {
+ kfree(table);
+ table = NULL;
+ return;
+ }
+ memset(table->table, 0, MAX_IRQS_PER_TABLE * sizeof(u32));
+
+ old_intr_virt = memremap(dte, MAX_IRQS_PER_TABLE * sizeof(u32),
MEMREMAP_WB);
Here if rename the 'dte' to 'irte', better to read?
+ memcpy(table->table, old_intr_virt, MAX_IRQS_PER_TABLE * sizeof(u32));
+ irq_lookup_table[devid] = table;
+ set_dte_irq_entry(devid, table);
+ if (devid != alias) {
+ irq_lookup_table[alias] = table;
+ set_dte_irq_entry(alias, table);
+ }
+ memunmap(old_intr_virt);
+}
void amd_iommu_apply_erratum_63(u16 devid)
{
diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h
index 743e209..ab562e0 100644
--- a/drivers/iommu/amd_iommu_proto.h
+++ b/drivers/iommu/amd_iommu_proto.h
@@ -101,5 +101,6 @@ static inline bool iommu_feature(struct amd_iommu *iommu,
u64 f)
/* kdump checking */
extern bool translation_pre_enabled(void);
extern void clear_translation_pre_enabled(void);
+extern void set_dte_irq_entry(u16 devid, struct irq_remap_table *table);
#endif /* _ASM_X86_AMD_IOMMU_PROTO_H */
_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu