Skip to content

Commit 912c0a7

Browse files
committed
powerpc/64s: Save FSCR to init_task.thread.fscr after feature init
At boot the FSCR is initialised via one of two paths. On most systems it's set to a hard coded value in __init_FSCR(). On newer skiboot systems we use the device tree CPU features binding, where firmware can tell Linux what bits to set in FSCR (and HFSCR). In both cases the value that's configured at boot is not propagated into the init_task.thread.fscr value prior to the initial fork of init (pid 1), which means the value is not used by any processes other than swapper (the idle task). For the __init_FSCR() case this is OK, because the value in init_task.thread.fscr is initialised to something sensible. However it does mean that the value set in __init_FSCR() is not used other than for swapper, which is odd and confusing. The bigger problem is for the device tree CPU features case it prevents firmware from setting (or clearing) FSCR bits for use by user space. This means all existing kernels can not have features enabled/disabled by firmware if those features require setting/clearing FSCR bits. We can handle both cases by saving the FSCR value into init_task.thread.fscr after we have initialised it at boot. This fixes the bug for device tree CPU features, and will allow us to simplify the initialisation for the __init_FSCR() case in a future patch. Fixes: 5a61ef7 ("powerpc/64s: Support new device tree binding for discovering CPU features") Cc: [email protected] # v4.12+ Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 993e3d9 commit 912c0a7

File tree

1 file changed

+19
-0
lines changed

1 file changed

+19
-0
lines changed

arch/powerpc/kernel/prom.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,23 @@ static void __init tm_init(void)
690690
static void tm_init(void) { }
691691
#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
692692

693+
#ifdef CONFIG_PPC64
694+
static void __init save_fscr_to_task(void)
695+
{
696+
/*
697+
* Ensure the init_task (pid 0, aka swapper) uses the value of FSCR we
698+
* have configured via the device tree features or via __init_FSCR().
699+
* That value will then be propagated to pid 1 (init) and all future
700+
* processes.
701+
*/
702+
if (early_cpu_has_feature(CPU_FTR_ARCH_207S))
703+
init_task.thread.fscr = mfspr(SPRN_FSCR);
704+
}
705+
#else
706+
static inline void save_fscr_to_task(void) {};
707+
#endif
708+
709+
693710
void __init early_init_devtree(void *params)
694711
{
695712
phys_addr_t limit;
@@ -778,6 +795,8 @@ void __init early_init_devtree(void *params)
778795
BUG();
779796
}
780797

798+
save_fscr_to_task();
799+
781800
#if defined(CONFIG_SMP) && defined(CONFIG_PPC64)
782801
/* We'll later wait for secondaries to check in; there are
783802
* NCPUS-1 non-boot CPUs :-)

0 commit comments

Comments
 (0)