@@ -17,6 +17,7 @@
#include <asm/sections.h>
#include <asm/pgtable.h>
#include <asm/kexec.h>
+#include <asm/svm.h>
#include "setup.h"
@@ -25,6 +26,33 @@
#endif
#define LPPACA_SIZE 0x400
+#define SHARED_LPPACA_SIZE PAGE_ALIGN(LPPACA_SIZE * CONFIG_NR_CPUS)
+
+static phys_addr_t shared_lppaca_pa;
+static unsigned long shared_lppaca_size;
+
+static void *__init alloc_shared_lppaca(unsigned long size, unsigned long align,
+ unsigned long limit, int cpu)
+{
+ unsigned long pa;
+
+ if (!shared_lppaca_pa) {
+ memblock_set_bottom_up(true);
+ shared_lppaca_pa = memblock_alloc_base_nid(SHARED_LPPACA_SIZE,
+ PAGE_SIZE, limit, -1, MEMBLOCK_NONE);
+ if (!shared_lppaca_pa)
+ panic("cannot allocate shared data");
+ memblock_set_bottom_up(false);
+ mem_convert_shared(PHYS_PFN(shared_lppaca_pa),
+ SHARED_LPPACA_SIZE / PAGE_SIZE);
+ }
+
+ pa = shared_lppaca_pa + shared_lppaca_size;
+ shared_lppaca_size += size;
+
+ BUG_ON(shared_lppaca_size >= SHARED_LPPACA_SIZE);
+ return __va(pa);
+}
static void *__init alloc_paca_data(unsigned long size, unsigned long align,
unsigned long limit, int cpu)
@@ -88,7 +116,11 @@ static struct lppaca * __init new_lppaca(int cpu, unsigned long limit)
if (early_cpu_has_feature(CPU_FTR_HVMODE))
return NULL;
- lp = alloc_paca_data(LPPACA_SIZE, 0x400, limit, cpu);
+ if (is_svm_platform())
+ lp = alloc_shared_lppaca(LPPACA_SIZE, 0x400, limit, cpu);
+ else
+ lp = alloc_paca_data(LPPACA_SIZE, 0x400, limit, cpu);
+
init_lppaca(lp);
return lp;