* Re: [PATCH 4/9] powerpc/bpf: Handle large branch ranges with BPF_EXIT
From: Christophe Leroy @ 2021-10-03 7:59 UTC (permalink / raw)
To: Naveen N. Rao, Michael Ellerman, Nicholas Piggin, Daniel Borkmann,
Alexei Starovoitov, Johan Almbladh
Cc: bpf, linuxppc-dev
In-Reply-To: <ebc0317ce465cb4f8d6fe485ab468ac5bda7c48f.1633104510.git.naveen.n.rao@linux.vnet.ibm.com>
Le 01/10/2021 à 23:14, Naveen N. Rao a écrit :
> In some scenarios, it is possible that the program epilogue is outside
> the branch range for a BPF_EXIT instruction. Instead of rejecting such
> programs, emit an indirect branch. We track the size of the bpf program
> emitted after the initial run and do a second pass since BPF_EXIT can
> end up emitting different number of instructions depending on the
> program size.
>
> Suggested-by: Jordan Niethe <jniethe5@gmail.com>
> Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
> ---
> arch/powerpc/net/bpf_jit.h | 3 +++
> arch/powerpc/net/bpf_jit_comp.c | 22 +++++++++++++++++++++-
> arch/powerpc/net/bpf_jit_comp32.c | 2 +-
> arch/powerpc/net/bpf_jit_comp64.c | 2 +-
> 4 files changed, 26 insertions(+), 3 deletions(-)
>
> diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
> index 89bd744c2bffd4..4023de1698b9f5 100644
> --- a/arch/powerpc/net/bpf_jit.h
> +++ b/arch/powerpc/net/bpf_jit.h
> @@ -126,6 +126,7 @@
>
> #define SEEN_FUNC 0x20000000 /* might call external helpers */
> #define SEEN_TAILCALL 0x40000000 /* uses tail calls */
> +#define SEEN_BIG_PROG 0x80000000 /* large prog, >32MB */
>
> #define SEEN_VREG_MASK 0x1ff80000 /* Volatile registers r3-r12 */
> #define SEEN_NVREG_MASK 0x0003ffff /* Non volatile registers r14-r31 */
> @@ -179,6 +180,8 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
> 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, unsigned long exit_addr);
>
> #endif
>
> diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
> index fcbf7a917c566e..3204872fbf2738 100644
> --- a/arch/powerpc/net/bpf_jit_comp.c
> +++ b/arch/powerpc/net/bpf_jit_comp.c
> @@ -72,6 +72,21 @@ static int bpf_jit_fixup_subprog_calls(struct bpf_prog *fp, u32 *image,
> return 0;
> }
>
> +int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx,
> + int tmp_reg, unsigned long exit_addr)
> +{
> + if (!(ctx->seen & SEEN_BIG_PROG) && is_offset_in_branch_range(exit_addr)) {
> + PPC_JMP(exit_addr);
> + } else {
> + ctx->seen |= SEEN_BIG_PROG;
> + PPC_FUNC_ADDR(tmp_reg, (unsigned long)image + exit_addr);
> + EMIT(PPC_RAW_MTCTR(tmp_reg));
> + EMIT(PPC_RAW_BCTR());
> + }
> +
> + return 0;
> +}
> +
> struct powerpc64_jit_data {
> struct bpf_binary_header *header;
> u32 *addrs;
> @@ -155,12 +170,17 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
> goto out_addrs;
> }
>
> + if (!is_offset_in_branch_range((long)cgctx.idx * 4))
> + cgctx.seen |= SEEN_BIG_PROG;
> +
> /*
> * If we have seen a tail call, we need a second pass.
> * This is because bpf_jit_emit_common_epilogue() is called
> * from bpf_jit_emit_tail_call() with a not yet stable ctx->seen.
> + * We also need a second pass if we ended up with too large
> + * a program so as to fix branches.
> */
> - if (cgctx.seen & SEEN_TAILCALL) {
> + if (cgctx.seen & (SEEN_TAILCALL | SEEN_BIG_PROG)) {
> cgctx.idx = 0;
> if (bpf_jit_build_body(fp, 0, &cgctx, addrs, false)) {
> fp = org_fp;
> diff --git a/arch/powerpc/net/bpf_jit_comp32.c b/arch/powerpc/net/bpf_jit_comp32.c
> index a74d52204f8da2..d2a67574a23066 100644
> --- a/arch/powerpc/net/bpf_jit_comp32.c
> +++ b/arch/powerpc/net/bpf_jit_comp32.c
> @@ -852,7 +852,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
> * we'll just fall through to the epilogue.
> */
> if (i != flen - 1)
> - PPC_JMP(exit_addr);
> + bpf_jit_emit_exit_insn(image, ctx, tmp_reg, exit_addr);
On ppc32, if you use tmp_reg you must flag it. But I think you could use
r0 instead.
> /* else fall through to the epilogue */
> break;
>
> diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
> index f06c62089b1457..3351a866ef6207 100644
> --- a/arch/powerpc/net/bpf_jit_comp64.c
> +++ b/arch/powerpc/net/bpf_jit_comp64.c
> @@ -761,7 +761,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
> * we'll just fall through to the epilogue.
> */
> if (i != flen - 1)
> - PPC_JMP(exit_addr);
> + bpf_jit_emit_exit_insn(image, ctx, b2p[TMP_REG_1], exit_addr);
> /* else fall through to the epilogue */
> break;
>
>
^ permalink raw reply
* Re: [PATCH 6/9] powerpc/bpf: Fix BPF_SUB when imm == 0x80000000
From: Christophe Leroy @ 2021-10-03 8:07 UTC (permalink / raw)
To: Naveen N. Rao, Michael Ellerman, Nicholas Piggin, Daniel Borkmann,
Alexei Starovoitov, Johan Almbladh
Cc: bpf, linuxppc-dev
In-Reply-To: <1912a409447071f46ac6cc957ce8edea0e5232b7.1633104510.git.naveen.n.rao@linux.vnet.ibm.com>
Le 01/10/2021 à 23:14, Naveen N. Rao a écrit :
> We aren't handling subtraction involving an immediate value of
> 0x80000000 properly. Fix the same.
>
> Fixes: 156d0e290e969c ("powerpc/ebpf/jit: Implement JIT compiler for extended BPF")
> Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
> ---
> arch/powerpc/net/bpf_jit_comp64.c | 16 ++++++++--------
> 1 file changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
> index ffb7a2877a8469..4641a50e82d50d 100644
> --- a/arch/powerpc/net/bpf_jit_comp64.c
> +++ b/arch/powerpc/net/bpf_jit_comp64.c
> @@ -333,15 +333,15 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
> case BPF_ALU | BPF_SUB | BPF_K: /* (u32) dst -= (u32) imm */
> case BPF_ALU64 | BPF_ADD | BPF_K: /* dst += imm */
> case BPF_ALU64 | BPF_SUB | BPF_K: /* dst -= imm */
> - if (BPF_OP(code) == BPF_SUB)
> - imm = -imm;
> - if (imm) {
> - if (imm >= -32768 && imm < 32768)
> - EMIT(PPC_RAW_ADDI(dst_reg, dst_reg, IMM_L(imm)));
> - else {
> - PPC_LI32(b2p[TMP_REG_1], imm);
> + if (imm > -32768 && imm < 32768) {
> + EMIT(PPC_RAW_ADDI(dst_reg, dst_reg,
> + BPF_OP(code) == BPF_SUB ? IMM_L(-imm) : IMM_L(imm)));
> + } else {
> + PPC_LI32(b2p[TMP_REG_1], imm);
> + if (BPF_OP(code) == BPF_SUB)
> + EMIT(PPC_RAW_SUB(dst_reg, dst_reg, b2p[TMP_REG_1]));
> + else
> EMIT(PPC_RAW_ADD(dst_reg, dst_reg, b2p[TMP_REG_1]));
> - }
> }
> goto bpf_alu32_trunc;
There is now so few code common to both BPF_ADD and BPF_SUB that you
should make them different cases.
While at it, why not also use ADDIS if imm is 32 bits ? That would be an
ADDIS/ADDI instead of LIS/ORI/ADD
> case BPF_ALU | BPF_MUL | BPF_X: /* (u32) dst *= (u32) src */
>
^ permalink raw reply
* Re: Add Apple M1 support to PASemi i2c driver
From: Sven Peter @ 2021-10-03 14:36 UTC (permalink / raw)
To: Christian Zigotzky
Cc: Darren Stevens, Arnd Bergmann, Hector Martin,
Linux Kernel Mailing List, linux-i2c, Paul Mackerras,
Alyssa Rosenzweig, R.T.Dickinson, Olof Johansson,
mohamed.mediouni, Matthew Leaman, Mark Kettenis, linuxppc-dev,
R.T.Dickinson, linux-arm-kernel, Stan Skowronek
In-Reply-To: <9c1f5c48-bf1a-0ecc-e769-773d2935c66c@xenosoft.de>
Hi,
On Fri, Oct 1, 2021, at 06:47, Christian Zigotzky wrote:
> On 27 September 2021 at 07:39 am, Sven Peter wrote:
> > Hi Christian,
> >
> > Thanks already for volunteering to test this!
> >
> Hello Sven,
>
> Damian (Hypex) has successfully tested the RC3 of kernel 5.15 with your
> modified i2c driver on his Nemo board yesterday. [1]
Thanks a lot, that's great to hear!
If he wants to I can credit him with a Tested-by tag in the commit message,
see e.g. https://www.kernel.org/doc/html/latest/process/submitting-patches.html#using-reported-by-tested-by-reviewed-by-suggested-by-and-fixes.
Best,
Sven
^ permalink raw reply
* Re: [PATCH 09/10] i2c: pasemi: Add Apple platform driver
From: Sven Peter @ 2021-10-03 14:37 UTC (permalink / raw)
To: Wolfram Sang
Cc: Arnd Bergmann, Hector Martin, linux-kernel, linux-i2c,
Paul Mackerras, linux-arm-kernel, Olof Johansson,
Mohamed Mediouni, Mark Kettenis, linuxppc-dev, Alyssa Rosenzweig,
Stan Skowronek
In-Reply-To: <YVTNpt/vOeZI5P+L@kunai>
On Wed, Sep 29, 2021, at 22:33, Wolfram Sang wrote:
>> drivers/i2c/busses/i2c-pasemi-apple.c | 122 ++++++++++++++++++++++++++
>
> Can't we name it 'i2c-pasemi-platform.c' instead? Makes more sense to me
> because the other instance is named -pci.
Sure, that's more consistent. I'll change the filename for v2.
Thanks,
Sven
^ permalink raw reply
* Re: Add Apple M1 support to PASemi i2c driver
From: Christian Zigotzky @ 2021-10-03 15:45 UTC (permalink / raw)
To: Sven Peter
Cc: Darren Stevens, Arnd Bergmann, Hector Martin,
Linux Kernel Mailing List, linux-i2c, Paul Mackerras,
Alyssa Rosenzweig, R.T.Dickinson, Olof Johansson,
mohamed.mediouni, Matthew Leaman, Mark Kettenis, linuxppc-dev,
R.T.Dickinson, linux-arm-kernel, Stan Skowronek
In-Reply-To: <49890226-cf04-46ff-bc37-33d1643faea2@www.fastmail.com>
On 03 October 2021 at 04:36 pm, Sven Peter wrote:
> Hi,
>
>
> On Fri, Oct 1, 2021, at 06:47, Christian Zigotzky wrote:
>> On 27 September 2021 at 07:39 am, Sven Peter wrote:
>> > Hi Christian,
>> >
>> > Thanks already for volunteering to test this!
>> >
>> Hello Sven,
>>
>> Damian (Hypex) has successfully tested the RC3 of kernel 5.15 with your
>> modified i2c driver on his Nemo board yesterday. [1]
>
> Thanks a lot, that's great to hear!
> If he wants to I can credit him with a Tested-by tag in the commit
message,
> see e.g.
https://www.kernel.org/doc/html/latest/process/submitting-patches.html#using-reported-by-tested-by-reviewed-by-suggested-by-and-fixes.
>
>
> Best,
>
>
> Sven
Hello Sven,
We are still testing your i2c modifications. [1]
Please wait a litte bit till we finished our tests.
@Darren
Could you also please check Sven's i2c modifications? He has also
modified your source code a little bit. [2]
@Olof
Are these i2c modifications OK? Do these work on your P.A. Semi board?
Thanks,
Christian
[1] https://forum.hyperion-entertainment.com/viewtopic.php?p=54138#p54138
[2] https://lists.ozlabs.org/pipermail/linuxppc-dev/2017-January/153195.html
^ permalink raw reply
* Re: [PATCH v4 07/11] mm: kasan: Use is_kernel() helper
From: Andrey Konovalov @ 2021-10-03 17:19 UTC (permalink / raw)
To: Kefeng Wang
Cc: linux-arch, Andrey Ryabinin, bpf, Arnd Bergmann, linux-alpha,
LKML, Steven Rostedt, Alexei Starovoitov, mingo, paulus,
Alexander Potapenko, Andrew Morton, linuxppc-dev, David Miller,
Dmitry Vyukov
In-Reply-To: <20210930071143.63410-8-wangkefeng.wang@huawei.com>
On Thu, Sep 30, 2021 at 9:09 AM Kefeng Wang <wangkefeng.wang@huawei.com> wrote:
>
> Directly use is_kernel() helper in kernel_or_module_addr().
>
> Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
> Cc: Alexander Potapenko <glider@google.com>
> Cc: Andrey Konovalov <andreyknvl@gmail.com>
> Cc: Dmitry Vyukov <dvyukov@google.com>
> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
> ---
> mm/kasan/report.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/mm/kasan/report.c b/mm/kasan/report.c
> index 3239fd8f8747..1c955e1c98d5 100644
> --- a/mm/kasan/report.c
> +++ b/mm/kasan/report.c
> @@ -226,7 +226,7 @@ static void describe_object(struct kmem_cache *cache, void *object,
>
> static inline bool kernel_or_module_addr(const void *addr)
> {
> - if (addr >= (void *)_stext && addr < (void *)_end)
> + if (is_kernel((unsigned long)addr))
> return true;
> if (is_module_address((unsigned long)addr))
> return true;
> --
> 2.26.2
>
Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com>
^ permalink raw reply
* Re: [PATCH v4 0/8] bpf powerpc: Add BPF_PROBE_MEM support in powerpc JIT compiler
From: Michael Ellerman @ 2021-10-03 22:49 UTC (permalink / raw)
To: Daniel Borkmann, Hari Bathini, naveen.n.rao, christophe.leroy,
ast
Cc: songliubraving, netdev, john.fastabend, andrii, kpsingh, paulus,
yhs, bpf, linuxppc-dev, kafai
In-Reply-To: <88b59272-e3f7-30ba-dda0-c4a6b42c0029@iogearbox.net>
Daniel Borkmann <daniel@iogearbox.net> writes:
> On 9/29/21 1:18 PM, Hari Bathini wrote:
>> Patch #1 & #2 are simple cleanup patches. Patch #3 refactors JIT
>> compiler code with the aim to simplify adding BPF_PROBE_MEM support.
>> Patch #4 introduces PPC_RAW_BRANCH() macro instead of open coding
>> branch instruction. Patch #5 & #7 add BPF_PROBE_MEM support for PPC64
>> & PPC32 JIT compilers respectively. Patch #6 & #8 handle bad userspace
>> pointers for PPC64 & PPC32 cases respectively.
>
> Michael, are you planning to pick up the series or shall we route via bpf-next?
Yeah I'll plan to take it, unless you think there is a strong reason it
needs to go via the bpf tree (doesn't look like it from the diffstat).
cheers
^ permalink raw reply
* Re: [PATCH v4 0/8] bpf powerpc: Add BPF_PROBE_MEM support in powerpc JIT compiler
From: Daniel Borkmann @ 2021-10-04 8:05 UTC (permalink / raw)
To: Michael Ellerman, Hari Bathini, naveen.n.rao, christophe.leroy,
ast
Cc: songliubraving, netdev, john.fastabend, andrii, kpsingh, paulus,
yhs, bpf, linuxppc-dev, kafai
In-Reply-To: <87o885raev.fsf@mpe.ellerman.id.au>
On 10/4/21 12:49 AM, Michael Ellerman wrote:
> Daniel Borkmann <daniel@iogearbox.net> writes:
>> On 9/29/21 1:18 PM, Hari Bathini wrote:
>>> Patch #1 & #2 are simple cleanup patches. Patch #3 refactors JIT
>>> compiler code with the aim to simplify adding BPF_PROBE_MEM support.
>>> Patch #4 introduces PPC_RAW_BRANCH() macro instead of open coding
>>> branch instruction. Patch #5 & #7 add BPF_PROBE_MEM support for PPC64
>>> & PPC32 JIT compilers respectively. Patch #6 & #8 handle bad userspace
>>> pointers for PPC64 & PPC32 cases respectively.
>>
>> Michael, are you planning to pick up the series or shall we route via bpf-next?
>
> Yeah I'll plan to take it, unless you think there is a strong reason it
> needs to go via the bpf tree (doesn't look like it from the diffstat).
Sounds good to me, in that case, please also route the recent JIT fixes from
Naveen through your tree.
Thanks,
Daniel
^ permalink raw reply
* Re: [PATCH v4 0/8] bpf powerpc: Add BPF_PROBE_MEM support in powerpc JIT compiler
From: Michael Ellerman @ 2021-10-04 8:43 UTC (permalink / raw)
To: Daniel Borkmann, Hari Bathini, naveen.n.rao, christophe.leroy,
ast
Cc: songliubraving, netdev, john.fastabend, andrii, kpsingh, paulus,
yhs, bpf, linuxppc-dev, kafai
In-Reply-To: <768469ec-a596-9e0c-541c-aca5693d69e7@iogearbox.net>
Daniel Borkmann <daniel@iogearbox.net> writes:
> On 10/4/21 12:49 AM, Michael Ellerman wrote:
>> Daniel Borkmann <daniel@iogearbox.net> writes:
>>> On 9/29/21 1:18 PM, Hari Bathini wrote:
>>>> Patch #1 & #2 are simple cleanup patches. Patch #3 refactors JIT
>>>> compiler code with the aim to simplify adding BPF_PROBE_MEM support.
>>>> Patch #4 introduces PPC_RAW_BRANCH() macro instead of open coding
>>>> branch instruction. Patch #5 & #7 add BPF_PROBE_MEM support for PPC64
>>>> & PPC32 JIT compilers respectively. Patch #6 & #8 handle bad userspace
>>>> pointers for PPC64 & PPC32 cases respectively.
>>>
>>> Michael, are you planning to pick up the series or shall we route via bpf-next?
>>
>> Yeah I'll plan to take it, unless you think there is a strong reason it
>> needs to go via the bpf tree (doesn't look like it from the diffstat).
>
> Sounds good to me, in that case, please also route the recent JIT fixes from
> Naveen through your tree.
Will do.
cheers
^ permalink raw reply
* [PATCH] powerpc/eeh:Fix docstrings in eeh
From: Kai Song @ 2021-10-04 8:58 UTC (permalink / raw)
To: linuxppc-dev; +Cc: paulus, Kai Song, oohall, linux-kernel, dja
We fix the following warnings when building kernel with W=1:
arch/powerpc/kernel/eeh.c:598: warning: Function parameter or member 'function' not described in 'eeh_pci_enable'
arch/powerpc/kernel/eeh.c:774: warning: Function parameter or member 'edev' not described in 'eeh_set_dev_freset'
arch/powerpc/kernel/eeh.c:774: warning: expecting prototype for eeh_set_pe_freset(). Prototype was for eeh_set_dev_freset() instead
arch/powerpc/kernel/eeh.c:814: warning: Function parameter or member 'include_passed' not described in 'eeh_pe_reset_full'
arch/powerpc/kernel/eeh.c:944: warning: Function parameter or member 'ops' not described in 'eeh_init'
arch/powerpc/kernel/eeh.c:1451: warning: Function parameter or member 'include_passed' not described in 'eeh_pe_reset'
arch/powerpc/kernel/eeh.c:1526: warning: Function parameter or member 'func' not described in 'eeh_pe_inject_err'
arch/powerpc/kernel/eeh.c:1526: warning: Excess function parameter 'function' described in 'eeh_pe_inject_err'
Signed-off-by: Kai Song <songkai01@inspur.com>
---
arch/powerpc/kernel/eeh.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index e9b597ed423c..57a6868a41ab 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -589,6 +589,7 @@ EXPORT_SYMBOL(eeh_check_failure);
/**
* eeh_pci_enable - Enable MMIO or DMA transfers for this slot
* @pe: EEH PE
+ * @function : EEH function
*
* This routine should be called to reenable frozen MMIO or DMA
* so that it would work correctly again. It's useful while doing
@@ -761,8 +762,8 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state stat
}
/**
- * eeh_set_pe_freset - Check the required reset for the indicated device
- * @data: EEH device
+ * eeh_set_dev_freset - Check the required reset for the indicated device
+ * @edev: EEH device
* @flag: return value
*
* Each device might have its preferred reset type: fundamental or
@@ -801,6 +802,7 @@ static void eeh_pe_refreeze_passed(struct eeh_pe *root)
/**
* eeh_pe_reset_full - Complete a full reset process on the indicated PE
* @pe: EEH PE
+ * @include_passed: include passed-through devices?
*
* This function executes a full reset procedure on a PE, including setting
* the appropriate flags, performing a fundamental or hot reset, and then
@@ -937,6 +939,7 @@ static struct notifier_block eeh_device_nb = {
/**
* eeh_init - System wide EEH initialization
+ * @ops: struct to trace EEH operation callback functions
*
* It's the platform's job to call this from an arch_initcall().
*/
@@ -1442,6 +1445,7 @@ static int eeh_pe_reenable_devices(struct eeh_pe *pe, bool include_passed)
* eeh_pe_reset - Issue PE reset according to specified type
* @pe: EEH PE
* @option: reset type
+ * @include_passed: include passed-through devices?
*
* The routine is called to reset the specified PE with the
* indicated type, either fundamental reset or hot reset.
@@ -1513,12 +1517,12 @@ EXPORT_SYMBOL_GPL(eeh_pe_configure);
* eeh_pe_inject_err - Injecting the specified PCI error to the indicated PE
* @pe: the indicated PE
* @type: error type
- * @function: error function
+ * @func: error function
* @addr: address
* @mask: address mask
*
* The routine is called to inject the specified PCI error, which
- * is determined by @type and @function, to the indicated PE for
+ * is determined by @type and @func, to the indicated PE for
* testing purpose.
*/
int eeh_pe_inject_err(struct eeh_pe *pe, int type, int func,
--
2.27.0
^ permalink raw reply related
* Re: [PATCH 1/5] dt-bindings: memory: fsl: convert ifc binding to yaml schema
From: Krzysztof Kozlowski @ 2021-10-04 9:31 UTC (permalink / raw)
To: Li Yang
Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
linuxppc-dev, lkml, Rob Herring, Shawn Guo,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <CADRPPNROVBp_QB=6XEgk8WF5fnEPFTSko4Nn+mm8oLM3iGTuuw@mail.gmail.com>
On 01/10/2021 18:17, Li Yang wrote:
> On Fri, Oct 1, 2021 at 5:01 AM Krzysztof Kozlowski
> <krzysztof.kozlowski@canonical.com> wrote:
>>
(...)
>>> +
>>> + interrupts:
>>> + minItems: 1
>>> + maxItems: 2
>>> + description: |
>>> + IFC may have one or two interrupts. If two interrupt specifiers are
>>> + present, the first is the "common" interrupt (CM_EVTER_STAT), and the
>>> + second is the NAND interrupt (NAND_EVTER_STAT). If there is only one,
>>> + that interrupt reports both types of event.
>>> +
>>> + little-endian:
>>> + $ref: '/schemas/types.yaml#/definitions/flag'
>>
>> type: boolean
>
> It will not have a true or false value, but only present or not. Is
> the boolean type taking care of this too?
boolean is for a property which does not accept values and true/false
depends on its presence.
See:
Documentation/devicetree/bindings/phy/lantiq,vrx200-pcie-phy.yaml
Documentation/devicetree/bindings/thermal/qoriq-thermal.yaml
Best regards,
Krzysztof
^ permalink raw reply
* Re: Add Apple M1 support to PASemi i2c driver
From: Christian Zigotzky @ 2021-10-04 9:47 UTC (permalink / raw)
To: Sven Peter
Cc: Darren Stevens, Arnd Bergmann, Hector Martin,
Linux Kernel Mailing List, linux-i2c, Paul Mackerras,
Alyssa Rosenzweig, R.T.Dickinson, Olof Johansson,
mohamed.mediouni, Matthew Leaman, Mark Kettenis, linuxppc-dev,
R.T.Dickinson, linux-arm-kernel, Stan Skowronek
In-Reply-To: <49890226-cf04-46ff-bc37-33d1643faea2@www.fastmail.com>
Hi Sven,
Unfortunately Damien has found an issue. [1]
Output of i2cdetect -l with the default RC3 of kernel 5.15 without your modifications:
2c-0 i2c Radeon i2c bit bus 0x90 I2C adapter
i2c-1 i2c Radeon i2c bit bus 0x91 I2C adapter
i2c-2 i2c Radeon i2c bit bus 0x92 I2C adapter
i2c-3 i2c Radeon i2c bit bus 0x93 I2C adapter
i2c-4 i2c Radeon i2c bit bus 0x94 I2C adapter
i2c-5 i2c Radeon i2c bit bus 0x95 I2C adapter
i2c-6 i2c Radeon i2c bit bus 0x96 I2C adapter
i2c-7 i2c Radeon i2c bit bus 0x97 I2C adapter
i2c-8 i2c PA Semi SMBus adapter at 0x800200 I2C adapter
i2c-9 i2c PA Semi SMBus adapter at 0x800240 I2C adapter
i2c-10 i2c PA Semi SMBus adapter at 0x800280 I2C adapter
Output of i2cdetect -l with your modifications:
i2c-0 i2c Radeon i2c bit bus 0x90 I2C adapter
i2c-1 i2c Radeon i2c bit bus 0x91 I2C adapter
i2c-2 i2c Radeon i2c bit bus 0x92 I2C adapter
i2c-3 i2c Radeon i2c bit bus 0x93 I2C adapter
i2c-4 i2c Radeon i2c bit bus 0x94 I2C adapter
i2c-5 i2c Radeon i2c bit bus 0x95 I2C adapter
i2c-6 i2c Radeon i2c bit bus 0x96 I2C adapter
i2c-7 i2c Radeon i2c bit bus 0x97 I2C adapter
i2c-8 i2c PA Semi SMBus adapter at 0x(____ptrval____) I2C adapter
i2c-9 i2c PA Semi SMBus adapter at 0x(____ptrval____) I2C adapter
i2c-10 i2c PA Semi SMBus adapter at 0x(____ptrval____) I2C adapter
Please check the outputs.
Thanks,
Christian
[1] https://forum.hyperion-entertainment.com/viewtopic.php?p=54165#p54165
^ permalink raw reply
* Re: Add Apple M1 support to PASemi i2c driver
From: Wolfram Sang @ 2021-10-04 9:55 UTC (permalink / raw)
To: Christian Zigotzky
Cc: Darren Stevens, Arnd Bergmann, Sven Peter, Hector Martin,
Linux Kernel Mailing List, linux-i2c, Paul Mackerras,
Alyssa Rosenzweig, R.T.Dickinson, Olof Johansson,
mohamed.mediouni, Matthew Leaman, Mark Kettenis, linuxppc-dev,
R.T.Dickinson, linux-arm-kernel, Stan Skowronek
In-Reply-To: <1B71F6A3-6467-46EF-858F-82E93D54365D@xenosoft.de>
[-- Attachment #1: Type: text/plain, Size: 349 bytes --]
> i2c-8 i2c PA Semi SMBus adapter at 0x(____ptrval____) I2C adapter
> i2c-9 i2c PA Semi SMBus adapter at 0x(____ptrval____) I2C adapter
> i2c-10 i2c PA Semi SMBus adapter at 0x(____ptrval____) I2C adapter
As Sven correctly switched from %lx to %p, this is intended behaviour.
Run 'i2cdetect' as root to see the values again.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: Add Apple M1 support to PASemi i2c driver
From: Sven Peter @ 2021-10-04 11:22 UTC (permalink / raw)
To: Arnd Bergmann, Wolfram Sang, Christian Zigotzky, Michael Ellerman,
Benjamin Herrenschmidt, Paul Mackerras, Olof Johansson,
Hector Martin, Mohamed Mediouni, Stan Skowronek, Mark Kettenis,
Linux ARM, Alyssa Rosenzweig, linuxppc-dev, Linux I2C,
Linux Kernel Mailing List, R.T.Dickinson, Darren Stevens,
Matthew Leaman, R.T.Dickinson
In-Reply-To: <CAK8P3a2760x4OYbNBuFCv32Tgt7K3MdJna4qXvPchdKhV8-8vQ@mail.gmail.com>
On Mon, Oct 4, 2021, at 13:20, Arnd Bergmann wrote:
> On Mon, Oct 4, 2021 at 11:55 AM Wolfram Sang <wsa@kernel.org> wrote:
>>
>>
>> > i2c-8 i2c PA Semi SMBus adapter at 0x(____ptrval____) I2C adapter
>> > i2c-9 i2c PA Semi SMBus adapter at 0x(____ptrval____) I2C adapter
>> > i2c-10 i2c PA Semi SMBus adapter at 0x(____ptrval____) I2C adapter
>>
>> As Sven correctly switched from %lx to %p, this is intended behaviour.
>> Run 'i2cdetect' as root to see the values again.
>
> I think the address could just get removed here, as this is clearly not helpful.
> port number, which is somewhat useful for identifying the device, now
> it's either the pointless string, or the virtual address that the
> device is mapped
> to, which is not helpful either and potentially leaks information about kernel
> internal structures.
Yeah, now that I'm looking at it again it doesn't make much sense to
include it there. Maybe just dev_name(smbus->dev) instead of the address?
Sven
^ permalink raw reply
* Re: Add Apple M1 support to PASemi i2c driver
From: Arnd Bergmann @ 2021-10-04 11:20 UTC (permalink / raw)
To: Wolfram Sang, Christian Zigotzky, Sven Peter, Michael Ellerman,
Benjamin Herrenschmidt, Paul Mackerras, Olof Johansson,
Arnd Bergmann, Hector Martin, Mohamed Mediouni, Stan Skowronek,
Mark Kettenis, Linux ARM, Alyssa Rosenzweig, linuxppc-dev,
Linux I2C, Linux Kernel Mailing List, R.T.Dickinson,
Darren Stevens, Matthew Leaman, R.T.Dickinson
In-Reply-To: <YVrPf4yVFm184LEG@shikoro>
On Mon, Oct 4, 2021 at 11:55 AM Wolfram Sang <wsa@kernel.org> wrote:
>
>
> > i2c-8 i2c PA Semi SMBus adapter at 0x(____ptrval____) I2C adapter
> > i2c-9 i2c PA Semi SMBus adapter at 0x(____ptrval____) I2C adapter
> > i2c-10 i2c PA Semi SMBus adapter at 0x(____ptrval____) I2C adapter
>
> As Sven correctly switched from %lx to %p, this is intended behaviour.
> Run 'i2cdetect' as root to see the values again.
I think the address could just get removed here, as this is clearly not helpful.
port number, which is somewhat useful for identifying the device, now
it's either the pointless string, or the virtual address that the
device is mapped
to, which is not helpful either and potentially leaks information about kernel
internal structures.
Arnd
^ permalink raw reply
* [PATCH v6 05/11] powerpc/eeh: Don't use driver member of struct pci_dev and further cleanups
From: Uwe Kleine-König @ 2021-10-04 12:59 UTC (permalink / raw)
To: Bjorn Helgaas, Michael Ellerman
Cc: linux-pci, Oliver O'Halloran, kernel, Paul Mackerras,
linuxppc-dev
In-Reply-To: <20211004125935.2300113-1-u.kleine-koenig@pengutronix.de>
The driver member of struct pci_dev is to be removed as it tracks
information already present by tracking of the driver core. So replace
pdev->driver->name by dev_driver_string() for the corresponding struct
device.
Also move the function nearer to its only user and instead of the ?:
operator use a normal if which is more readable.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
arch/powerpc/include/asm/ppc-pci.h | 5 -----
arch/powerpc/kernel/eeh.c | 8 ++++++++
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/include/asm/ppc-pci.h b/arch/powerpc/include/asm/ppc-pci.h
index 2b9edbf6e929..f6cf0159024e 100644
--- a/arch/powerpc/include/asm/ppc-pci.h
+++ b/arch/powerpc/include/asm/ppc-pci.h
@@ -55,11 +55,6 @@ void eeh_pe_dev_mode_mark(struct eeh_pe *pe, int mode);
void eeh_sysfs_add_device(struct pci_dev *pdev);
void eeh_sysfs_remove_device(struct pci_dev *pdev);
-static inline const char *eeh_driver_name(struct pci_dev *pdev)
-{
- return (pdev && pdev->driver) ? pdev->driver->name : "<null>";
-}
-
#endif /* CONFIG_EEH */
#define PCI_BUSNO(bdfn) ((bdfn >> 8) & 0xff)
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index e9b597ed423c..4b08881c4a1e 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -399,6 +399,14 @@ static int eeh_phb_check_failure(struct eeh_pe *pe)
return ret;
}
+static inline const char *eeh_driver_name(struct pci_dev *pdev)
+{
+ if (pdev)
+ return dev_driver_string(&pdev->dev);
+
+ return "<null>";
+}
+
/**
* eeh_dev_check_failure - Check if all 1's data is due to EEH slot freeze
* @edev: eeh device
--
2.30.2
^ permalink raw reply related
* [PATCH v6 07/11] PCI: Replace pci_dev::driver usage that gets the driver name
From: Uwe Kleine-König @ 2021-10-04 12:59 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-pci, Alexander Duyck, oss-drivers, Paul Mackerras,
Herbert Xu, Rafał Miłecki, Jesse Brandeburg,
Ido Schimmel, Jakub Kicinski, Yisen Zhuang, Vadym Kochan,
Michael Buesch, Jiri Pirko, Salil Mehta, netdev, linux-wireless,
linux-kernel, Taras Chornyi, Zhou Wang, linux-crypto, kernel,
Simon Horman, Oliver O'Halloran, linuxppc-dev,
David S. Miller
In-Reply-To: <20211004125935.2300113-1-u.kleine-koenig@pengutronix.de>
struct pci_dev::driver holds (apart from a constant offset) the same
data as struct pci_dev::dev->driver. With the goal to remove struct
pci_dev::driver to get rid of data duplication replace getting the
driver name by dev_driver_string() which implicitly makes use of struct
pci_dev::dev->driver.
Acked-by: Simon Horman <simon.horman@corigine.com> (for NFP)
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
drivers/crypto/hisilicon/qm.c | 2 +-
drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 2 +-
drivers/net/ethernet/marvell/prestera/prestera_pci.c | 2 +-
drivers/net/ethernet/mellanox/mlxsw/pci.c | 2 +-
drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c | 3 ++-
5 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
index 369562d34d66..8f361e54e524 100644
--- a/drivers/crypto/hisilicon/qm.c
+++ b/drivers/crypto/hisilicon/qm.c
@@ -3085,7 +3085,7 @@ static int qm_alloc_uacce(struct hisi_qm *qm)
};
int ret;
- ret = strscpy(interface.name, pdev->driver->name,
+ ret = strscpy(interface.name, dev_driver_string(&pdev->dev),
sizeof(interface.name));
if (ret < 0)
return -ENAMETOOLONG;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index 7ea511d59e91..f279edfce3f1 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -606,7 +606,7 @@ static void hns3_get_drvinfo(struct net_device *netdev,
return;
}
- strncpy(drvinfo->driver, h->pdev->driver->name,
+ strncpy(drvinfo->driver, dev_driver_string(&h->pdev->dev),
sizeof(drvinfo->driver));
drvinfo->driver[sizeof(drvinfo->driver) - 1] = '\0';
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_pci.c b/drivers/net/ethernet/marvell/prestera/prestera_pci.c
index a250d394da38..a8f007f6dad2 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_pci.c
+++ b/drivers/net/ethernet/marvell/prestera/prestera_pci.c
@@ -720,7 +720,7 @@ static int prestera_fw_load(struct prestera_fw *fw)
static int prestera_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
- const char *driver_name = pdev->driver->name;
+ const char *driver_name = dev_driver_string(&pdev->dev);
struct prestera_fw *fw;
int err;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c
index 13b0259f7ea6..8f306364f7bf 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/pci.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c
@@ -1876,7 +1876,7 @@ static void mlxsw_pci_cmd_fini(struct mlxsw_pci *mlxsw_pci)
static int mlxsw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
- const char *driver_name = pdev->driver->name;
+ const char *driver_name = dev_driver_string(&pdev->dev);
struct mlxsw_pci *mlxsw_pci;
int err;
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
index 0685ece1f155..1de076f55740 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
@@ -202,7 +202,8 @@ nfp_get_drvinfo(struct nfp_app *app, struct pci_dev *pdev,
{
char nsp_version[ETHTOOL_FWVERS_LEN] = {};
- strlcpy(drvinfo->driver, pdev->driver->name, sizeof(drvinfo->driver));
+ strlcpy(drvinfo->driver, dev_driver_string(&pdev->dev),
+ sizeof(drvinfo->driver));
nfp_net_get_nspinfo(app, nsp_version);
snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
"%s %s %s %s", vnic_version, nsp_version,
--
2.30.2
^ permalink raw reply related
* [PATCH v6 10/11] PCI: Replace pci_dev::driver usage by pci_dev::dev.driver
From: Uwe Kleine-König @ 2021-10-04 12:59 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Mark Rutland, Peter Zijlstra, linux-pci, Oliver O'Halloran,
H. Peter Anvin, Jiri Olsa, Boris Ostrovsky, Stefano Stabellini,
Mathias Nyman, x86, Alexander Shishkin, Ingo Molnar, xen-devel,
Andrew Donnellan, Arnd Bergmann, Konrad Rzeszutek Wilk,
Arnaldo Carvalho de Melo, Borislav Petkov, Bjorn Helgaas,
Namhyung Kim, Thomas Gleixner, Juergen Gross, Greg Kroah-Hartman,
linux-usb, linux-perf-users, kernel, Frederic Barrat,
Paul Mackerras, linuxppc-dev
In-Reply-To: <20211004125935.2300113-1-u.kleine-koenig@pengutronix.de>
struct pci_dev::driver contains (apart from a constant offset) the same
data as struct pci_dev::dev->driver. Replace all remaining users of the
former pointer by the latter to allow removing the former.
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
arch/powerpc/kernel/eeh_driver.c | 10 ++---
arch/x86/events/intel/uncore.c | 2 +-
arch/x86/kernel/probe_roms.c | 10 +++--
drivers/misc/cxl/guest.c | 24 +++++-----
drivers/misc/cxl/pci.c | 30 ++++++++-----
drivers/pci/iov.c | 33 ++++++++++----
drivers/pci/pci-driver.c | 76 +++++++++++++++++++-------------
drivers/pci/pci.c | 4 +-
drivers/pci/pcie/err.c | 36 ++++++++-------
drivers/pci/xen-pcifront.c | 4 +-
drivers/usb/host/xhci-pci.c | 2 +-
11 files changed, 140 insertions(+), 91 deletions(-)
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
index 3eff6a4888e7..350dab18e137 100644
--- a/arch/powerpc/kernel/eeh_driver.c
+++ b/arch/powerpc/kernel/eeh_driver.c
@@ -104,13 +104,13 @@ static bool eeh_edev_actionable(struct eeh_dev *edev)
*/
static inline struct pci_driver *eeh_pcid_get(struct pci_dev *pdev)
{
- if (!pdev || !pdev->driver)
+ if (!pdev || !pdev->dev.driver)
return NULL;
- if (!try_module_get(pdev->driver->driver.owner))
+ if (!try_module_get(pdev->dev.driver->owner))
return NULL;
- return pdev->driver;
+ return to_pci_driver(pdev->dev.driver);
}
/**
@@ -122,10 +122,10 @@ static inline struct pci_driver *eeh_pcid_get(struct pci_dev *pdev)
*/
static inline void eeh_pcid_put(struct pci_dev *pdev)
{
- if (!pdev || !pdev->driver)
+ if (!pdev || !pdev->dev.driver)
return;
- module_put(pdev->driver->driver.owner);
+ module_put(pdev->dev.driver->owner);
}
/**
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index c72e368dd164..f1ba6ab2e97e 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1187,7 +1187,7 @@ static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id
* PCI slot and func to indicate the uncore box.
*/
if (id->driver_data & ~0xffff) {
- struct pci_driver *pci_drv = pdev->driver;
+ struct pci_driver *pci_drv = to_pci_driver(pdev->dev.driver);
pmu = uncore_pci_find_dev_pmu(pdev, pci_drv->id_table);
if (pmu == NULL)
diff --git a/arch/x86/kernel/probe_roms.c b/arch/x86/kernel/probe_roms.c
index 9e1def3744f2..deaaef6efe34 100644
--- a/arch/x86/kernel/probe_roms.c
+++ b/arch/x86/kernel/probe_roms.c
@@ -80,15 +80,17 @@ static struct resource video_rom_resource = {
*/
static bool match_id(struct pci_dev *pdev, unsigned short vendor, unsigned short device)
{
- struct pci_driver *drv = pdev->driver;
const struct pci_device_id *id;
if (pdev->vendor == vendor && pdev->device == device)
return true;
- for (id = drv ? drv->id_table : NULL; id && id->vendor; id++)
- if (id->vendor == vendor && id->device == device)
- break;
+ if (pdev->dev.driver) {
+ struct pci_driver *drv = to_pci_driver(pdev->dev.driver);
+ for (id = drv->id_table; id && id->vendor; id++)
+ if (id->vendor == vendor && id->device == device)
+ break;
+ }
return id && id->vendor;
}
diff --git a/drivers/misc/cxl/guest.c b/drivers/misc/cxl/guest.c
index 186308f1f8eb..d997c9c3ebb5 100644
--- a/drivers/misc/cxl/guest.c
+++ b/drivers/misc/cxl/guest.c
@@ -25,28 +25,32 @@ static void pci_error_handlers(struct cxl_afu *afu,
return;
list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) {
- if (!afu_dev->driver)
+ struct pci_driver *afu_drv;
+
+ if (!afu_dev->dev.driver)
continue;
+ afu_drv = to_pci_driver(afu_dev->dev.driver);
+
switch (bus_error_event) {
case CXL_ERROR_DETECTED_EVENT:
afu_dev->error_state = state;
- if (afu_dev->driver->err_handler &&
- afu_dev->driver->err_handler->error_detected)
- afu_dev->driver->err_handler->error_detected(afu_dev, state);
+ if (afu_drv->err_handler &&
+ afu_drv->err_handler->error_detected)
+ afu_drv->err_handler->error_detected(afu_dev, state);
break;
case CXL_SLOT_RESET_EVENT:
afu_dev->error_state = state;
- if (afu_dev->driver->err_handler &&
- afu_dev->driver->err_handler->slot_reset)
- afu_dev->driver->err_handler->slot_reset(afu_dev);
+ if (afu_drv->err_handler &&
+ afu_drv->err_handler->slot_reset)
+ afu_drv->err_handler->slot_reset(afu_dev);
break;
case CXL_RESUME_EVENT:
- if (afu_dev->driver->err_handler &&
- afu_dev->driver->err_handler->resume)
- afu_dev->driver->err_handler->resume(afu_dev);
+ if (afu_drv->err_handler &&
+ afu_drv->err_handler->resume)
+ afu_drv->err_handler->resume(afu_dev);
break;
}
}
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index 2ba899f5659f..7e7545d01e27 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -1805,14 +1805,16 @@ static pci_ers_result_t cxl_vphb_error_detected(struct cxl_afu *afu,
return result;
list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) {
- if (!afu_dev->driver)
+ struct pci_driver *afu_drv;
+ if (!afu_dev->dev.driver)
continue;
+ afu_drv = to_pci_driver(afu_dev->dev.driver);
+
afu_dev->error_state = state;
- if (afu_dev->driver->err_handler)
- afu_result = afu_dev->driver->err_handler->error_detected(afu_dev,
- state);
+ if (afu_drv->err_handler)
+ afu_result = afu_drv->err_handler->error_detected(afu_dev, state);
/* Disconnect trumps all, NONE trumps NEED_RESET */
if (afu_result == PCI_ERS_RESULT_DISCONNECT)
result = PCI_ERS_RESULT_DISCONNECT;
@@ -2003,6 +2005,8 @@ static pci_ers_result_t cxl_pci_slot_reset(struct pci_dev *pdev)
continue;
list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) {
+ struct pci_driver *afu_drv;
+
/* Reset the device context.
* TODO: make this less disruptive
*/
@@ -2028,12 +2032,14 @@ static pci_ers_result_t cxl_pci_slot_reset(struct pci_dev *pdev)
* shouldn't start new work until we call
* their resume function.
*/
- if (!afu_dev->driver)
+ if (!afu_dev->dev.driver)
continue;
- if (afu_dev->driver->err_handler &&
- afu_dev->driver->err_handler->slot_reset)
- afu_result = afu_dev->driver->err_handler->slot_reset(afu_dev);
+ afu_drv = to_pci_driver(afu_dev->dev.driver);
+
+ if (afu_drv->err_handler &&
+ afu_drv->err_handler->slot_reset)
+ afu_result = afu_drv->err_handler->slot_reset(afu_dev);
if (afu_result == PCI_ERS_RESULT_DISCONNECT)
result = PCI_ERS_RESULT_DISCONNECT;
@@ -2074,9 +2080,11 @@ static void cxl_pci_resume(struct pci_dev *pdev)
continue;
list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) {
- if (afu_dev->driver && afu_dev->driver->err_handler &&
- afu_dev->driver->err_handler->resume)
- afu_dev->driver->err_handler->resume(afu_dev);
+ struct pci_driver *afu_drv;
+ if (afu_dev->dev.driver &&
+ (afu_drv = to_pci_driver(afu_dev->dev.driver))->err_handler &&
+ afu_drv->err_handler->resume)
+ afu_drv->err_handler->resume(afu_dev);
}
}
spin_unlock(&adapter->afu_list_lock);
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index dafdc652fcd0..0d0a34347868 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -164,13 +164,18 @@ static ssize_t sriov_vf_total_msix_show(struct device *dev,
char *buf)
{
struct pci_dev *pdev = to_pci_dev(dev);
+ struct pci_driver *pdrv;
u32 vf_total_msix = 0;
device_lock(dev);
- if (!pdev->driver || !pdev->driver->sriov_get_vf_total_msix)
+ if (!dev->driver)
goto unlock;
- vf_total_msix = pdev->driver->sriov_get_vf_total_msix(pdev);
+ pdrv = to_pci_driver(dev->driver);
+ if (!pdrv->sriov_get_vf_total_msix)
+ goto unlock;
+
+ vf_total_msix = pdrv->sriov_get_vf_total_msix(pdev);
unlock:
device_unlock(dev);
return sysfs_emit(buf, "%u\n", vf_total_msix);
@@ -183,6 +188,7 @@ static ssize_t sriov_vf_msix_count_store(struct device *dev,
{
struct pci_dev *vf_dev = to_pci_dev(dev);
struct pci_dev *pdev = pci_physfn(vf_dev);
+ struct pci_driver *pdrv;
int val, ret;
ret = kstrtoint(buf, 0, &val);
@@ -193,13 +199,19 @@ static ssize_t sriov_vf_msix_count_store(struct device *dev,
return -EINVAL;
device_lock(&pdev->dev);
- if (!pdev->driver || !pdev->driver->sriov_set_msix_vec_count) {
+ if (!pdev->dev.driver) {
+ ret = -EOPNOTSUPP;
+ goto err_pdev;
+ }
+
+ pdrv = to_pci_driver(pdev->dev.driver);
+ if (!pdrv->sriov_set_msix_vec_count) {
ret = -EOPNOTSUPP;
goto err_pdev;
}
device_lock(&vf_dev->dev);
- if (vf_dev->driver) {
+ if (vf_dev->dev.driver) {
/*
* A driver is already attached to this VF and has configured
* itself based on the current MSI-X vector count. Changing
@@ -209,7 +221,7 @@ static ssize_t sriov_vf_msix_count_store(struct device *dev,
goto err_dev;
}
- ret = pdev->driver->sriov_set_msix_vec_count(vf_dev, val);
+ ret = pdrv->sriov_set_msix_vec_count(vf_dev, val);
err_dev:
device_unlock(&vf_dev->dev);
@@ -376,6 +388,7 @@ static ssize_t sriov_numvfs_store(struct device *dev,
const char *buf, size_t count)
{
struct pci_dev *pdev = to_pci_dev(dev);
+ struct pci_driver *pdrv;
int ret;
u16 num_vfs;
@@ -392,14 +405,16 @@ static ssize_t sriov_numvfs_store(struct device *dev,
goto exit;
/* is PF driver loaded */
- if (!pdev->driver) {
+ if (!pdev->dev.driver) {
pci_info(pdev, "no driver bound to device; cannot configure SR-IOV\n");
ret = -ENOENT;
goto exit;
}
+ pdrv = to_pci_driver(pdev->dev.driver);
+
/* is PF driver loaded w/callback */
- if (!pdev->driver->sriov_configure) {
+ if (!pdrv->sriov_configure) {
pci_info(pdev, "driver does not support SR-IOV configuration via sysfs\n");
ret = -ENOENT;
goto exit;
@@ -407,7 +422,7 @@ static ssize_t sriov_numvfs_store(struct device *dev,
if (num_vfs == 0) {
/* disable VFs */
- ret = pdev->driver->sriov_configure(pdev, 0);
+ ret = pdrv->sriov_configure(pdev, 0);
goto exit;
}
@@ -419,7 +434,7 @@ static ssize_t sriov_numvfs_store(struct device *dev,
goto exit;
}
- ret = pdev->driver->sriov_configure(pdev, num_vfs);
+ ret = pdrv->sriov_configure(pdev, num_vfs);
if (ret < 0)
goto exit;
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 50449ec622a3..8654fe70cd66 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -457,7 +457,7 @@ static int pci_device_probe(struct device *dev)
static void pci_device_remove(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
- struct pci_driver *drv = pci_dev->driver;
+ struct pci_driver *drv = to_pci_driver(pci_dev->dev.driver);
if (drv->remove) {
pm_runtime_get_sync(dev);
@@ -493,12 +493,15 @@ static void pci_device_remove(struct device *dev)
static void pci_device_shutdown(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
- struct pci_driver *drv = pci_dev->driver;
pm_runtime_resume(dev);
- if (drv && drv->shutdown)
- drv->shutdown(pci_dev);
+ if (pci_dev->dev.driver) {
+ struct pci_driver *drv = to_pci_driver(pci_dev->dev.driver);
+
+ if (drv->shutdown)
+ drv->shutdown(pci_dev);
+ }
/*
* If this is a kexec reboot, turn off Bus Master bit on the
@@ -589,22 +592,25 @@ static int pci_pm_reenable_device(struct pci_dev *pci_dev)
static int pci_legacy_suspend(struct device *dev, pm_message_t state)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
- struct pci_driver *drv = pci_dev->driver;
- if (drv && drv->suspend) {
- pci_power_t prev = pci_dev->current_state;
- int error;
+ if (dev->driver) {
+ struct pci_driver *drv = to_pci_driver(dev->driver);
- error = drv->suspend(pci_dev, state);
- suspend_report_result(drv->suspend, error);
- if (error)
- return error;
+ if (drv->suspend) {
+ pci_power_t prev = pci_dev->current_state;
+ int error;
- if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
- && pci_dev->current_state != PCI_UNKNOWN) {
- pci_WARN_ONCE(pci_dev, pci_dev->current_state != prev,
- "PCI PM: Device state not saved by %pS\n",
- drv->suspend);
+ error = drv->suspend(pci_dev, state);
+ suspend_report_result(drv->suspend, error);
+ if (error)
+ return error;
+
+ if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
+ && pci_dev->current_state != PCI_UNKNOWN) {
+ pci_WARN_ONCE(pci_dev, pci_dev->current_state != prev,
+ "PCI PM: Device state not saved by %pS\n",
+ drv->suspend);
+ }
}
}
@@ -630,12 +636,17 @@ static int pci_legacy_suspend_late(struct device *dev, pm_message_t state)
static int pci_legacy_resume(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
- struct pci_driver *drv = pci_dev->driver;
pci_fixup_device(pci_fixup_resume, pci_dev);
- return drv && drv->resume ?
- drv->resume(pci_dev) : pci_pm_reenable_device(pci_dev);
+ if (pci_dev->dev.driver) {
+ struct pci_driver *drv = to_pci_driver(pci_dev->dev.driver);
+
+ if (drv->resume)
+ return drv->resume(pci_dev);
+ }
+
+ return pci_pm_reenable_device(pci_dev);
}
/* Auxiliary functions used by the new power management framework */
@@ -649,8 +660,14 @@ static void pci_pm_default_suspend(struct pci_dev *pci_dev)
static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev)
{
- struct pci_driver *drv = pci_dev->driver;
- bool ret = drv && (drv->suspend || drv->resume);
+ struct pci_driver *drv;
+ bool ret;
+
+ if (!pci_dev->dev.driver)
+ return false;
+
+ drv = to_pci_driver(pci_dev->dev.driver);
+ ret = drv && (drv->suspend || drv->resume);
/*
* Legacy PM support is used by default, so warn if the new framework is
@@ -1242,11 +1259,11 @@ static int pci_pm_runtime_suspend(struct device *dev)
int error;
/*
- * If pci_dev->driver is not set (unbound), we leave the device in D0,
+ * If pci_dev->dev.driver is not set (unbound), we leave the device in D0,
* but it may go to D3cold when the bridge above it runtime suspends.
* Save its config space in case that happens.
*/
- if (!pci_dev->driver) {
+ if (!pci_dev->dev.driver) {
pci_save_state(pci_dev);
return 0;
}
@@ -1303,7 +1320,7 @@ static int pci_pm_runtime_resume(struct device *dev)
*/
pci_restore_standard_config(pci_dev);
- if (!pci_dev->driver)
+ if (!dev->driver)
return 0;
pci_fixup_device(pci_fixup_resume_early, pci_dev);
@@ -1322,14 +1339,13 @@ static int pci_pm_runtime_resume(struct device *dev)
static int pci_pm_runtime_idle(struct device *dev)
{
- struct pci_dev *pci_dev = to_pci_dev(dev);
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
/*
- * If pci_dev->driver is not set (unbound), the device should
+ * If dev->driver is not set (unbound), the device should
* always remain in D0 regardless of the runtime PM status
*/
- if (!pci_dev->driver)
+ if (!dev->driver)
return 0;
if (!pm)
@@ -1436,8 +1452,8 @@ static struct pci_driver pci_compat_driver = {
*/
struct pci_driver *pci_dev_driver(const struct pci_dev *dev)
{
- if (dev->driver)
- return dev->driver;
+ if (dev->dev.driver)
+ return to_pci_driver(dev->dev.driver);
else {
int i;
for (i = 0; i <= PCI_ROM_RESOURCE; i++)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index ce2ab62b64cf..ccecf740de59 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -5089,7 +5089,7 @@ EXPORT_SYMBOL_GPL(pci_dev_unlock);
static void pci_dev_save_and_disable(struct pci_dev *dev)
{
const struct pci_error_handlers *err_handler =
- dev->driver ? dev->driver->err_handler : NULL;
+ dev->dev.driver ? to_pci_driver(dev->dev.driver)->err_handler : NULL;
/*
* dev->driver->err_handler->reset_prepare() is protected against
@@ -5120,7 +5120,7 @@ static void pci_dev_save_and_disable(struct pci_dev *dev)
static void pci_dev_restore(struct pci_dev *dev)
{
const struct pci_error_handlers *err_handler =
- dev->driver ? dev->driver->err_handler : NULL;
+ dev->dev.driver ? to_pci_driver(dev->dev.driver)->err_handler : NULL;
pci_restore_state(dev);
diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c
index b576aa890c76..b314b54f7821 100644
--- a/drivers/pci/pcie/err.c
+++ b/drivers/pci/pcie/err.c
@@ -49,14 +49,15 @@ static int report_error_detected(struct pci_dev *dev,
pci_channel_state_t state,
enum pci_ers_result *result)
{
+ struct pci_driver *pdrv;
pci_ers_result_t vote;
const struct pci_error_handlers *err_handler;
device_lock(&dev->dev);
if (!pci_dev_set_io_state(dev, state) ||
- !dev->driver ||
- !dev->driver->err_handler ||
- !dev->driver->err_handler->error_detected) {
+ !dev->dev.driver ||
+ !(pdrv = to_pci_driver(dev->dev.driver))->err_handler ||
+ !pdrv->err_handler->error_detected) {
/*
* If any device in the subtree does not have an error_detected
* callback, PCI_ERS_RESULT_NO_AER_DRIVER prevents subsequent
@@ -70,7 +71,7 @@ static int report_error_detected(struct pci_dev *dev,
vote = PCI_ERS_RESULT_NONE;
}
} else {
- err_handler = dev->driver->err_handler;
+ err_handler = pdrv->err_handler;
vote = err_handler->error_detected(dev, state);
}
pci_uevent_ers(dev, vote);
@@ -92,15 +93,16 @@ static int report_normal_detected(struct pci_dev *dev, void *data)
static int report_mmio_enabled(struct pci_dev *dev, void *data)
{
pci_ers_result_t vote, *result = data;
+ struct pci_driver *pdrv;
const struct pci_error_handlers *err_handler;
device_lock(&dev->dev);
- if (!dev->driver ||
- !dev->driver->err_handler ||
- !dev->driver->err_handler->mmio_enabled)
+ if (!dev->dev.driver ||
+ !(pdrv = to_pci_driver(dev->dev.driver))->err_handler ||
+ !pdrv->err_handler->mmio_enabled)
goto out;
- err_handler = dev->driver->err_handler;
+ err_handler = pdrv->err_handler;
vote = err_handler->mmio_enabled(dev);
*result = merge_result(*result, vote);
out:
@@ -112,14 +114,15 @@ static int report_slot_reset(struct pci_dev *dev, void *data)
{
pci_ers_result_t vote, *result = data;
const struct pci_error_handlers *err_handler;
+ struct pci_driver *pdrv;
device_lock(&dev->dev);
- if (!dev->driver ||
- !dev->driver->err_handler ||
- !dev->driver->err_handler->slot_reset)
+ if (!dev->dev.driver ||
+ !(pdrv = to_pci_driver(dev->dev.driver))->err_handler ||
+ !pdrv->err_handler->slot_reset)
goto out;
- err_handler = dev->driver->err_handler;
+ err_handler = pdrv->err_handler;
vote = err_handler->slot_reset(dev);
*result = merge_result(*result, vote);
out:
@@ -130,15 +133,16 @@ static int report_slot_reset(struct pci_dev *dev, void *data)
static int report_resume(struct pci_dev *dev, void *data)
{
const struct pci_error_handlers *err_handler;
+ struct pci_driver *pdrv;
device_lock(&dev->dev);
if (!pci_dev_set_io_state(dev, pci_channel_io_normal) ||
- !dev->driver ||
- !dev->driver->err_handler ||
- !dev->driver->err_handler->resume)
+ !dev->dev.driver ||
+ !(pdrv = to_pci_driver(dev->dev.driver))->err_handler ||
+ !pdrv->err_handler->resume)
goto out;
- err_handler = dev->driver->err_handler;
+ err_handler = pdrv->err_handler;
err_handler->resume(dev);
out:
pci_uevent_ers(dev, PCI_ERS_RESULT_RECOVERED);
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index f2d7f70a7a10..73831fb87a1e 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -601,12 +601,12 @@ static pci_ers_result_t pcifront_common_process(int cmd,
result = PCI_ERS_RESULT_NONE;
pcidev = pci_get_domain_bus_and_slot(domain, bus, devfn);
- if (!pcidev || !pcidev->driver) {
+ if (!pcidev || !pcidev->dev.driver) {
dev_err(&pdev->xdev->dev, "device or AER driver is NULL\n");
pci_dev_put(pcidev);
return result;
}
- pdrv = pcidev->driver;
+ pdrv = to_pci_driver(pcidev->dev.driver);
if (pdrv->err_handler && pdrv->err_handler->error_detected) {
pci_dbg(pcidev, "trying to call AER service\n");
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 2c9f25ca8edd..2f4729f4f1e0 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -103,7 +103,7 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
struct xhci_driver_data *driver_data;
const struct pci_device_id *id;
- id = pci_match_id(pdev->driver->id_table, pdev);
+ id = pci_match_id(to_pci_driver(pdev->dev.driver)->id_table, pdev);
if (id && id->driver_data) {
driver_data = (struct xhci_driver_data *)id->driver_data;
--
2.30.2
^ permalink raw reply related
* [PATCH 1/5] powerpc/64s: fix program check interrupt emergency stack path
From: Nicholas Piggin @ 2021-10-04 14:56 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Ganesh Goudar, Nicholas Piggin
In-Reply-To: <20211004145642.1331214-1-npiggin@gmail.com>
Emergency stack path was jumping into a 3: label inside the
__GEN_COMMON_BODY macro for the normal path after it had finished,
rather than jumping over it. By a small miracle this is the correct
place to build up a new interrupt frame with the existing stack
pointer, so things basically worked okay with an added weird looking
700 trap frame on top (which had the wrong ->nip so it didn't decode
bug messages either).
Fix this by avoiding using numeric labels when jumping over non-trivial
macros.
Before:
LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA PowerNV
Modules linked in:
CPU: 0 PID: 88 Comm: sh Not tainted 5.15.0-rc2-00034-ge057cdade6e5 #2637
NIP: 7265677368657265 LR: c00000000006c0c8 CTR: c0000000000097f0
REGS: c0000000fffb3a50 TRAP: 0700 Not tainted
MSR: 9000000000021031 <SF,HV,ME,IR,DR,LE> CR: 00000700 XER: 20040000
CFAR: c0000000000098b0 IRQMASK: 0
GPR00: c00000000006c964 c0000000fffb3cf0 c000000001513800 0000000000000000
GPR04: 0000000048ab0778 0000000042000000 0000000000000000 0000000000001299
GPR08: 000001e447c718ec 0000000022424282 0000000000002710 c00000000006bee8
GPR12: 9000000000009033 c0000000016b0000 00000000000000b0 0000000000000001
GPR16: 0000000000000000 0000000000000002 0000000000000000 0000000000000ff8
GPR20: 0000000000001fff 0000000000000007 0000000000000080 00007fff89d90158
GPR24: 0000000002000000 0000000002000000 0000000000000255 0000000000000300
GPR28: c000000001270000 0000000042000000 0000000048ab0778 c000000080647e80
NIP [7265677368657265] 0x7265677368657265
LR [c00000000006c0c8] ___do_page_fault+0x3f8/0xb10
Call Trace:
[c0000000fffb3cf0] [c00000000000bdac] soft_nmi_common+0x13c/0x1d0 (unreliable)
--- interrupt: 700 at decrementer_common_virt+0xb8/0x230
NIP: c0000000000098b8 LR: c00000000006c0c8 CTR: c0000000000097f0
REGS: c0000000fffb3d60 TRAP: 0700 Not tainted
MSR: 9000000000021031 <SF,HV,ME,IR,DR,LE> CR: 22424282 XER: 20040000
CFAR: c0000000000098b0 IRQMASK: 0
GPR00: c00000000006c964 0000000000002400 c000000001513800 0000000000000000
GPR04: 0000000048ab0778 0000000042000000 0000000000000000 0000000000001299
GPR08: 000001e447c718ec 0000000022424282 0000000000002710 c00000000006bee8
GPR12: 9000000000009033 c0000000016b0000 00000000000000b0 0000000000000001
GPR16: 0000000000000000 0000000000000002 0000000000000000 0000000000000ff8
GPR20: 0000000000001fff 0000000000000007 0000000000000080 00007fff89d90158
GPR24: 0000000002000000 0000000002000000 0000000000000255 0000000000000300
GPR28: c000000001270000 0000000042000000 0000000048ab0778 c000000080647e80
NIP [c0000000000098b8] decrementer_common_virt+0xb8/0x230
LR [c00000000006c0c8] ___do_page_fault+0x3f8/0xb10
--- interrupt: 700
Instruction dump:
XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
---[ end trace 6d28218e0cc3c949 ]---
After:
------------[ cut here ]------------
kernel BUG at arch/powerpc/kernel/exceptions-64s.S:491!
Oops: Exception in kernel mode, sig: 5 [#1]
LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA PowerNV
Modules linked in:
CPU: 0 PID: 88 Comm: login Not tainted 5.15.0-rc2-00034-ge057cdade6e5-dirty #2638
NIP: c0000000000098b8 LR: c00000000006bf04 CTR: c0000000000097f0
REGS: c0000000fffb3d60 TRAP: 0700 Not tainted
MSR: 9000000000021031 <SF,HV,ME,IR,DR,LE> CR: 24482227 XER: 00040000
CFAR: c0000000000098b0 IRQMASK: 0
GPR00: c00000000006bf04 0000000000002400 c000000001513800 c000000001271868
GPR04: 00000000100f0d29 0000000042000000 0000000000000007 0000000000000009
GPR08: 00000000100f0d29 0000000024482227 0000000000002710 c000000000181b3c
GPR12: 9000000000009033 c0000000016b0000 00000000100f0d29 c000000005b22f00
GPR16: 00000000ffff0000 0000000000000001 0000000000000009 00000000100eed90
GPR20: 00000000100eed90 0000000010000000 000000001000a49c 00000000100f1430
GPR24: c000000001271868 0000000002000000 0000000000000215 0000000000000300
GPR28: c000000001271800 0000000042000000 00000000100f0d29 c000000080647860
NIP [c0000000000098b8] decrementer_common_virt+0xb8/0x230
LR [c00000000006bf04] ___do_page_fault+0x234/0xb10
Call Trace:
Instruction dump:
4182000c 39400001 48000008 894d0932 714a0001 39400008 408225fc 718a4000
7c2a0b78 3821fcf0 41c20008 e82d0910 <0981fcf0> f92101a0 f9610170 f9810178
---[ end trace a5dbd1f5ea4ccc51 ]---
Fixes: 0a882e28468f4 ("powerpc/64s/exception: remove bad stack branch")
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/exceptions-64s.S | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 37859e62a8dc..024d9231f88c 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -1665,27 +1665,30 @@ EXC_COMMON_BEGIN(program_check_common)
*/
andi. r10,r12,MSR_PR
- bne 2f /* If userspace, go normal path */
+ bne .Lnormal_stack /* If userspace, go normal path */
andis. r10,r12,(SRR1_PROGTM)@h
- bne 1f /* If TM, emergency */
+ bne .Lemergency_stack /* If TM, emergency */
cmpdi r1,-INT_FRAME_SIZE /* check if r1 is in userspace */
- blt 2f /* normal path if not */
+ blt .Lnormal_stack /* normal path if not */
/* Use the emergency stack */
-1: andi. r10,r12,MSR_PR /* Set CR0 correctly for label */
+.Lemergency_stack:
+ andi. r10,r12,MSR_PR /* Set CR0 correctly for label */
/* 3 in EXCEPTION_PROLOG_COMMON */
mr r10,r1 /* Save r1 */
ld r1,PACAEMERGSP(r13) /* Use emergency stack */
subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */
__ISTACK(program_check)=0
__GEN_COMMON_BODY program_check
- b 3f
-2:
+ b .Ldo_program_check
+
+.Lnormal_stack:
__ISTACK(program_check)=1
__GEN_COMMON_BODY program_check
-3:
+
+.Ldo_program_check:
addi r3,r1,STACK_FRAME_OVERHEAD
bl program_check_exception
REST_NVGPRS(r1) /* instruction emulation may change GPRs */
--
2.23.0
^ permalink raw reply related
* [PATCH 0/5] powerpc: various interrupt handling fixes
From: Nicholas Piggin @ 2021-10-04 14:56 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Ganesh Goudar, Nicholas Piggin
This fixes a number of bugs found mostly looking at a MCE handler issue,
which should be fixed in patch 5 of the series, previous attempt here
which Ganesh found to be wrong.
https://patchwork.ozlabs.org/project/linuxppc-dev/patch/20210922020247.209409-1-npiggin@gmail.com/
I didn't increment to patch v2 because it's a different approach (so I
gave it a different title).
Thanks,
Nick
Nicholas Piggin (5):
powerpc/64s: fix program check interrupt emergency stack path
powerpc/traps: do not enable irqs in _exception
powerpc/64: warn if local irqs are enabled in NMI or hardirq context
powerpc/64/interrupt: Reconcile soft-mask state in NMI and fix false
BUG
powerpc/64s: Fix unrecoverable MCE calling async handler from NMI
arch/powerpc/include/asm/interrupt.h | 18 ++++++------
arch/powerpc/kernel/exceptions-64s.S | 25 ++++++++++------
arch/powerpc/kernel/irq.c | 6 ++++
arch/powerpc/kernel/traps.c | 43 +++++++++++++++++-----------
4 files changed, 59 insertions(+), 33 deletions(-)
--
2.23.0
^ permalink raw reply
* [PATCH 2/5] powerpc/traps: do not enable irqs in _exception
From: Nicholas Piggin @ 2021-10-04 14:56 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Ganesh Goudar, Nicholas Piggin
In-Reply-To: <20211004145642.1331214-1-npiggin@gmail.com>
_exception can be called by machine check handlers when the MCE hits
user code (e.g., pseries and powernv). This will enable local irqs
because, which is a dicey thing to do in NMI or hard irq context.
This seemed to worked out okay because a userspace MCE can basically be
treated like a synchronous interrupt (after async / imprecise MCEs are
filtered out). Since NMI and hard irq handlers have started growing
nmi_enter / irq_enter, and more irq state sanity checks, this has
started to cause problems (or at least trigger warnings).
The Fixes tag to the commit which introduced this rather than try to
work out exactly which commit was the first that could possibly cause a
problem because that may be difficult to prove.
Fixes: 9f2f79e3a3c1 ("powerpc: Disable interrupts in 64-bit kernel FP and vector faults")
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/traps.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index aac8c0412ff9..e453b666613b 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -340,10 +340,16 @@ static bool exception_common(int signr, struct pt_regs *regs, int code,
return false;
}
- show_signal_msg(signr, regs, code, addr);
+ /*
+ * Must not enable interrupts even for user-mode exception, because
+ * this can be called from machine check, which may be a NMI or IRQ
+ * which don't like interrupts being enabled. Could check for
+ * in_hardirq || in_nmi perhaps, but there doesn't seem to be a good
+ * reason why _exception() should enable irqs for an exception handler,
+ * the handlers themselves do that directly.
+ */
- if (arch_irqs_disabled())
- interrupt_cond_local_irq_enable(regs);
+ show_signal_msg(signr, regs, code, addr);
current->thread.trap_nr = code;
--
2.23.0
^ permalink raw reply related
* [PATCH 3/5] powerpc/64: warn if local irqs are enabled in NMI or hardirq context
From: Nicholas Piggin @ 2021-10-04 14:56 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Ganesh Goudar, Nicholas Piggin
In-Reply-To: <20211004145642.1331214-1-npiggin@gmail.com>
This can help catch bugs such as the one fixed by the previous change
to prevent _exception() from enabling irqs.
ppc32 could have a similar warning but it has no good config option to
debug this stuff (the test may be overkill to add for production
kernels).
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/irq.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 551b653228c4..c4f1d6b7d992 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -229,6 +229,9 @@ notrace void arch_local_irq_restore(unsigned long mask)
return;
}
+ if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
+ WARN_ON_ONCE(in_nmi() || in_hardirq());
+
/*
* After the stb, interrupts are unmasked and there are no interrupts
* pending replay. The restart sequence makes this atomic with
@@ -321,6 +324,9 @@ notrace void arch_local_irq_restore(unsigned long mask)
if (mask)
return;
+ if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
+ WARN_ON_ONCE(in_nmi() || in_hardirq());
+
/*
* From this point onward, we can take interrupts, preempt,
* etc... unless we got hard-disabled. We check if an event
--
2.23.0
^ permalink raw reply related
* [PATCH 4/5] powerpc/64/interrupt: Reconcile soft-mask state in NMI and fix false BUG
From: Nicholas Piggin @ 2021-10-04 14:56 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Ganesh Goudar, Nicholas Piggin
In-Reply-To: <20211004145642.1331214-1-npiggin@gmail.com>
If a NMI hits early in an interrupt handler before the irq soft-mask
state is reconciled, that can cause a false-positive BUG with a
CONFIG_PPC_IRQ_SOFT_MASK_DEBUG assertion.
Remove that assertion and instead check the case that if regs->msr has
EE clear, then regs->softe should be marked as disabled so the irq state
looks correct to NMI handlers, the same as how it's fixed up in the
case it was implicit soft-masked.
This doesn't fix a known problem -- the change that was fixed by commit
4ec5feec1ad02 ("powerpc/64s: Make NMI record implicitly soft-masked code
as irqs disabled") was the addition of a warning in the soft-nmi
watchdog interrupt which can never actually fire when MSR[EE]=0. However
it may be important if NMI handlers grow more code, and it's less
surprising to anything using 'regs' - (I tripped over this when working
in the area).
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/include/asm/interrupt.h | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h
index 6b800d3e2681..b894b7169706 100644
--- a/arch/powerpc/include/asm/interrupt.h
+++ b/arch/powerpc/include/asm/interrupt.h
@@ -265,13 +265,16 @@ static inline void interrupt_nmi_enter_prepare(struct pt_regs *regs, struct inte
local_paca->irq_soft_mask = IRQS_ALL_DISABLED;
local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
- if (is_implicit_soft_masked(regs)) {
- // Adjust regs->softe soft implicit soft-mask, so
- // arch_irq_disabled_regs(regs) behaves as expected.
+ if (!(regs->msr & MSR_EE) || is_implicit_soft_masked(regs)) {
+ /*
+ * Adjust regs->softe to be soft-masked if it had not been
+ * reconcied (e.g., interrupt entry with MSR[EE]=0 but softe
+ * not yet set disabled), or if it was in an implicit soft
+ * masked state. This makes arch_irq_disabled_regs(regs)
+ * behave as expected.
+ */
regs->softe = IRQS_ALL_DISABLED;
}
- if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
- BUG_ON(!arch_irq_disabled_regs(regs) && !(regs->msr & MSR_EE));
/* Don't do any per-CPU operations until interrupt state is fixed */
--
2.23.0
^ permalink raw reply related
* [PATCH 5/5] powerpc/64s: Fix unrecoverable MCE calling async handler from NMI
From: Nicholas Piggin @ 2021-10-04 14:56 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Ganesh Goudar, Nicholas Piggin
In-Reply-To: <20211004145642.1331214-1-npiggin@gmail.com>
The machine check handler is not considered NMI on 64s. The early
handler is the true NMI handler, and then it schedules the
machine_check_exception handler to run when interrupts are enabled.
This works fine except the case of an unrecoverable MCE, where the true
NMI is taken when MSR[RI] is clear, it can not recover, so it calls
machine_check_exception directly so something might be done about it.
Calling an async handler from NMI context can result in irq state and
other things getting corrupted. This can also trigger the BUG at
arch/powerpc/include/asm/interrupt.h:168
BUG_ON(!arch_irq_disabled_regs(regs) && !(regs->msr & MSR_EE));
Fix this by making an _async version of the handler which is called
in the normal case, and a NMI version that is called for unrecoverable
interrupts.
Fixes: 2b43dd7653cc ("powerpc/64: enable MSR[EE] in irq replay pt_regs")
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/include/asm/interrupt.h | 5 ++---
arch/powerpc/kernel/exceptions-64s.S | 8 +++++--
arch/powerpc/kernel/traps.c | 31 ++++++++++++++++------------
3 files changed, 26 insertions(+), 18 deletions(-)
diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h
index b894b7169706..a1d238255f07 100644
--- a/arch/powerpc/include/asm/interrupt.h
+++ b/arch/powerpc/include/asm/interrupt.h
@@ -528,10 +528,9 @@ static __always_inline long ____##func(struct pt_regs *regs)
/* kernel/traps.c */
DECLARE_INTERRUPT_HANDLER_NMI(system_reset_exception);
#ifdef CONFIG_PPC_BOOK3S_64
-DECLARE_INTERRUPT_HANDLER_ASYNC(machine_check_exception);
-#else
-DECLARE_INTERRUPT_HANDLER_NMI(machine_check_exception);
+DECLARE_INTERRUPT_HANDLER_ASYNC(machine_check_exception_async);
#endif
+DECLARE_INTERRUPT_HANDLER_NMI(machine_check_exception);
DECLARE_INTERRUPT_HANDLER(SMIException);
DECLARE_INTERRUPT_HANDLER(handle_hmi_exception);
DECLARE_INTERRUPT_HANDLER(unknown_exception);
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 024d9231f88c..eaf1f72131a1 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -1243,7 +1243,7 @@ EXC_COMMON_BEGIN(machine_check_common)
li r10,MSR_RI
mtmsrd r10,1
addi r3,r1,STACK_FRAME_OVERHEAD
- bl machine_check_exception
+ bl machine_check_exception_async
b interrupt_return_srr
@@ -1303,7 +1303,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
subi r12,r12,1
sth r12,PACA_IN_MCE(r13)
- /* Invoke machine_check_exception to print MCE event and panic. */
+ /*
+ * Invoke machine_check_exception to print MCE event and panic.
+ * This is the NMI version of the handler because we are called from
+ * the early handler which is a true NMI.
+ */
addi r3,r1,STACK_FRAME_OVERHEAD
bl machine_check_exception
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index e453b666613b..11741703d26e 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -796,24 +796,22 @@ void die_mce(const char *str, struct pt_regs *regs, long err)
* do_exit() checks for in_interrupt() and panics in that case, so
* exit the irq/nmi before calling die.
*/
- if (IS_ENABLED(CONFIG_PPC_BOOK3S_64))
- irq_exit();
- else
+ if (in_nmi())
nmi_exit();
+ else
+ irq_exit();
die(str, regs, err);
}
/*
- * BOOK3S_64 does not call this handler as a non-maskable interrupt
+ * BOOK3S_64 does not usually call this handler as a non-maskable interrupt
* (it uses its own early real-mode handler to handle the MCE proper
* and then raises irq_work to call this handler when interrupts are
- * enabled).
+ * enabled). The only time when this is not true is if the early handler
+ * is unrecoverable, then it does call this directly to try to get a
+ * message out.
*/
-#ifdef CONFIG_PPC_BOOK3S_64
-DEFINE_INTERRUPT_HANDLER_ASYNC(machine_check_exception)
-#else
-DEFINE_INTERRUPT_HANDLER_NMI(machine_check_exception)
-#endif
+static void __machine_check_exception(struct pt_regs *regs)
{
int recover = 0;
@@ -847,12 +845,19 @@ DEFINE_INTERRUPT_HANDLER_NMI(machine_check_exception)
/* Must die if the interrupt is not recoverable */
if (regs_is_unrecoverable(regs))
die_mce("Unrecoverable Machine check", regs, SIGBUS);
+}
#ifdef CONFIG_PPC_BOOK3S_64
- return;
-#else
- return 0;
+DEFINE_INTERRUPT_HANDLER_ASYNC(machine_check_exception_async)
+{
+ __machine_check_exception(regs);
+}
#endif
+DEFINE_INTERRUPT_HANDLER_NMI(machine_check_exception)
+{
+ __machine_check_exception(regs);
+
+ return 0;
}
DEFINE_INTERRUPT_HANDLER(SMIException) /* async? */
--
2.23.0
^ permalink raw reply related
* [PATCH] KVM: PPC: Book3S HV: H_ENTER filter out reserved HPTE[B] value
From: Nicholas Piggin @ 2021-10-04 14:57 UTC (permalink / raw)
To: kvm-ppc, linuxppc-dev; +Cc: Nicholas Piggin
The HPTE B field is a 2-bit field with values 0b10 and 0b11 reserved.
This field is also taken from the HPTE and used when KVM executes
TLBIEs to set the B field of those instructions.
Disallow the guest setting B to a reserved value with H_ENTER by
rejecting it. This is the same approach already taken for rejecting
reserved (unsupported) LLP values. This prevents the guest from being
able to induce the host to execute TLBIE with reserved values, which
is not known to be a problem with current processors but in theory it
could prevent the TLBIE from working correctly in a future processor.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/include/asm/kvm_book3s_64.h | 4 ++++
arch/powerpc/kvm/book3s_hv_rm_mmu.c | 9 +++++++++
2 files changed, 13 insertions(+)
diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h
index 19b6942c6969..fff391b9b97b 100644
--- a/arch/powerpc/include/asm/kvm_book3s_64.h
+++ b/arch/powerpc/include/asm/kvm_book3s_64.h
@@ -378,6 +378,10 @@ static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r,
rb |= 1; /* L field */
rb |= r & 0xff000 & ((1ul << a_pgshift) - 1); /* LP field */
}
+ /*
+ * This sets both bits of the B field in the PTE. 0b1x values are
+ * reserved, but those will have been filtered by kvmppc_do_h_enter.
+ */
rb |= (v >> HPTE_V_SSIZE_SHIFT) << 8; /* B field */
return rb;
}
diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
index 632b2545072b..2c1f3c6e72d1 100644
--- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
+++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
@@ -207,6 +207,15 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags,
if (kvm_is_radix(kvm))
return H_FUNCTION;
+ /*
+ * The HPTE gets used by compute_tlbie_rb() to set TLBIE bits, so
+ * these functions should work together -- must ensure a guest can not
+ * cause problems with the TLBIE that KVM executes.
+ */
+ if ((pteh >> HPTE_V_SSIZE_SHIFT) & 0x2) {
+ /* B=0b1x is a reserved value, disallow it. */
+ return H_PARAMETER;
+ }
psize = kvmppc_actual_pgsz(pteh, ptel);
if (!psize)
return H_PARAMETER;
--
2.23.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox