Re: [PATCH v3] tracing/net_sched: NULL pointer dereference in perf_trace_qdisc_reset()

2024-06-21 Thread Yunseong Kim
Hi Taehee,

On 6/22/24 2:50 오후, Taehee Yoo wrote:
> On Sat, Jun 22, 2024 at 1:58 PM  wrote:
>>
>> From: Yunseong Kim 
>>
> 
> Hi Yunseong,
> Thanks a lot for this work!

Thank you Taehee for reviewing our patch. It's greatly appreciated.

>> During qdisc initialization, qdisc was being set to noop_queue.
>> In veth_init_queue, the initial tx_num was reduced back to one,
>> causing the qdisc reset to be called with noop, which led to the kernel 
>> panic.
>>
>> I've attached the GitHub gist link that C converted syz-execprogram
>> source code and 3 log of reproduced vmcore-dmesg.
>>
>>  https://gist.github.com/yskelg/cc64562873ce249cdd0d5a358b77d740
>>
>> Yeoreum and I use two fuzzing tool simultaneously.
>>
>> One process with syz-executor : https://github.com/google/syzkaller
>>
>>  $ ./syz-execprog -executor=./syz-executor -repeat=1 -sandbox=setuid \
>> -enable=none -collide=false log1
>>
>> The other process with perf fuzzer:
>>  https://github.com/deater/perf_event_tests/tree/master/fuzzer
>>
>>  $ perf_event_tests/fuzzer/perf_fuzzer
>>
>> I think this will happen on the kernel version.
>>
>>  Linux kernel version +v6.7.10, +v6.8, +v6.9 and it could happen in v6.10.
>>
>> This occurred from 51270d573a8d. I think this patch is absolutely
>> necessary. Previously, It was showing not intended string value of name.


> I found a simple reproducer, please use the below command to test this patch.
> 
> echo 1 > /sys/kernel/debug/tracing/events/enable
> ip link add veth0 type veth peer name veth1

The perf event is activated by perf_fuzzer, and it's indeed a similar
environment with veth.

> In my machine, the splat looks like:
> 
> BUG: kernel NULL pointer dereference, address: 0130
> #PF: supervisor read access in kernel mode
> #PF: error_code(0x) - not-present page
> PGD 0 P4D 0
> Oops: Oops:  [#1] PREEMPT SMP NOPTI
> CPU: 1 PID: 1207 Comm: ip Not tainted 6.10.0-rc4+ #25
> 362ec22a686962a9936425abea9a73f03b445c0c
> Hardware name: ASUS System Product Name/PRIME Z690-P D4, BIOS 0603 11/01/2021
> RIP: 0010:strlen+0x0/0x20
> Code: f7 75 ec 31 c0 c3 cc cc cc cc 48 89 f8 c3 cc cc cc cc 0f 1f 84
> 00 00 00 00 00 90 90 90 90 9c
> RSP: 0018:bed8435c7630 EFLAGS: 00010206
> RAX: 92d629c0 RBX: a14100185c60 RCX: 
> RDX: 0001 RSI: 92d62840 RDI: 0130
> RBP: 92dc4600 R08: 0fd0 R09: 0010
> R10: 92c66c98 R11: 0001 R12: 0001
> R13:  R14: 0130 R15: 92d62840
> FS: 7f6a94e50b80() GS:a1485f68() knlGS:
> CS: 0010 DS:  ES:  CR0: 80050033
> CR2: 0130 CR3: 000103414000 CR4: 007506f0
> PKRU: 5554
> Call Trace:
> 
> ? __die+0x20/0x70
> ? page_fault_oops+0x15a/0x460
> ? trace_event_raw_event_x86_exceptions+0x5f/0xa0
> ? exc_page_fault+0x6e/0x180
> ? asm_exc_page_fault+0x22/0x30
> ? __pfx_strlen+0x10/0x10
> trace_event_raw_event_qdisc_reset+0x4d/0x180
> ? synchronize_rcu_expedited+0x215/0x240
> ? __pfx_autoremove_wake_function+0x10/0x10
> qdisc_reset+0x130/0x150
> netif_set_real_num_tx_queues+0xe3/0x1e0
> veth_init_queues+0x44/0x70 [veth 24a9dd1cd1b1b279e1b467ad46d47a753799b428]
> veth_newlink+0x22b/0x440 [veth 24a9dd1cd1b1b279e1b467ad46d47a753799b428]
> __rtnl_newlink+0x718/0x990
> rtnl_newlink+0x44/0x70
> rtnetlink_rcv_msg+0x159/0x410
> ? kmalloc_reserve+0x90/0xf0
> ? trace_event_raw_event_kmem_cache_alloc+0x87/0xe0
> ? __pfx_rtnetlink_rcv_msg+0x10/0x10
> netlink_rcv_skb+0x54/0x100
> netlink_unicast+0x243/0x370
> netlink_sendmsg+0x1bb/0x3e0
> sys_sendmsg+0x2bb/0x320
> ? copy_msghdr_from_user+0x6d/0xa0
> ___sys_sendmsg+0x88/0xd0
> 
> Thanks a lot!
> Taehee Yoo

I think this bug might cause inconvenience for developers working on net
devices driver in a virtual machine when they use tracing.

I'm appreciate your effort in reproducing it.

Warm Regards,
Yunseong Kim



Re: [PATCH v3] tracing/net_sched: NULL pointer dereference in perf_trace_qdisc_reset()

2024-06-21 Thread Taehee Yoo
On Sat, Jun 22, 2024 at 1:58 PM  wrote:
>
> From: Yunseong Kim 
>

Hi Yunseong,
Thanks a lot for this work!

> In the TRACE_EVENT(qdisc_reset) NULL dereference occurred from
>
>  qdisc->dev_queue->dev  ->name
>
> This situation simulated from bunch of veths and Bluetooth dis/reconnection.
>
> During qdisc initialization, qdisc was being set to noop_queue.
> In veth_init_queue, the initial tx_num was reduced back to one,
> causing the qdisc reset to be called with noop, which led to the kernel panic.
>
> I've attached the GitHub gist link that C converted syz-execprogram
> source code and 3 log of reproduced vmcore-dmesg.
>
>  https://gist.github.com/yskelg/cc64562873ce249cdd0d5a358b77d740
>
> Yeoreum and I use two fuzzing tool simultaneously.
>
> One process with syz-executor : https://github.com/google/syzkaller
>
>  $ ./syz-execprog -executor=./syz-executor -repeat=1 -sandbox=setuid \
> -enable=none -collide=false log1
>
> The other process with perf fuzzer:
>  https://github.com/deater/perf_event_tests/tree/master/fuzzer
>
>  $ perf_event_tests/fuzzer/perf_fuzzer
>
> I think this will happen on the kernel version.
>
>  Linux kernel version +v6.7.10, +v6.8, +v6.9 and it could happen in v6.10.
>
> This occurred from 51270d573a8d. I think this patch is absolutely
> necessary. Previously, It was showing not intended string value of name.
>
> I've reproduced 3 time from my fedora 40 Debug Kernel with any other module
> or patched.
>
>  version: 6.10.0-0.rc2.20240608gitdc772f8237f9.29.fc41.aarch64+debug
>
> [ 5287.164555] veth0_vlan: left promiscuous mode
> [ 5287.164929] veth1_macvtap: left promiscuous mode
> [ 5287.164950] veth0_macvtap: left promiscuous mode
> [ 5287.164983] veth1_vlan: left promiscuous mode
> [ 5287.165008] veth0_vlan: left promiscuous mode
> [ 5287.165450] veth1_macvtap: left promiscuous mode
> [ 5287.165472] veth0_macvtap: left promiscuous mode
> [ 5287.165502] veth1_vlan: left promiscuous mode
> …
> [ 5297.598240] bridge0: port 2(bridge_slave_1) entered blocking state
> [ 5297.598262] bridge0: port 2(bridge_slave_1) entered forwarding state
> [ 5297.598296] bridge0: port 1(bridge_slave_0) entered blocking state
> [ 5297.598313] bridge0: port 1(bridge_slave_0) entered forwarding state
> [ 5297.616090] 8021q: adding VLAN 0 to HW filter on device bond0
> [ 5297.620405] bridge0: port 1(bridge_slave_0) entered disabled state
> [ 5297.620730] bridge0: port 2(bridge_slave_1) entered disabled state
> [ 5297.627247] 8021q: adding VLAN 0 to HW filter on device team0
> [ 5297.629636] bridge0: port 1(bridge_slave_0) entered blocking state
> …
> [ 5298.002798] bridge_slave_0: left promiscuous mode
> [ 5298.002869] bridge0: port 1(bridge_slave_0) entered disabled state
> [ 5298.309444] bond0 (unregistering): (slave bond_slave_0): Releasing backup 
> interface
> [ 5298.315206] bond0 (unregistering): (slave bond_slave_1): Releasing backup 
> interface
> [ 5298.320207] bond0 (unregistering): Released all slaves
> [ 5298.354296] hsr_slave_0: left promiscuous mode
> [ 5298.360750] hsr_slave_1: left promiscuous mode
> [ 5298.374889] veth1_macvtap: left promiscuous mode
> [ 5298.374931] veth0_macvtap: left promiscuous mode
> [ 5298.374988] veth1_vlan: left promiscuous mode
> [ 5298.375024] veth0_vlan: left promiscuous mode
> [ 5299.109741] team0 (unregistering): Port device team_slave_1 removed
> [ 5299.185870] team0 (unregistering): Port device team_slave_0 removed
> …
> [ 5300.155443] Bluetooth: hci3: unexpected cc 0x0c03 length: 249 > 1
> [ 5300.155724] Bluetooth: hci3: unexpected cc 0x1003 length: 249 > 9
> [ 5300.155988] Bluetooth: hci3: unexpected cc 0x1001 length: 249 > 9
> ….
> [ 5301.075531] team0: Port device team_slave_1 added
> [ 5301.085515] bridge0: port 1(bridge_slave_0) entered blocking state
> [ 5301.085531] bridge0: port 1(bridge_slave_0) entered disabled state
> [ 5301.085588] bridge_slave_0: entered allmulticast mode
> [ 5301.085800] bridge_slave_0: entered promiscuous mode
> [ 5301.095617] bridge0: port 1(bridge_slave_0) entered blocking state
> [ 5301.095633] bridge0: port 1(bridge_slave_0) entered disabled state
> …
> [ 5301.149734] bond0: (slave bond_slave_0): Enslaving as an active interface 
> with an up link
> [ 5301.173234] bond0: (slave bond_slave_0): Enslaving as an active interface 
> with an up link
> [ 5301.180517] bond0: (slave bond_slave_1): Enslaving as an active interface 
> with an up link
> [ 5301.193481] hsr_slave_0: entered promiscuous mode
> [ 5301.204425] hsr_slave_1: entered promiscuous mode
> [ 5301.210172] debugfs: Directory 'hsr0' with parent 'hsr' already present!
> [ 5301.210185] Cannot create hsr debugfs directory
> [ 5301.224061] bond0: (slave bond_slave_1): Enslaving as an active interface 
> with an up link
> [ 5301.246901] bond0: (slave bond_slave_0): Enslaving as an active interface 
> with an up link
> [ 5301.255934] team0: Port device team_slave_0 added
> [ 5301.256480] team0: Port device team_slave_1 added
> [ 5301.256948] team0: Port device tea

[PATCH v3] tracing/net_sched: NULL pointer dereference in perf_trace_qdisc_reset()

2024-06-21 Thread yskelg
From: Yunseong Kim 

In the TRACE_EVENT(qdisc_reset) NULL dereference occurred from

 qdisc->dev_queue->dev  ->name

This situation simulated from bunch of veths and Bluetooth dis/reconnection.

During qdisc initialization, qdisc was being set to noop_queue.
In veth_init_queue, the initial tx_num was reduced back to one,
causing the qdisc reset to be called with noop, which led to the kernel panic.

I've attached the GitHub gist link that C converted syz-execprogram
source code and 3 log of reproduced vmcore-dmesg.

 https://gist.github.com/yskelg/cc64562873ce249cdd0d5a358b77d740

Yeoreum and I use two fuzzing tool simultaneously.

One process with syz-executor : https://github.com/google/syzkaller

 $ ./syz-execprog -executor=./syz-executor -repeat=1 -sandbox=setuid \
-enable=none -collide=false log1

The other process with perf fuzzer:
 https://github.com/deater/perf_event_tests/tree/master/fuzzer

 $ perf_event_tests/fuzzer/perf_fuzzer

I think this will happen on the kernel version.

 Linux kernel version +v6.7.10, +v6.8, +v6.9 and it could happen in v6.10.

This occurred from 51270d573a8d. I think this patch is absolutely 
necessary. Previously, It was showing not intended string value of name.

I've reproduced 3 time from my fedora 40 Debug Kernel with any other module 
or patched.

 version: 6.10.0-0.rc2.20240608gitdc772f8237f9.29.fc41.aarch64+debug

[ 5287.164555] veth0_vlan: left promiscuous mode
[ 5287.164929] veth1_macvtap: left promiscuous mode
[ 5287.164950] veth0_macvtap: left promiscuous mode
[ 5287.164983] veth1_vlan: left promiscuous mode
[ 5287.165008] veth0_vlan: left promiscuous mode
[ 5287.165450] veth1_macvtap: left promiscuous mode
[ 5287.165472] veth0_macvtap: left promiscuous mode
[ 5287.165502] veth1_vlan: left promiscuous mode
…
[ 5297.598240] bridge0: port 2(bridge_slave_1) entered blocking state
[ 5297.598262] bridge0: port 2(bridge_slave_1) entered forwarding state
[ 5297.598296] bridge0: port 1(bridge_slave_0) entered blocking state
[ 5297.598313] bridge0: port 1(bridge_slave_0) entered forwarding state
[ 5297.616090] 8021q: adding VLAN 0 to HW filter on device bond0
[ 5297.620405] bridge0: port 1(bridge_slave_0) entered disabled state
[ 5297.620730] bridge0: port 2(bridge_slave_1) entered disabled state
[ 5297.627247] 8021q: adding VLAN 0 to HW filter on device team0
[ 5297.629636] bridge0: port 1(bridge_slave_0) entered blocking state
…
[ 5298.002798] bridge_slave_0: left promiscuous mode
[ 5298.002869] bridge0: port 1(bridge_slave_0) entered disabled state
[ 5298.309444] bond0 (unregistering): (slave bond_slave_0): Releasing backup 
interface
[ 5298.315206] bond0 (unregistering): (slave bond_slave_1): Releasing backup 
interface
[ 5298.320207] bond0 (unregistering): Released all slaves
[ 5298.354296] hsr_slave_0: left promiscuous mode
[ 5298.360750] hsr_slave_1: left promiscuous mode
[ 5298.374889] veth1_macvtap: left promiscuous mode
[ 5298.374931] veth0_macvtap: left promiscuous mode
[ 5298.374988] veth1_vlan: left promiscuous mode
[ 5298.375024] veth0_vlan: left promiscuous mode
[ 5299.109741] team0 (unregistering): Port device team_slave_1 removed
[ 5299.185870] team0 (unregistering): Port device team_slave_0 removed
…
[ 5300.155443] Bluetooth: hci3: unexpected cc 0x0c03 length: 249 > 1
[ 5300.155724] Bluetooth: hci3: unexpected cc 0x1003 length: 249 > 9
[ 5300.155988] Bluetooth: hci3: unexpected cc 0x1001 length: 249 > 9
….
[ 5301.075531] team0: Port device team_slave_1 added
[ 5301.085515] bridge0: port 1(bridge_slave_0) entered blocking state
[ 5301.085531] bridge0: port 1(bridge_slave_0) entered disabled state
[ 5301.085588] bridge_slave_0: entered allmulticast mode
[ 5301.085800] bridge_slave_0: entered promiscuous mode
[ 5301.095617] bridge0: port 1(bridge_slave_0) entered blocking state
[ 5301.095633] bridge0: port 1(bridge_slave_0) entered disabled state
…
[ 5301.149734] bond0: (slave bond_slave_0): Enslaving as an active interface 
with an up link
[ 5301.173234] bond0: (slave bond_slave_0): Enslaving as an active interface 
with an up link
[ 5301.180517] bond0: (slave bond_slave_1): Enslaving as an active interface 
with an up link
[ 5301.193481] hsr_slave_0: entered promiscuous mode
[ 5301.204425] hsr_slave_1: entered promiscuous mode
[ 5301.210172] debugfs: Directory 'hsr0' with parent 'hsr' already present!
[ 5301.210185] Cannot create hsr debugfs directory
[ 5301.224061] bond0: (slave bond_slave_1): Enslaving as an active interface 
with an up link
[ 5301.246901] bond0: (slave bond_slave_0): Enslaving as an active interface 
with an up link
[ 5301.255934] team0: Port device team_slave_0 added
[ 5301.256480] team0: Port device team_slave_1 added
[ 5301.256948] team0: Port device team_slave_0 added
…
[ 5301.435928] hsr_slave_0: entered promiscuous mode
[ 5301.446029] hsr_slave_1: entered promiscuous mode
[ 5301.455872] debugfs: Directory 'hsr0' with parent 'hsr' already present!
[ 5301.455884] Cannot create hsr debugfs directory
[ 5301.502664] hsr_slave_

Re: [PATCH net v2] net/sched: Fixes: 51270d573a8d NULL ptr deref in perf_trace_qdisc_reset()

2024-06-21 Thread Yunseong Kim
Hi Jakub,

On 6/22/24 9:05 오전, Jakub Kicinski wrote:
> On Sat, 22 Jun 2024 01:25:54 +0900 ysk...@gmail.com wrote:
>> Subject: [PATCH net v2] net/sched: Fixes: 51270d573a8d NULL ptr deref in 
>> perf_trace_qdisc_reset()
> 
> the Fixes tag goes before your signoff, rather than as title.
> try
> 
>   git log --grep=Fixes

Oh, I'm sorry. I completely misunderstood. Thank you for kindly explaining!

I'll take your advice and send the next version of the patch!

Warm Regards,
Yunseong Kim



Re: [PATCH 0/4] MCE wrapper and support for new SMCA syndrome MSRs

2024-06-21 Thread Naik, Avadhut



On 6/21/2024 15:01, Yazen Ghannam wrote:
> On Fri, Jun 21, 2024 at 06:58:23PM +0200, Borislav Petkov wrote:
>> On Thu, May 30, 2024 at 04:16:16PM -0500, Avadhut Naik wrote:
>>>  arch/x86/include/asm/mce.h  |  20 ++-
>>>  arch/x86/kernel/cpu/mce/apei.c  | 111 ++
>>>  arch/x86/kernel/cpu/mce/core.c  | 191 ++--
>>>  arch/x86/kernel/cpu/mce/dev-mcelog.c|   2 +-
>>>  arch/x86/kernel/cpu/mce/genpool.c   |  20 +--
>>>  arch/x86/kernel/cpu/mce/inject.c|   4 +-
>>>  arch/x86/kernel/cpu/mce/internal.h  |   4 +-
>>>  drivers/acpi/acpi_extlog.c  |   2 +-
>>>  drivers/acpi/nfit/mce.c |   2 +-
>>>  drivers/edac/i7core_edac.c  |   2 +-
>>>  drivers/edac/igen6_edac.c   |   2 +-
>>>  drivers/edac/mce_amd.c  |  27 +++-
>>>  drivers/edac/pnd2_edac.c|   2 +-
>>>  drivers/edac/sb_edac.c  |   2 +-
>>>  drivers/edac/skx_common.c   |   2 +-
>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c |   2 +-
>>>  drivers/ras/amd/fmpm.c  |   2 +-
>>>  drivers/ras/cec.c   |   2 +-
>>>  include/trace/events/mce.h  |  51 ---
>>>  19 files changed, 286 insertions(+), 164 deletions(-)
>>
>> This doesn't apply anymore - please redo this ontop of the latest tip/master.
>>
> 
> Avadhut,
> 
> You can drop the dependencies on other sets. We can sort out any
> conflicts as needed.
> 
Sounds good! Will redo on top of tip/master and resubmit.

> Thanks,
> Yazen

-- 
Thanks,
Avadhut Naik



Re: [PATCH net-next] net: virtio: unify code to init stats

2024-06-21 Thread Jakub Kicinski
On Thu, 20 Jun 2024 03:44:53 -0400 Michael S. Tsirkin wrote:
> Moving initialization of stats structure into
> __free_old_xmit reduces the code size slightly.
> It also makes it clearer that this function shouldn't
> be called multiple times on the same stats struct.
> 
> Signed-off-by: Michael S. Tsirkin 

Hm, doesn't apply?



Re: [PATCH net v2] net/sched: Fixes: 51270d573a8d NULL ptr deref in perf_trace_qdisc_reset()

2024-06-21 Thread Jakub Kicinski
On Sat, 22 Jun 2024 01:25:54 +0900 ysk...@gmail.com wrote:
> Subject: [PATCH net v2] net/sched: Fixes: 51270d573a8d NULL ptr deref in 
> perf_trace_qdisc_reset()

the Fixes tag goes before your signoff, rather than as title.
try

  git log --grep=Fixes
-- 
pw-bot: cr



[PATCH v9 5/5] remoteproc: qcom: enable in-kernel PD mapper

2024-06-21 Thread Dmitry Baryshkov
Request in-kernel protection domain mapper to be started before starting
Qualcomm DSP and release it once DSP is stopped. Once all DSPs are
stopped, the PD mapper will be stopped too.

Reviewed-by: Chris Lew 
Tested-by: Steev Klimaszewski 
Tested-by: Neil Armstrong  # on SM8550-QRD
Signed-off-by: Dmitry Baryshkov 
---
 drivers/remoteproc/qcom_common.c| 87 +
 drivers/remoteproc/qcom_common.h| 10 +
 drivers/remoteproc/qcom_q6v5_adsp.c |  3 ++
 drivers/remoteproc/qcom_q6v5_mss.c  |  3 ++
 drivers/remoteproc/qcom_q6v5_pas.c  |  3 ++
 drivers/remoteproc/qcom_q6v5_wcss.c |  3 ++
 6 files changed, 109 insertions(+)

diff --git a/drivers/remoteproc/qcom_common.c b/drivers/remoteproc/qcom_common.c
index 03e5f5d533eb..8c8688f99f0a 100644
--- a/drivers/remoteproc/qcom_common.c
+++ b/drivers/remoteproc/qcom_common.c
@@ -13,6 +13,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -25,6 +26,7 @@
 #define to_glink_subdev(d) container_of(d, struct qcom_rproc_glink, subdev)
 #define to_smd_subdev(d) container_of(d, struct qcom_rproc_subdev, subdev)
 #define to_ssr_subdev(d) container_of(d, struct qcom_rproc_ssr, subdev)
+#define to_pdm_subdev(d) container_of(d, struct qcom_rproc_pdm, subdev)
 
 #define MAX_NUM_OF_SS   10
 #define MAX_REGION_NAME_LENGTH  16
@@ -519,5 +521,90 @@ void qcom_remove_ssr_subdev(struct rproc *rproc, struct 
qcom_rproc_ssr *ssr)
 }
 EXPORT_SYMBOL_GPL(qcom_remove_ssr_subdev);
 
+static void pdm_dev_release(struct device *dev)
+{
+   struct auxiliary_device *adev = to_auxiliary_dev(dev);
+
+   kfree(adev);
+}
+
+static int pdm_notify_prepare(struct rproc_subdev *subdev)
+{
+   struct qcom_rproc_pdm *pdm = to_pdm_subdev(subdev);
+   struct auxiliary_device *adev;
+   int ret;
+
+   adev = kzalloc(sizeof(*adev), GFP_KERNEL);
+   if (!adev)
+   return -ENOMEM;
+
+   adev->dev.parent = pdm->dev;
+   adev->dev.release = pdm_dev_release;
+   adev->name = "pd-mapper";
+   adev->id = pdm->index;
+
+   ret = auxiliary_device_init(adev);
+   if (ret) {
+   kfree(adev);
+   return ret;
+   }
+
+   ret = auxiliary_device_add(adev);
+   if (ret) {
+   auxiliary_device_uninit(adev);
+   return ret;
+   }
+
+   pdm->adev = adev;
+
+   return 0;
+}
+
+
+static void pdm_notify_unprepare(struct rproc_subdev *subdev)
+{
+   struct qcom_rproc_pdm *pdm = to_pdm_subdev(subdev);
+
+   if (!pdm->adev)
+   return;
+
+   auxiliary_device_delete(pdm->adev);
+   auxiliary_device_uninit(pdm->adev);
+   pdm->adev = NULL;
+}
+
+/**
+ * qcom_add_pdm_subdev() - register PD Mapper subdevice
+ * @rproc: rproc handle
+ * @pdm:   PDM subdevice handle
+ *
+ * Register @pdm so that Protection Device mapper service is started when the
+ * DSP is started too.
+ */
+void qcom_add_pdm_subdev(struct rproc *rproc, struct qcom_rproc_pdm *pdm)
+{
+   pdm->dev = &rproc->dev;
+   pdm->index = rproc->index;
+
+   pdm->subdev.prepare = pdm_notify_prepare;
+   pdm->subdev.unprepare = pdm_notify_unprepare;
+
+   rproc_add_subdev(rproc, &pdm->subdev);
+}
+EXPORT_SYMBOL_GPL(qcom_add_pdm_subdev);
+
+/**
+ * qcom_remove_pdm_subdev() - remove PD Mapper subdevice
+ * @rproc: rproc handle
+ * @pdm:   PDM subdevice handle
+ *
+ * Remove the PD Mapper subdevice.
+ */
+void qcom_remove_pdm_subdev(struct rproc *rproc, struct qcom_rproc_pdm *pdm)
+{
+   rproc_remove_subdev(rproc, &pdm->subdev);
+}
+EXPORT_SYMBOL_GPL(qcom_remove_pdm_subdev);
+
 MODULE_DESCRIPTION("Qualcomm Remoteproc helper driver");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/remoteproc/qcom_common.h b/drivers/remoteproc/qcom_common.h
index 9ef4449052a9..b07fbaa091a0 100644
--- a/drivers/remoteproc/qcom_common.h
+++ b/drivers/remoteproc/qcom_common.h
@@ -34,6 +34,13 @@ struct qcom_rproc_ssr {
struct qcom_ssr_subsystem *info;
 };
 
