Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 09/15] KVM: arm64: vgic-v5: align priority comparison with other GICs
From: Marc Zyngier @ 2026-03-31 17:18 UTC (permalink / raw)
  To: Sascha Bischoff
  Cc: kvmarm@lists.linux.dev, kvm@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, Joey Gouly,
	yuzenghui@huawei.com, Suzuki Poulose, oupton@kernel.org,
	broonie@kernel.org, nd
In-Reply-To: <729851f0e7d277d308adf04d0008156a01f482bb.camel@arm.com>

On Tue, 31 Mar 2026 16:09:10 +0100,
Sascha Bischoff <Sascha.Bischoff@arm.com> wrote:
> 
> On Thu, 2026-03-26 at 15:35 +0000, Marc Zyngier wrote:
> > The way the effective priority mask is computed, and then compared
> > to the priority of an interrupt to decide whether to wake-up or not,
> > is slightly odd, and breaks at the limits.
> > 
> > This could result in spurious wake-ups that are undesirable.
> > 
> > Adopt the GICv[23] logic instead, which checks that the priority
> > value
> > is strictly lower than the mask.
> > 
> > Fixes: 933e5288fa971 ("KVM: arm64: gic-v5: Check for pending PPIs")
> > Link:
> > https://sashiko.dev/#/patchset/20260319154937.3619520-1-sascha.bischoff%40arm.com
> > Signed-off-by: Marc Zyngier <maz@kernel.org>
> > ---
> >  arch/arm64/kvm/vgic/vgic-v5.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/arch/arm64/kvm/vgic/vgic-v5.c
> > b/arch/arm64/kvm/vgic/vgic-v5.c
> > index 0f269321ece4b..75372bbfb6a6a 100644
> > --- a/arch/arm64/kvm/vgic/vgic-v5.c
> > +++ b/arch/arm64/kvm/vgic/vgic-v5.c
> > @@ -238,7 +238,7 @@ static u32
> > vgic_v5_get_effective_priority_mask(struct kvm_vcpu *vcpu)
> >  	 */
> >  	priority_mask = FIELD_GET(FEAT_GCIE_ICH_VMCR_EL2_VPMR,
> > cpu_if->vgic_vmcr);
> >  
> > -	return min(highest_ap, priority_mask + 1);
> > +	return min(highest_ap, priority_mask);
> 
> Hi Marc,
> 
> This part of your change (dropping the `- 1`) is not correct for GICv5.
> The GICv[23] PMR works differently to the GICv5 PCR.
> 
> For GICv[23] the mask is exclusive, i.e., only higher priority (lower
> numerical value) interrupts are of sufficient priority to be signalled.
> 
> For GICv5, the priority of an interrupt can be equal to or higher than
> (numerically lower than) the mask. See DMSQKF in the GICv5 spec:
> 
> A physical interrupt has Sufficient priority to be signaled when all of
> the following are true:
>    * The priority of the interrupt is higher than the physical running
>    priority for the Physical Interrupt Domain.
>    * The priority of the interrupt is equal to or higher than the
>    Physical Priority Mask for the Physical Interrupt Domain.
>    
> Therefore, we require this `+ 1` for the priority_mask in order to allow
> us to combine the active priority and priority mask. Else, they operate on
> different scales.
> 
> I'd tried to explain this in a comment that lies just outside the diff,
> but hadn't explicitly called out that GICv5 operates differently to
> GICv[23] in this regard. Apologies.

Nothing to apologise about, this is me not being able to read.

