Skip to content

Commit e47d402

Browse files
joergroedelIngo Molnar
authored andcommitted
x86, AMD IOMMU: add detect code for AMD IOMMU hardware
This patch adds the detection of AMD IOMMU hardware provided on information from ACPI provided by the BIOS. Signed-off-by: Joerg Roedel <joerg.roedel@amd.com> Cc: iommu@lists.linux-foundation.org Cc: bhavna.sarathy@amd.com Cc: Sebastian.Biemueller@amd.com Cc: robert.richter@amd.com Cc: joro@8bytes.org Signed-off-by: Ingo Molnar <mingo@elte.hu>
1 parent 5d0c8e4 commit e47d402

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed

arch/x86/kernel/amd_iommu_init.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,3 +478,81 @@ static int __init init_iommu_devices(struct amd_iommu *iommu)
478478
return 0;
479479
}
480480

481+
static void __init free_iommu_one(struct amd_iommu *iommu)
482+
{
483+
free_command_buffer(iommu);
484+
iommu_unmap_mmio_space(iommu);
485+
}
486+
487+
static void __init free_iommu_all(void)
488+
{
489+
struct amd_iommu *iommu, *next;
490+
491+
list_for_each_entry_safe(iommu, next, &amd_iommu_list, list) {
492+
list_del(&iommu->list);
493+
free_iommu_one(iommu);
494+
kfree(iommu);
495+
}
496+
}
497+
498+
static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
499+
{
500+
spin_lock_init(&iommu->lock);
501+
list_add_tail(&iommu->list, &amd_iommu_list);
502+
503+
/*
504+
* Copy data from ACPI table entry to the iommu struct
505+
*/
506+
iommu->devid = h->devid;
507+
iommu->cap_ptr = h->cap_ptr;
508+
iommu->mmio_phys = h->mmio_phys;
509+
iommu->mmio_base = iommu_map_mmio_space(h->mmio_phys);
510+
if (!iommu->mmio_base)
511+
return -ENOMEM;
512+
513+
iommu_set_device_table(iommu);
514+
iommu->cmd_buf = alloc_command_buffer(iommu);
515+
if (!iommu->cmd_buf)
516+
return -ENOMEM;
517+
518+
init_iommu_from_pci(iommu);
519+
init_iommu_from_acpi(iommu, h);
520+
init_iommu_devices(iommu);
521+
522+
return 0;
523+
}
524+
525+
static int __init init_iommu_all(struct acpi_table_header *table)
526+
{
527+
u8 *p = (u8 *)table, *end = (u8 *)table;
528+
struct ivhd_header *h;
529+
struct amd_iommu *iommu;
530+
int ret;
531+
532+
INIT_LIST_HEAD(&amd_iommu_list);
533+
534+
end += table->length;
535+
p += IVRS_HEADER_LENGTH;
536+
537+
while (p < end) {
538+
h = (struct ivhd_header *)p;
539+
switch (*p) {
540+
case ACPI_IVHD_TYPE:
541+
iommu = kzalloc(sizeof(struct amd_iommu), GFP_KERNEL);
542+
if (iommu == NULL)
543+
return -ENOMEM;
544+
ret = init_iommu_one(iommu, h);
545+
if (ret)
546+
return ret;
547+
break;
548+
default:
549+
break;
550+
}
551+
p += h->length;
552+
553+
}
554+
WARN_ON(p != end);
555+
556+
return 0;
557+
}
558+

0 commit comments

Comments
 (0)