]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob
eb0b6feceecc5b60cfc33d2e7118104db27f2ff1
[thirdparty/kernel/stable-queue.git] /
1 From ac9184fbb8478dab4a0724b279f94956b69be827 Mon Sep 17 00:00:00 2001
2 From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
3 Date: Tue, 2 Jan 2024 20:01:50 +0900
4 Subject: firewire: ohci: suppress unexpected system reboot in AMD Ryzen machines and ASM108x/VT630x PCIe cards
5
6 From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
7
8 commit ac9184fbb8478dab4a0724b279f94956b69be827 upstream.
9
10 VIA VT6306/6307/6308 provides PCI interface compliant to 1394 OHCI. When
11 the hardware is combined with Asmedia ASM1083/1085 PCIe-to-PCI bus bridge,
12 it appears that accesses to its 'Isochronous Cycle Timer' register (offset
13 0xf0 on PCI memory space) often causes unexpected system reboot in any
14 type of AMD Ryzen machine (both 0x17 and 0x19 families). It does not
15 appears in the other type of machine (AMD pre-Ryzen machine, Intel
16 machine, at least), or in the other OHCI 1394 hardware (e.g. Texas
17 Instruments).
18
19 The issue explicitly appears at a commit dcadfd7f7c74 ("firewire: core:
20 use union for callback of transaction completion") added to v6.5 kernel.
21 It changed 1394 OHCI driver to access to the register every time to
22 dispatch local asynchronous transaction. However, the issue exists in
23 older version of kernel as long as it runs in AMD Ryzen machine, since
24 the access to the register is required to maintain bus time. It is not
25 hard to imagine that users experience the unexpected system reboot when
26 generating bus reset by plugging any devices in, or reading the register
27 by time-aware application programs; e.g. audio sample processing.
28
29 This commit suppresses the unexpected system reboot in the combination of
30 hardware. It avoids the access itself. As a result, the software stack can
31 not provide the hardware time anymore to unit drivers, userspace
32 applications, and nodes in the same IEEE 1394 bus. It brings apparent
33 disadvantage since time-aware application programs require it, while
34 time-unaware applications are available again; e.g. sbp2.
35
36 Cc: stable@vger.kernel.org
37 Reported-by: Jiri Slaby <jirislaby@kernel.org>
38 Closes: https://bugzilla.suse.com/show_bug.cgi?id=1215436
39 Reported-by: Mario Limonciello <mario.limonciello@amd.com>
40 Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217994
41 Reported-by: Tobias Gruetzmacher <tobias-lists@23.gs>
42 Closes: https://sourceforge.net/p/linux1394/mailman/message/58711901/
43 Closes: https://bugzilla.redhat.com/show_bug.cgi?id=2240973
44 Closes: https://bugs.launchpad.net/linux/+bug/2043905
45 Link: https://lore.kernel.org/r/20240102110150.244475-1-o-takashi@sakamocchi.jp
46 Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
47 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
48 ---
49 drivers/firewire/ohci.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++
50 1 file changed, 51 insertions(+)
51
52 --- a/drivers/firewire/ohci.c
53 +++ b/drivers/firewire/ohci.c
54 @@ -279,6 +279,51 @@ static char ohci_driver_name[] = KBUILD_
55 #define QUIRK_TI_SLLZ059 0x20
56 #define QUIRK_IR_WAKE 0x40
57
58 +// On PCI Express Root Complex in any type of AMD Ryzen machine, VIA VT6306/6307/6308 with Asmedia
59 +// ASM1083/1085 brings an inconvenience that the read accesses to 'Isochronous Cycle Timer' register
60 +// (at offset 0xf0 in PCI I/O space) often causes unexpected system reboot. The mechanism is not
61 +// clear, since the read access to the other registers is enough safe; e.g. 'Node ID' register,
62 +// while it is probable due to detection of any type of PCIe error.
63 +#define QUIRK_REBOOT_BY_CYCLE_TIMER_READ 0x80000000
64 +
65 +#if IS_ENABLED(CONFIG_X86)
66 +
67 +static bool has_reboot_by_cycle_timer_read_quirk(const struct fw_ohci *ohci)
68 +{
69 + return !!(ohci->quirks & QUIRK_REBOOT_BY_CYCLE_TIMER_READ);
70 +}
71 +
72 +#define PCI_DEVICE_ID_ASMEDIA_ASM108X 0x1080
73 +
74 +static bool detect_vt630x_with_asm1083_on_amd_ryzen_machine(const struct pci_dev *pdev)
75 +{
76 + const struct pci_dev *pcie_to_pci_bridge;
77 +
78 + // Detect any type of AMD Ryzen machine.
79 + if (!static_cpu_has(X86_FEATURE_ZEN))
80 + return false;
81 +
82 + // Detect VIA VT6306/6307/6308.
83 + if (pdev->vendor != PCI_VENDOR_ID_VIA)
84 + return false;
85 + if (pdev->device != PCI_DEVICE_ID_VIA_VT630X)
86 + return false;
87 +
88 + // Detect Asmedia ASM1083/1085.
89 + pcie_to_pci_bridge = pdev->bus->self;
90 + if (pcie_to_pci_bridge->vendor != PCI_VENDOR_ID_ASMEDIA)
91 + return false;
92 + if (pcie_to_pci_bridge->device != PCI_DEVICE_ID_ASMEDIA_ASM108X)
93 + return false;
94 +
95 + return true;
96 +}
97 +
98 +#else
99 +#define has_reboot_by_cycle_timer_read_quirk(ohci) false
100 +#define detect_vt630x_with_asm1083_on_amd_ryzen_machine(pdev) false
101 +#endif
102 +
103 /* In case of multiple matches in ohci_quirks[], only the first one is used. */
104 static const struct {
105 unsigned short vendor, device, revision, flags;
106 @@ -1717,6 +1762,9 @@ static u32 get_cycle_time(struct fw_ohci
107 s32 diff01, diff12;
108 int i;
109
110 + if (has_reboot_by_cycle_timer_read_quirk(ohci))
111 + return 0;
112 +
113 c2 = reg_read(ohci, OHCI1394_IsochronousCycleTimer);
114
115 if (ohci->quirks & QUIRK_CYCLE_TIMER) {
116 @@ -3619,6 +3667,9 @@ static int pci_probe(struct pci_dev *dev
117 if (param_quirks)
118 ohci->quirks = param_quirks;
119
120 + if (detect_vt630x_with_asm1083_on_amd_ryzen_machine(dev))
121 + ohci->quirks |= QUIRK_REBOOT_BY_CYCLE_TIMER_READ;
122 +
123 /*
124 * Because dma_alloc_coherent() allocates at least one page,
125 * we save space by using a common buffer for the AR request/