6.12.91-rc1 review
Subsystems (7)
Greg Kroah-Hartman
maintainerPATCH 110/666 Bluetooth: SCO: check for codecs->num_codecs == 1 before assigning to sco_pi(sk)->codec
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Metzmacher <[email protected]>
[ Upstream commit 4e10a9ebbf081c16517cdd9366ac618bf38d7d0c ]
copy_struct_from_sockptr() fill 'buffer' insco_sock_setsockopt() with zeros, so there's no
real problem.
But it actually looks strange to do this,
without checking all of codecs->codecs[0]
really comes from userspace:
sco_pi(sk)->codec = codecs->codecs[0];
As only optlen < sizeof(struct bt_codecs) is checked and codecs->num_codecs is not checked against != 1, but only <= 1, and the space for the additional struct bt_codec is not checked.
Note I don't understand bluetooth and I didn't do any runtime tests with this! I just found it when debugging a problem in copy_struct_from_sockptr().
I just added this to check the size is as expected:
BUILD_BUG_ON(struct_size(codecs, codecs, 0) != 1); BUILD_BUG_ON(struct_size(codecs, codecs, 1) != 8);
And made sure it still compiles using this:
make CF=-D__CHECK_ENDIAN__ W=1ce C=1 net/bluetooth/sco.o
--- net/bluetooth/sco.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/bluetooth/sco.c +2 -1
@@ -978,7 +978,8 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, codecs = (void *)buffer; -if (codecs->num_codecs >1 ) { +if (codecs->num_codecs !=1 || + optlen <struct_size (codecs, codecs, codecs->num_codecs)) {hci_dev_put (hdev); err = -EINVAL ;break ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 111/666 net: phy: qcom: at803x: Use the correct bit to disable extended next page
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maxime Chevallier <[email protected]>
[ Upstream commit e7a62edd34b1b4bc5f979988efc2f81c075733fd ]
As noted in the blamed commit, the AR8035 and other PHYs from this family advertise the Extended Next Page support by default, which may be understood by some partners as this PHY being multi-gig capable.
The fix is to disable XNP advertising, which is done by setting bit 12 of the Auto-Negotiation Advertisement Register (MII_ADVERTISE).
The blamed commit incorrectly uses MDIO_AN_CTRL1_XNP, which is bit 13 as per 802.3 : 45.2.7.1 AN control register (Register 7.0)
BIT 12 in MII_ADVERTISE is wrapped by ADVERTISE_RESV, used by some drivers such as the aquantia one. 802.3 Clause 28 defines bit 12 as Extended Next Page ability, at least in recent versions of the standard.
Let's add a define for it and use it in the at803x driver.
--- drivers/net/phy/qcom/at803x.c | 2 +- include/uapi/linux/mii.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-)
drivers/net/phy/qcom/at803x.c +1 -1
@@ -474,7 +474,7 @@ static int at803x_config_init(struct phy_device *phydev)* behaviour but we still need to accommodate it. XNP is only needed * for 10Gbps support, so disable XNP. */ -return phy_modify (phydev,MII_ADVERTISE ,MDIO_AN_CTRL1_XNP ,0 ); +return phy_modify (phydev,MII_ADVERTISE ,ADVERTISE_XNP ,0 ); }static void at803x_link_change_notify (struct phy_device *phydev)
include/uapi/linux/mii.h +2 -1
@@ -82,7 +82,8 @@#define ADVERTISE_100BASE4 0x0200/* Try for 100mbps 4k packets */ #define ADVERTISE_PAUSE_CAP 0x0400/* Try for pause */ #define ADVERTISE_PAUSE_ASYM 0x0800/* Try for asymetric pause */ -#define ADVERTISE_RESV 0x1000/* Unused... */ +#define ADVERTISE_XNP 0x1000/* Extended Next Page */ +#define ADVERTISE_RESV ADVERTISE_XNP/* Used to be reserved */ #define ADVERTISE_RFAULT 0x2000/* Say we can detect faults */ #define ADVERTISE_LPACK 0x4000/* Ack link partners response */ #define ADVERTISE_NPAGE 0x8000/* Next page bit */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 112/666 ipv4: udp: fix typos in comments
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alok Tiwari <[email protected]>
[ Upstream commit d436b5abba4f80e968b3ff83be4363c7aedcc799 ]
Correct typos in ipv4/udp.c comments for clarity:
"Encapulation" -> "Encapsulation"
"measureable" -> "measurable"
"tacking care" -> "taking care"
No functional changes.
Stable-dep-of: b80a95ccf160 ("udp: Force compute_score to always inline")
--- net/ipv4/udp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
net/ipv4/udp.c +3 -3
@@ -68,7 +68,7 @@* YOSHIFUJI Hideaki @USAGI and: Support IPV6_V6ONLY socket option, which * Alexey Kuznetsov: allow both IPv4 and IPv6 sockets to bind * a single port at the same time. -* Derek Atkins <[email protected]>: Add Encapulation Support +* Derek Atkins <[email protected]>: Add Encapsulation Support * James Chapman : Add L2TP encapsulation type. */
@@ -510,7 +510,7 @@ static struct sock *udp4_lib_lookup2(const struct net *net,/* compute_score is too long of a function to be * inlined, and calling it again here yields -* measureable overhead for some +* measurable overhead for some * workloads. Work around it by jumping * backwards to rescore 'result'. */
@@ -2414,7 +2414,7 @@ static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh,return 0 ; } -/* wrapper for udp_queue_rcv_skb tacking care of csum conversion and +/* wrapper for udp_queue_rcv_skb taking care of csum conversion and * return code conversion for ip layer consumption */ static int udp_unicast_rcv_skb(struct sock *sk, struct sk_buff *skb,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 113/666 ipv6: udp: fix typos in comments
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alok Tiwari <[email protected]>
[ Upstream commit ac36dea3bc85c2cde87e490736708032328dfbdc ]
Correct typos in ipv6/udp.c comments:
"execeeds" -> "exceeds"
"tacking care" -> "taking care"
"measureable" -> "measurable"
No functional changes.
Stable-dep-of: b80a95ccf160 ("udp: Force compute_score to always inline")
--- net/ipv6/udp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
net/ipv6/udp.c +3 -3
@@ -248,7 +248,7 @@ static struct sock *udp6_lib_lookup2(const struct net *net,/* compute_score is too long of a function to be * inlined, and calling it again here yields -* measureable overhead for some +* measurable overhead for some * workloads. Work around it by jumping * backwards to rescore 'result'. */
@@ -364,7 +364,7 @@ struct sock *udp6_lib_lookup(const struct net *net, const struct in6_addr *saddrEXPORT_SYMBOL_GPL (udp6_lib_lookup);#endif -/* do not use the scratch area len for jumbogram: their length execeeds the +/* do not use the scratch area len for jumbogram: their length exceeds the * scratch area space; note that the IP6CB flags is still in the first * cacheline, so checking for jumbograms is cheap */
@@ -964,7 +964,7 @@ static void udp6_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst) sk->sk_rx_dst_cookie =rt6_get_cookie (dst_rt6_info (dst)); } -/* wrapper for udp_queue_rcv_skb tacking care of csum conversion and +/* wrapper for udp_queue_rcv_skb taking care of csum conversion and * return code conversion for ip layer consumption */ static int udp6_unicast_rcv_skb(struct sock *sk, struct sk_buff *skb,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 114/666 udp: Force compute_score to always inline
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gabriel Krisman Bertazi <[email protected]>
[ Upstream commit b80a95ccf1604a882bb153c45ccb4056e44c8edb ]
Back in 2024 I reported a 7-12% regression on an iperf3 UDP loopback thoughput test that we traced to the extra overhead of calling compute_score on two places, introduced by commit f0ea27e7bfe1 ("udp:
re-score reuseport groups when connected sockets are present"). At the time, I pointed out the overhead was caused by the multiple calls, associated with cpu-specific mitigations, and merged commit 50aee97d1511 ("udp: Avoid call to compute_score on multiple sites") to jump back explicitly, to force the rescore call in a single place.
Recently though, we got another regression report against a newer distro version, which a team colleague traced back to the same root-cause. Turns out that once we updated to gcc-13, the compiler got smart enough to unroll the loop, undoing my previous mitigation. Let's bite the bullet and __always_inline compute_score on both ipv4 and ipv6 to prevent gcc from de-optimizing it again in the future. These functions are only called in two places each, udpX_lib_lookup1 and udpX_lib_lookup2, so the extra size shouldn't be a problem and it is hot enough to be very visible in profilings. In fact, with gcc13, forcing the inline will prevent gcc from unrolling the fix from commit 50aee97d1511, so we don't end up increasing udpX_lib_lookup2 at all.
I haven't recollected the results myself, as I don't have access to the machine at the moment. But the same colleague reported 4.67% inprovement with this patch in the loopback benchmark, solving the regression report within noise margins.
Eric Dumazet reported no size change to vmlinux when built with clang. I report the same also with gcc-13:
scripts/bloat-o-meter vmlinux vmlinux-inline add/remove: 0/2 grow/shrink: 4/0 up/down: 616/-416 (200)
Function old new delta udp6_lib_lookup2 762 949 +187 __udp6_lib_lookup 810 975 +165 udp4_lib_lookup2 757 906 +149 __udp4_lib_lookup 871 986 +115
__pfx_compute_score 32 - -32compute_score 384 - -384
Total: Before=35011784, After=35011984, chg +0.00%
--- net/ipv4/udp.c | 12 ++++++------ net/ipv6/udp.c | 13 +++++++------ 2 files changed, 13 insertions(+), 12 deletions(-)
net/ipv4/udp.c +6 -6
@@ -366,10 +366,10 @@ int udp_v4_get_port(struct sock *sk, unsigned short snum)return udp_lib_get_port (sk, snum, hash2_nulladdr); } -static int compute_score (struct sock *sk,const struct net *net, -__be32 saddr,__be16 sport, -__be32 daddr,unsigned short hnum, -int dif,int sdif) +static __always_inline int +compute_score (struct sock *sk,const struct net *net, +__be32 saddr,__be16 sport,__be32 daddr, +unsigned short hnum,int dif,int sdif) {int score;struct inet_sock *inet;
@@ -509,8 +509,8 @@ static struct sock *udp4_lib_lookup2(const struct net *net,continue ;/* compute_score is too long of a function to be -* inlined, and calling it again here yields -* measurable overhead for some +* inlined twice here, and calling it uninlined +* here yields measurable overhead for some * workloads. Work around it by jumping * backwards to rescore 'result'. */
net/ipv6/udp.c +7 -6
@@ -114,10 +114,11 @@ void udp_v6_rehash(struct sock *sk)udp_lib_rehash (sk, new_hash); } -static int compute_score (struct sock *sk,const struct net *net, -const struct in6_addr *saddr,__be16 sport, -const struct in6_addr *daddr,unsigned short hnum, -int dif,int sdif) +static __always_inline int +compute_score (struct sock *sk,const struct net *net, +const struct in6_addr *saddr,__be16 sport, +const struct in6_addr *daddr,unsigned short hnum, +int dif,int sdif) {int bound_dev_if, score;struct inet_sock *inet;
@@ -247,8 +248,8 @@ static struct sock *udp6_lib_lookup2(const struct net *net,continue ;/* compute_score is too long of a function to be -* inlined, and calling it again here yields -* measurable overhead for some +* inlined twice here, and calling it uninlined +* here yields measurable overhead for some * workloads. Work around it by jumping * backwards to rescore 'result'. */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 115/666 tcp: Dont set treq->req_usec_ts in cookie_tcp_reqsk_init().
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit c058bbf05b1197c33df7204842665bd8bc70b3a8 ]
Commit de5626b95e13 ("tcp: Factorise cookie-independent fields initialisation in cookie_v[46]_check().") miscategorised tcp_rsk(req)->req_usec_ts init to cookie_tcp_reqsk_init(), which is used by both BPF/non-BPF SYN cookie reqsk.
Rather, it should have been moved to cookie_tcp_reqsk_alloc() by commit 8e7bab6b9652 ("tcp: Factorise cookie-dependent fields initialisation in cookie_v[46]_check()") so that only non-BPF SYN cookie sets tcp_rsk(req)->req_usec_ts to false.
Let's move the initialisation to cookie_tcp_reqsk_alloc() to respect bpf_tcp_req_attrs.usec_ts_ok.
--- net/ipv4/syncookies.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv4/syncookies.c +1 -1
@@ -284,7 +284,6 @@ static int cookie_tcp_reqsk_init(struct sock *sk, struct sk_buff *skb, treq->rcv_isn =ntohl (th->seq) -1 ; treq->snt_isn =ntohl (th->ack_seq) -1 ; treq->syn_tos =TCP_SKB_CB (skb)->ip_dsfield; - treq->req_usec_ts = false;#if IS_ENABLED (CONFIG_MPTCP ) treq->is_mptcp =sk_is_mptcp (sk);
@@ -347,6 +346,7 @@ struct request_sock *cookie_tcp_reqsk_alloc(const struct request_sock_ops *ops, ireq->wscale_ok = tcp_opt->wscale_ok; ireq->ecn_ok = !!(tcp_opt->rcv_tsecr &TS_OPT_ECN ); + treq->req_usec_ts = false; treq->ts_off = tsoff;return req;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 116/666 sctp: fix missing encap_port propagation for GSO fragments
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xin Long <[email protected]>
[ Upstream commit bf6f95ae3b8b2638c0e1d6d802d50983ce5d0f45 ]
encap_port in SCTP_INPUT_CB(skb) is used by sctp_vtag_verify() for SCTP-over-UDP processing. In the GSO case, it is only set on the head skb, while fragment skbs leave it 0.
This results in fragment skbs seeing encap_port == 0, breaking SCTP-over-UDP connections.
Fix it by propagating encap_port from the head skb cb when initializing fragment skbs in sctp_inq_pop().
--- net/sctp/inqueue.c | 1 + 1 file changed, 1 insertion(+)
net/sctp/inqueue.c +1 -0
@@ -201,6 +201,7 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue) cb->chunk = head_cb->chunk; cb->af = head_cb->af; + cb->encap_port = head_cb->encap_port; } }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 117/666 net, bpf: fix null-ptr-deref in xdp_master_redirect() for down master
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <[email protected]>
[ Upstream commit 1921f91298d1388a0bb9db8f83800c998b649cb3 ]
syzkaller reported a kernel panic in bond_rr_gen_slave_id() reached via xdp_master_redirect(). Full decoded trace:
https://syzkaller.appspot.com/bug?extid=80e046b8da2820b6ba73
bond_rr_gen_slave_id() dereferences bond->rr_tx_counter, a per-CPU counter that bonding only allocates in bond_open() when the mode is round-robin. If the bond device was never brought up, rr_tx_counter stays NULL.
The XDP redirect path can still reach that code on a bond that was never opened: bpf_master_redirect_enabled_key is a global static key, so as soon as any bond device has native XDP attached, the XDP_TX -> xdp_master_redirect() interception is enabled for every slave system-wide. The path xdp_master_redirect() -> bond_xdp_get_xmit_slave() -> bond_xdp_xmit_roundrobin_slave_get() -> bond_rr_gen_slave_id() then runs against a bond that has no rr_tx_counter and crashes.
Fix this in the generic xdp_master_redirect() by refusing to call into the master's ->ndo_xdp_get_xmit_slave() when the master device is not up. IFF_UP is only set after ->ndo_open() has successfully returned, so this reliably excludes masters whose XDP state has not been fully initialized. Drop the frame with XDP_ABORTED so the exception is visible via trace_xdp_exception() rather than silently falling through. This is not specific to bonding: any current or future master that defers XDP state allocation to ->ndo_open() is protected.
--- net/core/filter.c | 2 ++ 1 file changed, 2 insertions(+)
net/core/filter.c +2 -0
@@ -4388,6 +4388,8 @@ u32 xdp_master_redirect(struct xdp_buff *xdp)struct net_device *master, *slave; master =netdev_master_upper_dev_get_rcu (xdp->rxq->dev); +if (unlikely (!(master->flags &IFF_UP ))) +return XDP_ABORTED ; slave = master->netdev_ops->ndo_xdp_get_xmit_slave (master, xdp);if (slave && slave != xdp->rxq->dev) {/* The target device is different from the receiving device, so
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 118/666 drm/komeda: fix integer overflow in AFBC framebuffer size check
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Konyukhov <[email protected]>
[ Upstream commit 779ec12c85c9e4547519e3903a371a3b26a289de ]
The AFBC framebuffer size validation calculates the minimum required buffer size by adding the AFBC payload size to the framebuffer offset. This addition is performed without checking for integer overflow.
If the addition oveflows, the size check may incorrectly succed and allow userspace to provide an undersized drm_gem_object, potentially leading to out-of-bounds memory access.
Add usage of check_add_overflow() to safely compute the minimum required size and reject the framebuffer if an overflow is detected. This makes the AFBC size validation more robust against malformed.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c +5 -1
@@ -4,6 +4,8 @@* Author: James.Qian.Wang <[email protected]> * */ +#include <linux/overflow.h> +#include <drm/drm_device.h> #include <drm/drm_fb_dma_helper.h> #include <drm/drm_gem.h>
@@ -92,7 +94,9 @@ komeda_fb_afbc_size_check(struct komeda_fb *kfb, struct drm_file *file, kfb->afbc_size = kfb->offset_payload + n_blocks *ALIGN (bpp *AFBC_SUPERBLK_PIXELS /8 ,AFBC_SUPERBLK_ALIGNMENT ); - min_size = kfb->afbc_size + fb->offsets[0 ]; +if (check_add_overflow (kfb->afbc_size, fb->offsets[0 ], &min_size)) { + goto check_failed; + }if (min_size > obj->size) {DRM_DEBUG_KMS ("afbc size check failed, obj_size: 0x%zx. min_size 0x%llx.\n" , obj->size, min_size);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 119/666 ASoC: SOF: ipc3: Use standard dev_dbg API
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Baluta <[email protected]>
[ Upstream commit 55c39835ee0ef94593a78f6ea808138d476f3b81 ]
Use standard dev_dbg API because it gives better debugging information and allows dynamic control of prints.
Stable-dep-of: 07c774dd64ba ("ASoC: soc-compress: use function to clear symmetric params")
--- sound/soc/sof/ipc3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/sof/ipc3.c +1 -1
@@ -226,7 +226,7 @@ static inline void ipc3_log_header(struct device *dev, u8 *text, u32 cmd)static void sof_ipc3_dump_payload (struct snd_sof_dev *sdev,void *ipc_data,size_t size) { -printk (KERN_DEBUG "Size of payload following the header: %zu\n" , size); +dev_dbg (sdev->dev,"Size of payload following the header: %zu\n" , size);print_hex_dump_debug ("Message payload: " ,DUMP_PREFIX_OFFSET ,16 ,4 , ipc_data, size, false); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 120/666 ASoC: add symmetric_ prefix for dai->rate/channels/sample_bits
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuninori Morimoto <[email protected]>
[ Upstream commit 1bd775da9ba919b87b2313a78d5957afc1a62dde ]
snd_soc_dai has rate/channels/sample_bits parameter, but it is only valid if symmetry is being enforced by symmetric_xxx flag on driver.
It is very difficult to know about it from current naming, and easy to misunderstand it. add symmetric_ prefix for it.
Stable-dep-of: 07c774dd64ba ("ASoC: soc-compress: use function to clear symmetric params")
--- include/sound/soc-dai.h | 6 ++--- sound/soc/mediatek/mt8188/mt8188-dai-pcm.c | 2 +- sound/soc/mediatek/mt8195/mt8195-dai-pcm.c | 2 +- sound/soc/mediatek/mt8365/mt8365-dai-dmic.c | 6 ++--- sound/soc/mediatek/mt8365/mt8365-dai-pcm.c | 2 +- sound/soc/soc-compress.c | 4 +-- sound/soc/soc-pcm.c | 29 +++++++++++---------- 7 files changed, 26 insertions(+), 25 deletions(-)
include/sound/soc-dai.h +3 -3
@@ -450,9 +450,9 @@ struct snd_soc_dai {struct snd_soc_dai_stream stream[SNDRV_PCM_STREAM_LAST +1 ];/* Symmetry data - only valid if symmetry is being enforced */ -unsigned int rate; -unsigned int channels; -unsigned int sample_bits; +unsigned int symmetric_rate; +unsigned int symmetric_channels; +unsigned int symmetric_sample_bits;/* parent platform/codec */ struct snd_soc_component *component;
sound/soc/mediatek/mt8188/mt8188-dai-pcm.c +1 -1
@@ -128,7 +128,7 @@ static int mtk_dai_pcm_configure(struct snd_pcm_substream *substream,unsigned int lrck_inv;unsigned int bck_inv;unsigned int fmt; -unsigned int bit_width = dai->sample_bits; +unsigned int bit_width = dai->symmetric_sample_bits;unsigned int val =0 ;unsigned int mask =0 ;int fs =0 ;
sound/soc/mediatek/mt8195/mt8195-dai-pcm.c +1 -1
@@ -127,7 +127,7 @@ static int mtk_dai_pcm_configure(struct snd_pcm_substream *substream,unsigned int lrck_inv;unsigned int bck_inv;unsigned int fmt; -unsigned int bit_width = dai->sample_bits; +unsigned int bit_width = dai->symmetric_sample_bits;unsigned int val =0 ;unsigned int mask =0 ;int fs =0 ;
sound/soc/mediatek/mt8365/mt8365-dai-dmic.c +3 -3
@@ -118,13 +118,13 @@ static int mt8365_dai_configure_dmic(struct mtk_base_afe *afe,unsigned int clk_phase_sel_ch1 = dmic_data->clk_phase_sel_ch1;unsigned int clk_phase_sel_ch2 = dmic_data->clk_phase_sel_ch2;unsigned int val =0 ; -unsigned int rate = dai->rate; -int reg =get_chan_reg (dai->channels); +unsigned int rate = dai->symmetric_rate; +int reg =get_chan_reg (dai->symmetric_channels);if (reg <0 )return -EINVAL ; - dmic_data->dmic_channel = dai->channels; + dmic_data->dmic_channel = dai->symmetric_channels; val |=DMIC_TOP_CON_SDM3_LEVEL_MODE ;
sound/soc/mediatek/mt8365/mt8365-dai-pcm.c +1 -1
@@ -44,7 +44,7 @@ static int mt8365_dai_configure_pcm1(struct snd_pcm_substream *substream,bool lrck_inv = pcm_priv->lrck_inv;bool bck_inv = pcm_priv->bck_inv;unsigned int fmt = pcm_priv->format; -unsigned int bit_width = dai->sample_bits; +unsigned int bit_width = dai->symmetric_sample_bits;unsigned int val =0 ;if (!slave_mode) {
sound/soc/soc-compress.c +2 -2
@@ -69,10 +69,10 @@ static int soc_compr_clean(struct snd_compr_stream *cstream, int rollback)snd_soc_dai_digital_mute (codec_dai,1 , stream);if (!snd_soc_dai_active (cpu_dai)) - cpu_dai->rate =0 ; + cpu_dai->symmetric_rate =0 ;if (!snd_soc_dai_active (codec_dai)) - codec_dai->rate =0 ; + codec_dai->symmetric_rate =0 ;snd_soc_link_compr_shutdown (cstream, rollback);
sound/soc/soc-pcm.c +15 -14
@@ -462,13 +462,13 @@ static void soc_pcm_set_dai_params(struct snd_soc_dai *dai, struct snd_pcm_hw_params *params) {if (params) { - dai->rate =params_rate (params); - dai->channels =params_channels (params); - dai->sample_bits =snd_pcm_format_physical_width (params_format (params)); + dai->symmetric_rate =params_rate (params); + dai->symmetric_channels =params_channels (params); + dai->symmetric_sample_bits =snd_pcm_format_physical_width (params_format (params)); }else { - dai->rate =0 ; - dai->channels =0 ; - dai->sample_bits =0 ; + dai->symmetric_rate =0 ; + dai->symmetric_channels =0 ; + dai->symmetric_sample_bits =0 ; } }
@@ -482,14 +482,14 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream,return 0 ;#define __soc_pcm_apply_symmetry (name,NAME ) \ - if (soc_dai->name && (soc_dai->driver->symmetric_##name || \ - rtd->dai_link->symmetric_##name)) { \ + if (soc_dai->symmetric_##name && \ + (soc_dai->driver->symmetric_##name || rtd->dai_link->symmetric_##name)) { \ dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %s to %d\n",\ - #name, soc_dai->name); \ + #name, soc_dai->symmetric_##name); \ \ ret = snd_pcm_hw_constraint_single(substream->runtime, \ SNDRV_PCM_HW_PARAM_##NAME,\ - soc_dai->name); \ + soc_dai->symmetric_##name); \ if (ret < 0) { \ dev_err(soc_dai->dev, \ "ASoC: Unable to apply %s constraint: %d\n",\
@@ -525,9 +525,11 @@ static int soc_pcm_params_symmetry(struct snd_pcm_substream *substream, if (symmetry) \ for_each_rtd_cpu_dais(rtd, i, cpu_dai) \ if (!snd_soc_dai_is_dummy(cpu_dai) && \ - cpu_dai->xxx && cpu_dai->xxx != d.xxx) { \ + cpu_dai->symmetric_##xxx && \ + cpu_dai->symmetric_##xxx != d.symmetric_##xxx) { \ dev_err(rtd->dev, "ASoC: unmatched %s symmetry: %s:%d - %s:%d\n", \ - #xxx, cpu_dai->name, cpu_dai->xxx, d.name, d.xxx); \ + #xxx, cpu_dai->name, cpu_dai->symmetric_##xxx, \ + d.name, d.symmetric_##xxx); \ return -EINVAL; \ }
@@ -798,8 +800,7 @@ static int soc_pcm_clean(struct snd_soc_pcm_runtime *rtd,/* Make sure DAI parameters cleared if the DAI becomes inactive */ for_each_rtd_dais (rtd, i, dai) { -if (snd_soc_dai_active (dai) ==0 && - (dai->rate || dai->channels || dai->sample_bits)) +if (snd_soc_dai_active (dai) ==0 )soc_pcm_set_dai_params (dai,NULL ); } }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 121/666 ASoC: soc-compress: use function to clear symmetric params
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuninori Morimoto <[email protected]>
[ Upstream commit 07c774dd64ba0c605dbf844132122e3edbdbea93 ]
Current soc-compress.c clears symmetric_rate, but it clears rate only, not clear other symmetric_channels/sample_bits.
static int soc_compr_clean(...)
{
...
if (!snd_soc_dai_active(cpu_dai))=> cpu_dai->symmetric_rate = 0;
if (!snd_soc_dai_active(codec_dai)) => codec_dai->symmetric_rate = 0; ... };
This feature was added when v3.7 kernel [1], and there was only symmetric_rate, no symmetric_channels/sample_bits in that timing.
symmetric_channels/sample_bits were added in v3.14 [2],
but I guess it didn't notice that soc-compress.c is updating symmetric_xxx.
We are clearing symmetry_xxx by soc_pcm_set_dai_params(), but is soc-pcm.c local function. Makes it global function and clear symmetry_xxx by it.
[1] commit 1245b7005de02 ("ASoC: add compress stream support")
[2] commit 3635bf09a89cf ("ASoC: soc-pcm: add symmetry for channels and sample bits")
--- include/sound/soc.h | 3 +++ sound/soc/soc-compress.c | 4 ++-- sound/soc/soc-pcm.c | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-)
include/sound/soc.h +3 -0
@@ -1452,6 +1452,9 @@ struct snd_soc_dai *snd_soc_find_dai(struct snd_soc_dai *snd_soc_find_dai_with_mutex (const struct snd_soc_dai_link_component *dlc); +void soc_pcm_set_dai_params (struct snd_soc_dai *dai, +struct snd_pcm_hw_params *params); +#include <sound/soc-dai.h> static inline
sound/soc/soc-compress.c +2 -2
@@ -69,10 +69,10 @@ static int soc_compr_clean(struct snd_compr_stream *cstream, int rollback)snd_soc_dai_digital_mute (codec_dai,1 , stream);if (!snd_soc_dai_active (cpu_dai)) - cpu_dai->symmetric_rate =0 ; +soc_pcm_set_dai_params (cpu_dai,NULL );if (!snd_soc_dai_active (codec_dai)) - codec_dai->symmetric_rate =0 ; +soc_pcm_set_dai_params (codec_dai,NULL );snd_soc_link_compr_shutdown (cstream, rollback);
sound/soc/soc-pcm.c +2 -2
@@ -458,8 +458,8 @@ int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir,return 0 ; } -static void soc_pcm_set_dai_params (struct snd_soc_dai *dai, -struct snd_pcm_hw_params *params) +void soc_pcm_set_dai_params (struct snd_soc_dai *dai, +struct snd_pcm_hw_params *params) {if (params) { dai->symmetric_rate =params_rate (params);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 122/666 drm/sun4i: backend: fix error pointer dereference
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ethan Tidmore <[email protected]>
[ Upstream commit 06277983eca4a31d3c2114fa33d99a6e82484b11 ]
The function drm_atomic_get_plane_state() can return an error pointer and is not checked for it. Add error pointer check.
Detected by Smatch:drivers/gpu/drm/sun4i/sun4i_backend.c:496 sun4i_backend_atomic_check() error:
'plane_state' dereferencing possible ERR_PTR()
--- drivers/gpu/drm/sun4i/sun4i_backend.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/sun4i/sun4i_backend.c +3 -0
@@ -490,6 +490,9 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine,drm_for_each_plane_mask (plane, drm, crtc_state->plane_mask) {struct drm_plane_state *plane_state =drm_atomic_get_plane_state (state, plane); +if (IS_ERR (plane_state)) +return PTR_ERR (plane_state); +struct sun4i_layer_state *layer_state =state_to_sun4i_layer_state (plane_state);struct drm_framebuffer *fb = plane_state->fb;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 123/666 ASoC: sti: Return errors from regmap_field_alloc()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sander Vanheule <[email protected]>
[ Upstream commit 272aabef50bc3fe58edd26de000f4cdd41bdbe60 ]
When regmap_field_alloc() fails, it can return an error. Specifically, it will return PTR_ERR(-ENOMEM) when the allocation returns a NULL pointer. The code then uses these allocations with a simple NULL check:
if (player->clk_sel) {
// May dereference invalid pointer (-ENOMEM)
err = regmap_field_write(player->clk_sel, ...);
}Ensure initialization fails by forwarding the errors from regmap_field_alloc(), thus avoiding the use of the invalid pointers.
--- sound/soc/sti/uniperif_player.c | 5 +++++ 1 file changed, 5 insertions(+)
sound/soc/sti/uniperif_player.c +5 -0
@@ -1029,7 +1029,12 @@ static int uni_player_parse_dt_audio_glue(struct platform_device *pdev, } player->clk_sel =regmap_field_alloc (regmap, regfield[0 ]); +if (IS_ERR (player->clk_sel)) +return PTR_ERR (player->clk_sel); + player->valid_sel =regmap_field_alloc (regmap, regfield[1 ]); +if (IS_ERR (player->valid_sel)) +return PTR_ERR (player->valid_sel);return 0 ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 124/666 ASoC: sti: use managed regmap_field allocations
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sander Vanheule <[email protected]>
[ Upstream commit 1696fad8b259a2d46e51cd6e17e4bcdbe02279fa ]
The regmap_field objects allocated at player init are never freed and may leak resources if the driver is removed.
Switch to devm_regmap_field_alloc() to automatically limit the lifetime of the allocations the lifetime of the device.
--- sound/soc/sti/uniperif_player.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/sti/uniperif_player.c +2 -2
@@ -1028,11 +1028,11 @@ static int uni_player_parse_dt_audio_glue(struct platform_device *pdev,return PTR_ERR (regmap); } - player->clk_sel =regmap_field_alloc (regmap, regfield[0 ]); + player->clk_sel =devm_regmap_field_alloc (&pdev->dev, regmap, regfield[0 ]);if (IS_ERR (player->clk_sel))return PTR_ERR (player->clk_sel); - player->valid_sel =regmap_field_alloc (regmap, regfield[1 ]); + player->valid_sel =devm_regmap_field_alloc (&pdev->dev, regmap, regfield[1 ]);if (IS_ERR (player->valid_sel))return PTR_ERR (player->valid_sel);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 125/666 dm cache: fix null-deref with concurrent writes in passthrough mode
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming-Hung Tsai <[email protected]>
[ Upstream commit 7d1f98d668ee34c1d15bdc0420fdd062f24a27c0 ]
In passthrough mode, when dm-cache starts to invalidate a cache entry and bio prison cell lock fails due to concurrent write to the same cached block, mg->cell remains NULL. The error path in invalidate_complete() attempts to unlock and free the cell unconditionally, causing a NULL pointer dereference:
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] CPU: 0 UID: 0 PID: 134 Comm: fio Not tainted 6.19.0-rc7 #3 PREEMPT RIP: 0010:dm_cell_unlock_v2+0x3f/0x210 <snip> Call Trace: invalidate_complete+0xef/0x430 map_bio+0x130f/0x1a10 cache_map+0x320/0x6b0 __map_bio+0x458/0x510 dm_submit_bio+0x40e/0x16d0 __submit_bio+0x419/0x870
<snip>
Reproduce steps:
1. Create a cache device
dmsetup create cmeta --table "0 8192 linear /dev/sdc 0" dmsetup create cdata --table "0 131072 linear /dev/sdc 8192" dmsetup create corig --table "0 262144 linear /dev/sdc 262144" dd if=/dev/zero of=/dev/mapper/cmeta bs=4k count=1 oflag=direct dmsetup create cache --table "0 262144 cache /dev/mapper/cmeta \/dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 writethrough smq 0"
2. Promote the first data block into cache
fio --filename=/dev/mapper/cache --name=populate --rw=write --bs=4k \
--direct=1 --size=64k
3. Reload the cache into passthrough mode
dmsetup suspend cache
dmsetup reload cache --table "0 262144 cache /dev/mapper/cmeta \/dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 passthrough smq 0" dmsetup resume cache
4. Write to the first cached block concurrently
fio --filename=/dev/mapper/cache --name test --rw=randwrite --bs=4k \
--randrepeat=0 --direct=1 --numjobs=2 --size 64k
Fix by checking if mg->cell is valid before attempting to unlock it.
--- drivers/md/dm-cache-target.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/md/dm-cache-target.c +4 -2
@@ -1456,8 +1456,10 @@ static void invalidate_complete(struct dm_cache_migration *mg, bool success)struct cache *cache = mg->cache;bio_list_init (&bios); -if (dm_cell_unlock_v2 (cache->prison, mg->cell, &bios)) -free_prison_cell (cache, mg->cell); +if (mg->cell) { +if (dm_cell_unlock_v2 (cache->prison, mg->cell, &bios)) +free_prison_cell (cache, mg->cell); + }if (!success && mg->overwrite_bio)bio_io_error (mg->overwrite_bio);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 126/666 dm cache: fix write path cache coherency in passthrough mode
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming-Hung Tsai <[email protected]>
[ Upstream commit 0c5eef0aad508231d8e43ff8392692925e131b68 ]
In passthrough mode, dm-cache defers write bio submission until cache invalidation completes to maintain existing coherency, requiring the target map function to return DM_MAPIO_SUBMITTED. The current map_bio() returns DM_MAPIO_REMAPPED, violating the required ordering constraint.
Reproduce steps:
1. Create a cache device
dmsetup create cmeta --table "0 8192 linear /dev/sdc 0" dmsetup create cdata --table "0 131072 linear /dev/sdc 8192" dmsetup create corig --table "0 262144 linear /dev/sdc 262144" dd if=/dev/zero of=/dev/mapper/cmeta bs=4k count=1 oflag=direct dmsetup create cache --table "0 262144 cache /dev/mapper/cmeta \/dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 writethrough smq 0"
2. Promote the first data block into the cache
fio --filename=/dev/mapper/cache --name=populate --rw=write --bs=4k \
--direct=1 --size=64k
3. Reload the cache into passthrough mode
dmsetup suspend cache
dmsetup reload cache --table "0 262144 cache /dev/mapper/cmeta \/dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 passthrough smq 0" dmsetup resume cache
4. Write to the first data block, and check io ordering using ftrace
echo 1 > /sys/kernel/debug/tracing/events/block/block_bio_queue/enable echo 1 > /sys/kernel/debug/tracing/events/block/block_bio_complete/enable echo 1 > /sys/kernel/debug/tracing/events/block/block_rq_complete/enable fio --filename=/dev/mapper/cache --name=test --rw=write --bs=64k \
--direct=1 --size 64k
5. ftrace logs show that write operations to the cache origin (252:2) and metadata operations (252:0) are unsynchronized: the origin write occurs before metadata commit.
<snip>
fio-146 [000] ..... 420.139562: block_bio_queue: 252,3 WS 0 + 128 [fio]
fio-146 [000] ..... 420.149395: block_bio_queue: 252,2 WS 0 + 128 [fio]
fio-146 [000] ..... 420.149763: block_bio_queue: 8,32 WS 262144 + 128 [fio]
fio-146 [000] dNh1. 420.151446: block_rq_complete: 8,32 WS () 262144 + 128 be,0,4 [0]
fio-146 [000] dNh1. 420.152731: block_bio_complete: 252,2 WS 0 + 128 [0]
fio-146 [000] dNh1. 420.154229: block_bio_complete: 252,3 WS 0 + 128 [0]
kworker/0:0-9 [000] ..... 420.160530: block_bio_queue: 252,0 W 408 + 8 [kworker/0:0]
kworker/0:0-9 [000] ..... 420.161641: block_bio_queue: 8,32 W 408 + 8 [kworker/0:0]
kworker/0:0-9 [000] ..... 420.162533: block_bio_queue: 252,0 W 416 + 8 [kworker/0:0]
kworker/0:0-9 [000] ..... 420.162821: block_bio_queue: 8,32 W 416 + 8 [kworker/0:0]<snip>
--- drivers/md/dm-cache-target.c | 1 + 1 file changed, 1 insertion(+)
drivers/md/dm-cache-target.c +1 -0
@@ -1697,6 +1697,7 @@ static int map_bio(struct cache *cache, struct bio *bio, dm_oblock_t block,bio_drop_shared_lock (cache, bio);atomic_inc (&cache->stats.demotion);invalidate_start (cache, cblock, block, bio); +return DM_MAPIO_SUBMITTED ; }else remap_to_origin_clear_discard (cache, bio, block); }else {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 127/666 dm cache: fix write hang in passthrough mode
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming-Hung Tsai <[email protected]>
[ Upstream commit 4ca8b8bd952df7c3ccdc68af9bd3419d0839a04b ]
The invalidate_remove() function has incomplete logic for handling write hit bios after cache invalidation. It sets up the remapping for the overwrite_bio but then drops it immediately without submission, causing write operations to hang.
Fix by adding a new invalidate_committed() continuation that submits the remapped writes to the cache origin after metadata commit completes, while using the overwrite_endio hook to ensure proper completion sequencing. This maintains existing coherency. Also improve error handling in invalidate_complete() to preserve the original error status instead of using bio_io_error() unconditionally.
--- drivers/md/dm-cache-target.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-)
drivers/md/dm-cache-target.c +25 -5
@@ -1461,8 +1461,14 @@ static void invalidate_complete(struct dm_cache_migration *mg, bool success)free_prison_cell (cache, mg->cell); } -if (!success && mg->overwrite_bio) -bio_io_error (mg->overwrite_bio); +if (mg->overwrite_bio) { +// Set generic error if the bio hasn't been issued yet, +// e.g., invalidation or metadata commit failed before bio +// submission. Otherwise preserve the bio's own error status. +if (!success && !mg->overwrite_bio->bi_status) + mg->overwrite_bio->bi_status =BLK_STS_IOERR ; +bio_endio (mg->overwrite_bio); + }free_migration (mg);defer_bios (cache, &bios);
@@ -1502,6 +1508,22 @@ static int invalidate_cblock(struct cache *cache, dm_cblock_t cblock)return r; } +static void invalidate_committed (struct work_struct *ws) +{ +struct dm_cache_migration *mg =ws_to_mg (ws); +struct cache *cache = mg->cache; +struct bio *bio = mg->overwrite_bio; +struct per_bio_data *pb =get_per_bio_data (bio); + +if (mg->k.input) +invalidate_complete (mg, false); + +init_continuation (&mg->k, invalidate_completed); +remap_to_origin_clear_discard (cache, bio, mg->invalidate_oblock); +dm_hook_bio (&pb->hook_info, bio, overwrite_endio, mg); +dm_submit_bio_remap (bio,NULL ); +} +static void invalidate_remove (struct work_struct *ws) {int r;
@@ -1514,10 +1536,8 @@ static void invalidate_remove(struct work_struct *ws)return ; } -init_continuation (&mg->k, invalidate_completed); +init_continuation (&mg->k, invalidate_committed);continue_after_commit (&cache->committer, &mg->k); -remap_to_origin_clear_discard (cache, mg->overwrite_bio, mg->invalidate_oblock); - mg->overwrite_bio =NULL ;schedule_commit (&cache->committer); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 128/666 dm cache policy smq: fix missing locks in invalidating cache blocks
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming-Hung Tsai <[email protected]>
[ Upstream commit 2d1f7b65f5deedd2e6b09fdc6ea27f8375f24b45 ]
In passthrough mode, the policy invalidate_mapping operation is called simultaneously from multiple workers, thus it should be protected by a lock. Otherwise, we might end up with data races on the allocated blocks counter, or even use-after-free issues with internal data structures when doing concurrent writes.
Note that the existing FIXME in smq_invalidate_mapping() doesn't affect passthrough mode since migration tasks don't exist there, but would need attention if supporting fast device shrinking via suspend/resume without target reloading.
Reproduce steps:
1. Create a cache device consisting of 1024 cache entries
dmsetup create cmeta --table "0 8192 linear /dev/sdc 0" dmsetup create cdata --table "0 131072 linear /dev/sdc 8192" dmsetup create corig --table "0 262144 linear /dev/sdc 262144" dd if=/dev/zero of=/dev/mapper/cmeta bs=4k count=1 oflag=direct dmsetup create cache --table "0 262144 cache /dev/mapper/cmeta \/dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 writethrough smq 0"
2. Populate the cache, and record the number of cached blocks
fio --name=populate --filename=/dev/mapper/cache --rw=randwrite --bs=4k \
--size=64m --direct=1
nr_cached=$(dmsetup status cache | awk '{split($7, a, "/"); print a[1]}')
3. Reload the cache into passthrough mode
dmsetup suspend cache
dmsetup reload cache --table "0 262144 cache /dev/mapper/cmeta \/dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 passthrough smq 0" dmsetup resume cache
4. Write to the passthrough cache. By setting multiple jobs with I/O size equal to the cache block size, cache blocks are invalidated concurrently from different workers.
fio --filename=/dev/mapper/cache --name=test --rw=randwrite --bs=64k \
--direct=1 --numjobs=2 --randrepeat=0 --size=64m
5. Check if demoted matches cached block count. These numbers should match but may differ due to the data race.
nr_demoted=$(dmsetup status cache | awk '{print $12}') echo "$nr_cached, $nr_demoted"
--- drivers/md/dm-cache-policy-smq.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/md/dm-cache-policy-smq.c +4 -0
@@ -1589,14 +1589,18 @@ static int smq_invalidate_mapping(struct dm_cache_policy *p, dm_cblock_t cblock) {struct smq_policy *mq =to_smq_policy (p);struct entry *e =get_entry (&mq->cache_alloc,from_cblock (cblock)); +unsigned long flags;if (!e->allocated)return -ENODATA ; +spin_lock_irqsave (&mq->lock, flags);// FIXME: what if this block has pending background work? del_queue (mq, e);h_remove (&mq->table, e);free_entry (&mq->cache_alloc, e); +spin_unlock_irqrestore (&mq->lock, flags); +return 0 ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 129/666 dm cache: fix concurrent write failure in passthrough mode
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming-Hung Tsai <[email protected]>
[ Upstream commit e4f66341779d0cf4c83c74793753a84094286d9e ]
When bio prison cell lock acquisition fails due to concurrent writes to the same block in passthrough mode, dm-cache incorrectly returns an I/O error instead of properly handling the concurrency. This can occur in both process and workqueue contexts when invalidate_lock() is called for exclusive access to a data block. Fix this by deferring the write bios to ensure proper block device behavior.
Reproduce steps:
1. Create a cache device
dmsetup create cmeta --table "0 8192 linear /dev/sdc 0" dmsetup create cdata --table "0 131072 linear /dev/sdc 8192" dmsetup create corig --table "0 262144 linear /dev/sdc 262144" dd if=/dev/zero of=/dev/mapper/cmeta bs=4k count=1 oflag=direct dmsetup create cache --table "0 262144 cache /dev/mapper/cmeta \/dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 writethrough smq 0"
2. Promote the first data block into cache
fio --filename=/dev/mapper/cache --name=populate --rw=write --bs=4k \
--direct=1 --size=64k
3. Reload the cache into passthrough mode
dmsetup suspend cache
dmsetup reload cache --table "0 262144 cache /dev/mapper/cmeta \/dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 passthrough smq 0" dmsetup resume cache
4. Write to the first cached block concurrently. Sometimes one of the processes will receive I/O errors.
fio --filename=/dev/mapper/cache --name test --rw=randwrite --bs=4k \
--randrepeat=0 --direct=1 --numjobs=2 --size 64k
<snip>
fio-3.41
fio: io_u error on file /dev/mapper/cache: Input/output error: write offset=4096, buflen=4096
fio: pid=106, err=5/file:io_u.c:2008, func=io_u error, error=Input/output error
test: (groupid=0, jobs=1): err= 0: pid=105
test: (groupid=0, jobs=1): err= 5 (file:io_u.c:2008, func=io_u error, error=Input/output error): pid=106 <snip>
--- drivers/md/dm-cache-target.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/md/dm-cache-target.c +9 -0
@@ -1555,6 +1555,15 @@ static int invalidate_lock(struct dm_cache_migration *mg) READ_WRITE_LOCK_LEVEL, prealloc, &mg->cell);if (r <0 ) {free_prison_cell (cache, prealloc); + +/* Defer the bio for retrying the cell lock */ +if (mg->overwrite_bio) { +struct bio *bio = mg->overwrite_bio; + + mg->overwrite_bio =NULL ; +defer_bio (cache, bio); + } +invalidate_complete (mg, false);return r; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 130/666 dm cache: support shrinking the origin device
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming-Hung Tsai <[email protected]>
[ Upstream commit c2662b1544cbd8ea3181381bb899b8e681dfedc7 ]
This patch introduces formal support for shrinking the cache origin by reducing the cache target length via table reloads. Cache blocks mapped beyond the new target length must be clean and are invalidated during preresume. If any dirty blocks exist in the area being removed, the preresume operation fails without setting the NEEDS_CHECK flag in superblock, and the resume ioctl returns EFBIG. The cache device remains suspended until a table reload with target length that fits existing mappings is performed.
Without this patch, reducing the cache target length could result in io errors (RHBZ: 2134334), out-of-bounds memory access to the discard bitset, and security concerns regarding data leakage.
Verification steps:
1. create a cache metadata with some cached blocks mapped to the tail of the origin device. Here we use cache_restore v1.0 to build a metadata with one clean block mapped to the last origin block.
cat <<EOF >> cmeta.xml
<superblock uuid="" block_size="128" nr_cache_blocks="512" \
policy="smq" hint_width="4">
<mappings>
<mapping cache_block="0" origin_block="4095" dirty="false"/>
</mappings>
</superblock>
EOF
dmsetup create cmeta --table "0 8192 linear /dev/sdc 0" cache_restore -i cmeta.xml -o /dev/mapper/cmeta --metadata-version=2 dmsetup remove cmeta
2. bring up the cache whilst shrinking the cache origin by one block:
dmsetup create cmeta --table "0 8192 linear /dev/sdc 0" dmsetup create cdata --table "0 65536 linear /dev/sdc 8192" dmsetup create corig --table "0 524160 linear /dev/sdc 262144" dmsetup create cache --table "0 524160 cache /dev/mapper/cmeta \/dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 writethrough smq 0"
3. check the number of cached data blocks via dmsetup status. It is expected to be zero.
dmsetup status cache | cut -d ' ' -f 7
In addition to the script above, this patch can be verified using the "cache/resize" tests in dmtest-python:
./dmtest run --rx cache/resize/shrink_origin --result-set default
Stable-dep-of: 322586745bd1 ("dm cache: fix dirty mapping checking in passthrough mode switching")
--- drivers/md/dm-cache-target.c | 72 ++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 3 deletions(-)
drivers/md/dm-cache-target.c +69 -3
@@ -406,6 +406,12 @@ struct cache {mempool_t migration_pool;struct bio_set bs; + +/* +* Cache_size entries. Set bits indicate blocks mapped beyond the +* target length, which are marked for invalidation. +*/ +unsigned long *invalid_bitset; };struct per_bio_data {
@@ -1954,6 +1960,9 @@ static void __destroy(struct cache *cache)if (cache->discard_bitset)free_bitset (cache->discard_bitset); +if (cache->invalid_bitset) +free_bitset (cache->invalid_bitset); +if (cache->copier)dm_kcopyd_client_destroy (cache->copier);
@@ -2542,6 +2551,13 @@ static int cache_create(struct cache_args *ca, struct cache **result) }clear_bitset (cache->discard_bitset,from_dblock (cache->discard_nr_blocks)); + cache->invalid_bitset =alloc_bitset (from_cblock (cache->cache_size)); +if (!cache->invalid_bitset) { + *error ="could not allocate bitset for invalid blocks" ; + goto bad; + } +clear_bitset (cache->invalid_bitset,from_cblock (cache->cache_size)); + cache->copier =dm_kcopyd_client_create (&dm_kcopyd_throttle);if (IS_ERR (cache->copier)) { *error ="could not create kcopyd client" ;
@@ -2840,6 +2856,24 @@ static int load_mapping(void *context, dm_oblock_t oblock, dm_cblock_t cblock,return policy_load_mapping (cache->policy, oblock, cblock, dirty, hint, hint_valid); } +static int load_filtered_mapping (void *context,dm_oblock_t oblock,dm_cblock_t cblock, +bool dirty,uint32_t hint,bool hint_valid) +{ +struct cache *cache = context; + +if (from_oblock (oblock) >=from_oblock (cache->origin_blocks)) { +if (dirty) { +DMERR ("%s: unable to shrink origin; cache block %u is dirty" , +cache_device_name (cache),from_cblock (cblock)); +return -EFBIG ; + } +set_bit (from_cblock (cblock), cache->invalid_bitset); +return 0 ; + } + +return load_mapping (context, oblock, cblock, dirty, hint, hint_valid); +} +/* * The discard block size in the on disk metadata is not * necessarily the same as we're currently using. So we have to
@@ -2994,6 +3028,24 @@ static int resize_cache_dev(struct cache *cache, dm_cblock_t new_size)return 0 ; } +static int truncate_oblocks (struct cache *cache) +{ +uint32_t nr_blocks =from_cblock (cache->cache_size); +uint32_t i; +int r; + +for_each_set_bit (i, cache->invalid_bitset, nr_blocks) { + r =dm_cache_remove_mapping (cache->cmd,to_cblock (i)); +if (r) { +DMERR_LIMIT ("%s: invalidation failed; couldn't update on disk metadata" , +cache_device_name (cache)); +return r; + } + } + +return 0 ; +} +static int cache_preresume (struct dm_target *ti) {int r =0 ;
@@ -3018,11 +3070,25 @@ static int cache_preresume(struct dm_target *ti) }if (!cache->loaded_mappings) { +/* +* The fast device could have been resized since the last +* failed preresume attempt. To be safe we start by a blank +* bitset for cache blocks. +*/ +clear_bitset (cache->invalid_bitset,from_cblock (cache->cache_size)); + r =dm_cache_load_mappings (cache->cmd, cache->policy, - load_mapping, cache); + load_filtered_mapping, cache);if (r) {DMERR ("%s: could not load cache mappings" ,cache_device_name (cache)); -metadata_operation_failed (cache,"dm_cache_load_mappings" , r); +if (r != -EFBIG ) +metadata_operation_failed (cache,"dm_cache_load_mappings" , r); +return r; + } + + r =truncate_oblocks (cache); +if (r) { +metadata_operation_failed (cache,"dm_cache_remove_mapping" , r);return r; }
@@ -3482,7 +3548,7 @@ static void cache_io_hints(struct dm_target *ti, struct queue_limits *limits)static struct target_type cache_target = { .name ="cache" , - .version = {2 ,2 ,0 }, + .version = {2 ,3 ,0 }, .module =THIS_MODULE , .ctr = cache_ctr, .dtr = cache_dtr,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 131/666 dm cache: fix dirty mapping checking in passthrough mode switching
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming-Hung Tsai <[email protected]>
[ Upstream commit 322586745bd1a0e5f3559fd1635fdeb4dbd1d6b8 ]
As mentioned in commit 9b1cc9f251af ("dm cache: share cache-metadata object across inactive and active DM tables"), dm-cache assumed table reload occurs after suspension, while LVM's table preload breaks this assumption. The dirty mapping check for passthrough mode was designed around this assumption and is performed during table creation, causing the check to fail with preload while metadata updates are ongoing. This risks loading dirty mappings into passthrough mode, resulting in data loss.
Reproduce steps:
1. Create a writeback cache with zero migration_threshold to produce dirty mappings
dmsetup create cmeta --table "0 8192 linear /dev/sdc 0" dmsetup create cdata --table "0 131072 linear /dev/sdc 8192" dmsetup create corig --table "0 262144 linear /dev/sdc 262144" dd if=/dev/zero of=/dev/mapper/cmeta bs=4k count=1 oflag=direct dmsetup create cache --table "0 262144 cache /dev/mapper/cmeta \/dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 writeback smq \
2 migration_threshold 0"
2. Preload a table in passthrough mode
dmsetup reload cache --table "0 262144 cache /dev/mapper/cmeta \/dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 passthrough smq 0"
3. Write to the first cache block to make it dirty
fio --filename=/dev/mapper/cache --name=populate --rw=write --bs=4k \
--direct=1 --size=64k
4. Resume the inactive table. Now it's possible to load the dirty block into passthrough mode.
dmsetup resume cache
Fix by moving the checks to the preresume phase to support table preloading. Also remove the unused function dm_cache_metadata_all_clean.
--- drivers/md/dm-cache-metadata.c | 11 ----------- drivers/md/dm-cache-metadata.h | 5 ----- drivers/md/dm-cache-target.c | 25 ++++++++----------------- 3 files changed, 8 insertions(+), 33 deletions(-)
drivers/md/dm-cache-metadata.c +0 -11
@@ -1747,17 +1747,6 @@ int dm_cache_write_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *return r; } -int dm_cache_metadata_all_clean (struct dm_cache_metadata *cmd,bool *result) -{ -int r; - -READ_LOCK (cmd); - r =blocks_are_unmapped_or_clean (cmd,0 , cmd->cache_blocks, result); -READ_UNLOCK (cmd); - -return r; -} -void dm_cache_metadata_set_read_only (struct dm_cache_metadata *cmd) {WRITE_LOCK_VOID (cmd);
drivers/md/dm-cache-metadata.h +0 -5
@@ -138,11 +138,6 @@ void dm_cache_dump(struct dm_cache_metadata *cmd);*/ int dm_cache_write_hints (struct dm_cache_metadata *cmd,struct dm_cache_policy *p); -/* -* Query method. Are all the blocks in the cache clean? -*/ -int dm_cache_metadata_all_clean (struct dm_cache_metadata *cmd,bool *result); -int dm_cache_metadata_needs_check (struct dm_cache_metadata *cmd,bool *result);int dm_cache_metadata_set_needs_check (struct dm_cache_metadata *cmd);void dm_cache_metadata_set_read_only (struct dm_cache_metadata *cmd);
drivers/md/dm-cache-target.c +8 -17
@@ -2506,23 +2506,8 @@ static int cache_create(struct cache_args *ca, struct cache **result) goto bad; } -if (passthrough_mode (cache)) { -bool all_clean; - - r =dm_cache_metadata_all_clean (cache->cmd, &all_clean); -if (r) { - *error ="dm_cache_metadata_all_clean() failed" ; - goto bad; - } - -if (!all_clean) { - *error ="Cannot enter passthrough mode unless all blocks are clean" ; - r = -EINVAL ; - goto bad; - } - +if (passthrough_mode (cache))policy_allow_migrations (cache->policy, false); - }spin_lock_init (&cache->lock);bio_list_init (&cache->deferred_bios);
@@ -2848,6 +2833,12 @@ static int load_mapping(void *context, dm_oblock_t oblock, dm_cblock_t cblock,struct cache *cache = context;if (dirty) { +if (passthrough_mode (cache)) { +DMERR ("%s: cannot enter passthrough mode unless all blocks are clean" , +cache_device_name (cache)); +return -EBUSY ; + } +set_bit (from_cblock (cblock), cache->dirty_bitset);atomic_inc (&cache->nr_dirty); }else
@@ -3081,7 +3072,7 @@ static int cache_preresume(struct dm_target *ti) load_filtered_mapping, cache);if (r) {DMERR ("%s: could not load cache mappings" ,cache_device_name (cache)); -if (r != -EFBIG ) +if (r != -EFBIG && r != -EBUSY )metadata_operation_failed (cache,"dm_cache_load_mappings" , r);return r; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 132/666 platform/chrome: chromeos_tbmc: Drop wakeup source on remove
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <[email protected]>
[ Upstream commit 5d441a4bc93642ed6f41da87327a39946b4e1455 ]
The wakeup source added by device_init_wakeup() in chromeos_tbmc_add() needs to be dropped during driver removal, so add a .remove() callback to the driver for this purpose.
--- drivers/platform/chrome/chromeos_tbmc.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/platform/chrome/chromeos_tbmc.c +6 -0
@@ -95,6 +95,11 @@ static int chromeos_tbmc_add(struct acpi_device *adev)return 0 ; } +static void chromeos_tbmc_remove (struct acpi_device *adev) +{ +device_init_wakeup (&adev->dev, false); +} +static const struct acpi_device_id chromeos_tbmc_acpi_device_ids[] = { {ACPI_DRV_NAME ,0 }, { }
@@ -110,6 +115,7 @@ static struct acpi_driver chromeos_tbmc_driver = { .ids = chromeos_tbmc_acpi_device_ids, .ops = { .add = chromeos_tbmc_add, + .remove = chromeos_tbmc_remove, .notify = chromeos_tbmc_notify, }, .drv.pm = &chromeos_tbmc_pm_ops,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 133/666 PCI: endpoint: Align pci_epc_set_msix(), pci_epc_ops::set_msix() nr_irqs encoding
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niklas Cassel <[email protected]>
[ Upstream commit de0321bcc5fdd83631f0c2a6fdebfe0ad4e23449 ]
The kdoc for pci_epc_set_msix() says:
"Invoke to set the required number of MSI-X interrupts."
The kdoc for the callback pci_epc_ops->set_msix() says:
"ops to set the requested number of MSI-X interrupts in the MSI-X capability register"
pci_epc_ops::set_msix() does however expect the parameter 'interrupts' to be in the encoding as defined by the Table Size field. Nowhere in the kdoc does it say that the number of interrupts should be in Table Size encoding.
It is very confusing that the API pci_epc_set_msix() and the callback function pci_epc_ops::set_msix() both take a parameter named 'interrupts', but they expect completely different encodings.
Clean up the API and the callback function to have the same semantics, i.e. the parameter represents the number of interrupts, regardless of the internal encoding of that value.
Also rename the parameter 'interrupts' to 'nr_irqs', in both the wrapper function and the callback function, such that the name is unambiguous.
[bhelgaas: more specific subject]
Stable-dep-of: 271d0b1f058a ("PCI: dwc: ep: Fix MSI-X Table Size configuration in dw_pcie_ep_set_msix()")
--- drivers/pci/controller/cadence/pcie-cadence-ep.c | 8 +++----- drivers/pci/controller/dwc/pcie-designware-ep.c | 7 +++---- drivers/pci/endpoint/pci-epc-core.c | 11 +++++------ include/linux/pci-epc.h | 6 +++--- 4 files changed, 14 insertions(+), 18 deletions(-)
drivers/pci/controller/cadence/pcie-cadence-ep.c +3 -5
@@ -285,21 +285,19 @@ static int cdns_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no) }static int cdns_pcie_ep_set_msix (struct pci_epc *epc,u8 fn,u8 vfn, -u16 interrupts,enum pci_barno bir, -u32 offset) +u16 nr_irqs,enum pci_barno bir,u32 offset) {struct cdns_pcie_ep *ep =epc_get_drvdata (epc);struct cdns_pcie *pcie = &ep->pcie;u32 cap =CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET ;u32 val, reg; -u16 actual_interrupts = interrupts +1 ; fn =cdns_pcie_get_fn_from_vfn (pcie, fn, vfn); reg = cap +PCI_MSIX_FLAGS ; val =cdns_pcie_ep_fn_readw (pcie, fn, reg); val &= ~PCI_MSIX_FLAGS_QSIZE ; - val |= interrupts;/* 0's based value */ + val |= nr_irqs -1 ;/* encoded as N-1 */ cdns_pcie_ep_fn_writew (pcie, fn, reg, val);/* Set MSIX BAR and offset */
@@ -309,7 +307,7 @@ static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,/* Set PBA BAR and offset. BAR must match MSIX BAR */ reg = cap +PCI_MSIX_PBA ; - val = (offset + (actual_interrupts *PCI_MSIX_ENTRY_SIZE )) | bir; + val = (offset + (nr_irqs *PCI_MSIX_ENTRY_SIZE )) | bir;cdns_pcie_ep_fn_writel (pcie, fn, reg, val);return 0 ;
drivers/pci/controller/dwc/pcie-designware-ep.c +3 -4
@@ -406,13 +406,12 @@ static int dw_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no) }static int dw_pcie_ep_set_msix (struct pci_epc *epc,u8 func_no,u8 vfunc_no, -u16 interrupts,enum pci_barno bir,u32 offset) +u16 nr_irqs,enum pci_barno bir,u32 offset) {struct dw_pcie_ep *ep =epc_get_drvdata (epc);struct dw_pcie *pci =to_dw_pcie_from_ep (ep);struct dw_pcie_ep_func *ep_func;u32 val, reg; -u16 actual_interrupts = interrupts +1 ; ep_func =dw_pcie_ep_get_func_from_ep (ep, func_no);if (!ep_func || !ep_func->msix_cap)
@@ -423,7 +422,7 @@ static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no, reg = ep_func->msix_cap +PCI_MSIX_FLAGS ; val =dw_pcie_ep_readw_dbi (ep, func_no, reg); val &= ~PCI_MSIX_FLAGS_QSIZE ; - val |= interrupts;/* 0's based value */ + val |= nr_irqs -1 ;/* encoded as N-1 */ dw_pcie_writew_dbi (pci, reg, val); reg = ep_func->msix_cap +PCI_MSIX_TABLE ;
@@ -431,7 +430,7 @@ static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,dw_pcie_ep_writel_dbi (ep, func_no, reg, val); reg = ep_func->msix_cap +PCI_MSIX_PBA ; - val = (offset + (actual_interrupts *PCI_MSIX_ENTRY_SIZE )) | bir; + val = (offset + (nr_irqs *PCI_MSIX_ENTRY_SIZE )) | bir;dw_pcie_ep_writel_dbi (ep, func_no, reg, val);dw_pcie_dbi_ro_wr_dis (pci);
drivers/pci/endpoint/pci-epc-core.c +5 -6
@@ -382,29 +382,28 @@ EXPORT_SYMBOL_GPL(pci_epc_get_msix);* @epc: the EPC device on which MSI-X has to be configured * @func_no: the physical endpoint function number in the EPC device * @vfunc_no: the virtual endpoint function number in the physical function -* @interrupts: number of MSI-X interrupts required by the EPF +* @nr_irqs: number of MSI-X interrupts required by the EPF * @bir: BAR where the MSI-X table resides * @offset: Offset pointing to the start of MSI-X table * * Invoke to set the required number of MSI-X interrupts. */ -int pci_epc_set_msix (struct pci_epc *epc,u8 func_no,u8 vfunc_no, -u16 interrupts,enum pci_barno bir,u32 offset) +int pci_epc_set_msix (struct pci_epc *epc,u8 func_no,u8 vfunc_no,u16 nr_irqs, +enum pci_barno bir,u32 offset) {int ret;if (!pci_epc_function_is_valid (epc, func_no, vfunc_no))return -EINVAL ; -if (interrupts <1 || interrupts >2048 ) +if (nr_irqs <1 || nr_irqs >2048 )return -EINVAL ;if (!epc->ops->set_msix)return 0 ;mutex_lock (&epc->lock); - ret = epc->ops->set_msix (epc, func_no, vfunc_no, interrupts -1 , bir, - offset); + ret = epc->ops->set_msix (epc, func_no, vfunc_no, nr_irqs, bir, offset);mutex_unlock (&epc->lock);return ret;
include/linux/pci-epc.h +3 -3
@@ -103,7 +103,7 @@ struct pci_epc_ops { u8 interrupts);int (*get_msi)(struct pci_epc *epc,u8 func_no,u8 vfunc_no);int (*set_msix)(struct pci_epc *epc,u8 func_no,u8 vfunc_no, -u16 interrupts,enum pci_barno ,u32 offset); +u16 nr_irqs,enum pci_barno ,u32 offset);int (*get_msix)(struct pci_epc *epc,u8 func_no,u8 vfunc_no);int (*raise_irq)(struct pci_epc *epc,u8 func_no,u8 vfunc_no,unsigned int type,u16 interrupt_num);
@@ -283,8 +283,8 @@ void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,int pci_epc_set_msi (struct pci_epc *epc,u8 func_no,u8 vfunc_no,u8 interrupts);int pci_epc_get_msi (struct pci_epc *epc,u8 func_no,u8 vfunc_no); -int pci_epc_set_msix (struct pci_epc *epc,u8 func_no,u8 vfunc_no, -u16 interrupts,enum pci_barno ,u32 offset); +int pci_epc_set_msix (struct pci_epc *epc,u8 func_no,u8 vfunc_no,u16 nr_irqs, +enum pci_barno ,u32 offset);int pci_epc_get_msix (struct pci_epc *epc,u8 func_no,u8 vfunc_no); int pci_epc_map_msi_irq(struct pci_epc *epc, u8 func_no, u8 vfunc_no, phys_addr_t phys_addr, u8 interrupt_num,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 134/666 PCI: dwc: ep: Fix MSI-X Table Size configuration in dw_pcie_ep_set_msix()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aksh Garg <[email protected]>
[ Upstream commit 271d0b1f058ae9815e75233d04b23e3558c3e4f4 ]
In dw_pcie_ep_set_msix(), while updating the MSI-X Table Size value for individual functions, Message Control register is read from the passed function number register space using dw_pcie_ep_readw_dbi(), but always written back to the Function 0's register space using dw_pcie_writew_dbi(). This causes incorrect MSI-X configuration for the rest of the functions, other than Function 0.
Fix this by using dw_pcie_ep_writew_dbi() to write to the correct function's register space, matching the read operation.
--- drivers/pci/controller/dwc/pcie-designware-ep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/controller/dwc/pcie-designware-ep.c +1 -1
@@ -423,7 +423,7 @@ static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no, val =dw_pcie_ep_readw_dbi (ep, func_no, reg); val &= ~PCI_MSIX_FLAGS_QSIZE ; val |= nr_irqs -1 ;/* encoded as N-1 */ -dw_pcie_writew_dbi (pci, reg, val); +dw_pcie_ep_writew_dbi (ep, func_no, reg, val); reg = ep_func->msix_cap +PCI_MSIX_TABLE ; val = offset | bir;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 135/666 PCI: dwc: Invoke post_init in dw_pcie_resume_noirq()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Zhu <[email protected]>
[ Upstream commit c577ce2881f9c76892de5ffc1a122e3ef427ecee ]
In some SoCs like i.MX95, CLKREQ# is pulled low by the controller driver before link up. After link up, if the 'supports-clkreq' property is specified in DT, the driver will release CLKREQ# so that it can go high and the endpoint can pull it low whenever required i.e., during exit from L1 Substates.
Hence, at the end of dw_pcie_resume_noirq(), invoke the '.post_init()' callback if exists to perform the above mentioned action.
Stable-dep-of: edb5ca3262e2 ("PCI: dwc: Perform cleanup in the error path of dw_pcie_resume_noirq()")
--- drivers/pci/controller/dwc/pcie-designware-host.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/pci/controller/dwc/pcie-designware-host.c +3 -0
@@ -990,6 +990,9 @@ int dw_pcie_resume_noirq(struct dw_pcie *pci)if (ret)return ret; +if (pci->pp.ops->post_init) + pci->pp.ops->post_init (&pci->pp); +return ret; }EXPORT_SYMBOL_GPL (dw_pcie_resume_noirq);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 136/666 PCI: dwc: Perform cleanup in the error path of dw_pcie_resume_noirq()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manivannan Sadhasivam <[email protected]>
[ Upstream commit edb5ca3262e2255cf938a5948709d3472d4871ad ]
If the dw_pcie_resume_noirq() API fails, it just returns the errno without doing cleanup in the error path, leading to resource leak.
So perform cleanup in the error path.
--- drivers/pci/controller/dwc/pcie-designware-host.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
drivers/pci/controller/dwc/pcie-designware-host.c +12 -3
@@ -984,15 +984,24 @@ int dw_pcie_resume_noirq(struct dw_pcie *pci) ret =dw_pcie_start_link (pci);if (ret) -return ret; + goto err_deinit; ret =dw_pcie_wait_for_link (pci); -if (ret) -return ret; +if (ret == -ETIMEDOUT ) + goto err_stop_link;if (pci->pp.ops->post_init) pci->pp.ops->post_init (&pci->pp); +return 0 ; + +err_stop_link: +dw_pcie_stop_link (pci); + +err_deinit: +if (pci->pp.ops->deinit) + pci->pp.ops->deinit (&pci->pp); +return ret; }EXPORT_SYMBOL_GPL (dw_pcie_resume_noirq);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 137/666 dm cache metadata: fix memory leak on metadata abort retry
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming-Hung Tsai <[email protected]>
[ Upstream commit 044ca491d4086dc5bf233e9fcb71db52df32f633 ]
When failing to acquire the root_lock in dm_cache_metadata_abort because the block_manager is read-only, the temporary block_manager created outside the root_lock is not properly released, causing a memory leak.
Reproduce steps:
This can be reproduced by reloading a new table while the metadata is read-only. While the second call to dm_cache_metadata_abort is caused by lack of support for table preload in dm-cache, mentioned in commit 9b1cc9f251af ("dm cache: share cache-metadata object across inactive and active DM tables"), it exposes the memory leak in dm_cache_metadata_abort when the function is called multiple times. Specifically, dm-cache fails to sync the new cache object's mode during preresume, creating the reproducer condition.
This issue could also occur through concurrent metadata_operation_failed calls due to races in cache mode updates, but the table preload scenario below provides a reliable reproducer.
1. Create a cache device with some faulty trailing metadata blocks
dmsetup create cmeta <<EOF
0 200 linear /dev/sdc 0
200 7992 error
EOF
dmsetup create cdata --table "0 131072 linear /dev/sdc 8192" dmsetup create corig --table "0 262144 linear /dev/sdc 262144" dd if=/dev/zero of=/dev/mapper/cmeta bs=4k count=1 oflag=direct dmsetup create cache --table "0 131072 cache /dev/mapper/cmeta \/dev/mapper/cdata /dev/mapper/corig 128 1 writethrough smq 0"
2. Suspend and resume the cache to start a new metadata transaction and trigger metadata io errors on the next metadata commit.
dmsetup suspend cache
dmsetup resume cache
3. Write to the cache device to update metadata
fio --filename=/dev/mapper/cache --name test --rw=randwrite --bs=4k \
--randrepeat=0 --direct=1 --size 64k
4. Preload the same table
dmsetup reload cache --table "$(dmsetup table cache)"
5. Resume the new table. This triggers the memory leak.
dmsetup suspend cache
dmsetup resume cache
kmemleak logs:
<snip>
unreferenced object 0xffff8880080c2010 (size 16):
comm "dmsetup", pid 132, jiffies 4294982580
hex dump (first 16 bytes):
00 38 b9 07 80 88 ff ff 6a 6b 6b 6b 6b 6b 6b a5 ...
backtrace (crc 3118f31c):
kmemleak_alloc+0x28/0x40
__kmalloc_cache_noprof+0x3d9/0x510
dm_block_manager_create+0x51/0x140
dm_cache_metadata_abort+0x85/0x320
metadata_operation_failed+0x103/0x1e0
cache_preresume+0xacd/0xe70
dm_table_resume_targets+0xd3/0x320
__dm_resume+0x1b/0xf0
dm_resume+0x127/0x170<snip>
--- drivers/md/dm-cache-metadata.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/md/dm-cache-metadata.c +8 -5
@@ -1023,6 +1023,12 @@ static bool cmd_write_lock(struct dm_cache_metadata *cmd)return ; \ } while (0) +#define WRITE_LOCK_OR_GOTO (cmd, label) \ + do { \ + if (!cmd_write_lock((cmd))) \ + goto label; \ + } while (0) +#define WRITE_UNLOCK (cmd) \ up_write(&(cmd)->root_lock)
@@ -1813,11 +1819,8 @@ int dm_cache_metadata_abort(struct dm_cache_metadata *cmd) new_bm =dm_block_manager_create (cmd->bdev,DM_CACHE_METADATA_BLOCK_SIZE <<SECTOR_SHIFT ,CACHE_MAX_CONCURRENT_LOCKS ); -WRITE_LOCK (cmd); -if (cmd->fail_io) { -WRITE_UNLOCK (cmd); - goto out; - } +/* cmd_write_lock() already checks fail_io with cmd->root_lock held */ +WRITE_LOCK_OR_GOTO (cmd, out);__destroy_persistent_data_objects (cmd, false); old_bm = cmd->bm;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 138/666 dm log: fix out-of-bounds write due to region_count overflow
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junrui Luo <[email protected]>
[ Upstream commit c20e36b7631d83e7535877f08af8b0af72c44b1a ]
The local variable region_count in create_log_context() is declared as unsigned int (32-bit), but dm_sector_div_up() returns sector_t (64-bit). When a device-mapper target has a sufficiently large ti->len with a small region_size, the division result can exceed UINT_MAX. The truncated value is then used to calculate bitset_size, causing clean_bits, sync_bits, and recovering_bits to be allocated far smaller than needed for the actual number of regions.
Subsequent log operations (log_set_bit, log_clear_bit, log_test_bit) use region indices derived from the full untruncated region space, causing out-of-bounds writes to kernel heap memory allocated by vmalloc.
This can be reproduced by creating a mirror target whose region_count overflows 32 bits:
dmsetup create bigzero --table '0 8589934594 zero'
dmsetup create mymirror --table '0 8589934594 mirror \
core 2 2 nosync 2 /dev/mapper/bigzero 0 \
/dev/mapper/bigzero 0'The status output confirms the truncation (sync_count=1 instead of 4294967297, because 0x100000001 was truncated to 1):
$ dmsetup status mymirror 0 8589934594 mirror 2 254:1 254:1 1/4294967297 ...
This leads to a kernel crash in core_in_sync:
BUG: scheduling while atomic: (udev-worker)/9150/0x00000000 RIP: 0010:core_in_sync+0x14/0x30 [dm_log] CR2: 0000000000000008 Fixing recursive fault but reboot is needed!
Fix by widening the local region_count to sector_t and adding an explicit overflow check before the value is assigned to lc->region_count.
--- drivers/md/dm-log.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/md/dm-log.c +5 -1
@@ -373,7 +373,7 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti,struct log_c *lc;uint32_t region_size; -unsigned int region_count; +sector_t region_count;size_t bitset_size, buf_size;int r;char dummy;
@@ -401,6 +401,10 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti, } region_count =dm_sector_div_up (ti->len, region_size); +if (region_count >UINT_MAX ) { +DMWARN ("region count exceeds limit of %u" ,UINT_MAX ); +return -EINVAL ; + } lc =kmalloc (sizeof (*lc),GFP_KERNEL );if (!lc) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 139/666 drm/bridge: cadence: cdns-mhdp8546-core: Set the mhdp connector earlier in atomic_enable()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jayesh Choudhary <[email protected]>
[ Upstream commit 43d6508ddbf9fb974fbc359a033154f78c9d4c8b ]
In case if we get errors in cdns_mhdp_link_up() or cdns_mhdp_reg_read() in atomic_enable, we will go to cdns_mhdp_modeset_retry_fn() and will hit NULL pointer while trying to access the mutex. We need the connector to be set before that. Unlike in legacy cases with flag !DRM_BRIDGE_ATTACH_NO_CONNECTOR, we do not have connector initialised in bridge_attach(), so add the mhdp->connector_ptr in device structure to handle both cases with DRM_BRIDGE_ATTACH_NO_CONNECTOR and !DRM_BRIDGE_ATTACH_NO_CONNECTOR, set it in atomic_enable() earlier to avoid possible NULL pointer dereference in recovery paths like modeset_retry_fn() with the DRM_BRIDGE_ATTACH_NO_CONNECTOR flag set.
--- .../drm/bridge/cadence/cdns-mhdp8546-core.c | 29 ++++++++++--------- .../drm/bridge/cadence/cdns-mhdp8546-core.h | 1 + .../drm/bridge/cadence/cdns-mhdp8546-hdcp.c | 18 +++++++++--- 3 files changed, 30 insertions(+), 18 deletions(-)
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +15 -14
@@ -810,7 +810,7 @@ static void cdns_mhdp_fw_cb(const struct firmware *fw, void *context) bridge_attached = mhdp->bridge_attached;spin_unlock (&mhdp->start_lock);if (bridge_attached) { -if (mhdp->connector.dev) +if (mhdp->connector_ptr)drm_kms_helper_hotplug_event (mhdp->bridge.dev);else drm_bridge_hpd_notify (&mhdp->bridge,cdns_mhdp_detect (mhdp));
@@ -1706,6 +1706,7 @@ static int cdns_mhdp_connector_init(struct cdns_mhdp_device *mhdp)return ret; } + mhdp->connector_ptr = conn;drm_connector_helper_add (conn, &cdns_mhdp_conn_helper_funcs); ret = drm_display_info_set_bus_formats(&conn->display_info,
@@ -1985,17 +1986,25 @@ static void cdns_mhdp_atomic_enable(struct drm_bridge *bridge,struct drm_atomic_state *state = bridge_state->base.state;struct cdns_mhdp_bridge_state *mhdp_state;struct drm_crtc_state *crtc_state; -struct drm_connector *connector;struct drm_connector_state *conn_state;struct drm_bridge_state *new_state;const struct drm_display_mode *mode;u32 resp; -int ret; +int ret =0 ;dev_dbg (mhdp->dev,"bridge enable\n" );mutex_lock (&mhdp->link_mutex); + mhdp->connector_ptr =drm_atomic_get_new_connector_for_encoder (state, + bridge->encoder); +if (WARN_ON (!mhdp->connector_ptr)) + goto out; + + conn_state =drm_atomic_get_new_connector_state (state, mhdp->connector_ptr); +if (WARN_ON (!conn_state)) + goto out; +if (mhdp->plugged && !mhdp->link_up) { ret =cdns_mhdp_link_up (mhdp);if (ret <0 )
@@ -2015,15 +2024,6 @@ static void cdns_mhdp_atomic_enable(struct drm_bridge *bridge,cdns_mhdp_reg_write (mhdp,CDNS_DPTX_CAR , resp |CDNS_VIF_CLK_EN |CDNS_VIF_CLK_RSTN ); - connector =drm_atomic_get_new_connector_for_encoder (state, - bridge->encoder); -if (WARN_ON (!connector)) - goto out; - - conn_state =drm_atomic_get_new_connector_state (state, connector); -if (WARN_ON (!conn_state)) - goto out; -if (mhdp->hdcp_supported && mhdp->hw_state ==MHDP_HW_READY && conn_state->content_protection ==
@@ -2100,6 +2100,7 @@ static void cdns_mhdp_atomic_disable(struct drm_bridge *bridge,if (mhdp->info && mhdp->info->ops && mhdp->info->ops->disable) mhdp->info->ops->disable (mhdp); + mhdp->connector_ptr =NULL ;mutex_unlock (&mhdp->link_mutex); }
@@ -2365,7 +2366,7 @@ static void cdns_mhdp_modeset_retry_fn(struct work_struct *work) mhdp =container_of (work,typeof (*mhdp), modeset_retry_work); - conn = &mhdp->connector; + conn = mhdp->connector_ptr;/* Grab the locks before changing connector property */ mutex_lock (&conn->dev->mode_config.mutex);
@@ -2442,7 +2443,7 @@ static void cdns_mhdp_hpd_work(struct work_struct *work)int ret; ret =cdns_mhdp_update_link_status (mhdp); -if (mhdp->connector.dev) { +if (mhdp->connector_ptr) {if (ret <0 )schedule_work (&mhdp->modeset_retry_work);else
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h +1 -0
@@ -376,6 +376,7 @@ struct cdns_mhdp_device {struct mutex link_mutex;struct drm_connector connector; +struct drm_connector *connector_ptr;struct drm_bridge bridge;struct cdns_mhdp_link link;
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c +14 -4
@@ -394,7 +394,7 @@ static int _cdns_mhdp_hdcp_disable(struct cdns_mhdp_device *mhdp)int ret;dev_dbg (mhdp->dev,"[%s:%d] HDCP is being disabled...\n" , - mhdp->connector.name, mhdp->connector.base.id); + mhdp->connector_ptr->name, mhdp->connector_ptr->base.id); ret =cdns_mhdp_hdcp_set_config (mhdp,0 , false);
@@ -436,6 +436,10 @@ static int cdns_mhdp_hdcp_check_link(struct cdns_mhdp_device *mhdp)int ret =0 ;mutex_lock (&mhdp->hdcp.mutex); + +if (!mhdp->connector_ptr) + goto out; +if (mhdp->hdcp.value ==DRM_MODE_CONTENT_PROTECTION_UNDESIRED ) goto out;
@@ -445,7 +449,7 @@ static int cdns_mhdp_hdcp_check_link(struct cdns_mhdp_device *mhdp)dev_err (mhdp->dev,"[%s:%d] HDCP link failed, retrying authentication\n" , - mhdp->connector.name, mhdp->connector.base.id); + mhdp->connector_ptr->name, mhdp->connector_ptr->base.id); ret =_cdns_mhdp_hdcp_disable (mhdp);if (ret) {
@@ -487,13 +491,19 @@ static void cdns_mhdp_hdcp_prop_work(struct work_struct *work)struct cdns_mhdp_device *mhdp =container_of (hdcp, struct cdns_mhdp_device, hdcp); -struct drm_device *dev = mhdp->connector.dev; +struct drm_device *dev =NULL ;struct drm_connector_state *state; +if (mhdp->connector_ptr) + dev = mhdp->connector_ptr->dev; + +if (!dev) +return ; +drm_modeset_lock (&dev->mode_config.connection_mutex,NULL );mutex_lock (&mhdp->hdcp.mutex);if (mhdp->hdcp.value !=DRM_MODE_CONTENT_PROTECTION_UNDESIRED ) { - state = mhdp->connector.state; + state = mhdp->connector_ptr->state; state->content_protection = mhdp->hdcp.value; }mutex_unlock (&mhdp->hdcp.mutex);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 140/666 drm/bridge: cadence: cdns-mhdp8546-core: Add mode_valid hook to drm_bridge_funcs
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jayesh Choudhary <[email protected]>
[ Upstream commit 6dbff34016052b099558b76632e4983e2df13fed ]
Add cdns_mhdp_bridge_mode_valid() to check if specific mode is valid for this bridge or not. In the legacy usecase with !DRM_BRIDGE_ATTACH_NO_CONNECTOR we were using the hook from drm_connector_helper_funcs but with DRM_BRIDGE_ATTACH_NO_CONNECTOR we need to have mode_valid() in drm_bridge_funcs.
Without this patch, when using DRM_BRIDGE_ATTACH_NO_CONNECTOR flag, the cdns_mhdp_bandwidth_ok() function would not be called during mode validation, potentially allowing modes that exceed the bridge's bandwidth capabilities to be incorrectly marked as valid.
--- .../drm/bridge/cadence/cdns-mhdp8546-core.c | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+)
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +20 -0
@@ -2231,6 +2231,25 @@ static const struct drm_edid *cdns_mhdp_bridge_edid_read(struct drm_bridge *bridreturn cdns_mhdp_edid_read (mhdp, connector); } +static enum drm_mode_status +cdns_mhdp_bridge_mode_valid (struct drm_bridge *bridge, +const struct drm_display_info *info, +const struct drm_display_mode *mode) +{ +struct cdns_mhdp_device *mhdp =bridge_to_mhdp (bridge); + +mutex_lock (&mhdp->link_mutex); + +if (!cdns_mhdp_bandwidth_ok (mhdp, mode, mhdp->link.num_lanes, + mhdp->link.rate)) { +mutex_unlock (&mhdp->link_mutex); +return MODE_CLOCK_HIGH ; + } + +mutex_unlock (&mhdp->link_mutex); +return MODE_OK ; +} +static const struct drm_bridge_funcs cdns_mhdp_bridge_funcs = { .atomic_enable = cdns_mhdp_atomic_enable, .atomic_disable = cdns_mhdp_atomic_disable,
@@ -2245,6 +2264,7 @@ static const struct drm_bridge_funcs cdns_mhdp_bridge_funcs = { .edid_read = cdns_mhdp_bridge_edid_read, .hpd_enable = cdns_mhdp_bridge_hpd_enable, .hpd_disable = cdns_mhdp_bridge_hpd_disable, + .mode_valid = cdns_mhdp_bridge_mode_valid, };static bool cdns_mhdp_detect_hpd (struct cdns_mhdp_device *mhdp,bool *hpd_pulse)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 141/666 drm/bridge: cadence: cdns-mhdp8546-core: Handle HDCP state in bridge atomic check
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harikrishna Shenoy <[email protected]>
[ Upstream commit 4a8edd658489ec2a3d7e20482fa9e8d366153d8d ]
Now that we have DRM_BRIDGE_ATTACH_NO_CONNECTOR framework, handle the HDCP state change in bridge atomic check as well to enable correct functioning for HDCP in both DRM_BRIDGE_ATTACH_NO_CONNECTOR and !DRM_BRIDGE_ATTACH_NO_CONNECTOR case.
Without this patch, when using DRM_BRIDGE_ATTACH_NO_CONNECTOR flag, HDCP state changes would not be properly handled during atomic commits, potentially leading to HDCP authentication failures or incorrect protection status for content requiring HDCP encryption.
--- .../drm/bridge/cadence/cdns-mhdp8546-core.c | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+)
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +23 -0
@@ -2193,6 +2193,10 @@ static int cdns_mhdp_atomic_check(struct drm_bridge *bridge, {struct cdns_mhdp_device *mhdp =bridge_to_mhdp (bridge);const struct drm_display_mode *mode = &crtc_state->adjusted_mode; +struct drm_connector_state *old_state, *new_state; +struct drm_atomic_state *state = crtc_state->state; +struct drm_connector *conn = mhdp->connector_ptr; +u64 old_cp, new_cp;mutex_lock (&mhdp->link_mutex);
@@ -2212,6 +2216,25 @@ static int cdns_mhdp_atomic_check(struct drm_bridge *bridge,if (mhdp->info) bridge_state->input_bus_cfg.flags = *mhdp->info->input_bus_flags; +if (conn && mhdp->hdcp_supported) { + old_state =drm_atomic_get_old_connector_state (state, conn); + new_state =drm_atomic_get_new_connector_state (state, conn); + old_cp = old_state->content_protection; + new_cp = new_state->content_protection; + +if (old_state->hdcp_content_type != new_state->hdcp_content_type && + new_cp !=DRM_MODE_CONTENT_PROTECTION_UNDESIRED ) { + new_state->content_protection =DRM_MODE_CONTENT_PROTECTION_DESIRED ; + crtc_state =drm_atomic_get_new_crtc_state (state, new_state->crtc); + crtc_state->mode_changed = true; + } + +if (!new_state->crtc) { +if (old_cp ==DRM_MODE_CONTENT_PROTECTION_ENABLED ) + new_state->content_protection =DRM_MODE_CONTENT_PROTECTION_DESIRED ; + } + } +mutex_unlock (&mhdp->link_mutex);return 0 ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 142/666 spi: spi-nxp-fspi: enable runtime pm for fspi
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haibo Chen <[email protected]>
[ Upstream commit 97be4b919a609fc8c4bd1118502b5d26cc2f77c4 ]
Enable the runtime PM in fspi driver.
Also for system PM, On some board like i.MX8ULP-EVK board, after system suspend, IOMUX module will lost power, so all the pinctrl setting will lost when system resume back, need driver to save/restore the pinctrl setting.
Stable-dep-of: 68c8c93fdb0d ("spi: nxp-fspi: Use reinit_completion() for repeated operations")
--- drivers/spi/spi-nxp-fspi.c | 93 +++++++++++++++++++++++++++++++------- 1 file changed, 76 insertions(+), 17 deletions(-)
drivers/spi/spi-nxp-fspi.c +76 -17
@@ -48,6 +48,8 @@#include <linux/mutex.h> #include <linux/of.h> #include <linux/platform_device.h> +#include <linux/pinctrl/consumer.h> +#include <linux/pm_runtime.h> #include <linux/pm_qos.h> #include <linux/regmap.h> #include <linux/sizes.h>
@@ -57,6 +59,9 @@#include <linux/spi/spi.h> #include <linux/spi/spi-mem.h> +/* runtime pm timeout */ +#define FSPI_RPM_TIMEOUT 50/* 50ms */ +/* Registers used by the driver */ #define FSPI_MCR0 0x00#define FSPI_MCR0_AHB_TIMEOUT (x) ((x) << 24)
@@ -396,6 +401,8 @@ struct nxp_fspi {struct mutex lock;struct pm_qos_request pm_qos_req;int selected; +#define FSPI_NEED_INIT (1 << 0) +int flags; };static inline int needs_ip_only (struct nxp_fspi *f)
@@ -935,6 +942,13 @@ static int nxp_fspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)mutex_lock (&f->lock); + err =pm_runtime_get_sync (f->dev); +if (err <0 ) { +mutex_unlock (&f->lock); +dev_err (f->dev,"Failed to enable clock %d\n" , __LINE__); +return err; + } +/* Wait for controller being ready. */ err =fspi_readl_poll_tout (f, f->iobase +FSPI_STS0 ,FSPI_STS0_ARB_IDLE ,1 ,POLL_TOUT , true);
@@ -963,8 +977,10 @@ static int nxp_fspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)/* Invalidate the data in the AHB buffer. */ nxp_fspi_invalid (f); -mutex_unlock (&f->lock); +pm_runtime_mark_last_busy (f->dev); +pm_runtime_put_autosuspend (f->dev); +mutex_unlock (&f->lock);return err; }
@@ -1231,9 +1247,14 @@ static int nxp_fspi_probe(struct platform_device *pdev)if (irq <0 )return dev_err_probe (dev, irq,"Failed to get irq source" ); - ret =nxp_fspi_clk_prep_enable (f); -if (ret) -return dev_err_probe (dev, ret,"Can't enable the clock\n" ); +pm_runtime_enable (dev); +pm_runtime_set_autosuspend_delay (dev,FSPI_RPM_TIMEOUT ); +pm_runtime_use_autosuspend (dev); + +/* enable clock */ + ret =pm_runtime_get_sync (f->dev); +if (ret <0 ) +return dev_err_probe (dev, ret,"Failed to enable clock" );/* Clear potential interrupts */ reg =fspi_readl (f, f->iobase +FSPI_INTR );
@@ -1242,12 +1263,14 @@ static int nxp_fspi_probe(struct platform_device *pdev)nxp_fspi_default_setup (f); + ret =pm_runtime_put_sync (dev); +if (ret <0 ) +return dev_err_probe (dev, ret,"Failed to disable clock" ); + ret =devm_request_irq (dev, irq, nxp_fspi_irq_handler,0 , pdev->name, f); -if (ret) { -nxp_fspi_clk_disable_unprep (f); +if (ret)return dev_err_probe (dev, ret,"Failed to request irq\n" ); - } ret =devm_mutex_init (dev, &f->lock);if (ret)
@@ -1271,29 +1294,70 @@ static void nxp_fspi_remove(struct platform_device *pdev) {struct nxp_fspi *f =platform_get_drvdata (pdev); +/* enable clock first since there is reigster access */ +pm_runtime_get_sync (f->dev); +/* disable the hardware */ fspi_writel (f,FSPI_MCR0_MDIS , f->iobase +FSPI_MCR0 ); +pm_runtime_disable (f->dev); +pm_runtime_put_noidle (f->dev);nxp_fspi_clk_disable_unprep (f);if (f->ahb_addr)iounmap (f->ahb_addr); } -static int nxp_fspi_suspend (struct device *dev) +static int nxp_fspi_runtime_suspend (struct device *dev) { +struct nxp_fspi *f =dev_get_drvdata (dev); + +nxp_fspi_clk_disable_unprep (f); +return 0 ; } -static int nxp_fspi_resume (struct device *dev) +static int nxp_fspi_runtime_resume (struct device *dev) {struct nxp_fspi *f =dev_get_drvdata (dev); +int ret; -nxp_fspi_default_setup (f); + ret =nxp_fspi_clk_prep_enable (f); +if (ret) +return ret; -return 0 ; +if (f->flags &FSPI_NEED_INIT ) { +nxp_fspi_default_setup (f); + ret =pinctrl_pm_select_default_state (dev); +if (ret) +dev_err (dev,"select flexspi default pinctrl failed!\n" ); + f->flags &= ~FSPI_NEED_INIT ; + } + +return ret; } +static int nxp_fspi_suspend (struct device *dev) +{ +struct nxp_fspi *f =dev_get_drvdata (dev); +int ret; + + ret =pinctrl_pm_select_sleep_state (dev); +if (ret) { +dev_err (dev,"select flexspi sleep pinctrl failed!\n" ); +return ret; + } + + f->flags |=FSPI_NEED_INIT ; + +return pm_runtime_force_suspend (dev); +} + +static const struct dev_pm_ops nxp_fspi_pm_ops = { + RUNTIME_PM_OPS(nxp_fspi_runtime_suspend, nxp_fspi_runtime_resume, NULL) +SYSTEM_SLEEP_PM_OPS (nxp_fspi_suspend, pm_runtime_force_resume) +}; +static const struct of_device_id nxp_fspi_dt_ids[] = { { .compatible ="nxp,lx2160a-fspi" , .data = (void *)&lx2160a_data, }, { .compatible ="nxp,imx8mm-fspi" , .data = (void *)&imx8mm_data, },
@@ -1313,17 +1377,12 @@ static const struct acpi_device_id nxp_fspi_acpi_ids[] = {MODULE_DEVICE_TABLE (acpi, nxp_fspi_acpi_ids);#endif -static const struct dev_pm_ops nxp_fspi_pm_ops = { - .suspend = nxp_fspi_suspend, - .resume = nxp_fspi_resume, -}; -static struct platform_driver nxp_fspi_driver = { .driver = { .name ="nxp-fspi" , .of_match_table = nxp_fspi_dt_ids, .acpi_match_table =ACPI_PTR (nxp_fspi_acpi_ids), - .pm = &nxp_fspi_pm_ops, + .pm =pm_ptr (&nxp_fspi_pm_ops), }, .probe = nxp_fspi_probe, .remove_new = nxp_fspi_remove,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 143/666 spi: nxp-fspi: Use reinit_completion() for repeated operations
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Gu <[email protected]>
[ Upstream commit 68c8c93fdb0de7e528dc3dfb1d17eb0f652259b8 ]
The driver currently calls init_completion() during every spi_mem_op. Tchnically it may work, but it's not the recommended pattern.
According to the kernel documentation: Calling init_completion() on the same completion object twice is most likely a bug as it re-initializes the queue to an empty queue and enqueued tasks could get "lost" - use reinit_completion() in that case, but be aware of other races.
So moves the initial initialization to probe function and uses reinit_completion() for subsequent operations.
--- drivers/spi/spi-nxp-fspi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/spi/spi-nxp-fspi.c +2 -1
@@ -907,7 +907,7 @@ static int nxp_fspi_do_op(struct nxp_fspi *f, const struct spi_mem_op *op) reg = reg |FSPI_IPRXFCR_CLR ;fspi_writel (f, reg, base +FSPI_IPRXFCR ); -init_completion (&f->c); +reinit_completion (&f->c);fspi_writel (f, op->addr.val, base +FSPI_IPCR0 );/*
@@ -1267,6 +1267,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)if (ret <0 )return dev_err_probe (dev, ret,"Failed to disable clock" ); +init_completion (&f->c); ret =devm_request_irq (dev, irq, nxp_fspi_irq_handler,0 , pdev->name, f);if (ret)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 144/666 spi: fsl-qspi: Use reinit_completion() for repeated operations
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Gu <[email protected]>
[ Upstream commit 981b080a79724738882b0af1c5bb7ade30d94f24 ]
The driver currently calls init_completion() during every spi_mem_op. Tchnically it may work, but it's not the recommended pattern.
According to the kernel documentation: Calling init_completion() on the same completion object twice is most likely a bug as it re-initializes the queue to an empty queue and enqueued tasks could get "lost" - use reinit_completion() in that case, but be aware of other races.
So moves the initial initialization to probe function and uses reinit_completion() for subsequent operations.
--- drivers/spi/spi-fsl-qspi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/spi/spi-fsl-qspi.c +2 -1
@@ -606,7 +606,7 @@ static int fsl_qspi_do_op(struct fsl_qspi *q, const struct spi_mem_op *op)void __iomem *base = q->iobase;int err =0 ; -init_completion (&q->c); +reinit_completion (&q->c);/* * Always start the sequence at the same index since we update
@@ -924,6 +924,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)if (ret <0 ) goto err_disable_clk; +init_completion (&q->c); ret =devm_request_irq (dev, ret, fsl_qspi_irq_handler,0 , pdev->name, q);if (ret) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 145/666 media: i2c: og01a1b: Replace client->dev usage
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Laurent Pinchart <[email protected]>
[ Upstream commit 4d58f671944a16314f03d3c0c40ee69058ca02c9 ]
The driver needs to access the struct device in many places, and retrieves it from the i2c_client itself retrieved with v4l2_get_subdevdata(). Store it as a pointer in struct og01a1b and access it from there instead, to simplify the driver.
While at it, fix a mistake in the sort order of include statements.
Stable-dep-of: 535b7f106991 ("media: i2c: og01a1b: Fix V4L2 subdevice data initialization on probe")
--- drivers/media/i2c/og01a1b.c | 80 ++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 42 deletions(-)
drivers/media/i2c/og01a1b.c +38 -42
@@ -1,7 +1,6 @@// SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2022 Intel Corporation. -#include <linux/unaligned.h> #include <linux/acpi.h> #include <linux/clk.h> #include <linux/delay.h>
@@ -10,6 +9,8 @@#include <linux/module.h> #include <linux/pm_runtime.h> #include <linux/regulator/consumer.h> +#include <linux/unaligned.h> +#include <media/v4l2-ctrls.h> #include <media/v4l2-device.h> #include <media/v4l2-fwnode.h>
@@ -421,6 +422,7 @@ static const struct og01a1b_mode supported_modes[] = { };struct og01a1b { +struct device *dev;struct clk *xvclk;struct gpio_desc *reset_gpio;struct regulator *avdd;
@@ -512,7 +514,6 @@ static int og01a1b_write_reg(struct og01a1b *og01a1b, u16 reg, u16 len, u32 val)static int og01a1b_write_reg_list (struct og01a1b *og01a1b,const struct og01a1b_reg_list *r_list) { -struct i2c_client *client =v4l2_get_subdevdata (&og01a1b->sd);unsigned int i;int ret;
@@ -520,7 +521,7 @@ static int og01a1b_write_reg_list(struct og01a1b *og01a1b, ret =og01a1b_write_reg (og01a1b, r_list->regs[i].address,1 , r_list->regs[i].val);if (ret) { -dev_err_ratelimited (&client->dev, +dev_err_ratelimited (og01a1b->dev,"failed to write reg 0x%4.4x. error = %d" , r_list->regs[i].address, ret);return ret;
@@ -544,7 +545,6 @@ static int og01a1b_set_ctrl(struct v4l2_ctrl *ctrl) {struct og01a1b *og01a1b =container_of (ctrl->handler, struct og01a1b, ctrl_handler); -struct i2c_client *client =v4l2_get_subdevdata (&og01a1b->sd);s64 exposure_max;int ret =0 ;
@@ -560,7 +560,7 @@ static int og01a1b_set_ctrl(struct v4l2_ctrl *ctrl) }/* V4L2 controls values will be applied only when power is already up */ -if (!pm_runtime_get_if_in_use (&client->dev)) +if (!pm_runtime_get_if_in_use (og01a1b->dev))return 0 ;switch (ctrl->id) {
@@ -596,7 +596,7 @@ static int og01a1b_set_ctrl(struct v4l2_ctrl *ctrl)break ; } -pm_runtime_put (&client->dev); +pm_runtime_put (og01a1b->dev);return ret; }
@@ -688,7 +688,6 @@ static void og01a1b_update_pad_format(const struct og01a1b_mode *mode,static int og01a1b_start_streaming (struct og01a1b *og01a1b) { -struct i2c_client *client =v4l2_get_subdevdata (&og01a1b->sd);const struct og01a1b_reg_list *reg_list;int link_freq_index, ret;
@@ -697,14 +696,14 @@ static int og01a1b_start_streaming(struct og01a1b *og01a1b) ret =og01a1b_write_reg_list (og01a1b, reg_list);if (ret) { -dev_err (&client->dev,"failed to set plls" ); +dev_err (og01a1b->dev,"failed to set plls" );return ret; } reg_list = &og01a1b->cur_mode->reg_list; ret =og01a1b_write_reg_list (og01a1b, reg_list);if (ret) { -dev_err (&client->dev,"failed to set mode" ); +dev_err (og01a1b->dev,"failed to set mode" );return ret; }
@@ -716,7 +715,7 @@ static int og01a1b_start_streaming(struct og01a1b *og01a1b)OG01A1B_REG_VALUE_08BIT , OG01A1B_MODE_STREAMING);if (ret) { -dev_err (&client->dev,"failed to set stream" ); +dev_err (og01a1b->dev,"failed to set stream" );return ret; }
@@ -725,22 +724,19 @@ static int og01a1b_start_streaming(struct og01a1b *og01a1b)static void og01a1b_stop_streaming (struct og01a1b *og01a1b) { -struct i2c_client *client =v4l2_get_subdevdata (&og01a1b->sd); -if (og01a1b_write_reg (og01a1b,OG01A1B_REG_MODE_SELECT ,OG01A1B_REG_VALUE_08BIT ,OG01A1B_MODE_STANDBY )) -dev_err (&client->dev,"failed to set stream" ); +dev_err (og01a1b->dev,"failed to set stream" ); }static int og01a1b_set_stream (struct v4l2_subdev *sd,int enable) {struct og01a1b *og01a1b =to_og01a1b (sd); -struct i2c_client *client =v4l2_get_subdevdata (sd);int ret =0 ;mutex_lock (&og01a1b->mutex);if (enable) { - ret =pm_runtime_resume_and_get (&client->dev); + ret =pm_runtime_resume_and_get (og01a1b->dev);if (ret) {mutex_unlock (&og01a1b->mutex);return ret;
@@ -750,11 +746,11 @@ static int og01a1b_set_stream(struct v4l2_subdev *sd, int enable)if (ret) { enable =0 ;og01a1b_stop_streaming (og01a1b); -pm_runtime_put (&client->dev); +pm_runtime_put (og01a1b->dev); } }else {og01a1b_stop_streaming (og01a1b); -pm_runtime_put (&client->dev); +pm_runtime_put (og01a1b->dev); }mutex_unlock (&og01a1b->mutex);
@@ -889,7 +885,6 @@ static const struct v4l2_subdev_internal_ops og01a1b_internal_ops = {static int og01a1b_identify_module (struct og01a1b *og01a1b) { -struct i2c_client *client =v4l2_get_subdevdata (&og01a1b->sd);int ret;u32 val;
@@ -899,7 +894,7 @@ static int og01a1b_identify_module(struct og01a1b *og01a1b)return ret;if (val !=OG01A1B_CHIP_ID ) { -dev_err (&client->dev,"chip id mismatch: %x!=%x" , +dev_err (og01a1b->dev,"chip id mismatch: %x!=%x" ,OG01A1B_CHIP_ID , val);return -ENXIO ; }
@@ -909,8 +904,7 @@ static int og01a1b_identify_module(struct og01a1b *og01a1b)static int og01a1b_check_hwcfg (struct og01a1b *og01a1b) { -struct i2c_client *client =v4l2_get_subdevdata (&og01a1b->sd); -struct device *dev = &client->dev; +struct device *dev = og01a1b->dev;struct fwnode_handle *ep;struct fwnode_handle *fwnode =dev_fwnode (dev);struct v4l2_fwnode_endpoint bus_cfg = {
@@ -1066,7 +1060,7 @@ static void og01a1b_remove(struct i2c_client *client)v4l2_async_unregister_subdev (sd);media_entity_cleanup (&sd->entity);v4l2_ctrl_handler_free (sd->ctrl_handler); -pm_runtime_disable (&client->dev); +pm_runtime_disable (og01a1b->dev);mutex_destroy (&og01a1b->mutex); }
@@ -1079,34 +1073,36 @@ static int og01a1b_probe(struct i2c_client *client)if (!og01a1b)return -ENOMEM ; + og01a1b->dev = &client->dev; +v4l2_i2c_subdev_init (&og01a1b->sd, client, &og01a1b_subdev_ops); - og01a1b->xvclk =devm_clk_get_optional (&client->dev,NULL ); + og01a1b->xvclk =devm_clk_get_optional (og01a1b->dev,NULL );if (IS_ERR (og01a1b->xvclk)) { ret =PTR_ERR (og01a1b->xvclk); -dev_err (&client->dev,"failed to get xvclk clock: %d\n" , ret); +dev_err (og01a1b->dev,"failed to get xvclk clock: %d\n" , ret);return ret; } ret =og01a1b_check_hwcfg (og01a1b);if (ret) { -dev_err (&client->dev,"failed to check HW configuration: %d" , +dev_err (og01a1b->dev,"failed to check HW configuration: %d" , ret);return ret; } - og01a1b->reset_gpio =devm_gpiod_get_optional (&client->dev,"reset" , + og01a1b->reset_gpio =devm_gpiod_get_optional (og01a1b->dev,"reset" ,GPIOD_OUT_LOW );if (IS_ERR (og01a1b->reset_gpio)) { -dev_err (&client->dev,"cannot get reset GPIO\n" ); +dev_err (og01a1b->dev,"cannot get reset GPIO\n" );return PTR_ERR (og01a1b->reset_gpio); } - og01a1b->avdd =devm_regulator_get_optional (&client->dev,"avdd" ); + og01a1b->avdd =devm_regulator_get_optional (og01a1b->dev,"avdd" );if (IS_ERR (og01a1b->avdd)) { ret =PTR_ERR (og01a1b->avdd);if (ret != -ENODEV ) { -dev_err_probe (&client->dev, ret, +dev_err_probe (og01a1b->dev, ret,"Failed to get 'avdd' regulator\n" );return ret; }
@@ -1114,11 +1110,11 @@ static int og01a1b_probe(struct i2c_client *client) og01a1b->avdd =NULL ; } - og01a1b->dovdd =devm_regulator_get_optional (&client->dev,"dovdd" ); + og01a1b->dovdd =devm_regulator_get_optional (og01a1b->dev,"dovdd" );if (IS_ERR (og01a1b->dovdd)) { ret =PTR_ERR (og01a1b->dovdd);if (ret != -ENODEV ) { -dev_err_probe (&client->dev, ret, +dev_err_probe (og01a1b->dev, ret,"Failed to get 'dovdd' regulator\n" );return ret; }
@@ -1126,11 +1122,11 @@ static int og01a1b_probe(struct i2c_client *client) og01a1b->dovdd =NULL ; } - og01a1b->dvdd =devm_regulator_get_optional (&client->dev,"dvdd" ); + og01a1b->dvdd =devm_regulator_get_optional (og01a1b->dev,"dvdd" );if (IS_ERR (og01a1b->dvdd)) { ret =PTR_ERR (og01a1b->dvdd);if (ret != -ENODEV ) { -dev_err_probe (&client->dev, ret, +dev_err_probe (og01a1b->dev, ret,"Failed to get 'dvdd' regulator\n" );return ret; }
@@ -1139,13 +1135,13 @@ static int og01a1b_probe(struct i2c_client *client) }/* The sensor must be powered on to read the CHIP_ID register */ - ret =og01a1b_power_on (&client->dev); + ret =og01a1b_power_on (og01a1b->dev);if (ret)return ret; ret =og01a1b_identify_module (og01a1b);if (ret) { -dev_err (&client->dev,"failed to find sensor: %d" , ret); +dev_err (og01a1b->dev,"failed to find sensor: %d" , ret); goto power_off; }
@@ -1153,7 +1149,7 @@ static int og01a1b_probe(struct i2c_client *client) og01a1b->cur_mode = &supported_modes[0 ]; ret =og01a1b_init_controls (og01a1b);if (ret) { -dev_err (&client->dev,"failed to init controls: %d" , ret); +dev_err (og01a1b->dev,"failed to init controls: %d" , ret); goto probe_error_v4l2_ctrl_handler_free; }
@@ -1164,21 +1160,21 @@ static int og01a1b_probe(struct i2c_client *client) og01a1b->pad.flags =MEDIA_PAD_FL_SOURCE ; ret =media_entity_pads_init (&og01a1b->sd.entity,1 , &og01a1b->pad);if (ret) { -dev_err (&client->dev,"failed to init entity pads: %d" , ret); +dev_err (og01a1b->dev,"failed to init entity pads: %d" , ret); goto probe_error_v4l2_ctrl_handler_free; } ret =v4l2_async_register_subdev_sensor (&og01a1b->sd);if (ret <0 ) { -dev_err (&client->dev,"failed to register V4L2 subdev: %d" , +dev_err (og01a1b->dev,"failed to register V4L2 subdev: %d" , ret); goto probe_error_media_entity_cleanup; }/* Enable runtime PM and turn off the device */ -pm_runtime_set_active (&client->dev); -pm_runtime_enable (&client->dev); -pm_runtime_idle (&client->dev); +pm_runtime_set_active (og01a1b->dev); +pm_runtime_enable (og01a1b->dev); +pm_runtime_idle (og01a1b->dev);return 0 ;
@@ -1190,7 +1186,7 @@ static int og01a1b_probe(struct i2c_client *client)mutex_destroy (&og01a1b->mutex); power_off: -og01a1b_power_off (&client->dev); +og01a1b_power_off (og01a1b->dev);return ret; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 146/666 media: i2c: og01a1b: Fix V4L2 subdevice data initialization on probe
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Zapolskiy <[email protected]>
[ Upstream commit 535b7f106991c7d8f0e5b8e1769bfb8b1ce9d3d6 ]
It's necessary to finalize the camera sensor subdevice initialization on driver probe and clean V4L2 subdevice data up on error paths and driver removal.
The change fixes a previously reported by v4l2-compliance issue of the failed VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT test:
fail: v4l2-test-controls.cpp(1104): subscribe event for control 'User Controls' failed
--- drivers/media/i2c/og01a1b.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/media/i2c/og01a1b.c +12 -1
@@ -1058,6 +1058,7 @@ static void og01a1b_remove(struct i2c_client *client)struct og01a1b *og01a1b =to_og01a1b (sd);v4l2_async_unregister_subdev (sd); +v4l2_subdev_cleanup (&og01a1b->sd);media_entity_cleanup (&sd->entity);v4l2_ctrl_handler_free (sd->ctrl_handler);pm_runtime_disable (og01a1b->dev);
@@ -1164,11 +1165,18 @@ static int og01a1b_probe(struct i2c_client *client) goto probe_error_v4l2_ctrl_handler_free; } + ret =v4l2_subdev_init_finalize (&og01a1b->sd); +if (ret <0 ) { +dev_err_probe (og01a1b->dev, ret, +"failed to finalize subdevice init\n" ); + goto probe_error_media_entity_cleanup; + } + ret =v4l2_async_register_subdev_sensor (&og01a1b->sd);if (ret <0 ) {dev_err (og01a1b->dev,"failed to register V4L2 subdev: %d" , ret); - goto probe_error_media_entity_cleanup; + goto probe_error_v4l2_subdev_cleanup; }/* Enable runtime PM and turn off the device */
@@ -1178,6 +1186,9 @@ static int og01a1b_probe(struct i2c_client *client)return 0 ; +probe_error_v4l2_subdev_cleanup: +v4l2_subdev_cleanup (&og01a1b->sd); + probe_error_media_entity_cleanup:media_entity_cleanup (&og01a1b->sd.entity);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 147/666 selftests/sched_ext: Add missing error check for exit__load()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Carlier <[email protected]>
[ Upstream commit 1d02346fec8d13b05e54296ddc6ae29b7e1067df ]
exit__load(skel) was called without checking its return value. Every other test in the suite wraps the load call with SCX_FAIL_IF(). Add the missing check to be consistent with the rest of the test suite.
--- tools/testing/selftests/sched_ext/exit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/sched_ext/exit.c +1 -1
@@ -32,7 +32,7 @@ static enum scx_test_status run(void *ctx) skel =exit__open (); skel->rodata->exit_point = tc; -exit__load (skel); +SCX_FAIL_IF (exit__load (skel),"Failed to load skel" ); link =bpf_map__attach_struct_ops (skel->maps.exit_ops);if (!link) {SCX_ERR ("Failed to attach scheduler" );
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 148/666 drm/v3d: Handle error from drm_sched_entity_init()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maíra Canal <[email protected]>
[ Upstream commit 8cf1bec37b27846ad3169744c9f1a89a06dcb3fa ]
drm_sched_entity_init() can fail but its return value is currently being ignored in v3d_open(). Check the return value and properly unwind on failure by destroying any already-initialized scheduler entities.
--- drivers/gpu/drm/v3d/v3d_drv.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
drivers/gpu/drm/v3d/v3d_drv.c +12 -4
@@ -109,7 +109,7 @@ v3d_open(struct drm_device *dev, struct drm_file *file)struct v3d_dev *v3d =to_v3d_dev (dev);struct v3d_file_priv *v3d_priv;struct drm_gpu_scheduler *sched; -int i; +int i, ret; v3d_priv =kzalloc (sizeof (*v3d_priv),GFP_KERNEL );if (!v3d_priv)
@@ -119,9 +119,11 @@ v3d_open(struct drm_device *dev, struct drm_file *file)for (i =0 ; i <V3D_MAX_QUEUES ; i++) { sched = &v3d->queue[i].sched; -drm_sched_entity_init (&v3d_priv->sched_entity[i], -DRM_SCHED_PRIORITY_NORMAL , &sched, -1 ,NULL ); + ret =drm_sched_entity_init (&v3d_priv->sched_entity[i], +DRM_SCHED_PRIORITY_NORMAL , &sched, +1 ,NULL ); +if (ret) + goto err_sched;memset (&v3d_priv->stats[i],0 ,sizeof (v3d_priv->stats[i]));seqcount_init (&v3d_priv->stats[i].lock);
@@ -131,6 +133,12 @@ v3d_open(struct drm_device *dev, struct drm_file *file) file->driver_priv = v3d_priv;return 0 ; + +err_sched: +for (i--; i >=0 ; i--) +drm_sched_entity_destroy (&v3d_priv->sched_entity[i]); +kfree (v3d_priv); +return ret; } static void
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 149/666 drm/sun4i: Fix resource leaks
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ethan Tidmore <[email protected]>
[ Upstream commit 127367ad2e0f4870de60c6d719ae82ecf68d674c ]
Three clocks are not being released in devm_regmap_init_mmio() error path.
Add proper goto and set ret to the error code.
--- drivers/gpu/drm/sun4i/sun4i_backend.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/sun4i/sun4i_backend.c +2 -1
@@ -880,7 +880,8 @@ static int sun4i_backend_bind(struct device *dev, struct device *master, &sun4i_backend_regmap_config);if (IS_ERR (backend->engine.regs)) {dev_err (dev,"Couldn't create the backend regmap\n" ); -return PTR_ERR (backend->engine.regs); + ret =PTR_ERR (backend->engine.regs); + goto err_disable_ram_clk; }list_add_tail (&backend->engine.list, &drv->engine_list);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 150/666 drm/amdgpu: Add default case in DVI mode validation
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <[email protected]>
[ Upstream commit e6020a55b8e364d15eac27f9c788e13114eec6b7 ]
amdgpu_connector_dvi_mode_valid() assigns max_digital_pixel_clock_khz based on connector_object_id using a switch statement that lacks a default case.
In practice this code path should never be hit because the existing cases already cover all digital connector types that this function is used for. This is also legacy display code which is not used for new hardware.
Add a default case returning MODE_BAD to make the switch exhaustive and silence the static analyzer smatch error. The new branch is effectively defensive and should never be reached during normal operation.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +2 -0
@@ -1247,6 +1247,8 @@ static enum drm_mode_status amdgpu_connector_dvi_mode_valid(struct drm_connectorcase CONNECTOR_OBJECT_ID_HDMI_TYPE_B : max_digital_pixel_clock_khz = max_dvi_single_link_pixel_clock *2 ;break ; +default : +return MODE_BAD ; }/* When the display EDID claims that it's an HDMI display,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 151/666 dm init: ensure device probing has finished in dm-mod.waitfor=
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guillaume Gonnet <[email protected]>
[ Upstream commit 99a2312f69805f4ba92d98a757625e0300a747ab ]
The early_lookup_bdev() function returns successfully when the disk device is present but not necessarily its partitions. In this situation, dm_early_create() fails as the partition block device does not exist yet.
In my case, this phenomenon occurs quite often because the device is an SD card with slow reading times, on which kernel takes time to enumerate available partitions.
Fortunately, the underlying device is back to "probing" state while enumerating partitions. Waiting for all probing to end is enough to fix this issue.
That's also the reason why this problem never occurs with rootwait=
parameter: the while loop inside wait_for_root() explicitly waits for probing to be done and then the function calls async_synchronize_full(). These lines were omitted in 035641b, even though the commit says it's based on the rootwait logic...
Anyway, calling wait_for_device_probe() after our while loop does the job (it both waits for probing and calls async_synchronize_full).
--- drivers/md/dm-init.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/md/dm-init.c +3 -1
@@ -303,8 +303,10 @@ static int __init dm_init_init(void) } } -if (waitfor[0 ]) +if (waitfor[0 ]) { +wait_for_device_probe ();DMINFO ("all devices available" ); + }list_for_each_entry (dev, &devices, list) { if (dm_early_create(&dev->dmi, dev->table,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 152/666 fbdev: matroxfb: Mark variable with __maybe_unused to avoid W=1 build break
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
[ Upstream commit caf6144053b4e1c815aa56afb54745a176f999df ]
Clang is not happy about set but unused variable:
drivers/video/fbdev/matrox/g450_pll.c:412:18: error: variable 'mnp' set but not used
412 | unsigned int mnp;
| ^
1 error generated.
Since the commit 7b987887f97b ("video: fbdev: matroxfb: remove dead code and set but not used variable") the 'mnp' became unused, but eliminating that code might have side-effects. The question here is what should we do with 'mnp'? The easiest way out is just mark it with __maybe_unused which will shut the compiler up and won't change any possible IO flow. So does this change.
A dive into the history of the driver:
The problem was revealed when the #if 0 guarded code along with unused pixel_vco variable was removed. That code was introduced in the original commit 213d22146d1f ("[PATCH] (1/3) matroxfb for 2.5.3"). And then guarded in the commit 705e41f82988 ("matroxfb DVI updates: Handle DVI output on G450/G550. Powerdown unused portions of G450/G550 DAC. Split G450/G550 DAC from older DAC1064 handling. Modify PLL setting when both CRTCs use same pixel clocks.").
NOTE: The two commits mentioned above pre-date Git era and available in history.git repository for archaeological purposes.
Even without that guard the modern compilers may see that the pixel_vco wasn't ever used and seems a leftover after some debug or review made 25 years ago.
The g450_mnp2vco() doesn't have any IO and as Jason said doesn't seem to have any side effects either than some unneeded CPU processing during runtime. I agree that's unlikely that timeout (or heating up the CPU) has any effect on the HW (GPU/display) functionality.
--- drivers/video/fbdev/matrox/g450_pll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/video/fbdev/matrox/g450_pll.c +1 -1
@@ -407,7 +407,7 @@ static int __g450_setclk(struct matrox_fb_info *minfo, unsigned int fout,case M_VIDEO_PLL : {u_int8_t tmp; -unsigned int mnp; +unsigned int mnp__maybe_unused ;unsigned long flags;matroxfb_DAC_lock_irqsave (flags);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 153/666 crypto: tegra - finalize crypto req on error
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Akhil R <[email protected]>
[ Upstream commit 1e245948ca0c252f561792fabb45de5518301d97 ]
Call the crypto finalize function before exiting *do_one_req() functions. This allows the driver to take up further requests even if the previous one fails.
Stable-dep-of: 2aeec9af775f ("crypto: tegra - Disable softirqs before finalizing request")
--- drivers/crypto/tegra/tegra-se-aes.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-)
drivers/crypto/tegra/tegra-se-aes.c +17 -11
@@ -275,8 +275,10 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq) rctx->datbuf.size = rctx->len; rctx->datbuf.buf =dma_alloc_coherent (se->dev, rctx->datbuf.size, &rctx->datbuf.addr,GFP_KERNEL ); -if (!rctx->datbuf.buf) -return -ENOMEM ; +if (!rctx->datbuf.buf) { + ret = -ENOMEM ; + goto out_finalize; + }scatterwalk_map_and_copy (rctx->datbuf.buf, req->src,0 , req->cryptlen,0 );
@@ -292,6 +294,7 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq)dma_free_coherent (ctx->se->dev, rctx->datbuf.size, rctx->datbuf.buf, rctx->datbuf.addr); +out_finalize:crypto_finalize_skcipher_request (se->engine, req, ret);return 0 ;
@@ -1153,21 +1156,21 @@ static int tegra_ccm_do_one_req(struct crypto_engine *engine, void *areq) ret =tegra_ccm_crypt_init (req, se, rctx);if (ret) -return ret; + goto out_finalize;/* Allocate buffers required */ rctx->inbuf.size = rctx->assoclen + rctx->authsize + rctx->cryptlen +100 ; rctx->inbuf.buf =dma_alloc_coherent (ctx->se->dev, rctx->inbuf.size, &rctx->inbuf.addr,GFP_KERNEL );if (!rctx->inbuf.buf) -return -ENOMEM ; + goto out_finalize; rctx->outbuf.size = rctx->assoclen + rctx->authsize + rctx->cryptlen +100 ; rctx->outbuf.buf =dma_alloc_coherent (ctx->se->dev, rctx->outbuf.size, &rctx->outbuf.addr,GFP_KERNEL );if (!rctx->outbuf.buf) { ret = -ENOMEM ; - goto outbuf_err; + goto out_free_inbuf; }if (rctx->encrypt) {
@@ -1196,10 +1199,11 @@ static int tegra_ccm_do_one_req(struct crypto_engine *engine, void *areq)dma_free_coherent (ctx->se->dev, rctx->inbuf.size, rctx->outbuf.buf, rctx->outbuf.addr); -outbuf_err: +out_free_inbuf:dma_free_coherent (ctx->se->dev, rctx->outbuf.size, rctx->inbuf.buf, rctx->inbuf.addr); +out_finalize:crypto_finalize_aead_request (ctx->se->engine, req, ret);return 0 ;
@@ -1230,15 +1234,17 @@ static int tegra_gcm_do_one_req(struct crypto_engine *engine, void *areq) rctx->inbuf.size = rctx->assoclen + rctx->authsize + rctx->cryptlen; rctx->inbuf.buf =dma_alloc_coherent (ctx->se->dev, rctx->inbuf.size, &rctx->inbuf.addr,GFP_KERNEL ); -if (!rctx->inbuf.buf) -return -ENOMEM ; +if (!rctx->inbuf.buf) { + ret = -ENOMEM ; + goto out_finalize; + } rctx->outbuf.size = rctx->assoclen + rctx->authsize + rctx->cryptlen; rctx->outbuf.buf =dma_alloc_coherent (ctx->se->dev, rctx->outbuf.size, &rctx->outbuf.addr,GFP_KERNEL );if (!rctx->outbuf.buf) { ret = -ENOMEM ; - goto outbuf_err; + goto out_free_inbuf; }/* If there is associated data perform GMAC operation */
@@ -1267,11 +1273,11 @@ static int tegra_gcm_do_one_req(struct crypto_engine *engine, void *areq)dma_free_coherent (ctx->se->dev, rctx->outbuf.size, rctx->outbuf.buf, rctx->outbuf.addr); -outbuf_err: +out_free_inbuf:dma_free_coherent (ctx->se->dev, rctx->inbuf.size, rctx->inbuf.buf, rctx->inbuf.addr); -/* Finalize the request if there are no errors */ +out_finalize:crypto_finalize_aead_request (ctx->se->engine, req, ret);return 0 ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 154/666 crypto: tegra - Transfer HASH init function to crypto engine
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Akhil R <[email protected]>
[ Upstream commit 97ee15ea101629d2ffe21d3c5dc03b8d8be43603 ]
Ahash init() function was called asynchronous to the crypto engine queue. This could corrupt the request context if there is any ongoing operation for the same request. Queue the init function as well to the crypto engine queue so that this scenario can be avoided.
Stable-dep-of: 2aeec9af775f ("crypto: tegra - Disable softirqs before finalizing request")
--- drivers/crypto/tegra/tegra-se-aes.c | 81 ++++++++++++--------- drivers/crypto/tegra/tegra-se-hash.c | 101 +++++++++++++++------------ drivers/crypto/tegra/tegra-se.h | 5 +- 3 files changed, 109 insertions(+), 78 deletions(-)
drivers/crypto/tegra/tegra-se-aes.c +48 -33
@@ -1460,6 +1460,34 @@ static void tegra_cmac_paste_result(struct tegra_se *se, struct tegra_cmac_reqct se->base + se->hw->regs->result + (i * 4)); } +static int tegra_cmac_do_init (struct ahash_request *req) +{ +struct tegra_cmac_reqctx *rctx =ahash_request_ctx (req); +struct crypto_ahash *tfm =crypto_ahash_reqtfm (req); +struct tegra_cmac_ctx *ctx =crypto_ahash_ctx (tfm); +struct tegra_se *se = ctx->se; +int i; + + rctx->total_len =0 ; + rctx->datbuf.size =0 ; + rctx->residue.size =0 ; + rctx->task |=SHA_FIRST ; + rctx->blk_size =crypto_ahash_blocksize (tfm); + + rctx->residue.buf =dma_alloc_coherent (se->dev, rctx->blk_size *2 , + &rctx->residue.addr,GFP_KERNEL ); +if (!rctx->residue.buf) +return -ENOMEM ; + + rctx->residue.size =0 ; + +/* Clear any previous result */ +for (i =0 ; i <CMAC_RESULT_REG_COUNT ; i++) +writel (0 , se->base + se->hw->regs->result + (i *4 )); + +return 0 ; +} +static int tegra_cmac_do_update (struct ahash_request *req) {struct tegra_cmac_reqctx *rctx =ahash_request_ctx (req);
@@ -1605,6 +1633,14 @@ static int tegra_cmac_do_one_req(struct crypto_engine *engine, void *areq)struct tegra_se *se = ctx->se;int ret =0 ; +if (rctx->task &SHA_INIT ) { + ret =tegra_cmac_do_init (req); +if (ret) + goto out; + + rctx->task &= ~SHA_INIT ; + } +if (rctx->task &SHA_UPDATE ) { ret =tegra_cmac_do_update (req);if (ret)
@@ -1685,34 +1721,6 @@ static void tegra_cmac_cra_exit(struct crypto_tfm *tfm)tegra_key_invalidate (ctx->se, ctx->key_id, ctx->alg); } -static int tegra_cmac_init (struct ahash_request *req) -{ -struct tegra_cmac_reqctx *rctx =ahash_request_ctx (req); -struct crypto_ahash *tfm =crypto_ahash_reqtfm (req); -struct tegra_cmac_ctx *ctx =crypto_ahash_ctx (tfm); -struct tegra_se *se = ctx->se; -int i; - - rctx->total_len =0 ; - rctx->datbuf.size =0 ; - rctx->residue.size =0 ; - rctx->task =SHA_FIRST ; - rctx->blk_size =crypto_ahash_blocksize (tfm); - - rctx->residue.buf =dma_alloc_coherent (se->dev, rctx->blk_size *2 , - &rctx->residue.addr,GFP_KERNEL ); -if (!rctx->residue.buf) -return -ENOMEM ; - - rctx->residue.size =0 ; - -/* Clear any previous result */ -for (i =0 ; i <CMAC_RESULT_REG_COUNT ; i++) -writel (0 , se->base + se->hw->regs->result + (i *4 )); - -return 0 ; -} -static int tegra_cmac_setkey (struct crypto_ahash *tfm,const u8 *key,unsigned int keylen) {
@@ -1729,6 +1737,17 @@ static int tegra_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,return tegra_key_submit (ctx->se, key, keylen, ctx->alg, &ctx->key_id); } +static int tegra_cmac_init (struct ahash_request *req) +{ +struct crypto_ahash *tfm =crypto_ahash_reqtfm (req); +struct tegra_cmac_ctx *ctx =crypto_ahash_ctx (tfm); +struct tegra_cmac_reqctx *rctx =ahash_request_ctx (req); + + rctx->task =SHA_INIT ; + +return crypto_transfer_hash_request_to_engine (ctx->se->engine, req); +} +static int tegra_cmac_update (struct ahash_request *req) {struct crypto_ahash *tfm =crypto_ahash_reqtfm (req);
@@ -1767,13 +1786,9 @@ static int tegra_cmac_digest(struct ahash_request *req)struct crypto_ahash *tfm =crypto_ahash_reqtfm (req);struct tegra_cmac_ctx *ctx =crypto_ahash_ctx (tfm);struct tegra_cmac_reqctx *rctx =ahash_request_ctx (req); -int ret; - ret =tegra_cmac_init (req); -if (ret) -return ret; + rctx->task |=SHA_INIT |SHA_UPDATE |SHA_FINAL ; - rctx->task |=SHA_UPDATE |SHA_FINAL ;return crypto_transfer_hash_request_to_engine (ctx->se->engine, req); }
drivers/crypto/tegra/tegra-se-hash.c +58 -43
136 lines not on this page · raw message
drivers/crypto/tegra/tegra-se.h +3 -2
@@ -342,8 +342,9 @@#define SE_MAX_MEM_ALLOC SZ_4M#define SHA_FIRST BIT(0) -#define SHA_UPDATE BIT(1) -#define SHA_FINAL BIT(2) +#define SHA_INIT BIT(1) +#define SHA_UPDATE BIT(2) +#define SHA_FINAL BIT(3)/* Security Engine operation modes */ enum se_aes_alg {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 155/666 crypto: tegra - Reserve keyslots to allocate dynamically
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Akhil R <[email protected]>
[ Upstream commit b157e7a228aee9b48c2de05129476b822aa7956d ]
The HW supports only storing 15 keys at a time. This limits the number of tfms that can work without failutes. Reserve keyslots to solve this and use the reserved ones during the encryption/decryption operation. This allow users to have the capability of hardware protected keys and faster operations if there are limited number of tfms while not halting the operation if there are more tfms.
Stable-dep-of: 2aeec9af775f ("crypto: tegra - Disable softirqs before finalizing request")
--- drivers/crypto/tegra/tegra-se-aes.c | 139 +++++++++++++++++++++++----- drivers/crypto/tegra/tegra-se-key.c | 19 +++- drivers/crypto/tegra/tegra-se.h | 28 ++++++ 3 files changed, 164 insertions(+), 22 deletions(-)
drivers/crypto/tegra/tegra-se-aes.c +118 -21
@@ -28,6 +28,9 @@ struct tegra_aes_ctx {u32 ivsize;u32 key1_id;u32 key2_id; +u32 keylen; +u8 key1[AES_MAX_KEY_SIZE ]; +u8 key2[AES_MAX_KEY_SIZE ]; };struct tegra_aes_reqctx {
@@ -43,8 +46,9 @@ struct tegra_aead_ctx {struct tegra_se *se;unsigned int authsize;u32 alg; -u32 keylen;u32 key_id; +u32 keylen; +u8 key[AES_MAX_KEY_SIZE ]; };struct tegra_aead_reqctx {
@@ -56,8 +60,8 @@ struct tegra_aead_reqctx {unsigned int cryptlen;unsigned int authsize;bool encrypt; -u32 config;u32 crypto_config; +u32 config;u32 key_id;u32 iv[4 ];u8 authdata[16 ];
@@ -67,6 +71,8 @@ struct tegra_cmac_ctx {struct tegra_se *se;unsigned int alg;u32 key_id; +u32 keylen; +u8 key[AES_MAX_KEY_SIZE ];struct crypto_shash *fallback_tfm; };
@@ -260,11 +266,13 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq)struct tegra_aes_ctx *ctx =crypto_skcipher_ctx (crypto_skcipher_reqtfm (req));struct tegra_aes_reqctx *rctx =skcipher_request_ctx (req);struct tegra_se *se = ctx->se; -unsigned int cmdlen; +unsigned int cmdlen, key1_id, key2_id;int ret; rctx->iv = (ctx->alg ==SE_ALG_ECB ) ?NULL : (u32 *)req->iv; rctx->len = req->cryptlen; + key1_id = ctx->key1_id; + key2_id = ctx->key2_id;/* Pad input to AES Block size */ if (ctx->alg !=SE_ALG_XTS ) {
@@ -282,6 +290,29 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq)scatterwalk_map_and_copy (rctx->datbuf.buf, req->src,0 , req->cryptlen,0 ); + rctx->config =tegra234_aes_cfg (ctx->alg, rctx->encrypt); + rctx->crypto_config =tegra234_aes_crypto_cfg (ctx->alg, rctx->encrypt); + +if (!key1_id) { + ret =tegra_key_submit_reserved_aes (ctx->se, ctx->key1, + ctx->keylen, ctx->alg, &key1_id); +if (ret) + goto out; + } + + rctx->crypto_config |=SE_AES_KEY_INDEX (key1_id); + +if (ctx->alg ==SE_ALG_XTS ) { +if (!key2_id) { + ret =tegra_key_submit_reserved_xts (ctx->se, ctx->key2, + ctx->keylen, ctx->alg, &key2_id); +if (ret) + goto out; + } + + rctx->crypto_config |=SE_AES_KEY2_INDEX (key2_id); + } +/* Prepare the command and submit for execution */ cmdlen =tegra_aes_prep_cmd (ctx, rctx); ret =tegra_se_host1x_submit (se, se->cmdbuf, cmdlen);
@@ -290,10 +321,17 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq)tegra_aes_update_iv (req, ctx);scatterwalk_map_and_copy (rctx->datbuf.buf, req->dst,0 , req->cryptlen,1 ); +out:/* Free the buffer */ dma_free_coherent (ctx->se->dev, rctx->datbuf.size, rctx->datbuf.buf, rctx->datbuf.addr); +if (tegra_key_is_reserved (key1_id)) +tegra_key_invalidate_reserved (ctx->se, key1_id, ctx->alg); + +if (tegra_key_is_reserved (key2_id)) +tegra_key_invalidate_reserved (ctx->se, key2_id, ctx->alg); + out_finalize:crypto_finalize_skcipher_request (se->engine, req, ret);
@@ -316,6 +354,7 @@ static int tegra_aes_cra_init(struct crypto_skcipher *tfm) ctx->se = se_alg->se_dev; ctx->key1_id =0 ; ctx->key2_id =0 ; + ctx->keylen =0 ; algname =crypto_tfm_alg_name (&tfm->base); ret =se_algname_to_algid (algname);
@@ -344,13 +383,20 @@ static int tegra_aes_setkey(struct crypto_skcipher *tfm, const u8 *key, u32 keylen) {struct tegra_aes_ctx *ctx =crypto_skcipher_ctx (tfm); +int ret;if (aes_check_keylen (keylen)) {dev_dbg (ctx->se->dev,"invalid key length (%d)\n" , keylen);return -EINVAL ; } -return tegra_key_submit (ctx->se, key, keylen, ctx->alg, &ctx->key1_id); + ret =tegra_key_submit (ctx->se, key, keylen, ctx->alg, &ctx->key1_id); +if (ret) { + ctx->keylen = keylen; +memcpy (ctx->key1, key, keylen); + } + +return 0 ; } static int tegra_xts_setkey(struct crypto_skcipher *tfm,
@@ -368,11 +414,17 @@ static int tegra_xts_setkey(struct crypto_skcipher *tfm, ret =tegra_key_submit (ctx->se, key, len, ctx->alg, &ctx->key1_id); -if (ret) -return ret; +if (ret) { + ctx->keylen = len; +memcpy (ctx->key1, key, len); + } -return tegra_key_submit (ctx->se, key + len, len, + ret =tegra_key_submit (ctx->se, key + len, len, ctx->alg, &ctx->key2_id); +if (ret) { + ctx->keylen = len; +memcpy (ctx->key2, key + len, len); + }return 0 ; }
@@ -447,12 +499,6 @@ static int tegra_aes_crypt(struct skcipher_request *req, bool encrypt)return 0 ; rctx->encrypt = encrypt; - rctx->config =tegra234_aes_cfg (ctx->alg, encrypt); - rctx->crypto_config =tegra234_aes_crypto_cfg (ctx->alg, encrypt); - rctx->crypto_config |=SE_AES_KEY_INDEX (ctx->key1_id); - -if (ctx->key2_id) - rctx->crypto_config |=SE_AES_KEY2_INDEX (ctx->key2_id);return crypto_transfer_skcipher_request_to_engine (ctx->se->engine, req); }
@@ -719,7 +765,7 @@ static int tegra_gcm_do_gmac(struct tegra_aead_ctx *ctx, struct tegra_aead_reqct rctx->config =tegra234_aes_cfg (SE_ALG_GMAC , rctx->encrypt); rctx->crypto_config =tegra234_aes_crypto_cfg (SE_ALG_GMAC , rctx->encrypt) | -SE_AES_KEY_INDEX (ctx->key_id); +SE_AES_KEY_INDEX (rctx->key_id); cmdlen =tegra_gmac_prep_cmd (ctx, rctx);
@@ -736,7 +782,7 @@ static int tegra_gcm_do_crypt(struct tegra_aead_ctx *ctx, struct tegra_aead_reqc rctx->config =tegra234_aes_cfg (SE_ALG_GCM , rctx->encrypt); rctx->crypto_config =tegra234_aes_crypto_cfg (SE_ALG_GCM , rctx->encrypt) | -SE_AES_KEY_INDEX (ctx->key_id); +SE_AES_KEY_INDEX (rctx->key_id);/* Prepare command and submit */ cmdlen =tegra_gcm_crypt_prep_cmd (ctx, rctx);
@@ -759,7 +805,7 @@ static int tegra_gcm_do_final(struct tegra_aead_ctx *ctx, struct tegra_aead_reqc rctx->config =tegra234_aes_cfg (SE_ALG_GCM_FINAL , rctx->encrypt); rctx->crypto_config =tegra234_aes_crypto_cfg (SE_ALG_GCM_FINAL , rctx->encrypt) | -SE_AES_KEY_INDEX (ctx->key_id); +SE_AES_KEY_INDEX (rctx->key_id);/* Prepare command and submit */ cmdlen =tegra_gcm_prep_final_cmd (se, cpuvaddr, rctx);
@@ -890,7 +936,7 @@ static int tegra_ccm_do_cbcmac(struct tegra_aead_ctx *ctx, struct tegra_aead_req rctx->config =tegra234_aes_cfg (SE_ALG_CBC_MAC , rctx->encrypt); rctx->crypto_config =tegra234_aes_crypto_cfg (SE_ALG_CBC_MAC , rctx->encrypt) | -SE_AES_KEY_INDEX (ctx->key_id); +SE_AES_KEY_INDEX (rctx->key_id);/* Prepare command and submit */ cmdlen =tegra_cbcmac_prep_cmd (ctx, rctx);
@@ -1077,7 +1123,7 @@ static int tegra_ccm_do_ctr(struct tegra_aead_ctx *ctx, struct tegra_aead_reqctx rctx->config =tegra234_aes_cfg (SE_ALG_CTR , rctx->encrypt); rctx->crypto_config =tegra234_aes_crypto_cfg (SE_ALG_CTR , rctx->encrypt) | -SE_AES_KEY_INDEX (ctx->key_id); +SE_AES_KEY_INDEX (rctx->key_id);/* Copy authdata in the top of buffer for encryption/decryption */ if (rctx->encrypt)
@@ -1158,6 +1204,8 @@ static int tegra_ccm_do_one_req(struct crypto_engine *engine, void *areq)if (ret) goto out_finalize; + rctx->key_id = ctx->key_id; +/* Allocate buffers required */ rctx->inbuf.size = rctx->assoclen + rctx->authsize + rctx->cryptlen +100 ; rctx->inbuf.buf = dma_alloc_coherent(ctx->se->dev, rctx->inbuf.size,
@@ -1173,6 +1221,13 @@ static int tegra_ccm_do_one_req(struct crypto_engine *engine, void *areq) goto out_free_inbuf; } +if (!ctx->key_id) { + ret =tegra_key_submit_reserved_aes (ctx->se, ctx->key, + ctx->keylen, ctx->alg, &rctx->key_id); +if (ret) + goto out; + } +if (rctx->encrypt) {/* CBC MAC Operation */ ret =tegra_ccm_compute_auth (ctx, rctx);
@@ -1203,6 +1258,9 @@ static int tegra_ccm_do_one_req(struct crypto_engine *engine, void *areq)dma_free_coherent (ctx->se->dev, rctx->outbuf.size, rctx->inbuf.buf, rctx->inbuf.addr); +if (tegra_key_is_reserved (rctx->key_id)) +tegra_key_invalidate_reserved (ctx->se, rctx->key_id, ctx->alg); + out_finalize:crypto_finalize_aead_request (ctx->se->engine, req, ret);
@@ -1230,6 +1288,8 @@ static int tegra_gcm_do_one_req(struct crypto_engine *engine, void *areq)memcpy (rctx->iv, req->iv,GCM_AES_IV_SIZE ); rctx->iv[3 ] = (1 <<24 ); + rctx->key_id = ctx->key_id; +/* Allocate buffers required */ rctx->inbuf.size = rctx->assoclen + rctx->authsize + rctx->cryptlen; rctx->inbuf.buf = dma_alloc_coherent(ctx->se->dev, rctx->inbuf.size,
@@ -1247,6 +1307,13 @@ static int tegra_gcm_do_one_req(struct crypto_engine *engine, void *areq) goto out_free_inbuf; } +if (!ctx->key_id) { + ret =tegra_key_submit_reserved_aes (ctx->se, ctx->key, + ctx->keylen, ctx->alg, &rctx->key_id); +if (ret) + goto out; + } +/* If there is associated data perform GMAC operation */ if (rctx->assoclen) { ret =tegra_gcm_do_gmac (ctx, rctx);
@@ -1277,6 +1344,9 @@ static int tegra_gcm_do_one_req(struct crypto_engine *engine, void *areq)dma_free_coherent (ctx->se->dev, rctx->inbuf.size, rctx->inbuf.buf, rctx->inbuf.addr); +if (tegra_key_is_reserved (rctx->key_id)) +tegra_key_invalidate_reserved (ctx->se, rctx->key_id, ctx->alg); + out_finalize:crypto_finalize_aead_request (ctx->se->engine, req, ret);
@@ -1299,6 +1369,7 @@ static int tegra_aead_cra_init(struct crypto_aead *tfm) ctx->se = se_alg->se_dev; ctx->key_id =0 ; + ctx->keylen =0 ; ret =se_algname_to_algid (algname);if (ret <0 ) {
@@ -1380,13 +1451,20 @@ static int tegra_aead_setkey(struct crypto_aead *tfm, const u8 *key, u32 keylen) {struct tegra_aead_ctx *ctx =crypto_aead_ctx (tfm); +int ret;if (aes_check_keylen (keylen)) {dev_dbg (ctx->se->dev,"invalid key length (%d)\n" , keylen);return -EINVAL ; } -return tegra_key_submit (ctx->se, key, keylen, ctx->alg, &ctx->key_id); + ret =tegra_key_submit (ctx->se, key, keylen, ctx->alg, &ctx->key_id); +if (ret) { + ctx->keylen = keylen; +memcpy (ctx->key, key, keylen); + } + +return 0 ; } static unsigned int tegra_cmac_prep_cmd(struct tegra_cmac_ctx *ctx,
@@ -1471,6 +1549,7 @@ static int tegra_cmac_do_init(struct ahash_request *req) rctx->total_len =0 ; rctx->datbuf.size =0 ; rctx->residue.size =0 ; + rctx->key_id = ctx->key_id; rctx->task |=SHA_FIRST ; rctx->blk_size =crypto_ahash_blocksize (tfm);
@@ -1515,7 +1594,7 @@ static int tegra_cmac_do_update(struct ahash_request *req) rctx->datbuf.size = (req->nbytes + rctx->residue.size) - nresidue; rctx->total_len += rctx->datbuf.size; rctx->config =tegra234_aes_cfg (SE_ALG_CMAC ,0 ); - rctx->crypto_config =SE_AES_KEY_INDEX (ctx->key_id); + rctx->crypto_config =SE_AES_KEY_INDEX (rctx->key_id);/* * Keep one block and residue bytes in residue and
@@ -1641,6 +1720,13 @@ static int tegra_cmac_do_one_req(struct crypto_engine *engine, void *areq) rctx->task &= ~SHA_INIT ; } +if (!ctx->key_id) { + ret =tegra_key_submit_reserved_aes (ctx->se, ctx->key, + ctx->keylen, ctx->alg, &rctx->key_id); +if (ret) + goto out; + } +if (rctx->task &SHA_UPDATE ) { ret =tegra_cmac_do_update (req);if (ret)
@@ -1657,6 +1743,9 @@ static int tegra_cmac_do_one_req(struct crypto_engine *engine, void *areq) rctx->task &= ~SHA_FINAL ; } out: +if (tegra_key_is_reserved (rctx->key_id)) +tegra_key_invalidate_reserved (ctx->se, rctx->key_id, ctx->alg); +crypto_finalize_hash_request (se->engine, req, ret);return 0 ;
@@ -1697,6 +1786,7 @@ static int tegra_cmac_cra_init(struct crypto_tfm *tfm) ctx->se = se_alg->se_dev; ctx->key_id =0 ; + ctx->keylen =0 ; ret =se_algname_to_algid (algname);if (ret <0 ) {
@@ -1725,6 +1815,7 @@ static int tegra_cmac_setkey(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen) {struct tegra_cmac_ctx *ctx =crypto_ahash_ctx (tfm); +int ret;if (aes_check_keylen (keylen)) {dev_dbg (ctx->se->dev,"invalid key length (%d)\n" , keylen);
@@ -1734,7 +1825,13 @@ static int tegra_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,if (ctx->fallback_tfm)crypto_shash_setkey (ctx->fallback_tfm, key, keylen); -return tegra_key_submit (ctx->se, key, keylen, ctx->alg, &ctx->key_id); + ret =tegra_key_submit (ctx->se, key, keylen, ctx->alg, &ctx->key_id); +if (ret) { + ctx->keylen = keylen; +memcpy (ctx->key, key, keylen); + } + +return 0 ; }static int tegra_cmac_init (struct ahash_request *req)
drivers/crypto/tegra/tegra-se-key.c +18 -1
@@ -141,6 +141,23 @@ void tegra_key_invalidate(struct tegra_se *se, u32 keyid, u32 alg)tegra_keyslot_free (keyid); } +void tegra_key_invalidate_reserved (struct tegra_se *se,u32 keyid,u32 alg) +{ +u8 zkey[AES_MAX_KEY_SIZE ] = {0 }; + +if (!keyid) +return ; + +/* Overwrite the key with 0s */ +tegra_key_insert (se, zkey,AES_MAX_KEY_SIZE , keyid, alg); +} + +inline int tegra_key_submit_reserved (struct tegra_se *se,const u8 *key, +u32 keylen,u32 alg,u32 *keyid) +{ +return tegra_key_insert (se, key, keylen, *keyid, alg); +} +int tegra_key_submit (struct tegra_se *se,const u8 *key,u32 keylen,u32 alg,u32 *keyid) {int ret;
@@ -149,7 +166,7 @@ int tegra_key_submit(struct tegra_se *se, const u8 *key, u32 keylen, u32 alg, u3if (!tegra_key_in_kslt (*keyid)) { *keyid =tegra_keyslot_alloc ();if (!(*keyid)) { -dev_err (se->dev,"failed to allocate key slot\n" ); +dev_dbg (se->dev,"failed to allocate key slot\n" );return -ENOMEM ; } }
drivers/crypto/tegra/tegra-se.h +28 -0
@@ -341,6 +341,9 @@#define SE_MAX_KEYSLOT 15#define SE_MAX_MEM_ALLOC SZ_4M +#define TEGRA_AES_RESERVED_KSLT 14 +#define TEGRA_XTS_RESERVED_KSLT 15 +#define SHA_FIRST BIT(0)#define SHA_INIT BIT(1)#define SHA_UPDATE BIT(2)
@@ -501,9 +504,34 @@ void tegra_deinit_aes(struct tegra_se *se);void tegra_deinit_hash (struct tegra_se *se);int tegra_key_submit (struct tegra_se *se,const u8 *key,u32 keylen,u32 alg,u32 *keyid); + +int tegra_key_submit_reserved (struct tegra_se *se,const u8 *key, +u32 keylen,u32 alg,u32 *keyid); +void tegra_key_invalidate (struct tegra_se *se,u32 keyid,u32 alg); +void tegra_key_invalidate_reserved (struct tegra_se *se,u32 keyid,u32 alg);int tegra_se_host1x_submit (struct tegra_se *se,struct tegra_se_cmdbuf *cmdbuf,u32 size); +static inline int tegra_key_submit_reserved_aes (struct tegra_se *se,const u8 *key, +u32 keylen,u32 alg,u32 *keyid) +{ + *keyid =TEGRA_AES_RESERVED_KSLT ; +return tegra_key_submit_reserved (se, key, keylen, alg, keyid); +} + +static inline int tegra_key_submit_reserved_xts (struct tegra_se *se,const u8 *key, +u32 keylen,u32 alg,u32 *keyid) +{ + *keyid =TEGRA_XTS_RESERVED_KSLT ; +return tegra_key_submit_reserved (se, key, keylen, alg, keyid); +} + +static inline bool tegra_key_is_reserved (u32 keyid) +{ +return ((keyid ==TEGRA_AES_RESERVED_KSLT ) || + (keyid ==TEGRA_XTS_RESERVED_KSLT )); +} +/* HOST1x OPCODES */ static inline u32 host1x_opcode_setpayload (unsigned int payload) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 156/666 crypto: tegra - Disable softirqs before finalizing request
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herbert Xu <[email protected]>
[ Upstream commit 2aeec9af775fb53aa086419b953302c6f4ad4984 ]
Softirqs must be disabled when calling the finalization fucntion on a request.
--- drivers/crypto/tegra/tegra-se-aes.c | 9 +++++++++ drivers/crypto/tegra/tegra-se-hash.c | 3 +++ 2 files changed, 12 insertions(+)
drivers/crypto/tegra/tegra-se-aes.c +9 -0
@@ -4,6 +4,7 @@* Crypto driver to handle block cipher algorithms using NVIDIA Security Engine. */ +#include <linux/bottom_half.h> #include <linux/clk.h> #include <linux/dma-mapping.h> #include <linux/module.h>
@@ -333,7 +334,9 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq)tegra_key_invalidate_reserved (ctx->se, key2_id, ctx->alg); out_finalize: +local_bh_disable ();crypto_finalize_skcipher_request (se->engine, req, ret); +local_bh_enable ();return 0 ; }
@@ -1262,7 +1265,9 @@ static int tegra_ccm_do_one_req(struct crypto_engine *engine, void *areq)tegra_key_invalidate_reserved (ctx->se, rctx->key_id, ctx->alg); out_finalize: +local_bh_disable ();crypto_finalize_aead_request (ctx->se->engine, req, ret); +local_bh_enable ();return 0 ; }
@@ -1348,7 +1353,9 @@ static int tegra_gcm_do_one_req(struct crypto_engine *engine, void *areq)tegra_key_invalidate_reserved (ctx->se, rctx->key_id, ctx->alg); out_finalize: +local_bh_disable ();crypto_finalize_aead_request (ctx->se->engine, req, ret); +local_bh_enable ();return 0 ; }
@@ -1746,7 +1753,9 @@ static int tegra_cmac_do_one_req(struct crypto_engine *engine, void *areq)if (tegra_key_is_reserved (rctx->key_id))tegra_key_invalidate_reserved (ctx->se, rctx->key_id, ctx->alg); +local_bh_disable ();crypto_finalize_hash_request (se->engine, req, ret); +local_bh_enable ();return 0 ; }
drivers/crypto/tegra/tegra-se-hash.c +3 -0
@@ -4,6 +4,7 @@* Crypto driver to handle HASH algorithms using NVIDIA Security Engine. */ +#include <linux/bottom_half.h> #include <linux/clk.h> #include <linux/dma-mapping.h> #include <linux/module.h>
@@ -498,7 +499,9 @@ static int tegra_sha_do_one_req(struct crypto_engine *engine, void *areq) } out: +local_bh_disable ();crypto_finalize_hash_request (se->engine, req, ret); +local_bh_enable ();return 0 ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 157/666 crypto: atmel - Use unregister_{aeads,ahashes,skciphers}
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thorsten Blum <[email protected]>
[ Upstream commit 2ffc1ef4e826f0c3274f9ff5eb42bc70a5571afd ]
Replace multiple for loops with calls to crypto_unregister_aeads(), crypto_unregister_ahashes(), and crypto_unregister_skciphers().
Remove the definition of atmel_tdes_unregister_algs() because it is equivalent to calling crypto_unregister_skciphers() directly, and the function parameter 'struct atmel_tdes_dev *' is unused anyway.
Stable-dep-of: 57a13941c0bb ("crypto: atmel-aes - guard unregister on error in atmel_aes_register_algs")
--- drivers/crypto/atmel-aes.c | 17 ++++++----------- drivers/crypto/atmel-sha.c | 27 ++++++++++----------------- drivers/crypto/atmel-tdes.c | 25 ++++++------------------- 3 files changed, 22 insertions(+), 47 deletions(-)
drivers/crypto/atmel-aes.c +6 -11
@@ -2200,12 +2200,10 @@ static irqreturn_t atmel_aes_irq(int irq, void *dev_id)static void atmel_aes_unregister_algs (struct atmel_aes_dev *dd) { -int i; -#if IS_ENABLED (CONFIG_CRYPTO_DEV_ATMEL_AUTHENC )if (dd->caps.has_authenc) -for (i =0 ; i <ARRAY_SIZE (aes_authenc_algs); i++) -crypto_unregister_aead (&aes_authenc_algs[i]); +crypto_unregister_aeads (aes_authenc_algs, +ARRAY_SIZE (aes_authenc_algs));#endif if (dd->caps.has_xts)
@@ -2214,8 +2212,7 @@ static void atmel_aes_unregister_algs(struct atmel_aes_dev *dd)if (dd->caps.has_gcm)crypto_unregister_aead (&aes_gcm_alg); -for (i =0 ; i <ARRAY_SIZE (aes_algs); i++) -crypto_unregister_skcipher (&aes_algs[i]); +crypto_unregister_skciphers (aes_algs,ARRAY_SIZE (aes_algs)); }static void atmel_aes_crypto_alg_init (struct crypto_alg *alg)
@@ -2228,7 +2225,7 @@ static void atmel_aes_crypto_alg_init(struct crypto_alg *alg)static int atmel_aes_register_algs (struct atmel_aes_dev *dd) { -int err, i, j; +int err, i;for (i =0 ; i <ARRAY_SIZE (aes_algs); i++) {atmel_aes_crypto_alg_init (&aes_algs[i].base);
@@ -2271,8 +2268,7 @@ static int atmel_aes_register_algs(struct atmel_aes_dev *dd)#if IS_ENABLED (CONFIG_CRYPTO_DEV_ATMEL_AUTHENC )/* i = ARRAY_SIZE(aes_authenc_algs); */ err_aes_authenc_alg: -for (j =0 ; j < i; j++) -crypto_unregister_aead (&aes_authenc_algs[j]); +crypto_unregister_aeads (aes_authenc_algs, i);crypto_unregister_skcipher (&aes_xts_alg);#endif err_aes_xts_alg:
@@ -2280,8 +2276,7 @@ static int atmel_aes_register_algs(struct atmel_aes_dev *dd) err_aes_gcm_alg: i =ARRAY_SIZE (aes_algs); err_aes_algs: -for (j =0 ; j < i; j++) -crypto_unregister_skcipher (&aes_algs[j]); +crypto_unregister_skciphers (aes_algs, i);return err; }
drivers/crypto/atmel-sha.c +10 -17
@@ -2416,27 +2416,23 @@ EXPORT_SYMBOL_GPL(atmel_sha_authenc_abort);static void atmel_sha_unregister_algs (struct atmel_sha_dev *dd) { -int i; -if (dd->caps.has_hmac) -for (i =0 ; i <ARRAY_SIZE (sha_hmac_algs); i++) -crypto_unregister_ahash (&sha_hmac_algs[i]); +crypto_unregister_ahashes (sha_hmac_algs, +ARRAY_SIZE (sha_hmac_algs)); -for (i =0 ; i <ARRAY_SIZE (sha_1_256_algs); i++) -crypto_unregister_ahash (&sha_1_256_algs[i]); +crypto_unregister_ahashes (sha_1_256_algs,ARRAY_SIZE (sha_1_256_algs));if (dd->caps.has_sha224)crypto_unregister_ahash (&sha_224_alg); -if (dd->caps.has_sha_384_512) { -for (i =0 ; i <ARRAY_SIZE (sha_384_512_algs); i++) -crypto_unregister_ahash (&sha_384_512_algs[i]); - } +if (dd->caps.has_sha_384_512) +crypto_unregister_ahashes (sha_384_512_algs, +ARRAY_SIZE (sha_384_512_algs)); }static int atmel_sha_register_algs (struct atmel_sha_dev *dd) { -int err, i, j; +int err, i;for (i =0 ; i <ARRAY_SIZE (sha_1_256_algs); i++) {atmel_sha_alg_init (&sha_1_256_algs[i]);
@@ -2478,18 +2474,15 @@ static int atmel_sha_register_algs(struct atmel_sha_dev *dd)/*i = ARRAY_SIZE(sha_hmac_algs);*/ err_sha_hmac_algs: -for (j =0 ; j < i; j++) -crypto_unregister_ahash (&sha_hmac_algs[j]); +crypto_unregister_ahashes (sha_hmac_algs, i); i =ARRAY_SIZE (sha_384_512_algs); err_sha_384_512_algs: -for (j =0 ; j < i; j++) -crypto_unregister_ahash (&sha_384_512_algs[j]); +crypto_unregister_ahashes (sha_384_512_algs, i);crypto_unregister_ahash (&sha_224_alg); err_sha_224_algs: i =ARRAY_SIZE (sha_1_256_algs); err_sha_1_256_algs: -for (j =0 ; j < i; j++) -crypto_unregister_ahash (&sha_1_256_algs[j]); +crypto_unregister_ahashes (sha_1_256_algs, i);return err; }
drivers/crypto/atmel-tdes.c +6 -19
@@ -897,38 +897,25 @@ static irqreturn_t atmel_tdes_irq(int irq, void *dev_id)return IRQ_NONE ; } -static void atmel_tdes_unregister_algs (struct atmel_tdes_dev *dd) -{ -int i; - -for (i =0 ; i <ARRAY_SIZE (tdes_algs); i++) -crypto_unregister_skcipher (&tdes_algs[i]); -} -static int atmel_tdes_register_algs (struct atmel_tdes_dev *dd) { -int err, i, j; +int err, i;for (i =0 ; i <ARRAY_SIZE (tdes_algs); i++) {atmel_tdes_skcipher_alg_init (&tdes_algs[i]); err =crypto_register_skcipher (&tdes_algs[i]); -if (err) - goto err_tdes_algs; +if (err) { +crypto_unregister_skciphers (tdes_algs, i); +return err; + } }return 0 ; - -err_tdes_algs: -for (j =0 ; j < i; j++) -crypto_unregister_skcipher (&tdes_algs[j]); - -return err; }static void atmel_tdes_get_cap (struct atmel_tdes_dev *dd) { - dd->caps.has_dma =0 ;/* keep only major version number */
@@ -1061,7 +1048,7 @@ static void atmel_tdes_remove(struct platform_device *pdev)list_del (&tdes_dd->list);spin_unlock (&atmel_tdes.lock); -atmel_tdes_unregister_algs (tdes_dd); +crypto_unregister_skciphers (tdes_algs,ARRAY_SIZE (tdes_algs));tasklet_kill (&tdes_dd->done_task);tasklet_kill (&tdes_dd->queue_task);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 158/666 crypto: atmel-aes - guard unregister on error in atmel_aes_register_algs
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thorsten Blum <[email protected]>
[ Upstream commit 57a13941c0bb06ae24e3b34672d7b6f2172b253f ]
Ensure the device supports XTS and GCM with 'has_xts' and 'has_gcm' before unregistering algorithms when XTS or authenc registration fails, which would trigger a WARN in crypto_unregister_alg().
Currently, with the capabilities defined in atmel_aes_get_cap(), this bug cannot happen because all devices that support XTS and authenc also support GCM, but the error handling should still be correct regardless of hardware capabilities.
--- drivers/crypto/atmel-aes.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/crypto/atmel-aes.c +4 -2
@@ -2269,10 +2269,12 @@ static int atmel_aes_register_algs(struct atmel_aes_dev *dd)/* i = ARRAY_SIZE(aes_authenc_algs); */ err_aes_authenc_alg:crypto_unregister_aeads (aes_authenc_algs, i); -crypto_unregister_skcipher (&aes_xts_alg); +if (dd->caps.has_xts) +crypto_unregister_skcipher (&aes_xts_alg);#endif err_aes_xts_alg: -crypto_unregister_aead (&aes_gcm_alg); +if (dd->caps.has_gcm) +crypto_unregister_aead (&aes_gcm_alg); err_aes_gcm_alg: i =ARRAY_SIZE (aes_algs); err_aes_algs:
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 159/666 padata: Remove cpu online check from cpu add and removal
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuyi Zhou <[email protected]>
[ Upstream commit 73117ea6470dca787f70f33c001f9faf437a1c0b ]
During the CPU offline process, the dying CPU is cleared from the cpu_online_mask in takedown_cpu(). After this step, various CPUHP_*_DEAD callbacks are executed to perform cleanup jobs for the dead CPU, so this cpu online check in padata_cpu_dead() is unnecessary.
Similarly, when executing padata_cpu_online() during the CPUHP_AP_ONLINE_DYN phase, the CPU has already been set in the cpu_online_mask, the action even occurs earlier than the CPUHP_AP_ONLINE_IDLE stage.
Remove this unnecessary cpu online check in __padata_add_cpu() and __padata_remove_cpu().
Stable-dep-of: c8c4a2972f83 ("padata: Put CPU offline callback in ONLINE section to allow failure")
--- kernel/padata.c | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-)
kernel/padata.c +8 -18
@@ -755,32 +755,22 @@ EXPORT_SYMBOL(padata_set_cpumask);static int __padata_add_cpu (struct padata_instance *pinst,int cpu) { -int err =0 ; - -if (cpumask_test_cpu (cpu, cpu_online_mask)) { - err =padata_replace (pinst); +int err =padata_replace (pinst); -if (padata_validate_cpumask (pinst, pinst->cpumask.pcpu) && -padata_validate_cpumask (pinst, pinst->cpumask.cbcpu)) -__padata_start (pinst); - } +if (padata_validate_cpumask (pinst, pinst->cpumask.pcpu) && +padata_validate_cpumask (pinst, pinst->cpumask.cbcpu)) +__padata_start (pinst);return err; }static int __padata_remove_cpu (struct padata_instance *pinst,int cpu) { -int err =0 ; - -if (!cpumask_test_cpu (cpu, cpu_online_mask)) { -if (!padata_validate_cpumask (pinst, pinst->cpumask.pcpu) || - !padata_validate_cpumask (pinst, pinst->cpumask.cbcpu)) -__padata_stop (pinst); - - err =padata_replace (pinst); - } +if (!padata_validate_cpumask (pinst, pinst->cpumask.pcpu) || + !padata_validate_cpumask (pinst, pinst->cpumask.cbcpu)) +__padata_stop (pinst); -return err; +return padata_replace (pinst); }static inline int pinst_has_cpu (struct padata_instance *pinst,int cpu)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 160/666 padata: Put CPU offline callback in ONLINE section to allow failure
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Jordan <[email protected]>
[ Upstream commit c8c4a2972f83c8b68ff03b43cecdb898939ff851 ]
syzbot reported the following warning:
DEAD callback error for CPU1
WARNING: kernel/cpu.c:1463 at _cpu_down+0x759/0x1020 kernel/cpu.c:1463, CPU#0: syz.0.1960/14614
at commit 4ae12d8bd9a8 ("Merge tag 'kbuild-fixes-7.0-2' of git://git.kernel.org/pub/scm/linux/kernel/git/kbuild/linux")
which tglx traced to padata_cpu_dead() given it's the only
sub-CPUHP_TEARDOWN_CPU callback that returns an error.
Failure isn't allowed in hotplug states before CPUHP_TEARDOWN_CPU so move the CPU offline callback to the ONLINE section where failure is possible.
--- include/linux/cpuhotplug.h | 1 - include/linux/padata.h | 8 +-- kernel/padata.c | 120 +++++++++++++++++++------------------ 3 files changed, 65 insertions(+), 64 deletions(-)
include/linux/cpuhotplug.h +0 -1
@@ -94,7 +94,6 @@ enum cpuhp_state {CPUHP_PCI_XGENE_DEAD ,CPUHP_IOMMU_IOVA_DEAD ,CPUHP_AP_ARM_CACHE_B15_RAC_DEAD , -CPUHP_PADATA_DEAD ,CPUHP_AP_DTPM_CPU_DEAD ,CPUHP_RANDOM_PREPARE , CPUHP_WORKQUEUE_PREP,
include/linux/padata.h +4 -4
@@ -149,23 +149,23 @@ struct padata_mt_job {/** * struct padata_instance - The overall control structure. * -* @cpu_online_node: Linkage for CPU online callback. -* @cpu_dead_node: Linkage for CPU offline callback. +* @cpuhp_node: Linkage for CPU hotplug callbacks. * @parallel_wq: The workqueue used for parallel work. * @serial_wq: The workqueue used for serial work. * @pslist: List of padata_shell objects attached to this instance. * @cpumask: User supplied cpumasks for parallel and serial works. +* @validate_cpumask: Internal cpumask used to validate @cpumask during hotplug. * @kobj: padata instance kernel object. * @lock: padata instance lock. * @flags: padata flags. */ struct padata_instance { -struct hlist_node cpu_online_node; -struct hlist_node cpu_dead_node; +struct hlist_node cpuhp_node;struct workqueue_struct *parallel_wq;struct workqueue_struct *serial_wq;struct list_head pslist;struct padata_cpumask cpumask; +cpumask_var_t validate_cpumask;struct kobject kobj;struct mutex lock;u8 flags;
kernel/padata.c +61 -59
270 lines not on this page · raw message
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 161/666 PCI: dwc: rcar-gen4: Change EPC BAR alignment to 4K as per the documentation
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Koichiro Den <[email protected]>
[ Upstream commit 13f55a7ca773c731a1e645934c1ae48577f48785 ]
R-Car S4 Series (R8A779F[4-7]*) EP controller uses a 4K minimum iATU region size (CX_ATU_MIN_REGION_SIZE = 4K) as per R19UH0161EJ0130 Rev.1.30. Also, the controller itself can only be configured in the range 4 KB to 64 KB, so the current 1 MB alignment requirement is incorrect.
Hence, change the alignment to the min size 4K as per the documentation.
This also fixes needless unusability of BAR4 on this platform when the target address is fixed, such as for doorbell targets.
--- drivers/pci/controller/dwc/pcie-rcar-gen4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/controller/dwc/pcie-rcar-gen4.c +1 -1
@@ -427,7 +427,7 @@ static const struct pci_epc_features rcar_gen4_pcie_epc_features = { .bar[BAR_3] = { .type = BAR_RESERVED, }, .bar[BAR_4] = { .type = BAR_FIXED, .fixed_size = 256 }, .bar[BAR_5] = { .type = BAR_RESERVED, }, - .align = SZ_1M, + .align = SZ_4K, }; static const struct pci_epc_features*
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 162/666 drm/amdgpu/gfx10: look at the right prop for gfx queue priority
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
[ Upstream commit 355d96cdec5c61fd83f7eb54f1a28e38809645d6 ]
Look at hqd_queue_priority rather than hqd_pipe_priority. In practice, it didn't matter as both were always set for kernel queues, but that will change in the future.
Reviewed-by:Jesse Zhang <[email protected]>
--- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +1 -1
@@ -6601,7 +6601,7 @@ static void gfx_v10_0_gfx_mqd_set_priority(struct amdgpu_device *adev,/* set up default queue priority level * 0x0 = low priority, 0x1 = high priority */ -if (prop->hqd_pipe_priority ==AMDGPU_GFX_PIPE_PRIO_HIGH ) +if (prop->hqd_queue_priority ==AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM ) priority =1 ; tmp =RREG32_SOC15 (GC ,0 , mmCP_GFX_HQD_QUEUE_PRIORITY);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 163/666 drm/amdgpu/gfx11: look at the right prop for gfx queue priority
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
[ Upstream commit f9a4e81bcbd04e6f967d851f9fe69d8bb3cc08b3 ]
Look at hqd_queue_priority rather than hqd_pipe_priority. In practice, it didn't matter as both were always set for kernel queues, but that will change in the future.
Reviewed-by:Jesse Zhang <[email protected]>
--- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +1 -1
@@ -3919,7 +3919,7 @@ static void gfx_v11_0_gfx_mqd_set_priority(struct amdgpu_device *adev,/* set up default queue priority level * 0x0 = low priority, 0x1 = high priority */ -if (prop->hqd_pipe_priority ==AMDGPU_GFX_PIPE_PRIO_HIGH ) +if (prop->hqd_queue_priority ==AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM ) priority =1 ; tmp = regCP_GFX_HQD_QUEUE_PRIORITY_DEFAULT;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 164/666 spi: hisi-kunpeng: prevent infinite while() loop in hisi_spi_flush_fifo
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pei Xiao <[email protected]>
[ Upstream commit 9f61daf2c2debe9f5cf4e1a4471e56a89a6fe45a ]
The hisi_spi_flush_fifo()'s inner while loop that lacks any timeout mechanism. Maybe the hardware never becomes empty, the loop will spin forever, causing the CPU to hang.
Fix this by adding a inner_limit based on loops_per_jiffy. The inner loop now exits after approximately one jiffy if the FIFO remains non-empty, logs a ratelimited warning, and breaks out of the outer loop. Additionally, add a cpu_relax() inside the busy loop to improve power efficiency.
--- drivers/spi/spi-hisi-kunpeng.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/spi/spi-hisi-kunpeng.c +11 -1
@@ -196,8 +196,18 @@ static void hisi_spi_flush_fifo(struct hisi_spi *hs)unsigned long limit = loops_per_jiffy <<1 ;do { -while (hisi_spi_rx_not_empty (hs)) +unsigned long inner_limit = loops_per_jiffy; + +while (hisi_spi_rx_not_empty (hs) && --inner_limit) {readl (hs->regs +HISI_SPI_DOUT ); +cpu_relax (); + } + +if (!inner_limit) { +dev_warn_ratelimited (hs->dev,"RX FIFO flush timeout\n" ); +break ; + } + }while (hisi_spi_busy (hs) && limit--); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 165/666 drm/imagination: Switch reset_reason fields from enum to u32
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexandru Dadu <[email protected]>
[ Upstream commit d2f83a6cd598bf413f1acf34153bd1d71023fbab ]
Update the reset_reason fwif structure fields from enum to u32 to remove any ambiguity from the interface (enum is not a fixed size thus is unfit for the purpose of the data type).
--- drivers/gpu/drm/imagination/pvr_rogue_fwif.h | 8 ++++++-- drivers/gpu/drm/imagination/pvr_rogue_fwif_shared.h | 6 +++++- 2 files changed, 11 insertions(+), 3 deletions(-)
drivers/gpu/drm/imagination/pvr_rogue_fwif.h +6 -2
@@ -1347,8 +1347,12 @@ struct rogue_fwif_fwccb_cmd_freelists_reconstruction_data {struct rogue_fwif_fwccb_cmd_context_reset_data {/* Context affected by the reset */ u32 server_common_context_id; -/* Reason for reset */ -enum rogue_context_reset_reason reset_reason; +/* +* Reason for reset +* The valid values for reset_reason are the ones from +* enum rogue_context_reset_reason +*/ +u32 reset_reason;/* Data Master affected by the reset */ u32 dm;/* Job ref running at the time of reset */
drivers/gpu/drm/imagination/pvr_rogue_fwif_shared.h +5 -1
@@ -249,7 +249,11 @@ enum rogue_context_reset_reason { };struct rogue_context_reset_reason_data { -enum rogue_context_reset_reason reset_reason; +/* +* The valid values for reset_reason are the ones from +* enum rogue_context_reset_reason +*/ +u32 reset_reason;u32 reset_ext_job_ref; };
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 166/666 iommu/tegra241-cmdqv: Set supports_cmd op in tegra241_vcmdq_hw_init()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicolin Chen <[email protected]>
[ Upstream commit 803e41f36d227022ab9bbe780c82283fd4713b2e ]
vintf->hyp_own is finalized in tegra241_vintf_hw_init(). On the other hand, tegra241_vcmdq_alloc_smmu_cmdq() is called via an init_structures callback, which is earlier than tegra241_vintf_hw_init().
This results in the supports_cmd op always being set to the guest function, although this doesn't break any functionality nor have some noticeable perf impact since non-invalidation commands are not issued in the perf sensitive context.
Fix this by moving supports_cmd to tegra241_vcmdq_hw_init().
After this change,
- For a guest kernel, this will be a status quo
- For a host kernel, non-invalidation commands will be issued to VCMDQ(s)
--- drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c +4 -3
@@ -387,6 +387,10 @@ static int tegra241_vcmdq_hw_init(struct tegra241_vcmdq *vcmdq)/* Reset VCMDQ */ tegra241_vcmdq_hw_deinit (vcmdq); +/* vintf->hyp_own is a HW state finalized in tegra241_vintf_hw_init() */ +if (!vcmdq->vintf->hyp_own) + vcmdq->cmdq.supports_cmd = tegra241_guest_vcmdq_supports_cmd; +/* Configure and enable VCMDQ */ writeq_relaxed (vcmdq->cmdq.q.q_base,REG_VCMDQ_PAGE1 (vcmdq,BASE ));
@@ -514,9 +518,6 @@ static int tegra241_vcmdq_alloc_smmu_cmdq(struct tegra241_vcmdq *vcmdq) q->q_base = q->base_dma &VCMDQ_ADDR ; q->q_base |=FIELD_PREP (VCMDQ_LOG2SIZE , q->llq.max_n_shift); -if (!vcmdq->vintf->hyp_own) - cmdq->supports_cmd = tegra241_guest_vcmdq_supports_cmd; -return arm_smmu_cmdq_init (smmu, cmdq); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 167/666 drm/msm/dpu: fix mismatch between power and frequency
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuanjie Yang <[email protected]>
[ Upstream commit bc1dccc518cc5ab5140fba06c27e7188e0ed342b ]
During DPU runtime suspend, calling dev_pm_opp_set_rate(dev, 0) drops the MMCX rail to MIN_SVS while the core clock frequency remains at its original (highest) rate. When runtime resume re-enables the clock, this may result in a mismatch between the rail voltage and the clock rate.
For example, in the DPU bind path, the sequence could be:
cpu0: dev_sync_state -> rpmhpd_sync_state
cpu1: dpu_kms_hw_init
timeline 0 ------------------------------------------------> t
After rpmhpd_sync_state, the voltage performance is no longer guaranteed to stay at the highest level. During dpu_kms_hw_init, calling dev_pm_opp_set_rate(dev, 0) drops the voltage, causing the MMCX rail to fall to MIN_SVS while the core clock is still at its maximum frequency. When the power is re-enabled, only the clock is enabled, leading to a situation where the MMCX rail is at MIN_SVS but the core clock is at its highest rate. In this state, the rail cannot sustain the clock rate, which may cause instability or system crash.
Remove the call to dev_pm_opp_set_rate(dev, 0) from dpu_runtime_suspend to ensure the correct vote is restored when DPU resumes.
Patchwork: https://patchwork.freedesktop.org/patch/710077/
--- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 2 -- 1 file changed, 2 deletions(-)
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +0 -2
@@ -1401,8 +1401,6 @@ static int __maybe_unused dpu_runtime_suspend(struct device *dev)struct msm_drm_private *priv =platform_get_drvdata (pdev);struct dpu_kms *dpu_kms =to_dpu_kms (priv->kms); -/* Drop the performance state vote */ -dev_pm_opp_set_rate (dev,0 );clk_bulk_disable_unprepare (dpu_kms->num_clocks, dpu_kms->clocks);for (i =0 ; i < dpu_kms->num_paths; i++)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 168/666 drm/msm/dsi: add the missing parameter description
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengyu Luo <[email protected]>
[ Upstream commit 958adefc4c0fddee3b12269da5dd7cb49bac953f ]
Add a description for is_bonded_dsi in dsi_adjust_pclk_for_compression to match the existing kernel-doc comment.
Patchwork: https://patchwork.freedesktop.org/patch/710112/
--- drivers/gpu/drm/msm/dsi/dsi_host.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/msm/dsi/dsi_host.c +1 -0
@@ -519,6 +519,7 @@ void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host)* dsi_adjust_pclk_for_compression() - Adjust the pclk rate for compression case * @mode: The selected mode for the DSI output * @dsc: DRM DSC configuration for this DSI output +* @is_bonded_dsi: True if two DSI controllers are bonded * * Adjust the pclk rate by calculating a new hdisplay proportional to * the compression ratio such that:
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 169/666 drm/msm/dsi: fix bits_per_pclk
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengyu Luo <[email protected]>
[ Upstream commit 2d51cfb77daa30b10bc68c403f8ace35783d2922 ]
mipi_dsi_pixel_format_to_bpp return dst bpp not src bpp, dst bpp may not be the uncompressed data size. use src bpc * 3 to get src bpp, this aligns with pclk rate calculation.
Patchwork: https://patchwork.freedesktop.org/patch/709916/
--- drivers/gpu/drm/msm/dsi/dsi_host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/msm/dsi/dsi_host.c +1 -1
@@ -999,7 +999,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)*/ h_total -= hdisplay;if (wide_bus_enabled) - bits_per_pclk =mipi_dsi_pixel_format_to_bpp (msm_host->format); + bits_per_pclk = dsc->bits_per_component *3 ;else bits_per_pclk =24 ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 170/666 drm/msm/dsi: fix hdisplay calculation for CMD mode panel
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengyu Luo <[email protected]>
[ Upstream commit 82159db4371f5cef56444ebd0b8f96e2a6d709ff ]
Commit ac47870fd795 ("drm/msm/dsi: fix hdisplay calculation when programming dsi registers") incorrecly broke hdisplay calculation for CMD mode by specifying incorrect number of bytes per transfer, fix it.
Patchwork: https://patchwork.freedesktop.org/patch/709917/
--- drivers/gpu/drm/msm/dsi/dsi_host.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/gpu/drm/msm/dsi/dsi_host.c +10 -5
@@ -985,8 +985,9 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)/* * DPU sends 3 bytes per pclk cycle to DSI. If widebus is * enabled, MDP always sends out 48-bit compressed data per -* pclk and on average, DSI consumes an amount of compressed -* data equivalent to the uncompressed pixel depth per pclk. +* pclk and on average, for video mode, DSI consumes only an +* amount of compressed data equivalent to the uncompressed +* pixel depth per pclk. * * Calculate the number of pclks needed to transmit one line of * the compressed data.
@@ -998,10 +999,14 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)* unused anyway. */ h_total -= hdisplay; -if (wide_bus_enabled) - bits_per_pclk = dsc->bits_per_component *3 ; -else +if (wide_bus_enabled) { +if (msm_host->mode_flags &MIPI_DSI_MODE_VIDEO ) + bits_per_pclk = dsc->bits_per_component *3 ; +else + bits_per_pclk =48 ; + }else { bits_per_pclk =24 ; + } hdisplay =DIV_ROUND_UP (msm_dsc_get_bytes_per_line (msm_host->dsc) *8 , bits_per_pclk);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 171/666 drm/msm/dsi: rename MSM8998 DSI version from V2_2_0 to V2_0_0
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Koskovich <[email protected]>
[ Upstream commit 913a709dea0eff9c7b2e9470f8c8594b9a0114ab ]
The MSM8998 DSI controller is v2.0.0 as stated in commit 7b8c9e203039 ("drm/msm/dsi: Add support for MSM8998 DSI controller"). The value was always correct just the name was wrong.
Rename and reorder to maintain version sorting.
Patchwork: https://patchwork.freedesktop.org/patch/713717/
--- drivers/gpu/drm/msm/dsi/dsi_cfg.c | 4 ++-- drivers/gpu/drm/msm/dsi/dsi_cfg.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
drivers/gpu/drm/msm/dsi/dsi_cfg.c +2 -2
@@ -278,10 +278,10 @@ static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = { &msm8996_dsi_cfg, &msm_dsi_6g_host_ops}, {MSM_DSI_VER_MAJOR_6G ,MSM_DSI_6G_VER_MINOR_V1_4_2 , &msm8976_dsi_cfg, &msm_dsi_6g_host_ops}, + {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_0_0, + &msm8998_dsi_cfg, &msm_dsi_6g_v2_host_ops}, {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_1_0, &sdm660_dsi_cfg, &msm_dsi_6g_v2_host_ops}, - {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_2_0, - &msm8998_dsi_cfg, &msm_dsi_6g_v2_host_ops}, {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_2_1, &sdm845_dsi_cfg, &msm_dsi_6g_v2_host_ops}, {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_3_0,
drivers/gpu/drm/msm/dsi/dsi_cfg.h +1 -1
@@ -19,8 +19,8 @@#define MSM_DSI_6G_VER_MINOR_V1_3_1 0x10030001#define MSM_DSI_6G_VER_MINOR_V1_4_1 0x10040001#define MSM_DSI_6G_VER_MINOR_V1_4_2 0x10040002 +#define MSM_DSI_6G_VER_MINOR_V2_0_0 0x20000000#define MSM_DSI_6G_VER_MINOR_V2_1_0 0x20010000 -#define MSM_DSI_6G_VER_MINOR_V2_2_0 0x20000000#define MSM_DSI_6G_VER_MINOR_V2_2_1 0x20020001#define MSM_DSI_6G_VER_MINOR_V2_3_0 0x20030000#define MSM_DSI_6G_VER_MINOR_V2_4_0 0x20040000
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 172/666 drm/panel: sharp-ls043t1le01: make use of prepare_prev_first
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov <[email protected]>
[ Upstream commit c222177d7c7e1b2e0433d9e47ec2da7015345d50 ]
The DSI link must be powered up to let panel driver to talk to the panel during prepare() callback execution. Set the prepare_prev_first flag to guarantee this.
--- drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c +1 -0
@@ -212,6 +212,7 @@ static int sharp_nt_panel_add(struct sharp_nt_panel *sharp_nt)drm_panel_init (&sharp_nt->base, &sharp_nt->dsi->dev, &sharp_nt_panel_funcs,DRM_MODE_CONNECTOR_DSI ); + sharp_nt->base.prepare_prev_first = true; ret =drm_panel_of_backlight (&sharp_nt->base);if (ret)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 173/666 drm/panel: simple: Correct G190EAN01 prepare timing
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Reichel <[email protected]>
[ Upstream commit f1080f82570b797598c1ba7e9c800ae9e94aafc6 ]
The prepare timing specified by the G190EAN01 datasheet should be between 30 and 50 ms. Considering it might take some time for the LVDS encoder to enable the signal, we should only wait the min. required time in the panel driver and not the max. allowed time.
--- drivers/gpu/drm/panel/panel-simple.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/panel/panel-simple.c +1 -1
@@ -1260,7 +1260,7 @@ static const struct panel_desc auo_g190ean01 = { .height = 301, }, .delay = { - .prepare = 50, + .prepare = 30, .enable = 200, .disable = 110, .unprepare = 1000,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 174/666 PCI: qcom: Advertise Hotplug Slot Capability with no Command Completion support
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krishna Chaitanya Chundru <[email protected]>
[ Upstream commit 33a76fc3c3e61386524479b99f35423bd3d9a895 ]
Qcom PCIe Root Ports advertise hotplug capability in hardware, but do not support hotplug command completion. As a result, the hotplug commands issued by the pciehp driver never gets completion notification, leading to repeated timeout warnings and multi-second delays during boot and suspend/resume.
Commit a54db86ddc153 ("PCI: qcom: Do not advertise hotplug capability for IPs v2.7.0 and v1.9.0") mistakenly assumed that the Root Ports doesn't support Hotplug due to timeouts and disabled the Hotplug functionality altogether. But the Root Ports does support reporting Hotplug events like DL_Up/Down events.
So to fix the command completion timeout issues, just set the No Command Completed Support (NCCS) bit and enable Hotplug in Slot Capability field back.
--- drivers/pci/controller/dwc/pcie-qcom.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
drivers/pci/controller/dwc/pcie-qcom.c +11 -6
@@ -329,15 +329,20 @@ static void qcom_pcie_clear_aspm_l0s(struct dw_pcie *pci)dw_pcie_dbi_ro_wr_dis (pci); } -static void qcom_pcie_clear_hpc (struct dw_pcie *pci) +static void qcom_pcie_set_slot_nccs (struct dw_pcie *pci) {u16 offset =dw_pcie_find_capability (pci,PCI_CAP_ID_EXP );u32 val;dw_pcie_dbi_ro_wr_en (pci); +/* +* Qcom PCIe Root Ports do not support generating command completion +* notifications for the Hot-Plug commands. So set the NCCS field to +* avoid waiting for the completions. +*/ val =readl (pci->dbi_base + offset +PCI_EXP_SLTCAP ); - val &= ~PCI_EXP_SLTCAP_HPC ; + val |=PCI_EXP_SLTCAP_NCCS ;writel (val, pci->dbi_base + offset +PCI_EXP_SLTCAP );dw_pcie_dbi_ro_wr_dis (pci);
@@ -532,7 +537,7 @@ static int qcom_pcie_post_init_2_1_0(struct qcom_pcie *pcie)writel (CFG_BRIDGE_SB_INIT , pci->dbi_base +AXI_MSTR_RESP_COMP_CTRL1 ); -qcom_pcie_clear_hpc (pcie->pci); +qcom_pcie_set_slot_nccs (pcie->pci);return 0 ; }
@@ -612,7 +617,7 @@ static int qcom_pcie_post_init_1_0_0(struct qcom_pcie *pcie)writel (val, pcie->parf +PARF_AXI_MSTR_WR_ADDR_HALT ); } -qcom_pcie_clear_hpc (pcie->pci); +qcom_pcie_set_slot_nccs (pcie->pci);return 0 ; }
@@ -705,7 +710,7 @@ static int qcom_pcie_post_init_2_3_2(struct qcom_pcie *pcie) val |=EN ;writel (val, pcie->parf +PARF_AXI_MSTR_WR_ADDR_HALT_V2 ); -qcom_pcie_clear_hpc (pcie->pci); +qcom_pcie_set_slot_nccs (pcie->pci);return 0 ; }
@@ -1009,7 +1014,7 @@ static int qcom_pcie_post_init_2_7_0(struct qcom_pcie *pcie)writel (WR_NO_SNOOP_OVERIDE_EN |RD_NO_SNOOP_OVERIDE_EN , pcie->parf +PARF_NO_SNOOP_OVERIDE ); -qcom_pcie_clear_hpc (pcie->pci); +qcom_pcie_set_slot_nccs (pcie->pci);return 0 ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 175/666 ALSA: core: Validate compress device numbers without dynamic minors
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cássio Gabriel <[email protected]>
[ Upstream commit 796e119e9b14763be905ad0d023c71a14bc2e931 ]
Without CONFIG_SND_DYNAMIC_MINORS, ALSA reserves only two fixed minors for compress devices on each card: comprD0 and comprD1.
snd_find_free_minor() currently computes the compress minor as type + dev without validating dev first, so device numbers greater than 1 spill into the HWDEP minor range instead of failing registration.
ASoC passes rtd->id to snd_compress_new(), so this can happen on real non-dynamic-minor builds.
Add a dedicated fixed-minor check for SNDRV_DEVICE_TYPE_COMPRESS in snd_find_free_minor() and reject out-of-range device numbers with -EINVAL before constructing the minor.
Also remove the stale TODO in compress_offload.c that still claims multiple compress nodes are missing.
--- sound/core/compress_offload.c | 7 ------- sound/core/sound.c | 7 +++++++ 2 files changed, 7 insertions(+), 7 deletions(-)
sound/core/compress_offload.c +0 -7
@@ -40,13 +40,6 @@#define COMPR_CODEC_CAPS_OVERFLOW #endif -/* TODO: -* - add substream support for multiple devices in case of -* SND_DYNAMIC_MINORS is not used -* - Multiple node representation -* driver should be able to register multiple nodes -*/ -struct snd_compr_file {unsigned long caps;struct snd_compr_stream stream;
sound/core/sound.c +7 -0
@@ -216,9 +216,16 @@ static int snd_find_free_minor(int type, struct snd_card *card, int dev)case SNDRV_DEVICE_TYPE_RAWMIDI :case SNDRV_DEVICE_TYPE_PCM_PLAYBACK :case SNDRV_DEVICE_TYPE_PCM_CAPTURE : +if (snd_BUG_ON (!card)) +return -EINVAL ; + minor =SNDRV_MINOR (card->number, type + dev); +break ;case SNDRV_DEVICE_TYPE_COMPRESS :if (snd_BUG_ON (!card))return -EINVAL ; +if (dev <0 || + dev >=SNDRV_MINOR_HWDEP -SNDRV_MINOR_COMPRESS ) +return -EINVAL ; minor =SNDRV_MINOR (card->number, type + dev);break ;default :
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 176/666 drm/amd/pm/ci: Use highest MCLK on CI when MCLK DPM is disabled
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
[ Upstream commit 894f0d34d66cb47fe718fe2ae5c18729d22c5218 ]
When MCLK DPM is disabled for any reason, populate the MCLK table with the highest MCLK DPM level, so that the ASIC can use the highest possible memory clock to get good performance even when MCLK DPM is disabled.
--- drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c +8 -0
@@ -1322,6 +1322,14 @@ static int ci_populate_all_memory_levels(struct pp_hwmgr *hwmgr)return result; } +if (data->mclk_dpm_key_disabled && dpm_table->mclk_table.count) { +/* Populate the table with the highest MCLK level when MCLK DPM is disabled */ +for (i =0 ; i < dpm_table->mclk_table.count -1 ; i++) { + levels[i] = levels[dpm_table->mclk_table.count -1 ]; + levels[i].DisplayWatermark =PPSMC_DISPLAY_WATERMARK_HIGH ; + } + } + smu_data->smc_state_table.MemoryLevel[0 ].EnabledForActivity =1 ; dev_id = adev->pdev->device;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 177/666 drm/amd/pm/ci: Disable MCLK DPM on problematic CI ASICs
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
[ Upstream commit 9851f29cb06c09f7dad3867d8b0feec3fc71b6c8 ]
There are two known cases where MCLK DPM can causes issues:
Radeon R9 M380 found in iMac computers from 2015. The SMU in this GPU just hangs as soon as we send it the PPSMC_MSG_MCLKDPM_Enable command, even when MCLK switching is disabled, and even when we only populate one MCLK DPM level. Apply workaround to all devices with the same subsystem ID.
Radeon R7 260X due to old memory controller microcode. We only flash the MC ucode when it isn't set up by the VBIOS, therefore there is no way to make sure that it has the correct ucode version.
I verified that this patch fixes the SMU hang on the R9 M380 which would previously fail to boot. This also fixes the UVD initialization error on that GPU which happened because the SMU couldn't ungate the UVD after it hung.
--- drivers/gpu/drm/amd/pm/powerplay/hwmgr/hwmgr.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
drivers/gpu/drm/amd/pm/powerplay/hwmgr/hwmgr.c +15 -0
@@ -104,6 +104,21 @@ int hwmgr_early_init(struct pp_hwmgr *hwmgr) PP_GFXOFF_MASK); hwmgr->pp_table_version =PP_TABLE_V0 ; hwmgr->od_enabled = false; +switch (hwmgr->chip_id) { +case CHIP_BONAIRE : +/* R9 M380 in iMac 2015: SMU hangs when enabling MCLK DPM +* R7 260X cards with old MC ucode: MCLK DPM is unstable +*/ +if (adev->pdev->subsystem_vendor ==0x106B || + adev->pdev->device ==0x6658 ) { +dev_info (adev->dev,"disabling MCLK DPM on quirky ASIC" ); + adev->pm.pp_feature &= ~PP_MCLK_DPM_MASK ; + hwmgr->feature_mask &= ~PP_MCLK_DPM_MASK ; + } +break ; +default : +break ; + }smu7_init_function_pointers (hwmgr);break ;case AMDGPU_FAMILY_CZ :
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 178/666 drm/amd/pm/smu7: Fix SMU7 voltage dependency on display clock
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
[ Upstream commit 0138610c14130425be53423b35336561829965e0 ]
The DCE (display controller engine) requires a minimum voltage in order to function correctly, depending on which clock level it currently uses.
Add a new table that contains display clock frequency levels and the corresponding required voltages. The clock frequency levels are taken from DC (and the old radeon driver's voltage dependency table for CI in cases where its values were lower). The voltage levels are taken from the following function:phm_initializa_dynamic_state_adjustment_rule_settings(). Furthermore, in case of CI, call smu7_patch_vddc() on the new table to account for leakage voltage (like in radeon).
Use the display clock value from amd_pp_display_configuration to look up the voltage level needed by the DCE. Send the voltage to the SMU via the PPSMC_MSG_VddC_Request command.
The previous implementation of this feature was non-functional because it relied on a "dal_power_level" field which was never assigned; and it was not at all implemented for CI ASICs.
I verified this on a Radeon R9 M380 which previously booted to a black screen with DC enabled (default since Linux 6.19), but now works correctly.
--- .../drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c | 88 ++++++++++++++++++- drivers/gpu/drm/amd/pm/powerplay/inc/hwmgr.h | 1 + 2 files changed, 86 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +85 -3
@@ -2802,6 +2802,10 @@ static int smu7_patch_dependency_tables_with_leakage(struct pp_hwmgr *hwmgr)if (tmp)return -EINVAL ; + tmp =smu7_patch_vddc (hwmgr, hwmgr->dyn_state.vddc_dependency_on_display_clock); +if (tmp) +return -EINVAL ; + tmp =smu7_patch_vce_vddc (hwmgr, hwmgr->dyn_state.vce_clock_voltage_dependency_table);if (tmp)return -EINVAL ;
@@ -2885,6 +2889,8 @@ static int smu7_hwmgr_backend_fini(struct pp_hwmgr *hwmgr) {kfree (hwmgr->dyn_state.vddc_dep_on_dal_pwrl); hwmgr->dyn_state.vddc_dep_on_dal_pwrl =NULL ; +kfree (hwmgr->dyn_state.vddc_dependency_on_display_clock); + hwmgr->dyn_state.vddc_dependency_on_display_clock =NULL ;kfree (hwmgr->backend); hwmgr->backend =NULL ;
@@ -2955,6 +2961,51 @@ static int smu7_update_edc_leakage_table(struct pp_hwmgr *hwmgr)return ret; } +static int smu7_init_voltage_dependency_on_display_clock_table (struct pp_hwmgr *hwmgr) +{ +struct phm_clock_voltage_dependency_table *table; + +if (!amdgpu_device_ip_get_ip_block (hwmgr->adev,AMD_IP_BLOCK_TYPE_DCE )) +return 0 ; + + table =kzalloc (struct_size (table, entries,4 ),GFP_KERNEL ); +if (!table) +return -ENOMEM ; + +if (hwmgr->chip_id >=CHIP_POLARIS10 ) { + table->entries[0 ].clk =38918 ; + table->entries[1 ].clk =45900 ; + table->entries[2 ].clk =66700 ; + table->entries[3 ].clk =113200 ; + + table->entries[0 ].v =700 ; + table->entries[1 ].v =740 ; + table->entries[2 ].v =800 ; + table->entries[3 ].v =900 ; + }else { +if (hwmgr->chip_family ==AMDGPU_FAMILY_CZ ) { + table->entries[0 ].clk =35200 ; + table->entries[1 ].clk =35200 ; + table->entries[2 ].clk =46700 ; + table->entries[3 ].clk =64300 ; + }else { + table->entries[0 ].clk =0 ; + table->entries[1 ].clk =35200 ; + table->entries[2 ].clk =54000 ; + table->entries[3 ].clk =62500 ; + } + + table->entries[0 ].v =0 ; + table->entries[1 ].v =720 ; + table->entries[2 ].v =810 ; + table->entries[3 ].v =900 ; + } + + table->count =4 ; + hwmgr->dyn_state.vddc_dependency_on_display_clock = table; +return 0 ; +} +static int smu7_hwmgr_backend_init (struct pp_hwmgr *hwmgr) {struct amdgpu_device *adev = hwmgr->adev;
@@ -2983,6 +3034,10 @@ static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr)smu7_get_elb_voltages (hwmgr); } + result =smu7_init_voltage_dependency_on_display_clock_table (hwmgr); +if (result) + goto fail; +if (hwmgr->pp_table_version ==PP_TABLE_V1 ) {smu7_complete_dependency_tables (hwmgr);smu7_set_private_data_based_on_pptable_v1 (hwmgr);
@@ -3079,13 +3134,40 @@ static int smu7_force_dpm_highest(struct pp_hwmgr *hwmgr)return 0 ; } +static uint32_t smu7_lookup_vddc_from_dispclk (struct pp_hwmgr *hwmgr) +{ +const struct amd_pp_display_configuration *cfg = hwmgr->display_config; +const struct phm_clock_voltage_dependency_table *vddc_dep_on_dispclk = + hwmgr->dyn_state.vddc_dependency_on_display_clock; +uint32_t i; + +if (!vddc_dep_on_dispclk || !vddc_dep_on_dispclk->count || + !cfg || !cfg->num_display || !cfg->display_clk) +return 0 ; + +/* Start from 1 because ClocksStateUltraLow should not be used according to DC. */ +for (i =1 ; i < vddc_dep_on_dispclk->count; ++i) +if (vddc_dep_on_dispclk->entries[i].clk >= cfg->display_clk) +return vddc_dep_on_dispclk->entries[i].v; + +return vddc_dep_on_dispclk->entries[vddc_dep_on_dispclk->count -1 ].v; +} + +static void smu7_apply_minimum_dce_voltage_request (struct pp_hwmgr *hwmgr) +{ +uint32_t req_vddc =smu7_lookup_vddc_from_dispclk (hwmgr); + +smum_send_msg_to_smc_with_parameter (hwmgr, + PPSMC_MSG_VddC_Request, + req_vddc *VOLTAGE_SCALE , +NULL ); +} +static int smu7_upload_dpm_level_enable_mask (struct pp_hwmgr *hwmgr) {struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); -if (hwmgr->pp_table_version ==PP_TABLE_V1 ) -phm_apply_dal_min_voltage_request (hwmgr); -/* TO DO for v0 iceland and Ci*/ +smu7_apply_minimum_dce_voltage_request (hwmgr);if (!data->sclk_dpm_key_disabled) {if (data->dpm_level_enable_mask.sclk_dpm_enable_mask)
drivers/gpu/drm/amd/pm/powerplay/inc/hwmgr.h +1 -0
@@ -632,6 +632,7 @@ struct phm_dynamic_state_info {struct phm_clock_voltage_dependency_table *vddci_dependency_on_mclk;struct phm_clock_voltage_dependency_table *vddc_dependency_on_mclk;struct phm_clock_voltage_dependency_table *mvdd_dependency_on_mclk; +struct phm_clock_voltage_dependency_table *vddc_dependency_on_display_clock;struct phm_clock_voltage_dependency_table *vddc_dep_on_dal_pwrl;struct phm_clock_array *valid_sclk_values;struct phm_clock_array *valid_mclk_values;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 179/666 drm/amd/pm/ci: Fix powertune defaults for Hawaii 0x67B0
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
[ Upstream commit d784759c07924280f3c313f205fc48eb62d7cb71 ]
There is no AMD GPU with the ID 0x66B0, this looks like a typo. It should be 0x67B0 which is actually part of the PCI ID list, and should use the Hawaii XT powertune defaults according to the old radeon driver.
--- drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c +1 -1
@@ -245,7 +245,7 @@ static void ci_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr) smu_data->power_tune_defaults = &defaults_hawaii_pro;break ;case 0x67B8 : -case 0x66B0 : +case 0x67B0 : smu_data->power_tune_defaults = &defaults_hawaii_xt;break ;case 0x6640 :
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 180/666 drm/amd/pm/ci: Clear EnabledForActivity field for memory levels
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
[ Upstream commit 5facfd4c4c67e8500116ffec0d9da35d92b9c787 ]
Follow what radeon did and what amdgpu does for other GPUs with SMU7.
--- drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c +1 -1
@@ -1217,7 +1217,7 @@ static int ci_populate_single_memory_level( } memory_level->EnabledForThrottle =1 ; - memory_level->EnabledForActivity =1 ; + memory_level->EnabledForActivity =0 ; memory_level->UpH = data->current_profile_setting.mclk_up_hyst; memory_level->DownH = data->current_profile_setting.mclk_down_hyst; memory_level->VoltageDownH =0 ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 181/666 drm/amd/pm/ci: Fill DW8 fields from SMC
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
[ Upstream commit baf28ec5795c077406d6f52b8ad39e614153bce6 ]
In ci_populate_dw8() we currently just read a value from the SMU and then throw it away. Instead of throwing away the value, we should use it to fill other fields in DW8 (like radeon).
Otherwise the value of the other fiels is just cleared when we copy this data to the SMU later.
--- drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c +1 -2
@@ -543,12 +543,11 @@ static int ci_populate_dw8(struct pp_hwmgr *hwmgr, uint32_t fuse_table_offset) {struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend);const struct ci_pt_defaults *defaults = smu_data->power_tune_defaults; -uint32_t temp;if (ci_read_smc_sram_dword (hwmgr, fuse_table_offset + offsetof(SMU7_Discrete_PmFuses , TdcWaterfallCtl), - (uint32_t *)&temp,SMC_RAM_END )) + (uint32_t *)&smu_data->power_tune_table.TdcWaterfallCtl,SMC_RAM_END ))PP_ASSERT_WITH_CODE (false,"Attempt to read PmFuses.DW6 (SviLoadLineEn) from SMC Failed!" , return -EINVAL );
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 182/666 drm/amd/pm/smu7: Add SCLK cap for quirky Hawaii board
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
[ Upstream commit 4724bc5b8d78c34b993594f9406135408ccb312a ]
On a specific Radeon R9 390X board, the GPU can "randomly" hang while gaming. Initially I thought this was a RADV bug and tried to work around this in Mesa:
commit 8ea08747b86b ("radv: Mitigate GPU hang on Hawaii in Dota 2 and RotTR")
However, I got some feedback from other users who are reporting that the above mitigation causes a significant performance regression for them, and they didn't experience the hang on their GPU in the first place.
After some further investigation, it turns out that the problem is that the highest SCLK DPM level on this board isn't stable. Lowering SCLK to 1040 MHz (from 1070 MHz) works around the issue, and has a negligible impact on performance compared to the Mesa patch. (Note that increasing the voltage can also work around it, but we felt that lowering the SCLK is the safer option.)
To solve the above issue, add an "sclk_cap" field to smu7_hwmgr and set this field for the affected board. The capped SCLK value correctly appears on the sysfs interface and shows up in GUI tools such as LACT.
--- .../drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c | 30 ++++++++++++++++--- .../drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.h | 1 + 2 files changed, 27 insertions(+), 4 deletions(-)
drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +26 -4
@@ -787,7 +787,7 @@ static int smu7_setup_dpm_tables_v0(struct pp_hwmgr *hwmgr) hwmgr->dyn_state.vddc_dependency_on_mclk;struct phm_cac_leakage_table *std_voltage_table = hwmgr->dyn_state.cac_leakage_table; -uint32_t i; +uint32_t i, clk;PP_ASSERT_WITH_CODE (allowed_vdd_sclk_table !=NULL ,"SCLK dependency table is missing. This table is mandatory" , return -EINVAL );
@@ -804,10 +804,12 @@ static int smu7_setup_dpm_tables_v0(struct pp_hwmgr *hwmgr) data->dpm_table.sclk_table.count =0 ;for (i =0 ; i < allowed_vdd_sclk_table->count; i++) { + clk =min (allowed_vdd_sclk_table->entries[i].clk, data->sclk_cap); +if (i ==0 || data->dpm_table.sclk_table.dpm_levels[data->dpm_table.sclk_table.count-1 ].value != - allowed_vdd_sclk_table->entries[i].clk) { + clk) { data->dpm_table.sclk_table.dpm_levels[data->dpm_table.sclk_table.count].value = - allowed_vdd_sclk_table->entries[i].clk; + clk; data->dpm_table.sclk_table.dpm_levels[data->dpm_table.sclk_table.count].enabled = (i ==0 ) ?1 :0 ; data->dpm_table.sclk_table.count++; }
@@ -3006,6 +3008,25 @@ static int smu7_init_voltage_dependency_on_display_clock_table(struct pp_hwmgr *return 0 ; } +static void smu7_set_sclk_cap (struct pp_hwmgr *hwmgr) +{ +struct amdgpu_device *adev = hwmgr->adev; +struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + data->sclk_cap =0xffffffff ; + +if (hwmgr->od_enabled) +return ; + +/* R9 390X board: last sclk dpm level is unstable, use lower sclk */ +if (adev->pdev->device ==0x67B0 && + adev->pdev->subsystem_vendor ==0x1043 ) + data->sclk_cap =104000 ;/* 1040 MHz */ + +if (data->sclk_cap !=0xffffffff ) +dev_info (adev->dev,"sclk cap: %u kHz on quirky ASIC\n" , data->sclk_cap *10 ); +} +static int smu7_hwmgr_backend_init (struct pp_hwmgr *hwmgr) {struct amdgpu_device *adev = hwmgr->adev;
@@ -3017,6 +3038,7 @@ static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr)return -ENOMEM ; hwmgr->backend = data; +smu7_set_sclk_cap (hwmgr);smu7_patch_voltage_workaround (hwmgr);smu7_init_dpm_defaults (hwmgr);
@@ -3903,7 +3925,7 @@ static int smu7_get_pp_table_entry_callback_func_v0(struct pp_hwmgr *hwmgr,/* Performance levels are arranged from low to high. */ performance_level->memory_clock = memory_clock; - performance_level->engine_clock = engine_clock; + performance_level->engine_clock =min (engine_clock, data->sclk_cap); pcie_gen_from_bios = visland_clk_info->ucPCIEGen;
drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.h +1 -0
@@ -234,6 +234,7 @@ struct smu7_hwmgr {uint32_t pcie_gen_cap;uint32_t pcie_lane_cap;uint32_t pcie_spc_cap; +uint32_t sclk_cap;struct smu7_leakage_voltage vddc_leakage;struct smu7_leakage_voltage vddci_leakage;struct smu7_leakage_voltage vddcgfx_leakage;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 183/666 drm/amdgpu: add amdgpu_device reference in ip block
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sunil Khatri <[email protected]>
[ Upstream commit 37b993225d37744f2a62bf67074a76a6cb7b8b98 ]
To handle amdgpu_device reference for different GPUs we add it's reference in each ip block which can be used to differentiate between difference gpu devices.
Stable-dep-of: 8b3e8fa6d7bd ("drm/amdgpu/uvd4.2: Don't initialize UVD 4.2 when DPM is disabled")
--- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 ++ 2 files changed, 3 insertions(+)
drivers/gpu/drm/amd/amdgpu/amdgpu.h +1 -0
@@ -388,6 +388,7 @@ struct amdgpu_ip_block_version {struct amdgpu_ip_block {struct amdgpu_ip_block_status status;const struct amdgpu_ip_block_version *version; +struct amdgpu_device *adev; }; int amdgpu_device_ip_block_version_cmp(struct amdgpu_device *adev,
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +2 -0
@@ -2336,6 +2336,8 @@ int amdgpu_device_ip_block_add(struct amdgpu_device *adev,DRM_INFO ("add ip block number %d <%s>\n" , adev->num_ip_blocks, ip_block_version->funcs->name); + adev->ip_blocks[adev->num_ip_blocks].adev = adev; + adev->ip_blocks[adev->num_ip_blocks++].version = ip_block_version;return 0 ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 184/666 drm/amdgpu: update the handle ptr in dump_ip_state
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sunil Khatri <[email protected]>
[ Upstream commit fa73462dc0482644416c2a2ee042c11d93a89663 ]
Update the ptr handle to amdgpu_ip_block ptr in all the functions.
Stable-dep-of: 8b3e8fa6d7bd ("drm/amdgpu/uvd4.2: Don't initialize UVD 4.2 when DPM is disabled")
--- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 2 +- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c | 4 ++-- drivers/gpu/drm/amd/include/amd_shared.h | 4 +++- 22 files changed, 43 insertions(+), 41 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +1 -1
@@ -5466,7 +5466,7 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,for (i =0 ; i < tmp_adev->num_ip_blocks; i++)if (tmp_adev->ip_blocks[i].version->funcs->dump_ip_state) tmp_adev->ip_blocks[i].version->funcs - ->dump_ip_state ((void *)tmp_adev); + ->dump_ip_state ((void *)&tmp_adev->ip_blocks[i]);dev_info (tmp_adev->dev,"Dumping IP State Completed\n" ); }
drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +1 -1
@@ -42,7 +42,7 @@ static void amdgpu_job_do_core_dump(struct amdgpu_device *adev,for (i =0 ; i < adev->num_ip_blocks; i++)if (adev->ip_blocks[i].version->funcs->dump_ip_state) adev->ip_blocks[i].version->funcs - ->dump_ip_state ((void *)adev); + ->dump_ip_state ((void *)&adev->ip_blocks[i]);dev_info (adev->dev,"Dumping IP State Completed\n" );amdgpu_coredump (adev, true, false, job);
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +2 -2
@@ -9630,9 +9630,9 @@ static void gfx_v10_ip_print(void *handle, struct drm_printer *p) } } -static void gfx_v10_ip_dump (void *handle) +static void gfx_v10_ip_dump (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;uint32_t i, j, k, reg, index =0 ;uint32_t reg_count =ARRAY_SIZE (gc_reg_list_10_1);
drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +2 -2
@@ -6746,9 +6746,9 @@ static void gfx_v11_ip_print(void *handle, struct drm_printer *p) } } -static void gfx_v11_ip_dump (void *handle) +static void gfx_v11_ip_dump (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;uint32_t i, j, k, reg, index =0 ;uint32_t reg_count =ARRAY_SIZE (gc_reg_list_11_0);
drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c +2 -2
@@ -5096,9 +5096,9 @@ static void gfx_v12_ip_print(void *handle, struct drm_printer *p) } } -static void gfx_v12_ip_dump (void *handle) +static void gfx_v12_ip_dump (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;uint32_t i, j, k, reg, index =0 ;uint32_t reg_count =ARRAY_SIZE (gc_reg_list_12_0);
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +2 -2
@@ -7364,9 +7364,9 @@ static void gfx_v9_ip_print(void *handle, struct drm_printer *p) } -static void gfx_v9_ip_dump (void *handle) +static void gfx_v9_ip_dump (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;uint32_t i, j, k, reg, index =0 ;uint32_t reg_count =ARRAY_SIZE (gc_reg_list_9);
drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c +2 -2
@@ -4644,9 +4644,9 @@ static void gfx_v9_4_3_ip_print(void *handle, struct drm_printer *p) } } -static void gfx_v9_4_3_ip_dump (void *handle) +static void gfx_v9_4_3_ip_dump (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;uint32_t i, j, k;uint32_t num_xcc, reg, num_inst;uint32_t xcc_id, xcc_offset, inst_offset;
drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +2 -2
@@ -2371,9 +2371,9 @@ static void sdma_v4_0_print_ip_state(void *handle, struct drm_printer *p) } } -static void sdma_v4_0_dump_ip_state (void *handle) +static void sdma_v4_0_dump_ip_state (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int i, j;uint32_t instance_offset;uint32_t reg_count =ARRAY_SIZE (sdma_reg_list_4_0);
drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c +2 -2
@@ -1884,9 +1884,9 @@ static void sdma_v4_4_2_print_ip_state(void *handle, struct drm_printer *p) } } -static void sdma_v4_4_2_dump_ip_state (void *handle) +static void sdma_v4_4_2_dump_ip_state (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int i, j;uint32_t instance_offset;uint32_t reg_count =ARRAY_SIZE (sdma_reg_list_4_4_2);
drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c +2 -2
@@ -1799,9 +1799,9 @@ static void sdma_v5_0_print_ip_state(void *handle, struct drm_printer *p) } } -static void sdma_v5_0_dump_ip_state (void *handle) +static void sdma_v5_0_dump_ip_state (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int i, j;uint32_t instance_offset;uint32_t reg_count =ARRAY_SIZE (sdma_reg_list_5_0);
drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c +2 -2
@@ -1757,9 +1757,9 @@ static void sdma_v5_2_print_ip_state(void *handle, struct drm_printer *p) } } -static void sdma_v5_2_dump_ip_state (void *handle) +static void sdma_v5_2_dump_ip_state (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int i, j;uint32_t instance_offset;uint32_t reg_count =ARRAY_SIZE (sdma_reg_list_5_2);
drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c +2 -2
@@ -1577,9 +1577,9 @@ static void sdma_v6_0_print_ip_state(void *handle, struct drm_printer *p) } } -static void sdma_v6_0_dump_ip_state (void *handle) +static void sdma_v6_0_dump_ip_state (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int i, j;uint32_t instance_offset;uint32_t reg_count =ARRAY_SIZE (sdma_reg_list_6_0);
drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c +2 -2
@@ -1565,9 +1565,9 @@ static void sdma_v7_0_print_ip_state(void *handle, struct drm_printer *p) } } -static void sdma_v7_0_dump_ip_state (void *handle) +static void sdma_v7_0_dump_ip_state (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int i, j;uint32_t instance_offset;uint32_t reg_count =ARRAY_SIZE (sdma_reg_list_7_0);
drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +2 -2
@@ -1957,9 +1957,9 @@ static void vcn_v1_0_print_ip_state(void *handle, struct drm_printer *p) } } -static void vcn_v1_0_dump_ip_state (void *handle) +static void vcn_v1_0_dump_ip_state (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int i, j;bool is_powered;uint32_t inst_off;
drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c +2 -2
@@ -2074,9 +2074,9 @@ static void vcn_v2_0_print_ip_state(void *handle, struct drm_printer *p) } } -static void vcn_v2_0_dump_ip_state (void *handle) +static void vcn_v2_0_dump_ip_state (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int i, j;bool is_powered;uint32_t inst_off;
drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c +2 -2
@@ -1965,9 +1965,9 @@ static void vcn_v2_5_print_ip_state(void *handle, struct drm_printer *p) } } -static void vcn_v2_5_dump_ip_state (void *handle) +static void vcn_v2_5_dump_ip_state (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int i, j;bool is_powered;uint32_t inst_off;
drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c +2 -2
@@ -2312,9 +2312,9 @@ static void vcn_v3_0_print_ip_state(void *handle, struct drm_printer *p) } } -static void vcn_v3_0_dump_ip_state (void *handle) +static void vcn_v3_0_dump_ip_state (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int i, j;bool is_powered;uint32_t inst_off;
drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c +2 -2
@@ -2210,9 +2210,9 @@ static void vcn_v4_0_print_ip_state(void *handle, struct drm_printer *p) } } -static void vcn_v4_0_dump_ip_state (void *handle) +static void vcn_v4_0_dump_ip_state (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int i, j;bool is_powered;uint32_t inst_off;
drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c +2 -2
@@ -1787,9 +1787,9 @@ static void vcn_v4_0_3_print_ip_state(void *handle, struct drm_printer *p) } } -static void vcn_v4_0_3_dump_ip_state (void *handle) +static void vcn_v4_0_3_dump_ip_state (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int i, j;bool is_powered;uint32_t inst_off, inst_id;
drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c +2 -2
@@ -1663,9 +1663,9 @@ static void vcn_v4_0_5_print_ip_state(void *handle, struct drm_printer *p) } } -static void vcn_v4_0_5_dump_ip_state (void *handle) +static void vcn_v4_0_5_dump_ip_state (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int i, j;bool is_powered;uint32_t inst_off;
drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c +2 -2
@@ -1386,9 +1386,9 @@ static void vcn_v5_0_print_ip_state(void *handle, struct drm_printer *p) } } -static void vcn_v5_0_dump_ip_state (void *handle) +static void vcn_v5_0_dump_ip_state (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int i, j;bool is_powered;uint32_t inst_off;
drivers/gpu/drm/amd/include/amd_shared.h +3 -1
@@ -375,6 +375,8 @@ enum amd_dpm_forced_level;* making calls to hooks from each IP block. This list is ordered to ensure * that the driver initializes the IP blocks in a safe sequence. */ +struct amdgpu_ip_block ; +struct amd_ip_funcs {char *name;int (*early_init)(void *handle);
@@ -399,7 +401,7 @@ struct amd_ip_funcs {int (*set_powergating_state)(void *handle,enum amd_powergating_state state);void (*get_clockgating_state)(void *handle,u64 *flags); -void (*dump_ip_state)(void *handle); +void (*dump_ip_state)(struct amdgpu_ip_block *ip_block);void (*print_ip_state)(void *handle,struct drm_printer *p); };
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 185/666 drm/amdgpu: update the handle ptr in early_init
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sunil Khatri <[email protected]>
[ Upstream commit 146b085eadd2ce405e67492a80d6e767748d5642 ]
update the handle ptr to amdgpu_ip_block ptr
for all functions pointers on early_init.
Stable-dep-of: 8b3e8fa6d7bd ("drm/amdgpu/uvd4.2: Don't initialize UVD 4.2 when DPM is disabled")
--- drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 24 +++++++++---------- drivers/gpu/drm/amd/amdgpu/amdgpu_isp.c | 5 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/cik.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/cik_ih.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/cik_sdma.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/cz_ih.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/dce_v6_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/ih_v6_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/ih_v6_1.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/ih_v7_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.h | 2 +- drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/mes_v11_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/mes_v12_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/navi10_ih.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/nv.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/si.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/si_dma.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/si_ih.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/soc15.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/soc21.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/soc24.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/uvd_v3_1.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/vce_v2_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/vce_v4_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 6 ++--- drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/vega20_ih.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/vi.c | 4 ++-- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 ++--- drivers/gpu/drm/amd/include/amd_shared.h | 2 +- drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c | 4 ++-- drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c | 4 ++-- .../gpu/drm/amd/pm/powerplay/amd_powerplay.c | 5 ++-- drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 4 ++-- 86 files changed, 182 insertions(+), 182 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c +1 -1
@@ -585,7 +585,7 @@ static int acp_resume(void *handle)return 0 ; } -static int acp_early_init (void *handle) +static int acp_early_init (struct amdgpu_ip_block *ip_block) {return 0 ; }
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +12 -12
@@ -2639,25 +2639,25 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev) total = true;for (i =0 ; i < adev->num_ip_blocks; i++) { + ip_block = &adev->ip_blocks[i]; +if ((amdgpu_ip_block_mask & (1 << i)) ==0 ) {DRM_WARN ("disabled ip block: %d <%s>\n" , i, adev->ip_blocks[i].version->funcs->name); adev->ip_blocks[i].status.valid = false; - }else { -if (adev->ip_blocks[i].version->funcs->early_init) { - r = adev->ip_blocks[i].version->funcs->early_init ((void *)adev); -if (r == -ENOENT ) { - adev->ip_blocks[i].status.valid = false; - }else if (r) { -DRM_ERROR ("early_init of IP block <%s> failed %d\n" , - adev->ip_blocks[i].version->funcs->name, r); - total = false; - }else { - adev->ip_blocks[i].status.valid = true; - } + }else if (ip_block->version->funcs->early_init) { + r = ip_block->version->funcs->early_init (ip_block); +if (r == -ENOENT ) { + adev->ip_blocks[i].status.valid = false; + }else if (r) { +DRM_ERROR ("early_init of IP block <%s> failed %d\n" , + adev->ip_blocks[i].version->funcs->name, r); + total = false; }else { adev->ip_blocks[i].status.valid = true; } + }else { + adev->ip_blocks[i].status.valid = true; }/* get the vbios after the asic_funcs are set up */ if (adev->ip_blocks[i].version->type ==AMD_IP_BLOCK_TYPE_COMMON ) {
drivers/gpu/drm/amd/amdgpu/amdgpu_isp.c +3 -2
@@ -122,9 +122,10 @@ static int isp_load_fw_by_psp(struct amdgpu_device *adev)return r; } -static int isp_early_init (void *handle) +static int isp_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; + +struct amdgpu_device *adev = ip_block->adev;struct amdgpu_isp *isp = &adev->isp;switch (amdgpu_ip_version (adev,ISP_HWIP ,0 )) {
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +2 -2
@@ -159,9 +159,9 @@ static int psp_init_sriov_microcode(struct psp_context *psp)return ret; } -static int psp_early_init (void *handle) +static int psp_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;struct psp_context *psp = &adev->psp; psp->autoload_supported = true;
drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c +2 -2
@@ -765,9 +765,9 @@ static int umsch_mm_init(struct amdgpu_device *adev) } -static int umsch_mm_early_init (void *handle) +static int umsch_mm_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;switch (amdgpu_ip_version (adev,VCN_HWIP ,0 )) {case IP_VERSION (4 ,0 ,5 ):
drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c +2 -2
@@ -295,9 +295,9 @@ int amdgpu_vpe_ring_fini(struct amdgpu_vpe *vpe)return 0 ; } -static int vpe_early_init (void *handle) +static int vpe_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;struct amdgpu_vpe *vpe = &adev->vpe;switch (amdgpu_ip_version (adev,VPE_HWIP ,0 )) {
drivers/gpu/drm/amd/amdgpu/cik.c +2 -2
@@ -1985,9 +1985,9 @@ static const struct amdgpu_asic_funcs cik_asic_funcs = .query_video_codecs = &cik_query_video_codecs, }; -static int cik_common_early_init (void *handle) +static int cik_common_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->smc_rreg = &cik_smc_rreg; adev->smc_wreg = &cik_smc_wreg;
drivers/gpu/drm/amd/amdgpu/cik_ih.c +2 -2
@@ -283,9 +283,9 @@ static void cik_ih_set_rptr(struct amdgpu_device *adev,WREG32 (mmIH_RB_RPTR, ih->rptr); } -static int cik_ih_early_init (void *handle) +static int cik_ih_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int ret; ret =amdgpu_irq_add_domain (adev);
drivers/gpu/drm/amd/amdgpu/cik_sdma.c +2 -2
@@ -918,9 +918,9 @@ static void cik_enable_sdma_mgls(struct amdgpu_device *adev, } } -static int cik_sdma_early_init (void *handle) +static int cik_sdma_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int r; adev->sdma.num_instances =SDMA_MAX_INSTANCE ;
drivers/gpu/drm/amd/amdgpu/cz_ih.c +2 -2
@@ -274,9 +274,9 @@ static void cz_ih_set_rptr(struct amdgpu_device *adev,WREG32 (mmIH_RB_RPTR, ih->rptr); } -static int cz_ih_early_init (void *handle) +static int cz_ih_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int ret; ret =amdgpu_irq_add_domain (adev);
drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +2 -2
@@ -2733,9 +2733,9 @@ static int dce_v10_0_crtc_init(struct amdgpu_device *adev, int index)return 0 ; } -static int dce_v10_0_early_init (void *handle) +static int dce_v10_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->audio_endpt_rreg = &dce_v10_0_audio_endpt_rreg; adev->audio_endpt_wreg = &dce_v10_0_audio_endpt_wreg;
drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +2 -2
@@ -2846,9 +2846,9 @@ static int dce_v11_0_crtc_init(struct amdgpu_device *adev, int index)return 0 ; } -static int dce_v11_0_early_init (void *handle) +static int dce_v11_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->audio_endpt_rreg = &dce_v11_0_audio_endpt_rreg; adev->audio_endpt_wreg = &dce_v11_0_audio_endpt_wreg;
drivers/gpu/drm/amd/amdgpu/dce_v6_0.c +2 -2
@@ -2628,9 +2628,9 @@ static int dce_v6_0_crtc_init(struct amdgpu_device *adev, int index)return 0 ; } -static int dce_v6_0_early_init (void *handle) +static int dce_v6_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->audio_endpt_rreg = &dce_v6_0_audio_endpt_rreg; adev->audio_endpt_wreg = &dce_v6_0_audio_endpt_wreg;
drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +2 -2
@@ -2639,9 +2639,9 @@ static int dce_v8_0_crtc_init(struct amdgpu_device *adev, int index)return 0 ; } -static int dce_v8_0_early_init (void *handle) +static int dce_v8_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->audio_endpt_rreg = &dce_v8_0_audio_endpt_rreg; adev->audio_endpt_wreg = &dce_v8_0_audio_endpt_wreg;
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +2 -2
@@ -7678,9 +7678,9 @@ static void gfx_v10_0_ring_emit_gds_switch(struct amdgpu_ring *ring, (1 << (oa_size + oa_base)) - (1 << oa_base)); } -static int gfx_v10_0_early_init (void *handle) +static int gfx_v10_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->gfx.funcs = &gfx_v10_0_gfx_funcs;
drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +2 -2
@@ -5037,9 +5037,9 @@ static void gfx_v11_0_ring_emit_gds_switch(struct amdgpu_ring *ring, (1 << (oa_size + oa_base)) - (1 << oa_base)); } -static int gfx_v11_0_early_init (void *handle) +static int gfx_v11_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->gfx.funcs = &gfx_v11_0_gfx_funcs;
drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c +2 -2
@@ -3712,9 +3712,9 @@ static uint64_t gfx_v12_0_get_gpu_clock_counter(struct amdgpu_device *adev)return clock; } -static int gfx_v12_0_early_init (void *handle) +static int gfx_v12_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->gfx.funcs = &gfx_v12_0_gfx_funcs;
drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c +2 -2
@@ -3023,9 +3023,9 @@ static const struct amdgpu_rlc_funcs gfx_v6_0_rlc_funcs = { .start = gfx_v6_0_rlc_start }; -static int gfx_v6_0_early_init (void *handle) +static int gfx_v6_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->gfx.xcc_mask =1 ; adev->gfx.num_gfx_rings =GFX6_NUM_GFX_RINGS ;
drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c +2 -2
@@ -4134,9 +4134,9 @@ static const struct amdgpu_rlc_funcs gfx_v7_0_rlc_funcs = { .update_spm_vmid = gfx_v7_0_update_spm_vmid }; -static int gfx_v7_0_early_init (void *handle) +static int gfx_v7_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->gfx.xcc_mask =1 ; adev->gfx.num_gfx_rings =GFX7_NUM_GFX_RINGS ;
drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +2 -2
@@ -5262,9 +5262,9 @@ static const struct amdgpu_gfx_funcs gfx_v8_0_gfx_funcs = { .select_me_pipe_q = &gfx_v8_0_select_me_pipe_q }; -static int gfx_v8_0_early_init (void *handle) +static int gfx_v8_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->gfx.xcc_mask =1 ; adev->gfx.num_gfx_rings =GFX8_NUM_GFX_RINGS ;
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +2 -2
@@ -4760,9 +4760,9 @@ static int gfx_v9_0_do_edc_gpr_workarounds(struct amdgpu_device *adev)return r; } -static int gfx_v9_0_early_init (void *handle) +static int gfx_v9_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->gfx.funcs = &gfx_v9_0_gfx_funcs;
drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c +2 -2
@@ -2517,9 +2517,9 @@ static void gfx_v9_4_3_ring_emit_gds_switch(struct amdgpu_ring *ring, (1 << (oa_size + oa_base)) - (1 << oa_base)); } -static int gfx_v9_4_3_early_init (void *handle) +static int gfx_v9_4_3_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->gfx.num_compute_rings =min (amdgpu_gfx_get_num_kcq (adev),AMDGPU_MAX_COMPUTE_RINGS );
drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c +2 -2
@@ -630,9 +630,9 @@ static void gmc_v10_0_set_gfxhub_funcs(struct amdgpu_device *adev) } -static int gmc_v10_0_early_init (void *handle) +static int gmc_v10_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;gmc_v10_0_set_mmhub_funcs (adev);gmc_v10_0_set_gfxhub_funcs (adev);
drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c +2 -2
@@ -628,9 +628,9 @@ static void gmc_v11_0_set_gfxhub_funcs(struct amdgpu_device *adev) } } -static int gmc_v11_0_early_init (void *handle) +static int gmc_v11_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;gmc_v11_0_set_gfxhub_funcs (adev);gmc_v11_0_set_mmhub_funcs (adev);
drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c +2 -2
@@ -614,9 +614,9 @@ static void gmc_v12_0_set_gfxhub_funcs(struct amdgpu_device *adev) } } -static int gmc_v12_0_early_init (void *handle) +static int gmc_v12_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;gmc_v12_0_set_gfxhub_funcs (adev);gmc_v12_0_set_mmhub_funcs (adev);
drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c +2 -2
@@ -762,9 +762,9 @@ static int gmc_v6_0_convert_vram_type(int mc_seq_vram_type) } } -static int gmc_v6_0_early_init (void *handle) +static int gmc_v6_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;gmc_v6_0_set_gmc_funcs (adev);gmc_v6_0_set_irq_funcs (adev);
drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +2 -2
@@ -921,9 +921,9 @@ static int gmc_v7_0_convert_vram_type(int mc_seq_vram_type) } } -static int gmc_v7_0_early_init (void *handle) +static int gmc_v7_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;gmc_v7_0_set_gmc_funcs (adev);gmc_v7_0_set_irq_funcs (adev);
drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +2 -2
@@ -1027,9 +1027,9 @@ static int gmc_v8_0_convert_vram_type(int mc_seq_vram_type) } } -static int gmc_v8_0_early_init (void *handle) +static int gmc_v8_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;gmc_v8_0_set_gmc_funcs (adev);gmc_v8_0_set_irq_funcs (adev);
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +2 -2
@@ -1554,9 +1554,9 @@ static void gmc_v9_0_set_xgmi_ras_funcs(struct amdgpu_device *adev) adev->gmc.xgmi.ras = &xgmi_ras; } -static int gmc_v9_0_early_init (void *handle) +static int gmc_v9_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;/* * 9.4.0, 9.4.1 and 9.4.3 don't have XGMI defined
drivers/gpu/drm/amd/amdgpu/iceland_ih.c +2 -2
@@ -273,9 +273,9 @@ static void iceland_ih_set_rptr(struct amdgpu_device *adev,WREG32 (mmIH_RB_RPTR, ih->rptr); } -static int iceland_ih_early_init (void *handle) +static int iceland_ih_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int ret; ret =amdgpu_irq_add_domain (adev);
drivers/gpu/drm/amd/amdgpu/ih_v6_0.c +2 -2
@@ -559,9 +559,9 @@ static void ih_v6_0_set_self_irq_funcs(struct amdgpu_device *adev) adev->irq.self_irq.funcs = &ih_v6_0_self_irq_funcs; } -static int ih_v6_0_early_init (void *handle) +static int ih_v6_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;ih_v6_0_set_interrupt_funcs (adev);ih_v6_0_set_self_irq_funcs (adev);
drivers/gpu/drm/amd/amdgpu/ih_v6_1.c +2 -2
@@ -532,9 +532,9 @@ static void ih_v6_1_set_self_irq_funcs(struct amdgpu_device *adev) adev->irq.self_irq.funcs = &ih_v6_1_self_irq_funcs; } -static int ih_v6_1_early_init (void *handle) +static int ih_v6_1_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int ret; ret =amdgpu_irq_add_domain (adev);
drivers/gpu/drm/amd/amdgpu/ih_v7_0.c +2 -2
@@ -528,9 +528,9 @@ static void ih_v7_0_set_self_irq_funcs(struct amdgpu_device *adev) adev->irq.self_irq.funcs = &ih_v7_0_self_irq_funcs; } -static int ih_v7_0_early_init (void *handle) +static int ih_v7_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;ih_v7_0_set_interrupt_funcs (adev);ih_v7_0_set_self_irq_funcs (adev);
drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c +2 -2
@@ -462,9 +462,9 @@ static int jpeg_v1_0_process_interrupt(struct amdgpu_device *adev,* * Set ring and irq function pointers */ -int jpeg_v1_0_early_init (void *handle) +int jpeg_v1_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->jpeg.num_jpeg_inst =1 ; adev->jpeg.num_jpeg_rings =1 ;
drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.h +1 -1
@@ -24,7 +24,7 @@#ifndef __JPEG_V1_0_H__#define __JPEG_V1_0_H__ -int jpeg_v1_0_early_init (void *handle); +int jpeg_v1_0_early_init (struct amdgpu_ip_block *ip_block);int jpeg_v1_0_sw_init (void *handle);void jpeg_v1_0_sw_fini (void *handle);void jpeg_v1_0_start (struct amdgpu_device *adev,int mode);
drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c +2 -2
@@ -45,9 +45,9 @@ static int jpeg_v2_0_set_powergating_state(void *handle,* * Set ring and irq function pointers */ -static int jpeg_v2_0_early_init (void *handle) +static int jpeg_v2_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->jpeg.num_jpeg_inst =1 ; adev->jpeg.num_jpeg_rings =1 ;
drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c +2 -2
@@ -54,9 +54,9 @@ static int amdgpu_ih_clientid_jpeg[] = {* * Set ring and irq function pointers */ -static int jpeg_v2_5_early_init (void *handle) +static int jpeg_v2_5_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;u32 harvest;int i;
drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c +2 -2
@@ -46,9 +46,9 @@ static int jpeg_v3_0_set_powergating_state(void *handle,* * Set ring and irq function pointers */ -static int jpeg_v3_0_early_init (void *handle) +static int jpeg_v3_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;u32 harvest;
drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c +2 -2
@@ -52,9 +52,9 @@ static void jpeg_v4_0_dec_ring_set_wptr(struct amdgpu_ring *ring);* * Set ring and irq function pointers */ -static int jpeg_v4_0_early_init (void *handle) +static int jpeg_v4_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->jpeg.num_jpeg_inst =1 ;
drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c +2 -2
@@ -72,9 +72,9 @@ static inline bool jpeg_v4_0_3_normalizn_reqd(struct amdgpu_device *adev)* * Set ring and irq function pointers */ -static int jpeg_v4_0_3_early_init (void *handle) +static int jpeg_v4_0_3_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->jpeg.num_jpeg_rings =AMDGPU_MAX_JPEG_RINGS ;
drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c +2 -2
@@ -65,9 +65,9 @@ static int amdgpu_ih_clientid_jpeg[] = {* * Set ring and irq function pointers */ -static int jpeg_v4_0_5_early_init (void *handle) +static int jpeg_v4_0_5_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;switch (amdgpu_ip_version (adev,UVD_HWIP ,0 )) {case IP_VERSION (4 ,0 ,5 ):
drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.c +2 -2
@@ -46,9 +46,9 @@ static int jpeg_v5_0_0_set_powergating_state(void *handle,* * Set ring and irq function pointers */ -static int jpeg_v5_0_0_early_init (void *handle) +static int jpeg_v5_0_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->jpeg.num_jpeg_inst =1 ; adev->jpeg.num_jpeg_rings =1 ;
drivers/gpu/drm/amd/amdgpu/mes_v11_0.c +2 -2
@@ -1633,9 +1633,9 @@ static int mes_v11_0_resume(void *handle)return amdgpu_mes_resume (adev); } -static int mes_v11_0_early_init (void *handle) +static int mes_v11_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int pipe, r;for (pipe =0 ; pipe <AMDGPU_MAX_MES_PIPES ; pipe++) {
drivers/gpu/drm/amd/amdgpu/mes_v12_0.c +2 -2
@@ -1628,9 +1628,9 @@ static int mes_v12_0_resume(void *handle)return amdgpu_mes_resume (adev); } -static int mes_v12_0_early_init (void *handle) +static int mes_v12_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int pipe, r;for (pipe =0 ; pipe <AMDGPU_MAX_MES_PIPES ; pipe++) {
drivers/gpu/drm/amd/amdgpu/navi10_ih.c +2 -2
@@ -542,9 +542,9 @@ static void navi10_ih_set_self_irq_funcs(struct amdgpu_device *adev) adev->irq.self_irq.funcs = &navi10_ih_self_irq_funcs; } -static int navi10_ih_early_init (void *handle) +static int navi10_ih_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;navi10_ih_set_interrupt_funcs (adev);navi10_ih_set_self_irq_funcs (adev);
drivers/gpu/drm/amd/amdgpu/nv.c +2 -2
@@ -634,9 +634,9 @@ static const struct amdgpu_asic_funcs nv_asic_funcs = { .query_video_codecs = &nv_query_video_codecs, }; -static int nv_common_early_init (void *handle) +static int nv_common_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->nbio.funcs->set_reg_remap (adev); adev->smc_rreg =NULL ;
drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c +2 -2
@@ -807,9 +807,9 @@ static void sdma_v2_4_ring_emit_wreg(struct amdgpu_ring *ring,amdgpu_ring_write (ring, val); } -static int sdma_v2_4_early_init (void *handle) +static int sdma_v2_4_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int r; adev->sdma.num_instances =SDMA_MAX_INSTANCE ;
drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +2 -2
@@ -1080,9 +1080,9 @@ static void sdma_v3_0_ring_emit_wreg(struct amdgpu_ring *ring,amdgpu_ring_write (ring, val); } -static int sdma_v3_0_early_init (void *handle) +static int sdma_v3_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int r;switch (adev->asic_type) {
drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +2 -2
@@ -1751,9 +1751,9 @@ static bool sdma_v4_0_fw_support_paging_queue(struct amdgpu_device *adev) } } -static int sdma_v4_0_early_init (void *handle) +static int sdma_v4_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int r; r =sdma_v4_0_init_microcode (adev);
drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c +2 -2
@@ -1296,9 +1296,9 @@ static bool sdma_v4_4_2_fw_support_paging_queue(struct amdgpu_device *adev) } } -static int sdma_v4_4_2_early_init (void *handle) +static int sdma_v4_4_2_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int r; r =sdma_v4_4_2_init_microcode (adev);
drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c +2 -2
@@ -1366,9 +1366,9 @@ static void sdma_v5_0_ring_emit_reg_write_reg_wait(struct amdgpu_ring *ring,amdgpu_ring_emit_reg_wait (ring, reg1, mask, mask); } -static int sdma_v5_0_early_init (void *handle) +static int sdma_v5_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int r; r =sdma_v5_0_init_microcode (adev);
drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c +2 -2
@@ -1216,9 +1216,9 @@ static void sdma_v5_2_ring_emit_reg_write_reg_wait(struct amdgpu_ring *ring,amdgpu_ring_emit_reg_wait (ring, reg1, mask, mask); } -static int sdma_v5_2_early_init (void *handle) +static int sdma_v5_2_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int r; r =amdgpu_sdma_init_microcode (adev,0 , true);
drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c +2 -2
@@ -1272,9 +1272,9 @@ static void sdma_v6_0_set_ras_funcs(struct amdgpu_device *adev) } } -static int sdma_v6_0_early_init (void *handle) +static int sdma_v6_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int r; r =amdgpu_sdma_init_microcode (adev,0 , true);
drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c +2 -2
@@ -1259,9 +1259,9 @@ static void sdma_v7_0_ring_emit_reg_write_reg_wait(struct amdgpu_ring *ring,amdgpu_ring_emit_reg_wait (ring, reg1, mask, mask); } -static int sdma_v7_0_early_init (void *handle) +static int sdma_v7_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int r; r =amdgpu_sdma_init_microcode (adev,0 , true);
drivers/gpu/drm/amd/amdgpu/si.c +2 -2
@@ -2022,9 +2022,9 @@ static uint32_t si_get_rev_id(struct amdgpu_device *adev) >> CC_DRM_ID_STRAPS__ATI_REV_ID__SHIFT; } -static int si_common_early_init (void *handle) +static int si_common_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->smc_rreg = &si_smc_rreg; adev->smc_wreg = &si_smc_wreg;
drivers/gpu/drm/amd/amdgpu/si_dma.c +2 -2
@@ -457,9 +457,9 @@ static void si_dma_ring_emit_wreg(struct amdgpu_ring *ring,amdgpu_ring_write (ring, val); } -static int si_dma_early_init (void *handle) +static int si_dma_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->sdma.num_instances =2 ;
drivers/gpu/drm/amd/amdgpu/si_ih.c +2 -2
@@ -156,9 +156,9 @@ static void si_ih_set_rptr(struct amdgpu_device *adev,WREG32 (IH_RB_RPTR , ih->rptr); } -static int si_ih_early_init (void *handle) +static int si_ih_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;si_ih_set_interrupt_funcs (adev);
drivers/gpu/drm/amd/amdgpu/soc15.c +2 -2
@@ -928,9 +928,9 @@ static const struct amdgpu_asic_funcs aqua_vanjaram_asic_funcs = .get_reg_state = &aqua_vanjaram_get_reg_state, }; -static int soc15_common_early_init (void *handle) +static int soc15_common_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->nbio.funcs->set_reg_remap (adev); adev->smc_rreg =NULL ;
drivers/gpu/drm/amd/amdgpu/soc21.c +2 -2
@@ -556,9 +556,9 @@ static const struct amdgpu_asic_funcs soc21_asic_funcs = { .update_umd_stable_pstate = &soc21_update_umd_stable_pstate, }; -static int soc21_common_early_init (void *handle) +static int soc21_common_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->nbio.funcs->set_reg_remap (adev); adev->smc_rreg =NULL ;
drivers/gpu/drm/amd/amdgpu/soc24.c +2 -2
@@ -363,9 +363,9 @@ static const struct amdgpu_asic_funcs soc24_asic_funcs = { .update_umd_stable_pstate = &soc24_update_umd_stable_pstate, }; -static int soc24_common_early_init (void *handle) +static int soc24_common_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->nbio.funcs->set_reg_remap (adev); adev->smc_rreg =NULL ;
drivers/gpu/drm/amd/amdgpu/tonga_ih.c +2 -2
@@ -283,9 +283,9 @@ static void tonga_ih_set_rptr(struct amdgpu_device *adev, } } -static int tonga_ih_early_init (void *handle) +static int tonga_ih_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int ret; ret =amdgpu_irq_add_domain (adev);
drivers/gpu/drm/amd/amdgpu/uvd_v3_1.c +2 -2
@@ -531,9 +531,9 @@ static void uvd_v3_1_set_irq_funcs(struct amdgpu_device *adev) } -static int uvd_v3_1_early_init (void *handle) +static int uvd_v3_1_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->uvd.num_uvd_inst =1 ;uvd_v3_1_set_ring_funcs (adev);
drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c +2 -2
@@ -90,9 +90,9 @@ static void uvd_v4_2_ring_set_wptr(struct amdgpu_ring *ring)WREG32 (mmUVD_RBC_RB_WPTR,lower_32_bits (ring->wptr)); } -static int uvd_v4_2_early_init (void *handle) +static int uvd_v4_2_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->uvd.num_uvd_inst =1 ;uvd_v4_2_set_ring_funcs (adev);
drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c +2 -2
@@ -88,9 +88,9 @@ static void uvd_v5_0_ring_set_wptr(struct amdgpu_ring *ring)WREG32 (mmUVD_RBC_RB_WPTR,lower_32_bits (ring->wptr)); } -static int uvd_v5_0_early_init (void *handle) +static int uvd_v5_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->uvd.num_uvd_inst =1 ;uvd_v5_0_set_ring_funcs (adev);
drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +2 -2
@@ -354,9 +354,9 @@ static int uvd_v6_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)return r; } -static int uvd_v6_0_early_init (void *handle) +static int uvd_v6_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->uvd.num_uvd_inst =1 ; if (!(adev->flags & AMD_IS_APU) &&
drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +2 -2
@@ -361,9 +361,9 @@ static int uvd_v7_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)return r; } -static int uvd_v7_0_early_init (void *handle) +static int uvd_v7_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;if (adev->asic_type ==CHIP_VEGA20 ) {u32 harvest;
drivers/gpu/drm/amd/amdgpu/vce_v2_0.c +2 -2
@@ -398,9 +398,9 @@ static void vce_v2_0_enable_mgcg(struct amdgpu_device *adev, bool enable, } } -static int vce_v2_0_early_init (void *handle) +static int vce_v2_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->vce.num_rings =2 ;
drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +2 -2
@@ -396,9 +396,9 @@ static unsigned vce_v3_0_get_harvest_config(struct amdgpu_device *adev) } } -static int vce_v3_0_early_init (void *handle) +static int vce_v3_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->vce.harvest_config =vce_v3_0_get_harvest_config (adev);
drivers/gpu/drm/amd/amdgpu/vce_v4_0.c +2 -2
@@ -407,9 +407,9 @@ static int vce_v4_0_stop(struct amdgpu_device *adev)return 0 ; } -static int vce_v4_0_early_init (void *handle) +static int vce_v4_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;if (amdgpu_sriov_vf (adev))/* currently only VCN0 support SRIOV */ adev->vce.num_rings =1 ;
drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +3 -3
@@ -100,9 +100,9 @@ static void vcn_v1_0_ring_begin_use(struct amdgpu_ring *ring);* Set ring and irq function pointers * Load microcode from filesystem */ -static int vcn_v1_0_early_init (void *handle) +static int vcn_v1_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->vcn.num_enc_rings =2 ;
@@ -110,7 +110,7 @@ static int vcn_v1_0_early_init(void *handle)vcn_v1_0_set_enc_ring_funcs (adev);vcn_v1_0_set_irq_funcs (adev); -jpeg_v1_0_early_init (handle); +jpeg_v1_0_early_init (ip_block);return amdgpu_vcn_early_init (adev); }
drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c +2 -2
@@ -106,9 +106,9 @@ static int vcn_v2_0_start_sriov(struct amdgpu_device *adev);* Set ring and irq function pointers * Load microcode from filesystem */ -static int vcn_v2_0_early_init (void *handle) +static int vcn_v2_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;if (amdgpu_sriov_vf (adev)) adev->vcn.num_enc_rings =1 ;
drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c +2 -2
@@ -116,9 +116,9 @@ static int amdgpu_ih_clientid_vcns[] = {* Set ring and irq function pointers * Load microcode from filesystem */ -static int vcn_v2_5_early_init (void *handle) +static int vcn_v2_5_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;if (amdgpu_sriov_vf (adev)) { adev->vcn.num_vcn_inst =2 ;
drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c +2 -2
@@ -122,9 +122,9 @@ static void vcn_v3_0_enc_ring_set_wptr(struct amdgpu_ring *ring);* Set ring and irq function pointers * Load microcode from filesystem */ -static int vcn_v3_0_early_init (void *handle) +static int vcn_v3_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;if (amdgpu_sriov_vf (adev)) { adev->vcn.num_vcn_inst =VCN_INSTANCES_SIENNA_CICHLID ;
drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c +2 -2
@@ -112,9 +112,9 @@ static void vcn_v4_0_set_ras_funcs(struct amdgpu_device *adev);* Set ring and irq function pointers * Load microcode from filesystem */ -static int vcn_v4_0_early_init (void *handle) +static int vcn_v4_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;int i;if (amdgpu_sriov_vf (adev)) {
drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c +2 -2
@@ -103,9 +103,9 @@ static void vcn_v4_0_3_enable_ras(struct amdgpu_device *adev,* * Set ring and irq function pointers */ -static int vcn_v4_0_3_early_init (void *handle) +static int vcn_v4_0_3_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;/* re-use enc ring as unified ring */ adev->vcn.num_enc_rings =1 ;
drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c +2 -2
@@ -110,9 +110,9 @@ static void vcn_v4_0_5_unified_ring_set_wptr(struct amdgpu_ring *ring);* Set ring and irq function pointers * Load microcode from filesystem */ -static int vcn_v4_0_5_early_init (void *handle) +static int vcn_v4_0_5_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;/* re-use enc ring as unified ring */ adev->vcn.num_enc_rings =1 ;
drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c +2 -2
@@ -92,9 +92,9 @@ static void vcn_v5_0_0_unified_ring_set_wptr(struct amdgpu_ring *ring);* Set ring and irq function pointers * Load microcode from filesystem */ -static int vcn_v5_0_0_early_init (void *handle) +static int vcn_v5_0_0_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;/* re-use enc ring as unified ring */ adev->vcn.num_enc_rings =1 ;
drivers/gpu/drm/amd/amdgpu/vega10_ih.c +2 -2
@@ -472,9 +472,9 @@ static void vega10_ih_set_self_irq_funcs(struct amdgpu_device *adev) adev->irq.self_irq.funcs = &vega10_ih_self_irq_funcs; } -static int vega10_ih_early_init (void *handle) +static int vega10_ih_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;vega10_ih_set_interrupt_funcs (adev);vega10_ih_set_self_irq_funcs (adev);
drivers/gpu/drm/amd/amdgpu/vega20_ih.c +2 -2
@@ -553,9 +553,9 @@ static void vega20_ih_set_self_irq_funcs(struct amdgpu_device *adev) adev->irq.self_irq.funcs = &vega20_ih_self_irq_funcs; } -static int vega20_ih_early_init (void *handle) +static int vega20_ih_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;vega20_ih_set_interrupt_funcs (adev);vega20_ih_set_self_irq_funcs (adev);
drivers/gpu/drm/amd/amdgpu/vi.c +2 -2
@@ -1455,9 +1455,9 @@ static const struct amdgpu_asic_funcs vi_asic_funcs =#define CZ_REV_BRISTOL (rev) \ ((rev >= 0xC8 && rev <= 0xCE) || (rev >= 0xE1 && rev <= 0xE6)) -static int vi_common_early_init (void *handle) +static int vi_common_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;if (adev->flags &AMD_IS_APU ) { adev->smc_rreg = &cz_smc_rreg;
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +3 -3
@@ -975,7 +975,7 @@ static int dm_set_powergating_state(void *handle, }/* Prototypes of private functions */ -static int dm_early_init (void *handle); +static int dm_early_init (struct amdgpu_ip_block *ip_block);/* Allocate memory for FBC compressed data */ static void amdgpu_dm_fbc_init (struct drm_connector *connector)
@@ -5386,9 +5386,9 @@ static int dm_init_microcode(struct amdgpu_device *adev)return r; } -static int dm_early_init (void *handle) +static int dm_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;struct amdgpu_mode_info *mode_info = &adev->mode_info;struct atom_context *ctx = mode_info->atom_context;int index =GetIndexIntoMasterTable (DATA , Object_Header);
drivers/gpu/drm/amd/include/amd_shared.h +1 -1
@@ -379,7 +379,7 @@ struct amdgpu_ip_block;struct amd_ip_funcs {char *name; -int (*early_init)(void *handle); +int (*early_init)(struct amdgpu_ip_block *ip_block);int (*late_init)(void *handle);int (*sw_init)(void *handle);int (*sw_fini)(void *handle);
drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c +2 -2
@@ -2954,9 +2954,9 @@ static int kv_dpm_get_temp(void *handle)return actual_temp; } -static int kv_dpm_early_init (void *handle) +static int kv_dpm_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->powerplay.pp_funcs = &kv_dpm_funcs; adev->powerplay.pp_handle = adev;
drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c +2 -2
@@ -7972,10 +7972,10 @@ static void si_dpm_print_power_state(void *handle,amdgpu_dpm_print_ps_status (adev, rps); } -static int si_dpm_early_init (void *handle) +static int si_dpm_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev; adev->powerplay.pp_funcs = &si_dpm_funcs; adev->powerplay.pp_handle = adev;
drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c +2 -3
@@ -80,11 +80,10 @@ static void amd_powerplay_destroy(struct amdgpu_device *adev) hwmgr =NULL ; } -static int pp_early_init (void *handle) +static int pp_early_init (struct amdgpu_ip_block *ip_block) {int ret; -struct amdgpu_device *adev = handle; - +struct amdgpu_device *adev = ip_block->adev; ret =amd_powerplay_create (adev);if (ret !=0 )
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +2 -2
@@ -746,9 +746,9 @@ static int smu_set_funcs(struct amdgpu_device *adev)return 0 ; } -static int smu_early_init (void *handle) +static int smu_early_init (struct amdgpu_ip_block *ip_block) { -struct amdgpu_device *adev = (struct amdgpu_device *)handle; +struct amdgpu_device *adev = ip_block->adev;struct smu_context *smu;int r;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 186/666 drm/amdgpu/uvd4.2: Dont initialize UVD 4.2 when DPM is disabled
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
[ Upstream commit 8b3e8fa6d7bdab292447a43f70532db437d5d4f5 ]
UVD 4.2 doesn't work at all when DPM is disabled because the SMU is responsible for ungating it. So, Linux fails to boot with CIK GPUs when using the amdgpu.dpm=0 parameter.
Fix this by returning -ENOENT from uvd_v4_2_early_init() when amdgpu_dpm isn't enabled.
Note: amdgpu.dpm=0 is often suggested as a workaround for issues and is useful for debugging.
--- drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c +5 -0
@@ -93,6 +93,11 @@ static void uvd_v4_2_ring_set_wptr(struct amdgpu_ring *ring)static int uvd_v4_2_early_init (struct amdgpu_ip_block *ip_block) {struct amdgpu_device *adev = ip_block->adev; + +/* UVD doesn't work without DPM, it needs DPM to ungate it. */ +if (!amdgpu_dpm) +return -ENOENT ; + adev->uvd.num_uvd_inst =1 ;uvd_v4_2_set_ring_funcs (adev);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 187/666 hwmon: Switch back to struct platform_driver::remove()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <[email protected]>
[ Upstream commit 6126f7bb6075d0af577e55bf7e2cbbcc272f520b ]
After commit 0edb555a65d1 ("platform: Make platform_driver::remove() return void") .remove() is (again) the right callback to implement for platform drivers.
Convert all platform drivers below drivers/hwmonto use .remove(), with the eventual goal to drop struct platform_driver::remove_new(). As .remove() and .remove_new() have the same prototypes, conversion is done by just changing the structure member name in the driver initializer.
While touching these files, make indention of the struct initializer consistent in several files.
Message-ID: <[email protected]>
Stable-dep-of: 46fef8583daa ("hwmon: (aspeed-g6-pwm-tach): remove redundant driver remove callback")
--- drivers/hwmon/abituguru.c | 2 +- drivers/hwmon/abituguru3.c | 4 ++-- drivers/hwmon/aspeed-g6-pwm-tach.c | 2 +- drivers/hwmon/da9052-hwmon.c | 2 +- drivers/hwmon/dme1737.c | 2 +- drivers/hwmon/f71805f.c | 2 +- drivers/hwmon/f71882fg.c | 2 +- drivers/hwmon/i5k_amb.c | 2 +- drivers/hwmon/max197.c | 2 +- drivers/hwmon/mc13783-adc.c | 2 +- drivers/hwmon/occ/p9_sbe.c | 4 ++-- drivers/hwmon/pc87360.c | 2 +- drivers/hwmon/pc87427.c | 2 +- drivers/hwmon/sch5636.c | 2 +- drivers/hwmon/sht15.c | 2 +- drivers/hwmon/sis5595.c | 2 +- drivers/hwmon/smsc47m1.c | 2 +- drivers/hwmon/ultra45_env.c | 2 +- drivers/hwmon/via-cputemp.c | 2 +- drivers/hwmon/via686a.c | 2 +- drivers/hwmon/vt1211.c | 2 +- drivers/hwmon/vt8231.c | 4 ++-- drivers/hwmon/w83627hf.c | 2 +- drivers/hwmon/w83781d.c | 2 +- drivers/hwmon/xgene-hwmon.c | 2 +- 25 files changed, 28 insertions(+), 28 deletions(-)
drivers/hwmon/abituguru.c +1 -1
@@ -1531,7 +1531,7 @@ static struct platform_driver abituguru_driver = { .pm = pm_sleep_ptr(&abituguru_pm), }, .probe = abituguru_probe, - .remove_new = abituguru_remove, + .remove = abituguru_remove, };static int __init abituguru_detect (void )
drivers/hwmon/abituguru3.c +2 -2
@@ -1147,12 +1147,12 @@ static int abituguru3_resume(struct device *dev) static DEFINE_SIMPLE_DEV_PM_OPS(abituguru3_pm, abituguru3_suspend, abituguru3_resume);static struct platform_driver abituguru3_driver = { - .driver = { + .driver = { .name =ABIT_UGURU3_NAME , .pm =pm_sleep_ptr (&abituguru3_pm), }, .probe = abituguru3_probe, - .remove_new = abituguru3_remove, + .remove = abituguru3_remove, };static int __init abituguru3_dmi_detect (void )
drivers/hwmon/aspeed-g6-pwm-tach.c +1 -1
@@ -534,7 +534,7 @@ MODULE_DEVICE_TABLE(of, aspeed_pwm_tach_match);static struct platform_driver aspeed_pwm_tach_driver = { .probe = aspeed_pwm_tach_probe, - .remove_new = aspeed_pwm_tach_remove, + .remove = aspeed_pwm_tach_remove, .driver = { .name ="aspeed-g6-pwm-tach" , .of_match_table = aspeed_pwm_tach_match,
drivers/hwmon/da9052-hwmon.c +1 -1
@@ -473,7 +473,7 @@ static void da9052_hwmon_remove(struct platform_device *pdev)static struct platform_driver da9052_hwmon_driver = { .probe = da9052_hwmon_probe, - .remove_new = da9052_hwmon_remove, + .remove = da9052_hwmon_remove, .driver = { .name ="da9052-hwmon" , },
drivers/hwmon/dme1737.c +1 -1
@@ -2721,7 +2721,7 @@ static struct platform_driver dme1737_isa_driver = { .name = "dme1737", }, .probe = dme1737_isa_probe, - .remove_new = dme1737_isa_remove, + .remove = dme1737_isa_remove, };/* ---------------------------------------------------------------------
drivers/hwmon/f71805f.c +1 -1
@@ -1497,7 +1497,7 @@ static struct platform_driver f71805f_driver = { .name = DRVNAME, }, .probe = f71805f_probe, - .remove_new = f71805f_remove, + .remove = f71805f_remove, }; static int __init f71805f_device_add(unsigned short address,
drivers/hwmon/f71882fg.c +1 -1
@@ -2660,7 +2660,7 @@ static struct platform_driver f71882fg_driver = { .name = DRVNAME, }, .probe = f71882fg_probe, - .remove_new = f71882fg_remove, + .remove = f71882fg_remove, };static int __init f71882fg_init (void )
drivers/hwmon/i5k_amb.c +1 -1
@@ -568,7 +568,7 @@ static struct platform_driver i5k_amb_driver = { .name = DRVNAME, }, .probe = i5k_amb_probe, - .remove_new = i5k_amb_remove, + .remove = i5k_amb_remove, };static int __init i5k_amb_init (void )
drivers/hwmon/max197.c +1 -1
@@ -332,7 +332,7 @@ static struct platform_driver max197_driver = { .name = "max197", }, .probe = max197_probe, - .remove_new = max197_remove, + .remove = max197_remove, .id_table = max197_device_ids, };module_platform_driver (max197_driver);
drivers/hwmon/mc13783-adc.c +1 -1
@@ -315,7 +315,7 @@ static const struct platform_device_id mc13783_adc_idtable[] = {MODULE_DEVICE_TABLE (platform, mc13783_adc_idtable);static struct platform_driver mc13783_adc_driver = { - .remove_new = mc13783_adc_remove, + .remove = mc13783_adc_remove, .driver = { .name =DRIVER_NAME , },
drivers/hwmon/occ/p9_sbe.c +2 -2
@@ -192,8 +192,8 @@ static struct platform_driver p9_sbe_occ_driver = { .name = "occ-hwmon", .of_match_table = p9_sbe_occ_of_match, }, - .probe = p9_sbe_occ_probe, - .remove_new = p9_sbe_occ_remove, + .probe = p9_sbe_occ_probe, + .remove = p9_sbe_occ_remove, };module_platform_driver (p9_sbe_occ_driver);
drivers/hwmon/pc87360.c +1 -1
@@ -1606,7 +1606,7 @@ static struct platform_driver pc87360_driver = { .name = DRIVER_NAME, }, .probe = pc87360_probe, - .remove_new = pc87360_remove, + .remove = pc87360_remove, };/*
drivers/hwmon/pc87427.c +1 -1
@@ -1129,7 +1129,7 @@ static struct platform_driver pc87427_driver = { .name = DRVNAME, }, .probe = pc87427_probe, - .remove_new = pc87427_remove, + .remove = pc87427_remove, };static int __init pc87427_device_add (const struct pc87427_sio_data *sio_data)
drivers/hwmon/sch5636.c +1 -1
@@ -512,7 +512,7 @@ static struct platform_driver sch5636_driver = { .name = DRVNAME, }, .probe = sch5636_probe, - .remove_new = sch5636_remove, + .remove = sch5636_remove, .id_table = sch5636_device_id, };
drivers/hwmon/sht15.c +1 -1
@@ -1051,7 +1051,7 @@ static struct platform_driver sht15_driver = { .of_match_table = of_match_ptr(sht15_dt_match), }, .probe = sht15_probe, - .remove_new = sht15_remove, + .remove = sht15_remove, .id_table = sht15_device_ids, };module_platform_driver (sht15_driver);
drivers/hwmon/sis5595.c +1 -1
@@ -784,7 +784,7 @@ static struct platform_driver sis5595_driver = { .name = DRIVER_NAME, }, .probe = sis5595_probe, - .remove_new = sis5595_remove, + .remove = sis5595_remove, }; static int sis5595_pci_probe(struct pci_dev *dev,
drivers/hwmon/smsc47m1.c +1 -1
@@ -858,7 +858,7 @@ static struct platform_driver smsc47m1_driver __refdata = { .driver = { .name = DRVNAME, }, - .remove_new = __exit_p(smsc47m1_remove), + .remove = __exit_p(smsc47m1_remove), }; static int __init smsc47m1_device_add(unsigned short address,
drivers/hwmon/ultra45_env.c +1 -1
@@ -317,7 +317,7 @@ static struct platform_driver env_driver = { .of_match_table = env_match, }, .probe = env_probe, - .remove_new = env_remove, + .remove = env_remove, };module_platform_driver (env_driver);
drivers/hwmon/via-cputemp.c +1 -1
@@ -197,7 +197,7 @@ static struct platform_driver via_cputemp_driver = { .name = DRVNAME, }, .probe = via_cputemp_probe, - .remove_new = via_cputemp_remove, + .remove = via_cputemp_remove, }; struct pdev_entry {
drivers/hwmon/via686a.c +1 -1
@@ -799,7 +799,7 @@ static struct platform_driver via686a_driver = { .name = DRIVER_NAME, }, .probe = via686a_probe, - .remove_new = via686a_remove, + .remove = via686a_remove, }; static const struct pci_device_id via686a_pci_ids[] = {
drivers/hwmon/vt1211.c +1 -1
@@ -1221,7 +1221,7 @@ static struct platform_driver vt1211_driver = { .name = DRVNAME, }, .probe = vt1211_probe, - .remove_new = vt1211_remove, + .remove = vt1211_remove, };static int __init vt1211_device_add (unsigned short address)
drivers/hwmon/vt8231.c +2 -2
@@ -910,11 +910,11 @@ static void vt8231_remove(struct platform_device *pdev)static struct platform_driver vt8231_driver = { - .driver = { + .driver = { .name =DRIVER_NAME , }, .probe = vt8231_probe, - .remove_new = vt8231_remove, + .remove = vt8231_remove, };static const struct pci_device_id vt8231_pci_ids[] = {
drivers/hwmon/w83627hf.c +1 -1
@@ -1844,7 +1844,7 @@ static struct platform_driver w83627hf_driver = { .pm = W83627HF_DEV_PM_OPS, }, .probe = w83627hf_probe, - .remove_new = w83627hf_remove, + .remove = w83627hf_remove, }; static int __init w83627hf_find(int sioaddr, unsigned short *addr,
drivers/hwmon/w83781d.c +1 -1
@@ -1828,7 +1828,7 @@ static struct platform_driver w83781d_isa_driver = { .name = "w83781d", }, .probe = w83781d_isa_probe, - .remove_new = w83781d_isa_remove, + .remove = w83781d_isa_remove, };/* return 1 if a supported chip is found, 0 otherwise */
drivers/hwmon/xgene-hwmon.c +1 -1
@@ -772,7 +772,7 @@ MODULE_DEVICE_TABLE(of, xgene_hwmon_of_match);static struct platform_driver xgene_hwmon_driver = { .probe = xgene_hwmon_probe, - .remove_new = xgene_hwmon_remove, + .remove = xgene_hwmon_remove, .driver = { .name ="xgene-slimpro-hwmon" , .of_match_table = xgene_hwmon_of_match,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 188/666 hwmon: (aspeed-g6-pwm-tach): remove redundant driver remove callback
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Billy Tsai <[email protected]>
[ Upstream commit 46fef8583daa1bf78fda7eaa523c64d4440322ac ]
Drops the remove callback as it only asserts reset and the probe already registers a devres action (devm_add_action_or_reset()) to call aspeed_pwm_tach_reset_assert().
--- drivers/hwmon/aspeed-g6-pwm-tach.c | 8 -------- 1 file changed, 8 deletions(-)
drivers/hwmon/aspeed-g6-pwm-tach.c +0 -8
@@ -517,13 +517,6 @@ static int aspeed_pwm_tach_probe(struct platform_device *pdev)return 0 ; } -static void aspeed_pwm_tach_remove (struct platform_device *pdev) -{ -struct aspeed_pwm_tach_data *priv =platform_get_drvdata (pdev); - -reset_control_assert (priv->reset); -} -static const struct of_device_id aspeed_pwm_tach_match[] = { { .compatible ="aspeed,ast2600-pwm-tach" ,
@@ -534,7 +527,6 @@ MODULE_DEVICE_TABLE(of, aspeed_pwm_tach_match);static struct platform_driver aspeed_pwm_tach_driver = { .probe = aspeed_pwm_tach_probe, - .remove = aspeed_pwm_tach_remove, .driver = { .name ="aspeed-g6-pwm-tach" , .of_match_table = aspeed_pwm_tach_match,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 189/666 ALSA: hda/realtek: fix code style (ERROR: else should follow close brace })
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lei Huang <[email protected]>
[ Upstream commit d1888bf848ade6a9e71c7ba516fd215aa1bd8d65 ]
Fix checkpatch code style errors:
ERROR: else should follow close brace '}' #2300: FILE: sound/hda/codecs/realtek/alc269.c:2300:
+ }
+ else
--- sound/pci/hda/patch_realtek.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
sound/pci/hda/patch_realtek.c +2 -2
@@ -6428,9 +6428,9 @@ static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec,struct alc_spec *spec = codec->spec; spec->parse_flags |=HDA_PINCFG_HEADSET_MIC ;alc255_set_default_jack_type (codec); - } -else + }else {alc_fixup_headset_mode (codec, fix, action); + } } static void alc288_update_headset_jack_cb(struct hda_codec *codec,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 190/666 ASoC: SOF: Intel: hda: Place check before dereference
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ethan Tidmore <[email protected]>
[ Upstream commit 6cbc8360f51a3df2ea16a786b262b9fe44d4c68c ]
The struct hext_stream is dereferenced before it is checked for NULL. Although it can never be NULL due to a check prior to hda_dsp_iccmax_stream_hw_params() being called, this change clears any confusion regarding hext_stream possibly being NULL.
Check hext_stream for NULL and then assign its members.
Detected by Smatch:sound/soc/sof/intel/hda-stream.c:488 hda_dsp_iccmax_stream_hw_params() warn:
variable dereferenced before check 'hext_stream' (see line 486)
--- sound/soc/sof/intel/hda-stream.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
sound/soc/sof/intel/hda-stream.c +7 -3
@@ -419,16 +419,20 @@ int hda_dsp_iccmax_stream_hw_params(struct snd_sof_dev *sdev, struct hdac_ext_ststruct snd_dma_buffer *dmab, struct snd_pcm_hw_params *params) { - struct hdac_stream *hstream = &hext_stream->hstream; -int sd_offset =SOF_STREAM_SD_OFFSET (hstream); + struct hdac_stream *hstream; +int sd_offset;int ret; -u32 mask =0x1 << hstream->index; +u32 mask;if (!hext_stream) {dev_err (sdev->dev,"error: no stream available\n" );return -ENODEV ; } + hstream = &hext_stream->hstream; + sd_offset =SOF_STREAM_SD_OFFSET (hstream); + mask =0x1 << hstream->index; +if (!dmab) {dev_err (sdev->dev,"error: no dma buffer allocated!\n" );return -ENODEV ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 191/666 drm/msm/a6xx: Fix HLSQ register dumping
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rob Clark <[email protected]>
[ Upstream commit c289a6db9ba6cb974f0317da142e4f665d589566 ]
Fix the bitfield offset of HLSQ_READ_SEL state-type bitfield. Otherwise we are always reading TP state when we wanted SP or HLSQ state.
Patchwork: https://patchwork.freedesktop.org/patch/714236/
Message-ID: <[email protected]>
--- drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c +1 -1
@@ -996,7 +996,7 @@ static void a6xx_get_crashdumper_hlsq_registers(struct msm_gpu *gpu,u64 out = dumper->iova +A6XX_CD_DATA_OFFSET ;int i, regcount =0 ; - in +=CRASHDUMP_WRITE (in,REG_A6XX_HLSQ_DBG_READ_SEL , regs->val1); + in +=CRASHDUMP_WRITE (in,REG_A6XX_HLSQ_DBG_READ_SEL , (regs->val1 &0xff ) <<8 );for (i =0 ; i < regs->count; i +=2 ) {u32 count =RANGE (regs->registers, i);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 192/666 drm/msm/shrinker: Fix can_block() logic
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rob Clark <[email protected]>
[ Upstream commit df0f439e3926817cf577ca6272aad68468ff7624 ]
The intention here was to allow blocking if DIRECT_RECLAIM or if called from kswapd and KSWAPD_RECLAIM is set.
Reported by Claude code review: https://lore.gitlab.freedesktop.org/drm-ai-reviews/review-patch9-20260309151119.290217-10-boris.brezillon@collabora.com/ on a panthor patch which had copied similar logic.
Patchwork: https://patchwork.freedesktop.org/patch/714238/
Message-ID: <[email protected]>
--- drivers/gpu/drm/msm/msm_gem_shrinker.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/gpu/drm/msm/msm_gem_shrinker.c +2 -3
@@ -26,9 +26,8 @@ static bool can_swap(void)static bool can_block (struct shrink_control *sc) { -if (!(sc->gfp_mask & __GFP_DIRECT_RECLAIM)) -return false; -return current_is_kswapd () || (sc->gfp_mask & __GFP_RECLAIM); +return (sc->gfp_mask & __GFP_DIRECT_RECLAIM) || + (current_is_kswapd () && (sc->gfp_mask & __GFP_KSWAPD_RECLAIM)); } static unsigned long
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 193/666 drm/msm/a6xx: Fix dumping A650+ debugbus blocks
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Connor Abbott <[email protected]>
[ Upstream commit cc83f71c9be0715fe93b963ffa9767d5d84354ed ]
These should be appended after the existing debugbus blocks, instead of replacing them.
Patchwork: https://patchwork.freedesktop.org/patch/714270/
Message-ID: <[email protected]>
--- drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c +6 -6
@@ -346,7 +346,7 @@ static void a6xx_get_debugbus_blocks(struct msm_gpu *gpu, sizeof(*a6xx_state->debugbus));if (a6xx_state->debugbus) { -int i; +int i, j;for (i =0 ; i <ARRAY_SIZE (a6xx_debugbus_blocks); i++) a6xx_get_debugbus_block(gpu,
@@ -354,8 +354,6 @@ static void a6xx_get_debugbus_blocks(struct msm_gpu *gpu, &a6xx_debugbus_blocks[i], &a6xx_state->debugbus[i]); - a6xx_state->nr_debugbus =ARRAY_SIZE (a6xx_debugbus_blocks); -/* * GBIF has same debugbus as of other GPU blocks, fall back to * default path if GPU uses GBIF, also GBIF uses exactly same
@@ -366,17 +364,19 @@ static void a6xx_get_debugbus_blocks(struct msm_gpu *gpu, &a6xx_gbif_debugbus_block, &a6xx_state->debugbus[i]); - a6xx_state->nr_debugbus +=1 ; + i++; }if (adreno_is_a650_family (to_adreno_gpu (gpu))) { -for (i =0 ; i <ARRAY_SIZE (a650_debugbus_blocks); i++) +for (j =0 ; j <ARRAY_SIZE (a650_debugbus_blocks); i++, j++)a6xx_get_debugbus_block (gpu, a6xx_state, - &a650_debugbus_blocks[i], + &a650_debugbus_blocks[j], &a6xx_state->debugbus[i]); } + + a6xx_state->nr_debugbus = i; } }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 194/666 drm/msm/a6xx: Use barriers while updating HFI Q headers
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Akhil P Oommen <[email protected]>
[ Upstream commit dc78b35d5ec09d1b0b8a937e6e640d2c5a030915 ]
To avoid harmful compiler optimizations and IO reordering in the HW, use barriers and READ/WRITE_ONCE helpers as necessary while accessing the HFI queue index variables.
Patchwork: https://patchwork.freedesktop.org/patch/714653/
Message-ID: <[email protected]>
--- drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
drivers/gpu/drm/msm/adreno/a6xx_hfi.c +10 -4
@@ -31,7 +31,7 @@ static int a6xx_hfi_queue_read(struct a6xx_gmu *gmu,struct a6xx_hfi_queue_header *header = queue->header;u32 i, hdr, index = header->read_index; -if (header->read_index == header->write_index) { +if (header->read_index ==READ_ONCE (header->write_index)) { header->rx_request =1 ;return 0 ; }
@@ -59,7 +59,10 @@ static int a6xx_hfi_queue_read(struct a6xx_gmu *gmu,if (!gmu->legacy) index =ALIGN (index,4 ) % header->size; - header->read_index = index; +/* Ensure all memory operations are complete before updating the read index */ +dma_mb (); + +WRITE_ONCE (header->read_index, index);return HFI_HEADER_SIZE (hdr); }
@@ -71,7 +74,7 @@ static int a6xx_hfi_queue_write(struct a6xx_gmu *gmu,spin_lock (&queue->lock); - space =CIRC_SPACE (header->write_index, header->read_index, + space =CIRC_SPACE (header->write_index,READ_ONCE (header->read_index), header->size);if (space < dwords) { header->dropped++;
@@ -92,7 +95,10 @@ static int a6xx_hfi_queue_write(struct a6xx_gmu *gmu, queue->data[index] =0xfafafafa ; } - header->write_index = index; +/* Ensure all memory operations are complete before updating the write index */ +dma_mb (); + +WRITE_ONCE (header->write_index, index);spin_unlock (&queue->lock);gmu_write (gmu,REG_A6XX_GMU_HOST2GMU_INTR_SET ,0x01 );
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 195/666 pmdomain: ti: omap_prm: Fix a reference leak on device node
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Gu <[email protected]>
[ Upstream commit 44c28e1c52764fef6dd1c1ada3a248728812e67f ]
When calling of_parse_phandle_with_args(), the caller is responsible to call of_node_put() to release the reference of device node. In omap_prm_domain_attach_dev, it does not release the reference.
--- drivers/pmdomain/ti/omap_prm.c | 1 + 1 file changed, 1 insertion(+)
drivers/pmdomain/ti/omap_prm.c +1 -0
@@ -651,6 +651,7 @@ static int omap_prm_domain_attach_dev(struct generic_pm_domain *domain,if (pd_args.args_count !=0 )dev_warn (dev,"%s: unusupported #power-domain-cells: %i\n" , prmd->pd.name, pd_args.args_count); +of_node_put (pd_args.np); genpd_data =dev_gpd_data (dev); genpd_data->data =NULL ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 196/666 pmdomain: imx: scu-pd: Fix device_node reference leak during ->probe()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Gu <[email protected]>
[ Upstream commit c8e9b6a55702be6c6d034e973d519c52c3848415 ]
When calling of_parse_phandle_with_args(), the caller is responsible to call of_node_put() to release the reference of device node. In imx_sc_pd_get_console_rsrc(), it does not release the reference.
--- drivers/pmdomain/imx/scu-pd.c | 1 + 1 file changed, 1 insertion(+)
drivers/pmdomain/imx/scu-pd.c +1 -0
@@ -326,6 +326,7 @@ static void imx_sc_pd_get_console_rsrc(void)return ; imx_con_rsrc = specs.args[0 ]; +of_node_put (specs.np); }static int imx_sc_get_pd_power (struct device *dev,u32 rsrc)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 197/666 PM: domains: De-constify fields in struct dev_pm_domain_attach_data
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov <[email protected]>
[ Upstream commit 1877d3f258cbb57d64e275754fb9b18b089ce72d ]
It doesn't really make sense to keep u32 fields to be marked as const. Having the const fields prevents their modification in the driver. Instead the whole struct can be defined as const, if it is constant.
--- include/linux/pm_domain.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
include/linux/pm_domain.h +2 -2
@@ -36,8 +36,8 @@struct dev_pm_domain_attach_data {const char *const *pd_names; -const u32 num_pd_names; -const u32 pd_flags; +u32 num_pd_names; +u32 pd_flags; };struct dev_pm_domain_list {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 198/666 ASoC: fsl_micfil: Add access property for "VAD Detected"
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengjiu Wang <[email protected]>
[ Upstream commit c7661bfc7422443df394c01e069ae4e5c3a7f04c ]
Add access property SNDRV_CTL_ELEM_ACCESS_READ for control "VAD Detected", which doesn't support put operation, otherwise there will be issue with mixer-test.
--- sound/soc/fsl/fsl_micfil.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
sound/soc/fsl/fsl_micfil.c +7 -1
@@ -395,7 +395,13 @@ static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = {SOC_SINGLE ("HWVAD ZCD Adjustment" ,REG_MICFIL_VAD0_ZCD ,8 ,15 ,0 ),SOC_SINGLE ("HWVAD ZCD And Behavior Switch" , REG_MICFIL_VAD0_ZCD, 4, 1, 0), - SOC_SINGLE_BOOL_EXT("VAD Detected", 0, hwvad_detected, NULL), + { + .iface =SNDRV_CTL_ELEM_IFACE_MIXER , + .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .name = "VAD Detected", + .info = snd_soc_info_bool_ext, + .get = hwvad_detected, + }, };static int fsl_micfil_use_verid (struct device *dev)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 199/666 ASoC: fsl_micfil: Fix event generation in hwvad_put_enable()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengjiu Wang <[email protected]>
[ Upstream commit 59b9061824f2179fe133e2636203548eaba3e528 ]
ALSA controls should return 1 if the value in the control changed but the control put operation hwvad_put_enable() only returns 0 or a negative error code, causing ALSA to not generate any change events.
Add a suitable check in the function before updating the vad_enabled variable.
--- sound/soc/fsl/fsl_micfil.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
sound/soc/fsl/fsl_micfil.c +6 -1
@@ -277,10 +277,15 @@ static int hwvad_put_enable(struct snd_kcontrol *kcontrol,unsigned int *item = ucontrol->value.enumerated.item;struct fsl_micfil *micfil =snd_soc_component_get_drvdata (comp);int val =snd_soc_enum_item_to_val (e, item[0 ]); +bool change = false; +if (val <0 || val >1 ) +return -EINVAL ; + + change = (micfil->vad_enabled != val); micfil->vad_enabled = val; -return 0 ; +return change; } static int hwvad_get_enable(struct snd_kcontrol *kcontrol,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 200/666 ASoC: fsl_micfil: Fix event generation in hwvad_put_init_mode()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengjiu Wang <[email protected]>
[ Upstream commit 7e226209906906421f0d952d7304e48fdb0adabc ]
ALSA controls should return 1 if the value in the control changed but the control put operation hwvad_put_init_mode() only returns 0 or a negative error code, causing ALSA to not generate any change events.
Add a suitable check in the function before updating the vad_init_mode variable.
--- sound/soc/fsl/fsl_micfil.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
sound/soc/fsl/fsl_micfil.c +6 -1
@@ -307,13 +307,18 @@ static int hwvad_put_init_mode(struct snd_kcontrol *kcontrol,unsigned int *item = ucontrol->value.enumerated.item;struct fsl_micfil *micfil =snd_soc_component_get_drvdata (comp);int val =snd_soc_enum_item_to_val (e, item[0 ]); +bool change = false; + +if (val <MICFIL_HWVAD_ENVELOPE_MODE || val >MICFIL_HWVAD_ENERGY_MODE ) +return -EINVAL ;/* 0 - Envelope-based Mode * 1 - Energy-based Mode */ + change = (micfil->vad_init_mode != val); micfil->vad_init_mode = val; -return 0 ; +return change; } static int hwvad_get_init_mode(struct snd_kcontrol *kcontrol,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 201/666 ASoC: fsl_micfil: Fix event generation in micfil_put_dc_remover_state()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengjiu Wang <[email protected]>
[ Upstream commit 7d2bd35100de370dc326b250e8f6b66bee06a2f3 ]
ALSA controls should return 1 if the value in the control changed but the control put operation micfil_put_dc_remover_state() only returns 0 or a negative error code, causing ALSA to not generate any change events.
return the value of snd_soc_component_update_bits() directly, as it has the capability of return check status of changed or not.
Also enable pm runtime before calling the function snd_soc_component_update_bits() to make the regmap cache data align with the value in hardware.
--- sound/soc/fsl/fsl_micfil.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
sound/soc/fsl/fsl_micfil.c +7 -3
@@ -243,6 +243,10 @@ static int micfil_put_dc_remover_state(struct snd_kcontrol *kcontrol,if (val <0 || val >3 )return -EINVAL ; + ret =pm_runtime_resume_and_get (comp->dev); +if (ret) +return ret; + micfil->dc_remover = val;/* Calculate total value for all channels */
@@ -252,10 +256,10 @@ static int micfil_put_dc_remover_state(struct snd_kcontrol *kcontrol,/* Update DC Remover mode for all channels */ ret =snd_soc_component_update_bits (comp,REG_MICFIL_DC_CTRL ,MICFIL_DC_CTRL_CONFIG , reg_val); -if (ret <0 ) -return ret; -return 0 ; +pm_runtime_put_autosuspend (comp->dev); + +return ret; } static int micfil_get_dc_remover_state(struct snd_kcontrol *kcontrol,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 202/666 ASoC: fsl_micfil: Fix event generation in micfil_quality_set()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengjiu Wang <[email protected]>
[ Upstream commit e5785093b1b45af7ee57d18619b2854a8aed073a ]
ALSA controls should return 1 if the value in the control changed but the control put operation micfil_quality_set() only returns 0 or a negative error code, causing ALSA to not generate any change events.
Add a suitable check in the function before updating the quality variable.
Also enable pm runtime before calling the function micfil_set_quality() to make the regmap cache data align with the value in hardware.
--- sound/soc/fsl/fsl_micfil.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-)
sound/soc/fsl/fsl_micfil.c +26 -2
@@ -181,10 +181,34 @@ static int micfil_quality_set(struct snd_kcontrol *kcontrol, {struct snd_soc_component *cmpnt =snd_soc_kcontrol_component (kcontrol);struct fsl_micfil *micfil =snd_soc_component_get_drvdata (cmpnt); +int val = ucontrol->value.integer.value[0 ]; +bool change = false; +int old_val; +int ret; + +if (val <QUALITY_HIGH || val >QUALITY_VLOW2 ) +return -EINVAL ; + +if (micfil->quality != val) { + ret =pm_runtime_resume_and_get (cmpnt->dev); +if (ret) +return ret; + + old_val = micfil->quality; + micfil->quality = val; + ret =micfil_set_quality (micfil); - micfil->quality = ucontrol->value.integer.value[0 ]; +pm_runtime_put_autosuspend (cmpnt->dev); -return micfil_set_quality (micfil); +if (ret) { + micfil->quality = old_val; +return ret; + } + + change = true; + } + +return change; }static const char *const micfil_hwvad_enable[] = {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 203/666 ASoC: fsl_xcvr: Fix event generation in fsl_xcvr_arc_mode_put()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengjiu Wang <[email protected]>
[ Upstream commit 1b61c8103c9317a9c37fe544c2d83cee1c281149 ]
ALSA controls should return 1 if the value in the control changed but the control put operation fsl_xcvr_arc_mode_put() only returns 0 or a negative error code, causing ALSA to not generate any change events.
Add a suitable check in the function before updating the arc_mode variable.
--- sound/soc/fsl/fsl_xcvr.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
sound/soc/fsl/fsl_xcvr.c +9 -2
@@ -108,10 +108,17 @@ static int fsl_xcvr_arc_mode_put(struct snd_kcontrol *kcontrol,struct fsl_xcvr *xcvr =snd_soc_dai_get_drvdata (dai);struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;unsigned int *item = ucontrol->value.enumerated.item; +int val =snd_soc_enum_item_to_val (e, item[0 ]); +int ret; - xcvr->arc_mode =snd_soc_enum_item_to_val (e, item[0 ]); +if (val <0 || val >1 ) +return -EINVAL ; -return 0 ; + ret = (xcvr->arc_mode != val); + + xcvr->arc_mode = val; + +return ret; } static int fsl_xcvr_arc_mode_get(struct snd_kcontrol *kcontrol,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 204/666 ASoC: fsl_xcvr: Fix event generation in fsl_xcvr_mode_put()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengjiu Wang <[email protected]>
[ Upstream commit 64a496ba976324615b845d60739dfcdae3d57434 ]
ALSA controls should return 1 if the value in the control changed but the control put operation fsl_xcvr_mode_put() only returns 0 or a negative error code, causing ALSA to not generate any change events.
Add a suitable check in the function before updating the mode variable.
--- sound/soc/fsl/fsl_xcvr.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
sound/soc/fsl/fsl_xcvr.c +9 -2
@@ -218,10 +218,17 @@ static int fsl_xcvr_mode_put(struct snd_kcontrol *kcontrol,struct fsl_xcvr *xcvr =snd_soc_dai_get_drvdata (dai);struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;unsigned int *item = ucontrol->value.enumerated.item; +int val =snd_soc_enum_item_to_val (e, item[0 ]);struct snd_soc_card *card = dai->component->card;struct snd_soc_pcm_runtime *rtd; +int ret; + +if (val <FSL_XCVR_MODE_SPDIF || val >FSL_XCVR_MODE_EARC ) +return -EINVAL ; - xcvr->mode =snd_soc_enum_item_to_val (e, item[0 ]); + ret = (xcvr->mode != val); + + xcvr->mode = val;fsl_xcvr_activate_ctl (dai, fsl_xcvr_arc_mode_kctl.name, (xcvr->mode ==FSL_XCVR_MODE_ARC ));
@@ -231,7 +238,7 @@ static int fsl_xcvr_mode_put(struct snd_kcontrol *kcontrol, rtd =snd_soc_get_pcm_runtime (card, card->dai_link); rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK ].substream_count = (xcvr->mode ==FSL_XCVR_MODE_SPDIF ?1 :0 ); -return 0 ; +return ret; } static int fsl_xcvr_mode_get(struct snd_kcontrol *kcontrol,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 205/666 ASoC: fsl_easrc: Check the variable range in fsl_easrc_iec958_put_bits()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengjiu Wang <[email protected]>
[ Upstream commit 00541b86fb578d4949cfdd6aff1f82d43fcf07af ]
Add check of input value's range in fsl_easrc_iec958_put_bits(), otherwise the wrong value may be written from user space.
--- sound/soc/fsl/fsl_easrc.c | 3 +++ 1 file changed, 3 insertions(+)
sound/soc/fsl/fsl_easrc.c +3 -0
@@ -54,6 +54,9 @@ static int fsl_easrc_iec958_put_bits(struct snd_kcontrol *kcontrol,unsigned int regval = ucontrol->value.integer.value[0 ];int ret; +if (regval <EASRC_WIDTH_16_BIT || regval >EASRC_WIDTH_24_BIT ) +return -EINVAL ; + ret = (easrc_priv->bps_iec958[mc->regbase] != regval); easrc_priv->bps_iec958[mc->regbase] = regval;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 206/666 ASoC: fsl_easrc: Fix value type in fsl_easrc_iec958_get_bits()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengjiu Wang <[email protected]>
[ Upstream commit aa21fe4a81458cf469c2615b08cbde5997dde25a ]
The value type of controls "Context 0 IEC958 Bits Per Sample" should be integer, not enumerated, the issue is found by the mixer-test.
--- sound/soc/fsl/fsl_easrc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/fsl/fsl_easrc.c +1 -1
@@ -73,7 +73,7 @@ static int fsl_easrc_iec958_get_bits(struct snd_kcontrol *kcontrol,struct soc_mreg_control *mc = (struct soc_mreg_control *)kcontrol->private_value; - ucontrol->value.enumerated.item[0 ] = easrc_priv->bps_iec958[mc->regbase]; + ucontrol->value.integer.value[0 ] = easrc_priv->bps_iec958[mc->regbase];return 0 ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 207/666 ASoC: fsl_easrc: Change the type for iec958 channel status controls
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengjiu Wang <[email protected]>
[ Upstream commit 47f28a5bd154a95d5aa563dde02a801bd32ddb81 ]
Use the type SNDRV_CTL_ELEM_TYPE_IEC958 for iec958 channel status controls, the original type will cause mixer-test to iterate all 32bit values, which costs a lot of time. And using IEC958 type can reduce the control numbers.
Also enable pm runtime before updating registers to make the regmap cache data align with the value in hardware.
--- sound/soc/fsl/fsl_easrc.c | 118 +++++++++++++++++++++++++++----------- 1 file changed, 84 insertions(+), 34 deletions(-)
sound/soc/fsl/fsl_easrc.c +84 -34
@@ -78,17 +78,47 @@ static int fsl_easrc_iec958_get_bits(struct snd_kcontrol *kcontrol,return 0 ; } +static int fsl_easrc_iec958_info (struct snd_kcontrol *kcontrol, +struct snd_ctl_elem_info *uinfo) +{ + uinfo->type =SNDRV_CTL_ELEM_TYPE_IEC958 ; + uinfo->count =1 ; +return 0 ; +} +static int fsl_easrc_get_reg (struct snd_kcontrol *kcontrol,struct snd_ctl_elem_value *ucontrol) {struct snd_soc_component *component =snd_kcontrol_chip (kcontrol);struct soc_mreg_control *mc = (struct soc_mreg_control *)kcontrol->private_value; -unsigned int regval; +struct fsl_asrc *easrc =snd_soc_component_get_drvdata (component); +unsigned int *regval = (unsigned int *)ucontrol->value.iec958.status; +int ret; + + ret =regmap_read (easrc->regmap,REG_EASRC_CS0 (mc->regbase), ®val[0 ]); +if (ret) +return ret; + + ret =regmap_read (easrc->regmap,REG_EASRC_CS1 (mc->regbase), ®val[1 ]); +if (ret) +return ret; + + ret =regmap_read (easrc->regmap,REG_EASRC_CS2 (mc->regbase), ®val[2 ]); +if (ret) +return ret; - regval =snd_soc_component_read (component, mc->regbase); + ret =regmap_read (easrc->regmap,REG_EASRC_CS3 (mc->regbase), ®val[3 ]); +if (ret) +return ret; + + ret =regmap_read (easrc->regmap,REG_EASRC_CS4 (mc->regbase), ®val[4 ]); +if (ret) +return ret; - ucontrol->value.integer.value[0 ] = regval; + ret =regmap_read (easrc->regmap,REG_EASRC_CS5 (mc->regbase), ®val[5 ]); +if (ret) +return ret;return 0 ; }
@@ -100,22 +130,62 @@ static int fsl_easrc_set_reg(struct snd_kcontrol *kcontrol,struct soc_mreg_control *mc = (struct soc_mreg_control *)kcontrol->private_value;struct fsl_asrc *easrc =snd_soc_component_get_drvdata (component); -unsigned int regval = ucontrol->value.integer.value[0 ]; -bool changed; +unsigned int *regval = (unsigned int *)ucontrol->value.iec958.status; +bool changed, changed_all = false;int ret; - ret =regmap_update_bits_check (easrc->regmap, mc->regbase, -GENMASK (31 ,0 ), regval, &changed); -if (ret !=0 ) + ret =pm_runtime_resume_and_get (component->dev); +if (ret)return ret; -return changed; + ret =regmap_update_bits_check (easrc->regmap,REG_EASRC_CS0 (mc->regbase), +GENMASK (31 ,0 ), regval[0 ], &changed); +if (ret !=0 ) + goto err; + changed_all |= changed; + + ret =regmap_update_bits_check (easrc->regmap,REG_EASRC_CS1 (mc->regbase), +GENMASK (31 ,0 ), regval[1 ], &changed); +if (ret !=0 ) + goto err; + changed_all |= changed; + + ret =regmap_update_bits_check (easrc->regmap,REG_EASRC_CS2 (mc->regbase), +GENMASK (31 ,0 ), regval[2 ], &changed); +if (ret !=0 ) + goto err; + changed_all |= changed; + + ret =regmap_update_bits_check (easrc->regmap,REG_EASRC_CS3 (mc->regbase), +GENMASK (31 ,0 ), regval[3 ], &changed); +if (ret !=0 ) + goto err; + changed_all |= changed; + + ret =regmap_update_bits_check (easrc->regmap,REG_EASRC_CS4 (mc->regbase), +GENMASK (31 ,0 ), regval[4 ], &changed); +if (ret !=0 ) + goto err; + changed_all |= changed; + + ret =regmap_update_bits_check (easrc->regmap,REG_EASRC_CS5 (mc->regbase), +GENMASK (31 ,0 ), regval[5 ], &changed); +if (ret !=0 ) + goto err; + changed_all |= changed; +err: +pm_runtime_put_autosuspend (component->dev); + +if (ret !=0 ) +return ret; +else +return changed_all; }#define SOC_SINGLE_REG_RW (xname, xreg) \ { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = (xname), \ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ - .info = snd_soc_info_xr_sx, .get = fsl_easrc_get_reg, \ + .info = fsl_easrc_iec958_info, .get = fsl_easrc_get_reg, \ .put = fsl_easrc_set_reg, \ .private_value = (unsigned long)&(struct soc_mreg_control) \ { .regbase = xreg, .regcount = 1, .nbits = 32, \
@@ -146,30 +216,10 @@ static const struct snd_kcontrol_new fsl_easrc_snd_controls[] = {SOC_SINGLE_VAL_RW ("Context 2 IEC958 Bits Per Sample" ,2 ),SOC_SINGLE_VAL_RW ("Context 3 IEC958 Bits Per Sample" ,3 ), -SOC_SINGLE_REG_RW ("Context 0 IEC958 CS0" ,REG_EASRC_CS0 (0 )), -SOC_SINGLE_REG_RW ("Context 1 IEC958 CS0" ,REG_EASRC_CS0 (1 )), -SOC_SINGLE_REG_RW ("Context 2 IEC958 CS0" ,REG_EASRC_CS0 (2 )), -SOC_SINGLE_REG_RW ("Context 3 IEC958 CS0" ,REG_EASRC_CS0 (3 )), -SOC_SINGLE_REG_RW ("Context 0 IEC958 CS1" ,REG_EASRC_CS1 (0 )), -SOC_SINGLE_REG_RW ("Context 1 IEC958 CS1" ,REG_EASRC_CS1 (1 )), -SOC_SINGLE_REG_RW ("Context 2 IEC958 CS1" ,REG_EASRC_CS1 (2 )), -SOC_SINGLE_REG_RW ("Context 3 IEC958 CS1" ,REG_EASRC_CS1 (3 )), -SOC_SINGLE_REG_RW ("Context 0 IEC958 CS2" ,REG_EASRC_CS2 (0 )), -SOC_SINGLE_REG_RW ("Context 1 IEC958 CS2" ,REG_EASRC_CS2 (1 )), -SOC_SINGLE_REG_RW ("Context 2 IEC958 CS2" ,REG_EASRC_CS2 (2 )), -SOC_SINGLE_REG_RW ("Context 3 IEC958 CS2" ,REG_EASRC_CS2 (3 )), -SOC_SINGLE_REG_RW ("Context 0 IEC958 CS3" ,REG_EASRC_CS3 (0 )), -SOC_SINGLE_REG_RW ("Context 1 IEC958 CS3" ,REG_EASRC_CS3 (1 )), -SOC_SINGLE_REG_RW ("Context 2 IEC958 CS3" ,REG_EASRC_CS3 (2 )), -SOC_SINGLE_REG_RW ("Context 3 IEC958 CS3" ,REG_EASRC_CS3 (3 )), -SOC_SINGLE_REG_RW ("Context 0 IEC958 CS4" ,REG_EASRC_CS4 (0 )), -SOC_SINGLE_REG_RW ("Context 1 IEC958 CS4" ,REG_EASRC_CS4 (1 )), -SOC_SINGLE_REG_RW ("Context 2 IEC958 CS4" ,REG_EASRC_CS4 (2 )), -SOC_SINGLE_REG_RW ("Context 3 IEC958 CS4" ,REG_EASRC_CS4 (3 )), -SOC_SINGLE_REG_RW ("Context 0 IEC958 CS5" ,REG_EASRC_CS5 (0 )), -SOC_SINGLE_REG_RW ("Context 1 IEC958 CS5" ,REG_EASRC_CS5 (1 )), -SOC_SINGLE_REG_RW ("Context 2 IEC958 CS5" ,REG_EASRC_CS5 (2 )), - SOC_SINGLE_REG_RW("Context 3 IEC958 CS5", REG_EASRC_CS5(3)), +SOC_SINGLE_REG_RW ("Context 0 IEC958 CS" ,0 ), +SOC_SINGLE_REG_RW ("Context 1 IEC958 CS" ,1 ), +SOC_SINGLE_REG_RW ("Context 2 IEC958 CS" ,2 ), + SOC_SINGLE_REG_RW("Context 3 IEC958 CS", 3), };/*
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 208/666 iommu/amd: Remove protection_domain.dev_cnt variable
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vasant Hegde <[email protected]>
[ Upstream commit 743a4bae9fa1480e5f6837f6a55be918d6cd0e16 ]
protection_domain->dev_list tracks list of attached devices to domain. We can use list_* functions on dev_list to get device count. Hence remove 'dev_cnt' variable.
No functional change intended.
Stable-dep-of: faad224fe0f0 ("iommu/amd: Fix clone_alias() to use the original device's devid")
--- drivers/iommu/amd/amd_iommu_types.h | 1 - drivers/iommu/amd/iommu.c | 7 +------ 2 files changed, 1 insertion(+), 7 deletions(-)
drivers/iommu/amd/amd_iommu_types.h +0 -1
@@ -580,7 +580,6 @@ struct protection_domain {u16 id;/* the domain id written to the device table */ enum protection_domain_mode pd_mode;/* Track page table type */ bool dirty_tracking;/* dirty tracking is enabled in the domain */ -unsigned dev_cnt;/* devices assigned to this domain */ unsigned dev_iommu[MAX_IOMMUS ];/* per-IOMMU reference count */ struct mmu_notifier mn;/* mmu notifier for the SVA domain */
drivers/iommu/amd/iommu.c +1 -6
@@ -2068,7 +2068,6 @@ static int do_attach(struct iommu_dev_data *dev_data,/* Do reference counting */ domain->dev_iommu[iommu->index] +=1 ; - domain->dev_cnt +=1 ;/* Setup GCR3 table */ if (pdom_is_sva_capable (domain)) {
@@ -2101,7 +2100,6 @@ static void do_detach(struct iommu_dev_data *dev_data)/* decrease reference counters - needs to happen after the flushes */ domain->dev_iommu[iommu->index] -=1 ; - domain->dev_cnt -=1 ; }/*
@@ -2274,16 +2272,13 @@ static void cleanup_domain(struct protection_domain *domain)lockdep_assert_held (&domain->lock); -if (!domain->dev_cnt) -return ; -while (!list_empty (&domain->dev_list)) { entry =list_first_entry (&domain->dev_list, struct iommu_dev_data, list);BUG_ON (!entry->domain);do_detach (entry); } -WARN_ON (domain->dev_cnt !=0 ); +WARN_ON (!list_empty (&domain->dev_list)); }void protection_domain_free (struct protection_domain *domain)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 209/666 iommu/amd: xarray to track protection_domain->iommu list
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vasant Hegde <[email protected]>
[ Upstream commit d16041124de1dea4389b5e6b330657f34f8c0492 ]
Use xarray to track IOMMU attached to protection domain instead of static array of MAX_IOMMUS. Also add lockdep assertion.
Stable-dep-of: faad224fe0f0 ("iommu/amd: Fix clone_alias() to use the original device's devid")
--- drivers/iommu/amd/amd_iommu_types.h | 8 ++- drivers/iommu/amd/iommu.c | 89 +++++++++++++++++++++++------ 2 files changed, 77 insertions(+), 20 deletions(-)
drivers/iommu/amd/amd_iommu_types.h +7 -1
@@ -567,6 +567,12 @@ struct pdom_dev_data {struct list_head list; }; +/* Keeps track of the IOMMUs attached to protection domain */ +struct pdom_iommu_info { +struct amd_iommu *iommu;/* IOMMUs attach to protection domain */ +u32 refcnt;/* Count of attached dev/pasid per domain/IOMMU */ +}; +/* * This structure contains generic data for IOMMU protection domains * independent of their use.
@@ -580,7 +586,7 @@ struct protection_domain {u16 id;/* the domain id written to the device table */ enum protection_domain_mode pd_mode;/* Track page table type */ bool dirty_tracking;/* dirty tracking is enabled in the domain */ -unsigned dev_iommu[MAX_IOMMUS ];/* per-IOMMU reference count */ +struct xarray iommu_array;/* per-IOMMU reference count */ struct mmu_notifier mn;/* mmu notifier for the SVA domain */ struct list_head dev_data_list;/* List of pdom_dev_data */
drivers/iommu/amd/iommu.c +70 -19
147 lines not on this page · raw message
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 210/666 iommu/amd: Do not detach devices in domain free path
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vasant Hegde <[email protected]>
[ Upstream commit 07bbd660dbd6ff03907d9ddbdfe9deabbd18ac4d ]
All devices attached to a protection domain must be freed before calling domain free. Hence do not try to free devices in domain free path. Continue to throw warning if pdom->dev_list is not empty so that any potential issues can be fixed.
Stable-dep-of: faad224fe0f0 ("iommu/amd: Fix clone_alias() to use the original device's devid")
--- drivers/iommu/amd/iommu.c | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-)
drivers/iommu/amd/iommu.c +1 -25
@@ -2316,21 +2316,6 @@ static struct iommu_group *amd_iommu_device_group(struct device *dev)* *****************************************************************************/ -static void cleanup_domain (struct protection_domain *domain) -{ -struct iommu_dev_data *entry; - -lockdep_assert_held (&domain->lock); - -while (!list_empty (&domain->dev_list)) { - entry =list_first_entry (&domain->dev_list, - struct iommu_dev_data, list); -BUG_ON (!entry->domain); -do_detach (entry); - } -WARN_ON (!list_empty (&domain->dev_list)); -} -void protection_domain_free (struct protection_domain *domain) {WARN_ON (!list_empty (&domain->dev_list));
@@ -2498,16 +2483,7 @@ amd_iommu_domain_alloc_user(struct device *dev, u32 flags,void amd_iommu_domain_free (struct iommu_domain *dom) { -struct protection_domain *domain; -unsigned long flags; - - domain =to_pdomain (dom); - -spin_lock_irqsave (&domain->lock, flags); - -cleanup_domain (domain); - -spin_unlock_irqrestore (&domain->lock, flags); +struct protection_domain *domain =to_pdomain (dom);protection_domain_free (domain); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 211/666 iommu/amd: Reduce domain lock scope in attach device path
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vasant Hegde <[email protected]>
[ Upstream commit d6b47dec368400a62d2b9d44c8e136fc15eac72c ]
Currently attach device path takes protection domain lock followed by dev_data lock. Most of the operations in this function is specific to device data except pdom_attach_iommu() where it updates protection domain structure. Hence reduce the scope of protection domain lock.
Note that this changes the locking order. Now it takes device lock before taking doamin lock (group->mutex -> dev_data->lock -> pdom->lock). dev_data->lock is used only in device attachment path. So changing order is fine. It will not create any issue.
Finally move numa node assignment to pdom_attach_iommu().
Stable-dep-of: faad224fe0f0 ("iommu/amd: Fix clone_alias() to use the original device's devid")
--- drivers/iommu/amd/iommu.c | 52 ++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 22 deletions(-)
drivers/iommu/amd/iommu.c +30 -22
@@ -2057,16 +2057,23 @@ static int pdom_attach_iommu(struct amd_iommu *iommu, struct protection_domain *pdom) {struct pdom_iommu_info *pdom_iommu_info, *curr; +struct io_pgtable_cfg *cfg = &pdom->iop.pgtbl.cfg; +unsigned long flags; +int ret =0 ; + +spin_lock_irqsave (&pdom->lock, flags); pdom_iommu_info =xa_load (&pdom->iommu_array, iommu->index);if (pdom_iommu_info) { pdom_iommu_info->refcnt++; -return 0 ; + goto out_unlock; } pdom_iommu_info =kzalloc (sizeof (*pdom_iommu_info),GFP_ATOMIC ); -if (!pdom_iommu_info) -return -ENOMEM ; +if (!pdom_iommu_info) { + ret = -ENOMEM ; + goto out_unlock; + } pdom_iommu_info->iommu = iommu; pdom_iommu_info->refcnt =1 ;
@@ -2075,43 +2082,52 @@ static int pdom_attach_iommu(struct amd_iommu *iommu, NULL, pdom_iommu_info, GFP_ATOMIC);if (curr) {kfree (pdom_iommu_info); -return -ENOSPC ; + ret = -ENOSPC ; + goto out_unlock; } -return 0 ; +/* Update NUMA Node ID */ +if (cfg->amd.nid ==NUMA_NO_NODE ) + cfg->amd.nid =dev_to_node (&iommu->dev->dev); + +out_unlock: +spin_unlock_irqrestore (&pdom->lock, flags); +return ret; }static void pdom_detach_iommu (struct amd_iommu *iommu,struct protection_domain *pdom) {struct pdom_iommu_info *pdom_iommu_info; +unsigned long flags; + +spin_lock_irqsave (&pdom->lock, flags); pdom_iommu_info =xa_load (&pdom->iommu_array, iommu->index); -if (!pdom_iommu_info) +if (!pdom_iommu_info) { +spin_unlock_irqrestore (&pdom->lock, flags);return ; + } pdom_iommu_info->refcnt--;if (pdom_iommu_info->refcnt ==0 ) {xa_erase (&pdom->iommu_array, iommu->index);kfree (pdom_iommu_info); } + +spin_unlock_irqrestore (&pdom->lock, flags); }static int do_attach (struct iommu_dev_data *dev_data,struct protection_domain *domain) {struct amd_iommu *iommu =get_amd_iommu_from_dev_data (dev_data); -struct io_pgtable_cfg *cfg = &domain->iop.pgtbl.cfg;int ret =0 ;/* Update data structures */ dev_data->domain = domain;list_add (&dev_data->list, &domain->dev_list); -/* Update NUMA Node ID */ -if (cfg->amd.nid ==NUMA_NO_NODE ) - cfg->amd.nid =dev_to_node (dev_data->dev); -/* Do reference counting */ ret =pdom_attach_iommu (iommu, domain);if (ret)
@@ -2133,12 +2149,15 @@ static void do_detach(struct iommu_dev_data *dev_data) {struct protection_domain *domain = dev_data->domain;struct amd_iommu *iommu =get_amd_iommu_from_dev_data (dev_data); +unsigned long flags;/* Clear DTE and flush the entry */ dev_update_dte (dev_data, false);/* Flush IOTLB and wait for the flushes to finish */ +spin_lock_irqsave (&domain->lock, flags);amd_iommu_domain_flush_all (domain); +spin_unlock_irqrestore (&domain->lock, flags);/* Clear GCR3 table */ if (pdom_is_sva_capable (domain))
@@ -2160,11 +2179,8 @@ static int attach_device(struct device *dev, struct protection_domain *domain) {struct iommu_dev_data *dev_data; -unsigned long flags;int ret =0 ; -spin_lock_irqsave (&domain->lock, flags); - dev_data =dev_iommu_priv_get (dev);spin_lock (&dev_data->lock);
@@ -2179,8 +2195,6 @@ static int attach_device(struct device *dev, out:spin_unlock (&dev_data->lock); -spin_unlock_irqrestore (&domain->lock, flags); -return ret; }
@@ -2190,13 +2204,9 @@ static int attach_device(struct device *dev,static void detach_device (struct device *dev) {struct iommu_dev_data *dev_data =dev_iommu_priv_get (dev); -struct protection_domain *domain = dev_data->domain;struct amd_iommu *iommu =get_amd_iommu_from_dev_data (dev_data); -unsigned long flags;bool ppr = dev_data->ppr; -spin_lock_irqsave (&domain->lock, flags); -spin_lock (&dev_data->lock);/*
@@ -2220,8 +2230,6 @@ static void detach_device(struct device *dev) out:spin_unlock (&dev_data->lock); -spin_unlock_irqrestore (&domain->lock, flags); -/* Remove IOPF handler */ if (ppr)amd_iommu_iopf_remove_device (iommu, dev_data);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 212/666 iommu/amd: Rearrange attach device code
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vasant Hegde <[email protected]>
[ Upstream commit 4b18ef8491b06e353e8801705092cc292582cb7a ]
attach_device() is just holding lock and calling do_attach(). There is not need to have another function. Just move do_attach() code to attach_device(). Similarly move do_detach() code to detach_device().
Stable-dep-of: faad224fe0f0 ("iommu/amd: Fix clone_alias() to use the original device's devid")
--- drivers/iommu/amd/iommu.c | 91 ++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 55 deletions(-)
drivers/iommu/amd/iommu.c +36 -55
@@ -2118,12 +2118,24 @@ static void pdom_detach_iommu(struct amd_iommu *iommu,spin_unlock_irqrestore (&pdom->lock, flags); } -static int do_attach (struct iommu_dev_data *dev_data, -struct protection_domain *domain) +/* +* If a device is not yet associated with a domain, this function makes the +* device visible in the domain +*/ +static int attach_device (struct device *dev, +struct protection_domain *domain) { +struct iommu_dev_data *dev_data =dev_iommu_priv_get (dev);struct amd_iommu *iommu =get_amd_iommu_from_dev_data (dev_data);int ret =0 ; +spin_lock (&dev_data->lock); + +if (dev_data->domain !=NULL ) { + ret = -EBUSY ; + goto out; + } +/* Update data structures */ dev_data->domain = domain;list_add (&dev_data->list, &domain->dev_list);
@@ -2131,67 +2143,17 @@ static int do_attach(struct iommu_dev_data *dev_data,/* Do reference counting */ ret =pdom_attach_iommu (iommu, domain);if (ret) -return ret; + goto out;/* Setup GCR3 table */ if (pdom_is_sva_capable (domain)) { ret =init_gcr3_table (dev_data, domain);if (ret) {pdom_detach_iommu (iommu, domain); -return ret; + goto out; } } -return ret; -} - -static void do_detach (struct iommu_dev_data *dev_data) -{ -struct protection_domain *domain = dev_data->domain; -struct amd_iommu *iommu =get_amd_iommu_from_dev_data (dev_data); -unsigned long flags; - -/* Clear DTE and flush the entry */ -dev_update_dte (dev_data, false); - -/* Flush IOTLB and wait for the flushes to finish */ -spin_lock_irqsave (&domain->lock, flags); -amd_iommu_domain_flush_all (domain); -spin_unlock_irqrestore (&domain->lock, flags); - -/* Clear GCR3 table */ -if (pdom_is_sva_capable (domain)) -destroy_gcr3_table (dev_data, domain); - -/* Update data structures */ - dev_data->domain =NULL ; -list_del (&dev_data->list); - -/* decrease reference counters - needs to happen after the flushes */ -pdom_detach_iommu (iommu, domain); -} - -/* -* If a device is not yet associated with a domain, this function makes the -* device visible in the domain -*/ -static int attach_device (struct device *dev, -struct protection_domain *domain) -{ -struct iommu_dev_data *dev_data; -int ret =0 ; - - dev_data =dev_iommu_priv_get (dev); - -spin_lock (&dev_data->lock); - -if (dev_data->domain !=NULL ) { - ret = -EBUSY ; - goto out; - } - - ret =do_attach (dev_data, domain); - out:spin_unlock (&dev_data->lock);
@@ -2205,7 +2167,9 @@ static void detach_device(struct device *dev) {struct iommu_dev_data *dev_data =dev_iommu_priv_get (dev);struct amd_iommu *iommu =get_amd_iommu_from_dev_data (dev_data); +struct protection_domain *domain = dev_data->domain;bool ppr = dev_data->ppr; +unsigned long flags;spin_lock (&dev_data->lock);
@@ -2225,7 +2189,24 @@ static void detach_device(struct device *dev) dev_data->ppr = false; } -do_detach (dev_data); +/* Clear DTE and flush the entry */ +dev_update_dte (dev_data, false); + +/* Flush IOTLB and wait for the flushes to finish */ +spin_lock_irqsave (&domain->lock, flags); +amd_iommu_domain_flush_all (domain); +spin_unlock_irqrestore (&domain->lock, flags); + +/* Clear GCR3 table */ +if (pdom_is_sva_capable (domain)) +destroy_gcr3_table (dev_data, domain); + +/* Update data structures */ + dev_data->domain =NULL ; +list_del (&dev_data->list); + +/* decrease reference counters - needs to happen after the flushes */ +pdom_detach_iommu (iommu, domain); out:spin_unlock (&dev_data->lock);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 213/666 iommu/amd: Convert dev_data lock from spinlock to mutex
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vasant Hegde <[email protected]>
[ Upstream commit e843aedbeb82b17a5fe6172449bff133fc8b68a1 ]
Currently in attach device path it takes dev_data->spinlock. But as per design attach device path can sleep. Also if device is PRI capable then it adds device to IOMMU fault handler queue which takes mutex. Hence currently PRI enablement is done outside dev_data lock.
Covert dev_data lock from spinlock to mutex so that it follows the design and also PRI enablement can be done properly.
Stable-dep-of: faad224fe0f0 ("iommu/amd: Fix clone_alias() to use the original device's devid")
--- drivers/iommu/amd/amd_iommu_types.h | 2 +- drivers/iommu/amd/iommu.c | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-)
drivers/iommu/amd/amd_iommu_types.h +1 -1
@@ -838,7 +838,7 @@ struct devid_map {*/ struct iommu_dev_data {/*Protect against attach/detach races */ -spinlock_t lock; +struct mutex mutex;struct list_head list;/* For domain->dev_list */ struct llist_node dev_data_list;/* For global dev_data_list */
drivers/iommu/amd/iommu.c +7 -7
@@ -225,7 +225,7 @@ static struct iommu_dev_data *alloc_dev_data(struct amd_iommu *iommu, u16 devid)if (!dev_data)return NULL ; -spin_lock_init (&dev_data->lock); +mutex_init (&dev_data->mutex); dev_data->devid = devid;ratelimit_default_init (&dev_data->rs);
@@ -2129,7 +2129,7 @@ static int attach_device(struct device *dev,struct amd_iommu *iommu =get_amd_iommu_from_dev_data (dev_data);int ret =0 ; -spin_lock (&dev_data->lock); +mutex_lock (&dev_data->mutex);if (dev_data->domain !=NULL ) { ret = -EBUSY ;
@@ -2155,7 +2155,7 @@ static int attach_device(struct device *dev, } out: -spin_unlock (&dev_data->lock); +mutex_unlock (&dev_data->mutex);return ret; }
@@ -2171,7 +2171,7 @@ static void detach_device(struct device *dev)bool ppr = dev_data->ppr;unsigned long flags; -spin_lock (&dev_data->lock); +mutex_lock (&dev_data->mutex);/* * First check if the device is still attached. It might already
@@ -2209,7 +2209,7 @@ static void detach_device(struct device *dev)pdom_detach_iommu (iommu, domain); out: -spin_unlock (&dev_data->lock); +mutex_unlock (&dev_data->mutex);/* Remove IOPF handler */ if (ppr)
@@ -2486,9 +2486,9 @@ static int blocked_domain_attach_device(struct iommu_domain *domain,detach_device (dev);/* Clear DTE and flush the entry */ -spin_lock (&dev_data->lock); +mutex_lock (&dev_data->mutex);dev_update_dte (dev_data, false); -spin_unlock (&dev_data->lock); +mutex_unlock (&dev_data->mutex);return 0 ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 214/666 iommu/amd: Introduce helper function to update 256-bit DTE
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Suravee Suthikulpanit <[email protected]>
[ Upstream commit 8b3f78733814b180089a400743b6f19d118aec62 ]
The current implementation does not follow 128-bit write requirement to update DTE as specified in the AMD I/O Virtualization Techonology (IOMMU) Specification.
Therefore, modify the struct dev_table_entry to contain union of u128 data array, and introduce a helper functions update_dte256() to update DTE using two 128-bit cmpxchg operations to update 256-bit DTE with the modified structure, and take into account the DTE[V, GV] bits when programming the DTE to ensure proper order of DTE programming and flushing.
In addition, introduce a per-DTE spin_lock struct dev_data.dte_lock to provide synchronization when updating the DTE to prevent cmpxchg128 failure.
Stable-dep-of: faad224fe0f0 ("iommu/amd: Fix clone_alias() to use the original device's devid")
--- drivers/iommu/amd/amd_iommu_types.h | 10 ++- drivers/iommu/amd/iommu.c | 123 ++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 1 deletion(-)
drivers/iommu/amd/amd_iommu_types.h +9 -1
@@ -426,9 +426,13 @@#define DTE_GCR3_SHIFT_C 43#define DTE_GPT_LEVEL_SHIFT 54 +#define DTE_GPT_LEVEL_MASK GENMASK_ULL(55, 54)#define GCR3_VALID 0x01ULL +/* DTE[128:179] | DTE[184:191] */ +#define DTE_DATA2_INTR_MASK ~GENMASK_ULL(55, 52) +#define IOMMU_PAGE_MASK (((1ULL << 52) - 1) & ~0xfffULL)#define IOMMU_PTE_PRESENT (pte) ((pte) & IOMMU_PTE_PR)#define IOMMU_PTE_DIRTY (pte) ((pte) & IOMMU_PTE_HD)
@@ -839,6 +843,7 @@ struct devid_map {struct iommu_dev_data {/*Protect against attach/detach races */ struct mutex mutex; +spinlock_t dte_lock;/* DTE lock for 256-bit access */ struct list_head list;/* For domain->dev_list */ struct llist_node dev_data_list;/* For global dev_data_list */
@@ -889,7 +894,10 @@ extern struct amd_iommu *amd_iommus[MAX_IOMMUS];* Structure defining one entry in the device table */ struct dev_table_entry { -u64 data[4 ]; +union { +u64 data[4 ]; +u128 data128[2 ]; + }; };/*
drivers/iommu/amd/iommu.c +123 -0
147 lines not on this page · raw message
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 215/666 iommu/amd: Introduce helper function get_dte256()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Suravee Suthikulpanit <[email protected]>
[ Upstream commit a2ce608a1eb65c2af99c58b63eae557165a0da87 ]
And use it in clone_alias() along with update_dte256(). Also use get_dte256() in dump_dte_entry().
Stable-dep-of: faad224fe0f0 ("iommu/amd: Fix clone_alias() to use the original device's devid")
--- drivers/iommu/amd/iommu.c | 62 ++++++++++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 11 deletions(-)
drivers/iommu/amd/iommu.c +51 -11
@@ -79,6 +79,8 @@ static void set_dte_entry(struct amd_iommu *iommu,static void iommu_flush_dte_sync (struct amd_iommu *iommu,u16 devid); +static struct iommu_dev_data *find_dev_data (struct amd_iommu *iommu,u16 devid); +/**************************************************************************** * * Helper functions
@@ -196,6 +198,21 @@ static void update_dte256(struct amd_iommu *iommu, struct iommu_dev_data *dev_daspin_unlock_irqrestore (&dev_data->dte_lock, flags); } +static void get_dte256 (struct amd_iommu *iommu,struct iommu_dev_data *dev_data, +struct dev_table_entry *dte) +{ +unsigned long flags; +struct dev_table_entry *ptr; +struct dev_table_entry *dev_table =get_dev_table (iommu); + + ptr = &dev_table[dev_data->devid]; + +spin_lock_irqsave (&dev_data->dte_lock, flags); + dte->data128[0 ] = ptr->data128[0 ]; + dte->data128[1 ] = ptr->data128[1 ]; +spin_unlock_irqrestore (&dev_data->dte_lock, flags); +} +static inline bool pdom_is_v2_pgtbl_mode (struct protection_domain *pdom) {return (pdom && (pdom->pd_mode ==PD_MODE_V2 ));
@@ -367,9 +384,11 @@ static struct iommu_dev_data *search_dev_data(struct amd_iommu *iommu, u16 devidstatic int clone_alias (struct pci_dev *pdev,u16 alias,void *data) { +struct dev_table_entry new;struct amd_iommu *iommu; -struct dev_table_entry *dev_table; +struct iommu_dev_data *dev_data, *alias_data;u16 devid =pci_dev_id (pdev); +int ret =0 ;if (devid == alias)return 0 ;
@@ -378,13 +397,27 @@ static int clone_alias(struct pci_dev *pdev, u16 alias, void *data)if (!iommu)return 0 ; -amd_iommu_set_rlookup_table (iommu, alias); - dev_table =get_dev_table (iommu); -memcpy (dev_table[alias].data, - dev_table[devid].data, -sizeof (dev_table[alias].data)); +/* Copy the data from pdev */ + dev_data =dev_iommu_priv_get (&pdev->dev); +if (!dev_data) { +pr_err ("%s : Failed to get dev_data for 0x%x\n" , __func__, devid); + ret = -EINVAL ; + goto out; + } +get_dte256 (iommu, dev_data, &new); -return 0 ; +/* Setup alias */ + alias_data =find_dev_data (iommu, alias); +if (!alias_data) { +pr_err ("%s : Failed to get alias dev_data for 0x%x\n" , __func__, alias); + ret = -EINVAL ; + goto out; + } +update_dte256 (iommu, alias_data, &new); + +amd_iommu_set_rlookup_table (iommu, alias); +out: +return ret; }static void clone_aliases (struct amd_iommu *iommu,struct device *dev)
@@ -657,6 +690,12 @@ static int iommu_init_device(struct amd_iommu *iommu, struct device *dev)return -ENOMEM ; dev_data->dev = dev; + +/* +* The dev_iommu_priv_set() needes to be called before setup_aliases. +* Otherwise, subsequent call to dev_iommu_priv_get() will fail. +*/ +dev_iommu_priv_set (dev, dev_data);setup_aliases (iommu, dev);/*
@@ -670,8 +709,6 @@ static int iommu_init_device(struct amd_iommu *iommu, struct device *dev) dev_data->flags =pdev_get_caps (to_pci_dev (dev)); } -dev_iommu_priv_set (dev, dev_data); -return 0 ; }
@@ -718,10 +755,13 @@ static void amd_iommu_uninit_device(struct device *dev)static void dump_dte_entry (struct amd_iommu *iommu,u16 devid) {int i; -struct dev_table_entry *dev_table =get_dev_table (iommu); +struct dev_table_entry dte; +struct iommu_dev_data *dev_data =find_dev_data (iommu, devid); + +get_dte256 (iommu, dev_data, &dte);for (i =0 ; i <4 ; ++i) -pr_err ("DTE[%d]: %016llx\n" , i, dev_table[devid].data[i]); +pr_err ("DTE[%d]: %016llx\n" , i, dte.data[i]); }static void dump_command (unsigned long phys_addr)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 216/666 iommu/amd: Fix clone_alias() to use the original devices devid
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vasant Hegde <[email protected]>
[ Upstream commit faad224fe0f0857a04ff2eb3c90f0de57f47d0f3 ]
Currently clone_alias() assumes first argument (pdev) is always the original device pointer. This function is called by pci_for_each_dma_alias() which based on topology decides to send original or alias device details in first argument.
This meant that the source devid used to look up and copy the DTE may be incorrect, leading to wrong or stale DTE entries being propagated to alias device.
Fix this by passing the original pdev as the opaque data argument to both the direct clone_alias() call and pci_for_each_dma_alias(). Inside clone_alias(), retrieve the original device from data and compute devid from it.
--- drivers/iommu/amd/iommu.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/iommu/amd/iommu.c +4 -3
@@ -382,11 +382,12 @@ static struct iommu_dev_data *search_dev_data(struct amd_iommu *iommu, u16 devidreturn NULL ; } -static int clone_alias (struct pci_dev *pdev,u16 alias,void *data) +static int clone_alias (struct pci_dev *pdev_origin,u16 alias,void *data) {struct dev_table_entry new;struct amd_iommu *iommu;struct iommu_dev_data *dev_data, *alias_data; +struct pci_dev *pdev = data;u16 devid =pci_dev_id (pdev);int ret =0 ;
@@ -433,9 +434,9 @@ static void clone_aliases(struct amd_iommu *iommu, struct device *dev)* part of the PCI DMA aliases if it's bus differs * from the original device. */ -clone_alias (pdev, iommu->pci_seg->alias_table[pci_dev_id (pdev)],NULL ); +clone_alias (pdev, iommu->pci_seg->alias_table[pci_dev_id (pdev)], pdev); -pci_for_each_dma_alias (pdev, clone_alias,NULL ); +pci_for_each_dma_alias (pdev, clone_alias, pdev); }static void setup_aliases (struct amd_iommu *iommu,struct device *dev)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 217/666 ASoC: qcom: qdsp6: topology: check widget type before accessing data
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivas Kandagatla <[email protected]>
[ Upstream commit d5bfdd28e0cdd45043ae6e0ac168a451d59283dc ]
Check widget type before accessing the private data, as this could a virtual widget which is no associated with a dsp graph, container and module. Accessing witout check could lead to incorrect memory access.
--- sound/soc/qcom/qdsp6/topology.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
sound/soc/qcom/qdsp6/topology.c +5 -3
@@ -930,9 +930,6 @@ static int audioreach_widget_unload(struct snd_soc_component *scomp,struct audioreach_container *cont;struct audioreach_module *mod; - mod = dobj->private; - cont = mod->container; -if (w->id == snd_soc_dapm_mixer) {/* virtual widget */ struct snd_ar_control *scontrol = dobj->private;
@@ -941,6 +938,11 @@ static int audioreach_widget_unload(struct snd_soc_component *scomp,kfree (scontrol);return 0 ; } + mod = dobj->private; +if (!mod) +return 0 ; + + cont = mod->container;mutex_lock (&apm->lock);idr_remove (&apm->modules_idr, mod->instance_id);
Signature · 1 line
2.53.0