From: Adrien Thierry athierry@redhat.com
[ Upstream commit 45d89a344eb46db9dce851c28e14f5e3c635c251 ]
In the dwc3 core, both system and runtime suspend end up calling dwc3_suspend_common(). From there, what happens for the PHYs depends on the USB mode and whether the controller is entering system or runtime suspend.
HOST mode: (1) system suspend on a non-wakeup-capable controller
The [1] if branch is taken. dwc3_core_exit() is called, which ends up calling phy_power_off() and phy_exit(). Those two functions decrease the PM runtime count at some point, so they will trigger the PHY runtime sleep (assuming the count is right).
(2) runtime suspend / system suspend on a wakeup-capable controller
The [1] branch is not taken. dwc3_suspend_common() calls phy_pm_runtime_put_sync(). Assuming the ref count is right, the PHY runtime suspend op is called.
DEVICE mode: dwc3_core_exit() is called on both runtime and system sleep unless the controller is already runtime suspended.
OTG mode: (1) system suspend : dwc3_core_exit() is called
(2) runtime suspend : do nothing
In host mode, the code seems to make a distinction between 1) runtime sleep / system sleep for wakeup-capable controller, and 2) system sleep for non-wakeup-capable controller, where phy_power_off() and phy_exit() are only called for the latter. This suggests the PHY is not supposed to be in a fully powered-off state for runtime sleep and system sleep for wakeup-capable controller.
Moreover, downstream, cfg_ahb_clk only gets disabled for system suspend. The clocks are disabled by phy->set_suspend() [2] which is only called in the system sleep path through dwc3_core_exit() [3].
With that in mind, don't disable the clocks during the femto PHY runtime suspend callback. The clocks will only be disabled during system suspend for non-wakeup-capable controllers, through dwc3_core_exit().
[1] https://elixir.bootlin.com/linux/v6.4/source/drivers/usb/dwc3/core.c#L1988 [2] https://git.codelinaro.org/clo/la/kernel/msm-5.4/-/blob/LV.AU.1.2.1.r2-05300... [3] https://git.codelinaro.org/clo/la/kernel/msm-5.4/-/blob/LV.AU.1.2.1.r2-05300...
Signed-off-by: Adrien Thierry athierry@redhat.com Link: https://lore.kernel.org/r/20230629144542.14906-2-athierry@redhat.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c | 9 --------- 1 file changed, 9 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c index 7e61202aa234e..a107f98c662d5 100644 --- a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c +++ b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c @@ -122,22 +122,13 @@ static int qcom_snps_hsphy_suspend(struct qcom_snps_hsphy *hsphy) 0, USB2_AUTO_RESUME); }
- clk_disable_unprepare(hsphy->cfg_ahb_clk); return 0; }
static int qcom_snps_hsphy_resume(struct qcom_snps_hsphy *hsphy) { - int ret; - dev_dbg(&hsphy->phy->dev, "Resume QCOM SNPS PHY, mode\n");
- ret = clk_prepare_enable(hsphy->cfg_ahb_clk); - if (ret) { - dev_err(&hsphy->phy->dev, "failed to enable cfg ahb clock\n"); - return ret; - } - return 0; }
From: Adrien Thierry athierry@redhat.com
[ Upstream commit 8932089b566c24ea19b57e37704c492678de1420 ]
The return value from qcom_snps_hsphy_suspend/resume is not used. Make sure qcom_snps_hsphy_runtime_suspend/resume return this value as well.
Signed-off-by: Adrien Thierry athierry@redhat.com Link: https://lore.kernel.org/r/20230629144542.14906-4-athierry@redhat.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c index a107f98c662d5..68c21c08a0397 100644 --- a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c +++ b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c @@ -139,8 +139,7 @@ static int __maybe_unused qcom_snps_hsphy_runtime_suspend(struct device *dev) if (!hsphy->phy_initialized) return 0;
- qcom_snps_hsphy_suspend(hsphy); - return 0; + return qcom_snps_hsphy_suspend(hsphy); }
static int __maybe_unused qcom_snps_hsphy_runtime_resume(struct device *dev) @@ -150,8 +149,7 @@ static int __maybe_unused qcom_snps_hsphy_runtime_resume(struct device *dev) if (!hsphy->phy_initialized) return 0;
- qcom_snps_hsphy_resume(hsphy); - return 0; + return qcom_snps_hsphy_resume(hsphy); }
static int qcom_snps_hsphy_set_mode(struct phy *phy, enum phy_mode mode,
From: Dmitry Antipov dmantipov@yandex.ru
[ Upstream commit 92cbf865ea2e0f2997ff97815c6db182eb23df1b ]
Handle (and warn about) possible error waiting for MSGCODE_PING result.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Signed-off-by: Dmitry Antipov dmantipov@yandex.ru Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/cec/usb/pulse8/pulse8-cec.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/media/cec/usb/pulse8/pulse8-cec.c b/drivers/media/cec/usb/pulse8/pulse8-cec.c index 04b13cdc38d2c..ba67587bd43ec 100644 --- a/drivers/media/cec/usb/pulse8/pulse8-cec.c +++ b/drivers/media/cec/usb/pulse8/pulse8-cec.c @@ -809,8 +809,11 @@ static void pulse8_ping_eeprom_work_handler(struct work_struct *work)
mutex_lock(&pulse8->lock); cmd = MSGCODE_PING; - pulse8_send_and_wait(pulse8, &cmd, 1, - MSGCODE_COMMAND_ACCEPTED, 0); + if (pulse8_send_and_wait(pulse8, &cmd, 1, + MSGCODE_COMMAND_ACCEPTED, 0)) { + dev_warn(pulse8->dev, "failed to ping EEPROM\n"); + goto unlock; + }
if (pulse8->vers < 2) goto unlock;
From: Nikolay Burykin burikin@ivk.ru
[ Upstream commit 4aaa96b59df5fac41ba891969df6b092061ea9d7 ]
After having been assigned to NULL value at cx23885-dvb.c:1202, pointer '0' is dereferenced at cx23885-dvb.c:2469.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Signed-off-by: Nikolay Burykin burikin@ivk.ru Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/pci/cx23885/cx23885-dvb.c | 12 ------------ 1 file changed, 12 deletions(-)
diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 45c2f4afceb82..9b437faf2c3f6 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -2459,16 +2459,10 @@ static int dvb_register(struct cx23885_tsport *port) request_module("%s", info.type); client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info); if (!i2c_client_has_driver(client_tuner)) { - module_put(client_demod->dev.driver->owner); - i2c_unregister_device(client_demod); - port->i2c_client_demod = NULL; goto frontend_detach; } if (!try_module_get(client_tuner->dev.driver->owner)) { i2c_unregister_device(client_tuner); - module_put(client_demod->dev.driver->owner); - i2c_unregister_device(client_demod); - port->i2c_client_demod = NULL; goto frontend_detach; } port->i2c_client_tuner = client_tuner; @@ -2505,16 +2499,10 @@ static int dvb_register(struct cx23885_tsport *port) request_module("%s", info.type); client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info); if (!i2c_client_has_driver(client_tuner)) { - module_put(client_demod->dev.driver->owner); - i2c_unregister_device(client_demod); - port->i2c_client_demod = NULL; goto frontend_detach; } if (!try_module_get(client_tuner->dev.driver->owner)) { i2c_unregister_device(client_tuner); - module_put(client_demod->dev.driver->owner); - i2c_unregister_device(client_demod); - port->i2c_client_demod = NULL; goto frontend_detach; } port->i2c_client_tuner = client_tuner;
From: Dominique Martinet asmadeus@codewreck.org
[ Upstream commit 4a73edab69d3a6623f03817fe950a2d9585f80e4 ]
Similarly to the previous patch: offs can be used in handle_rerrors without initializing on small payloads; in this case handle_rerrors will not use it because of the size check, but it doesn't hurt to make sure it is zero to please scan-build.
This fixes the following warning: net/9p/trans_virtio.c:539:3: warning: 3rd function call argument is an uninitialized value [core.CallAndMessage] handle_rerror(req, in_hdr_len, offs, in_pages); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: Dominique Martinet asmadeus@codewreck.org Signed-off-by: Eric Van Hensbergen ericvh@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/9p/trans_virtio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index d110df3cb4e1d..96eecc2dcaa36 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c @@ -399,7 +399,7 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req, struct page **in_pages = NULL, **out_pages = NULL; struct virtio_chan *chan = client->trans; struct scatterlist *sgs[4]; - size_t offs; + size_t offs = 0; int need_drop = 0; int kicked = 0;
From: Namjae Jeon linkinjeon@kernel.org
[ Upstream commit dc318846f3dd54574a36ae97fc8d8b75dd7cdb1e ]
smb3_decrypt_req() validate if pdu_length is smaller than smb2_transform_hdr size.
Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-21589 Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ksmbd/smb2pdu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c index 9f9d07caa57e9..a4673831fc10d 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -8642,7 +8642,8 @@ int smb3_decrypt_req(struct ksmbd_work *work) struct smb2_transform_hdr *tr_hdr = (struct smb2_transform_hdr *)buf; int rc = 0;
- if (buf_data_size < sizeof(struct smb2_hdr)) { + if (pdu_length < sizeof(struct smb2_transform_hdr) || + buf_data_size < sizeof(struct smb2_hdr)) { pr_err("Transform message is too small (%u)\n", pdu_length); return -ECONNABORTED;
From: Namjae Jeon linkinjeon@kernel.org
[ Upstream commit e202a1e8634b186da38cbbff85382ea2b9e297cf ]
ksmbd doesn't support compound read. If client send read-read in compound to ksmbd, there can be memory leak from read buffer. Windows and linux clients doesn't send it to server yet. For now, No response from compound read. compound read will be supported soon.
Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-21587, ZDI-CAN-21588 Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ksmbd/smb2pdu.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c index a4673831fc10d..437bfc970bc5e 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -6246,6 +6246,11 @@ int smb2_read(struct ksmbd_work *work)
rsp_org = work->response_buf; WORK_BUFFERS(work, req, rsp); + if (work->next_smb2_rcv_hdr_off) { + work->send_no_response = 1; + err = -EOPNOTSUPP; + goto out; + }
if (test_share_config_flag(work->tcon->share_conf, KSMBD_SHARE_FLAG_PIPE)) {
From: Dmytro Maluka dmy@semihalf.com
[ Upstream commit 91e292917dad64ab8d1d5ca2ab3069ad9dac6f72 ]
da7219_aad_suspend() disables jack detection, which should prevent generating new interrupts by DA7219 while suspended. However, there is a theoretical possibility that there is a pending interrupt generated just before suspending DA7219 and not handled yet, so the IRQ handler may still run after DA7219 is suspended. To prevent that, wait until the pending IRQ handling is done.
This patch arose as an attempt to fix the following I2C failure occurring sometimes during system suspend or resume:
[ 355.876211] i2c_designware i2c_designware.3: Transfer while suspended [ 355.876245] WARNING: CPU: 2 PID: 3576 at drivers/i2c/busses/i2c-designware-master.c:570 i2c_dw_xfer+0x411/0x440 ... [ 355.876462] Call Trace: [ 355.876468] <TASK> [ 355.876475] ? update_load_avg+0x1b3/0x615 [ 355.876484] __i2c_transfer+0x101/0x1d8 [ 355.876494] i2c_transfer+0x74/0x10d [ 355.876504] regmap_i2c_read+0x6a/0x9c [ 355.876513] _regmap_raw_read+0x179/0x223 [ 355.876521] regmap_raw_read+0x1e1/0x28e [ 355.876527] regmap_bulk_read+0x17d/0x1ba [ 355.876532] ? __wake_up+0xed/0x1bb [ 355.876542] da7219_aad_irq_thread+0x54/0x2c9 [snd_soc_da7219 5fb8ebb2179cf2fea29af090f3145d68ed8e2184] [ 355.876556] irq_thread+0x13c/0x231 [ 355.876563] ? irq_forced_thread_fn+0x5f/0x5f [ 355.876570] ? irq_thread_fn+0x4d/0x4d [ 355.876576] kthread+0x13a/0x152 [ 355.876581] ? synchronize_irq+0xc3/0xc3 [ 355.876587] ? kthread_blkcg+0x31/0x31 [ 355.876592] ret_from_fork+0x1f/0x30 [ 355.876601] </TASK>
which indicates that the AAD IRQ handler is unexpectedly running when DA7219 is suspended, and as a result, is trying to read data from DA7219 over I2C and is hitting the I2C driver "Transfer while suspended" failure.
However, with this patch the above failure is still reproducible. So this patch does not fix any real observed issue so far, but at least is useful for confirming that the above issue is not caused by a pending IRQ but rather looks like a DA7219 hardware issue with an IRQ unexpectedly generated after jack detection is already disabled.
Signed-off-by: Dmytro Maluka dmy@semihalf.com Link: https://lore.kernel.org/r/20230717193737.161784-2-dmy@semihalf.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/da7219-aad.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/soc/codecs/da7219-aad.c b/sound/soc/codecs/da7219-aad.c index 7998fdd3b378e..6b368ab945be5 100644 --- a/sound/soc/codecs/da7219-aad.c +++ b/sound/soc/codecs/da7219-aad.c @@ -854,6 +854,8 @@ void da7219_aad_suspend(struct snd_soc_component *component) } } } + + synchronize_irq(da7219_aad->irq); }
void da7219_aad_resume(struct snd_soc_component *component)
From: Dmytro Maluka dmy@semihalf.com
[ Upstream commit f0691dc16206f21b13c464434366e2cd632b8ed7 ]
When handling an AAD interrupt, if IRQ events read failed (for example, due to i2c "Transfer while suspended" failure, i.e. when attempting to read it while DA7219 is suspended, which may happen due to a spurious AAD interrupt), the events array contains garbage uninitialized values. So instead of trying to interprete those values and doing any actions based on them (potentially resulting in misbehavior, e.g. reporting bogus events), refuse to handle the interrupt.
Signed-off-by: Dmytro Maluka dmy@semihalf.com Link: https://lore.kernel.org/r/20230717193737.161784-3-dmy@semihalf.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/da7219-aad.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/sound/soc/codecs/da7219-aad.c b/sound/soc/codecs/da7219-aad.c index 6b368ab945be5..7d18de959439f 100644 --- a/sound/soc/codecs/da7219-aad.c +++ b/sound/soc/codecs/da7219-aad.c @@ -347,11 +347,15 @@ static irqreturn_t da7219_aad_irq_thread(int irq, void *data) struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); u8 events[DA7219_AAD_IRQ_REG_MAX]; u8 statusa; - int i, report = 0, mask = 0; + int i, ret, report = 0, mask = 0;
/* Read current IRQ events */ - regmap_bulk_read(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A, - events, DA7219_AAD_IRQ_REG_MAX); + ret = regmap_bulk_read(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A, + events, DA7219_AAD_IRQ_REG_MAX); + if (ret) { + dev_warn_ratelimited(component->dev, "Failed to read IRQ events: %d\n", ret); + return IRQ_NONE; + }
if (!events[DA7219_AAD_IRQ_REG_A] && !events[DA7219_AAD_IRQ_REG_B]) return IRQ_NONE;
From: Yuanjun Gong ruc_gongyuanjun@163.com
[ Upstream commit 8d01da0a1db237c44c92859ce3612df7af8d3a53 ]
in atl1c_tso_csum, it should check the return value of pskb_trim(), and return an error code if an unexpected value is returned by pskb_trim().
Signed-off-by: Yuanjun Gong ruc_gongyuanjun@163.com Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index 5cbd815c737e7..dad21b4fbc0bc 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c @@ -2104,8 +2104,11 @@ static int atl1c_tso_csum(struct atl1c_adapter *adapter, real_len = (((unsigned char *)ip_hdr(skb) - skb->data) + ntohs(ip_hdr(skb)->tot_len));
- if (real_len < skb->len) - pskb_trim(skb, real_len); + if (real_len < skb->len) { + err = pskb_trim(skb, real_len); + if (err) + return err; + }
hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb)); if (unlikely(skb->len == hdr_len)) {
From: Jiri Benc jbenc@redhat.com
[ Upstream commit 17a0a64448b568442a101de09575f81ffdc45d15 ]
The vxlan_parse_gpe_hdr function extracts the next protocol value from the GPE header and marks GPE bits as parsed.
In order to be used in the next patch, split the function into protocol extraction and bit marking. The bit marking is meaningful only in vxlan_rcv; move it directly there.
Rename the function to vxlan_parse_gpe_proto to reflect what it now does. Remove unused arguments skb and vxflags. Move the function earlier in the file to allow it to be called from more places in the next patch.
Signed-off-by: Jiri Benc jbenc@redhat.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/vxlan.c | 58 ++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 30 deletions(-)
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 129e270e9a7cd..90d656ea8fc6a 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -730,6 +730,32 @@ static int vxlan_fdb_append(struct vxlan_fdb *f, return 1; }
+static bool vxlan_parse_gpe_proto(struct vxlanhdr *hdr, __be16 *protocol) +{ + struct vxlanhdr_gpe *gpe = (struct vxlanhdr_gpe *)hdr; + + /* Need to have Next Protocol set for interfaces in GPE mode. */ + if (!gpe->np_applied) + return false; + /* "The initial version is 0. If a receiver does not support the + * version indicated it MUST drop the packet. + */ + if (gpe->version != 0) + return false; + /* "When the O bit is set to 1, the packet is an OAM packet and OAM + * processing MUST occur." However, we don't implement OAM + * processing, thus drop the packet. + */ + if (gpe->oam_flag) + return false; + + *protocol = tun_p_to_eth_p(gpe->next_protocol); + if (!*protocol) + return false; + + return true; +} + static struct vxlanhdr *vxlan_gro_remcsum(struct sk_buff *skb, unsigned int off, struct vxlanhdr *vh, size_t hdrlen, @@ -1738,35 +1764,6 @@ static void vxlan_parse_gbp_hdr(struct vxlanhdr *unparsed, unparsed->vx_flags &= ~VXLAN_GBP_USED_BITS; }
-static bool vxlan_parse_gpe_hdr(struct vxlanhdr *unparsed, - __be16 *protocol, - struct sk_buff *skb, u32 vxflags) -{ - struct vxlanhdr_gpe *gpe = (struct vxlanhdr_gpe *)unparsed; - - /* Need to have Next Protocol set for interfaces in GPE mode. */ - if (!gpe->np_applied) - return false; - /* "The initial version is 0. If a receiver does not support the - * version indicated it MUST drop the packet. - */ - if (gpe->version != 0) - return false; - /* "When the O bit is set to 1, the packet is an OAM packet and OAM - * processing MUST occur." However, we don't implement OAM - * processing, thus drop the packet. - */ - if (gpe->oam_flag) - return false; - - *protocol = tun_p_to_eth_p(gpe->next_protocol); - if (!*protocol) - return false; - - unparsed->vx_flags &= ~VXLAN_GPE_USED_BITS; - return true; -} - static bool vxlan_set_mac(struct vxlan_dev *vxlan, struct vxlan_sock *vs, struct sk_buff *skb, __be32 vni) @@ -1867,8 +1864,9 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb) * used by VXLAN extensions if explicitly requested. */ if (vs->flags & VXLAN_F_GPE) { - if (!vxlan_parse_gpe_hdr(&unparsed, &protocol, skb, vs->flags)) + if (!vxlan_parse_gpe_proto(&unparsed, &protocol)) goto drop; + unparsed.vx_flags &= ~VXLAN_GPE_USED_BITS; raw_proto = true; }
From: Ben Hutchings benh@debian.org
[ Upstream commit 922a9bd138101e3e5718f0f4d40dba68ef89bb43 ]
gas supports several different forms for .section for ELF targets, including: .section NAME [, "FLAGS"[, @TYPE[,FLAG_SPECIFIC_ARGUMENTS]]] and: .section "NAME"[, #FLAGS...]
In several places we use a mix of these two forms: .section NAME, #FLAGS...
A current development snapshot of binutils (2.40.50.20230611) treats this mixed syntax as an error.
Change to consistently use: .section NAME, "FLAGS" as is used elsewhere in the kernel.
Link: https://buildd.debian.org/status/fetch.php?pkg=linux&arch=m68k&ver=6... Signed-off-by: Ben Hutchings benh@debian.org Tested-by: Jan-Benedict Glaw jbglaw@lug-owl.de Link: https://lore.kernel.org/r/ZIyBaueWT9jnTwRC@decadent.org.uk Signed-off-by: Geert Uytterhoeven geert@linux-m68k.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/m68k/fpsp040/skeleton.S | 4 ++-- arch/m68k/ifpsp060/os.S | 4 ++-- arch/m68k/kernel/relocate_kernel.S | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/m68k/fpsp040/skeleton.S b/arch/m68k/fpsp040/skeleton.S index 439395aa6fb42..081922c72daaa 100644 --- a/arch/m68k/fpsp040/skeleton.S +++ b/arch/m68k/fpsp040/skeleton.S @@ -499,13 +499,13 @@ in_ea: dbf %d0,morein rts
- .section .fixup,#alloc,#execinstr + .section .fixup,"ax" .even 1: jbsr fpsp040_die jbra .Lnotkern
- .section __ex_table,#alloc + .section __ex_table,"a" .align 4
.long in_ea,1b diff --git a/arch/m68k/ifpsp060/os.S b/arch/m68k/ifpsp060/os.S index 7a0d6e4280665..89e2ec224ab6c 100644 --- a/arch/m68k/ifpsp060/os.S +++ b/arch/m68k/ifpsp060/os.S @@ -379,11 +379,11 @@ _060_real_access:
| Execption handling for movs access to illegal memory - .section .fixup,#alloc,#execinstr + .section .fixup,"ax" .even 1: moveq #-1,%d1 rts -.section __ex_table,#alloc +.section __ex_table,"a" .align 4 .long dmrbuae,1b .long dmrwuae,1b diff --git a/arch/m68k/kernel/relocate_kernel.S b/arch/m68k/kernel/relocate_kernel.S index ab0f1e7d46535..f7667079e08e9 100644 --- a/arch/m68k/kernel/relocate_kernel.S +++ b/arch/m68k/kernel/relocate_kernel.S @@ -26,7 +26,7 @@ ENTRY(relocate_new_kernel) lea %pc@(.Lcopy),%a4 2: addl #0x00000000,%a4 /* virt_to_phys() */
- .section ".m68k_fixup","aw" + .section .m68k_fixup,"aw" .long M68K_FIXUP_MEMOFFSET, 2b+2 .previous
@@ -49,7 +49,7 @@ ENTRY(relocate_new_kernel) lea %pc@(.Lcont040),%a4 5: addl #0x00000000,%a4 /* virt_to_phys() */
- .section ".m68k_fixup","aw" + .section .m68k_fixup,"aw" .long M68K_FIXUP_MEMOFFSET, 5b+2 .previous
From: Stefan Haberland sth@linux.ibm.com
[ Upstream commit acea28a6b74f458defda7417d2217b051ba7d444 ]
If a DASD request fails an error recovery procedure (ERP) request might be built as a copy of the original request to do error recovery.
The ERP request gets a number of retries assigned. This number is always 256 no matter what other value might have been set for the original request. This is not what is expected when a user specifies a certain amount of retries for the device via sysfs.
Correctly use the number of retries of the original request for ERP requests.
Signed-off-by: Stefan Haberland sth@linux.ibm.com Reviewed-by: Jan Hoeppner hoeppner@linux.ibm.com Link: https://lore.kernel.org/r/20230721193647.3889634-3-sth@linux.ibm.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/s390/block/dasd_3990_erp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c index 4691a3c35d725..c2d4ea74e0d00 100644 --- a/drivers/s390/block/dasd_3990_erp.c +++ b/drivers/s390/block/dasd_3990_erp.c @@ -2436,7 +2436,7 @@ static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr) erp->block = cqr->block; erp->magic = cqr->magic; erp->expires = cqr->expires; - erp->retries = 256; + erp->retries = device->default_retries; erp->buildclk = get_tod_clock(); erp->status = DASD_CQR_FILLED;
From: Stefan Haberland sth@linux.ibm.com
[ Upstream commit 8a2278ce9c25048d999fe1a3561def75d963f471 ]
The DASD device driver has a function to requeue requests to the blocklayer. This function is used in various cases when basic settings for the device have to be changed like High Performance Ficon related parameters or copy pair settings.
The functions iterates over the device->ccw_queue and also removes the requests from the block->ccw_queue. In case the device is started on an alias device instead of the base device it might be removed from the block->ccw_queue without having it canceled properly before. This might lead to a hanging device since the request is no longer on a queue and can not be handled properly.
Fix by iterating over the block->ccw_queue instead of the device->ccw_queue. This will take care of all blocklayer related requests and handle them on all associated DASD devices.
Signed-off-by: Stefan Haberland sth@linux.ibm.com Reviewed-by: Jan Hoeppner hoeppner@linux.ibm.com Link: https://lore.kernel.org/r/20230721193647.3889634-4-sth@linux.ibm.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/s390/block/dasd.c | 125 +++++++++++++++----------------------- 1 file changed, 48 insertions(+), 77 deletions(-)
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index ed897dc499ff6..0c6ab288201e5 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -2948,41 +2948,32 @@ static void _dasd_wake_block_flush_cb(struct dasd_ccw_req *cqr, void *data) * Requeue a request back to the block request queue * only works for block requests */ -static int _dasd_requeue_request(struct dasd_ccw_req *cqr) +static void _dasd_requeue_request(struct dasd_ccw_req *cqr) { - struct dasd_block *block = cqr->block; struct request *req;
- if (!block) - return -EINVAL; /* * If the request is an ERP request there is nothing to requeue. * This will be done with the remaining original request. */ if (cqr->refers) - return 0; + return; spin_lock_irq(&cqr->dq->lock); req = (struct request *) cqr->callback_data; blk_mq_requeue_request(req, true); spin_unlock_irq(&cqr->dq->lock);
- return 0; + return; }
-/* - * Go through all request on the dasd_block request queue, cancel them - * on the respective dasd_device, and return them to the generic - * block layer. - */ -static int dasd_flush_block_queue(struct dasd_block *block) +static int _dasd_requests_to_flushqueue(struct dasd_block *block, + struct list_head *flush_queue) { struct dasd_ccw_req *cqr, *n; - int rc, i; - struct list_head flush_queue; unsigned long flags; + int rc, i;
- INIT_LIST_HEAD(&flush_queue); - spin_lock_bh(&block->queue_lock); + spin_lock_irqsave(&block->queue_lock, flags); rc = 0; restart: list_for_each_entry_safe(cqr, n, &block->ccw_queue, blocklist) { @@ -2997,13 +2988,32 @@ static int dasd_flush_block_queue(struct dasd_block *block) * is returned from the dasd_device layer. */ cqr->callback = _dasd_wake_block_flush_cb; - for (i = 0; cqr != NULL; cqr = cqr->refers, i++) - list_move_tail(&cqr->blocklist, &flush_queue); + for (i = 0; cqr; cqr = cqr->refers, i++) + list_move_tail(&cqr->blocklist, flush_queue); if (i > 1) /* moved more than one request - need to restart */ goto restart; } - spin_unlock_bh(&block->queue_lock); + spin_unlock_irqrestore(&block->queue_lock, flags); + + return rc; +} + +/* + * Go through all request on the dasd_block request queue, cancel them + * on the respective dasd_device, and return them to the generic + * block layer. + */ +static int dasd_flush_block_queue(struct dasd_block *block) +{ + struct dasd_ccw_req *cqr, *n; + struct list_head flush_queue; + unsigned long flags; + int rc; + + INIT_LIST_HEAD(&flush_queue); + rc = _dasd_requests_to_flushqueue(block, &flush_queue); + /* Now call the callback function of flushed requests */ restart_cb: list_for_each_entry_safe(cqr, n, &flush_queue, blocklist) { @@ -3926,75 +3936,36 @@ EXPORT_SYMBOL_GPL(dasd_generic_space_avail); */ static int dasd_generic_requeue_all_requests(struct dasd_device *device) { + struct dasd_block *block = device->block; struct list_head requeue_queue; struct dasd_ccw_req *cqr, *n; - struct dasd_ccw_req *refers; int rc;
- INIT_LIST_HEAD(&requeue_queue); - spin_lock_irq(get_ccwdev_lock(device->cdev)); - rc = 0; - list_for_each_entry_safe(cqr, n, &device->ccw_queue, devlist) { - /* Check status and move request to flush_queue */ - if (cqr->status == DASD_CQR_IN_IO) { - rc = device->discipline->term_IO(cqr); - if (rc) { - /* unable to terminate requeust */ - dev_err(&device->cdev->dev, - "Unable to terminate request %p " - "on suspend\n", cqr); - spin_unlock_irq(get_ccwdev_lock(device->cdev)); - dasd_put_device(device); - return rc; - } - } - list_move_tail(&cqr->devlist, &requeue_queue); - } - spin_unlock_irq(get_ccwdev_lock(device->cdev)); - - list_for_each_entry_safe(cqr, n, &requeue_queue, devlist) { - wait_event(dasd_flush_wq, - (cqr->status != DASD_CQR_CLEAR_PENDING)); + if (!block) + return 0;
- /* - * requeue requests to blocklayer will only work - * for block device requests - */ - if (_dasd_requeue_request(cqr)) - continue; + INIT_LIST_HEAD(&requeue_queue); + rc = _dasd_requests_to_flushqueue(block, &requeue_queue);
- /* remove requests from device and block queue */ - list_del_init(&cqr->devlist); - while (cqr->refers != NULL) { - refers = cqr->refers; - /* remove the request from the block queue */ - list_del(&cqr->blocklist); - /* free the finished erp request */ - dasd_free_erp_request(cqr, cqr->memdev); - cqr = refers; + /* Now call the callback function of flushed requests */ +restart_cb: + list_for_each_entry_safe(cqr, n, &requeue_queue, blocklist) { + wait_event(dasd_flush_wq, (cqr->status < DASD_CQR_QUEUED)); + /* Process finished ERP request. */ + if (cqr->refers) { + spin_lock_bh(&block->queue_lock); + __dasd_process_erp(block->base, cqr); + spin_unlock_bh(&block->queue_lock); + /* restart list_for_xx loop since dasd_process_erp + * might remove multiple elements + */ + goto restart_cb; } - - /* - * _dasd_requeue_request already checked for a valid - * blockdevice, no need to check again - * all erp requests (cqr->refers) have a cqr->block - * pointer copy from the original cqr - */ + _dasd_requeue_request(cqr); list_del_init(&cqr->blocklist); cqr->block->base->discipline->free_cp( cqr, (struct request *) cqr->callback_data); } - - /* - * if requests remain then they are internal request - * and go back to the device queue - */ - if (!list_empty(&requeue_queue)) { - /* move freeze_queue to start of the ccw_queue */ - spin_lock_irq(get_ccwdev_lock(device->cdev)); - list_splice_tail(&requeue_queue, &device->ccw_queue); - spin_unlock_irq(get_ccwdev_lock(device->cdev)); - } dasd_schedule_device_bh(device); return rc; }
From: Winston Wen wentao@uniontech.com
[ Upstream commit c1ed39ec116272935528ca9b348b8ee79b0791da ]
load_nls() take a char * parameter, use it to find nls module in list or construct the module name to load it.
This change make load_nls() take a const parameter, so we don't need do some cast like this:
ses->local_nls = load_nls((char *)ctx->local_nls->charset);
Suggested-by: Stephen Rothwell sfr@canb.auug.org.au Signed-off-by: Winston Wen wentao@uniontech.com Reviewed-by: Paulo Alcantara pc@manguebit.com Reviewed-by: Christian Brauner brauner@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nls/nls_base.c | 4 ++-- include/linux/nls.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c index 52ccd34b1e792..a026dbd3593f6 100644 --- a/fs/nls/nls_base.c +++ b/fs/nls/nls_base.c @@ -272,7 +272,7 @@ int unregister_nls(struct nls_table * nls) return -EINVAL; }
-static struct nls_table *find_nls(char *charset) +static struct nls_table *find_nls(const char *charset) { struct nls_table *nls; spin_lock(&nls_lock); @@ -288,7 +288,7 @@ static struct nls_table *find_nls(char *charset) return nls; }
-struct nls_table *load_nls(char *charset) +struct nls_table *load_nls(const char *charset) { return try_then_request_module(find_nls(charset), "nls_%s", charset); } diff --git a/include/linux/nls.h b/include/linux/nls.h index 499e486b3722d..e0bf8367b274a 100644 --- a/include/linux/nls.h +++ b/include/linux/nls.h @@ -47,7 +47,7 @@ enum utf16_endian { /* nls_base.c */ extern int __register_nls(struct nls_table *, struct module *); extern int unregister_nls(struct nls_table *); -extern struct nls_table *load_nls(char *); +extern struct nls_table *load_nls(const char *charset); extern void unload_nls(struct nls_table *); extern struct nls_table *load_nls_default(void); #define register_nls(nls) __register_nls((nls), THIS_MODULE)
From: Shuming Fan shumingf@realtek.com
[ Upstream commit 02fb23d72720df2b6be3f29fc5787ca018eb92c3 ]
When the system suspends, peripheral Imp-defined interrupt is disabled. When system level resume is invoked, the peripheral Imp-defined interrupts should be enabled to handle JD events.
Signed-off-by: Shuming Fan shumingf@realtek.com Reported-by: Vijendar Mukunda Vijendar.Mukunda@amd.com Link: https://lore.kernel.org/r/20230721090643.128213-1-shumingf@realtek.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/rt5682-sdw.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/rt5682-sdw.c b/sound/soc/codecs/rt5682-sdw.c index f04e18c32489d..9fdd9afe00da4 100644 --- a/sound/soc/codecs/rt5682-sdw.c +++ b/sound/soc/codecs/rt5682-sdw.c @@ -786,8 +786,15 @@ static int __maybe_unused rt5682_dev_resume(struct device *dev) if (!rt5682->first_hw_init) return 0;
- if (!slave->unattach_request) + if (!slave->unattach_request) { + if (rt5682->disable_irq == true) { + mutex_lock(&rt5682->disable_irq_lock); + sdw_write_no_pm(slave, SDW_SCP_INTMASK1, SDW_SCP_INT1_IMPL_DEF); + rt5682->disable_irq = false; + mutex_unlock(&rt5682->disable_irq_lock); + } goto regmap_sync; + }
time = wait_for_completion_timeout(&slave->initialization_complete, msecs_to_jiffies(RT5682_PROBE_TIMEOUT));
From: Edgar ljijcj@163.com
[ Upstream commit d20d35d1ad62c6cca36368c1e8f29335a068659e ]
According to the datasheet, the DMIC config should be changed to { 0, 2 ,3 }
Signed-off-by: Edgar ljijcj@163.com Link: https://lore.kernel.org/r/20230719054722.401954-1-ljijcj@163.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/es8316.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c index b36ccfc54cd69..93549f8ee130c 100644 --- a/sound/soc/codecs/es8316.c +++ b/sound/soc/codecs/es8316.c @@ -153,7 +153,7 @@ static const char * const es8316_dmic_txt[] = { "dmic data at high level", "dmic data at low level", }; -static const unsigned int es8316_dmic_values[] = { 0, 1, 2 }; +static const unsigned int es8316_dmic_values[] = { 0, 2, 3 }; static const struct soc_enum es8316_dmic_src_enum = SOC_VALUE_ENUM_SINGLE(ES8316_ADC_DMIC, 0, 3, ARRAY_SIZE(es8316_dmic_txt),
From: Shuming Fan shumingf@realtek.com
[ Upstream commit b69de265bd0e877015a00fbba453ef72af162e0f ]
When the system suspends, peripheral Imp-defined interrupt is disabled. When system level resume is invoked, the peripheral Imp-defined interrupts should be enabled to handle JD events.
Signed-off-by: Shuming Fan shumingf@realtek.com Reported-by: Vijendar Mukunda Vijendar.Mukunda@amd.com Link: https://lore.kernel.org/r/20230721090654.128230-1-shumingf@realtek.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/rt711-sdw.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/rt711-sdw.c b/sound/soc/codecs/rt711-sdw.c index 4fe68bcf2a7c2..9545b8a7eb192 100644 --- a/sound/soc/codecs/rt711-sdw.c +++ b/sound/soc/codecs/rt711-sdw.c @@ -541,8 +541,15 @@ static int __maybe_unused rt711_dev_resume(struct device *dev) if (!rt711->first_hw_init) return 0;
- if (!slave->unattach_request) + if (!slave->unattach_request) { + if (rt711->disable_irq == true) { + mutex_lock(&rt711->disable_irq_lock); + sdw_write_no_pm(slave, SDW_SCP_INTMASK1, SDW_SCP_INT1_IMPL_DEF); + rt711->disable_irq = false; + mutex_unlock(&rt711->disable_irq_lock); + } goto regmap_sync; + }
time = wait_for_completion_timeout(&slave->initialization_complete, msecs_to_jiffies(RT711_PROBE_TIMEOUT));
From: Shuming Fan shumingf@realtek.com
[ Upstream commit 23adeb7056acd4fd866969f4afb91441776cc4f5 ]
When the system suspends, peripheral SDCA interrupts are disabled. When system level resume is invoked, the peripheral SDCA interrupts should be enabled to handle JD events. Enable SDCA interrupts in resume sequence when ClockStop Mode0 is applied.
Signed-off-by: Shuming Fan shumingf@realtek.com Reported-by: Vijendar Mukunda Vijendar.Mukunda@amd.com Link: https://lore.kernel.org/r/20230721090711.128247-1-shumingf@realtek.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/rt711-sdca-sdw.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/rt711-sdca-sdw.c b/sound/soc/codecs/rt711-sdca-sdw.c index 31e77d462ef34..4faf6b8544ddd 100644 --- a/sound/soc/codecs/rt711-sdca-sdw.c +++ b/sound/soc/codecs/rt711-sdca-sdw.c @@ -442,8 +442,16 @@ static int __maybe_unused rt711_sdca_dev_resume(struct device *dev) if (!rt711->first_hw_init) return 0;
- if (!slave->unattach_request) + if (!slave->unattach_request) { + if (rt711->disable_irq == true) { + mutex_lock(&rt711->disable_irq_lock); + sdw_write_no_pm(slave, SDW_SCP_SDCA_INTMASK1, SDW_SCP_SDCA_INTMASK_SDCA_0); + sdw_write_no_pm(slave, SDW_SCP_SDCA_INTMASK2, SDW_SCP_SDCA_INTMASK_SDCA_8); + rt711->disable_irq = false; + mutex_unlock(&rt711->disable_irq_lock); + } goto regmap_sync; + }
time = wait_for_completion_timeout(&slave->initialization_complete, msecs_to_jiffies(RT711_PROBE_TIMEOUT));
From: Guiting Shen aarongt.shen@gmail.com
[ Upstream commit f85739c0b2b0d98a32f5ca4fcc5501d2b76df4f6 ]
The 8K sample parameter of 12.288Mhz main system bus clock doesn't work because the I2SC_MR.IMCKDIV must not be 0 according to the sama5d2 series datasheet(I2SC Mode Register of Register Summary).
So use the 6.144Mhz instead of 12.288Mhz to support 8K sample.
Signed-off-by: Guiting Shen aarongt.shen@gmail.com Link: https://lore.kernel.org/r/20230715030620.62328-1-aarongt.shen@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/atmel/atmel-i2s.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/sound/soc/atmel/atmel-i2s.c b/sound/soc/atmel/atmel-i2s.c index 6b3d9c05eaf27..4cb0605f6daa2 100644 --- a/sound/soc/atmel/atmel-i2s.c +++ b/sound/soc/atmel/atmel-i2s.c @@ -163,11 +163,14 @@ struct atmel_i2s_gck_param {
#define I2S_MCK_12M288 12288000UL #define I2S_MCK_11M2896 11289600UL +#define I2S_MCK_6M144 6144000UL
/* mck = (32 * (imckfs+1) / (imckdiv+1)) * fs */ static const struct atmel_i2s_gck_param gck_params[] = { + /* mck = 6.144Mhz */ + { 8000, I2S_MCK_6M144, 1, 47}, /* mck = 768 fs */ + /* mck = 12.288MHz */ - { 8000, I2S_MCK_12M288, 0, 47}, /* mck = 1536 fs */ { 16000, I2S_MCK_12M288, 1, 47}, /* mck = 768 fs */ { 24000, I2S_MCK_12M288, 3, 63}, /* mck = 512 fs */ { 32000, I2S_MCK_12M288, 3, 47}, /* mck = 384 fs */
From: Takashi Iwai tiwai@suse.de
[ Upstream commit 3da435063777f8d861ba5a165344e3f75f839357 ]
Microsoft Modern Wireless Headset (appearing on the host as "Microsoft USB Link") has a playback and a capture mixer volume/switch, but they are fairly broken. The descriptor reports wrong dB ranges for playback, and the capture volume/switch don't influence on the actual recording at all. Moreover, there seem instabilities in the connection, and at best, we should disable the runtime PM.
So this ended up with a quirk entry for: - Correct the playback dB range; I picked up some reasonable values but it's a guess work - Disable the capture mixer; it's completely useless and confuses PA/PW - Suppress get-sample-rate, apply the delay for message handling, and suppress the auto-suspend
The behavior of the wheel control on the headset is somehow flaky, too, but it's an issue of HID.
Link: https://bugzilla.suse.com/show_bug.cgi?id=1207129 Link: https://lore.kernel.org/r/20230725092057.15115-1-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/usb/mixer_maps.c | 14 ++++++++++++++ sound/usb/quirks.c | 3 +++ 2 files changed, 17 insertions(+)
diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c index 3f8f6056ff6a5..8e0915f02b26f 100644 --- a/sound/usb/mixer_maps.c +++ b/sound/usb/mixer_maps.c @@ -366,6 +366,15 @@ static const struct usbmix_name_map corsair_virtuoso_map[] = { { 0 } };
+/* Microsoft USB Link headset */ +/* a guess work: raw playback volume values are from 2 to 129 */ +static const struct usbmix_dB_map ms_usb_link_dB = { -3225, 0, true }; +static const struct usbmix_name_map ms_usb_link_map[] = { + { 9, NULL, .dB = &ms_usb_link_dB }, + { 10, NULL }, /* Headset Capture volume; seems non-working, disabled */ + { 0 } /* terminator */ +}; + /* ASUS ROG Zenith II with Realtek ALC1220-VB */ static const struct usbmix_name_map asus_zenith_ii_map[] = { { 19, NULL, 12 }, /* FU, Input Gain Pad - broken response, disabled */ @@ -625,6 +634,11 @@ static const struct usbmix_ctl_map usbmix_ctl_maps[] = { .id = USB_ID(0x1395, 0x0025), .map = sennheiser_pc8_map, }, + { + /* Microsoft USB Link headset */ + .id = USB_ID(0x045e, 0x083c), + .map = ms_usb_link_map, + }, { 0 } /* terminator */ };
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 8de572e774ddc..e5eab3b84b3f7 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1747,6 +1747,9 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_IGNORE_CTL_ERROR), DEVICE_FLG(0x041e, 0x4080, /* Creative Live Cam VF0610 */ QUIRK_FLAG_GET_SAMPLE_RATE), + DEVICE_FLG(0x045e, 0x083c, /* MS USB Link headset */ + QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_CTL_MSG_DELAY | + QUIRK_FLAG_DISABLE_AUTOSUSPEND), DEVICE_FLG(0x046d, 0x084c, /* Logitech ConferenceCam Connect */ QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_CTL_MSG_DELAY_1M), DEVICE_FLG(0x046d, 0x0991, /* Logitech QuickCam Pro */
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit e3ab18de2b09361d6f0e4aafb9cfd6d002ce43a1 ]
On a HP Elite Dragonfly G2 the 0xcc and 0xcd events for SW_TABLET_MODE are only send after the BTNL ACPI method has been called.
Likely more devices need this, so make the BTNL ACPI method unconditional instead of only doing it on devices with a 5 button array.
Note this also makes the intel_button_array_enable() call in probe() unconditional, that function does its own priv->array check. This makes the intel_button_array_enable() call in probe() consistent with the calls done on suspend/resume which also rely on the priv->array check inside the function.
Reported-by: Maxim Mikityanskiy maxtram95@gmail.com Closes: https://lore.kernel.org/platform-driver-x86/20230712175023.31651-1-maxtram95... Signed-off-by: Hans de Goede hdegoede@redhat.com Link: https://lore.kernel.org/r/20230715181516.5173-1-hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/intel/hid.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-)
diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c index 4d1c78635114e..73ecbdfcfb7c0 100644 --- a/drivers/platform/x86/intel/hid.c +++ b/drivers/platform/x86/intel/hid.c @@ -608,7 +608,7 @@ static bool button_array_present(struct platform_device *device) static int intel_hid_probe(struct platform_device *device) { acpi_handle handle = ACPI_HANDLE(&device->dev); - unsigned long long mode; + unsigned long long mode, dummy; struct intel_hid_priv *priv; acpi_status status; int err; @@ -673,18 +673,15 @@ static int intel_hid_probe(struct platform_device *device) if (err) goto err_remove_notify;
- if (priv->array) { - unsigned long long dummy; + intel_button_array_enable(&device->dev, true);
- intel_button_array_enable(&device->dev, true); - - /* Call button load method to enable HID power button */ - if (!intel_hid_evaluate_method(handle, INTEL_HID_DSM_BTNL_FN, - &dummy)) { - dev_warn(&device->dev, - "failed to enable HID power button\n"); - } - } + /* + * Call button load method to enable HID power button + * Always do this since it activates events on some devices without + * a button array too. + */ + if (!intel_hid_evaluate_method(handle, INTEL_HID_DSM_BTNL_FN, &dummy)) + dev_warn(&device->dev, "failed to enable HID power button\n");
device_init_wakeup(&device->dev, true); /*
From: Maxim Mikityanskiy maxtram95@gmail.com
[ Upstream commit 7783e97f8558ad7a4d1748922461bc88483fbcdf ]
HP Elite Dragonfly G2 (a convertible laptop/tablet) has a reliable VGBS method. If VGBS is not called on boot, the firmware sends an initial 0xcd event shortly after calling the BTNL method, but only if the device is booted in the laptop mode. However, if the device is booted in the tablet mode and VGBS is not called, there is no initial 0xcc event, and the input device for SW_TABLET_MODE is not registered up until the user turns the device into the laptop mode.
Call VGBS on boot on this device to get the initial state of SW_TABLET_MODE in a reliable way.
Tested with BIOS 1.13.1.
Signed-off-by: Maxim Mikityanskiy maxtram95@gmail.com Link: https://lore.kernel.org/r/20230716183213.64173-1-maxtram95@gmail.com Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/intel/hid.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c index 73ecbdfcfb7c0..f59a3cc9767b9 100644 --- a/drivers/platform/x86/intel/hid.c +++ b/drivers/platform/x86/intel/hid.c @@ -138,6 +138,12 @@ static const struct dmi_system_id dmi_vgbs_allow_list[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Surface Go"), }, }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Elite Dragonfly G2 Notebook PC"), + }, + }, { } };
From: Konstantin Shelekhin k.shelekhin@ftml.net
[ Upstream commit c21733754cd6ecbca346f2adf9b17d4cfa50504f ]
Currently huawei-wmi causes a lot of spam in dmesg on my Huawei MateBook X Pro 2022:
... [36409.328463] input input9: Unknown key pressed, code: 0x02c1 [36411.335104] input input9: Unknown key pressed, code: 0x02c1 [36412.338674] input input9: Unknown key pressed, code: 0x02c1 [36414.848564] input input9: Unknown key pressed, code: 0x02c1 [36416.858706] input input9: Unknown key pressed, code: 0x02c1 ...
Fix that by ignoring events generated by ambient light sensor.
This issue was reported on GitHub and resolved with the following merge request:
https://github.com/aymanbagabas/Huawei-WMI/pull/70
I've contacted the mainter of this repo and he gave me the "go ahead" to send this patch to the maling list.
Signed-off-by: Konstantin Shelekhin k.shelekhin@ftml.net Link: https://lore.kernel.org/r/20230722155922.173856-1-k.shelekhin@ftml.net Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/huawei-wmi.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/platform/x86/huawei-wmi.c b/drivers/platform/x86/huawei-wmi.c index 935562c870c3d..23ebd0c046e16 100644 --- a/drivers/platform/x86/huawei-wmi.c +++ b/drivers/platform/x86/huawei-wmi.c @@ -86,6 +86,8 @@ static const struct key_entry huawei_wmi_keymap[] = { { KE_IGNORE, 0x293, { KEY_KBDILLUMTOGGLE } }, { KE_IGNORE, 0x294, { KEY_KBDILLUMUP } }, { KE_IGNORE, 0x295, { KEY_KBDILLUMUP } }, + // Ignore Ambient Light Sensoring + { KE_KEY, 0x2c1, { KEY_RESERVED } }, { KE_END, 0 } };
From: Leo Chen sancchen@amd.com
[ Upstream commit de612738e9771bd66aeb20044486c457c512f684 ]
[Why & How] DMUB may hang when powering down pixel clocks due to no dprefclk.
It is fixed by exiting idle optimization before the attempt to access PHY.
Reviewed-by: Nicholas Kazlauskas nicholas.kazlauskas@amd.com Acked-by: Alex Hung alex.hung@amd.com Signed-off-by: Leo Chen sancchen@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 46d7e75e4553e..52142d272c868 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -1744,10 +1744,13 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context) hws->funcs.edp_backlight_control(edp_link_with_sink, false); } /*resume from S3, no vbios posting, no need to power down again*/ + clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr); + power_down_all_hw_blocks(dc); disable_vga_and_power_gate_all_controllers(dc); if (edp_link_with_sink && !keep_edp_vdd_on) dc->hwss.edp_power_control(edp_link_with_sink, false); + clk_mgr_optimize_pwr_state(dc, dc->clk_mgr); } bios_set_scratch_acc_mode_change(dc->ctx->dc_bios, 1); }
From: Eric Snowberg eric.snowberg@oracle.com
[ Upstream commit 18b44bc5a67275641fb26f2c54ba7eef80ac5950 ]
Commit db1d1e8b9867 ("IMA: use vfs_getattr_nosec to get the i_version") partially closed an IMA integrity issue when directly modifying a file on the lower filesystem. If the overlay file is first opened by a user and later the lower backing file is modified by root, but the extended attribute is NOT updated, the signature validation succeeds with the old original signature.
Update the super_block s_iflags to SB_I_IMA_UNVERIFIABLE_SIGNATURE to force signature reevaluation on every file access until a fine grained solution can be found.
Signed-off-by: Eric Snowberg eric.snowberg@oracle.com Signed-off-by: Mimi Zohar zohar@linux.ibm.com Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/overlayfs/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 5310271cf2e38..e18025b5c8872 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -2140,7 +2140,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) ovl_trusted_xattr_handlers; sb->s_fs_info = ofs; sb->s_flags |= SB_POSIXACL; - sb->s_iflags |= SB_I_SKIP_SYNC; + sb->s_iflags |= SB_I_SKIP_SYNC | SB_I_IMA_UNVERIFIABLE_SIGNATURE;
err = -ENOMEM; root_dentry = ovl_get_root(sb, upperpath.dentry, oe);
From: Minjie Du duminjie@vivo.com
[ Upstream commit 4139f992c49356391fb086c0c8ce51f66c26d623 ]
It is possible for dma_request_chan() to return EPROBE_DEFER, which means acdev->host->dev is not ready yet. At this point dev_err() will have no output. Use dev_err_probe() instead.
Signed-off-by: Minjie Du duminjie@vivo.com Acked-by: Viresh Kumar viresh.kumar@linaro.org Reviewed-by: Sergey Shtylyov s.shtylyov@omp.ru Signed-off-by: Damien Le Moal dlemoal@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ata/pata_arasan_cf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index 63f39440a9b42..4ba02f082f962 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c @@ -528,7 +528,8 @@ static void data_xfer(struct work_struct *work) /* dma_request_channel may sleep, so calling from process context */ acdev->dma_chan = dma_request_chan(acdev->host->dev, "data"); if (IS_ERR(acdev->dma_chan)) { - dev_err(acdev->host->dev, "Unable to get dma_chan\n"); + dev_err_probe(acdev->host->dev, PTR_ERR(acdev->dma_chan), + "Unable to get dma_chan\n"); acdev->dma_chan = NULL; goto chan_request_fail; }
From: Ilya Dryomov idryomov@gmail.com
[ Upstream commit f38cb9d9c2045dad16eead4a2e1aedfddd94603b ]
Make the "num_lockers can be only 0 or 1" assumption explicit and simplify the API by getting rid of output parameters in preparation for calling get_lock_owner_info() twice before blocklisting.
Signed-off-by: Ilya Dryomov idryomov@gmail.com Reviewed-by: Dongsheng Yang dongsheng.yang@easystack.cn Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/rbd.c | 84 +++++++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 33 deletions(-)
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index a4188825bd195..189e2f74b9147 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -3851,10 +3851,17 @@ static void wake_lock_waiters(struct rbd_device *rbd_dev, int result) list_splice_tail_init(&rbd_dev->acquiring_list, &rbd_dev->running_list); }
-static int get_lock_owner_info(struct rbd_device *rbd_dev, - struct ceph_locker **lockers, u32 *num_lockers) +static void free_locker(struct ceph_locker *locker) +{ + if (locker) + ceph_free_lockers(locker, 1); +} + +static struct ceph_locker *get_lock_owner_info(struct rbd_device *rbd_dev) { struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; + struct ceph_locker *lockers; + u32 num_lockers; u8 lock_type; char *lock_tag; int ret; @@ -3863,39 +3870,45 @@ static int get_lock_owner_info(struct rbd_device *rbd_dev,
ret = ceph_cls_lock_info(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, RBD_LOCK_NAME, - &lock_type, &lock_tag, lockers, num_lockers); - if (ret) - return ret; + &lock_type, &lock_tag, &lockers, &num_lockers); + if (ret) { + rbd_warn(rbd_dev, "failed to retrieve lockers: %d", ret); + return ERR_PTR(ret); + }
- if (*num_lockers == 0) { + if (num_lockers == 0) { dout("%s rbd_dev %p no lockers detected\n", __func__, rbd_dev); + lockers = NULL; goto out; }
if (strcmp(lock_tag, RBD_LOCK_TAG)) { rbd_warn(rbd_dev, "locked by external mechanism, tag %s", lock_tag); - ret = -EBUSY; - goto out; + goto err_busy; }
if (lock_type == CEPH_CLS_LOCK_SHARED) { rbd_warn(rbd_dev, "shared lock type detected"); - ret = -EBUSY; - goto out; + goto err_busy; }
- if (strncmp((*lockers)[0].id.cookie, RBD_LOCK_COOKIE_PREFIX, + WARN_ON(num_lockers != 1); + if (strncmp(lockers[0].id.cookie, RBD_LOCK_COOKIE_PREFIX, strlen(RBD_LOCK_COOKIE_PREFIX))) { rbd_warn(rbd_dev, "locked by external mechanism, cookie %s", - (*lockers)[0].id.cookie); - ret = -EBUSY; - goto out; + lockers[0].id.cookie); + goto err_busy; }
out: kfree(lock_tag); - return ret; + return lockers; + +err_busy: + kfree(lock_tag); + ceph_free_lockers(lockers, num_lockers); + return ERR_PTR(-EBUSY); }
static int find_watcher(struct rbd_device *rbd_dev, @@ -3949,51 +3962,56 @@ static int find_watcher(struct rbd_device *rbd_dev, static int rbd_try_lock(struct rbd_device *rbd_dev) { struct ceph_client *client = rbd_dev->rbd_client->client; - struct ceph_locker *lockers; - u32 num_lockers; + struct ceph_locker *locker; int ret;
for (;;) { + locker = NULL; + ret = rbd_lock(rbd_dev); if (ret != -EBUSY) - return ret; + goto out;
/* determine if the current lock holder is still alive */ - ret = get_lock_owner_info(rbd_dev, &lockers, &num_lockers); - if (ret) - return ret; - - if (num_lockers == 0) + locker = get_lock_owner_info(rbd_dev); + if (IS_ERR(locker)) { + ret = PTR_ERR(locker); + locker = NULL; + goto out; + } + if (!locker) goto again;
- ret = find_watcher(rbd_dev, lockers); + ret = find_watcher(rbd_dev, locker); if (ret) goto out; /* request lock or error */
rbd_warn(rbd_dev, "breaking header lock owned by %s%llu", - ENTITY_NAME(lockers[0].id.name)); + ENTITY_NAME(locker->id.name));
ret = ceph_monc_blocklist_add(&client->monc, - &lockers[0].info.addr); + &locker->info.addr); if (ret) { - rbd_warn(rbd_dev, "blocklist of %s%llu failed: %d", - ENTITY_NAME(lockers[0].id.name), ret); + rbd_warn(rbd_dev, "failed to blocklist %s%llu: %d", + ENTITY_NAME(locker->id.name), ret); goto out; }
ret = ceph_cls_break_lock(&client->osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, RBD_LOCK_NAME, - lockers[0].id.cookie, - &lockers[0].id.name); - if (ret && ret != -ENOENT) + locker->id.cookie, &locker->id.name); + if (ret && ret != -ENOENT) { + rbd_warn(rbd_dev, "failed to break header lock: %d", + ret); goto out; + }
again: - ceph_free_lockers(lockers, num_lockers); + free_locker(locker); }
out: - ceph_free_lockers(lockers, num_lockers); + free_locker(locker); return ret; }
On Sun, Aug 13, 2023 at 6:09 PM Sasha Levin sashal@kernel.org wrote:
From: Ilya Dryomov idryomov@gmail.com
[ Upstream commit f38cb9d9c2045dad16eead4a2e1aedfddd94603b ]
Make the "num_lockers can be only 0 or 1" assumption explicit and simplify the API by getting rid of output parameters in preparation for calling get_lock_owner_info() twice before blocklisting.
Signed-off-by: Ilya Dryomov idryomov@gmail.com Reviewed-by: Dongsheng Yang dongsheng.yang@easystack.cn Signed-off-by: Sasha Levin sashal@kernel.org
Hi Sasha,
I think this patch, as well as "rbd: harden get_lock_owner_info() a bit", have already been applied to 5.15, 6.1 and 6.4 by Greg. The emails went out on Aug 1.
Thanks,
Ilya
From: Ilya Dryomov idryomov@gmail.com
[ Upstream commit 8ff2c64c9765446c3cef804fb99da04916603e27 ]
- we want the exclusive lock type, so test for it directly - use sscanf() to actually parse the lock cookie and avoid admitting invalid handles - bail if locker has a blank address
Signed-off-by: Ilya Dryomov idryomov@gmail.com Reviewed-by: Dongsheng Yang dongsheng.yang@easystack.cn Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/rbd.c | 21 +++++++++++++++------ net/ceph/messenger.c | 1 + 2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 189e2f74b9147..1d2ba739fb268 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -3864,10 +3864,9 @@ static struct ceph_locker *get_lock_owner_info(struct rbd_device *rbd_dev) u32 num_lockers; u8 lock_type; char *lock_tag; + u64 handle; int ret;
- dout("%s rbd_dev %p\n", __func__, rbd_dev); - ret = ceph_cls_lock_info(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, RBD_LOCK_NAME, &lock_type, &lock_tag, &lockers, &num_lockers); @@ -3888,18 +3887,28 @@ static struct ceph_locker *get_lock_owner_info(struct rbd_device *rbd_dev) goto err_busy; }
- if (lock_type == CEPH_CLS_LOCK_SHARED) { - rbd_warn(rbd_dev, "shared lock type detected"); + if (lock_type != CEPH_CLS_LOCK_EXCLUSIVE) { + rbd_warn(rbd_dev, "incompatible lock type detected"); goto err_busy; }
WARN_ON(num_lockers != 1); - if (strncmp(lockers[0].id.cookie, RBD_LOCK_COOKIE_PREFIX, - strlen(RBD_LOCK_COOKIE_PREFIX))) { + ret = sscanf(lockers[0].id.cookie, RBD_LOCK_COOKIE_PREFIX " %llu", + &handle); + if (ret != 1) { rbd_warn(rbd_dev, "locked by external mechanism, cookie %s", lockers[0].id.cookie); goto err_busy; } + if (ceph_addr_is_blank(&lockers[0].info.addr)) { + rbd_warn(rbd_dev, "locker has a blank address"); + goto err_busy; + } + + dout("%s rbd_dev %p got locker %s%llu@%pISpc/%u handle %llu\n", + __func__, rbd_dev, ENTITY_NAME(lockers[0].id.name), + &lockers[0].info.addr.in_addr, + le32_to_cpu(lockers[0].info.addr.nonce), handle);
out: kfree(lock_tag); diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 57d043b382ed0..9bf085ddbe51f 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c @@ -1144,6 +1144,7 @@ bool ceph_addr_is_blank(const struct ceph_entity_addr *addr) return true; } } +EXPORT_SYMBOL(ceph_addr_is_blank);
int ceph_addr_port(const struct ceph_entity_addr *addr) {
From: Christian Göttsche cgzones@googlemail.com
[ Upstream commit 2d7f105edbb3b2be5ffa4d833abbf9b6965e9ce7 ]
If the current task fails the check for the queried capability via `capable(CAP_SYS_ADMIN)` LSMs like SELinux generate a denial message. Issuing such denial messages unnecessarily can lead to a policy author granting more privileges to a subject than needed to silence them.
Reorder CAP_SYS_ADMIN checks after the check whether the operation is actually privileged.
Signed-off-by: Christian Göttsche cgzones@googlemail.com Reviewed-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- security/keys/keyctl.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 96a92a645216d..cfb5000876922 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -980,14 +980,19 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group) ret = -EACCES; down_write(&key->sem);
- if (!capable(CAP_SYS_ADMIN)) { + { + bool is_privileged_op = false; + /* only the sysadmin can chown a key to some other UID */ if (user != (uid_t) -1 && !uid_eq(key->uid, uid)) - goto error_put; + is_privileged_op = true;
/* only the sysadmin can set the key's GID to a group other * than one of those that the current process subscribes to */ if (group != (gid_t) -1 && !gid_eq(gid, key->gid) && !in_group_p(gid)) + is_privileged_op = true; + + if (is_privileged_op && !capable(CAP_SYS_ADMIN)) goto error_put; }
@@ -1088,7 +1093,7 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm) down_write(&key->sem);
/* if we're not the sysadmin, we can only change a key that we own */ - if (capable(CAP_SYS_ADMIN) || uid_eq(key->uid, current_fsuid())) { + if (uid_eq(key->uid, current_fsuid()) || capable(CAP_SYS_ADMIN)) { key->perm = perm; notify_key(key, NOTIFY_KEY_SETATTR, 0); ret = 0;
From: "Masami Hiramatsu (Google)" mhiramat@kernel.org
[ Upstream commit de02f2ac5d8cfb311f44f2bf144cc20002f1fbbd ]
Do not allow to probe on "__cfi_" or "__pfx_" started symbol, because those are used for CFI and not executed. Probing it will break the CFI.
Link: https://lore.kernel.org/all/168904024679.116016.18089228029322008512.stgit@d...
Signed-off-by: Masami Hiramatsu (Google) mhiramat@kernel.org Reviewed-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/kprobes.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 7e9fa1b7ff671..6cf561322bbe6 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -1545,6 +1545,17 @@ int __weak arch_check_ftrace_location(struct kprobe *p) return 0; }
+static bool is_cfi_preamble_symbol(unsigned long addr) +{ + char symbuf[KSYM_NAME_LEN]; + + if (lookup_symbol_name(addr, symbuf)) + return false; + + return str_has_prefix("__cfi_", symbuf) || + str_has_prefix("__pfx_", symbuf); +} + static int check_kprobe_address_safe(struct kprobe *p, struct module **probed_mod) { @@ -1563,7 +1574,8 @@ static int check_kprobe_address_safe(struct kprobe *p, within_kprobe_blacklist((unsigned long) p->addr) || jump_label_text_reserved(p->addr, p->addr) || static_call_text_reserved(p->addr, p->addr) || - find_bug((unsigned long)p->addr)) { + find_bug((unsigned long)p->addr) || + is_cfi_preamble_symbol((unsigned long)p->addr)) { ret = -EINVAL; goto out; }
linux-stable-mirror@lists.linaro.org