powerpc/iseries: Fix early init access to lppaca

The combination of commit

8154c5d2 and
93c22703

Broke boot on iSeries.

The problem is that iSeries very early boot code, which generates
the device-tree and runs before our normal early initializations
does need access the lppaca's very early, before the PACA array is
initialized, and in fact even before the boot PACA has been
initialized (it contains all 0's at this stage).

However, the first patch above makes that code use the new
llpaca_of(cpu) accessor, which itself is changed by the second patch to
use the PACA array.

We fix that by reverting iSeries to directly dereferencing the array. In
addition, we fix all iterators in the iSeries code to always skip CPU
whose number is above 63 which is the maximum size of that array and
the maximum number of supported CPUs on these machines.

Additionally, we make sure the boot_paca is properly initialized
in our early startup code.
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent a5abba98
...@@ -33,9 +33,25 @@ ...@@ -33,9 +33,25 @@
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
#include <linux/cache.h> #include <linux/cache.h>
#include <linux/threads.h>
#include <asm/types.h> #include <asm/types.h>
#include <asm/mmu.h> #include <asm/mmu.h>
/*
* We only have to have statically allocated lppaca structs on
* legacy iSeries, which supports at most 64 cpus.
*/
#ifdef CONFIG_PPC_ISERIES
#if NR_CPUS < 64
#define NR_LPPACAS NR_CPUS
#else
#define NR_LPPACAS 64
#endif
#else /* not iSeries */
#define NR_LPPACAS 1
#endif
/* The Hypervisor barfs if the lppaca crosses a page boundary. A 1k /* The Hypervisor barfs if the lppaca crosses a page boundary. A 1k
* alignment is sufficient to prevent this */ * alignment is sufficient to prevent this */
struct lppaca { struct lppaca {
......
...@@ -26,20 +26,6 @@ extern unsigned long __toc_start; ...@@ -26,20 +26,6 @@ extern unsigned long __toc_start;
#ifdef CONFIG_PPC_BOOK3S #ifdef CONFIG_PPC_BOOK3S
/*
* We only have to have statically allocated lppaca structs on
* legacy iSeries, which supports at most 64 cpus.
*/
#ifdef CONFIG_PPC_ISERIES
#if NR_CPUS < 64
#define NR_LPPACAS NR_CPUS
#else
#define NR_LPPACAS 64
#endif
#else /* not iSeries */
#define NR_LPPACAS 1
#endif
/* /*
* The structure which the hypervisor knows about - this structure * The structure which the hypervisor knows about - this structure
* should not cross a page boundary. The vpa_init/register_vpa call * should not cross a page boundary. The vpa_init/register_vpa call
......
...@@ -242,8 +242,8 @@ static void __init dt_cpus(struct iseries_flat_dt *dt) ...@@ -242,8 +242,8 @@ static void __init dt_cpus(struct iseries_flat_dt *dt)
pft_size[0] = 0; /* NUMA CEC cookie, 0 for non NUMA */ pft_size[0] = 0; /* NUMA CEC cookie, 0 for non NUMA */
pft_size[1] = __ilog2(HvCallHpt_getHptPages() * HW_PAGE_SIZE); pft_size[1] = __ilog2(HvCallHpt_getHptPages() * HW_PAGE_SIZE);
for (i = 0; i < NR_CPUS; i++) { for (i = 0; i < NR_LPPACAS; i++) {
if (lppaca_of(i).dyn_proc_status >= 2) if (lppaca[i].dyn_proc_status >= 2)
continue; continue;
snprintf(p, 32 - (p - buf), "@%d", i); snprintf(p, 32 - (p - buf), "@%d", i);
...@@ -251,7 +251,7 @@ static void __init dt_cpus(struct iseries_flat_dt *dt) ...@@ -251,7 +251,7 @@ static void __init dt_cpus(struct iseries_flat_dt *dt)
dt_prop_str(dt, "device_type", device_type_cpu); dt_prop_str(dt, "device_type", device_type_cpu);
index = lppaca_of(i).dyn_hv_phys_proc_index; index = lppaca[i].dyn_hv_phys_proc_index;
d = &xIoHriProcessorVpd[index]; d = &xIoHriProcessorVpd[index];
dt_prop_u32(dt, "i-cache-size", d->xInstCacheSize * 1024); dt_prop_u32(dt, "i-cache-size", d->xInstCacheSize * 1024);
......
...@@ -680,6 +680,7 @@ void * __init iSeries_early_setup(void) ...@@ -680,6 +680,7 @@ void * __init iSeries_early_setup(void)
* on but calling this function multiple times is fine. * on but calling this function multiple times is fine.
*/ */
identify_cpu(0, mfspr(SPRN_PVR)); identify_cpu(0, mfspr(SPRN_PVR));
initialise_paca(&boot_paca, 0);
powerpc_firmware_features |= FW_FEATURE_ISERIES; powerpc_firmware_features |= FW_FEATURE_ISERIES;
powerpc_firmware_features |= FW_FEATURE_LPAR; powerpc_firmware_features |= FW_FEATURE_LPAR;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment