Commit e942d752 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull powerpc fixes from Michael Ellerman:

 - fix miscompilation with GCC 4.9 by using asm_goto_volatile for put_user()

 - fix for an RCU splat at boot caused by a recent lockdep change

 - fix for a possible deadlock in our EEH debugfs code

 - several fixes for handling of _PAGE_ACCESSED on 32-bit platforms

 - build fix when CONFIG_NUMA=n

Thanks to Andreas Schwab, Christophe Leroy, Oliver O'Halloran, Qian Cai,
and Scott Cheloha.

* tag 'powerpc-5.10-3' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
  powerpc/numa: Fix build when CONFIG_NUMA=n
  powerpc/8xx: Manage _PAGE_ACCESSED through APG bits in L1 entry
  powerpc/8xx: Always fault when _PAGE_ACCESSED is not set
  powerpc/40x: Always fault when _PAGE_ACCESSED is not set
  powerpc/603: Always fault when _PAGE_ACCESSED is not set
  powerpc: Use asm_goto_volatile for put_user()
  powerpc/smp: Call rcu_cpu_starting() earlier
  powerpc/eeh_cache: Fix a possible debugfs deadlock
parents 4429f14a 3fb4a8fa
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -63,7 +63,7 @@ static inline void restore_user_access(unsigned long flags)
static inline bool
bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
{
	return WARN(!((regs->kuap ^ MD_APG_KUAP) & 0xf0000000),
	return WARN(!((regs->kuap ^ MD_APG_KUAP) & 0xff000000),
		    "Bug: fault blocked by AP register !");
}

+15 −32
Original line number Diff line number Diff line
@@ -33,19 +33,18 @@
 * respectively NA for All or X for Supervisor and no access for User.
 * Then we use the APG to say whether accesses are according to Page rules or
 * "all Supervisor" rules (Access to all)
 * Therefore, we define 2 APG groups. lsb is _PMD_USER
 * 0 => Kernel => 01 (all accesses performed according to page definition)
 * 1 => User => 00 (all accesses performed as supervisor iaw page definition)
 * 2-15 => Not Used
 */
#define MI_APG_INIT	0x40000000

/*
 * 0 => Kernel => 01 (all accesses performed according to page definition)
 * 1 => User => 10 (all accesses performed according to swaped page definition)
 * 2-15 => Not Used
 */
#define MI_APG_KUEP	0x60000000
 * _PAGE_ACCESSED is also managed via APG. When _PAGE_ACCESSED is not set, say
 * "all User" rules, that will lead to NA for all.
 * Therefore, we define 4 APG groups. lsb is _PAGE_ACCESSED
 * 0 => Kernel => 11 (all accesses performed according as user iaw page definition)
 * 1 => Kernel+Accessed => 01 (all accesses performed according to page definition)
 * 2 => User => 11 (all accesses performed according as user iaw page definition)
 * 3 => User+Accessed => 00 (all accesses performed as supervisor iaw page definition) for INIT
 *                    => 10 (all accesses performed according to swaped page definition) for KUEP
 * 4-15 => Not Used
 */
#define MI_APG_INIT	0xdc000000
#define MI_APG_KUEP	0xde000000

/* The effective page number register.  When read, contains the information
 * about the last instruction TLB miss.  When MI_RPN is written, bits in
@@ -106,25 +105,9 @@
#define MD_Ks		0x80000000	/* Should not be set */
#define MD_Kp		0x40000000	/* Should always be set */

/*
 * All pages' PP data bits are set to either 000 or 011 or 001, which means
 * respectively RW for Supervisor and no access for User, or RO for
 * Supervisor and no access for user and NA for ALL.
 * Then we use the APG to say whether accesses are according to Page rules or
 * "all Supervisor" rules (Access to all)
 * Therefore, we define 2 APG groups. lsb is _PMD_USER
 * 0 => Kernel => 01 (all accesses performed according to page definition)
 * 1 => User => 00 (all accesses performed as supervisor iaw page definition)
 * 2-15 => Not Used
 */
#define MD_APG_INIT	0x40000000

/*
 * 0 => No user => 01 (all accesses performed according to page definition)
 * 1 => User => 10 (all accesses performed according to swaped page definition)
 * 2-15 => Not Used
 */
#define MD_APG_KUAP	0x60000000
/* See explanation above at the definition of MI_APG_INIT */
#define MD_APG_INIT	0xdc000000
#define MD_APG_KUAP	0xde000000

/* The effective page number register.  When read, contains the information
 * about the last instruction TLB miss.  When MD_RPN is written, bits in
+5 −4
Original line number Diff line number Diff line
@@ -39,9 +39,9 @@
 * into the TLB.
 */
#define _PAGE_GUARDED	0x0010	/* Copied to L1 G entry in DTLB */
#define _PAGE_SPECIAL	0x0020	/* SW entry */
#define _PAGE_ACCESSED	0x0020	/* Copied to L1 APG 1 entry in I/DTLB */
#define _PAGE_EXEC	0x0040	/* Copied to PP (bit 21) in ITLB */
#define _PAGE_ACCESSED	0x0080	/* software: page referenced */
#define _PAGE_SPECIAL	0x0080	/* SW entry */

#define _PAGE_NA	0x0200	/* Supervisor NA, User no access */
#define _PAGE_RO	0x0600	/* Supervisor RO, User no access */
@@ -59,11 +59,12 @@

#define _PMD_PRESENT	0x0001
#define _PMD_PRESENT_MASK	_PMD_PRESENT
#define _PMD_BAD	0x0fd0
#define _PMD_BAD	0x0f90
#define _PMD_PAGE_MASK	0x000c
#define _PMD_PAGE_8M	0x000c
#define _PMD_PAGE_512K	0x0004
#define _PMD_USER	0x0020	/* APG 1 */
#define _PMD_ACCESSED	0x0020	/* APG 1 */
#define _PMD_USER	0x0040	/* APG 2 */

#define _PTE_NONE_MASK	0

+9 −3
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@

struct device;
struct device_node;
struct drmem_lmb;

#ifdef CONFIG_NUMA

@@ -61,6 +62,9 @@ static inline int early_cpu_to_node(int cpu)
	 */
	return (nid < 0) ? 0 : nid;
}

