[PATCH 3.16 261/328] powerpc/pseries: Fix unitialized timer reset on migration

From: Ben Hutchings
Date: Sun Dec 09 2018 - 17:01:09 EST

3.16.62-rc1 review patch. If anyone has any objections, please let me know.


From: Michael Bringmann <mwb@xxxxxxxxxxxxxxxxxx>

commit 8604895a34d92f5e186ceb931b0d1b384030ea3d upstream.

After migration of a powerpc LPAR, the kernel executes code to
update the system state to reflect new platform characteristics.

Such changes include modifications to device tree properties provided
to the system by PHYP. Property notifications received by the
post_mobility_fixup() code are passed along to the kernel in general
through a call to of_update_property() which in turn passes such
events back to all modules through entries like the '.notifier_call'
function within the NUMA module.

When the NUMA module updates its state, it resets its event timer. If
this occurs after a previous call to stop_topology_update() or on a
system without VPHN enabled, the code runs into an unitialized timer
structure and crashes. This patch adds a safety check along this path
toward the problem code.

An example crash log is as follows.

ibmvscsi 30000081: Re-enabling adapter!
------------[ cut here ]------------
kernel BUG at kernel/time/timer.c:958!
Oops: Exception in kernel mode, sig: 5 [#1]
LE SMP NR_CPUS=2048 NUMA pSeries
Modules linked in: nfsv3 nfs_acl nfs tcp_diag udp_diag inet_diag lockd unix_diag af_packet_diag netlink_diag grace fscache sunrpc xts vmx_crypto pseries_rng sg binfmt_misc ip_tables xfs libcrc32c sd_mod ibmvscsi ibmveth scsi_transport_srp dm_mirror dm_region_hash dm_log dm_mod
CPU: 11 PID: 3067 Comm: drmgr Not tainted 4.17.0+ #179
NIP mod_timer+0x4c/0x400
LR reset_topology_timer+0x40/0x60
Call Trace:
0xc0000003f9407830 (unreliable)

Fixes: 5d88aa85c00b ("powerpc/pseries: Update CPU maps when device tree is updated")
Signed-off-by: Michael Bringmann <mwb@xxxxxxxxxxxxxxxxxx>
Signed-off-by: Michael Ellerman <mpe@xxxxxxxxxxxxxx>
[bwh: Backported to 3.16: Also remove direct assignment to
topology_timer.expires, done upstream as part of commit df7e828c1b69
"timer: Remove init_timer_deferrable() in favor of timer_setup()"]
Signed-off-by: Ben Hutchings <ben@xxxxxxxxxxxxxxx>
arch/powerpc/mm/numa.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -1654,8 +1654,8 @@ static struct timer_list topology_timer
static void reset_topology_timer(void)
topology_timer.data = 0;
- topology_timer.expires = jiffies + 60 * HZ;
- mod_timer(&topology_timer, topology_timer.expires);
+ if (vphn_enabled)
+ mod_timer(&topology_timer, jiffies + 60 * HZ);