Skip to content

Commit be2a022

Browse files
joergroedelIngo Molnar
authored andcommitted
x86, AMD IOMMU: add functions to parse IOMMU memory mapping requirements for devices
This patch adds the functions to parse the information about IOMMU exclusion ranges and required unity mappings for the devices handled by the IOMMU. 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 e47d402 commit be2a022

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed

arch/x86/kernel/amd_iommu_init.c

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,3 +556,90 @@ static int __init init_iommu_all(struct acpi_table_header *table)
556556
return 0;
557557
}
558558

559+
static void __init free_unity_maps(void)
560+
{
561+
struct unity_map_entry *entry, *next;
562+
563+
list_for_each_entry_safe(entry, next, &amd_iommu_unity_map, list) {
564+
list_del(&entry->list);
565+
kfree(entry);
566+
}
567+
}
568+
569+
static int __init init_exclusion_range(struct ivmd_header *m)
570+
{
571+
int i;
572+
573+
switch (m->type) {
574+
case ACPI_IVMD_TYPE:
575+
set_device_exclusion_range(m->devid, m);
576+
break;
577+
case ACPI_IVMD_TYPE_ALL:
578+
for (i = 0; i < amd_iommu_last_bdf; ++i)
579+
set_device_exclusion_range(i, m);
580+
break;
581+
case ACPI_IVMD_TYPE_RANGE:
582+
for (i = m->devid; i <= m->aux; ++i)
583+
set_device_exclusion_range(i, m);
584+
break;
585+
default:
586+
break;
587+
}
588+
589+
return 0;
590+
}
591+
592+
static int __init init_unity_map_range(struct ivmd_header *m)
593+
{
594+
struct unity_map_entry *e = 0;
595+
596+
e = kzalloc(sizeof(*e), GFP_KERNEL);
597+
if (e == NULL)
598+
return -ENOMEM;
599+
600+
switch (m->type) {
601+
default:
602+
case ACPI_IVMD_TYPE:
603+
e->devid_start = e->devid_end = m->devid;
604+
break;
605+
case ACPI_IVMD_TYPE_ALL:
606+
e->devid_start = 0;
607+
e->devid_end = amd_iommu_last_bdf;
608+
break;
609+
case ACPI_IVMD_TYPE_RANGE:
610+
e->devid_start = m->devid;
611+
e->devid_end = m->aux;
612+
break;
613+
}
614+
e->address_start = PAGE_ALIGN(m->range_start);
615+
e->address_end = e->address_start + PAGE_ALIGN(m->range_length);
616+
e->prot = m->flags >> 1;
617+
618+
list_add_tail(&e->list, &amd_iommu_unity_map);
619+
620+
return 0;
621+
}
622+
623+
static int __init init_memory_definitions(struct acpi_table_header *table)
624+
{
625+
u8 *p = (u8 *)table, *end = (u8 *)table;
626+
struct ivmd_header *m;
627+
628+
INIT_LIST_HEAD(&amd_iommu_unity_map);
629+
630+
end += table->length;
631+
p += IVRS_HEADER_LENGTH;
632+
633+
while (p < end) {
634+
m = (struct ivmd_header *)p;
635+
if (m->flags & IVMD_FLAG_EXCL_RANGE)
636+
init_exclusion_range(m);
637+
else if (m->flags & IVMD_FLAG_UNITY_MAP)
638+
init_unity_map_range(m);
639+
640+
p += m->length;
641+
}
642+
643+
return 0;
644+
}
645+

0 commit comments

Comments
 (0)