int of_drconf_to_nid_single(struct drmem_lmb *lmb);

#else

static inline int early_cpu_to_node(int cpu) { return 0; }
@@ -84,10 +88,12 @@ static inline int cpu_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc)
	return 0;
}

#endif /* CONFIG_NUMA */
static inline int of_drconf_to_nid_single(struct drmem_lmb *lmb)
{
	return first_online_node;
}

struct drmem_lmb;
int of_drconf_to_nid_single(struct drmem_lmb *lmb);
#endif /* CONFIG_NUMA */

#if defined(CONFIG_NUMA) && defined(CONFIG_PPC_SPLPAR)
extern int find_and_online_cpu_nid(int cpu);
+2 −2
Original line number Diff line number Diff line
@@ -178,7 +178,7 @@ do { \
 * are no aliasing issues.
 */
#define __put_user_asm_goto(x, addr, label, op)			\
	asm volatile goto(					\
	asm_volatile_goto(					\
		"1:	" op "%U1%X1 %0,%1	# put_user\n"	\
		EX_TABLE(1b, %l2)				\
		:						\
@@ -191,7 +191,7 @@ do { \
	__put_user_asm_goto(x, ptr, label, "std")
#else /* __powerpc64__ */
#define __put_user_asm2_goto(x, addr, label)			\
	asm volatile goto(					\
	asm_volatile_goto(					\
		"1:	stw%X1 %0, %1\n"			\
		"2:	stw%X1 %L0, %L1\n"			\
		EX_TABLE(1b, %l2)				\
Loading