* [PATCH v2 net] net: mscc: ocelot: unregister the PTP clock on deinit
@ 2019-11-28 11:23 Vladimir Oltean
2019-11-29 3:55 ` Y.b. Lu
2019-11-29 7:13 ` David Miller
0 siblings, 2 replies; 3+ messages in thread
From: Vladimir Oltean @ 2019-11-28 11:23 UTC (permalink / raw)
To: davem, richardcochran
Cc: andrew, f.fainelli, vivien.didelot, claudiu.manoil,
alexandru.marginean, xiaoliang.yang_1, yangbo.lu, netdev,
alexandre.belloni, UNGLinuxDriver, Vladimir Oltean,
Antoine Tenart
From: Vladimir Oltean <vladimir.oltean@nxp.com>
Currently a switch driver deinit frees the regmaps, but the PTP clock is
still out there, available to user space via /dev/ptpN. Any PTP
operation is a ticking time bomb, since it will attempt to use the freed
regmaps and thus trigger kernel panics:
[ 4.291746] fsl_enetc 0000:00:00.2 eth1: error -22 setting up slave phy
[ 4.291871] mscc_felix 0000:00:00.5: Failed to register DSA switch: -22
[ 4.308666] mscc_felix: probe of 0000:00:00.5 failed with error -22
[ 6.358270] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000088
[ 6.367090] Mem abort info:
[ 6.369888] ESR = 0x96000046
[ 6.369891] EC = 0x25: DABT (current EL), IL = 32 bits
[ 6.369892] SET = 0, FnV = 0
[ 6.369894] EA = 0, S1PTW = 0
[ 6.369895] Data abort info:
[ 6.369897] ISV = 0, ISS = 0x00000046
[ 6.369899] CM = 0, WnR = 1
[ 6.369902] user pgtable: 4k pages, 48-bit VAs, pgdp=00000020d58c7000
[ 6.369904] [0000000000000088] pgd=00000020d5912003, pud=00000020d5915003, pmd=0000000000000000
[ 6.369914] Internal error: Oops: 96000046 [#1] PREEMPT SMP
[ 6.420443] Modules linked in:
[ 6.423506] CPU: 1 PID: 262 Comm: phc_ctl Not tainted 5.4.0-03625-gb7b2a5dadd7f #204
[ 6.431273] Hardware name: LS1028A RDB Board (DT)
[ 6.435989] pstate: 40000085 (nZcv daIf -PAN -UAO)
[ 6.440802] pc : css_release+0x24/0x58
[ 6.444561] lr : regmap_read+0x40/0x78
[ 6.448316] sp : ffff800010513cc0
[ 6.451636] x29: ffff800010513cc0 x28: ffff002055873040
[ 6.456963] x27: 0000000000000000 x26: 0000000000000000
[ 6.462289] x25: 0000000000000000 x24: 0000000000000000
[ 6.467617] x23: 0000000000000000 x22: 0000000000000080
[ 6.472944] x21: ffff800010513d44 x20: 0000000000000080
[ 6.478270] x19: 0000000000000000 x18: 0000000000000000
[ 6.483596] x17: 0000000000000000 x16: 0000000000000000
[ 6.488921] x15: 0000000000000000 x14: 0000000000000000
[ 6.494247] x13: 0000000000000000 x12: 0000000000000000
[ 6.499573] x11: 0000000000000000 x10: 0000000000000000
[ 6.504899] x9 : 0000000000000000 x8 : 0000000000000000
[ 6.510225] x7 : 0000000000000000 x6 : ffff800010513cf0
[ 6.515550] x5 : 0000000000000000 x4 : 0000000fffffffe0
[ 6.520876] x3 : 0000000000000088 x2 : ffff800010513d44
[ 6.526202] x1 : ffffcada668ea000 x0 : ffffcada64d8b0c0
[ 6.531528] Call trace:
[ 6.533977] css_release+0x24/0x58
[ 6.537385] regmap_read+0x40/0x78
[ 6.540795] __ocelot_read_ix+0x6c/0xa0
[ 6.544641] ocelot_ptp_gettime64+0x4c/0x110
[ 6.548921] ptp_clock_gettime+0x4c/0x58
[ 6.552853] pc_clock_gettime+0x5c/0xa8
[ 6.556699] __arm64_sys_clock_gettime+0x68/0xc8
[ 6.561331] el0_svc_common.constprop.2+0x7c/0x178
[ 6.566133] el0_svc_handler+0x34/0xa0
[ 6.569891] el0_sync_handler+0x114/0x1d0
[ 6.573908] el0_sync+0x140/0x180
[ 6.577232] Code: d503201f b00119a1 91022263 b27b7be4 (f9004663)
[ 6.583349] ---[ end trace d196b9b14cdae2da ]---
[ 6.587977] Kernel panic - not syncing: Fatal exception
[ 6.593216] SMP: stopping secondary CPUs
[ 6.597151] Kernel Offset: 0x4ada54400000 from 0xffff800010000000
[ 6.603261] PHYS_OFFSET: 0xffffd0a7c0000000
[ 6.607454] CPU features: 0x10002,21806008
[ 6.611558] Memory Limit: none
And now that ocelot->ptp_clock is checked at exit, prevent a potential
error where ptp_clock_register returned a pointer-encoded error, which
we are keeping in the ocelot private data structure. So now,
ocelot->ptp_clock is now either NULL or a valid pointer.
Fixes: 4e3b0468e6d7 ("net: mscc: PTP Hardware Clock (PHC) support")
Cc: Antoine Tenart <antoine.tenart@bootlin.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Changes in v2:
- Dropped the redundant check on ocelot->ptp and changed the topic of
the if condition.
- Populated ocelot->ptp_clock in ocelot_init_timestamp only on valid
return value from ptp_clock_register, so that the deinit check can
never mis-trigger.
drivers/net/ethernet/mscc/ocelot.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index 52a1b1f12af8..875eea702c58 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -2166,16 +2166,26 @@ static struct ptp_clock_info ocelot_ptp_clock_info = {
.adjfine = ocelot_ptp_adjfine,
};
+static void ocelot_deinit_timestamp(struct ocelot *ocelot)
+{
+ if (ocelot->ptp_clock)
+ ptp_clock_unregister(ocelot->ptp_clock);
+}
+
static int ocelot_init_timestamp(struct ocelot *ocelot)
{
+ struct ptp_clock *ptp_clock;
+
ocelot->ptp_info = ocelot_ptp_clock_info;
- ocelot->ptp_clock = ptp_clock_register(&ocelot->ptp_info, ocelot->dev);
- if (IS_ERR(ocelot->ptp_clock))
- return PTR_ERR(ocelot->ptp_clock);
+ ptp_clock = ptp_clock_register(&ocelot->ptp_info, ocelot->dev);
+ if (IS_ERR(ptp_clock))
+ return PTR_ERR(ptp_clock);
/* Check if PHC support is missing at the configuration level */
- if (!ocelot->ptp_clock)
+ if (!ptp_clock)
return 0;
+ ocelot->ptp_clock = ptp_clock;
+
ocelot_write(ocelot, SYS_PTP_CFG_PTP_STAMP_WID(30), SYS_PTP_CFG);
ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_LOW);
ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_HIGH);
@@ -2508,6 +2518,7 @@ void ocelot_deinit(struct ocelot *ocelot)
destroy_workqueue(ocelot->stats_queue);
mutex_destroy(&ocelot->stats_lock);
ocelot_ace_deinit();
+ ocelot_deinit_timestamp(ocelot);
for (i = 0; i < ocelot->num_phys_ports; i++) {
port = ocelot->ports[i];
--
2.17.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* RE: [PATCH v2 net] net: mscc: ocelot: unregister the PTP clock on deinit
2019-11-28 11:23 [PATCH v2 net] net: mscc: ocelot: unregister the PTP clock on deinit Vladimir Oltean
@ 2019-11-29 3:55 ` Y.b. Lu
2019-11-29 7:13 ` David Miller
1 sibling, 0 replies; 3+ messages in thread
From: Y.b. Lu @ 2019-11-29 3:55 UTC (permalink / raw)
To: Vladimir Oltean, davem, richardcochran
Cc: andrew, f.fainelli, vivien.didelot, Claudiu Manoil,
Alexandru Marginean, Xiaoliang Yang, netdev, alexandre.belloni,
UNGLinuxDriver, Vladimir Oltean, Antoine Tenart
> -----Original Message-----
> From: Vladimir Oltean <olteanv@gmail.com>
> Sent: Thursday, November 28, 2019 7:24 PM
> To: davem@davemloft.net; richardcochran@gmail.com
> Cc: andrew@lunn.ch; f.fainelli@gmail.com; vivien.didelot@gmail.com;
> Claudiu Manoil <claudiu.manoil@nxp.com>; Alexandru Marginean
> <alexandru.marginean@nxp.com>; Xiaoliang Yang
> <xiaoliang.yang_1@nxp.com>; Y.b. Lu <yangbo.lu@nxp.com>;
> netdev@vger.kernel.org; alexandre.belloni@bootlin.com;
> UNGLinuxDriver@microchip.com; Vladimir Oltean
> <vladimir.oltean@nxp.com>; Antoine Tenart <antoine.tenart@bootlin.com>
> Subject: [PATCH v2 net] net: mscc: ocelot: unregister the PTP clock on deinit
[Y.b. Lu]
Acked-by: Yangbo Lu <yangbo.lu@nxp.com>
>
> From: Vladimir Oltean <vladimir.oltean@nxp.com>
>
> Currently a switch driver deinit frees the regmaps, but the PTP clock is still out
> there, available to user space via /dev/ptpN. Any PTP operation is a ticking
> time bomb, since it will attempt to use the freed regmaps and thus trigger
> kernel panics:
>
> [ 4.291746] fsl_enetc 0000:00:00.2 eth1: error -22 setting up slave phy
> [ 4.291871] mscc_felix 0000:00:00.5: Failed to register DSA switch: -22
> [ 4.308666] mscc_felix: probe of 0000:00:00.5 failed with error -22
> [ 6.358270] Unable to handle kernel NULL pointer dereference at virtual
> address 0000000000000088
> [ 6.367090] Mem abort info:
> [ 6.369888] ESR = 0x96000046
> [ 6.369891] EC = 0x25: DABT (current EL), IL = 32 bits
> [ 6.369892] SET = 0, FnV = 0
> [ 6.369894] EA = 0, S1PTW = 0
> [ 6.369895] Data abort info:
> [ 6.369897] ISV = 0, ISS = 0x00000046
> [ 6.369899] CM = 0, WnR = 1
> [ 6.369902] user pgtable: 4k pages, 48-bit VAs, pgdp=00000020d58c7000
> [ 6.369904] [0000000000000088] pgd=00000020d5912003,
> pud=00000020d5915003, pmd=0000000000000000
> [ 6.369914] Internal error: Oops: 96000046 [#1] PREEMPT SMP
> [ 6.420443] Modules linked in:
> [ 6.423506] CPU: 1 PID: 262 Comm: phc_ctl Not tainted
> 5.4.0-03625-gb7b2a5dadd7f #204
> [ 6.431273] Hardware name: LS1028A RDB Board (DT)
> [ 6.435989] pstate: 40000085 (nZcv daIf -PAN -UAO)
> [ 6.440802] pc : css_release+0x24/0x58
> [ 6.444561] lr : regmap_read+0x40/0x78
> [ 6.448316] sp : ffff800010513cc0
> [ 6.451636] x29: ffff800010513cc0 x28: ffff002055873040
> [ 6.456963] x27: 0000000000000000 x26: 0000000000000000
> [ 6.462289] x25: 0000000000000000 x24: 0000000000000000
> [ 6.467617] x23: 0000000000000000 x22: 0000000000000080
> [ 6.472944] x21: ffff800010513d44 x20: 0000000000000080
> [ 6.478270] x19: 0000000000000000 x18: 0000000000000000
> [ 6.483596] x17: 0000000000000000 x16: 0000000000000000
> [ 6.488921] x15: 0000000000000000 x14: 0000000000000000
> [ 6.494247] x13: 0000000000000000 x12: 0000000000000000
> [ 6.499573] x11: 0000000000000000 x10: 0000000000000000
> [ 6.504899] x9 : 0000000000000000 x8 : 0000000000000000
> [ 6.510225] x7 : 0000000000000000 x6 : ffff800010513cf0
> [ 6.515550] x5 : 0000000000000000 x4 : 0000000fffffffe0
> [ 6.520876] x3 : 0000000000000088 x2 : ffff800010513d44
> [ 6.526202] x1 : ffffcada668ea000 x0 : ffffcada64d8b0c0
> [ 6.531528] Call trace:
> [ 6.533977] css_release+0x24/0x58
> [ 6.537385] regmap_read+0x40/0x78
> [ 6.540795] __ocelot_read_ix+0x6c/0xa0
> [ 6.544641] ocelot_ptp_gettime64+0x4c/0x110
> [ 6.548921] ptp_clock_gettime+0x4c/0x58
> [ 6.552853] pc_clock_gettime+0x5c/0xa8
> [ 6.556699] __arm64_sys_clock_gettime+0x68/0xc8
> [ 6.561331] el0_svc_common.constprop.2+0x7c/0x178
> [ 6.566133] el0_svc_handler+0x34/0xa0
> [ 6.569891] el0_sync_handler+0x114/0x1d0
> [ 6.573908] el0_sync+0x140/0x180
> [ 6.577232] Code: d503201f b00119a1 91022263 b27b7be4 (f9004663)
> [ 6.583349] ---[ end trace d196b9b14cdae2da ]---
> [ 6.587977] Kernel panic - not syncing: Fatal exception
> [ 6.593216] SMP: stopping secondary CPUs
> [ 6.597151] Kernel Offset: 0x4ada54400000 from 0xffff800010000000
> [ 6.603261] PHYS_OFFSET: 0xffffd0a7c0000000
> [ 6.607454] CPU features: 0x10002,21806008
> [ 6.611558] Memory Limit: none
>
> And now that ocelot->ptp_clock is checked at exit, prevent a potential error
> where ptp_clock_register returned a pointer-encoded error, which we are
> keeping in the ocelot private data structure. So now,
> ocelot->ptp_clock is now either NULL or a valid pointer.
>
> Fixes: 4e3b0468e6d7 ("net: mscc: PTP Hardware Clock (PHC) support")
> Cc: Antoine Tenart <antoine.tenart@bootlin.com>
> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
> ---
> Changes in v2:
> - Dropped the redundant check on ocelot->ptp and changed the topic of
> the if condition.
> - Populated ocelot->ptp_clock in ocelot_init_timestamp only on valid
> return value from ptp_clock_register, so that the deinit check can
> never mis-trigger.
>
> drivers/net/ethernet/mscc/ocelot.c | 19 +++++++++++++++----
> 1 file changed, 15 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/ethernet/mscc/ocelot.c
> b/drivers/net/ethernet/mscc/ocelot.c
> index 52a1b1f12af8..875eea702c58 100644
> --- a/drivers/net/ethernet/mscc/ocelot.c
> +++ b/drivers/net/ethernet/mscc/ocelot.c
> @@ -2166,16 +2166,26 @@ static struct ptp_clock_info
> ocelot_ptp_clock_info = {
> .adjfine = ocelot_ptp_adjfine,
> };
>
> +static void ocelot_deinit_timestamp(struct ocelot *ocelot) {
> + if (ocelot->ptp_clock)
> + ptp_clock_unregister(ocelot->ptp_clock);
> +}
> +
> static int ocelot_init_timestamp(struct ocelot *ocelot) {
> + struct ptp_clock *ptp_clock;
> +
> ocelot->ptp_info = ocelot_ptp_clock_info;
> - ocelot->ptp_clock = ptp_clock_register(&ocelot->ptp_info, ocelot->dev);
> - if (IS_ERR(ocelot->ptp_clock))
> - return PTR_ERR(ocelot->ptp_clock);
> + ptp_clock = ptp_clock_register(&ocelot->ptp_info, ocelot->dev);
> + if (IS_ERR(ptp_clock))
> + return PTR_ERR(ptp_clock);
> /* Check if PHC support is missing at the configuration level */
> - if (!ocelot->ptp_clock)
> + if (!ptp_clock)
> return 0;
>
> + ocelot->ptp_clock = ptp_clock;
> +
> ocelot_write(ocelot, SYS_PTP_CFG_PTP_STAMP_WID(30), SYS_PTP_CFG);
> ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_LOW);
> ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_HIGH); @@ -2508,6
> +2518,7 @@ void ocelot_deinit(struct ocelot *ocelot)
> destroy_workqueue(ocelot->stats_queue);
> mutex_destroy(&ocelot->stats_lock);
> ocelot_ace_deinit();
> + ocelot_deinit_timestamp(ocelot);
>
> for (i = 0; i < ocelot->num_phys_ports; i++) {
> port = ocelot->ports[i];
> --
> 2.17.1
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v2 net] net: mscc: ocelot: unregister the PTP clock on deinit
2019-11-28 11:23 [PATCH v2 net] net: mscc: ocelot: unregister the PTP clock on deinit Vladimir Oltean
2019-11-29 3:55 ` Y.b. Lu
@ 2019-11-29 7:13 ` David Miller
1 sibling, 0 replies; 3+ messages in thread
From: David Miller @ 2019-11-29 7:13 UTC (permalink / raw)
To: olteanv
Cc: richardcochran, andrew, f.fainelli, vivien.didelot,
claudiu.manoil, alexandru.marginean, xiaoliang.yang_1, yangbo.lu,
netdev, alexandre.belloni, UNGLinuxDriver, vladimir.oltean,
antoine.tenart
From: Vladimir Oltean <olteanv@gmail.com>
Date: Thu, 28 Nov 2019 13:23:42 +0200
> +static void ocelot_deinit_timestamp(struct ocelot *ocelot)
> +{
> + if (ocelot->ptp_clock)
> + ptp_clock_unregister(ocelot->ptp_clock);
> +}
No need for a helper function, you're calling this in only _one_ place.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2019-11-29 7:13 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-28 11:23 [PATCH v2 net] net: mscc: ocelot: unregister the PTP clock on deinit Vladimir Oltean
2019-11-29 3:55 ` Y.b. Lu
2019-11-29 7:13 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).