Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f2a77abd authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull powerpc fixes from Ben Herrenschmidt:
 "Here are some more powerpc fixes for 3.14

  The main one is a nasty issue with the NUMA balancing support which
  requires a small generic change and the addition of a new accessor to
  set _PAGE_NUMA.  Both have been reviewed and acked by Mel and Rik.

  The changelog should have plenty of details but basically, without
  this fix, we get random user segfaults and/or corruptions due to
  missing TLB/hash flushes.  Aneesh series of 3 patches fixes it.

  We have some vDSO vs.  perf fixes from Anton, some small EEH fixes
  from Gavin, a ppc32 regression vs the stack overflow detector, and a
  fix for the way we handle PCIe host bridge speed settings on pseries
  (which is needed for proper operations of AMD graphics cards on
  Power8)"

* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc:
  powerpc/eeh: Disable EEH on reboot
  powerpc/eeh: Cleanup on eeh_subsystem_enabled
  powerpc/powernv: Rework EEH reset
  powerpc: Use unstripped VDSO image for more accurate profiling data
  powerpc: Link VDSOs at 0x0
  mm: Use ptep/pmdp_set_numa() for updating _PAGE_NUMA bit
  mm: Dirty accountable change only apply to non prot numa case
  powerpc/mm: Add new "set" flag argument to pte/pmd update function
  powerpc/pseries: Add Gen3 definitions for PCIE link speed
  powerpc/pseries: Fix regression on PCI link speed
  powerpc: Set the correct ksp_limit on ppc32 when switching to irq stack
parents e4178d80 66f9af83
Loading
Loading
Loading
Loading
+19 −2
Original line number Diff line number Diff line
@@ -172,10 +172,20 @@ struct eeh_ops {
};

extern struct eeh_ops *eeh_ops;
extern int eeh_subsystem_enabled;
extern bool eeh_subsystem_enabled;
extern raw_spinlock_t confirm_error_lock;
extern int eeh_probe_mode;

static inline bool eeh_enabled(void)
{
	return eeh_subsystem_enabled;
}

static inline void eeh_set_enable(bool mode)
{
	eeh_subsystem_enabled = mode;
}

#define EEH_PROBE_MODE_DEV	(1<<0)	/* From PCI device	*/
#define EEH_PROBE_MODE_DEVTREE	(1<<1)	/* From device tree	*/

@@ -246,7 +256,7 @@ void eeh_remove_device(struct pci_dev *);
 * If this macro yields TRUE, the caller relays to eeh_check_failure()
 * which does further tests out of line.
 */
#define EEH_POSSIBLE_ERROR(val, type)	((val) == (type)~0 && eeh_subsystem_enabled)
#define EEH_POSSIBLE_ERROR(val, type)	((val) == (type)~0 && eeh_enabled())

/*
 * Reads from a device which has been isolated by EEH will return
@@ -257,6 +267,13 @@ void eeh_remove_device(struct pci_dev *);

#else /* !CONFIG_EEH */

static inline bool eeh_enabled(void)
{
        return false;
}

static inline void eeh_set_enable(bool mode) { }

static inline int eeh_init(void)
{
	return 0;
+1 −1
Original line number Diff line number Diff line
@@ -127,7 +127,7 @@ static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
					    unsigned long addr, pte_t *ptep)
{
#ifdef CONFIG_PPC64
	return __pte(pte_update(mm, addr, ptep, ~0UL, 1));
	return __pte(pte_update(mm, addr, ptep, ~0UL, 0, 1));
#else
	return __pte(pte_update(ptep, ~0UL, 0));
#endif
+15 −11
Original line number Diff line number Diff line
@@ -195,6 +195,7 @@ extern void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
static inline unsigned long pte_update(struct mm_struct *mm,
				       unsigned long addr,
				       pte_t *ptep, unsigned long clr,
				       unsigned long set,
				       int huge)
{
#ifdef PTE_ATOMIC_UPDATES
@@ -205,14 +206,15 @@ static inline unsigned long pte_update(struct mm_struct *mm,
	andi.	%1,%0,%6\n\
	bne-	1b \n\
	andc	%1,%0,%4 \n\
	or	%1,%1,%7\n\
	stdcx.	%1,0,%3 \n\
	bne-	1b"
	: "=&r" (old), "=&r" (tmp), "=m" (*ptep)
	: "r" (ptep), "r" (clr), "m" (*ptep), "i" (_PAGE_BUSY)
	: "r" (ptep), "r" (clr), "m" (*ptep), "i" (_PAGE_BUSY), "r" (set)
	: "cc" );
#else
	unsigned long old = pte_val(*ptep);
	*ptep = __pte(old & ~clr);
	*ptep = __pte((old & ~clr) | set);
#endif
	/* huge pages use the old page table lock */
	if (!huge)
@@ -233,7 +235,7 @@ static inline int __ptep_test_and_clear_young(struct mm_struct *mm,

	if ((pte_val(*ptep) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0)
		return 0;
	old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0);
	old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0, 0);
	return (old & _PAGE_ACCESSED) != 0;
}
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
@@ -252,7 +254,7 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
	if ((pte_val(*ptep) & _PAGE_RW) == 0)
		return;

	pte_update(mm, addr, ptep, _PAGE_RW, 0);
	pte_update(mm, addr, ptep, _PAGE_RW, 0, 0);
}

static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
@@ -261,7 +263,7 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
	if ((pte_val(*ptep) & _PAGE_RW) == 0)
		return;

	pte_update(mm, addr, ptep, _PAGE_RW, 1);
	pte_update(mm, addr, ptep, _PAGE_RW, 0, 1);
}

/*
@@ -284,14 +286,14 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
				       unsigned long addr, pte_t *ptep)
{
	unsigned long old = pte_update(mm, addr, ptep, ~0UL, 0);
	unsigned long old = pte_update(mm, addr, ptep, ~0UL, 0, 0);
	return __pte(old);
}

static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
			     pte_t * ptep)
{
	pte_update(mm, addr, ptep, ~0UL, 0);
	pte_update(mm, addr, ptep, ~0UL, 0, 0);
}


@@ -506,7 +508,9 @@ extern int pmdp_set_access_flags(struct vm_area_struct *vma,

extern unsigned long pmd_hugepage_update(struct mm_struct *mm,
					 unsigned long addr,
					 pmd_t *pmdp, unsigned long clr);
					 pmd_t *pmdp,
					 unsigned long clr,
					 unsigned long set);

static inline int __pmdp_test_and_clear_young(struct mm_struct *mm,
					      unsigned long addr, pmd_t *pmdp)
@@ -515,7 +519,7 @@ static inline int __pmdp_test_and_clear_young(struct mm_struct *mm,

	if ((pmd_val(*pmdp) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0)
		return 0;
	old = pmd_hugepage_update(mm, addr, pmdp, _PAGE_ACCESSED);
	old = pmd_hugepage_update(mm, addr, pmdp, _PAGE_ACCESSED, 0);
	return ((old & _PAGE_ACCESSED) != 0);
}

@@ -542,7 +546,7 @@ static inline void pmdp_set_wrprotect(struct mm_struct *mm, unsigned long addr,
	if ((pmd_val(*pmdp) & _PAGE_RW) == 0)
		return;

	pmd_hugepage_update(mm, addr, pmdp, _PAGE_RW);
	pmd_hugepage_update(mm, addr, pmdp, _PAGE_RW, 0);
}

#define __HAVE_ARCH_PMDP_SPLITTING_FLUSH
+22 −0
Original line number Diff line number Diff line
@@ -75,12 +75,34 @@ static inline pte_t pte_mknuma(pte_t pte)
	return pte;
}

#define ptep_set_numa ptep_set_numa
static inline void ptep_set_numa(struct mm_struct *mm, unsigned long addr,
				 pte_t *ptep)
{
	if ((pte_val(*ptep) & _PAGE_PRESENT) == 0)
		VM_BUG_ON(1);

	pte_update(mm, addr, ptep, _PAGE_PRESENT, _PAGE_NUMA, 0);
	return;
}

#define pmd_numa pmd_numa
static inline int pmd_numa(pmd_t pmd)
{
	return pte_numa(pmd_pte(pmd));
}

#define pmdp_set_numa pmdp_set_numa
static inline void pmdp_set_numa(struct mm_struct *mm, unsigned long addr,
				 pmd_t *pmdp)
{
	if ((pmd_val(*pmdp) & _PAGE_PRESENT) == 0)
		VM_BUG_ON(1);

	pmd_hugepage_update(mm, addr, pmdp, _PAGE_PRESENT, _PAGE_NUMA);
	return;
}

#define pmd_mknonnuma pmd_mknonnuma
static inline pmd_t pmd_mknonnuma(pmd_t pmd)
{
+3 −3
Original line number Diff line number Diff line
@@ -4,11 +4,11 @@
#ifdef __KERNEL__

/* Default link addresses for the vDSOs */
#define VDSO32_LBASE	0x100000
#define VDSO64_LBASE	0x100000
#define VDSO32_LBASE	0x0
#define VDSO64_LBASE	0x0

/* Default map addresses for 32bit vDSO */
#define VDSO32_MBASE	VDSO32_LBASE
#define VDSO32_MBASE	0x100000

#define VDSO_VERSION_STRING	LINUX_2.6.15

Loading