Reset PCIe devices to address DMA problem on kdump with iommu
Subsystems (4)
RFC PATCH 1/1 Reset PCIe devices to address DMA problem on kdump with iommu
Hi all,
This patch adds kernel parameter "reset_pcie_devices" which resets PCIe devices at boot time to address DMA problem on kdump with iommu. When this parameter is specified, a hot reset is triggered on each PCIe root port and downstream port to reset its downstream endpoint.
Background:
A kdump problem about DMA has been discussed for a long time. That is, when a kernel is switched to the kdump kernel DMA derived from first kernel affects second kernel. Recently this problem surfaces when iommu is used for PCI passthrough on KVM guest. In the case of the machine I use, when intel_iommu=on is specified, DMAR error is detected in kdump kernel and PCI SERR is also detected. Finally kdump fails because some devices does not work correctly.
The root cause is that ongoing DMA from first kernel causes DMAR fault because page table of DMAR is initialized while kdump kernel is booting up. Therefore to address this problem DMA needs to be stopped before DMAR is initialized at kdump kernel boot time. By this patch, PCIe devices are reset by hot reset and its DMA is stopped when reset_pcie_devices is specified. One problem of this solution is that VGA is reset and the monitor blacks out when the link between the port and VGA controller was reset. So this patch does not reset the port whose child endpoint is VGA device.
Any comments would be appreciated.
--- Documentation/kernel-parameters.txt | 4 + drivers/pci/quirks.c | 59 ++++++++++++++++++++++++++ 2 files changed, 63 insertions(+)
Documentation/kernel-parameters.txt +4 -0
@@ -2489,6 +2489,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. reset_devices [KNL] Force drivers to reset the underlying device during initialization. + reset_pcie_devices + [PCIE] Reset PCIe endpoint at boot time by sending a + hot reset to root port and downstream port + resume= [SWSUSP] Specify the partition device for software suspend Format:
drivers/pci/quirks.c +59 -0
65 lines not on this page · raw message
Quoted 6 lines · Takao Indoh
Hi all,
This patch adds kernel parameter "
reset_pcie_devices" which resets PCIe devices at boot time to address DMA problem on kdump with iommu. When this parameter is specified, a hot reset is triggered on each PCIe root port and downstream port to reset its downstream endpoint.
Hi Takao,
Why not use existing "reset_devices" parameter instead of introducing a new one?
Thanks
Vivek
Quoted 103 lines
Background:
A kdump problem about DMA has been discussed for a long time. That is, when a kernel is switched to the kdump kernel DMA derived from first kernel affects second kernel. Recently this problem surfaces when iommu is used for PCI passthrough on KVM guest. In the case of the machine I use, when intel_iommu=on is specified, DMAR error is detected in kdump kernel and PCI SERR is also detected. Finally kdump fails because some devices does not work correctly.The root cause is that ongoing DMA from first kernel causes DMAR fault because page table of DMAR is initialized while kdump kernel is booting up. Therefore to address this problem DMA needs to be stopped before DMAR is initialized at kdump kernel boot time. By this patch, PCIe devices are reset by hot reset and its DMA is stopped when
reset_pcie_devicesis specified. One problem of this solution is that VGA is reset and the monitor blacks out when the link between the port and VGA controller was reset. So this patch does not reset the port whose child endpoint is VGA device.Any comments would be appreciated.
Signed-off-by Takao Indoh <[email protected]>--- Documentation/kernel-parameters.txt | 4 + drivers/pci/quirks.c | 59 ++++++++++++++++++++++++++ 2 files changed, 63 insertions(+)Documentation/kernel-parameters.txt +4
-0@@ -2489,6 +2489,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. reset_devices [KNL] Force drivers to reset the underlying device during initialization. + reset_pcie_devices + [PCIE] Reset PCIe endpoint at boot time by sending a + hot reset to root port and downstream port + resume= [SWSUSP] Specify the partition device for software suspend Format:drivers/pci/quirks.c +52
-0@@ -32,6 +32,65 @@#include "pci.h" /* +* Reset PCIe endpoint by sending a hot reset to root port and downstream port +*/ +unsigned int reset_pcie_devices; +EXPORT_SYMBOL (reset_pcie_devices); +static int __init set_reset_pcie_devices (char *str) +{ + reset_pcie_devices =1 ; +return 1 ; +} +__setup ("reset_pcie_devices" , set_reset_pcie_devices); + +static void __devinit quirk_pcie_device_reset (struct pci_dev *dev) +{ +struct pci_bus *subordinate; +struct pci_dev *child; +u16 ctrl; + +if (!reset_pcie_devices || !pci_is_pcie (dev) || !dev->subordinate || + ((dev->pcie_type !=PCI_EXP_TYPE_ROOT_PORT ) && + (dev->pcie_type !=PCI_EXP_TYPE_DOWNSTREAM ))) +return ; + + subordinate = dev->subordinate; +list_for_each_entry (child, &subordinate->devices, bus_list) { +if ((child->pcie_type ==PCI_EXP_TYPE_UPSTREAM ) || + (child->pcie_type ==PCI_EXP_TYPE_PCI_BRIDGE ) || + ((child->class >>16 ) ==PCI_BASE_CLASS_DISPLAY )) +/* Don't reset switch, bridge, VGA device */ +return ; + } + +dev_info (&dev->dev,"Reset Secondary bus\n" ); + +list_for_each_entry (child, &subordinate->devices, bus_list) { +dev_info (&child->dev,"save state\n" ); +pci_save_state (child); + } + +/* Assert Secondary Bus Reset */ +pci_read_config_word (dev,PCI_BRIDGE_CONTROL , &ctrl); + ctrl |=PCI_BRIDGE_CTL_BUS_RESET ; +pci_write_config_word (dev,PCI_BRIDGE_CONTROL , ctrl); + +msleep (2 ); + +/* De-assert Secondary Bus Reset */ + ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET ; +pci_write_config_word (dev,PCI_BRIDGE_CONTROL , ctrl); + +msleep (200 ); + +list_for_each_entry (child, &subordinate->devices, bus_list) {
drivers/pci/quirks.c line 96
Quoted 10 lines
drivers/pci/quirks.c +7
-0+dev_info (&child->dev,"restore state\n" ); +pci_restore_state (child); + } +} +DECLARE_PCI_FIXUP_FINAL (PCI_ANY_ID ,PCI_ANY_ID , quirk_pcie_device_reset); + +/* * Decoding should be disabled for a PCI device during BAR sizing to avoid * conflict. But doing so may cause problems on host bridge and perhaps other * key system devices. For devices that need to have mmio decoding always-on,
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Hi Vivek,
Quoted 8 lines · Vivek Goyal
Quoted 6 lines · Takao Indoh
Hi all,
This patch adds kernel parameter "
reset_pcie_devices" which resets PCIe devices at boot time to address DMA problem on kdump with iommu. When this parameter is specified, a hot reset is triggered on each PCIe root port and downstream port to reset its downstream endpoint.
Quoted 4 lines
Hi Takao,
Why not use existing "
reset_devices" parameter instead of introducing a new one?
"reset_devices" is used for each driver to reset their own device, and this patch resets all devices forcibly, so I thought they were different things.
Thanks,
Takao Indoh
Quoted 119 lines
Thanks
VivekQuoted 113 lines
Background:
A kdump problem about DMA has been discussed for a long time. That is, when a kernel is switched to the kdump kernel DMA derived from first kernel affects second kernel. Recently this problem surfaces when iommu is used for PCI passthrough on KVM guest. In the case of the machine I use, when intel_iommu=on is specified, DMAR error is detected in kdump kernel and PCI SERR is also detected. Finally kdump fails because some devices does not work correctly.The root cause is that ongoing DMA from first kernel causes DMAR fault because page table of DMAR is initialized while kdump kernel is booting up. Therefore to address this problem DMA needs to be stopped before DMAR is initialized at kdump kernel boot time. By this patch, PCIe devices are reset by hot reset and its DMA is stopped when
reset_pcie_devicesis specified. One problem of this solution is that VGA is reset and the monitor blacks out when the link between the port and VGA controller was reset. So this patch does not reset the port whose child endpoint is VGA device.Any comments would be appreciated.
Signed-off-by Takao Indoh <[email protected]>--- Documentation/kernel-parameters.txt | 4 + drivers/pci/quirks.c | 59 ++++++++++++++++++++++++++ 2 files changed, 63 insertions(+)Documentation/kernel-parameters.txt +4
-0@@ -2489,6 +2489,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. reset_devices [KNL] Force drivers to reset the underlying device during initialization. + reset_pcie_devices + [PCIE] Reset PCIe endpoint at boot time by sending a + hot reset to root port and downstream port + resume= [SWSUSP] Specify the partition device for software suspend Format:drivers/pci/quirks.c +59
-0@@ -32,6 +32,65 @@#include "pci.h" /* +* Reset PCIe endpoint by sending a hot reset to root port and downstream port +*/ +unsigned int reset_pcie_devices; +EXPORT_SYMBOL (reset_pcie_devices); +static int __init set_reset_pcie_devices (char *str) +{ + reset_pcie_devices =1 ; +return 1 ; +} +__setup ("reset_pcie_devices" , set_reset_pcie_devices); + +static void __devinit quirk_pcie_device_reset (struct pci_dev *dev) +{ +struct pci_bus *subordinate; +struct pci_dev *child; +u16 ctrl; + +if (!reset_pcie_devices || !pci_is_pcie (dev) || !dev->subordinate || + ((dev->pcie_type !=PCI_EXP_TYPE_ROOT_PORT ) && + (dev->pcie_type !=PCI_EXP_TYPE_DOWNSTREAM ))) +return ; + + subordinate = dev->subordinate; +list_for_each_entry (child, &subordinate->devices, bus_list) { +if ((child->pcie_type ==PCI_EXP_TYPE_UPSTREAM ) || + (child->pcie_type ==PCI_EXP_TYPE_PCI_BRIDGE ) || + ((child->class >>16 ) ==PCI_BASE_CLASS_DISPLAY )) +/* Don't reset switch, bridge, VGA device */ +return ; + } + +dev_info (&dev->dev,"Reset Secondary bus\n" ); + +list_for_each_entry (child, &subordinate->devices, bus_list) { +dev_info (&child->dev,"save state\n" ); +pci_save_state (child); + } + +/* Assert Secondary Bus Reset */ +pci_read_config_word (dev,PCI_BRIDGE_CONTROL , &ctrl); + ctrl |=PCI_BRIDGE_CTL_BUS_RESET ; +pci_write_config_word (dev,PCI_BRIDGE_CONTROL , ctrl); + +msleep (2 ); + +/* De-assert Secondary Bus Reset */ + ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET ; +pci_write_config_word (dev,PCI_BRIDGE_CONTROL , ctrl); + +msleep (200 ); + +list_for_each_entry (child, &subordinate->devices, bus_list) { +dev_info (&child->dev,"restore state\n" ); +pci_restore_state (child); + } +} +DECLARE_PCI_FIXUP_FINAL (PCI_ANY_ID ,PCI_ANY_ID , quirk_pcie_device_reset); + +/* * Decoding should be disabled for a PCI device during BAR sizing to avoid * conflict. But doing so may cause problems on host bridge and perhaps other * key system devices. For devices that need to have mmio decoding always-on,
Quoted 11 lines · Takao Indoh
Hi Vivek,
Quoted 8 lines · Vivek Goyal
Quoted 6 lines · Takao Indoh
Hi all,
This patch adds kernel parameter "
reset_pcie_devices" which resets PCIe devices at boot time to address DMA problem on kdump with iommu. When this parameter is specified, a hot reset is triggered on each PCIe root port and downstream port to reset its downstream endpoint.
Quoted 8 lines
Quoted 4 lines
Hi Takao,
Why not use existing "
reset_devices" parameter instead of introducing a new one?"
reset_devices" is used for each driver to reset their own device, and this patch resets all devices forcibly, so I thought they were different things.
Yes reset_devices currently is used for driver to reset its device. I thought one could very well extend its reach to reset pci express devices at bus level.
Having them separate is not going to be much useful from kdump perspective. We will end up passing both reset_devices and reset_pcie_devices to second kernel whill lead to bus level reset as well as device level reset.
Ideal situation would be that somehow detect that bus level reset has been done and skip device level reset (assuming bus level reset obviates the need of device level reset, please correct me if that's not the case).
After pcie reset, can we store the state in a variable and drivers can use that variable to check if PCIe level reset was done or not. If yes, skip device level reset (Assuming driver knows that device is on a PCIe slot).
In that case we will not have to introduce new kernel command line, and also avoid double reset?
Thanks
Vivek
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Quoted 34 lines · Vivek Goyal
Quoted 11 lines · Takao Indoh
Hi Vivek,
Quoted 8 lines · Vivek Goyal
Quoted 6 lines · Takao Indoh
Hi all,
This patch adds kernel parameter "
reset_pcie_devices" which resets PCIe devices at boot time to address DMA problem on kdump with iommu. When this parameter is specified, a hot reset is triggered on each PCIe root port and downstream port to reset its downstream endpoint.Quoted 8 lines
Quoted 4 lines
Hi Takao,
Why not use existing "
reset_devices" parameter instead of introducing a new one?"
reset_devices" is used for each driver to reset their own device, and this patch resets all devices forcibly, so I thought they were different things.Yes
reset_devicescurrently is used for driver to reset its device. I thought one could very well extend its reach to reset pci express devices at bus level.Having them separate is not going to be much useful from kdump perspective. We will end up passing both
reset_devicesandreset_pcie_devicesto second kernel whill lead to bus level reset as well as device level reset.Ideal situation would be that somehow detect that bus level reset has been done and skip device level reset (assuming bus level reset obviates the need of device level reset, please correct me if that's not the case).
Quoted 7 lines
After pcie reset, can we store the state in a variable and drivers can use that variable to check if PCIe level reset was done or not. If yes, skip device level reset (Assuming driver knows that device is on a PCIe slot).
In that case we will not have to introduce new kernel command line, and also avoid double reset?
Actually I'm not sure whether the driver does not need to do their reset after bus level reset, but I agree with you, now I'm thinking that using reset_devices is better rather than adding narrow one which is limited to PCI express, otherwise we may have to add new parameter every time when adding new reset method, such as reset_pcie_devices, reset_pci_legacy_devices, etc.
Thanks,
Takao Indoh
Quoted 34 lines · Vivek Goyal
Quoted 11 lines · Takao Indoh
Hi Vivek,
Quoted 8 lines · Vivek Goyal
Quoted 6 lines · Takao Indoh
Hi all,
This patch adds kernel parameter "
reset_pcie_devices" which resets PCIe devices at boot time to address DMA problem on kdump with iommu. When this parameter is specified, a hot reset is triggered on each PCIe root port and downstream port to reset its downstream endpoint.Quoted 8 lines
Quoted 4 lines
Hi Takao,
Why not use existing "
reset_devices" parameter instead of introducing a new one?"
reset_devices" is used for each driver to reset their own device, and this patch resets all devices forcibly, so I thought they were different things.Yes
reset_devicescurrently is used for driver to reset its device. I thought one could very well extend its reach to reset pci express devices at bus level.Having them separate is not going to be much useful from kdump perspective. We will end up passing both
reset_devicesandreset_pcie_devicesto second kernel whill lead to bus level reset as well as device level reset.Ideal situation would be that somehow detect that bus level reset has been done and skip device level reset (assuming bus level reset obviates the need of device level reset, please correct me if that's not the case).
Quoted 7 lines
After pcie reset, can we store the state in a variable and drivers can use that variable to check if PCIe level reset was done or not. If yes, skip device level reset (Assuming driver knows that device is on a PCIe slot).
In that case we will not have to introduce new kernel command line, and also avoid double reset?
I found a problem when testing my patch on some machines.
Originally there are two problems in kdump kernel when iommu is enabled; DMAR error and PCI SERR. I thought they are fixed by my patch, but I noticed that PCI SERR is still detected after applying the patch. It seems that something happens when Interrupt Remapping is initialized in kdump kernel.
Therefore resetting devices has to be done before enable_IR() is called. I have three ideas for it.
(i) Resetting devices in 1st kernel(panic kernel)
We can reset devices before jumping into 2nd kernel. Of course it may be dangerous to scan pci device tree and call PCI functions in panic'd kernel. Beforehand we need to collect device information so that only minimal code could run on panic.
(ii) Resetting devices in purgatory
It seems to be be appropriate place to do this, but I'm not sure where I can save/restore PCI config when resetting devices in purgatory.
(iii) Resetting devices in 2nd kernel(kdump kernel) Important point is to do reset before enable_IR() is called as I wrote above. I think I should add new function to do reset into arch/x86/pci/early.c and call it in setup_arch like early_dump_pci_devices() or early_quirks().
Any comments?
Thanks,
Takao Indoh
Quoted 57 lines
-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Takao Indoh
Sent: Wednesday, September 05, 2012 8:10 PM
To: [email protected]
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Ishii, Hironobu/石井 宏延; [email protected]
Subject: Re: [RFC][PATCH] Reset PCIe devices to address DMA problem on kdump with iommuQuoted 8 lines · Vivek Goyal
Quoted 7 lines · Takao Indoh
Hi Vivek,
Quoted 4 lines · Vivek Goyal
Quoted 3 lines · Takao Indoh
Hi all,
This patch adds kernel parameter "
reset_pcie_devices" which resetsPCIe
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
devices at boot time to address DMA problem on kdump with iommu. When this parameter is specified, a hot reset is triggered on each PCIe
root
Quoted 15 lines
Quoted 10 lines
Quoted 6 lines
Quoted 1 line
port and downstream port to reset its downstream endpoint.
Hi Takao,
Why not use existing "
reset_devices" parameter instead of introducing a new one?"
reset_devices" is used for each driver to reset their own device, and this patch resets all devices forcibly, so I thought they were different things.Yes
reset_devicescurrently is used for driver to reset its device. I thought one could very well extend its reach to reset pci express devices at bus level.Quoted 6 lines
Having them separate is not going to be much useful from kdump perspective. We will end up passing both
reset_devicesandreset_pcie_devicesto second kernel whill lead to bus level reset as well as device level reset.Ideal situation would be that somehow detect that bus level reset has
been
Quoted 10 lines
done and skip device level reset (assuming bus level reset obviates the need of device level reset, please correct me if that's not the case).
After pcie reset, can we store the state in a variable and drivers can use that variable to check if PCIe level reset was done or not. If yes, skip device level reset (Assuming driver knows that device is on a PCIe slot).
In that case we will not have to introduce new kernel command line, and also avoid double reset?
Quoted 7 lines
I found a problem when testing my patch on some machines.
Originally there are two problems in kdump kernel when iommu is enabled; DMAR error and PCI SERR. I thought they are fixed by my patch, but I noticed that PCI SERR is still detected after applying the patch. It seems that something happens when Interrupt Remapping is initialized in kdump kernel.
I'm not sure, but I guess the PCI SERR might be caused as follows.
- The 1st kernel enables interrupt remapping. The MSI(-X) address and data registers of PCI devices are programmed in remappable format.
- At the beginning of 2nd kernel, interrupt remapping is still active. And then it is disabled by enable_IR() function for initialization.
- PCI device generate an interrupt. At this moment, interrupt remapping is not enabled yet. On the other hand, MSI(-X) address and data of this interrupt is in remappable format because those are programmed by 1st kernel. I guess this might be a cause of PCI SERR.
I guess clearing command register or disabling MSI before interrupt remapping initialization in 2nd kernel might solve the PCI SERR problem.
Regards,
Kenji Kaneshige
Quoted 30 lines
Therefore resetting devices has to be done before
enable_IR()is called. I have three ideas for it.(i) Resetting devices in 1st kernel(panic kernel)
We can reset devices before jumping into 2nd kernel. Of course it may be dangerous to scan pci device tree and call PCI functions in panic'd kernel. Beforehand we need to collect device information so that only minimal code could run on panic.(ii) Resetting devices in purgatory
It seems to be be appropriate place to do this, but I'm not sure where I can save/restore PCI config when resetting devices in purgatory.(iii) Resetting devices in 2nd kernel(kdump kernel) Important point is to do reset before
enable_IR()is called as I wrote above. I think I should add new function to do reset intoarch/x86/pci/early.cand call it insetup_archlikeearly_dump_pci_devices()orearly_quirks().Any comments?
Thanks,
Takao Indoh--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 73 lines · Kenji
Quoted 57 lines
-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Takao Indoh
Sent: Wednesday, September 05, 2012 8:10 PM
To: [email protected]
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Ishii, Hironobu/石井 宏延; [email protected]
Subject: Re: [RFC][PATCH] Reset PCIe devices to address DMA problem on kdump with iommuQuoted 8 lines · Vivek Goyal
Quoted 7 lines · Takao Indoh
Hi Vivek,
Quoted 4 lines · Vivek Goyal
Quoted 3 lines · Takao Indoh
Hi all,
This patch adds kernel parameter "
reset_pcie_devices" which resetsPCIe
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
devices at boot time to address DMA problem on kdump with iommu. When this parameter is specified, a hot reset is triggered on each PCIe
root
Quoted 15 lines
Quoted 10 lines
Quoted 6 lines
Quoted 1 line
port and downstream port to reset its downstream endpoint.
Hi Takao,
Why not use existing "
reset_devices" parameter instead of introducing a new one?"
reset_devices" is used for each driver to reset their own device, and this patch resets all devices forcibly, so I thought they were different things.Yes
reset_devicescurrently is used for driver to reset its device. I thought one could very well extend its reach to reset pci express devices at bus level.Quoted 6 lines
Having them separate is not going to be much useful from kdump perspective. We will end up passing both
reset_devicesandreset_pcie_devicesto second kernel whill lead to bus level reset as well as device level reset.Ideal situation would be that somehow detect that bus level reset has
been
Quoted 10 lines
done and skip device level reset (assuming bus level reset obviates the need of device level reset, please correct me if that's not the case).
After pcie reset, can we store the state in a variable and drivers can use that variable to check if PCIe level reset was done or not. If yes, skip device level reset (Assuming driver knows that device is on a PCIe slot).
In that case we will not have to introduce new kernel command line, and also avoid double reset?
Quoted 7 lines
I found a problem when testing my patch on some machines.
Originally there are two problems in kdump kernel when iommu is enabled; DMAR error and PCI SERR. I thought they are fixed by my patch, but I noticed that PCI SERR is still detected after applying the patch. It seems that something happens when Interrupt Remapping is initialized in kdump kernel.
I'm not sure, but I guess the PCI SERR might be caused as follows.
- The 1st kernel enables interrupt remapping. The MSI(-X) address and data registers of PCI devices are programmed in remappable format.
- At the beginning of 2nd kernel, interrupt remapping is still active. And then it is disabled by
enable_IR()function for initialization.
Quoted 7 lines
- PCI device generate an interrupt. At this moment, interrupt remapping is not enabled yet. On the other hand, MSI(-X) address and data of this interrupt is in remappable format because those are programmed by 1st kernel. I guess this might be a cause of PCI SERR.
I guess clearing command register or disabling MSI before interrupt remapping initialization in 2nd kernel might solve the PCI SERR problem.
Thank you for your comment. That makes sense.
Though I think clearing bus master bit is enough, do you think I need to clear all command register bit not only bus master?
Thanks,
Takao Indoh
Quoted 36 lines
Regards,
Kenji KaneshigeQuoted 30 lines
Therefore resetting devices has to be done before
enable_IR()is called. I have three ideas for it.(i) Resetting devices in 1st kernel(panic kernel)
We can reset devices before jumping into 2nd kernel. Of course it may be dangerous to scan pci device tree and call PCI functions in panic'd kernel. Beforehand we need to collect device information so that only minimal code could run on panic.(ii) Resetting devices in purgatory
It seems to be be appropriate place to do this, but I'm not sure where I can save/restore PCI config when resetting devices in purgatory.(iii) Resetting devices in 2nd kernel(kdump kernel) Important point is to do reset before
enable_IR()is called as I wrote above. I think I should add new function to do reset intoarch/x86/pci/early.cand call it insetup_archlikeearly_dump_pci_devices()orearly_quirks().Any comments?
Thanks,
Takao Indoh--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 100 lines
-----Original Message-----
From: Takao Indoh [mailto:[email protected]]
Sent: Monday, September 10, 2012 3:35 PM
To: Kaneshige, Kenji/金重 憲治
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Ishii, Hironobu/石井 宏延; [email protected]
Subject: Re: [RFC][PATCH] Reset PCIe devices to address DMA problem on kdump with iommuQuoted 7 lines · Kenji
Quoted 7 lines
-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Takao Indoh
Sent: Wednesday, September 05, 2012 8:10 PM
To: [email protected]
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected];Ishii,
Quoted 2 lines
Quoted 2 lines
Hironobu/石井 宏延; [email protected]
Subject: Re: [RFC][PATCH] Reset PCIe devices to address DMA problem onkdump
Quoted 6 lines
Quoted 6 lines
with iommu
Quoted 3 lines · Vivek Goyal
Quoted 2 lines · Takao Indoh
Hi Vivek,
Quoted 7 lines
Quoted 7 lines
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines · Vivek Goyal
Quoted 3 lines · Takao Indoh
Hi all,
This patch adds kernel parameter "
reset_pcie_devices" which resetsPCIe
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
devices at boot time to address DMA problem on kdump with iommu.
When
Quoted 10 lines
Quoted 10 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
this parameter is specified, a hot reset is triggered on each PCIe
root
Quoted 8 lines
Quoted 8 lines
Quoted 6 lines
Quoted 1 line
port and downstream port to reset its downstream endpoint.
Hi Takao,
Why not use existing "
reset_devices" parameter instead of introducing a new one?"
reset_devices" is used for each driver to reset their own device,and
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 2 lines
this patch resets all devices forcibly, so I thought they were different things.
Yes
reset_devicescurrently is used for driver to reset its device.I
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
thought one could very well extend its reach to reset pci express devices at bus level.
Having them separate is not going to be much useful from kdump perspective. We will end up passing both
reset_devicesandreset_pcie_devicesto second kernel whill lead to bus level reset aswell
Quoted 5 lines
Quoted 5 lines
Quoted 3 lines
as device level reset.
Ideal situation would be that somehow detect that bus level reset has
been
Quoted 1 line
done and skip device level reset (assuming bus level reset obviates
the
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
need of device level reset, please correct me if that's not the case).
After pcie reset, can we store the state in a variable and drivers can use that variable to check if PCIe level reset was done or not. If yes, skip device level reset (Assuming driver knows that device is on a PCIe slot).
In that case we will not have to introduce new kernel command line,
and
Quoted 8 lines
Quoted 8 lines
Quoted 1 line
also avoid double reset?
I found a problem when testing my patch on some machines.
Originally there are two problems in kdump kernel when iommu is enabled; DMAR error and PCI SERR. I thought they are fixed by my patch, but I noticed that PCI SERR is still detected after applying the patch. It seems that something happens when Interrupt Remapping is initialized
in
Quoted 4 lines
Quoted 1 line
kdump kernel.
I'm not sure, but I guess the PCI SERR might be caused as follows.
Quoted 8 lines
- The 1st kernel enables interrupt remapping. The MSI(-X) address and data registers of PCI devices are programmed in remappable format.
- At the beginning of 2nd kernel, interrupt remapping is still active. And then it is disabled by
enable_IR()function for initialization.- PCI device generate an interrupt. At this moment, interrupt remapping is not enabled yet. On the other hand, MSI(-X) address and data of
this
Quoted 3 lines
interrupt is in remappable format because those are programmed by 1st kernel. I guess this might be a cause of PCI SERR.
Quoted 8 lines
Quoted 2 lines
I guess clearing command register or disabling MSI before interrupt remapping initialization in 2nd kernel might solve the PCI SERR problem.
Thank you for your comment. That makes sense.
Though I think clearing bus master bit is enough, do you think I need to clear
all command register bit not only bus master?
I thought clearing bus master bit. But we might also need to set the disable INTx bit.
It would not be needed if we can reset devices before interrupt remapping initialization. I guess resetting devices before interrupt remapping initialization would need complex code change and be difficult to implement. If so, clearing bus master bit would be one of the alternative solution against PCI SERR issue.
Regards,
Kenji Kaneshige
Quoted 43 lines
Thanks,
Takao IndohQuoted 10 lines
Regards,
Kenji KaneshigeQuoted 6 lines
Therefore resetting devices has to be done before
enable_IR()is called. I have three ideas for it.(i) Resetting devices in 1st kernel(panic kernel)
We can reset devices before jumping into 2nd kernel. Of course itmay
Quoted 15 lines
Quoted 15 lines
be dangerous to scan pci device tree and call PCI functions in panic'd kernel. Beforehand we need to collect device information so that only minimal code could run on panic.
(ii) Resetting devices in purgatory
It seems to be be appropriate place to do this, but I'm not sure where I can save/restore PCI config when resetting devices in purgatory.(iii) Resetting devices in 2nd kernel(kdump kernel) Important point is to do reset before
enable_IR()is called as I wrote above. I think I should add new function to do reset intoarch/x86/pci/early.cand call it insetup_archlikeearly_dump_pci_devices()orearly_quirks().Quoted 7 lines
Quoted 7 lines
Any comments?
Thanks,
Takao Indoh--
To unsubscribe from this list: send the line "unsubscribe linux-pci"in
Quoted 4 lines
Quoted 2 lines
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 64 lines · Takao Indoh
Quoted 34 lines · Vivek Goyal
Quoted 11 lines · Takao Indoh
Hi Vivek,
Quoted 8 lines · Vivek Goyal
Quoted 6 lines · Takao Indoh
Hi all,
This patch adds kernel parameter "
reset_pcie_devices" which resets PCIe devices at boot time to address DMA problem on kdump with iommu. When this parameter is specified, a hot reset is triggered on each PCIe root port and downstream port to reset its downstream endpoint.Quoted 8 lines
Quoted 4 lines
Hi Takao,
Why not use existing "
reset_devices" parameter instead of introducing a new one?"
reset_devices" is used for each driver to reset their own device, and this patch resets all devices forcibly, so I thought they were different things.Yes
reset_devicescurrently is used for driver to reset its device. I thought one could very well extend its reach to reset pci express devices at bus level.Having them separate is not going to be much useful from kdump perspective. We will end up passing both
reset_devicesandreset_pcie_devicesto second kernel whill lead to bus level reset as well as device level reset.Ideal situation would be that somehow detect that bus level reset has been done and skip device level reset (assuming bus level reset obviates the need of device level reset, please correct me if that's not the case).
Quoted 7 lines
After pcie reset, can we store the state in a variable and drivers can use that variable to check if PCIe level reset was done or not. If yes, skip device level reset (Assuming driver knows that device is on a PCIe slot).
In that case we will not have to introduce new kernel command line, and also avoid double reset?
I found a problem when testing my patch on some machines.
Originally there are two problems in kdump kernel when iommu is enabled; DMAR error and PCI SERR. I thought they are fixed by my patch, but I noticed that PCI SERR is still detected after applying the patch. It seems that something happens when Interrupt Remapping is initialized in kdump kernel.
Therefore resetting devices has to be done before
enable_IR()is called. I have three ideas for it.(i) Resetting devices in 1st kernel(panic kernel)
We can reset devices before jumping into 2nd kernel. Of course it may be dangerous to scan pci device tree and call PCI functions in panic'd kernel. Beforehand we need to collect device information so that only minimal code could run on panic.(ii) Resetting devices in purgatory
It seems to be be appropriate place to do this, but I'm not sure where I can save/restore PCI config when resetting devices in purgatory.
Quoted 5 lines
(iii) Resetting devices in 2nd kernel(kdump kernel) Important point is to do reset before
enable_IR()is called as I wrote above. I think I should add new function to do reset intoarch/x86/pci/early.cand call it insetup_archlikeearly_dump_pci_devices()orearly_quirks().
I would not claim that I understand hte PCI SERR issue. But whatever resettings needs to happen, should happen early in second kernel.
Doing it in first kernel is not a good idea as it is crashed kernel and we want to as little as possible.
Doing it in purgatory is not a good idea either as purgatory does not konw anything about kernel as such. We don't want to bloat purgatory with reset code and embedding the device knowledge there.
Keeping it in second kernel makes sense so that code remains with kernel and can be maintained there.
Thanks
Vivek
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Quoted 77 lines · Vivek Goyal
Quoted 64 lines · Takao Indoh
Quoted 34 lines · Vivek Goyal
Quoted 11 lines · Takao Indoh
Hi Vivek,
Quoted 8 lines · Vivek Goyal
Quoted 6 lines · Takao Indoh
Hi all,
This patch adds kernel parameter "
reset_pcie_devices" which resets PCIe devices at boot time to address DMA problem on kdump with iommu. When this parameter is specified, a hot reset is triggered on each PCIe root port and downstream port to reset its downstream endpoint.Quoted 8 lines
Quoted 4 lines
Hi Takao,
Why not use existing "
reset_devices" parameter instead of introducing a new one?"
reset_devices" is used for each driver to reset their own device, and this patch resets all devices forcibly, so I thought they were different things.Yes
reset_devicescurrently is used for driver to reset its device. I thought one could very well extend its reach to reset pci express devices at bus level.Having them separate is not going to be much useful from kdump perspective. We will end up passing both
reset_devicesandreset_pcie_devicesto second kernel whill lead to bus level reset as well as device level reset.Ideal situation would be that somehow detect that bus level reset has been done and skip device level reset (assuming bus level reset obviates the need of device level reset, please correct me if that's not the case).
Quoted 7 lines
After pcie reset, can we store the state in a variable and drivers can use that variable to check if PCIe level reset was done or not. If yes, skip device level reset (Assuming driver knows that device is on a PCIe slot).
In that case we will not have to introduce new kernel command line, and also avoid double reset?
I found a problem when testing my patch on some machines.
Originally there are two problems in kdump kernel when iommu is enabled; DMAR error and PCI SERR. I thought they are fixed by my patch, but I noticed that PCI SERR is still detected after applying the patch. It seems that something happens when Interrupt Remapping is initialized in kdump kernel.
Therefore resetting devices has to be done before
enable_IR()is called. I have three ideas for it.(i) Resetting devices in 1st kernel(panic kernel)
We can reset devices before jumping into 2nd kernel. Of course it may be dangerous to scan pci device tree and call PCI functions in panic'd kernel. Beforehand we need to collect device information so that only minimal code could run on panic.(ii) Resetting devices in purgatory
It seems to be be appropriate place to do this, but I'm not sure where I can save/restore PCI config when resetting devices in purgatory.Quoted 5 lines
(iii) Resetting devices in 2nd kernel(kdump kernel) Important point is to do reset before
enable_IR()is called as I wrote above. I think I should add new function to do reset intoarch/x86/pci/early.cand call it insetup_archlikeearly_dump_pci_devices()orearly_quirks().I would not claim that I understand hte PCI SERR issue. But whatever resettings needs to happen, should happen early in second kernel.
Doing it in first kernel is not a good idea as it is crashed kernel and we want to as little as possible.
Quoted 6 lines
Doing it in purgatory is not a good idea either as purgatory does not konw anything about kernel as such. We don't want to bloat purgatory with reset code and embedding the device knowledge there.
Keeping it in second kernel makes sense so that code remains with kernel and can be maintained there.
I'll post new patch which clears bus master bit and resets devices in second kernel.
As to the boot parameter to enable this function, you suggested using reset_devices. I found that on a certain platform resetting devices caused PCIe error due to a hardware bug. Therefore I think we need new parameter apart from reset_devices to disable this function on such a machine.
Thanks,
Takao Indoh
On Tue, Sep 11, 2012 at 07:32:35PM +0900, Takao Indoh wrote:
[..]
Quoted 8 lines
I'll post new patch which clears bus master bit and resets devices in second kernel.
As to the boot parameter to enable this function, you suggested using
reset_devices. I found that on a certain platform resetting devices caused PCIe error due to a hardware bug. Therefore I think we need new parameter apart fromreset_devicesto disable this function on such a machine.
Can you explain a bit more how the error happens. I still don't think that because of a bug in a platform somewhere we should be introducing a separate command line parameter and not reuse the exisiting one. Also you have not explained what's the bug and how a new parameter will avoid the bug.
Thanks
Vivek
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Quoted 12 lines · Vivek Goyal
On Tue, Sep 11, 2012 at 07:32:35PM +0900, Takao Indoh wrote:
[..]
Quoted 8 lines
I'll post new patch which clears bus master bit and resets devices in second kernel.
As to the boot parameter to enable this function, you suggested using
reset_devices. I found that on a certain platform resetting devices caused PCIe error due to a hardware bug. Therefore I think we need new parameter apart fromreset_devicesto disable this function on such a machine.
Quoted 5 lines
Can you explain a bit more how the error happens. I still don't think that because of a bug in a platform somewhere we should be introducing a separate command line parameter and not reuse the exisiting one. Also you have not explained what's the bug and how a new parameter will avoid the bug.
The bug I mentioned is that ACS Violation occurs at PCIe switch when reading PCI configuration after device reset. I got information that this violation is caused by PCIe switch bug. The machine becomes fatal status by this error.
The reason why I try to introduce new parameter is that I want to avoid regression by this patch. Let's say this patch was included in kernel and its reset function was enabled by reset_devices as you said. AFAIK reset_devices is always needed for kdump, so it means that devices are always reset at kdump boot time. It causes a regression that system always becomes abnormal status when we run kdump on the machine which has a bug I mentioned.
To avoid this regression, I want to separate reset_devices from this reset function. Or how about this?
- if user specify reset_devices, devices are reset by this patch, as you said.
- To avoid a regression I said, add new parameter like "pci=noreset". If this parameter is specified, the reset function I add is disabled and we can avoid regression.
Thanks,
Takao Indoh
Quoted 32 lines · Takao Indoh
Quoted 12 lines · Vivek Goyal
On Tue, Sep 11, 2012 at 07:32:35PM +0900, Takao Indoh wrote:
[..]
Quoted 8 lines
I'll post new patch which clears bus master bit and resets devices in second kernel.
As to the boot parameter to enable this function, you suggested using
reset_devices. I found that on a certain platform resetting devices caused PCIe error due to a hardware bug. Therefore I think we need new parameter apart fromreset_devicesto disable this function on such a machine.Quoted 5 lines
Can you explain a bit more how the error happens. I still don't think that because of a bug in a platform somewhere we should be introducing a separate command line parameter and not reuse the exisiting one. Also you have not explained what's the bug and how a new parameter will avoid the bug.
The bug I mentioned is that ACS Violation occurs at PCIe switch when reading PCI configuration after device reset. I got information that this violation is caused by PCIe switch bug. The machine becomes fatal status by this error.
The reason why I try to introduce new parameter is that I want to avoid regression by this patch. Let's say this patch was included in kernel and its reset function was enabled by
reset_devicesas you said. AFAIKreset_devicesis always needed for kdump, so it means that devices are always reset at kdump boot time. It causes a regression that system always becomes abnormal status when we run kdump on the machine which has a bug I mentioned.
Quoted 7 lines
To avoid this regression, I want to separate
reset_devicesfrom this reset function. Or how about this?
- if user specifyreset_devices, devices are reset by this patch, as you said.
- To avoid a regression I said, add new parameter like "pci=noreset". If this parameter is specified, the reset function I add is disabled and we can avoid regression.
Can we identify that particular switch in code and not reset it in code. Introducing new paramenters to avoid bugs really feels odd.
Also, what was the conclusion to avoid double reset. I am assuming that we don't want to do bus level reset as well as driver level reset based on reset_devices.
Thanks
Vivek
Quoted 41 lines · Vivek Goyal
Quoted 32 lines · Takao Indoh
Quoted 12 lines · Vivek Goyal
On Tue, Sep 11, 2012 at 07:32:35PM +0900, Takao Indoh wrote:
[..]
Quoted 8 lines
I'll post new patch which clears bus master bit and resets devices in second kernel.
As to the boot parameter to enable this function, you suggested using
reset_devices. I found that on a certain platform resetting devices caused PCIe error due to a hardware bug. Therefore I think we need new parameter apart fromreset_devicesto disable this function on such a machine.Quoted 5 lines
Can you explain a bit more how the error happens. I still don't think that because of a bug in a platform somewhere we should be introducing a separate command line parameter and not reuse the exisiting one. Also you have not explained what's the bug and how a new parameter will avoid the bug.
The bug I mentioned is that ACS Violation occurs at PCIe switch when reading PCI configuration after device reset. I got information that this violation is caused by PCIe switch bug. The machine becomes fatal status by this error.
The reason why I try to introduce new parameter is that I want to avoid regression by this patch. Let's say this patch was included in kernel and its reset function was enabled by
reset_devicesas you said. AFAIKreset_devicesis always needed for kdump, so it means that devices are always reset at kdump boot time. It causes a regression that system always becomes abnormal status when we run kdump on the machine which has a bug I mentioned.Quoted 7 lines
To avoid this regression, I want to separate
reset_devicesfrom this reset function. Or how about this?
- if user specifyreset_devices, devices are reset by this patch, as you said.
- To avoid a regression I said, add new parameter like "pci=noreset". If this parameter is specified, the reset function I add is disabled and we can avoid regression.
Quoted 2 lines
Can we identify that particular switch in code and not reset it in code. Introducing new paramenters to avoid bugs really feels odd.
Maybe we can do it using PCI quirk or DMI quirk as Konrad and Don said. But I'm still thinking whether I can add boot parameter or something to disable reset function so that we can use it as workaround untill we add quirk when we find such a buggy hardware.
Quoted 3 lines
Also, what was the conclusion to avoid double reset. I am assuming that we don't want to do bus level reset as well as driver level reset based on
reset_devices.
I don't have a good idea to do it yet. Maybe we need to write bus:slot:func information to somewhere when we reset device.
Thanks,
Takao Indoh
Quoted 5 lines
As to the boot parameter to enable this function, you suggested using
reset_devices. I found that on a certain platform resetting devices caused PCIe error due to a hardware bug. Therefore I think we need new parameter apart fromreset_devicesto disable this function on such a machine.
Wouldn't a DMI quirk be better for this? That way the second kernel internally would know not to do this.
Quoted 8 lines · Konrad Rzeszutek Wilk
Quoted 5 lines
As to the boot parameter to enable this function, you suggested using
reset_devices. I found that on a certain platform resetting devices caused PCIe error due to a hardware bug. Therefore I think we need new parameter apart fromreset_devicesto disable this function on such a machine.Wouldn't a DMI quirk be better for this? That way the second kernel internally would know not to do this.
That sounds good. I'll try it, thanks.
Thanks,
Takao Indoh
Quoted 6 lines · Konrad Rzeszutek Wilk
Quoted 5 lines
As to the boot parameter to enable this function, you suggested using
reset_devices. I found that on a certain platform resetting devices caused PCIe error due to a hardware bug. Therefore I think we need new parameter apart fromreset_devicesto disable this function on such a machine.
Quoted 6 lines
Wouldn't a DMI quirk be better for this? That way the second kernel internally would know not to do this.
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
a DMI quirk for a PCIe switch? pci-quirk maybe? there is a hook in per-device pci reset code path, which could be setup for such a case.
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Quoted 13 lines · Don Dutile
Quoted 6 lines · Konrad Rzeszutek Wilk
Quoted 5 lines
As to the boot parameter to enable this function, you suggested using
reset_devices. I found that on a certain platform resetting devices caused PCIe error due to a hardware bug. Therefore I think we need new parameter apart fromreset_devicesto disable this function on such a machine.Quoted 6 lines
Wouldn't a DMI quirk be better for this? That way the second kernel internally would know not to do this.
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 3 lines
a DMI quirk for a PCIe switch? pci-quirk maybe? there is a hook in per-device pci reset code path, which could be setup for such a case.
Yep, I think early-quirk is better.
Thanks,
Takao Indoh
Quoted 26 lines · Takao Indoh
Hi all,
This patch adds kernel parameter "
reset_pcie_devices" which resets PCIe devices at boot time to address DMA problem on kdump with iommu. When this parameter is specified, a hot reset is triggered on each PCIe root port and downstream port to reset its downstream endpoint.Background:
A kdump problem about DMA has been discussed for a long time. That is, when a kernel is switched to the kdump kernel DMA derived from first kernel affects second kernel. Recently this problem surfaces when iommu is used for PCI passthrough on KVM guest. In the case of the machine I use, when intel_iommu=on is specified, DMAR error is detected in kdump kernel and PCI SERR is also detected. Finally kdump fails because some devices does not work correctly.The root cause is that ongoing DMA from first kernel causes DMAR fault because page table of DMAR is initialized while kdump kernel is booting up. Therefore to address this problem DMA needs to be stopped before DMAR is initialized at kdump kernel boot time. By this patch, PCIe devices are reset by hot reset and its DMA is stopped when
reset_pcie_devicesis specified. One problem of this solution is that VGA is reset and the monitor blacks out when the link between the port and VGA controller was reset. So this patch does not reset the port whose child endpoint is VGA device.
Quoted 4 lines
Any comments would be appreciated.
Signed-off-by Takao Indoh<[email protected]>---
Have you considered something less disruptive such as clearing the Master Enable in each endpoint's PCI Command Register ?
That should prevent DMA transactions from endpoints during the kdump and kexec, and when the driver for the device gets reconfigured, Master Enable will be set back on, but after the driver has had the opportunity to do a device-specific reset.
- Don
Quoted 91 lines
Documentation/kernel-parameters.txt | 4 + drivers/pci/quirks.c | 59 ++++++++++++++++++++++++++ 2 files changed, 63 insertions(+)Documentation/kernel-parameters.txt +4
-0@@ -2489,6 +2489,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. reset_devices [KNL] Force drivers to reset the underlying device during initialization. + reset_pcie_devices + [PCIE] Reset PCIe endpoint at boot time by sending a + hot reset to root port and downstream port + resume= [SWSUSP] Specify the partition device for software suspend Format:drivers/pci/quirks.c +59
-1@@ -32,6 +32,65 @@#include "pci.h" /* +* Reset PCIe endpoint by sending a hot reset to root port and downstream port +*/ +unsigned int reset_pcie_devices; +EXPORT_SYMBOL (reset_pcie_devices); +static int __init set_reset_pcie_devices (char *str) +{ + reset_pcie_devices =1 ; +return 1 ; +} +__setup ("reset_pcie_devices" , set_reset_pcie_devices); + +static void __devinit quirk_pcie_device_reset (struct pci_dev *dev) +{ +struct pci_bus *subordinate; +struct pci_dev *child; +u16 ctrl; + +if (!reset_pcie_devices || !pci_is_pcie (dev) || !dev->subordinate || + ((dev->pcie_type !=PCI_EXP_TYPE_ROOT_PORT )&& + (dev->pcie_type !=PCI_EXP_TYPE_DOWNSTREAM ))) +return ; + + subordinate = dev->subordinate; +list_for_each_entry (child,&subordinate->devices, bus_list) { +if ((child->pcie_type ==PCI_EXP_TYPE_UPSTREAM ) || + (child->pcie_type ==PCI_EXP_TYPE_PCI_BRIDGE ) || + ((child->class>>16 ) ==PCI_BASE_CLASS_DISPLAY )) +/* Don't reset switch, bridge, VGA device */ +return ; + } + +dev_info (&dev->dev,"Reset Secondary bus\n" ); + +list_for_each_entry (child,&subordinate->devices, bus_list) { +dev_info (&child->dev,"save state\n" ); +pci_save_state (child); + } + +/* Assert Secondary Bus Reset */ +pci_read_config_word (dev,PCI_BRIDGE_CONTROL ,&ctrl); + ctrl |=PCI_BRIDGE_CTL_BUS_RESET ; +pci_write_config_word (dev,PCI_BRIDGE_CONTROL , ctrl); + +msleep (2 ); + +/* De-assert Secondary Bus Reset */ + ctrl&= ~PCI_BRIDGE_CTL_BUS_RESET ; +pci_write_config_word (dev,PCI_BRIDGE_CONTROL , ctrl); + +msleep (200 ); + +list_for_each_entry (child,&subordinate->devices, bus_list) { +dev_info (&child->dev,"restore state\n" ); +pci_restore_state (child); + } +} +DECLARE_PCI_FIXUP_FINAL (PCI_ANY_ID ,PCI_ANY_ID , quirk_pcie_device_reset); + +/* * Decoding should be disabled for a PCI device during BAR sizing to avoid * conflict. But doing so may cause problems on host bridge and perhaps other * key system devices. For devices that need to have mmio decoding always-on, --
Quoted 3 lines
To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Hi Don,
Quoted 29 lines · Don Dutile
Quoted 28 lines · Takao Indoh
Hi all,
This patch adds kernel parameter "
reset_pcie_devices" which resets PCIe devices at boot time to address DMA problem on kdump with iommu. When this parameter is specified, a hot reset is triggered on each PCIe root port and downstream port to reset its downstream endpoint.Background:
A kdump problem about DMA has been discussed for a long time. That is, when a kernel is switched to the kdump kernel DMA derived from first kernel affects second kernel. Recently this problem surfaces when iommu is used for PCI passthrough on KVM guest. In the case of the machine I use, when intel_iommu=on is specified, DMAR error is detected in kdump kernel and PCI SERR is also detected. Finally kdump fails because some devices does not work correctly.The root cause is that ongoing DMA from first kernel causes DMAR fault because page table of DMAR is initialized while kdump kernel is booting up. Therefore to address this problem DMA needs to be stopped before DMAR is initialized at kdump kernel boot time. By this patch, PCIe devices are reset by hot reset and its DMA is stopped when
reset_pcie_devicesis specified. One problem of this solution is that VGA is reset and the monitor blacks out when the link between the port and VGA controller was reset. So this patch does not reset the port whose child endpoint is VGA device.Any comments would be appreciated.
Quoted 8 lines
Quoted 2 lines
Signed-off-by Takao Indoh<[email protected]>---
Have you considered something less disruptive such as clearing the Master Enable in each endpoint's PCI Command Register ?
That should prevent DMA transactions from endpoints during the kdump and kexec, and when the driver for the device gets reconfigured, Master Enable will be set back on, but after the driver has had the opportunity to do a device-specific reset.
Yes, that is what I tried first. First of all I found this thread.
[PATCH] Disable Bus Master on PCI device shutdown
https://lkml.org/lkml/2012/6/6/278
original patch: http://marc.info/?l=kexec&m=133546519231295&w=2
And I thought ongoing DMA could be stopped by disabling it on kdump kernel boot, but DMAR error is still found after adding quirk below.
In this thread, AER link reset was also suggested, so I got the idea to reset root port and downstream port.
Thanks,
Takao Indoh
drivers/pci/quirks.c +16 -0
@@ -31,6 +31,22 @@#include <asm/dma.h> /* isa_dma_bridge_buggy */ #include "pci.h" +static void test_pci_device_reset (struct pci_dev *dev) +{ +u16 pci_command; + +if (!reset_devices) +return ; + +pci_read_config_word (dev,PCI_COMMAND , &pci_command); +if (pci_command &PCI_COMMAND_MASTER ) { +dev_info (&dev->dev,"DEBUG: Disable Bus Master bit\n" ); + pci_command &= ~PCI_COMMAND_MASTER ; +pci_write_config_word (dev,PCI_COMMAND , pci_command); + } +} +DECLARE_PCI_FIXUP_EARLY (PCI_ANY_ID ,PCI_ANY_ID , test_pci_device_reset); +/* * Decoding should be disabled for a PCI device during BAR sizing to avoid * conflict. But doing so may cause problems on host bridge and perhaps other