Hi, all
We hit hard-lockups when the Intel IOMMU waits indefinitely for an ATS invalidation
that cannot complete, especially under GDR high-load conditions.
1. Hard-lock when a passthrough PCIe NIC with ATS enabled link-down in Intel IOMMU
non-scalable mode. Two scenarios exist: NIC link-down with an explicit link-down
event and link-down without any event.
a) NIC link-down with an explicit link-dow event.
Call Trace:
qi_submit_sync
qi_flush_dev_iotlb
__context_flush_dev_iotlb.part.0
domain_context_clear_one_cb
pci_for_each_dma_alias
device_block_translation
blocking_domain_attach_dev
iommu_deinit_device
__iommu_group_remove_device
iommu_release_device
iommu_bus_notifier
blocking_notifier_call_chain
bus_notify
device_del
pci_remove_bus_device
pci_stop_and_remove_bus_device
pciehp_unconfigure_device
pciehp_disable_slot
pciehp_handle_presence_or_link_change
pciehp_ist
b) NIC link-down without an event - hard-lock on VM destroy.
Call Trace:
qi_submit_sync
qi_flush_dev_iotlb
__context_flush_dev_iotlb.part.0
domain_context_clear_one_cb
pci_for_each_dma_alias
device_block_translation
blocking_domain_attach_dev
__iommu_attach_device
__iommu_device_set_domain
__iommu_group_set_domain_internal
iommu_detach_group
vfio_iommu_type1_detach_group
vfio_group_detach_container
vfio_group_fops_release
__fput
2. Hard-lock when a passthrough PCIe NIC with ATS enabled link-down in Intel IOMMU
scalable mode; NIC link-down without an event hard-locks on VM destroy.
Call Trace:
qi_submit_sync
qi_flush_dev_iotlb
intel_pasid_tear_down_entry
device_block_translation
blocking_domain_attach_dev
__iommu_attach_device
__iommu_device_set_domain
__iommu_group_set_domain_internal
iommu_detach_group
vfio_iommu_type1_detach_group
vfio_group_detach_container
vfio_group_fops_release
__fput
Fix both issues with two patches:
1. Skip dev-IOTLB flush for inaccessible devices in __context_flush_dev_iotlb() using
pci_device_is_present().
2. Use pci_device_is_present() instead of pci_dev_is_disconnected() to decide when to
skip ATS invalidation in devtlb_invalidation_with_pasid().
Best Regards,
Jinhui
---
v1: https://lore.kernel.org/all/20251210171431.1589-1-guojinhui.liam@bytedance.…
Changelog in v1 -> v2 (suggested by Baolu Lu)
- Simplify the pci_device_is_present() check in __context_flush_dev_iotlb().
- Add Cc: stable(a)vger.kernel.org to both patches.
Jinhui Guo (2):
iommu/vt-d: Skip dev-iotlb flush for inaccessible PCIe device without
scalable mode
iommu/vt-d: Flush dev-IOTLB only when PCIe device is accessible in
scalable mode
drivers/iommu/intel/pasid.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
--
2.20.1
Commit under Fixes enabled loadable module support for the driver under
the assumption that it shall be the sole user of the Cadence Host and
Endpoint library APIs. This assumption guarantees that we won't end up
in a case where the driver is built-in and the library support is built
as a loadable module.
With the introduction of [1], this assumption is no longer valid. The
SG2042 driver could be built as a loadable module, implying that the
Cadence Host library is also selected as a loadable module. However, the
pci-j721e.c driver could be built-in as indicated by CONFIG_PCI_J721E=y
due to which the Cadence Endpoint library is built-in. Despite the
library drivers being built as specified by their respective consumers,
since the 'pci-j721e.c' driver has references to the Cadence Host
library APIs as well, we run into a build error as reported at [0].
Fix this by adding config guards as a temporary workaround. The proper
fix is to split the 'pci-j721e.c' driver into independent Host and
Endpoint drivers as aligned at [2].
Fixes: a2790bf81f0f ("PCI: j721e: Add support to build as a loadable module")
Reported-by: kernel test robot <lkp(a)intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202511111705.MZ7ls8Hm-lkp@intel.com/
Cc: <stable(a)vger.kernel.org>
[0]: https://lore.kernel.org/r/202511111705.MZ7ls8Hm-lkp@intel.com/
[1]: commit 1c72774df028 ("PCI: sg2042: Add Sophgo SG2042 PCIe driver")
[2]: https://lore.kernel.org/r/37f6f8ce-12b2-44ee-a94c-f21b29c98821@app.fastmail…
Suggested-by: Arnd Bergmann <arnd(a)arndb.de>
Signed-off-by: Siddharth Vadapalli <s-vadapalli(a)ti.com>
---
drivers/pci/controller/cadence/pci-j721e.c | 43 +++++++++++++---------
1 file changed, 26 insertions(+), 17 deletions(-)
diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
index 5bc5ab20aa6d..67c5e02afccf 100644
--- a/drivers/pci/controller/cadence/pci-j721e.c
+++ b/drivers/pci/controller/cadence/pci-j721e.c
@@ -628,10 +628,12 @@ static int j721e_pcie_probe(struct platform_device *pdev)
gpiod_set_value_cansleep(gpiod, 1);
}
- ret = cdns_pcie_host_setup(rc);
- if (ret < 0) {
- clk_disable_unprepare(pcie->refclk);
- goto err_pcie_setup;
+ if (IS_ENABLED(CONFIG_PCI_J721E_HOST)) {
+ ret = cdns_pcie_host_setup(rc);
+ if (ret < 0) {
+ clk_disable_unprepare(pcie->refclk);
+ goto err_pcie_setup;
+ }
}
break;
@@ -642,9 +644,11 @@ static int j721e_pcie_probe(struct platform_device *pdev)
goto err_get_sync;
}
- ret = cdns_pcie_ep_setup(ep);
- if (ret < 0)
- goto err_pcie_setup;
+ if (IS_ENABLED(CONFIG_PCI_J721E_EP)) {
+ ret = cdns_pcie_ep_setup(ep);
+ if (ret < 0)
+ goto err_pcie_setup;
+ }
break;
}
@@ -669,10 +673,11 @@ static void j721e_pcie_remove(struct platform_device *pdev)
struct cdns_pcie_ep *ep;
struct cdns_pcie_rc *rc;
- if (pcie->mode == PCI_MODE_RC) {
+ if (IS_ENABLED(CONFIG_PCI_J721E_HOST) &&
+ pcie->mode == PCI_MODE_RC) {
rc = container_of(cdns_pcie, struct cdns_pcie_rc, pcie);
cdns_pcie_host_disable(rc);
- } else {
+ } else if (IS_ENABLED(CONFIG_PCI_J721E_EP)) {
ep = container_of(cdns_pcie, struct cdns_pcie_ep, pcie);
cdns_pcie_ep_disable(ep);
}
@@ -739,10 +744,12 @@ static int j721e_pcie_resume_noirq(struct device *dev)
gpiod_set_value_cansleep(pcie->reset_gpio, 1);
}
- ret = cdns_pcie_host_link_setup(rc);
- if (ret < 0) {
- clk_disable_unprepare(pcie->refclk);
- return ret;
+ if (IS_ENABLED(CONFIG_PCI_J721E_HOST)) {
+ ret = cdns_pcie_host_link_setup(rc);
+ if (ret < 0) {
+ clk_disable_unprepare(pcie->refclk);
+ return ret;
+ }
}
/*
@@ -752,10 +759,12 @@ static int j721e_pcie_resume_noirq(struct device *dev)
for (enum cdns_pcie_rp_bar bar = RP_BAR0; bar <= RP_NO_BAR; bar++)
rc->avail_ib_bar[bar] = true;
- ret = cdns_pcie_host_init(rc);
- if (ret) {
- clk_disable_unprepare(pcie->refclk);
- return ret;
+ if (IS_ENABLED(CONFIG_PCI_J721E_HOST)) {
+ ret = cdns_pcie_host_init(rc);
+ if (ret) {
+ clk_disable_unprepare(pcie->refclk);
+ return ret;
+ }
}
}
--
2.51.1
From: Li Nan <linan122(a)huawei.com>
commit 9c47127a807da3e36ce80f7c83a1134a291fc021 upstream.
Raid checks if pad3 is zero when loading superblock from disk. Arrays
created with new features may fail to assemble on old kernels as pad3
is used.
Add module parameter check_new_feature to bypass this check.
Link: https://lore.kernel.org/linux-raid/20251103125757.1405796-5-linan666@huawei…
Signed-off-by: Li Nan <linan122(a)huawei.com>
Reviewed-by: Xiao Ni <xni(a)redhat.com>
Signed-off-by: Yu Kuai <yukuai(a)fnnas.com>
---
drivers/md/md.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 4e033c26fdd4..9d9cb7e1e6e8 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -340,6 +340,7 @@ static int start_readonly;
*/
static bool create_on_open = true;
static bool legacy_async_del_gendisk = true;
+static bool check_new_feature = true;
/*
* We have a system wide 'event count' that is incremented
@@ -1752,9 +1753,13 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_
}
if (sb->pad0 ||
sb->pad3[0] ||
- memcmp(sb->pad3, sb->pad3+1, sizeof(sb->pad3) - sizeof(sb->pad3[1])))
- /* Some padding is non-zero, might be a new feature */
- return -EINVAL;
+ memcmp(sb->pad3, sb->pad3+1, sizeof(sb->pad3) - sizeof(sb->pad3[1]))) {
+ pr_warn("Some padding is non-zero on %pg, might be a new feature\n",
+ rdev->bdev);
+ if (check_new_feature)
+ return -EINVAL;
+ pr_warn("check_new_feature is disabled, data corruption possible\n");
+ }
rdev->preferred_minor = 0xffff;
rdev->data_offset = le64_to_cpu(sb->data_offset);
@@ -10459,6 +10464,7 @@ module_param(start_dirty_degraded, int, S_IRUGO|S_IWUSR);
module_param_call(new_array, add_named_array, NULL, NULL, S_IWUSR);
module_param(create_on_open, bool, S_IRUSR|S_IWUSR);
module_param(legacy_async_del_gendisk, bool, 0600);
+module_param(check_new_feature, bool, 0600);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MD RAID framework");
--
2.39.2
Originally, the notification for connector change will be enabled after
the first read of the connector status. Therefore, if the event happens
during this window, it will be missing and make the status unsynced.
Get the connector status only after enabling the notification for
connector change to ensure the status is synced.
Fixes: c1b0bc2dabfa ("usb: typec: Add support for UCSI interface")
Cc: stable(a)vger.kernel.org # v4.13+
Tested-by: Kenneth R. Crudup <kenny(a)panix.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus(a)linux.intel.com>
Signed-off-by: Hsin-Te Yuan <yuanhsinte(a)chromium.org>
---
Changes in v7:
- Rebase onto 6.19-rc1
- Link to v6: https://lore.kernel.org/r/20251205-ucsi-v6-1-e2ad16550242@chromium.org
Changes in v6:
- Free the locks in error path.
- Link to v5: https://lore.kernel.org/r/20251205-ucsi-v5-1-488eb89bc9b8@chromium.org
Changes in v5:
- Hold the lock of each connector during the initialization to avoid
race condition between initialization and other event handler
- Add Fixes tag
- Link to v4: https://lore.kernel.org/r/20251125-ucsi-v4-1-8c94568ddaa5@chromium.org
Changes in v4:
- Handle a single connector in ucsi_init_port() and call it in a loop
- Link to v3: https://lore.kernel.org/r/20251121-ucsi-v3-1-b1047ca371b8@chromium.org
Changes in v3:
- Seperate the status checking part into a new function called
ucsi_init_port() and call it after enabling the notifications
- Link to v2: https://lore.kernel.org/r/20251118-ucsi-v2-1-d314d50333e2@chromium.org
Changes in v2:
- Remove unnecessary braces.
- Link to v1: https://lore.kernel.org/r/20251117-ucsi-v1-1-1dcbc5ea642b@chromium.org
---
drivers/usb/typec/ucsi/ucsi.c | 133 +++++++++++++++++++++++-------------------
1 file changed, 74 insertions(+), 59 deletions(-)
diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
index 9b3df776137a17e569588d41ee437a778342146e..f933c873f9e0d5f85275ebd96d34f90803230565 100644
--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -1624,11 +1624,71 @@ static struct fwnode_handle *ucsi_find_fwnode(struct ucsi_connector *con)
return NULL;
}
+static void ucsi_init_port(struct ucsi *ucsi, struct ucsi_connector *con)
+{
+ enum usb_role u_role = USB_ROLE_NONE;
+ int ret;
+
+ /* Get the status */
+ ret = ucsi_get_connector_status(con, false);
+ if (ret) {
+ dev_err(ucsi->dev, "con%d: failed to get status\n", con->num);
+ return;
+ }
+
+ if (ucsi->ops->connector_status)
+ ucsi->ops->connector_status(con);
+
+ switch (UCSI_CONSTAT(con, PARTNER_TYPE)) {
+ case UCSI_CONSTAT_PARTNER_TYPE_UFP:
+ case UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP:
+ u_role = USB_ROLE_HOST;
+ fallthrough;
+ case UCSI_CONSTAT_PARTNER_TYPE_CABLE:
+ typec_set_data_role(con->port, TYPEC_HOST);
+ break;
+ case UCSI_CONSTAT_PARTNER_TYPE_DFP:
+ u_role = USB_ROLE_DEVICE;
+ typec_set_data_role(con->port, TYPEC_DEVICE);
+ break;
+ default:
+ break;
+ }
+
+ /* Check if there is already something connected */
+ if (UCSI_CONSTAT(con, CONNECTED)) {
+ typec_set_pwr_role(con->port, UCSI_CONSTAT(con, PWR_DIR));
+ ucsi_register_partner(con);
+ ucsi_pwr_opmode_change(con);
+ ucsi_orientation(con);
+ ucsi_port_psy_changed(con);
+ if (con->ucsi->cap.features & UCSI_CAP_GET_PD_MESSAGE)
+ ucsi_get_partner_identity(con);
+ if (con->ucsi->cap.features & UCSI_CAP_CABLE_DETAILS)
+ ucsi_check_cable(con);
+ }
+
+ /* Only notify USB controller if partner supports USB data */
+ if (!(UCSI_CONSTAT(con, PARTNER_FLAG_USB)))
+ u_role = USB_ROLE_NONE;
+
+ ret = usb_role_switch_set_role(con->usb_role_sw, u_role);
+ if (ret)
+ dev_err(ucsi->dev, "con:%d: failed to set usb role:%d\n",
+ con->num, u_role);
+
+ if (con->partner && UCSI_CONSTAT(con, PWR_OPMODE) == UCSI_CONSTAT_PWR_OPMODE_PD) {
+ ucsi_register_device_pdos(con);
+ ucsi_get_src_pdos(con);
+ ucsi_check_altmodes(con);
+ ucsi_check_connector_capability(con);
+ }
+}
+
static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con)
{
struct typec_capability *cap = &con->typec_cap;
enum typec_accessory *accessory = cap->accessory;
- enum usb_role u_role = USB_ROLE_NONE;
u64 command;
char *name;
int ret;
@@ -1729,63 +1789,6 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con)
goto out;
}
- /* Get the status */
- ret = ucsi_get_connector_status(con, false);
- if (ret) {
- dev_err(ucsi->dev, "con%d: failed to get status\n", con->num);
- goto out;
- }
-
- if (ucsi->ops->connector_status)
- ucsi->ops->connector_status(con);
-
- switch (UCSI_CONSTAT(con, PARTNER_TYPE)) {
- case UCSI_CONSTAT_PARTNER_TYPE_UFP:
- case UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP:
- u_role = USB_ROLE_HOST;
- fallthrough;
- case UCSI_CONSTAT_PARTNER_TYPE_CABLE:
- typec_set_data_role(con->port, TYPEC_HOST);
- break;
- case UCSI_CONSTAT_PARTNER_TYPE_DFP:
- u_role = USB_ROLE_DEVICE;
- typec_set_data_role(con->port, TYPEC_DEVICE);
- break;
- default:
- break;
- }
-
- /* Check if there is already something connected */
- if (UCSI_CONSTAT(con, CONNECTED)) {
- typec_set_pwr_role(con->port, UCSI_CONSTAT(con, PWR_DIR));
- ucsi_register_partner(con);
- ucsi_pwr_opmode_change(con);
- ucsi_orientation(con);
- ucsi_port_psy_changed(con);
- if (con->ucsi->cap.features & UCSI_CAP_GET_PD_MESSAGE)
- ucsi_get_partner_identity(con);
- if (con->ucsi->cap.features & UCSI_CAP_CABLE_DETAILS)
- ucsi_check_cable(con);
- }
-
- /* Only notify USB controller if partner supports USB data */
- if (!(UCSI_CONSTAT(con, PARTNER_FLAG_USB)))
- u_role = USB_ROLE_NONE;
-
- ret = usb_role_switch_set_role(con->usb_role_sw, u_role);
- if (ret) {
- dev_err(ucsi->dev, "con:%d: failed to set usb role:%d\n",
- con->num, u_role);
- ret = 0;
- }
-
- if (con->partner && UCSI_CONSTAT(con, PWR_OPMODE) == UCSI_CONSTAT_PWR_OPMODE_PD) {
- ucsi_register_device_pdos(con);
- ucsi_get_src_pdos(con);
- ucsi_check_altmodes(con);
- ucsi_check_connector_capability(con);
- }
-
trace_ucsi_register_port(con->num, con);
out:
@@ -1903,17 +1906,29 @@ static int ucsi_init(struct ucsi *ucsi)
goto err_unregister;
}
+ /* Delay other interactions with each connector until ucsi_init_port is done */
+ for (i = 0; i < ucsi->cap.num_connectors; i++)
+ mutex_lock(&connector[i].lock);
+
/* Enable all supported notifications */
ntfy = ucsi_get_supported_notifications(ucsi);
command = UCSI_SET_NOTIFICATION_ENABLE | ntfy;
ucsi->message_in_size = 0;
ret = ucsi_send_command(ucsi, command);
- if (ret < 0)
+ if (ret < 0) {
+ for (i = 0; i < ucsi->cap.num_connectors; i++)
+ mutex_unlock(&connector[i].lock);
goto err_unregister;
+ }
ucsi->connector = connector;
ucsi->ntfy = ntfy;
+ for (i = 0; i < ucsi->cap.num_connectors; i++) {
+ ucsi_init_port(ucsi, &connector[i]);
+ mutex_unlock(&connector[i].lock);
+ }
+
mutex_lock(&ucsi->ppm_lock);
ret = ucsi->ops->read_cci(ucsi, &cci);
mutex_unlock(&ucsi->ppm_lock);
---
base-commit: ea1013c1539270e372fc99854bc6e4d94eaeff66
change-id: 20251117-ucsi-c2dfe8c006d7
Best regards,
--
Hsin-Te Yuan <yuanhsinte(a)chromium.org>
From: Bjorn Helgaas <bhelgaas(a)google.com>
Previously meson_pcie_link_up() only returned true if the link was in the
L0 state. This was incorrect because hardware autonomously manages
transitions between L0, L0s, and L1 while both components on the link stay
in D0. Those states should all be treated as "link is active".
Returning false when the device was in L0s or L1 broke config accesses
because dw_pcie_other_conf_map_bus() fails if the link is down, which
caused errors like this:
meson-pcie fc000000.pcie: error: wait linkup timeout
pci 0000:01:00.0: BAR 0: error updating (0xfc700004 != 0xffffffff)
Remove the LTSSM state check, timeout, speed check, and error message from
meson_pcie_link_up(), the dw_pcie_ops.link_up() method, so it is a simple
boolean check of whether the link is active. Timeouts and and error
messages are handled at a higher level, e.g., dw_pcie_wait_for_link().
Fixes: 9c0ef6d34fdb ("PCI: amlogic: Add the Amlogic Meson PCIe controller driver")
Reported-by: Linnaea Lavia <linnaea-von-lavia(a)live.com>
Closes: https://lore.kernel.org/r/DM4PR05MB102707B8CDF84D776C39F22F2C7F0A@DM4PR05MB…
Signed-off-by: Bjorn Helgaas <bhelgaas(a)google.com>
Tested-by: Linnaea Lavia <linnaea-von-lavia(a)live.com>
Cc: stable(a)vger.kernel.org
---
drivers/pci/controller/dwc/pci-meson.c | 36 +++-----------------------
1 file changed, 3 insertions(+), 33 deletions(-)
diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c
index 787469d1b396..13685d89227a 100644
--- a/drivers/pci/controller/dwc/pci-meson.c
+++ b/drivers/pci/controller/dwc/pci-meson.c
@@ -338,40 +338,10 @@ static struct pci_ops meson_pci_ops = {
static bool meson_pcie_link_up(struct dw_pcie *pci)
{
struct meson_pcie *mp = to_meson_pcie(pci);
- struct device *dev = pci->dev;
- u32 speed_okay = 0;
- u32 cnt = 0;
- u32 state12, state17, smlh_up, ltssm_up, rdlh_up;
+ u32 state12;
- do {
- state12 = meson_cfg_readl(mp, PCIE_CFG_STATUS12);
- state17 = meson_cfg_readl(mp, PCIE_CFG_STATUS17);
- smlh_up = IS_SMLH_LINK_UP(state12);
- rdlh_up = IS_RDLH_LINK_UP(state12);
- ltssm_up = IS_LTSSM_UP(state12);
-
- if (PM_CURRENT_STATE(state17) < PCIE_GEN3)
- speed_okay = 1;
-
- if (smlh_up)
- dev_dbg(dev, "smlh_link_up is on\n");
- if (rdlh_up)
- dev_dbg(dev, "rdlh_link_up is on\n");
- if (ltssm_up)
- dev_dbg(dev, "ltssm_up is on\n");
- if (speed_okay)
- dev_dbg(dev, "speed_okay\n");
-
- if (smlh_up && rdlh_up && ltssm_up && speed_okay)
- return true;
-
- cnt++;
-
- udelay(10);
- } while (cnt < WAIT_LINKUP_TIMEOUT);
-
- dev_err(dev, "error: wait linkup timeout\n");
- return false;
+ state12 = meson_cfg_readl(mp, PCIE_CFG_STATUS12);
+ return IS_SMLH_LINK_UP(state12) && IS_RDLH_LINK_UP(state12);
}
static int meson_pcie_host_init(struct dw_pcie_rp *pp)
--
2.43.0
When VM boots with one virtio-crypto PCI device and builtin backend,
run openssl benchmark command with multiple processes, such as
openssl speed -evp aes-128-cbc -engine afalg -seconds 10 -multi 32
openssl processes will hangup and there is error reported like this:
virtio_crypto virtio0: dataq.0:id 3 is not a head!
It seems that the data virtqueue need protection when it is handled
for virtio done notification. If the spinlock protection is added
in virtcrypto_done_task(), openssl benchmark with multiple processes
works well.
Fixes: fed93fb62e05 ("crypto: virtio - Handle dataq logic with tasklet")
Cc: stable(a)vger.kernel.org
Signed-off-by: Bibo Mao <maobibo(a)loongson.cn>
Acked-by: Jason Wang <jasowang(a)redhat.com>
---
drivers/crypto/virtio/virtio_crypto_core.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/crypto/virtio/virtio_crypto_core.c b/drivers/crypto/virtio/virtio_crypto_core.c
index 3d241446099c..ccc6b5c1b24b 100644
--- a/drivers/crypto/virtio/virtio_crypto_core.c
+++ b/drivers/crypto/virtio/virtio_crypto_core.c
@@ -75,15 +75,20 @@ static void virtcrypto_done_task(unsigned long data)
struct data_queue *data_vq = (struct data_queue *)data;
struct virtqueue *vq = data_vq->vq;
struct virtio_crypto_request *vc_req;
+ unsigned long flags;
unsigned int len;
+ spin_lock_irqsave(&data_vq->lock, flags);
do {
virtqueue_disable_cb(vq);
while ((vc_req = virtqueue_get_buf(vq, &len)) != NULL) {
+ spin_unlock_irqrestore(&data_vq->lock, flags);
if (vc_req->alg_cb)
vc_req->alg_cb(vc_req, len);
+ spin_lock_irqsave(&data_vq->lock, flags);
}
} while (!virtqueue_enable_cb(vq));
+ spin_unlock_irqrestore(&data_vq->lock, flags);
}
static void virtcrypto_dataq_callback(struct virtqueue *vq)
--
2.39.3
sched_mm_cid_after_execve() is called from the failure path
of bprm_execve(). At that point exec has not completed successfully,
so updating the mm CID state is incorrect and can trigger a panic,
as reported by syzbot.
Remove the call from the exec failure path.
Cc: stable(a)vger.kernel.org
Reported-by: syzbot+9ca2c6e6b098bf5ae60a(a)syzkaller.appspotmail.com
Signed-off-by: Jinchao Wang <wangjinchao600(a)gmail.com>
---
fs/exec.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/fs/exec.c b/fs/exec.c
index 9d5ebc9d15b0..9044a75d26ab 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1773,7 +1773,6 @@ static int bprm_execve(struct linux_binprm *bprm)
if (bprm->point_of_no_return && !fatal_signal_pending(current))
force_fatal_sig(SIGSEGV);
- sched_mm_cid_after_execve(current);
rseq_force_update();
current->in_execve = 0;
--
2.43.0