diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2008-09-05 08:29:07 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-09-19 06:59:11 -0400 |
commit | 335503e57b6b8de04cec5d27eb2c3d09ff98905b (patch) | |
tree | a2f33f3a2a668e832273aa0b18608ef51e90a742 /arch | |
parent | 6d4f343f84993eb0d5864c0823dc9babd171a33a (diff) |
AMD IOMMU: add event buffer allocation
This patch adds the allocation of a event buffer for each AMD IOMMU in
the system. The hardware will log events like device page faults or
other errors to this buffer once this is enabled.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/amd_iommu_init.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index f2fa8dc81beb..41ce8d5d626e 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c | |||
@@ -417,6 +417,30 @@ static void __init free_command_buffer(struct amd_iommu *iommu) | |||
417 | free_pages((unsigned long)iommu->cmd_buf, get_order(CMD_BUFFER_SIZE)); | 417 | free_pages((unsigned long)iommu->cmd_buf, get_order(CMD_BUFFER_SIZE)); |
418 | } | 418 | } |
419 | 419 | ||
420 | /* allocates the memory where the IOMMU will log its events to */ | ||
421 | static u8 * __init alloc_event_buffer(struct amd_iommu *iommu) | ||
422 | { | ||
423 | u64 entry; | ||
424 | iommu->evt_buf = (u8 *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, | ||
425 | get_order(EVT_BUFFER_SIZE)); | ||
426 | |||
427 | if (iommu->evt_buf == NULL) | ||
428 | return NULL; | ||
429 | |||
430 | entry = (u64)virt_to_phys(iommu->evt_buf) | EVT_LEN_MASK; | ||
431 | memcpy_toio(iommu->mmio_base + MMIO_EVT_BUF_OFFSET, | ||
432 | &entry, sizeof(entry)); | ||
433 | |||
434 | iommu->evt_buf_size = EVT_BUFFER_SIZE; | ||
435 | |||
436 | return iommu->evt_buf; | ||
437 | } | ||
438 | |||
439 | static void __init free_event_buffer(struct amd_iommu *iommu) | ||
440 | { | ||
441 | free_pages((unsigned long)iommu->evt_buf, get_order(EVT_BUFFER_SIZE)); | ||
442 | } | ||
443 | |||
420 | /* sets a specific bit in the device table entry. */ | 444 | /* sets a specific bit in the device table entry. */ |
421 | static void set_dev_entry_bit(u16 devid, u8 bit) | 445 | static void set_dev_entry_bit(u16 devid, u8 bit) |
422 | { | 446 | { |
@@ -622,6 +646,7 @@ static int __init init_iommu_devices(struct amd_iommu *iommu) | |||
622 | static void __init free_iommu_one(struct amd_iommu *iommu) | 646 | static void __init free_iommu_one(struct amd_iommu *iommu) |
623 | { | 647 | { |
624 | free_command_buffer(iommu); | 648 | free_command_buffer(iommu); |
649 | free_event_buffer(iommu); | ||
625 | iommu_unmap_mmio_space(iommu); | 650 | iommu_unmap_mmio_space(iommu); |
626 | } | 651 | } |
627 | 652 | ||
@@ -661,6 +686,10 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h) | |||
661 | if (!iommu->cmd_buf) | 686 | if (!iommu->cmd_buf) |
662 | return -ENOMEM; | 687 | return -ENOMEM; |
663 | 688 | ||
689 | iommu->evt_buf = alloc_event_buffer(iommu); | ||
690 | if (!iommu->evt_buf) | ||
691 | return -ENOMEM; | ||
692 | |||
664 | init_iommu_from_pci(iommu); | 693 | init_iommu_from_pci(iommu); |
665 | init_iommu_from_acpi(iommu, h); | 694 | init_iommu_from_acpi(iommu, h); |
666 | init_iommu_devices(iommu); | 695 | init_iommu_devices(iommu); |