Re: [RFC PATCH v12 14/33] KVM: Add KVM_CREATE_GUEST_MEMFD ioctl() for guest-specific backing memory

2023-09-20 Thread Binbin Wu




On 9/20/2023 10:24 PM, Sean Christopherson wrote:

On Tue, Sep 19, 2023, Binbin Wu wrote:


On 9/14/2023 9:55 AM, Sean Christopherson wrote:
[...]

+
+static void kvm_gmem_invalidate_begin(struct kvm_gmem *gmem, pgoff_t start,
+ pgoff_t end)
+{
+   struct kvm_memory_slot *slot;
+   struct kvm *kvm = gmem->kvm;
+   unsigned long index;
+   bool flush = false;
+
+   KVM_MMU_LOCK(kvm);
+
+   kvm_mmu_invalidate_begin(kvm);
+
+   xa_for_each_range(>bindings, index, slot, start, end - 1) {
+   pgoff_t pgoff = slot->gmem.pgoff;
+
+   struct kvm_gfn_range gfn_range = {
+   .start = slot->base_gfn + max(pgoff, start) - pgoff,
+   .end = slot->base_gfn + min(pgoff + slot->npages, end) 
- pgoff,
+   .slot = slot,
+   .may_block = true,
+   };
+
+   flush |= kvm_mmu_unmap_gfn_range(kvm, _range);
+   }
+
+   if (flush)
+   kvm_flush_remote_tlbs(kvm);
+
+   KVM_MMU_UNLOCK(kvm);
+}
+
+static void kvm_gmem_invalidate_end(struct kvm_gmem *gmem, pgoff_t start,
+   pgoff_t end)
+{
+   struct kvm *kvm = gmem->kvm;
+
+   KVM_MMU_LOCK(kvm);
+   if (xa_find(>bindings, , end - 1, XA_PRESENT))
+   kvm_mmu_invalidate_end(kvm);

kvm_mmu_invalidate_begin() is called unconditionally in
kvm_gmem_invalidate_begin(),
but kvm_mmu_invalidate_end() is not here.
This makes the kvm_gmem_invalidate_{begin, end}() calls asymmetric.

Another ouch :-(

And there should be no need to acquire mmu_lock() unconditionally, the inode's
mutex protects the bindings, not mmu_lock.

I'll get a fix posted today.  I think KVM can also add a sanity check to detect
unresolved invalidations, e.g.

diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 7ba1ab1832a9..2a2d18070856 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1381,8 +1381,13 @@ static void kvm_destroy_vm(struct kvm *kvm)
  * No threads can be waiting in kvm_swap_active_memslots() as the
  * last reference on KVM has been dropped, but freeing
  * memslots would deadlock without this manual intervention.
+*
+* If the count isn't unbalanced, i.e. KVM did NOT unregister between
+* a start() and end(), then there shouldn't be any in-progress
+* invalidations.
  */
 WARN_ON(rcuwait_active(>mn_memslots_update_rcuwait));
+   WARN_ON(!kvm->mn_active_invalidate_count && 
kvm->mmu_invalidate_in_progress);
 kvm->mn_active_invalidate_count = 0;
  #else
 kvm_flush_shadow_all(kvm);


or an alternative style

if (kvm->mn_active_invalidate_count)
kvm->mn_active_invalidate_count = 0;
else
WARN_ON(kvm->mmu_invalidate_in_progress)


+   KVM_MMU_UNLOCK(kvm);
+}
+
+static long kvm_gmem_punch_hole(struct inode *inode, loff_t offset, loff_t len)
+{
+   struct list_head *gmem_list = >i_mapping->private_list;
+   pgoff_t start = offset >> PAGE_SHIFT;
+   pgoff_t end = (offset + len) >> PAGE_SHIFT;
+   struct kvm_gmem *gmem;
+
+   /*
+* Bindings must stable across invalidation to ensure the start+end
+* are balanced.
+*/
+   filemap_invalidate_lock(inode->i_mapping);
+
+   list_for_each_entry(gmem, gmem_list, entry) {
+   kvm_gmem_invalidate_begin(gmem, start, end);
+   kvm_gmem_invalidate_end(gmem, start, end);
+   }

Why to loop for each gmem in gmem_list here?

IIUIC, offset is the offset according to the inode, it is only meaningful to
the inode passed in, i.e, it is only meaningful to the gmem binding with the
inode, not others.

The code is structured to allow for multiple gmem instances per inode.  This 
isn't
actually possible in the initial code base, but it's on the horizon[*].  I 
included
the list-based infrastructure in this initial series to ensure that guest_memfd
can actually support multiple files per inode, and to minimize the churn when 
the
"link" support comes along.

[*] https://lore.kernel.org/all/cover.1691446946.git.ackerley...@google.com

Got it, thanks for the explanation!





Re: [RFC PATCH v12 18/33] KVM: x86/mmu: Handle page fault for private memory

2023-09-20 Thread Binbin Wu




On 9/15/2023 10:26 PM, Sean Christopherson wrote:

On Fri, Sep 15, 2023, Yan Zhao wrote:

On Wed, Sep 13, 2023 at 06:55:16PM -0700, Sean Christopherson wrote:


+static void kvm_mmu_prepare_memory_fault_exit(struct kvm_vcpu *vcpu,
+ struct kvm_page_fault *fault)
+{
+   kvm_prepare_memory_fault_exit(vcpu, fault->gfn << PAGE_SHIFT,
+ PAGE_SIZE, fault->write, fault->exec,
+ fault->is_private);
+}
+
+static int kvm_faultin_pfn_private(struct kvm_vcpu *vcpu,
+  struct kvm_page_fault *fault)
+{
+   int max_order, r;
+
+   if (!kvm_slot_can_be_private(fault->slot)) {
+   kvm_mmu_prepare_memory_fault_exit(vcpu, fault);
+   return -EFAULT;
+   }
+
+   r = kvm_gmem_get_pfn(vcpu->kvm, fault->slot, fault->gfn, >pfn,
+_order);
+   if (r) {
+   kvm_mmu_prepare_memory_fault_exit(vcpu, fault);
+   return r;
+   }
+
+   fault->max_level = min(kvm_max_level_for_order(max_order),
+  fault->max_level);
+   fault->map_writable = !(fault->slot->flags & KVM_MEM_READONLY);
+
+   return RET_PF_CONTINUE;
+}
+
  static int __kvm_faultin_pfn(struct kvm_vcpu *vcpu, struct kvm_page_fault 
*fault)
  {
struct kvm_memory_slot *slot = fault->slot;
@@ -4293,6 +4356,14 @@ static int __kvm_faultin_pfn(struct kvm_vcpu *vcpu, 
struct kvm_page_fault *fault
return RET_PF_EMULATE;
}
  
+	if (fault->is_private != kvm_mem_is_private(vcpu->kvm, fault->gfn)) {

In patch 21,
fault->is_private is set as:
".is_private = kvm_mem_is_private(vcpu->kvm, cr2_or_gpa >> PAGE_SHIFT)",
then, the inequality here means memory attribute has been updated after
last check.
So, why an exit to user space for converting is required instead of a mere 
retry?

Or, is it because how .is_private is assigned in patch 21 is subjected to change
in future?

This.  Retrying on SNP or TDX would hang the guest.  I suppose we could special
case VMs where .is_private is derived from the memory attributes, but the
SW_PROTECTED_VM type is primary a development vehicle at this point.  I'd like 
to
have it mimic SNP/TDX as much as possible; performance is a secondary concern.
So when .is_private is derived from the memory attributes, and if I 
didn't miss
anything, there is no explicit conversion mechanism introduced yet so 
far, does

it mean for pure sw-protected VM (withouth SNP/TDX), the page fault will be
handled according to the memory attributes setup by host/user vmm, no 
implicit

conversion will be triggered, right?




E.g. userspace needs to be prepared for "spurious" exits due to races on SNP and
TDX, which this can theoretically exercise.  Though the window is quite small so
I doubt that'll actually happen in practice; which of course also makes it less
important to retry instead of exiting.




Re: [RFC PATCH v12 02/33] KVM: Use gfn instead of hva for mmu_notifier_retry

2023-09-20 Thread Xu Yilun
On 2023-09-20 at 06:55:05 -0700, Sean Christopherson wrote:
> On Wed, Sep 20, 2023, Xu Yilun wrote:
> > On 2023-09-13 at 18:55:00 -0700, Sean Christopherson wrote:
> > > +void kvm_mmu_invalidate_range_add(struct kvm *kvm, gfn_t start, gfn_t 
> > > end)
> > > +{
> > > + lockdep_assert_held_write(>mmu_lock);
> > > +
> > > + WARN_ON_ONCE(!kvm->mmu_invalidate_in_progress);
> > > +
> > >   if (likely(kvm->mmu_invalidate_in_progress == 1)) {
> > >   kvm->mmu_invalidate_range_start = start;
> > >   kvm->mmu_invalidate_range_end = end;
> > 
> > IIUC, Now we only add or override a part of the invalidate range in
> > these fields, IOW only the range in last slot is stored when we unlock.
> 
> Ouch.  Good catch!
> 
> > That may break mmu_invalidate_retry_gfn() cause it can never know the
> > whole invalidate range.
> > 
> > How about we extend the mmu_invalidate_range_start/end everytime so that
> > it records the whole invalidate range:
> > 
> > if (kvm->mmu_invalidate_range_start == INVALID_GPA) {
> > kvm->mmu_invalidate_range_start = start;
> > kvm->mmu_invalidate_range_end = end;
> > } else {
> > kvm->mmu_invalidate_range_start =
> > min(kvm->mmu_invalidate_range_start, start);
> > kvm->mmu_invalidate_range_end =
> > max(kvm->mmu_invalidate_range_end, end);
> > }
> 
> Yeah, that does seem to be the easiest solution.
> 
> I'll post a fixup patch, unless you want the honors.

Please go ahead, cause at a second thought I'm wondering if this simple
range extension is reasonable.

When the invalidation acrosses multiple slots, I'm not sure if the
contiguous HVA range must correspond to contiguous GFN range. If not,
are we producing a larger range than required?

And when the invalidation acrosses multiple address space, I'm almost
sure it is wrong to merge GFN ranges from different address spaces. But
I have no clear solution yet.

Thanks,
Yilun


Re: [RFC PATCH v12 11/33] KVM: Introduce per-page memory attributes

2023-09-20 Thread Yan Zhao
On Wed, Sep 20, 2023 at 02:00:22PM -0700, Sean Christopherson wrote:
> On Fri, Sep 15, 2023, Yan Zhao wrote:
> > On Wed, Sep 13, 2023 at 06:55:09PM -0700, Sean Christopherson wrote:
> > > From: Chao Peng 
> > > 
> > > In confidential computing usages, whether a page is private or shared is
> > > necessary information for KVM to perform operations like page fault
> > > handling, page zapping etc. There are other potential use cases for
> > > per-page memory attributes, e.g. to make memory read-only (or no-exec,
> > > or exec-only, etc.) without having to modify memslots.
> > > 
> > ...
> > >> +bool kvm_range_has_memory_attributes(struct kvm *kvm, gfn_t start, 
> > >> gfn_t end,
> > > +  unsigned long attrs)
> > > +{
> > > + XA_STATE(xas, >mem_attr_array, start);
> > > + unsigned long index;
> > > + bool has_attrs;
> > > + void *entry;
> > > +
> > > + rcu_read_lock();
> > > +
> > > + if (!attrs) {
> > > + has_attrs = !xas_find(, end);
> > > + goto out;
> > > + }
> > > +
> > > + has_attrs = true;
> > > + for (index = start; index < end; index++) {
> > > + do {
> > > + entry = xas_next();
> > > + } while (xas_retry(, entry));
> > > +
> > > + if (xas.xa_index != index || xa_to_value(entry) != attrs) {
> > Should "xa_to_value(entry) != attrs" be "!(xa_to_value(entry) & attrs)" ?
> 
> No, the exact comparsion is deliberate.  The intent of the API is to determine
> if the entire range already has the desired attributes, not if there is 
> overlap
> between the two.
> 
> E.g. if/when RWX attributes are supported, the exact comparison is needed to
> handle a RW => R conversion.
> 
> > > + has_attrs = false;
> > > + break;
> > > + }
> > > + }
> > > +
> > > +out:
> > > + rcu_read_unlock();
> > > + return has_attrs;
> > > +}
> > > +
> > ...
> > > +/* Set @attributes for the gfn range [@start, @end). */
> > > +static int kvm_vm_set_mem_attributes(struct kvm *kvm, gfn_t start, gfn_t 
> > > end,
> > > +  unsigned long attributes)
> > > +{
> > > + struct kvm_mmu_notifier_range pre_set_range = {
> > > + .start = start,
> > > + .end = end,
> > > + .handler = kvm_arch_pre_set_memory_attributes,
> > > + .on_lock = kvm_mmu_invalidate_begin,
> > > + .flush_on_ret = true,
> > > + .may_block = true,
> > > + };
> > > + struct kvm_mmu_notifier_range post_set_range = {
> > > + .start = start,
> > > + .end = end,
> > > + .arg.attributes = attributes,
> > > + .handler = kvm_arch_post_set_memory_attributes,
> > > + .on_lock = kvm_mmu_invalidate_end,
> > > + .may_block = true,
> > > + };
> > > + unsigned long i;
> > > + void *entry;
> > > + int r = 0;
> > > +
> > > + entry = attributes ? xa_mk_value(attributes) : NULL;
> > Also here, do we need to get existing attributes of a GFN first ?
> 
> No?  @entry is the new value that will be set for all entries.  This line 
> doesn't
> touch the xarray in any way.  Maybe I'm just not understanding your question.
Hmm, I thought this interface was to allow users to add/remove an attribute to 
a GFN
rather than overwrite all attributes of a GFN. Now I think I misunderstood the 
intention.

But I wonder if there is a way for users to just add one attribute, as I don't 
find
ioctl like KVM_GET_MEMORY_ATTRIBUTES for users to get current attributes and 
then to
add/remove one based on that. e.g. maybe in future, KVM wants to add one 
attribute in
kernel without being told by userspace ?



Re: [RFC PATCH v12 14/33] KVM: Add KVM_CREATE_GUEST_MEMFD ioctl() for guest-specific backing memory

2023-09-20 Thread Sean Christopherson
On Mon, Sep 18, 2023, Michael Roth wrote:
> > +static long kvm_gmem_punch_hole(struct inode *inode, loff_t offset, loff_t 
> > len)
> > +{
> > +   struct list_head *gmem_list = >i_mapping->private_list;
> > +   pgoff_t start = offset >> PAGE_SHIFT;
> > +   pgoff_t end = (offset + len) >> PAGE_SHIFT;
> > +   struct kvm_gmem *gmem;
> > +
> > +   /*
> > +* Bindings must stable across invalidation to ensure the start+end
> > +* are balanced.
> > +*/
> > +   filemap_invalidate_lock(inode->i_mapping);
> > +
> > +   list_for_each_entry(gmem, gmem_list, entry) {
> > +   kvm_gmem_invalidate_begin(gmem, start, end);
> 
> In v11 we used to call truncate_inode_pages_range() here to drop filemap's
> reference on the folio. AFAICT the folios are only getting free'd upon
> guest shutdown without this. Was this on purpose?

Nope, I just spotted this too.  And then after scratching my head for a few 
minutes,
wondering if I was having an -ENOCOFFEE moment, I finally read your mail.  
*sigh*

Looking at my reflog history, I'm pretty sure I deleted the wrong line when
removing the truncation from kvm_gmem_error_page().

> > +   kvm_gmem_invalidate_end(gmem, start, end);
> > +   }
> > +
> > +   filemap_invalidate_unlock(inode->i_mapping);
> > +
> > +   return 0;
> > +}
> > +
> > +static long kvm_gmem_allocate(struct inode *inode, loff_t offset, loff_t 
> > len)
> > +{
> > +   struct address_space *mapping = inode->i_mapping;
> > +   pgoff_t start, index, end;
> > +   int r;
> > +
> > +   /* Dedicated guest is immutable by default. */
> > +   if (offset + len > i_size_read(inode))
> > +   return -EINVAL;
> > +
> > +   filemap_invalidate_lock_shared(mapping);
> 
> We take the filemap lock here, but not for
> kvm_gmem_get_pfn()->kvm_gmem_get_folio(). Is it needed there as well?

No, we specifically do not want to take a rwsem when faulting in guest memory.
Callers of kvm_gmem_get_pfn() *must* guard against concurrent invalidations via
mmu_invalidate_seq and friends.

> > +   /*
> > +* For simplicity, require the offset into the file and the size of the
> > +* memslot to be aligned to the largest possible page size used to back
> > +* the file (same as the size of the file itself).
> > +*/
> > +   if (!kvm_gmem_is_valid_size(offset, flags) ||
> > +   !kvm_gmem_is_valid_size(size, flags))
> > +   goto err;
> 
> I needed to relax this check for SNP. KVM_GUEST_MEMFD_ALLOW_HUGEPAGE
> applies to entire gmem inode, so it makes sense for userspace to enable
> hugepages if start/end are hugepage-aligned, but QEMU will do things
> like map overlapping regions for ROMs and other things on top of the
> GPA range that the gmem inode was originally allocated for. For
> instance:
> 
>   692500@1689108688.696338:kvm_set_user_memory AddrSpace#0 Slot#0 flags=0x4 
> gpa=0x0 size=0x8000 ua=0x7fbf5be0 ret=0 restricted_fd=19 
> restricted_offset=0x0
>   692500@1689108688.699802:kvm_set_user_memory AddrSpace#0 Slot#1 flags=0x4 
> gpa=0x1 size=0x38000 ua=0x7fbfdbe0 ret=0 restricted_fd=19 
> restricted_offset=0x8000
>   692500@1689108688.795412:kvm_set_user_memory AddrSpace#0 Slot#0 flags=0x0 
> gpa=0x0 size=0x0 ua=0x7fbf5be0 ret=0 restricted_fd=19 
> restricted_offset=0x0
>   692500@1689108688.795550:kvm_set_user_memory AddrSpace#0 Slot#0 flags=0x4 
> gpa=0x0 size=0xc ua=0x7fbf5be0 ret=0 restricted_fd=19 
> restricted_offset=0x0
>   692500@1689108688.796227:kvm_set_user_memory AddrSpace#0 Slot#6 flags=0x4 
> gpa=0x10 size=0x7ff0 ua=0x7fbf5bf0 ret=0 restricted_fd=19 
> restricted_offset=0x10
> 
> Because of that the KVM_SET_USER_MEMORY_REGIONs for non-THP-aligned GPAs
> will fail. Maybe instead it should be allowed, and kvm_gmem_get_folio()
> should handle the alignment checks on a case-by-case and simply force 4k
> for offsets corresponding to unaligned bindings?

Yeah, I wanted to keep the code simple, but disallowing small bindings/memslots
is probably going to be a deal-breaker.  Even though I'm skeptical that QEMU
_needs_ to play these games for SNP guests, not playing nice will make it all
but impossible to use guest_memfd for regular VMs.

And the code isn't really any more complex, so long as we punt on allowing
hugepages on interior sub-ranges.

Compile-tested only, but this?

---
 virt/kvm/guest_mem.c | 54 ++--
 1 file changed, 27 insertions(+), 27 deletions(-)

diff --git a/virt/kvm/guest_mem.c b/virt/kvm/guest_mem.c
index a819367434e9..dc12e38211df 100644
--- a/virt/kvm/guest_mem.c
+++ b/virt/kvm/guest_mem.c
@@ -426,20 +426,6 @@ static int __kvm_gmem_create(struct kvm *kvm, loff_t size, 
u64 flags,
return err;
 }
 
-static bool kvm_gmem_is_valid_size(loff_t size, u64 flags)
-{
-   if (size < 0 || !PAGE_ALIGNED(size))
-   return false;
-
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-   if ((flags & KVM_GUEST_MEMFD_ALLOW_HUGEPAGE) &&
-   !IS_ALIGNED(size, 

Re: Questions: Should kernel panic when PCIe fatal error occurs?

2023-09-20 Thread Bjorn Helgaas
On Mon, Sep 18, 2023 at 05:39:58PM +0800, Shuai Xue wrote:
> Hi, all folks,
> 
> Error reporting and recovery are one of the important features of PCIe, and
> the kernel has been supporting them since version 2.6, 17 years ago.
> I am very curious about the expected behavior of the software.
> I first recap the error classification and then list my questions bellow it.
> 
> ## Recap: Error classification
> 
> - Fatal Errors
> 
> Fatal errors are uncorrectable error conditions which render the particular
> Link and related hardware unreliable. For Fatal errors, a reset of the
> components on the Link may be required to return to reliable operation.
> Platform handling of Fatal errors, and any efforts to limit the effects of
> these errors, is platform implementation specific. (PCIe 6.0.1, sec
> 6.2.2.2.1 Fatal Errors).
> 
> - Non-Fatal Errors
> 
> Non-fatal errors are uncorrectable errors which cause a particular
> transaction to be unreliable but the Link is otherwise fully functional.
> Isolating Non-fatal from Fatal errors provides Requester/Receiver logic in
> a device or system management software the opportunity to recover from the
> error without resetting the components on the Link and disturbing other
> transactions in progress. Devices not associated with the transaction in
> error are not impacted by the error.  (PCIe 6.0.1, sec 6.2.2.2.1 Non-Fatal
> Errors).
> 
> ## What the kernel do?
> 
> The Linux kernel supports both the OS native and firmware first modes in
> AER and DPC drivers. The error recovery API is defined in `struct
> pci_error_handlers`, and the recovery process is performed in several
> stages in pcie_do_recovery(). One main difference in handling PCIe errors
> is that the kernel only resets the link when a fatal error is detected.
> 
> ## Questions
> 
> 1. Should kernel panic when fatal errors occur without AER recovery?
> 
> IMHO, the answer is NO. The AER driver handles both fatal and
> non-fatal errors, and I have not found any panic changes in the
> recovery path in OS native mode.
> 
> As far as I know, on many X86 platforms, struct
> `acpi_hest_generic_status::error_severity` is set as CPER_SEV_FATAL
> in firmware first mode. As a result, kernel will panic immediately
> in ghes_proc() when fatal AER errors occur, and there is no chance
> to handle the error and perform recovery in AER driver.

UEFI r2.10, sec N.2.1,, defines CPER_SEV_FATAL, and platform firmware
decides which Error Severity to put in the error record.  I don't see
anything in UEFI about how the OS should handle fatal errors.

ACPI r6.5, sec 18.1, says on fatal uncorrected error, the system
should be restarted to prevent propagation of the error.  For
CPER_SEV_FATAL errors, it looks like ghes_proc() panics even before
trying AER recovery.

I guess your point is that for CPER_SEV_FATAL errors, the APEI/GHES
path always panics but the native path never does, and that maybe both
paths should work the same way?

It would be nice if they worked the same, but I suspect that vendors
may rely on the fact that CPER_SEV_FATAL forces a restart/panic as
part of their system integrity story.

It doesn't seem like the native path should always panic.  If we can
tell that data was corrupted, we may want to panic, but otherwise I
don't think we should crash the entire system even if some device is
permanently broken.

> For fatal and non-fatal errors, struct
> `acpi_hest_generic_status::error_severity` should as
> CPER_SEV_RECOVERABLE, and struct
> `acpi_hest_generic_data::error_severity` should reflect its real
> severity. Then, the kernel is equivalent to handling PCIe errors in
> Firmware first mode as it does in OS native mode.  Please correct me
> if I am wrong.

I don't know enough to comment on how Error Severity should be used in
the Generic Error Status Block vs the Generic Error Data Entry.

> However, I have changed my mind on this issue as I encounter a case where
> a error propagation is detected due to fatal DLLP (Data Link Protocol
> Error) error. A DLLP error occurred in the Compute node, causing the
> node to panic because `struct acpi_hest_generic_status::error_severity` was
> set as CPER_SEV_FATAL. However, data corruption was still detected in the
> storage node by CRC.

The only mention of Data Link Protocol Error that looks relevant is
PCIe r6.0, sec 3.6.2.2, which basically says a DLLP with an unexpected
Sequence Number should be discarded:

  For Ack and Nak DLLPs, the following steps are followed (see Figure
  3-21):

- If the Sequence Number specified by the AckNak_Seq_Num does not
  correspond to an unacknowledged TLP, or to the value in
  ACKD_SEQ, the DLLP is discarded

  - This is a Data Link Protocol Error, which is a reported error
associated with the Port (see Section 6.2).

So data from that DLLP should not have made it to memory, although of
course the DMA may not have been completed.  But it sounds like you
did see corrupted data written to memory?

I assume it is 

Re: [RFC PATCH v12 11/33] KVM: Introduce per-page memory attributes

2023-09-20 Thread Sean Christopherson
On Mon, Sep 18, 2023, Binbin Wu wrote:
> 
> 
> On 9/14/2023 9:55 AM, Sean Christopherson wrote:
> > From: Chao Peng 
> [...]
> > +#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES
> > +/*
> > + * Returns true if _all_ gfns in the range [@start, @end) have attributes
> > + * matching @attrs.
> > + */
> > +bool kvm_range_has_memory_attributes(struct kvm *kvm, gfn_t start, gfn_t 
> > end,
> > +unsigned long attrs)
> > +{
> > +   XA_STATE(xas, >mem_attr_array, start);
> > +   unsigned long index;
> > +   bool has_attrs;
> > +   void *entry;
> > +
> > +   rcu_read_lock();
> > +
> > +   if (!attrs) {
> > +   has_attrs = !xas_find(, end);
> IIUIC, xas_find() is inclusive for "end", so here should be "end - 1" ?

Yes, that does appear to be the case.  Inclusive vs. exclusive on gfn ranges has
is the bane of my existence.


Re: [PATCH v2 0/8] sysctl: Remove sentinel elements from arch

2023-09-20 Thread Luis Chamberlain
On Wed, Sep 13, 2023 at 11:10:54AM +0200, Joel Granados via B4 Relay wrote:
> V2:
> * Added clarification both in the commit messages and the coverletter as
>   to why this patch is safe to apply.
> * Added {Acked,Reviewed,Tested}-by from list
> * Link to v1: 
> https://lore.kernel.org/r/20230906-jag-sysctl_remove_empty_elem_arch-v1-0-3935d4854...@samsung.com

Thanks! I've merged this onto sysctl-next.

  Luis


Re: [RFC PATCH v12 11/33] KVM: Introduce per-page memory attributes

2023-09-20 Thread Sean Christopherson
On Fri, Sep 15, 2023, Yan Zhao wrote:
> On Wed, Sep 13, 2023 at 06:55:09PM -0700, Sean Christopherson wrote:
> > From: Chao Peng 
> > 
> > In confidential computing usages, whether a page is private or shared is
> > necessary information for KVM to perform operations like page fault
> > handling, page zapping etc. There are other potential use cases for
> > per-page memory attributes, e.g. to make memory read-only (or no-exec,
> > or exec-only, etc.) without having to modify memslots.
> > 
> ...
> >> +bool kvm_range_has_memory_attributes(struct kvm *kvm, gfn_t start, gfn_t 
> >> end,
> > +unsigned long attrs)
> > +{
> > +   XA_STATE(xas, >mem_attr_array, start);
> > +   unsigned long index;
> > +   bool has_attrs;
> > +   void *entry;
> > +
> > +   rcu_read_lock();
> > +
> > +   if (!attrs) {
> > +   has_attrs = !xas_find(, end);
> > +   goto out;
> > +   }
> > +
> > +   has_attrs = true;
> > +   for (index = start; index < end; index++) {
> > +   do {
> > +   entry = xas_next();
> > +   } while (xas_retry(, entry));
> > +
> > +   if (xas.xa_index != index || xa_to_value(entry) != attrs) {
> Should "xa_to_value(entry) != attrs" be "!(xa_to_value(entry) & attrs)" ?

No, the exact comparsion is deliberate.  The intent of the API is to determine
if the entire range already has the desired attributes, not if there is overlap
between the two.

E.g. if/when RWX attributes are supported, the exact comparison is needed to
handle a RW => R conversion.

> > +   has_attrs = false;
> > +   break;
> > +   }
> > +   }
> > +
> > +out:
> > +   rcu_read_unlock();
> > +   return has_attrs;
> > +}
> > +
> ...
> > +/* Set @attributes for the gfn range [@start, @end). */
> > +static int kvm_vm_set_mem_attributes(struct kvm *kvm, gfn_t start, gfn_t 
> > end,
> > +unsigned long attributes)
> > +{
> > +   struct kvm_mmu_notifier_range pre_set_range = {
> > +   .start = start,
> > +   .end = end,
> > +   .handler = kvm_arch_pre_set_memory_attributes,
> > +   .on_lock = kvm_mmu_invalidate_begin,
> > +   .flush_on_ret = true,
> > +   .may_block = true,
> > +   };
> > +   struct kvm_mmu_notifier_range post_set_range = {
> > +   .start = start,
> > +   .end = end,
> > +   .arg.attributes = attributes,
> > +   .handler = kvm_arch_post_set_memory_attributes,
> > +   .on_lock = kvm_mmu_invalidate_end,
> > +   .may_block = true,
> > +   };
> > +   unsigned long i;
> > +   void *entry;
> > +   int r = 0;
> > +
> > +   entry = attributes ? xa_mk_value(attributes) : NULL;
> Also here, do we need to get existing attributes of a GFN first ?

No?  @entry is the new value that will be set for all entries.  This line 
doesn't
touch the xarray in any way.  Maybe I'm just not understanding your question.


[PATCH v4 15/20] EDAC/mc: Re-use generic unique MC index allocation procedure

2023-09-20 Thread Serge Semin
The EDAC drivers locally maintaining a statically defined
memory-controllers counter don't care much about the MC index assigned as
long as it's unique so the EDAC core perceives it. Convert these drivers
to be using the generic MC index allocation procedure recently added to
the EDAC core.

Signed-off-by: Serge Semin 

---

Changelog v4:
- Initial patch introduction.
---
 drivers/edac/dmc520_edac.c | 4 +---
 drivers/edac/pasemi_edac.c | 5 +
 drivers/edac/ppc4xx_edac.c | 5 +
 3 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/drivers/edac/dmc520_edac.c b/drivers/edac/dmc520_edac.c
index 1fa5ca57e9ec..abd73ed0ad89 100644
--- a/drivers/edac/dmc520_edac.c
+++ b/drivers/edac/dmc520_edac.c
@@ -173,8 +173,6 @@ struct dmc520_edac {
int masks[NUMBER_OF_IRQS];
 };
 
-static int dmc520_mc_idx;
-
 static u32 dmc520_read_reg(struct dmc520_edac *pvt, u32 offset)
 {
return readl(pvt->reg_base + offset);
@@ -517,7 +515,7 @@ static int dmc520_edac_probe(struct platform_device *pdev)
layers[0].size = dmc520_get_rank_count(reg_base);
layers[0].is_virt_csrow = true;
 
-   mci = edac_mc_alloc(dmc520_mc_idx++, ARRAY_SIZE(layers), layers, 
sizeof(*pvt));
+   mci = edac_mc_alloc(EDAC_AUTO_MC_NUM, ARRAY_SIZE(layers), layers, 
sizeof(*pvt));
if (!mci) {
edac_printk(KERN_ERR, EDAC_MOD_NAME,
"Failed to allocate memory for mc instance\n");
diff --git a/drivers/edac/pasemi_edac.c b/drivers/edac/pasemi_edac.c
index 1a1c3296ccc8..afebfbda1ea0 100644
--- a/drivers/edac/pasemi_edac.c
+++ b/drivers/edac/pasemi_edac.c
@@ -57,8 +57,6 @@
 #define PASEMI_EDAC_ERROR_GRAIN64
 
 static int last_page_in_mmc;
-static int system_mmc_id;
-
 
 static u32 pasemi_edac_get_error_info(struct mem_ctl_info *mci)
 {
@@ -203,8 +201,7 @@ static int pasemi_edac_probe(struct pci_dev *pdev,
layers[1].type = EDAC_MC_LAYER_CHANNEL;
layers[1].size = PASEMI_EDAC_NR_CHANS;
layers[1].is_virt_csrow = false;
-   mci = edac_mc_alloc(system_mmc_id++, ARRAY_SIZE(layers), layers,
-   0);
+   mci = edac_mc_alloc(EDAC_AUTO_MC_NUM, ARRAY_SIZE(layers), layers, 0);
if (mci == NULL)
return -ENOMEM;
 
diff --git a/drivers/edac/ppc4xx_edac.c b/drivers/edac/ppc4xx_edac.c
index 046969b4e82e..2b3d66bd0c28 100644
--- a/drivers/edac/ppc4xx_edac.c
+++ b/drivers/edac/ppc4xx_edac.c
@@ -1214,7 +1214,6 @@ static int ppc4xx_edac_probe(struct platform_device *op)
const struct device_node *np = op->dev.of_node;
struct mem_ctl_info *mci = NULL;
struct edac_mc_layer layers[2];
-   static int ppc4xx_edac_instance;
 
/*
 * At this point, we only support the controller realized on
@@ -1265,7 +1264,7 @@ static int ppc4xx_edac_probe(struct platform_device *op)
layers[1].type = EDAC_MC_LAYER_CHANNEL;
layers[1].size = ppc4xx_edac_nr_chans;
layers[1].is_virt_csrow = false;
-   mci = edac_mc_alloc(ppc4xx_edac_instance, ARRAY_SIZE(layers), layers,
+   mci = edac_mc_alloc(EDAC_AUTO_MC_NUM, ARRAY_SIZE(layers), layers,
sizeof(struct ppc4xx_edac_pdata));
if (mci == NULL) {
ppc4xx_edac_printk(KERN_ERR, "%pOF: "
@@ -1303,8 +1302,6 @@ static int ppc4xx_edac_probe(struct platform_device *op)
goto fail1;
}
 
-   ppc4xx_edac_instance++;
-
return 0;
 
  fail1:
-- 
2.41.0



[PATCH rc] kvm: Prevent compiling virt/kvm/vfio.c unless VFIO is selected

2023-09-20 Thread Jason Gunthorpe
There are a bunch of reported randconfig failures now because of this,
something like:

>> arch/powerpc/kvm/../../../virt/kvm/vfio.c:89:7: warning: attribute 
>> declaration must precede definition [-Wignored-attributes]
   fn = symbol_get(vfio_file_iommu_group);
^
   include/linux/module.h:805:60: note: expanded from macro 'symbol_get'
   #define symbol_get(x) ({ extern typeof(x) x 
__attribute__((weak,visibility("hidden"))); &(x); })

It happens because the arch forces KVM_VFIO without knowing if VFIO is
even enabled.

Split the kconfig so the arch selects the usual HAVE_KVM_ARCH_VFIO and
then KVM_VFIO is only enabled if the arch wants it and VFIO is turned on.

Reported-by: kernel test robot 
Closes: 
https://lore.kernel.org/oe-kbuild-all/202308251949.5iiav0sz-...@intel.com/
Closes: 
https://lore.kernel.org/oe-kbuild-all/202309030741.82alacdg-...@intel.com/
Closes: 
https://lore.kernel.org/oe-kbuild-all/202309110914.qlh0lu6l-...@intel.com/
Cc: Nick Desaulniers 
Fixes: c1cce6d079b8 ("vfio: Compile vfio_group infrastructure optionally")
Signed-off-by: Jason Gunthorpe 
---
 arch/arm64/kvm/Kconfig   | 2 +-
 arch/powerpc/kvm/Kconfig | 2 +-
 arch/s390/kvm/Kconfig| 2 +-
 arch/x86/kvm/Kconfig | 2 +-
 virt/kvm/Kconfig | 7 ++-
 5 files changed, 10 insertions(+), 5 deletions(-)

Sean's large series will also address this:

https://lore.kernel.org/kvm/20230916003118.2540661-7-sea...@google.com/

I don't know if it is sever enough to fix in the rc cycle, but here is the
patch.

diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 83c1e09be42e5b..7c43eaea51ce05 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -28,7 +28,7 @@ menuconfig KVM
select KVM_MMIO
select KVM_GENERIC_DIRTYLOG_READ_PROTECT
select KVM_XFER_TO_GUEST_WORK
-   select KVM_VFIO
+   select HAVE_KVM_ARCH_VFIO
select HAVE_KVM_EVENTFD
select HAVE_KVM_IRQFD
select HAVE_KVM_DIRTY_RING_ACQ_REL
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index 902611954200df..b64824e4cbc1eb 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -22,7 +22,7 @@ config KVM
select PREEMPT_NOTIFIERS
select HAVE_KVM_EVENTFD
select HAVE_KVM_VCPU_ASYNC_IOCTL
-   select KVM_VFIO
+   select HAVE_KVM_ARCH_VFIO
select IRQ_BYPASS_MANAGER
select HAVE_KVM_IRQ_BYPASS
select INTERVAL_TREE
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig
index 45fdf2a9b2e326..d206ad3a777d5d 100644
--- a/arch/s390/kvm/Kconfig
+++ b/arch/s390/kvm/Kconfig
@@ -31,7 +31,7 @@ config KVM
select HAVE_KVM_IRQ_ROUTING
select HAVE_KVM_INVALID_WAKEUPS
select HAVE_KVM_NO_POLL
-   select KVM_VFIO
+   select HAVE_KVM_ARCH_VFIO
select INTERVAL_TREE
select MMU_NOTIFIER
help
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index ed90f148140dfe..8e70e693f90e30 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -45,7 +45,7 @@ config KVM
select HAVE_KVM_NO_POLL
select KVM_XFER_TO_GUEST_WORK
select KVM_GENERIC_DIRTYLOG_READ_PROTECT
-   select KVM_VFIO
+   select HAVE_KVM_ARCH_VFIO
select INTERVAL_TREE
select HAVE_KVM_PM_NOTIFIER if PM
select KVM_GENERIC_HARDWARE_ENABLING
diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig
index 484d0873061ca5..0bf34809e1bbfe 100644
--- a/virt/kvm/Kconfig
+++ b/virt/kvm/Kconfig
@@ -59,9 +59,14 @@ config HAVE_KVM_MSI
 config HAVE_KVM_CPU_RELAX_INTERCEPT
bool
 
-config KVM_VFIO
+config HAVE_KVM_ARCH_VFIO
bool
 
+config KVM_VFIO
+   def_bool y
+   depends on HAVE_KVM_ARCH_VFIO
+   depends on VFIO
+
 config HAVE_KVM_INVALID_WAKEUPS
bool
 

base-commit: 0bb80ecc33a8fb5a682236443c1e740d5c917d1d
-- 
2.42.0



Re: [PATCH 0/7] arch/*: config: Remove ReiserFS from defconfig

2023-09-20 Thread Jan Kara
On Tue 19-09-23 18:02:39, Geert Uytterhoeven wrote:
> Hi Peter,
> 
> On Tue, Sep 19, 2023 at 5:58 PM Peter Lafreniere  wrote:
> >  2) Stops building an obsolete and largely-unused filesystem unnecessarily.
> > Some hobbyist targets like m68k and alpha may prefer to keep all 
> > filesystems
> > available until total removal, but others like arm and UML have no need 
> > for
> > ReiserFS to be built unless specifically configured.
> 
> As UML is used a lot for testing, isn't it actually counter-productive
> to remove ReiserFS from the UML defconfig?  The less testing it
> receives, the higher the chance of introducing regressions.

The only testing I know about for reiserfs (besides build testing) is
syzbot. And regarding the people / bots doing filesystem testing I know
none of them uses UML. Rather it is x86 VMs these days where reiserfs is
disabled in the defconfig for a *long* time (many years). Also when you do
filesystem testing, you usually just test the few filesystems you care
about and for which you have all the tools installed. So frankly I don't
see a good reason to leave reiserfs enabled in defconfigs. But sure if
m68k or other arch wants to keep reiserfs in it's defconfig for some
consistency reasons, I'm fine with it. I just suspect that for most archs
this is just a historical reason.

Honza
-- 
Jan Kara 
SUSE Labs, CR


Re: linux-next: Tree for Sep 20 (ppc32: ADB_CUDA Kconfig warning)

2023-09-20 Thread Randy Dunlap


On 9/19/23 20:37, Stephen Rothwell wrote:
> Hi all,
> 
> Changes since 20230919:
> 
> The mm tree lost its boot warning.
> 
> The drm-misc tree gained a conflict against Linus' tree.
> 
> Non-merge commits (relative to Linus' tree): 6006
>  3996 files changed, 459968 insertions(+), 111742 deletions(-)
> 
> 

4 out of 10 randconfigs have this warning:

WARNING: unmet direct dependencies detected for ADB_CUDA
  Depends on [n]: MACINTOSH_DRIVERS [=n] && (ADB [=n] || PPC_PMAC [=y]) && 
!PPC_PMAC64 [=n]
  Selected by [y]:
  - PPC_PMAC [=y] && PPC_BOOK3S [=y] && CPU_BIG_ENDIAN [=y] && POWER_RESET [=y] 
&& PPC32 [=y]

WARNING: unmet direct dependencies detected for ADB_CUDA
  Depends on [n]: MACINTOSH_DRIVERS [=n] && (ADB [=n] || PPC_PMAC [=y]) && 
!PPC_PMAC64 [=n]
  Selected by [y]:
  - PPC_PMAC [=y] && PPC_BOOK3S [=y] && CPU_BIG_ENDIAN [=y] && POWER_RESET [=y] 
&& PPC32 [=y]

WARNING: unmet direct dependencies detected for ADB_CUDA
  Depends on [n]: MACINTOSH_DRIVERS [=n] && (ADB [=n] || PPC_PMAC [=y]) && 
!PPC_PMAC64 [=n]
  Selected by [y]:
  - PPC_PMAC [=y] && PPC_BOOK3S [=y] && CPU_BIG_ENDIAN [=y] && POWER_RESET [=y] 
&& PPC32 [=y]


One failing randconfig file is attached.
-- 
~Randy

config-r7483.gz
Description: application/gzip


Re: [PATCH v10 13/15] PCI/AER: Forward RCH downstream port-detected errors to the CXL.mem dev handler

2023-09-20 Thread Terry Bowman
Hi Dan,

I adde danothe comment below.

On 9/19/23 15:58, Terry Bowman wrote:
> Hi Dan,
> 
> On 8/31/23 15:35, Dan Williams wrote:
>> Terry Bowman wrote:
>>> From: Robert Richter 
>>>
>>> In Restricted CXL Device (RCD) mode a CXL device is exposed as an
>>> RCiEP, but CXL downstream and upstream ports are not enumerated and
>>> not visible in the PCIe hierarchy. [1] Protocol and link errors from
>>> these non-enumerated ports are signaled as internal AER errors, either
>>> Uncorrectable Internal Error (UIE) or Corrected Internal Errors (CIE)
>>> via an RCEC.
>>>
>>> Restricted CXL host (RCH) downstream port-detected errors have the
>>> Requester ID of the RCEC set in the RCEC's AER Error Source ID
>>> register. A CXL handler must then inspect the error status in various
>>> CXL registers residing in the dport's component register space (CXL
>>> RAS capability) or the dport's RCRB (PCIe AER extended
>>> capability). [2]
>>>
>>> Errors showing up in the RCEC's error handler must be handled and
>>> connected to the CXL subsystem. Implement this by forwarding the error
>>> to all CXL devices below the RCEC. Since the entire CXL device is
>>> controlled only using PCIe Configuration Space of device 0, function
>>> 0, only pass it there [3]. The error handling is limited to currently
>>> supported devices with the Memory Device class code set (CXL Type 3
>>> Device, PCI_CLASS_MEMORY_CXL, 502h), handle downstream port errors in
>>> the device's cxl_pci driver. Support for other CXL Device Types
>>> (e.g. a CXL.cache Device) can be added later.
>>>
>>> To handle downstream port errors in addition to errors directed to the
>>> CXL endpoint device, a handler must also inspect the CXL RAS and PCIe
>>> AER capabilities of the CXL downstream port the device is connected
>>> to.
>>>
>>> Since CXL downstream port errors are signaled using internal errors,
>>> the handler requires those errors to be unmasked. This is subject of a
>>> follow-on patch.
>>>
>>> The reason for choosing this implementation is that the AER service
>>> driver claims the RCEC device, but does not allow it to register a
>>> custom specific handler to support CXL. Connecting the RCEC hard-wired
>>> with a CXL handler does not work, as the CXL subsystem might not be
>>> present all the time. The alternative to add an implementation to the
>>> portdrv to allow the registration of a custom RCEC error handler isn't
>>> worth doing it as CXL would be its only user. Instead, just check for
>>> an CXL RCEC and pass it down to the connected CXL device's error
>>> handler. With this approach the code can entirely be implemented in
>>> the PCIe AER driver and is independent of the CXL subsystem. The CXL
>>> driver only provides the handler.
>>>
>>> [1] CXL 3.0 spec: 9.11.8 CXL Devices Attached to an RCH
>>> [2] CXL 3.0 spec, 12.2.1.1 RCH Downstream Port-detected Errors
>>> [3] CXL 3.0 spec, 8.1.3 PCIe DVSEC for CXL Devices
>>>
>>> Co-developed-by: Terry Bowman 
>>> Signed-off-by: Terry Bowman 
>>> Signed-off-by: Robert Richter 
>>> Cc: "Oliver O'Halloran" 
>>> Cc: Bjorn Helgaas 
>>> Cc: linuxppc-dev@lists.ozlabs.org
>>> Cc: linux-...@vger.kernel.org
>>> Acked-by: Bjorn Helgaas 
>>> Reviewed-by: Jonathan Cameron 
>>> Reviewed-by: Dave Jiang 
>>> ---
>>>  drivers/pci/pcie/Kconfig | 12 +
>>>  drivers/pci/pcie/aer.c   | 96 +++-
>>>  2 files changed, 106 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig
>>> index 228652a59f27..4f0e70fafe2d 100644
>>> --- a/drivers/pci/pcie/Kconfig
>>> +++ b/drivers/pci/pcie/Kconfig
>>> @@ -49,6 +49,18 @@ config PCIEAER_INJECT
>>>   gotten from:
>>>  
>>> https://git.kernel.org/cgit/linux/kernel/git/gong.chen/aer-inject.git/
>>>  
>>> +config PCIEAER_CXL
>>> +   bool "PCI Express CXL RAS support for Restricted Hosts (RCH)"
>>
>> Why the "for Restricted Hosts (RCH)" clarification? I am seeing nothing
>> that prevents this from working with RCECs on VH topologies.
>>
> 
> The same option can be used in VH mode. Will remove the RCH reference.
> 
>>
>>> +   default y
>>
>> Minor, but I think "default PCIEAER" makes it slightly clearer that CXL
>> error handling comes along for the ride with PCIE AER.
>>
> 
> We found Kconfig entries do not typically list a dependancy and the default 
> to be the same. We prefer to leave as 'default y'. If you want we can make 
> your requested change. 
> 
>>> +   depends on PCIEAER && CXL_PCI
>>> +   help
>>> + Enables error handling of downstream ports of a CXL host
>>> + that is operating in RCD mode (Restricted CXL Host, RCH).
>>> + The downstream port reports AER errors to a given RCEC.
>>> + Errors are handled by the CXL memory device driver.
>>> +
>>> + If unsure, say Y.
>>> +
>>>  #
>>>  # PCI Express ECRC
>>>  #
>>> diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
>>> index d3344fcf1f79..c354ca5e8f2b 100644
>>> --- a/drivers/pci/pcie/aer.c
>>> +++ 

Re: [PATCH v4 0/5] ppc, fbdev: Clean up fbdev mmap helper

2023-09-20 Thread Arnd Bergmann
On Tue, Sep 12, 2023, at 09:48, Thomas Zimmermann wrote:
> Clean up and rename fb_pgprotect() to work without struct file. Then
> refactor the implementation for PowerPC. This change has been discussed
> at [1] in the context of refactoring fbdev's mmap code.
>
> The first two patches update fbdev and replace fbdev's fb_pgprotect()
> with pgprot_framebuffer() on all architectures. The new helper's stream-
> lined interface enables more refactoring within fbdev's mmap
> implementation.
>
> Patches 3 to 5 adapt PowerPC's internal interfaces to provide
> phys_mem_access_prot() that works without struct file. Neither the
> architecture code or fbdev helpers need the parameter.
>
> v4:
>   * fix commit message (Christophe)
> v3:
>   * rename fb_pgrotect() to pgprot_framebuffer() (Arnd)

I had another look today, and everything look good to me now.

Whole series

Reviewed-by: Arnd Bergmann 


Re: [PATCH] i2c: replace deprecated strncpy

2023-09-20 Thread Kees Cook
On Wed, Sep 20, 2023 at 11:07:35AM +, Justin Stitt wrote:
> `strncpy` is deprecated for use on NUL-terminated destination strings [1].
> 
> We should prefer more robust and less ambiguous string interfaces.
> 
> `info.type` is expected to be NUL-terminated judging by its use in
> `i2c_new_client_device()` wherein it is used to populate `client->name`:
> | strscpy(client->name, info->type, sizeof(client->name));
> 
> NUL-padding is not required and even if it was, `client` is already
> zero-initialized.
> 
> Considering the two points from above, a suitable replacement is
> `strscpy` [2] due to the fact that it guarantees NUL-termination on the
> destination buffer without unnecessarily NUL-padding.
> 
> Link: 
> https://www.kernel.org/doc/html/latest/process/deprecated.html#strncpy-on-nul-terminated-strings
>  [1]
> Link: https://manpages.debian.org/testing/linux-manual-4.8/strscpy.9.en.html 
> [2]
> Link: https://github.com/KSPP/linux/issues/90
> Cc: linux-harden...@vger.kernel.org
> Signed-off-by: Justin Stitt 

Looks like a straight replacement. Thanks!

Reviewed-by: Kees Cook 

-- 
Kees Cook


Re: [RFC PATCH v12 14/33] KVM: Add KVM_CREATE_GUEST_MEMFD ioctl() for guest-specific backing memory

2023-09-20 Thread Sean Christopherson
On Tue, Sep 19, 2023, Binbin Wu wrote:
> 
> 
> On 9/14/2023 9:55 AM, Sean Christopherson wrote:
> [...]
> > +
> > +static void kvm_gmem_invalidate_begin(struct kvm_gmem *gmem, pgoff_t start,
> > + pgoff_t end)
> > +{
> > +   struct kvm_memory_slot *slot;
> > +   struct kvm *kvm = gmem->kvm;
> > +   unsigned long index;
> > +   bool flush = false;
> > +
> > +   KVM_MMU_LOCK(kvm);
> > +
> > +   kvm_mmu_invalidate_begin(kvm);
> > +
> > +   xa_for_each_range(>bindings, index, slot, start, end - 1) {
> > +   pgoff_t pgoff = slot->gmem.pgoff;
> > +
> > +   struct kvm_gfn_range gfn_range = {
> > +   .start = slot->base_gfn + max(pgoff, start) - pgoff,
> > +   .end = slot->base_gfn + min(pgoff + slot->npages, end) 
> > - pgoff,
> > +   .slot = slot,
> > +   .may_block = true,
> > +   };
> > +
> > +   flush |= kvm_mmu_unmap_gfn_range(kvm, _range);
> > +   }
> > +
> > +   if (flush)
> > +   kvm_flush_remote_tlbs(kvm);
> > +
> > +   KVM_MMU_UNLOCK(kvm);
> > +}
> > +
> > +static void kvm_gmem_invalidate_end(struct kvm_gmem *gmem, pgoff_t start,
> > +   pgoff_t end)
> > +{
> > +   struct kvm *kvm = gmem->kvm;
> > +
> > +   KVM_MMU_LOCK(kvm);
> > +   if (xa_find(>bindings, , end - 1, XA_PRESENT))
> > +   kvm_mmu_invalidate_end(kvm);
> kvm_mmu_invalidate_begin() is called unconditionally in
> kvm_gmem_invalidate_begin(),
> but kvm_mmu_invalidate_end() is not here.
> This makes the kvm_gmem_invalidate_{begin, end}() calls asymmetric.

Another ouch :-(

And there should be no need to acquire mmu_lock() unconditionally, the inode's
mutex protects the bindings, not mmu_lock.

I'll get a fix posted today.  I think KVM can also add a sanity check to detect
unresolved invalidations, e.g.

diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 7ba1ab1832a9..2a2d18070856 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1381,8 +1381,13 @@ static void kvm_destroy_vm(struct kvm *kvm)
 * No threads can be waiting in kvm_swap_active_memslots() as the
 * last reference on KVM has been dropped, but freeing
 * memslots would deadlock without this manual intervention.
+*
+* If the count isn't unbalanced, i.e. KVM did NOT unregister between
+* a start() and end(), then there shouldn't be any in-progress
+* invalidations.
 */
WARN_ON(rcuwait_active(>mn_memslots_update_rcuwait));
+   WARN_ON(!kvm->mn_active_invalidate_count && 
kvm->mmu_invalidate_in_progress);
kvm->mn_active_invalidate_count = 0;
 #else
kvm_flush_shadow_all(kvm);


or an alternative style

if (kvm->mn_active_invalidate_count)
kvm->mn_active_invalidate_count = 0;
else
WARN_ON(kvm->mmu_invalidate_in_progress)

> > +   KVM_MMU_UNLOCK(kvm);
> > +}
> > +
> > +static long kvm_gmem_punch_hole(struct inode *inode, loff_t offset, loff_t 
> > len)
> > +{
> > +   struct list_head *gmem_list = >i_mapping->private_list;
> > +   pgoff_t start = offset >> PAGE_SHIFT;
> > +   pgoff_t end = (offset + len) >> PAGE_SHIFT;
> > +   struct kvm_gmem *gmem;
> > +
> > +   /*
> > +* Bindings must stable across invalidation to ensure the start+end
> > +* are balanced.
> > +*/
> > +   filemap_invalidate_lock(inode->i_mapping);
> > +
> > +   list_for_each_entry(gmem, gmem_list, entry) {
> > +   kvm_gmem_invalidate_begin(gmem, start, end);
> > +   kvm_gmem_invalidate_end(gmem, start, end);
> > +   }
> Why to loop for each gmem in gmem_list here?
> 
> IIUIC, offset is the offset according to the inode, it is only meaningful to
> the inode passed in, i.e, it is only meaningful to the gmem binding with the
> inode, not others.

The code is structured to allow for multiple gmem instances per inode.  This 
isn't
actually possible in the initial code base, but it's on the horizon[*].  I 
included
the list-based infrastructure in this initial series to ensure that guest_memfd
can actually support multiple files per inode, and to minimize the churn when 
the
"link" support comes along.

[*] https://lore.kernel.org/all/cover.1691446946.git.ackerley...@google.com



Re: [PATCH v2 1/2] powerpc: add `cur_cpu_spec` symbol to vmcoreinfo

2023-09-20 Thread Aditya Gupta
On Wed, Sep 20, 2023 at 05:45:36PM +0530, Aneesh Kumar K.V wrote:
> Aditya Gupta  writes:
> 
> > Since below commit, address mapping for vmemmap has changed for Radix
> > MMU, where address mapping is stored in kernel page table itself,
> > instead of earlier used 'vmemmap_list'.
> >
> > commit 368a0590d954 ("powerpc/book3s64/vmemmap: switch radix to use
> > a different vmemmap handling function")
> >
> > Hence with upstream kernel, in case of Radix MMU, makedumpfile fails to do
> > address translation for vmemmap addresses, as it depended on vmemmap_list,
> > which can now be empty.
> >
> > While fixing the address translation in makedumpfile, it was identified
> > that currently makedumpfile cannot distinguish between Hash MMU and
> > Radix MMU, unless VMLINUX is passed with -x flag to makedumpfile.
> > And hence fails to assign offsets and shifts correctly (such as in L4 to
> > PGDIR offset calculation in makedumpfile).
> >
> > For getting the MMU, makedumpfile uses `cur_cpu_spec.mmu_features`.
> >
> > Add `cur_cpu_spec` symbol and offset of `mmu_features` in the
> > `cpu_spec` struct, to VMCOREINFO, so that makedumpfile can assign the
> > offsets correctly, without needing a VMLINUX.
> >
> > Fixes: 368a0590d954 ("powerpc/book3s64/vmemmap: switch radix to use a 
> > different vmemmap handling function")
> > Reported-by: Sachin Sant 
> > Tested-by: Sachin Sant 
> > Signed-off-by: Aditya Gupta 
> >
> > ---
> > Corresponding makedumpfile patches to fix address translation, in Radix
> > MMU case:
> >
> > Link: 
> > https://lore.kernel.org/kexec/b5f0f00e-f2b1-47d7-a143-5683d10dc...@linux.ibm.com/T/#t
> > ---
> > ---
> >  arch/powerpc/kexec/core.c | 2 ++
> >  1 file changed, 2 insertions(+)
> >
> > diff --git a/arch/powerpc/kexec/core.c b/arch/powerpc/kexec/core.c
> > index de64c7962991..369b8334a4f0 100644
> > --- a/arch/powerpc/kexec/core.c
> > +++ b/arch/powerpc/kexec/core.c
> > @@ -63,6 +63,8 @@ void arch_crash_save_vmcoreinfo(void)
> >  #ifndef CONFIG_NUMA
> > VMCOREINFO_SYMBOL(contig_page_data);
> >  #endif
> > +   VMCOREINFO_SYMBOL(cur_cpu_spec);
> > +   VMCOREINFO_OFFSET(cpu_spec, mmu_features);
> >  #if defined(CONFIG_PPC64) && defined(CONFIG_SPARSEMEM_VMEMMAP)
> > VMCOREINFO_SYMBOL(vmemmap_list);
> > VMCOREINFO_SYMBOL(mmu_vmemmap_psize);
> >
> 
> That implies we now have to be careful when updating MMU_FTR_* #defines.
> It is not bad considering other hacks we do in crash to identify kernel
> changes tied to version number. But i am wondering if there another way
> to identify radix vs hash?
> 

I could not find another way to get any other flag for RADIX vs HASH in
makedumpfile. And currently I don't know of any other way.

Both makedumpfile and crash look for '0x40' flag set in
'cur_cpu_spec.mmu_features', so only requirement for 'MMU_FTR_TYPE_RADIX' is to
be '0x40', or we will need to change the value accordingly in the tools.

Thanks,
- Aditya Gupta



Re: Recent Power changes and stack_trace_save_tsk_reliable?

2023-09-20 Thread Petr Mladek
On Wed 2023-08-30 17:47:35, Joe Lawrence wrote:
> On 8/30/23 02:37, Michael Ellerman wrote:
> > Michael Ellerman  writes:
> >> Joe Lawrence  writes:
> >>> Hi ppc-dev list,
> >>>
> >>> We noticed that our kpatch integration tests started failing on ppc64le
> >>> when targeting the upstream v6.4 kernel, and then confirmed that the
> >>> in-tree livepatching kselftests similarly fail, too.  From the kselftest
> >>> results, it appears that livepatch transitions are no longer completing.
> >>
> >> Hi Joe,
> >>
> >> Thanks for the report.
> >>
> >> I thought I was running the livepatch tests, but looks like somewhere
> >> along the line my kernel .config lost CONFIG_TEST_LIVEPATCH=m, so I have
> >> been running the test but it just skips. :/
> >>
> 
> That config option is easy to drop if you use `make localmodconfig` to
> try and expedite the builds :D  Been there, done that too many times.
> 
> >> I can reproduce the failure, and will see if I can bisect it more
> >> successfully.
> > 
> > It's caused by:
> > 
> >   eed7c420aac7 ("powerpc: copy_thread differentiate kthreads and user mode 
> > threads")
> > 
> > Which is obvious in hindsight :)
> > 
> > The diff below fixes it for me, can you test that on your setup?
> > 
> 
> Thanks for the fast triage of this one.  The proposed fix works well on
> our setup.  I have yet to try the kpatch integration tests with this,
> but I can verify that all of the kernel livepatching kselftests now
> happily run.

Have this been somehow handled, please? I do not see the proposed
change in linux-next as of now.

> > A proper fix will need to be a bit bigger because the comments in there
> > are all slightly wrong now since the above commit.
> > 
> > Possibly we can also rework that code more substantially now that
> > copy_thread() is more careful about setting things up, but that would be
> > a follow-up.
> > 
> > diff --git a/arch/powerpc/kernel/stacktrace.c 
> > b/arch/powerpc/kernel/stacktrace.c
> > index 5de8597eaab8..d0b3509f13ee 100644
> > --- a/arch/powerpc/kernel/stacktrace.c
> > +++ b/arch/powerpc/kernel/stacktrace.c
> > @@ -73,7 +73,7 @@ int __no_sanitize_address 
> > arch_stack_walk_reliable(stack_trace_consume_fn consum
> > bool firstframe;
> >  
> > stack_end = stack_page + THREAD_SIZE;
> > -   if (!is_idle_task(task)) {
> > +   if (!(task->flags & PF_KTHREAD)) {
> > /*
> >  * For user tasks, this is the SP value loaded on
> >  * kernel entry, see "PACAKSAVE(r13)" in _switch() and

If I read the change in the commit eed7c420aac7fde ("powerpc: copy_thread
differentiate kthreads and user mode threads") correctly then the
above fix is correct.

It is probably just enough to update the comment about that
STACK_FRAME_MIN_SIZE is used by all kthreads.

Best Regards,
Petr


Re: [RFC PATCH v12 02/33] KVM: Use gfn instead of hva for mmu_notifier_retry

2023-09-20 Thread Sean Christopherson
On Wed, Sep 20, 2023, Xu Yilun wrote:
> On 2023-09-13 at 18:55:00 -0700, Sean Christopherson wrote:
> > +void kvm_mmu_invalidate_range_add(struct kvm *kvm, gfn_t start, gfn_t end)
> > +{
> > +   lockdep_assert_held_write(>mmu_lock);
> > +
> > +   WARN_ON_ONCE(!kvm->mmu_invalidate_in_progress);
> > +
> > if (likely(kvm->mmu_invalidate_in_progress == 1)) {
> > kvm->mmu_invalidate_range_start = start;
> > kvm->mmu_invalidate_range_end = end;
> 
> IIUC, Now we only add or override a part of the invalidate range in
> these fields, IOW only the range in last slot is stored when we unlock.

Ouch.  Good catch!

> That may break mmu_invalidate_retry_gfn() cause it can never know the
> whole invalidate range.
> 
> How about we extend the mmu_invalidate_range_start/end everytime so that
> it records the whole invalidate range:
> 
> if (kvm->mmu_invalidate_range_start == INVALID_GPA) {
>   kvm->mmu_invalidate_range_start = start;
>   kvm->mmu_invalidate_range_end = end;
> } else {
>   kvm->mmu_invalidate_range_start =
>   min(kvm->mmu_invalidate_range_start, start);
>   kvm->mmu_invalidate_range_end =
>   max(kvm->mmu_invalidate_range_end, end);
> }

Yeah, that does seem to be the easiest solution.

I'll post a fixup patch, unless you want the honors.


Re: [PATCH v2 1/2] powerpc: add `cur_cpu_spec` symbol to vmcoreinfo

2023-09-20 Thread Aneesh Kumar K.V
Aditya Gupta  writes:

> Since below commit, address mapping for vmemmap has changed for Radix
> MMU, where address mapping is stored in kernel page table itself,
> instead of earlier used 'vmemmap_list'.
>
> commit 368a0590d954 ("powerpc/book3s64/vmemmap: switch radix to use
> a different vmemmap handling function")
>
> Hence with upstream kernel, in case of Radix MMU, makedumpfile fails to do
> address translation for vmemmap addresses, as it depended on vmemmap_list,
> which can now be empty.
>
> While fixing the address translation in makedumpfile, it was identified
> that currently makedumpfile cannot distinguish between Hash MMU and
> Radix MMU, unless VMLINUX is passed with -x flag to makedumpfile.
> And hence fails to assign offsets and shifts correctly (such as in L4 to
> PGDIR offset calculation in makedumpfile).
>
> For getting the MMU, makedumpfile uses `cur_cpu_spec.mmu_features`.
>
> Add `cur_cpu_spec` symbol and offset of `mmu_features` in the
> `cpu_spec` struct, to VMCOREINFO, so that makedumpfile can assign the
> offsets correctly, without needing a VMLINUX.
>
> Fixes: 368a0590d954 ("powerpc/book3s64/vmemmap: switch radix to use a 
> different vmemmap handling function")
> Reported-by: Sachin Sant 
> Tested-by: Sachin Sant 
> Signed-off-by: Aditya Gupta 
>
> ---
> Corresponding makedumpfile patches to fix address translation, in Radix
> MMU case:
>
> Link: 
> https://lore.kernel.org/kexec/b5f0f00e-f2b1-47d7-a143-5683d10dc...@linux.ibm.com/T/#t
> ---
> ---
>  arch/powerpc/kexec/core.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/arch/powerpc/kexec/core.c b/arch/powerpc/kexec/core.c
> index de64c7962991..369b8334a4f0 100644
> --- a/arch/powerpc/kexec/core.c
> +++ b/arch/powerpc/kexec/core.c
> @@ -63,6 +63,8 @@ void arch_crash_save_vmcoreinfo(void)
>  #ifndef CONFIG_NUMA
>   VMCOREINFO_SYMBOL(contig_page_data);
>  #endif
> + VMCOREINFO_SYMBOL(cur_cpu_spec);
> + VMCOREINFO_OFFSET(cpu_spec, mmu_features);
>  #if defined(CONFIG_PPC64) && defined(CONFIG_SPARSEMEM_VMEMMAP)
>   VMCOREINFO_SYMBOL(vmemmap_list);
>   VMCOREINFO_SYMBOL(mmu_vmemmap_psize);
>

That implies we now have to be careful when updating MMU_FTR_* #defines.
It is not bad considering other hacks we do in crash to identify kernel
changes tied to version number. But i am wondering if there another way
to identify radix vs hash?

-aneesh


[PATCH] i2c: replace deprecated strncpy

2023-09-20 Thread Justin Stitt
`strncpy` is deprecated for use on NUL-terminated destination strings [1].

We should prefer more robust and less ambiguous string interfaces.

`info.type` is expected to be NUL-terminated judging by its use in
`i2c_new_client_device()` wherein it is used to populate `client->name`:
|   strscpy(client->name, info->type, sizeof(client->name));

NUL-padding is not required and even if it was, `client` is already
zero-initialized.

Considering the two points from above, a suitable replacement is
`strscpy` [2] due to the fact that it guarantees NUL-termination on the
destination buffer without unnecessarily NUL-padding.

Link: 
https://www.kernel.org/doc/html/latest/process/deprecated.html#strncpy-on-nul-terminated-strings
 [1]
Link: https://manpages.debian.org/testing/linux-manual-4.8/strscpy.9.en.html [2]
Link: https://github.com/KSPP/linux/issues/90
Cc: linux-harden...@vger.kernel.org
Signed-off-by: Justin Stitt 
---
 drivers/i2c/busses/i2c-powermac.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-powermac.c 
b/drivers/i2c/busses/i2c-powermac.c
index 4996a628fdae..8e57ebe595be 100644
--- a/drivers/i2c/busses/i2c-powermac.c
+++ b/drivers/i2c/busses/i2c-powermac.c
@@ -231,7 +231,7 @@ static void i2c_powermac_create_one(struct i2c_adapter 
*adap,
struct i2c_board_info info = {};
struct i2c_client *newdev;
 
-   strncpy(info.type, type, sizeof(info.type));
+   strscpy(info.type, type, sizeof(info.type));
info.addr = addr;
newdev = i2c_new_client_device(adap, );
if (IS_ERR(newdev))

---
base-commit: 2cf0f715623872823a72e451243bbf555d10d032
change-id: 20230920-strncpy-drivers-i2c-busses-i2c-powermac-c-a95017b69711

Best regards,
--
Justin Stitt 



Re: [PATCH] powerpc: add `cur_cpu_spec` symbol to vmcoreinfo

2023-09-20 Thread Aditya Gupta
On Tue, Sep 19, 2023 at 08:07:15PM +1000, Michael Ellerman wrote:
> Aditya Gupta  writes:
> > On Thu, Sep 14, 2023 at 11:22:01PM +1000, Michael Ellerman wrote:
> >> Aditya Gupta  writes:
> >> > Presently, while reading a vmcore, makedumpfile uses
> >> > `cur_cpu_spec.mmu_features` to decide whether the crashed system had
> >> > RADIX MMU or not.
> >> >
> >> > Currently, makedumpfile fails to get the `cur_cpu_spec` symbol (unless
> >> > a vmlinux is passed with the `-x` flag to makedumpfile), and hence
> >> > assigns offsets and shifts (such as pgd_offset_l4) incorrecly considering
> >> > MMU to be hash MMU.
> >> >
> >> > Add `cur_cpu_spec` symbol and offset of `mmu_features` in the
> >> > `cpu_spec` struct, to VMCOREINFO, so that the symbol address and offset
> >> > is accessible to makedumpfile, without needing the vmlinux file
> >> 
> >> This looks fine.
> >> 
> >> Seems like cpu_features would be needed or at least pretty useful too?
> >> 
> >> cheers
> >
> > Sure, that can be added too, to the vmcoreinfo. Not sure if it's used now, 
> > but
> > sure it can help to identify features in makedumpfile.
> >
> > Will add it, in next version.
> 
> Please do it in a separate commit to the mmu_features :)
> 
> cheers

Sure, have done it in a separate patch in V2.

Thanks


[PATCH v2 1/2] powerpc: add `cur_cpu_spec` symbol to vmcoreinfo

2023-09-20 Thread Aditya Gupta
Since below commit, address mapping for vmemmap has changed for Radix
MMU, where address mapping is stored in kernel page table itself,
instead of earlier used 'vmemmap_list'.

commit 368a0590d954 ("powerpc/book3s64/vmemmap: switch radix to use
a different vmemmap handling function")

Hence with upstream kernel, in case of Radix MMU, makedumpfile fails to do
address translation for vmemmap addresses, as it depended on vmemmap_list,
which can now be empty.

While fixing the address translation in makedumpfile, it was identified
that currently makedumpfile cannot distinguish between Hash MMU and
Radix MMU, unless VMLINUX is passed with -x flag to makedumpfile.
And hence fails to assign offsets and shifts correctly (such as in L4 to
PGDIR offset calculation in makedumpfile).

For getting the MMU, makedumpfile uses `cur_cpu_spec.mmu_features`.

Add `cur_cpu_spec` symbol and offset of `mmu_features` in the
`cpu_spec` struct, to VMCOREINFO, so that makedumpfile can assign the
offsets correctly, without needing a VMLINUX.

Fixes: 368a0590d954 ("powerpc/book3s64/vmemmap: switch radix to use a different 
vmemmap handling function")
Reported-by: Sachin Sant 
Tested-by: Sachin Sant 
Signed-off-by: Aditya Gupta 

---
Corresponding makedumpfile patches to fix address translation, in Radix
MMU case:

Link: 
https://lore.kernel.org/kexec/b5f0f00e-f2b1-47d7-a143-5683d10dc...@linux.ibm.com/T/#t
---
---
 arch/powerpc/kexec/core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/powerpc/kexec/core.c b/arch/powerpc/kexec/core.c
index de64c7962991..369b8334a4f0 100644
--- a/arch/powerpc/kexec/core.c
+++ b/arch/powerpc/kexec/core.c
@@ -63,6 +63,8 @@ void arch_crash_save_vmcoreinfo(void)
 #ifndef CONFIG_NUMA
VMCOREINFO_SYMBOL(contig_page_data);
 #endif
+   VMCOREINFO_SYMBOL(cur_cpu_spec);
+   VMCOREINFO_OFFSET(cpu_spec, mmu_features);
 #if defined(CONFIG_PPC64) && defined(CONFIG_SPARSEMEM_VMEMMAP)
VMCOREINFO_SYMBOL(vmemmap_list);
VMCOREINFO_SYMBOL(mmu_vmemmap_psize);
-- 
2.41.0



[PATCH v2 2/2] powerpc: add cpu_spec.cpu_features to vmcoreinfo

2023-09-20 Thread Aditya Gupta
CPU features can be determined in makedumpfile, using
'cur_cpu_spec.cpu_features'.

This provides more data to makedumpfile about the crashed system, and
can help in filtering the vmcore accordingly.

Signed-off-by: Aditya Gupta 
---
 arch/powerpc/kexec/core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/kexec/core.c b/arch/powerpc/kexec/core.c
index 369b8334a4f0..0d70c7ea820c 100644
--- a/arch/powerpc/kexec/core.c
+++ b/arch/powerpc/kexec/core.c
@@ -64,6 +64,7 @@ void arch_crash_save_vmcoreinfo(void)
VMCOREINFO_SYMBOL(contig_page_data);
 #endif
VMCOREINFO_SYMBOL(cur_cpu_spec);
+   VMCOREINFO_OFFSET(cpu_spec, cpu_features);
VMCOREINFO_OFFSET(cpu_spec, mmu_features);
 #if defined(CONFIG_PPC64) && defined(CONFIG_SPARSEMEM_VMEMMAP)
VMCOREINFO_SYMBOL(vmemmap_list);
-- 
2.41.0



Re: [RFC PATCH v4 01/11] ASoC: fsl_asrc: define functions for memory to memory usage

2023-09-20 Thread Hans Verkuil
On 20/09/2023 11:32, Shengjiu Wang wrote:
> ASRC can be used on memory to memory case, define several
> functions for m2m usage.
> 
> m2m_start_part_one: first part of the start steps
> m2m_start_part_two: second part of the start steps
> m2m_stop_part_one: first part of stop steps
> m2m_stop_part_two: second part of stop steps, optional
> m2m_check_format: check format is supported or not
> m2m_calc_out_len: calculate output length according to input length
> m2m_get_maxburst: burst size for dma
> m2m_pair_suspend: suspend function of pair, optional.
> m2m_pair_resume: resume function of pair
> get_output_fifo_size: get remaining data size in FIFO
> 
> Signed-off-by: Shengjiu Wang 
> ---
>  sound/soc/fsl/fsl_asrc.c| 150 
>  sound/soc/fsl/fsl_asrc.h|   2 +
>  sound/soc/fsl/fsl_asrc_common.h |  42 +
>  3 files changed, 194 insertions(+)
> 
> diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
> index b793263291dc..f9d830e0957f 100644
> --- a/sound/soc/fsl/fsl_asrc.c
> +++ b/sound/soc/fsl/fsl_asrc.c
> @@ -1063,6 +1063,145 @@ static int fsl_asrc_get_fifo_addr(u8 dir, enum 
> asrc_pair_index index)
>   return REG_ASRDx(dir, index);
>  }
>  
> +/* Get sample numbers in FIFO */
> +static unsigned int fsl_asrc_get_output_fifo_size(struct fsl_asrc_pair *pair)
> +{
> + struct fsl_asrc *asrc = pair->asrc;
> + enum asrc_pair_index index = pair->index;
> + u32 val;
> +
> + regmap_read(asrc->regmap, REG_ASRFST(index), );
> +
> + val &= ASRFSTi_OUTPUT_FIFO_MASK;
> +
> + return val >> ASRFSTi_OUTPUT_FIFO_SHIFT;
> +}
> +
> +static int fsl_asrc_m2m_start_part_one(struct fsl_asrc_pair *pair)
> +{
> + struct fsl_asrc_pair_priv *pair_priv = pair->private;
> + struct fsl_asrc *asrc = pair->asrc;
> + struct device *dev = >pdev->dev;
> + struct asrc_config config;
> + int ret;
> +
> + /* fill config */
> + config.pair = pair->index;
> + config.channel_num = pair->channels;
> + config.input_sample_rate = pair->rate[IN];
> + config.output_sample_rate = pair->rate[OUT];
> + config.input_format = pair->sample_format[IN];
> + config.output_format = pair->sample_format[OUT];
> + config.inclk = INCLK_NONE;
> + config.outclk = OUTCLK_ASRCK1_CLK;
> +
> + pair_priv->config = 
> + ret = fsl_asrc_config_pair(pair, true);
> + if (ret) {
> + dev_err(dev, "failed to config pair: %d\n", ret);
> + return ret;
> + }
> +
> + fsl_asrc_start_pair(pair);
> +
> + return 0;
> +}
> +
> +static int fsl_asrc_m2m_start_part_two(struct fsl_asrc_pair *pair)
> +{
> + /*
> +  * Clear DMA request during the stall state of ASRC:
> +  * During STALL state, the remaining in input fifo would never be
> +  * smaller than the input threshold while the output fifo would not
> +  * be bigger than output one. Thus the DMA request would be cleared.
> +  */
> + fsl_asrc_set_watermarks(pair, ASRC_FIFO_THRESHOLD_MIN,
> + ASRC_FIFO_THRESHOLD_MAX);
> +
> + /* Update the real input threshold to raise DMA request */
> + fsl_asrc_set_watermarks(pair, ASRC_M2M_INPUTFIFO_WML,
> + ASRC_M2M_OUTPUTFIFO_WML);
> +
> + return 0;
> +}
> +
> +static int fsl_asrc_m2m_stop_part_one(struct fsl_asrc_pair *pair)
> +{
> + fsl_asrc_stop_pair(pair);
> +
> + return 0;
> +}
> +
> +static int fsl_asrc_m2m_check_format(u8 dir, u32 format)
> +{
> + u64 support_format = FSL_ASRC_FORMATS;
> +
> + if (dir == IN)
> + support_format |= SNDRV_PCM_FMTBIT_S8;
> +
> + if (!(1 << format & support_format))
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> +static int fsl_asrc_m2m_check_rate(u8 dir, u32 rate)
> +{
> + if (rate < 5512 || rate > 192000)
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> +static int fsl_asrc_m2m_check_channel(u8 dir, u32 channels)
> +{
> + if (channels < 1 || channels > 10)
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> +/* calculate capture data length according to output data length and sample 
> rate */
> +static int fsl_asrc_m2m_calc_out_len(struct fsl_asrc_pair *pair, int 
> input_buffer_length)
> +{
> + unsigned int in_width, out_width;
> + unsigned int channels = pair->channels;
> + unsigned int in_samples, out_samples;
> + unsigned int out_length;
> +
> + in_width = snd_pcm_format_physical_width(pair->sample_format[IN]) / 8;
> + out_width = snd_pcm_format_physical_width(pair->sample_format[OUT]) / 8;
> +
> + in_samples = input_buffer_length / in_width / channels;
> + out_samples = pair->rate[OUT] * in_samples / pair->rate[IN];
> + out_length = (out_samples - ASRC_OUTPUT_LAST_SAMPLE) * out_width * 
> channels;
> +
> + return out_length;
> +}
> +
> +static int fsl_asrc_m2m_get_maxburst(u8 dir, struct fsl_asrc_pair *pair)
> +{
> + struct fsl_asrc *asrc = 

[PATCH] ASoC: fsl-asoc-card: use integer type for fll_id and pll_id

2023-09-20 Thread Shengjiu Wang
As the pll_id and pll_id can be zero (WM8960_SYSCLK_AUTO)
with the commit 2bbc2df46e67 ("ASoC: wm8960: Make automatic the
default clocking mode")

Then the machine driver will skip to call set_sysclk() and set_pll()
for codec, when the sysclk rate is different with what wm8960 read
at probe, the output sound frequency is wrong.

So change the fll_id and pll_id initial value, still keep machine
driver's behavior same as before.

Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/fsl-asoc-card.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 76b5bfc288fd..bab7d34cf585 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -52,8 +52,8 @@ struct codec_priv {
unsigned long mclk_freq;
unsigned long free_freq;
u32 mclk_id;
-   u32 fll_id;
-   u32 pll_id;
+   int fll_id;
+   int pll_id;
 };
 
 /**
@@ -206,7 +206,7 @@ static int fsl_asoc_card_hw_params(struct snd_pcm_substream 
*substream,
}
 
/* Specific configuration for PLL */
-   if (codec_priv->pll_id && codec_priv->fll_id) {
+   if (codec_priv->pll_id >= 0 && codec_priv->fll_id >= 0) {
if (priv->sample_format == SNDRV_PCM_FORMAT_S24_LE)
pll_out = priv->sample_rate * 384;
else
@@ -248,7 +248,7 @@ static int fsl_asoc_card_hw_free(struct snd_pcm_substream 
*substream)
 
priv->streams &= ~BIT(substream->stream);
 
-   if (!priv->streams && codec_priv->pll_id && codec_priv->fll_id) {
+   if (!priv->streams && codec_priv->pll_id >= 0 && codec_priv->fll_id >= 
0) {
/* Force freq to be free_freq to avoid error message in codec */
ret = snd_soc_dai_set_sysclk(asoc_rtd_to_codec(rtd, 0),
 codec_priv->mclk_id,
@@ -621,6 +621,10 @@ static int fsl_asoc_card_probe(struct platform_device 
*pdev)
priv->card.dapm_routes = audio_map;
priv->card.num_dapm_routes = ARRAY_SIZE(audio_map);
priv->card.driver_name = DRIVER_NAME;
+
+   priv->codec_priv.fll_id = -1;
+   priv->codec_priv.pll_id = -1;
+
/* Diversify the card configurations */
if (of_device_is_compatible(np, "fsl,imx-audio-cs42888")) {
codec_dai_name = "cs42888";
-- 
2.34.1



Re: [RFC PATCH v4 09/11] media: uapi: Add V4L2_CID_USER_IMX_ASRC_RATIO_MOD control

2023-09-20 Thread Hans Verkuil
On 20/09/2023 11:32, Shengjiu Wang wrote:
> The input clock and output clock may not be the accurate
> rate as the sample rate, there is some drift, so the convert
> ratio of i.MX ASRC module need to be changed according to
> actual clock rate.
> 
> Add V4L2_CID_USER_IMX_ASRC_RATIO_MOD control for user to
> adjust the ratio.
> 
> Signed-off-by: Shengjiu Wang 
> ---
>  Documentation/userspace-api/media/v4l/control.rst | 5 +
>  drivers/media/v4l2-core/v4l2-ctrls-defs.c | 1 +
>  include/uapi/linux/v4l2-controls.h| 1 +
>  3 files changed, 7 insertions(+)
> 
> diff --git a/Documentation/userspace-api/media/v4l/control.rst 
> b/Documentation/userspace-api/media/v4l/control.rst
> index 4463fce694b0..2bc175900a34 100644
> --- a/Documentation/userspace-api/media/v4l/control.rst
> +++ b/Documentation/userspace-api/media/v4l/control.rst
> @@ -318,6 +318,11 @@ Control IDs
>  depending on particular custom controls should check the driver name
>  and version, see :ref:`querycap`.
>  
> +.. _v4l2-audio-imx:
> +
> +``V4L2_CID_USER_IMX_ASRC_RATIO_MOD``
> +sets the rasampler ratio modifier of i.MX asrc module.

rasampler -> resampler (I think?)

This doesn't document at all what the type of the control is or how to 
interpret it.

> +
>  Applications can enumerate the available controls with the
>  :ref:`VIDIOC_QUERYCTRL` and
>  :ref:`VIDIOC_QUERYMENU ` ioctls, get and set a
> diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c 
> b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
> index 8696eb1cdd61..16f66f66198c 100644
> --- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c
> +++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
> @@ -1242,6 +1242,7 @@ const char *v4l2_ctrl_get_name(u32 id)
>   case V4L2_CID_COLORIMETRY_CLASS:return "Colorimetry Controls";
>   case V4L2_CID_COLORIMETRY_HDR10_CLL_INFO:   return "HDR10 
> Content Light Info";
>   case V4L2_CID_COLORIMETRY_HDR10_MASTERING_DISPLAY:  return "HDR10 
> Mastering Display";
> + case V4L2_CID_USER_IMX_ASRC_RATIO_MOD:  return "ASRC 
> RATIO MOD";

Let's stay consistent with the other control names:

"ASRC Ratio Modifier"

But if this is a driver specific control, then this doesn't belong here.

Driver specific controls are defined in the driver itself, including this
description.

Same for the control documentation: if it is driver specific, then that
typically is documented either in a driver-specific public header, or
possibly in driver-specific documentation (Documentation/admin-guide/media/).

But is this imx specific? Wouldn't other similar devices need this?

>   default:
>   return NULL;
>   }
> diff --git a/include/uapi/linux/v4l2-controls.h 
> b/include/uapi/linux/v4l2-controls.h
> index c3604a0a3e30..b1c319906d12 100644
> --- a/include/uapi/linux/v4l2-controls.h
> +++ b/include/uapi/linux/v4l2-controls.h
> @@ -162,6 +162,7 @@ enum v4l2_colorfx {
>  /* The base for the imx driver controls.
>   * We reserve 16 controls for this driver. */
>  #define V4L2_CID_USER_IMX_BASE   (V4L2_CID_USER_BASE + 
> 0x10b0)
> +#define V4L2_CID_USER_IMX_ASRC_RATIO_MOD (V4L2_CID_USER_IMX_BASE + 0)
>  
>  /*
>   * The base for the atmel isc driver controls.

Regards,

Hans


Re: [RFC PATCH v3 6/9] media: v4l2: Add audio capture and output support

2023-09-20 Thread Hans Verkuil
Hi Shengjiu,

I just noticed you posted a v4, but I expect that my comments below are still 
valid...

On 14/09/2023 07:54, Shengjiu Wang wrote:
> Audio signal processing has the requirement for memory to
> memory similar as Video.
> 
> This patch is to add this support in v4l2 framework, defined
> new buffer type V4L2_BUF_TYPE_AUDIO_CAPTURE and
> V4L2_BUF_TYPE_AUDIO_OUTPUT, defined new format v4l2_audio_format
> for audio case usage.
> 
> Defined V4L2_AUDIO_FMT_LPCM format type for audio.
> 
> Defined V4L2_CAP_AUDIO_M2M capability type for audio memory
> to memory case.
> 
> The created audio device is named "/dev/v4l-audioX".
> 
> Signed-off-by: Shengjiu Wang 
> ---
>  .../userspace-api/media/v4l/audio-formats.rst | 15 +
>  .../userspace-api/media/v4l/buffer.rst|  6 ++
>  .../userspace-api/media/v4l/dev-audio.rst | 63 +++
>  .../userspace-api/media/v4l/devices.rst   |  1 +
>  .../media/v4l/pixfmt-aud-lpcm.rst | 31 +
>  .../userspace-api/media/v4l/pixfmt.rst|  1 +
>  .../media/v4l/vidioc-enum-fmt.rst |  2 +
>  .../userspace-api/media/v4l/vidioc-g-fmt.rst  |  4 ++
>  .../media/v4l/vidioc-querycap.rst |  3 +
>  .../media/videodev2.h.rst.exceptions  |  2 +
>  .../media/common/videobuf2/videobuf2-v4l2.c   |  4 ++
>  drivers/media/v4l2-core/v4l2-dev.c| 17 +
>  drivers/media/v4l2-core/v4l2-ioctl.c  | 53 
>  include/media/v4l2-dev.h  |  2 +
>  include/media/v4l2-ioctl.h| 34 ++
>  include/uapi/linux/videodev2.h| 25 
>  16 files changed, 263 insertions(+)
>  create mode 100644 Documentation/userspace-api/media/v4l/audio-formats.rst
>  create mode 100644 Documentation/userspace-api/media/v4l/dev-audio.rst
>  create mode 100644 Documentation/userspace-api/media/v4l/pixfmt-aud-lpcm.rst
> 
> diff --git a/Documentation/userspace-api/media/v4l/audio-formats.rst 
> b/Documentation/userspace-api/media/v4l/audio-formats.rst
> new file mode 100644
> index ..bc52712d20d3
> --- /dev/null
> +++ b/Documentation/userspace-api/media/v4l/audio-formats.rst
> @@ -0,0 +1,15 @@
> +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
> +
> +.. _audio-formats:
> +
> +*
> +Audio Formats
> +*
> +
> +These formats are used for :ref:`audio` interface only.
> +
> +
> +.. toctree::
> +:maxdepth: 1
> +
> +pixfmt-aud-lpcm
> diff --git a/Documentation/userspace-api/media/v4l/buffer.rst 
> b/Documentation/userspace-api/media/v4l/buffer.rst
> index 04dec3e570ed..80cf2cb20dfe 100644
> --- a/Documentation/userspace-api/media/v4l/buffer.rst
> +++ b/Documentation/userspace-api/media/v4l/buffer.rst
> @@ -438,6 +438,12 @@ enum v4l2_buf_type
>  * - ``V4L2_BUF_TYPE_META_OUTPUT``
>- 14
>- Buffer for metadata output, see :ref:`metadata`.
> +* - ``V4L2_BUF_TYPE_AUDIO_CAPTURE``
> +  - 15
> +  - Buffer for audio capture, see :ref:`audio`.
> +* - ``V4L2_BUF_TYPE_AUDIO_OUTPUT``
> +  - 16
> +  - Buffer for audio output, see :ref:`audio`.
>  
>  
>  .. _buffer-flags:
> diff --git a/Documentation/userspace-api/media/v4l/dev-audio.rst 
> b/Documentation/userspace-api/media/v4l/dev-audio.rst
> new file mode 100644
> index ..f9bcf0c7b056
> --- /dev/null
> +++ b/Documentation/userspace-api/media/v4l/dev-audio.rst

Rename the file to dev-audio-mem2mem.rst as this is specific to an audio
M2M interface.

> @@ -0,0 +1,63 @@
> +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
> +
> +.. _audiodev:
> +
> +**
> +audio Interface
> +**
> +
> +The audio interface is implemented on audio device nodes. The audio device
> +which uses application software for modulation or demodulation. This
> +interface is intended for controlling and data streaming of such devices
> +
> +Audio devices are accessed through character device special files named
> +``/dev/v4l-audio``

I think this intro is somewhat confusing. I would recommend to copy the intro
from dev-mem2mem.rst instead, adapting it for audio.

> +
> +Querying Capabilities
> +=
> +
> +Device nodes supporting the audio capture and output interface set the
> +``V4L2_CAP_AUDIO_M2M`` flag in the ``device_caps`` field of the
> +:c:type:`v4l2_capability` structure returned by the :c:func:`VIDIOC_QUERYCAP`
> +ioctl.
> +
> +At least one of the read/write or streaming I/O methods must be supported.

M2M devices do not support read/write, only streaming I/O is supported.

> +
> +
> +Data Format Negotiation
> +===
> +
> +The audio device uses the :ref:`format` ioctls to select the capture format.
> +The audio buffer content format is bound to that selected format. In addition
> +to the basic :ref:`format` ioctls, the :c:func:`VIDIOC_ENUM_FMT` ioctl must 
> be
> +supported as well.
> +
> +To use the :ref:`format` ioctls applications set the ``type`` 

[RFC PATCH v4 11/11] media: imx-asrc: Add memory to memory driver

2023-09-20 Thread Shengjiu Wang
Implement the ASRC memory to memory function using
the v4l2 framework, user can use this function with
v4l2 ioctl interface.

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

This feature can be shared by ASRC and EASRC drivers

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

diff --git a/drivers/media/platform/nxp/Kconfig 
b/drivers/media/platform/nxp/Kconfig
index 40e3436669e2..8234644ee341 100644
--- a/drivers/media/platform/nxp/Kconfig
+++ b/drivers/media/platform/nxp/Kconfig
@@ -67,3 +67,15 @@ config VIDEO_MX2_EMMAPRP
 
 source "drivers/media/platform/nxp/dw100/Kconfig"
 source "drivers/media/platform/nxp/imx-jpeg/Kconfig"
+
+config VIDEO_IMX_ASRC
+   tristate "NXP i.MX ASRC M2M support"
+   depends on V4L_MEM2MEM_DRIVERS
+   depends on MEDIA_SUPPORT
+   select VIDEOBUF2_DMA_CONTIG
+   select V4L2_MEM2MEM_DEV
+   help
+   Say Y if you want to add ASRC M2M support for NXP CPUs.
+   It is a complement for ASRC M2P and ASRC P2M features.
+   This option is only useful for out-of-tree drivers since
+   in-tree drivers select it automatically.
diff --git a/drivers/media/platform/nxp/Makefile 
b/drivers/media/platform/nxp/Makefile
index 4d90eb713652..1325675e34f5 100644
--- a/drivers/media/platform/nxp/Makefile
+++ b/drivers/media/platform/nxp/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_VIDEO_IMX8MQ_MIPI_CSI2) += imx8mq-mipi-csi2.o
 obj-$(CONFIG_VIDEO_IMX_MIPI_CSIS) += imx-mipi-csis.o
 obj-$(CONFIG_VIDEO_IMX_PXP) += imx-pxp.o
 obj-$(CONFIG_VIDEO_MX2_EMMAPRP) += mx2_emmaprp.o
+obj-$(CONFIG_VIDEO_IMX_ASRC) += imx-asrc.o
diff --git a/drivers/media/platform/nxp/imx-asrc.c 
b/drivers/media/platform/nxp/imx-asrc.c
new file mode 100644
index ..21079c7abd27
--- /dev/null
+++ b/drivers/media/platform/nxp/imx-asrc.c
@@ -0,0 +1,1058 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+// Copyright (C) 2019-2023 NXP
+//
+// Freescale ASRC Memory to Memory (M2M) driver
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define V4L_CAP OUT
+#define V4L_OUT IN
+
+/* Flags that indicate a format can be used for capture/output */
+#define MEM2MEM_CAPTUREBIT(0)
+#define MEM2MEM_OUTPUT BIT(1)
+
+#define ASRC_xPUT_DMA_CALLBACK(dir) \
+   (((dir) == V4L_OUT) ? asrc_input_dma_callback \
+   : asrc_output_dma_callback)
+
+#define DIR_STR(dir) (dir) == V4L_OUT ? "out" : "cap"
+
+#define ASRC_M2M_BUFFER_SIZE (512 * 1024)
+#define ASRC_M2M_PERIOD_SIZE (48 * 1024)
+#define ASRC_M2M_SG_NUM (20)
+
+struct asrc_pair_m2m {
+   struct fsl_asrc_pair *pair;
+   struct asrc_m2m *m2m;
+   struct v4l2_fh fh;
+   struct v4l2_ctrl_handler ctrl_handler;
+};
+
+struct asrc_m2m {
+   struct fsl_asrc *asrc;
+   struct v4l2_device v4l2_dev;
+   struct v4l2_m2m_dev *m2m_dev;
+   struct video_device *dec_vdev;
+   struct mutex mlock; /* v4l2 ioctls serialization */
+   struct platform_device *pdev;
+};
+
+struct asrc_fmt {
+   u32 fourcc;
+   u32 types;
+};
+
+static struct asrc_fmt formats[] = {
+   {
+   .fourcc = V4L2_AUDIO_FMT_LPCM,
+   .types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
+   },
+};
+
+#define NUM_FORMATS ARRAY_SIZE(formats)
+
+static inline struct asrc_pair_m2m *asrc_m2m_fh_to_ctx(struct v4l2_fh *fh)
+{
+   return container_of(fh, struct asrc_pair_m2m, fh);
+}
+
+/**
+ * asrc_read_last_fifo: read all the remaining data from FIFO
+ * @pair: Structure pointer of fsl_asrc_pair
+ * @dma_vaddr: virtual address of capture buffer
+ * @length: payload length of capture buffer
+ */
+static void asrc_read_last_fifo(struct fsl_asrc_pair *pair, void *dma_vaddr, 
u32 *length)
+{
+   struct fsl_asrc *asrc = pair->asrc;
+   enum asrc_pair_index index = pair->index;
+   u32 i, reg, size, t_size = 0, width;
+   u32 *reg32 = NULL;
+   u16 *reg16 = NULL;
+   u8  *reg24 = NULL;
+
+   width = snd_pcm_format_physical_width(pair->sample_format[V4L_CAP]);
+   if (width == 32)
+   reg32 = dma_vaddr + *length;
+   else if (width == 16)
+   reg16 = dma_vaddr + *length;
+   else
+   reg24 = dma_vaddr + *length;
+retry:
+   size = asrc->get_output_fifo_size(pair);
+   if (size + *length > ASRC_M2M_BUFFER_SIZE)
+   goto end;
+
+   for (i = 0; i < size * pair->channels; i++) {
+   regmap_read(asrc->regmap, asrc->get_fifo_addr(OUT, index), 
);
+   if (reg32) {
+   *(reg32) = reg;
+   reg32++;
+  

[RFC PATCH v4 10/11] media: audm2m: add virtual driver for audio memory to memory

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

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

Signed-off-by: Shengjiu Wang 
---
 drivers/media/test-drivers/Kconfig  |   9 +
 drivers/media/test-drivers/Makefile |   1 +
 drivers/media/test-drivers/audm2m.c | 767 
 3 files changed, 777 insertions(+)
 create mode 100644 drivers/media/test-drivers/audm2m.c

diff --git a/drivers/media/test-drivers/Kconfig 
b/drivers/media/test-drivers/Kconfig
index 459b433e9fae..be60d73cbf97 100644
--- a/drivers/media/test-drivers/Kconfig
+++ b/drivers/media/test-drivers/Kconfig
@@ -17,6 +17,15 @@ config VIDEO_VIM2M
  This is a virtual test device for the memory-to-memory driver
  framework.
 
+config VIDEO_AUDM2M
+   tristate "Virtual Memory-to-Memory Driver For Audio"
+   depends on VIDEO_DEV
+   select VIDEOBUF2_VMALLOC
+   select V4L2_MEM2MEM_DEV
+   help
+ This is a virtual audio test device for the memory-to-memory driver
+ framework.
+
 source "drivers/media/test-drivers/vicodec/Kconfig"
 source "drivers/media/test-drivers/vimc/Kconfig"
 source "drivers/media/test-drivers/vivid/Kconfig"
diff --git a/drivers/media/test-drivers/Makefile 
b/drivers/media/test-drivers/Makefile
index 740714a4584d..b53ed7e6eaf1 100644
--- a/drivers/media/test-drivers/Makefile
+++ b/drivers/media/test-drivers/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_DVB_VIDTV) += vidtv/
 
 obj-$(CONFIG_VIDEO_VICODEC) += vicodec/
 obj-$(CONFIG_VIDEO_VIM2M) += vim2m.o
+obj-$(CONFIG_VIDEO_AUDM2M) += audm2m.o
 obj-$(CONFIG_VIDEO_VIMC) += vimc/
 obj-$(CONFIG_VIDEO_VIVID) += vivid/
 obj-$(CONFIG_VIDEO_VISL) += visl/
diff --git a/drivers/media/test-drivers/audm2m.c 
b/drivers/media/test-drivers/audm2m.c
new file mode 100644
index ..d54bc99b9275
--- /dev/null
+++ b/drivers/media/test-drivers/audm2m.c
@@ -0,0 +1,767 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * A virtual v4l2-mem2mem example for audio device.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+MODULE_DESCRIPTION("Virtual device for audio mem2mem testing");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.1");
+MODULE_ALIAS("audio_mem2mem_testdev");
+
+static unsigned int debug;
+module_param(debug, uint, 0644);
+MODULE_PARM_DESC(debug, "debug level");
+
+/* Flags that indicate a format can be used for capture/output */
+#define MEM2MEM_CAPTUREBIT(0)
+#define MEM2MEM_OUTPUT BIT(1)
+
+#define MEM2MEM_NAME "audm2m"
+
+#define dprintk(dev, lvl, fmt, arg...) \
+   v4l2_dbg(lvl, debug, &(dev)->v4l2_dev, "%s: " fmt, __func__, ## arg)
+
+#define SAMPLE_NUM 4096
+
+static void audm2m_dev_release(struct device *dev)
+{}
+
+static struct platform_device audm2m_pdev = {
+   .name   = MEM2MEM_NAME,
+   .dev.release= audm2m_dev_release,
+};
+
+struct audm2m_fmt {
+   u32 fourcc;
+   u32 types;
+};
+
+static struct audm2m_fmt formats[] = {
+   {
+   .fourcc = V4L2_AUDIO_FMT_LPCM,
+   .types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
+   }
+};
+
+#define NUM_FORMATS ARRAY_SIZE(formats)
+
+/* Per-queue, driver-specific private data */
+struct audm2m_q_data {
+   unsigned intrate;
+   snd_pcm_format_tformat;
+   unsigned intchannels;
+   unsigned intbuffersize;
+   struct audm2m_fmt   *fmt;
+};
+
+enum {
+   V4L2_M2M_SRC = 0,
+   V4L2_M2M_DST = 1,
+};
+
+static struct audm2m_fmt *find_format(u32 fourcc)
+{
+   struct audm2m_fmt *fmt;
+   unsigned int k;
+
+   for (k = 0; k < NUM_FORMATS; k++) {
+   fmt = [k];
+   if (fmt->fourcc == fourcc)
+   break;
+   }
+
+   if (k == NUM_FORMATS)
+   return NULL;
+
+   return [k];
+}
+
+struct audm2m_dev {
+   struct v4l2_device  v4l2_dev;
+   struct video_device vfd;
+
+   atomic_tnum_inst;
+   struct mutexdev_mutex;
+
+   struct v4l2_m2m_dev *m2m_dev;
+};
+
+struct audm2m_ctx {
+   struct v4l2_fh  fh;
+   struct audm2m_dev   *dev;
+
+   struct mutexvb_mutex;
+
+   /* Abort requested by m2m */
+   int aborting;
+
+   /* Source and destination queue data */
+   struct audm2m_q_data   q_data[2];
+};
+
+static inline struct audm2m_ctx *file2ctx(struct file *file)
+{
+   return container_of(file->private_data, struct audm2m_ctx, fh);
+}
+
+static struct audm2m_q_data *get_q_data(struct audm2m_ctx *ctx,
+   enum v4l2_buf_type type)
+{
+   switch (type) {
+   case 

[RFC PATCH v4 09/11] media: uapi: Add V4L2_CID_USER_IMX_ASRC_RATIO_MOD control

2023-09-20 Thread Shengjiu Wang
The input clock and output clock may not be the accurate
rate as the sample rate, there is some drift, so the convert
ratio of i.MX ASRC module need to be changed according to
actual clock rate.

Add V4L2_CID_USER_IMX_ASRC_RATIO_MOD control for user to
adjust the ratio.

Signed-off-by: Shengjiu Wang 
---
 Documentation/userspace-api/media/v4l/control.rst | 5 +
 drivers/media/v4l2-core/v4l2-ctrls-defs.c | 1 +
 include/uapi/linux/v4l2-controls.h| 1 +
 3 files changed, 7 insertions(+)

diff --git a/Documentation/userspace-api/media/v4l/control.rst 
b/Documentation/userspace-api/media/v4l/control.rst
index 4463fce694b0..2bc175900a34 100644
--- a/Documentation/userspace-api/media/v4l/control.rst
+++ b/Documentation/userspace-api/media/v4l/control.rst
@@ -318,6 +318,11 @@ Control IDs
 depending on particular custom controls should check the driver name
 and version, see :ref:`querycap`.
 
+.. _v4l2-audio-imx:
+
+``V4L2_CID_USER_IMX_ASRC_RATIO_MOD``
+sets the rasampler ratio modifier of i.MX asrc module.
+
 Applications can enumerate the available controls with the
 :ref:`VIDIOC_QUERYCTRL` and
 :ref:`VIDIOC_QUERYMENU ` ioctls, get and set a
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c 
b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
index 8696eb1cdd61..16f66f66198c 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
@@ -1242,6 +1242,7 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_COLORIMETRY_CLASS:return "Colorimetry Controls";
case V4L2_CID_COLORIMETRY_HDR10_CLL_INFO:   return "HDR10 
Content Light Info";
case V4L2_CID_COLORIMETRY_HDR10_MASTERING_DISPLAY:  return "HDR10 
Mastering Display";
+   case V4L2_CID_USER_IMX_ASRC_RATIO_MOD:  return "ASRC 
RATIO MOD";
default:
return NULL;
}
diff --git a/include/uapi/linux/v4l2-controls.h 
b/include/uapi/linux/v4l2-controls.h
index c3604a0a3e30..b1c319906d12 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -162,6 +162,7 @@ enum v4l2_colorfx {
 /* The base for the imx driver controls.
  * We reserve 16 controls for this driver. */
 #define V4L2_CID_USER_IMX_BASE (V4L2_CID_USER_BASE + 0x10b0)
+#define V4L2_CID_USER_IMX_ASRC_RATIO_MOD   (V4L2_CID_USER_IMX_BASE + 0)
 
 /*
  * The base for the atmel isc driver controls.
-- 
2.34.1



[RFC PATCH v4 08/11] media: v4l2: Add audio capture and output support

2023-09-20 Thread Shengjiu Wang
Audio signal processing has the requirement for memory to
memory similar as Video.

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

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

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

diff --git a/Documentation/userspace-api/media/v4l/buffer.rst 
b/Documentation/userspace-api/media/v4l/buffer.rst
index 04dec3e570ed..80cf2cb20dfe 100644
--- a/Documentation/userspace-api/media/v4l/buffer.rst
+++ b/Documentation/userspace-api/media/v4l/buffer.rst
@@ -438,6 +438,12 @@ enum v4l2_buf_type
 * - ``V4L2_BUF_TYPE_META_OUTPUT``
   - 14
   - Buffer for metadata output, see :ref:`metadata`.
+* - ``V4L2_BUF_TYPE_AUDIO_CAPTURE``
+  - 15
+  - Buffer for audio capture, see :ref:`audio`.
+* - ``V4L2_BUF_TYPE_AUDIO_OUTPUT``
+  - 16
+  - Buffer for audio output, see :ref:`audio`.
 
 
 .. _buffer-flags:
diff --git a/Documentation/userspace-api/media/v4l/dev-audio.rst 
b/Documentation/userspace-api/media/v4l/dev-audio.rst
new file mode 100644
index ..549d4cc17b50
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/dev-audio.rst
@@ -0,0 +1,63 @@
+.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+
+.. _audiodev:
+
+***
+Audio Interface
+***
+
+The audio interface is implemented on audio device nodes. The audio device
+which uses application software for modulation or demodulation. This
+interface is intended for controlling and data streaming of such devices
+
+Audio devices are accessed through character device special files named
+``/dev/v4l-audio``
+
+Querying Capabilities
+=
+
+Device nodes supporting the audio capture and output interface set the
+``V4L2_CAP_AUDIO_M2M`` flag in the ``device_caps`` field of the
+:c:type:`v4l2_capability` structure returned by the :c:func:`VIDIOC_QUERYCAP`
+ioctl.
+
+At least one of the read/write or streaming I/O methods must be supported.
+
+
+Data Format Negotiation
+===
+
+The audio device uses the :ref:`format` ioctls to select the capture format.
+The audio buffer content format is bound to that selected format. In addition
+to the basic :ref:`format` ioctls, the :c:func:`VIDIOC_ENUM_FMT` ioctl must be
+supported as well.
+
+To use the :ref:`format` ioctls applications set the ``type`` field of the
+:c:type:`v4l2_format` structure to ``V4L2_BUF_TYPE_AUDIO_CAPTURE`` or to
+``V4L2_BUF_TYPE_AUDIO_OUTPUT``. Both drivers and applications must set the
+remainder of the :c:type:`v4l2_format` structure to 0.
+
+.. c:type:: v4l2_audio_format
+
+.. tabularcolumns:: |p{1.4cm}|p{2.4cm}|p{13.5cm}|
+
+.. flat-table:: struct v4l2_audio_format
+:header-rows:  0
+:stub-columns: 0
+:widths:   1 1 2
+
+* - __u32
+  - ``rate``
+  - The sample rate, set by the application. The range is [5512, 768000].
+* - __u32
+  - ``format``
+  - The sample format, set by the application. format is defined as
+SNDRV_PCM_FORMAT_S8, SNDRV_PCM_FORMAT_U8, ...,
+* - __u32
+  - ``channels``
+  - The channel number, set by the application. channel number range is
+[1, 32].
+* - __u32
+  - ``buffersize``
+  - Maximum buffer size in bytes required for data. The value is set by the
+driver.
diff --git a/Documentation/userspace-api/media/v4l/devices.rst 
b/Documentation/userspace-api/media/v4l/devices.rst
index 8bfbad65a9d4..8261f3468489 100644
--- a/Documentation/userspace-api/media/v4l/devices.rst
+++ b/Documentation/userspace-api/media/v4l/devices.rst
@@ -24,3 +24,4 @@ Interfaces
 dev-event
 dev-subdev
 dev-meta
+dev-audio
diff --git a/Documentation/userspace-api/media/v4l/vidioc-enum-fmt.rst 
b/Documentation/userspace-api/media/v4l/vidioc-enum-fmt.rst
index 000c154b0f98..42deb07f4ff4 100644
--- a/Documentation/userspace-api/media/v4l/vidioc-enum-fmt.rst
+++ b/Documentation/userspace-api/media/v4l/vidioc-enum-fmt.rst
@@ -96,6 +96,8 @@ the ``mbus_code`` field is handled differently:
``V4L2_BUF_TYPE_VIDEO_OVERLAY``,
 

[RFC PATCH v4 07/11] media: uapi: Add V4L2_AUDIO_FMT_LPCM fourcc format

2023-09-20 Thread Shengjiu Wang
Linear Pulse-Code Modulation is used to represent
audio samples in buffer, the samples for each channel
are interleaved.

Signed-off-by: Shengjiu Wang 
---
 .../userspace-api/media/v4l/audio-formats.rst | 15 +
 .../media/v4l/pixfmt-aud-lpcm.rst | 61 +++
 .../userspace-api/media/v4l/pixfmt.rst|  1 +
 drivers/media/v4l2-core/v4l2-ioctl.c  |  1 +
 include/uapi/linux/videodev2.h|  3 +
 5 files changed, 81 insertions(+)
 create mode 100644 Documentation/userspace-api/media/v4l/audio-formats.rst
 create mode 100644 Documentation/userspace-api/media/v4l/pixfmt-aud-lpcm.rst

diff --git a/Documentation/userspace-api/media/v4l/audio-formats.rst 
b/Documentation/userspace-api/media/v4l/audio-formats.rst
new file mode 100644
index ..bc52712d20d3
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/audio-formats.rst
@@ -0,0 +1,15 @@
+.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+
+.. _audio-formats:
+
+*
+Audio Formats
+*
+
+These formats are used for :ref:`audio` interface only.
+
+
+.. toctree::
+:maxdepth: 1
+
+pixfmt-aud-lpcm
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-aud-lpcm.rst 
b/Documentation/userspace-api/media/v4l/pixfmt-aud-lpcm.rst
new file mode 100644
index ..2231bd95212f
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-aud-lpcm.rst
@@ -0,0 +1,61 @@
+.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+
+.. _v4l2-audio-fmt-lpcm:
+
+
+V4L2_AUDIO_FMT_LPCM ('LPCM')
+
+
+Linear Pulse-Code Modulation (LPCM)
+
+
+Description
+===
+
+LPCM audio is coded using a combination of values such as:
+
+Sample rate: which is the number of times per second that samples are taken,
+The typical rates are 8kHz, 11025Hz, 16kHz, 22050Hz, 32kHz, 44100Hz, 48kHz,
+88200Hz, 96kHz, 176400Hz, 192kHz...
+
+Sample format: which determines the number of possible digital values that
+can be used to represent each sample. The format can be SND_PCM_FORMAT_S8,
+SND_PCM_FORMAT_S16_LE, SND_PCM_FORMAT_S24_LE, SND_PCM_FORMAT_S32_LE...
+
+Channels: It is the "location" or "passageway" of a specific signal or
+data in a piece of audio. The channel number can be 1,2,3...
+
+Please refer to https://www.alsa-project.org/alsa-doc/alsa-lib/pcm.html
+for more detail
+
+Each sample contains several channels data,  the channel data format is
+defined by sample format.
+
+.. flat-table::
+:header-rows:  0
+:stub-columns: 0
+
+* - Sample 0:
+  - Channel 0
+  - Channel 1
+  - Channel 2
+  - Channel 3
+  - ...
+* - Sample 1:
+  - Channel 0
+  - Channel 1
+  - Channel 2
+  - Channel 3
+  - ...
+* - Sample 2:
+  - Channel 0
+  - Channel 1
+  - Channel 2
+  - Channel 3
+  - ...
+* - Sample 3:
+  - Channel 0
+  - Channel 1
+  - Channel 2
+  - Channel 3
+  - ...
diff --git a/Documentation/userspace-api/media/v4l/pixfmt.rst 
b/Documentation/userspace-api/media/v4l/pixfmt.rst
index 11dab4a90630..e205db5fa8af 100644
--- a/Documentation/userspace-api/media/v4l/pixfmt.rst
+++ b/Documentation/userspace-api/media/v4l/pixfmt.rst
@@ -36,3 +36,4 @@ see also :ref:`VIDIOC_G_FBUF `.)
 colorspaces
 colorspaces-defs
 colorspaces-details
+audio-formats
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index f4d9d6279094..55fd4da10ba6 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1452,6 +1452,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
case V4L2_PIX_FMT_Y210: descr = "10-bit YUYV Packed"; break;
case V4L2_PIX_FMT_Y212: descr = "12-bit YUYV Packed"; break;
case V4L2_PIX_FMT_Y216: descr = "16-bit YUYV Packed"; break;
+   case V4L2_AUDIO_FMT_LPCM:   descr = "Audio LPCM"; break;
 
default:
/* Compressed formats */
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 3decf7d73870..ce71e9343705 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -839,6 +839,9 @@ struct v4l2_pix_format {
 #define V4L2_META_FMT_RK_ISP1_PARAMS   v4l2_fourcc('R', 'K', '1', 'P') /* 
Rockchip ISP1 3A Parameters */
 #define V4L2_META_FMT_RK_ISP1_STAT_3A  v4l2_fourcc('R', 'K', '1', 'S') /* 
Rockchip ISP1 3A Statistics */
 
+/* Audio-data formats */
+#define V4L2_AUDIO_FMT_LPCM   v4l2_fourcc('L', 'P', 'C', 'M') /* audio 
lpcm */
+
 /* priv field value to indicates that subsequent fields are valid. */
 #define V4L2_PIX_FMT_PRIV_MAGIC0xfeedcafe
 
-- 
2.34.1



[RFC PATCH v4 06/11] media: uapi: Add V4L2_CAP_AUDIO_M2M capability flag

2023-09-20 Thread Shengjiu Wang
V4L2_CAP_AUDIO_M2M is similar to V4L2_CAP_VIDEO_M2M flag.

It is used for audio memory to memory case.

Signed-off-by: Shengjiu Wang 
---
 Documentation/userspace-api/media/v4l/vidioc-querycap.rst| 3 +++
 Documentation/userspace-api/media/videodev2.h.rst.exceptions | 1 +
 include/uapi/linux/videodev2.h   | 1 +
 3 files changed, 5 insertions(+)

diff --git a/Documentation/userspace-api/media/v4l/vidioc-querycap.rst 
b/Documentation/userspace-api/media/v4l/vidioc-querycap.rst
index 6c57b8428356..0b3cefefc86b 100644
--- a/Documentation/userspace-api/media/v4l/vidioc-querycap.rst
+++ b/Documentation/userspace-api/media/v4l/vidioc-querycap.rst
@@ -259,6 +259,9 @@ specification the ioctl returns an ``EINVAL`` error code.
 video topology configuration, including which I/O entity is routed to
 the input/output, is configured by userspace via the Media Controller.
 See :ref:`media_controller`.
+* - ``V4L2_CAP_AUDIO_M2M``
+  - 0x4000
+  - The device supports the audio Memory-To-Memory interface.
 * - ``V4L2_CAP_DEVICE_CAPS``
   - 0x8000
   - The driver fills the ``device_caps`` field. This capability can
diff --git a/Documentation/userspace-api/media/videodev2.h.rst.exceptions 
b/Documentation/userspace-api/media/videodev2.h.rst.exceptions
index 3e58aac4ef0b..da6d0b8e4c2c 100644
--- a/Documentation/userspace-api/media/videodev2.h.rst.exceptions
+++ b/Documentation/userspace-api/media/videodev2.h.rst.exceptions
@@ -197,6 +197,7 @@ replace define V4L2_CAP_META_OUTPUT device-capabilities
 replace define V4L2_CAP_DEVICE_CAPS device-capabilities
 replace define V4L2_CAP_TOUCH device-capabilities
 replace define V4L2_CAP_IO_MC device-capabilities
+replace define V4L2_CAP_AUDIO_M2M device-capabilities
 
 # V4L2 pix flags
 replace define V4L2_PIX_FMT_PRIV_MAGIC :c:type:`v4l2_pix_format`
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 78260e5d9985..3decf7d73870 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -508,6 +508,7 @@ struct v4l2_capability {
 #define V4L2_CAP_TOUCH  0x1000  /* Is a touch device */
 
 #define V4L2_CAP_IO_MC 0x2000  /* Is input/output 
controlled by the media controller */
+#define V4L2_CAP_AUDIO_M2M  0x4000  /* audio memory to memory 
*/
 
 #define V4L2_CAP_DEVICE_CAPS0x8000  /* sets device 
capabilities field */
 
-- 
2.34.1



[RFC PATCH v4 05/11] ASoC: fsl_easrc: register m2m platform device

2023-09-20 Thread Shengjiu Wang
Register m2m platform device,that user can
use M2M feature.

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

diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c
index f517b407672d..b719d517f9b4 100644
--- a/sound/soc/fsl/fsl_easrc.c
+++ b/sound/soc/fsl/fsl_easrc.c
@@ -2084,6 +2084,7 @@ MODULE_DEVICE_TABLE(of, fsl_easrc_dt_ids);
 static int fsl_easrc_probe(struct platform_device *pdev)
 {
struct fsl_easrc_priv *easrc_priv;
+   struct fsl_asrc_m2m_pdata m2m_pdata;
struct device *dev = >dev;
struct fsl_asrc *easrc;
struct resource *res;
@@ -2202,11 +2203,23 @@ static int fsl_easrc_probe(struct platform_device *pdev)
return ret;
}
 
+   m2m_pdata.asrc = easrc;
+   easrc->m2m_pdev = platform_device_register_data(>dev,
+   M2M_DRV_NAME,
+   PLATFORM_DEVID_AUTO,
+   _pdata,
+   sizeof(m2m_pdata));
+
return 0;
 }
 
 static void fsl_easrc_remove(struct platform_device *pdev)
 {
+   struct fsl_asrc *easrc = dev_get_drvdata(>dev);
+
+   if (easrc->m2m_pdev && !IS_ERR(easrc->m2m_pdev))
+   platform_device_unregister(easrc->m2m_pdev);
+
pm_runtime_disable(>dev);
 }
 
-- 
2.34.1



[RFC PATCH v4 04/11] ASoC: fsl_asrc: register m2m platform device

2023-09-20 Thread Shengjiu Wang
Register m2m platform device, that user can
use M2M feature.

Defined platform data structure and platform
driver name.

Signed-off-by: Shengjiu Wang 
---
 include/sound/fsl_asrc_common.h | 12 
 sound/soc/fsl/fsl_asrc.c| 12 
 2 files changed, 24 insertions(+)

diff --git a/include/sound/fsl_asrc_common.h b/include/sound/fsl_asrc_common.h
index 7f7e725075fe..e978a2f9cd24 100644
--- a/include/sound/fsl_asrc_common.h
+++ b/include/sound/fsl_asrc_common.h
@@ -69,6 +69,7 @@ struct fsl_asrc_pair {
  * @dma_params_rx: DMA parameters for receive channel
  * @dma_params_tx: DMA parameters for transmit channel
  * @pdev: platform device pointer
+ * @m2m_pdev: m2m platform device pointer
  * @regmap: regmap handler
  * @paddr: physical address to the base address of registers
  * @mem_clk: clock source to access register
@@ -104,6 +105,7 @@ struct fsl_asrc {
struct snd_dmaengine_dai_dma_data dma_params_rx;
struct snd_dmaengine_dai_dma_data dma_params_tx;
struct platform_device *pdev;
+   struct platform_device *m2m_pdev;
struct regmap *regmap;
unsigned long paddr;
struct clk *mem_clk;
@@ -144,6 +146,16 @@ struct fsl_asrc {
void *private;
 };
 
+/**
+ * struct fsl_asrc_m2m_pdata - platform data
+ * @asrc: pointer to struct fsl_asrc
+ *
+ */
+struct fsl_asrc_m2m_pdata {
+   struct fsl_asrc *asrc;
+};
+
+#define M2M_DRV_NAME "fsl_asrc_m2m"
 #define DRV_NAME "fsl-asrc-dai"
 extern struct snd_soc_component_driver fsl_asrc_component;
 
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index f9d830e0957f..7b72d6bcf281 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -1208,6 +1208,7 @@ static int fsl_asrc_runtime_suspend(struct device *dev);
 static int fsl_asrc_probe(struct platform_device *pdev)
 {
struct device_node *np = pdev->dev.of_node;
+   struct fsl_asrc_m2m_pdata m2m_pdata;
struct fsl_asrc_priv *asrc_priv;
struct fsl_asrc *asrc;
struct resource *res;
@@ -1392,6 +1393,12 @@ static int fsl_asrc_probe(struct platform_device *pdev)
goto err_pm_get_sync;
}
 
+   m2m_pdata.asrc = asrc;
+   asrc->m2m_pdev = platform_device_register_data(>dev,
+  M2M_DRV_NAME,
+  PLATFORM_DEVID_AUTO,
+  _pdata,
+  sizeof(m2m_pdata));
return 0;
 
 err_pm_get_sync:
@@ -1404,6 +1411,11 @@ static int fsl_asrc_probe(struct platform_device *pdev)
 
 static void fsl_asrc_remove(struct platform_device *pdev)
 {
+   struct fsl_asrc *asrc = dev_get_drvdata(>dev);
+
+   if (asrc->m2m_pdev && !IS_ERR(asrc->m2m_pdev))
+   platform_device_unregister(asrc->m2m_pdev);
+
pm_runtime_disable(>dev);
if (!pm_runtime_status_suspended(>dev))
fsl_asrc_runtime_suspend(>dev);
-- 
2.34.1



[RFC PATCH v4 03/11] ASoC: fsl_asrc: move fsl_asrc_common.h to include/sound

2023-09-20 Thread Shengjiu Wang
Move fsl_asrc_common.h to include/sound that it can be
included from other drivers.

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

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



[RFC PATCH v4 02/11] ASoC: fsl_easrc: define functions for memory to memory usage

2023-09-20 Thread Shengjiu Wang
ASRC can be used on memory to memory case, define several
functions for m2m usage and export them as function pointer.

Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/fsl_easrc.c | 226 ++
 sound/soc/fsl/fsl_easrc.h |   6 +
 2 files changed, 232 insertions(+)

diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c
index ba62995c909a..f517b407672d 100644
--- a/sound/soc/fsl/fsl_easrc.c
+++ b/sound/soc/fsl/fsl_easrc.c
@@ -1861,6 +1861,220 @@ static int fsl_easrc_get_fifo_addr(u8 dir, enum 
asrc_pair_index index)
return REG_EASRC_FIFO(dir, index);
 }
 
+/* Get sample numbers in FIFO */
+static unsigned int fsl_easrc_get_output_fifo_size(struct fsl_asrc_pair *pair)
+{
+   struct fsl_asrc *asrc = pair->asrc;
+   enum asrc_pair_index index = pair->index;
+   u32 val;
+
+   regmap_read(asrc->regmap, REG_EASRC_SFS(index), );
+   val &= EASRC_SFS_NSGO_MASK;
+
+   return val >> EASRC_SFS_NSGO_SHIFT;
+}
+
+static int fsl_easrc_m2m_start_part_one(struct fsl_asrc_pair *pair)
+{
+   struct fsl_easrc_ctx_priv *ctx_priv = pair->private;
+   struct fsl_asrc *asrc = pair->asrc;
+   struct device *dev = >pdev->dev;
+   int ret;
+
+   ctx_priv->in_params.sample_rate = pair->rate[IN];
+   ctx_priv->in_params.sample_format = pair->sample_format[IN];
+   ctx_priv->out_params.sample_rate = pair->rate[OUT];
+   ctx_priv->out_params.sample_format = pair->sample_format[OUT];
+
+   ctx_priv->in_params.fifo_wtmk = FSL_EASRC_INPUTFIFO_WML;
+   ctx_priv->out_params.fifo_wtmk = FSL_EASRC_OUTPUTFIFO_WML;
+   /* Fill the right half of the re-sampler with zeros */
+   ctx_priv->rs_init_mode = 0x2;
+   /* Zero fill the right half of the prefilter */
+   ctx_priv->pf_init_mode = 0x2;
+
+   ret = fsl_easrc_set_ctx_format(pair,
+  _priv->in_params.sample_format,
+  _priv->out_params.sample_format);
+   if (ret) {
+   dev_err(dev, "failed to set context format: %d\n", ret);
+   return ret;
+   }
+
+   ret = fsl_easrc_config_context(asrc, pair->index);
+   if (ret) {
+   dev_err(dev, "failed to config context %d\n", ret);
+   return ret;
+   }
+
+   ctx_priv->in_params.iterations = 1;
+   ctx_priv->in_params.group_len = pair->channels;
+   ctx_priv->in_params.access_len = pair->channels;
+   ctx_priv->out_params.iterations = 1;
+   ctx_priv->out_params.group_len = pair->channels;
+   ctx_priv->out_params.access_len = pair->channels;
+
+   ret = fsl_easrc_set_ctx_organziation(pair);
+   if (ret) {
+   dev_err(dev, "failed to set fifo organization\n");
+   return ret;
+   }
+
+   /* The context start flag */
+   ctx_priv->first_convert = 1;
+   return 0;
+}
+
+static int fsl_easrc_m2m_start_part_two(struct fsl_asrc_pair *pair)
+{
+   struct fsl_easrc_ctx_priv *ctx_priv = pair->private;
+   /* start context once */
+   if (ctx_priv->first_convert) {
+   fsl_easrc_start_context(pair);
+   ctx_priv->first_convert = 0;
+   }
+
+   return 0;
+}
+
+static int fsl_easrc_m2m_stop_part_two(struct fsl_asrc_pair *pair)
+{
+   struct fsl_easrc_ctx_priv *ctx_priv = pair->private;
+   /* Stop pair/context */
+   if (!ctx_priv->first_convert) {
+   fsl_easrc_stop_context(pair);
+   ctx_priv->first_convert = 1;
+   }
+
+   return 0;
+}
+
+static int fsl_easrc_m2m_check_format(u8 dir, u32 format)
+{
+   u64 support_format = FSL_EASRC_FORMATS;
+
+   if (dir == OUT)
+   support_format |= SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE;
+
+   if (!(1 << format & support_format))
+   return -EINVAL;
+
+   return 0;
+}
+
+static int fsl_easrc_m2m_check_rate(u8 dir, u32 rate)
+{
+   if (rate < 8000 || rate > 768000)
+   return -EINVAL;
+
+   return 0;
+}
+
+static int fsl_easrc_m2m_check_channel(u8 dir, u32 channels)
+{
+   if (channels < 1 || channels > 32)
+   return -EINVAL;
+
+   return 0;
+}
+
+/* calculate capture data length according to output data length and sample 
rate */
+static int fsl_easrc_m2m_calc_out_len(struct fsl_asrc_pair *pair, int 
input_buffer_length)
+{
+   struct fsl_asrc *easrc = pair->asrc;
+   struct fsl_easrc_priv *easrc_priv = easrc->private;
+   struct fsl_easrc_ctx_priv *ctx_priv = pair->private;
+   unsigned int in_rate = ctx_priv->in_params.norm_rate;
+   unsigned int out_rate = ctx_priv->out_params.norm_rate;
+   unsigned int channels = pair->channels;
+   unsigned int in_samples, out_samples;
+   unsigned int in_width, out_width;
+   unsigned int out_length;
+   unsigned int frac_bits;
+   u64 val1, val2;
+
+   switch (easrc_priv->rs_num_taps) {
+   case EASRC_RS_32_TAPS:
+

[RFC PATCH v4 01/11] ASoC: fsl_asrc: define functions for memory to memory usage

2023-09-20 Thread Shengjiu Wang
ASRC can be used on memory to memory case, define several
functions for m2m usage.

m2m_start_part_one: first part of the start steps
m2m_start_part_two: second part of the start steps
m2m_stop_part_one: first part of stop steps
m2m_stop_part_two: second part of stop steps, optional
m2m_check_format: check format is supported or not
m2m_calc_out_len: calculate output length according to input length
m2m_get_maxburst: burst size for dma
m2m_pair_suspend: suspend function of pair, optional.
m2m_pair_resume: resume function of pair
get_output_fifo_size: get remaining data size in FIFO

Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/fsl_asrc.c| 150 
 sound/soc/fsl/fsl_asrc.h|   2 +
 sound/soc/fsl/fsl_asrc_common.h |  42 +
 3 files changed, 194 insertions(+)

diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index b793263291dc..f9d830e0957f 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -1063,6 +1063,145 @@ static int fsl_asrc_get_fifo_addr(u8 dir, enum 
asrc_pair_index index)
return REG_ASRDx(dir, index);
 }
 
+/* Get sample numbers in FIFO */
+static unsigned int fsl_asrc_get_output_fifo_size(struct fsl_asrc_pair *pair)
+{
+   struct fsl_asrc *asrc = pair->asrc;
+   enum asrc_pair_index index = pair->index;
+   u32 val;
+
+   regmap_read(asrc->regmap, REG_ASRFST(index), );
+
+   val &= ASRFSTi_OUTPUT_FIFO_MASK;
+
+   return val >> ASRFSTi_OUTPUT_FIFO_SHIFT;
+}
+
+static int fsl_asrc_m2m_start_part_one(struct fsl_asrc_pair *pair)
+{
+   struct fsl_asrc_pair_priv *pair_priv = pair->private;
+   struct fsl_asrc *asrc = pair->asrc;
+   struct device *dev = >pdev->dev;
+   struct asrc_config config;
+   int ret;
+
+   /* fill config */
+   config.pair = pair->index;
+   config.channel_num = pair->channels;
+   config.input_sample_rate = pair->rate[IN];
+   config.output_sample_rate = pair->rate[OUT];
+   config.input_format = pair->sample_format[IN];
+   config.output_format = pair->sample_format[OUT];
+   config.inclk = INCLK_NONE;
+   config.outclk = OUTCLK_ASRCK1_CLK;
+
+   pair_priv->config = 
+   ret = fsl_asrc_config_pair(pair, true);
+   if (ret) {
+   dev_err(dev, "failed to config pair: %d\n", ret);
+   return ret;
+   }
+
+   fsl_asrc_start_pair(pair);
+
+   return 0;
+}
+
+static int fsl_asrc_m2m_start_part_two(struct fsl_asrc_pair *pair)
+{
+   /*
+* Clear DMA request during the stall state of ASRC:
+* During STALL state, the remaining in input fifo would never be
+* smaller than the input threshold while the output fifo would not
+* be bigger than output one. Thus the DMA request would be cleared.
+*/
+   fsl_asrc_set_watermarks(pair, ASRC_FIFO_THRESHOLD_MIN,
+   ASRC_FIFO_THRESHOLD_MAX);
+
+   /* Update the real input threshold to raise DMA request */
+   fsl_asrc_set_watermarks(pair, ASRC_M2M_INPUTFIFO_WML,
+   ASRC_M2M_OUTPUTFIFO_WML);
+
+   return 0;
+}
+
+static int fsl_asrc_m2m_stop_part_one(struct fsl_asrc_pair *pair)
+{
+   fsl_asrc_stop_pair(pair);
+
+   return 0;
+}
+
+static int fsl_asrc_m2m_check_format(u8 dir, u32 format)
+{
+   u64 support_format = FSL_ASRC_FORMATS;
+
+   if (dir == IN)
+   support_format |= SNDRV_PCM_FMTBIT_S8;
+
+   if (!(1 << format & support_format))
+   return -EINVAL;
+
+   return 0;
+}
+
+static int fsl_asrc_m2m_check_rate(u8 dir, u32 rate)
+{
+   if (rate < 5512 || rate > 192000)
+   return -EINVAL;
+
+   return 0;
+}
+
+static int fsl_asrc_m2m_check_channel(u8 dir, u32 channels)
+{
+   if (channels < 1 || channels > 10)
+   return -EINVAL;
+
+   return 0;
+}
+
+/* calculate capture data length according to output data length and sample 
rate */
+static int fsl_asrc_m2m_calc_out_len(struct fsl_asrc_pair *pair, int 
input_buffer_length)
+{
+   unsigned int in_width, out_width;
+   unsigned int channels = pair->channels;
+   unsigned int in_samples, out_samples;
+   unsigned int out_length;
+
+   in_width = snd_pcm_format_physical_width(pair->sample_format[IN]) / 8;
+   out_width = snd_pcm_format_physical_width(pair->sample_format[OUT]) / 8;
+
+   in_samples = input_buffer_length / in_width / channels;
+   out_samples = pair->rate[OUT] * in_samples / pair->rate[IN];
+   out_length = (out_samples - ASRC_OUTPUT_LAST_SAMPLE) * out_width * 
channels;
+
+   return out_length;
+}
+
+static int fsl_asrc_m2m_get_maxburst(u8 dir, struct fsl_asrc_pair *pair)
+{
+   struct fsl_asrc *asrc = pair->asrc;
+   struct fsl_asrc_priv *asrc_priv = asrc->private;
+   int wml = (dir == IN) ? ASRC_M2M_INPUTFIFO_WML : 
ASRC_M2M_OUTPUTFIFO_WML;
+
+   if (!asrc_priv->soc->use_edma)
+   return 

[RFC PATCH v4 00/11] Add audio support in v4l2 framework

2023-09-20 Thread Shengjiu Wang
Audio signal processing also has the requirement for memory to
memory similar as Video.

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

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

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

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

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

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

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

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

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

Shengjiu Wang (11):
  ASoC: fsl_asrc: define functions for memory to memory usage
  ASoC: fsl_easrc: define functions for memory to memory usage
  ASoC: fsl_asrc: move fsl_asrc_common.h to include/sound
  ASoC: fsl_asrc: register m2m platform device
  ASoC: fsl_easrc: register m2m platform device
  media: uapi: Add V4L2_CAP_AUDIO_M2M capability flag
  media: uapi: Add V4L2_AUDIO_FMT_LPCM fourcc format
  media: v4l2: Add audio capture and output support
  media: uapi: Add V4L2_CID_USER_IMX_ASRC_RATIO_MOD control
  media: audm2m: add virtual driver for audio memory to memory
  media: imx-asrc: Add memory to memory driver

 .../userspace-api/media/v4l/audio-formats.rst |   15 +
 .../userspace-api/media/v4l/buffer.rst|6 +
 .../userspace-api/media/v4l/control.rst   |5 +
 .../userspace-api/media/v4l/dev-audio.rst |   63 +
 .../userspace-api/media/v4l/devices.rst   |1 +
 .../media/v4l/pixfmt-aud-lpcm.rst |   61 +
 .../userspace-api/media/v4l/pixfmt.rst|1 +
 .../media/v4l/vidioc-enum-fmt.rst |2 +
 .../userspace-api/media/v4l/vidioc-g-fmt.rst  |4 +
 .../media/v4l/vidioc-querycap.rst |3 +
 .../media/videodev2.h.rst.exceptions  |3 +
 .../media/common/videobuf2/videobuf2-v4l2.c   |4 +
 drivers/media/platform/nxp/Kconfig|   12 +
 drivers/media/platform/nxp/Makefile   |1 +
 drivers/media/platform/nxp/imx-asrc.c | 1058 +
 drivers/media/test-drivers/Kconfig|9 +
 drivers/media/test-drivers/Makefile   |1 +
 drivers/media/test-drivers/audm2m.c   |  767 
 drivers/media/v4l2-core/v4l2-ctrls-defs.c |1 +
 drivers/media/v4l2-core/v4l2-dev.c|   17 +
 drivers/media/v4l2-core/v4l2-ioctl.c  |   53 +
 include/media/v4l2-dev.h  |2 +
 include/media/v4l2-ioctl.h|   34 +
 .../fsl => include/sound}/fsl_asrc_common.h   |   54 +
 include/uapi/linux/v4l2-controls.h|1 +
 include/uapi/linux/videodev2.h|   25 +
 sound/soc/fsl/fsl_asrc.c  |  162 +++
 sound/soc/fsl/fsl_asrc.h  |4 +-
 sound/soc/fsl/fsl_asrc_dma.c  |2 +-
 sound/soc/fsl/fsl_easrc.c |  239 
 sound/soc/fsl/fsl_easrc.h |8 +-
 31 files changed, 2615 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/userspace-api/media/v4l/audio-formats.rst
 create mode 100644 Documentation/userspace-api/media/v4l/dev-audio.rst
 create mode 100644 Documentation/userspace-api/media/v4l/pixfmt-aud-lpcm.rst
 create mode 100644 drivers/media/platform/nxp/imx-asrc.c
 create mode 100644 drivers/media/test-drivers/audm2m.c
 rename {sound/soc/fsl => include/sound}/fsl_asrc_common.h (60%)

-- 
2.34.1



Re: (subset) [PATCH v4 23/28] mfd: core: Ensure disabled devices are skiped without aborting

2023-09-20 Thread Lee Jones
On Fri, 18 Aug 2023 18:39:17 +0200, Christophe Leroy wrote:
> The loop searching for a matching device based on its compatible
> string is aborted when a matching disabled device is found.
> This abort prevents to add devices as soon as one disabled device
> is found.
> 
> Continue searching for an other device instead of aborting on the
> first disabled one fixes the issue.
> 
> [...]

Applied, thanks!

[23/28] mfd: core: Ensure disabled devices are skiped without aborting
commit: 36d139dc63db18eb95165fcc2bd3c670c948d605

--
Lee Jones [李琼斯]



Re: [PATCH 0/7] arch/*: config: Remove ReiserFS from defconfig

2023-09-20 Thread Geert Uytterhoeven
Hi Peter,

On Tue, Sep 19, 2023 at 6:16 PM Peter Lafreniere  wrote:
> On Tue, Sep 19, 2023 at 12:02, Geert Uytterhoeven  
> wrote:
> > On Tue, Sep 19, 2023 at 5:58 PM Peter Lafreniere pe...@n8pjl.ca wrote:
> > > 2) Stops building an obsolete and largely-unused filesystem unnecessarily.
> > > Some hobbyist targets like m68k and alpha may prefer to keep all 
> > > filesystems
> > > available until total removal, but others like arm and UML have no need 
> > > for
> > > ReiserFS to be built unless specifically configured.
> >
> >
> > As UML is used a lot for testing, isn't it actually counter-productive
> > to remove ReiserFS from the UML defconfig? The less testing it
> > receives, the higher the chance of introducing regressions.
>
> UML is used for testing, but in my view that makes the inclusion of
> ReiserFS in its defconfig even worse. Users of UML are trying to test a

Why?
Because you want to avoid doing any testing at all on deprecated features?

> particular function, and so tend to use ext[2-4], as those are included in
> the defconfig and are well tested and stable. So there is no extra testing
> being done on ReiserFS due to its inclusion in the defconfig.

I'd expect global file system testers to use something along the line of:

for i in $(grep -v nodev /proc/filesystems ); do
echo --- Testing $i ---
dd if=/dev/zero of=testimage bs=1M count=1 seek=1
mkfs.$i testimage
mount testimage /mnt -t $i
[run xfstests on testimage]
rm -f testimage
done

> Keeping UML's defconfig as slim as possible improves build times, which is
> particularly important for kernel testing and development.

Good luck testing all functionality using a "slim" kernel ;-)

Gr{oetje,eeting}s,

Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds


Re: [PATCH v4 2/5] fbdev: Replace fb_pgprotect() with pgprot_framebuffer()

2023-09-20 Thread Javier Martinez Canillas
Thomas Zimmermann  writes:

Hello Thomas,

> Rename the fbdev mmap helper fb_pgprotect() to pgprot_framebuffer().
> The helper sets VMA page-access flags for framebuffers in device I/O
> memory.
>

I think this rename makes it more clear.

> Also clean up the helper's parameters and return value. Instead of
> the VMA instance, pass the individial parameters separately: existing
> page-access flags, the VMAs start and end addresses and the offset

But I fail to see the benefit of this part. Could you please add an
explanation about why this change is desirable ?

-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat



Re: [PATCH v4 1/5] fbdev: Avoid file argument in fb_pgprotect()

2023-09-20 Thread Javier Martinez Canillas
Thomas Zimmermann  writes:

Hello Thomas,

> Only PowerPC's fb_pgprotect() needs the file argument, although
> the implementation does not use it. Pass NULL to the internal

Can you please mention the function that's the implementation for
PowerPC ? If I'm looking at the code correctly, that function is
phys_mem_access_prot() defined in the arch/powerpc/mm/mem.c file:

pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
  unsigned long size, pgprot_t vma_prot)
{
if (ppc_md.phys_mem_access_prot)
return ppc_md.phys_mem_access_prot(file, pfn, size, vma_prot);

if (!page_is_ram(pfn))
vma_prot = pgprot_noncached(vma_prot);

return vma_prot;
}

and if set, ppc_md.phys_mem_access_prot is pci_phys_mem_access_prot()
that is defined in the arch/powerpc/kernel/pci-common.c source file:

https://elixir.bootlin.com/linux/v6.6-rc2/source/arch/powerpc/kernel/pci-common.c#L524

That function indeed doesn't use the file argument. So your patch looks
correct to me.

Reviewed-by: Javier Martinez Canillas 

-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat



Re: [RFC PATCH v12 02/33] KVM: Use gfn instead of hva for mmu_notifier_retry

2023-09-20 Thread Xu Yilun
On 2023-09-13 at 18:55:00 -0700, Sean Christopherson wrote:
> From: Chao Peng 
> 
> Currently in mmu_notifier invalidate path, hva range is recorded and
> then checked against by mmu_notifier_retry_hva() in the page fault
  ^

Now it is mmu_invalidate_retry_hva().

> handling path. However, for the to be introduced private memory, a page
> fault may not have a hva associated, checking gfn(gpa) makes more sense.
> 
> For existing hva based shared memory, gfn is expected to also work. The
> only downside is when aliasing multiple gfns to a single hva, the
> current algorithm of checking multiple ranges could result in a much
> larger range being rejected. Such aliasing should be uncommon, so the
> impact is expected small.
> 
> Suggested-by: Sean Christopherson 
> Signed-off-by: Chao Peng 
> Reviewed-by: Fuad Tabba 
> Tested-by: Fuad Tabba 
> [sean: convert vmx_set_apic_access_page_addr() to gfn-based API]
> Signed-off-by: Sean Christopherson 
> ---
>  arch/x86/kvm/mmu/mmu.c   | 10 ++
>  arch/x86/kvm/vmx/vmx.c   | 11 +--
>  include/linux/kvm_host.h | 33 +
>  virt/kvm/kvm_main.c  | 40 +++-
>  4 files changed, 63 insertions(+), 31 deletions(-)
> 
> diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
> index e1d011c67cc6..0f0231d2b74f 100644
> --- a/arch/x86/kvm/mmu/mmu.c
> +++ b/arch/x86/kvm/mmu/mmu.c
> @@ -3056,7 +3056,7 @@ static void direct_pte_prefetch(struct kvm_vcpu *vcpu, 
> u64 *sptep)
>   *
>   * There are several ways to safely use this helper:
>   *
> - * - Check mmu_invalidate_retry_hva() after grabbing the mapping level, 
> before
> + * - Check mmu_invalidate_retry_gfn() after grabbing the mapping level, 
> before
>   *   consuming it.  In this case, mmu_lock doesn't need to be held during the
>   *   lookup, but it does need to be held while checking the MMU notifier.
>   *
> @@ -4358,7 +4358,7 @@ static bool is_page_fault_stale(struct kvm_vcpu *vcpu,
>   return true;
>  
>   return fault->slot &&
> -mmu_invalidate_retry_hva(vcpu->kvm, fault->mmu_seq, fault->hva);
> +mmu_invalidate_retry_gfn(vcpu->kvm, fault->mmu_seq, fault->gfn);
>  }
>  
>  static int direct_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault 
> *fault)
> @@ -6253,7 +6253,9 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t 
> gfn_start, gfn_t gfn_end)
>  
>   write_lock(>mmu_lock);
>  
> - kvm_mmu_invalidate_begin(kvm, 0, -1ul);
> + kvm_mmu_invalidate_begin(kvm);
> +
> + kvm_mmu_invalidate_range_add(kvm, gfn_start, gfn_end);
>  
>   flush = kvm_rmap_zap_gfn_range(kvm, gfn_start, gfn_end);
>  
> @@ -6266,7 +6268,7 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t 
> gfn_start, gfn_t gfn_end)
>   if (flush)
>   kvm_flush_remote_tlbs_range(kvm, gfn_start, gfn_end - 
> gfn_start);
>  
> - kvm_mmu_invalidate_end(kvm, 0, -1ul);
> + kvm_mmu_invalidate_end(kvm);
>  
>   write_unlock(>mmu_lock);
>  }
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index 72e3943f3693..6e502ba93141 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -6757,10 +6757,10 @@ static void vmx_set_apic_access_page_addr(struct 
> kvm_vcpu *vcpu)
>   return;
>  
>   /*
> -  * Grab the memslot so that the hva lookup for the mmu_notifier retry
> -  * is guaranteed to use the same memslot as the pfn lookup, i.e. rely
> -  * on the pfn lookup's validation of the memslot to ensure a valid hva
> -  * is used for the retry check.
> +  * Explicitly grab the memslot using KVM's internal slot ID to ensure
> +  * KVM doesn't unintentionally grab a userspace memslot.  It _should_
> +  * be impossible for userspace to create a memslot for the APIC when
> +  * APICv is enabled, but paranoia won't hurt in this case.
>*/
>   slot = id_to_memslot(slots, APIC_ACCESS_PAGE_PRIVATE_MEMSLOT);
>   if (!slot || slot->flags & KVM_MEMSLOT_INVALID)
> @@ -6785,8 +6785,7 @@ static void vmx_set_apic_access_page_addr(struct 
> kvm_vcpu *vcpu)
>   return;
>  
>   read_lock(>kvm->mmu_lock);
> - if (mmu_invalidate_retry_hva(kvm, mmu_seq,
> -  gfn_to_hva_memslot(slot, gfn))) {
> + if (mmu_invalidate_retry_gfn(kvm, mmu_seq, gfn)) {
>   kvm_make_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu);
>   read_unlock(>kvm->mmu_lock);
>   goto out;
> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index fb6c6109fdca..11d091688346 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -787,8 +787,8 @@ struct kvm {
>   struct mmu_notifier mmu_notifier;
>   unsigned long mmu_invalidate_seq;
>   long mmu_invalidate_in_progress;
> - unsigned long mmu_invalidate_range_start;
> - unsigned long mmu_invalidate_range_end;
> + gfn_t mmu_invalidate_range_start;
> +