>    
> >  }
> >  
> >  /*
> > @@ -367,7 +367,7 @@ bool vgic_v5_has_pending_ppi(struct kvm_vcpu
> > *vcpu)
> >  
> >  		scoped_guard(raw_spinlock_irqsave, &irq->irq_lock)
> >  			has_pending = (irq->enabled &&
> > irq_is_pending(irq) &&
> > -				       irq->priority <=
> > priority_mask);
> > +				       irq->priority <
> > priority_mask);
> 
> I agree that this was wrong and should never have included the
> equality. This was definitely a bug!

Cool. I'll revert the revert of the first hunk and keep the second
one.

Thanks!

	M.

-- 
Without deviation from the norm, progress is not possible.


^ permalink raw reply

* Re: [PATCH v4 0/8] Bluetooth: Add MediaTek MT7927 (MT6639) support
From: Javier Tia @ 2026-03-31 17:10 UTC (permalink / raw)
  To: Luiz Augusto von Dentz
  Cc: Marcel Holtmann, Matthias Brugger, AngeloGioacchino Del Regno,
	linux-bluetooth, linux-kernel, linux-arm-kernel, linux-mediatek,
	Ryan Gilbert, Jose Tiburcio Ribeiro Netto, Llewellyn Curran,
	Chapuis Dario, Evgeny Kapusta, Nitin Gurram, Thibaut FRANCOIS,
	Ivan Lubnin

Hi Luiz,

On Tue, 31 Mar 2026 Luiz Augusto von Dentz wrote:
> Ok, but on 8/8 it seem to suggest the problem still exists which
> trigger the following review:
>
> https://sashiko.dev/#/patchset/20260330-mt7927-bt-support-v4-0-cecc025e7062%40jetm.me
>
> Perhaps we should ajust the commit description if the 19 seconds
> doesn't really occurs when 2/8 is applied.

Good catch. The ~19 second delay is indeed fixed by patch 2/8, so the
note in 8/8 was misleading as written.

I've updated the commit message in 8/8 to clarify:

  Note: boards with this USB ID expose only one ISO alternate setting
  (alt 0). Without the fix in patch 2/8 ("btmtk: fix ISO interface
  setup for single alt setting"), this caused ~19 second initialization
  delays. With the fix applied, initialization completes in ~2.6
  seconds.

This is addressed in v5:
https://lore.kernel.org/linux-bluetooth/20260331-mt7927-bt-support-v5-0-6f31b4342daa@jetm.me/

Best,
Javier


^ permalink raw reply

* [PATCH v5 8/8] Bluetooth: btusb: Add MT7927 ID for ASUS X870E / ProArt X870E-Creator
From: Javier Tia @ 2026-03-31 17:09 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz, Matthias Brugger,
	AngeloGioacchino Del Regno
  Cc: linux-bluetooth, linux-kernel, linux-arm-kernel, linux-mediatek,
	Jose Tiburcio Ribeiro Netto, Ivan Lubnin
In-Reply-To: <20260331-mt7927-bt-support-v5-0-6f31b4342daa@jetm.me>

Add USB device ID 13d3:3588 (IMC Networks/Azurewave) for the MediaTek
MT7927 (Filogic 380) Bluetooth interface found on the ASUS ROG STRIX
X870E-E GAMING WIFI and ASUS ProArt X870E-Creator WiFi motherboards.

Note: boards with this USB ID expose only one ISO alternate setting
(alt 0). Without the fix in patch 2/8 ("btmtk: fix ISO interface
setup for single alt setting"), this caused ~19 second initialization
delays. With the fix applied, initialization completes in ~2.6
seconds.

The information in /sys/kernel/debug/usb/devices about the Bluetooth
device is listed as the below.

T:  Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  5 Spd=480  MxCh= 0
D:  Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=13d3 ProdID=3588 Rev= 1.00
S:  Manufacturer=MediaTek Inc.
S:  Product=Wireless_Device
S:  SerialNumber=000000000
C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA
A:  FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01
I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=125us
E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=   0 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=   0 Ivl=1ms
I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us
E:  Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us

Link: https://bugzilla.kernel.org/show_bug.cgi?id=221096
Link: https://github.com/openwrt/mt76/issues/927
Signed-off-by: Javier Tia <floss@jetm.me>
Tested-by: Jose Tiburcio Ribeiro Netto <jnetto@mineiro.io>
Tested-by: Ivan Lubnin <lubnin.ivan@gmail.com>
---
 drivers/bluetooth/btusb.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 55a000540439..45ef0d008bce 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -761,6 +761,8 @@ static const struct usb_device_id quirks_table[] = {
 						     BTUSB_WIDEBAND_SPEECH },
 	{ USB_DEVICE(0x0489, 0xe116), .driver_info = BTUSB_MEDIATEK |
 						     BTUSB_WIDEBAND_SPEECH },
+	{ USB_DEVICE(0x13d3, 0x3588), .driver_info = BTUSB_MEDIATEK |
+						     BTUSB_WIDEBAND_SPEECH },
 	{ USB_DEVICE(0x0489, 0xe14e), .driver_info = BTUSB_MEDIATEK |
 						     BTUSB_WIDEBAND_SPEECH },
 	{ USB_DEVICE(0x0489, 0xe14f), .driver_info = BTUSB_MEDIATEK |

-- 
2.53.0



^ permalink raw reply related

* [PATCH v5 7/8] Bluetooth: btusb: Add MT7927 ID for TP-Link Archer TBE550E
From: Javier Tia @ 2026-03-31 17:09 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz, Matthias Brugger,
	AngeloGioacchino Del Regno
  Cc: linux-bluetooth, linux-kernel, linux-arm-kernel, linux-mediatek,
	Thibaut FRANCOIS
In-Reply-To: <20260331-mt7927-bt-support-v5-0-6f31b4342daa@jetm.me>

Add USB device ID 0489:e116 (Foxconn/Hon Hai) for the MediaTek MT7927
(Filogic 380) Bluetooth interface found on the TP-Link Archer TBE550E
PCIe adapter.

The information in /sys/kernel/debug/usb/devices about the Bluetooth
device is listed as the below.

T:  Bus=01 Lev=01 Prnt=01 Port=05 Cnt=04 Dev#=  5 Spd=480  MxCh= 0
D:  Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=0489 ProdID=e116 Rev= 1.00
S:  Manufacturer=MediaTek Inc.
S:  Product=Wireless_Device
S:  SerialNumber=000000000
C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA
A:  FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01
I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=125us
E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=   0 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=   0 Ivl=1ms
I:  If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
...
I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us
E:  Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us

Link: https://bugzilla.kernel.org/show_bug.cgi?id=221096
Link: https://github.com/openwrt/mt76/issues/927
Signed-off-by: Javier Tia <floss@jetm.me>
Tested-by: Thibaut FRANCOIS <tibo@humeurlibre.fr>
---
 drivers/bluetooth/btusb.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 96882e9b831c..55a000540439 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -759,6 +759,8 @@ static const struct usb_device_id quirks_table[] = {
 						     BTUSB_WIDEBAND_SPEECH },
 	{ USB_DEVICE(0x0489, 0xe110), .driver_info = BTUSB_MEDIATEK |
 						     BTUSB_WIDEBAND_SPEECH },
+	{ USB_DEVICE(0x0489, 0xe116), .driver_info = BTUSB_MEDIATEK |
+						     BTUSB_WIDEBAND_SPEECH },
 	{ USB_DEVICE(0x0489, 0xe14e), .driver_info = BTUSB_MEDIATEK |
 						     BTUSB_WIDEBAND_SPEECH },
 	{ USB_DEVICE(0x0489, 0xe14f), .driver_info = BTUSB_MEDIATEK |

-- 
2.53.0



^ permalink raw reply related

* [PATCH v5 6/8] Bluetooth: btusb: Add MT7927 ID for MSI X870E Ace Max
From: Javier Tia @ 2026-03-31 17:09 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz, Matthias Brugger,
	AngeloGioacchino Del Regno
  Cc: linux-bluetooth, linux-kernel, linux-arm-kernel, linux-mediatek,
	Nitin Gurram
In-Reply-To: <20260331-mt7927-bt-support-v5-0-6f31b4342daa@jetm.me>

Add USB device ID 0489:e110 (Foxconn/Hon Hai) for the MediaTek MT7927
(Filogic 380) Bluetooth interface found on the MSI X870E Ace Max
motherboard.

The information in /sys/kernel/debug/usb/devices about the Bluetooth
device is listed as the below.

T:  Bus=01 Lev=01 Prnt=01 Port=05 Cnt=04 Dev#=  5 Spd=480  MxCh= 0
D:  Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=0489 ProdID=e110 Rev= 1.00
S:  Manufacturer=MediaTek Inc.
S:  Product=Wireless_Device
S:  SerialNumber=000000000
C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA
A:  FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01
I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=125us
E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=   0 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=   0 Ivl=1ms
I:  If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
...
I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us
E:  Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us

Link: https://bugzilla.kernel.org/show_bug.cgi?id=221096
Link: https://github.com/openwrt/mt76/issues/927
Signed-off-by: Javier Tia <floss@jetm.me>
Tested-by: Nitin Gurram <nitin.reddy88@gmail.com>
---
 drivers/bluetooth/btusb.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index d60798331bb3..96882e9b831c 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -757,6 +757,8 @@ static const struct usb_device_id quirks_table[] = {
 						     BTUSB_WIDEBAND_SPEECH },
 	{ USB_DEVICE(0x0489, 0xe10f), .driver_info = BTUSB_MEDIATEK |
 						     BTUSB_WIDEBAND_SPEECH },
+	{ USB_DEVICE(0x0489, 0xe110), .driver_info = BTUSB_MEDIATEK |
+						     BTUSB_WIDEBAND_SPEECH },
 	{ USB_DEVICE(0x0489, 0xe14e), .driver_info = BTUSB_MEDIATEK |
 						     BTUSB_WIDEBAND_SPEECH },
 	{ USB_DEVICE(0x0489, 0xe14f), .driver_info = BTUSB_MEDIATEK |

-- 
2.53.0



^ permalink raw reply related

* [PATCH v5 5/8] Bluetooth: btusb: Add MT7927 ID for Gigabyte Z790 AORUS MASTER X
From: Javier Tia @ 2026-03-31 17:09 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz, Matthias Brugger,
	AngeloGioacchino Del Regno
  Cc: linux-bluetooth, linux-kernel, linux-arm-kernel, linux-mediatek,
	Chapuis Dario, Evgeny Kapusta
In-Reply-To: <20260331-mt7927-bt-support-v5-0-6f31b4342daa@jetm.me>

Add USB device ID 0489:e10f (Foxconn/Hon Hai) for the MediaTek MT7927
(Filogic 380) Bluetooth interface found on the Gigabyte Z790 AORUS
MASTER X motherboard.

The information in /sys/kernel/debug/usb/devices about the Bluetooth
device is listed as the below.

T:  Bus=01 Lev=01 Prnt=01 Port=05 Cnt=04 Dev#=  5 Spd=480  MxCh= 0
D:  Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=0489 ProdID=e10f Rev= 1.00
S:  Manufacturer=MediaTek Inc.
S:  Product=Wireless_Device
S:  SerialNumber=000000000
C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA
A:  FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01
I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=125us
E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=   0 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=   0 Ivl=1ms
I:  If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
...
I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us
E:  Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us

Link: https://bugzilla.kernel.org/show_bug.cgi?id=221096
Link: https://github.com/openwrt/mt76/issues/927
Signed-off-by: Javier Tia <floss@jetm.me>
Tested-by: Chapuis Dario <chapuisdario4@gmail.com>
Tested-by: Evgeny Kapusta <3193631@gmail.com>
---
 drivers/bluetooth/btusb.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 2c9ca3d6016b..d60798331bb3 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -755,6 +755,8 @@ static const struct usb_device_id quirks_table[] = {
 						     BTUSB_WIDEBAND_SPEECH },
 	{ USB_DEVICE(0x0489, 0xe0fa), .driver_info = BTUSB_MEDIATEK |
 						     BTUSB_WIDEBAND_SPEECH },
+	{ USB_DEVICE(0x0489, 0xe10f), .driver_info = BTUSB_MEDIATEK |
+						     BTUSB_WIDEBAND_SPEECH },
 	{ USB_DEVICE(0x0489, 0xe14e), .driver_info = BTUSB_MEDIATEK |
 						     BTUSB_WIDEBAND_SPEECH },
 	{ USB_DEVICE(0x0489, 0xe14f), .driver_info = BTUSB_MEDIATEK |

-- 
2.53.0



^ permalink raw reply related

* [PATCH v5 4/8] Bluetooth: btusb: Add MT7927 ID for Lenovo Legion Pro 7 16ARX9
From: Javier Tia @ 2026-03-31 17:09 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz, Matthias Brugger,
	AngeloGioacchino Del Regno
  Cc: linux-bluetooth, linux-kernel, linux-arm-kernel, linux-mediatek,
	Llewellyn Curran
In-Reply-To: <20260331-mt7927-bt-support-v5-0-6f31b4342daa@jetm.me>

Add USB device ID 0489:e0fa (Foxconn/Hon Hai) for the MediaTek MT7927
(Filogic 380) Bluetooth interface found on the Lenovo Legion Pro 7
16ARX9 laptop.

The information in /sys/kernel/debug/usb/devices about the Bluetooth
device is listed as the below.

T:  Bus=01 Lev=01 Prnt=01 Port=05 Cnt=04 Dev#=  5 Spd=480  MxCh= 0
D:  Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=0489 ProdID=e0fa Rev= 1.00
S:  Manufacturer=MediaTek Inc.
S:  Product=Wireless_Device
S:  SerialNumber=000000000
C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA
A:  FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01
I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=125us
E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=   0 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=   0 Ivl=1ms
I:  If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
...
I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us
E:  Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us

Link: https://bugzilla.kernel.org/show_bug.cgi?id=221096
Link: https://github.com/openwrt/mt76/issues/927
Signed-off-by: Javier Tia <floss@jetm.me>
Tested-by: Llewellyn Curran <melinko2003@gmail.com>
---
 drivers/bluetooth/btusb.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 58309af0f7a2..2c9ca3d6016b 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -753,6 +753,8 @@ static const struct usb_device_id quirks_table[] = {
 						     BTUSB_WIDEBAND_SPEECH },
 	{ USB_DEVICE(0x0489, 0xe13a), .driver_info = BTUSB_MEDIATEK |
 						     BTUSB_WIDEBAND_SPEECH },
+	{ USB_DEVICE(0x0489, 0xe0fa), .driver_info = BTUSB_MEDIATEK |
+						     BTUSB_WIDEBAND_SPEECH },
 	{ USB_DEVICE(0x0489, 0xe14e), .driver_info = BTUSB_MEDIATEK |
 						     BTUSB_WIDEBAND_SPEECH },
 	{ USB_DEVICE(0x0489, 0xe14f), .driver_info = BTUSB_MEDIATEK |

-- 
2.53.0



^ permalink raw reply related

* [PATCH v5 3/8] Bluetooth: btusb: Add MT7927 ID for ASUS ROG Crosshair X870E Hero
From: Javier Tia @ 2026-03-31 17:09 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz, Matthias Brugger,
	AngeloGioacchino Del Regno
  Cc: linux-bluetooth, linux-kernel, linux-arm-kernel, linux-mediatek,
	Jose Tiburcio Ribeiro Netto
In-Reply-To: <20260331-mt7927-bt-support-v5-0-6f31b4342daa@jetm.me>

Add USB device ID 0489:e13a (Foxconn/Hon Hai) for the MediaTek MT7927
(Filogic 380) Bluetooth interface found on the ASUS ROG Crosshair X870E
Hero WiFi motherboard.

The information in /sys/kernel/debug/usb/devices about the Bluetooth
device is listed as the below.

T:  Bus=01 Lev=01 Prnt=01 Port=05 Cnt=04 Dev#=  5 Spd=480  MxCh= 0
D:  Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=0489 ProdID=e13a Rev= 1.00
S:  Manufacturer=MediaTek Inc.
S:  Product=Wireless_Device
S:  SerialNumber=000000000
C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA
A:  FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01
I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=125us
E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=   0 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=   0 Ivl=1ms
I:  If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
...
I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us
E:  Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us

Link: https://bugzilla.kernel.org/show_bug.cgi?id=221096
Link: https://github.com/openwrt/mt76/issues/927
Signed-off-by: Javier Tia <floss@jetm.me>
Tested-by: Jose Tiburcio Ribeiro Netto <jnetto@mineiro.io>
---
 drivers/bluetooth/btusb.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index a5e44887a5b5..58309af0f7a2 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -751,6 +751,8 @@ static const struct usb_device_id quirks_table[] = {
 						     BTUSB_WIDEBAND_SPEECH },
 	{ USB_DEVICE(0x0489, 0xe139), .driver_info = BTUSB_MEDIATEK |
 						     BTUSB_WIDEBAND_SPEECH },
+	{ USB_DEVICE(0x0489, 0xe13a), .driver_info = BTUSB_MEDIATEK |
+						     BTUSB_WIDEBAND_SPEECH },
 	{ USB_DEVICE(0x0489, 0xe14e), .driver_info = BTUSB_MEDIATEK |
 						     BTUSB_WIDEBAND_SPEECH },
 	{ USB_DEVICE(0x0489, 0xe14f), .driver_info = BTUSB_MEDIATEK |

-- 
2.53.0



^ permalink raw reply related

* [PATCH v5 2/8] Bluetooth: btmtk: fix ISO interface setup for single alt setting
From: Javier Tia @ 2026-03-31 17:09 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz, Matthias Brugger,
	AngeloGioacchino Del Regno
  Cc: linux-bluetooth, linux-kernel, linux-arm-kernel, linux-mediatek,
	Ryan Gilbert
In-Reply-To: <20260331-mt7927-bt-support-v5-0-6f31b4342daa@jetm.me>

Some MT6639 Bluetooth USB interfaces (e.g. IMC Networks 13d3:3588 on
ASUS ROG STRIX X870E-E and ProArt X870E-Creator boards) expose only a
single alternate setting (alt 0) on the ISO interface. The driver
unconditionally requests alt setting 1, which fails with EINVAL on
these devices, causing a ~20 second initialization delay and no LE
audio support.

Check the number of available alternate settings before selecting one.
If only alt 0 exists, use it; otherwise request alt 1 as before.

Closes: https://github.com/jetm/mediatek-mt7927-dkms/pull/39
Signed-off-by: Javier Tia <floss@jetm.me>
Reported-by: Ryan Gilbert <xelnaga@gmail.com>
Tested-by: Ryan Gilbert <xelnaga@gmail.com>
---
 drivers/bluetooth/btmtk.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
index 4af19b86c551..f8cff895f14c 100644
--- a/drivers/bluetooth/btmtk.c
+++ b/drivers/bluetooth/btmtk.c
@@ -1029,7 +1029,8 @@ static int __set_mtk_intr_interface(struct hci_dev *hdev)
 	if (!btmtk_data->isopkt_intf)
 		return -ENODEV;
 
-	err = usb_set_interface(btmtk_data->udev, MTK_ISO_IFNUM, 1);
+	err = usb_set_interface(btmtk_data->udev, MTK_ISO_IFNUM,
+			       (intf->num_altsetting > 1) ? 1 : 0);
 	if (err < 0) {
 		bt_dev_err(hdev, "setting interface failed (%d)", -err);
 		return err;

-- 
2.53.0



^ permalink raw reply related

* [PATCH v5 1/8] Bluetooth: btmtk: Add MT6639 (MT7927) Bluetooth support
From: Javier Tia @ 2026-03-31 17:09 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz, Matthias Brugger,
	AngeloGioacchino Del Regno
  Cc: linux-bluetooth, linux-kernel, linux-arm-kernel, linux-mediatek,
	Ryan Gilbert
In-Reply-To: <20260331-mt7927-bt-support-v5-0-6f31b4342daa@jetm.me>

The MediaTek MT7927 (Filogic 380) combo WiFi 7 + BT 5.4 module uses
hardware variant 0x6639 for its Bluetooth subsystem. Without this patch,
the chip fails with "Unsupported hardware variant (00006639)" or hangs
during firmware download.

Three changes are needed to support MT6639:

1. CHIPID workaround: On some boards the BT USB MMIO register reads
   0x0000 for dev_id, causing the driver to skip the 0x6639 init path.
   Force dev_id to 0x6639 only when the USB VID/PID matches a known
   MT6639 device, avoiding misdetection if a future chip also reads
   zero. This follows the WiFi-side pattern that uses PCI device IDs
   to scope the same workaround.

2. Firmware naming: MT6639 uses firmware version prefix "2_1" instead of
   "1_1" used by MT7925 and other variants. The firmware path is
   mediatek/mt7927/BT_RAM_CODE_MT6639_2_1_hdr.bin, using the mt7927
   directory to match the WiFi firmware convention. The filename will
   likely change to use MT7927 once MediaTek submits a dedicated
   Linux firmware binary.

3. Section filtering: The MT6639 firmware binary contains 9 sections, but
   only sections with (dlmodecrctype & 0xff) == 0x01 are Bluetooth-related.
   Sending the remaining WiFi/other sections causes an irreversible BT
   subsystem hang requiring a full power cycle. This matches the Windows
   driver behavior observed via USB captures.

Also add 0x6639 to the reset register (CONNV3) and firmware setup switch
cases alongside the existing 0x7925 handling.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=221096
Link: https://github.com/openwrt/mt76/issues/927
Reported-by: Ryan Gilbert <xelnaga@gmail.com>
Signed-off-by: Javier Tia <floss@jetm.me>
---
 drivers/bluetooth/btmtk.c     | 60 +++++++++++++++++++++++++++++++++++++++----
 drivers/bluetooth/btmtk.h     |  7 +++--
 drivers/bluetooth/btmtksdio.c |  2 +-
 3 files changed, 61 insertions(+), 8 deletions(-)

diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
index 2507d587f28a..4af19b86c551 100644
--- a/drivers/bluetooth/btmtk.c
+++ b/drivers/bluetooth/btmtk.c
@@ -25,6 +25,22 @@
 /* It is for mt79xx iso data transmission setting */
 #define MTK_ISO_THRESHOLD	264
 
+/* Known MT6639 (MT7927) Bluetooth USB devices.
+ * Used to scope the zero-CHIPID workaround to real MT6639 hardware,
+ * since some boards return 0x0000 from the MMIO chip ID register.
+ */
+static const struct {
+	u16 vendor;
+	u16 product;
+} btmtk_mt6639_devs[] = {
+	{ 0x0489, 0xe13a },	/* ASUS ROG Crosshair X870E Hero */
+	{ 0x0489, 0xe0fa },	/* Lenovo Legion Pro 7 16ARX9 */
+	{ 0x0489, 0xe10f },	/* Gigabyte Z790 AORUS MASTER X */
+	{ 0x0489, 0xe110 },	/* MSI X870E Ace Max */
+	{ 0x0489, 0xe116 },	/* TP-Link Archer TBE550E */
+	{ 0x13d3, 0x3588 },	/* ASUS ROG STRIX X870E-E */
+};
+
 struct btmtk_patch_header {
 	u8 datetime[16];
 	u8 platform[4];
@@ -112,7 +128,11 @@ static void btmtk_coredump_notify(struct hci_dev *hdev, int state)
 void btmtk_fw_get_filename(char *buf, size_t size, u32 dev_id, u32 fw_ver,
 			   u32 fw_flavor)
 {
-	if (dev_id == 0x7925)
+	if (dev_id == 0x6639)
+		snprintf(buf, size,
+			 "mediatek/mt7927/BT_RAM_CODE_MT%04x_2_%x_hdr.bin",
+			 dev_id & 0xffff, (fw_ver & 0xff) + 1);
+	else if (dev_id == 0x7925)
 		snprintf(buf, size,
 			 "mediatek/mt%04x/BT_RAM_CODE_MT%04x_1_%x_hdr.bin",
 			 dev_id & 0xffff, dev_id & 0xffff, (fw_ver & 0xff) + 1);
@@ -128,7 +148,8 @@ void btmtk_fw_get_filename(char *buf, size_t size, u32 dev_id, u32 fw_ver,
 EXPORT_SYMBOL_GPL(btmtk_fw_get_filename);
 
 int btmtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwname,
-			      wmt_cmd_sync_func_t wmt_cmd_sync)
+			      wmt_cmd_sync_func_t wmt_cmd_sync,
+			      u32 dev_id)
 {
 	struct btmtk_hci_wmt_params wmt_params;
 	struct btmtk_patch_header *hdr;
@@ -166,6 +187,14 @@ int btmtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwname,
 		section_offset = le32_to_cpu(sectionmap->secoffset);
 		dl_size = le32_to_cpu(sectionmap->bin_info_spec.dlsize);
 
+		/* MT6639: only download sections where dlmode byte0 == 0x01,
+		 * matching the Windows driver behavior which skips WiFi/other
+		 * sections that would cause the chip to hang.
+		 */
+		if (dev_id == 0x6639 && dl_size > 0 &&
+		    (le32_to_cpu(sectionmap->bin_info_spec.dlmodecrctype) & 0xff) != 0x01)
+			continue;
+
 		if (dl_size > 0) {
 			retry = 20;
 			while (retry > 0) {
@@ -852,7 +881,7 @@ int btmtk_usb_subsys_reset(struct hci_dev *hdev, u32 dev_id)
 		if (err < 0)
 			return err;
 		msleep(100);
-	} else if (dev_id == 0x7925) {
+	} else if (dev_id == 0x7925 || dev_id == 0x6639) {
 		err = btmtk_usb_uhw_reg_read(hdev, MTK_BT_RESET_REG_CONNV3, &val);
 		if (err < 0)
 			return err;
@@ -938,7 +967,7 @@ int btmtk_usb_subsys_reset(struct hci_dev *hdev, u32 dev_id)
 	}
 
 	err = btmtk_usb_id_get(hdev, 0x70010200, &val);
-	if (err < 0 || !val)
+	if (err < 0 || (!val && dev_id != 0x6639))
 		bt_dev_err(hdev, "Can't get device id, subsys reset fail.");
 
 	return err;
@@ -1322,6 +1351,24 @@ int btmtk_usb_setup(struct hci_dev *hdev)
 		fw_flavor = (fw_flavor & 0x00000080) >> 7;
 	}
 
+	if (!dev_id) {
+		u16 vid = le16_to_cpu(btmtk_data->udev->descriptor.idVendor);
+		u16 pid = le16_to_cpu(btmtk_data->udev->descriptor.idProduct);
+		int i;
+
+		for (i = 0; i < ARRAY_SIZE(btmtk_mt6639_devs); i++) {
+			if (vid == btmtk_mt6639_devs[i].vendor &&
+			    pid == btmtk_mt6639_devs[i].product) {
+				dev_id = 0x6639;
+				break;
+			}
+		}
+
+		if (dev_id)
+			bt_dev_info(hdev, "MT6639: CHIPID=0x0000 with VID=%04x PID=%04x, using 0x6639",
+				    vid, pid);
+	}
+
 	btmtk_data->dev_id = dev_id;
 
 	err = btmtk_register_coredump(hdev, btmtk_data->drv_name, fw_version);
@@ -1339,11 +1386,13 @@ int btmtk_usb_setup(struct hci_dev *hdev)
 	case 0x7925:
 	case 0x7961:
 	case 0x7902:
+	case 0x6639:
 		btmtk_fw_get_filename(fw_bin_name, sizeof(fw_bin_name), dev_id,
 				      fw_version, fw_flavor);
 
 		err = btmtk_setup_firmware_79xx(hdev, fw_bin_name,
-						btmtk_usb_hci_wmt_sync);
+						btmtk_usb_hci_wmt_sync,
+						dev_id);
 		if (err < 0) {
 			/* retry once if setup firmware error */
 			if (!test_and_set_bit(BTMTK_FIRMWARE_DL_RETRY, &btmtk_data->flags))
@@ -1516,3 +1565,4 @@ MODULE_FIRMWARE(FIRMWARE_MT7668);
 MODULE_FIRMWARE(FIRMWARE_MT7922);
 MODULE_FIRMWARE(FIRMWARE_MT7961);
 MODULE_FIRMWARE(FIRMWARE_MT7925);
+MODULE_FIRMWARE(FIRMWARE_MT7927);
diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h
index adaf385626ee..c564aedc0ce0 100644
--- a/drivers/bluetooth/btmtk.h
+++ b/drivers/bluetooth/btmtk.h
@@ -8,6 +8,7 @@
 #define FIRMWARE_MT7902		"mediatek/BT_RAM_CODE_MT7902_1_1_hdr.bin"
 #define FIRMWARE_MT7961		"mediatek/BT_RAM_CODE_MT7961_1_2_hdr.bin"
 #define FIRMWARE_MT7925		"mediatek/mt7925/BT_RAM_CODE_MT7925_1_1_hdr.bin"
+#define FIRMWARE_MT7927		"mediatek/mt7927/BT_RAM_CODE_MT6639_2_1_hdr.bin"
 
 #define HCI_EV_WMT 0xe4
 #define HCI_WMT_MAX_EVENT_SIZE		64
@@ -189,7 +190,8 @@ typedef int (*wmt_cmd_sync_func_t)(struct hci_dev *,
 int btmtk_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
 
 int btmtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwname,
-			      wmt_cmd_sync_func_t wmt_cmd_sync);
+			      wmt_cmd_sync_func_t wmt_cmd_sync,
+			      u32 dev_id);
 
 int btmtk_setup_firmware(struct hci_dev *hdev, const char *fwname,
 			 wmt_cmd_sync_func_t wmt_cmd_sync);
@@ -228,7 +230,8 @@ static inline int btmtk_set_bdaddr(struct hci_dev *hdev,
 
 static inline int btmtk_setup_firmware_79xx(struct hci_dev *hdev,
 					    const char *fwname,
-					    wmt_cmd_sync_func_t wmt_cmd_sync)
+					    wmt_cmd_sync_func_t wmt_cmd_sync,
+					    u32 dev_id)
 {
 	return -EOPNOTSUPP;
 }
diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c
index 042064464d34..5b0fab7b89b5 100644
--- a/drivers/bluetooth/btmtksdio.c
+++ b/drivers/bluetooth/btmtksdio.c
@@ -883,7 +883,7 @@ static int mt79xx_setup(struct hci_dev *hdev, const char *fwname)
 	u8 param = 0x1;
 	int err;
 
-	err = btmtk_setup_firmware_79xx(hdev, fwname, mtk_hci_wmt_sync);
+	err = btmtk_setup_firmware_79xx(hdev, fwname, mtk_hci_wmt_sync, 0);
 	if (err < 0) {
 		bt_dev_err(hdev, "Failed to setup 79xx firmware (%d)", err);
 		return err;

-- 
2.53.0



^ permalink raw reply related

* [PATCH v5 0/8] Bluetooth: Add MediaTek MT7927 (MT6639) support
From: Javier Tia @ 2026-03-31 17:09 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz, Matthias Brugger,
	AngeloGioacchino Del Regno
  Cc: linux-bluetooth, linux-kernel, linux-arm-kernel, linux-mediatek,
	Ryan Gilbert, Jose Tiburcio Ribeiro Netto, Llewellyn Curran,
	Chapuis Dario, Evgeny Kapusta, Nitin Gurram, Thibaut FRANCOIS,
	Ivan Lubnin

Add Bluetooth support for the MediaTek MT7927 (Filogic 380), a PCIe
combo WiFi 7 + BT 5.4 module. The BT subsystem uses hardware variant
0x6639 and connects via USB.

The MT7927 is shipping in motherboards and PCIe add-in cards from ASUS,
Gigabyte, Lenovo, MSI, and TP-Link since mid-2024. Without these patches,
users see "Unsupported hardware variant (00006639)" or the BT subsystem
hangs during firmware download.

The series consists of eight patches:

  [1/8] Bluetooth: btmtk: Add MT6639 (MT7927) Bluetooth support
  [2/8] Bluetooth: btmtk: fix ISO interface setup for single alt setting
  [3/8] Bluetooth: btusb: Add MT7927 ID for ASUS ROG Crosshair X870E Hero
  [4/8] Bluetooth: btusb: Add MT7927 ID for Lenovo Legion Pro 7 16ARX9
  [5/8] Bluetooth: btusb: Add MT7927 ID for Gigabyte Z790 AORUS MASTER X
  [6/8] Bluetooth: btusb: Add MT7927 ID for MSI X870E Ace Max
  [7/8] Bluetooth: btusb: Add MT7927 ID for TP-Link Archer TBE550E
  [8/8] Bluetooth: btusb: Add MT7927 ID for ASUS X870E / ProArt X870E-Creator

Three driver changes are needed for MT6639 (patch 1):

1. CHIPID workaround: On some boards the BT USB MMIO register reads
   0x0000 for dev_id. Force dev_id to 0x6639 only when the USB VID/PID
   matches a known MT6639 device, avoiding misdetection if a future
   chip also reads zero. This follows the WiFi-side pattern.

2. Firmware naming: MT6639 uses firmware version prefix "2_1" instead of
   "1_1" used by MT7925 and other variants. The firmware path is
   mediatek/mt7927/BT_RAM_CODE_MT6639_2_1_hdr.bin, using the mt7927
   directory to match the WiFi firmware convention. The filename will
   likely change to use MT7927 once MediaTek submits a dedicated
   Linux firmware binary.

3. Section filtering: The firmware binary contains 9 sections, but only
   sections with (dlmodecrctype & 0xff) == 0x01 are Bluetooth-related.
   Sending WiFi/other sections causes an irreversible BT subsystem hang.

Patch 2 fixes the ISO interface setup for devices that expose only a
single alternate setting (alt 0) on the ISO endpoint. Without this fix,
btmtk_usb_claim_iso_intf() fails with EINVAL, causing ~20 second
initialization delays on 13d3:3588 devices.

WBS (Wideband Speech) was verified on MT7927 hardware. The controller
reports LMP_TRANSPARENT, LMP_ERR_DATA_REPORTING, and mSBC codec support.
A btmon capture confirms eSCO links establish with Transparent air mode
(mSBC) and 60-byte frames. BTUSB_WIDEBAND_SPEECH is correct for this
controller family.

Tested on:
- ASUS ROG Crosshair X870E Hero (USB 0489:e13a)
- ASUS ROG STRIX X870E-E (USB 13d3:3588)
- ASUS ROG STRIX B850-E GAMING WIFI (USB 0489:e13a)
- Gigabyte Z790 AORUS MASTER X (USB 0489:e10f)
- Lenovo Legion Pro 7 16ARX9 (USB 0489:e0fa)

Changes in v5:
- Fix patch 8/8 commit message: the ~19 second delay note was misleading
  since patch 2/8 already fixes that issue. Updated to clarify the
  relationship between the two patches (suggested by Luiz Augusto von
  Dentz)

Link to v4: https://lore.kernel.org/linux-bluetooth/20260330-mt7927-bt-support-v4-0-cecc025e7062@jetm.me/

Signed-off-by: Javier Tia <floss@jetm.me>
---
Javier Tia (8):
      Bluetooth: btmtk: Add MT6639 (MT7927) Bluetooth support
      Bluetooth: btmtk: fix ISO interface setup for single alt setting
      Bluetooth: btusb: Add MT7927 ID for ASUS ROG Crosshair X870E Hero
      Bluetooth: btusb: Add MT7927 ID for Lenovo Legion Pro 7 16ARX9
      Bluetooth: btusb: Add MT7927 ID for Gigabyte Z790 AORUS MASTER X
      Bluetooth: btusb: Add MT7927 ID for MSI X870E Ace Max
      Bluetooth: btusb: Add MT7927 ID for TP-Link Archer TBE550E
      Bluetooth: btusb: Add MT7927 ID for ASUS X870E / ProArt X870E-Creator

 drivers/bluetooth/btmtk.c     | 63 ++++++++++++++++++++++++++++++++++++++-----
 drivers/bluetooth/btmtk.h     |  7 +++--
 drivers/bluetooth/btmtksdio.c |  2 +-
 drivers/bluetooth/btusb.c     | 12 +++++++++
 4 files changed, 75 insertions(+), 9 deletions(-)
---
base-commit: 7f9446b23ac77f46d356b354ea8da49113e8000d
change-id: 20260305-mt7927-bt-support-6589a50c961f

Best regards,
--  
Javier Tia <floss@jetm.me>



^ permalink raw reply

* Re: [PATCH 12/15] KVM: arm64: Remove evaluation of timer state in kvm_cpu_has_pending_timer()
From: Marc Zyngier @ 2026-03-31 17:02 UTC (permalink / raw)
  To: Sascha Bischoff
  Cc: kvmarm@lists.linux.dev, kvm@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, Joey Gouly,
	yuzenghui@huawei.com, Suzuki Poulose, oupton@kernel.org,
	broonie@kernel.org, nd
In-Reply-To: <2779510cb9795d1c934d2122478485847930358a.camel@arm.com>

On Tue, 31 Mar 2026 16:44:04 +0100,
Sascha Bischoff <Sascha.Bischoff@arm.com> wrote:
> 
> On Thu, 2026-03-26 at 15:35 +0000, Marc Zyngier wrote:
> > The vgic-v5 code added some evaluations of the timers in a helper
> > funtion
> > (kvm_cpu_has_pending_timer()) that is called to determine whether
> > the vcpu can wake-up.
> > 
> > But looking at the timer there is wrong:
> > 
> > - we want to see timers that are signalling an interrupt to the
> >   vcpu, and not just that have a pending interrupt
> > 
> > - we already have kvm_arch_vcpu_runnable() that evaluates the
> >   state of interrupts
> > 
> > - kvm_cpu_has_pending_timer() really is about WFIT, as the timeout
> >   does not generate an interrupt, and is therefore distinct from
> >   the point above
> > 
> > As a consequence, revert these changes.
> > 
> > Fixes: 9491c63b6cd7b ("KVM: arm64: gic-v5: Enlighten arch timer for
> > GICv5")
> > Link:
> > https://sashiko.dev/#/patchset/20260319154937.3619520-1-sascha.bischoff%40arm.com
> > Signed-off-by: Marc Zyngier <maz@kernel.org>
> > ---
> >  arch/arm64/kvm/arch_timer.c | 6 +-----
> >  1 file changed, 1 insertion(+), 5 deletions(-)
> > 
> > diff --git a/arch/arm64/kvm/arch_timer.c
> > b/arch/arm64/kvm/arch_timer.c
> > index 37279f8748695..6608c47d1f628 100644
> > --- a/arch/arm64/kvm/arch_timer.c
> > +++ b/arch/arm64/kvm/arch_timer.c
> > @@ -402,11 +402,7 @@ static bool kvm_timer_should_fire(struct
> > arch_timer_context *timer_ctx)
> >  
> >  int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
> >  {
> > -	struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
> > -	struct arch_timer_context *ptimer = vcpu_ptimer(vcpu);
> > -
> > -	return kvm_timer_should_fire(vtimer) ||
> > kvm_timer_should_fire(ptimer) ||
> > -	       (vcpu_has_wfit_active(vcpu) && wfit_delay_ns(vcpu) ==
> > 0);
> > +	return vcpu_has_wfit_active(vcpu) && wfit_delay_ns(vcpu) ==
> > 0;
> >  }
> >  
> >  /*
> 
> Hi Marc,
> 
> It appears that I'd misunderstood the intent of this function when I
> originally wrote this bit code. That is: I agree that these checks
> shouldn't be here.
> 
> However, said checks are needed somewhere. With GICv5, we directly
> inject the timer state (when possible, at least) which means that we
> never see the timer interrupt firing on the host, and don't track if it
> is pending or not in struct vgic_irq as the pending state is driven by
> the hardware itself. The result of this is that we explicitly need to
> check if the timer interrupt would be pending if the guest were running
> somewhere.
> 
> I've run with this complete series and have tested the following
> change. It is sufficient to catch this case, and does it as part of
> checking if there are pending interrupts, i.e., a more appropriate
> place called via kvm_arch_vcpu_runnable(). It is yet-another GICv5
> special case, however. I'd love to hear your thoughts.
> 
> diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
> index cbea4d9ee9552..f8b95721857c3 100644
> --- a/arch/arm64/kvm/arch_timer.c
> +++ b/arch/arm64/kvm/arch_timer.c
> @@ -400,6 +400,14 @@ static bool kvm_timer_should_fire(struct arch_timer_context *timer_ctx)
>         return cval <= now;
>  }
>  
> +int kvm_cpu_timer_should_fire(struct kvm_vcpu *vcpu)
> +{
> +       struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
> +       struct arch_timer_context *ptimer = vcpu_ptimer(vcpu);
> +
> +       return kvm_timer_should_fire(vtimer) || kvm_timer_should_fire(ptimer);
> +}
> +
>  int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
>  {
>         return vcpu_has_wfit_active(vcpu) && wfit_delay_ns(vcpu) == 0;
> diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c
> index 7680ced92f715..ffb91f535efe8 100644
> --- a/arch/arm64/kvm/vgic/vgic.c
> +++ b/arch/arm64/kvm/vgic/vgic.c
> @@ -1238,6 +1238,9 @@ int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu)
>                 if (READ_ONCE(vcpu->arch.vgic_cpu.vgic_v5.gicv5_vpe.db_fired))
>                         return true;
>  
> +               if (kvm_cpu_timer_should_fire(vcpu))
> +                       return true;
> +

This unfortunately seems to suffer from the exact same problem: you
are evaluating the output of the timer independently of the enable
bits gating the timer interrupt at the GIC level.

With this, you can disable the timers at the GIC level, arm the timers
so that they are in a firing position, and enter WFI: the vcpu will
exit WFI immediately, which is not the expected result.

I'd suggest something like this instead (compile tested only):

diff --git a/arch/arm64/kvm/vgic/vgic-v5.c b/arch/arm64/kvm/vgic/vgic-v5.c
index 75372bbfb6a6a..e7d23d0519e8b 100644
--- a/arch/arm64/kvm/vgic/vgic-v5.c
+++ b/arch/arm64/kvm/vgic/vgic-v5.c
@@ -365,9 +365,13 @@ bool vgic_v5_has_pending_ppi(struct kvm_vcpu *vcpu)
 
 		irq = vgic_get_vcpu_irq(vcpu, intid);
 
-		scoped_guard(raw_spinlock_irqsave, &irq->irq_lock)
-			has_pending = (irq->enabled && irq_is_pending(irq) &&
+		scoped_guard(raw_spinlock_irqsave, &irq->irq_lock) {
+			bool pending;
+
+			pending = irq->hw ? vgic_get_phys_line_level(irq) : irq_is_pending(irq);
+			has_pending = (irq->enabled && pending &&
 				       irq->priority < priority_mask);
+		}
 
 		vgic_put_irq(vcpu->kvm, irq);
 

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


^ permalink raw reply related

* Re: [PATCH v2 2/8] perf build loongarch: Remove reference to missing file
From: Ian Rogers @ 2026-03-31 17:01 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: 9erthalion6, adrian.hunter, alex, alexander.shishkin,
	andrew.jones, aou, atrajeev, blakejones, ctshao, dapeng1.mi,
	howardchu95, james.clark, john.g.garry, jolsa, leo.yan,
	libunwind-devel, linux-arm-kernel, linux-kernel, linux-perf-users,
	linux-riscv, mingo, namhyung, palmer, peterz, pjw, shimin.guo,
	tglozar, tmricht, will, yuzhuo
In-Reply-To: <acrln3IwOebvb6yj@x1>

On Mon, Mar 30, 2026 at 2:05 PM Arnaldo Carvalho de Melo
<acme@kernel.org> wrote:
>
> On Thu, Mar 05, 2026 at 02:19:21PM -0800, Ian Rogers wrote:
> > The file was removed in commit e62fae9d9e85 ("perf unwind-libdw: Fix a
> > cross-arch unwinding bug") but the Build file not updated.
> >
> > Fixes: commit e62fae9d9e85 ("perf unwind-libdw: Fix a cross-arch unwinding bug")
>
> Removing the 'commit' part.

Thanks, checkpatch caught this but somehow I missed it.

Ian

> - Arnaldo
>
> > Signed-off-by: Ian Rogers <irogers@google.com>
> > ---
> >  tools/perf/arch/loongarch/util/Build | 1 -
> >  1 file changed, 1 deletion(-)
> >
> > diff --git a/tools/perf/arch/loongarch/util/Build b/tools/perf/arch/loongarch/util/Build
> > index 3ad73d0289f3..8d91e78d31c9 100644
> > --- a/tools/perf/arch/loongarch/util/Build
> > +++ b/tools/perf/arch/loongarch/util/Build
> > @@ -1,4 +1,3 @@
> >  perf-util-y += header.o
> >
> >  perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
> > -perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
> > --
> > 2.53.0.473.g4a7958ca14-goog


^ permalink raw reply

* [PATCH] dmaengine: xilinx_dma: Fix CPU stall in xilinx_dma_poll_timeout
From: Alex Bereza @ 2026-03-31 16:44 UTC (permalink / raw)
  To: Vinod Koul, Frank Li, Michal Simek, Geert Uytterhoeven,
	Ulf Hansson, Arnd Bergmann, Tony Lindgren
  Cc: dmaengine, linux-arm-kernel, linux-kernel, Alex Bereza

Currently when calling xilinx_dma_poll_timeout with delay_us=0 and a
condition that is never fulfilled, the CPU busy-waits for prolonged time
and the timeout triggers only with a massive delay causing a CPU stall.

This happens due to a huge underestimation of wall clock time in
poll_timeout_us_atomic. Commit 7349a69cf312 ("iopoll: Do not use
timekeeping in read_poll_timeout_atomic()") changed the behavior to no
longer use ktime_get at the expense of underestimation of wall clock
time which appears to be very large for delay_us=0. Instead of timing
out after approximately XILINX_DMA_LOOP_COUNT microseconds, the timeout
takes XILINX_DMA_LOOP_COUNT * 1000 * (time that the overhead of the for
loop in poll_timeout_us_atomic takes) which is in the range of several
minutes for XILINX_DMA_LOOP_COUNT=1000000. Fix this by using a non-zero
value for delay_us. Use delay_us=10 to keep the delay in the hot path of
starting DMA transfers minimal but still avoid CPU stalls in case of
unexpected hardware failures.

One-off measurement with delay_us=0 causes the cpu to busy wait around 7
minutes in the timeout case. After applying this patch with delay_us=10
the measured timeout was 1053428 microseconds which is roughly
equivalent to the expected 1000000 microseconds specified in
XILINX_DMA_POLL_TIMEOUT_US.

Rename XILINX_DMA_LOOP_COUNT to XILINX_DMA_POLL_TIMEOUT_US because the
former is incorrect. It is a timeout value for polling various register
bits in microseconds. It is not a loop count. Add a constant
XILINX_DMA_POLL_DELAY_US for delay_us value.

Fixes: 7349a69cf312 ("iopoll: Do not use timekeeping in read_poll_timeout_atomic()")
Signed-off-by: Alex Bereza <alex@bereza.email>
---
Hi, in addition to this patch I also have a question: what is the point
of atomically polling for the HALTED or IDLE bit in the stop_transfer
functions? Does device_terminate_all really need to be callable from
atomic context? If not, one could switch to polling non-atomically and
avoid burning CPU cycles.

As this is my first patch, please feel free to point me in the right
direction if I am missing anything.
---
 drivers/dma/xilinx/xilinx_dma.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index 02a05f215614..8556c357b665 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -165,8 +165,10 @@
 #define XILINX_DMA_FLUSH_MM2S		2
 #define XILINX_DMA_FLUSH_BOTH		1
 
-/* Delay loop counter to prevent hardware failure */
-#define XILINX_DMA_LOOP_COUNT		1000000
+/* Timeout for polling various registers */
+#define XILINX_DMA_POLL_TIMEOUT_US		1000000
+/* Delay between polls (avoid a delay of 0 to prevent CPU stalls) */
+#define XILINX_DMA_POLL_DELAY_US		10
 
 /* AXI DMA Specific Registers/Offsets */
 #define XILINX_DMA_REG_SRCDSTADDR	0x18
@@ -1332,8 +1334,9 @@ static int xilinx_dma_stop_transfer(struct xilinx_dma_chan *chan)
 
 	/* Wait for the hardware to halt */
 	return xilinx_dma_poll_timeout(chan, XILINX_DMA_REG_DMASR, val,
-				       val & XILINX_DMA_DMASR_HALTED, 0,
-				       XILINX_DMA_LOOP_COUNT);
+				       val & XILINX_DMA_DMASR_HALTED,
+				       XILINX_DMA_POLL_DELAY_US,
+				       XILINX_DMA_POLL_TIMEOUT_US);
 }
 
 /**
@@ -1347,8 +1350,9 @@ static int xilinx_cdma_stop_transfer(struct xilinx_dma_chan *chan)
 	u32 val;
 
 	return xilinx_dma_poll_timeout(chan, XILINX_DMA_REG_DMASR, val,
-				       val & XILINX_DMA_DMASR_IDLE, 0,
-				       XILINX_DMA_LOOP_COUNT);
+				       val & XILINX_DMA_DMASR_IDLE,
+				       XILINX_DMA_POLL_DELAY_US,
+				       XILINX_DMA_POLL_TIMEOUT_US);
 }
 
 /**
@@ -1364,8 +1368,9 @@ static void xilinx_dma_start(struct xilinx_dma_chan *chan)
 
 	/* Wait for the hardware to start */
 	err = xilinx_dma_poll_timeout(chan, XILINX_DMA_REG_DMASR, val,
-				      !(val & XILINX_DMA_DMASR_HALTED), 0,
-				      XILINX_DMA_LOOP_COUNT);
+				      !(val & XILINX_DMA_DMASR_HALTED),
+				      XILINX_DMA_POLL_DELAY_US,
+				      XILINX_DMA_POLL_TIMEOUT_US);
 
 	if (err) {
 		dev_err(chan->dev, "Cannot start channel %p: %x\n",
@@ -1780,8 +1785,9 @@ static int xilinx_dma_reset(struct xilinx_dma_chan *chan)
 
 	/* Wait for the hardware to finish reset */
 	err = xilinx_dma_poll_timeout(chan, XILINX_DMA_REG_DMACR, tmp,
-				      !(tmp & XILINX_DMA_DMACR_RESET), 0,
-				      XILINX_DMA_LOOP_COUNT);
+				      !(tmp & XILINX_DMA_DMACR_RESET),
+				      XILINX_DMA_POLL_DELAY_US,
+				      XILINX_DMA_POLL_TIMEOUT_US);
 
 	if (err) {
 		dev_err(chan->dev, "reset timeout, cr %x, sr %x\n",

---
base-commit: b7560798466a07d9c3fb011698e92c335ab28baf
change-id: 20260330-fix-atomic-poll-timeout-regression-4f4e3baf3fd7

Best regards,
--  
Alex Bereza <alex@bereza.email>



^ permalink raw reply related

* Re: [PATCH v4 0/8] Bluetooth: Add MediaTek MT7927 (MT6639) support
From: patchwork-bot+bluetooth @ 2026-03-31 16:50 UTC (permalink / raw)
  To: Javier Tia
  Cc: marcel, luiz.dentz, matthias.bgg, angelogioacchino.delregno,
	linux-bluetooth, linux-kernel, linux-arm-kernel, linux-mediatek,
	xelnaga, jnetto, melinko2003, chapuisdario4, 3193631,
	nitin.reddy88, tibo, lubnin.ivan
In-Reply-To: <20260330-mt7927-bt-support-v4-0-cecc025e7062@jetm.me>

Hello:

This series was applied to bluetooth/bluetooth-next.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:

On Mon, 30 Mar 2026 14:39:22 -0600 you wrote:
> combo WiFi 7 + BT 5.4 module. The BT subsystem uses hardware variant
> 0x6639 and connects via USB.
> 
> The MT7927 is shipping in motherboards and PCIe add-in cards from ASUS,
> Gigabyte, Lenovo, MSI, and TP-Link since mid-2024. Without these patches,
> users see "Unsupported hardware variant (00006639)" or the BT subsystem
> hangs during firmware download.
> 
> [...]

Here is the summary with links:
  - [v4,1/8] Bluetooth: btmtk: Add MT6639 (MT7927) Bluetooth support
    https://git.kernel.org/bluetooth/bluetooth-next/c/4cdd001ff03f
  - [v4,2/8] Bluetooth: btmtk: fix ISO interface setup for single alt setting
    https://git.kernel.org/bluetooth/bluetooth-next/c/fe9e35d0b3f1
  - [v4,3/8] Bluetooth: btusb: Add MT7927 ID for ASUS ROG Crosshair X870E Hero
    https://git.kernel.org/bluetooth/bluetooth-next/c/af6731663d8f
  - [v4,4/8] Bluetooth: btusb: Add MT7927 ID for Lenovo Legion Pro 7 16ARX9
    https://git.kernel.org/bluetooth/bluetooth-next/c/70d2954d3051
  - [v4,5/8] Bluetooth: btusb: Add MT7927 ID for Gigabyte Z790 AORUS MASTER X
    https://git.kernel.org/bluetooth/bluetooth-next/c/e4fb2113d5e2
  - [v4,6/8] Bluetooth: btusb: Add MT7927 ID for MSI X870E Ace Max
    https://git.kernel.org/bluetooth/bluetooth-next/c/4be0c8800708
  - [v4,7/8] Bluetooth: btusb: Add MT7927 ID for TP-Link Archer TBE550E
    https://git.kernel.org/bluetooth/bluetooth-next/c/26308f935d23
  - [v4,8/8] Bluetooth: btusb: Add MT7927 ID for ASUS X870E / ProArt X870E-Creator
    https://git.kernel.org/bluetooth/bluetooth-next/c/b65fdb465d54

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




^ permalink raw reply

* Re: [PATCH v3 1/8] Bluetooth: btmtk: Add MT6639 (MT7927) Bluetooth support
From: patchwork-bot+bluetooth @ 2026-03-31 16:50 UTC (permalink / raw)
  To: Javier Tia
  Cc: marcel, luiz.dentz, matthias.bgg, angelogioacchino.delregno,
	linux-bluetooth, linux-kernel, linux-arm-kernel, linux-mediatek,
	xelnaga
In-Reply-To: <20260326-mt7927-bt-support-v3-1-fa7ebd424323@jetm.me>

Hello:

This series was applied to bluetooth/bluetooth-next.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:

On Thu, 26 Mar 2026 16:13:04 -0600 you wrote:
> The MediaTek MT7927 (Filogic 380) combo WiFi 7 + BT 5.4 module uses
> hardware variant 0x6639 for its Bluetooth subsystem. Without this patch,
> the chip fails with "Unsupported hardware variant (00006639)" or hangs
> during firmware download.
> 
> Three changes are needed to support MT6639:
> 
> [...]

Here is the summary with links:
  - [v3,1/8] Bluetooth: btmtk: Add MT6639 (MT7927) Bluetooth support
    (no matching commit)
  - [v3,2/8] Bluetooth: btmtk: fix ISO interface setup for single alt setting
    https://git.kernel.org/bluetooth/bluetooth-next/c/fe9e35d0b3f1
  - [v3,3/8] Bluetooth: btusb: Add MT7927 ID for ASUS ROG Crosshair X870E Hero
    https://git.kernel.org/bluetooth/bluetooth-next/c/af6731663d8f
  - [v3,4/8] Bluetooth: btusb: Add MT7927 ID for Lenovo Legion Pro 7 16ARX9
    https://git.kernel.org/bluetooth/bluetooth-next/c/70d2954d3051
  - [v3,5/8] Bluetooth: btusb: Add MT7927 ID for Gigabyte Z790 AORUS MASTER X
    https://git.kernel.org/bluetooth/bluetooth-next/c/e4fb2113d5e2
  - [v3,6/8] Bluetooth: btusb: Add MT7927 ID for MSI X870E Ace Max
    https://git.kernel.org/bluetooth/bluetooth-next/c/4be0c8800708
  - [v3,7/8] Bluetooth: btusb: Add MT7927 ID for TP-Link Archer TBE550E
    https://git.kernel.org/bluetooth/bluetooth-next/c/26308f935d23
  - [v3,8/8] Bluetooth: btusb: Add MT7927 ID for ASUS X870E / ProArt X870E-Creator
    https://git.kernel.org/bluetooth/bluetooth-next/c/b65fdb465d54

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




^ permalink raw reply

* Re: [PATCH 00/15] KVM: arm64: First batch of vgic-v5 related fixes
From: Sascha Bischoff @ 2026-03-31 16:34 UTC (permalink / raw)
  To: maz@kernel.org, kvmarm@lists.linux.dev, kvm@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
  Cc: Joey Gouly, yuzenghui@huawei.com, Suzuki Poulose,
	oupton@kernel.org, broonie@kernel.org, nd
In-Reply-To: <20260326153530.3981879-1-maz@kernel.org>

On Thu, 2026-03-26 at 15:35 +0000, Marc Zyngier wrote:
> Well, merging the first batch of vgic-v5 patches didn't go smoothly
> at
> all. We initially found a couple of regressions, but most of the crap
> was actually uncovered by everyone's new best friend (enemy?), the AI
> bot sitting behind sashiko.dev [1].
> 
> While not all of the remarks were valid, a bunch of them were
> actually
> extremely pertinent, and resulted in me frantically hacking away at
> the series. Hopefully the bot doesn't find even more issues in the
> fixes. Note that the first patch has already been posted and merged,
> and is only here for reference.
> 
> Note that given the amount of rework, I'm really in two minds between
> adding these patches on top, or pulling the whole series for another
> cycle. I guess time will tell.
> 
> [1]
> https://sashiko.dev/#/patchset/20260319154937.3619520-1-sascha.bischoff%40arm.com

Hi Marc,

Thanks so much for taking the time to go through things, and to fix up
these issues. Apologies for introducing them in the first place!

I'll spend some time going through the rest of the issues flagged at
[1] to see which others are true positives and provide fixes for them.

I've gone through this series, and am happy with everything except for
'KVM: arm64: vgic-v5: align priority comparison with other GICs', as
I've mentioned in the thread there. In summary, the `+ 1` is needed due
to GICv5's priority masking working a little different to that of
GICv[23].

When it comes to 'KVM: arm64: Remove evaluation of timer state in   
kvm_cpu_has_pending_timer()', I agree with the change - doing the check
in that location was definitely wrong. However, a similar check is
required on GICv5 due to the DVI mechanism being used on GICv5. I've
provided a potential (tested) fix in the thread there.

For all of these, with the exception of #9 ('KVM: arm64: vgic-v5: align
priority comparison with other GICs'), I'm happy for you to consider
them as:

Reviewed-by: Sascha Bischoff <sascha.bischoff@arm.com>

Thanks,
Sascha

> 
> Marc Zyngier (15):
>   KVM: arm64: vgic: Don't reset cpuif/redist addresses at finalize
> time
>   KVM: arm64: Don't skip per-vcpu NV initialisation
>   arm64: Fix field references for ICH_PPI_DVIR[01]_EL2
>   KVM: arm64: Fix writeable mask for ID_AA64PFR2_EL1
>   KVM: arm64: Account for RESx bits in __compute_fgt()
>   KVM: arm64: vgic-v5: Hold config_lock while finalizing GICv5 PPIs
>   KVM: arm64: vgic-v5: Transfer edge pending state to
> ICH_PPI_PENDRx_EL2
>   KVM: arm64: vgic-v5: Cast vgic_apr to u32 to avoid undefined
>     behaviours
>   KVM: arm64: vgic-v5: align priority comparison with other GICs
>   KVM: arm64: vgic-v5: Correctly set dist->ready once initialised
>   KVM: arm64: Kill arch_timer_context::direct field
>   KVM: arm64: Remove evaluation of timer state in
>     kvm_cpu_has_pending_timer()
>   KVM: arm64: Move GICv5 timer PPI validation into
>     timer_irqs_are_valid()
>   KVM: arm64: Correctly plumb ID_AA64PFR2_EL1 into pkvm idreg
> handling
>   KVM: arm64: Don't advertises GICv3 in ID_PFR1_EL1 if AArch32 isn't
>     supported
> 
>  arch/arm64/kvm/arch_timer.c        | 32 +++++++++++++---------------
> --
>  arch/arm64/kvm/config.c            |  4 ++--
>  arch/arm64/kvm/hyp/nvhe/sys_regs.c |  2 +-
>  arch/arm64/kvm/sys_regs.c          | 20 +++++++++----------
>  arch/arm64/kvm/vgic/vgic-init.c    | 32 ++++++++++++++++++++--------
> --
>  arch/arm64/kvm/vgic/vgic-v5.c      | 24 +++++++++++++++++-----
>  arch/arm64/tools/sysreg            |  4 ++--
>  include/kvm/arm_arch_timer.h       |  3 ---
>  8 files changed, 70 insertions(+), 51 deletions(-)
> 


^ permalink raw reply

* Re: [PATCH v1] media: rkisp1: Add support for CAC
From: Laurent Pinchart @ 2026-03-31 16:15 UTC (permalink / raw)
  To: Barnabás Pőcze
  Cc: Jacopo Mondi, Dafna Hirschfeld, Mauro Carvalho Chehab,
	Heiko Stuebner, linux-media, linux-rockchip, linux-arm-kernel,
	linux-kernel
In-Reply-To: <5a7d1894-ee12-42b6-b40c-4d0e0b370974@ideasonboard.com>

On Tue, Mar 31, 2026 at 05:24:38PM +0200, Barnabás Pőcze wrote:
> 2026. 03. 31. 15:39 keltezéssel, Laurent Pinchart írta:
> > On Tue, Mar 31, 2026 at 02:42:33PM +0200, Jacopo Mondi wrote:
> >> On Mon, Mar 30, 2026 at 04:40:18PM +0200, Barnabás Pőcze wrote:
> >>> 2026. 03. 25. 16:21 keltezéssel, Jacopo Mondi írta:
> >>>> On Mon, Mar 23, 2026 at 03:02:16PM +0100, Barnabás Pőcze wrote:
> >>>>> The CAC block implements chromatic aberration correction. Expose it to
> >>>>> userspace using the extensible parameters format. This was tested on the
> >>>>> i.MX8MP platform, but based on available documentation it is also present
> >>>>> in the RK3399 variant (V10). Thus presumably also in later versions,
> >>>>> so no feature flag is introduced.
> >>>>>
> >>>>> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
> >>>>
> >>>> Only minors..
> >>>>
> >>>>> ---
> >>>>>    .../platform/rockchip/rkisp1/rkisp1-params.c  |  69 ++++++++++++
> >>>>>    .../platform/rockchip/rkisp1/rkisp1-regs.h    |  21 +++-
> >>>>>    include/uapi/linux/rkisp1-config.h            | 106 +++++++++++++++++-
> >>>>>    3 files changed, 193 insertions(+), 3 deletions(-)
> >>>>>
> >>>>> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> >>>>> index 6442436a5e428..b889af9dcee45 100644
> >>>>> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> >>>>> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> >>>>> @@ -64,6 +64,7 @@ union rkisp1_ext_params_config {
> >>>>>    	struct rkisp1_ext_params_compand_bls_config compand_bls;
> >>>>>    	struct rkisp1_ext_params_compand_curve_config compand_curve;
> >>>>>    	struct rkisp1_ext_params_wdr_config wdr;
> >>>>> +	struct rkisp1_ext_params_cac_config cac;
> >>>>>    };
> >>>>>
> >>>>>    enum rkisp1_params_formats {
> >>>>> @@ -1413,6 +1414,48 @@ static void rkisp1_wdr_config(struct rkisp1_params *params,
> >>>>>    				     RKISP1_CIF_ISP_WDR_TONE_CURVE_YM_MASK);
> >>>>>    }
> >>>>>
> >>>>> +static void
> >>>>> +rkisp1_cac_config(struct rkisp1_params *params,
> >>>>> +		  const struct rkisp1_cif_isp_cac_config *arg)
> >>>>
> >>>> Fits in one line without going over 80 cols
> >>>
> >>> This is what the other functions looks like, so went this this.
> >>
> >> It seems to me not all of them are broken, but only the ones that go
> >> over 80 cols
> 
> I think I misunderstood initially. Adjusted now.
> 
> >> in example:
> >>
> >> static void rkisp1_dpf_config(struct rkisp1_params *params,
> >> 			      const struct rkisp1_cif_isp_dpf_config *arg)
> >>
> >> A detail anyway, up to you
> >>
> >>>>> +{
> >>>>> +	u32 regval;
> > 
> > All other functions in this file name similar variables "val", "value"
> > or "reg_val". Let's not introduce a fourth one. I have a small
> > preference for "val", but that's not mandatory.
> 
> Adjusted.
> 
> >>>>> +
> >>>>> +	/*
> >>>>> +	 * The enable bit is in the same register (RKISP1_CIF_ISP_CAC_CTRL),
> >>>>> +	 * so only set the clipping mode, and do not modify the other bits.
> >>>>> +	 */
> >>>>> +	regval = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_CAC_CTRL);
> >>>>> +	regval &= ~(RKISP1_CIF_ISP_CAC_CTRL_H_CLIP_MODE |
> >>>>> +		    RKISP1_CIF_ISP_CAC_CTRL_V_CLIP_MODE);
> >>>>> +	regval |= FIELD_PREP(RKISP1_CIF_ISP_CAC_CTRL_H_CLIP_MODE, arg->h_clip_mode) |
> >>>>> +		  FIELD_PREP(RKISP1_CIF_ISP_CAC_CTRL_V_CLIP_MODE, arg->v_clip_mode);
> >>>>> +	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_CTRL, regval);
> >>>>> +
> >>>>> +	regval = FIELD_PREP(RKISP1_CIF_ISP_CAC_COUNT_START_H_MASK, arg->h_count_start) |
> >>>>> +		 FIELD_PREP(RKISP1_CIF_ISP_CAC_COUNT_START_V_MASK, arg->v_count_start);
> >>>>> +	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_COUNT_START, regval);
> >>>>> +
> >>>>> +	regval = FIELD_PREP(RKISP1_CIF_ISP_CAC_A_RED_MASK, arg->red[0]) |
> >>>>> +		 FIELD_PREP(RKISP1_CIF_ISP_CAC_A_BLUE_MASK, arg->blue[0]);
> >>>>> +	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_A, regval);
> >>>>> +
> >>>>> +	regval = FIELD_PREP(RKISP1_CIF_ISP_CAC_B_RED_MASK, arg->red[1]) |
> >>>>> +		 FIELD_PREP(RKISP1_CIF_ISP_CAC_B_BLUE_MASK, arg->blue[1]);
> >>>>> +	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_B, regval);
> >>>>> +
> >>>>> +	regval = FIELD_PREP(RKISP1_CIF_ISP_CAC_C_RED_MASK, arg->red[2]) |
> >>>>> +		 FIELD_PREP(RKISP1_CIF_ISP_CAC_C_BLUE_MASK, arg->blue[2]);
> >>>>> +	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_C, regval);
> >>>>> +
> >>>>> +	regval = FIELD_PREP(RKISP1_CIF_ISP_CAC_X_NORM_NF_MASK, arg->x_nf) |
> >>>>> +		 FIELD_PREP(RKISP1_CIF_ISP_CAC_X_NORM_NS_MASK, arg->x_ns);
> >>>>> +	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_X_NORM, regval);
> >>>>> +
> >>>>> +	regval = FIELD_PREP(RKISP1_CIF_ISP_CAC_Y_NORM_NF_MASK, arg->y_nf) |
> >>>>> +		 FIELD_PREP(RKISP1_CIF_ISP_CAC_Y_NORM_NS_MASK, arg->y_ns);
> >>>>> +	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_Y_NORM, regval);
> >>>>> +}
> >>>>> +
> >>>>>    static void
> >>>>>    rkisp1_isp_isr_other_config(struct rkisp1_params *params,
> >>>>>    			    const struct rkisp1_params_cfg *new_params)
> >>>>> @@ -2089,6 +2132,25 @@ static void rkisp1_ext_params_wdr(struct rkisp1_params *params,
> >>>>>    				      RKISP1_CIF_ISP_WDR_CTRL_ENABLE);
> >>>>>    }
> >>>>>
> >>>>> +static void rkisp1_ext_params_cac(struct rkisp1_params *params,
> >>>>> +				  const union rkisp1_ext_params_config *block)
> >>>>> +{
> >>>>> +	const struct rkisp1_ext_params_cac_config *cac = &block->cac;
> >>>>> +
> >>>>> +	if (cac->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {
> >>>>> +		rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CAC_CTRL,
> >>>>> +					RKISP1_CIF_ISP_CAC_CTRL_ENABLE);
> >>>>> +		return;
> >>>>> +	}
> >>>>> +
> >>>>> +	rkisp1_cac_config(params, &cac->config);
> >>>>> +
> >>>>> +	if ((cac->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&
> >>>>> +	    !(params->enabled_blocks & BIT(cac->header.type)))
> >>>>> +		rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CAC_CTRL,
> >>>>> +				      RKISP1_CIF_ISP_CAC_CTRL_ENABLE);
> >>>>> +}
> >>>>> +
> >>>>>    typedef void (*rkisp1_block_handler)(struct rkisp1_params *params,
> >>>>>    			     const union rkisp1_ext_params_config *config);
> >>>>>
> >>>>> @@ -2185,6 +2247,10 @@ static const struct rkisp1_ext_params_handler {
> >>>>>    		.handler	= rkisp1_ext_params_wdr,
> >>>>>    		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> >>>>>    	},
> >>>>> +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_CAC] = {
> >>>>> +		.handler	= rkisp1_ext_params_cac,
> >>>>> +		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> >>>>> +	},
> >>>>>    };
> >>>>>
> >>>>>    #define RKISP1_PARAMS_BLOCK_INFO(block, data) \
> >>>>> @@ -2215,6 +2281,7 @@ rkisp1_ext_params_block_types_info[] = {
> >>>>>    	RKISP1_PARAMS_BLOCK_INFO(COMPAND_EXPAND, compand_curve),
> >>>>>    	RKISP1_PARAMS_BLOCK_INFO(COMPAND_COMPRESS, compand_curve),
> >>>>>    	RKISP1_PARAMS_BLOCK_INFO(WDR, wdr),
> >>>>> +	RKISP1_PARAMS_BLOCK_INFO(CAC, cac),
> >>>>>    };
> >>>>>
> >>>>>    static_assert(ARRAY_SIZE(rkisp1_ext_params_handlers) ==
> >>>>> @@ -2474,6 +2541,8 @@ void rkisp1_params_disable(struct rkisp1_params *params)
> >>>>>    	rkisp1_ie_enable(params, false);
> >>>>>    	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPF_MODE,
> >>>>>    				RKISP1_CIF_ISP_DPF_MODE_EN);
> >>>>> +	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CAC_CTRL,
> >>>>> +				RKISP1_CIF_ISP_CAC_CTRL_ENABLE);
> >>>>>    }
> >>>>>
> >>>>>    static const struct rkisp1_params_ops rkisp1_v10_params_ops = {
> >>>>> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
> >>>>> index fbeb186cde0d5..8e25537459bbd 100644
> >>>>> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
> >>>>> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
> >>>>> @@ -724,6 +724,23 @@
> >>>>>    #define RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_MASK		GENMASK(20, 16)
> >>>>>    #define RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_MAX		16U
> >>>>>
> >>>>> +/* CAC */
> >>>>> +#define RKISP1_CIF_ISP_CAC_CTRL_ENABLE		BIT(0)
> >>>>> +#define RKISP1_CIF_ISP_CAC_CTRL_V_CLIP_MODE	GENMASK(2, 1)
> >>>>> +#define RKISP1_CIF_ISP_CAC_CTRL_H_CLIP_MODE	GENMASK(3, 3)
> > 
> > I'd go for BIT(3) as you use BIT(0) for the enable bit.
> 
> Adjusted.
> 
> >>>>> +#define RKISP1_CIF_ISP_CAC_COUNT_START_H_MASK	GENMASK(12, 0)
> >>>>> +#define RKISP1_CIF_ISP_CAC_COUNT_START_V_MASK	GENMASK(28, 16)
> >>>>> +#define RKISP1_CIF_ISP_CAC_A_RED_MASK		GENMASK(8, 0)
> >>>>> +#define RKISP1_CIF_ISP_CAC_A_BLUE_MASK		GENMASK(24, 16)
> >>>>> +#define RKISP1_CIF_ISP_CAC_B_RED_MASK		GENMASK(8, 0)
> >>>>> +#define RKISP1_CIF_ISP_CAC_B_BLUE_MASK		GENMASK(24, 16)
> >>>>> +#define RKISP1_CIF_ISP_CAC_C_RED_MASK		GENMASK(8, 0)
> >>>>> +#define RKISP1_CIF_ISP_CAC_C_BLUE_MASK		GENMASK(24, 16)
> >>>>
> >>>> All these masks for coefficients 0, 1 and 2 are identical. Maybe
> >>>> #define RKISP1_CIF_ISP_CAC_RED_MASK		GENMASK(8, 0)
> >>>> #define RKISP1_CIF_ISP_CAC_BLUE_MASK		GENMASK(24, 16)
> >>>>
> >>>> is enough
> >>>
> >>> Adjusted.
> >>>
> >>>>> +#define RKISP1_CIF_ISP_CAC_X_NORM_NF_MASK	GENMASK(4, 0)
> >>>>> +#define RKISP1_CIF_ISP_CAC_X_NORM_NS_MASK	GENMASK(19, 16)
> >>>>> +#define RKISP1_CIF_ISP_CAC_Y_NORM_NF_MASK	GENMASK(4, 0)
> >>>>> +#define RKISP1_CIF_ISP_CAC_Y_NORM_NS_MASK	GENMASK(19, 16)
> >>>
> >>> Did the same with these as well.
> >>
> >> Ah thanks!
> >>
> >>>>> +
> >>>>>    /* =================================================================== */
> >>>>>    /*                            CIF Registers                            */
> >>>>>    /* =================================================================== */
> >>>>> @@ -1196,8 +1213,8 @@
> >>>>>    #define RKISP1_CIF_ISP_CAC_A			(RKISP1_CIF_ISP_CAC_BASE + 0x00000008)
> >>>>>    #define RKISP1_CIF_ISP_CAC_B			(RKISP1_CIF_ISP_CAC_BASE + 0x0000000c)
> >>>>>    #define RKISP1_CIF_ISP_CAC_C			(RKISP1_CIF_ISP_CAC_BASE + 0x00000010)
> >>>>> -#define RKISP1_CIF_ISP_X_NORM			(RKISP1_CIF_ISP_CAC_BASE + 0x00000014)
> >>>>> -#define RKISP1_CIF_ISP_Y_NORM			(RKISP1_CIF_ISP_CAC_BASE + 0x00000018)
> >>>>> +#define RKISP1_CIF_ISP_CAC_X_NORM		(RKISP1_CIF_ISP_CAC_BASE + 0x00000014)
> >>>>> +#define RKISP1_CIF_ISP_CAC_Y_NORM		(RKISP1_CIF_ISP_CAC_BASE + 0x00000018)
> >>>>>
> >>>>>    #define RKISP1_CIF_ISP_EXP_BASE			0x00002600
> >>>>>    #define RKISP1_CIF_ISP_EXP_CTRL			(RKISP1_CIF_ISP_EXP_BASE + 0x00000000)
> >>>>> diff --git a/include/uapi/linux/rkisp1-config.h b/include/uapi/linux/rkisp1-config.h
> >>>>> index b2d2a71f7baff..d8acccaddd0e9 100644
> >>>>> --- a/include/uapi/linux/rkisp1-config.h
> >>>>> +++ b/include/uapi/linux/rkisp1-config.h
> >>>>> @@ -967,6 +967,92 @@ struct rkisp1_cif_isp_wdr_config {
> >>>>>    	__u8 use_iref;
> >>>>>    };
> >>>>>
> >>>>> +/*
> >>>>> + * enum rkisp1_cif_isp_cac_h_clip_mode - horizontal clipping mode
> >>>>> + *
> >>>>> + * @RKISP1_CIF_ISP_CAC_H_CLIP_MODE_4PX: +/- 4 pixels
> >>>>> + * @RKISP1_CIF_ISP_CAC_H_CLIP_MODE_4_5PX: +/- 4/5 pixels depending on bayer position
> >>>>> + */
> >>>>> +enum rkisp1_cif_isp_cac_h_clip_mode {
> >>>>> +	RKISP1_CIF_ISP_CAC_H_CLIP_MODE_4PX = 0,
> >>>>> +	RKISP1_CIF_ISP_CAC_H_CLIP_MODE_4_5PX = 1,
> >>>>> +};
> >>>>> +
> >>>>> +/**
> >>>>> + * enum rkisp1_cif_isp_cac_v_clip_mode - vertical clipping mode
> >>>>> + *
> >>>>> + * @RKISP1_CIF_ISP_CAC_V_CLIP_MODE_2PX: +/- 2 pixels
> >>>>> + * @RKISP1_CIF_ISP_CAC_V_CLIP_MODE_3PX: +/- 3 pixels
> >>>>> + * @RKISP1_CIF_ISP_CAC_V_CLIP_MODE_3_4PX: +/- 3/4 pixels depending on bayer position
> >>>>> + */
> >>>>> +enum rkisp1_cif_isp_cac_v_clip_mode {
> >>>>> +	RKISP1_CIF_ISP_CAC_V_CLIP_MODE_2PX = 0,
> >>>>> +	RKISP1_CIF_ISP_CAC_V_CLIP_MODE_3PX = 1,
> >>>>> +	RKISP1_CIF_ISP_CAC_V_CLIP_MODE_3_4PX = 2,
> >>>>> +};
> >>>>> +
> >>>>> +/**
> >>>>> + * struct rkisp1_cif_isp_cac_config - chromatic aberration correction configuration
> >>>>> + *
> >>>>> + * The correction is carried out by shifting the red and blue pixels relative
> >>>>> + * to the green ones, depending on the distance from the optical center:
> >>>>
> >>>> Yes, the distance to the center is one parameter, but the shifting
> >>>> amount depends on other things. I would drop the last part of the
> >>>> sentence and move the description of the two below fields after the
> >>>> text
> >>>
> >>> That's true, but within a specific image, the only varying quantity
> >>> is the distance, so I think it is important to emphasize that.
> >>>
> >>> And I also quite like this structure of
> >>>    - description of step
> >>>    - parameters of step
> >>>    - description of step
> >>>    ...
> >>>
> >>> so I would love to keep it like this, if that's ok?
> >>
> >> Ok!
> > 
> > Ack.
> > 
> >>>>> + *
> >>>>> + * @h_count_start: horizontal coordinate of the optical center (13-bit unsigned integer; [1,8191])
> >>>>> + * @v_count_start: vertical coordinate of the optical center (13-bit unsigned integer; [1,8191])
> >>>>
> >>>> so these could go just before @x_nf
> >>>>
> >>>>> + *
> >>>>> + * For each pixel, the x/y distances from the optical center are calculated and
> >>>>
> >>>> I forgot: did we establish that the correction is applied to the
> >>>> euclidean distance or to x and y separately ?
> >>>
> >>> Given that there are two sets of "normalization" parameters, the assumption is that
> >>> at least the x/y distances are transformed separately. I see two reasonable choices
> >>> after that: (a) use the two distances separately, (b) use the radial distance. The
> >>> documentation says (b). However, testing with sensor test patterns suggests that
> >>> it is not the case (a horizontal/vertical boundary between appropriately colored
> >>> regions should have a curvature after the transformation with appropriate parameters).
> >>
> >> I now recall that you have been able to shift just one plan when using
> >> the sensor's test pattern
> > 
> > I agree about the normalization, but it sounds really weird that the
> > hardware would then shift separately in the X and Y directions. Below
> > you document the radial correction formula, which looks correct to me.
> 
> I think so, too. But if it uses the radial distance, I would expect the shifting to happen
> along the radius. But that does not appear to be the case (e.g. y_nf=0 removes all vertical
> correction). This could be explained by saying that the shifting actually happens along the
> direction determined by the sum of the normalized distance vectors, but that seemed a bit
> far fetched to me.

It may not be that far fetched. The X and Y normalization factors are
separate to support non-square pixels. Taking for example a pixel whose
height is twice the width, the vertical distance in physical units is
twice the vertical distance in pixels. The vertical normalization factor
will be twice the horizontal factor to account for that and calculate a
radius in physical units (as the displacement caused by the chromatic
aberration depends on the physical distance to the image sensor). The
pixel displacement then needs to be converted back to pixel units.

Of course someone may point out that a normalization factor of 0 should
result in an infinite vertical displacement when converting back. The
above explanation may make no sense, or the hardware implementation may
take some shortcuts that result in no vertical displacement when y_nf is
0. It could be interesting to vary y_nf and see how the vertical
displacement evolves.

> And even with that, I would expect to be able to turn a straight line
> into a curve. Maybe I'm doing something wrong, but I can't recall ever being able to.
> 
> >>>>> + * then transformed into the [0,255] range based on the following formula:
> >>>>
> >>>> s/transformed/normalized ?
> >>>
> >>> To be honest I vastly prefer "transform" / "map" over "normalize" here.
> >>
> >> You're right here, the below formula doesn't normalize the
> >> distance in an interval but just re-scale it
> >>
> >>>>> + *
> >>>>> + *   (((d << 4) >> s) * f) >> 5
> >>>>> + *
> >>>>> + * where `d` is the distance, `s` and `f` are the normalization parameters:
> >>>>
> >>>> Can you use 'ns' and 'nf' to match the below ?
> >>>
> >>> Adjusted.
> >>
> >> Thanks!
> >>
> >>>>> + *
> >>>>> + * @x_nf: horizontal normalization scale parameter (5-bit unsigned integer; [0,31])
> >>>>> + * @x_ns: horizontal normalization shift parameter (4-bit unsigned integer; [0,15])
> >>>>> + *
> >>>>> + * @y_nf: vertical normalization scale parameter (5-bit unsigned integer; [0,31])
> >>>>> + * @y_ns: vertical normalization shift parameter (4-bit unsigned integer; [0,15])
> >>>>> + *
> >>>>> + * These parameters should be chosen based on the image resolution, the position
> >>>>> + * of the optical center, and the shape of pixels: so that no normalized distance
> >>>>
> >>>> s/pixels:/pixels/
> >>>
> >>> Replaced `:` with `,`.
> >>>
> >>>>> + * is larger than 255. If the pixels have square shape, the two sets of parameters
> >>>>> + * should be equal.
> > 
> > I wonder if we could have anisotropic lenses (from the point of view of
> > chromatic aberrations) with square pixels. We can deal with it later.
> 
> Right, this is what the documentation suggests, and I believe it is probably "correct enough"
> most of the time. But should I remove it?
> 
> >>>>> + *
> >>>>> + * The actual amount of correction is calculated with a third degree polynomial:
> >>>>> + *
> >>>>> + *   c[0] * r + c[1] * r^2 + c[2] * r^3
> >>>>> + *
> >>>>> + * where `c` is the set of coefficients for the given color, and `r` is distance:
> >>>>> + *
> >>>>> + * @red: red coefficients (5.4 two's complement; [-16,15.9375])
> >>>>> + * @blue: blue coefficients (5.4 two's complement; [-16,15.9375])
> >>>>> + *
> >>>>> + * Finally, the amount is clipped as requested:
> >>>>> + *
> >>>>> + * @h_clip_mode: maximum horizontal shift (from enum rkisp1_cif_isp_cac_h_clip_mode)
> >>>>> + * @v_clip_mode: maximum vertical shift (from enum rkisp1_cif_isp_cac_v_clip_mode)
> >>>>> + *
> >>>>> + * A positive result will shift away from the optical center, while a negative
> >>>>> + * one will shift towards the optical center. In the latter case, the pixel
> >>>>> + * values at the edges are duplicated.
> >>>>> + */
> >>>>> +struct rkisp1_cif_isp_cac_config {
> >>>>> +	__u8 h_clip_mode;
> >>>>> +	__u8 v_clip_mode;
> >>>>> +
> >>>>> +	__u16 h_count_start;
> >>>>> +	__u16 v_count_start;
> >>>>> +
> >>>>> +	__u16 red[3];
> >>>>> +	__u16 blue[3];
> >>>>> +
> >>>>> +	__u8 x_nf;
> >>>>> +	__u8 x_ns;
> >>>>> +
> >>>>> +	__u8 y_nf;
> >>>>> +	__u8 y_ns;
> >>>>> +};
> >>>>> +
> >>>>>    /*---------- PART2: Measurement Statistics ------------*/
> >>>>>
> >>>>>    /**
> >>>>> @@ -1161,6 +1247,7 @@ enum rkisp1_ext_params_block_type {
> >>>>>    	RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND,
> >>>>>    	RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS,
> >>>>>    	RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR,
> >>>>> +	RKISP1_EXT_PARAMS_BLOCK_TYPE_CAC,
> >>>>>    };
> >>>>>
> >>>>>    /* For backward compatibility */
> >>>>> @@ -1507,6 +1594,22 @@ struct rkisp1_ext_params_wdr_config {
> >>>>>    	struct rkisp1_cif_isp_wdr_config config;
> >>>>>    } __attribute__((aligned(8)));
> >>>>>
> >>>>> +/**
> >>>>> + * struct rkisp1_ext_params_cac_config - RkISP1 extensible params CAC config
> >>>>> + *
> >>>>> + * RkISP1 extensible parameters CAC block.
> >>>>> + * Identified by :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_CAC`.
> >>>>> + *
> >>>>> + * @header: The RkISP1 extensible parameters header, see
> >>>>> + *	    :c:type:`rkisp1_ext_params_block_header`
> >>>>> + * @config: CAC configuration, see
> >>>>> + *	    :c:type:`rkisp1_cif_isp_cac_config`
> >>>>> + */
> >>>>> +struct rkisp1_ext_params_cac_config {
> >>>>> +	struct rkisp1_ext_params_block_header header;
> >>>>> +	struct rkisp1_cif_isp_cac_config config;
> >>>>> +} __attribute__((aligned(8)));
> >>>>> +
> >>>>>    /*
> >>>>>     * The rkisp1_ext_params_compand_curve_config structure is counted twice as it
> >>>>>     * is used for both the COMPAND_EXPAND and COMPAND_COMPRESS block types.
> >>>>> @@ -1532,7 +1635,8 @@ struct rkisp1_ext_params_wdr_config {
> >>>>>    	sizeof(struct rkisp1_ext_params_compand_bls_config)		+\
> >>>>>    	sizeof(struct rkisp1_ext_params_compand_curve_config)		+\
> >>>>>    	sizeof(struct rkisp1_ext_params_compand_curve_config)		+\
> >>>>> -	sizeof(struct rkisp1_ext_params_wdr_config))
> >>>>> +	sizeof(struct rkisp1_ext_params_wdr_config)			+\
> >>>>> +	sizeof(struct rkisp1_ext_params_cac_config))
> >>>>
> >>>> All minors, please add
> >>>> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
> > 
> > and
> > 
> > Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > 
> >>>>>
> >>>>>    /**
> >>>>>     * enum rksip1_ext_param_buffer_version - RkISP1 extensible parameters version

-- 
Regards,

Laurent Pinchart


^ permalink raw reply

* Re: [PATCH v4 2/4] irqchip/ast2700-intc: Add AST2700-A2 support
From: Thomas Gleixner @ 2026-03-31 16:10 UTC (permalink / raw)
  To: Ryan Chen, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Joel Stanley, Andrew Jeffery, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Alexandre Ghiti
  Cc: linux-kernel, devicetree, linux-arm-kernel, linux-aspeed,
	linux-riscv, Ryan Chen
In-Reply-To: <20260330-irqchip-v4-2-3c0f1620cc06@aspeedtech.com>

On Mon, Mar 30 2026 at 14:32, Ryan Chen wrote:
> +static int resolve_parent_range_for_output(const struct aspeed_intc0 *intc0,
> +					   const struct fwnode_handle *parent,
> +					   u32 output,
> +					   struct aspeed_intc_interrupt_range *resolved)

Please reduce the number of line breaks. You still have 100 characters.

> +{
> +	for (size_t i = 0; i < intc0->ranges.nranges; i++) {
> +		struct aspeed_intc_interrupt_range range =
> +			intc0->ranges.ranges[i];

No line break required.

> +static int aspeed_intc1_irq_domain_activate(struct irq_domain *domain,
> +					    struct irq_data *data, bool reserve)
> +{
> +	struct aspeed_intc1 *intc1 = irq_data_get_irq_chip_data(data);
> +	struct aspeed_intc_interrupt_range resolved;
> +	int rc, bank, bit;
> +	u32 mask;
> +
> +	if (WARN_ON_ONCE((data->hwirq >> INTC1_ROUTE_SHIFT) >= ARRAY_SIZE(aspeed_intc1_routes)))
> +		return -EINVAL;
> +
> +	/*
> +	 * outpin may be an error if the upstream is the BootMCU APLIC node, or
> +	 * anything except a valid intc0 driver instance
> +	 */
> +	rc = aspeed_intc0_resolve_route(intc1->upstream, INTC1_ROUTE_NUM,
> +					aspeed_intc1_routes[data->hwirq >> INTC1_ROUTE_SHIFT],
> +					intc1->ranges.nranges,
> +					intc1->ranges.ranges, &resolved);

Please test your code with CONFIG_PROVE_LOCKING=y, which is mandatory
for submission according to documentation.

This is invoked with the interrupt descriptor lock held and interrupts
disabled.

       aspeed_intc0_resolve_route()
                ....
                irq_find_matching_fwspec()
                	mutex_lock(&irq_domain_mutex); <---- FAIL

Thanks,

        tglx

        


^ permalink raw reply

* Re: [PATCH 2/3] drm: lcdif: Use dedicated set/clr registers for polarity/edge
From: Lucas Stach @ 2026-03-31 16:04 UTC (permalink / raw)
  To: Paul Kocialkowski
  Cc: dri-devel, imx, linux-arm-kernel, linux-kernel, Marek Vasut,
	Stefan Agner, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Simona Vetter, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Krzysztof Hałasa,
	Marco Felsch, Liu Ying
In-Reply-To: <acvllbRTHyVFTgmS@collins>

Am Dienstag, dem 31.03.2026 um 17:17 +0200 schrieb Paul Kocialkowski:
> Hi Lucas,
> 
> Le Tue 31 Mar 26, 11:09, Lucas Stach a écrit :
> > Hi Paul,
> > 
> > Am Dienstag, dem 31.03.2026 um 00:46 +0200 schrieb Paul Kocialkowski:
> > > The lcdif v3 hardware comes with dedicated registers to set and clear
> > > polarity bits in the CTRL register. It is unclear if there is a
> > > difference with writing to the CTRL register directly.
> > > 
> > > Follow the NXP BSP reference by using these registers, in case there is
> > > a subtle difference caused by using them.
> > > 
> > I don't really like that patch, as it blows up what is currently a
> > single register access to three separate ones. If there is no clear
> > benefit (as in it has been shown to fix any issue), I would prefer this
> > code to stay as-is.
> 
> Well I guess the cost of a few writes vs a single one is rather
> negligible.
> 
Yea, a few writes don't really hurt. But I don't think there is a very
good reason to set this register this way, see below.

> I'm rather worried that there might be an undocumented
> reason why these registers exist in the first place and why they are
> used in the BSP.
> 
> But yes this is only speculation and I could not witness any actual
> issue. My setup (lcdif3 with hdmi) uses all positive polarities which is
> the default state, so not a good way to check.
> 
> It would be great if somebody from NXP could confirm whether this is
> needed or not. In the meantime I guess we can drop the patch. It'll stay
> on the list in case someone has polarity issues later :)

The separate clr/set registers are a rather common design feat found on
Freescale/NXP IP blocks from the MXS era. On some of those IP blocks
_all_ registers are presented as a base/clr/set triplet in the
registers space. As far as I can tell they are mostly useful when you
want to set/clear individual bits from a register without having to
remember or executing a readback of the current state.

In cases like the one changed in this patch, where the full register
state is set in one go, directly writing to the base register is the
right thing to do.

Regards,
Lucas


^ permalink raw reply

* Re: [PATCH] pmdomain: imx8mp-blk-ctrl: Keep the NOC_HDCP clock enabled
From: Ulf Hansson @ 2026-03-31 16:03 UTC (permalink / raw)
  To: Jacky Bai
  Cc: Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	Shawn Guo, Peng Fan, linux-pm, imx, linux-arm-kernel,
	linux-kernel
In-Reply-To: <20260320-imx8mp_hdmi_hang-v1-1-ccfce0517999@nxp.com>

On Fri, 20 Mar 2026 at 09:41, Jacky Bai <ping.bai@nxp.com> wrote:
>
> Keep the NOC_HDCP clock always enabled to fix the potential hang
> caused by the NoC ADB400 port power down handshake.
>
> Fixes: 77b0ddb42add ("soc: imx: add i.MX8MP HDMI blk ctrl HDCP/HRV_MWR")
> Signed-off-by: Jacky Bai <ping.bai@nxp.com>

