* Re: clock_gettime64 vdso bug on 32-bit arm, rpi-4
From: Adhemerval Zanella @ 2020-05-19 20:24 UTC (permalink / raw)
To: Arnd Bergmann, Vincenzo Frascino, Russell King - ARM Linux
Cc: Rich Felker, Szabolcs Nagy, Will Deacon,
Linux Kernel Mailing List, Stephen Boyd, Thomas Gleixner,
Jack Schmidt, Linux ARM
In-Reply-To: <CAK8P3a2Tw2w73ZkK-W6AA9veMK4-miLUx-TL1EuOdP7EdW-AmQ@mail.gmail.com>
On 19/05/2020 16:54, Arnd Bergmann wrote:
> Jack Schmidt reported a bug for the arm32 clock_gettimeofday64 vdso call last
> month: https://github.com/richfelker/musl-cross-make/issues/96 and
> https://github.com/raspberrypi/linux/issues/3579
>
> As Will Deacon pointed out, this was never reported on the mailing list,
> so I'll try to summarize what we know, so this can hopefully be resolved soon.
>
> - This happened reproducibly on Linux-5.6 on a 32-bit Raspberry Pi patched
> kernel running on a 64-bit Raspberry Pi 4b (bcm2711) when calling
> clock_gettime64(CLOCK_REALTIME)
Does it happen with other clocks as well?
>
> - The kernel tree is at https://github.com/raspberrypi/linux/, but I could
> see no relevant changes compared to a mainline kernel.
Is this bug reproducible with mainline kernel or mainline kernel can't be
booted on bcm2711?
>
> - From the report, I see that the returned time value is larger than the
> expected time, by 3.4 to 14.5 million seconds in four samples, my
> guess is that a random number gets added in at some point.
What kind code are you using to reproduce it? It is threaded or issue
clock_gettime from signal handlers?
>
> - From other sources, I found that the Raspberry Pi clocksource runs
> at 54 MHz, with a mask value of 0xffffffffffffff. From these numbers
> I would expect that reading a completely random hardware register
> value would result in an offset up to 1.33 billion seconds, which is
> around factor 100 more than the error we see, though similar.
>
> - The test case calls the musl clock_gettime() function, which falls back to
> the clock_gettime64() syscall on kernels prior to 5.5, or to the 32-bit
> clock_gettime() prior to Linux-5.1. As reported in the bug, Linux-4.19 does
> not show the bug.
>
> - The behavior was not reproduced on the same user space in qemu,
> though I cannot tell whether the exact same kernel binary was used.
>
> - glibc-2.31 calls the same clock_gettime64() vdso function on arm to
> implement clock_gettime(), but earlier versions did not. I have not
> seen any reports of this bug, which could be explained by users
> generally being on older versions.
>
> - As far as I can tell, there are no reports of this bug from other users,
> and so far nobody could reproduce it.
>
> - The current musl git tree has been patched to not call clock_gettime64
> on ARM because of this problem, so it cannot be used for reproducing it.
So should glibc follow musl and remove arm clock_gettime6y4 vDSO support
or this bug is localized to an specific kernel version running on an
specific hardware?
>
> If anyone has other information that may help figure out what is going
> on, please share.
>
> Arnd
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] ARM64: dts: imx8mm-evk: Assigned clocks for audio plls
From: Tim Harvey @ 2020-05-19 20:29 UTC (permalink / raw)
To: S.j. Wang
Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, Jacky Bai,
Anson Huang, shawnguo@kernel.org, s.hauer@pengutronix.de,
daniel.lezcano@linaro.org, linux-kernel@vger.kernel.org,
Daniel Baluta, robh+dt@kernel.org, dl-linux-imx,
kernel@pengutronix.de, Leonard Crestez, festevam@gmail.com,
linux-arm-kernel@lists.infradead.org, Jun Li
In-Reply-To: <20191016103513.13088-1-shengjiu.wang@nxp.com>
On Wed, Oct 16, 2019 at 3:36 AM S.j. Wang <shengjiu.wang@nxp.com> wrote:
>
> Assign clocks and clock-rates for audio plls, that audio
> drivers can utilize them.
>
> Add dai-tdm-slot-num and dai-tdm-slot-width for sound-wm8524,
> that sai driver can generate correct bit clock.
>
> Fixes: 13f3b9fdef6c ("arm64: dts: imx8mm-evk: Enable audio codec wm8524")
> Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
> ---
> arch/arm64/boot/dts/freescale/imx8mm-evk.dts | 2 ++
> arch/arm64/boot/dts/freescale/imx8mm.dtsi | 8 ++++++--
> 2 files changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dts b/arch/arm64/boot/dts/freescale/imx8mm-evk.dts
> index f7a15f3904c2..13137451b438 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dts
> +++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dts
> @@ -62,6 +62,8 @@
>
> cpudai: simple-audio-card,cpu {
> sound-dai = <&sai3>;
> + dai-tdm-slot-num = <2>;
> + dai-tdm-slot-width = <32>;
> };
>
Shengjiu,
Can you explain the why dai-tdm-slot-width here is 32? I noticed when
I assigned that for an imx8mm board I'm working on (that uses a
tlv320aic3x codec) I ended up with the clock being off by a factor of
2 (audio playback was 2x too slow).
Best Regards,
Tim
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: clock_gettime64 vdso bug on 32-bit arm, rpi-4
From: Arnd Bergmann @ 2020-05-19 20:31 UTC (permalink / raw)
To: Adhemerval Zanella
Cc: Rich Felker, Szabolcs Nagy, Will Deacon, Russell King - ARM Linux,
Linux Kernel Mailing List, Stephen Boyd, Thomas Gleixner,
Vincenzo Frascino, Jack Schmidt, Linux ARM
In-Reply-To: <0c2abcd1-7da8-2559-1e93-4c3bdd38dec1@linaro.org>
On Tue, May 19, 2020 at 10:24 PM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
> On 19/05/2020 16:54, Arnd Bergmann wrote:
> > Jack Schmidt reported a bug for the arm32 clock_gettimeofday64 vdso call last
> > month: https://github.com/richfelker/musl-cross-make/issues/96 and
> > https://github.com/raspberrypi/linux/issues/3579
> >
> > As Will Deacon pointed out, this was never reported on the mailing list,
> > so I'll try to summarize what we know, so this can hopefully be resolved soon.
> >
> > - This happened reproducibly on Linux-5.6 on a 32-bit Raspberry Pi patched
> > kernel running on a 64-bit Raspberry Pi 4b (bcm2711) when calling
> > clock_gettime64(CLOCK_REALTIME)
>
> Does it happen with other clocks as well?
Unclear.
> > - The kernel tree is at https://github.com/raspberrypi/linux/, but I could
> > see no relevant changes compared to a mainline kernel.
>
> Is this bug reproducible with mainline kernel or mainline kernel can't be
> booted on bcm2711?
Mainline linux-5.6 should boot on that machine but might not have
all the other features, so I think users tend to use the raspberry pi
kernel sources for now.
> > - From the report, I see that the returned time value is larger than the
> > expected time, by 3.4 to 14.5 million seconds in four samples, my
> > guess is that a random number gets added in at some point.
>
> What kind code are you using to reproduce it? It is threaded or issue
> clock_gettime from signal handlers?
The reproducer is very simple without threads or signals,
see the start of https://github.com/richfelker/musl-cross-make/issues/96
It does rely on calling into the musl wrapper, not the direct vdso
call.
> > - From other sources, I found that the Raspberry Pi clocksource runs
> > at 54 MHz, with a mask value of 0xffffffffffffff. From these numbers
> > I would expect that reading a completely random hardware register
> > value would result in an offset up to 1.33 billion seconds, which is
> > around factor 100 more than the error we see, though similar.
> >
> > - The test case calls the musl clock_gettime() function, which falls back to
> > the clock_gettime64() syscall on kernels prior to 5.5, or to the 32-bit
> > clock_gettime() prior to Linux-5.1. As reported in the bug, Linux-4.19 does
> > not show the bug.
> >
> > - The behavior was not reproduced on the same user space in qemu,
> > though I cannot tell whether the exact same kernel binary was used.
> >
> > - glibc-2.31 calls the same clock_gettime64() vdso function on arm to
> > implement clock_gettime(), but earlier versions did not. I have not
> > seen any reports of this bug, which could be explained by users
> > generally being on older versions.
> >
> > - As far as I can tell, there are no reports of this bug from other users,
> > and so far nobody could reproduce it.
> >
> > - The current musl git tree has been patched to not call clock_gettime64
> > on ARM because of this problem, so it cannot be used for reproducing it.
>
> So should glibc follow musl and remove arm clock_gettime6y4 vDSO support
> or this bug is localized to an specific kernel version running on an
> specific hardware?
I hope we can figure out what is actually going on soon, there is probably
no need to change glibc before we have.
Arnd
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH 06/15] PCI: brcmstb: Asserting PERST is different for 7278
From: Jim Quinlan @ 2020-05-19 20:34 UTC (permalink / raw)
To: james.quinlan, Nicolas Saenz Julienne
Cc: Rob Herring, Lorenzo Pieralisi,
open list:PCI NATIVE HOST BRIDGE AND ENDPOINT DRIVERS, open list,
Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE,
Jim Quinlan, Bjorn Helgaas,
moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE
In-Reply-To: <20200519203419.12369-1-james.quinlan@broadcom.com>
From: Jim Quinlan <jquinlan@broadcom.com>
The PERST bit was moved to a different register in 7278-type
STB chips. In addition, the polarity of the bit was also
changed; for other chips writing a 1 specified assert; for
7278-type chips, writing a 0 specifies assert.
Signal-wise, PERST is an asserted-low signal.
Signed-off-by: Jim Quinlan <jquinlan@broadcom.com>
---
drivers/pci/controller/pcie-brcmstb.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index 39993203b991..2c470104ba38 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -81,6 +81,7 @@
#define PCIE_MISC_PCIE_CTRL 0x4064
#define PCIE_MISC_PCIE_CTRL_PCIE_L23_REQUEST_MASK 0x1
+#define PCIE_MISC_PCIE_CTRL_PCIE_PERSTB_MASK 0x4
#define PCIE_MISC_PCIE_STATUS 0x4068
#define PCIE_MISC_PCIE_STATUS_PCIE_PORT_MASK 0x80
@@ -679,9 +680,17 @@ static inline void brcm_pcie_perst_set(struct brcm_pcie *pcie, u32 val)
{
u32 tmp;
- tmp = readl(pcie->base + PCIE_RGR1_SW_INIT_1(pcie));
- u32p_replace_bits(&tmp, val, PCIE_RGR1_SW_INIT_1_PERST_MASK);
- writel(tmp, pcie->base + PCIE_RGR1_SW_INIT_1(pcie));
+ if (pcie->type == BCM7278) {
+ /* Perst bit has moved and assert value is 0 */
+ tmp = readl(pcie->base + PCIE_MISC_PCIE_CTRL);
+ u32p_replace_bits(&tmp,
+ !val, PCIE_MISC_PCIE_CTRL_PCIE_PERSTB_MASK);
+ writel(tmp, pcie->base + PCIE_MISC_PCIE_CTRL);
+ } else {
+ tmp = readl(pcie->base + PCIE_RGR1_SW_INIT_1(pcie));
+ u32p_replace_bits(&tmp, val, PCIE_RGR1_SW_INIT_1_PERST_MASK);
+ writel(tmp, pcie->base + PCIE_RGR1_SW_INIT_1(pcie));
+ }
}
static inline int brcm_pcie_get_rc_bar2_size_and_offset(struct brcm_pcie *pcie,
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 03/15] dt-bindings: PCI: Add bindings for more Brcmstb chips
From: Jim Quinlan @ 2020-05-19 20:34 UTC (permalink / raw)
To: james.quinlan, Nicolas Saenz Julienne
Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
Florian Fainelli, open list:PCI SUBSYSTEM, open list, Rob Herring,
maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE,
Jim Quinlan, Bjorn Helgaas,
moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE
In-Reply-To: <20200519203419.12369-1-james.quinlan@broadcom.com>
From: Jim Quinlan <jquinlan@broadcom.com>
- Add compatible strings for three more Broadcom STB chips:
7278, 7216, 7211 (STB version of RPi4).
- add new property 'brcm,scb-sizes'
- add new property 'resets'
- add new property 'reset-names'
- allow 'ranges' and 'dma-ranges' to have more than one item
and update the example to show this.
Signed-off-by: Jim Quinlan <jquinlan@broadcom.com>
---
.../bindings/pci/brcm,stb-pcie.yaml | 40 +++++++++++++++++--
1 file changed, 36 insertions(+), 4 deletions(-)
diff --git a/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml b/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
index 8680a0f86c5a..66a7df45983d 100644
--- a/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
@@ -14,7 +14,13 @@ allOf:
properties:
compatible:
- const: brcm,bcm2711-pcie # The Raspberry Pi 4
+ items:
+ - enum:
+ - brcm,bcm2711-pcie # The Raspberry Pi 4
+ - brcm,bcm7211-pcie # Broadcom STB version of RPi4
+ - brcm,bcm7278-pcie # Broadcom 7278 Arm
+ - brcm,bcm7216-pcie # Broadcom 7216 Arm
+ - brcm,bcm7445-pcie # Broadcom 7445 Arm
reg:
maxItems: 1
@@ -34,10 +40,12 @@ properties:
- const: msi
ranges:
- maxItems: 1
+ minItems: 1
+ maxItems: 4
dma-ranges:
- maxItems: 1
+ minItems: 1
+ maxItems: 6
clocks:
maxItems: 1
@@ -58,8 +66,30 @@ properties:
aspm-no-l0s: true
+ resets:
+ description: for "brcm,bcm7216-pcie", must be a valid reset
+ phandle pointing to the RESCAL reset controller provider node.
+ $ref: "/schemas/types.yaml#/definitions/phandle"
+
+ reset-names:
+ items:
+ - const: rescal
+
+ brcm,scb-sizes:
+ description: (u32, u32) tuple giving the 64bit PCIe memory
+ viewport size of a memory controller. There may be up to
+ three controllers, and each size must be a power of two
+ with a size greater or equal to the amount of memory the
+ controller supports.
+ allOf:
+ - $ref: /schemas/types.yaml#/definitions/uint32-array
+ - items:
+ minItems: 2
+ maxItems: 6
+
required:
- reg
+ - ranges
- dma-ranges
- "#interrupt-cells"
- interrupts
@@ -93,7 +123,9 @@ examples:
msi-parent = <&pcie0>;
msi-controller;
ranges = <0x02000000 0x0 0xf8000000 0x6 0x00000000 0x0 0x04000000>;
- dma-ranges = <0x02000000 0x0 0x00000000 0x0 0x00000000 0x0 0x80000000>;
+ dma-ranges = <0x42000000 0x1 0x00000000 0x0 0x40000000 0x0 0x80000000>,
+ <0x42000000 0x1 0x80000000 0x3 0x00000000 0x0 0x80000000>;
brcm,enable-ssc;
+ brcm,scb-sizes = <0x0 0x80000000 0x0 0x80000000>;
};
};
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 05/15] PCI: brcmstb: Add suspend and resume pm_ops
From: Jim Quinlan @ 2020-05-19 20:34 UTC (permalink / raw)
To: james.quinlan, Nicolas Saenz Julienne
Cc: Rob Herring, Lorenzo Pieralisi,
open list:PCI NATIVE HOST BRIDGE AND ENDPOINT DRIVERS, open list,
Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE,
Jim Quinlan, Bjorn Helgaas,
moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE
In-Reply-To: <20200519203419.12369-1-james.quinlan@broadcom.com>
From: Jim Quinlan <jquinlan@broadcom.com>
Broadcom Set-top (BrcmSTB) boards typically support S2, S3,
and S5 suspend and resume. This commit enables the PCIe
driver to do so.
Signed-off-by: Jim Quinlan <jquinlan@broadcom.com>
---
drivers/pci/controller/pcie-brcmstb.c | 49 +++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index c1cf4ea7d3d9..39993203b991 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -972,6 +972,49 @@ static void brcm_pcie_turn_off(struct brcm_pcie *pcie)
brcm_pcie_bridge_sw_init_set(pcie, 1);
}
+static int brcm_pcie_suspend(struct device *dev)
+{
+ struct brcm_pcie *pcie = dev_get_drvdata(dev);
+ int ret = 0;
+
+ brcm_pcie_turn_off(pcie);
+ clk_disable_unprepare(pcie->clk);
+
+ return ret;
+}
+
+static int brcm_pcie_resume(struct device *dev)
+{
+ struct brcm_pcie *pcie = dev_get_drvdata(dev);
+ void __iomem *base;
+ u32 tmp;
+ int ret;
+
+ base = pcie->base;
+ clk_prepare_enable(pcie->clk);
+
+ /* Take bridge out of reset so we can access the SERDES reg */
+ brcm_pcie_bridge_sw_init_set(pcie, 0);
+
+ /* SERDES_IDDQ = 0 */
+ tmp = readl(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
+ u32p_replace_bits(&tmp, 0,
+ PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK);
+ writel(tmp, base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
+
+ /* wait for serdes to be stable */
+ udelay(100);
+
+ ret = brcm_pcie_setup(pcie);
+ if (ret)
+ return ret;
+
+ if (pcie->msi)
+ brcm_msi_set_regs(pcie->msi);
+
+ return 0;
+}
+
static void __brcm_pcie_remove(struct brcm_pcie *pcie)
{
brcm_msi_remove(pcie);
@@ -1090,12 +1133,18 @@ static int brcm_pcie_probe(struct platform_device *pdev)
MODULE_DEVICE_TABLE(of, brcm_pcie_match);
+static const struct dev_pm_ops brcm_pcie_pm_ops = {
+ .suspend_noirq = brcm_pcie_suspend,
+ .resume_noirq = brcm_pcie_resume,
+};
+
static struct platform_driver brcm_pcie_driver = {
.probe = brcm_pcie_probe,
.remove = brcm_pcie_remove,
.driver = {
.name = "brcm-pcie",
.of_match_table = brcm_pcie_match,
+ .pm = &brcm_pcie_pm_ops,
},
};
module_platform_driver(brcm_pcie_driver);
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 04/15] PCI: brcmstb: Add compatibily of other chips
From: Jim Quinlan @ 2020-05-19 20:34 UTC (permalink / raw)
To: james.quinlan, Nicolas Saenz Julienne
Cc: Rob Herring, Lorenzo Pieralisi,
open list:PCI NATIVE HOST BRIDGE AND ENDPOINT DRIVERS, open list,
Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE,
Jim Quinlan, Bjorn Helgaas,
moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE
In-Reply-To: <20200519203419.12369-1-james.quinlan@broadcom.com>
From: Jim Quinlan <jquinlan@broadcom.com>
Add in compatibility strings and code for three Broadcom STB chips.
Some of the register locations, shifts, and masks are different
for certain chips, requiring the use of different constants based
on of_id.
We would like to add the following at this time to the match list
but we need to wait until the end of this patchset so that
everything works.
{ .compatible = "brcm,bcm7211-pcie", .data = &generic_cfg },
{ .compatible = "brcm,bcm7278-pcie", .data = &bcm7278_cfg },
{ .compatible = "brcm,bcm7216-pcie", .data = &bcm7278_cfg },
{ .compatible = "brcm,bcm7445-pcie", .data = &generic_cfg },
Signed-off-by: Jim Quinlan <jquinlan@broadcom.com>
---
drivers/pci/controller/pcie-brcmstb.c | 103 +++++++++++++++++++++++---
1 file changed, 91 insertions(+), 12 deletions(-)
diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index 73020b4ff090..c1cf4ea7d3d9 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -120,9 +120,8 @@
#define PCIE_EXT_SLOT_SHIFT 15
#define PCIE_EXT_FUNC_SHIFT 12
-#define PCIE_RGR1_SW_INIT_1 0x9210
#define PCIE_RGR1_SW_INIT_1_PERST_MASK 0x1
-#define PCIE_RGR1_SW_INIT_1_INIT_MASK 0x2
+#define PCIE_RGR1_SW_INIT_1_PERST_SHIFT 0x0
/* PCIe parameters */
#define BRCM_NUM_PCIE_OUT_WINS 0x4
@@ -152,6 +151,69 @@
#define SSC_STATUS_SSC_MASK 0x400
#define SSC_STATUS_PLL_LOCK_MASK 0x800
+#define IDX_ADDR(pcie) \
+ (pcie->reg_offsets[EXT_CFG_INDEX])
+#define DATA_ADDR(pcie) \
+ (pcie->reg_offsets[EXT_CFG_DATA])
+#define PCIE_RGR1_SW_INIT_1(pcie) \
+ (pcie->reg_offsets[RGR1_SW_INIT_1])
+
+enum {
+ RGR1_SW_INIT_1,
+ EXT_CFG_INDEX,
+ EXT_CFG_DATA,
+};
+
+enum {
+ RGR1_SW_INIT_1_INIT_MASK,
+ RGR1_SW_INIT_1_INIT_SHIFT,
+};
+
+enum pcie_type {
+ GENERIC,
+ BCM7278,
+};
+
+struct pcie_cfg_data {
+ const int *reg_field_info;
+ const int *offsets;
+ const enum pcie_type type;
+};
+
+static const int pcie_reg_field_info[] = {
+ [RGR1_SW_INIT_1_INIT_MASK] = 0x2,
+ [RGR1_SW_INIT_1_INIT_SHIFT] = 0x1,
+};
+
+static const int pcie_reg_field_info_bcm7278[] = {
+ [RGR1_SW_INIT_1_INIT_MASK] = 0x1,
+ [RGR1_SW_INIT_1_INIT_SHIFT] = 0x0,
+};
+
+static const int pcie_offsets[] = {
+ [RGR1_SW_INIT_1] = 0x9210,
+ [EXT_CFG_INDEX] = 0x9000,
+ [EXT_CFG_DATA] = 0x9004,
+};
+
+static const struct pcie_cfg_data generic_cfg = {
+ .reg_field_info = pcie_reg_field_info,
+ .offsets = pcie_offsets,
+ .type = GENERIC,
+};
+
+static const int pcie_offset_bcm7278[] = {
+ [RGR1_SW_INIT_1] = 0xc010,
+ [EXT_CFG_INDEX] = 0x9000,
+ [EXT_CFG_DATA] = 0x9004,
+};
+
+static const struct pcie_cfg_data bcm7278_cfg = {
+ .reg_field_info = pcie_reg_field_info_bcm7278,
+ .offsets = pcie_offset_bcm7278,
+ .type = BCM7278,
+};
+
struct brcm_msi {
struct device *dev;
void __iomem *base;
@@ -176,6 +238,9 @@ struct brcm_pcie {
int gen;
u64 msi_target_addr;
struct brcm_msi *msi;
+ const int *reg_offsets;
+ const int *reg_field_info;
+ enum pcie_type type;
};
/*
@@ -602,20 +667,21 @@ static struct pci_ops brcm_pcie_ops = {
static inline void brcm_pcie_bridge_sw_init_set(struct brcm_pcie *pcie, u32 val)
{
- u32 tmp;
+ u32 tmp, mask = pcie->reg_field_info[RGR1_SW_INIT_1_INIT_MASK];
+ u32 shift = pcie->reg_field_info[RGR1_SW_INIT_1_INIT_SHIFT];
- tmp = readl(pcie->base + PCIE_RGR1_SW_INIT_1);
- u32p_replace_bits(&tmp, val, PCIE_RGR1_SW_INIT_1_INIT_MASK);
- writel(tmp, pcie->base + PCIE_RGR1_SW_INIT_1);
+ tmp = readl(pcie->base + PCIE_RGR1_SW_INIT_1(pcie));
+ tmp = (tmp & ~mask) | ((val << shift) & mask);
+ writel(tmp, pcie->base + PCIE_RGR1_SW_INIT_1(pcie));
}
static inline void brcm_pcie_perst_set(struct brcm_pcie *pcie, u32 val)
{
u32 tmp;
- tmp = readl(pcie->base + PCIE_RGR1_SW_INIT_1);
+ tmp = readl(pcie->base + PCIE_RGR1_SW_INIT_1(pcie));
u32p_replace_bits(&tmp, val, PCIE_RGR1_SW_INIT_1_PERST_MASK);
- writel(tmp, pcie->base + PCIE_RGR1_SW_INIT_1);
+ writel(tmp, pcie->base + PCIE_RGR1_SW_INIT_1(pcie));
}
static inline int brcm_pcie_get_rc_bar2_size_and_offset(struct brcm_pcie *pcie,
@@ -924,10 +990,17 @@ static int brcm_pcie_remove(struct platform_device *pdev)
return 0;
}
+static const struct of_device_id brcm_pcie_match[] = {
+ { .compatible = "brcm,bcm2711-pcie", .data = &generic_cfg },
+ {},
+};
+
static int brcm_pcie_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node, *msi_np;
struct pci_host_bridge *bridge;
+ const struct pcie_cfg_data *data;
+ const struct of_device_id *of_id;
struct brcm_pcie *pcie;
struct pci_bus *child;
struct resource *res;
@@ -937,9 +1010,19 @@ static int brcm_pcie_probe(struct platform_device *pdev)
if (!bridge)
return -ENOMEM;
+ of_id = of_match_node(brcm_pcie_match, np);
+ if (!of_id) {
+ pr_err("failed to look up compatible string\n");
+ return -EINVAL;
+ }
+ data = of_id->data;
+
pcie = pci_host_bridge_priv(bridge);
pcie->dev = &pdev->dev;
pcie->np = np;
+ pcie->reg_offsets = data->offsets;
+ pcie->reg_field_info = data->reg_field_info;
+ pcie->type = data->type;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pcie->base = devm_ioremap_resource(&pdev->dev, res);
@@ -1005,10 +1088,6 @@ static int brcm_pcie_probe(struct platform_device *pdev)
return ret;
}
-static const struct of_device_id brcm_pcie_match[] = {
- { .compatible = "brcm,bcm2711-pcie" },
- {},
-};
MODULE_DEVICE_TABLE(of, brcm_pcie_match);
static struct platform_driver brcm_pcie_driver = {
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 00/15] PCI: brcmstb: enable PCIe for STB chips
From: Jim Quinlan @ 2020-05-19 20:33 UTC (permalink / raw)
To: james.quinlan, Nicolas Saenz Julienne
Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE, Ulf Hansson,
Heikki Krogerus, Saravana Kannan, Rob Herring, Greg Kroah-Hartman,
Rafael J. Wysocki, Suzuki K Poulose, Julien Grall, open list,
open list:LIBATA SUBSYSTEM Serial and Parallel ATA drivers,
open list:DMA MAPPING HELPERS, Stefano Stabellini,
open list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE,
moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE,
open list:PCI NATIVE HOST BRIDGE AND ENDPOINT DRIVERS,
Dan Williams, Robin Murphy, moderated list:ARM PORT
This patchset expands the usefulness of the Broadcom Settop Box PCIe
controller by building upon the PCIe driver used currently by the
Raspbery Pi. Other forms of this patchset were submitted by me years
ago and not accepted; the major sticking point was the code required
for the DMA remapping needed for the PCIe driver to work [1].
There have been many changes to the DMA and OF subsystems since that
time, making a cleaner and less intrusive patchset possible. This
patchset implements a generalization of "dev->dma_pfn_offset", except
that instead of a single scalar offset it provides for multiple
offsets via a function which depends upon the "dma-ranges" property of
the PCIe host controller. This is required for proper functionality
of the BrcmSTB PCIe controller and possibly some other devices.
[1] https://lore.kernel.org/linux-arm-kernel/1516058925-46522-5-git-send-email-jim2101024@gmail.com/
Jim Quinlan (15):
PCI: brcmstb: PCIE_BRCMSTB depends on ARCH_BRCMSTB
ahci_brcm: fix use of BCM7216 reset controller
dt-bindings: PCI: Add bindings for more Brcmstb chips
PCI: brcmstb: Add compatibily of other chips
PCI: brcmstb: Add suspend and resume pm_ops
PCI: brcmstb: Asserting PERST is different for 7278
PCI: brcmstb: Add control of rescal reset
of: Include a dev param in of_dma_get_range()
device core: Add ability to handle multiple dma offsets
dma-direct: Invoke dma offset func if needed
arm: dma-mapping: Invoke dma offset func if needed
PCI: brcmstb: Set internal memory viewport sizes
PCI: brcmstb: Accommodate MSI for older chips
PCI: brcmstb: Set bus max burst side by chip type
PCI: brcmstb: add compatilbe chips to match list
.../bindings/pci/brcm,stb-pcie.yaml | 40 +-
arch/arm/include/asm/dma-mapping.h | 17 +-
drivers/ata/ahci_brcm.c | 14 +-
drivers/of/address.c | 54 ++-
drivers/of/device.c | 2 +-
drivers/of/of_private.h | 8 +-
drivers/pci/controller/Kconfig | 4 +-
drivers/pci/controller/pcie-brcmstb.c | 403 +++++++++++++++---
include/linux/device.h | 9 +-
include/linux/dma-direct.h | 16 +
include/linux/dma-mapping.h | 44 ++
kernel/dma/Kconfig | 12 +
12 files changed, 542 insertions(+), 81 deletions(-)
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH 07/15] PCI: brcmstb: Add control of rescal reset
From: Jim Quinlan @ 2020-05-19 20:34 UTC (permalink / raw)
To: james.quinlan, Nicolas Saenz Julienne
Cc: Rob Herring, Lorenzo Pieralisi, Philipp Zabel,
open list:PCI NATIVE HOST BRIDGE AND ENDPOINT DRIVERS, open list,
Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE,
Jim Quinlan, Bjorn Helgaas,
moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE
In-Reply-To: <20200519203419.12369-1-james.quinlan@broadcom.com>
From: Jim Quinlan <jquinlan@broadcom.com>
Some STB chips have a special purpose reset controller named
RESCAL (reset calibration). This commit adds the control
of RESCAL as well as the ability to start and stop its
operation for PCIe HW.
Signed-off-by: Jim Quinlan <jquinlan@broadcom.com>
---
drivers/pci/controller/pcie-brcmstb.c | 81 ++++++++++++++++++++++++++-
1 file changed, 80 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index 2c470104ba38..0787e8f6f7e5 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -23,6 +23,7 @@
#include <linux/of_platform.h>
#include <linux/pci.h>
#include <linux/printk.h>
+#include <linux/reset.h>
#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/string.h>
@@ -152,7 +153,17 @@
#define SSC_STATUS_SSC_MASK 0x400
#define SSC_STATUS_PLL_LOCK_MASK 0x800
-#define IDX_ADDR(pcie) \
+/* Rescal registers */
+#define PCIE_DVT_PMU_PCIE_PHY_CTRL 0xc700
+#define PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_NFLDS 0x3
+#define PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_DIG_RESET_MASK 0x4
+#define PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_DIG_RESET_SHIFT 0x2
+#define PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_RESET_MASK 0x2
+#define PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_RESET_SHIFT 0x1
+#define PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_PWRDN_MASK 0x1
+#define PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_PWRDN_SHIFT 0x0
+
+#define IDX_ADDR(pcie) \
(pcie->reg_offsets[EXT_CFG_INDEX])
#define DATA_ADDR(pcie) \
(pcie->reg_offsets[EXT_CFG_DATA])
@@ -242,6 +253,7 @@ struct brcm_pcie {
const int *reg_offsets;
const int *reg_field_info;
enum pcie_type type;
+ struct reset_control *rescal;
};
/*
@@ -957,6 +969,47 @@ static void brcm_pcie_enter_l23(struct brcm_pcie *pcie)
dev_err(pcie->dev, "failed to enter low-power link state\n");
}
+static int brcm_phy_cntl(struct brcm_pcie *pcie, const int start)
+{
+ static const u32 shifts[PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_NFLDS] = {
+ PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_PWRDN_SHIFT,
+ PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_RESET_SHIFT,
+ PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_DIG_RESET_SHIFT,};
+ static const u32 masks[PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_NFLDS] = {
+ PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_PWRDN_MASK,
+ PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_RESET_MASK,
+ PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_DIG_RESET_MASK,};
+ const int beg = start ? 0 : PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_NFLDS - 1;
+ const int end = start ? PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_NFLDS : -1;
+ u32 tmp, combined_mask = 0;
+ u32 val = !!start;
+ void __iomem *base = pcie->base;
+ int i;
+
+ for (i = beg; i != end; start ? i++ : i--) {
+ tmp = readl(base + PCIE_DVT_PMU_PCIE_PHY_CTRL);
+ tmp = (tmp & ~masks[i]) | ((val << shifts[i]) & masks[i]);
+ writel(tmp, base + PCIE_DVT_PMU_PCIE_PHY_CTRL);
+ usleep_range(50, 200);
+ combined_mask |= masks[i];
+ }
+
+ tmp = readl(base + PCIE_DVT_PMU_PCIE_PHY_CTRL);
+ val = start ? combined_mask : 0;
+
+ return (tmp & combined_mask) == val ? 0 : -EIO;
+}
+
+static inline int brcm_phy_start(struct brcm_pcie *pcie)
+{
+ return pcie->rescal ? brcm_phy_cntl(pcie, 1) : 0;
+}
+
+static inline int brcm_phy_stop(struct brcm_pcie *pcie)
+{
+ return pcie->rescal ? brcm_phy_cntl(pcie, 0) : 0;
+}
+
static void brcm_pcie_turn_off(struct brcm_pcie *pcie)
{
void __iomem *base = pcie->base;
@@ -987,6 +1040,9 @@ static int brcm_pcie_suspend(struct device *dev)
int ret = 0;
brcm_pcie_turn_off(pcie);
+ ret = brcm_phy_stop(pcie);
+ if (ret)
+ dev_err(pcie->dev, "failed to stop phy\n");
clk_disable_unprepare(pcie->clk);
return ret;
@@ -1002,6 +1058,12 @@ static int brcm_pcie_resume(struct device *dev)
base = pcie->base;
clk_prepare_enable(pcie->clk);
+ ret = brcm_phy_start(pcie);
+ if (ret) {
+ dev_err(pcie->dev, "failed to start phy\n");
+ return ret;
+ }
+
/* Take bridge out of reset so we can access the SERDES reg */
brcm_pcie_bridge_sw_init_set(pcie, 0);
@@ -1028,6 +1090,8 @@ static void __brcm_pcie_remove(struct brcm_pcie *pcie)
{
brcm_msi_remove(pcie);
brcm_pcie_turn_off(pcie);
+ if (brcm_phy_stop(pcie))
+ dev_err(pcie->dev, "failed to stop phy\n");
clk_disable_unprepare(pcie->clk);
}
@@ -1100,6 +1164,21 @@ static int brcm_pcie_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "could not enable clock\n");
return ret;
}
+ pcie->rescal = devm_reset_control_get_shared(&pdev->dev, "rescal");
+ if (IS_ERR(pcie->rescal)) {
+ if (PTR_ERR(pcie->rescal) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ pcie->rescal = NULL;
+ } else {
+ ret = reset_control_deassert(pcie->rescal);
+ if (ret)
+ dev_err(&pdev->dev, "failed to deassert 'rescal'\n");
+ }
+ ret = brcm_phy_start(pcie);
+ if (ret) {
+ dev_err(pcie->dev, "failed to start phy\n");
+ return ret;
+ }
ret = brcm_pcie_setup(pcie);
if (ret)
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 11/15] arm: dma-mapping: Invoke dma offset func if needed
From: Jim Quinlan @ 2020-05-19 20:34 UTC (permalink / raw)
To: james.quinlan, Nicolas Saenz Julienne
Cc: Ulf Hansson, Stefano Stabellini, Russell King, open list,
Julien Grall, moderated list:ARM PORT
In-Reply-To: <20200519203419.12369-1-james.quinlan@broadcom.com>
Just like dma_pfn_offset, another offset is added to
the dma/phys translation if there happen to be multiple
regions that have different mapping offsets.
Signed-off-by: Jim Quinlan <james.quinlan@broadcom.com>
---
arch/arm/include/asm/dma-mapping.h | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index bdd80ddbca34..f0c0a1fa9ac0 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -35,8 +35,14 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
#ifndef __arch_pfn_to_dma
static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn)
{
- if (dev)
+ if (dev) {
+#ifdef CONFIG_DMA_PFN_OFFSET_MAP
+ if (unlikely(dev->dma_offset_map))
+ pfn -= dma_pfn_offset_frm_phys_addr(
+ dev->dma_offset_map, PFN_PHYS(pfn));
+#endif
pfn -= dev->dma_pfn_offset;
+ }
return (dma_addr_t)__pfn_to_bus(pfn);
}
@@ -44,9 +50,14 @@ static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr)
{
unsigned long pfn = __bus_to_pfn(addr);
- if (dev)
+ if (dev) {
+#ifdef CONFIG_DMA_PFN_OFFSET_MAP
+ if (unlikely(dev->dma_offset_map))
+ pfn += dma_pfn_offset_frm_dma_addr(
+ dev->dma_offset_map, addr);
+#endif
pfn += dev->dma_pfn_offset;
-
+ }
return pfn;
}
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 15/15] PCI: brcmstb: add compatilbe chips to match list
From: Jim Quinlan @ 2020-05-19 20:34 UTC (permalink / raw)
To: james.quinlan, Nicolas Saenz Julienne
Cc: Rob Herring, Lorenzo Pieralisi,
open list:PCI NATIVE HOST BRIDGE AND ENDPOINT DRIVERS, open list,
Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE,
Bjorn Helgaas,
moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE
In-Reply-To: <20200519203419.12369-1-james.quinlan@broadcom.com>
Now that the support is in place with previous commits, we add several
chips that use the BrcmSTB driver.
Signed-off-by: Jim Quinlan <james.quinlan@broadcom.com>
---
drivers/pci/controller/pcie-brcmstb.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index 0dfa1bbd9764..ccb88ed763bb 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -1180,6 +1180,10 @@ static int brcm_pcie_remove(struct platform_device *pdev)
static const struct of_device_id brcm_pcie_match[] = {
{ .compatible = "brcm,bcm2711-pcie", .data = &generic_cfg },
+ { .compatible = "brcm,bcm7211-pcie", .data = &generic_cfg },
+ { .compatible = "brcm,bcm7278-pcie", .data = &bcm7278_cfg },
+ { .compatible = "brcm,bcm7216-pcie", .data = &bcm7278_cfg },
+ { .compatible = "brcm,bcm7445-pcie", .data = &generic_cfg },
{},
};
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 14/15] PCI: brcmstb: Set bus max burst side by chip type
From: Jim Quinlan @ 2020-05-19 20:34 UTC (permalink / raw)
To: james.quinlan, Nicolas Saenz Julienne
Cc: Rob Herring, Lorenzo Pieralisi,
open list:PCI NATIVE HOST BRIDGE AND ENDPOINT DRIVERS, open list,
Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE,
Jim Quinlan, Bjorn Helgaas,
moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE
In-Reply-To: <20200519203419.12369-1-james.quinlan@broadcom.com>
From: Jim Quinlan <jquinlan@broadcom.com>
The proper value of the parameter SCB_MAX_BURST_SIZE varies
per chip. The 2711 family requires 128B whereas other devices
can employ 512. The assignment is complicated by the fact
that the values for this two-bit field have different meanings;
Value Type_Generic Type_7278
00 Reserved 128B
01 128B 256B
10 256B 512B
11 512B Reserved
Signed-off-by: Jim Quinlan <jquinlan@broadcom.com>
---
drivers/pci/controller/pcie-brcmstb.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index 7bf945efd71b..0dfa1bbd9764 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -53,7 +53,7 @@
#define PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK 0x1000
#define PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK 0x2000
#define PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK 0x300000
-#define PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_128 0x0
+
#define PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK 0xf8000000
#define PCIE_MISC_MISC_CTRL_SCB1_SIZE_MASK 0x07c00000
#define PCIE_MISC_MISC_CTRL_SCB2_SIZE_MASK 0x0000001f
@@ -276,6 +276,7 @@ struct brcm_pcie {
int num_memc;
u64 memc_size[PCIE_BRCM_MAX_MEMC];
u32 hw_rev;
+ const struct of_device_id *of_id;
};
/*
@@ -841,7 +842,7 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie)
int num_out_wins = 0;
u16 nlw, cls, lnksta;
int i, ret, memc;
- u32 tmp, aspm_support;
+ u32 tmp, burst, aspm_support;
/* Reset the bridge */
brcm_pcie_bridge_sw_init_set(pcie, 1);
@@ -857,10 +858,20 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie)
/* Wait for SerDes to be stable */
usleep_range(100, 200);
+ /*
+ * SCB_MAX_BURST_SIZE is a two bit field. For GENERIC chips it
+ * is encoded as 0=128, 1=256, 2=512, 3=Rsvd, for BCM7278 it
+ * is encoded as 0=Rsvd, 1=128, 2=256, 3=512.
+ */
+ if (strcmp(pcie->of_id->compatible, "brcm,bcm2711-pcie") == 0)
+ burst = 0x0; /* 128B */
+ else
+ burst = (pcie->type == BCM7278) ? 0x3 : 0x2; /* 512 bytes */
+
/* Set SCB_MAX_BURST_SIZE, CFG_READ_UR_MODE, SCB_ACCESS_EN */
u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK);
u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK);
- u32p_replace_bits(&tmp, PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_128,
+ u32p_replace_bits(&tmp, burst,
PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK);
writel(tmp, base + PCIE_MISC_MISC_CTRL);
@@ -1200,6 +1211,7 @@ static int brcm_pcie_probe(struct platform_device *pdev)
pcie->reg_offsets = data->offsets;
pcie->reg_field_info = data->reg_field_info;
pcie->type = data->type;
+ pcie->of_id = of_id;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pcie->base = devm_ioremap_resource(&pdev->dev, res);
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 13/15] PCI: brcmstb: Accommodate MSI for older chips
From: Jim Quinlan @ 2020-05-19 20:34 UTC (permalink / raw)
To: james.quinlan, Nicolas Saenz Julienne
Cc: Rob Herring, Lorenzo Pieralisi,
open list:PCI NATIVE HOST BRIDGE AND ENDPOINT DRIVERS, open list,
Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE,
Jim Quinlan, Bjorn Helgaas,
moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE
In-Reply-To: <20200519203419.12369-1-james.quinlan@broadcom.com>
From: Jim Quinlan <jquinlan@broadcom.com>
Older BrcmSTB chips do not have a separate register for MSI
interrupts; the MSIs are in a register that also contains
unrelated interrupts. In addition, the interrupts lie in
bits [31..24] for these legacy chips. This commit provides
commont code for both legacy and non-legacy MSI interrupt
registers.
Signed-off-by: Jim Quinlan <jquinlan@broadcom.com>
---
drivers/pci/controller/pcie-brcmstb.c | 72 +++++++++++++++++++--------
1 file changed, 52 insertions(+), 20 deletions(-)
diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index 532f2bc76202..7bf945efd71b 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -80,7 +80,8 @@
#define PCIE_MISC_MSI_BAR_CONFIG_HI 0x4048
#define PCIE_MISC_MSI_DATA_CONFIG 0x404c
-#define PCIE_MISC_MSI_DATA_CONFIG_VAL 0xffe06540
+#define PCIE_MISC_MSI_DATA_CONFIG_VAL_32 0xffe06540
+#define PCIE_MISC_MSI_DATA_CONFIG_VAL_8 0xfff86540
#define PCIE_MISC_PCIE_CTRL 0x4064
#define PCIE_MISC_PCIE_CTRL_PCIE_L23_REQUEST_MASK 0x1
@@ -92,6 +93,9 @@
#define PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK 0x10
#define PCIE_MISC_PCIE_STATUS_PCIE_LINK_IN_L23_MASK 0x40
+#define PCIE_MISC_REVISION 0x406c
+#define BRCM_PCIE_HW_REV_33 0x0303
+
#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT 0x4070
#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK 0xfff00000
#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK 0xfff0
@@ -112,10 +116,14 @@
#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK 0x2
#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x08000000
-#define PCIE_MSI_INTR2_STATUS 0x4500
-#define PCIE_MSI_INTR2_CLR 0x4508
-#define PCIE_MSI_INTR2_MASK_SET 0x4510
-#define PCIE_MSI_INTR2_MASK_CLR 0x4514
+
+#define PCIE_INTR2_CPU_BASE 0x4300
+#define PCIE_MSI_INTR2_BASE 0x4500
+/* Offsets from PCIE_INTR2_CPU_BASE and PCIE_MSI_INTR2_BASE */
+#define MSI_INT_STATUS 0x0
+#define MSI_INT_CLR 0x8
+#define MSI_INT_MASK_SET 0x10
+#define MSI_INT_MASK_CLR 0x14
#define PCIE_EXT_CFG_DATA 0x8000
@@ -130,6 +138,8 @@
/* PCIe parameters */
#define BRCM_NUM_PCIE_OUT_WINS 0x4
#define BRCM_INT_PCI_MSI_NR 32
+#define BRCM_INT_PCI_MSI_LEGACY_NR 8
+#define BRCM_INT_PCI_MSI_SHIFT 0
/* MSI target adresses */
#define BRCM_MSI_TARGET_ADDR_LT_4GB 0x0fffffffcULL
@@ -240,6 +250,12 @@ struct brcm_msi {
int irq;
/* used indicates which MSI interrupts have been alloc'd */
unsigned long used;
+ bool legacy;
+ /* Some chips have MSIs in bits [31..24] of a shared register. */
+ int legacy_shift;
+ int nr; /* No. of MSI available, depends on chip */
+ /* This is the base pointer for interrupt status/set/clr regs */
+ void __iomem *intr_base;
};
/* Internal PCIe Host Controller Information.*/
@@ -259,6 +275,7 @@ struct brcm_pcie {
struct reset_control *rescal;
int num_memc;
u64 memc_size[PCIE_BRCM_MAX_MEMC];
+ u32 hw_rev;
};
/*
@@ -449,8 +466,10 @@ static void brcm_pcie_msi_isr(struct irq_desc *desc)
msi = irq_desc_get_handler_data(desc);
dev = msi->dev;
- status = readl(msi->base + PCIE_MSI_INTR2_STATUS);
- for_each_set_bit(bit, &status, BRCM_INT_PCI_MSI_NR) {
+ status = readl(msi->intr_base + MSI_INT_STATUS);
+ status >>= msi->legacy_shift;
+
+ for_each_set_bit(bit, &status, msi->nr) {
virq = irq_find_mapping(msi->inner_domain, bit);
if (virq)
generic_handle_irq(virq);
@@ -467,7 +486,7 @@ static void brcm_msi_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
msg->address_lo = lower_32_bits(msi->target_addr);
msg->address_hi = upper_32_bits(msi->target_addr);
- msg->data = (0xffff & PCIE_MISC_MSI_DATA_CONFIG_VAL) | data->hwirq;
+ msg->data = (0xffff & PCIE_MISC_MSI_DATA_CONFIG_VAL_32) | data->hwirq;
}
static int brcm_msi_set_affinity(struct irq_data *irq_data,
@@ -479,8 +498,9 @@ static int brcm_msi_set_affinity(struct irq_data *irq_data,
static void brcm_msi_ack_irq(struct irq_data *data)
{
struct brcm_msi *msi = irq_data_get_irq_chip_data(data);
+ const int shift_amt = data->hwirq + msi->legacy_shift;
- writel(1 << data->hwirq, msi->base + PCIE_MSI_INTR2_CLR);
+ writel(1 << shift_amt, msi->intr_base + MSI_INT_CLR);
}
@@ -496,7 +516,7 @@ static int brcm_msi_alloc(struct brcm_msi *msi)
int hwirq;
mutex_lock(&msi->lock);
- hwirq = bitmap_find_free_region(&msi->used, BRCM_INT_PCI_MSI_NR, 0);
+ hwirq = bitmap_find_free_region(&msi->used, msi->nr, 0);
mutex_unlock(&msi->lock);
return hwirq;
@@ -545,7 +565,7 @@ static int brcm_allocate_domains(struct brcm_msi *msi)
struct fwnode_handle *fwnode = of_node_to_fwnode(msi->np);
struct device *dev = msi->dev;
- msi->inner_domain = irq_domain_add_linear(NULL, BRCM_INT_PCI_MSI_NR,
+ msi->inner_domain = irq_domain_add_linear(NULL, msi->nr,
&msi_domain_ops, msi);
if (!msi->inner_domain) {
dev_err(dev, "failed to create IRQ domain\n");
@@ -583,7 +603,10 @@ static void brcm_msi_remove(struct brcm_pcie *pcie)
static void brcm_msi_set_regs(struct brcm_msi *msi)
{
- writel(0xffffffff, msi->base + PCIE_MSI_INTR2_MASK_CLR);
+ u32 val = __GENMASK(31, msi->legacy_shift);
+
+ writel(val, msi->intr_base + MSI_INT_MASK_CLR);
+ writel(val, msi->intr_base + MSI_INT_CLR);
/*
* The 0 bit of PCIE_MISC_MSI_BAR_CONFIG_LO is repurposed to MSI
@@ -594,8 +617,10 @@ static void brcm_msi_set_regs(struct brcm_msi *msi)
writel(upper_32_bits(msi->target_addr),
msi->base + PCIE_MISC_MSI_BAR_CONFIG_HI);
- writel(PCIE_MISC_MSI_DATA_CONFIG_VAL,
- msi->base + PCIE_MISC_MSI_DATA_CONFIG);
+ val = msi->legacy ? PCIE_MISC_MSI_DATA_CONFIG_VAL_8 :
+ PCIE_MISC_MSI_DATA_CONFIG_VAL_32;
+
+ writel(val, msi->base + PCIE_MISC_MSI_DATA_CONFIG);
}
static int brcm_pcie_enable_msi(struct brcm_pcie *pcie)
@@ -620,6 +645,17 @@ static int brcm_pcie_enable_msi(struct brcm_pcie *pcie)
msi->np = pcie->np;
msi->target_addr = pcie->msi_target_addr;
msi->irq = irq;
+ msi->legacy = pcie->hw_rev < BRCM_PCIE_HW_REV_33;
+
+ if (msi->legacy) {
+ msi->intr_base = msi->base + PCIE_INTR2_CPU_BASE;
+ msi->nr = BRCM_INT_PCI_MSI_LEGACY_NR;
+ msi->legacy_shift = 24;
+ } else {
+ msi->intr_base = msi->base + PCIE_MSI_INTR2_BASE;
+ msi->nr = BRCM_INT_PCI_MSI_NR;
+ msi->legacy_shift = 0;
+ }
ret = brcm_allocate_domains(msi);
if (ret)
@@ -878,12 +914,6 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie)
tmp &= ~PCIE_MISC_RC_BAR3_CONFIG_LO_SIZE_MASK;
writel(tmp, base + PCIE_MISC_RC_BAR3_CONFIG_LO);
- /* Mask all interrupts since we are not handling any yet */
- writel(0xffffffff, pcie->base + PCIE_MSI_INTR2_MASK_SET);
-
- /* clear any interrupts we find on boot */
- writel(0xffffffff, pcie->base + PCIE_MSI_INTR2_CLR);
-
if (pcie->gen)
brcm_pcie_set_gen(pcie, pcie->gen);
@@ -1215,6 +1245,8 @@ static int brcm_pcie_probe(struct platform_device *pdev)
if (ret)
goto fail;
+ pcie->hw_rev = readl(pcie->base + PCIE_MISC_REVISION);
+
msi_np = of_parse_phandle(pcie->np, "msi-parent", 0);
if (pci_msi_enabled() && msi_np == pcie->np) {
ret = brcm_pcie_enable_msi(pcie);
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 12/15] PCI: brcmstb: Set internal memory viewport sizes
From: Jim Quinlan @ 2020-05-19 20:34 UTC (permalink / raw)
To: james.quinlan, Nicolas Saenz Julienne
Cc: Rob Herring, Lorenzo Pieralisi,
open list:PCI NATIVE HOST BRIDGE AND ENDPOINT DRIVERS, open list,
Florian Fainelli, maintainer:BROADCOM BCM7XXX ARM ARCHITECTURE,
moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE,
Bjorn Helgaas,
moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE
In-Reply-To: <20200519203419.12369-1-james.quinlan@broadcom.com>
BrcmSTB PCIe controllers are intimately connected to the memory
controller(s) on the SOC. There is a "viewport" for each memory
controller that allows inbound accesses to CPU memory. Each
viewport's size must be set to a power of two, and that size must be
equal to or larger than the amount of memory each controller supports.
Signed-off-by: Jim Quinlan <james.quinlan@broadcom.com>
---
drivers/pci/controller/Kconfig | 1 +
drivers/pci/controller/pcie-brcmstb.c | 67 ++++++++++++++++++++-------
2 files changed, 50 insertions(+), 18 deletions(-)
diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index c0f3d4d10047..a5049613b00e 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -248,6 +248,7 @@ config PCIE_BRCMSTB
depends on OF
depends on PCI_MSI_IRQ_DOMAIN
default ARCH_BRCMSTB
+ select DMA_PFN_OFFSET_MAP
help
Say Y here to enable PCIe host controller support for
Broadcom STB based SoCs, like the Raspberry Pi 4.
diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index 0787e8f6f7e5..532f2bc76202 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -55,6 +55,8 @@
#define PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK 0x300000
#define PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_128 0x0
#define PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK 0xf8000000
+#define PCIE_MISC_MISC_CTRL_SCB1_SIZE_MASK 0x07c00000
+#define PCIE_MISC_MISC_CTRL_SCB2_SIZE_MASK 0x0000001f
#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO 0x400c
#define PCIE_MEM_WIN0_LO(win) \
@@ -152,6 +154,7 @@
#define SSC_STATUS_OFFSET 0x1
#define SSC_STATUS_SSC_MASK 0x400
#define SSC_STATUS_PLL_LOCK_MASK 0x800
+#define PCIE_BRCM_MAX_MEMC 3
/* Rescal registers */
#define PCIE_DVT_PMU_PCIE_PHY_CTRL 0xc700
@@ -254,6 +257,8 @@ struct brcm_pcie {
const int *reg_field_info;
enum pcie_type type;
struct reset_control *rescal;
+ int num_memc;
+ u64 memc_size[PCIE_BRCM_MAX_MEMC];
};
/*
@@ -710,22 +715,40 @@ static inline int brcm_pcie_get_rc_bar2_size_and_offset(struct brcm_pcie *pcie,
u64 *rc_bar2_offset)
{
struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
- struct device *dev = pcie->dev;
struct resource_entry *entry;
+ struct device *dev = pcie->dev;
+ u64 lowest_pcie_addr = ~(u64)0;
+ int ret, i = 0;
+ u64 size = 0;
- entry = resource_list_first_type(&bridge->dma_ranges, IORESOURCE_MEM);
- if (!entry)
- return -ENODEV;
+ resource_list_for_each_entry(entry, &bridge->dma_ranges) {
+ u64 pcie_beg = entry->res->start - entry->offset;
+ size += entry->res->end - entry->res->start + 1;
+ if (pcie_beg < lowest_pcie_addr)
+ lowest_pcie_addr = pcie_beg;
+ }
- /*
- * The controller expects the inbound window offset to be calculated as
- * the difference between PCIe's address space and CPU's. The offset
- * provided by the firmware is calculated the opposite way, so we
- * negate it.
- */
- *rc_bar2_offset = -entry->offset;
- *rc_bar2_size = 1ULL << fls64(entry->res->end - entry->res->start);
+ ret = of_property_read_variable_u64_array(
+ pcie->np, "brcm,scb-sizes", pcie->memc_size, 1,
+ PCIE_BRCM_MAX_MEMC);
+
+ if (ret <= 0) {
+ /* Make an educated guess */
+ pcie->num_memc = 1;
+ pcie->memc_size[0] = 1 << fls64(size - 1);
+ } else {
+ pcie->num_memc = ret;
+ }
+
+ /* Each memc is viewed through a "port" that is a power of 2 */
+ for (i = 0, size = 0; i < pcie->num_memc; i++)
+ size += pcie->memc_size[i];
+
+ /* System memory starts at this address in PCIe-space */
+ *rc_bar2_offset = lowest_pcie_addr;
+ /* The sum of all memc views must also be a power of 2 */
+ *rc_bar2_size = 1ULL << fls64(size - 1);
/*
* We validate the inbound memory view even though we should trust
@@ -777,12 +800,11 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie)
void __iomem *base = pcie->base;
struct device *dev = pcie->dev;
struct resource_entry *entry;
- unsigned int scb_size_val;
bool ssc_good = false;
struct resource *res;
int num_out_wins = 0;
u16 nlw, cls, lnksta;
- int i, ret;
+ int i, ret, memc;
u32 tmp, aspm_support;
/* Reset the bridge */
@@ -818,11 +840,20 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie)
writel(upper_32_bits(rc_bar2_offset),
base + PCIE_MISC_RC_BAR2_CONFIG_HI);
- scb_size_val = rc_bar2_size ?
- ilog2(rc_bar2_size) - 15 : 0xf; /* 0xf is 1GB */
tmp = readl(base + PCIE_MISC_MISC_CTRL);
- u32p_replace_bits(&tmp, scb_size_val,
- PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK);
+ for (memc = 0; memc < pcie->num_memc; memc++) {
+ u32 scb_size_val = ilog2(pcie->memc_size[memc]) - 15;
+
+ if (memc == 0)
+ u32p_replace_bits(&tmp, scb_size_val,
+ PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK);
+ else if (memc == 1)
+ u32p_replace_bits(&tmp, scb_size_val,
+ PCIE_MISC_MISC_CTRL_SCB1_SIZE_MASK);
+ else if (memc == 2)
+ u32p_replace_bits(&tmp, scb_size_val,
+ PCIE_MISC_MISC_CTRL_SCB2_SIZE_MASK);
+ }
writel(tmp, base + PCIE_MISC_MISC_CTRL);
/*
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH v10] arm64: dts: qcom: sc7180: Add WCN3990 WLAN module device node
From: Doug Anderson @ 2020-05-19 20:38 UTC (permalink / raw)
To: Rakesh Pillai
Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS, LKML,
Linux ARM, linux-arm-msm
In-Reply-To: <1589914405-6674-1-git-send-email-pillair@codeaurora.org>
Hi,
On Tue, May 19, 2020 at 11:53 AM Rakesh Pillai <pillair@codeaurora.org> wrote:
>
> + wifi: wifi@18800000 {
> + compatible = "qcom,wcn3990-wifi";
> + reg = <0 0x18800000 0 0x800000>;
> + reg-names = "membase";
> + iommus = <&apps_smmu 0xc0 0x1>;
> + interrupts =
> + <GIC_SPI 414 IRQ_TYPE_LEVEL_HIGH /* CE0 */ >,
> + <GIC_SPI 415 IRQ_TYPE_LEVEL_HIGH /* CE1 */ >,
> + <GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH /* CE2 */ >,
> + <GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH /* CE3 */ >,
> + <GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH /* CE4 */ >,
> + <GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH /* CE5 */ >,
> + <GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH /* CE6 */ >,
> + <GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH /* CE7 */ >,
> + <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH /* CE8 */ >,
> + <GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH /* CE9 */ >,
> + <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH /* CE10 */>,
> + <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH /* CE11 */>;
> + memory-region = <&wlan_fw_mem>;
> + status = "disabled";
> + };
> +
> config_noc: interconnect@1500000 {
> compatible = "qcom,sc7180-config-noc";
> reg = <0 0x01500000 0 0x28000>;
For completeness sake, I'll also point out that the WiFi node is also
sorted incorrectly. 0x18800000 comes after 0x01500000.
-Doug
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: clock_gettime64 vdso bug on 32-bit arm, rpi-4
From: Rich Felker @ 2020-05-19 20:41 UTC (permalink / raw)
To: Adhemerval Zanella
Cc: Arnd Bergmann, Szabolcs Nagy, Will Deacon,
Russell King - ARM Linux, Linux Kernel Mailing List, Stephen Boyd,
Thomas Gleixner, Vincenzo Frascino, Jack Schmidt, Linux ARM
In-Reply-To: <0c2abcd1-7da8-2559-1e93-4c3bdd38dec1@linaro.org>
On Tue, May 19, 2020 at 05:24:18PM -0300, Adhemerval Zanella wrote:
>
>
> On 19/05/2020 16:54, Arnd Bergmann wrote:
> > Jack Schmidt reported a bug for the arm32 clock_gettimeofday64 vdso call last
> > month: https://github.com/richfelker/musl-cross-make/issues/96 and
> > https://github.com/raspberrypi/linux/issues/3579
> >
> > As Will Deacon pointed out, this was never reported on the mailing list,
> > so I'll try to summarize what we know, so this can hopefully be resolved soon.
> >
> > - This happened reproducibly on Linux-5.6 on a 32-bit Raspberry Pi patched
> > kernel running on a 64-bit Raspberry Pi 4b (bcm2711) when calling
> > clock_gettime64(CLOCK_REALTIME)
>
> Does it happen with other clocks as well?
>
> >
> > - The kernel tree is at https://github.com/raspberrypi/linux/, but I could
> > see no relevant changes compared to a mainline kernel.
>
> Is this bug reproducible with mainline kernel or mainline kernel can't be
> booted on bcm2711?
>
> >
> > - From the report, I see that the returned time value is larger than the
> > expected time, by 3.4 to 14.5 million seconds in four samples, my
> > guess is that a random number gets added in at some point.
>
> What kind code are you using to reproduce it? It is threaded or issue
> clock_gettime from signal handlers?
Original report thread is here:
https://github.com/richfelker/musl-cross-make/issues/96
The reporter originally misunderstood the issue and wrongly attributed
it to difference between gettimeofday and clock_gettime but it was
just big jumps between successive vdso clock_gettime64 calls.
No transformation was being done on the output of the vdso function;
as long as it succeeds musl just returns directly with the value it
stored in the timespec. No threads or anything fancy were involved.
Current musl will no longer call it but you should be able to
dlopen("linux-gate.so.1", RTLD_NOW|RTLD_LOCAL) then use dlsym to get
its address and call it (not tested; I've never used it this way).
> > - The current musl git tree has been patched to not call clock_gettime64
> > on ARM because of this problem, so it cannot be used for reproducing it.
>
> So should glibc follow musl and remove arm clock_gettime6y4 vDSO support
> or this bug is localized to an specific kernel version running on an
> specific hardware?
For musl it was important to disable it asap pending a fix, because
users are expected to generate static binaries, and these could make
it into the wild without anyone realizing they're broken until much
later when run on an affected kernel (especially since pre-5.6 kernels
would hide the issue entirely due to lacking vdso). Ideally a fix will
be something we can detect (e.g. new symbol version) so as not to risk
calling the broken one, but whether that's necessary may depend on
what's affected.
I'm not sure if glibc should do the same; it's not often used in
static linking, and replacing libc (shared lib, or re-static-linking
which LGPL requires you to facilitate to distribute static binaries)
could solve the issue on affected systems.
Rich
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 2/2] ARM: Allow either FLATMEM or SPARSEMEM on the multiplatform build
From: Arnd Bergmann @ 2020-05-19 20:42 UTC (permalink / raw)
To: Russell King - ARM Linux admin
Cc: Doug Berger, Stephen Boyd, Kevin Cernekee, Mike Rapoport,
Florian Fainelli, Gregory Fong, Linux ARM
In-Reply-To: <20200519165445.GI1551@shell.armlinux.org.uk>
On Tue, May 19, 2020 at 6:54 PM Russell King - ARM Linux admin
<linux@armlinux.org.uk> wrote:
> On Tue, May 19, 2020 at 05:32:52PM +0200, Arnd Bergmann wrote:
> > On Tue, May 19, 2020 at 5:27 PM Mike Rapoport <rppt@linux.ibm.com> wrote:
> > > On Tue, May 19, 2020 at 04:04:52PM +0100, Russell King - ARM Linux admin wrote:
> > > > There are cases where the reason to use sparsemem is not an optional
> > > > one but is out of necessity - they require the page array to be split
> > > > up in order to boot successfully.
> > > >
> > > > With that in mind, flatmem becomes an "optimisation" over sparsemem.
> > >
> > > At the moment, there are three platforms that enable SPARSEMEM: ARCH_EP93XX,
> > > ARCH_RPC and ARCH_SA1100. All the rest have FLATMEM implcitly selected.
> > >
> > > I do not intend to change that, I am only going add an ability to select
> > > the memory model for ARCH_MULTIPLATFORM.
> > >
> > > I'll respin the series on the list before adding the patches to the
> > > patch system.
> >
> > I think we'll make EP93xx part of multiplatform at some point, IIRC
> > only the missing clock driver is stopping us at the moment, and I already
> > discussed with Linus Walleij how that can be done.
> >
> > My guess is that ep93xx is one platform on which sparsemem is
> > just an optimization to reduce the initial memory consumption, but
> > we should verify that when we get there.
>
> When you have a platform where the memory is segmented into separate
> blocks widely spaced, sparsemem is not an optimisation. For example,
> If you have four blocks spaced across 1GB, that requires about
> 256Ki struct page's. Assuming 32 byte struct page, that requires 8MiB
> of contiguous memory.
I checked the datasheet: ep93xx has four chip-selects, each of them
with their own 256MB memory area. Most boards we support use only
the last chipselect, but those that have more than one would waste
up to 2MB per additional memory chip, which is not nice but doesn't
make it a hard requirement as long as the kernel can fit into the first one.
However, the chips has a second problem: depending on the
specific memory configuration, only every other 2/4/8MB within
that range may actually be used, so the mem_map[] array would
double its size in practice and (worse) the kernel would likely
not fit into the first section without sparsemem.
This means we should indeed treat it as a requirement for ep93xx.
Arnd
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] arm64: dts: ls1028a: sl28: keep switch port names consistent
From: Michael Walle @ 2020-05-19 21:03 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel; +Cc: Michael Walle, Shawn Guo
Keep the switch port labels consistent across the different board
variants. If the user wants to rename them, it should be done in
user-space.
Fixes: ab43f0307449 ("arm64: dts: ls1028a: sl28: add support for variant 2")
Signed-off-by: Michael Walle <michael@walle.cc>
---
.../boot/dts/freescale/fsl-ls1028a-kontron-sl28-var2.dts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var2.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var2.dts
index 901b5b161def..dd764b720fb0 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var2.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var2.dts
@@ -53,14 +53,14 @@
};
&mscc_felix_port0 {
- label = "gbe0";
+ label = "swp0";
phy-handle = <&phy0>;
phy-mode = "sgmii";
status = "okay";
};
&mscc_felix_port1 {
- label = "gbe1";
+ label = "swp1";
phy-handle = <&phy1>;
phy-mode = "sgmii";
status = "okay";
--
2.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 0/2] Set the quality value for two HW RNGs
From: Łukasz Stelmach @ 2020-05-19 21:25 UTC (permalink / raw)
To: Matt Mackall, Herbert Xu, Arnd Bergmann, Greg Kroah-Hartman,
Ray Jui, Scott Branden, bcm-kernel-feedback-list, Kukjin Kim,
Krzysztof Kozlowski, Florian Fainelli, Markus Elfring,
Matthias Brugger, Stefan Wahren, linux-crypto, linux-arm-kernel,
linux-kernel, linux-samsung-soc, Stephan Mueller
Cc: Łukasz Stelmach, Bartlomiej Zolnierkiewicz
In-Reply-To: <20200514190734.32746-1-l.stelmach@samsung.com>
The rng structure contains the quality field which tells how many bits
of entropy can be obtained from 1024 bits read from a device. With the
quality value set the hw_random framework starts a kernel thread to feed
the entropy pool in the CRNG, which helps to initialize it quickly
especially during boot.
Łukasz Stelmach (2):
hwrng: iproc-rng200 - Set the quality value
hwrng: exynos - Set the quality value
drivers/char/hw_random/exynos-trng.c | 1 +
drivers/char/hw_random/iproc-rng200.c | 1 +
2 files changed, 2 insertions(+)
v2:
- recalculated values using the SP800-90B_EntropyAssessment package
--
2.25.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v2 1/2] hwrng: iproc-rng200 - Set the quality value
From: Łukasz Stelmach @ 2020-05-19 21:25 UTC (permalink / raw)
To: Matt Mackall, Herbert Xu, Arnd Bergmann, Greg Kroah-Hartman,
Ray Jui, Scott Branden, bcm-kernel-feedback-list, Kukjin Kim,
Krzysztof Kozlowski, Florian Fainelli, Markus Elfring,
Matthias Brugger, Stefan Wahren, linux-crypto, linux-arm-kernel,
linux-kernel, linux-samsung-soc, Stephan Mueller
Cc: Łukasz Stelmach, Bartlomiej Zolnierkiewicz
In-Reply-To: <20200519212552.11671-1-l.stelmach@samsung.com>
The value was estimaded with ea_iid[1] using on 10485760 bytes read from
the RNG via /dev/hwrng. The min-entropy value calculated using the most
common value estimate (NIST SP 800-90P[2], section 6.3.1) was 7.964464.
[1] https://github.com/usnistgov/SP800-90B_EntropyAssessment
[2] https://csrc.nist.gov/publications/detail/sp/800-90b/final
Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
---
drivers/char/hw_random/iproc-rng200.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/char/hw_random/iproc-rng200.c b/drivers/char/hw_random/iproc-rng200.c
index 32d9fe61a225..95669ece050f 100644
--- a/drivers/char/hw_random/iproc-rng200.c
+++ b/drivers/char/hw_random/iproc-rng200.c
@@ -199,6 +199,7 @@ static int iproc_rng200_probe(struct platform_device *pdev)
priv->rng.read = iproc_rng200_read,
priv->rng.init = iproc_rng200_init,
priv->rng.cleanup = iproc_rng200_cleanup,
+ priv->rng.quality = 1000,
/* Register driver */
ret = devm_hwrng_register(dev, &priv->rng);
--
2.26.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 2/2] hwrng: exynos - Set the quality value
From: Łukasz Stelmach @ 2020-05-19 21:25 UTC (permalink / raw)
To: Matt Mackall, Herbert Xu, Arnd Bergmann, Greg Kroah-Hartman,
Ray Jui, Scott Branden, bcm-kernel-feedback-list, Kukjin Kim,
Krzysztof Kozlowski, Florian Fainelli, Markus Elfring,
Matthias Brugger, Stefan Wahren, linux-crypto, linux-arm-kernel,
linux-kernel, linux-samsung-soc, Stephan Mueller
Cc: Łukasz Stelmach, Bartlomiej Zolnierkiewicz
In-Reply-To: <20200519212552.11671-1-l.stelmach@samsung.com>
The value was estimaded with ea_iid[1] using on 10485760 bytes read from
the RNG via /dev/hwrng. The min-entropy value calculated using the most
common value estimate (NIST SP 800-90P[2], section 6.3.1) was 7.489627.
[1] https://github.com/usnistgov/SP800-90B_EntropyAssessment
[2] https://csrc.nist.gov/publications/detail/sp/800-90b/final
Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
---
drivers/char/hw_random/exynos-trng.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/char/hw_random/exynos-trng.c b/drivers/char/hw_random/exynos-trng.c
index 8e1fe3f8dd2d..2a5896122001 100644
--- a/drivers/char/hw_random/exynos-trng.c
+++ b/drivers/char/hw_random/exynos-trng.c
@@ -123,6 +123,7 @@ static int exynos_trng_probe(struct platform_device *pdev)
trng->rng.init = exynos_trng_init;
trng->rng.read = exynos_trng_do_read;
trng->rng.priv = (unsigned long) trng;
+ trng->rng.quality = 900;
platform_set_drvdata(pdev, trng);
trng->dev = &pdev->dev;
--
2.26.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH 3/4] clk/soc: mediatek: mt6779: Bind clock driver from platform device
From: Matthias Brugger @ 2020-05-19 21:26 UTC (permalink / raw)
To: Chun-Kuang Hu, matthias.bgg
Cc: Kate Stewart, devicetree, Stephen Boyd, Greg Kroah-Hartman,
Michael Turquette, linux-kernel, Rob Herring,
moderated list:ARM/Mediatek SoC support, Allison Randal,
Matthias Brugger, mtk01761, Thomas Gleixner, linux-clk, Linux ARM
In-Reply-To: <CAAOTY_80D6ZMM5_nEyf_XDjOLaWCOyi3mn9ibWhNX8_ozPK1BQ@mail.gmail.com>
On 19/05/2020 17:10, Chun-Kuang Hu wrote:
> Hi, Matthias:
>
> <matthias.bgg@kernel.org> 於 2020年5月18日 週一 下午7:33寫道:
>>
>> From: Matthias Brugger <matthias.bgg@gmail.com>
>>
>> The mmsys driver is now the top level entry point for the multimedia
>> system (mmsys), we bind the clock driver by creating a platform device.
>> We also bind the MediaTek DRM driver which is not yet implement and
>> therefor will errror out for now.
>>
>> Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
>> ---
>>
>> drivers/clk/mediatek/clk-mt6779-mm.c | 9 ++-------
>> drivers/soc/mediatek/mtk-mmsys.c | 8 ++++++++
>> 2 files changed, 10 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/clk/mediatek/clk-mt6779-mm.c b/drivers/clk/mediatek/clk-mt6779-mm.c
>> index fb5fbb8e3e41..059c1a41ac7a 100644
>> --- a/drivers/clk/mediatek/clk-mt6779-mm.c
>> +++ b/drivers/clk/mediatek/clk-mt6779-mm.c
>> @@ -84,15 +84,11 @@ static const struct mtk_gate mm_clks[] = {
>> GATE_MM1(CLK_MM_DISP_OVL_FBDC, "mm_disp_ovl_fbdc", "mm_sel", 16),
>> };
>>
>> -static const struct of_device_id of_match_clk_mt6779_mm[] = {
>> - { .compatible = "mediatek,mt6779-mmsys", },
>> - {}
>> -};
>> -
>> static int clk_mt6779_mm_probe(struct platform_device *pdev)
>> {
>> + struct device *dev = &pdev->dev;
>> + struct device_node *node = dev->parent->of_node;
>> struct clk_onecell_data *clk_data;
>> - struct device_node *node = pdev->dev.of_node;
>>
>> clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
>>
>> @@ -106,7 +102,6 @@ static struct platform_driver clk_mt6779_mm_drv = {
>> .probe = clk_mt6779_mm_probe,
>> .driver = {
>> .name = "clk-mt6779-mm",
>> - .of_match_table = of_match_clk_mt6779_mm,
>> },
>> };
>>
>> diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
>> index fee64c8d3020..dc15808cf3a3 100644
>> --- a/drivers/soc/mediatek/mtk-mmsys.c
>> +++ b/drivers/soc/mediatek/mtk-mmsys.c
>> @@ -88,6 +88,10 @@ static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = {
>> .clk_driver = "clk-mt2712-mm",
>> };
>>
>> +static const struct mtk_mmsys_driver_data mt6779_mmsys_driver_data = {
>> + .clk_driver = "clk-mt6779-mm",
>
> This patch looks good to me, but I've one question: why drm driver
> just use single "mediatek-drm" for sub driver name, but clock driver
> has different name for each SoC?
> Could we just use single name for clock driver such as "mediatek-clk-mm"?
Because the DRM for all SoCs are handled in the same driver, while we have a
different clock drivers for each SoC. So we need to specify which clock driver
we want to load.
If we want to change that, we would need to refactor heavily the clock drivers
for all MediaTek SoCs. I don't think it's worth the effort.
Regards,
Matthias
>
> Regards,
> Chun-Kuang.
>
>> +};
>> +
>> static const struct mtk_mmsys_driver_data mt6797_mmsys_driver_data = {
>> .clk_driver = "clk-mt6797-mm",
>> };
>> @@ -343,6 +347,10 @@ static const struct of_device_id of_match_mtk_mmsys[] = {
>> .compatible = "mediatek,mt2712-mmsys",
>> .data = &mt2712_mmsys_driver_data,
>> },
>> + {
>> + .compatible = "mediatek,mt6779-mmsys",
>> + .data = &mt6779_mmsys_driver_data,
>> + },
>> {
>> .compatible = "mediatek,mt6797-mmsys",
>> .data = &mt6797_mmsys_driver_data,
>> --
>> 2.26.2
>>
>>
>> _______________________________________________
>> Linux-mediatek mailing list
>> Linux-mediatek@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-mediatek
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v6] arm64: Expose FAR_EL1 tag bits in sigcontext
From: Peter Collingbourne @ 2020-05-19 22:00 UTC (permalink / raw)
To: Dave Martin
Cc: Andrey Konovalov, Kevin Brodsky, Kostya Serebryany,
Evgenii Stepanov, Catalin Marinas, Vincenzo Frascino, Will Deacon,
Linux ARM, Richard Henderson
In-Reply-To: <20200518095313.GZ21779@arm.com>
On Mon, May 18, 2020 at 2:53 AM Dave Martin <Dave.Martin@arm.com> wrote:
>
> On Thu, May 14, 2020 at 05:58:21PM -0700, Peter Collingbourne wrote:
> > On Wed, May 13, 2020 at 1:28 PM Dave Martin <Dave.Martin@arm.com> wrote:
> > >
> > > On Wed, May 13, 2020 at 11:09:14AM -0700, Peter Collingbourne wrote:
> > > > The kernel currently clears the tag bits (i.e. bits 56-63) in the fault
> > > > address exposed via siginfo.si_addr and sigcontext.fault_address. However,
> > > > the tag bits may be needed by tools in order to accurately diagnose
> > > > memory errors, such as HWASan [1] or future tools based on the Memory
> > > > Tagging Extension (MTE).
> > > >
> > > > We should not stop clearing these bits in the existing fault address fields,
> > > > because there may be existing userspace applications that are expecting the tag
> > > > bits to be cleared. Instead, create a fault_addr_top_byte_context in sigcontext
> > > > (similar to the existing esr_context), and store the tag bits of FAR_EL1 there.
> > > >
> > > > [1] http://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html
> > > >
> > > > Signed-off-by: Peter Collingbourne <pcc@google.com>
> > > > ---
> > > > v6:
> > > > - bring back comment about __reserved[]
> > > >
> > > > v5:
> > > > - add padding to fault_addr_top_byte_context in order to ensure the correct
> > > > size and preserve sp alignment
> > > >
> > > > v4:
> > > > - expose only the tag bits in the context instead of the entire FAR_EL1
> > > > - remove mention of the new context from the sigcontext.__reserved[] note
> > > >
> > > > v3:
> > > > - add documentation to tagged-pointers.rst
> > > > - update comments in sigcontext.h
> > > >
> > > > v2:
> > > > - revert changes to hw_breakpoint.c
> > > > - rename set_thread_esr to set_thread_far_esr
> > > >
> > > > Documentation/arm64/tagged-pointers.rst | 17 +++++----
> > > > arch/arm64/include/asm/exception.h | 2 +-
> > > > arch/arm64/include/asm/processor.h | 2 +-
> > > > arch/arm64/include/uapi/asm/sigcontext.h | 22 ++++++++----
> > > > arch/arm64/kernel/entry-common.c | 2 --
> > > > arch/arm64/kernel/signal.c | 22 +++++++++++-
> > > > arch/arm64/mm/fault.c | 45 ++++++++++++++----------
> > > > 7 files changed, 77 insertions(+), 35 deletions(-)
> > > >
> > > > diff --git a/Documentation/arm64/tagged-pointers.rst b/Documentation/arm64/tagged-pointers.rst
> > > > index eab4323609b9..c6e9592a9dea 100644
> > > > --- a/Documentation/arm64/tagged-pointers.rst
> > > > +++ b/Documentation/arm64/tagged-pointers.rst
> > > > @@ -53,12 +53,17 @@ visibility.
> > > > Preserving tags
> > > > ---------------
> > > >
> > > > -Non-zero tags are not preserved when delivering signals. This means that
> > > > -signal handlers in applications making use of tags cannot rely on the
> > > > -tag information for user virtual addresses being maintained for fields
> > > > -inside siginfo_t. One exception to this rule is for signals raised in
> > > > -response to watchpoint debug exceptions, where the tag information will
> > > > -be preserved.
> > > > +Non-zero tags are not preserved in the fault address fields
> > > > +siginfo.si_addr or sigcontext.fault_address when delivering
> > > > +signals. This means that signal handlers in applications making use
> > > > +of tags cannot rely on the tag information for user virtual addresses
> > > > +being maintained in these fields. One exception to this rule is for
> > > > +signals raised in response to watchpoint debug exceptions, where the
> > > > +tag information will be preserved.
> > > > +
> > > > +The fault address tag is preserved in the fault_addr_top_byte field of
> > > > +the signal frame record fault_addr_top_byte_context, which is present
> > > > +for signals raised in response to data aborts and instruction aborts.
> > > >
> > > > The architecture prevents the use of a tagged PC, so the upper byte will
> > > > be set to a sign-extension of bit 55 on exception return.
> > > > diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h
> > > > index 7a6e81ca23a8..90e772d9b2cd 100644
> > > > --- a/arch/arm64/include/asm/exception.h
> > > > +++ b/arch/arm64/include/asm/exception.h
> > > > @@ -32,7 +32,7 @@ static inline u32 disr_to_esr(u64 disr)
> > > > }
> > > >
> > > > asmlinkage void enter_from_user_mode(void);
> > > > -void do_mem_abort(unsigned long addr, unsigned int esr, struct pt_regs *regs);
> > > > +void do_mem_abort(unsigned long far, unsigned int esr, struct pt_regs *regs);
> > > > void do_undefinstr(struct pt_regs *regs);
> > > > asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr);
> > > > void do_debug_exception(unsigned long addr_if_watchpoint, unsigned int esr,
> > > > diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
> > > > index 240fe5e5b720..63185be29ff9 100644
> > > > --- a/arch/arm64/include/asm/processor.h
> > > > +++ b/arch/arm64/include/asm/processor.h
> > > > @@ -144,7 +144,7 @@ struct thread_struct {
> > > > void *sve_state; /* SVE registers, if any */
> > > > unsigned int sve_vl; /* SVE vector length */
> > > > unsigned int sve_vl_onexec; /* SVE vl after next exec */
> > > > - unsigned long fault_address; /* fault info */
> > > > + unsigned long fault_address; /* FAR_EL1 value */
> > > > unsigned long fault_code; /* ESR_EL1 value */
> > > > struct debug_info debug; /* debugging */
> > > > #ifdef CONFIG_ARM64_PTR_AUTH
> > > > diff --git a/arch/arm64/include/uapi/asm/sigcontext.h b/arch/arm64/include/uapi/asm/sigcontext.h
> > > > index 8b0ebce92427..2a3fe3de899d 100644
> > > > --- a/arch/arm64/include/uapi/asm/sigcontext.h
> > > > +++ b/arch/arm64/include/uapi/asm/sigcontext.h
> > > > @@ -44,11 +44,12 @@ struct sigcontext {
> > > > *
> > > > * 0x210 fpsimd_context
> > > > * 0x10 esr_context
> > > > + * 0x10 fault_addr_top_byte_context
> > > > * 0x8a0 sve_context (vl <= 64) (optional)
> > > > * 0x20 extra_context (optional)
> > > > * 0x10 terminator (null _aarch64_ctx)
> > > > *
> > > > - * 0x510 (reserved for future allocation)
> > > > + * 0x500 (reserved for future allocation)
> > > > *
> > > > * New records that can exceed this space need to be opt-in for userspace, so
> > > > * that an expanded signal frame is not generated unexpectedly. The mechanism
> > > > @@ -94,17 +95,26 @@ struct esr_context {
> > > > __u64 esr;
> > > > };
> > > >
> > > > +/* Top byte of fault address (normally not exposed via si_addr) */
> > > > +#define FAULT_ADDR_TOP_BYTE_MAGIC 0x46544201
> > > > +
> > > > +struct fault_addr_top_byte_context {
> > > > + struct _aarch64_ctx head;
> > > > + __u8 fault_addr_top_byte;
> > > > + __u8 __reserved[7];
> > > > +};
> > > > +
> > >
> > > Nit: the name here is a bit cumbersome (obviously bikeshedding...)
> > >
> > >
> > > For the rest, some of my comments may be bogus -- I haven't dug into
> > > this stuff for a little while!
> > >
> > >
> > > Anyway:
> > >
> > > Do we really get the whole top byte of the address in the FAR? If so,
> > > fine, but I'm having trouble finding a clear statement in the
> > > architecture one way or the other. (I didn't attempt to dive into the
> > > pseudocode.)
> >
> > I rely on this statement in the ARM:
> >
> > https://developer.arm.com/docs/ddi0595/b/aarch64-system-registers/far_el1
> > "For a Data Abort or Watchpoint exception, if address tagging is
> > enabled for the address accessed by the data access that caused the
> > exception, then this field includes the tag."
>
> Yes, I think that covers it. I hadn't found a clear definition of
> "tag", but I think the TBI mechanism makes it "reasonably obvious" the
> non-address (i.e., tag) bits are [63:56].
>
> > And note that address tagging here essentially means TBI (which is
> > always enabled on Linux), and not memory tagging.
> >
> > > Also, since we're burning 16 bytes here, I'd prefer if we make this
> > > extensible. At present the __reserved[7] is unusable because
> > > userspace has no way to know whether it's valid or not.
> > >
> > > Options include an additional flag byte (0 for now), or just making
> > > the whole thing a __u64. In that case we can leave the top byte bits
> > > in their original positions if we want, but it would be a good idea to
> > > include a flag to say that field is valid at all. (See comments below
> > > on Synchronous external abort.)
> > >
> > > So, say, foo_context->fault_info = (esr & (~0ULL << 56)) | TOP_BYTE_VALID.
> > > (with #defines for the bits/fields as appropriate).
> >
> > The flag bits seem like a good idea. Thinking ahead to the MTE sync
> > tag fault (which might not provide us with bits 60-63), we may
> > consider having separate bits to indicate "bits 56-59 valid" and "bits
> > 60-63 valid", set both bits for regular data aborts and only the
> > former for sync tag faults, which would avoid the need to define a
> > separate context for these faults. And if a future architecture
> > revision provides us with bits 60-63 for tag faults, we could start
> > setting both flag bits even for tag faults.
>
> Seems reasonable, but a "tag mask" field of some sort might be
> preferable to hard-wiring, just in case a future update to MTE supports
> more than 4 bits.
That's fine with me.
> > > > /*
> > > > * extra_context: describes extra space in the signal frame for
> > > > * additional structures that don't fit in sigcontext.__reserved[].
> > > > *
> > > > * Note:
> > > > *
> > > > - * 1) fpsimd_context, esr_context and extra_context must be placed in
> > > > - * sigcontext.__reserved[] if present. They cannot be placed in the
> > > > - * extra space. Any other record can be placed either in the extra
> > > > - * space or in sigcontext.__reserved[], unless otherwise specified in
> > > > - * this file.
> > > > + * 1) fpsimd_context, esr_context, fault_addr_top_byte_context and
> > > > + * extra_context must be placed in sigcontext.__reserved[] if present.
> > > > + * They cannot be placed in the extra space. Any other record can be
> > > > + * placed either in the extra space or in sigcontext.__reserved[],
> > > > + * unless otherwise specified in this file.
> > > > *
> > > > * 2) There must not be more than one extra_context.
> > > > *
> > > > diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
> > > > index c839b5bf1904..045b4f518836 100644
> > > > --- a/arch/arm64/kernel/entry-common.c
> > > > +++ b/arch/arm64/kernel/entry-common.c
> > > > @@ -22,7 +22,6 @@ static void notrace el1_abort(struct pt_regs *regs, unsigned long esr)
> > > > unsigned long far = read_sysreg(far_el1);
> > > >
> > > > local_daif_inherit(regs);
> > > > - far = untagged_addr(far);
> > > > do_mem_abort(far, esr, regs);
> > > > }
> > > > NOKPROBE_SYMBOL(el1_abort);
> > > > @@ -104,7 +103,6 @@ static void notrace el0_da(struct pt_regs *regs, unsigned long esr)
> > > >
> > > > user_exit_irqoff();
> > > > local_daif_restore(DAIF_PROCCTX);
> > > > - far = untagged_addr(far);
> > > > do_mem_abort(far, esr, regs);
> > > > }
> > > > NOKPROBE_SYMBOL(el0_da);
> > > > diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
> > > > index 339882db5a91..baa88dc02e5c 100644
> > > > --- a/arch/arm64/kernel/signal.c
> > > > +++ b/arch/arm64/kernel/signal.c
> > > > @@ -55,6 +55,7 @@ struct rt_sigframe_user_layout {
> > > >
> > > > unsigned long fpsimd_offset;
> > > > unsigned long esr_offset;
> > > > + unsigned long ftb_offset;
> > > > unsigned long sve_offset;
> > > > unsigned long extra_offset;
> > > > unsigned long end_offset;
> > > > @@ -383,6 +384,7 @@ static int parse_user_sigframe(struct user_ctxs *user,
> > > > break;
> > > >
> > > > case ESR_MAGIC:
> > > > + case FAULT_ADDR_TOP_BYTE_MAGIC:
> > > > /* ignore */
> > > > break;
> > > >
> > > > @@ -581,6 +583,12 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user,
> > > > sizeof(struct esr_context));
> > > > if (err)
> > > > return err;
> > > > +
> > > > + err = sigframe_alloc(
> > > > + user, &user->ftb_offset,
> > > > + sizeof(struct fault_addr_top_byte_context));
> > >
> > > Nit: inconsistent indentation?
> > >
> > > (Mostly just because it makes the change look odd against the hunk
> > > context, but not a big deal.)
> >
> > With consistent indentation we violate 80 cols due to the extra long
> > struct name. The indentation is what clang-format is giving me.
>
> I suspected that might be why. Fair enough (though a shorter name would
> be no bad thing, it's not worth changing that just for nicer indentation).
>
> >
> > > > + if (err)
> > > > + return err;
> > > > }
> > > >
> > > > if (system_supports_sve()) {
> > > > @@ -621,7 +629,8 @@ static int setup_sigframe(struct rt_sigframe_user_layout *user,
> > > > __put_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err);
> > > > __put_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err);
> > > >
> > > > - __put_user_error(current->thread.fault_address, &sf->uc.uc_mcontext.fault_address, err);
> > > > + __put_user_error(untagged_addr(current->thread.fault_address),
> > > > + &sf->uc.uc_mcontext.fault_address, err);
> > > >
> > > > err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set));
> > > >
> > > > @@ -641,6 +650,17 @@ static int setup_sigframe(struct rt_sigframe_user_layout *user,
> > > > __put_user_error(current->thread.fault_code, &esr_ctx->esr, err);
> > > > }
> > > >
> > > > + if (err == 0 && user->ftb_offset) {
> > > > + struct fault_addr_top_byte_context __user *ftb_ctx =
> > > > + apply_user_offset(user, user->ftb_offset);
> > > > +
> > > > + __put_user_error(FAULT_ADDR_TOP_BYTE_MAGIC,
> > > > + &ftb_ctx->head.magic, err);
> > > > + __put_user_error(sizeof(*ftb_ctx), &ftb_ctx->head.size, err);
> > > > + __put_user_error(current->thread.fault_address >> 56,
> > > > + &ftb_ctx->fault_addr_top_byte, err);
> > > > + }
> > > > +
> > >
> > > How do we handle the fact that the top byte of FAR is sometimes UNKNOWN?
> > >
> > > For Synchronous external aborts in particular, those bits are documented
> > > as UNKNOWN, but I don't see any special handling, There may be other
> > > cases I haven't spotted.
> > >
> > > For preference we can omit this record entirely if we don't have any
> > > information we can report, but certainly we shouldn't expose UNKNOWN
> > > bits.
> >
> > In this case we mask out the top byte in do_sea before passing the
> > address to arm64_notify_die (which clears fault_address and passes the
> > address argument on to arm64_force_sig_fault to be exposed via
> > si_addr). So the record would always contain a 0 byte. It seems
> > reasonable to omit the record in this case instead.
>
> Ah, right. Missed that.
>
> The record is already omitted when fault_code == 0 IIUC, so perhaps
> we're already doing the right thing for synchronous external aborts.
>
> > > [ Aside:
> > >
> > > Also, what if we're not reporting a memory abort at all? Does
> > > thread.fault_address just contain junk from the last fault? I see
> > > nothing anywhere that cleans this up. (This is historical and not
> > > your fault, but it would be good to close this down while we're about
> > > it.)
> > >
> > >
> > > Hmmm, looking at the code I think we probably leak fault_address etc.
> > > across execve() too, so it may even be stale junk from an old process
> > > :/
> > >
> > > Maybe I just confused myself.
> > >
> > > End aside. ]
> >
> > Yes, it's unclear whether we always manage to not expose a fault
> > address if we're not reporting a data or instruction abort. The code
> > would need to arrange for fault_code to be set to 0 in order to avoid
> > exposing previous fault_address values via future signals. I don't see
> > anywhere where we're resetting these fields after delivering a signal,
> > so it seems possible by calling arm64_force_sig_fault without first
> > setting fault_code (most callers do this, but the calls in
> > arch/arm64/kernel/debug-monitors.c and arch/arm64/kernel/ptrace.c seem
> > not to), or simply by calling force_sig_fault (which happens in many
> > places throughout the kernel).
> >
> > Maybe something like this would do the trick? (Untested, and forgive
> > spaces instead of tabs, grumble grumble gmail):
> >
> > diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
> > index baa88dc02e5c..5867f2fdbe64 100644
> > --- a/arch/arm64/kernel/signal.c
> > +++ b/arch/arm64/kernel/signal.c
> > @@ -648,6 +648,7 @@ static int setup_sigframe(struct
> > rt_sigframe_user_layout *user,
> > __put_user_error(ESR_MAGIC, &esr_ctx->head.magic, err);
> > __put_user_error(sizeof(*esr_ctx), &esr_ctx->head.size, err);
> > __put_user_error(current->thread.fault_code,
> > &esr_ctx->esr, err);
> > + current->thread.fault_code = 0;
>
> Perhaps, but we'd need to be careful. For example, can we run out of
> user stack before this and deliver a SIGSEGV, but with the old
> fault_code still set? Then we'd emit the old fault code with the
> new "can't deliver signal" signal, which doesn't make sense.
>
> Stuff may also go wrong with signal prioritisation.
>
> If a higher-priority signal (say SIGINT) comes in after a data abort
> enters the kernel but before the resulting SIGSEGV is dequeued for
> delivery, wouldn't we deliver SIGINT first, with the bogus fault code?
> With your change we'd then have cleared the fault code by the time we
> deliver the SIGSEGV it actually relates to, if I've understood right.
>
> Today, I think we just attach that fault code to every signal that's
> delivered until something overwrites or resets it, which means that
> a signal that needs fault_code gets it, at the expense of attaching
> it to a bunch of other random signals too.
>
>
> Checking the signal number and si_code might help us to know what we
> should be doing with fault_code. We need to have sure userspace can't
> trick us with a non kernel generated signal here. It would also be
> necessary to check how PTRACE_SETSIGINFO interacts with this.
With these possible interactions in mind I think we should store the
fault code and fault address in kernel_siginfo instead of
thread_struct (and clear these fields when we receive a siginfo from
userspace, i.e. in copy_siginfo_from_user which is used by
ptrace(PTRACE_SETSIGINFO) among other places). That way, the
information is clearly associated with the signal itself and not the
thread, so we don't need to worry about our signal being delivered out
of order.
Peter
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* BUG: sleeping function called from atomic due to "Balance initial LPI affinity across CPUs"
From: Qian Cai @ 2020-05-19 22:09 UTC (permalink / raw)
To: Marc Zyngier, Stephen Rothwell
Cc: Linux Next Mailing List, Thomas Gleixner, John Garry,
Linux Kernel Mailing List, Linux ARM
Reverted the linux-next commit f068a62c548c ("irqchip/gic-v3-its:
Balance initial LPI affinity across CPUs") fixed these warnings during
boot,
its_select_cpu at drivers/irqchip/irq-gic-v3-its.c:1572
[ 332.819381][ T3359] BUG: sleeping function called from invalid
context at mm/slab.h:568
[ 332.827405][ T3359] in_atomic(): 1, irqs_disabled(): 128,
non_block: 0, pid: 3359, name: irqbalance
[ 332.836455][ T3359] INFO: lockdep is turned off.
[ 332.841076][ T3359] irq event stamp: 0
[ 332.844836][ T3359] hardirqs last enabled at (0): [<0000000000000000>] 0x0
[ 332.851828][ T3359] hardirqs last disabled at (0):
[<ffff9000101ea65c>] copy_process+0x98c/0x1f34
[ 332.860710][ T3359] softirqs last enabled at (0):
[<ffff9000101ea690>] copy_process+0x9c0/0x1f34
[ 332.869586][ T3359] softirqs last disabled at (0): [<0000000000000000>] 0x0
[ 332.876560][ T3359] CPU: 155 PID: 3359 Comm: irqbalance Tainted: G
W L 5.7.0-rc6-next-20200519 #1
[ 332.886563][ T3359] Hardware name: HPE Apollo 70
/C01_APACHE_MB , BIOS L50_5.13_1.11 06/18/2019
[ 332.897000][ T3359] Call trace:
[ 332.900151][ T3359] dump_backtrace+0x0/0x22c
[ 332.904514][ T3359] show_stack+0x28/0x34
[ 332.908543][ T3359] dump_stack+0x104/0x194
[ 332.912738][ T3359] ___might_sleep+0x314/0x328
[ 332.917274][ T3359] __might_sleep+0x7c/0xe0
[ 332.921563][ T3359] slab_pre_alloc_hook+0x44/0x8c
[ 332.926360][ T3359] __kmalloc_node+0xb0/0x618
[ 332.930811][ T3359] alloc_cpumask_var_node+0x48/0x94
[ 332.935868][ T3359] alloc_cpumask_var+0x10/0x1c
[ 332.940496][ T3359] its_select_cpu+0x58/0x2e4
[ 332.944945][ T3359] its_set_affinity+0xe8/0x27c
[ 332.949576][ T3359] msi_domain_set_affinity+0x78/0x114
[ 332.954813][ T3359] irq_do_set_affinity+0x84/0x198
[ 332.959697][ T3359] irq_set_affinity_locked+0x80/0x1a8
[ 332.964927][ T3359] __irq_set_affinity+0x54/0x84
[ 332.969637][ T3359] write_irq_affinity+0x16c/0x198
[ 332.974520][ T3359] irq_affinity_proc_write+0x34/0x44
[ 332.979672][ T3359] pde_write+0x5c/0x78
[ 332.983602][ T3359] proc_reg_write+0x74/0xc0
[ 332.987974][ T3359] __vfs_write+0x84/0x1d8
[ 332.992163][ T3359] vfs_write+0x13c/0x1b8
[ 332.996265][ T3359] ksys_write+0xb0/0x120
[ 333.000385][ T3359] __arm64_sys_write+0x54/0x88
[ 333.005017][ T3359] do_el0_svc+0x128/0x1dc
[ 333.009213][ T3359] el0_sync_handler+0xd0/0x268
[ 333.013836][ T3359] el0_sync+0x164/0x180
[ 336.527739][ T3356] mlx5_core 0000:0b:00.1 enp11s0f1np1: Link down
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] ARM: pass -msoft-float to gcc earlier
From: Arnd Bergmann @ 2020-05-19 22:08 UTC (permalink / raw)
To: Russell King
Cc: Arnd Bergmann, Szabolcs Nagy, Linus Walleij, Nick Desaulniers,
linux-kernel, Masahiro Yamada, linux-arm-kernel
Szabolcs Nagy ran into a kernel build failure with a custom gcc
toochain that sets -mfpu=auto -mfloat-abi=hard:
/tmp/ccmNdcdf.s:1898: Error: selected processor does not support `cpsid i' in ARM mode
The problem is that $(call cc-option, -march=armv7-a) fails before the
kernel overrides the gcc options to also pass -msoft-float.
Move the option to the beginning the Makefile, before we call
cc-option for the first time.
Reported-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87302
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
arch/arm/Makefile | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 7d5cd0f85461..e428ea6eb0fa 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -16,6 +16,8 @@ LDFLAGS_vmlinux += --be8
KBUILD_LDFLAGS_MODULE += --be8
endif
+KBUILD_CFLAGS += -msoft-float
+
ifeq ($(CONFIG_ARM_MODULE_PLTS),y)
KBUILD_LDS_MODULE += $(srctree)/arch/arm/kernel/module.lds
endif
@@ -135,7 +137,7 @@ AFLAGS_ISA :=$(CFLAGS_ISA)
endif
# Need -Uarm for gcc < 3.x
-KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
+KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -Uarm
KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_ISA) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float
CHECKFLAGS += -D__arm__
--
2.26.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ 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