Re: [PATCH v2 00/14] Introducing TIF_NOTIFY_IPI flag

2024-06-20 Thread Chen Yu
On 2024-06-19 at 00:03:30 +0530, K Prateek Nayak wrote:
> Hello Chenyu,
> 
> On 6/18/2024 1:19 PM, Chen Yu wrote:
> > [..snip..]
> > > > > > 
> > > > > > > Vincent [5] pointed out a case where the idle load kick will fail 
> > > > > > > to
> > > > > > > run on an idle CPU since the IPI handler launching the ILB will 
> > > > > > > check
> > > > > > > for need_resched(). In such cases, the idle CPU relies on
> > > > > > > newidle_balance() to pull tasks towards itself.
> > > > > > 
> > > > > > Is this the need_resched() in _nohz_idle_balance() ? Should we 
> > > > > > change
> > > > > > this to 'need_resched() && (rq->nr_running || rq->ttwu_pending)' or
> > > > > > something long those lines?
> > > > > 
> > > > > It's not only this but also in do_idle() as well which exits the loop
> > > > > to look for tasks to schedule
> > > > > 
> > > > > > 
> > > > > > I mean, it's fairly trivial to figure out if there really is going 
> > > > > > to be
> > > > > > work there.
> > > > > > 
> > > > > > > Using an alternate flag instead of NEED_RESCHED to indicate a 
> > > > > > > pending
> > > > > > > IPI was suggested as the correct approach to solve this problem 
> > > > > > > on the
> > > > > > > same thread.
> > > > > > 
> > > > > > So adding per-arch changes for this seems like something we 
> > > > > > shouldn't
> > > > > > unless there really is no other sane options.
> > > > > > 
> > > > > > That is, I really think we should start with something like the 
> > > > > > below
> > > > > > and then fix any fallout from that.
> > > > > 
> > > > > The main problem is that need_resched becomes somewhat meaningless
> > > > > because it doesn't  only mean "I need to resched a task" and we have
> > > > > to add more tests around even for those not using polling
> > > > > 
> > > > > > 
> > > > > > diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> > > > > > index 0935f9d4bb7b..cfa45338ae97 100644
> > > > > > --- a/kernel/sched/core.c
> > > > > > +++ b/kernel/sched/core.c
> > > > > > @@ -5799,7 +5800,7 @@ static inline struct task_struct *
> > > > > >__pick_next_task(struct rq *rq, struct task_struct *prev, struct 
> > > > > > rq_flags *rf)
> > > > > >{
> > > > > >   const struct sched_class *class;
> > > > > > -   struct task_struct *p;
> > > > > > +   struct task_struct *p = NULL;
> > > > > > 
> > > > > >   /*
> > > > > >* Optimization: we know that if all tasks are in the 
> > > > > > fair class we can
> > > > > > @@ -5810,9 +5811,11 @@ __pick_next_task(struct rq *rq, struct 
> > > > > > task_struct *prev, struct rq_flags *rf)
> > > > > >   if (likely(!sched_class_above(prev->sched_class, 
> > > > > > &fair_sched_class) &&
> > > > > >  rq->nr_running == rq->cfs.h_nr_running)) {
> > > > > > 
> > > > > > -   p = pick_next_task_fair(rq, prev, rf);
> > > > > > -   if (unlikely(p == RETRY_TASK))
> > > > > > -   goto restart;
> > > > > > +   if (rq->nr_running) {
> > > > > 
> > > > > How do you make the diff between a spurious need_resched() because of
> > > > > polling and a cpu becoming idle ? isn't rq->nr_running null in both
> > > > > cases ?
> > > > > In the later case, we need to call sched_balance_newidle() but not in 
> > > > > the former
> > > > > 
> > > > 
> > > > Not sure if I understand correctly, if the goal of 
> > > > smp_call_function_single() is to
> > > > kick the idle CPU and do not force it to launch the 
> > > > schedule()->sched_balance_newidle(),
> > > > can we set the _TIF_POLLING_NRFLAG rather than _TIF_NEED_RESCHED in 
> > > > set_nr_if_polling()?
> > > > I think writing any value to the monitor address would wakeup the idle 
> > > > CPU. And _TIF_POLLING_NRFLAG
> > > > will be cleared once that idle CPU exit the idle loop, so we don't 
> > > > introduce arch-wide flag.
> > > Although this might work for MWAIT, there is no way for the generic idle
> > > path to know if there is a pending interrupt within a TIF_POLLING_NRFLAG
> > > section. do_idle() sets TIF_POLLING_NRFLAG and relies on a bunch of
> > > need_resched() checks along the way to bail early until finally doing a
> > > current_clr_polling_and_test() before handing off to the cpuidle driver
> > > in call_cpuidle(). I believe this section will necessarily need the sender
> > > to indicate a pending interrupt via TIF_NEED_RESCHED flag to enable the
> > > early bail out before going into the cpuidle driver since this case cannot
> > > be considered the same as a break from MWAIT.
> > > 
> > 
> > I see, this is a good point. So you mean with only TIF_POLLING_NRFLAG there 
> > is
> > possibility that the 'ipi kick CPU out of idle' is lost after the CPU enters
> > do_idle() and before finally entering the idle state. While setting 
> > _TIF_NEED_RESCHED
> > could help the do_idle() loop to detect pending request easier.
> 
> Yup, that is correct.
> 
> > BTW, before the
> > commit b2a02fc43a1f ("smp: Optimize send_call

Re: [PATCH] tools/perf: Handle perftool-testsuite_probe testcases fail when kernel debuginfo is not present

2024-06-20 Thread James Clark



On 18/06/2024 11:44, James Clark wrote:
> 
> 
> On 17/06/2024 17:47, Athira Rajeev wrote:
>>
>>
>>> On 17 Jun 2024, at 8:30 PM, James Clark  wrote:
>>>
>>>
>>>
>>> On 17/06/2024 13:21, Athira Rajeev wrote:
 Running "perftool-testsuite_probe" fails as below:

 ./perf test -v "perftool-testsuite_probe"
 83: perftool-testsuite_probe  : FAILED

 There are three fails:

 1. Regexp not found: "\s*probe:inode_permission(?:_\d+)?\s+\(on 
 inode_permission(?:[:\+][0-9A-Fa-f]+)?@.+\)"
   -- [ FAIL ] -- perf_probe :: test_adding_kernel :: listing added probe 
 :: perf probe -l (output regexp parsing)

>>>
>>> On a machine where NO_DEBUGINFO gets set, this one skips for me. But on
>>> a machine where there _is_ debug info this test still fails.
>>>
>>> But in both cases the probe looks like it was added successfully. So I'm
>>> wondering if this one does need to be skipped, or it's just always
>>> failing? Do you have this test passing anywhere where there is debug info?
>>>
>>> The list command looks like it successfully lists the probe for me in
>>> both cases, it just doesn't have an address on the end:
>>>
>>> perf list 'probe:*'
>>>
>>>   probe:inode_permission (on inode_permission)
>>>
>>> Does the missing address mean anything or is it just not handled
>>> properly by the test?
>>>
>>> Ironically the machine that _does_ pass the debug info test also prints
>>> this, but it looks like it still adds and lists the probe correctly:
>>>
>>>  perf probe -l probe:*
>>>
>>>  Failed to find debug information for address 0x80008047ac30
>>>probe:inode_permission (on inode_permission)
>>
>> Hi James,
>>
>> Thanks for checking this patch.
>>
>> In environment where kernel is compiled with debuginfo:
>>
>> 1) Add probe point
>>
>> # ./perf probe --add inode_permission
>> Added new event:
>>   probe:inode_permission (on inode_permission)
>>
>> You can now use it in all perf tools, such as:
>>
>> perf record -e probe:inode_permission -aR sleep 1
>>
>>
>> 2) Check using perf probe -l
>>
>> # ./perf probe -l
>> probe:inode_permission (on inode_permission:2@fs/namei.c)
>>
>> With debuginfo, the result has additional info.
>>  The test looks for matching pattern 
>> "\s*probe:inode_permission(?:_\d+)?\s+\(on 
>> inode_permission(?:[:\+][0-9A-Fa-f]+)?@.+\)” in result
>> where it is expecting "inode_permission:2@fs/namei.c” . The “@fs/namei.c” 
>> info needs debuginfo here.
>>
> 
> Hi Athira,
> 
> Maybe there is a real bug and this patch is ok to go in and we should leave
> it as failing. Probe -L shows there is debug info available for 
> inode_permission:
> 
>$ ./perf probe -L inode_permission
> 
>   
>   0  int inode_permission(struct mnt_idmap *idmap,
>  struct inode *inode, int mask)
>   ... more source code ...
> 
> But probe -l has an error which could be related to the following
> line not showing the filename details:
> 
>   $ ./perf probe -l
>   
>   Failed to find debug information for address 0x80008047ac30
> probe:inode_permission (on inode_permission)
> 
> I'm running a clang kernel and sometimes I see issues with debug
> info or toolchain stuff, that could be the reason.
> 
>> The function I am using in patch to check for debuginfo 
>> (skip_if_no_debuginfo) is from "tests/shell/lib/probe_vfs_getname.sh"
>>
>> skip_if_no_debuginfo() {
>> add_probe_vfs_getname -v 2>&1 | grep -E -q "^(Failed to find the 
>> path for the kernel|Debuginfo-analysis is not supported)|(file has no debug 
>> information)" && return 2
>> return 1
>> }
>>
>> So the debuginfo test passes in your case since the log has "Failed to find 
>> debug information” which is not present in above grep string. 
>>
> 
> It passes because there is debug info for getname_flags() which is what the
> debug info check looks for. After some greps and seds it ultimately does this
> which succeeds:
> 
>  $ perf probe "vfs_getname=getname_flags:72 pathname=result->name:string"
> 
>  Added new event:
> probe:vfs_getname(on getname_flags:72 with 
> pathname=result->name:string)
> 
> "Failed to find debug information for address" is only ever printed
> with "perf probe -l" when there are probes added. The stderr
> of that command is never piped into any grep anyway, which is why I
> see it on the test output.
> 
> So "probe -L" is working but "probe -l" isn't. Ultimately it looks like a real
> issue and we should leave the failure in.
> 

To avoid confusion, by leave it in I mean this debuginfo patch is ok and
the failure I'm seeing is caused by something else.

Reviewed-by: James Clark 

>> James,
>>
>> Only “perf probe -l” subtest fails with debuginfo enabled or other two 
>> subtests as well? Can you also share result on how other two subtests 
>> behaves ? 
>>
>> 1. Fail 2 :
>>perf probe -nf --max-probes=512 -a 'vfs_* $params’
>>   
>>
>> 2. Fail 3 :
>>   perf probe 'vfs_read 
>> somenonexistingrandomstuffwhichisalsoprettylongorevenlonge

[PATCH 07/10] soc: fsl: cpm1: qmc: Introduce functions to get a channel from a phandle list

2024-06-20 Thread Herve Codina
qmc_chan_get_byphandle() and the resource managed version retrieve a
channel from a simple phandle.

Extend the API and introduce qmc_chan_get_byphandles_index() and the
resource managed version in order to retrieve a channel from a phandle
list using the provided index to identify the phandle in the list.

Also update qmc_chan_get_byphandle() and the resource managed version to
use qmc_chan_get_byphandles_index() and so avoid code duplication.

Signed-off-by: Herve Codina 
---
 drivers/soc/fsl/qe/qmc.c | 19 +++
 include/soc/fsl/qe/qmc.h | 25 ++---
 2 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
index f498db9abe35..e23d60018400 100644
--- a/drivers/soc/fsl/qe/qmc.c
+++ b/drivers/soc/fsl/qe/qmc.c
@@ -1777,13 +1777,15 @@ static struct qmc_chan *qmc_chan_get_from_qmc(struct 
device_node *qmc_np, unsign
return qmc_chan;
 }
 
-struct qmc_chan *qmc_chan_get_byphandle(struct device_node *np, const char 
*phandle_name)
+struct qmc_chan *qmc_chan_get_byphandles_index(struct device_node *np,
+  const char *phandles_name,
+  int index)
 {
struct of_phandle_args out_args;
struct qmc_chan *qmc_chan;
int ret;
 
-   ret = of_parse_phandle_with_fixed_args(np, phandle_name, 1, 0,
+   ret = of_parse_phandle_with_fixed_args(np, phandles_name, 1, index,
   &out_args);
if (ret < 0)
return ERR_PTR(ret);
@@ -1797,7 +1799,7 @@ struct qmc_chan *qmc_chan_get_byphandle(struct 
device_node *np, const char *phan
of_node_put(out_args.np);
return qmc_chan;
 }
-EXPORT_SYMBOL(qmc_chan_get_byphandle);
+EXPORT_SYMBOL(qmc_chan_get_byphandles_index);
 
 struct qmc_chan *qmc_chan_get_bychild(struct device_node *np)
 {
@@ -1827,9 +1829,10 @@ static void devm_qmc_chan_release(struct device *dev, 
void *res)
qmc_chan_put(*qmc_chan);
 }
 
-struct qmc_chan *devm_qmc_chan_get_byphandle(struct device *dev,
-struct device_node *np,
-const char *phandle_name)
+struct qmc_chan *devm_qmc_chan_get_byphandles_index(struct device *dev,
+   struct device_node *np,
+   const char *phandles_name,
+   int index)
 {
struct qmc_chan *qmc_chan;
struct qmc_chan **dr;
@@ -1838,7 +1841,7 @@ struct qmc_chan *devm_qmc_chan_get_byphandle(struct 
device *dev,
if (!dr)
return ERR_PTR(-ENOMEM);
 
-   qmc_chan = qmc_chan_get_byphandle(np, phandle_name);
+   qmc_chan = qmc_chan_get_byphandles_index(np, phandles_name, index);
if (!IS_ERR(qmc_chan)) {
*dr = qmc_chan;
devres_add(dev, dr);
@@ -1848,7 +1851,7 @@ struct qmc_chan *devm_qmc_chan_get_byphandle(struct 
device *dev,
 
return qmc_chan;
 }
-EXPORT_SYMBOL(devm_qmc_chan_get_byphandle);
+EXPORT_SYMBOL(devm_qmc_chan_get_byphandles_index);
 
 struct qmc_chan *devm_qmc_chan_get_bychild(struct device *dev,
   struct device_node *np)
diff --git a/include/soc/fsl/qe/qmc.h b/include/soc/fsl/qe/qmc.h
index 2a333fc1ea81..0fa7205145ce 100644
--- a/include/soc/fsl/qe/qmc.h
+++ b/include/soc/fsl/qe/qmc.h
@@ -16,11 +16,30 @@ struct device_node;
 struct device;
 struct qmc_chan;
 
-struct qmc_chan *qmc_chan_get_byphandle(struct device_node *np, const char 
*phandle_name);
+struct qmc_chan *qmc_chan_get_byphandles_index(struct device_node *np,
+  const char *phandles_name,
+  int index);
+struct qmc_chan *devm_qmc_chan_get_byphandles_index(struct device *dev,
+   struct device_node *np,
+   const char *phandles_name,
+   int index);
+
+static inline struct qmc_chan *qmc_chan_get_byphandle(struct device_node *np,
+ const char *phandle_name)
+{
+   return qmc_chan_get_byphandles_index(np, phandle_name, 0);
+}
+
+static inline struct qmc_chan *devm_qmc_chan_get_byphandle(struct device *dev,
+  struct device_node 
*np,
+  const char 
*phandle_name)
+{
+   return devm_qmc_chan_get_byphandles_index(dev, np, phandle_name, 0);
+}
+
 struct qmc_chan *qmc_chan_get_bychild(struct device_node *np);
 void qmc_chan_put(struct qmc_chan *chan);
-struct qmc_chan *devm_qmc_chan_get_byphandle(struct device *dev, struct 
device_node *np,
-   

[PATCH 06/10] ASoC: fsl: fsl_qmc_audio: Introduce qmc_dai_constraints_interleaved()

2024-06-20 Thread Herve Codina
Constraints are set by qmc_dai_startup(). These constraints are specific
to the interleaved mode.

With the future introduction of support for non-interleaved mode, a new
set of constraints will be set. To make the code clear and keep
qmc_dai_startup() simple, extract the current interleaved mode
constraints settings to a specific function.

Signed-off-by: Herve Codina 
---
 sound/soc/fsl/fsl_qmc_audio.c | 37 +--
 1 file changed, 22 insertions(+), 15 deletions(-)

diff --git a/sound/soc/fsl/fsl_qmc_audio.c b/sound/soc/fsl/fsl_qmc_audio.c
index 36145f1ddbf1..f70c6c8eec4a 100644
--- a/sound/soc/fsl/fsl_qmc_audio.c
+++ b/sound/soc/fsl/fsl_qmc_audio.c
@@ -436,24 +436,14 @@ static int 
qmc_dai_hw_rule_capture_format_by_channels(struct snd_pcm_hw_params *
return qmc_dai_hw_rule_format_by_channels(qmc_dai, params, 
qmc_dai->nb_rx_ts);
 }
 
-static int qmc_dai_startup(struct snd_pcm_substream *substream,
-  struct snd_soc_dai *dai)
+static int qmc_dai_constraints_interleaved(struct snd_pcm_substream *substream,
+  struct qmc_dai *qmc_dai)
 {
-   struct qmc_dai_prtd *prtd = substream->runtime->private_data;
snd_pcm_hw_rule_func_t hw_rule_channels_by_format;
snd_pcm_hw_rule_func_t hw_rule_format_by_channels;
-   struct qmc_dai *qmc_dai;
unsigned int frame_bits;
int ret;
 
-   qmc_dai = qmc_dai_get_data(dai);
-   if (!qmc_dai) {
-   dev_err(dai->dev, "Invalid dai\n");
-   return -EINVAL;
-   }
-
-   prtd->qmc_dai = qmc_dai;
-
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
hw_rule_channels_by_format = 
qmc_dai_hw_rule_capture_channels_by_format;
hw_rule_format_by_channels = 
qmc_dai_hw_rule_capture_format_by_channels;
@@ -468,7 +458,7 @@ static int qmc_dai_startup(struct snd_pcm_substream 
*substream,
  hw_rule_channels_by_format, qmc_dai,
  SNDRV_PCM_HW_PARAM_FORMAT, -1);
if (ret) {
-   dev_err(dai->dev, "Failed to add channels rule (%d)\n", ret);
+   dev_err(qmc_dai->dev, "Failed to add channels rule (%d)\n", 
ret);
return ret;
}
 
@@ -476,7 +466,7 @@ static int qmc_dai_startup(struct snd_pcm_substream 
*substream,
  hw_rule_format_by_channels, qmc_dai,
  SNDRV_PCM_HW_PARAM_CHANNELS, -1);
if (ret) {
-   dev_err(dai->dev, "Failed to add format rule (%d)\n", ret);
+   dev_err(qmc_dai->dev, "Failed to add format rule (%d)\n", ret);
return ret;
}
 
@@ -484,13 +474,30 @@ static int qmc_dai_startup(struct snd_pcm_substream 
*substream,
   SNDRV_PCM_HW_PARAM_FRAME_BITS,
   frame_bits);
if (ret < 0) {
-   dev_err(dai->dev, "Failed to add frame_bits constraint (%d)\n", 
ret);
+   dev_err(qmc_dai->dev, "Failed to add frame_bits constraint 
(%d)\n", ret);
return ret;
}
 
return 0;
 }
 
+static int qmc_dai_startup(struct snd_pcm_substream *substream,
+  struct snd_soc_dai *dai)
+{
+   struct qmc_dai_prtd *prtd = substream->runtime->private_data;
+   struct qmc_dai *qmc_dai;
+
+   qmc_dai = qmc_dai_get_data(dai);
+   if (!qmc_dai) {
+   dev_err(dai->dev, "Invalid dai\n");
+   return -EINVAL;
+   }
+
+   prtd->qmc_dai = qmc_dai;
+
+   return qmc_dai_constraints_interleaved(substream, qmc_dai);
+}
+
 static int qmc_dai_hw_params(struct snd_pcm_substream *substream,
 struct snd_pcm_hw_params *params,
 struct snd_soc_dai *dai)
-- 
2.45.0



[PATCH 08/10] soc: fsl: cpm1: qmc: Introduce qmc_chan_count_phandles()

2024-06-20 Thread Herve Codina
No function in the QMC API is available to get the number of phandles
present in a phandle list.

Fill this lack introducing qmc_chan_count_phandles().

Signed-off-by: Herve Codina 
---
 drivers/soc/fsl/qe/qmc.c | 13 +
 include/soc/fsl/qe/qmc.h |  2 ++
 2 files changed, 15 insertions(+)

diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
index e23d60018400..76bb496305a0 100644
--- a/drivers/soc/fsl/qe/qmc.c
+++ b/drivers/soc/fsl/qe/qmc.c
@@ -1777,6 +1777,19 @@ static struct qmc_chan *qmc_chan_get_from_qmc(struct 
device_node *qmc_np, unsign
return qmc_chan;
 }
 
+int qmc_chan_count_phandles(struct device_node *np, const char *phandles_name)
+{
+   int count;
+
+   /* phandles are fixed args phandles with one arg */
+   count = of_count_phandle_with_args(np, phandles_name, NULL);
+   if (count < 0)
+   return count;
+
+   return count / 2;
+}
+EXPORT_SYMBOL(qmc_chan_count_phandles);
+
 struct qmc_chan *qmc_chan_get_byphandles_index(struct device_node *np,
   const char *phandles_name,
   int index)
diff --git a/include/soc/fsl/qe/qmc.h b/include/soc/fsl/qe/qmc.h
index 0fa7205145ce..294e42ea8d4c 100644
--- a/include/soc/fsl/qe/qmc.h
+++ b/include/soc/fsl/qe/qmc.h
@@ -16,6 +16,8 @@ struct device_node;
 struct device;
 struct qmc_chan;
 
+int qmc_chan_count_phandles(struct device_node *np, const char *phandles_name);
+
 struct qmc_chan *qmc_chan_get_byphandles_index(struct device_node *np,
   const char *phandles_name,
   int index);
-- 
2.45.0



[PATCH 02/10] ASoC: fsl: fsl_qmc_audio: Fix issues detected by checkpatch

2024-06-20 Thread Herve Codina
./scripts/checkpatch.pl --strict --codespell detected several issues
when running on the fsl_qmc_audio.c file:
  - CHECK: spaces preferred around that '*' (ctx:VxV)
  - CHECK: Alignment should match open parenthesis
  - CHECK: Comparison to NULL could be written "!prtd"
  - CHECK: spaces preferred around that '/' (ctx:VxV)
  - CHECK: Lines should not end with a '('
  - CHECK: Please don't use multiple blank lines
Some of them are present several times.

Fix all of these issues without any functional changes.

Signed-off-by: Herve Codina 
---
 sound/soc/fsl/fsl_qmc_audio.c | 65 +--
 1 file changed, 31 insertions(+), 34 deletions(-)

diff --git a/sound/soc/fsl/fsl_qmc_audio.c b/sound/soc/fsl/fsl_qmc_audio.c
index dd90ef16fa97..917a32389f3d 100644
--- a/sound/soc/fsl/fsl_qmc_audio.c
+++ b/sound/soc/fsl/fsl_qmc_audio.c
@@ -54,7 +54,7 @@ static int qmc_audio_pcm_construct(struct snd_soc_component 
*component,
return ret;
 
snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, card->dev,
-  64*1024, 64*1024);
+  64 * 1024, 64 * 1024);
return 0;
 }
 
@@ -89,8 +89,8 @@ static void qmc_audio_pcm_write_complete(void *context)
prtd->period_ptr_submitted = prtd->dma_buffer_start;
 
ret = qmc_chan_write_submit(prtd->qmc_dai->qmc_chan,
-   prtd->period_ptr_submitted, prtd->period_size,
-   qmc_audio_pcm_write_complete, prtd);
+   prtd->period_ptr_submitted, 
prtd->period_size,
+   qmc_audio_pcm_write_complete, prtd);
if (ret) {
dev_err(prtd->qmc_dai->dev, "write_submit failed %d\n",
ret);
@@ -118,8 +118,8 @@ static void qmc_audio_pcm_read_complete(void *context, 
size_t length, unsigned i
prtd->period_ptr_submitted = prtd->dma_buffer_start;
 
ret = qmc_chan_read_submit(prtd->qmc_dai->qmc_chan,
-   prtd->period_ptr_submitted, prtd->period_size,
-   qmc_audio_pcm_read_complete, prtd);
+  prtd->period_ptr_submitted, 
prtd->period_size,
+  qmc_audio_pcm_read_complete, prtd);
if (ret) {
dev_err(prtd->qmc_dai->dev, "read_submit failed %d\n",
ret);
@@ -144,8 +144,8 @@ static int qmc_audio_pcm_trigger(struct snd_soc_component 
*component,
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
/* Submit first chunk ... */
ret = qmc_chan_write_submit(prtd->qmc_dai->qmc_chan,
-   prtd->period_ptr_submitted, prtd->period_size,
-   qmc_audio_pcm_write_complete, prtd);
+   prtd->period_ptr_submitted, 
prtd->period_size,
+   
qmc_audio_pcm_write_complete, prtd);
if (ret) {
dev_err(component->dev, "write_submit failed 
%d\n",
ret);
@@ -159,8 +159,8 @@ static int qmc_audio_pcm_trigger(struct snd_soc_component 
*component,
 
/* ... and send it */
ret = qmc_chan_write_submit(prtd->qmc_dai->qmc_chan,
-   prtd->period_ptr_submitted, prtd->period_size,
-   qmc_audio_pcm_write_complete, prtd);
+   prtd->period_ptr_submitted, 
prtd->period_size,
+   
qmc_audio_pcm_write_complete, prtd);
if (ret) {
dev_err(component->dev, "write_submit failed 
%d\n",
ret);
@@ -169,8 +169,8 @@ static int qmc_audio_pcm_trigger(struct snd_soc_component 
*component,
} else {
/* Submit first chunk ... */
ret = qmc_chan_read_submit(prtd->qmc_dai->qmc_chan,
-   prtd->period_ptr_submitted, prtd->period_size,
-   qmc_audio_pcm_read_complete, prtd);
+  prtd->period_ptr_submitted, 
prtd->period_size,
+  qmc_audio_pcm_read_complete, 
prtd);
if (ret) {
dev_err(component->dev, "read_submit failed 
%d\n",
ret);
@@ -184,8 +184,8 @@ static int qmc_audio_pcm_trigger(struct snd_soc_component 
*component,
 
/* ... and send it */
ret = qmc_chan_read_submit(prtd->qmc_dai->qmc_chan,
-   prtd->period_ptr_submitted, prtd->period_size,
-

[PATCH 00/10] Add support for non-interleaved mode in qmc_audio

2024-06-20 Thread Herve Codina
The qmc_audio driver supports only audio in interleaved mode.
Non-interleaved mode can be easily supported using several QMC channel
per DAI. In that case, data related to ch0 are sent to (received from)
the first QMC channel, data related to ch1 use the next QMC channel and
so on up to the last channel.

In terms of constraints and settings, the interleaved and
non-interleaved modes are slightly different.

In interleaved mode:
  - The sample size should fit in the number of time-slots available for
the QMC channel.
  - The number of audio channels should fit in the number of time-slots
(taking into account the sample size) available for the QMC channel.

In non-interleaved mode:
  - The number of audio channels is the number of available QMC
channels.
  - Each QMC channel should have the same number of time-slots.
  - The sample size equals the number of time-slots of one QMC channel.

This series add support for the non-interleaved mode in the qmc_audio
driver and is composed of the following parts:
  - Patches 1 and 2: Fix some issues in the qmc_audio
  - Patches 3 to 6: Prepare qmc_audio for the non-interleaved mode
  - Patches 7 and 8: Extend the QMC driver API
  - Patches 9 and 10: The support for non-interleaved mode itself

Best regards,
Hervé

Herve Codina (10):
  ASoC: fsl: fsl_qmc_audio: Check devm_kasprintf() returned value
  ASoC: fsl: fsl_qmc_audio: Fix issues detected by checkpatch
  ASoC: fsl: fsl_qmc_audio: Split channel buffer and PCM pointer
handling
  ASoC: fsl: fsl_qmc_audio: Identify the QMC channel involved in
completion routines
  ASoC: fsl: fsl_qmc_audio: Introduce
qmc_audio_pcm_{read,write}_submit()
  ASoC: fsl: fsl_qmc_audio: Introduce qmc_dai_constraints_interleaved()
  soc: fsl: cpm1: qmc: Introduce functions to get a channel from a
phandle list
  soc: fsl: cpm1: qmc: Introduce qmc_chan_count_phandles()
  dt-bindings: sound: fsl,qmc-audio: Add support for multiple QMC
channels per DAI
  ASoC: fsl: fsl_qmc_audio: Add support for non-interleaved mode.

 .../bindings/sound/fsl,qmc-audio.yaml |  41 +-
 drivers/soc/fsl/qe/qmc.c  |  32 +-
 include/soc/fsl/qe/qmc.h  |  27 +-
 sound/soc/fsl/fsl_qmc_audio.c | 590 +-
 4 files changed, 505 insertions(+), 185 deletions(-)

-- 
2.45.0



[PATCH 10/10] ASoC: fsl: fsl_qmc_audio: Add support for non-interleaved mode.

2024-06-20 Thread Herve Codina
The current fsl_qmc_audio works in interleaved mode. The audio samples
are interleaved and all data are sent to (received from) one QMC
channel.

Using several QMC channels, non interleaved mode can be easily
supported. In that case, data related to ch0 are sent to (received from)
the first QMC channel, data related to ch1 use the next QMC channel and
so on up to the last channel.

In terms of constraints and settings, the two modes are slightly
different:
- Interleaved mode:
- The sample size should fit in the number of time-slots available
  for the QMC channel.
- The number of audio channels should fit in the number of
  time-slots (taking into account the sample size) available for the
  QMC channel.
- Non-interleaved mode:
- The number of audio channels is the number of available QMC
  channels.
- Each QMC channel should have the same number of time-slots.
- The sample size equals the number of time-slots of one QMC
  channel.

Add support for the non-interleaved mode allowing multiple QMC channel
per DAI. The DAI switches in non-interleaved mode when more that one QMC
channel is available.

Signed-off-by: Herve Codina 
---
 sound/soc/fsl/fsl_qmc_audio.c | 371 +++---
 1 file changed, 296 insertions(+), 75 deletions(-)

diff --git a/sound/soc/fsl/fsl_qmc_audio.c b/sound/soc/fsl/fsl_qmc_audio.c
index f70c6c8eec4a..1560731c8372 100644
--- a/sound/soc/fsl/fsl_qmc_audio.c
+++ b/sound/soc/fsl/fsl_qmc_audio.c
@@ -29,7 +29,11 @@ struct qmc_dai {
struct device *dev;
unsigned int nb_tx_ts;
unsigned int nb_rx_ts;
-   struct qmc_dai_chan chan;
+
+   unsigned int nb_chans_avail;
+   unsigned int nb_chans_used_tx;
+   unsigned int nb_chans_used_rx;
+   struct qmc_dai_chan *chans;
 };
 
 struct qmc_audio {
@@ -50,7 +54,10 @@ struct qmc_dai_prtd {
dma_addr_t ch_dma_addr_current;
dma_addr_t ch_dma_addr_end;
size_t ch_dma_size;
+   size_t ch_dma_offset;
 
+   unsigned int channels;
+   DECLARE_BITMAP(chans_pending, 64);
struct snd_pcm_substream *substream;
 };
 
@@ -69,6 +76,17 @@ static int qmc_audio_pcm_construct(struct snd_soc_component 
*component,
return 0;
 }
 
+static bool qmc_audio_access_is_interleaved(snd_pcm_access_t access)
+{
+   switch (access) {
+   case SNDRV_PCM_ACCESS_MMAP_INTERLEAVED:
+   case SNDRV_PCM_ACCESS_RW_INTERLEAVED:
+   return true;
+   default:
+   return false;
+   }
+};
+
 static int qmc_audio_pcm_hw_params(struct snd_soc_component *component,
   struct snd_pcm_substream *substream,
   struct snd_pcm_hw_params *params)
@@ -76,6 +94,14 @@ static int qmc_audio_pcm_hw_params(struct snd_soc_component 
*component,
struct snd_pcm_runtime *runtime = substream->runtime;
struct qmc_dai_prtd *prtd = substream->runtime->private_data;
 
+   /*
+* In interleaved mode, the driver uses one QMC channel for all audio
+* channels whereas in non-interleaved mode, it uses one QMC channel per
+* audio channel.
+*/
+   prtd->channels = qmc_audio_access_is_interleaved(params_access(params)) 
?
+   1 : params_channels(params);
+
prtd->substream = substream;
 
prtd->buffer_ended = 0;
@@ -83,9 +109,10 @@ static int qmc_audio_pcm_hw_params(struct snd_soc_component 
*component,
prtd->period_size = params_period_size(params);
 
prtd->ch_dma_addr_start = runtime->dma_addr;
-   prtd->ch_dma_addr_end = runtime->dma_addr + params_buffer_bytes(params);
+   prtd->ch_dma_offset = params_buffer_bytes(params) / prtd->channels;
+   prtd->ch_dma_addr_end = runtime->dma_addr + prtd->ch_dma_offset;
prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
-   prtd->ch_dma_size = params_period_bytes(params);
+   prtd->ch_dma_size = params_period_bytes(params) / prtd->channels;
 
return 0;
 }
@@ -94,16 +121,23 @@ static void qmc_audio_pcm_write_complete(void *context);
 
 static int qmc_audio_pcm_write_submit(struct qmc_dai_prtd *prtd)
 {
+   unsigned int i;
int ret;
 
-   ret = qmc_chan_write_submit(prtd->qmc_dai->chan.qmc_chan,
-   prtd->ch_dma_addr_current, 
prtd->ch_dma_size,
-   qmc_audio_pcm_write_complete,
-   &prtd->qmc_dai->chan);
-   if (ret) {
-   dev_err(prtd->qmc_dai->dev, "write_submit failed %d\n",
-   ret);
-   return ret;
+   for (i = 0; i < prtd->channels; i++) {
+   bitmap_set(prtd->chans_pending, i, 1);
+
+   ret = qmc_chan_write_submit(prtd->qmc_dai->chans[i].qmc_chan,
+   prtd->ch_dma_addr_current + i * 
prtd->ch_dma_offset,
+   prtd->

[PATCH 01/10] ASoC: fsl: fsl_qmc_audio: Check devm_kasprintf() returned value

2024-06-20 Thread Herve Codina
devm_kasprintf() can return a NULL pointer on failure but this returned
value is not checked.

Fix this lack and check the returned value.

Fixes: 075c7125b11c ("ASoC: fsl: Add support for QMC audio")
Cc: sta...@vger.kernel.org
Signed-off-by: Herve Codina 
---
 sound/soc/fsl/fsl_qmc_audio.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sound/soc/fsl/fsl_qmc_audio.c b/sound/soc/fsl/fsl_qmc_audio.c
index bfaaa451735b..dd90ef16fa97 100644
--- a/sound/soc/fsl/fsl_qmc_audio.c
+++ b/sound/soc/fsl/fsl_qmc_audio.c
@@ -604,6 +604,8 @@ static int qmc_audio_dai_parse(struct qmc_audio *qmc_audio, 
struct device_node *
 
qmc_dai->name = devm_kasprintf(qmc_audio->dev, GFP_KERNEL, "%s.%d",
   np->parent->name, qmc_dai->id);
+   if (!qmc_dai->name)
+   return -ENOMEM;
 
qmc_dai->qmc_chan = devm_qmc_chan_get_byphandle(qmc_audio->dev, np,
"fsl,qmc-chan");
-- 
2.45.0



[PATCH 04/10] ASoC: fsl: fsl_qmc_audio: Identify the QMC channel involved in completion routines

2024-06-20 Thread Herve Codina
The current QMC audio driver uses only one QMC channel per DAI. The
context used by QMC channel transfer (read and write) completion
routines does not contains any QMC channel and the only one available
per DAI is used to schedule the next transfer.
This works pretty well with only one QMC channel per DAI.

The future support for non-inlerleave mode will use several QMC channel
per DAI. In that case, QMC channel transfer completion routines need to
identify the QMC channel related to the completion.

In order to fill this lack, even if identifying the current QMC channel
among several QMC channels is not needed for the current code, add one
indirection level and introduce the qmc_dai_chan data structrure.
This structure contains the QMC channel involved in the completion and
refererences to the runtime context (capture and playback) used by the
DAI.

Signed-off-by: Herve Codina 
---
 sound/soc/fsl/fsl_qmc_audio.c | 72 +++
 1 file changed, 47 insertions(+), 25 deletions(-)

diff --git a/sound/soc/fsl/fsl_qmc_audio.c b/sound/soc/fsl/fsl_qmc_audio.c
index e8281e548746..b07770257bad 100644
--- a/sound/soc/fsl/fsl_qmc_audio.c
+++ b/sound/soc/fsl/fsl_qmc_audio.c
@@ -17,13 +17,19 @@
 #include 
 #include 
 
+struct qmc_dai_chan {
+   struct qmc_dai_prtd *prtd_tx;
+   struct qmc_dai_prtd *prtd_rx;
+   struct qmc_chan *qmc_chan;
+};
+
 struct qmc_dai {
char *name;
int id;
struct device *dev;
-   struct qmc_chan *qmc_chan;
unsigned int nb_tx_ts;
unsigned int nb_rx_ts;
+   struct qmc_dai_chan chan;
 };
 
 struct qmc_audio {
@@ -86,9 +92,12 @@ static int qmc_audio_pcm_hw_params(struct snd_soc_component 
*component,
 
 static void qmc_audio_pcm_write_complete(void *context)
 {
-   struct qmc_dai_prtd *prtd = context;
+   struct qmc_dai_chan *chan = context;
+   struct qmc_dai_prtd *prtd;
int ret;
 
+   prtd = chan->prtd_tx;
+
prtd->buffer_ended += prtd->period_size;
if (prtd->buffer_ended >= prtd->buffer_size)
prtd->buffer_ended = 0;
@@ -97,9 +106,10 @@ static void qmc_audio_pcm_write_complete(void *context)
if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end)
prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
 
-   ret = qmc_chan_write_submit(prtd->qmc_dai->qmc_chan,
+   ret = qmc_chan_write_submit(prtd->qmc_dai->chan.qmc_chan,
prtd->ch_dma_addr_current, 
prtd->ch_dma_size,
-   qmc_audio_pcm_write_complete, prtd);
+   qmc_audio_pcm_write_complete,
+   &prtd->qmc_dai->chan);
if (ret) {
dev_err(prtd->qmc_dai->dev, "write_submit failed %d\n",
ret);
@@ -110,9 +120,12 @@ static void qmc_audio_pcm_write_complete(void *context)
 
 static void qmc_audio_pcm_read_complete(void *context, size_t length, unsigned 
int flags)
 {
-   struct qmc_dai_prtd *prtd = context;
+   struct qmc_dai_chan *chan = context;
+   struct qmc_dai_prtd *prtd;
int ret;
 
+   prtd = chan->prtd_rx;
+
if (length != prtd->ch_dma_size) {
dev_err(prtd->qmc_dai->dev, "read complete length = %zu, exp 
%zu\n",
length, prtd->ch_dma_size);
@@ -126,9 +139,10 @@ static void qmc_audio_pcm_read_complete(void *context, 
size_t length, unsigned i
if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end)
prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
 
-   ret = qmc_chan_read_submit(prtd->qmc_dai->qmc_chan,
+   ret = qmc_chan_read_submit(prtd->qmc_dai->chan.qmc_chan,
   prtd->ch_dma_addr_current, prtd->ch_dma_size,
-  qmc_audio_pcm_read_complete, prtd);
+  qmc_audio_pcm_read_complete,
+  &prtd->qmc_dai->chan);
if (ret) {
dev_err(prtd->qmc_dai->dev, "read_submit failed %d\n",
ret);
@@ -151,10 +165,13 @@ static int qmc_audio_pcm_trigger(struct snd_soc_component 
*component,
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+   prtd->qmc_dai->chan.prtd_tx = prtd;
+
/* Submit first chunk ... */
-   ret = qmc_chan_write_submit(prtd->qmc_dai->qmc_chan,
+   ret = 
qmc_chan_write_submit(prtd->qmc_dai->chan.qmc_chan,
prtd->ch_dma_addr_current, 
prtd->ch_dma_size,
-   
qmc_audio_pcm_write_complete, prtd);
+   
qmc_audio_pcm_write_complete,
+   &prtd->qmc_dai->chan);
   

[PATCH 09/10] dt-bindings: sound: fsl,qmc-audio: Add support for multiple QMC channels per DAI

2024-06-20 Thread Herve Codina
The QMC audio uses one QMC channel per DAI and uses this QMC channel to
transmit interleaved audio channel samples.

In order to work in non-interleave mode, a QMC audio DAI needs to use
multiple QMC channels. In that case, the DAI maps each QMC channel to
exactly one audio channel.

Allow QMC audio DAIs with multiple QMC channels attached.

Signed-off-by: Herve Codina 
---
 .../bindings/sound/fsl,qmc-audio.yaml | 41 ---
 1 file changed, 35 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/fsl,qmc-audio.yaml 
b/Documentation/devicetree/bindings/sound/fsl,qmc-audio.yaml
index b522ed7dcc51..a23e49198c37 100644
--- a/Documentation/devicetree/bindings/sound/fsl,qmc-audio.yaml
+++ b/Documentation/devicetree/bindings/sound/fsl,qmc-audio.yaml
@@ -12,7 +12,9 @@ maintainers:
 description: |
   The QMC audio is an ASoC component which uses QMC (QUICC Multichannel
   Controller) channels to transfer the audio data.
-  It provides as many DAI as the number of QMC channel used.
+  It provides several DAIs. For each DAI, the DAI is working in interleaved 
mode
+  if only one QMC channel is used by the DAI or it is working in 
non-interleaved
+  mode if several QMC channels are used by the DAI.
 
 allOf:
   - $ref: dai-common.yaml#
@@ -45,12 +47,19 @@ patternProperties:
   fsl,qmc-chan:
 $ref: /schemas/types.yaml#/definitions/phandle-array
 items:
-  - items:
-  - description: phandle to QMC node
-  - description: Channel number
+  items:
+- description: phandle to QMC node
+- description: Channel number
+minItems: 1
 description:
-  Should be a phandle/number pair. The phandle to QMC node and the QMC
-  channel to use for this DAI.
+  Should be a phandle/number pair list. The list of phandle to QMC node
+  and the QMC channel pair to use for this DAI.
+  If only one phandle/number pair is provided, this DAI works in
+  interleaved mode, i.e. audio channels for this DAI are interleaved in
+  the QMC channel. If more than one pair is provided, this DAI works
+  in non-interleave mode. In that case the first audio channel uses the
+  the first QMC channel, the second audio channel uses the second QMC
+  channel, etc...
 
 required:
   - reg
@@ -79,6 +88,11 @@ examples:
 reg = <17>;
 fsl,qmc-chan = <&qmc 17>;
 };
+dai@18 {
+reg = <18>;
+/* Non-interleaved mode */
+fsl,qmc-chan = <&qmc 18>, <&qmc 19>;
+};
 };
 
 sound {
@@ -115,4 +129,19 @@ examples:
 dai-tdm-slot-rx-mask = <0 0 1 0 1 0 1 0 1>;
 };
 };
+simple-audio-card,dai-link@2 {
+reg = <2>;
+format = "dsp_b";
+cpu {
+sound-dai = <&audio_controller 18>;
+};
+codec {
+sound-dai = <&codec3>;
+dai-tdm-slot-num = <2>;
+dai-tdm-slot-width = <8>;
+/* TS 9, 10 */
+dai-tdm-slot-tx-mask = <0 0 0 0 0 0 0 0 0 1 1>;
+dai-tdm-slot-rx-mask = <0 0 0 0 0 0 0 0 0 1 1>;
+};
+};
 };
-- 
2.45.0



[PATCH 05/10] ASoC: fsl: fsl_qmc_audio: Introduce qmc_audio_pcm_{read,write}_submit()

2024-06-20 Thread Herve Codina
Submitting data to QMC channels is done in several places: transfer
completions and DAI start. The operation done is simple and consist in
one function call.

With the future introduction of support for non-interleaved mode,
submitting data will be more complex.

To avoid copy/paste of code in several places, introduce
qmc_audio_pcm_{read,write}_submit() whose goal is to handle this
data submission.

Signed-off-by: Herve Codina 
---
 sound/soc/fsl/fsl_qmc_audio.c | 93 +--
 1 file changed, 45 insertions(+), 48 deletions(-)

diff --git a/sound/soc/fsl/fsl_qmc_audio.c b/sound/soc/fsl/fsl_qmc_audio.c
index b07770257bad..36145f1ddbf1 100644
--- a/sound/soc/fsl/fsl_qmc_audio.c
+++ b/sound/soc/fsl/fsl_qmc_audio.c
@@ -90,11 +90,29 @@ static int qmc_audio_pcm_hw_params(struct snd_soc_component 
*component,
return 0;
 }
 
+static void qmc_audio_pcm_write_complete(void *context);
+
+static int qmc_audio_pcm_write_submit(struct qmc_dai_prtd *prtd)
+{
+   int ret;
+
+   ret = qmc_chan_write_submit(prtd->qmc_dai->chan.qmc_chan,
+   prtd->ch_dma_addr_current, 
prtd->ch_dma_size,
+   qmc_audio_pcm_write_complete,
+   &prtd->qmc_dai->chan);
+   if (ret) {
+   dev_err(prtd->qmc_dai->dev, "write_submit failed %d\n",
+   ret);
+   return ret;
+   }
+
+   return 0;
+}
+
 static void qmc_audio_pcm_write_complete(void *context)
 {
struct qmc_dai_chan *chan = context;
struct qmc_dai_prtd *prtd;
-   int ret;
 
prtd = chan->prtd_tx;
 
@@ -106,23 +124,33 @@ static void qmc_audio_pcm_write_complete(void *context)
if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end)
prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
 
-   ret = qmc_chan_write_submit(prtd->qmc_dai->chan.qmc_chan,
-   prtd->ch_dma_addr_current, 
prtd->ch_dma_size,
-   qmc_audio_pcm_write_complete,
-   &prtd->qmc_dai->chan);
+   qmc_audio_pcm_write_submit(prtd);
+
+   snd_pcm_period_elapsed(prtd->substream);
+}
+
+static void qmc_audio_pcm_read_complete(void *context, size_t length, unsigned 
int flags);
+
+static int qmc_audio_pcm_read_submit(struct qmc_dai_prtd *prtd)
+{
+   int ret;
+
+   ret = qmc_chan_read_submit(prtd->qmc_dai->chan.qmc_chan,
+  prtd->ch_dma_addr_current, prtd->ch_dma_size,
+  qmc_audio_pcm_read_complete,
+  &prtd->qmc_dai->chan);
if (ret) {
-   dev_err(prtd->qmc_dai->dev, "write_submit failed %d\n",
+   dev_err(prtd->qmc_dai->dev, "read_submit failed %d\n",
ret);
}
 
-   snd_pcm_period_elapsed(prtd->substream);
+   return 0;
 }
 
 static void qmc_audio_pcm_read_complete(void *context, size_t length, unsigned 
int flags)
 {
struct qmc_dai_chan *chan = context;
struct qmc_dai_prtd *prtd;
-   int ret;
 
prtd = chan->prtd_rx;
 
@@ -139,14 +167,7 @@ static void qmc_audio_pcm_read_complete(void *context, 
size_t length, unsigned i
if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end)
prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
 
-   ret = qmc_chan_read_submit(prtd->qmc_dai->chan.qmc_chan,
-  prtd->ch_dma_addr_current, prtd->ch_dma_size,
-  qmc_audio_pcm_read_complete,
-  &prtd->qmc_dai->chan);
-   if (ret) {
-   dev_err(prtd->qmc_dai->dev, "read_submit failed %d\n",
-   ret);
-   }
+   qmc_audio_pcm_read_submit(prtd);
 
snd_pcm_period_elapsed(prtd->substream);
 }
@@ -168,15 +189,9 @@ static int qmc_audio_pcm_trigger(struct snd_soc_component 
*component,
prtd->qmc_dai->chan.prtd_tx = prtd;
 
/* Submit first chunk ... */
-   ret = 
qmc_chan_write_submit(prtd->qmc_dai->chan.qmc_chan,
-   prtd->ch_dma_addr_current, 
prtd->ch_dma_size,
-   
qmc_audio_pcm_write_complete,
-   &prtd->qmc_dai->chan);
-   if (ret) {
-   dev_err(component->dev, "write_submit failed 
%d\n",
-   ret);
+   ret = qmc_audio_pcm_write_submit(prtd);
+   if (ret)
return ret;
-   }
 
/* ... prepare next one ... */
prtd->ch_dma_addr_current += prtd->ch_dma_size;
@@ -184,28 +199,16 @@ static int qmc_audio_pcm_trigger(struct

[PATCH 03/10] ASoC: fsl: fsl_qmc_audio: Split channel buffer and PCM pointer handling

2024-06-20 Thread Herve Codina
The driver mixes some internal values for channel DMA buffer handling
and PCM pointer handling. In the currently supported interleaved mode,
this mix does not lead to any issues but in order to prepare the
support for the non-interleaved mode, having them clearly separated will
ease the support and avoid additional computation to convert values used
in channel DMA buffer management in values usable for PCM pointer.

Use a specific set of variable for PCM pointer handling and an other set
for channel DMA buffer.

Signed-off-by: Herve Codina 
---
 sound/soc/fsl/fsl_qmc_audio.c | 84 +++
 1 file changed, 46 insertions(+), 38 deletions(-)

diff --git a/sound/soc/fsl/fsl_qmc_audio.c b/sound/soc/fsl/fsl_qmc_audio.c
index 917a32389f3d..e8281e548746 100644
--- a/sound/soc/fsl/fsl_qmc_audio.c
+++ b/sound/soc/fsl/fsl_qmc_audio.c
@@ -35,11 +35,16 @@ struct qmc_audio {
 
 struct qmc_dai_prtd {
struct qmc_dai *qmc_dai;
-   dma_addr_t dma_buffer_start;
-   dma_addr_t period_ptr_submitted;
-   dma_addr_t period_ptr_ended;
-   dma_addr_t dma_buffer_end;
-   size_t period_size;
+
+   snd_pcm_uframes_t buffer_ended;
+   snd_pcm_uframes_t buffer_size;
+   snd_pcm_uframes_t period_size;
+
+   dma_addr_t ch_dma_addr_start;
+   dma_addr_t ch_dma_addr_current;
+   dma_addr_t ch_dma_addr_end;
+   size_t ch_dma_size;
+
struct snd_pcm_substream *substream;
 };
 
@@ -65,13 +70,17 @@ static int qmc_audio_pcm_hw_params(struct snd_soc_component 
*component,
struct snd_pcm_runtime *runtime = substream->runtime;
struct qmc_dai_prtd *prtd = substream->runtime->private_data;
 
-   prtd->dma_buffer_start = runtime->dma_addr;
-   prtd->dma_buffer_end = runtime->dma_addr + params_buffer_bytes(params);
-   prtd->period_size = params_period_bytes(params);
-   prtd->period_ptr_submitted = prtd->dma_buffer_start;
-   prtd->period_ptr_ended = prtd->dma_buffer_start;
prtd->substream = substream;
 
+   prtd->buffer_ended = 0;
+   prtd->buffer_size = params_buffer_size(params);
+   prtd->period_size = params_period_size(params);
+
+   prtd->ch_dma_addr_start = runtime->dma_addr;
+   prtd->ch_dma_addr_end = runtime->dma_addr + params_buffer_bytes(params);
+   prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
+   prtd->ch_dma_size = params_period_bytes(params);
+
return 0;
 }
 
@@ -80,16 +89,16 @@ static void qmc_audio_pcm_write_complete(void *context)
struct qmc_dai_prtd *prtd = context;
int ret;
 
-   prtd->period_ptr_ended += prtd->period_size;
-   if (prtd->period_ptr_ended >= prtd->dma_buffer_end)
-   prtd->period_ptr_ended = prtd->dma_buffer_start;
+   prtd->buffer_ended += prtd->period_size;
+   if (prtd->buffer_ended >= prtd->buffer_size)
+   prtd->buffer_ended = 0;
 
-   prtd->period_ptr_submitted += prtd->period_size;
-   if (prtd->period_ptr_submitted >= prtd->dma_buffer_end)
-   prtd->period_ptr_submitted = prtd->dma_buffer_start;
+   prtd->ch_dma_addr_current += prtd->ch_dma_size;
+   if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end)
+   prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
 
ret = qmc_chan_write_submit(prtd->qmc_dai->qmc_chan,
-   prtd->period_ptr_submitted, 
prtd->period_size,
+   prtd->ch_dma_addr_current, 
prtd->ch_dma_size,
qmc_audio_pcm_write_complete, prtd);
if (ret) {
dev_err(prtd->qmc_dai->dev, "write_submit failed %d\n",
@@ -104,21 +113,21 @@ static void qmc_audio_pcm_read_complete(void *context, 
size_t length, unsigned i
struct qmc_dai_prtd *prtd = context;
int ret;
 
-   if (length != prtd->period_size) {
+   if (length != prtd->ch_dma_size) {
dev_err(prtd->qmc_dai->dev, "read complete length = %zu, exp 
%zu\n",
-   length, prtd->period_size);
+   length, prtd->ch_dma_size);
}
 
-   prtd->period_ptr_ended += prtd->period_size;
-   if (prtd->period_ptr_ended >= prtd->dma_buffer_end)
-   prtd->period_ptr_ended = prtd->dma_buffer_start;
+   prtd->buffer_ended += prtd->period_size;
+   if (prtd->buffer_ended >= prtd->buffer_size)
+   prtd->buffer_ended = 0;
 
-   prtd->period_ptr_submitted += prtd->period_size;
-   if (prtd->period_ptr_submitted >= prtd->dma_buffer_end)
-   prtd->period_ptr_submitted = prtd->dma_buffer_start;
+   prtd->ch_dma_addr_current += prtd->ch_dma_size;
+   if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end)
+   prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
 
ret = qmc_chan_read_submit(prtd->qmc_dai->qmc_chan,
-  prtd->period_ptr_submitted, 
prtd->period_size,
+   

Re: [PATCH] KVM: PPC: Book3S HV: Prevent UAF in kvm_spapr_tce_attach_iommu_group()

2024-06-20 Thread Michael Ellerman
On Fri, 14 Jun 2024 22:29:10 +1000, Michael Ellerman wrote:
> Al reported a possible use-after-free (UAF) in 
> kvm_spapr_tce_attach_iommu_group().
> 
> It looks up `stt` from tablefd, but then continues to use it after doing
> fdput() on the returned fd. After the fdput() the tablefd is free to be
> closed by another thread. The close calls kvm_spapr_tce_release() and
> then release_spapr_tce_table() (via call_rcu()) which frees `stt`.
> 
> [...]

Applied to powerpc/fixes.

[1/1] KVM: PPC: Book3S HV: Prevent UAF in kvm_spapr_tce_attach_iommu_group()
  https://git.kernel.org/powerpc/c/a986fa57fd81a1430e00b3c6cf8a325d6f894a63

cheers


Re: [PATCH] powerpc/crypto: Add generated P8 asm to .gitignore

2024-06-20 Thread Michael Ellerman
On Mon, 03 Jun 2024 08:01:03 -0500, Nathan Lynch wrote:
> Looks like drivers/crypto/vmx/.gitignore should have been merged into
> arch/powerpc/crypto/.gitignore as part of commit
> 109303336a0c ("crypto: vmx - Move to arch/powerpc/crypto") so that all
> generated asm files are ignored.
> 
> 

Applied to powerpc/fixes.

[1/1] powerpc/crypto: Add generated P8 asm to .gitignore
  https://git.kernel.org/powerpc/c/2b85b7fb1376481f7d4c2cf92e5da942f06b2547

cheers


Re: (subset) [PATCH 0/6] defconfig: drop RT_GROUP_SCHED=y

2024-06-20 Thread Michael Ellerman
On Thu, 30 May 2024 19:19:48 +0800, Celeste Liu wrote:
> For cgroup v1, if turned on, and there's any cgroup in the "cpu" hierarchy it
> needs an RT budget assigned, otherwise the processes in it will not be able to
> get RT at all. The problem with RT group scheduling is that it requires the
> budget assigned but there's no way we could assign a default budget, since the
> values to assign are both upper and lower time limits, are absolute, and need 
> to
> be sum up to < 1 for each individal cgroup. That means we cannot really come 
> up
> with values that would work by default in the general case.[1]
> 
> [...]

Patch 4 applied to powerpc/next.

[4/6] powerpc: defconfig: drop RT_GROUP_SCHED=y from ppc6xx_defconfig
  https://git.kernel.org/powerpc/c/2bac6caee94e25f59ee47e2d365d7e07465089ba

cheers


Re: [PATCH v2] arch/powerpc: Remove unused cede related functions

2024-06-20 Thread Michael Ellerman
On Tue, 14 May 2024 18:54:55 +0530, Gautam Menghani wrote:
> Remove extended_cede_processor() and its helpers as
> extended_cede_processor() has no callers since
> commit 48f6e7f6d948("powerpc/pseries: remove cede offline state for CPUs")
> 
> 

Applied to powerpc/next.

[1/1] arch/powerpc: Remove unused cede related functions
  https://git.kernel.org/powerpc/c/214f33fcf656bf1be3f9f03d58fda067cdf7eecc

cheers


Re: [PATCH] powerpc/pseries/iommu: Split Dynamic DMA Window to be used in Hybrid mode

2024-06-20 Thread Michael Ellerman
On Mon, 13 May 2024 20:46:08 -0500, Gaurav Batra wrote:
> Dynamic DMA Window (DDW) supports TCEs that are backed by 2MB page size.
> In most configurations, DDW is big enough to pre-map all of LPAR memory
> for IO. Pre-mapping of memory for DMA results in improvements in IO
> performance.
> 
> Persistent memory, vPMEM, can be assigned to an LPAR as well. vPMEM is not
> contiguous with LPAR memory and usually is assigned at high memory
> addresses.  This makes is not possible to pre-map both vPMEM and LPAR
> memory in the same DDW.
> 
> [...]

Applied to powerpc/next.

[1/1] powerpc/pseries/iommu: Split Dynamic DMA Window to be used in Hybrid mode
  https://git.kernel.org/powerpc/c/ff5163bb7000a0254ffdd7b50cb6df43add94f33

cheers


Re: [PATCH v6] powerpc/pseries/vas: Use usleep_range() to support HCALL delay

2024-06-20 Thread Michael Ellerman
On Mon, 15 Jan 2024 21:59:10 -0800, Haren Myneni wrote:
> VAS allocate, modify and deallocate HCALLs returns
> H_LONG_BUSY_ORDER_1_MSEC or H_LONG_BUSY_ORDER_10_MSEC for busy
> delay and expects OS to reissue HCALL after that delay. But using
> msleep() will often sleep at least 20 msecs even though the
> hypervisor suggests OS reissue these HCALLs after 1 or 10msecs.
> 
> The open and close VAS window functions hold mutex and then issue
> these HCALLs. So these operations can take longer than the
> necessary when multiple threads issue open or close window APIs
> simultaneously, especially might affect the performance in the
> case of repeat open/close APIs for each compression request.
> 
> [...]

Applied to powerpc/next.

[1/1] powerpc/pseries/vas: Use usleep_range() to support HCALL delay
  https://git.kernel.org/powerpc/c/43ac9f5cd457bb01930f87448ddaaae455f8a8cf

cheers


Re: [PATCH] powerpc/mm/drmem: Silence drmem_init() early return

2024-06-20 Thread Michael Ellerman
On Mon, 03 Jun 2024 14:31:32 -0500, Nathan Lynch wrote:
> It's not an error or noteworthy condition if the
> "ibm,dynamic-reconfiguration-memory" node isn't present.
> 
> Drop the needless message.
> 
> 

Applied to powerpc/next.

[1/1] powerpc/mm/drmem: Silence drmem_init() early return
  https://git.kernel.org/powerpc/c/11e6e6d8bf8f908468bac0447727e3f3923c8512

cheers


Re: [PATCH v2 0/1] powerpc/numa: Make cpu/memory less numa-node online

2024-06-20 Thread Michael Ellerman
On Fri, 17 May 2024 19:55:21 +0530, Nilay Shroff wrote:
> On NUMA aware system, we make a numa-node online only if that node is
> attached to cpu/memory. However it's possible that we have some PCI/IO
> device affinitized to a numa-node which is not currently online. In such
> case we set the numa-node id of the corresponding PCI device to -1
> (NUMA_NO_NODE). Not assigning the correct numa-node id to PCI device may
> impact the performance of such device. For instance, we have a multi
> controller NVMe disk where each controller of the disk is attached to
> different PHB (PCI host bridge). Each of these PHBs has numa-node id
> assigned during PCI enumeration. During PCI enumeration if we find that
> the numa-node is not online then we set the numa-node id of the PHB to -1.
> If we create shared namespace and attach to multi controller NVMe disk
> then that namespace could be accessed through each controller and as each
> controller is connected to different PHBs, it's possible to access the
> same namespace using multiple PCI channel. While sending IO to a shared
> namespace, NVMe driver would calculate the optimal IO path using numa-node
> distance. However if the numa-node id is not correctly assigned to NVMe
> PCIe controller then it's possible that driver would calculate incorrect
> NUMA distance and hence select the non-optimal path for sending IO. If
> this happens then we could potentially observe the degraded IO performance.
> 
> [...]

Applied to powerpc/next.

[1/1] powerpc/numa: Online a node if PHB is attached.
  https://git.kernel.org/powerpc/c/11981816e3614156a1fe14a1e8e77094ea46c7d5

cheers


[PATCHv5 0/9] ASoC: fsl-asoc-card: add S/PDIF controller

2024-06-20 Thread Elinor Montmasson
Hello,

This is the v5 of the series of patches aiming to make the machine
driver `fsl-asoc-card` compatible with S/PDIF controllers on imx boards.
The main goal is to allow the use of S/PDIF controllers with ASRC
modules.

The `imx-spdif` machine driver already has specific support for S/PDIF
controllers but doesn't support using an ASRC with it. However, the
`fsl-asoc-card` machine driver has the necessary code to create a sound
card which can use an ASRC module.
It is then possible to extend the support for S/PDIF audio cards by
merging the `imx-spdif` driver into `fsl-asoc-card`.

The first patch fixes a NULL pointer dereference in `fsl-asoc-card`
which occurs when the function "fsl_asoc_card_audmux_init()" prints
error logs.

The next three patches adapt the `fsl-asoc-card` driver to support
multiple codec use cases.
The driver can get 2 codec phandles from the device tree, and
codec-related variables are doubled.
`for_each_codecs` macros are also used when possible to ease adding
other multi-codec use cases in the future.
This makes possible to use the two S/PDIF dummy codec drivers
`spdif_receiver` and `spdif_transmitter` instead of `snd-soc-dummy`,
which was used in `imx-spdif`.

The fifth patch merges the S/PDIF support from `imx-spdif` to
`fsl-asoc-card`.
`fsl-asoc-card` offers the same functionalities as `imx-spdif` did, but
this merge also extends the S/PDIF support with the possibility of using
an ASRC.
Compatible "fsl,imx-audio-spdif" is kept, but some DT properties have to
be updated in device trees to match those of `fsl-asoc-card`:
* "spdif-controller" is now "audio-cpu" in `fsl-asoc-card`.
* "spdif-in" and "spdif-out" are now replaced by the "audio-codec"
  property of `fsl-asoc-card`. S/PDIF specific dummy codecs should be
  used with `fsl-asoc-card`, and therefore declared in device trees.

The last four patches update the device tree bindings of
`fsl-asoc-card`, remove the now obsolete binding of `imx-spdif`, and
update all device trees using the `fsl,imx-audio-spdif` compatible.

This series of patches was successfully built for arm64 and x86 on top
of the latest??"for-next" branch of the ASoC git tree on the 19th of June
2024.
These modifications have also been tested on an i.MX8MN evaluation board
with a linux kernel RT v6.1.26-rt8.

If you have any questions or remarks about these commits, don't hesitate
to reply to this message.

Best regards,
Elinor Montmasson

Changelog:
v4 -> v5:
* Focus the contribution to bringing S/PDIF / ASRC support.
* Instead of creating a new compatible for the S/PDIF `fsl-asoc-card`
  support, merge the driver `imx-spdif` into `fsl-asoc-card`, and keep
  the compatible. It preserves the base S/PDIF audio card support but
  also extends it with the possibility to use an ASRC.
  It also reduces code and driver duplication.
* Following driver merge, adapt device trees using "fsl,imx-audio-spdif"
  compatible. 
* Use more `for_each_codecs` macros in `fsl-asoc-card` when adding
  multi-codec support.
* Remove patches about new device-tree bindings that were not relevant
  for an S/PDIF specific support.
* Improve DT schema changes.
* Move `priv->pdev` assignment earlier in "fsl_asoc_card_probe()" to fix
  a NULL pointer dereference in "fsl_asoc_card_audmux_init()".
* v4 patch series at :
https://lore.kernel.org/all/20240515135411.34-1-elinor.montmas...@savoirfairelinux.com/

v3 -> v4:
* Use the standard TDM bidings, as defined in "tdm-slot.txt", for the
  new optional DT bindings setting the TDM slots number and width.
* Use the clock DT bindings to optionally specify the CPU DAI system
  clock frequency, instead of a dedicated new binding.
* Rename the new DT binding "cpu-sysclk-dir-out" to
  "cpu-system-clock-direction-out" to better follow the style of the
  simple-card driver.
* Merge TX an RX bindings for CPU DAI system-clock, to better follow the
  style of the simple-card driver, and also as there was no use case in
  fsl-asoc-card where TX and RX settings had to be different.
* Add the documentation for the new bindings in the new DT schema
  bindings documentation. Also add an example with the generic codec.
* v3 patch series at :
https://lore.kernel.org/alsa-devel/20231218124058.2047167-1-elinor.montmas...@savoirfairelinux.com/

v2 -> v3:
* When the bitmaster or framemaster are retrieved from the device tree,
  the driver will now compare them with the two codecs possibly given in
  device tree, and not just the first codec.
* Improve driver modifications to use multiple codecs for better
  integration of future multi-codec use cases:
* Use `for_each_codec` macros when possible.
* `fsl_asoc_card_priv` struct now has 2 `codec_priv` as the driver
  can currently retrieve 2 codec phandles from the device tree.
* Fix subject of patch 10/10 to follow the style of the subsystem
* v2 patch series at:
https://lore.kernel.org/alsa-devel/20231027144734.3654829-1-elinor.montmas...@savoirfairelinux.com/

v1 -> v2:
* Replace use of the dummy cod

[PATCHv5 1/9] ASoC: fsl-asoc-card: set priv->pdev before using it

2024-06-20 Thread Elinor Montmasson
priv->pdev pointer was set after being used in
fsl_asoc_card_audmux_init().
Move this assignment at the start of the probe function, so
sub-functions can correctly use pdev through priv.

fsl_asoc_card_audmux_init() dereferences priv->pdev to get access to the
dev struct, used with dev_err macros.
As priv is zero-initialised, there would be a NULL pointer dereference.
Note that if priv->dev is dereferenced before assignment but never used,
for example if there is no error to be printed, the driver won't crash
probably due to compiler optimisations.

Fixes: 708b4351f08c ("ASoC: fsl: Add Freescale Generic ASoC Sound Card with 
ASRC support")
Signed-off-by: Elinor Montmasson 
---
 sound/soc/fsl/fsl-asoc-card.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 5ddc0c2fe53f..eb67689dcd6e 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -559,6 +559,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
if (!priv)
return -ENOMEM;
 
+   priv->pdev = pdev;
+
cpu_np = of_parse_phandle(np, "audio-cpu", 0);
/* Give a chance to old DT binding */
if (!cpu_np)
@@ -787,7 +789,6 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
}
 
/* Initialize sound card */
-   priv->pdev = pdev;
priv->card.dev = &pdev->dev;
priv->card.owner = THIS_MODULE;
ret = snd_soc_of_parse_card_name(&priv->card, "model");
-- 
2.34.1



[PATCHv5 2/9] ASoC: fsl-asoc-card: add support for dai links with multiple codecs

2024-06-20 Thread Elinor Montmasson
Add support for dai links using multiple codecs for multi-codec
use cases.

Co-developed-by: Philip-Dylan Gleonec 

Signed-off-by: Philip-Dylan Gleonec 
Signed-off-by: Elinor Montmasson 
---
 sound/soc/fsl/fsl-asoc-card.c | 19 +++
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index eb67689dcd6e..e8003fbc8092 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -542,6 +542,7 @@ static int fsl_asoc_card_late_probe(struct snd_soc_card 
*card)
 static int fsl_asoc_card_probe(struct platform_device *pdev)
 {
struct device_node *cpu_np, *codec_np, *asrc_np;
+   struct snd_soc_dai_link_component *codec_comp;
struct device_node *np = pdev->dev.of_node;
struct platform_device *asrc_pdev = NULL;
struct device_node *bitclkprovider = NULL;
@@ -552,6 +553,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
const char *codec_dai_name;
const char *codec_dev_name;
u32 asrc_fmt = 0;
+   int codec_idx;
u32 width;
int ret;
 
@@ -816,10 +818,10 @@ static int fsl_asoc_card_probe(struct platform_device 
*pdev)
 
/* Normal DAI Link */
priv->dai_link[0].cpus->of_node = cpu_np;
-   priv->dai_link[0].codecs->dai_name = codec_dai_name;
+   priv->dai_link[0].codecs[0].dai_name = codec_dai_name;
 
if (!fsl_asoc_card_is_ac97(priv))
-   priv->dai_link[0].codecs->of_node = codec_np;
+   priv->dai_link[0].codecs[0].of_node = codec_np;
else {
u32 idx;
 
@@ -830,11 +832,11 @@ static int fsl_asoc_card_probe(struct platform_device 
*pdev)
goto asrc_fail;
}
 
-   priv->dai_link[0].codecs->name =
+   priv->dai_link[0].codecs[0].name =
devm_kasprintf(&pdev->dev, GFP_KERNEL,
   "ac97-codec.%u",
   (unsigned int)idx);
-   if (!priv->dai_link[0].codecs->name) {
+   if (!priv->dai_link[0].codecs[0].name) {
ret = -ENOMEM;
goto asrc_fail;
}
@@ -848,10 +850,11 @@ static int fsl_asoc_card_probe(struct platform_device 
*pdev)
/* DPCM DAI Links only if ASRC exists */
priv->dai_link[1].cpus->of_node = asrc_np;
priv->dai_link[1].platforms->of_node = asrc_np;
-   priv->dai_link[2].codecs->dai_name = codec_dai_name;
-   priv->dai_link[2].codecs->of_node = codec_np;
-   priv->dai_link[2].codecs->name =
-   priv->dai_link[0].codecs->name;
+   for_each_link_codecs((&(priv->dai_link[2])), codec_idx, 
codec_comp) {
+   codec_comp->dai_name = 
priv->dai_link[0].codecs[codec_idx].dai_name;
+   codec_comp->of_node = 
priv->dai_link[0].codecs[codec_idx].of_node;
+   codec_comp->name = 
priv->dai_link[0].codecs[codec_idx].name;
+   }
priv->dai_link[2].cpus->of_node = cpu_np;
priv->dai_link[2].dai_fmt = priv->dai_fmt;
priv->card.num_links = 3;
-- 
2.34.1



[PATCHv5 3/9] ASoC: fsl-asoc-card: add second dai link component for codecs

2024-06-20 Thread Elinor Montmasson
Add a second dai link component for codecs that will be used for use
cases with 2 codecs.
It is needed for future integration of the SPDIF support, which will
use spdif_receiver and spdif_transmitter drivers.

To prevent deferring in use cases using only one codec, also set
by default the number of codecs to 1 for the relevant dai links.

Co-developed-by: Philip-Dylan Gleonec 

Signed-off-by: Philip-Dylan Gleonec 
Signed-off-by: Elinor Montmasson 
---
 sound/soc/fsl/fsl-asoc-card.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index e8003fbc8092..805e2030bde4 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -296,7 +296,7 @@ static int be_hw_params_fixup(struct snd_soc_pcm_runtime 
*rtd,
 
 SND_SOC_DAILINK_DEFS(hifi,
DAILINK_COMP_ARRAY(COMP_EMPTY()),
-   DAILINK_COMP_ARRAY(COMP_EMPTY()),
+   DAILINK_COMP_ARRAY(COMP_EMPTY(), COMP_EMPTY()),
DAILINK_COMP_ARRAY(COMP_EMPTY()));
 
 SND_SOC_DAILINK_DEFS(hifi_fe,
@@ -306,7 +306,7 @@ SND_SOC_DAILINK_DEFS(hifi_fe,
 
 SND_SOC_DAILINK_DEFS(hifi_be,
DAILINK_COMP_ARRAY(COMP_EMPTY()),
-   DAILINK_COMP_ARRAY(COMP_EMPTY()));
+   DAILINK_COMP_ARRAY(COMP_EMPTY(), COMP_EMPTY()));
 
 static const struct snd_soc_dai_link fsl_asoc_card_dai[] = {
/* Default ASoC DAI Link*/
@@ -622,6 +622,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 
memcpy(priv->dai_link, fsl_asoc_card_dai,
   sizeof(struct snd_soc_dai_link) * ARRAY_SIZE(priv->dai_link));
+   priv->dai_link[0].num_codecs = 1;
+   priv->dai_link[2].num_codecs = 1;
 
priv->card.dapm_routes = audio_map;
priv->card.num_dapm_routes = ARRAY_SIZE(audio_map);
-- 
2.34.1



[PATCHv5 4/9] ASoC: fsl-asoc-card: add compatibility to use 2 codecs in dai-links

2024-06-20 Thread Elinor Montmasson
Adapt the driver to work with configurations using two codecs or more.
Modify fsl_asoc_card_probe() to handle use cases where 2 codecs are
given in the device tree.
This will be needed to add support for the SPDIF.

Use cases using one codec will ignore any given codecs other than the
first.

Co-developed-by: Philip-Dylan Gleonec 

Signed-off-by: Philip-Dylan Gleonec 
Signed-off-by: Elinor Montmasson 
---
 sound/soc/fsl/fsl-asoc-card.c | 279 --
 1 file changed, 161 insertions(+), 118 deletions(-)

diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 805e2030bde4..87329731e02d 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -99,7 +99,7 @@ struct fsl_asoc_card_priv {
struct simple_util_jack hp_jack;
struct simple_util_jack mic_jack;
struct platform_device *pdev;
-   struct codec_priv codec_priv;
+   struct codec_priv codec_priv[2];
struct cpu_priv cpu_priv;
struct snd_soc_card card;
u8 streams;
@@ -172,10 +172,12 @@ static int fsl_asoc_card_hw_params(struct 
snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
-   struct codec_priv *codec_priv = &priv->codec_priv;
+   struct codec_priv *codec_priv;
+   struct snd_soc_dai *codec_dai;
struct cpu_priv *cpu_priv = &priv->cpu_priv;
struct device *dev = rtd->card->dev;
unsigned int pll_out;
+   int codec_idx;
int ret;
 
priv->sample_rate = params_rate(params);
@@ -208,28 +210,32 @@ static int fsl_asoc_card_hw_params(struct 
snd_pcm_substream *substream,
}
 
/* Specific configuration for PLL */
-   if (codec_priv->pll_id >= 0 && codec_priv->fll_id >= 0) {
-   if (priv->sample_format == SNDRV_PCM_FORMAT_S24_LE)
-   pll_out = priv->sample_rate * 384;
-   else
-   pll_out = priv->sample_rate * 256;
+   for_each_rtd_codec_dais(rtd, codec_idx, codec_dai) {
+   codec_priv = &priv->codec_priv[codec_idx];
 
-   ret = snd_soc_dai_set_pll(snd_soc_rtd_to_codec(rtd, 0),
- codec_priv->pll_id,
- codec_priv->mclk_id,
- codec_priv->mclk_freq, pll_out);
-   if (ret) {
-   dev_err(dev, "failed to start FLL: %d\n", ret);
-   goto fail;
-   }
+   if (codec_priv->pll_id >= 0 && codec_priv->fll_id >= 0) {
+   if (priv->sample_format == SNDRV_PCM_FORMAT_S24_LE)
+   pll_out = priv->sample_rate * 384;
+   else
+   pll_out = priv->sample_rate * 256;
 
-   ret = snd_soc_dai_set_sysclk(snd_soc_rtd_to_codec(rtd, 0),
-codec_priv->fll_id,
-pll_out, SND_SOC_CLOCK_IN);
+   ret = snd_soc_dai_set_pll(codec_dai,
+   codec_priv->pll_id,
+   codec_priv->mclk_id,
+   codec_priv->mclk_freq, pll_out);
+   if (ret) {
+   dev_err(dev, "failed to start FLL: %d\n", ret);
+   goto fail;
+   }
 
-   if (ret && ret != -ENOTSUPP) {
-   dev_err(dev, "failed to set SYSCLK: %d\n", ret);
-   goto fail;
+   ret = snd_soc_dai_set_sysclk(codec_dai,
+   codec_priv->fll_id,
+   pll_out, SND_SOC_CLOCK_IN);
+
+   if (ret && ret != -ENOTSUPP) {
+   dev_err(dev, "failed to set SYSCLK: %d\n", ret);
+   goto fail;
+   }
}
}
 
@@ -244,28 +250,34 @@ static int fsl_asoc_card_hw_free(struct snd_pcm_substream 
*substream)
 {
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
-   struct codec_priv *codec_priv = &priv->codec_priv;
+   struct codec_priv *codec_priv;
+   struct snd_soc_dai *codec_dai;
struct device *dev = rtd->card->dev;
+   int codec_idx;
int ret;
 
priv->streams &= ~BIT(substream->stream);
 
-   if (!priv->streams && codec_priv->pll_id >= 0 && codec_priv->fll_id >= 
0) {
-   /* Force freq to be free_freq to avoid error message in codec */
-   

[PATCHv5 5/9] ASoC: fsl-asoc-card: merge spdif support from imx-spdif.c

2024-06-20 Thread Elinor Montmasson
The imx-spdif machine driver creates audio card to directly use an
S/PDIF device. However, it doesn't support interacting with an ASRC.
fsl-asoc-card already has the support to create audio card which can
use the ASRC.

Merge the S/PDIF support from imx-spdif into fsl-asoc-card to extend
the support of S/PDIF audio card with the use of ASRC devices.
It also substitutes the use of the dummy codec in imx-spdif with the
existing spdif_transmitter and spdif_receiver codec drivers.

Signed-off-by: Elinor Montmasson 
---
 arch/arm/configs/imx_v6_v7_defconfig |   1 -
 arch/arm64/configs/defconfig |   1 -
 sound/soc/fsl/Kconfig|  10 +--
 sound/soc/fsl/Makefile   |   2 -
 sound/soc/fsl/fsl-asoc-card.c|  58 +++
 sound/soc/fsl/imx-spdif.c| 103 ---
 6 files changed, 59 insertions(+), 116 deletions(-)
 delete mode 100644 sound/soc/fsl/imx-spdif.c

diff --git a/arch/arm/configs/imx_v6_v7_defconfig 
b/arch/arm/configs/imx_v6_v7_defconfig
index cf2480dce285..ac5ae621b2af 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -311,7 +311,6 @@ CONFIG_SND_IMX_SOC=y
 CONFIG_SND_SOC_EUKREA_TLV320=y
 CONFIG_SND_SOC_IMX_ES8328=y
 CONFIG_SND_SOC_IMX_SGTL5000=y
-CONFIG_SND_SOC_IMX_SPDIF=y
 CONFIG_SND_SOC_FSL_ASOC_CARD=y
 CONFIG_SND_SOC_AC97_CODEC=y
 CONFIG_SND_SOC_CS42XX8_I2C=y
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 57a9abe78ee4..a6c9688fee0e 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -940,7 +940,6 @@ CONFIG_SND_SOC_FSL_MICFIL=m
 CONFIG_SND_SOC_FSL_EASRC=m
 CONFIG_SND_IMX_SOC=m
 CONFIG_SND_SOC_IMX_SGTL5000=m
-CONFIG_SND_SOC_IMX_SPDIF=m
 CONFIG_SND_SOC_FSL_ASOC_CARD=m
 CONFIG_SND_SOC_IMX_AUDMIX=m
 CONFIG_SND_SOC_MT8183=m
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 9a371d4496c2..e3b2bfb016c8 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -296,15 +296,6 @@ config SND_SOC_IMX_SGTL5000
  SND_SOC_FSL_ASOC_CARD and SND_SOC_SGTL5000 to use the newer
  driver.
 
-config SND_SOC_IMX_SPDIF
-   tristate "SoC Audio support for i.MX boards with S/PDIF"
-   select SND_SOC_IMX_PCM_DMA
-   select SND_SOC_FSL_SPDIF
-   help
- SoC Audio support for i.MX boards with S/PDIF
- Say Y if you want to add support for SoC audio on an i.MX board with
- a S/DPDIF.
-
 config SND_SOC_FSL_ASOC_CARD
tristate "Generic ASoC Sound Card with ASRC support"
depends on OF && I2C
@@ -316,6 +307,7 @@ config SND_SOC_FSL_ASOC_CARD
select SND_SOC_FSL_ESAI
select SND_SOC_FSL_SAI
select SND_SOC_FSL_SSI
+   select SND_SOC_FSL_SPDIF
select SND_SOC_TLV320AIC31XX
select SND_SOC_WM8994
select MFD_WM8994
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 2fe78eed3a48..1ae181b24a88 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -65,7 +65,6 @@ obj-$(CONFIG_SND_SOC_IMX_PCM_RPMSG) += imx-pcm-rpmsg.o
 snd-soc-eukrea-tlv320-y := eukrea-tlv320.o
 snd-soc-imx-es8328-y := imx-es8328.o
 snd-soc-imx-sgtl5000-y := imx-sgtl5000.o
-snd-soc-imx-spdif-y := imx-spdif.o
 snd-soc-imx-audmix-y := imx-audmix.o
 snd-soc-imx-hdmi-y := imx-hdmi.o
 snd-soc-imx-rpmsg-y := imx-rpmsg.o
@@ -74,7 +73,6 @@ snd-soc-imx-card-y := imx-card.o
 obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
 obj-$(CONFIG_SND_SOC_IMX_ES8328) += snd-soc-imx-es8328.o
 obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o
-obj-$(CONFIG_SND_SOC_IMX_SPDIF) += snd-soc-imx-spdif.o
 obj-$(CONFIG_SND_SOC_IMX_AUDMIX) += snd-soc-imx-audmix.o
 obj-$(CONFIG_SND_SOC_IMX_HDMI) += snd-soc-imx-hdmi.o
 obj-$(CONFIG_SND_SOC_IMX_RPMSG) += snd-soc-imx-rpmsg.o
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 87329731e02d..c0e600525680 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -477,6 +477,59 @@ static int fsl_asoc_card_audmux_init(struct device_node 
*np,
return 0;
 }
 
+static int fsl_asoc_card_spdif_init(struct device_node *codec_np[],
+   struct device_node *cpu_np,
+   const char *codec_dai_name[],
+   struct fsl_asoc_card_priv *priv)
+{
+   struct device *dev = &priv->pdev->dev;
+
+   if (!of_node_name_eq(cpu_np, "spdif")) {
+   dev_err(dev, "CPU phandle invalid, should be an SPDIF 
device\n");
+   return -EINVAL;
+   }
+
+   priv->dai_link[0].playback_only = true;
+   priv->dai_link[0].capture_only = true;
+
+   for (int i = 0; i < 2; i++) {
+   if (!codec_np[i])
+   break;
+
+   if (of_device_is_compatible(codec_np[i], "linux,spdif-dit")) {
+   priv->dai_link[0].capture_only = false;
+   codec_dai_name[i] = "dit-hifi";
+   

[PATCHv5 6/9] ASoC: dt-bindings: fsl-asoc-card: add compatible string for spdif

2024-06-20 Thread Elinor Montmasson
The S/PDIF audio card support was merged from imx-spdif into the
fsl-asoc-card driver, making it possible to use an S/PDIF with an ASRC.
Add the new compatible and update properties.

Signed-off-by: Elinor Montmasson 
---
 .../bindings/sound/fsl-asoc-card.yaml | 30 ---
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/fsl-asoc-card.yaml 
b/Documentation/devicetree/bindings/sound/fsl-asoc-card.yaml
index 9922664d5ccc..f2e28b32808e 100644
--- a/Documentation/devicetree/bindings/sound/fsl-asoc-card.yaml
+++ b/Documentation/devicetree/bindings/sound/fsl-asoc-card.yaml
@@ -33,6 +33,7 @@ properties:
   - items:
   - enum:
   - fsl,imx-sgtl5000
+  - fsl,imx-sabreauto-spdif
   - fsl,imx25-pdk-sgtl5000
   - fsl,imx53-cpuvo-sgtl5000
   - fsl,imx51-babbage-sgtl5000
@@ -54,6 +55,7 @@ properties:
   - fsl,imx6q-ventana-sgtl5000
   - fsl,imx6sl-evk-wm8962
   - fsl,imx6sx-sdb-mqs
+  - fsl,imx6sx-sdb-spdif
   - fsl,imx6sx-sdb-wm8962
   - fsl,imx7d-evk-wm8960
   - karo,tx53-audio-sgtl5000
@@ -65,6 +67,7 @@ properties:
   - fsl,imx-audio-sgtl5000
   - fsl,imx-audio-wm8960
   - fsl,imx-audio-wm8962
+  - fsl,imx-audio-spdif
   - items:
   - enum:
   - fsl,imx-audio-ac97
@@ -81,6 +84,7 @@ properties:
   - fsl,imx-audio-wm8960
   - fsl,imx-audio-wm8962
   - fsl,imx-audio-wm8958
+  - fsl,imx-audio-spdif
 
   model:
 $ref: /schemas/types.yaml#/definitions/string
@@ -93,8 +97,15 @@ properties:
   need to add ASRC support via DPCM.
 
   audio-codec:
-$ref: /schemas/types.yaml#/definitions/phandle
-description: The phandle of an audio codec
+$ref: /schemas/types.yaml#/definitions/phandle-array
+description: |
+  The phandle of an audio codec.
+  With "fsl,imx-audio-spdif", either SPDIF audio codec spdif_transmitter,
+  spdif_receiver or both.
+minItems: 1
+maxItems: 2
+items:
+  maxItems: 1
 
   audio-cpu:
 $ref: /schemas/types.yaml#/definitions/phandle
@@ -150,8 +161,10 @@ properties:
 description: dai-link uses bit clock inversion.
 
   mclk-id:
-$ref: /schemas/types.yaml#/definitions/uint32
-description: main clock id, specific for each card configuration.
+$ref: /schemas/types.yaml#/definitions/uint32-array
+description: Main clock id for each codec, specific for each card 
configuration.
+minItems: 1
+maxItems: 2
 
   mux-int-port:
 $ref: /schemas/types.yaml#/definitions/uint32
@@ -195,3 +208,12 @@ examples:
  "AIN2L", "Line In Jack",
  "AIN2R", "Line In Jack";
 };
+
+  - |
+sound-spdif-asrc {
+  compatible = "fsl,imx-audio-spdif";
+  model = "spdif-asrc-audio";
+  audio-cpu = <&spdif>;
+  audio-asrc = <&easrc>;
+  audio-codec = <&spdifdit>, <&spdifdir>;
+};
-- 
2.34.1



[PATCHv5 7/9] ASoC: dt-bindings: imx-audio-spdif: remove binding

2024-06-20 Thread Elinor Montmasson
imx-audio-spdif was merged into the fsl-asoc-card driver, and therefore
removed.

Signed-off-by: Elinor Montmasson 
---
 .../bindings/sound/fsl,imx-audio-spdif.yaml   | 66 ---
 1 file changed, 66 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/sound/fsl,imx-audio-spdif.yaml

diff --git a/Documentation/devicetree/bindings/sound/fsl,imx-audio-spdif.yaml 
b/Documentation/devicetree/bindings/sound/fsl,imx-audio-spdif.yaml
deleted file mode 100644
index 5fc543d02ecb..
--- a/Documentation/devicetree/bindings/sound/fsl,imx-audio-spdif.yaml
+++ /dev/null
@@ -1,66 +0,0 @@
-# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-%YAML 1.2

-$id: http://devicetree.org/schemas/sound/fsl,imx-audio-spdif.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: Freescale i.MX audio complex with S/PDIF transceiver
-
-maintainers:
-  - Shengjiu Wang 
-
-properties:
-  compatible:
-oneOf:
-  - items:
-  - enum:
-  - fsl,imx-sabreauto-spdif
-  - fsl,imx6sx-sdb-spdif
-  - const: fsl,imx-audio-spdif
-  - enum:
-  - fsl,imx-audio-spdif
-
-  model:
-$ref: /schemas/types.yaml#/definitions/string
-description: User specified audio sound card name
-
-  spdif-controller:
-$ref: /schemas/types.yaml#/definitions/phandle
-description: The phandle of the i.MX S/PDIF controller
-
-  spdif-out:
-type: boolean
-description:
-  If present, the transmitting function of S/PDIF will be enabled,
-  indicating there's a physical S/PDIF out connector or jack on the
-  board or it's connecting to some other IP block, such as an HDMI
-  encoder or display-controller.
-
-  spdif-in:
-type: boolean
-description:
-  If present, the receiving function of S/PDIF will be enabled,
-  indicating there is a physical S/PDIF in connector/jack on the board.
-
-required:
-  - compatible
-  - model
-  - spdif-controller
-
-anyOf:
-  - required:
-  - spdif-in
-  - required:
-  - spdif-out
-
-additionalProperties: false
-
-examples:
-  - |
-sound-spdif {
-compatible = "fsl,imx-audio-spdif";
-model = "imx-spdif";
-spdif-controller = <&spdif>;
-spdif-out;
-spdif-in;
-};
-- 
2.34.1



[PATCHv5 8/9] arm64: dts: imx8m: update spdif sound card node properties

2024-06-20 Thread Elinor Montmasson
Following merge of imx-spdif driver into fsl-asoc-card:
* update properties to match those used by fsl-asoc-card.
* S/PDIF in/out dummy codecs must now be declared explicitly, add and
  use them.

These modifications were tested only on an imx8mn-evk board.

Signed-off-by: Elinor Montmasson 
---
 arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi | 15 +---
 arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi | 15 +---
 arch/arm64/boot/dts/freescale/imx8mq-evk.dts  | 24 +++
 3 files changed, 43 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi 
b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
index 90d1901df2b1..348855a41852 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
@@ -180,12 +180,21 @@ cpu {
};
};
 
+   spdif_out: spdif-out {
+   #sound-dai-cells = <0>;
+   compatible = "linux,spdif-dit";
+   };
+
+   spdif_in: spdif-in {
+   #sound-dai-cells = <0>;
+   compatible = "linux,spdif-dir";
+   };
+
sound-spdif {
compatible = "fsl,imx-audio-spdif";
model = "imx-spdif";
-   spdif-controller = <&spdif1>;
-   spdif-out;
-   spdif-in;
+   audio-cpu = <&spdif1>;
+   audio-codec = <&spdif_out>, <&spdif_in>;
};
 };
 
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi 
b/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
index 9e0259ddf4bc..6a47e09703a7 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
@@ -124,12 +124,21 @@ sound-wm8524 {
"Line Out Jack", "LINEVOUTR";
};
 
+   spdif_out: spdif-out {
+   #sound-dai-cells = <0>;
+   compatible = "linux,spdif-dit";
+   };
+
+   spdif_in: spdif-in {
+   #sound-dai-cells = <0>;
+   compatible = "linux,spdif-dir";
+   };
+
sound-spdif {
compatible = "fsl,imx-audio-spdif";
model = "imx-spdif";
-   spdif-controller = <&spdif1>;
-   spdif-out;
-   spdif-in;
+   audio-cpu = <&spdif1>;
+   audio-codec = <&spdif_out>, <&spdif_in>;
};
 
sound-micfil {
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts 
b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
index 7507548cdb16..b953865f0b46 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
@@ -125,19 +125,33 @@ link_codec: simple-audio-card,codec {
};
};
 
+   spdif_out: spdif-out {
+   #sound-dai-cells = <0>;
+   compatible = "linux,spdif-dit";
+   };
+
+   spdif_in: spdif-in {
+   #sound-dai-cells = <0>;
+   compatible = "linux,spdif-dir";
+   };
+
sound-spdif {
compatible = "fsl,imx-audio-spdif";
model = "imx-spdif";
-   spdif-controller = <&spdif1>;
-   spdif-out;
-   spdif-in;
+   audio-cpu = <&spdif1>;
+   audio-codec = <&spdif_out>, <&spdif_in>;
+   };
+
+   hdmi_arc_in: hdmi-arc-in {
+   #sound-dai-cells = <0>;
+   compatible = "linux,spdif-dir";
};
 
sound-hdmi-arc {
compatible = "fsl,imx-audio-spdif";
model = "imx-hdmi-arc";
-   spdif-controller = <&spdif2>;
-   spdif-in;
+   audio-cpu = <&spdif2>;
+   audio-codec = <&hdmi_arc_in>;
};
 };
 
-- 
2.34.1



[PATCHv5 9/9] ARM: dts: imx6: update spdif sound card node properties

2024-06-20 Thread Elinor Montmasson
Following merge of imx-spdif driver into fsl-asoc-card:
* update properties to match those used by fsl-asoc-card.
* S/PDIF in/out dummy codecs must now be declared explicitly, add and
  use them.

These modifications were tested only on an imx8mn-evk board.

Signed-off-by: Elinor Montmasson 
---
 arch/arm/boot/dts/nxp/imx/imx6q-cm-fx6.dts| 15 ---
 arch/arm/boot/dts/nxp/imx/imx6q-prti6q.dts| 15 ---
 arch/arm/boot/dts/nxp/imx/imx6q-tbs2910.dts   |  9 +++--
 arch/arm/boot/dts/nxp/imx/imx6qdl-apalis.dtsi | 15 ---
 arch/arm/boot/dts/nxp/imx/imx6qdl-apf6dev.dtsi|  9 +++--
 arch/arm/boot/dts/nxp/imx/imx6qdl-colibri.dtsi| 15 ---
 arch/arm/boot/dts/nxp/imx/imx6qdl-cubox-i.dtsi|  9 +++--
 .../boot/dts/nxp/imx/imx6qdl-hummingboard.dtsi|  9 +++--
 arch/arm/boot/dts/nxp/imx/imx6qdl-sabreauto.dtsi  |  9 +++--
 arch/arm/boot/dts/nxp/imx/imx6qdl-wandboard.dtsi  |  9 +++--
 arch/arm/boot/dts/nxp/imx/imx6sx-sabreauto.dts|  9 +++--
 arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi |  9 +++--
 12 files changed, 104 insertions(+), 28 deletions(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-cm-fx6.dts 
b/arch/arm/boot/dts/nxp/imx/imx6q-cm-fx6.dts
index 95b49fc83f7b..5c664c0f2169 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6q-cm-fx6.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6q-cm-fx6.dts
@@ -127,12 +127,21 @@ simple-audio-card,codec {
};
};
 
+   spdif_out: spdif-out {
+   #sound-dai-cells = <0>;
+   compatible = "linux,spdif-dit";
+   };
+
+   spdif_in: spdif-in {
+   #sound-dai-cells = <0>;
+   compatible = "linux,spdif-dir";
+   };
+
sound-spdif {
compatible = "fsl,imx-audio-spdif";
model = "imx-spdif";
-   spdif-controller = <&spdif>;
-   spdif-out;
-   spdif-in;
+   audio-cpu = <&spdif>;
+   audio-codec = <&spdif_out>, <&spdif_in>;
};
 };
 
diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-prti6q.dts 
b/arch/arm/boot/dts/nxp/imx/imx6q-prti6q.dts
index a7d5693c5ab7..8491d656ef17 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6q-prti6q.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6q-prti6q.dts
@@ -111,12 +111,21 @@ simple-audio-card,codec {
};
};
 
+   spdif_out: spdif-out {
+   #sound-dai-cells = <0>;
+   compatible = "linux,spdif-dit";
+   };
+
+   spdif_in: spdif-in {
+   #sound-dai-cells = <0>;
+   compatible = "linux,spdif-dir";
+   };
+
sound-spdif {
compatible = "fsl,imx-audio-spdif";
model = "imx-spdif";
-   spdif-controller = <&spdif>;
-   spdif-in;
-   spdif-out;
+   audio-cpu = <&spdif>;
+   audio-codec = <&spdif_out>, <&spdif_in>;
};
 };
 
diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-tbs2910.dts 
b/arch/arm/boot/dts/nxp/imx/imx6q-tbs2910.dts
index 7c298d9aa21e..ea9a98887c7b 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6q-tbs2910.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6q-tbs2910.dts
@@ -90,11 +90,16 @@ sound-sgtl5000 {
ssi-controller = <&ssi1>;
};
 
+   spdif_out: spdif-out {
+   #sound-dai-cells = <0>;
+   compatible = "linux,spdif-dit";
+   };
+
sound-spdif {
compatible = "fsl,imx-audio-spdif";
model = "On-board SPDIF";
-   spdif-controller = <&spdif>;
-   spdif-out;
+   audio-cpu = <&spdif>;
+   audio-codec = <&spdif_out>;
};
 };
 
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-apalis.dtsi 
b/arch/arm/boot/dts/nxp/imx/imx6qdl-apalis.dtsi
index ea40623d12e5..6f4546c59d38 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-apalis.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-apalis.dtsi
@@ -197,11 +197,20 @@ sound {
ssi-controller = <&ssi1>;
};
 
+   spdif_out: spdif-out {
+   #sound-dai-cells = <0>;
+   compatible = "linux,spdif-dit";
+   };
+
+   spdif_in: spdif-in {
+   #sound-dai-cells = <0>;
+   compatible = "linux,spdif-dir";
+   };
+
sound_spdif: sound-spdif {
compatible = "fsl,imx-audio-spdif";
-   spdif-controller = <&spdif>;
-   spdif-in;
-   spdif-out;
+   audio-cpu = <&spdif>;
+   audio-codec = <&spdif_out>, <&spdif_in>;
model = "imx-spdif";
status = "disabled";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-apf6dev.dtsi 
b/arch/arm/boot/dts/nxp/imx/imx6qdl-apf6dev.dtsi
index 3a46ade3b6bd..6aa6b152c3ae 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-apf6dev.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-apf6dev.dtsi
@@ -121,11 +121,16 @@ sound {
mux-

Re: [PATCH v2 0/2] powerpc: kexec fixes

2024-06-20 Thread Michael Ellerman
On Fri, 10 May 2024 15:52:33 +0530, Sourabh Jain wrote:
> Patch series fixes two kexec issues.
> 
> 01/02: Update extra size calculation for kexec FDT to avoid kexec load
> failure due to FDT_ERR_NOSPACE while including CPU nodes added post
> boot and reserved memory ranges.
> 
> 02/02: Fix update_cpus_node/core_64.c function to include missing device
> nodes under /cpus node with device_type != "cpu".
> 
> [...]

Applied to powerpc/next.

[1/2] powerpc/kexec_file: fix extra size calculation for kexec FDT
  https://git.kernel.org/powerpc/c/0d3ff067331ef84e7e7f49537d768881042ed5ba
[2/2] powerpc/kexec_file: fix cpus node update to FDT
  https://git.kernel.org/powerpc/c/932bed41217059638c78a75411b7893b121d2162

cheers


Re: [PATCH v2 0/2] Fix doorbell emulation for v2 API on PPC

2024-06-20 Thread Michael Ellerman
On Wed, 05 Jun 2024 17:09:08 +0530, Gautam Menghani wrote:
> Doorbell emulation for KVM on PAPR guests is broken as support for DPDES
> was not added in initial patch series [1].
> Add DPDES support and doorbell handling support for V2 API.
> 
> [1] lore.kernel.org/linuxppc-dev/20230914030600.16993-1-jniet...@gmail.com
> 
> Changes in v2:
> 1. Split DPDES support into its own patch
> 
> [...]

Applied to powerpc/topic/ppc-kvm.

[1/2] arch/powerpc/kvm: Add DPDES support in helper library for Guest state 
buffer
  https://git.kernel.org/powerpc/c/55dfb8bed6fe8bda390cc71cca878d11a9407099
[2/2] arch/powerpc/kvm: Fix doorbell emulation for v2 API
  https://git.kernel.org/powerpc/c/54ec2bd9e0173b75daf84675d07c56584f96564b

cheers


Re: [PATCH v9] arch/powerpc/kvm: Add support for reading VPA counters for pseries guests

2024-06-20 Thread Michael Ellerman
On Mon, 20 May 2024 23:27:40 +0530, Gautam Menghani wrote:
> PAPR hypervisor has introduced three new counters in the VPA area of
> LPAR CPUs for KVM L2 guest (see [1] for terminology) observability - 2
> for context switches from host to guest and vice versa, and 1 counter
> for getting the total time spent inside the KVM guest. Add a tracepoint
> that enables reading the counters for use by ftrace/perf. Note that this
> tracepoint is only available for nestedv2 API (i.e, KVM on PowerVM).
> 
> [...]

Applied to powerpc/topic/ppc-kvm.

[1/1] arch/powerpc/kvm: Add support for reading VPA counters for pseries guests
  https://git.kernel.org/powerpc/c/e1f288d2f9c69bb8965db9fb99a19b58231a00dd

cheers


Re: [PATCH v2 0/8] KVM: PPC: Book3S HV: Nested guest migration fixes

2024-06-20 Thread Michael Ellerman
On Wed, 05 Jun 2024 13:06:00 +, Shivaprasad G Bhat wrote:
> The series fixes the issues exposed by the kvm-unit-tests[1]
> sprs-migration test.
> 
> The SDAR, MMCR3 were seen to have some typo/refactoring bugs.
> The first two patches fix them.
> 
> The remaining patches take care of save-restoring the guest
> state elements for DEXCR, HASHKEYR and HASHPKEYR SPRs with PHYP
> during entry-exit. The KVM_PPC_REG too for them are missing which
> are added for use by the QEMU.
> 
> [...]

Applied to powerpc/topic/ppc-kvm.

[1/8] KVM: PPC: Book3S HV: Fix the set_one_reg for MMCR3
  https://git.kernel.org/powerpc/c/f9ca6a10be20479d526f27316cc32cfd1785ed39
[2/8] KVM: PPC: Book3S HV: Fix the get_one_reg of SDAR
  https://git.kernel.org/powerpc/c/009f6f42c67e9de737d6d3d199f92b21a8cb9622
[3/8] KVM: PPC: Book3S HV: Add one-reg interface for DEXCR register
  https://git.kernel.org/powerpc/c/1a1e6865f516696adcf6e94f286c7a0f84d78df3
[4/8] KVM: PPC: Book3S HV nestedv2: Keep nested guest DEXCR in sync
  https://git.kernel.org/powerpc/c/2d6be3ca3276ab30fb14f285d400461a718d45e7
[5/8] KVM: PPC: Book3S HV: Add one-reg interface for HASHKEYR register
  https://git.kernel.org/powerpc/c/e9eb790b25577a15d3f450ed585c59048e4e6c44
[6/8] KVM: PPC: Book3S HV nestedv2: Keep nested guest HASHKEYR in sync
  https://git.kernel.org/powerpc/c/1e97c1eb785fe2dc863c2bd570030d6fcf4b5e5b
[7/8] KVM: PPC: Book3S HV: Add one-reg interface for HASHPKEYR register
  https://git.kernel.org/powerpc/c/9a0d2f4995ddde3022c54e43f9ece4f71f76f6e8
[8/8] KVM: PPC: Book3S HV nestedv2: Keep nested guest HASHPKEYR in sync
  https://git.kernel.org/powerpc/c/0b65365f3fa95c2c5e2094739151a05cabb3c48a

cheers


Re: [PATCH] tools/perf: Handle perftool-testsuite_probe testcases fail when kernel debuginfo is not present

2024-06-20 Thread Athira Rajeev



> On 20 Jun 2024, at 2:03 PM, James Clark  wrote:
> 
> 
> 
> On 18/06/2024 11:44, James Clark wrote:
>> 
>> 
>> On 17/06/2024 17:47, Athira Rajeev wrote:
>>> 
>>> 
 On 17 Jun 2024, at 8:30 PM, James Clark  wrote:
 
 
 
 On 17/06/2024 13:21, Athira Rajeev wrote:
> Running "perftool-testsuite_probe" fails as below:
> 
> ./perf test -v "perftool-testsuite_probe"
> 83: perftool-testsuite_probe  : FAILED
> 
> There are three fails:
> 
> 1. Regexp not found: "\s*probe:inode_permission(?:_\d+)?\s+\(on 
> inode_permission(?:[:\+][0-9A-Fa-f]+)?@.+\)"
>  -- [ FAIL ] -- perf_probe :: test_adding_kernel :: listing added probe 
> :: perf probe -l (output regexp parsing)
> 
 
 On a machine where NO_DEBUGINFO gets set, this one skips for me. But on
 a machine where there _is_ debug info this test still fails.
 
 But in both cases the probe looks like it was added successfully. So I'm
 wondering if this one does need to be skipped, or it's just always
 failing? Do you have this test passing anywhere where there is debug info?
 
 The list command looks like it successfully lists the probe for me in
 both cases, it just doesn't have an address on the end:
 
 perf list 'probe:*'
 
  probe:inode_permission (on inode_permission)
 
 Does the missing address mean anything or is it just not handled
 properly by the test?
 
 Ironically the machine that _does_ pass the debug info test also prints
 this, but it looks like it still adds and lists the probe correctly:
 
 perf probe -l probe:*
 
 Failed to find debug information for address 0x80008047ac30
   probe:inode_permission (on inode_permission)
>>> 
>>> Hi James,
>>> 
>>> Thanks for checking this patch.
>>> 
>>> In environment where kernel is compiled with debuginfo:
>>> 
>>> 1) Add probe point
>>> 
>>> # ./perf probe --add inode_permission
>>> Added new event:
>>>  probe:inode_permission (on inode_permission)
>>> 
>>> You can now use it in all perf tools, such as:
>>> 
>>> perf record -e probe:inode_permission -aR sleep 1
>>> 
>>> 
>>> 2) Check using perf probe -l
>>> 
>>> # ./perf probe -l
>>> probe:inode_permission (on inode_permission:2@fs/namei.c)
>>> 
>>> With debuginfo, the result has additional info.
>>> The test looks for matching pattern 
>>> "\s*probe:inode_permission(?:_\d+)?\s+\(on 
>>> inode_permission(?:[:\+][0-9A-Fa-f]+)?@.+\)” in result
>>> where it is expecting "inode_permission:2@fs/namei.c” . The “@fs/namei.c” 
>>> info needs debuginfo here.
>>> 
>> 
>> Hi Athira,
>> 
>> Maybe there is a real bug and this patch is ok to go in and we should leave
>> it as failing. Probe -L shows there is debug info available for 
>> inode_permission:
>> 
>>   $ ./perf probe -L inode_permission
>> 
>>  
>>  0  int inode_permission(struct mnt_idmap *idmap,
>> struct inode *inode, int mask)
>>  ... more source code ...
>> 
>> But probe -l has an error which could be related to the following
>> line not showing the filename details:
>> 
>>  $ ./perf probe -l
>> 
>>  Failed to find debug information for address 0x80008047ac30
>>probe:inode_permission (on inode_permission)
>> 
>> I'm running a clang kernel and sometimes I see issues with debug
>> info or toolchain stuff, that could be the reason.
>> 
>>> The function I am using in patch to check for debuginfo 
>>> (skip_if_no_debuginfo) is from "tests/shell/lib/probe_vfs_getname.sh"
>>> 
>>> skip_if_no_debuginfo() {
>>>add_probe_vfs_getname -v 2>&1 | grep -E -q "^(Failed to find the 
>>> path for the kernel|Debuginfo-analysis is not supported)|(file has no debug 
>>> information)" && return 2
>>>return 1
>>> }
>>> 
>>> So the debuginfo test passes in your case since the log has "Failed to find 
>>> debug information” which is not present in above grep string. 
>>> 
>> 
>> It passes because there is debug info for getname_flags() which is what the
>> debug info check looks for. After some greps and seds it ultimately does this
>> which succeeds:
>> 
>> $ perf probe "vfs_getname=getname_flags:72 pathname=result->name:string"
>> 
>> Added new event:
>>probe:vfs_getname(on getname_flags:72 with 
>> pathname=result->name:string)
>> 
>> "Failed to find debug information for address" is only ever printed
>> with "perf probe -l" when there are probes added. The stderr
>> of that command is never piped into any grep anyway, which is why I
>> see it on the test output.
>> 
>> So "probe -L" is working but "probe -l" isn't. Ultimately it looks like a 
>> real
>> issue and we should leave the failure in.
>> 
> 
> To avoid confusion, by leave it in I mean this debuginfo patch is ok and
> the failure I'm seeing is caused by something else.
> 
> Reviewed-by: James Clark 

Thanks James for the Reviewed-by,

Athira
> 
>>> James,
>>> 
>>> Only “perf probe -l” subtest fails with debuginfo enabled or other two 
>>> su

Re: [V4 00/16] Add data type profiling support for powerpc

2024-06-20 Thread Athira Rajeev



> On 14 Jun 2024, at 10:56 PM, Athira Rajeev  
> wrote:
> 
> The patchset from Namhyung added support for data type profiling
> in perf tool. This enabled support to associate PMU samples to data
> types they refer using DWARF debug information. With the upstream
> perf, currently it possible to run perf report or perf annotate to
> view the data type information on x86.
> 
> Initial patchset posted here had changes need to enable data type
> profiling support for powerpc.
> 
> https://lore.kernel.org/all/6e09dc28-4a2e-49d8-a2b5-ffb3396a9...@csgroup.eu/T/
> 
> Main change were:
> 1. powerpc instruction nmemonic table to associate load/store
> instructions with move_ops which is use to identify if instruction
> is a memory access one.
> 2. To get register number and access offset from the given
> instruction, code uses fields from "struct arch" -> objump.
> Added entry for powerpc here.
> 3. A get_arch_regnum to return register number from the
> register name string.
> 
> But the apporach used in the initial patchset used parsing of
> disassembled code which the current perf tool implementation does.
> 
> Example: lwz r10,0(r9)
> 
> This line "lwz r10,0(r9)" is parsed to extract instruction name,
> registers names and offset. Also to find whether there is a memory
> reference in the operands, "memory_ref_char" field of objdump is used.
> For x86, "(" is used as memory_ref_char to tackle instructions of the
> form "mov  (%rax), %rcx".
> 
> In case of powerpc, not all instructions using "(" are the only memory
> instructions. Example, above instruction can also be of extended form (X
> form) "lwzx r10,0,r19". Inorder to easy identify the instruction category
> and extract the source/target registers, second patchset added support to use
> raw instruction. With raw instruction, macros are added to extract opcode
> and register fields.
> Link to second patchset:
> https://lore.kernel.org/all/20240506121906.76639-1-atraj...@linux.vnet.ibm.com/
> 
> Example representation using --show-raw-insn in objdump gives result:
> 
> 38 01 81 e8 ld  r4,312(r1)
> 
> Here "38 01 81 e8" is the raw instruction representation. In powerpc,
> this translates to instruction form: "ld RT,DS(RA)" and binary code
> as:
>  _
>  | 58 |  RT  |  RA |  DS   | |
>  -
> 06 1116  30 31
> 
> Second patchset used "objdump" again to read the raw instruction.
> But since there is no need to disassemble and binary code can be read
> directly from the DSO, third patchset (ie this patchset) uses below
> apporach. The apporach preferred in powerpc to parse sample for data
> type profiling in V3 patchset is:
> - Read directly from DSO using dso__data_read_offset
> - If that fails for any case, fallback to using libcapstone
> - If libcapstone is not supported, approach will use objdump
> 
> Patchset adds support to pick the opcode and reg fields from this
> raw/binary instruction code. This approach came in from review comment
> by Segher Boessenkool and Christophe for the initial patchset.
> 
> Apart from that, instruction tracking is enabled for powerpc and
> support function is added to find variables defined as registers
> Example, in powerpc, below two registers are
> defined to represent variable:
> 1. r13: represents local_paca
> register struct paca_struct *local_paca asm("r13");
> 
> 2. r1: represents stack_pointer
> register void *__stack_pointer asm("r1");
> 
> These are handled in this patchset.
> 
> - Patch 1 is to rearrange register state type structures to header file
> so that it can referred from other arch specific files
> - Patch 2 is to make instruction tracking as a callback to"struct arch"
> so that it can be implemented by other archs easily and defined in arch
> specific files
> - Patch 3 adds support to capture and parse raw instruction in powerpc
> using dso__data_read_offset utility
> - Patch 4 adds logic to support using objdump when doing default "perf
> report" or "perf annotate" since it that needs disassembled instruction.
> - Patch 5 adds disasm_line__parse to parse raw instruction for powerpc
> - Patch 6 update parameters for reg extract functions to use raw
> instruction on powerpc
> - Patch 7 add support to identify memory instructions of opcode 31 in
> powerpc
> - Patch 8 adds more instructions to support instruction tracking in powerpc
> - Patch 9 and 10 handles instruction tracking for powerpc.
> - Patch 11, 12 and 13 add support to use libcapstone in powerpc
> - Patch 14 and patch 15 handles support to find global register variables
> - Patch 16 handles insn-stat option for perf annotate
> 
> Note:
> - There are remaining unknowns (25%) as seen in annotate Instruction stats
> below.
> - This patchset is not tested on powerpc32. In next step of enhancements
> along with handling remaining unknowns, plan to cover powerpc32 changes
> based on how testing goes.
> 
> With the current patchset:
> 
> ./

[PATCH 00/15] linux system call fixes

2024-06-20 Thread Arnd Bergmann
From: Arnd Bergmann 

I'm working on cleanup series for Linux system call handling, trying to
unify some of the architecture specific code there among other things.

In the process, I came across a number of bugs that are ABI relevant,
so I'm trying to merge these first. I found all of these by inspection,
not by running the code, so any extra review would help. I assume some
of the issues were already caught by existing LTP tests, while for others
we could add a test. Again, I did not check what is already there.

The sync_file_range and fadvise64_64 changes on sh, csky and hexagon
are likely to also require changes in the libc implementation.

Once the patches are reviewed, I plan to merge my changes as bugfixes
through the asm-generic tree, but architecture maintainers can also
pick them up directly to speed up the bugfix.

 Arnd

Cc: linux-a...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Cc: Thomas Bogendoerfer 
Cc: linux-m...@vger.kernel.org
Cc: Helge Deller 
Cc: linux-par...@vger.kernel.org
Cc: "David S. Miller" 
Cc: Andreas Larsson 
Cc: sparcli...@vger.kernel.org
Cc: Michael Ellerman 
Cc: Nicholas Piggin 
Cc: Christophe Leroy 
Cc: Naveen N. Rao 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Brian Cain 
Cc: linux-hexa...@vger.kernel.org
Cc: Guo Ren 
Cc: linux-c...@vger.kernel.org
Cc: Heiko Carstens 
Cc: linux-s...@vger.kernel.org
Cc: Rich Felker 
Cc: John Paul Adrian Glaubitz 
Cc: linux...@vger.kernel.org
Cc: "H. Peter Anvin" 
Cc: Alexander Viro 
Cc: Christian Brauner 
Cc: linux-fsde...@vger.kernel.org
Cc: libc-al...@sourceware.org
Cc: m...@lists.openwall.com
Cc: l...@lists.linux.it

Arnd Bergmann (15):
  ftruncate: pass a signed offset
  syscalls: fix compat_sys_io_pgetevents_time64 usage
  mips: fix compat_sys_lseek syscall
  sparc: fix old compat_sys_select()
  sparc: fix compat recv/recvfrom syscalls
  parisc: use correct compat recv/recvfrom syscalls
  parisc: use generic sys_fanotify_mark implementation
  powerpc: restore some missing spu syscalls
  sh: rework sync_file_range ABI
  csky, hexagon: fix broken sys_sync_file_range
  hexagon: fix fadvise64_64 calling conventions
  s390: remove native mmap2() syscall
  syscalls: mmap(): use unsigned offset type consistently
  asm-generic: unistd: fix time32 compat syscall handling
  linux/syscalls.h: add missing __user annotations

 arch/arm64/include/asm/unistd32.h |   2 +-
 arch/csky/include/uapi/asm/unistd.h   |   1 +
 arch/csky/kernel/syscall.c|   2 +-
 arch/hexagon/include/asm/syscalls.h   |   6 +
 arch/hexagon/include/uapi/asm/unistd.h|   1 +
 arch/hexagon/kernel/syscalltab.c  |   7 +
 arch/loongarch/kernel/syscall.c   |   2 +-
 arch/microblaze/kernel/sys_microblaze.c   |   2 +-
 arch/mips/kernel/syscalls/syscall_n32.tbl |   2 +-
 arch/mips/kernel/syscalls/syscall_o32.tbl |   4 +-
 arch/parisc/Kconfig   |   1 +
 arch/parisc/kernel/sys_parisc32.c |   9 -
 arch/parisc/kernel/syscalls/syscall.tbl   |   6 +-
 arch/powerpc/kernel/syscalls/syscall.tbl  |   6 +-
 arch/riscv/kernel/sys_riscv.c |   4 +-
 arch/s390/kernel/syscall.c|  27 ---
 arch/s390/kernel/syscalls/syscall.tbl |   2 +-
 arch/sh/kernel/sys_sh32.c |  11 ++
 arch/sh/kernel/syscalls/syscall.tbl   |   3 +-
 arch/sparc/kernel/sys32.S | 221 --
 arch/sparc/kernel/syscalls/syscall.tbl|   8 +-
 arch/x86/entry/syscalls/syscall_32.tbl|   2 +-
 fs/open.c |   4 +-
 include/asm-generic/syscalls.h|   2 +-
 include/linux/compat.h|   2 +-
 include/linux/syscalls.h  |  20 +-
 include/uapi/asm-generic/unistd.h | 146 +-
 27 files changed, 160 insertions(+), 343 deletions(-)
 create mode 100644 arch/hexagon/include/asm/syscalls.h

-- 
2.39.2



[PATCH 01/15] ftruncate: pass a signed offset

2024-06-20 Thread Arnd Bergmann
From: Arnd Bergmann 

The old ftruncate() syscall, using the 32-bit off_t misses a sign
extension when called in compat mode on 64-bit architectures.  As a
result, passing a negative length accidentally succeeds in truncating
to file size between 2GiB and 4GiB.

Changing the type of the compat syscall to the signed compat_off_t
changes the behavior so it instead returns -EINVAL.

The native entry point, the truncate() syscall and the corresponding
loff_t based variants are all correct already and do not suffer
from this mistake.

Fixes: 3f6d078d4acc ("fix compat truncate/ftruncate")
Cc: sta...@vger.kernel.org
Signed-off-by: Arnd Bergmann 
---
 fs/open.c| 4 ++--
 include/linux/compat.h   | 2 +-
 include/linux/syscalls.h | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/open.c b/fs/open.c
index 89cafb572061..50e45bc7c4d8 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -202,13 +202,13 @@ long do_sys_ftruncate(unsigned int fd, loff_t length, int 
small)
return error;
 }
 
-SYSCALL_DEFINE2(ftruncate, unsigned int, fd, unsigned long, length)
+SYSCALL_DEFINE2(ftruncate, unsigned int, fd, off_t, length)
 {
return do_sys_ftruncate(fd, length, 1);
 }
 
 #ifdef CONFIG_COMPAT
-COMPAT_SYSCALL_DEFINE2(ftruncate, unsigned int, fd, compat_ulong_t, length)
+COMPAT_SYSCALL_DEFINE2(ftruncate, unsigned int, fd, compat_off_t, length)
 {
return do_sys_ftruncate(fd, length, 1);
 }
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 233f61ec8afc..56cebaff0c91 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -608,7 +608,7 @@ asmlinkage long compat_sys_fstatfs(unsigned int fd,
 asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz,
 struct compat_statfs64 __user *buf);
 asmlinkage long compat_sys_truncate(const char __user *, compat_off_t);
-asmlinkage long compat_sys_ftruncate(unsigned int, compat_ulong_t);
+asmlinkage long compat_sys_ftruncate(unsigned int, compat_off_t);
 /* No generic prototype for truncate64, ftruncate64, fallocate */
 asmlinkage long compat_sys_openat(int dfd, const char __user *filename,
  int flags, umode_t mode);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 9104952d323d..ba9337709878 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -418,7 +418,7 @@ asmlinkage long sys_listmount(const struct mnt_id_req 
__user *req,
  u64 __user *mnt_ids, size_t nr_mnt_ids,
  unsigned int flags);
 asmlinkage long sys_truncate(const char __user *path, long length);
-asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length);
+asmlinkage long sys_ftruncate(unsigned int fd, off_t length);
 #if BITS_PER_LONG == 32
 asmlinkage long sys_truncate64(const char __user *path, loff_t length);
 asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length);
-- 
2.39.2



[PATCH 02/15] syscalls: fix compat_sys_io_pgetevents_time64 usage

2024-06-20 Thread Arnd Bergmann
From: Arnd Bergmann 

Using sys_io_pgetevents() as the entry point for compat mode tasks
works almost correctly, but misses the sign extension for the min_nr
and nr arguments.

This was addressed on parisc by switching to
compat_sys_io_pgetevents_time64() in commit 6431e92fc827 ("parisc:
io_pgetevents_time64() needs compat syscall in 32-bit compat mode"),
as well as by using more sophisticated system call wrappers on x86 and
s390. However, arm64, mips, powerpc, sparc and riscv still have the
same bug.

Changes all of them over to use compat_sys_io_pgetevents_time64()
like parisc already does. This was clearly the intention when the
function was originally added, but it got hooked up incorrectly in
the tables.

Cc: sta...@vger.kernel.org
Fixes: 48166e6ea47d ("y2038: add 64-bit time_t syscalls to all 32-bit 
architectures")
Signed-off-by: Arnd Bergmann 
---
 arch/arm64/include/asm/unistd32.h | 2 +-
 arch/mips/kernel/syscalls/syscall_n32.tbl | 2 +-
 arch/mips/kernel/syscalls/syscall_o32.tbl | 2 +-
 arch/powerpc/kernel/syscalls/syscall.tbl  | 2 +-
 arch/s390/kernel/syscalls/syscall.tbl | 2 +-
 arch/sparc/kernel/syscalls/syscall.tbl| 2 +-
 arch/x86/entry/syscalls/syscall_32.tbl| 2 +-
 include/uapi/asm-generic/unistd.h | 2 +-
 8 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/unistd32.h 
b/arch/arm64/include/asm/unistd32.h
index 266b96acc014..1386e8e751f2 100644
--- a/arch/arm64/include/asm/unistd32.h
+++ b/arch/arm64/include/asm/unistd32.h
@@ -840,7 +840,7 @@ __SYSCALL(__NR_pselect6_time64, compat_sys_pselect6_time64)
 #define __NR_ppoll_time64 414
 __SYSCALL(__NR_ppoll_time64, compat_sys_ppoll_time64)
 #define __NR_io_pgetevents_time64 416
-__SYSCALL(__NR_io_pgetevents_time64, sys_io_pgetevents)
+__SYSCALL(__NR_io_pgetevents_time64, compat_sys_io_pgetevents_time64)
 #define __NR_recvmmsg_time64 417
 __SYSCALL(__NR_recvmmsg_time64, compat_sys_recvmmsg_time64)
 #define __NR_mq_timedsend_time64 418
diff --git a/arch/mips/kernel/syscalls/syscall_n32.tbl 
b/arch/mips/kernel/syscalls/syscall_n32.tbl
index cc869f5d5693..953f5b7dc723 100644
--- a/arch/mips/kernel/syscalls/syscall_n32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_n32.tbl
@@ -354,7 +354,7 @@
 412n32 utimensat_time64sys_utimensat
 413n32 pselect6_time64 compat_sys_pselect6_time64
 414n32 ppoll_time64compat_sys_ppoll_time64
-416n32 io_pgetevents_time64sys_io_pgetevents
+416n32 io_pgetevents_time64compat_sys_io_pgetevents_time64
 417n32 recvmmsg_time64 compat_sys_recvmmsg_time64
 418n32 mq_timedsend_time64 sys_mq_timedsend
 419n32 mq_timedreceive_time64  sys_mq_timedreceive
diff --git a/arch/mips/kernel/syscalls/syscall_o32.tbl 
b/arch/mips/kernel/syscalls/syscall_o32.tbl
index 008ebe60263e..85751c9b9cdb 100644
--- a/arch/mips/kernel/syscalls/syscall_o32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_o32.tbl
@@ -403,7 +403,7 @@
 412o32 utimensat_time64sys_utimensat   
sys_utimensat
 413o32 pselect6_time64 sys_pselect6
compat_sys_pselect6_time64
 414o32 ppoll_time64sys_ppoll   
compat_sys_ppoll_time64
-416o32 io_pgetevents_time64sys_io_pgetevents   
sys_io_pgetevents
+416o32 io_pgetevents_time64sys_io_pgetevents   
compat_sys_io_pgetevents_time64
 417o32 recvmmsg_time64 sys_recvmmsg
compat_sys_recvmmsg_time64
 418o32 mq_timedsend_time64 sys_mq_timedsend
sys_mq_timedsend
 419o32 mq_timedreceive_time64  sys_mq_timedreceive 
sys_mq_timedreceive
diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl 
b/arch/powerpc/kernel/syscalls/syscall.tbl
index 3656f1ca7a21..c6b0546b284d 100644
--- a/arch/powerpc/kernel/syscalls/syscall.tbl
+++ b/arch/powerpc/kernel/syscalls/syscall.tbl
@@ -502,7 +502,7 @@
 41232  utimensat_time64sys_utimensat   
sys_utimensat
 41332  pselect6_time64 sys_pselect6
compat_sys_pselect6_time64
 41432  ppoll_time64sys_ppoll   
compat_sys_ppoll_time64
-41632  io_pgetevents_time64sys_io_pgetevents   
sys_io_pgetevents
+41632  io_pgetevents_time64sys_io_pgetevents   
compat_sys_io_pgetevents_time64
 41732  recvmmsg_time64 sys_recvmmsg
compat_sys_recvmmsg_time64
 41832  mq_timedsend_time64 sys_mq_timedsend
sys_mq_timedsend
 41932  mq_timedreceive_time64  sys_mq_timedreceive 
sys_mq_timedreceive
diff --git a/arch/s390/kernel

[PATCH 03/15] mips: fix compat_sys_lseek syscall

2024-06-20 Thread Arnd Bergmann
From: Arnd Bergmann 

This is almost compatible, but passing a negative offset should result
in a EINVAL error, but on mips o32 compat mode would seek to a large
32-bit byte offset.

Use compat_sys_lseek() to correctly sign-extend the argument.

Signed-off-by: Arnd Bergmann 
---
 arch/mips/kernel/syscalls/syscall_o32.tbl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/kernel/syscalls/syscall_o32.tbl 
b/arch/mips/kernel/syscalls/syscall_o32.tbl
index 85751c9b9cdb..2439a2491cff 100644
--- a/arch/mips/kernel/syscalls/syscall_o32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_o32.tbl
@@ -27,7 +27,7 @@
 17 o32 break   sys_ni_syscall
 # 18 was sys_stat
 18 o32 unused18sys_ni_syscall
-19 o32 lseek   sys_lseek
+19 o32 lseek   sys_lseek   
compat_sys_lseek
 20 o32 getpid  sys_getpid
 21 o32 mount   sys_mount
 22 o32 umount  sys_oldumount
-- 
2.39.2



[PATCH 04/15] sparc: fix old compat_sys_select()

2024-06-20 Thread Arnd Bergmann
From: Arnd Bergmann 

sparc has two identical select syscalls at numbers 93 and 230, respectively.
During the conversion to the modern syscall.tbl format, the older one of the
two broke in compat mode, and now refers to the native 64-bit syscall.

Restore the correct behavior. This has very little effect, as glibc has
been using the newer number anyway.

Fixes: 6ff645dd683a ("sparc: add system call table generation support")
Signed-off-by: Arnd Bergmann 
---
 arch/sparc/kernel/syscalls/syscall.tbl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/sparc/kernel/syscalls/syscall.tbl 
b/arch/sparc/kernel/syscalls/syscall.tbl
index b354139b40be..5e55f73f9880 100644
--- a/arch/sparc/kernel/syscalls/syscall.tbl
+++ b/arch/sparc/kernel/syscalls/syscall.tbl
@@ -117,7 +117,7 @@
 90 common  dup2sys_dup2
 91 32  setfsuid32  sys_setfsuid
 92 common  fcntl   sys_fcntl   
compat_sys_fcntl
-93 common  select  sys_select
+93 common  select  sys_select  
compat_sys_select
 94 32  setfsgid32  sys_setfsgid
 95 common  fsync   sys_fsync
 96 common  setpriority sys_setpriority
-- 
2.39.2



[PATCH 05/15] sparc: fix compat recv/recvfrom syscalls

2024-06-20 Thread Arnd Bergmann
From: Arnd Bergmann 

sparc has the wrong compat version of recv() and recvfrom() for both the
direct syscalls and socketcall().

The direct syscalls just need to use the compat version. For socketcall,
the same thing could be done, but it seems better to completely remove
the custom assembler code for it and just use the same implementation that
everyone else has.

Fixes: 1dacc76d0014 ("net/compat/wext: send different messages to compat tasks")
Signed-off-by: Arnd Bergmann 
---
 arch/sparc/kernel/sys32.S  | 221 -
 arch/sparc/kernel/syscalls/syscall.tbl |   4 +-
 2 files changed, 2 insertions(+), 223 deletions(-)

diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S
index a45f0f31fe51..a3d308f2043e 100644
--- a/arch/sparc/kernel/sys32.S
+++ b/arch/sparc/kernel/sys32.S
@@ -18,224 +18,3 @@ sys32_mmap2:
sethi   %hi(sys_mmap), %g1
jmpl%g1 + %lo(sys_mmap), %g0
 sllx   %o5, 12, %o5
-
-   .align  32
-   .globl  sys32_socketcall
-sys32_socketcall:  /* %o0=call, %o1=args */
-   cmp %o0, 1
-   bl,pn   %xcc, do_einval
-cmp%o0, 18
-   bg,pn   %xcc, do_einval
-sub%o0, 1, %o0
-   sllx%o0, 5, %o0
-   sethi   %hi(__socketcall_table_begin), %g2
-   or  %g2, %lo(__socketcall_table_begin), %g2
-   jmpl%g2 + %o0, %g0
-nop
-do_einval:
-   retl
-mov-EINVAL, %o0
-
-   .align  32
-__socketcall_table_begin:
-
-   /* Each entry is exactly 32 bytes. */
-do_sys_socket: /* sys_socket(int, int, int) */
-1: ldswa   [%o1 + 0x0] %asi, %o0
-   sethi   %hi(sys_socket), %g1
-2: ldswa   [%o1 + 0x8] %asi, %o2
-   jmpl%g1 + %lo(sys_socket), %g0
-3:  ldswa  [%o1 + 0x4] %asi, %o1
-   nop
-   nop
-   nop
-do_sys_bind: /* sys_bind(int fd, struct sockaddr *, int) */
-4: ldswa   [%o1 + 0x0] %asi, %o0
-   sethi   %hi(sys_bind), %g1
-5: ldswa   [%o1 + 0x8] %asi, %o2
-   jmpl%g1 + %lo(sys_bind), %g0
-6:  lduwa  [%o1 + 0x4] %asi, %o1
-   nop
-   nop
-   nop
-do_sys_connect: /* sys_connect(int, struct sockaddr *, int) */
-7: ldswa   [%o1 + 0x0] %asi, %o0
-   sethi   %hi(sys_connect), %g1
-8: ldswa   [%o1 + 0x8] %asi, %o2
-   jmpl%g1 + %lo(sys_connect), %g0
-9:  lduwa  [%o1 + 0x4] %asi, %o1
-   nop
-   nop
-   nop
-do_sys_listen: /* sys_listen(int, int) */
-10:ldswa   [%o1 + 0x0] %asi, %o0
-   sethi   %hi(sys_listen), %g1
-   jmpl%g1 + %lo(sys_listen), %g0
-11: ldswa  [%o1 + 0x4] %asi, %o1
-   nop
-   nop
-   nop
-   nop
-do_sys_accept: /* sys_accept(int, struct sockaddr *, int *) */
-12:ldswa   [%o1 + 0x0] %asi, %o0
-   sethi   %hi(sys_accept), %g1
-13:lduwa   [%o1 + 0x8] %asi, %o2
-   jmpl%g1 + %lo(sys_accept), %g0
-14: lduwa  [%o1 + 0x4] %asi, %o1
-   nop
-   nop
-   nop
-do_sys_getsockname: /* sys_getsockname(int, struct sockaddr *, int *) */
-15:ldswa   [%o1 + 0x0] %asi, %o0
-   sethi   %hi(sys_getsockname), %g1
-16:lduwa   [%o1 + 0x8] %asi, %o2
-   jmpl%g1 + %lo(sys_getsockname), %g0
-17: lduwa  [%o1 + 0x4] %asi, %o1
-   nop
-   nop
-   nop
-do_sys_getpeername: /* sys_getpeername(int, struct sockaddr *, int *) */
-18:ldswa   [%o1 + 0x0] %asi, %o0
-   sethi   %hi(sys_getpeername), %g1
-19:lduwa   [%o1 + 0x8] %asi, %o2
-   jmpl%g1 + %lo(sys_getpeername), %g0
-20: lduwa  [%o1 + 0x4] %asi, %o1
-   nop
-   nop
-   nop
-do_sys_socketpair: /* sys_socketpair(int, int, int, int *) */
-21:ldswa   [%o1 + 0x0] %asi, %o0
-   sethi   %hi(sys_socketpair), %g1
-22:ldswa   [%o1 + 0x8] %asi, %o2
-23:lduwa   [%o1 + 0xc] %asi, %o3
-   jmpl%g1 + %lo(sys_socketpair), %g0
-24: ldswa  [%o1 + 0x4] %asi, %o1
-   nop
-   nop
-do_sys_send: /* sys_send(int, void *, size_t, unsigned int) */
-25:ldswa   [%o1 + 0x0] %asi, %o0
-   sethi   %hi(sys_send), %g1
-26:lduwa   [%o1 + 0x8] %asi, %o2
-27:lduwa   [%o1 + 0xc] %asi, %o3
-   jmpl%g1 + %lo(sys_send), %g0
-28: lduwa  [%o1 + 0x4] %asi, %o1
-   nop
-   nop
-do_sys_recv: /* sys_recv(int, void *, size_t, unsigned int) */
-29:ldswa   [%o1 + 0x0] %asi, %o0
-   sethi   %hi(sys_recv), %g1
-30:lduwa   [%o1 + 0x8] %asi, %o2
-31:lduwa   [%o1 + 0xc] %asi, %o3
-   jmpl%g1 + %lo(sys_recv), %g

[PATCH 06/15] parisc: use correct compat recv/recvfrom syscalls

2024-06-20 Thread Arnd Bergmann
From: Arnd Bergmann 

Johannes missed parisc back when he introduced the compat version
of these syscalls, so receiving cmsg messages that require a compat
conversion is still broken.

Use the correct calls like the other architectures do.

Fixes: 1dacc76d0014 ("net/compat/wext: send different messages to compat tasks")
Signed-off-by: Arnd Bergmann 
---
 arch/parisc/kernel/syscalls/syscall.tbl | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/parisc/kernel/syscalls/syscall.tbl 
b/arch/parisc/kernel/syscalls/syscall.tbl
index b13c21373974..39e67fab7515 100644
--- a/arch/parisc/kernel/syscalls/syscall.tbl
+++ b/arch/parisc/kernel/syscalls/syscall.tbl
@@ -108,7 +108,7 @@
 95 common  fchown  sys_fchown
 96 common  getpriority sys_getpriority
 97 common  setpriority sys_setpriority
-98 common  recvsys_recv
+98 common  recvsys_recv
compat_sys_recv
 99 common  statfs  sys_statfs  
compat_sys_statfs
 100common  fstatfs sys_fstatfs 
compat_sys_fstatfs
 101common  stat64  sys_stat64
@@ -135,7 +135,7 @@
 120common  clone   sys_clone_wrapper
 121common  setdomainname   sys_setdomainname
 122common  sendfilesys_sendfile
compat_sys_sendfile
-123common  recvfromsys_recvfrom
+123common  recvfromsys_recvfrom
compat_sys_recvfrom
 12432  adjtimexsys_adjtimex_time32
 12464  adjtimexsys_adjtimex
 125common  mprotectsys_mprotect
-- 
2.39.2



[PATCH 07/15] parisc: use generic sys_fanotify_mark implementation

2024-06-20 Thread Arnd Bergmann
From: Arnd Bergmann 

The sys_fanotify_mark() syscall on parisc uses the reverse word order
for the two halves of the 64-bit argument compared to all syscalls on
all 32-bit architectures. As far as I can tell, the problem is that
the function arguments on parisc are sorted backwards (26, 25, 24, 23,
...) compared to everyone else, so the calling conventions of using an
even/odd register pair in native word order result in the lower word
coming first in function arguments, matching the expected behavior
on little-endian architectures. The system call conventions however
ended up matching what the other 32-bit architectures do.

A glibc cleanup in 2020 changed the userspace behavior in a way that
handles all architectures consistently, but this inadvertently broke
parisc32 by changing to the same method as everyone else.

The change made it into glibc-2.35 and subsequently into debian 12
(bookworm), which is the latest stable release. This means we
need to choose between reverting the glibc change or changing the
kernel to match it again, but either hange will leave some systems
broken.

Pick the option that is more likely to help current and future
users and change the kernel to match current glibc. This also
means the behavior is now consistent across architectures, but
it breaks running new kernels with old glibc builds before 2.35.

Link: https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=d150181d73d9
Link: 
https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/commit/arch/parisc/kernel/sys_parisc.c?h=57b1dfbd5b4a39d
Cc: Adhemerval Zanella 
Signed-off-by: Arnd Bergmann 
---
I found this through code inspection, please double-check to make
sure I got the bug and the fix right.

The alternative is to fix this by reverting glibc back to the
unusual behavior.
---
 arch/parisc/Kconfig | 1 +
 arch/parisc/kernel/sys_parisc32.c   | 9 -
 arch/parisc/kernel/syscalls/syscall.tbl | 2 +-
 3 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index daafeb20f993..dc9b902de8ea 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -16,6 +16,7 @@ config PARISC
select ARCH_HAS_UBSAN
select ARCH_HAS_PTE_SPECIAL
select ARCH_NO_SG_CHAIN
+   select ARCH_SPLIT_ARG64 if !64BIT
select ARCH_SUPPORTS_HUGETLBFS if PA20
select ARCH_SUPPORTS_MEMORY_FAILURE
select ARCH_STACKWALK
diff --git a/arch/parisc/kernel/sys_parisc32.c 
b/arch/parisc/kernel/sys_parisc32.c
index 2a12a547b447..826c8e51b585 100644
--- a/arch/parisc/kernel/sys_parisc32.c
+++ b/arch/parisc/kernel/sys_parisc32.c
@@ -23,12 +23,3 @@ asmlinkage long sys32_unimplemented(int r26, int r25, int 
r24, int r23,
current->comm, current->pid, r20);
 return -ENOSYS;
 }
-
-asmlinkage long sys32_fanotify_mark(compat_int_t fanotify_fd, compat_uint_t 
flags,
-   compat_uint_t mask0, compat_uint_t mask1, compat_int_t dfd,
-   const char  __user * pathname)
-{
-   return sys_fanotify_mark(fanotify_fd, flags,
-   ((__u64)mask1 << 32) | mask0,
-dfd, pathname);
-}
diff --git a/arch/parisc/kernel/syscalls/syscall.tbl 
b/arch/parisc/kernel/syscalls/syscall.tbl
index 39e67fab7515..66dc406b12e4 100644
--- a/arch/parisc/kernel/syscalls/syscall.tbl
+++ b/arch/parisc/kernel/syscalls/syscall.tbl
@@ -364,7 +364,7 @@
 320common  accept4 sys_accept4
 321common  prlimit64   sys_prlimit64
 322common  fanotify_init   sys_fanotify_init
-323common  fanotify_mark   sys_fanotify_mark   
sys32_fanotify_mark
+323common  fanotify_mark   sys_fanotify_mark   
compat_sys_fanotify_mark
 32432  clock_adjtime   sys_clock_adjtime32
 32464  clock_adjtime   sys_clock_adjtime
 325common  name_to_handle_at   sys_name_to_handle_at
-- 
2.39.2



[PATCH 08/15] powerpc: restore some missing spu syscalls

2024-06-20 Thread Arnd Bergmann
From: Arnd Bergmann 

A couple of system calls were inadventently removed from the table during
a bugfix for 32-bit powerpc entry. Restore the original behavior.

Fixes: e23750623835 ("powerpc/32: fix syscall wrappers with 64-bit arguments of 
unaligned register-pairs")
Signed-off-by: Arnd Bergmann 
---
 arch/powerpc/kernel/syscalls/syscall.tbl | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl 
b/arch/powerpc/kernel/syscalls/syscall.tbl
index c6b0546b284d..ebae8415dfbb 100644
--- a/arch/powerpc/kernel/syscalls/syscall.tbl
+++ b/arch/powerpc/kernel/syscalls/syscall.tbl
@@ -230,8 +230,10 @@
 178nospu   rt_sigsuspend   sys_rt_sigsuspend   
compat_sys_rt_sigsuspend
 17932  pread64 sys_ppc_pread64 
compat_sys_ppc_pread64
 17964  pread64 sys_pread64
+179spu pread64 sys_pread64
 18032  pwrite64sys_ppc_pwrite64
compat_sys_ppc_pwrite64
 18064  pwrite64sys_pwrite64
+180spu pwrite64sys_pwrite64
 181common  chown   sys_chown
 182common  getcwd  sys_getcwd
 183common  capget  sys_capget
@@ -246,6 +248,7 @@
 190common  ugetrlimit  sys_getrlimit   
compat_sys_getrlimit
 19132  readahead   sys_ppc_readahead   
compat_sys_ppc_readahead
 19164  readahead   sys_readahead
+191spu readahead   sys_readahead
 19232  mmap2   sys_mmap2   
compat_sys_mmap2
 19332  truncate64  sys_ppc_truncate64  
compat_sys_ppc_truncate64
 19432  ftruncate64 sys_ppc_ftruncate64 
compat_sys_ppc_ftruncate64
@@ -293,6 +296,7 @@
 232nospu   set_tid_address sys_set_tid_address
 23332  fadvise64   sys_ppc32_fadvise64 
compat_sys_ppc32_fadvise64
 23364  fadvise64   sys_fadvise64
+233spu fadvise64   sys_fadvise64
 234nospu   exit_group  sys_exit_group
 235nospu   lookup_dcookie  sys_ni_syscall
 236common  epoll_createsys_epoll_create
-- 
2.39.2



[PATCH 09/15] sh: rework sync_file_range ABI

2024-06-20 Thread Arnd Bergmann
From: Arnd Bergmann 

The unusual function calling conventions on superh ended up causing
sync_file_range to have the wrong argument order, with the 'flags'
argument getting sorted before 'nbytes' by the compiler.

In userspace, I found that musl, glibc, uclibc and strace all expect the
normal calling conventions with 'nbytes' last, so changing the kernel
to match them should make all of those work.

In order to be able to also fix libc implementations to work with existing
kernels, they need to be able to tell which ABI is used. An easy way
to do this is to add yet another system call using the sync_file_range2
ABI that works the same on all architectures.

Old user binaries can now work on new kernels, and new binaries can
try the new sync_file_range2() to work with new kernels or fall back
to the old sync_file_range() version if that doesn't exist.

Cc: sta...@vger.kernel.org
Fixes: 75c92acdd5b1 ("sh: Wire up new syscalls.")
Signed-off-by: Arnd Bergmann 
---
 arch/sh/kernel/sys_sh32.c   | 11 +++
 arch/sh/kernel/syscalls/syscall.tbl |  3 ++-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/sh/kernel/sys_sh32.c b/arch/sh/kernel/sys_sh32.c
index 9dca568509a5..d5a4f7c697d8 100644
--- a/arch/sh/kernel/sys_sh32.c
+++ b/arch/sh/kernel/sys_sh32.c
@@ -59,3 +59,14 @@ asmlinkage int sys_fadvise64_64_wrapper(int fd, u32 offset0, 
u32 offset1,
 (u64)len0 << 32 | len1, advice);
 #endif
 }
+
+/*
+ * swap the arguments the way that libc wants it instead of
+ * moving flags ahead of the 64-bit nbytes argument
+ */
+SYSCALL_DEFINE6(sh_sync_file_range6, int, fd, SC_ARG64(offset),
+SC_ARG64(nbytes), unsigned int, flags)
+{
+return ksys_sync_file_range(fd, SC_VAL64(loff_t, offset),
+SC_VAL64(loff_t, nbytes), flags);
+}
diff --git a/arch/sh/kernel/syscalls/syscall.tbl 
b/arch/sh/kernel/syscalls/syscall.tbl
index bbf83a2db986..c55fd7696d40 100644
--- a/arch/sh/kernel/syscalls/syscall.tbl
+++ b/arch/sh/kernel/syscalls/syscall.tbl
@@ -321,7 +321,7 @@
 311common  set_robust_list sys_set_robust_list
 312common  get_robust_list sys_get_robust_list
 313common  splice  sys_splice
-314common  sync_file_range sys_sync_file_range
+314common  sync_file_range sys_sh_sync_file_range6
 315common  tee sys_tee
 316common  vmsplicesys_vmsplice
 317common  move_pages  sys_move_pages
@@ -395,6 +395,7 @@
 385common  pkey_alloc  sys_pkey_alloc
 386common  pkey_free   sys_pkey_free
 387common  rseqsys_rseq
+388common  sync_file_range2sys_sync_file_range2
 # room for arch specific syscalls
 393common  semget  sys_semget
 394common  semctl  sys_semctl
-- 
2.39.2



[PATCH 10/15] csky, hexagon: fix broken sys_sync_file_range

2024-06-20 Thread Arnd Bergmann
From: Arnd Bergmann 

Both of these architectures require u64 function arguments to be
passed in even/odd pairs of registers or stack slots, which in case of
sync_file_range would result in a seven-argument system call that is
not currently possible. The system call is therefore incompatible with
all existing binaries.

While it would be possible to implement support for seven arguments
like on mips, it seems better to use a six-argument version, either
with the normal argument order but misaligned as on most architectures
or with the reordered sync_file_range2() calling conventions as on
arm and powerpc.

Cc: sta...@vger.kernel.org
Signed-off-by: Arnd Bergmann 
---
 arch/csky/include/uapi/asm/unistd.h| 1 +
 arch/hexagon/include/uapi/asm/unistd.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/csky/include/uapi/asm/unistd.h 
b/arch/csky/include/uapi/asm/unistd.h
index 7ff6a2466af1..e0594b6370a6 100644
--- a/arch/csky/include/uapi/asm/unistd.h
+++ b/arch/csky/include/uapi/asm/unistd.h
@@ -6,6 +6,7 @@
 #define __ARCH_WANT_SYS_CLONE3
 #define __ARCH_WANT_SET_GET_RLIMIT
 #define __ARCH_WANT_TIME32_SYSCALLS
+#define __ARCH_WANT_SYNC_FILE_RANGE2
 #include 
 
 #define __NR_set_thread_area   (__NR_arch_specific_syscall + 0)
diff --git a/arch/hexagon/include/uapi/asm/unistd.h 
b/arch/hexagon/include/uapi/asm/unistd.h
index 432c4db1b623..21ae22306b5d 100644
--- a/arch/hexagon/include/uapi/asm/unistd.h
+++ b/arch/hexagon/include/uapi/asm/unistd.h
@@ -36,5 +36,6 @@
 #define __ARCH_WANT_SYS_VFORK
 #define __ARCH_WANT_SYS_FORK
 #define __ARCH_WANT_TIME32_SYSCALLS
+#define __ARCH_WANT_SYNC_FILE_RANGE2
 
 #include 
-- 
2.39.2



[PATCH 11/15] hexagon: fix fadvise64_64 calling conventions

2024-06-20 Thread Arnd Bergmann
From: Arnd Bergmann 

fadvise64_64() has two 64-bit arguments at the wrong alignment
for hexagon, which turns them into a 7-argument syscall that is
not supported by Linux.

The downstream musl port for hexagon actually asks for a 6-argument
version the same way we do it on arm, csky, powerpc, so make the
kernel do it the same way to avoid having to change both.

Link: https://github.com/quic/musl/blob/hexagon/arch/hexagon/syscall_arch.h#L78
Cc: sta...@vger.kernel.org
Signed-off-by: Arnd Bergmann 
---
 arch/hexagon/include/asm/syscalls.h | 6 ++
 arch/hexagon/kernel/syscalltab.c| 7 +++
 2 files changed, 13 insertions(+)
 create mode 100644 arch/hexagon/include/asm/syscalls.h

diff --git a/arch/hexagon/include/asm/syscalls.h 
b/arch/hexagon/include/asm/syscalls.h
new file mode 100644
index ..40f2d08bec92
--- /dev/null
+++ b/arch/hexagon/include/asm/syscalls.h
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include 
+
+asmlinkage long sys_hexagon_fadvise64_64(int fd, int advice,
+ u32 a2, u32 a3, u32 a4, u32 a5);
diff --git a/arch/hexagon/kernel/syscalltab.c b/arch/hexagon/kernel/syscalltab.c
index 0fadd582cfc7..5d98bdc494ec 100644
--- a/arch/hexagon/kernel/syscalltab.c
+++ b/arch/hexagon/kernel/syscalltab.c
@@ -14,6 +14,13 @@
 #undef __SYSCALL
 #define __SYSCALL(nr, call) [nr] = (call),
 
+SYSCALL_DEFINE6(hexagon_fadvise64_64, int, fd, int, advice,
+   SC_ARG64(offset), SC_ARG64(len))
+{
+   return ksys_fadvise64_64(fd, SC_VAL64(loff_t, offset), SC_VAL64(loff_t, 
len), advice);
+}
+#define sys_fadvise64_64 sys_hexagon_fadvise64_64
+
 void *sys_call_table[__NR_syscalls] = {
 #include 
 };
-- 
2.39.2



[PATCH 12/15] s390: remove native mmap2() syscall

2024-06-20 Thread Arnd Bergmann
From: Arnd Bergmann 

The mmap2() syscall has never been used on 64-bit s390x and should
have been removed as part of 5a79859ae0f3 ("s390: remove 31 bit
support").

Remove it now.

Signed-off-by: Arnd Bergmann 
---
 arch/s390/kernel/syscall.c | 27 ---
 1 file changed, 27 deletions(-)

diff --git a/arch/s390/kernel/syscall.c b/arch/s390/kernel/syscall.c
index dc2355c623d6..50cbcbbaa03d 100644
--- a/arch/s390/kernel/syscall.c
+++ b/arch/s390/kernel/syscall.c
@@ -38,33 +38,6 @@
 
 #include "entry.h"
 
-/*
- * Perform the mmap() system call. Linux for S/390 isn't able to handle more
- * than 5 system call parameters, so this system call uses a memory block
- * for parameter passing.
- */
-
-struct s390_mmap_arg_struct {
-   unsigned long addr;
-   unsigned long len;
-   unsigned long prot;
-   unsigned long flags;
-   unsigned long fd;
-   unsigned long offset;
-};
-
-SYSCALL_DEFINE1(mmap2, struct s390_mmap_arg_struct __user *, arg)
-{
-   struct s390_mmap_arg_struct a;
-   int error = -EFAULT;
-
-   if (copy_from_user(&a, arg, sizeof(a)))
-   goto out;
-   error = ksys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
-out:
-   return error;
-}
-
 #ifdef CONFIG_SYSVIPC
 /*
  * sys_ipc() is the de-multiplexer for the SysV IPC calls.
-- 
2.39.2



[PATCH 13/15] syscalls: mmap(): use unsigned offset type consistently

2024-06-20 Thread Arnd Bergmann
From: Arnd Bergmann 

Most architectures that implement the old-style mmap() with byte offset
use 'unsigned long' as the type for that offset, but microblaze and
riscv have the off_t type that is shared with userspace, matching the
prototype in include/asm-generic/syscalls.h.

Make this consistent by using an unsigned argument everywhere. This
changes the behavior slightly, as the argument is shifted to a page
number, and an user input with the top bit set would result in a
negative page offset rather than a large one as we use elsewhere.

For riscv, the 32-bit sys_mmap2() definition actually used a custom
type that is different from the global declaration, but this was
missed due to an incorrect type check.

Signed-off-by: Arnd Bergmann 
---
 arch/csky/kernel/syscall.c  | 2 +-
 arch/loongarch/kernel/syscall.c | 2 +-
 arch/microblaze/kernel/sys_microblaze.c | 2 +-
 arch/riscv/kernel/sys_riscv.c   | 4 ++--
 include/asm-generic/syscalls.h  | 2 +-
 5 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/csky/kernel/syscall.c b/arch/csky/kernel/syscall.c
index 3d30e58a45d2..4540a271ee39 100644
--- a/arch/csky/kernel/syscall.c
+++ b/arch/csky/kernel/syscall.c
@@ -20,7 +20,7 @@ SYSCALL_DEFINE6(mmap2,
unsigned long, prot,
unsigned long, flags,
unsigned long, fd,
-   off_t, offset)
+   unsigned long, offset)
 {
if (unlikely(offset & (~PAGE_MASK >> 12)))
return -EINVAL;
diff --git a/arch/loongarch/kernel/syscall.c b/arch/loongarch/kernel/syscall.c
index b4c5acd7aa3b..8801611143ab 100644
--- a/arch/loongarch/kernel/syscall.c
+++ b/arch/loongarch/kernel/syscall.c
@@ -22,7 +22,7 @@
 #define __SYSCALL(nr, call)[nr] = (call),
 
 SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, unsigned long,
-   prot, unsigned long, flags, unsigned long, fd, off_t, offset)
+   prot, unsigned long, flags, unsigned long, fd, unsigned long, 
offset)
 {
if (offset & ~PAGE_MASK)
return -EINVAL;
diff --git a/arch/microblaze/kernel/sys_microblaze.c 
b/arch/microblaze/kernel/sys_microblaze.c
index ed9f34da1a2a..0850b099f300 100644
--- a/arch/microblaze/kernel/sys_microblaze.c
+++ b/arch/microblaze/kernel/sys_microblaze.c
@@ -35,7 +35,7 @@
 
 SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
unsigned long, prot, unsigned long, flags, unsigned long, fd,
-   off_t, pgoff)
+   unsigned long, pgoff)
 {
if (pgoff & ~PAGE_MASK)
return -EINVAL;
diff --git a/arch/riscv/kernel/sys_riscv.c b/arch/riscv/kernel/sys_riscv.c
index 64155323cc92..d77afe05578f 100644
--- a/arch/riscv/kernel/sys_riscv.c
+++ b/arch/riscv/kernel/sys_riscv.c
@@ -23,7 +23,7 @@ static long riscv_sys_mmap(unsigned long addr, unsigned long 
len,
 #ifdef CONFIG_64BIT
 SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
unsigned long, prot, unsigned long, flags,
-   unsigned long, fd, off_t, offset)
+   unsigned long, fd, unsigned long, offset)
 {
return riscv_sys_mmap(addr, len, prot, flags, fd, offset, 0);
 }
@@ -32,7 +32,7 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
 #if defined(CONFIG_32BIT) || defined(CONFIG_COMPAT)
 SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
unsigned long, prot, unsigned long, flags,
-   unsigned long, fd, off_t, offset)
+   unsigned long, fd, unsigned long, offset)
 {
/*
 * Note that the shift for mmap2 is constant (12),
diff --git a/include/asm-generic/syscalls.h b/include/asm-generic/syscalls.h
index 933ca6581aba..fabcefe8a80a 100644
--- a/include/asm-generic/syscalls.h
+++ b/include/asm-generic/syscalls.h
@@ -19,7 +19,7 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long 
len,
 #ifndef sys_mmap
 asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
-   unsigned long fd, off_t pgoff);
+   unsigned long fd, unsigned long off);
 #endif
 
 #ifndef sys_rt_sigreturn
-- 
2.39.2



[PATCH 14/15] asm-generic: unistd: fix time32 compat syscall handling

2024-06-20 Thread Arnd Bergmann
From: Arnd Bergmann 

arch/riscv/ appears to have accidentally enabled the compat time32
syscalls in 64-bit kernels even though the native 32-bit ABI does
not expose those.

Address this by adding another level of indirection, checking for both
the target ABI (32 or 64) and the __ARCH_WANT_TIME32_SYSCALLS macro.

The macro arguments are meant to follow the syscall.tbl format, the idea
here is that by the end of the series, all other syscalls are changed
to the same format to make it possible to move all architectures over
to generating the system call table consistently.
Only this patch needs to be backported though.

Cc: sta...@vger.kernel.org # v5.19+
Fixes: 7eb6369d7acf ("RISC-V: Add support for rv32 userspace via COMPAT")
Signed-off-by: Arnd Bergmann 
---
 include/uapi/asm-generic/unistd.h | 146 +++---
 1 file changed, 94 insertions(+), 52 deletions(-)

diff --git a/include/uapi/asm-generic/unistd.h 
b/include/uapi/asm-generic/unistd.h
index 3fdaa573d661..e47c966557d0 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -16,10 +16,32 @@
 #define __SYSCALL(x, y)
 #endif
 
+#ifndef __SC
+#define __SC(_cond, _nr, _sys) __SYSCALL_ ## _cond (_nr, _sys)
+#endif
+
+#ifndef __SCC
+#ifdef __SYSCALL_COMPAT
+#define __SCC(_cond, _nr, _sys, _comp) __SC(_cond, _nr, _comp)
+#else
+#define __SCC(_cond, _nr, _sys, _comp) __SC(_cond, _nr, _sys)
+#endif
+#endif
+
 #if __BITS_PER_LONG == 32 || defined(__SYSCALL_COMPAT)
 #define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _32)
+#define __SYSCALL_32(_nr, _sys)__SYSCALL(__NR_ ## _nr, _sys)
+#define __SYSCALL_64(_nr, _sys)
 #else
 #define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _64)
+#define __SYSCALL_32(_nr, _sys)
+#define __SYSCALL_64(_nr, _sys)__SYSCALL(__NR_ ## _nr, _sys)
+#endif
+
+#if defined(__ARCH_WANT_TIME32_SYSCALLS)
+#define __SYSCALL_time32(_nr, _sys)__SYSCALL_32(__NR_ ## _nr, _sys)
+#else
+#define __SYSCALL_time32(_nr, _sys)
 #endif
 
 #ifdef __SYSCALL_COMPAT
@@ -41,7 +63,8 @@ __SYSCALL(__NR_io_cancel, sys_io_cancel)
 
 #if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
 #define __NR_io_getevents 4
-__SC_3264(__NR_io_getevents, sys_io_getevents_time32, sys_io_getevents)
+__SC(time32, io_getevents, sys_io_getevents_time32)
+__SC(64, io_getevents, sys_io_getevents)
 #endif
 
 #define __NR_setxattr 5
@@ -190,9 +213,11 @@ __SYSCALL(__NR3264_sendfile, sys_sendfile64)
 
 #if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
 #define __NR_pselect6 72
-__SC_COMP_3264(__NR_pselect6, sys_pselect6_time32, sys_pselect6, 
compat_sys_pselect6_time32)
+__SCC(time32, pselect6, sys_pselect6_time32, compat_sys_pselect6_time32)
+__SC(64, pselect6, sys_pselect6)
 #define __NR_ppoll 73
-__SC_COMP_3264(__NR_ppoll, sys_ppoll_time32, sys_ppoll, 
compat_sys_ppoll_time32)
+__SCC(time32, ppoll, sys_ppoll_time32, compat_sys_ppoll_time32)
+__SC(64, ppoll, sys_ppoll)
 #endif
 
 #define __NR_signalfd4 74
@@ -235,16 +260,17 @@ __SYSCALL(__NR_timerfd_create, sys_timerfd_create)
 
 #if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
 #define __NR_timerfd_settime 86
-__SC_3264(__NR_timerfd_settime, sys_timerfd_settime32, \
- sys_timerfd_settime)
+__SC(time32, timerfd_settime, sys_timerfd_settime32)
+__SC(64, timerfd_settime, sys_timerfd_settime)
 #define __NR_timerfd_gettime 87
-__SC_3264(__NR_timerfd_gettime, sys_timerfd_gettime32, \
- sys_timerfd_gettime)
+__SC(time32, timerfd_gettime, sys_timerfd_gettime32)
+__SC(64, timerfd_gettime, sys_timerfd_gettime)
 #endif
 
 #if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
 #define __NR_utimensat 88
-__SC_3264(__NR_utimensat, sys_utimensat_time32, sys_utimensat)
+__SC(time32, utimensat, sys_utimensat_time32)
+__SC(64, utimensat, sys_utimensat)
 #endif
 
 #define __NR_acct 89
@@ -268,7 +294,8 @@ __SYSCALL(__NR_unshare, sys_unshare)
 
 #if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
 #define __NR_futex 98
-__SC_3264(__NR_futex, sys_futex_time32, sys_futex)
+__SC(time32, futex, sys_futex_time32)
+__SC(64, futex, sys_futex)
 #endif
 
 #define __NR_set_robust_list 99
@@ -280,7 +307,8 @@ __SC_COMP(__NR_get_robust_list, sys_get_robust_list, \
 
 #if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
 #define __NR_nanosleep 101
-__SC_3264(__NR_nanosleep, sys_nanosleep_time32, sys_nanosleep)
+__SC(time32, nanosleep, sys_nanosleep_time32)
+__SC(64, nanosleep, sys_nanosleep)
 #endif
 
 #define __NR_getitimer 102
@@ -298,7 +326,8 @@ __SC_COMP(__NR_timer_create, sys_timer_create, 
compat_sys_timer_create)
 
 #if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
 #define __NR_timer_gettime 108
-__SC_3264(__NR_timer_gettime, sys_timer_gettime32, sys_timer_gettime)
+__SC(time32, timer_gettime, sys_timer_gettime32)
+__SC(64, timer_gettime, sys_timer_gettime)
 #endif
 
 #define __NR_timer_getoverrun 109
@@ -306,7 +335,8 @@ __SYSCALL(__NR_timer_getoverrun, sys_timer_g

[PATCH 15/15] linux/syscalls.h: add missing __user annotations

2024-06-20 Thread Arnd Bergmann
From: Arnd Bergmann 

A couple of declarations in linux/syscalls.h are missing __user
annotations on their pointers, which can lead to warnings from
sparse because these don't match the implementation that have
the correct address space annotations.

Signed-off-by: Arnd Bergmann 
---
 include/linux/syscalls.h | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index ba9337709878..63424af87bba 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -322,13 +322,13 @@ asmlinkage long sys_io_pgetevents(aio_context_t ctx_id,
long nr,
struct io_event __user *events,
struct __kernel_timespec __user *timeout,
-   const struct __aio_sigset *sig);
+   const struct __aio_sigset __user *sig);
 asmlinkage long sys_io_pgetevents_time32(aio_context_t ctx_id,
long min_nr,
long nr,
struct io_event __user *events,
struct old_timespec32 __user *timeout,
-   const struct __aio_sigset *sig);
+   const struct __aio_sigset __user *sig);
 asmlinkage long sys_io_uring_setup(u32 entries,
struct io_uring_params __user *p);
 asmlinkage long sys_io_uring_enter(unsigned int fd, u32 to_submit,
@@ -441,7 +441,7 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, 
gid_t group);
 asmlinkage long sys_openat(int dfd, const char __user *filename, int flags,
   umode_t mode);
 asmlinkage long sys_openat2(int dfd, const char __user *filename,
-   struct open_how *how, size_t size);
+   struct open_how __user *how, size_t size);
 asmlinkage long sys_close(unsigned int fd);
 asmlinkage long sys_close_range(unsigned int fd, unsigned int max_fd,
unsigned int flags);
@@ -555,7 +555,7 @@ asmlinkage long sys_get_robust_list(int pid,
 asmlinkage long sys_set_robust_list(struct robust_list_head __user *head,
size_t len);
 
-asmlinkage long sys_futex_waitv(struct futex_waitv *waiters,
+asmlinkage long sys_futex_waitv(struct futex_waitv __user *waiters,
unsigned int nr_futexes, unsigned int flags,
struct __kernel_timespec __user *timeout, 
clockid_t clockid);
 
@@ -907,7 +907,7 @@ asmlinkage long sys_seccomp(unsigned int op, unsigned int 
flags,
 asmlinkage long sys_getrandom(char __user *buf, size_t count,
  unsigned int flags);
 asmlinkage long sys_memfd_create(const char __user *uname_ptr, unsigned int 
flags);
-asmlinkage long sys_bpf(int cmd, union bpf_attr *attr, unsigned int size);
+asmlinkage long sys_bpf(int cmd, union bpf_attr __user *attr, unsigned int 
size);
 asmlinkage long sys_execveat(int dfd, const char __user *filename,
const char __user *const __user *argv,
const char __user *const __user *envp, int flags);
@@ -960,11 +960,11 @@ asmlinkage long sys_cachestat(unsigned int fd,
struct cachestat_range __user *cstat_range,
struct cachestat __user *cstat, unsigned int flags);
 asmlinkage long sys_map_shadow_stack(unsigned long addr, unsigned long size, 
unsigned int flags);
-asmlinkage long sys_lsm_get_self_attr(unsigned int attr, struct lsm_ctx *ctx,
- u32 *size, u32 flags);
-asmlinkage long sys_lsm_set_self_attr(unsigned int attr, struct lsm_ctx *ctx,
+asmlinkage long sys_lsm_get_self_attr(unsigned int attr, struct lsm_ctx __user 
*ctx,
+ u32 __user *size, u32 flags);
+asmlinkage long sys_lsm_set_self_attr(unsigned int attr, struct lsm_ctx __user 
*ctx,
  u32 size, u32 flags);
-asmlinkage long sys_lsm_list_modules(u64 *ids, u32 *size, u32 flags);
+asmlinkage long sys_lsm_list_modules(u64 __user *ids, u32 __user *size, u32 
flags);
 
 /*
  * Architecture-specific system calls
-- 
2.39.2



Re: [PATCH] powerpc/pseries: Whitelist dtl slub object for copying to userspace

2024-06-20 Thread Anjali K
Hi Kees
Thank you for your review.

On 17/06/24 23:29, Kees Cook wrote:
> On Fri, Jun 14, 2024 at 11:08:44PM +0530, Anjali K wrote:
>> Reading the dispatch trace log from /sys/kernel/debug/powerpc/dtl/cpu-*
>> results in a BUG() when the config CONFIG_HARDENED_USERCOPY is enabled as
>> shown below.
>>
>> kernel BUG at mm/usercopy.c:102!
>> Oops: Exception in kernel mode, sig: 5 [#1]
>> LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA pSeries
>> Modules linked in: xfs libcrc32c dm_service_time sd_mod t10_pi sg ibmvfc
>> scsi_transport_fc ibmveth pseries_wdt dm_multipath dm_mirror 
>> dm_region_hash dm_log dm_mod fuse
>> CPU: 27 PID: 1815 Comm: python3 Not tainted 6.10.0-rc3 #85
>> Hardware name: IBM,9040-MRX POWER10 (raw) 0x800200 0xf06 
>> of:IBM,FW1060.00 (NM1060_042) hv:phyp pSeries
>> NIP:  c05d23d4 LR: c05d23d0 CTR: 006ee6f8
>> REGS: c00120c078c0 TRAP: 0700   Not tainted  (6.10.0-rc3)
>> MSR:  80029033   CR: 2828220f  XER: 
>> 000e
>> CFAR: c01fdc80 IRQMASK: 0
>> [ ... GPRs omitted ... ]
>> NIP [c05d23d4] usercopy_abort+0x78/0xb0
>> LR [c05d23d0] usercopy_abort+0x74/0xb0
>> Call Trace:
>>  usercopy_abort+0x74/0xb0 (unreliable)
>>  __check_heap_object+0xf8/0x120
>>  check_heap_object+0x218/0x240
>>  __check_object_size+0x84/0x1a4
>>  dtl_file_read+0x17c/0x2c4
>>  full_proxy_read+0x8c/0x110
>>  vfs_read+0xdc/0x3a0
>>  ksys_read+0x84/0x144
>>  system_call_exception+0x124/0x330
>>  system_call_vectored_common+0x15c/0x2ec
>> --- interrupt: 3000 at 0x7fff81f3ab34
>>
>> Commit 6d07d1cd300f ("usercopy: Restrict non-usercopy caches to size 0")
>> requires that only whitelisted areas in slab/slub objects can be copied to
>> userspace when usercopy hardening is enabled using CONFIG_HARDENED_USERCOPY.
>> Dtl contains hypervisor dispatch events which are expected to be read by
>> privileged users. Hence mark this safe for user access.
>> Specify useroffset=0 and usersize=DISPATCH_LOG_BYTES to whitelist the
>> entire object.
>>
>> Co-developed-by: Vishal Chourasia 
>> Signed-off-by: Vishal Chourasia 
>> Signed-off-by: Anjali K 
>> ---
>>  arch/powerpc/platforms/pseries/setup.c | 4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/powerpc/platforms/pseries/setup.c 
>> b/arch/powerpc/platforms/pseries/setup.c
>> index 284a6fa04b0c..cba40d9d1284 100644
>> --- a/arch/powerpc/platforms/pseries/setup.c
>> +++ b/arch/powerpc/platforms/pseries/setup.c
>> @@ -343,8 +343,8 @@ static int alloc_dispatch_log_kmem_cache(void)
>>  {
>>  void (*ctor)(void *) = get_dtl_cache_ctor();
>>  
>> -dtl_cache = kmem_cache_create("dtl", DISPATCH_LOG_BYTES,
>> -DISPATCH_LOG_BYTES, 0, ctor);
>> +dtl_cache = kmem_cache_create_usercopy("dtl", DISPATCH_LOG_BYTES,
>> +DISPATCH_LOG_BYTES, 0, 0, 
>> DISPATCH_LOG_BYTES, ctor);
>>  if (!dtl_cache) {
>>  pr_warn("Failed to create dispatch trace log buffer cache\n");
>>  pr_warn("Stolen time statistics will be unreliable\n");
> Are you sure you want to universally expose this memory region? It
> sounds like it's only exposed via a debug interface. Maybe it'd be
> better to use a bounce buffer in the debug interface instead
>
> diff --git a/arch/powerpc/platforms/pseries/dtl.c 
> b/arch/powerpc/platforms/pseries/dtl.c
> index 3f1cdccebc9c..3adcff5cc4b2 100644
> --- a/arch/powerpc/platforms/pseries/dtl.c
> +++ b/arch/powerpc/platforms/pseries/dtl.c
> @@ -257,6 +257,22 @@ static int dtl_file_release(struct inode *inode, struct 
> file *filp)
>   return 0;
>  }
>  
> +static inline int bounce_copy(char __user *buf, void *src, size_t size)
> +{
> + u8 *bounce;
> + int rc;
> +
> + bounce = kmalloc(size, GFP_KERNEL);
> + if (!bounce)
> + return -ENOMEM;
> +
> + memcpy(bounce, src, size);
> + rc = copy_to_user(buf, bounce, size);
> +
> + kfree(bounce);
> + return rc;
> +}
> +
>  static ssize_t dtl_file_read(struct file *filp, char __user *buf, size_t len,
>   loff_t *pos)
>  {
> @@ -300,7 +316,7 @@ static ssize_t dtl_file_read(struct file *filp, char 
> __user *buf, size_t len,
>   if (i + n_req > dtl->buf_entries) {
>   read_size = dtl->buf_entries - i;
>  
> - rc = copy_to_user(buf, &dtl->buf[i],
> + rc = bounce_copy(buf, &dtl->buf[i],
>   read_size * sizeof(struct dtl_entry));
>   if (rc)
>   return -EFAULT;
> @@ -312,7 +328,7 @@ static ssize_t dtl_file_read(struct file *filp, char 
> __user *buf, size_t len,
>   }
>  
>   /* .. and now the head */
> - rc = copy_to_user(buf, &dtl->buf[i], n_req * sizeof(struct dtl_entry));
> + rc = bounce_copy(buf, &dtl->buf[i], n_req * sizeof(struct dtl_entry));  
>   

[PATCH 1/3] powerpc/pseries: Macros and wrapper functions for H_HTM call

2024-06-20 Thread Madhavan Srinivasan
Define macros and wrapper functions to handle
H_HTM (Hardware Trace Macro) hypervisor call.
H_HTM is new HCALL added to export data from
Hardware Trace Macro (HTM) function.

Signed-off-by: Madhavan Srinivasan 
---
 arch/powerpc/include/asm/hvcall.h | 34 +++
 arch/powerpc/include/asm/plpar_wrappers.h | 21 ++
 2 files changed, 55 insertions(+)

diff --git a/arch/powerpc/include/asm/hvcall.h 
b/arch/powerpc/include/asm/hvcall.h
index 7a8495660c2f..7ad13685c127 100644
--- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h
@@ -348,6 +348,7 @@
 #define H_SCM_FLUSH0x44C
 #define H_GET_ENERGY_SCALE_INFO0x450
 #define H_PKS_SIGNED_UPDATE0x454
+#define H_HTM  0x458
 #define H_WATCHDOG 0x45C
 #define H_GUEST_GET_CAPABILITIES 0x460
 #define H_GUEST_SET_CAPABILITIES 0x464
@@ -497,6 +498,39 @@
 #define H_GUEST_CAP_POWER10(1UL<<(63-2))
 #define H_GUEST_CAP_BITMAP2(1UL<<(63-63))
 
+/*
+ * Defines for H_HTM - Macros for hardware trace macro (HTM) function.
+ */
+#define H_HTM_FLAGS_HARDWARE_TARGET(1ul << 63)
+#define H_HTM_FLAGS_LOGICAL_TARGET (1ul << 62)
+#define H_HTM_FLAGS_PROCID_TARGET  (1ul << 61)
+#define H_HTM_FLAGS_NOWRAP (1ul << 60)
+
+#define H_HTM_OP_SHIFT (63-15)
+#define H_HTM_OP(x)((unsigned long)(x)<
 
diff --git a/arch/powerpc/include/asm/plpar_wrappers.h 
b/arch/powerpc/include/asm/plpar_wrappers.h
index b3ee44a40c2f..24d5647096e0 100644
--- a/arch/powerpc/include/asm/plpar_wrappers.h
+++ b/arch/powerpc/include/asm/plpar_wrappers.h
@@ -93,6 +93,27 @@ static inline long register_dtl(unsigned long cpu, unsigned 
long vpa)
return vpa_call(H_VPA_REG_DTL, cpu, vpa);
 }
 
+static inline long htm_call(unsigned long flags, unsigned long target,
+   unsigned long operation, unsigned long param1,
+   unsigned long param2, unsigned long param3)
+{
+   return plpar_hcall_norets(H_HTM, flags, target, operation,
+ param1, param2, param3);
+}
+
+static inline long htm_get_dump_hardware(unsigned long nodeindex,
+   unsigned long nodalchipindex, unsigned long coreindexonchip,
+   unsigned long type, unsigned long addr, unsigned long size,
+   unsigned long offset)
+{
+   return htm_call(H_HTM_FLAGS_HARDWARE_TARGET,
+   H_HTM_TARGET_NODE_INDEX(nodeindex) |
+   H_HTM_TARGET_NODAL_CHIP_INDEX(nodalchipindex) |
+   H_HTM_TARGET_CORE_INDEX_ON_CHIP(coreindexonchip),
+   H_HTM_OP(H_HTM_OP_DUMP_DATA) | H_HTM_TYPE(type),
+   addr, size, offset);
+}
+
 extern void vpa_init(int cpu);
 
 static inline long plpar_pte_enter(unsigned long flags,
-- 
2.45.2



[PATCH 2/3] powerpc/pseries: Export hardware trace macro dump via debugfs

2024-06-20 Thread Madhavan Srinivasan
This patch adds debugfs interface to export Hardware Trace Macro (HTM)
function data in a LPAR. New hypervisor call "H_HTM" has been
defined to setup, configure, control and dump the HTM data.
This patch supports only dumping of HTM data in a LPAR.
New debugfs folder called "htmdump" has been added under
/sys/kernel/debug/arch path which contains files need to
pass required parameters for the H_HTM dump function. New Kconfig
option called "CONFIG_HTMDUMP" has been in platform/pseries for the same.

With patch series applied and booted, list of files in debugfs path

# pwd
/sys/kernel/debug/powerpc/htmdump
# ls
coreindexonchip  htmtype  nodalchipindex  nodeindex  trace

Signed-off-by: Madhavan Srinivasan 
---
 arch/powerpc/platforms/pseries/Kconfig   |   8 ++
 arch/powerpc/platforms/pseries/Makefile  |   1 +
 arch/powerpc/platforms/pseries/htmdump.c | 130 +++
 3 files changed, 139 insertions(+)
 create mode 100644 arch/powerpc/platforms/pseries/htmdump.c

diff --git a/arch/powerpc/platforms/pseries/Kconfig 
b/arch/powerpc/platforms/pseries/Kconfig
index afc0f6a61337..46c0ea605e33 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -128,6 +128,14 @@ config CMM
  will be reused for other LPARs. The interface allows firmware to
  balance memory across many LPARs.
 
+config HTMDUMP
+   tristate "PHYP HTM data dumper"
+   default y
+   help
+ Select this option, if you want to enable the kernel debugfs
+ interface to dump the Hardware Trace Macro (HTM) function data
+ in the LPAR.
+
 config HV_PERF_CTRS
bool "Hypervisor supplied PMU events (24x7 & GPCI)"
default y
diff --git a/arch/powerpc/platforms/pseries/Makefile 
b/arch/powerpc/platforms/pseries/Makefile
index 7bf506f6b8c8..3f3e3492e436 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o
 obj-$(CONFIG_HVCS) += hvcserver.o
 obj-$(CONFIG_HCALL_STATS)  += hvCall_inst.o
 obj-$(CONFIG_CMM)  += cmm.o
+obj-$(CONFIG_HTMDUMP)  += htmdump.o
 obj-$(CONFIG_IO_EVENT_IRQ) += io_event_irq.o
 obj-$(CONFIG_LPARCFG)  += lparcfg.o
 obj-$(CONFIG_IBMVIO)   += vio.o
diff --git a/arch/powerpc/platforms/pseries/htmdump.c 
b/arch/powerpc/platforms/pseries/htmdump.c
new file mode 100644
index ..540cdb7e069c
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/htmdump.c
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) IBM Corporation, 2024
+ */
+
+#define pr_fmt(fmt) "htmdump: " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* This enables us to keep track of the memory removed from each node. */
+struct htmdump_entry {
+   void *buf;
+   struct dentry *dir;
+   char name[16];
+};
+
+static u32 nodeindex = 0;
+static u32 nodalchipindex = 0;
+static u32 coreindexonchip = 0;
+static u32 htmtype = 0;
+
+#define BUFFER_SIZE PAGE_SIZE
+
+static ssize_t htmdump_read(struct file *filp, char __user *ubuf,
+size_t count, loff_t *ppos)
+{
+   struct htmdump_entry *ent = filp->private_data;
+   unsigned long page, read_size, available;
+   loff_t offset;
+   long rc;
+
+   page = ALIGN_DOWN(*ppos, BUFFER_SIZE);
+   offset = (*ppos) % BUFFER_SIZE;
+
+   rc = htm_get_dump_hardware(nodeindex, nodalchipindex, coreindexonchip,
+  htmtype, virt_to_phys(ent->buf), 
BUFFER_SIZE, page);
+
+   switch(rc) {
+   case H_SUCCESS:
+   case H_PARTIAL:
+   break;
+   case H_NOT_AVAILABLE:
+   return 0;
+   case H_BUSY:
+   case H_LONG_BUSY_ORDER_1_MSEC:
+   case H_LONG_BUSY_ORDER_10_MSEC:
+   case H_LONG_BUSY_ORDER_100_MSEC:
+   case H_LONG_BUSY_ORDER_1_SEC:
+   case H_LONG_BUSY_ORDER_10_SEC:
+   case H_LONG_BUSY_ORDER_100_SEC:
+   case H_PARAMETER:
+   case H_P2:
+   case H_P3:
+   case H_P4:
+   case H_P5:
+   case H_P6:
+   case H_STATE:
+   case H_AUTHORITY:
+   return -EINVAL;
+   }
+
+   available = BUFFER_SIZE - offset;
+   read_size = min(count, available);
+   *ppos += read_size;
+   return simple_read_from_buffer(ubuf, count, &offset, ent->buf, 
available);
+}
+
+static const struct file_operations htmdump_fops = {
+   .llseek = default_llseek,
+   .read   = htmdump_read,
+   .open   = simple_open,
+};
+
+static struct dentry *htmdump_debugfs_dir;
+
+static int htmdump_init_debugfs(void)
+{
+   struct htmdump_entry *ent;
+
+   ent = kcalloc(1, sizeof(struct htmdump_entry), GFP_KERNEL);
+   if (!ent) {
+   pr_err("Failed to allocate ent\n");
+   return -EINVAL;
+   }
+
+   e

[PATCH 3/3] powerpc: Document details on H_HTM hcall

2024-06-20 Thread Madhavan Srinivasan
Add documentation to 'papr_hcalls.rst' describing the
input, output and return values of the H_HTM hcall as
per the internal specification.

Signed-off-by: Madhavan Srinivasan 
---
 Documentation/arch/powerpc/papr_hcalls.rst | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/Documentation/arch/powerpc/papr_hcalls.rst 
b/Documentation/arch/powerpc/papr_hcalls.rst
index 80d2c0aadab5..805e1cb9bab9 100644
--- a/Documentation/arch/powerpc/papr_hcalls.rst
+++ b/Documentation/arch/powerpc/papr_hcalls.rst
@@ -289,6 +289,17 @@ to be issued multiple times in order to be completely 
serviced. The
 subsequent hcalls to the hypervisor until the hcall is completely serviced
 at which point H_SUCCESS or other error is returned by the hypervisor.
 
+**H_HTM**
+
+| Input: flags, target, operation (op), op-param1, op-param2, op-param3
+| Out: *dumphtmbufferdata*
+| Return Value: *H_Success,H_Busy,H_LongBusyOrder,H_Partial,H_Parameter,
+H_P2,H_P3,H_P4,H_P5,H_P6,H_State,H_Not_Available,H_Authority*
+
+H_HTM supports setup, configuration, control and dumping of Hardware Trace
+Macro (HTM) function and its data. HTM buffer stores tracing data for functions
+like core instruction, core LLAT and nest.
+
 References
 ==
 .. [1] "Power Architecture Platform Reference"
-- 
2.45.2



[Patch v4 00/10] Add audio support for LPC32XX CPUs

2024-06-20 Thread Piotr Wojtaszczyk
This pach set is to bring back audio to machines with a LPC32XX CPU.
The legacy LPC32XX SoC used to have audio spport in linux 2.6.27.
The support was dropped due to lack of interest from mainaeners.

Piotr Wojtaszczyk (10):
  dt-bindings: dma: pl08x: Add dma-cells description
  dt-bindings: dma: Add lpc32xx DMA mux binding
  ASoC: dt-bindings: lpc32xx: Add lpc32xx i2s DT binding
  ARM: dts: lpc32xx: Add missing dma and i2s properties
  clk: lpc32xx: initialize regmap using parent syscon
  dmaengine: Add dma router for pl08x in LPC32XX SoC
  ARM: lpc32xx: Remove pl08x platform data in favor for device tree
  mtd: rawnand: lpx32xx: Request DMA channels using DT entries
  ASoC: fsl: Add i2s and pcm drivers for LPC32xx CPUs
  i2x: pnx: Use threaded irq to fix warning from del_timer_sync()

 .../devicetree/bindings/dma/arm-pl08x.yaml|   7 +
 .../bindings/dma/nxp,lpc3220-dmamux.yaml  |  56 +++
 .../bindings/sound/nxp,lpc3220-i2s.yaml   |  73 
 MAINTAINERS   |  21 +
 arch/arm/boot/dts/nxp/lpc/lpc32xx.dtsi|  53 ++-
 arch/arm/mach-lpc32xx/phy3250.c   |  54 ---
 drivers/clk/Kconfig   |   1 +
 drivers/clk/nxp/clk-lpc32xx.c |  10 +-
 drivers/dma/Kconfig   |   9 +
 drivers/dma/Makefile  |   1 +
 drivers/dma/lpc32xx-dmamux.c  | 195 +
 drivers/i2c/busses/i2c-pnx.c  |   4 +-
 drivers/mtd/nand/raw/lpc32xx_mlc.c|  10 +-
 drivers/mtd/nand/raw/lpc32xx_slc.c|  10 +-
 sound/soc/fsl/Kconfig |   7 +
 sound/soc/fsl/Makefile|   2 +
 sound/soc/fsl/lpc3xxx-i2s.c   | 376 ++
 sound/soc/fsl/lpc3xxx-i2s.h   |  79 
 sound/soc/fsl/lpc3xxx-pcm.c   |  73 
 19 files changed, 954 insertions(+), 87 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/dma/nxp,lpc3220-dmamux.yaml
 create mode 100644 Documentation/devicetree/bindings/sound/nxp,lpc3220-i2s.yaml
 create mode 100644 drivers/dma/lpc32xx-dmamux.c
 create mode 100644 sound/soc/fsl/lpc3xxx-i2s.c
 create mode 100644 sound/soc/fsl/lpc3xxx-i2s.h
 create mode 100644 sound/soc/fsl/lpc3xxx-pcm.c

-- 
2.25.1



[PATCH v4 18/40] powerpc: optimize arch code by using atomic find_bit() API

2024-06-20 Thread Yury Norov
Use find_and_{set,clear}_bit() where appropriate and simplify the logic.

Signed-off-by: Yury Norov 
---
 arch/powerpc/mm/book3s32/mmu_context.c | 11 +++---
 arch/powerpc/platforms/pasemi/dma_lib.c| 46 ++
 arch/powerpc/platforms/powernv/pci-sriov.c | 13 ++
 3 files changed, 20 insertions(+), 50 deletions(-)

diff --git a/arch/powerpc/mm/book3s32/mmu_context.c 
b/arch/powerpc/mm/book3s32/mmu_context.c
index 1922f9a6b058..ece7b55b6cdb 100644
--- a/arch/powerpc/mm/book3s32/mmu_context.c
+++ b/arch/powerpc/mm/book3s32/mmu_context.c
@@ -17,6 +17,7 @@
  *Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -50,13 +51,11 @@ static unsigned long context_map[LAST_CONTEXT / 
BITS_PER_LONG + 1];
 
 unsigned long __init_new_context(void)
 {
-   unsigned long ctx = next_mmu_context;
+   unsigned long ctx;
 
-   while (test_and_set_bit(ctx, context_map)) {
-   ctx = find_next_zero_bit(context_map, LAST_CONTEXT+1, ctx);
-   if (ctx > LAST_CONTEXT)
-   ctx = 0;
-   }
+   ctx = find_and_set_next_bit(context_map, LAST_CONTEXT + 1, 
next_mmu_context);
+   if (ctx > LAST_CONTEXT)
+   ctx = 0;
next_mmu_context = (ctx + 1) & LAST_CONTEXT;
 
return ctx;
diff --git a/arch/powerpc/platforms/pasemi/dma_lib.c 
b/arch/powerpc/platforms/pasemi/dma_lib.c
index 1be1f18f6f09..db008902e5f3 100644
--- a/arch/powerpc/platforms/pasemi/dma_lib.c
+++ b/arch/powerpc/platforms/pasemi/dma_lib.c
@@ -5,6 +5,7 @@
  * Common functions for DMA access on PA Semi PWRficient
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -118,14 +119,9 @@ static int pasemi_alloc_tx_chan(enum pasemi_dmachan_type 
type)
limit = MAX_TXCH;
break;
}
-retry:
-   bit = find_next_bit(txch_free, MAX_TXCH, start);
-   if (bit >= limit)
-   return -ENOSPC;
-   if (!test_and_clear_bit(bit, txch_free))
-   goto retry;
-
-   return bit;
+
+   bit = find_and_clear_next_bit(txch_free, MAX_TXCH, start);
+   return bit < limit ? bit : -ENOSPC;
 }
 
 static void pasemi_free_tx_chan(int chan)
@@ -136,15 +132,9 @@ static void pasemi_free_tx_chan(int chan)
 
 static int pasemi_alloc_rx_chan(void)
 {
-   int bit;
-retry:
-   bit = find_first_bit(rxch_free, MAX_RXCH);
-   if (bit >= MAX_TXCH)
-   return -ENOSPC;
-   if (!test_and_clear_bit(bit, rxch_free))
-   goto retry;
-
-   return bit;
+   int bit = find_and_clear_bit(rxch_free, MAX_RXCH);
+
+   return bit < MAX_TXCH ? bit : -ENOSPC;
 }
 
 static void pasemi_free_rx_chan(int chan)
@@ -374,16 +364,9 @@ EXPORT_SYMBOL(pasemi_dma_free_buf);
  */
 int pasemi_dma_alloc_flag(void)
 {
-   int bit;
+   int bit = find_and_clear_bit(flags_free, MAX_FLAGS);
 
-retry:
-   bit = find_first_bit(flags_free, MAX_FLAGS);
-   if (bit >= MAX_FLAGS)
-   return -ENOSPC;
-   if (!test_and_clear_bit(bit, flags_free))
-   goto retry;
-
-   return bit;
+   return bit < MAX_FLAGS ? bit : -ENOSPC;
 }
 EXPORT_SYMBOL(pasemi_dma_alloc_flag);
 
@@ -439,16 +422,9 @@ EXPORT_SYMBOL(pasemi_dma_clear_flag);
  */
 int pasemi_dma_alloc_fun(void)
 {
-   int bit;
-
-retry:
-   bit = find_first_bit(fun_free, MAX_FLAGS);
-   if (bit >= MAX_FLAGS)
-   return -ENOSPC;
-   if (!test_and_clear_bit(bit, fun_free))
-   goto retry;
+   int bit = find_and_clear_bit(fun_free, MAX_FLAGS);
 
-   return bit;
+   return bit < MAX_FLAGS ? bit : -ENOSPC;
 }
 EXPORT_SYMBOL(pasemi_dma_alloc_fun);
 
diff --git a/arch/powerpc/platforms/powernv/pci-sriov.c 
b/arch/powerpc/platforms/powernv/pci-sriov.c
index cc7b1dd54ac6..e33e57c559f7 100644
--- a/arch/powerpc/platforms/powernv/pci-sriov.c
+++ b/arch/powerpc/platforms/powernv/pci-sriov.c
@@ -3,6 +3,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -397,18 +398,12 @@ static int64_t pnv_ioda_map_m64_single(struct pnv_phb 
*phb,
 
 static int pnv_pci_alloc_m64_bar(struct pnv_phb *phb, struct pnv_iov_data *iov)
 {
-   int win;
+   int win = find_and_set_bit(&phb->ioda.m64_bar_alloc, 
phb->ioda.m64_bar_idx + 1);
 
-   do {
-   win = find_next_zero_bit(&phb->ioda.m64_bar_alloc,
-   phb->ioda.m64_bar_idx + 1, 0);
-
-   if (win >= phb->ioda.m64_bar_idx + 1)
-   return -1;
-   } while (test_and_set_bit(win, &phb->ioda.m64_bar_alloc));
+   if (win >= phb->ioda.m64_bar_idx + 1)
+   return -1;
 
set_bit(win, iov->used_m64_bar_mask);
-
return win;
 }
 
-- 
2.43.0



[Patch v4 01/10] dt-bindings: dma: pl08x: Add dma-cells description

2024-06-20 Thread Piotr Wojtaszczyk
Recover dma-cells description from the legacy DT binding.

Signed-off-by: Piotr Wojtaszczyk 
---
Changes for v4:
- This patch is new in v4

 Documentation/devicetree/bindings/dma/arm-pl08x.yaml | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/dma/arm-pl08x.yaml 
b/Documentation/devicetree/bindings/dma/arm-pl08x.yaml
index ab25ae63d2c3..191215d36c85 100644
--- a/Documentation/devicetree/bindings/dma/arm-pl08x.yaml
+++ b/Documentation/devicetree/bindings/dma/arm-pl08x.yaml
@@ -52,6 +52,13 @@ properties:
   clock-names:
 maxItems: 1
 
+  "#dma-cells":
+const: 2
+description: |
+  First cell should contain the DMA request,
+  second cell should contain either 1 or 2 depending on
+  which AHB master that is used.
+
   lli-bus-interface-ahb1:
 type: boolean
 description: if AHB master 1 is eligible for fetching LLIs
-- 
2.25.1



[Patch v4 02/10] dt-bindings: dma: Add lpc32xx DMA mux binding

2024-06-20 Thread Piotr Wojtaszczyk
LPC32XX SoCs use pl080 dma controller which have few request signals
multiplexed between peripherals. This binding describes how devices can
use the multiplexed request signals.

Signed-off-by: Piotr Wojtaszczyk 
---
Changes for v4:
- This patch is new in v4

 .../bindings/dma/nxp,lpc3220-dmamux.yaml  | 56 +++
 MAINTAINERS   |  9 +++
 2 files changed, 65 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/dma/nxp,lpc3220-dmamux.yaml

diff --git a/Documentation/devicetree/bindings/dma/nxp,lpc3220-dmamux.yaml 
b/Documentation/devicetree/bindings/dma/nxp,lpc3220-dmamux.yaml
new file mode 100644
index ..a5384b6c67fc
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/nxp,lpc3220-dmamux.yaml
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/nxp,lpc3220-dmamux.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: DMA multiplexer for LPC32XX SoC (DMA request router)
+
+maintainers:
+  - J.M.B. Downing 
+  - Piotr Wojtaszczyk 
+
+allOf:
+  - $ref: dma-router.yaml#
+
+properties:
+  "#dma-cells":
+const: 3
+description: |
+  First two cells same as for device pointed in dma-masters.
+  Third cell represents mux value for the request.
+
+  compatible:
+const: nxp,lpc3220-dmamux
+
+  dma-masters:
+description: phandle to a dma node compatible with arm,pl080
+
+  reg:
+maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - dma-masters
+
+additionalProperties: false
+
+examples:
+  - |
+syscon@40004000 {
+  compatible = "nxp,lpc3220-creg", "syscon", "simple-mfd";
+  reg = <0x40004000 0x114>;
+  ranges = <0 0x40004000 0x114>;
+  #address-cells = <1>;
+  #size-cells = <1>;
+
+  dma-router@7c {
+compatible = "nxp,lpc3220-dmamux";
+reg = <0x7c 0x8>;
+#dma-cells = <3>;
+dma-masters = <&dma>;
+  };
+};
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index aacccb376c28..f7adf9f66dfa 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2396,6 +2396,15 @@ F:   drivers/usb/host/ohci-nxp.c
 F: drivers/watchdog/pnx4008_wdt.c
 N: lpc32xx
 
+ARM/LPC32XX DMAMUX SUPPORT
+M: J.M.B. Downing 
+M: Piotr Wojtaszczyk 
+R: Vladimir Zapolskiy 
+L: linux-arm-ker...@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: Documentation/devicetree/bindings/dma/nxp,lpc3220-dmamux.yaml
+N: lpc32xx
+
 ARM/Marvell Dove/MV78xx0/Orion SOC support
 M: Andrew Lunn 
 M: Sebastian Hesselbarth 
-- 
2.25.1



[Patch v4 03/10] ASoC: dt-bindings: lpc32xx: Add lpc32xx i2s DT binding

2024-06-20 Thread Piotr Wojtaszczyk
Add nxp,lpc3220-i2s DT binding documentation.

Signed-off-by: Piotr Wojtaszczyk 
---
Changes for v4:
- Custom dma-vc-names property with standard dmas and dma-names
- Added to MAINTAINERS

Changes for v3:
- Added '$ref: dai-common.yaml#' and '#sound-dai-cells'
- Dropped all clock-names, references
- Dropped status property from the example
- Added interrupts property
- 'make dt_binding_check' pass

Changes for v2:
- Added maintainers field
- Dropped clock-names
- Dropped unused unneded interrupts field

 .../bindings/sound/nxp,lpc3220-i2s.yaml   | 73 +++
 MAINTAINERS   | 10 +++
 2 files changed, 83 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/nxp,lpc3220-i2s.yaml

diff --git a/Documentation/devicetree/bindings/sound/nxp,lpc3220-i2s.yaml 
b/Documentation/devicetree/bindings/sound/nxp,lpc3220-i2s.yaml
new file mode 100644
index ..40a0877a8aba
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/nxp,lpc3220-i2s.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/nxp,lpc3220-i2s.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP LPC32XX I2S Controller
+
+description:
+  The I2S controller in LPC32XX SoCs, ASoC DAI.
+
+maintainers:
+  - J.M.B. Downing 
+  - Piotr Wojtaszczyk 
+
+allOf:
+  - $ref: dai-common.yaml#
+
+properties:
+  compatible:
+enum:
+  - nxp,lpc3220-i2s
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  clocks:
+items:
+  - description: input clock of the peripheral.
+
+  dmas:
+items:
+  - description: RX DMA Channel
+  - description: TX DMA Channel
+
+  dma-names:
+items:
+  - const: rx
+  - const: tx
+
+  "#sound-dai-cells":
+const: 0
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - dmas
+  - dma-names
+  - '#sound-dai-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+
+i2s@20094000 {
+  compatible = "nxp,lpc3220-i2s";
+  reg = <0x20094000 0x1000>;
+  interrupts = <22 IRQ_TYPE_LEVEL_HIGH>;
+  clocks = <&clk LPC32XX_CLK_I2S0>;
+  dmas = <&dma 0 1>, <&dma 13 1>;
+  dma-names = "rx", "tx";
+  #sound-dai-cells = <0>;
+};
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index f7adf9f66dfa..fadf1baafd89 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8918,6 +8918,16 @@ S:   Maintained
 F: sound/soc/fsl/fsl*
 F: sound/soc/fsl/imx*
 
+FREESCALE SOC LPC32XX SOUND DRIVERS
+M: J.M.B. Downing 
+M: Piotr Wojtaszczyk 
+R: Vladimir Zapolskiy 
+L: alsa-de...@alsa-project.org (moderated for non-subscribers)
+L: linuxppc-dev@lists.ozlabs.org
+S: Maintained
+F: Documentation/devicetree/bindings/sound/nxp,lpc3220-i2s.yaml
+N: lpc32xx
+
 FREESCALE SOC SOUND QMC DRIVER
 M: Herve Codina 
 L: alsa-de...@alsa-project.org (moderated for non-subscribers)
-- 
2.25.1



[PATCH v4 37/40] KVM: PPC: Book3s HV: drop locking around kvmppc_uvmem_bitmap

2024-06-20 Thread Yury Norov
The driver operates on individual bits of the kvmppc_uvmem_bitmap.
Now that we have an atomic search API for bitmaps, we can rely on
it and drop locking around the bitmap entirely.

Signed-off-by: Yury Norov 
---
 arch/powerpc/kvm/book3s_hv_uvmem.c | 33 ++
 1 file changed, 11 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_hv_uvmem.c 
b/arch/powerpc/kvm/book3s_hv_uvmem.c
index 92f33115144b..93d09137cb23 100644
--- a/arch/powerpc/kvm/book3s_hv_uvmem.c
+++ b/arch/powerpc/kvm/book3s_hv_uvmem.c
@@ -86,6 +86,7 @@
  * page-sizes, we need to break this assumption.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -99,7 +100,6 @@
 
 static struct dev_pagemap kvmppc_uvmem_pgmap;
 static unsigned long *kvmppc_uvmem_bitmap;
-static DEFINE_SPINLOCK(kvmppc_uvmem_bitmap_lock);
 
 /*
  * States of a GFN
@@ -697,23 +697,20 @@ static struct page *kvmppc_uvmem_get_page(unsigned long 
gpa, struct kvm *kvm)
struct page *dpage = NULL;
unsigned long bit, uvmem_pfn;
struct kvmppc_uvmem_page_pvt *pvt;
-   unsigned long pfn_last, pfn_first;
+   unsigned long num_pfns, pfn_first;
 
pfn_first = kvmppc_uvmem_pgmap.range.start >> PAGE_SHIFT;
-   pfn_last = pfn_first +
-  (range_len(&kvmppc_uvmem_pgmap.range) >> PAGE_SHIFT);
+   num_pfns = range_len(&kvmppc_uvmem_pgmap.range) >> PAGE_SHIFT;
 
-   spin_lock(&kvmppc_uvmem_bitmap_lock);
-   bit = find_first_zero_bit(kvmppc_uvmem_bitmap,
- pfn_last - pfn_first);
-   if (bit >= (pfn_last - pfn_first))
-   goto out;
-   bitmap_set(kvmppc_uvmem_bitmap, bit, 1);
-   spin_unlock(&kvmppc_uvmem_bitmap_lock);
+   bit = find_and_set_bit(kvmppc_uvmem_bitmap, num_pfns);
+   if (bit >= num_pfns)
+   return NULL;
 
pvt = kzalloc(sizeof(*pvt), GFP_KERNEL);
-   if (!pvt)
-   goto out_clear;
+   if (!pvt) {
+   clear_bit(bit, kvmppc_uvmem_bitmap);
+   return NULL;
+   }
 
uvmem_pfn = bit + pfn_first;
kvmppc_gfn_secure_uvmem_pfn(gpa >> PAGE_SHIFT, uvmem_pfn, kvm);
@@ -725,12 +722,6 @@ static struct page *kvmppc_uvmem_get_page(unsigned long 
gpa, struct kvm *kvm)
dpage->zone_device_data = pvt;
zone_device_page_init(dpage);
return dpage;
-out_clear:
-   spin_lock(&kvmppc_uvmem_bitmap_lock);
-   bitmap_clear(kvmppc_uvmem_bitmap, bit, 1);
-out:
-   spin_unlock(&kvmppc_uvmem_bitmap_lock);
-   return NULL;
 }
 
 /*
@@ -1021,9 +1012,7 @@ static void kvmppc_uvmem_page_free(struct page *page)
(kvmppc_uvmem_pgmap.range.start >> PAGE_SHIFT);
struct kvmppc_uvmem_page_pvt *pvt;
 
-   spin_lock(&kvmppc_uvmem_bitmap_lock);
-   bitmap_clear(kvmppc_uvmem_bitmap, pfn, 1);
-   spin_unlock(&kvmppc_uvmem_bitmap_lock);
+   clear_bit(pfn, kvmppc_uvmem_bitmap);
 
pvt = page->zone_device_data;
page->zone_device_data = NULL;
-- 
2.43.0



[PATCH v4 40/40] powerpc/xive: drop locking around IRQ map

2024-06-20 Thread Yury Norov
The code operates on individual bits of the bitmap, and leveraging
atomic find ops we can drop locking scheme around the map.

Signed-off-by: Yury Norov 
---
 arch/powerpc/sysdev/xive/spapr.c | 34 ++--
 1 file changed, 6 insertions(+), 28 deletions(-)

diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c
index e45419264391..2b3b8ad75b42 100644
--- a/arch/powerpc/sysdev/xive/spapr.c
+++ b/arch/powerpc/sysdev/xive/spapr.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -41,7 +42,6 @@ struct xive_irq_bitmap {
unsigned long   *bitmap;
unsigned intbase;
unsigned intcount;
-   spinlock_t  lock;
struct list_headlist;
 };
 
@@ -55,7 +55,6 @@ static int __init xive_irq_bitmap_add(int base, int count)
if (!xibm)
return -ENOMEM;
 
-   spin_lock_init(&xibm->lock);
xibm->base = base;
xibm->count = count;
xibm->bitmap = bitmap_zalloc(xibm->count, GFP_KERNEL);
@@ -81,47 +80,26 @@ static void xive_irq_bitmap_remove_all(void)
}
 }
 
-static int __xive_irq_bitmap_alloc(struct xive_irq_bitmap *xibm)
-{
-   int irq;
-
-   irq = find_first_zero_bit(xibm->bitmap, xibm->count);
-   if (irq != xibm->count) {
-   set_bit(irq, xibm->bitmap);
-   irq += xibm->base;
-   } else {
-   irq = -ENOMEM;
-   }
-
-   return irq;
-}
-
 static int xive_irq_bitmap_alloc(void)
 {
struct xive_irq_bitmap *xibm;
-   unsigned long flags;
-   int irq = -ENOENT;
 
list_for_each_entry(xibm, &xive_irq_bitmaps, list) {
-   spin_lock_irqsave(&xibm->lock, flags);
-   irq = __xive_irq_bitmap_alloc(xibm);
-   spin_unlock_irqrestore(&xibm->lock, flags);
-   if (irq >= 0)
-   break;
+   int irq = find_and_set_bit(xibm->bitmap, xibm->count);
+
+   if (irq < xibm->count)
+   return irq + xibm->base;
}
-   return irq;
+   return -ENOENT;
 }
 
 static void xive_irq_bitmap_free(int irq)
 {
-   unsigned long flags;
struct xive_irq_bitmap *xibm;
 
list_for_each_entry(xibm, &xive_irq_bitmaps, list) {
if ((irq >= xibm->base) && (irq < xibm->base + xibm->count)) {
-   spin_lock_irqsave(&xibm->lock, flags);
clear_bit(irq - xibm->base, xibm->bitmap);
-   spin_unlock_irqrestore(&xibm->lock, flags);
break;
}
}
-- 
2.43.0



[Patch v4 04/10] ARM: dts: lpc32xx: Add missing dma and i2s properties

2024-06-20 Thread Piotr Wojtaszczyk
Adds properties declared in the new DT bindings:
 - nxp,lpc3220-i2s.yaml
 - nxp,lpc3220-dmamux.yaml
for dma router/mux and I2S interface.

Signed-off-by: Piotr Wojtaszczyk 
---
Changes for v4:
- This patch is renamed from
  "ARM: dts: lpc32xx: Add missing properties for the i2s interfaces"
  to describe dma changes as well
- Added dmas and dma-names properties in to all node which have dma request 
signals
- Add bus properties to pl08x dma node since they are removed from platform 
data in phy3250.c
- Put clock-controller@0 and dma-router@7c under the same syscon, simple-mfd 
device

Changes for v3:
- Split previous commit for separate subsystems
- Add properties to match dt binding

 arch/arm/boot/dts/nxp/lpc/lpc32xx.dtsi | 53 +++---
 1 file changed, 48 insertions(+), 5 deletions(-)

diff --git a/arch/arm/boot/dts/nxp/lpc/lpc32xx.dtsi 
b/arch/arm/boot/dts/nxp/lpc/lpc32xx.dtsi
index 974410918f35..c58dc127e59f 100644
--- a/arch/arm/boot/dts/nxp/lpc/lpc32xx.dtsi
+++ b/arch/arm/boot/dts/nxp/lpc/lpc32xx.dtsi
@@ -67,6 +67,8 @@ slc: flash@2002 {
reg = <0x2002 0x1000>;
clocks = <&clk LPC32XX_CLK_SLC>;
status = "disabled";
+   dmas = <&dma 1 1>;
+   dma-names = "rx-tx";
};
 
mlc: flash@200a8000 {
@@ -75,6 +77,8 @@ mlc: flash@200a8000 {
interrupts = <11 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk LPC32XX_CLK_MLC>;
status = "disabled";
+   dmas = <&dma 12 1>;
+   dma-names = "rx-tx";
};
 
dma: dma@3100 {
@@ -83,6 +87,13 @@ dma: dma@3100 {
interrupts = <28 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk LPC32XX_CLK_DMA>;
clock-names = "apb_pclk";
+   #dma-cells = <2>;
+   dma-channels = <8>;
+   dma-requests = <16>;
+   lli-bus-interface-ahb1;
+   mem-bus-interface-ahb1;
+   memcpy-burst-size = <256>;
+   memcpy-bus-width = <32>;
};
 
usb {
@@ -182,6 +193,8 @@ ssp0: spi@20084000 {
clock-names = "apb_pclk";
#address-cells = <1>;
#size-cells = <0>;
+   dmas = <&dmamux 14 1 1>, <&dmamux 15 1 1>;
+   dma-names = "rx", "tx";
status = "disabled";
};
 
@@ -191,6 +204,8 @@ spi1: spi@20088000 {
clocks = <&clk LPC32XX_CLK_SPI1>;
#address-cells = <1>;
#size-cells = <0>;
+   dmas = <&dmamux 11 1 0>;
+   dma-names = "rx-tx";
status = "disabled";
};
 
@@ -206,6 +221,8 @@ ssp1: spi@2008c000 {
clock-names = "apb_pclk";
#address-cells = <1>;
#size-cells = <0>;
+   dmas = <&dmamux 3 1 1>, <&dmamux 11 1 1>;
+   dma-names = "rx", "tx";
status = "disabled";
};
 
@@ -215,12 +232,19 @@ spi2: spi@2009 {
clocks = <&clk LPC32XX_CLK_SPI2>;
#address-cells = <1>;
#size-cells = <0>;
+   dmas = <&dmamux 3 1 0>;
+   dma-names = "rx-tx";
status = "disabled";
};
 
i2s0: i2s@20094000 {
compatible = "nxp,lpc3220-i2s";
reg = <0x20094000 0x1000>;
+   interrupts = <22 IRQ_TYPE_LEVEL_HIGH>;
+   clocks = <&clk LPC32XX_CLK_I2S0>;
+   dmas = <&dma 0 1>, <&dma 13 1>;
+   dma-names = "rx", "tx";
+   #sound-dai-cells = <0>;
status = "disabled";
};
 
@@ -231,12 +255,19 @@ sd: sd@20098000 {
 <13 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk LPC32XX_CLK_SD>;
clock-names = "apb_pclk";
+   dmas = <&dma 4 1>;
+   dma-names = "rx";
status = "disabled";
};
 
i2s1: i2s@2009c000 {
   

[Patch v4 05/10] clk: lpc32xx: initialize regmap using parent syscon

2024-06-20 Thread Piotr Wojtaszczyk
This allows to share the regmap with other simple-mfd devices like
nxp,lpc32xx-dmamux

Signed-off-by: Piotr Wojtaszczyk 
---
Changes for v4:
- This patch is new in v4

 drivers/clk/Kconfig   |  1 +
 drivers/clk/nxp/clk-lpc32xx.c | 10 ++
 2 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 3e9099504fad..85ef57d5cccf 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -346,6 +346,7 @@ config COMMON_CLK_LOONGSON2
 config COMMON_CLK_NXP
def_bool COMMON_CLK && (ARCH_LPC18XX || ARCH_LPC32XX)
select REGMAP_MMIO if ARCH_LPC32XX
+   select MFD_SYSCON if ARCH_LPC32XX
select MFD_SYSCON if ARCH_LPC18XX
help
  Support for clock providers on NXP platforms.
diff --git a/drivers/clk/nxp/clk-lpc32xx.c b/drivers/clk/nxp/clk-lpc32xx.c
index d0f870eff0d6..2a183a9ded93 100644
--- a/drivers/clk/nxp/clk-lpc32xx.c
+++ b/drivers/clk/nxp/clk-lpc32xx.c
@@ -7,6 +7,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -1511,17 +1512,10 @@ static void __init lpc32xx_clk_init(struct device_node 
*np)
return;
}
 
-   base = of_iomap(np, 0);
-   if (!base) {
-   pr_err("failed to map system control block registers\n");
-   return;
-   }
-
-   clk_regmap = regmap_init_mmio(NULL, base, &lpc32xx_scb_regmap_config);
+   clk_regmap = syscon_node_to_regmap(np->parent);
if (IS_ERR(clk_regmap)) {
pr_err("failed to regmap system control block: %ld\n",
PTR_ERR(clk_regmap));
-   iounmap(base);
return;
}
 
-- 
2.25.1



[Patch v4 06/10] dmaengine: Add dma router for pl08x in LPC32XX SoC

2024-06-20 Thread Piotr Wojtaszczyk
LPC32XX connects few of its peripherals to pl08x DMA thru a multiplexer,
this driver allows to route a signal request line thru the multiplexer for
given peripheral.

Signed-off-by: Piotr Wojtaszczyk 
---
Changes for v4:
- This patch is new in v4

 MAINTAINERS  |   1 +
 drivers/dma/Kconfig  |   9 ++
 drivers/dma/Makefile |   1 +
 drivers/dma/lpc32xx-dmamux.c | 195 +++
 4 files changed, 206 insertions(+)
 create mode 100644 drivers/dma/lpc32xx-dmamux.c

diff --git a/MAINTAINERS b/MAINTAINERS
index fadf1baafd89..5ffe988ee282 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2403,6 +2403,7 @@ R:Vladimir Zapolskiy 
 L: linux-arm-ker...@lists.infradead.org (moderated for non-subscribers)
 S: Maintained
 F: Documentation/devicetree/bindings/dma/nxp,lpc3220-dmamux.yaml
+F: drivers/dma/lpc32xx-dmamux.c
 N: lpc32xx
 
 ARM/Marvell Dove/MV78xx0/Orion SOC support
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 002a5ec80620..aeace3d7e066 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -378,6 +378,15 @@ config LPC18XX_DMAMUX
  Enable support for DMA on NXP LPC18xx/43xx platforms
  with PL080 and multiplexed DMA request lines.
 
+config LPC32XX_DMAMUX
+   bool "NXP LPC32xx DMA MUX for PL080"
+   depends on ARCH_LPC32XX || COMPILE_TEST
+   depends on OF && AMBA_PL08X
+   select MFD_SYSCON
+   help
+ Support for PL080 multiplexed DMA request lines on
+ LPC32XX platrofm.
+
 config LS2X_APB_DMA
tristate "Loongson LS2X APB DMA support"
depends on LOONGARCH || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 802ca916f05f..6f1350b62e7f 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_INTEL_IOATDMA) += ioat/
 obj-y += idxd/
 obj-$(CONFIG_K3_DMA) += k3dma.o
 obj-$(CONFIG_LPC18XX_DMAMUX) += lpc18xx-dmamux.o
+obj-$(CONFIG_LPC32XX_DMAMUX) += lpc32xx-dmamux.o
 obj-$(CONFIG_LS2X_APB_DMA) += ls2x-apb-dma.o
 obj-$(CONFIG_MILBEAUT_HDMAC) += milbeaut-hdmac.o
 obj-$(CONFIG_MILBEAUT_XDMAC) += milbeaut-xdmac.o
diff --git a/drivers/dma/lpc32xx-dmamux.c b/drivers/dma/lpc32xx-dmamux.c
new file mode 100644
index ..4e6ce6026164
--- /dev/null
+++ b/drivers/dma/lpc32xx-dmamux.c
@@ -0,0 +1,195 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright 2024 Timesys Corporation 
+//
+// Based on TI DMA Crossbar driver by:
+//   Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com
+//   Author: Peter Ujfalusi 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LPC32XX_SSP_CLK_CTRL 0x78
+#define LPC32XX_I2S_CLK_CTRL 0x7c
+
+struct lpc32xx_dmamux {
+   int signal;
+   char *name_sel0;
+   char *name_sel1;
+   int muxval;
+   int muxreg;
+   int bit;
+   bool busy;
+};
+
+/* From LPC32x0 User manual "3.2.1 DMA request signals" */
+static struct lpc32xx_dmamux lpc32xx_muxes[] = {
+   {
+   .signal = 3,
+   .name_sel0 = "spi2-rx-tx",
+   .name_sel1 = "ssp1-rx",
+   .muxreg = LPC32XX_SSP_CLK_CTRL,
+   .bit = 5,
+   },
+   {
+   .signal = 10,
+   .name_sel0 = "uart7-rx",
+   .name_sel1 = "i2s1-dma1",
+   .muxreg = LPC32XX_I2S_CLK_CTRL,
+   .bit = 4,
+   },
+   {
+   .signal = 11,
+   .name_sel0 = "spi1-rx-tx",
+   .name_sel1 = "ssp1-tx",
+   .muxreg = LPC32XX_SSP_CLK_CTRL,
+   .bit = 4,
+   },
+   {
+   .signal = 14,
+   .name_sel0 = "none",
+   .name_sel1 = "ssp0-rx",
+   .muxreg = LPC32XX_SSP_CLK_CTRL,
+   .bit = 3,
+   },
+   {
+   .signal = 15,
+   .name_sel0 = "none",
+   .name_sel1 = "ssp0-tx",
+   .muxreg = LPC32XX_SSP_CLK_CTRL,
+   .bit = 2,
+   },
+};
+
+struct lpc32xx_dmamux_data {
+   struct dma_router dmarouter;
+   struct regmap *reg;
+   spinlock_t lock; /* protects busy status flag */
+};
+
+static void lpc32xx_dmamux_release(struct device *dev, void *route_data)
+{
+   struct lpc32xx_dmamux_data *dmamux = dev_get_drvdata(dev);
+   struct lpc32xx_dmamux *mux = route_data;
+   unsigned long flags;
+
+   dev_dbg(dev, "releasing dma request signal %d routed to %s\n",
+   mux->signal, mux->muxval ? mux->name_sel1 : mux->name_sel1);
+
+   guard(spinlock)(&dmamux->lock);
+
+   mux->busy = false;
+}
+
+static void *lpc32xx_dmamux_reserve(struct of_phandle_args *dma_spec,
+   struct of_dma *ofdma)
+{
+   struct platform_device *pdev = of_find_device_by_node(ofdma->of_node);
+   struct device *dev = &pdev->dev;
+   struct lpc32xx_dmamux_data *dmamux = platform_

[Patch v4 07/10] ARM: lpc32xx: Remove pl08x platform data in favor for device tree

2024-06-20 Thread Piotr Wojtaszczyk
With the driver for nxp,lpc3220-dmamux we can remove the pl08x platform
data and let pl08x driver to create peripheral channels from the DT
properties.

Signed-off-by: Piotr Wojtaszczyk 
---
Changes for v4:
- This patch is new in v4

 arch/arm/mach-lpc32xx/phy3250.c | 54 -
 1 file changed, 54 deletions(-)

diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c
index 66701bf43248..0c7797a0e44e 100644
--- a/arch/arm/mach-lpc32xx/phy3250.c
+++ b/arch/arm/mach-lpc32xx/phy3250.c
@@ -16,64 +16,10 @@
 #include 
 #include "common.h"
 
-static struct pl08x_channel_data pl08x_slave_channels[] = {
-   {
-   .bus_id = "nand-slc",
-   .min_signal = 1, /* SLC NAND Flash */
-   .max_signal = 1,
-   .periph_buses = PL08X_AHB1,
-   },
-   {
-   .bus_id = "nand-mlc",
-   .min_signal = 12, /* MLC NAND Flash */
-   .max_signal = 12,
-   .periph_buses = PL08X_AHB1,
-   },
-};
-
-static int pl08x_get_signal(const struct pl08x_channel_data *cd)
-{
-   return cd->min_signal;
-}
-
-static void pl08x_put_signal(const struct pl08x_channel_data *cd, int ch)
-{
-}
-
-static struct pl08x_platform_data pl08x_pd = {
-   /* Some reasonable memcpy defaults */
-   .memcpy_burst_size = PL08X_BURST_SZ_256,
-   .memcpy_bus_width = PL08X_BUS_WIDTH_32_BITS,
-   .slave_channels = &pl08x_slave_channels[0],
-   .num_slave_channels = ARRAY_SIZE(pl08x_slave_channels),
-   .get_xfer_signal = pl08x_get_signal,
-   .put_xfer_signal = pl08x_put_signal,
-   .lli_buses = PL08X_AHB1,
-   .mem_buses = PL08X_AHB1,
-};
-
-static struct lpc32xx_slc_platform_data lpc32xx_slc_data = {
-   .dma_filter = pl08x_filter_id,
-};
-
-static struct lpc32xx_mlc_platform_data lpc32xx_mlc_data = {
-   .dma_filter = pl08x_filter_id,
-};
-
-static const struct of_dev_auxdata lpc32xx_auxdata_lookup[] __initconst = {
-   OF_DEV_AUXDATA("arm,pl080", 0x3100, "pl08xdmac", &pl08x_pd),
-   OF_DEV_AUXDATA("nxp,lpc3220-slc", 0x2002, "2002.flash",
-  &lpc32xx_slc_data),
-   OF_DEV_AUXDATA("nxp,lpc3220-mlc", 0x200a8000, "200a8000.flash",
-  &lpc32xx_mlc_data),
-   { }
-};
-
 static void __init lpc3250_machine_init(void)
 {
lpc32xx_serial_init();
 
-   of_platform_default_populate(NULL, lpc32xx_auxdata_lookup, NULL);
 }
 
 static const char *const lpc32xx_dt_compat[] __initconst = {
-- 
2.25.1



[Patch v4 08/10] mtd: rawnand: lpx32xx: Request DMA channels using DT entries

2024-06-20 Thread Piotr Wojtaszczyk
Move away from pl08x platform data towards device tree.

Signed-off-by: Piotr Wojtaszczyk 
---
Changes for v4:
- This patch is new in v4

 drivers/mtd/nand/raw/lpc32xx_mlc.c | 10 +-
 drivers/mtd/nand/raw/lpc32xx_slc.c | 10 +-
 2 files changed, 2 insertions(+), 18 deletions(-)

diff --git a/drivers/mtd/nand/raw/lpc32xx_mlc.c 
b/drivers/mtd/nand/raw/lpc32xx_mlc.c
index 677fcb03f9be..e504e3c5af11 100644
--- a/drivers/mtd/nand/raw/lpc32xx_mlc.c
+++ b/drivers/mtd/nand/raw/lpc32xx_mlc.c
@@ -574,15 +574,7 @@ static int lpc32xx_dma_setup(struct lpc32xx_nand_host 
*host)
struct mtd_info *mtd = nand_to_mtd(&host->nand_chip);
dma_cap_mask_t mask;
 
-   if (!host->pdata || !host->pdata->dma_filter) {
-   dev_err(mtd->dev.parent, "no DMA platform data\n");
-   return -ENOENT;
-   }
-
-   dma_cap_zero(mask);
-   dma_cap_set(DMA_SLAVE, mask);
-   host->dma_chan = dma_request_channel(mask, host->pdata->dma_filter,
-"nand-mlc");
+   host->dma_chan = dma_request_chan(mtd->dev.parent, "rx-tx");
if (!host->dma_chan) {
dev_err(mtd->dev.parent, "Failed to request DMA channel\n");
return -EBUSY;
diff --git a/drivers/mtd/nand/raw/lpc32xx_slc.c 
b/drivers/mtd/nand/raw/lpc32xx_slc.c
index 1c5fa855b9f2..f83a31411bde 100644
--- a/drivers/mtd/nand/raw/lpc32xx_slc.c
+++ b/drivers/mtd/nand/raw/lpc32xx_slc.c
@@ -721,15 +721,7 @@ static int lpc32xx_nand_dma_setup(struct lpc32xx_nand_host 
*host)
struct mtd_info *mtd = nand_to_mtd(&host->nand_chip);
dma_cap_mask_t mask;
 
-   if (!host->pdata || !host->pdata->dma_filter) {
-   dev_err(mtd->dev.parent, "no DMA platform data\n");
-   return -ENOENT;
-   }
-
-   dma_cap_zero(mask);
-   dma_cap_set(DMA_SLAVE, mask);
-   host->dma_chan = dma_request_channel(mask, host->pdata->dma_filter,
-"nand-slc");
+   host->dma_chan = dma_request_chan(mtd->dev.parent, "rx-tx");
if (!host->dma_chan) {
dev_err(mtd->dev.parent, "Failed to request DMA channel\n");
return -EBUSY;
-- 
2.25.1



[Patch v4 09/10] ASoC: fsl: Add i2s and pcm drivers for LPC32xx CPUs

2024-06-20 Thread Piotr Wojtaszczyk
This driver was ported from an old version in linux 2.6.27 and adjusted
for the new ASoC framework and DMA API.

Signed-off-by: Piotr Wojtaszczyk 
---
Changes for v4:
- Add to MAINTAINERS
- Use guard(mutex)(&i2s_info_p->lock) when possible
- Request dma chennels using DT entries in devm_snd_dmaengine_pcm_register

Changes for v3:
- Split previous commit for separate subsystems
- Add support and  as a maintainer for the driver
- Replaced `SND_SOC` config dependency with COMPILE_TEST
- Moved `snd-soc-fsl-lpc3xxx-y` in Makefile up in the list to maintain 
alfabedical order
- Changed comment to c++ format
- replaced custom absd32() with standard abs() function
- Added clock provider check in lpc3xxx_i2s_set_dai_fmt()
- Removed empty lpc32xx_i2s_remove() function
- Reworked i2s regs definitions to include LPC3XXX prefix
- Replaced custom _BIT, _SBD with standard BIT and FIELD_PREP macros

Changes for v2:
- Coding Style cleanup
- Use dev_err_probe() for error handling in probe function
- Removed unneded err_clk_disable label
- Removed empty function
- Droped of_match_ptr in lpc32xx_i2s_match DT match table
- ASoC struct adjustmes for the latest 6.10-rc3 kernel

 MAINTAINERS |   1 +
 sound/soc/fsl/Kconfig   |   7 +
 sound/soc/fsl/Makefile  |   2 +
 sound/soc/fsl/lpc3xxx-i2s.c | 376 
 sound/soc/fsl/lpc3xxx-i2s.h |  79 
 sound/soc/fsl/lpc3xxx-pcm.c |  73 +++
 6 files changed, 538 insertions(+)
 create mode 100644 sound/soc/fsl/lpc3xxx-i2s.c
 create mode 100644 sound/soc/fsl/lpc3xxx-i2s.h
 create mode 100644 sound/soc/fsl/lpc3xxx-pcm.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 5ffe988ee282..2705f48c967d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8927,6 +8927,7 @@ L:alsa-de...@alsa-project.org (moderated for 
non-subscribers)
 L: linuxppc-dev@lists.ozlabs.org
 S: Maintained
 F: Documentation/devicetree/bindings/sound/nxp,lpc3220-i2s.yaml
+F: sound/soc/fsl/lpc3xxx-*
 N: lpc32xx
 
 FREESCALE SOC SOUND QMC DRIVER
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 270726c134b3..72f2d4d15696 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -130,6 +130,13 @@ config SND_SOC_FSL_RPMSG
  This option is only useful for out-of-tree drivers since
  in-tree drivers select it automatically.
 
+config SND_SOC_FSL_LPC3XXX
+   tristate "SoC Audio for NXP LPC32XX CPUs"
+   depends on ARCH_LPC32XX || COMPILE_TEST
+   select SND_SOC_GENERIC_DMAENGINE_PCM
+   help
+ Say Y or M if you want to add support for the LPC3XXX I2S interface.
+
 config SND_SOC_IMX_PCM_DMA
tristate
select SND_SOC_GENERIC_DMAENGINE_PCM
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 2fe78eed3a48..2a61e2f96438 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o
 snd-soc-fsl-audmix-y := fsl_audmix.o
 snd-soc-fsl-asoc-card-y := fsl-asoc-card.o
 snd-soc-fsl-asrc-y := fsl_asrc.o fsl_asrc_dma.o
+snd-soc-fsl-lpc3xxx-y := lpc3xxx-pcm.o lpc3xxx-i2s.o
 snd-soc-fsl-sai-y := fsl_sai.o
 snd-soc-fsl-ssi-y := fsl_ssi.o
 snd-soc-fsl-ssi-$(CONFIG_DEBUG_FS) += fsl_ssi_dbg.o
@@ -29,6 +30,7 @@ snd-soc-fsl-qmc-audio-y := fsl_qmc_audio.o
 obj-$(CONFIG_SND_SOC_FSL_AUDMIX) += snd-soc-fsl-audmix.o
 obj-$(CONFIG_SND_SOC_FSL_ASOC_CARD) += snd-soc-fsl-asoc-card.o
 obj-$(CONFIG_SND_SOC_FSL_ASRC) += snd-soc-fsl-asrc.o
+obj-$(CONFIG_SND_SOC_FSL_LPC3XXX) += snd-soc-fsl-lpc3xxx.o
 obj-$(CONFIG_SND_SOC_FSL_SAI) += snd-soc-fsl-sai.o
 obj-$(CONFIG_SND_SOC_FSL_SSI) += snd-soc-fsl-ssi.o
 obj-$(CONFIG_SND_SOC_FSL_SPDIF) += snd-soc-fsl-spdif.o
diff --git a/sound/soc/fsl/lpc3xxx-i2s.c b/sound/soc/fsl/lpc3xxx-i2s.c
new file mode 100644
index ..7fdba451c643
--- /dev/null
+++ b/sound/soc/fsl/lpc3xxx-i2s.c
@@ -0,0 +1,376 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+//
+// Author: Kevin Wells 
+//
+// Copyright (C) 2008 NXP Semiconductors
+// Copyright 2023 Timesys Corporation 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "lpc3xxx-i2s.h"
+
+#define I2S_PLAYBACK_FLAG 0x1
+#define I2S_CAPTURE_FLAG 0x2
+
+#define LPC3XXX_I2S_RATES ( \
+   SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
+   SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
+   SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)
+
+#define LPC3XXX_I2S_FORMATS ( \
+   SNDRV_PCM_FMTBIT_S8 | \
+   SNDRV_PCM_FMTBIT_S16_LE | \
+   SNDRV_PCM_FMTBIT_S32_LE)
+
+static void __lpc3xxx_find_clkdiv(u32 *clkx, u32 *clky, int freq, int xbytes, 
u32 clkrate)
+{
+   u32 i2srate;
+   u32 idxx, idyy;
+   u32 savedbitclkrate, diff, trate, baseclk;
+
+   /* Adjust rate for sample size (bits) and 2 channels and offset for
+* divider in clock output
+*/
+   i2srate = (freq / 100) * 2 * (8 * xbytes

[Patch v4 10/10] i2x: pnx: Use threaded irq to fix warning from del_timer_sync()

2024-06-20 Thread Piotr Wojtaszczyk
When del_timer_sync() is called in an interrupt context it throws a warning
because of potential deadlock. Threaded irq handler fixes the potential
problem.

Signed-off-by: Piotr Wojtaszczyk 
---
 drivers/i2c/busses/i2c-pnx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c
index a12525b3186b..b2ab6fb168bf 100644
--- a/drivers/i2c/busses/i2c-pnx.c
+++ b/drivers/i2c/busses/i2c-pnx.c
@@ -718,8 +718,8 @@ static int i2c_pnx_probe(struct platform_device *pdev)
ret = alg_data->irq;
goto out_clock;
}
-   ret = devm_request_irq(&pdev->dev, alg_data->irq, i2c_pnx_interrupt,
-  0, pdev->name, alg_data);
+   ret = devm_request_threaded_irq(&pdev->dev, alg_data->irq, NULL, 
i2c_pnx_interrupt,
+   IRQF_ONESHOT, pdev->name, alg_data);
if (ret)
goto out_clock;
 
-- 
2.25.1



[RFC PATCH v3 00/11] powerpc: Add support for ftrace direct and BPF trampolines

2024-06-20 Thread Naveen N Rao
This is v3 of the patches posted here:
http://lkml.kernel.org/r/cover.1718008093.git.nav...@kernel.org

Since v2, I have addressed review comments from Steven and Masahiro 
along with a few fixes. Patches 7-11 are new in this series and add 
support for ftrace direct and bpf trampolines. 

This series depends on the patch series from Benjamin Gray adding 
support for patch_ulong():
http://lkml.kernel.org/r/20240515024445.236364-1-bg...@linux.ibm.com


- Naveen


Naveen N Rao (11):
  powerpc/kprobes: Use ftrace to determine if a probe is at function
entry
  powerpc/ftrace: Unify 32-bit and 64-bit ftrace entry code
  powerpc/module_64: Convert #ifdef to IS_ENABLED()
  powerpc/ftrace: Remove pointer to struct module from dyn_arch_ftrace
  kbuild: Add generic hook for architectures to use before the final
vmlinux link
  powerpc64/ftrace: Move ftrace sequence out of line
  powerpc/ftrace: Add support for DYNAMIC_FTRACE_WITH_CALL_OPS
  powerpc/ftrace: Add support for DYNAMIC_FTRACE_WITH_DIRECT_CALLS
  samples/ftrace: Add support for ftrace direct samples on powerpc
  powerpc64/bpf: Fold bpf_jit_emit_func_call_hlp() into
bpf_jit_emit_func_call_rel()
  powerpc64/bpf: Add support for bpf trampolines

 arch/Kconfig|   3 +
 arch/powerpc/Kconfig|   9 +
 arch/powerpc/Makefile   |   8 +
 arch/powerpc/include/asm/ftrace.h   |  29 +-
 arch/powerpc/include/asm/module.h   |   5 +
 arch/powerpc/include/asm/ppc-opcode.h   |  14 +
 arch/powerpc/kernel/asm-offsets.c   |  11 +
 arch/powerpc/kernel/kprobes.c   |  18 +-
 arch/powerpc/kernel/module_64.c |  67 +-
 arch/powerpc/kernel/trace/ftrace.c  | 269 +++-
 arch/powerpc/kernel/trace/ftrace_64_pg.c|  73 +-
 arch/powerpc/kernel/trace/ftrace_entry.S| 210 --
 arch/powerpc/kernel/vmlinux.lds.S   |   3 +-
 arch/powerpc/net/bpf_jit.h  |  11 +
 arch/powerpc/net/bpf_jit_comp.c | 702 +++-
 arch/powerpc/net/bpf_jit_comp32.c   |   7 +-
 arch/powerpc/net/bpf_jit_comp64.c   |  68 +-
 arch/powerpc/tools/Makefile |  10 +
 arch/powerpc/tools/gen-ftrace-pfe-stubs.sh  |  49 ++
 samples/ftrace/ftrace-direct-modify.c   |  85 ++-
 samples/ftrace/ftrace-direct-multi-modify.c | 101 ++-
 samples/ftrace/ftrace-direct-multi.c|  79 ++-
 samples/ftrace/ftrace-direct-too.c  |  83 ++-
 samples/ftrace/ftrace-direct.c  |  69 +-
 scripts/Makefile.vmlinux|   8 +
 scripts/link-vmlinux.sh |  11 +-
 26 files changed, 1813 insertions(+), 189 deletions(-)
 create mode 100644 arch/powerpc/tools/Makefile
 create mode 100755 arch/powerpc/tools/gen-ftrace-pfe-stubs.sh


base-commit: e2b06d707dd067509cdc9ceba783c06fa6a551c2
prerequisite-patch-id: a1d50e589288239d5a8b1c1f354cd4737057c9d3
prerequisite-patch-id: da4142d56880861bd0ad7ad7087c9e2670a2ee54
prerequisite-patch-id: 609d292e054b2396b603890522a940fa0bdfb6d8
prerequisite-patch-id: 6f7213fb77b1260defbf43be0e47bff9c80054cc
prerequisite-patch-id: ad3b71bf071ae4ba1bee5b087e61a2055772a74f
-- 
2.45.2




[RFC PATCH v3 02/11] powerpc/ftrace: Unify 32-bit and 64-bit ftrace entry code

2024-06-20 Thread Naveen N Rao
On 32-bit powerpc, gcc generates a three instruction sequence for
function profiling:
mflrr0
stw r0, 4(r1)
bl  _mcount

On kernel boot, the call to _mcount() is nop-ed out, to be patched back
in when ftrace is actually enabled. The 'stw' instruction therefore is
not necessary unless ftrace is enabled. Nop it out during ftrace init.

When ftrace is enabled, we want the 'stw' so that stack unwinding works
properly. Perform the same within the ftrace handler, similar to 64-bit
powerpc.

For 64-bit powerpc, early versions of gcc used to emit a three
instruction sequence for function profiling (with -mprofile-kernel) with
a 'std' instruction to mimic the 'stw' above. Address that scenario also
by nop-ing out the 'std' instruction during ftrace init.

Signed-off-by: Naveen N Rao 
---
 arch/powerpc/kernel/trace/ftrace.c   | 6 --
 arch/powerpc/kernel/trace/ftrace_entry.S | 4 ++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/kernel/trace/ftrace.c 
b/arch/powerpc/kernel/trace/ftrace.c
index d8d6b4fd9a14..463bd7531dc8 100644
--- a/arch/powerpc/kernel/trace/ftrace.c
+++ b/arch/powerpc/kernel/trace/ftrace.c
@@ -241,13 +241,15 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace 
*rec)
/* Expected sequence: 'mflr r0', 'stw r0,4(r1)', 'bl _mcount' */
ret = ftrace_validate_inst(ip - 8, ppc_inst(PPC_RAW_MFLR(_R0)));
if (!ret)
-   ret = ftrace_validate_inst(ip - 4, 
ppc_inst(PPC_RAW_STW(_R0, _R1, 4)));
+   ret = ftrace_modify_code(ip - 4, 
ppc_inst(PPC_RAW_STW(_R0, _R1, 4)),
+ppc_inst(PPC_RAW_NOP()));
} else if (IS_ENABLED(CONFIG_MPROFILE_KERNEL)) {
/* Expected sequence: 'mflr r0', ['std r0,16(r1)'], 'bl 
_mcount' */
ret = ftrace_read_inst(ip - 4, &old);
if (!ret && !ppc_inst_equal(old, ppc_inst(PPC_RAW_MFLR(_R0 {
ret = ftrace_validate_inst(ip - 8, 
ppc_inst(PPC_RAW_MFLR(_R0)));
-   ret |= ftrace_validate_inst(ip - 4, 
ppc_inst(PPC_RAW_STD(_R0, _R1, 16)));
+   ret |= ftrace_modify_code(ip - 4, 
ppc_inst(PPC_RAW_STD(_R0, _R1, 16)),
+ ppc_inst(PPC_RAW_NOP()));
}
} else {
return -EINVAL;
diff --git a/arch/powerpc/kernel/trace/ftrace_entry.S 
b/arch/powerpc/kernel/trace/ftrace_entry.S
index 76dbe9fd2c0f..244a1c7bb1e8 100644
--- a/arch/powerpc/kernel/trace/ftrace_entry.S
+++ b/arch/powerpc/kernel/trace/ftrace_entry.S
@@ -33,6 +33,8 @@
  * and then arrange for the ftrace function to be called.
  */
 .macro ftrace_regs_entry allregs
+   /* Save the original return address in A's stack frame */
+   PPC_STL r0, LRSAVE(r1)
/* Create a minimal stack frame for representing B */
PPC_STLUr1, -STACK_FRAME_MIN_SIZE(r1)
 
@@ -44,8 +46,6 @@
SAVE_GPRS(3, 10, r1)
 
 #ifdef CONFIG_PPC64
-   /* Save the original return address in A's stack frame */
-   std r0, LRSAVE+SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE(r1)
/* Ok to continue? */
lbz r3, PACA_FTRACE_ENABLED(r13)
cmpdi   r3, 0
-- 
2.45.2




[RFC PATCH v3 03/11] powerpc/module_64: Convert #ifdef to IS_ENABLED()

2024-06-20 Thread Naveen N Rao
Minor refactor for converting #ifdef to IS_ENABLED().

Signed-off-by: Naveen N Rao 
---
 arch/powerpc/kernel/module_64.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index e9bab599d0c2..c202be11683b 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -241,14 +241,13 @@ static unsigned long get_stubs_size(const Elf64_Ehdr *hdr,
}
}
 
-#ifdef CONFIG_DYNAMIC_FTRACE
/* make the trampoline to the ftrace_caller */
-   relocs++;
-#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
+   if (IS_ENABLED(CONFIG_DYNAMIC_FTRACE))
+   relocs++;
+
/* an additional one for ftrace_regs_caller */
-   relocs++;
-#endif
-#endif
+   if (IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_REGS))
+   relocs++;
 
pr_debug("Looks like a total of %lu stubs, max\n", relocs);
return relocs * sizeof(struct ppc64_stub_entry);
-- 
2.45.2




[RFC PATCH v3 04/11] powerpc/ftrace: Remove pointer to struct module from dyn_arch_ftrace

2024-06-20 Thread Naveen N Rao
Pointer to struct module is only relevant for ftrace records belonging
to kernel modules. Having this field in dyn_arch_ftrace wastes memory
for all ftrace records belonging to the kernel. Remove the same in
favour of looking up the module from the ftrace record address, similar
to other architectures.

Signed-off-by: Naveen N Rao 
---
 arch/powerpc/include/asm/ftrace.h|  1 -
 arch/powerpc/kernel/trace/ftrace.c   | 54 +++---
 arch/powerpc/kernel/trace/ftrace_64_pg.c | 73 +++-
 3 files changed, 65 insertions(+), 63 deletions(-)

diff --git a/arch/powerpc/include/asm/ftrace.h 
b/arch/powerpc/include/asm/ftrace.h
index 107fc5a48456..201f9d15430a 100644
--- a/arch/powerpc/include/asm/ftrace.h
+++ b/arch/powerpc/include/asm/ftrace.h
@@ -26,7 +26,6 @@ unsigned long prepare_ftrace_return(unsigned long parent, 
unsigned long ip,
 struct module;
 struct dyn_ftrace;
 struct dyn_arch_ftrace {
-   struct module *mod;
 };
 
 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS
diff --git a/arch/powerpc/kernel/trace/ftrace.c 
b/arch/powerpc/kernel/trace/ftrace.c
index 463bd7531dc8..2cff37b5fd2c 100644
--- a/arch/powerpc/kernel/trace/ftrace.c
+++ b/arch/powerpc/kernel/trace/ftrace.c
@@ -106,28 +106,48 @@ static unsigned long find_ftrace_tramp(unsigned long ip)
return 0;
 }
 
+#ifdef CONFIG_MODULES
+static unsigned long ftrace_lookup_module_stub(unsigned long ip, unsigned long 
addr)
+{
+   struct module *mod = NULL;
+
+   /*
+* NOTE: __module_text_address() must be called with preemption
+* disabled, but we can rely on ftrace_lock to ensure that 'mod'
+* retains its validity throughout the remainder of this code.
+*/
+   preempt_disable();
+   mod = __module_text_address(ip);
+   preempt_enable();
+
+   if (!mod)
+   pr_err("No module loaded at addr=%lx\n", ip);
+
+   return (addr == (unsigned long)ftrace_caller ? mod->arch.tramp : 
mod->arch.tramp_regs);
+}
+#else
+static unsigned long ftrace_lookup_module_stub(unsigned long ip, unsigned long 
addr)
+{
+   return 0;
+}
+#endif
+
 static int ftrace_get_call_inst(struct dyn_ftrace *rec, unsigned long addr, 
ppc_inst_t *call_inst)
 {
unsigned long ip = rec->ip;
unsigned long stub;
 
-   if (is_offset_in_branch_range(addr - ip)) {
+   if (is_offset_in_branch_range(addr - ip))
/* Within range */
stub = addr;
-#ifdef CONFIG_MODULES
-   } else if (rec->arch.mod) {
-   /* Module code would be going to one of the module stubs */
-   stub = (addr == (unsigned long)ftrace_caller ? 
rec->arch.mod->arch.tramp :
-  
rec->arch.mod->arch.tramp_regs);
-#endif
-   } else if (core_kernel_text(ip)) {
+   else if (core_kernel_text(ip))
/* We would be branching to one of our ftrace stubs */
stub = find_ftrace_tramp(ip);
-   if (!stub) {
-   pr_err("0x%lx: No ftrace stubs reachable\n", ip);
-   return -EINVAL;
-   }
-   } else {
+   else
+   stub = ftrace_lookup_module_stub(ip, addr);
+
+   if (!stub) {
+   pr_err("0x%lx: No ftrace stubs reachable\n", ip);
return -EINVAL;
}
 
@@ -258,14 +278,6 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace 
*rec)
if (ret)
return ret;
 
-   if (!core_kernel_text(ip)) {
-   if (!mod) {
-   pr_err("0x%lx: No module provided for non-kernel 
address\n", ip);
-   return -EFAULT;
-   }
-   rec->arch.mod = mod;
-   }
-
/* Nop-out the ftrace location */
new = ppc_inst(PPC_RAW_NOP());
addr = MCOUNT_ADDR;
diff --git a/arch/powerpc/kernel/trace/ftrace_64_pg.c 
b/arch/powerpc/kernel/trace/ftrace_64_pg.c
index 12fab1803bcf..a563b9ffcc2b 100644
--- a/arch/powerpc/kernel/trace/ftrace_64_pg.c
+++ b/arch/powerpc/kernel/trace/ftrace_64_pg.c
@@ -116,6 +116,24 @@ static unsigned long find_bl_target(unsigned long ip, 
ppc_inst_t op)
 }
 
 #ifdef CONFIG_MODULES
+static struct module *ftrace_lookup_module(struct dyn_ftrace *rec)
+{
+   struct module *mod;
+   /*
+* NOTE: __module_text_address() must be called with preemption
+* disabled, but we can rely on ftrace_lock to ensure that 'mod'
+* retains its validity throughout the remainder of this code.
+*/
+   preempt_disable();
+   mod = __module_text_address(rec->ip);
+   preempt_enable();
+
+   if (!mod)
+   pr_err("No module loaded at addr=%lx\n", rec->ip);
+
+   return mod;
+}
+
 static int
 __ftrace_make_nop(struct module *mod,
  struct dyn_ftrace *rec, unsigned long addr)
@@ -124,6 +142,12 @@ __ftrace_make_nop(struct module *mod,
unsigned long ip = rec->ip;
ppc_ins

[RFC PATCH v3 05/11] kbuild: Add generic hook for architectures to use before the final vmlinux link

2024-06-20 Thread Naveen N Rao
On powerpc, we would like to be able to make a pass on vmlinux.o and
generate a new object file to be linked into vmlinux. Add a generic pass
in Makefile.vmlinux that architectures can use for this purpose.

Architectures need to select CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX and must
provide arch//tools/Makefile with .arch.vmlinux.o target, which
will be invoked prior to the final vmlinux link step.

Signed-off-by: Naveen N Rao 
---
 arch/Kconfig |  3 +++
 scripts/Makefile.vmlinux |  8 
 scripts/link-vmlinux.sh  | 11 ---
 3 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 975dd22a2dbd..649f0903e7ef 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -1643,4 +1643,7 @@ config CC_HAS_SANE_FUNCTION_ALIGNMENT
 config ARCH_NEED_CMPXCHG_1_EMU
bool
 
+config ARCH_WANTS_PRE_LINK_VMLINUX
+   def_bool n
+
 endmenu
diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux
index 49946cb96844..6410e0be7f52 100644
--- a/scripts/Makefile.vmlinux
+++ b/scripts/Makefile.vmlinux
@@ -22,6 +22,14 @@ targets += .vmlinux.export.o
 vmlinux: .vmlinux.export.o
 endif
 
+ifdef CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX
+targets += .arch.vmlinux.o
+.arch.vmlinux.o: vmlinux.o FORCE
+   $(Q)$(MAKE) $(build)=arch/$(SRCARCH)/tools .arch.vmlinux.o
+
+vmlinux: .arch.vmlinux.o
+endif
+
 ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink)
 
 # Final link of vmlinux with optional arch pass after final link
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index 518c70b8db50..aafaed1412ea 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -122,7 +122,7 @@ gen_btf()
return 1
fi
 
-   vmlinux_link ${1}
+   vmlinux_link ${1} ${arch_vmlinux_o}
 
info "BTF" ${2}
LLVM_OBJCOPY="${OBJCOPY}" ${PAHOLE} -J ${PAHOLE_FLAGS} ${1}
@@ -178,7 +178,7 @@ kallsyms_step()
kallsymso=${kallsyms_vmlinux}.o
kallsyms_S=${kallsyms_vmlinux}.S
 
-   vmlinux_link ${kallsyms_vmlinux} "${kallsymso_prev}" 
${btf_vmlinux_bin_o}
+   vmlinux_link ${kallsyms_vmlinux} "${kallsymso_prev}" 
${btf_vmlinux_bin_o} ${arch_vmlinux_o}
mksysmap ${kallsyms_vmlinux} ${kallsyms_vmlinux}.syms
kallsyms ${kallsyms_vmlinux}.syms ${kallsyms_S}
 
@@ -223,6 +223,11 @@ fi
 
 ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init 
init/version-timestamp.o
 
+arch_vmlinux_o=""
+if is_enabled CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX; then
+   arch_vmlinux_o=.arch.vmlinux.o
+fi
+
 btf_vmlinux_bin_o=""
 if is_enabled CONFIG_DEBUG_INFO_BTF; then
btf_vmlinux_bin_o=.btf.vmlinux.bin.o
@@ -273,7 +278,7 @@ if is_enabled CONFIG_KALLSYMS; then
fi
 fi
 
-vmlinux_link vmlinux "${kallsymso}" ${btf_vmlinux_bin_o}
+vmlinux_link vmlinux "${kallsymso}" ${btf_vmlinux_bin_o} ${arch_vmlinux_o}
 
 # fill in BTF IDs
 if is_enabled CONFIG_DEBUG_INFO_BTF && is_enabled CONFIG_BPF; then
-- 
2.45.2




[RFC PATCH v3 06/11] powerpc64/ftrace: Move ftrace sequence out of line

2024-06-20 Thread Naveen N Rao
Function profile sequence on powerpc includes two instructions at the
beginning of each function:
mflrr0
bl  ftrace_caller

The call to ftrace_caller() gets nop'ed out during kernel boot and is
patched in when ftrace is enabled.

Given the sequence, we cannot return from ftrace_caller with 'blr' as we
need to keep LR and r0 intact. This results in link stack imbalance when
ftrace is enabled. To address that, we would like to use a three
instruction sequence:
mflrr0
bl  ftrace_caller
mtlrr0

Further more, to support DYNAMIC_FTRACE_WITH_CALL_OPS, we need to
reserve two instruction slots before the function. This results in a
total of five instruction slots to be reserved for ftrace use on each
function that is traced.

Move the function profile sequence out-of-line to minimize its impact.
To do this, we reserve a single nop at function entry using
-fpatchable-function-entry=1 and add a pass on vmlinux.o to determine
the total number of functions that can be traced. This is then used to
generate a .S file reserving the appropriate amount of space for use as
ftrace stubs, which is built and linked into vmlinux.

On bootup, the stub space is split into separate stubs per function and
populated with the proper instruction sequence. A pointer to the
associated stub is maintained in dyn_arch_ftrace.

For modules, space for ftrace stubs is reserved from the generic module
stub space.

This is restricted to and enabled by default only on 64-bit powerpc.

Signed-off-by: Naveen N Rao 
---
 arch/powerpc/Kconfig   |   5 +
 arch/powerpc/Makefile  |   4 +
 arch/powerpc/include/asm/ftrace.h  |  10 ++
 arch/powerpc/include/asm/module.h  |   5 +
 arch/powerpc/kernel/asm-offsets.c  |   4 +
 arch/powerpc/kernel/module_64.c|  58 +++-
 arch/powerpc/kernel/trace/ftrace.c | 147 +++--
 arch/powerpc/kernel/trace/ftrace_entry.S   |  99 ++
 arch/powerpc/kernel/vmlinux.lds.S  |   3 +-
 arch/powerpc/tools/Makefile|  10 ++
 arch/powerpc/tools/gen-ftrace-pfe-stubs.sh |  48 +++
 11 files changed, 355 insertions(+), 38 deletions(-)
 create mode 100644 arch/powerpc/tools/Makefile
 create mode 100755 arch/powerpc/tools/gen-ftrace-pfe-stubs.sh

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index c88c6d46a5bc..dd7efca2275a 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -568,6 +568,11 @@ config ARCH_USING_PATCHABLE_FUNCTION_ENTRY
def_bool 
$(success,$(srctree)/arch/powerpc/tools/gcc-check-fpatchable-function-entry.sh 
$(CC) -mlittle-endian) if PPC64 && CPU_LITTLE_ENDIAN
def_bool 
$(success,$(srctree)/arch/powerpc/tools/gcc-check-fpatchable-function-entry.sh 
$(CC) -mbig-endian) if PPC64 && CPU_BIG_ENDIAN
 
+config FTRACE_PFE_OUT_OF_LINE
+   def_bool PPC64 && ARCH_USING_PATCHABLE_FUNCTION_ENTRY
+   depends on PPC64
+   select ARCH_WANTS_PRE_LINK_VMLINUX
+
 config HOTPLUG_CPU
bool "Support for enabling/disabling CPUs"
depends on SMP && (PPC_PSERIES || \
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index a8479c881cac..bb920d48ec6e 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -155,7 +155,11 @@ CC_FLAGS_NO_FPU:= $(call 
cc-option,-msoft-float)
 ifdef CONFIG_FUNCTION_TRACER
 ifdef CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY
 KBUILD_CPPFLAGS+= -DCC_USING_PATCHABLE_FUNCTION_ENTRY
+ifdef CONFIG_FTRACE_PFE_OUT_OF_LINE
+CC_FLAGS_FTRACE := -fpatchable-function-entry=1
+else
 CC_FLAGS_FTRACE := -fpatchable-function-entry=2
+endif
 else
 CC_FLAGS_FTRACE := -pg
 ifdef CONFIG_MPROFILE_KERNEL
diff --git a/arch/powerpc/include/asm/ftrace.h 
b/arch/powerpc/include/asm/ftrace.h
index 201f9d15430a..9da1da0f87b4 100644
--- a/arch/powerpc/include/asm/ftrace.h
+++ b/arch/powerpc/include/asm/ftrace.h
@@ -26,6 +26,9 @@ unsigned long prepare_ftrace_return(unsigned long parent, 
unsigned long ip,
 struct module;
 struct dyn_ftrace;
 struct dyn_arch_ftrace {
+#ifdef CONFIG_FTRACE_PFE_OUT_OF_LINE
+   unsigned long pfe_stub;
+#endif
 };
 
 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS
@@ -132,6 +135,13 @@ static inline u8 this_cpu_get_ftrace_enabled(void) { 
return 1; }
 
 #ifdef CONFIG_FUNCTION_TRACER
 extern unsigned int ftrace_tramp_text[], ftrace_tramp_init[];
+#ifdef CONFIG_FTRACE_PFE_OUT_OF_LINE
+struct ftrace_pfe_stub {
+   u32 insn[4];
+};
+extern struct ftrace_pfe_stub ftrace_pfe_stub_text[], 
ftrace_pfe_stub_inittext[];
+extern unsigned long ftrace_pfe_stub_text_count, 
ftrace_pfe_stub_inittext_count;
+#endif
 void ftrace_free_init_tramp(void);
 unsigned long ftrace_call_adjust(unsigned long addr);
 #else
diff --git a/arch/powerpc/include/asm/module.h 
b/arch/powerpc/include/asm/module.h
index 300c777cc307..28dbd1ec5593 100644
--- a/arch/powerpc/include/asm/module.h
+++ b/arch/powerpc/include/asm/module.h
@@ -47,6 +47,11 @@ struct mod_ar

[RFC PATCH v3 07/11] powerpc/ftrace: Add support for DYNAMIC_FTRACE_WITH_CALL_OPS

2024-06-20 Thread Naveen N Rao
Implement support for DYNAMIC_FTRACE_WITH_CALL_OPS similar to the
arm64 implementation.

This works by patching-in a pointer to an associated ftrace_ops
structure before each traceable function. If multiple ftrace_ops are
associated with a call site, then a special ftrace_list_ops is used to
enable iterating over all the registered ftrace_ops. If no ftrace_ops
are associated with a call site, then a special ftrace_nop_ops structure
is used to render the ftrace call as a no-op. ftrace trampoline can then
read the associated ftrace_ops for a call site by loading from an offset
from the LR, and branch directly to the associated function.

The primary advantage with this approach is that we don't have to
iterate over all the registered ftrace_ops for call sites that have a
single ftrace_ops registered. This is the equivalent of implementing
support for dynamic ftrace trampolines, which set up a special ftrace
trampoline for each registered ftrace_ops and have individual call sites
branch into those directly.

A secondary advantage is that this gives us a way to add support for
direct ftrace callers without having to resort to using stubs. The
address of the direct call trampoline can be loaded from the ftrace_ops
structure.

To support this, we reserve a nop before each function on 32-bit
powerpc. For 64-bit powerpc, two nops are reserved before each
out-of-line stub. During ftrace activation, we update this location with
the associated ftrace_ops pointer. Then, on ftrace entry, we load from
this location and call into ftrace_ops->func().

For 64-bit powerpc, we ensure that the out-of-line stub area is
doubleword aligned so that ftrace_ops address can be updated atomically.

Signed-off-by: Naveen N Rao 
---
 arch/powerpc/Kconfig   |  1 +
 arch/powerpc/Makefile  |  4 ++
 arch/powerpc/include/asm/ftrace.h  |  5 +-
 arch/powerpc/kernel/asm-offsets.c  |  4 ++
 arch/powerpc/kernel/trace/ftrace.c | 59 +-
 arch/powerpc/kernel/trace/ftrace_entry.S   | 34 ++---
 arch/powerpc/tools/gen-ftrace-pfe-stubs.sh |  5 +-
 7 files changed, 101 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index dd7efca2275a..fde64ad19de5 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -235,6 +235,7 @@ config PPC
select HAVE_DEBUG_STACKOVERFLOW
select HAVE_DYNAMIC_FTRACE
select HAVE_DYNAMIC_FTRACE_WITH_ARGSif 
ARCH_USING_PATCHABLE_FUNCTION_ENTRY || MPROFILE_KERNEL || PPC32
+   select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS if FTRACE_PFE_OUT_OF_LINE || 
(PPC32 && ARCH_USING_PATCHABLE_FUNCTION_ENTRY)
select HAVE_DYNAMIC_FTRACE_WITH_REGSif 
ARCH_USING_PATCHABLE_FUNCTION_ENTRY || MPROFILE_KERNEL || PPC32
select HAVE_EBPF_JIT
select HAVE_EFFICIENT_UNALIGNED_ACCESS
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index bb920d48ec6e..c3e577dea137 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -158,8 +158,12 @@ KBUILD_CPPFLAGS+= -DCC_USING_PATCHABLE_FUNCTION_ENTRY
 ifdef CONFIG_FTRACE_PFE_OUT_OF_LINE
 CC_FLAGS_FTRACE := -fpatchable-function-entry=1
 else
+ifdef CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS # PPC32 only
+CC_FLAGS_FTRACE := -fpatchable-function-entry=3,1
+else
 CC_FLAGS_FTRACE := -fpatchable-function-entry=2
 endif
+endif
 else
 CC_FLAGS_FTRACE := -pg
 ifdef CONFIG_MPROFILE_KERNEL
diff --git a/arch/powerpc/include/asm/ftrace.h 
b/arch/powerpc/include/asm/ftrace.h
index 9da1da0f87b4..938cecf72eb1 100644
--- a/arch/powerpc/include/asm/ftrace.h
+++ b/arch/powerpc/include/asm/ftrace.h
@@ -137,8 +137,11 @@ static inline u8 this_cpu_get_ftrace_enabled(void) { 
return 1; }
 extern unsigned int ftrace_tramp_text[], ftrace_tramp_init[];
 #ifdef CONFIG_FTRACE_PFE_OUT_OF_LINE
 struct ftrace_pfe_stub {
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS
+   struct ftrace_ops *ftrace_op;
+#endif
u32 insn[4];
-};
+} __aligned(sizeof(unsigned long));
 extern struct ftrace_pfe_stub ftrace_pfe_stub_text[], 
ftrace_pfe_stub_inittext[];
 extern unsigned long ftrace_pfe_stub_text_count, 
ftrace_pfe_stub_inittext_count;
 #endif
diff --git a/arch/powerpc/kernel/asm-offsets.c 
b/arch/powerpc/kernel/asm-offsets.c
index 5f1a411d714c..a11ea5f4d86a 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -678,5 +678,9 @@ int main(void)
DEFINE(FTRACE_PFE_STUB_SIZE, sizeof(struct ftrace_pfe_stub));
 #endif
 
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS
+   OFFSET(FTRACE_OPS_FUNC, ftrace_ops, func);
+#endif
+
return 0;
 }
diff --git a/arch/powerpc/kernel/trace/ftrace.c 
b/arch/powerpc/kernel/trace/ftrace.c
index 9f3c10307331..028548312c23 100644
--- a/arch/powerpc/kernel/trace/ftrace.c
+++ b/arch/powerpc/kernel/trace/ftrace.c
@@ -38,8 +38,11 @@ unsigned long ftrace_call_adjust(unsigned long addr)
return 0;
 
if (IS_ENABLED(CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENT

[RFC PATCH v3 08/11] powerpc/ftrace: Add support for DYNAMIC_FTRACE_WITH_DIRECT_CALLS

2024-06-20 Thread Naveen N Rao
Add support for DYNAMIC_FTRACE_WITH_DIRECT_CALLS similar to the arm64
implementation.

ftrace direct calls allow custom trampolines to be called into directly
from function ftrace call sites, bypassing the ftrace trampoline
completely. This functionality is currently utilized by BPF trampolines
to hook into kernel function entries.

Since we have limited relative branch range, we support ftrace direct
calls through support for DYNAMIC_FTRACE_WITH_CALL_OPS. In this
approach, ftrace trampoline is not entirely bypassed. Rather, it is
re-purposed into a stub that reads direct_call field from the associated
ftrace_ops structure and branches into that, if it is not NULL. For
this, it is sufficient if we can ensure that the ftrace trampoline is
reachable from all traceable functions.

When multiple ftrace_ops are associated with a call site, we utilize a
call back to set pt_regs->orig_gpr3 that can then be tested on the
return path from the ftrace trampoline to branch into the direct caller.

Signed-off-by: Naveen N Rao 
---
 arch/powerpc/Kconfig |  1 +
 arch/powerpc/include/asm/ftrace.h| 15 
 arch/powerpc/kernel/asm-offsets.c|  3 +
 arch/powerpc/kernel/trace/ftrace.c   |  9 +++
 arch/powerpc/kernel/trace/ftrace_entry.S | 99 ++--
 5 files changed, 105 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index fde64ad19de5..96ae653bdcde 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -236,6 +236,7 @@ config PPC
select HAVE_DYNAMIC_FTRACE
select HAVE_DYNAMIC_FTRACE_WITH_ARGSif 
ARCH_USING_PATCHABLE_FUNCTION_ENTRY || MPROFILE_KERNEL || PPC32
select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS if FTRACE_PFE_OUT_OF_LINE || 
(PPC32 && ARCH_USING_PATCHABLE_FUNCTION_ENTRY)
+   select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS if 
HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS
select HAVE_DYNAMIC_FTRACE_WITH_REGSif 
ARCH_USING_PATCHABLE_FUNCTION_ENTRY || MPROFILE_KERNEL || PPC32
select HAVE_EBPF_JIT
select HAVE_EFFICIENT_UNALIGNED_ACCESS
diff --git a/arch/powerpc/include/asm/ftrace.h 
b/arch/powerpc/include/asm/ftrace.h
index 938cecf72eb1..fc0f25b10e86 100644
--- a/arch/powerpc/include/asm/ftrace.h
+++ b/arch/powerpc/include/asm/ftrace.h
@@ -147,6 +147,21 @@ extern unsigned long ftrace_pfe_stub_text_count, 
ftrace_pfe_stub_inittext_count;
 #endif
 void ftrace_free_init_tramp(void);
 unsigned long ftrace_call_adjust(unsigned long addr);
+
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
+/*
+ * When an ftrace registered caller is tracing a function that is also set by a
+ * register_ftrace_direct() call, it needs to be differentiated in the
+ * ftrace_caller trampoline so that the direct call can be invoked after the
+ * other ftrace ops. To do this, place the direct caller in the orig_gpr3 field
+ * of pt_regs. This tells ftrace_caller that there's a direct caller.
+ */
+static inline void arch_ftrace_set_direct_caller(struct ftrace_regs *fregs, 
unsigned long addr)
+{
+   struct pt_regs *regs = &fregs->regs;
+   regs->orig_gpr3 = addr;
+}
+#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
 #else
 static inline void ftrace_free_init_tramp(void) { }
 static inline unsigned long ftrace_call_adjust(unsigned long addr) { return 
addr; }
diff --git a/arch/powerpc/kernel/asm-offsets.c 
b/arch/powerpc/kernel/asm-offsets.c
index a11ea5f4d86a..0b955dddeb28 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -680,6 +680,9 @@ int main(void)
 
 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS
OFFSET(FTRACE_OPS_FUNC, ftrace_ops, func);
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
+   OFFSET(FTRACE_OPS_DIRECT_CALL, ftrace_ops, direct_call);
+#endif
 #endif
 
return 0;
diff --git a/arch/powerpc/kernel/trace/ftrace.c 
b/arch/powerpc/kernel/trace/ftrace.c
index 028548312c23..799612ee270f 100644
--- a/arch/powerpc/kernel/trace/ftrace.c
+++ b/arch/powerpc/kernel/trace/ftrace.c
@@ -153,6 +153,15 @@ static int ftrace_get_call_inst(struct dyn_ftrace *rec, 
unsigned long addr, ppc_
if (IS_ENABLED(CONFIG_FTRACE_PFE_OUT_OF_LINE))
ip = ftrace_get_pfe_stub(rec) + MCOUNT_INSN_SIZE; /* second 
instruction in stub */
 
+   if (!is_offset_in_branch_range(addr - ip) && addr != FTRACE_ADDR && 
addr != FTRACE_REGS_ADDR) {
+   /* This can only happen with ftrace direct */
+   if (!IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS)) {
+   pr_err("0x%lx (0x%lx): Unexpected target address 
0x%lx\n", ip, rec->ip, addr);
+   return -EINVAL;
+   }
+   addr = FTRACE_ADDR;
+   }
+
if (is_offset_in_branch_range(addr - ip))
/* Within range */
stub = addr;
diff --git a/arch/powerpc/kernel/trace/ftrace_entry.S 
b/arch/powerpc/kernel/trace/ftrace_entry.S
index a76aedd970a6..d5a63e60aafa 100644
--- a/arc

[RFC PATCH v3 01/11] powerpc/kprobes: Use ftrace to determine if a probe is at function entry

2024-06-20 Thread Naveen N Rao
Rather than hard-coding the offset into a function to be used to
determine if a kprobe is at function entry, use ftrace_location() to
determine the ftrace location within the function and categorize all
instructions till that offset to be function entry.

For functions that cannot be traced, we fall back to using a fixed
offset of 8 (two instructions) to categorize a probe as being at
function entry for 64-bit elfv2, unless we are using pcrel.

Acked-by: Masami Hiramatsu (Google) 
Signed-off-by: Naveen N Rao 
---
 arch/powerpc/kernel/kprobes.c | 18 --
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 14c5ddec3056..ca204f4f21c1 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -105,24 +105,22 @@ kprobe_opcode_t *kprobe_lookup_name(const char *name, 
unsigned int offset)
return addr;
 }
 
-static bool arch_kprobe_on_func_entry(unsigned long offset)
+static bool arch_kprobe_on_func_entry(unsigned long addr, unsigned long offset)
 {
-#ifdef CONFIG_PPC64_ELF_ABI_V2
-#ifdef CONFIG_KPROBES_ON_FTRACE
-   return offset <= 16;
-#else
-   return offset <= 8;
-#endif
-#else
+   unsigned long ip = ftrace_location(addr);
+
+   if (ip)
+   return offset <= (ip - addr);
+   if (IS_ENABLED(CONFIG_PPC64_ELF_ABI_V2) && 
!IS_ENABLED(CONFIG_PPC_KERNEL_PCREL))
+   return offset <= 8;
return !offset;
-#endif
 }
 
 /* XXX try and fold the magic of kprobe_lookup_name() in this */
 kprobe_opcode_t *arch_adjust_kprobe_addr(unsigned long addr, unsigned long 
offset,
 bool *on_func_entry)
 {
-   *on_func_entry = arch_kprobe_on_func_entry(offset);
+   *on_func_entry = arch_kprobe_on_func_entry(addr, offset);
return (kprobe_opcode_t *)(addr + offset);
 }
 
-- 
2.45.2




[RFC PATCH v3 09/11] samples/ftrace: Add support for ftrace direct samples on powerpc

2024-06-20 Thread Naveen N Rao
Add powerpc 32-bit and 64-bit samples for ftrace direct. This serves to
show the sample instruction sequence to be used by ftrace direct calls
to adhere to the ftrace ABI.

On 64-bit powerpc, TOC setup requires some additional work.

Signed-off-by: Naveen N Rao 
---
 arch/powerpc/Kconfig|   2 +
 samples/ftrace/ftrace-direct-modify.c   |  85 +++-
 samples/ftrace/ftrace-direct-multi-modify.c | 101 +++-
 samples/ftrace/ftrace-direct-multi.c|  79 ++-
 samples/ftrace/ftrace-direct-too.c  |  83 +++-
 samples/ftrace/ftrace-direct.c  |  69 -
 6 files changed, 414 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 96ae653bdcde..cf5780d6f7bf 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -275,6 +275,8 @@ config PPC
select HAVE_REGS_AND_STACK_ACCESS_API
select HAVE_RELIABLE_STACKTRACE
select HAVE_RSEQ
+   select HAVE_SAMPLE_FTRACE_DIRECTif 
HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
+   select HAVE_SAMPLE_FTRACE_DIRECT_MULTI  if 
HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
select HAVE_SETUP_PER_CPU_AREA  if PPC64
select HAVE_SOFTIRQ_ON_OWN_STACK
select HAVE_STACKPROTECTOR  if PPC32 && 
$(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r2)
diff --git a/samples/ftrace/ftrace-direct-modify.c 
b/samples/ftrace/ftrace-direct-modify.c
index 81220390851a..fa8996e251c8 100644
--- a/samples/ftrace/ftrace-direct-modify.c
+++ b/samples/ftrace/ftrace-direct-modify.c
@@ -2,7 +2,7 @@
 #include 
 #include 
 #include 
-#ifndef CONFIG_ARM64
+#if !defined(CONFIG_ARM64) && !defined(CONFIG_PPC32)
 #include 
 #endif
 
@@ -199,6 +199,89 @@ asm (
 
 #endif /* CONFIG_LOONGARCH */
 
+#ifdef CONFIG_PPC
+#include 
+
+#ifdef CONFIG_PPC64
+#define STACK_FRAME_SIZE 48
+#else
+#define STACK_FRAME_SIZE 24
+#endif
+
+#if defined(CONFIG_PPC64_ELF_ABI_V2) && !defined(CONFIG_PPC_KERNEL_PCREL)
+#define PPC64_TOC_SAVE_AND_UPDATE  \
+"  std 2, 24(1)\n" \
+"  bcl 20, 31, 1f\n"   \
+"   1: mflr12\n"   \
+"  ld  2, (99f - 1b)(12)\n"
+#define PPC64_TOC_RESTORE  \
+"  ld  2, 24(1)\n"
+#define PPC64_TOC  \
+"   99:.quad   .TOC.@tocbase\n"
+#else
+#define PPC64_TOC_SAVE_AND_UPDATE ""
+#define PPC64_TOC_RESTORE ""
+#define PPC64_TOC ""
+#endif
+
+#ifdef CONFIG_FTRACE_PFE_OUT_OF_LINE
+#define PPC_FTRACE_RESTORE_LR  \
+   PPC_LL" 0, "__stringify(PPC_LR_STKOFF)"(1)\n"   \
+"  mtlr0\n"
+#define PPC_FTRACE_RET \
+"  blr\n"
+#else
+#define PPC_FTRACE_RESTORE_LR  \
+   PPC_LL" 0, "__stringify(PPC_LR_STKOFF)"(1)\n"   \
+"  mtctr   0\n"
+#define PPC_FTRACE_RET \
+"  mtlr0\n"\
+"  bctr\n"
+#endif
+
+asm (
+"  .pushsection.text, \"ax\", @progbits\n"
+"  .type   my_tramp1, @function\n"
+"  .globl  my_tramp1\n"
+"   my_tramp1:\n"
+   PPC_STL"0, "__stringify(PPC_LR_STKOFF)"(1)\n"
+   PPC_STLU"   1, -"__stringify(STACK_FRAME_MIN_SIZE)"(1)\n"
+"  mflr0\n"
+   PPC_STL"0, "__stringify(PPC_LR_STKOFF)"(1)\n"
+   PPC_STLU"   1, -"__stringify(STACK_FRAME_SIZE)"(1)\n"
+   PPC64_TOC_SAVE_AND_UPDATE
+"  bl  my_direct_func1\n"
+   PPC64_TOC_RESTORE
+"  addi1, 1, "__stringify(STACK_FRAME_SIZE)"\n"
+   PPC_FTRACE_RESTORE_LR
+"  addi1, 1, "__stringify(STACK_FRAME_MIN_SIZE)"\n"
+   PPC_LL" 0, "__stringify(PPC_LR_STKOFF)"(1)\n"
+   PPC_FTRACE_RET
+"  .size   my_tramp1, .-my_tramp1\n"
+
+"  .type   my_tramp2, @function\n"
+"  .globl  my_tramp2\n"
+"   my_tramp2:\n"
+   PPC_STL"0, "__stringify(PPC_LR_STKOFF)"(1)\n"
+   PPC_STLU"   1, -"__stringify(STACK_FRAME_MIN_SIZE)"(1)\n"
+"  mflr0\n"
+   PPC_STL"0, "__stringify(PPC_LR_STKOFF)"(1)\n"
+   PPC_STLU"   1, -"__stringify(STACK_FRAME_SIZE)"(1)\n"
+   PPC64_TOC_SAVE_AND_UPDATE
+"  bl  my_direct_func2\n"
+   PPC64_TOC_RESTORE
+"  addi1, 1, "__stringify(STACK_FRAME_SIZE)"\n"
+   PPC_FTRACE_RESTORE_LR
+"  addi1, 1, "__stringify(STACK_FRAME_MIN_SIZE)"\n"
+   PPC_LL" 0, "__stringify(PPC_LR_STKOFF)"(1)\n"
+   PPC_FTRACE_RET
+   PPC64_TOC
+"  .size   my_tramp2, .-my_tramp2\n"
+"  .popsection\n"
+);
+
+#endif /* CONFIG_PPC */
+
 static struct ftrace_ops direct;
 
 static unsigned long my_tramp = (unsig

Re: [PATCH] powerpc/pseries: Whitelist dtl slub object for copying to userspace

2024-06-20 Thread Kees Cook
On Thu, Jun 20, 2024 at 10:58:49PM +0530, Anjali K wrote:
> However given that:    
> (i) The dtl buffer is read-only. The dtl trace is a set of metrics which   
> are collected to be read by privileged users.  
> (ii) Users usually reads all the dtl entries, not a subset.   
>   
> (iii) Read overflows are unlikely to expose anything useful to attackers  
>   
> since we are whitelisting the complete slub object and there are no    
> contiguous memory locations which need to be hidden.   
> Can we go ahead with the whitelisting using kmem_cache_create_usercopy()   
> approach?  
> Or are there other reasons to prefer the bounce buffer approach?

Yeah, based on this and what mpe said, I have no objection to just
allowing it in kmem_cache_create_usercopy(). I was mainly just curious
what the threat model was. :)

Reviewed-by: Kees Cook 

-- 
Kees Cook


[RFC PATCH v3 10/11] powerpc64/bpf: Fold bpf_jit_emit_func_call_hlp() into bpf_jit_emit_func_call_rel()

2024-06-20 Thread Naveen N Rao
Commit 61688a82e047 ("powerpc/bpf: enable kfunc call") enhanced
bpf_jit_emit_func_call_hlp() to handle calls out to module region, where
bpf progs are generated. The only difference now between
bpf_jit_emit_func_call_hlp() and bpf_jit_emit_func_call_rel() is in
handling of the initial pass where target function address is not known.
Fold that logic into bpf_jit_emit_func_call_hlp() and rename it to
bpf_jit_emit_func_call_rel() to simplify bpf function call JIT code.

We don't actually need to load/restore TOC across a call out to a
different kernel helper or to a different bpf program since they all
work with the kernel TOC. We only need to do it if we have to call out
to a module function. So, guard TOC load/restore with appropriate
conditions.

Signed-off-by: Naveen N Rao 
---
 arch/powerpc/net/bpf_jit_comp64.c | 61 +--
 1 file changed, 17 insertions(+), 44 deletions(-)

diff --git a/arch/powerpc/net/bpf_jit_comp64.c 
b/arch/powerpc/net/bpf_jit_comp64.c
index 7703dcf48be8..288ff32d676f 100644
--- a/arch/powerpc/net/bpf_jit_comp64.c
+++ b/arch/powerpc/net/bpf_jit_comp64.c
@@ -202,14 +202,22 @@ void bpf_jit_build_epilogue(u32 *image, struct 
codegen_context *ctx)
EMIT(PPC_RAW_BLR());
 }
 
-static int
-bpf_jit_emit_func_call_hlp(u32 *image, u32 *fimage, struct codegen_context 
*ctx, u64 func)
+int bpf_jit_emit_func_call_rel(u32 *image, u32 *fimage, struct codegen_context 
*ctx, u64 func)
 {
unsigned long func_addr = func ? ppc_function_entry((void *)func) : 0;
long reladdr;
 
-   if (WARN_ON_ONCE(!kernel_text_address(func_addr)))
-   return -EINVAL;
+   /* bpf to bpf call, func is not known in the initial pass. Emit 5 nops 
as a placeholder */
+   if (!func) {
+   for (int i = 0; i < 5; i++)
+   EMIT(PPC_RAW_NOP());
+   /* elfv1 needs an additional instruction to load addr from 
descriptor */
+   if (IS_ENABLED(CONFIG_PPC64_ELF_ABI_V1))
+   EMIT(PPC_RAW_NOP());
+   EMIT(PPC_RAW_MTCTR(_R12));
+   EMIT(PPC_RAW_BCTRL());
+   return 0;
+   }
 
 #ifdef CONFIG_PPC_KERNEL_PCREL
reladdr = func_addr - local_paca->kernelbase;
@@ -266,7 +274,8 @@ bpf_jit_emit_func_call_hlp(u32 *image, u32 *fimage, struct 
codegen_context *ctx,
 * We can clobber r2 since we get called through a
 * function pointer (so caller will save/restore r2).
 */
-   EMIT(PPC_RAW_LD(_R2, bpf_to_ppc(TMP_REG_2), 8));
+   if (is_module_text_address(func_addr))
+   EMIT(PPC_RAW_LD(_R2, bpf_to_ppc(TMP_REG_2), 8));
} else {
PPC_LI64(_R12, func);
EMIT(PPC_RAW_MTCTR(_R12));
@@ -276,46 +285,14 @@ bpf_jit_emit_func_call_hlp(u32 *image, u32 *fimage, 
struct codegen_context *ctx,
 * Load r2 with kernel TOC as kernel TOC is used if function 
address falls
 * within core kernel text.
 */
-   EMIT(PPC_RAW_LD(_R2, _R13, offsetof(struct paca_struct, 
kernel_toc)));
+   if (is_module_text_address(func_addr))
+   EMIT(PPC_RAW_LD(_R2, _R13, offsetof(struct paca_struct, 
kernel_toc)));
}
 #endif
 
return 0;
 }
 
-int bpf_jit_emit_func_call_rel(u32 *image, u32 *fimage, struct codegen_context 
*ctx, u64 func)
-{
-   unsigned int i, ctx_idx = ctx->idx;
-
-   if (WARN_ON_ONCE(func && is_module_text_address(func)))
-   return -EINVAL;
-
-   /* skip past descriptor if elf v1 */
-   func += FUNCTION_DESCR_SIZE;
-
-   /* Load function address into r12 */
-   PPC_LI64(_R12, func);
-
-   /* For bpf-to-bpf function calls, the callee's address is unknown
-* until the last extra pass. As seen above, we use PPC_LI64() to
-* load the callee's address, but this may optimize the number of
-* instructions required based on the nature of the address.
-*
-* Since we don't want the number of instructions emitted to increase,
-* we pad the optimized PPC_LI64() call with NOPs to guarantee that
-* we always have a five-instruction sequence, which is the maximum
-* that PPC_LI64() can emit.
-*/
-   if (!image)
-   for (i = ctx->idx - ctx_idx; i < 5; i++)
-   EMIT(PPC_RAW_NOP());
-
-   EMIT(PPC_RAW_MTCTR(_R12));
-   EMIT(PPC_RAW_BCTRL());
-
-   return 0;
-}
-
 static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 
out)
 {
/*
@@ -1047,11 +1024,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, 
u32 *fimage, struct code
if (ret < 0)
return ret;
 
-   if (func_addr_fixed)
-   ret = bpf_jit_emi

[RFC PATCH v3 11/11] powerpc64/bpf: Add support for bpf trampolines

2024-06-20 Thread Naveen N Rao
Add support for bpf_arch_text_poke() and arch_prepare_bpf_trampoline()
for 64-bit powerpc.

BPF prog JIT is extended to mimic 64-bit powerpc approach for ftrace
having a single nop at function entry, followed by the function
profiling sequence out-of-line and a separate long branch stub for calls
to trampolines that are out of range. A dummy_tramp is provided to
simplify synchronization similar to arm64.

BPF Trampolines adhere to the existing ftrace ABI utilizing a
two-instruction profiling sequence, as well as the newer ABI utilizing a
three-instruction profiling sequence enabling return with a 'blr'. The
trampoline code itself closely follows x86 implementation.

While the code is generic, BPF trampolines are only enabled on 64-bit
powerpc. 32-bit powerpc will need testing and some updates.

Signed-off-by: Naveen N Rao 
---
 arch/powerpc/include/asm/ppc-opcode.h |  14 +
 arch/powerpc/net/bpf_jit.h|  11 +
 arch/powerpc/net/bpf_jit_comp.c   | 702 +-
 arch/powerpc/net/bpf_jit_comp32.c |   7 +-
 arch/powerpc/net/bpf_jit_comp64.c |   7 +-
 5 files changed, 738 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/include/asm/ppc-opcode.h 
b/arch/powerpc/include/asm/ppc-opcode.h
index 076ae60b4a55..9eaa2c5d9b73 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -585,12 +585,26 @@
 #define PPC_RAW_MTSPR(spr, d)  (0x7c0003a6 | ___PPC_RS(d) | 
__PPC_SPR(spr))
 #define PPC_RAW_EIEIO()(0x7c0006ac)
 
+/* bcl 20,31,$+4 */
+#define PPC_RAW_BCL()  (0x429f0005)
 #define PPC_RAW_BRANCH(offset) (0x4800 | PPC_LI(offset))
 #define PPC_RAW_BL(offset) (0x4801 | PPC_LI(offset))
 #define PPC_RAW_TW(t0, a, b)   (0x7c08 | ___PPC_RS(t0) | 
___PPC_RA(a) | ___PPC_RB(b))
 #define PPC_RAW_TRAP() PPC_RAW_TW(31, 0, 0)
 #define PPC_RAW_SETB(t, bfa)   (0x7c000100 | ___PPC_RT(t) | 
___PPC_RA((bfa) << 2))
 
+#ifdef CONFIG_PPC32
+#define PPC_RAW_STLPPC_RAW_STW
+#define PPC_RAW_STLU   PPC_RAW_STWU
+#define PPC_RAW_LL PPC_RAW_LWZ
+#define PPC_RAW_CMPLI  PPC_RAW_CMPWI
+#else
+#define PPC_RAW_STLPPC_RAW_STD
+#define PPC_RAW_STLU   PPC_RAW_STDU
+#define PPC_RAW_LL PPC_RAW_LD
+#define PPC_RAW_CMPLI  PPC_RAW_CMPDI
+#endif
+
 /* Deal with instructions that older assemblers aren't aware of */
 #definePPC_BCCTR_FLUSH stringify_in_c(.long 
PPC_INST_BCCTR_FLUSH)
 #definePPC_CP_ABORTstringify_in_c(.long PPC_RAW_CP_ABORT)
diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
index cdea5dccaefe..58cdfbfbef94 100644
--- a/arch/powerpc/net/bpf_jit.h
+++ b/arch/powerpc/net/bpf_jit.h
@@ -21,6 +21,9 @@
 
 #define CTX_NIA(ctx) ((unsigned long)ctx->idx * 4)
 
+#define SZLsizeof(unsigned long)
+#define BPF_INSN_SAFETY64
+
 #define PLANT_INSTR(d, idx, instr)   \
do { if (d) { (d)[idx] = instr; } idx++; } while (0)
 #define EMIT(instr)PLANT_INSTR(image, ctx->idx, instr)
@@ -81,6 +84,13 @@
EMIT(PPC_RAW_ORI(d, d, (uintptr_t)(i) &   \
0x)); \
} } while (0)
+#define PPC_LI_ADDRPPC_LI64
+#define PPC64_LOAD_PACA()\
+   EMIT(PPC_RAW_LD(_R2, _R13, offsetof(struct paca_struct, kernel_toc)))
+#else
+#define PPC_LI64   BUILD_BUG
+#define PPC_LI_ADDRPPC_LI32
+#define PPC64_LOAD_PACA() BUILD_BUG()
 #endif
 
 /*
@@ -165,6 +175,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 
*fimage, struct code
   u32 *addrs, int pass, bool extra_pass);
 void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx);
 void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx);
+void bpf_jit_build_fentry_stubs(u32 *image, struct codegen_context *ctx);
 void bpf_jit_realloc_regs(struct codegen_context *ctx);
 int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int 
tmp_reg, long exit_addr);
 
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index 984655419da5..54df51ce54c8 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -22,11 +22,81 @@
 
 #include "bpf_jit.h"
 
+/* These offsets are from bpf prog end and stay the same across progs */
+static int bpf_jit_ool_stub, bpf_jit_long_branch_stub;
+
 static void bpf_jit_fill_ill_insns(void *area, unsigned int size)
 {
memset32(area, BREAKPOINT_INSTRUCTION, size / 4);
 }
 
+void dummy_tramp(void);
+
+asm (
+"  .pushsection .text, \"ax\", @progbits   ;"
+"  .global dummy_tramp ;"
+"  .type dummy_tramp, @function;"
+"dummy_tramp:  

Re: [Patch v4 02/10] dt-bindings: dma: Add lpc32xx DMA mux binding

2024-06-20 Thread Rob Herring (Arm)


On Thu, 20 Jun 2024 19:56:33 +0200, Piotr Wojtaszczyk wrote:
> LPC32XX SoCs use pl080 dma controller which have few request signals
> multiplexed between peripherals. This binding describes how devices can
> use the multiplexed request signals.
> 
> Signed-off-by: Piotr Wojtaszczyk 
> ---
> Changes for v4:
> - This patch is new in v4
> 
>  .../bindings/dma/nxp,lpc3220-dmamux.yaml  | 56 +++
>  MAINTAINERS   |  9 +++
>  2 files changed, 65 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/dma/nxp,lpc3220-dmamux.yaml
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/dma/nxp,lpc3220-dmamux.example.dtb: 
/example-0/syscon@40004000: failed to match any schema with compatible: 
['nxp,lpc3220-creg', 'syscon', 'simple-mfd']

doc reference errors (make refcheckdocs):

See 
https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240620175657.358273-3-piotr.wojtaszc...@timesys.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



Re: [PATCH 07/15] parisc: use generic sys_fanotify_mark implementation

2024-06-20 Thread Helge Deller

On 6/20/24 18:23, Arnd Bergmann wrote:

From: Arnd Bergmann 

The sys_fanotify_mark() syscall on parisc uses the reverse word order
for the two halves of the 64-bit argument compared to all syscalls on
all 32-bit architectures. As far as I can tell, the problem is that
the function arguments on parisc are sorted backwards (26, 25, 24, 23,
...) compared to everyone else,


r26 is arg0, r25 is arg1, and so on.
I'm not sure I would call this "sorted backwards".
I think the reason is simply that hppa is the only 32-bit big-endian
arch left...


so the calling conventions of using an
even/odd register pair in native word order result in the lower word
coming first in function arguments, matching the expected behavior
on little-endian architectures. The system call conventions however
ended up matching what the other 32-bit architectures do.

A glibc cleanup in 2020 changed the userspace behavior in a way that
handles all architectures consistently, but this inadvertently broke
parisc32 by changing to the same method as everyone else.


I appreciate such cleanups to make arches consistent.
But it's bad if breakages aren't noticed or reported then...


The change made it into glibc-2.35 and subsequently into debian 12
(bookworm), which is the latest stable release. This means we
need to choose between reverting the glibc change or changing the
kernel to match it again, but either hange will leave some systems
broken.

Pick the option that is more likely to help current and future
users and change the kernel to match current glibc.


Agreed (assuming we have really a problem on parisc).


This also
means the behavior is now consistent across architectures, but
it breaks running new kernels with old glibc builds before 2.35.

Link: https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=d150181d73d9
Link: 
https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/commit/arch/parisc/kernel/sys_parisc.c?h=57b1dfbd5b4a39d
Cc: Adhemerval Zanella 
Signed-off-by: Arnd Bergmann 
---
I found this through code inspection, please double-check to make
sure I got the bug and the fix right.


The patch looks good at first sight.
I'll pick it up in my parisc git tree and will do some testing the
next few days and then push forward for 6.11 when it opens

Thank you!!

Helge


The alternative is to fix this by reverting glibc back to the
unusual behavior.
---
  arch/parisc/Kconfig | 1 +
  arch/parisc/kernel/sys_parisc32.c   | 9 -
  arch/parisc/kernel/syscalls/syscall.tbl | 2 +-
  3 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index daafeb20f993..dc9b902de8ea 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -16,6 +16,7 @@ config PARISC
select ARCH_HAS_UBSAN
select ARCH_HAS_PTE_SPECIAL
select ARCH_NO_SG_CHAIN
+   select ARCH_SPLIT_ARG64 if !64BIT
select ARCH_SUPPORTS_HUGETLBFS if PA20
select ARCH_SUPPORTS_MEMORY_FAILURE
select ARCH_STACKWALK
diff --git a/arch/parisc/kernel/sys_parisc32.c 
b/arch/parisc/kernel/sys_parisc32.c
index 2a12a547b447..826c8e51b585 100644
--- a/arch/parisc/kernel/sys_parisc32.c
+++ b/arch/parisc/kernel/sys_parisc32.c
@@ -23,12 +23,3 @@ asmlinkage long sys32_unimplemented(int r26, int r25, int 
r24, int r23,
current->comm, current->pid, r20);
  return -ENOSYS;
  }
-
-asmlinkage long sys32_fanotify_mark(compat_int_t fanotify_fd, compat_uint_t 
flags,
-   compat_uint_t mask0, compat_uint_t mask1, compat_int_t dfd,
-   const char  __user * pathname)
-{
-   return sys_fanotify_mark(fanotify_fd, flags,
-   ((__u64)mask1 << 32) | mask0,
-dfd, pathname);
-}
diff --git a/arch/parisc/kernel/syscalls/syscall.tbl 
b/arch/parisc/kernel/syscalls/syscall.tbl
index 39e67fab7515..66dc406b12e4 100644
--- a/arch/parisc/kernel/syscalls/syscall.tbl
+++ b/arch/parisc/kernel/syscalls/syscall.tbl
@@ -364,7 +364,7 @@
  320   common  accept4 sys_accept4
  321   common  prlimit64   sys_prlimit64
  322   common  fanotify_init   sys_fanotify_init
-323common  fanotify_mark   sys_fanotify_mark   
sys32_fanotify_mark
+323common  fanotify_mark   sys_fanotify_mark   
compat_sys_fanotify_mark
  324   32  clock_adjtime   sys_clock_adjtime32
  324   64  clock_adjtime   sys_clock_adjtime
  325   common  name_to_handle_at   sys_name_to_handle_at




Re: [Patch v4 10/10] i2x: pnx: Use threaded irq to fix warning from del_timer_sync()

2024-06-20 Thread Andi Shyti
Hi Piotr,

On Thu, Jun 20, 2024 at 07:56:41PM GMT, Piotr Wojtaszczyk wrote:
> When del_timer_sync() is called in an interrupt context it throws a warning
> because of potential deadlock. Threaded irq handler fixes the potential
> problem.
> 
> Signed-off-by: Piotr Wojtaszczyk 

did you run into a lockdep splat?

Anything against using del_timer(), instead? Have you tried?

Thanks,
Andi


Re: (subset) [PATCHv5 0/9] ASoC: fsl-asoc-card: add S/PDIF controller

2024-06-20 Thread Mark Brown
On Thu, 20 Jun 2024 15:25:02 +0200, Elinor Montmasson wrote:
> This is the v5 of the series of patches aiming to make the machine
> driver `fsl-asoc-card` compatible with S/PDIF controllers on imx boards.
> The main goal is to allow the use of S/PDIF controllers with ASRC
> modules.
> 
> The `imx-spdif` machine driver already has specific support for S/PDIF
> controllers but doesn't support using an ASRC with it. However, the
> `fsl-asoc-card` machine driver has the necessary code to create a sound
> card which can use an ASRC module.
> It is then possible to extend the support for S/PDIF audio cards by
> merging the `imx-spdif` driver into `fsl-asoc-card`.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/9] ASoC: fsl-asoc-card: set priv->pdev before using it
  commit: 90f3feb24172185f1832636264943e8b5e289245

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark



[powerpc:merge] BUILD SUCCESS e2b06d707dd067509cdc9ceba783c06fa6a551c2

2024-06-20 Thread kernel test robot
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git 
merge
branch HEAD: e2b06d707dd067509cdc9ceba783c06fa6a551c2  Automatic merge of 
'next' into merge (2024-06-17 15:38)

elapsed time: 5231m

configs tested: 121
configs skipped: 2

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
alpha allnoconfig   gcc-13.2.0
alpha   defconfig   gcc-13.2.0
arc   allnoconfig   gcc-13.2.0
arc defconfig   gcc-13.2.0
arc   randconfig-001-20240618   gcc-13.2.0
arc   randconfig-002-20240618   gcc-13.2.0
arm   allnoconfig   clang-19
arm defconfig   clang-14
arm   randconfig-001-20240618   gcc-13.2.0
arm   randconfig-002-20240618   gcc-13.2.0
arm   randconfig-003-20240618   clang-19
arm   randconfig-004-20240618   gcc-13.2.0
arm64 allnoconfig   gcc-13.2.0
arm64   defconfig   gcc-13.2.0
arm64 randconfig-001-20240618   clang-17
arm64 randconfig-002-20240618   clang-19
arm64 randconfig-003-20240618   clang-16
arm64 randconfig-004-20240618   clang-19
csky  allnoconfig   gcc-13.2.0
cskydefconfig   gcc-13.2.0
csky  randconfig-001-20240618   gcc-13.2.0
csky  randconfig-002-20240618   gcc-13.2.0
hexagon   allnoconfig   clang-19
hexagon defconfig   clang-19
hexagon   randconfig-001-20240618   clang-19
hexagon   randconfig-002-20240618   clang-19
i386 buildonly-randconfig-001-20240618   gcc-13
i386 buildonly-randconfig-002-20240618   gcc-12
i386 buildonly-randconfig-003-20240618   gcc-8
i386 buildonly-randconfig-004-20240618   gcc-10
i386 buildonly-randconfig-005-20240618   gcc-10
i386 buildonly-randconfig-006-20240618   gcc-10
i386  randconfig-001-20240618   clang-18
i386  randconfig-002-20240618   gcc-13
i386  randconfig-003-20240618   gcc-13
i386  randconfig-004-20240618   clang-18
i386  randconfig-005-20240618   clang-18
i386  randconfig-006-20240618   clang-18
i386  randconfig-011-20240618   gcc-13
i386  randconfig-012-20240618   gcc-11
i386  randconfig-013-20240618   gcc-7
i386  randconfig-014-20240618   gcc-11
i386  randconfig-015-20240618   clang-18
i386  randconfig-016-20240618   clang-18
loongarch allnoconfig   gcc-13.2.0
loongarch   defconfig   gcc-13.2.0
loongarch randconfig-001-20240618   gcc-13.2.0
loongarch randconfig-002-20240618   gcc-13.2.0
m68k  allnoconfig   gcc-13.2.0
m68kdefconfig   gcc-13.2.0
microblazeallnoconfig   gcc-13.2.0
microblaze  defconfig   gcc-13.2.0
mips  allnoconfig   gcc-13.2.0
nios2 allnoconfig   gcc-13.2.0
nios2   defconfig   gcc-13.2.0
nios2 randconfig-001-20240618   gcc-13.2.0
nios2 randconfig-002-20240618   gcc-13.2.0
openrisc  allnoconfig   gcc-13.2.0
openriscdefconfig   gcc-13.2.0
pariscallnoconfig   gcc-13.2.0
parisc  defconfig   gcc-13.2.0
pariscrandconfig-001-20240618   gcc-13.2.0
pariscrandconfig-002-20240618   gcc-13.2.0
parisc64defconfig   gcc-13.2.0
powerpc   allnoconfig   gcc-13.2.0
powerpc   randconfig-001-20240618   gcc-13.2.0
powerpc   randconfig-002-20240618   clang-19
powerpc   randconfig-003-20240618   clang-19
powerpc64 randconfig-001-20240618   clang-19
powerpc64 randconfig-002-20240618   clang-17
powerpc64 randconfig-003-20240618   clang-19
riscv allnoconfig   gcc-13.2.0
riscv   defconfig   clang-19
riscv randconfig-001-20240618   gcc-13.2.0
riscv randconfig-002-20240618   clang-14
s390  allnoconfig   clang-19
s390defconfig   clang-19
s390  randconfig-001-20240618   clang-15
s390  randconfig-002-20240618   gcc-13.2.0
shallnoconfig   gcc-13.2.0
s

[PATCH 12/15] net: ibmvnic: Convert tasklet API to new bottom half workqueue mechanism

2024-06-20 Thread Allen Pais
Migrate tasklet APIs to the new bottom half workqueue mechanism. It
replaces all occurrences of tasklet usage with the appropriate workqueue
APIs throughout the ibmvnic driver. This transition ensures compatibility
with the latest design and enhances performance.

Signed-off-by: Allen Pais 
---
 drivers/net/ethernet/ibm/ibmvnic.c | 24 
 drivers/net/ethernet/ibm/ibmvnic.h |  2 +-
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 5e9a93bdb518..2e817a560c3a 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -2725,7 +2725,7 @@ static const char *reset_reason_to_string(enum 
ibmvnic_reset_reason reason)
 /*
  * Initialize the init_done completion and return code values. We
  * can get a transport event just after registering the CRQ and the
- * tasklet will use this to communicate the transport event. To ensure
+ * bh work will use this to communicate the transport event. To ensure
  * we don't miss the notification/error, initialize these _before_
  * regisering the CRQ.
  */
@@ -4429,7 +4429,7 @@ static void send_request_cap(struct ibmvnic_adapter 
*adapter, int retry)
int cap_reqs;
 
/* We send out 6 or 7 REQUEST_CAPABILITY CRQs below (depending on
-* the PROMISC flag). Initialize this count upfront. When the tasklet
+* the PROMISC flag). Initialize this count upfront. When the bh work
 * receives a response to all of these, it will send the next protocol
 * message (QUERY_IP_OFFLOAD).
 */
@@ -4965,7 +4965,7 @@ static void send_query_cap(struct ibmvnic_adapter 
*adapter)
int cap_reqs;
 
/* We send out 25 QUERY_CAPABILITY CRQs below.  Initialize this count
-* upfront. When the tasklet receives a response to all of these, it
+* upfront. When the bh work receives a response to all of these, it
 * can send out the next protocol messaage (REQUEST_CAPABILITY).
 */
cap_reqs = 25;
@@ -5477,7 +5477,7 @@ static int handle_login_rsp(union ibmvnic_crq 
*login_rsp_crq,
int i;
 
/* CHECK: Test/set of login_pending does not need to be atomic
-* because only ibmvnic_tasklet tests/clears this.
+* because only ibmvnic_bh_work tests/clears this.
 */
if (!adapter->login_pending) {
netdev_warn(netdev, "Ignoring unexpected login response\n");
@@ -6063,13 +6063,13 @@ static irqreturn_t ibmvnic_interrupt(int irq, void 
*instance)
 {
struct ibmvnic_adapter *adapter = instance;
 
-   tasklet_schedule(&adapter->tasklet);
+   queue_work(system_bh_wq, &adapter->bh_work);
return IRQ_HANDLED;
 }
 
-static void ibmvnic_tasklet(struct tasklet_struct *t)
+static void ibmvnic_bh_work(struct work_struct *work)
 {
-   struct ibmvnic_adapter *adapter = from_tasklet(adapter, t, tasklet);
+   struct ibmvnic_adapter *adapter = from_work(adapter, work, bh_work);
struct ibmvnic_crq_queue *queue = &adapter->crq;
union ibmvnic_crq *crq;
unsigned long flags;
@@ -6150,7 +6150,7 @@ static void release_crq_queue(struct ibmvnic_adapter 
*adapter)
 
netdev_dbg(adapter->netdev, "Releasing CRQ\n");
free_irq(vdev->irq, adapter);
-   tasklet_kill(&adapter->tasklet);
+   cancel_work_sync(&adapter->bh_work);
do {
rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
} while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
@@ -6201,7 +6201,7 @@ static int init_crq_queue(struct ibmvnic_adapter *adapter)
 
retrc = 0;
 
-   tasklet_setup(&adapter->tasklet, (void *)ibmvnic_tasklet);
+   INIT_WORK(&adapter->bh_work, (void *)ibmvnic_bh_work);
 
netdev_dbg(adapter->netdev, "registering irq 0x%x\n", vdev->irq);
snprintf(crq->name, sizeof(crq->name), "ibmvnic-%x",
@@ -6223,12 +6223,12 @@ static int init_crq_queue(struct ibmvnic_adapter 
*adapter)
spin_lock_init(&crq->lock);
 
/* process any CRQs that were queued before we enabled interrupts */
-   tasklet_schedule(&adapter->tasklet);
+   queue_work(system_bh_wq, &adapter->bh_work);
 
return retrc;
 
 req_irq_failed:
-   tasklet_kill(&adapter->tasklet);
+   cancel_work_sync(&adapter->bh_work);
do {
rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
} while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
@@ -6621,7 +6621,7 @@ static int ibmvnic_resume(struct device *dev)
if (adapter->state != VNIC_OPEN)
return 0;
 
-   tasklet_schedule(&adapter->tasklet);
+   queue_work(system_bh_wq, &adapter->bh_work);
 
return 0;
 }
diff --git a/drivers/net/ethernet/ibm/ibmvnic.h 
b/drivers/net/ethernet/ibm/ibmvnic.h
index 94ac36b1408b..b65b210a8059 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.h
+++ b/drivers/net/ethernet/ibm/ibmvnic.h
@@ -1036,7 +1036,7 @@ struct ibmvni

Re: [PATCH 07/15] parisc: use generic sys_fanotify_mark implementation

2024-06-20 Thread LEROY Christophe


Le 20/06/2024 à 23:21, Helge Deller a écrit :
> [Vous ne recevez pas souvent de courriers de del...@gmx.de. Découvrez
> pourquoi ceci est important à
> https://aka.ms/LearnAboutSenderIdentification ]
>
> On 6/20/24 18:23, Arnd Bergmann wrote:
>> From: Arnd Bergmann 
>>
>> The sys_fanotify_mark() syscall on parisc uses the reverse word order
>> for the two halves of the 64-bit argument compared to all syscalls on
>> all 32-bit architectures. As far as I can tell, the problem is that
>> the function arguments on parisc are sorted backwards (26, 25, 24, 23,
>> ...) compared to everyone else,
>
> r26 is arg0, r25 is arg1, and so on.
> I'm not sure I would call this "sorted backwards".
> I think the reason is simply that hppa is the only 32-bit big-endian
> arch left...

powerpc/32 is big-endian: r3 is arg0, r4 is arg1, ... r10 is arg7.

In case of a 64bits arg, r3 is the high part and r4 is the low part.

Christophe

>
>> so the calling conventions of using an
>> even/odd register pair in native word order result in the lower word
>> coming first in function arguments, matching the expected behavior
>> on little-endian architectures. The system call conventions however
>> ended up matching what the other 32-bit architectures do.
>>
>> A glibc cleanup in 2020 changed the userspace behavior in a way that
>> handles all architectures consistently, but this inadvertently broke
>> parisc32 by changing to the same method as everyone else.
>
> I appreciate such cleanups to make arches consistent.
> But it's bad if breakages aren't noticed or reported then...
>
>> The change made it into glibc-2.35 and subsequently into debian 12
>> (bookworm), which is the latest stable release. This means we
>> need to choose between reverting the glibc change or changing the
>> kernel to match it again, but either hange will leave some systems
>> broken.
>>
>> Pick the option that is more likely to help current and future
>> users and change the kernel to match current glibc.
>
> Agreed (assuming we have really a problem on parisc).
>
>> This also
>> means the behavior is now consistent across architectures, but
>> it breaks running new kernels with old glibc builds before 2.35.
>>
>> Link:
>> https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=d150181d73d9
>> Link:
>> https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/commit/arch/parisc/kernel/sys_parisc.c?h=57b1dfbd5b4a39d
>> Cc: Adhemerval Zanella 
>> Signed-off-by: Arnd Bergmann 
>> ---
>> I found this through code inspection, please double-check to make
>> sure I got the bug and the fix right.
>
> The patch looks good at first sight.
> I'll pick it up in my parisc git tree and will do some testing the
> next few days and then push forward for 6.11 when it opens
>
> Thank you!!
>
> Helge
>
>> The alternative is to fix this by reverting glibc back to the
>> unusual behavior.
>> ---
>>   arch/parisc/Kconfig | 1 +
>>   arch/parisc/kernel/sys_parisc32.c   | 9 -
>>   arch/parisc/kernel/syscalls/syscall.tbl | 2 +-
>>   3 files changed, 2 insertions(+), 10 deletions(-)
>>
>> diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
>> index daafeb20f993..dc9b902de8ea 100644
>> --- a/arch/parisc/Kconfig
>> +++ b/arch/parisc/Kconfig
>> @@ -16,6 +16,7 @@ config PARISC
>>   select ARCH_HAS_UBSAN
>>   select ARCH_HAS_PTE_SPECIAL
>>   select ARCH_NO_SG_CHAIN
>> + select ARCH_SPLIT_ARG64 if !64BIT
>>   select ARCH_SUPPORTS_HUGETLBFS if PA20
>>   select ARCH_SUPPORTS_MEMORY_FAILURE
>>   select ARCH_STACKWALK
>> diff --git a/arch/parisc/kernel/sys_parisc32.c
>> b/arch/parisc/kernel/sys_parisc32.c
>> index 2a12a547b447..826c8e51b585 100644
>> --- a/arch/parisc/kernel/sys_parisc32.c
>> +++ b/arch/parisc/kernel/sys_parisc32.c
>> @@ -23,12 +23,3 @@ asmlinkage long sys32_unimplemented(int r26, int
>> r25, int r24, int r23,
>>   current->comm, current->pid, r20);
>>   return -ENOSYS;
>>   }
>> -
>> -asmlinkage long sys32_fanotify_mark(compat_int_t fanotify_fd,
>> compat_uint_t flags,
>> - compat_uint_t mask0, compat_uint_t mask1, compat_int_t dfd,
>> - const char  __user * pathname)
>> -{
>> - return sys_fanotify_mark(fanotify_fd, flags,
>> - ((__u64)mask1 << 32) | mask0,
>> -  dfd, pathname);
>> -}
>> diff --git a/arch/parisc/kernel/syscalls/syscall.tbl
>> b/arch/parisc/kernel/syscalls/syscall.tbl
>> index 39e67fab7515..66dc406b12e4 100644
>> --- a/arch/parisc/kernel/syscalls/syscall.tbl
>> +++ b/arch/parisc/kernel/syscalls/syscall.tbl
>> @@ -364,7 +364,7 @@
>>   320 common  accept4 sys_accept4
>>   321 common  prlimit64   sys_prlimit64
>>   322 common  fanotify_init   sys_fanotify_init
>> -323  common  fanotify_mark   sys_fanotify_mark
>> sys32_fanotify_mark
>> +323  common  fanotify_mark   sys_fanotify_mark
>> compat_sys_fanotify_mark
>>   324 32  clock_adjtime   sys_clock_adjtime32
>>

Re: [Patch v4 04/10] ARM: dts: lpc32xx: Add missing dma and i2s properties

2024-06-20 Thread Markus Elfring
> Adds properties declared in the new DT bindings:

  Add?How do you think about to replace such an 
abbreviation?

  
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/submitting-patches.rst?h=v6.10-rc4#n94

Regards,
Markus


Re: [Patch v4 05/10] clk: lpc32xx: initialize regmap using parent syscon

2024-06-20 Thread Markus Elfring
> This allows to share the regmap with other simple-mfd devices like
> nxp,lpc32xx-dmamux

Please choose an imperative wording for an improved change description.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/submitting-patches.rst?h=v6.10-rc4#n94

Regards,
Markus


Re: [Patch v4 06/10] dmaengine: Add dma router for pl08x in LPC32XX SoC

2024-06-20 Thread Markus Elfring
…
> this driver allows to route a signal request line thru the multiplexer for
> given peripheral.

Would you like to choose an imperative wording for an improved change 
description?
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/submitting-patches.rst?h=v6.10-rc4#n94

Regards,
Markus


Re: [Patch v4 07/10] ARM: lpc32xx: Remove pl08x platform data in favor for device tree

2024-06-20 Thread Markus Elfring
> With the driver for nxp,lpc3220-dmamux we can remove the pl08x platform
> data and let pl08x driver to create peripheral channels from the DT
> properties.

Do you see opportunities to improve such a change description?
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/submitting-patches.rst?h=v6.10-rc4#n94

Regards,
Markus


[PATCH v1 1/2] powerpc/mmiotrace: Add MMIO Tracing tool for PowerPC

2024-06-20 Thread Jialong Yang
mmiotrace is a useful tool to trace MMIO accesses. Nowadays, it only
supported on x86 and x86_64 platforms. Here is a support for powerpc.
The manual is located at Documentation/trace/mmiotrace.rst which means
I have not changed user API. People will be easy to use it.
Almost all files are copied from x86/mm, there are only some
differences from hardware and architectures software.

LINK: https://lore.kernel.org/lkml/20080127195536.50809...@daedalus.pq.iki.fi/

Signed-off-by: Jialong Yang 
---
 arch/powerpc/Kconfig.debug   |   3 +
 arch/powerpc/mm/Makefile |   1 +
 arch/powerpc/mm/kmmio.c  | 649 +++
 arch/powerpc/mm/mmio-mod.c   | 414 
 arch/powerpc/mm/mmiotrace_arch.c | 149 +++
 arch/powerpc/mm/mmiotrace_arch.h |  25 ++
 arch/powerpc/mm/pf_in.c  | 185 +
 arch/powerpc/mm/pf_in.h  |  33 ++
 8 files changed, 1459 insertions(+)
 create mode 100644 arch/powerpc/mm/kmmio.c
 create mode 100644 arch/powerpc/mm/mmio-mod.c
 create mode 100644 arch/powerpc/mm/mmiotrace_arch.c
 create mode 100644 arch/powerpc/mm/mmiotrace_arch.h
 create mode 100644 arch/powerpc/mm/pf_in.c
 create mode 100644 arch/powerpc/mm/pf_in.h

diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 8c80b154e814..8a69188aa75a 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -1,5 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0
 
+config HAVE_MMIOTRACE_SUPPORT
+   def_bool y
+
 config PPC_DISABLE_WERROR
bool "Don't build arch/powerpc code with -Werror"
help
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index 0fe2f085c05a..cb92049f1239 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o
 obj-$(CONFIG_PPC_COPRO_BASE)   += copro_fault.o
 obj-$(CONFIG_PTDUMP_CORE)  += ptdump/
 obj-$(CONFIG_KASAN)+= kasan/
+obj-$(CONFIG_MMIOTRACE) += kmmio.o mmio-mod.o pf_in.o mmiotrace_arch.o
diff --git a/arch/powerpc/mm/kmmio.c b/arch/powerpc/mm/kmmio.c
new file mode 100644
index ..f4374e721b37
--- /dev/null
+++ b/arch/powerpc/mm/kmmio.c
@@ -0,0 +1,649 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Support for MMIO probes.
+ * Derived from arch/x86/mm/kmmio.c:
+ *   Copyright (C) 2024 Jialong Yang (jialong.y...@shingroup.cn)
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "mmiotrace_arch.h"
+
+typedef unsigned long  pteval_t;
+typedef unsigned long  pmdval_t;
+
+#define KMMIO_PAGE_HASH_BITS 4
+#define KMMIO_PAGE_TABLE_SIZE (1 << KMMIO_PAGE_HASH_BITS)
+
+struct kmmio_fault_page {
+   struct list_head list;
+   struct kmmio_fault_page *release_next;
+   unsigned long addr; /* the requested address */
+   pteval_t old_presence; /* page presence prior to arming */
+   bool armed;
+
+   /*
+* Number of times this page has been registered as a part
+* of a probe. If zero, page is disarmed and this may be freed.
+* Used only by writers (RCU) and post_kmmio_handler().
+* Protected by kmmio_lock, when linked into kmmio_page_table.
+*/
+   int count;
+
+   bool scheduled_for_release;
+};
+
+struct kmmio_delayed_release {
+   struct rcu_head rcu;
+   struct kmmio_fault_page *release_list;
+};
+
+struct kmmio_context {
+   struct kmmio_fault_page *fpage;
+   struct kmmio_probe *probe;
+   unsigned long saved_flags;
+   unsigned long saved_softe;
+   unsigned long addr;
+   int active;
+};
+
+/*
+ * The kmmio_lock is taken in int3 context, which is treated as NMI context.
+ * This causes lockdep to complain about it bein in both NMI and normal
+ * context. Hide it from lockdep, as it should not have any other locks
+ * taken under it, and this is only enabled for debugging mmio anyway.
+ */
+static arch_spinlock_t kmmio_lock = __ARCH_SPIN_LOCK_UNLOCKED;
+
+/* Protected by kmmio_lock */
+unsigned int kmmio_count;
+
+/* Read-protected by RCU, write-protected by kmmio_lock. */
+static struct list_head kmmio_page_table[KMMIO_PAGE_TABLE_SIZE];
+static LIST_HEAD(kmmio_probes);
+
+static struct list_head *kmmio_page_list(unsigned long addr)
+{
+   unsigned int l;
+   pte_t *pte = lookup_address(addr, &l);
+
+   if (!pte)
+   return NULL;
+   addr &= page_level_mask(l);
+
+   return &kmmio_page_table[hash_long(addr, KMMIO_PAGE_HASH_BITS)];
+}
+
+/* Accessed per-cpu */
+static DEFINE_PER_CPU(struct kmmio_context, kmmio_ctx);
+
+/*
+ * this is basically a dynamic stabbing problem:
+ * Could use the existing prio tree code or
+ * Possible better implementations:
+ * The Interval Skip List: A Data Structure for Finding All Intervals That
+ * Over

[PATCH v1 2/2] powerpc/mmiotrace: bind ioremap and page fault to active mmiotrace

2024-06-20 Thread Jialong Yang
Hacking the code in ioremap entry and page fault handler entry to
integrate mmiotrace.

Signed-off-by: Jialong Yang 
---
 arch/powerpc/mm/fault.c  | 17 +
 arch/powerpc/mm/ioremap_64.c | 11 +--
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 215690452495..b03cba73de92 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -50,6 +51,19 @@
  * do_page_fault error handling helpers
  */
 
+/*
+ * Returns 0 if mmiotrace is disabled, or if the fault is not
+ * handled by mmiotrace:
+ */
+static nokprobe_inline int
+kmmio_fault(struct pt_regs *regs, unsigned long addr)
+{
+   if (unlikely(is_kmmio_active()))
+   if (kmmio_handler(regs, addr) == 1)
+   return -1;
+   return 0;
+}
+
 static int
 __bad_area_nosemaphore(struct pt_regs *regs, unsigned long address, int 
si_code)
 {
@@ -422,6 +436,9 @@ static int ___do_page_fault(struct pt_regs *regs, unsigned 
long address,
vm_fault_t fault, major = 0;
bool kprobe_fault = kprobe_page_fault(regs, 11);
 
+   if (unlikely(kmmio_fault(regs, address)))
+   return 0;
+
if (unlikely(debugger_fault_handler(regs) || kprobe_fault))
return 0;
 
diff --git a/arch/powerpc/mm/ioremap_64.c b/arch/powerpc/mm/ioremap_64.c
index d24e5f166723..f5f717bf35df 100644
--- a/arch/powerpc/mm/ioremap_64.c
+++ b/arch/powerpc/mm/ioremap_64.c
@@ -3,12 +3,15 @@
 #include 
 #include 
 #include 
+#include 
 
 void __iomem *__ioremap_caller(phys_addr_t addr, unsigned long size,
   pgprot_t prot, void *caller)
 {
phys_addr_t paligned, offset;
void __iomem *ret;
+   phys_addr_t unaligned_phys_addr = addr;
+   const unsigned long unaligned_size = size;
int err;
 
/* We don't support the 4K PFN hack with ioremap */
@@ -28,8 +31,11 @@ void __iomem *__ioremap_caller(phys_addr_t addr, unsigned 
long size,
if (size == 0 || paligned == 0)
return NULL;
 
-   if (slab_is_available())
-   return generic_ioremap_prot(addr, size, prot);
+   if (slab_is_available()) {
+   ret = generic_ioremap_prot(addr, size, prot);
+   mmiotrace_ioremap(unaligned_phys_addr, unaligned_size, ret);
+   return ret;
+   }
 
pr_warn("ioremap() called early from %pS. Use early_ioremap() 
instead\n", caller);
 
@@ -52,6 +58,7 @@ void iounmap(volatile void __iomem *token)
if (!slab_is_available())
return;
 
+   mmiotrace_iounmap(token);
generic_iounmap(PCI_FIX_ADDR(token));
 }
 EXPORT_SYMBOL(iounmap);
-- 
2.34.1



RE: [PATCH 00/26] KVM: vfio: Hide KVM internals from others

2024-06-20 Thread Shameerali Kolothum Thodi


> -Original Message-
> From: Sean Christopherson 
> Sent: Saturday, September 16, 2023 1:31 AM
> To: Catalin Marinas ; Will Deacon
> ; Marc Zyngier ; Oliver Upton
> ; Huacai Chen ; Michael
> Ellerman ; Anup Patel ; Paul
> Walmsley ; Palmer Dabbelt
> ; Albert Ou ; Heiko
> Carstens ; Vasily Gorbik ;
> Alexander Gordeev ; Christian Borntraeger
> ; Janosch Frank ;
> Claudio Imbrenda ; Thomas Gleixner
> ; Ingo Molnar ; Borislav Petkov
> ; Dave Hansen ;
> x...@kernel.org; Peter Zijlstra ; Arnaldo Carvalho de
> Melo ; Sean Christopherson ;
> Paolo Bonzini ; Tony Krowiak
> ; Halil Pasic ; Jason Herne
> ; Harald Freudenberger ;
> Alex Williamson ; Andy Lutomirski
> 
> Cc: linux-arm-ker...@lists.infradead.org; kvm...@lists.linux.dev; linux-
> m...@vger.kernel.org; k...@vger.kernel.org; linuxppc-dev@lists.ozlabs.org;
> kvm-ri...@lists.infradead.org; linux-ri...@lists.infradead.org; linux-
> s...@vger.kernel.org; linux-ker...@vger.kernel.org; linux-perf-
> us...@vger.kernel.org; Anish Ghulati ; Venkatesh
> Srinivas ; Andrew Thornton
> 
> Subject: [PATCH 00/26] KVM: vfio: Hide KVM internals from others
> 
> This is a borderline RFC series to hide KVM's internals from the rest of
> the kernel, where "internals" means data structures, enums, #defines,
> APIs, etc. that are intended to be KVM-only, but are exposed everywhere
> due to kvm_host.h (and other headers) living in the global include paths.
> 
> The motiviation for hiding KVM's internals is to allow *safely* loading a
> "new" KVM module without having to reboot the host.  Where "new" doesn't
> have to be strictly newer, just a different incarnation of KVM.  Hiding
> KVM's internals means those assets can change across KVM instances
> without
> breaking things, e.g. would allow modifying the layout of struct kvm_vcpu
> to introduce new fields related to a new feature or mitigation for hardware
> bugs.
> 
> The end goal for all of this is to allow loading and running multiple
> instances of KVM (the module) simultaneously on a single host, e.g. to
> deploy fixes, mitigations, and/or new features without having to drain
> all VMs from the host.
> 
> For now, the immediate goal is to get KVM to a state where KVM x86 doesn't
> expose anything to the broader world that isn't intended for external
> consumption, e.g. the page write-tracking APIs used by KVM-GT.
> 
> I say this is borderline RFC because I don't think I've "formally" proposed
> the idea of hiding KVM internals before now.  I decided not to tag this RFC
> because the changes ended up being not _that_ invasive, and everything
> before the last six patches is worthwhile even if hiding internals is
> ultimately rejected (IMO).
> 
> This would ideally be ~5 separate series, and I certainly have no objection
> if that's how we want to get this stuff merged.  E.g. (1) VFIO cleanups,
> (2) drop HAVE_KVM, (3) clean up makefiles, (4) x86 perf cleanup, and
> (5) final push for hiding state.  The HAVE_KVM and virt/kvm include stuff
> isn't strictly necessary, but I included them here because they're
> relatively minor (in the grand scheme).

Hi Sean,

Just thought of checking with you on this series. Do you have plans to revive 
this
series? The reason I am asking is, on ARM64/KVM side we do have a requirement
to share the KVM VMID with SMMUV3. Please see the RFC I sent out earlier this
year[1]. The series basically provides a way for KVM to pin a VMID and also
associates an iommufd ctx with a struct kvm * to retrieve that VMID. 

As mentioned above, some of the patches in this series(especially 1-4 & 6) that
does the VFIO cleanups and dropping CONFIG_KVM_VFIO looks very straightforward
and useful. I am thinking of including those when I re-spin my RFC series, if 
that’s ok.

Please let me know your thoughts.

Thanks,
Shameer

[1]. https://lore.kernel.org/linux-iommu/20240209115824.GA2922446@myrica/



[PATCH v4 00/40] lib/find: add atomic find_bit() primitives

2024-06-20 Thread Yury Norov
--- 

This v4 moves new API to separate headers, as adding stuff to find.h
concerns people, particularly Linus. It also adds few more conversions
alongside other cosmetic changes. See full changelog below.

---

Add helpers around test_and_{set,clear}_bit() to allow searching for
clear or set bits and flipping them atomically.

Using atomic search primitives allows to implement lockless bitmap
handling where only individual bits are touched by concurrent processes,
and where people now have to protect their bitmaps to search for a free
or set bit due to the lack of atomic searching routines.

The typical lock-protected bit allocation may look like this:

unsigned long alloc_bit()
{
unsigned long bit;

spin_lock(bitmap_lock);
bit = find_first_zero_bit(bitmap, nbits);
if (bit < nbits)
__set_bit(bit, bitmap);
spin_unlock(bitmap_lock);

return bit;
}

void free_bit(unsigned long bit)
{
spin_lock(bitmap_lock);
__clear_bit(bit, bitmap);
spin_unlock(bitmap_lock);
}

Now with atomic find_and_set_bit(), the above can be implemented
lockless, directly by using it and atomic clear_bit().

Patches 36-40 do this in few places in the kernel where the
transition is clear. There is likely more candidates for
refactoring.

The other important case is when people opencode atomic search
or atomic traverse on the maps with the patterns looking like:

for (idx = 0; idx < nbits; idx++)
if (test_and_clear_bit(idx, bitmap))
do_something(idx);

Or like this:

do {
bit = find_first_bit(bitmap, nbits);
if (bit >= nbits)
return nbits;

} while (!test_and_clear_bit(bit, bitmap));

return bit;

In both cases, the opencoded loop may be converted to a single function
or iterator call. Correspondingly:

for_each_test_and_clear_bit(idx, bitmap, nbits)
do_something(idx);

Or:
return find_and_clear_bit(bitmap, nbits);

Obviously, the less routine code people have to write themself, the
less probability to make a mistake. The patch #33 fixes one such
mistake.

The new API is not only a handy helpers - it also resolves a non-trivial
issue of using non-atomic find_bit() together with atomic
test_and_{set,clear)_bit().

The trick is that find_bit() implies that the bitmap is a regular
non-volatile piece of memory, and compiler is allowed to use such
optimization techniques like re-fetching memory instead of caching it.

For example, find_first_bit() is implemented like:

  for (idx = 0; idx * BITS_PER_LONG < sz; idx++) {
  val = addr[idx];
  if (val) {
  sz = min(idx * BITS_PER_LONG + __ffs(val), sz);
  break;
  }
  }

On register-memory architectures, like x86, compiler may decide to
access memory twice - first time to compare against 0, and second time
to fetch its value to pass it to __ffs().

When running find_first_bit() on volatile memory, the memory may get
changed in-between, and for instance, it may lead to passing 0 to
__ffs(), which is an undefined behaviour. This is a potentially
dangerous call.

find_and_clear_bit() as a wrapper around test_and_clear_bit()
naturally treats underlying bitmap as a volatile memory and prevents
compiler from such optimizations.

Now that KCSAN is catching exactly this type of situations and warns on
undercover memory modifications. We can use it to reveal improper usage
of find_bit(), and convert it to atomic find_and_*_bit() as appropriate.

In some cases concurrent operations with plain find_bit() are acceptable.
For example:

 - two threads running find_*_bit(): safe wrt ffs(0) and returns correct
   value, because underlying bitmap is unchanged;
 - find_next_bit() in parallel with set or clear_bit(), when modifying
   a bit prior to the start bit to search: safe and correct;
 - find_first_bit() in parallel with set_bit(): safe, but may return wrong
   bit number;
 - find_first_zero_bit() in parallel with clear_bit(): same as above.

In last 2 cases find_bit() may not return a correct bit number, but
it may be OK if caller requires any (not exactly the first) set or clear
bit, correspondingly.

In such cases, KCSAN may be safely silenced with data_race(). But in most
cases where KCSAN detects concurrency we should carefully review the code
and likely protect critical sections or switch to atomic find_and_bit(),
as appropriate.

This patch adds the following atomic primitives:

find_and_set_bit(addr, nbits);
find_and_set_next_bit(addr, nbits, start);
...

Here find_and_{set,clear} part refers to the corresponding
test_and_{set,clear}_bit function. Suffixes like _wrap or _lock
derive their semantics from corresponding find() or

[PATCH v4 02/40] lib/find: add test for atomic find_bit() ops

2024-06-20 Thread Yury Norov
Add basic functionality test for new API.

Signed-off-by: Yury Norov 
---
 lib/test_bitmap.c | 62 +++
 1 file changed, 62 insertions(+)

diff --git a/lib/test_bitmap.c b/lib/test_bitmap.c
index 65a75d58ed9e..405f79dd2266 100644
--- a/lib/test_bitmap.c
+++ b/lib/test_bitmap.c
@@ -6,6 +6,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -221,6 +222,65 @@ static void __init test_zero_clear(void)
expect_eq_pbl("", bmap, 1024);
 }
 
+static void __init test_find_and_bit(void)
+{
+   unsigned long w, w_part, bit, cnt = 0;
+   DECLARE_BITMAP(bmap, EXP1_IN_BITS);
+
+   /*
+* Test find_and_clear{_next}_bit() and corresponding
+* iterators
+*/
+   bitmap_copy(bmap, exp1, EXP1_IN_BITS);
+   w = bitmap_weight(bmap, EXP1_IN_BITS);
+
+   for_each_test_and_clear_bit(bit, bmap, EXP1_IN_BITS)
+   cnt++;
+
+   expect_eq_uint(w, cnt);
+   expect_eq_uint(0, bitmap_weight(bmap, EXP1_IN_BITS));
+
+   bitmap_copy(bmap, exp1, EXP1_IN_BITS);
+   w = bitmap_weight(bmap, EXP1_IN_BITS);
+   w_part = bitmap_weight(bmap, EXP1_IN_BITS / 3);
+
+   cnt = 0;
+   bit = EXP1_IN_BITS / 3;
+   for_each_test_and_clear_bit_from(bit, bmap, EXP1_IN_BITS)
+   cnt++;
+
+   expect_eq_uint(bitmap_weight(bmap, EXP1_IN_BITS), bitmap_weight(bmap, 
EXP1_IN_BITS / 3));
+   expect_eq_uint(w_part, bitmap_weight(bmap, EXP1_IN_BITS));
+   expect_eq_uint(w - w_part, cnt);
+
+   /*
+* Test find_and_set{_next}_bit() and corresponding
+* iterators
+*/
+   bitmap_copy(bmap, exp1, EXP1_IN_BITS);
+   w = bitmap_weight(bmap, EXP1_IN_BITS);
+   cnt = 0;
+
+   for_each_test_and_set_bit(bit, bmap, EXP1_IN_BITS)
+   cnt++;
+
+   expect_eq_uint(EXP1_IN_BITS - w, cnt);
+   expect_eq_uint(EXP1_IN_BITS, bitmap_weight(bmap, EXP1_IN_BITS));
+
+   bitmap_copy(bmap, exp1, EXP1_IN_BITS);
+   w = bitmap_weight(bmap, EXP1_IN_BITS);
+   w_part = bitmap_weight(bmap, EXP1_IN_BITS / 3);
+   cnt = 0;
+
+   bit = EXP1_IN_BITS / 3;
+   for_each_test_and_set_bit_from(bit, bmap, EXP1_IN_BITS)
+   cnt++;
+
+   expect_eq_uint(EXP1_IN_BITS - bitmap_weight(bmap, EXP1_IN_BITS),
+   EXP1_IN_BITS / 3 - bitmap_weight(bmap, EXP1_IN_BITS / 
3));
+   expect_eq_uint(EXP1_IN_BITS * 2 / 3 - (w - w_part), cnt);
+}
+
 static void __init test_find_nth_bit(void)
 {
unsigned long b, bit, cnt = 0;
@@ -1482,6 +1542,8 @@ static void __init selftest(void)
test_for_each_clear_bitrange_from();
test_for_each_set_clump8();
test_for_each_set_bit_wrap();
+
+   test_find_and_bit();
 }
 
 KSTM_MODULE_LOADERS(test_bitmap);
-- 
2.43.0



  1   2   >