Re: [PATCH] treewide: Spelling fix in comment
On Fri, 20 Oct 2023 17:31:56 +0800 Kunwu Chan wrote: > reques -> request > > Fixes: 09dde54c6a69 ("PS3: gelic: Add wireless support for PS3") > Signed-off-by: Kunwu Chan Appears to have been applied to net, thank you!
[PATCH v2 1/3] hvc/xen: fix event channel handling for secondary consoles
From: David Woodhouse The xencons_connect_backend() function allocates a local interdomain event channel with xenbus_alloc_evtchn(), then calls bind_interdomain_evtchn_to_irq_lateeoi() to bind to that port# on the *remote* domain. That doesn't work very well: (qemu) device_add xen-console,id=con1,chardev=pty0 [ 44.323872] xenconsole console-1: 2 xenbus_dev_probe on device/console/1 [ 44.323995] xenconsole: probe of console-1 failed with error -2 Fix it to use bind_evtchn_to_irq_lateeoi(), which does the right thing by just binding that *local* event channel to an irq. The backend will do the interdomain binding. This didn't affect the primary console because the setup for that is special — the toolstack allocates the guest event channel and the guest discovers it with HVMOP_get_param. Fixes: fe415186b4 ("xen/console: harden hvc_xen against event channel storms") Signed-off-by: David Woodhouse Reviewed-by: Juergen Gross Cc: sta...@vger.kernel.org --- drivers/tty/hvc/hvc_xen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index 98764e740c07..f24e285b6441 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c @@ -433,7 +433,7 @@ static int xencons_connect_backend(struct xenbus_device *dev, if (ret) return ret; info->evtchn = evtchn; - irq = bind_interdomain_evtchn_to_irq_lateeoi(dev, evtchn); + irq = bind_evtchn_to_irq_lateeoi(evtchn); if (irq < 0) return irq; info->irq = irq; -- 2.40.1
[PATCH v2 3/3] hvc/xen: fix console unplug
From: David Woodhouse On unplug of a Xen console, xencons_disconnect_backend() unconditionally calls free_irq() via unbind_from_irqhandler(), causing a warning of freeing an already-free IRQ: (qemu) device_del con1 [ 32.050919] [ cut here ] [ 32.050942] Trying to free already-free IRQ 33 [ 32.050990] WARNING: CPU: 0 PID: 51 at kernel/irq/manage.c:1895 __free_irq+0x1d4/0x330 It should be using evtchn_put() to tear down the event channel binding, and let the Linux IRQ side of it be handled by notifier_del_irq() through the HVC code. On which topic... xencons_disconnect_backend() should call hvc_remove() *first*, rather than tearing down the event channel and grant mapping while they are in use. And then the IRQ is guaranteed to be freed by the time it's torn down by evtchn_put(). Since evtchn_put() also closes the actual event channel, avoid calling xenbus_free_evtchn() except in the failure path where the IRQ was not successfully set up. However, calling hvc_remove() at the start of xencons_disconnect_backend() still isn't early enough. An unplug request is indicated by the backend setting its state to XenbusStateClosing, which triggers a notification to xencons_backend_changed(), which... does nothing except set its own frontend state directly to XenbusStateClosed without *actually* tearing down the HVC device or, you know, making sure it isn't actively in use. So the backend sees the guest frontend set its state to XenbusStateClosed and stops servicing the interrupt... and the guest spins for ever in the domU_write_console() function waiting for the ring to drain. Fix that one by calling hvc_remove() from xencons_backend_changed() before signalling to the backend that it's OK to proceed with the removal. Tested with 'dd if=/dev/zero of=/dev/hvc1' while telling Qemu to remove the console device. Signed-off-by: David Woodhouse Cc: sta...@vger.kernel.org --- drivers/tty/hvc/hvc_xen.c | 32 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index 4a768b504263..34c01874f45b 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c @@ -377,18 +377,21 @@ void xen_console_resume(void) #ifdef CONFIG_HVC_XEN_FRONTEND static void xencons_disconnect_backend(struct xencons_info *info) { - if (info->irq > 0) - unbind_from_irqhandler(info->irq, NULL); - info->irq = 0; + if (info->hvc != NULL) + hvc_remove(info->hvc); + info->hvc = NULL; + if (info->irq > 0) { + evtchn_put(info->evtchn); + info->irq = 0; + info->evtchn = 0; + } + /* evtchn_put() will also close it so this is only an error path */ if (info->evtchn > 0) xenbus_free_evtchn(info->xbdev, info->evtchn); info->evtchn = 0; if (info->gntref > 0) gnttab_free_grant_references(info->gntref); info->gntref = 0; - if (info->hvc != NULL) - hvc_remove(info->hvc); - info->hvc = NULL; } static void xencons_free(struct xencons_info *info) @@ -553,10 +556,23 @@ static void xencons_backend_changed(struct xenbus_device *dev, if (dev->state == XenbusStateClosed) break; fallthrough;/* Missed the backend's CLOSING state */ - case XenbusStateClosing: + case XenbusStateClosing: { + struct xencons_info *info = dev_get_drvdata(&dev->dev);; + + /* +* Don't tear down the evtchn and grant ref before the other +* end has disconnected, but do stop userspace from trying +* to use the device before we allow the backend to close. +*/ + if (info->hvc) { + hvc_remove(info->hvc); + info->hvc = NULL; + } + xenbus_frontend_closed(dev); break; } + } } static const struct xenbus_device_id xencons_ids[] = { @@ -616,7 +632,7 @@ static int __init xen_hvc_init(void) list_del(&info->list); spin_unlock_irqrestore(&xencons_lock, flags); if (info->irq) - unbind_from_irqhandler(info->irq, NULL); + evtchn_put(info->evtchn); kfree(info); return r; } -- 2.40.1
[PATCH v2 0/3] hvc/xen: Xen console fixes.
It started out relatively simple, fixing the fact that the secondary consoles didn't work at *all* due to bugs in the IRQ setup. There were one or two other simple fixes that I snuck into the same patch in v1. But it's much more broken than that, so split the fixes out, especially the last one for hot-unplug. Preserving the Reviewed-by: from Jürgen on the first two seems fair; the third patch is new and exciting but *does* fix the case of removing the console while userspace is spamming it. And all I really wanted to do this week was spin up a PV guest under KVM so I could play with its SMEP behaviour... David Woodhouse (3): hvc/xen: fix event channel handling for secondary consoles hvc/xen: fix error path in xen_hvc_init() to always register frontend driver hvc/xen: fix console unplug drivers/tty/hvc/hvc_xen.c | 39 --- 1 file changed, 28 insertions(+), 11 deletions(-)
[PATCH v2 2/3] hvc/xen: fix error path in xen_hvc_init() to always register frontend driver
From: David Woodhouse The xen_hvc_init() function should always register the frontend driver, even when there's no primary console — as there may be secondary consoles. (Qemu can always add secondary consoles, but only the toolstack can add the primary because it's special.) Signed-off-by: David Woodhouse Reviewed-by: Juergen Gross Cc: sta...@vger.kernel.org --- drivers/tty/hvc/hvc_xen.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index f24e285b6441..4a768b504263 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c @@ -588,7 +588,7 @@ static int __init xen_hvc_init(void) ops = &dom0_hvc_ops; r = xen_initial_domain_console_init(); if (r < 0) - return r; + goto register_fe; info = vtermno_to_xencons(HVC_COOKIE); } else { ops = &domU_hvc_ops; @@ -597,7 +597,7 @@ static int __init xen_hvc_init(void) else r = xen_pv_console_init(); if (r < 0) - return r; + goto register_fe; info = vtermno_to_xencons(HVC_COOKIE); info->irq = bind_evtchn_to_irq_lateeoi(info->evtchn); @@ -622,6 +622,7 @@ static int __init xen_hvc_init(void) } r = 0; + register_fe: #ifdef CONFIG_HVC_XEN_FRONTEND r = xenbus_register_frontend(&xencons_driver); #endif -- 2.40.1
Re: [PATCH] hvc/xen: fix event channel handling for secondary consoles
On Fri, 2023-10-20 at 10:51 +0200, Juergen Gross wrote: > > > (qemu) device_del con1 > > [ 32.050919] [ cut here ] > > [ 32.050942] Trying to free already-free IRQ 33 > > [ 32.050990] WARNING: CPU: 0 PID: 51 at kernel/irq/manage.c:1895 > > __free_irq+0x1d4/0x330 > > > > Fix that by calling notifier_del_irq() first, which only calls > > free_irq() if the irq was requested in the first place. Then use > > I don't think the "if the irq was requested in the first place" is the correct > reasoning. > > I think the problem is that notifier_del_irq() will be called another time > through the .notifier_del hook. Two calls of notifier_del_irq() are fine, but > one call of it and another call of free_irq() via unbind_from_irqhandler() is > a problem. Er... yes, the HVC tty device still exists, can still be open and in use by userspace during the time that xencons_disconnect_backend() is running. Why does xencons_disconnect_backend() do all the evtchn and gnttab teardown *first* and then only call hvc_remove() at the end. That seems weird. So if I do 'dd if=/dev/zero of=/dev/hvc1' while I remove the device from qemu... yep, that seems to have filled the ring after the evtchn was torn down, and it's waiting for ever in domU_write_console(). In fact, that isn't *even* because of the race within xencons_disconnect_backend(). In xencons_backend_changed() when the backend goes into state XenbusStateClos{ing,ed} for the disconnect, we just set the frontend state directly to XenbusStateClosed without even *calling* xencons_disconnect_backend(). So we were *told* of the impending unplug. We fail to actually stop using the device, but we tell the backend that it's OK to go away. Oops :) The incremental patch below makes it work if I unplug a console while writing /dev/zero to it. But I suspect instead of calling xencons_disconnect_backend() when the backend changes to XenbusStateClos{ing,ed}, it should actually *just* do the hvc_close() part? The evtchn and gnttab cleanup should wait until the backend has actually finished closing? And what locking is there around xencons_disconnect_backend() anyway? Do we rely on the fact that it can all only happen from the xenstore watch thread? diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index f0376612b267..0806078835f6 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c @@ -377,8 +377,10 @@ void xen_console_resume(void) #ifdef CONFIG_HVC_XEN_FRONTEND static void xencons_disconnect_backend(struct xencons_info *info) { + if (info->hvc != NULL) + hvc_remove(info->hvc); + info->hvc = NULL; if (info->irq > 0) { - notifier_del_irq(info->hvc, info->irq); evtchn_put(info->evtchn); info->irq = 0; info->evtchn = 0; @@ -390,9 +392,6 @@ static void xencons_disconnect_backend(struct xencons_info *info) if (info->gntref > 0) gnttab_free_grant_references(info->gntref); info->gntref = 0; - if (info->hvc != NULL) - hvc_remove(info->hvc); - info->hvc = NULL; } static void xencons_free(struct xencons_info *info) @@ -558,6 +557,7 @@ static void xencons_backend_changed(struct xenbus_device *dev, break; fallthrough;/* Missed the backend's CLOSING state */ case XenbusStateClosing: + xencons_disconnect_backend(dev_get_drvdata(&dev->dev)); xenbus_frontend_closed(dev); break; } smime.p7s Description: S/MIME cryptographic signature
Re: [PATCH v6 5/5] powerpc/bpf: use bpf_jit_binary_pack_[alloc|finalize|free]
On 19/10/23 11:41 am, Michael Ellerman wrote: Hari Bathini writes: Use bpf_jit_binary_pack_alloc in powerpc jit. The jit engine first writes the program to the rw buffer. When the jit is done, the program is copied to the final location with bpf_jit_binary_pack_finalize. With multiple jit_subprogs, bpf_jit_free is called on some subprograms that haven't got bpf_jit_binary_pack_finalize() yet. Implement custom bpf_jit_free() like in commit 1d5f82d9dd47 ("bpf, x86: fix freeing of not-finalized bpf_prog_pack") to call bpf_jit_binary_pack_finalize(), if necessary. As bpf_flush_icache() is not needed anymore, remove it. Signed-off-by: Hari Bathini Acked-by: Song Liu --- arch/powerpc/net/bpf_jit.h| 18 ++--- arch/powerpc/net/bpf_jit_comp.c | 106 ++ arch/powerpc/net/bpf_jit_comp32.c | 13 ++-- arch/powerpc/net/bpf_jit_comp64.c | 10 +-- 4 files changed, 96 insertions(+), 51 deletions(-) This causes a crash at boot on my Power7 box: Thanks, Michael. Posted v7. - Hari
[PATCH v7 1/5] powerpc/code-patching: introduce patch_instructions()
patch_instruction() entails setting up pte, patching the instruction, clearing the pte and flushing the tlb. If multiple instructions need to be patched, every instruction would have to go through the above drill unnecessarily. Instead, introduce patch_instructions() function that sets up the pte, clears the pte and flushes the tlb only once per page range of instructions to be patched. Duplicate most of the patch_instruction() code instead of merging with it, to avoid the performance degradation observed on ppc32, for patch_instruction(), with the code path merged. Also, setup poking_init() always as BPF expects poking_init() to be setup even when STRICT_KERNEL_RWX is off. Signed-off-by: Hari Bathini Acked-by: Song Liu --- Changes in v7: * Fixed crash observed with !STRICT_RWX. arch/powerpc/include/asm/code-patching.h | 1 + arch/powerpc/lib/code-patching.c | 141 ++- 2 files changed, 139 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h index 3f881548fb61..0e29ccf903d0 100644 --- a/arch/powerpc/include/asm/code-patching.h +++ b/arch/powerpc/include/asm/code-patching.h @@ -74,6 +74,7 @@ int create_cond_branch(ppc_inst_t *instr, const u32 *addr, int patch_branch(u32 *addr, unsigned long target, int flags); int patch_instruction(u32 *addr, ppc_inst_t instr); int raw_patch_instruction(u32 *addr, ppc_inst_t instr); +int patch_instructions(u32 *addr, u32 *code, size_t len, bool repeat_instr); static inline unsigned long patch_site_addr(s32 *site) { diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c index b00112d7ad46..e1c1fd9246d8 100644 --- a/arch/powerpc/lib/code-patching.c +++ b/arch/powerpc/lib/code-patching.c @@ -204,9 +204,6 @@ void __init poking_init(void) { int ret; - if (!IS_ENABLED(CONFIG_STRICT_KERNEL_RWX)) - return; - if (mm_patch_enabled()) ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "powerpc/text_poke_mm:online", @@ -378,6 +375,144 @@ int patch_instruction(u32 *addr, ppc_inst_t instr) } NOKPROBE_SYMBOL(patch_instruction); +static int __patch_instructions(u32 *patch_addr, u32 *code, size_t len, bool repeat_instr) +{ + unsigned long start = (unsigned long)patch_addr; + + /* Repeat instruction */ + if (repeat_instr) { + ppc_inst_t instr = ppc_inst_read(code); + + if (ppc_inst_prefixed(instr)) { + u64 val = ppc_inst_as_ulong(instr); + + memset64((u64 *)patch_addr, val, len / 8); + } else { + u32 val = ppc_inst_val(instr); + + memset32(patch_addr, val, len / 4); + } + } else { + memcpy(patch_addr, code, len); + } + + smp_wmb(); /* smp write barrier */ + flush_icache_range(start, start + len); + return 0; +} + +/* + * A page is mapped and instructions that fit the page are patched. + * Assumes 'len' to be (PAGE_SIZE - offset_in_page(addr)) or below. + */ +static int __do_patch_instructions_mm(u32 *addr, u32 *code, size_t len, bool repeat_instr) +{ + struct mm_struct *patching_mm, *orig_mm; + unsigned long pfn = get_patch_pfn(addr); + unsigned long text_poke_addr; + spinlock_t *ptl; + u32 *patch_addr; + pte_t *pte; + int err; + + patching_mm = __this_cpu_read(cpu_patching_context.mm); + text_poke_addr = __this_cpu_read(cpu_patching_context.addr); + patch_addr = (u32 *)(text_poke_addr + offset_in_page(addr)); + + pte = get_locked_pte(patching_mm, text_poke_addr, &ptl); + if (!pte) + return -ENOMEM; + + __set_pte_at(patching_mm, text_poke_addr, pte, pfn_pte(pfn, PAGE_KERNEL), 0); + + /* order PTE update before use, also serves as the hwsync */ + asm volatile("ptesync" ::: "memory"); + + /* order context switch after arbitrary prior code */ + isync(); + + orig_mm = start_using_temp_mm(patching_mm); + + err = __patch_instructions(patch_addr, code, len, repeat_instr); + + /* context synchronisation performed by __patch_instructions */ + stop_using_temp_mm(patching_mm, orig_mm); + + pte_clear(patching_mm, text_poke_addr, pte); + /* +* ptesync to order PTE update before TLB invalidation done +* by radix__local_flush_tlb_page_psize (in _tlbiel_va) +*/ + local_flush_tlb_page_psize(patching_mm, text_poke_addr, mmu_virtual_psize); + + pte_unmap_unlock(pte, ptl); + + return err; +} + +/* + * A page is mapped and instructions that fit the page are patched. + * Assumes 'len' to be (PAGE_SIZE - offset_in_page(addr)) or below. + */ +static int __do_patch_instructions(u32 *addr, u32 *code, size_t len, bool repeat_instr) +{ + unsigned long pfn = get_patch_pfn(addr)
[PATCH v7 5/5] powerpc/bpf: use bpf_jit_binary_pack_[alloc|finalize|free]
Use bpf_jit_binary_pack_alloc in powerpc jit. The jit engine first writes the program to the rw buffer. When the jit is done, the program is copied to the final location with bpf_jit_binary_pack_finalize. With multiple jit_subprogs, bpf_jit_free is called on some subprograms that haven't got bpf_jit_binary_pack_finalize() yet. Implement custom bpf_jit_free() like in commit 1d5f82d9dd47 ("bpf, x86: fix freeing of not-finalized bpf_prog_pack") to call bpf_jit_binary_pack_finalize(), if necessary. As bpf_flush_icache() is not needed anymore, remove it. Signed-off-by: Hari Bathini Acked-by: Song Liu --- * No changes in v7. arch/powerpc/net/bpf_jit.h| 18 ++--- arch/powerpc/net/bpf_jit_comp.c | 106 ++ arch/powerpc/net/bpf_jit_comp32.c | 13 ++-- arch/powerpc/net/bpf_jit_comp64.c | 10 +-- 4 files changed, 96 insertions(+), 51 deletions(-) diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h index 72b7bb34fade..cdea5dccaefe 100644 --- a/arch/powerpc/net/bpf_jit.h +++ b/arch/powerpc/net/bpf_jit.h @@ -36,9 +36,6 @@ EMIT(PPC_RAW_BRANCH(offset)); \ } while (0) -/* bl (unconditional 'branch' with link) */ -#define PPC_BL(dest) EMIT(PPC_RAW_BL((dest) - (unsigned long)(image + ctx->idx))) - /* "cond" here covers BO:BI fields. */ #define PPC_BCC_SHORT(cond, dest)\ do { \ @@ -147,12 +144,6 @@ struct codegen_context { #define BPF_FIXUP_LEN 2 /* Two instructions => 8 bytes */ #endif -static inline void bpf_flush_icache(void *start, void *end) -{ - smp_wmb(); /* smp write barrier */ - flush_icache_range((unsigned long)start, (unsigned long)end); -} - static inline bool bpf_is_seen_register(struct codegen_context *ctx, int i) { return ctx->seen & (1 << (31 - i)); @@ -169,16 +160,17 @@ static inline void bpf_clear_seen_register(struct codegen_context *ctx, int i) } void bpf_jit_init_reg_mapping(struct codegen_context *ctx); -int bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx, u64 func); -int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *ctx, +int bpf_jit_emit_func_call_rel(u32 *image, u32 *fimage, struct codegen_context *ctx, u64 func); +int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct codegen_context *ctx, u32 *addrs, int pass, bool extra_pass); void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx); void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx); void bpf_jit_realloc_regs(struct codegen_context *ctx); int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int tmp_reg, long exit_addr); -int bpf_add_extable_entry(struct bpf_prog *fp, u32 *image, int pass, struct codegen_context *ctx, - int insn_idx, int jmp_off, int dst_reg); +int bpf_add_extable_entry(struct bpf_prog *fp, u32 *image, u32 *fimage, int pass, + struct codegen_context *ctx, int insn_idx, + int jmp_off, int dst_reg); #endif diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index e7ca270a39d5..a79d7c478074 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -44,9 +44,12 @@ int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int tmp_reg, } struct powerpc_jit_data { - struct bpf_binary_header *header; + /* address of rw header */ + struct bpf_binary_header *hdr; + /* address of ro final header */ + struct bpf_binary_header *fhdr; u32 *addrs; - u8 *image; + u8 *fimage; u32 proglen; struct codegen_context ctx; }; @@ -67,11 +70,14 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) struct codegen_context cgctx; int pass; int flen; - struct bpf_binary_header *bpf_hdr; + struct bpf_binary_header *fhdr = NULL; + struct bpf_binary_header *hdr = NULL; struct bpf_prog *org_fp = fp; struct bpf_prog *tmp_fp; bool bpf_blinded = false; bool extra_pass = false; + u8 *fimage = NULL; + u32 *fcode_base; u32 extable_len; u32 fixup_len; @@ -101,9 +107,16 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) addrs = jit_data->addrs; if (addrs) { cgctx = jit_data->ctx; - image = jit_data->image; - bpf_hdr = jit_data->header; + /* +* JIT compiled to a writable location (image/code_base) first. +* It is then moved to the readonly final location (fimage/fcode_base) +* using instruction patching. +*/ + fimage = jit_data->fimage; + fhdr = jit_data->f
[PATCH v7 3/5] powerpc/bpf: implement bpf_arch_text_invalidate for bpf_prog_pack
Implement bpf_arch_text_invalidate and use it to fill unused part of the bpf_prog_pack with trap instructions when a BPF program is freed. Signed-off-by: Hari Bathini Acked-by: Song Liu --- * No changes in v7. arch/powerpc/net/bpf_jit_comp.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index c740eac8d584..ecd7cffbbe28 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -292,3 +292,18 @@ void *bpf_arch_text_copy(void *dst, void *src, size_t len) return err ? ERR_PTR(err) : dst; } + +int bpf_arch_text_invalidate(void *dst, size_t len) +{ + u32 insn = BREAKPOINT_INSTRUCTION; + int ret; + + if (WARN_ON_ONCE(core_kernel_text((unsigned long)dst))) + return -EINVAL; + + mutex_lock(&text_mutex); + ret = patch_instructions(dst, &insn, len, true); + mutex_unlock(&text_mutex); + + return ret; +} -- 2.41.0
[PATCH v7 4/5] powerpc/bpf: rename powerpc64_jit_data to powerpc_jit_data
powerpc64_jit_data is a misnomer as it is meant for both ppc32 and ppc64. Rename it to powerpc_jit_data. Signed-off-by: Hari Bathini Acked-by: Song Liu --- * No changes in v7. arch/powerpc/net/bpf_jit_comp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index ecd7cffbbe28..e7ca270a39d5 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -43,7 +43,7 @@ int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int tmp_reg, return 0; } -struct powerpc64_jit_data { +struct powerpc_jit_data { struct bpf_binary_header *header; u32 *addrs; u8 *image; @@ -63,7 +63,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) u8 *image = NULL; u32 *code_base; u32 *addrs; - struct powerpc64_jit_data *jit_data; + struct powerpc_jit_data *jit_data; struct codegen_context cgctx; int pass; int flen; -- 2.41.0
[PATCH v7 2/5] powerpc/bpf: implement bpf_arch_text_copy
bpf_arch_text_copy is used to dump JITed binary to RX page, allowing multiple BPF programs to share the same page. Use the newly introduced patch_instructions() to implement it. Signed-off-by: Hari Bathini Acked-by: Song Liu --- * No changes in v7. arch/powerpc/net/bpf_jit_comp.c | 20 +++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index 37043dfc1add..c740eac8d584 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -13,9 +13,13 @@ #include #include #include -#include +#include +#include #include +#include +#include + #include "bpf_jit.h" static void bpf_jit_fill_ill_insns(void *area, unsigned int size) @@ -274,3 +278,17 @@ int bpf_add_extable_entry(struct bpf_prog *fp, u32 *image, int pass, struct code ctx->exentry_idx++; return 0; } + +void *bpf_arch_text_copy(void *dst, void *src, size_t len) +{ + int err; + + if (WARN_ON_ONCE(core_kernel_text((unsigned long)dst))) + return ERR_PTR(-EINVAL); + + mutex_lock(&text_mutex); + err = patch_instructions(dst, src, len, false); + mutex_unlock(&text_mutex); + + return err ? ERR_PTR(err) : dst; +} -- 2.41.0
[PATCH v7 0/5] powerpc/bpf: use BPF prog pack allocator
Most BPF programs are small, but they consume a page each. For systems with busy traffic and many BPF programs, this may also add significant pressure on instruction TLB. High iTLB pressure usually slows down the whole system causing visible performance degradation for production workloads. bpf_prog_pack, a customized allocator that packs multiple bpf programs into preallocated memory chunks, was proposed [1] to address it. This series extends this support on powerpc. Both bpf_arch_text_copy() & bpf_arch_text_invalidate() functions, needed for this support depend on instruction patching in text area. Currently, patch_instruction() supports patching only one instruction at a time. The first patch introduces patch_instructions() function to enable patching more than one instruction at a time. This helps in avoiding performance degradation while JITing bpf programs. Patches 2 & 3 implement the above mentioned arch specific functions using patch_instructions(). Patch 4 fixes a misnomer in bpf JITing code. The last patch enables the use of BPF prog pack allocator on powerpc and also, ensures cleanup is handled gracefully. [1] https://lore.kernel.org/bpf/20220204185742.271030-1-s...@kernel.org/ Changes in v7: * Fixed crash observed with !STRICT_RWX. Changes in v6: * No changes in patches 2-5/5 except addition of Acked-by tags from Song. * Skipped merging code path of patch_instruction() & patch_instructions() to avoid performance overhead observed on ppc32 with that. Changes in v5: * Moved introduction of patch_instructions() as 1st patch in series. * Improved patch_instructions() to use memset & memcpy. * Fixed the misnomer in JITing code as a separate patch. * Removed unused bpf_flush_icache() function. Changes in v4: * Updated bpf_patch_instructions() definition in patch 1/5 so that it doesn't have to be updated again in patch 2/5. * Addressed Christophe's comment on bpf_arch_text_invalidate() return value in patch 2/5. Changes in v3: * Fixed segfault issue observed on ppc32 due to inaccurate offset calculation for branching. * Tried to minimize the performance impact for patch_instruction() with the introduction of patch_instructions(). * Corrected uses of u32* vs ppc_instr_t. * Moved the change that introduces patch_instructions() to after enabling bpf_prog_pack support. * Added few comments to improve code readability. Changes in v2: * Introduced patch_instructions() to help with patching bpf programs. Hari Bathini (5): powerpc/code-patching: introduce patch_instructions() powerpc/bpf: implement bpf_arch_text_copy powerpc/bpf: implement bpf_arch_text_invalidate for bpf_prog_pack powerpc/bpf: rename powerpc64_jit_data to powerpc_jit_data powerpc/bpf: use bpf_jit_binary_pack_[alloc|finalize|free] arch/powerpc/include/asm/code-patching.h | 1 + arch/powerpc/lib/code-patching.c | 141 +- arch/powerpc/net/bpf_jit.h | 18 +-- arch/powerpc/net/bpf_jit_comp.c | 145 ++- arch/powerpc/net/bpf_jit_comp32.c| 13 +- arch/powerpc/net/bpf_jit_comp64.c| 10 +- 6 files changed, 271 insertions(+), 57 deletions(-) -- 2.41.0
Re: [PATCH v3 8/9] tty: Add SBI debug console support to HVC SBI driver
On Fri, Oct 20, 2023 at 4:16 PM Andrew Jones wrote: > > On Fri, Oct 20, 2023 at 12:51:39PM +0530, Anup Patel wrote: > > From: Atish Patra > > > > RISC-V SBI specification supports advanced debug console > > support via SBI DBCN extension. > > > > Extend the HVC SBI driver to support it. > > > > Signed-off-by: Atish Patra > > Signed-off-by: Anup Patel > > --- > > drivers/tty/hvc/Kconfig | 2 +- > > drivers/tty/hvc/hvc_riscv_sbi.c | 82 ++--- > > 2 files changed, 76 insertions(+), 8 deletions(-) > > > > diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig > > index 4f9264d005c0..6e05c5c7bca1 100644 > > --- a/drivers/tty/hvc/Kconfig > > +++ b/drivers/tty/hvc/Kconfig > > @@ -108,7 +108,7 @@ config HVC_DCC_SERIALIZE_SMP > > > > config HVC_RISCV_SBI > > bool "RISC-V SBI console support" > > - depends on RISCV_SBI_V01 > > + depends on RISCV_SBI > > select HVC_DRIVER > > help > > This enables support for console output via RISC-V SBI calls, which > > diff --git a/drivers/tty/hvc/hvc_riscv_sbi.c > > b/drivers/tty/hvc/hvc_riscv_sbi.c > > index 31f53fa77e4a..56da1a4b5aca 100644 > > --- a/drivers/tty/hvc/hvc_riscv_sbi.c > > +++ b/drivers/tty/hvc/hvc_riscv_sbi.c > > @@ -39,21 +39,89 @@ static int hvc_sbi_tty_get(uint32_t vtermno, char *buf, > > int count) > > return i; > > } > > > > -static const struct hv_ops hvc_sbi_ops = { > > +static const struct hv_ops hvc_sbi_v01_ops = { > > .get_chars = hvc_sbi_tty_get, > > .put_chars = hvc_sbi_tty_put, > > }; > > > > -static int __init hvc_sbi_init(void) > > +static int hvc_sbi_dbcn_tty_put(uint32_t vtermno, const char *buf, int > > count) > > { > > - return PTR_ERR_OR_ZERO(hvc_alloc(0, 0, &hvc_sbi_ops, 16)); > > + phys_addr_t pa; > > + struct sbiret ret; > > + > > + if (is_vmalloc_addr(buf)) { > > + pa = page_to_phys(vmalloc_to_page(buf)) + offset_in_page(buf); > > + if (PAGE_SIZE < (offset_in_page(buf) + count)) > > I thought checkpatch complained about uppercase constants being on the > left in comparisons. Nope checkpatch does not complain about this. > > > + count = PAGE_SIZE - offset_in_page(buf); > > + } else { > > + pa = __pa(buf); > > + } > > + > > + if (IS_ENABLED(CONFIG_32BIT)) > > + ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_WRITE, > > + count, lower_32_bits(pa), upper_32_bits(pa), > > + 0, 0, 0); > > + else > > + ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_WRITE, > > + count, pa, 0, 0, 0, 0); > > + if (ret.error) > > + return 0; > > + > > + return count; > > Shouldn't we return ret.value here in case it's less than count? I see we > already do that below in get(). Ahh, yes. Good catch, I will update. > > > } > > -device_initcall(hvc_sbi_init); > > > > -static int __init hvc_sbi_console_init(void) > > +static int hvc_sbi_dbcn_tty_get(uint32_t vtermno, char *buf, int count) > > { > > - hvc_instantiate(0, 0, &hvc_sbi_ops); > > + phys_addr_t pa; > > + struct sbiret ret; > > + > > + if (is_vmalloc_addr(buf)) { > > + pa = page_to_phys(vmalloc_to_page(buf)) + offset_in_page(buf); > > + if (PAGE_SIZE < (offset_in_page(buf) + count)) > > + count = PAGE_SIZE - offset_in_page(buf); > > + } else { > > + pa = __pa(buf); > > + } > > + > > + if (IS_ENABLED(CONFIG_32BIT)) > > + ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_READ, > > + count, lower_32_bits(pa), upper_32_bits(pa), > > + 0, 0, 0); > > + else > > + ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_READ, > > + count, pa, 0, 0, 0, 0); > > + if (ret.error) > > + return 0; > > + > > + return ret.value; > > +} > > + > > +static const struct hv_ops hvc_sbi_dbcn_ops = { > > + .put_chars = hvc_sbi_dbcn_tty_put, > > + .get_chars = hvc_sbi_dbcn_tty_get, > > +}; > > + > > +static int __init hvc_sbi_init(void) > > +{ > > + int err; > > + > > + if ((sbi_spec_version >= sbi_mk_version(2, 0)) && > > + (sbi_probe_extension(SBI_EXT_DBCN) > 0)) { > > + err = PTR_ERR_OR_ZERO(hvc_alloc(0, 0, &hvc_sbi_dbcn_ops, 16)); > > Why an outbuf size of only 16? The output buffer size of 16 is a very common choice across HVC drivers. The next best choice is 256. I guess 256 is better so I will go with that. > > > + if (err) > > + return err; > > + hvc_instantiate(0, 0, &hvc_sbi_dbcn_ops); > > + } else { > > + if (IS_ENABLED(CONFIG_RISCV_SBI_V01)) { > > + err = PTR_ERR_OR_ZERO(hvc_alloc(0, 0, > > &hvc_sbi_v01_ops, 16)); > > + if (err) > > +
Re: [PATCH] powerpc/smp: Dynamically build powerpc topology
* Michael Ellerman [2023-10-20 23:10:55]: > Srikar Dronamraju writes: > > Currently there are four powerpc specific sched topologies. These are > > all statically defined. However not all these topologies are used by > > all powerpc systems. > > > > To avoid unnecessary degenerations by the scheduler , masks and flags > > are compared. However if the sched topologies are build dynamically then > > the code is simpler and there are greater chances of avoiding > > degenerations. > > > > Even x86 builds its sched topologies dynamically and new changes are > > very similar to the way x86 is building its topologies. > > > > System Configuration > > type=Shared mode=Uncapped smt=8 lcpu=128 mem=1063126592 kB cpus=96 ent=40.00 > > > > $ lscpu > > Architecture:ppc64le > > Byte Order: Little Endian > > CPU(s): 1024 > > On-line CPU(s) list: 0-1023 > > Model name: POWER10 (architected), altivec supported > > Model: 2.0 (pvr 0080 0200) > > Thread(s) per core: 8 > > Core(s) per socket: 32 > > Socket(s): 4 > > Hypervisor vendor: pHyp > > Virtualization type: para > > L1d cache: 8 MiB (256 instances) > > L1i cache: 12 MiB (256 instances) > > NUMA node(s):4 > > > > From dmesg of v6.5 > > [0.17] smp: Bringing up secondary CPUs ... > > [3.918535] smp: Brought up 4 nodes, 1024 CPUs > > [ 38.001402] sysrq: Changing Loglevel > > [ 38.001446] sysrq: Loglevel set to 9 > > > > From dmesg of v6.5 + patch > > [0.174462] smp: Bringing up secondary CPUs ... > > [3.421462] smp: Brought up 4 nodes, 1024 CPUs > > [ 35.417917] sysrq: Changing Loglevel > > [ 35.417959] sysrq: Loglevel set to 9 > > > > 5 runs of ppc64_cpu --smt=1 (time measured: lesser is better) > > Kernel N Min Max Median Avg Stddev %Change > > v6.55 518.08 574.27 528.61 535.388 22.341542 > > +patch 5 481.73 495.47 484.21 486.402 5.7997 -9.14963 > > > > 5 runs of ppc64_cpu --smt=8 (time measured: lesser is better) > > Kernel N Min Max Median Avg Stddev %Change > > v6.55 1094.12 1117.1 1108.97 1106.38.606361 > > +patch 5 1067.5 1090.03 1073.89 1076.574 9.4189347 -2.68697 > > > > Signed-off-by: Srikar Dronamraju > > --- > > arch/powerpc/kernel/smp.c | 78 ++- > > 1 file changed, 28 insertions(+), 50 deletions(-) > > > > diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c > > index 48b8161179a8..c16443a04c26 100644 > > --- a/arch/powerpc/kernel/smp.c > > +++ b/arch/powerpc/kernel/smp.c > > @@ -92,15 +92,6 @@ EXPORT_PER_CPU_SYMBOL(cpu_l2_cache_map); > > EXPORT_PER_CPU_SYMBOL(cpu_core_map); > > EXPORT_SYMBOL_GPL(has_big_cores); > > > > -enum { > > -#ifdef CONFIG_SCHED_SMT > > - smt_idx, > > -#endif > > - cache_idx, > > - mc_idx, > > - die_idx, > > -}; > > - > > #define MAX_THREAD_LIST_SIZE 8 > > #define THREAD_GROUP_SHARE_L1 1 > > #define THREAD_GROUP_SHARE_L2_L3 2 > > @@ -1048,16 +1039,6 @@ static const struct cpumask *cpu_mc_mask(int cpu) > > return cpu_coregroup_mask(cpu); > > } > > > > -static struct sched_domain_topology_level powerpc_topology[] = { > > -#ifdef CONFIG_SCHED_SMT > > - { cpu_smt_mask, powerpc_smt_flags, SD_INIT_NAME(SMT) }, > > -#endif > > - { shared_cache_mask, powerpc_shared_cache_flags, SD_INIT_NAME(CACHE) }, > > - { cpu_mc_mask, powerpc_shared_proc_flags, SD_INIT_NAME(MC) }, > > - { cpu_cpu_mask, powerpc_shared_proc_flags, SD_INIT_NAME(DIE) }, > > - { NULL, }, > > -}; > > This doesn't apply on my next or upstream. > > It looks like it depends on your other 6-patch series. Please append > this patch to that series. > > cheers Ok, will do the needful in the next iteration. -- Thanks and Regards Srikar Dronamraju
Re: [PATCH v2] powerpc: Enable generic cpu idle-loop
Hi Vaibhav, Vaibhav Jain writes: > This minor patch enables config option GENERIC_IDLE_POLL_SETUP for arch > powerpc. This should add support for kernel param 'nohlt'. > > Powerpc kernel also supports another kernel boot-time param called > 'powersave' which can also be used to disable all cpu idle-states and > forces CPU to an idle-loop similar to what cpu_idle_poll() does. Hence this > patch also updates the handling of 'powersave=off' kernel param to enable > generic cpu idle-loop if its enabled. > > Signed-off-by: Vaibhav Jain > --- > Changelog: > > Since v1: > https://lore.kernel.org/all/20230818050739.827851-1-vaib...@linux.ibm.com > * Updated powersave_off() to enable generic cpu idle-loop if > 'powersave=off' kernel arg is given. [Mpe] > * Update patch description I had already merged the v1 when I saw this, and ... > diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c > index b1c0418b25c8..7367a0698459 100644 > --- a/arch/powerpc/kernel/idle.c > +++ b/arch/powerpc/kernel/idle.c > @@ -35,6 +36,8 @@ EXPORT_SYMBOL(cpuidle_disable); > > static int __init powersave_off(char *arg) > { > + /* Use generic idle loop if thats available */ > + cpu_idle_poll_ctrl(true); > ppc_md.power_save = NULL; > cpuidle_disable = IDLE_POWERSAVE_OFF; > return 1; The hope here would be that we could remove the need for cpuidle_disable. cheers
Re: [PATCH] powerpc/smp: Dynamically build powerpc topology
Srikar Dronamraju writes: > Currently there are four powerpc specific sched topologies. These are > all statically defined. However not all these topologies are used by > all powerpc systems. > > To avoid unnecessary degenerations by the scheduler , masks and flags > are compared. However if the sched topologies are build dynamically then > the code is simpler and there are greater chances of avoiding > degenerations. > > Even x86 builds its sched topologies dynamically and new changes are > very similar to the way x86 is building its topologies. > > System Configuration > type=Shared mode=Uncapped smt=8 lcpu=128 mem=1063126592 kB cpus=96 ent=40.00 > > $ lscpu > Architecture:ppc64le > Byte Order: Little Endian > CPU(s): 1024 > On-line CPU(s) list: 0-1023 > Model name: POWER10 (architected), altivec supported > Model: 2.0 (pvr 0080 0200) > Thread(s) per core: 8 > Core(s) per socket: 32 > Socket(s): 4 > Hypervisor vendor: pHyp > Virtualization type: para > L1d cache: 8 MiB (256 instances) > L1i cache: 12 MiB (256 instances) > NUMA node(s):4 > > From dmesg of v6.5 > [0.17] smp: Bringing up secondary CPUs ... > [3.918535] smp: Brought up 4 nodes, 1024 CPUs > [ 38.001402] sysrq: Changing Loglevel > [ 38.001446] sysrq: Loglevel set to 9 > > From dmesg of v6.5 + patch > [0.174462] smp: Bringing up secondary CPUs ... > [3.421462] smp: Brought up 4 nodes, 1024 CPUs > [ 35.417917] sysrq: Changing Loglevel > [ 35.417959] sysrq: Loglevel set to 9 > > 5 runs of ppc64_cpu --smt=1 (time measured: lesser is better) > Kernel N Min Max Median Avg Stddev %Change > v6.55 518.08 574.27 528.61 535.388 22.341542 > +patch 5 481.73 495.47 484.21 486.402 5.7997 -9.14963 > > 5 runs of ppc64_cpu --smt=8 (time measured: lesser is better) > Kernel N Min Max Median Avg Stddev %Change > v6.55 1094.12 1117.1 1108.97 1106.38.606361 > +patch 5 1067.5 1090.03 1073.89 1076.574 9.4189347 -2.68697 > > Signed-off-by: Srikar Dronamraju > --- > arch/powerpc/kernel/smp.c | 78 ++- > 1 file changed, 28 insertions(+), 50 deletions(-) > > diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c > index 48b8161179a8..c16443a04c26 100644 > --- a/arch/powerpc/kernel/smp.c > +++ b/arch/powerpc/kernel/smp.c > @@ -92,15 +92,6 @@ EXPORT_PER_CPU_SYMBOL(cpu_l2_cache_map); > EXPORT_PER_CPU_SYMBOL(cpu_core_map); > EXPORT_SYMBOL_GPL(has_big_cores); > > -enum { > -#ifdef CONFIG_SCHED_SMT > - smt_idx, > -#endif > - cache_idx, > - mc_idx, > - die_idx, > -}; > - > #define MAX_THREAD_LIST_SIZE 8 > #define THREAD_GROUP_SHARE_L1 1 > #define THREAD_GROUP_SHARE_L2_L3 2 > @@ -1048,16 +1039,6 @@ static const struct cpumask *cpu_mc_mask(int cpu) > return cpu_coregroup_mask(cpu); > } > > -static struct sched_domain_topology_level powerpc_topology[] = { > -#ifdef CONFIG_SCHED_SMT > - { cpu_smt_mask, powerpc_smt_flags, SD_INIT_NAME(SMT) }, > -#endif > - { shared_cache_mask, powerpc_shared_cache_flags, SD_INIT_NAME(CACHE) }, > - { cpu_mc_mask, powerpc_shared_proc_flags, SD_INIT_NAME(MC) }, > - { cpu_cpu_mask, powerpc_shared_proc_flags, SD_INIT_NAME(DIE) }, > - { NULL, }, > -}; This doesn't apply on my next or upstream. It looks like it depends on your other 6-patch series. Please append this patch to that series. cheers
Re: (subset) [PATCH 0/6] powerpc/qspinlock: Fix yield latency bug and other
On Mon, 16 Oct 2023 22:42:59 +1000, Nicholas Piggin wrote: > This fixes a long-standing latency bug in the powerpc qspinlock > implementation that quite a few people have reported and helped > out with debugging. > > The first patch is a minimal fix that avoids the problem. The > other patches are streamlining and improvements after the fix. > > [...] Patch 1 applied to powerpc/fixes. [1/6] powerpc/qspinlock: Fix stale propagated yield_cpu https://git.kernel.org/powerpc/c/f9bc9bbe8afdf83412728f0b464979a72a3b9ec2 cheers
Re: [PATCH] powerpc/64s/radix: Don't warn on copros in radix__tlb_flush()
On Tue, 17 Oct 2023 23:15:27 +1100, Michael Ellerman wrote: > Sachin reported a warning when running the inject-ra-err selftest: > > # selftests: powerpc/mce: inject-ra-err > Disabling lock debugging due to kernel taint > MCE: CPU19: machine check (Severe) Real address Load/Store > (foreign/control memory) [Not recovered] > MCE: CPU19: PID: 5254 Comm: inject-ra-err NIP: [1e48] > MCE: CPU19: Initiator CPU > MCE: CPU19: Unknown > [ cut here ] > WARNING: CPU: 19 PID: 5254 at arch/powerpc/mm/book3s64/radix_tlb.c:1221 > radix__tlb_flush+0x160/0x180 > CPU: 19 PID: 5254 Comm: inject-ra-err Kdump: loaded Tainted: G ME > 6.6.0-rc3-00055-g9ed22ae6be81 #4 > Hardware name: IBM,9080-HEX POWER10 (raw) 0x800200 0xf06 > of:IBM,FW1030.20 (NH1030_058) hv:phyp pSeries > ... > NIP radix__tlb_flush+0x160/0x180 > LR radix__tlb_flush+0x104/0x180 > Call Trace: > radix__tlb_flush+0xf4/0x180 (unreliable) > tlb_finish_mmu+0x15c/0x1e0 > exit_mmap+0x1a0/0x510 > __mmput+0x60/0x1e0 > exit_mm+0xdc/0x170 > do_exit+0x2bc/0x5a0 > do_group_exit+0x4c/0xc0 > sys_exit_group+0x28/0x30 > system_call_exception+0x138/0x330 > system_call_vectored_common+0x15c/0x2ec > > [...] Applied to powerpc/fixes. [1/1] powerpc/64s/radix: Don't warn on copros in radix__tlb_flush() https://git.kernel.org/powerpc/c/20045f0155ab79f8beb840022ea86bff46167f79 cheers
Re: [PATCH v3 0/9] RISC-V SBI debug console extension support
On Fri, Oct 20, 2023 at 12:51 PM Anup Patel wrote: > > The SBI v2.0 specification is now frozen. The SBI v2.0 specification defines > SBI debug console (DBCN) extension which replaces the legacy SBI v0.1 > functions sbi_console_putchar() and sbi_console_getchar(). > (Refer v2.0-rc5 at https://github.com/riscv-non-isa/riscv-sbi-doc/releases) > > This series adds support for SBI debug console (DBCN) extension in KVM RISC-V > and Linux RISC-V. > > To try these patches with KVM RISC-V, use KVMTOOL from riscv_sbi_dbcn_v1 > branch at: https://github.com/avpatel/kvmtool.git > > These patches can also be found in the riscv_sbi_dbcn_v3 branch at: > https://github.com/avpatel/linux.git > > Changes since v2: > - Rebased on Linux-6.6-rc5 > - Handled page-crossing in PATCH7 of v2 series > - Addressed Drew's comment in PATCH3 of v2 series > - Added new PATCH5 to make get-reg-list test aware of SBI DBCN extension > > Changes since v1: > - Remove use of #ifdef from PATCH4 and PATCH5 of the v1 series > - Improved commit description of PATCH3 in v1 series > - Introduced new PATCH3 in this series to allow some SBI extensions >(such as SBI DBCN) do to disabled by default so that older KVM user space >work fine and newer KVM user space have to explicitly opt-in for emulating >SBI DBCN. > - Introduced new PATCH5 in this series which adds inline version of >sbi_console_getchar() and sbi_console_putchar() for the case where >CONFIG_RISCV_SBI_V01 is disabled. > > Anup Patel (8): > RISC-V: Add defines for SBI debug console extension > RISC-V: KVM: Change the SBI specification version to v2.0 > RISC-V: KVM: Allow some SBI extensions to be disabled by default > RISC-V: KVM: Forward SBI DBCN extension to user-space > KVM: riscv: selftests: Add SBI DBCN extension to get-reg-list test > RISC-V: Add stubs for sbi_console_putchar/getchar() > tty/serial: Add RISC-V SBI debug console based earlycon > RISC-V: Enable SBI based earlycon support > > Atish Patra (1): > tty: Add SBI debug console support to HVC SBI driver Queued PATCH1 to PATCH5 for Linux-6.7 Remaining PATCH6 to PATCH9 are still under review. Thanks, Anup > > arch/riscv/configs/defconfig | 1 + > arch/riscv/configs/rv32_defconfig | 1 + > arch/riscv/include/asm/kvm_vcpu_sbi.h | 7 +- > arch/riscv/include/asm/sbi.h | 12 +++ > arch/riscv/include/uapi/asm/kvm.h | 1 + > arch/riscv/kvm/vcpu.c | 6 ++ > arch/riscv/kvm/vcpu_sbi.c | 61 +++--- > arch/riscv/kvm/vcpu_sbi_replace.c | 32 > drivers/tty/hvc/Kconfig | 2 +- > drivers/tty/hvc/hvc_riscv_sbi.c | 82 +-- > drivers/tty/serial/Kconfig| 2 +- > drivers/tty/serial/earlycon-riscv-sbi.c | 32 +++- > .../selftests/kvm/riscv/get-reg-list.c| 2 + > 13 files changed, 198 insertions(+), 43 deletions(-) > > -- > 2.34.1 > > > -- > kvm-riscv mailing list > kvm-ri...@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/kvm-riscv
Re: [PATCH] treewide: Spelling fix in comment
Hi Kunwu, Thanks for your patch! This is not a treewide change. Hence the oneline-summary should be something prefixed by "[net-next] ps3_gelic" On Fri, Oct 20, 2023 at 11:32 AM Kunwu Chan wrote: > reques -> request > > Fixes: 09dde54c6a69 ("PS3: gelic: Add wireless support for PS3") No need for a Fixes tag for a spelling fix in a comment. > Signed-off-by: Kunwu Chan Reviewed-by: Geert Uytterhoeven > --- a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c > +++ b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c > @@ -1217,7 +1217,7 @@ static int gelic_wl_set_encodeext(struct net_device > *netdev, > key_index = wl->current_key; > > if (!enc->length && (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)) { > - /* reques to change default key index */ > + /* request to change default key index */ > pr_debug("%s: request to change default key to %d\n", > __func__, key_index); > wl->current_key = key_index; 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 v3 8/9] tty: Add SBI debug console support to HVC SBI driver
On Fri, Oct 20, 2023 at 12:51:39PM +0530, Anup Patel wrote: > From: Atish Patra > > RISC-V SBI specification supports advanced debug console > support via SBI DBCN extension. > > Extend the HVC SBI driver to support it. > > Signed-off-by: Atish Patra > Signed-off-by: Anup Patel > --- > drivers/tty/hvc/Kconfig | 2 +- > drivers/tty/hvc/hvc_riscv_sbi.c | 82 ++--- > 2 files changed, 76 insertions(+), 8 deletions(-) > > diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig > index 4f9264d005c0..6e05c5c7bca1 100644 > --- a/drivers/tty/hvc/Kconfig > +++ b/drivers/tty/hvc/Kconfig > @@ -108,7 +108,7 @@ config HVC_DCC_SERIALIZE_SMP > > config HVC_RISCV_SBI > bool "RISC-V SBI console support" > - depends on RISCV_SBI_V01 > + depends on RISCV_SBI > select HVC_DRIVER > help > This enables support for console output via RISC-V SBI calls, which > diff --git a/drivers/tty/hvc/hvc_riscv_sbi.c b/drivers/tty/hvc/hvc_riscv_sbi.c > index 31f53fa77e4a..56da1a4b5aca 100644 > --- a/drivers/tty/hvc/hvc_riscv_sbi.c > +++ b/drivers/tty/hvc/hvc_riscv_sbi.c > @@ -39,21 +39,89 @@ static int hvc_sbi_tty_get(uint32_t vtermno, char *buf, > int count) > return i; > } > > -static const struct hv_ops hvc_sbi_ops = { > +static const struct hv_ops hvc_sbi_v01_ops = { > .get_chars = hvc_sbi_tty_get, > .put_chars = hvc_sbi_tty_put, > }; > > -static int __init hvc_sbi_init(void) > +static int hvc_sbi_dbcn_tty_put(uint32_t vtermno, const char *buf, int count) > { > - return PTR_ERR_OR_ZERO(hvc_alloc(0, 0, &hvc_sbi_ops, 16)); > + phys_addr_t pa; > + struct sbiret ret; > + > + if (is_vmalloc_addr(buf)) { > + pa = page_to_phys(vmalloc_to_page(buf)) + offset_in_page(buf); > + if (PAGE_SIZE < (offset_in_page(buf) + count)) I thought checkpatch complained about uppercase constants being on the left in comparisons. > + count = PAGE_SIZE - offset_in_page(buf); > + } else { > + pa = __pa(buf); > + } > + > + if (IS_ENABLED(CONFIG_32BIT)) > + ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_WRITE, > + count, lower_32_bits(pa), upper_32_bits(pa), > + 0, 0, 0); > + else > + ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_WRITE, > + count, pa, 0, 0, 0, 0); > + if (ret.error) > + return 0; > + > + return count; Shouldn't we return ret.value here in case it's less than count? I see we already do that below in get(). > } > -device_initcall(hvc_sbi_init); > > -static int __init hvc_sbi_console_init(void) > +static int hvc_sbi_dbcn_tty_get(uint32_t vtermno, char *buf, int count) > { > - hvc_instantiate(0, 0, &hvc_sbi_ops); > + phys_addr_t pa; > + struct sbiret ret; > + > + if (is_vmalloc_addr(buf)) { > + pa = page_to_phys(vmalloc_to_page(buf)) + offset_in_page(buf); > + if (PAGE_SIZE < (offset_in_page(buf) + count)) > + count = PAGE_SIZE - offset_in_page(buf); > + } else { > + pa = __pa(buf); > + } > + > + if (IS_ENABLED(CONFIG_32BIT)) > + ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_READ, > + count, lower_32_bits(pa), upper_32_bits(pa), > + 0, 0, 0); > + else > + ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_READ, > + count, pa, 0, 0, 0, 0); > + if (ret.error) > + return 0; > + > + return ret.value; > +} > + > +static const struct hv_ops hvc_sbi_dbcn_ops = { > + .put_chars = hvc_sbi_dbcn_tty_put, > + .get_chars = hvc_sbi_dbcn_tty_get, > +}; > + > +static int __init hvc_sbi_init(void) > +{ > + int err; > + > + if ((sbi_spec_version >= sbi_mk_version(2, 0)) && > + (sbi_probe_extension(SBI_EXT_DBCN) > 0)) { > + err = PTR_ERR_OR_ZERO(hvc_alloc(0, 0, &hvc_sbi_dbcn_ops, 16)); Why an outbuf size of only 16? > + if (err) > + return err; > + hvc_instantiate(0, 0, &hvc_sbi_dbcn_ops); > + } else { > + if (IS_ENABLED(CONFIG_RISCV_SBI_V01)) { > + err = PTR_ERR_OR_ZERO(hvc_alloc(0, 0, &hvc_sbi_v01_ops, > 16)); > + if (err) > + return err; > + hvc_instantiate(0, 0, &hvc_sbi_v01_ops); > + } else { > + return -ENODEV; > + } > + } > > return 0; > } > -console_initcall(hvc_sbi_console_init); > +device_initcall(hvc_sbi_init); > -- > 2.34.1 > Thanks, drew
Re: [PATCH v2 3/6] powerpc/smp: Move shared_processor static key to smp.h
Srikar Dronamraju writes: > * Michael Ellerman [2023-10-19 15:41:40]: > >> Srikar Dronamraju writes: >> > The ability to detect if the system is running in a shared processor >> > mode is helpful in few more generic cases not just in >> > paravirtualization. >> > For example: At boot time, different scheduler/ topology flags may be >> > set based on the processor mode. Hence move it to a more generic file. >> >> I'd rather you just included paravirt.h in the few files where you need it. > > I thought, detecting if a Processor was shared or not was more a > smp/processor related than a paravirt related. It's both really :) It's definitely paravirt related though, because if we weren't *para*virt then we wouldn't know there was a hypervisor at all :) But having smaller more focused headers is preferable in general just for mechanical reasons. cheers
[RFC PATCH v7 13/13] media: vim2m_audio: add virtual driver for audio memory to memory
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/vim2m_audio.c | 680 +++ 3 files changed, 690 insertions(+) create mode 100644 drivers/media/test-drivers/vim2m_audio.c diff --git a/drivers/media/test-drivers/Kconfig b/drivers/media/test-drivers/Kconfig index 459b433e9fae..c280e192d43a 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_VIM2M_AUDIO + 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..c2c33282bf96 100644 --- a/drivers/media/test-drivers/Makefile +++ b/drivers/media/test-drivers/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_DVB_VIDTV) += vidtv/ obj-$(CONFIG_VIDEO_VICODEC) += vicodec/ obj-$(CONFIG_VIDEO_VIM2M) += vim2m.o +obj-$(CONFIG_VIDEO_VIM2M_AUDIO) += vim2m_audio.o obj-$(CONFIG_VIDEO_VIMC) += vimc/ obj-$(CONFIG_VIDEO_VIVID) += vivid/ obj-$(CONFIG_VIDEO_VISL) += visl/ diff --git a/drivers/media/test-drivers/vim2m_audio.c b/drivers/media/test-drivers/vim2m_audio.c new file mode 100644 index ..13f8cc6f2722 --- /dev/null +++ b/drivers/media/test-drivers/vim2m_audio.c @@ -0,0 +1,680 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * A virtual v4l2-mem2mem example for audio device. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_DESCRIPTION("Virtual device for audio mem2mem testing"); +MODULE_LICENSE("GPL"); + +static unsigned int debug; +module_param(debug, uint, 0644); +MODULE_PARM_DESC(debug, "debug level"); + +#define MEM2MEM_NAME "vim2m-audio" + +#define dprintk(dev, lvl, fmt, arg...) \ + v4l2_dbg(lvl, debug, &(dev)->v4l2_dev, "%s: " fmt, __func__, ## arg) + +#define SAMPLE_NUM 4096 + +static void audm2m_dev_release(struct device *dev) +{} + +static struct platform_device audm2m_pdev = { + .name = MEM2MEM_NAME, + .dev.release= audm2m_dev_release, +}; + +static u32 formats[] = { + V4L2_AUDIO_FMT_S8, + V4L2_AUDIO_FMT_S16_LE, + V4L2_AUDIO_FMT_U16_LE, + V4L2_AUDIO_FMT_S24_LE, + V4L2_AUDIO_FMT_S24_3LE, + V4L2_AUDIO_FMT_U24_LE, + V4L2_AUDIO_FMT_U24_3LE, + V4L2_AUDIO_FMT_S32_LE, + V4L2_AUDIO_FMT_U32_LE, + V4L2_AUDIO_FMT_S20_3LE, + V4L2_AUDIO_FMT_U20_3LE, +}; + +#define NUM_FORMATS ARRAY_SIZE(formats) + +/* Per-queue, driver-specific private data */ +struct audm2m_q_data { + unsigned intrate; + unsigned intchannels; + unsigned intbuffersize; + u32 fourcc; +}; + +enum { + V4L2_M2M_SRC = 0, + V4L2_M2M_DST = 1, +}; + +static snd_pcm_format_t find_format(u32 fourcc) +{ + snd_pcm_format_t fmt; + unsigned int k; + + for (k = 0; k < NUM_FORMATS; k++) { + if (formats[k] == fourcc) + break; + } + + if (k == NUM_FORMATS) + return 0; + + fmt = v4l2_fourcc_to_audfmt(formats[k]); + + return fmt; +} + +struct audm2m_dev { + struct v4l2_device v4l2_dev; + struct video_device vfd; + + struct mutexdev_mutex; + + struct v4l2_m2m_dev *m2m_dev; +}; + +struct audm2m_ctx { + struct v4l2_fh fh; + struct audm2m_dev *dev; + + struct mutexvb_mutex; + + /* Source and destination queue data */ + struct audm2m_q_data q_data[2]; +}; + +static inline struct audm2m_ctx *file2ctx(struct file *file) +{ + return container_of(file->private_data, struct audm2m_ctx, fh); +} + +static struct audm2m_q_data *get_q_data(struct audm2m_ctx *ctx, + enum v4l2_buf_type type) +{ + if (type == V4L2_BUF_TYPE_AUDIO_OUTPUT) + return &ctx->q_data[V4L2_M2M_SRC]; + return &ctx->q_data[V4L2_M2M_DST]; +} + +static const char *type_name(enum v4l2_buf_type type) +{ + if (type == V4L2_BUF_
[RFC PATCH v7 12/13] media: imx-asrc: Add memory to memory driver
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 | 1207 + 3 files changed, 1220 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 ..b1b5f1bbdf19 --- /dev/null +++ b/drivers/media/platform/nxp/imx-asrc.c @@ -0,0 +1,1207 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (C) 2014-2016 Freescale Semiconductor, Inc. +// Copyright (C) 2019-2023 NXP +// +// Freescale ASRC Memory to Memory (M2M) driver + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define V4L_CAP OUT +#define V4L_OUT IN + +#define ASRC_xPUT_DMA_CALLBACK(dir) \ + (((dir) == V4L_OUT) ? asrc_input_dma_callback \ + : asrc_output_dma_callback) + +#define DIR_STR(dir) (dir) == V4L_OUT ? "out" : "cap" + +/* Maximum output and capture buffer size */ +#define ASRC_M2M_BUFFER_SIZE (512 * 1024) + +/* Maximum output and capture period size */ +#define ASRC_M2M_PERIOD_SIZE (48 * 1024) + +struct asrc_pair_m2m { + struct fsl_asrc_pair *pair; + struct asrc_m2m *m2m; + struct v4l2_fh fh; + struct v4l2_ctrl_handler ctrl_handler; + int channels[2]; + s64 src_rate_off_prev; /* Q31.32 */ + s64 dst_rate_off_prev; /* Q31.32 */ + s64 src_rate_off_cur; /* Q31.32 */ + s64 dst_rate_off_cur; /* Q31.32 */ +}; + +struct asrc_m2m { + struct fsl_asrc_m2m_pdata pdata; + struct v4l2_device v4l2_dev; + struct v4l2_m2m_dev *m2m_dev; + struct video_device *dec_vdev; + struct mutex mlock; /* v4l2 ioctls serialization */ + struct platform_device *pdev; +}; + +static u32 formats[] = { + V4L2_AUDIO_FMT_S8, + V4L2_AUDIO_FMT_S16_LE, + V4L2_AUDIO_FMT_U16_LE, + V4L2_AUDIO_FMT_S24_LE, + V4L2_AUDIO_FMT_S24_3LE, + V4L2_AUDIO_FMT_U24_LE, + V4L2_AUDIO_FMT_U24_3LE, + V4L2_AUDIO_FMT_S32_LE, + V4L2_AUDIO_FMT_U32_LE, + V4L2_AUDIO_FMT_S20_3LE, + V4L2_AUDIO_FMT_U20_3LE, + V4L2_AUDIO_FMT_FLOAT_LE, + V4L2_AUDIO_FMT_IEC958_SUBFRAME_LE, +}; + +#define NUM_FORMATS ARRAY_SIZE(formats) + +static const s64 asrc_v1_m2m_rates[] = { + 5512, 8000, 11025, 12000, 16000, + 22050, 24000, 32000, 44100, + 48000, 64000, 88200, 96000, + 128000, 176400, 192000, +}; + +static const s64 asrc_v2_m2m_rates[] = { + 8000, 11025, 12000, 16000, + 22050, 24000, 32000, 44100, + 48000, 64000, 88200, 96000, + 128000, 176400, 192000, 256000, + 352800, 384000, 705600, 768000, +}; + +static u32 find_fourcc(snd_pcm_format_t format) +{ + snd_pcm_format_t fmt; + unsigned int k; + + for (k = 0; k < NUM_FORMATS; k++) { + fmt = v4l2_fourcc_to_audfmt(formats[k]); + if (fmt == format) + break; + } + + if (k == NUM_FORMATS) + return 0; + + return formats[k]; +} + +static snd_pcm_format_t find_format(u32 fourcc) +{ + snd_pcm_format_t fmt; + unsigned int k; + + for (k = 0; k < NUM_FORMATS; k++) { +
[RFC PATCH v7 11/13] media: uapi: Add audio rate controls support
Add V4L2_CID_M2M_AUDIO_SOURCE_RATE and V4L2_CID_M2M_AUDIO_DEST_RATE new IDs for rate control. Add V4L2_CID_M2M_AUDIO_SOURCE_RATE_OFFSET and V4L2_CID_M2M_AUDIO_DEST_RATE_OFFSET for clock drift. Signed-off-by: Shengjiu Wang --- .../media/v4l/ext-ctrls-audio-m2m.rst | 18 ++ drivers/media/v4l2-core/v4l2-ctrls-defs.c | 12 include/uapi/linux/v4l2-controls.h | 5 + 3 files changed, 35 insertions(+) diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-audio-m2m.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-audio-m2m.rst index 82d2ecedbfee..e6972a2d3b17 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-audio-m2m.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-audio-m2m.rst @@ -19,3 +19,21 @@ Audio M2M Control IDs The Audio M2M class descriptor. Calling :ref:`VIDIOC_QUERYCTRL` for this control will return a description of this control class. + +.. _v4l2-audio-asrc: + +``V4L2_CID_M2M_AUDIO_SOURCE_RATE`` +Sets the audio source rate, unit is (Hz) + +``V4L2_CID_M2M_AUDIO_DEST_RATE`` +Sets the audio destination rate, unit is (Hz) + +``V4L2_CID_M2M_AUDIO_SOURCE_RATE_OFFSET`` +Sets the offset for audio source rate, unit is (Hz). +Offset expresses the drift of clock if there is. It is +equal to real rate minus ideal rate. + +``V4L2_CID_M2M_AUDIO_DEST_RATE_OFFSET`` +Sets the offset for audio destination rate, unit is (Hz) +Offset expresses the drift of clock if there is. It is +equal to real rate minus ideal rate. diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c b/drivers/media/v4l2-core/v4l2-ctrls-defs.c index 2a85ea3dc92f..b695cbdd1f6e 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c +++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c @@ -1245,6 +1245,10 @@ const char *v4l2_ctrl_get_name(u32 id) /* Audio M2M controls */ case V4L2_CID_M2M_AUDIO_CLASS: return "Audio M2M Controls"; + case V4L2_CID_M2M_AUDIO_SOURCE_RATE:return "Audio Source Sample Rate"; + case V4L2_CID_M2M_AUDIO_DEST_RATE: return "Audio Dest Sample Rate"; + case V4L2_CID_M2M_AUDIO_SOURCE_RATE_OFFSET: return "Audio Source Sample Rate Offset"; + case V4L2_CID_M2M_AUDIO_DEST_RATE_OFFSET: return "Audio Dest Sample Rate Offset"; default: return NULL; } @@ -1606,6 +1610,14 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, case V4L2_CID_COLORIMETRY_HDR10_MASTERING_DISPLAY: *type = V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY; break; + case V4L2_CID_M2M_AUDIO_SOURCE_RATE: + case V4L2_CID_M2M_AUDIO_DEST_RATE: + *type = V4L2_CTRL_TYPE_INTEGER_MENU; + break; + case V4L2_CID_M2M_AUDIO_SOURCE_RATE_OFFSET: + case V4L2_CID_M2M_AUDIO_DEST_RATE_OFFSET: + *type = V4L2_CTRL_TYPE_FIXED_POINT; + break; default: *type = V4L2_CTRL_TYPE_INTEGER; break; diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index eb0f0a76f867..d433c6f0b533 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -3498,4 +3498,9 @@ struct v4l2_ctrl_av1_film_grain { #define V4L2_CID_M2M_AUDIO_CLASS_BASE (V4L2_CTRL_CLASS_M2M_AUDIO | 0x900) #define V4L2_CID_M2M_AUDIO_CLASS (V4L2_CTRL_CLASS_M2M_AUDIO | 1) +#define V4L2_CID_M2M_AUDIO_SOURCE_RATE (V4L2_CID_M2M_AUDIO_CLASS_BASE + 0) +#define V4L2_CID_M2M_AUDIO_DEST_RATE (V4L2_CID_M2M_AUDIO_CLASS_BASE + 1) +#define V4L2_CID_M2M_AUDIO_SOURCE_RATE_OFFSET (V4L2_CID_M2M_AUDIO_CLASS_BASE + 2) +#define V4L2_CID_M2M_AUDIO_DEST_RATE_OFFSET(V4L2_CID_M2M_AUDIO_CLASS_BASE + 3) + #endif -- 2.34.1
[RFC PATCH v7 10/13] media: uapi: Add V4L2_CTRL_TYPE_FIXED_POINT
Fixed point controls are used by the user to configure a fixed point value in 64bits, which Q31.32 format. Signed-off-by: Shengjiu Wang --- Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst | 6 ++ .../userspace-api/media/videodev2.h.rst.exceptions | 1 + drivers/media/v4l2-core/v4l2-ctrls-api.c| 5 - drivers/media/v4l2-core/v4l2-ctrls-core.c | 2 ++ include/uapi/linux/videodev2.h | 1 + 5 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst index 4d38acafe8e1..2e15db0779f2 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst @@ -549,6 +549,12 @@ See also the examples in :ref:`control`. - n/a - A struct :c:type:`v4l2_ctrl_av1_film_grain`, containing AV1 Film Grain parameters for stateless video decoders. +* - ``V4L2_CTRL_TYPE_FIXED_POINT`` + - n/a + - n/a + - n/a + - A struct :c:type:`v4l2_ctrl_fixed_point`, containing parameter which is +Q31.32 format. .. raw:: latex diff --git a/Documentation/userspace-api/media/videodev2.h.rst.exceptions b/Documentation/userspace-api/media/videodev2.h.rst.exceptions index e61152bb80d1..2faa5a2015eb 100644 --- a/Documentation/userspace-api/media/videodev2.h.rst.exceptions +++ b/Documentation/userspace-api/media/videodev2.h.rst.exceptions @@ -167,6 +167,7 @@ replace symbol V4L2_CTRL_TYPE_AV1_SEQUENCE :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_AV1_TILE_GROUP_ENTRY :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_AV1_FRAME :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_AV1_FILM_GRAIN :c:type:`v4l2_ctrl_type` +replace symbol V4L2_CTRL_TYPE_FIXED_POINT :c:type:`v4l2_ctrl_type` # V4L2 capability defines replace define V4L2_CAP_VIDEO_CAPTURE device-capabilities diff --git a/drivers/media/v4l2-core/v4l2-ctrls-api.c b/drivers/media/v4l2-core/v4l2-ctrls-api.c index 002ea6588edf..e6a0fb8d6791 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls-api.c +++ b/drivers/media/v4l2-core/v4l2-ctrls-api.c @@ -57,6 +57,7 @@ static int ptr_to_user(struct v4l2_ext_control *c, return copy_to_user(c->string, ptr.p_char, len + 1) ? -EFAULT : 0; case V4L2_CTRL_TYPE_INTEGER64: + case V4L2_CTRL_TYPE_FIXED_POINT: c->value64 = *ptr.p_s64; break; default: @@ -132,6 +133,7 @@ static int user_to_new(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl) switch (ctrl->type) { case V4L2_CTRL_TYPE_INTEGER64: + case V4L2_CTRL_TYPE_FIXED_POINT: *ctrl->p_new.p_s64 = c->value64; break; case V4L2_CTRL_TYPE_STRING: @@ -540,7 +542,8 @@ static int validate_ctrls(struct v4l2_ext_controls *cs, */ if (ctrl->is_ptr) continue; - if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64) + if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64 || + ctrl->type == V4L2_CTRL_TYPE_FIXED_POINT) p_new.p_s64 = &cs->controls[i].value64; else p_new.p_s32 = &cs->controls[i].value; diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c index a662fb60f73f..9d50df0d9874 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls-core.c +++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c @@ -1187,6 +1187,7 @@ static int std_validate_elem(const struct v4l2_ctrl *ctrl, u32 idx, case V4L2_CTRL_TYPE_INTEGER: return ROUND_TO_RANGE(ptr.p_s32[idx], u32, ctrl); case V4L2_CTRL_TYPE_INTEGER64: + case V4L2_CTRL_TYPE_FIXED_POINT: /* * We can't use the ROUND_TO_RANGE define here due to * the u64 divide that needs special care. @@ -1779,6 +1780,7 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, /* Prefill elem_size for all types handled by std_type_ops */ switch ((u32)type) { case V4L2_CTRL_TYPE_INTEGER64: + case V4L2_CTRL_TYPE_FIXED_POINT: elem_size = sizeof(s64); break; case V4L2_CTRL_TYPE_STRING: diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 4ef08b3a9e39..ef8913d561bf 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -1903,6 +1903,7 @@ enum v4l2_ctrl_type { V4L2_CTRL_TYPE_STRING= 7, V4L2_CTRL_TYPE_BITMASK = 8, V4L2_CTRL_TYPE_INTEGER_MENU = 9, + V4L2_CTRL_TYPE_FIXED_POINT = 10, /* Compound types are >= 0x0100 */ V4L2_CTRL_COMPOUND_TYPES = 0x0100, -- 2.34.1
[RFC PATCH v7 09/13] media: uapi: Add V4L2_CTRL_CLASS_M2M_AUDIO
The Audio M2M class includes controls for audio memory-to-memory use cases. The controls can be used for audio codecs, audio preprocessing, audio postprocessing. Signed-off-by: Shengjiu Wang --- .../userspace-api/media/v4l/common.rst| 1 + .../media/v4l/ext-ctrls-audio-m2m.rst | 21 +++ .../media/v4l/vidioc-g-ext-ctrls.rst | 4 drivers/media/v4l2-core/v4l2-ctrls-defs.c | 4 include/uapi/linux/v4l2-controls.h| 4 5 files changed, 34 insertions(+) create mode 100644 Documentation/userspace-api/media/v4l/ext-ctrls-audio-m2m.rst diff --git a/Documentation/userspace-api/media/v4l/common.rst b/Documentation/userspace-api/media/v4l/common.rst index ea0435182e44..d5366e96a596 100644 --- a/Documentation/userspace-api/media/v4l/common.rst +++ b/Documentation/userspace-api/media/v4l/common.rst @@ -52,6 +52,7 @@ applicable to all devices. ext-ctrls-fm-rx ext-ctrls-detect ext-ctrls-colorimetry +ext-ctrls-audio-m2m fourcc format planar-apis diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-audio-m2m.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-audio-m2m.rst new file mode 100644 index ..82d2ecedbfee --- /dev/null +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-audio-m2m.rst @@ -0,0 +1,21 @@ +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later + +.. _audiom2m-controls: + +*** +Audio M2M Control Reference +*** + +The Audio M2M class includes controls for audio memory-to-memory +use cases. The controls can be used for audio codecs, audio +preprocessing, audio postprocessing. + +Audio M2M Control IDs +--- + +.. _audiom2m-control-id: + +``V4L2_CID_M2M_AUDIO_CLASS (class)`` +The Audio M2M class descriptor. Calling +:ref:`VIDIOC_QUERYCTRL` for this control will +return a description of this control class. diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst index f9f73530a6be..e8475f9fd2cf 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst @@ -480,6 +480,10 @@ still cause this situation. - 0xa5 - The class containing colorimetry controls. These controls are described in :ref:`colorimetry-controls`. +* - ``V4L2_CTRL_CLASS_M2M_AUDIO`` + - 0xa6 + - The class containing audio m2m controls. These controls are + described in :ref:`audiom2m-controls`. Return Value diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c b/drivers/media/v4l2-core/v4l2-ctrls-defs.c index 8696eb1cdd61..2a85ea3dc92f 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c +++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c @@ -1242,6 +1242,9 @@ const char *v4l2_ctrl_get_name(u32 id) case V4L2_CID_COLORIMETRY_CLASS:return "Colorimetry Controls"; case V4L2_CID_COLORIMETRY_HDR10_CLL_INFO: return "HDR10 Content Light Info"; case V4L2_CID_COLORIMETRY_HDR10_MASTERING_DISPLAY: return "HDR10 Mastering Display"; + + /* Audio M2M controls */ + case V4L2_CID_M2M_AUDIO_CLASS: return "Audio M2M Controls"; default: return NULL; } @@ -1451,6 +1454,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, case V4L2_CID_DETECT_CLASS: case V4L2_CID_CODEC_STATELESS_CLASS: case V4L2_CID_COLORIMETRY_CLASS: + case V4L2_CID_M2M_AUDIO_CLASS: *type = V4L2_CTRL_TYPE_CTRL_CLASS; /* You can neither read nor write these */ *flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY; diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index 68db66d4aae8..eb0f0a76f867 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -30,6 +30,7 @@ #define V4L2_CTRL_CLASS_DETECT 0x00a3 /* Detection controls */ #define V4L2_CTRL_CLASS_CODEC_STATELESS 0x00a4 /* Stateless codecs controls */ #define V4L2_CTRL_CLASS_COLORIMETRY0x00a5 /* Colorimetry controls */ +#define V4L2_CTRL_CLASS_M2M_AUDIO 0x00a6 /* Audio M2M controls */ /* User-class control IDs */ @@ -3494,4 +3495,7 @@ struct v4l2_ctrl_av1_film_grain { #define V4L2_CID_MPEG_MFC51_BASEV4L2_CID_CODEC_MFC51_BASE #endif +#define V4L2_CID_M2M_AUDIO_CLASS_BASE (V4L2_CTRL_CLASS_M2M_AUDIO | 0x900) +#define V4L2_CID_M2M_AUDIO_CLASS (V4L2_CTRL_CLASS_M2M_AUDIO | 1) + #endif -- 2.34.1
[RFC PATCH v7 08/13] media: uapi: define audio sample format fourcc type
The audio sample format definition is from alsa, the header file is include/uapi/sound/asound.h, but don't include this header file directly, because in user space, there is another copy in alsa-lib. There will be conflict in userspace for include videodev2.h & asound.h and asoundlib.h Here still use the fourcc format. Signed-off-by: Shengjiu Wang --- .../userspace-api/media/v4l/pixfmt-audio.rst | 87 +++ .../userspace-api/media/v4l/pixfmt.rst| 1 + drivers/media/v4l2-core/v4l2-ioctl.c | 13 +++ include/uapi/linux/videodev2.h| 23 + 4 files changed, 124 insertions(+) create mode 100644 Documentation/userspace-api/media/v4l/pixfmt-audio.rst diff --git a/Documentation/userspace-api/media/v4l/pixfmt-audio.rst b/Documentation/userspace-api/media/v4l/pixfmt-audio.rst new file mode 100644 index ..04b4a7fbd8f4 --- /dev/null +++ b/Documentation/userspace-api/media/v4l/pixfmt-audio.rst @@ -0,0 +1,87 @@ +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later + +.. _pixfmt-audio: + +* +Audio Formats +* + +These formats are used for :ref:`audiomem2mem` interface only. + +.. tabularcolumns:: |p{5.8cm}|p{1.2cm}|p{10.3cm}| + +.. cssclass:: longtable + +.. flat-table:: Audio Format +:header-rows: 1 +:stub-columns: 0 +:widths: 3 1 4 + +* - Identifier + - Code + - Details +* .. _V4L2-AUDIO-FMT-S8: + + - ``V4L2_AUDIO_FMT_S8`` + - 'S8' + - Corresponds to SNDRV_PCM_FORMAT_S8 in ALSA +* .. _V4L2-AUDIO-FMT-S16-LE: + + - ``V4L2_AUDIO_FMT_S16_LE`` + - 'S16_LE' + - Corresponds to SNDRV_PCM_FORMAT_S16_LE in ALSA +* .. _V4L2-AUDIO-FMT-U16-LE: + + - ``V4L2_AUDIO_FMT_U16_LE`` + - 'U16_LE' + - Corresponds to SNDRV_PCM_FORMAT_U16_LE in ALSA +* .. _V4L2-AUDIO-FMT-S24-LE: + + - ``V4L2_AUDIO_FMT_S24_LE`` + - 'S24_LE' + - Corresponds to SNDRV_PCM_FORMAT_S24_LE in ALSA +* .. _V4L2-AUDIO-FMT-U24-LE: + + - ``V4L2_AUDIO_FMT_U24_LE`` + - 'U24_LE' + - Corresponds to SNDRV_PCM_FORMAT_U24_LE in ALSA +* .. _V4L2-AUDIO-FMT-S32-LE: + + - ``V4L2_AUDIO_FMT_S32_LE`` + - 'S32_LE' + - Corresponds to SNDRV_PCM_FORMAT_S32_LE in ALSA +* .. _V4L2-AUDIO-FMT-U32-LE: + + - ``V4L2_AUDIO_FMT_U32_LE`` + - 'U32_LE' + - Corresponds to SNDRV_PCM_FORMAT_U32_LE in ALSA +* .. _V4L2-AUDIO-FMT-FLOAT-LE: + + - ``V4L2_AUDIO_FMT_FLOAT_LE`` + - 'FLOAT_LE' + - Corresponds to SNDRV_PCM_FORMAT_FLOAT_LE in ALSA +* .. _V4L2-AUDIO-FMT-IEC958-SUBFRAME-LE: + + - ``V4L2_AUDIO_FMT_IEC958_SUBFRAME_LE`` + - 'IEC958_SUBFRAME_LE' + - Corresponds to SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE in ALSA +* .. _V4L2-AUDIO-FMT-S24-3LE: + + - ``V4L2_AUDIO_FMT_S24_3LE`` + - 'S24_3LE' + - Corresponds to SNDRV_PCM_FORMAT_S24_3LE in ALSA +* .. _V4L2-AUDIO-FMT-U24-3LE: + + - ``V4L2_AUDIO_FMT_U24_3LE`` + - 'U24_3LE' + - Corresponds to SNDRV_PCM_FORMAT_U24_3LE in ALSA +* .. _V4L2-AUDIO-FMT-S20-3LE: + + - ``V4L2_AUDIO_FMT_S20_3LE`` + - 'S20_3LE' + - Corresponds to SNDRV_PCM_FORMAT_S24_3LE in ALSA +* .. _V4L2-AUDIO-FMT-U20-3LE: + + - ``V4L2_AUDIO_FMT_U20_3LE`` + - 'U20_3LE' + - Corresponds to SNDRV_PCM_FORMAT_U20_3LE in ALSA diff --git a/Documentation/userspace-api/media/v4l/pixfmt.rst b/Documentation/userspace-api/media/v4l/pixfmt.rst index 11dab4a90630..2eb6fdd3b43d 100644 --- a/Documentation/userspace-api/media/v4l/pixfmt.rst +++ b/Documentation/userspace-api/media/v4l/pixfmt.rst @@ -36,3 +36,4 @@ see also :ref:`VIDIOC_G_FBUF `.) colorspaces colorspaces-defs colorspaces-details +pixfmt-audio diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 1bb03794922a..c86633b82038 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1471,6 +1471,19 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_Y210: descr = "10-bit YUYV Packed"; break; case V4L2_PIX_FMT_Y212: descr = "12-bit YUYV Packed"; break; case V4L2_PIX_FMT_Y216: descr = "16-bit YUYV Packed"; break; + case V4L2_AUDIO_FMT_S8: descr = "8-bit Signed"; break; + case V4L2_AUDIO_FMT_S16_LE: descr = "16-bit Signed LE"; break; + case V4L2_AUDIO_FMT_U16_LE: descr = "16-bit Unsigned LE"; break; + case V4L2_AUDIO_FMT_S24_LE: descr = "24(32)-bit Signed LE"; break; + case V4L2_AUDIO_FMT_U24_LE: descr = "24(32)-bit Unsigned LE"; break; + case V4L2_AUDIO_FMT_S32_LE: descr = "32-bit Signed LE"; break; + case V4L2_AUDIO_FMT_U32_LE: descr = "32-bit Unsigned LE"; break; + case V4L2_AUDIO_FMT_FLOAT_LE: descr = "32-bit Float LE"; break; + case V4L2_AUDIO_FMT_IEC958_SUBFRAME_LE: descr = "32-bi
[RFC PATCH v7 07/13] media: v4l2: Add audio capture and output support
Audio signal processing has the requirement for memory to memory similar as Video. This patch is to add this support in v4l2 framework, defined new buffer type V4L2_BUF_TYPE_AUDIO_CAPTURE and V4L2_BUF_TYPE_AUDIO_OUTPUT, defined new format v4l2_audio_format for audio case usage. The created audio device is named "/dev/v4l-audioX". Signed-off-by: Shengjiu Wang --- .../userspace-api/media/v4l/buffer.rst| 6 ++ .../media/v4l/dev-audio-mem2mem.rst | 71 +++ .../userspace-api/media/v4l/devices.rst | 1 + .../media/v4l/vidioc-enum-fmt.rst | 2 + .../userspace-api/media/v4l/vidioc-g-fmt.rst | 4 ++ .../media/videodev2.h.rst.exceptions | 2 + .../media/common/videobuf2/videobuf2-v4l2.c | 4 ++ drivers/media/v4l2-core/v4l2-dev.c| 17 + drivers/media/v4l2-core/v4l2-ioctl.c | 53 ++ include/media/v4l2-dev.h | 2 + include/media/v4l2-ioctl.h| 34 + include/uapi/linux/videodev2.h| 17 + 12 files changed, 213 insertions(+) create mode 100644 Documentation/userspace-api/media/v4l/dev-audio-mem2mem.rst diff --git a/Documentation/userspace-api/media/v4l/buffer.rst b/Documentation/userspace-api/media/v4l/buffer.rst index 52bbee81c080..a3754ca6f0d6 100644 --- a/Documentation/userspace-api/media/v4l/buffer.rst +++ b/Documentation/userspace-api/media/v4l/buffer.rst @@ -438,6 +438,12 @@ enum v4l2_buf_type * - ``V4L2_BUF_TYPE_META_OUTPUT`` - 14 - Buffer for metadata output, see :ref:`metadata`. +* - ``V4L2_BUF_TYPE_AUDIO_CAPTURE`` + - 15 + - Buffer for audio capture, see :ref:`audio`. +* - ``V4L2_BUF_TYPE_AUDIO_OUTPUT`` + - 16 + - Buffer for audio output, see :ref:`audio`. .. _buffer-flags: diff --git a/Documentation/userspace-api/media/v4l/dev-audio-mem2mem.rst b/Documentation/userspace-api/media/v4l/dev-audio-mem2mem.rst new file mode 100644 index ..68faecfe3a02 --- /dev/null +++ b/Documentation/userspace-api/media/v4l/dev-audio-mem2mem.rst @@ -0,0 +1,71 @@ +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later + +.. _audiomem2mem: + + +Audio Memory-To-Memory Interface + + +An audio memory-to-memory device can compress, decompress, transform, or +otherwise convert audio data from one format into another format, in memory. +Such memory-to-memory devices set the ``V4L2_CAP_AUDIO_M2M`` capability. +Examples of memory-to-memory devices are audio codecs, audio preprocessing, +audio postprocessing. + +A memory-to-memory audio node supports both output (sending audio frames from +memory to the hardware) and capture (receiving the processed audio frames +from the hardware into memory) stream I/O. An application will have to +setup the stream I/O for both sides and finally call +:ref:`VIDIOC_STREAMON ` for both capture and output to +start the hardware. + +Memory-to-memory devices function as a shared resource: you can +open the audio node multiple times, each application setting up their +own properties that are local to the file handle, and each can use +it independently from the others. The driver will arbitrate access to +the hardware and reprogram it whenever another file handler gets access. + +Audio memory-to-memory devices are accessed through character device +special files named ``/dev/v4l-audio`` + +Querying Capabilities += + +Device nodes supporting the audio memory-to-memory interface set the +``V4L2_CAP_AUDIO_M2M`` flag in the ``device_caps`` field of the +:c:type:`v4l2_capability` structure returned by the :c:func:`VIDIOC_QUERYCAP` +ioctl. + +Data Format Negotiation +=== + +The audio device uses the :ref:`format` ioctls to select the capture format. +The audio buffer content format is bound to that selected format. In addition +to the basic :ref:`format` ioctls, the :c:func:`VIDIOC_ENUM_FMT` ioctl must be +supported as well. + +To use the :ref:`format` ioctls applications set the ``type`` field of the +:c:type:`v4l2_format` structure to ``V4L2_BUF_TYPE_AUDIO_CAPTURE`` or to +``V4L2_BUF_TYPE_AUDIO_OUTPUT``. Both drivers and applications must set the +remainder of the :c:type:`v4l2_format` structure to 0. + +.. c:type:: v4l2_audio_format + +.. tabularcolumns:: |p{1.4cm}|p{2.4cm}|p{13.5cm}| + +.. flat-table:: struct v4l2_audio_format +:header-rows: 0 +:stub-columns: 0 +:widths: 1 1 2 + +* - __u32 + - ``pixelformat`` + - The sample format, set by the application. see :ref:`pixfmt-audio` +* - __u32 + - ``channels`` + - The channel number, set by the application. channel number range is +[1, 32]. +* - __u32 + - ``buffersize`` + - Maximum buffer size in bytes required for data. The value is set by the +driver. diff --git a/Documentation/userspace-api/media/v4l/devices.rst b/Documentation/userspace-a
[RFC PATCH v7 06/13] media: uapi: Add V4L2_CAP_AUDIO_M2M capability flag
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 c3d4e490ce7c..d5da76607101 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 v7 05/13] ASoC: fsl_easrc: register m2m platform device
Register m2m platform device,that user can use M2M feature. Signed-off-by: Shengjiu Wang Acked-by: Mark Brown --- sound/soc/fsl/fsl_easrc.c | 19 +++ 1 file changed, 19 insertions(+) diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c index 0b9f3df8efc2..07e7475db7f3 100644 --- a/sound/soc/fsl/fsl_easrc.c +++ b/sound/soc/fsl/fsl_easrc.c @@ -2075,6 +2075,7 @@ MODULE_DEVICE_TABLE(of, fsl_easrc_dt_ids); static int fsl_easrc_probe(struct platform_device *pdev) { struct fsl_easrc_priv *easrc_priv; + struct fsl_asrc_m2m_pdata m2m_pdata; struct device *dev = &pdev->dev; struct fsl_asrc *easrc; struct resource *res; @@ -2190,11 +2191,29 @@ static int fsl_easrc_probe(struct platform_device *pdev) return ret; } + m2m_pdata.asrc = easrc; + m2m_pdata.fmt_in = FSL_EASRC_FORMATS; + m2m_pdata.fmt_out = FSL_EASRC_FORMATS | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE; + m2m_pdata.rate_min = 8000; + m2m_pdata.rate_max = 768000; + m2m_pdata.chan_min = 1; + m2m_pdata.chan_max = 32; + easrc->m2m_pdev = platform_device_register_data(&pdev->dev, + M2M_DRV_NAME, + PLATFORM_DEVID_AUTO, + &m2m_pdata, + sizeof(m2m_pdata)); + return 0; } static void fsl_easrc_remove(struct platform_device *pdev) { + struct fsl_asrc *easrc = dev_get_drvdata(&pdev->dev); + + if (easrc->m2m_pdev && !IS_ERR(easrc->m2m_pdev)) + platform_device_unregister(easrc->m2m_pdev); + pm_runtime_disable(&pdev->dev); } -- 2.34.1
[RFC PATCH v7 04/13] ASoC: fsl_asrc: register m2m platform device
Register m2m platform device, that user can use M2M feature. Defined platform data structure and platform driver name. Signed-off-by: Shengjiu Wang Acked-by: Mark Brown --- include/sound/fsl_asrc_common.h | 23 +++ sound/soc/fsl/fsl_asrc.c| 18 ++ 2 files changed, 41 insertions(+) diff --git a/include/sound/fsl_asrc_common.h b/include/sound/fsl_asrc_common.h index 3b53d366182f..c709b8906929 100644 --- a/include/sound/fsl_asrc_common.h +++ b/include/sound/fsl_asrc_common.h @@ -71,6 +71,7 @@ struct fsl_asrc_pair { * @dma_params_rx: DMA parameters for receive channel * @dma_params_tx: DMA parameters for transmit channel * @pdev: platform device pointer + * @m2m_pdev: m2m platform device pointer * @regmap: regmap handler * @paddr: physical address to the base address of registers * @mem_clk: clock source to access register @@ -103,6 +104,7 @@ struct fsl_asrc { struct snd_dmaengine_dai_dma_data dma_params_rx; struct snd_dmaengine_dai_dma_data dma_params_tx; struct platform_device *pdev; + struct platform_device *m2m_pdev; struct regmap *regmap; unsigned long paddr; struct clk *mem_clk; @@ -139,6 +141,27 @@ struct fsl_asrc { void *private; }; +/** + * struct fsl_asrc_m2m_pdata - platform data + * @asrc: pointer to struct fsl_asrc + * @fmt_in: input sample format + * @fmt_out: output sample format + * @chan_min: minimum channel number + * @chan_max: maximum channel number + * @rate_min: minimum rate + * @rate_max: maximum rete + */ +struct fsl_asrc_m2m_pdata { + struct fsl_asrc *asrc; + u64 fmt_in; + u64 fmt_out; + int chan_min; + int chan_max; + int rate_min; + int rate_max; +}; + +#define M2M_DRV_NAME "fsl_asrc_m2m" #define DRV_NAME "fsl-asrc-dai" extern struct snd_soc_component_driver fsl_asrc_component; diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index 7d8643ee0ba0..5ecb5d869607 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c @@ -1187,6 +1187,7 @@ static int fsl_asrc_runtime_suspend(struct device *dev); static int fsl_asrc_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; + struct fsl_asrc_m2m_pdata m2m_pdata; struct fsl_asrc_priv *asrc_priv; struct fsl_asrc *asrc; struct resource *res; @@ -1368,6 +1369,18 @@ static int fsl_asrc_probe(struct platform_device *pdev) goto err_pm_get_sync; } + m2m_pdata.asrc = asrc; + m2m_pdata.fmt_in = FSL_ASRC_FORMATS; + m2m_pdata.fmt_out = FSL_ASRC_FORMATS | SNDRV_PCM_FMTBIT_S8; + m2m_pdata.rate_min = 5512; + m2m_pdata.rate_max = 192000; + m2m_pdata.chan_min = 1; + m2m_pdata.chan_max = 10; + asrc->m2m_pdev = platform_device_register_data(&pdev->dev, + M2M_DRV_NAME, + PLATFORM_DEVID_AUTO, + &m2m_pdata, + sizeof(m2m_pdata)); return 0; err_pm_get_sync: @@ -1380,6 +1393,11 @@ static int fsl_asrc_probe(struct platform_device *pdev) static void fsl_asrc_remove(struct platform_device *pdev) { + struct fsl_asrc *asrc = dev_get_drvdata(&pdev->dev); + + if (asrc->m2m_pdev && !IS_ERR(asrc->m2m_pdev)) + platform_device_unregister(asrc->m2m_pdev); + pm_runtime_disable(&pdev->dev); if (!pm_runtime_status_suspended(&pdev->dev)) fsl_asrc_runtime_suspend(&pdev->dev); -- 2.34.1
[RFC PATCH v7 03/13] ASoC: fsl_asrc: move fsl_asrc_common.h to include/sound
Move fsl_asrc_common.h to include/sound that it can be included from other drivers. Signed-off-by: Shengjiu Wang Acked-by: Mark Brown --- {sound/soc/fsl => include/sound}/fsl_asrc_common.h | 0 sound/soc/fsl/fsl_asrc.h | 2 +- sound/soc/fsl/fsl_asrc_dma.c | 2 +- sound/soc/fsl/fsl_easrc.h | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename {sound/soc/fsl => include/sound}/fsl_asrc_common.h (100%) diff --git a/sound/soc/fsl/fsl_asrc_common.h b/include/sound/fsl_asrc_common.h similarity index 100% rename from sound/soc/fsl/fsl_asrc_common.h rename to include/sound/fsl_asrc_common.h diff --git a/sound/soc/fsl/fsl_asrc.h b/sound/soc/fsl/fsl_asrc.h index 1c492eb237f5..66544624de7b 100644 --- a/sound/soc/fsl/fsl_asrc.h +++ b/sound/soc/fsl/fsl_asrc.h @@ -10,7 +10,7 @@ #ifndef _FSL_ASRC_H #define _FSL_ASRC_H -#include "fsl_asrc_common.h" +#include #define ASRC_M2M_INPUTFIFO_WML 0x4 #define ASRC_M2M_OUTPUTFIFO_WML0x2 diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c index f501f47242fb..f067bf1ecea7 100644 --- a/sound/soc/fsl/fsl_asrc_dma.c +++ b/sound/soc/fsl/fsl_asrc_dma.c @@ -12,7 +12,7 @@ #include #include -#include "fsl_asrc_common.h" +#include #define FSL_ASRC_DMABUF_SIZE (256 * 1024) diff --git a/sound/soc/fsl/fsl_easrc.h b/sound/soc/fsl/fsl_easrc.h index c9f770862662..a24e540876a4 100644 --- a/sound/soc/fsl/fsl_easrc.h +++ b/sound/soc/fsl/fsl_easrc.h @@ -9,7 +9,7 @@ #include #include -#include "fsl_asrc_common.h" +#include /* EASRC Register Map */ -- 2.34.1
[RFC PATCH v7 02/13] ASoC: fsl_easrc: define functions for memory to memory usage
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 Acked-by: Mark Brown --- sound/soc/fsl/fsl_easrc.c | 214 ++ sound/soc/fsl/fsl_easrc.h | 4 + 2 files changed, 218 insertions(+) diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c index ba62995c909a..0b9f3df8efc2 100644 --- a/sound/soc/fsl/fsl_easrc.c +++ b/sound/soc/fsl/fsl_easrc.c @@ -1861,6 +1861,211 @@ 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); + val &= EASRC_SFS_NSGO_MASK; + + return val >> EASRC_SFS_NSGO_SHIFT; +} + +static int fsl_easrc_m2m_prepare(struct fsl_asrc_pair *pair) +{ + struct fsl_easrc_ctx_priv *ctx_priv = pair->private; + struct fsl_asrc *asrc = pair->asrc; + struct device *dev = &asrc->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, + &ctx_priv->in_params.sample_format, + &ctx_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 */ + pair->first_convert = 1; + return 0; +} + +static int fsl_easrc_m2m_start(struct fsl_asrc_pair *pair) +{ + /* start context once */ + if (pair->first_convert) { + fsl_easrc_start_context(pair); + pair->first_convert = 0; + } + + return 0; +} + +static int fsl_easrc_m2m_stop(struct fsl_asrc_pair *pair) +{ + /* Stop pair/context */ + if (!pair->first_convert) { + fsl_easrc_stop_context(pair); + pair->first_convert = 1; + } + + 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: + /* integer bits = 5; */ + frac_bits = 39; + break; + case EASRC_RS_64_TAPS: + /* integer bits = 6; */ + frac_bits = 38; + break; + case EASRC_RS_128_TAPS: + /* integer bits = 7; */ + frac_bits = 37; + break; + default: + return -EINVAL; + } + + val1 = (u64)in_rate << frac_bits; + do_div(val1, out_rate); + val1 += (s64)ctx_priv->ratio_mod << (frac_bits - 31); + + in_width = snd_pcm_format_physical_width(ctx_priv->in_params.sample_format) / 8; + out_width = snd_pcm_format_physical_width(ctx_priv->out_params.sample_format) / 8; + + ctx_priv->in_filled_len += input_b
[RFC PATCH v7 01/13] ASoC: fsl_asrc: define functions for memory to memory usage
ASRC can be used on memory to memory case, define several functions for m2m usage. m2m_prepare: prepare for the start step m2m_start: the start step m2m_unprepare: unprepare for stop step, optional m2m_stop: stop step 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 Acked-by: Mark Brown --- sound/soc/fsl/fsl_asrc.c| 126 sound/soc/fsl/fsl_asrc.h| 2 + sound/soc/fsl/fsl_asrc_common.h | 37 ++ 3 files changed, 165 insertions(+) diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index b793263291dc..7d8643ee0ba0 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c @@ -1063,6 +1063,124 @@ 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); + + val &= ASRFSTi_OUTPUT_FIFO_MASK; + + return val >> ASRFSTi_OUTPUT_FIFO_SHIFT; +} + +static int fsl_asrc_m2m_prepare(struct fsl_asrc_pair *pair) +{ + struct fsl_asrc_pair_priv *pair_priv = pair->private; + struct fsl_asrc *asrc = pair->asrc; + struct device *dev = &asrc->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 = &config; + ret = fsl_asrc_config_pair(pair, true); + if (ret) { + dev_err(dev, "failed to config pair: %d\n", ret); + return ret; + } + + pair->first_convert = 1; + + return 0; +} + +static int fsl_asrc_m2m_start(struct fsl_asrc_pair *pair) +{ + if (pair->first_convert) { + fsl_asrc_start_pair(pair); + pair->first_convert = 0; + } + /* +* 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(struct fsl_asrc_pair *pair) +{ + if (!pair->first_convert) { + fsl_asrc_stop_pair(pair); + pair->first_convert = 1; + } + + 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 wml * pair->channels; + else + return 1; +} + +static int fsl_asrc_m2m_pair_resume(struct fsl_asrc_pair *pair) +{ + struct fsl_asrc *asrc = pair->asrc; + int i; + + for (i = 0; i < pair->channels * 4; i++) + regmap_write(asrc->regmap, REG_ASRDI(pair->index), 0); + + pair->first_convert = 1; + return 0; +} + static int fsl_asrc_runtime_resume(struct device *dev); static in
[RFC PATCH v7 00/13] Add audio support in v4l2 framework
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 v7: - add acked-by from Mark - separate commit for fixed point, m2m audio class, audio rate controls - use INTEGER_MENU for rate, FIXED_POINT for rate offset - remove used fmts - address other comments for Hans changes in v6: - use m2m_prepare/m2m_unprepare/m2m_start/m2m_stop to replace m2m_start_part_one/m2m_stop_part_one, m2m_start_part_two/m2m_stop_part_two. - change V4L2_CTRL_TYPE_ASRC_RATE to V4L2_CTRL_TYPE_FIXED_POINT - fix warning by kernel test rebot - remove some unused format V4L2_AUDIO_FMT_XX - Get SNDRV_PCM_FORMAT from V4L2_AUDIO_FMT in driver. - rename audm2m to viaudm2m. changes in v5: - remove V4L2_AUDIO_FMT_LPCM - define audio pixel format like V4L2_AUDIO_FMT_S8... - remove rate and format in struct v4l2_audio_format. - Add V4L2_CID_ASRC_SOURCE_RATE and V4L2_CID_ASRC_DEST_RATE controls - updata document accordingly. changes in v4: - update document style - separate V4L2_AUDIO_FMT_LPCM and V4L2_CAP_AUDIO_M2M in separate commit changes in v3: - Modify documents for adding audio m2m support - Add audio virtual m2m driver - Defined V4L2_AUDIO_FMT_LPCM format type for audio. - Defined V4L2_CAP_AUDIO_M2M capability type for audio m2m case. - with modification in v4l-utils, pass v4l2-compliance test. changes in v2: - decouple the implementation in v4l2 and ALSA - implement the memory to memory driver as a platfrom driver and move it to driver/media - move fsl_asrc_common.h to include/sound folder Shengjiu Wang (13): ASoC: fsl_asrc: define functions for memory to memory usage ASoC: fsl_easrc: define functions for memory to memory usage ASoC: fsl_asrc: move fsl_asrc_common.h to include/sound ASoC: fsl_asrc: register m2m platform device ASoC: fsl_easrc: register m2m platform device media: uapi: Add V4L2_CAP_AUDIO_M2M capability flag media: v4l2: Add audio capture and output support media: uapi: define audio sample format fourcc type media: uapi: Add V4L2_CTRL_CLASS_M2M_AUDIO media: uapi: Add V4L2_CTRL_TYPE_FIXED_POINT media: uapi: Add audio rate controls support media: imx-asrc: Add memory to memory driver media: vim2m_audio: add virtual driver for audio memory to memory .../userspace-api/media/v4l/buffer.rst|6 + .../userspace-api/media/v4l/common.rst|1 + .../media/v4l/dev-audio-mem2mem.rst | 71 + .../userspace-api/media/v4l/devices.rst |1 + .../media/v4l/ext-ctrls-audio-m2m.rst | 39 + .../userspace-api/media/v4l/pixfmt-audio.rst | 87 ++ .../userspace-api/media/v4l/pixfmt.rst|1 + .../media/v4l/vidioc-enum-fmt.rst |2 + .../media/v4l/vidioc-g-ext-ctrls.rst |4 + .../userspace-api/media/v4l/vidioc-g-fmt.rst |4 + .../media/v4l/vidioc-querycap.rst |3 + .../media/v4l/vidioc-queryctrl.rst|6 + .../media/videodev2.h.rst.exceptions |4 + .../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 | 1207 + drivers/media/test-drivers/Kconfig|9 + drivers/media/test-drivers/Makefile |1 + drivers/media/test-drivers/vim2m_audio.c | 680 ++ drivers/media/v4l2-core/v4l2-ctrls-api.c |5 +- drivers/media/v4l2-core/v4l2-ctrls-core.c |2 + drivers/media/v4l2-core/v4l2-ctrls-defs.c | 16 + drivers/media/v4l2-core/v4l2-dev.c| 17 + drivers/media/v4l2-core/v4l2-ioctl.c | 66 + include/media/v4l2-dev.h |2 + include/media/v4l2-ioctl.h| 34 + .../fsl => include/sound}/fsl_asrc_common.h | 60 + include/uapi/linux/v4l2-controls.h|9 + include/uapi/linux/videodev2.h| 42 + sound/soc/fsl/fsl_asrc.c
Re: [PATCH v3 8/9] tty: Add SBI debug console support to HVC SBI driver
On Fri, Oct 20, 2023 at 3:25 PM Björn Töpel wrote: > > Anup Patel writes: > > > From: Atish Patra > > > > RISC-V SBI specification supports advanced debug console > > support via SBI DBCN extension. > > > > Extend the HVC SBI driver to support it. > > > > Signed-off-by: Atish Patra > > Signed-off-by: Anup Patel > > --- > > drivers/tty/hvc/Kconfig | 2 +- > > drivers/tty/hvc/hvc_riscv_sbi.c | 82 ++--- > > 2 files changed, 76 insertions(+), 8 deletions(-) > > > > diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig > > index 4f9264d005c0..6e05c5c7bca1 100644 > > --- a/drivers/tty/hvc/Kconfig > > +++ b/drivers/tty/hvc/Kconfig > > @@ -108,7 +108,7 @@ config HVC_DCC_SERIALIZE_SMP > > > > config HVC_RISCV_SBI > > bool "RISC-V SBI console support" > > - depends on RISCV_SBI_V01 > > + depends on RISCV_SBI > > select HVC_DRIVER > > help > > This enables support for console output via RISC-V SBI calls, which > > diff --git a/drivers/tty/hvc/hvc_riscv_sbi.c > > b/drivers/tty/hvc/hvc_riscv_sbi.c > > index 31f53fa77e4a..56da1a4b5aca 100644 > > --- a/drivers/tty/hvc/hvc_riscv_sbi.c > > +++ b/drivers/tty/hvc/hvc_riscv_sbi.c > > @@ -39,21 +39,89 @@ static int hvc_sbi_tty_get(uint32_t vtermno, char *buf, > > int count) > > return i; > > } > > > > -static const struct hv_ops hvc_sbi_ops = { > > +static const struct hv_ops hvc_sbi_v01_ops = { > > .get_chars = hvc_sbi_tty_get, > > .put_chars = hvc_sbi_tty_put, > > }; > > > > -static int __init hvc_sbi_init(void) > > +static int hvc_sbi_dbcn_tty_put(uint32_t vtermno, const char *buf, int > > count) > > { > > - return PTR_ERR_OR_ZERO(hvc_alloc(0, 0, &hvc_sbi_ops, 16)); > > + phys_addr_t pa; > > + struct sbiret ret; > > + > > + if (is_vmalloc_addr(buf)) { > > + pa = page_to_phys(vmalloc_to_page(buf)) + offset_in_page(buf); > > + if (PAGE_SIZE < (offset_in_page(buf) + count)) > > + count = PAGE_SIZE - offset_in_page(buf); > > Thanks for fixing the cross-page issue. Now you're cutting the buffer > off. What about doing two SBI calls instead? (Dito on the get side) We don't need to handle that because the hvc_console framework will ensure remaining characters are sent-out. Same applies to get side as well. Regards, Anup
Re: [PATCH 0/6] powerpc/qspinlock: Fix yield latency bug and other
On Mon, Oct 16, 2023 at 10:42:59PM +1000, Nicholas Piggin wrote: > This fixes a long-standing latency bug in the powerpc qspinlock > implementation that quite a few people have reported and helped > out with debugging. > > The first patch is a minimal fix that avoids the problem. The > other patches are streamlining and improvements after the fix. > > Thanks, > Nick > > Nicholas Piggin (6): > powerpc/qspinlock: Fix stale propagated yield_cpu > powerpc/qspinlock: stop queued waiters trying to set lock sleepy > powerpc/qspinlock: propagate owner preemptedness rather than CPU > number > powerpc/qspinlock: don't propagate the not-sleepy state > powerpc/qspinlock: Propagate sleepy if previous waiter is preempted > powerpc/qspinlock: Rename yield_propagate_owner tunable > > arch/powerpc/lib/qspinlock.c | 119 +++ > 1 file changed, 52 insertions(+), 67 deletions(-) > > -- > 2.42.0 > Just a minor comment regarding patch 2. For the series: Reviewed-by: Nysal Jan K.A
Re: [PATCH v3 8/9] tty: Add SBI debug console support to HVC SBI driver
Anup Patel writes: > From: Atish Patra > > RISC-V SBI specification supports advanced debug console > support via SBI DBCN extension. > > Extend the HVC SBI driver to support it. > > Signed-off-by: Atish Patra > Signed-off-by: Anup Patel > --- > drivers/tty/hvc/Kconfig | 2 +- > drivers/tty/hvc/hvc_riscv_sbi.c | 82 ++--- > 2 files changed, 76 insertions(+), 8 deletions(-) > > diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig > index 4f9264d005c0..6e05c5c7bca1 100644 > --- a/drivers/tty/hvc/Kconfig > +++ b/drivers/tty/hvc/Kconfig > @@ -108,7 +108,7 @@ config HVC_DCC_SERIALIZE_SMP > > config HVC_RISCV_SBI > bool "RISC-V SBI console support" > - depends on RISCV_SBI_V01 > + depends on RISCV_SBI > select HVC_DRIVER > help > This enables support for console output via RISC-V SBI calls, which > diff --git a/drivers/tty/hvc/hvc_riscv_sbi.c b/drivers/tty/hvc/hvc_riscv_sbi.c > index 31f53fa77e4a..56da1a4b5aca 100644 > --- a/drivers/tty/hvc/hvc_riscv_sbi.c > +++ b/drivers/tty/hvc/hvc_riscv_sbi.c > @@ -39,21 +39,89 @@ static int hvc_sbi_tty_get(uint32_t vtermno, char *buf, > int count) > return i; > } > > -static const struct hv_ops hvc_sbi_ops = { > +static const struct hv_ops hvc_sbi_v01_ops = { > .get_chars = hvc_sbi_tty_get, > .put_chars = hvc_sbi_tty_put, > }; > > -static int __init hvc_sbi_init(void) > +static int hvc_sbi_dbcn_tty_put(uint32_t vtermno, const char *buf, int count) > { > - return PTR_ERR_OR_ZERO(hvc_alloc(0, 0, &hvc_sbi_ops, 16)); > + phys_addr_t pa; > + struct sbiret ret; > + > + if (is_vmalloc_addr(buf)) { > + pa = page_to_phys(vmalloc_to_page(buf)) + offset_in_page(buf); > + if (PAGE_SIZE < (offset_in_page(buf) + count)) > + count = PAGE_SIZE - offset_in_page(buf); Thanks for fixing the cross-page issue. Now you're cutting the buffer off. What about doing two SBI calls instead? (Dito on the get side) Björn
Re: [PATCH 2/6] powerpc/qspinlock: stop queued waiters trying to set lock sleepy
On Mon, Oct 16, 2023 at 10:43:01PM +1000, Nicholas Piggin wrote: > If a queued waiter notices the lock owner or the previous waiter has > been preempted, it attempts to mark the lock sleepy, but it does this > as a try-set operation using the original lock value it got when > queueing, which will become stale as the queue progresses, and the > try-set will fail. Drop this and just set the sleepy seen clock. > > Signed-off-by: Nicholas Piggin > --- > arch/powerpc/lib/qspinlock.c | 24 ++-- > 1 file changed, 10 insertions(+), 14 deletions(-) > > diff --git a/arch/powerpc/lib/qspinlock.c b/arch/powerpc/lib/qspinlock.c > index 6dd2f46bd3ef..75608ced14c2 100644 > --- a/arch/powerpc/lib/qspinlock.c > +++ b/arch/powerpc/lib/qspinlock.c > @@ -247,22 +247,18 @@ static __always_inline void seen_sleepy_lock(void) > this_cpu_write(sleepy_lock_seen_clock, sched_clock()); > } > > -static __always_inline void seen_sleepy_node(struct qspinlock *lock, u32 val) > +static __always_inline void seen_sleepy_node(void) > { > if (pv_sleepy_lock) { > if (pv_sleepy_lock_interval_ns) > this_cpu_write(sleepy_lock_seen_clock, sched_clock()); > - if (val & _Q_LOCKED_VAL) { > - if (!(val & _Q_SLEEPY_VAL)) > - try_set_sleepy(lock, val); > - } > + /* Don't set sleepy because we likely have a stale val */ > } > } seen_sleepy_lock() and seen_sleepy_node() are now the same > > -static struct qnode *get_tail_qnode(struct qspinlock *lock, u32 val) > +static struct qnode *get_tail_qnode(struct qspinlock *lock, int prev_cpu) > { > - int cpu = decode_tail_cpu(val); > - struct qnodes *qnodesp = per_cpu_ptr(&qnodes, cpu); > + struct qnodes *qnodesp = per_cpu_ptr(&qnodes, prev_cpu); > int idx; > > /* > @@ -381,9 +377,8 @@ static __always_inline void propagate_yield_cpu(struct > qnode *node, u32 val, int > } > > /* Called inside spin_begin() */ > -static __always_inline bool yield_to_prev(struct qspinlock *lock, struct > qnode *node, u32 val, bool paravirt) > +static __always_inline bool yield_to_prev(struct qspinlock *lock, struct > qnode *node, int prev_cpu, bool paravirt) > { > - int prev_cpu = decode_tail_cpu(val); > u32 yield_count; > int yield_cpu; > bool preempted = false; > @@ -412,7 +407,7 @@ static __always_inline bool yield_to_prev(struct > qspinlock *lock, struct qnode * > spin_end(); > > preempted = true; > - seen_sleepy_node(lock, val); > + seen_sleepy_node(); > > smp_rmb(); > > @@ -436,7 +431,7 @@ static __always_inline bool yield_to_prev(struct > qspinlock *lock, struct qnode * > spin_end(); > > preempted = true; > - seen_sleepy_node(lock, val); > + seen_sleepy_node(); > > smp_rmb(); /* See __yield_to_locked_owner comment */ > > @@ -587,7 +582,8 @@ static __always_inline void > queued_spin_lock_mcs_queue(struct qspinlock *lock, b >* head of the waitqueue. >*/ > if (old & _Q_TAIL_CPU_MASK) { > - struct qnode *prev = get_tail_qnode(lock, old); > + int prev_cpu = decode_tail_cpu(old); > + struct qnode *prev = get_tail_qnode(lock, prev_cpu); > > /* Link @node into the waitqueue. */ > WRITE_ONCE(prev->next, node); > @@ -597,7 +593,7 @@ static __always_inline void > queued_spin_lock_mcs_queue(struct qspinlock *lock, b > while (!READ_ONCE(node->locked)) { > spec_barrier(); > > - if (yield_to_prev(lock, node, old, paravirt)) > + if (yield_to_prev(lock, node, prev_cpu, paravirt)) > seen_preempted = true; > } > spec_barrier(); > -- > 2.42.0 >
Re: [PATCH v2 1/6] powerpc/smp: Cache CPU has Asymmetric SMP
* Michael Ellerman [2023-10-19 15:33:16]: > Srikar Dronamraju writes: > > Currently cpu feature flag is checked whenever powerpc_smt_flags gets > > called. This is an unnecessary overhead. CPU_FTR_ASYM_SMT is set based > > on the processor and all processors will either have this set or will > > have it unset. > > The cpu_has_feature() test is implemented with a static key. > > So AFAICS this is just replacing one static key with another? > > I see that you use the new static key in subsequent patches. But > couldn't those just use the existing cpu feature test? > Yes, we can use the existing cpu feature test itself. > Anyway I'd be interested to see how the generated code differs > before/after this. > >8--8< Before this change 0500 : { 500: 00 00 4c 3c addis r2,r12,0 504: 00 00 42 38 addir2,r2,0 508: a6 02 08 7c mflrr0 50c: 01 00 00 48 bl 50c 510: f8 ff e1 fb std r31,-8(r1) 514: 91 ff 21 f8 stdur1,-112(r1) #define JUMP_ENTRY_TYPE stringify_in_c(FTR_ENTRY_LONG) #define JUMP_LABEL_NOP_SIZE 4 static __always_inline bool arch_static_branch(struct static_key *key, bool branch) { asm_volatile_goto("1:\n\t" 518: 00 00 00 60 nop printk_once(KERN_INFO "Enabling Asymmetric SMT scheduling\n"); 51c: 00 00 22 3d addis r9,r2,0 flags |= SD_ASYM_PACKING; 520: 80 05 e0 3b li r31,1408 printk_once(KERN_INFO "Enabling Asymmetric SMT scheduling\n"); 524: 00 00 29 89 lbz r9,0(r9) 528: 00 00 09 2c cmpwi r9,0 52c: 28 00 82 41 beq 554 } 530: 70 00 21 38 addir1,r1,112 534: b4 07 e3 7f extsw r3,r31 538: f8 ff e1 eb ld r31,-8(r1) 53c: 20 00 80 4e blr int flags = SD_SHARE_CPUCAPACITY | SD_SHARE_PKG_RESOURCES; 540: 80 01 e0 3b li r31,384 } 544: 70 00 21 38 addir1,r1,112 548: b4 07 e3 7f extsw r3,r31 54c: f8 ff e1 eb ld r31,-8(r1) 550: 20 00 80 4e blr printk_once(KERN_INFO "Enabling Asymmetric SMT scheduling\n"); 554: a6 02 08 7c mflrr0 558: 00 00 62 3c addis r3,r2,0 55c: 01 00 20 39 li r9,1 560: 00 00 42 3d addis r10,r2,0 564: 00 00 63 38 addir3,r3,0 568: 00 00 2a 99 stb r9,0(r10) 56c: 80 00 01 f8 std r0,128(r1) 570: 01 00 00 48 bl 570 574: 00 00 00 60 nop 578: 80 00 01 e8 ld r0,128(r1) 57c: a6 03 08 7c mtlrr0 580: b0 ff ff 4b b 530 584: 00 00 00 60 nop 588: 00 00 00 60 nop 58c: 00 00 00 60 nop post this change. 0340 : { 340: a6 02 08 7c mflrr0 344: 01 00 00 48 bl 344 #define JUMP_ENTRY_TYPE stringify_in_c(FTR_ENTRY_LONG) #define JUMP_LABEL_NOP_SIZE 4 static __always_inline bool arch_static_branch(struct static_key *key, bool branch) { asm_volatile_goto("1:\n\t" 348: 00 00 00 60 nop return SD_SHARE_CPUCAPACITY | SD_SHARE_PKG_RESOURCES; 34c: 80 01 60 38 li r3,384 } 350: b4 07 63 7c extsw r3,r3 354: 20 00 80 4e blr 358: 00 00 00 60 nop 35c: 00 00 00 60 nop return SD_SHARE_CPUCAPACITY | SD_SHARE_PKG_RESOURCES | SD_ASYM_PACKING; 360: 80 05 60 38 li r3,1408 } 364: b4 07 63 7c extsw r3,r3 368: 20 00 80 4e blr 36c: 00 00 00 60 nop >8--8< I think the most of the difference is due to moving pr_info_once to fixup_topology. Does it make sense to move the pr_info_once to fixup_topology (which is called less often) from powerpc_smt_flags? Even though the pr_info_once would probably translate to load + cmp + branch we could avoid that for each smt_flag call. So something like diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 5826f5108a12..bc22f775425b 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -993,13 +993,10 @@ static bool shared_caches; /* cpumask of CPUs with asymmetric SMT dependency */ static int powerpc_smt_flags(void) { - int flags = SD_SHARE_CPUCAPACITY | SD_SHARE_PKG_RESOURCES; + if (cpu_has_feature(CPU_FTR_ASYM_SMT)) { + return SD_SHARE_CPUCAPACITY | SD_SHARE_PKG_RESOURCES | SD_ASYM_PACKING; - if (cpu_has_feature(CPU_FTR_ASYM_SMT)) { - printk_onc
Re: [PATCH] hvc/xen: fix event channel handling for secondary consoles
On 18.10.23 01:46, David Woodhouse wrote: From: David Woodhouse The xencons_connect_backend() function allocates a local interdomain event channel with xenbus_alloc_evtchn(), then calls bind_interdomain_evtchn_to_irq_lateeoi() to bind to that port# on the *remote* domain. That doesn't work very well: (qemu) device_add xen-console,id=con1,chardev=pty0 [ 44.323872] xenconsole console-1: 2 xenbus_dev_probe on device/console/1 [ 44.323995] xenconsole: probe of console-1 failed with error -2 Fix it to use bind_evtchn_to_irq_lateeoi(), which does the right thing by just binding that *local* event channel to an irq. The backend will do the interdomain binding. This didn't affect the primary console because the setup for that is special — the toolstack allocates the guest event channel and the guest discovers it with HVMOP_get_param. Once that's fixed, there's also a warning on hot-unplug because xencons_disconnect_backend() unconditionally calls free_irq() via unbind_from_irqhandler(): (qemu) device_del con1 [ 32.050919] [ cut here ] [ 32.050942] Trying to free already-free IRQ 33 [ 32.050990] WARNING: CPU: 0 PID: 51 at kernel/irq/manage.c:1895 __free_irq+0x1d4/0x330 Fix that by calling notifier_del_irq() first, which only calls free_irq() if the irq was requested in the first place. Then use I don't think the "if the irq was requested in the first place" is the correct reasoning. I think the problem is that notifier_del_irq() will be called another time through the .notifier_del hook. Two calls of notifier_del_irq() are fine, but one call of it and another call of free_irq() via unbind_from_irqhandler() is a problem. evtchn_put() to release the irq and event channel. Avoid calling xenbus_free_evtchn() in the normal case, as evtchn_put() will do that too. The only time xenbus_free_evtchn() needs to be called is for the cleanup when bind_evtchn_to_irq_lateeoi() fails. Finally, fix the error path in xen_hvc_init() when there's no primary console. It should still register the frontend driver, as there may be secondary consoles. (Qemu can always add secondary consoles, but only the toolstack can add the primary because it's special.) Fixes: fe415186b4 ("xen/console: harden hvc_xen against event channel storms") Signed-off-by: David Woodhouse Cc: sta...@vger.kernel.org With above fixed in the commit message: Reviewed-by: Juergen Gross Juergen OpenPGP_0xB0DE9DD628BF132F.asc Description: OpenPGP public key OpenPGP_signature.asc Description: OpenPGP digital signature
Re: [PATCH v3 5/9] KVM: riscv: selftests: Add SBI DBCN extension to get-reg-list test
On Fri, Oct 20, 2023 at 12:51:36PM +0530, Anup Patel wrote: > We have a new SBI debug console (DBCN) extension supported by in-kernel > KVM so let us add this extension to get-reg-list test. > > Signed-off-by: Anup Patel > --- > tools/testing/selftests/kvm/riscv/get-reg-list.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c > b/tools/testing/selftests/kvm/riscv/get-reg-list.c > index 234006d035c9..6bedaea95395 100644 > --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c > +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c > @@ -394,6 +394,7 @@ static const char *sbi_ext_single_id_to_str(__u64 reg_off) > KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_PMU), > KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_EXPERIMENTAL), > KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_VENDOR), > + KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_DBCN), > }; > > if (reg_off >= ARRAY_SIZE(kvm_sbi_ext_reg_name)) > @@ -567,6 +568,7 @@ static __u64 base_regs[] = { > KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | > KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_PMU, > KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | > KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_EXPERIMENTAL, > KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | > KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_VENDOR, > + KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | > KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_DBCN, > KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | > KVM_REG_RISCV_SBI_MULTI_EN | 0, > KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | > KVM_REG_RISCV_SBI_MULTI_DIS | 0, > }; > -- > 2.34.1 > Reviewed-by: Andrew Jones
Re: [PATCH v3 3/9] RISC-V: KVM: Allow some SBI extensions to be disabled by default
On Fri, Oct 20, 2023 at 12:51:34PM +0530, Anup Patel wrote: > Currently, all SBI extensions are enabled by default which is > problematic for SBI extensions (such as DBCN) which are forwarded > to the KVM user-space because we might have an older KVM user-space > which is not aware/ready to handle newer SBI extensions. Ideally, > the SBI extensions forwarded to the KVM user-space must be > disabled by default. > > To address above, we allow certain SBI extensions to be disabled > by default so that KVM user-space must explicitly enable such > SBI extensions to receive forwarded calls from Guest VCPU. > > Signed-off-by: Anup Patel > --- > arch/riscv/include/asm/kvm_vcpu_sbi.h | 4 ++ > arch/riscv/kvm/vcpu.c | 6 +++ > arch/riscv/kvm/vcpu_sbi.c | 57 +-- > 3 files changed, 38 insertions(+), 29 deletions(-) > Reviewed-by: Andrew Jones
Re: [PATCHv9 2/2] powerpc/setup: Loosen the mapping between cpu logical id and its seq in dt
On 18/10/23 1:51 pm, Pingfan Liu wrote: On Tue, Oct 17, 2023 at 6:39 PM Hari Bathini wrote: On 17/10/23 7:58 am, Pingfan Liu wrote: *** Idea *** For kexec -p, the boot cpu can be not the cpu0, this causes the problem of allocating memory for paca_ptrs[]. However, in theory, there is no requirement to assign cpu's logical id as its present sequence in the device tree. But there is something like cpu_first_thread_sibling(), which makes assumption on the mapping inside a core. Hence partially loosening the mapping, i.e. unbind the mapping of core while keep the mapping inside a core. *** Implement *** At this early stage, there are plenty of memory to utilize. Hence, this patch allocates interim memory to link the cpu info on a list, then reorder cpus by changing the list head. As a result, there is a rotate shift between the sequence number in dt and the cpu logical number. *** Result *** After this patch, a boot-cpu's logical id will always be mapped into the range [0,threads_per_core). Besides this, at this phase, all threads in the boot core are forced to be onlined. This restriction will be lifted in a later patch with extra effort. Signed-off-by: Pingfan Liu Cc: Michael Ellerman Cc: Nicholas Piggin Cc: Christophe Leroy Cc: Mahesh Salgaonkar Cc: Wen Xiong Cc: Baoquan He Cc: Ming Lei Cc: Sourabh Jain Cc: Hari Bathini Cc: ke...@lists.infradead.org To: linuxppc-dev@lists.ozlabs.org Thanks for working on this, Pingfan. Looks good to me. Acked-by: Hari Bathini Thank you for kindly reviewing. I hope that after all these years, we have accomplished the objective. I hope so too. Thanks!
[PATCH v3 9/9] RISC-V: Enable SBI based earlycon support
Let us enable SBI based earlycon support in defconfigs for both RV32 and RV64 so that "earlycon=sbi" can be used again. Signed-off-by: Anup Patel Reviewed-by: Andrew Jones --- arch/riscv/configs/defconfig | 1 + arch/riscv/configs/rv32_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig index ab86ec3b9eab..f82700da0056 100644 --- a/arch/riscv/configs/defconfig +++ b/arch/riscv/configs/defconfig @@ -132,6 +132,7 @@ CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_DW=y CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_SH_SCI=y +CONFIG_SERIAL_EARLYCON_RISCV_SBI=y CONFIG_VIRTIO_CONSOLE=y CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_VIRTIO=y diff --git a/arch/riscv/configs/rv32_defconfig b/arch/riscv/configs/rv32_defconfig index 89b601e253a6..5721af39afd1 100644 --- a/arch/riscv/configs/rv32_defconfig +++ b/arch/riscv/configs/rv32_defconfig @@ -66,6 +66,7 @@ CONFIG_INPUT_MOUSEDEV=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_EARLYCON_RISCV_SBI=y CONFIG_VIRTIO_CONSOLE=y CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_VIRTIO=y -- 2.34.1
[PATCH v3 8/9] tty: Add SBI debug console support to HVC SBI driver
From: Atish Patra RISC-V SBI specification supports advanced debug console support via SBI DBCN extension. Extend the HVC SBI driver to support it. Signed-off-by: Atish Patra Signed-off-by: Anup Patel --- drivers/tty/hvc/Kconfig | 2 +- drivers/tty/hvc/hvc_riscv_sbi.c | 82 ++--- 2 files changed, 76 insertions(+), 8 deletions(-) diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig index 4f9264d005c0..6e05c5c7bca1 100644 --- a/drivers/tty/hvc/Kconfig +++ b/drivers/tty/hvc/Kconfig @@ -108,7 +108,7 @@ config HVC_DCC_SERIALIZE_SMP config HVC_RISCV_SBI bool "RISC-V SBI console support" - depends on RISCV_SBI_V01 + depends on RISCV_SBI select HVC_DRIVER help This enables support for console output via RISC-V SBI calls, which diff --git a/drivers/tty/hvc/hvc_riscv_sbi.c b/drivers/tty/hvc/hvc_riscv_sbi.c index 31f53fa77e4a..56da1a4b5aca 100644 --- a/drivers/tty/hvc/hvc_riscv_sbi.c +++ b/drivers/tty/hvc/hvc_riscv_sbi.c @@ -39,21 +39,89 @@ static int hvc_sbi_tty_get(uint32_t vtermno, char *buf, int count) return i; } -static const struct hv_ops hvc_sbi_ops = { +static const struct hv_ops hvc_sbi_v01_ops = { .get_chars = hvc_sbi_tty_get, .put_chars = hvc_sbi_tty_put, }; -static int __init hvc_sbi_init(void) +static int hvc_sbi_dbcn_tty_put(uint32_t vtermno, const char *buf, int count) { - return PTR_ERR_OR_ZERO(hvc_alloc(0, 0, &hvc_sbi_ops, 16)); + phys_addr_t pa; + struct sbiret ret; + + if (is_vmalloc_addr(buf)) { + pa = page_to_phys(vmalloc_to_page(buf)) + offset_in_page(buf); + if (PAGE_SIZE < (offset_in_page(buf) + count)) + count = PAGE_SIZE - offset_in_page(buf); + } else { + pa = __pa(buf); + } + + if (IS_ENABLED(CONFIG_32BIT)) + ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_WRITE, + count, lower_32_bits(pa), upper_32_bits(pa), + 0, 0, 0); + else + ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_WRITE, + count, pa, 0, 0, 0, 0); + if (ret.error) + return 0; + + return count; } -device_initcall(hvc_sbi_init); -static int __init hvc_sbi_console_init(void) +static int hvc_sbi_dbcn_tty_get(uint32_t vtermno, char *buf, int count) { - hvc_instantiate(0, 0, &hvc_sbi_ops); + phys_addr_t pa; + struct sbiret ret; + + if (is_vmalloc_addr(buf)) { + pa = page_to_phys(vmalloc_to_page(buf)) + offset_in_page(buf); + if (PAGE_SIZE < (offset_in_page(buf) + count)) + count = PAGE_SIZE - offset_in_page(buf); + } else { + pa = __pa(buf); + } + + if (IS_ENABLED(CONFIG_32BIT)) + ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_READ, + count, lower_32_bits(pa), upper_32_bits(pa), + 0, 0, 0); + else + ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_READ, + count, pa, 0, 0, 0, 0); + if (ret.error) + return 0; + + return ret.value; +} + +static const struct hv_ops hvc_sbi_dbcn_ops = { + .put_chars = hvc_sbi_dbcn_tty_put, + .get_chars = hvc_sbi_dbcn_tty_get, +}; + +static int __init hvc_sbi_init(void) +{ + int err; + + if ((sbi_spec_version >= sbi_mk_version(2, 0)) && + (sbi_probe_extension(SBI_EXT_DBCN) > 0)) { + err = PTR_ERR_OR_ZERO(hvc_alloc(0, 0, &hvc_sbi_dbcn_ops, 16)); + if (err) + return err; + hvc_instantiate(0, 0, &hvc_sbi_dbcn_ops); + } else { + if (IS_ENABLED(CONFIG_RISCV_SBI_V01)) { + err = PTR_ERR_OR_ZERO(hvc_alloc(0, 0, &hvc_sbi_v01_ops, 16)); + if (err) + return err; + hvc_instantiate(0, 0, &hvc_sbi_v01_ops); + } else { + return -ENODEV; + } + } return 0; } -console_initcall(hvc_sbi_console_init); +device_initcall(hvc_sbi_init); -- 2.34.1
[PATCH v3 7/9] tty/serial: Add RISC-V SBI debug console based earlycon
We extend the existing RISC-V SBI earlycon support to use the new RISC-V SBI debug console extension. Signed-off-by: Anup Patel Reviewed-by: Andrew Jones --- drivers/tty/serial/Kconfig | 2 +- drivers/tty/serial/earlycon-riscv-sbi.c | 32 + 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index bdc568a4ab66..cec46091a716 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -87,7 +87,7 @@ config SERIAL_EARLYCON_SEMIHOST config SERIAL_EARLYCON_RISCV_SBI bool "Early console using RISC-V SBI" - depends on RISCV_SBI_V01 + depends on RISCV_SBI select SERIAL_CORE select SERIAL_CORE_CONSOLE select SERIAL_EARLYCON diff --git a/drivers/tty/serial/earlycon-riscv-sbi.c b/drivers/tty/serial/earlycon-riscv-sbi.c index 27afb0b74ea7..c21cdef254e7 100644 --- a/drivers/tty/serial/earlycon-riscv-sbi.c +++ b/drivers/tty/serial/earlycon-riscv-sbi.c @@ -15,17 +15,41 @@ static void sbi_putc(struct uart_port *port, unsigned char c) sbi_console_putchar(c); } -static void sbi_console_write(struct console *con, - const char *s, unsigned n) +static void sbi_0_1_console_write(struct console *con, + const char *s, unsigned int n) { struct earlycon_device *dev = con->data; uart_console_write(&dev->port, s, n, sbi_putc); } +static void sbi_dbcn_console_write(struct console *con, + const char *s, unsigned int n) +{ + phys_addr_t pa = __pa(s); + + if (IS_ENABLED(CONFIG_32BIT)) + sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_WRITE, + n, lower_32_bits(pa), upper_32_bits(pa), 0, 0, 0); + else + sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_WRITE, + n, pa, 0, 0, 0, 0); +} + static int __init early_sbi_setup(struct earlycon_device *device, const char *opt) { - device->con->write = sbi_console_write; - return 0; + int ret = 0; + + if ((sbi_spec_version >= sbi_mk_version(2, 0)) && + (sbi_probe_extension(SBI_EXT_DBCN) > 0)) { + device->con->write = sbi_dbcn_console_write; + } else { + if (IS_ENABLED(CONFIG_RISCV_SBI_V01)) + device->con->write = sbi_0_1_console_write; + else + ret = -ENODEV; + } + + return ret; } EARLYCON_DECLARE(sbi, early_sbi_setup); -- 2.34.1
[PATCH v3 6/9] RISC-V: Add stubs for sbi_console_putchar/getchar()
The functions sbi_console_putchar() and sbi_console_getchar() are not defined when CONFIG_RISCV_SBI_V01 is disabled so let us add stub of these functions to avoid "#ifdef" on user side. Signed-off-by: Anup Patel Reviewed-by: Andrew Jones --- arch/riscv/include/asm/sbi.h | 5 + 1 file changed, 5 insertions(+) diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h index 12dfda6bb924..cbcefa344417 100644 --- a/arch/riscv/include/asm/sbi.h +++ b/arch/riscv/include/asm/sbi.h @@ -271,8 +271,13 @@ struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0, unsigned long arg3, unsigned long arg4, unsigned long arg5); +#ifdef CONFIG_RISCV_SBI_V01 void sbi_console_putchar(int ch); int sbi_console_getchar(void); +#else +static inline void sbi_console_putchar(int ch) { } +static inline int sbi_console_getchar(void) { return -1; } +#endif long sbi_get_mvendorid(void); long sbi_get_marchid(void); long sbi_get_mimpid(void); -- 2.34.1
[PATCH v3 5/9] KVM: riscv: selftests: Add SBI DBCN extension to get-reg-list test
We have a new SBI debug console (DBCN) extension supported by in-kernel KVM so let us add this extension to get-reg-list test. Signed-off-by: Anup Patel --- tools/testing/selftests/kvm/riscv/get-reg-list.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c index 234006d035c9..6bedaea95395 100644 --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c @@ -394,6 +394,7 @@ static const char *sbi_ext_single_id_to_str(__u64 reg_off) KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_PMU), KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_EXPERIMENTAL), KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_VENDOR), + KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_DBCN), }; if (reg_off >= ARRAY_SIZE(kvm_sbi_ext_reg_name)) @@ -567,6 +568,7 @@ static __u64 base_regs[] = { KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_PMU, KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_EXPERIMENTAL, KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_VENDOR, + KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_DBCN, KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_MULTI_EN | 0, KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_MULTI_DIS | 0, }; -- 2.34.1
[PATCH v3 4/9] RISC-V: KVM: Forward SBI DBCN extension to user-space
The frozen SBI v2.0 specification defines the SBI debug console (DBCN) extension which replaces the legacy SBI v0.1 console functions namely sbi_console_getchar() and sbi_console_putchar(). The SBI DBCN extension needs to be emulated in the KVM user-space (i.e. QEMU-KVM or KVMTOOL) so we forward SBI DBCN calls from KVM guest to the KVM user-space which can then redirect the console input/output to wherever it wants (e.g. telnet, file, stdio, etc). The SBI debug console is simply a early console available to KVM guest for early prints and it does not intend to replace the proper console devices such as 8250, VirtIO console, etc. Signed-off-by: Anup Patel Reviewed-by: Andrew Jones --- arch/riscv/include/asm/kvm_vcpu_sbi.h | 1 + arch/riscv/include/uapi/asm/kvm.h | 1 + arch/riscv/kvm/vcpu_sbi.c | 4 arch/riscv/kvm/vcpu_sbi_replace.c | 32 +++ 4 files changed, 38 insertions(+) diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm/kvm_vcpu_sbi.h index c02bda5559d7..6a453f7f8b56 100644 --- a/arch/riscv/include/asm/kvm_vcpu_sbi.h +++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h @@ -73,6 +73,7 @@ extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_ipi; extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_rfence; extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_srst; extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_hsm; +extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_dbcn; extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_experimental; extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_vendor; diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h index 917d8cc2489e..60d3b21dead7 100644 --- a/arch/riscv/include/uapi/asm/kvm.h +++ b/arch/riscv/include/uapi/asm/kvm.h @@ -156,6 +156,7 @@ enum KVM_RISCV_SBI_EXT_ID { KVM_RISCV_SBI_EXT_PMU, KVM_RISCV_SBI_EXT_EXPERIMENTAL, KVM_RISCV_SBI_EXT_VENDOR, + KVM_RISCV_SBI_EXT_DBCN, KVM_RISCV_SBI_EXT_MAX, }; diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c index bda8b0b33343..a04ff98085d9 100644 --- a/arch/riscv/kvm/vcpu_sbi.c +++ b/arch/riscv/kvm/vcpu_sbi.c @@ -66,6 +66,10 @@ static const struct kvm_riscv_sbi_extension_entry sbi_ext[] = { .ext_idx = KVM_RISCV_SBI_EXT_PMU, .ext_ptr = &vcpu_sbi_ext_pmu, }, + { + .ext_idx = KVM_RISCV_SBI_EXT_DBCN, + .ext_ptr = &vcpu_sbi_ext_dbcn, + }, { .ext_idx = KVM_RISCV_SBI_EXT_EXPERIMENTAL, .ext_ptr = &vcpu_sbi_ext_experimental, diff --git a/arch/riscv/kvm/vcpu_sbi_replace.c b/arch/riscv/kvm/vcpu_sbi_replace.c index 7c4d5d38a339..23b57c931b15 100644 --- a/arch/riscv/kvm/vcpu_sbi_replace.c +++ b/arch/riscv/kvm/vcpu_sbi_replace.c @@ -175,3 +175,35 @@ const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_srst = { .extid_end = SBI_EXT_SRST, .handler = kvm_sbi_ext_srst_handler, }; + +static int kvm_sbi_ext_dbcn_handler(struct kvm_vcpu *vcpu, + struct kvm_run *run, + struct kvm_vcpu_sbi_return *retdata) +{ + struct kvm_cpu_context *cp = &vcpu->arch.guest_context; + unsigned long funcid = cp->a6; + + switch (funcid) { + case SBI_EXT_DBCN_CONSOLE_WRITE: + case SBI_EXT_DBCN_CONSOLE_READ: + case SBI_EXT_DBCN_CONSOLE_WRITE_BYTE: + /* +* The SBI debug console functions are unconditionally +* forwarded to the userspace. +*/ + kvm_riscv_vcpu_sbi_forward(vcpu, run); + retdata->uexit = true; + break; + default: + retdata->err_val = SBI_ERR_NOT_SUPPORTED; + } + + return 0; +} + +const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_dbcn = { + .extid_start = SBI_EXT_DBCN, + .extid_end = SBI_EXT_DBCN, + .default_unavail = true, + .handler = kvm_sbi_ext_dbcn_handler, +}; -- 2.34.1
[PATCH v3 3/9] RISC-V: KVM: Allow some SBI extensions to be disabled by default
Currently, all SBI extensions are enabled by default which is problematic for SBI extensions (such as DBCN) which are forwarded to the KVM user-space because we might have an older KVM user-space which is not aware/ready to handle newer SBI extensions. Ideally, the SBI extensions forwarded to the KVM user-space must be disabled by default. To address above, we allow certain SBI extensions to be disabled by default so that KVM user-space must explicitly enable such SBI extensions to receive forwarded calls from Guest VCPU. Signed-off-by: Anup Patel --- arch/riscv/include/asm/kvm_vcpu_sbi.h | 4 ++ arch/riscv/kvm/vcpu.c | 6 +++ arch/riscv/kvm/vcpu_sbi.c | 57 +-- 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm/kvm_vcpu_sbi.h index 8d6d4dce8a5e..c02bda5559d7 100644 --- a/arch/riscv/include/asm/kvm_vcpu_sbi.h +++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h @@ -35,6 +35,9 @@ struct kvm_vcpu_sbi_return { struct kvm_vcpu_sbi_extension { unsigned long extid_start; unsigned long extid_end; + + bool default_unavail; + /** * SBI extension handler. It can be defined for a given extension or group of * extension. But it should always return linux error codes rather than SBI @@ -59,6 +62,7 @@ int kvm_riscv_vcpu_get_reg_sbi_ext(struct kvm_vcpu *vcpu, const struct kvm_vcpu_sbi_extension *kvm_vcpu_sbi_find_ext( struct kvm_vcpu *vcpu, unsigned long extid); int kvm_riscv_vcpu_sbi_ecall(struct kvm_vcpu *vcpu, struct kvm_run *run); +void kvm_riscv_vcpu_sbi_init(struct kvm_vcpu *vcpu); #ifdef CONFIG_RISCV_SBI_V01 extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_v01; diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c index c061a1c5fe98..e087c809073c 100644 --- a/arch/riscv/kvm/vcpu.c +++ b/arch/riscv/kvm/vcpu.c @@ -141,6 +141,12 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) if (rc) return rc; + /* +* Setup SBI extensions +* NOTE: This must be the last thing to be initialized. +*/ + kvm_riscv_vcpu_sbi_init(vcpu); + /* Reset VCPU */ kvm_riscv_reset_vcpu(vcpu); diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c index 9cd97091c723..bda8b0b33343 100644 --- a/arch/riscv/kvm/vcpu_sbi.c +++ b/arch/riscv/kvm/vcpu_sbi.c @@ -155,14 +155,8 @@ static int riscv_vcpu_set_sbi_ext_single(struct kvm_vcpu *vcpu, if (!sext) return -ENOENT; - /* -* We can't set the extension status to available here, since it may -* have a probe() function which needs to confirm availability first, -* but it may be too early to call that here. We can set the status to -* unavailable, though. -*/ - if (!reg_val) - scontext->ext_status[sext->ext_idx] = + scontext->ext_status[sext->ext_idx] = (reg_val) ? + KVM_RISCV_SBI_EXT_AVAILABLE : KVM_RISCV_SBI_EXT_UNAVAILABLE; return 0; @@ -188,16 +182,8 @@ static int riscv_vcpu_get_sbi_ext_single(struct kvm_vcpu *vcpu, if (!sext) return -ENOENT; - /* -* If the extension status is still uninitialized, then we should probe -* to determine if it's available, but it may be too early to do that -* here. The best we can do is report that the extension has not been -* disabled, i.e. we return 1 when the extension is available and also -* when it only may be available. -*/ - *reg_val = scontext->ext_status[sext->ext_idx] != - KVM_RISCV_SBI_EXT_UNAVAILABLE; - + *reg_val = scontext->ext_status[sext->ext_idx] == + KVM_RISCV_SBI_EXT_AVAILABLE; return 0; } @@ -337,18 +323,8 @@ const struct kvm_vcpu_sbi_extension *kvm_vcpu_sbi_find_ext( scontext->ext_status[entry->ext_idx] == KVM_RISCV_SBI_EXT_AVAILABLE) return ext; - if (scontext->ext_status[entry->ext_idx] == - KVM_RISCV_SBI_EXT_UNAVAILABLE) - return NULL; - if (ext->probe && !ext->probe(vcpu)) { - scontext->ext_status[entry->ext_idx] = - KVM_RISCV_SBI_EXT_UNAVAILABLE; - return NULL; - } - scontext->ext_status[entry->ext_idx] = - KVM_RISCV_SBI_EXT_AVAILABLE; - return ext; + return NULL; } } @@ -419,3 +395,26 @@ int kvm_riscv_vcpu_sbi_ecall(struct kvm_vcpu *vcpu, struct kvm_run *r
[PATCH v3 2/9] RISC-V: KVM: Change the SBI specification version to v2.0
We will be implementing SBI DBCN extension for KVM RISC-V so let us change the KVM RISC-V SBI specification version to v2.0. Signed-off-by: Anup Patel Reviewed-by: Andrew Jones --- arch/riscv/include/asm/kvm_vcpu_sbi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm/kvm_vcpu_sbi.h index cdcf0ff07be7..8d6d4dce8a5e 100644 --- a/arch/riscv/include/asm/kvm_vcpu_sbi.h +++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h @@ -11,7 +11,7 @@ #define KVM_SBI_IMPID 3 -#define KVM_SBI_VERSION_MAJOR 1 +#define KVM_SBI_VERSION_MAJOR 2 #define KVM_SBI_VERSION_MINOR 0 enum kvm_riscv_sbi_ext_status { -- 2.34.1
[PATCH v3 1/9] RISC-V: Add defines for SBI debug console extension
We add SBI debug console extension related defines/enum to the asm/sbi.h header. Signed-off-by: Anup Patel Reviewed-by: Andrew Jones --- arch/riscv/include/asm/sbi.h | 7 +++ 1 file changed, 7 insertions(+) diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h index 5b4a1bf5f439..12dfda6bb924 100644 --- a/arch/riscv/include/asm/sbi.h +++ b/arch/riscv/include/asm/sbi.h @@ -30,6 +30,7 @@ enum sbi_ext_id { SBI_EXT_HSM = 0x48534D, SBI_EXT_SRST = 0x53525354, SBI_EXT_PMU = 0x504D55, + SBI_EXT_DBCN = 0x4442434E, /* Experimentals extensions must lie within this range */ SBI_EXT_EXPERIMENTAL_START = 0x0800, @@ -236,6 +237,12 @@ enum sbi_pmu_ctr_type { /* Flags defined for counter stop function */ #define SBI_PMU_STOP_FLAG_RESET (1 << 0) +enum sbi_ext_dbcn_fid { + SBI_EXT_DBCN_CONSOLE_WRITE = 0, + SBI_EXT_DBCN_CONSOLE_READ = 1, + SBI_EXT_DBCN_CONSOLE_WRITE_BYTE = 2, +}; + #define SBI_SPEC_VERSION_DEFAULT 0x1 #define SBI_SPEC_VERSION_MAJOR_SHIFT 24 #define SBI_SPEC_VERSION_MAJOR_MASK0x7f -- 2.34.1
[PATCH v3 0/9] RISC-V SBI debug console extension support
The SBI v2.0 specification is now frozen. The SBI v2.0 specification defines SBI debug console (DBCN) extension which replaces the legacy SBI v0.1 functions sbi_console_putchar() and sbi_console_getchar(). (Refer v2.0-rc5 at https://github.com/riscv-non-isa/riscv-sbi-doc/releases) This series adds support for SBI debug console (DBCN) extension in KVM RISC-V and Linux RISC-V. To try these patches with KVM RISC-V, use KVMTOOL from riscv_sbi_dbcn_v1 branch at: https://github.com/avpatel/kvmtool.git These patches can also be found in the riscv_sbi_dbcn_v3 branch at: https://github.com/avpatel/linux.git Changes since v2: - Rebased on Linux-6.6-rc5 - Handled page-crossing in PATCH7 of v2 series - Addressed Drew's comment in PATCH3 of v2 series - Added new PATCH5 to make get-reg-list test aware of SBI DBCN extension Changes since v1: - Remove use of #ifdef from PATCH4 and PATCH5 of the v1 series - Improved commit description of PATCH3 in v1 series - Introduced new PATCH3 in this series to allow some SBI extensions (such as SBI DBCN) do to disabled by default so that older KVM user space work fine and newer KVM user space have to explicitly opt-in for emulating SBI DBCN. - Introduced new PATCH5 in this series which adds inline version of sbi_console_getchar() and sbi_console_putchar() for the case where CONFIG_RISCV_SBI_V01 is disabled. Anup Patel (8): RISC-V: Add defines for SBI debug console extension RISC-V: KVM: Change the SBI specification version to v2.0 RISC-V: KVM: Allow some SBI extensions to be disabled by default RISC-V: KVM: Forward SBI DBCN extension to user-space KVM: riscv: selftests: Add SBI DBCN extension to get-reg-list test RISC-V: Add stubs for sbi_console_putchar/getchar() tty/serial: Add RISC-V SBI debug console based earlycon RISC-V: Enable SBI based earlycon support Atish Patra (1): tty: Add SBI debug console support to HVC SBI driver arch/riscv/configs/defconfig | 1 + arch/riscv/configs/rv32_defconfig | 1 + arch/riscv/include/asm/kvm_vcpu_sbi.h | 7 +- arch/riscv/include/asm/sbi.h | 12 +++ arch/riscv/include/uapi/asm/kvm.h | 1 + arch/riscv/kvm/vcpu.c | 6 ++ arch/riscv/kvm/vcpu_sbi.c | 61 +++--- arch/riscv/kvm/vcpu_sbi_replace.c | 32 drivers/tty/hvc/Kconfig | 2 +- drivers/tty/hvc/hvc_riscv_sbi.c | 82 +-- drivers/tty/serial/Kconfig| 2 +- drivers/tty/serial/earlycon-riscv-sbi.c | 32 +++- .../selftests/kvm/riscv/get-reg-list.c| 2 + 13 files changed, 198 insertions(+), 43 deletions(-) -- 2.34.1