Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

intel_th: Disallow multi mode on devices where it's broken

Some versions of Intel TH have an issue that prevents the multi mode of
MSU from working correctly, resulting in no trace data and potentially
stuck MSU pipeline.

Disable multi mode on such devices.

Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20200317062215.15598-2-alexander.shishkin@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Alexander Shishkin and committed by
Greg Kroah-Hartman
397c7729 2cca608a

+17 -4
+2
drivers/hwtracing/intel_th/intel_th.h
··· 47 47 /** 48 48 * struct intel_th_drvdata - describes hardware capabilities and quirks 49 49 * @tscu_enable: device needs SW to enable time stamping unit 50 + * @multi_is_broken: device has multiblock mode is broken 50 51 * @has_mintctl: device has interrupt control (MINTCTL) register 51 52 * @host_mode_only: device can only operate in 'host debugger' mode 52 53 */ 53 54 struct intel_th_drvdata { 54 55 unsigned int tscu_enable : 1, 56 + multi_is_broken : 1, 55 57 has_mintctl : 1, 56 58 host_mode_only : 1; 57 59 };
+9 -2
drivers/hwtracing/intel_th/msu.c
··· 157 157 /* config */ 158 158 unsigned int enabled : 1, 159 159 wrap : 1, 160 - do_irq : 1; 160 + do_irq : 1, 161 + multi_is_broken : 1; 161 162 unsigned int mode; 162 163 unsigned int burst_len; 163 164 unsigned int index; ··· 1665 1664 { 1666 1665 atomic_set(&msc->user_count, -1); 1667 1666 1668 - msc->mode = MSC_MODE_MULTI; 1667 + msc->mode = msc->multi_is_broken ? MSC_MODE_SINGLE : MSC_MODE_MULTI; 1669 1668 mutex_init(&msc->buf_mutex); 1670 1669 INIT_LIST_HEAD(&msc->win_list); 1671 1670 INIT_LIST_HEAD(&msc->iter_list); ··· 1877 1876 return -EINVAL; 1878 1877 1879 1878 found: 1879 + if (i == MSC_MODE_MULTI && msc->multi_is_broken) 1880 + return -EOPNOTSUPP; 1881 + 1880 1882 mutex_lock(&msc->buf_mutex); 1881 1883 ret = 0; 1882 1884 ··· 2085 2081 res = intel_th_device_get_resource(thdev, IORESOURCE_IRQ, 1); 2086 2082 if (!res) 2087 2083 msc->do_irq = 1; 2084 + 2085 + if (INTEL_TH_CAP(to_intel_th(thdev), multi_is_broken)) 2086 + msc->multi_is_broken = 1; 2088 2087 2089 2088 msc->index = thdev->id; 2090 2089
+6 -2
drivers/hwtracing/intel_th/pci.c
··· 120 120 pci_free_irq_vectors(pdev); 121 121 } 122 122 123 + static const struct intel_th_drvdata intel_th_1x_multi_is_broken = { 124 + .multi_is_broken = 1, 125 + }; 126 + 123 127 static const struct intel_th_drvdata intel_th_2x = { 124 128 .tscu_enable = 1, 125 129 .has_mintctl = 1, ··· 156 152 { 157 153 /* Kaby Lake PCH-H */ 158 154 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa2a6), 159 - .driver_data = (kernel_ulong_t)0, 155 + .driver_data = (kernel_ulong_t)&intel_th_1x_multi_is_broken, 160 156 }, 161 157 { 162 158 /* Denverton */ ··· 211 207 { 212 208 /* Comet Lake PCH-V */ 213 209 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa3a6), 214 - .driver_data = (kernel_ulong_t)&intel_th_2x, 210 + .driver_data = (kernel_ulong_t)&intel_th_1x_multi_is_broken, 215 211 }, 216 212 { 217 213 /* Ice Lake NNPI */