Applied for fixes and by adding a stable tag, thanks!

Kind regards
Uffe


> ---
>  drivers/pmdomain/imx/imx8mp-blk-ctrl.c | 8 +-------
>  1 file changed, 1 insertion(+), 7 deletions(-)
>
> diff --git a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c
> index 8fc79f9723f07e34fd3f5162f2c9c549dcdaeb5b..3f5b9499d30a0c8fb8ad8ba3b638d7de1fc55ab6 100644
> --- a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c
> +++ b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c
> @@ -352,9 +352,6 @@ static void imx8mp_hdmi_blk_ctrl_power_on(struct imx8mp_blk_ctrl *bc,
>                 regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(12));
>                 regmap_clear_bits(bc->regmap, HDMI_TX_CONTROL0, BIT(3));
>                 break;
> -       case IMX8MP_HDMIBLK_PD_HDCP:
> -               regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL0, BIT(11));
> -               break;
>         case IMX8MP_HDMIBLK_PD_HRV:
>                 regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(3) | BIT(4) | BIT(5));
>                 regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(15));
> @@ -408,9 +405,6 @@ static void imx8mp_hdmi_blk_ctrl_power_off(struct imx8mp_blk_ctrl *bc,
>                 regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL0, BIT(7));
>                 regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(22) | BIT(24));
>                 break;
> -       case IMX8MP_HDMIBLK_PD_HDCP:
> -               regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL0, BIT(11));
> -               break;
>         case IMX8MP_HDMIBLK_PD_HRV:
>                 regmap_clear_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(15));
>                 regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(3) | BIT(4) | BIT(5));
> @@ -439,7 +433,7 @@ static int imx8mp_hdmi_power_notifier(struct notifier_block *nb,
>         regmap_write(bc->regmap, HDMI_RTX_CLK_CTL0, 0x0);
>         regmap_write(bc->regmap, HDMI_RTX_CLK_CTL1, 0x0);
>         regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL0,
> -                       BIT(0) | BIT(1) | BIT(10));
> +                       BIT(0) | BIT(1) | BIT(10) | BIT(11));
>         regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(0));
>
>         /*
>
> ---
> base-commit: b84a0ebe421ca56995ff78b66307667b62b3a900
> change-id: 20260122-imx8mp_hdmi_hang-e7c5b4bdf1bb
>
> Best regards,
> --
> Jacky Bai <ping.bai@nxp.com>
>


^ permalink raw reply

* Re: [PATCH v4 5/9] mfd: mt6397: Add support for MT6392 PMIC
From: kernel test robot @ 2026-03-31 16:01 UTC (permalink / raw)
  To: Luca Leonardo Scorcia, linux-mediatek
  Cc: llvm, oe-kbuild-all, Fabien Parent, Val Packett,
	Luca Leonardo Scorcia, AngeloGioacchino Del Regno,
	Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Sen Chu, Sean Wang, Macpaul Lin, Lee Jones, Matthias Brugger,
	Linus Walleij, Liam Girdwood, Mark Brown, Gary Bisson,
	Julien Massot, Louis-Alexis Eyraud, Chen Zhong, linux-input,
	devicetree, linux-kernel, linux-pm, linux-arm-kernel, linux-gpio
In-Reply-To: <20260330083429.359819-6-l.scorcia@gmail.com>

Hi Luca,

kernel test robot noticed the following build warnings:

[auto build test WARNING on lee-mfd/for-mfd-next]
[also build test WARNING on broonie-regulator/for-next linusw-pinctrl/devel linusw-pinctrl/for-next lee-mfd/for-mfd-fixes linus/master v7.0-rc6 next-20260330]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Luca-Leonardo-Scorcia/dt-bindings-mfd-mt6397-Add-MT6392-PMIC/20260331-081127
base:   https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next
patch link:    https://lore.kernel.org/r/20260330083429.359819-6-l.scorcia%40gmail.com
patch subject: [PATCH v4 5/9] mfd: mt6397: Add support for MT6392 PMIC
config: s390-randconfig-002-20260331 (https://download.01.org/0day-ci/archive/20260331/202603312339.CMJpqhEq-lkp@intel.com/config)
compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260331/202603312339.CMJpqhEq-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603312339.CMJpqhEq-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/mfd/mt6397-core.c:421:16: warning: cast to smaller integer type 'enum mfd_match_data' from 'const void *' [-Wvoid-pointer-to-enum-cast]
     421 |         device_data = (enum mfd_match_data)of_device_get_match_data(&pdev->dev);
         |                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1 warning generated.


vim +421 drivers/mfd/mt6397-core.c

   398	
   399	static int mt6397_probe(struct platform_device *pdev)
   400	{
   401		int ret;
   402		unsigned int id = 0;
   403		struct mt6397_chip *pmic;
   404		const struct chip_data *pmic_core;
   405		enum mfd_match_data device_data;
   406	
   407		pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
   408		if (!pmic)
   409			return -ENOMEM;
   410	
   411		pmic->dev = &pdev->dev;
   412	
   413		/*
   414		 * mt6397 MFD is child device of soc pmic wrapper.
   415		 * Regmap is set from its parent.
   416		 */
   417		pmic->regmap = dev_get_regmap(pdev->dev.parent, NULL);
   418		if (!pmic->regmap)
   419			return -ENODEV;
   420	
 > 421		device_data = (enum mfd_match_data)of_device_get_match_data(&pdev->dev);
   422		switch (device_data) {
   423		case MATCH_DATA_MT6323:
   424			pmic_core = &mt6323_core;
   425			break;
   426		case MATCH_DATA_MT6328:
   427			pmic_core = &mt6328_core;
   428			break;
   429		case MATCH_DATA_MT6331:
   430			pmic_core = &mt6331_mt6332_core;
   431			break;
   432		case MATCH_DATA_MT6357:
   433			pmic_core = &mt6357_core;
   434			break;
   435		case MATCH_DATA_MT6358:
   436			pmic_core = &mt6358_core;
   437			break;
   438		case MATCH_DATA_MT6359:
   439			pmic_core = &mt6359_core;
   440			break;
   441		case MATCH_DATA_MT6392:
   442			pmic_core = &mt6392_core;
   443			break;
   444		case MATCH_DATA_MT6397:
   445			pmic_core = &mt6397_core;
   446			break;
   447		default:
   448			dev_err(&pdev->dev, "Unknown device match data %u\n", device_data);
   449			return -ENODEV;
   450		}
   451	
   452		ret = regmap_read(pmic->regmap, pmic_core->cid_addr, &id);
   453		if (ret) {
   454			dev_err(&pdev->dev, "Failed to read chip id: %d\n", ret);
   455			return ret;
   456		}
   457	
   458		pmic->chip_id = (id >> pmic_core->cid_shift) & 0xff;
   459	
   460		platform_set_drvdata(pdev, pmic);
   461	
   462		pmic->irq = platform_get_irq(pdev, 0);
   463		if (pmic->irq <= 0)
   464			return pmic->irq;
   465	
   466		ret = pmic_core->irq_init(pmic);
   467		if (ret)
   468			return ret;
   469	
   470		ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
   471					   pmic_core->cells, pmic_core->cell_size,
   472					   NULL, 0, pmic->irq_domain);
   473		if (ret) {
   474			irq_domain_remove(pmic->irq_domain);
   475			dev_err(&pdev->dev, "failed to add child devices: %d\n", ret);
   476		}
   477	
   478		return ret;
   479	}
   480	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


