[PATCH] perf test: Skip perf bench breakpoint run if no breakpoints available
Based on commit 7d54a4acd8c1 ("perf test: Skip watchpoint tests if no watchpoints available"), hardware breakpoints are not available for power9 platform and because of that perf bench breakpoint run fails on power9 platform. Add code to check for the return value of perf_event_open() in breakpoint run and skip the perf bench breakpoint run, if hardware breakpoints are not available. Result on power9 system before patch changes: [command]# perf bench breakpoint thread perf_event_open: No such device Result on power9 system after patch changes: [command]# ./perf bench breakpoint thread Skipping perf bench breakpoint thread: No hardware support Reported-by: Disha Goel Signed-off-by: Kajol Jain --- tools/perf/bench/breakpoint.c | 24 +--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/tools/perf/bench/breakpoint.c b/tools/perf/bench/breakpoint.c index 41385f89ffc7..dfd18f5db97d 100644 --- a/tools/perf/bench/breakpoint.c +++ b/tools/perf/bench/breakpoint.c @@ -47,6 +47,7 @@ struct breakpoint { static int breakpoint_setup(void *addr) { struct perf_event_attr attr = { .size = 0, }; + int fd; attr.type = PERF_TYPE_BREAKPOINT; attr.size = sizeof(attr); @@ -56,7 +57,12 @@ static int breakpoint_setup(void *addr) attr.bp_addr = (unsigned long)addr; attr.bp_type = HW_BREAKPOINT_RW; attr.bp_len = HW_BREAKPOINT_LEN_1; - return syscall(SYS_perf_event_open, &attr, 0, -1, -1, 0); + fd = syscall(SYS_perf_event_open, &attr, 0, -1, -1, 0); + + if (fd < 0) + fd = -errno; + + return fd; } static void *passive_thread(void *arg) @@ -122,8 +128,14 @@ int bench_breakpoint_thread(int argc, const char **argv) for (i = 0; i < thread_params.nbreakpoints; i++) { breakpoints[i].fd = breakpoint_setup(&breakpoints[i].watched); - if (breakpoints[i].fd == -1) + + if (breakpoints[i].fd < 0) { + if (breakpoints[i].fd == -ENODEV) { + printf("Skipping perf bench breakpoint thread: No hardware support\n"); + return 0; + } exit((perror("perf_event_open"), EXIT_FAILURE)); + } } gettimeofday(&start, NULL); for (i = 0; i < thread_params.nparallel; i++) { @@ -196,8 +208,14 @@ int bench_breakpoint_enable(int argc, const char **argv) exit(EXIT_FAILURE); } fd = breakpoint_setup(&watched); - if (fd == -1) + + if (fd < 0) { + if (fd == -ENODEV) { + printf("Skipping perf bench breakpoint enable: No hardware support\n"); + return 0; + } exit((perror("perf_event_open"), EXIT_FAILURE)); + } nthreads = enable_params.npassive + enable_params.nactive; threads = calloc(nthreads, sizeof(threads[0])); if (!threads) -- 2.39.3
[PATCH 1/2] perf vendor events: Update JSON/events for power10 platform
Update JSON/Events list with data-source events for power10 platform. Signed-off-by: Kajol Jain --- .../arch/powerpc/power10/datasource.json | 1787 + .../arch/powerpc/power10/others.json | 10 - .../arch/powerpc/power10/translation.json |5 - 3 files changed, 1787 insertions(+), 15 deletions(-) create mode 100644 tools/perf/pmu-events/arch/powerpc/power10/datasource.json diff --git a/tools/perf/pmu-events/arch/powerpc/power10/datasource.json b/tools/perf/pmu-events/arch/powerpc/power10/datasource.json new file mode 100644 index ..6b0356f2d301 --- /dev/null +++ b/tools/perf/pmu-events/arch/powerpc/power10/datasource.json @@ -0,0 +1,1787 @@ +[ + { +"EventCode": "0x200FE", +"EventName": "PM_DATA_FROM_L2MISS", +"BriefDescription": "The processor's L1 data cache was reloaded from a source beyond the local core's L2 due to a demand miss." + }, + { +"EventCode": "0x300FE", +"EventName": "PM_DATA_FROM_L3MISS", +"BriefDescription": "The processor's L1 data cache was reloaded from beyond the local core's L3 due to a demand miss." + }, + { +"EventCode": "0x400FE", +"EventName": "PM_DATA_FROM_MEMORY", +"BriefDescription": "The processor's data cache was reloaded from local, remote, or distant memory due to a demand miss." + }, + { +"EventCode": "0x0003C040", +"EventName": "PM_INST_FROM_L2", +"BriefDescription": "The processor's instruction cache was reloaded from the local core's L2 due to a demand miss." + }, + { +"EventCode": "0x00034000C040", +"EventName": "PM_DATA_FROM_L2", +"BriefDescription": "The processor's L1 data cache was reloaded from the local core's L2 due to a demand miss." + }, + { +"EventCode": "0x00030010C040", +"EventName": "PM_INST_FROM_L2_ALL", +"BriefDescription": "The processor's instruction cache was reloaded from the local core's L2 due to a demand miss or prefetch reload." + }, + { +"EventCode": "0x00034020C040", +"EventName": "PM_DATA_FROM_L2_ALL", +"BriefDescription": "The processor's L1 data cache was reloaded from the local core's L2 due to a demand miss or prefetch reload." + }, + { +"EventCode": "0x003FC040", +"EventName": "PM_INST_FROM_L1MISS", +"BriefDescription": "The processor's instruction cache was reloaded from a source beyond the local core's L1 due to a demand miss." + }, + { +"EventCode": "0x003F4000C040", +"EventName": "PM_DATA_FROM_L1MISS", +"BriefDescription": "The processor's L1 data cache was reloaded from a source beyond the local core's L1 due to a demand miss." + }, + { +"EventCode": "0x003F0010C040", +"EventName": "PM_INST_FROM_L1MISS_ALL", +"BriefDescription": "The processor's instruction cache was reloaded from a source beyond the local core's L1 due to a demand miss or prefetch reload." + }, + { +"EventCode": "0x003F4020C040", +"EventName": "PM_DATA_FROM_L1MISS_ALL", +"BriefDescription": "The processor's L1 data cache was reloaded from a source beyond the local core's L1 due to a demand miss or prefetch reload." + }, + { +"EventCode": "0x4000C040", +"EventName": "PM_DATA_FROM_L2_NO_CONFLICT", +"BriefDescription": "The processor's L1 data cache was reloaded without dispatch conflicts with data NOT in the MEPF state from the local core's L2 due to a demand miss." + }, + { +"EventCode": "0x4020C040", +"EventName": "PM_DATA_FROM_L2_NO_CONFLICT_ALL", +"BriefDescription": "The processor's L1 data cache was reloaded without dispatch conflicts with data NOT in the MEPF state from the local core's L2 due to a demand miss or prefetch reload." + }, + { +"EventCode": "0x00404000C040", +"EventName": "PM_DATA_FROM_L2_MEPF", +"BriefDescription": "The processor's L1 data cache was reloaded with data in the MEPF state without dispatch conflicts from the local core's L2 due to a demand miss." + }, + { +"EventCode": "0x00404020C040", +"EventName": "PM_DATA_FROM_L2_MEPF_ALL", +"BriefDescription": "The processor's L1 data cache was reloaded with data in the MEPF state without dispatch conflicts from the local core's L2 due to a demand miss or prefetch reload." + }, + { +"EventCode": "0x00804000C040", +"EventName": "PM_DATA_FROM_L2_LDHITST_CONFLICT", +"BriefDescription": "The processor's L1 data cache was reloaded with data that had a dispatch conflict on ld-hit-store from the local core's L2 due to a demand miss." + }, + { +"EventCode": "0x00804020C040", +"EventName": "PM_DATA_FROM_L2_LDHITST_CONFLICT_ALL", +"BriefDescription": "The processor's L1 data cache was reloaded with data that had a dispatch conflict on ld-hit-store from the local core's L2 due to a demand miss or prefetch reload." + }, + { +"EventCode": "0x00C04000C040", +"EventName": "PM_DATA_FROM_L2_OTHER_CONFLICT", +"Brie
[PATCH 2/2] perf vendor events: Update metric events for power10 platform
Update JSON/events for power10 platform with additional metrics. Signed-off-by: Kajol Jain --- .../arch/powerpc/power10/metrics.json | 388 ++ 1 file changed, 388 insertions(+) diff --git a/tools/perf/pmu-events/arch/powerpc/power10/metrics.json b/tools/perf/pmu-events/arch/powerpc/power10/metrics.json index 4d66b75c6ad5..a36621858ea3 100644 --- a/tools/perf/pmu-events/arch/powerpc/power10/metrics.json +++ b/tools/perf/pmu-events/arch/powerpc/power10/metrics.json @@ -434,6 +434,13 @@ "MetricName": "L1_INST_MISS_RATE", "ScaleUnit": "1%" }, +{ +"BriefDescription": "Percentage of completed instructions that were demand fetches that missed the L1 and L2 instruction cache", +"MetricExpr": "PM_INST_FROM_L2MISS * 100 / PM_RUN_INST_CMPL", +"MetricGroup": "General", +"MetricName": "L2_INST_MISS_RATE", +"ScaleUnit": "1%" +}, { "BriefDescription": "Percentage of completed instructions that were demand fetches that reloaded from beyond the L3 icache", "MetricExpr": "PM_INST_FROM_L3MISS / PM_RUN_INST_CMPL * 100", @@ -466,6 +473,13 @@ "MetricGroup": "General", "MetricName": "LOADS_PER_INST" }, +{ +"BriefDescription": "Percentage of demand loads that reloaded from the L2 per completed instruction", +"MetricExpr": "PM_DATA_FROM_L2 * 100 / PM_RUN_INST_CMPL", +"MetricGroup": "dL1_Reloads", +"MetricName": "DL1_RELOAD_FROM_L2_RATE", +"ScaleUnit": "1%" +}, { "BriefDescription": "Percentage of demand loads that reloaded from beyond the L2 per completed instruction", "MetricExpr": "PM_DATA_FROM_L2MISS / PM_RUN_INST_CMPL * 100", @@ -473,6 +487,34 @@ "MetricName": "DL1_RELOAD_FROM_L2_MISS_RATE", "ScaleUnit": "1%" }, +{ +"BriefDescription": "Percentage of demand loads that reloaded using modified data from another core's L2 or L3 on a remote chip, per completed instruction", +"MetricExpr": "PM_DATA_FROM_RL2L3_MOD * 100 / PM_RUN_INST_CMPL", +"MetricGroup": "dL1_Reloads", +"MetricName": "DL1_RELOAD_FROM_RL2L3_MOD_RATE", +"ScaleUnit": "1%" +}, +{ +"BriefDescription": "Percentage of demand loads that reloaded using shared data from another core's L2 or L3 on a remote chip, per completed instruction", +"MetricExpr": "PM_DATA_FROM_RL2L3_SHR * 100 / PM_RUN_INST_CMPL", +"MetricGroup": "dL1_Reloads", +"MetricName": "DL1_RELOAD_FROM_RL2L3_SHR_RATE", +"ScaleUnit": "1%" +}, +{ +"BriefDescription": "Percentage of demand loads that reloaded from the L3 per completed instruction", +"MetricExpr": "PM_DATA_FROM_L3 * 100 / PM_RUN_INST_CMPL", +"MetricGroup": "dL1_Reloads", +"MetricName": "DL1_RELOAD_FROM_L3_RATE", +"ScaleUnit": "1%" +}, +{ +"BriefDescription": "Percentage of demand loads that reloaded with data brought into the L3 by prefetch per completed instruction", +"MetricExpr": "PM_DATA_FROM_L3_MEPF * 100 / PM_RUN_INST_CMPL", +"MetricGroup": "dL1_Reloads", +"MetricName": "DL1_RELOAD_FROM_L3_MEPF_RATE", +"ScaleUnit": "1%" +}, { "BriefDescription": "Percentage of demand loads that reloaded from beyond the L3 per completed instruction", "MetricExpr": "PM_DATA_FROM_L3MISS / PM_RUN_INST_CMPL * 100", @@ -480,6 +522,66 @@ "MetricName": "DL1_RELOAD_FROM_L3_MISS_RATE", "ScaleUnit": "1%" }, +{ +"BriefDescription": "Percentage of demand loads that reloaded using modified data from another core's L2 or L3 on a distant chip, per completed instruction", +"MetricExpr": "PM_DATA_FROM_DL2L3_MOD * 100 / PM_RUN_INST_CMPL", +"MetricGroup": "dL1_Reloads", +"MetricName": "DL1_RELOAD_FROM_DL2L3_MOD_RATE", +"ScaleUnit": "1%" +}, +{ +"BriefDescription": "Percentage of demand loads that reloaded using shared data from another core's L2 or L3 on a distant chip, per completed instruction", +"MetricExpr": "PM_DATA_FROM_DL2L3_SHR * 100 / PM_RUN_INST_CMPL", +"MetricGroup": "dL1_Reloads", +"MetricName": "DL1_RELOAD_FROM_DL2L3_SHR_RATE", +"ScaleUnit": "1%" +}, +{ +"BriefDescription": "Percentage of demand loads that reloaded from local memory per completed instruction", +"MetricExpr": "PM_DATA_FROM_LMEM * 100 / PM_RUN_INST_CMPL", +"MetricGroup": "dL1_Reloads", +"MetricName": "DL1_RELOAD_FROM_LMEM_RATE", +"ScaleUnit": "1%" +}, +{ +"BriefDescription": "Percentage of demand loads that reloaded from remote memory per completed instruction", +"MetricExpr": "PM_DATA_FROM_RMEM * 100 / PM_RUN_INST_CMPL", +"MetricGroup": "dL1_Reloads", +"MetricName": "DL1_RELOAD_FROM_RMEM_RATE", +"ScaleUnit": "1%" +}, +{ +
Re: [PATCH v3 3/4] arch/mips/configs/*_defconfig cleanup
On Thu, Aug 17, 2023 at 07:50:13AM -0400, Trevor Woerner wrote: > Drop CONFIG_IP_NF_TARGET_CLUSTERIP from any remaining mips defconfigs as it > was removed in commit 9db5d918e2c0 ("netfilter: ip_tables: remove clusterip > target"). > > Signed-off-by: Trevor Woerner > --- > arch/mips/configs/ip22_defconfig| 1 - > arch/mips/configs/malta_defconfig | 1 - > arch/mips/configs/malta_kvm_defconfig | 1 - > arch/mips/configs/maltaup_xpa_defconfig | 1 - > arch/mips/configs/rm200_defconfig | 1 - > 5 files changed, 5 deletions(-) applied to mips-next. Thomas. -- Crap can work. Given enough thrust pigs will fly, but it's not necessarily a good idea.[ RFC1925, 2.3 ]
Re: [PATCH] perf test: Skip perf bench breakpoint run if no breakpoints available
Hi Kajol, On Wed Aug 23, 2023 at 1:21 PM IST, Kajol Jain wrote: > Based on commit 7d54a4acd8c1 ("perf test: Skip watchpoint > tests if no watchpoints available"), hardware breakpoints > are not available for power9 platform and because of that > perf bench breakpoint run fails on power9 platform. > Add code to check for the return value of perf_event_open() > in breakpoint run and skip the perf bench breakpoint run, > if hardware breakpoints are not available. > > Result on power9 system before patch changes: > [command]# perf bench breakpoint thread > perf_event_open: No such device > > Result on power9 system after patch changes: > [command]# ./perf bench breakpoint thread > Skipping perf bench breakpoint thread: No hardware support > > Reported-by: Disha Goel > Signed-off-by: Kajol Jain > --- > tools/perf/bench/breakpoint.c | 24 +--- > 1 file changed, 21 insertions(+), 3 deletions(-) Thanks for fixing this to not report an error. A minor nit below, but otherwise: Acked-by: Naveen N Rao > > diff --git a/tools/perf/bench/breakpoint.c b/tools/perf/bench/breakpoint.c > index 41385f89ffc7..dfd18f5db97d 100644 > --- a/tools/perf/bench/breakpoint.c > +++ b/tools/perf/bench/breakpoint.c > @@ -47,6 +47,7 @@ struct breakpoint { > static int breakpoint_setup(void *addr) > { > struct perf_event_attr attr = { .size = 0, }; > + int fd; > > attr.type = PERF_TYPE_BREAKPOINT; > attr.size = sizeof(attr); > @@ -56,7 +57,12 @@ static int breakpoint_setup(void *addr) > attr.bp_addr = (unsigned long)addr; > attr.bp_type = HW_BREAKPOINT_RW; > attr.bp_len = HW_BREAKPOINT_LEN_1; > - return syscall(SYS_perf_event_open, &attr, 0, -1, -1, 0); > + fd = syscall(SYS_perf_event_open, &attr, 0, -1, -1, 0); > + > + if (fd < 0) > + fd = -errno; > + > + return fd; > } > > static void *passive_thread(void *arg) > @@ -122,8 +128,14 @@ int bench_breakpoint_thread(int argc, const char **argv) > > for (i = 0; i < thread_params.nbreakpoints; i++) { > breakpoints[i].fd = breakpoint_setup(&breakpoints[i].watched); > - if (breakpoints[i].fd == -1) > + > + if (breakpoints[i].fd < 0) { > + if (breakpoints[i].fd == -ENODEV) { > + printf("Skipping perf bench breakpoint thread: > No hardware support\n"); > + return 0; Should we instead do 'exit(0)' here to stop further benchmarks? Perhaps: err(EXIT_SUCCESS, "Skipping perf bench breakpoint thread: No hardware support"); EXIT_SUCCESS looks weird, but should help document that this is not an error. > + } > exit((perror("perf_event_open"), EXIT_FAILURE)); > + } > } > gettimeofday(&start, NULL); > for (i = 0; i < thread_params.nparallel; i++) { > @@ -196,8 +208,14 @@ int bench_breakpoint_enable(int argc, const char **argv) > exit(EXIT_FAILURE); > } > fd = breakpoint_setup(&watched); > - if (fd == -1) > + > + if (fd < 0) { > + if (fd == -ENODEV) { > + printf("Skipping perf bench breakpoint enable: No > hardware support\n"); > + return 0; Here too. - Naveen > + } > exit((perror("perf_event_open"), EXIT_FAILURE)); > + } > nthreads = enable_params.npassive + enable_params.nactive; > threads = calloc(nthreads, sizeof(threads[0])); > if (!threads)
Re: [PATCH] ibmveth: Use dcbf rather than dcbfl
Hello: This patch was applied to netdev/net.git (main) by David S. Miller : On Wed, 23 Aug 2023 14:51:39 +1000 you wrote: > When building for power4, newer binutils don't recognise the "dcbfl" > extended mnemonic. > > dcbfl RA, RB is equivalent to dcbf RA, RB, 1. > > Switch to "dcbf" to avoid the build error. > > [...] Here is the summary with links: - ibmveth: Use dcbf rather than dcbfl https://git.kernel.org/netdev/net/c/bfedba3b2c77 You are awesome, thank you! -- Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html
Re: [PATCH] perf test: Skip perf bench breakpoint run if no breakpoints available
Em Wed, Aug 23, 2023 at 01:21:03PM +0530, Kajol Jain escreveu: > Based on commit 7d54a4acd8c1 ("perf test: Skip watchpoint > tests if no watchpoints available"), hardware breakpoints > are not available for power9 platform and because of that > perf bench breakpoint run fails on power9 platform. > Add code to check for the return value of perf_event_open() > in breakpoint run and skip the perf bench breakpoint run, > if hardware breakpoints are not available. > > Result on power9 system before patch changes: > [command]# perf bench breakpoint thread > perf_event_open: No such device > > Result on power9 system after patch changes: > [command]# ./perf bench breakpoint thread > Skipping perf bench breakpoint thread: No hardware support > > Reported-by: Disha Goel > Signed-off-by: Kajol Jain Thanks, applied. - Arnaldo > --- > tools/perf/bench/breakpoint.c | 24 +--- > 1 file changed, 21 insertions(+), 3 deletions(-) > > diff --git a/tools/perf/bench/breakpoint.c b/tools/perf/bench/breakpoint.c > index 41385f89ffc7..dfd18f5db97d 100644 > --- a/tools/perf/bench/breakpoint.c > +++ b/tools/perf/bench/breakpoint.c > @@ -47,6 +47,7 @@ struct breakpoint { > static int breakpoint_setup(void *addr) > { > struct perf_event_attr attr = { .size = 0, }; > + int fd; > > attr.type = PERF_TYPE_BREAKPOINT; > attr.size = sizeof(attr); > @@ -56,7 +57,12 @@ static int breakpoint_setup(void *addr) > attr.bp_addr = (unsigned long)addr; > attr.bp_type = HW_BREAKPOINT_RW; > attr.bp_len = HW_BREAKPOINT_LEN_1; > - return syscall(SYS_perf_event_open, &attr, 0, -1, -1, 0); > + fd = syscall(SYS_perf_event_open, &attr, 0, -1, -1, 0); > + > + if (fd < 0) > + fd = -errno; > + > + return fd; > } > > static void *passive_thread(void *arg) > @@ -122,8 +128,14 @@ int bench_breakpoint_thread(int argc, const char **argv) > > for (i = 0; i < thread_params.nbreakpoints; i++) { > breakpoints[i].fd = breakpoint_setup(&breakpoints[i].watched); > - if (breakpoints[i].fd == -1) > + > + if (breakpoints[i].fd < 0) { > + if (breakpoints[i].fd == -ENODEV) { > + printf("Skipping perf bench breakpoint thread: > No hardware support\n"); > + return 0; > + } > exit((perror("perf_event_open"), EXIT_FAILURE)); > + } > } > gettimeofday(&start, NULL); > for (i = 0; i < thread_params.nparallel; i++) { > @@ -196,8 +208,14 @@ int bench_breakpoint_enable(int argc, const char **argv) > exit(EXIT_FAILURE); > } > fd = breakpoint_setup(&watched); > - if (fd == -1) > + > + if (fd < 0) { > + if (fd == -ENODEV) { > + printf("Skipping perf bench breakpoint enable: No > hardware support\n"); > + return 0; > + } > exit((perror("perf_event_open"), EXIT_FAILURE)); > + } > nthreads = enable_params.npassive + enable_params.nactive; > threads = calloc(nthreads, sizeof(threads[0])); > if (!threads) > -- > 2.39.3 > -- - Arnaldo
Re: (subset) [PATCH 00/17] -Wmissing-prototype warning fixes
On Thu, 10 Aug 2023 16:19:18 +0200, Arnd Bergmann wrote: > Most of the patches I sent so far for the -Wmissing-prototype warnings > have made it into linux-next now. There are a few that I'm resending > now as nobody has picked them up, and then a number of fixes that I > found while test-building across all architectures rather than just the > ones I usually test. > > The first 15 patches in this series should be uncontroversial, so > I expect that either a subsystem maintainer or Andrew Morton can > apply these directly. > > [...] Applied to powerpc/next. [06/17] macintosh/ams: mark ams_init() static https://git.kernel.org/powerpc/c/cd50430ceb3598957803934068531a274349bcf9 cheers
Re: (subset) [PATCH v4 1/2] powerpc/mm: Cleanup memory block size probing
On Tue, 01 Aug 2023 10:14:46 +0530, Aneesh Kumar K.V wrote: > Parse the device tree in early init to find the memory block size to be > used by the kernel. Consolidate the memory block size device tree parsing > to one helper and use that on both powernv and pseries. We still want to > use machine-specific callback because on all machine types other than > powernv and pseries we continue to return MIN_MEMORY_BLOCK_SIZE. > > pseries_memory_block_size used to look for the second memory > block (memory@x) to determine the memory_block_size value. This patch > changed that to look at all memory blocks and make sure we can map them all > correctly using the computed memory block size value. > > [...] Patch 1 applied to powerpc/next. [1/2] powerpc/mm: Cleanup memory block size probing https://git.kernel.org/powerpc/c/4d15721177d539d743fcf31d7bb376fb3b81aeb6 cheers
Re: [PATCH 1/2] powerpc: mark more local variables as volatile
On Wed, 09 Aug 2023 15:10:08 +0200, Arnd Bergmann wrote: > A while ago I created a2305e3de8193 ("powerpc: mark local variables > around longjmp as volatile") in order to allow building powerpc with > -Wextra enabled on gcc-11. > > I tried this again with gcc-13 and found two more of the same issues, > presumably based on slightly different optimization paths being taken > here: > > [...] Applied to powerpc/next. [1/2] powerpc: mark more local variables as volatile https://git.kernel.org/powerpc/c/0f7ce21ab5209426b00636636a5f2d9008738654 [2/2] powerpc: xmon: remove unused variables https://git.kernel.org/powerpc/c/ef73dcaa31217c79adc548bf9045afb40ac75b82 cheers
Re: [PATCH 0/7] Rework perf and ptrace watchpoint tracking
On Tue, 01 Aug 2023 11:17:37 +1000, Benjamin Gray wrote: > Syzkaller triggered a null pointer dereference in the > arch_unregister_hw_breakpoint() hook. This is due to accessing > the bp->ctx->task field changing to -1 while we iterate the breakpoints. > > This series refactors the breakpoint tracking logic to remove the > dependency on bp->ctx entirely. It also simplifies handling of ptrace and > perf breakpoints, making insertion less restrictive. > > [...] Applied to powerpc/next. [1/7] powerpc/watchpoints: Explain thread_change_pc() more https://git.kernel.org/powerpc/c/8f8f1cd67aa026c9dab8eb4e087e4a2d8fa9d5bc [2/7] powerpc/watchpoints: Don't track info persistently https://git.kernel.org/powerpc/c/668a6ec6ed57f0248070c490aba75a9572e4b0a4 [3/7] powerpc/watchpoints: Track perf single step directly on the breakpoint https://git.kernel.org/powerpc/c/1e60f3564bad09962646bf8c2af588ecf518d337 [4/7] powerpc/watchpoints: Simplify watchpoint reinsertion https://git.kernel.org/powerpc/c/5a2d8b9c06712b52b2f0f2fc9a144242277fda74 [5/7] powerpc/watchpoints: Remove ptrace/perf exclusion tracking https://git.kernel.org/powerpc/c/bd29813ae10698f7bdfb3c68eacbb6464ec701ff [6/7] selftests/powerpc/ptrace: Update ptrace-perf watchpoint selftest https://git.kernel.org/powerpc/c/58709f6fc327a997daeeca77aa5e6bd4d4c238cf [7/7] perf/hw_breakpoint: Remove arch breakpoint hooks https://git.kernel.org/powerpc/c/53834a0c09252dea7918a9e1788bad880690900b cheers
Re: (subset) [PATCH v1 0/4] Improve ptrace selftest usability
On Tue, 25 Jul 2023 10:58:37 +1000, Benjamin Gray wrote: > While trying to test changes to the breakpoint implementation in the kernel, I > tried to run the ptrace tests and met many unexplained skips and failures. > > This series addresses the pain points of trying to run these tests and learn > what they are doing. > > Benjamin Gray (4): > Documentation/powerpc: Fix ptrace request names > selftests/powerpc/ptrace: Explain why tests are skipped > selftests/powerpc/ptrace: Fix typo in pid_max search error > selftests/powerpc/ptrace: Declare test temporary variables as volatile > > [...] Patch 1 applied to powerpc/next. [1/4] Documentation/powerpc: Fix ptrace request names https://git.kernel.org/powerpc/c/0e216fa576e1cdea3913fe82b7283fdfb58c5c07 cheers
Re: [PATCH 1/2] powerpc/83xx: Fix style problems in usb.c and remove unneccessary includes from mpc83xx.h
On Wed, 16 Aug 2023 17:22:16 +0200, Christophe Leroy wrote: > Replace printk(KERN_WARN with pr_warn( > > Remove a couple of blank lines > > Re-align multi-line code. > > Replace asm/io.h by linux/io.h > > [...] Applied to powerpc/next. [1/2] powerpc/83xx: Fix style problems in usb.c and remove unneccessary includes from mpc83xx.h https://git.kernel.org/powerpc/c/d25f01fba71dbaa117021aed3ea85cc5476c1a5a [2/2] powerpc/83xx: Split usb.c https://git.kernel.org/powerpc/c/5951b62ba4635881f1eb6c30e35d476871ff5d12 cheers
Re: [PATCH] powerpc/47x: Add prototype for mmu_init_secondary()
On Thu, 17 Aug 2023 16:25:49 +0200, Christophe Leroy wrote: > A W=1 build of 44x/iss476-smp_defconfig gives: > > arch/powerpc/mm/nohash/44x.c:220:13: error: no previous prototype for > 'mmu_init_secondary' [-Werror=missing-prototypes] > 220 | void __init mmu_init_secondary(int cpu) > | ^~ > > That function is called from head_4xx.S > > [...] Applied to powerpc/next. [1/1] powerpc/47x: Add prototype for mmu_init_secondary() https://git.kernel.org/powerpc/c/b27c1a0a4e62af1fd9d2688bf8156a5d546e4227 cheers
Re: [PATCH] powerpc/4xx: Add missing includes to fix no previous prototype errors
On Thu, 17 Aug 2023 16:27:23 +0200, Christophe Leroy wrote: > A W=1 build of ppc40x_defconfig throws the followings errors: > > CC arch/powerpc/platforms/4xx/uic.o > arch/powerpc/platforms/4xx/uic.c:274:13: warning: no previous prototype for > 'uic_init_tree' [-Wmissing-prototypes] > 274 | void __init uic_init_tree(void) > | ^ > arch/powerpc/platforms/4xx/uic.c:319:14: warning: no previous prototype for > 'uic_get_irq' [-Wmissing-prototypes] > 319 | unsigned int uic_get_irq(void) > | ^~~ > CC arch/powerpc/platforms/4xx/machine_check.o > CC arch/powerpc/platforms/4xx/soc.o > arch/powerpc/platforms/4xx/soc.c:193:6: warning: no previous prototype for > 'ppc4xx_reset_system' [-Wmissing-prototypes] > 193 | void ppc4xx_reset_system(char *cmd) > | ^~~ > > [...] Applied to powerpc/next. [1/1] powerpc/4xx: Add missing includes to fix no previous prototype errors https://git.kernel.org/powerpc/c/7dac7cf1b407605c15d85ae885377ba0560ca4cd cheers
Re: [PATCH] powerpc/4xx: Remove pika_dtm_[un]register_shutdown() to fix no previous prototype
On Thu, 17 Aug 2023 15:44:26 +0200, Christophe Leroy wrote: > ppc4xx_defconfig with W=1 results in: > > CC arch/powerpc/platforms/44x/warp.o > arch/powerpc/platforms/44x/warp.c:369:5: error: no previous prototype for > 'pika_dtm_register_shutdown' [-Werror=missing-prototypes] > 369 | int pika_dtm_register_shutdown(void (*func)(void *arg), void *arg) > | ^~ > arch/powerpc/platforms/44x/warp.c:374:5: error: no previous prototype for > 'pika_dtm_unregister_shutdown' [-Werror=missing-prototypes] > 374 | int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg) > | ^~~~ > > [...] Applied to powerpc/next. [1/1] powerpc/4xx: Remove pika_dtm_[un]register_shutdown() to fix no previous prototype https://git.kernel.org/powerpc/c/81554d10b22a211e4598a067a0f84b6e9e492669 cheers
Re: [PATCH] powerpc/4xx: Remove WatchdogHandler() to fix no previous prototype error
On Thu, 17 Aug 2023 14:40:49 +0200, Christophe Leroy wrote: > Building ppc40x_defconfig throws the following error: > > CC arch/powerpc/kernel/traps.o > arch/powerpc/kernel/traps.c:2232:29: warning: no previous prototype for > 'WatchdogHandler' [-Wmissing-prototypes] > 2232 | void __attribute__ ((weak)) WatchdogHandler(struct pt_regs *regs) > | ^~~ > > [...] Applied to powerpc/next. [1/1] powerpc/4xx: Remove WatchdogHandler() to fix no previous prototype error https://git.kernel.org/powerpc/c/ca13c130a43fe3ab625d22ada0a61e5c0b612229 cheers
Re: [PATCH] powerpc/82xx: Remove CONFIG_8260 and CONFIG_8272
On Thu, 17 Aug 2023 10:05:49 +0200, Christophe Leroy wrote: > CONFIG_8272 is never used, remove it. > > CONFIG_8260 is redundant with CONFIG_PPC_82xx, remove it. > > Applied to powerpc/next. [1/1] powerpc/82xx: Remove CONFIG_8260 and CONFIG_8272 https://git.kernel.org/powerpc/c/eb5aa2137275da82052586f9bd405a1358b48139 cheers
Re: [PATCH] powerpc/82xx: Remove pq2_init_pci
On Thu, 17 Aug 2023 10:05:08 +0200, Christophe Leroy wrote: > Commit 859b21a008eb ("powerpc: drop PowerQUICC II Family ADS platform > support") removed last user of pq2_init_pci. > > Remove it. > > Applied to powerpc/next. [1/1] powerpc/82xx: Remove pq2_init_pci https://git.kernel.org/powerpc/c/188da8af0a06b985c2e0f00ec04bd12dbbf870eb cheers
Re: [PATCH] powerpc/8xx: Remove init_internal_rtc() to fix no previous prototype error
On Thu, 17 Aug 2023 14:26:45 +0200, Christophe Leroy wrote: > A W=1 build of mpc885_ads_defconfig throws the following error: > > CC arch/powerpc/platforms/8xx/m8xx_setup.o > arch/powerpc/platforms/8xx/m8xx_setup.c:41:1: error: no previous prototype > for 'init_internal_rtc' [-Werror=missing-prototypes] >41 | init_internal_rtc(void) > | ^ > > [...] Applied to powerpc/next. [1/1] powerpc/8xx: Remove init_internal_rtc() to fix no previous prototype error https://git.kernel.org/powerpc/c/4531f128eac356144545b833908b6ffbc0292e16 cheers
Re: [PATCH] powerpc/fsl_pci: Make fsl_add_bridge() static
On Wed, 16 Aug 2023 17:19:54 +0200, Christophe Leroy wrote: > Since commit 905e75c46dba ("powerpc/fsl-pci: Unify pci/pcie initialization > code") > fsl_add_bridge() is not used anymore outside of fsl_pci.c > > Make it static. > > Applied to powerpc/next. [1/1] powerpc/fsl_pci: Make fsl_add_bridge() static https://git.kernel.org/powerpc/c/6960c53c4c32865a7e79022e626aa82b64da4110 cheers
Re: [PATCH] powerpc/perf: Convert fsl_emb notifier to state machine callbacks
On Fri, 18 Aug 2023 10:59:44 +0200, Christophe Leroy wrote: > CC arch/powerpc/perf/core-fsl-emb.o > arch/powerpc/perf/core-fsl-emb.c:675:6: error: no previous prototype for > 'hw_perf_event_setup' [-Werror=missing-prototypes] > 675 | void hw_perf_event_setup(int cpu) > | ^~~ > > Looks like fsl_emb was completely missed by commit 3f6da3905398 ("perf: > Rework and fix the arch CPU-hotplug hooks") > > [...] Applied to powerpc/next. [1/1] powerpc/perf: Convert fsl_emb notifier to state machine callbacks https://git.kernel.org/powerpc/c/34daf445f82bd3a4df852bb5f1dffd792ac830a0 cheers
Re: [PATCH] powerpc/radix: Move some functions into #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
On Wed, 09 Aug 2023 10:01:43 +0200, Christophe Leroy wrote: > With skiboot_defconfig, Clang reports: > > CC arch/powerpc/mm/book3s64/radix_tlb.o > arch/powerpc/mm/book3s64/radix_tlb.c:419:20: error: unused function > '_tlbie_pid_lpid' [-Werror,-Wunused-function] > static inline void _tlbie_pid_lpid(unsigned long pid, unsigned long lpid, >^ > arch/powerpc/mm/book3s64/radix_tlb.c:663:20: error: unused function > '_tlbie_va_range_lpid' [-Werror,-Wunused-function] > static inline void _tlbie_va_range_lpid(unsigned long start, unsigned long > end, >^ > > [...] Applied to powerpc/next. [1/1] powerpc/radix: Move some functions into #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE https://git.kernel.org/powerpc/c/4a9dd8f292efd614f0a18452e6474fe19ae17b47 cheers
Re: [PATCH] powerpc/reg: Remove #ifdef around mtspr macro
On Wed, 21 Jun 2023 12:40:50 +0200, Christophe Leroy wrote: > That ifdef was introduced by commit 1458dd951f7c ("powerpc/8xx: > Handle CPU6 ERRATA directly in mtspr() macro") and left over by > commit 2a45addd21de ("powerpc/8xx: Remove CPU6 ERRATA Workaround") > > Remove it. > > > [...] Applied to powerpc/next. [1/1] powerpc/reg: Remove #ifdef around mtspr macro https://git.kernel.org/powerpc/c/6039fcd3fba99451ea9d013c4d3a65a40b2feff0 cheers
Re: [PATCH] powerpc/step: Mark __copy_mem_out() and __emulate_dcbz() __always_inline
On Wed, 21 Jun 2023 12:38:10 +0200, Christophe Leroy wrote: > objtool reports two folliwng warnings: > arch/powerpc/lib/sstep.o: warning: objtool: copy_mem_out+0x3c > (.text+0x30c): call to __copy_mem_out() with UACCESS enabled > arch/powerpc/lib/sstep.o: warning: objtool: emulate_dcbz+0x70 > (.text+0x4dc): call to __emulate_dcbz() with UACCESS enabled > > Mark __copy_mem_out() and __emulate_dcbz() __always_inline > > [...] Applied to powerpc/next. [1/1] powerpc/step: Mark __copy_mem_out() and __emulate_dcbz() __always_inline https://git.kernel.org/powerpc/c/0d5769f9503d9a88661b82fee6a320e711f8b01a cheers
Re: [PATCH v1 1/6] powerpc/include: Remove unneeded #include
On Tue, 08 Aug 2023 08:04:38 +0200, Christophe Leroy wrote: > tqm8xx_setup.c and fs_enet.h don't use any items provided by fs_pd.h > > Remove unneeded #include > > Applied to powerpc/next. [1/6] powerpc/include: Remove unneeded #include https://git.kernel.org/powerpc/c/60bc069c433fc89caa97927b1636401a0e647f67 [2/6] powerpc/include: Declare mpc8xx_immr in 8xx_immap.h https://git.kernel.org/powerpc/c/e6e077cb2aa4ffb8b320f9a1464f29a21986a901 [3/6] powerpc/include: Remove mpc8260.h and m82xx_pci.h https://git.kernel.org/powerpc/c/fecc436a97afed920486be609c3989e05547a384 [4/6] powerpc: Remove CONFIG_PCI_8260 https://git.kernel.org/powerpc/c/cb888cdf741c958cae3e00b649fb7ed5c9bb2d49 [5/6] powerpc/8xx: Remove immr_map() and immr_unmap() https://git.kernel.org/powerpc/c/fbbf4280dae4c02d2f176a8fdac7a7d32fe76fc0 [6/6] powerpc/cpm2: Remove cpm2_map() and cpm2_unmap() https://git.kernel.org/powerpc/c/7768716d2f1906c9258ed4b39584da6317020594 cheers
Re: [PATCH v2] powerpc/32s: Cleanup the mess in __set_pte_at()
On Tue, 15 Aug 2023 19:42:40 +0200, Christophe Leroy wrote: > __set_pte_at() handles 3 main cases with #ifdefs plus the 'percpu' > subcase which leads to code duplication. > > Rewrite the function using IS_ENABLED() to minimise the total number > of cases and remove duplicated code. > > > [...] Applied to powerpc/next. [1/1] powerpc/32s: Cleanup the mess in __set_pte_at() https://git.kernel.org/powerpc/c/7cb0094be4a5dfb3c91d285977f489d334455e19 cheers
Re: [PATCH v2] powerpc/47x: Remove early_init_mmu_47x() to fix no previous prototype
On Thu, 17 Aug 2023 16:26:44 +0200, Christophe Leroy wrote: > 4xx/iss476-smp_defconfig leads to: > > CC arch/powerpc/mm/nohash/tlb.o > arch/powerpc/mm/nohash/tlb.c:322:13: error: no previous prototype for > 'early_init_mmu_47x' [-Werror=missing-prototypes] > 322 | void __init early_init_mmu_47x(void) > | ^~ > > [...] Applied to powerpc/next. [1/1] powerpc/47x: Remove early_init_mmu_47x() to fix no previous prototype https://git.kernel.org/powerpc/c/ed05c71a574235aec3418d2b5c94f24ae84cc2db cheers
Re: [PATCH v2] powerpc/512x: Make mpc512x_select_reset_compat() static
On Fri, 18 Aug 2023 08:51:48 +0200, Christophe Leroy wrote: > mpc512x_select_reset_compat() is only used in the file it > is defined. > > Make it static. > > Move mpc512x_restart_init() after mpc512x_select_reset_compat(). > > [...] Applied to powerpc/next. [1/1] powerpc/512x: Make mpc512x_select_reset_compat() static https://git.kernel.org/powerpc/c/be922070d0914c6642256ceec6b7be75c0a5ddf3 cheers
Re: [PATCH v2] powerpc/ptrace: Split gpr32_set_common
On Thu, 22 Jun 2023 12:01:23 +0200, Christophe Leroy wrote: > objtool report the following warning: > > arch/powerpc/kernel/ptrace/ptrace-view.o: warning: objtool: > gpr32_set_common+0x23c (.text+0x860): redundant UACCESS disable > > gpr32_set_common() conditionnaly opens and closes UACCESS based on > whether kbuf point is NULL or not. This is wackelig. > > [...] Applied to powerpc/next. [1/1] powerpc/ptrace: Split gpr32_set_common https://git.kernel.org/powerpc/c/9a32584bc108c8fe4d02fa33b16caf686e4a788a cheers
Re: [PATCH v2] arch/powerpc: Remove unnecessary endian conversion code in XICS
On Mon, 31 Jul 2023 17:25:39 +0530, Gautam Menghani wrote: > Remove an unnecessary piece of code that does an endianness conversion but > does not use the result. The following warning was reported by Clang's > static analyzer: > > arch/powerpc/sysdev/xics/ics-opal.c:114:2: warning: Value stored to > 'server' is never read [deadcode.DeadStores] > server = be16_to_cpu(oserver); > > [...] Applied to powerpc/next. [1/1] arch/powerpc: Remove unnecessary endian conversion code in XICS https://git.kernel.org/powerpc/c/984b07b428994d9e83c6de9a5f1307948188fe71 cheers
Re: [PATCH v2] powerpc/fadump: invoke ibm,os-term with rtas_call_unlocked()
On Fri, 09 Jun 2023 12:44:04 +0530, Hari Bathini wrote: > Invoke ibm,os-term call with rtas_call_unlocked(), without using the > RTAS spinlock, to avoid deadlock in the unlikely event of a machine > crash while making an RTAS call. > > Applied to powerpc/next. [1/1] powerpc/fadump: invoke ibm,os-term with rtas_call_unlocked() https://git.kernel.org/powerpc/c/b949ee6801f4a47ae0e02845242c99af351c4d26 cheers
Re: [PATCH] powerpc/ps3: refactor strncpy usage
On Wed, 16 Aug 2023 21:39:24 +, Justin Stitt wrote: > `strncpy` is deprecated for use on NUL-terminated destination strings [1]. > > `make_first_field()` should use similar implementation to `make_field()` > due to memcpy having more obvious behavior here. The end result yields > the same behavior as the previous `strncpy`-based implementation > including the NUL-padding. > > [...] Applied to powerpc/next. [1/1] powerpc/ps3: refactor strncpy usage https://git.kernel.org/powerpc/c/f94a84a0914841d79a38df7cc75512d88b31a0dc cheers
Re: [PATCH v4 00/10] Add sysfs interface files to hv_gpci device to expose system information
On Sat, 29 Jul 2023 13:04:45 +0530, Kajol Jain wrote: > The hcall H_GET_PERF_COUNTER_INFO can be used to get data related to > chips, dimms and system topology, by passing different counter request > values. > Patchset adds sysfs files to "/sys/devices/hv_gpci/interface/" > of hv_gpci pmu driver, which will expose system topology information > using H_GET_PERF_COUNTER_INFO hcall. The added sysfs files are > available for power10 and above platforms and needs root access > to read the data. > > [...] Applied to powerpc/next. [01/10] powerpc/hv_gpci: Add sysfs file inside hv_gpci device to show processor bus topology information https://git.kernel.org/powerpc/c/71f1c39647d8c9d4d54a861ec81f1ff17544bcb6 [02/10] docs: ABI: sysfs-bus-event_source-devices-hv_gpci: Document processor_bus_topology sysfs interface file https://git.kernel.org/powerpc/c/9caf9e2b8bae58e39501f6fb1fc9189009538ccc [03/10] powerpc/hv_gpci: Add sysfs file inside hv_gpci device to show processor config information https://git.kernel.org/powerpc/c/1a160c2a13c66c9ad47436e73c821f3d26818733 [04/10] docs: ABI: sysfs-bus-event_source-devices-hv_gpci: Document processor_config sysfs interface file https://git.kernel.org/powerpc/c/3255171d3e861b14e4248a5c676099819cadfb6d [05/10] powerpc/hv_gpci: Add sysfs file inside hv_gpci device to show affinity domain via virtual processor information https://git.kernel.org/powerpc/c/71a7ccb478fcfe1495bcabf4972d859b24264df7 [06/10] docs: ABI: sysfs-bus-event_source-devices-hv_gpci: Document affinity_domain_via_virtual_processor sysfs interface file https://git.kernel.org/powerpc/c/cc89ff3491b61cebc90b3394eb6b36635173d0dd [07/10] powerpc/hv_gpci: Add sysfs file inside hv_gpci device to show affinity domain via domain information https://git.kernel.org/powerpc/c/a69a57cac1ec8995bb0b571dfccc3fe2f046719a [08/10] docs: ABI: sysfs-bus-event_source-devices-hv_gpci: Document affinity_domain_via_domain sysfs interface file https://git.kernel.org/powerpc/c/ab7e991286e729b0018722591c04eb2fd31771b0 [09/10] powerpc/hv_gpci: Add sysfs file inside hv_gpci device to show affinity domain via partition information https://git.kernel.org/powerpc/c/a15e0d6a6929e737f71578ed4b05531fed5a96e8 [10/10] docs: ABI: sysfs-bus-event_source-devices-hv_gpci: Document affinity_domain_via_partition sysfs interface file https://git.kernel.org/powerpc/c/8df99066940b6c82a0851f13adf653827dc524f7 cheers
Re: [PATCH] powerpc: Make virt_to_pfn() a static inline
On Wed, 09 Aug 2023 10:07:13 +0200, Linus Walleij wrote: > Making virt_to_pfn() a static inline taking a strongly typed > (const void *) makes the contract of a passing a pointer of that > type to the function explicit and exposes any misuse of the > macro virt_to_pfn() acting polymorphic and accepting many types > such as (void *), (unitptr_t) or (unsigned long) as arguments > without warnings. > > [...] Applied to powerpc/next. [1/1] powerpc: Make virt_to_pfn() a static inline https://git.kernel.org/powerpc/c/58b6fed89ab0f602de0d143c617c29c3d4c67429 cheers
Re: [PATCH v9 1/2] powerpc/rtas: export rtas_error_rc() for reuse.
On Fri, 18 Aug 2023 16:59:07 +0530, Mahesh Salgaonkar wrote: > Also, #define descriptive names for common rtas return codes and use it > instead of numeric values. > > Applied to powerpc/next. [1/2] powerpc/rtas: export rtas_error_rc() for reuse. https://git.kernel.org/powerpc/c/e160bf64e2d3df7bf83ed41d09390a32490be6c5 [2/2] PCI: rpaphp: Error out on busy status from get-sensor-state https://git.kernel.org/powerpc/c/77583f77ed9b1452ac62caebf09b2206da10bbf9 cheers
Re: [PATCH 1/3] powerpc: remove unneeded #include
On Mon, 07 Aug 2023 00:09:52 +0900, Masahiro Yamada wrote: > There is no EXPORT_SYMBOL line there, hence #include > is unneeded. > > Applied to powerpc/next. [1/3] powerpc: remove unneeded #include https://git.kernel.org/powerpc/c/3eb3f168e83aa7a7b8477507cf4b08b9515b4b13 [2/3] powerpc: replace #include with #include https://git.kernel.org/powerpc/c/393261828740c3ed95fc810c3f4c1018b86af7e5 [3/3] powerpc: remove https://git.kernel.org/powerpc/c/efa1f85019537ce44832cf73a6db18611e3e41cd cheers
Re: [PATCH] powerpc: Move DMA64_PROPNAME define to a header
On Thu, 17 Aug 2023 18:24:08 +0200, Michal Suchanek wrote: > Avoid redefining the same value in multiple source. > > Applied to powerpc/next. [1/1] powerpc: Move DMA64_PROPNAME define to a header https://git.kernel.org/powerpc/c/89c9ce1c99df553029fc4503506ff5a1793f3eaf cheers
Re: [PATCH 0/2] powerpc/selftests: miscellaneous improvements
On Thu, 17 Aug 2023 11:21:51 -0500, Nathan Lynch wrote: > Just some minor things to tidy up I noticed when adding tests. > Applied to powerpc/next. [1/2] powerpc/selftests: sort mm/.gitignore, add exec_prot https://git.kernel.org/powerpc/c/ae3a8cc292d01a1558dff837bb485712dfaeb9c6 [2/2] selftests/powerpc: add const qualification where possible https://git.kernel.org/powerpc/c/701ca3657d5d489add2bedce0c31938e521c7913 cheers
Re: [PATCH 00/17] powerpc/ftrace: refactor and add support for -fpatchable-function-entry
On Mon, 19 Jun 2023 15:17:18 +0530, Naveen N Rao wrote: > Since RFC (*): > - Patches 1 and 17 have been included in this series due to > dependencies. Both had been posted out separately. > - Patch 10 has a small change to not throw errors when checking > instruction sequence generated by older toolchains. > > This has had more testing since and this looks good to me. Christophe > mentioned that this results in a slowdown with ftrace [de-]activation on > ppc32, but that isn't performance critical and we can address that > separately. > > [...] Patch 1-16 applied to powerpc/next. [01/17] powerpc/ftrace: Fix dropping weak symbols with older toolchains https://git.kernel.org/powerpc/c/f6834c8c59a8e977a6f6e4f96c5d28dfa5db8430 [02/17] powerpc/module: Remove unused .ftrace.tramp section https://git.kernel.org/powerpc/c/0240605931ec300ddb698020edff05a4c93edbb2 [03/17] powerpc64/ftrace: Move ELFv1 and -pg support code into a separate file https://git.kernel.org/powerpc/c/7f7797b372693ce17223678428490dea2b3e4389 [04/17] powerpc/ftrace: Simplify function_graph support in ftrace.c https://git.kernel.org/powerpc/c/96d7a13610abcf6bff9d0d0e195c6d2650310125 [05/17] powerpc/ftrace: Use FTRACE_REGS_ADDR to identify the correct ftrace trampoline https://git.kernel.org/powerpc/c/b5efb61c70f8ba9b1e168185530b9c7342184a4c [06/17] powerpc/ftrace: Extend ftrace support for large kernels to ppc32 https://git.kernel.org/powerpc/c/f3993a0330e2d11e42c095810c6c33084024df46 [07/17] powerpc/ftrace: Consolidate ftrace support into fewer files https://git.kernel.org/powerpc/c/bad90aa52d9a0141c41e00ccd4c40be30a29acc6 [08/17] powerpc/ftrace: Refactor ftrace_modify_code() https://git.kernel.org/powerpc/c/f4fcbf2e093e25a7faa8a3c2a5097524114e9547 [09/17] powerpc/ftrace: Stop re-purposing linker generated long branches for ftrace https://git.kernel.org/powerpc/c/33bb8a0be9c826fce545ae390ecaf91e96b5db43 [10/17] powerpc/ftrace: Add separate ftrace_init_nop() with additional validation https://git.kernel.org/powerpc/c/cc93b9233230312a8a905fabd590c405d60f9edd [11/17] powerpc/ftrace: Simplify ftrace_make_nop() https://git.kernel.org/powerpc/c/562bde0bfc968d212d10ba6bf921a0774feebbac [12/17] powerpc/ftrace: Simplify ftrace_make_call() https://git.kernel.org/powerpc/c/9365e23b15f28b7b3b333a7fc6f4c8e9464ca99f [13/17] powerpc/ftrace: Simplify ftrace_modify_call() https://git.kernel.org/powerpc/c/67385738e3c248673668663ffb434ae4e0abf7f1 [14/17] powerpc/ftrace: Replace use of ftrace_call_replace() with ftrace_create_branch_inst() https://git.kernel.org/powerpc/c/a26ce4272eea2b20d4f39b9d7e56daf0c77151d8 [15/17] powerpc/ftrace: Implement ftrace_replace_code() https://git.kernel.org/powerpc/c/c91c5a828685563c24ab8879d8386de356d9085a [16/17] powerpc/ftrace: Add support for -fpatchable-function-entry https://git.kernel.org/powerpc/c/0f71dcfb4aef6043da6cc509e7a7f6a3ae87c12d cheers
Re: [PATCH] Revert "powerpc/xmon: Relax frame size for clang"
On Thu, 17 Aug 2023 11:11:56 -0700, ndesaulni...@google.com wrote: > This reverts commit 9c87156cce5a63735d1218f0096a65c50a7a32aa. > > I have not been able to reproduce the reported -Wframe-larger-than= > warning (or disassembly) with clang-11 or clang-18. > > I don't know precisely when this was fixed in llvm, but it may be time > to revert this. > > [...] Applied to powerpc/next. [1/1] Revert "powerpc/xmon: Relax frame size for clang" https://git.kernel.org/powerpc/c/7f3c5d099b6f8452dc4dcfe4179ea48e6a13d0eb cheers
Re: [PATCH v3] powerpc/inst: add PPC_TLBILX_LPID
On Thu, 03 Aug 2023 11:33:52 -0700, Nick Desaulniers wrote: > Clang didn't recognize the instruction tlbilxlpid. This was fixed in > clang-18 [0] then backported to clang-17 [1]. To support clang-16 and > older, rather than using that instruction bare in inline asm, add it to > ppc-opcode.h and use that macro as is done elsewhere for other > instructions. > > > [...] Applied to powerpc/next. [1/1] powerpc/inst: add PPC_TLBILX_LPID https://git.kernel.org/powerpc/c/ae7936d232d862e5b8311180036281ffe93735b8 cheers
Re: [PATCH] powerpc/pseries: PLPKS: undo kernel-doc comment notation
On Wed, 09 Aug 2023 17:07:40 -0700, Randy Dunlap wrote: > Don't use kernel-doc "/**" comment format for non-kernel-doc comments. > This prevents a kernel-doc warning: > > arch/powerpc/platforms/pseries/plpks.c:186: warning: This comment starts > with '/**', but isn't a kernel-doc comment. Refer > Documentation/doc-guide/kernel-doc.rst > * Label is combination of label attributes + name. > > > [...] Applied to powerpc/next. [1/1] powerpc/pseries: PLPKS: undo kernel-doc comment notation https://git.kernel.org/powerpc/c/506e550a7da9e995bea3bd585db591068f98b2bf cheers
Re: [PATCH] powerpc/pseries: fix possible memory leak in ibmebus_bus_init()
On Thu, 10 Nov 2022 09:19:29 +0800, ruanjinjie wrote: > If device_register() returns error in ibmebus_bus_init(), name of kobject > which is allocated in dev_set_name() called in device_add() is leaked. > > As comment of device_add() says, it should call put_device() to drop > the reference count that was set in device_initialize() when it fails, > so the name can be freed in kobject_cleanup(). > > [...] Applied to powerpc/next. [1/1] powerpc/pseries: fix possible memory leak in ibmebus_bus_init() https://git.kernel.org/powerpc/c/afda85b963c12947e298ad85d757e333aa40fd74 cheers
Re: [PATCH v2] powerpc/fadump: reset dump area size if fadump memory reserve fails
On Tue, 04 Jul 2023 10:37:15 +0530, Sourabh Jain wrote: > In case fadump_reserve_mem() fails to reserve memory, the > reserve_dump_area_size variable will retain the reserve area size. This > will lead to /sys/kernel/fadump/mem_reserved node displaying an incorrect > memory reserved by fadump. > > To fix this problem, reserve dump area size variable is set to 0 if fadump > failed to reserve memory. > > [...] Applied to powerpc/next. [1/1] powerpc/fadump: reset dump area size if fadump memory reserve fails https://git.kernel.org/powerpc/c/d1eb75e0dfed80d2d85b664e28a39f65b290ab55 cheers
Re: [PATCH] powerpc: pmac32: enable serial options by default in defconfig
On Wed, 02 Aug 2023 21:41:30 +0800, Yuan Tan wrote: > Serial is a critical feature for logging and debuging, and the other > architectures enable serial by default. > > Let's enable CONFIG_SERIAL_PMACZILOG and CONFIG_SERIAL_PMACZILOG_CONSOLE > by default. > > > [...] Applied to powerpc/next. [1/1] powerpc: pmac32: enable serial options by default in defconfig https://git.kernel.org/powerpc/c/0b5e06e9cb156e7e97bfb4e1ebf6acd62497eaf5 cheers
Re: (subset) [PATCH v3 0/4] general defconfig cleanups
On Thu, 17 Aug 2023 07:50:10 -0400, Trevor Woerner wrote: > Drop config options from defconfigs whose code has been removed. > > v3: > While reorganizing the patches, I put the wrong commit message with the > CONFIG_IP_NF_TARGET_CLUSTERIP option. > > v2: > Generate arch-specific patches. In v1 I organized the patches by > CONFIG_ option which caused some of the patches to cross architectural > lines. This requires cross-arch consensus before they can be applied. > Therefore organize the changes by architecture so each one can apply them > independently (or not). > > [...] Patch 4 applied to powerpc/next. [4/4] arch/powerpc/configs/*_defconfig cleanup https://git.kernel.org/powerpc/c/455d3d38ef9d5f69c504d1af5fa2359563ea4148 cheers
Re: [PATCH] powerpc: Enable generic cpu idle-loop
On Fri, 18 Aug 2023 10:37:37 +0530, Vaibhav Jain wrote: > This minor patch enables config option GENERIC_IDLE_POLL_SETUP for arch > powerpc. This should add support for kernel param 'nohlt'. > > Powerpc kernel also supports another kernel boot-time param called > 'powersave' which can also be used to disable all cpu idle-states and > forces CPU to an idle-loop similar to what cpu_idle_poll() does. This > patch however makes powerpc kernel-parameters better aligned to the > generic boot-time parameters. > > [...] Applied to powerpc/next. [1/1] powerpc: Enable generic cpu idle-loop https://git.kernel.org/powerpc/c/0ceef6e99cc3a57f33b84dafc6df5dfb3b28278d cheers
Re: [PATCH] powerpc/powernv/pci: use pci_dev_id() to simplify the code
On Fri, 04 Aug 2023 16:04:35 +0800, Xiongfeng Wang wrote: > PCI core API pci_dev_id() can be used to get the BDF number for a pci > device. We don't need to compose it mannually. Use pci_dev_id() to > simplify the code a little bit. > > Applied to powerpc/next. [1/1] powerpc/powernv/pci: use pci_dev_id() to simplify the code https://git.kernel.org/powerpc/c/fe8aa8e3379326ecb77203cae50e8e83c054aedc cheers
Re: [RFC PATCH] cxl: Use pci_find_vsec_capability() to simplify the code
On Fri, 04 Aug 2023 15:56:30 +0800, Xiongfeng Wang wrote: > PCI core add pci_find_vsec_capability() to query VSEC. We can use that > core API to simplify the code. > > The only logical change is that pci_find_vsec_capability check the > Vendor ID before finding the VSEC. > > PCI spec rev 5.0 says in 7.9.5.2 Vendor-Specific Header: > VSEC ID - This field is a vendor-defined ID number that indicates the > nature and format of the VSEC structure > Software must qualify the Vendor ID before interpreting this field. > > [...] Applied to powerpc/next. [1/1] cxl: Use pci_find_vsec_capability() to simplify the code https://git.kernel.org/powerpc/c/0e1cd3d9f82eb5440d32d4c0f12c65403b956cb5 cheers
Re: [PATCH] ocxl: Use pci_dev_id() to simplify the code
On Fri, 11 Aug 2023 18:20:39 +0800, Zheng Zengkai wrote: > PCI core API pci_dev_id() can be used to get the BDF number for a pci > device. We don't need to compose it mannually. Use pci_dev_id() to > simplify the code a little bit. > > Applied to powerpc/next. [1/1] ocxl: Use pci_dev_id() to simplify the code https://git.kernel.org/powerpc/c/075a88d5eb2806712c64bed98c30b6890ec30311 cheers
Re: [PATCH] perf test: Skip perf bench breakpoint run if no breakpoints available
On 23/08/23 1:21 pm, Kajol Jain wrote: Based on commit 7d54a4acd8c1 ("perf test: Skip watchpoint tests if no watchpoints available"), hardware breakpoints are not available for power9 platform and because of that perf bench breakpoint run fails on power9 platform. Add code to check for the return value of perf_event_open() in breakpoint run and skip the perf bench breakpoint run, if hardware breakpoints are not available. Result on power9 system before patch changes: [command]# perf bench breakpoint thread perf_event_open: No such device Result on power9 system after patch changes: [command]# ./perf bench breakpoint thread Skipping perf bench breakpoint thread: No hardware support Reported-by: Disha Goel Signed-off-by: Kajol Jain With this patch applied perf bench breakpoint test works correctly on Power9 and Power10. Result on Power9 system with patch changes: [root@]# ./perf bench breakpoint all # Running breakpoint/thread benchmark... Skipping perf bench breakpoint thread: No hardware support # Running breakpoint/enable benchmark... Skipping perf bench breakpoint enable: No hardware support Result on Power10 system with patch changes: [root@]# ./perf bench breakpoint all # Running breakpoint/thread benchmark... # Created/joined 10 threads with 1 breakpoints and 1 parallelism Total time: 0.001 [sec] 115.10 usecs/op 115.10 usecs/op/cpu # Running breakpoint/enable benchmark... # Enabled/disabled breakpoint 10 time with 0 passive and 0 active threads Total time: 0.000 [sec] 2.80 usecs/op Tested-by: Disha Goel --- tools/perf/bench/breakpoint.c | 24 +--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/tools/perf/bench/breakpoint.c b/tools/perf/bench/breakpoint.c index 41385f89ffc7..dfd18f5db97d 100644 --- a/tools/perf/bench/breakpoint.c +++ b/tools/perf/bench/breakpoint.c @@ -47,6 +47,7 @@ struct breakpoint { static int breakpoint_setup(void *addr) { struct perf_event_attr attr = { .size = 0, }; + int fd; attr.type = PERF_TYPE_BREAKPOINT; attr.size = sizeof(attr); @@ -56,7 +57,12 @@ static int breakpoint_setup(void *addr) attr.bp_addr = (unsigned long)addr; attr.bp_type = HW_BREAKPOINT_RW; attr.bp_len = HW_BREAKPOINT_LEN_1; - return syscall(SYS_perf_event_open, &attr, 0, -1, -1, 0); + fd = syscall(SYS_perf_event_open, &attr, 0, -1, -1, 0); + + if (fd < 0) + fd = -errno; + + return fd; } static void *passive_thread(void *arg) @@ -122,8 +128,14 @@ int bench_breakpoint_thread(int argc, const char **argv) for (i = 0; i < thread_params.nbreakpoints; i++) { breakpoints[i].fd = breakpoint_setup(&breakpoints[i].watched); - if (breakpoints[i].fd == -1) + + if (breakpoints[i].fd < 0) { + if (breakpoints[i].fd == -ENODEV) { + printf("Skipping perf bench breakpoint thread: No hardware support\n"); + return 0; + } exit((perror("perf_event_open"), EXIT_FAILURE)); + } } gettimeofday(&start, NULL); for (i = 0; i < thread_params.nparallel; i++) { @@ -196,8 +208,14 @@ int bench_breakpoint_enable(int argc, const char **argv) exit(EXIT_FAILURE); } fd = breakpoint_setup(&watched); - if (fd == -1) + + if (fd < 0) { + if (fd == -ENODEV) { + printf("Skipping perf bench breakpoint enable: No hardware support\n"); + return 0; + } exit((perror("perf_event_open"), EXIT_FAILURE)); + } nthreads = enable_params.npassive + enable_params.nactive; threads = calloc(nthreads, sizeof(threads[0])); if (!threads)
[PATCH net-next] kunit: Fix checksum tests on big endian CPUs
On powerpc64le checksum kunit tests work: [2.011457][T1] KTAP version 1 [2.011662][T1] # Subtest: checksum [2.011848][T1] 1..3 [2.034710][T1] ok 1 test_csum_fixed_random_inputs [2.079325][T1] ok 2 test_csum_all_carry_inputs [2.127102][T1] ok 3 test_csum_no_carry_inputs [2.127202][T1] # checksum: pass:3 fail:0 skip:0 total:3 [2.127533][T1] # Totals: pass:3 fail:0 skip:0 total:3 [2.127956][T1] ok 1 checksum But on powerpc64 and powerpc32 they fail: [1.859890][T1] KTAP version 1 [1.860041][T1] # Subtest: checksum [1.860201][T1] 1..3 [1.861927][ T58] # test_csum_fixed_random_inputs: ASSERTION FAILED at lib/checksum_kunit.c:243 [1.861927][ T58] Expected result == expec, but [1.861927][ T58] result == 54991 (0xd6cf) [1.861927][ T58] expec == 33316 (0x8224) [1.863742][T1] not ok 1 test_csum_fixed_random_inputs [1.864520][ T60] # test_csum_all_carry_inputs: ASSERTION FAILED at lib/checksum_kunit.c:267 [1.864520][ T60] Expected result == expec, but [1.864520][ T60] result == 255 (0xff) [1.864520][ T60] expec == 65280 (0xff00) [1.868820][T1] not ok 2 test_csum_all_carry_inputs [1.869977][ T62] # test_csum_no_carry_inputs: ASSERTION FAILED at lib/checksum_kunit.c:306 [1.869977][ T62] Expected result == expec, but [1.869977][ T62] result == 64515 (0xfc03) [1.869977][ T62] expec == 0 (0x0) [1.872060][T1] not ok 3 test_csum_no_carry_inputs [1.872102][T1] # checksum: pass:0 fail:3 skip:0 total:3 [1.872458][T1] # Totals: pass:0 fail:3 skip:0 total:3 [1.872791][T1] not ok 3 checksum This is because all expected values were calculated for X86 which is little endian. On big endian systems all precalculated 16 bits halves must be byte swapped. And this is confirmed by a huge amount of sparse errors when building with C=2 So fix all sparse errors and it will naturally work on all endianness. Fixes: 688eb8191b47 ("x86/csum: Improve performance of `csum_partial`") Signed-off-by: Christophe Leroy --- lib/checksum_kunit.c | 54 +++- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/lib/checksum_kunit.c b/lib/checksum_kunit.c index ace3c4799fe1..0eed92b77ba3 100644 --- a/lib/checksum_kunit.c +++ b/lib/checksum_kunit.c @@ -10,7 +10,8 @@ #define MAX_ALIGN 64 #define TEST_BUFLEN (MAX_LEN + MAX_ALIGN) -static const __wsum random_init_sum = 0x2847aab; +/* Values for a little endian CPU. Byte swap each half on big endian CPU. */ +static const u32 random_init_sum = 0x2847aab; static const u8 random_buf[] = { 0xac, 0xd7, 0x76, 0x69, 0x6e, 0xf2, 0x93, 0x2c, 0x1f, 0xe0, 0xde, 0x86, 0x8f, 0x54, 0x33, 0x90, 0x95, 0xbf, 0xff, 0xb9, 0xea, 0x62, 0x6e, 0xb5, @@ -56,7 +57,9 @@ static const u8 random_buf[] = { 0xe1, 0xdf, 0x4b, 0xe1, 0x81, 0xe2, 0x17, 0x02, 0x7b, 0x58, 0x8b, 0x92, 0x1a, 0xac, 0x46, 0xdd, 0x2e, 0xce, 0x40, 0x09 }; -static const __sum16 expected_results[] = { + +/* Values for a little endian CPU. Byte swap on big endian CPU. */ +static const u16 expected_results[] = { 0x82d0, 0x8224, 0xab23, 0xaaad, 0x41ad, 0x413f, 0x4f3e, 0x4eab, 0x22ab, 0x228c, 0x428b, 0x41ad, 0xbbac, 0xbb1d, 0x671d, 0x66ea, 0xd6e9, 0xd654, 0x1754, 0x1655, 0x5d54, 0x5c6a, 0xfa69, 0xf9fb, 0x44fb, 0x4428, 0xf527, @@ -115,7 +118,9 @@ static const __sum16 expected_results[] = { 0x1d47, 0x3c46, 0x3bc5, 0x59c4, 0x59ad, 0x57ad, 0x5732, 0xff31, 0xfea6, 0x6ca6, 0x6c8c, 0xc08b, 0xc045, 0xe344, 0xe316, 0x1516, 0x14d6, }; -static const __wsum init_sums_no_overflow[] = { + +/* Values for a little endian CPU. Byte swap each half on big endian CPU. */ +static const u32 init_sums_no_overflow[] = { 0x, 0xfffb, 0xfbfb, 0xfbf7, 0xf7f7, 0xf7f3, 0xf3f3, 0xf3ef, 0xefef, 0xefeb, 0xebeb, 0xebe7, 0xe7e7, 0xe7e3, 0xe3e3, 0xe3df, 0xdfdf, 0xdfdb, @@ -208,7 +213,21 @@ static u8 tmp_buf[TEST_BUFLEN]; #define full_csum(buff, len, sum) csum_fold(csum_partial(buff, len, sum)) -#define CHECK_EQ(lhs, rhs) KUNIT_ASSERT_EQ(test, lhs, rhs) +#define CHECK_EQ(lhs, rhs) KUNIT_ASSERT_EQ(test, (__force u64)lhs, (__force u64)rhs) + +static __sum16 to_sum16(u16 x) +{ + return (__force __sum16)le16_to_cpu((__force __le16)x); +} + +/* This function swaps the bytes inside each half of a __wsum */ +static __wsum to_wsum(u32 x) +{ + u16 hi = le16_to_cpu((__force __le16)(x >> 16)); + u16 lo = le16_to_cpu((__force __le16)x); + + return (__force __wsum)((hi << 16) | lo); +} static void assert_setup_correct(struct kunit *test) { @@ -226,7 +245,8 @@ static void assert_setup_correct(struct kunit *test) static void te
Re: [RFC PATCH v2 0/7] Add audio support in v4l2 framework
On Fri, Aug 11, 2023 at 7:05 PM Shengjiu Wang wrote: > > Hi Mark, Takashi > > On Thu, Aug 3, 2023 at 9:11 PM Shengjiu Wang wrote: > > > > On Thu, Aug 3, 2023 at 1:28 AM Mark Brown wrote: > > > > > > On Wed, Aug 02, 2023 at 10:41:43PM +0800, Shengjiu Wang wrote: > > > > > > > Currently the ASRC in ALSA is to connect to another I2S device as > > > > a sound card. But we'd like to the ASRC can be used by user space > > > > directly > > > > that user space application can get the output after conversion from > > > > ASRC. > > > > > > That sort of use case would be handled via DPCM at the minute, though > > > persuading it to connect two front ends together might be fun (which is > > > the sort of reason why we want to push digital information down into > > > DAPM and make everything a component). > > > > Thanks. > > > > ASRC M2M case needs to run as fast as possible, no sync clock control. > > If use sound card to handle ASRC M2M case, the user application > > should be aplay/arecord, then we need to consider xrun issue, buffer > > may timeout, sync between aplay and arecord, these should't be > > considered by pure memory to memory operation. > > > > DPCM may achitect all the audio things in components and sound > > card, it is good. but for the M2M case, it is complcated. not sure > > it is doable. > > > > Beside the concern in previous mail, > > DPCM needs to separate ASRC to be two substreams (playback and capture). > > But the ASRC needs the sample rate & format of input and output first > then start conversion. > > If the playback controls the rate & format of input, capture substream > controls the rate & format of output, as a result > one substream needs to get information(dma buffer address, size... > rate, format) from another substream, then start both substreams in the > last substream. How to synchronize these two substreams is a problem. > One stream can be released but another stream doesn't know . > > So I don't think it is a good idea to use DPCM for pure M2M case. > > So can I persuade you to consider the V4L2 solution? > Just a summary: Basic M2M conversion can work with DPCM, I have tried with some workaround to make it work. But there are several issues: 1. Need to create sound cards. ASRC module support multi instances, then need to create multi sound cards for each instance. 2. The ASRC is an entirety but with DPCM we need to separate input port and output port to playback substream and capture stream. Synchronous between playback substream and capture substream is a problem. How to start them and stop them at the same time. 3. How to handle the xrun issue. pause or resume. which are brought by ALSA. So shall we make the decision that we can go to the V4L2 solution? Best regards Wang Shengjiu
Re: [PATCH v4 1/2] PCI: layerscape: Add support for Link down notification
On Wed, Aug 16, 2023 at 11:53:16AM -0400, Frank Li wrote: > On Mon, Jul 31, 2023 at 11:06:31AM -0400, Frank Li wrote: > > On Thu, Jul 20, 2023 at 09:58:33AM -0400, Frank Li wrote: > > > Add support to pass Link down notification to Endpoint function driver > > > so that the LINK_DOWN event can be processed by the function. > > > > > > Acked-by: Manivannan Sadhasivam > > > Signed-off-by: Frank Li > > > --- > > > > @Lorenzo > > > > Could you please consider pick both patches? > > Manivannan already reviewed and only impact layerscape. > > @lorenzo: > ping > > > > > Frank @lorenzo ping Frank > > > > > Change from v2 to v4 > > > - none > > > Change from v1 to v2 > > > > > > drivers/pci/controller/dwc/pci-layerscape-ep.c | 1 + > > > 1 file changed, 1 insertion(+) > > > > > > diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c > > > b/drivers/pci/controller/dwc/pci-layerscape-ep.c > > > index de4c1758a6c3..e0969ff2ddf7 100644 > > > --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c > > > +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c > > > @@ -89,6 +89,7 @@ static irqreturn_t ls_pcie_ep_event_handler(int irq, > > > void *dev_id) > > > dev_dbg(pci->dev, "Link up\n"); > > > } else if (val & PEX_PF0_PME_MES_DR_LDD) { > > > dev_dbg(pci->dev, "Link down\n"); > > > + pci_epc_linkdown(pci->ep.epc); > > > } else if (val & PEX_PF0_PME_MES_DR_HRD) { > > > dev_dbg(pci->dev, "Hot reset\n"); > > > } > > > -- > > > 2.34.1 > > >
Re: [PATCH v4 1/2] PCI: layerscape: Add support for Link down notification
On Wed, Aug 16, 2023 at 11:53:16AM -0400, Frank Li wrote: > On Mon, Jul 31, 2023 at 11:06:31AM -0400, Frank Li wrote: > > On Thu, Jul 20, 2023 at 09:58:33AM -0400, Frank Li wrote: > > > Add support to pass Link down notification to Endpoint function driver > > > so that the LINK_DOWN event can be processed by the function. > > > > > > Acked-by: Manivannan Sadhasivam > > > Signed-off-by: Frank Li > > > --- > > > > @Lorenzo > > > > Could you please consider pick both patches? > > Manivannan already reviewed and only impact layerscape. > > @lorenzo: > ping I will have a look tomorrow. Lorenzo > > > > Frank > > > > > Change from v2 to v4 > > > - none > > > Change from v1 to v2 > > > > > > drivers/pci/controller/dwc/pci-layerscape-ep.c | 1 + > > > 1 file changed, 1 insertion(+) > > > > > > diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c > > > b/drivers/pci/controller/dwc/pci-layerscape-ep.c > > > index de4c1758a6c3..e0969ff2ddf7 100644 > > > --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c > > > +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c > > > @@ -89,6 +89,7 @@ static irqreturn_t ls_pcie_ep_event_handler(int irq, > > > void *dev_id) > > > dev_dbg(pci->dev, "Link up\n"); > > > } else if (val & PEX_PF0_PME_MES_DR_LDD) { > > > dev_dbg(pci->dev, "Link down\n"); > > > + pci_epc_linkdown(pci->ep.epc); > > > } else if (val & PEX_PF0_PME_MES_DR_HRD) { > > > dev_dbg(pci->dev, "Hot reset\n"); > > > } > > > -- > > > 2.34.1 > > >
Re: [PATCH v3] powerpc: Use shared font data
* li...@treblig.org (li...@treblig.org) wrote: > From: "Dr. David Alan Gilbert" > > PowerPC has a 'btext' font used for the console which is almost identical > to the shared font_sun8x16, so use it rather than duplicating the data. > > They were actually identical until about a decade ago when >commit bcfbeecea11c ("drivers: console: font_: Change a glyph from > "broken bar" to "vertical line"") > > which changed the | in the shared font to be a solid > bar rather than a broken bar. That's the only difference. > > This was originally spotted by the PMF source code analyser, which > noticed that sparc does the same thing with the same data, and they > also share a bunch of functions to manipulate the data. I've previously > posted a near identical patch for sparc. > > Tested very lightly with a boot without FS in qemu. > > Signed-off-by: Dr. David Alan Gilbert Hi Michael, Just checking, is there anything else I need to do here? Dave > --- > v3 > Fixup lib/fonts/Kconfig to not require FRAMEBUFFER_CONSOLE > for BOOTX, and add a || PPC, no longer need to 'select FONTS' > Passes a bunch of randconfigs (as spotted by Randy) > > arch/powerpc/Kconfig.debug | 2 + > arch/powerpc/kernel/btext.c | 360 +--- > lib/fonts/Kconfig | 3 +- > 3 files changed, 10 insertions(+), 355 deletions(-) > > diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug > index 2a54fadbeaf51..50ff3359cde93 100644 > --- a/arch/powerpc/Kconfig.debug > +++ b/arch/powerpc/Kconfig.debug > @@ -147,6 +147,8 @@ config BDI_SWITCH > config BOOTX_TEXT > bool "Support for early boot text console (BootX or OpenFirmware only)" > depends on PPC_BOOK3S > + select FONT_SUN8x16 > + select FONT_SUPPORT > help > Say Y here to see progress messages from the boot firmware in text > mode. Requires either BootX or Open Firmware. > diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c > index 19e46fd623b0d..7f63f1cdc6c39 100644 > --- a/arch/powerpc/kernel/btext.c > +++ b/arch/powerpc/kernel/btext.c > @@ -8,6 +8,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -41,10 +42,6 @@ static unsigned char *logicalDisplayBase __force_data; > > unsigned long disp_BAT[2] __initdata = {0, 0}; > > -#define cmapsz (16*256) > - > -static unsigned char vga_font[cmapsz]; > - > static int boot_text_mapped __force_data; > > extern void rmci_on(void); > @@ -407,7 +404,7 @@ static unsigned int expand_bits_16[4] = { > }; > > > -static void draw_byte_32(unsigned char *font, unsigned int *base, int rb) > +static void draw_byte_32(const unsigned char *font, unsigned int *base, int > rb) > { > int l, bits; > int fg = 0xUL; > @@ -428,7 +425,7 @@ static void draw_byte_32(unsigned char *font, unsigned > int *base, int rb) > } > } > > -static inline void draw_byte_16(unsigned char *font, unsigned int *base, int > rb) > +static inline void draw_byte_16(const unsigned char *font, unsigned int > *base, int rb) > { > int l, bits; > int fg = 0xUL; > @@ -446,7 +443,7 @@ static inline void draw_byte_16(unsigned char *font, > unsigned int *base, int rb) > } > } > > -static inline void draw_byte_8(unsigned char *font, unsigned int *base, int > rb) > +static inline void draw_byte_8(const unsigned char *font, unsigned int > *base, int rb) > { > int l, bits; > int fg = 0x0F0F0F0FUL; > @@ -465,7 +462,8 @@ static inline void draw_byte_8(unsigned char *font, > unsigned int *base, int rb) > static noinline void draw_byte(unsigned char c, long locX, long locY) > { > unsigned char *base = calc_base(locX << 3, locY << 4); > - unsigned char *font = &vga_font[((unsigned int)c) * 16]; > + unsigned int font_index = c * 16; > + const unsigned char *font = font_sun_8x16.data + font_index; > int rb = dispDeviceRowBytes; > > rmci_maybe_on(); > @@ -583,349 +581,3 @@ void __init udbg_init_btext(void) >*/ > udbg_putc = btext_drawchar; > } > - > -static unsigned char vga_font[cmapsz] = { > -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, > -0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff, > -0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, > -0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, > -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, > -0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, > -0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, > -0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, > -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, > -0x3c
[PATCH v7 03/24] powerpc/iommu: Setup a default domain and remove set_platform_dma_ops
POWER is using the set_platform_dma_ops() callback to hook up its private dma_ops, but this is buired under some indirection and is weirdly happening for a BLOCKED domain as well. For better documentation create a PLATFORM domain to manage the dma_ops, since that is what it is for, and make the BLOCKED domain an alias for it. BLOCKED is required for VFIO. Also removes the leaky allocation of the BLOCKED domain by using a global static. Reviewed-by: Lu Baolu Signed-off-by: Jason Gunthorpe --- arch/powerpc/kernel/iommu.c | 38 + 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index c52449ae6936ad..ffe8d1411a9d56 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -1269,7 +1269,7 @@ struct iommu_table_group_ops spapr_tce_table_group_ops = { /* * A simple iommu_ops to allow less cruft in generic VFIO code. */ -static int spapr_tce_blocking_iommu_attach_dev(struct iommu_domain *dom, +static int spapr_tce_platform_iommu_attach_dev(struct iommu_domain *dom, struct device *dev) { struct iommu_group *grp = iommu_group_get(dev); @@ -1286,17 +1286,22 @@ static int spapr_tce_blocking_iommu_attach_dev(struct iommu_domain *dom, return ret; } -static void spapr_tce_blocking_iommu_set_platform_dma(struct device *dev) -{ - struct iommu_group *grp = iommu_group_get(dev); - struct iommu_table_group *table_group; +static const struct iommu_domain_ops spapr_tce_platform_domain_ops = { + .attach_dev = spapr_tce_platform_iommu_attach_dev, +}; - table_group = iommu_group_get_iommudata(grp); - table_group->ops->release_ownership(table_group); -} +static struct iommu_domain spapr_tce_platform_domain = { + .type = IOMMU_DOMAIN_PLATFORM, + .ops = &spapr_tce_platform_domain_ops, +}; -static const struct iommu_domain_ops spapr_tce_blocking_domain_ops = { - .attach_dev = spapr_tce_blocking_iommu_attach_dev, +static struct iommu_domain spapr_tce_blocked_domain = { + .type = IOMMU_DOMAIN_BLOCKED, + /* +* FIXME: SPAPR mixes blocked and platform behaviors, the blocked domain +* also sets the dma_api ops +*/ + .ops = &spapr_tce_platform_domain_ops, }; static bool spapr_tce_iommu_capable(struct device *dev, enum iommu_cap cap) @@ -1313,18 +1318,9 @@ static bool spapr_tce_iommu_capable(struct device *dev, enum iommu_cap cap) static struct iommu_domain *spapr_tce_iommu_domain_alloc(unsigned int type) { - struct iommu_domain *dom; - if (type != IOMMU_DOMAIN_BLOCKED) return NULL; - - dom = kzalloc(sizeof(*dom), GFP_KERNEL); - if (!dom) - return NULL; - - dom->ops = &spapr_tce_blocking_domain_ops; - - return dom; + return &spapr_tce_blocked_domain; } static struct iommu_device *spapr_tce_iommu_probe_device(struct device *dev) @@ -1360,12 +1356,12 @@ static struct iommu_group *spapr_tce_iommu_device_group(struct device *dev) } static const struct iommu_ops spapr_tce_iommu_ops = { + .default_domain = &spapr_tce_platform_domain, .capable = spapr_tce_iommu_capable, .domain_alloc = spapr_tce_iommu_domain_alloc, .probe_device = spapr_tce_iommu_probe_device, .release_device = spapr_tce_iommu_release_device, .device_group = spapr_tce_iommu_device_group, - .set_platform_dma_ops = spapr_tce_blocking_iommu_set_platform_dma, }; static struct attribute *spapr_tce_iommu_attrs[] = { -- 2.41.0
[PATCH v7 16/24] iommu/qcom_iommu: Add an IOMMU_IDENTITIY_DOMAIN
This brings back the ops->detach_dev() code that commit 1b932ceddd19 ("iommu: Remove detach_dev callbacks") deleted and turns it into an IDENTITY domain. Reviewed-by: Lu Baolu Signed-off-by: Jason Gunthorpe --- drivers/iommu/arm/arm-smmu/qcom_iommu.c | 39 + 1 file changed, 39 insertions(+) diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c index 775a3cbaff4ed0..bc45d18f350cb9 100644 --- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c +++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c @@ -400,6 +400,44 @@ static int qcom_iommu_attach_dev(struct iommu_domain *domain, struct device *dev return 0; } +static int qcom_iommu_identity_attach(struct iommu_domain *identity_domain, + struct device *dev) +{ + struct iommu_domain *domain = iommu_get_domain_for_dev(dev); + struct qcom_iommu_domain *qcom_domain; + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); + struct qcom_iommu_dev *qcom_iommu = to_iommu(dev); + unsigned int i; + + if (domain == identity_domain || !domain) + return 0; + + qcom_domain = to_qcom_iommu_domain(domain); + if (WARN_ON(!qcom_domain->iommu)) + return -EINVAL; + + pm_runtime_get_sync(qcom_iommu->dev); + for (i = 0; i < fwspec->num_ids; i++) { + struct qcom_iommu_ctx *ctx = to_ctx(qcom_domain, fwspec->ids[i]); + + /* Disable the context bank: */ + iommu_writel(ctx, ARM_SMMU_CB_SCTLR, 0); + + ctx->domain = NULL; + } + pm_runtime_put_sync(qcom_iommu->dev); + return 0; +} + +static struct iommu_domain_ops qcom_iommu_identity_ops = { + .attach_dev = qcom_iommu_identity_attach, +}; + +static struct iommu_domain qcom_iommu_identity_domain = { + .type = IOMMU_DOMAIN_IDENTITY, + .ops = &qcom_iommu_identity_ops, +}; + static int qcom_iommu_map(struct iommu_domain *domain, unsigned long iova, phys_addr_t paddr, size_t pgsize, size_t pgcount, int prot, gfp_t gfp, size_t *mapped) @@ -565,6 +603,7 @@ static int qcom_iommu_of_xlate(struct device *dev, struct of_phandle_args *args) } static const struct iommu_ops qcom_iommu_ops = { + .identity_domain = &qcom_iommu_identity_domain, .capable= qcom_iommu_capable, .domain_alloc = qcom_iommu_domain_alloc, .probe_device = qcom_iommu_probe_device, -- 2.41.0
[PATCH v7 18/24] iommu/mtk_iommu: Add an IOMMU_IDENTITIY_DOMAIN
This brings back the ops->detach_dev() code that commit 1b932ceddd19 ("iommu: Remove detach_dev callbacks") deleted and turns it into an IDENTITY domain. Reviewed-by: Lu Baolu Signed-off-by: Jason Gunthorpe --- drivers/iommu/mtk_iommu.c | 23 +++ 1 file changed, 23 insertions(+) diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index 640275873a271e..164f9759e1c039 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -777,6 +777,28 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain, return ret; } +static int mtk_iommu_identity_attach(struct iommu_domain *identity_domain, +struct device *dev) +{ + struct iommu_domain *domain = iommu_get_domain_for_dev(dev); + struct mtk_iommu_data *data = dev_iommu_priv_get(dev); + + if (domain == identity_domain || !domain) + return 0; + + mtk_iommu_config(data, dev, false, 0); + return 0; +} + +static struct iommu_domain_ops mtk_iommu_identity_ops = { + .attach_dev = mtk_iommu_identity_attach, +}; + +static struct iommu_domain mtk_iommu_identity_domain = { + .type = IOMMU_DOMAIN_IDENTITY, + .ops = &mtk_iommu_identity_ops, +}; + static int mtk_iommu_map(struct iommu_domain *domain, unsigned long iova, phys_addr_t paddr, size_t pgsize, size_t pgcount, int prot, gfp_t gfp, size_t *mapped) @@ -996,6 +1018,7 @@ static void mtk_iommu_get_resv_regions(struct device *dev, } static const struct iommu_ops mtk_iommu_ops = { + .identity_domain = &mtk_iommu_identity_domain, .domain_alloc = mtk_iommu_domain_alloc, .probe_device = mtk_iommu_probe_device, .release_device = mtk_iommu_release_device, -- 2.41.0
[PATCH v7 02/24] iommu: Add IOMMU_DOMAIN_PLATFORM
This is used when the iommu driver is taking control of the dma_ops, currently only on S390 and power spapr. It is designed to preserve the original ops->detach_dev() semantic that these S390 was built around. Provide an opaque domain type and a 'default_domain' ops value that allows the driver to trivially force any single domain as the default domain. Update iommufd selftest to use this instead of set_platform_dma_ops Reviewed-by: Lu Baolu Signed-off-by: Jason Gunthorpe --- drivers/iommu/iommu.c| 13 + drivers/iommu/iommufd/selftest.c | 14 +- include/linux/iommu.h| 6 ++ 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 33bd1107090720..7cedb0640290c8 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -184,6 +184,8 @@ static const char *iommu_domain_type_str(unsigned int t) case IOMMU_DOMAIN_DMA: case IOMMU_DOMAIN_DMA_FQ: return "Translated"; + case IOMMU_DOMAIN_PLATFORM: + return "Platform"; default: return "Unknown"; } @@ -1752,6 +1754,17 @@ iommu_group_alloc_default_domain(struct iommu_group *group, int req_type) lockdep_assert_held(&group->mutex); + /* +* Allow legacy drivers to specify the domain that will be the default +* domain. This should always be either an IDENTITY or PLATFORM domain. +* Do not use in new drivers. +*/ + if (bus->iommu_ops->default_domain) { + if (req_type) + return ERR_PTR(-EINVAL); + return bus->iommu_ops->default_domain; + } + if (req_type) return __iommu_group_alloc_default_domain(bus, group, req_type); diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c index d48a202a7c3b81..fb981ba97c4e87 100644 --- a/drivers/iommu/iommufd/selftest.c +++ b/drivers/iommu/iommufd/selftest.c @@ -281,14 +281,6 @@ static bool mock_domain_capable(struct device *dev, enum iommu_cap cap) return cap == IOMMU_CAP_CACHE_COHERENCY; } -static void mock_domain_set_plaform_dma_ops(struct device *dev) -{ - /* -* mock doesn't setup default domains because we can't hook into the -* normal probe path -*/ -} - static struct iommu_device mock_iommu_device = { }; @@ -298,12 +290,16 @@ static struct iommu_device *mock_probe_device(struct device *dev) } static const struct iommu_ops mock_ops = { + /* +* IOMMU_DOMAIN_BLOCKED cannot be returned from def_domain_type() +* because it is zero. +*/ + .default_domain = &mock_blocking_domain, .owner = THIS_MODULE, .pgsize_bitmap = MOCK_IO_PAGE_SIZE, .hw_info = mock_domain_hw_info, .domain_alloc = mock_domain_alloc, .capable = mock_domain_capable, - .set_platform_dma_ops = mock_domain_set_plaform_dma_ops, .device_group = generic_device_group, .probe_device = mock_probe_device, .default_domain_ops = diff --git a/include/linux/iommu.h b/include/linux/iommu.h index d0920b2a9f1c0e..48a18b6e07abff 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -64,6 +64,7 @@ struct iommu_domain_geometry { #define __IOMMU_DOMAIN_DMA_FQ (1U << 3) /* DMA-API uses flush queue*/ #define __IOMMU_DOMAIN_SVA (1U << 4) /* Shared process address space */ +#define __IOMMU_DOMAIN_PLATFORM(1U << 5) #define IOMMU_DOMAIN_ALLOC_FLAGS ~__IOMMU_DOMAIN_DMA_FQ /* @@ -81,6 +82,8 @@ struct iommu_domain_geometry { * invalidation. * IOMMU_DOMAIN_SVA- DMA addresses are shared process addresses * represented by mm_struct's. + * IOMMU_DOMAIN_PLATFORM - Legacy domain for drivers that do their own + * dma_api stuff. Do not use in new drivers. */ #define IOMMU_DOMAIN_BLOCKED (0U) #define IOMMU_DOMAIN_IDENTITY (__IOMMU_DOMAIN_PT) @@ -91,6 +94,7 @@ struct iommu_domain_geometry { __IOMMU_DOMAIN_DMA_API | \ __IOMMU_DOMAIN_DMA_FQ) #define IOMMU_DOMAIN_SVA (__IOMMU_DOMAIN_SVA) +#define IOMMU_DOMAIN_PLATFORM (__IOMMU_DOMAIN_PLATFORM) struct iommu_domain { unsigned type; @@ -262,6 +266,7 @@ struct iommu_iotlb_gather { * @owner: Driver module providing these ops * @identity_domain: An always available, always attachable identity * translation. + * @default_domain: If not NULL this will always be set as the default domain. */ struct iommu_ops { bool (*capable)(struct device *dev, enum iommu_cap); @@ -297,6 +302,7 @@ struct iommu_ops { unsigned long pgsize_bitmap; struct module *owner; struct iommu_domain *identity_domain; + struct iommu_domain *default_domain; }; /** -- 2
[PATCH v7 05/24] iommu/fsl_pamu: Implement a PLATFORM domain
This driver is nonsensical. To not block migrating the core API away from NULL default_domains give it a hacky of a PLATFORM domain that keeps it working exactly as it always did. Leave some comments around to warn away any future people looking at this. Reviewed-by: Lu Baolu Signed-off-by: Jason Gunthorpe --- drivers/iommu/fsl_pamu_domain.c | 41 ++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c index 4ac0e247ec2b51..e9d2bff4659b7c 100644 --- a/drivers/iommu/fsl_pamu_domain.c +++ b/drivers/iommu/fsl_pamu_domain.c @@ -196,6 +196,13 @@ static struct iommu_domain *fsl_pamu_domain_alloc(unsigned type) { struct fsl_dma_domain *dma_domain; + /* +* FIXME: This isn't creating an unmanaged domain since the +* default_domain_ops do not have any map/unmap function it doesn't meet +* the requirements for __IOMMU_DOMAIN_PAGING. The only purpose seems to +* allow drivers/soc/fsl/qbman/qman_portal.c to do +* fsl_pamu_configure_l1_stash() +*/ if (type != IOMMU_DOMAIN_UNMANAGED) return NULL; @@ -283,15 +290,33 @@ static int fsl_pamu_attach_device(struct iommu_domain *domain, return ret; } -static void fsl_pamu_set_platform_dma(struct device *dev) +/* + * FIXME: fsl/pamu is completely broken in terms of how it works with the iommu + * API. Immediately after probe the HW is left in an IDENTITY translation and + * the driver provides a non-working UNMANAGED domain that it can switch over + * to. However it cannot switch back to an IDENTITY translation, instead it + * switches to what looks like BLOCKING. + */ +static int fsl_pamu_platform_attach(struct iommu_domain *platform_domain, + struct device *dev) { struct iommu_domain *domain = iommu_get_domain_for_dev(dev); - struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain); + struct fsl_dma_domain *dma_domain; const u32 *prop; int len; struct pci_dev *pdev = NULL; struct pci_controller *pci_ctl; + /* +* Hack to keep things working as they always have, only leaving an +* UNMANAGED domain makes it BLOCKING. +*/ + if (domain == platform_domain || !domain || + domain->type != IOMMU_DOMAIN_UNMANAGED) + return 0; + + dma_domain = to_fsl_dma_domain(domain); + /* * Use LIODN of the PCI controller while detaching a * PCI device. @@ -312,8 +337,18 @@ static void fsl_pamu_set_platform_dma(struct device *dev) detach_device(dev, dma_domain); else pr_debug("missing fsl,liodn property at %pOF\n", dev->of_node); + return 0; } +static struct iommu_domain_ops fsl_pamu_platform_ops = { + .attach_dev = fsl_pamu_platform_attach, +}; + +static struct iommu_domain fsl_pamu_platform_domain = { + .type = IOMMU_DOMAIN_PLATFORM, + .ops = &fsl_pamu_platform_ops, +}; + /* Set the domain stash attribute */ int fsl_pamu_configure_l1_stash(struct iommu_domain *domain, u32 cpu) { @@ -395,11 +430,11 @@ static struct iommu_device *fsl_pamu_probe_device(struct device *dev) } static const struct iommu_ops fsl_pamu_ops = { + .default_domain = &fsl_pamu_platform_domain, .capable= fsl_pamu_capable, .domain_alloc = fsl_pamu_domain_alloc, .probe_device = fsl_pamu_probe_device, .device_group = fsl_pamu_device_group, - .set_platform_dma_ops = fsl_pamu_set_platform_dma, .default_domain_ops = &(const struct iommu_domain_ops) { .attach_dev = fsl_pamu_attach_device, .iova_to_phys = fsl_pamu_iova_to_phys, -- 2.41.0
[PATCH v7 01/24] iommu: Add iommu_ops->identity_domain
This allows a driver to set a global static to an IDENTITY domain and the core code will automatically use it whenever an IDENTITY domain is requested. By making it always available it means the IDENTITY can be used in error handling paths to force the iommu driver into a known state. Devices implementing global static identity domains should avoid failing their attach_dev ops. To make global static domains simpler allow drivers to omit their free function and update the iommufd selftest. Convert rockchip to use the new mechanism. Tested-by: Steven Price Tested-by: Marek Szyprowski Tested-by: Nicolin Chen Reviewed-by: Lu Baolu Signed-off-by: Jason Gunthorpe --- drivers/iommu/iommu.c| 6 +- drivers/iommu/iommufd/selftest.c | 5 - drivers/iommu/rockchip-iommu.c | 9 + include/linux/iommu.h| 3 +++ 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 3bfc56df4f781c..33bd1107090720 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -1978,6 +1978,9 @@ static struct iommu_domain *__iommu_domain_alloc(const struct bus_type *bus, if (bus == NULL || bus->iommu_ops == NULL) return NULL; + if (alloc_type == IOMMU_DOMAIN_IDENTITY && bus->iommu_ops->identity_domain) + return bus->iommu_ops->identity_domain; + domain = bus->iommu_ops->domain_alloc(alloc_type); if (!domain) return NULL; @@ -2011,7 +2014,8 @@ void iommu_domain_free(struct iommu_domain *domain) if (domain->type == IOMMU_DOMAIN_SVA) mmdrop(domain->mm); iommu_put_dma_cookie(domain); - domain->ops->free(domain); + if (domain->ops->free) + domain->ops->free(domain); } EXPORT_SYMBOL_GPL(iommu_domain_free); diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c index 56506d5753f15c..d48a202a7c3b81 100644 --- a/drivers/iommu/iommufd/selftest.c +++ b/drivers/iommu/iommufd/selftest.c @@ -111,10 +111,6 @@ struct selftest_obj { }; }; -static void mock_domain_blocking_free(struct iommu_domain *domain) -{ -} - static int mock_domain_nop_attach(struct iommu_domain *domain, struct device *dev) { @@ -122,7 +118,6 @@ static int mock_domain_nop_attach(struct iommu_domain *domain, } static const struct iommu_domain_ops mock_blocking_ops = { - .free = mock_domain_blocking_free, .attach_dev = mock_domain_nop_attach, }; diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index 8ff69fbf9f65db..033678f2f8b3ab 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c @@ -989,13 +989,8 @@ static int rk_iommu_identity_attach(struct iommu_domain *identity_domain, return 0; } -static void rk_iommu_identity_free(struct iommu_domain *domain) -{ -} - static struct iommu_domain_ops rk_identity_ops = { .attach_dev = rk_iommu_identity_attach, - .free = rk_iommu_identity_free, }; static struct iommu_domain rk_identity_domain = { @@ -1059,9 +1054,6 @@ static struct iommu_domain *rk_iommu_domain_alloc(unsigned type) { struct rk_iommu_domain *rk_domain; - if (type == IOMMU_DOMAIN_IDENTITY) - return &rk_identity_domain; - if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA) return NULL; @@ -1186,6 +1178,7 @@ static int rk_iommu_of_xlate(struct device *dev, } static const struct iommu_ops rk_iommu_ops = { + .identity_domain = &rk_identity_domain, .domain_alloc = rk_iommu_domain_alloc, .probe_device = rk_iommu_probe_device, .release_device = rk_iommu_release_device, diff --git a/include/linux/iommu.h b/include/linux/iommu.h index c50a769d569a60..d0920b2a9f1c0e 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -260,6 +260,8 @@ struct iommu_iotlb_gather { *will be blocked by the hardware. * @pgsize_bitmap: bitmap of all possible supported page sizes * @owner: Driver module providing these ops + * @identity_domain: An always available, always attachable identity + * translation. */ struct iommu_ops { bool (*capable)(struct device *dev, enum iommu_cap); @@ -294,6 +296,7 @@ struct iommu_ops { const struct iommu_domain_ops *default_domain_ops; unsigned long pgsize_bitmap; struct module *owner; + struct iommu_domain *identity_domain; }; /** -- 2.41.0
[PATCH v7 24/24] iommu: Convert remaining simple drivers to domain_alloc_paging()
These drivers don't support IOMMU_DOMAIN_DMA, so this commit effectively allows them to support that mode. The prior work to require default_domains makes this safe because every one of these drivers is either compilation incompatible with dma-iommu.c, or already establishing a default_domain. In both cases alloc_domain() will never be called with IOMMU_DOMAIN_DMA for these drivers so it is safe to drop the test. Removing these tests clarifies that the domain allocation path is only about the functionality of a paging domain and has nothing to do with policy of how the paging domain is used for UNMANAGED/DMA/DMA_FQ. Tested-by: Niklas Schnelle Tested-by: Steven Price Tested-by: Marek Szyprowski Tested-by: Nicolin Chen Reviewed-by: Lu Baolu Signed-off-by: Jason Gunthorpe --- drivers/iommu/msm_iommu.c| 7 ++- drivers/iommu/mtk_iommu_v1.c | 7 ++- drivers/iommu/omap-iommu.c | 7 ++- drivers/iommu/s390-iommu.c | 7 ++- 4 files changed, 8 insertions(+), 20 deletions(-) diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c index 26ed81cfeee897..a163cee0b7242d 100644 --- a/drivers/iommu/msm_iommu.c +++ b/drivers/iommu/msm_iommu.c @@ -302,13 +302,10 @@ static void __program_context(void __iomem *base, int ctx, SET_M(base, ctx, 1); } -static struct iommu_domain *msm_iommu_domain_alloc(unsigned type) +static struct iommu_domain *msm_iommu_domain_alloc_paging(struct device *dev) { struct msm_priv *priv; - if (type != IOMMU_DOMAIN_UNMANAGED) - return NULL; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) goto fail_nomem; @@ -691,7 +688,7 @@ irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id) static struct iommu_ops msm_iommu_ops = { .identity_domain = &msm_iommu_identity_domain, - .domain_alloc = msm_iommu_domain_alloc, + .domain_alloc_paging = msm_iommu_domain_alloc_paging, .probe_device = msm_iommu_probe_device, .device_group = generic_device_group, .pgsize_bitmap = MSM_IOMMU_PGSIZES, diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c index 7c0c1d50df5f75..67e044c1a7d93b 100644 --- a/drivers/iommu/mtk_iommu_v1.c +++ b/drivers/iommu/mtk_iommu_v1.c @@ -270,13 +270,10 @@ static int mtk_iommu_v1_domain_finalise(struct mtk_iommu_v1_data *data) return 0; } -static struct iommu_domain *mtk_iommu_v1_domain_alloc(unsigned type) +static struct iommu_domain *mtk_iommu_v1_domain_alloc_paging(struct device *dev) { struct mtk_iommu_v1_domain *dom; - if (type != IOMMU_DOMAIN_UNMANAGED) - return NULL; - dom = kzalloc(sizeof(*dom), GFP_KERNEL); if (!dom) return NULL; @@ -585,7 +582,7 @@ static int mtk_iommu_v1_hw_init(const struct mtk_iommu_v1_data *data) static const struct iommu_ops mtk_iommu_v1_ops = { .identity_domain = &mtk_iommu_v1_identity_domain, - .domain_alloc = mtk_iommu_v1_domain_alloc, + .domain_alloc_paging = mtk_iommu_v1_domain_alloc_paging, .probe_device = mtk_iommu_v1_probe_device, .probe_finalize = mtk_iommu_v1_probe_finalize, .release_device = mtk_iommu_v1_release_device, diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index 34340ef15241bc..fcf99bd195b32e 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c @@ -1580,13 +1580,10 @@ static struct iommu_domain omap_iommu_identity_domain = { .ops = &omap_iommu_identity_ops, }; -static struct iommu_domain *omap_iommu_domain_alloc(unsigned type) +static struct iommu_domain *omap_iommu_domain_alloc_paging(struct device *dev) { struct omap_iommu_domain *omap_domain; - if (type != IOMMU_DOMAIN_UNMANAGED) - return NULL; - omap_domain = kzalloc(sizeof(*omap_domain), GFP_KERNEL); if (!omap_domain) return NULL; @@ -1748,7 +1745,7 @@ static struct iommu_group *omap_iommu_device_group(struct device *dev) static const struct iommu_ops omap_iommu_ops = { .identity_domain = &omap_iommu_identity_domain, - .domain_alloc = omap_iommu_domain_alloc, + .domain_alloc_paging = omap_iommu_domain_alloc_paging, .probe_device = omap_iommu_probe_device, .release_device = omap_iommu_release_device, .device_group = omap_iommu_device_group, diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c index f0c867c57a5b9b..5695ad71d60e24 100644 --- a/drivers/iommu/s390-iommu.c +++ b/drivers/iommu/s390-iommu.c @@ -39,13 +39,10 @@ static bool s390_iommu_capable(struct device *dev, enum iommu_cap cap) } } -static struct iommu_domain *s390_domain_alloc(unsigned domain_type) +static struct iommu_domain *s390_domain_alloc_paging(struct device *dev) { struct s390_domain *s390_domain; - if (domain_type != IOMMU_DOMAIN_UNMANAGED) - return NULL; - s390_domai
[PATCH v7 14/24] iommu/msm: Implement an IDENTITY domain
What msm does during msm_iommu_set_platform_dma() is actually putting the iommu into identity mode. Move to the new core support for ARM_DMA_USE_IOMMU by defining ops->identity_domain. This driver does not support IOMMU_DOMAIN_DMA, however it cannot be compiled on ARM64 either. Most likely it is fine to support dma-iommu.c Reviewed-by: Lu Baolu Signed-off-by: Jason Gunthorpe --- drivers/iommu/msm_iommu.c | 23 +++ 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c index 79d89bad5132b7..26ed81cfeee897 100644 --- a/drivers/iommu/msm_iommu.c +++ b/drivers/iommu/msm_iommu.c @@ -443,15 +443,20 @@ static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev) return ret; } -static void msm_iommu_set_platform_dma(struct device *dev) +static int msm_iommu_identity_attach(struct iommu_domain *identity_domain, +struct device *dev) { struct iommu_domain *domain = iommu_get_domain_for_dev(dev); - struct msm_priv *priv = to_msm_priv(domain); + struct msm_priv *priv; unsigned long flags; struct msm_iommu_dev *iommu; struct msm_iommu_ctx_dev *master; - int ret; + int ret = 0; + if (domain == identity_domain || !domain) + return 0; + + priv = to_msm_priv(domain); free_io_pgtable_ops(priv->iop); spin_lock_irqsave(&msm_iommu_lock, flags); @@ -468,8 +473,18 @@ static void msm_iommu_set_platform_dma(struct device *dev) } fail: spin_unlock_irqrestore(&msm_iommu_lock, flags); + return ret; } +static struct iommu_domain_ops msm_iommu_identity_ops = { + .attach_dev = msm_iommu_identity_attach, +}; + +static struct iommu_domain msm_iommu_identity_domain = { + .type = IOMMU_DOMAIN_IDENTITY, + .ops = &msm_iommu_identity_ops, +}; + static int msm_iommu_map(struct iommu_domain *domain, unsigned long iova, phys_addr_t pa, size_t pgsize, size_t pgcount, int prot, gfp_t gfp, size_t *mapped) @@ -675,10 +690,10 @@ irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id) } static struct iommu_ops msm_iommu_ops = { + .identity_domain = &msm_iommu_identity_domain, .domain_alloc = msm_iommu_domain_alloc, .probe_device = msm_iommu_probe_device, .device_group = generic_device_group, - .set_platform_dma_ops = msm_iommu_set_platform_dma, .pgsize_bitmap = MSM_IOMMU_PGSIZES, .of_xlate = qcom_iommu_of_xlate, .default_domain_ops = &(const struct iommu_domain_ops) { -- 2.41.0
[PATCH v7 13/24] iommu/omap: Implement an IDENTITY domain
What omap does during omap_iommu_set_platform_dma() is actually putting the iommu into identity mode. Move to the new core support for ARM_DMA_USE_IOMMU by defining ops->identity_domain. This driver does not support IOMMU_DOMAIN_DMA, however it cannot be compiled on ARM64 either. Most likely it is fine to support dma-iommu.c Reviewed-by: Lu Baolu Signed-off-by: Jason Gunthorpe --- drivers/iommu/omap-iommu.c | 21 ++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index 537e402f9bba97..34340ef15241bc 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c @@ -1555,16 +1555,31 @@ static void _omap_iommu_detach_dev(struct omap_iommu_domain *omap_domain, omap_domain->dev = NULL; } -static void omap_iommu_set_platform_dma(struct device *dev) +static int omap_iommu_identity_attach(struct iommu_domain *identity_domain, + struct device *dev) { struct iommu_domain *domain = iommu_get_domain_for_dev(dev); - struct omap_iommu_domain *omap_domain = to_omap_domain(domain); + struct omap_iommu_domain *omap_domain; + if (domain == identity_domain || !domain) + return 0; + + omap_domain = to_omap_domain(domain); spin_lock(&omap_domain->lock); _omap_iommu_detach_dev(omap_domain, dev); spin_unlock(&omap_domain->lock); + return 0; } +static struct iommu_domain_ops omap_iommu_identity_ops = { + .attach_dev = omap_iommu_identity_attach, +}; + +static struct iommu_domain omap_iommu_identity_domain = { + .type = IOMMU_DOMAIN_IDENTITY, + .ops = &omap_iommu_identity_ops, +}; + static struct iommu_domain *omap_iommu_domain_alloc(unsigned type) { struct omap_iommu_domain *omap_domain; @@ -1732,11 +1747,11 @@ static struct iommu_group *omap_iommu_device_group(struct device *dev) } static const struct iommu_ops omap_iommu_ops = { + .identity_domain = &omap_iommu_identity_domain, .domain_alloc = omap_iommu_domain_alloc, .probe_device = omap_iommu_probe_device, .release_device = omap_iommu_release_device, .device_group = omap_iommu_device_group, - .set_platform_dma_ops = omap_iommu_set_platform_dma, .pgsize_bitmap = OMAP_IOMMU_PGSIZES, .default_domain_ops = &(const struct iommu_domain_ops) { .attach_dev = omap_iommu_attach_dev, -- 2.41.0
[PATCH v7 17/24] iommu/ipmmu: Add an IOMMU_IDENTITIY_DOMAIN
This brings back the ops->detach_dev() code that commit 1b932ceddd19 ("iommu: Remove detach_dev callbacks") deleted and turns it into an IDENTITY domain. Also reverts commit 584d334b1393 ("iommu/ipmmu-vmsa: Remove ipmmu_utlb_disable()") Reviewed-by: Lu Baolu Signed-off-by: Jason Gunthorpe --- drivers/iommu/ipmmu-vmsa.c | 43 ++ 1 file changed, 43 insertions(+) diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c index 65ff69477c43e4..04830d3931d239 100644 --- a/drivers/iommu/ipmmu-vmsa.c +++ b/drivers/iommu/ipmmu-vmsa.c @@ -295,6 +295,18 @@ static void ipmmu_utlb_enable(struct ipmmu_vmsa_domain *domain, mmu->utlb_ctx[utlb] = domain->context_id; } +/* + * Disable MMU translation for the microTLB. + */ +static void ipmmu_utlb_disable(struct ipmmu_vmsa_domain *domain, + unsigned int utlb) +{ + struct ipmmu_vmsa_device *mmu = domain->mmu; + + ipmmu_imuctr_write(mmu, utlb, 0); + mmu->utlb_ctx[utlb] = IPMMU_CTX_INVALID; +} + static void ipmmu_tlb_flush_all(void *cookie) { struct ipmmu_vmsa_domain *domain = cookie; @@ -627,6 +639,36 @@ static int ipmmu_attach_device(struct iommu_domain *io_domain, return 0; } +static int ipmmu_iommu_identity_attach(struct iommu_domain *identity_domain, + struct device *dev) +{ + struct iommu_domain *io_domain = iommu_get_domain_for_dev(dev); + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); + struct ipmmu_vmsa_domain *domain; + unsigned int i; + + if (io_domain == identity_domain || !io_domain) + return 0; + + domain = to_vmsa_domain(io_domain); + for (i = 0; i < fwspec->num_ids; ++i) + ipmmu_utlb_disable(domain, fwspec->ids[i]); + + /* +* TODO: Optimize by disabling the context when no device is attached. +*/ + return 0; +} + +static struct iommu_domain_ops ipmmu_iommu_identity_ops = { + .attach_dev = ipmmu_iommu_identity_attach, +}; + +static struct iommu_domain ipmmu_iommu_identity_domain = { + .type = IOMMU_DOMAIN_IDENTITY, + .ops = &ipmmu_iommu_identity_ops, +}; + static int ipmmu_map(struct iommu_domain *io_domain, unsigned long iova, phys_addr_t paddr, size_t pgsize, size_t pgcount, int prot, gfp_t gfp, size_t *mapped) @@ -849,6 +891,7 @@ static struct iommu_group *ipmmu_find_group(struct device *dev) } static const struct iommu_ops ipmmu_ops = { + .identity_domain = &ipmmu_iommu_identity_domain, .domain_alloc = ipmmu_domain_alloc, .probe_device = ipmmu_probe_device, .release_device = ipmmu_release_device, -- 2.41.0
[PATCH v7 04/24] iommu: Add IOMMU_DOMAIN_PLATFORM for S390
The PLATFORM domain will be set as the default domain and attached as normal during probe. The driver will ignore the initial attach from a NULL domain to the PLATFORM domain. After this, the PLATFORM domain's attach_dev will be called whenever we detach from an UNMANAGED domain (eg for VFIO). This is the same time the original design would have called op->detach_dev(). This is temporary until the S390 dma-iommu.c conversion is merged. Tested-by: Heiko Stuebner Tested-by: Niklas Schnelle Reviewed-by: Lu Baolu Signed-off-by: Jason Gunthorpe --- drivers/iommu/s390-iommu.c | 21 +++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c index fbf59a8db29b11..f0c867c57a5b9b 100644 --- a/drivers/iommu/s390-iommu.c +++ b/drivers/iommu/s390-iommu.c @@ -142,14 +142,31 @@ static int s390_iommu_attach_device(struct iommu_domain *domain, return 0; } -static void s390_iommu_set_platform_dma(struct device *dev) +/* + * Switch control over the IOMMU to S390's internal dma_api ops + */ +static int s390_iommu_platform_attach(struct iommu_domain *platform_domain, + struct device *dev) { struct zpci_dev *zdev = to_zpci_dev(dev); + if (!zdev->s390_domain) + return 0; + __s390_iommu_detach_device(zdev); zpci_dma_init_device(zdev); + return 0; } +static struct iommu_domain_ops s390_iommu_platform_ops = { + .attach_dev = s390_iommu_platform_attach, +}; + +static struct iommu_domain s390_iommu_platform_domain = { + .type = IOMMU_DOMAIN_PLATFORM, + .ops = &s390_iommu_platform_ops, +}; + static void s390_iommu_get_resv_regions(struct device *dev, struct list_head *list) { @@ -428,12 +445,12 @@ void zpci_destroy_iommu(struct zpci_dev *zdev) } static const struct iommu_ops s390_iommu_ops = { + .default_domain = &s390_iommu_platform_domain, .capable = s390_iommu_capable, .domain_alloc = s390_domain_alloc, .probe_device = s390_iommu_probe_device, .release_device = s390_iommu_release_device, .device_group = generic_device_group, - .set_platform_dma_ops = s390_iommu_set_platform_dma, .pgsize_bitmap = SZ_4K, .get_resv_regions = s390_iommu_get_resv_regions, .default_domain_ops = &(const struct iommu_domain_ops) { -- 2.41.0
[PATCH v7 21/24] iommu: Add __iommu_group_domain_alloc()
Allocate a domain from a group. Automatically obtains the iommu_ops to use from the device list of the group. Convert the internal callers to use it. Tested-by: Steven Price Tested-by: Marek Szyprowski Tested-by: Nicolin Chen Reviewed-by: Lu Baolu Signed-off-by: Jason Gunthorpe --- drivers/iommu/iommu.c | 59 +-- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 3003c249ab9b8e..568dec45a06954 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -96,8 +96,8 @@ static const char * const iommu_group_resv_type_string[] = { static int iommu_bus_notifier(struct notifier_block *nb, unsigned long action, void *data); static void iommu_release_device(struct device *dev); -static struct iommu_domain *__iommu_domain_alloc(const struct bus_type *bus, -unsigned type); +static struct iommu_domain * +__iommu_group_domain_alloc(struct iommu_group *group, unsigned int type); static int __iommu_attach_device(struct iommu_domain *domain, struct device *dev); static int __iommu_attach_group(struct iommu_domain *domain, @@ -1719,12 +1719,11 @@ struct iommu_group *fsl_mc_device_group(struct device *dev) EXPORT_SYMBOL_GPL(fsl_mc_device_group); static struct iommu_domain * -__iommu_group_alloc_default_domain(const struct bus_type *bus, - struct iommu_group *group, int req_type) +__iommu_group_alloc_default_domain(struct iommu_group *group, int req_type) { if (group->default_domain && group->default_domain->type == req_type) return group->default_domain; - return __iommu_domain_alloc(bus, req_type); + return __iommu_group_domain_alloc(group, req_type); } /* @@ -1751,9 +1750,7 @@ static const struct iommu_ops *group_iommu_ops(struct iommu_group *group) static struct iommu_domain * iommu_group_alloc_default_domain(struct iommu_group *group, int req_type) { - const struct bus_type *bus = - list_first_entry(&group->devices, struct group_device, list) - ->dev->bus; + const struct iommu_ops *ops = group_iommu_ops(group); struct iommu_domain *dom; lockdep_assert_held(&group->mutex); @@ -1763,24 +1760,24 @@ iommu_group_alloc_default_domain(struct iommu_group *group, int req_type) * domain. This should always be either an IDENTITY or PLATFORM domain. * Do not use in new drivers. */ - if (bus->iommu_ops->default_domain) { + if (ops->default_domain) { if (req_type) return ERR_PTR(-EINVAL); - return bus->iommu_ops->default_domain; + return ops->default_domain; } if (req_type) - return __iommu_group_alloc_default_domain(bus, group, req_type); + return __iommu_group_alloc_default_domain(group, req_type); /* The driver gave no guidance on what type to use, try the default */ - dom = __iommu_group_alloc_default_domain(bus, group, iommu_def_domain_type); + dom = __iommu_group_alloc_default_domain(group, iommu_def_domain_type); if (dom) return dom; /* Otherwise IDENTITY and DMA_FQ defaults will try DMA */ if (iommu_def_domain_type == IOMMU_DOMAIN_DMA) return NULL; - dom = __iommu_group_alloc_default_domain(bus, group, IOMMU_DOMAIN_DMA); + dom = __iommu_group_alloc_default_domain(group, IOMMU_DOMAIN_DMA); if (!dom) return NULL; @@ -2043,19 +2040,16 @@ void iommu_set_fault_handler(struct iommu_domain *domain, } EXPORT_SYMBOL_GPL(iommu_set_fault_handler); -static struct iommu_domain *__iommu_domain_alloc(const struct bus_type *bus, -unsigned type) +static struct iommu_domain *__iommu_domain_alloc(const struct iommu_ops *ops, +unsigned int type) { struct iommu_domain *domain; unsigned int alloc_type = type & IOMMU_DOMAIN_ALLOC_FLAGS; - if (bus == NULL || bus->iommu_ops == NULL) - return NULL; + if (alloc_type == IOMMU_DOMAIN_IDENTITY && ops->identity_domain) + return ops->identity_domain; - if (alloc_type == IOMMU_DOMAIN_IDENTITY && bus->iommu_ops->identity_domain) - return bus->iommu_ops->identity_domain; - - domain = bus->iommu_ops->domain_alloc(alloc_type); + domain = ops->domain_alloc(alloc_type); if (!domain) return NULL; @@ -2065,10 +2059,10 @@ static struct iommu_domain *__iommu_domain_alloc(const struct bus_type *bus, * may override this later */ if (!domain->pgsize_bitmap) - domain->pgsize_bitmap = bus->iommu_ops->pgsize_bitmap; +
[PATCH v7 15/24] iommu: Remove ops->set_platform_dma_ops()
All drivers are now using IDENTITY or PLATFORM domains for what this did, we can remove it now. It is no longer possible to attach to a NULL domain. Tested-by: Heiko Stuebner Tested-by: Niklas Schnelle Tested-by: Steven Price Tested-by: Marek Szyprowski Tested-by: Nicolin Chen Reviewed-by: Lu Baolu Signed-off-by: Jason Gunthorpe --- drivers/iommu/iommu.c | 30 +- include/linux/iommu.h | 4 2 files changed, 5 insertions(+), 29 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 5fb25bcbc42f76..a3b016543fad00 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2351,21 +2351,8 @@ static int __iommu_group_set_domain_internal(struct iommu_group *group, if (group->domain == new_domain) return 0; - /* -* New drivers should support default domains, so set_platform_dma() -* op will never be called. Otherwise the NULL domain represents some -* platform specific behavior. -*/ - if (!new_domain) { - for_each_group_device(group, gdev) { - const struct iommu_ops *ops = dev_iommu_ops(gdev->dev); - - if (!WARN_ON(!ops->set_platform_dma_ops)) - ops->set_platform_dma_ops(gdev->dev); - } - group->domain = NULL; - return 0; - } + if (WARN_ON(!new_domain)) + return -EINVAL; /* * Changing the domain is done by calling attach_dev() on the new @@ -2401,19 +2388,15 @@ static int __iommu_group_set_domain_internal(struct iommu_group *group, */ last_gdev = gdev; for_each_group_device(group, gdev) { - const struct iommu_ops *ops = dev_iommu_ops(gdev->dev); - /* -* If set_platform_dma_ops is not present a NULL domain can -* happen only for first probe, in which case we leave -* group->domain as NULL and let release clean everything up. +* A NULL domain can happen only for first probe, in which case +* we leave group->domain as NULL and let release clean +* everything up. */ if (group->domain) WARN_ON(__iommu_device_set_domain( group, gdev->dev, group->domain, IOMMU_SET_DOMAIN_MUST_SUCCEED)); - else if (ops->set_platform_dma_ops) - ops->set_platform_dma_ops(gdev->dev); if (gdev == last_gdev) break; } @@ -3036,9 +3019,6 @@ static int iommu_setup_default_domain(struct iommu_group *group, /* * There are still some drivers which don't support default domains, so * we ignore the failure and leave group->default_domain NULL. -* -* We assume that the iommu driver starts up the device in -* 'set_platform_dma_ops' mode if it does not support default domains. */ dom = iommu_group_alloc_default_domain(group, req_type); if (!dom) { diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 48a18b6e07abff..c3d2e79076ffab 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -243,9 +243,6 @@ struct iommu_iotlb_gather { * @release_device: Remove device from iommu driver handling * @probe_finalize: Do final setup work after the device is added to an IOMMU * group and attached to the groups domain - * @set_platform_dma_ops: Returning control back to the platform DMA ops. This op - *is to support old IOMMU drivers, new drivers should use - *default domains, and the common IOMMU DMA ops. * @device_group: find iommu group for a particular device * @get_resv_regions: Request list of reserved regions for a device * @of_xlate: add OF master IDs to iommu grouping @@ -278,7 +275,6 @@ struct iommu_ops { struct iommu_device *(*probe_device)(struct device *dev); void (*release_device)(struct device *dev); void (*probe_finalize)(struct device *dev); - void (*set_platform_dma_ops)(struct device *dev); struct iommu_group *(*device_group)(struct device *dev); /* Request/Free a list of reserved regions for a device */ -- 2.41.0
[PATCH v7 08/24] iommu: Reorganize iommu_get_default_domain_type() to respect def_domain_type()
Except for dart (which forces IOMMU_DOMAIN_DMA) every driver returns 0 or IDENTITY from ops->def_domain_type(). The drivers that return IDENTITY have some kind of good reason, typically that quirky hardware really can't support anything other than IDENTITY. Arrange things so that if the driver says it needs IDENTITY then iommu_get_default_domain_type() either fails or returns IDENTITY. It will not ignore the driver's override to IDENTITY. Split the function into two steps, reducing the group device list to the driver's def_domain_type() and the untrusted flag. Then compute the result based on those two reduced variables. Fully reject combining untrusted with IDENTITY. Remove the debugging print on the iommu_group_store_type() failure path, userspace should not be able to trigger kernel prints. This makes the next patch cleaner that wants to force IDENTITY always for ARM_IOMMU because there is no support for DMA. Signed-off-by: Jason Gunthorpe --- drivers/iommu/iommu.c | 117 -- 1 file changed, 79 insertions(+), 38 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 7cedb0640290c8..bdeeb574d9495c 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -1718,19 +1718,6 @@ struct iommu_group *fsl_mc_device_group(struct device *dev) } EXPORT_SYMBOL_GPL(fsl_mc_device_group); -static int iommu_get_def_domain_type(struct device *dev) -{ - const struct iommu_ops *ops = dev_iommu_ops(dev); - - if (dev_is_pci(dev) && to_pci_dev(dev)->untrusted) - return IOMMU_DOMAIN_DMA; - - if (ops->def_domain_type) - return ops->def_domain_type(dev); - - return 0; -} - static struct iommu_domain * __iommu_group_alloc_default_domain(const struct bus_type *bus, struct iommu_group *group, int req_type) @@ -1740,6 +1727,23 @@ __iommu_group_alloc_default_domain(const struct bus_type *bus, return __iommu_domain_alloc(bus, req_type); } +/* + * Returns the iommu_ops for the devices in an iommu group. + * + * It is assumed that all devices in an iommu group are managed by a single + * IOMMU unit. Therefore, this returns the dev_iommu_ops of the first device + * in the group. + */ +static const struct iommu_ops *group_iommu_ops(struct iommu_group *group) +{ + struct group_device *device = + list_first_entry(&group->devices, struct group_device, list); + + lockdep_assert_held(&group->mutex); + + return dev_iommu_ops(device->dev); +} + /* * req_type of 0 means "auto" which means to select a domain based on * iommu_def_domain_type or what the driver actually supports. @@ -1820,40 +1824,77 @@ static int iommu_bus_notifier(struct notifier_block *nb, return 0; } -/* A target_type of 0 will select the best domain type and cannot fail */ +/* + * Combine the driver's chosen def_domain_type across all the devices in a + * group. Drivers must give a consistent result. + */ +static int iommu_get_def_domain_type(struct iommu_group *group, +struct device *dev, int cur_type) +{ + const struct iommu_ops *ops = group_iommu_ops(group); + int type; + + if (!ops->def_domain_type) + return cur_type; + + type = ops->def_domain_type(dev); + if (!type || cur_type == type) + return cur_type; + if (!cur_type) + return type; + + dev_err_ratelimited( + dev, + "IOMMU driver error, requesting conflicting def_domain_type, %s and %s, for devices in group %u.\n", + iommu_domain_type_str(cur_type), iommu_domain_type_str(type), + group->id); + + /* +* Try to recover, drivers are allowed to force IDENITY or DMA, IDENTITY +* takes precedence. +*/ + if (type == IOMMU_DOMAIN_IDENTITY) + return type; + return cur_type; +} + +/* + * A target_type of 0 will select the best domain type. 0 can be returned in + * this case meaning the global default should be used. + */ static int iommu_get_default_domain_type(struct iommu_group *group, int target_type) { - int best_type = target_type; + struct device *untrusted = NULL; struct group_device *gdev; - struct device *last_dev; + int driver_type = 0; lockdep_assert_held(&group->mutex); - for_each_group_device(group, gdev) { - unsigned int type = iommu_get_def_domain_type(gdev->dev); + driver_type = iommu_get_def_domain_type(group, gdev->dev, + driver_type); - if (best_type && type && best_type != type) { - if (target_type) { - dev_err_ratelimited( - gdev->dev, -
[PATCH v7 00/24] iommu: Make default_domain's mandatory
It has been a long time coming, this series completes the default_domain transition and makes it so that the core IOMMU code will always have a non-NULL default_domain for every driver on every platform. set_platform_dma_ops() turned out to be a bad idea, and so completely remove it. This is achieved by changing each driver to either: 1 - Convert the existing (or deleted) ops->detach_dev() into an op->attach_dev() of an IDENTITY domain. This is based on the theory that the ARM32 HW is able to function when the iommu is turned off and so the turned off state is an IDENTITY translation. 2 - Use a new PLATFORM domain type. This is a hack to accommodate drivers that we don't really know WTF they do. S390 is legitimately using this to switch to it's platform dma_ops implementation, which is where the name comes from. 3 - Do #1 and force the default domain to be IDENTITY, this corrects the tegra-smmu case where even an ARM64 system would have a NULL default_domain. Using this we can apply the rules: a) ARM_DMA_USE_IOMMU mode always uses either the driver's ops->default_domain, ops->def_domain_type(), or an IDENTITY domain. All ARM32 drivers provide one of these three options. b) dma-iommu.c mode uses either the driver's ops->default_domain, ops->def_domain_type or the usual DMA API policy logic based on the command line/etc to pick IDENTITY/DMA domain types c) All other arch's (PPC/S390) use ops->default_domain always. See the patch "Require a default_domain for all iommu drivers" for a per-driver breakdown. The conversion broadly teaches a bunch of ARM32 drivers that they can do IDENTITY domains. There is some educated guessing involved that these are actual IDENTITY domains. If this turns out to be wrong the driver can be trivially changed to use a BLOCKING domain type instead. Further, the domain type only matters for drivers using ARM64's dma-iommu.c mode as it will select IDENTITY based on the command line and expect IDENTITY to work. For ARM32 and other arch cases it is purely documentation. Finally, based on all the analysis in this series, we can purge IOMMU_DOMAIN_UNMANAGED/DMA constants from most of the drivers. This greatly simplifies understanding the driver contract to the core code. IOMMU drivers should not be involved in policy for how the DMA API works, that should be a core core decision. The main gain from this work is to remove alot of ARM_DMA_USE_IOMMU specific code and behaviors from drivers. All that remains in iommu drivers after this series is the calls to arm_iommu_create_mapping(). This is a step toward removing ARM_DMA_USE_IOMMU. The IDENTITY domains added to the ARM64 supporting drivers can be tested by booting in ARM64 mode and enabling CONFIG_IOMMU_DEFAULT_PASSTHROUGH. If the system still boots then most likely the implementation is an IDENTITY domain. If not we can trivially change it to BLOCKING or at worst PLATFORM if there is no detail what is going on in the HW. I think this is pretty safe for the ARM32 drivers as they don't really change, the code that was in detach_dev continues to be called in the same places it was called before. This is on github: https://github.com/jgunthorpe/linux/commits/iommu_all_defdom v7: - Rebase on v6.5-rc6/Joerg's tree/iommufd - Most of patch "iommufd/selftest: Make the mock iommu driver into a real driver" is now in the iommufd tree, diffuse the remaining bits to "iommu: Add iommu_ops->identity_domain" and "iommu: Add IOMMU_DOMAIN_PLATFORM" - Move the check for domain->ops->free to patch 1 as the rockchip conversion relies on it - Add IOMMU_DOMAIN_PLATFORM to iommu_domain_type_str - Rewrite "iommu: Reorganize iommu_get_default_domain_type() to respect def_domain_type()" to be clearer and more robust - Remove left over .default_domain in tegra-smmu.c - Use group_iommu_ops() in all appropriate places - Typo s/paging/dev/ in sun50i v6: https://lore.kernel.org/r/0-v6-e8114faedade+425-iommu_all_defdom_...@nvidia.com - Rebase on v6.5-rc1/Joerg's tree - Fix the iommufd self test missing the iommu_device_sysfs_add() - Update typo in msm commit message v5: https://lore.kernel.org/r/0-v5-d0a204c678c7+3d16a-iommu_all_defdom_...@nvidia.com - Rebase on v6.5-rc1/Joerg's tree - Fix Dan's remark about 'gdev uninitialized' in patch 9 v4: https://lore.kernel.org/r/0-v4-874277bde66e+1a9f6-iommu_all_defdom_...@nvidia.com - Fix rebasing typo missing ops->alloc_domain_paging check - Rebase on latest Joerg tree v3: https://lore.kernel.org/r/0-v3-89830a6c7841+43d-iommu_all_defdom_...@nvidia.com - FSL is back to a PLATFORM domain, with some fixing so it attach only does something when leaving an UNMANAGED domain like it always was - Rebase on Joerg's tree, adjust for "alloc_type" change - Change the ARM32 untrusted check to a WARN_ON since no ARM32 system can currently set trusted v2: https://lore.kernel.org/r/0-v2-8d1dc464eac9+10f-iommu_all_defdom_...@nvidia.co
[PATCH v7 20/24] iommu: Require a default_domain for all iommu drivers
At this point every iommu driver will cause a default_domain to be selected, so we can finally remove this gap from the core code. The following table explains what each driver supports and what the resulting default_domain will be: ops->defaut_domain IDENTITY DMA PLATFORMv ARM32 dma-iommu ARCH amd/iommu.c Y Y N/A either apple-dart.cY Y N/A either arm-smmu.c Y Y IDENTITYeither qcom_iommu.cG Y IDENTITYeither arm-smmu-v3.c Y Y N/A either exynos-iommu.c G Y IDENTITYeither fsl_pamu_domain.c Y Y N/A N/A PLATFORM intel/iommu.c Y Y N/A either ipmmu-vmsa.cG Y IDENTITYeither msm_iommu.c G IDENTITYN/A mtk_iommu.c G Y IDENTITYeither mtk_iommu_v1.c G IDENTITYN/A omap-iommu.cG IDENTITYN/A rockchip-iommu.cG Y IDENTITYeither s390-iommu.cY Y N/A N/A PLATFORM sprd-iommu.cY N/A DMA sun50i-iommu.c G Y IDENTITYeither tegra-smmu.cG Y IDENTITYIDENTITY virtio-iommu.c Y Y N/A either spapr Y Y N/A N/A PLATFORM * G means ops->identity_domain is used * N/A means the driver will not compile in this configuration ARM32 drivers select an IDENTITY default domain through either the ops->identity_domain or directly requesting an IDENTIY domain through alloc_domain(). In ARM64 mode tegra-smmu will still block the use of dma-iommu.c and forces an IDENTITY domain. S390 uses a PLATFORM domain to represent when the dma_ops are set to the s390 iommu code. fsl_pamu uses an PLATFORM domain. POWER SPAPR uses PLATFORM and blocking to enable its weird VFIO mode. The x86 drivers continue unchanged. After this patch group->default_domain is only NULL for a short period during bus iommu probing while all the groups are constituted. Otherwise it is always !NULL. This completes changing the iommu subsystem driver contract to a system where the current iommu_domain always represents some form of translation and the driver is continuously asserting a definable translation mode. It resolves the confusion that the original ops->detach_dev() caused around what translation, exactly, is the IOMMU performing after detach. There were at least three different answers to that question in the tree, they are all now clearly named with domain types. Tested-by: Heiko Stuebner Tested-by: Niklas Schnelle Tested-by: Steven Price Tested-by: Marek Szyprowski Tested-by: Nicolin Chen Reviewed-by: Lu Baolu Signed-off-by: Jason Gunthorpe --- drivers/iommu/iommu.c | 22 +++--- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index a3b016543fad00..3003c249ab9b8e 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -1865,7 +1865,6 @@ static int iommu_get_def_domain_type(struct iommu_group *group, static int iommu_get_default_domain_type(struct iommu_group *group, int target_type) { - const struct iommu_ops *ops = group_iommu_ops(group); struct device *untrusted = NULL; struct group_device *gdev; int driver_type = 0; @@ -1876,11 +1875,13 @@ static int iommu_get_default_domain_type(struct iommu_group *group, * ARM32 drivers supporting CONFIG_ARM_DMA_USE_IOMMU can declare an * identity_domain and it will automatically become their default * domain. Later on ARM_DMA_USE_IOMMU will install its UNMANAGED domain. -* Override the selection to IDENTITY if we are sure the driver supports -* it. +* Override the selection to IDENTITY. */ - if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) && ops->identity_domain) + if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) { + static_assert(!(IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) && + IS_ENABLED(CONFIG_IOMMU_DMA))); driver_type = IOMMU_DOMAIN_IDENTITY; + } for_each_group_device(group, gdev) { driver_type = iommu_get_def_domain_type(group, gdev->dev, @@ -3016,18 +3
[PATCH v7 06/24] iommu/tegra-gart: Remove tegra-gart
Thierry says this is not used anymore, and doesn't think it makes sense as an iommu driver. The HW it supports is about 10 years old now and newer HW uses different IOMMU drivers. As this is the only driver with a GART approach, and it doesn't really meet the driver expectations from the IOMMU core, let's just remove it so we don't have to think about how to make it fit in. It has a number of identified problems: - The assignment of iommu_groups doesn't match the HW behavior - It claims to have an UNMANAGED domain but it is really an IDENTITY domain with a translation aperture. This is inconsistent with the core expectation for security sensitive operations - It doesn't implement a SW page table under struct iommu_domain so * It can't accept a map until the domain is attached * It forgets about all maps after the domain is detached * It doesn't clear the HW of maps once the domain is detached (made worse by having the wrong groups) Cc: Thierry Reding Cc: Dmitry Osipenko Acked-by: Thierry Reding Reviewed-by: Lu Baolu Signed-off-by: Jason Gunthorpe --- arch/arm/configs/multi_v7_defconfig | 1 - arch/arm/configs/tegra_defconfig| 1 - drivers/iommu/Kconfig | 11 - drivers/iommu/Makefile | 1 - drivers/iommu/tegra-gart.c | 371 drivers/memory/tegra/mc.c | 34 --- drivers/memory/tegra/tegra20.c | 28 --- include/soc/tegra/mc.h | 26 -- 8 files changed, 473 deletions(-) delete mode 100644 drivers/iommu/tegra-gart.c diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index c7b2550d706cac..ae1aa32c30b25e 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -1063,7 +1063,6 @@ CONFIG_BCM2835_MBOX=y CONFIG_QCOM_APCS_IPC=y CONFIG_QCOM_IPCC=y CONFIG_ROCKCHIP_IOMMU=y -CONFIG_TEGRA_IOMMU_GART=y CONFIG_TEGRA_IOMMU_SMMU=y CONFIG_EXYNOS_IOMMU=y CONFIG_QCOM_IOMMU=y diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig index 3c6af935e9328a..79141dddb037a9 100644 --- a/arch/arm/configs/tegra_defconfig +++ b/arch/arm/configs/tegra_defconfig @@ -292,7 +292,6 @@ CONFIG_CHROME_PLATFORMS=y CONFIG_CROS_EC=y CONFIG_CROS_EC_I2C=m CONFIG_CROS_EC_SPI=m -CONFIG_TEGRA_IOMMU_GART=y CONFIG_TEGRA_IOMMU_SMMU=y CONFIG_ARCH_TEGRA_2x_SOC=y CONFIG_ARCH_TEGRA_3x_SOC=y diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 2b12b583ef4b1e..cd6727898b1175 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -236,17 +236,6 @@ config SUN50I_IOMMU help Support for the IOMMU introduced in the Allwinner H6 SoCs. -config TEGRA_IOMMU_GART - bool "Tegra GART IOMMU Support" - depends on ARCH_TEGRA_2x_SOC - depends on TEGRA_MC - select IOMMU_API - help - Enables support for remapping discontiguous physical memory - shared with the operating system into contiguous I/O virtual - space through the GART (Graphics Address Relocation Table) - hardware included on Tegra SoCs. - config TEGRA_IOMMU_SMMU bool "NVIDIA Tegra SMMU Support" depends on ARCH_TEGRA diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 769e43d780ce89..95ad9dbfbda022 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -20,7 +20,6 @@ obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o obj-$(CONFIG_SUN50I_IOMMU) += sun50i-iommu.o -obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c deleted file mode 100644 index a482ff838b5331..00 --- a/drivers/iommu/tegra-gart.c +++ /dev/null @@ -1,371 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * IOMMU API for Graphics Address Relocation Table on Tegra20 - * - * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. - * - * Author: Hiroshi DOYU - */ - -#define dev_fmt(fmt) "gart: " fmt - -#include -#include -#include -#include -#include -#include -#include - -#include - -#define GART_REG_BASE 0x24 -#define GART_CONFIG(0x24 - GART_REG_BASE) -#define GART_ENTRY_ADDR(0x28 - GART_REG_BASE) -#define GART_ENTRY_DATA(0x2c - GART_REG_BASE) - -#define GART_ENTRY_PHYS_ADDR_VALID BIT(31) - -#define GART_PAGE_SHIFT12 -#define GART_PAGE_SIZE (1 << GART_PAGE_SHIFT) -#define GART_PAGE_MASK GENMASK(30, GART_PAGE_SHIFT) - -/* bitmap of the page sizes currently supported */ -#define GART_IOMMU_PGSIZES (GART_PAGE_SIZE) - -struct gart_device { - void __iomem*regs; - u32 *savedata; - unsigned
[PATCH v7 12/24] iommu/tegra-smmu: Support DMA domains in tegra
All ARM64 iommu drivers should support IOMMU_DOMAIN_DMA to enable dma-iommu.c. tegra is blocking dma-iommu usage, and also default_domain's, because it wants an identity translation. This is needed for some device quirk. The correct way to do this is to support IDENTITY domains and use ops->def_domain_type() to return IOMMU_DOMAIN_IDENTITY for only the quirky devices. Add support for IOMMU_DOMAIN_DMA and force IOMMU_DOMAIN_IDENTITY mode for everything so no behavior changes. Signed-off-by: Jason Gunthorpe --- drivers/iommu/tegra-smmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index 80481e1ba561b8..b91ad1b5a20d36 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c @@ -276,7 +276,7 @@ static struct iommu_domain *tegra_smmu_domain_alloc(unsigned type) { struct tegra_smmu_as *as; - if (type != IOMMU_DOMAIN_UNMANAGED) + if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA) return NULL; as = kzalloc(sizeof(*as), GFP_KERNEL); -- 2.41.0
[PATCH v7 22/24] iommu: Add ops->domain_alloc_paging()
This callback requests the driver to create only a __IOMMU_DOMAIN_PAGING domain, so it saves a few lines in a lot of drivers needlessly checking the type. More critically, this allows us to sweep out all the IOMMU_DOMAIN_UNMANAGED and IOMMU_DOMAIN_DMA checks from a lot of the drivers, simplifying what is going on in the code and ultimately removing the now-unused special cases in drivers where they did not support IOMMU_DOMAIN_DMA. domain_alloc_paging() should return a struct iommu_domain that is functionally compatible with ARM_DMA_USE_IOMMU, dma-iommu.c and iommufd. Be forwards looking and pass in a 'struct device *' argument. We can provide this when allocating the default_domain. No drivers will look at this. Tested-by: Steven Price Tested-by: Marek Szyprowski Tested-by: Nicolin Chen Reviewed-by: Lu Baolu Signed-off-by: Jason Gunthorpe --- drivers/iommu/iommu.c | 17 ++--- include/linux/iommu.h | 3 +++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 568dec45a06954..c5d8cf48a99332 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2041,6 +2041,7 @@ void iommu_set_fault_handler(struct iommu_domain *domain, EXPORT_SYMBOL_GPL(iommu_set_fault_handler); static struct iommu_domain *__iommu_domain_alloc(const struct iommu_ops *ops, +struct device *dev, unsigned int type) { struct iommu_domain *domain; @@ -2048,8 +2049,13 @@ static struct iommu_domain *__iommu_domain_alloc(const struct iommu_ops *ops, if (alloc_type == IOMMU_DOMAIN_IDENTITY && ops->identity_domain) return ops->identity_domain; + else if (type & __IOMMU_DOMAIN_PAGING && ops->domain_alloc_paging) + domain = ops->domain_alloc_paging(dev); + else if (ops->domain_alloc) + domain = ops->domain_alloc(alloc_type); + else + return NULL; - domain = ops->domain_alloc(alloc_type); if (!domain) return NULL; @@ -2074,14 +2080,19 @@ static struct iommu_domain *__iommu_domain_alloc(const struct iommu_ops *ops, static struct iommu_domain * __iommu_group_domain_alloc(struct iommu_group *group, unsigned int type) { - return __iommu_domain_alloc(group_iommu_ops(group), type); + struct device *dev = + list_first_entry(&group->devices, struct group_device, list) + ->dev; + + return __iommu_domain_alloc(group_iommu_ops(group), dev, type); } struct iommu_domain *iommu_domain_alloc(const struct bus_type *bus) { if (bus == NULL || bus->iommu_ops == NULL) return NULL; - return __iommu_domain_alloc(bus->iommu_ops, IOMMU_DOMAIN_UNMANAGED); + return __iommu_domain_alloc(bus->iommu_ops, NULL, + IOMMU_DOMAIN_UNMANAGED); } EXPORT_SYMBOL_GPL(iommu_domain_alloc); diff --git a/include/linux/iommu.h b/include/linux/iommu.h index c3d2e79076ffab..319bdc8328b407 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -239,6 +239,8 @@ struct iommu_iotlb_gather { * use. The information type is one of enum iommu_hw_info_type defined * in include/uapi/linux/iommufd.h. * @domain_alloc: allocate iommu domain + * @domain_alloc_paging: Allocate an iommu_domain that can be used for + * UNMANAGED, DMA, and DMA_FQ domain types. * @probe_device: Add device to iommu driver handling * @release_device: Remove device from iommu driver handling * @probe_finalize: Do final setup work after the device is added to an IOMMU @@ -271,6 +273,7 @@ struct iommu_ops { /* Domain allocation and freeing by the iommu driver */ struct iommu_domain *(*domain_alloc)(unsigned iommu_domain_type); + struct iommu_domain *(*domain_alloc_paging)(struct device *dev); struct iommu_device *(*probe_device)(struct device *dev); void (*release_device)(struct device *dev); -- 2.41.0
[PATCH v7 11/24] iommu/tegra-smmu: Implement an IDENTITY domain
What tegra-smmu does during tegra_smmu_set_platform_dma() is actually putting the iommu into identity mode. Move to the new core support for ARM_DMA_USE_IOMMU by defining ops->identity_domain. Reviewed-by: Lu Baolu Signed-off-by: Jason Gunthorpe --- drivers/iommu/tegra-smmu.c | 37 - 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index e445f80d02263b..80481e1ba561b8 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c @@ -511,23 +511,39 @@ static int tegra_smmu_attach_dev(struct iommu_domain *domain, return err; } -static void tegra_smmu_set_platform_dma(struct device *dev) +static int tegra_smmu_identity_attach(struct iommu_domain *identity_domain, + struct device *dev) { struct iommu_domain *domain = iommu_get_domain_for_dev(dev); struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); - struct tegra_smmu_as *as = to_smmu_as(domain); - struct tegra_smmu *smmu = as->smmu; + struct tegra_smmu_as *as; + struct tegra_smmu *smmu; unsigned int index; if (!fwspec) - return; + return -ENODEV; + if (domain == identity_domain || !domain) + return 0; + + as = to_smmu_as(domain); + smmu = as->smmu; for (index = 0; index < fwspec->num_ids; index++) { tegra_smmu_disable(smmu, fwspec->ids[index], as->id); tegra_smmu_as_unprepare(smmu, as); } + return 0; } +static struct iommu_domain_ops tegra_smmu_identity_ops = { + .attach_dev = tegra_smmu_identity_attach, +}; + +static struct iommu_domain tegra_smmu_identity_domain = { + .type = IOMMU_DOMAIN_IDENTITY, + .ops = &tegra_smmu_identity_ops, +}; + static void tegra_smmu_set_pde(struct tegra_smmu_as *as, unsigned long iova, u32 value) { @@ -962,11 +978,22 @@ static int tegra_smmu_of_xlate(struct device *dev, return iommu_fwspec_add_ids(dev, &id, 1); } +static int tegra_smmu_def_domain_type(struct device *dev) +{ + /* +* FIXME: For now we want to run all translation in IDENTITY mode, due +* to some device quirks. Better would be to just quirk the troubled +* devices. +*/ + return IOMMU_DOMAIN_IDENTITY; +} + static const struct iommu_ops tegra_smmu_ops = { + .identity_domain = &tegra_smmu_identity_domain, + .def_domain_type = &tegra_smmu_def_domain_type, .domain_alloc = tegra_smmu_domain_alloc, .probe_device = tegra_smmu_probe_device, .device_group = tegra_smmu_device_group, - .set_platform_dma_ops = tegra_smmu_set_platform_dma, .of_xlate = tegra_smmu_of_xlate, .pgsize_bitmap = SZ_4K, .default_domain_ops = &(const struct iommu_domain_ops) { -- 2.41.0
[PATCH v7 07/24] iommu/mtk_iommu_v1: Implement an IDENTITY domain
What mtk does during mtk_iommu_v1_set_platform_dma() is actually putting the iommu into identity mode. Make this available as a proper IDENTITY domain. The mtk_iommu_v1_def_domain_type() from commit 8bbe13f52cb7 ("iommu/mediatek-v1: Add def_domain_type") explains this was needed to allow probe_finalize() to be called, but now the IDENTITY domain will do the same job so change the returned def_domain_type. mkt_v1 is the only driver that returns IOMMU_DOMAIN_UNMANAGED from def_domain_type(). This allows the next patch to enforce an IDENTITY domain policy for this driver. Signed-off-by: Jason Gunthorpe --- drivers/iommu/mtk_iommu_v1.c | 21 +++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c index 8a0a5e5d049f4a..cc3e7d53d33ad9 100644 --- a/drivers/iommu/mtk_iommu_v1.c +++ b/drivers/iommu/mtk_iommu_v1.c @@ -319,11 +319,27 @@ static int mtk_iommu_v1_attach_device(struct iommu_domain *domain, struct device return 0; } -static void mtk_iommu_v1_set_platform_dma(struct device *dev) +static int mtk_iommu_v1_identity_attach(struct iommu_domain *identity_domain, + struct device *dev) { struct mtk_iommu_v1_data *data = dev_iommu_priv_get(dev); mtk_iommu_v1_config(data, dev, false); + return 0; +} + +static struct iommu_domain_ops mtk_iommu_v1_identity_ops = { + .attach_dev = mtk_iommu_v1_identity_attach, +}; + +static struct iommu_domain mtk_iommu_v1_identity_domain = { + .type = IOMMU_DOMAIN_IDENTITY, + .ops = &mtk_iommu_v1_identity_ops, +}; + +static void mtk_iommu_v1_set_platform_dma(struct device *dev) +{ + mtk_iommu_v1_identity_attach(&mtk_iommu_v1_identity_domain, dev); } static int mtk_iommu_v1_map(struct iommu_domain *domain, unsigned long iova, @@ -443,7 +459,7 @@ static int mtk_iommu_v1_create_mapping(struct device *dev, struct of_phandle_arg static int mtk_iommu_v1_def_domain_type(struct device *dev) { - return IOMMU_DOMAIN_UNMANAGED; + return IOMMU_DOMAIN_IDENTITY; } static struct iommu_device *mtk_iommu_v1_probe_device(struct device *dev) @@ -578,6 +594,7 @@ static int mtk_iommu_v1_hw_init(const struct mtk_iommu_v1_data *data) } static const struct iommu_ops mtk_iommu_v1_ops = { + .identity_domain = &mtk_iommu_v1_identity_domain, .domain_alloc = mtk_iommu_v1_domain_alloc, .probe_device = mtk_iommu_v1_probe_device, .probe_finalize = mtk_iommu_v1_probe_finalize, -- 2.41.0
[PATCH v7 10/24] iommu/exynos: Implement an IDENTITY domain
What exynos calls exynos_iommu_detach_device is actually putting the iommu into identity mode. Move to the new core support for ARM_DMA_USE_IOMMU by defining ops->identity_domain. Tested-by: Marek Szyprowski Acked-by: Marek Szyprowski Signed-off-by: Jason Gunthorpe --- drivers/iommu/exynos-iommu.c | 66 +--- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index c275fe71c4db32..5e12b85dfe8705 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -24,6 +24,7 @@ typedef u32 sysmmu_iova_t; typedef u32 sysmmu_pte_t; +static struct iommu_domain exynos_identity_domain; /* We do not consider super section mapping (16MB) */ #define SECT_ORDER 20 @@ -829,7 +830,7 @@ static int __maybe_unused exynos_sysmmu_suspend(struct device *dev) struct exynos_iommu_owner *owner = dev_iommu_priv_get(master); mutex_lock(&owner->rpm_lock); - if (data->domain) { + if (&data->domain->domain != &exynos_identity_domain) { dev_dbg(data->sysmmu, "saving state\n"); __sysmmu_disable(data); } @@ -847,7 +848,7 @@ static int __maybe_unused exynos_sysmmu_resume(struct device *dev) struct exynos_iommu_owner *owner = dev_iommu_priv_get(master); mutex_lock(&owner->rpm_lock); - if (data->domain) { + if (&data->domain->domain != &exynos_identity_domain) { dev_dbg(data->sysmmu, "restoring state\n"); __sysmmu_enable(data); } @@ -980,17 +981,20 @@ static void exynos_iommu_domain_free(struct iommu_domain *iommu_domain) kfree(domain); } -static void exynos_iommu_detach_device(struct iommu_domain *iommu_domain, - struct device *dev) +static int exynos_iommu_identity_attach(struct iommu_domain *identity_domain, + struct device *dev) { - struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain); struct exynos_iommu_owner *owner = dev_iommu_priv_get(dev); - phys_addr_t pagetable = virt_to_phys(domain->pgtable); + struct exynos_iommu_domain *domain; + phys_addr_t pagetable; struct sysmmu_drvdata *data, *next; unsigned long flags; - if (!has_sysmmu(dev) || owner->domain != iommu_domain) - return; + if (owner->domain == identity_domain) + return 0; + + domain = to_exynos_domain(owner->domain); + pagetable = virt_to_phys(domain->pgtable); mutex_lock(&owner->rpm_lock); @@ -1009,15 +1013,25 @@ static void exynos_iommu_detach_device(struct iommu_domain *iommu_domain, list_del_init(&data->domain_node); spin_unlock(&data->lock); } - owner->domain = NULL; + owner->domain = identity_domain; spin_unlock_irqrestore(&domain->lock, flags); mutex_unlock(&owner->rpm_lock); - dev_dbg(dev, "%s: Detached IOMMU with pgtable %pa\n", __func__, - &pagetable); + dev_dbg(dev, "%s: Restored IOMMU to IDENTITY from pgtable %pa\n", + __func__, &pagetable); + return 0; } +static struct iommu_domain_ops exynos_identity_ops = { + .attach_dev = exynos_iommu_identity_attach, +}; + +static struct iommu_domain exynos_identity_domain = { + .type = IOMMU_DOMAIN_IDENTITY, + .ops = &exynos_identity_ops, +}; + static int exynos_iommu_attach_device(struct iommu_domain *iommu_domain, struct device *dev) { @@ -1026,12 +1040,11 @@ static int exynos_iommu_attach_device(struct iommu_domain *iommu_domain, struct sysmmu_drvdata *data; phys_addr_t pagetable = virt_to_phys(domain->pgtable); unsigned long flags; + int err; - if (!has_sysmmu(dev)) - return -ENODEV; - - if (owner->domain) - exynos_iommu_detach_device(owner->domain, dev); + err = exynos_iommu_identity_attach(&exynos_identity_domain, dev); + if (err) + return err; mutex_lock(&owner->rpm_lock); @@ -1407,26 +1420,12 @@ static struct iommu_device *exynos_iommu_probe_device(struct device *dev) return &data->iommu; } -static void exynos_iommu_set_platform_dma(struct device *dev) -{ - struct exynos_iommu_owner *owner = dev_iommu_priv_get(dev); - - if (owner->domain) { - struct iommu_group *group = iommu_group_get(dev); - - if (group) { - exynos_iommu_detach_device(owner->domain, dev); - iommu_group_put(group); - } - } -} - static void exynos_iommu_release_device(struct device *dev) { struct exynos_iommu_owner *owner = dev_iommu_priv_get(dev);
[PATCH v7 23/24] iommu: Convert simple drivers with DOMAIN_DMA to domain_alloc_paging()
These drivers are all trivially converted since the function is only called if the domain type is going to be IOMMU_DOMAIN_UNMANAGED/DMA. Tested-by: Heiko Stuebner Tested-by: Steven Price Tested-by: Marek Szyprowski Tested-by: Nicolin Chen Reviewed-by: Lu Baolu Signed-off-by: Jason Gunthorpe --- drivers/iommu/arm/arm-smmu/qcom_iommu.c | 6 ++ drivers/iommu/exynos-iommu.c| 7 ++- drivers/iommu/ipmmu-vmsa.c | 7 ++- drivers/iommu/mtk_iommu.c | 7 ++- drivers/iommu/rockchip-iommu.c | 7 ++- drivers/iommu/sprd-iommu.c | 7 ++- drivers/iommu/sun50i-iommu.c| 9 +++-- drivers/iommu/tegra-smmu.c | 7 ++- 8 files changed, 17 insertions(+), 40 deletions(-) diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c index bc45d18f350cb9..97b2122032b237 100644 --- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c +++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c @@ -332,12 +332,10 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain, return ret; } -static struct iommu_domain *qcom_iommu_domain_alloc(unsigned type) +static struct iommu_domain *qcom_iommu_domain_alloc_paging(struct device *dev) { struct qcom_iommu_domain *qcom_domain; - if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA) - return NULL; /* * Allocate the domain and initialise some of its data structures. * We can't really do anything meaningful until we've added a @@ -605,7 +603,7 @@ static int qcom_iommu_of_xlate(struct device *dev, struct of_phandle_args *args) static const struct iommu_ops qcom_iommu_ops = { .identity_domain = &qcom_iommu_identity_domain, .capable= qcom_iommu_capable, - .domain_alloc = qcom_iommu_domain_alloc, + .domain_alloc_paging = qcom_iommu_domain_alloc_paging, .probe_device = qcom_iommu_probe_device, .device_group = generic_device_group, .of_xlate = qcom_iommu_of_xlate, diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 5e12b85dfe8705..d6dead2ed10c11 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -887,7 +887,7 @@ static inline void exynos_iommu_set_pte(sysmmu_pte_t *ent, sysmmu_pte_t val) DMA_TO_DEVICE); } -static struct iommu_domain *exynos_iommu_domain_alloc(unsigned type) +static struct iommu_domain *exynos_iommu_domain_alloc_paging(struct device *dev) { struct exynos_iommu_domain *domain; dma_addr_t handle; @@ -896,9 +896,6 @@ static struct iommu_domain *exynos_iommu_domain_alloc(unsigned type) /* Check if correct PTE offsets are initialized */ BUG_ON(PG_ENT_SHIFT < 0 || !dma_dev); - if (type != IOMMU_DOMAIN_DMA && type != IOMMU_DOMAIN_UNMANAGED) - return NULL; - domain = kzalloc(sizeof(*domain), GFP_KERNEL); if (!domain) return NULL; @@ -1472,7 +1469,7 @@ static int exynos_iommu_of_xlate(struct device *dev, static const struct iommu_ops exynos_iommu_ops = { .identity_domain = &exynos_identity_domain, - .domain_alloc = exynos_iommu_domain_alloc, + .domain_alloc_paging = exynos_iommu_domain_alloc_paging, .device_group = generic_device_group, .probe_device = exynos_iommu_probe_device, .release_device = exynos_iommu_release_device, diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c index 04830d3931d239..eaabae76157761 100644 --- a/drivers/iommu/ipmmu-vmsa.c +++ b/drivers/iommu/ipmmu-vmsa.c @@ -563,13 +563,10 @@ static irqreturn_t ipmmu_irq(int irq, void *dev) * IOMMU Operations */ -static struct iommu_domain *ipmmu_domain_alloc(unsigned type) +static struct iommu_domain *ipmmu_domain_alloc_paging(struct device *dev) { struct ipmmu_vmsa_domain *domain; - if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA) - return NULL; - domain = kzalloc(sizeof(*domain), GFP_KERNEL); if (!domain) return NULL; @@ -892,7 +889,7 @@ static struct iommu_group *ipmmu_find_group(struct device *dev) static const struct iommu_ops ipmmu_ops = { .identity_domain = &ipmmu_iommu_identity_domain, - .domain_alloc = ipmmu_domain_alloc, + .domain_alloc_paging = ipmmu_domain_alloc_paging, .probe_device = ipmmu_probe_device, .release_device = ipmmu_release_device, .probe_finalize = ipmmu_probe_finalize, diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index 164f9759e1c039..19ef50221c93db 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -689,13 +689,10 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom, return 0; } -static struct iommu_domain *mtk_iommu_domain_alloc(unsigned type) +static struct iommu_dom
[PATCH v7 19/24] iommu/sun50i: Add an IOMMU_IDENTITIY_DOMAIN
Prior to commit 1b932ceddd19 ("iommu: Remove detach_dev callbacks") the sun50i_iommu_detach_device() function was being called by ops->detach_dev(). This is an IDENTITY domain so convert sun50i_iommu_detach_device() into sun50i_iommu_identity_attach() and a full IDENTITY domain and thus hook it back up the same was as the old ops->detach_dev(). Signed-off-by: Jason Gunthorpe --- drivers/iommu/sun50i-iommu.c | 26 +++--- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c index 74c5cb93e90027..0bf08b120cf105 100644 --- a/drivers/iommu/sun50i-iommu.c +++ b/drivers/iommu/sun50i-iommu.c @@ -757,21 +757,32 @@ static void sun50i_iommu_detach_domain(struct sun50i_iommu *iommu, iommu->domain = NULL; } -static void sun50i_iommu_detach_device(struct iommu_domain *domain, - struct device *dev) +static int sun50i_iommu_identity_attach(struct iommu_domain *identity_domain, + struct device *dev) { - struct sun50i_iommu_domain *sun50i_domain = to_sun50i_domain(domain); struct sun50i_iommu *iommu = dev_iommu_priv_get(dev); + struct sun50i_iommu_domain *sun50i_domain; dev_dbg(dev, "Detaching from IOMMU domain\n"); - if (iommu->domain != domain) - return; + if (iommu->domain == identity_domain) + return 0; + sun50i_domain = to_sun50i_domain(iommu->domain); if (refcount_dec_and_test(&sun50i_domain->refcnt)) sun50i_iommu_detach_domain(iommu, sun50i_domain); + return 0; } +static struct iommu_domain_ops sun50i_iommu_identity_ops = { + .attach_dev = sun50i_iommu_identity_attach, +}; + +static struct iommu_domain sun50i_iommu_identity_domain = { + .type = IOMMU_DOMAIN_IDENTITY, + .ops = &sun50i_iommu_identity_ops, +}; + static int sun50i_iommu_attach_device(struct iommu_domain *domain, struct device *dev) { @@ -789,8 +800,7 @@ static int sun50i_iommu_attach_device(struct iommu_domain *domain, if (iommu->domain == domain) return 0; - if (iommu->domain) - sun50i_iommu_detach_device(iommu->domain, dev); + sun50i_iommu_identity_attach(&sun50i_iommu_identity_domain, dev); sun50i_iommu_attach_domain(iommu, sun50i_domain); @@ -827,6 +837,7 @@ static int sun50i_iommu_of_xlate(struct device *dev, } static const struct iommu_ops sun50i_iommu_ops = { + .identity_domain = &sun50i_iommu_identity_domain, .pgsize_bitmap = SZ_4K, .device_group = sun50i_iommu_device_group, .domain_alloc = sun50i_iommu_domain_alloc, @@ -985,6 +996,7 @@ static int sun50i_iommu_probe(struct platform_device *pdev) if (!iommu) return -ENOMEM; spin_lock_init(&iommu->iommu_lock); + iommu->domain = &sun50i_iommu_identity_domain; platform_set_drvdata(pdev, iommu); iommu->dev = &pdev->dev; -- 2.41.0
[PATCH v7 09/24] iommu: Allow an IDENTITY domain as the default_domain in ARM32
Even though dma-iommu.c and CONFIG_ARM_DMA_USE_IOMMU do approximately the same stuff, the way they relate to the IOMMU core is quiet different. dma-iommu.c expects the core code to setup an UNMANAGED domain (of type IOMMU_DOMAIN_DMA) and then configures itself to use that domain. This becomes the default_domain for the group. ARM_DMA_USE_IOMMU does not use the default_domain, instead it directly allocates an UNMANAGED domain and operates it just like an external driver. In this case group->default_domain is NULL. If the driver provides a global static identity_domain then automatically use it as the default_domain when in ARM_DMA_USE_IOMMU mode. This allows drivers that implemented default_domain == NULL as an IDENTITY translation to trivially get a properly labeled non-NULL default_domain on ARM32 configs. With this arrangment when ARM_DMA_USE_IOMMU wants to disconnect from the device the normal detach_domain flow will restore the IDENTITY domain as the default domain. Overall this makes attach_dev() of the IDENTITY domain called in the same places as detach_dev(). This effectively migrates these drivers to default_domain mode. For drivers that support ARM64 they will gain support for the IDENTITY translation mode for the dma_api and behave in a uniform way. Drivers use this by setting ops->identity_domain to a static singleton iommu_domain that implements the identity attach. If the core detects ARM_DMA_USE_IOMMU mode then it automatically attaches the IDENTITY domain during probe. Drivers can continue to prevent the use of DMA translation by returning IOMMU_DOMAIN_IDENTITY from def_domain_type, this will completely prevent IOMMU_DMA from running but will not impact ARM_DMA_USE_IOMMU. This allows removing the set_platform_dma_ops() from every remaining driver. Remove the set_platform_dma_ops from rockchip and mkt_v1 as all it does is set an existing global static identity domain. mkt_v1 does not support IOMMU_DOMAIN_DMA and it does not compile on ARM64 so this transformation is safe. Tested-by: Steven Price Tested-by: Marek Szyprowski Tested-by: Nicolin Chen Reviewed-by: Lu Baolu Signed-off-by: Jason Gunthorpe --- drivers/iommu/iommu.c | 21 - drivers/iommu/mtk_iommu_v1.c | 12 drivers/iommu/rockchip-iommu.c | 10 -- 3 files changed, 20 insertions(+), 23 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index bdeeb574d9495c..5fb25bcbc42f76 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -1865,17 +1865,36 @@ static int iommu_get_def_domain_type(struct iommu_group *group, static int iommu_get_default_domain_type(struct iommu_group *group, int target_type) { + const struct iommu_ops *ops = group_iommu_ops(group); struct device *untrusted = NULL; struct group_device *gdev; int driver_type = 0; lockdep_assert_held(&group->mutex); + + /* +* ARM32 drivers supporting CONFIG_ARM_DMA_USE_IOMMU can declare an +* identity_domain and it will automatically become their default +* domain. Later on ARM_DMA_USE_IOMMU will install its UNMANAGED domain. +* Override the selection to IDENTITY if we are sure the driver supports +* it. +*/ + if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) && ops->identity_domain) + driver_type = IOMMU_DOMAIN_IDENTITY; + for_each_group_device(group, gdev) { driver_type = iommu_get_def_domain_type(group, gdev->dev, driver_type); - if (dev_is_pci(gdev->dev) && to_pci_dev(gdev->dev)->untrusted) + if (dev_is_pci(gdev->dev) && to_pci_dev(gdev->dev)->untrusted) { + /* +* No ARM32 using systems will set untrusted, it cannot +* work. +*/ + if (WARN_ON(IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU))) + return -1; untrusted = gdev->dev; + } } if (untrusted) { diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c index cc3e7d53d33ad9..7c0c1d50df5f75 100644 --- a/drivers/iommu/mtk_iommu_v1.c +++ b/drivers/iommu/mtk_iommu_v1.c @@ -337,11 +337,6 @@ static struct iommu_domain mtk_iommu_v1_identity_domain = { .ops = &mtk_iommu_v1_identity_ops, }; -static void mtk_iommu_v1_set_platform_dma(struct device *dev) -{ - mtk_iommu_v1_identity_attach(&mtk_iommu_v1_identity_domain, dev); -} - static int mtk_iommu_v1_map(struct iommu_domain *domain, unsigned long iova, phys_addr_t paddr, size_t pgsize, size_t pgcount, int prot, gfp_t gfp, size_t *mapped) @@ -457,11 +452,6 @@ static int mtk_iommu_v1_create_mapping(struct device *dev, struct of_phandle_arg return 0; }
Re: [PATCH] cpufreq: pmac32: Use of_property_read_reg() to parse "reg"
On Sun, Jul 2, 2023 at 10:01 PM Viresh Kumar wrote: > > On 09-06-23, 12:31, Rob Herring wrote: > > Use the recently added of_property_read_reg() helper to get the > > untranslated "reg" address value. > > > > Signed-off-by: Rob Herring > > --- > > drivers/cpufreq/pmac32-cpufreq.c | 5 ++--- > > 1 file changed, 2 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/cpufreq/pmac32-cpufreq.c > > b/drivers/cpufreq/pmac32-cpufreq.c > > index ec75e79659ac..f53635ba16c1 100644 > > --- a/drivers/cpufreq/pmac32-cpufreq.c > > +++ b/drivers/cpufreq/pmac32-cpufreq.c > > @@ -378,10 +378,9 @@ static int pmac_cpufreq_cpu_init(struct cpufreq_policy > > *policy) > > > > static u32 read_gpio(struct device_node *np) > > { > > - const u32 *reg = of_get_property(np, "reg", NULL); > > - u32 offset; > > + u64 offset; > > > > - if (reg == NULL) > > + if (of_property_read_reg(np, 0, &offset, NULL) < 0) > > return 0; > > /* That works for all keylargos but shall be fixed properly > >* some day... The problem is that it seems we can't rely > > Acked-by: Viresh Kumar Is someone going to apply this? Rob
Re: [PATCH RFC] rcu: torture: shorten the time between forward-progress tests
On Tue, May 02, 2023 at 11:06:02PM +0800, zhouzho...@gmail.com wrote: > From: Zhouyi Zhou > > Currently, default time between rcu torture forward-progress tests is 60HZ, > Under this configuration, false positive caused by __stack_chk_fail [1] is > difficult to reproduce (needs average 5*420 seconds for SRCU-P), > which means one has to invoke [2] 5 times in average to make [1] appear. > > With time between rcu torture forward-progress tests be 1 HZ, above > phenomenon will be reproduced within 3 minutes, which means we can > reproduce [1] everytime we invoke [2]. > > Although [1] is a false positive, this change will make possible future > true bugs easier to be discovered. > > [1] Link: > https://lore.kernel.org/lkml/CAABZP2yS5=zuwezq7ihkv0wdm_hgo8k-teahyjrzhavzkda...@mail.gmail.com/T/ > [2] tools/testing/selftests/rcutorture/bin/torture.sh > > Tested in PPC VM of Opensource Lab of Oregon State Univerisity. > > Signed-off-by: Zhouyi Zhou Please accept my apologies for being ridiculously slow to reply! In recent -rcu, module parameters such as this one that simply set a value can be overridden on the command line. So you could get the effect (again, in recent kernels) in your testing by adding: --bootargs "rcutorture.fwd_progress_holdoff=1" The reason that I am reluctant to accept this patch is that we sometimes have trouble with this forward-progress testing exhausting memory, and making in happen could therefore cause trouble with generic rcutorture testing. Or am I missing the point of this change? Thanx, Paul > --- > tools/testing/selftests/rcutorture/configs/rcu/SRCU-N.boot | 1 + > tools/testing/selftests/rcutorture/configs/rcu/SRCU-P.boot | 1 + > tools/testing/selftests/rcutorture/configs/rcu/TRACE02.boot | 1 + > tools/testing/selftests/rcutorture/configs/rcu/TREE02.boot | 1 + > tools/testing/selftests/rcutorture/configs/rcu/TREE10.boot | 1 + > 5 files changed, 5 insertions(+) > > diff --git a/tools/testing/selftests/rcutorture/configs/rcu/SRCU-N.boot > b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-N.boot > index ce0694fd9b92..982582bff041 100644 > --- a/tools/testing/selftests/rcutorture/configs/rcu/SRCU-N.boot > +++ b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-N.boot > @@ -1,2 +1,3 @@ > rcutorture.torture_type=srcu > rcutorture.fwd_progress=3 > +rcutorture.fwd_progress_holdoff=1 > diff --git a/tools/testing/selftests/rcutorture/configs/rcu/SRCU-P.boot > b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-P.boot > index 2db39f298d18..18f5d7361d8a 100644 > --- a/tools/testing/selftests/rcutorture/configs/rcu/SRCU-P.boot > +++ b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-P.boot > @@ -1,4 +1,5 @@ > rcutorture.torture_type=srcud > rcupdate.rcu_self_test=1 > rcutorture.fwd_progress=3 > +rcutorture.fwd_progress_holdoff=1 > srcutree.big_cpu_lim=5 > diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TRACE02.boot > b/tools/testing/selftests/rcutorture/configs/rcu/TRACE02.boot > index c70b5db6c2ae..b86bc7df7603 100644 > --- a/tools/testing/selftests/rcutorture/configs/rcu/TRACE02.boot > +++ b/tools/testing/selftests/rcutorture/configs/rcu/TRACE02.boot > @@ -1,2 +1,3 @@ > rcutorture.torture_type=tasks-tracing > rcutorture.fwd_progress=2 > +rcutorture.fwd_progress_holdoff=1 > diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE02.boot > b/tools/testing/selftests/rcutorture/configs/rcu/TREE02.boot > index dd914fa8f690..933302f885df 100644 > --- a/tools/testing/selftests/rcutorture/configs/rcu/TREE02.boot > +++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE02.boot > @@ -1 +1,2 @@ > rcutorture.fwd_progress=2 > +rcutorture.fwd_progress_holdoff=1 > diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE10.boot > b/tools/testing/selftests/rcutorture/configs/rcu/TREE10.boot > index dd914fa8f690..933302f885df 100644 > --- a/tools/testing/selftests/rcutorture/configs/rcu/TREE10.boot > +++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE10.boot > @@ -1 +1,2 @@ > rcutorture.fwd_progress=2 > +rcutorture.fwd_progress_holdoff=1 > -- > 2.34.1 >
Re: [PATCH treewide 0/9] Remove obsolete IDE headers
On 8/18/23 01:07, Geert Uytterhoeven wrote: > Hi all, > > This patch series removes all unused headers and > . was still included by 3 PATA > drivers for m68k platforms, but without any real need. > > The first 5 patches have no dependencies. > The last patch depends on the 3 pata patches. > > Thanks for your comments! > > Geert Uytterhoeven (9): > ARM: Remove > parisc: Remove > powerpc: Remove > sparc: Remove > asm-generic: Remove ide_iops.h > ata: pata_buddha: Remove #include > ata: pata_falcon: Remove #include > ata: pata_gayle: Remove #include > m68k: Remove Applied to libata for-6.6. Thanks ! -- Damien Le Moal Western Digital Research
Re: KASAN debug kernel fails to boot at early stage when CONFIG_SMP=y is set (kernel 6.5-rc5, PowerMac G4 3,6)
On Tue, 22 Aug 2023 07:31:54 + Christophe Leroy wrote: > Le 18/08/2023 à 18:23, Erhard Furtner a écrit : > > On Fri, 18 Aug 2023 15:47:38 + > > Christophe Leroy wrote: > > > >> I'm wondering if the problem is just linked to the kernel being built > >> with CONFIG_SMP or if it is the actual startup of a secondary CPU that > >> cause the freeze. > >> > >> Please leave the btext_unmap() in place because I think it is important > >> to keep it, and start the kernel with the following parameter: > >> > >> nr_cpus=1 > > > > With btext_unmap() back and place and nr_cpus=1 set the freeze still > > happens after the 1st btext_unmap:129 on cold boots: > > > > [0.00] printk: bootconsole [udbg0] enabled > > [0.00] Total memory = 2048MB; using 4096kB for hash table > > [0.00] mapin_ram:125 > > [0.00] mmu_mapin_ram:169 0 3000 140 200 > > [0.00] __mmu_mapin_ram:146 0 140 > > [0.00] __mmu_mapin_ram:155 140 > > [0.00] __mmu_mapin_ram:146 140 3000 > > [0.00] __mmu_mapin_ram:155 2000 > > [0.00] __mapin_ram_chunk:107 2000 3000 > > [0.00] __mapin_ram_chunk:117 > > [0.00] mapin_ram:134 > > [0.00] kasan_mmu_init:129 > > [0.00] kasan_mmu_init:132 0 > > [0.00] kasan_mmu_init:137 > > [0.00] btext_unmap:129 > > > > Thanks, > > Can you replace the call to btext_unmap() by a call to btext_map() at > the end of MMU_init() ? > > If that gives no interesting result, can you leave the call to > btext_unmap() and add a call to btext_map() at the very begining of > function start_kernel() in init/main.c (You may have to add a include of > asm/btext.h) > > With that I hope we can see more stuff. Ok, I tested out both methods. 1.) Replace btext_unmap() with btext_map() at the end of MMU_init(). Warm boot again is unspectacular (attached). On cold boots I sometimes get: printk: bootconsole [udbg0] enabled Total memory = 2048MB; using 4096kB for hash table mapin_ram:125 mmu_mapin_ram:169 0 3000 140 200 __mmu_mapin_ram:146 0 140 __mmu_mapin_ram:155 140 __mmu_mapin_ram:146 140 3000 __mmu_mapin_ram:155 2000 __mapin_ram_chunk:107 2000 3000 __mapin_ram_chunk:117 mapin_ram:134 kasan_mmu_init:129 kasan_mmu_init:132 0 kasan_mmu_init:137 ioremap() called early from btext_map+0x64/0xdc. Use early_ioremap() instead Linux version 6.5.0-rc7-PMacG4-dirty (root@T1000) (gcc (Gentoo 12.3.1_p20230526 p2) 12.3.1 20230526, GNU ld (Gentoo 2.40 p7) 2.40.0) #4 SMP Wed Aug 23 12:59:11 CEST 2023 which shows one line (Linux version...) more than before. Most of the time I get this more interesting output however: kasan_mmu_init:129 kasan_mmu_init:132 0 kasan_mmu_init:137 Linux version 6.5.0-rc7-PMacG4-dirty (root@T1000) (gcc (Gentoo 12.3.1_p20230526 p2) 12.3.1 20230526, GNU ld (Gentoo 2.40 p7) 2.40.0) #4 SMP Wed Aug 23 12:59:11 CEST 2023 KASAN init done list_add corruption. prev->next should be next (c17100c0), but was 2c03. (prev=c036ac7c). [ cut here ] kernel BUG at lib/list_debug.c:30! [ cut here ] WARNING: CPU: 0 PID: 0 at arch/powerpc/include/asm/machdep.h:227 die+0xd8/0x39c Modules linked in: CPU: 0 PID: 0 Comm: swapper Tainted: G T ∎∎irty⊥q NIP: c0012c64 LR: c0012c58 CTR: REGS: c1717d10 TRAP: 0700 Tainted: G T (∎∎irty⊥q) MSR: 00021032 CR: 24000484 XER: GPR00: c1717dc0 c1551c40 GPR08: 00dd6f30 021f6e90 GPR16: 021f69b0 02201994 00dd6f3c efff3190 c1717f10 c1455dd8 c11ec6c0 GPR24: 1032 c0fab540 c1717e10 0005 c174 c174 c1746380 c1555a20 NIP [c0012c64] die+0xd8/0x39c LR [c0012c58] die+0xcc/0x39c Call Trace: [c1717dc0] [c0012c58] die+0xcc/0x39c (unreliable) [c1717e00] [c00047f0] ProgramCheck_virt+0x100/0x150 --- interrupt: 700 at __list_add_valid+0xe8/0x120 NIP: c0854ca0 LR: c0854ca0 CTR: REGS: c1717e10 TRAP: 0700 Tainted: GT (∎∎irty⊥q) MSR: 00021032 CR: 24000488 XER: GPR00: c1717ec0 c1551c40 005d GPR08: 00dd6f30 021f6e90 GPR16: 021f69b0 02201994 00dd6f3c efff3190 c1717f10 c1455dd8 c11ec6c0 GPR24: f82e2fde c11ec680 fefefefe c11ec700 effec7a8 c036ac7c c036ac7c c17100c0 NIP [c0854ca0] __list_add_valid+0xe8/@x120 LR [c0854ca0] __list_add_valid+0xe8/@x120 --- interrupt: 700 [c1717ee8] [c0c18764] of_alias_scan+0x330/0x44c [c1717f70] [c140b0fc] setup_arch+0x78/0x44c [c1717fc0] [c14045b0] start_kernel+0x78/0x2d8 [c1717ff0] [35d0] 0x35d0 Code: 3fa0c174 915f0060 39290001 913e0040 480f602d 3861 488189f1 387db620 4835654d 813db620 2c09 40820008 <0fe0> 80de0080 3fa0c0fb 3ee0c172 ---[ end
Re: [PATCH RFC] rcu: torture: shorten the time between forward-progress tests
On Thu, Aug 24, 2023 at 5:15 AM Paul E. McKenney wrote: > > On Tue, May 02, 2023 at 11:06:02PM +0800, zhouzho...@gmail.com wrote: > > From: Zhouyi Zhou > > > > Currently, default time between rcu torture forward-progress tests is 60HZ, > > Under this configuration, false positive caused by __stack_chk_fail [1] is > > difficult to reproduce (needs average 5*420 seconds for SRCU-P), > > which means one has to invoke [2] 5 times in average to make [1] appear. > > > > With time between rcu torture forward-progress tests be 1 HZ, above > > phenomenon will be reproduced within 3 minutes, which means we can > > reproduce [1] everytime we invoke [2]. > > > > Although [1] is a false positive, this change will make possible future > > true bugs easier to be discovered. > > > > [1] Link: > > https://lore.kernel.org/lkml/CAABZP2yS5=zuwezq7ihkv0wdm_hgo8k-teahyjrzhavzkda...@mail.gmail.com/T/ > > [2] tools/testing/selftests/rcutorture/bin/torture.sh > > > > Tested in PPC VM of Opensource Lab of Oregon State Univerisity. > > > > Signed-off-by: Zhouyi Zhou > > Please accept my apologies for being ridiculously slow to reply! Never mind. I have made a lot of self improvement during the study of RCU and RCU torture and your book ;-) > > In recent -rcu, module parameters such as this one that simply set a > value can be overridden on the command line. So you could get the effect > (again, in recent kernels) in your testing by adding: > > --bootargs "rcutorture.fwd_progress_holdoff=1" > > The reason that I am reluctant to accept this patch is that we sometimes > have trouble with this forward-progress testing exhausting memory, and > making in happen could therefore cause trouble with generic rcutorture > testing. Agree, false positives can disrupt our judgement in many cases. Thanx Zhouyi > > Or am I missing the point of this change? > > Thanx, Paul > > > --- > > tools/testing/selftests/rcutorture/configs/rcu/SRCU-N.boot | 1 + > > tools/testing/selftests/rcutorture/configs/rcu/SRCU-P.boot | 1 + > > tools/testing/selftests/rcutorture/configs/rcu/TRACE02.boot | 1 + > > tools/testing/selftests/rcutorture/configs/rcu/TREE02.boot | 1 + > > tools/testing/selftests/rcutorture/configs/rcu/TREE10.boot | 1 + > > 5 files changed, 5 insertions(+) > > > > diff --git a/tools/testing/selftests/rcutorture/configs/rcu/SRCU-N.boot > > b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-N.boot > > index ce0694fd9b92..982582bff041 100644 > > --- a/tools/testing/selftests/rcutorture/configs/rcu/SRCU-N.boot > > +++ b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-N.boot > > @@ -1,2 +1,3 @@ > > rcutorture.torture_type=srcu > > rcutorture.fwd_progress=3 > > +rcutorture.fwd_progress_holdoff=1 > > diff --git a/tools/testing/selftests/rcutorture/configs/rcu/SRCU-P.boot > > b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-P.boot > > index 2db39f298d18..18f5d7361d8a 100644 > > --- a/tools/testing/selftests/rcutorture/configs/rcu/SRCU-P.boot > > +++ b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-P.boot > > @@ -1,4 +1,5 @@ > > rcutorture.torture_type=srcud > > rcupdate.rcu_self_test=1 > > rcutorture.fwd_progress=3 > > +rcutorture.fwd_progress_holdoff=1 > > srcutree.big_cpu_lim=5 > > diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TRACE02.boot > > b/tools/testing/selftests/rcutorture/configs/rcu/TRACE02.boot > > index c70b5db6c2ae..b86bc7df7603 100644 > > --- a/tools/testing/selftests/rcutorture/configs/rcu/TRACE02.boot > > +++ b/tools/testing/selftests/rcutorture/configs/rcu/TRACE02.boot > > @@ -1,2 +1,3 @@ > > rcutorture.torture_type=tasks-tracing > > rcutorture.fwd_progress=2 > > +rcutorture.fwd_progress_holdoff=1 > > diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE02.boot > > b/tools/testing/selftests/rcutorture/configs/rcu/TREE02.boot > > index dd914fa8f690..933302f885df 100644 > > --- a/tools/testing/selftests/rcutorture/configs/rcu/TREE02.boot > > +++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE02.boot > > @@ -1 +1,2 @@ > > rcutorture.fwd_progress=2 > > +rcutorture.fwd_progress_holdoff=1 > > diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE10.boot > > b/tools/testing/selftests/rcutorture/configs/rcu/TREE10.boot > > index dd914fa8f690..933302f885df 100644 > > --- a/tools/testing/selftests/rcutorture/configs/rcu/TREE10.boot > > +++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE10.boot > > @@ -1 +1,2 @@ > > rcutorture.fwd_progress=2 > > +rcutorture.fwd_progress_holdoff=1 > > -- > > 2.34.1 > >
Re: [PATCH v7 01/24] iommu: Add iommu_ops->identity_domain
On Wed, Aug 23, 2023 at 01:47:15PM -0300, Jason Gunthorpe wrote: > This allows a driver to set a global static to an IDENTITY domain and > the core code will automatically use it whenever an IDENTITY domain > is requested. > > By making it always available it means the IDENTITY can be used in error > handling paths to force the iommu driver into a known state. Devices > implementing global static identity domains should avoid failing their > attach_dev ops. > > To make global static domains simpler allow drivers to omit their free > function and update the iommufd selftest. > > Convert rockchip to use the new mechanism. > > Tested-by: Steven Price > Tested-by: Marek Szyprowski > Tested-by: Nicolin Chen > Reviewed-by: Lu Baolu > Signed-off-by: Jason Gunthorpe Reviewed-by: Jerry Snitselaar
[PATCH 2/3] PCI/AER: Disable AER service on suspend
When the power rail gets cut off, the hardware can create some electric noise on the link that triggers AER. If IRQ is shared between AER with PME, such AER noise will cause a spurious wakeup on system suspend. When the power rail gets back, the firmware of the device resets itself and can create unexpected behavior like sending PTM messages. For this case, the driver will always be too late to toggle off features should be disabled. As Per PCIe Base Spec 5.0, section 5.2, titled "Link State Power Management", TLP and DLLP transmission are disabled for a Link in L2/L3 Ready (D3hot), L2 (D3cold with aux power) and L3 (D3cold) states. So if the power will be turned off during suspend process, disable AER service and re-enable it during the resume process. This should not affect the basic functionality. Link: https://bugzilla.kernel.org/show_bug.cgi?id=209149 Link: https://bugzilla.kernel.org/show_bug.cgi?id=216295 v7: - Wording - Disable AER completely (again) if power will be turned off v6: v5: - Wording. v4: v3: - No change. v2: - Only disable AER IRQ. - No more check on PME IRQ#. - Use helper. Signed-off-by: Kai-Heng Feng --- drivers/pci/pcie/aer.c | 25 + 1 file changed, 25 insertions(+) diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c index f6c24ded134c..b5161bfedd8b 100644 --- a/drivers/pci/pcie/aer.c +++ b/drivers/pci/pcie/aer.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -1340,6 +1341,28 @@ static int aer_probe(struct pcie_device *dev) return 0; } +static int aer_suspend(struct pcie_device *dev) +{ + struct aer_rpc *rpc = get_service_data(dev); + struct pci_dev *pdev = rpc->rpd; + + if (pci_ancestor_pr3_present(pdev) || pm_suspend_via_firmware()) + aer_disable_rootport(rpc); + + return 0; +} + +static int aer_resume(struct pcie_device *dev) +{ + struct aer_rpc *rpc = get_service_data(dev); + struct pci_dev *pdev = rpc->rpd; + + if (pci_ancestor_pr3_present(pdev) || pm_resume_via_firmware()) + aer_enable_rootport(rpc); + + return 0; +} + /** * aer_root_reset - reset Root Port hierarchy, RCEC, or RCiEP * @dev: pointer to Root Port, RCEC, or RCiEP @@ -1411,6 +1434,8 @@ static struct pcie_port_service_driver aerdriver = { .service= PCIE_PORT_SERVICE_AER, .probe = aer_probe, + .suspend= aer_suspend, + .resume = aer_resume, .remove = aer_remove, }; -- 2.34.1
[PATCH 3/3] PCI/DPC: Disable DPC service on suspend
When the power rail gets cut off, the hardware can create some electric noise on the link that triggers AER. If IRQ is shared between AER with PME, such AER noise will cause a spurious wakeup on system suspend. When the power rail gets back, the firmware of the device resets itself and can create unexpected behavior like sending PTM messages. For this case, the driver will always be too late to toggle off features should be disabled. As Per PCIe Base Spec 5.0, section 5.2, titled "Link State Power Management", TLP and DLLP transmission are disabled for a Link in L2/L3 Ready (D3hot), L2 (D3cold with aux power) and L3 (D3cold) states. So if the power will be turned off during suspend process, disable DPC service and re-enable it during the resume process. This should not affect the basic functionality. Since DPC depends on AER to function, also disable DPC. Link: https://bugzilla.kernel.org/show_bug.cgi?id=209149 Link: https://bugzilla.kernel.org/show_bug.cgi?id=216295 v7: - Wording. - Disable DPC completely (again) if power will be turned off v6: v5: - Wording. v4: v3: - No change. v2: - Only disable DPC IRQ. - No more check on PME IRQ#. Signed-off-by: Kai-Heng Feng --- drivers/pci/pcie/dpc.c | 56 ++ 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c index 3ceed8e3de41..73426addb2f1 100644 --- a/drivers/pci/pcie/dpc.c +++ b/drivers/pci/pcie/dpc.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "portdrv.h" #include "../pci.h" @@ -347,13 +348,34 @@ void pci_dpc_init(struct pci_dev *pdev) } } +static void dpc_enable(struct pcie_device *dev) +{ + struct pci_dev *pdev = dev->port; + u16 ctl; + + pci_read_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_CTL, &ctl); + + ctl = (ctl & 0xfff4) | PCI_EXP_DPC_CTL_EN_FATAL | PCI_EXP_DPC_CTL_INT_EN; + pci_write_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_CTL, ctl); +} + +static void dpc_disable(struct pcie_device *dev) +{ + struct pci_dev *pdev = dev->port; + u16 ctl; + + pci_read_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_CTL, &ctl); + ctl &= ~(PCI_EXP_DPC_CTL_EN_FATAL | PCI_EXP_DPC_CTL_INT_EN); + pci_write_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_CTL, ctl); +} + #define FLAG(x, y) (((x) & (y)) ? '+' : '-') static int dpc_probe(struct pcie_device *dev) { struct pci_dev *pdev = dev->port; struct device *device = &dev->device; int status; - u16 ctl, cap; + u16 cap; if (!pcie_aer_is_native(pdev) && !pcie_ports_dpc_native) return -ENOTSUPP; @@ -368,10 +390,7 @@ static int dpc_probe(struct pcie_device *dev) } pci_read_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_CAP, &cap); - pci_read_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_CTL, &ctl); - - ctl = (ctl & 0xfff4) | PCI_EXP_DPC_CTL_EN_FATAL | PCI_EXP_DPC_CTL_INT_EN; - pci_write_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_CTL, ctl); + dpc_enable(dev); pci_info(pdev, "enabled with IRQ %d\n", dev->irq); pci_info(pdev, "error containment capabilities: Int Msg #%d, RPExt%c PoisonedTLP%c SwTrigger%c RP PIO Log %d, DL_ActiveErr%c\n", @@ -384,14 +403,29 @@ static int dpc_probe(struct pcie_device *dev) return status; } -static void dpc_remove(struct pcie_device *dev) +static int dpc_suspend(struct pcie_device *dev) { struct pci_dev *pdev = dev->port; - u16 ctl; - pci_read_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_CTL, &ctl); - ctl &= ~(PCI_EXP_DPC_CTL_EN_FATAL | PCI_EXP_DPC_CTL_INT_EN); - pci_write_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_CTL, ctl); + if (pci_ancestor_pr3_present(pdev) || pm_suspend_via_firmware()) + dpc_disable(dev); + + return 0; +} + +static int dpc_resume(struct pcie_device *dev) +{ + struct pci_dev *pdev = dev->port; + + if (pci_ancestor_pr3_present(pdev) || pm_resume_via_firmware()) + dpc_enable(dev); + + return 0; +} + +static void dpc_remove(struct pcie_device *dev) +{ + dpc_disable(dev); } static struct pcie_port_service_driver dpcdriver = { @@ -399,6 +433,8 @@ static struct pcie_port_service_driver dpcdriver = { .port_type = PCIE_ANY_PORT, .service= PCIE_PORT_SERVICE_DPC, .probe = dpc_probe, + .suspend= dpc_suspend, + .resume = dpc_resume, .remove = dpc_remove, }; -- 2.34.1
Re: [PATCH v3 2/4] arch/loongarch/configs/*_defconfig cleanup
On 8/17/23 19:50, Trevor Woerner wrote: Drop CONFIG_IP_NF_TARGET_CLUSTERIP as it was removed in commit 9db5d918e2c0 ("netfilter: ip_tables: remove clusterip target"). Drop CONFIG_NFT_OBJREF as it was removed in commit d037abc2414b ("netfilter: nft_objref: make it builtin"). Signed-off-by: Trevor Woerner --- arch/loongarch/configs/loongson3_defconfig | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/loongarch/configs/loongson3_defconfig b/arch/loongarch/configs/loongson3_defconfig index d64849b4cba1..4700655b2bcb 100644 --- a/arch/loongarch/configs/loongson3_defconfig +++ b/arch/loongarch/configs/loongson3_defconfig @@ -137,7 +137,6 @@ CONFIG_NFT_MASQ=m CONFIG_NFT_REDIR=m CONFIG_NFT_NAT=m CONFIG_NFT_TUNNEL=m -CONFIG_NFT_OBJREF=m CONFIG_NFT_QUEUE=m CONFIG_NFT_QUOTA=m CONFIG_NFT_REJECT=m @@ -227,7 +226,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_TTL=m CONFIG_IP_NF_RAW=m Acked-by: WANG Xuerui Thanks! -- WANG "xen0n" Xuerui Linux/LoongArch mailing list: https://lore.kernel.org/loongarch/
Re: [PATCH RFC 2/2] powerpc/selftests: add test for papr-vpd
On Tue, 2023-08-22 at 16:33 -0500, Nathan Lynch via B4 Relay wrote: > From: Nathan Lynch Hi Nathan, snowpatch has found a compiler error with this patch. Error: papr_vpd.c:346:33: error: passing argument 2 of 'test_harness' discards 'const' qualifier from pointer target type [-Werror=discarded- qualifiers] if (test_harness(t->function, t->description)) ^ In file included from papr_vpd.c:11:0: /linux/tools/testing/selftests/powerpc/include/utils.h:35:5: note: expected 'char *' but argument is of type 'const char * const' int test_harness(int (test_function)(void), char *name); ^ https://github.com/linuxppc/linux-snowpatch/actions/runs/5960052721/job/16166735476#step:6:1337 https://patchwork.ozlabs.org/project/linuxppc-dev/patch/20230822-papr-sys_rtas-vs-lockdown-v1-2-932623cf3...@linux.ibm.com/ - Russell
[PATCH] powerpc: Hide empty pt_regs at base of the stack
A thread started via eg. user_mode_thread() runs in the kernel to begin with and then may later return to userspace. While it's running in the kernel it has a pt_regs at the base of its kernel stack, but that pt_regs is all zeroes. If the thread oopses in that state, it leads to an ugly stack trace with a big block of zero GPRs, as reported by Joel: Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0) CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.5.0-rc7-4-gf7757129e3de-dirty #3 Hardware name: IBM PowerNV (emulated by qemu) POWER9 0x4e1200 opal:v7.0 PowerNV Call Trace: [c36afb00] [c10dd058] dump_stack_lvl+0x6c/0x9c (unreliable) [c36afb30] [c013c524] panic+0x178/0x424 [c36afbd0] [c2005100] mount_root_generic+0x250/0x324 [c36afca0] [c20057d0] prepare_namespace+0x2d4/0x344 [c36afd20] [c20049c0] kernel_init_freeable+0x358/0x3ac [c36afdf0] [c00111b0] kernel_init+0x30/0x1a0 [c36afe50] [c000debc] ret_from_kernel_user_thread+0x14/0x1c --- interrupt: 0 at 0x0 NIP: LR: CTR: REGS: c36afe80 TRAP: Not tainted (6.5.0-rc7-4-gf7757129e3de-dirty) MSR: <> CR: XER: CFAR: IRQMASK: 0 GPR00: GPR04: GPR08: GPR12: GPR16: GPR20: GPR24: GPR28: NIP [] 0x0 LR [] 0x0 --- interrupt: 0 The all-zero pt_regs looks ugly and conveys no useful information, other than its presence. So detect that case and just show the presence of the frame by printing the interrupt marker, eg: Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0) CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.5.0-rc3-00126-g18e9506562a0-dirty #301 Hardware name: IBM pSeries (emulated by qemu) POWER9 (raw) 0x4e1202 0xf05 of:SLOF,HEAD hv:linux,kvm pSeries Call Trace: [c3aabb00] [c1143db8] dump_stack_lvl+0x6c/0x9c (unreliable) [c3aabb30] [c014c624] panic+0x178/0x424 [c3aabbd0] [c20050fc] mount_root_generic+0x250/0x324 [c3aabca0] [c20057cc] prepare_namespace+0x2d4/0x344 [c3aabd20] [c20049bc] kernel_init_freeable+0x358/0x3ac [c3aabdf0] [c00111b0] kernel_init+0x30/0x1a0 [c3aabe50] [c000debc] ret_from_kernel_user_thread+0x14/0x1c --- interrupt: 0 at 0x0 To avoid ever suppressing a valid pt_regs make sure the pt_regs has a zero MSR and TRAP value, and is located at the very base of the stack. Reported-by: Joel Stanley Reported-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/process.c | 26 +++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index b68898ac07e1..392404688cec 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -2258,6 +2258,22 @@ unsigned long __get_wchan(struct task_struct *p) return ret; } +static bool empty_user_regs(struct pt_regs *regs, struct task_struct *tsk) +{ + unsigned long stack_page; + + // A non-empty pt_regs should never have a zero MSR or TRAP value. + if (regs->msr || regs->trap) + return false; + + // Check it sits at the very base of the stack + stack_page = (unsigned long)task_stack_page(tsk); + if ((unsigned long)(regs + 1) != stack_page + THREAD_SIZE) + return false; + + return true; +} + static int kstack_depth_to_print = CONFIG_PRINT_STACK_DEPTH; void __no_sanitize_address show_stack(struct task_struct *tsk, @@ -2322,9 +2338,13 @@ void __no_sanitize_address show_stack(struct task_struct *tsk, lr = regs->link; printk("%s--- interrupt: %lx at %pS\n", loglvl, regs->trap, (void *)regs->nip); - __show_regs(regs); - printk("%s--- interrupt: %lx\n", - loglvl, regs->trap); + + // Detect the case of an empty pt_regs at the very base + // of the stack and suppress showing it in full. + if (!empty_user_regs(regs, tsk)) { +