+struct qcom_rproc_pdm {
+   struct rproc_subdev subdev;
+   struct device *dev;
+   int index;
+   struct auxiliary_device *adev;
+};
+
 void qcom_minidump(struct rproc *rproc, unsigned int minidump_id,
void (*rproc_dumpfn_t)(struct rproc *rproc,
struct rproc_dump_segment *segment, void *dest, 
size_t offset,
@@ -52,6 +59,9 @@ void qcom_add_ssr_subdev(struct rproc *rproc, struct 
qcom_rproc_ssr *ssr,
 const char *ssr_name);
 void qcom_remove_ssr_subdev(struct rproc *rproc, struct qcom_rproc_ssr *ssr);
 
+void qcom_add_pdm_subdev(struct rproc *rproc, struct qcom_rproc_pdm *pdm);
+void qcom_remove_pdm_subdev(struct rproc *rproc, struct qcom_rproc_pdm *pdm);
+
 #if IS_ENABLED(CONFIG_QCOM_SYSMON)
 struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
   const char *name,
diff --git a/drivers/remoteproc/qcom_q6v5_adsp.c 
b/driv

[PATCH v9 4/5] soc: qcom: add pd-mapper implementation

2024-06-21 Thread Dmitry Baryshkov
Existing userspace protection domain mapper implementation has several
issue. It doesn't play well with CONFIG_EXTRA_FIRMWARE, it doesn't
reread JSON files if firmware location is changed (or if firmware was
not available at the time pd-mapper was started but the corresponding
directory is mounted later), etc.

Provide in-kernel service implementing protection domain mapping
required to work with several services, which are provided by the DSP
firmware.

This module is loaded automatically by the remoteproc drivers when
necessary via the symbol dependency. It uses a root node to match a
protection domains map for a particular board. It is not possible to
implement it as a 'driver' as there is no corresponding device.

Tested-by: Steev Klimaszewski 
Tested-by: Alexey Minnekhanov 
Reviewed-by: Chris Lew 
Tested-by: Neil Armstrong  # on SM8550-QRD
Signed-off-by: Dmitry Baryshkov 
---
 drivers/soc/qcom/Kconfig  |  11 +
 drivers/soc/qcom/Makefile |   1 +
 drivers/soc/qcom/pdr_internal.h   |  14 +
 drivers/soc/qcom/qcom_pd_mapper.c | 676 ++
 drivers/soc/qcom/qcom_pdr_msg.c   |  34 ++
 5 files changed, 736 insertions(+)

diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 95973c6b828f..0a2f2bfd7863 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -72,6 +72,17 @@ config QCOM_OCMEM
  requirements. This is typically used by the GPU, camera/video, and
  audio components on some Snapdragon SoCs.
 
+config QCOM_PD_MAPPER
+   tristate "Qualcomm Protection Domain Mapper"
+   select QCOM_QMI_HELPERS
+   depends on NET && QRTR
+   default QCOM_RPROC_COMMON
+   help
+ The Protection Domain Mapper maps registered services to the domains
+ and instances handled by the remote DSPs. This is a kernel-space
+ implementation of the service. It is a simpler alternative to the
+ userspace daemon.
+
 config QCOM_PDR_HELPERS
tristate
select QCOM_QMI_HELPERS
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index 3110ac3288bc..d3560f861085 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o
 obj-$(CONFIG_QCOM_GSBI)+=  qcom_gsbi.o
 obj-$(CONFIG_QCOM_MDT_LOADER)  += mdt_loader.o
 obj-$(CONFIG_QCOM_OCMEM)   += ocmem.o
+obj-$(CONFIG_QCOM_PD_MAPPER)   += qcom_pd_mapper.o
 obj-$(CONFIG_QCOM_PDR_HELPERS) += pdr_interface.o
 obj-$(CONFIG_QCOM_PDR_MSG) += qcom_pdr_msg.o
 obj-$(CONFIG_QCOM_PMIC_GLINK)  += pmic_glink.o
diff --git a/drivers/soc/qcom/pdr_internal.h b/drivers/soc/qcom/pdr_internal.h
index 7e5bb5a95275..8d17f7fb79e7 100644
--- a/drivers/soc/qcom/pdr_internal.h
+++ b/drivers/soc/qcom/pdr_internal.h
@@ -13,6 +13,8 @@
 #define SERVREG_SET_ACK_REQ0x23
 #define SERVREG_RESTART_PD_REQ 0x24
 
+#define SERVREG_LOC_PFR_REQ0x24
+
 #define SERVREG_DOMAIN_LIST_LENGTH 32
 #define SERVREG_RESTART_PD_REQ_MAX_LEN 67
 #define SERVREG_REGISTER_LISTENER_REQ_LEN  71
@@ -20,6 +22,7 @@
 #define SERVREG_GET_DOMAIN_LIST_REQ_MAX_LEN74
 #define SERVREG_STATE_UPDATED_IND_MAX_LEN  79
 #define SERVREG_GET_DOMAIN_LIST_RESP_MAX_LEN   2389
+#define SERVREG_LOC_PFR_RESP_MAX_LEN   10
 
 struct servreg_location_entry {
char name[SERVREG_NAME_LENGTH + 1];
@@ -79,6 +82,15 @@ struct servreg_set_ack_resp {
struct qmi_response_type_v01 resp;
 };
 
+struct servreg_loc_pfr_req {
+   char service[SERVREG_NAME_LENGTH + 1];
+   char reason[257];
+};
+
+struct servreg_loc_pfr_resp {
+   struct qmi_response_type_v01 rsp;
+};
+
 extern const struct qmi_elem_info servreg_location_entry_ei[];
 extern const struct qmi_elem_info servreg_get_domain_list_req_ei[];
 extern const struct qmi_elem_info servreg_get_domain_list_resp_ei[];
@@ -89,5 +101,7 @@ extern const struct qmi_elem_info 
servreg_restart_pd_resp_ei[];
 extern const struct qmi_elem_info servreg_state_updated_ind_ei[];
 extern const struct qmi_elem_info servreg_set_ack_req_ei[];
 extern const struct qmi_elem_info servreg_set_ack_resp_ei[];
+extern const struct qmi_elem_info servreg_loc_pfr_req_ei[];
+extern const struct qmi_elem_info servreg_loc_pfr_resp_ei[];
 
 #endif
diff --git a/drivers/soc/qcom/qcom_pd_mapper.c 
b/drivers/soc/qcom/qcom_pd_mapper.c
new file mode 100644
index ..ecb64f06527f
--- /dev/null
+++ b/drivers/soc/qcom/qcom_pd_mapper.c
@@ -0,0 +1,676 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Qualcomm Protection Domain mapper
+ *
+ * Copyright (c) 2023 Linaro Ltd.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pdr_internal.h"
+
+#define SERVREG_QMI_VERSION 0x101
+#define SERVREG_QMI_INSTANCE 0
+
+#define TMS_SERVREG_SERVICE "tms/servreg"
+
+struct qcom_pdm_

[PATCH v9 3/5] soc: qcom: pdr: extract PDR message marshalling data

2024-06-21 Thread Dmitry Baryshkov
The in-kernel PD mapper is going to use same message structures as the
QCOM_PDR_HELPERS module. Extract message marshalling data to separate
module that can be used by both PDR helpers and by PD mapper.

Reviewed-by: Bryan O'Donoghue 
Tested-by: Steev Klimaszewski 
Tested-by: Alexey Minnekhanov 
Tested-by: Neil Armstrong  # on SM8550-QRD
Signed-off-by: Dmitry Baryshkov 
---
 drivers/soc/qcom/Kconfig|   4 +
 drivers/soc/qcom/Makefile   |   1 +
 drivers/soc/qcom/pdr_internal.h | 306 ++
 drivers/soc/qcom/qcom_pdr_msg.c | 319 
 4 files changed, 334 insertions(+), 296 deletions(-)

diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 5af33b0e3470..95973c6b828f 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -75,8 +75,12 @@ config QCOM_OCMEM
 config QCOM_PDR_HELPERS
tristate
select QCOM_QMI_HELPERS
+   select QCOM_PDR_MSG
depends on NET
 
+config QCOM_PDR_MSG
+   tristate
+
 config QCOM_PMIC_PDCHARGER_ULOG
tristate "Qualcomm PMIC PDCharger ULOG driver"
depends on RPMSG
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index ca0bece0dfff..3110ac3288bc 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_QCOM_GSBI) +=  qcom_gsbi.o
 obj-$(CONFIG_QCOM_MDT_LOADER)  += mdt_loader.o
 obj-$(CONFIG_QCOM_OCMEM)   += ocmem.o
 obj-$(CONFIG_QCOM_PDR_HELPERS) += pdr_interface.o
+obj-$(CONFIG_QCOM_PDR_MSG) += qcom_pdr_msg.o
 obj-$(CONFIG_QCOM_PMIC_GLINK)  += pmic_glink.o
 obj-$(CONFIG_QCOM_PMIC_GLINK)  += pmic_glink_altmode.o
 obj-$(CONFIG_QCOM_PMIC_PDCHARGER_ULOG) += pmic_pdcharger_ulog.o
diff --git a/drivers/soc/qcom/pdr_internal.h b/drivers/soc/qcom/pdr_internal.h
index 03c282b7f17e..7e5bb5a95275 100644
--- a/drivers/soc/qcom/pdr_internal.h
+++ b/drivers/soc/qcom/pdr_internal.h
@@ -28,83 +28,12 @@ struct servreg_location_entry {
u32 instance;
 };
 
-static const struct qmi_elem_info servreg_location_entry_ei[] = {
-   {
-   .data_type  = QMI_STRING,
-   .elem_len   = SERVREG_NAME_LENGTH + 1,
-   .elem_size  = sizeof(char),
-   .array_type = NO_ARRAY,
-   .tlv_type   = 0,
-   .offset = offsetof(struct servreg_location_entry,
-  name),
-   },
-   {
-   .data_type  = QMI_UNSIGNED_4_BYTE,
-   .elem_len   = 1,
-   .elem_size  = sizeof(u32),
-   .array_type = NO_ARRAY,
-   .tlv_type   = 0,
-   .offset = offsetof(struct servreg_location_entry,
-  instance),
-   },
-   {
-   .data_type  = QMI_UNSIGNED_1_BYTE,
-   .elem_len   = 1,
-   .elem_size  = sizeof(u8),
-   .array_type = NO_ARRAY,
-   .tlv_type   = 0,
-   .offset = offsetof(struct servreg_location_entry,
-  service_data_valid),
-   },
-   {
-   .data_type  = QMI_UNSIGNED_4_BYTE,
-   .elem_len   = 1,
-   .elem_size  = sizeof(u32),
-   .array_type = NO_ARRAY,
-   .tlv_type   = 0,
-   .offset = offsetof(struct servreg_location_entry,
-  service_data),
-   },
-   {}
-};
-
 struct servreg_get_domain_list_req {
char service_name[SERVREG_NAME_LENGTH + 1];
u8 domain_offset_valid;
u32 domain_offset;
 };
 
-static const struct qmi_elem_info servreg_get_domain_list_req_ei[] = {
-   {
-   .data_type  = QMI_STRING,
-   .elem_len   = SERVREG_NAME_LENGTH + 1,
-   .elem_size  = sizeof(char),
-   .array_type = NO_ARRAY,
-   .tlv_type   = 0x01,
-   .offset = offsetof(struct servreg_get_domain_list_req,
-  service_name),
-   },
-   {
-   .data_type  = QMI_OPT_FLAG,
-   .elem_len   = 1,
-   .elem_size  = sizeof(u8),
-   .array_type = NO_ARRAY,
-   .tlv_type   = 0x10,
-   .offset = offsetof(struct servreg_get_domain_list_req,
-  domain_offset_valid),
-   },
-   {
-   .data_type  = QMI_UNSIGNED_4_BYTE,
-   .elem_len   = 1,
-   .elem_size  = sizeof(u32),
-   .array_type = NO_ARRAY,
-   .tlv_type   = 0x10,
-   .offset = offsetof(struct servreg_get_domain_list_req,
-  domain_offset),
-   },
-   {

[PATCH v9 2/5] soc: qcom: pdr: fix parsing of domains lists

2024-06-21 Thread Dmitry Baryshkov
While parsing the domains list, start offsets from 0 rather than from
domains_read. The domains_read is equal to the total count of the
domains we have seen, while the domains list in the message starts from
offset 0.

Fixes: fbe639b44a82 ("soc: qcom: Introduce Protection Domain Restart helpers")
Tested-by: Steev Klimaszewski 
Tested-by: Alexey Minnekhanov 
Reviewed-by: Chris Lew 
Tested-by: Neil Armstrong  # on SM8550-QRD
Signed-off-by: Dmitry Baryshkov 
---
 drivers/soc/qcom/pdr_interface.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/soc/qcom/pdr_interface.c b/drivers/soc/qcom/pdr_interface.c
index 76a62c2ecc58..216166e98fae 100644
--- a/drivers/soc/qcom/pdr_interface.c
+++ b/drivers/soc/qcom/pdr_interface.c
@@ -417,7 +417,7 @@ static int pdr_locate_service(struct pdr_handle *pdr, 
struct pdr_service *pds)
if (ret < 0)
goto out;
 
-   for (i = domains_read; i < resp->domain_list_len; i++) {
+   for (i = 0; i < resp->domain_list_len; i++) {
entry = &resp->domain_list[i];
 
if (strnlen(entry->name, sizeof(entry->name)) == 
sizeof(entry->name))

-- 
2.39.2




[PATCH v9 1/5] soc: qcom: pdr: protect locator_addr with the main mutex

2024-06-21 Thread Dmitry Baryshkov
If the service locator server is restarted fast enough, the PDR can
rewrite locator_addr fields concurrently. Protect them by placing
modification of those fields under the main pdr->lock.

Fixes: fbe639b44a82 ("soc: qcom: Introduce Protection Domain Restart helpers")
Tested-by: Neil Armstrong  # on SM8550-QRD
Tested-by: Steev Klimaszewski 
Tested-by: Alexey Minnekhanov 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/soc/qcom/pdr_interface.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/qcom/pdr_interface.c b/drivers/soc/qcom/pdr_interface.c
index a1b6a4081dea..76a62c2ecc58 100644
--- a/drivers/soc/qcom/pdr_interface.c
+++ b/drivers/soc/qcom/pdr_interface.c
@@ -76,12 +76,12 @@ static int pdr_locator_new_server(struct qmi_handle *qmi,
  locator_hdl);
struct pdr_service *pds;
 
+   mutex_lock(&pdr->lock);
/* Create a local client port for QMI communication */
pdr->locator_addr.sq_family = AF_QIPCRTR;
pdr->locator_addr.sq_node = svc->node;
pdr->locator_addr.sq_port = svc->port;
 
-   mutex_lock(&pdr->lock);
pdr->locator_init_complete = true;
mutex_unlock(&pdr->lock);
 
@@ -104,10 +104,10 @@ static void pdr_locator_del_server(struct qmi_handle *qmi,
 
mutex_lock(&pdr->lock);
pdr->locator_init_complete = false;
-   mutex_unlock(&pdr->lock);
 
pdr->locator_addr.sq_node = 0;
pdr->locator_addr.sq_port = 0;
+   mutex_unlock(&pdr->lock);
 }
 
 static const struct qmi_ops pdr_locator_ops = {
@@ -365,12 +365,14 @@ static int pdr_get_domain_list(struct 
servreg_get_domain_list_req *req,
if (ret < 0)
return ret;
 
+   mutex_lock(&pdr->lock);
ret = qmi_send_request(&pdr->locator_hdl,
   &pdr->locator_addr,
   &txn, SERVREG_GET_DOMAIN_LIST_REQ,
   SERVREG_GET_DOMAIN_LIST_REQ_MAX_LEN,
   servreg_get_domain_list_req_ei,
   req);
+   mutex_unlock(&pdr->lock);
if (ret < 0) {
qmi_txn_cancel(&txn);
return ret;

-- 
2.39.2




[PATCH v9 0/5] soc: qcom: add in-kernel pd-mapper implementation

2024-06-21 Thread Dmitry Baryshkov
Protection domain mapper is a QMI service providing mapping between
'protection domains' and services supported / allowed in these domains.
For example such mapping is required for loading of the WiFi firmware or
for properly starting up the UCSI / altmode / battery manager support.

The existing userspace implementation has several issue. It doesn't play
well with CONFIG_EXTRA_FIRMWARE, it doesn't reread the JSON files if the
firmware location is changed (or if the firmware was not available at
the time pd-mapper was started but the corresponding directory is
mounted later), etc.

However this configuration is largely static and common between
different platforms. Provide in-kernel service implementing static
per-platform data.

---
Changes in v9:
- Adjust locking in pdr_get_domain_list(), releasing the mutex right
  after qmi_send_request() (Chris Lew)
- Link to v8: 
https://lore.kernel.org/r/20240512-qcom-pd-mapper-v8-0-5ecbb276f...@linaro.org

Changes in v8:
- Reworked pd-mapper to register as an rproc_subdev / auxdev
- Dropped Tested-by from Steev and Alexey from the last patch since the
  implementation was changed significantly.
- Add sensors, cdsp and mpss_root domains to 660 config (Alexey
  Minnekhanov)
- Added platform entry for sm4250 (used for qrb4210 / RB2)
- Added locking to the pdr_get_domain_list() (Chris Lew)
- Remove the call to qmi_del_server() and corresponding API (Chris Lew)
- In qmi_handle_init() changed 1024 to a defined constant (Chris Lew)
- Link to v7: 
https://lore.kernel.org/r/20240424-qcom-pd-mapper-v7-0-05f7fc646...@linaro.org

Changes in v7:
- Fixed modular build (Steev)
- Link to v6: 
https://lore.kernel.org/r/20240422-qcom-pd-mapper-v6-0-f96957d01...@linaro.org

Changes in v6:
- Reworked mutex to fix lockdep issue on deregistration
- Fixed dependencies between PD-mapper and remoteproc to fix modular
  builds (Krzysztof)
- Added EXPORT_SYMBOL_GPL to fix modular builds (Krzysztof)
- Fixed kerneldocs (Krzysztof)
- Removed extra pr_debug messages (Krzysztof)
- Fixed wcss build (Krzysztof)
- Added platforms which do not require protection domain mapping to
  silence the notice on those platforms
- Link to v5: 
https://lore.kernel.org/r/20240419-qcom-pd-mapper-v5-0-e35b6f847...@linaro.org

Changes in v5:
- pdr: drop lock in pdr_register_listener, list_lock is already held (Chris Lew)
- pd_mapper: reworked to provide static configuration per platform
  (Bjorn)
- Link to v4: 
https://lore.kernel.org/r/20240311-qcom-pd-mapper-v4-0-24679cca5...@linaro.org

Changes in v4:
- Fixed missing chunk, reenabled kfree in qmi_del_server (Konrad)
- Added configuration for sm6350 (Thanks to Luca)
- Removed RFC tag (Konrad)
- Link to v3: 
https://lore.kernel.org/r/20240304-qcom-pd-mapper-v3-0-6858fa1ac...@linaro.org

Changes in RFC v3:
- Send start / stop notifications when PD-mapper domain list is changed
- Reworked the way PD-mapper treats protection domains, register all of
  them in a single batch
- Added SC7180 domains configuration based on TCL Book 14 GO
- Link to v2: 
https://lore.kernel.org/r/20240301-qcom-pd-mapper-v2-0-5d12a081d...@linaro.org

Changes in RFC v2:
- Swapped num_domains / domains (Konrad)
- Fixed an issue with battery not working on sc8280xp
- Added missing configuration for QCS404

To: Bjorn Andersson 
To: Konrad Dybcio 
To: Sibi Sankar 
To: Mathieu Poirier 
Cc: linux-arm-...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-remotep...@vger.kernel.org

---
Dmitry Baryshkov (5):
  soc: qcom: pdr: protect locator_addr with the main mutex
  soc: qcom: pdr: fix parsing of domains lists
  soc: qcom: pdr: extract PDR message marshalling data
  soc: qcom: add pd-mapper implementation
  remoteproc: qcom: enable in-kernel PD mapper

 drivers/remoteproc/qcom_common.c|  87 +
 drivers/remoteproc/qcom_common.h|  10 +
 drivers/remoteproc/qcom_q6v5_adsp.c |   3 +
 drivers/remoteproc/qcom_q6v5_mss.c  |   3 +
 drivers/remoteproc/qcom_q6v5_pas.c  |   3 +
 drivers/remoteproc/qcom_q6v5_wcss.c |   3 +
 drivers/soc/qcom/Kconfig|  15 +
 drivers/soc/qcom/Makefile   |   2 +
 drivers/soc/qcom/pdr_interface.c|   8 +-
 drivers/soc/qcom/pdr_internal.h | 318 ++---
 drivers/soc/qcom/qcom_pd_mapper.c   | 676 
 drivers/soc/qcom/qcom_pdr_msg.c | 353 +++
 12 files changed, 1183 insertions(+), 298 deletions(-)
---
base-commit: 2102cb0d050d34d50b9642a3a50861787527e922
change-id: 20240301-qcom-pd-mapper-e12d622d4ad0

Best regards,
-- 
Dmitry Baryshkov 




Re: [PATCH v2 0/3] Add Sony Xperia Z3 Compact smartphone

2024-06-21 Thread Dmitry Baryshkov
On Fri, Jun 21, 2024 at 05:26:41PM GMT, Valeriy Klimin wrote:
> This is almost the same as the dts of the Xperia Z3, except for the
> battery charge limits. 
> 
> The current on the l21 regulator for shinano is also bumped up
> to stop SD card errors.
> 
> Signed-off-by: Valeriy Klimin 
> ---
> Changes in v2:
> - Reordered dt-bindings and dts commits
> - Link to v1: 
> https://lore.kernel.org/r/20240621-sony-aries-v1-0-bcf968769...@gmail.com

Please let reviewers finish their job first. It's recommended to post
once in 24 hours timeframe. Otherwise you end up getting feedback and
tags for v1, while you have already posted v2.

> 
> ---
> Valeriy Klimin (3):
>   dt-bindings: arm: qcom: Add Sony Xperia Z3 Compact
>   ARM: dts: qcom: Add Sony Xperia Z3 Compact smartphone
>   ARM: dts: qcom: msm8974-sony-shinano: increase load on l21 for sdhc2
> 
>  Documentation/devicetree/bindings/arm/qcom.yaml|  1 +
>  arch/arm/boot/dts/qcom/Makefile|  1 +
>  .../qcom-msm8974pro-sony-xperia-shinano-aries.dts  | 44 
> ++
>  ...qcom-msm8974pro-sony-xperia-shinano-common.dtsi |  2 +
>  4 files changed, 48 insertions(+)
> ---
> base-commit: cd214efd16e30bf1aa40ccfaaf9177f47dd21fd5
> change-id: 20240620-sony-aries-4a5bce06c91d
> 
> Best regards,
> -- 
> Valeriy Klimin 
> 

-- 
With best wishes
Dmitry



Re: [PATCH v9 7/8] clk: qcom: Add WCSSAON reset

2024-06-21 Thread Dmitry Baryshkov
On Fri, Jun 21, 2024 at 05:16:58PM GMT, Gokul Sriram Palanisamy wrote:
> Add WCSSAON reset required for Q6v5 on IPQ8074 SoC.
> 
> Signed-off-by: Nikhil Prakash V 
> Signed-off-by: Sricharan R 
> Signed-off-by: Gokul Sriram Palanisamy 

Three authors for a single line?

> Acked-by: Stephen Boyd 
> ---
>  drivers/clk/qcom/gcc-ipq8074.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
> index 32fd01ef469a..d382d16b9c10 100644
> --- a/drivers/clk/qcom/gcc-ipq8074.c
> +++ b/drivers/clk/qcom/gcc-ipq8074.c
> @@ -4712,6 +4712,7 @@ static const struct qcom_reset_map gcc_ipq8074_resets[] 
> = {
>   [GCC_NSSPORT4_RESET] = { .reg = 0x68014, .bitmask = BIT(27) | 
> GENMASK(9, 8) },
>   [GCC_NSSPORT5_RESET] = { .reg = 0x68014, .bitmask = BIT(28) | 
> GENMASK(11, 10) },
>   [GCC_NSSPORT6_RESET] = { .reg = 0x68014, .bitmask = BIT(29) | 
> GENMASK(13, 12) },
> + [GCC_WCSSAON_RESET] = { 0x59010, 0 },

Do you notice that you line is pretty significantly different from the
previous lines? The time has passed since Stephen has acked this line in
2019.

>  };
>  
>  static struct gdsc *gcc_ipq8074_gdscs[] = {
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry



Re: [PATCH v9 0/8] remoteproc: qcom: q6v5-wcss: Add support for secure pil

2024-06-21 Thread Dmitry Baryshkov
On Fri, Jun 21, 2024 at 05:16:51PM GMT, Gokul Sriram Palanisamy wrote:
> IPQ8074 needs support for secure pil as well.
> Also, currently only unified firmware is supported.
> IPQ8074 supports split firmware for q6 and m3, so
> adding support for that.
> 
> changes since v8:
>  - Rebased on top of Linux 6.10-rc4

Why do you have so many dead email addresses in you To/Cc lists?

> 
> Gokul Sriram Palanisamy (8):
>   remoteproc: qcom: Add PRNG proxy clock
>   remoteproc: qcom: Add secure PIL support
>   remoteproc: qcom: Add support for split q6 + m3 wlan firmware
>   remoteproc: qcom: Add ssr subdevice identifier
>   remoteproc: qcom: Update regmap offsets for halt register
>   dt-bindings: clock: qcom: Add reset for WCSSAON
>   clk: qcom: Add WCSSAON reset
>   arm64: dts: qcom: Enable Q6v5 WCSS for ipq8074 SoC
> 
>  arch/arm64/boot/dts/qcom/ipq8074.dtsi|  80 +
>  drivers/clk/qcom/gcc-ipq8074.c   |   1 +
>  drivers/remoteproc/qcom_q6v5_wcss.c  | 162 +++
>  include/dt-bindings/clock/qcom,gcc-ipq8074.h |   1 +
>  4 files changed, 212 insertions(+), 32 deletions(-)
> 
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry



Re: [PATCH v9 4/8] remoteproc: qcom: Add ssr subdevice identifier

2024-06-21 Thread Dmitry Baryshkov
On Fri, Jun 21, 2024 at 05:16:55PM GMT, Gokul Sriram Palanisamy wrote:
> Add name for ssr subdevice on IPQ8074 SoC.

Is it SSR or ssr? Why is it necessary?

> 
> Signed-off-by: Nikhil Prakash V 
> Signed-off-by: Sricharan R 
> Signed-off-by: Gokul Sriram Palanisamy 

Three authors for a single-line patch?

> ---
>  drivers/remoteproc/qcom_q6v5_wcss.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c 
> b/drivers/remoteproc/qcom_q6v5_wcss.c
> index d8b79765d5c6..06936ca1d079 100644
> --- a/drivers/remoteproc/qcom_q6v5_wcss.c
> +++ b/drivers/remoteproc/qcom_q6v5_wcss.c
> @@ -1170,6 +1170,7 @@ static const struct wcss_data wcss_ipq8074_res_init = {
>   .crash_reason_smem = WCSS_CRASH_REASON,
>   .aon_reset_required = true,
>   .wcss_q6_reset_required = true,
> + .ssr_name = "q6wcss",
>   .ops = &q6v5_wcss_ipq8074_ops,
>   .requires_force_stop = true,
>   .need_mem_protection = true,
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry



Re: [PATCH v9 0/8] remoteproc: qcom: q6v5-wcss: Add support for secure pil

2024-06-21 Thread Dmitry Baryshkov
On Fri, Jun 21, 2024 at 05:16:51PM GMT, Gokul Sriram Palanisamy wrote:
> IPQ8074 needs support for secure pil as well.

Could you please settle on 'pil' or 'PIL'. Just use one of them.
Explain, what is secure PIL.

> Also, currently only unified firmware is supported.

What is unified firmware? What is split firmware? Why do I have so many
questions after reading the cover letter for what claims to be v9?

> IPQ8074 supports split firmware for q6 and m3, so
> adding support for that.

Ok. After reading through the first few patches. Is WCSS support on
IPQ8074 broken?

> 
> changes since v8:
>  - Rebased on top of Linux 6.10-rc4

Previous changelog has wanished?

> 
> Gokul Sriram Palanisamy (8):
>   remoteproc: qcom: Add PRNG proxy clock
>   remoteproc: qcom: Add secure PIL support
>   remoteproc: qcom: Add support for split q6 + m3 wlan firmware
>   remoteproc: qcom: Add ssr subdevice identifier
>   remoteproc: qcom: Update regmap offsets for halt register
>   dt-bindings: clock: qcom: Add reset for WCSSAON
>   clk: qcom: Add WCSSAON reset
>   arm64: dts: qcom: Enable Q6v5 WCSS for ipq8074 SoC
> 
>  arch/arm64/boot/dts/qcom/ipq8074.dtsi|  80 +
>  drivers/clk/qcom/gcc-ipq8074.c   |   1 +
>  drivers/remoteproc/qcom_q6v5_wcss.c  | 162 +++
>  include/dt-bindings/clock/qcom,gcc-ipq8074.h |   1 +
>  4 files changed, 212 insertions(+), 32 deletions(-)
> 
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry



Re: [PATCH v9 2/8] remoteproc: qcom: Add secure PIL support

2024-06-21 Thread Dmitry Baryshkov
On Fri, Jun 21, 2024 at 05:16:53PM GMT, Gokul Sriram Palanisamy wrote:
> IPQ8074 uses secure PIL. Hence, adding the support for the same.

See Documentation/process/submitting-patches.rst

> 
> Signed-off-by: Nikhil Prakash V 
> Signed-off-by: Sricharan R 
> Signed-off-by: Gokul Sriram Palanisamy 
> ---
>  drivers/remoteproc/qcom_q6v5_wcss.c | 43 +++--
>  1 file changed, 40 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c 
> b/drivers/remoteproc/qcom_q6v5_wcss.c
> index 366b19cbd994..e45e79d80238 100644
> --- a/drivers/remoteproc/qcom_q6v5_wcss.c
> +++ b/drivers/remoteproc/qcom_q6v5_wcss.c
> @@ -18,6 +18,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include "qcom_common.h"
>  #include "qcom_pil_info.h"
>  #include "qcom_q6v5.h"
> @@ -86,6 +87,9 @@
>  #define TCSR_WCSS_CLK_ENABLE 0x14
>  
>  #define MAX_HALT_REG 3
> +
> +#define WCNSS_PAS_ID 6
> +
>  enum {
>   WCSS_IPQ8074,
>   WCSS_QCS404,
> @@ -134,6 +138,7 @@ struct q6v5_wcss {
>   unsigned int crash_reason_smem;
>   u32 version;
>   bool requires_force_stop;
> + bool need_mem_protection;

needs

>  
>   struct qcom_rproc_glink glink_subdev;
>   struct qcom_rproc_ssr ssr_subdev;
> @@ -152,6 +157,7 @@ struct wcss_data {
>   int ssctl_id;
>   const struct rproc_ops *ops;
>   bool requires_force_stop;
> + bool need_mem_protection;

needs

>  };
>  
>  static int q6v5_wcss_reset(struct q6v5_wcss *wcss)
> @@ -251,6 +257,15 @@ static int q6v5_wcss_start(struct rproc *rproc)
>  
>   qcom_q6v5_prepare(&wcss->q6v5);
>  
> + if (wcss->need_mem_protection) {
> + ret = qcom_scm_pas_auth_and_reset(WCNSS_PAS_ID);
> + if (ret) {
> + dev_err(wcss->dev, "wcss_reset failed\n");
> + return ret;
> + }
> + goto wait_for_reset;
> + }

Use if/else instead of a goto.

> +
>   /* Release Q6 and WCSS reset */
>   ret = reset_control_deassert(wcss->wcss_reset);
>   if (ret) {
> @@ -285,6 +300,7 @@ static int q6v5_wcss_start(struct rproc *rproc)
>   if (ret)
>   goto wcss_q6_reset;
>  
> +wait_for_reset:

This is more like wait_for_start

>   ret = qcom_q6v5_wait_for_start(&wcss->q6v5, 5 * HZ);
>   if (ret == -ETIMEDOUT)
>   dev_err(wcss->dev, "start timed out\n");
> @@ -718,6 +734,15 @@ static int q6v5_wcss_stop(struct rproc *rproc)
>   struct q6v5_wcss *wcss = rproc->priv;
>   int ret;
>  
> + if (wcss->need_mem_protection) {
> + ret = qcom_scm_pas_shutdown(WCNSS_PAS_ID);
> + if (ret) {
> + dev_err(wcss->dev, "not able to shutdown\n");
> + return ret;
> + }
> + goto pas_done;
> + }

if/else. Or abstract this to functions.

> +
>   /* WCSS powerdown */
>   if (wcss->requires_force_stop) {
>   ret = qcom_q6v5_request_stop(&wcss->q6v5, NULL);
> @@ -742,6 +767,7 @@ static int q6v5_wcss_stop(struct rproc *rproc)
>   return ret;
>   }
>  
> +pas_done:
>   clk_disable_unprepare(wcss->prng_clk);
>   qcom_q6v5_unprepare(&wcss->q6v5);
>  
> @@ -765,9 +791,15 @@ static int q6v5_wcss_load(struct rproc *rproc, const 
> struct firmware *fw)
>   struct q6v5_wcss *wcss = rproc->priv;
>   int ret;
>  
> - ret = qcom_mdt_load_no_init(wcss->dev, fw, rproc->firmware,
> - 0, wcss->mem_region, wcss->mem_phys,
> - wcss->mem_size, &wcss->mem_reloc);
> + if (wcss->need_mem_protection)
> + ret = qcom_mdt_load(wcss->dev, fw, rproc->firmware,
> + WCNSS_PAS_ID, wcss->mem_region,
> + wcss->mem_phys, wcss->mem_size,
> + &wcss->mem_reloc);
> + else
> + ret = qcom_mdt_load_no_init(wcss->dev, fw, rproc->firmware,
> + 0, wcss->mem_region, wcss->mem_phys,
> + wcss->mem_size, &wcss->mem_reloc);
>   if (ret)
>   return ret;
>  
> @@ -1035,6 +1067,9 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
>   if (!desc)
>   return -EINVAL;
>  
> + if (desc->need_mem_protection && !qcom_scm_is_available())
> + return -EPROBE_DEFER;
> +
>   rproc = devm_rproc_alloc(&pdev->dev, pdev->name, desc->ops,
>desc->firmware_name, sizeof(*wcss));
>   if (!rproc) {
> @@ -1048,6 +1083,7 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
>  
>   wcss->version = desc->version;
>   wcss->requires_force_stop = desc->requires_force_stop;
> + wcss->need_mem_protection = desc->need_mem_protection;
>  
>   ret = q6v5_wcss_init_mmio(wcss, pdev);
>   if (ret)
> @@ -,6 +1147,7 @@ static const struct wcss_dat

Re: [PATCH v9 1/8] remoteproc: qcom: Add PRNG proxy clock

2024-06-21 Thread Dmitry Baryshkov
On Fri, Jun 21, 2024 at 05:16:52PM GMT, Gokul Sriram Palanisamy wrote:
> PRNG clock is needed by the secure PIL, support for the same
> is added in subsequent patches.

Which 'same'?
What is 'secure PIL'?

> 
> Signed-off-by: Nikhil Prakash V 
> Signed-off-by: Sricharan R 
> Signed-off-by: Gokul Sriram Palanisamy 
> ---
>  drivers/remoteproc/qcom_q6v5_wcss.c | 65 +
>  1 file changed, 47 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c 
> b/drivers/remoteproc/qcom_q6v5_wcss.c
> index 94f68c919ee6..366b19cbd994 100644
> --- a/drivers/remoteproc/qcom_q6v5_wcss.c
> +++ b/drivers/remoteproc/qcom_q6v5_wcss.c
> @@ -91,19 +91,6 @@ enum {
>   WCSS_QCS404,
>  };
>  
> -struct wcss_data {
> - const char *firmware_name;
> - unsigned int crash_reason_smem;
> - u32 version;
> - bool aon_reset_required;
> - bool wcss_q6_reset_required;
> - const char *ssr_name;
> - const char *sysmon_name;
> - int ssctl_id;
> - const struct rproc_ops *ops;
> - bool requires_force_stop;
> -};
> -
>  struct q6v5_wcss {
>   struct device *dev;
>  
> @@ -128,6 +115,7 @@ struct q6v5_wcss {
>   struct clk *qdsp6ss_xo_cbcr;
>   struct clk *qdsp6ss_core_gfmux;
>   struct clk *lcc_bcr_sleep;
> + struct clk *prng_clk;
>   struct regulator *cx_supply;
>   struct qcom_sysmon *sysmon;
>  
> @@ -151,6 +139,21 @@ struct q6v5_wcss {
>   struct qcom_rproc_ssr ssr_subdev;
>  };
>  
> +struct wcss_data {
> + int (*init_clock)(struct q6v5_wcss *wcss);
> + int (*init_regulator)(struct q6v5_wcss *wcss);
> + const char *firmware_name;
> + unsigned int crash_reason_smem;
> + u32 version;
> + bool aon_reset_required;
> + bool wcss_q6_reset_required;
> + const char *ssr_name;
> + const char *sysmon_name;
> + int ssctl_id;
> + const struct rproc_ops *ops;
> + bool requires_force_stop;
> +};

Move this back and use forward-declaration of struct q6v5_wcss.

> +
>  static int q6v5_wcss_reset(struct q6v5_wcss *wcss)
>  {
>   int ret;

-- 
With best wishes
Dmitry



Re: [PATCH 2/2] arm64: dts: qcom: qcm6490-fairphone-fp5: Configure PM8008 regulators

2024-06-21 Thread Dmitry Baryshkov
On Fri, Jun 21, 2024 at 10:42:31AM GMT, Luca Weiss wrote:
> PM8008 regulators are used for the cameras found on FP5. Configure the
> chip and its voltages.
> 
> Signed-off-by: Luca Weiss 
> ---
>  arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts | 105 
> -
>  1 file changed, 104 insertions(+), 1 deletion(-)
> 


Reviewed-by: Dmitry Baryshkov 

-- 
With best wishes
Dmitry



Re: [PATCH 1/2] arm64: dts: qcom: sm7225-fairphone-fp4: Configure PM8008 regulators

2024-06-21 Thread Dmitry Baryshkov
On Fri, Jun 21, 2024 at 10:42:30AM GMT, Luca Weiss wrote:
> PM8008 regulators are used for the cameras found on FP4. Configure the
> chip and its voltages.
> 
> Signed-off-by: Luca Weiss 
> ---
>  arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts | 109 
> +-
>  1 file changed, 108 insertions(+), 1 deletion(-)
> 

Reviewed-by: Dmitry Baryshkov 


-- 
With best wishes
Dmitry



Re: [PATCH 1/3] ARM: dts: qcom: Add Sony Xperia Z3 Compact smartphone

2024-06-21 Thread Dmitry Baryshkov
On Fri, Jun 21, 2024 at 11:14:46AM GMT, Valeriy Klimin wrote:
> Add the dts for the Z3 Compact. This is currently almost the same
> as the plain Z3 as they share almost the same hardware and
> nothing device-specific is currently supported.
> 
> Signed-off-by: Valeriy Klimin 
> ---
>  arch/arm/boot/dts/qcom/Makefile|  1 +
>  .../qcom-msm8974pro-sony-xperia-shinano-aries.dts  | 44 
> ++
>  2 files changed, 45 insertions(+)
> 

Reviewed-by: Dmitry Baryshkov 


-- 
With best wishes
Dmitry



Re: [PATCH 3/3] ARM: dts: qcom: msm8974-sony-shinano: increase load on l21 for sdhc2

2024-06-21 Thread Dmitry Baryshkov
On Fri, Jun 21, 2024 at 11:14:48AM GMT, Valeriy Klimin wrote:
> SD cards would exhibit errors similar to ones described in commit
> 27fe0fc05f35 ("ARM: dts: msm8974-FP2: Increase load on l20 for sdhci")
> 
> This patch applies the same change to the regulator for sdhc2.
> 
> Signed-off-by: Valeriy Klimin 
> ---
>  arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-common.dtsi | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git 
> a/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-common.dtsi 
> b/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-common.dtsi
> index e129bb1bd6ec..6af7c71c7158 100644
> --- a/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-common.dtsi
> +++ b/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-common.dtsi
> @@ -380,6 +380,8 @@ pm8941_l20: l20 {
>   pm8941_l21: l21 {
>   regulator-min-microvolt = <295>;
>   regulator-max-microvolt = <295>;
> + regulator-system-load = <50>;
> + regulator-allow-set-load;
>   regulator-boot-on;
>   };
>  

Just out of pure interest, how the value was choosen? Do you have any
reference to the vendor kernel or DT?

-- 
With best wishes
Dmitry



Re: [PATCH 0/4] MCE wrapper and support for new SMCA syndrome MSRs

2024-06-21 Thread Yazen Ghannam
On Fri, Jun 21, 2024 at 06:58:23PM +0200, Borislav Petkov wrote:
> On Thu, May 30, 2024 at 04:16:16PM -0500, Avadhut Naik wrote:
> >  arch/x86/include/asm/mce.h  |  20 ++-
> >  arch/x86/kernel/cpu/mce/apei.c  | 111 ++
> >  arch/x86/kernel/cpu/mce/core.c  | 191 ++--
> >  arch/x86/kernel/cpu/mce/dev-mcelog.c|   2 +-
> >  arch/x86/kernel/cpu/mce/genpool.c   |  20 +--
> >  arch/x86/kernel/cpu/mce/inject.c|   4 +-
> >  arch/x86/kernel/cpu/mce/internal.h  |   4 +-
> >  drivers/acpi/acpi_extlog.c  |   2 +-
> >  drivers/acpi/nfit/mce.c |   2 +-
> >  drivers/edac/i7core_edac.c  |   2 +-
> >  drivers/edac/igen6_edac.c   |   2 +-
> >  drivers/edac/mce_amd.c  |  27 +++-
> >  drivers/edac/pnd2_edac.c|   2 +-
> >  drivers/edac/sb_edac.c  |   2 +-
> >  drivers/edac/skx_common.c   |   2 +-
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c |   2 +-
> >  drivers/ras/amd/fmpm.c  |   2 +-
> >  drivers/ras/cec.c   |   2 +-
> >  include/trace/events/mce.h  |  51 ---
> >  19 files changed, 286 insertions(+), 164 deletions(-)
> 
> This doesn't apply anymore - please redo this ontop of the latest tip/master.
>

Avadhut,

You can drop the dependencies on other sets. We can sort out any
conflicts as needed.

Thanks,
Yazen



[RFC PATCH v1 1/2] virtio/vsock: rework deferred credit update logic

2024-06-21 Thread Arseniy Krasnov
Previous calculation of 'free_space' was wrong (but worked as expected
in most cases, see below), because it didn't account number of bytes in
rx queue. Let's rework 'free_space' calculation in the following way:
as this value is considered free space at rx side from tx point of view,
it must be equal to return value of 'virtio_transport_get_credit()' at
tx side. This function uses 'tx_cnt' counter and 'peer_fwd_cnt': first
is number of transmitted bytes (without wrap), second is last 'fwd_cnt'
value received from rx. So let's use same approach at rx side during
'free_space' calculation: add 'rx_cnt' counter which is number of
received bytes (also without wrap) and subtract 'last_fwd_cnt' from it.
Now we have:
1) 'rx_cnt' == 'tx_cnt' at both sides.
2) 'last_fwd_cnt' == 'peer_fwd_cnt' - because first is last 'fwd_cnt'
   sent to tx, while second is last 'fwd_cnt' received from rx.

Now 'free_space' is handled correctly and also we don't need
'low_rx_bytes' flag - this was more like a hack.

Previous calculation of 'free_space' worked (in 99% cases), because if
we take a look on behaviour of both expressions (new and previous):

'(rx_cnt - last_fwd_cnt)' and '(fwd_cnt - last_fwd_cnt)'

Both of them always grows up, with almost same "speed": only difference
is that 'rx_cnt' is incremented earlier during packet is received,
while 'fwd_cnt' in incremented when packet is read by user. So if 'rx_cnt'
grows "faster", then resulting 'free_space' become smaller also, so we
send credit updates a little bit more, but:

  * 'free_space' calculation based on 'rx_cnt' gives the same value,
which tx sees as free space at rx side, so original idea of
'free_space' is now implemented as planned.
  * Hack with 'low_rx_bytes' now is not needed.

Also here is some performance comparison between both versions of
'free_space' calculation:

 *--*--*--*
 |  | 'rx_cnt' | previous |
 *--*--*--*
 |H -> G|   8.42   |   7.82   |
 *--*--*--*
 |G -> H|   11.6   |   12.1   |
 *--*--*--*

As benchmark 'vsock-iperf' with default arguments was used. There is no
significant performance difference before and after this patch.

Signed-off-by: Arseniy Krasnov 
---
 include/linux/virtio_vsock.h| 1 +
 net/vmw_vsock/virtio_transport_common.c | 8 +++-
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
index c82089dee0c8..3579491c411e 100644
--- a/include/linux/virtio_vsock.h
+++ b/include/linux/virtio_vsock.h
@@ -135,6 +135,7 @@ struct virtio_vsock_sock {
u32 peer_buf_alloc;
 
/* Protected by rx_lock */
+   u32 rx_cnt;
u32 fwd_cnt;
u32 last_fwd_cnt;
u32 rx_bytes;
diff --git a/net/vmw_vsock/virtio_transport_common.c 
b/net/vmw_vsock/virtio_transport_common.c
index 16ff976a86e3..1d4e2328e06e 100644
--- a/net/vmw_vsock/virtio_transport_common.c
+++ b/net/vmw_vsock/virtio_transport_common.c
@@ -441,6 +441,7 @@ static bool virtio_transport_inc_rx_pkt(struct 
virtio_vsock_sock *vvs,
return false;
 
vvs->rx_bytes += len;
+   vvs->rx_cnt += len;
return true;
 }
 
@@ -558,7 +559,6 @@ virtio_transport_stream_do_dequeue(struct vsock_sock *vsk,
size_t bytes, total = 0;
struct sk_buff *skb;
u32 fwd_cnt_delta;
-   bool low_rx_bytes;
int err = -EFAULT;
u32 free_space;
 
@@ -603,9 +603,7 @@ virtio_transport_stream_do_dequeue(struct vsock_sock *vsk,
}
 
fwd_cnt_delta = vvs->fwd_cnt - vvs->last_fwd_cnt;
-   free_space = vvs->buf_alloc - fwd_cnt_delta;
-   low_rx_bytes = (vvs->rx_bytes <
-   sock_rcvlowat(sk_vsock(vsk), 0, INT_MAX));
+   free_space = vvs->buf_alloc - (vvs->rx_cnt - vvs->last_fwd_cnt);
 
spin_unlock_bh(&vvs->rx_lock);
 
@@ -619,7 +617,7 @@ virtio_transport_stream_do_dequeue(struct vsock_sock *vsk,
 * number of bytes in rx queue is not enough to wake up reader.
 */
if (fwd_cnt_delta &&
-   (free_space < VIRTIO_VSOCK_MAX_PKT_BUF_SIZE || low_rx_bytes))
+   (free_space < VIRTIO_VSOCK_MAX_PKT_BUF_SIZE))
virtio_transport_send_credit_update(vsk);
 
return total;
-- 
2.25.1




[RFC PATCH v1 2/2] vsock/test: add test for deferred credit update

2024-06-21 Thread Arseniy Krasnov
This test checks, that we send exactly expected number of credit
update packets during deferred credit update optimization. Test
work in client/server modes:
1) Client just connects to server and send 256Kb of data. 256Kb
   is chosen because it is default space for vsock peer. After
   transmission client waits until server performs checks of this
   test.

2) Server waits for vsock connection and also open raw socket
   binded to vsock monitor interface. Then server waits until
   there will be 256Kb of data in its rx queue (by reading data
   from stream socket with MSG_PEEK flag). Then server starts
   reading data from stream socket - it reads entire socket,
   also reading packets from raw vsock socket, to check that
   there is OP_RW packets. After data read is done, it checks
   raw socket again, by waiting exact amount of CREDIT_UPDATE
   packets. Finally it checks that rx queue of raw socket is
   empty using read with timeout.

Some notes about this test:
* It is only for virtio transport.
* It relies on sizes of virtio rx buffers for guest and host,
  to handle raw packets properly (4Kb for guest and 64Kb for
  host).
* It relies on free space limit for deferred credit update -
  currently it is 64Kb.
* It needs permissions to open raw sockets.

Signed-off-by: Arseniy Krasnov 
---
 tools/testing/vsock/.gitignore  |   1 +
 tools/testing/vsock/Makefile|   2 +
 tools/testing/vsock/virtio_vsock_test.c | 369 
 3 files changed, 372 insertions(+)
 create mode 100644 tools/testing/vsock/virtio_vsock_test.c

diff --git a/tools/testing/vsock/.gitignore b/tools/testing/vsock/.gitignore
index d9f798713cd7..74d13a38cf43 100644
--- a/tools/testing/vsock/.gitignore
+++ b/tools/testing/vsock/.gitignore
@@ -4,3 +4,4 @@ vsock_test
 vsock_diag_test
 vsock_perf
 vsock_uring_test
+virtio_vsock_test
diff --git a/tools/testing/vsock/Makefile b/tools/testing/vsock/Makefile
index a7f56a09ca9f..e04d69903687 100644
--- a/tools/testing/vsock/Makefile
+++ b/tools/testing/vsock/Makefile
@@ -8,6 +8,8 @@ vsock_perf: vsock_perf.o msg_zerocopy_common.o
 vsock_uring_test: LDLIBS = -luring
 vsock_uring_test: control.o util.o vsock_uring_test.o timeout.o 
msg_zerocopy_common.o
 
+virtio_vsock_test: virtio_vsock_test.o util.o timeout.o control.o
+
 CFLAGS += -g -O2 -Werror -Wall -I. -I../../include -I../../../usr/include 
-Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD 
-U_FORTIFY_SOURCE -D_GNU_SOURCE
 .PHONY: all test clean
 clean:
diff --git a/tools/testing/vsock/virtio_vsock_test.c 
b/tools/testing/vsock/virtio_vsock_test.c
new file mode 100644
index ..4320dbc31ecc
--- /dev/null
+++ b/tools/testing/vsock/virtio_vsock_test.c
@@ -0,0 +1,369 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * virtio_vsock_test - vsock.ko test suite for VirtIO transport.
+ *
+ * Copyright (C) 2024 SaluteDevices.
+ *
+ * Author: Arseniy Krasnov 
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "control.h"
+#include "util.h"
+
+#define RAW_SOCK_RCV_BUF   (1024 * 1024)
+
+#define TOTAL_TX_BYTES (1024 * 256)
+
+#define VIRTIO_VSOCK_MAX_PKT_BUF_SIZE  (1024 * 64)
+
+#define VIRTIO_VSOCK_GUEST_RX_BUF_SIZE (4096)
+#define VIRTIO_VSOCK_HOST_RX_BUF_SIZE  (1024 * 64)
+
+static const char *interface;
+
+static void test_stream_deferred_credit_update_client(const struct test_opts 
*opts)
+{
+   unsigned char buf[VIRTIO_VSOCK_MAX_PKT_BUF_SIZE];
+   int fd;
+   int i;
+
+   fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
+   if (fd < 0) {
+   perror("connect");
+   exit(EXIT_FAILURE);
+   }
+
+   control_expectln("SERVERREADY");
+   memset(buf, 0, sizeof(buf));
+
+   for (i = 0; i < TOTAL_TX_BYTES / VIRTIO_VSOCK_MAX_PKT_BUF_SIZE; i++) {
+   if (write(fd, buf, sizeof(buf)) != sizeof(buf)) {
+   perror("write");
+   exit(EXIT_FAILURE);
+   }
+   }
+
+   control_writeln("CLIENTDONE");
+   control_expectln("SERVERDONE");
+
+   close(fd);
+}
+
+static int create_raw_sock(const char *ifname)
+{
+   struct sockaddr_ll addr_ll;
+   struct ifreq ifr;
+   size_t rcv_buf;
+   int fd;
+
+   fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+   if (fd < 0) {
+   perror("socket");
+   exit(EXIT_FAILURE);
+   }
+
+   memset(&ifr, 0, sizeof(ifr));
+   snprintf(ifr.ifr_name, sizeof(ifr.ifr_name),
+"%s", ifname);
+
+   rcv_buf = RAW_SOCK_RCV_BUF;
+   if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &rcv_buf,
+   sizeof(rcv_buf))) {
+   perror("setsockopt(SO_RCVBUFFORCE)");
+   exit(EXIT_FAILURE);
+   }
+
+   if (ioctl(fd,

[RFC PATCH v1 0/2] virtio/vsock: some updates for deferred credit update

2024-06-21 Thread Arseniy Krasnov
This patchset contains:
0001 - patch which reworks deferred credit update. Pls see commit message,
   it contains full description of this problem.

0002 - test which uses vsockmon interface, and checks that deferred
   credit update works as expected by parsing raw packets.

Arseniy Krasnov (2):
  virtio/vsock: rework deferred credit update logic
  vsock/test: add test for deferred credit update

 include/linux/virtio_vsock.h|   1 +
 net/vmw_vsock/virtio_transport_common.c |   8 +-
 tools/testing/vsock/.gitignore  |   1 +
 tools/testing/vsock/Makefile|   2 +
 tools/testing/vsock/virtio_vsock_test.c | 369 
 5 files changed, 376 insertions(+), 5 deletions(-)
 create mode 100644 tools/testing/vsock/virtio_vsock_test.c

-- 
2.25.1




Re: [PATCH v7 00/38] kmsan: Enable on s390

2024-06-21 Thread Andrew Morton
On Fri, 21 Jun 2024 13:34:44 +0200 Ilya Leoshkevich  wrote:

> v6 -> v7: Drop the ptdump patch.
>   All patches are reviewed.

I added v7 to mm.git (and hence linux-next).



Re: [PATCH 0/4] MCE wrapper and support for new SMCA syndrome MSRs

2024-06-21 Thread Borislav Petkov
On Thu, May 30, 2024 at 04:16:16PM -0500, Avadhut Naik wrote:
>  arch/x86/include/asm/mce.h  |  20 ++-
>  arch/x86/kernel/cpu/mce/apei.c  | 111 ++
>  arch/x86/kernel/cpu/mce/core.c  | 191 ++--
>  arch/x86/kernel/cpu/mce/dev-mcelog.c|   2 +-
>  arch/x86/kernel/cpu/mce/genpool.c   |  20 +--
>  arch/x86/kernel/cpu/mce/inject.c|   4 +-
>  arch/x86/kernel/cpu/mce/internal.h  |   4 +-
>  drivers/acpi/acpi_extlog.c  |   2 +-
>  drivers/acpi/nfit/mce.c |   2 +-
>  drivers/edac/i7core_edac.c  |   2 +-
>  drivers/edac/igen6_edac.c   |   2 +-
>  drivers/edac/mce_amd.c  |  27 +++-
>  drivers/edac/pnd2_edac.c|   2 +-
>  drivers/edac/sb_edac.c  |   2 +-
>  drivers/edac/skx_common.c   |   2 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c |   2 +-
>  drivers/ras/amd/fmpm.c  |   2 +-
>  drivers/ras/cec.c   |   2 +-
>  include/trace/events/mce.h  |  51 ---
>  19 files changed, 286 insertions(+), 164 deletions(-)

This doesn't apply anymore - please redo this ontop of the latest tip/master.

Thx.

-- 
Regards/Gruss,
Boris.

https://people.kernel.org/tglx/notes-about-netiquette



[PATCH net v2] net/sched: Fixes: 51270d573a8d NULL ptr deref in perf_trace_qdisc_reset()

2024-06-21 Thread yskelg
From: Yunseong Kim 

In the TRACE_EVENT(qdisc_reset) NULL dereference occurred from

 qdisc->dev_queue->dev  ->name

This situation simulated from bunch of veths and Bluetooth dis/reconnection.

During qdisc initialization, qdisc was being set to noop_queue.
In veth_init_queue, the initial tx_num was reduced back to one,
causing the qdisc reset to be called with noop, which led to the kernel panic.

I've attached the GitHub gist link that C converted syz-execprogram
source code and 3 log of reproduced vmcore-dmesg.

 https://gist.github.com/yskelg/cc64562873ce249cdd0d5a358b77d740

Yeoreum and I use two fuzzing tool simultaneously.

One process with syz-executor : https://github.com/google/syzkaller

 $ ./syz-execprog -executor=./syz-executor -repeat=1 -sandbox=setuid \
-enable=none -collide=false log1

The other process with perf fuzzer:
 https://github.com/deater/perf_event_tests/tree/master/fuzzer

 $ perf_event_tests/fuzzer/perf_fuzzer

I think this will happen on the kernel version.

 Linux kernel version ≥ v6.7.10, ≥ v6.8 ≥ v6.9 and 6.10

This occurred from 51270d573a8d. I think this patch is absolutely 
necessary. Previously, It was showing not intended string value of name.

I've reproduced 3 time from my fedora 40 Debug Kernel with any other module 
or patched.

 version: 6.10.0-0.rc2.20240608gitdc772f8237f9.29.fc41.aarch64+debug

[ 5287.164555] veth0_vlan: left promiscuous mode
[ 5287.164929] veth1_macvtap: left promiscuous mode
[ 5287.164950] veth0_macvtap: left promiscuous mode
[ 5287.164983] veth1_vlan: left promiscuous mode
[ 5287.165008] veth0_vlan: left promiscuous mode
[ 5287.165450] veth1_macvtap: left promiscuous mode
[ 5287.165472] veth0_macvtap: left promiscuous mode
[ 5287.165502] veth1_vlan: left promiscuous mode
…
[ 5297.598240] bridge0: port 2(bridge_slave_1) entered blocking state
[ 5297.598262] bridge0: port 2(bridge_slave_1) entered forwarding state
[ 5297.598296] bridge0: port 1(bridge_slave_0) entered blocking state
[ 5297.598313] bridge0: port 1(bridge_slave_0) entered forwarding state
[ 5297.616090] 8021q: adding VLAN 0 to HW filter on device bond0
[ 5297.620405] bridge0: port 1(bridge_slave_0) entered disabled state
[ 5297.620730] bridge0: port 2(bridge_slave_1) entered disabled state
[ 5297.627247] 8021q: adding VLAN 0 to HW filter on device team0
[ 5297.629636] bridge0: port 1(bridge_slave_0) entered blocking state
…
[ 5298.002798] bridge_slave_0: left promiscuous mode
[ 5298.002869] bridge0: port 1(bridge_slave_0) entered disabled state
[ 5298.309444] bond0 (unregistering): (slave bond_slave_0): Releasing backup 
interface
[ 5298.315206] bond0 (unregistering): (slave bond_slave_1): Releasing backup 
interface
[ 5298.320207] bond0 (unregistering): Released all slaves
[ 5298.354296] hsr_slave_0: left promiscuous mode
[ 5298.360750] hsr_slave_1: left promiscuous mode
[ 5298.374889] veth1_macvtap: left promiscuous mode
[ 5298.374931] veth0_macvtap: left promiscuous mode
[ 5298.374988] veth1_vlan: left promiscuous mode
[ 5298.375024] veth0_vlan: left promiscuous mode
[ 5299.109741] team0 (unregistering): Port device team_slave_1 removed
[ 5299.185870] team0 (unregistering): Port device team_slave_0 removed
…
[ 5300.155443] Bluetooth: hci3: unexpected cc 0x0c03 length: 249 > 1
[ 5300.155724] Bluetooth: hci3: unexpected cc 0x1003 length: 249 > 9
[ 5300.155988] Bluetooth: hci3: unexpected cc 0x1001 length: 249 > 9
….
[ 5301.075531] team0: Port device team_slave_1 added
[ 5301.085515] bridge0: port 1(bridge_slave_0) entered blocking state
[ 5301.085531] bridge0: port 1(bridge_slave_0) entered disabled state
[ 5301.085588] bridge_slave_0: entered allmulticast mode
[ 5301.085800] bridge_slave_0: entered promiscuous mode
[ 5301.095617] bridge0: port 1(bridge_slave_0) entered blocking state
[ 5301.095633] bridge0: port 1(bridge_slave_0) entered disabled state
…
[ 5301.149734] bond0: (slave bond_slave_0): Enslaving as an active interface 
with an up link
[ 5301.173234] bond0: (slave bond_slave_0): Enslaving as an active interface 
with an up link
[ 5301.180517] bond0: (slave bond_slave_1): Enslaving as an active interface 
with an up link
[ 5301.193481] hsr_slave_0: entered promiscuous mode
[ 5301.204425] hsr_slave_1: entered promiscuous mode
[ 5301.210172] debugfs: Directory 'hsr0' with parent 'hsr' already present!
[ 5301.210185] Cannot create hsr debugfs directory
[ 5301.224061] bond0: (slave bond_slave_1): Enslaving as an active interface 
with an up link
[ 5301.246901] bond0: (slave bond_slave_0): Enslaving as an active interface 
with an up link
[ 5301.255934] team0: Port device team_slave_0 added
[ 5301.256480] team0: Port device team_slave_1 added
[ 5301.256948] team0: Port device team_slave_0 added
…
[ 5301.435928] hsr_slave_0: entered promiscuous mode
[ 5301.446029] hsr_slave_1: entered promiscuous mode
[ 5301.455872] debugfs: Directory 'hsr0' with parent 'hsr' already present!
[ 5301.455884] Cannot create hsr debugfs directory
[ 5301.502664] hsr_slave_0: entered promiscu

Re: [PATCH v9 6/8] dt-bindings: clock: qcom: Add reset for WCSSAON

2024-06-21 Thread Kathiravan Thirumoorthy




On 6/21/2024 5:16 PM, Gokul Sriram Palanisamy wrote:

Add binding for WCSSAON reset required for Q6v5 reset on IPQ8074 SoC.


Can we include ipq8074 in the title? "dt-bindings: clock: qcom: ipq8074: 
Add reset for WCSSAON"





Signed-off-by: Nikhil Prakash V 
Signed-off-by: Sricharan R 
Signed-off-by: Gokul Sriram Palanisamy 
Acked-by: Rob Herring 
Acked-by: Stephen Boyd 
---
  include/dt-bindings/clock/qcom,gcc-ipq8074.h | 1 +
  1 file changed, 1 insertion(+)

diff --git a/include/dt-bindings/clock/qcom,gcc-ipq8074.h 
b/include/dt-bindings/clock/qcom,gcc-ipq8074.h
index f9ea55811104..e47cbf7394aa 100644
--- a/include/dt-bindings/clock/qcom,gcc-ipq8074.h
+++ b/include/dt-bindings/clock/qcom,gcc-ipq8074.h
@@ -381,6 +381,7 @@
  #define GCC_NSSPORT4_RESET143
  #define GCC_NSSPORT5_RESET144
  #define GCC_NSSPORT6_RESET145
+#define GCC_WCSSAON_RESET  146
  
  #define USB0_GDSC0

  #define USB1_GDSC 1




Re: [PATCH v9 7/8] clk: qcom: Add WCSSAON reset

2024-06-21 Thread Kathiravan Thirumoorthy




On 6/21/2024 5:16 PM, Gokul Sriram Palanisamy wrote:

Add WCSSAON reset required for Q6v5 on IPQ8074 SoC.


Commit title can be written as "clk: qcom: ipq8074: Add WCSSAON reset" ?

With that,

Reviewed-by: Kathiravan Thirumoorthy 



Signed-off-by: Nikhil Prakash V 
Signed-off-by: Sricharan R 
Signed-off-by: Gokul Sriram Palanisamy 
Acked-by: Stephen Boyd 
---
  drivers/clk/qcom/gcc-ipq8074.c | 1 +
  1 file changed, 1 insertion(+)

diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
index 32fd01ef469a..d382d16b9c10 100644
--- a/drivers/clk/qcom/gcc-ipq8074.c
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -4712,6 +4712,7 @@ static const struct qcom_reset_map gcc_ipq8074_resets[] = 
{
[GCC_NSSPORT4_RESET] = { .reg = 0x68014, .bitmask = BIT(27) | 
GENMASK(9, 8) },
[GCC_NSSPORT5_RESET] = { .reg = 0x68014, .bitmask = BIT(28) | 
GENMASK(11, 10) },
[GCC_NSSPORT6_RESET] = { .reg = 0x68014, .bitmask = BIT(29) | 
GENMASK(13, 12) },
+   [GCC_WCSSAON_RESET] = { 0x59010, 0 },
  };
  
  static struct gdsc *gcc_ipq8074_gdscs[] = {




Re: [PATCH v9 8/8] arm64: dts: qcom: Enable Q6v5 WCSS for ipq8074 SoC

2024-06-21 Thread Kathiravan Thirumoorthy




On 6/21/2024 5:16 PM, Gokul Sriram Palanisamy wrote:

Enable remoteproc WCSS PIL driver with glink. Also,
configure shared memory and enables smp2p required for IPC.

Signed-off-by: Nikhil Prakash V 
Signed-off-by: Sricharan R 
Signed-off-by: Gokul Sriram Palanisamy 
---
  arch/arm64/boot/dts/qcom/ipq8074.dtsi | 80 +++
  1 file changed, 80 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi 
b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
index 92682d3c9478..b98766cce0d6 100644
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -108,6 +108,12 @@ memory@4ac0 {
reg = <0x0 0x4ac0 0x0 0x40>;
no-map;
};
+
+   q6_region: memory@4b00 {
+   no-map;


move the no-map after reg, to align with other entries.


+   reg = <0x0 0x4b00 0x0 0x5f0>;
+   };
+
};
  
  	firmware {

@@ -117,6 +123,30 @@ scm {
};
};
  


...

  
+		q6v5_wcss: remoteproc@cd0 {

+   compatible = "qcom,ipq8074-wcss-pil";
+   reg = <0x0cd0 0x4040>,
+ <0x004ab000 0x20>;
+   reg-names = "qdsp6",
+   "rmb";
+   qca,auto-restart;
+   qca,extended-intc;
+   interrupts-extended = <&intc 0 325 1>,



Use macros instead of open coding.


+ <&wcss_smp2p_in 0 0>,
+ <&wcss_smp2p_in 1 0>,
+ <&wcss_smp2p_in 2 0>,
+ <&wcss_smp2p_in 3 0>;
+   interrupt-names = "wdog",
+ "fatal",
+ "ready",
+ "handover",
+ "stop-ack";
+
+   resets = <&gcc GCC_WCSSAON_RESET>,
+<&gcc GCC_WCSS_BCR>,
+<&gcc GCC_WCSS_Q6_BCR>;
+
+   reset-names = "wcss_aon_reset",
+ "wcss_reset",
+ "wcss_q6_reset";
+
+   clocks = <&gcc GCC_PRNG_AHB_CLK>;
+   clock-names = "prng";
+
+   qcom,halt-regs = <&tcsr 0xa000 0xd000 0xe000>;
+
+   qcom,smem-states = <&wcss_smp2p_out 0>,
+  <&wcss_smp2p_out 1>;
+   qcom,smem-state-names = "shutdown",
+   "stop";
+
+   memory-region = <&q6_region>;
+
+   glink-edge {
+   interrupts = ;
+   qcom,remote-pid = <1>;
+   mboxes = <&apcs_glb 8>;
+
+   rpm_requests {
+   qcom,glink-channels = "rpm_requests";
+   };
+   };
+   };
+
pcie1: pcie@1000 {
compatible = "qcom,pcie-ipq8074";
reg = <0x1000 0xf1d>,




Re: [PATCH v9 4/8] remoteproc: qcom: Add ssr subdevice identifier

2024-06-21 Thread Krzysztof Kozlowski
On 21/06/2024 13:46, Gokul Sriram Palanisamy wrote:
> Add name for ssr subdevice on IPQ8074 SoC.

Why?

> 
> Signed-off-by: Nikhil Prakash V 
> Signed-off-by: Sricharan R 
> Signed-off-by: Gokul Sriram Palanisamy 

Three people developed that single line?

Something is really odd with your DCO chain.


Best regards,
Krzysztof




Re: [PATCH v9 8/8] arm64: dts: qcom: Enable Q6v5 WCSS for ipq8074 SoC

2024-06-21 Thread Krzysztof Kozlowski
On 21/06/2024 13:46, Gokul Sriram Palanisamy wrote:
> Enable remoteproc WCSS PIL driver with glink. Also,
> configure shared memory and enables smp2p required for IPC.
> 
> Signed-off-by: Nikhil Prakash V 
> Signed-off-by: Sricharan R 
> Signed-off-by: Gokul Sriram Palanisamy 
> ---
>  arch/arm64/boot/dts/qcom/ipq8074.dtsi | 80 +++
>  1 file changed, 80 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi 
> b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
> index 92682d3c9478..b98766cce0d6 100644
> --- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
> +++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
> @@ -108,6 +108,12 @@ memory@4ac0 {
>   reg = <0x0 0x4ac0 0x0 0x40>;
>   no-map;
>   };
> +
> + q6_region: memory@4b00 {
> + no-map;
> + reg = <0x0 0x4b00 0x0 0x5f0>;
> + };
> +
>   };
>  
>   firmware {
> @@ -117,6 +123,30 @@ scm {
>   };
>   };
>  
> + wcss: smp2p-wcss {
> + compatible = "qcom,smp2p";
> + qcom,smem = <435>, <428>;
> +
> + interrupt-parent = <&intc>;
> + interrupts = ;
> +
> + mboxes = <&apcs_glb 9>;
> +
> + qcom,local-pid = <0>;
> + qcom,remote-pid = <1>;
> +
> + wcss_smp2p_out: master-kernel {
> + qcom,entry-name = "master-kernel";
> + #qcom,smem-state-cells = <1>;
> + };
> +
> + wcss_smp2p_in: slave-kernel {
> + qcom,entry-name = "slave-kernel";
> + interrupt-controller;
> + #interrupt-cells = <2>;
> + };
> + };
> +
>   soc: soc@0 {
>   #address-cells = <1>;
>   #size-cells = <1>;
> @@ -824,6 +854,56 @@ frame@b128000 {
>   };
>   };
>  
> + q6v5_wcss: remoteproc@cd0 {
> + compatible = "qcom,ipq8074-wcss-pil";
> + reg = <0x0cd0 0x4040>,
> +   <0x004ab000 0x20>;
> + reg-names = "qdsp6",
> + "rmb";
> + qca,auto-restart;
> + qca,extended-intc;
> + interrupts-extended = <&intc 0 325 1>,
> +   <&wcss_smp2p_in 0 0>,
> +   <&wcss_smp2p_in 1 0>,
> +   <&wcss_smp2p_in 2 0>,
> +   <&wcss_smp2p_in 3 0>;
> + interrupt-names = "wdog",
> +   "fatal",
> +   "ready",
> +   "handover",
> +   "stop-ack";
> +
> + resets = <&gcc GCC_WCSSAON_RESET>,
> +  <&gcc GCC_WCSS_BCR>,
> +  <&gcc GCC_WCSS_Q6_BCR>;
> +
> + reset-names = "wcss_aon_reset",
> +   "wcss_reset",
> +   "wcss_q6_reset";
> +
> + clocks = <&gcc GCC_PRNG_AHB_CLK>;
> + clock-names = "prng";

That's not what your binding is saying. Convert the binding to DT schema
and then validate this DTS.


Best regards,
Krzysztof




Re: [PATCH v9 6/8] dt-bindings: clock: qcom: Add reset for WCSSAON

2024-06-21 Thread Krzysztof Kozlowski
On 21/06/2024 13:46, Gokul Sriram Palanisamy wrote:
> Add binding for WCSSAON reset required for Q6v5 reset on IPQ8074 SoC.
> 
> Signed-off-by: Nikhil Prakash V 
> Signed-off-by: Sricharan R 
> Signed-off-by: Gokul Sriram Palanisamy 

Again, three people contributed to this one define?

Best regards,
Krzysztof




Re: [PATCH v9 5/8] remoteproc: qcom: Update regmap offsets for halt register

2024-06-21 Thread Krzysztof Kozlowski
On 21/06/2024 13:46, Gokul Sriram Palanisamy wrote:
> Fixed issue in reading halt-regs parameter from device-tree.

What issue?

That's a terrible commit msg. Explain what is the problem, how can it be
reproduced.

> 
> Signed-off-by: Sricharan R 
> Signed-off-by: Gokul Sriram Palanisamy 
> ---
>  drivers/remoteproc/qcom_q6v5_wcss.c | 22 ++
>  1 file changed, 14 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c 
> b/drivers/remoteproc/qcom_q6v5_wcss.c
> index 06936ca1d079..87b78eb15b86 100644
> --- a/drivers/remoteproc/qcom_q6v5_wcss.c
> +++ b/drivers/remoteproc/qcom_q6v5_wcss.c
> @@ -86,7 +86,7 @@
>  #define TCSR_WCSS_CLK_MASK   0x1F
>  #define TCSR_WCSS_CLK_ENABLE 0x14
>  
> -#define MAX_HALT_REG 3
> +#define MAX_HALT_REG 4

? That's confusing and looks unrelated.


Best regards,
Krzysztof




[PATCH] ring-buffer: Limit time with disabled interrupts in rb_check_pages()

2024-06-21 Thread Petr Pavlu
Function rb_check_pages() validates the integrity of a specified per-CPU
tracing ring buffer. It does so by walking the underlying linked
list and checking its next and prev links.

To guarantee that the list doesn't get modified during the check,
a caller typically needs to take cpu_buffer->reader_lock. This prevents
the check from running concurrently with a potential reader which can
make the list temporarily inconsistent when swapping its old reader page
into the buffer.

A problem is that the time when interrupts are disabled is
non-deterministic, dependent on the ring buffer size. This particularly
affects PREEMPT_RT because the reader_lock is a raw spinlock which
doesn't become sleepable on PREEMPT_RT kernels.

Modify the check so it still tries to walk the whole list but gives up
the reader_lock between checking individual pages.

Signed-off-by: Petr Pavlu 
---

This is a follow-up to the discussion in
https://lore.kernel.org/linux-trace-kernel/20240517134008.24529-1-petr.pa...@suse.com/

 kernel/trace/ring_buffer.c | 96 +++---
 1 file changed, 70 insertions(+), 26 deletions(-)

diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 28853966aa9a..3aefaf8a4d58 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -1454,40 +1454,91 @@ static void rb_check_bpage(struct ring_buffer_per_cpu 
*cpu_buffer,
RB_WARN_ON(cpu_buffer, val & RB_FLAG_MASK);
 }
 
+static bool rb_check_links(struct ring_buffer_per_cpu *cpu_buffer,
+  struct list_head *list)
+{
+   if (RB_WARN_ON(cpu_buffer,
+  rb_list_head(rb_list_head(list->next)->prev) != list))
+   return false;
+
+   if (RB_WARN_ON(cpu_buffer,
+  rb_list_head(rb_list_head(list->prev)->next) != list))
+   return false;
+
+   return true;
+}
+
 /**
  * rb_check_pages - integrity check of buffer pages
  * @cpu_buffer: CPU buffer with pages to test
  *
  * As a safety measure we check to make sure the data pages have not
  * been corrupted.
- *
- * Callers of this function need to guarantee that the list of pages doesn't 
get
- * modified during the check. In particular, if it's possible that the function
- * is invoked with concurrent readers which can swap in a new reader page then
- * the caller should take cpu_buffer->reader_lock.
  */
 static void rb_check_pages(struct ring_buffer_per_cpu *cpu_buffer)
 {
-   struct list_head *head = rb_list_head(cpu_buffer->pages);
-   struct list_head *tmp;
+   struct list_head *head, *tmp;
+   unsigned long flags;
+   size_t pages_read;
+   int nr_loops = 0;
 
-   if (RB_WARN_ON(cpu_buffer,
-   rb_list_head(rb_list_head(head->next)->prev) != head))
+   /*
+* Walk the linked list underpinning the ring buffer and validate all
+* its next and prev links.
+*
+* The check acquires the reader_lock in order to avoid concurrent
+* processing with a potential reader which can make the list
+* temporarily inconsistent when swapping its old reader page into the
+* buffer and obtaining a new page. However, the lock cannot be held for
+* the whole duration of the walk, as this would make the time when
+* interrupts are disabled non-deterministic, dependent on the ring
+* buffer size. Therefore, the code releases and re-acquires the lock
+* after checking each page. The pages_read variable is then used to
+* detect if a reader changed the list while the lock was not held, in
+* which case the check needs to be restarted.
+*
+* The code attempts to perform the check at most three times before
+* giving up. That itself is ok because this is only a self-validation
+* to detect problems early on. In practice, if it even happens that
+* this code runs concurrently with a reader getting a new page from the
+* buffer, it should take the reader a bit to process the obtained page
+* before coming back for more data and so this check typically succeeds
+* at most on the second try.
+*/
+again:
+   if (++nr_loops > 3)
return;
 
-   if (RB_WARN_ON(cpu_buffer,
-   rb_list_head(rb_list_head(head->prev)->next) != head))
-   return;
+   raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
+   head = rb_list_head(cpu_buffer->pages);
+   if (!rb_check_links(cpu_buffer, head))
+   goto out_locked;
+   pages_read = local_read(&cpu_buffer->pages_read);
+   tmp = head;
+   raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
 
-   for (tmp = rb_list_head(head->next); tmp != head; tmp = 
rb_list_head(tmp->next)) {
-   if (RB_WARN_ON(cpu_buffer,
-   rb_list_head(rb_list_head(tmp->next)->prev) != 
tmp))
-

Re: [PATCH v9 1/8] remoteproc: qcom: Add PRNG proxy clock

2024-06-21 Thread Krzysztof Kozlowski
On 21/06/2024 13:46, Gokul Sriram Palanisamy wrote:
>  
> -static int q6v5_wcss_init_clock(struct q6v5_wcss *wcss)
> +static int ipq8074_init_clock(struct q6v5_wcss *wcss)
> +{
> + int ret;
> +
> + wcss->prng_clk = devm_clk_get(wcss->dev, "prng");

Missing binding.

Best regards,
Krzysztof




Re: [PATCH] qdisc: fix NULL pointer dereference in perf_trace_qdisc_reset()

2024-06-21 Thread Yunseong Kim
Hi Pedro,

On 6/21/24 11:24 오후, Pedro Tammela wrote:
> On 21/06/2024 08:45, ysk...@gmail.com wrote:
>> From: Yunseong Kim 
>>
>> In the TRACE_EVENT(qdisc_reset) NULL dereference occurred from
>>
>>   qdisc->dev_queue->dev  ->name
>>
>> This situation simulated from bunch of veths and Bluetooth
>> dis/reconnection.
>>
>> During qdisc initialization, qdisc was being set to noop_queue.
>> In veth_init_queue, the initial tx_num was reduced back to one,
>> causing the qdisc reset to be called with noop, which led to the
>> kernel panic.
>>
>> I think this will happen on the kernel version.
>>   Linux kernel version ≥ v6.7.10, ≥ v6.8 ≥ v6.9 and 6.10
> 
> You should tag your patch for the net tree
Thank you for the code review, I will tag the next patch for the net tree.

>> This occurred from 51270d573a8d. I think this patch is absolutely
>> necessary. Previously, It was showing not intended string value of name.
> Add a 'Fixes:' tag with this commit

I will added 'Fixes: 51270d573a8d' Tag on patch v2 message.

>> I can attach a sys-execprog's executing program, kernel dump and dmesg
>> if someone need it, but I'm not sure how to safely attach large vmcore
>> with vmlinux.
> 
> The syzkaller program + C reproducer is usually enough, please make it
> visible somewhere

I got it, I have a converted C syz program. So, I've attached the GitHub
gist link and C source code in this mail.

 https://gist.github.com/yskelg/cc64562873ce249cdd0d5a358b77d740

>> Signed-off-by: Yunseong Kim , Yeoreum Yun
>> 
> 
> Should be two SoB tags

Oh, It's the first time we've sent together, I made a mistake.. Sorry.
Thank you Pedro for the advice!

>> ---
>>   include/trace/events/qdisc.h | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/include/trace/events/qdisc.h b/include/trace/events/qdisc.h
>> index f1b5e816e7e5..170b51fbe47a 100644
>> --- a/include/trace/events/qdisc.h
>> +++ b/include/trace/events/qdisc.h
>> @@ -81,7 +81,7 @@ TRACE_EVENT(qdisc_reset,
>>   TP_ARGS(q),
>>     TP_STRUCT__entry(
>> -    __string(    dev,    qdisc_dev(q)->name    )
>> +    __string(dev, qdisc_dev(q) ? qdisc_dev(q)->name : "noop_queue")
>>   __string(    kind,    q->ops->id    )
>>   __field(    u32,    parent    )
>>   __field(    u32,    handle    )
> 


Warm Regards,
Yunseong Kim// autogenerated by syzkaller (https://github.com/google/syzkaller)

#define _GNU_SOURCE

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#ifndef __NR_add_key
#define __NR_add_key 217
#endif
#ifndef __NR_bpf
#define __NR_bpf 280
#endif
#ifndef __NR_io_uring_register
#define __NR_io_uring_register 427
#endif
#ifndef __NR_io_uring_setup
#define __NR_io_uring_setup 425
#endif
#ifndef __NR_keyctl
#define __NR_keyctl 219
#endif
#ifndef __NR_mlockall
#define __NR_mlockall 230
#endif
#ifndef __NR_mmap
#define __NR_mmap 222
#endif
#ifndef __NR_mremap
#define __NR_mremap 216
#endif
#ifndef __NR_munmap
#define __NR_munmap 215
#endif
#ifndef __NR_openat
#define __NR_openat 56
#endif
#ifndef __NR_read
#define __NR_read 63
#endif
#ifndef __NR_shmctl
#define __NR_shmctl 195
#endif

#define BITMASK(bf_off, bf_len) (((1ull << (bf_len)) - 1) << (bf_off))
#define STORE_BY_BITMASK(type, htobe, addr, val, bf_off, bf_len)   \
  *(type*)(addr) = \
  htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) |   \
(((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len

uint64_t r[7] = {0x,
 0x,
 0x,
 0x0,
 0x,
 0x,
 0x0};

int main(void)
{
  syscall(__NR_mmap, /*addr=*/0x1000ul, /*len=*/0x1000ul, /*prot=*/0ul,
  /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/-1,
  /*offset=*/0ul);
  syscall(__NR_mmap, /*addr=*/0x2000ul, /*len=*/0x100ul,
  /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul,
  /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/-1,
  /*offset=*/0ul);
  syscall(__NR_mmap, /*addr=*/0x2100ul, /*len=*/0x1000ul, /*prot=*/0ul,
  /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/-1,
  /*offset=*/0ul);
  const char* reason;
  (void)reason;
  intptr_t res = 0;
  if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {
  }
  *(uint32_t*)0x2004 = 0;
  *(uint32_t*)0x2008 = 0;
  *(uint32_t*)0x200c = 0;
  *(uint32_t*)0x2010 = 0;
  *(uint32_t*)0x2018 = -1;
  memset((void*)0x201c, 0, 12);
  res =
  syscall(__NR_io_uring_setup, /*entries=*/0xe68, /*params=*/0x2000ul);
  if (res != -1)
r[0] = res;
  memset((void*)0x2080, 111, 1);
  syscall(__NR_io_uring_register, /*fd=*/r[0], /*opcode=*/0xaul,
  /*arg=*/0x2080ul, /*size=*/1ul);

[PATCH 1/4] remoteproc: k3-r5: Fix IPC-only mode detection

2024-06-21 Thread Richard Genoud
ret variable was used to test reset status, get from
reset_control_status() call. But this variable was overwritten by
ti_sci_proc_get_status() a few lines bellow.
And as ti_sci_proc_get_status() returns 0 or a negative value (in this
latter case, followed by a return), the expression !ret was always true,

Clearly, this was not what was intended:
In the comment above it's said that "requires both local and module
resets to be deasserted"; if reset_control_status() returns 0 it means
that the reset line is deasserted.
So, it's pretty clear that the return value of reset_control_status()
was intended to be used instead of ti_sci_proc_get_status() return
value.

This could lead in an incorrect IPC-only mode detection if reset line is
asserted (so reset_control_status() return > 0) and c_state != 0 and
halted == 0.
In this case, the old code would have detected an IPC-only mode instead
of a mismatched mode.

Fixes: 1168af40b1ad ("remoteproc: k3-r5: Add support for IPC-only mode for all 
R5Fs")
Signed-off-by: Richard Genoud 
---
 drivers/remoteproc/ti_k3_r5_remoteproc.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c 
b/drivers/remoteproc/ti_k3_r5_remoteproc.c
index 50e486bcfa10..39a47540c590 100644
--- a/drivers/remoteproc/ti_k3_r5_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c
@@ -1144,6 +1144,7 @@ static int k3_r5_rproc_configure_mode(struct k3_r5_rproc 
*kproc)
u32 atcm_enable, btcm_enable, loczrama;
struct k3_r5_core *core0;
enum cluster_mode mode = cluster->mode;
+   int reset_ctrl_status;
int ret;
 
core0 = list_first_entry(&cluster->cores, struct k3_r5_core, elem);
@@ -1160,11 +1161,11 @@ static int k3_r5_rproc_configure_mode(struct 
k3_r5_rproc *kproc)
 r_state, c_state);
}
 
-   ret = reset_control_status(core->reset);
-   if (ret < 0) {
+   reset_ctrl_status = reset_control_status(core->reset);
+   if (reset_ctrl_status < 0) {
dev_err(cdev, "failed to get initial local reset status, ret = 
%d\n",
-   ret);
-   return ret;
+   reset_ctrl_status);
+   return reset_ctrl_status;
}
 
/*
@@ -1199,7 +1200,7 @@ static int k3_r5_rproc_configure_mode(struct k3_r5_rproc 
*kproc)
 * irrelevant if module reset is asserted (POR value has local reset
 * deasserted), and is deemed as remoteproc mode
 */
-   if (c_state && !ret && !halted) {
+   if (c_state && !reset_ctrl_status && !halted) {
dev_info(cdev, "configured R5F for IPC-only mode\n");
kproc->rproc->state = RPROC_DETACHED;
ret = 1;
@@ -1217,7 +1218,7 @@ static int k3_r5_rproc_configure_mode(struct k3_r5_rproc 
*kproc)
ret = 0;
} else {
dev_err(cdev, "mismatched mode: local_reset = %s, module_reset 
= %s, core_state = %s\n",
-   !ret ? "deasserted" : "asserted",
+   !reset_ctrl_status ? "deasserted" : "asserted",
c_state ? "deasserted" : "asserted",
halted ? "halted" : "unhalted");
ret = -EINVAL;



[PATCH 4/4] remoteproc: k3-r5: support for graceful stop of remote cores

2024-06-21 Thread Richard Genoud
Introduce software IPC handshake between the K3-R5 remote proc driver
and the R5 MCU to gracefully stop/reset the remote core.

Upon a stop request, K3-R5 remote proc driver sends a RP_MBOX_SHUTDOWN
mailbox message to the remote R5 core.
The remote core is expected to:
- relinquish all the resources acquired through Device Manager (DM)
- disable its interrupts
- send back a mailbox acknowledgment RP_MBOX_SHUDOWN_ACK
- enter WFI state.

Meanwhile, the K3-R5 remote proc driver does:
- wait for the RP_MBOX_SHUTDOWN_ACK from the remote core
- wait for the remote proc to enter WFI state
- reset the remote core through device manager

Based on work from: Hari Nagalla 

Signed-off-by: Richard Genoud 
---
 drivers/remoteproc/omap_remoteproc.h |  9 +-
 drivers/remoteproc/ti_k3_r5_remoteproc.c | 40 
 2 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/remoteproc/omap_remoteproc.h 
b/drivers/remoteproc/omap_remoteproc.h
index 828e13256c02..c008f11fa2a4 100644
--- a/drivers/remoteproc/omap_remoteproc.h
+++ b/drivers/remoteproc/omap_remoteproc.h
@@ -42,6 +42,11 @@
  * @RP_MBOX_SUSPEND_CANCEL: a cancel suspend response from a remote processor
  * on a suspend request
  *
+ * @RP_MBOX_SHUTDOWN: shutdown request for the remote processor
+ *
+ * @RP_MBOX_SHUTDOWN_ACK: successful response from remote processor for a
+ * shutdown request. The remote processor should be in WFI state short after.
+ *
  * Introduce new message definitions if any here.
  *
  * @RP_MBOX_END_MSG: Indicates end of known/defined messages from remote core
@@ -59,7 +64,9 @@ enum omap_rp_mbox_messages {
RP_MBOX_SUSPEND_SYSTEM  = 0xFF11,
RP_MBOX_SUSPEND_ACK = 0xFF12,
RP_MBOX_SUSPEND_CANCEL  = 0xFF13,
-   RP_MBOX_END_MSG = 0xFF14,
+   RP_MBOX_SHUTDOWN= 0xFF14,
+   RP_MBOX_SHUTDOWN_ACK= 0xFF15,
+   RP_MBOX_END_MSG = 0xFF16,
 };
 
 #endif /* _OMAP_RPMSG_H */
diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c 
b/drivers/remoteproc/ti_k3_r5_remoteproc.c
index a2ead87952c7..918a15e1dd9a 100644
--- a/drivers/remoteproc/ti_k3_r5_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -172,8 +173,23 @@ struct k3_r5_rproc {
struct k3_r5_core *core;
struct k3_r5_mem *rmem;
int num_rmems;
+   struct completion shutdown_complete;
 };
 
+/*
+ * This will return true if the remote core is in Wait For Interrupt state.
+ */
+static bool k3_r5_is_core_in_wfi(struct k3_r5_core *core)
+{
+   int ret;
+   u64 boot_vec;
+   u32 cfg, ctrl, stat;
+
+   ret = ti_sci_proc_get_status(core->tsp, &boot_vec, &cfg, &ctrl, &stat);
+
+   return !ret ? !!(stat & PROC_BOOT_STATUS_FLAG_R5_WFI) : false;
+}
+
 /**
  * k3_r5_rproc_mbox_callback() - inbound mailbox message handler
  * @client: mailbox client pointer used for requesting the mailbox channel
@@ -209,6 +225,10 @@ static void k3_r5_rproc_mbox_callback(struct mbox_client 
*client, void *data)
case RP_MBOX_ECHO_REPLY:
dev_info(dev, "received echo reply from %s\n", name);
break;
+   case RP_MBOX_SHUTDOWN_ACK:
+   dev_dbg(dev, "received shutdown_ack from %s\n", name);
+   complete(&kproc->shutdown_complete);
+   break;
default:
/* silently handle all other valid messages */
if (msg >= RP_MBOX_READY && msg < RP_MBOX_END_MSG)
@@ -634,6 +654,7 @@ static int k3_r5_rproc_stop(struct rproc *rproc)
struct k3_r5_cluster *cluster = kproc->cluster;
struct device *dev = kproc->dev;
struct k3_r5_core *core1, *core = kproc->core;
+   bool wfi;
int ret;
 
 
@@ -650,6 +671,24 @@ static int k3_r5_rproc_stop(struct rproc *rproc)
}
}
 
+   /* Send SHUTDOWN message to remote proc */
+   reinit_completion(&kproc->shutdown_complete);
+   ret = mbox_send_message(kproc->mbox, (void *)RP_MBOX_SHUTDOWN);
+   if (ret < 0) {
+   dev_err(dev, "Sending SHUTDOWN message failed: %d. Halting core 
anyway.\n", ret);
+   } else {
+   ret = wait_for_completion_timeout(&kproc->shutdown_complete,
+ msecs_to_jiffies(1000));
+   if (ret == 0) {
+   dev_err(dev, "Timeout waiting SHUTDOWN_ACK message. 
Halting core anyway.\n");
+   } else {
+   ret = readx_poll_timeout(k3_r5_is_core_in_wfi, core,
+wfi, wfi, 200, 2000);
+   if (ret)
+   dev_err(dev, "Timeout waiting for remote proc 
to be in WFI state. Halting core anyway.\n");
+   }
+   }
+
/* halt all applicable cores */
if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
 

[PATCH 3/4] remoteproc: k3-r5: k3_r5_rproc_stop: code reorder

2024-06-21 Thread Richard Genoud
In the next commit, a RP_MBOX_SHUTDOWN message will be sent in
k3_r5_rproc_stop() to the remote proc (in lockstep on not)
Thus, the sanity check "do not allow core 0 to stop before core 1"
should be moved at the beginning of the function so that the generic case
can be dealt with.

In order to have an easier patch to review, those actions are broke in
two patches:
- this patch: moving the sanity check at the beginning (No functional
  change).
- next patch: doing the real job (sending shutdown messages to remote
  procs before halting them).

Basically, we had:
- cluster_mode actions
- !cluster_mode sanity check
- !cluster_mode actions
And now:
- !cluster_mode sanity check
- cluster_mode actions
- !cluster_mode actions

Signed-off-by: Richard Genoud 
---
 drivers/remoteproc/ti_k3_r5_remoteproc.c | 24 ++--
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c 
b/drivers/remoteproc/ti_k3_r5_remoteproc.c
index 1f18b08618c8..a2ead87952c7 100644
--- a/drivers/remoteproc/ti_k3_r5_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c
@@ -636,16 +636,8 @@ static int k3_r5_rproc_stop(struct rproc *rproc)
struct k3_r5_core *core1, *core = kproc->core;
int ret;
 
-   /* halt all applicable cores */
-   if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
-   list_for_each_entry(core, &cluster->cores, elem) {
-   ret = k3_r5_core_halt(core);
-   if (ret) {
-   core = list_prev_entry(core, elem);
-   goto unroll_core_halt;
-   }
-   }
-   } else {
+
+   if (cluster->mode != CLUSTER_MODE_LOCKSTEP) {
/* do not allow core 0 to stop before core 1 */
core1 = list_last_entry(&cluster->cores, struct k3_r5_core,
elem);
@@ -656,6 +648,18 @@ static int k3_r5_rproc_stop(struct rproc *rproc)
ret = -EPERM;
goto out;
}
+   }
+
+   /* halt all applicable cores */
+   if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
+   list_for_each_entry(core, &cluster->cores, elem) {
+   ret = k3_r5_core_halt(core);
+   if (ret) {
+   core = list_prev_entry(core, elem);
+   goto unroll_core_halt;
+   }
+   }
+   } else {
 
ret = k3_r5_core_halt(core);
if (ret)



[PATCH 2/4] remoteproc: k3-r5: Introduce PM suspend/resume handlers

2024-06-21 Thread Richard Genoud
This patch adds the support for system suspend/resume to the ti_k3_R5
remoteproc driver.

In order to save maximum power, the approach here is to shutdown
completely the cores that were started by the kernel (i.e. those in
RUNNING state).
Those which were started before the kernel (in attached mode) will be
detached.

The pm_notifier mechanism is used here because the remote procs firmwares
have to be reloaded at resume, and thus the driver must have access to
the file system were the firmware is stored.

On suspend, the running remote procs are stopped, the attached remote
procs are detached and processor control released.

On resume, the reverse operation is done.

Based on work from: Hari Nagalla 

Signed-off-by: Richard Genoud 
---
 drivers/remoteproc/ti_k3_r5_remoteproc.c | 123 ++-
 1 file changed, 121 insertions(+), 2 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c 
b/drivers/remoteproc/ti_k3_r5_remoteproc.c
index 39a47540c590..1f18b08618c8 100644
--- a/drivers/remoteproc/ti_k3_r5_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -112,6 +113,7 @@ struct k3_r5_cluster {
struct list_head cores;
wait_queue_head_t core_transition;
const struct k3_r5_soc_data *soc_data;
+   struct notifier_block pm_notifier;
 };
 
 /**
@@ -577,7 +579,8 @@ static int k3_r5_rproc_start(struct rproc *rproc)
/* do not allow core 1 to start before core 0 */
core0 = list_first_entry(&cluster->cores, struct k3_r5_core,
 elem);
-   if (core != core0 && core0->rproc->state == RPROC_OFFLINE) {
+   if (core != core0 && (core0->rproc->state == RPROC_OFFLINE ||
+ core0->rproc->state == RPROC_SUSPENDED)) {
dev_err(dev, "%s: can not start core 1 before core 0\n",
__func__);
ret = -EPERM;
@@ -646,7 +649,8 @@ static int k3_r5_rproc_stop(struct rproc *rproc)
/* do not allow core 0 to stop before core 1 */
core1 = list_last_entry(&cluster->cores, struct k3_r5_core,
elem);
-   if (core != core1 && core1->rproc->state != RPROC_OFFLINE) {
+   if (core != core1 && core1->rproc->state != RPROC_OFFLINE &&
+   core1->rproc->state != RPROC_SUSPENDED) {
dev_err(dev, "%s: can not stop core 0 before core 1\n",
__func__);
ret = -EPERM;
@@ -1238,6 +1242,117 @@ static int k3_r5_rproc_configure_mode(struct 
k3_r5_rproc *kproc)
return ret;
 }
 
+static int k3_r5_rproc_suspend(struct k3_r5_rproc *kproc)
+{
+   unsigned int rproc_state = kproc->rproc->state;
+   int ret;
+
+   if (rproc_state != RPROC_RUNNING && rproc_state != RPROC_ATTACHED)
+   return 0;
+
+   if (rproc_state == RPROC_RUNNING)
+   ret = rproc_shutdown(kproc->rproc);
+   else
+   ret = rproc_detach(kproc->rproc);
+
+   if (ret) {
+   dev_err(kproc->dev, "Failed to %s rproc (%d)\n",
+   (rproc_state == RPROC_RUNNING) ? "shutdown" : "detach",
+   ret);
+   return ret;
+   }
+
+   kproc->rproc->state = RPROC_SUSPENDED;
+
+   return ret;
+}
+
+static int k3_r5_rproc_resume(struct k3_r5_rproc *kproc)
+{
+   int ret;
+
+   if (kproc->rproc->state != RPROC_SUSPENDED)
+   return 0;
+
+   ret = k3_r5_rproc_configure_mode(kproc);
+   if (ret < 0)
+   return -EBUSY;
+
+   /*
+* ret > 0 for IPC-only mode
+* ret == 0 for remote proc mode
+*/
+   if (ret == 0) {
+   /*
+* remote proc looses its configuration when powered off.
+* So, we have to configure it again on resume.
+*/
+   ret = k3_r5_rproc_configure(kproc);
+   if (ret < 0) {
+   dev_err(kproc->dev, "k3_r5_rproc_configure failed 
(%d)\n", ret);
+   return -EBUSY;
+   }
+   }
+
+   return rproc_boot(kproc->rproc);
+}
+
+static int k3_r5_cluster_pm_notifier_call(struct notifier_block *bl,
+ unsigned long state, void *unused)
+{
+   struct k3_r5_cluster *cluster = container_of(bl, struct k3_r5_cluster,
+pm_notifier);
+   struct k3_r5_core *core;
+   int ret;
+
+   switch (state) {
+   case PM_HIBERNATION_PREPARE:
+   case PM_RESTORE_PREPARE:
+   case PM_SUSPEND_PREPARE:
+   /* core1 should be suspended before core0 */
+   list_for_each_entry_reverse(core, &cluster->cores, elem) {
+ 

[PATCH 0/4] remoteproc: k3-r5: Introduce suspend to ram support

2024-06-21 Thread Richard Genoud
This series enables the suspend to ram with R5F remote processors on TI K3
platform.

The 1st patch is actually a fix, independent from the others

The 2nd patch introduces the suspend/resume handlers.
On suspend, the running rprocs will be stopped (or detached) and then
re-loaded in resume.
The logic behind this is:
 - shutdown the cores that Linux started to save power in suspend.
 - detach the cores that were started before Linux.

Then, the 3rd and 4th patches introduce the graceful shutdown of remote
procs. This will give them a chance to release resources and shut down
in a civilized manner.

Without this series, the suspend fails with:

omap-mailbox 31f81000.mailbox: fifo 1 has unexpected unread messages
omap-mailbox 31f81000.mailbox: PM: dpm_run_callback(): platform_pm_suspend 
returns -16
omap-mailbox 31f81000.mailbox: PM: platform_pm_suspend returned -16 after 16328 
usecs
omap-mailbox 31f81000.mailbox: PM: failed to suspend: error -16

Patches 2 and 4 are based on work from Hari Nagalla .

@Hari, please feel free to add your Co-developed-by:/Signed-off-by:

Tested on J7200X SoM
Series is based on v6.10-rc4

Richard Genoud (4):
  remoteproc: k3-r5: Fix IPC-only mode detection
  remoteproc: k3-r5: Introduce PM suspend/resume handlers
  remoteproc: k3-r5: k3_r5_rproc_stop: code reorder
  remoteproc: k3-r5: support for graceful stop of remote cores

 drivers/remoteproc/omap_remoteproc.h |   9 +-
 drivers/remoteproc/ti_k3_r5_remoteproc.c | 196 +--
 2 files changed, 188 insertions(+), 17 deletions(-)




[PATCH v8 0/5] Introduction of a remoteproc tee to load signed firmware

2024-06-21 Thread Arnaud Pouliquen
Main updates from version V7[1]

Update the series based on Mathieu Poirier's comments.
Details of the updates are listed in the commit messages of the patches.

[1] 
https://lore.kernel.org/linux-arm-kernel/20240611073904.475019-1-arnaud.pouliq...@foss.st.com/

base-commit: 1613e604df0cd359cf2a7fbd9be7a0bcfacfabd0

Description of the feature:
--
This series proposes the implementation of a remoteproc tee driver to
communicate with a TEE trusted application responsible for authenticating
and loading the remoteproc firmware image in an Arm secure context.

1) Principle:

The remoteproc tee driver provides services to communicate with the OP-TEE
trusted application running on the Trusted Execution Context (TEE).
The trusted application in TEE manages the remote processor lifecycle:

- authenticating and loading firmware images,
- isolating and securing the remote processor memories,
- supporting multi-firmware (e.g., TF-M + Zephyr on a Cortex-M33),
- managing the start and stop of the firmware by the TEE.

2) Format of the signed image:

Refer to:
https://github.com/OP-TEE/optee_os/blob/master/ta/remoteproc/src/remoteproc_core.c#L18-L57

3) OP-TEE trusted application API:

Refer to:
https://github.com/OP-TEE/optee_os/blob/master/ta/remoteproc/include/ta_remoteproc.h

4) OP-TEE signature script

Refer to:
https://github.com/OP-TEE/optee_os/blob/master/scripts/sign_rproc_fw.py

Example of usage:
sign_rproc_fw.py --in  --in  --out  --key 
${OP-TEE_PATH}/keys/default.pem


5) Impact on User space Application

No sysfs impact.the user only needs to provide the signed firmware image
instead of the ELF image.


For more information about the implementation, a presentation is available here
(note that the format of the signed image has evolved between the presentation
and the integration in OP-TEE).

https://resources.linaro.org/en/resource/6c5bGvZwUAjX56fvxthxds

Arnaud Pouliquen (5):
  remoteproc: core: Introduce rproc_pa_to_va helper
  remoteproc: Add TEE support
  dt-bindings: remoteproc: Add compatibility for TEE support
  remoteproc: stm32: Create sub-functions to request shutdown and
release
  remoteproc: stm32: Add support of an OP-TEE TA to load the firmware

 .../bindings/remoteproc/st,stm32-rproc.yaml   |  58 ++-
 drivers/remoteproc/Kconfig|  10 +
 drivers/remoteproc/Makefile   |   1 +
 drivers/remoteproc/remoteproc_core.c  |  46 ++
 drivers/remoteproc/remoteproc_tee.c   | 446 ++
 drivers/remoteproc/stm32_rproc.c  | 147 --
 include/linux/remoteproc.h|   5 +
 include/linux/remoteproc_tee.h| 100 
 8 files changed, 769 insertions(+), 44 deletions(-)
 create mode 100644 drivers/remoteproc/remoteproc_tee.c
 create mode 100644 include/linux/remoteproc_tee.h


base-commit: 1613e604df0cd359cf2a7fbd9be7a0bcfacfabd0
-- 
2.25.1




[PATCH v8 3/5] dt-bindings: remoteproc: Add compatibility for TEE support

2024-06-21 Thread Arnaud Pouliquen
The "st,stm32mp1-m4-tee" compatible is utilized in a system configuration
where the Cortex-M4 firmware is loaded by the Trusted Execution Environment
(TEE).

For instance, this compatible is used in both the Linux and OP-TEE device
trees:
- In OP-TEE, a node is defined in the device tree with the
  "st,stm32mp1-m4-tee" compatible to support signed remoteproc firmware.
  Based on DT properties, the OP-TEE remoteproc framework is initiated to
  expose a trusted application service to authenticate and load the remote
  processor firmware provided by the Linux remoteproc framework, as well
  as to start and stop the remote processor.
- In Linux, when the compatibility is set, the Cortex-M resets should not
  be declared in the device tree. In such a configuration, the reset is
  managed by the OP-TEE remoteproc driver and is no longer accessible from
  the Linux kernel.

Associated with this new compatible, add the "st,proc-id" property to
identify the remote processor. This ID is used to define a unique ID,
common between Linux, U-Boot, and OP-TEE, to identify a coprocessor.
This ID will be used in requests to the OP-TEE remoteproc Trusted
Application to specify the remote processor.

Signed-off-by: Arnaud Pouliquen 
Reviewed-by: Rob Herring (Arm) 
---
 .../bindings/remoteproc/st,stm32-rproc.yaml   | 58 ---
 1 file changed, 50 insertions(+), 8 deletions(-)

diff --git a/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml 
b/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml
index 370af61d8f28..409123cd4667 100644
--- a/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml
@@ -16,7 +16,12 @@ maintainers:
 
 properties:
   compatible:
-const: st,stm32mp1-m4
+enum:
+  - st,stm32mp1-m4
+  - st,stm32mp1-m4-tee
+description:
+  Use "st,stm32mp1-m4" for the Cortex-M4 coprocessor management by 
non-secure context
+  Use "st,stm32mp1-m4-tee" for the Cortex-M4 coprocessor management by 
secure context
 
   reg:
 description:
@@ -43,6 +48,10 @@ properties:
   - description: The offset of the hold boot setting register
   - description: The field mask of the hold boot
 
+  st,proc-id:
+description: remote processor identifier
+$ref: /schemas/types.yaml#/definitions/uint32
+
   st,syscfg-tz:
 deprecated: true
 description:
@@ -142,21 +151,43 @@ properties:
 required:
   - compatible
   - reg
-  - resets
 
 allOf:
   - if:
   properties:
-reset-names:
-  not:
-contains:
-  const: hold_boot
+compatible:
+  contains:
+const: st,stm32mp1-m4
 then:
+  if:
+properties:
+  reset-names:
+not:
+  contains:
+const: hold_boot
+  then:
+required:
+  - st,syscfg-holdboot
+  else:
+properties:
+  st,syscfg-holdboot: false
+required:
+  - reset-names
   required:
-- st,syscfg-holdboot
-else:
+- resets
+
+  - if:
+  properties:
+compatible:
+  contains:
+const: st,stm32mp1-m4-tee
+then:
   properties:
 st,syscfg-holdboot: false
+reset-names: false
+resets: false
+  required:
+- st,proc-id
 
 additionalProperties: false
 
@@ -188,5 +219,16 @@ examples:
   st,syscfg-rsc-tbl = <&tamp 0x144 0x>;
   st,syscfg-m4-state = <&tamp 0x148 0x>;
 };
+  - |
+#include 
+m4@1000 {
+  compatible = "st,stm32mp1-m4-tee";
+  reg = <0x1000 0x4>,
+<0x3000 0x4>,
+<0x3800 0x1>;
+  st,proc-id = <0>;
+  st,syscfg-rsc-tbl = <&tamp 0x144 0x>;
+  st,syscfg-m4-state = <&tamp 0x148 0x>;
+};
 
 ...
-- 
2.25.1




[PATCH v8 4/5] remoteproc: stm32: Create sub-functions to request shutdown and release

2024-06-21 Thread Arnaud Pouliquen
To prepare for the support of TEE remoteproc, create sub-functions
that can be used in both cases, with and without remoteproc TEE support.

Signed-off-by: Arnaud Pouliquen 
---
 drivers/remoteproc/stm32_rproc.c | 84 +++-
 1 file changed, 51 insertions(+), 33 deletions(-)

diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index 88623df7d0c3..8cd838df4e92 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -209,6 +209,54 @@ static int stm32_rproc_mbox_idx(struct rproc *rproc, const 
unsigned char *name)
return -EINVAL;
 }
 
+static void stm32_rproc_request_shutdown(struct rproc *rproc)
+{
+   struct stm32_rproc *ddata = rproc->priv;
+   int err, dummy_data, idx;
+
+   /* Request shutdown of the remote processor */
+   if (rproc->state != RPROC_OFFLINE && rproc->state != RPROC_CRASHED) {
+   idx = stm32_rproc_mbox_idx(rproc, STM32_MBX_SHUTDOWN);
+   if (idx >= 0 && ddata->mb[idx].chan) {
+   /* A dummy data is sent to allow to block on transmit. 
*/
+   err = mbox_send_message(ddata->mb[idx].chan,
+   &dummy_data);
+   if (err < 0)
+   dev_warn(&rproc->dev, "warning: remote FW 
shutdown without ack\n");
+   }
+   }
+}
+
+static int stm32_rproc_release(struct rproc *rproc)
+{
+   struct stm32_rproc *ddata = rproc->priv;
+   unsigned int err = 0;
+
+   /* To allow platform Standby power mode, set remote proc Deep Sleep. */
+   if (ddata->pdds.map) {
+   err = regmap_update_bits(ddata->pdds.map, ddata->pdds.reg,
+ddata->pdds.mask, 1);
+   if (err) {
+   dev_err(&rproc->dev, "failed to set pdds\n");
+   return err;
+   }
+   }
+
+   /* Update coprocessor state to OFF if available. */
+   if (ddata->m4_state.map) {
+   err = regmap_update_bits(ddata->m4_state.map,
+ddata->m4_state.reg,
+ddata->m4_state.mask,
+M4_STATE_OFF);
+   if (err) {
+   dev_err(&rproc->dev, "failed to set copro state\n");
+   return err;
+   }
+   }
+
+   return 0;
+}
+
 static int stm32_rproc_prepare(struct rproc *rproc)
 {
struct device *dev = rproc->dev.parent;
@@ -519,17 +567,9 @@ static int stm32_rproc_detach(struct rproc *rproc)
 static int stm32_rproc_stop(struct rproc *rproc)
 {
struct stm32_rproc *ddata = rproc->priv;
-   int err, idx;
+   int err;
 
-   /* request shutdown of the remote processor */
-   if (rproc->state != RPROC_OFFLINE && rproc->state != RPROC_CRASHED) {
-   idx = stm32_rproc_mbox_idx(rproc, STM32_MBX_SHUTDOWN);
-   if (idx >= 0 && ddata->mb[idx].chan) {
-   err = mbox_send_message(ddata->mb[idx].chan, "detach");
-   if (err < 0)
-   dev_warn(&rproc->dev, "warning: remote FW 
shutdown without ack\n");
-   }
-   }
+   stm32_rproc_request_shutdown(rproc);
 
err = stm32_rproc_set_hold_boot(rproc, true);
if (err)
@@ -541,29 +581,7 @@ static int stm32_rproc_stop(struct rproc *rproc)
return err;
}
 
-   /* to allow platform Standby power mode, set remote proc Deep Sleep */
-   if (ddata->pdds.map) {
-   err = regmap_update_bits(ddata->pdds.map, ddata->pdds.reg,
-ddata->pdds.mask, 1);
-   if (err) {
-   dev_err(&rproc->dev, "failed to set pdds\n");
-   return err;
-   }
-   }
-
-   /* update coprocessor state to OFF if available */
-   if (ddata->m4_state.map) {
-   err = regmap_update_bits(ddata->m4_state.map,
-ddata->m4_state.reg,
-ddata->m4_state.mask,
-M4_STATE_OFF);
-   if (err) {
-   dev_err(&rproc->dev, "failed to set copro state\n");
-   return err;
-   }
-   }
-
-   return 0;
+   return stm32_rproc_release(rproc);
 }
 
 static void stm32_rproc_kick(struct rproc *rproc, int vqid)
-- 
2.25.1




[PATCH v8 2/5] remoteproc: Add TEE support

2024-06-21 Thread Arnaud Pouliquen
Add a remoteproc TEE (Trusted Execution Environment) driver
that will be probed by the TEE bus. If the associated Trusted
application is supported on secure part this driver offers a client
interface to load a firmware by the secure part.
This firmware could be authenticated by the secure trusted application.

Signed-off-by: Arnaud Pouliquen 
---
Updates vs previous version:
- rename tee_remoteproc.* file to rmeoteproc_tee.*,
- rename TEE_REMOTEPROC config to REMOTEPROC_TEE,
- remove "stm32" in some variable declarations,
- remove useless "remoteproc_internal.h" include,
- fix tee_rproc_ctx devm_kzalloc.
- rework module description
---
 drivers/remoteproc/Kconfig  |  10 +
 drivers/remoteproc/Makefile |   1 +
 drivers/remoteproc/remoteproc_tee.c | 446 
 include/linux/remoteproc.h  |   4 +
 include/linux/remoteproc_tee.h  | 100 +++
 5 files changed, 561 insertions(+)
 create mode 100644 drivers/remoteproc/remoteproc_tee.c
 create mode 100644 include/linux/remoteproc_tee.h

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 48845dc8fa85..278f197acb90 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -365,6 +365,16 @@ config XLNX_R5_REMOTEPROC
 
  It's safe to say N if not interested in using RPU r5f cores.
 
+
+config REMOTEPROC_TEE
+   tristate "Remoteproc support by a TEE application"
+   depends on OPTEE
+   help
+ Support a remote processor with a TEE application. The Trusted
+ Execution Context is responsible for loading the trusted firmware
+ image and managing the remote processor's lifecycle.
+ This can be either built-in or a loadable module.
+
 endif # REMOTEPROC
 
 endmenu
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 91314a9b43ce..b4eb37177005 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_RCAR_REMOTEPROC) += rcar_rproc.o
 obj-$(CONFIG_ST_REMOTEPROC)+= st_remoteproc.o
 obj-$(CONFIG_ST_SLIM_REMOTEPROC)   += st_slim_rproc.o
 obj-$(CONFIG_STM32_RPROC)  += stm32_rproc.o
+obj-$(CONFIG_REMOTEPROC_TEE)   += remoteproc_tee.o
 obj-$(CONFIG_TI_K3_DSP_REMOTEPROC) += ti_k3_dsp_remoteproc.o
 obj-$(CONFIG_TI_K3_R5_REMOTEPROC)  += ti_k3_r5_remoteproc.o
 obj-$(CONFIG_XLNX_R5_REMOTEPROC)   += xlnx_r5_remoteproc.o
diff --git a/drivers/remoteproc/remoteproc_tee.c 
b/drivers/remoteproc/remoteproc_tee.c
new file mode 100644
index ..70cb67451767
--- /dev/null
+++ b/drivers/remoteproc/remoteproc_tee.c
@@ -0,0 +1,446 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) STMicroelectronics 2024
+ * Author: Arnaud Pouliquen 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MAX_TEE_PARAM_ARRY_MEMBER  4
+
+/*
+ * Authentication of the firmware and load in the remote processor memory
+ *
+ * [in]  params[0].value.a:unique 32bit identifier of the remote processor
+ * [in] params[1].memref:  buffer containing the image of the 
buffer
+ */
+#define TA_RPROC_FW_CMD_LOAD_FW1
+
+/*
+ * Start the remote processor
+ *
+ * [in]  params[0].value.a:unique 32bit identifier of the remote processor
+ */
+#define TA_RPROC_FW_CMD_START_FW   2
+
+/*
+ * Stop the remote processor
+ *
+ * [in]  params[0].value.a:unique 32bit identifier of the remote processor
+ */
+#define TA_RPROC_FW_CMD_STOP_FW3
+
+/*
+ * Return the address of the resource table, or 0 if not found
+ * No check is done to verify that the address returned is accessible by
+ * the non secure context. If the resource table is loaded in a protected
+ * memory the access by the non secure context will lead to a data abort.
+ *
+ * [in]  params[0].value.a:unique 32bit identifier of the remote processor
+ * [out]  params[1].value.a:   32bit LSB resource table memory address
+ * [out]  params[1].value.b:   32bit MSB resource table memory address
+ * [out]  params[2].value.a:   32bit LSB resource table memory size
+ * [out]  params[2].value.b:   32bit MSB resource table memory size
+ */
+#define TA_RPROC_FW_CMD_GET_RSC_TABLE  4
+
+/*
+ * Return the address of the core dump
+ *
+ * [in]  params[0].value.a:unique 32bit identifier of the remote processor
+ * [out] params[1].memref: address of the core dump image if exist,
+ * else return Null
+ */
+#define TA_RPROC_FW_CMD_GET_COREDUMP   5
+
+struct tee_rproc_context {
+   struct list_head sessions;
+   struct tee_context *tee_ctx;
+   struct device *dev;
+};
+
+static struct tee_rproc_context *tee_rproc_ctx;
+
+static void tee_rproc_prepare_args(struct tee_rproc *trproc, int cmd,
+  struct tee_ioctl_invoke_arg *arg,
+  struct tee_param *param,
+  unsigned

[PATCH v8 1/5] remoteproc: core: Introduce rproc_pa_to_va helper

2024-06-21 Thread Arnaud Pouliquen
When a resource table is loaded by an external entity such as U-boot or
OP-TEE, we do not necessarily get the device address(da) but the physical
address(pa).
This helper performs similar translation than the rproc_da_to_va()
but based on a physical address.

Signed-off-by: Arnaud Pouliquen 
---
updates vs previous version:
- remove pa_to_va in the rproc_ops structure as not used
- simplify the rproc_pa_to_va() documentation header
- fix typos
---
 drivers/remoteproc/remoteproc_core.c | 46 
 include/linux/remoteproc.h   |  1 +
 2 files changed, 47 insertions(+)

diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index f276956f2c5c..ace11ea17097 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -230,6 +230,52 @@ void *rproc_da_to_va(struct rproc *rproc, u64 da, size_t 
len, bool *is_iomem)
 }
 EXPORT_SYMBOL(rproc_da_to_va);
 
+/**
+ * rproc_pa_to_va() - lookup the kernel virtual address for a physical address 
of a remoteproc
+ * memory
+ *
+ * @rproc: handle of a remote processor
+ * @pa: remoteproc physical address
+ * @len: length of the memory region @pa is pointing to
+ * @is_iomem: optional pointer filled in to indicate if @da is iomapped memory
+ *
+ * This function is a helper function similar to rproc_da_to_va() but it deals 
with physical
+ * addresses instead of device addresses.
+ *
+ * Return: a valid kernel address on success or NULL on failure
+ */
+void *rproc_pa_to_va(struct rproc *rproc, phys_addr_t pa, size_t len, bool 
*is_iomem)
+{
+   struct rproc_mem_entry *carveout;
+   void *ptr = NULL;
+
+   list_for_each_entry(carveout, &rproc->carveouts, node) {
+   int offset = pa - carveout->dma;
+
+   /*  Verify that carveout is allocated */
+   if (!carveout->va)
+   continue;
+
+   /* try next carveout if da is too small */
+   if (offset < 0)
+   continue;
+
+   /* try next carveout if da is too large */
+   if (offset + len > carveout->len)
+   continue;
+
+   ptr = carveout->va + offset;
+
+   if (is_iomem)
+   *is_iomem = carveout->is_iomem;
+
+   break;
+   }
+
+   return ptr;
+}
+EXPORT_SYMBOL(rproc_pa_to_va);
+
 /**
  * rproc_find_carveout_by_name() - lookup the carveout region by a name
  * @rproc: handle of a remote processor
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index b4795698d8c2..8fd0d7f63c8e 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -690,6 +690,7 @@ int rproc_detach(struct rproc *rproc);
 int rproc_set_firmware(struct rproc *rproc, const char *fw_name);
 void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type);
 void *rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem);
+void *rproc_pa_to_va(struct rproc *rproc, phys_addr_t pa, size_t len, bool 
*is_iomem);
 
 /* from remoteproc_coredump.c */
 void rproc_coredump_cleanup(struct rproc *rproc);
-- 
2.25.1




[PATCH v8 5/5] remoteproc: stm32: Add support of an OP-TEE TA to load the firmware

2024-06-21 Thread Arnaud Pouliquen
The new TEE remoteproc device is used to manage remote firmware in a
secure, trusted context. The 'st,stm32mp1-m4-tee' compatibility is
introduced to delegate the loading of the firmware to the trusted
execution context. In such cases, the firmware should be signed and
adhere to the image format defined by the TEE.

Signed-off-by: Arnaud Pouliquen 
---
 drivers/remoteproc/stm32_rproc.c | 63 ++--
 1 file changed, 60 insertions(+), 3 deletions(-)

diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index 8cd838df4e92..fd905b3cf206 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -257,6 +258,19 @@ static int stm32_rproc_release(struct rproc *rproc)
return 0;
 }
 
+static int stm32_rproc_tee_stop(struct rproc *rproc)
+{
+   int err;
+
+   stm32_rproc_request_shutdown(rproc);
+
+   err = tee_rproc_stop(rproc);
+   if (err)
+   return err;
+
+   return stm32_rproc_release(rproc);
+}
+
 static int stm32_rproc_prepare(struct rproc *rproc)
 {
struct device *dev = rproc->dev.parent;
@@ -693,8 +707,20 @@ static const struct rproc_ops st_rproc_ops = {
.get_boot_addr  = rproc_elf_get_boot_addr,
 };
 
+static const struct rproc_ops st_rproc_tee_ops = {
+   .prepare= stm32_rproc_prepare,
+   .start  = tee_rproc_start,
+   .stop   = stm32_rproc_tee_stop,
+   .kick   = stm32_rproc_kick,
+   .load   = tee_rproc_load_fw,
+   .parse_fw   = tee_rproc_parse_fw,
+   .find_loaded_rsc_table = tee_rproc_find_loaded_rsc_table,
+
+};
+
 static const struct of_device_id stm32_rproc_match[] = {
{ .compatible = "st,stm32mp1-m4" },
+   { .compatible = "st,stm32mp1-m4-tee" },
{},
 };
 MODULE_DEVICE_TABLE(of, stm32_rproc_match);
@@ -853,17 +879,42 @@ static int stm32_rproc_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct stm32_rproc *ddata;
struct device_node *np = dev->of_node;
+   struct tee_rproc *trproc = NULL;
struct rproc *rproc;
unsigned int state;
+   u32 proc_id;
int ret;
 
ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
if (ret)
return ret;
 
-   rproc = devm_rproc_alloc(dev, np->name, &st_rproc_ops, NULL, 
sizeof(*ddata));
-   if (!rproc)
-   return -ENOMEM;
+   if (of_device_is_compatible(np, "st,stm32mp1-m4-tee")) {
+   /*
+* Delegate the firmware management to the secure context.
+* The firmware loaded has to be signed.
+*/
+   ret = of_property_read_u32(np, "st,proc-id", &proc_id);
+   if (ret) {
+   dev_err(dev, "failed to read st,rproc-id property\n");
+   return ret;
+   }
+
+   rproc = devm_rproc_alloc(dev, np->name, &st_rproc_tee_ops, 
NULL, sizeof(*ddata));
+   if (!rproc)
+   return -ENOMEM;
+
+   trproc = tee_rproc_register(dev, rproc, proc_id);
+   if (IS_ERR(trproc)) {
+   dev_err_probe(dev, PTR_ERR(trproc),
+ "signed firmware not supported by TEE\n");
+   return PTR_ERR(trproc);
+   }
+   } else {
+   rproc = devm_rproc_alloc(dev, np->name, &st_rproc_ops, NULL, 
sizeof(*ddata));
+   if (!rproc)
+   return -ENOMEM;
+   }
 
ddata = rproc->priv;
 
@@ -915,6 +966,9 @@ static int stm32_rproc_probe(struct platform_device *pdev)
dev_pm_clear_wake_irq(dev);
device_init_wakeup(dev, false);
}
+   if (trproc)
+   tee_rproc_unregister(trproc);
+
return ret;
 }
 
@@ -935,6 +989,9 @@ static void stm32_rproc_remove(struct platform_device *pdev)
dev_pm_clear_wake_irq(dev);
device_init_wakeup(dev, false);
}
+   if (rproc->tee_interface)
+   tee_rproc_unregister(rproc->tee_interface);
+
 }
 
 static int stm32_rproc_suspend(struct device *dev)
-- 
2.25.1




[PATCH v2 3/3] ARM: dts: qcom: msm8974-sony-shinano: increase load on l21 for sdhc2

2024-06-21 Thread Valeriy Klimin
SD cards would exhibit errors similar to ones described in commit
27fe0fc05f35 ("ARM: dts: msm8974-FP2: Increase load on l20 for sdhci")

This patch applies the same change to the regulator for sdhc2.

Signed-off-by: Valeriy Klimin 
---
 arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-common.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git 
a/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-common.dtsi 
b/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-common.dtsi
index e129bb1bd6ec..6af7c71c7158 100644
--- a/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-common.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-common.dtsi
@@ -380,6 +380,8 @@ pm8941_l20: l20 {
pm8941_l21: l21 {
regulator-min-microvolt = <295>;
regulator-max-microvolt = <295>;
+   regulator-system-load = <50>;
+   regulator-allow-set-load;
regulator-boot-on;
};
 

-- 
2.43.2




[PATCH v2 2/3] ARM: dts: qcom: Add Sony Xperia Z3 Compact smartphone

2024-06-21 Thread Valeriy Klimin
Add the dts for the Z3 Compact. This is currently almost the same
as the plain Z3 as they share almost the same hardware and
nothing device-specific is currently supported.

Signed-off-by: Valeriy Klimin 
---
 arch/arm/boot/dts/qcom/Makefile|  1 +
 .../qcom-msm8974pro-sony-xperia-shinano-aries.dts  | 44 ++
 2 files changed, 45 insertions(+)

diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile
index e2e922bdc9e9..d057396cfeef 100644
--- a/arch/arm/boot/dts/qcom/Makefile
+++ b/arch/arm/boot/dts/qcom/Makefile
@@ -47,6 +47,7 @@ dtb-$(CONFIG_ARCH_QCOM) += \
qcom-msm8974pro-oneplus-bacon.dtb \
qcom-msm8974pro-samsung-klte.dtb \
qcom-msm8974pro-samsung-kltechn.dtb \
+   qcom-msm8974pro-sony-xperia-shinano-aries.dtb \
qcom-msm8974pro-sony-xperia-shinano-castor.dtb \
qcom-msm8974pro-sony-xperia-shinano-leo.dtb \
qcom-mdm9615-wp8548-mangoh-green.dtb \
diff --git 
a/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-aries.dts 
b/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-aries.dts
new file mode 100644
index ..2621c5928b6a
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-aries.dts
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "qcom-msm8974pro-sony-xperia-shinano-common.dtsi"
+
+/ {
+   model = "Sony Xperia Z3 Compact";
+   compatible = "sony,xperia-aries", "qcom,msm8974pro", "qcom,msm8974";
+   chassis-type = "handset";
+
+   gpio-keys {
+   key-camera-snapshot {
+   label = "camera_snapshot";
+   gpios = <&pm8941_gpios 3 GPIO_ACTIVE_LOW>;
+   linux,code = ;
+   debounce-interval = <15>;
+   };
+
+   key-camera-focus {
+   label = "camera_focus";
+   gpios = <&pm8941_gpios 4 GPIO_ACTIVE_LOW>;
+   linux,code = ;
+   debounce-interval = <15>;
+   };
+   };
+};
+
+&gpio_keys_pin_a {
+   pins = "gpio2", "gpio3", "gpio4", "gpio5";
+};
+
+&smbb {
+   usb-charge-current-limit = <150>;
+   qcom,fast-charge-safe-current = <210>;
+   qcom,fast-charge-current-limit = <180>;
+   qcom,fast-charge-safe-voltage = <440>;
+   qcom,fast-charge-high-threshold-voltage = <435>;
+   qcom,auto-recharge-threshold-voltage = <428>;
+   qcom,minimum-input-voltage = <420>;
+
+   status = "okay";
+};
+
+&synaptics_touchscreen {
+   vio-supply = <&pm8941_s3>;
+};

-- 
2.43.2




[PATCH v2 1/3] dt-bindings: arm: qcom: Add Sony Xperia Z3 Compact

2024-06-21 Thread Valeriy Klimin
Add the compatible for this device.

Signed-off-by: Valeriy Klimin 
---
 Documentation/devicetree/bindings/arm/qcom.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml 
b/Documentation/devicetree/bindings/arm/qcom.yaml
index ae885414b181..e53f061fc1cf 100644
--- a/Documentation/devicetree/bindings/arm/qcom.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom.yaml
@@ -184,6 +184,7 @@ properties:
   - fairphone,fp2
   - oneplus,bacon
   - samsung,klte
+  - sony,xperia-aries
   - sony,xperia-castor
   - sony,xperia-leo
   - const: qcom,msm8974pro

-- 
2.43.2




[PATCH v2 0/3] Add Sony Xperia Z3 Compact smartphone

2024-06-21 Thread Valeriy Klimin
This is almost the same as the dts of the Xperia Z3, except for the
battery charge limits. 

The current on the l21 regulator for shinano is also bumped up
to stop SD card errors.

Signed-off-by: Valeriy Klimin 
---
Changes in v2:
- Reordered dt-bindings and dts commits
- Link to v1: 
https://lore.kernel.org/r/20240621-sony-aries-v1-0-bcf968769...@gmail.com

---
Valeriy Klimin (3):
  dt-bindings: arm: qcom: Add Sony Xperia Z3 Compact
  ARM: dts: qcom: Add Sony Xperia Z3 Compact smartphone
  ARM: dts: qcom: msm8974-sony-shinano: increase load on l21 for sdhc2

 Documentation/devicetree/bindings/arm/qcom.yaml|  1 +
 arch/arm/boot/dts/qcom/Makefile|  1 +
 .../qcom-msm8974pro-sony-xperia-shinano-aries.dts  | 44 ++
 ...qcom-msm8974pro-sony-xperia-shinano-common.dtsi |  2 +
 4 files changed, 48 insertions(+)
---
base-commit: cd214efd16e30bf1aa40ccfaaf9177f47dd21fd5
change-id: 20240620-sony-aries-4a5bce06c91d

Best regards,
-- 
Valeriy Klimin 




Re: [PATCH] qdisc: fix NULL pointer dereference in perf_trace_qdisc_reset()

2024-06-21 Thread Pedro Tammela

On 21/06/2024 08:45, ysk...@gmail.com wrote:

From: Yunseong Kim 

In the TRACE_EVENT(qdisc_reset) NULL dereference occurred from

  qdisc->dev_queue->dev  ->name

This situation simulated from bunch of veths and Bluetooth dis/reconnection.

During qdisc initialization, qdisc was being set to noop_queue.
In veth_init_queue, the initial tx_num was reduced back to one,
causing the qdisc reset to be called with noop, which led to the kernel panic.

I think this will happen on the kernel version.
  Linux kernel version ≥ v6.7.10, ≥ v6.8 ≥ v6.9 and 6.10


You should tag your patch for the net tree



This occurred from 51270d573a8d. I think this patch is absolutely
necessary. Previously, It was showing not intended string value of name.

Add a 'Fixes:' tag with this commit



I've reproduced 3 time from my fedora 40 Debug Kernel with any other module
and patched.

version: 6.10.0-0.rc2.20240608gitdc772f8237f9.29.fc41.aarch64+debug

[ 5287.164555] veth0_vlan: left promiscuous mode
[ 5287.164929] veth1_macvtap: left promiscuous mode
[ 5287.164950] veth0_macvtap: left promiscuous mode
[ 5287.164983] veth1_vlan: left promiscuous mode
[ 5287.165008] veth0_vlan: left promiscuous mode
[ 5287.165450] veth1_macvtap: left promiscuous mode
[ 5287.165472] veth0_macvtap: left promiscuous mode
[ 5287.165502] veth1_vlan: left promiscuous mode
…
[ 5297.598240] bridge0: port 2(bridge_slave_1) entered blocking state
[ 5297.598262] bridge0: port 2(bridge_slave_1) entered forwarding state
[ 5297.598296] bridge0: port 1(bridge_slave_0) entered blocking state
[ 5297.598313] bridge0: port 1(bridge_slave_0) entered forwarding state
[ 5297.616090] 8021q: adding VLAN 0 to HW filter on device bond0
[ 5297.620405] bridge0: port 1(bridge_slave_0) entered disabled state
[ 5297.620730] bridge0: port 2(bridge_slave_1) entered disabled state
[ 5297.627247] 8021q: adding VLAN 0 to HW filter on device team0
[ 5297.629636] bridge0: port 1(bridge_slave_0) entered blocking state
…
[ 5298.002798] bridge_slave_0: left promiscuous mode
[ 5298.002869] bridge0: port 1(bridge_slave_0) entered disabled state
[ 5298.309444] bond0 (unregistering): (slave bond_slave_0): Releasing backup 
interface
[ 5298.315206] bond0 (unregistering): (slave bond_slave_1): Releasing backup 
interface
[ 5298.320207] bond0 (unregistering): Released all slaves
[ 5298.354296] hsr_slave_0: left promiscuous mode
[ 5298.360750] hsr_slave_1: left promiscuous mode
[ 5298.374889] veth1_macvtap: left promiscuous mode
[ 5298.374931] veth0_macvtap: left promiscuous mode
[ 5298.374988] veth1_vlan: left promiscuous mode
[ 5298.375024] veth0_vlan: left promiscuous mode
[ 5299.109741] team0 (unregistering): Port device team_slave_1 removed
[ 5299.185870] team0 (unregistering): Port device team_slave_0 removed
…
[ 5300.155443] Bluetooth: hci3: unexpected cc 0x0c03 length: 249 > 1
[ 5300.155724] Bluetooth: hci3: unexpected cc 0x1003 length: 249 > 9
[ 5300.155988] Bluetooth: hci3: unexpected cc 0x1001 length: 249 > 9
….
[ 5301.075531] team0: Port device team_slave_1 added
[ 5301.085515] bridge0: port 1(bridge_slave_0) entered blocking state
[ 5301.085531] bridge0: port 1(bridge_slave_0) entered disabled state
[ 5301.085588] bridge_slave_0: entered allmulticast mode
[ 5301.085800] bridge_slave_0: entered promiscuous mode
[ 5301.095617] bridge0: port 1(bridge_slave_0) entered blocking state
[ 5301.095633] bridge0: port 1(bridge_slave_0) entered disabled state
…
[ 5301.149734] bond0: (slave bond_slave_0): Enslaving as an active interface 
with an up link
[ 5301.173234] bond0: (slave bond_slave_0): Enslaving as an active interface 
with an up link
[ 5301.180517] bond0: (slave bond_slave_1): Enslaving as an active interface 
with an up link
[ 5301.193481] hsr_slave_0: entered promiscuous mode
[ 5301.204425] hsr_slave_1: entered promiscuous mode
[ 5301.210172] debugfs: Directory 'hsr0' with parent 'hsr' already present!
[ 5301.210185] Cannot create hsr debugfs directory
[ 5301.224061] bond0: (slave bond_slave_1): Enslaving as an active interface 
with an up link
[ 5301.246901] bond0: (slave bond_slave_0): Enslaving as an active interface 
with an up link
[ 5301.255934] team0: Port device team_slave_0 added
[ 5301.256480] team0: Port device team_slave_1 added
[ 5301.256948] team0: Port device team_slave_0 added
…
[ 5301.435928] hsr_slave_0: entered promiscuous mode
[ 5301.446029] hsr_slave_1: entered promiscuous mode
[ 5301.455872] debugfs: Directory 'hsr0' with parent 'hsr' already present!
[ 5301.455884] Cannot create hsr debugfs directory
[ 5301.502664] hsr_slave_0: entered promiscuous mode
[ 5301.513675] hsr_slave_1: entered promiscuous mode
[ 5301.526155] debugfs: Directory 'hsr0' with parent 'hsr' already present!
[ 5301.526164] Cannot create hsr debugfs directory
[ 5301.563662] hsr_slave_0: entered promiscuous mode
[ 5301.576129] hsr_slave_1: entered promiscuous mode
[ 5301.580259] debugfs: Directory 'hsr0' with parent 'hsr' already present!
[ 5301.580270] Cannot create hsr debugfs directory
[

Re: [PATCH 6.10.0-rc2] kernel/module: avoid panic on loading broken module

2024-06-21 Thread Daniel von Kirschten

Am 18.06.2024 um 21:58 schrieb Luis Chamberlain:

On Thu, Jun 06, 2024 at 03:31:49PM +0200, Daniel v. Kirschten wrote:

If a module is being loaded, and the .gnu.linkonce.this_module section
in the module's ELF file does not have the WRITE flag, the kernel will
map the finished module struct of that module as read-only.
This causes a kernel panic when the struct is written to the first time
after it has been marked read-only. Currently this happens in
complete_formation in kernel/module/main.c:2765 when the module's state is
set to MODULE_STATE_COMING, just after setting up the memory protections.


How did you find this issue?


In a university course I got the assignment to manually craft a loadable 
.ko file, given only a regular object file, without using Kbuild. During 
testing my module files, most of them were simply (correctly) rejected 
by the kernel with an appropriate error message, but at some point I ran 
into this exact kernel panic, and investigated it to understand why my 
module file was invalid.





Down the line, this seems to lead to unpredictable freezes when trying to
load other modules - I guess this is due to some structures not being
cleaned up properly, but I didn't investigate this further.

A check already exists which verifies that .gnu.linkonce.this_module
is ALLOC. This patch simply adds an analogous check for WRITE.


Can you check to ensure our modules generated have a respective check to
ensure this check exists at build time? That would proactively inform
userspace when a built module is not built correctly, and the tool
responsible can be identified.


See above - I don't think it's possible to create such a broken module 
file with any of "official" tools. I haven't looked too deeply into how 
Kbuild actually builds modules, but as far as I know, the user doesn't 
even come into contact with this_module when using the regular 
toolchain, because Kbuild is responsible for creating the .this_module 
section. And Kbuild of course creates it with the correct flags. So if I 
understand correctly, this problem can only occur when the module was 
built by some external tooling (or manually, in my case).


  Daniel



Re: [RFC PATCH v3 0/7] Add virtio_rtc module and related changes

2024-06-21 Thread David Woodhouse
On Thu, 2024-06-20 at 14:37 +0200, Peter Hilber wrote:
> Should implement .gettimex64 instead.

Thanks. This look sane?

As noted in the code comment, in the *ideal* case we just build all
three pre/post/device timestamps from the very same counter read. So
sts->pre_ts == sts->post_ts.

In the less ideal case (which will happen on x86 when kvmclock is being
used for the system time), we use the time from ktime_get_snapshot() as
the pre_ts and take a new snapshot immediately after the get_cycles().


diff --git a/drivers/ptp/ptp_vmclock.c b/drivers/ptp/ptp_vmclock.c
index e8c65405a8f3..07a81a94d29a 100644
--- a/drivers/ptp/ptp_vmclock.c
+++ b/drivers/ptp/ptp_vmclock.c
@@ -96,9 +96,11 @@ static inline uint64_t mul_u64_u64_add_u64(uint64_t *res_hi, 
uint64_t delta,
 }
 
 static int vmclock_get_crosststamp(struct vmclock_state *st,
+  struct ptp_system_timestamp *sts,
   struct system_counterval_t *system_counter,
   struct timespec64 *tspec)
 {
+   struct system_time_snapshot systime_snapshot;
uint64_t cycle, delta, seq, frac_sec;
int ret = 0;
 
@@ -119,7 +121,17 @@ static int vmclock_get_crosststamp(struct vmclock_state 
*st,
continue;
}
 
-   cycle = get_cycles();
+   if (sts) {
+   ktime_get_snapshot(&systime_snapshot);
+
+   if (systime_snapshot.cs_id == st->cs_id) {
+   cycle = systime_snapshot.cycles;
+   } else {
+   cycle = get_cycles();
+   ptp_read_system_postts(sts);
+   }
+   } else
+   cycle = get_cycles();
 
delta = cycle - st->clk->counter_value;
 
@@ -139,6 +151,21 @@ static int vmclock_get_crosststamp(struct vmclock_state 
*st,
if (ret)
return ret;
 
+   /*
+* When invoked for gettimex64, fill in the pre/post system times.
+* The ideal case is when system time is based on the the same
+* counter as st->cs_id, in which case all three pre/post/device
+* times are derived from the *same* counter value. If cs_id does
+* not match, then the value from ktime_get_snapshot() is used as
+* pre_ts, and ptp_read_system_postts() was already called above
+* for the post_ts. Those are either side of the get_cycles() call.
+*/
+   if (sts) {
+   sts->pre_ts = ktime_to_timespec64(systime_snapshot.real);
+   if (systime_snapshot.cs_id == st->cs_id)
+   sts->post_ts = sts->pre_ts;
+   }
+
if (system_counter) {
system_counter->cycles = cycle;
system_counter->cs_id = st->cs_id;
@@ -155,7 +182,7 @@ static int ptp_vmclock_get_time_fn(ktime_t *device_time,
struct timespec64 tspec;
int ret;
 
-   ret = vmclock_get_crosststamp(st, system_counter, &tspec);
+   ret = vmclock_get_crosststamp(st, NULL, system_counter, &tspec);
if (!ret)
*device_time = timespec64_to_ktime(tspec);
 
@@ -198,7 +225,16 @@ static int ptp_vmclock_gettime(struct ptp_clock_info *ptp, 
struct timespec64 *ts
struct vmclock_state *st = container_of(ptp, struct vmclock_state,
ptp_clock_info);
 
-   return vmclock_get_crosststamp(st, NULL, ts);
+   return vmclock_get_crosststamp(st, NULL, NULL, ts);
+}
+
+static int ptp_vmclock_gettimex(struct ptp_clock_info *ptp, struct timespec64 
*ts,
+   struct ptp_system_timestamp *sts)
+{
+   struct vmclock_state *st = container_of(ptp, struct vmclock_state,
+   ptp_clock_info);
+
+   return vmclock_get_crosststamp(st, sts, NULL, ts);
 }
 
 static int ptp_vmclock_enable(struct ptp_clock_info *ptp,
@@ -216,6 +252,7 @@ static const struct ptp_clock_info ptp_vmclock_info = {
.adjfine= ptp_vmclock_adjfine,
.adjtime= ptp_vmclock_adjtime,
.gettime64  = ptp_vmclock_gettime,
+   .gettimex64 = ptp_vmclock_gettimex,
.settime64  = ptp_vmclock_settime,
.enable = ptp_vmclock_enable,
.getcrosststamp = ptp_vmclock_getcrosststamp,




smime.p7s
Description: S/MIME cryptographic signature


Re: [PATCH v2 2/3] remoteproc: k3-r5: Acquire mailbox handle during probe

2024-06-21 Thread Andrew Davis

On 6/21/24 6:14 AM, Beleswar Prasad Padhi wrote:

Hi Andrew,

On 04/06/24 22:40, Andrew Davis wrote:

On 6/4/24 12:17 AM, Beleswar Padhi wrote:

Acquire the mailbox handle during device probe and do not release handle
in stop/detach routine or error paths. This removes the redundant
requests for mbox handle later during rproc start/attach. This also
allows to defer remoteproc driver's probe if mailbox is not probed yet.

Signed-off-by: Beleswar Padhi 
---
  drivers/remoteproc/ti_k3_r5_remoteproc.c | 74 +---
  1 file changed, 26 insertions(+), 48 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c 
b/drivers/remoteproc/ti_k3_r5_remoteproc.c
index 26362a509ae3c..7e02e3472ce25 100644
--- a/drivers/remoteproc/ti_k3_r5_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c
@@ -194,6 +194,10 @@ static void k3_r5_rproc_mbox_callback(struct mbox_client 
*client, void *data)
  const char *name = kproc->rproc->name;
  u32 msg = omap_mbox_message(data);
  +    /* Do not forward message to a detached core */


s/to/from

This is the receive side from the core.


+    if (kproc->rproc->state == RPROC_DETACHED)
+    return;
+


Do we need a similar check when sending messages to the core in
k3_r5_rproc_kick()? No one should be sending anything as they
all should have detached at this point, but something to double
check on.

Will add this in the next revision.



  dev_dbg(dev, "mbox msg: 0x%x\n", msg);
    switch (msg) {
@@ -399,12 +403,9 @@ static int k3_r5_rproc_request_mbox(struct rproc *rproc)
  client->knows_txdone = false;
    kproc->mbox = mbox_request_channel(client, 0);
-    if (IS_ERR(kproc->mbox)) {
-    ret = -EBUSY;
-    dev_err(dev, "mbox_request_channel failed: %ld\n",
-    PTR_ERR(kproc->mbox));
-    return ret;
-    }
+    if (IS_ERR(kproc->mbox))
+    return dev_err_probe(dev, PTR_ERR(kproc->mbox),
+ "mbox_request_channel failed\n");


This is good cleanup, but maybe something for its own patch.

I think this cleanup is dependent to this patch itself. The current patch moves 
the mbox_handle_request to probe routine. And the cleanup returns an 
-EDEFER_PROBE ERR code. So, this cleanup is only valid if the current patch is 
applied. Else, if this err code is returned at any point after creation of 
child devices, it could lead to a infinite loop[0]. Please correct me if I am 
wrong..?



Okay I see what you are saying, k3_r5_rproc_request_mbox() is now called from
probe() and not start() as it was before. Then you are correct.

Andrew


[0]: 
https://www.kernel.org/doc/html/v6.5-rc3/driver-api/driver-model/driver.html#callbacks



    /*
   * Ping the remote processor, this is only for sanity-sake for now;
@@ -552,10 +553,6 @@ static int k3_r5_rproc_start(struct rproc *rproc)
  u32 boot_addr;
  int ret;
  -    ret = k3_r5_rproc_request_mbox(rproc);
-    if (ret)
-    return ret;
-
  boot_addr = rproc->bootaddr;
  /* TODO: add boot_addr sanity checking */
  dev_dbg(dev, "booting R5F core using boot addr = 0x%x\n", boot_addr);
@@ -564,7 +561,7 @@ static int k3_r5_rproc_start(struct rproc *rproc)
  core = kproc->core;
  ret = ti_sci_proc_set_config(core->tsp, boot_addr, 0, 0);
  if (ret)
-    goto put_mbox;
+    return ret;
    /* unhalt/run all applicable cores */
  if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
@@ -580,13 +577,12 @@ static int k3_r5_rproc_start(struct rproc *rproc)
  if (core != core0 && core0->rproc->state == RPROC_OFFLINE) {
  dev_err(dev, "%s: can not start core 1 before core 0\n",
  __func__);
-    ret = -EPERM;
-    goto put_mbox;
+    return -EPERM;
  }
    ret = k3_r5_core_run(core);
  if (ret)
-    goto put_mbox;
+    return ret;
  }
    return 0;
@@ -596,8 +592,6 @@ static int k3_r5_rproc_start(struct rproc *rproc)
  if (k3_r5_core_halt(core))
  dev_warn(core->dev, "core halt back failed\n");
  }
-put_mbox:
-    mbox_free_channel(kproc->mbox);
  return ret;
  }
  @@ -658,8 +652,6 @@ static int k3_r5_rproc_stop(struct rproc *rproc)
  goto out;
  }
  -    mbox_free_channel(kproc->mbox);
-
  return 0;
    unroll_core_halt:
@@ -674,42 +666,22 @@ static int k3_r5_rproc_stop(struct rproc *rproc)
  /*
   * Attach to a running R5F remote processor (IPC-only mode)
   *
- * The R5F attach callback only needs to request the mailbox, the remote
- * processor is already booted, so there is no need to issue any TI-SCI
- * commands to boot the R5F cores in IPC-only mode. This callback is invoked
- * only in IPC-only mode.
+ * The R5F attach callback is a NOP. The remote processor is already booted, 
and
+ * all required resources have been acquired during probe routine, so there is
+ * no need to issue any TI-SCI commands to boot the R5F cores in IPC-only mode.
+ * This

Re: [PATCH] uprobe: Do not use UPROBE_SWBP_INSN as static initializer

2024-06-21 Thread Jiri Olsa
On Fri, Jun 21, 2024 at 02:01:50PM +0200, Oleg Nesterov wrote:
> On 06/20, Andrii Nakryiko wrote:
> >
> > On Thu, Jun 20, 2024 at 12:40 PM Oleg Nesterov  wrote:
> > >
> > > But I can't understand what does it do, it calls emit_break() and
> > > git grep -w emit_break finds nothing.
> > >
> >
> > It's DEF_EMIT_REG0I15_FORMAT(break, break_op) in
> > arch/loongarch/include/asm/inst.h
> >
> > A bunch of macro magic, but in the end it produces some constant
> > value, of course.
> 
> I see, thanks!
> 
> Then perhaps something like below?

lgtm, added loong arch list/folks

for context:
  https://lore.kernel.org/bpf/20240614174822.GA1185149@thelio-3990X/

thanks,
jirka

> 
> Oleg.
> 
> 
> --- x/arch/loongarch/include/asm/uprobes.h
> +++ x/arch/loongarch/include/asm/uprobes.h
> @@ -9,7 +9,7 @@ typedef u32 uprobe_opcode_t;
>  #define MAX_UINSN_BYTES  8
>  #define UPROBE_XOL_SLOT_BYTESMAX_UINSN_BYTES
>  
> -#define UPROBE_SWBP_INSN larch_insn_gen_break(BRK_UPROBE_BP)
> +#define UPROBE_SWBP_INSN (uprobe_opcode_t)(BRK_UPROBE_BP | (break_op << 
> 15))
>  #define UPROBE_SWBP_INSN_SIZELOONGARCH_INSN_SIZE
>  
>  #define UPROBE_XOLBP_INSNlarch_insn_gen_break(BRK_UPROBE_XOLBP)
> --- x/arch/loongarch/kernel/uprobes.c
> +++ x/arch/loongarch/kernel/uprobes.c
> @@ -7,6 +7,13 @@
>  
>  #define UPROBE_TRAP_NR   UINT_MAX
>  
> +static __init int __ck_insn(void)
> +{
> + BUG_ON(UPROBE_SWBP_INSN != larch_insn_gen_break(BRK_UPROBE_BP));
> + return 0;
> +}
> +late_initcall(__ck_insn);
> +
>  int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe,
>struct mm_struct *mm, unsigned long addr)
>  {
> 



Re: [PATCH v3 2/2] rust: add tracepoint support

2024-06-21 Thread Alice Ryhl
On Fri, Jun 21, 2024 at 12:35 PM Alice Ryhl  wrote:
>
> Make it possible to have Rust code call into tracepoints defined by C
> code. It is still required that the tracepoint is declared in a C
> header, and that this header is included in the input to bindgen.
>
> Signed-off-by: Alice Ryhl 
> ---
>  include/linux/tracepoint.h  | 18 +++-
>  include/trace/define_trace.h|  7 ++
>  rust/bindings/bindings_helper.h |  1 +
>  rust/kernel/lib.rs  |  1 +
>  rust/kernel/tracepoint.rs   | 47 
> +
>  5 files changed, 73 insertions(+), 1 deletion(-)
>
> diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
> index 689b6d71590e..d82af4d77c9f 100644
> --- a/include/linux/tracepoint.h
> +++ b/include/linux/tracepoint.h
> @@ -238,6 +238,20 @@ static inline struct tracepoint 
> *tracepoint_ptr_deref(tracepoint_ptr_t *p)
>  #define __DECLARE_TRACE_RCU(name, proto, args, cond)
>  #endif
>
> +/*
> + * Declare an exported function that Rust code can call to trigger this
> + * tracepoint. This function does not include the static branch; that is done
> + * in Rust to avoid a function call when the tracepoint is disabled.
> + */
> +#define DEFINE_RUST_DO_TRACE(name, proto, args)
> +#define DEFINE_RUST_DO_TRACE_REAL(name, proto, args)   \
> +   notrace void rust_do_trace_##name(proto)\
> +   {   \
> +   __DO_TRACE(name,\
> +   TP_ARGS(args),  \
> +   cpu_online(raw_smp_processor_id()), 0); \
> +   }
> +
>  /*
>   * Make sure the alignment of the structure in the __tracepoints section will
>   * not add unwanted padding between the beginning of the section and the
> @@ -253,6 +267,7 @@ static inline struct tracepoint 
> *tracepoint_ptr_deref(tracepoint_ptr_t *p)
> extern int __traceiter_##name(data_proto);  \
> DECLARE_STATIC_CALL(tp_func_##name, __traceiter_##name);\
> extern struct tracepoint __tracepoint_##name;   \
> +   extern void rust_do_trace_##name(proto);\
> static inline void trace_##name(proto)  \
> {   \
> if (static_key_false(&__tracepoint_##name.key)) \
> @@ -337,7 +352,8 @@ static inline struct tracepoint 
> *tracepoint_ptr_deref(tracepoint_ptr_t *p)
> void __probestub_##_name(void *__data, proto)   \
> {   \
> }   \
> -   DEFINE_STATIC_CALL(tp_func_##_name, __traceiter_##_name);
> +   DEFINE_STATIC_CALL(tp_func_##_name, __traceiter_##_name);   \
> +   DEFINE_RUST_DO_TRACE(_name, TP_PROTO(proto), TP_ARGS(args))
>
>  #define DEFINE_TRACE(name, proto, args)\
> DEFINE_TRACE_FN(name, NULL, NULL, PARAMS(proto), PARAMS(args));
> diff --git a/include/trace/define_trace.h b/include/trace/define_trace.h
> index 00723935dcc7..b47cc036acba 100644
> --- a/include/trace/define_trace.h
> +++ b/include/trace/define_trace.h
> @@ -72,6 +72,13 @@
>  #define DECLARE_TRACE(name, proto, args)   \
> DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
>
> +/* If requested, create helpers for calling these tracepoints from Rust. */
> +#ifdef CREATE_RUST_TRACE_POINTS
> +#undef DEFINE_RUST_DO_TRACE
> +#define DEFINE_RUST_DO_TRACE(name, proto, args)\
> +   DEFINE_RUST_DO_TRACE_REAL(name, PARAMS(proto), PARAMS(args))
> +#endif
> +
>  #undef TRACE_INCLUDE
>  #undef __TRACE_INCLUDE
>
> diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h

Hmm, I tried using the support where I have both events and hooks:

#define CREATE_TRACE_POINTS
#define CREATE_RUST_TRACE_POINTS
#include 
#include 

But it's not really working. Initially I thought that it's because I
need to undef DEFINE_RUST_DO_TRACE at the end of this file, but even
when I added that, I still get this error:

error: redefinition of 'str__rust_binder__trace_system_name'

Is the Rust support missing something, or is the answer just that you
can't have two files of the same name like this? Or am I doing
something else wrong?

Alice



Re: [PATCH] uprobe: Do not use UPROBE_SWBP_INSN as static initializer

2024-06-21 Thread Oleg Nesterov
On 06/20, Andrii Nakryiko wrote:
>
> On Thu, Jun 20, 2024 at 12:40 PM Oleg Nesterov  wrote:
> >
> > But I can't understand what does it do, it calls emit_break() and
> > git grep -w emit_break finds nothing.
> >
>
> It's DEF_EMIT_REG0I15_FORMAT(break, break_op) in
> arch/loongarch/include/asm/inst.h
>
> A bunch of macro magic, but in the end it produces some constant
> value, of course.

I see, thanks!

Then perhaps something like below?

Oleg.


--- x/arch/loongarch/include/asm/uprobes.h
+++ x/arch/loongarch/include/asm/uprobes.h
@@ -9,7 +9,7 @@ typedef u32 uprobe_opcode_t;
 #define MAX_UINSN_BYTES8
 #define UPROBE_XOL_SLOT_BYTES  MAX_UINSN_BYTES
 
-#define UPROBE_SWBP_INSN   larch_insn_gen_break(BRK_UPROBE_BP)
+#define UPROBE_SWBP_INSN   (uprobe_opcode_t)(BRK_UPROBE_BP | (break_op << 
15))
 #define UPROBE_SWBP_INSN_SIZE  LOONGARCH_INSN_SIZE
 
 #define UPROBE_XOLBP_INSN  larch_insn_gen_break(BRK_UPROBE_XOLBP)
--- x/arch/loongarch/kernel/uprobes.c
+++ x/arch/loongarch/kernel/uprobes.c
@@ -7,6 +7,13 @@
 
 #define UPROBE_TRAP_NR UINT_MAX
 
+static __init int __ck_insn(void)
+{
+   BUG_ON(UPROBE_SWBP_INSN != larch_insn_gen_break(BRK_UPROBE_BP));
+   return 0;
+}
+late_initcall(__ck_insn);
+
 int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe,
 struct mm_struct *mm, unsigned long addr)
 {




[PATCH] qdisc: fix NULL pointer dereference in perf_trace_qdisc_reset()

2024-06-21 Thread yskelg
From: Yunseong Kim 

In the TRACE_EVENT(qdisc_reset) NULL dereference occurred from

 qdisc->dev_queue->dev  ->name

This situation simulated from bunch of veths and Bluetooth dis/reconnection.

During qdisc initialization, qdisc was being set to noop_queue.
In veth_init_queue, the initial tx_num was reduced back to one,
causing the qdisc reset to be called with noop, which led to the kernel panic.

I think this will happen on the kernel version.
 Linux kernel version ≥ v6.7.10, ≥ v6.8 ≥ v6.9 and 6.10

This occurred from 51270d573a8d. I think this patch is absolutely 
necessary. Previously, It was showing not intended string value of name.

I've reproduced 3 time from my fedora 40 Debug Kernel with any other module 
and patched.

version: 6.10.0-0.rc2.20240608gitdc772f8237f9.29.fc41.aarch64+debug

[ 5287.164555] veth0_vlan: left promiscuous mode
[ 5287.164929] veth1_macvtap: left promiscuous mode
[ 5287.164950] veth0_macvtap: left promiscuous mode
[ 5287.164983] veth1_vlan: left promiscuous mode
[ 5287.165008] veth0_vlan: left promiscuous mode
[ 5287.165450] veth1_macvtap: left promiscuous mode
[ 5287.165472] veth0_macvtap: left promiscuous mode
[ 5287.165502] veth1_vlan: left promiscuous mode
…
[ 5297.598240] bridge0: port 2(bridge_slave_1) entered blocking state
[ 5297.598262] bridge0: port 2(bridge_slave_1) entered forwarding state
[ 5297.598296] bridge0: port 1(bridge_slave_0) entered blocking state
[ 5297.598313] bridge0: port 1(bridge_slave_0) entered forwarding state
[ 5297.616090] 8021q: adding VLAN 0 to HW filter on device bond0
[ 5297.620405] bridge0: port 1(bridge_slave_0) entered disabled state
[ 5297.620730] bridge0: port 2(bridge_slave_1) entered disabled state
[ 5297.627247] 8021q: adding VLAN 0 to HW filter on device team0
[ 5297.629636] bridge0: port 1(bridge_slave_0) entered blocking state
…
[ 5298.002798] bridge_slave_0: left promiscuous mode
[ 5298.002869] bridge0: port 1(bridge_slave_0) entered disabled state
[ 5298.309444] bond0 (unregistering): (slave bond_slave_0): Releasing backup 
interface
[ 5298.315206] bond0 (unregistering): (slave bond_slave_1): Releasing backup 
interface
[ 5298.320207] bond0 (unregistering): Released all slaves
[ 5298.354296] hsr_slave_0: left promiscuous mode
[ 5298.360750] hsr_slave_1: left promiscuous mode
[ 5298.374889] veth1_macvtap: left promiscuous mode
[ 5298.374931] veth0_macvtap: left promiscuous mode
[ 5298.374988] veth1_vlan: left promiscuous mode
[ 5298.375024] veth0_vlan: left promiscuous mode
[ 5299.109741] team0 (unregistering): Port device team_slave_1 removed
[ 5299.185870] team0 (unregistering): Port device team_slave_0 removed
…
[ 5300.155443] Bluetooth: hci3: unexpected cc 0x0c03 length: 249 > 1
[ 5300.155724] Bluetooth: hci3: unexpected cc 0x1003 length: 249 > 9
[ 5300.155988] Bluetooth: hci3: unexpected cc 0x1001 length: 249 > 9
….
[ 5301.075531] team0: Port device team_slave_1 added
[ 5301.085515] bridge0: port 1(bridge_slave_0) entered blocking state
[ 5301.085531] bridge0: port 1(bridge_slave_0) entered disabled state
[ 5301.085588] bridge_slave_0: entered allmulticast mode
[ 5301.085800] bridge_slave_0: entered promiscuous mode
[ 5301.095617] bridge0: port 1(bridge_slave_0) entered blocking state
[ 5301.095633] bridge0: port 1(bridge_slave_0) entered disabled state
…
[ 5301.149734] bond0: (slave bond_slave_0): Enslaving as an active interface 
with an up link
[ 5301.173234] bond0: (slave bond_slave_0): Enslaving as an active interface 
with an up link
[ 5301.180517] bond0: (slave bond_slave_1): Enslaving as an active interface 
with an up link
[ 5301.193481] hsr_slave_0: entered promiscuous mode
[ 5301.204425] hsr_slave_1: entered promiscuous mode
[ 5301.210172] debugfs: Directory 'hsr0' with parent 'hsr' already present!
[ 5301.210185] Cannot create hsr debugfs directory
[ 5301.224061] bond0: (slave bond_slave_1): Enslaving as an active interface 
with an up link
[ 5301.246901] bond0: (slave bond_slave_0): Enslaving as an active interface 
with an up link
[ 5301.255934] team0: Port device team_slave_0 added
[ 5301.256480] team0: Port device team_slave_1 added
[ 5301.256948] team0: Port device team_slave_0 added
…
[ 5301.435928] hsr_slave_0: entered promiscuous mode
[ 5301.446029] hsr_slave_1: entered promiscuous mode
[ 5301.455872] debugfs: Directory 'hsr0' with parent 'hsr' already present!
[ 5301.455884] Cannot create hsr debugfs directory
[ 5301.502664] hsr_slave_0: entered promiscuous mode
[ 5301.513675] hsr_slave_1: entered promiscuous mode
[ 5301.526155] debugfs: Directory 'hsr0' with parent 'hsr' already present!
[ 5301.526164] Cannot create hsr debugfs directory
[ 5301.563662] hsr_slave_0: entered promiscuous mode
[ 5301.576129] hsr_slave_1: entered promiscuous mode
[ 5301.580259] debugfs: Directory 'hsr0' with parent 'hsr' already present!
[ 5301.580270] Cannot create hsr debugfs directory
[ 5301.590269] 8021q: adding VLAN 0 to HW filter on device bond0

[ 5301.595872] KASAN: null-ptr-deref in range 
[0x0130-0

[PATCH v9 8/8] arm64: dts: qcom: Enable Q6v5 WCSS for ipq8074 SoC

2024-06-21 Thread Gokul Sriram Palanisamy
Enable remoteproc WCSS PIL driver with glink. Also,
configure shared memory and enables smp2p required for IPC.

Signed-off-by: Nikhil Prakash V 
Signed-off-by: Sricharan R 
Signed-off-by: Gokul Sriram Palanisamy 
---
 arch/arm64/boot/dts/qcom/ipq8074.dtsi | 80 +++
 1 file changed, 80 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi 
b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
index 92682d3c9478..b98766cce0d6 100644
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -108,6 +108,12 @@ memory@4ac0 {
reg = <0x0 0x4ac0 0x0 0x40>;
no-map;
};
+
+   q6_region: memory@4b00 {
+   no-map;
+   reg = <0x0 0x4b00 0x0 0x5f0>;
+   };
+
};
 
firmware {
@@ -117,6 +123,30 @@ scm {
};
};
 
+   wcss: smp2p-wcss {
+   compatible = "qcom,smp2p";
+   qcom,smem = <435>, <428>;
+
+   interrupt-parent = <&intc>;
+   interrupts = ;
+
+   mboxes = <&apcs_glb 9>;
+
+   qcom,local-pid = <0>;
+   qcom,remote-pid = <1>;
+
+   wcss_smp2p_out: master-kernel {
+   qcom,entry-name = "master-kernel";
+   #qcom,smem-state-cells = <1>;
+   };
+
+   wcss_smp2p_in: slave-kernel {
+   qcom,entry-name = "slave-kernel";
+   interrupt-controller;
+   #interrupt-cells = <2>;
+   };
+   };
+
soc: soc@0 {
#address-cells = <1>;
#size-cells = <1>;
@@ -824,6 +854,56 @@ frame@b128000 {
};
};
 
+   q6v5_wcss: remoteproc@cd0 {
+   compatible = "qcom,ipq8074-wcss-pil";
+   reg = <0x0cd0 0x4040>,
+ <0x004ab000 0x20>;
+   reg-names = "qdsp6",
+   "rmb";
+   qca,auto-restart;
+   qca,extended-intc;
+   interrupts-extended = <&intc 0 325 1>,
+ <&wcss_smp2p_in 0 0>,
+ <&wcss_smp2p_in 1 0>,
+ <&wcss_smp2p_in 2 0>,
+ <&wcss_smp2p_in 3 0>;
+   interrupt-names = "wdog",
+ "fatal",
+ "ready",
+ "handover",
+ "stop-ack";
+
+   resets = <&gcc GCC_WCSSAON_RESET>,
+<&gcc GCC_WCSS_BCR>,
+<&gcc GCC_WCSS_Q6_BCR>;
+
+   reset-names = "wcss_aon_reset",
+ "wcss_reset",
+ "wcss_q6_reset";
+
+   clocks = <&gcc GCC_PRNG_AHB_CLK>;
+   clock-names = "prng";
+
+   qcom,halt-regs = <&tcsr 0xa000 0xd000 0xe000>;
+
+   qcom,smem-states = <&wcss_smp2p_out 0>,
+  <&wcss_smp2p_out 1>;
+   qcom,smem-state-names = "shutdown",
+   "stop";
+
+   memory-region = <&q6_region>;
+
+   glink-edge {
+   interrupts = ;
+   qcom,remote-pid = <1>;
+   mboxes = <&apcs_glb 8>;
+
+   rpm_requests {
+   qcom,glink-channels = "rpm_requests";
+   };
+   };
+   };
+
pcie1: pcie@1000 {
compatible = "qcom,pcie-ipq8074";
reg = <0x1000 0xf1d>,
-- 
2.34.1




[PATCH v9 7/8] clk: qcom: Add WCSSAON reset

2024-06-21 Thread Gokul Sriram Palanisamy
Add WCSSAON reset required for Q6v5 on IPQ8074 SoC.

Signed-off-by: Nikhil Prakash V 
Signed-off-by: Sricharan R 
Signed-off-by: Gokul Sriram Palanisamy 
Acked-by: Stephen Boyd 
---
 drivers/clk/qcom/gcc-ipq8074.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
index 32fd01ef469a..d382d16b9c10 100644
--- a/drivers/clk/qcom/gcc-ipq8074.c
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -4712,6 +4712,7 @@ static const struct qcom_reset_map gcc_ipq8074_resets[] = 
{
[GCC_NSSPORT4_RESET] = { .reg = 0x68014, .bitmask = BIT(27) | 
GENMASK(9, 8) },
[GCC_NSSPORT5_RESET] = { .reg = 0x68014, .bitmask = BIT(28) | 
GENMASK(11, 10) },
[GCC_NSSPORT6_RESET] = { .reg = 0x68014, .bitmask = BIT(29) | 
GENMASK(13, 12) },
+   [GCC_WCSSAON_RESET] = { 0x59010, 0 },
 };
 
 static struct gdsc *gcc_ipq8074_gdscs[] = {
-- 
2.34.1




[PATCH v9 6/8] dt-bindings: clock: qcom: Add reset for WCSSAON

2024-06-21 Thread Gokul Sriram Palanisamy
Add binding for WCSSAON reset required for Q6v5 reset on IPQ8074 SoC.

Signed-off-by: Nikhil Prakash V 
Signed-off-by: Sricharan R 
Signed-off-by: Gokul Sriram Palanisamy 
Acked-by: Rob Herring 
Acked-by: Stephen Boyd 
---
 include/dt-bindings/clock/qcom,gcc-ipq8074.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/dt-bindings/clock/qcom,gcc-ipq8074.h 
b/include/dt-bindings/clock/qcom,gcc-ipq8074.h
index f9ea55811104..e47cbf7394aa 100644
--- a/include/dt-bindings/clock/qcom,gcc-ipq8074.h
+++ b/include/dt-bindings/clock/qcom,gcc-ipq8074.h
@@ -381,6 +381,7 @@
 #define GCC_NSSPORT4_RESET 143
 #define GCC_NSSPORT5_RESET 144
 #define GCC_NSSPORT6_RESET 145
+#define GCC_WCSSAON_RESET  146
 
 #define USB0_GDSC  0
 #define USB1_GDSC  1
-- 
2.34.1




[PATCH v9 5/8] remoteproc: qcom: Update regmap offsets for halt register

2024-06-21 Thread Gokul Sriram Palanisamy
Fixed issue in reading halt-regs parameter from device-tree.

Signed-off-by: Sricharan R 
Signed-off-by: Gokul Sriram Palanisamy 
---
 drivers/remoteproc/qcom_q6v5_wcss.c | 22 ++
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c 
b/drivers/remoteproc/qcom_q6v5_wcss.c
index 06936ca1d079..87b78eb15b86 100644
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -86,7 +86,7 @@
 #define TCSR_WCSS_CLK_MASK 0x1F
 #define TCSR_WCSS_CLK_ENABLE   0x14
 
-#define MAX_HALT_REG   3
+#define MAX_HALT_REG   4
 
 #define WCNSS_PAS_ID   6
 
@@ -154,6 +154,7 @@ struct wcss_data {
u32 version;
bool aon_reset_required;
bool wcss_q6_reset_required;
+   bool bcr_reset_required;
const char *ssr_name;
const char *sysmon_name;
int ssctl_id;
@@ -875,10 +876,13 @@ static int q6v5_wcss_init_reset(struct q6v5_wcss *wcss,
}
}
 
-   wcss->wcss_q6_bcr_reset = devm_reset_control_get_exclusive(dev, 
"wcss_q6_bcr_reset");
-   if (IS_ERR(wcss->wcss_q6_bcr_reset)) {
-   dev_err(wcss->dev, "unable to acquire wcss_q6_bcr_reset\n");
-   return PTR_ERR(wcss->wcss_q6_bcr_reset);
+   if (desc->bcr_reset_required) {
+   wcss->wcss_q6_bcr_reset = devm_reset_control_get_exclusive(dev,
+  
"wcss_q6_bcr_reset");
+   if (IS_ERR(wcss->wcss_q6_bcr_reset)) {
+   dev_err(wcss->dev, "unable to acquire 
wcss_q6_bcr_reset\n");
+   return PTR_ERR(wcss->wcss_q6_bcr_reset);
+   }
}
 
return 0;
@@ -928,9 +932,9 @@ static int q6v5_wcss_init_mmio(struct q6v5_wcss *wcss,
return -EINVAL;
}
 
-   wcss->halt_q6 = halt_reg[0];
-   wcss->halt_wcss = halt_reg[1];
-   wcss->halt_nc = halt_reg[2];
+   wcss->halt_q6 = halt_reg[1];
+   wcss->halt_wcss = halt_reg[2];
+   wcss->halt_nc = halt_reg[3];
 
return 0;
 }
@@ -1170,6 +1174,7 @@ static const struct wcss_data wcss_ipq8074_res_init = {
.crash_reason_smem = WCSS_CRASH_REASON,
.aon_reset_required = true,
.wcss_q6_reset_required = true,
+   .bcr_reset_required = false,
.ssr_name = "q6wcss",
.ops = &q6v5_wcss_ipq8074_ops,
.requires_force_stop = true,
@@ -1184,6 +1189,7 @@ static const struct wcss_data wcss_qcs404_res_init = {
.version = WCSS_QCS404,
.aon_reset_required = false,
.wcss_q6_reset_required = false,
+   .bcr_reset_required = true,
.ssr_name = "mpss",
.sysmon_name = "wcnss",
.ssctl_id = 0x12,
-- 
2.34.1




[PATCH v9 4/8] remoteproc: qcom: Add ssr subdevice identifier

2024-06-21 Thread Gokul Sriram Palanisamy
Add name for ssr subdevice on IPQ8074 SoC.

Signed-off-by: Nikhil Prakash V 
Signed-off-by: Sricharan R 
Signed-off-by: Gokul Sriram Palanisamy 
---
 drivers/remoteproc/qcom_q6v5_wcss.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c 
b/drivers/remoteproc/qcom_q6v5_wcss.c
index d8b79765d5c6..06936ca1d079 100644
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -1170,6 +1170,7 @@ static const struct wcss_data wcss_ipq8074_res_init = {
.crash_reason_smem = WCSS_CRASH_REASON,
.aon_reset_required = true,
.wcss_q6_reset_required = true,
+   .ssr_name = "q6wcss",
.ops = &q6v5_wcss_ipq8074_ops,
.requires_force_stop = true,
.need_mem_protection = true,
-- 
2.34.1




[PATCH v9 2/8] remoteproc: qcom: Add secure PIL support

2024-06-21 Thread Gokul Sriram Palanisamy
IPQ8074 uses secure PIL. Hence, adding the support for the same.

Signed-off-by: Nikhil Prakash V 
Signed-off-by: Sricharan R 
Signed-off-by: Gokul Sriram Palanisamy 
---
 drivers/remoteproc/qcom_q6v5_wcss.c | 43 +++--
 1 file changed, 40 insertions(+), 3 deletions(-)

diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c 
b/drivers/remoteproc/qcom_q6v5_wcss.c
index 366b19cbd994..e45e79d80238 100644
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "qcom_common.h"
 #include "qcom_pil_info.h"
 #include "qcom_q6v5.h"
@@ -86,6 +87,9 @@
 #define TCSR_WCSS_CLK_ENABLE   0x14
 
 #define MAX_HALT_REG   3
+
+#define WCNSS_PAS_ID   6
+
 enum {
WCSS_IPQ8074,
WCSS_QCS404,
@@ -134,6 +138,7 @@ struct q6v5_wcss {
unsigned int crash_reason_smem;
u32 version;
bool requires_force_stop;
+   bool need_mem_protection;
 
struct qcom_rproc_glink glink_subdev;
struct qcom_rproc_ssr ssr_subdev;
@@ -152,6 +157,7 @@ struct wcss_data {
int ssctl_id;
const struct rproc_ops *ops;
bool requires_force_stop;
+   bool need_mem_protection;
 };
 
 static int q6v5_wcss_reset(struct q6v5_wcss *wcss)
@@ -251,6 +257,15 @@ static int q6v5_wcss_start(struct rproc *rproc)
 
qcom_q6v5_prepare(&wcss->q6v5);
 
+   if (wcss->need_mem_protection) {
+   ret = qcom_scm_pas_auth_and_reset(WCNSS_PAS_ID);
+   if (ret) {
+   dev_err(wcss->dev, "wcss_reset failed\n");
+   return ret;
+   }
+   goto wait_for_reset;
+   }
+
/* Release Q6 and WCSS reset */
ret = reset_control_deassert(wcss->wcss_reset);
if (ret) {
@@ -285,6 +300,7 @@ static int q6v5_wcss_start(struct rproc *rproc)
if (ret)
goto wcss_q6_reset;
 
+wait_for_reset:
ret = qcom_q6v5_wait_for_start(&wcss->q6v5, 5 * HZ);
if (ret == -ETIMEDOUT)
dev_err(wcss->dev, "start timed out\n");
@@ -718,6 +734,15 @@ static int q6v5_wcss_stop(struct rproc *rproc)
struct q6v5_wcss *wcss = rproc->priv;
int ret;
 
+   if (wcss->need_mem_protection) {
+   ret = qcom_scm_pas_shutdown(WCNSS_PAS_ID);
+   if (ret) {
+   dev_err(wcss->dev, "not able to shutdown\n");
+   return ret;
+   }
+   goto pas_done;
+   }
+
/* WCSS powerdown */
if (wcss->requires_force_stop) {
ret = qcom_q6v5_request_stop(&wcss->q6v5, NULL);
@@ -742,6 +767,7 @@ static int q6v5_wcss_stop(struct rproc *rproc)
return ret;
}
 
+pas_done:
clk_disable_unprepare(wcss->prng_clk);
qcom_q6v5_unprepare(&wcss->q6v5);
 
@@ -765,9 +791,15 @@ static int q6v5_wcss_load(struct rproc *rproc, const 
struct firmware *fw)
struct q6v5_wcss *wcss = rproc->priv;
int ret;
 
-   ret = qcom_mdt_load_no_init(wcss->dev, fw, rproc->firmware,
-   0, wcss->mem_region, wcss->mem_phys,
-   wcss->mem_size, &wcss->mem_reloc);
+   if (wcss->need_mem_protection)
+   ret = qcom_mdt_load(wcss->dev, fw, rproc->firmware,
+   WCNSS_PAS_ID, wcss->mem_region,
+   wcss->mem_phys, wcss->mem_size,
+   &wcss->mem_reloc);
+   else
+   ret = qcom_mdt_load_no_init(wcss->dev, fw, rproc->firmware,
+   0, wcss->mem_region, wcss->mem_phys,
+   wcss->mem_size, &wcss->mem_reloc);
if (ret)
return ret;
 
@@ -1035,6 +1067,9 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
if (!desc)
return -EINVAL;
 
+   if (desc->need_mem_protection && !qcom_scm_is_available())
+   return -EPROBE_DEFER;
+
rproc = devm_rproc_alloc(&pdev->dev, pdev->name, desc->ops,
 desc->firmware_name, sizeof(*wcss));
if (!rproc) {
@@ -1048,6 +1083,7 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
 
wcss->version = desc->version;
wcss->requires_force_stop = desc->requires_force_stop;
+   wcss->need_mem_protection = desc->need_mem_protection;
 
ret = q6v5_wcss_init_mmio(wcss, pdev);
if (ret)
@@ -,6 +1147,7 @@ static const struct wcss_data wcss_ipq8074_res_init = {
.wcss_q6_reset_required = true,
.ops = &q6v5_wcss_ipq8074_ops,
.requires_force_stop = true,
+   .need_mem_protection = true,
 };
 
 static const struct wcss_data wcss_qcs404_res_init = {
-- 
2.34.1




[PATCH v9 1/8] remoteproc: qcom: Add PRNG proxy clock

2024-06-21 Thread Gokul Sriram Palanisamy
PRNG clock is needed by the secure PIL, support for the same
is added in subsequent patches.

Signed-off-by: Nikhil Prakash V 
Signed-off-by: Sricharan R 
Signed-off-by: Gokul Sriram Palanisamy 
---
 drivers/remoteproc/qcom_q6v5_wcss.c | 65 +
 1 file changed, 47 insertions(+), 18 deletions(-)

diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c 
b/drivers/remoteproc/qcom_q6v5_wcss.c
index 94f68c919ee6..366b19cbd994 100644
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -91,19 +91,6 @@ enum {
WCSS_QCS404,
 };
 
-struct wcss_data {
-   const char *firmware_name;
-   unsigned int crash_reason_smem;
-   u32 version;
-   bool aon_reset_required;
-   bool wcss_q6_reset_required;
-   const char *ssr_name;
-   const char *sysmon_name;
-   int ssctl_id;
-   const struct rproc_ops *ops;
-   bool requires_force_stop;
-};
-
 struct q6v5_wcss {
struct device *dev;
 
@@ -128,6 +115,7 @@ struct q6v5_wcss {
struct clk *qdsp6ss_xo_cbcr;
struct clk *qdsp6ss_core_gfmux;
struct clk *lcc_bcr_sleep;
+   struct clk *prng_clk;
struct regulator *cx_supply;
struct qcom_sysmon *sysmon;
 
@@ -151,6 +139,21 @@ struct q6v5_wcss {
struct qcom_rproc_ssr ssr_subdev;
 };
 
+struct wcss_data {
+   int (*init_clock)(struct q6v5_wcss *wcss);
+   int (*init_regulator)(struct q6v5_wcss *wcss);
+   const char *firmware_name;
+   unsigned int crash_reason_smem;
+   u32 version;
+   bool aon_reset_required;
+   bool wcss_q6_reset_required;
+   const char *ssr_name;
+   const char *sysmon_name;
+   int ssctl_id;
+   const struct rproc_ops *ops;
+   bool requires_force_stop;
+};
+
 static int q6v5_wcss_reset(struct q6v5_wcss *wcss)
 {
int ret;
@@ -240,6 +243,12 @@ static int q6v5_wcss_start(struct rproc *rproc)
struct q6v5_wcss *wcss = rproc->priv;
int ret;
 
+   ret = clk_prepare_enable(wcss->prng_clk);
+   if (ret) {
+   dev_err(wcss->dev, "prng clock enable failed\n");
+   return ret;
+   }
+
qcom_q6v5_prepare(&wcss->q6v5);
 
/* Release Q6 and WCSS reset */
@@ -733,6 +742,7 @@ static int q6v5_wcss_stop(struct rproc *rproc)
return ret;
}
 
+   clk_disable_unprepare(wcss->prng_clk);
qcom_q6v5_unprepare(&wcss->q6v5);
 
return 0;
@@ -899,7 +909,21 @@ static int q6v5_alloc_memory_region(struct q6v5_wcss *wcss)
return 0;
 }
 
-static int q6v5_wcss_init_clock(struct q6v5_wcss *wcss)
+static int ipq8074_init_clock(struct q6v5_wcss *wcss)
+{
+   int ret;
+
+   wcss->prng_clk = devm_clk_get(wcss->dev, "prng");
+   if (IS_ERR(wcss->prng_clk)) {
+   ret = PTR_ERR(wcss->prng_clk);
+   if (ret != -EPROBE_DEFER)
+   dev_err(wcss->dev, "Failed to get prng clock\n");
+   return ret;
+   }
+   return 0;
+}
+
+static int qcs404_init_clock(struct q6v5_wcss *wcss)
 {
int ret;
 
@@ -989,7 +1013,7 @@ static int q6v5_wcss_init_clock(struct q6v5_wcss *wcss)
return 0;
 }
 
-static int q6v5_wcss_init_regulator(struct q6v5_wcss *wcss)
+static int qcs404_init_regulator(struct q6v5_wcss *wcss)
 {
wcss->cx_supply = devm_regulator_get(wcss->dev, "cx");
if (IS_ERR(wcss->cx_supply))
@@ -1033,12 +1057,14 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
if (ret)
return ret;
 
-   if (wcss->version == WCSS_QCS404) {
-   ret = q6v5_wcss_init_clock(wcss);
+   if (desc->init_clock) {
+   ret = desc->init_clock(wcss);
if (ret)
return ret;
+   }
 
-   ret = q6v5_wcss_init_regulator(wcss);
+   if (desc->init_regulator) {
+   ret = desc->init_regulator(wcss);
if (ret)
return ret;
}
@@ -1078,6 +1104,7 @@ static void q6v5_wcss_remove(struct platform_device *pdev)
 }
 
 static const struct wcss_data wcss_ipq8074_res_init = {
+   .init_clock = ipq8074_init_clock,
.firmware_name = "IPQ8074/q6_fw.mdt",
.crash_reason_smem = WCSS_CRASH_REASON,
.aon_reset_required = true,
@@ -1087,6 +1114,8 @@ static const struct wcss_data wcss_ipq8074_res_init = {
 };
 
 static const struct wcss_data wcss_qcs404_res_init = {
+   .init_clock = qcs404_init_clock,
+   .init_regulator = qcs404_init_regulator,
.crash_reason_smem = WCSS_CRASH_REASON,
.firmware_name = "wcnss.mdt",
.version = WCSS_QCS404,
-- 
2.34.1




[PATCH v9 3/8] remoteproc: qcom: Add support for split q6 + m3 wlan firmware

2024-06-21 Thread Gokul Sriram Palanisamy
IPQ8074 supports split firmware for q6 and m3 as well.
So add support for loading the m3 firmware before q6.
Now the drivers works fine for both split and unified
firmwares.

Signed-off-by: Nikhil Prakash V 
Signed-off-by: Sricharan R 
Signed-off-by: Gokul Sriram Palanisamy 
---
 drivers/remoteproc/qcom_q6v5_wcss.c | 33 +
 1 file changed, 29 insertions(+), 4 deletions(-)

diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c 
b/drivers/remoteproc/qcom_q6v5_wcss.c
index e45e79d80238..d8b79765d5c6 100644
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -139,6 +139,7 @@ struct q6v5_wcss {
u32 version;
bool requires_force_stop;
bool need_mem_protection;
+   const char *m3_firmware_name;
 
struct qcom_rproc_glink glink_subdev;
struct qcom_rproc_ssr ssr_subdev;
@@ -147,7 +148,8 @@ struct q6v5_wcss {
 struct wcss_data {
int (*init_clock)(struct q6v5_wcss *wcss);
int (*init_regulator)(struct q6v5_wcss *wcss);
-   const char *firmware_name;
+   const char *q6_firmware_name;
+   const char *m3_firmware_name;
unsigned int crash_reason_smem;
u32 version;
bool aon_reset_required;
@@ -789,8 +791,29 @@ static void *q6v5_wcss_da_to_va(struct rproc *rproc, u64 
da, size_t len, bool *i
 static int q6v5_wcss_load(struct rproc *rproc, const struct firmware *fw)
 {
struct q6v5_wcss *wcss = rproc->priv;
+   const struct firmware *m3_fw;
int ret;
 
+   if (wcss->m3_firmware_name) {
+   ret = request_firmware(&m3_fw, wcss->m3_firmware_name,
+  wcss->dev);
+   if (ret)
+   goto skip_m3;
+
+   ret = qcom_mdt_load_no_init(wcss->dev, m3_fw,
+   wcss->m3_firmware_name, 0,
+   wcss->mem_region, wcss->mem_phys,
+   wcss->mem_size, &wcss->mem_reloc);
+
+   release_firmware(m3_fw);
+
+   if (ret) {
+   dev_err(wcss->dev, "can't load m3_fw.bXX\n");
+   return ret;
+   }
+   }
+
+skip_m3:
if (wcss->need_mem_protection)
ret = qcom_mdt_load(wcss->dev, fw, rproc->firmware,
WCNSS_PAS_ID, wcss->mem_region,
@@ -1071,7 +1094,7 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
return -EPROBE_DEFER;
 
rproc = devm_rproc_alloc(&pdev->dev, pdev->name, desc->ops,
-desc->firmware_name, sizeof(*wcss));
+desc->q6_firmware_name, sizeof(*wcss));
if (!rproc) {
dev_err(&pdev->dev, "failed to allocate rproc\n");
return -ENOMEM;
@@ -1084,6 +1107,7 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
wcss->version = desc->version;
wcss->requires_force_stop = desc->requires_force_stop;
wcss->need_mem_protection = desc->need_mem_protection;
+   wcss->m3_firmware_name = desc->m3_firmware_name;
 
ret = q6v5_wcss_init_mmio(wcss, pdev);
if (ret)
@@ -1141,7 +1165,8 @@ static void q6v5_wcss_remove(struct platform_device *pdev)
 
 static const struct wcss_data wcss_ipq8074_res_init = {
.init_clock = ipq8074_init_clock,
-   .firmware_name = "IPQ8074/q6_fw.mdt",
+   .q6_firmware_name = "IPQ8074/q6_fw.mdt",
+   .m3_firmware_name = "IPQ8074/m3_fw.mdt",
.crash_reason_smem = WCSS_CRASH_REASON,
.aon_reset_required = true,
.wcss_q6_reset_required = true,
@@ -1154,7 +1179,7 @@ static const struct wcss_data wcss_qcs404_res_init = {
.init_clock = qcs404_init_clock,
.init_regulator = qcs404_init_regulator,
.crash_reason_smem = WCSS_CRASH_REASON,
-   .firmware_name = "wcnss.mdt",
+   .q6_firmware_name = "wcnss.mdt",
.version = WCSS_QCS404,
.aon_reset_required = false,
.wcss_q6_reset_required = false,
-- 
2.34.1




[PATCH v9 0/8] remoteproc: qcom: q6v5-wcss: Add support for secure pil

2024-06-21 Thread Gokul Sriram Palanisamy
IPQ8074 needs support for secure pil as well.
Also, currently only unified firmware is supported.
IPQ8074 supports split firmware for q6 and m3, so
adding support for that.

changes since v8:
 - Rebased on top of Linux 6.10-rc4

Gokul Sriram Palanisamy (8):
  remoteproc: qcom: Add PRNG proxy clock
  remoteproc: qcom: Add secure PIL support
  remoteproc: qcom: Add support for split q6 + m3 wlan firmware
  remoteproc: qcom: Add ssr subdevice identifier
  remoteproc: qcom: Update regmap offsets for halt register
  dt-bindings: clock: qcom: Add reset for WCSSAON
  clk: qcom: Add WCSSAON reset
  arm64: dts: qcom: Enable Q6v5 WCSS for ipq8074 SoC

 arch/arm64/boot/dts/qcom/ipq8074.dtsi|  80 +
 drivers/clk/qcom/gcc-ipq8074.c   |   1 +
 drivers/remoteproc/qcom_q6v5_wcss.c  | 162 +++
 include/dt-bindings/clock/qcom,gcc-ipq8074.h |   1 +
 4 files changed, 212 insertions(+), 32 deletions(-)

-- 
2.34.1




[PATCH v7 36/38] s390/unwind: Disable KMSAN checks

2024-06-21 Thread Ilya Leoshkevich
The unwind code can read uninitialized frames. Furthermore, even in
the good case, KMSAN does not emit shadow for backchains. Therefore
disable it for the unwinding functions.

Reviewed-by: Alexander Potapenko 
Acked-by: Heiko Carstens 
Signed-off-by: Ilya Leoshkevich 
---
 arch/s390/kernel/unwind_bc.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/s390/kernel/unwind_bc.c b/arch/s390/kernel/unwind_bc.c
index 0ece156fdd7c..cd44be2b6ce8 100644
--- a/arch/s390/kernel/unwind_bc.c
+++ b/arch/s390/kernel/unwind_bc.c
@@ -49,6 +49,8 @@ static inline bool is_final_pt_regs(struct unwind_state 
*state,
   READ_ONCE_NOCHECK(regs->psw.mask) & PSW_MASK_PSTATE;
 }
 
+/* Avoid KMSAN false positives from touching uninitialized frames. */
+__no_kmsan_checks
 bool unwind_next_frame(struct unwind_state *state)
 {
struct stack_info *info = &state->stack_info;
@@ -118,6 +120,8 @@ bool unwind_next_frame(struct unwind_state *state)
 }
 EXPORT_SYMBOL_GPL(unwind_next_frame);
 
+/* Avoid KMSAN false positives from touching uninitialized frames. */
+__no_kmsan_checks
 void __unwind_start(struct unwind_state *state, struct task_struct *task,
struct pt_regs *regs, unsigned long first_frame)
 {
-- 
2.45.1




[PATCH v7 33/38] s390/traps: Unpoison the kernel_stack_overflow()'s pt_regs

2024-06-21 Thread Ilya Leoshkevich
This is normally done by the generic entry code, but the
kernel_stack_overflow() flow bypasses it.

Reviewed-by: Alexander Potapenko 
Acked-by: Heiko Carstens 
Signed-off-by: Ilya Leoshkevich 
---
 arch/s390/kernel/traps.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 52578b5cecbd..dde69d2a64f0 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -262,6 +263,11 @@ static void monitor_event_exception(struct pt_regs *regs)
 
 void kernel_stack_overflow(struct pt_regs *regs)
 {
+   /*
+* Normally regs are unpoisoned by the generic entry code, but
+* kernel_stack_overflow() is a rare case that is called bypassing it.
+*/
+   kmsan_unpoison_entry_regs(regs);
bust_spinlocks(1);
printk("Kernel stack overflow.\n");
show_regs(regs);
-- 
2.45.1




[PATCH v7 37/38] s390/kmsan: Implement the architecture-specific functions

2024-06-21 Thread Ilya Leoshkevich
arch_kmsan_get_meta_or_null() finds the lowcore shadow by querying the
prefix and calling kmsan_get_metadata() again.

kmsan_virt_addr_valid() delegates to virt_addr_valid().

Acked-by: Alexander Gordeev 
Reviewed-by: Alexander Potapenko 
Signed-off-by: Ilya Leoshkevich 
---
 arch/s390/include/asm/kmsan.h | 59 +++
 1 file changed, 59 insertions(+)
 create mode 100644 arch/s390/include/asm/kmsan.h

diff --git a/arch/s390/include/asm/kmsan.h b/arch/s390/include/asm/kmsan.h
new file mode 100644
index ..27db65fbf3f6
--- /dev/null
+++ b/arch/s390/include/asm/kmsan.h
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_S390_KMSAN_H
+#define _ASM_S390_KMSAN_H
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef MODULE
+
+static inline bool is_lowcore_addr(void *addr)
+{
+   return addr >= (void *)&S390_lowcore &&
+  addr < (void *)(&S390_lowcore + 1);
+}
+
+static inline void *arch_kmsan_get_meta_or_null(void *addr, bool is_origin)
+{
+   if (is_lowcore_addr(addr)) {
+   /*
+* Different lowcores accessed via S390_lowcore are described
+* by the same struct page. Resolve the prefix manually in
+* order to get a distinct struct page.
+*/
+   addr += (void *)lowcore_ptr[raw_smp_processor_id()] -
+   (void *)&S390_lowcore;
+   if (KMSAN_WARN_ON(is_lowcore_addr(addr)))
+   return NULL;
+   return kmsan_get_metadata(addr, is_origin);
+   }
+   return NULL;
+}
+
+static inline bool kmsan_virt_addr_valid(void *addr)
+{
+   bool ret;
+
+   /*
+* pfn_valid() relies on RCU, and may call into the scheduler on exiting
+* the critical section. However, this would result in recursion with
+* KMSAN. Therefore, disable preemption here, and re-enable preemption
+* below while suppressing reschedules to avoid recursion.
+*
+* Note, this sacrifices occasionally breaking scheduling guarantees.
+* Although, a kernel compiled with KMSAN has already given up on any
+* performance guarantees due to being heavily instrumented.
+*/
+   preempt_disable();
+   ret = virt_addr_valid(addr);
+   preempt_enable_no_resched();
+
+   return ret;
+}
+
+#endif /* !MODULE */
+
+#endif /* _ASM_S390_KMSAN_H */
-- 
2.45.1




[PATCH v7 35/38] s390/uaccess: Add the missing linux/instrumented.h #include

2024-06-21 Thread Ilya Leoshkevich
uaccess.h uses instrument_get_user() and instrument_put_user(), which
are defined in linux/instrumented.h. Currently we get this header from
somewhere else by accident; prefer to be explicit about it and include
it directly.

Suggested-by: Alexander Potapenko 
Reviewed-by: Alexander Potapenko 
Signed-off-by: Ilya Leoshkevich 
---
 arch/s390/include/asm/uaccess.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h
index 70f0edc00c2a..9213be0529ee 100644
--- a/arch/s390/include/asm/uaccess.h
+++ b/arch/s390/include/asm/uaccess.h
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 
 void debug_user_asce(int exit);
 
-- 
2.45.1




[PATCH v7 32/38] s390/string: Add KMSAN support

2024-06-21 Thread Ilya Leoshkevich
Add KMSAN support for the s390 implementations of the string functions.
Do this similar to how it's already done for KASAN, except that the
optimized memset{16,32,64}() functions need to be disabled: it's
important for KMSAN to know that they initialized something.

The way boot code is built with regard to string functions is
problematic, since most files think it's configured with sanitizers,
but boot/string.c doesn't. This creates various problems with the
memset64() definitions, depending on whether the code is built with
sanitizers or fortify. This should probably be streamlined, but in the
meantime resolve the issues by introducing the IN_BOOT_STRING_C macro,
similar to the existing IN_ARCH_STRING_C macro.

Reviewed-by: Alexander Potapenko 
Acked-by: Heiko Carstens 
Signed-off-by: Ilya Leoshkevich 
---
 arch/s390/boot/string.c| 16 
 arch/s390/include/asm/string.h | 20 +++-
 2 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/arch/s390/boot/string.c b/arch/s390/boot/string.c
index faccb33b462c..f6b9b1df48a8 100644
--- a/arch/s390/boot/string.c
+++ b/arch/s390/boot/string.c
@@ -1,11 +1,18 @@
 // SPDX-License-Identifier: GPL-2.0
+#define IN_BOOT_STRING_C 1
 #include 
 #include 
 #include 
 #undef CONFIG_KASAN
 #undef CONFIG_KASAN_GENERIC
+#undef CONFIG_KMSAN
 #include "../lib/string.c"
 
+/*
+ * Duplicate some functions from the common lib/string.c
+ * instead of fully including it.
+ */
+
 int strncmp(const char *cs, const char *ct, size_t count)
 {
unsigned char c1, c2;
@@ -22,6 +29,15 @@ int strncmp(const char *cs, const char *ct, size_t count)
return 0;
 }
 
+void *memset64(uint64_t *s, uint64_t v, size_t count)
+{
+   uint64_t *xs = s;
+
+   while (count--)
+   *xs++ = v;
+   return s;
+}
+
 char *skip_spaces(const char *str)
 {
while (isspace(*str))
diff --git a/arch/s390/include/asm/string.h b/arch/s390/include/asm/string.h
index 351685de53d2..2ab868cbae6c 100644
--- a/arch/s390/include/asm/string.h
+++ b/arch/s390/include/asm/string.h
@@ -15,15 +15,12 @@
 #define __HAVE_ARCH_MEMCPY /* gcc builtin & arch function */
 #define __HAVE_ARCH_MEMMOVE/* gcc builtin & arch function */
 #define __HAVE_ARCH_MEMSET /* gcc builtin & arch function */
-#define __HAVE_ARCH_MEMSET16   /* arch function */
-#define __HAVE_ARCH_MEMSET32   /* arch function */
-#define __HAVE_ARCH_MEMSET64   /* arch function */
 
 void *memcpy(void *dest, const void *src, size_t n);
 void *memset(void *s, int c, size_t n);
 void *memmove(void *dest, const void *src, size_t n);
 
-#ifndef CONFIG_KASAN
+#if !defined(CONFIG_KASAN) && !defined(CONFIG_KMSAN)
 #define __HAVE_ARCH_MEMCHR /* inline & arch function */
 #define __HAVE_ARCH_MEMCMP /* arch function */
 #define __HAVE_ARCH_MEMSCAN/* inline & arch function */
@@ -36,6 +33,9 @@ void *memmove(void *dest, const void *src, size_t n);
 #define __HAVE_ARCH_STRNCPY/* arch function */
 #define __HAVE_ARCH_STRNLEN/* inline & arch function */
 #define __HAVE_ARCH_STRSTR /* arch function */
+#define __HAVE_ARCH_MEMSET16   /* arch function */
+#define __HAVE_ARCH_MEMSET32   /* arch function */
+#define __HAVE_ARCH_MEMSET64   /* arch function */
 
 /* Prototypes for non-inlined arch strings functions. */
 int memcmp(const void *s1, const void *s2, size_t n);
@@ -44,7 +44,7 @@ size_t strlcat(char *dest, const char *src, size_t n);
 char *strncat(char *dest, const char *src, size_t n);
 char *strncpy(char *dest, const char *src, size_t n);
 char *strstr(const char *s1, const char *s2);
-#endif /* !CONFIG_KASAN */
+#endif /* !defined(CONFIG_KASAN) && !defined(CONFIG_KMSAN) */
 
 #undef __HAVE_ARCH_STRCHR
 #undef __HAVE_ARCH_STRNCHR
@@ -74,20 +74,30 @@ void *__memset16(uint16_t *s, uint16_t v, size_t count);
 void *__memset32(uint32_t *s, uint32_t v, size_t count);
 void *__memset64(uint64_t *s, uint64_t v, size_t count);
 
+#ifdef __HAVE_ARCH_MEMSET16
 static inline void *memset16(uint16_t *s, uint16_t v, size_t count)
 {
return __memset16(s, v, count * sizeof(v));
 }
+#endif
 
+#ifdef __HAVE_ARCH_MEMSET32
 static inline void *memset32(uint32_t *s, uint32_t v, size_t count)
 {
return __memset32(s, v, count * sizeof(v));
 }
+#endif
 
+#ifdef __HAVE_ARCH_MEMSET64
+#ifdef IN_BOOT_STRING_C
+void *memset64(uint64_t *s, uint64_t v, size_t count);
+#else
 static inline void *memset64(uint64_t *s, uint64_t v, size_t count)
 {
return __memset64(s, v, count * sizeof(v));
 }
+#endif
+#endif
 
 #if !defined(IN_ARCH_STRING_C) && (!defined(CONFIG_FORTIFY_SOURCE) || 
defined(__NO_FORTIFY))
 
-- 
2.45.1




[PATCH v7 30/38] s390/irqflags: Do not instrument arch_local_irq_*() with KMSAN

2024-06-21 Thread Ilya Leoshkevich
Lockdep generates the following false positives with KMSAN on s390x:

[6.063666] DEBUG_LOCKS_WARN_ON(lockdep_hardirqs_enabled())
[ ...]
[6.577050] Call Trace:
[6.619637]  [<0690d2de>] check_flags+0x1fe/0x210
[6.665411] ([<0690d2da>] check_flags+0x1fa/0x210)
[6.707478]  [<006cec1a>] lock_acquire+0x2ca/0xce0
[6.749959]  [<069820ea>] _raw_spin_lock_irqsave+0xea/0x190
[6.794912]  [<041fc988>] __stack_depot_save+0x218/0x5b0
[6.838420]  [<0197affe>] __msan_poison_alloca+0xfe/0x1a0
[6.882985]  [<07c5827c>] start_kernel+0x70c/0xd50
[6.927454]  [<00100036>] startup_continue+0x36/0x40

Between trace_hardirqs_on() and `stosm __mask, 3` lockdep thinks that
interrupts are on, but on the CPU they are still off. KMSAN
instrumentation takes spinlocks, giving lockdep a chance to see and
complain about this discrepancy.

KMSAN instrumentation is inserted in order to poison the __mask
variable. Disable instrumentation in the respective functions. They are
very small and it's easy to see that no important metadata updates are
lost because of this.

Reviewed-by: Alexander Potapenko 
Signed-off-by: Ilya Leoshkevich 
---
 arch/s390/include/asm/irqflags.h | 17 ++---
 drivers/s390/char/sclp.c |  2 +-
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/arch/s390/include/asm/irqflags.h b/arch/s390/include/asm/irqflags.h
index 02427b205c11..bcab456dfb80 100644
--- a/arch/s390/include/asm/irqflags.h
+++ b/arch/s390/include/asm/irqflags.h
@@ -37,12 +37,18 @@ static __always_inline void __arch_local_irq_ssm(unsigned 
long flags)
asm volatile("ssm   %0" : : "Q" (flags) : "memory");
 }
 
-static __always_inline unsigned long arch_local_save_flags(void)
+#ifdef CONFIG_KMSAN
+#define arch_local_irq_attributes noinline notrace __no_sanitize_memory 
__maybe_unused
+#else
+#define arch_local_irq_attributes __always_inline
+#endif
+
+static arch_local_irq_attributes unsigned long arch_local_save_flags(void)
 {
return __arch_local_irq_stnsm(0xff);
 }
 
-static __always_inline unsigned long arch_local_irq_save(void)
+static arch_local_irq_attributes unsigned long arch_local_irq_save(void)
 {
return __arch_local_irq_stnsm(0xfc);
 }
@@ -52,7 +58,12 @@ static __always_inline void arch_local_irq_disable(void)
arch_local_irq_save();
 }
 
-static __always_inline void arch_local_irq_enable(void)
+static arch_local_irq_attributes void arch_local_irq_enable_external(void)
+{
+   __arch_local_irq_stosm(0x01);
+}
+
+static arch_local_irq_attributes void arch_local_irq_enable(void)
 {
__arch_local_irq_stosm(0x03);
 }
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index d53ee34d398f..fb1d9949adca 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -736,7 +736,7 @@ sclp_sync_wait(void)
cr0_sync.val = cr0.val & ~CR0_IRQ_SUBCLASS_MASK;
cr0_sync.val |= 1UL << (63 - 54);
local_ctl_load(0, &cr0_sync);
-   __arch_local_irq_stosm(0x01);
+   arch_local_irq_enable_external();
/* Loop until driver state indicates finished request */
while (sclp_running_state != sclp_running_state_idle) {
/* Check for expired request timer */
-- 
2.45.1




[PATCH v7 28/38] s390/diag: Unpoison diag224() output buffer

2024-06-21 Thread Ilya Leoshkevich
Diagnose 224 stores 4k bytes, which currently cannot be deduced from
the inline assembly constraints. This leads to KMSAN false positives.

Fix the constraints by using a 4k-sized struct instead of a raw
pointer. While at it, prettify them too.

Suggested-by: Heiko Carstens 
Reviewed-by: Alexander Potapenko 
Signed-off-by: Ilya Leoshkevich 
---
 arch/s390/kernel/diag.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/s390/kernel/diag.c b/arch/s390/kernel/diag.c
index 8dee9aa0ec95..8a7009618ba7 100644
--- a/arch/s390/kernel/diag.c
+++ b/arch/s390/kernel/diag.c
@@ -278,12 +278,14 @@ int diag224(void *ptr)
int rc = -EOPNOTSUPP;
 
diag_stat_inc(DIAG_STAT_X224);
-   asm volatile(
-   "   diag%1,%2,0x224\n"
-   "0: lhi %0,0x0\n"
+   asm volatile("\n"
+   "   diag%[type],%[addr],0x224\n"
+   "0: lhi %[rc],0\n"
"1:\n"
EX_TABLE(0b,1b)
-   : "+d" (rc) :"d" (0), "d" (addr) : "memory");
+   : [rc] "+d" (rc)
+   , "=m" (*(struct { char buf[PAGE_SIZE]; } *)ptr)
+   : [type] "d" (0), [addr] "d" (addr));
return rc;
 }
 EXPORT_SYMBOL(diag224);
-- 
2.45.1




[PATCH v7 31/38] s390/mm: Define KMSAN metadata for vmalloc and modules

2024-06-21 Thread Ilya Leoshkevich
The pages for the KMSAN metadata associated with most kernel mappings
are taken from memblock by the common code. However, vmalloc and module
metadata needs to be defined by the architectures.

Be a little bit more careful than x86: allocate exactly MODULES_LEN
for the module shadow and origins, and then take 2/3 of vmalloc for
the vmalloc shadow and origins. This ensures that users passing small
vmalloc= values on the command line do not cause module metadata
collisions.

Reviewed-by: Alexander Potapenko 
Acked-by: Alexander Gordeev 
Acked-by: Heiko Carstens 
Signed-off-by: Ilya Leoshkevich 
---
 arch/s390/boot/startup.c|  7 +++
 arch/s390/include/asm/pgtable.h | 12 
 2 files changed, 19 insertions(+)

diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c
index 48ef5fe5c08a..d6b0d114939a 100644
--- a/arch/s390/boot/startup.c
+++ b/arch/s390/boot/startup.c
@@ -301,11 +301,18 @@ static unsigned long setup_kernel_memory_layout(unsigned 
long kernel_size)
MODULES_END = round_down(kernel_start, _SEGMENT_SIZE);
MODULES_VADDR = MODULES_END - MODULES_LEN;
VMALLOC_END = MODULES_VADDR;
+   if (IS_ENABLED(CONFIG_KMSAN))
+   VMALLOC_END -= MODULES_LEN * 2;
 
/* allow vmalloc area to occupy up to about 1/2 of the rest virtual 
space left */
vsize = (VMALLOC_END - FIXMAP_SIZE) / 2;
vsize = round_down(vsize, _SEGMENT_SIZE);
vmalloc_size = min(vmalloc_size, vsize);
+   if (IS_ENABLED(CONFIG_KMSAN)) {
+   /* take 2/3 of vmalloc area for KMSAN shadow and origins */
+   vmalloc_size = round_down(vmalloc_size / 3, _SEGMENT_SIZE);
+   VMALLOC_END -= vmalloc_size * 2;
+   }
VMALLOC_START = VMALLOC_END - vmalloc_size;
 
__memcpy_real_area = round_down(VMALLOC_START - MEMCPY_REAL_SIZE, 
PAGE_SIZE);
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index 70b6ee557eb2..fb6870384b97 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -107,6 +107,18 @@ static inline int is_module_addr(void *addr)
return 1;
 }
 
+#ifdef CONFIG_KMSAN
+#define KMSAN_VMALLOC_SIZE (VMALLOC_END - VMALLOC_START)
+#define KMSAN_VMALLOC_SHADOW_START VMALLOC_END
+#define KMSAN_VMALLOC_SHADOW_END (KMSAN_VMALLOC_SHADOW_START + 
KMSAN_VMALLOC_SIZE)
+#define KMSAN_VMALLOC_ORIGIN_START KMSAN_VMALLOC_SHADOW_END
+#define KMSAN_VMALLOC_ORIGIN_END (KMSAN_VMALLOC_ORIGIN_START + 
KMSAN_VMALLOC_SIZE)
+#define KMSAN_MODULES_SHADOW_START KMSAN_VMALLOC_ORIGIN_END
+#define KMSAN_MODULES_SHADOW_END (KMSAN_MODULES_SHADOW_START + MODULES_LEN)
+#define KMSAN_MODULES_ORIGIN_START KMSAN_MODULES_SHADOW_END
+#define KMSAN_MODULES_ORIGIN_END (KMSAN_MODULES_ORIGIN_START + MODULES_LEN)
+#endif
+
 #ifdef CONFIG_RANDOMIZE_BASE
 #define KASLR_LEN  (1UL << 31)
 #else
-- 
2.45.1




[PATCH v7 29/38] s390/ftrace: Unpoison ftrace_regs in kprobe_ftrace_handler()

2024-06-21 Thread Ilya Leoshkevich
s390 uses assembly code to initialize ftrace_regs and call
kprobe_ftrace_handler(). Therefore, from the KMSAN's point of view,
ftrace_regs is poisoned on kprobe_ftrace_handler() entry. This causes
KMSAN warnings when running the ftrace testsuite.

Fix by trusting the assembly code and always unpoisoning ftrace_regs in
kprobe_ftrace_handler().

Reviewed-by: Alexander Potapenko 
Acked-by: Heiko Carstens 
Signed-off-by: Ilya Leoshkevich 
---
 arch/s390/kernel/ftrace.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c
index ddf2ee47cb87..0bd6adc40a34 100644
--- a/arch/s390/kernel/ftrace.c
+++ b/arch/s390/kernel/ftrace.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -303,6 +304,7 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long 
parent_ip,
if (bit < 0)
return;
 
+   kmsan_unpoison_memory(fregs, sizeof(*fregs));
regs = ftrace_get_regs(fregs);
p = get_kprobe((kprobe_opcode_t *)ip);
if (!regs || unlikely(!p) || kprobe_disabled(p))
-- 
2.45.1




[PATCH v7 38/38] kmsan: Enable on s390

2024-06-21 Thread Ilya Leoshkevich
Now that everything else is in place, enable KMSAN in Kconfig.

Acked-by: Heiko Carstens 
Reviewed-by: Alexander Potapenko 
Signed-off-by: Ilya Leoshkevich 
---
 arch/s390/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index c59d2b54df49..3cba4993d7c7 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -158,6 +158,7 @@ config S390
select HAVE_ARCH_KASAN
select HAVE_ARCH_KASAN_VMALLOC
select HAVE_ARCH_KCSAN
+   select HAVE_ARCH_KMSAN
select HAVE_ARCH_KFENCE
select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
select HAVE_ARCH_SECCOMP_FILTER
-- 
2.45.1




[PATCH v7 27/38] s390/cpumf: Unpoison STCCTM output buffer

2024-06-21 Thread Ilya Leoshkevich
stcctm() uses the "Q" constraint for dest, therefore KMSAN does not
understand that it fills multiple doublewords pointed to by dest, not
just one. This results in false positives.

Unpoison the whole dest manually with kmsan_unpoison_memory().

Reported-by: Alexander Gordeev 
Reviewed-by: Alexander Potapenko 
Acked-by: Heiko Carstens 
Signed-off-by: Ilya Leoshkevich 
---
 arch/s390/include/asm/cpu_mf.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/arch/s390/include/asm/cpu_mf.h b/arch/s390/include/asm/cpu_mf.h
index a0de5b9b02ea..9e4bbc3e53f8 100644
--- a/arch/s390/include/asm/cpu_mf.h
+++ b/arch/s390/include/asm/cpu_mf.h
@@ -10,6 +10,7 @@
 #define _ASM_S390_CPU_MF_H
 
 #include 
+#include 
 #include 
 #include 
 
@@ -239,6 +240,11 @@ static __always_inline int stcctm(enum stcctm_ctr_set set, 
u64 range, u64 *dest)
: "=d" (cc)
: "Q" (*dest), "d" (range), "i" (set)
: "cc", "memory");
+   /*
+* If cc == 2, less than RANGE counters are stored, but it's not easy
+* to tell how many. Always unpoison the whole range for simplicity.
+*/
+   kmsan_unpoison_memory(dest, range * sizeof(u64));
return cc;
 }
 
-- 
2.45.1




[PATCH v7 23/38] s390: Use a larger stack for KMSAN

2024-06-21 Thread Ilya Leoshkevich
Adjust the stack size for the KMSAN-enabled kernel like it was done
for the KASAN-enabled one in commit 7fef92ccadd7 ("s390/kasan: double
the stack size"). Both tools have similar requirements.

Reviewed-by: Alexander Gordeev 
Reviewed-by: Alexander Potapenko 
Signed-off-by: Ilya Leoshkevich 
---
 arch/s390/Makefile  | 2 +-
 arch/s390/include/asm/thread_info.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index f2b21c7a70ef..7fd57398221e 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -36,7 +36,7 @@ KBUILD_CFLAGS_DECOMPRESSOR += $(if 
$(CONFIG_DEBUG_INFO_DWARF4), $(call cc-option
 KBUILD_CFLAGS_DECOMPRESSOR += $(if 
$(CONFIG_CC_NO_ARRAY_BOUNDS),-Wno-array-bounds)
 
 UTS_MACHINE:= s390x
-STACK_SIZE := $(if $(CONFIG_KASAN),65536,16384)
+STACK_SIZE := $(if $(CONFIG_KASAN),65536,$(if $(CONFIG_KMSAN),65536,16384))
 CHECKFLAGS += -D__s390__ -D__s390x__
 
 export LD_BFD
diff --git a/arch/s390/include/asm/thread_info.h 
b/arch/s390/include/asm/thread_info.h
index a674c7d25da5..d02a709717b8 100644
--- a/arch/s390/include/asm/thread_info.h
+++ b/arch/s390/include/asm/thread_info.h
@@ -16,7 +16,7 @@
 /*
  * General size of kernel stacks
  */
-#ifdef CONFIG_KASAN
+#if defined(CONFIG_KASAN) || defined(CONFIG_KMSAN)
 #define THREAD_SIZE_ORDER 4
 #else
 #define THREAD_SIZE_ORDER 2
-- 
2.45.1




[PATCH v7 26/38] s390/cpacf: Unpoison the results of cpacf_trng()

2024-06-21 Thread Ilya Leoshkevich
Prevent KMSAN from complaining about buffers filled by cpacf_trng()
being uninitialized.

Tested-by: Alexander Gordeev 
Reviewed-by: Alexander Potapenko 
Acked-by: Heiko Carstens 
Signed-off-by: Ilya Leoshkevich 
---
 arch/s390/include/asm/cpacf.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/s390/include/asm/cpacf.h b/arch/s390/include/asm/cpacf.h
index c786538e397c..dae8843b164f 100644
--- a/arch/s390/include/asm/cpacf.h
+++ b/arch/s390/include/asm/cpacf.h
@@ -12,6 +12,7 @@
 #define _ASM_S390_CPACF_H
 
 #include 
+#include 
 
 /*
  * Instruction opcodes for the CPACF instructions
@@ -542,6 +543,8 @@ static inline void cpacf_trng(u8 *ucbuf, unsigned long 
ucbuf_len,
: [ucbuf] "+&d" (u.pair), [cbuf] "+&d" (c.pair)
: [fc] "K" (CPACF_PRNO_TRNG), [opc] "i" (CPACF_PRNO)
: "cc", "memory", "0");
+   kmsan_unpoison_memory(ucbuf, ucbuf_len);
+   kmsan_unpoison_memory(cbuf, cbuf_len);
 }
 
 /**
-- 
2.45.1




[PATCH v7 19/38] mm: kfence: Disable KMSAN when checking the canary

2024-06-21 Thread Ilya Leoshkevich
KMSAN warns about check_canary() accessing the canary.

The reason is that, even though set_canary() is properly instrumented
and sets shadow, slub explicitly poisons the canary's address range
afterwards.

Unpoisoning the canary is not the right thing to do: only
check_canary() is supposed to ever touch it. Instead, disable KMSAN
checks around canary read accesses.

Reviewed-by: Alexander Potapenko 
Tested-by: Alexander Potapenko 
Signed-off-by: Ilya Leoshkevich 
---
 mm/kfence/core.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/mm/kfence/core.c b/mm/kfence/core.c
index 964b8482275b..83f8e78827c0 100644
--- a/mm/kfence/core.c
+++ b/mm/kfence/core.c
@@ -305,8 +305,14 @@ metadata_update_state(struct kfence_metadata *meta, enum 
kfence_object_state nex
WRITE_ONCE(meta->state, next);
 }
 
+#ifdef CONFIG_KMSAN
+#define check_canary_attributes noinline __no_kmsan_checks
+#else
+#define check_canary_attributes inline
+#endif
+
 /* Check canary byte at @addr. */
-static inline bool check_canary_byte(u8 *addr)
+static check_canary_attributes bool check_canary_byte(u8 *addr)
 {
struct kfence_metadata *meta;
unsigned long flags;
@@ -341,7 +347,8 @@ static inline void set_canary(const struct kfence_metadata 
*meta)
*((u64 *)addr) = KFENCE_CANARY_PATTERN_U64;
 }
 
-static inline void check_canary(const struct kfence_metadata *meta)
+static check_canary_attributes void
+check_canary(const struct kfence_metadata *meta)
 {
const unsigned long pageaddr = ALIGN_DOWN(meta->addr, PAGE_SIZE);
unsigned long addr = pageaddr;
-- 
2.45.1




[PATCH v7 34/38] s390/uaccess: Add KMSAN support to put_user() and get_user()

2024-06-21 Thread Ilya Leoshkevich
put_user() uses inline assembly with precise constraints, so Clang is
in principle capable of instrumenting it automatically. Unfortunately,
one of the constraints contains a dereferenced user pointer, and Clang
does not currently distinguish user and kernel pointers. Therefore
KMSAN attempts to access shadow for user pointers, which is not a right
thing to do.

An obvious fix to add __no_sanitize_memory to __put_user_fn() does not
work, since it's __always_inline. And __always_inline cannot be removed
due to the __put_user_bad() trick.

A different obvious fix of using the "a" instead of the "+Q" constraint
degrades the code quality, which is very important here, since it's a
hot path.

Instead, repurpose the __put_user_asm() macro to define
__put_user_{char,short,int,long}_noinstr() functions and mark them with
__no_sanitize_memory. For the non-KMSAN builds make them
__always_inline in order to keep the generated code quality. Also
define __put_user_{char,short,int,long}() functions, which call the
aforementioned ones and which *are* instrumented, because they call
KMSAN hooks, which may be implemented as macros.

The same applies to get_user() as well.

Acked-by: Heiko Carstens 
Reviewed-by: Alexander Potapenko 
Signed-off-by: Ilya Leoshkevich 
---
 arch/s390/include/asm/uaccess.h | 111 +++-
 1 file changed, 79 insertions(+), 32 deletions(-)

diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h
index 81ae8a98e7ec..70f0edc00c2a 100644
--- a/arch/s390/include/asm/uaccess.h
+++ b/arch/s390/include/asm/uaccess.h
@@ -78,13 +78,24 @@ union oac {
 
 int __noreturn __put_user_bad(void);
 
-#define __put_user_asm(to, from, size) \
-({ \
+#ifdef CONFIG_KMSAN
+#define get_put_user_noinstr_attributes \
+   noinline __maybe_unused __no_sanitize_memory
+#else
+#define get_put_user_noinstr_attributes __always_inline
+#endif
+
+#define DEFINE_PUT_USER(type)  \
+static get_put_user_noinstr_attributes int \
+__put_user_##type##_noinstr(unsigned type __user *to,  \
+   unsigned type *from,\
+   unsigned long size) \
+{  \
union oac __oac_spec = {\
.oac1.as = PSW_BITS_AS_SECONDARY,   \
.oac1.a = 1,\
};  \
-   int __rc;   \
+   int rc; \
\
asm volatile(   \
"   lr  0,%[spec]\n"\
@@ -93,12 +104,28 @@ int __noreturn __put_user_bad(void);
"2:\n"  \
EX_TABLE_UA_STORE(0b, 2b, %[rc])\
EX_TABLE_UA_STORE(1b, 2b, %[rc])\
-   : [rc] "=&d" (__rc), [_to] "+Q" (*(to)) \
+   : [rc] "=&d" (rc), [_to] "+Q" (*(to))   \
: [_size] "d" (size), [_from] "Q" (*(from)),\
  [spec] "d" (__oac_spec.val)   \
: "cc", "0");   \
-   __rc;   \
-})
+   return rc;  \
+}  \
+   \
+static __always_inline int \
+__put_user_##type(unsigned type __user *to, unsigned type *from,   \
+ unsigned long size)   \
+{  \
+   int rc; \
+   \
+   rc = __put_user_##type##_noinstr(to, from, size);   \
+   instrument_put_user(*from, to, size);   \
+   return rc;  \
+}
+
+DEFINE_PUT_USER(char);
+DEFINE_PUT_USER(short);
+DEFINE_PUT_USER(int);
+DEFINE_PUT_USER(long);
 
 static __always_inline int __put_user_fn(void *x, void __user *ptr, unsigned 
long size)
 {
@@ -106,24 +133,24 @@ static __always_inline int __put_user_fn(void *x, v

[PATCH v7 22/38] s390/boot: Turn off KMSAN

2024-06-21 Thread Ilya Leoshkevich
All other sanitizers are disabled for boot as well. While at it, add a
comment explaining why we need this.

Reviewed-by: Alexander Gordeev 
Reviewed-by: Alexander Potapenko 
Signed-off-by: Ilya Leoshkevich 
---
 arch/s390/boot/Makefile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile
index 070c9b2e905f..526ed20b9d31 100644
--- a/arch/s390/boot/Makefile
+++ b/arch/s390/boot/Makefile
@@ -3,11 +3,13 @@
 # Makefile for the linux s390-specific parts of the memory manager.
 #
 
+# Tooling runtimes are unavailable and cannot be linked for early boot code
 KCOV_INSTRUMENT := n
 GCOV_PROFILE := n
 UBSAN_SANITIZE := n
 KASAN_SANITIZE := n
 KCSAN_SANITIZE := n
+KMSAN_SANITIZE := n
 
 KBUILD_AFLAGS := $(KBUILD_AFLAGS_DECOMPRESSOR)
 KBUILD_CFLAGS := $(KBUILD_CFLAGS_DECOMPRESSOR)
-- 
2.45.1




[PATCH v7 18/38] mm: slub: Disable KMSAN when checking the padding bytes

2024-06-21 Thread Ilya Leoshkevich
Even though the KMSAN warnings generated by memchr_inv() are suppressed
by metadata_access_enable(), its return value may still be poisoned.

The reason is that the last iteration of memchr_inv() returns
`*start != value ? start : NULL`, where *start is poisoned. Because of
this, somewhat counterintuitively, the shadow value computed by
visitSelectInst() is equal to `(uintptr_t)start`.

One possibility to fix this, since the intention behind guarding
memchr_inv() behind metadata_access_enable() is to touch poisoned
metadata without triggering KMSAN, is to unpoison its return value.
However, this approach is too fragile. So simply disable the KMSAN
checks in the respective functions.

Reviewed-by: Alexander Potapenko 
Signed-off-by: Ilya Leoshkevich 
---
 mm/slub.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/mm/slub.c b/mm/slub.c
index b050e528112c..fcd68fcea4ab 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1176,9 +1176,16 @@ static void restore_bytes(struct kmem_cache *s, char 
*message, u8 data,
memset(from, data, to - from);
 }
 
-static int check_bytes_and_report(struct kmem_cache *s, struct slab *slab,
-   u8 *object, char *what,
-   u8 *start, unsigned int value, unsigned int bytes)
+#ifdef CONFIG_KMSAN
+#define pad_check_attributes noinline __no_kmsan_checks
+#else
+#define pad_check_attributes
+#endif
+
+static pad_check_attributes int
+check_bytes_and_report(struct kmem_cache *s, struct slab *slab,
+  u8 *object, char *what,
+  u8 *start, unsigned int value, unsigned int bytes)
 {
u8 *fault;
u8 *end;
@@ -1270,7 +1277,8 @@ static int check_pad_bytes(struct kmem_cache *s, struct 
slab *slab, u8 *p)
 }
 
 /* Check the pad bytes at the end of a slab page */
-static void slab_pad_check(struct kmem_cache *s, struct slab *slab)
+static pad_check_attributes void
+slab_pad_check(struct kmem_cache *s, struct slab *slab)
 {
u8 *start;
u8 *fault;
-- 
2.45.1




[PATCH v7 14/38] kmsan: Use ALIGN_DOWN() in kmsan_get_metadata()

2024-06-21 Thread Ilya Leoshkevich
Improve the readability by replacing the custom aligning logic with
ALIGN_DOWN(). Unlike other places where a similar sequence is used,
there is no size parameter that needs to be adjusted, so the standard
macro fits.

Reviewed-by: Alexander Potapenko 
Signed-off-by: Ilya Leoshkevich 
---
 mm/kmsan/shadow.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/mm/kmsan/shadow.c b/mm/kmsan/shadow.c
index 2d57408c78ae..9c58f081d84f 100644
--- a/mm/kmsan/shadow.c
+++ b/mm/kmsan/shadow.c
@@ -123,14 +123,12 @@ struct shadow_origin_ptr kmsan_get_shadow_origin_ptr(void 
*address, u64 size,
  */
 void *kmsan_get_metadata(void *address, bool is_origin)
 {
-   u64 addr = (u64)address, pad, off;
+   u64 addr = (u64)address, off;
struct page *page;
void *ret;
 
-   if (is_origin && !IS_ALIGNED(addr, KMSAN_ORIGIN_SIZE)) {
-   pad = addr % KMSAN_ORIGIN_SIZE;
-   addr -= pad;
-   }
+   if (is_origin)
+   addr = ALIGN_DOWN(addr, KMSAN_ORIGIN_SIZE);
address = (void *)addr;
if (kmsan_internal_is_vmalloc_addr(address) ||
kmsan_internal_is_module_addr(address))
-- 
2.45.1




[PATCH v7 25/38] s390/checksum: Add a KMSAN check

2024-06-21 Thread Ilya Leoshkevich
Add a KMSAN check to the CKSM inline assembly, similar to how it was
done for ASAN in commit e42ac7789df6 ("s390/checksum: always use cksm
instruction").

Acked-by: Alexander Gordeev 
Reviewed-by: Alexander Potapenko 
Signed-off-by: Ilya Leoshkevich 
---
 arch/s390/include/asm/checksum.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/s390/include/asm/checksum.h b/arch/s390/include/asm/checksum.h
index b89159591ca0..46f5c9660616 100644
--- a/arch/s390/include/asm/checksum.h
+++ b/arch/s390/include/asm/checksum.h
@@ -13,6 +13,7 @@
 #define _S390_CHECKSUM_H
 
 #include 
+#include 
 #include 
 
 static inline __wsum cksm(const void *buff, int len, __wsum sum)
@@ -23,6 +24,7 @@ static inline __wsum cksm(const void *buff, int len, __wsum 
sum)
};
 
instrument_read(buff, len);
+   kmsan_check_memory(buff, len);
asm volatile("\n"
"0: cksm%[sum],%[rp]\n"
"   jo  0b\n"
-- 
2.45.1




[PATCH v7 11/38] kmsan: Allow disabling KMSAN checks for the current task

2024-06-21 Thread Ilya Leoshkevich
Like for KASAN, it's useful to temporarily disable KMSAN checks around,
e.g., redzone accesses. Introduce kmsan_disable_current() and
kmsan_enable_current(), which are similar to their KASAN counterparts.

Make them reentrant in order to handle memory allocations in interrupt
context. Repurpose the allow_reporting field for this.

Reviewed-by: Alexander Potapenko 
Signed-off-by: Ilya Leoshkevich 
---
 Documentation/dev-tools/kmsan.rst | 11 +--
 include/linux/kmsan.h | 24 
 include/linux/kmsan_types.h   |  2 +-
 mm/kmsan/core.c   |  1 -
 mm/kmsan/hooks.c  | 18 +++---
 mm/kmsan/report.c |  7 ---
 tools/objtool/check.c |  2 ++
 7 files changed, 55 insertions(+), 10 deletions(-)

diff --git a/Documentation/dev-tools/kmsan.rst 
b/Documentation/dev-tools/kmsan.rst
index 323eedad53cd..6a48d96c5c85 100644
--- a/Documentation/dev-tools/kmsan.rst
+++ b/Documentation/dev-tools/kmsan.rst
@@ -110,6 +110,13 @@ in the Makefile. Think of this as applying 
``__no_sanitize_memory`` to every
 function in the file or directory. Most users won't need KMSAN_SANITIZE, unless
 their code gets broken by KMSAN (e.g. runs at early boot time).
 
+KMSAN checks can also be temporarily disabled for the current task using
+``kmsan_disable_current()`` and ``kmsan_enable_current()`` calls. Each
+``kmsan_enable_current()`` call must be preceded by a
+``kmsan_disable_current()`` call; these call pairs may be nested. One needs to
+be careful with these calls, keeping the regions short and preferring other
+ways to disable instrumentation, where possible.
+
 Support
 ===
 
@@ -338,11 +345,11 @@ Per-task KMSAN state
 
 
 Every task_struct has an associated KMSAN task state that holds the KMSAN
-context (see above) and a per-task flag disallowing KMSAN reports::
+context (see above) and a per-task counter disallowing KMSAN reports::
 
   struct kmsan_context {
 ...
-bool allow_reporting;
+unsigned int depth;
 struct kmsan_context_state cstate;
 ...
   }
diff --git a/include/linux/kmsan.h b/include/linux/kmsan.h
index fe6c2212bdb1..14b5ea6d3a43 100644
--- a/include/linux/kmsan.h
+++ b/include/linux/kmsan.h
@@ -239,6 +239,22 @@ void kmsan_unpoison_entry_regs(const struct pt_regs *regs);
  */
 void *kmsan_get_metadata(void *addr, bool is_origin);
 
+/**
+ * kmsan_enable_current(): Enable KMSAN for the current task.
+ *
+ * Each kmsan_enable_current() current call must be preceded by a
+ * kmsan_disable_current() call. These call pairs may be nested.
+ */
+void kmsan_enable_current(void);
+
+/**
+ * kmsan_disable_current(): Disable KMSAN for the current task.
+ *
+ * Each kmsan_disable_current() current call must be followed by a
+ * kmsan_enable_current() call. These call pairs may be nested.
+ */
+void kmsan_disable_current(void);
+
 #else
 
 static inline void kmsan_init_shadow(void)
@@ -338,6 +354,14 @@ static inline void kmsan_unpoison_entry_regs(const struct 
pt_regs *regs)
 {
 }
 
+static inline void kmsan_enable_current(void)
+{
+}
+
+static inline void kmsan_disable_current(void)
+{
+}
+
 #endif
 
 #endif /* _LINUX_KMSAN_H */
diff --git a/include/linux/kmsan_types.h b/include/linux/kmsan_types.h
index 929287981afe..dfc59918b3c0 100644
--- a/include/linux/kmsan_types.h
+++ b/include/linux/kmsan_types.h
@@ -31,7 +31,7 @@ struct kmsan_context_state {
 struct kmsan_ctx {
struct kmsan_context_state cstate;
int kmsan_in_runtime;
-   bool allow_reporting;
+   unsigned int depth;
 };
 
 #endif /* _LINUX_KMSAN_TYPES_H */
diff --git a/mm/kmsan/core.c b/mm/kmsan/core.c
index 95f859e38c53..81b0711a 100644
--- a/mm/kmsan/core.c
+++ b/mm/kmsan/core.c
@@ -43,7 +43,6 @@ void kmsan_internal_task_create(struct task_struct *task)
struct thread_info *info = current_thread_info();
 
__memset(ctx, 0, sizeof(*ctx));
-   ctx->allow_reporting = true;
kmsan_internal_unpoison_memory(info, sizeof(*info), false);
 }
 
diff --git a/mm/kmsan/hooks.c b/mm/kmsan/hooks.c
index b408714f9ba3..267d0afa2e8b 100644
--- a/mm/kmsan/hooks.c
+++ b/mm/kmsan/hooks.c
@@ -39,12 +39,10 @@ void kmsan_task_create(struct task_struct *task)
 
 void kmsan_task_exit(struct task_struct *task)
 {
-   struct kmsan_ctx *ctx = &task->kmsan_ctx;
-
if (!kmsan_enabled || kmsan_in_runtime())
return;
 
-   ctx->allow_reporting = false;
+   kmsan_disable_current();
 }
 
 void kmsan_slab_alloc(struct kmem_cache *s, void *object, gfp_t flags)
@@ -424,3 +422,17 @@ void kmsan_check_memory(const void *addr, size_t size)
   REASON_ANY);
 }
 EXPORT_SYMBOL(kmsan_check_memory);
+
+void kmsan_enable_current(void)
+{
+   KMSAN_WARN_ON(current->kmsan_ctx.depth == 0);
+   current->kmsan_ctx.depth--;
+}
+EXPORT_SYMBOL(kmsan_enable_current);
+
+void kmsan_disable_current(void)
+{
+   current->kmsan_ctx.depth++;
+

[PATCH v7 20/38] lib/zlib: Unpoison DFLTCC output buffers

2024-06-21 Thread Ilya Leoshkevich
The constraints of the DFLTCC inline assembly are not precise: they
do not communicate the size of the output buffers to the compiler, so
it cannot automatically instrument it.

Add the manual kmsan_unpoison_memory() calls for the output buffers.
The logic is the same as in [1].

[1] 
https://github.com/zlib-ng/zlib-ng/commit/1f5ddcc009ac3511e99fc88736a9e1a6381168c5

Reported-by: Alexander Gordeev 
Reviewed-by: Alexander Potapenko 
Signed-off-by: Ilya Leoshkevich 
---
 lib/zlib_dfltcc/dfltcc.h  |  1 +
 lib/zlib_dfltcc/dfltcc_util.h | 28 
 2 files changed, 29 insertions(+)

diff --git a/lib/zlib_dfltcc/dfltcc.h b/lib/zlib_dfltcc/dfltcc.h
index b96232bdd44d..0f2a16d7a48a 100644
--- a/lib/zlib_dfltcc/dfltcc.h
+++ b/lib/zlib_dfltcc/dfltcc.h
@@ -80,6 +80,7 @@ struct dfltcc_param_v0 {
 uint8_t csb[1152];
 };
 
+static_assert(offsetof(struct dfltcc_param_v0, csb) == 384);
 static_assert(sizeof(struct dfltcc_param_v0) == 1536);
 
 #define CVT_CRC32 0
diff --git a/lib/zlib_dfltcc/dfltcc_util.h b/lib/zlib_dfltcc/dfltcc_util.h
index 4a46b5009f0d..10509270d822 100644
--- a/lib/zlib_dfltcc/dfltcc_util.h
+++ b/lib/zlib_dfltcc/dfltcc_util.h
@@ -2,6 +2,8 @@
 #ifndef DFLTCC_UTIL_H
 #define DFLTCC_UTIL_H
 
+#include "dfltcc.h"
+#include 
 #include 
 
 /*
@@ -20,6 +22,7 @@ typedef enum {
 #define DFLTCC_CMPR 2
 #define DFLTCC_XPND 4
 #define HBT_CIRCULAR (1 << 7)
+#define DFLTCC_FN_MASK ((1 << 7) - 1)
 #define HB_BITS 15
 #define HB_SIZE (1 << HB_BITS)
 
@@ -34,6 +37,7 @@ static inline dfltcc_cc dfltcc(
 )
 {
 Byte *t2 = op1 ? *op1 : NULL;
+unsigned char *orig_t2 = t2;
 size_t t3 = len1 ? *len1 : 0;
 const Byte *t4 = op2 ? *op2 : NULL;
 size_t t5 = len2 ? *len2 : 0;
@@ -59,6 +63,30 @@ static inline dfltcc_cc dfltcc(
  : "cc", "memory");
 t2 = r2; t3 = r3; t4 = r4; t5 = r5;
 
+/*
+ * Unpoison the parameter block and the output buffer.
+ * This is a no-op in non-KMSAN builds.
+ */
+switch (fn & DFLTCC_FN_MASK) {
+case DFLTCC_QAF:
+kmsan_unpoison_memory(param, sizeof(struct dfltcc_qaf_param));
+break;
+case DFLTCC_GDHT:
+kmsan_unpoison_memory(param, offsetof(struct dfltcc_param_v0, csb));
+break;
+case DFLTCC_CMPR:
+kmsan_unpoison_memory(param, sizeof(struct dfltcc_param_v0));
+kmsan_unpoison_memory(
+orig_t2,
+t2 - orig_t2 +
+(((struct dfltcc_param_v0 *)param)->sbb == 0 ? 0 : 1));
+break;
+case DFLTCC_XPND:
+kmsan_unpoison_memory(param, sizeof(struct dfltcc_param_v0));
+kmsan_unpoison_memory(orig_t2, t2 - orig_t2);
+break;
+}
+
 if (op1)
 *op1 = t2;
 if (len1)
-- 
2.45.1




[PATCH v7 09/38] kmsan: Expose kmsan_get_metadata()

2024-06-21 Thread Ilya Leoshkevich
Each s390 CPU has lowcore pages associated with it. Each CPU sees its
own lowcore at virtual address 0 through a hardware mechanism called
prefixing. Additionally, all lowcores are mapped to non-0 virtual
addresses stored in the lowcore_ptr[] array.

When lowcore is accessed through virtual address 0, one needs to
resolve metadata for lowcore_ptr[raw_smp_processor_id()].

Expose kmsan_get_metadata() to make it possible to do this from the
arch code.

Reviewed-by: Alexander Potapenko 
Signed-off-by: Ilya Leoshkevich 
---
 include/linux/kmsan.h  | 9 +
 mm/kmsan/instrumentation.c | 1 +
 mm/kmsan/kmsan.h   | 1 -
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/include/linux/kmsan.h b/include/linux/kmsan.h
index e0c23a32cdf0..fe6c2212bdb1 100644
--- a/include/linux/kmsan.h
+++ b/include/linux/kmsan.h
@@ -230,6 +230,15 @@ void kmsan_handle_urb(const struct urb *urb, bool is_out);
  */
 void kmsan_unpoison_entry_regs(const struct pt_regs *regs);
 
+/**
+ * kmsan_get_metadata() - Return a pointer to KMSAN shadow or origins.
+ * @addr:  kernel address.
+ * @is_origin: whether to return origins or shadow.
+ *
+ * Return NULL if metadata cannot be found.
+ */
+void *kmsan_get_metadata(void *addr, bool is_origin);
+
 #else
 
 static inline void kmsan_init_shadow(void)
diff --git a/mm/kmsan/instrumentation.c b/mm/kmsan/instrumentation.c
index 8a1bbbc723ab..94b49fac9d8b 100644
--- a/mm/kmsan/instrumentation.c
+++ b/mm/kmsan/instrumentation.c
@@ -14,6 +14,7 @@
 
 #include "kmsan.h"
 #include 
+#include 
 #include 
 #include 
 #include 
diff --git a/mm/kmsan/kmsan.h b/mm/kmsan/kmsan.h
index adf443bcffe8..34b83c301d57 100644
--- a/mm/kmsan/kmsan.h
+++ b/mm/kmsan/kmsan.h
@@ -66,7 +66,6 @@ struct shadow_origin_ptr {
 
 struct shadow_origin_ptr kmsan_get_shadow_origin_ptr(void *addr, u64 size,
 bool store);
-void *kmsan_get_metadata(void *addr, bool is_origin);
 void __init kmsan_init_alloc_meta_for_range(void *start, void *end);
 
 enum kmsan_bug_reason {
-- 
2.45.1




[PATCH v7 17/38] mm: slub: Let KMSAN access metadata

2024-06-21 Thread Ilya Leoshkevich
Building the kernel with CONFIG_SLUB_DEBUG and CONFIG_KMSAN causes
KMSAN to complain about touching redzones in kfree().

Fix by extending the existing KASAN-related metadata_access_enable()
and metadata_access_disable() functions to KMSAN.

Acked-by: Vlastimil Babka 
Reviewed-by: Alexander Potapenko 
Signed-off-by: Ilya Leoshkevich 
---
 mm/slub.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/mm/slub.c b/mm/slub.c
index 1134091abac5..b050e528112c 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -829,10 +829,12 @@ static int disable_higher_order_debug;
 static inline void metadata_access_enable(void)
 {
kasan_disable_current();
+   kmsan_disable_current();
 }
 
 static inline void metadata_access_disable(void)
 {
+   kmsan_enable_current();
kasan_enable_current();
 }
 
-- 
2.45.1




[PATCH v7 10/38] kmsan: Export panic_on_kmsan

2024-06-21 Thread Ilya Leoshkevich
When building the kmsan test as a module, modpost fails with the
following error message:

ERROR: modpost: "panic_on_kmsan" [mm/kmsan/kmsan_test.ko] undefined!

Export panic_on_kmsan in order to improve the KMSAN usability for
modules.

Reviewed-by: Alexander Potapenko 
Signed-off-by: Ilya Leoshkevich 
---
 mm/kmsan/report.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/mm/kmsan/report.c b/mm/kmsan/report.c
index 02736ec757f2..c79d3b0d2d0d 100644
--- a/mm/kmsan/report.c
+++ b/mm/kmsan/report.c
@@ -20,6 +20,7 @@ static DEFINE_RAW_SPINLOCK(kmsan_report_lock);
 /* Protected by kmsan_report_lock */
 static char report_local_descr[DESCR_SIZE];
 int panic_on_kmsan __read_mostly;
+EXPORT_SYMBOL_GPL(panic_on_kmsan);
 
 #ifdef MODULE_PARAM_PREFIX
 #undef MODULE_PARAM_PREFIX
-- 
2.45.1




[PATCH v7 16/38] kmsan: Expose KMSAN_WARN_ON()

2024-06-21 Thread Ilya Leoshkevich
KMSAN_WARN_ON() is required for implementing s390-specific KMSAN
functions, but right now it's available only to the KMSAN internal
functions. Expose it to subsystems through .

Reviewed-by: Alexander Potapenko 
Signed-off-by: Ilya Leoshkevich 
---
 include/linux/kmsan.h | 25 +
 mm/kmsan/kmsan.h  | 24 +---
 2 files changed, 26 insertions(+), 23 deletions(-)

diff --git a/include/linux/kmsan.h b/include/linux/kmsan.h
index 7109644f4c19..2b1432cc16d5 100644
--- a/include/linux/kmsan.h
+++ b/include/linux/kmsan.h
@@ -268,6 +268,29 @@ static inline void *memset_no_sanitize_memory(void *s, int 
c, size_t n)
return __memset(s, c, n);
 }
 
+extern bool kmsan_enabled;
+extern int panic_on_kmsan;
+
+/*
+ * KMSAN performs a lot of consistency checks that are currently enabled by
+ * default. BUG_ON is normally discouraged in the kernel, unless used for
+ * debugging, but KMSAN itself is a debugging tool, so it makes little sense to
+ * recover if something goes wrong.
+ */
+#define KMSAN_WARN_ON(cond)   \
+   ({\
+   const bool __cond = WARN_ON(cond);\
+   if (unlikely(__cond)) {   \
+   WRITE_ONCE(kmsan_enabled, false); \
+   if (panic_on_kmsan) { \
+   /* Can't call panic() here because */ \
+   /* of uaccess checks. */  \
+   BUG();\
+   } \
+   } \
+   __cond;   \
+   })
+
 #else
 
 static inline void kmsan_init_shadow(void)
@@ -380,6 +403,8 @@ static inline void *memset_no_sanitize_memory(void *s, int 
c, size_t n)
return memset(s, c, n);
 }
 
+#define KMSAN_WARN_ON WARN_ON
+
 #endif
 
 #endif /* _LINUX_KMSAN_H */
diff --git a/mm/kmsan/kmsan.h b/mm/kmsan/kmsan.h
index 34b83c301d57..91a360a31e85 100644
--- a/mm/kmsan/kmsan.h
+++ b/mm/kmsan/kmsan.h
@@ -11,6 +11,7 @@
 #define __MM_KMSAN_KMSAN_H
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -34,29 +35,6 @@
 #define KMSAN_META_SHADOW (false)
 #define KMSAN_META_ORIGIN (true)
 
-extern bool kmsan_enabled;
-extern int panic_on_kmsan;
-
-/*
- * KMSAN performs a lot of consistency checks that are currently enabled by
- * default. BUG_ON is normally discouraged in the kernel, unless used for
- * debugging, but KMSAN itself is a debugging tool, so it makes little sense to
- * recover if something goes wrong.
- */
-#define KMSAN_WARN_ON(cond)   \
-   ({\
-   const bool __cond = WARN_ON(cond);\
-   if (unlikely(__cond)) {   \
-   WRITE_ONCE(kmsan_enabled, false); \
-   if (panic_on_kmsan) { \
-   /* Can't call panic() here because */ \
-   /* of uaccess checks. */  \
-   BUG();\
-   } \
-   } \
-   __cond;   \
-   })
-
 /*
  * A pair of metadata pointers to be returned by the instrumentation functions.
  */
-- 
2.45.1




[PATCH v7 04/38] kmsan: Increase the maximum store size to 4096

2024-06-21 Thread Ilya Leoshkevich
The inline assembly block in s390's chsc() stores that much.

Reviewed-by: Alexander Potapenko 
Signed-off-by: Ilya Leoshkevich 
---
 mm/kmsan/instrumentation.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/mm/kmsan/instrumentation.c b/mm/kmsan/instrumentation.c
index cc3907a9c33a..470b0b4afcc4 100644
--- a/mm/kmsan/instrumentation.c
+++ b/mm/kmsan/instrumentation.c
@@ -110,11 +110,10 @@ void __msan_instrument_asm_store(void *addr, uintptr_t 
size)
 
ua_flags = user_access_save();
/*
-* Most of the accesses are below 32 bytes. The two exceptions so far
-* are clwb() (64 bytes) and FPU state (512 bytes).
-* It's unlikely that the assembly will touch more than 512 bytes.
+* Most of the accesses are below 32 bytes. The exceptions so far are
+* clwb() (64 bytes), FPU state (512 bytes) and chsc() (4096 bytes).
 */
-   if (size > 512) {
+   if (size > 4096) {
WARN_ONCE(1, "assembly store size too big: %ld\n", size);
size = 8;
}
-- 
2.45.1




[PATCH v7 21/38] kmsan: Accept ranges starting with 0 on s390

2024-06-21 Thread Ilya Leoshkevich
On s390 the virtual address 0 is valid (current CPU's lowcore is mapped
there), therefore KMSAN should not complain about it.

Disable the respective check on s390. There doesn't seem to be a
Kconfig option to describe this situation, so explicitly check for
s390.

Reviewed-by: Alexander Potapenko 
Signed-off-by: Ilya Leoshkevich 
---
 mm/kmsan/init.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/mm/kmsan/init.c b/mm/kmsan/init.c
index 9de76ac7062c..3f8b1bbb9060 100644
--- a/mm/kmsan/init.c
+++ b/mm/kmsan/init.c
@@ -33,7 +33,10 @@ static void __init kmsan_record_future_shadow_range(void 
*start, void *end)
bool merged = false;
 
KMSAN_WARN_ON(future_index == NUM_FUTURE_RANGES);
-   KMSAN_WARN_ON((nstart >= nend) || !nstart || !nend);
+   KMSAN_WARN_ON((nstart >= nend) ||
+ /* Virtual address 0 is valid on s390. */
+ (!IS_ENABLED(CONFIG_S390) && !nstart) ||
+ !nend);
nstart = ALIGN_DOWN(nstart, PAGE_SIZE);
nend = ALIGN(nend, PAGE_SIZE);
 
-- 
2.45.1




  1   2   >