Commit 04e28c8d authored by Keir Fraser's avatar Keir Fraser

iommu: make interrupt remapping more generic

Signed-off-by: default avatarWei Wang <wei.wang2@amd.com>
parent 443d1f91
......@@ -173,8 +173,8 @@ static int unset_vector_msi(int vector)
static void write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
{
if ( vtd_enabled )
msi_msg_write_remap_rte(entry, msg);
if ( iommu_enabled )
iommu_update_ire_from_msi(entry, msg);
switch ( entry->msi_attrib.type )
{
......
......@@ -649,4 +649,6 @@ struct iommu_ops amd_iommu_ops = {
.unmap_page = amd_iommu_unmap_page,
.reassign_device = amd_iommu_return_device,
.get_device_group_id = amd_iommu_group_id,
.update_ire_from_apic = amd_iommu_ioapic_update_ire,
.update_ire_from_msi = amd_iommu_msi_msg_update_ire,
};
......@@ -290,6 +290,43 @@ int iommu_get_device_group(struct domain *d, u8 bus, u8 devfn,
return i;
}
void iommu_update_ire_from_apic(
unsigned int apic, unsigned int reg, unsigned int value)
{
struct iommu_ops *ops = NULL;
switch ( boot_cpu_data.x86_vendor )
{
case X86_VENDOR_INTEL:
ops = &intel_iommu_ops;
break;
case X86_VENDOR_AMD:
ops = &amd_iommu_ops;
break;
default:
BUG();
}
ops->update_ire_from_apic(apic, reg, value);
}
void iommu_update_ire_from_msi(
struct msi_desc *msi_desc, struct msi_msg *msg)
{
struct iommu_ops *ops = NULL;
switch ( boot_cpu_data.x86_vendor )
{
case X86_VENDOR_INTEL:
ops = &intel_iommu_ops;
break;
case X86_VENDOR_AMD:
ops = &amd_iommu_ops;
break;
default:
BUG();
}
ops->update_ire_from_msi(msi_desc, msg);
}
/*
* Local variables:
* mode: C
......
......@@ -1883,6 +1883,8 @@ struct iommu_ops intel_iommu_ops = {
.unmap_page = intel_iommu_unmap_page,
.reassign_device = reassign_device_ownership,
.get_device_group_id = intel_iommu_group_id,
.update_ire_from_apic = io_apic_write_remap_rte,
.update_ire_from_msi = msi_msg_write_remap_rte,
};
/*
......
......@@ -133,8 +133,8 @@ static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
{
if (vtd_enabled)
return io_apic_write_remap_rte(apic, reg, value);
if (iommu_enabled)
return iommu_update_ire_from_apic(apic, reg, value);
*IO_APIC_BASE(apic) = reg;
*(IO_APIC_BASE(apic)+4) = value;
}
......
......@@ -103,6 +103,10 @@ struct iommu_ops {
int (*reassign_device)(struct domain *s, struct domain *t,
u8 bus, u8 devfn);
int (*get_device_group_id)(u8 bus, u8 devfn);
void (*update_ire_from_apic)(unsigned int apic, unsigned int reg, unsigned int value);
void (*update_ire_from_msi)(struct msi_desc *msi_desc, struct msi_msg *msg);
};
void iommu_update_ire_from_apic(unsigned int apic, unsigned int reg, unsigned int value);
void iommu_update_ire_from_msi(struct msi_desc *msi_desc, struct msi_msg *msg);
#endif /* _IOMMU_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment