diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/4123-Fix-to-the-crash-observed-when-the-following-operati.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/4123-Fix-to-the-crash-observed-when-the-following-operati.patch | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/4123-Fix-to-the-crash-observed-when-the-following-operati.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/4123-Fix-to-the-crash-observed-when-the-following-operati.patch new file mode 100644 index 00000000..0b49c20a --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/4123-Fix-to-the-crash-observed-when-the-following-operati.patch @@ -0,0 +1,189 @@ +From 6e99456ad3089ecf55dcf73d8162defdc637fa88 Mon Sep 17 00:00:00 2001 +From: Sudheesh Mavila <sudheesh.mavila@amd.com> +Date: Mon, 20 Aug 2018 00:18:38 +0530 +Subject: [PATCH 4123/4131] Fix to the crash observed when the following + operations are performed. write and read an i2c device from i2c1 and then + i2c0 - works write to a device in i2c1 - crash happens because mp2 gives a + wrong interrupt Write to MP2 device is performed but the interrupt received + is for read completion + +[ 493.360134] in write +[ 493.362745] BUG: unable to handle kernel NULL pointer dereference at (null) +[ 493.370643] IP: [<ffffffffc0768181>] i2c_amd_read_completion+0x91/0xe0 [i2c_amd_platdrv] +[ 493.378779] PGD 2f92ad067 [ 493.381322] PUD 2c4243067 +PMD 0 [ 493.384596] +[ 493.386107] Oops: 0002 [#1] SMP +[ 493.389259] Modules linked in: i2c_amd_platdrv(E) marvell binfmt_misc nls_iso8859_1 +pl2303 usbserial amd64_edac_mod edac_mce_amd edac_core snd_hda_codec_hdmi kvm irqbypass +snd_hda_intel snd_hda_codec snd_hda_core snd_hwdep snd_pcm crct10dif_pclmul crc32_pclmul +ghash_clmulni_intel snd_seq_midi snd_seq_midi_event joydev input_leds aesni_intel snd_rawmidi snd_seq aes_x86_64 snd_seq_device snd_timer lrw snd_pci_acp3x snd gf128mul soundcore glue_helper i2c_amd_pci_mp2(E) ablk_helper cryptd shpchp i2c_designware_platform i2c_piix4 i2c_designware_core mac_hid parport_pc ppdev lp parport autofs4 amdkfd amd_iommu_v2 mmc_block hid_generic amdgpu chash i2c_algo_bit ttm drm_kms_helper syscopyarea sysfillrect sysimgblt usbhid fb_sys_fops ixgbe dca amd_xgbe ahci ptp drm sdhci_acpi hid libahci pps_core mdio video fjes sdhci +[ 493.462798] CPU: 1 PID: 371 Comm: kworker/1:2 Tainted: G E 4.9.0-2018_30_staging+ #71 +[ 493.471769] Hardware name: AMD Dibbler/Dibbler, BIOS RDB1106B 07/02/2018 +[ 493.478486] Workqueue: events amd_mp2_pci_work [i2c_amd_pci_mp2] +[ 493.484526] task: ffff9f3d36bf2ac0 task.stack: ffffbdfac21e4000 +[ 493.490457] RIP: 0010:[<ffffffffc0768181>] [<ffffffffc0768181>] i2c_amd_read_completion+0x91/0xe0 [i2c_amd_platdrv] +[ 493.501014] RSP: 0018:ffffbdfac21e7e08 EFLAGS: 00010246 +[ 493.506337] RAX: 0000000000000001 RBX: ffff9f3d40998f00 RCX: 0000000000000000 +[ 493.513481] RDX: 0000000000000000 RSI: ffff9f3d3b46da10 RDI: 0000000000060001 +[ 493.520624] RBP: ffffbdfac21e7e08 R08: ffff9f3d39db1818 R09: 0000000000000000 +[ 493.527771] R10: 00000000ffffffff R11: 0000000000000eb5 R12: ffff9f3d43259180 +[ 493.534915] R13: ffff9f3d4325da00 R14: 0000000000000040 R15: ffff9f3d380054b0 +[ 493.542061] FS: 0000000000000000(0000) GS:ffff9f3d43240000(0000) knlGS:0000000000000000 +[ 493.550162] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 493.555918] CR2: 0000000000000000 CR3: 00000002fe0a7000 CR4: 00000000003406f0 +[ 493.563064] Stack: +[ 493.565087] ffffbdfac21e7e18 ffffffffc034d202 ffffbdfac21e7e58 ffffffffbb0a0641 +[ 493.572587] 0000000000000000 ffff9f3d43259180 ffff9f3d40998f30 0000000000000008 +[ 493.580096] ffff9f3d432591a0 ffff9f3d40998f00 ffffbdfac21e7ec0 ffffffffbb0a09ab +[ 493.587600] Call Trace: +[ 493.590059] [<ffffffffc034d202>] amd_mp2_pci_work+0xa2/0x130 [i2c_amd_pci_mp2] +[ 493.597382] [<ffffffffbb0a0641>] process_one_work+0x171/0x490 +[ 493.603225] [<ffffffffbb0a09ab>] worker_thread+0x4b/0x500 +[ 493.608719] [<ffffffffbb0a0960>] ? process_one_work+0x490/0x490 +[ 493.614736] [<ffffffffbb0a0960>] ? process_one_work+0x490/0x490 +[ 493.620753] [<ffffffffbb08a894>] ? SyS_exit_group+0x14/0x20 +[ 493.626424] [<ffffffffbb0a6c5b>] kthread+0xdb/0x100 +[ 493.631401] [<ffffffffbb0a6b80>] ? kthread_park+0x60/0x60 +[ 493.636900] [<ffffffffbb003b83>] ? do_syscall_64+0x73/0xe0 +[ 493.642486] [<ffffffffbb874774>] ret_from_fork+0x44/0x70 +[ 493.647894] Code: 03 f3 48 a5 31 d2 49 8d b8 68 04 00 00 66 41 89 90 92 04 00 00 e8 10 2f 96 fa 31 c0 5d c3 a8 04 75 46 85 c0 74 de 0f b6 16 a8 02 <88> 11 74 d5 89 c2 0f b7 44 16 fe 66 89 44 11 fe eb c7 83 f8 08 +[ 493.668399] RIP [<ffffffffc0768181>] i2c_amd_read_completion+0x91/0xe0 [i2c_amd_platdrv] +[ 493.676623] RSP <ffffbdfac21e7e08> +[ 493.680125] CR2: 0000000000000000 +[ 493.685840] ---[ end trace 7505e21302a270d5 ]--- +[ 493.690480] BUG: unable to handle kernel paging request at 00000000ee1d23ba +[ 493.697502] IP:[ 493.697968] in write +[ 493.702151] [<ffffffffbb0ca68e>] __wake_up_common+0x2e/0x90 +[ 493.708523] PGD 2f92ad067 [ 493.711069] PUD 0 +[ 493.713785] +[ 493.715961] Oops: 0000 [#2] SMP + +Signed-off-by: Sudheesh Mavila <sudheesh.mavila@amd.com> +--- + drivers/i2c/busses/i2c-amd-pci-mp2.c | 50 +++++++++++++++++++++++++----------- + drivers/i2c/busses/i2c-amd-pci-mp2.h | 2 +- + 2 files changed, 36 insertions(+), 16 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-amd-pci-mp2.c b/drivers/i2c/busses/i2c-amd-pci-mp2.c +index e8c58c7..d313435 100644 +--- a/drivers/i2c/busses/i2c-amd-pci-mp2.c ++++ b/drivers/i2c/busses/i2c-amd-pci-mp2.c +@@ -76,6 +76,7 @@ int amd_mp2_connect(struct pci_dev *dev, + dev_dbg(ndev_dev(privdata), "%s addr: %x id: %d\n", __func__, + connect_cfg.dev_addr, connect_cfg.bus_id); + ++ privdata->requested[connect_cfg.bus_id] = true; + i2c_cmd_base.ul = 0; + i2c_cmd_base.s.i2c_cmd = i2c_enable; + i2c_cmd_base.s.bus_id = connect_cfg.bus_id; +@@ -99,11 +100,12 @@ int amd_mp2_read(struct pci_dev *dev, struct i2c_read_config read_cfg) + { + struct amd_mp2_dev *privdata = pci_get_drvdata(dev); + union i2c_cmd_base i2c_cmd_base; +- ++ int busid = read_cfg.bus_id; ++ + dev_dbg(ndev_dev(privdata), "%s addr: %x id: %d\n", __func__, + read_cfg.dev_addr, read_cfg.bus_id); + +- privdata->requested = true; ++ privdata->requested[busid] = true; + i2c_cmd_base.ul = 0; + i2c_cmd_base.s.i2c_cmd = i2c_read; + i2c_cmd_base.s.dev_addr = read_cfg.dev_addr; +@@ -166,8 +168,10 @@ int amd_mp2_write(struct pci_dev *dev, struct i2c_write_config write_cfg) + struct amd_mp2_dev *privdata = pci_get_drvdata(dev); + union i2c_cmd_base i2c_cmd_base; + int i = 0; ++ int busid = write_cfg.bus_id; + +- privdata->requested = true; ++ privdata->requested[busid] = true; ++ + dev_dbg(ndev_dev(privdata), "%s addr: %x id: %d\n", __func__, + write_cfg.dev_addr, write_cfg.bus_id); + +@@ -292,31 +296,46 @@ static irqreturn_t amd_mp2_irq_isr(int irq, void *dev) + { + struct amd_mp2_dev *privdata = dev; + u32 val = 0; ++ int busid = i2c_bus_max; + unsigned long flags; + ++ ++ if (!privdata->ops) { ++ writel(0, privdata->mmio + AMD_P2C_MSG_INTEN); ++ return IRQ_HANDLED; ++ } + raw_spin_lock_irqsave(&privdata->lock, flags); + val = readl(privdata->mmio + AMD_P2C_MSG1); + if (val != 0) { + writel(0, privdata->mmio + AMD_P2C_MSG_INTEN); +- privdata->eventval.base.ul = val; +- } else { ++ busid = i2c_bus_0; ++ ++ if (privdata->requested[i2c_bus_0] ) { ++ privdata->eventval.base.ul = val; ++ privdata->requested[i2c_bus_0] = false; ++ raw_spin_unlock_irqrestore(&privdata->lock, flags); ++ schedule_delayed_work(&privdata->work, 0); ++ return IRQ_HANDLED; ++ } ++ } ++ + val = readl(privdata->mmio + AMD_P2C_MSG2); + if (val != 0) { + writel(0, privdata->mmio + AMD_P2C_MSG_INTEN); ++ busid = i2c_bus_1; ++ if (privdata->requested[i2c_bus_1] ) { + privdata->eventval.base.ul = val; ++ privdata->requested[i2c_bus_1] = false; ++ raw_spin_unlock_irqrestore(&privdata->lock, flags); ++ schedule_delayed_work(&privdata->work, 0); ++ return IRQ_HANDLED; + } + } + ++ if(busid == i2c_bus_max) { ++ writel(0, privdata->mmio + AMD_P2C_MSG_INTEN); ++ } + raw_spin_unlock_irqrestore(&privdata->lock, flags); +- if (!privdata->ops) +- return IRQ_NONE; +- +- if (!privdata->requested) +- return IRQ_HANDLED; +- +- privdata->requested = false; +- schedule_delayed_work(&privdata->work, 0); +- + return IRQ_HANDLED; + } + +@@ -495,7 +514,8 @@ static int amd_mp2_pci_init(struct amd_mp2_dev *privdata, struct pci_dev *pdev) + /* Try to set up intx irq */ + pci_intx(pdev, 1); + privdata->eventval.buf = NULL; +- privdata->requested = false; ++ privdata->requested[i2c_bus_0] = false; ++ privdata->requested[i2c_bus_1] = false; + raw_spin_lock_init(&privdata->lock); + rc = request_irq(pdev->irq, amd_mp2_irq_isr, IRQF_SHARED, "mp2_irq_isr", + privdata); +diff --git a/drivers/i2c/busses/i2c-amd-pci-mp2.h b/drivers/i2c/busses/i2c-amd-pci-mp2.h +index d4b343a..8fef977 100644 +--- a/drivers/i2c/busses/i2c-amd-pci-mp2.h ++++ b/drivers/i2c/busses/i2c-amd-pci-mp2.h +@@ -233,7 +233,7 @@ struct amd_mp2_dev { + const struct amd_i2c_pci_ops *ops; + struct delayed_work work; + u8 i2c_dev_id; +- bool requested; ++ bool requested[i2c_bus_max]; + raw_spinlock_t lock; + }; + +-- +2.7.4 + |