Merge tag 'v3.12-rc4' into sched/core
Merge Linux v3.12-rc4 to fix a conflict and also to refresh the tree before applying more scheduler patches. Conflicts: arch/avr32/include/asm/Kbuild Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
@@ -74,7 +74,7 @@ src-wlib-$(CONFIG_8xx) += mpc8xx.c planetcore.c
|
||||
src-wlib-$(CONFIG_PPC_82xx) += pq2.c fsl-soc.c planetcore.c
|
||||
src-wlib-$(CONFIG_EMBEDDED6xx) += mv64x60.c mv64x60_i2c.c ugecon.c
|
||||
|
||||
src-plat-y := of.c
|
||||
src-plat-y := of.c epapr.c
|
||||
src-plat-$(CONFIG_40x) += fixed-head.S ep405.c cuboot-hotfoot.c \
|
||||
treeboot-walnut.c cuboot-acadia.c \
|
||||
cuboot-kilauea.c simpleboot.c \
|
||||
@@ -97,7 +97,7 @@ src-plat-$(CONFIG_EMBEDDED6xx) += cuboot-pq2.c cuboot-mpc7448hpc2.c \
|
||||
prpmc2800.c
|
||||
src-plat-$(CONFIG_AMIGAONE) += cuboot-amigaone.c
|
||||
src-plat-$(CONFIG_PPC_PS3) += ps3-head.S ps3-hvcall.S ps3.c
|
||||
src-plat-$(CONFIG_EPAPR_BOOT) += epapr.c
|
||||
src-plat-$(CONFIG_EPAPR_BOOT) += epapr.c epapr-wrapper.c
|
||||
|
||||
src-wlib := $(sort $(src-wlib-y))
|
||||
src-plat := $(sort $(src-plat-y))
|
||||
|
||||
9
arch/powerpc/boot/epapr-wrapper.c
Normal file
9
arch/powerpc/boot/epapr-wrapper.c
Normal file
@@ -0,0 +1,9 @@
|
||||
extern void epapr_platform_init(unsigned long r3, unsigned long r4,
|
||||
unsigned long r5, unsigned long r6,
|
||||
unsigned long r7);
|
||||
|
||||
void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7)
|
||||
{
|
||||
epapr_platform_init(r3, r4, r5, r6, r7);
|
||||
}
|
||||
@@ -48,8 +48,8 @@ static void platform_fixups(void)
|
||||
fdt_addr, fdt_totalsize((void *)fdt_addr), ima_size);
|
||||
}
|
||||
|
||||
void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7)
|
||||
void epapr_platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7)
|
||||
{
|
||||
epapr_magic = r6;
|
||||
ima_size = r7;
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
|
||||
static unsigned long claim_base;
|
||||
|
||||
void epapr_platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7);
|
||||
|
||||
static void *of_try_claim(unsigned long size)
|
||||
{
|
||||
unsigned long addr = 0;
|
||||
@@ -61,7 +64,7 @@ static void of_image_hdr(const void *hdr)
|
||||
}
|
||||
}
|
||||
|
||||
void platform_init(unsigned long a1, unsigned long a2, void *promptr)
|
||||
static void of_platform_init(unsigned long a1, unsigned long a2, void *promptr)
|
||||
{
|
||||
platform_ops.image_hdr = of_image_hdr;
|
||||
platform_ops.malloc = of_try_claim;
|
||||
@@ -81,3 +84,14 @@ void platform_init(unsigned long a1, unsigned long a2, void *promptr)
|
||||
loader_info.initrd_size = a2;
|
||||
}
|
||||
}
|
||||
|
||||
void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7)
|
||||
{
|
||||
/* Detect OF vs. ePAPR boot */
|
||||
if (r5)
|
||||
of_platform_init(r3, r4, (void *)r5);
|
||||
else
|
||||
epapr_platform_init(r3, r4, r5, r6, r7);
|
||||
}
|
||||
|
||||
|
||||
@@ -148,18 +148,18 @@ make_space=y
|
||||
|
||||
case "$platform" in
|
||||
pseries)
|
||||
platformo=$object/of.o
|
||||
platformo="$object/of.o $object/epapr.o"
|
||||
link_address='0x4000000'
|
||||
;;
|
||||
maple)
|
||||
platformo=$object/of.o
|
||||
platformo="$object/of.o $object/epapr.o"
|
||||
link_address='0x400000'
|
||||
;;
|
||||
pmac|chrp)
|
||||
platformo=$object/of.o
|
||||
platformo="$object/of.o $object/epapr.o"
|
||||
;;
|
||||
coff)
|
||||
platformo="$object/crt0.o $object/of.o"
|
||||
platformo="$object/crt0.o $object/of.o $object/epapr.o"
|
||||
lds=$object/zImage.coff.lds
|
||||
link_address='0x500000'
|
||||
pie=
|
||||
@@ -253,6 +253,7 @@ treeboot-iss4xx-mpic)
|
||||
platformo="$object/treeboot-iss4xx.o"
|
||||
;;
|
||||
epapr)
|
||||
platformo="$object/epapr.o $object/epapr-wrapper.o"
|
||||
link_address='0x20000000'
|
||||
pie=-pie
|
||||
;;
|
||||
|
||||
@@ -69,9 +69,9 @@ extern struct thread_info *softirq_ctx[NR_CPUS];
|
||||
|
||||
extern void irq_ctx_init(void);
|
||||
extern void call_do_softirq(struct thread_info *tp);
|
||||
extern int call_handle_irq(int irq, void *p1,
|
||||
struct thread_info *tp, void *func);
|
||||
extern void call_do_irq(struct pt_regs *regs, struct thread_info *tp);
|
||||
extern void do_IRQ(struct pt_regs *regs);
|
||||
extern void __do_irq(struct pt_regs *regs);
|
||||
|
||||
int irq_choose_cpu(const struct cpumask *mask);
|
||||
|
||||
|
||||
@@ -149,8 +149,6 @@ typedef struct {
|
||||
|
||||
struct thread_struct {
|
||||
unsigned long ksp; /* Kernel stack pointer */
|
||||
unsigned long ksp_limit; /* if ksp <= ksp_limit stack overflow */
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
unsigned long ksp_vsid;
|
||||
#endif
|
||||
@@ -162,6 +160,7 @@ struct thread_struct {
|
||||
#endif
|
||||
#ifdef CONFIG_PPC32
|
||||
void *pgdir; /* root of page-table tree */
|
||||
unsigned long ksp_limit; /* if ksp <= ksp_limit stack overflow */
|
||||
#endif
|
||||
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
|
||||
/*
|
||||
@@ -321,7 +320,6 @@ struct thread_struct {
|
||||
#else
|
||||
#define INIT_THREAD { \
|
||||
.ksp = INIT_SP, \
|
||||
.ksp_limit = INIT_SP_LIMIT, \
|
||||
.regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \
|
||||
.fs = KERNEL_DS, \
|
||||
.fpr = {{0}}, \
|
||||
|
||||
@@ -80,10 +80,11 @@ int main(void)
|
||||
DEFINE(TASKTHREADPPR, offsetof(struct task_struct, thread.ppr));
|
||||
#else
|
||||
DEFINE(THREAD_INFO, offsetof(struct task_struct, stack));
|
||||
DEFINE(THREAD_INFO_GAP, _ALIGN_UP(sizeof(struct thread_info), 16));
|
||||
DEFINE(KSP_LIMIT, offsetof(struct thread_struct, ksp_limit));
|
||||
#endif /* CONFIG_PPC64 */
|
||||
|
||||
DEFINE(KSP, offsetof(struct thread_struct, ksp));
|
||||
DEFINE(KSP_LIMIT, offsetof(struct thread_struct, ksp_limit));
|
||||
DEFINE(PT_REGS, offsetof(struct thread_struct, regs));
|
||||
#ifdef CONFIG_BOOKE
|
||||
DEFINE(THREAD_NORMSAVES, offsetof(struct thread_struct, normsave[0]));
|
||||
|
||||
@@ -661,7 +661,7 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid)
|
||||
/* number of bytes needed for the bitmap */
|
||||
sz = BITS_TO_LONGS(tbl->it_size) * sizeof(unsigned long);
|
||||
|
||||
page = alloc_pages_node(nid, GFP_ATOMIC, get_order(sz));
|
||||
page = alloc_pages_node(nid, GFP_KERNEL, get_order(sz));
|
||||
if (!page)
|
||||
panic("iommu_init_table: Can't allocate %ld bytes\n", sz);
|
||||
tbl->it_map = page_address(page);
|
||||
|
||||
@@ -441,50 +441,6 @@ void migrate_irqs(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void handle_one_irq(unsigned int irq)
|
||||
{
|
||||
struct thread_info *curtp, *irqtp;
|
||||
unsigned long saved_sp_limit;
|
||||
struct irq_desc *desc;
|
||||
|
||||
desc = irq_to_desc(irq);
|
||||
if (!desc)
|
||||
return;
|
||||
|
||||
/* Switch to the irq stack to handle this */
|
||||
curtp = current_thread_info();
|
||||
irqtp = hardirq_ctx[smp_processor_id()];
|
||||
|
||||
if (curtp == irqtp) {
|
||||
/* We're already on the irq stack, just handle it */
|
||||
desc->handle_irq(irq, desc);
|
||||
return;
|
||||
}
|
||||
|
||||
saved_sp_limit = current->thread.ksp_limit;
|
||||
|
||||
irqtp->task = curtp->task;
|
||||
irqtp->flags = 0;
|
||||
|
||||
/* Copy the softirq bits in preempt_count so that the
|
||||
* softirq checks work in the hardirq context. */
|
||||
irqtp->preempt_count = (irqtp->preempt_count & ~SOFTIRQ_MASK) |
|
||||
(curtp->preempt_count & SOFTIRQ_MASK);
|
||||
|
||||
current->thread.ksp_limit = (unsigned long)irqtp +
|
||||
_ALIGN_UP(sizeof(struct thread_info), 16);
|
||||
|
||||
call_handle_irq(irq, desc, irqtp, desc->handle_irq);
|
||||
current->thread.ksp_limit = saved_sp_limit;
|
||||
irqtp->task = NULL;
|
||||
|
||||
/* Set any flag that may have been set on the
|
||||
* alternate stack
|
||||
*/
|
||||
if (irqtp->flags)
|
||||
set_bits(irqtp->flags, &curtp->flags);
|
||||
}
|
||||
|
||||
static inline void check_stack_overflow(void)
|
||||
{
|
||||
#ifdef CONFIG_DEBUG_STACKOVERFLOW
|
||||
@@ -501,9 +457,9 @@ static inline void check_stack_overflow(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
void do_IRQ(struct pt_regs *regs)
|
||||
void __do_irq(struct pt_regs *regs)
|
||||
{
|
||||
struct pt_regs *old_regs = set_irq_regs(regs);
|
||||
struct irq_desc *desc;
|
||||
unsigned int irq;
|
||||
|
||||
irq_enter();
|
||||
@@ -519,18 +475,56 @@ void do_IRQ(struct pt_regs *regs)
|
||||
*/
|
||||
irq = ppc_md.get_irq();
|
||||
|
||||
/* We can hard enable interrupts now */
|
||||
/* We can hard enable interrupts now to allow perf interrupts */
|
||||
may_hard_irq_enable();
|
||||
|
||||
/* And finally process it */
|
||||
if (irq != NO_IRQ)
|
||||
handle_one_irq(irq);
|
||||
else
|
||||
if (unlikely(irq == NO_IRQ))
|
||||
__get_cpu_var(irq_stat).spurious_irqs++;
|
||||
else {
|
||||
desc = irq_to_desc(irq);
|
||||
if (likely(desc))
|
||||
desc->handle_irq(irq, desc);
|
||||
}
|
||||
|
||||
trace_irq_exit(regs);
|
||||
|
||||
irq_exit();
|
||||
}
|
||||
|
||||
void do_IRQ(struct pt_regs *regs)
|
||||
{
|
||||
struct pt_regs *old_regs = set_irq_regs(regs);
|
||||
struct thread_info *curtp, *irqtp;
|
||||
|
||||
/* Switch to the irq stack to handle this */
|
||||
curtp = current_thread_info();
|
||||
irqtp = hardirq_ctx[raw_smp_processor_id()];
|
||||
|
||||
/* Already there ? */
|
||||
if (unlikely(curtp == irqtp)) {
|
||||
__do_irq(regs);
|
||||
set_irq_regs(old_regs);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Prepare the thread_info in the irq stack */
|
||||
irqtp->task = curtp->task;
|
||||
irqtp->flags = 0;
|
||||
|
||||
/* Copy the preempt_count so that the [soft]irq checks work. */
|
||||
irqtp->preempt_count = curtp->preempt_count;
|
||||
|
||||
/* Switch stack and call */
|
||||
call_do_irq(regs, irqtp);
|
||||
|
||||
/* Restore stack limit */
|
||||
irqtp->task = NULL;
|
||||
|
||||
/* Copy back updates to the thread_info */
|
||||
if (irqtp->flags)
|
||||
set_bits(irqtp->flags, &curtp->flags);
|
||||
|
||||
set_irq_regs(old_regs);
|
||||
}
|
||||
|
||||
@@ -592,28 +586,22 @@ void irq_ctx_init(void)
|
||||
memset((void *)softirq_ctx[i], 0, THREAD_SIZE);
|
||||
tp = softirq_ctx[i];
|
||||
tp->cpu = i;
|
||||
tp->preempt_count = 0;
|
||||
|
||||
memset((void *)hardirq_ctx[i], 0, THREAD_SIZE);
|
||||
tp = hardirq_ctx[i];
|
||||
tp->cpu = i;
|
||||
tp->preempt_count = HARDIRQ_OFFSET;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void do_softirq_onstack(void)
|
||||
{
|
||||
struct thread_info *curtp, *irqtp;
|
||||
unsigned long saved_sp_limit = current->thread.ksp_limit;
|
||||
|
||||
curtp = current_thread_info();
|
||||
irqtp = softirq_ctx[smp_processor_id()];
|
||||
irqtp->task = curtp->task;
|
||||
irqtp->flags = 0;
|
||||
current->thread.ksp_limit = (unsigned long)irqtp +
|
||||
_ALIGN_UP(sizeof(struct thread_info), 16);
|
||||
call_do_softirq(irqtp);
|
||||
current->thread.ksp_limit = saved_sp_limit;
|
||||
irqtp->task = NULL;
|
||||
|
||||
/* Set any flag that may have been set on the
|
||||
|
||||
@@ -36,26 +36,41 @@
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
* We store the saved ksp_limit in the unused part
|
||||
* of the STACK_FRAME_OVERHEAD
|
||||
*/
|
||||
_GLOBAL(call_do_softirq)
|
||||
mflr r0
|
||||
stw r0,4(r1)
|
||||
lwz r10,THREAD+KSP_LIMIT(r2)
|
||||
addi r11,r3,THREAD_INFO_GAP
|
||||
stwu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r3)
|
||||
mr r1,r3
|
||||
stw r10,8(r1)
|
||||
stw r11,THREAD+KSP_LIMIT(r2)
|
||||
bl __do_softirq
|
||||
lwz r10,8(r1)
|
||||
lwz r1,0(r1)
|
||||
lwz r0,4(r1)
|
||||
stw r10,THREAD+KSP_LIMIT(r2)
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
_GLOBAL(call_handle_irq)
|
||||
_GLOBAL(call_do_irq)
|
||||
mflr r0
|
||||
stw r0,4(r1)
|
||||
mtctr r6
|
||||
stwu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r5)
|
||||
mr r1,r5
|
||||
bctrl
|
||||
lwz r10,THREAD+KSP_LIMIT(r2)
|
||||
addi r11,r3,THREAD_INFO_GAP
|
||||
stwu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r4)
|
||||
mr r1,r4
|
||||
stw r10,8(r1)
|
||||
stw r11,THREAD+KSP_LIMIT(r2)
|
||||
bl __do_irq
|
||||
lwz r10,8(r1)
|
||||
lwz r1,0(r1)
|
||||
lwz r0,4(r1)
|
||||
stw r10,THREAD+KSP_LIMIT(r2)
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
|
||||
@@ -40,14 +40,12 @@ _GLOBAL(call_do_softirq)
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
_GLOBAL(call_handle_irq)
|
||||
ld r8,0(r6)
|
||||
_GLOBAL(call_do_irq)
|
||||
mflr r0
|
||||
std r0,16(r1)
|
||||
mtctr r8
|
||||
stdu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r5)
|
||||
mr r1,r5
|
||||
bctrl
|
||||
stdu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r4)
|
||||
mr r1,r4
|
||||
bl .__do_irq
|
||||
ld r1,0(r1)
|
||||
ld r0,16(r1)
|
||||
mtlr r0
|
||||
|
||||
@@ -1000,9 +1000,10 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
|
||||
kregs = (struct pt_regs *) sp;
|
||||
sp -= STACK_FRAME_OVERHEAD;
|
||||
p->thread.ksp = sp;
|
||||
#ifdef CONFIG_PPC32
|
||||
p->thread.ksp_limit = (unsigned long)task_stack_page(p) +
|
||||
_ALIGN_UP(sizeof(struct thread_info), 16);
|
||||
|
||||
#endif
|
||||
#ifdef CONFIG_HAVE_HW_BREAKPOINT
|
||||
p->thread.ptrace_bps[0] = NULL;
|
||||
#endif
|
||||
|
||||
@@ -196,6 +196,8 @@ static int __initdata mem_reserve_cnt;
|
||||
|
||||
static cell_t __initdata regbuf[1024];
|
||||
|
||||
static bool rtas_has_query_cpu_stopped;
|
||||
|
||||
|
||||
/*
|
||||
* Error results ... some OF calls will return "-1" on error, some
|
||||
@@ -1574,6 +1576,11 @@ static void __init prom_instantiate_rtas(void)
|
||||
prom_setprop(rtas_node, "/rtas", "linux,rtas-entry",
|
||||
&val, sizeof(val));
|
||||
|
||||
/* Check if it supports "query-cpu-stopped-state" */
|
||||
if (prom_getprop(rtas_node, "query-cpu-stopped-state",
|
||||
&val, sizeof(val)) != PROM_ERROR)
|
||||
rtas_has_query_cpu_stopped = true;
|
||||
|
||||
#if defined(CONFIG_PPC_POWERNV) && defined(__BIG_ENDIAN__)
|
||||
/* PowerVN takeover hack */
|
||||
prom_rtas_data = base;
|
||||
@@ -1815,6 +1822,18 @@ static void __init prom_hold_cpus(void)
|
||||
= (void *) LOW_ADDR(__secondary_hold_acknowledge);
|
||||
unsigned long secondary_hold = LOW_ADDR(__secondary_hold);
|
||||
|
||||
/*
|
||||
* On pseries, if RTAS supports "query-cpu-stopped-state",
|
||||
* we skip this stage, the CPUs will be started by the
|
||||
* kernel using RTAS.
|
||||
*/
|
||||
if ((of_platform == PLATFORM_PSERIES ||
|
||||
of_platform == PLATFORM_PSERIES_LPAR) &&
|
||||
rtas_has_query_cpu_stopped) {
|
||||
prom_printf("prom_hold_cpus: skipped\n");
|
||||
return;
|
||||
}
|
||||
|
||||
prom_debug("prom_hold_cpus: start...\n");
|
||||
prom_debug(" 1) spinloop = 0x%x\n", (unsigned long)spinloop);
|
||||
prom_debug(" 1) *spinloop = 0x%x\n", *spinloop);
|
||||
@@ -3011,6 +3030,8 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
|
||||
* On non-powermacs, put all CPUs in spin-loops.
|
||||
*
|
||||
* PowerMacs use a different mechanism to spin CPUs
|
||||
*
|
||||
* (This must be done after instanciating RTAS)
|
||||
*/
|
||||
if (of_platform != PLATFORM_POWERMAC &&
|
||||
of_platform != PLATFORM_OPAL)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/smp.h>
|
||||
#include <asm/pmc.h>
|
||||
#include <asm/firmware.h>
|
||||
|
||||
#include "cacheinfo.h"
|
||||
|
||||
@@ -179,15 +180,25 @@ SYSFS_PMCSETUP(spurr, SPRN_SPURR);
|
||||
SYSFS_PMCSETUP(dscr, SPRN_DSCR);
|
||||
SYSFS_PMCSETUP(pir, SPRN_PIR);
|
||||
|
||||
/*
|
||||
Lets only enable read for phyp resources and
|
||||
enable write when needed with a separate function.
|
||||
Lets be conservative and default to pseries.
|
||||
*/
|
||||
static DEVICE_ATTR(mmcra, 0600, show_mmcra, store_mmcra);
|
||||
static DEVICE_ATTR(spurr, 0400, show_spurr, NULL);
|
||||
static DEVICE_ATTR(dscr, 0600, show_dscr, store_dscr);
|
||||
static DEVICE_ATTR(purr, 0600, show_purr, store_purr);
|
||||
static DEVICE_ATTR(purr, 0400, show_purr, store_purr);
|
||||
static DEVICE_ATTR(pir, 0400, show_pir, NULL);
|
||||
|
||||
unsigned long dscr_default = 0;
|
||||
EXPORT_SYMBOL(dscr_default);
|
||||
|
||||
static void add_write_permission_dev_attr(struct device_attribute *attr)
|
||||
{
|
||||
attr->attr.mode |= 0200;
|
||||
}
|
||||
|
||||
static ssize_t show_dscr_default(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
@@ -394,8 +405,11 @@ static void register_cpu_online(unsigned int cpu)
|
||||
if (cpu_has_feature(CPU_FTR_MMCRA))
|
||||
device_create_file(s, &dev_attr_mmcra);
|
||||
|
||||
if (cpu_has_feature(CPU_FTR_PURR))
|
||||
if (cpu_has_feature(CPU_FTR_PURR)) {
|
||||
if (!firmware_has_feature(FW_FEATURE_LPAR))
|
||||
add_write_permission_dev_attr(&dev_attr_purr);
|
||||
device_create_file(s, &dev_attr_purr);
|
||||
}
|
||||
|
||||
if (cpu_has_feature(CPU_FTR_SPURR))
|
||||
device_create_file(s, &dev_attr_spurr);
|
||||
|
||||
@@ -79,6 +79,11 @@ _GLOBAL(tm_abort)
|
||||
TABORT(R3)
|
||||
blr
|
||||
|
||||
.section ".toc","aw"
|
||||
DSCR_DEFAULT:
|
||||
.tc dscr_default[TC],dscr_default
|
||||
|
||||
.section ".text"
|
||||
|
||||
/* void tm_reclaim(struct thread_struct *thread,
|
||||
* unsigned long orig_msr,
|
||||
@@ -123,6 +128,7 @@ _GLOBAL(tm_reclaim)
|
||||
mr r15, r14
|
||||
ori r15, r15, MSR_FP
|
||||
li r16, MSR_RI
|
||||
ori r16, r16, MSR_EE /* IRQs hard off */
|
||||
andc r15, r15, r16
|
||||
oris r15, r15, MSR_VEC@h
|
||||
#ifdef CONFIG_VSX
|
||||
@@ -187,11 +193,18 @@ dont_backup_fp:
|
||||
std r1, PACATMSCRATCH(r13)
|
||||
ld r1, PACAR1(r13)
|
||||
|
||||
/* Store the PPR in r11 and reset to decent value */
|
||||
std r11, GPR11(r1) /* Temporary stash */
|
||||
mfspr r11, SPRN_PPR
|
||||
HMT_MEDIUM
|
||||
|
||||
/* Now get some more GPRS free */
|
||||
std r7, GPR7(r1) /* Temporary stash */
|
||||
std r12, GPR12(r1) /* '' '' '' */
|
||||
ld r12, STACK_PARAM(0)(r1) /* Param 0, thread_struct * */
|
||||
|
||||
std r11, THREAD_TM_PPR(r12) /* Store PPR and free r11 */
|
||||
|
||||
addi r7, r12, PT_CKPT_REGS /* Thread's ckpt_regs */
|
||||
|
||||
/* Make r7 look like an exception frame so that we
|
||||
@@ -203,15 +216,19 @@ dont_backup_fp:
|
||||
SAVE_GPR(0, r7) /* user r0 */
|
||||
SAVE_GPR(2, r7) /* user r2 */
|
||||
SAVE_4GPRS(3, r7) /* user r3-r6 */
|
||||
SAVE_4GPRS(8, r7) /* user r8-r11 */
|
||||
SAVE_GPR(8, r7) /* user r8 */
|
||||
SAVE_GPR(9, r7) /* user r9 */
|
||||
SAVE_GPR(10, r7) /* user r10 */
|
||||
ld r3, PACATMSCRATCH(r13) /* user r1 */
|
||||
ld r4, GPR7(r1) /* user r7 */
|
||||
ld r5, GPR12(r1) /* user r12 */
|
||||
GET_SCRATCH0(6) /* user r13 */
|
||||
ld r5, GPR11(r1) /* user r11 */
|
||||
ld r6, GPR12(r1) /* user r12 */
|
||||
GET_SCRATCH0(8) /* user r13 */
|
||||
std r3, GPR1(r7)
|
||||
std r4, GPR7(r7)
|
||||
std r5, GPR12(r7)
|
||||
std r6, GPR13(r7)
|
||||
std r5, GPR11(r7)
|
||||
std r6, GPR12(r7)
|
||||
std r8, GPR13(r7)
|
||||
|
||||
SAVE_NVGPRS(r7) /* user r14-r31 */
|
||||
|
||||
@@ -234,14 +251,12 @@ dont_backup_fp:
|
||||
std r6, _XER(r7)
|
||||
|
||||
|
||||
/* ******************** TAR, PPR, DSCR ********** */
|
||||
/* ******************** TAR, DSCR ********** */
|
||||
mfspr r3, SPRN_TAR
|
||||
mfspr r4, SPRN_PPR
|
||||
mfspr r5, SPRN_DSCR
|
||||
mfspr r4, SPRN_DSCR
|
||||
|
||||
std r3, THREAD_TM_TAR(r12)
|
||||
std r4, THREAD_TM_PPR(r12)
|
||||
std r5, THREAD_TM_DSCR(r12)
|
||||
std r4, THREAD_TM_DSCR(r12)
|
||||
|
||||
/* MSR and flags: We don't change CRs, and we don't need to alter
|
||||
* MSR.
|
||||
@@ -258,7 +273,7 @@ dont_backup_fp:
|
||||
std r3, THREAD_TM_TFHAR(r12)
|
||||
std r4, THREAD_TM_TFIAR(r12)
|
||||
|
||||
/* AMR and PPR are checkpointed too, but are unsupported by Linux. */
|
||||
/* AMR is checkpointed too, but is unsupported by Linux. */
|
||||
|
||||
/* Restore original MSR/IRQ state & clear TM mode */
|
||||
ld r14, TM_FRAME_L0(r1) /* Orig MSR */
|
||||
@@ -274,6 +289,12 @@ dont_backup_fp:
|
||||
mtcr r4
|
||||
mtlr r0
|
||||
ld r2, 40(r1)
|
||||
|
||||
/* Load system default DSCR */
|
||||
ld r4, DSCR_DEFAULT@toc(r2)
|
||||
ld r0, 0(r4)
|
||||
mtspr SPRN_DSCR, r0
|
||||
|
||||
blr
|
||||
|
||||
|
||||
@@ -358,25 +379,24 @@ dont_restore_fp:
|
||||
|
||||
restore_gprs:
|
||||
|
||||
/* ******************** TAR, PPR, DSCR ********** */
|
||||
ld r4, THREAD_TM_TAR(r3)
|
||||
ld r5, THREAD_TM_PPR(r3)
|
||||
ld r6, THREAD_TM_DSCR(r3)
|
||||
|
||||
mtspr SPRN_TAR, r4
|
||||
mtspr SPRN_PPR, r5
|
||||
mtspr SPRN_DSCR, r6
|
||||
|
||||
/* ******************** CR,LR,CCR,MSR ********** */
|
||||
ld r3, _CTR(r7)
|
||||
ld r4, _LINK(r7)
|
||||
ld r5, _CCR(r7)
|
||||
ld r6, _XER(r7)
|
||||
ld r4, _CTR(r7)
|
||||
ld r5, _LINK(r7)
|
||||
ld r6, _CCR(r7)
|
||||
ld r8, _XER(r7)
|
||||
|
||||
mtctr r3
|
||||
mtlr r4
|
||||
mtcr r5
|
||||
mtxer r6
|
||||
mtctr r4
|
||||
mtlr r5
|
||||
mtcr r6
|
||||
mtxer r8
|
||||
|
||||
/* ******************** TAR ******************** */
|
||||
ld r4, THREAD_TM_TAR(r3)
|
||||
mtspr SPRN_TAR, r4
|
||||
|
||||
/* Load up the PPR and DSCR in GPRs only at this stage */
|
||||
ld r5, THREAD_TM_DSCR(r3)
|
||||
ld r6, THREAD_TM_PPR(r3)
|
||||
|
||||
/* Clear the MSR RI since we are about to change R1. EE is already off
|
||||
*/
|
||||
@@ -384,19 +404,26 @@ restore_gprs:
|
||||
mtmsrd r4, 1
|
||||
|
||||
REST_4GPRS(0, r7) /* GPR0-3 */
|
||||
REST_GPR(4, r7) /* GPR4-6 */
|
||||
REST_GPR(5, r7)
|
||||
REST_GPR(6, r7)
|
||||
REST_GPR(4, r7) /* GPR4 */
|
||||
REST_4GPRS(8, r7) /* GPR8-11 */
|
||||
REST_2GPRS(12, r7) /* GPR12-13 */
|
||||
|
||||
REST_NVGPRS(r7) /* GPR14-31 */
|
||||
|
||||
ld r7, GPR7(r7) /* GPR7 */
|
||||
/* Load up PPR and DSCR here so we don't run with user values for long
|
||||
*/
|
||||
mtspr SPRN_DSCR, r5
|
||||
mtspr SPRN_PPR, r6
|
||||
|
||||
REST_GPR(5, r7) /* GPR5-7 */
|
||||
REST_GPR(6, r7)
|
||||
ld r7, GPR7(r7)
|
||||
|
||||
/* Commit register state as checkpointed state: */
|
||||
TRECHKPT
|
||||
|
||||
HMT_MEDIUM
|
||||
|
||||
/* Our transactional state has now changed.
|
||||
*
|
||||
* Now just get out of here. Transactional (current) state will be
|
||||
@@ -419,6 +446,12 @@ restore_gprs:
|
||||
mtcr r4
|
||||
mtlr r0
|
||||
ld r2, 40(r1)
|
||||
|
||||
/* Load system default DSCR */
|
||||
ld r4, DSCR_DEFAULT@toc(r2)
|
||||
ld r0, 0(r4)
|
||||
mtspr SPRN_DSCR, r0
|
||||
|
||||
blr
|
||||
|
||||
/* ****************************************************************** */
|
||||
|
||||
@@ -1530,11 +1530,15 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
|
||||
const char *cp;
|
||||
|
||||
dn = dev->of_node;
|
||||
if (!dn)
|
||||
return -ENODEV;
|
||||
if (!dn) {
|
||||
strcat(buf, "\n");
|
||||
return strlen(buf);
|
||||
}
|
||||
cp = of_get_property(dn, "compatible", NULL);
|
||||
if (!cp)
|
||||
return -ENODEV;
|
||||
if (!cp) {
|
||||
strcat(buf, "\n");
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
return sprintf(buf, "vio:T%sS%s\n", vio_dev->type, cp);
|
||||
}
|
||||
|
||||
@@ -226,19 +226,35 @@ _GLOBAL(csum_partial)
|
||||
blr
|
||||
|
||||
|
||||
.macro source
|
||||
.macro srcnr
|
||||
100:
|
||||
.section __ex_table,"a"
|
||||
.align 3
|
||||
.llong 100b,.Lsrc_error
|
||||
.llong 100b,.Lsrc_error_nr
|
||||
.previous
|
||||
.endm
|
||||
|
||||
.macro source
|
||||
150:
|
||||
.section __ex_table,"a"
|
||||
.align 3
|
||||
.llong 150b,.Lsrc_error
|
||||
.previous
|
||||
.endm
|
||||
|
||||
.macro dstnr
|
||||
200:
|
||||
.section __ex_table,"a"
|
||||
.align 3
|
||||
.llong 200b,.Ldest_error_nr
|
||||
.previous
|
||||
.endm
|
||||
|
||||
.macro dest
|
||||
200:
|
||||
250:
|
||||
.section __ex_table,"a"
|
||||
.align 3
|
||||
.llong 200b,.Ldest_error
|
||||
.llong 250b,.Ldest_error
|
||||
.previous
|
||||
.endm
|
||||
|
||||
@@ -269,16 +285,16 @@ _GLOBAL(csum_partial_copy_generic)
|
||||
rldicl. r6,r3,64-1,64-2 /* r6 = (r3 & 0x3) >> 1 */
|
||||
beq .Lcopy_aligned
|
||||
|
||||
li r7,4
|
||||
sub r6,r7,r6
|
||||
li r9,4
|
||||
sub r6,r9,r6
|
||||
mtctr r6
|
||||
|
||||
1:
|
||||
source; lhz r6,0(r3) /* align to doubleword */
|
||||
srcnr; lhz r6,0(r3) /* align to doubleword */
|
||||
subi r5,r5,2
|
||||
addi r3,r3,2
|
||||
adde r0,r0,r6
|
||||
dest; sth r6,0(r4)
|
||||
dstnr; sth r6,0(r4)
|
||||
addi r4,r4,2
|
||||
bdnz 1b
|
||||
|
||||
@@ -392,10 +408,10 @@ dest; std r16,56(r4)
|
||||
|
||||
mtctr r6
|
||||
3:
|
||||
source; ld r6,0(r3)
|
||||
srcnr; ld r6,0(r3)
|
||||
addi r3,r3,8
|
||||
adde r0,r0,r6
|
||||
dest; std r6,0(r4)
|
||||
dstnr; std r6,0(r4)
|
||||
addi r4,r4,8
|
||||
bdnz 3b
|
||||
|
||||
@@ -405,10 +421,10 @@ dest; std r6,0(r4)
|
||||
srdi. r6,r5,2
|
||||
beq .Lcopy_tail_halfword
|
||||
|
||||
source; lwz r6,0(r3)
|
||||
srcnr; lwz r6,0(r3)
|
||||
addi r3,r3,4
|
||||
adde r0,r0,r6
|
||||
dest; stw r6,0(r4)
|
||||
dstnr; stw r6,0(r4)
|
||||
addi r4,r4,4
|
||||
subi r5,r5,4
|
||||
|
||||
@@ -416,10 +432,10 @@ dest; stw r6,0(r4)
|
||||
srdi. r6,r5,1
|
||||
beq .Lcopy_tail_byte
|
||||
|
||||
source; lhz r6,0(r3)
|
||||
srcnr; lhz r6,0(r3)
|
||||
addi r3,r3,2
|
||||
adde r0,r0,r6
|
||||
dest; sth r6,0(r4)
|
||||
dstnr; sth r6,0(r4)
|
||||
addi r4,r4,2
|
||||
subi r5,r5,2
|
||||
|
||||
@@ -427,10 +443,10 @@ dest; sth r6,0(r4)
|
||||
andi. r6,r5,1
|
||||
beq .Lcopy_finish
|
||||
|
||||
source; lbz r6,0(r3)
|
||||
srcnr; lbz r6,0(r3)
|
||||
sldi r9,r6,8 /* Pad the byte out to 16 bits */
|
||||
adde r0,r0,r9
|
||||
dest; stb r6,0(r4)
|
||||
dstnr; stb r6,0(r4)
|
||||
|
||||
.Lcopy_finish:
|
||||
addze r0,r0 /* add in final carry */
|
||||
@@ -440,6 +456,11 @@ dest; stb r6,0(r4)
|
||||
blr
|
||||
|
||||
.Lsrc_error:
|
||||
ld r14,STK_REG(R14)(r1)
|
||||
ld r15,STK_REG(R15)(r1)
|
||||
ld r16,STK_REG(R16)(r1)
|
||||
addi r1,r1,STACKFRAMESIZE
|
||||
.Lsrc_error_nr:
|
||||
cmpdi 0,r7,0
|
||||
beqlr
|
||||
li r6,-EFAULT
|
||||
@@ -447,6 +468,11 @@ dest; stb r6,0(r4)
|
||||
blr
|
||||
|
||||
.Ldest_error:
|
||||
ld r14,STK_REG(R14)(r1)
|
||||
ld r15,STK_REG(R15)(r1)
|
||||
ld r16,STK_REG(R16)(r1)
|
||||
addi r1,r1,STACKFRAMESIZE
|
||||
.Ldest_error_nr:
|
||||
cmpdi 0,r8,0
|
||||
beqlr
|
||||
li r6,-EFAULT
|
||||
|
||||
@@ -1505,6 +1505,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
|
||||
*/
|
||||
if ((ra == 1) && !(regs->msr & MSR_PR) \
|
||||
&& (val3 >= (regs->gpr[1] - STACK_INT_FRAME_SIZE))) {
|
||||
#ifdef CONFIG_PPC32
|
||||
/*
|
||||
* Check if we will touch kernel sack overflow
|
||||
*/
|
||||
@@ -1513,7 +1514,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
|
||||
err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PPC32 */
|
||||
/*
|
||||
* Check if we already set since that means we'll
|
||||
* lose the previous value.
|
||||
|
||||
@@ -300,5 +300,9 @@ void vmemmap_free(unsigned long start, unsigned long end)
|
||||
{
|
||||
}
|
||||
|
||||
void register_page_bootmem_memmap(unsigned long section_nr,
|
||||
struct page *start_page, unsigned long size)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_SPARSEMEM_VMEMMAP */
|
||||
|
||||
|
||||
@@ -297,12 +297,21 @@ void __init paging_init(void)
|
||||
}
|
||||
#endif /* ! CONFIG_NEED_MULTIPLE_NODES */
|
||||
|
||||
static void __init register_page_bootmem_info(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for_each_online_node(i)
|
||||
register_page_bootmem_info_node(NODE_DATA(i));
|
||||
}
|
||||
|
||||
void __init mem_init(void)
|
||||
{
|
||||
#ifdef CONFIG_SWIOTLB
|
||||
swiotlb_init(0);
|
||||
#endif
|
||||
|
||||
register_page_bootmem_info();
|
||||
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
|
||||
set_max_mapnr(max_pfn);
|
||||
free_all_bootmem();
|
||||
|
||||
@@ -199,6 +199,7 @@
|
||||
#define MMCR1_UNIT_SHIFT(pmc) (60 - (4 * ((pmc) - 1)))
|
||||
#define MMCR1_COMBINE_SHIFT(pmc) (35 - ((pmc) - 1))
|
||||
#define MMCR1_PMCSEL_SHIFT(pmc) (24 - (((pmc) - 1)) * 8)
|
||||
#define MMCR1_FAB_SHIFT 36
|
||||
#define MMCR1_DC_QUAL_SHIFT 47
|
||||
#define MMCR1_IC_QUAL_SHIFT 46
|
||||
|
||||
@@ -388,8 +389,8 @@ static int power8_compute_mmcr(u64 event[], int n_ev,
|
||||
* the threshold bits are used for the match value.
|
||||
*/
|
||||
if (event_is_fab_match(event[i])) {
|
||||
mmcr1 |= (event[i] >> EVENT_THR_CTL_SHIFT) &
|
||||
EVENT_THR_CTL_MASK;
|
||||
mmcr1 |= ((event[i] >> EVENT_THR_CTL_SHIFT) &
|
||||
EVENT_THR_CTL_MASK) << MMCR1_FAB_SHIFT;
|
||||
} else {
|
||||
val = (event[i] >> EVENT_THR_CTL_SHIFT) & EVENT_THR_CTL_MASK;
|
||||
mmcra |= val << MMCRA_THR_CTL_SHIFT;
|
||||
|
||||
@@ -233,17 +233,23 @@ static void __init smp_init_pseries(void)
|
||||
|
||||
alloc_bootmem_cpumask_var(&of_spin_mask);
|
||||
|
||||
/* Mark threads which are still spinning in hold loops. */
|
||||
if (cpu_has_feature(CPU_FTR_SMT)) {
|
||||
for_each_present_cpu(i) {
|
||||
if (cpu_thread_in_core(i) == 0)
|
||||
cpumask_set_cpu(i, of_spin_mask);
|
||||
}
|
||||
} else {
|
||||
cpumask_copy(of_spin_mask, cpu_present_mask);
|
||||
}
|
||||
/*
|
||||
* Mark threads which are still spinning in hold loops
|
||||
*
|
||||
* We know prom_init will not have started them if RTAS supports
|
||||
* query-cpu-stopped-state.
|
||||
*/
|
||||
if (rtas_token("query-cpu-stopped-state") == RTAS_UNKNOWN_SERVICE) {
|
||||
if (cpu_has_feature(CPU_FTR_SMT)) {
|
||||
for_each_present_cpu(i) {
|
||||
if (cpu_thread_in_core(i) == 0)
|
||||
cpumask_set_cpu(i, of_spin_mask);
|
||||
}
|
||||
} else
|
||||
cpumask_copy(of_spin_mask, cpu_present_mask);
|
||||
|
||||
cpumask_clear_cpu(boot_cpuid, of_spin_mask);
|
||||
cpumask_clear_cpu(boot_cpuid, of_spin_mask);
|
||||
}
|
||||
|
||||
/* Non-lpar has additional take/give timebase */
|
||||
if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) {
|
||||
|
||||
Reference in New Issue
Block a user