Re: [PATCH 1/2] radix/kfence: map __kfence_pool at page granularity
Hari Bathini writes: > When KFENCE is enabled, total system memory is mapped at page level > granularity. But in radix MMU mode, ~3GB additional memory is needed > to map 100GB of system memory at page level granularity when compared > to using 2MB direct mapping. This is not desired considering KFENCE is > designed to be enabled in production kernels [1]. Also, mapping memory > allocated for KFENCE pool at page granularity seems sufficient enough > to enable KFENCE support. So, allocate __kfence_pool during bootup and > map it at page granularity instead of mapping all system memory at > page granularity. > > Without patch: > # cat /proc/meminfo > MemTotal: 101201920 kB > > With patch: > # cat /proc/meminfo > MemTotal: 104483904 kB > > All kfence_test.c testcases passed with this patch. > > [1] https://lore.kernel.org/all/20201103175841.3495947-2-el...@google.com/ > > Signed-off-by: Hari Bathini > --- > arch/powerpc/include/asm/kfence.h| 5 > arch/powerpc/mm/book3s64/radix_pgtable.c | 34 ++-- > arch/powerpc/mm/init_64.c| 14 ++ New at this. But the patch looked interesting, hence my review comments. > 3 files changed, 45 insertions(+), 8 deletions(-) > > diff --git a/arch/powerpc/include/asm/kfence.h > b/arch/powerpc/include/asm/kfence.h > index 424ceef82ae6..18ec2b06ba1e 100644 > --- a/arch/powerpc/include/asm/kfence.h > +++ b/arch/powerpc/include/asm/kfence.h > @@ -8,6 +8,7 @@ > #ifndef __ASM_POWERPC_KFENCE_H > #define __ASM_POWERPC_KFENCE_H > > +#include > #include > #include > > @@ -15,6 +16,10 @@ > #define ARCH_FUNC_PREFIX "." > #endif > > +#ifdef CONFIG_KFENCE > +extern bool kfence_early_init; > +#endif > + > static inline bool arch_kfence_init_pool(void) > { > return true; Shouldn't we return false for !kfence_early_init? Because otherwise, this patch may break the late init case which your next patch is fixing, and maybe git bisect will break? > diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c > b/arch/powerpc/mm/book3s64/radix_pgtable.c > index 15e88f1439ec..fccbf92f279b 100644 > --- a/arch/powerpc/mm/book3s64/radix_pgtable.c > +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c > @@ -31,6 +31,7 @@ > #include > #include > #include > +#include > > #include > > @@ -291,9 +292,8 @@ static unsigned long next_boundary(unsigned long addr, > unsigned long end) > return end; > } > > -static int __meminit create_physical_mapping(unsigned long start, > - unsigned long end, > - int nid, pgprot_t _prot) > +static int __meminit create_physical_mapping(unsigned long start, unsigned > long end, int nid, > + pgprot_t _prot, unsigned long > mapping_sz_limit) lines over 80 chars. > { > unsigned long vaddr, addr, mapping_size = 0; > bool prev_exec, exec = false; > @@ -301,7 +301,10 @@ static int __meminit create_physical_mapping(unsigned > long start, > int psize; > unsigned long max_mapping_size = memory_block_size; > > - if (debug_pagealloc_enabled_or_kfence()) > + if (mapping_sz_limit < max_mapping_size) > + max_mapping_size = mapping_sz_limit; > + > + if (debug_pagealloc_enabled()) > max_mapping_size = PAGE_SIZE; > > start = ALIGN(start, PAGE_SIZE); > @@ -358,6 +361,7 @@ static int __meminit create_physical_mapping(unsigned > long start, > > static void __init radix_init_pgtable(void) > { > + phys_addr_t kfence_pool __maybe_unused; > unsigned long rts_field; > phys_addr_t start, end; > u64 i; > @@ -365,6 +369,13 @@ static void __init radix_init_pgtable(void) > /* We don't support slb for radix */ > slb_set_size(0); > > +#ifdef CONFIG_KFENCE > + if (kfence_early_init) { > + kfence_pool = memblock_phys_alloc(KFENCE_POOL_SIZE, PAGE_SIZE); What if memblock_phys_alloc() failed? error handling? > + memblock_mark_nomap(kfence_pool, KFENCE_POOL_SIZE); > + } > +#endif > + Instead of #ifdef CONFIG_KFENCE in the function, maybe we can define radix_kfence_alloc_pool()? Then we won't need __maybe_unused too. > /* >* Create the linear mapping >*/ > @@ -380,10 +391,18 @@ static void __init radix_init_pgtable(void) > continue; > } > > - WARN_ON(create_physical_mapping(start, end, > - -1, PAGE_KERNEL)); > + WARN_ON(create_physical_mapping(start, end, -1, PAGE_KERNEL, > ~0UL)); > } > > +#ifdef CONFIG_KFENCE > + if (kfence_early_init) { > + create_physical_mapping(kfence_pool, kfence_pool + > KFENCE_POOL_SIZE, -1, > + PAGE_KERNEL, PAGE_SIZE); Even this can return an error. Maybe WARN_ON_ONCE()? or disabling kfence for an error?
Re: [PATCH v15 00/16] Add audio support in v4l2 framework
On Tue, Apr 30, 2024 at 05:27:52PM +0100, Mauro Carvalho Chehab wrote: > Mark Brown escreveu: > > On Tue, Apr 30, 2024 at 10:21:12AM +0200, Sebastian Fricke wrote: > > The discussion around this originally was that all the audio APIs are > > very much centered around real time operations rather than completely > The media subsystem is also centered around real time. Without real > time, you can't have a decent video conference system. Having > mem2mem transfers actually help reducing real time delays, as it > avoids extra latency due to CPU congestion and/or data transfers > from/to userspace. Real time means strongly tied to wall clock times rather than fast - the issue was that all the ALSA APIs are based around pushing data through the system based on a clock. > > That doesn't sound like an immediate solution to maintainer overload > > issues... if something like this is going to happen the DRM solution > > does seem more general but I'm not sure the amount of stop energy is > > proportionate. > I don't think maintainer overload is the issue here. The main > point is to avoid a fork at the audio uAPI, plus the burden > of re-inventing the wheel with new codes for audio formats, > new documentation for them, etc. I thought that discussion had been had already at one of the earlier versions? TBH I've not really been paying attention to this since the very early versions where I raised some similar "why is this in media" points and I thought everyone had decided that this did actually make sense. signature.asc Description: PGP signature
Re: [PATCH v4 13/15] drm/amd/display: Use ARCH_HAS_KERNEL_FPU_SUPPORT
On 2024-03-29 03:18, Samuel Holland wrote: > Now that all previously-supported architectures select > ARCH_HAS_KERNEL_FPU_SUPPORT, this code can depend on that symbol instead > of the existing list of architectures. It can also take advantage of the > common kernel-mode FPU API and method of adjusting CFLAGS. > > Acked-by: Alex Deucher > Reviewed-by: Christoph Hellwig Really nice set of changes. Acked-by: Harry Wentland Harry > Signed-off-by: Samuel Holland > --- > > (no changes since v2) > > Changes in v2: > - Split altivec removal to a separate patch > - Use linux/fpu.h instead of asm/fpu.h in consumers > > drivers/gpu/drm/amd/display/Kconfig | 2 +- > .../gpu/drm/amd/display/amdgpu_dm/dc_fpu.c| 27 ++ > drivers/gpu/drm/amd/display/dc/dml/Makefile | 36 ++- > drivers/gpu/drm/amd/display/dc/dml2/Makefile | 36 ++- > 4 files changed, 7 insertions(+), 94 deletions(-) > > diff --git a/drivers/gpu/drm/amd/display/Kconfig > b/drivers/gpu/drm/amd/display/Kconfig > index 901d1961b739..5fcd4f778dc3 100644 > --- a/drivers/gpu/drm/amd/display/Kconfig > +++ b/drivers/gpu/drm/amd/display/Kconfig > @@ -8,7 +8,7 @@ config DRM_AMD_DC > depends on BROKEN || !CC_IS_CLANG || ARM64 || RISCV || SPARC64 || X86_64 > select SND_HDA_COMPONENT if SND_HDA_CORE > # !CC_IS_CLANG: https://github.com/ClangBuiltLinux/linux/issues/1752 > - select DRM_AMD_DC_FP if (X86 || LOONGARCH || (PPC64 && ALTIVEC) || > (ARM64 && KERNEL_MODE_NEON && !CC_IS_CLANG)) > + select DRM_AMD_DC_FP if ARCH_HAS_KERNEL_FPU_SUPPORT && (!ARM64 || > !CC_IS_CLANG) > help > Choose this option if you want to use the new display engine > support for AMDGPU. This adds required support for Vega and > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/dc_fpu.c > b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_fpu.c > index 0de16796466b..e46f8ce41d87 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/dc_fpu.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_fpu.c > @@ -26,16 +26,7 @@ > > #include "dc_trace.h" > > -#if defined(CONFIG_X86) > -#include > -#elif defined(CONFIG_PPC64) > -#include > -#include > -#elif defined(CONFIG_ARM64) > -#include > -#elif defined(CONFIG_LOONGARCH) > -#include > -#endif > +#include > > /** > * DOC: DC FPU manipulation overview > @@ -87,16 +78,9 @@ void dc_fpu_begin(const char *function_name, const int > line) > WARN_ON_ONCE(!in_task()); > preempt_disable(); > depth = __this_cpu_inc_return(fpu_recursion_depth); > - > if (depth == 1) { > -#if defined(CONFIG_X86) || defined(CONFIG_LOONGARCH) > + BUG_ON(!kernel_fpu_available()); > kernel_fpu_begin(); > -#elif defined(CONFIG_PPC64) > - if (!cpu_has_feature(CPU_FTR_FPU_UNAVAILABLE)) > - enable_kernel_fp(); > -#elif defined(CONFIG_ARM64) > - kernel_neon_begin(); > -#endif > } > > TRACE_DCN_FPU(true, function_name, line, depth); > @@ -118,14 +102,7 @@ void dc_fpu_end(const char *function_name, const int > line) > > depth = __this_cpu_dec_return(fpu_recursion_depth); > if (depth == 0) { > -#if defined(CONFIG_X86) || defined(CONFIG_LOONGARCH) > kernel_fpu_end(); > -#elif defined(CONFIG_PPC64) > - if (!cpu_has_feature(CPU_FTR_FPU_UNAVAILABLE)) > - disable_kernel_fp(); > -#elif defined(CONFIG_ARM64) > - kernel_neon_end(); > -#endif > } else { > WARN_ON_ONCE(depth < 0); > } > diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile > b/drivers/gpu/drm/amd/display/dc/dml/Makefile > index 59d3972341d2..a94b6d546cd1 100644 > --- a/drivers/gpu/drm/amd/display/dc/dml/Makefile > +++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile > @@ -25,40 +25,8 @@ > # It provides the general basic services required by other DAL > # subcomponents. > > -ifdef CONFIG_X86 > -dml_ccflags-$(CONFIG_CC_IS_GCC) := -mhard-float > -dml_ccflags := $(dml_ccflags-y) -msse > -endif > - > -ifdef CONFIG_PPC64 > -dml_ccflags := -mhard-float > -endif > - > -ifdef CONFIG_ARM64 > -dml_rcflags := -mgeneral-regs-only > -endif > - > -ifdef CONFIG_LOONGARCH > -dml_ccflags := -mfpu=64 > -dml_rcflags := -msoft-float > -endif > - > -ifdef CONFIG_CC_IS_GCC > -ifneq ($(call gcc-min-version, 70100),y) > -IS_OLD_GCC = 1 > -endif > -endif > - > -ifdef CONFIG_X86 > -ifdef IS_OLD_GCC > -# Stack alignment mismatch, proceed with caution. > -# GCC < 7.1 cannot compile code using `double` and > -mpreferred-stack-boundary=3 > -# (8B stack alignment). > -dml_ccflags += -mpreferred-stack-boundary=4 > -else > -dml_ccflags += -msse2 > -endif > -endif > +dml_ccflags := $(CC_FLAGS_FPU) > +dml_rcflags := $(CC_FLAGS_NO_FPU) > > ifneq ($(CONFIG_FRAME_WARN),0) > ifeq ($(filter y,$(CONFIG_KASAN)$(CONFIG_KCSAN)),y) > diff --git a/drivers/gpu/drm/amd/display/dc/dml2/Makefile > b/drivers/gpu/drm/amd/display/dc/dml2/Make
Re: [PATCH v4 12/15] drm/amd/display: Only use hard-float, not altivec on powerpc
On 2024-03-29 03:18, Samuel Holland wrote: > From: Michael Ellerman > > The compiler flags enable altivec, but that is not required; hard-float > is sufficient for the code to build and function. > > Drop altivec from the compiler flags and adjust the enable/disable code > to only enable FPU use. > > Signed-off-by: Michael Ellerman > Acked-by: Alex Deucher > Signed-off-by: Samuel Holland Acked-by: Harry Wentland Harry > --- > > (no changes since v2) > > Changes in v2: > - New patch for v2 > > drivers/gpu/drm/amd/display/amdgpu_dm/dc_fpu.c | 12 ++-- > drivers/gpu/drm/amd/display/dc/dml/Makefile| 2 +- > drivers/gpu/drm/amd/display/dc/dml2/Makefile | 2 +- > 3 files changed, 4 insertions(+), 12 deletions(-) > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/dc_fpu.c > b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_fpu.c > index 4ae4720535a5..0de16796466b 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/dc_fpu.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_fpu.c > @@ -92,11 +92,7 @@ void dc_fpu_begin(const char *function_name, const int > line) > #if defined(CONFIG_X86) || defined(CONFIG_LOONGARCH) > kernel_fpu_begin(); > #elif defined(CONFIG_PPC64) > - if (cpu_has_feature(CPU_FTR_VSX_COMP)) > - enable_kernel_vsx(); > - else if (cpu_has_feature(CPU_FTR_ALTIVEC_COMP)) > - enable_kernel_altivec(); > - else if (!cpu_has_feature(CPU_FTR_FPU_UNAVAILABLE)) > + if (!cpu_has_feature(CPU_FTR_FPU_UNAVAILABLE)) > enable_kernel_fp(); > #elif defined(CONFIG_ARM64) > kernel_neon_begin(); > @@ -125,11 +121,7 @@ void dc_fpu_end(const char *function_name, const int > line) > #if defined(CONFIG_X86) || defined(CONFIG_LOONGARCH) > kernel_fpu_end(); > #elif defined(CONFIG_PPC64) > - if (cpu_has_feature(CPU_FTR_VSX_COMP)) > - disable_kernel_vsx(); > - else if (cpu_has_feature(CPU_FTR_ALTIVEC_COMP)) > - disable_kernel_altivec(); > - else if (!cpu_has_feature(CPU_FTR_FPU_UNAVAILABLE)) > + if (!cpu_has_feature(CPU_FTR_FPU_UNAVAILABLE)) > disable_kernel_fp(); > #elif defined(CONFIG_ARM64) > kernel_neon_end(); > diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile > b/drivers/gpu/drm/amd/display/dc/dml/Makefile > index c4a5efd2dda5..59d3972341d2 100644 > --- a/drivers/gpu/drm/amd/display/dc/dml/Makefile > +++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile > @@ -31,7 +31,7 @@ dml_ccflags := $(dml_ccflags-y) -msse > endif > > ifdef CONFIG_PPC64 > -dml_ccflags := -mhard-float -maltivec > +dml_ccflags := -mhard-float > endif > > ifdef CONFIG_ARM64 > diff --git a/drivers/gpu/drm/amd/display/dc/dml2/Makefile > b/drivers/gpu/drm/amd/display/dc/dml2/Makefile > index acff3449b8d7..7b51364084b5 100644 > --- a/drivers/gpu/drm/amd/display/dc/dml2/Makefile > +++ b/drivers/gpu/drm/amd/display/dc/dml2/Makefile > @@ -30,7 +30,7 @@ dml2_ccflags := $(dml2_ccflags-y) -msse > endif > > ifdef CONFIG_PPC64 > -dml2_ccflags := -mhard-float -maltivec > +dml2_ccflags := -mhard-float > endif > > ifdef CONFIG_ARM64
Re: [PATCH 0/4] KVM: Fold kvm_arch_sched_in() into kvm_arch_vcpu_load()
On Tue, Apr 30, 2024 at 12:31:53PM -0700, Sean Christopherson wrote: > Drop kvm_arch_sched_in() and instead pass a @sched_in boolean to > kvm_arch_vcpu_load(). > > While fiddling with an idea for optimizing state management on AMD CPUs, > I wanted to skip re-saving certain host state when a vCPU is scheduled back > in, as the state (theoretically) shouldn't change for the task while it's > scheduled out. Actually doing that was annoying and unnecessarily brittle > due to having a separate API for the kvm_sched_in() case (the state save > needed to be in kvm_arch_vcpu_load() for the common path). > > E.g. I could have set a "temporary"-ish flag somewhere in kvm_vcpu, but (a) > that's gross and (b) it would rely on the arbitrary ordering between > sched_in() and vcpu_load() staying the same. Another option would be to change the rules around kvm_arch_sched_in() where the callee is expected to load the vCPU context. The default implementation could just call kvm_arch_vcpu_load() directly and the x86 implementation can order things the way it wants before kvm_arch_vcpu_load(). I say this because ... > The only real downside I see is that arm64 and riscv end up having to pass > "false" for their direct usage of kvm_arch_vcpu_load(), and passing boolean > literals isn't ideal. But that can be solved by adding an inner helper that > omits the @sched_in param (I almost added a patch to do that, but I couldn't > convince myself it was necessary). Needing to pass @sched_in for other usage of kvm_arch_vcpu_load() hurts readability, especially when no other architecture besides x86 cares about it. -- Thanks, Oliver
Re: [PATCH v2] kprobe/ftrace: bail out if ftrace was killed
Steven Rostedt writes: > On Mon, 29 Apr 2024 10:47:18 -0700 > Stephen Brennan wrote: > >> If an error happens in ftrace, ftrace_kill() will prevent disarming >> kprobes. Eventually, the ftrace_ops associated with the kprobes will be >> freed, yet the kprobes will still be active, and when triggered, they >> will use the freed memory, likely resulting in a page fault and panic. >> >> This behavior can be reproduced quite easily, by creating a kprobe and >> then triggering a ftrace_kill(). For simplicity, we can simulate an >> ftrace error with a kernel module like [1]: >> >> [1]: https://github.com/brenns10/kernel_stuff/tree/master/ftrace_killer >> >> sudo perf probe --add commit_creds >> sudo perf trace -e probe:commit_creds >> # In another terminal >> make >> sudo insmod ftrace_killer.ko # calls ftrace_kill(), simulating bug >> # Back to perf terminal >> # ctrl-c >> sudo perf probe --del commit_creds >> >> After a short period, a page fault and panic would occur as the kprobe >> continues to execute and uses the freed ftrace_ops. While ftrace_kill() >> is supposed to be used only in extreme circumstances, it is invoked in >> FTRACE_WARN_ON() and so there are many places where an unexpected bug >> could be triggered, yet the system may continue operating, possibly >> without the administrator noticing. If ftrace_kill() does not panic the >> system, then we should do everything we can to continue operating, >> rather than leave a ticking time bomb. >> >> Signed-off-by: Stephen Brennan >> --- >> Difference from v1: removed both existing declarations of ftrace_is_dead() >> from kernel/trace/trace.h. >> >> arch/csky/kernel/probes/ftrace.c | 3 +++ >> arch/loongarch/kernel/ftrace_dyn.c | 3 +++ >> arch/parisc/kernel/ftrace.c | 3 +++ >> arch/powerpc/kernel/kprobes-ftrace.c | 3 +++ >> arch/riscv/kernel/probes/ftrace.c| 3 +++ >> arch/s390/kernel/ftrace.c| 3 +++ >> arch/x86/kernel/kprobes/ftrace.c | 3 +++ >> include/linux/ftrace.h | 2 ++ >> kernel/trace/trace.h | 2 -- >> 9 files changed, 23 insertions(+), 2 deletions(-) >> >> diff --git a/arch/csky/kernel/probes/ftrace.c >> b/arch/csky/kernel/probes/ftrace.c >> index 834cffcfbce3..3931bf9f707b 100644 >> --- a/arch/csky/kernel/probes/ftrace.c >> +++ b/arch/csky/kernel/probes/ftrace.c >> @@ -12,6 +12,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long >> parent_ip, >> struct kprobe_ctlblk *kcb; >> struct pt_regs *regs; >> >> +if (unlikely(ftrace_is_dead())) >> +return; >> + >> bit = ftrace_test_recursion_trylock(ip, parent_ip); >> if (bit < 0) >> return; >> diff --git a/arch/loongarch/kernel/ftrace_dyn.c >> b/arch/loongarch/kernel/ftrace_dyn.c >> index 73858c9029cc..82c952cb5be0 100644 >> --- a/arch/loongarch/kernel/ftrace_dyn.c >> +++ b/arch/loongarch/kernel/ftrace_dyn.c >> @@ -287,6 +287,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned >> long parent_ip, >> struct kprobe *p; >> struct kprobe_ctlblk *kcb; >> >> +if (unlikely(ftrace_is_dead())) >> +return; >> + >> bit = ftrace_test_recursion_trylock(ip, parent_ip); >> if (bit < 0) >> return; >> diff --git a/arch/parisc/kernel/ftrace.c b/arch/parisc/kernel/ftrace.c >> index 621a4b386ae4..3660834f54c3 100644 >> --- a/arch/parisc/kernel/ftrace.c >> +++ b/arch/parisc/kernel/ftrace.c >> @@ -206,6 +206,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned >> long parent_ip, >> struct kprobe *p; >> int bit; >> >> +if (unlikely(ftrace_is_dead())) >> +return; >> + >> bit = ftrace_test_recursion_trylock(ip, parent_ip); >> if (bit < 0) >> return; >> diff --git a/arch/powerpc/kernel/kprobes-ftrace.c >> b/arch/powerpc/kernel/kprobes-ftrace.c >> index 072ebe7f290b..85eb55aa1457 100644 >> --- a/arch/powerpc/kernel/kprobes-ftrace.c >> +++ b/arch/powerpc/kernel/kprobes-ftrace.c >> @@ -21,6 +21,9 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned >> long parent_nip, >> struct pt_regs *regs; >> int bit; >> >> +if (unlikely(ftrace_is_dead())) >> +return; >> + >> bit = ftrace_test_recursion_trylock(nip, parent_nip); >> if (bit < 0) >> return; >> diff --git a/arch/riscv/kernel/probes/ftrace.c >> b/arch/riscv/kernel/probes/ftrace.c >> index 7142ec42e889..8814fbe4c888 100644 >> --- a/arch/riscv/kernel/probes/ftrace.c >> +++ b/arch/riscv/kernel/probes/ftrace.c >> @@ -11,6 +11,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long >> parent_ip, >> struct kprobe_ctlblk *kcb; >> int bit; >> >> +if (unlikely(ftrace_is_dead())) >> +return; >> + >> bit = ftrace_test_recursion_trylock(ip, parent_ip); >> if (bit < 0) >> return; >> diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c >> index c46381ea04ec..ccbe8ccf945b 100644 >> --- a/ar
[RFC PATCH v2 6/6] powerpc/iommu: Implement the iommu_table_group_ops for pSeries
PPC64 IOMMU API defines iommu_table_group_ops which handles DMA windows for PEs, their ownership transfer, create/set/unset the TCE tables for the Dynamic DMA wundows(DDW). VFIOS uses these APIs for support on POWER. The commit 9d67c9433509 "(powerpc/iommu: Add "borrowing" iommu_table_group_ops)" implemented partial support for this API with "borrow" mechanism wherein the DMA windows if created already by the host driver, they would be available for VFIO to use. Also, it didn't have the support to control/modify the window size or the IO page size. The current patch implements all the necessary iommu_table_group_ops APIs there by avoiding the "borrrowing". So, just the way it is on the PowerNV platform, with this patch the iommu table group ownership is transferred to the VFIO PPC subdriver, the iommu table, DMA windows creation/deletion all driven through the APIs. The pSeries uses the query-pe-dma-window, create-pe-dma-window and reset-pe-dma-window RTAS calls for DMA window creation, deletion and reset to defaul. The RTAs calls do show some minor differences to the way things are to be handled on the pSeries which are listed below. * On pSeries, the default DMA window size is "fixed" cannot be custom sized as requested by the user. For non-SRIOV VFs, It is fixed at 2GB and for SRIOV VFs, its variable sized based on the capacity assigned to it during the VF assignment to the LPAR. So, for the default DMA window alone the size if requested less than tce32_size, the smaller size is enforced using the iommu table->it_size. * The DMA start address for 32-bit window is 0, and for the 64-bit window in case of PowerNV is hardcoded to TVE select (bit 59) at 512PiB offset. And this address is returned at the time of create_table() API call(even before the window is created), the subsequent set_window() call actually opens the DMA window. On pSeries, the DMA start address for 32-bit window is known from the 'ibm,dma-window' DT property. However, the 64-bit window start address is not known until the create-pe-dma RTAS call is made. So, the create_table() which returns the DMA window start address actually opens the DMA window and returns the DMA start address as returned by the Hypervisor for the create-pe-dma RTAS call. * The reset-pe-dma RTAS call resets the DMA windows and restores the default DMA window, however it does not clear the TCE table entries if there are any. In case of ownership transfer from platform domain which used direct mapping, the patch chooses remove-pe-dma instead of reset-pe for the 64-bit window intentionally so that the clear_dma_window() is called. Other than the DMA window management changes mentioned above, the patch also brings back the userspace view for the single level TCE as it existed before commit 090bad39b237a ("powerpc/powernv: Add indirect levels to it_userspace") along with the relavent refactoring. Signed-off-by: Shivaprasad G Bhat --- arch/powerpc/include/asm/iommu.h |4 arch/powerpc/kernel/iommu.c |4 arch/powerpc/platforms/powernv/pci-ioda.c |6 arch/powerpc/platforms/pseries/iommu.c| 643 + 4 files changed, 559 insertions(+), 98 deletions(-) diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h index 784809e34abe..1e0c2b2882c2 100644 --- a/arch/powerpc/include/asm/iommu.h +++ b/arch/powerpc/include/asm/iommu.h @@ -181,9 +181,9 @@ struct iommu_table_group_ops { long (*unset_window)(struct iommu_table_group *table_group, int num); /* Switch ownership from platform code to external user (e.g. VFIO) */ - long (*take_ownership)(struct iommu_table_group *table_group); + long (*take_ownership)(struct iommu_table_group *table_group, struct device *dev); /* Switch ownership from external user (e.g. VFIO) back to core */ - void (*release_ownership)(struct iommu_table_group *table_group); + void (*release_ownership)(struct iommu_table_group *table_group, struct device *dev); }; struct iommu_table_group_link { diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 31dc663be0cc..2ad1e320f69f 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -1170,7 +1170,7 @@ spapr_tce_platform_iommu_attach_dev(struct iommu_domain *platform_domain, * The domain being set to PLATFORM from earlier * BLOCKED. The table_group ownership has to be released. */ - table_group->ops->release_ownership(table_group); + table_group->ops->release_ownership(table_group, dev); iommu_group_put(grp); return 0; @@ -1198,7 +1198,7 @@ spapr_tce_blocked_iommu_attach_dev(struct iommu_domain *platform_domain, * also sets the dma_api ops */ table_group = iommu_group_get_iommudata(grp); - ret = table_group->ops->take_ownership(table_group); + ret = table_group->ops->take_ownership(table_group,
[RFC PATCH v2 4/6] vfio/spapr: Always clear TCEs before unsetting the window
The PAPR expects the TCE table to have no entries at the time of unset window(i.e. remove-pe). The TCE clear right now is done before freeing the iommu table. On pSeries, the unset window makes those entries inaccessible to the OS and the H_PUT/GET calls fail on them with H_CONSTRAINED. On PowerNV, this has no side effect as the TCE clear can be done before the DMA window removal as well. Signed-off-by: Shivaprasad G Bhat --- drivers/vfio/vfio_iommu_spapr_tce.c | 13 + 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c index a94ec6225d31..5f9e7e477078 100644 --- a/drivers/vfio/vfio_iommu_spapr_tce.c +++ b/drivers/vfio/vfio_iommu_spapr_tce.c @@ -364,7 +364,6 @@ static void tce_iommu_release(void *iommu_data) if (!tbl) continue; - tce_iommu_clear(container, tbl, tbl->it_offset, tbl->it_size); tce_iommu_free_table(container, tbl); } @@ -720,6 +719,8 @@ static long tce_iommu_remove_window(struct tce_container *container, BUG_ON(!tbl->it_size); + tce_iommu_clear(container, tbl, tbl->it_offset, tbl->it_size); + /* Detach groups from IOMMUs */ list_for_each_entry(tcegrp, &container->group_list, next) { table_group = iommu_group_get_iommudata(tcegrp->grp); @@ -738,7 +739,6 @@ static long tce_iommu_remove_window(struct tce_container *container, } /* Free table */ - tce_iommu_clear(container, tbl, tbl->it_offset, tbl->it_size); tce_iommu_free_table(container, tbl); container->tables[num] = NULL; @@ -1197,9 +1197,14 @@ static void tce_iommu_release_ownership(struct tce_container *container, return; } - for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) - if (container->tables[i]) + for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) { + if (container->tables[i]) { + tce_iommu_clear(container, container->tables[i], + container->tables[i]->it_offset, + container->tables[i]->it_size); table_group->ops->unset_window(table_group, i); + } + } } static long tce_iommu_take_ownership(struct tce_container *container,
[RFC PATCH v2 5/6] powerpc/iommu: Move dev_has_iommu_table() to iommu.c
Move function dev_has_iommu_table() to powerpc/kernel/iommu.c as it is going to be used by machine specific iommu code as well in subsequent patches. Signed-off-by: Shivaprasad G Bhat --- arch/powerpc/include/asm/iommu.h |1 + arch/powerpc/kernel/eeh.c| 16 arch/powerpc/kernel/iommu.c | 17 + 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h index 744cc5fc22d3..784809e34abe 100644 --- a/arch/powerpc/include/asm/iommu.h +++ b/arch/powerpc/include/asm/iommu.h @@ -220,6 +220,7 @@ extern long iommu_tce_xchg_no_kill(struct mm_struct *mm, enum dma_data_direction *direction); extern void iommu_tce_kill(struct iommu_table *tbl, unsigned long entry, unsigned long pages); +int dev_has_iommu_table(struct device *dev, void *data); #else static inline void iommu_register_group(struct iommu_table_group *table_group, diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index ab316e155ea9..37bfbef929b5 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -1264,22 +1264,6 @@ EXPORT_SYMBOL(eeh_dev_release); #ifdef CONFIG_IOMMU_API -static int dev_has_iommu_table(struct device *dev, void *data) -{ - struct pci_dev *pdev = to_pci_dev(dev); - struct pci_dev **ppdev = data; - - if (!dev) - return 0; - - if (device_iommu_mapped(dev)) { - *ppdev = pdev; - return 1; - } - - return 0; -} - /** * eeh_iommu_group_to_pe - Convert IOMMU group to EEH PE * @group: IOMMU group diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index bc4584e73061..31dc663be0cc 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -987,6 +987,23 @@ unsigned long iommu_direction_to_tce_perm(enum dma_data_direction dir) EXPORT_SYMBOL_GPL(iommu_direction_to_tce_perm); #ifdef CONFIG_IOMMU_API + +int dev_has_iommu_table(struct device *dev, void *data) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct pci_dev **ppdev = data; + + if (!dev) + return 0; + + if (device_iommu_mapped(dev)) { + *ppdev = pdev; + return 1; + } + + return 0; +} + /* * SPAPR TCE API */
[RFC PATCH v2 3/6] powerpc/pseries/iommu: Use the iommu table[0] for IOV VF's DDW
This patch basically brings consistency with PowerNV approach to use the first freely available iommu table when the default window is removed. The pSeries iommu code convention has been that the table[0] is for the default 32 bit DMA window and the table[1] is for the 64 bit DDW. With VFs having only 1 DMA window, the default has to be removed for creating the larger DMA window. The existing code uses the table[1] for that, while marking the table[0] as NULL. This is fine as long as the host driver itself uses the device. For the VFIO user, on pSeries there is no way to skip table[0] as the VFIO subdriver uses the first freely available table. The window 0, when created as 64-bit DDW in that context would still be on table[0], as the maximum number of windows is 1. This won't have any impact for the host driver as the table is fetched from the device's iommu_table_base. Signed-off-by: Shivaprasad G Bhat --- arch/powerpc/platforms/pseries/iommu.c | 12 +++- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 5b68a4918d63..e701255560a6 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -155,7 +155,7 @@ static void iommu_pseries_free_group(struct iommu_table_group *table_group, #endif /* Default DMA window table is at index 0, while DDW at 1. SR-IOV -* adapters only have table on index 1. +* adapters only have table on index 0(if not direct mapped). */ if (table_group->tables[0]) iommu_tce_table_put(table_group->tables[0]); @@ -1519,6 +1519,11 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn) clean_dma_window(pdn, win64->value); goto out_del_list; } + if (default_win_removed) { + iommu_tce_table_put(pci->table_group->tables[0]); + pci->table_group->tables[0] = NULL; + set_iommu_table_base(&dev->dev, NULL); + } } else { struct iommu_table *newtbl; int i; @@ -1548,15 +1553,12 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn) 1UL << len, page_shift, NULL, &iommu_table_lpar_multi_ops); iommu_init_table(newtbl, pci->phb->node, start, end); - pci->table_group->tables[1] = newtbl; + pci->table_group->tables[default_win_removed ? 0 : 1] = newtbl; set_iommu_table_base(&dev->dev, newtbl); } if (default_win_removed) { - iommu_tce_table_put(pci->table_group->tables[0]); - pci->table_group->tables[0] = NULL; - /* default_win is valid here because default_win_removed == true */ of_remove_property(pdn, default_win); dev_info(&dev->dev, "Removed default DMA window for %pOF\n", pdn);
[RFC PATCH v2 2/6] powerpc/pseries/iommu: Fix the VFIO_IOMMU_SPAPR_TCE_GET_INFO ioctl output
The ioctl VFIO_IOMMU_SPAPR_TCE_GET_INFO is not reporting the actuals on the platform as not all the details are correctly collected during the platform probe/scan into the iommu_table_group. Collect the information during the device setup time as the DMA window property is already looked up on parent nodes anyway. Signed-off-by: Shivaprasad G Bhat --- arch/powerpc/platforms/pseries/iommu.c | 81 ++-- 1 file changed, 67 insertions(+), 14 deletions(-) diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index c6850ec1919a..5b68a4918d63 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -857,13 +857,6 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus) be32_to_cpu(prop.tce_shift), NULL, &iommu_table_lpar_multi_ops); - /* Only for normal boot with default window. Doesn't matter even -* if we set these with DDW which is 64bit during kdump, since -* these will not be used during kdump. -*/ - ppci->table_group->tce32_start = be64_to_cpu(prop.dma_base); - ppci->table_group->tce32_size = 1 << be32_to_cpu(prop.window_shift); - if (!iommu_init_table(tbl, ppci->phb->node, 0, 0)) panic("Failed to initialize iommu table"); @@ -1615,6 +1608,71 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn) return direct_mapping; } +static __u64 query_page_size_to_mask(u32 query_page_size) +{ + const long shift[] = { + (SZ_4K), (SZ_64K), (SZ_16M), + (SZ_32M), (SZ_64M), (SZ_128M), + (SZ_256M), (SZ_16G), (SZ_2M) + }; + int i, ret = 0; + + for (i = 0; i < ARRAY_SIZE(shift); i++) { + if (query_page_size & (1 << i)) + ret |= shift[i]; + } + + return ret; +} + +static void spapr_tce_init_table_group(struct pci_dev *pdev, + struct device_node *pdn, + struct dynamic_dma_window_prop prop) +{ + struct iommu_table_group *table_group = PCI_DN(pdn)->table_group; + u32 ddw_avail[DDW_APPLICABLE_SIZE]; + + struct ddw_query_response query; + int ret; + + /* Only for normal boot with default window. Doesn't matter during +* kdump, since these will not be used during kdump. +*/ + if (is_kdump_kernel()) + return; + + if (table_group->max_dynamic_windows_supported != 0) + return; /* already initialized */ + + table_group->tce32_start = be64_to_cpu(prop.dma_base); + table_group->tce32_size = 1 << be32_to_cpu(prop.window_shift); + + if (!of_find_property(pdn, "ibm,dma-window", NULL)) + dev_err(&pdev->dev, "default dma window missing!\n"); + + ret = of_property_read_u32_array(pdn, "ibm,ddw-applicable", + &ddw_avail[0], DDW_APPLICABLE_SIZE); + if (ret) { + table_group->max_dynamic_windows_supported = -1; + return; + } + + ret = query_ddw(pdev, ddw_avail, &query, pdn); + if (ret) { + dev_err(&pdev->dev, "%s: query_ddw failed\n", __func__); + table_group->max_dynamic_windows_supported = -1; + return; + } + + if (query.windows_available == 0) + table_group->max_dynamic_windows_supported = 1; + else + table_group->max_dynamic_windows_supported = IOMMU_TABLE_GROUP_MAX_TABLES; + + table_group->max_levels = 1; + table_group->pgsizes |= query_page_size_to_mask(query.page_size); +} + static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) { struct device_node *pdn, *dn; @@ -1654,13 +1712,6 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) be32_to_cpu(prop.tce_shift), NULL, &iommu_table_lpar_multi_ops); - /* Only for normal boot with default window. Doesn't matter even -* if we set these with DDW which is 64bit during kdump, since -* these will not be used during kdump. -*/ - pci->table_group->tce32_start = be64_to_cpu(prop.dma_base); - pci->table_group->tce32_size = 1 << be32_to_cpu(prop.window_shift); - iommu_init_table(tbl, pci->phb->node, 0, 0); iommu_register_group(pci->table_group, pci_domain_nr(pci->phb->bus), 0); @@ -1669,6 +1720,8 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) pr_debug(" found DMA window, table: %p\n", pci->table_group); } + spapr_tce_init_table_group(dev, pdn, prop); + set_iommu_table_base(&dev
[RFC PATCH v2 1/6] powerpc/iommu: Move pSeries specific functions to pseries/iommu.c
The PowerNV specific table_group_ops are defined in powernv/pci-ioda.c. The pSeries specific table_group_ops are sitting in the generic powerpc file. Move it to where it actually belong(pseries/iommu.c). Only code movement, no functional changes intended. Signed-off-by: Shivaprasad G Bhat --- arch/powerpc/include/asm/iommu.h |4 + arch/powerpc/kernel/iommu.c| 149 arch/powerpc/platforms/pseries/iommu.c | 144 +++ 3 files changed, 149 insertions(+), 148 deletions(-) diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h index 026695943550..744cc5fc22d3 100644 --- a/arch/powerpc/include/asm/iommu.h +++ b/arch/powerpc/include/asm/iommu.h @@ -156,6 +156,9 @@ extern int iommu_tce_table_put(struct iommu_table *tbl); extern struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid, unsigned long res_start, unsigned long res_end); bool iommu_table_in_use(struct iommu_table *tbl); +extern void iommu_table_reserve_pages(struct iommu_table *tbl, + unsigned long res_start, unsigned long res_end); +extern void iommu_table_clear(struct iommu_table *tbl); #define IOMMU_TABLE_GROUP_MAX_TABLES 2 @@ -218,7 +221,6 @@ extern long iommu_tce_xchg_no_kill(struct mm_struct *mm, extern void iommu_tce_kill(struct iommu_table *tbl, unsigned long entry, unsigned long pages); -extern struct iommu_table_group_ops spapr_tce_table_group_ops; #else static inline void iommu_register_group(struct iommu_table_group *table_group, int pci_domain_number, diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 29a8c8e18585..bc4584e73061 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -642,7 +642,7 @@ void ppc_iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, tbl->it_ops->flush(tbl); } -static void iommu_table_clear(struct iommu_table *tbl) +void iommu_table_clear(struct iommu_table *tbl) { /* * In case of firmware assisted dump system goes through clean @@ -683,7 +683,7 @@ static void iommu_table_clear(struct iommu_table *tbl) #endif } -static void iommu_table_reserve_pages(struct iommu_table *tbl, +void iommu_table_reserve_pages(struct iommu_table *tbl, unsigned long res_start, unsigned long res_end) { int i; @@ -1101,59 +1101,6 @@ void iommu_tce_kill(struct iommu_table *tbl, } EXPORT_SYMBOL_GPL(iommu_tce_kill); -#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) -static int iommu_take_ownership(struct iommu_table *tbl) -{ - unsigned long flags, i, sz = (tbl->it_size + 7) >> 3; - int ret = 0; - - /* -* VFIO does not control TCE entries allocation and the guest -* can write new TCEs on top of existing ones so iommu_tce_build() -* must be able to release old pages. This functionality -* requires exchange() callback defined so if it is not -* implemented, we disallow taking ownership over the table. -*/ - if (!tbl->it_ops->xchg_no_kill) - return -EINVAL; - - spin_lock_irqsave(&tbl->large_pool.lock, flags); - for (i = 0; i < tbl->nr_pools; i++) - spin_lock_nest_lock(&tbl->pools[i].lock, &tbl->large_pool.lock); - - if (iommu_table_in_use(tbl)) { - pr_err("iommu_tce: it_map is not empty"); - ret = -EBUSY; - } else { - memset(tbl->it_map, 0xff, sz); - } - - for (i = 0; i < tbl->nr_pools; i++) - spin_unlock(&tbl->pools[i].lock); - spin_unlock_irqrestore(&tbl->large_pool.lock, flags); - - return ret; -} - -static void iommu_release_ownership(struct iommu_table *tbl) -{ - unsigned long flags, i, sz = (tbl->it_size + 7) >> 3; - - spin_lock_irqsave(&tbl->large_pool.lock, flags); - for (i = 0; i < tbl->nr_pools; i++) - spin_lock_nest_lock(&tbl->pools[i].lock, &tbl->large_pool.lock); - - memset(tbl->it_map, 0, sz); - - iommu_table_reserve_pages(tbl, tbl->it_reserved_start, - tbl->it_reserved_end); - - for (i = 0; i < tbl->nr_pools; i++) - spin_unlock(&tbl->pools[i].lock); - spin_unlock_irqrestore(&tbl->large_pool.lock, flags); -} -#endif - int iommu_add_device(struct iommu_table_group *table_group, struct device *dev) { /* @@ -1185,98 +1132,6 @@ int iommu_add_device(struct iommu_table_group *table_group, struct device *dev) EXPORT_SYMBOL_GPL(iommu_add_device); #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) -/* - * A simple iommu_table_group_ops which only allows reusing the existing - * iommu_table. This handles VFIO for POWER7 or the nested KVM. - * The ops does not allow creating windows and only allows reusing the existing - * one if it matches table_group->tce3
[RFC PATCH v2 0/6] powerpc: pSeries: vfio: iommu: Re-enable support for SPAPR TCE VFIO
RFC v1 was posted here [1]. As I was testing more and fixing the issues, I realized its clean to have the table_group_ops implemented the way it is done on PowerNV and stop 'borrowing' the DMA windows for pSeries. This patch-set implements the iommu table_group_ops for pSeries for VFIO SPAPR TCE sub-driver thereby enabling the VFIO support on POWER pSeries machines. So, this patchset is a re-write and not close to the V1 except for few changes. Structure of the patchset: - The first and fifth patches just code movements. Second patch takes care of collecting the TCE and DDW information for the vfio_iommu_spapr_tce_ddw_info during probe. Third patch fixes the convention of using table[1] for VFs on pSeries when used by the host driver. Fourth patch fixes the VFIO to call TCE clear before unset window. The last patch has the API implementations, please find the details on its commit description. Testing: --- Tested with nested guest for NVME card, Mellanox multi-function card by attaching them to nested kvm guest running on a pSeries lpar. Also vfio-test [2] by Alex Willamson, was forked and updated to add support for pSeries guest and used to test these patches[3]. Limitations/Known Issues: * The DMA window restrictions with SRIOV VF scenarios of having maximum 1 dma window is taken care in the current patches itself. However, the necessary changes required in vfio_iommu_spapr_tce_ddw_info to expose the default window being a 64-bit one and the qemu changes handle the same will be taken care in next versions. * KVM guest boot throws warning at remap_pfn_range_notrack(), on the host, I will post the fix along in the next versions. * The DLPAR hotplugged device has no FDT entry until next reboot, default dma window property has to be preserved differently for this case. References: -- [1] https://lore.kernel.org/linuxppc-dev/171026724548.8367.8321359354119254395.st...@linux.ibm.com/ [2] https://github.com/awilliam/tests [3] https://github.com/nnmwebmin/vfio-ppc-tests/tree/vfio-ppc-ex --- Changelog: v1: https://lore.kernel.org/linuxppc-dev/171026724548.8367.8321359354119254395.st...@linux.ibm.com/ - Rewrite as to stop borrowing the DMA windows and implemented the table_group_ops for pSeries. - Cover letter and Patch 6 has more details as this was a rewrite. Shivaprasad G Bhat (6): powerpc/iommu: Move pSeries specific functions to pseries/iommu.c powerpc/pseries/iommu: Fix the VFIO_IOMMU_SPAPR_TCE_GET_INFO ioctl output powerpc/pseries/iommu: Use the iommu table[0] for IOV VF's DDW vfio/spapr: Always clear TCEs before unsetting the window powerpc/iommu: Move dev_has_iommu_table() to iommu.c powerpc/iommu: Implement the iommu_table_group_ops for pSeries arch/powerpc/include/asm/iommu.h | 9 +- arch/powerpc/kernel/eeh.c | 16 - arch/powerpc/kernel/iommu.c | 170 + arch/powerpc/platforms/powernv/pci-ioda.c | 6 +- arch/powerpc/platforms/pseries/iommu.c| 720 +- drivers/vfio/vfio_iommu_spapr_tce.c | 13 +- 6 files changed, 729 insertions(+), 205 deletions(-) -- Signature
Re: [PATCH 13/13] ASoC: sunxi: Use snd_soc_substream_to_rtd() for accessing private_data
Dne torek, 30. april 2024 ob 16:02:22 GMT +2 je Krzysztof Kozlowski napisal(a): > Do not open-code snd_soc_substream_to_rtd(). > > Signed-off-by: Krzysztof Kozlowski Reviewed-by: Jernej Skrabec Best regards, Jernej > --- > sound/soc/sunxi/sun50i-dmic.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/sound/soc/sunxi/sun50i-dmic.c b/sound/soc/sunxi/sun50i-dmic.c > index c76628bc86c6..fedfa4fc95fb 100644 > --- a/sound/soc/sunxi/sun50i-dmic.c > +++ b/sound/soc/sunxi/sun50i-dmic.c > @@ -74,7 +74,7 @@ static const struct dmic_rate dmic_rate_s[] = { > static int sun50i_dmic_startup(struct snd_pcm_substream *substream, > struct snd_soc_dai *cpu_dai) > { > - struct snd_soc_pcm_runtime *rtd = substream->private_data; > + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); > struct sun50i_dmic_dev *host = > snd_soc_dai_get_drvdata(snd_soc_rtd_to_cpu(rtd, 0)); > > /* only support capture */ > >
[PATCH 4/4] KVM: Delete the now unused kvm_arch_sched_in()
Delete kvm_arch_sched_in() now that all implementations are nops. Signed-off-by: Sean Christopherson --- arch/arm64/include/asm/kvm_host.h | 1 - arch/loongarch/include/asm/kvm_host.h | 1 - arch/mips/include/asm/kvm_host.h | 1 - arch/powerpc/include/asm/kvm_host.h | 1 - arch/riscv/include/asm/kvm_host.h | 1 - arch/s390/include/asm/kvm_host.h | 1 - arch/x86/kvm/pmu.c| 6 +++--- arch/x86/kvm/x86.c| 5 - include/linux/kvm_host.h | 2 -- virt/kvm/kvm_main.c | 1 - 10 files changed, 3 insertions(+), 17 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 9e8a496fb284..a12d3bb0b590 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -1180,7 +1180,6 @@ static inline bool kvm_system_needs_idmapped_vectors(void) } static inline void kvm_arch_sync_events(struct kvm *kvm) {} -static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {} void kvm_arm_init_debug(void); void kvm_arm_vcpu_init_debug(struct kvm_vcpu *vcpu); diff --git a/arch/loongarch/include/asm/kvm_host.h b/arch/loongarch/include/asm/kvm_host.h index 69305441f40d..64ca60a3ce24 100644 --- a/arch/loongarch/include/asm/kvm_host.h +++ b/arch/loongarch/include/asm/kvm_host.h @@ -228,7 +228,6 @@ static inline bool kvm_is_ifetch_fault(struct kvm_vcpu_arch *arch) static inline void kvm_arch_hardware_unsetup(void) {} static inline void kvm_arch_sync_events(struct kvm *kvm) {} static inline void kvm_arch_memslots_updated(struct kvm *kvm, u64 gen) {} -static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {} static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {} static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {} static inline void kvm_arch_vcpu_block_finish(struct kvm_vcpu *vcpu) {} diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h index 179f320cc231..6743a57c1ab4 100644 --- a/arch/mips/include/asm/kvm_host.h +++ b/arch/mips/include/asm/kvm_host.h @@ -890,7 +890,6 @@ static inline void kvm_arch_sync_events(struct kvm *kvm) {} static inline void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *slot) {} static inline void kvm_arch_memslots_updated(struct kvm *kvm, u64 gen) {} -static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {} static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {} static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {} diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 8abac532146e..c4fb6a27fb92 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -897,7 +897,6 @@ struct kvm_vcpu_arch { static inline void kvm_arch_sync_events(struct kvm *kvm) {} static inline void kvm_arch_memslots_updated(struct kvm *kvm, u64 gen) {} static inline void kvm_arch_flush_shadow_all(struct kvm *kvm) {} -static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {} static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {} static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {} diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h index 484d04a92fa6..6cd7a576ef14 100644 --- a/arch/riscv/include/asm/kvm_host.h +++ b/arch/riscv/include/asm/kvm_host.h @@ -272,7 +272,6 @@ struct kvm_vcpu_arch { }; static inline void kvm_arch_sync_events(struct kvm *kvm) {} -static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {} #define KVM_RISCV_GSTAGE_TLB_MIN_ORDER 12 diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index 95990461888f..e9fcaf4607a6 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h @@ -1045,7 +1045,6 @@ extern int kvm_s390_gisc_register(struct kvm *kvm, u32 gisc); extern int kvm_s390_gisc_unregister(struct kvm *kvm, u32 gisc); static inline void kvm_arch_sync_events(struct kvm *kvm) {} -static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {} static inline void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *slot) {} static inline void kvm_arch_memslots_updated(struct kvm *kvm, u64 gen) {} diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c index c397b28e3d1b..75346a588e13 100644 --- a/arch/x86/kvm/pmu.c +++ b/arch/x86/kvm/pmu.c @@ -521,9 +521,9 @@ void kvm_pmu_handle_event(struct kvm_vcpu *vcpu) } /* -* Unused perf_events are only released if the corresponding MSRs -* weren't accessed during the last vCPU time slice. kvm_arch_sched_in -* triggers KVM_REQ_PMU if cleanup is needed. +* Release unused perf_events if the corresponding guest MSRs weren't +* accessed during the last vCPU time slice (
[PATCH 3/4] KVM: x86: Fold kvm_arch_sched_in() into kvm_arch_vcpu_load()
Fold the guts of kvm_arch_sched_in() into kvm_arch_vcpu_load(), keying off the recently added @sched_in as appropriate. Note, there is a very slight functional change, as PLE shrink updates will now happen after blasting WBINVD, but that is quite uninteresting. Signed-off-by: Sean Christopherson --- arch/x86/include/asm/kvm-x86-ops.h | 1 - arch/x86/include/asm/kvm_host.h| 4 +--- arch/x86/kvm/svm/svm.c | 13 - arch/x86/kvm/vmx/main.c| 2 -- arch/x86/kvm/vmx/vmx.c | 11 --- arch/x86/kvm/vmx/x86_ops.h | 3 +-- arch/x86/kvm/x86.c | 19 +++ 7 files changed, 21 insertions(+), 32 deletions(-) diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-x86-ops.h index 5187fcf4b610..910d06cdb86b 100644 --- a/arch/x86/include/asm/kvm-x86-ops.h +++ b/arch/x86/include/asm/kvm-x86-ops.h @@ -103,7 +103,6 @@ KVM_X86_OP(write_tsc_multiplier) KVM_X86_OP(get_exit_info) KVM_X86_OP(check_intercept) KVM_X86_OP(handle_exit_irqoff) -KVM_X86_OP(sched_in) KVM_X86_OP_OPTIONAL(update_cpu_dirty_logging) KVM_X86_OP_OPTIONAL(vcpu_blocking) KVM_X86_OP_OPTIONAL(vcpu_unblocking) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 01c69840647e..9fd1ec82303d 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1624,7 +1624,7 @@ struct kvm_x86_ops { void (*vcpu_reset)(struct kvm_vcpu *vcpu, bool init_event); void (*prepare_switch_to_guest)(struct kvm_vcpu *vcpu); - void (*vcpu_load)(struct kvm_vcpu *vcpu, int cpu); + void (*vcpu_load)(struct kvm_vcpu *vcpu, int cpu, bool sched_in); void (*vcpu_put)(struct kvm_vcpu *vcpu); void (*update_exception_bitmap)(struct kvm_vcpu *vcpu); @@ -1746,8 +1746,6 @@ struct kvm_x86_ops { struct x86_exception *exception); void (*handle_exit_irqoff)(struct kvm_vcpu *vcpu); - void (*sched_in)(struct kvm_vcpu *vcpu, int cpu); - /* * Size of the CPU's dirty log buffer, i.e. VMX's PML buffer. A zero * value indicates CPU dirty logging is unsupported or disabled. diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 0f3b59da0d4a..6d9763dc4fed 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1539,11 +1539,14 @@ static void svm_prepare_host_switch(struct kvm_vcpu *vcpu) to_svm(vcpu)->guest_state_loaded = false; } -static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu, bool sched_in) { struct vcpu_svm *svm = to_svm(vcpu); struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu); + if (sched_in && !kvm_pause_in_guest(vcpu->kvm)) + shrink_ple_window(vcpu); + if (sd->current_vmcb != svm->vmcb) { sd->current_vmcb = svm->vmcb; @@ -4548,12 +4551,6 @@ static void svm_handle_exit_irqoff(struct kvm_vcpu *vcpu) vcpu->arch.at_instruction_boundary = true; } -static void svm_sched_in(struct kvm_vcpu *vcpu, int cpu) -{ - if (!kvm_pause_in_guest(vcpu->kvm)) - shrink_ple_window(vcpu); -} - static void svm_setup_mce(struct kvm_vcpu *vcpu) { /* [63:9] are reserved. */ @@ -5013,8 +5010,6 @@ static struct kvm_x86_ops svm_x86_ops __initdata = { .check_intercept = svm_check_intercept, .handle_exit_irqoff = svm_handle_exit_irqoff, - .sched_in = svm_sched_in, - .nested_ops = &svm_nested_ops, .deliver_interrupt = svm_deliver_interrupt, diff --git a/arch/x86/kvm/vmx/main.c b/arch/x86/kvm/vmx/main.c index 7c546ad3e4c9..4fee9a8cc5a1 100644 --- a/arch/x86/kvm/vmx/main.c +++ b/arch/x86/kvm/vmx/main.c @@ -121,8 +121,6 @@ struct kvm_x86_ops vt_x86_ops __initdata = { .check_intercept = vmx_check_intercept, .handle_exit_irqoff = vmx_handle_exit_irqoff, - .sched_in = vmx_sched_in, - .cpu_dirty_log_size = PML_ENTITY_NUM, .update_cpu_dirty_logging = vmx_update_cpu_dirty_logging, diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index cb36db7b6140..ccea594187c7 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -1505,10 +1505,13 @@ void vmx_vcpu_load_vmcs(struct kvm_vcpu *vcpu, int cpu, * Switches to specified vcpu, until a matching vcpu_put(), but assumes * vcpu mutex is already taken. */ -void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu, bool sched_in) { struct vcpu_vmx *vmx = to_vmx(vcpu); + if (sched_in && !kvm_pause_in_guest(vcpu->kvm)) + shrink_ple_window(vcpu); + vmx_vcpu_load_vmcs(vcpu, cpu, NULL); vmx_vcpu_pi_load(vcpu, cpu); @@ -8093,12 +8096,6 @@ void vmx_cancel_hv_timer(struct kvm_vcpu *vcpu) } #endif -void vmx_sched_in(struct kvm_vcpu *vcpu, int cpu) -{ - if (!kvm_pause_in_guest(vcpu->kvm)
[PATCH 2/4] KVM: VMX: Move PLE grow/shrink helpers above vmx_vcpu_load()
Move VMX's {grow,shrink}_ple_window() above vmx_vcpu_load() in preparation of moving the sched_in logic, which handles shrinking the PLE window, into vmx_vcpu_load(). No functional change intended. Signed-off-by: Sean Christopherson --- arch/x86/kvm/vmx/vmx.c | 64 +- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 6780313914f8..cb36db7b6140 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -1402,6 +1402,38 @@ static void vmx_write_guest_kernel_gs_base(struct vcpu_vmx *vmx, u64 data) } #endif +static void grow_ple_window(struct kvm_vcpu *vcpu) +{ + struct vcpu_vmx *vmx = to_vmx(vcpu); + unsigned int old = vmx->ple_window; + + vmx->ple_window = __grow_ple_window(old, ple_window, + ple_window_grow, + ple_window_max); + + if (vmx->ple_window != old) { + vmx->ple_window_dirty = true; + trace_kvm_ple_window_update(vcpu->vcpu_id, + vmx->ple_window, old); + } +} + +static void shrink_ple_window(struct kvm_vcpu *vcpu) +{ + struct vcpu_vmx *vmx = to_vmx(vcpu); + unsigned int old = vmx->ple_window; + + vmx->ple_window = __shrink_ple_window(old, ple_window, + ple_window_shrink, + ple_window); + + if (vmx->ple_window != old) { + vmx->ple_window_dirty = true; + trace_kvm_ple_window_update(vcpu->vcpu_id, + vmx->ple_window, old); + } +} + void vmx_vcpu_load_vmcs(struct kvm_vcpu *vcpu, int cpu, struct loaded_vmcs *buddy) { @@ -5871,38 +5903,6 @@ int vmx_vcpu_pre_run(struct kvm_vcpu *vcpu) return 1; } -static void grow_ple_window(struct kvm_vcpu *vcpu) -{ - struct vcpu_vmx *vmx = to_vmx(vcpu); - unsigned int old = vmx->ple_window; - - vmx->ple_window = __grow_ple_window(old, ple_window, - ple_window_grow, - ple_window_max); - - if (vmx->ple_window != old) { - vmx->ple_window_dirty = true; - trace_kvm_ple_window_update(vcpu->vcpu_id, - vmx->ple_window, old); - } -} - -static void shrink_ple_window(struct kvm_vcpu *vcpu) -{ - struct vcpu_vmx *vmx = to_vmx(vcpu); - unsigned int old = vmx->ple_window; - - vmx->ple_window = __shrink_ple_window(old, ple_window, - ple_window_shrink, - ple_window); - - if (vmx->ple_window != old) { - vmx->ple_window_dirty = true; - trace_kvm_ple_window_update(vcpu->vcpu_id, - vmx->ple_window, old); - } -} - /* * Indicate a busy-waiting vcpu in spinlock. We do not enable the PAUSE * exiting, so only get here on cpu with PAUSE-Loop-Exiting. -- 2.45.0.rc0.197.gbae5840b3b-goog
[PATCH 1/4] KVM: Plumb in a @sched_in flag to kvm_arch_vcpu_load()
Add a @sched_in flag to kvm_arch_vcpu_load() to note that the vCPU is being (re)loaded by kvm_sched_in(), i.e. after the vCPU was previously scheduled out. KVM x86 currently uses a dedicated kvm_arch_sched_in() hook, but that's unnecessarily brittle as the behavior of the arch hook heavily depends on the arbitrary order of the two arch calls. A separate hook also makes it unnecessarily difficult to do something unique when re-loading vCPU during kvm_sched_in(), e.g. to optimize vCPU loading if KVM knows that some CPU state couldn't have changed while the vCPU was scheduled out. Signed-off-by: Sean Christopherson --- arch/arm64/kvm/arm.c| 2 +- arch/arm64/kvm/emulate-nested.c | 4 ++-- arch/arm64/kvm/reset.c | 2 +- arch/loongarch/kvm/vcpu.c | 2 +- arch/mips/kvm/mmu.c | 2 +- arch/powerpc/kvm/powerpc.c | 2 +- arch/riscv/kvm/vcpu.c | 4 ++-- arch/s390/kvm/kvm-s390.c| 2 +- arch/x86/kvm/x86.c | 2 +- include/linux/kvm_host.h| 2 +- virt/kvm/kvm_main.c | 4 ++-- 11 files changed, 14 insertions(+), 14 deletions(-) diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index c4a0a35e02c7..30ea103bfacb 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -428,7 +428,7 @@ void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) } -void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu, bool sched_in) { struct kvm_s2_mmu *mmu; int *last_ran; diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c index 4697ba41b3a9..ad5458c47e5e 100644 --- a/arch/arm64/kvm/emulate-nested.c +++ b/arch/arm64/kvm/emulate-nested.c @@ -2193,7 +2193,7 @@ void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu) *vcpu_pc(vcpu) = elr; *vcpu_cpsr(vcpu) = spsr; - kvm_arch_vcpu_load(vcpu, smp_processor_id()); + kvm_arch_vcpu_load(vcpu, smp_processor_id(), false); preempt_enable(); } @@ -2274,7 +2274,7 @@ static int kvm_inject_nested(struct kvm_vcpu *vcpu, u64 esr_el2, */ __kvm_adjust_pc(vcpu); - kvm_arch_vcpu_load(vcpu, smp_processor_id()); + kvm_arch_vcpu_load(vcpu, smp_processor_id(), false); preempt_enable(); return 1; diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c index 68d1d05672bd..654cf09c81e9 100644 --- a/arch/arm64/kvm/reset.c +++ b/arch/arm64/kvm/reset.c @@ -262,7 +262,7 @@ void kvm_reset_vcpu(struct kvm_vcpu *vcpu) kvm_timer_vcpu_reset(vcpu); if (loaded) - kvm_arch_vcpu_load(vcpu, smp_processor_id()); + kvm_arch_vcpu_load(vcpu, smp_processor_id(), false); preempt_enable(); } diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c index 3a8779065f73..61d549c4f8d1 100644 --- a/arch/loongarch/kvm/vcpu.c +++ b/arch/loongarch/kvm/vcpu.c @@ -1050,7 +1050,7 @@ static int _kvm_vcpu_load(struct kvm_vcpu *vcpu, int cpu) return 0; } -void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu, bool sched_in) { unsigned long flags; diff --git a/arch/mips/kvm/mmu.c b/arch/mips/kvm/mmu.c index c17157e700c0..6797799f3f32 100644 --- a/arch/mips/kvm/mmu.c +++ b/arch/mips/kvm/mmu.c @@ -682,7 +682,7 @@ static void kvm_mips_migrate_count(struct kvm_vcpu *vcpu) } /* Restore ASID once we are scheduled back after preemption */ -void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu, bool sched_in) { unsigned long flags; diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index d32abe7fe6ab..8de620716875 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -826,7 +826,7 @@ int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) return kvmppc_core_pending_dec(vcpu); } -void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu, bool sched_in) { #ifdef CONFIG_BOOKE /* diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c index b5ca9f2e98ac..a7b7f172fa61 100644 --- a/arch/riscv/kvm/vcpu.c +++ b/arch/riscv/kvm/vcpu.c @@ -87,7 +87,7 @@ static void kvm_riscv_reset_vcpu(struct kvm_vcpu *vcpu) /* Reset the guest CSRs for hotplug usecase */ if (loaded) - kvm_arch_vcpu_load(vcpu, smp_processor_id()); + kvm_arch_vcpu_load(vcpu, smp_processor_id(), false); put_cpu(); } @@ -507,7 +507,7 @@ static void kvm_riscv_vcpu_setup_config(struct kvm_vcpu *vcpu) } } -void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu, bool sched_in) { struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr; struct kvm_vcpu_config *cfg = &vcpu->arch.cfg; diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 5147
[PATCH 0/4] KVM: Fold kvm_arch_sched_in() into kvm_arch_vcpu_load()
Drop kvm_arch_sched_in() and instead pass a @sched_in boolean to kvm_arch_vcpu_load(). While fiddling with an idea for optimizing state management on AMD CPUs, I wanted to skip re-saving certain host state when a vCPU is scheduled back in, as the state (theoretically) shouldn't change for the task while it's scheduled out. Actually doing that was annoying and unnecessarily brittle due to having a separate API for the kvm_sched_in() case (the state save needed to be in kvm_arch_vcpu_load() for the common path). E.g. I could have set a "temporary"-ish flag somewhere in kvm_vcpu, but (a) that's gross and (b) it would rely on the arbitrary ordering between sched_in() and vcpu_load() staying the same. The only real downside I see is that arm64 and riscv end up having to pass "false" for their direct usage of kvm_arch_vcpu_load(), and passing boolean literals isn't ideal. But that can be solved by adding an inner helper that omits the @sched_in param (I almost added a patch to do that, but I couldn't convince myself it was necessary). The other motivation for this is to avoid yet another arch hook, and more arbitrary ordering, if there's a future need to hook kvm_sched_out() (we've come close on the x86 side several times). Sean Christopherson (4): KVM: Plumb in a @sched_in flag to kvm_arch_vcpu_load() KVM: VMX: Move PLE grow/shrink helpers above vmx_vcpu_load() KVM: x86: Fold kvm_arch_sched_in() into kvm_arch_vcpu_load() KVM: Delete the now unused kvm_arch_sched_in() arch/arm64/include/asm/kvm_host.h | 1 - arch/arm64/kvm/arm.c | 2 +- arch/arm64/kvm/emulate-nested.c | 4 +- arch/arm64/kvm/reset.c| 2 +- arch/loongarch/include/asm/kvm_host.h | 1 - arch/loongarch/kvm/vcpu.c | 2 +- arch/mips/include/asm/kvm_host.h | 1 - arch/mips/kvm/mmu.c | 2 +- arch/powerpc/include/asm/kvm_host.h | 1 - arch/powerpc/kvm/powerpc.c| 2 +- arch/riscv/include/asm/kvm_host.h | 1 - arch/riscv/kvm/vcpu.c | 4 +- arch/s390/include/asm/kvm_host.h | 1 - arch/s390/kvm/kvm-s390.c | 2 +- arch/x86/include/asm/kvm-x86-ops.h| 1 - arch/x86/include/asm/kvm_host.h | 4 +- arch/x86/kvm/pmu.c| 6 +-- arch/x86/kvm/svm/svm.c| 13 ++--- arch/x86/kvm/vmx/main.c | 2 - arch/x86/kvm/vmx/vmx.c| 75 +-- arch/x86/kvm/vmx/x86_ops.h| 3 +- arch/x86/kvm/x86.c| 26 +- include/linux/kvm_host.h | 4 +- virt/kvm/kvm_main.c | 5 +- 24 files changed, 70 insertions(+), 95 deletions(-) base-commit: a96cb3bf390eebfead5fc7a2092f8452a7997d1b -- 2.45.0.rc0.197.gbae5840b3b-goog
Re: [PATCH v15 00/16] Add audio support in v4l2 framework
Em Tue, 30 Apr 2024 23:46:03 +0900 Mark Brown escreveu: > On Tue, Apr 30, 2024 at 10:21:12AM +0200, Sebastian Fricke wrote: > > > first of all thanks for all of this work and I am very sorry for only > > emerging this late into the series, I sadly didn't notice it earlier. > > It might be worth checking out the discussion on earlier versions... > > > 1. The biggest objection is, that the Linux Kernel has a subsystem > > specifically targeted for audio devices, adding support for these > > devices in another subsystem are counterproductive as they work around > > the shortcomings of the audio subsystem while forcing support for a > > device into a subsystem that was never designed for such devices. > > Instead, the audio subsystem has to be adjusted to be able to support > > all of the required workflows, otherwise, the next audio driver with > > similar requirements will have to move to the media subsystem as well, > > the audio subsystem would then never experience the required change and > > soon we would have two audio subsystems. > > The discussion around this originally was that all the audio APIs are > very much centered around real time operations rather than completely > async memory to memory operations and that it's not clear that it's > worth reinventing the wheel simply for the sake of having things in > ALSA when that's already pretty idiomatic for the media subsystem. It > wasn't the memory to memory bit per se, it was the disconnection from > any timing. The media subsystem is also centered around real time. Without real time, you can't have a decent video conference system. Having mem2mem transfers actually help reducing real time delays, as it avoids extra latency due to CPU congestion and/or data transfers from/to userspace. > > > So instead of hammering a driver into the wrong destination, I would > > suggest bundling our forces and implementing a general memory-to-memory > > framework that both the media and the audio subsystem can use, that > > addresses the current shortcomings of the implementation and allows you > > to upload the driver where it is supposed to be. > > That doesn't sound like an immediate solution to maintainer overload > issues... if something like this is going to happen the DRM solution > does seem more general but I'm not sure the amount of stop energy is > proportionate. I don't think maintainer overload is the issue here. The main point is to avoid a fork at the audio uAPI, plus the burden of re-inventing the wheel with new codes for audio formats, new documentation for them, etc. Regards, Mauro
Re: [PATCH v15 00/16] Add audio support in v4l2 framework
On 30. 04. 24 16:46, Mark Brown wrote: So instead of hammering a driver into the wrong destination, I would suggest bundling our forces and implementing a general memory-to-memory framework that both the media and the audio subsystem can use, that addresses the current shortcomings of the implementation and allows you to upload the driver where it is supposed to be. That doesn't sound like an immediate solution to maintainer overload issues... if something like this is going to happen the DRM solution does seem more general but I'm not sure the amount of stop energy is proportionate. The "do what you want" ALSA's hwdep device / interface can be used to transfer data in/out from SRC using custom read/write/ioctl/mmap syscalls. The question is, if the changes cannot be more simpler for the first implementation keeping the hardware enumeration in one subsystem where is the driver code placed. I also see the benefit to reuse the already existing framework (but is v4l2 the right one?). Jaroslav -- Jaroslav Kysela Linux Sound Maintainer; ALSA Project; Red Hat, Inc.
Re: [PATCH v15 00/16] Add audio support in v4l2 framework
On Tue, Apr 30, 2024 at 10:21:12AM +0200, Sebastian Fricke wrote: > first of all thanks for all of this work and I am very sorry for only > emerging this late into the series, I sadly didn't notice it earlier. It might be worth checking out the discussion on earlier versions... > 1. The biggest objection is, that the Linux Kernel has a subsystem > specifically targeted for audio devices, adding support for these > devices in another subsystem are counterproductive as they work around > the shortcomings of the audio subsystem while forcing support for a > device into a subsystem that was never designed for such devices. > Instead, the audio subsystem has to be adjusted to be able to support > all of the required workflows, otherwise, the next audio driver with > similar requirements will have to move to the media subsystem as well, > the audio subsystem would then never experience the required change and > soon we would have two audio subsystems. The discussion around this originally was that all the audio APIs are very much centered around real time operations rather than completely async memory to memory operations and that it's not clear that it's worth reinventing the wheel simply for the sake of having things in ALSA when that's already pretty idiomatic for the media subsystem. It wasn't the memory to memory bit per se, it was the disconnection from any timing. > So instead of hammering a driver into the wrong destination, I would > suggest bundling our forces and implementing a general memory-to-memory > framework that both the media and the audio subsystem can use, that > addresses the current shortcomings of the implementation and allows you > to upload the driver where it is supposed to be. That doesn't sound like an immediate solution to maintainer overload issues... if something like this is going to happen the DRM solution does seem more general but I'm not sure the amount of stop energy is proportionate. signature.asc Description: PGP signature
[PATCH] powerpc: Set _IO_BASE to POISON_POINTER_DELTA not 0 for CONFIG_PCI=n
With -Wextra clang warns about pointer arithmetic using a null pointer. When building with CONFIG_PCI=n, that triggers a warning in the IO accessors, eg: In file included from linux/arch/powerpc/include/asm/io.h:672: linux/arch/powerpc/include/asm/io-defs.h:23:1: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] 23 | DEF_PCI_AC_RET(inb, u8, (unsigned long port), (port), pio, port) | ^~~~ ... linux/arch/powerpc/include/asm/io.h:591:53: note: expanded from macro '__do_inb' 591 | #define __do_inb(port) readb((PCI_IO_ADDR)_IO_BASE + port); | ~ ^ That is because when CONFIG_PCI=n, _IO_BASE is defined as 0. There is code that builds with calls to IO accessors even when CONFIG_PCI=n, but the actual calls are guarded by runtime checks. If not those calls would be faulting, because the page at virtual address zero is (usually) not mapped into the kernel. As Arnd pointed out, it is possible a large port value could cause the address to be above mmap_min_addr which would then access userspace, which would be a bug. To avoid any such issues, and also fix the compiler warning, set the _IO_BASE to POISON_POINTER_DELTA. That is a value chosen to point into unmapped space between the kernel and userspace, so any access will always fault. Reported-by: Naresh Kamboju Closes: https://lore.kernel.org/all/CA+G9fYtEh8zmq8k8wE-8RZwW-Qr927RLTn+KqGnq1F=ptaa...@mail.gmail.com Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/io.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h index 08c550ed49be..1cd6eb6c8101 100644 --- a/arch/powerpc/include/asm/io.h +++ b/arch/powerpc/include/asm/io.h @@ -37,7 +37,7 @@ extern struct pci_dev *isa_bridge_pcidev; * define properly based on the platform */ #ifndef CONFIG_PCI -#define _IO_BASE 0 +#define _IO_BASE POISON_POINTER_DELTA #define _ISA_MEM_BASE 0 #define PCI_DRAM_OFFSET 0 #elif defined(CONFIG_PPC32) -- 2.44.0
[PATCH 13/13] ASoC: sunxi: Use snd_soc_substream_to_rtd() for accessing private_data
Do not open-code snd_soc_substream_to_rtd(). Signed-off-by: Krzysztof Kozlowski --- sound/soc/sunxi/sun50i-dmic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/sunxi/sun50i-dmic.c b/sound/soc/sunxi/sun50i-dmic.c index c76628bc86c6..fedfa4fc95fb 100644 --- a/sound/soc/sunxi/sun50i-dmic.c +++ b/sound/soc/sunxi/sun50i-dmic.c @@ -74,7 +74,7 @@ static const struct dmic_rate dmic_rate_s[] = { static int sun50i_dmic_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct sun50i_dmic_dev *host = snd_soc_dai_get_drvdata(snd_soc_rtd_to_cpu(rtd, 0)); /* only support capture */ -- 2.43.0
[PATCH 12/13] ASoC: samsung: Use snd_soc_substream_to_rtd() for accessing private_data
Do not open-code snd_soc_substream_to_rtd(). Signed-off-by: Krzysztof Kozlowski --- sound/soc/samsung/midas_wm1811.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/samsung/midas_wm1811.c b/sound/soc/samsung/midas_wm1811.c index f31244156ff6..0841e2e6f8ce 100644 --- a/sound/soc/samsung/midas_wm1811.c +++ b/sound/soc/samsung/midas_wm1811.c @@ -127,7 +127,7 @@ static int midas_stop_fll1(struct snd_soc_pcm_runtime *rtd) static int midas_aif1_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); unsigned int pll_out; /* AIF1CLK should be at least 3MHz for "optimal performance" */ -- 2.43.0
[PATCH 11/13] ASoC: meson: Use snd_soc_substream_to_rtd() for accessing private_data
Do not open-code snd_soc_substream_to_rtd(). Signed-off-by: Krzysztof Kozlowski --- sound/soc/meson/aiu-fifo.c | 2 +- sound/soc/meson/axg-fifo.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/meson/aiu-fifo.c b/sound/soc/meson/aiu-fifo.c index 4041ff8e437f..b222bde1f61b 100644 --- a/sound/soc/meson/aiu-fifo.c +++ b/sound/soc/meson/aiu-fifo.c @@ -25,7 +25,7 @@ static struct snd_soc_dai *aiu_fifo_dai(struct snd_pcm_substream *ss) { - struct snd_soc_pcm_runtime *rtd = ss->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(ss); return snd_soc_rtd_to_cpu(rtd, 0); } diff --git a/sound/soc/meson/axg-fifo.c b/sound/soc/meson/axg-fifo.c index bebee0ca8e38..1ead5ebc84c4 100644 --- a/sound/soc/meson/axg-fifo.c +++ b/sound/soc/meson/axg-fifo.c @@ -46,7 +46,7 @@ static struct snd_pcm_hardware axg_fifo_hw = { static struct snd_soc_dai *axg_fifo_dai(struct snd_pcm_substream *ss) { - struct snd_soc_pcm_runtime *rtd = ss->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(ss); return snd_soc_rtd_to_cpu(rtd, 0); } -- 2.43.0
[PATCH 10/13] ASoC: mediatek: Use snd_soc_substream_to_rtd() for accessing private_data
Do not open-code snd_soc_substream_to_rtd(). Signed-off-by: Krzysztof Kozlowski --- sound/soc/mediatek/mt7986/mt7986-afe-pcm.c | 4 ++-- sound/soc/mediatek/mt8186/mt8186-afe-pcm.c | 14 +++--- sound/soc/mediatek/mt8186/mt8186-mt6366.c | 2 +- sound/soc/mediatek/mt8188/mt8188-afe-pcm.c | 8 sound/soc/mediatek/mt8188/mt8188-mt6359.c | 6 +++--- sound/soc/mediatek/mt8195/mt8195-afe-pcm.c | 10 +- sound/soc/mediatek/mt8195/mt8195-mt6359.c | 4 ++-- 7 files changed, 24 insertions(+), 24 deletions(-) diff --git a/sound/soc/mediatek/mt7986/mt7986-afe-pcm.c b/sound/soc/mediatek/mt7986/mt7986-afe-pcm.c index c1c486e275b9..572ded279b53 100644 --- a/sound/soc/mediatek/mt7986/mt7986-afe-pcm.c +++ b/sound/soc/mediatek/mt7986/mt7986-afe-pcm.c @@ -106,7 +106,7 @@ static const struct snd_pcm_hardware mt7986_afe_hardware = { static int mt7986_memif_fs(struct snd_pcm_substream *substream, unsigned int rate) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); @@ -116,7 +116,7 @@ static int mt7986_memif_fs(struct snd_pcm_substream *substream, static int mt7986_irq_fs(struct snd_pcm_substream *substream, unsigned int rate) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-pcm.c b/sound/soc/mediatek/mt8186/mt8186-afe-pcm.c index bfcfc68ac64d..bafbef96a42d 100644 --- a/sound/soc/mediatek/mt8186/mt8186-afe-pcm.c +++ b/sound/soc/mediatek/mt8186/mt8186-afe-pcm.c @@ -40,7 +40,7 @@ static const struct snd_pcm_hardware mt8186_afe_hardware = { static int mt8186_fe_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); struct snd_pcm_runtime *runtime = substream->runtime; int id = snd_soc_rtd_to_cpu(rtd, 0)->id; @@ -82,7 +82,7 @@ static int mt8186_fe_startup(struct snd_pcm_substream *substream, static void mt8186_fe_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); struct mt8186_afe_private *afe_priv = afe->platform_priv; int id = snd_soc_rtd_to_cpu(rtd, 0)->id; @@ -104,7 +104,7 @@ static int mt8186_fe_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); int id = snd_soc_rtd_to_cpu(rtd, 0)->id; unsigned int channels = params_channels(params); @@ -153,7 +153,7 @@ static int mt8186_fe_hw_free(struct snd_pcm_substream *substream, static int mt8186_fe_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_pcm_runtime * const runtime = substream->runtime; struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); struct mt8186_afe_private *afe_priv = afe->platform_priv; @@ -252,7 +252,7 @@ static int mt8186_fe_trigger(struct snd_pcm_substream *substream, int cmd, static int mt8186_memif_fs(struct snd_pcm_substream *substream, unsigned int rate) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); @@ -269,7 +269,7 @@ static int mt8186_get_dai_fs(struct mtk_base_afe *afe, static int mt8186_irq_fs(struct snd_pcm_substream *substream, unsigned int rate) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *r
[PATCH 09/13] ASoC: loongson: Use snd_soc_substream_to_rtd() for accessing private_data
Do not open-code snd_soc_substream_to_rtd(). Signed-off-by: Krzysztof Kozlowski --- sound/soc/loongson/loongson_card.c | 2 +- sound/soc/loongson/loongson_dma.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/loongson/loongson_card.c b/sound/soc/loongson/loongson_card.c index e8432d466f60..fae5e9312bf0 100644 --- a/sound/soc/loongson/loongson_card.c +++ b/sound/soc/loongson/loongson_card.c @@ -23,7 +23,7 @@ struct loongson_card_data { static int loongson_card_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct loongson_card_data *ls_card = snd_soc_card_get_drvdata(rtd->card); diff --git a/sound/soc/loongson/loongson_dma.c b/sound/soc/loongson/loongson_dma.c index 8090662e8ff2..4fcc2868160b 100644 --- a/sound/soc/loongson/loongson_dma.c +++ b/sound/soc/loongson/loongson_dma.c @@ -226,7 +226,7 @@ static int loongson_pcm_open(struct snd_soc_component *component, struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_card *card = substream->pcm->card; struct loongson_runtime_data *prtd; struct loongson_dma_data *dma_data; -- 2.43.0
[PATCH 08/13] ASoC: kirkwood: Use snd_soc_substream_to_rtd() for accessing private_data
Do not open-code snd_soc_substream_to_rtd(). Signed-off-by: Krzysztof Kozlowski --- sound/soc/kirkwood/kirkwood-dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c index ef00792e1d49..036b42058272 100644 --- a/sound/soc/kirkwood/kirkwood-dma.c +++ b/sound/soc/kirkwood/kirkwood-dma.c @@ -19,7 +19,7 @@ static struct kirkwood_dma_data *kirkwood_priv(struct snd_pcm_substream *subs) { - struct snd_soc_pcm_runtime *soc_runtime = subs->private_data; + struct snd_soc_pcm_runtime *soc_runtime = snd_soc_substream_to_rtd(subs); return snd_soc_dai_get_drvdata(snd_soc_rtd_to_cpu(soc_runtime, 0)); } -- 2.43.0
[PATCH 07/13] ASoC: img: Use snd_soc_substream_to_rtd() for accessing private_data
Do not open-code snd_soc_substream_to_rtd(). Signed-off-by: Krzysztof Kozlowski --- sound/soc/img/img-i2s-in.c | 2 +- sound/soc/img/img-i2s-out.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/img/img-i2s-in.c b/sound/soc/img/img-i2s-in.c index dacc29fcf24b..b69a364d619e 100644 --- a/sound/soc/img/img-i2s-in.c +++ b/sound/soc/img/img-i2s-in.c @@ -395,7 +395,7 @@ static int img_i2s_in_dma_prepare_slave_config(struct snd_pcm_substream *st, struct snd_pcm_hw_params *params, struct dma_slave_config *sc) { unsigned int i2s_channels = params_channels(params) / 2; - struct snd_soc_pcm_runtime *rtd = st->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(st); struct snd_dmaengine_dai_dma_data *dma_data; int ret; diff --git a/sound/soc/img/img-i2s-out.c b/sound/soc/img/img-i2s-out.c index f442d985ab87..6f9831c6d6e0 100644 --- a/sound/soc/img/img-i2s-out.c +++ b/sound/soc/img/img-i2s-out.c @@ -401,7 +401,7 @@ static int img_i2s_out_dma_prepare_slave_config(struct snd_pcm_substream *st, struct snd_pcm_hw_params *params, struct dma_slave_config *sc) { unsigned int i2s_channels = params_channels(params) / 2; - struct snd_soc_pcm_runtime *rtd = st->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(st); struct snd_dmaengine_dai_dma_data *dma_data; int ret; -- 2.43.0
[PATCH 06/13] ASoC: fsl: Use snd_soc_substream_to_rtd() for accessing private_data
Do not open-code snd_soc_substream_to_rtd(). Signed-off-by: Krzysztof Kozlowski --- sound/soc/fsl/fsl-asoc-card.c | 2 +- sound/soc/fsl/imx-card.c | 6 +++--- sound/soc/fsl/imx-hdmi.c | 2 +- sound/soc/fsl/imx-pcm-rpmsg.c | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c index f6d2564864c6..5ddc0c2fe53f 100644 --- a/sound/soc/fsl/fsl-asoc-card.c +++ b/sound/soc/fsl/fsl-asoc-card.c @@ -242,7 +242,7 @@ static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream, static int fsl_asoc_card_hw_free(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); struct codec_priv *codec_priv = &priv->codec_priv; struct device *dev = rtd->card->dev; diff --git a/sound/soc/fsl/imx-card.c b/sound/soc/fsl/imx-card.c index cb8723965f2f..0e18ccabe28c 100644 --- a/sound/soc/fsl/imx-card.c +++ b/sound/soc/fsl/imx-card.c @@ -252,7 +252,7 @@ static unsigned long akcodec_get_mclk_rate(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, int slots, int slot_width) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct imx_card_data *data = snd_soc_card_get_drvdata(rtd->card); const struct imx_card_plat_data *plat_data = data->plat_data; struct dai_link_data *link_data = &data->link_data[rtd->num]; @@ -289,7 +289,7 @@ static unsigned long akcodec_get_mclk_rate(struct snd_pcm_substream *substream, static int imx_aif_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); struct snd_soc_card *card = rtd->card; struct imx_card_data *data = snd_soc_card_get_drvdata(card); @@ -405,7 +405,7 @@ static int ak5558_hw_rule_rate(struct snd_pcm_hw_params *p, struct snd_pcm_hw_ru static int imx_aif_startup(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_card *card = rtd->card; struct imx_card_data *data = snd_soc_card_get_drvdata(card); struct dai_link_data *link_data = &data->link_data[rtd->num]; diff --git a/sound/soc/fsl/imx-hdmi.c b/sound/soc/fsl/imx-hdmi.c index e454085c6e5c..fe47b439a818 100644 --- a/sound/soc/fsl/imx-hdmi.c +++ b/sound/soc/fsl/imx-hdmi.c @@ -32,7 +32,7 @@ struct imx_hdmi_data { static int imx_hdmi_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct imx_hdmi_data *data = snd_soc_card_get_drvdata(rtd->card); bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); diff --git a/sound/soc/fsl/imx-pcm-rpmsg.c b/sound/soc/fsl/imx-pcm-rpmsg.c index b84d1dfddba2..ba491cbb9930 100644 --- a/sound/soc/fsl/imx-pcm-rpmsg.c +++ b/sound/soc/fsl/imx-pcm-rpmsg.c @@ -316,7 +316,7 @@ static int imx_rpmsg_pcm_prepare(struct snd_soc_component *component, struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); struct fsl_rpmsg *rpmsg = dev_get_drvdata(cpu_dai->dev); @@ -461,7 +461,7 @@ static int imx_rpmsg_pcm_trigger(struct snd_soc_component *component, struct snd_pcm_substream *substream, int cmd) { struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); struct fsl_rpmsg *rpmsg = dev_get_drvdata(cpu_dai->dev); int ret = 0; @@ -515,7 +515,7 @@ static int imx_rpmsg_pcm_ack(struct snd_soc_component *component, struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runti
[PATCH 05/13] ASoC: amd: Use snd_soc_substream_to_rtd() for accessing private_data
Do not open-code snd_soc_substream_to_rtd(). Signed-off-by: Krzysztof Kozlowski --- sound/soc/amd/acp/acp-mach-common.c | 2 +- sound/soc/amd/acp3x-rt5682-max9836.c | 2 +- sound/soc/amd/ps/ps-sdw-dma.c| 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/amd/acp/acp-mach-common.c b/sound/soc/amd/acp/acp-mach-common.c index 665a6ea0a2a8..a36300a4ed8a 100644 --- a/sound/soc/amd/acp/acp-mach-common.c +++ b/sound/soc/amd/acp/acp-mach-common.c @@ -217,7 +217,7 @@ static void acp_card_shutdown(struct snd_pcm_substream *substream) static int acp_card_rt5682_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_card *card = rtd->card; struct acp_card_drvdata *drvdata = card->drvdata; struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); diff --git a/sound/soc/amd/acp3x-rt5682-max9836.c b/sound/soc/amd/acp3x-rt5682-max9836.c index d6cdb6d9fdd6..357dfd016baf 100644 --- a/sound/soc/amd/acp3x-rt5682-max9836.c +++ b/sound/soc/amd/acp3x-rt5682-max9836.c @@ -143,7 +143,7 @@ static int rt5682_clk_enable(struct snd_pcm_substream *substream) static int acp3x_1015_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; int srate, i, ret; diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c index 66b800962f8c..2f630753278d 100644 --- a/sound/soc/amd/ps/ps-sdw-dma.c +++ b/sound/soc/amd/ps/ps-sdw-dma.c @@ -218,7 +218,7 @@ static int acp63_sdw_dma_open(struct snd_soc_component *component, struct acp_sdw_dma_stream *stream; struct snd_soc_dai *cpu_dai; struct amd_sdw_manager *amd_manager; - struct snd_soc_pcm_runtime *prtd = substream->private_data; + struct snd_soc_pcm_runtime *prtd = snd_soc_substream_to_rtd(substream); int ret; runtime = substream->runtime; -- 2.43.0
[PATCH 04/13] ASoC: arm: Use snd_soc_substream_to_rtd() for accessing private_data
Do not open-code snd_soc_substream_to_rtd(). Signed-off-by: Krzysztof Kozlowski --- sound/arm/pxa2xx-pcm-lib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/arm/pxa2xx-pcm-lib.c b/sound/arm/pxa2xx-pcm-lib.c index 51d2ff80df16..571e9d909cdf 100644 --- a/sound/arm/pxa2xx-pcm-lib.c +++ b/sound/arm/pxa2xx-pcm-lib.c @@ -33,7 +33,7 @@ int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream); - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_dmaengine_dai_dma_data *dma_params; struct dma_slave_config config; int ret; @@ -79,7 +79,7 @@ EXPORT_SYMBOL(pxa2xx_pcm_prepare); int pxa2xx_pcm_open(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_pcm_runtime *runtime = substream->runtime; struct snd_dmaengine_dai_dma_data *dma_params; int ret; -- 2.43.0
[PATCH 03/13] ASoC: ti: Use snd_soc_substream_to_rtd() for accessing private_data
Do not open-code snd_soc_substream_to_rtd(). Signed-off-by: Krzysztof Kozlowski --- sound/soc/ti/omap-hdmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/ti/omap-hdmi.c b/sound/soc/ti/omap-hdmi.c index 4513b527ab97..639bc83f4263 100644 --- a/sound/soc/ti/omap-hdmi.c +++ b/sound/soc/ti/omap-hdmi.c @@ -40,7 +40,7 @@ struct hdmi_audio_data { static struct hdmi_audio_data *card_drvdata_substream(struct snd_pcm_substream *ss) { - struct snd_soc_pcm_runtime *rtd = ss->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(ss); return snd_soc_card_get_drvdata(rtd->card); } -- 2.43.0
[PATCH 01/13] ASoC: qcom: Use snd_soc_substream_to_rtd() for accessing private_data
Do not open-code snd_soc_substream_to_rtd(). Signed-off-by: Krzysztof Kozlowski --- sound/soc/qcom/apq8016_sbc.c | 4 ++-- sound/soc/qcom/qdsp6/q6apm-dai.c | 2 +- sound/soc/qcom/sc7180.c | 10 +- sound/soc/qcom/sc7280.c | 12 ++-- sound/soc/qcom/sc8280xp.c| 8 sound/soc/qcom/sdw.c | 8 sound/soc/qcom/sm8250.c | 10 +- sound/soc/qcom/x1e80100.c| 8 8 files changed, 31 insertions(+), 31 deletions(-) diff --git a/sound/soc/qcom/apq8016_sbc.c b/sound/soc/qcom/apq8016_sbc.c index 4834a56eaa88..3023cf180a75 100644 --- a/sound/soc/qcom/apq8016_sbc.c +++ b/sound/soc/qcom/apq8016_sbc.c @@ -192,7 +192,7 @@ static int msm8916_qdsp6_dai_init(struct snd_soc_pcm_runtime *rtd) static int msm8916_qdsp6_startup(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_card *card = rtd->card; struct apq8016_sbc_data *data = snd_soc_card_get_drvdata(card); struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); @@ -213,7 +213,7 @@ static int msm8916_qdsp6_startup(struct snd_pcm_substream *substream) static void msm8916_qdsp6_shutdown(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_card *card = rtd->card; struct apq8016_sbc_data *data = snd_soc_card_get_drvdata(card); struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c index df19fc3376b7..db2f82e00a49 100644 --- a/sound/soc/qcom/qdsp6/q6apm-dai.c +++ b/sound/soc/qcom/qdsp6/q6apm-dai.c @@ -329,7 +329,7 @@ static int q6apm_dai_open(struct snd_soc_component *component, struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; + struct snd_soc_pcm_runtime *soc_prtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(soc_prtd, 0); struct device *dev = component->dev; struct q6apm_dai_data *pdata; diff --git a/sound/soc/qcom/sc7180.c b/sound/soc/qcom/sc7180.c index 029780d6fe6d..bc030ce29680 100644 --- a/sound/soc/qcom/sc7180.c +++ b/sound/soc/qcom/sc7180.c @@ -200,7 +200,7 @@ static int sc7180_startup_realtek_codec(struct snd_soc_pcm_runtime *rtd) static int sc7180_snd_startup(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_card *card = rtd->card; struct sc7180_snd_data *data = snd_soc_card_get_drvdata(card); struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); @@ -234,7 +234,7 @@ static int sc7180_snd_startup(struct snd_pcm_substream *substream) static int sc7180_qdsp_snd_startup(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_card *card = rtd->card; struct sc7180_snd_data *data = snd_soc_card_get_drvdata(card); struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); @@ -307,7 +307,7 @@ static int dmic_set(struct snd_kcontrol *kcontrol, static void sc7180_snd_shutdown(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_card *card = rtd->card; struct sc7180_snd_data *data = snd_soc_card_get_drvdata(card); struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); @@ -334,7 +334,7 @@ static void sc7180_snd_shutdown(struct snd_pcm_substream *substream) static void sc7180_qdsp_snd_shutdown(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_card *card = rtd->card; struct sc7180_snd_data *data = snd_soc_card_get_drvdata(card); struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); @@ -389,7 +389,7 @@ static int sc7180_adau7002_init(struct snd_soc_pcm_runtime *rtd) static int sc7180_adau7002_snd_startup(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd,
[PATCH 00/13] ASoC: Use snd_soc_substream_to_rtd() for accessing private_data
Hi, Do not open-code snd_soc_substream_to_rtd() when accessing snd_pcm_substream->private_data. This makes code more consistent with rest of ASoC and allows in the future to move the field to any other place or add additional checks in snd_soc_substream_to_rtd(). Best regards, Krzysztof --- Krzysztof Kozlowski (13): ASoC: qcom: Use snd_soc_substream_to_rtd() for accessing private_data ASoC: tegra: Use snd_soc_substream_to_rtd() for accessing private_data ASoC: ti: Use snd_soc_substream_to_rtd() for accessing private_data ASoC: arm: Use snd_soc_substream_to_rtd() for accessing private_data ASoC: amd: Use snd_soc_substream_to_rtd() for accessing private_data ASoC: fsl: Use snd_soc_substream_to_rtd() for accessing private_data ASoC: img: Use snd_soc_substream_to_rtd() for accessing private_data ASoC: kirkwood: Use snd_soc_substream_to_rtd() for accessing private_data ASoC: loongson: Use snd_soc_substream_to_rtd() for accessing private_data ASoC: mediatek: Use snd_soc_substream_to_rtd() for accessing private_data ASoC: meson: Use snd_soc_substream_to_rtd() for accessing private_data ASoC: samsung: Use snd_soc_substream_to_rtd() for accessing private_data ASoC: sunxi: Use snd_soc_substream_to_rtd() for accessing private_data sound/arm/pxa2xx-pcm-lib.c | 4 ++-- sound/soc/amd/acp/acp-mach-common.c| 2 +- sound/soc/amd/acp3x-rt5682-max9836.c | 2 +- sound/soc/amd/ps/ps-sdw-dma.c | 2 +- sound/soc/fsl/fsl-asoc-card.c | 2 +- sound/soc/fsl/imx-card.c | 6 +++--- sound/soc/fsl/imx-hdmi.c | 2 +- sound/soc/fsl/imx-pcm-rpmsg.c | 6 +++--- sound/soc/img/img-i2s-in.c | 2 +- sound/soc/img/img-i2s-out.c| 2 +- sound/soc/kirkwood/kirkwood-dma.c | 2 +- sound/soc/loongson/loongson_card.c | 2 +- sound/soc/loongson/loongson_dma.c | 2 +- sound/soc/mediatek/mt7986/mt7986-afe-pcm.c | 4 ++-- sound/soc/mediatek/mt8186/mt8186-afe-pcm.c | 14 +++--- sound/soc/mediatek/mt8186/mt8186-mt6366.c | 2 +- sound/soc/mediatek/mt8188/mt8188-afe-pcm.c | 8 sound/soc/mediatek/mt8188/mt8188-mt6359.c | 6 +++--- sound/soc/mediatek/mt8195/mt8195-afe-pcm.c | 10 +- sound/soc/mediatek/mt8195/mt8195-mt6359.c | 4 ++-- sound/soc/meson/aiu-fifo.c | 2 +- sound/soc/meson/axg-fifo.c | 2 +- sound/soc/qcom/apq8016_sbc.c | 4 ++-- sound/soc/qcom/qdsp6/q6apm-dai.c | 2 +- sound/soc/qcom/sc7180.c| 10 +- sound/soc/qcom/sc7280.c| 12 ++-- sound/soc/qcom/sc8280xp.c | 8 sound/soc/qcom/sdw.c | 8 sound/soc/qcom/sm8250.c| 10 +- sound/soc/qcom/x1e80100.c | 8 sound/soc/samsung/midas_wm1811.c | 2 +- sound/soc/sunxi/sun50i-dmic.c | 2 +- sound/soc/tegra/tegra_asoc_machine.c | 2 +- sound/soc/tegra/tegra_pcm.c| 6 +++--- sound/soc/ti/omap-hdmi.c | 2 +- 35 files changed, 82 insertions(+), 82 deletions(-) --- base-commit: 82415cf72c7e224be7a6496f3a53c0b365c2fe9d change-id: 20240430-asoc-snd-substream-clean-924b717d8f54 Best regards, -- Krzysztof Kozlowski
[PATCH 02/13] ASoC: tegra: Use snd_soc_substream_to_rtd() for accessing private_data
Do not open-code snd_soc_substream_to_rtd(). Signed-off-by: Krzysztof Kozlowski --- sound/soc/tegra/tegra_asoc_machine.c | 2 +- sound/soc/tegra/tegra_pcm.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/tegra/tegra_asoc_machine.c b/sound/soc/tegra/tegra_asoc_machine.c index 192e9692bdf2..775ce433fdbf 100644 --- a/sound/soc/tegra/tegra_asoc_machine.c +++ b/sound/soc/tegra/tegra_asoc_machine.c @@ -290,7 +290,7 @@ static unsigned int tegra_machine_mclk_rate_6mhz(unsigned int srate) static int tegra_machine_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_card *card = rtd->card; struct tegra_machine *machine = snd_soc_card_get_drvdata(card); diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c index 42acb56543db..4bdbcd2635ef 100644 --- a/sound/soc/tegra/tegra_pcm.c +++ b/sound/soc/tegra/tegra_pcm.c @@ -76,7 +76,7 @@ EXPORT_SYMBOL_GPL(tegra_pcm_platform_unregister); int tegra_pcm_open(struct snd_soc_component *component, struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_dmaengine_dai_dma_data *dmap; struct dma_chan *chan; struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); @@ -127,7 +127,7 @@ EXPORT_SYMBOL_GPL(tegra_pcm_open); int tegra_pcm_close(struct snd_soc_component *component, struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); if (rtd->dai_link->no_pcm) return 0; @@ -142,7 +142,7 @@ int tegra_pcm_hw_params(struct snd_soc_component *component, struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_dmaengine_dai_dma_data *dmap; struct dma_slave_config slave_config; struct dma_chan *chan; -- 2.43.0
Re: [PATCH v15 00/16] Add audio support in v4l2 framework
Em Tue, 30 Apr 2024 10:47:13 +0200 Hans Verkuil escreveu: > On 30/04/2024 10:21, Sebastian Fricke wrote: > > Hey Shengjiu, > > > > first of all thanks for all of this work and I am very sorry for only > > emerging this late into the series, I sadly didn't notice it earlier. > > > > I would like to voice a few concerns about the general idea of adding > > Audio support to the Media subsystem. > > > > 1. The biggest objection is, that the Linux Kernel has a subsystem > > specifically targeted for audio devices, adding support for these > > devices in another subsystem are counterproductive as they work around > > the shortcomings of the audio subsystem while forcing support for a > > device into a subsystem that was never designed for such devices. > > Instead, the audio subsystem has to be adjusted to be able to support > > all of the required workflows, otherwise, the next audio driver with > > similar requirements will have to move to the media subsystem as well, > > the audio subsystem would then never experience the required change and > > soon we would have two audio subsystems. > > > > 2. Closely connected to the previous objection, the media subsystem with > > its current staff of maintainers is overworked and barely capable of > > handling the workload, which includes an abundance of different devices > > from DVB, codecs, cameras, PCI devices, radio tuners, HDMI CEC, IR > > receivers, etc. Adding more device types to this matrix will make the > > situation worse and should only be done with a plan for how first to > > improve the current maintainer situation. > > > > 3. By using the same framework and APIs as the video codecs, the audio > > codecs are going to cause extra work for the video codec developers and > > maintainers simply by occupying the same space that was orginally > > designed for the purpose of video only. Even if you try to not cause any > > extra stress the simple presence of the audio code in the codebase is > > going to cause restrictions. > > > > The main issue here is that the audio subsystem doesn't provide a > > mem2mem framework and I would say you are in luck because the media > > subsystem has gathered a lot of shortcomings with its current > > implementation of the mem2mem framework over time, which is why a new > > implementation will be necessary anyway. > > > > So instead of hammering a driver into the wrong destination, I would > > suggest bundling our forces and implementing a general memory-to-memory > > framework that both the media and the audio subsystem can use, that > > addresses the current shortcomings of the implementation and allows you > > to upload the driver where it is supposed to be. > > This is going to cause restrictions as well, like mentioned in the > > concern number 3, but with the difference that we can make a general > > plan for such a framework that accomodates lots of use cases and each > > subsystem can add their routines on top of the general framework. > > > > Another possible alternative is to try and make the DRM scheduler more > > generally available, this scheduler is the most mature and in fact is > > very similar to what you and what the media devices need. > > Which again just shows how common your usecase actually is and how a > > general solution is the best long term solution. > > > > Please notice that Daniel Almeida is currently working on something > > related to this: > > https://lore.kernel.org/linux-media/3f80ac0d-dcaa-4ede-bf58-bb1369c7e...@collabora.com/T/#u > > > > If the toplevel maintainers decide to add the patchset so be it, but I > > wanted to voice my concerns and also highlight that this is likely going > > to cause extra stress for the video codecs maintainers and the > > maintainers in general. We cannot spend a lot of time on audio codecs, > > as video codecs already fill up our available time sufficiently, > > so the use of the framework needs to be conservative and cause as little > > extra work as possible for the original use case of the framework. > > I would really like to get the input of the audio maintainers on this. > Sebastian has a good point, especially with us being overworked :-) > > Having a shared mem2mem framework would certainly be nice, on the other > hand, developing that will most likely take a substantial amount of time. > > Perhaps it is possible to copy the current media v4l2-mem2mem.c and turn > it into an alsa-mem2mem.c? I really do not know enough about the alsa > subsystem to tell if that is possible. > > While this driver is a rate converter, not an audio codec, the same > principles would apply to off-line audio codecs as well. And it is true > that we definitely do not want to support audio codecs in the media > subsystem. > > Accepting this driver creates a precedent and would open the door for > audio codecs. > > I may have been too hasty in saying yes to this, I did not consider > the wider implications for our workload and what it can lead to. I > since
[PATCH v2] mm/gup: Fix hugepd handling in hugetlb rework
Commit a12083d721d7 added hugepd handling for gup-slow, reusing gup-fast functions. follow_hugepd() correctly took the vma pointer in, however didn't pass it over into the lower functions, which was overlooked. The issue is gup_fast_hugepte() uses the vma pointer to make the correct decision on whether an unshare is needed for a FOLL_PIN|FOLL_LONGTERM. Now without vma ponter it will constantly return "true" (needs an unshare) for a page cache, even though in the SHARED case it will be wrong to unshare. The other problem is, even if an unshare is needed, it now returns 0 rather than -EMLINK, which will not trigger a follow up FAULT_FLAG_UNSHARE fault. That will need to be fixed too when the unshare is wanted. gup_longterm test didn't expose this issue in the past because it didn't yet test R/O unshare in this case, another separate patch will enable that in future tests. Fix it by passing vma correctly to the bottom, rename gup_fast_hugepte() back to gup_hugepte() as it is shared between the fast/slow paths, and also allow -EMLINK to be returned properly by gup_hugepte() even though gup-fast will take it the same as zero. Reported-by: David Hildenbrand Fixes: a12083d721d7 ("mm/gup: handle hugepd for follow_page()") Reviewed-by: David Hildenbrand Signed-off-by: Peter Xu --- v1: https://lore.kernel.org/r/20240428190151.201002-1-pet...@redhat.com This is v2 and dropped the 2nd test patch as a better one can come later, this patch alone is kept untouched, added David's R-b. Should apply to both mm-stable and mm-unstable. The target commit to be fixed should just been moved into mm-stable, so no need to cc stable. --- mm/gup.c | 64 ++-- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/mm/gup.c b/mm/gup.c index 2f7baf96f655..ca0f5cedce9b 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -525,9 +525,17 @@ static unsigned long hugepte_addr_end(unsigned long addr, unsigned long end, return (__boundary - 1 < end - 1) ? __boundary : end; } -static int gup_fast_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr, - unsigned long end, unsigned int flags, struct page **pages, - int *nr) +/* + * Returns 1 if succeeded, 0 if failed, -EMLINK if unshare needed. + * + * NOTE: for the same entry, gup-fast and gup-slow can return different + * results (0 v.s. -EMLINK) depending on whether vma is available. This is + * the expected behavior, where we simply want gup-fast to fallback to + * gup-slow to take the vma reference first. + */ +static int gup_hugepte(struct vm_area_struct *vma, pte_t *ptep, unsigned long sz, + unsigned long addr, unsigned long end, unsigned int flags, + struct page **pages, int *nr) { unsigned long pte_end; struct page *page; @@ -559,9 +567,9 @@ static int gup_fast_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr, return 0; } - if (!pte_write(pte) && gup_must_unshare(NULL, flags, &folio->page)) { + if (!pte_write(pte) && gup_must_unshare(vma, flags, &folio->page)) { gup_put_folio(folio, refs, flags); - return 0; + return -EMLINK; } *nr += refs; @@ -577,19 +585,22 @@ static int gup_fast_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr, * of the other folios. See writable_file_mapping_allowed() and * gup_fast_folio_allowed() for more information. */ -static int gup_fast_hugepd(hugepd_t hugepd, unsigned long addr, - unsigned int pdshift, unsigned long end, unsigned int flags, - struct page **pages, int *nr) +static int gup_hugepd(struct vm_area_struct *vma, hugepd_t hugepd, + unsigned long addr, unsigned int pdshift, + unsigned long end, unsigned int flags, + struct page **pages, int *nr) { pte_t *ptep; unsigned long sz = 1UL << hugepd_shift(hugepd); unsigned long next; + int ret; ptep = hugepte_offset(hugepd, addr, pdshift); do { next = hugepte_addr_end(addr, end, sz); - if (!gup_fast_hugepte(ptep, sz, addr, end, flags, pages, nr)) - return 0; + ret = gup_hugepte(vma, ptep, sz, addr, end, flags, pages, nr); + if (ret != 1) + return ret; } while (ptep++, addr = next, addr != end); return 1; @@ -613,22 +624,25 @@ static struct page *follow_hugepd(struct vm_area_struct *vma, hugepd_t hugepd, h = hstate_vma(vma); ptep = hugepte_offset(hugepd, addr, pdshift); ptl = huge_pte_lock(h, vma->vm_mm, ptep); - ret = gup_fast_hugepd(hugepd, addr, pdshift, addr + PAGE_SIZE, - flags, &page, &nr); + ret = gup_hugepd(vma, hugepd, addr, pdshift, addr + PAGE_SIZE, +flags, &page, &nr);
Re: [PATCH v7 05/16] module: make module_memory_{alloc,free} more self-contained
On 29/4/24 14:16, Mike Rapoport wrote: From: "Mike Rapoport (IBM)" Move the logic related to the memory allocation and freeing into module_memory_alloc() and module_memory_free(). Signed-off-by: Mike Rapoport (IBM) --- kernel/module/main.c | 64 +++- 1 file changed, 39 insertions(+), 25 deletions(-) Nice code simplification. Reviewed-by: Philippe Mathieu-Daudé
[PATCH 1/1] ALSA: aoa: soundbus: i2sbus: pcm: use 'time_left' variable with wait_for_completion_timeout()
There is a confusing pattern in the kernel to use a variable named 'timeout' to store the result of wait_for_completion_timeout() causing patterns like: timeout = wait_for_completion_timeout(...) if (!timeout) return -ETIMEDOUT; with all kinds of permutations. Use 'time_left' as a variable to make the code self explaining. Fix to the proper variable type 'unsigned long' while here. Signed-off-by: Wolfram Sang --- sound/aoa/soundbus/i2sbus/pcm.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/aoa/soundbus/i2sbus/pcm.c b/sound/aoa/soundbus/i2sbus/pcm.c index 07df5cc0f2d7..98b812ffbde6 100644 --- a/sound/aoa/soundbus/i2sbus/pcm.c +++ b/sound/aoa/soundbus/i2sbus/pcm.c @@ -255,24 +255,24 @@ static void i2sbus_wait_for_stop(struct i2sbus_dev *i2sdev, { unsigned long flags; DECLARE_COMPLETION_ONSTACK(done); - long timeout; + unsigned long time_left; spin_lock_irqsave(&i2sdev->low_lock, flags); if (pi->dbdma_ring.stopping) { pi->stop_completion = &done; spin_unlock_irqrestore(&i2sdev->low_lock, flags); - timeout = wait_for_completion_timeout(&done, HZ); + time_left = wait_for_completion_timeout(&done, HZ); spin_lock_irqsave(&i2sdev->low_lock, flags); pi->stop_completion = NULL; - if (timeout == 0) { + if (time_left == 0) { /* timeout expired, stop dbdma forcefully */ printk(KERN_ERR "i2sbus_wait_for_stop: timed out\n"); /* make sure RUN, PAUSE and S0 bits are cleared */ out_le32(&pi->dbdma->control, (RUN | PAUSE | 1) << 16); pi->dbdma_ring.stopping = 0; - timeout = 10; + time_left = 10; while (in_le32(&pi->dbdma->status) & ACTIVE) { - if (--timeout <= 0) + if (--time_left <= 0) break; udelay(1); } -- 2.43.0
Re: [EXT] [PATCH v8 6/6] docs: trusted-encrypted: add DCP as new trust source
Hi Jarkko, > On 30.04.2024, at 13:48, Kshitiz Varshney wrote: > > Hi David, > >> -Original Message- >> From: David Gstir >> Sent: Monday, April 29, 2024 5:05 PM >> To: Kshitiz Varshney >> >> Did you get around to testing this? >> I’d greatly appreciate a Tested-by for this. :-) >> >> Thanks! >> BR, David > > Currently, I am bit busy with other priority activities. It will take time to > test this patch set. How should we proceed here? Do we have to miss another release cycle, because of a Tested-by? If any bugs pop up I’ll happily fix them, but at the moment it appears to be more of a formality. IMHO the patch set itself is rather small and has been thoroughly reviewed to ensure that any huge issues would already have been caught by now. Thanks! BR, David
Re: [PATCH v3 2/2] fs/xattr: add *at family syscalls
On Fri 26-04-24 18:20:14, Christian Göttsche wrote: > From: Christian Göttsche > > Add the four syscalls setxattrat(), getxattrat(), listxattrat() and > removexattrat(). Those can be used to operate on extended attributes, > especially security related ones, either relative to a pinned directory > or on a file descriptor without read access, avoiding a > /proc//fd/ detour, requiring a mounted procfs. > > One use case will be setfiles(8) setting SELinux file contexts > ("security.selinux") without race conditions and without a file > descriptor opened with read access requiring SELinux read permission. > > Use the do_{name}at() pattern from fs/open.c. > > Pass the value of the extended attribute, its length, and for > setxattrat(2) the command (XATTR_CREATE or XATTR_REPLACE) via an added > struct xattr_args to not exceed six syscall arguments and not > merging the AT_* and XATTR_* flags. > > Signed-off-by: Christian Göttsche The patch looks good to me. Just a few nits below: > -static int path_setxattr(const char __user *pathname, > +static int do_setxattrat(int dfd, const char __user *pathname, unsigned int > at_flags, Can we please stay within 80 columns (happens in multiple places in the patch)? I don't insist but it makes things easier to read in some setups so I prefer it. > @@ -852,13 +908,21 @@ listxattr(struct dentry *d, char __user *list, size_t > size) > return error; > } > > -static ssize_t path_listxattr(const char __user *pathname, char __user *list, > - size_t size, unsigned int lookup_flags) > +static ssize_t do_listxattrat(int dfd, const char __user *pathname, char > __user *list, > + size_t size, int flags) So I like how in previous syscalls you have 'at_flags', 'lookup_flags', and 'xattr_flags'. That makes things much easier to digest. Can you please stay with that convention here as well and call this argument 'at_flags'? Also I think the argument ordering like "dfd, pathname, at_flags, list, size" is more consistent with other syscalls you define. > @@ -870,16 +934,22 @@ static ssize_t path_listxattr(const char __user > *pathname, char __user *list, > return error; > } > > +SYSCALL_DEFINE5(listxattrat, int, dfd, const char __user *, pathname, char > __user *, list, > + size_t, size, int, flags) > +{ > + return do_listxattrat(dfd, pathname, list, size, flags); > +} > + Same comment as above - "flags" -> "at_flags" and reorder args please. > @@ -917,13 +987,21 @@ removexattr(struct mnt_idmap *idmap, struct dentry *d, > return vfs_removexattr(idmap, d, kname); > } > > -static int path_removexattr(const char __user *pathname, > - const char __user *name, unsigned int lookup_flags) > +static int do_removexattrat(int dfd, const char __user *pathname, > + const char __user *name, int flags) > { Same comment as above - "flags" -> "at_flags" and reorder args please. > @@ -939,16 +1017,22 @@ static int path_removexattr(const char __user > *pathname, > return error; > } > > +SYSCALL_DEFINE4(removexattrat, int, dfd, const char __user *, pathname, > + const char __user *, name, int, flags) > +{ Same comment as above - "flags" -> "at_flags" and reorder args please. Honza -- Jan Kara SUSE Labs, CR
RE: [EXT] [PATCH v8 6/6] docs: trusted-encrypted: add DCP as new trust source
Hi David, > -Original Message- > From: David Gstir > Sent: Monday, April 29, 2024 5:05 PM > To: Kshitiz Varshney > Cc: Jarkko Sakkinen ; Mimi Zohar > ; James Bottomley ; Herbert > Xu ; David S. Miller > ; Shawn Guo ; Jonathan > Corbet ; Sascha Hauer ; > ker...@pengutronix.de; Fabio Estevam ; dl-linux-imx > ; Ahmad Fatoum ; sigma > star Kernel Team ; David Howells > ; Li Yang ; Paul Moore > ; James Morris ; Serge E. > Hallyn ; Paul E. McKenney ; > Randy Dunlap ; Catalin Marinas > ; Rafael J. Wysocki > ; Tejun Heo ; Steven Rostedt > (Google) ; linux-...@vger.kernel.org; linux- > ker...@vger.kernel.org; linux-integr...@vger.kernel.org; > keyri...@vger.kernel.org; linux-cry...@vger.kernel.org; linux-arm- > ker...@lists.infradead.org; linuxppc-dev@lists.ozlabs.org; linux-security- > mod...@vger.kernel.org; Richard Weinberger ; David > Oberhollenzer ; Varun Sethi > ; Gaurav Jain ; Pankaj Gupta > > Subject: Re: [EXT] [PATCH v8 6/6] docs: trusted-encrypted: add DCP as new > trust source > > Caution: This is an external email. Please take care when clicking links or > opening attachments. When in doubt, report the message using the 'Report > this email' button > > > Hi Kshitiz, > > > On 09.04.2024, at 11:48, Kshitiz Varshney > wrote: > > > > Hi Jarkko, > > > > > >> -Original Message- > >> From: Jarkko Sakkinen > >> Sent: Wednesday, April 3, 2024 9:18 PM > >> To: David Gstir ; Mimi Zohar > >> ; James Bottomley ; > Herbert > >> Xu ; David S. Miller > >> > >> Cc: Shawn Guo ; Jonathan Corbet > >> ; Sascha Hauer ; > Pengutronix > >> Kernel Team ; Fabio Estevam > >> ; dl-linux-imx ; Ahmad > Fatoum > >> ; sigma star Kernel Team > >> ; David Howells ; > Li > >> Yang ; Paul Moore ; > James > >> Morris ; Serge E. Hallyn ; Paul > E. > >> McKenney ; Randy Dunlap > ; > >> Catalin Marinas ; Rafael J. Wysocki > >> ; Tejun Heo ; Steven > >> Rostedt > >> (Google) ; linux-...@vger.kernel.org; linux- > >> ker...@vger.kernel.org; linux-integr...@vger.kernel.org; > >> keyri...@vger.kernel.org; linux-cry...@vger.kernel.org; linux-arm- > >> ker...@lists.infradead.org; linuxppc-dev@lists.ozlabs.org; > >> linux-security- mod...@vger.kernel.org; Richard Weinberger > >> ; David Oberhollenzer > >> > >> Subject: [EXT] Re: [PATCH v8 6/6] docs: trusted-encrypted: add DCP as > >> new trust source > >> > >> Caution: This is an external email. Please take care when clicking > >> links or opening attachments. When in doubt, report the message using > >> the 'Report this email' button > >> > >> > >> On Wed Apr 3, 2024 at 10:21 AM EEST, David Gstir wrote: > >>> Update the documentation for trusted and encrypted KEYS with DCP as > >>> new trust source: > >>> > >>> - Describe security properties of DCP trust source > >>> - Describe key usage > >>> - Document blob format > >>> > >>> Co-developed-by: Richard Weinberger > >>> Signed-off-by: Richard Weinberger > >>> Co-developed-by: David Oberhollenzer > >>> > >>> Signed-off-by: David Oberhollenzer > >>> > >>> Signed-off-by: David Gstir > >>> --- > >>> .../security/keys/trusted-encrypted.rst | 53 +++ > >>> security/keys/trusted-keys/trusted_dcp.c | 19 +++ > >>> 2 files changed, 72 insertions(+) > >>> > >>> diff --git a/Documentation/security/keys/trusted-encrypted.rst > >>> b/Documentation/security/keys/trusted-encrypted.rst > >>> index e989b9802f92..f4d7e162d5e4 100644 > >>> --- a/Documentation/security/keys/trusted-encrypted.rst > >>> +++ b/Documentation/security/keys/trusted-encrypted.rst > >>> @@ -42,6 +42,14 @@ safe. > >>> randomly generated and fused into each SoC at manufacturing > time. > >>> Otherwise, a common fixed test key is used instead. > >>> > >>> + (4) DCP (Data Co-Processor: crypto accelerator of various i.MX > >>> + SoCs) > >>> + > >>> + Rooted to a one-time programmable key (OTP) that is > >>> + generally > >> burnt > >>> + in the on-chip fuses and is accessible to the DCP > >>> + encryption engine > >> only. > >>> + DCP provides two keys that can be used as root of trust: > >>> + the OTP > >> key > >>> + and the UNIQUE key. Default is to use the UNIQUE key, but > selecting > >>> + the OTP key can be done via a module parameter > >> (dcp_use_otp_key). > >>> + > >>> * Execution isolation > >>> > >>> (1) TPM > >>> @@ -57,6 +65,12 @@ safe. > >>> > >>> Fixed set of operations running in isolated execution > >>> environment. > >>> > >>> + (4) DCP > >>> + > >>> + Fixed set of cryptographic operations running in isolated > execution > >>> + environment. Only basic blob key encryption is executed there. > >>> + The actual key sealing/unsealing is done on main > >>> + processor/kernel > >> space. > >>> + > >>> * Optional binding to platform integrity state > >>> > >>> (1) TPM > >>> @@ -79,6 +93,11 @@ safe. > >>> Relies on the High Assurance Boot (HAB) mechanism of NXP SoCs > >>> for platform integrity.
Re: [PATCH v15 00/16] Add audio support in v4l2 framework
On 30/04/2024 10:21, Sebastian Fricke wrote: > Hey Shengjiu, > > first of all thanks for all of this work and I am very sorry for only > emerging this late into the series, I sadly didn't notice it earlier. > > I would like to voice a few concerns about the general idea of adding > Audio support to the Media subsystem. > > 1. The biggest objection is, that the Linux Kernel has a subsystem > specifically targeted for audio devices, adding support for these > devices in another subsystem are counterproductive as they work around > the shortcomings of the audio subsystem while forcing support for a > device into a subsystem that was never designed for such devices. > Instead, the audio subsystem has to be adjusted to be able to support > all of the required workflows, otherwise, the next audio driver with > similar requirements will have to move to the media subsystem as well, > the audio subsystem would then never experience the required change and > soon we would have two audio subsystems. > > 2. Closely connected to the previous objection, the media subsystem with > its current staff of maintainers is overworked and barely capable of > handling the workload, which includes an abundance of different devices > from DVB, codecs, cameras, PCI devices, radio tuners, HDMI CEC, IR > receivers, etc. Adding more device types to this matrix will make the > situation worse and should only be done with a plan for how first to > improve the current maintainer situation. > > 3. By using the same framework and APIs as the video codecs, the audio > codecs are going to cause extra work for the video codec developers and > maintainers simply by occupying the same space that was orginally > designed for the purpose of video only. Even if you try to not cause any > extra stress the simple presence of the audio code in the codebase is > going to cause restrictions. > > The main issue here is that the audio subsystem doesn't provide a > mem2mem framework and I would say you are in luck because the media > subsystem has gathered a lot of shortcomings with its current > implementation of the mem2mem framework over time, which is why a new > implementation will be necessary anyway. > > So instead of hammering a driver into the wrong destination, I would > suggest bundling our forces and implementing a general memory-to-memory > framework that both the media and the audio subsystem can use, that > addresses the current shortcomings of the implementation and allows you > to upload the driver where it is supposed to be. > This is going to cause restrictions as well, like mentioned in the > concern number 3, but with the difference that we can make a general > plan for such a framework that accomodates lots of use cases and each > subsystem can add their routines on top of the general framework. > > Another possible alternative is to try and make the DRM scheduler more > generally available, this scheduler is the most mature and in fact is > very similar to what you and what the media devices need. > Which again just shows how common your usecase actually is and how a > general solution is the best long term solution. > > Please notice that Daniel Almeida is currently working on something > related to this: > https://lore.kernel.org/linux-media/3f80ac0d-dcaa-4ede-bf58-bb1369c7e...@collabora.com/T/#u > > If the toplevel maintainers decide to add the patchset so be it, but I > wanted to voice my concerns and also highlight that this is likely going > to cause extra stress for the video codecs maintainers and the > maintainers in general. We cannot spend a lot of time on audio codecs, > as video codecs already fill up our available time sufficiently, > so the use of the framework needs to be conservative and cause as little > extra work as possible for the original use case of the framework. I would really like to get the input of the audio maintainers on this. Sebastian has a good point, especially with us being overworked :-) Having a shared mem2mem framework would certainly be nice, on the other hand, developing that will most likely take a substantial amount of time. Perhaps it is possible to copy the current media v4l2-mem2mem.c and turn it into an alsa-mem2mem.c? I really do not know enough about the alsa subsystem to tell if that is possible. While this driver is a rate converter, not an audio codec, the same principles would apply to off-line audio codecs as well. And it is true that we definitely do not want to support audio codecs in the media subsystem. Accepting this driver creates a precedent and would open the door for audio codecs. I may have been too hasty in saying yes to this, I did not consider the wider implications for our workload and what it can lead to. I sincerely apologize to Shengjiu Wang as it is no fun to end up in a situation like this. Regards, Hans