Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 10/10] drm: of: forbid bridge-only calls to drm_of_find_panel_or_bridge()
From: Luca Ceresoli @ 2026-04-14  7:02 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
	Jessica Zhang, Sean Paul, Marijn Suijten, Xinliang Liu, Tian Tao,
	Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
	Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Tomi Valkeinen, Michal Simek,
	Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, linux-arm-kernel
In-Reply-To: <nligqvm3lq6n556onglmb345arxztd4pc6fboo4yrs3bfu27eu@uiyu2xklnexb>

Hello Dmitry, Maxime,

On Mon Apr 13, 2026 at 8:04 PM CEST, Dmitry Baryshkov wrote:
> On Mon, Apr 13, 2026 at 03:58:42PM +0200, Luca Ceresoli wrote:
>> Up to now drm_of_find_panel_or_bridge() can be called with a bridge pointer
>> only, a panel pointer only, or both a bridge and a panel pointers. The
>> logic to handle all the three cases is somewhat complex to read however.
>>
>> Now all bridge-only callers have been converted to
>> of_drm_get_bridge_by_endpoint(), which is simpler and handles bridge
>> refcounting. So forbid new bridge-only users by mandating a non-NULL panel
>> pointer in the docs and in the sanity checks along with a warning.
>
> Are there remaining users which still use either the bridge or the
> panel? Would it be possible / better to drop the two-arg version?

Yes. I counted ~20 panel+bridge and 4 panel-only callers with this series
applied, and on top of those there are devm_drm_of_get_bridge() and
drmm_of_get_bridge() which to me are the real issue because they make it
impossible to correctly handle bridge lifetime.

We discussed this with both you and Maxime a while back. AFAIK Maxime has a
plan to make every panel automatically instantiate a panel_bridge. I think
that's the only reasonable approach to get rid of
drm_of_find_panel_or_bridge() + *_of_get_bridge() and make bridge lifetime
easier and safe.

@Maxime, do you have updates on that idea?

Best regards,
Luca

--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


^ permalink raw reply

* Re: [PATCH] arm64/hwcap: Include kernel-hwcap.h in list of generated files
From: Anshuman Khandual @ 2026-04-14  6:55 UTC (permalink / raw)
  To: Mark Brown, Catalin Marinas, Will Deacon
  Cc: Marek Vasut, linux-arm-kernel, linux-kernel
In-Reply-To: <20260413-arm64-hwcap-gen-fix-v1-1-26c56aed6908@kernel.org>



On 13/04/26 9:14 PM, Mark Brown wrote:
> When adding generation for the kernel internal constants for hwcaps the
> generated file was not explicitly flagged as such in the build system,
> causing it to be regenerated on each build. This wasn't obvious when the
> series the change was included in was developed since it was all about
> changes that trigger rebuilds anyway.
> 
> Fixes: abed23c3c44f5 (arm64/hwcap: Generate the KERNEL_HWCAP_ definitions for the hwcaps)
> Reported-by: Marek Vasut <marex@nabladev.com>
> Signed-off-by: Mark Brown <broonie@kernel.org>

Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>

> ---
>  arch/arm64/include/asm/Kbuild | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
> index d2ff8f6c3231..31441790b808 100644
> --- a/arch/arm64/include/asm/Kbuild
> +++ b/arch/arm64/include/asm/Kbuild
> @@ -17,4 +17,5 @@ generic-y += parport.h
>  generic-y += user.h
>  
>  generated-y += cpucap-defs.h
> +generated-y += kernel-hwcap.h
>  generated-y += sysreg-defs.h
> 
> ---
> base-commit: abed23c3c44f565dc812563ac015be70dd61e97b
> change-id: 20260413-arm64-hwcap-gen-fix-ecb4bb6dbb91
> 
> Best regards,
> --  
> Mark Brown <broonie@kernel.org>
> 
> 



^ permalink raw reply

* [PATCH net v2] net: airoha: Add missing bits in airoha_qdma_cleanup_tx_queue()
From: Lorenzo Bianconi @ 2026-04-14  6:50 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Lorenzo Bianconi
  Cc: linux-arm-kernel, linux-mediatek, netdev

Similar to airoha_qdma_cleanup_rx_queue(), reset DMA TX descriptors in
airoha_qdma_cleanup_tx_queue routine. Moreover, reset TX_DMA_IDX to
TX_CPU_IDX to notify the NIC the QDMA TX ring is empty.

Fixes: 23020f0493270 ("net: airoha: Introduce ethernet support for EN7581 SoC")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
Changes in v2:
- Move q->ndesc initialization at end of airoha_qdma_init_tx routine in
  order to avoid any possible NULL pointer dereference in
  airoha_qdma_cleanup_tx_queue()
- Check if q->tx_list is empty in airoha_qdma_cleanup_tx_queue()
- Link to v1: https://lore.kernel.org/r/20260410-airoha_qdma_cleanup_tx_queue-fix-net-v1-1-b7171c8f1e78@kernel.org
---
 drivers/net/ethernet/airoha/airoha_eth.c | 41 ++++++++++++++++++++++++++------
 1 file changed, 34 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 9e995094c32a..3c1a2bc68c42 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -966,27 +966,27 @@ static int airoha_qdma_init_tx_queue(struct airoha_queue *q,
 	dma_addr_t dma_addr;
 
 	spin_lock_init(&q->lock);
-	q->ndesc = size;
 	q->qdma = qdma;
 	q->free_thr = 1 + MAX_SKB_FRAGS;
 	INIT_LIST_HEAD(&q->tx_list);
 
-	q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry),
+	q->entry = devm_kzalloc(eth->dev, size * sizeof(*q->entry),
 				GFP_KERNEL);
 	if (!q->entry)
 		return -ENOMEM;
 
-	q->desc = dmam_alloc_coherent(eth->dev, q->ndesc * sizeof(*q->desc),
+	q->desc = dmam_alloc_coherent(eth->dev, size * sizeof(*q->desc),
 				      &dma_addr, GFP_KERNEL);
 	if (!q->desc)
 		return -ENOMEM;
 
-	for (i = 0; i < q->ndesc; i++) {
+	for (i = 0; i < size; i++) {
 		u32 val = FIELD_PREP(QDMA_DESC_DONE_MASK, 1);
 
 		list_add_tail(&q->entry[i].list, &q->tx_list);
 		WRITE_ONCE(q->desc[i].ctrl, cpu_to_le32(val));
 	}
+	q->ndesc = size;
 
 	/* xmit ring drop default setting */
 	airoha_qdma_set(qdma, REG_TX_RING_BLOCKING(qid),
@@ -1051,13 +1051,17 @@ static int airoha_qdma_init_tx(struct airoha_qdma *qdma)
 
 static void airoha_qdma_cleanup_tx_queue(struct airoha_queue *q)
 {
-	struct airoha_eth *eth = q->qdma->eth;
-	int i;
+	struct airoha_qdma *qdma = q->qdma;
+	struct airoha_eth *eth = qdma->eth;
+	int i, qid = q - &qdma->q_tx[0];
+	struct airoha_queue_entry *e;
+	u16 index = 0;
 
 	spin_lock_bh(&q->lock);
 	for (i = 0; i < q->ndesc; i++) {
-		struct airoha_queue_entry *e = &q->entry[i];
+		struct airoha_qdma_desc *desc = &q->desc[i];
 
+		e = &q->entry[i];
 		if (!e->dma_addr)
 			continue;
 
@@ -1067,8 +1071,31 @@ static void airoha_qdma_cleanup_tx_queue(struct airoha_queue *q)
 		e->dma_addr = 0;
 		e->skb = NULL;
 		list_add_tail(&e->list, &q->tx_list);
+
+		/* Reset DMA descriptor */
+		WRITE_ONCE(desc->ctrl, 0);
+		WRITE_ONCE(desc->addr, 0);
+		WRITE_ONCE(desc->data, 0);
+		WRITE_ONCE(desc->msg0, 0);
+		WRITE_ONCE(desc->msg1, 0);
+		WRITE_ONCE(desc->msg2, 0);
+
 		q->queued--;
 	}
+
+	if (!list_empty(&q->tx_list)) {
+		e = list_first_entry(&q->tx_list, struct airoha_queue_entry,
+				     list);
+		index = e - q->entry;
+	}
+	/* Set TX_DMA_IDX to TX_CPU_IDX to notify the hw the QDMA TX ring is
+	 * empty.
+	 */
+	airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK,
+			FIELD_PREP(TX_RING_CPU_IDX_MASK, index));
+	airoha_qdma_rmw(qdma, REG_TX_DMA_IDX(qid), TX_RING_DMA_IDX_MASK,
+			FIELD_PREP(TX_RING_DMA_IDX_MASK, index));
+
 	spin_unlock_bh(&q->lock);
 }
 

---
base-commit: 2cd7e6971fc2787408ceef17906ea152791448cf
change-id: 20260410-airoha_qdma_cleanup_tx_queue-fix-net-93375f5ee80f

Best regards,
-- 
Lorenzo Bianconi <lorenzo@kernel.org>



^ permalink raw reply related

* Re: [PATCH net] net: airoha: Add missing bits in airoha_qdma_cleanup_tx_queue()
From: Lorenzo Bianconi @ 2026-04-14  6:50 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: andrew+netdev, davem, edumazet, pabeni, linux-arm-kernel,
	linux-mediatek, netdev
In-Reply-To: <20260413225709.3648413-1-kuba@kernel.org>

[-- Attachment #1: Type: text/plain, Size: 3295 bytes --]

> This is an AI-generated review of your patch. The human sending this
> email has considered the AI review valid, or at least plausible.
> ---
> net: airoha: Add missing bits in airoha_qdma_cleanup_tx_queue()
> 
> This commit resets DMA TX descriptors in airoha_qdma_cleanup_tx_queue
> and synchronizes TX_DMA_IDX to TX_CPU_IDX to notify the hardware that
> the ring is empty.
> 
> > diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
> > index 9285a68f435fe..963ab7b8d166b 100644
> > --- a/drivers/net/ethernet/airoha/airoha_eth.c
> > +++ b/drivers/net/ethernet/airoha/airoha_eth.c
> > @@ -1044,13 +1044,17 @@ static int airoha_qdma_init_tx(struct airoha_qdma *qdma)
> [ ... ]
> >  	spin_lock_bh(&q->lock);
> >  	for (i = 0; i < q->ndesc; i++) {
> > -		struct airoha_queue_entry *e = &q->entry[i];
> > +		struct airoha_qdma_desc *desc = &q->desc[i];
> >  
> > +		e = &q->entry[i];
> 
> Can this result in a NULL pointer dereference?
> 
> If airoha_qdma_init_tx_queue() sets q->ndesc before allocating q->entry and
> q->desc, and devm_kzalloc() fails, the error path jumps to
> airoha_hw_cleanup().
> 
> Because q->ndesc > 0, this cleanup loop would execute and dereference
> q->entry[i] and q->desc[i], which may not have been allocated.

ack, I will fix it in v2.

> 
> [ ... ]
> > +		/* Reset DMA descriptor */
> > +		WRITE_ONCE(desc->ctrl, 0);
> > +		WRITE_ONCE(desc->addr, 0);
> > +		WRITE_ONCE(desc->data, 0);
> > +		WRITE_ONCE(desc->msg0, 0);
> > +		WRITE_ONCE(desc->msg1, 0);
> > +		WRITE_ONCE(desc->msg2, 0);
> 
> Is it safe to modify these DMA descriptors and reset the ring indices below
> without waiting for the hardware DMA engine to become idle?
> 
> In airoha_dev_stop(), the driver clears GLOBAL_CFG_TX_DMA_EN_MASK to request
> the hardware DMA engine to stop, but it does not appear to poll
> GLOBAL_CFG_TX_DMA_BUSY_MASK to ensure it has actually stopped.
> 
> Modifying the DMA descriptors and internal ring indices while the hardware
> is still actively processing in-flight descriptors could potentially lead
> to corrupted DMA fetches or IOMMU faults.

This is already fixed here:
https://lore.kernel.org/netdev/20260411-airoha-fix-ndo_stop-v1-1-caddaa181739@kernel.org/

> 
> >  		q->queued--;
> >  	}
> > +
> > +	e = list_first_entry(&q->tx_list, struct airoha_queue_entry,
> > +			     list);
> > +	index = e - q->entry;
> > +	/* Set TX_DMA_IDX to TX_CPU_IDX to notify the hw the QDMA TX ring is
> > +	 * empty.
> > +	 */
> > +	airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK,
> > +			FIELD_PREP(TX_RING_CPU_IDX_MASK, index));
> > +	airoha_qdma_rmw(qdma, REG_TX_DMA_IDX(qid), TX_RING_DMA_IDX_MASK,
> > +			FIELD_PREP(TX_RING_DMA_IDX_MASK, index));
> 
> Could list_first_entry() be called on an empty list here?
> 
> If q->tx_list is empty (for example, if allocation failed in
> airoha_qdma_init_tx_queue or if no entries had a valid dma_addr), calling
> list_first_entry() returns an invalid pointer.
> 
> The subsequent pointer arithmetic would produce a garbage index value,
> which is then written to the REG_TX_CPU_IDX and REG_TX_DMA_IDX registers.

ack, I will fix it in v2.

Regards,
Lorenzo

> -- 
> pw-bot: cr

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* [PATCH] [v2] ARM: dts: bcm4709: fix bus range assignment
From: Arnd Bergmann @ 2026-04-14  6:47 UTC (permalink / raw)
  To: Florian Fainelli, Hauke Mehrtens, Rafał Miłecki,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Rosen Penev
  Cc: soc, Arnd Bergmann, Broadcom internal kernel review list,
	linux-arm-kernel, devicetree, linux-kernel

From: Arnd Bergmann <arnd@arndb.de>

The netgear r8000 dts file limits the bus range for the first host
bridge to exclude bus 0, but the two devices on the first bus are
explicitly assigned to bus 0, causing a build time warning:

/home/arnd/arm-soc/arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts:142.3-27: Warning (pci_device_bus_num): /axi@18000000/pcie@13000/pcie@0/pcie@0,0/pcie@1,0:bus-range: PCI bus number 0 out of range, expected (1 - 255)
/home/arnd/arm-soc/arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts:142.3-27: Warning (pci_device_bus_num): /axi@18000000/pcie@13000/pcie@0/pcie@0,0/pcie@2,0:bus-range: PCI bus number 0 out of range, expected (1 - 255)

As Rosen mentioned, the bus-range property was a mistake, so just
remove it and keep the reg values pointing to bus 0, which is
allowed by the default bus range of the SoC.

Suggested-by: Rosen Penev <rosenp@gmail.com>
Fixes: 893faf67438c ("ARM: dts: BCM5301X: add root pcie bridges")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts b/arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts
index d170c71cbd76..e85693fba16a 100644
--- a/arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts
+++ b/arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts
@@ -139,7 +139,6 @@ &pcie_bridge1 {
 	pcie@0,0 {
 		device_type = "pci";
 		reg = <0x0000 0 0 0 0>;
-		bus-range = <0x01 0xff>;
 
 		#address-cells = <3>;
 		#size-cells = <2>;
-- 
2.39.5



^ permalink raw reply related

* Re: [PATCH 01/10] drm/bridge: add of_drm_get_bridge_by_endpoint()
From: Luca Ceresoli @ 2026-04-14  6:44 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
	Jessica Zhang, Sean Paul, Marijn Suijten, Xinliang Liu, Tian Tao,
	Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
	Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Tomi Valkeinen, Michal Simek,
	Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, linux-arm-kernel
In-Reply-To: <omlnswxukeqgnatzdvooaashgkfcacjevkvbkm6xt33itgua2k@jcmzll2w6kdq>

Hi Dmitry,

On Mon Apr 13, 2026 at 7:56 PM CEST, Dmitry Baryshkov wrote:
> On Mon, Apr 13, 2026 at 07:07:14PM +0200, Luca Ceresoli wrote:
>> Hi Dmitry, Maxime,
>>
>> thanks Dmitry for the quick feedback!
>>
>> On Mon Apr 13, 2026 at 4:58 PM CEST, Dmitry Baryshkov wrote:
>>
>> >> --- a/drivers/gpu/drm/drm_bridge.c
>> >> +++ b/drivers/gpu/drm/drm_bridge.c
>> >> @@ -1581,6 +1581,52 @@ struct drm_bridge *of_drm_find_bridge(struct device_node *np)
>> >>  	return bridge;
>> >>  }
>> >>  EXPORT_SYMBOL(of_drm_find_bridge);
>> >> +
>> >> +/**
>> >> + * of_drm_get_bridge_by_endpoint - return DRM bridge connected to a port/endpoint
>> >> + * @np: device tree node containing output ports
>> >> + * @port: port in the device tree node, or -1 for the first port found
>> >> + * @endpoint: endpoint in the device tree node, or -1 for the first endpoint found
>> >> + * @bridge: pointer to hold returned drm_bridge, must not be NULL
>> >> + *
>> >> + * Given a DT node's port and endpoint number, find the connected node and
>> >> + * return the associated drm_bridge device.
>> >> + *
>> >> + * The refcount of the returned bridge is incremented. Use drm_bridge_put()
>> >> + * when done with it.
>> >> + *
>> >> + * Returns zero (and sets *bridge to a valid bridge pointer) if successful,
>> >> + * or one of the standard error codes (and the value in *bridge is
>> >> + * unspecified) if it fails.
>> >
>> > Can we return drm_bridge or error cookie instead?
>>
>> (while replying I realized there is a design flaw in my implementation, but
>> see below)
>>
>> I initially thought I'd do it, but I don't like returning an error cookie
>> for functions getting a bridge pointer. The main reason is that with bridge
>> refcounting the __free() cleanup actions are handy in a lot of places, so we
>> are introdugin a lot of code like:
>>
>>   struct drm_bridge *foo __free(drm_bridge_put) = some_func(...);
>>
>> Where some_func can be one of of_drm_find_bridge(),
>> drm_bridge_get_next_bridge(), drm_bridge_chain_get_{first,last}_bridge()
>> etc.
>
> This is fine even with the functions returning a cookie: the free
> function can explicitly check and return early if IS_ERR() pointer is
> passed to it.
>
>>
>> Such code is very handy exactly because these functions return either a
>> valid pointer or NULL, and thus the cleanup actions always does the right
>> thing. If an error cookie were returned, the caller would have to be very
>> careful in inhibiting the cleanup action by clearing the pointer before
>> returning. This originate for example this discussion: [0]
>>
>> [0] https://lore.kernel.org/lkml/4cd29943-a8d0-4706-b0c5-01d6b33863e4@bootlin.com/
>>
>> So I think never having a negative error value in the bridge pointer is
>> useful to prevent bugs slipping in drivers. For this we should take one of
>> these two opposite approaches:
>>
>>  1. don't return a bridge pointer which can be an ERR_PTR; return an int
>>     with the error code and take a **drm_bridge and:
>>       - on success, set the valid pointer in *bridge
>>       - on failure, set *bridge = NULL (*)
>>  2. like the above-mentioned functions (of_drm_find_bridge(),
>>     drm_bridge_get_next_bridge() etc) return a drm_bridge pointer which is
>>     either a valid pointer or NULL
>
> 3. Return pointer or cookie, ignore cookie in the release function.

Ah, that's a good idea indeed!

It had been proposed recently by Laurent too, but in that case I didn't
take the suggestion because it was referring to a panel API which IIUC is
meant to be reworked anyway [0]. I must have archived the idea too much and
didn't think about using it now! :)

So yes, being of_drm_get_bridge_by_endpoint() a new API that is meant to
stay, I think it's worth doing.

Sadly, I guess that means I have to drop all the R-by you already gave to
various patches in the series.

[0] https://lore.kernel.org/all/DH624WYWKT14.5TSCJXZPVN0T@bootlin.com/

>> >> + */
>> >> +int of_drm_get_bridge_by_endpoint(const struct device_node *np,
>> >> +				  int port, int endpoint,
>> >> +				  struct drm_bridge **bridge)
>> >
>> > Nit: can it be drm_of_get_bridge_by_endpoint?
>>
>> Argh, this convention is changing periodically it seems! :-)
>>
>> I previous discussions I was asked to do either drm_of_ [1] of of_drm_ [2],
>> but since the latter was the last one requested I sticked on it.
>>
>> @Maxime, Dmitry, I'm OK with either, just let me know if I need to change.
>
> I missed Maxime's response, sorry. I'm fine with the suggested
> convention of using the first argument.

OK, no problem. Based on current discussion, in v2 the new API will be:

/**
 * of_drm_get_bridge_by_endpoint - return DRM bridge connected to a port/endpoint
 * @np: device tree node containing output ports
 * @port: port in the device tree node, or -1 for the first port found
 * @endpoint: endpoint in the device tree node, or -1 for the first endpoint found
 *
 * Given a DT node's port and endpoint number, find the connected node and
 * return the associated drm_bridge device.
 *
 * The refcount of the returned bridge is incremented. Use drm_bridge_put()
 * when done with it.
 *
 * Returns a pointer to the connected drm_bridge, or a negative error on failure
 */
struct drm_bridge *int of_drm_get_bridge_by_endpoint(const struct device_node *np,
                                                     int port, int endpoint);

It would be nice to agree on the API before v2, to avoid the need to rework
many patches and drop any review tags multiple times.

Luca

--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


^ permalink raw reply

* Re: [PATCH] drm: mxsfb: lcdif: enforce 64-byte pitch alignment for scanout
From: Advait Dhamorikar @ 2026-04-14  6:35 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: marex, simona, imx, festevam, kernel, dri-devel, Frank.Li,
	s.hauer, maarten.lankhorst, linux-kernel, mripard, stefan,
	tzimmermann, airlied, linux-arm-kernel
In-Reply-To: <99fdddde59e1b0fe13d5014182b1c97de4fbec86.camel@pengutronix.de>

Hello Philipp,

> I wonder if setting 4320 bytes stride works if you reduce the burst
> size, for example by reverting commit 2215cb3be5c2 ("drm: lcdif: change
> burst size to 256B") to test.

Unfortunately, reverting the commit doesn't seem to fix the issue.
I tested with the reduced/default burst size as well as explicitly
setting it to 128 bytes, but a pitch of 4320 bytes still results in a
corrupted output(stretched and choppy display).

However, using a 64 byte aligned pitch works in all cases without having
to alter the burst size.

Best regards,
Advait

On Mon, Apr 13, 2026 at 7:16 PM Philipp Zabel <p.zabel@pengutronix.de> wrote:
>
> Hi,
>
> On Mo, 2026-04-13 at 17:14 +0530, Advait Dhamorikar wrote:
> > The LCDIF controller expects framebuffer pitch to be aligned to a
> > 64 byte boundary for reliable scanout.
> >
> > While byte-granular pitches are
> > supported by the interface, the i.MX8MP reference manual
> > recommends 64-byte alignment for optimal operation.
> >
> > Corrupted output was observed with XR24 framebuffers where a pitch of
> > 4320 bytes caused visible corruption and choppy display, while an aligned
> > pitch of 4352 bytes worked correctly.
>
> This happens to be divisible by 256, which is is the burst size
> currently set in the undocumented CTRLDESCL0_3 register fields,
> according to the comment in lcdif_set_mode().
>
> I wonder if setting 4320 bytes stride works if you reduce the burst
> size, for example by reverting commit 2215cb3be5c2 ("drm: lcdif: change
> burst size to 256B") to test.
>
> If that is the case, it might be better to allow unaligned pitches but
> configure the burst size depending on pitch alignment.
>
> regards
> Philipp


^ permalink raw reply

* Re: [PATCH] mm/arm: pgtable: remove young bit check for pte_valid_user
From: Brian Ruley @ 2026-04-14  6:28 UTC (permalink / raw)
  To: Will Deacon
  Cc: Russell King (Oracle), Steve Capper, linux-arm-kernel,
	linux-kernel, catalin.marinas
In-Reply-To: <ad0Ky09tLcFx7JCa@zoo11.fihel.lab.ge-healthcare.net>

On Apr 13, Brian Ruley wrote:
> 
> Applied the fix and so far so good. We're going to run `stress-ng'
> tests overnight to be sure. In the meanwhile, I'll see if I can add
> some instrumentation to verify this is the bug we're seeing.

No failures in any of our tests. I can confirm that this solved our
problem.

Would you like me to submit the patch or will you guys take care of it?

BR,
Brian


^ permalink raw reply

* Re: [PATCH v10 00/20] CoreSight: Refactor power management for CoreSight path
From: Leo Yan @ 2026-04-14  6:09 UTC (permalink / raw)
  To: Jie Gan
  Cc: Suzuki K Poulose, Mike Leach, James Clark, Yeoreum Yun,
	Mark Rutland, Will Deacon, Yabin Cui, Keita Morisaki,
	Yuanfang Zhang, Greg Kroah-Hartman, Alexander Shishkin,
	Tamas Petz, Thomas Gleixner, Peter Zijlstra, coresight,
	linux-arm-kernel
In-Reply-To: <633b8a0e-5e78-4c4d-83d8-d4c8ea71bf15@oss.qualcomm.com>

On Tue, Apr 14, 2026 at 11:30:39AM +0800, Jie Gan wrote:

[...]

> > > Tested-by: Jie Gan <jie.gan@oss.qualcomm.com>
> > 
> > Just heads up: since Sashiko [1] pointed out a corner case where an SMP call
> > may fail when disabling the source device, the per-CPU path pointer
> > might not be cleared.  If the ETMv4 device is then removed (e.g. if the
> > user unloads the ETMv4 module), CPU PM notifier might access the stale
> > path pointer.  Though this is a rare case, we should handle it safely.
> > This is why the series was not picked for the v7.1 merge window.
> > 
> > Thanks a lot for the testing, Jie! It's very helpful, and I will add
> > your test tags in the next spin.
> > 
> > Anyway, please expect more iterations.
> 
> Noted, will run the test cases on new iterations.

Thank you!


^ permalink raw reply

* Re: [PATCH v10 00/20] CoreSight: Refactor power management for CoreSight path
From: Jie Gan @ 2026-04-14  3:30 UTC (permalink / raw)
  To: Leo Yan
  Cc: Suzuki K Poulose, Mike Leach, James Clark, Yeoreum Yun,
	Mark Rutland, Will Deacon, Yabin Cui, Keita Morisaki,
	Yuanfang Zhang, Greg Kroah-Hartman, Alexander Shishkin,
	Tamas Petz, Thomas Gleixner, Peter Zijlstra, coresight,
	linux-arm-kernel
In-Reply-To: <20260413163130.GC356832@e132581.arm.com>



On 4/14/2026 12:31 AM, Leo Yan wrote:
> On Mon, Apr 13, 2026 at 06:30:18PM +0800, Jie Gan wrote:
> 
> [...]
> 
>> tested on QCOM sa8775-ride:
>>
>> === 1. Sysfs mode: basic enable/disable ===
>> PASS: Sink tmc_etr0 enabled
>> PASS: Source etm0 enabled
>> PASS: Source etm0 disabled cleanly
>> PASS: Sink tmc_etr0 disabled cleanly
>>
>> === 2. Sysfs mode: repeated enable/disable cycles (10x) ===
>> PASS: 10 enable/disable cycles completed without error
>>
>> === 3. Sysfs mode: enable source with no active sink ===
>> PASS: Enable without sink returned error (expected)
>>
>> === 4. Sysfs mode: enable/disable all per-CPU sources ===
>>      etm0 (cpu0): enabled OK
>>      etm1 (cpu1): enabled OK
>>      etm2 (cpu2): enabled OK
>>      etm3 (cpu3): enabled OK
>>      etm4 (cpu4): enabled OK
>>      etm5 (cpu5): enabled OK
>>      etm6 (cpu6): enabled OK
>>      etm7 (cpu7): enabled OK
>> PASS: All online per-CPU sources enabled/disabled successfully
>>
>> === 5. CPU hotplug: offline CPU while sysfs tracing active ===
>>    Using source etm1 on cpu1
>>    Tracing active on cpu1, offlining CPU...
>> [   82.805359] psci: CPU1 killed (polled 0 ms)
>> PASS: Source auto-disabled on CPU offline
>> [   83.346033] Detected PIPT I-cache on CPU1
>> [   83.346114] GICv3: CPU1: found redistributor 100 region
>> 0:0x0000000017a80000
>> [   83.346283] CPU1: Booted secondary processor 0x0000000100 [0x410fd4b2]
>> PASS: Source re-enabled after CPU re-online
>>
>> === 6. Sysfs: enable source on offline CPU (expect ENODEV) ===
>> [   84.013788] psci: CPU1 killed (polled 0 ms)
>> PASS: Enable on offline cpu1 rejected (enable_source=0)
>> [   84.349558] Detected PIPT I-cache on CPU1
>> [   84.349640] GICv3: CPU1: found redistributor 100 region
>> 0:0x0000000017a80000
>> [   84.349811] CPU1: Booted secondary processor 0x0000000100 [0x410fd4b2]
>>
>> === 7. CPU PM: trace survives CPU idle entry/exit ===
>>    Sleeping 3s to allow CPU idle entry...
>>    Idle entries on cpu0 during test: 35
>> PASS: Source still enabled after idle (PM save/restore working)
>>
>> === 8. Perf mode: basic cs_etm recording ===
>> SKIP: perf not found in PATH
>>
>> === 11. TRBE: check save/restore sysfs nodes (if present) ===
>> SKIP: No TRBE devices found
>>
>> Tested-by: Jie Gan <jie.gan@oss.qualcomm.com>
> 
> Just heads up: since Sashiko [1] pointed out a corner case where an SMP call
> may fail when disabling the source device, the per-CPU path pointer
> might not be cleared.  If the ETMv4 device is then removed (e.g. if the
> user unloads the ETMv4 module), CPU PM notifier might access the stale
> path pointer.  Though this is a rare case, we should handle it safely.
> This is why the series was not picked for the v7.1 merge window.
> 
> Thanks a lot for the testing, Jie! It's very helpful, and I will add
> your test tags in the next spin.
> 
> Anyway, please expect more iterations.

Noted, will run the test cases on new iterations.

Thanks,
Jie

> 
> Thanks,
> Leo
> 
> [1] https://sashiko.dev/#/patchset/20260405-arm_coresight_path_power_management_improvement-v10-0-13e94754a8be%40arm.com?part=5



^ permalink raw reply

* [PATCH mpam mpam/snapshot+extras/v6.18-rc1 v2 3/3] fs/resctrl: Migrate IOMMU groups when removing resource groups
From: Zeng Heng @ 2026-04-14  3:26 UTC (permalink / raw)
  To: ben.horgan, james.morse, Dave.Martin, fenghuay, reinette.chatre
  Cc: xiaqinxin, sunnanyong, jonathan.cameron, linux-kernel,
	linux-arm-kernel
In-Reply-To: <20260414032610.1523958-1-zengheng4@huawei.com>

When deleting a control group, monitor group, or unmounting the resctrl
filesystem, migrate all associated IOMMU groups to the appropriate
destination:
  * Control group deletion: move IOMMU groups to the default group
  * Monitor group deletion: move IOMMU groups to the parent control group
  * Filesystem unmount: move all IOMMU groups to the default group

Without this migration, IOMMU groups remain bound to stale PARTID/PMG
values of the destroyed group, causing them to "disappear" from the
resctrl interface.

Add rdt_move_group_iommus() to handle this migration, mirroring the
existing rdt_move_group_tasks() pattern for task migration.

When deleting a control group or unmounting the resctrl file system, it
is necessary to move its all iommu_groups back to the default group. When
removing a monitor group, need to move its iommu_groups back to the parent
control group.

Otherwise, these iommu_groups remain bound to the old PARTID and PMG, and
they will appear to "disappear" from the resctrl fs.

Signed-off-by: Zeng Heng <zengheng4@huawei.com>
---
 fs/resctrl/rdtgroup.c | 47 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c
index e92b5dcb6f2e..351e430bde1a 100644
--- a/fs/resctrl/rdtgroup.c
+++ b/fs/resctrl/rdtgroup.c
@@ -3292,6 +3292,44 @@ static void rdt_move_group_tasks(struct rdtgroup *from, struct rdtgroup *to,
 	read_unlock(&tasklist_lock);
 }
 
+static int rdt_move_group_iommus(struct rdtgroup *from, struct rdtgroup *to)
+{
+	struct kset *iommu_groups;
+	struct iommu_group *group;
+	int err = 0, iommu_group_id;
+	struct kobject *group_kobj = NULL;
+
+	if (!IS_ENABLED(CONFIG_RESCTRL_IOMMU))
+		return 0;
+
+	if (from == to)
+		return 0;
+
+	iommu_groups = iommu_get_group_kset();
+
+	while ((group_kobj = kset_get_next_obj(iommu_groups, group_kobj))) {
+		/* iommu_group_get_from_kobj() wants to drop a reference */
+		kobject_get(group_kobj);
+
+		group = iommu_group_get_from_kobj(group_kobj);
+		if (!group)
+			continue;
+
+		if (!from || iommu_matches_rdtgroup(group, from)) {
+			err = kstrtoint(group_kobj->name, 0, &iommu_group_id);
+			if (err)
+				break;
+
+			err = rdtgroup_move_iommu(iommu_group_id, to);
+			if (err)
+				break;
+		}
+	}
+
+	kset_put(iommu_groups);
+	return err;
+}
+
 static void free_all_child_rdtgrp(struct rdtgroup *rdtgrp)
 {
 	struct rdtgroup *sentry, *stmp;
@@ -3320,6 +3358,9 @@ static void rmdir_all_sub(void)
 	/* Move all tasks to the default resource group */
 	rdt_move_group_tasks(NULL, &rdtgroup_default, NULL);
 
+	/* Move all iommu_groups to the default resource group */
+	rdt_move_group_iommus(NULL, &rdtgroup_default);
+
 	list_for_each_entry_safe(rdtgrp, tmp, &rdt_all_groups, rdtgroup_list) {
 		/* Free any child rmids */
 		free_all_child_rdtgrp(rdtgrp);
@@ -4189,6 +4230,9 @@ static int rdtgroup_rmdir_mon(struct rdtgroup *rdtgrp, cpumask_var_t tmpmask)
 	/* Give any tasks back to the parent group */
 	rdt_move_group_tasks(rdtgrp, prdtgrp, tmpmask);
 
+	/* Give any iommu_groups back to the parent group */
+	rdt_move_group_iommus(rdtgrp, prdtgrp);
+
 	/*
 	 * Update per cpu closid/rmid of the moved CPUs first.
 	 * Note: the closid will not change, but the arch code still needs it.
@@ -4239,6 +4283,9 @@ static int rdtgroup_rmdir_ctrl(struct rdtgroup *rdtgrp, cpumask_var_t tmpmask)
 	/* Give any tasks back to the default group */
 	rdt_move_group_tasks(rdtgrp, &rdtgroup_default, tmpmask);
 
+	/* Give any iommu_groups back to the default group */
+	rdt_move_group_iommus(rdtgrp, &rdtgroup_default);
+
 	/* Give any CPUs back to the default group */
 	cpumask_or(&rdtgroup_default.cpu_mask,
 		   &rdtgroup_default.cpu_mask, &rdtgrp->cpu_mask);
-- 
2.25.1



^ permalink raw reply related

* [PATCH mpam mpam/snapshot+extras/v6.18-rc1 v2 2/3] fs/resctrl: Remove unused 'of' parameter from rdtgroup_move_iommu()
From: Zeng Heng @ 2026-04-14  3:26 UTC (permalink / raw)
  To: ben.horgan, james.morse, Dave.Martin, fenghuay, reinette.chatre
  Cc: xiaqinxin, sunnanyong, jonathan.cameron, linux-kernel,
	linux-arm-kernel
In-Reply-To: <20260414032610.1523958-1-zengheng4@huawei.com>

The 'of' (kernfs_open_file) parameter in rdtgroup_move_iommu() is
not used within the function body. Remove it to simplify the
interface and eliminate the unnecessary argument passing.

Signed-off-by: Zeng Heng <zengheng4@huawei.com>
---
 fs/resctrl/rdtgroup.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c
index 1810ace9538f..e92b5dcb6f2e 100644
--- a/fs/resctrl/rdtgroup.c
+++ b/fs/resctrl/rdtgroup.c
@@ -767,8 +767,7 @@ static int rdtgroup_move_task(pid_t pid, struct rdtgroup *rdtgrp,
 	return ret;
 }
 
-static int rdtgroup_move_iommu(int iommu_group_id, struct rdtgroup *rdtgrp,
-			       struct kernfs_open_file *of)
+static int rdtgroup_move_iommu(int iommu_group_id, struct rdtgroup *rdtgrp)
 {
 	const struct cred *cred = current_cred();
 	struct iommu_group *iommu_group;
@@ -849,7 +848,7 @@ static ssize_t rdtgroup_tasks_write(struct kernfs_open_file *of,
 
 		is_iommu = string_is_iommu_group(pid_str, &iommu_group_id);
 		if (is_iommu) {
-			ret = rdtgroup_move_iommu(iommu_group_id, rdtgrp, of);
+			ret = rdtgroup_move_iommu(iommu_group_id, rdtgrp);
 			if (ret) {
 				rdt_last_cmd_printf("Error while processing iommu_group %d\n",
 						     iommu_group_id);
-- 
2.25.1



^ permalink raw reply related

* [PATCH mpam mpam/snapshot+extras/v6.18-rc1 v2 1/3] fs/resctrl: Fix incorrect PID parsing after IOMMU group token
From: Zeng Heng @ 2026-04-14  3:26 UTC (permalink / raw)
  To: ben.horgan, james.morse, Dave.Martin, fenghuay, reinette.chatre
  Cc: xiaqinxin, sunnanyong, jonathan.cameron, linux-kernel,
	linux-arm-kernel
In-Reply-To: <20260414032610.1523958-1-zengheng4@huawei.com>

When the tasks interface receives an "iommu_group:id" configuration,
the original code fails to skip the PID parsing logic after processing
the IOMMU group. This causes the same token to be incorrectly passed
to kstrtoint() as a PID, resulting in -EINVAL.

Restructure the conditional logic to use explicit if-else branches,
ensuring that IOMMU group tokens are processed by rdtgroup_move_iommu()
and then skipped.

This fix also enables proper handling of mixed configurations with
multiple consecutive iommu_group:id and pid entries (e.g.,
echo "iommu_group:1,1234,iommu_group:2,5678" > tasks).

Fixes: 98b622c413ee ("fs/resctrl: Add support for assigning iommu_groups to resctrl groups")
Signed-off-by: Zeng Heng <zengheng4@huawei.com>
---
 fs/resctrl/rdtgroup.c | 39 ++++++++++++++++++++++++---------------
 1 file changed, 24 insertions(+), 15 deletions(-)

diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c
index 5381233adceb..1810ace9538f 100644
--- a/fs/resctrl/rdtgroup.c
+++ b/fs/resctrl/rdtgroup.c
@@ -848,24 +848,33 @@ static ssize_t rdtgroup_tasks_write(struct kernfs_open_file *of,
 		pid_str = strim(strsep(&buf, ","));
 
 		is_iommu = string_is_iommu_group(pid_str, &iommu_group_id);
-		if (is_iommu)
+		if (is_iommu) {
 			ret = rdtgroup_move_iommu(iommu_group_id, rdtgrp, of);
-		else if (kstrtoint(pid_str, 0, &pid)) {
-			rdt_last_cmd_printf("Task list parsing error pid %s\n", pid_str);
-			ret = -EINVAL;
-			break;
-		}
+			if (ret) {
+				rdt_last_cmd_printf("Error while processing iommu_group %d\n",
+						     iommu_group_id);
+				break;
+			}
+		} else {
+			if (kstrtoint(pid_str, 0, &pid)) {
+				rdt_last_cmd_printf("Task list parsing error pid %s\n",
+						     pid_str);
+				ret = -EINVAL;
+				break;
+			}
 
-		if (pid < 0) {
-			rdt_last_cmd_printf("Invalid pid %d\n", pid);
-			ret = -EINVAL;
-			break;
-		}
+			if (pid < 0) {
+				rdt_last_cmd_printf("Invalid pid %d\n", pid);
+				ret = -EINVAL;
+				break;
+			}
 
-		ret = rdtgroup_move_task(pid, rdtgrp, of);
-		if (ret) {
-			rdt_last_cmd_printf("Error while processing task %d\n", pid);
-			break;
+			ret = rdtgroup_move_task(pid, rdtgrp, of);
+			if (ret) {
+				rdt_last_cmd_printf("Error while processing task %d\n",
+						     pid);
+				break;
+			}
 		}
 	}
 
-- 
2.25.1



^ permalink raw reply related

* [PATCH mpam mpam/snapshot+extras/v6.18-rc1 v2 0/3] fs/resctrl: IOMMU group fixes for tasks interface and cleanup
From: Zeng Heng @ 2026-04-14  3:26 UTC (permalink / raw)
  To: ben.horgan, james.morse, Dave.Martin, fenghuay, reinette.chatre
  Cc: xiaqinxin, sunnanyong, jonathan.cameron, linux-kernel,
	linux-arm-kernel

This fix patch is against the mpam/snapshot+extras/v6.18-rc1 branch at
https://kernel.googlesource.com/pub/scm/linux/kernel/git/morse/linux.git .

The patch series fixes several issues with IOMMU group handling in the
resctrl filesystem.

Changes
=======

Compared with v1:
  - Split patch 2 into separate patches 2 and 3.

Previous Versions
=================

  v1: https://lore.kernel.org/all/20251107063300.1580046-1-zengheng4@huawei.com/

---

Zeng Heng (3):
  fs/resctrl: Fix incorrect PID parsing after IOMMU group token
  fs/resctrl: Remove unused 'of' parameter from rdtgroup_move_iommu()
  fs/resctrl: Migrate IOMMU groups when removing resource groups

 fs/resctrl/rdtgroup.c | 91 ++++++++++++++++++++++++++++++++++---------
 1 file changed, 73 insertions(+), 18 deletions(-)

--
2.25.1



^ permalink raw reply

* Re: [PATCH bpf-next v14 1/5] bpf: Move constants blinding out of arch-specific JITs
From: Xu Kuohai @ 2026-04-14  3:20 UTC (permalink / raw)
  To: bot+bpf-ci, bpf, linux-kernel, linux-arm-kernel
  Cc: ast, daniel, andrii, martin.lau, eddyz87, memxor, yonghong.song,
	puranjay, a.s.protopopov, alexis.lothore, list+bpf, linux,
	yangtiezhu, hengqi.chen, johan.almbladh, paulburton, hbathini,
	chleroy, naveen, luke.r.nels, xi.wang, bjorn, pulehui, iii, hca,
	gor, davem, udknight, martin.lau, clm, ihor.solodrai
In-Reply-To: <fa46a9034904c7622f935d3e3a60264a37afda290705f40c816c9846c9d3f3f8@mail.kernel.org>

On 4/13/2026 9:47 PM, bot+bpf-ci@kernel.org wrote:
>> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
>> index 066b86e7233c..fc9fb3c07866 100644
>> --- a/kernel/bpf/core.c
>> +++ b/kernel/bpf/core.c
> 
> [ ... ]
> 
>>   /**
>>    *	bpf_prog_select_runtime - select exec runtime for BPF program
>>    *	@fp: bpf_prog populated with BPF program
> 
> [ ... ]
> 
>> -	/* eBPF JITs can rewrite the program in case constant
>> -	 * blinding is active. However, in case of error during
>> -	 * blinding, bpf_int_jit_compile() must always return a
>> -	 * valid program, which in this case would simply not
>> -	 * be JITed, but falls back to the interpreter.
>> -	 */
>> +	/* eBPF JITs can rewrite the program in case constant
>> +	 * blinding is active. However, in case of error during
>> +	 * blinding, bpf_int_jit_compile() must always return a
>> +	 * valid program, which in this case would simply not
>> +	 * be JITed, but falls back to the interpreter.
>> +	 */
> 
> This isn't a bug, but this comment still references bpf_int_jit_compile()
> even though the code now calls bpf_prog_jit_compile(). Should this be
> updated to match?
>

This comment is not touched by the patch, it was already there before
the patch, so I'd leave it as is.

>> -		fp = bpf_int_jit_compile(fp);
>> +		fp = bpf_prog_jit_compile(fp);
> 
>> diff --git a/kernel/bpf/fixups.c b/kernel/bpf/fixups.c
>> index 67c9b28767e1..ec8afd6a9369 100644
>> --- a/kernel/bpf/fixups.c
>> +++ b/kernel/bpf/fixups.c
> 
> [ ... ]
> 
>> +out_jit_err:
>> +	if (blinded) {
>> +		bpf_jit_prog_release_other(orig_prog, prog);
>> +		/* roll back to the clean original prog */
>> +		prog = env->prog = orig_prog;
>> +		goto out_restore;
>> +	} else {
>> +		if (err != -EFAULT) {
>> +			/*
>> +			 * We will fall back to interpreter mode when err is not -EFAULT, before
>> +			 * that, insn->off and insn->imm should be restored to their original
>> +			 * values since they were modified by __jit_subprogs.
>> +			 */
> 
> The comment references __jit_subprogs, but the function is named
> jit_subprogs (no double underscore prefix). Should this be updated?
>

Yes, it should be jit_subprogs.

In addition, sashiko reported an issue that subprog_start of the fake
exit subprog is not restored on the rollback path. It said that
bpf_fixup_call_args() relies on this sentinel to detect the end of the
last subprog. I checked the bpf_fixup_call_args() function and its child
functions, but could not find any usage of the sentinel.

IIUC, the sentinel is only used to compute the length of the last subprog
and is not used after jit_subprogs fails, so not restoring it does not
to be a real issue.

However, leaving the sentinel unrestored seems error-prone, and for code
consistency, I'll restore it in the next version.

>> +			for (i = 0, insn = prog->insnsi; i < prog->len; i++, insn++) {
>> +				if (!bpf_pseudo_call(insn))
>> +					continue;
>> +				insn->off = 0;
>> +				insn->imm = env->insn_aux_data[i].call_imm;
>> +			}
>> +		}
> 
> 
> ---
> AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
> See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
> 
> CI run summary: https://github.com/kernel-patches/bpf/actions/runs/24345549165



^ permalink raw reply

* Re: [PATCH v7 0/2] arm64: dts/defconfig: enable BST C1200 eMMC
From: Albert Yang @ 2026-04-14  3:10 UTC (permalink / raw)
  To: Gordon Ge
  Cc: Albert Yang, krzk, arnd, krzk+dt, robh, conor+dt, bst-upstream,
	linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <20260310091211.4171307-1-yangzh0906@thundersoft.com>

Hi Gordon,

Could you please help with:

1) Reviewing the remaining 2 patches in this series.

If acceptable, please reply with an Acked-by on each patch below:

- [PATCH v7 1/2] arm64: dts: bst: enable eMMC controller in C1200 CDCU1.0 board
- [PATCH v7 2/2] arm64: defconfig: enable BST SDHCI controller

I will carry your tags in the next revision.

Thanks,
Albert


^ permalink raw reply

* Re: [PATCH v2] dt-bindings: arm: marvell: Convert armada-380-mpcore-soc-ctrl to DT Schema
From: Padmashree S S @ 2026-04-14  2:13 UTC (permalink / raw)
  To: Rob Herring
  Cc: andrew, gregory.clement, sebastian.hesselbarth, krzk+dt, conor+dt,
	linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <20260407184455.GA3369046-robh@kernel.org>

On Wed, Apr 8, 2026 at 12:14 AM Rob Herring <robh@kernel.org> wrote:
>
> On Fri, Mar 27, 2026 at 05:16:53PM +0530, Padmashree S S wrote:
> > Convert armada-380-mpcore-soc-ctrl to DT schema
> >
> > Signed-off-by: Padmashree S S <padmashreess2006@gmail.com>
> > ---
> >  .../marvell/armada-380-mpcore-soc-ctrl.txt    | 14 --------
> >  .../marvell/armada-380-mpcore-soc-ctrl.yaml   | 32 +++++++++++++++++++
> >  2 files changed, 32 insertions(+), 14 deletions(-)
> >  delete mode 100644 Documentation/devicetree/bindings/arm/marvell/armada-380-mpcore-soc-ctrl.txt
> >  create mode 100644 Documentation/devicetree/bindings/arm/marvell/armada-380-mpcore-soc-ctrl.yaml
>
> Please move this to
> bindings/soc/marvell/marvell,armada-380-mpcore-soc-ctrl.yaml
>
> Don't forget to update the '$id' value.
>
> Rob
Thank you for the review, I'll move the binding and change the $id in
the next version of this patch.


^ permalink raw reply

* RE: [EXT] Re: [PATCH v2] pmdomain: imx: Make IMX8M/IMX9 BLK_CTRL tristate
From: Zhipeng Wang @ 2026-04-14  1:59 UTC (permalink / raw)
  To: Marco Felsch
  Cc: ulfh@kernel.org, Frank Li, s.hauer@pengutronix.de,
	imx@lists.linux.dev, linux-pm@vger.kernel.org, Xuegang Liu,
	Jindong Yue, linux-kernel@vger.kernel.org, kernel@pengutronix.de,
	festevam@gmail.com, linux-arm-kernel@lists.infradead.org
In-Reply-To: <ql2c6m54fjjwifycaan3hcr3p3bp4phva2vdux2qcramt7wrvy@4dsvpyct5tqx>

 > On 26-04-13, Zhipeng Wang wrote:
> > Convert IMX8M_BLK_CTRL and IMX9_BLK_CTRL from bool to tristate to
> > allow building as loadable modules.
>
> Out of curiosity, why do you want to have a PM driver to be buildable as
> module?
>
> Regards,
>   Marco
>
Hi Marco,

Thank you for your question.

The primary motivation is to support Google's GKI (Generic Kernel Image)
requirement for Android devices.

GKI separates the kernel into two parts:
1. A unified kernel image (GKI) that is common across all Android devices
2. Vendor-specific drivers that must be built as loadable modules

Under the GKI architecture, SoC-specific drivers like IMX8M/IMX9 BLK_CTRL
cannot be built into the core kernel image. Instead, they must be loadable
modules that vendors can ship separately. This allows:

- A single kernel binary to support multiple hardware platforms
- Vendors to update their drivers independently without rebuilding the entire kernel
- Better compliance with Android's kernel update and security policies

For i.MX8M/i.MX9 devices running Android with GKI kernels, the BLK_CTRL
drivers need to be loaded as modules during boot. Without tristate support,
these devices cannot properly initialize their power domains, making them
non-functional under GKI.

Best regards,
Zhipeng Wang
> > Add prompt strings to make these options visible and configurable in
> > menuconfig, keeping them enabled by default on appropriate platforms.
> >
> > Also remove the IMX_GPCV2_PM_DOMAINS dependency from
> IMX9_BLK_CTRL.
> > This dependency was incorrect from the beginning - i.MX93 uses a
> > different power domain architecture compared to i.MX8M series:
> >
> > - i.MX8M uses GPCv2 (General Power Controller v2) for power domain
> >   management, hence IMX8M_BLK_CTRL correctly depends on it.
> >
> > - i.MX93 uses BLK_CTRL directly without GPCv2. The hardware doesn't
> >   have GPCv2 at all.
> >
> > Signed-off-by: Zhipeng Wang <zhipeng.wang_1@nxp.com>
> > ---
> >  drivers/pmdomain/imx/Kconfig | 11 +++++++----
> >  1 file changed, 7 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/pmdomain/imx/Kconfig
> > b/drivers/pmdomain/imx/Kconfig index 00203615c65e..9168d183b0c5
> 100644
> > --- a/drivers/pmdomain/imx/Kconfig
> > +++ b/drivers/pmdomain/imx/Kconfig
> > @@ -10,15 +10,18 @@ config IMX_GPCV2_PM_DOMAINS
> >       default y if SOC_IMX7D
> >
> >  config IMX8M_BLK_CTRL
> > -     bool
> > -     default SOC_IMX8M && IMX_GPCV2_PM_DOMAINS
> > +     tristate "i.MX8M BLK CTRL driver"
> > +     depends on SOC_IMX8M
> > +     depends on IMX_GPCV2_PM_DOMAINS
> >       depends on PM_GENERIC_DOMAINS
> >       depends on COMMON_CLK
> > +     default y
> >
> >  config IMX9_BLK_CTRL
> > -     bool
> > -     default SOC_IMX9 && IMX_GPCV2_PM_DOMAINS
> > +     tristate "i.MX93 BLK CTRL driver"
> > +     depends on SOC_IMX9
> >       depends on PM_GENERIC_DOMAINS
> > +     default y
> >
> >  config IMX_SCU_PD
> >       bool "IMX SCU Power Domain driver"
> > --
> > 2.34.1
> >
> >
> >
>
> --
> #gernperDu
> #CallMeByMyFirstName
>
> Pengutronix e.K.                           |
> |
> Steuerwalder Str. 21                       |
> https://www.pe/
> ngutronix.de%2F&data=05%7C02%7Czhipeng.wang_1%40nxp.com%7Cb056e
> 81e107a466e482a08de995e4054%7C686ea1d3bc2b4c6fa92cd99c5c301635
> %7C0%7C0%7C639116827251261199%7CUnknown%7CTWFpbGZsb3d8eyJFb
> XB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFp
> bCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=qeSCoz6%2BawDiK1ISgG6Rs
> %2BtKScilTDoryyrt08WQYiA%3D&reserved=0 |
> 31137 Hildesheim, Germany                  | Phone:
> +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-9
> |


^ permalink raw reply

* Re: [PATCH bpf-next v2 1/2] bpf, arm64: Remove redundant bpf_flush_icache() after pack allocator finalize
From: Xu Kuohai @ 2026-04-14  1:55 UTC (permalink / raw)
  To: Puranjay Mohan, bpf
  Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Eduard Zingerman, Kumar Kartikeya Dwivedi,
	Song Liu, Yonghong Song, Jiri Olsa, Catalin Marinas, Will Deacon,
	Luke Nelson, Xi Wang, Björn Töpel, Pu Lehui,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	linux-arm-kernel, linux-riscv, linux-kernel
In-Reply-To: <20260413191111.3426023-2-puranjay@kernel.org>

On 4/14/2026 3:11 AM, Puranjay Mohan wrote:
> bpf_flush_icache() calls flush_icache_range() to clean the data cache
> and invalidate the instruction cache for the JITed code region. However,
> since commit 1dad391daef1 ("bpf, arm64: use bpf_prog_pack for memory
> management"), this flush is redundant.
> 
> bpf_jit_binary_pack_finalize() copies the JITed instructions to the ROX
> region via bpf_arch_text_copy() -> aarch64_insn_copy() -> __text_poke(),
> and __text_poke() already calls flush_icache_range() on the written
> range. The subsequent bpf_flush_icache() repeats the same cache
> maintenance on an overlapping range, including an unnecessary second
> synchronous IPI to all CPUs via kick_all_cpus_sync().
>

So icache is flushed twice: once per instruction and again after all
instructions are copied. I think it's better to remove the per-instruction
flush and retain the single final flush to avoid repeating flush overhead
for each instruction.

> Remove the redundant bpf_flush_icache() call and its now-unused
> definition.
> 
> Fixes: 1dad391daef1 ("bpf, arm64: use bpf_prog_pack for memory management")
> Acked-by: Song Liu <song@kernel.org>
> Signed-off-by: Puranjay Mohan <puranjay@kernel.org>
> ---
>   arch/arm64/net/bpf_jit_comp.c | 12 ------------
>   1 file changed, 12 deletions(-)
> 
> diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
> index adf84962d579..7417d24a5b6f 100644
> --- a/arch/arm64/net/bpf_jit_comp.c
> +++ b/arch/arm64/net/bpf_jit_comp.c
> @@ -18,7 +18,6 @@
>   
>   #include <asm/asm-extable.h>
>   #include <asm/byteorder.h>
> -#include <asm/cacheflush.h>
>   #include <asm/cpufeature.h>
>   #include <asm/debug-monitors.h>
>   #include <asm/insn.h>
> @@ -1961,11 +1960,6 @@ static int validate_ctx(struct jit_ctx *ctx)
>   	return 0;
>   }
>   
> -static inline void bpf_flush_icache(void *start, void *end)
> -{
> -	flush_icache_range((unsigned long)start, (unsigned long)end);
> -}
> -
>   static void priv_stack_init_guard(void __percpu *priv_stack_ptr, int alloc_size)
>   {
>   	int cpu, underflow_idx = (alloc_size - PRIV_STACK_GUARD_SZ) >> 3;
> @@ -2204,12 +2198,6 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
>   			prog = orig_prog;
>   			goto out_off;
>   		}
> -		/*
> -		 * The instructions have now been copied to the ROX region from
> -		 * where they will execute. Now the data cache has to be cleaned to
> -		 * the PoU and the I-cache has to be invalidated for the VAs.
> -		 */
> -		bpf_flush_icache(ro_header, ctx.ro_image + ctx.idx);
>   	} else {
>   		jit_data->ctx = ctx;
>   		jit_data->ro_image = ro_image_ptr;



^ permalink raw reply

* RE: [PATCH v1] PCI: imx6: Add force_suspend flag to override L1SS suspend skip
From: Hongxing Zhu @ 2026-04-14  1:53 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: mani@kernel.org, Frank Li, jingoohan1@gmail.com,
	l.stach@pengutronix.de, lpieralisi@kernel.org,
	kwilczynski@kernel.org, robh@kernel.org, bhelgaas@google.com,
	s.hauer@pengutronix.de, kernel@pengutronix.de, festevam@gmail.com,
	linux-pci@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	imx@lists.linux.dev, linux-kernel@vger.kernel.org,
	stable@vger.kernel.org
In-Reply-To: <20260410225341.GA598942@bhelgaas>

> -----Original Message-----
> From: Bjorn Helgaas <helgaas@kernel.org>
> Sent: 2026年4月11日 6:54
> To: Hongxing Zhu <hongxing.zhu@nxp.com>
> Cc: mani@kernel.org; Frank Li <frank.li@nxp.com>; jingoohan1@gmail.com;
> l.stach@pengutronix.de; lpieralisi@kernel.org; kwilczynski@kernel.org;
> robh@kernel.org; bhelgaas@google.com; s.hauer@pengutronix.de;
> kernel@pengutronix.de; festevam@gmail.com; linux-pci@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; imx@lists.linux.dev;
> linux-kernel@vger.kernel.org; stable@vger.kernel.org
> Subject: Re: [PATCH v1] PCI: imx6: Add force_suspend flag to override L1SS
> suspend skip
> 
> On Wed, Apr 08, 2026 at 02:38:35AM +0000, Hongxing Zhu wrote:
> > ...
> 
> > One additional note regarding NVMe: ASPM (Active State Power
> > Management) is disabled locally on i.MX platforms for NVMe devices.
> > This decision was made after encountering a system hang issue similar
> > to the one reported by Hans a few months ago in his patch listed below.
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore
> > .kernel.org%2Flinux-nvme%2F20250502032051.920990-1-hans.zhang%40cix
> tec
> >
> h.com%2F&data=05%7C02%7Chongxing.zhu%40nxp.com%7Cbcdec1ffa5144c
> dc70ec0
> >
> 8de97540509%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C639114
> 5842866
> >
> 17247%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIw
> LjAuMDAw
> >
> MCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C
> &sdat
> >
> a=Lpafp%2Fo3n%2FzCC%2F9iwxviRdFZzT8azQC%2FzSjTbArDV8E%3D&reserve
> d=0
> 
> Where is ASPM disabled for i.MX?  I don't see anything in pci-imx6.c.
Hi Bjorn:
Thanks for your concerns.
You're correct - the ASPM L1SS disabling for NVMe is currently implemented as
 a local quirk patch, not in pci-imx6.c.
> 
> It doesn't sound architecturally clean to me to disable ASPM based on
> whether an NVMe device is involved.

I agree this approach isn't ideal. The quirk-based solution was a temporary
 workaround.

Best Regards
Richard Zhu


^ permalink raw reply

* Re: [PATCH bpf-next v2 2/2] bpf, riscv: Remove redundant bpf_flush_icache() after pack allocator finalize
From: Pu Lehui @ 2026-04-14  1:13 UTC (permalink / raw)
  To: Puranjay Mohan, bpf
  Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Eduard Zingerman, Kumar Kartikeya Dwivedi,
	Song Liu, Yonghong Song, Jiri Olsa, Xu Kuohai, Catalin Marinas,
	Will Deacon, Luke Nelson, Xi Wang, Björn Töpel,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	linux-arm-kernel, linux-riscv, linux-kernel
In-Reply-To: <20260413191111.3426023-3-puranjay@kernel.org>


On 2026/4/14 3:11, Puranjay Mohan wrote:
> bpf_flush_icache() calls flush_icache_range() to clean the data cache
> and invalidate the instruction cache for the JITed code region. However,
> since commit 48a8f78c50bd ("bpf, riscv: use prog pack allocator in the
> BPF JIT"), this flush is redundant.
> 
> bpf_jit_binary_pack_finalize() copies the JITed instructions to the ROX
> region via bpf_arch_text_copy() -> patch_text_nosync(), and
> patch_text_nosync() already calls flush_icache_range() on the written
> range. The subsequent bpf_flush_icache() repeats the same cache
> maintenance on an overlapping range.
> 
> Remove the redundant bpf_flush_icache() call and its now-unused
> definition.
> 
> Fixes: 48a8f78c50bd ("bpf, riscv: use prog pack allocator in the BPF JIT")
> Acked-by: Song Liu <song@kernel.org>
> Signed-off-by: Puranjay Mohan <puranjay@kernel.org>
> ---
>   arch/riscv/net/bpf_jit.h      | 6 ------
>   arch/riscv/net/bpf_jit_core.c | 7 -------
>   2 files changed, 13 deletions(-)
> 
> diff --git a/arch/riscv/net/bpf_jit.h b/arch/riscv/net/bpf_jit.h
> index 632ced07bca4..da0271790244 100644
> --- a/arch/riscv/net/bpf_jit.h
> +++ b/arch/riscv/net/bpf_jit.h
> @@ -11,7 +11,6 @@
>   
>   #include <linux/bpf.h>
>   #include <linux/filter.h>
> -#include <asm/cacheflush.h>
>   
>   /* verify runtime detection extension status */
>   #define rv_ext_enabled(ext) \
> @@ -105,11 +104,6 @@ static inline void bpf_fill_ill_insns(void *area, unsigned int size)
>   	memset(area, 0, size);
>   }
>   
> -static inline void bpf_flush_icache(void *start, void *end)
> -{
> -	flush_icache_range((unsigned long)start, (unsigned long)end);
> -}
> -
>   /* Emit a 4-byte riscv instruction. */
>   static inline void emit(const u32 insn, struct rv_jit_context *ctx)
>   {
> diff --git a/arch/riscv/net/bpf_jit_core.c b/arch/riscv/net/bpf_jit_core.c
> index b3581e926436..f7fd4afc3ca3 100644
> --- a/arch/riscv/net/bpf_jit_core.c
> +++ b/arch/riscv/net/bpf_jit_core.c
> @@ -183,13 +183,6 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
>   			prog = orig_prog;
>   			goto out_offset;
>   		}
> -		/*
> -		 * The instructions have now been copied to the ROX region from
> -		 * where they will execute.
> -		 * Write any modified data cache blocks out to memory and
> -		 * invalidate the corresponding blocks in the instruction cache.
> -		 */
> -		bpf_flush_icache(jit_data->ro_header, ctx->ro_insns + ctx->ninsns);
>   		for (i = 0; i < prog->len; i++)
>   			ctx->offset[i] = ninsns_rvoff(ctx->offset[i]);
>   		bpf_prog_fill_jited_linfo(prog, ctx->offset);

Reviewed-by: Pu Lehui <pulehui@huawei.com>


^ permalink raw reply

* Re: [GIT PULL] CRC updates for 7.1
From: pr-tracker-bot @ 2026-04-14  0:37 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Linus Torvalds, linux-crypto, linux-arm-kernel, linux-kernel,
	Ard Biesheuvel, Demian Shulhan
In-Reply-To: <20260412002343.GB6632@sol>

The pull request you sent on Sat, 11 Apr 2026 17:23:43 -0700:

> https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git tags/crc-for-linus

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/d142ab35ee0b7f9e84115fe3e4c3de4a9ac35f5e

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


^ permalink raw reply

* Re: [GIT PULL] Crypto library updates for 7.1
From: pr-tracker-bot @ 2026-04-14  0:37 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Linus Torvalds, linux-crypto, linux-arm-kernel, linux-kernel,
	Ard Biesheuvel, Jason A. Donenfeld, Herbert Xu, AlanSong-oc,
	Arnd Bergmann, Dan Williams, David Howells, Johannes Berg,
	Randy Dunlap
In-Reply-To: <20260412003225.GC6632@sol>

The pull request you sent on Sat, 11 Apr 2026 17:32:25 -0700:

> https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git tags/libcrypto-for-linus

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/370c3883195566ee3e7d79e0146c3d735a406573

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


^ permalink raw reply

* Re: [PATCH net-next] net: airoha: Remove PCE_MC_EN_MASK bit in REG_FE_PCE_CFG configuration
From: patchwork-bot+netdevbpf @ 2026-04-14  0:20 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: andrew+netdev, davem, edumazet, kuba, pabeni, linux-arm-kernel,
	linux-mediatek, netdev
In-Reply-To: <20260412-airoha_fe_init_remove_mc_en_bit-v1-1-7b6a5a25a74d@kernel.org>

Hello:

This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Sun, 12 Apr 2026 11:56:25 +0200 you wrote:
> PCE_MC_EN_MASK bit in REG_FE_PCE_CFG configuration performed in
> airoha_fe_init() is used to duplicate multicast packets and send a copy
> to the CPU when the traffic is offloaded. This is necessary just if
> it is requested by the user. Disable multicast packets duplication by
> default.
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> 
> [...]

Here is the summary with links:
  - [net-next] net: airoha: Remove PCE_MC_EN_MASK bit in REG_FE_PCE_CFG configuration
    https://git.kernel.org/netdev/net-next/c/34e1a98ff2a8

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




^ permalink raw reply

* [PATCH v2 4/4] KVM: arm64: Fallback to a supported value for unsupported guest TGx
From: Wei-Lin Chang @ 2026-04-14  0:03 UTC (permalink / raw)
  To: linux-arm-kernel, kvmarm, linux-kernel
  Cc: Marc Zyngier, Oliver Upton, Joey Gouly, Suzuki K Poulose,
	Zenghui Yu, Catalin Marinas, Will Deacon, Wei-Lin Chang
In-Reply-To: <20260414000334.3947257-1-weilin.chang@arm.com>

When KVM derives the translation granule for emulated stage-1 and
stage-2 walks, it decodes TCR/VTCR.TGx and treats the granule as-is.
This is wrong when the guest programs a granule size that is not
advertised in the guest's ID_AA64MMFR0_EL1.TGRAN* fields.
Architecturally, such a value must be treated as an implemented granule
size. Choose an available one while prioritizing PAGE_SIZE.

Signed-off-by: Wei-Lin Chang <weilin.chang@arm.com>
---
 arch/arm64/kvm/at.c     | 52 +++++++++++++++++++++-
 arch/arm64/kvm/nested.c | 98 +++++++++++++++++++++++++++++------------
 2 files changed, 121 insertions(+), 29 deletions(-)

diff --git a/arch/arm64/kvm/at.c b/arch/arm64/kvm/at.c
index 927226266081..702ce531afd5 100644
--- a/arch/arm64/kvm/at.c
+++ b/arch/arm64/kvm/at.c
@@ -135,6 +135,30 @@ static void compute_s1poe(struct kvm_vcpu *vcpu, struct s1_walk_info *wi)
 	wi->e0poe = (wi->regime != TR_EL2) && (val & TCR2_EL1_E0POE);
 }
 
+#define _has_tgran(__r, __sz)					\
+	({							\
+		u64 _s1, _mmfr0 = __r;				\
+								\
+		_s1 = SYS_FIELD_GET(ID_AA64MMFR0_EL1,		\
+				    TGRAN##__sz, _mmfr0);	\
+								\
+		_s1 != ID_AA64MMFR0_EL1_TGRAN##__sz##_NI;	\
+	})
+
+static bool has_tgran(u64 mmfr0, unsigned int shift)
+{
+	switch (shift) {
+	case 12:
+		return _has_tgran(mmfr0, 4);
+	case 14:
+		return _has_tgran(mmfr0, 16);
+	case 16:
+		return _has_tgran(mmfr0, 64);
+	default:
+		BUG();
+	}
+}
+
 static unsigned int tcr_to_tg0_pgshift(u64 tcr)
 {
 	u64 tg0 = tcr & TCR_TG0_MASK;
@@ -165,8 +189,23 @@ static unsigned int tcr_to_tg1_pgshift(u64 tcr)
 	}
 }
 
-static unsigned int tcr_tg_pgshift(u64 tcr, bool upper_range)
+static unsigned int fallback_tgran_shift(u64 mmfr0)
+{
+	if (has_tgran(mmfr0, PAGE_SHIFT))
+		return PAGE_SHIFT;
+	else if (has_tgran(mmfr0, 12))
+		return 12;
+	else if (has_tgran(mmfr0, 14))
+		return 14;
+	else if (has_tgran(mmfr0, 16))
+		return 16;
+	else
+		return PAGE_SHIFT;
+}
+
+static unsigned int tcr_tg_pgshift(struct kvm *kvm, u64 tcr, bool upper_range)
 {
+	u64 mmfr0 = kvm_read_vm_id_reg(kvm, SYS_ID_AA64MMFR0_EL1);
 	unsigned int shift;
 
 	/* Someone was silly enough to encode TG0/TG1 differently */
@@ -175,6 +214,15 @@ static unsigned int tcr_tg_pgshift(u64 tcr, bool upper_range)
 	else
 		shift = tcr_to_tg0_pgshift(tcr);
 
+	/*
+	 * If TGx is programmed to an unimplemented value (not advertised in
+	 * ID_AA64MMFR0_EL1), we should treat it as if an implemented value is
+	 * written, as per the architecture. Choose an available one while
+	 * prioritizing PAGE_SIZE.
+	 */
+	if (!has_tgran(mmfr0, shift))
+		return fallback_tgran_shift(mmfr0);
+
 	return shift;
 }
 
@@ -222,7 +270,7 @@ static int setup_s1_walk(struct kvm_vcpu *vcpu, struct s1_walk_info *wi,
 	else
 		wi->txsz = FIELD_GET(TCR_T0SZ_MASK, tcr);
 
-	wi->pgshift = tcr_tg_pgshift(tcr, upper_range);
+	wi->pgshift = tcr_tg_pgshift(vcpu->kvm, tcr, upper_range);
 	wi->pa52bit = has_52bit_pa(vcpu, wi, tcr);
 
 	ia_bits = get_ia_size(wi);
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index a732d7b0bd5d..327a6aaa45db 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -378,25 +378,83 @@ static int walk_nested_s2_pgd(struct kvm_vcpu *vcpu, phys_addr_t ipa,
 	return 0;
 }
 
+#define _has_tgran_2(__r, __sz)						\
+	({								\
+		u64 _s1, _s2, _mmfr0 = __r;				\
+									\
+		_s2 = SYS_FIELD_GET(ID_AA64MMFR0_EL1,			\
+				    TGRAN##__sz##_2, _mmfr0);		\
+									\
+		_s1 = SYS_FIELD_GET(ID_AA64MMFR0_EL1,			\
+				    TGRAN##__sz, _mmfr0);		\
+									\
+		((_s2 != ID_AA64MMFR0_EL1_TGRAN##__sz##_2_NI &&		\
+		  _s2 != ID_AA64MMFR0_EL1_TGRAN##__sz##_2_TGRAN##__sz) || \
+		 (_s2 == ID_AA64MMFR0_EL1_TGRAN##__sz##_2_TGRAN##__sz && \
+		  _s1 != ID_AA64MMFR0_EL1_TGRAN##__sz##_NI));		\
+	})
+
+static bool has_tgran_2(u64 mmfr0, unsigned int shift)
+{
+	switch (shift) {
+	case 12:
+		return _has_tgran_2(mmfr0, 4);
+	case 14:
+		return _has_tgran_2(mmfr0, 16);
+	case 16:
+		return _has_tgran_2(mmfr0, 64);
+	default:
+		BUG();
+	}
+}
+
+static unsigned int fallback_tgran2_shift(u64 mmfr0)
+{
+	if (has_tgran_2(mmfr0, PAGE_SHIFT))
+		return PAGE_SHIFT;
+	else if (has_tgran_2(mmfr0, 12))
+		return 12;
+	else if (has_tgran_2(mmfr0, 14))
+		return 14;
+	else if (has_tgran_2(mmfr0, 16))
+		return 16;
+	else
+		return PAGE_SHIFT;
+}
 
-static unsigned int vtcr_to_tg0_pgshift(u64 vtcr)
+static unsigned int vtcr_to_tg0_pgshift(struct kvm *kvm, u64 vtcr)
 {
 	u64 tg0 = FIELD_GET(VTCR_EL2_TG0_MASK, vtcr);
+	u64 mmfr0 = kvm_read_vm_id_reg(kvm, SYS_ID_AA64MMFR0_EL1);
+	unsigned int shift;
 
 	switch (tg0) {
 	case VTCR_EL2_TG0_4K:
-		return 12;
+		shift = 12;
+		break;
 	case VTCR_EL2_TG0_16K:
-		return 14;
+		shift = 14;
+		break;
 	case VTCR_EL2_TG0_64K:
 	default:	/* IMPDEF: treat any other value as 64k */
-		return 16;
+		shift = 16;
 	}
+
+	/*
+	 * If TGx is programmed to an unimplemented value (not advertised in
+	 * ID_AA64MMFR0_EL1), we should treat it as if an implemented value is
+	 * written, as per the architecture. Choose an available one while
+	 * prioritizing PAGE_SIZE.
+	 */
+	if (!has_tgran_2(mmfr0, shift))
+		return fallback_tgran2_shift(mmfr0);
+
+	return shift;
 }
 
-static size_t vtcr_to_tg0_pgsize(u64 vtcr)
+static size_t vtcr_to_tg0_pgsize(struct kvm *kvm, u64 vtcr)
 {
-	return BIT(vtcr_to_tg0_pgshift(vtcr));
+	return BIT(vtcr_to_tg0_pgshift(kvm, vtcr));
 }
 
 static void setup_s2_walk(struct kvm_vcpu *vcpu, struct s2_walk_info *wi)
@@ -405,7 +463,7 @@ static void setup_s2_walk(struct kvm_vcpu *vcpu, struct s2_walk_info *wi)
 
 	wi->baddr = vcpu_read_sys_reg(vcpu, VTTBR_EL2);
 	wi->t0sz = vtcr & VTCR_EL2_T0SZ_MASK;
-	wi->pgshift = vtcr_to_tg0_pgshift(vtcr);
+	wi->pgshift = vtcr_to_tg0_pgshift(vcpu->kvm, vtcr);
 	wi->sl = FIELD_GET(VTCR_EL2_SL0_MASK, vtcr);
 	/* Global limit for now, should eventually be per-VM */
 	wi->max_oa_bits = min(get_kvm_ipa_limit(),
@@ -524,7 +582,8 @@ static u8 get_guest_mapping_ttl(struct kvm_s2_mmu *mmu, u64 addr)
 	u64 tmp, sz = 0;
 	kvm_pte_t pte;
 	u8 ttl, level;
-	size_t tg0_size = vtcr_to_tg0_pgsize(mmu->tlb_vtcr);
+	struct kvm *kvm = kvm_s2_mmu_to_kvm(mmu);
+	size_t tg0_size = vtcr_to_tg0_pgsize(kvm, mmu->tlb_vtcr);
 
 	lockdep_assert_held_write(&kvm_s2_mmu_to_kvm(mmu)->mmu_lock);
 
@@ -608,7 +667,7 @@ unsigned long compute_tlb_inval_range(struct kvm_s2_mmu *mmu, u64 val)
 
 	if (!max_size) {
 		/* Compute the maximum extent of the invalidation */
-		switch (vtcr_to_tg0_pgsize(mmu->tlb_vtcr)) {
+		switch (vtcr_to_tg0_pgsize(kvm, mmu->tlb_vtcr)) {
 		case SZ_4K:
 			max_size = SZ_1G;
 			break;
@@ -1504,21 +1563,6 @@ static void kvm_map_l1_vncr(struct kvm_vcpu *vcpu)
 	}
 }
 
-#define has_tgran_2(__r, __sz)						\
-	({								\
-		u64 _s1, _s2, _mmfr0 = __r;				\
-									\
-		_s2 = SYS_FIELD_GET(ID_AA64MMFR0_EL1,			\
-				    TGRAN##__sz##_2, _mmfr0);		\
-									\
-		_s1 = SYS_FIELD_GET(ID_AA64MMFR0_EL1,			\
-				    TGRAN##__sz, _mmfr0);		\
-									\
-		((_s2 != ID_AA64MMFR0_EL1_TGRAN##__sz##_2_NI &&		\
-		  _s2 != ID_AA64MMFR0_EL1_TGRAN##__sz##_2_TGRAN##__sz) || \
-		 (_s2 == ID_AA64MMFR0_EL1_TGRAN##__sz##_2_TGRAN##__sz && \
-		  _s1 != ID_AA64MMFR0_EL1_TGRAN##__sz##_NI));		\
-	})
 /*
  * Our emulated CPU doesn't support all the possible features. For the
  * sake of simplicity (and probably mental sanity), wipe out a number
@@ -1600,15 +1644,15 @@ u64 limit_nv_id_reg(struct kvm *kvm, u32 reg, u64 val)
 		 */
 		switch (PAGE_SIZE) {
 		case SZ_4K:
-			if (has_tgran_2(orig_val, 4))
+			if (_has_tgran_2(orig_val, 4))
 				val |= SYS_FIELD_PREP_ENUM(ID_AA64MMFR0_EL1, TGRAN4_2, IMP);
 			fallthrough;
 		case SZ_16K:
-			if (has_tgran_2(orig_val, 16))
+			if (_has_tgran_2(orig_val, 16))
 				val |= SYS_FIELD_PREP_ENUM(ID_AA64MMFR0_EL1, TGRAN16_2, IMP);
 			fallthrough;
 		case SZ_64K:
-			if (has_tgran_2(orig_val, 64))
+			if (_has_tgran_2(orig_val, 64))
 				val |= SYS_FIELD_PREP_ENUM(ID_AA64MMFR0_EL1, TGRAN64_2, IMP);
 			break;
 		}
-- 
2.43.0



^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox