Re: [PATCHv10 3/4] genirq: Avoid summation loops for /proc/interrupts

2024-02-26 Thread Liu Song



在 2024/2/26 10:09, Bitao Hu 写道:

We could use the irq_desc::tot_count member to avoid the summation
loop for interrupts which are not marked as 'PER_CPU' interrupts in
'show_interrupts'. This could reduce the time overhead of reading
/proc/interrupts.

Originally-by: Thomas Gleixner 
Signed-off-by: Bitao Hu 
---
  include/linux/irqdesc.h | 2 ++
  kernel/irq/irqdesc.c| 2 +-
  kernel/irq/proc.c   | 9 +++--
  3 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index 2912b1998670..1ee96d7232b4 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -121,6 +121,8 @@ static inline void irq_unlock_sparse(void) { }
  extern struct irq_desc irq_desc[NR_IRQS];
  #endif
  
+extern bool irq_is_nmi(struct irq_desc *desc);

+
  static inline unsigned int irq_desc_kstat_cpu(struct irq_desc *desc,
  unsigned int cpu)
  {
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index 9cd17080b2d8..56a767957a9d 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -955,7 +955,7 @@ unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
return desc && desc->kstat_irqs ? per_cpu(desc->kstat_irqs->cnt, cpu) : 
0;
  }
  
-static bool irq_is_nmi(struct irq_desc *desc)

+bool irq_is_nmi(struct irq_desc *desc)
  {
return desc->istate & IRQS_NMI;
  }
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index 6954e0a02047..b3b1b93f0410 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -489,8 +489,13 @@ int show_interrupts(struct seq_file *p, void *v)
goto outsparse;
  
  	if (desc->kstat_irqs) {

-   for_each_online_cpu(j)
-   any_count |= data_race(per_cpu(desc->kstat_irqs->cnt, 
j));
+   if (!irq_settings_is_per_cpu_devid(desc) &&
+   !irq_settings_is_per_cpu(desc) &&
+   !irq_is_nmi(desc))
+   any_count = data_race(desc->tot_count);
+   else
+   for_each_online_cpu(j)
+   any_count |= 
data_race(per_cpu(desc->kstat_irqs->cnt, j));
}
  
  	if ((!desc->action || irq_desc_is_chained(desc)) && !any_count)


The modification borrows from the implementation of |kstat_irqs. Looks 
good.|


|Reviewed-by: Liu Song  |

||



Re: [PATCH v2 5/9] mm: Initialize struct vm_unmapped_area_info

2024-02-26 Thread Christophe Leroy


Le 26/02/2024 à 20:09, Rick Edgecombe a écrit :
> Future changes will need to add a field to struct vm_unmapped_area_info.
> This would cause trouble for any archs that don't initialize the
> struct. Currently every user sets each field, so if new fields are
> added, the core code parsing the struct will see garbage in the new
> field.
> 
> It could be possible to initialize the new field for each arch to 0, but
> instead simply inialize the field with a C99 struct inializing syntax.

Why doing a full init of the struct when all fields are re-written a few 
lines after ?

If I take the exemple of powerpc function slice_find_area_bottomup():

struct vm_unmapped_area_info info;

info.flags = 0;
info.length = len;
info.align_mask = PAGE_MASK & ((1ul << pshift) - 1);
info.align_offset = 0;

For me it looks better to just add:

info.new_field = 0; /* or whatever value it needs to have */

Christophe


> 
> Cc: linux...@kvack.org
> Cc: linux-al...@vger.kernel.org
> Cc: linux-snps-...@lists.infradead.org
> Cc: linux-arm-ker...@lists.infradead.org
> Cc: linux-c...@vger.kernel.org
> Cc: loonga...@lists.linux.dev
> Cc: linux-m...@vger.kernel.org
> Cc: linux-par...@vger.kernel.org
> Cc: linuxppc-dev@lists.ozlabs.org
> Cc: linux-s...@vger.kernel.org
> Cc: linux...@vger.kernel.org
> Cc: sparcli...@vger.kernel.org
> Cc: x...@kernel.org
> Suggested-by: Kirill A. Shutemov 
> Signed-off-by: Rick Edgecombe 
> Link: 
> https://lore.kernel.org/lkml/3ynogxcgokc6i6xojbxzzwqectg472laes24u7jmtktlxcch5e@dfytra3ia3zc/#t
> ---
> Hi archs,
> 
> For some context, this is part of a larger series to improve shadow stack
> guard gaps. It involves plumbing a new field via
> struct vm_unmapped_area_info. The first user is x86, but arm and riscv may
> likely use it as well. The change is compile tested only for non-x86 but
> seems like a relatively safe one.
> 
> Thanks,
> 
> Rick
> 
> v2:
>   - New patch
> ---
>   arch/alpha/kernel/osf_sys.c  | 2 +-
>   arch/arc/mm/mmap.c   | 2 +-
>   arch/arm/mm/mmap.c   | 4 ++--
>   arch/csky/abiv1/mmap.c   | 2 +-
>   arch/loongarch/mm/mmap.c | 2 +-
>   arch/mips/mm/mmap.c  | 2 +-
>   arch/parisc/kernel/sys_parisc.c  | 2 +-
>   arch/powerpc/mm/book3s64/slice.c | 4 ++--
>   arch/s390/mm/hugetlbpage.c   | 4 ++--
>   arch/s390/mm/mmap.c  | 4 ++--
>   arch/sh/mm/mmap.c| 4 ++--
>   arch/sparc/kernel/sys_sparc_32.c | 2 +-
>   arch/sparc/kernel/sys_sparc_64.c | 4 ++--
>   arch/sparc/mm/hugetlbpage.c  | 4 ++--
>   arch/x86/kernel/sys_x86_64.c | 4 ++--
>   arch/x86/mm/hugetlbpage.c| 4 ++--
>   fs/hugetlbfs/inode.c | 4 ++--
>   mm/mmap.c| 4 ++--
>   18 files changed, 29 insertions(+), 29 deletions(-)
> 
> diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
> index 5db88b627439..dd6801bb9240 100644
> --- a/arch/alpha/kernel/osf_sys.c
> +++ b/arch/alpha/kernel/osf_sys.c
> @@ -1218,7 +1218,7 @@ static unsigned long
>   arch_get_unmapped_area_1(unsigned long addr, unsigned long len,
>unsigned long limit)
>   {
> - struct vm_unmapped_area_info info;
> + struct vm_unmapped_area_info info = {};
>   
>   info.flags = 0;
>   info.length = len;
> diff --git a/arch/arc/mm/mmap.c b/arch/arc/mm/mmap.c
> index 3c1c7ae73292..6549b3375f54 100644
> --- a/arch/arc/mm/mmap.c
> +++ b/arch/arc/mm/mmap.c
> @@ -27,7 +27,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long 
> addr,
>   {
>   struct mm_struct *mm = current->mm;
>   struct vm_area_struct *vma;
> - struct vm_unmapped_area_info info;
> + struct vm_unmapped_area_info info = {};
>   
>   /*
>* We enforce the MAP_FIXED case.
> diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
> index a0f8a0ca0788..525795578c29 100644
> --- a/arch/arm/mm/mmap.c
> +++ b/arch/arm/mm/mmap.c
> @@ -34,7 +34,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long 
> addr,
>   struct vm_area_struct *vma;
>   int do_align = 0;
>   int aliasing = cache_is_vipt_aliasing();
> - struct vm_unmapped_area_info info;
> + struct vm_unmapped_area_info info = {};
>   
>   /*
>* We only need to do colour alignment if either the I or D
> @@ -87,7 +87,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const 
> unsigned long addr0,
>   unsigned long addr = addr0;
>   int do_align = 0;
>   int aliasing = cache_is_vipt_aliasing();
> - struct vm_unmapped_area_info info;
> + struct vm_unmapped_area_info info = {};
>   
>   /*
>* We only need to do colour alignment if either the I or D
> diff --git a/arch/csky/abiv1/mmap.c b/arch/csky/abiv1/mmap.c
> index 6792aca4..726659d41fa9 100644
> --- a/arch/csky/abiv1/mmap.c
> +++ b/arch/csky/abiv1/mmap.c
> @@ -28,7 +28,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long 
> addr,
>   struct mm_struct *mm = 

Re: [PATCH] powerpc/mm: Code cleanup for __hash_page_thp

2024-02-26 Thread Michael Ellerman
Kunwu Chan  writes:
> Thanks for the reply.
>
> On 2024/2/26 18:49, Michael Ellerman wrote:
>> Kunwu Chan  writes:
>>> This part was commented from commit 6d492ecc6489
>>> ("powerpc/THP: Add code to handle HPTE faults for hugepages")
>>> in about 11 years before.
>>>
>>> If there are no plans to enable this part code in the future,
>>> we can remove this dead code.
>> 
>> I agree the code can go. But I'd like it to be replaced with a comment
>> explaining what the dead code was trying to say.

> Thanks, i'll update a new patch with the following comment:
>  /*
>  * No CPU has hugepages but lacks no execute, so we
>  * don't need to worry about cpu no CPU_FTR_COHERENT_ICACHE feature case
>  */

Maybe wait until we can get some input from Aneesh. I'm not sure the
code/comment are really up to date.

cheers


Re: [PATCHv10 2/4] genirq: Provide a snapshot mechanism for interrupt statistics

2024-02-26 Thread Liu Song



在 2024/2/26 10:09, Bitao Hu 写道:

The soft lockup detector lacks a mechanism to identify interrupt storms
as root cause of a lockup. To enable this the detector needs a
mechanism to snapshot the interrupt count statistics on a CPU when the
detector observes a potential lockup scenario and compare that against
the interrupt count when it warns about the lockup later on. The number
of interrupts in that period give a hint whether the lockup might be
caused by an interrupt storm.

Instead of having extra storage in the lockup detector and accessing
the internals of the interrupt descriptor directly, convert the per CPU
irq_desc::kstat_irq member to a data structure which contains the
counter plus a snapshot member and provide interfaces to take a
snapshot of all interrupts on the current CPU and to retrieve the delta
of a specific interrupt later on.

Originally-by: Thomas Gleixner 
Signed-off-by: Bitao Hu 
---
  arch/mips/dec/setup.c|  2 +-
  arch/parisc/kernel/smp.c |  2 +-
  arch/powerpc/kvm/book3s_hv_rm_xics.c |  2 +-
  include/linux/irqdesc.h  |  9 ++--
  include/linux/kernel_stat.h  |  3 +++
  kernel/irq/internals.h   |  2 +-
  kernel/irq/irqdesc.c | 34 ++--
  kernel/irq/proc.c|  5 ++--
  scripts/gdb/linux/interrupts.py  |  6 ++---
  9 files changed, 46 insertions(+), 19 deletions(-)

diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c
index 6c3704f51d0d..87f0a1436bf9 100644
--- a/arch/mips/dec/setup.c
+++ b/arch/mips/dec/setup.c
@@ -756,7 +756,7 @@ void __init arch_init_irq(void)
NULL))
pr_err("Failed to register fpu interrupt\n");
desc_fpu = irq_to_desc(irq_fpu);
-   fpu_kstat_irq = this_cpu_ptr(desc_fpu->kstat_irqs);
+   fpu_kstat_irq = this_cpu_ptr(_fpu->kstat_irqs->cnt);
}
if (dec_interrupt[DEC_IRQ_CASCADE] >= 0) {
if (request_irq(dec_interrupt[DEC_IRQ_CASCADE], no_action,
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index 444154271f23..800eb64e91ad 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -344,7 +344,7 @@ static int smp_boot_one_cpu(int cpuid, struct task_struct 
*idle)
struct irq_desc *desc = irq_to_desc(i);
  
  		if (desc && desc->kstat_irqs)

-   *per_cpu_ptr(desc->kstat_irqs, cpuid) = 0;
+   *per_cpu_ptr(desc->kstat_irqs, cpuid) = (struct 
irqstat) { };
}
  #endif
  
diff --git a/arch/powerpc/kvm/book3s_hv_rm_xics.c b/arch/powerpc/kvm/book3s_hv_rm_xics.c

index e42984878503..f2636414d82a 100644
--- a/arch/powerpc/kvm/book3s_hv_rm_xics.c
+++ b/arch/powerpc/kvm/book3s_hv_rm_xics.c
@@ -837,7 +837,7 @@ static inline void this_cpu_inc_rm(unsigned int __percpu 
*addr)
   */
  static void kvmppc_rm_handle_irq_desc(struct irq_desc *desc)
  {
-   this_cpu_inc_rm(desc->kstat_irqs);
+   this_cpu_inc_rm(>kstat_irqs->cnt);
__this_cpu_inc(kstat.irqs_sum);
  }
  
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h

index d9451d456a73..2912b1998670 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -17,6 +17,11 @@ struct irq_desc;
  struct irq_domain;
  struct pt_regs;
  
+struct irqstat {

+   unsigned intcnt;
+   unsigned intref;
+};
+
  /**
   * struct irq_desc - interrupt descriptor
   * @irq_common_data:  per irq and chip data passed down to chip functions
@@ -55,7 +60,7 @@ struct pt_regs;
  struct irq_desc {
struct irq_common_data  irq_common_data;
struct irq_data irq_data;
-   unsigned int __percpu   *kstat_irqs;
+   struct irqstat __percpu *kstat_irqs;
irq_flow_handler_t  handle_irq;
struct irqaction*action;/* IRQ action list */
unsigned intstatus_use_accessors;
@@ -119,7 +124,7 @@ extern struct irq_desc irq_desc[NR_IRQS];
  static inline unsigned int irq_desc_kstat_cpu(struct irq_desc *desc,
  unsigned int cpu)
  {
-   return desc->kstat_irqs ? *per_cpu_ptr(desc->kstat_irqs, cpu) : 0;
+   return desc->kstat_irqs ? per_cpu(desc->kstat_irqs->cnt, cpu) : 0;
  }
  
  static inline struct irq_desc *irq_data_to_desc(struct irq_data *data)

diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h
index 9935f7ecbfb9..98b3043ea5e6 100644
--- a/include/linux/kernel_stat.h
+++ b/include/linux/kernel_stat.h
@@ -79,6 +79,9 @@ static inline unsigned int kstat_cpu_softirqs_sum(int cpu)
return sum;
  }
  
+extern void kstat_snapshot_irqs(void);

+extern unsigned int kstat_get_irq_since_snapshot(unsigned int irq);
+
  /*
   * Number of interrupts per specific IRQ source, since bootup
   */
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index bcc7f21db9ee..1d92532c2aae 100644
--- a/kernel/irq/internals.h
+++ 

Re: [PATCH v13 09/16] media: uapi: Define audio sample format fourcc type

2024-02-26 Thread Shengjiu Wang
On Mon, Feb 26, 2024 at 9:55 PM Nicolas Dufresne 
wrote:
>
> Le lundi 26 février 2024 à 16:28 +0800, Shengjiu Wang a écrit :
> > The audio sample format definition is from alsa,
> > the header file is include/uapi/sound/asound.h, but
> > don't include this header file directly, because in
> > user space, there is another copy in alsa-lib.
> > There will be conflict in userspace for include
> > videodev2.h & asound.h and asoundlib.h
> >
> > Here still use the fourcc format.
>
> I'd like to join Mauro's voice that duplicating the audio formats is a
bad idea.
> We have the same issues with video formats when you look at V4L2 vs DRM.
You're
> rationale is that videodev2.h will be ambiguous if it includes asound.h,
but
> looking at this change, there is no reason why you need to include
asound.h in
> videodev2.h at all. The format type can be abstracted out with a uint32
in the
> API, and then it would be up to the users to include and use the
appropriate
> formats IDs.
>

Thanks.

There is another reason mentioned by Hans:
"
















*The problem is that within V4L2 we use fourcc consistently to describe
aformat, including in VIDIOC_ENUM_FMT. And the expectation is that the
fourcccan be printed to a human readable string (there is even a printk
format forthat these days).But the pcm values are all small integers (and
can even be 0!), andprinting the fourcc will give garbage. It doesn't work
well at allwith the V4L2 API. But by having a straightforward conversion
between thepcm identifier and a fourcc it was really easy to deal with
this.There might even be applications today that call VIDIOC_ENUM_FMT to
seewhat is supported and fail if it is not a proper fourcc is returned.It
will certainly report nonsense in v4l_print_fmtdesc() (v4l2-ioctl.c).One of
the early versions of this patch series did precisely what you request,but
it just doesn't work well within the V4L2 uAPI.*
*"*

Best regards
Shengjiu Wang

> Nicolas
>
> >
> > Signed-off-by: Shengjiu Wang 
> > ---
> >  .../userspace-api/media/v4l/pixfmt-audio.rst  | 87 +++
> >  .../userspace-api/media/v4l/pixfmt.rst|  1 +
> >  drivers/media/v4l2-core/v4l2-ioctl.c  | 13 +++
> >  include/uapi/linux/videodev2.h| 23 +
> >  4 files changed, 124 insertions(+)
> >  create mode 100644
Documentation/userspace-api/media/v4l/pixfmt-audio.rst
> >
> > diff --git a/Documentation/userspace-api/media/v4l/pixfmt-audio.rst
b/Documentation/userspace-api/media/v4l/pixfmt-audio.rst
> > new file mode 100644
> > index ..04b4a7fbd8f4
> > --- /dev/null
> > +++ b/Documentation/userspace-api/media/v4l/pixfmt-audio.rst
> > @@ -0,0 +1,87 @@
> > +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
> > +
> > +.. _pixfmt-audio:
> > +
> > +*
> > +Audio Formats
> > +*
> > +
> > +These formats are used for :ref:`audiomem2mem` interface only.
> > +
> > +.. tabularcolumns:: |p{5.8cm}|p{1.2cm}|p{10.3cm}|
> > +
> > +.. cssclass:: longtable
> > +
> > +.. flat-table:: Audio Format
> > +:header-rows:  1
> > +:stub-columns: 0
> > +:widths:   3 1 4
> > +
> > +* - Identifier
> > +  - Code
> > +  - Details
> > +* .. _V4L2-AUDIO-FMT-S8:
> > +
> > +  - ``V4L2_AUDIO_FMT_S8``
> > +  - 'S8'
> > +  - Corresponds to SNDRV_PCM_FORMAT_S8 in ALSA
> > +* .. _V4L2-AUDIO-FMT-S16-LE:
> > +
> > +  - ``V4L2_AUDIO_FMT_S16_LE``
> > +  - 'S16_LE'
> > +  - Corresponds to SNDRV_PCM_FORMAT_S16_LE in ALSA
> > +* .. _V4L2-AUDIO-FMT-U16-LE:
> > +
> > +  - ``V4L2_AUDIO_FMT_U16_LE``
> > +  - 'U16_LE'
> > +  - Corresponds to SNDRV_PCM_FORMAT_U16_LE in ALSA
> > +* .. _V4L2-AUDIO-FMT-S24-LE:
> > +
> > +  - ``V4L2_AUDIO_FMT_S24_LE``
> > +  - 'S24_LE'
> > +  - Corresponds to SNDRV_PCM_FORMAT_S24_LE in ALSA
> > +* .. _V4L2-AUDIO-FMT-U24-LE:
> > +
> > +  - ``V4L2_AUDIO_FMT_U24_LE``
> > +  - 'U24_LE'
> > +  - Corresponds to SNDRV_PCM_FORMAT_U24_LE in ALSA
> > +* .. _V4L2-AUDIO-FMT-S32-LE:
> > +
> > +  - ``V4L2_AUDIO_FMT_S32_LE``
> > +  - 'S32_LE'
> > +  - Corresponds to SNDRV_PCM_FORMAT_S32_LE in ALSA
> > +* .. _V4L2-AUDIO-FMT-U32-LE:
> > +
> > +  - ``V4L2_AUDIO_FMT_U32_LE``
> > +  - 'U32_LE'
> > +  - Corresponds to SNDRV_PCM_FORMAT_U32_LE in ALSA
> > +* .. _V4L2-AUDIO-FMT-FLOAT-LE:
> > +
> > +  - ``V4L2_AUDIO_FMT_FLOAT_LE``
> > +  - 'FLOAT_LE'
> > +  - Corresponds to SNDRV_PCM_FORMAT_FLOAT_LE in ALSA
> > +* .. _V4L2-AUDIO-FMT-IEC958-SUBFRAME-LE:
> > +
> > +  - ``V4L2_AUDIO_FMT_IEC958_SUBFRAME_LE``
> > +  - 'IEC958_SUBFRAME_LE'
> > +  - Corresponds to SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE in ALSA
> > +* .. _V4L2-AUDIO-FMT-S24-3LE:
> > +
> > +  - ``V4L2_AUDIO_FMT_S24_3LE``
> > +  - 'S24_3LE'
> > +  - Corresponds to SNDRV_PCM_FORMAT_S24_3LE in ALSA
> > +* .. _V4L2-AUDIO-FMT-U24-3LE:
> > +
> > +  - ``V4L2_AUDIO_FMT_U24_3LE``
> > +  - 'U24_3LE'
> > + 

Re: [PATCH v13 09/16] media: uapi: Define audio sample format fourcc type

2024-02-26 Thread Shengjiu Wang
On Mon, Feb 26, 2024 at 9:55 PM Nicolas Dufresne  wrote:
>
> Le lundi 26 février 2024 à 16:28 +0800, Shengjiu Wang a écrit :
> > The audio sample format definition is from alsa,
> > the header file is include/uapi/sound/asound.h, but
> > don't include this header file directly, because in
> > user space, there is another copy in alsa-lib.
> > There will be conflict in userspace for include
> > videodev2.h & asound.h and asoundlib.h
> >
> > Here still use the fourcc format.
>
> I'd like to join Mauro's voice that duplicating the audio formats is a bad 
> idea.
> We have the same issues with video formats when you look at V4L2 vs DRM. 
> You're
> rationale is that videodev2.h will be ambiguous if it includes asound.h, but
> looking at this change, there is no reason why you need to include asound.h in
> videodev2.h at all. The format type can be abstracted out with a uint32 in the
> API, and then it would be up to the users to include and use the appropriate
> formats IDs.
>

Resend for the plain text issue

Thanks.

There is another reason mentioned by Hans:

"
The problem is that within V4L2 we use fourcc consistently to describe a
format, including in VIDIOC_ENUM_FMT. And the expectation is that the fourcc
can be printed to a human readable string (there is even a printk format for
that these days).

But the pcm values are all small integers (and can even be 0!), and
printing the fourcc will give garbage. It doesn't work well at all
with the V4L2 API. But by having a straightforward conversion between the
pcm identifier and a fourcc it was really easy to deal with this.

There might even be applications today that call VIDIOC_ENUM_FMT to see
what is supported and fail if it is not a proper fourcc is returned.

It will certainly report nonsense in v4l_print_fmtdesc() (v4l2-ioctl.c).

One of the early versions of this patch series did precisely what you request,
but it just doesn't work well within the V4L2 uAPI.
"

Best regards
Shengjiu Wang
> Nicolas
>
> >
> > Signed-off-by: Shengjiu Wang 
> > ---
> >  .../userspace-api/media/v4l/pixfmt-audio.rst  | 87 +++
> >  .../userspace-api/media/v4l/pixfmt.rst|  1 +
> >  drivers/media/v4l2-core/v4l2-ioctl.c  | 13 +++
> >  include/uapi/linux/videodev2.h| 23 +
> >  4 files changed, 124 insertions(+)
> >  create mode 100644 Documentation/userspace-api/media/v4l/pixfmt-audio.rst
> >
> > diff --git a/Documentation/userspace-api/media/v4l/pixfmt-audio.rst 
> > b/Documentation/userspace-api/media/v4l/pixfmt-audio.rst
> > new file mode 100644
> > index ..04b4a7fbd8f4
> > --- /dev/null
> > +++ b/Documentation/userspace-api/media/v4l/pixfmt-audio.rst
> > @@ -0,0 +1,87 @@
> > +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
> > +
> > +.. _pixfmt-audio:
> > +
> > +*
> > +Audio Formats
> > +*
> > +
> > +These formats are used for :ref:`audiomem2mem` interface only.
> > +
> > +.. tabularcolumns:: |p{5.8cm}|p{1.2cm}|p{10.3cm}|
> > +
> > +.. cssclass:: longtable
> > +
> > +.. flat-table:: Audio Format
> > +:header-rows:  1
> > +:stub-columns: 0
> > +:widths:   3 1 4
> > +
> > +* - Identifier
> > +  - Code
> > +  - Details
> > +* .. _V4L2-AUDIO-FMT-S8:
> > +
> > +  - ``V4L2_AUDIO_FMT_S8``
> > +  - 'S8'
> > +  - Corresponds to SNDRV_PCM_FORMAT_S8 in ALSA
> > +* .. _V4L2-AUDIO-FMT-S16-LE:
> > +
> > +  - ``V4L2_AUDIO_FMT_S16_LE``
> > +  - 'S16_LE'
> > +  - Corresponds to SNDRV_PCM_FORMAT_S16_LE in ALSA
> > +* .. _V4L2-AUDIO-FMT-U16-LE:
> > +
> > +  - ``V4L2_AUDIO_FMT_U16_LE``
> > +  - 'U16_LE'
> > +  - Corresponds to SNDRV_PCM_FORMAT_U16_LE in ALSA
> > +* .. _V4L2-AUDIO-FMT-S24-LE:
> > +
> > +  - ``V4L2_AUDIO_FMT_S24_LE``
> > +  - 'S24_LE'
> > +  - Corresponds to SNDRV_PCM_FORMAT_S24_LE in ALSA
> > +* .. _V4L2-AUDIO-FMT-U24-LE:
> > +
> > +  - ``V4L2_AUDIO_FMT_U24_LE``
> > +  - 'U24_LE'
> > +  - Corresponds to SNDRV_PCM_FORMAT_U24_LE in ALSA
> > +* .. _V4L2-AUDIO-FMT-S32-LE:
> > +
> > +  - ``V4L2_AUDIO_FMT_S32_LE``
> > +  - 'S32_LE'
> > +  - Corresponds to SNDRV_PCM_FORMAT_S32_LE in ALSA
> > +* .. _V4L2-AUDIO-FMT-U32-LE:
> > +
> > +  - ``V4L2_AUDIO_FMT_U32_LE``
> > +  - 'U32_LE'
> > +  - Corresponds to SNDRV_PCM_FORMAT_U32_LE in ALSA
> > +* .. _V4L2-AUDIO-FMT-FLOAT-LE:
> > +
> > +  - ``V4L2_AUDIO_FMT_FLOAT_LE``
> > +  - 'FLOAT_LE'
> > +  - Corresponds to SNDRV_PCM_FORMAT_FLOAT_LE in ALSA
> > +* .. _V4L2-AUDIO-FMT-IEC958-SUBFRAME-LE:
> > +
> > +  - ``V4L2_AUDIO_FMT_IEC958_SUBFRAME_LE``
> > +  - 'IEC958_SUBFRAME_LE'
> > +  - Corresponds to SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE in ALSA
> > +* .. _V4L2-AUDIO-FMT-S24-3LE:
> > +
> > +  - ``V4L2_AUDIO_FMT_S24_3LE``
> > +  - 'S24_3LE'
> > +  - Corresponds to SNDRV_PCM_FORMAT_S24_3LE in ALSA
> > +* .. _V4L2-AUDIO-FMT-U24-3LE:
> > +
> > +  - 

Re: [PATCH] powerpc/mm: Code cleanup for __hash_page_thp

2024-02-26 Thread Kunwu Chan

Thanks for the reply.

On 2024/2/26 18:49, Michael Ellerman wrote:

Kunwu Chan  writes:

This part was commented from commit 6d492ecc6489
("powerpc/THP: Add code to handle HPTE faults for hugepages")
in about 11 years before.

If there are no plans to enable this part code in the future,
we can remove this dead code.


I agree the code can go. But I'd like it to be replaced with a comment
explaining what the dead code was trying to say.

Thanks, i'll update a new patch with the following comment:
/*
* No CPU has hugepages but lacks no execute, so we
* don't need to worry about cpu no CPU_FTR_COHERENT_ICACHE feature case
*/



cheers


diff --git a/arch/powerpc/mm/book3s64/hash_hugepage.c 
b/arch/powerpc/mm/book3s64/hash_hugepage.c
index c0fabe6c5a12..127a3a2c174b 100644
--- a/arch/powerpc/mm/book3s64/hash_hugepage.c
+++ b/arch/powerpc/mm/book3s64/hash_hugepage.c
@@ -59,16 +59,6 @@ int __hash_page_thp(unsigned long ea, unsigned long access, 
unsigned long vsid,
  
  	rflags = htab_convert_pte_flags(new_pmd, flags);
  
-#if 0

-   if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) {
-
-   /*
-* No CPU has hugepages but lacks no execute, so we
-* don't need to worry about that case
-*/
-   rflags = hash_page_do_lazy_icache(rflags, __pte(old_pte), trap);
-   }
-#endif
/*
 * Find the slot index details for this ea, using base page size.
 */
--
2.39.2

--
Thanks,
  Kunwu



Re: linux-next: Tree for Feb 26 (drivers/mtd/ubi/nvmem.c)

2024-02-26 Thread Randy Dunlap



On 2/25/24 22:55, Stephen Rothwell wrote:
> Hi all,
> 
> Changes since 20240223:
> 

on powerpc32:

In file included from ./arch/powerpc/include/generated/asm/div64.h:1,
 from ../include/linux/math.h:6,
 from ../include/linux/kernel.h:27,
 from ../arch/powerpc/include/asm/page.h:11,
 from ../arch/powerpc/include/asm/thread_info.h:13,
 from ../include/linux/thread_info.h:60,
 from ../arch/powerpc/include/asm/ptrace.h:342,
 from ../arch/powerpc/include/asm/hw_irq.h:12,
 from ../arch/powerpc/include/asm/irqflags.h:12,
 from ../include/linux/irqflags.h:18,
 from ../include/asm-generic/cmpxchg-local.h:6,
 from ../arch/powerpc/include/asm/cmpxchg.h:755,
 from ../arch/powerpc/include/asm/atomic.h:11,
 from ../include/linux/atomic.h:7,
 from ../include/linux/rcupdate.h:25,
 from ../include/linux/rbtree.h:24,
 from ../drivers/mtd/ubi/ubi.h:14,
 from ../drivers/mtd/ubi/nvmem.c:7:
../drivers/mtd/ubi/nvmem.c: In function 'ubi_nvmem_reg_read':
../include/asm-generic/div64.h:222:35: warning: comparison of distinct pointer 
types lacks a cast
  222 | (void)(((typeof((n)) *)0) == ((uint64_t *)0));  \
  |   ^~
../drivers/mtd/ubi/nvmem.c:34:16: note: in expansion of macro 'do_div'
   34 | offs = do_div(lnum, unv->usable_leb_size);
  |^~
In file included from ../include/linux/build_bug.h:5,
 from ../include/linux/container_of.h:5,
 from ../include/linux/list.h:5,
 from ../drivers/mtd/ubi/ubi.h:13:
../include/asm-generic/div64.h:234:32: warning: right shift count >= width of 
type [-Wshift-count-overflow]
  234 | } else if (likely(((n) >> 32) == 0)) {  \
  |^~
../include/linux/compiler.h:76:45: note: in definition of macro 'likely'
   76 | # define likely(x)  __builtin_expect(!!(x), 1)
  | ^
../drivers/mtd/ubi/nvmem.c:34:16: note: in expansion of macro 'do_div'
   34 | offs = do_div(lnum, unv->usable_leb_size);
  |^~
../include/asm-generic/div64.h:238:36: error: passing argument 1 of 
'__div64_32' from incompatible pointer type [-Werror=incompatible-pointer-types]
  238 | __rem = __div64_32(&(n), __base);   \
  |^~~~
  ||
  |int *
../drivers/mtd/ubi/nvmem.c:34:16: note: in expansion of macro 'do_div'
   34 | offs = do_div(lnum, unv->usable_leb_size);
  |^~
../include/asm-generic/div64.h:213:38: note: expected 'uint64_t *' {aka 'long 
long unsigned int *'} but argument is of type 'int *'
  213 | extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor);
  |~~^~~~




-- 
#Randy


Re: [PATCH 3/4] arch: define CONFIG_PAGE_SIZE_*KB on all architectures

2024-02-26 Thread Guo Ren
On Tue, Feb 27, 2024 at 12:15 AM Arnd Bergmann  wrote:
>
> From: Arnd Bergmann 
>
> Most architectures only support a single hardcoded page size. In order
> to ensure that each one of these sets the corresponding Kconfig symbols,
> change over the PAGE_SHIFT definition to the common one and allow
> only the hardware page size to be selected.
>
> Signed-off-by: Arnd Bergmann 
> ---
>  arch/alpha/Kconfig | 1 +
>  arch/alpha/include/asm/page.h  | 2 +-
>  arch/arm/Kconfig   | 1 +
>  arch/arm/include/asm/page.h| 2 +-
>  arch/csky/Kconfig  | 1 +
>  arch/csky/include/asm/page.h   | 2 +-
>  arch/m68k/Kconfig  | 3 +++
>  arch/m68k/Kconfig.cpu  | 2 ++
>  arch/m68k/include/asm/page.h   | 6 +-
>  arch/microblaze/Kconfig| 1 +
>  arch/microblaze/include/asm/page.h | 2 +-
>  arch/nios2/Kconfig | 1 +
>  arch/nios2/include/asm/page.h  | 2 +-
>  arch/openrisc/Kconfig  | 1 +
>  arch/openrisc/include/asm/page.h   | 2 +-
>  arch/riscv/Kconfig | 1 +
>  arch/riscv/include/asm/page.h  | 2 +-
>  arch/s390/Kconfig  | 1 +
>  arch/s390/include/asm/page.h   | 2 +-
>  arch/sparc/Kconfig | 2 ++
>  arch/sparc/include/asm/page_32.h   | 2 +-
>  arch/sparc/include/asm/page_64.h   | 3 +--
>  arch/um/Kconfig| 1 +
>  arch/um/include/asm/page.h | 2 +-
>  arch/x86/Kconfig   | 1 +
>  arch/x86/include/asm/page_types.h  | 2 +-
>  arch/xtensa/Kconfig| 1 +
>  arch/xtensa/include/asm/page.h | 2 +-
>  28 files changed, 32 insertions(+), 19 deletions(-)
>
> diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
> index d6968d090d49..4f490250d323 100644
> --- a/arch/alpha/Kconfig
> +++ b/arch/alpha/Kconfig
> @@ -14,6 +14,7 @@ config ALPHA
> select PCI_DOMAINS if PCI
> select PCI_SYSCALL if PCI
> select HAVE_ASM_MODVERSIONS
> +   select HAVE_PAGE_SIZE_8KB
> select HAVE_PCSPKR_PLATFORM
> select HAVE_PERF_EVENTS
> select NEED_DMA_MAP_STATE
> diff --git a/arch/alpha/include/asm/page.h b/arch/alpha/include/asm/page.h
> index 4db1ebc0ed99..70419e6be1a3 100644
> --- a/arch/alpha/include/asm/page.h
> +++ b/arch/alpha/include/asm/page.h
> @@ -6,7 +6,7 @@
>  #include 
>
>  /* PAGE_SHIFT determines the page size */
> -#define PAGE_SHIFT 13
> +#define PAGE_SHIFT CONFIG_PAGE_SHIFT
>  #define PAGE_SIZE  (_AC(1,UL) << PAGE_SHIFT)
>  #define PAGE_MASK  (~(PAGE_SIZE-1))
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 0af6709570d1..9d52ba3a8ad1 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -116,6 +116,7 @@ config ARM
> select HAVE_MOD_ARCH_SPECIFIC
> select HAVE_NMI
> select HAVE_OPTPROBES if !THUMB2_KERNEL
> +   select HAVE_PAGE_SIZE_4KB
> select HAVE_PCI if MMU
> select HAVE_PERF_EVENTS
> select HAVE_PERF_REGS
> diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
> index 119aa85d1feb..62af9f7f9e96 100644
> --- a/arch/arm/include/asm/page.h
> +++ b/arch/arm/include/asm/page.h
> @@ -8,7 +8,7 @@
>  #define _ASMARM_PAGE_H
>
>  /* PAGE_SHIFT determines the page size */
> -#define PAGE_SHIFT 12
> +#define PAGE_SHIFT CONFIG_PAGE_SHIFT
>  #define PAGE_SIZE  (_AC(1,UL) << PAGE_SHIFT)
>  #define PAGE_MASK  (~((1 << PAGE_SHIFT) - 1))
>
> diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig
> index cf2a6fd7dff8..9c2723ab1c94 100644
> --- a/arch/csky/Kconfig
> +++ b/arch/csky/Kconfig
> @@ -89,6 +89,7 @@ config CSKY
> select HAVE_KPROBES if !CPU_CK610
> select HAVE_KPROBES_ON_FTRACE if !CPU_CK610
> select HAVE_KRETPROBES if !CPU_CK610
> +   select HAVE_PAGE_SIZE_4KB
> select HAVE_PERF_EVENTS
> select HAVE_PERF_REGS
> select HAVE_PERF_USER_STACK_DUMP
> diff --git a/arch/csky/include/asm/page.h b/arch/csky/include/asm/page.h
> index 4a0502e324a6..f70f37402d75 100644
> --- a/arch/csky/include/asm/page.h
> +++ b/arch/csky/include/asm/page.h
> @@ -10,7 +10,7 @@
>  /*
>   * PAGE_SHIFT determines the page size: 4KB
>   */
> -#define PAGE_SHIFT 12
> +#define PAGE_SHIFT CONFIG_PAGE_SHIFT
LGTM, thx.
Acked-by: Guo Ren 

>  #define PAGE_SIZE  (_AC(1, UL) << PAGE_SHIFT)
>  #define PAGE_MASK  (~(PAGE_SIZE - 1))
>  #define THREAD_SIZE(PAGE_SIZE * 2)
> diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
> index 4b3e93cac723..7b709453d5e7 100644
> --- a/arch/m68k/Kconfig
> +++ b/arch/m68k/Kconfig
> @@ -84,12 +84,15 @@ config MMU
>
>  config MMU_MOTOROLA
> bool
> +   select HAVE_PAGE_SIZE_4KB
>
>  config MMU_COLDFIRE
> +   select HAVE_PAGE_SIZE_8KB
> bool
>
>  config MMU_SUN3
> bool
> +   select HAVE_PAGE_SIZE_8KB
> depends on MMU && !MMU_MOTOROLA && !MMU_COLDFIRE
>
>  config ARCH_SUPPORTS_KEXEC
> diff --git 

[Bug 207129] PowerMac G4 DP (5.6.2 debug kernel + inline KASAN) freezes shortly after booting with "do_IRQ: stack overflow: 1760"

2024-02-26 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=207129

--- Comment #9 from Erhard F. (erhar...@mailbox.org) ---
Created attachment 305910
  --> https://bugzilla.kernel.org/attachment.cgi?id=305910=edit
kernel .config (6.8-rc6, KASAN_INLINE=y, PowerMac G4 DP)

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

[Bug 207129] PowerMac G4 DP (5.6.2 debug kernel + inline KASAN) freezes shortly after booting with "do_IRQ: stack overflow: 1760"

2024-02-26 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=207129

Erhard F. (erhar...@mailbox.org) changed:

   What|Removed |Added

 Status|CLOSED  |REOPENED
 Resolution|CODE_FIX|---

--- Comment #8 from Erhard F. (erhar...@mailbox.org) ---
Currently (as of v6.8-rc6) and since quite a while my G4 does not boot at all
with CONFIG_KASAN_INLINE=y.

When I try booting an KASAN_INLINE enabled kernel it fails with an invalid
memory access and I get dropped out to the OpenFirmaware console.

A small difference is when I boot the 56M vmlinux-6.8.0-rc6-PMacG4:

Please wait, loading kernel...
   Elf32 kernel loaded...

Invalid memory access at   %SRR0: 0013   %SRR1: 1300

Apple PowerMac3,6 4.6.0f1 BootROM built on 02/20/03 at 13:52:27
[...]


vs. booting the 16M arch/powerpc/boot/zImage:


Please wait, loading kernel...
   Elf32 kernel loaded...

zImage starting: loaded at 0x0040 (sp: 0x012eefb0)
OF version = 'OpenFirmware 3'
Allocating 0x2c337e0 bytes for kernel...
Trying to claim from 0x40 to 0x12ef5d8 (0xeef5d8) got 
Decompressing (0x01414000 <- 0x0041:0x12ea9c9)...
Done! Decompressed 0x2bcc80c bytes

Linux/PowerPC load: ro root=/dev/sda5 slub_debug=FZP page_poison=1
netconsole=@192.168.2.8/eth0,@192.168.2.3/A8:A1:59:16:4F:EA debug

Finalizing device tree... using OF tree (promptr=ff847240)

Invalid memory access at   %SRR0: 4000   %SRR1: 

Apple PowerMac3,6 4.6.0f1 BootROM built on 02/20/03 at 13:52:27
[...]


Same kernel with CONFIG_KASAN_OUTLINE=y instead of KASAN_INLINE boots and runs
ok.

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

[PATCH v2 5/9] mm: Initialize struct vm_unmapped_area_info

2024-02-26 Thread Rick Edgecombe
Future changes will need to add a field to struct vm_unmapped_area_info.
This would cause trouble for any archs that don't initialize the
struct. Currently every user sets each field, so if new fields are
added, the core code parsing the struct will see garbage in the new
field.

It could be possible to initialize the new field for each arch to 0, but
instead simply inialize the field with a C99 struct inializing syntax.

Cc: linux...@kvack.org
Cc: linux-al...@vger.kernel.org
Cc: linux-snps-...@lists.infradead.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-c...@vger.kernel.org
Cc: loonga...@lists.linux.dev
Cc: linux-m...@vger.kernel.org
Cc: linux-par...@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-s...@vger.kernel.org
Cc: linux...@vger.kernel.org
Cc: sparcli...@vger.kernel.org
Cc: x...@kernel.org
Suggested-by: Kirill A. Shutemov 
Signed-off-by: Rick Edgecombe 
Link: 
https://lore.kernel.org/lkml/3ynogxcgokc6i6xojbxzzwqectg472laes24u7jmtktlxcch5e@dfytra3ia3zc/#t
---
Hi archs,

For some context, this is part of a larger series to improve shadow stack
guard gaps. It involves plumbing a new field via
struct vm_unmapped_area_info. The first user is x86, but arm and riscv may
likely use it as well. The change is compile tested only for non-x86 but
seems like a relatively safe one.

Thanks,

Rick

v2:
 - New patch
---
 arch/alpha/kernel/osf_sys.c  | 2 +-
 arch/arc/mm/mmap.c   | 2 +-
 arch/arm/mm/mmap.c   | 4 ++--
 arch/csky/abiv1/mmap.c   | 2 +-
 arch/loongarch/mm/mmap.c | 2 +-
 arch/mips/mm/mmap.c  | 2 +-
 arch/parisc/kernel/sys_parisc.c  | 2 +-
 arch/powerpc/mm/book3s64/slice.c | 4 ++--
 arch/s390/mm/hugetlbpage.c   | 4 ++--
 arch/s390/mm/mmap.c  | 4 ++--
 arch/sh/mm/mmap.c| 4 ++--
 arch/sparc/kernel/sys_sparc_32.c | 2 +-
 arch/sparc/kernel/sys_sparc_64.c | 4 ++--
 arch/sparc/mm/hugetlbpage.c  | 4 ++--
 arch/x86/kernel/sys_x86_64.c | 4 ++--
 arch/x86/mm/hugetlbpage.c| 4 ++--
 fs/hugetlbfs/inode.c | 4 ++--
 mm/mmap.c| 4 ++--
 18 files changed, 29 insertions(+), 29 deletions(-)

diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 5db88b627439..dd6801bb9240 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -1218,7 +1218,7 @@ static unsigned long
 arch_get_unmapped_area_1(unsigned long addr, unsigned long len,
 unsigned long limit)
 {
-   struct vm_unmapped_area_info info;
+   struct vm_unmapped_area_info info = {};
 
info.flags = 0;
info.length = len;
diff --git a/arch/arc/mm/mmap.c b/arch/arc/mm/mmap.c
index 3c1c7ae73292..6549b3375f54 100644
--- a/arch/arc/mm/mmap.c
+++ b/arch/arc/mm/mmap.c
@@ -27,7 +27,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 {
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
-   struct vm_unmapped_area_info info;
+   struct vm_unmapped_area_info info = {};
 
/*
 * We enforce the MAP_FIXED case.
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index a0f8a0ca0788..525795578c29 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -34,7 +34,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
struct vm_area_struct *vma;
int do_align = 0;
int aliasing = cache_is_vipt_aliasing();
-   struct vm_unmapped_area_info info;
+   struct vm_unmapped_area_info info = {};
 
/*
 * We only need to do colour alignment if either the I or D
@@ -87,7 +87,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const 
unsigned long addr0,
unsigned long addr = addr0;
int do_align = 0;
int aliasing = cache_is_vipt_aliasing();
-   struct vm_unmapped_area_info info;
+   struct vm_unmapped_area_info info = {};
 
/*
 * We only need to do colour alignment if either the I or D
diff --git a/arch/csky/abiv1/mmap.c b/arch/csky/abiv1/mmap.c
index 6792aca4..726659d41fa9 100644
--- a/arch/csky/abiv1/mmap.c
+++ b/arch/csky/abiv1/mmap.c
@@ -28,7 +28,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
int do_align = 0;
-   struct vm_unmapped_area_info info;
+   struct vm_unmapped_area_info info = {};
 
/*
 * We only need to do colour alignment if either the I or D
diff --git a/arch/loongarch/mm/mmap.c b/arch/loongarch/mm/mmap.c
index a9630a81b38a..664bf4abfdcf 100644
--- a/arch/loongarch/mm/mmap.c
+++ b/arch/loongarch/mm/mmap.c
@@ -24,7 +24,7 @@ static unsigned long arch_get_unmapped_area_common(struct 
file *filp,
struct vm_area_struct *vma;
unsigned long addr = addr0;
int do_color_align;
-   struct vm_unmapped_area_info info;
+   struct vm_unmapped_area_info info = {};
 
if (unlikely(len > TASK_SIZE))
   

Re: [PATCH 2/4] arch: simplify architecture specific page size configuration

2024-02-26 Thread Christophe Leroy


Le 26/02/2024 à 17:14, Arnd Bergmann a écrit :
> From: Arnd Bergmann 
> 
> arc, arm64, parisc and powerpc all have their own Kconfig symbols
> in place of the common CONFIG_PAGE_SIZE_4KB symbols. Change these
> so the common symbols are the ones that are actually used, while
> leaving the arhcitecture specific ones as the user visible
> place for configuring it, to avoid breaking user configs.
> 
> Signed-off-by: Arnd Bergmann 

Reviewed-by: Christophe Leroy  (powerpc32)

> ---
>   arch/arc/Kconfig  |  3 +++
>   arch/arc/include/uapi/asm/page.h  |  6 ++
>   arch/arm64/Kconfig| 29 +
>   arch/arm64/include/asm/page-def.h |  2 +-
>   arch/parisc/Kconfig   |  3 +++
>   arch/parisc/include/asm/page.h| 10 +-
>   arch/powerpc/Kconfig  | 31 ++-
>   arch/powerpc/include/asm/page.h   |  2 +-
>   scripts/gdb/linux/constants.py.in |  2 +-
>   scripts/gdb/linux/mm.py   |  2 +-
>   10 files changed, 32 insertions(+), 58 deletions(-)
> 
> diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
> index 1b0483c51cc1..4092bec198be 100644
> --- a/arch/arc/Kconfig
> +++ b/arch/arc/Kconfig
> @@ -284,14 +284,17 @@ choice
>   
>   config ARC_PAGE_SIZE_8K
>   bool "8KB"
> + select HAVE_PAGE_SIZE_8KB
>   help
> Choose between 8k vs 16k
>   
>   config ARC_PAGE_SIZE_16K
> + select HAVE_PAGE_SIZE_16KB
>   bool "16KB"
>   
>   config ARC_PAGE_SIZE_4K
>   bool "4KB"
> + select HAVE_PAGE_SIZE_4KB
>   depends on ARC_MMU_V3 || ARC_MMU_V4
>   
>   endchoice
> diff --git a/arch/arc/include/uapi/asm/page.h 
> b/arch/arc/include/uapi/asm/page.h
> index 2a4ad619abfb..7fd9e741b527 100644
> --- a/arch/arc/include/uapi/asm/page.h
> +++ b/arch/arc/include/uapi/asm/page.h
> @@ -13,10 +13,8 @@
>   #include 
>   
>   /* PAGE_SHIFT determines the page size */
> -#if defined(CONFIG_ARC_PAGE_SIZE_16K)
> -#define PAGE_SHIFT 14
> -#elif defined(CONFIG_ARC_PAGE_SIZE_4K)
> -#define PAGE_SHIFT 12
> +#ifdef __KERNEL__
> +#define PAGE_SHIFT CONFIG_PAGE_SHIFT
>   #else
>   /*
>* Default 8k
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index aa7c1d435139..29290b8cb36d 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -277,27 +277,21 @@ config 64BIT
>   config MMU
>   def_bool y
>   
> -config ARM64_PAGE_SHIFT
> - int
> - default 16 if ARM64_64K_PAGES
> - default 14 if ARM64_16K_PAGES
> - default 12
> -
>   config ARM64_CONT_PTE_SHIFT
>   int
> - default 5 if ARM64_64K_PAGES
> - default 7 if ARM64_16K_PAGES
> + default 5 if PAGE_SIZE_64KB
> + default 7 if PAGE_SIZE_16KB
>   default 4
>   
>   config ARM64_CONT_PMD_SHIFT
>   int
> - default 5 if ARM64_64K_PAGES
> - default 5 if ARM64_16K_PAGES
> + default 5 if PAGE_SIZE_64KB
> + default 5 if PAGE_SIZE_16KB
>   default 4
>   
>   config ARCH_MMAP_RND_BITS_MIN
> - default 14 if ARM64_64K_PAGES
> - default 16 if ARM64_16K_PAGES
> + default 14 if PAGE_SIZE_64KB
> + default 16 if PAGE_SIZE_16KB
>   default 18
>   
>   # max bits determined by the following formula:
> @@ -1259,11 +1253,13 @@ choice
>   
>   config ARM64_4K_PAGES
>   bool "4KB"
> + select HAVE_PAGE_SIZE_4KB
>   help
> This feature enables 4KB pages support.
>   
>   config ARM64_16K_PAGES
>   bool "16KB"
> + select HAVE_PAGE_SIZE_16KB
>   help
> The system will use 16KB pages support. AArch32 emulation
> requires applications compiled with 16K (or a multiple of 16K)
> @@ -1271,6 +1267,7 @@ config ARM64_16K_PAGES
>   
>   config ARM64_64K_PAGES
>   bool "64KB"
> + select HAVE_PAGE_SIZE_64KB
>   help
> This feature enables 64KB pages support (4KB by default)
> allowing only two levels of page tables and faster TLB
> @@ -1291,19 +1288,19 @@ choice
>   
>   config ARM64_VA_BITS_36
>   bool "36-bit" if EXPERT
> - depends on ARM64_16K_PAGES
> + depends on PAGE_SIZE_16KB
>   
>   config ARM64_VA_BITS_39
>   bool "39-bit"
> - depends on ARM64_4K_PAGES
> + depends on PAGE_SIZE_4KB
>   
>   config ARM64_VA_BITS_42
>   bool "42-bit"
> - depends on ARM64_64K_PAGES
> + depends on PAGE_SIZE_64KB
>   
>   config ARM64_VA_BITS_47
>   bool "47-bit"
> - depends on ARM64_16K_PAGES
> + depends on PAGE_SIZE_16KB
>   
>   config ARM64_VA_BITS_48
>   bool "48-bit"
> diff --git a/arch/arm64/include/asm/page-def.h 
> b/arch/arm64/include/asm/page-def.h
> index 2403f7b4cdbf..792e9fe881dc 100644
> --- a/arch/arm64/include/asm/page-def.h
> +++ b/arch/arm64/include/asm/page-def.h
> @@ -11,7 +11,7 @@
>   #include 
>   
>   /* PAGE_SHIFT determines the page size */
> -#define PAGE_SHIFT   CONFIG_ARM64_PAGE_SHIFT
> +#define PAGE_SHIFT   CONFIG_PAGE_SHIFT
>   #define PAGE_SIZE   (_AC(1, UL) << PAGE_SHIFT)
>   #define PAGE_MASK   

Re: [PATCH 1/4] arch: consolidate existing CONFIG_PAGE_SIZE_*KB definitions

2024-02-26 Thread Christophe Leroy


Le 26/02/2024 à 17:14, Arnd Bergmann a écrit :
> From: Arnd Bergmann 
> 
> These four architectures define the same Kconfig symbols for configuring
> the page size. Move the logic into a common place where it can be shared
> with all other architectures.
> 
> Signed-off-by: Arnd Bergmann 
> ---
>   arch/Kconfig  | 58 +--
>   arch/hexagon/Kconfig  | 25 +++--
>   arch/hexagon/include/asm/page.h   |  6 +---
>   arch/loongarch/Kconfig| 21 ---
>   arch/loongarch/include/asm/page.h | 10 +-
>   arch/mips/Kconfig | 58 +++
>   arch/mips/include/asm/page.h  | 16 +
>   arch/sh/include/asm/page.h| 13 +--
>   arch/sh/mm/Kconfig| 42 +++---
>   9 files changed, 88 insertions(+), 161 deletions(-)
> 
> diff --git a/arch/Kconfig b/arch/Kconfig
> index a5af0edd3eb8..237cea01ed9b 100644
> --- a/arch/Kconfig
> +++ b/arch/Kconfig
> @@ -1078,17 +1078,71 @@ config HAVE_ARCH_COMPAT_MMAP_BASES
> and vice-versa 32-bit applications to call 64-bit mmap().
> Required for applications doing different bitness syscalls.
>   
> +config HAVE_PAGE_SIZE_4KB
> + bool
> +
> +config HAVE_PAGE_SIZE_8KB
> + bool
> +
> +config HAVE_PAGE_SIZE_16KB
> + bool
> +
> +config HAVE_PAGE_SIZE_32KB
> + bool
> +
> +config HAVE_PAGE_SIZE_64KB
> + bool
> +
> +config HAVE_PAGE_SIZE_256KB
> + bool
> +
> +choice
> + prompt "MMU page size"
> +

That's a nice re-factor.

The only drawback I see is that we are loosing several interesting 
arch-specific comments/help text. Don't know if there could be an easy 
way to keep them.


> +config PAGE_SIZE_4KB
> + bool "4KB pages"
> + depends on HAVE_PAGE_SIZE_4KB
> +
> +config PAGE_SIZE_8KB
> + bool "8KB pages"
> + depends on HAVE_PAGE_SIZE_8KB
> +
> +config PAGE_SIZE_16KB
> + bool "16KB pages"
> + depends on HAVE_PAGE_SIZE_16KB
> +
> +config PAGE_SIZE_32KB
> + bool "32KB pages"
> + depends on HAVE_PAGE_SIZE_32KB
> +
> +config PAGE_SIZE_64KB
> + bool "64KB pages"
> + depends on HAVE_PAGE_SIZE_64KB
> +
> +config PAGE_SIZE_256KB
> + bool "256KB pages"
> + depends on HAVE_PAGE_SIZE_256KB

Hexagon seem to also use CONFIG_PAGE_SIZE_1MB ?

> +
> +endchoice
> +
>   config PAGE_SIZE_LESS_THAN_64KB
>   def_bool y
> - depends on !ARM64_64K_PAGES
>   depends on !PAGE_SIZE_64KB
> - depends on !PARISC_PAGE_SIZE_64KB
>   depends on PAGE_SIZE_LESS_THAN_256KB
>   
>   config PAGE_SIZE_LESS_THAN_256KB
>   def_bool y
>   depends on !PAGE_SIZE_256KB
>   
> +config PAGE_SHIFT
> + int
> + default 12 if PAGE_SIZE_4KB
> + default 13 if PAGE_SIZE_8KB
> + default 14 if PAGE_SIZE_16KB
> + default 15 if PAGE_SIZE_32KB
> + default 16 if PAGE_SIZE_64KB
> + default 18 if PAGE_SIZE_256KB
> +
>   # This allows to use a set of generic functions to determine mmap base
>   # address by giving priority to top-down scheme only if the process
>   # is not in legacy mode (compat task, unlimited stack size or
> diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig
> index a880ee067d2e..aac46ee1a000 100644
> --- a/arch/hexagon/Kconfig
> +++ b/arch/hexagon/Kconfig
> @@ -8,6 +8,11 @@ config HEXAGON
>   select ARCH_HAS_SYNC_DMA_FOR_DEVICE
>   select ARCH_NO_PREEMPT
>   select DMA_GLOBAL_POOL
> + select FRAME_POINTER
> + select HAVE_PAGE_SIZE_4KB
> + select HAVE_PAGE_SIZE_16KB
> + select HAVE_PAGE_SIZE_64KB
> + select HAVE_PAGE_SIZE_256KB
>   # Other pending projects/to-do items.
>   # select HAVE_REGS_AND_STACK_ACCESS_API
>   # select HAVE_HW_BREAKPOINT if PERF_EVENTS
> @@ -120,26 +125,6 @@ config NR_CPUS
> This is purely to save memory - each supported CPU adds
> approximately eight kilobytes to the kernel image.
>   
> -choice
> - prompt "Kernel page size"
> - default PAGE_SIZE_4KB
> - help
> -   Changes the default page size; use with caution.
> -
> -config PAGE_SIZE_4KB
> - bool "4KB"
> -
> -config PAGE_SIZE_16KB
> - bool "16KB"
> -
> -config PAGE_SIZE_64KB
> - bool "64KB"
> -
> -config PAGE_SIZE_256KB
> - bool "256KB"
> -
> -endchoice
> -
>   source "kernel/Kconfig.hz"
>   
>   endmenu
> diff --git a/arch/hexagon/include/asm/page.h b/arch/hexagon/include/asm/page.h
> index 10f1bc07423c..65c9bac639fa 100644
> --- a/arch/hexagon/include/asm/page.h
> +++ b/arch/hexagon/include/asm/page.h
> @@ -13,27 +13,22 @@
>   /*  This is probably not the most graceful way to handle this.  */
>   
>   #ifdef CONFIG_PAGE_SIZE_4KB
> -#define PAGE_SHIFT 12
>   #define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_4KB
>   #endif
>   
>   #ifdef CONFIG_PAGE_SIZE_16KB
> -#define PAGE_SHIFT 14
>   #define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_16KB
>   #endif
>   
>   #ifdef CONFIG_PAGE_SIZE_64KB
> -#define PAGE_SHIFT 16
>   #define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_64KB
>   

Re: [PATCH 4/4] vdso: avoid including asm/page.h

2024-02-26 Thread Christophe Leroy


Le 26/02/2024 à 17:14, Arnd Bergmann a écrit :
> From: Arnd Bergmann 
> 
> The recent change to the vdso_data_store broke building compat VDSO
> on at least arm64 because it includes headers outside of the include/vdso/
> namespace:

I understand that powerpc64 also has an issue, see 
https://patchwork.ozlabs.org/project/linuxppc-dev/patch/20231221120410.2226678-1-...@ellerman.id.au/

> 
> In file included from arch/arm64/include/asm/lse.h:5,
>   from arch/arm64/include/asm/cmpxchg.h:14,
>   from arch/arm64/include/asm/atomic.h:16,
>   from include/linux/atomic.h:7,
>   from include/asm-generic/bitops/atomic.h:5,
>   from arch/arm64/include/asm/bitops.h:25,
>   from include/linux/bitops.h:68,
>   from arch/arm64/include/asm/memory.h:209,
>   from arch/arm64/include/asm/page.h:46,
>   from include/vdso/datapage.h:22,
>   from lib/vdso/gettimeofday.c:5,
>   from :
> arch/arm64/include/asm/atomic_ll_sc.h:298:9: error: unknown type name 'u128'
>298 | u128 full;
> 
> Use an open-coded page size calculation based on the new CONFIG_PAGE_SHIFT
> Kconfig symbol instead.
> 
> Reported-by: Linux Kernel Functional Testing 
> Fixes: a0d2fcd62ac2 ("vdso/ARM: Make union vdso_data_store available for all 
> architectures")
> Link: 
> https://lore.kernel.org/lkml/ca+g9fytrxxm_ko9fnpz3xarxhv7ud_yqp-teupqrnrhu+_0...@mail.gmail.com/
> Signed-off-by: Arnd Bergmann 
> ---
>   include/vdso/datapage.h | 4 +---
>   1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
> index 7ba44379a095..2c39a67d7e23 100644
> --- a/include/vdso/datapage.h
> +++ b/include/vdso/datapage.h
> @@ -19,8 +19,6 @@
>   #include 
>   #include 
>   
> -#include 
> -
>   #ifdef CONFIG_ARCH_HAS_VDSO_DATA
>   #include 
>   #else
> @@ -128,7 +126,7 @@ extern struct vdso_data _timens_data[CS_BASES] 
> __attribute__((visibility("hidden
>*/
>   union vdso_data_store {
>   struct vdso_datadata[CS_BASES];
> - u8  page[PAGE_SIZE];
> + u8  page[1ul << CONFIG_PAGE_SHIFT];

Usually 1UL is used (capital letter)

Maybe better to (re)define PAGE_SIZE instead, something like:

#define PAGE_SIZE (1UL << CONFIG_PAGE_SHIFT)


>   };
>   
>   /*


Re: [PATCH v8 10/10] PCI: dwc: ep: Add Kernel-doc comments for APIs

2024-02-26 Thread Frank Li
On Sat, Feb 24, 2024 at 12:24:16PM +0530, Manivannan Sadhasivam wrote:
> All of the APIs are missing the Kernel-doc comments. Hence, add them.
> 
> Signed-off-by: Manivannan Sadhasivam 

Reviewed-by: Frank Li 

> ---
>  drivers/pci/controller/dwc/pcie-designware-ep.c | 92 
> +
>  1 file changed, 92 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c 
> b/drivers/pci/controller/dwc/pcie-designware-ep.c
> index fed4c2936c78..cdcb33a279db 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> @@ -14,6 +14,11 @@
>  #include 
>  #include 
>  
> +/**
> + * dw_pcie_ep_init_notify - Notify EPF drivers about EPC initialization
> + *   complete
> + * @ep: DWC EP device
> + */
>  void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep)
>  {
>   struct pci_epc *epc = ep->epc;
> @@ -22,6 +27,14 @@ void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep)
>  }
>  EXPORT_SYMBOL_GPL(dw_pcie_ep_init_notify);
>  
> +/**
> + * dw_pcie_ep_get_func_from_ep - Get the struct dw_pcie_ep_func 
> corresponding to
> + *the endpoint function
> + * @ep: DWC EP device
> + * @func_no: Function number of the endpoint device
> + *
> + * Return: struct dw_pcie_ep_func if success, NULL otherwise.
> + */
>  struct dw_pcie_ep_func *
>  dw_pcie_ep_get_func_from_ep(struct dw_pcie_ep *ep, u8 func_no)
>  {
> @@ -52,6 +65,11 @@ static void __dw_pcie_ep_reset_bar(struct dw_pcie *pci, u8 
> func_no,
>   dw_pcie_dbi_ro_wr_dis(pci);
>  }
>  
> +/**
> + * dw_pcie_ep_reset_bar - Reset endpoint BAR
> + * @pci: DWC PCI device
> + * @bar: BAR number of the endpoint
> + */
>  void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
>  {
>   u8 func_no, funcs;
> @@ -431,6 +449,13 @@ static const struct pci_epc_ops epc_ops = {
>   .get_features   = dw_pcie_ep_get_features,
>  };
>  
> +/**
> + * dw_pcie_ep_raise_intx_irq - Raise INTx IRQ to the host
> + * @ep: DWC EP device
> + * @func_no: Function number of the endpoint
> + *
> + * Return: 0 if success, errono otherwise.
> + */
>  int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no)
>  {
>   struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> @@ -442,6 +467,14 @@ int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 
> func_no)
>  }
>  EXPORT_SYMBOL_GPL(dw_pcie_ep_raise_intx_irq);
>  
> +/**
> + * dw_pcie_ep_raise_msi_irq - Raise MSI IRQ to the host
> + * @ep: DWC EP device
> + * @func_no: Function number of the endpoint
> + * @interrupt_num: Interrupt number to be raised
> + *
> + * Return: 0 if success, errono otherwise.
> + */
>  int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
>u8 interrupt_num)
>  {
> @@ -490,6 +523,15 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 
> func_no,
>  }
>  EXPORT_SYMBOL_GPL(dw_pcie_ep_raise_msi_irq);
>  
> +/**
> + * dw_pcie_ep_raise_msix_irq_doorbell - Raise MSIX to the host using Doorbell
> + *   method
> + * @ep: DWC EP device
> + * @func_no: Function number of the endpoint device
> + * @interrupt_num: Interrupt number to be raised
> + *
> + * Return: 0 if success, errno otherwise.
> + */
>  int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep, u8 func_no,
>  u16 interrupt_num)
>  {
> @@ -509,6 +551,14 @@ int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep 
> *ep, u8 func_no,
>   return 0;
>  }
>  
> +/**
> + * dw_pcie_ep_raise_msix_irq - Raise MSIX to the host
> + * @ep: DWC EP device
> + * @func_no: Function number of the endpoint device
> + * @interrupt_num: Interrupt number to be raised
> + *
> + * Return: 0 if success, errno otherwise.
> + */
>  int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
> u16 interrupt_num)
>  {
> @@ -556,6 +606,12 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 
> func_no,
>   return 0;
>  }
>  
> +/**
> + * dw_pcie_ep_cleanup - Cleanup DWC EP resources
> + * @ep: DWC EP device
> + *
> + * Cleans up the DWC EP specific resources like eDMA etc...
> + */
>  void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep)
>  {
>   struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> @@ -564,6 +620,13 @@ void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep)
>  }
>  EXPORT_SYMBOL_GPL(dw_pcie_ep_cleanup);
>  
> +/**
> + * dw_pcie_ep_deinit - Deinitialize the endpoint device
> + * @ep: DWC EP device
> + *
> + * Deinitialize the endpoint device. EPC device is not destroyed since that 
> will
> + * taken care by Devres.
> + */
>  void dw_pcie_ep_deinit(struct dw_pcie_ep *ep)
>  {
>   struct pci_epc *epc = ep->epc;
> @@ -635,6 +698,14 @@ static void dw_pcie_ep_init_non_sticky_registers(struct 
> dw_pcie *pci)
>   dw_pcie_dbi_ro_wr_dis(pci);
>  }
>  
> +/**
> + * dw_pcie_ep_init_registers - Initialize DWC EP specific registers
> + * @ep: DWC EP device
> + *
> + * Initialize the 

Re: [PATCH v8 09/10] PCI: qcom-ep: Use the generic dw_pcie_ep_linkdown() API to handle LINK_DOWN event

2024-02-26 Thread Frank Li
On Sat, Feb 24, 2024 at 12:24:15PM +0530, Manivannan Sadhasivam wrote:
> Now that the API is available, let's make use of it. It also handles the
> reinitialization of DWC non-sticky registers in addition to sending the
> notification to EPF drivers.
> 
> Signed-off-by: Manivannan Sadhasivam 
> ---
>  drivers/pci/controller/dwc/pcie-qcom-ep.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c 
> b/drivers/pci/controller/dwc/pcie-qcom-ep.c
> index 2fb8c15e7a91..4e45bc4bca45 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
> @@ -640,7 +640,7 @@ static irqreturn_t qcom_pcie_ep_global_irq_thread(int 
> irq, void *data)
>   if (FIELD_GET(PARF_INT_ALL_LINK_DOWN, status)) {
>   dev_dbg(dev, "Received Linkdown event\n");
>   pcie_ep->link_status = QCOM_PCIE_EP_LINK_DOWN;
> - pci_epc_linkdown(pci->ep.epc);
> + dw_pcie_ep_linkdown(>ep);

Suppose pci_epc_linkdown() will call dw_pcie_ep_linkdown() ?
why need direct call dw_pcie_ep_linkdown() here?

Frank

>   } else if (FIELD_GET(PARF_INT_ALL_BME, status)) {
>   dev_dbg(dev, "Received BME event. Link is enabled!\n");
>   pcie_ep->link_status = QCOM_PCIE_EP_LINK_ENABLED;
> 
> -- 
> 2.25.1
> 


Re: Kernel WARNING at lib/vsprintf.c:2721 while running ftrace kernel selftests

2024-02-26 Thread Steven Rostedt
On Sun, 25 Feb 2024 22:01:50 +0530
Sachin Sant  wrote:

> While running ftrace specific kernel selftests following warning
> is seen on a Power10 logical partition (LPAR) booted with
> latest mainline kernel.
> 
> [ cut here ]
> precision 63492 too large
> WARNING: CPU: 15 PID: 2538829 at lib/vsprintf.c:2721 set_precision+0x68/0xa4

Interesting. I'm guessing something went negative.

> Modules linked in: nvram rpadlpar_io rpaphp uinput torture vmac 
> poly1305_generic chacha_generic chacha20poly1305 n_gsm pps_ldisc ppp_synctty 
> ppp_async ppp_generic serport slcan can_dev slip slhc snd_hrtimer snd_seq 
> snd_seq_device snd_timer snd soundcore pcrypt crypto_user n_hdlc dummy veth 
> tun nfsv3 nfs netfs brd overlay exfat vfat fat btrfs blake2b_generic xor 
> raid6_pq zstd_compress xfs loop sctp ip6_udp_tunnel udp_tunnel nfsd 
> auth_rpcgss nfs_acl lockd grace configs dm_mod nft_fib_inet nft_fib_ipv4 
> nft_fib_ipv6 nft_fib nft_reject_inet nf_reject_ipv4 nf_reject_ipv6 nft_reject 
> nft_ct nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 
> bonding rfkill tls ip_set nf_tables libcrc32c nfnetlink sunrpc pseries_rng 
> vmx_crypto ext4 mbcache jbd2 sd_mod t10_pi crc64_rocksoft crc64 sg ibmvscsi 
> ibmveth scsi_transport_srp fuse [last unloaded: test_cpuidle_latency(O)]
> CPU: 15 PID: 2538829 Comm: awk Tainted: G M O K 6.8.0-rc5-gfca7526b7d89 #1
> Hardware name: IBM,9080-HEX POWER10 (raw) 0x800200 0xf06 of:IBM,FW1060.00 
> (NH1060_018) hv:phyp pSeries
> NIP: c0f57c34 LR: c0f57c30 CTR: c0f5cdf0
> REGS: c00a58e4f5f0 TRAP: 0700 Tainted: G M O K (6.8.0-rc5-gfca7526b7d89)
> MSR: 82029033  CR: 48000824 XER: 0005
> CFAR: c016154c IRQMASK: 0 
> GPR00: c0f57c30 c00a58e4f890 c1482800 0019 
> GPR04: 000100011559 c00a58e4f660 c00a58e4f658 0027 
> GPR08: c00e84e37c10 0001 0027 c2a47e50 
> GPR12:  c00e87bf7300   
> GPR16:     
> GPR20: c004a43ec590 00400cc0 0003 c12c3e65 
> GPR24: c00a58e4fa18 0025 0020 0001ff97 
> GPR28: c001168a00dd c001168c0074 c00a58e4f920 f804 
> NIP [c0f57c34] set_precision+0x68/0xa4
> LR [c0f57c30] set_precision+0x64/0xa4
> Call Trace:
> [c00a58e4f890] [c0f57c30] set_precision+0x64/0xa4 (unreliable)
> [c00a58e4f900] [c0f5ccc4] vsnprintf+0x198/0x4c8
> [c00a58e4f980] [c0f53228] seq_buf_vprintf+0x50/0xa0
> [c00a58e4f9b0] [c031cec0] trace_seq_printf+0x60/0xe0
> [c00a58e4f9e0] [c031b5f0] trace_print_print+0x78/0xa4
> [c00a58e4fa60] [c03133a4] print_trace_line+0x2ac/0x6d8
> [c00a58e4fb20] [c03145c0] s_show+0x58/0x2c0
> [c00a58e4fba0] [c05dfb2c] seq_read_iter+0x448/0x618
> [c00a58e4fc70] [c05dfe08] seq_read+0x10c/0x174
> [c00a58e4fd10] [c059a7e0] vfs_read+0xe0/0x39c
> [c00a58e4fdc0] [c059b59c] ksys_read+0x7c/0x140
> [c00a58e4fe10] [c0035d74] system_call_exception+0x134/0x330
> [c00a58e4fe50] [c000d6a0] system_call_common+0x160/0x2e4
> --- interrupt: c00 at 0x7fff84521684
> NIP: 7fff84521684 LR: 0001252f0dc4 CTR: 
> REGS: c00a58e4fe80 TRAP: 0c00 Tainted: G M O K (6.8.0-rc5-gfca7526b7d89)
> MSR: 8000f033  CR: 22000202 XER: 
> IRQMASK: 0 
> GPR00: 0003 7fffcd076c30 7fff84607300 0005 
> GPR04: 00012a8a1a20 0001 fff5 00012a9bcce6 
> GPR08: 0001    
> GPR12:  7fff84a5d2a0 0001 00012a8851d8 
> GPR16: 00012a884268 7fff84601888 000125377f50 7fff84601880 
> GPR20: 0044 000f   
> GPR24: 7fffcd076e48 7fffcd076d98   
> GPR28: 7fffcd076e48  7fffcd076da0 00012a8a1900 
> NIP [7fff84521684] 0x7fff84521684
> LR [0001252f0dc4] 0x1252f0dc4
> --- interrupt: c00
> Code: f821ff91 2f89 409e0034 7c0802a6 3c62fff0 3921 3d420177 3863e310 
> 992ad6db f8010080 4b209899 6000 <0fe0> e8010080 7c0803a6 2f9f 
> ---[ end trace  ]—
> 
> This warning is seen while running test that was added by
> following commit:
> 
> commit 3bf7009251f0f41cdd0188ab7b3879df81810703
>  tracing/selftests: Add test to test the trace_marker

This adds the user space selftest that triggered this warning, but it is
not the cause of it. Could you run this test against kernel builds before
this commit. Does this test cause this to trigger on older versions of the
kernel?

-- Steve


Re: [PATCH v8 08/10] PCI: dwc: ep: Add a generic dw_pcie_ep_linkdown() API to handle LINK_DOWN event

2024-02-26 Thread Frank Li
On Sat, Feb 24, 2024 at 12:24:14PM +0530, Manivannan Sadhasivam wrote:
> The PCIe link can go to LINK_DOWN state in one of the following scenarios:
> 
> 1. Fundamental (PERST#)/hot/warm reset
> 2. Link transition from L2/L3 to L0

>From L0 to L2/l3

> 
> In those cases, LINK_DOWN causes some non-sticky DWC registers to loose the
> state (like REBAR, PTM_CAP etc...). So the drivers need to reinitialize
> them to function properly once the link comes back again.
> 
> This is not a problem for drivers supporting PERST# IRQ, since they can
> reinitialize the registers in the PERST# IRQ callback. But for the drivers
> not supporting PERST#, there is no way they can reinitialize the registers
> other than relying on LINK_DOWN IRQ received when the link goes down. So
> let's add a DWC generic API dw_pcie_ep_linkdown() that reinitializes the
> non-sticky registers and also notifies the EPF drivers about link going
> down.
> 
> This API can also be used by the drivers supporting PERST# to handle the
> scenario (2) mentioned above.
> 
> Signed-off-by: Manivannan Sadhasivam 
> ---
>  drivers/pci/controller/dwc/pcie-designware-ep.c | 111 
> ++--
>  drivers/pci/controller/dwc/pcie-designware.h|   5 ++
>  2 files changed, 72 insertions(+), 44 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c 
> b/drivers/pci/controller/dwc/pcie-designware-ep.c
> index 278bdc9b2269..fed4c2936c78 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> @@ -14,14 +14,6 @@
>  #include 
>  #include 
>  
> -void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
> -{
> - struct pci_epc *epc = ep->epc;
> -
> - pci_epc_linkup(epc);
> -}
> -EXPORT_SYMBOL_GPL(dw_pcie_ep_linkup);
> -

No sure why git remove this block and add these back.


>  void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep)
>  {
>   struct pci_epc *epc = ep->epc;
> @@ -603,19 +595,56 @@ static unsigned int 
> dw_pcie_ep_find_ext_capability(struct dw_pcie *pci, int cap)
>   return 0;
>  }
>  
> +static void dw_pcie_ep_init_non_sticky_registers(struct dw_pcie *pci)
> +{
> + unsigned int offset, ptm_cap_base;
> + unsigned int nbars;
> + u32 reg, i;
> +
> + offset = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_REBAR);
> + ptm_cap_base = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_PTM);
> +
> + dw_pcie_dbi_ro_wr_en(pci);
> +
> + if (offset) {
> + reg = dw_pcie_readl_dbi(pci, offset + PCI_REBAR_CTRL);
> + nbars = (reg & PCI_REBAR_CTRL_NBAR_MASK) >>
> + PCI_REBAR_CTRL_NBAR_SHIFT;
> +
> + for (i = 0; i < nbars; i++, offset += PCI_REBAR_CTRL)
> + dw_pcie_writel_dbi(pci, offset + PCI_REBAR_CAP, 0x0);
> + }
> +
> + /*
> +  * PTM responder capability can be disabled only after disabling
> +  * PTM root capability.
> +  */
> + if (ptm_cap_base) {
> + dw_pcie_dbi_ro_wr_en(pci);
> + reg = dw_pcie_readl_dbi(pci, ptm_cap_base + PCI_PTM_CAP);
> + reg &= ~PCI_PTM_CAP_ROOT;
> + dw_pcie_writel_dbi(pci, ptm_cap_base + PCI_PTM_CAP, reg);
> +
> + reg = dw_pcie_readl_dbi(pci, ptm_cap_base + PCI_PTM_CAP);
> + reg &= ~(PCI_PTM_CAP_RES | PCI_PTM_GRANULARITY_MASK);
> + dw_pcie_writel_dbi(pci, ptm_cap_base + PCI_PTM_CAP, reg);
> + dw_pcie_dbi_ro_wr_dis(pci);
> + }
> +
> + dw_pcie_setup(pci);
> + dw_pcie_dbi_ro_wr_dis(pci);
> +}
> +
>  int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
>  {
>   struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
>   struct dw_pcie_ep_func *ep_func;
>   struct device *dev = pci->dev;
>   struct pci_epc *epc = ep->epc;
> - unsigned int offset, ptm_cap_base;
> - unsigned int nbars;
>   u8 hdr_type;
>   u8 func_no;
> - int i, ret;
>   void *addr;
> - u32 reg;
> + int ret;
>  
>   hdr_type = dw_pcie_readb_dbi(pci, PCI_HEADER_TYPE) &
>  PCI_HEADER_TYPE_MASK;
> @@ -678,38 +707,7 @@ int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
>   if (ep->ops->init)
>   ep->ops->init(ep);
>  
> - offset = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_REBAR);
> - ptm_cap_base = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_PTM);
> -
> - dw_pcie_dbi_ro_wr_en(pci);
> -
> - if (offset) {
> - reg = dw_pcie_readl_dbi(pci, offset + PCI_REBAR_CTRL);
> - nbars = (reg & PCI_REBAR_CTRL_NBAR_MASK) >>
> - PCI_REBAR_CTRL_NBAR_SHIFT;
> -
> - for (i = 0; i < nbars; i++, offset += PCI_REBAR_CTRL)
> - dw_pcie_writel_dbi(pci, offset + PCI_REBAR_CAP, 0x0);
> - }
> -
> - /*
> -  * PTM responder capability can be disabled only after disabling
> -  * PTM root capability.
> -  */
> - if (ptm_cap_base) {
> - dw_pcie_dbi_ro_wr_en(pci);
> 

Re: [PATCH v8 07/10] PCI: dwc: ep: Remove "core_init_notifier" flag

2024-02-26 Thread Frank Li
On Sat, Feb 24, 2024 at 12:24:13PM +0530, Manivannan Sadhasivam wrote:
> "core_init_notifier" flag is set by the glue drivers requiring refclk from
> the host to complete the DWC core initialization. Also, those drivers will
> send a notification to the EPF drivers once the initialization is fully
> completed using the pci_epc_init_notify() API. Only then, the EPF drivers
> will start functioning.
> 
> For the rest of the drivers generating refclk locally, EPF drivers will
> start functioning post binding with them. EPF drivers rely on the
> 'core_init_notifier' flag to differentiate between the drivers.
> Unfortunately, this creates two different flows for the EPF drivers.
> 
> So to avoid that, let's get rid of the "core_init_notifier" flag and follow
> a single initialization flow for the EPF drivers. This is done by calling
> the dw_pcie_ep_init_notify() from all glue drivers after the completion of
> dw_pcie_ep_init_registers() API. This will allow all the glue drivers to
> send the notification to the EPF drivers once the initialization is fully
> completed.
> 
> Only difference here is that, the drivers requiring refclk from host will
> send the notification once refclk is received, while others will send it
> during probe time itself.
> 
> Signed-off-by: Manivannan Sadhasivam 

Reviewed-by: Frank Li 

> ---
>  drivers/pci/controller/dwc/pci-dra7xx.c   |  2 ++
>  drivers/pci/controller/dwc/pci-imx6.c |  2 ++
>  drivers/pci/controller/dwc/pci-keystone.c |  2 ++
>  drivers/pci/controller/dwc/pci-layerscape-ep.c|  2 ++
>  drivers/pci/controller/dwc/pcie-designware-plat.c |  2 ++
>  drivers/pci/controller/dwc/pcie-qcom-ep.c |  1 -
>  drivers/pci/controller/dwc/pcie-rcar-gen4.c   |  2 ++
>  drivers/pci/controller/dwc/pcie-tegra194.c|  1 -
>  drivers/pci/controller/dwc/pcie-uniphier-ep.c |  2 ++
>  drivers/pci/endpoint/functions/pci-epf-test.c | 18 +-
>  include/linux/pci-epc.h   |  3 ---
>  11 files changed, 19 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c 
> b/drivers/pci/controller/dwc/pci-dra7xx.c
> index 395042b29ffc..d2d17d37d3e0 100644
> --- a/drivers/pci/controller/dwc/pci-dra7xx.c
> +++ b/drivers/pci/controller/dwc/pci-dra7xx.c
> @@ -474,6 +474,8 @@ static int dra7xx_add_pcie_ep(struct dra7xx_pcie *dra7xx,
>   return ret;
>   }
>  
> + dw_pcie_ep_init_notify(ep);
> +
>   return 0;
>  }
>  
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c 
> b/drivers/pci/controller/dwc/pci-imx6.c
> index bfcafa440ddb..894b5de76e3a 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -1144,6 +1144,8 @@ static int imx6_add_pcie_ep(struct imx6_pcie *imx6_pcie,
>   return ret;
>   }
>  
> + dw_pcie_ep_init_notify(ep);
> +
>   /* Start LTSSM. */
>   imx6_pcie_ltssm_enable(dev);
>  
> diff --git a/drivers/pci/controller/dwc/pci-keystone.c 
> b/drivers/pci/controller/dwc/pci-keystone.c
> index 8392894ed286..1d00c5fa14ce 100644
> --- a/drivers/pci/controller/dwc/pci-keystone.c
> +++ b/drivers/pci/controller/dwc/pci-keystone.c
> @@ -1293,6 +1293,8 @@ static int ks_pcie_probe(struct platform_device *pdev)
>   goto err_ep_init;
>   }
>  
> + dw_pcie_ep_init_notify(>ep);
> +
>   break;
>   default:
>   dev_err(dev, "INVALID device type %d\n", mode);
> diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c 
> b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> index b712fdd06549..c513598a46d7 100644
> --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> @@ -283,6 +283,8 @@ static int __init ls_pcie_ep_probe(struct platform_device 
> *pdev)
>   return ret;
>   }
>  
> + dw_pcie_ep_init_notify(>ep);
> +
>   return ls_pcie_ep_interrupt_init(pcie, pdev);
>  }
>  
> diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c 
> b/drivers/pci/controller/dwc/pcie-designware-plat.c
> index ca9b22e654cd..8490c5d6ff9f 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-plat.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-plat.c
> @@ -154,6 +154,8 @@ static int dw_plat_pcie_probe(struct platform_device 
> *pdev)
>   dw_pcie_ep_deinit(>ep);
>   }
>  
> + dw_pcie_ep_init_notify(>ep);
> +
>   break;
>   default:
>   dev_err(dev, "INVALID device type %d\n", dw_plat_pcie->mode);
> diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c 
> b/drivers/pci/controller/dwc/pcie-qcom-ep.c
> index 3697b4a944cc..2fb8c15e7a91 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
> @@ -775,7 +775,6 @@ static void qcom_pcie_ep_init_debugfs(struct qcom_pcie_ep 
> *pcie_ep)
>  
>  static const struct pci_epc_features 

Re: [PATCH v8 06/10] PCI: dwc: ep: Call dw_pcie_ep_init_registers() API directly from all glue drivers

2024-02-26 Thread Frank Li
On Sat, Feb 24, 2024 at 12:24:12PM +0530, Manivannan Sadhasivam wrote:
> Currently, dw_pcie_ep_init_registers() API is directly called by the glue
> drivers requiring active refclk from host. But for the other drivers, it is
> getting called implicitly by dw_pcie_ep_init(). This is due to the fact
> that this API initializes DWC EP specific registers and that requires an
> active refclk (either from host or generated locally by endpoint itsef).
> 
> But, this causes a discrepancy among the glue drivers. So to avoid this
> confusion, let's call this API directly from all glue drivers irrespective
> of refclk dependency. Only difference here is that the drivers requiring
> refclk from host will call this API only after the refclk is received and
> other drivers without refclk dependency will call this API right after
> dw_pcie_ep_init().
> 
> This change will also allow us to remove the "core_init_notifier" flag in
> the later commits.
> 
> Signed-off-by: Manivannan Sadhasivam 
> ---
>  drivers/pci/controller/dwc/pci-dra7xx.c   |  7 +++
>  drivers/pci/controller/dwc/pci-imx6.c |  8 
>  drivers/pci/controller/dwc/pci-keystone.c |  9 +
>  drivers/pci/controller/dwc/pci-layerscape-ep.c|  7 +++
>  drivers/pci/controller/dwc/pcie-designware-ep.c   | 22 --
>  drivers/pci/controller/dwc/pcie-designware-plat.c |  9 +
>  drivers/pci/controller/dwc/pcie-rcar-gen4.c   | 12 +++-
>  drivers/pci/controller/dwc/pcie-uniphier-ep.c | 13 -
>  8 files changed, 63 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c 
> b/drivers/pci/controller/dwc/pci-dra7xx.c
> index 0e406677060d..395042b29ffc 100644
> --- a/drivers/pci/controller/dwc/pci-dra7xx.c
> +++ b/drivers/pci/controller/dwc/pci-dra7xx.c
> @@ -467,6 +467,13 @@ static int dra7xx_add_pcie_ep(struct dra7xx_pcie *dra7xx,
>   return ret;
>   }
>  
> + ret = dw_pcie_ep_init_registers(ep);
> + if (ret) {
> + dev_err(dev, "Failed to initialize DWC endpoint registers\n");
> + dw_pcie_ep_deinit(ep);
> + return ret;
> + }
> +
>   return 0;
>  }
>  
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c 
> b/drivers/pci/controller/dwc/pci-imx6.c
> index dc2c036ab28c..bfcafa440ddb 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -1136,6 +1136,14 @@ static int imx6_add_pcie_ep(struct imx6_pcie 
> *imx6_pcie,
>   dev_err(dev, "failed to initialize endpoint\n");
>   return ret;
>   }
> +
> + ret = dw_pcie_ep_init_registers(ep);
> + if (ret) {
> + dev_err(dev, "Failed to initialize DWC endpoint registers\n");
> + dw_pcie_ep_deinit(ep);
> + return ret;
> + }
> +
>   /* Start LTSSM. */
>   imx6_pcie_ltssm_enable(dev);
>  
> diff --git a/drivers/pci/controller/dwc/pci-keystone.c 
> b/drivers/pci/controller/dwc/pci-keystone.c
> index c0c62533a3f1..8392894ed286 100644
> --- a/drivers/pci/controller/dwc/pci-keystone.c
> +++ b/drivers/pci/controller/dwc/pci-keystone.c
> @@ -1286,6 +1286,13 @@ static int ks_pcie_probe(struct platform_device *pdev)
>   ret = dw_pcie_ep_init(>ep);
>   if (ret < 0)
>   goto err_get_sync;
> +
> + ret = dw_pcie_ep_init_registers(>ep);
> + if (ret < 0) {
> + dev_err(dev, "Failed to initialize DWC endpoint 
> registers\n");
> + goto err_ep_init;
> + }
> +
>   break;
>   default:
>   dev_err(dev, "INVALID device type %d\n", mode);
> @@ -1295,6 +1302,8 @@ static int ks_pcie_probe(struct platform_device *pdev)
>  
>   return 0;
>  
> +err_ep_init:
> + dw_pcie_ep_deinit(>ep);
>  err_get_sync:
>   pm_runtime_put(dev);
>   pm_runtime_disable(dev);
> diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c 
> b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> index 2e398494e7c0..b712fdd06549 100644
> --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> @@ -276,6 +276,13 @@ static int __init ls_pcie_ep_probe(struct 
> platform_device *pdev)
>   if (ret)
>   return ret;
>  
> + ret = dw_pcie_ep_init_registers(>ep);
> + if (ret) {
> + dev_err(dev, "Failed to initialize DWC endpoint registers\n");
> + dw_pcie_ep_deinit(>ep);
> + return ret;
> + }
> +
>   return ls_pcie_ep_interrupt_init(pcie, pdev);
>  }
>  
> diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c 
> b/drivers/pci/controller/dwc/pcie-designware-ep.c
> index ed1f2afd830a..278bdc9b2269 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> @@ -729,7 +729,6 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
>   

Re: [PATCH v8 05/10] PCI: dwc: ep: Rename dw_pcie_ep_init_complete() to dw_pcie_ep_init_registers()

2024-02-26 Thread Frank Li
On Sat, Feb 24, 2024 at 12:24:11PM +0530, Manivannan Sadhasivam wrote:
> The goal of the dw_pcie_ep_init_complete() API is to initialize the DWC
> specific registers post registering the controller with the EP framework.
> 
> But the naming doesn't reflect its functionality and causes confusion. So,
> let's rename it to dw_pcie_ep_init_registers() to make it clear that it
> initializes the DWC specific registers.
> 
> Signed-off-by: Manivannan Sadhasivam 

Reviewed-by: Frank Li 

> ---
>  drivers/pci/controller/dwc/pcie-designware-ep.c | 6 +++---
>  drivers/pci/controller/dwc/pcie-designware.h| 4 ++--
>  drivers/pci/controller/dwc/pcie-qcom-ep.c   | 2 +-
>  drivers/pci/controller/dwc/pcie-tegra194.c  | 2 +-
>  4 files changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c 
> b/drivers/pci/controller/dwc/pcie-designware-ep.c
> index 99d66b0fa59b..ed1f2afd830a 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> @@ -603,7 +603,7 @@ static unsigned int dw_pcie_ep_find_ext_capability(struct 
> dw_pcie *pci, int cap)
>   return 0;
>  }
>  
> -int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep)
> +int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
>  {
>   struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
>   struct dw_pcie_ep_func *ep_func;
> @@ -718,7 +718,7 @@ int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep)
>  
>   return ret;
>  }
> -EXPORT_SYMBOL_GPL(dw_pcie_ep_init_complete);
> +EXPORT_SYMBOL_GPL(dw_pcie_ep_init_registers);
>  
>  int dw_pcie_ep_init(struct dw_pcie_ep *ep)
>  {
> @@ -788,7 +788,7 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
>* (Ex: tegra194). Any hardware access on such platforms result
>* in system hang.
>*/
> - ret = dw_pcie_ep_init_complete(ep);
> + ret = dw_pcie_ep_init_registers(ep);
>   if (ret)
>   goto err_free_epc_mem;
>  
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h 
> b/drivers/pci/controller/dwc/pcie-designware.h
> index 351d2fe3ea4d..f8e5431a207b 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -669,7 +669,7 @@ static inline void __iomem 
> *dw_pcie_own_conf_map_bus(struct pci_bus *bus,
>  #ifdef CONFIG_PCIE_DW_EP
>  void dw_pcie_ep_linkup(struct dw_pcie_ep *ep);
>  int dw_pcie_ep_init(struct dw_pcie_ep *ep);
> -int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep);
> +int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep);
>  void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep);
>  void dw_pcie_ep_deinit(struct dw_pcie_ep *ep);
>  void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep);
> @@ -693,7 +693,7 @@ static inline int dw_pcie_ep_init(struct dw_pcie_ep *ep)
>   return 0;
>  }
>  
> -static inline int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep)
> +static inline int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
>  {
>   return 0;
>  }
> diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c 
> b/drivers/pci/controller/dwc/pcie-qcom-ep.c
> index 59b1c0110288..3697b4a944cc 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
> @@ -463,7 +463,7 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
> PARF_INT_ALL_LINK_UP | PARF_INT_ALL_EDMA;
>   writel_relaxed(val, pcie_ep->parf + PARF_INT_ALL_MASK);
>  
> - ret = dw_pcie_ep_init_complete(_ep->pci.ep);
> + ret = dw_pcie_ep_init_registers(_ep->pci.ep);
>   if (ret) {
>   dev_err(dev, "Failed to complete initialization: %d\n", ret);
>   goto err_disable_resources;
> diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c 
> b/drivers/pci/controller/dwc/pcie-tegra194.c
> index 68bfeed3429b..264ee76bf008 100644
> --- a/drivers/pci/controller/dwc/pcie-tegra194.c
> +++ b/drivers/pci/controller/dwc/pcie-tegra194.c
> @@ -1897,7 +1897,7 @@ static void pex_ep_event_pex_rst_deassert(struct 
> tegra_pcie_dw *pcie)
>   val = (upper_32_bits(ep->msi_mem_phys) & MSIX_ADDR_MATCH_HIGH_OFF_MASK);
>   dw_pcie_writel_dbi(pci, MSIX_ADDR_MATCH_HIGH_OFF, val);
>  
> - ret = dw_pcie_ep_init_complete(ep);
> + ret = dw_pcie_ep_init_registers(ep);
>   if (ret) {
>   dev_err(dev, "Failed to complete initialization: %d\n", ret);
>   goto fail_init_complete;
> 
> -- 
> 2.25.1
> 


Re: [PATCH v8 04/10] PCI: dwc: ep: Fix DBI access failure for drivers requiring refclk from host

2024-02-26 Thread Frank Li
On Sat, Feb 24, 2024 at 12:24:10PM +0530, Manivannan Sadhasivam wrote:
> The DWC glue drivers requiring an active reference clock from the PCIe host
> for initializing their PCIe EP core, set a flag called 'core_init_notifier'
> to let DWC driver know that these drivers need a special attention during
> initialization. In these drivers, access to the hw registers (like DBI)
> before receiving the active refclk from host will result in access failure
> and also could cause a whole system hang.
> 
> But the current DWC EP driver doesn't honor the requirements of the drivers
> setting 'core_init_notifier' flag and tries to access the DBI registers
> during dw_pcie_ep_init(). This causes the system hang for glue drivers such
> as Tegra194 and Qcom EP as they depend on refclk from host and have set the
> above mentioned flag.
> 
> To workaround this issue, users of the affected platforms have to maintain
> the dependency with the PCIe host by booting the PCIe EP after host boot.
> But this won't provide a good user experience, since PCIe EP is _one_ of
> the features of those platforms and it doesn't make sense to delay the
> whole platform booting due to PCIe requiring active refclk.
> 
> So to fix this issue, let's move all the DBI access from
> dw_pcie_ep_init() in the DWC EP driver to the dw_pcie_ep_init_complete()
> API. This API will only be called by the drivers setting
> 'core_init_notifier' flag once refclk is received from host. For the rest
> of the drivers that gets the refclk locally, this API will be called
> within dw_pcie_ep_init().
> 
> Fixes: e966f7390da9 ("PCI: dwc: Refactor core initialization code for EP 
> mode")
> Co-developed-by: Vidya Sagar 
> Signed-off-by: Vidya Sagar 
> Signed-off-by: Manivannan Sadhasivam 

Reviewed-by: Frank Li 

> ---
>  drivers/pci/controller/dwc/pcie-designware-ep.c | 120 
> ++--
>  1 file changed, 71 insertions(+), 49 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c 
> b/drivers/pci/controller/dwc/pcie-designware-ep.c
> index 1205bfba8310..99d66b0fa59b 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> @@ -606,11 +606,16 @@ static unsigned int 
> dw_pcie_ep_find_ext_capability(struct dw_pcie *pci, int cap)
>  int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep)
>  {
>   struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> + struct dw_pcie_ep_func *ep_func;
> + struct device *dev = pci->dev;
> + struct pci_epc *epc = ep->epc;
>   unsigned int offset, ptm_cap_base;
>   unsigned int nbars;
>   u8 hdr_type;
> + u8 func_no;
> + int i, ret;
> + void *addr;
>   u32 reg;
> - int i;
>  
>   hdr_type = dw_pcie_readb_dbi(pci, PCI_HEADER_TYPE) &
>  PCI_HEADER_TYPE_MASK;
> @@ -621,6 +626,58 @@ int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep)
>   return -EIO;
>   }
>  
> + dw_pcie_version_detect(pci);
> +
> + dw_pcie_iatu_detect(pci);
> +
> + ret = dw_pcie_edma_detect(pci);
> + if (ret)
> + return ret;
> +
> + if (!ep->ib_window_map) {
> + ep->ib_window_map = devm_bitmap_zalloc(dev, pci->num_ib_windows,
> +GFP_KERNEL);
> + if (!ep->ib_window_map)
> + goto err_remove_edma;
> + }
> +
> + if (!ep->ob_window_map) {
> + ep->ob_window_map = devm_bitmap_zalloc(dev, pci->num_ob_windows,
> +GFP_KERNEL);
> + if (!ep->ob_window_map)
> + goto err_remove_edma;
> + }
> +
> + if (!ep->outbound_addr) {
> + addr = devm_kcalloc(dev, pci->num_ob_windows, 
> sizeof(phys_addr_t),
> + GFP_KERNEL);
> + if (!addr)
> + goto err_remove_edma;
> + ep->outbound_addr = addr;
> + }
> +
> + for (func_no = 0; func_no < epc->max_functions; func_no++) {
> +
> + ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
> + if (ep_func)
> + continue;
> +
> + ep_func = devm_kzalloc(dev, sizeof(*ep_func), GFP_KERNEL);
> + if (!ep_func)
> + goto err_remove_edma;
> +
> + ep_func->func_no = func_no;
> + ep_func->msi_cap = dw_pcie_ep_find_capability(ep, func_no,
> +   PCI_CAP_ID_MSI);
> + ep_func->msix_cap = dw_pcie_ep_find_capability(ep, func_no,
> +PCI_CAP_ID_MSIX);
> +
> + list_add_tail(_func->list, >func_list);
> + }
> +
> + if (ep->ops->init)
> + ep->ops->init(ep);
> +
>   offset = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_REBAR);
>   ptm_cap_base = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_PTM);
> 

Re: [PATCH 1/4] arch: consolidate existing CONFIG_PAGE_SIZE_*KB definitions

2024-02-26 Thread Samuel Holland
On 2024-02-26 10:14 AM, Arnd Bergmann wrote:
> From: Arnd Bergmann 
> 
> These four architectures define the same Kconfig symbols for configuring
> the page size. Move the logic into a common place where it can be shared
> with all other architectures.
> 
> Signed-off-by: Arnd Bergmann 
> ---
>  arch/Kconfig  | 58 +--
>  arch/hexagon/Kconfig  | 25 +++--
>  arch/hexagon/include/asm/page.h   |  6 +---
>  arch/loongarch/Kconfig| 21 ---
>  arch/loongarch/include/asm/page.h | 10 +-
>  arch/mips/Kconfig | 58 +++
>  arch/mips/include/asm/page.h  | 16 +
>  arch/sh/include/asm/page.h| 13 +--
>  arch/sh/mm/Kconfig| 42 +++---
>  9 files changed, 88 insertions(+), 161 deletions(-)
> 
> diff --git a/arch/Kconfig b/arch/Kconfig
> index a5af0edd3eb8..237cea01ed9b 100644
> --- a/arch/Kconfig
> +++ b/arch/Kconfig
> @@ -1078,17 +1078,71 @@ config HAVE_ARCH_COMPAT_MMAP_BASES
> and vice-versa 32-bit applications to call 64-bit mmap().
> Required for applications doing different bitness syscalls.
>  
> +config HAVE_PAGE_SIZE_4KB
> + bool
> +
> +config HAVE_PAGE_SIZE_8KB
> + bool
> +
> +config HAVE_PAGE_SIZE_16KB
> + bool
> +
> +config HAVE_PAGE_SIZE_32KB
> + bool
> +
> +config HAVE_PAGE_SIZE_64KB
> + bool
> +
> +config HAVE_PAGE_SIZE_256KB
> + bool
> +
> +choice
> + prompt "MMU page size"

Should this have some generic help text (at least a warning about 
compatibility)?

> +
> +config PAGE_SIZE_4KB
> + bool "4KB pages"
> + depends on HAVE_PAGE_SIZE_4KB
> +
> +config PAGE_SIZE_8KB
> + bool "8KB pages"
> + depends on HAVE_PAGE_SIZE_8KB
> +
> +config PAGE_SIZE_16KB
> + bool "16KB pages"
> + depends on HAVE_PAGE_SIZE_16KB
> +
> +config PAGE_SIZE_32KB
> + bool "32KB pages"
> + depends on HAVE_PAGE_SIZE_32KB
> +
> +config PAGE_SIZE_64KB
> + bool "64KB pages"
> + depends on HAVE_PAGE_SIZE_64KB
> +
> +config PAGE_SIZE_256KB
> + bool "256KB pages"
> + depends on HAVE_PAGE_SIZE_256KB
> +
> +endchoice
> +
>  config PAGE_SIZE_LESS_THAN_64KB
>   def_bool y
> - depends on !ARM64_64K_PAGES
>   depends on !PAGE_SIZE_64KB
> - depends on !PARISC_PAGE_SIZE_64KB
>   depends on PAGE_SIZE_LESS_THAN_256KB
>  
>  config PAGE_SIZE_LESS_THAN_256KB
>   def_bool y
>   depends on !PAGE_SIZE_256KB
>  
> +config PAGE_SHIFT
> + int
> + default 12 if PAGE_SIZE_4KB
> + default 13 if PAGE_SIZE_8KB
> + default 14 if PAGE_SIZE_16KB
> + default 15 if PAGE_SIZE_32KB
> + default 16 if PAGE_SIZE_64KB
> + default 18 if PAGE_SIZE_256KB
> +
>  # This allows to use a set of generic functions to determine mmap base
>  # address by giving priority to top-down scheme only if the process
>  # is not in legacy mode (compat task, unlimited stack size or
> diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig
> index a880ee067d2e..aac46ee1a000 100644
> --- a/arch/hexagon/Kconfig
> +++ b/arch/hexagon/Kconfig
> @@ -8,6 +8,11 @@ config HEXAGON
>   select ARCH_HAS_SYNC_DMA_FOR_DEVICE
>   select ARCH_NO_PREEMPT
>   select DMA_GLOBAL_POOL
> + select FRAME_POINTER

Looks like a paste error.

> + select HAVE_PAGE_SIZE_4KB
> + select HAVE_PAGE_SIZE_16KB
> + select HAVE_PAGE_SIZE_64KB
> + select HAVE_PAGE_SIZE_256KB
>   # Other pending projects/to-do items.
>   # select HAVE_REGS_AND_STACK_ACCESS_API
>   # select HAVE_HW_BREAKPOINT if PERF_EVENTS
> @@ -120,26 +125,6 @@ config NR_CPUS
> This is purely to save memory - each supported CPU adds
> approximately eight kilobytes to the kernel image.
>  
> -choice
> - prompt "Kernel page size"
> - default PAGE_SIZE_4KB
> - help
> -   Changes the default page size; use with caution.
> -
> -config PAGE_SIZE_4KB
> - bool "4KB"
> -
> -config PAGE_SIZE_16KB
> - bool "16KB"
> -
> -config PAGE_SIZE_64KB
> - bool "64KB"
> -
> -config PAGE_SIZE_256KB
> - bool "256KB"
> -
> -endchoice
> -
>  source "kernel/Kconfig.hz"
>  
>  endmenu
> diff --git a/arch/hexagon/include/asm/page.h b/arch/hexagon/include/asm/page.h
> index 10f1bc07423c..65c9bac639fa 100644
> --- a/arch/hexagon/include/asm/page.h
> +++ b/arch/hexagon/include/asm/page.h
> @@ -13,27 +13,22 @@
>  /*  This is probably not the most graceful way to handle this.  */
>  
>  #ifdef CONFIG_PAGE_SIZE_4KB
> -#define PAGE_SHIFT 12
>  #define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_4KB
>  #endif
>  
>  #ifdef CONFIG_PAGE_SIZE_16KB
> -#define PAGE_SHIFT 14
>  #define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_16KB
>  #endif
>  
>  #ifdef CONFIG_PAGE_SIZE_64KB
> -#define PAGE_SHIFT 16
>  #define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_64KB
>  #endif
>  
>  #ifdef CONFIG_PAGE_SIZE_256KB
> -#define PAGE_SHIFT 18
>  #define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_256KB
>  #endif
>  
>  #ifdef CONFIG_PAGE_SIZE_1MB
> 

Re: [PATCH v8 03/10] PCI: dwc: ep: Introduce dw_pcie_ep_cleanup() API for drivers supporting PERST#

2024-02-26 Thread Frank Li
On Sat, Feb 24, 2024 at 12:24:09PM +0530, Manivannan Sadhasivam wrote:
> For DWC glue drivers supporting PERST# (currently Qcom and Tegra194), some
> of the DWC resources like eDMA should be cleaned up during the PERST#
> assert time.
> 
> So let's introduce a dw_pcie_ep_cleanup() API that could be called by these
> drivers to cleanup the DWC specific resources. Currently, it just removes
> eDMA.
> 
> Reported-by: Niklas Cassel 
> Closes: https://lore.kernel.org/linux-pci/ZWYmX8Y%2F7Q9WMxES@x1-carbon
> Signed-off-by: Manivannan Sadhasivam 

Reviewed-by: Frank Li 

> ---
>  drivers/pci/controller/dwc/pcie-designware-ep.c | 11 +--
>  drivers/pci/controller/dwc/pcie-designware.h|  5 +
>  drivers/pci/controller/dwc/pcie-qcom-ep.c   |  1 +
>  drivers/pci/controller/dwc/pcie-tegra194.c  |  2 ++
>  4 files changed, 17 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c 
> b/drivers/pci/controller/dwc/pcie-designware-ep.c
> index 2b11290aab4c..1205bfba8310 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> @@ -564,12 +564,19 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 
> func_no,
>   return 0;
>  }
>  
> -void dw_pcie_ep_deinit(struct dw_pcie_ep *ep)
> +void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep)
>  {
>   struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> - struct pci_epc *epc = ep->epc;
>  
>   dw_pcie_edma_remove(pci);
> +}
> +EXPORT_SYMBOL_GPL(dw_pcie_ep_cleanup);
> +
> +void dw_pcie_ep_deinit(struct dw_pcie_ep *ep)
> +{
> + struct pci_epc *epc = ep->epc;
> +
> + dw_pcie_ep_cleanup(ep);
>  
>   pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem,
> epc->mem->window.page_size);
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h 
> b/drivers/pci/controller/dwc/pcie-designware.h
> index 61465203bb60..351d2fe3ea4d 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -672,6 +672,7 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep);
>  int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep);
>  void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep);
>  void dw_pcie_ep_deinit(struct dw_pcie_ep *ep);
> +void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep);
>  int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no);
>  int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
>u8 interrupt_num);
> @@ -705,6 +706,10 @@ static inline void dw_pcie_ep_deinit(struct dw_pcie_ep 
> *ep)
>  {
>  }
>  
> +static inline void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep)
> +{
> +}
> +
>  static inline int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 
> func_no)
>  {
>   return 0;
> diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c 
> b/drivers/pci/controller/dwc/pcie-qcom-ep.c
> index 36e5e80cd22f..59b1c0110288 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
> @@ -507,6 +507,7 @@ static void qcom_pcie_perst_assert(struct dw_pcie *pci)
>   return;
>   }
>  
> + dw_pcie_ep_cleanup(>ep);
>   qcom_pcie_disable_resources(pcie_ep);
>   pcie_ep->link_status = QCOM_PCIE_EP_LINK_DISABLED;
>  }
> diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c 
> b/drivers/pci/controller/dwc/pcie-tegra194.c
> index 7afa9e9aabe2..68bfeed3429b 100644
> --- a/drivers/pci/controller/dwc/pcie-tegra194.c
> +++ b/drivers/pci/controller/dwc/pcie-tegra194.c
> @@ -1715,6 +1715,8 @@ static void pex_ep_event_pex_rst_assert(struct 
> tegra_pcie_dw *pcie)
>   if (ret)
>   dev_err(pcie->dev, "Failed to go Detect state: %d\n", ret);
>  
> + dw_pcie_ep_cleanup(>pci.ep);
> +
>   reset_control_assert(pcie->core_rst);
>  
>   tegra_pcie_disable_phy(pcie);
> 
> -- 
> 2.25.1
> 


Re: [PATCH v8 02/10] PCI: dwc: ep: Rename dw_pcie_ep_exit() to dw_pcie_ep_deinit()

2024-02-26 Thread Frank Li
On Sat, Feb 24, 2024 at 12:24:08PM +0530, Manivannan Sadhasivam wrote:
> dw_pcie_ep_exit() API is undoing what the dw_pcie_ep_init() API has done
> already (at least partly). But the API name dw_pcie_ep_exit() is not quite
> reflecting that. So let's rename it to dw_pcie_ep_deinit() to make the
> purpose of this API clear. This also aligns with the DWC host driver.
> 
> Signed-off-by: Manivannan Sadhasivam 

Reviewed-by: Frank Li 

> ---
>  drivers/pci/controller/dwc/pcie-designware-ep.c | 4 ++--
>  drivers/pci/controller/dwc/pcie-designware.h| 4 ++--
>  drivers/pci/controller/dwc/pcie-rcar-gen4.c | 2 +-
>  3 files changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c 
> b/drivers/pci/controller/dwc/pcie-designware-ep.c
> index d305f9b4cdfe..2b11290aab4c 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> @@ -564,7 +564,7 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 
> func_no,
>   return 0;
>  }
>  
> -void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
> +void dw_pcie_ep_deinit(struct dw_pcie_ep *ep)
>  {
>   struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
>   struct pci_epc *epc = ep->epc;
> @@ -576,7 +576,7 @@ void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
>  
>   pci_epc_mem_exit(epc);
>  }
> -EXPORT_SYMBOL_GPL(dw_pcie_ep_exit);
> +EXPORT_SYMBOL_GPL(dw_pcie_ep_deinit);
>  
>  static unsigned int dw_pcie_ep_find_ext_capability(struct dw_pcie *pci, int 
> cap)
>  {
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h 
> b/drivers/pci/controller/dwc/pcie-designware.h
> index ab7431a37209..61465203bb60 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -671,7 +671,7 @@ void dw_pcie_ep_linkup(struct dw_pcie_ep *ep);
>  int dw_pcie_ep_init(struct dw_pcie_ep *ep);
>  int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep);
>  void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep);
> -void dw_pcie_ep_exit(struct dw_pcie_ep *ep);
> +void dw_pcie_ep_deinit(struct dw_pcie_ep *ep);
>  int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no);
>  int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
>u8 interrupt_num);
> @@ -701,7 +701,7 @@ static inline void dw_pcie_ep_init_notify(struct 
> dw_pcie_ep *ep)
>  {
>  }
>  
> -static inline void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
> +static inline void dw_pcie_ep_deinit(struct dw_pcie_ep *ep)
>  {
>  }
>  
> diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c 
> b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> index ac97d594ea47..9d9d22e367bb 100644
> --- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> +++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> @@ -430,7 +430,7 @@ static int rcar_gen4_add_dw_pcie_ep(struct rcar_gen4_pcie 
> *rcar)
>  
>  static void rcar_gen4_remove_dw_pcie_ep(struct rcar_gen4_pcie *rcar)
>  {
> - dw_pcie_ep_exit(>dw.ep);
> + dw_pcie_ep_deinit(>dw.ep);
>   rcar_gen4_pcie_ep_deinit(rcar);
>  }
>  
> 
> -- 
> 2.25.1
> 


Re: [PATCH v8 01/10] PCI: dwc: ep: Remove deinit() callback from struct dw_pcie_ep_ops

2024-02-26 Thread Frank Li
On Sat, Feb 24, 2024 at 12:24:07PM +0530, Manivannan Sadhasivam wrote:
> deinit() callback was solely introduced for the pcie-rcar-gen4 driver where
> it is used to do platform specific resource deallocation. And this callback
> is called right at the end of the dw_pcie_ep_exit() API. So it doesn't
> matter whether it is called within or outside of dw_pcie_ep_exit() API.
> 
> So let's remove this callback and directly call rcar_gen4_pcie_ep_deinit()
> in pcie-rcar-gen4 driver to do resource deallocation after the completion
> of dw_pcie_ep_exit() API in rcar_gen4_remove_dw_pcie_ep().
> 
> This simplifies the DWC layer.
> 
> Signed-off-by: Manivannan Sadhasivam 

Reviewed-by: Frank Li 

> ---
>  drivers/pci/controller/dwc/pcie-designware-ep.c |  9 +
>  drivers/pci/controller/dwc/pcie-designware.h|  1 -
>  drivers/pci/controller/dwc/pcie-rcar-gen4.c | 14 --
>  3 files changed, 9 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c 
> b/drivers/pci/controller/dwc/pcie-designware-ep.c
> index 5befed2dc02b..d305f9b4cdfe 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> @@ -575,9 +575,6 @@ void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
> epc->mem->window.page_size);
>  
>   pci_epc_mem_exit(epc);
> -
> - if (ep->ops->deinit)
> - ep->ops->deinit(ep);
>  }
>  EXPORT_SYMBOL_GPL(dw_pcie_ep_exit);
>  
> @@ -738,7 +735,7 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
>  ep->page_size);
>   if (ret < 0) {
>   dev_err(dev, "Failed to initialize address space\n");
> - goto err_ep_deinit;
> + return ret;
>   }
>  
>   ep->msi_mem = pci_epc_mem_alloc_addr(epc, >msi_mem_phys,
> @@ -775,10 +772,6 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
>  err_exit_epc_mem:
>   pci_epc_mem_exit(epc);
>  
> -err_ep_deinit:
> - if (ep->ops->deinit)
> - ep->ops->deinit(ep);
> -
>   return ret;
>  }
>  EXPORT_SYMBOL_GPL(dw_pcie_ep_init);
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h 
> b/drivers/pci/controller/dwc/pcie-designware.h
> index 26dae4837462..ab7431a37209 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -333,7 +333,6 @@ struct dw_pcie_rp {
>  struct dw_pcie_ep_ops {
>   void(*pre_init)(struct dw_pcie_ep *ep);
>   void(*init)(struct dw_pcie_ep *ep);
> - void(*deinit)(struct dw_pcie_ep *ep);
>   int (*raise_irq)(struct dw_pcie_ep *ep, u8 func_no,
>unsigned int type, u16 interrupt_num);
>   const struct pci_epc_features* (*get_features)(struct dw_pcie_ep *ep);
> diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c 
> b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> index e9166619b1f9..ac97d594ea47 100644
> --- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> +++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> @@ -352,11 +352,8 @@ static void rcar_gen4_pcie_ep_init(struct dw_pcie_ep *ep)
>   dw_pcie_ep_reset_bar(pci, bar);
>  }
>  
> -static void rcar_gen4_pcie_ep_deinit(struct dw_pcie_ep *ep)
> +static void rcar_gen4_pcie_ep_deinit(struct rcar_gen4_pcie *rcar)
>  {
> - struct dw_pcie *dw = to_dw_pcie_from_ep(ep);
> - struct rcar_gen4_pcie *rcar = to_rcar_gen4_pcie(dw);
> -
>   writel(0, rcar->base + PCIEDMAINTSTSEN);
>   rcar_gen4_pcie_common_deinit(rcar);
>  }
> @@ -408,7 +405,6 @@ static unsigned int 
> rcar_gen4_pcie_ep_get_dbi2_offset(struct dw_pcie_ep *ep,
>  static const struct dw_pcie_ep_ops pcie_ep_ops = {
>   .pre_init = rcar_gen4_pcie_ep_pre_init,
>   .init = rcar_gen4_pcie_ep_init,
> - .deinit = rcar_gen4_pcie_ep_deinit,
>   .raise_irq = rcar_gen4_pcie_ep_raise_irq,
>   .get_features = rcar_gen4_pcie_ep_get_features,
>   .get_dbi_offset = rcar_gen4_pcie_ep_get_dbi_offset,
> @@ -418,18 +414,24 @@ static const struct dw_pcie_ep_ops pcie_ep_ops = {
>  static int rcar_gen4_add_dw_pcie_ep(struct rcar_gen4_pcie *rcar)
>  {
>   struct dw_pcie_ep *ep = >dw.ep;
> + int ret;
>  
>   if (!IS_ENABLED(CONFIG_PCIE_RCAR_GEN4_EP))
>   return -ENODEV;
>  
>   ep->ops = _ep_ops;
>  
> - return dw_pcie_ep_init(ep);
> + ret = dw_pcie_ep_init(ep);
> + if (ret)
> + rcar_gen4_pcie_ep_deinit(rcar);
> +
> + return ret;
>  }
>  
>  static void rcar_gen4_remove_dw_pcie_ep(struct rcar_gen4_pcie *rcar)
>  {
>   dw_pcie_ep_exit(>dw.ep);
> + rcar_gen4_pcie_ep_deinit(rcar);
>  }
>  
>  /* Common */
> 
> -- 
> 2.25.1
> 


[PATCH 4/4] vdso: avoid including asm/page.h

2024-02-26 Thread Arnd Bergmann
From: Arnd Bergmann 

The recent change to the vdso_data_store broke building compat VDSO
on at least arm64 because it includes headers outside of the include/vdso/
namespace:

In file included from arch/arm64/include/asm/lse.h:5,
 from arch/arm64/include/asm/cmpxchg.h:14,
 from arch/arm64/include/asm/atomic.h:16,
 from include/linux/atomic.h:7,
 from include/asm-generic/bitops/atomic.h:5,
 from arch/arm64/include/asm/bitops.h:25,
 from include/linux/bitops.h:68,
 from arch/arm64/include/asm/memory.h:209,
 from arch/arm64/include/asm/page.h:46,
 from include/vdso/datapage.h:22,
 from lib/vdso/gettimeofday.c:5,
 from :
arch/arm64/include/asm/atomic_ll_sc.h:298:9: error: unknown type name 'u128'
  298 | u128 full;

Use an open-coded page size calculation based on the new CONFIG_PAGE_SHIFT
Kconfig symbol instead.

Reported-by: Linux Kernel Functional Testing 
Fixes: a0d2fcd62ac2 ("vdso/ARM: Make union vdso_data_store available for all 
architectures")
Link: 
https://lore.kernel.org/lkml/ca+g9fytrxxm_ko9fnpz3xarxhv7ud_yqp-teupqrnrhu+_0...@mail.gmail.com/
Signed-off-by: Arnd Bergmann 
---
 include/vdso/datapage.h | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
index 7ba44379a095..2c39a67d7e23 100644
--- a/include/vdso/datapage.h
+++ b/include/vdso/datapage.h
@@ -19,8 +19,6 @@
 #include 
 #include 
 
-#include 
-
 #ifdef CONFIG_ARCH_HAS_VDSO_DATA
 #include 
 #else
@@ -128,7 +126,7 @@ extern struct vdso_data _timens_data[CS_BASES] 
__attribute__((visibility("hidden
  */
 union vdso_data_store {
struct vdso_datadata[CS_BASES];
-   u8  page[PAGE_SIZE];
+   u8  page[1ul << CONFIG_PAGE_SHIFT];
 };
 
 /*
-- 
2.39.2



[PATCH 3/4] arch: define CONFIG_PAGE_SIZE_*KB on all architectures

2024-02-26 Thread Arnd Bergmann
From: Arnd Bergmann 

Most architectures only support a single hardcoded page size. In order
to ensure that each one of these sets the corresponding Kconfig symbols,
change over the PAGE_SHIFT definition to the common one and allow
only the hardware page size to be selected.

Signed-off-by: Arnd Bergmann 
---
 arch/alpha/Kconfig | 1 +
 arch/alpha/include/asm/page.h  | 2 +-
 arch/arm/Kconfig   | 1 +
 arch/arm/include/asm/page.h| 2 +-
 arch/csky/Kconfig  | 1 +
 arch/csky/include/asm/page.h   | 2 +-
 arch/m68k/Kconfig  | 3 +++
 arch/m68k/Kconfig.cpu  | 2 ++
 arch/m68k/include/asm/page.h   | 6 +-
 arch/microblaze/Kconfig| 1 +
 arch/microblaze/include/asm/page.h | 2 +-
 arch/nios2/Kconfig | 1 +
 arch/nios2/include/asm/page.h  | 2 +-
 arch/openrisc/Kconfig  | 1 +
 arch/openrisc/include/asm/page.h   | 2 +-
 arch/riscv/Kconfig | 1 +
 arch/riscv/include/asm/page.h  | 2 +-
 arch/s390/Kconfig  | 1 +
 arch/s390/include/asm/page.h   | 2 +-
 arch/sparc/Kconfig | 2 ++
 arch/sparc/include/asm/page_32.h   | 2 +-
 arch/sparc/include/asm/page_64.h   | 3 +--
 arch/um/Kconfig| 1 +
 arch/um/include/asm/page.h | 2 +-
 arch/x86/Kconfig   | 1 +
 arch/x86/include/asm/page_types.h  | 2 +-
 arch/xtensa/Kconfig| 1 +
 arch/xtensa/include/asm/page.h | 2 +-
 28 files changed, 32 insertions(+), 19 deletions(-)

diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index d6968d090d49..4f490250d323 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -14,6 +14,7 @@ config ALPHA
select PCI_DOMAINS if PCI
select PCI_SYSCALL if PCI
select HAVE_ASM_MODVERSIONS
+   select HAVE_PAGE_SIZE_8KB
select HAVE_PCSPKR_PLATFORM
select HAVE_PERF_EVENTS
select NEED_DMA_MAP_STATE
diff --git a/arch/alpha/include/asm/page.h b/arch/alpha/include/asm/page.h
index 4db1ebc0ed99..70419e6be1a3 100644
--- a/arch/alpha/include/asm/page.h
+++ b/arch/alpha/include/asm/page.h
@@ -6,7 +6,7 @@
 #include 
 
 /* PAGE_SHIFT determines the page size */
-#define PAGE_SHIFT 13
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
 #define PAGE_SIZE  (_AC(1,UL) << PAGE_SHIFT)
 #define PAGE_MASK  (~(PAGE_SIZE-1))
 
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0af6709570d1..9d52ba3a8ad1 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -116,6 +116,7 @@ config ARM
select HAVE_MOD_ARCH_SPECIFIC
select HAVE_NMI
select HAVE_OPTPROBES if !THUMB2_KERNEL
+   select HAVE_PAGE_SIZE_4KB
select HAVE_PCI if MMU
select HAVE_PERF_EVENTS
select HAVE_PERF_REGS
diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
index 119aa85d1feb..62af9f7f9e96 100644
--- a/arch/arm/include/asm/page.h
+++ b/arch/arm/include/asm/page.h
@@ -8,7 +8,7 @@
 #define _ASMARM_PAGE_H
 
 /* PAGE_SHIFT determines the page size */
-#define PAGE_SHIFT 12
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
 #define PAGE_SIZE  (_AC(1,UL) << PAGE_SHIFT)
 #define PAGE_MASK  (~((1 << PAGE_SHIFT) - 1))
 
diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig
index cf2a6fd7dff8..9c2723ab1c94 100644
--- a/arch/csky/Kconfig
+++ b/arch/csky/Kconfig
@@ -89,6 +89,7 @@ config CSKY
select HAVE_KPROBES if !CPU_CK610
select HAVE_KPROBES_ON_FTRACE if !CPU_CK610
select HAVE_KRETPROBES if !CPU_CK610
+   select HAVE_PAGE_SIZE_4KB
select HAVE_PERF_EVENTS
select HAVE_PERF_REGS
select HAVE_PERF_USER_STACK_DUMP
diff --git a/arch/csky/include/asm/page.h b/arch/csky/include/asm/page.h
index 4a0502e324a6..f70f37402d75 100644
--- a/arch/csky/include/asm/page.h
+++ b/arch/csky/include/asm/page.h
@@ -10,7 +10,7 @@
 /*
  * PAGE_SHIFT determines the page size: 4KB
  */
-#define PAGE_SHIFT 12
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
 #define PAGE_SIZE  (_AC(1, UL) << PAGE_SHIFT)
 #define PAGE_MASK  (~(PAGE_SIZE - 1))
 #define THREAD_SIZE(PAGE_SIZE * 2)
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 4b3e93cac723..7b709453d5e7 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -84,12 +84,15 @@ config MMU
 
 config MMU_MOTOROLA
bool
+   select HAVE_PAGE_SIZE_4KB
 
 config MMU_COLDFIRE
+   select HAVE_PAGE_SIZE_8KB
bool
 
 config MMU_SUN3
bool
+   select HAVE_PAGE_SIZE_8KB
depends on MMU && !MMU_MOTOROLA && !MMU_COLDFIRE
 
 config ARCH_SUPPORTS_KEXEC
diff --git a/arch/m68k/Kconfig.cpu b/arch/m68k/Kconfig.cpu
index 9dcf245c9cbf..c777a129768a 100644
--- a/arch/m68k/Kconfig.cpu
+++ b/arch/m68k/Kconfig.cpu
@@ -30,6 +30,7 @@ config COLDFIRE
select GENERIC_CSUM
select GPIOLIB
select HAVE_LEGACY_CLK
+   select HAVE_PAGE_SIZE_8KB if !MMU
 
 endchoice
 
@@ -45,6 +46,7 @@ config M68000
   

[PATCH 2/4] arch: simplify architecture specific page size configuration

2024-02-26 Thread Arnd Bergmann
From: Arnd Bergmann 

arc, arm64, parisc and powerpc all have their own Kconfig symbols
in place of the common CONFIG_PAGE_SIZE_4KB symbols. Change these
so the common symbols are the ones that are actually used, while
leaving the arhcitecture specific ones as the user visible
place for configuring it, to avoid breaking user configs.

Signed-off-by: Arnd Bergmann 
---
 arch/arc/Kconfig  |  3 +++
 arch/arc/include/uapi/asm/page.h  |  6 ++
 arch/arm64/Kconfig| 29 +
 arch/arm64/include/asm/page-def.h |  2 +-
 arch/parisc/Kconfig   |  3 +++
 arch/parisc/include/asm/page.h| 10 +-
 arch/powerpc/Kconfig  | 31 ++-
 arch/powerpc/include/asm/page.h   |  2 +-
 scripts/gdb/linux/constants.py.in |  2 +-
 scripts/gdb/linux/mm.py   |  2 +-
 10 files changed, 32 insertions(+), 58 deletions(-)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 1b0483c51cc1..4092bec198be 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -284,14 +284,17 @@ choice
 
 config ARC_PAGE_SIZE_8K
bool "8KB"
+   select HAVE_PAGE_SIZE_8KB
help
  Choose between 8k vs 16k
 
 config ARC_PAGE_SIZE_16K
+   select HAVE_PAGE_SIZE_16KB
bool "16KB"
 
 config ARC_PAGE_SIZE_4K
bool "4KB"
+   select HAVE_PAGE_SIZE_4KB
depends on ARC_MMU_V3 || ARC_MMU_V4
 
 endchoice
diff --git a/arch/arc/include/uapi/asm/page.h b/arch/arc/include/uapi/asm/page.h
index 2a4ad619abfb..7fd9e741b527 100644
--- a/arch/arc/include/uapi/asm/page.h
+++ b/arch/arc/include/uapi/asm/page.h
@@ -13,10 +13,8 @@
 #include 
 
 /* PAGE_SHIFT determines the page size */
-#if defined(CONFIG_ARC_PAGE_SIZE_16K)
-#define PAGE_SHIFT 14
-#elif defined(CONFIG_ARC_PAGE_SIZE_4K)
-#define PAGE_SHIFT 12
+#ifdef __KERNEL__
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
 #else
 /*
  * Default 8k
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index aa7c1d435139..29290b8cb36d 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -277,27 +277,21 @@ config 64BIT
 config MMU
def_bool y
 
-config ARM64_PAGE_SHIFT
-   int
-   default 16 if ARM64_64K_PAGES
-   default 14 if ARM64_16K_PAGES
-   default 12
-
 config ARM64_CONT_PTE_SHIFT
int
-   default 5 if ARM64_64K_PAGES
-   default 7 if ARM64_16K_PAGES
+   default 5 if PAGE_SIZE_64KB
+   default 7 if PAGE_SIZE_16KB
default 4
 
 config ARM64_CONT_PMD_SHIFT
int
-   default 5 if ARM64_64K_PAGES
-   default 5 if ARM64_16K_PAGES
+   default 5 if PAGE_SIZE_64KB
+   default 5 if PAGE_SIZE_16KB
default 4
 
 config ARCH_MMAP_RND_BITS_MIN
-   default 14 if ARM64_64K_PAGES
-   default 16 if ARM64_16K_PAGES
+   default 14 if PAGE_SIZE_64KB
+   default 16 if PAGE_SIZE_16KB
default 18
 
 # max bits determined by the following formula:
@@ -1259,11 +1253,13 @@ choice
 
 config ARM64_4K_PAGES
bool "4KB"
+   select HAVE_PAGE_SIZE_4KB
help
  This feature enables 4KB pages support.
 
 config ARM64_16K_PAGES
bool "16KB"
+   select HAVE_PAGE_SIZE_16KB
help
  The system will use 16KB pages support. AArch32 emulation
  requires applications compiled with 16K (or a multiple of 16K)
@@ -1271,6 +1267,7 @@ config ARM64_16K_PAGES
 
 config ARM64_64K_PAGES
bool "64KB"
+   select HAVE_PAGE_SIZE_64KB
help
  This feature enables 64KB pages support (4KB by default)
  allowing only two levels of page tables and faster TLB
@@ -1291,19 +1288,19 @@ choice
 
 config ARM64_VA_BITS_36
bool "36-bit" if EXPERT
-   depends on ARM64_16K_PAGES
+   depends on PAGE_SIZE_16KB
 
 config ARM64_VA_BITS_39
bool "39-bit"
-   depends on ARM64_4K_PAGES
+   depends on PAGE_SIZE_4KB
 
 config ARM64_VA_BITS_42
bool "42-bit"
-   depends on ARM64_64K_PAGES
+   depends on PAGE_SIZE_64KB
 
 config ARM64_VA_BITS_47
bool "47-bit"
-   depends on ARM64_16K_PAGES
+   depends on PAGE_SIZE_16KB
 
 config ARM64_VA_BITS_48
bool "48-bit"
diff --git a/arch/arm64/include/asm/page-def.h 
b/arch/arm64/include/asm/page-def.h
index 2403f7b4cdbf..792e9fe881dc 100644
--- a/arch/arm64/include/asm/page-def.h
+++ b/arch/arm64/include/asm/page-def.h
@@ -11,7 +11,7 @@
 #include 
 
 /* PAGE_SHIFT determines the page size */
-#define PAGE_SHIFT CONFIG_ARM64_PAGE_SHIFT
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
 #define PAGE_SIZE  (_AC(1, UL) << PAGE_SHIFT)
 #define PAGE_MASK  (~(PAGE_SIZE-1))
 
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 5c845e8d59d9..b180e684fa0d 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -273,6 +273,7 @@ choice
 
 config PARISC_PAGE_SIZE_4KB
bool "4KB"
+   select HAVE_PAGE_SIZE_4KB
help
  This lets you select the page size of the kernel.  For 

[PATCH 1/4] arch: consolidate existing CONFIG_PAGE_SIZE_*KB definitions

2024-02-26 Thread Arnd Bergmann
From: Arnd Bergmann 

These four architectures define the same Kconfig symbols for configuring
the page size. Move the logic into a common place where it can be shared
with all other architectures.

Signed-off-by: Arnd Bergmann 
---
 arch/Kconfig  | 58 +--
 arch/hexagon/Kconfig  | 25 +++--
 arch/hexagon/include/asm/page.h   |  6 +---
 arch/loongarch/Kconfig| 21 ---
 arch/loongarch/include/asm/page.h | 10 +-
 arch/mips/Kconfig | 58 +++
 arch/mips/include/asm/page.h  | 16 +
 arch/sh/include/asm/page.h| 13 +--
 arch/sh/mm/Kconfig| 42 +++---
 9 files changed, 88 insertions(+), 161 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index a5af0edd3eb8..237cea01ed9b 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -1078,17 +1078,71 @@ config HAVE_ARCH_COMPAT_MMAP_BASES
  and vice-versa 32-bit applications to call 64-bit mmap().
  Required for applications doing different bitness syscalls.
 
+config HAVE_PAGE_SIZE_4KB
+   bool
+
+config HAVE_PAGE_SIZE_8KB
+   bool
+
+config HAVE_PAGE_SIZE_16KB
+   bool
+
+config HAVE_PAGE_SIZE_32KB
+   bool
+
+config HAVE_PAGE_SIZE_64KB
+   bool
+
+config HAVE_PAGE_SIZE_256KB
+   bool
+
+choice
+   prompt "MMU page size"
+
+config PAGE_SIZE_4KB
+   bool "4KB pages"
+   depends on HAVE_PAGE_SIZE_4KB
+
+config PAGE_SIZE_8KB
+   bool "8KB pages"
+   depends on HAVE_PAGE_SIZE_8KB
+
+config PAGE_SIZE_16KB
+   bool "16KB pages"
+   depends on HAVE_PAGE_SIZE_16KB
+
+config PAGE_SIZE_32KB
+   bool "32KB pages"
+   depends on HAVE_PAGE_SIZE_32KB
+
+config PAGE_SIZE_64KB
+   bool "64KB pages"
+   depends on HAVE_PAGE_SIZE_64KB
+
+config PAGE_SIZE_256KB
+   bool "256KB pages"
+   depends on HAVE_PAGE_SIZE_256KB
+
+endchoice
+
 config PAGE_SIZE_LESS_THAN_64KB
def_bool y
-   depends on !ARM64_64K_PAGES
depends on !PAGE_SIZE_64KB
-   depends on !PARISC_PAGE_SIZE_64KB
depends on PAGE_SIZE_LESS_THAN_256KB
 
 config PAGE_SIZE_LESS_THAN_256KB
def_bool y
depends on !PAGE_SIZE_256KB
 
+config PAGE_SHIFT
+   int
+   default 12 if PAGE_SIZE_4KB
+   default 13 if PAGE_SIZE_8KB
+   default 14 if PAGE_SIZE_16KB
+   default 15 if PAGE_SIZE_32KB
+   default 16 if PAGE_SIZE_64KB
+   default 18 if PAGE_SIZE_256KB
+
 # This allows to use a set of generic functions to determine mmap base
 # address by giving priority to top-down scheme only if the process
 # is not in legacy mode (compat task, unlimited stack size or
diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig
index a880ee067d2e..aac46ee1a000 100644
--- a/arch/hexagon/Kconfig
+++ b/arch/hexagon/Kconfig
@@ -8,6 +8,11 @@ config HEXAGON
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
select ARCH_NO_PREEMPT
select DMA_GLOBAL_POOL
+   select FRAME_POINTER
+   select HAVE_PAGE_SIZE_4KB
+   select HAVE_PAGE_SIZE_16KB
+   select HAVE_PAGE_SIZE_64KB
+   select HAVE_PAGE_SIZE_256KB
# Other pending projects/to-do items.
# select HAVE_REGS_AND_STACK_ACCESS_API
# select HAVE_HW_BREAKPOINT if PERF_EVENTS
@@ -120,26 +125,6 @@ config NR_CPUS
  This is purely to save memory - each supported CPU adds
  approximately eight kilobytes to the kernel image.
 
-choice
-   prompt "Kernel page size"
-   default PAGE_SIZE_4KB
-   help
- Changes the default page size; use with caution.
-
-config PAGE_SIZE_4KB
-   bool "4KB"
-
-config PAGE_SIZE_16KB
-   bool "16KB"
-
-config PAGE_SIZE_64KB
-   bool "64KB"
-
-config PAGE_SIZE_256KB
-   bool "256KB"
-
-endchoice
-
 source "kernel/Kconfig.hz"
 
 endmenu
diff --git a/arch/hexagon/include/asm/page.h b/arch/hexagon/include/asm/page.h
index 10f1bc07423c..65c9bac639fa 100644
--- a/arch/hexagon/include/asm/page.h
+++ b/arch/hexagon/include/asm/page.h
@@ -13,27 +13,22 @@
 /*  This is probably not the most graceful way to handle this.  */
 
 #ifdef CONFIG_PAGE_SIZE_4KB
-#define PAGE_SHIFT 12
 #define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_4KB
 #endif
 
 #ifdef CONFIG_PAGE_SIZE_16KB
-#define PAGE_SHIFT 14
 #define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_16KB
 #endif
 
 #ifdef CONFIG_PAGE_SIZE_64KB
-#define PAGE_SHIFT 16
 #define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_64KB
 #endif
 
 #ifdef CONFIG_PAGE_SIZE_256KB
-#define PAGE_SHIFT 18
 #define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_256KB
 #endif
 
 #ifdef CONFIG_PAGE_SIZE_1MB
-#define PAGE_SHIFT 20
 #define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_1MB
 #endif
 
@@ -50,6 +45,7 @@
 #define HVM_HUGEPAGE_SIZE 0x5
 #endif
 
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
 #define PAGE_SIZE  (1UL << PAGE_SHIFT)
 #define PAGE_MASK  (~((1 << PAGE_SHIFT) - 1))
 
diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index 929f68926b34..b274784c2e26 100644
--- 

[PATCH 0/4] arch: mm, vdso: consolidate PAGE_SIZE definition

2024-02-26 Thread Arnd Bergmann
From: Arnd Bergmann 

Naresh noticed that the newly added usage of the PAGE_SIZE macro in
include/vdso/datapage.h introduced a build regression. I had an older
patch that I revived to have this defined through Kconfig rather than
through including asm/page.h, which is not allowed in vdso code.

I rebased and tested on top of the tip/timers/core branch that
introduced the regression. If these patches get added, the
compat VDSOs all build again, but the changes are a bit invasive.

  Arnd

Link: 
https://lore.kernel.org/lkml/ca+g9fytrxxm_ko9fnpz3xarxhv7ud_yqp-teupqrnrhu+_0...@mail.gmail.com/
Link: https://lore.kernel.org/all/65dc6c14.170a0220.f4a3f.9...@mx.google.com/

Arnd Bergmann (4):
  arch: consolidate existing CONFIG_PAGE_SIZE_*KB definitions
  arch: simplify architecture specific page size configuration
  arch: define CONFIG_PAGE_SIZE_*KB on all architectures
  vdso: avoid including asm/page.h

 arch/Kconfig   | 58 --
 arch/alpha/Kconfig |  1 +
 arch/alpha/include/asm/page.h  |  2 +-
 arch/arc/Kconfig   |  3 ++
 arch/arc/include/uapi/asm/page.h   |  6 ++--
 arch/arm/Kconfig   |  1 +
 arch/arm/include/asm/page.h|  2 +-
 arch/arm64/Kconfig | 29 +++
 arch/arm64/include/asm/page-def.h  |  2 +-
 arch/csky/Kconfig  |  1 +
 arch/csky/include/asm/page.h   |  2 +-
 arch/hexagon/Kconfig   | 25 +++--
 arch/hexagon/include/asm/page.h|  6 +---
 arch/loongarch/Kconfig | 21 ---
 arch/loongarch/include/asm/page.h  | 10 +-
 arch/m68k/Kconfig  |  3 ++
 arch/m68k/Kconfig.cpu  |  2 ++
 arch/m68k/include/asm/page.h   |  6 +---
 arch/microblaze/Kconfig|  1 +
 arch/microblaze/include/asm/page.h |  2 +-
 arch/mips/Kconfig  | 58 +++---
 arch/mips/include/asm/page.h   | 16 +
 arch/nios2/Kconfig |  1 +
 arch/nios2/include/asm/page.h  |  2 +-
 arch/openrisc/Kconfig  |  1 +
 arch/openrisc/include/asm/page.h   |  2 +-
 arch/parisc/Kconfig|  3 ++
 arch/parisc/include/asm/page.h | 10 +-
 arch/powerpc/Kconfig   | 31 
 arch/powerpc/include/asm/page.h|  2 +-
 arch/riscv/Kconfig |  1 +
 arch/riscv/include/asm/page.h  |  2 +-
 arch/s390/Kconfig  |  1 +
 arch/s390/include/asm/page.h   |  2 +-
 arch/sh/include/asm/page.h | 13 +--
 arch/sh/mm/Kconfig | 42 +++---
 arch/sparc/Kconfig |  2 ++
 arch/sparc/include/asm/page_32.h   |  2 +-
 arch/sparc/include/asm/page_64.h   |  3 +-
 arch/um/Kconfig|  1 +
 arch/um/include/asm/page.h |  2 +-
 arch/x86/Kconfig   |  1 +
 arch/x86/include/asm/page_types.h  |  2 +-
 arch/xtensa/Kconfig|  1 +
 arch/xtensa/include/asm/page.h |  2 +-
 include/vdso/datapage.h|  4 +--
 scripts/gdb/linux/constants.py.in  |  2 +-
 scripts/gdb/linux/mm.py|  2 +-
 48 files changed, 153 insertions(+), 241 deletions(-)

-- 
2.39.2
To: Thomas Gleixner 
To: Vincenzo Frascino 
To: Kees Cook 
To: Anna-Maria Behnsen 
Cc: Matt Turner 
Cc: Vineet Gupta 
Cc: Russell King 
Cc: Catalin Marinas 
Cc: Guo Ren 
Cc: Brian Cain 
Cc: Huacai Chen 
Cc: Geert Uytterhoeven 
Cc: Michal Simek 
Cc: Thomas Bogendoerfer 
Cc: Helge Deller 
Cc: Michael Ellerman 
Cc: Christophe Leroy 
Cc: Palmer Dabbelt 
Cc: John Paul Adrian Glaubitz 
Cc: Andreas Larsson 
Cc: Richard Weinberger 
Cc: x...@kernel.org
Cc: Max Filippov 
Cc: Andy Lutomirski 
Cc: Vincenzo Frascino 
Cc: Jan Kiszka 
Cc: Kieran Bingham 
Cc: Andrew Morton 
Cc: Arnd Bergmann 
Cc: linux-ker...@vger.kernel.org
Cc: linux-al...@vger.kernel.org
Cc: linux-snps-...@lists.infradead.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-c...@vger.kernel.org
Cc: linux-hexa...@vger.kernel.org
Cc: loonga...@lists.linux.dev
Cc: linux-m...@lists.linux-m68k.org
Cc: linux-m...@vger.kernel.org
Cc: linux-openr...@vger.kernel.org
Cc: linux-par...@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-ri...@lists.infradead.org
Cc: linux-s...@vger.kernel.org
Cc: linux...@vger.kernel.org
Cc: sparcli...@vger.kernel.org
Cc: linux...@lists.infradead.org


Re: [PATCH v13 09/16] media: uapi: Define audio sample format fourcc type

2024-02-26 Thread Nicolas Dufresne
Le lundi 26 février 2024 à 16:28 +0800, Shengjiu Wang a écrit :
> The audio sample format definition is from alsa,
> the header file is include/uapi/sound/asound.h, but
> don't include this header file directly, because in
> user space, there is another copy in alsa-lib.
> There will be conflict in userspace for include
> videodev2.h & asound.h and asoundlib.h
> 
> Here still use the fourcc format.

I'd like to join Mauro's voice that duplicating the audio formats is a bad idea.
We have the same issues with video formats when you look at V4L2 vs DRM. You're
rationale is that videodev2.h will be ambiguous if it includes asound.h, but
looking at this change, there is no reason why you need to include asound.h in
videodev2.h at all. The format type can be abstracted out with a uint32 in the
API, and then it would be up to the users to include and use the appropriate
formats IDs.

Nicolas

> 
> Signed-off-by: Shengjiu Wang 
> ---
>  .../userspace-api/media/v4l/pixfmt-audio.rst  | 87 +++
>  .../userspace-api/media/v4l/pixfmt.rst|  1 +
>  drivers/media/v4l2-core/v4l2-ioctl.c  | 13 +++
>  include/uapi/linux/videodev2.h| 23 +
>  4 files changed, 124 insertions(+)
>  create mode 100644 Documentation/userspace-api/media/v4l/pixfmt-audio.rst
> 
> diff --git a/Documentation/userspace-api/media/v4l/pixfmt-audio.rst 
> b/Documentation/userspace-api/media/v4l/pixfmt-audio.rst
> new file mode 100644
> index ..04b4a7fbd8f4
> --- /dev/null
> +++ b/Documentation/userspace-api/media/v4l/pixfmt-audio.rst
> @@ -0,0 +1,87 @@
> +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
> +
> +.. _pixfmt-audio:
> +
> +*
> +Audio Formats
> +*
> +
> +These formats are used for :ref:`audiomem2mem` interface only.
> +
> +.. tabularcolumns:: |p{5.8cm}|p{1.2cm}|p{10.3cm}|
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: Audio Format
> +:header-rows:  1
> +:stub-columns: 0
> +:widths:   3 1 4
> +
> +* - Identifier
> +  - Code
> +  - Details
> +* .. _V4L2-AUDIO-FMT-S8:
> +
> +  - ``V4L2_AUDIO_FMT_S8``
> +  - 'S8'
> +  - Corresponds to SNDRV_PCM_FORMAT_S8 in ALSA
> +* .. _V4L2-AUDIO-FMT-S16-LE:
> +
> +  - ``V4L2_AUDIO_FMT_S16_LE``
> +  - 'S16_LE'
> +  - Corresponds to SNDRV_PCM_FORMAT_S16_LE in ALSA
> +* .. _V4L2-AUDIO-FMT-U16-LE:
> +
> +  - ``V4L2_AUDIO_FMT_U16_LE``
> +  - 'U16_LE'
> +  - Corresponds to SNDRV_PCM_FORMAT_U16_LE in ALSA
> +* .. _V4L2-AUDIO-FMT-S24-LE:
> +
> +  - ``V4L2_AUDIO_FMT_S24_LE``
> +  - 'S24_LE'
> +  - Corresponds to SNDRV_PCM_FORMAT_S24_LE in ALSA
> +* .. _V4L2-AUDIO-FMT-U24-LE:
> +
> +  - ``V4L2_AUDIO_FMT_U24_LE``
> +  - 'U24_LE'
> +  - Corresponds to SNDRV_PCM_FORMAT_U24_LE in ALSA
> +* .. _V4L2-AUDIO-FMT-S32-LE:
> +
> +  - ``V4L2_AUDIO_FMT_S32_LE``
> +  - 'S32_LE'
> +  - Corresponds to SNDRV_PCM_FORMAT_S32_LE in ALSA
> +* .. _V4L2-AUDIO-FMT-U32-LE:
> +
> +  - ``V4L2_AUDIO_FMT_U32_LE``
> +  - 'U32_LE'
> +  - Corresponds to SNDRV_PCM_FORMAT_U32_LE in ALSA
> +* .. _V4L2-AUDIO-FMT-FLOAT-LE:
> +
> +  - ``V4L2_AUDIO_FMT_FLOAT_LE``
> +  - 'FLOAT_LE'
> +  - Corresponds to SNDRV_PCM_FORMAT_FLOAT_LE in ALSA
> +* .. _V4L2-AUDIO-FMT-IEC958-SUBFRAME-LE:
> +
> +  - ``V4L2_AUDIO_FMT_IEC958_SUBFRAME_LE``
> +  - 'IEC958_SUBFRAME_LE'
> +  - Corresponds to SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE in ALSA
> +* .. _V4L2-AUDIO-FMT-S24-3LE:
> +
> +  - ``V4L2_AUDIO_FMT_S24_3LE``
> +  - 'S24_3LE'
> +  - Corresponds to SNDRV_PCM_FORMAT_S24_3LE in ALSA
> +* .. _V4L2-AUDIO-FMT-U24-3LE:
> +
> +  - ``V4L2_AUDIO_FMT_U24_3LE``
> +  - 'U24_3LE'
> +  - Corresponds to SNDRV_PCM_FORMAT_U24_3LE in ALSA
> +* .. _V4L2-AUDIO-FMT-S20-3LE:
> +
> +  - ``V4L2_AUDIO_FMT_S20_3LE``
> +  - 'S20_3LE'
> +  - Corresponds to SNDRV_PCM_FORMAT_S24_3LE in ALSA
> +* .. _V4L2-AUDIO-FMT-U20-3LE:
> +
> +  - ``V4L2_AUDIO_FMT_U20_3LE``
> +  - 'U20_3LE'
> +  - Corresponds to SNDRV_PCM_FORMAT_U20_3LE in ALSA
> diff --git a/Documentation/userspace-api/media/v4l/pixfmt.rst 
> b/Documentation/userspace-api/media/v4l/pixfmt.rst
> index 11dab4a90630..2eb6fdd3b43d 100644
> --- a/Documentation/userspace-api/media/v4l/pixfmt.rst
> +++ b/Documentation/userspace-api/media/v4l/pixfmt.rst
> @@ -36,3 +36,4 @@ see also :ref:`VIDIOC_G_FBUF `.)
>  colorspaces
>  colorspaces-defs
>  colorspaces-details
> +pixfmt-audio
> diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
> b/drivers/media/v4l2-core/v4l2-ioctl.c
> index 961abcdf7290..be229c69e991 100644
> --- a/drivers/media/v4l2-core/v4l2-ioctl.c
> +++ b/drivers/media/v4l2-core/v4l2-ioctl.c
> @@ -1471,6 +1471,19 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
>   case V4L2_PIX_FMT_Y210: descr = "10-bit YUYV Packed"; break;
>   case V4L2_PIX_FMT_Y212: descr = "12-bit YUYV 

Re: [kvm-unit-tests PATCH 02/32] powerpc: Fix pseries getchar return value

2024-02-26 Thread Thomas Huth

On 26/02/2024 11.11, Nicholas Piggin wrote:

getchar() didn't get the shift value correct and never returned the
first character. This never really mattered since it was only ever
used for press-a-key-to-continue prompts. but it tripped me up when
debugging a QEMU console output problem.

Signed-off-by: Nicholas Piggin 
---
  lib/powerpc/hcall.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/powerpc/hcall.c b/lib/powerpc/hcall.c
index 711cb1b0f..b4d39ac65 100644
--- a/lib/powerpc/hcall.c
+++ b/lib/powerpc/hcall.c
@@ -43,5 +43,5 @@ int __getchar(void)
asm volatile (" sc 1 "  : "+r"(r3), "+r"(r4), "=r"(r5)
: "r"(r3),  "r"(r4));
  
-	return r3 == H_SUCCESS && r4 > 0 ? r5 >> 48 : -1;

+   return r3 == H_SUCCESS && r4 > 0 ? r5 >> 56 : -1;
  }


Reviewed-by: Thomas Huth 



Re: [kvm-unit-tests PATCH 01/32] powerpc: Fix KVM caps on POWER9 hosts

2024-02-26 Thread Thomas Huth

On 26/02/2024 11.11, Nicholas Piggin wrote:

KVM does not like to run on POWER9 hosts without cap-ccf-assist=off.

Signed-off-by: Nicholas Piggin 
---
  powerpc/run | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/powerpc/run b/powerpc/run
index e469f1eb3..5cdb94194 100755
--- a/powerpc/run
+++ b/powerpc/run
@@ -24,6 +24,8 @@ M+=",accel=$ACCEL$ACCEL_PROPS"
  
  if [[ "$ACCEL" == "tcg" ]] ; then

M+=",cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken,cap-ccf-assist=off"
+elif [[ "$ACCEL" == "kvm" ]] ; then
+   M+=",cap-ccf-assist=off"
  fi


Since it is needed in both cases, you could also move it out of the 
if-statement and remove it from the tcg part.


Anyway,
Reviewed-by: Thomas Huth 



[Bug 207129] PowerMac G4 DP (5.6.2 debug kernel + inline KASAN) freezes shortly after booting with "do_IRQ: stack overflow: 1760"

2024-02-26 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=207129

Michael Ellerman (mich...@ellerman.id.au) changed:

   What|Removed |Added

 Status|RESOLVED|CLOSED

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

[Bug 207129] PowerMac G4 DP (5.6.2 debug kernel + inline KASAN) freezes shortly after booting with "do_IRQ: stack overflow: 1760"

2024-02-26 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=207129

Michael Ellerman (mich...@ellerman.id.au) changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 CC||mich...@ellerman.id.au
 Resolution|--- |CODE_FIX

--- Comment #7 from Michael Ellerman (mich...@ellerman.id.au) ---
I think this was resolved by increasing the stack size for KASAN builds.

ie.
edbadaf06710 ("powerpc/kasan: Fix stack overflow by increasing THREAD_SHIFT")
and later
3e8635fb2e07 ("powerpc/kasan: Force thread size increase with KASAN")

If not feel free to reopen.

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

[Bug 155231] powerpc : native aslr vdso randomization is not working in powerpc platform

2024-02-26 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=155231

Michael Ellerman (mich...@ellerman.id.au) changed:

   What|Removed |Added

 Status|RESOLVED|CLOSED

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

[Bug 155231] powerpc : native aslr vdso randomization is not working in powerpc platform

2024-02-26 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=155231

Michael Ellerman (mich...@ellerman.id.au) changed:

   What|Removed |Added

 Status|NEEDINFO|RESOLVED
 Resolution|--- |CODE_FIX

--- Comment #3 from Michael Ellerman (mich...@ellerman.id.au) ---
This was fixed in v6.1, see:

https://github.com/torvalds/linux/commit/8a8f783588b162031a5348c24e42161461cd

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

Re: [PATCH] powerpc/mm: Code cleanup for __hash_page_thp

2024-02-26 Thread Michael Ellerman
Kunwu Chan  writes:
> This part was commented from commit 6d492ecc6489
> ("powerpc/THP: Add code to handle HPTE faults for hugepages")
> in about 11 years before.
>
> If there are no plans to enable this part code in the future,
> we can remove this dead code.

I agree the code can go. But I'd like it to be replaced with a comment
explaining what the dead code was trying to say.

cheers

> diff --git a/arch/powerpc/mm/book3s64/hash_hugepage.c 
> b/arch/powerpc/mm/book3s64/hash_hugepage.c
> index c0fabe6c5a12..127a3a2c174b 100644
> --- a/arch/powerpc/mm/book3s64/hash_hugepage.c
> +++ b/arch/powerpc/mm/book3s64/hash_hugepage.c
> @@ -59,16 +59,6 @@ int __hash_page_thp(unsigned long ea, unsigned long 
> access, unsigned long vsid,
>  
>   rflags = htab_convert_pte_flags(new_pmd, flags);
>  
> -#if 0
> - if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) {
> -
> - /*
> -  * No CPU has hugepages but lacks no execute, so we
> -  * don't need to worry about that case
> -  */
> - rflags = hash_page_do_lazy_icache(rflags, __pte(old_pte), trap);
> - }
> -#endif
>   /*
>* Find the slot index details for this ea, using base page size.
>*/
> -- 
> 2.39.2


[PATCH linux-next v2 2/3] powerpc/kexec: split CONFIG_KEXEC_FILE and CONFIG_CRASH_DUMP

2024-02-26 Thread Hari Bathini
CONFIG_KEXEC_FILE does not have to select CONFIG_CRASH_DUMP. Move
some code under CONFIG_CRASH_DUMP to support CONFIG_KEXEC_FILE and
!CONFIG_CRASH_DUMP case.

Signed-off-by: Hari Bathini 
---

* No changes in v2.

 arch/powerpc/kexec/elf_64.c   |   4 +-
 arch/powerpc/kexec/file_load_64.c | 269 --
 2 files changed, 142 insertions(+), 131 deletions(-)

diff --git a/arch/powerpc/kexec/elf_64.c b/arch/powerpc/kexec/elf_64.c
index 904016cf89ea..6d8951e8e966 100644
--- a/arch/powerpc/kexec/elf_64.c
+++ b/arch/powerpc/kexec/elf_64.c
@@ -47,7 +47,7 @@ static void *elf64_load(struct kimage *image, char 
*kernel_buf,
if (ret)
return ERR_PTR(ret);
 
-   if (image->type == KEXEC_TYPE_CRASH) {
+   if (IS_ENABLED(CONFIG_CRASH_DUMP) && image->type == KEXEC_TYPE_CRASH) {
/* min & max buffer values for kdump case */
kbuf.buf_min = pbuf.buf_min = crashk_res.start;
kbuf.buf_max = pbuf.buf_max =
@@ -70,7 +70,7 @@ static void *elf64_load(struct kimage *image, char 
*kernel_buf,
kexec_dprintk("Loaded purgatory at 0x%lx\n", pbuf.mem);
 
/* Load additional segments needed for panic kernel */
-   if (image->type == KEXEC_TYPE_CRASH) {
+   if (IS_ENABLED(CONFIG_CRASH_DUMP) && image->type == KEXEC_TYPE_CRASH) {
ret = load_crashdump_segments_ppc64(image, );
if (ret) {
pr_err("Failed to load kdump kernel segments\n");
diff --git a/arch/powerpc/kexec/file_load_64.c 
b/arch/powerpc/kexec/file_load_64.c
index 5b4c5cb23354..1bc65de6174f 100644
--- a/arch/powerpc/kexec/file_load_64.c
+++ b/arch/powerpc/kexec/file_load_64.c
@@ -96,119 +96,6 @@ static int get_exclude_memory_ranges(struct crash_mem 
**mem_ranges)
return ret;
 }
 
-/**
- * get_usable_memory_ranges - Get usable memory ranges. This list includes
- *regions like crashkernel, opal/rtas & tce-table,
- *that kdump kernel could use.
- * @mem_ranges:   Range list to add the memory ranges to.
- *
- * Returns 0 on success, negative errno on error.
- */
-static int get_usable_memory_ranges(struct crash_mem **mem_ranges)
-{
-   int ret;
-
-   /*
-* Early boot failure observed on guests when low memory (first memory
-* block?) is not added to usable memory. So, add [0, crashk_res.end]
-* instead of [crashk_res.start, crashk_res.end] to workaround it.
-* Also, crashed kernel's memory must be added to reserve map to
-* avoid kdump kernel from using it.
-*/
-   ret = add_mem_range(mem_ranges, 0, crashk_res.end + 1);
-   if (ret)
-   goto out;
-
-   ret = add_rtas_mem_range(mem_ranges);
-   if (ret)
-   goto out;
-
-   ret = add_opal_mem_range(mem_ranges);
-   if (ret)
-   goto out;
-
-   ret = add_tce_mem_ranges(mem_ranges);
-out:
-   if (ret)
-   pr_err("Failed to setup usable memory ranges\n");
-   return ret;
-}
-
-/**
- * get_crash_memory_ranges - Get crash memory ranges. This list includes
- *   first/crashing kernel's memory regions that
- *   would be exported via an elfcore.
- * @mem_ranges:  Range list to add the memory ranges to.
- *
- * Returns 0 on success, negative errno on error.
- */
-static int get_crash_memory_ranges(struct crash_mem **mem_ranges)
-{
-   phys_addr_t base, end;
-   struct crash_mem *tmem;
-   u64 i;
-   int ret;
-
-   for_each_mem_range(i, , ) {
-   u64 size = end - base;
-
-   /* Skip backup memory region, which needs a separate entry */
-   if (base == BACKUP_SRC_START) {
-   if (size > BACKUP_SRC_SIZE) {
-   base = BACKUP_SRC_END + 1;
-   size -= BACKUP_SRC_SIZE;
-   } else
-   continue;
-   }
-
-   ret = add_mem_range(mem_ranges, base, size);
-   if (ret)
-   goto out;
-
-   /* Try merging adjacent ranges before reallocation attempt */
-   if ((*mem_ranges)->nr_ranges == (*mem_ranges)->max_nr_ranges)
-   sort_memory_ranges(*mem_ranges, true);
-   }
-
-   /* Reallocate memory ranges if there is no space to split ranges */
-   tmem = *mem_ranges;
-   if (tmem && (tmem->nr_ranges == tmem->max_nr_ranges)) {
-   tmem = realloc_mem_ranges(mem_ranges);
-   if (!tmem)
-   goto out;
-   }
-
-   /* Exclude crashkernel region */
-   ret = crash_exclude_mem_range(tmem, crashk_res.start, crashk_res.end);
-   if (ret)
-   goto out;
-
-   /*
-* FIXME: For now, stay in parity with kexec-tools but if RTAS/OPAL
-*regions are 

[PATCH linux-next v2 3/3] powerpc/kdump: Split KEXEC_CORE and CRASH_DUMP dependency

2024-02-26 Thread Hari Bathini
Remove CONFIG_CRASH_DUMP dependency on CONFIG_KEXEC. CONFIG_KEXEC_CORE
was used at places where CONFIG_CRASH_DUMP or CONFIG_CRASH_RESERVE was
appropriate. Replace with appropriate #ifdefs to support CONFIG_KEXEC
and !CONFIG_CRASH_DUMP configuration option. Also, make CONFIG_FA_DUMP
dependent on CONFIG_CRASH_DUMP to avoid unmet dependencies for FA_DUMP
with !CONFIG_KEXEC_CORE configuration option.

Signed-off-by: Hari Bathini 
---

Changes in v2:
* Fixed a compile error for POWERNV build reported by Sourabh.

 arch/powerpc/Kconfig |  9 +--
 arch/powerpc/include/asm/kexec.h | 98 ++--
 arch/powerpc/kernel/prom.c   |  2 +-
 arch/powerpc/kernel/setup-common.c   |  2 +-
 arch/powerpc/kernel/smp.c|  4 +-
 arch/powerpc/kexec/Makefile  |  3 +-
 arch/powerpc/kexec/core.c|  4 ++
 arch/powerpc/platforms/powernv/smp.c |  2 +-
 8 files changed, 61 insertions(+), 63 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 5cf8ad8d7e8e..e377deefa2dc 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -607,11 +607,6 @@ config PPC64_SUPPORTS_MEMORY_FAILURE
 config ARCH_SUPPORTS_KEXEC
def_bool PPC_BOOK3S || PPC_E500 || (44x && !SMP)
 
-config ARCH_SELECTS_KEXEC
-   def_bool y
-   depends on KEXEC
-   select CRASH_DUMP
-
 config ARCH_SUPPORTS_KEXEC_FILE
def_bool PPC64
 
@@ -622,7 +617,6 @@ config ARCH_SELECTS_KEXEC_FILE
def_bool y
depends on KEXEC_FILE
select KEXEC_ELF
-   select CRASH_DUMP
select HAVE_IMA_KEXEC if IMA
 
 config PPC64_BIG_ENDIAN_ELF_ABI_V2
@@ -694,8 +688,7 @@ config ARCH_SELECTS_CRASH_DUMP
 
 config FA_DUMP
bool "Firmware-assisted dump"
-   depends on PPC64 && (PPC_RTAS || PPC_POWERNV)
-   select CRASH_DUMP
+   depends on CRASH_DUMP && PPC64 && (PPC_RTAS || PPC_POWERNV)
help
  A robust mechanism to get reliable kernel crash dump with
  assistance from firmware. This approach does not use kexec,
diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
index e1b43aa12175..fdb90e24dc74 100644
--- a/arch/powerpc/include/asm/kexec.h
+++ b/arch/powerpc/include/asm/kexec.h
@@ -55,59 +55,18 @@
 typedef void (*crash_shutdown_t)(void);
 
 #ifdef CONFIG_KEXEC_CORE
-
-/*
- * This function is responsible for capturing register states if coming
- * via panic or invoking dump using sysrq-trigger.
- */
-static inline void crash_setup_regs(struct pt_regs *newregs,
-   struct pt_regs *oldregs)
-{
-   if (oldregs)
-   memcpy(newregs, oldregs, sizeof(*newregs));
-   else
-   ppc_save_regs(newregs);
-}
+struct kimage;
+struct pt_regs;
 
 extern void kexec_smp_wait(void);  /* get and clear naca physid, wait for
  master to copy new code to 0 */
-extern int crashing_cpu;
-extern void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *));
-extern void crash_ipi_callback(struct pt_regs *);
-extern int crash_wake_offline;
-
-struct kimage;
-struct pt_regs;
 extern void default_machine_kexec(struct kimage *image);
-extern void default_machine_crash_shutdown(struct pt_regs *regs);
-extern int crash_shutdown_register(crash_shutdown_t handler);
-extern int crash_shutdown_unregister(crash_shutdown_t handler);
-
-extern void crash_kexec_prepare(void);
-extern void crash_kexec_secondary(struct pt_regs *regs);
-int __init overlaps_crashkernel(unsigned long start, unsigned long size);
-extern void reserve_crashkernel(void);
 extern void machine_kexec_mask_interrupts(void);
 
-static inline bool kdump_in_progress(void)
-{
-   return crashing_cpu >= 0;
-}
-
 void relocate_new_kernel(unsigned long indirection_page, unsigned long 
reboot_code_buffer,
 unsigned long start_address) __noreturn;
-
 void kexec_copy_flush(struct kimage *image);
 
-#if defined(CONFIG_CRASH_DUMP)
-bool is_kdump_kernel(void);
-#define is_kdump_kernelis_kdump_kernel
-#if defined(CONFIG_PPC_RTAS)
-void crash_free_reserved_phys_range(unsigned long begin, unsigned long end);
-#define crash_free_reserved_phys_range crash_free_reserved_phys_range
-#endif /* CONFIG_PPC_RTAS */
-#endif /* CONFIG_CRASH_DUMP */
-
 #ifdef CONFIG_KEXEC_FILE
 extern const struct kexec_file_ops kexec_elf64_ops;
 
@@ -152,15 +111,56 @@ int setup_new_fdt_ppc64(const struct kimage *image, void 
*fdt,
 
 #endif /* CONFIG_KEXEC_FILE */
 
-#else /* !CONFIG_KEXEC_CORE */
-static inline void crash_kexec_secondary(struct pt_regs *regs) { }
+#endif /* CONFIG_KEXEC_CORE */
+
+#ifdef CONFIG_CRASH_RESERVE
+int __init overlaps_crashkernel(unsigned long start, unsigned long size);
+extern void reserve_crashkernel(void);
+#else
+static inline void reserve_crashkernel(void) {}
+static inline int overlaps_crashkernel(unsigned long start, unsigned long 
size) { return 0; }
+#endif
 
-static inline int 

[PATCH linux-next v2 0/3] powerpc/kexec: split CONFIG_CRASH_DUMP out from CONFIG_KEXEC_CORE

2024-02-26 Thread Hari Bathini
This patch series is a follow-up to [1] based on discussions at [2]
about additional work needed to get it working on powerpc.

The first patch in the series makes struct crash_mem available with or
without CONFIG_CRASH_DUMP enabled. The next patch moves kdump specific
code for kexec_file_load syscall under CONFIG_CRASH_DUMP and the last
patch splits other kdump specific code under CONFIG_CRASH_DUMP and
removes dependency with CONFIG_CRASH_DUMP for CONFIG_KEXEC_CORE.

[1] https://lore.kernel.org/all/20240124051254.67105-1-...@redhat.com/
[2] 
https://lore.kernel.org/all/9101bb07-70f1-476c-bec9-ec67e9899...@linux.ibm.com/

Changes in v2:
* Fixed a compile error for POWERNV build reported by Sourabh.

Hari Bathini (3):
  kexec/kdump: make struct crash_mem available without CONFIG_CRASH_DUMP
  powerpc/kexec: split CONFIG_KEXEC_FILE and CONFIG_CRASH_DUMP
  powerpc/kdump: Split KEXEC_CORE and CRASH_DUMP dependency

 arch/powerpc/Kconfig |   9 +-
 arch/powerpc/include/asm/kexec.h |  98 +-
 arch/powerpc/kernel/prom.c   |   2 +-
 arch/powerpc/kernel/setup-common.c   |   2 +-
 arch/powerpc/kernel/smp.c|   4 +-
 arch/powerpc/kexec/Makefile  |   3 +-
 arch/powerpc/kexec/core.c|   4 +
 arch/powerpc/kexec/elf_64.c  |   4 +-
 arch/powerpc/kexec/file_load_64.c| 269 ++-
 arch/powerpc/platforms/powernv/smp.c |   2 +-
 include/linux/crash_core.h   |  12 +-
 11 files changed, 209 insertions(+), 200 deletions(-)

-- 
2.43.2



[PATCH linux-next v2 1/3] kexec/kdump: make struct crash_mem available without CONFIG_CRASH_DUMP

2024-02-26 Thread Hari Bathini
struct crash_mem defined under include/linux/crash_core.h represents
a list of memory ranges. While it is used to represent memory ranges
for kdump kernel, it can also be used for other kind of memory ranges.
In fact, KEXEC_FILE_LOAD syscall in powerpc uses this structure to
represent reserved memory ranges and exclude memory ranges needed to
find the right memory regions to load kexec kernel. So, make the
definition of crash_mem structure available for !CONFIG_CRASH_DUMP
case too.

Signed-off-by: Hari Bathini 
---

* No changes in v2.

 include/linux/crash_core.h | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h
index 23270b16e1db..d33352c2e386 100644
--- a/include/linux/crash_core.h
+++ b/include/linux/crash_core.h
@@ -8,6 +8,12 @@
 
 struct kimage;
 
+struct crash_mem {
+   unsigned int max_nr_ranges;
+   unsigned int nr_ranges;
+   struct range ranges[] __counted_by(max_nr_ranges);
+};
+
 #ifdef CONFIG_CRASH_DUMP
 
 int crash_shrink_memory(unsigned long new_size);
@@ -51,12 +57,6 @@ static inline unsigned int crash_get_elfcorehdr_size(void) { 
return 0; }
 /* Alignment required for elf header segment */
 #define ELF_CORE_HEADER_ALIGN   4096
 
-struct crash_mem {
-   unsigned int max_nr_ranges;
-   unsigned int nr_ranges;
-   struct range ranges[] __counted_by(max_nr_ranges);
-};
-
 extern int crash_exclude_mem_range(struct crash_mem *mem,
   unsigned long long mstart,
   unsigned long long mend);
-- 
2.43.2



[kvm-unit-tests PATCH 32/32] powerpc: gitlab CI update

2024-02-26 Thread Nicholas Piggin
This adds testing for the powernv machine, and adds a gitlab-ci test
group instead of specifying all tests in .gitlab-ci.yml.

Signed-off-by: Nicholas Piggin 
---
 .gitlab-ci.yml| 16 ++--
 powerpc/unittests.cfg | 15 ---
 2 files changed, 14 insertions(+), 17 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 61f196d5d..51a593021 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -69,11 +69,9 @@ build-ppc64be:
  - cd build
  - ../configure --arch=ppc64 --endian=big --cross-prefix=powerpc64-linux-gnu-
  - make -j2
- - ACCEL=tcg ./run_tests.sh
- selftest-setup selftest-migration selftest-migration-skip spapr_hcall
- rtas-get-time-of-day rtas-get-time-of-day-base rtas-set-time-of-day
- emulator
- | tee results.txt
+ - ACCEL=tcg MAX_SMP=8 ./run_tests.sh -g gitlab-ci | tee results.txt
+ - if grep -q FAIL results.txt ; then exit 1 ; fi
+ - ACCEL=tcg MAX_SMP=8 MACHINE=powernv ./run_tests.sh -g gitlab-ci | tee 
results.txt
  - if grep -q FAIL results.txt ; then exit 1 ; fi
 
 build-ppc64le:
@@ -82,11 +80,9 @@ build-ppc64le:
  - dnf install -y qemu-system-ppc gcc-powerpc64-linux-gnu nmap-ncat
  - ./configure --arch=ppc64 --endian=little --cross-prefix=powerpc64-linux-gnu-
  - make -j2
- - ACCEL=tcg ./run_tests.sh
- selftest-setup selftest-migration selftest-migration-skip spapr_hcall
- rtas-get-time-of-day rtas-get-time-of-day-base rtas-set-time-of-day
- emulator
- | tee results.txt
+ - ACCEL=tcg MAX_SMP=8 ./run_tests.sh -g gitlab-ci | tee results.txt
+ - if grep -q FAIL results.txt ; then exit 1 ; fi
+ - ACCEL=tcg MAX_SMP=8 MACHINE=powernv ./run_tests.sh -g gitlab-ci | tee 
results.txt
  - if grep -q FAIL results.txt ; then exit 1 ; fi
 
 # build-riscv32:
diff --git a/powerpc/unittests.cfg b/powerpc/unittests.cfg
index e275f389b..21071a1a1 100644
--- a/powerpc/unittests.cfg
+++ b/powerpc/unittests.cfg
@@ -34,17 +34,17 @@
 file = selftest.elf
 smp = 2
 extra_params = -m 1g -append 'setup smp=2 mem=1024'
-groups = selftest
+groups = selftest gitlab-ci
 
 [selftest-migration]
 file = selftest-migration.elf
 machine = pseries
-groups = selftest migration
+groups = selftest migration gitlab-ci
 
 [selftest-migration-skip]
 file = selftest-migration.elf
 machine = pseries
-groups = selftest migration
+groups = selftest migration gitlab-ci
 extra_params = -append "skip"
 
 # This fails due to a QEMU TCG bug so KVM-only until QEMU is fixed upstream
@@ -56,7 +56,7 @@ groups = migration
 
 [spapr_hcall]
 file = spapr_hcall.elf
-machine = pseries
+machine = pseries gitlab-ci
 
 [spapr_vpa]
 file = spapr_vpa.elf
@@ -67,24 +67,25 @@ file = rtas.elf
 machine = pseries
 timeout = 5
 extra_params = -append "get-time-of-day date=$(date +%s)"
-groups = rtas
+groups = rtas gitlab-ci
 
 [rtas-get-time-of-day-base]
 file = rtas.elf
 machine = pseries
 timeout = 5
 extra_params = -rtc base="2006-06-17" -append "get-time-of-day date=$(date 
--date="2006-06-17 UTC" +%s)"
-groups = rtas
+groups = rtas gitlab-ci
 
 [rtas-set-time-of-day]
 file = rtas.elf
 machine = pseries
 extra_params = -append "set-time-of-day"
 timeout = 5
-groups = rtas
+groups = rtas gitlab-ci
 
 [emulator]
 file = emulator.elf
+groups = gitlab-ci
 
 [interrupts]
 file = interrupts.elf
-- 
2.42.0



[kvm-unit-tests PATCH 31/32] powerpc: Remove remnants of ppc64 directory and build structure

2024-02-26 Thread Nicholas Piggin
This moves merges ppc64 directories and files into powerpc, and
merges the 3 makefiles into one.

The configure --arch=powerpc option is aliased to ppc64 for
good measure.

Signed-off-by: Nicholas Piggin 
---
 MAINTAINERS|   1 -
 configure  |   3 +-
 lib/{ppc64 => powerpc}/asm-offsets.c   |   0
 lib/{ppc64 => powerpc}/asm/asm-offsets.h   |   0
 lib/{ppc64 => powerpc}/asm/atomic.h|   0
 lib/{ppc64 => powerpc}/asm/barrier.h   |   4 +-
 lib/{ppc64 => powerpc}/asm/bitops.h|   4 +-
 lib/{ppc64 => powerpc}/asm/io.h|   4 +-
 lib/{ppc64 => powerpc}/asm/mmu.h   |   0
 lib/{ppc64 => powerpc}/asm/opal.h  |   4 +-
 lib/{ppc64 => powerpc}/asm/page.h  |   6 +-
 lib/{ppc64 => powerpc}/asm/pgtable-hwdef.h |   6 +-
 lib/{ppc64 => powerpc}/asm/pgtable.h   |   2 +-
 lib/{ppc64 => powerpc}/asm/ptrace.h|   6 +-
 lib/{ppc64 => powerpc}/asm/spinlock.h  |   6 +-
 lib/powerpc/asm/stack.h|   3 +
 lib/{ppc64 => powerpc}/asm/vpa.h   |   0
 lib/{ppc64 => powerpc}/mmu.c   |   0
 lib/{ppc64 => powerpc}/opal-calls.S|   0
 lib/{ppc64 => powerpc}/opal.c  |   0
 lib/{ppc64 => powerpc}/stack.c |   0
 lib/ppc64/.gitignore   |   1 -
 lib/ppc64/asm/handlers.h   |   1 -
 lib/ppc64/asm/hcall.h  |   1 -
 lib/ppc64/asm/memory_areas.h   |   6 --
 lib/ppc64/asm/ppc_asm.h|   1 -
 lib/ppc64/asm/processor.h  |   1 -
 lib/ppc64/asm/reg.h|   1 -
 lib/ppc64/asm/rtas.h   |   1 -
 lib/ppc64/asm/setup.h  |   1 -
 lib/ppc64/asm/smp.h|   1 -
 lib/ppc64/asm/stack.h  |  11 --
 powerpc/Makefile   | 111 -
 powerpc/Makefile.common|  95 --
 powerpc/Makefile.ppc64 |  31 --
 35 files changed, 136 insertions(+), 176 deletions(-)
 rename lib/{ppc64 => powerpc}/asm-offsets.c (100%)
 rename lib/{ppc64 => powerpc}/asm/asm-offsets.h (100%)
 rename lib/{ppc64 => powerpc}/asm/atomic.h (100%)
 rename lib/{ppc64 => powerpc}/asm/barrier.h (83%)
 rename lib/{ppc64 => powerpc}/asm/bitops.h (69%)
 rename lib/{ppc64 => powerpc}/asm/io.h (50%)
 rename lib/{ppc64 => powerpc}/asm/mmu.h (100%)
 rename lib/{ppc64 => powerpc}/asm/opal.h (90%)
 rename lib/{ppc64 => powerpc}/asm/page.h (94%)
 rename lib/{ppc64 => powerpc}/asm/pgtable-hwdef.h (93%)
 rename lib/{ppc64 => powerpc}/asm/pgtable.h (99%)
 rename lib/{ppc64 => powerpc}/asm/ptrace.h (89%)
 rename lib/{ppc64 => powerpc}/asm/spinlock.h (54%)
 rename lib/{ppc64 => powerpc}/asm/vpa.h (100%)
 rename lib/{ppc64 => powerpc}/mmu.c (100%)
 rename lib/{ppc64 => powerpc}/opal-calls.S (100%)
 rename lib/{ppc64 => powerpc}/opal.c (100%)
 rename lib/{ppc64 => powerpc}/stack.c (100%)
 delete mode 100644 lib/ppc64/.gitignore
 delete mode 100644 lib/ppc64/asm/handlers.h
 delete mode 100644 lib/ppc64/asm/hcall.h
 delete mode 100644 lib/ppc64/asm/memory_areas.h
 delete mode 100644 lib/ppc64/asm/ppc_asm.h
 delete mode 100644 lib/ppc64/asm/processor.h
 delete mode 100644 lib/ppc64/asm/reg.h
 delete mode 100644 lib/ppc64/asm/rtas.h
 delete mode 100644 lib/ppc64/asm/setup.h
 delete mode 100644 lib/ppc64/asm/smp.h
 delete mode 100644 lib/ppc64/asm/stack.h
 delete mode 100644 powerpc/Makefile.common
 delete mode 100644 powerpc/Makefile.ppc64

diff --git a/MAINTAINERS b/MAINTAINERS
index a2fa437da..1309863f2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -92,7 +92,6 @@ S: Maintained
 L: linuxppc-dev@lists.ozlabs.org
 F: powerpc/
 F: lib/powerpc/
-F: lib/ppc64/
 
 RISCV
 M: Andrew Jones 
diff --git a/configure b/configure
index 8c0e3506f..2dbc101cb 100755
--- a/configure
+++ b/configure
@@ -198,6 +198,7 @@ fi
 
 arch_name=$arch
 [ "$arch" = "aarch64" ] && arch="arm64"
+[ "$arch" = "powerpc" ] && arch="ppc64"
 [ "$arch_name" = "arm64" ] && arch_name="aarch64"
 
 if [ "$arch" = "riscv" ]; then
@@ -315,7 +316,7 @@ elif [ "$arch" = "arm" ] || [ "$arch" = "arm64" ]; then
 fi
 elif [ "$arch" = "ppc64" ]; then
 testdir=powerpc
-arch_libdir=ppc64
+arch_libdir=powerpc
 firmware="$testdir/boot_rom.bin"
 if [ "$endian" != "little" ] && [ "$endian" != "big" ]; then
 echo "You must provide endianness (big or little)!"
diff --git a/lib/ppc64/asm-offsets.c b/lib/powerpc/asm-offsets.c
similarity index 100%
rename from lib/ppc64/asm-offsets.c
rename to lib/powerpc/asm-offsets.c
diff --git a/lib/ppc64/asm/asm-offsets.h b/lib/powerpc/asm/asm-offsets.h
similarity index 100%
rename from lib/ppc64/asm/asm-offsets.h
rename to lib/powerpc/asm/asm-offsets.h
diff --git a/lib/ppc64/asm/atomic.h b/lib/powerpc/asm/atomic.h
similarity index 100%
rename from lib/ppc64/asm/atomic.h
rename to lib/powerpc/asm/atomic.h
diff --git 

[kvm-unit-tests PATCH 30/32] configure: Make arch_libdir a first-class entity

2024-02-26 Thread Nicholas Piggin
arch_libdir was brought in to improve the heuristic determination of
the lib/ directory based on arch and testdir names, but it did not
entirely clean that mess up.

Remove the arch_libdir->arch->testdir heuristic and just require
everybody sets arch_libdir correctly. Fail if the lib/arch or
lib/arch/asm directories can not be found.

Cc: Alexandru Elisei 
Cc: Andrew Jones 
Cc: Claudio Imbrenda 
Cc: David Hildenbrand 
Cc: Eric Auger 
Cc: Janosch Frank 
Cc: Laurent Vivier 
Cc: Nico Böhr 
Cc: Paolo Bonzini 
Cc: Thomas Huth 
Cc: k...@vger.kernel.org
Cc: linux-s...@vger.kernel.org
Cc: kvm...@lists.linux.dev
Cc: kvm-ri...@lists.infradead.org
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Nicholas Piggin 
---
 Makefile  |  2 +-
 configure | 18 +-
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/Makefile b/Makefile
index 4f35fffc6..4e0f54543 100644
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,7 @@ include config.mak
 VPATH = $(SRCDIR)
 
 libdirs-get = $(shell [ -d "lib/$(1)" ] && echo "lib/$(1) lib/$(1)/asm")
-ARCH_LIBDIRS := $(call libdirs-get,$(ARCH_LIBDIR)) $(call 
libdirs-get,$(TEST_DIR))
+ARCH_LIBDIRS := $(call libdirs-get,$(ARCH_LIBDIR))
 OBJDIRS := $(ARCH_LIBDIRS)
 
 DESTDIR := $(PREFIX)/share/kvm-unit-tests/
diff --git a/configure b/configure
index ae522c556..8c0e3506f 100755
--- a/configure
+++ b/configure
@@ -199,7 +199,6 @@ fi
 arch_name=$arch
 [ "$arch" = "aarch64" ] && arch="arm64"
 [ "$arch_name" = "arm64" ] && arch_name="aarch64"
-arch_libdir=$arch
 
 if [ "$arch" = "riscv" ]; then
 echo "riscv32 or riscv64 must be specified"
@@ -264,8 +263,10 @@ fi
 
 if [ "$arch" = "i386" ] || [ "$arch" = "x86_64" ]; then
 testdir=x86
+arch_libdir=x86
 elif [ "$arch" = "arm" ] || [ "$arch" = "arm64" ]; then
 testdir=arm
+arch_libdir=$arch
 if [ "$target" = "qemu" ]; then
 arm_uart_early_addr=0x0900
 elif [ "$target" = "kvmtool" ]; then
@@ -314,6 +315,7 @@ elif [ "$arch" = "arm" ] || [ "$arch" = "arm64" ]; then
 fi
 elif [ "$arch" = "ppc64" ]; then
 testdir=powerpc
+arch_libdir=ppc64
 firmware="$testdir/boot_rom.bin"
 if [ "$endian" != "little" ] && [ "$endian" != "big" ]; then
 echo "You must provide endianness (big or little)!"
@@ -324,6 +326,7 @@ elif [ "$arch" = "riscv32" ] || [ "$arch" = "riscv64" ]; 
then
 arch_libdir=riscv
 elif [ "$arch" = "s390x" ]; then
 testdir=s390x
+arch_libdir=s390x
 else
 echo "arch $arch is not supported!"
 arch=
@@ -333,6 +336,10 @@ if [ ! -d "$srcdir/$testdir" ]; then
 echo "$srcdir/$testdir does not exist!"
 exit 1
 fi
+if [ ! -d "$srcdir/lib/$arch_libdir" ]; then
+echo "$srcdir/lib/$arch_libdir does not exist!"
+exit 1
+fi
 
 if [ "$efi" = "y" ] && [ -f "$srcdir/$testdir/efi/run" ]; then
 ln -fs "$srcdir/$testdir/efi/run" $testdir-run
@@ -395,10 +402,11 @@ fi
 # link lib/asm for the architecture
 rm -f lib/asm
 asm="asm-generic"
-if [ -d "$srcdir/lib/$arch/asm" ]; then
-   asm="$srcdir/lib/$arch/asm"
-elif [ -d "$srcdir/lib/$testdir/asm" ]; then
-   asm="$srcdir/lib/$testdir/asm"
+if [ -d "$srcdir/lib/$arch_libdir/asm" ]; then
+asm="$srcdir/lib/$arch_libdir/asm"
+else
+echo "$srcdir/lib/$arch_libdir/asm does not exist"
+exit 1
 fi
 mkdir -p lib
 ln -sf "$asm" lib/asm
-- 
2.42.0



[kvm-unit-tests PATCH 29/32] configure: Fail on unknown arch

2024-02-26 Thread Nicholas Piggin
configure will accept an unknown arch, and if it is the name of a
directory in the source tree the command will silently succeed. Make
it only accept supported arch names.

Also print the full path of a missing test directory to disambiguate
the error in out of tree builds.

Cc: Alexandru Elisei 
Cc: Andrew Jones 
Cc: Claudio Imbrenda 
Cc: David Hildenbrand 
Cc: Eric Auger 
Cc: Janosch Frank 
Cc: Laurent Vivier 
Cc: Nico Böhr 
Cc: Paolo Bonzini 
Cc: Thomas Huth 
Cc: k...@vger.kernel.org
Cc: linux-s...@vger.kernel.org
Cc: kvm...@lists.linux.dev
Cc: kvm-ri...@lists.infradead.org
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Nicholas Piggin 
---
 configure | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/configure b/configure
index 6907ccbbb..ae522c556 100755
--- a/configure
+++ b/configure
@@ -45,7 +45,8 @@ usage() {
Usage: $0 [options]
 
Options include:
-   --arch=ARCHarchitecture to compile for ($arch)
+   --arch=ARCHarchitecture to compile for ($arch). ARCH 
can be one of:
+  arm, arm64, i386, ppc64, riscv32, riscv64, 
s390x, x86_64
--processor=PROCESSOR  processor to compile for ($arch)
--target=TARGETtarget platform that the tests will be 
running on (qemu or
   kvmtool, default is qemu) (arm/arm64 only)
@@ -321,11 +322,15 @@ elif [ "$arch" = "ppc64" ]; then
 elif [ "$arch" = "riscv32" ] || [ "$arch" = "riscv64" ]; then
 testdir=riscv
 arch_libdir=riscv
+elif [ "$arch" = "s390x" ]; then
+testdir=s390x
 else
-testdir=$arch
+echo "arch $arch is not supported!"
+arch=
+usage
 fi
 if [ ! -d "$srcdir/$testdir" ]; then
-echo "$testdir does not exist!"
+echo "$srcdir/$testdir does not exist!"
 exit 1
 fi
 
-- 
2.42.0



[kvm-unit-tests PATCH 28/32] powerpc: add pmu tests

2024-02-26 Thread Nicholas Piggin
Add some initial PMU testing.

- PMC5/6 tests
- PMAE / PMI test
- BHRB basic tests

Signed-off-by: Nicholas Piggin 
---
 lib/powerpc/asm/processor.h |   2 +
 lib/powerpc/asm/reg.h   |   9 +
 lib/powerpc/asm/setup.h |   1 +
 lib/powerpc/setup.c |  23 +++
 powerpc/Makefile.common |   3 +-
 powerpc/pmu.c   | 337 
 powerpc/unittests.cfg   |   3 +
 7 files changed, 377 insertions(+), 1 deletion(-)
 create mode 100644 powerpc/pmu.c

diff --git a/lib/powerpc/asm/processor.h b/lib/powerpc/asm/processor.h
index 749155696..28239c610 100644
--- a/lib/powerpc/asm/processor.h
+++ b/lib/powerpc/asm/processor.h
@@ -14,6 +14,8 @@ extern bool cpu_has_hv;
 extern bool cpu_has_power_mce;
 extern bool cpu_has_siar;
 extern bool cpu_has_heai;
+extern bool cpu_has_bhrb;
+extern bool cpu_has_p10_bhrb;
 extern bool cpu_has_radix;
 extern bool cpu_has_prefix;
 extern bool cpu_has_sc_lev;
diff --git a/lib/powerpc/asm/reg.h b/lib/powerpc/asm/reg.h
index 69ef21adb..602fba1b6 100644
--- a/lib/powerpc/asm/reg.h
+++ b/lib/powerpc/asm/reg.h
@@ -40,10 +40,19 @@
 #define SPR_LPIDR  0x13f
 #define SPR_HEIR   0x153
 #define SPR_PTCR   0x1d0
+#define SPR_MMCRA  0x312
+#define   MMCRA_BHRBRD UL(0x0020)
+#define   MMCRA_IFM_MASK   UL(0xc000)
+#define SPR_PMC5   0x317
+#define SPR_PMC6   0x318
 #define SPR_MMCR0  0x31b
 #define   MMCR0_FC UL(0x8000)
+#define   MMCR0_FCPUL(0x2000)
 #define   MMCR0_PMAE   UL(0x0400)
+#define   MMCR0_BHRBA  UL(0x0020)
+#define   MMCR0_FCPC   UL(0x1000)
 #define   MMCR0_PMAO   UL(0x0080)
+#define   MMCR0_FC56   UL(0x0010)
 #define SPR_SIAR   0x31c
 
 /* Machine State Register definitions: */
diff --git a/lib/powerpc/asm/setup.h b/lib/powerpc/asm/setup.h
index 9ca318ce6..8f0b58ed0 100644
--- a/lib/powerpc/asm/setup.h
+++ b/lib/powerpc/asm/setup.h
@@ -10,6 +10,7 @@
 #define NR_CPUS8   /* arbitrarily set for now */
 
 extern uint64_t tb_hz;
+extern uint64_t cpu_hz;
 
 #define NR_MEM_REGIONS 8
 #define MR_F_PRIMARY   (1U << 0)
diff --git a/lib/powerpc/setup.c b/lib/powerpc/setup.c
index 30b988a5c..42ba06ad1 100644
--- a/lib/powerpc/setup.c
+++ b/lib/powerpc/setup.c
@@ -32,6 +32,7 @@ u32 initrd_size;
 u32 cpu_to_hwid[NR_CPUS] = { [0 ... NR_CPUS-1] = (~0U) };
 int nr_cpus_present;
 uint64_t tb_hz;
+uint64_t cpu_hz;
 
 struct mem_region mem_regions[NR_MEM_REGIONS];
 phys_addr_t __physical_start, __physical_end;
@@ -41,6 +42,7 @@ struct cpu_set_params {
unsigned icache_bytes;
unsigned dcache_bytes;
uint64_t tb_hz;
+   uint64_t cpu_hz;
 };
 
 static void cpu_set(int fdtnode, u64 regval, void *info)
@@ -94,6 +96,22 @@ static void cpu_set(int fdtnode, u64 regval, void *info)
data = (u32 *)prop->data;
params->tb_hz = fdt32_to_cpu(*data);
 
+   prop = fdt_get_property(dt_fdt(), fdtnode,
+   "ibm,extended-clock-frequency", NULL);
+   if (prop) {
+   data = (u32 *)prop->data;
+   params->cpu_hz = fdt32_to_cpu(*data);
+   params->cpu_hz <<= 32;
+   data = (u32 *)prop->data + 1;
+   params->cpu_hz |= fdt32_to_cpu(*data);
+   } else {
+   prop = fdt_get_property(dt_fdt(), fdtnode,
+   "clock-frequency", NULL);
+   assert(prop != NULL);
+   data = (u32 *)prop->data;
+   params->cpu_hz = fdt32_to_cpu(*data);
+   }
+
read_common_info = true;
}
 }
@@ -102,6 +120,8 @@ bool cpu_has_hv;
 bool cpu_has_power_mce; /* POWER CPU machine checks */
 bool cpu_has_siar;
 bool cpu_has_heai;
+bool cpu_has_bhrb;
+bool cpu_has_p10_bhrb;
 bool cpu_has_radix;
 bool cpu_has_prefix;
 bool cpu_has_sc_lev; /* sc interrupt has LEV field in SRR1 */
@@ -118,12 +138,14 @@ static void cpu_init_params(void)
__icache_bytes = params.icache_bytes;
__dcache_bytes = params.dcache_bytes;
tb_hz = params.tb_hz;
+   cpu_hz = params.cpu_hz;
 
switch (mfspr(SPR_PVR) & PVR_VERSION_MASK) {
case PVR_VER_POWER10:
cpu_has_prefix = true;
cpu_has_sc_lev = true;
cpu_has_pause_short = true;
+   cpu_has_p10_bhrb = true;
case PVR_VER_POWER9:
cpu_has_radix = true;
case PVR_VER_POWER8E:
@@ -132,6 +154,7 @@ static void cpu_init_params(void)
cpu_has_power_mce = true;
cpu_has_heai = true;
cpu_has_siar = true;
+   cpu_has_bhrb = true;
break;
default:
break;
diff --git a/powerpc/Makefile.common 

[kvm-unit-tests PATCH 27/32] powerpc: add usermode support

2024-02-26 Thread Nicholas Piggin
The biggest difficulty for user mode is MMU support. Otherwise it is
a simple matter of setting and clearing MSR[PR] with rfid and sc
respectively.

Some common harness operations will fail in usermode, so some workarounds
are reqiured (e.g., puts() can't be used directly).

A usermode privileged instruction interrupt test is added.

Signed-off-by: Nicholas Piggin 
---
 lib/powerpc/asm/processor.h |  9 +
 lib/powerpc/asm/reg.h   |  1 +
 lib/powerpc/asm/smp.h   |  1 +
 lib/powerpc/io.c|  7 +++
 lib/powerpc/processor.c | 38 +
 lib/powerpc/rtas.c  |  3 +++
 lib/powerpc/setup.c |  8 ++--
 lib/powerpc/spinlock.c  |  4 
 lib/ppc64/mmu.c |  2 ++
 powerpc/interrupts.c| 28 +++
 10 files changed, 99 insertions(+), 2 deletions(-)

diff --git a/lib/powerpc/asm/processor.h b/lib/powerpc/asm/processor.h
index d348239c5..749155696 100644
--- a/lib/powerpc/asm/processor.h
+++ b/lib/powerpc/asm/processor.h
@@ -19,6 +19,8 @@ extern bool cpu_has_prefix;
 extern bool cpu_has_sc_lev;
 extern bool cpu_has_pause_short;
 
+bool in_usermode(void);
+
 static inline uint64_t mfspr(int nr)
 {
uint64_t ret;
@@ -51,6 +53,8 @@ static inline void local_irq_enable(void)
 {
unsigned long msr;
 
+   assert(!in_usermode());
+
asm volatile(
 "  mfmsr   %0  \n \
ori %0,%0,%1\n \
@@ -62,6 +66,8 @@ static inline void local_irq_disable(void)
 {
unsigned long msr;
 
+   assert(!in_usermode());
+
asm volatile(
 "  mfmsr   %0  \n \
andc%0,%0,%1\n \
@@ -90,4 +96,7 @@ static inline bool machine_is_pseries(void)
 void enable_mcheck(void);
 void disable_mcheck(void);
 
+void enter_usermode(void);
+void exit_usermode(void);
+
 #endif /* _ASMPOWERPC_PROCESSOR_H_ */
diff --git a/lib/powerpc/asm/reg.h b/lib/powerpc/asm/reg.h
index b2fab4313..69ef21adb 100644
--- a/lib/powerpc/asm/reg.h
+++ b/lib/powerpc/asm/reg.h
@@ -58,5 +58,6 @@
 #define MSR_SE UL(0x0400)  /* Single Step Enable */
 #define MSR_EE UL(0x8000)
 #define MSR_ME UL(0x1000)
+#define MSR_PR UL(0x4000)
 
 #endif
diff --git a/lib/powerpc/asm/smp.h b/lib/powerpc/asm/smp.h
index 820c05e9e..b96a55903 100644
--- a/lib/powerpc/asm/smp.h
+++ b/lib/powerpc/asm/smp.h
@@ -11,6 +11,7 @@ struct cpu {
unsigned long server_no;
unsigned long stack;
unsigned long exception_stack;
+   bool in_user;
secondary_entry_fn entry;
pgd_t *pgtable;
 } __attribute__((packed)); /* used by asm */
diff --git a/lib/powerpc/io.c b/lib/powerpc/io.c
index cb7f2f050..5c2810884 100644
--- a/lib/powerpc/io.c
+++ b/lib/powerpc/io.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "io.h"
 
 static struct spinlock print_lock;
@@ -41,10 +42,16 @@ void io_init(void)
 
 void puts(const char *s)
 {
+   bool user = in_usermode();
+
+   if (user)
+   exit_usermode();
spin_lock(_lock);
while (*s)
putchar(*s++);
spin_unlock(_lock);
+   if (user)
+   enter_usermode();
 }
 
 /*
diff --git a/lib/powerpc/processor.c b/lib/powerpc/processor.c
index 09f6bb9d8..6c3000d5c 100644
--- a/lib/powerpc/processor.c
+++ b/lib/powerpc/processor.c
@@ -47,6 +47,8 @@ void do_handle_exception(struct pt_regs *regs)
unsigned char v;
 
__current_cpu = (struct cpu *)mfspr(SPR_SPRG0);
+   if (in_usermode())
+   current_cpu()->in_user = false;
 
/*
 * We run with AIL=0, so interrupts taken with MMU disabled.
@@ -60,6 +62,8 @@ void do_handle_exception(struct pt_regs *regs)
 
if (v < 128 && handlers[v].func) {
handlers[v].func(regs, handlers[v].data);
+   if (regs->msr & MSR_PR)
+   current_cpu()->in_user = true;
return;
}
 
@@ -169,3 +173,37 @@ void disable_mcheck(void)
 {
rfid_msr(mfmsr() & ~MSR_ME);
 }
+
+bool in_usermode(void)
+{
+   return current_cpu()->in_user;
+}
+
+static void usermode_sc_handler(struct pt_regs *regs, void *data)
+{
+   regs->msr &= ~(MSR_PR|MSR_EE);
+   /* Interrupt return handler will keep in_user clear */
+}
+
+void enter_usermode(void)
+{
+   assert_msg(!in_usermode(), "enter_usermode called with in_usermode");
+   /* mfmsr would fault in usermode anyway */
+   assert_msg(!(mfmsr() & MSR_PR), "enter_usermode called from user mode");
+   assert_msg(!(mfmsr() & MSR_EE), "enter_usermode called with interrupts 
enabled");
+   assert_msg((mfmsr() & (MSR_IR|MSR_DR)) == (MSR_IR|MSR_DR),
+   "enter_usermode called with virtual memory disabled");
+
+   handle_exception(0xc00, usermode_sc_handler, NULL);
+   rfid_msr(mfmsr() | (MSR_PR|MSR_IR|MSR_DR|MSR_EE));
+   current_cpu()->in_user = 

[kvm-unit-tests PATCH 26/32] powerpc: Add sieve.c common test

2024-02-26 Thread Nicholas Piggin
Now that sieve copes with lack of MMU support, it can be run by
powerpc.

Signed-off-by: Nicholas Piggin 
---
 powerpc/Makefile.common | 1 +
 powerpc/sieve.c | 1 +
 powerpc/unittests.cfg   | 3 +++
 3 files changed, 5 insertions(+)
 create mode 12 powerpc/sieve.c

diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
index 5871da47a..410a675d9 100644
--- a/powerpc/Makefile.common
+++ b/powerpc/Makefile.common
@@ -8,6 +8,7 @@ tests-common = \
$(TEST_DIR)/selftest.elf \
$(TEST_DIR)/selftest-migration.elf \
$(TEST_DIR)/memory-verify.elf \
+   $(TEST_DIR)/sieve.elf \
$(TEST_DIR)/spapr_hcall.elf \
$(TEST_DIR)/rtas.elf \
$(TEST_DIR)/emulator.elf \
diff --git a/powerpc/sieve.c b/powerpc/sieve.c
new file mode 12
index 0..fe299f309
--- /dev/null
+++ b/powerpc/sieve.c
@@ -0,0 +1 @@
+../common/sieve.c
\ No newline at end of file
diff --git a/powerpc/unittests.cfg b/powerpc/unittests.cfg
index 3ebdf9dd3..008559b43 100644
--- a/powerpc/unittests.cfg
+++ b/powerpc/unittests.cfg
@@ -136,3 +136,6 @@ file = sprs.elf
 machine = pseries
 extra_params = -append '-w'
 groups = migration
+
+[sieve]
+file = sieve.elf
-- 
2.42.0



[kvm-unit-tests PATCH 25/32] common/sieve: Support machines without MMU

2024-02-26 Thread Nicholas Piggin
Not all powerpc CPUs provide MMU support. Define vm_available() that is
true by default but archs can override it. Use this to run VM tests.

Cc: Paolo Bonzini 
Cc: Thomas Huth 
Cc: Andrew Jones 
Cc: k...@vger.kernel.org
Signed-off-by: Nicholas Piggin 
---
 common/sieve.c  | 14 --
 lib/ppc64/asm/mmu.h |  1 -
 lib/ppc64/mmu.c |  2 +-
 lib/vmalloc.c   |  7 +++
 lib/vmalloc.h   |  2 ++
 5 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/common/sieve.c b/common/sieve.c
index 8fe05ef13..db084691a 100644
--- a/common/sieve.c
+++ b/common/sieve.c
@@ -40,12 +40,14 @@ int main(void)
 
 printf("starting sieve\n");
 test_sieve("static", static_data, STATIC_SIZE);
-setup_vm();
-test_sieve("mapped", static_data, STATIC_SIZE);
-for (i = 0; i < 3; ++i) {
-   v = malloc(VSIZE);
-   test_sieve("virtual", v, VSIZE);
-   free(v);
+if (vm_available()) {
+   setup_vm();
+   test_sieve("mapped", static_data, STATIC_SIZE);
+   for (i = 0; i < 3; ++i) {
+   v = malloc(VSIZE);
+   test_sieve("virtual", v, VSIZE);
+   free(v);
+   }
 }
 
 return 0;
diff --git a/lib/ppc64/asm/mmu.h b/lib/ppc64/asm/mmu.h
index fadeee4bc..eaff0f1f7 100644
--- a/lib/ppc64/asm/mmu.h
+++ b/lib/ppc64/asm/mmu.h
@@ -3,7 +3,6 @@
 
 #include 
 
-bool vm_available(void);
 bool mmu_enabled(void);
 void mmu_enable(pgd_t *pgtable);
 void mmu_disable(void);
diff --git a/lib/ppc64/mmu.c b/lib/ppc64/mmu.c
index 6adf94151..f1219033a 100644
--- a/lib/ppc64/mmu.c
+++ b/lib/ppc64/mmu.c
@@ -24,7 +24,7 @@
 
 static pgd_t *identity_pgd;
 
-bool vm_available(void)
+bool vm_available(void) /* weak override */
 {
return cpu_has_radix;
 }
diff --git a/lib/vmalloc.c b/lib/vmalloc.c
index 572682576..cf2ef7a70 100644
--- a/lib/vmalloc.c
+++ b/lib/vmalloc.c
@@ -206,10 +206,17 @@ void init_alloc_vpage(void *top)
spin_unlock();
 }
 
+bool __attribute__((__weak__)) vm_available(void)
+{
+   return true;
+}
+
 void __setup_vm(void *opaque)
 {
phys_addr_t base, top;
 
+   assert_msg(vm_available(), "Virtual memory not available. Must check 
vm_available() before calling setup_vm()");
+
if (alloc_ops == _ops)
return;
 
diff --git a/lib/vmalloc.h b/lib/vmalloc.h
index 0269fdde9..e81be39f4 100644
--- a/lib/vmalloc.h
+++ b/lib/vmalloc.h
@@ -17,6 +17,8 @@ extern void setup_vm(void);
 /* As above, plus passes an opaque value to setup_mmu(). */
 extern void __setup_vm(void *opaque);
 
+/* common/ tests must check availability before calling setup_vm() */
+extern bool vm_available(void);
 /* Set up paging */
 extern void *setup_mmu(phys_addr_t top, void *opaque);
 /* Walk the page table and resolve the virtual address to a physical address */
-- 
2.42.0



[kvm-unit-tests PATCH 24/32] common/sieve: Use vmalloc.h for setup_mmu definition

2024-02-26 Thread Nicholas Piggin
There is no good reason to put setup_vm in libcflat.h when it's
defined in vmalloc.h.

Cc: Paolo Bonzini 
Cc: Thomas Huth 
Cc: Andrew Jones 
Cc: Janosch Frank 
Cc: Claudio Imbrenda 
Cc: Nico Böhr 
Cc: David Hildenbrand 
Cc: k...@vger.kernel.org
Cc: linux-s...@vger.kernel.org
Signed-off-by: Nicholas Piggin 
---
 common/sieve.c | 1 +
 lib/libcflat.h | 2 --
 lib/s390x/io.c | 1 +
 lib/s390x/uv.h | 1 +
 lib/x86/vm.h   | 1 +
 s390x/mvpg.c   | 1 +
 s390x/selftest.c   | 1 +
 x86/pmu.c  | 1 +
 x86/pmu_lbr.c  | 1 +
 x86/vmexit.c   | 1 +
 x86/vmware_backdoors.c | 1 +
 11 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/common/sieve.c b/common/sieve.c
index 8150f2d98..8fe05ef13 100644
--- a/common/sieve.c
+++ b/common/sieve.c
@@ -1,5 +1,6 @@
 #include "alloc.h"
 #include "libcflat.h"
+#include "vmalloc.h"
 
 static int sieve(char* data, int size)
 {
diff --git a/lib/libcflat.h b/lib/libcflat.h
index 700f43527..8c8dd0286 100644
--- a/lib/libcflat.h
+++ b/lib/libcflat.h
@@ -152,8 +152,6 @@ do {
\
 void binstr(unsigned long x, char out[BINSTR_SZ]);
 void print_binstr(unsigned long x);
 
-extern void setup_vm(void);
-
 #endif /* !__ASSEMBLY__ */
 
 #define SZ_256 (1 << 8)
diff --git a/lib/s390x/io.c b/lib/s390x/io.c
index fb7b7ddaa..2b28ccaa0 100644
--- a/lib/s390x/io.c
+++ b/lib/s390x/io.c
@@ -10,6 +10,7 @@
  */
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
diff --git a/lib/s390x/uv.h b/lib/s390x/uv.h
index 286933caa..00a370410 100644
--- a/lib/s390x/uv.h
+++ b/lib/s390x/uv.h
@@ -4,6 +4,7 @@
 
 #include 
 #include 
+#include 
 
 bool uv_os_is_guest(void);
 bool uv_os_is_host(void);
diff --git a/lib/x86/vm.h b/lib/x86/vm.h
index 4b714bad7..cf39787aa 100644
--- a/lib/x86/vm.h
+++ b/lib/x86/vm.h
@@ -2,6 +2,7 @@
 #define _X86_VM_H_
 
 #include "processor.h"
+#include "vmalloc.h"
 #include "asm/page.h"
 #include "asm/io.h"
 #include "asm/bitops.h"
diff --git a/s390x/mvpg.c b/s390x/mvpg.c
index 296338d4f..a0cfc575a 100644
--- a/s390x/mvpg.c
+++ b/s390x/mvpg.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
diff --git a/s390x/selftest.c b/s390x/selftest.c
index 92ed4e5d3..3eaae9b06 100644
--- a/s390x/selftest.c
+++ b/s390x/selftest.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
diff --git a/x86/pmu.c b/x86/pmu.c
index 47a1a602a..7062c1ad9 100644
--- a/x86/pmu.c
+++ b/x86/pmu.c
@@ -6,6 +6,7 @@
 #include "x86/apic.h"
 #include "x86/desc.h"
 #include "x86/isr.h"
+#include "vmalloc.h"
 #include "alloc.h"
 
 #include "libcflat.h"
diff --git a/x86/pmu_lbr.c b/x86/pmu_lbr.c
index 40b63fa3d..c6f010847 100644
--- a/x86/pmu_lbr.c
+++ b/x86/pmu_lbr.c
@@ -2,6 +2,7 @@
 #include "x86/processor.h"
 #include "x86/pmu.h"
 #include "x86/desc.h"
+#include "vmalloc.h"
 
 #define N 100
 
diff --git a/x86/vmexit.c b/x86/vmexit.c
index eb5d3023a..48a38f60f 100644
--- a/x86/vmexit.c
+++ b/x86/vmexit.c
@@ -1,6 +1,7 @@
 #include "libcflat.h"
 #include "acpi.h"
 #include "smp.h"
+#include "vmalloc.h"
 #include "pci.h"
 #include "x86/vm.h"
 #include "x86/desc.h"
diff --git a/x86/vmware_backdoors.c b/x86/vmware_backdoors.c
index bc1002056..f8cf7ecb1 100644
--- a/x86/vmware_backdoors.c
+++ b/x86/vmware_backdoors.c
@@ -6,6 +6,7 @@
 #include "x86/desc.h"
 #include "x86/isr.h"
 #include "alloc.h"
+#include "vmalloc.h"
 #include "setjmp.h"
 #include "usermode.h"
 #include "fault_test.h"
-- 
2.42.0



[kvm-unit-tests PATCH 23/32] powerpc: Add MMU support

2024-02-26 Thread Nicholas Piggin
Add support for radix MMU, 4kB and 64kB pages.

This also adds MMU interrupt test cases, and runs the interrupts
test entirely with MMU enabled if it is available (aside from
machine check tests).

Signed-off-by: Nicholas Piggin 
---
 configure |  39 +++--
 lib/powerpc/asm/hcall.h   |   6 +
 lib/powerpc/asm/processor.h   |   1 +
 lib/powerpc/asm/reg.h |   3 +
 lib/powerpc/asm/smp.h |   2 +
 lib/powerpc/processor.c   |   9 ++
 lib/powerpc/setup.c   |   4 +
 lib/ppc64/asm/mmu.h   |  11 ++
 lib/ppc64/asm/page.h  |  67 -
 lib/ppc64/asm/pgtable-hwdef.h |  67 +
 lib/ppc64/asm/pgtable.h   | 126 
 lib/ppc64/mmu.c   | 273 ++
 lib/ppc64/opal-calls.S|   4 +-
 powerpc/Makefile.common   |   2 +
 powerpc/Makefile.ppc64|   1 +
 powerpc/interrupts.c  |  96 ++--
 16 files changed, 684 insertions(+), 27 deletions(-)
 create mode 100644 lib/ppc64/asm/mmu.h
 create mode 100644 lib/ppc64/asm/pgtable-hwdef.h
 create mode 100644 lib/ppc64/asm/pgtable.h
 create mode 100644 lib/ppc64/mmu.c

diff --git a/configure b/configure
index 05e6702ea..6907ccbbb 100755
--- a/configure
+++ b/configure
@@ -222,29 +222,35 @@ fi
 if [ -z "$page_size" ]; then
 if [ "$efi" = 'y' ] && [ "$arch" = "arm64" ]; then
 page_size="4096"
-elif [ "$arch" = "arm64" ]; then
+elif [ "$arch" = "arm64" ] || [ "$arch" = "ppc64" ]; then
 page_size="65536"
 elif [ "$arch" = "arm" ]; then
 page_size="4096"
 fi
 else
-if [ "$arch" != "arm64" ]; then
-echo "--page-size is not supported for $arch"
-usage
-fi
-
 if [ "${page_size: -1}" = "K" ] || [ "${page_size: -1}" = "k" ]; then
 page_size=$(( ${page_size%?} * 1024 ))
 fi
-if [ "$page_size" != "4096" ] && [ "$page_size" != "16384" ] &&
-   [ "$page_size" != "65536" ]; then
-echo "arm64 doesn't support page size of $page_size"
+
+if [ "$arch" = "arm64" ]; then
+if [ "$page_size" != "4096" ] && [ "$page_size" != "16384" ] &&
+   [ "$page_size" != "65536" ]; then
+echo "arm64 doesn't support page size of $page_size"
+usage
+fi
+if [ "$efi" = 'y' ] && [ "$page_size" != "4096" ]; then
+echo "efi must use 4K pages"
+exit 1
+fi
+elif [ "$arch" = "ppc64" ]; then
+if [ "$page_size" != "4096" ] && [ "$page_size" != "65536" ]; then
+echo "ppc64 doesn't support page size of $page_size"
+usage
+fi
+else
+echo "--page-size is not supported for $arch"
 usage
 fi
-if [ "$efi" = 'y' ] && [ "$page_size" != "4096" ]; then
-echo "efi must use 4K pages"
-exit 1
-fi
 fi
 
 [ -z "$processor" ] && processor="$arch"
@@ -444,6 +450,13 @@ cat <> lib/config.h
 
 #define CONFIG_UART_EARLY_BASE ${arm_uart_early_addr}
 #define CONFIG_ERRATA_FORCE ${errata_force}
+
+EOF
+fi
+
+if [ "$arch" = "arm" ] || [ "$arch" = "arm64" ] || [ "$arch" = "ppc64" ]; then
+cat <> lib/config.h
+
 #define CONFIG_PAGE_SIZE _AC(${page_size}, UL)
 
 EOF
diff --git a/lib/powerpc/asm/hcall.h b/lib/powerpc/asm/hcall.h
index e0f5009e3..3b44dd204 100644
--- a/lib/powerpc/asm/hcall.h
+++ b/lib/powerpc/asm/hcall.h
@@ -24,6 +24,12 @@
 #define H_PUT_TERM_CHAR0x58
 #define H_RANDOM   0x300
 #define H_SET_MODE 0x31C
+#define H_REGISTER_PROCESS_TABLE   0x37C
+
+#define PTBL_NEW   0x18
+#define PTBL_UNREGISTER0x10
+#define PTBL_RADIX 0x04
+#define PTBL_GTSE  0x01
 
 #define KVMPPC_HCALL_BASE  0xf000
 #define KVMPPC_H_RTAS  (KVMPPC_HCALL_BASE + 0x0)
diff --git a/lib/powerpc/asm/processor.h b/lib/powerpc/asm/processor.h
index a3859b5d4..d348239c5 100644
--- a/lib/powerpc/asm/processor.h
+++ b/lib/powerpc/asm/processor.h
@@ -14,6 +14,7 @@ extern bool cpu_has_hv;
 extern bool cpu_has_power_mce;
 extern bool cpu_has_siar;
 extern bool cpu_has_heai;
+extern bool cpu_has_radix;
 extern bool cpu_has_prefix;
 extern bool cpu_has_sc_lev;
 extern bool cpu_has_pause_short;
diff --git a/lib/powerpc/asm/reg.h b/lib/powerpc/asm/reg.h
index 12f9e8ac6..b2fab4313 100644
--- a/lib/powerpc/asm/reg.h
+++ b/lib/powerpc/asm/reg.h
@@ -11,6 +11,7 @@
 #define SPR_SRR0   0x01a
 #define SPR_SRR1   0x01b
 #define   SRR1_PREFIX  UL(0x2000)
+#define SPR_PIDR   0x030
 #define SPR_FSCR   0x099
 #define   FSCR_PREFIX  UL(0x2000)
 #define SPR_HFSCR  0x0be
@@ -36,7 +37,9 @@
 #define SPR_LPCR   0x13e
 #define   LPCR_HDICE   UL(0x1)
 #define   LPCR_LD  UL(0x2)
+#define SPR_LPIDR  0x13f
 #define SPR_HEIR   0x153
+#define SPR_PTCR   0x1d0
 #define SPR_MMCR0  0x31b
 #define   MMCR0_FC UL(0x8000)
 #define   MMCR0_PMAE   UL(0x0400)
diff --git 

[kvm-unit-tests PATCH 22/32] powerpc: Add timebase tests

2024-02-26 Thread Nicholas Piggin
This has a known failure on QEMU TCG machines where the decrementer
interrupt is not lowered when the DEC wraps from -ve to +ve.

Signed-off-by: Nicholas Piggin 
---
 lib/powerpc/asm/reg.h   |   1 +
 powerpc/Makefile.common |   1 +
 powerpc/timebase.c  | 330 
 powerpc/unittests.cfg   |   8 +
 4 files changed, 340 insertions(+)
 create mode 100644 powerpc/timebase.c

diff --git a/lib/powerpc/asm/reg.h b/lib/powerpc/asm/reg.h
index d2ca964c4..12f9e8ac6 100644
--- a/lib/powerpc/asm/reg.h
+++ b/lib/powerpc/asm/reg.h
@@ -35,6 +35,7 @@
 #define SPR_HSRR1  0x13b
 #define SPR_LPCR   0x13e
 #define   LPCR_HDICE   UL(0x1)
+#define   LPCR_LD  UL(0x2)
 #define SPR_HEIR   0x153
 #define SPR_MMCR0  0x31b
 #define   MMCR0_FC UL(0x8000)
diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
index b6f9b3b85..1348f658b 100644
--- a/powerpc/Makefile.common
+++ b/powerpc/Makefile.common
@@ -15,6 +15,7 @@ tests-common = \
$(TEST_DIR)/tm.elf \
$(TEST_DIR)/smp.elf \
$(TEST_DIR)/sprs.elf \
+   $(TEST_DIR)/timebase.elf \
$(TEST_DIR)/interrupts.elf
 
 tests-all = $(tests-common) $(tests)
diff --git a/powerpc/timebase.c b/powerpc/timebase.c
new file mode 100644
index 0..6d8d54cb1
--- /dev/null
+++ b/powerpc/timebase.c
@@ -0,0 +1,330 @@
+/*
+ * Test Timebase
+ *
+ * Copyright 2024 Nicholas Piggin, IBM Corp.
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ *
+ * This contains tests of timebase facility, TB, DEC, etc.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int dec_bits = 0;
+
+static void cpu_dec_bits(int fdtnode, u64 regval __unused, void *arg __unused)
+{
+   const struct fdt_property *prop;
+   int plen;
+
+   prop = fdt_get_property(dt_fdt(), fdtnode, "ibm,dec-bits", );
+   if (!prop) {
+   dec_bits = 32;
+   return;
+   }
+
+   /* Sanity check for the property layout (first two bytes are header) */
+   assert(plen == 4);
+
+   dec_bits = fdt32_to_cpu(*(uint32_t *)prop->data);
+}
+
+/* Check amount of CPUs nodes that have the TM flag */
+static int find_dec_bits(void)
+{
+   int ret;
+
+   ret = dt_for_each_cpu_node(cpu_dec_bits, NULL);
+   if (ret < 0)
+   return ret;
+
+   return dec_bits;
+}
+
+
+static bool do_migrate = false;
+static volatile bool got_interrupt;
+static volatile struct pt_regs recorded_regs;
+
+static uint64_t dec_max;
+static uint64_t dec_min;
+
+static void test_tb(int argc, char **argv)
+{
+   uint64_t tb;
+
+   tb = get_tb();
+   if (do_migrate)
+   migrate();
+   report(get_tb() >= tb, "timebase is incrementing");
+}
+
+static void dec_stop_handler(struct pt_regs *regs, void *data)
+{
+   mtspr(SPR_DEC, dec_max);
+}
+
+static void dec_handler(struct pt_regs *regs, void *data)
+{
+   got_interrupt = true;
+   memcpy((void *)_regs, regs, sizeof(struct pt_regs));
+   regs->msr &= ~MSR_EE;
+}
+
+static void test_dec(int argc, char **argv)
+{
+   uint64_t tb1, tb2, dec;
+   int i;
+
+   handle_exception(0x900, _handler, NULL);
+
+   for (i = 0; i < 100; i++) {
+   tb1 = get_tb();
+   mtspr(SPR_DEC, dec_max);
+   dec = mfspr(SPR_DEC);
+   tb2 = get_tb();
+   if (tb2 - tb1 < dec_max - dec)
+   break;
+   }
+   report(tb2 - tb1 >= dec_max - dec, "decrementer remains within TB after 
mtDEC");
+
+   tb1 = get_tb();
+   mtspr(SPR_DEC, dec_max);
+   mdelay(1000);
+   dec = mfspr(SPR_DEC);
+   tb2 = get_tb();
+   report(tb2 - tb1 >= dec_max - dec, "decrementer remains within TB after 
1s");
+
+   mtspr(SPR_DEC, dec_max);
+   local_irq_enable();
+   local_irq_disable();
+   if (mfspr(SPR_DEC) <= dec_max) {
+   report(!got_interrupt, "no interrupt on decrementer positive");
+   }
+   got_interrupt = false;
+
+   mtspr(SPR_DEC, 1);
+   mdelay(100); /* Give the timer a chance to run */
+   if (do_migrate)
+   migrate();
+   local_irq_enable();
+   local_irq_disable();
+   report(got_interrupt, "interrupt on decrementer underflow");
+   got_interrupt = false;
+
+   if (do_migrate)
+   migrate();
+   local_irq_enable();
+   local_irq_disable();
+   report(got_interrupt, "interrupt on decrementer still underflown");
+   got_interrupt = false;
+
+   mtspr(SPR_DEC, 0);
+   mdelay(100); /* Give the timer a chance to run */
+   if (do_migrate)
+   migrate();
+   local_irq_enable();
+   local_irq_disable();
+   report(got_interrupt, "DEC deal with set to 0");
+   got_interrupt = false;
+
+   /* Test for level-triggered decrementer */
+   mtspr(SPR_DEC, -1ULL);
+

[kvm-unit-tests PATCH 21/32] powerpc: Add atomics tests

2024-02-26 Thread Nicholas Piggin
Signed-off-by: Nicholas Piggin 
---
 powerpc/Makefile.common |   1 +
 powerpc/atomics.c   | 373 
 powerpc/unittests.cfg   |   9 +
 3 files changed, 383 insertions(+)
 create mode 100644 powerpc/atomics.c

diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
index 02af54b83..b6f9b3b85 100644
--- a/powerpc/Makefile.common
+++ b/powerpc/Makefile.common
@@ -11,6 +11,7 @@ tests-common = \
$(TEST_DIR)/spapr_hcall.elf \
$(TEST_DIR)/rtas.elf \
$(TEST_DIR)/emulator.elf \
+   $(TEST_DIR)/atomics.elf \
$(TEST_DIR)/tm.elf \
$(TEST_DIR)/smp.elf \
$(TEST_DIR)/sprs.elf \
diff --git a/powerpc/atomics.c b/powerpc/atomics.c
new file mode 100644
index 0..d79e70eaa
--- /dev/null
+++ b/powerpc/atomics.c
@@ -0,0 +1,373 @@
+/*
+ * Test some powerpc instructions
+ *
+ * Copyright 2024 Nicholas Piggin, IBM Corp.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static bool do_migrate;
+static bool do_record;
+
+#define RSV_SIZE 128
+
+static uint8_t granule[RSV_SIZE] __attribute((__aligned__(RSV_SIZE)));
+
+static void spin_lock(unsigned int *lock)
+{
+   unsigned int old;
+
+   asm volatile ("1:"
+ "lwarx%0,0,%2;"
+ "cmpwi%0,0;"
+ "bne  1b;"
+ "stwcx.   %1,0,%2;"
+ "bne- 1b;"
+ "lwsync;"
+ : "="(old) : "r"(1), "r"(lock) : "cr0", "memory");
+}
+
+static void spin_unlock(unsigned int *lock)
+{
+   asm volatile("lwsync;"
+"stw   %1,%0;"
+: "+m"(*lock) : "r"(0) : "memory");
+}
+
+static volatile bool got_interrupt;
+static volatile struct pt_regs recorded_regs;
+
+static void interrupt_handler(struct pt_regs *regs, void *opaque)
+{
+   assert(!got_interrupt);
+   got_interrupt = true;
+   memcpy((void *)_regs, regs, sizeof(struct pt_regs));
+   regs_advance_insn(regs);
+}
+
+static void test_lwarx_stwcx(int argc, char *argv[])
+{
+   unsigned int *var = (unsigned int *)granule;
+   unsigned int old;
+   unsigned int result;
+
+   *var = 0;
+   asm volatile ("1:"
+ "lwarx%0,0,%2;"
+ "stwcx.   %1,0,%2;"
+ "bne- 1b;"
+ : "="(old) : "r"(1), "r"(var) : "cr0", "memory");
+   report(old == 0 && *var == 1, "simple update");
+
+   *var = 0;
+   asm volatile ("li   %0,0;"
+ "stwcx.   %1,0,%2;"
+ "stwcx.   %1,0,%2;"
+ "bne- 1f;"
+ "li   %0,1;"
+ "1:"
+ : "="(result)
+ : "r"(1), "r"(var) : "cr0", "memory");
+   report(result == 0 && *var == 0, "failed stwcx. (no reservation)");
+
+   *var = 0;
+   asm volatile ("li   %0,0;"
+ "lwarx%1,0,%4;"
+ "stw  %3,0(%4);"
+ "stwcx.   %2,0,%4;"
+ "bne- 1f;"
+ "li   %0,1;"
+ "1:"
+ : "="(result), "="(old)
+ : "r"(1), "r"(2), "r"(var) : "cr0", "memory");
+   /* This is implementation specific, so don't fail */
+   if (result == 0 && *var == 2)
+   report(true, "failed stwcx. (intervening store)");
+   else
+   report(true, "succeeded stwcx. (intervening store)");
+
+   handle_exception(0x600, interrupt_handler, NULL);
+   handle_exception(0x700, interrupt_handler, NULL);
+
+   /* Implementations may not necessarily invoke the alignment interrupt */
+   old = 10;
+   *var = 0;
+   asm volatile (
+ "lwarx%0,0,%1;"
+ : "+"(old) : "r"((char *)var + 1));
+   report(old == 10 && got_interrupt && recorded_regs.trap == 0x600, 
"unaligned lwarx causes fault");
+   got_interrupt = false;
+
+   /*
+* Unaligned stwcx. is more difficult to test, at least under QEMU,
+* the store does not proceed if there is no matching reservation, so
+* the alignment handler does not get invoked. This is okay according
+* to the Power ISA (unalignment does not necessarily invoke the
+* alignment interrupt). But POWER CPUs do cause alignment interrupt.
+*/
+   *var = 0;
+   asm volatile (
+ "lwarx%0,0,%2;"
+ "stwcx.   %1,0,%3;"
+ : "="(old) : "r"(1), "r"(var), "r"((char *)var+1) : 
"cr0", "memory");
+   report(old == 0 && *var == 0 && got_interrupt && recorded_regs.trap == 
0x600, "unaligned stwcx. causes fault");
+   got_interrupt = false;
+
+   handle_exception(0x600, NULL, NULL);
+
+}
+
+static void test_lqarx_stqcx(int argc, char *argv[])
+{
+   

[kvm-unit-tests PATCH 20/32] powerpc: Avoid using larx/stcx. in spinlocks when only one CPU is running

2024-02-26 Thread Nicholas Piggin
The test harness uses spinlocks if they are implemented with larx/stcx.
it can prevent some test scenarios such as testing migration of a
reservation.

Signed-off-by: Nicholas Piggin 
---
 lib/powerpc/asm/smp.h|  1 +
 lib/powerpc/smp.c|  5 +
 lib/powerpc/spinlock.c   | 28 
 lib/ppc64/asm/spinlock.h |  7 ++-
 powerpc/Makefile.common  |  1 +
 5 files changed, 41 insertions(+), 1 deletion(-)
 create mode 100644 lib/powerpc/spinlock.c

diff --git a/lib/powerpc/asm/smp.h b/lib/powerpc/asm/smp.h
index 4519e5436..6ef3ae521 100644
--- a/lib/powerpc/asm/smp.h
+++ b/lib/powerpc/asm/smp.h
@@ -15,6 +15,7 @@ struct cpu {
 
 extern int nr_cpus_present;
 extern int nr_cpus_online;
+extern bool multithreaded;
 extern struct cpu cpus[];
 
 register struct cpu *__current_cpu asm("r13");
diff --git a/lib/powerpc/smp.c b/lib/powerpc/smp.c
index a3bf85d44..f3b2a3faf 100644
--- a/lib/powerpc/smp.c
+++ b/lib/powerpc/smp.c
@@ -276,6 +276,8 @@ static void start_each_secondary(int fdtnode, u64 regval 
__unused, void *info)
start_core(fdtnode, datap->entry);
 }
 
+bool multithreaded = false;
+
 /*
  * Start all stopped cpus on the guest at entry with register 3 set to r3
  * We expect that we come in with only one thread currently started
@@ -290,6 +292,7 @@ bool start_all_cpus(secondary_entry_fn entry)
 
assert(nr_cpus_online == 1);
assert(nr_started == 1);
+   multithreaded = true;
ret = dt_for_each_cpu_node(start_each_secondary, );
assert(ret == 0);
assert(nr_started == nr_cpus_present);
@@ -308,8 +311,10 @@ bool start_all_cpus(secondary_entry_fn entry)
 
 void stop_all_cpus(void)
 {
+   assert(multithreaded);
while (nr_cpus_online > 1)
cpu_relax();
mb();
nr_started = 1;
+   multithreaded = false;
 }
diff --git a/lib/powerpc/spinlock.c b/lib/powerpc/spinlock.c
new file mode 100644
index 0..238549f12
--- /dev/null
+++ b/lib/powerpc/spinlock.c
@@ -0,0 +1,28 @@
+#include 
+#include 
+
+/*
+ * Skip the atomic when single-threaded, which helps avoid larx/stcx. in
+ * the harness when testing tricky larx/stcx. sequences (e.g., migration
+ * vs reservation).
+ */
+void spin_lock(struct spinlock *lock)
+{
+   if (!multithreaded) {
+   assert(lock->v == 0);
+   lock->v = 1;
+   } else {
+   while (__sync_lock_test_and_set(>v, 1))
+   ;
+   }
+}
+
+void spin_unlock(struct spinlock *lock)
+{
+   assert(lock->v == 1);
+   if (!multithreaded) {
+   lock->v = 0;
+   } else {
+   __sync_lock_release(>v);
+   }
+}
diff --git a/lib/ppc64/asm/spinlock.h b/lib/ppc64/asm/spinlock.h
index f59eed191..b952386da 100644
--- a/lib/ppc64/asm/spinlock.h
+++ b/lib/ppc64/asm/spinlock.h
@@ -1,6 +1,11 @@
 #ifndef _ASMPPC64_SPINLOCK_H_
 #define _ASMPPC64_SPINLOCK_H_
 
-#include 
+struct spinlock {
+   unsigned int v;
+};
+
+void spin_lock(struct spinlock *lock);
+void spin_unlock(struct spinlock *lock);
 
 #endif /* _ASMPPC64_SPINLOCK_H_ */
diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
index 744dfc1f7..02af54b83 100644
--- a/powerpc/Makefile.common
+++ b/powerpc/Makefile.common
@@ -48,6 +48,7 @@ cflatobjs += lib/powerpc/rtas.o
 cflatobjs += lib/powerpc/processor.o
 cflatobjs += lib/powerpc/handlers.o
 cflatobjs += lib/powerpc/smp.o
+cflatobjs += lib/powerpc/spinlock.o
 
 OBJDIRS += lib/powerpc
 
-- 
2.42.0



[kvm-unit-tests PATCH 19/32] powerpc: Permit ACCEL=tcg,thread=single

2024-02-26 Thread Nicholas Piggin
Modify run script to permit single vs mttcg threading, add a
thread=single smp case to unittests.cfg.

Signed-off-by: Nicholas Piggin 
---
 powerpc/run   | 4 ++--
 powerpc/unittests.cfg | 6 ++
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/powerpc/run b/powerpc/run
index 172f32a46..27abf1ef6 100755
--- a/powerpc/run
+++ b/powerpc/run
@@ -36,8 +36,8 @@ if ! $qemu -machine '?' 2>&1 | grep $MACHINE > /dev/null; then
exit 2
 fi
 
+A="-accel $ACCEL$ACCEL_PROPS"
 M="-machine $MACHINE"
-M+=",accel=$ACCEL$ACCEL_PROPS"
 B=""
 D=""
 
@@ -54,7 +54,7 @@ if [[ "$MACHINE" == "powernv"* ]] ; then
D+="-device ipmi-bmc-sim,id=bmc0 -device isa-ipmi-bt,bmc=bmc0,irq=10"
 fi
 
-command="$qemu -nodefaults $M $B $D"
+command="$qemu -nodefaults $A $M $B $D"
 command+=" -display none -serial stdio -kernel"
 command="$(migration_cmd) $(timeout_cmd) $command"
 
diff --git a/powerpc/unittests.cfg b/powerpc/unittests.cfg
index 97a549c0d..915b6a482 100644
--- a/powerpc/unittests.cfg
+++ b/powerpc/unittests.cfg
@@ -97,6 +97,12 @@ smp = 2
 file = smp.elf
 smp = 8,threads=4
 
+# mttcg is the default most places, so add a thread=single test
+[smp-thread-single]
+file = smp.elf
+smp = 8,threads=4
+accel = tcg,thread=single
+
 [h_cede_tm]
 file = tm.elf
 machine = pseries
-- 
2.42.0



[kvm-unit-tests PATCH 18/32] powerpc: add SMP and IPI support

2024-02-26 Thread Nicholas Piggin
powerpc SMP support is very primitive and does not set up a first-class
runtime environment for secondary CPUs.

This reworks SMP support, and provides a complete C and harness
environment for the secondaries, including interrupt handling, as well
as IPI support.

Signed-off-by: Nicholas Piggin 
---
 lib/powerpc/asm/processor.h |  23 +++
 lib/powerpc/asm/reg.h   |   1 +
 lib/powerpc/asm/setup.h |   2 -
 lib/powerpc/asm/smp.h   |  46 +++--
 lib/powerpc/io.c|  15 +-
 lib/powerpc/processor.c |   7 +-
 lib/powerpc/setup.c |  90 +++---
 lib/powerpc/smp.c   | 282 +
 lib/ppc64/asm-offsets.c |   7 +
 lib/ppc64/asm/atomic.h  |   6 +
 lib/ppc64/asm/barrier.h |   3 +
 lib/ppc64/asm/opal.h|   7 +
 powerpc/Makefile.common |   1 +
 powerpc/cstart64.S  |  52 +-
 powerpc/selftest.c  |   4 +-
 powerpc/smp.c   | 349 
 powerpc/tm.c|   4 +-
 powerpc/unittests.cfg   |   8 +
 18 files changed, 822 insertions(+), 85 deletions(-)
 create mode 100644 lib/ppc64/asm/atomic.h
 create mode 100644 powerpc/smp.c

diff --git a/lib/powerpc/asm/processor.h b/lib/powerpc/asm/processor.h
index eed37d1f4..a3859b5d4 100644
--- a/lib/powerpc/asm/processor.h
+++ b/lib/powerpc/asm/processor.h
@@ -16,6 +16,7 @@ extern bool cpu_has_siar;
 extern bool cpu_has_heai;
 extern bool cpu_has_prefix;
 extern bool cpu_has_sc_lev;
+extern bool cpu_has_pause_short;
 
 static inline uint64_t mfspr(int nr)
 {
@@ -45,6 +46,28 @@ static inline void mtmsr(uint64_t msr)
asm volatile ("mtmsrd %[msr]" :: [msr] "r" (msr) : "memory");
 }
 
+static inline void local_irq_enable(void)
+{
+   unsigned long msr;
+
+   asm volatile(
+"  mfmsr   %0  \n \
+   ori %0,%0,%1\n \
+   mtmsrd  %0,1"
+   : "=r"(msr) : "i"(MSR_EE): "memory");
+}
+
+static inline void local_irq_disable(void)
+{
+   unsigned long msr;
+
+   asm volatile(
+"  mfmsr   %0  \n \
+   andc%0,%0,%1\n \
+   mtmsrd  %0,1"
+   : "=r"(msr) : "r"(MSR_EE): "memory");
+}
+
 /*
  * This returns true on PowerNV / OPAL machines which run in hypervisor
  * mode. False on pseries / PAPR machines that run in guest mode.
diff --git a/lib/powerpc/asm/reg.h b/lib/powerpc/asm/reg.h
index d6097f48f..d2ca964c4 100644
--- a/lib/powerpc/asm/reg.h
+++ b/lib/powerpc/asm/reg.h
@@ -19,6 +19,7 @@
 #define SPR_SPRG1  0x111
 #define SPR_SPRG2  0x112
 #define SPR_SPRG3  0x113
+#define SPR_TBU40  0x11e
 #define SPR_PVR0x11f
 #define   PVR_VERSION_MASK UL(0x)
 #define   PVR_VER_970  UL(0x0039)
diff --git a/lib/powerpc/asm/setup.h b/lib/powerpc/asm/setup.h
index cc7cf5e25..9ca318ce6 100644
--- a/lib/powerpc/asm/setup.h
+++ b/lib/powerpc/asm/setup.h
@@ -8,8 +8,6 @@
 #include 
 
 #define NR_CPUS8   /* arbitrarily set for now */
-extern u32 cpus[NR_CPUS];
-extern int nr_cpus;
 
 extern uint64_t tb_hz;
 
diff --git a/lib/powerpc/asm/smp.h b/lib/powerpc/asm/smp.h
index 21940b4bc..4519e5436 100644
--- a/lib/powerpc/asm/smp.h
+++ b/lib/powerpc/asm/smp.h
@@ -2,21 +2,45 @@
 #define _ASMPOWERPC_SMP_H_
 
 #include 
+#include 
 
-extern int nr_threads;
+typedef void (*secondary_entry_fn)(int cpu_id);
 
-struct start_threads {
-   int nr_threads;
-   int nr_started;
-};
+struct cpu {
+   unsigned long server_no;
+   unsigned long stack;
+   unsigned long exception_stack;
+   secondary_entry_fn entry;
+} __attribute__((packed)); /* used by asm */
 
-typedef void (*secondary_entry_fn)(void);
+extern int nr_cpus_present;
+extern int nr_cpus_online;
+extern struct cpu cpus[];
 
-extern void halt(void);
+register struct cpu *__current_cpu asm("r13");
+static inline struct cpu *current_cpu(void)
+{
+   return __current_cpu;
+}
 
-extern int start_thread(int cpu_id, secondary_entry_fn entry, uint32_t r3);
-extern struct start_threads start_cpu(int cpu_node, secondary_entry_fn entry,
- uint32_t r3);
-extern bool start_all_cpus(secondary_entry_fn entry, uint32_t r3);
+static inline int smp_processor_id(void)
+{
+   return current_cpu()->server_no;
+}
+
+void cpu_init(struct cpu *cpu, int cpu_id);
+
+extern void halt(int cpu_id);
+
+extern bool start_all_cpus(secondary_entry_fn entry);
+extern void stop_all_cpus(void);
+
+struct pt_regs;
+void register_ipi(void (*fn)(struct pt_regs *, void *), void *data);
+void unregister_ipi(void);
+void cpu_init_ipis(void);
+void local_ipi_enable(void);
+void local_ipi_disable(void);
+void send_ipi(int cpu_id);
 
 #endif /* _ASMPOWERPC_SMP_H_ */
diff --git a/lib/powerpc/io.c b/lib/powerpc/io.c
index ab7bb843c..cb7f2f050 100644
--- a/lib/powerpc/io.c
+++ b/lib/powerpc/io.c
@@ -10,6 +10,7 @@
 #include 
 

[kvm-unit-tests PATCH 17/32] arch-run: Fix handling multiple exit status messages

2024-02-26 Thread Nicholas Piggin
In SMP tests, it's possible for multiple CPUs to print an exit
message if they abort concurrently, confusing the harness:

  EXIT: STATUS=127

  EXIT: STATUS=127
  scripts/arch-run.bash: line 85: [: too many arguments
  scripts/arch-run.bash: line 93: return: too many arguments

lib/arch code should probably serialise this to prevent it, but
at the moment not all do. So make the parser handle this by
just looking at the first EXIT.

Cc: Paolo Bonzini 
Cc: Thomas Huth 
Cc: Andrew Jones 
Cc: k...@vger.kernel.org
Signed-off-by: Nicholas Piggin 
---
 scripts/arch-run.bash | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/arch-run.bash b/scripts/arch-run.bash
index 5c7e72036..4af670f1c 100644
--- a/scripts/arch-run.bash
+++ b/scripts/arch-run.bash
@@ -79,7 +79,7 @@ run_qemu_status ()
exec {stdout}>&-
 
if [ $ret -eq 1 ]; then
-   testret=$(grep '^EXIT: ' <<<"$lines" | sed 
's/.*STATUS=\([0-9][0-9]*\).*/\1/')
+   testret=$(grep '^EXIT: ' <<<"$lines" | head -n1 | sed 
's/.*STATUS=\([0-9][0-9]*\).*/\1/')
if [ "$testret" ]; then
if [ $testret -eq 1 ]; then
ret=0
-- 
2.42.0



[kvm-unit-tests PATCH 16/32] powerpc: Remove broken SMP exception stack setup

2024-02-26 Thread Nicholas Piggin
The exception stack setup does not work correctly for SMP, because
it is the boot processor that calls cpu_set() which sets SPRG2 to
the exception stack, not the target CPU itself. So secondaries
never got their SPRG2 set to a valid exception stack.

Remove the SMP code and just set an exception stack for the boot
processor. Make the stack 64kB while we're here, to match the
size of the regular stack.

Signed-off-by: Nicholas Piggin 
---
 lib/powerpc/setup.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/lib/powerpc/setup.c b/lib/powerpc/setup.c
index 9b665f59c..496af40f8 100644
--- a/lib/powerpc/setup.c
+++ b/lib/powerpc/setup.c
@@ -42,10 +42,6 @@ struct cpu_set_params {
uint64_t tb_hz;
 };
 
-#define EXCEPTION_STACK_SIZE   (32*1024) /* 32kB */
-
-static char exception_stack[NR_CPUS][EXCEPTION_STACK_SIZE];
-
 static void cpu_set(int fdtnode, u64 regval, void *info)
 {
static bool read_common_info = false;
@@ -56,10 +52,6 @@ static void cpu_set(int fdtnode, u64 regval, void *info)
 
cpus[cpu] = regval;
 
-   /* set exception stack address for this CPU (in SPGR0) */
-   asm volatile ("mtsprg0 %[addr]" ::
- [addr] "r" (exception_stack[cpu + 1]));
-
if (!read_common_info) {
const struct fdt_property *prop;
u32 *data;
@@ -180,6 +172,10 @@ static void mem_init(phys_addr_t freemem_start)
 ? __icache_bytes : __dcache_bytes);
 }
 
+#define EXCEPTION_STACK_SIZE   SZ_64K
+
+static char boot_exception_stack[EXCEPTION_STACK_SIZE];
+
 void setup(const void *fdt)
 {
void *freemem = 
@@ -189,6 +185,10 @@ void setup(const void *fdt)
 
cpu_has_hv = !!(mfmsr() & (1ULL << MSR_HV_BIT));
 
+   /* set exception stack address for this CPU (in SPGR0) */
+   asm volatile ("mtsprg0 %[addr]" ::
+ [addr] "r" (boot_exception_stack));
+
enable_mcheck();
 
/*
-- 
2.42.0



[kvm-unit-tests PATCH 15/32] powerpc: Add rtas stop-self support

2024-02-26 Thread Nicholas Piggin
In preparation for improved SMP support, add stop-self support to the
harness. This is non-trivial because it requires an unlocked rtas
call: a CPU can't be holding a spin lock when it goes offline or it
will deadlock other CPUs. rtas permits stop-self to be called without
serialising all other rtas operations.

Reviewed-by: Thomas Huth 
Signed-off-by: Nicholas Piggin 
---
 lib/powerpc/asm/rtas.h |  2 ++
 lib/powerpc/rtas.c | 78 +-
 2 files changed, 64 insertions(+), 16 deletions(-)

diff --git a/lib/powerpc/asm/rtas.h b/lib/powerpc/asm/rtas.h
index 6fb407a18..364bf9355 100644
--- a/lib/powerpc/asm/rtas.h
+++ b/lib/powerpc/asm/rtas.h
@@ -23,8 +23,10 @@ struct rtas_args {
 extern void rtas_init(void);
 extern int rtas_token(const char *service, uint32_t *token);
 extern int rtas_call(int token, int nargs, int nret, int *outputs, ...);
+extern int rtas_call_unlocked(struct rtas_args *args, int token, int nargs, 
int nret, int *outputs, ...);
 
 extern void rtas_power_off(void);
+extern void rtas_stop_self(void);
 #endif /* __ASSEMBLY__ */
 
 #define RTAS_MSR_MASK 0xfffe
diff --git a/lib/powerpc/rtas.c b/lib/powerpc/rtas.c
index 41c0a243e..b477a38e0 100644
--- a/lib/powerpc/rtas.c
+++ b/lib/powerpc/rtas.c
@@ -87,40 +87,86 @@ int rtas_token(const char *service, uint32_t *token)
return 0;
 }
 
-int rtas_call(int token, int nargs, int nret, int *outputs, ...)
+static void __rtas_call(struct rtas_args *args)
 {
-   va_list list;
-   int ret, i;
+   enter_rtas(__pa(args));
+}
 
-   spin_lock(_lock);
+static int rtas_call_unlocked_va(struct rtas_args *args,
+ int token, int nargs, int nret, int *outputs,
+ va_list list)
+{
+   int ret, i;
 
-   rtas_args.token = cpu_to_be32(token);
-   rtas_args.nargs = cpu_to_be32(nargs);
-   rtas_args.nret = cpu_to_be32(nret);
-   rtas_args.rets = _args.args[nargs];
+   args->token = cpu_to_be32(token);
+   args->nargs = cpu_to_be32(nargs);
+   args->nret = cpu_to_be32(nret);
+   args->rets = >args[nargs];
 
-   va_start(list, outputs);
for (i = 0; i < nargs; ++i)
-   rtas_args.args[i] = cpu_to_be32(va_arg(list, u32));
-   va_end(list);
+   args->args[i] = cpu_to_be32(va_arg(list, u32));
 
for (i = 0; i < nret; ++i)
-   rtas_args.rets[i] = 0;
+   args->rets[i] = 0;
 
-   enter_rtas(__pa(_args));
+   __rtas_call(args);
 
if (nret > 1 && outputs != NULL)
for (i = 0; i < nret - 1; ++i)
-   outputs[i] = be32_to_cpu(rtas_args.rets[i + 1]);
+   outputs[i] = be32_to_cpu(args->rets[i + 1]);
+
+   ret = nret > 0 ? be32_to_cpu(args->rets[0]) : 0;
+
+   return ret;
+}
+
+int rtas_call_unlocked(struct rtas_args *args, int token, int nargs, int nret, 
int *outputs, ...)
+{
+   va_list list;
+   int ret;
 
-   ret = nret > 0 ? be32_to_cpu(rtas_args.rets[0]) : 0;
+   va_start(list, outputs);
+   ret = rtas_call_unlocked_va(args, token, nargs, nret, outputs, list);
+   va_end(list);
+
+   return ret;
+}
+
+int rtas_call(int token, int nargs, int nret, int *outputs, ...)
+{
+   va_list list;
+   int ret;
+
+   spin_lock(_lock);
+
+   va_start(list, outputs);
+   ret = rtas_call_unlocked_va(_args, token, nargs, nret, outputs, 
list);
+   va_end(list);
 
spin_unlock(_lock);
+
return ret;
 }
 
+void rtas_stop_self(void)
+{
+   struct rtas_args args;
+   uint32_t token;
+   int ret;
+
+   ret = rtas_token("stop-self", );
+   if (ret) {
+   puts("RTAS stop-self not available\n");
+   return;
+   }
+
+   ret = rtas_call_unlocked(, token, 0, 1, NULL);
+   printf("RTAS stop-self returned %d\n", ret);
+}
+
 void rtas_power_off(void)
 {
+   struct rtas_args args;
uint32_t token;
int ret;
 
@@ -130,6 +176,6 @@ void rtas_power_off(void)
return;
}
 
-   ret = rtas_call(token, 2, 1, NULL, -1, -1);
+   ret = rtas_call_unlocked(, token, 2, 1, NULL, -1, -1);
printf("RTAS power-off returned %d\n", ret);
 }
-- 
2.42.0



[kvm-unit-tests PATCH 14/32] powerpc: general interrupt tests

2024-02-26 Thread Nicholas Piggin
Add basic testing of various kinds of interrupts, machine check,
page fault, illegal, decrementer, trace, syscall, etc.

This has a known failure on QEMU TCG pseries machines where MSR[ME]
can be incorrectly set to 0.

Signed-off-by: Nicholas Piggin 
---
 lib/powerpc/asm/processor.h |   4 +
 lib/powerpc/asm/reg.h   |  17 ++
 lib/powerpc/setup.c |  11 +
 lib/ppc64/asm/ptrace.h  |  16 ++
 powerpc/Makefile.common |   3 +-
 powerpc/interrupts.c| 415 
 powerpc/unittests.cfg   |   3 +
 7 files changed, 468 insertions(+), 1 deletion(-)
 create mode 100644 powerpc/interrupts.c

diff --git a/lib/powerpc/asm/processor.h b/lib/powerpc/asm/processor.h
index cf1b9d8ff..eed37d1f4 100644
--- a/lib/powerpc/asm/processor.h
+++ b/lib/powerpc/asm/processor.h
@@ -11,7 +11,11 @@ void do_handle_exception(struct pt_regs *regs);
 #endif /* __ASSEMBLY__ */
 
 extern bool cpu_has_hv;
+extern bool cpu_has_power_mce;
+extern bool cpu_has_siar;
 extern bool cpu_has_heai;
+extern bool cpu_has_prefix;
+extern bool cpu_has_sc_lev;
 
 static inline uint64_t mfspr(int nr)
 {
diff --git a/lib/powerpc/asm/reg.h b/lib/powerpc/asm/reg.h
index 782e75527..d6097f48f 100644
--- a/lib/powerpc/asm/reg.h
+++ b/lib/powerpc/asm/reg.h
@@ -5,8 +5,15 @@
 
 #define UL(x) _AC(x, UL)
 
+#define SPR_DSISR  0x012
+#define SPR_DAR0x013
+#define SPR_DEC0x016
 #define SPR_SRR0   0x01a
 #define SPR_SRR1   0x01b
+#define   SRR1_PREFIX  UL(0x2000)
+#define SPR_FSCR   0x099
+#define   FSCR_PREFIX  UL(0x2000)
+#define SPR_HFSCR  0x0be
 #define SPR_TB 0x10c
 #define SPR_SPRG0  0x110
 #define SPR_SPRG1  0x111
@@ -22,12 +29,17 @@
 #define   PVR_VER_POWER8   UL(0x004d)
 #define   PVR_VER_POWER9   UL(0x004e)
 #define   PVR_VER_POWER10  UL(0x0080)
+#define SPR_HDEC   0x136
 #define SPR_HSRR0  0x13a
 #define SPR_HSRR1  0x13b
+#define SPR_LPCR   0x13e
+#define   LPCR_HDICE   UL(0x1)
+#define SPR_HEIR   0x153
 #define SPR_MMCR0  0x31b
 #define   MMCR0_FC UL(0x8000)
 #define   MMCR0_PMAE   UL(0x0400)
 #define   MMCR0_PMAO   UL(0x0080)
+#define SPR_SIAR   0x31c
 
 /* Machine State Register definitions: */
 #define MSR_LE_BIT 0
@@ -35,6 +47,11 @@
 #define MSR_HV_BIT 60  /* Hypervisor mode */
 #define MSR_SF_BIT 63  /* 64-bit mode */
 
+#define MSR_DR UL(0x0010)
+#define MSR_IR UL(0x0020)
+#define MSR_BE UL(0x0200)  /* Branch Trace Enable */
+#define MSR_SE UL(0x0400)  /* Single Step Enable */
+#define MSR_EE UL(0x8000)
 #define MSR_ME UL(0x1000)
 
 #endif
diff --git a/lib/powerpc/setup.c b/lib/powerpc/setup.c
index 3c81aee9e..9b665f59c 100644
--- a/lib/powerpc/setup.c
+++ b/lib/powerpc/setup.c
@@ -87,7 +87,11 @@ static void cpu_set(int fdtnode, u64 regval, void *info)
 }
 
 bool cpu_has_hv;
+bool cpu_has_power_mce; /* POWER CPU machine checks */
+bool cpu_has_siar;
 bool cpu_has_heai;
+bool cpu_has_prefix;
+bool cpu_has_sc_lev; /* sc interrupt has LEV field in SRR1 */
 
 static void cpu_init(void)
 {
@@ -112,15 +116,22 @@ static void cpu_init(void)
 
switch (mfspr(SPR_PVR) & PVR_VERSION_MASK) {
case PVR_VER_POWER10:
+   cpu_has_prefix = true;
+   cpu_has_sc_lev = true;
case PVR_VER_POWER9:
case PVR_VER_POWER8E:
case PVR_VER_POWER8NVL:
case PVR_VER_POWER8:
+   cpu_has_power_mce = true;
cpu_has_heai = true;
+   cpu_has_siar = true;
break;
default:
break;
}
+
+   if (!cpu_has_hv) /* HEIR is HV register */
+   cpu_has_heai = false;
 }
 
 static void mem_init(phys_addr_t freemem_start)
diff --git a/lib/ppc64/asm/ptrace.h b/lib/ppc64/asm/ptrace.h
index 12de7499b..db263a59e 100644
--- a/lib/ppc64/asm/ptrace.h
+++ b/lib/ppc64/asm/ptrace.h
@@ -5,6 +5,9 @@
 #define STACK_FRAME_OVERHEAD112 /* size of minimum stack frame */
 
 #ifndef __ASSEMBLY__
+
+#include 
+
 struct pt_regs {
unsigned long gpr[32];
unsigned long nip;
@@ -17,6 +20,19 @@ struct pt_regs {
unsigned long _pad; /* stack must be 16-byte aligned */
 };
 
+static inline bool regs_is_prefix(volatile struct pt_regs *regs)
+{
+   return regs->msr & SRR1_PREFIX;
+}
+
+static inline void regs_advance_insn(struct pt_regs *regs)
+{
+   if (regs_is_prefix(regs))
+   regs->nip += 8;
+   else
+   regs->nip += 4;
+}
+
 #define STACK_INT_FRAME_SIZE(sizeof(struct pt_regs) + \
 STACK_FRAME_OVERHEAD + KERNEL_REDZONE_SIZE)
 
diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
index 1e181da69..68165fc25 100644
--- a/powerpc/Makefile.common
+++ b/powerpc/Makefile.common
@@ -12,7 +12,8 @@ 

[kvm-unit-tests PATCH 13/32] powerpc/sprs: Test hypervisor registers on powernv machine

2024-02-26 Thread Nicholas Piggin
This enables HV privilege registers to be tested with the powernv
machine.

Acked-by: Thomas Huth 
Signed-off-by: Nicholas Piggin 
---
 powerpc/sprs.c | 33 +
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/powerpc/sprs.c b/powerpc/sprs.c
index cb1d6c980..0a82418d6 100644
--- a/powerpc/sprs.c
+++ b/powerpc/sprs.c
@@ -199,16 +199,16 @@ static const struct spr sprs_power_common[1024] = {
 [190] = { "HFSCR", 64, HV_RW, },
 [256] = { "VRSAVE",32, RW, },
 [259] = { "SPRG3", 64, RO, },
-[284] = { "TBL",   32, HV_WO, },
-[285] = { "TBU",   32, HV_WO, },
-[286] = { "TBU40", 64, HV_WO, },
+[284] = { "TBL",   32, HV_WO, }, /* Things can go a bit wonky with */
+[285] = { "TBU",   32, HV_WO, }, /* Timebase changing. Should save */
+[286] = { "TBU40", 64, HV_WO, }, /* and restore it. */
 [304] = { "HSPRG0",64, HV_RW, },
 [305] = { "HSPRG1",64, HV_RW, },
 [306] = { "HDSISR",32, HV_RW,  SPR_INT, },
 [307] = { "HDAR",  64, HV_RW,  SPR_INT, },
 [308] = { "SPURR", 64, HV_RW | OS_RO,  SPR_ASYNC, },
 [309] = { "PURR",  64, HV_RW | OS_RO,  SPR_ASYNC, },
-[313] = { "HRMOR", 64, HV_RW, },
+[313] = { "HRMOR", 64, HV_RW,  SPR_HARNESS, }, /* Harness 
can't cope with HRMOR changing */
 [314] = { "HSRR0", 64, HV_RW,  SPR_INT, },
 [315] = { "HSRR1", 64, HV_RW,  SPR_INT, },
 [318] = { "LPCR",  64, HV_RW, },
@@ -306,7 +306,7 @@ static const struct spr sprs_power9_10[1024] = {
 [921] = { "TSCR",  32, HV_RW, },
 [922] = { "TTR",   64, HV_RW, },
 [1006]= { "TRACE", 64, WO, },
-[1008]= { "HID",   64, HV_RW, },
+[1008]= { "HID",   64, HV_RW,  SPR_HARNESS, }, /* HILE would 
be unhelpful to change */
 };
 
 /* This covers POWER8 and POWER9 PMUs */
@@ -350,6 +350,22 @@ static const struct spr sprs_power10_pmu[1024] = {
 
 static struct spr sprs[1024];
 
+static bool spr_read_perms(int spr)
+{
+   if (cpu_has_hv)
+   return !!(sprs[spr].access & SPR_HV_READ);
+   else
+   return !!(sprs[spr].access & SPR_OS_READ);
+}
+
+static bool spr_write_perms(int spr)
+{
+   if (cpu_has_hv)
+   return !!(sprs[spr].access & SPR_HV_WRITE);
+   else
+   return !!(sprs[spr].access & SPR_OS_WRITE);
+}
+
 static void setup_sprs(void)
 {
int i;
@@ -461,7 +477,7 @@ static void get_sprs(uint64_t *v)
int i;
 
for (i = 0; i < 1024; i++) {
-   if (!(sprs[i].access & SPR_OS_READ))
+   if (!spr_read_perms(i))
continue;
v[i] = __mfspr(i);
}
@@ -472,8 +488,9 @@ static void set_sprs(uint64_t val)
int i;
 
for (i = 0; i < 1024; i++) {
-   if (!(sprs[i].access & SPR_OS_WRITE))
+   if (!spr_write_perms(i))
continue;
+
if (sprs[i].type & SPR_HARNESS)
continue;
__mtspr(i, val);
@@ -561,7 +578,7 @@ int main(int argc, char **argv)
for (i = 0; i < 1024; i++) {
bool pass = true;
 
-   if (!(sprs[i].access & SPR_OS_READ))
+   if (!spr_read_perms(i))
continue;
 
if (sprs[i].width == 32) {
-- 
2.42.0



[kvm-unit-tests PATCH 12/32] powerpc: Fix emulator illegal instruction test for powernv

2024-02-26 Thread Nicholas Piggin
Illegal instructions cause 0xe40 (HEAI) interrupts rather
than program interrupts.

Acked-by: Thomas Huth 
Signed-off-by: Nicholas Piggin 
---
 lib/powerpc/asm/processor.h |  1 +
 lib/powerpc/setup.c | 13 +
 powerpc/emulator.c  | 21 -
 3 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/lib/powerpc/asm/processor.h b/lib/powerpc/asm/processor.h
index 9d8061962..cf1b9d8ff 100644
--- a/lib/powerpc/asm/processor.h
+++ b/lib/powerpc/asm/processor.h
@@ -11,6 +11,7 @@ void do_handle_exception(struct pt_regs *regs);
 #endif /* __ASSEMBLY__ */
 
 extern bool cpu_has_hv;
+extern bool cpu_has_heai;
 
 static inline uint64_t mfspr(int nr)
 {
diff --git a/lib/powerpc/setup.c b/lib/powerpc/setup.c
index 89e5157f2..3c81aee9e 100644
--- a/lib/powerpc/setup.c
+++ b/lib/powerpc/setup.c
@@ -87,6 +87,7 @@ static void cpu_set(int fdtnode, u64 regval, void *info)
 }
 
 bool cpu_has_hv;
+bool cpu_has_heai;
 
 static void cpu_init(void)
 {
@@ -108,6 +109,18 @@ static void cpu_init(void)
hcall(H_SET_MODE, 0, 4, 0, 0);
 #endif
}
+
+   switch (mfspr(SPR_PVR) & PVR_VERSION_MASK) {
+   case PVR_VER_POWER10:
+   case PVR_VER_POWER9:
+   case PVR_VER_POWER8E:
+   case PVR_VER_POWER8NVL:
+   case PVR_VER_POWER8:
+   cpu_has_heai = true;
+   break;
+   default:
+   break;
+   }
 }
 
 static void mem_init(phys_addr_t freemem_start)
diff --git a/powerpc/emulator.c b/powerpc/emulator.c
index 39dd59645..c9b17f742 100644
--- a/powerpc/emulator.c
+++ b/powerpc/emulator.c
@@ -31,6 +31,20 @@ static void program_check_handler(struct pt_regs *regs, void 
*opaque)
regs->nip += 4;
 }
 
+static void heai_handler(struct pt_regs *regs, void *opaque)
+{
+   int *data = opaque;
+
+   if (verbose) {
+   printf("Detected invalid instruction %#018lx: %08x\n",
+  regs->nip, *(uint32_t*)regs->nip);
+   }
+
+   *data = 8; /* Illegal instruction */
+
+   regs->nip += 4;
+}
+
 static void alignment_handler(struct pt_regs *regs, void *opaque)
 {
int *data = opaque;
@@ -362,7 +376,12 @@ int main(int argc, char **argv)
 {
int i;
 
-   handle_exception(0x700, program_check_handler, (void *)_invalid);
+   if (cpu_has_heai) {
+   handle_exception(0xe40, heai_handler, (void *)_invalid);
+   handle_exception(0x700, program_check_handler, (void 
*)_invalid);
+   } else {
+   handle_exception(0x700, program_check_handler, (void 
*)_invalid);
+   }
handle_exception(0x600, alignment_handler, (void *));
 
for (i = 1; i < argc; i++) {
-- 
2.42.0



[kvm-unit-tests PATCH 11/32] powerpc: Support powernv machine with QEMU TCG

2024-02-26 Thread Nicholas Piggin
Add support for QEMU's powernv machine. This uses standard firmware
(skiboot) rather than a minimal firmware shim.

Reviewed-by: Cédric Le Goater 
Signed-off-by: Nicholas Piggin 
---
 lib/powerpc/asm/processor.h | 23 +++
 lib/powerpc/asm/reg.h   |  4 ++
 lib/powerpc/hcall.c |  4 +-
 lib/powerpc/io.c| 27 -
 lib/powerpc/io.h|  6 +++
 lib/powerpc/processor.c | 37 ++
 lib/powerpc/setup.c | 14 +--
 lib/ppc64/asm/opal.h| 15 
 lib/ppc64/opal-calls.S  | 50 
 lib/ppc64/opal.c| 76 +
 powerpc/Makefile.ppc64  |  2 +
 powerpc/cstart64.S  |  7 
 powerpc/run | 42 
 powerpc/unittests.cfg   | 10 -
 14 files changed, 301 insertions(+), 16 deletions(-)
 create mode 100644 lib/ppc64/asm/opal.h
 create mode 100644 lib/ppc64/opal-calls.S
 create mode 100644 lib/ppc64/opal.c

diff --git a/lib/powerpc/asm/processor.h b/lib/powerpc/asm/processor.h
index e415f9235..9d8061962 100644
--- a/lib/powerpc/asm/processor.h
+++ b/lib/powerpc/asm/processor.h
@@ -10,6 +10,8 @@ void handle_exception(int trap, void (*func)(struct pt_regs 
*, void *), void *);
 void do_handle_exception(struct pt_regs *regs);
 #endif /* __ASSEMBLY__ */
 
+extern bool cpu_has_hv;
+
 static inline uint64_t mfspr(int nr)
 {
uint64_t ret;
@@ -38,4 +40,25 @@ static inline void mtmsr(uint64_t msr)
asm volatile ("mtmsrd %[msr]" :: [msr] "r" (msr) : "memory");
 }
 
+/*
+ * This returns true on PowerNV / OPAL machines which run in hypervisor
+ * mode. False on pseries / PAPR machines that run in guest mode.
+ */
+static inline bool machine_is_powernv(void)
+{
+   return cpu_has_hv;
+}
+
+/*
+ * This returns true on pseries / PAPR / KVM machines which run under a
+ * hypervisor or QEMU pseries machine. False for PowerNV / OPAL.
+ */
+static inline bool machine_is_pseries(void)
+{
+   return !machine_is_powernv();
+}
+
+void enable_mcheck(void);
+void disable_mcheck(void);
+
 #endif /* _ASMPOWERPC_PROCESSOR_H_ */
diff --git a/lib/powerpc/asm/reg.h b/lib/powerpc/asm/reg.h
index c80b32059..782e75527 100644
--- a/lib/powerpc/asm/reg.h
+++ b/lib/powerpc/asm/reg.h
@@ -30,7 +30,11 @@
 #define   MMCR0_PMAO   UL(0x0080)
 
 /* Machine State Register definitions: */
+#define MSR_LE_BIT 0
 #define MSR_EE_BIT 15  /* External Interrupts Enable */
+#define MSR_HV_BIT 60  /* Hypervisor mode */
 #define MSR_SF_BIT 63  /* 64-bit mode */
 
+#define MSR_ME UL(0x1000)
+
 #endif
diff --git a/lib/powerpc/hcall.c b/lib/powerpc/hcall.c
index b4d39ac65..45f201315 100644
--- a/lib/powerpc/hcall.c
+++ b/lib/powerpc/hcall.c
@@ -25,7 +25,7 @@ int hcall_have_broken_sc1(void)
return r3 == (unsigned long)H_PRIVILEGE;
 }
 
-void putchar(int c)
+void papr_putchar(int c)
 {
unsigned long vty = 0;  /* 0 == default */
unsigned long nr_chars = 1;
@@ -34,7 +34,7 @@ void putchar(int c)
hcall(H_PUT_TERM_CHAR, vty, nr_chars, chars);
 }
 
-int __getchar(void)
+int __papr_getchar(void)
 {
register unsigned long r3 asm("r3") = H_GET_TERM_CHAR;
register unsigned long r4 asm("r4") = 0; /* 0 == default vty */
diff --git a/lib/powerpc/io.c b/lib/powerpc/io.c
index a381688bc..ab7bb843c 100644
--- a/lib/powerpc/io.c
+++ b/lib/powerpc/io.c
@@ -9,13 +9,33 @@
 #include 
 #include 
 #include 
+#include 
 #include "io.h"
 
 static struct spinlock print_lock;
 
+void putchar(int c)
+{
+   if (machine_is_powernv())
+   opal_putchar(c);
+   else
+   papr_putchar(c);
+}
+
+int __getchar(void)
+{
+   if (machine_is_powernv())
+   return __opal_getchar();
+   else
+   return __papr_getchar();
+}
+
 void io_init(void)
 {
-   rtas_init();
+   if (machine_is_powernv())
+   assert(!opal_init());
+   else
+   rtas_init();
 }
 
 void puts(const char *s)
@@ -38,7 +58,10 @@ void exit(int code)
 // FIXME: change this print-exit/rtas-poweroff to chr_testdev_exit(),
 //maybe by plugging chr-testdev into a spapr-vty.
printf("\nEXIT: STATUS=%d\n", ((code) << 1) | 1);
-   rtas_power_off();
+   if (machine_is_powernv())
+   opal_power_off();
+   else
+   rtas_power_off();
halt(code);
__builtin_unreachable();
 }
diff --git a/lib/powerpc/io.h b/lib/powerpc/io.h
index d4f21ba15..943bf142b 100644
--- a/lib/powerpc/io.h
+++ b/lib/powerpc/io.h
@@ -8,6 +8,12 @@
 #define _POWERPC_IO_H_
 
 extern void io_init(void);
+extern int opal_init(void);
+extern void opal_power_off(void);
 extern void putchar(int c);
+extern void opal_putchar(int c);
+extern void papr_putchar(int c);
+extern int __opal_getchar(void);
+extern int __papr_getchar(void);
 
 #endif
diff --git 

[kvm-unit-tests PATCH 10/32] scripts: Accommodate powerpc powernv machine differences

2024-02-26 Thread Nicholas Piggin
The QEMU powerpc powernv machine has minor differences that must be
accommodated for in output parsing:

- Summary parsing must search more lines of output for the summary
  line, to accommodate OPAL message on shutdown.
- Premature failure testing must tolerate case differences in kernel
  load error message.

Acked-by: Thomas Huth 
Signed-off-by: Nicholas Piggin 
---
 scripts/runtime.bash | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/scripts/runtime.bash b/scripts/runtime.bash
index 8f9672d0d..bb32c0d10 100644
--- a/scripts/runtime.bash
+++ b/scripts/runtime.bash
@@ -9,7 +9,7 @@ FAIL() { echo -ne "\e[31mFAIL\e[0m"; }
 extract_summary()
 {
 local cr=$'\r'
-tail -3 | grep '^SUMMARY: ' | sed 's/^SUMMARY: /(/;s/'"$cr"'\{0,1\}$/)/'
+tail -5 | grep '^SUMMARY: ' | sed 's/^SUMMARY: /(/;s/'"$cr"'\{0,1\}$/)/'
 }
 
 # We assume that QEMU is going to work if it tried to load the kernel
@@ -18,7 +18,7 @@ premature_failure()
 local log="$(eval "$(get_cmdline _NO_FILE_4Uhere_)" 2>&1)"
 
 echo "$log" | grep "_NO_FILE_4Uhere_" |
-grep -q -e "could not \(load\|open\) kernel" -e "error loading" &&
+grep -q -e "[Cc]ould not \(load\|open\) kernel" -e "error loading" &&
 return 1
 
 RUNTIME_log_stderr <<< "$log"
-- 
2.42.0



[kvm-unit-tests PATCH 09/32] scripts: allow machine option to be specified in unittests.cfg

2024-02-26 Thread Nicholas Piggin
This allows different machines with different requirements to be
supported by run_tests.sh, similarly to how different accelerators
are handled.

Acked-by: Thomas Huth 
Signed-off-by: Nicholas Piggin 
---
 scripts/common.bash  |  8 ++--
 scripts/runtime.bash | 16 
 2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/scripts/common.bash b/scripts/common.bash
index b9413d683..ee1dd8659 100644
--- a/scripts/common.bash
+++ b/scripts/common.bash
@@ -10,6 +10,7 @@ function for_each_unittest()
local opts
local groups
local arch
+   local machine
local check
local accel
local timeout
@@ -21,7 +22,7 @@ function for_each_unittest()
if [[ "$line" =~ ^\[(.*)\]$ ]]; then
rematch=${BASH_REMATCH[1]}
if [ -n "${testname}" ]; then
-   $(arch_cmd) "$cmd" "$testname" "$groups" "$smp" 
"$kernel" "$opts" "$arch" "$check" "$accel" "$timeout"
+   $(arch_cmd) "$cmd" "$testname" "$groups" "$smp" 
"$kernel" "$opts" "$arch" "$machine" "$check" "$accel" "$timeout"
fi
testname=$rematch
smp=1
@@ -29,6 +30,7 @@ function for_each_unittest()
opts=""
groups=""
arch=""
+   machine=""
check=""
accel=""
timeout=""
@@ -58,6 +60,8 @@ function for_each_unittest()
groups=${BASH_REMATCH[1]}
elif [[ $line =~ ^arch\ *=\ *(.*)$ ]]; then
arch=${BASH_REMATCH[1]}
+   elif [[ $line =~ ^machine\ *=\ *(.*)$ ]]; then
+   machine=${BASH_REMATCH[1]}
elif [[ $line =~ ^check\ *=\ *(.*)$ ]]; then
check=${BASH_REMATCH[1]}
elif [[ $line =~ ^accel\ *=\ *(.*)$ ]]; then
@@ -67,7 +71,7 @@ function for_each_unittest()
fi
done
if [ -n "${testname}" ]; then
-   $(arch_cmd) "$cmd" "$testname" "$groups" "$smp" "$kernel" 
"$opts" "$arch" "$check" "$accel" "$timeout"
+   $(arch_cmd) "$cmd" "$testname" "$groups" "$smp" "$kernel" 
"$opts" "$arch" "$machine" "$check" "$accel" "$timeout"
fi
exec {fd}<&-
 }
diff --git a/scripts/runtime.bash b/scripts/runtime.bash
index c73fb0240..8f9672d0d 100644
--- a/scripts/runtime.bash
+++ b/scripts/runtime.bash
@@ -30,7 +30,7 @@ premature_failure()
 get_cmdline()
 {
 local kernel=$1
-echo "TESTNAME=$testname TIMEOUT=$timeout ACCEL=$accel $RUNTIME_arch_run 
$kernel -smp $smp $opts"
+echo "TESTNAME=$testname TIMEOUT=$timeout MACHINE=$machine ACCEL=$accel 
$RUNTIME_arch_run $kernel -smp $smp $opts"
 }
 
 skip_nodefault()
@@ -78,9 +78,10 @@ function run()
 local kernel="$4"
 local opts="$5"
 local arch="$6"
-local check="${CHECK:-$7}"
-local accel="$8"
-local timeout="${9:-$TIMEOUT}" # unittests.cfg overrides the default
+local machine="$7"
+local check="${CHECK:-$8}"
+local accel="$9"
+local timeout="${10:-$TIMEOUT}" # unittests.cfg overrides the default
 
 if [ "${CONFIG_EFI}" == "y" ]; then
 kernel=${kernel/%.flat/.efi}
@@ -114,6 +115,13 @@ function run()
 return 2
 fi
 
+if [ -n "$machine" ] && [ -n "$MACHINE" ] && [ "$machine" != "$MACHINE" ]; 
then
+print_result "SKIP" $testname "" "$machine only"
+return 2
+elif [ -n "$MACHINE" ]; then
+machine="$MACHINE"
+fi
+
 if [ -n "$accel" ] && [ -n "$ACCEL" ] && [ "$accel" != "$ACCEL" ]; then
 print_result "SKIP" $testname "" "$accel only, but ACCEL=$ACCEL"
 return 2
-- 
2.42.0



[kvm-unit-tests PATCH 08/32] powerpc/sprs: Avoid taking PMU interrupts caused by register fuzzing

2024-02-26 Thread Nicholas Piggin
Storing certain values in MMCR0 can cause PMU interrupts when msleep
enables MSR[EE], and this crashes the test. Freeze the PMU counters
and clear any PMU exception before calling msleep.

Signed-off-by: Nicholas Piggin 
---
 lib/powerpc/asm/reg.h |  4 
 powerpc/sprs.c| 17 +++--
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/lib/powerpc/asm/reg.h b/lib/powerpc/asm/reg.h
index 1f991288e..c80b32059 100644
--- a/lib/powerpc/asm/reg.h
+++ b/lib/powerpc/asm/reg.h
@@ -24,6 +24,10 @@
 #define   PVR_VER_POWER10  UL(0x0080)
 #define SPR_HSRR0  0x13a
 #define SPR_HSRR1  0x13b
+#define SPR_MMCR0  0x31b
+#define   MMCR0_FC UL(0x8000)
+#define   MMCR0_PMAE   UL(0x0400)
+#define   MMCR0_PMAO   UL(0x0080)
 
 /* Machine State Register definitions: */
 #define MSR_EE_BIT 15  /* External Interrupts Enable */
diff --git a/powerpc/sprs.c b/powerpc/sprs.c
index 44edd0d7b..cb1d6c980 100644
--- a/powerpc/sprs.c
+++ b/powerpc/sprs.c
@@ -476,12 +476,7 @@ static void set_sprs(uint64_t val)
continue;
if (sprs[i].type & SPR_HARNESS)
continue;
-   if (!strcmp(sprs[i].name, "MMCR0")) {
-   /* XXX: could use a comment or better abstraction! */
-   __mtspr(i, (val & 0xfbab3fffULL) | 0xfa0b2070);
-   } else {
-   __mtspr(i, val);
-   }
+   __mtspr(i, val);
}
 }
 
@@ -538,6 +533,16 @@ int main(int argc, char **argv)
if (sprs[895].name)
before[895] = mfspr(895);
} else {
+   /*
+* msleep will enable MSR[EE] and take a decrementer
+* interrupt. Must account for changed registers and
+* prevent taking unhandled interrupts.
+*/
+   /* Prevent PMU interrupt */
+   mtspr(SPR_MMCR0, (mfspr(SPR_MMCR0) | MMCR0_FC) &
+   ~(MMCR0_PMAO | MMCR0_PMAE));
+   before[SPR_MMCR0] = mfspr(SPR_MMCR0);
+   before[779] = mfspr(SPR_MMCR0);
msleep(2000);
 
/* Reload regs changed by dec interrupt */
-- 
2.42.0



[kvm-unit-tests PATCH 07/32] powerpc/sprs: Don't fail changed SPRs that are used by the test harness

2024-02-26 Thread Nicholas Piggin
SPRs annotated with SPR_HARNESS can change between consecutive reads
because the test harness code has changed them. Avoid failing the
test in this case.

Signed-off-by: Nicholas Piggin 
---
 powerpc/sprs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/powerpc/sprs.c b/powerpc/sprs.c
index 8253ea971..44edd0d7b 100644
--- a/powerpc/sprs.c
+++ b/powerpc/sprs.c
@@ -563,7 +563,7 @@ int main(int argc, char **argv)
if (before[i] >> 32)
pass = false;
}
-   if (!(sprs[i].type & SPR_ASYNC) && (before[i] != after[i]))
+   if (!(sprs[i].type & (SPR_HARNESS|SPR_ASYNC)) && (before[i] != 
after[i]))
pass = false;
 
if (sprs[i].width == 32 && !(before[i] >> 32) && !(after[i] >> 
32))
-- 
2.42.0



[kvm-unit-tests PATCH 06/32] powerpc/sprs: Specify SPRs with data rather than code

2024-02-26 Thread Nicholas Piggin
A significant rework that builds an array of 'struct spr', where each
element describes an SPR. This makes various metadata about the SPR
like name and access type easier to carry and use.

Hypervisor privileged registers are described despite not being used
at the moment for completeness, but also the code might one day be
reused for a hypervisor-privileged test.

Acked-by: Thomas Huth 
Signed-off-by: Nicholas Piggin 
---
 lib/powerpc/asm/reg.h |   2 +
 powerpc/sprs.c| 647 +-
 2 files changed, 457 insertions(+), 192 deletions(-)

diff --git a/lib/powerpc/asm/reg.h b/lib/powerpc/asm/reg.h
index 6810c1d82..1f991288e 100644
--- a/lib/powerpc/asm/reg.h
+++ b/lib/powerpc/asm/reg.h
@@ -5,6 +5,8 @@
 
 #define UL(x) _AC(x, UL)
 
+#define SPR_SRR0   0x01a
+#define SPR_SRR1   0x01b
 #define SPR_TB 0x10c
 #define SPR_SPRG0  0x110
 #define SPR_SPRG1  0x111
diff --git a/powerpc/sprs.c b/powerpc/sprs.c
index a19d80a1a..8253ea971 100644
--- a/powerpc/sprs.c
+++ b/powerpc/sprs.c
@@ -30,229 +30,458 @@
 #include 
 #include 
 
-uint64_t before[1024], after[1024];
-
-/* Common SPRs for all PowerPC CPUs */
-static void set_sprs_common(uint64_t val)
+/* "Indirect" mfspr/mtspr which accept a non-constant spr number */
+static uint64_t __mfspr(unsigned spr)
 {
-   mtspr(9, val);  /* CTR */
-   // mtspr(273, val); /* SPRG1 */  /* Used by our exception handler */
-   mtspr(274, val);/* SPRG2 */
-   mtspr(275, val);/* SPRG3 */
+   uint64_t tmp;
+   uint64_t ret;
+
+   asm volatile(
+"  bcl 20, 31, 1f  \n"
+"1:mflr%0  \n"
+"  addi%0, %0, (2f-1b) \n"
+"  add %0, %0, %2  \n"
+"  mtctr   %0  \n"
+"  bctr\n"
+"2:\n"
+".LSPR=0   \n"
+".rept 1024\n"
+"  mfspr   %1, .LSPR   \n"
+"  b   3f  \n"
+"  .LSPR=.LSPR+1   \n"
+".endr \n"
+"3:\n"
+   : "="(tmp),
+ "=r"(ret)
+   : "r"(spr*8) /* 8 bytes per 'mfspr ; b' block */
+   : "lr", "ctr");
+
+   return ret;
 }
 
-/* SPRs from PowerPC Operating Environment Architecture, Book III, Vers. 2.01 
*/
-static void set_sprs_book3s_201(uint64_t val)
+static void __mtspr(unsigned spr, uint64_t val)
 {
-   mtspr(18, val); /* DSISR */
-   mtspr(19, val); /* DAR */
-   mtspr(152, val);/* CTRL */
-   mtspr(256, val);/* VRSAVE */
-   mtspr(786, val);/* MMCRA */
-   mtspr(795, val);/* MMCR0 */
-   mtspr(798, val);/* MMCR1 */
+   uint64_t tmp;
+
+   asm volatile(
+"  bcl 20, 31, 1f  \n"
+"1:mflr%0  \n"
+"  addi%0, %0, (2f-1b) \n"
+"  add %0, %0, %2  \n"
+"  mtctr   %0  \n"
+"  bctr\n"
+"2:\n"
+".LSPR=0   \n"
+".rept 1024\n"
+"  mtspr   .LSPR, %1   \n"
+"  b   3f  \n"
+"  .LSPR=.LSPR+1   \n"
+".endr \n"
+"3:\n"
+   : "="(tmp)
+   : "r"(val),
+ "r"(spr*8) /* 8 bytes per 'mfspr ; b' block */
+   : "lr", "ctr", "xer");
 }
 
+static uint64_t before[1024], after[1024];
+
+#define SPR_PR_READ0x0001
+#define SPR_PR_WRITE   0x0002
+#define SPR_OS_READ0x0010
+#define SPR_OS_WRITE   0x0020
+#define SPR_HV_READ0x0100
+#define SPR_HV_WRITE   0x0200
+
+#define RW 0x333
+#define RO 0x111
+#define WO 0x222
+#define OS_RW  0x330
+#define OS_RO  0x110
+#define OS_WO  0x220
+#define HV_RW  0x300
+#define HV_RO  0x100
+#define HV_WO  0x200
+
+#define SPR_ASYNC  0x1000  /* May be updated asynchronously */
+#define SPR_INT0x2000  /* May be updated by synchronous 
interrupt */
+#define SPR_HARNESS0x4000  /* Test harness uses the register */
+
+struct spr {
+   const char  *name;
+   uint8_t width;
+   uint16_taccess;
+   uint16_ttype;
+};
+
+/* SPRs common denominator back to PowerPC Operating Environment Architecture 
*/
+static const struct spr sprs_common[1024] = {
+  [1] = { "XER",   64, RW, SPR_HARNESS, }, /* Used by 
compiler */
+  [8] = { "LR",64, RW, SPR_HARNESS, }, /* Compiler, 
mfspr/mtspr */
+  [9] = { "CTR",   64, RW, SPR_HARNESS, }, /* Compiler, 
mfspr/mtspr */
+ [18] = { "DSISR", 32, OS_RW,  SPR_INT, },
+ 

[kvm-unit-tests PATCH 05/32] powerpc: Cleanup SPR and MSR definitions

2024-02-26 Thread Nicholas Piggin
Move SPR and MSR defines out of ppc_asm.h and processor.h and into a
new include, asm/reg.h.

Add a define for the PVR SPR and various processor versions, and replace
the open coded numbers in the sprs.c test case.

Signed-off-by: Nicholas Piggin 
---
 lib/powerpc/asm/ppc_asm.h   |  8 +---
 lib/powerpc/asm/processor.h |  7 +--
 lib/powerpc/asm/reg.h   | 30 ++
 lib/powerpc/asm/time.h  |  1 +
 lib/ppc64/asm/reg.h |  1 +
 powerpc/sprs.c  | 21 ++---
 6 files changed, 44 insertions(+), 24 deletions(-)
 create mode 100644 lib/powerpc/asm/reg.h
 create mode 100644 lib/ppc64/asm/reg.h

diff --git a/lib/powerpc/asm/ppc_asm.h b/lib/powerpc/asm/ppc_asm.h
index 46b4be009..52a42dfbe 100644
--- a/lib/powerpc/asm/ppc_asm.h
+++ b/lib/powerpc/asm/ppc_asm.h
@@ -2,6 +2,7 @@
 #define _ASMPOWERPC_PPC_ASM_H
 
 #include 
+#include 
 
 #define SAVE_GPR(n, base)  std n,GPR0+8*(n)(base)
 #define REST_GPR(n, base)  ld  n,GPR0+8*(n)(base)
@@ -35,11 +36,4 @@
 
 #endif /* __BYTE_ORDER__ */
 
-#define SPR_HSRR0  0x13A
-#define SPR_HSRR1  0x13B
-
-/* Machine State Register definitions: */
-#define MSR_EE_BIT 15  /* External Interrupts Enable */
-#define MSR_SF_BIT 63  /* 64-bit mode */
-
 #endif /* _ASMPOWERPC_PPC_ASM_H */
diff --git a/lib/powerpc/asm/processor.h b/lib/powerpc/asm/processor.h
index fe1052939..e415f9235 100644
--- a/lib/powerpc/asm/processor.h
+++ b/lib/powerpc/asm/processor.h
@@ -3,18 +3,13 @@
 
 #include 
 #include 
+#include 
 
 #ifndef __ASSEMBLY__
 void handle_exception(int trap, void (*func)(struct pt_regs *, void *), void 
*);
 void do_handle_exception(struct pt_regs *regs);
 #endif /* __ASSEMBLY__ */
 
-#define SPR_TB 0x10c
-#define SPR_SPRG0  0x110
-#define SPR_SPRG1  0x111
-#define SPR_SPRG2  0x112
-#define SPR_SPRG3  0x113
-
 static inline uint64_t mfspr(int nr)
 {
uint64_t ret;
diff --git a/lib/powerpc/asm/reg.h b/lib/powerpc/asm/reg.h
new file mode 100644
index 0..6810c1d82
--- /dev/null
+++ b/lib/powerpc/asm/reg.h
@@ -0,0 +1,30 @@
+#ifndef _ASMPOWERPC_REG_H
+#define _ASMPOWERPC_REG_H
+
+#include 
+
+#define UL(x) _AC(x, UL)
+
+#define SPR_TB 0x10c
+#define SPR_SPRG0  0x110
+#define SPR_SPRG1  0x111
+#define SPR_SPRG2  0x112
+#define SPR_SPRG3  0x113
+#define SPR_PVR0x11f
+#define   PVR_VERSION_MASK UL(0x)
+#define   PVR_VER_970  UL(0x0039)
+#define   PVR_VER_970FXUL(0x003c)
+#define   PVR_VER_970MPUL(0x0044)
+#define   PVR_VER_POWER8E  UL(0x004b)
+#define   PVR_VER_POWER8NVLUL(0x004c)
+#define   PVR_VER_POWER8   UL(0x004d)
+#define   PVR_VER_POWER9   UL(0x004e)
+#define   PVR_VER_POWER10  UL(0x0080)
+#define SPR_HSRR0  0x13a
+#define SPR_HSRR1  0x13b
+
+/* Machine State Register definitions: */
+#define MSR_EE_BIT 15  /* External Interrupts Enable */
+#define MSR_SF_BIT 63  /* 64-bit mode */
+
+#endif
diff --git a/lib/powerpc/asm/time.h b/lib/powerpc/asm/time.h
index 72fcb1bd0..a1f072989 100644
--- a/lib/powerpc/asm/time.h
+++ b/lib/powerpc/asm/time.h
@@ -3,6 +3,7 @@
 
 #include 
 #include 
+#include 
 
 static inline uint64_t get_tb(void)
 {
diff --git a/lib/ppc64/asm/reg.h b/lib/ppc64/asm/reg.h
new file mode 100644
index 0..bc407b555
--- /dev/null
+++ b/lib/ppc64/asm/reg.h
@@ -0,0 +1 @@
+#include "../../powerpc/asm/reg.h"
diff --git a/powerpc/sprs.c b/powerpc/sprs.c
index 285976488..a19d80a1a 100644
--- a/powerpc/sprs.c
+++ b/powerpc/sprs.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -120,25 +121,23 @@ static void set_sprs_book3s_31(uint64_t val)
 
 static void set_sprs(uint64_t val)
 {
-   uint32_t pvr = mfspr(287);  /* Processor Version Register */
-
set_sprs_common(val);
 
-   switch (pvr >> 16) {
-   case 0x39:  /* PPC970 */
-   case 0x3C:  /* PPC970FX */
-   case 0x44:  /* PPC970MP */
+   switch (mfspr(SPR_PVR) & PVR_VERSION_MASK) {
+   case PVR_VER_970:
+   case PVR_VER_970FX:
+   case PVR_VER_970MP:
set_sprs_book3s_201(val);
break;
-   case 0x4b:  /* POWER8E */
-   case 0x4c:  /* POWER8NVL */
-   case 0x4d:  /* POWER8 */
+   case PVR_VER_POWER8E:
+   case PVR_VER_POWER8NVL:
+   case PVR_VER_POWER8:
set_sprs_book3s_207(val);
break;
-   case 0x4e:  /* POWER9 */
+   case PVR_VER_POWER9:
set_sprs_book3s_300(val);
break;
-   case 0x80:  /* POWER10 */
+   case PVR_VER_POWER10:
set_sprs_book3s_31(val);
 

[kvm-unit-tests PATCH 04/32] powerpc: interrupt stack backtracing

2024-02-26 Thread Nicholas Piggin
Add support for backtracing across interrupt stacks, and
add interrupt frame backtrace for unhandled interrupts.

Signed-off-by: Nicholas Piggin 
---
 lib/powerpc/processor.c |  4 ++-
 lib/ppc64/asm/stack.h   |  3 +++
 lib/ppc64/stack.c   | 55 +
 powerpc/Makefile.ppc64  |  1 +
 powerpc/cstart64.S  |  7 --
 5 files changed, 67 insertions(+), 3 deletions(-)
 create mode 100644 lib/ppc64/stack.c

diff --git a/lib/powerpc/processor.c b/lib/powerpc/processor.c
index ad0d95666..114584024 100644
--- a/lib/powerpc/processor.c
+++ b/lib/powerpc/processor.c
@@ -51,7 +51,9 @@ void do_handle_exception(struct pt_regs *regs)
return;
}
 
-   printf("unhandled cpu exception %#lx at NIA:0x%016lx MSR:0x%016lx\n", 
regs->trap, regs->nip, regs->msr);
+   printf("Unhandled cpu exception %#lx at NIA:0x%016lx MSR:0x%016lx\n",
+   regs->trap, regs->nip, regs->msr);
+   dump_frame_stack((void *)regs->nip, (void *)regs->gpr[1]);
abort();
 }
 
diff --git a/lib/ppc64/asm/stack.h b/lib/ppc64/asm/stack.h
index 9734bbb8f..94fd1021c 100644
--- a/lib/ppc64/asm/stack.h
+++ b/lib/ppc64/asm/stack.h
@@ -5,4 +5,7 @@
 #error Do not directly include . Just use .
 #endif
 
+#define HAVE_ARCH_BACKTRACE
+#define HAVE_ARCH_BACKTRACE_FRAME
+
 #endif
diff --git a/lib/ppc64/stack.c b/lib/ppc64/stack.c
new file mode 100644
index 0..fcb7fa860
--- /dev/null
+++ b/lib/ppc64/stack.c
@@ -0,0 +1,55 @@
+#include 
+#include 
+#include 
+
+extern char exception_stack_marker[];
+
+int backtrace_frame(const void *frame, const void **return_addrs, int 
max_depth)
+{
+   static int walking;
+   int depth = 0;
+   const unsigned long *bp = (unsigned long *)frame;
+   void *return_addr;
+
+   asm volatile("" ::: "lr"); /* Force it to save LR */
+
+   if (walking) {
+   printf("RECURSIVE STACK WALK!!!\n");
+   return 0;
+   }
+   walking = 1;
+
+   bp = (unsigned long *)bp[0];
+   return_addr = (void *)bp[2];
+
+   for (depth = 0; bp && depth < max_depth; depth++) {
+   return_addrs[depth] = return_addr;
+   if (return_addrs[depth] == 0)
+   break;
+   if (return_addrs[depth] == exception_stack_marker) {
+   struct pt_regs *regs;
+
+   regs = (void *)bp + STACK_FRAME_OVERHEAD;
+   bp = (unsigned long *)bp[0];
+   /* Represent interrupt frame with vector number */
+   return_addr = (void *)regs->trap;
+   if (depth + 1 < max_depth) {
+   depth++;
+   return_addrs[depth] = return_addr;
+   return_addr = (void *)regs->nip;
+   }
+   } else {
+   bp = (unsigned long *)bp[0];
+   return_addr = (void *)bp[2];
+   }
+   }
+
+   walking = 0;
+   return depth;
+}
+
+int backtrace(const void **return_addrs, int max_depth)
+{
+   return backtrace_frame(__builtin_frame_address(0), return_addrs,
+  max_depth);
+}
diff --git a/powerpc/Makefile.ppc64 b/powerpc/Makefile.ppc64
index b0ed2b104..eb682c226 100644
--- a/powerpc/Makefile.ppc64
+++ b/powerpc/Makefile.ppc64
@@ -17,6 +17,7 @@ cstart.o = $(TEST_DIR)/cstart64.o
 reloc.o  = $(TEST_DIR)/reloc64.o
 
 OBJDIRS += lib/ppc64
+cflatobjs += lib/ppc64/stack.o
 
 # ppc64 specific tests
 tests = $(TEST_DIR)/spapr_vpa.elf
diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S
index 14ab0c6c8..278af84a6 100644
--- a/powerpc/cstart64.S
+++ b/powerpc/cstart64.S
@@ -188,6 +188,7 @@ call_handler:
.endr
mfsprg1 r0
std r0,GPR1(r1)
+   std r0,0(r1)
 
/* lr, xer, ccr */
 
@@ -206,12 +207,12 @@ call_handler:
subir31, r31, 0b - start_text
ld  r2, (p_toc_text - start_text)(r31)
 
-   /* FIXME: build stack frame */
-
/* call generic handler */
 
addir3,r1,STACK_FRAME_OVERHEAD
bl  do_handle_exception
+   .global exception_stack_marker
+exception_stack_marker:
 
/* restore context */
 
@@ -321,6 +322,7 @@ handler_trampoline:
/* nip and msr */
mfsrr0  r0
std r0, _NIP(r1)
+   std r0, INT_FRAME_SIZE+16(r1)
 
mfsrr1  r0
std r0, _MSR(r1)
@@ -337,6 +339,7 @@ handler_htrampoline:
/* nip and msr */
mfspr   r0, SPR_HSRR0
std r0, _NIP(r1)
+   std r0, INT_FRAME_SIZE+16(r1)
 
mfspr   r0, SPR_HSRR1
std r0, _MSR(r1)
-- 
2.42.0



[kvm-unit-tests PATCH 03/32] powerpc: Fix stack backtrace termination

2024-02-26 Thread Nicholas Piggin
The backtrace handler terminates when it sees a NULL caller address,
but the powerpc stack setup does not keep such a NULL caller frame
at the start of the stack.

This happens to work on pseries because the memory at 0 is mapped and
it contains 0 at the location of the return address pointer if it
were a stack frame. But this is fragile, and does not work with powernv
where address 0 contains firmware instructions.

Use the existing dummy frame on stack as the NULL caller, and create a
new frame on stack for the entry code.

Signed-off-by: Nicholas Piggin 
---
 powerpc/cstart64.S | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S
index e18ae9a22..14ab0c6c8 100644
--- a/powerpc/cstart64.S
+++ b/powerpc/cstart64.S
@@ -46,8 +46,16 @@ start:
add r1, r1, r31
add r2, r2, r31
 
+   /* Zero backpointers in initial stack frame so backtrace() stops */
+   li  r0,0
+   std r0,0(r1)
+   std r0,16(r1)
+
+   /* Create entry frame */
+   stdur1,-INT_FRAME_SIZE(r1)
+
/* save DTB pointer */
-   std r3, 56(r1)
+   SAVE_GPR(3,r1)
 
/*
 * Call relocate. relocate is C code, but careful to not use
@@ -101,7 +109,7 @@ start:
stw r4, 0(r3)
 
/* complete setup */
-1: ld  r3, 56(r1)
+1: REST_GPR(3, r1)
bl  setup
 
/* run the test */
-- 
2.42.0



[kvm-unit-tests PATCH 02/32] powerpc: Fix pseries getchar return value

2024-02-26 Thread Nicholas Piggin
getchar() didn't get the shift value correct and never returned the
first character. This never really mattered since it was only ever
used for press-a-key-to-continue prompts. but it tripped me up when
debugging a QEMU console output problem.

Signed-off-by: Nicholas Piggin 
---
 lib/powerpc/hcall.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/powerpc/hcall.c b/lib/powerpc/hcall.c
index 711cb1b0f..b4d39ac65 100644
--- a/lib/powerpc/hcall.c
+++ b/lib/powerpc/hcall.c
@@ -43,5 +43,5 @@ int __getchar(void)
asm volatile (" sc 1 "  : "+r"(r3), "+r"(r4), "=r"(r5)
: "r"(r3),  "r"(r4));
 
-   return r3 == H_SUCCESS && r4 > 0 ? r5 >> 48 : -1;
+   return r3 == H_SUCCESS && r4 > 0 ? r5 >> 56 : -1;
 }
-- 
2.42.0



[kvm-unit-tests PATCH 01/32] powerpc: Fix KVM caps on POWER9 hosts

2024-02-26 Thread Nicholas Piggin
KVM does not like to run on POWER9 hosts without cap-ccf-assist=off.

Signed-off-by: Nicholas Piggin 
---
 powerpc/run | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/powerpc/run b/powerpc/run
index e469f1eb3..5cdb94194 100755
--- a/powerpc/run
+++ b/powerpc/run
@@ -24,6 +24,8 @@ M+=",accel=$ACCEL$ACCEL_PROPS"
 
 if [[ "$ACCEL" == "tcg" ]] ; then
M+=",cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken,cap-ccf-assist=off"
+elif [[ "$ACCEL" == "kvm" ]] ; then
+   M+=",cap-ccf-assist=off"
 fi
 
 command="$qemu -nodefaults $M -bios $FIRMWARE"
-- 
2.42.0



[kvm-unit-tests PATCH 00/32] powerpc improvements

2024-02-26 Thread Nicholas Piggin
This is the same familiar set of powerpc patches, it's taken a
while to get them merged. And unfortunately they keep growing
with fixes and new tests.

This goes on top of the previous migration and other core
patches. Full tree can be found here.

https://gitlab.com/npiggin/kvm-unit-tests/-/tree/powerpc?ref_type=heads

I have tried to test all combinations of KVM and TCG for P8/9/10
and powernv. There are a small number of failures, some due to
bugs in TCG, QEMU, and KVM. I don't want to drop such test cases
but xfail doesn't quite work because it will start failing if we
fix implementation to now work AFAIKS. If there is concern about
that, then maybe we could add a known-failure type of report that
can document the reason and not fail the entire group of tests.

Since last posting, this adds several fixes to the start of the
series, fixes a bunch of bugs in the SPRs and other tests that
Joel and Thomas raised.  Tidied up the new new SMP support and
fixed a couple of issues there. Added MMU, usermode support,
add atomics, timebase, PMU tests, and removes the ppc64
subdirectories.

Thanks,
Nick

Nicholas Piggin (32):
  powerpc: Fix KVM caps on POWER9 hosts
  powerpc: Fix pseries getchar return value
  powerpc: Fix stack backtrace termination
  powerpc: interrupt stack backtracing
  powerpc: Cleanup SPR and MSR definitions
  powerpc/sprs: Specify SPRs with data rather than code
  powerpc/sprs: Don't fail changed SPRs that are used by the test
harness
  powerpc/sprs: Avoid taking PMU interrupts caused by register fuzzing
  scripts: allow machine option to be specified in unittests.cfg
  scripts: Accommodate powerpc powernv machine differences
  powerpc: Support powernv machine with QEMU TCG
  powerpc: Fix emulator illegal instruction test for powernv
  powerpc/sprs: Test hypervisor registers on powernv machine
  powerpc: general interrupt tests
  powerpc: Add rtas stop-self support
  powerpc: Remove broken SMP exception stack setup
  arch-run: Fix handling multiple exit status messages
  powerpc: add SMP and IPI support
  powerpc: Permit ACCEL=tcg,thread=single
  powerpc: Avoid using larx/stcx. in spinlocks when only one CPU is
running
  powerpc: Add atomics tests
  powerpc: Add timebase tests
  powerpc: Add MMU support
  common/sieve: Use vmalloc.h for setup_mmu definition
  common/sieve: Support machines without MMU
  powerpc: Add sieve.c common test
  powerpc: add usermode support
  powerpc: add pmu tests
  configure: Fail on unknown arch
  configure: Make arch_libdir a first-class entity
  powerpc: Remove remnants of ppc64 directory and build structure
  powerpc: gitlab CI update

 .gitlab-ci.yml   |  16 +-
 MAINTAINERS  |   1 -
 Makefile |   2 +-
 common/sieve.c   |  15 +-
 configure|  69 ++-
 lib/libcflat.h   |   2 -
 lib/{ppc64 => powerpc}/asm-offsets.c |   7 +
 lib/{ppc64 => powerpc}/asm/asm-offsets.h |   0
 lib/powerpc/asm/atomic.h |   6 +
 lib/powerpc/asm/barrier.h|  12 +
 lib/{ppc64 => powerpc}/asm/bitops.h  |   4 +-
 lib/powerpc/asm/hcall.h  |   6 +
 lib/{ppc64 => powerpc}/asm/io.h  |   4 +-
 lib/powerpc/asm/mmu.h|  10 +
 lib/powerpc/asm/opal.h   |  22 +
 lib/powerpc/asm/page.h   |  66 +++
 lib/powerpc/asm/pgtable-hwdef.h  |  67 +++
 lib/powerpc/asm/pgtable.h| 126 +
 lib/powerpc/asm/ppc_asm.h|   8 +-
 lib/powerpc/asm/processor.h  |  68 ++-
 lib/{ppc64 => powerpc}/asm/ptrace.h  |  22 +-
 lib/powerpc/asm/reg.h|  72 +++
 lib/powerpc/asm/rtas.h   |   2 +
 lib/powerpc/asm/setup.h  |   3 +-
 lib/powerpc/asm/smp.h|  50 +-
 lib/powerpc/asm/spinlock.h   |  11 +
 lib/powerpc/asm/stack.h  |   3 +
 lib/powerpc/asm/time.h   |   1 +
 lib/{ppc64 => powerpc}/asm/vpa.h |   0
 lib/powerpc/hcall.c  |   6 +-
 lib/powerpc/io.c |  41 +-
 lib/powerpc/io.h |   6 +
 lib/powerpc/mmu.c| 275 +
 lib/powerpc/opal-calls.S |  50 ++
 lib/powerpc/opal.c   |  76 +++
 lib/powerpc/processor.c  |  91 ++-
 lib/powerpc/rtas.c   |  81 ++-
 lib/powerpc/setup.c  | 159 +-
 lib/powerpc/smp.c| 287 --
 lib/powerpc/spinlock.c   |  32 ++
 lib/powerpc/stack.c  |  55 ++
 lib/ppc64/.gitignore |   1 -
 lib/ppc64/asm/barrier.h  |   9 -
 lib/ppc64/asm/handlers.h |   1 -
 lib/ppc64/asm/hcall.h|   1 -
 lib/ppc64/asm/memory_areas.h |   6 -
 

[kvm-unit-tests PATCH 7/7] common: add memory dirtying vs migration test

2024-02-26 Thread Nicholas Piggin
This test stores to a bunch of pages and verifies previous stores,
while being continually migrated. This can fail due to a QEMU TCG
physical memory dirty bitmap bug.

Signed-off-by: Nicholas Piggin 
---
 common/memory-verify.c  | 48 +
 powerpc/Makefile.common |  1 +
 powerpc/memory-verify.c |  1 +
 powerpc/unittests.cfg   |  7 ++
 s390x/Makefile  |  1 +
 s390x/memory-verify.c   |  1 +
 s390x/unittests.cfg |  6 ++
 7 files changed, 65 insertions(+)
 create mode 100644 common/memory-verify.c
 create mode 12 powerpc/memory-verify.c
 create mode 12 s390x/memory-verify.c

diff --git a/common/memory-verify.c b/common/memory-verify.c
new file mode 100644
index 0..7c4ec087b
--- /dev/null
+++ b/common/memory-verify.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Simple memory verification test, used to exercise dirty memory migration.
+ *
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define NR_PAGES 32
+
+int main(int argc, char **argv)
+{
+   void *mem = malloc(NR_PAGES*PAGE_SIZE);
+   bool success = true;
+   uint64_t ms;
+   long i;
+
+   report_prefix_push("memory");
+
+   memset(mem, 0, NR_PAGES*PAGE_SIZE);
+
+   migrate_begin_continuous();
+   ms = get_clock_ms();
+   i = 0;
+   do {
+   int j;
+
+   for (j = 0; j < NR_PAGES*PAGE_SIZE; j += PAGE_SIZE) {
+   if (*(volatile long *)(mem + j) != i) {
+   success = false;
+   goto out;
+   }
+   *(volatile long *)(mem + j) = i + 1;
+   }
+   i++;
+   } while (get_clock_ms() - ms < 5000);
+out:
+   migrate_end_continuous();
+
+   report(success, "memory verification stress test");
+
+   report_prefix_pop();
+
+   return report_summary();
+}
diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
index da4a7bbb8..1e181da69 100644
--- a/powerpc/Makefile.common
+++ b/powerpc/Makefile.common
@@ -7,6 +7,7 @@
 tests-common = \
$(TEST_DIR)/selftest.elf \
$(TEST_DIR)/selftest-migration.elf \
+   $(TEST_DIR)/memory-verify.elf \
$(TEST_DIR)/spapr_hcall.elf \
$(TEST_DIR)/rtas.elf \
$(TEST_DIR)/emulator.elf \
diff --git a/powerpc/memory-verify.c b/powerpc/memory-verify.c
new file mode 12
index 0..5985c730f
--- /dev/null
+++ b/powerpc/memory-verify.c
@@ -0,0 +1 @@
+../common/memory-verify.c
\ No newline at end of file
diff --git a/powerpc/unittests.cfg b/powerpc/unittests.cfg
index 89abf2095..fadd8dde6 100644
--- a/powerpc/unittests.cfg
+++ b/powerpc/unittests.cfg
@@ -46,6 +46,13 @@ machine = pseries
 groups = selftest migration
 extra_params = -append "skip"
 
+# This fails due to a QEMU TCG bug so KVM-only until QEMU is fixed upstream
+[migration-memory]
+file = memory-verify.elf
+accel = kvm
+machine = pseries
+groups = migration
+
 [spapr_hcall]
 file = spapr_hcall.elf
 
diff --git a/s390x/Makefile b/s390x/Makefile
index 344d46d68..ddc0969f3 100644
--- a/s390x/Makefile
+++ b/s390x/Makefile
@@ -1,5 +1,6 @@
 tests = $(TEST_DIR)/selftest.elf
 tests += $(TEST_DIR)/selftest-migration.elf
+tests += $(TEST_DIR)/memory-verify.elf
 tests += $(TEST_DIR)/intercept.elf
 tests += $(TEST_DIR)/emulator.elf
 tests += $(TEST_DIR)/sieve.elf
diff --git a/s390x/memory-verify.c b/s390x/memory-verify.c
new file mode 12
index 0..5985c730f
--- /dev/null
+++ b/s390x/memory-verify.c
@@ -0,0 +1 @@
+../common/memory-verify.c
\ No newline at end of file
diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg
index f613602d3..a88fe9e79 100644
--- a/s390x/unittests.cfg
+++ b/s390x/unittests.cfg
@@ -33,6 +33,12 @@ file = selftest-migration.elf
 groups = selftest migration
 extra_params = -append "skip"
 
+# This fails due to a QEMU TCG bug so KVM-only until QEMU is fixed upstream
+[migration-memory]
+file = memory-verify.elf
+accel = kvm
+groups = migration
+
 [intercept]
 file = intercept.elf
 
-- 
2.42.0



[kvm-unit-tests PATCH 6/7] gitlab-ci: Run migration selftest on s390x and powerpc

2024-02-26 Thread Nicholas Piggin
The migration harness is complicated and easy to break so CI will
be helpful.

Signed-off-by: Nicholas Piggin 
---
 .gitlab-ci.yml | 18 +++---
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 71d986e98..61f196d5d 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -64,26 +64,28 @@ build-arm:
 build-ppc64be:
  extends: .outoftree_template
  script:
- - dnf install -y qemu-system-ppc gcc-powerpc64-linux-gnu
+ - dnf install -y qemu-system-ppc gcc-powerpc64-linux-gnu nmap-ncat
  - mkdir build
  - cd build
  - ../configure --arch=ppc64 --endian=big --cross-prefix=powerpc64-linux-gnu-
  - make -j2
  - ACCEL=tcg ./run_tests.sh
- selftest-setup spapr_hcall rtas-get-time-of-day rtas-get-time-of-day-base
- rtas-set-time-of-day emulator
+ selftest-setup selftest-migration selftest-migration-skip spapr_hcall
+ rtas-get-time-of-day rtas-get-time-of-day-base rtas-set-time-of-day
+ emulator
  | tee results.txt
  - if grep -q FAIL results.txt ; then exit 1 ; fi
 
 build-ppc64le:
  extends: .intree_template
  script:
- - dnf install -y qemu-system-ppc gcc-powerpc64-linux-gnu
+ - dnf install -y qemu-system-ppc gcc-powerpc64-linux-gnu nmap-ncat
  - ./configure --arch=ppc64 --endian=little --cross-prefix=powerpc64-linux-gnu-
  - make -j2
  - ACCEL=tcg ./run_tests.sh
- selftest-setup spapr_hcall rtas-get-time-of-day rtas-get-time-of-day-base
- rtas-set-time-of-day emulator
+ selftest-setup selftest-migration selftest-migration-skip spapr_hcall
+ rtas-get-time-of-day rtas-get-time-of-day-base rtas-set-time-of-day
+ emulator
  | tee results.txt
  - if grep -q FAIL results.txt ; then exit 1 ; fi
 
@@ -107,7 +109,7 @@ build-riscv64:
 build-s390x:
  extends: .outoftree_template
  script:
- - dnf install -y qemu-system-s390x gcc-s390x-linux-gnu
+ - dnf install -y qemu-system-s390x gcc-s390x-linux-gnu nmap-ncat
  - mkdir build
  - cd build
  - ../configure --arch=s390x --cross-prefix=s390x-linux-gnu-
@@ -133,6 +135,8 @@ build-s390x:
   sclp-1g
   sclp-3g
   selftest-setup
+  selftest-migration
+  selftest-migration-skip
   sieve
   smp
   stsi
-- 
2.42.0



[kvm-unit-tests PATCH 5/7] arch-run: Add a "continuous" migration option for tests

2024-02-26 Thread Nicholas Piggin
The cooperative migration protocol is very good to control precise
pre and post conditions for a migration event. However in some cases
its intrusiveness to the test program, can mask problems and make
analysis more difficult.

For example to stress test migration vs concurrent complicated
memory access, including TLB refill, ram dirtying, etc., then the
tight spin at getchar() and resumption of the workload after
migration is unhelpful.

This adds a continuous migration mode that directs the harness to
perform migrations continually. This is added to the migration
selftests, which also sees cooperative migration iterations reduced
to avoid increasing test time too much.

Signed-off-by: Nicholas Piggin 
---
 common/selftest-migration.c | 16 +--
 lib/migrate.c   | 18 
 lib/migrate.h   |  3 ++
 scripts/arch-run.bash   | 55 -
 4 files changed, 82 insertions(+), 10 deletions(-)

diff --git a/common/selftest-migration.c b/common/selftest-migration.c
index 0afd8581c..9a9b61835 100644
--- a/common/selftest-migration.c
+++ b/common/selftest-migration.c
@@ -9,12 +9,13 @@
  */
 #include 
 #include 
+#include 
 
-#define NR_MIGRATIONS 30
+#define NR_MIGRATIONS 15
 
 int main(int argc, char **argv)
 {
-   report_prefix_push("migration");
+   report_prefix_push("migration harness");
 
if (argc > 1 && !strcmp(argv[1], "skip")) {
migrate_skip();
@@ -24,7 +25,16 @@ int main(int argc, char **argv)
 
for (i = 0; i < NR_MIGRATIONS; i++)
migrate_quiet();
-   report(true, "simple harness stress");
+   report(true, "cooperative migration");
+
+   migrate_begin_continuous();
+   mdelay(2000);
+   migrate_end_continuous();
+   mdelay(1000);
+   migrate_begin_continuous();
+   mdelay(2000);
+   migrate_end_continuous();
+   report(true, "continuous migration");
}
 
report_prefix_pop();
diff --git a/lib/migrate.c b/lib/migrate.c
index 1d22196b7..770f76d5c 100644
--- a/lib/migrate.c
+++ b/lib/migrate.c
@@ -60,3 +60,21 @@ void migrate_skip(void)
puts("Skipped VM migration (quiet)\n");
(void)getchar();
 }
+
+void migrate_begin_continuous(void)
+{
+   puts("Begin continuous migration\n");
+   (void)getchar();
+}
+
+void migrate_end_continuous(void)
+{
+   /*
+* Migration can split this output between source and dest QEMU
+* output files, print twice and match once to always cope with
+* a split.
+*/
+   puts("End continuous migration\n");
+   puts("End continuous migration (quiet)\n");
+   (void)getchar();
+}
diff --git a/lib/migrate.h b/lib/migrate.h
index db6e0c501..35b6703a2 100644
--- a/lib/migrate.h
+++ b/lib/migrate.h
@@ -11,3 +11,6 @@ void migrate_quiet(void);
 void migrate_once(void);
 
 void migrate_skip(void);
+
+void migrate_begin_continuous(void);
+void migrate_end_continuous(void);
diff --git a/scripts/arch-run.bash b/scripts/arch-run.bash
index d0f6f098f..5c7e72036 100644
--- a/scripts/arch-run.bash
+++ b/scripts/arch-run.bash
@@ -125,15 +125,17 @@ qmp_events ()
 filter_quiet_msgs ()
 {
grep -v "Now migrate the VM (quiet)" |
+   grep -v "Begin continuous migration (quiet)" |
+   grep -v "End continuous migration (quiet)" |
grep -v "Skipped VM migration (quiet)"
 }
 
 seen_migrate_msg ()
 {
if [ $skip_migration -eq 1 ]; then
-   grep -q -e "Now migrate the VM" < $1
+   grep -q -e "Now migrate the VM" -e "Begin continuous migration" 
< $1
else
-   grep -q -e "Now migrate the VM" -e "Skipped VM migration" < $1
+   grep -q -e "Now migrate the VM" -e "Begin continuous migration" 
-e "Skipped VM migration" < $1
fi
 }
 
@@ -161,6 +163,7 @@ run_migration ()
src_qmpout=/dev/null
dst_qmpout=/dev/null
skip_migration=0
+   continuous_migration=0
 
mkfifo ${src_outfifo}
mkfifo ${dst_outfifo}
@@ -186,9 +189,12 @@ run_migration ()
do_migration || return $?
 
while ps -p ${live_pid} > /dev/null ; do
-   # Wait for test exit or further migration messages.
-   if ! seen_migrate_msg ${src_out} ;  then
+   if [[ ${continuous_migration} -eq 1 ]] ; then
+   do_migration || return $?
+   elif ! seen_migrate_msg ${src_out} ;  then
sleep 0.1
+   elif grep -q "Begin continuous migration" < ${src_out} ; then
+   do_migration || return $?
elif grep -q "Now migrate the VM" < ${src_out} ; then
do_migration || return $?
elif [ $skip_migration -eq 0 ] && grep -q "Skipped VM 
migration" < ${src_out} ; then
@@ -218,7 +224,7 @@ do_migration ()
 
# The test must 

[kvm-unit-tests PATCH 4/7] powerpc: add asm/time.h header with delay and get_clock_us/ms

2024-02-26 Thread Nicholas Piggin
This matches s390x clock and delay APIs, so common test code can start
using time facilities.

Signed-off-by: Nicholas Piggin 
---
 lib/powerpc/asm/processor.h | 21 -
 lib/powerpc/asm/time.h  | 30 ++
 lib/powerpc/processor.c | 11 +++
 lib/powerpc/smp.c   |  1 +
 lib/ppc64/asm/time.h|  1 +
 powerpc/spapr_vpa.c |  1 +
 powerpc/sprs.c  |  1 +
 powerpc/tm.c|  1 +
 8 files changed, 46 insertions(+), 21 deletions(-)
 create mode 100644 lib/powerpc/asm/time.h
 create mode 100644 lib/ppc64/asm/time.h

diff --git a/lib/powerpc/asm/processor.h b/lib/powerpc/asm/processor.h
index 4ad6612b3..fe1052939 100644
--- a/lib/powerpc/asm/processor.h
+++ b/lib/powerpc/asm/processor.h
@@ -43,25 +43,4 @@ static inline void mtmsr(uint64_t msr)
asm volatile ("mtmsrd %[msr]" :: [msr] "r" (msr) : "memory");
 }
 
-static inline uint64_t get_tb(void)
-{
-   return mfspr(SPR_TB);
-}
-
-extern void delay(uint64_t cycles);
-extern void udelay(uint64_t us);
-extern void sleep_tb(uint64_t cycles);
-extern void usleep(uint64_t us);
-
-static inline void mdelay(uint64_t ms)
-{
-   while (ms--)
-   udelay(1000);
-}
-
-static inline void msleep(uint64_t ms)
-{
-   usleep(ms * 1000);
-}
-
 #endif /* _ASMPOWERPC_PROCESSOR_H_ */
diff --git a/lib/powerpc/asm/time.h b/lib/powerpc/asm/time.h
new file mode 100644
index 0..72fcb1bd0
--- /dev/null
+++ b/lib/powerpc/asm/time.h
@@ -0,0 +1,30 @@
+#ifndef _ASMPOWERPC_TIME_H_
+#define _ASMPOWERPC_TIME_H_
+
+#include 
+#include 
+
+static inline uint64_t get_tb(void)
+{
+   return mfspr(SPR_TB);
+}
+
+extern uint64_t get_clock_us(void);
+extern uint64_t get_clock_ms(void);
+extern void delay(uint64_t cycles);
+extern void udelay(uint64_t us);
+extern void sleep_tb(uint64_t cycles);
+extern void usleep(uint64_t us);
+
+static inline void mdelay(uint64_t ms)
+{
+   while (ms--)
+   udelay(1000);
+}
+
+static inline void msleep(uint64_t ms)
+{
+   usleep(ms * 1000);
+}
+
+#endif /* _ASMPOWERPC_TIME_H_ */
diff --git a/lib/powerpc/processor.c b/lib/powerpc/processor.c
index b224fc8eb..ad0d95666 100644
--- a/lib/powerpc/processor.c
+++ b/lib/powerpc/processor.c
@@ -7,6 +7,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -54,6 +55,16 @@ void do_handle_exception(struct pt_regs *regs)
abort();
 }
 
+uint64_t get_clock_us(void)
+{
+   return get_tb() * 100 / tb_hz;
+}
+
+uint64_t get_clock_ms(void)
+{
+   return get_tb() * 1000 / tb_hz;
+}
+
 void delay(uint64_t cycles)
 {
uint64_t start = get_tb();
diff --git a/lib/powerpc/smp.c b/lib/powerpc/smp.c
index afe436179..3e211eba8 100644
--- a/lib/powerpc/smp.c
+++ b/lib/powerpc/smp.c
@@ -7,6 +7,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
diff --git a/lib/ppc64/asm/time.h b/lib/ppc64/asm/time.h
new file mode 100644
index 0..326d2887a
--- /dev/null
+++ b/lib/ppc64/asm/time.h
@@ -0,0 +1 @@
+#include "../../powerpc/asm/time.h"
diff --git a/powerpc/spapr_vpa.c b/powerpc/spapr_vpa.c
index 6a3fe5e3f..c2075e157 100644
--- a/powerpc/spapr_vpa.c
+++ b/powerpc/spapr_vpa.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
diff --git a/powerpc/sprs.c b/powerpc/sprs.c
index 57e487ceb..285976488 100644
--- a/powerpc/sprs.c
+++ b/powerpc/sprs.c
@@ -26,6 +26,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 uint64_t before[1024], after[1024];
diff --git a/powerpc/tm.c b/powerpc/tm.c
index 7fa916366..6b1ceeb6e 100644
--- a/powerpc/tm.c
+++ b/powerpc/tm.c
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
-- 
2.42.0



[kvm-unit-tests PATCH 3/7] (arm|s390): Use migrate_skip in test cases

2024-02-26 Thread Nicholas Piggin
Have tests use the new migrate_skip command in skip paths, rather than
calling migrate_once to prevent harness reporting an error.

s390x/migration.c adds a new command that looks like it was missing
previously.

Signed-off-by: Nicholas Piggin 
---
 arm/gic.c  | 21 -
 s390x/migration-cmm.c  |  8 
 s390x/migration-skey.c |  4 +++-
 s390x/migration.c  |  1 +
 4 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/arm/gic.c b/arm/gic.c
index c950b0d15..bbf828f17 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -782,13 +782,15 @@ static void test_its_migration(void)
struct its_device *dev2, *dev7;
cpumask_t mask;
 
-   if (its_setup1())
+   if (its_setup1()) {
+   migrate_skip();
return;
+   }
 
dev2 = its_get_device(2);
dev7 = its_get_device(7);
 
-   migrate_once();
+   migrate();
 
stats_reset();
cpumask_clear();
@@ -819,8 +821,10 @@ static void test_migrate_unmapped_collection(void)
int pe0 = 0;
u8 config;
 
-   if (its_setup1())
+   if (its_setup1()) {
+   migrate_skip();
return;
+   }
 
if (!errata(ERRATA_UNMAPPED_COLLECTIONS)) {
report_skip("Skipping test, as this test hangs without the fix. 
"
@@ -836,7 +840,7 @@ static void test_migrate_unmapped_collection(void)
its_send_mapti(dev2, 8192, 0, col);
gicv3_lpi_set_config(8192, LPI_PROP_DEFAULT);
 
-   migrate_once();
+   migrate();
 
/* on the destination, map the collection */
its_send_mapc(col, true);
@@ -875,8 +879,10 @@ static void test_its_pending_migration(void)
void *ptr;
int i;
 
-   if (its_prerequisites(4))
+   if (its_prerequisites(4)) {
+   migrate_skip();
return;
+   }
 
dev = its_create_device(2 /* dev id */, 8 /* nb_ites */);
its_send_mapd(dev, true);
@@ -923,7 +929,7 @@ static void test_its_pending_migration(void)
gicv3_lpi_rdist_enable(pe0);
gicv3_lpi_rdist_enable(pe1);
 
-   migrate_once();
+   migrate();
 
/* let's wait for the 256 LPIs to be handled */
mdelay(1000);
@@ -970,17 +976,14 @@ int main(int argc, char **argv)
} else if (!strcmp(argv[1], "its-migration")) {
report_prefix_push(argv[1]);
test_its_migration();
-   migrate_once();
report_prefix_pop();
} else if (!strcmp(argv[1], "its-pending-migration")) {
report_prefix_push(argv[1]);
test_its_pending_migration();
-   migrate_once();
report_prefix_pop();
} else if (!strcmp(argv[1], "its-migrate-unmapped-collection")) {
report_prefix_push(argv[1]);
test_migrate_unmapped_collection();
-   migrate_once();
report_prefix_pop();
} else if (strcmp(argv[1], "its-introspection") == 0) {
report_prefix_push(argv[1]);
diff --git a/s390x/migration-cmm.c b/s390x/migration-cmm.c
index 43673f18e..b4043a80e 100644
--- a/s390x/migration-cmm.c
+++ b/s390x/migration-cmm.c
@@ -55,12 +55,12 @@ int main(void)
 {
report_prefix_push("migration-cmm");
 
-   if (!check_essa_available())
+   if (!check_essa_available()) {
report_skip("ESSA is not available");
-   else
+   migrate_skip();
+   } else {
test_migration();
-
-   migrate_once();
+   }
 
report_prefix_pop();
return report_summary();
diff --git a/s390x/migration-skey.c b/s390x/migration-skey.c
index 8d6d8ecfe..1a196ae1e 100644
--- a/s390x/migration-skey.c
+++ b/s390x/migration-skey.c
@@ -169,6 +169,7 @@ static void test_skey_migration_parallel(void)
 
if (smp_query_num_cpus() == 1) {
report_skip("need at least 2 cpus for this test");
+   migrate_skip();
goto error;
}
 
@@ -233,6 +234,7 @@ int main(int argc, char **argv)
 
if (test_facility(169)) {
report_skip("storage key removal facility is active");
+   migrate_skip();
goto error;
}
 
@@ -247,11 +249,11 @@ int main(int argc, char **argv)
break;
default:
print_usage();
+   migrate_skip();
break;
}
 
 error:
-   migrate_once();
report_prefix_pop();
return report_summary();
 }
diff --git a/s390x/migration.c b/s390x/migration.c
index 269e272de..115afb731 100644
--- a/s390x/migration.c
+++ b/s390x/migration.c
@@ -164,6 +164,7 @@ int main(void)
 
if (smp_query_num_cpus() == 1) {
report_skip("need at least 2 cpus for this test");
+   migrate_skip();
goto done;
}
 
-- 
2.42.0



[kvm-unit-tests PATCH 2/7] migration: Add a migrate_skip command

2024-02-26 Thread Nicholas Piggin
Tests that are run with MIGRATION=yes but skip due to some requirement
not being met will show as a failure due to the harness requirement to
see one successful migration. The workaround for this is to migrate in
test's skip path. Add a new command that just tells the harness to not
expect a migration.

Signed-off-by: Nicholas Piggin 
---
 common/selftest-migration.c | 14 -
 lib/migrate.c   | 19 -
 lib/migrate.h   |  2 ++
 powerpc/unittests.cfg   |  6 ++
 s390x/unittests.cfg |  5 +
 scripts/arch-run.bash   | 41 +
 6 files changed, 73 insertions(+), 14 deletions(-)

diff --git a/common/selftest-migration.c b/common/selftest-migration.c
index 54b5d6b2d..0afd8581c 100644
--- a/common/selftest-migration.c
+++ b/common/selftest-migration.c
@@ -14,14 +14,18 @@
 
 int main(int argc, char **argv)
 {
-   int i = 0;
-
report_prefix_push("migration");
 
-   for (i = 0; i < NR_MIGRATIONS; i++)
-   migrate_quiet();
+   if (argc > 1 && !strcmp(argv[1], "skip")) {
+   migrate_skip();
+   report(true, "migration skipping");
+   } else {
+   int i;
 
-   report(true, "simple harness stress test");
+   for (i = 0; i < NR_MIGRATIONS; i++)
+   migrate_quiet();
+   report(true, "simple harness stress");
+   }
 
report_prefix_pop();
 
diff --git a/lib/migrate.c b/lib/migrate.c
index 92d1d957d..1d22196b7 100644
--- a/lib/migrate.c
+++ b/lib/migrate.c
@@ -39,7 +39,24 @@ void migrate_once(void)
 
if (migrated)
return;
-
migrated = true;
+
migrate();
 }
+
+/*
+ * When the test has been started in migration mode, but the test case is
+ * skipped and no migration point is reached, this can be used to tell the
+ * harness not to mark it as a failure to migrate.
+ */
+void migrate_skip(void)
+{
+   static bool did_migrate_skip;
+
+   if (did_migrate_skip)
+   return;
+   did_migrate_skip = true;
+
+   puts("Skipped VM migration (quiet)\n");
+   (void)getchar();
+}
diff --git a/lib/migrate.h b/lib/migrate.h
index 95b9102b0..db6e0c501 100644
--- a/lib/migrate.h
+++ b/lib/migrate.h
@@ -9,3 +9,5 @@
 void migrate(void);
 void migrate_quiet(void);
 void migrate_once(void);
+
+void migrate_skip(void);
diff --git a/powerpc/unittests.cfg b/powerpc/unittests.cfg
index 7ce57de02..89abf2095 100644
--- a/powerpc/unittests.cfg
+++ b/powerpc/unittests.cfg
@@ -40,6 +40,12 @@ groups = selftest
 file = selftest-migration.elf
 groups = selftest migration
 
+[selftest-migration-skip]
+file = selftest-migration.elf
+machine = pseries
+groups = selftest migration
+extra_params = -append "skip"
+
 [spapr_hcall]
 file = spapr_hcall.elf
 
diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg
index a7ad522ca..f613602d3 100644
--- a/s390x/unittests.cfg
+++ b/s390x/unittests.cfg
@@ -28,6 +28,11 @@ extra_params = -append 'test 123'
 file = selftest-migration.elf
 groups = selftest migration
 
+[selftest-migration-skip]
+file = selftest-migration.elf
+groups = selftest migration
+extra_params = -append "skip"
+
 [intercept]
 file = intercept.elf
 
diff --git a/scripts/arch-run.bash b/scripts/arch-run.bash
index e5b36a07b..d0f6f098f 100644
--- a/scripts/arch-run.bash
+++ b/scripts/arch-run.bash
@@ -124,12 +124,17 @@ qmp_events ()
 
 filter_quiet_msgs ()
 {
-   grep -v "Now migrate the VM (quiet)"
+   grep -v "Now migrate the VM (quiet)" |
+   grep -v "Skipped VM migration (quiet)"
 }
 
 seen_migrate_msg ()
 {
-   grep -q -e "Now migrate the VM" < $1
+   if [ $skip_migration -eq 1 ]; then
+   grep -q -e "Now migrate the VM" < $1
+   else
+   grep -q -e "Now migrate the VM" -e "Skipped VM migration" < $1
+   fi
 }
 
 run_migration ()
@@ -142,7 +147,7 @@ run_migration ()
migcmdline=$@
 
trap 'trap - TERM ; kill 0 ; exit 2' INT TERM
-   trap 'rm -f ${src_out} ${dst_out} ${src_outfifo} ${dst_outfifo} 
${dst_incoming} ${src_qmp} ${dst_qmp} ${dst_infifo}' RETURN EXIT
+   trap 'rm -f ${src_out} ${dst_out} ${src_outfifo} ${dst_outfifo} 
${dst_incoming} ${src_qmp} ${dst_qmp} ${src_infifo} ${dst_infifo}' RETURN EXIT
 
dst_incoming=$(mktemp -u -t mig-helper-socket-incoming.XX)
src_out=$(mktemp -t mig-helper-stdout1.XX)
@@ -151,21 +156,26 @@ run_migration ()
dst_outfifo=$(mktemp -u -t mig-helper-fifo-stdout2.XX)
src_qmp=$(mktemp -u -t mig-helper-qmp1.XX)
dst_qmp=$(mktemp -u -t mig-helper-qmp2.XX)
-   dst_infifo=$(mktemp -u -t mig-helper-fifo-stdin.XX)
+   src_infifo=$(mktemp -u -t mig-helper-fifo-stdin1.XX)
+   dst_infifo=$(mktemp -u -t mig-helper-fifo-stdin2.XX)
src_qmpout=/dev/null
dst_qmpout=/dev/null
+   skip_migration=0
 
mkfifo ${src_outfifo}
   

[kvm-unit-tests PATCH 1/7] arch-run: Keep infifo open

2024-02-26 Thread Nicholas Piggin
The infifo fifo that is used to send characters to QEMU console is
only able to receive one character before the cat process exits.
Supporting interactions between test and harness involving multiple
characters requires the fifo to remain open.

This also allows us to let the cat out of the bag, simplifying the
input pipeline.

Signed-off-by: Nicholas Piggin 
---
 scripts/arch-run.bash | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/scripts/arch-run.bash b/scripts/arch-run.bash
index 6daef3218..e5b36a07b 100644
--- a/scripts/arch-run.bash
+++ b/scripts/arch-run.bash
@@ -158,6 +158,11 @@ run_migration ()
mkfifo ${src_outfifo}
mkfifo ${dst_outfifo}
 
+   # Holding both ends of the input fifo open prevents opens from
+   # blocking and readers getting EOF when a writer closes it.
+   mkfifo ${dst_infifo}
+   exec {dst_infifo_fd}<>${dst_infifo}
+
eval "$migcmdline" \
-chardev socket,id=mon,path=${src_qmp},server=on,wait=off \
-mon chardev=mon,mode=control > ${src_outfifo} &
@@ -191,14 +196,10 @@ run_migration ()
 
 do_migration ()
 {
-   # We have to use cat to open the named FIFO, because named FIFO's,
-   # unlike pipes, will block on open() until the other end is also
-   # opened, and that totally breaks QEMU...
-   mkfifo ${dst_infifo}
eval "$migcmdline" \
-chardev socket,id=mon,path=${dst_qmp},server=on,wait=off \
-mon chardev=mon,mode=control -incoming unix:${dst_incoming} \
-   < <(cat ${dst_infifo}) > ${dst_outfifo} &
+   < ${dst_infifo} > ${dst_outfifo} &
incoming_pid=$!
cat ${dst_outfifo} | tee ${dst_out} | filter_quiet_msgs &
 
@@ -245,7 +246,6 @@ do_migration ()
 
# keypress to dst so getchar completes and test continues
echo > ${dst_infifo}
-   rm ${dst_infifo}
 
# Ensure the incoming socket is removed, ready for next destination
if [ -S ${dst_incoming} ] ; then
-- 
2.42.0



[kvm-unit-tests PATCH 0/7] more migration enhancements and tests

2024-02-26 Thread Nicholas Piggin
This series applies on top of the multi-migration patches and just
has assorted things I've been collecting.

- New migrate_skip() command that tidies up the wart of using
  migrate_once() to skip migration.
- New "continuous migration" mode where the harness just
  migrates the test contually while it is running.
- Put some migration tests in gitlab CI for powerpc and s390.
- Add a test case that can reproduce the QEMU TCG dirty bitmap
  migration bug.

Nicholas Piggin (7):
  arch-run: Keep infifo open
  migration: Add a migrate_skip command
  (arm|s390): Use migrate_skip in test cases
  powerpc: add asm/time.h header with delay and get_clock_us/ms
  arch-run: Add a "continuous" migration option for tests
  gitlab-ci: Run migration selftest on s390x and powerpc
  common: add memory dirtying vs migration test

 .gitlab-ci.yml  |  18 ---
 arm/gic.c   |  21 
 common/memory-verify.c  |  48 +
 common/selftest-migration.c |  26 ++---
 lib/migrate.c   |  37 -
 lib/migrate.h   |   5 ++
 lib/powerpc/asm/processor.h |  21 
 lib/powerpc/asm/time.h  |  30 +++
 lib/powerpc/processor.c |  11 
 lib/powerpc/smp.c   |   1 +
 lib/ppc64/asm/time.h|   1 +
 powerpc/Makefile.common |   1 +
 powerpc/memory-verify.c |   1 +
 powerpc/spapr_vpa.c |   1 +
 powerpc/sprs.c  |   1 +
 powerpc/tm.c|   1 +
 powerpc/unittests.cfg   |  13 +
 s390x/Makefile  |   1 +
 s390x/memory-verify.c   |   1 +
 s390x/migration-cmm.c   |   8 +--
 s390x/migration-skey.c  |   4 +-
 s390x/migration.c   |   1 +
 s390x/unittests.cfg |  11 
 scripts/arch-run.bash   | 104 +---
 24 files changed, 299 insertions(+), 68 deletions(-)
 create mode 100644 common/memory-verify.c
 create mode 100644 lib/powerpc/asm/time.h
 create mode 100644 lib/ppc64/asm/time.h
 create mode 12 powerpc/memory-verify.c
 create mode 12 s390x/memory-verify.c

-- 
2.42.0



Re: [PATCH v5 0/6] DCP as trusted keys backend

2024-02-26 Thread Jarkko Sakkinen
On Mon Feb 26, 2024 at 12:20 AM EET, Richard Weinberger wrote:
> Mimi, James, Jarkko, David,
>
> you remained silent for a whole release cycle.
> Is there anything we can do to get this forward?
>
> Thanks,
> //richard

Thanks for reminding.

>From my side, I've had pretty busy month as I've adapted to a new work
project: https://sochub.fi/

I exported the thread [1] and will look into it within this or next week
in detail (thus the large'ish time window).

[1] 
https://lore.kernel.org/linux-integrity/1733761.uacIGzncQW@somecomputer/t.mbox.gz

BR, Jarkko


Re: [kvm-unit-tests PATCH v5 0/8] Multi-migration support

2024-02-26 Thread Thomas Huth

On 26/02/2024 09.10, Nicholas Piggin wrote:

On Fri Feb 23, 2024 at 5:06 PM AEST, Thomas Huth wrote:

On 21/02/2024 04.27, Nicholas Piggin wrote:

Now that strange arm64 hang is found to be QEMU bug, I'll repost.
Since arm64 requires Thomas's uart patch and it is worse affected
by the QEMU bug, I will just not build it on arm. The QEMU bug
still affects powerpc (and presumably s390x) but it's not causing
so much trouble for this test case.

I have another test case that can hit it reliably and doesn't
cause crashes but that takes some harness and common lib work so
I'll send that another time.

Since v4:
- Don't build selftest-migration on arm.
- Reduce selftest-migration iterations from 100 to 30 to make the
test run faster (it's ~0.5s per migration).


Thanks, I think the series is ready to go now ... we just have to wait for
your QEMU TCG migration fix to get merged first. Or should we maybe mark the
selftest-migration with "accel = kvm" for now and remove that line later
once QEMU has been fixed?


Could we merge it? I'm juggling a bunch of different things and prone to
lose track of something :\ I'll need to drum up a bit of interest to
review the QEMU fixes from those who know the code too, so that may take
some time.


Ok, I merged it, but with "accel = kvm" for the time being (otherwise this 
would be quite a pitfall for people trying to run the k-u-t with TCG when 
they don't know that they have to fetch a patch from the mailing list to get 
it working).



I left it out of arm unittests.cfg entirely, and s390 and powerpc seems
to work by luck enough to be useful for gitlab CI so I don't think there
is a chnage needed really unless you're paranoid.


At least the s390x test does not work reliably at all when running with TCG 
without your QEMU patch, so I think we really need the "accel = kvm" for the 
time being here.



I do have a later patch that adds a memory tester that does trigger it
right away on powerpc. I'll send that out after this series is merged...
but we do still have the issue that the gitlab CI image has the old QEMU
don't we? Until we update distro.


We only run selected tests in the gitlab-CI, so unless you add it to 
.gitlab-ci.yml, the selftest-migration test won't be run there.


 Thomas




[PATCH v13 14/16] media: vivid: add fixed point test controls

2024-02-26 Thread Shengjiu Wang
Add fixed point test controls, one is for Q4.16 format
another one is for Q63 format.

Signed-off-by: Shengjiu Wang 
---
 drivers/media/test-drivers/vivid/vivid-core.h |  2 ++
 .../media/test-drivers/vivid/vivid-ctrls.c| 26 +++
 include/media/v4l2-ctrls.h|  6 +
 3 files changed, 34 insertions(+)

diff --git a/drivers/media/test-drivers/vivid/vivid-core.h 
b/drivers/media/test-drivers/vivid/vivid-core.h
index cfb8e66083f6..f65465191bc9 100644
--- a/drivers/media/test-drivers/vivid/vivid-core.h
+++ b/drivers/media/test-drivers/vivid/vivid-core.h
@@ -222,6 +222,8 @@ struct vivid_dev {
struct v4l2_ctrl*boolean;
struct v4l2_ctrl*int32;
struct v4l2_ctrl*int64;
+   struct v4l2_ctrl*int32_q16;
+   struct v4l2_ctrl*int64_q63;
struct v4l2_ctrl*menu;
struct v4l2_ctrl*string;
struct v4l2_ctrl*bitmask;
diff --git a/drivers/media/test-drivers/vivid/vivid-ctrls.c 
b/drivers/media/test-drivers/vivid/vivid-ctrls.c
index f2b20e25a7a4..2444ea95b285 100644
--- a/drivers/media/test-drivers/vivid/vivid-ctrls.c
+++ b/drivers/media/test-drivers/vivid/vivid-ctrls.c
@@ -38,6 +38,8 @@
 #define VIVID_CID_U8_PIXEL_ARRAY   (VIVID_CID_CUSTOM_BASE + 14)
 #define VIVID_CID_S32_ARRAY(VIVID_CID_CUSTOM_BASE + 15)
 #define VIVID_CID_S64_ARRAY(VIVID_CID_CUSTOM_BASE + 16)
+#define VIVID_CID_INT_Q4_16(VIVID_CID_CUSTOM_BASE + 17)
+#define VIVID_CID_INT64_Q63(VIVID_CID_CUSTOM_BASE + 18)
 
 #define VIVID_CID_VIVID_BASE   (0x00f0 | 0xf000)
 #define VIVID_CID_VIVID_CLASS  (0x00f0 | 1)
@@ -182,6 +184,28 @@ static const struct v4l2_ctrl_config vivid_ctrl_int64 = {
.step = 1,
 };
 
+static const struct v4l2_ctrl_config vivid_ctrl_int32_q16 = {
+   .ops = _user_gen_ctrl_ops,
+   .id = VIVID_CID_INT_Q4_16,
+   .name = "Integer 32 Bits Q4.16",
+   .type = V4L2_CTRL_TYPE_INTEGER,
+   .min = v4l2_ctrl_fp_compose(-16, 0, 16),
+   .max = v4l2_ctrl_fp_compose(15, 0x, 16),
+   .step = 1,
+   .fraction_bits = 16,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_int64_q63 = {
+   .ops = _user_gen_ctrl_ops,
+   .id = VIVID_CID_INT64_Q63,
+   .name = "Integer 64 Bits Q63",
+   .type = V4L2_CTRL_TYPE_INTEGER64,
+   .min = v4l2_ctrl_fp_compose(-1, 0, 63),
+   .max = v4l2_ctrl_fp_compose(0, LLONG_MAX, 63),
+   .step = 1,
+   .fraction_bits = 63,
+};
+
 static const struct v4l2_ctrl_config vivid_ctrl_u32_array = {
.ops = _user_gen_ctrl_ops,
.id = VIVID_CID_U32_ARRAY,
@@ -1670,6 +1694,8 @@ int vivid_create_controls(struct vivid_dev *dev, bool 
show_ccs_cap,
dev->button = v4l2_ctrl_new_custom(hdl_user_gen, _ctrl_button, 
NULL);
dev->int32 = v4l2_ctrl_new_custom(hdl_user_gen, _ctrl_int32, 
NULL);
dev->int64 = v4l2_ctrl_new_custom(hdl_user_gen, _ctrl_int64, 
NULL);
+   dev->int32_q16 = v4l2_ctrl_new_custom(hdl_user_gen, 
_ctrl_int32_q16, NULL);
+   dev->int64_q63 = v4l2_ctrl_new_custom(hdl_user_gen, 
_ctrl_int64_q63, NULL);
dev->boolean = v4l2_ctrl_new_custom(hdl_user_gen, _ctrl_boolean, 
NULL);
dev->menu = v4l2_ctrl_new_custom(hdl_user_gen, _ctrl_menu, NULL);
dev->string = v4l2_ctrl_new_custom(hdl_user_gen, _ctrl_string, 
NULL);
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index c35514c5bf88..197d8b67ac13 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -1593,4 +1593,10 @@ void v4l2_ctrl_type_op_log(const struct v4l2_ctrl *ctrl);
  */
 int v4l2_ctrl_type_op_validate(const struct v4l2_ctrl *ctrl, union 
v4l2_ctrl_ptr ptr);
 
+/*
+ * Fixed point compose helper define. This helper maps to the value
+ * i + f / (1 << fraction_bits).
+ */
+#define v4l2_ctrl_fp_compose(i, f, fraction_bits) (((s64)(i) << fraction_bits) 
+ (f))
+
 #endif
-- 
2.34.1



[PATCH v13 09/16] media: uapi: Define audio sample format fourcc type

2024-02-26 Thread Shengjiu Wang
The audio sample format definition is from alsa,
the header file is include/uapi/sound/asound.h, but
don't include this header file directly, because in
user space, there is another copy in alsa-lib.
There will be conflict in userspace for include
videodev2.h & asound.h and asoundlib.h

Here still use the fourcc format.

Signed-off-by: Shengjiu Wang 
---
 .../userspace-api/media/v4l/pixfmt-audio.rst  | 87 +++
 .../userspace-api/media/v4l/pixfmt.rst|  1 +
 drivers/media/v4l2-core/v4l2-ioctl.c  | 13 +++
 include/uapi/linux/videodev2.h| 23 +
 4 files changed, 124 insertions(+)
 create mode 100644 Documentation/userspace-api/media/v4l/pixfmt-audio.rst

diff --git a/Documentation/userspace-api/media/v4l/pixfmt-audio.rst 
b/Documentation/userspace-api/media/v4l/pixfmt-audio.rst
new file mode 100644
index ..04b4a7fbd8f4
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-audio.rst
@@ -0,0 +1,87 @@
+.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+
+.. _pixfmt-audio:
+
+*
+Audio Formats
+*
+
+These formats are used for :ref:`audiomem2mem` interface only.
+
+.. tabularcolumns:: |p{5.8cm}|p{1.2cm}|p{10.3cm}|
+
+.. cssclass:: longtable
+
+.. flat-table:: Audio Format
+:header-rows:  1
+:stub-columns: 0
+:widths:   3 1 4
+
+* - Identifier
+  - Code
+  - Details
+* .. _V4L2-AUDIO-FMT-S8:
+
+  - ``V4L2_AUDIO_FMT_S8``
+  - 'S8'
+  - Corresponds to SNDRV_PCM_FORMAT_S8 in ALSA
+* .. _V4L2-AUDIO-FMT-S16-LE:
+
+  - ``V4L2_AUDIO_FMT_S16_LE``
+  - 'S16_LE'
+  - Corresponds to SNDRV_PCM_FORMAT_S16_LE in ALSA
+* .. _V4L2-AUDIO-FMT-U16-LE:
+
+  - ``V4L2_AUDIO_FMT_U16_LE``
+  - 'U16_LE'
+  - Corresponds to SNDRV_PCM_FORMAT_U16_LE in ALSA
+* .. _V4L2-AUDIO-FMT-S24-LE:
+
+  - ``V4L2_AUDIO_FMT_S24_LE``
+  - 'S24_LE'
+  - Corresponds to SNDRV_PCM_FORMAT_S24_LE in ALSA
+* .. _V4L2-AUDIO-FMT-U24-LE:
+
+  - ``V4L2_AUDIO_FMT_U24_LE``
+  - 'U24_LE'
+  - Corresponds to SNDRV_PCM_FORMAT_U24_LE in ALSA
+* .. _V4L2-AUDIO-FMT-S32-LE:
+
+  - ``V4L2_AUDIO_FMT_S32_LE``
+  - 'S32_LE'
+  - Corresponds to SNDRV_PCM_FORMAT_S32_LE in ALSA
+* .. _V4L2-AUDIO-FMT-U32-LE:
+
+  - ``V4L2_AUDIO_FMT_U32_LE``
+  - 'U32_LE'
+  - Corresponds to SNDRV_PCM_FORMAT_U32_LE in ALSA
+* .. _V4L2-AUDIO-FMT-FLOAT-LE:
+
+  - ``V4L2_AUDIO_FMT_FLOAT_LE``
+  - 'FLOAT_LE'
+  - Corresponds to SNDRV_PCM_FORMAT_FLOAT_LE in ALSA
+* .. _V4L2-AUDIO-FMT-IEC958-SUBFRAME-LE:
+
+  - ``V4L2_AUDIO_FMT_IEC958_SUBFRAME_LE``
+  - 'IEC958_SUBFRAME_LE'
+  - Corresponds to SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE in ALSA
+* .. _V4L2-AUDIO-FMT-S24-3LE:
+
+  - ``V4L2_AUDIO_FMT_S24_3LE``
+  - 'S24_3LE'
+  - Corresponds to SNDRV_PCM_FORMAT_S24_3LE in ALSA
+* .. _V4L2-AUDIO-FMT-U24-3LE:
+
+  - ``V4L2_AUDIO_FMT_U24_3LE``
+  - 'U24_3LE'
+  - Corresponds to SNDRV_PCM_FORMAT_U24_3LE in ALSA
+* .. _V4L2-AUDIO-FMT-S20-3LE:
+
+  - ``V4L2_AUDIO_FMT_S20_3LE``
+  - 'S20_3LE'
+  - Corresponds to SNDRV_PCM_FORMAT_S24_3LE in ALSA
+* .. _V4L2-AUDIO-FMT-U20-3LE:
+
+  - ``V4L2_AUDIO_FMT_U20_3LE``
+  - 'U20_3LE'
+  - Corresponds to SNDRV_PCM_FORMAT_U20_3LE in ALSA
diff --git a/Documentation/userspace-api/media/v4l/pixfmt.rst 
b/Documentation/userspace-api/media/v4l/pixfmt.rst
index 11dab4a90630..2eb6fdd3b43d 100644
--- a/Documentation/userspace-api/media/v4l/pixfmt.rst
+++ b/Documentation/userspace-api/media/v4l/pixfmt.rst
@@ -36,3 +36,4 @@ see also :ref:`VIDIOC_G_FBUF `.)
 colorspaces
 colorspaces-defs
 colorspaces-details
+pixfmt-audio
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index 961abcdf7290..be229c69e991 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1471,6 +1471,19 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
case V4L2_PIX_FMT_Y210: descr = "10-bit YUYV Packed"; break;
case V4L2_PIX_FMT_Y212: descr = "12-bit YUYV Packed"; break;
case V4L2_PIX_FMT_Y216: descr = "16-bit YUYV Packed"; break;
+   case V4L2_AUDIO_FMT_S8: descr = "8-bit Signed"; break;
+   case V4L2_AUDIO_FMT_S16_LE: descr = "16-bit Signed LE"; break;
+   case V4L2_AUDIO_FMT_U16_LE: descr = "16-bit Unsigned LE"; 
break;
+   case V4L2_AUDIO_FMT_S24_LE: descr = "24(32)-bit Signed LE"; 
break;
+   case V4L2_AUDIO_FMT_U24_LE: descr = "24(32)-bit Unsigned 
LE"; break;
+   case V4L2_AUDIO_FMT_S32_LE: descr = "32-bit Signed LE"; 
break;
+   case V4L2_AUDIO_FMT_U32_LE: descr = "32-bit Unsigned LE"; 
break;
+   case V4L2_AUDIO_FMT_FLOAT_LE:   descr = "32-bit Float LE"; 
break;
+   case V4L2_AUDIO_FMT_IEC958_SUBFRAME_LE: descr = 

[PATCH v13 16/16] media: vim2m-audio: add virtual driver for audio memory to memory

2024-02-26 Thread Shengjiu Wang
Audio memory to memory virtual driver use video memory to memory
virtual driver vim2m.c as example. The main difference is
device type is VFL_TYPE_AUDIO and device cap type is V4L2_CAP_AUDIO_M2M.

The device_run function is a dummy function, which is simply
copy the data from input buffer to output buffer.

Signed-off-by: Shengjiu Wang 
---
 drivers/media/test-drivers/Kconfig   |  10 +
 drivers/media/test-drivers/Makefile  |   1 +
 drivers/media/test-drivers/vim2m-audio.c | 793 +++
 3 files changed, 804 insertions(+)
 create mode 100644 drivers/media/test-drivers/vim2m-audio.c

diff --git a/drivers/media/test-drivers/Kconfig 
b/drivers/media/test-drivers/Kconfig
index 5a5379524bde..b6b52a7ca042 100644
--- a/drivers/media/test-drivers/Kconfig
+++ b/drivers/media/test-drivers/Kconfig
@@ -16,6 +16,16 @@ config VIDEO_VIM2M
  This is a virtual test device for the memory-to-memory driver
  framework.
 
+config VIDEO_VIM2M_AUDIO
+   tristate "Virtual Memory-to-Memory Driver For Audio"
+   depends on VIDEO_DEV
+   select VIDEOBUF2_VMALLOC
+   select V4L2_MEM2MEM_DEV
+   select MEDIA_CONTROLLER
+   help
+ This is a virtual audio test device for the memory-to-memory driver
+ framework.
+
 source "drivers/media/test-drivers/vicodec/Kconfig"
 source "drivers/media/test-drivers/vimc/Kconfig"
 source "drivers/media/test-drivers/vivid/Kconfig"
diff --git a/drivers/media/test-drivers/Makefile 
b/drivers/media/test-drivers/Makefile
index 740714a4584d..0c61c9ada3e1 100644
--- a/drivers/media/test-drivers/Makefile
+++ b/drivers/media/test-drivers/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_DVB_VIDTV) += vidtv/
 
 obj-$(CONFIG_VIDEO_VICODEC) += vicodec/
 obj-$(CONFIG_VIDEO_VIM2M) += vim2m.o
+obj-$(CONFIG_VIDEO_VIM2M_AUDIO) += vim2m-audio.o
 obj-$(CONFIG_VIDEO_VIMC) += vimc/
 obj-$(CONFIG_VIDEO_VIVID) += vivid/
 obj-$(CONFIG_VIDEO_VISL) += visl/
diff --git a/drivers/media/test-drivers/vim2m-audio.c 
b/drivers/media/test-drivers/vim2m-audio.c
new file mode 100644
index ..6361df6320b3
--- /dev/null
+++ b/drivers/media/test-drivers/vim2m-audio.c
@@ -0,0 +1,793 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * A virtual v4l2-mem2mem example for audio device.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+MODULE_DESCRIPTION("Virtual device for audio mem2mem testing");
+MODULE_LICENSE("GPL");
+
+static unsigned int debug;
+module_param(debug, uint, 0644);
+MODULE_PARM_DESC(debug, "debug level");
+
+#define MEM2MEM_NAME "vim2m-audio"
+
+#define dprintk(dev, lvl, fmt, arg...) \
+   v4l2_dbg(lvl, debug, &(dev)->v4l2_dev, "%s: " fmt, __func__, ## arg)
+
+#define SAMPLE_NUM 4096
+
+static void audm2m_dev_release(struct device *dev)
+{}
+
+static struct platform_device audm2m_pdev = {
+   .name   = MEM2MEM_NAME,
+   .dev.release= audm2m_dev_release,
+};
+
+static u32 formats[] = {
+   V4L2_AUDIO_FMT_S16_LE,
+};
+
+#define NUM_FORMATS ARRAY_SIZE(formats)
+
+/* Per-queue, driver-specific private data */
+struct audm2m_q_data {
+   unsigned intrate;
+   unsigned intchannels;
+   unsigned intbuffersize;
+   unsigned intsequence;
+   u32 fourcc;
+};
+
+enum {
+   V4L2_M2M_SRC = 0,
+   V4L2_M2M_DST = 1,
+};
+
+static snd_pcm_format_t find_format(u32 fourcc)
+{
+   snd_pcm_format_t fmt;
+   unsigned int k;
+
+   for (k = 0; k < NUM_FORMATS; k++) {
+   if (formats[k] == fourcc)
+   break;
+   }
+
+   if (k == NUM_FORMATS)
+   return 0;
+
+   fmt = v4l2_fourcc_to_audfmt(formats[k]);
+
+   return fmt;
+}
+
+struct audm2m_dev {
+   struct v4l2_device  v4l2_dev;
+   struct video_device vfd;
+
+   struct mutexdev_mutex;
+
+   struct v4l2_m2m_dev *m2m_dev;
+#ifdef CONFIG_MEDIA_CONTROLLER
+   struct media_device mdev;
+#endif
+};
+
+struct audm2m_ctx {
+   struct v4l2_fh  fh;
+   struct v4l2_ctrl_handlerctrl_handler;
+   struct audm2m_dev   *dev;
+
+   struct mutexvb_mutex;
+
+   /* Source and destination queue data */
+   struct audm2m_q_data   q_data[2];
+};
+
+static inline struct audm2m_ctx *file2ctx(struct file *file)
+{
+   return container_of(file->private_data, struct audm2m_ctx, fh);
+}
+
+static struct audm2m_q_data *get_q_data(struct audm2m_ctx *ctx,
+   enum v4l2_buf_type type)
+{
+   if (type == V4L2_BUF_TYPE_AUDIO_OUTPUT)
+   return >q_data[V4L2_M2M_SRC];
+   return >q_data[V4L2_M2M_DST];
+}
+
+static const char *type_name(enum v4l2_buf_type type)
+{
+   if (type == V4L2_BUF_TYPE_AUDIO_OUTPUT)
+   return "Output";
+   return "Capture";
+}
+
+/*
+ * mem2mem callbacks
+ */

[PATCH v13 15/16] media: imx-asrc: Add memory to memory driver

2024-02-26 Thread Shengjiu Wang
Implement the ASRC memory to memory function using
the v4l2 framework, user can use this function with
v4l2 ioctl interface.

User send the output and capture buffer to driver and
driver store the converted data to the capture buffer.

This feature can be shared by ASRC and EASRC drivers

Signed-off-by: Shengjiu Wang 
---
 drivers/media/platform/nxp/Kconfig|   13 +
 drivers/media/platform/nxp/Makefile   |1 +
 drivers/media/platform/nxp/imx-asrc.c | 1256 +
 3 files changed, 1270 insertions(+)
 create mode 100644 drivers/media/platform/nxp/imx-asrc.c

diff --git a/drivers/media/platform/nxp/Kconfig 
b/drivers/media/platform/nxp/Kconfig
index 40e3436669e2..8d0ca335601f 100644
--- a/drivers/media/platform/nxp/Kconfig
+++ b/drivers/media/platform/nxp/Kconfig
@@ -67,3 +67,16 @@ config VIDEO_MX2_EMMAPRP
 
 source "drivers/media/platform/nxp/dw100/Kconfig"
 source "drivers/media/platform/nxp/imx-jpeg/Kconfig"
+
+config VIDEO_IMX_ASRC
+   tristate "NXP i.MX ASRC M2M support"
+   depends on V4L_MEM2MEM_DRIVERS
+   depends on MEDIA_SUPPORT
+   select VIDEOBUF2_DMA_CONTIG
+   select V4L2_MEM2MEM_DEV
+   select MEDIA_CONTROLLER
+   help
+   Say Y if you want to add ASRC M2M support for NXP CPUs.
+   It is a complement for ASRC M2P and ASRC P2M features.
+   This option is only useful for out-of-tree drivers since
+   in-tree drivers select it automatically.
diff --git a/drivers/media/platform/nxp/Makefile 
b/drivers/media/platform/nxp/Makefile
index 4d90eb713652..1325675e34f5 100644
--- a/drivers/media/platform/nxp/Makefile
+++ b/drivers/media/platform/nxp/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_VIDEO_IMX8MQ_MIPI_CSI2) += imx8mq-mipi-csi2.o
 obj-$(CONFIG_VIDEO_IMX_MIPI_CSIS) += imx-mipi-csis.o
 obj-$(CONFIG_VIDEO_IMX_PXP) += imx-pxp.o
 obj-$(CONFIG_VIDEO_MX2_EMMAPRP) += mx2_emmaprp.o
+obj-$(CONFIG_VIDEO_IMX_ASRC) += imx-asrc.o
diff --git a/drivers/media/platform/nxp/imx-asrc.c 
b/drivers/media/platform/nxp/imx-asrc.c
new file mode 100644
index ..0c25a36199b1
--- /dev/null
+++ b/drivers/media/platform/nxp/imx-asrc.c
@@ -0,0 +1,1256 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+// Copyright (C) 2019-2023 NXP
+//
+// Freescale ASRC Memory to Memory (M2M) driver
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define V4L_CAP OUT
+#define V4L_OUT IN
+
+#define ASRC_xPUT_DMA_CALLBACK(dir) \
+   (((dir) == V4L_OUT) ? asrc_input_dma_callback \
+   : asrc_output_dma_callback)
+
+#define DIR_STR(dir) (dir) == V4L_OUT ? "out" : "cap"
+
+/* Maximum output and capture buffer size */
+#define ASRC_M2M_BUFFER_SIZE (512 * 1024)
+
+/* Maximum output and capture period size */
+#define ASRC_M2M_PERIOD_SIZE (48 * 1024)
+
+struct asrc_pair_m2m {
+   struct fsl_asrc_pair *pair;
+   struct asrc_m2m *m2m;
+   struct v4l2_fh fh;
+   struct v4l2_ctrl_handler ctrl_handler;
+   int channels[2];
+   unsigned int sequence[2];
+   s64 src_rate_off_prev;  /* Q31.32 */
+   s64 dst_rate_off_prev;  /* Q31.32 */
+   s64 src_rate_off_cur;   /* Q31.32 */
+   s64 dst_rate_off_cur;   /* Q31.32 */
+};
+
+struct asrc_m2m {
+   struct fsl_asrc_m2m_pdata pdata;
+   struct v4l2_device v4l2_dev;
+   struct v4l2_m2m_dev *m2m_dev;
+   struct video_device *dec_vdev;
+   struct mutex mlock; /* v4l2 ioctls serialization */
+   struct platform_device *pdev;
+#ifdef CONFIG_MEDIA_CONTROLLER
+   struct media_device mdev;
+#endif
+};
+
+static u32 formats[] = {
+   V4L2_AUDIO_FMT_S8,
+   V4L2_AUDIO_FMT_S16_LE,
+   V4L2_AUDIO_FMT_U16_LE,
+   V4L2_AUDIO_FMT_S24_LE,
+   V4L2_AUDIO_FMT_S24_3LE,
+   V4L2_AUDIO_FMT_U24_LE,
+   V4L2_AUDIO_FMT_U24_3LE,
+   V4L2_AUDIO_FMT_S32_LE,
+   V4L2_AUDIO_FMT_U32_LE,
+   V4L2_AUDIO_FMT_S20_3LE,
+   V4L2_AUDIO_FMT_U20_3LE,
+   V4L2_AUDIO_FMT_FLOAT_LE,
+   V4L2_AUDIO_FMT_IEC958_SUBFRAME_LE,
+};
+
+#define NUM_FORMATS ARRAY_SIZE(formats)
+
+static const s64 asrc_v1_m2m_rates[] = {
+   5512, 8000, 11025, 12000, 16000,
+   22050, 24000, 32000, 44100,
+   48000, 64000, 88200, 96000,
+   128000, 176400, 192000,
+};
+
+static const s64 asrc_v2_m2m_rates[] = {
+   8000, 11025, 12000, 16000,
+   22050, 24000, 32000, 44100,
+   48000, 64000, 88200, 96000,
+   128000, 176400, 192000, 256000,
+   352800, 384000, 705600, 768000,
+};
+
+static u32 find_fourcc(snd_pcm_format_t format)
+{
+   snd_pcm_format_t fmt;
+   unsigned int k;
+
+   for (k = 0; k < NUM_FORMATS; k++) {
+   fmt = v4l2_fourcc_to_audfmt(formats[k]);
+   if (fmt == format)
+   return formats[k];
+   }
+
+   return 0;
+}
+
+static snd_pcm_format_t find_format(u32 fourcc)
+{
+   unsigned int k;
+

[PATCH v13 00/16] Add audio support in v4l2 framework

2024-02-26 Thread Shengjiu Wang
Audio signal processing also has the requirement for memory to
memory similar as Video.

This asrc memory to memory (memory ->asrc->memory) case is a non
real time use case.

User fills the input buffer to the asrc module, after conversion, then asrc
sends back the output buffer to user. So it is not a traditional ALSA playback
and capture case.

It is a specific use case,  there is no reference in current kernel.
v4l2 memory to memory is the closed implementation,  v4l2 current
support video, image, radio, tuner, touch devices, so it is not
complicated to add support for this specific audio case.

Because we had implemented the "memory -> asrc ->i2s device-> codec"
use case in ALSA.  Now the "memory->asrc->memory" needs
to reuse the code in asrc driver, so the first 3 patches is for refining
the code to make it can be shared by the "memory->asrc->memory"
driver.

The main change is in the v4l2 side, A /dev/vl4-audioX will be created,
user applications only use the ioctl of v4l2 framework.

Other change is to add memory to memory support for two kinds of i.MX ASRC
module.

changes in v13
- change 'pixelformat' to 'audioformat' in dev-audio-mem2mem.rst
- add more description for clock drift in ext-ctrls-audio-m2m.rst
- Add "media: v4l2-ctrls: add support for fraction_bits" from Hans
  to avoid build issue for kernel test robot

changes in v12
- minor changes according to comments
- drop min_buffers_needed = 1 and V4L2_CTRL_FLAG_UPDATE flag
- drop bus_info

changes in v11
- add add-fixed-point-test-controls in vivid.
- add v4l2_ctrl_fp_compose() helper function for min and max

changes in v10
- remove FIXED_POINT type
- change code base on media: v4l2-ctrls: add support for fraction_bits
- fix issue reported by kernel test robot
- remove module_alias

changes in v9:
- add MEDIA_ENT_F_PROC_AUDIO_RESAMPLER.
- add MEDIA_INTF_T_V4L_AUDIO
- add media controller support
- refine the vim2m-audio to support 8k<->16k conversion.

changes in v8:
- refine V4L2_CAP_AUDIO_M2M to be 0x0008
- update doc for FIXED_POINT
- address comments for imx-asrc

changes in v7:
- add acked-by from Mark
- separate commit for fixed point, m2m audio class, audio rate controls
- use INTEGER_MENU for rate,  FIXED_POINT for rate offset
- remove used fmts
- address other comments for Hans

changes in v6:
- use m2m_prepare/m2m_unprepare/m2m_start/m2m_stop to replace
  m2m_start_part_one/m2m_stop_part_one, m2m_start_part_two/m2m_stop_part_two.
- change V4L2_CTRL_TYPE_ASRC_RATE to V4L2_CTRL_TYPE_FIXED_POINT
- fix warning by kernel test rebot
- remove some unused format V4L2_AUDIO_FMT_XX
- Get SNDRV_PCM_FORMAT from V4L2_AUDIO_FMT in driver.
- rename audm2m to viaudm2m.

changes in v5:
- remove V4L2_AUDIO_FMT_LPCM
- define audio pixel format like V4L2_AUDIO_FMT_S8...
- remove rate and format in struct v4l2_audio_format.
- Add V4L2_CID_ASRC_SOURCE_RATE and V4L2_CID_ASRC_DEST_RATE controls
- updata document accordingly.

changes in v4:
- update document style
- separate V4L2_AUDIO_FMT_LPCM and V4L2_CAP_AUDIO_M2M in separate commit

changes in v3:
- Modify documents for adding audio m2m support
- Add audio virtual m2m driver
- Defined V4L2_AUDIO_FMT_LPCM format type for audio.
- Defined V4L2_CAP_AUDIO_M2M capability type for audio m2m case.
- with modification in v4l-utils, pass v4l2-compliance test.

changes in v2:
- decouple the implementation in v4l2 and ALSA
- implement the memory to memory driver as a platfrom driver
  and move it to driver/media
- move fsl_asrc_common.h to include/sound folder

Hans Verkuil (1):
  media: v4l2-ctrls: add support for fraction_bits

Shengjiu Wang (15):
  ASoC: fsl_asrc: define functions for memory to memory usage
  ASoC: fsl_easrc: define functions for memory to memory usage
  ASoC: fsl_asrc: move fsl_asrc_common.h to include/sound
  ASoC: fsl_asrc: register m2m platform device
  ASoC: fsl_easrc: register m2m platform device
  media: uapi: Add V4L2_CAP_AUDIO_M2M capability flag
  media: v4l2: Add audio capture and output support
  media: uapi: Define audio sample format fourcc type
  media: uapi: Add V4L2_CTRL_CLASS_M2M_AUDIO
  media: uapi: Add audio rate controls support
  media: uapi: Declare interface types for Audio
  media: uapi: Add an entity type for audio resampler
  media: vivid: add fixed point test controls
  media: imx-asrc: Add memory to memory driver
  media: vim2m-audio: add virtual driver for audio memory to memory

 .../media/mediactl/media-types.rst|   11 +
 .../userspace-api/media/v4l/buffer.rst|6 +
 .../userspace-api/media/v4l/common.rst|1 +
 .../media/v4l/dev-audio-mem2mem.rst   |   71 +
 .../userspace-api/media/v4l/devices.rst   |1 +
 .../media/v4l/ext-ctrls-audio-m2m.rst |   59 +
 .../userspace-api/media/v4l/pixfmt-audio.rst  |   87 ++
 .../userspace-api/media/v4l/pixfmt.rst|1 +
 .../media/v4l/vidioc-enum-fmt.rst |2 +
 .../media/v4l/vidioc-g-ext-ctrls.rst  |4 +
 

[PATCH v13 04/16] ASoC: fsl_asrc: move fsl_asrc_common.h to include/sound

2024-02-26 Thread Shengjiu Wang
Move fsl_asrc_common.h to include/sound that it can be
included from other drivers.

Signed-off-by: Shengjiu Wang 
Acked-by: Mark Brown 
---
 {sound/soc/fsl => include/sound}/fsl_asrc_common.h | 0
 sound/soc/fsl/fsl_asrc.h   | 2 +-
 sound/soc/fsl/fsl_asrc_dma.c   | 2 +-
 sound/soc/fsl/fsl_easrc.h  | 2 +-
 4 files changed, 3 insertions(+), 3 deletions(-)
 rename {sound/soc/fsl => include/sound}/fsl_asrc_common.h (100%)

diff --git a/sound/soc/fsl/fsl_asrc_common.h b/include/sound/fsl_asrc_common.h
similarity index 100%
rename from sound/soc/fsl/fsl_asrc_common.h
rename to include/sound/fsl_asrc_common.h
diff --git a/sound/soc/fsl/fsl_asrc.h b/sound/soc/fsl/fsl_asrc.h
index 1c492eb237f5..66544624de7b 100644
--- a/sound/soc/fsl/fsl_asrc.h
+++ b/sound/soc/fsl/fsl_asrc.h
@@ -10,7 +10,7 @@
 #ifndef _FSL_ASRC_H
 #define _FSL_ASRC_H
 
-#include  "fsl_asrc_common.h"
+#include  
 
 #define ASRC_M2M_INPUTFIFO_WML 0x4
 #define ASRC_M2M_OUTPUTFIFO_WML0x2
diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c
index f501f47242fb..f067bf1ecea7 100644
--- a/sound/soc/fsl/fsl_asrc_dma.c
+++ b/sound/soc/fsl/fsl_asrc_dma.c
@@ -12,7 +12,7 @@
 #include 
 #include 
 
-#include "fsl_asrc_common.h"
+#include 
 
 #define FSL_ASRC_DMABUF_SIZE   (256 * 1024)
 
diff --git a/sound/soc/fsl/fsl_easrc.h b/sound/soc/fsl/fsl_easrc.h
index c9f770862662..a24e540876a4 100644
--- a/sound/soc/fsl/fsl_easrc.h
+++ b/sound/soc/fsl/fsl_easrc.h
@@ -9,7 +9,7 @@
 #include 
 #include 
 
-#include "fsl_asrc_common.h"
+#include 
 
 /* EASRC Register Map */
 
-- 
2.34.1



[PATCH v13 13/16] media: uapi: Add an entity type for audio resampler

2024-02-26 Thread Shengjiu Wang
Add and document a media entity type for an audio resampler.
It is MEDIA_ENT_F_PROC_AUDIO_RESAMPLER.

Signed-off-by: Shengjiu Wang 
---
 Documentation/userspace-api/media/mediactl/media-types.rst | 6 ++
 include/uapi/linux/media.h | 1 +
 2 files changed, 7 insertions(+)

diff --git a/Documentation/userspace-api/media/mediactl/media-types.rst 
b/Documentation/userspace-api/media/mediactl/media-types.rst
index adfb37430f8e..d353f17c3344 100644
--- a/Documentation/userspace-api/media/mediactl/media-types.rst
+++ b/Documentation/userspace-api/media/mediactl/media-types.rst
@@ -40,6 +40,7 @@ Types and flags used to represent the media graph elements
 .. _MEDIA-ENT-F-PROC-VIDEO-ENCODER:
 .. _MEDIA-ENT-F-PROC-VIDEO-DECODER:
 .. _MEDIA-ENT-F-PROC-VIDEO-ISP:
+.. _MEDIA-ENT-F-PROC-AUDIO-RESAMPLER:
 .. _MEDIA-ENT-F-VID-MUX:
 .. _MEDIA-ENT-F-VID-IF-BRIDGE:
 .. _MEDIA-ENT-F-DV-DECODER:
@@ -208,6 +209,11 @@ Types and flags used to represent the media graph elements
  combination of custom V4L2 controls and IOCTLs, and parameters
  supplied in a metadata buffer.
 
+*  -  ``MEDIA_ENT_F_PROC_AUDIO_RESAMPLER``
+   -  An Audio Resampler device. An entity capable of
+ resampling an audio stream from one sample rate to another sample
+ rate. Must have one sink pad and at least one source pad.
+
 *  -  ``MEDIA_ENT_F_VID_MUX``
- Video multiplexer. An entity capable of multiplexing must have at
  least two sink pads and one source pad, and must pass the video
diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h
index 9ff6dec7393a..a8266eaa8042 100644
--- a/include/uapi/linux/media.h
+++ b/include/uapi/linux/media.h
@@ -125,6 +125,7 @@ struct media_device_info {
 #define MEDIA_ENT_F_PROC_VIDEO_ENCODER (MEDIA_ENT_F_BASE + 0x4007)
 #define MEDIA_ENT_F_PROC_VIDEO_DECODER (MEDIA_ENT_F_BASE + 0x4008)
 #define MEDIA_ENT_F_PROC_VIDEO_ISP (MEDIA_ENT_F_BASE + 0x4009)
+#define MEDIA_ENT_F_PROC_AUDIO_RESAMPLER   (MEDIA_ENT_F_BASE + 0x400a)
 
 /*
  * Switch and bridge entity functions
-- 
2.34.1



[PATCH v13 08/16] media: v4l2: Add audio capture and output support

2024-02-26 Thread Shengjiu Wang
Audio signal processing has the requirement for memory to
memory similar as Video.

This patch is to add this support in v4l2 framework, defined
new buffer type V4L2_BUF_TYPE_AUDIO_CAPTURE and
V4L2_BUF_TYPE_AUDIO_OUTPUT, defined new format v4l2_audio_format
for audio case usage.

The created audio device is named "/dev/v4l-audioX".

Signed-off-by: Shengjiu Wang 
---
 .../userspace-api/media/v4l/buffer.rst|  6 ++
 .../media/v4l/dev-audio-mem2mem.rst   | 71 +++
 .../userspace-api/media/v4l/devices.rst   |  1 +
 .../media/v4l/vidioc-enum-fmt.rst |  2 +
 .../userspace-api/media/v4l/vidioc-g-fmt.rst  |  4 ++
 .../media/videodev2.h.rst.exceptions  |  2 +
 .../media/common/videobuf2/videobuf2-v4l2.c   |  4 ++
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c |  9 +++
 drivers/media/v4l2-core/v4l2-dev.c| 17 +
 drivers/media/v4l2-core/v4l2-ioctl.c  | 53 ++
 include/media/v4l2-dev.h  |  2 +
 include/media/v4l2-ioctl.h| 34 +
 include/uapi/linux/videodev2.h| 17 +
 13 files changed, 222 insertions(+)
 create mode 100644 Documentation/userspace-api/media/v4l/dev-audio-mem2mem.rst

diff --git a/Documentation/userspace-api/media/v4l/buffer.rst 
b/Documentation/userspace-api/media/v4l/buffer.rst
index 52bbee81c080..a3754ca6f0d6 100644
--- a/Documentation/userspace-api/media/v4l/buffer.rst
+++ b/Documentation/userspace-api/media/v4l/buffer.rst
@@ -438,6 +438,12 @@ enum v4l2_buf_type
 * - ``V4L2_BUF_TYPE_META_OUTPUT``
   - 14
   - Buffer for metadata output, see :ref:`metadata`.
+* - ``V4L2_BUF_TYPE_AUDIO_CAPTURE``
+  - 15
+  - Buffer for audio capture, see :ref:`audio`.
+* - ``V4L2_BUF_TYPE_AUDIO_OUTPUT``
+  - 16
+  - Buffer for audio output, see :ref:`audio`.
 
 
 .. _buffer-flags:
diff --git a/Documentation/userspace-api/media/v4l/dev-audio-mem2mem.rst 
b/Documentation/userspace-api/media/v4l/dev-audio-mem2mem.rst
new file mode 100644
index ..54cc2abb6c04
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/dev-audio-mem2mem.rst
@@ -0,0 +1,71 @@
+.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+
+.. _audiomem2mem:
+
+
+Audio Memory-To-Memory Interface
+
+
+An audio memory-to-memory device can compress, decompress, transform, or
+otherwise convert audio data from one format into another format, in memory.
+Such memory-to-memory devices set the ``V4L2_CAP_AUDIO_M2M`` capability.
+Examples of memory-to-memory devices are audio codecs, audio preprocessing,
+audio postprocessing.
+
+A memory-to-memory audio node supports both output (sending audio frames from
+memory to the hardware) and capture (receiving the processed audio frames
+from the hardware into memory) stream I/O. An application will have to
+setup the stream I/O for both sides and finally call
+:ref:`VIDIOC_STREAMON ` for both capture and output to
+start the hardware.
+
+Memory-to-memory devices function as a shared resource: you can
+open the audio node multiple times, each application setting up their
+own properties that are local to the file handle, and each can use
+it independently from the others. The driver will arbitrate access to
+the hardware and reprogram it whenever another file handler gets access.
+
+Audio memory-to-memory devices are accessed through character device
+special files named ``/dev/v4l-audio``
+
+Querying Capabilities
+=
+
+Device nodes supporting the audio memory-to-memory interface set the
+``V4L2_CAP_AUDIO_M2M`` flag in the ``device_caps`` field of the
+:c:type:`v4l2_capability` structure returned by the :c:func:`VIDIOC_QUERYCAP`
+ioctl.
+
+Data Format Negotiation
+===
+
+The audio device uses the :ref:`format` ioctls to select the capture format.
+The audio buffer content format is bound to that selected format. In addition
+to the basic :ref:`format` ioctls, the :c:func:`VIDIOC_ENUM_FMT` ioctl must be
+supported as well.
+
+To use the :ref:`format` ioctls applications set the ``type`` field of the
+:c:type:`v4l2_format` structure to ``V4L2_BUF_TYPE_AUDIO_CAPTURE`` or to
+``V4L2_BUF_TYPE_AUDIO_OUTPUT``. Both drivers and applications must set the
+remainder of the :c:type:`v4l2_format` structure to 0.
+
+.. c:type:: v4l2_audio_format
+
+.. tabularcolumns:: |p{1.4cm}|p{2.4cm}|p{13.5cm}|
+
+.. flat-table:: struct v4l2_audio_format
+:header-rows:  0
+:stub-columns: 0
+:widths:   1 1 2
+
+* - __u32
+  - ``audioformat``
+  - The sample format, set by the application. see :ref:`pixfmt-audio`
+* - __u32
+  - ``channels``
+  - The channel number, set by the application. channel number range is
+[1, 32].
+* - __u32
+  - ``buffersize``
+  - Maximum buffer size in bytes required for data. The value is set by the
+driver.
diff --git 

[PATCH v13 10/16] media: uapi: Add V4L2_CTRL_CLASS_M2M_AUDIO

2024-02-26 Thread Shengjiu Wang
The Audio M2M class includes controls for audio memory-to-memory
use cases. The controls can be used for audio codecs, audio
preprocessing, audio postprocessing.

Signed-off-by: Shengjiu Wang 
---
 .../userspace-api/media/v4l/common.rst|  1 +
 .../media/v4l/ext-ctrls-audio-m2m.rst | 21 +++
 .../media/v4l/vidioc-g-ext-ctrls.rst  |  4 
 drivers/media/v4l2-core/v4l2-ctrls-defs.c |  4 
 include/uapi/linux/v4l2-controls.h|  4 
 5 files changed, 34 insertions(+)
 create mode 100644 
Documentation/userspace-api/media/v4l/ext-ctrls-audio-m2m.rst

diff --git a/Documentation/userspace-api/media/v4l/common.rst 
b/Documentation/userspace-api/media/v4l/common.rst
index ea0435182e44..d5366e96a596 100644
--- a/Documentation/userspace-api/media/v4l/common.rst
+++ b/Documentation/userspace-api/media/v4l/common.rst
@@ -52,6 +52,7 @@ applicable to all devices.
 ext-ctrls-fm-rx
 ext-ctrls-detect
 ext-ctrls-colorimetry
+ext-ctrls-audio-m2m
 fourcc
 format
 planar-apis
diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-audio-m2m.rst 
b/Documentation/userspace-api/media/v4l/ext-ctrls-audio-m2m.rst
new file mode 100644
index ..82d2ecedbfee
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-audio-m2m.rst
@@ -0,0 +1,21 @@
+.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+
+.. _audiom2m-controls:
+
+***
+Audio M2M Control Reference
+***
+
+The Audio M2M class includes controls for audio memory-to-memory
+use cases. The controls can be used for audio codecs, audio
+preprocessing, audio postprocessing.
+
+Audio M2M Control IDs
+---
+
+.. _audiom2m-control-id:
+
+``V4L2_CID_M2M_AUDIO_CLASS (class)``
+The Audio M2M class descriptor. Calling
+:ref:`VIDIOC_QUERYCTRL` for this control will
+return a description of this control class.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst 
b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
index 4d56c0528ad7..aeb1ad8e7d29 100644
--- a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
@@ -488,6 +488,10 @@ still cause this situation.
   - 0xa5
   - The class containing colorimetry controls. These controls are
described in :ref:`colorimetry-controls`.
+* - ``V4L2_CTRL_CLASS_M2M_AUDIO``
+  - 0xa6
+  - The class containing audio m2m controls. These controls are
+   described in :ref:`audiom2m-controls`.
 
 Return Value
 
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c 
b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
index 8696eb1cdd61..2a85ea3dc92f 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
@@ -1242,6 +1242,9 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_COLORIMETRY_CLASS:return "Colorimetry Controls";
case V4L2_CID_COLORIMETRY_HDR10_CLL_INFO:   return "HDR10 
Content Light Info";
case V4L2_CID_COLORIMETRY_HDR10_MASTERING_DISPLAY:  return "HDR10 
Mastering Display";
+
+   /* Audio M2M controls */
+   case V4L2_CID_M2M_AUDIO_CLASS:  return "Audio M2M Controls";
default:
return NULL;
}
@@ -1451,6 +1454,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum 
v4l2_ctrl_type *type,
case V4L2_CID_DETECT_CLASS:
case V4L2_CID_CODEC_STATELESS_CLASS:
case V4L2_CID_COLORIMETRY_CLASS:
+   case V4L2_CID_M2M_AUDIO_CLASS:
*type = V4L2_CTRL_TYPE_CTRL_CLASS;
/* You can neither read nor write these */
*flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY;
diff --git a/include/uapi/linux/v4l2-controls.h 
b/include/uapi/linux/v4l2-controls.h
index 99c3f5e99da7..a8b4b830c757 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -30,6 +30,7 @@
 #define V4L2_CTRL_CLASS_DETECT 0x00a3  /* Detection controls */
 #define V4L2_CTRL_CLASS_CODEC_STATELESS 0x00a4 /* Stateless codecs 
controls */
 #define V4L2_CTRL_CLASS_COLORIMETRY0x00a5  /* Colorimetry controls 
*/
+#define V4L2_CTRL_CLASS_M2M_AUDIO  0x00a6  /* Audio M2M controls */
 
 /* User-class control IDs */
 
@@ -3491,6 +3492,9 @@ struct v4l2_ctrl_av1_film_grain {
__u8 reserved[4];
 };
 
+#define V4L2_CID_M2M_AUDIO_CLASS_BASE  (V4L2_CTRL_CLASS_M2M_AUDIO | 0x900)
+#define V4L2_CID_M2M_AUDIO_CLASS   (V4L2_CTRL_CLASS_M2M_AUDIO | 1)
+
 /* MPEG-compression definitions kept for backwards compatibility */
 #ifndef __KERNEL__
 #define V4L2_CTRL_CLASS_MPEGV4L2_CTRL_CLASS_CODEC
-- 
2.34.1



[PATCH v13 11/16] media: uapi: Add audio rate controls support

2024-02-26 Thread Shengjiu Wang
Add V4L2_CID_M2M_AUDIO_SOURCE_RATE and V4L2_CID_M2M_AUDIO_DEST_RATE
new IDs for rate control.

Add V4L2_CID_M2M_AUDIO_SOURCE_RATE_OFFSET and
V4L2_CID_M2M_AUDIO_DEST_RATE_OFFSET for clock drift.

Signed-off-by: Shengjiu Wang 
---
 .../media/v4l/ext-ctrls-audio-m2m.rst | 38 +++
 drivers/media/v4l2-core/v4l2-ctrls-defs.c |  6 +++
 include/uapi/linux/v4l2-controls.h|  5 +++
 3 files changed, 49 insertions(+)

diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-audio-m2m.rst 
b/Documentation/userspace-api/media/v4l/ext-ctrls-audio-m2m.rst
index 82d2ecedbfee..b137b7c442e6 100644
--- a/Documentation/userspace-api/media/v4l/ext-ctrls-audio-m2m.rst
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-audio-m2m.rst
@@ -19,3 +19,41 @@ Audio M2M Control IDs
 The Audio M2M class descriptor. Calling
 :ref:`VIDIOC_QUERYCTRL` for this control will
 return a description of this control class.
+
+.. _v4l2-audio-asrc:
+
+``V4L2_CID_M2M_AUDIO_SOURCE_RATE (integer menu)``
+This control specifies the audio source sample rate, unit is Hz
+
+``V4L2_CID_M2M_AUDIO_DEST_RATE (integer menu)``
+This control specifies the audio destination sample rate, unit is Hz
+
+``V4L2_CID_M2M_AUDIO_SOURCE_RATE_OFFSET (fixed point)``
+This control specifies the offset from the audio source sample rate,
+unit is Hz.
+
+The offset compensates for any clock drift. The actual source audio
+sample rate is the ideal source audio sample rate from
+``V4L2_CID_M2M_AUDIO_SOURCE_RATE`` plus this fixed point offset.
+
+The audio source clock may have some drift. Reducing or increasing the
+audio sample rate dynamically to ensure that Sample Rate Converter is
+working on the real sample rate, this feature is for the Asynchronous
+Sample Rate Converter module.
+So, userspace would be expected to be monitoring such drift
+and increasing/decreasing the sample frequency as needed by this control.
+
+``V4L2_CID_M2M_AUDIO_DEST_RATE_OFFSET (fixed point)``
+This control specifies the offset from the audio destination sample rate,
+unit is Hz.
+
+The offset compensates for any clock drift. The actual destination audio
+sample rate is the ideal source audio sample rate from
+``V4L2_CID_M2M_AUDIO_DEST_RATE`` plus this fixed point offset.
+
+The audio destination clock may have some drift. Reducing or increasing
+the audio sample rate dynamically to ensure that sample rate converter
+is working on the real sample rate, this feature is for the Asynchronous
+Sample Rate Converter module.
+So, userspace would be expected to be monitoring such drift
+and increasing/decreasing the sample frequency as needed by this control.
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c 
b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
index 2a85ea3dc92f..91e1f5348c23 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
@@ -1245,6 +1245,8 @@ const char *v4l2_ctrl_get_name(u32 id)
 
/* Audio M2M controls */
case V4L2_CID_M2M_AUDIO_CLASS:  return "Audio M2M Controls";
+   case V4L2_CID_M2M_AUDIO_SOURCE_RATE:return "Audio Source Sample 
Rate";
+   case V4L2_CID_M2M_AUDIO_DEST_RATE:  return "Audio Destination 
Sample Rate";
default:
return NULL;
}
@@ -1606,6 +1608,10 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum 
v4l2_ctrl_type *type,
case V4L2_CID_COLORIMETRY_HDR10_MASTERING_DISPLAY:
*type = V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY;
break;
+   case V4L2_CID_M2M_AUDIO_SOURCE_RATE:
+   case V4L2_CID_M2M_AUDIO_DEST_RATE:
+   *type = V4L2_CTRL_TYPE_INTEGER_MENU;
+   break;
default:
*type = V4L2_CTRL_TYPE_INTEGER;
break;
diff --git a/include/uapi/linux/v4l2-controls.h 
b/include/uapi/linux/v4l2-controls.h
index a8b4b830c757..30129ccdc282 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -3495,6 +3495,11 @@ struct v4l2_ctrl_av1_film_grain {
 #define V4L2_CID_M2M_AUDIO_CLASS_BASE  (V4L2_CTRL_CLASS_M2M_AUDIO | 0x900)
 #define V4L2_CID_M2M_AUDIO_CLASS   (V4L2_CTRL_CLASS_M2M_AUDIO | 1)
 
+#define V4L2_CID_M2M_AUDIO_SOURCE_RATE (V4L2_CID_M2M_AUDIO_CLASS_BASE + 0)
+#define V4L2_CID_M2M_AUDIO_DEST_RATE   (V4L2_CID_M2M_AUDIO_CLASS_BASE + 1)
+#define V4L2_CID_M2M_AUDIO_SOURCE_RATE_OFFSET  (V4L2_CID_M2M_AUDIO_CLASS_BASE 
+ 2)
+#define V4L2_CID_M2M_AUDIO_DEST_RATE_OFFSET(V4L2_CID_M2M_AUDIO_CLASS_BASE 
+ 3)
+
 /* MPEG-compression definitions kept for backwards compatibility */
 #ifndef __KERNEL__
 #define V4L2_CTRL_CLASS_MPEGV4L2_CTRL_CLASS_CODEC
-- 
2.34.1



[PATCH v13 05/16] ASoC: fsl_asrc: register m2m platform device

2024-02-26 Thread Shengjiu Wang
Register m2m platform device, that user can
use M2M feature.

Defined platform data structure and platform
driver name.

Signed-off-by: Shengjiu Wang 
Acked-by: Mark Brown 
---
 include/sound/fsl_asrc_common.h | 23 +++
 sound/soc/fsl/fsl_asrc.c| 18 ++
 2 files changed, 41 insertions(+)

diff --git a/include/sound/fsl_asrc_common.h b/include/sound/fsl_asrc_common.h
index 3b53d366182f..c709b8906929 100644
--- a/include/sound/fsl_asrc_common.h
+++ b/include/sound/fsl_asrc_common.h
@@ -71,6 +71,7 @@ struct fsl_asrc_pair {
  * @dma_params_rx: DMA parameters for receive channel
  * @dma_params_tx: DMA parameters for transmit channel
  * @pdev: platform device pointer
+ * @m2m_pdev: m2m platform device pointer
  * @regmap: regmap handler
  * @paddr: physical address to the base address of registers
  * @mem_clk: clock source to access register
@@ -103,6 +104,7 @@ struct fsl_asrc {
struct snd_dmaengine_dai_dma_data dma_params_rx;
struct snd_dmaengine_dai_dma_data dma_params_tx;
struct platform_device *pdev;
+   struct platform_device *m2m_pdev;
struct regmap *regmap;
unsigned long paddr;
struct clk *mem_clk;
@@ -139,6 +141,27 @@ struct fsl_asrc {
void *private;
 };
 
+/**
+ * struct fsl_asrc_m2m_pdata - platform data
+ * @asrc: pointer to struct fsl_asrc
+ * @fmt_in: input sample format
+ * @fmt_out: output sample format
+ * @chan_min: minimum channel number
+ * @chan_max: maximum channel number
+ * @rate_min: minimum rate
+ * @rate_max: maximum rete
+ */
+struct fsl_asrc_m2m_pdata {
+   struct fsl_asrc *asrc;
+   u64 fmt_in;
+   u64 fmt_out;
+   int chan_min;
+   int chan_max;
+   int rate_min;
+   int rate_max;
+};
+
+#define M2M_DRV_NAME "fsl_asrc_m2m"
 #define DRV_NAME "fsl-asrc-dai"
 extern struct snd_soc_component_driver fsl_asrc_component;
 
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index 7d8643ee0ba0..5ecb5d869607 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -1187,6 +1187,7 @@ static int fsl_asrc_runtime_suspend(struct device *dev);
 static int fsl_asrc_probe(struct platform_device *pdev)
 {
struct device_node *np = pdev->dev.of_node;
+   struct fsl_asrc_m2m_pdata m2m_pdata;
struct fsl_asrc_priv *asrc_priv;
struct fsl_asrc *asrc;
struct resource *res;
@@ -1368,6 +1369,18 @@ static int fsl_asrc_probe(struct platform_device *pdev)
goto err_pm_get_sync;
}
 
+   m2m_pdata.asrc = asrc;
+   m2m_pdata.fmt_in = FSL_ASRC_FORMATS;
+   m2m_pdata.fmt_out = FSL_ASRC_FORMATS | SNDRV_PCM_FMTBIT_S8;
+   m2m_pdata.rate_min = 5512;
+   m2m_pdata.rate_max = 192000;
+   m2m_pdata.chan_min = 1;
+   m2m_pdata.chan_max = 10;
+   asrc->m2m_pdev = platform_device_register_data(>dev,
+  M2M_DRV_NAME,
+  PLATFORM_DEVID_AUTO,
+  _pdata,
+  sizeof(m2m_pdata));
return 0;
 
 err_pm_get_sync:
@@ -1380,6 +1393,11 @@ static int fsl_asrc_probe(struct platform_device *pdev)
 
 static void fsl_asrc_remove(struct platform_device *pdev)
 {
+   struct fsl_asrc *asrc = dev_get_drvdata(>dev);
+
+   if (asrc->m2m_pdev && !IS_ERR(asrc->m2m_pdev))
+   platform_device_unregister(asrc->m2m_pdev);
+
pm_runtime_disable(>dev);
if (!pm_runtime_status_suspended(>dev))
fsl_asrc_runtime_suspend(>dev);
-- 
2.34.1



[PATCH v13 06/16] ASoC: fsl_easrc: register m2m platform device

2024-02-26 Thread Shengjiu Wang
Register m2m platform device,that user can
use M2M feature.

Signed-off-by: Shengjiu Wang 
Acked-by: Mark Brown 
---
 sound/soc/fsl/fsl_easrc.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c
index cf7ad30a323b..ccbf45c7abf4 100644
--- a/sound/soc/fsl/fsl_easrc.c
+++ b/sound/soc/fsl/fsl_easrc.c
@@ -2075,6 +2075,7 @@ MODULE_DEVICE_TABLE(of, fsl_easrc_dt_ids);
 static int fsl_easrc_probe(struct platform_device *pdev)
 {
struct fsl_easrc_priv *easrc_priv;
+   struct fsl_asrc_m2m_pdata m2m_pdata;
struct device *dev = >dev;
struct fsl_asrc *easrc;
struct resource *res;
@@ -2190,6 +2191,19 @@ static int fsl_easrc_probe(struct platform_device *pdev)
goto err_pm_disable;
}
 
+   m2m_pdata.asrc = easrc;
+   m2m_pdata.fmt_in = FSL_EASRC_FORMATS;
+   m2m_pdata.fmt_out = FSL_EASRC_FORMATS | 
SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE;
+   m2m_pdata.rate_min = 8000;
+   m2m_pdata.rate_max = 768000;
+   m2m_pdata.chan_min = 1;
+   m2m_pdata.chan_max = 32;
+   easrc->m2m_pdev = platform_device_register_data(>dev,
+   M2M_DRV_NAME,
+   PLATFORM_DEVID_AUTO,
+   _pdata,
+   sizeof(m2m_pdata));
+
return 0;
 
 err_pm_disable:
@@ -2199,6 +2213,11 @@ static int fsl_easrc_probe(struct platform_device *pdev)
 
 static void fsl_easrc_remove(struct platform_device *pdev)
 {
+   struct fsl_asrc *easrc = dev_get_drvdata(>dev);
+
+   if (easrc->m2m_pdev && !IS_ERR(easrc->m2m_pdev))
+   platform_device_unregister(easrc->m2m_pdev);
+
pm_runtime_disable(>dev);
 }
 
-- 
2.34.1



[PATCH v13 01/16] media: v4l2-ctrls: add support for fraction_bits

2024-02-26 Thread Shengjiu Wang
From: Hans Verkuil 

This adds support for the fraction_bits field, used with integer controls.
This allows fixed point formats to be described.

The fraction_bits field is only exposed through VIDIOC_QUERY_EXT_CTRL.

For a given signed two's complement Qf fixed point value 'f' equals
fraction_bits.

Signed-off-by: Hans Verkuil 
---
 .../media/v4l/vidioc-queryctrl.rst| 11 ++-
 drivers/media/v4l2-core/v4l2-ctrls-api.c  |  1 +
 drivers/media/v4l2-core/v4l2-ctrls-core.c | 93 +++
 include/media/v4l2-ctrls.h|  7 +-
 include/uapi/linux/videodev2.h|  3 +-
 5 files changed, 95 insertions(+), 20 deletions(-)

diff --git a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst 
b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
index 4d38acafe8e1..e65c7e5d78ec 100644
--- a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
+++ b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
@@ -267,7 +267,16 @@ See also the examples in :ref:`control`.
   - The size of each dimension. The first ``nr_of_dims`` elements of
this array must be non-zero, all remaining elements must be zero.
 * - __u32
-  - ``reserved``\ [32]
+  - ``fraction_bits``
+  - The number of least significant bits of the control value that
+form the fraction of the fixed point value. This is 0 if the value
+   is a regular integer. This can be used with all integer control types
+   (``INTEGER``, ``INTEGER64``, ``U8``, ``U16`` and ``U32``).
+   For the signed types the signed two's complement representation is used.
+   This field applies to the control value as well as the ``minimum``,
+   ``maximum``, ``step`` and ``default_value`` fields.
+* - __u32
+  - ``reserved``\ [31]
   - Reserved for future extensions. Applications and drivers must set
the array to zero.
 
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-api.c 
b/drivers/media/v4l2-core/v4l2-ctrls-api.c
index d9a422017bd9..ef16b00421ec 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-api.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-api.c
@@ -1101,6 +1101,7 @@ int v4l2_query_ext_ctrl(struct v4l2_ctrl_handler *hdl, 
struct v4l2_query_ext_ctr
qc->elems = ctrl->elems;
qc->nr_of_dims = ctrl->nr_of_dims;
memcpy(qc->dims, ctrl->dims, qc->nr_of_dims * sizeof(qc->dims[0]));
+   qc->fraction_bits = ctrl->fraction_bits;
qc->minimum = ctrl->minimum;
qc->maximum = ctrl->maximum;
qc->default_value = ctrl->default_value;
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c 
b/drivers/media/v4l2-core/v4l2-ctrls-core.c
index c4d995f32191..d83a37198bb5 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
@@ -252,12 +252,61 @@ void v4l2_ctrl_type_op_init(const struct v4l2_ctrl *ctrl, 
u32 from_idx,
 }
 EXPORT_SYMBOL(v4l2_ctrl_type_op_init);
 
+static void v4l2_ctrl_log_fp(s64 v, unsigned int fraction_bits)
+{
+   s64 i, f, mask;
+
+   if (!fraction_bits) {
+   pr_cont("%lld", v);
+   return;
+   }
+
+   mask = (1ULL << fraction_bits) - 1;
+
+   /*
+* Note: this function does not support fixed point u64 with
+* fraction_bits set to 64. At the moment there is no U64
+* control type, but if that is added, then this code will have
+* to add support for it.
+*/
+   if (fraction_bits >= 63)
+   i = v < 0 ? -1 : 0;
+   else
+   i = div64_s64(v, 1LL << fraction_bits);
+
+   f = v < 0 ? -((-v) & mask) : (v & mask);
+
+   if (!f) {
+   pr_cont("%lld", i);
+   } else if (fraction_bits < 20) {
+   u64 div = 1ULL << fraction_bits;
+
+   if (!i && f < 0)
+   pr_cont("-%lld/%llu", -f, div);
+   else if (!i)
+   pr_cont("%lld/%llu", f, div);
+   else if (i < 0 || f < 0)
+   pr_cont("-%lld-%llu/%llu", -i, -f, div);
+   else
+   pr_cont("%lld+%llu/%llu", i, f, div);
+   } else {
+   if (!i && f < 0)
+   pr_cont("-%lld/(2^%u)", -f, fraction_bits);
+   else if (!i)
+   pr_cont("%lld/(2^%u)", f, fraction_bits);
+   else if (i < 0 || f < 0)
+   pr_cont("-%lld-%llu/(2^%u)", -i, -f, fraction_bits);
+   else
+   pr_cont("%lld+%llu/(2^%u)", i, f, fraction_bits);
+   }
+}
+
 void v4l2_ctrl_type_op_log(const struct v4l2_ctrl *ctrl)
 {
union v4l2_ctrl_ptr ptr = ctrl->p_cur;
 
if (ctrl->is_array) {
-   unsigned i;
+   unsigned int i;
 
for (i = 0; i < ctrl->nr_of_dims; i++)
pr_cont("[%u]", ctrl->dims[i]);
@@ -266,7 +315,7 @@ void v4l2_ctrl_type_op_log(const struct v4l2_ctrl *ctrl)
 
 

  1   2   >