* Re: [PATCH kernel] powerpc/iommu: Report the correct most efficient DMA mask for PCI devices
From: Michael Ellerman @ 2021-10-01 14:36 UTC (permalink / raw)
To: Alexey Kardashevskiy, linuxppc-dev; +Cc: Carol L Soto, iommu, Christoph Hellwig
In-Reply-To: <20210930034454.95794-1-aik@ozlabs.ru>
On Thu, 30 Sep 2021 13:44:54 +1000, Alexey Kardashevskiy wrote:
> According to dma-api.rst, the dma_get_required_mask() helper should return
> "the mask that the platform requires to operate efficiently". Which in
> the case of PPC64 means the bypass mask and not a mask from an IOMMU table
> which is shorter and slower to use due to map/unmap operations (especially
> expensive on "pseries").
>
> However the existing implementation ignores the possibility of bypassing
> and returns the IOMMU table mask on the pseries platform which makes some
> drivers (mpt3sas is one example) choose 32bit DMA even though bypass is
> supported. The powernv platform sort of handles it by having a bigger
> default window with a mask >=40 but it only works as drivers choose
> 63/64bit if the required mask is >32 which is rather pointless.
>
> [...]
Applied to powerpc/fixes.
[1/1] powerpc/iommu: Report the correct most efficient DMA mask for PCI devices
https://git.kernel.org/powerpc/c/23c216b335d1fbd716076e8263b54a714ea3cf0e
cheers
^ permalink raw reply
* Re: [PATCH 1/5] dt-bindings: memory: fsl: convert ifc binding to yaml schema
From: Li Yang @ 2021-10-01 16:17 UTC (permalink / raw)
To: Krzysztof Kozlowski
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: <db751cb1-9107-3857-7576-644bde4c28e5@canonical.com>
On Fri, Oct 1, 2021 at 5:01 AM Krzysztof Kozlowski
<krzysztof.kozlowski@canonical.com> wrote:
>
> On 01/10/2021 02:09, Li Yang wrote:
> > Convert the txt binding to yaml format and add description. Drop the
> > "simple-bus" compatible string from the example and not allowed by the
> > binding any more. This will help to enforce the correct probe order
> > between parent device and child devices, but will require the ifc driver
> > to probe the child devices to work properly.
> >
> > Signed-off-by: Li Yang <leoyang.li@nxp.com>
> > ---
> > updates from previous submission:
> > - Drop "simple-bus" from binding and only "fsl,ifc" as compatible
> > - Fix one identiation problem of "reg"
> > - Add type restriction to "little-endian" property
> >
> > .../bindings/memory-controllers/fsl/ifc.txt | 82 -----------
> > .../bindings/memory-controllers/fsl/ifc.yaml | 137 ++++++++++++++++++
> > 2 files changed, 137 insertions(+), 82 deletions(-)
> > delete mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/ifc.txt
> > create mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/ifc.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/memory-controllers/fsl/ifc.txt b/Documentation/devicetree/bindings/memory-controllers/fsl/ifc.txt
> > deleted file mode 100644
> > index 89427b018ba7..000000000000
> > --- a/Documentation/devicetree/bindings/memory-controllers/fsl/ifc.txt
> > +++ /dev/null
> > @@ -1,82 +0,0 @@
> > -Integrated Flash Controller
> > -
> > -Properties:
> > -- name : Should be ifc
> > -- compatible : should contain "fsl,ifc". The version of the integrated
> > - flash controller can be found in the IFC_REV register at
> > - offset zero.
> > -
> > -- #address-cells : Should be either two or three. The first cell is the
> > - chipselect number, and the remaining cells are the
> > - offset into the chipselect.
> > -- #size-cells : Either one or two, depending on how large each chipselect
> > - can be.
> > -- reg : Offset and length of the register set for the device
> > -- interrupts: 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 : If this property is absent, the big-endian mode will
> > - be in use as default for registers.
> > -
> > -- ranges : Each range corresponds to a single chipselect, and covers
> > - the entire access window as configured.
> > -
> > -Child device nodes describe the devices connected to IFC such as NOR (e.g.
> > -cfi-flash) and NAND (fsl,ifc-nand). There might be board specific devices
> > -like FPGAs, CPLDs, etc.
> > -
> > -Example:
> > -
> > - ifc@ffe1e000 {
> > - compatible = "fsl,ifc", "simple-bus";
> > - #address-cells = <2>;
> > - #size-cells = <1>;
> > - reg = <0x0 0xffe1e000 0 0x2000>;
> > - interrupts = <16 2 19 2>;
> > - little-endian;
> > -
> > - /* NOR, NAND Flashes and CPLD on board */
> > - ranges = <0x0 0x0 0x0 0xee000000 0x02000000
> > - 0x1 0x0 0x0 0xffa00000 0x00010000
> > - 0x3 0x0 0x0 0xffb00000 0x00020000>;
> > -
> > - flash@0,0 {
> > - #address-cells = <1>;
> > - #size-cells = <1>;
> > - compatible = "cfi-flash";
> > - reg = <0x0 0x0 0x2000000>;
> > - bank-width = <2>;
> > - device-width = <1>;
> > -
> > - partition@0 {
> > - /* 32MB for user data */
> > - reg = <0x0 0x02000000>;
> > - label = "NOR Data";
> > - };
> > - };
> > -
> > - flash@1,0 {
> > - #address-cells = <1>;
> > - #size-cells = <1>;
> > - compatible = "fsl,ifc-nand";
> > - reg = <0x1 0x0 0x10000>;
> > -
> > - partition@0 {
> > - /* This location must not be altered */
> > - /* 1MB for u-boot Bootloader Image */
> > - reg = <0x0 0x00100000>;
> > - label = "NAND U-Boot Image";
> > - read-only;
> > - };
> > - };
> > -
> > - cpld@3,0 {
> > - #address-cells = <1>;
> > - #size-cells = <1>;
> > - compatible = "fsl,p1010rdb-cpld";
> > - reg = <0x3 0x0 0x000001f>;
> > - };
> > - };
> > diff --git a/Documentation/devicetree/bindings/memory-controllers/fsl/ifc.yaml b/Documentation/devicetree/bindings/memory-controllers/fsl/ifc.yaml
> > new file mode 100644
> > index 000000000000..19871ce39fe3
>
> Thanks for the patch.
>
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/memory-controllers/fsl/ifc.yaml
> > @@ -0,0 +1,137 @@
> > +# SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
>
> Checkpatch should scream here. If it doesn't, maybe you work on some old
> tree, which would also explain why you send it to my old address (not
> the one from get_maintainers). Please use both checkpatch and
> get_maintainers.
>
> You basically relicense bindings from GPL-2.0 only to new license,
> including GPL-3.0.
Ok. Will update the license.
>
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/memory-controllers/fsl/ifc.yaml#
>
> File name should be "fsl,ifc.yaml"
Ok. But probably it is a little bit redundant as the upper level
folder also has fsl.
>
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: FSL/NXP Integrated Flash Controller
> > +
> > +maintainers:
> > + - Li Yang <leoyang.li@nxp.com>
> > +
> > +description: |
> > + NXP's integrated flash controller (IFC) is an advanced version of the
> > + enhanced local bus controller which includes similar programming and signal
> > + interfaces with an extended feature set. The IFC provides access to multiple
> > + external memory types, such as NAND flash (SLC and MLC), NOR flash, EPROM,
> > + SRAM and other memories where address and data are shared on a bus.
> > +
> > +properties:
> > + $nodename:
> > + pattern: "^ifc@[0-9a-f]+$"
>
> Nodes should be generic, so this looks like "memory-controller".
Ok.
>
> > +
> > + compatible:
> > + const: fsl,ifc
> > +
> > + "#address-cells":
> > + enum: [2, 3]
> > + description: |
> > + Should be either two or three. The first cell is the chipselect
> > + number, and the remaining cells are the offset into the chipselect.
> > +
> > + "#size-cells":
> > + enum: [1, 2]
> > + description: |
> > + Either one or two, depending on how large each chipselect can be.
> > +
> > + reg:
> > + maxItems: 1
> > + description: |
> > + Offset and length of the register set for the device.
>
> Skip the description, it's obvious.
Ok.
>
> > +
> > + 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?
>
>
> Best regards,
> Krzysztof
^ permalink raw reply
* Re: [PATCH 1/5] dt-bindings: memory: fsl: convert ifc binding to yaml schema
From: Li Yang @ 2021-10-01 16:29 UTC (permalink / raw)
To: Rob Herring
Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
linuxppc-dev, lkml, Krzysztof Kozlowski, Rob Herring, Shawn Guo,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <1633094217.843390.3666440.nullmailer@robh.at.kernel.org>
On Fri, Oct 1, 2021 at 8:18 AM Rob Herring <robh@kernel.org> wrote:
>
> On Thu, 30 Sep 2021 19:09:20 -0500, Li Yang wrote:
> > Convert the txt binding to yaml format and add description. Drop the
> > "simple-bus" compatible string from the example and not allowed by the
> > binding any more. This will help to enforce the correct probe order
> > between parent device and child devices, but will require the ifc driver
> > to probe the child devices to work properly.
> >
> > Signed-off-by: Li Yang <leoyang.li@nxp.com>
> > ---
> > updates from previous submission:
> > - Drop "simple-bus" from binding and only "fsl,ifc" as compatible
> > - Fix one identiation problem of "reg"
> > - Add type restriction to "little-endian" property
> >
> > .../bindings/memory-controllers/fsl/ifc.txt | 82 -----------
> > .../bindings/memory-controllers/fsl/ifc.yaml | 137 ++++++++++++++++++
> > 2 files changed, 137 insertions(+), 82 deletions(-)
> > delete mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/ifc.txt
> > create mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/ifc.yaml
> >
>
> My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
> on your patch (DT_CHECKER_FLAGS is new in v5.13):
>
> yamllint warnings/errors:
>
> dtschema/dtc warnings/errors:
> Documentation/devicetree/bindings/memory-controllers/fsl/ifc.example.dt.yaml:0:0: /example-0/soc/ifc@ffe1e000/flash@1,0: failed to match any schema with compatible: ['fsl,ifc-nand']
> Documentation/devicetree/bindings/memory-controllers/fsl/ifc.example.dt.yaml:0:0: /example-0/soc/ifc@ffe1e000/cpld@3,0: failed to match any schema with compatible: ['fsl,p1010rdb-cpld']
These are defined in other bindings, but unfortunately they are not
converted to yaml format yet.
>
> doc reference errors (make refcheckdocs):
>
> See https://patchwork.ozlabs.org/patch/1535102
>
> This check can fail if there are any dependencies. The base for a patch
> series is generally the most recent rc1.
>
> If you already ran 'make dt_binding_check' and didn't see the above
> error(s), then make sure 'yamllint' is installed and dt-schema is up to
> date:
>
> pip3 install dtschema --upgrade
>
> Please check and re-submit.
>
^ permalink raw reply
* Re: [PATCH 1/5] dt-bindings: memory: fsl: convert ifc binding to yaml schema
From: Rob Herring @ 2021-10-01 16:35 UTC (permalink / raw)
To: Li Yang
Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
linuxppc-dev, lkml, Krzysztof Kozlowski, Shawn Guo,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <CADRPPNQBR63pS60nmfUQx02GbBoWEbgroU5Zw-iY62TodmB91Q@mail.gmail.com>
On Fri, Oct 1, 2021 at 11:29 AM Li Yang <leoyang.li@nxp.com> wrote:
>
> On Fri, Oct 1, 2021 at 8:18 AM Rob Herring <robh@kernel.org> wrote:
> >
> > On Thu, 30 Sep 2021 19:09:20 -0500, Li Yang wrote:
> > > Convert the txt binding to yaml format and add description. Drop the
> > > "simple-bus" compatible string from the example and not allowed by the
> > > binding any more. This will help to enforce the correct probe order
> > > between parent device and child devices, but will require the ifc driver
> > > to probe the child devices to work properly.
> > >
> > > Signed-off-by: Li Yang <leoyang.li@nxp.com>
> > > ---
> > > updates from previous submission:
> > > - Drop "simple-bus" from binding and only "fsl,ifc" as compatible
> > > - Fix one identiation problem of "reg"
> > > - Add type restriction to "little-endian" property
> > >
> > > .../bindings/memory-controllers/fsl/ifc.txt | 82 -----------
> > > .../bindings/memory-controllers/fsl/ifc.yaml | 137 ++++++++++++++++++
> > > 2 files changed, 137 insertions(+), 82 deletions(-)
> > > delete mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/ifc.txt
> > > create mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/ifc.yaml
> > >
> >
> > My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
> > on your patch (DT_CHECKER_FLAGS is new in v5.13):
> >
> > yamllint warnings/errors:
> >
> > dtschema/dtc warnings/errors:
> > Documentation/devicetree/bindings/memory-controllers/fsl/ifc.example.dt.yaml:0:0: /example-0/soc/ifc@ffe1e000/flash@1,0: failed to match any schema with compatible: ['fsl,ifc-nand']
> > Documentation/devicetree/bindings/memory-controllers/fsl/ifc.example.dt.yaml:0:0: /example-0/soc/ifc@ffe1e000/cpld@3,0: failed to match any schema with compatible: ['fsl,p1010rdb-cpld']
>
> These are defined in other bindings, but unfortunately they are not
> converted to yaml format yet.
Yes, I know. I'm trying to turn on this check by default and adding
more cases here doesn't help. And often, when those other bindings get
converted, it's the example here that has errors and has to get fixed.
So either convert those bindings too or drop them from the example.
Rob
^ permalink raw reply
* Re: [PATCH v5 6/6] sched/fair: Consider SMT in ASYM_PACKING load balance
From: Ricardo Neri @ 2021-10-01 17:43 UTC (permalink / raw)
To: Vincent Guittot
Cc: Juri Lelli, Rafael J . Wysocki, Srikar Dronamraju,
Ravi V. Shankar, Peter Zijlstra (Intel), Ricardo Neri, Ben Segall,
Srinivas Pandruvada, Joel Fernandes (Google), Ingo Molnar,
Aubrey Li, Steven Rostedt, Mel Gorman, Len Brown, linuxppc-dev,
Nicholas Piggin, Aubrey Li, Dietmar Eggemann, Tim Chen,
kernelci-results@groups.io, Quentin Perret, Guillaume Tucker,
linux-kernel, Daniel Bristot de Oliveira
In-Reply-To: <CAKfTPtD1xE0amjCSkgczBjN=KbdVhVdK=6wiP=P+ynfGojky=Q@mail.gmail.com>
On Fri, Oct 01, 2021 at 12:25:42PM +0200, Vincent Guittot wrote:
> Hi Guillaume,
>
> This patch and the patchset which includes this patch only impacts
> systems with hyperthreading which is not the case of rk3328-rock64
> AFAICT. So there is no reason that this code is used by the board. The
> only impact should be an increase of the binary for this platform.
> Could it be that it reached a limit ?
>
> Regards,
> Vincent
>
> On Fri, 1 Oct 2021 at 11:33, Guillaume Tucker
> <guillaume.tucker@collabora.com> wrote:
> >
> > Hi Ricardo,
> >
> > Please see the bisection report below about a boot failure on
> > rk3288-rock64.
> >
> > Reports aren't automatically sent to the public while we're
> > trialing new bisection features on kernelci.org but this one
> > looks valid.
> >
> > Some more details can be found here:
> >
> > https://linux.kernelci.org/test/case/id/6155a4b0836c79a98f99a31d/
> >
> > It looks like some i.MX arm64 platforms also regressed with
> > next-20210920 although it hasn't been verified yet whether that's
> > due to the same commit:
> >
> > https://linux.kernelci.org/test/job/next/branch/master/kernel/next-20210930/plan/baseline/
> >
> > The x86 platforms don't seem to be impacted though.
> >
> > Please let us know if you need help debugging the issue or if you
> > have a fix to try.
Hi Guillaume,
I accessed the bug report above. It does not seem to include any kernel
log or crash. Maybe it hangs very early at boot? As Vicent mention, this
code is specific to hyperthreading. Furthermore, for this code path to
be executed the scheduling domains must have the SD_ASYM_PACKING flag.
AFAIK, only powerpc and x86 use this flag. Also, by the time this code
is executed, we should be past early boot. At least some messages should
have been printed to the kernel console.
Maybe Vincent's idea on the binary size is the issue?
Thanks and BR,
Ricardo
> >
> > Best wishes,
> > Guillaume
> >
> >
> > GitHub: https://github.com/kernelci/kernelci-project/issues/65
> >
> > -------------------------------------------------------------------------------
> >
> >
> > * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
> > * This automated bisection report was sent to you on the basis *
> > * that you may be involved with the breaking commit it has *
> > * found. No manual investigation has been done to verify it, *
> > * and the root cause of the problem may be somewhere else. *
> > * *
> > * If you do send a fix, please include this trailer: *
> > * Reported-by: "kernelci.org bot" <bot@kernelci.org> *
> > * *
> > * Hope this helps! *
> > * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
> >
> > next/master bisection: baseline.login on rk3328-rock64
> >
> > Summary:
> > Start: 2d02a18f75fc Add linux-next specific files for 20210929
> > Plain log: https://storage.kernelci.org/next/master/next-20210929/arm64/defconfig+CONFIG_RANDOMIZE_BASE=y/gcc-8/lab-baylibre/baseline-rk3328-rock64.txt
> > HTML log: https://storage.kernelci.org/next/master/next-20210929/arm64/defconfig+CONFIG_RANDOMIZE_BASE=y/gcc-8/lab-baylibre/baseline-rk3328-rock64.html
> > Result: eac6f3841f1d sched/fair: Consider SMT in ASYM_PACKING load balance
> >
> > Checks:
> > revert: PASS
> > verify: PASS
> >
> > Parameters:
> > Tree: next
> > URL: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
> > Branch: master
> > Target: rk3328-rock64
> > CPU arch: arm64
> > Lab: lab-baylibre
> > Compiler: gcc-8
> > Config: defconfig+CONFIG_RANDOMIZE_BASE=y
> > Test case: baseline.login
> >
> > Breaking commit found:
> >
> > -------------------------------------------------------------------------------
> > commit eac6f3841f1dac7b6f43002056b63f44cc1f1543
> > Author: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
> > Date: Fri Sep 10 18:18:19 2021 -0700
> >
> > sched/fair: Consider SMT in ASYM_PACKING load balance
> >
> >
> > On 11/09/2021 03:18, Ricardo Neri wrote:
> > > When deciding to pull tasks in ASYM_PACKING, it is necessary not only to
> > > check for the idle state of the destination CPU, dst_cpu, but also of
> > > its SMT siblings.
> > >
> > > If dst_cpu is idle but its SMT siblings are busy, performance suffers
> > > if it pulls tasks from a medium priority CPU that does not have SMT
> > > siblings.
> > >
> > > Implement asym_smt_can_pull_tasks() to inspect the state of the SMT
> > > siblings of both dst_cpu and the CPUs in the candidate busiest group.
> > >
> > > Cc: Aubrey Li <aubrey.li@intel.com>
> > > Cc: Ben Segall <bsegall@google.com>
> > > Cc: Daniel Bristot de Oliveira <bristot@redhat.com>
> > > Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
> > > Cc: Mel Gorman <mgorman@suse.de>
> > > Cc: Quentin Perret <qperret@google.com>
> > > Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > > Cc: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
> > > Cc: Steven Rostedt <rostedt@goodmis.org>
> > > Cc: Tim Chen <tim.c.chen@linux.intel.com>
> > > Reviewed-by: Joel Fernandes (Google) <joel@joelfernandes.org>
> > > Reviewed-by: Len Brown <len.brown@intel.com>
> > > Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
> > > ---
> > > Changes since v4:
> > > * Use sg_lb_stats::sum_nr_running the idle state of a scheduling group.
> > > (Vincent, Peter)
> > > * Do not even idle CPUs in asym_smt_can_pull_tasks(). (Vincent)
> > > * Updated function documentation and corrected a typo.
> > >
> > > Changes since v3:
> > > * Removed the arch_asym_check_smt_siblings() hook. Discussions with the
> > > powerpc folks showed that this patch should not impact them. Also, more
> > > recent powerpc processor no longer use asym_packing. (PeterZ)
> > > * Removed unnecessary local variable in asym_can_pull_tasks(). (Dietmar)
> > > * Removed unnecessary check for local CPUs when the local group has zero
> > > utilization. (Joel)
> > > * Renamed asym_can_pull_tasks() as asym_smt_can_pull_tasks() to reflect
> > > the fact that it deals with SMT cases.
> > > * Made asym_smt_can_pull_tasks() return false for !CONFIG_SCHED_SMT so
> > > that callers can deal with non-SMT cases.
> > >
> > > Changes since v2:
> > > * Reworded the commit message to reflect updates in code.
> > > * Corrected misrepresentation of dst_cpu as the CPU doing the load
> > > balancing. (PeterZ)
> > > * Removed call to arch_asym_check_smt_siblings() as it is now called in
> > > sched_asym().
> > >
> > > Changes since v1:
> > > * Don't bailout in update_sd_pick_busiest() if dst_cpu cannot pull
> > > tasks. Instead, reclassify the candidate busiest group, as it
> > > may still be selected. (PeterZ)
> > > * Avoid an expensive and unnecessary call to cpumask_weight() when
> > > determining if a sched_group is comprised of SMT siblings.
> > > (PeterZ).
> > > ---
> > > kernel/sched/fair.c | 94 +++++++++++++++++++++++++++++++++++++++++++++
> > > 1 file changed, 94 insertions(+)
> > >
> > > diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> > > index 26db017c14a3..8d763dd0174b 100644
> > > --- a/kernel/sched/fair.c
> > > +++ b/kernel/sched/fair.c
> > > @@ -8597,10 +8597,98 @@ group_type group_classify(unsigned int imbalance_pct,
> > > return group_has_spare;
> > > }
> > >
> > > +/**
> > > + * asym_smt_can_pull_tasks - Check whether the load balancing CPU can pull tasks
> > > + * @dst_cpu: Destination CPU of the load balancing
> > > + * @sds: Load-balancing data with statistics of the local group
> > > + * @sgs: Load-balancing statistics of the candidate busiest group
> > > + * @sg: The candidate busiest group
> > > + *
> > > + * Check the state of the SMT siblings of both @sds::local and @sg and decide
> > > + * if @dst_cpu can pull tasks.
> > > + *
> > > + * If @dst_cpu does not have SMT siblings, it can pull tasks if two or more of
> > > + * the SMT siblings of @sg are busy. If only one CPU in @sg is busy, pull tasks
> > > + * only if @dst_cpu has higher priority.
> > > + *
> > > + * If both @dst_cpu and @sg have SMT siblings, and @sg has exactly one more
> > > + * busy CPU than @sds::local, let @dst_cpu pull tasks if it has higher priority.
> > > + * Bigger imbalances in the number of busy CPUs will be dealt with in
> > > + * update_sd_pick_busiest().
> > > + *
> > > + * If @sg does not have SMT siblings, only pull tasks if all of the SMT siblings
> > > + * of @dst_cpu are idle and @sg has lower priority.
> > > + */
> > > +static bool asym_smt_can_pull_tasks(int dst_cpu, struct sd_lb_stats *sds,
> > > + struct sg_lb_stats *sgs,
> > > + struct sched_group *sg)
> > > +{
> > > +#ifdef CONFIG_SCHED_SMT
> > > + bool local_is_smt, sg_is_smt;
> > > + int sg_busy_cpus;
> > > +
> > > + local_is_smt = sds->local->flags & SD_SHARE_CPUCAPACITY;
> > > + sg_is_smt = sg->flags & SD_SHARE_CPUCAPACITY;
> > > +
> > > + sg_busy_cpus = sgs->group_weight - sgs->idle_cpus;
> > > +
> > > + if (!local_is_smt) {
> > > + /*
> > > + * If we are here, @dst_cpu is idle and does not have SMT
> > > + * siblings. Pull tasks if candidate group has two or more
> > > + * busy CPUs.
> > > + */
> > > + if (sg_is_smt && sg_busy_cpus >= 2)
> > > + return true;
> > > +
> > > + /*
> > > + * @dst_cpu does not have SMT siblings. @sg may have SMT
> > > + * siblings and only one is busy. In such case, @dst_cpu
> > > + * can help if it has higher priority and is idle (i.e.,
> > > + * it has no running tasks).
> > > + */
> > > + return !sds->local_stat.sum_nr_running &&
> > > + sched_asym_prefer(dst_cpu, sg->asym_prefer_cpu);
> > > + }
> > > +
> > > + /* @dst_cpu has SMT siblings. */
> > > +
> > > + if (sg_is_smt) {
> > > + int local_busy_cpus = sds->local->group_weight -
> > > + sds->local_stat.idle_cpus;
> > > + int busy_cpus_delta = sg_busy_cpus - local_busy_cpus;
> > > +
> > > + if (busy_cpus_delta == 1)
> > > + return sched_asym_prefer(dst_cpu,
> > > + sg->asym_prefer_cpu);
> > > +
> > > + return false;
> > > + }
> > > +
> > > + /*
> > > + * @sg does not have SMT siblings. Ensure that @sds::local does not end
> > > + * up with more than one busy SMT sibling and only pull tasks if there
> > > + * are not busy CPUs (i.e., no CPU has running tasks).
> > > + */
> > > + if (!sds->local_stat.sum_nr_running)
> > > + return sched_asym_prefer(dst_cpu, sg->asym_prefer_cpu);
> > > +
> > > + return false;
> > > +#else
> > > + /* Always return false so that callers deal with non-SMT cases. */
> > > + return false;
> > > +#endif
> > > +}
> > > +
> > > static inline bool
> > > sched_asym(struct lb_env *env, struct sd_lb_stats *sds, struct sg_lb_stats *sgs,
> > > struct sched_group *group)
> > > {
> > > + /* Only do SMT checks if either local or candidate have SMT siblings */
> > > + if ((sds->local->flags & SD_SHARE_CPUCAPACITY) ||
> > > + (group->flags & SD_SHARE_CPUCAPACITY))
> > > + return asym_smt_can_pull_tasks(env->dst_cpu, sds, sgs, group);
> > > +
> > > return sched_asym_prefer(env->dst_cpu, group->asym_prefer_cpu);
> > > }
> > >
> > > @@ -9606,6 +9694,12 @@ static struct rq *find_busiest_queue(struct lb_env *env,
> > > nr_running == 1)
> > > continue;
> > >
> > > + /* Make sure we only pull tasks from a CPU of lower priority */
> > > + if ((env->sd->flags & SD_ASYM_PACKING) &&
> > > + sched_asym_prefer(i, env->dst_cpu) &&
> > > + nr_running == 1)
> > > + continue;
> > > +
> > > switch (env->migration_type) {
> > > case migrate_load:
> > > /*
> > >
> >
^ permalink raw reply
* Re: [PATCH 0/5] convert ifc binding to yaml and drop "simple-bus"
From: Li Yang @ 2021-10-01 19:51 UTC (permalink / raw)
To: Krzysztof Kozlowski
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: <4697aa5c-35de-8331-e7a9-831837618477@canonical.com>
On Fri, Oct 1, 2021 at 4:46 AM Krzysztof Kozlowski
<krzysztof.kozlowski@canonical.com> wrote:
>
> On 01/10/2021 02:09, Li Yang wrote:
> > Convert the ifc binding to yaml schema, in the mean while remove the
> > "simple-bus" compatible from the binding to make sure ifc device probes
> > before any of the child devices. Update the driver and existing DTSes
> > accordingly.
> >
> > DTS changes should be merged together with the driver/binding changes
> > if DTS maintainer is ok with it or after the driver changes are applied.
> >
>
> It's discouraged to merge DTS along with drivers (e.g. soc folks don't
> accept such pull requests), so I propose to apply it in the next cycle.
Ok. Will separate the DTS changes in the next version.
>
> Best regards,
> Krzysztof
^ permalink raw reply
* [PATCH 0/9] powerpc/bpf: Various fixes
From: Naveen N. Rao @ 2021-10-01 21:14 UTC (permalink / raw)
To: Michael Ellerman, Nicholas Piggin, Daniel Borkmann,
Alexei Starovoitov, Christophe Leroy, Johan Almbladh
Cc: bpf, linuxppc-dev
Various fixes to the eBPF JIT for powerpc, thanks to some new tests
added by Johan. This series fixes all failures in test_bpf on powerpc64.
There are still some failures on powerpc32 to be looked into.
- Naveen
Naveen N. Rao (8):
powerpc/lib: Add helper to check if offset is within conditional
branch range
powerpc/bpf: Validate branch ranges
powerpc/bpf: Handle large branch ranges with BPF_EXIT
powerpc/bpf: Fix BPF_MOD when imm == 1
powerpc/bpf: Fix BPF_SUB when imm == 0x80000000
powerpc/bpf: Limit 'ldbrx' to processors compliant with ISA v2.06
powerpc/security: Add a helper to query stf_barrier type
powerpc/bpf: Emit stf barrier instruction sequences for BPF_NOSPEC
Ravi Bangoria (1):
powerpc/bpf: Remove unused SEEN_STACK
arch/powerpc/include/asm/code-patching.h | 1 +
arch/powerpc/include/asm/ppc-opcode.h | 1 +
arch/powerpc/include/asm/security_features.h | 5 +
arch/powerpc/kernel/security.c | 5 +
arch/powerpc/lib/code-patching.c | 7 +-
arch/powerpc/net/bpf_jit.h | 39 ++++---
arch/powerpc/net/bpf_jit64.h | 8 +-
arch/powerpc/net/bpf_jit_comp.c | 28 ++++-
arch/powerpc/net/bpf_jit_comp32.c | 10 +-
arch/powerpc/net/bpf_jit_comp64.c | 113 ++++++++++++++-----
10 files changed, 167 insertions(+), 50 deletions(-)
base-commit: 044c2d99d9f43c6d6fde8bed00672517dd9a5a57
--
2.33.0
^ permalink raw reply
* [PATCH 1/9] powerpc/lib: Add helper to check if offset is within conditional branch range
From: Naveen N. Rao @ 2021-10-01 21:14 UTC (permalink / raw)
To: Michael Ellerman, Nicholas Piggin, Daniel Borkmann,
Alexei Starovoitov, Christophe Leroy, Johan Almbladh
Cc: bpf, linuxppc-dev
In-Reply-To: <cover.1633104510.git.naveen.n.rao@linux.vnet.ibm.com>
Add a helper to check if a given offset is within the branch range for a
powerpc conditional branch instruction, and update some sites to use the
new helper.
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/code-patching.h | 1 +
arch/powerpc/lib/code-patching.c | 7 ++++++-
arch/powerpc/net/bpf_jit.h | 7 +------
3 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
index a95f63788c6b14..4ba834599c4d4c 100644
--- a/arch/powerpc/include/asm/code-patching.h
+++ b/arch/powerpc/include/asm/code-patching.h
@@ -23,6 +23,7 @@
#define BRANCH_ABSOLUTE 0x2
bool is_offset_in_branch_range(long offset);
+bool is_offset_in_cond_branch_range(long offset);
int create_branch(struct ppc_inst *instr, const u32 *addr,
unsigned long target, int flags);
int create_cond_branch(struct ppc_inst *instr, const u32 *addr,
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index f9a3019e37b43c..e2342b9a1ab9c9 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -228,6 +228,11 @@ bool is_offset_in_branch_range(long offset)
return (offset >= -0x2000000 && offset <= 0x1fffffc && !(offset & 0x3));
}
+bool is_offset_in_cond_branch_range(long offset)
+{
+ return offset >= -0x8000 && offset <= 0x7FFF && !(offset & 0x3);
+}
+
/*
* Helper to check if a given instruction is a conditional branch
* Derived from the conditional checks in analyse_instr()
@@ -280,7 +285,7 @@ int create_cond_branch(struct ppc_inst *instr, const u32 *addr,
offset = offset - (unsigned long)addr;
/* Check we can represent the target in the instruction format */
- if (offset < -0x8000 || offset > 0x7FFF || offset & 0x3)
+ if (!is_offset_in_cond_branch_range(offset))
return 1;
/* Mask out the flags and target, so they don't step on each other. */
diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
index 99fad093f43ec1..935ea95b66359e 100644
--- a/arch/powerpc/net/bpf_jit.h
+++ b/arch/powerpc/net/bpf_jit.h
@@ -78,11 +78,6 @@
#define PPC_FUNC_ADDR(d,i) do { PPC_LI32(d, i); } while(0)
#endif
-static inline bool is_nearbranch(int offset)
-{
- return (offset < 32768) && (offset >= -32768);
-}
-
/*
* The fly in the ointment of code size changing from pass to pass is
* avoided by padding the short branch case with a NOP. If code size differs
@@ -91,7 +86,7 @@ static inline bool is_nearbranch(int offset)
* state.
*/
#define PPC_BCC(cond, dest) do { \
- if (is_nearbranch((dest) - (ctx->idx * 4))) { \
+ if (is_offset_in_cond_branch_range((long)(dest) - (ctx->idx * 4))) { \
PPC_BCC_SHORT(cond, dest); \
EMIT(PPC_RAW_NOP()); \
} else { \
--
2.33.0
^ permalink raw reply related
* [PATCH 2/9] powerpc/bpf: Validate branch ranges
From: Naveen N. Rao @ 2021-10-01 21:14 UTC (permalink / raw)
To: Michael Ellerman, Nicholas Piggin, Daniel Borkmann,
Alexei Starovoitov, Christophe Leroy, Johan Almbladh
Cc: bpf, linuxppc-dev
In-Reply-To: <cover.1633104510.git.naveen.n.rao@linux.vnet.ibm.com>
Add checks to ensure that we never emit branch instructions with
truncated branch offsets.
Suggested-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
---
arch/powerpc/net/bpf_jit.h | 26 ++++++++++++++++++++------
arch/powerpc/net/bpf_jit_comp.c | 6 +++++-
arch/powerpc/net/bpf_jit_comp32.c | 8 ++++++--
arch/powerpc/net/bpf_jit_comp64.c | 8 ++++++--
4 files changed, 37 insertions(+), 11 deletions(-)
diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
index 935ea95b66359e..7e9b978b768ed9 100644
--- a/arch/powerpc/net/bpf_jit.h
+++ b/arch/powerpc/net/bpf_jit.h
@@ -24,16 +24,30 @@
#define EMIT(instr) PLANT_INSTR(image, ctx->idx, instr)
/* Long jump; (unconditional 'branch') */
-#define PPC_JMP(dest) EMIT(PPC_INST_BRANCH | \
- (((dest) - (ctx->idx * 4)) & 0x03fffffc))
+#define PPC_JMP(dest) \
+ do { \
+ long offset = (long)(dest) - (ctx->idx * 4); \
+ if (!is_offset_in_branch_range(offset)) { \
+ pr_err_ratelimited("Branch offset 0x%lx (@%u) out of range\n", offset, ctx->idx); \
+ return -ERANGE; \
+ } \
+ EMIT(PPC_INST_BRANCH | (offset & 0x03fffffc)); \
+ } while (0)
+
/* blr; (unconditional 'branch' with link) to absolute address */
#define PPC_BL_ABS(dest) EMIT(PPC_INST_BL | \
(((dest) - (unsigned long)(image + ctx->idx)) & 0x03fffffc))
/* "cond" here covers BO:BI fields. */
-#define PPC_BCC_SHORT(cond, dest) EMIT(PPC_INST_BRANCH_COND | \
- (((cond) & 0x3ff) << 16) | \
- (((dest) - (ctx->idx * 4)) & \
- 0xfffc))
+#define PPC_BCC_SHORT(cond, dest) \
+ do { \
+ long offset = (long)(dest) - (ctx->idx * 4); \
+ if (!is_offset_in_cond_branch_range(offset)) { \
+ pr_err_ratelimited("Conditional branch offset 0x%lx (@%u) out of range\n", offset, ctx->idx); \
+ return -ERANGE; \
+ } \
+ EMIT(PPC_INST_BRANCH_COND | (((cond) & 0x3ff) << 16) | (offset & 0xfffc)); \
+ } while (0)
+
/* Sign-extended 32-bit immediate load */
#define PPC_LI32(d, i) do { \
if ((int)(uintptr_t)(i) >= -32768 && \
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index 53aefee3fe70be..fcbf7a917c566e 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -210,7 +210,11 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
/* Now build the prologue, body code & epilogue for real. */
cgctx.idx = 0;
bpf_jit_build_prologue(code_base, &cgctx);
- bpf_jit_build_body(fp, code_base, &cgctx, addrs, extra_pass);
+ if (bpf_jit_build_body(fp, code_base, &cgctx, addrs, extra_pass)) {
+ bpf_jit_binary_free(bpf_hdr);
+ fp = org_fp;
+ goto out_addrs;
+ }
bpf_jit_build_epilogue(code_base, &cgctx);
if (bpf_jit_enable > 1)
diff --git a/arch/powerpc/net/bpf_jit_comp32.c b/arch/powerpc/net/bpf_jit_comp32.c
index beb12cbc8c2994..a74d52204f8da2 100644
--- a/arch/powerpc/net/bpf_jit_comp32.c
+++ b/arch/powerpc/net/bpf_jit_comp32.c
@@ -200,7 +200,7 @@ void bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx, u64 fun
}
}
-static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out)
+static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out)
{
/*
* By now, the eBPF program has already setup parameters in r3-r6
@@ -261,7 +261,9 @@ static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32
bpf_jit_emit_common_epilogue(image, ctx);
EMIT(PPC_RAW_BCTR());
+
/* out: */
+ return 0;
}
/* Assemble the body code between the prologue & epilogue */
@@ -1090,7 +1092,9 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
*/
case BPF_JMP | BPF_TAIL_CALL:
ctx->seen |= SEEN_TAILCALL;
- bpf_jit_emit_tail_call(image, ctx, addrs[i + 1]);
+ ret = bpf_jit_emit_tail_call(image, ctx, addrs[i + 1]);
+ if (ret < 0)
+ return ret;
break;
default:
diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
index b87a63dba9c8fb..f06c62089b1457 100644
--- a/arch/powerpc/net/bpf_jit_comp64.c
+++ b/arch/powerpc/net/bpf_jit_comp64.c
@@ -206,7 +206,7 @@ void bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx, u64 fun
EMIT(PPC_RAW_BCTRL());
}
-static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out)
+static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out)
{
/*
* By now, the eBPF program has already setup parameters in r3, r4 and r5
@@ -267,7 +267,9 @@ static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32
bpf_jit_emit_common_epilogue(image, ctx);
EMIT(PPC_RAW_BCTR());
+
/* out: */
+ return 0;
}
/* Assemble the body code between the prologue & epilogue */
@@ -993,7 +995,9 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
*/
case BPF_JMP | BPF_TAIL_CALL:
ctx->seen |= SEEN_TAILCALL;
- bpf_jit_emit_tail_call(image, ctx, addrs[i + 1]);
+ ret = bpf_jit_emit_tail_call(image, ctx, addrs[i + 1]);
+ if (ret < 0)
+ return ret;
break;
default:
--
2.33.0
^ permalink raw reply related
* [PATCH 3/9] powerpc/bpf: Remove unused SEEN_STACK
From: Naveen N. Rao @ 2021-10-01 21:14 UTC (permalink / raw)
To: Michael Ellerman, Nicholas Piggin, Daniel Borkmann,
Alexei Starovoitov, Christophe Leroy, Johan Almbladh
Cc: bpf, linuxppc-dev
In-Reply-To: <cover.1633104510.git.naveen.n.rao@linux.vnet.ibm.com>
From: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
SEEN_STACK is unused on PowerPC. Remove it. Also, have
SEEN_TAILCALL use 0x40000000.
Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/net/bpf_jit.h | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
index 7e9b978b768ed9..89bd744c2bffd4 100644
--- a/arch/powerpc/net/bpf_jit.h
+++ b/arch/powerpc/net/bpf_jit.h
@@ -125,8 +125,7 @@
#define COND_LE (CR0_GT | COND_CMP_FALSE)
#define SEEN_FUNC 0x20000000 /* might call external helpers */
-#define SEEN_STACK 0x40000000 /* uses BPF stack */
-#define SEEN_TAILCALL 0x80000000 /* uses tail calls */
+#define SEEN_TAILCALL 0x40000000 /* uses tail calls */
#define SEEN_VREG_MASK 0x1ff80000 /* Volatile registers r3-r12 */
#define SEEN_NVREG_MASK 0x0003ffff /* Non volatile registers r14-r31 */
--
2.33.0
^ permalink raw reply related
* [PATCH 4/9] powerpc/bpf: Handle large branch ranges with BPF_EXIT
From: Naveen N. Rao @ 2021-10-01 21:14 UTC (permalink / raw)
To: Michael Ellerman, Nicholas Piggin, Daniel Borkmann,
Alexei Starovoitov, Christophe Leroy, Johan Almbladh
Cc: bpf, linuxppc-dev
In-Reply-To: <cover.1633104510.git.naveen.n.rao@linux.vnet.ibm.com>
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);
/* 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;
--
2.33.0
^ permalink raw reply related
* [PATCH 5/9] powerpc/bpf: Fix BPF_MOD when imm == 1
From: Naveen N. Rao @ 2021-10-01 21:14 UTC (permalink / raw)
To: Michael Ellerman, Nicholas Piggin, Daniel Borkmann,
Alexei Starovoitov, Christophe Leroy, Johan Almbladh
Cc: bpf, linuxppc-dev
In-Reply-To: <cover.1633104510.git.naveen.n.rao@linux.vnet.ibm.com>
Only ignore the operation if dividing by 1.
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 | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
index 3351a866ef6207..ffb7a2877a8469 100644
--- a/arch/powerpc/net/bpf_jit_comp64.c
+++ b/arch/powerpc/net/bpf_jit_comp64.c
@@ -391,8 +391,14 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
case BPF_ALU64 | BPF_DIV | BPF_K: /* dst /= imm */
if (imm == 0)
return -EINVAL;
- else if (imm == 1)
- goto bpf_alu32_trunc;
+ if (imm == 1) {
+ if (BPF_OP(code) == BPF_DIV) {
+ goto bpf_alu32_trunc;
+ } else {
+ EMIT(PPC_RAW_LI(dst_reg, 0));
+ break;
+ }
+ }
PPC_LI32(b2p[TMP_REG_1], imm);
switch (BPF_CLASS(code)) {
--
2.33.0
^ permalink raw reply related
* [PATCH 6/9] powerpc/bpf: Fix BPF_SUB when imm == 0x80000000
From: Naveen N. Rao @ 2021-10-01 21:14 UTC (permalink / raw)
To: Michael Ellerman, Nicholas Piggin, Daniel Borkmann,
Alexei Starovoitov, Christophe Leroy, Johan Almbladh
Cc: bpf, linuxppc-dev
In-Reply-To: <cover.1633104510.git.naveen.n.rao@linux.vnet.ibm.com>
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;
case BPF_ALU | BPF_MUL | BPF_X: /* (u32) dst *= (u32) src */
--
2.33.0
^ permalink raw reply related
* [PATCH 7/9] powerpc/bpf: Limit 'ldbrx' to processors compliant with ISA v2.06
From: Naveen N. Rao @ 2021-10-01 21:14 UTC (permalink / raw)
To: Michael Ellerman, Nicholas Piggin, Daniel Borkmann,
Alexei Starovoitov, Christophe Leroy, Johan Almbladh
Cc: bpf, linuxppc-dev
In-Reply-To: <cover.1633104510.git.naveen.n.rao@linux.vnet.ibm.com>
Johan reported the below crash with test_bpf on ppc64 e5500:
test_bpf: #296 ALU_END_FROM_LE 64: 0x0123456789abcdef -> 0x67452301 jited:1
Oops: Exception in kernel mode, sig: 4 [#1]
BE PAGE_SIZE=4K SMP NR_CPUS=24 QEMU e500
Modules linked in: test_bpf(+)
CPU: 0 PID: 76 Comm: insmod Not tainted 5.14.0-03771-g98c2059e008a-dirty #1
NIP: 8000000000061c3c LR: 80000000006dea64 CTR: 8000000000061c18
REGS: c0000000032d3420 TRAP: 0700 Not tainted (5.14.0-03771-g98c2059e008a-dirty)
MSR: 0000000080089000 <EE,ME> CR: 88002822 XER: 20000000 IRQMASK: 0
<...>
NIP [8000000000061c3c] 0x8000000000061c3c
LR [80000000006dea64] .__run_one+0x104/0x17c [test_bpf]
Call Trace:
.__run_one+0x60/0x17c [test_bpf] (unreliable)
.test_bpf_init+0x6a8/0xdc8 [test_bpf]
.do_one_initcall+0x6c/0x28c
.do_init_module+0x68/0x28c
.load_module+0x2460/0x2abc
.__do_sys_init_module+0x120/0x18c
.system_call_exception+0x110/0x1b8
system_call_common+0xf0/0x210
--- interrupt: c00 at 0x101d0acc
<...>
---[ end trace 47b2bf19090bb3d0 ]---
Illegal instruction
The illegal instruction turned out to be 'ldbrx' emitted for
BPF_FROM_[L|B]E, which was only introduced in ISA v2.06. Guard use of
the same and implement an alternative approach for older processors.
Fixes: 156d0e290e969c ("powerpc/ebpf/jit: Implement JIT compiler for extended BPF")
Reported-by: Johan Almbladh <johan.almbladh@anyfinetworks.com>
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/ppc-opcode.h | 1 +
arch/powerpc/net/bpf_jit_comp64.c | 22 +++++++++++++---------
2 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index baea657bc8687e..bca31a61e57f88 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -498,6 +498,7 @@
#define PPC_RAW_LDX(r, base, b) (0x7c00002a | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b))
#define PPC_RAW_LHZ(r, base, i) (0xa0000000 | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
#define PPC_RAW_LHBRX(r, base, b) (0x7c00062c | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b))
+#define PPC_RAW_LWBRX(r, base, b) (0x7c00042c | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b))
#define PPC_RAW_LDBRX(r, base, b) (0x7c000428 | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b))
#define PPC_RAW_STWCX(s, a, b) (0x7c00012d | ___PPC_RS(s) | ___PPC_RA(a) | ___PPC_RB(b))
#define PPC_RAW_CMPWI(a, i) (0x2c000000 | ___PPC_RA(a) | IMM_L(i))
diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
index 4641a50e82d50d..097d1ecfb9f562 100644
--- a/arch/powerpc/net/bpf_jit_comp64.c
+++ b/arch/powerpc/net/bpf_jit_comp64.c
@@ -601,17 +601,21 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
EMIT(PPC_RAW_MR(dst_reg, b2p[TMP_REG_1]));
break;
case 64:
- /*
- * Way easier and faster(?) to store the value
- * into stack and then use ldbrx
- *
- * ctx->seen will be reliable in pass2, but
- * the instructions generated will remain the
- * same across all passes
- */
+ /* Store the value to stack and then use byte-reverse loads */
PPC_BPF_STL(dst_reg, 1, bpf_jit_stack_local(ctx));
EMIT(PPC_RAW_ADDI(b2p[TMP_REG_1], 1, bpf_jit_stack_local(ctx)));
- EMIT(PPC_RAW_LDBRX(dst_reg, 0, b2p[TMP_REG_1]));
+ if (cpu_has_feature(CPU_FTR_ARCH_206)) {
+ EMIT(PPC_RAW_LDBRX(dst_reg, 0, b2p[TMP_REG_1]));
+ } else {
+ EMIT(PPC_RAW_LWBRX(dst_reg, 0, b2p[TMP_REG_1]));
+ if (IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN))
+ EMIT(PPC_RAW_SLDI(dst_reg, dst_reg, 32));
+ EMIT(PPC_RAW_LI(b2p[TMP_REG_2], 4));
+ EMIT(PPC_RAW_LWBRX(b2p[TMP_REG_2], b2p[TMP_REG_2], b2p[TMP_REG_1]));
+ if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
+ EMIT(PPC_RAW_SLDI(b2p[TMP_REG_2], b2p[TMP_REG_2], 32));
+ EMIT(PPC_RAW_OR(dst_reg, dst_reg, b2p[TMP_REG_2]));
+ }
break;
}
break;
--
2.33.0
^ permalink raw reply related
* [PATCH 9/9] powerpc/bpf: Emit stf barrier instruction sequences for BPF_NOSPEC
From: Naveen N. Rao @ 2021-10-01 21:14 UTC (permalink / raw)
To: Michael Ellerman, Nicholas Piggin, Daniel Borkmann,
Alexei Starovoitov, Christophe Leroy, Johan Almbladh
Cc: bpf, linuxppc-dev
In-Reply-To: <cover.1633104510.git.naveen.n.rao@linux.vnet.ibm.com>
Emit similar instruction sequences to commit a048a07d7f4535
("powerpc/64s: Add support for a store forwarding barrier at kernel
entry/exit") when encountering BPF_NOSPEC.
Mitigations are enabled depending on what the firmware advertises. In
particular, we do not gate these mitigations based on current settings,
just like in x86. Due to this, we don't need to take any action if
mitigations are enabled or disabled at runtime.
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
---
Thanks to Daniel Borkmann and Nick Piggin for their help in putting
together this patch!
arch/powerpc/net/bpf_jit64.h | 8 ++---
arch/powerpc/net/bpf_jit_comp64.c | 55 ++++++++++++++++++++++++++++---
2 files changed, 55 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/net/bpf_jit64.h b/arch/powerpc/net/bpf_jit64.h
index 7b713edfa7e261..b63b35e45e558c 100644
--- a/arch/powerpc/net/bpf_jit64.h
+++ b/arch/powerpc/net/bpf_jit64.h
@@ -16,18 +16,18 @@
* with our redzone usage.
*
* [ prev sp ] <-------------
- * [ nv gpr save area ] 6*8 |
+ * [ nv gpr save area ] 5*8 |
* [ tail_call_cnt ] 8 |
- * [ local_tmp_var ] 8 |
+ * [ local_tmp_var ] 16 |
* fp (r31) --> [ ebpf stack space ] upto 512 |
* [ frame header ] 32/112 |
* sp (r1) ---> [ stack pointer ] --------------
*/
/* for gpr non volatile registers BPG_REG_6 to 10 */
-#define BPF_PPC_STACK_SAVE (6*8)
+#define BPF_PPC_STACK_SAVE (5*8)
/* for bpf JIT code internal usage */
-#define BPF_PPC_STACK_LOCALS 16
+#define BPF_PPC_STACK_LOCALS 24
/* stack frame excluding BPF stack, ensure this is quadword aligned */
#define BPF_PPC_STACKFRAME (STACK_FRAME_MIN_SIZE + \
BPF_PPC_STACK_LOCALS + BPF_PPC_STACK_SAVE)
diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
index 097d1ecfb9f562..df1666f0b54d9b 100644
--- a/arch/powerpc/net/bpf_jit_comp64.c
+++ b/arch/powerpc/net/bpf_jit_comp64.c
@@ -15,6 +15,7 @@
#include <linux/if_vlan.h>
#include <asm/kprobes.h>
#include <linux/bpf.h>
+#include <asm/security_features.h>
#include "bpf_jit64.h"
@@ -35,9 +36,9 @@ static inline bool bpf_has_stack_frame(struct codegen_context *ctx)
* [ prev sp ] <-------------
* [ ... ] |
* sp (r1) ---> [ stack pointer ] --------------
- * [ nv gpr save area ] 6*8
+ * [ nv gpr save area ] 5*8
* [ tail_call_cnt ] 8
- * [ local_tmp_var ] 8
+ * [ local_tmp_var ] 16
* [ unused red zone ] 208 bytes protected
*/
static int bpf_jit_stack_local(struct codegen_context *ctx)
@@ -45,12 +46,12 @@ static int bpf_jit_stack_local(struct codegen_context *ctx)
if (bpf_has_stack_frame(ctx))
return STACK_FRAME_MIN_SIZE + ctx->stack_size;
else
- return -(BPF_PPC_STACK_SAVE + 16);
+ return -(BPF_PPC_STACK_SAVE + 24);
}
static int bpf_jit_stack_tailcallcnt(struct codegen_context *ctx)
{
- return bpf_jit_stack_local(ctx) + 8;
+ return bpf_jit_stack_local(ctx) + 16;
}
static int bpf_jit_stack_offsetof(struct codegen_context *ctx, int reg)
@@ -272,10 +273,33 @@ static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 o
return 0;
}
+/*
+ * We spill into the redzone always, even if the bpf program has its own stackframe.
+ * Offsets hardcoded based on BPF_PPC_STACK_SAVE -- see bpf_jit_stack_local()
+ */
+void bpf_stf_barrier(void);
+
+asm (
+" .global bpf_stf_barrier ;"
+" bpf_stf_barrier: ;"
+" std 21,-64(1) ;"
+" std 22,-56(1) ;"
+" sync ;"
+" ld 21,-64(1) ;"
+" ld 22,-56(1) ;"
+" ori 31,31,0 ;"
+" .rept 14 ;"
+" b 1f ;"
+" 1: ;"
+" .endr ;"
+" blr ;"
+);
+
/* Assemble the body code between the prologue & epilogue */
int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *ctx,
u32 *addrs, bool extra_pass)
{
+ enum stf_barrier_type stf_barrier = stf_barrier_type_get();
const struct bpf_insn *insn = fp->insnsi;
int flen = fp->len;
int i, ret;
@@ -643,6 +667,29 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
* BPF_ST NOSPEC (speculation barrier)
*/
case BPF_ST | BPF_NOSPEC:
+ if (!security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) ||
+ !security_ftr_enabled(SEC_FTR_STF_BARRIER))
+ break;
+
+ switch (stf_barrier) {
+ case STF_BARRIER_EIEIO:
+ EMIT(PPC_RAW_EIEIO() | 0x02000000);
+ break;
+ case STF_BARRIER_SYNC_ORI:
+ EMIT(PPC_RAW_SYNC());
+ EMIT(PPC_RAW_LD(b2p[TMP_REG_1], _R13, 0));
+ EMIT(PPC_RAW_ORI(_R31, _R31, 0));
+ break;
+ case STF_BARRIER_FALLBACK:
+ EMIT(PPC_RAW_MFLR(b2p[TMP_REG_1]));
+ PPC_LI64(12, dereference_kernel_function_descriptor(bpf_stf_barrier));
+ EMIT(PPC_RAW_MTCTR(12));
+ EMIT(PPC_RAW_BCTRL());
+ EMIT(PPC_RAW_MTLR(b2p[TMP_REG_1]));
+ break;
+ case STF_BARRIER_NONE:
+ break;
+ }
break;
/*
--
2.33.0
^ permalink raw reply related
* [PATCH 8/9] powerpc/security: Add a helper to query stf_barrier type
From: Naveen N. Rao @ 2021-10-01 21:14 UTC (permalink / raw)
To: Michael Ellerman, Nicholas Piggin, Daniel Borkmann,
Alexei Starovoitov, Christophe Leroy, Johan Almbladh
Cc: bpf, linuxppc-dev
In-Reply-To: <cover.1633104510.git.naveen.n.rao@linux.vnet.ibm.com>
Add a helper to return the stf_barrier type for the current processor.
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/security_features.h | 5 +++++
arch/powerpc/kernel/security.c | 5 +++++
2 files changed, 10 insertions(+)
diff --git a/arch/powerpc/include/asm/security_features.h b/arch/powerpc/include/asm/security_features.h
index 792eefaf230b80..27574f218b371f 100644
--- a/arch/powerpc/include/asm/security_features.h
+++ b/arch/powerpc/include/asm/security_features.h
@@ -39,6 +39,11 @@ static inline bool security_ftr_enabled(u64 feature)
return !!(powerpc_security_features & feature);
}
+#ifdef CONFIG_PPC_BOOK3S_64
+enum stf_barrier_type stf_barrier_type_get(void);
+#else
+static inline enum stf_barrier_type stf_barrier_type_get(void) { return STF_BARRIER_NONE; }
+#endif
// Features indicating support for Spectre/Meltdown mitigations
diff --git a/arch/powerpc/kernel/security.c b/arch/powerpc/kernel/security.c
index 1a998490fe60f0..15fb5ea1b9eafa 100644
--- a/arch/powerpc/kernel/security.c
+++ b/arch/powerpc/kernel/security.c
@@ -263,6 +263,11 @@ static int __init handle_no_stf_barrier(char *p)
early_param("no_stf_barrier", handle_no_stf_barrier);
+enum stf_barrier_type stf_barrier_type_get(void)
+{
+ return stf_enabled_flush_types;
+}
+
/* This is the generic flag used by other architectures */
static int __init handle_ssbd(char *p)
{
--
2.33.0
^ permalink raw reply related
* Re: [PATCH v4 0/8] bpf powerpc: Add BPF_PROBE_MEM support in powerpc JIT compiler
From: Naveen N. Rao @ 2021-10-01 21:22 UTC (permalink / raw)
To: ast, christophe.leroy, Daniel Borkmann, Hari Bathini, mpe
Cc: songliubraving, netdev, john.fastabend, kpsingh, andrii, paulus,
yhs, bpf, linuxppc-dev, kafai
In-Reply-To: <88b59272-e3f7-30ba-dda0-c4a6b42c0029@iogearbox.net>
Daniel Borkmann wrote:
> 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?
I just posted a few fixes to the powerpc BPF JIT (*). It would be nice
if those can be picked up for v5.15 through bpf/master or powerpc/fixes.
If so, this series may need to be rebased to address some conflicts.
Otherwise, I can re-post my fixes atop this.
Thanks,
Naveen
(*) https://lore.kernel.org/linuxppc-dev/cover.1633104510.git.naveen.n.rao@linux.vnet.ibm.com/T/#u
^ permalink raw reply
* Re: [PATCH 1/9] powerpc/lib: Add helper to check if offset is within conditional branch range
From: Song Liu @ 2021-10-01 21:37 UTC (permalink / raw)
To: Naveen N. Rao
Cc: Daniel Borkmann, Johan Almbladh, Nicholas Piggin, bpf,
linuxppc-dev, Alexei Starovoitov
In-Reply-To: <f8d581e6a5d9555180c38e009f90d236f310f85e.1633104510.git.naveen.n.rao@linux.vnet.ibm.com>
On Fri, Oct 1, 2021 at 2:16 PM Naveen N. Rao
<naveen.n.rao@linux.vnet.ibm.com> wrote:
>
> Add a helper to check if a given offset is within the branch range for a
> powerpc conditional branch instruction, and update some sites to use the
> new helper.
>
> Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Acked-by: Song Liu <songliubraving@fb.com>
With one nitpick:
> ---
> arch/powerpc/include/asm/code-patching.h | 1 +
> arch/powerpc/lib/code-patching.c | 7 ++++++-
> arch/powerpc/net/bpf_jit.h | 7 +------
> 3 files changed, 8 insertions(+), 7 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
> index a95f63788c6b14..4ba834599c4d4c 100644
> --- a/arch/powerpc/include/asm/code-patching.h
> +++ b/arch/powerpc/include/asm/code-patching.h
> @@ -23,6 +23,7 @@
> #define BRANCH_ABSOLUTE 0x2
>
> bool is_offset_in_branch_range(long offset);
> +bool is_offset_in_cond_branch_range(long offset);
> int create_branch(struct ppc_inst *instr, const u32 *addr,
> unsigned long target, int flags);
> int create_cond_branch(struct ppc_inst *instr, const u32 *addr,
> diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
> index f9a3019e37b43c..e2342b9a1ab9c9 100644
> --- a/arch/powerpc/lib/code-patching.c
> +++ b/arch/powerpc/lib/code-patching.c
> @@ -228,6 +228,11 @@ bool is_offset_in_branch_range(long offset)
> return (offset >= -0x2000000 && offset <= 0x1fffffc && !(offset & 0x3));
> }
>
> +bool is_offset_in_cond_branch_range(long offset)
> +{
> + return offset >= -0x8000 && offset <= 0x7FFF && !(offset & 0x3);
> +}
Why not inline this one?
> +
> /*
> * Helper to check if a given instruction is a conditional branch
> * Derived from the conditional checks in analyse_instr()
> @@ -280,7 +285,7 @@ int create_cond_branch(struct ppc_inst *instr, const u32 *addr,
> offset = offset - (unsigned long)addr;
>
> /* Check we can represent the target in the instruction format */
> - if (offset < -0x8000 || offset > 0x7FFF || offset & 0x3)
> + if (!is_offset_in_cond_branch_range(offset))
> return 1;
>
> /* Mask out the flags and target, so they don't step on each other. */
> diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
> index 99fad093f43ec1..935ea95b66359e 100644
> --- a/arch/powerpc/net/bpf_jit.h
> +++ b/arch/powerpc/net/bpf_jit.h
> @@ -78,11 +78,6 @@
> #define PPC_FUNC_ADDR(d,i) do { PPC_LI32(d, i); } while(0)
> #endif
>
> -static inline bool is_nearbranch(int offset)
> -{
> - return (offset < 32768) && (offset >= -32768);
> -}
> -
> /*
> * The fly in the ointment of code size changing from pass to pass is
> * avoided by padding the short branch case with a NOP. If code size differs
> @@ -91,7 +86,7 @@ static inline bool is_nearbranch(int offset)
> * state.
> */
> #define PPC_BCC(cond, dest) do { \
> - if (is_nearbranch((dest) - (ctx->idx * 4))) { \
> + if (is_offset_in_cond_branch_range((long)(dest) - (ctx->idx * 4))) { \
> PPC_BCC_SHORT(cond, dest); \
> EMIT(PPC_RAW_NOP()); \
> } else { \
> --
> 2.33.0
>
^ permalink raw reply
* Re: [PATCH 2/9] powerpc/bpf: Validate branch ranges
From: Song Liu @ 2021-10-01 21:45 UTC (permalink / raw)
To: Naveen N. Rao
Cc: Daniel Borkmann, Johan Almbladh, Nicholas Piggin, bpf,
linuxppc-dev, Alexei Starovoitov
In-Reply-To: <d4a44c52712468b805cbf5c244b3c9ba0f802ab8.1633104510.git.naveen.n.rao@linux.vnet.ibm.com>
On Fri, Oct 1, 2021 at 2:16 PM Naveen N. Rao
<naveen.n.rao@linux.vnet.ibm.com> wrote:
>
> Add checks to ensure that we never emit branch instructions with
> truncated branch offsets.
>
> Suggested-by: Michael Ellerman <mpe@ellerman.id.au>
> Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Acked-by: Song Liu <songliubraving@fb.com>
> ---
> arch/powerpc/net/bpf_jit.h | 26 ++++++++++++++++++++------
> arch/powerpc/net/bpf_jit_comp.c | 6 +++++-
> arch/powerpc/net/bpf_jit_comp32.c | 8 ++++++--
> arch/powerpc/net/bpf_jit_comp64.c | 8 ++++++--
> 4 files changed, 37 insertions(+), 11 deletions(-)
>
> diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
> index 935ea95b66359e..7e9b978b768ed9 100644
> --- a/arch/powerpc/net/bpf_jit.h
> +++ b/arch/powerpc/net/bpf_jit.h
> @@ -24,16 +24,30 @@
> #define EMIT(instr) PLANT_INSTR(image, ctx->idx, instr)
>
> /* Long jump; (unconditional 'branch') */
> -#define PPC_JMP(dest) EMIT(PPC_INST_BRANCH | \
> - (((dest) - (ctx->idx * 4)) & 0x03fffffc))
> +#define PPC_JMP(dest) \
> + do { \
> + long offset = (long)(dest) - (ctx->idx * 4); \
> + if (!is_offset_in_branch_range(offset)) { \
> + pr_err_ratelimited("Branch offset 0x%lx (@%u) out of range\n", offset, ctx->idx); \
> + return -ERANGE; \
> + } \
> + EMIT(PPC_INST_BRANCH | (offset & 0x03fffffc)); \
> + } while (0)
> +
> /* blr; (unconditional 'branch' with link) to absolute address */
> #define PPC_BL_ABS(dest) EMIT(PPC_INST_BL | \
> (((dest) - (unsigned long)(image + ctx->idx)) & 0x03fffffc))
> /* "cond" here covers BO:BI fields. */
> -#define PPC_BCC_SHORT(cond, dest) EMIT(PPC_INST_BRANCH_COND | \
> - (((cond) & 0x3ff) << 16) | \
> - (((dest) - (ctx->idx * 4)) & \
> - 0xfffc))
> +#define PPC_BCC_SHORT(cond, dest) \
> + do { \
> + long offset = (long)(dest) - (ctx->idx * 4); \
> + if (!is_offset_in_cond_branch_range(offset)) { \
> + pr_err_ratelimited("Conditional branch offset 0x%lx (@%u) out of range\n", offset, ctx->idx); \
> + return -ERANGE; \
> + } \
> + EMIT(PPC_INST_BRANCH_COND | (((cond) & 0x3ff) << 16) | (offset & 0xfffc)); \
> + } while (0)
> +
> /* Sign-extended 32-bit immediate load */
> #define PPC_LI32(d, i) do { \
> if ((int)(uintptr_t)(i) >= -32768 && \
> diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
> index 53aefee3fe70be..fcbf7a917c566e 100644
> --- a/arch/powerpc/net/bpf_jit_comp.c
> +++ b/arch/powerpc/net/bpf_jit_comp.c
> @@ -210,7 +210,11 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
> /* Now build the prologue, body code & epilogue for real. */
> cgctx.idx = 0;
> bpf_jit_build_prologue(code_base, &cgctx);
> - bpf_jit_build_body(fp, code_base, &cgctx, addrs, extra_pass);
> + if (bpf_jit_build_body(fp, code_base, &cgctx, addrs, extra_pass)) {
> + bpf_jit_binary_free(bpf_hdr);
> + fp = org_fp;
> + goto out_addrs;
> + }
> bpf_jit_build_epilogue(code_base, &cgctx);
>
> if (bpf_jit_enable > 1)
> diff --git a/arch/powerpc/net/bpf_jit_comp32.c b/arch/powerpc/net/bpf_jit_comp32.c
> index beb12cbc8c2994..a74d52204f8da2 100644
> --- a/arch/powerpc/net/bpf_jit_comp32.c
> +++ b/arch/powerpc/net/bpf_jit_comp32.c
> @@ -200,7 +200,7 @@ void bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx, u64 fun
> }
> }
>
> -static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out)
> +static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out)
> {
> /*
> * By now, the eBPF program has already setup parameters in r3-r6
> @@ -261,7 +261,9 @@ static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32
> bpf_jit_emit_common_epilogue(image, ctx);
>
> EMIT(PPC_RAW_BCTR());
> +
> /* out: */
> + return 0;
> }
>
> /* Assemble the body code between the prologue & epilogue */
> @@ -1090,7 +1092,9 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
> */
> case BPF_JMP | BPF_TAIL_CALL:
> ctx->seen |= SEEN_TAILCALL;
> - bpf_jit_emit_tail_call(image, ctx, addrs[i + 1]);
> + ret = bpf_jit_emit_tail_call(image, ctx, addrs[i + 1]);
> + if (ret < 0)
> + return ret;
> break;
>
> default:
> diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
> index b87a63dba9c8fb..f06c62089b1457 100644
> --- a/arch/powerpc/net/bpf_jit_comp64.c
> +++ b/arch/powerpc/net/bpf_jit_comp64.c
> @@ -206,7 +206,7 @@ void bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx, u64 fun
> EMIT(PPC_RAW_BCTRL());
> }
>
> -static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out)
> +static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out)
> {
> /*
> * By now, the eBPF program has already setup parameters in r3, r4 and r5
> @@ -267,7 +267,9 @@ static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32
> bpf_jit_emit_common_epilogue(image, ctx);
>
> EMIT(PPC_RAW_BCTR());
> +
> /* out: */
> + return 0;
> }
>
> /* Assemble the body code between the prologue & epilogue */
> @@ -993,7 +995,9 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
> */
> case BPF_JMP | BPF_TAIL_CALL:
> ctx->seen |= SEEN_TAILCALL;
> - bpf_jit_emit_tail_call(image, ctx, addrs[i + 1]);
> + ret = bpf_jit_emit_tail_call(image, ctx, addrs[i + 1]);
> + if (ret < 0)
> + return ret;
> break;
>
> default:
> --
> 2.33.0
>
^ permalink raw reply
* Re: [PATCH 3/9] powerpc/bpf: Remove unused SEEN_STACK
From: Song Liu @ 2021-10-01 21:47 UTC (permalink / raw)
To: Naveen N. Rao
Cc: Daniel Borkmann, Johan Almbladh, Nicholas Piggin, bpf,
linuxppc-dev, Alexei Starovoitov
In-Reply-To: <92fcd53a43dede52fbba52dc50c76042a6ce284c.1633104510.git.naveen.n.rao@linux.vnet.ibm.com>
On Fri, Oct 1, 2021 at 2:16 PM Naveen N. Rao
<naveen.n.rao@linux.vnet.ibm.com> wrote:
>
> From: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
>
> SEEN_STACK is unused on PowerPC. Remove it. Also, have
> SEEN_TAILCALL use 0x40000000.
>
> Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
> Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Acked-by: Song Liu <songliubraving@fb.com>
> ---
> arch/powerpc/net/bpf_jit.h | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
> index 7e9b978b768ed9..89bd744c2bffd4 100644
> --- a/arch/powerpc/net/bpf_jit.h
> +++ b/arch/powerpc/net/bpf_jit.h
> @@ -125,8 +125,7 @@
> #define COND_LE (CR0_GT | COND_CMP_FALSE)
>
> #define SEEN_FUNC 0x20000000 /* might call external helpers */
> -#define SEEN_STACK 0x40000000 /* uses BPF stack */
> -#define SEEN_TAILCALL 0x80000000 /* uses tail calls */
> +#define SEEN_TAILCALL 0x40000000 /* uses tail calls */
>
> #define SEEN_VREG_MASK 0x1ff80000 /* Volatile registers r3-r12 */
> #define SEEN_NVREG_MASK 0x0003ffff /* Non volatile registers r14-r31 */
> --
> 2.33.0
>
^ permalink raw reply
* Re: [PATCH 4/9] powerpc/bpf: Handle large branch ranges with BPF_EXIT
From: Song Liu @ 2021-10-01 21:53 UTC (permalink / raw)
To: Naveen N. Rao
Cc: Daniel Borkmann, Johan Almbladh, Nicholas Piggin, bpf,
linuxppc-dev, Alexei Starovoitov
In-Reply-To: <ebc0317ce465cb4f8d6fe485ab468ac5bda7c48f.1633104510.git.naveen.n.rao@linux.vnet.ibm.com>
On Fri, Oct 1, 2021 at 2:17 PM Naveen N. Rao
<naveen.n.rao@linux.vnet.ibm.com> wrote:
>
> 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>
Acked-by: Song Liu <songliubraving@fb.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);
> /* 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;
>
> --
> 2.33.0
>
^ permalink raw reply
* Re: [PATCH 5/9] powerpc/bpf: Fix BPF_MOD when imm == 1
From: Song Liu @ 2021-10-01 21:55 UTC (permalink / raw)
To: Naveen N. Rao
Cc: Daniel Borkmann, Johan Almbladh, Nicholas Piggin, bpf,
linuxppc-dev, Alexei Starovoitov
In-Reply-To: <8cb6a1725cf3c38ca90ed7f195f78a5b5a83bb25.1633104510.git.naveen.n.rao@linux.vnet.ibm.com>
On Fri, Oct 1, 2021 at 2:16 PM Naveen N. Rao
<naveen.n.rao@linux.vnet.ibm.com> wrote:
>
> Only ignore the operation if dividing by 1.
>
> Fixes: 156d0e290e969c ("powerpc/ebpf/jit: Implement JIT compiler for extended BPF")
> Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Acked-by: Song Liu <songliubraving@fb.com>
> ---
> arch/powerpc/net/bpf_jit_comp64.c | 10 ++++++++--
> 1 file changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
> index 3351a866ef6207..ffb7a2877a8469 100644
> --- a/arch/powerpc/net/bpf_jit_comp64.c
> +++ b/arch/powerpc/net/bpf_jit_comp64.c
> @@ -391,8 +391,14 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
> case BPF_ALU64 | BPF_DIV | BPF_K: /* dst /= imm */
> if (imm == 0)
> return -EINVAL;
> - else if (imm == 1)
> - goto bpf_alu32_trunc;
> + if (imm == 1) {
> + if (BPF_OP(code) == BPF_DIV) {
> + goto bpf_alu32_trunc;
> + } else {
> + EMIT(PPC_RAW_LI(dst_reg, 0));
> + break;
> + }
> + }
>
> PPC_LI32(b2p[TMP_REG_1], imm);
> switch (BPF_CLASS(code)) {
> --
> 2.33.0
>
^ permalink raw reply
* Re: [PATCH 6/9] powerpc/bpf: Fix BPF_SUB when imm == 0x80000000
From: Song Liu @ 2021-10-01 22:01 UTC (permalink / raw)
To: Naveen N. Rao
Cc: Daniel Borkmann, Johan Almbladh, Nicholas Piggin, bpf,
linuxppc-dev, Alexei Starovoitov
In-Reply-To: <1912a409447071f46ac6cc957ce8edea0e5232b7.1633104510.git.naveen.n.rao@linux.vnet.ibm.com>
On Fri, Oct 1, 2021 at 2:17 PM Naveen N. Rao
<naveen.n.rao@linux.vnet.ibm.com> wrote:
>
> 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>
Acked-by: Song Liu <songliubraving@fb.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;
> case BPF_ALU | BPF_MUL | BPF_X: /* (u32) dst *= (u32) src */
> --
> 2.33.0
>
^ permalink raw reply
* Re: [PATCH] ASoC: fsl_spdif: implement bypass mode from in to out
From: Mark Brown @ 2021-10-02 0:16 UTC (permalink / raw)
To: festevam, tiwai, alsa-devel, perex, timur, Xiubo.Lee,
Shengjiu Wang, nicoleotsuka
Cc: Mark Brown, linuxppc-dev, linux-kernel
In-Reply-To: <1632649760-1651-1-git-send-email-shengjiu.wang@nxp.com>
On Sun, 26 Sep 2021 17:49:20 +0800, Shengjiu Wang wrote:
> From: Viorel Suman <viorel.suman@nxp.com>
>
> Implement SPDIF bypass mode. It implies internal SoC
> routing of SPDIF input signal to SPDIF output signal. The
> test bed requires two boards: B1 configured in bypass mode,
> and B2 to feed B1 SPDIF RX port and read B1 SPDIF TX port:
> B2 TX -> B1 RX,
> B2 RX <- B1 TX.
> The test procedure:
> a) Boot both boards
> b) B2: start "arecord <spdifcard> -r 48kHz | aplay <local DAC>"
> c) B2: start "aplay <spdifcard> -r 48kHz <2ch 48kHz audio file>"
> d) B1: enable bypass mode:
> amixer -cimxspdif cset numid=8,iface=PCM,name='Bypass Mode' on
> e) B2: check DAC audio, make sure the same sample rate is used at
> steps b) and c), in example above the rate is 48kHz.
> f) B1: try to run "aplay" or "arecord" on imxspdif card while in
> bypass mode - both must fail until bypass mode is disabled
> g) B1: disable bypass mode:
> amixer -cimxspdif cset numid=8,iface=PCM,name='Bypass Mode' off
> h) B1: check the usual playback and capture on imxspdif card.
> During this test try to set bypass mode - must not be allowed
> while playback or capture is running.
>
> [...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/1] ASoC: fsl_spdif: implement bypass mode from in to out
commit: 83bea088f976a289bc2efe4e404af47ab79d6639
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
^ permalink raw reply
* Re: [PATCH 2/9] powerpc/bpf: Validate branch ranges
From: Johan Almbladh @ 2021-10-02 17:29 UTC (permalink / raw)
To: Naveen N. Rao
Cc: Daniel Borkmann, Nicholas Piggin, bpf, linuxppc-dev,
Alexei Starovoitov
In-Reply-To: <d4a44c52712468b805cbf5c244b3c9ba0f802ab8.1633104510.git.naveen.n.rao@linux.vnet.ibm.com>
On Fri, Oct 1, 2021 at 11:15 PM Naveen N. Rao
<naveen.n.rao@linux.vnet.ibm.com> wrote:
>
> Add checks to ensure that we never emit branch instructions with
> truncated branch offsets.
>
> Suggested-by: Michael Ellerman <mpe@ellerman.id.au>
> Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Acked-by: Johan Almbladh <johan.almbladh@anyfinetworks.com>
Tested-by: Johan Almbladh <johan.almbladh@anyfinetworks.com>
> ---
> arch/powerpc/net/bpf_jit.h | 26 ++++++++++++++++++++------
> arch/powerpc/net/bpf_jit_comp.c | 6 +++++-
> arch/powerpc/net/bpf_jit_comp32.c | 8 ++++++--
> arch/powerpc/net/bpf_jit_comp64.c | 8 ++++++--
> 4 files changed, 37 insertions(+), 11 deletions(-)
>
> diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
> index 935ea95b66359e..7e9b978b768ed9 100644
> --- a/arch/powerpc/net/bpf_jit.h
> +++ b/arch/powerpc/net/bpf_jit.h
> @@ -24,16 +24,30 @@
> #define EMIT(instr) PLANT_INSTR(image, ctx->idx, instr)
>
> /* Long jump; (unconditional 'branch') */
> -#define PPC_JMP(dest) EMIT(PPC_INST_BRANCH | \
> - (((dest) - (ctx->idx * 4)) & 0x03fffffc))
> +#define PPC_JMP(dest) \
> + do { \
> + long offset = (long)(dest) - (ctx->idx * 4); \
> + if (!is_offset_in_branch_range(offset)) { \
> + pr_err_ratelimited("Branch offset 0x%lx (@%u) out of range\n", offset, ctx->idx); \
> + return -ERANGE; \
> + } \
> + EMIT(PPC_INST_BRANCH | (offset & 0x03fffffc)); \
> + } while (0)
> +
> /* blr; (unconditional 'branch' with link) to absolute address */
> #define PPC_BL_ABS(dest) EMIT(PPC_INST_BL | \
> (((dest) - (unsigned long)(image + ctx->idx)) & 0x03fffffc))
> /* "cond" here covers BO:BI fields. */
> -#define PPC_BCC_SHORT(cond, dest) EMIT(PPC_INST_BRANCH_COND | \
> - (((cond) & 0x3ff) << 16) | \
> - (((dest) - (ctx->idx * 4)) & \
> - 0xfffc))
> +#define PPC_BCC_SHORT(cond, dest) \
> + do { \
> + long offset = (long)(dest) - (ctx->idx * 4); \
> + if (!is_offset_in_cond_branch_range(offset)) { \
> + pr_err_ratelimited("Conditional branch offset 0x%lx (@%u) out of range\n", offset, ctx->idx); \
> + return -ERANGE; \
> + } \
> + EMIT(PPC_INST_BRANCH_COND | (((cond) & 0x3ff) << 16) | (offset & 0xfffc)); \
> + } while (0)
> +
> /* Sign-extended 32-bit immediate load */
> #define PPC_LI32(d, i) do { \
> if ((int)(uintptr_t)(i) >= -32768 && \
> diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
> index 53aefee3fe70be..fcbf7a917c566e 100644
> --- a/arch/powerpc/net/bpf_jit_comp.c
> +++ b/arch/powerpc/net/bpf_jit_comp.c
> @@ -210,7 +210,11 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
> /* Now build the prologue, body code & epilogue for real. */
> cgctx.idx = 0;
> bpf_jit_build_prologue(code_base, &cgctx);
> - bpf_jit_build_body(fp, code_base, &cgctx, addrs, extra_pass);
> + if (bpf_jit_build_body(fp, code_base, &cgctx, addrs, extra_pass)) {
> + bpf_jit_binary_free(bpf_hdr);
> + fp = org_fp;
> + goto out_addrs;
> + }
> bpf_jit_build_epilogue(code_base, &cgctx);
>
> if (bpf_jit_enable > 1)
> diff --git a/arch/powerpc/net/bpf_jit_comp32.c b/arch/powerpc/net/bpf_jit_comp32.c
> index beb12cbc8c2994..a74d52204f8da2 100644
> --- a/arch/powerpc/net/bpf_jit_comp32.c
> +++ b/arch/powerpc/net/bpf_jit_comp32.c
> @@ -200,7 +200,7 @@ void bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx, u64 fun
> }
> }
>
> -static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out)
> +static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out)
> {
> /*
> * By now, the eBPF program has already setup parameters in r3-r6
> @@ -261,7 +261,9 @@ static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32
> bpf_jit_emit_common_epilogue(image, ctx);
>
> EMIT(PPC_RAW_BCTR());
> +
> /* out: */
> + return 0;
> }
>
> /* Assemble the body code between the prologue & epilogue */
> @@ -1090,7 +1092,9 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
> */
> case BPF_JMP | BPF_TAIL_CALL:
> ctx->seen |= SEEN_TAILCALL;
> - bpf_jit_emit_tail_call(image, ctx, addrs[i + 1]);
> + ret = bpf_jit_emit_tail_call(image, ctx, addrs[i + 1]);
> + if (ret < 0)
> + return ret;
> break;
>
> default:
> diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
> index b87a63dba9c8fb..f06c62089b1457 100644
> --- a/arch/powerpc/net/bpf_jit_comp64.c
> +++ b/arch/powerpc/net/bpf_jit_comp64.c
> @@ -206,7 +206,7 @@ void bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx, u64 fun
> EMIT(PPC_RAW_BCTRL());
> }
>
> -static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out)
> +static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out)
> {
> /*
> * By now, the eBPF program has already setup parameters in r3, r4 and r5
> @@ -267,7 +267,9 @@ static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32
> bpf_jit_emit_common_epilogue(image, ctx);
>
> EMIT(PPC_RAW_BCTR());
> +
> /* out: */
> + return 0;
> }
>
> /* Assemble the body code between the prologue & epilogue */
> @@ -993,7 +995,9 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
> */
> case BPF_JMP | BPF_TAIL_CALL:
> ctx->seen |= SEEN_TAILCALL;
> - bpf_jit_emit_tail_call(image, ctx, addrs[i + 1]);
> + ret = bpf_jit_emit_tail_call(image, ctx, addrs[i + 1]);
> + if (ret < 0)
> + return ret;
> break;
>
> default:
> --
> 2.33.0
>
^ permalink raw reply
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