diff --git a/patches.suse/usb-chipidea-core-fix-possible-concurrent-when-switc.patch b/patches.suse/usb-chipidea-core-fix-possible-concurrent-when-switc.patch new file mode 100644 index 0000000..93ea4ec --- /dev/null +++ b/patches.suse/usb-chipidea-core-fix-possible-concurrent-when-switc.patch @@ -0,0 +1,93 @@ +From 451b15ed138ec15bffbebb58a00ebdd884c3e659 Mon Sep 17 00:00:00 2001 +From: Xu Yang +Date: Fri, 17 Mar 2023 14:15:16 +0800 +Subject: [PATCH] usb: chipidea: core: fix possible concurrent when switch role +Git-commit: 451b15ed138ec15bffbebb58a00ebdd884c3e659 +References: git-fixes +Patch-mainline: v6.3-rc4 + +The user may call role_store() when driver is handling +ci_handle_id_switch() which is triggerred by otg event or power lost +event. Unfortunately, the controller may go into chaos in this case. +Fix this by protecting it with mutex lock. + +Fixes: a932a8041ff9 ("usb: chipidea: core: add sysfs group") +cc: +Acked-by: Peter Chen +Signed-off-by: Xu Yang +Link: https://lore.kernel.org/r/20230317061516.2451728-2-xu.yang_2@nxp.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/chipidea/ci.h | 2 ++ + drivers/usb/chipidea/core.c | 4 ++++ + drivers/usb/chipidea/otg.c | 5 ++++- + 3 files changed, 10 insertions(+), 1 deletion(-) + +--- a/drivers/usb/chipidea/ci.h ++++ b/drivers/usb/chipidea/ci.h +@@ -205,6 +205,7 @@ struct hw_bank { + * @in_lpm: if the core in low power mode + * @wakeup_int: if wakeup interrupt occur + * @rev: The revision number for controller ++ * @mutex: protect code from concorrent running when doing role switch + */ + struct ci_hdrc { + struct device *dev; +@@ -259,6 +260,7 @@ struct ci_hdrc { + bool in_lpm; + bool wakeup_int; + enum ci_revision rev; ++ struct mutex mutex; + }; + + static inline struct ci_role_driver *ci_role(struct ci_hdrc *ci) +--- a/drivers/usb/chipidea/core.c ++++ b/drivers/usb/chipidea/core.c +@@ -878,6 +878,8 @@ static ssize_t ci_role_store(struct devi + if (role == CI_ROLE_END || role == ci->role) + return -EINVAL; + ++ mutex_lock(&ci->mutex); ++ + pm_runtime_get_sync(dev); + disable_irq(ci->irq); + ci_role_stop(ci); +@@ -886,6 +888,7 @@ static ssize_t ci_role_store(struct devi + ci_handle_vbus_change(ci); + enable_irq(ci->irq); + pm_runtime_put_sync(dev); ++ mutex_unlock(&ci->mutex); + + return (ret == 0) ? n : ret; + } +@@ -924,6 +927,7 @@ static int ci_hdrc_probe(struct platform + return -ENOMEM; + + spin_lock_init(&ci->lock); ++ mutex_init(&ci->mutex); + ci->dev = dev; + ci->platdata = dev_get_platdata(dev); + ci->imx28_write_fix = !!(ci->platdata->flags & +--- a/drivers/usb/chipidea/otg.c ++++ b/drivers/usb/chipidea/otg.c +@@ -167,8 +167,10 @@ static int hw_wait_vbus_lower_bsv(struct + + static void ci_handle_id_switch(struct ci_hdrc *ci) + { +- enum ci_role role = ci_otg_role(ci); ++ enum ci_role role; + ++ mutex_lock(&ci->mutex); ++ role = ci_otg_role(ci); + if (role != ci->role) { + dev_dbg(ci->dev, "switching from %s to %s\n", + ci_role(ci)->name, ci->roles[role]->name); +@@ -191,6 +193,7 @@ static void ci_handle_id_switch(struct c + if (role == CI_ROLE_GADGET) + ci_handle_vbus_change(ci); + } ++ mutex_unlock(&ci->mutex); + } + /** + * ci_otg_work - perform otg (vbus/id) event handle diff --git a/series.conf b/series.conf index 66837c4..62a43f4 100644 --- a/series.conf +++ b/series.conf @@ -63250,6 +63250,7 @@ patches.suse/net-usb-lan78xx-Limit-packet-length-to-skb-len.patch patches.suse/Bluetooth-btsdio-fix-use-after-free-bug-in-btsdio_re.patch patches.suse/power-supply-da9150-Fix-use-after-free-bug-in-da9150.patch + patches.suse/usb-chipidea-core-fix-possible-concurrent-when-switc.patch patches.suse/s390-vfio-ap-fix-memory-leak-in-vfio_ap-device-drive.patch patches.suse/NFSv4-Fix-hangs-when-recovering-open-state-after-a-s.patch patches.suse/ring-buffer-Fix-race-while-reader-and-writer-are-on-the-same-page.patch