^ permalink raw reply

* Re: [PATCH 12/15] KVM: arm64: Remove evaluation of timer state in kvm_cpu_has_pending_timer()
From: Sascha Bischoff @ 2026-03-31 15:44 UTC (permalink / raw)
  To: maz@kernel.org, kvmarm@lists.linux.dev, kvm@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
  Cc: Joey Gouly, yuzenghui@huawei.com, Suzuki Poulose,
	oupton@kernel.org, broonie@kernel.org, nd
In-Reply-To: <20260326153530.3981879-13-maz@kernel.org>

On Thu, 2026-03-26 at 15:35 +0000, Marc Zyngier wrote:
> The vgic-v5 code added some evaluations of the timers in a helper
> funtion
> (kvm_cpu_has_pending_timer()) that is called to determine whether
> the vcpu can wake-up.
> 
> But looking at the timer there is wrong:
> 
> - we want to see timers that are signalling an interrupt to the
>   vcpu, and not just that have a pending interrupt
> 
> - we already have kvm_arch_vcpu_runnable() that evaluates the
>   state of interrupts
> 
> - kvm_cpu_has_pending_timer() really is about WFIT, as the timeout
>   does not generate an interrupt, and is therefore distinct from
>   the point above
> 
> As a consequence, revert these changes.
> 
> Fixes: 9491c63b6cd7b ("KVM: arm64: gic-v5: Enlighten arch timer for
> GICv5")
> Link:
> https://sashiko.dev/#/patchset/20260319154937.3619520-1-sascha.bischoff%40arm.com
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>  arch/arm64/kvm/arch_timer.c | 6 +-----
>  1 file changed, 1 insertion(+), 5 deletions(-)
> 
> diff --git a/arch/arm64/kvm/arch_timer.c
> b/arch/arm64/kvm/arch_timer.c
> index 37279f8748695..6608c47d1f628 100644
> --- a/arch/arm64/kvm/arch_timer.c
> +++ b/arch/arm64/kvm/arch_timer.c
> @@ -402,11 +402,7 @@ static bool kvm_timer_should_fire(struct
> arch_timer_context *timer_ctx)
>  
>  int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
>  {
> -	struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
> -	struct arch_timer_context *ptimer = vcpu_ptimer(vcpu);
> -
> -	return kvm_timer_should_fire(vtimer) ||
> kvm_timer_should_fire(ptimer) ||
> -	       (vcpu_has_wfit_active(vcpu) && wfit_delay_ns(vcpu) ==
> 0);
> +	return vcpu_has_wfit_active(vcpu) && wfit_delay_ns(vcpu) ==
> 0;
>  }
>  
>  /*

Hi Marc,

It appears that I'd misunderstood the intent of this function when I
originally wrote this bit code. That is: I agree that these checks
shouldn't be here.

However, said checks are needed somewhere. With GICv5, we directly
inject the timer state (when possible, at least) which means that we
never see the timer interrupt firing on the host, and don't track if it
is pending or not in struct vgic_irq as the pending state is driven by
the hardware itself. The result of this is that we explicitly need to
check if the timer interrupt would be pending if the guest were running
somewhere.

I've run with this complete series and have tested the following
change. It is sufficient to catch this case, and does it as part of
checking if there are pending interrupts, i.e., a more appropriate
place called via kvm_arch_vcpu_runnable(). It is yet-another GICv5
special case, however. I'd love to hear your thoughts.

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index cbea4d9ee9552..f8b95721857c3 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -400,6 +400,14 @@ static bool kvm_timer_should_fire(struct arch_timer_context *timer_ctx)
        return cval <= now;
 }
 
+int kvm_cpu_timer_should_fire(struct kvm_vcpu *vcpu)
+{
+       struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
+       struct arch_timer_context *ptimer = vcpu_ptimer(vcpu);
+
+       return kvm_timer_should_fire(vtimer) || kvm_timer_should_fire(ptimer);
+}
+
 int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
 {
        return vcpu_has_wfit_active(vcpu) && wfit_delay_ns(vcpu) == 0;
diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c
index 7680ced92f715..ffb91f535efe8 100644
--- a/arch/arm64/kvm/vgic/vgic.c
+++ b/arch/arm64/kvm/vgic/vgic.c
@@ -1238,6 +1238,9 @@ int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu)
                if (READ_ONCE(vcpu->arch.vgic_cpu.vgic_v5.gicv5_vpe.db_fired))
                        return true;
 
+               if (kvm_cpu_timer_should_fire(vcpu))
+                       return true;
+
                return vgic_v5_has_pending_ppi(vcpu);
        }
 
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index f0e56ad36bf1f..1bd6f23979837 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -825,6 +825,7 @@ int kvm_vgic_get_map(struct kvm_vcpu *vcpu, unsigned int vintid);
 bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid);
 
 int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
+int kvm_cpu_timer_should_fire(struct kvm_vcpu *vcpu);
 
 void kvm_vgic_load(struct kvm_vcpu *vcpu);
 void kvm_vgic_put(struct kvm_vcpu *vcpu);



^ permalink raw reply related

* [PATCH 3/3] KVM: arm64: Don't hold 'vm_table_lock' across guest page reclaim
From: Will Deacon @ 2026-03-31 15:50 UTC (permalink / raw)
  To: kvmarm
  Cc: linux-arm-kernel, Will Deacon, Marc Zyngier, Oliver Upton,
	Joey Gouly, Suzuki K Poulose, Zenghui Yu, Catalin Marinas,
	Quentin Perret, Fuad Tabba, Vincent Donnefort, Mostafa Saleh,
	Alexandru Elisei
In-Reply-To: <20260331155056.28220-1-will@kernel.org>

Now that the teardown of a VM cannot be finalised as long as a reference
is held on the VM, rework __pkvm_reclaim_dying_guest_page() to hold a
reference to the dying VM rather than take the global 'vm_table_lock'
during the reclaim operation.

Signed-off-by: Will Deacon <will@kernel.org>
---
 arch/arm64/kvm/hyp/nvhe/pkvm.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index b955da0e50bc..7ed96d64d611 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -918,15 +918,16 @@ teardown_donated_memory(struct kvm_hyp_memcache *mc, void *addr, size_t size)
 
 int __pkvm_reclaim_dying_guest_page(pkvm_handle_t handle, u64 gfn)
 {
-	struct pkvm_hyp_vm *hyp_vm;
+	struct pkvm_hyp_vm *hyp_vm = get_pkvm_hyp_vm(handle);
 	int ret = -EINVAL;
 
-	hyp_spin_lock(&vm_table_lock);
-	hyp_vm = get_vm_by_handle(handle);
-	if (hyp_vm && hyp_vm->kvm.arch.pkvm.is_dying)
-		ret = __pkvm_host_reclaim_page_guest(gfn, hyp_vm);
-	hyp_spin_unlock(&vm_table_lock);
+	if (!hyp_vm)
+		return ret;
 
+	if (hyp_vm->kvm.arch.pkvm.is_dying)
+		ret = __pkvm_host_reclaim_page_guest(gfn, hyp_vm);
+
+	put_pkvm_hyp_vm(hyp_vm);
 	return ret;
 }
 
-- 
2.53.0.1118.gaef5881109-goog



^ permalink raw reply related

* [PATCH 2/3] KVM: arm64: Allow get_pkvm_hyp_vm() to take a reference to a dying VM
From: Will Deacon @ 2026-03-31 15:50 UTC (permalink / raw)
  To: kvmarm
  Cc: linux-arm-kernel, Will Deacon, Marc Zyngier, Oliver Upton,
	Joey Gouly, Suzuki K Poulose, Zenghui Yu, Catalin Marinas,
	Quentin Perret, Fuad Tabba, Vincent Donnefort, Mostafa Saleh,
	Alexandru Elisei
In-Reply-To: <20260331155056.28220-1-will@kernel.org>

Now that completion of the teardown path requires a refcount of zero for
the target VM, we can allow get_pkvm_hyp_vm() to take a reference on a
dying VM, which is necessary to unshare pages with a non-protected VM
during the teardown process itself.

Note that vCPUs belonging to a dying VM cannot be loaded and pages can
only be reclaimed from a protected VM (via
__pkvm_reclaim_dying_guest_page()) if the target VM is in the dying
state.

Signed-off-by: Will Deacon <will@kernel.org>
---
 arch/arm64/kvm/hyp/nvhe/pkvm.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 3fd3b930beeb..b955da0e50bc 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -309,14 +309,8 @@ struct pkvm_hyp_vm *get_pkvm_hyp_vm(pkvm_handle_t handle)
 
 	hyp_spin_lock(&vm_table_lock);
 	hyp_vm = get_vm_by_handle(handle);
-	if (!hyp_vm)
-		goto unlock;
-
-	if (hyp_vm->kvm.arch.pkvm.is_dying)
-		hyp_vm = NULL;
-	else
+	if (hyp_vm)
 		hyp_page_ref_inc(hyp_virt_to_page(hyp_vm));
-unlock:
 	hyp_spin_unlock(&vm_table_lock);
 
 	return hyp_vm;
-- 
2.53.0.1118.gaef5881109-goog



^ 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