[PATCH 00/10] Fix AMD IOMMU faults in kdump kernel

From: Baoquan He
Date: Thu Sep 24 2015 - 02:38:32 EST


This is a draft patchset trying to fix the issue that AMD IOMMU doesn't
work well in kdump kernel. The patch arrangement is not foraml, just
presenting what I have done and what's the problem being encountered
currently.


It contains 3 parts.

1) Clean up patch
Patch 1/10, 2/10, 3/10 are code clean up patches, which later part will
be based on.

2) IO page mapping
Patch 4/10 ~ 9/10
.> Checking if it's in kdump kernel and previously enabled
.> If yes do below operatons:
.> Do not disable amd iommu and do not touch dev tables before coping old dev tables
.> Copy dev table form old kernel and set the old domain id in amd_iommu_pd_alloc_bitmap
.> Don't call update_domain() to set domain->pt_root to dev entries before device driver initialization.
.> Reset the pre-enabled status when the first __map_single() is called during device driver init

3)interrupt remapping
Patch 10/10
.> I didn't think of this well. Now I only copy the old irq table when it first calls get_irq_table().
This need people's suggestion. Maybe not correct old irq table copy cause kdump kernel hang.

Now there are several problems I got:
Now there's always a hang when go into kdump kernel so that I can't test
futher if command buffer/envent buffer need be copied and where flush need
be called.

Kdump kernel hang and dump the call trace to show it happened in check_timer.
This is similar as people found when they debugged intel iommu issue.
http://lists.infradead.org/pipermail/kexec/2014-December/013137.html

[ 12.296525] ..TIMER: vector=0x30 apic1=0 pin1=2 apic2=-1 pin2=-1
[ 12.302513] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.2.0+ #18
[ 12.308500] Hardware name: AMD Dinar/Dinar, BIOS RDN1505B 06/05/2013
[ 12.314832] 0000000000000000 0000000085c693e9 ffff880030d6fd58
ffffffff8139746f
[ 12.322239] 00000000000000a0 ffff880030d6fd90 ffffffff814b4813
ffff880030d283c0
[ 12.329645] ffff880030d2e100 0000000000000002 0000000000000000
ffff880030c29808
[ 12.337052] Call Trace:
[ 12.339493] [<ffffffff8139746f>] dump_stack+0x44/0x55
[ 12.344616] [<ffffffff814b4813>] modify_irte+0x23/0xc0
[ 12.349827] [<ffffffff814b48cc>] irq_remapping_deactivate+0x1c/0x20
[ 12.356162] [<ffffffff814b48de>] irq_remapping_activate+0xe/0x10
[ 12.362238] [<ffffffff810fa6b1>] irq_domain_activate_irq+0x41/0x50
[ 12.368486] [<ffffffff810fa69b>] irq_domain_activate_irq+0x2b/0x50
[ 12.374736] [<ffffffff81d6ccbb>] setup_IO_APIC+0x33e/0x7e4
[ 12.380294] [<ffffffff81052039>] ? clear_IO_APIC+0x39/0x60
[ 12.385853] [<ffffffff81d6b82c>] apic_bsp_setup+0xa1/0xac
[ 12.391323] [<ffffffff81d69463>] native_smp_prepare_cpus+0x25f/0x2db
[ 12.397747] [<ffffffff81d550ee>] kernel_init_freeable+0xc9/0x228
[ 12.403824] [<ffffffff81762370>] ? rest_init+0x80/0x80
[ 12.409034] [<ffffffff8176237e>] kernel_init+0xe/0xe0
[ 12.414158] [<ffffffff8176e19f>] ret_from_fork+0x3f/0x70
[ 12.419541] [<ffffffff81762370>] ? rest_init+0x80/0x80
[ 12.424751] modify_irte devid: 00:14.0 index: 2, vector:48
[ 12.440491] Kernel panic - not syncing: timer doesn't work through
Interrupt-remapped IO-APIC
[ 12.449022] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.2.0+ #18
[ 12.455008] Hardware name: AMD Dinar/Dinar, BIOS RDN1505B 06/05/2013
[ 12.461340] 0000000000000000 0000000085c693e9 ffff880030d6fd58
ffffffff8139746f
[ 12.468753] ffffffff81a3cdf8 ffff880030d6fde0 ffffffff8119e921
0000000000000008
[ 12.476165] ffff880030d6fdf0 ffff880030d6fd88 0000000085c693e9
ffffffff813a41b5
[ 12.483577] Call Trace:
[ 12.486018] [<ffffffff8139746f>] dump_stack+0x44/0x55
[ 12.491142] [<ffffffff8119e921>] panic+0xd3/0x20b
[ 12.495919] [<ffffffff813a41b5>] ? delay_tsc+0x25/0x60
[ 12.501129] [<ffffffff814bfaba>] panic_if_irq_remap+0x1a/0x20
[ 12.506947] [<ffffffff81d6ccf2>] setup_IO_APIC+0x375/0x7e4
[ 12.512503] [<ffffffff81052039>] ? clear_IO_APIC+0x39/0x60
[ 12.518060] [<ffffffff81d6b82c>] apic_bsp_setup+0xa1/0xac
[ 12.523530] [<ffffffff81d69463>] native_smp_prepare_cpus+0x25f/0x2db
[ 12.529952] [<ffffffff81d550ee>] kernel_init_freeable+0xc9/0x228
[ 12.536030] [<ffffffff81762370>] ? rest_init+0x80/0x80
[ 12.541238] [<ffffffff8176237e>] kernel_init+0xe/0xe0
[ 12.546361] [<ffffffff8176e19f>] ret_from_fork+0x3f/0x70
[ 12.551745] [<ffffffff81762370>] ? rest_init+0x80/0x80
[ 12.556957] Rebooting in 10 seconds..
The problem happened in check_timer(). Seems timer interrupt doesn't
work well after modify_irte(). I don't know why it happened. Though I
have copied the old irte tables.

Baoquan He (10):
iommu/amd: Use standard bitmap operation to set bitmap
iommu/amd: Adjust functons which get first/last devid by reading pci
config
iommu/amd: Get the first/last device of iommu earlier
iommu/amd: Detect pre enabled translation
iommu/amd: Add function copy_dev_tables
iommu/amd: Add functions copy_command_buffer/copy_event_buffer
iommu/amd: copy old dev tables and do not change it
iommu/amd: Do not update the information of domain to devtables before
device driver init
iommu/amd: Clear the iommu pre enabled setting
iommu/amd: Copy the old ir table

drivers/iommu/amd_iommu.c | 31 ++++--
drivers/iommu/amd_iommu_init.c | 205 +++++++++++++++++++++++++++++++---------
drivers/iommu/amd_iommu_proto.h | 4 +
drivers/iommu/amd_iommu_types.h | 3 +
4 files changed, 189 insertions(+), 54 deletions(-)

--
2.4.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/