Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
Pull third set of powerpc updates from Benjamin Herrenschmidt: "This is a small collection of random bug fixes and a few improvements of Oops output which I deemed valuable enough to include as well. The fixes are essentially recent build breakage and regressions, and a couple of older bugs such as the DTL log duplication, the EEH issue with PCI_COMMAND_MASTER and the problem with small contexts passed to get/set_context with VSX enabled" * 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: powerpc/signals: Mark VSX not saved with small contexts powerpc/pseries: Fix SMP=n build of rng.c powerpc: Make cpu_to_chip_id() available when SMP=n powerpc/vio: Fix a dma_mask issue of vio powerpc: booke: Fix build failures powerpc: ppc64 address space capped at 32TB, mmap randomisation disabled powerpc: Only print PACATMSCRATCH in oops when TM is active powerpc/pseries: Duplicate dtl entries sometimes sent to userspace powerpc: Remove a few lines of oops output powerpc: Print DAR and DSISR on machine check oopses powerpc: Fix __get_user_pages_fast() irq handling powerpc/eeh: More accurate log powerpc/eeh: Enable PCI_COMMAND_MASTER for PCI bridges
This commit is contained in:
commit
3bab0bf045
20 changed files with 75 additions and 36 deletions
|
@ -33,6 +33,7 @@ extern int boot_cpuid;
|
||||||
extern int spinning_secondaries;
|
extern int spinning_secondaries;
|
||||||
|
|
||||||
extern void cpu_die(void);
|
extern void cpu_die(void);
|
||||||
|
extern int cpu_to_chip_id(int cpu);
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
|
|
||||||
|
@ -112,7 +113,6 @@ static inline struct cpumask *cpu_core_mask(int cpu)
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int cpu_to_core_id(int cpu);
|
extern int cpu_to_core_id(int cpu);
|
||||||
extern int cpu_to_chip_id(int cpu);
|
|
||||||
|
|
||||||
/* Since OpenPIC has only 4 IPIs, we use slightly different message numbers.
|
/* Since OpenPIC has only 4 IPIs, we use slightly different message numbers.
|
||||||
*
|
*
|
||||||
|
|
|
@ -686,6 +686,15 @@ void eeh_save_bars(struct eeh_dev *edev)
|
||||||
|
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
eeh_ops->read_config(dn, i * 4, 4, &edev->config_space[i]);
|
eeh_ops->read_config(dn, i * 4, 4, &edev->config_space[i]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For PCI bridges including root port, we need enable bus
|
||||||
|
* master explicitly. Otherwise, it can't fetch IODA table
|
||||||
|
* entries correctly. So we cache the bit in advance so that
|
||||||
|
* we can restore it after reset, either PHB range or PE range.
|
||||||
|
*/
|
||||||
|
if (edev->mode & EEH_DEV_BRIDGE)
|
||||||
|
edev->config_space[1] |= PCI_COMMAND_MASTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -74,8 +74,13 @@ static int eeh_event_handler(void * dummy)
|
||||||
pe = event->pe;
|
pe = event->pe;
|
||||||
if (pe) {
|
if (pe) {
|
||||||
eeh_pe_state_mark(pe, EEH_PE_RECOVERING);
|
eeh_pe_state_mark(pe, EEH_PE_RECOVERING);
|
||||||
pr_info("EEH: Detected PCI bus error on PHB#%d-PE#%x\n",
|
if (pe->type & EEH_PE_PHB)
|
||||||
pe->phb->global_number, pe->addr);
|
pr_info("EEH: Detected error on PHB#%d\n",
|
||||||
|
pe->phb->global_number);
|
||||||
|
else
|
||||||
|
pr_info("EEH: Detected PCI bus error on "
|
||||||
|
"PHB#%d-PE#%x\n",
|
||||||
|
pe->phb->global_number, pe->addr);
|
||||||
eeh_handle_event(pe);
|
eeh_handle_event(pe);
|
||||||
eeh_pe_state_clear(pe, EEH_PE_RECOVERING);
|
eeh_pe_state_clear(pe, EEH_PE_RECOVERING);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -858,17 +858,21 @@ void show_regs(struct pt_regs * regs)
|
||||||
printk("MSR: "REG" ", regs->msr);
|
printk("MSR: "REG" ", regs->msr);
|
||||||
printbits(regs->msr, msr_bits);
|
printbits(regs->msr, msr_bits);
|
||||||
printk(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer);
|
printk(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer);
|
||||||
#ifdef CONFIG_PPC64
|
|
||||||
printk("SOFTE: %ld\n", regs->softe);
|
|
||||||
#endif
|
|
||||||
trap = TRAP(regs);
|
trap = TRAP(regs);
|
||||||
if ((regs->trap != 0xc00) && cpu_has_feature(CPU_FTR_CFAR))
|
if ((regs->trap != 0xc00) && cpu_has_feature(CPU_FTR_CFAR))
|
||||||
printk("CFAR: "REG"\n", regs->orig_gpr3);
|
printk("CFAR: "REG" ", regs->orig_gpr3);
|
||||||
if (trap == 0x300 || trap == 0x600)
|
if (trap == 0x200 || trap == 0x300 || trap == 0x600)
|
||||||
#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
|
#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
|
||||||
printk("DEAR: "REG", ESR: "REG"\n", regs->dar, regs->dsisr);
|
printk("DEAR: "REG" ESR: "REG" ", regs->dar, regs->dsisr);
|
||||||
#else
|
#else
|
||||||
printk("DAR: "REG", DSISR: %08lx\n", regs->dar, regs->dsisr);
|
printk("DAR: "REG" DSISR: %08lx ", regs->dar, regs->dsisr);
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_PPC64
|
||||||
|
printk("SOFTE: %ld ", regs->softe);
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
||||||
|
if (MSR_TM_ACTIVE(regs->msr))
|
||||||
|
printk("\nPACATMSCRATCH: %016llx ", get_paca()->tm_scratch);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < 32; i++) {
|
for (i = 0; i < 32; i++) {
|
||||||
|
@ -886,9 +890,6 @@ void show_regs(struct pt_regs * regs)
|
||||||
*/
|
*/
|
||||||
printk("NIP ["REG"] %pS\n", regs->nip, (void *)regs->nip);
|
printk("NIP ["REG"] %pS\n", regs->nip, (void *)regs->nip);
|
||||||
printk("LR ["REG"] %pS\n", regs->link, (void *)regs->link);
|
printk("LR ["REG"] %pS\n", regs->link, (void *)regs->link);
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
|
||||||
printk("PACATMSCRATCH [%llx]\n", get_paca()->tm_scratch);
|
|
||||||
#endif
|
#endif
|
||||||
show_stack(current, (unsigned long *) regs->gpr[1]);
|
show_stack(current, (unsigned long *) regs->gpr[1]);
|
||||||
if (!user_mode(regs))
|
if (!user_mode(regs))
|
||||||
|
|
|
@ -777,6 +777,26 @@ int of_get_ibm_chip_id(struct device_node *np)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cpu_to_chip_id - Return the cpus chip-id
|
||||||
|
* @cpu: The logical cpu number.
|
||||||
|
*
|
||||||
|
* Return the value of the ibm,chip-id property corresponding to the given
|
||||||
|
* logical cpu number. If the chip-id can not be found, returns -1.
|
||||||
|
*/
|
||||||
|
int cpu_to_chip_id(int cpu)
|
||||||
|
{
|
||||||
|
struct device_node *np;
|
||||||
|
|
||||||
|
np = of_get_cpu_node(cpu, NULL);
|
||||||
|
if (!np)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
of_node_put(np);
|
||||||
|
return of_get_ibm_chip_id(np);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(cpu_to_chip_id);
|
||||||
|
|
||||||
#ifdef CONFIG_PPC_PSERIES
|
#ifdef CONFIG_PPC_PSERIES
|
||||||
/*
|
/*
|
||||||
* Fix up the uninitialized fields in a new device node:
|
* Fix up the uninitialized fields in a new device node:
|
||||||
|
|
|
@ -457,7 +457,15 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
|
||||||
if (copy_vsx_to_user(&frame->mc_vsregs, current))
|
if (copy_vsx_to_user(&frame->mc_vsregs, current))
|
||||||
return 1;
|
return 1;
|
||||||
msr |= MSR_VSX;
|
msr |= MSR_VSX;
|
||||||
}
|
} else if (!ctx_has_vsx_region)
|
||||||
|
/*
|
||||||
|
* With a small context structure we can't hold the VSX
|
||||||
|
* registers, hence clear the MSR value to indicate the state
|
||||||
|
* was not saved.
|
||||||
|
*/
|
||||||
|
msr &= ~MSR_VSX;
|
||||||
|
|
||||||
|
|
||||||
#endif /* CONFIG_VSX */
|
#endif /* CONFIG_VSX */
|
||||||
#ifdef CONFIG_SPE
|
#ifdef CONFIG_SPE
|
||||||
/* save spe registers */
|
/* save spe registers */
|
||||||
|
|
|
@ -597,22 +597,6 @@ out:
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the value of the chip-id property corresponding
|
|
||||||
* to the given logical cpu.
|
|
||||||
*/
|
|
||||||
int cpu_to_chip_id(int cpu)
|
|
||||||
{
|
|
||||||
struct device_node *np;
|
|
||||||
|
|
||||||
np = of_get_cpu_node(cpu, NULL);
|
|
||||||
if (!np)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
of_node_put(np);
|
|
||||||
return of_get_ibm_chip_id(np);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(cpu_to_chip_id);
|
|
||||||
|
|
||||||
/* Helper routines for cpu to core mapping */
|
/* Helper routines for cpu to core mapping */
|
||||||
int cpu_core_index_of_thread(int cpu)
|
int cpu_core_index_of_thread(int cpu)
|
||||||
{
|
{
|
||||||
|
|
|
@ -213,8 +213,6 @@ static u64 scan_dispatch_log(u64 stop_tb)
|
||||||
if (i == be64_to_cpu(vpa->dtl_idx))
|
if (i == be64_to_cpu(vpa->dtl_idx))
|
||||||
return 0;
|
return 0;
|
||||||
while (i < be64_to_cpu(vpa->dtl_idx)) {
|
while (i < be64_to_cpu(vpa->dtl_idx)) {
|
||||||
if (dtl_consumer)
|
|
||||||
dtl_consumer(dtl, i);
|
|
||||||
dtb = be64_to_cpu(dtl->timebase);
|
dtb = be64_to_cpu(dtl->timebase);
|
||||||
tb_delta = be32_to_cpu(dtl->enqueue_to_dispatch_time) +
|
tb_delta = be32_to_cpu(dtl->enqueue_to_dispatch_time) +
|
||||||
be32_to_cpu(dtl->ready_to_enqueue_time);
|
be32_to_cpu(dtl->ready_to_enqueue_time);
|
||||||
|
@ -227,6 +225,8 @@ static u64 scan_dispatch_log(u64 stop_tb)
|
||||||
}
|
}
|
||||||
if (dtb > stop_tb)
|
if (dtb > stop_tb)
|
||||||
break;
|
break;
|
||||||
|
if (dtl_consumer)
|
||||||
|
dtl_consumer(dtl, i);
|
||||||
stolen += tb_delta;
|
stolen += tb_delta;
|
||||||
++i;
|
++i;
|
||||||
++dtl;
|
++dtl;
|
||||||
|
|
|
@ -1419,7 +1419,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node)
|
||||||
|
|
||||||
/* needed to ensure proper operation of coherent allocations
|
/* needed to ensure proper operation of coherent allocations
|
||||||
* later, in case driver doesn't set it explicitly */
|
* later, in case driver doesn't set it explicitly */
|
||||||
dma_set_mask_and_coherent(&viodev->dev, DMA_BIT_MASK(64));
|
dma_coerce_mask_and_coherent(&viodev->dev, DMA_BIT_MASK(64));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* register with generic device framework */
|
/* register with generic device framework */
|
||||||
|
|
|
@ -123,6 +123,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
|
||||||
struct mm_struct *mm = current->mm;
|
struct mm_struct *mm = current->mm;
|
||||||
unsigned long addr, len, end;
|
unsigned long addr, len, end;
|
||||||
unsigned long next;
|
unsigned long next;
|
||||||
|
unsigned long flags;
|
||||||
pgd_t *pgdp;
|
pgd_t *pgdp;
|
||||||
int nr = 0;
|
int nr = 0;
|
||||||
|
|
||||||
|
@ -156,7 +157,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
|
||||||
* So long as we atomically load page table pointers versus teardown,
|
* So long as we atomically load page table pointers versus teardown,
|
||||||
* we can follow the address down to the the page and take a ref on it.
|
* we can follow the address down to the the page and take a ref on it.
|
||||||
*/
|
*/
|
||||||
local_irq_disable();
|
local_irq_save(flags);
|
||||||
|
|
||||||
pgdp = pgd_offset(mm, addr);
|
pgdp = pgd_offset(mm, addr);
|
||||||
do {
|
do {
|
||||||
|
@ -179,7 +180,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
|
||||||
break;
|
break;
|
||||||
} while (pgdp++, addr = next, addr != end);
|
} while (pgdp++, addr = next, addr != end);
|
||||||
|
|
||||||
local_irq_enable();
|
local_irq_restore(flags);
|
||||||
|
|
||||||
return nr;
|
return nr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -258,7 +258,7 @@ static bool slice_scan_available(unsigned long addr,
|
||||||
slice = GET_HIGH_SLICE_INDEX(addr);
|
slice = GET_HIGH_SLICE_INDEX(addr);
|
||||||
*boundary_addr = (slice + end) ?
|
*boundary_addr = (slice + end) ?
|
||||||
((slice + end) << SLICE_HIGH_SHIFT) : SLICE_LOW_TOP;
|
((slice + end) << SLICE_HIGH_SHIFT) : SLICE_LOW_TOP;
|
||||||
return !!(available.high_slices & (1u << slice));
|
return !!(available.high_slices & (1ul << slice));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/prom.h>
|
#include <asm/prom.h>
|
||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
|
#include <asm/smp.h>
|
||||||
|
|
||||||
|
|
||||||
struct powernv_rng {
|
struct powernv_rng {
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <asm/archrandom.h>
|
#include <asm/archrandom.h>
|
||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
|
#include <asm/plpar_wrappers.h>
|
||||||
|
|
||||||
|
|
||||||
static int pseries_get_random_long(unsigned long *v)
|
static int pseries_get_random_long(unsigned long *v)
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/smp.h>
|
#include <linux/smp.h>
|
||||||
#include <linux/time.h>
|
#include <linux/time.h>
|
||||||
|
#include <linux/of_fdt.h>
|
||||||
|
|
||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
#include <asm/udbg.h>
|
#include <asm/udbg.h>
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
|
#include <linux/of_address.h>
|
||||||
|
|
||||||
#include "wsp.h"
|
#include "wsp.h"
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
#include <linux/smp.h>
|
#include <linux/smp.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
#include <linux/of_address.h>
|
||||||
|
#include <linux/of_irq.h>
|
||||||
|
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/time.h>
|
#include <linux/time.h>
|
||||||
|
#include <linux/of_address.h>
|
||||||
|
#include <linux/of_irq.h>
|
||||||
|
|
||||||
#include <asm/reg_a2.h>
|
#include <asm/reg_a2.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/smp.h>
|
#include <linux/smp.h>
|
||||||
#include <linux/time.h>
|
#include <linux/time.h>
|
||||||
|
#include <linux/of_fdt.h>
|
||||||
|
|
||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
#include <asm/udbg.h>
|
#include <asm/udbg.h>
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
#include <linux/of_address.h>
|
||||||
|
|
||||||
#include <asm/cputhreads.h>
|
#include <asm/cputhreads.h>
|
||||||
#include <asm/reg_a2.h>
|
#include <asm/reg_a2.h>
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <linux/smp.h>
|
#include <linux/smp.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/time.h>
|
#include <linux/time.h>
|
||||||
|
#include <linux/of_address.h>
|
||||||
|
|
||||||
#include <asm/scom.h>
|
#include <asm/scom.h>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue