LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v2] powerpc, pkey: make protection key 0 less special
From: Ram Pai @ 2018-04-06 18:01 UTC (permalink / raw)
  To: Thiago Jung Bauermann
  Cc: mpe, mingo, akpm, fweimer, shuah, msuchanek, linux-kernel, mhocko,
	dave.hansen, paulus, aneesh.kumar, tglx, linuxppc-dev
In-Reply-To: <876056645u.fsf@morokweng.localdomain>

On Wed, Apr 04, 2018 at 06:41:01PM -0300, Thiago Jung Bauermann wrote:
> 
> Hello Ram,
> 
> Ram Pai <linuxram@us.ibm.com> writes:
> 
> > Applications need the ability to associate an address-range with some
> > key and latter revert to its initial default key. Pkey-0 comes close to
> > providing this function but falls short, because the current
> > implementation disallows applications to explicitly associate pkey-0 to
> > the address range.
> >
> > Lets make pkey-0 less special and treat it almost like any other key.
> > Thus it can be explicitly associated with any address range, and can be
> > freed. This gives the application more flexibility and power.  The
> > ability to free pkey-0 must be used responsibily, since pkey-0 is
> > associated with almost all address-range by default.
> >
> > Even with this change pkey-0 continues to be slightly more special
> > from the following point of view.
> > (a) it is implicitly allocated.
> > (b) it is the default key assigned to any address-range.
> 
> It's also special in more ways (and if intentional, these should be part
> of the commit message as well):
> 
> (c) it's not possible to change permissions for key 0
> 
>   This has two causes: this patch explicitly forbids it in
>   arch_set_user_pkey_access(), and also because even if it's allocated,
>   the bits for key 0 in AMOR and UAMOR aren't set.

Yes. will have to capture that one aswell.

we cannot let userspace change permissions on key 0 because
doing so will hurt the kernel too. Unlike x86 where keys are effective
only in userspace, powerpc keys are effective even in the kernel.
So if the kernel tries to access something, it will get stuck forever.
Almost everything in the kernel is associated with key-0.

I ran a small test program which disabled access on key 0 from
userspace, and as expected ran into softlockups. It certainly
can lead to denial-of-service-attack. We can let apps
shoot-itself-in-its-foot but if the shot hurts someone else, we will
have to stop it.

The key-semantics discussed with the x86 folks did not 
explicitly say anything about changing permissions on key-0. We will
have to keep that part of the semantics open-ended.

> 
> (d) it can be freed, but can't be allocated again later.
> 
>   This is because mm_pkey_alloc() only calls __arch_activate_pkey(ret)
>   if ret > 0.
> 
> It looks like (d) is a bug. Either mm_pkey_free() should fail with key
> 0, or mm_pkey_alloc() should work with it.

Well, it can be allocated, just that we do not let userspace change the
permissions on the key.  __arch_activate_pkey(ret) does not get called
for pkey-0.


> 
> (c) could be a measure to prevent users from shooting themselves in
> their feet. But if that is the case, then mm_pkey_free() should forbid
> freeing key 0 too.
> 
> > Tested on powerpc.
> >
> > cc: Thomas Gleixner <tglx@linutronix.de>
> > cc: Dave Hansen <dave.hansen@intel.com>
> > cc: Michael Ellermen <mpe@ellerman.id.au>
> > cc: Ingo Molnar <mingo@kernel.org>
> > cc: Andrew Morton <akpm@linux-foundation.org>
> > Signed-off-by: Ram Pai <linuxram@us.ibm.com>
> > ---
> > History:
> > 	v2: mm_pkey_is_allocated() continued to treat pkey-0 special.
> > 	    fixed it.
> >
> >  arch/powerpc/include/asm/pkeys.h | 20 ++++++++++++++++----
> >  arch/powerpc/mm/pkeys.c          | 20 ++++++++++++--------
> >  2 files changed, 28 insertions(+), 12 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/pkeys.h b/arch/powerpc/include/asm/pkeys.h
> > index 0409c80..b598fa9 100644
> > --- a/arch/powerpc/include/asm/pkeys.h
> > +++ b/arch/powerpc/include/asm/pkeys.h
> > @@ -101,10 +101,14 @@ static inline u16 pte_to_pkey_bits(u64 pteflags)
> >
> >  static inline bool mm_pkey_is_allocated(struct mm_struct *mm, int pkey)
> >  {
> > -	/* A reserved key is never considered as 'explicitly allocated' */
> > -	return ((pkey < arch_max_pkey()) &&
> > -		!__mm_pkey_is_reserved(pkey) &&
> > -		__mm_pkey_is_allocated(mm, pkey));
> > +	if (pkey < 0 || pkey >= arch_max_pkey())
> > +		return false;
> > +
> > +	/* Reserved keys are never allocated. */
> > +	if (__mm_pkey_is_reserved(pkey))
> > +		return false;
> > +
> > +	return __mm_pkey_is_allocated(mm, pkey);
> >  }
> >
> >  extern void __arch_activate_pkey(int pkey);
> > @@ -200,6 +204,14 @@ static inline int arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
> >  {
> >  	if (static_branch_likely(&pkey_disabled))
> >  		return -EINVAL;
> > +
> > +	/*
> > +	 * userspace is discouraged from changing permissions of
> > +	 * pkey-0.
> 
> They're not discouraged. They're not allowed to. :-)

ok :-)

> 
> > +	 * powerpc hardware does not support it anyway.
> 
> It doesn't? I don't get that impression from reading the ISA, but
> perhaps I'm missing something.

Good Catch. I am wrongly blaming it on powerpc hardware.
Its a semantics enforced by our pkey code to block DOS attacks.

> 
> > +	 */
> > +	if (!pkey)
> > +		return init_val ? -EINVAL : 0;
> > +
> >  	return __arch_set_user_pkey_access(tsk, pkey, init_val);
> >  }
> >
> > diff --git a/arch/powerpc/mm/pkeys.c b/arch/powerpc/mm/pkeys.c
> > index ba71c54..e7a9e34 100644
> > --- a/arch/powerpc/mm/pkeys.c
> > +++ b/arch/powerpc/mm/pkeys.c
> > @@ -119,19 +119,21 @@ int pkey_initialize(void)
> >  #else
> >  	os_reserved = 0;
> >  #endif
> > -	/*
> > -	 * Bits are in LE format. NOTE: 1, 0 are reserved.
> > -	 * key 0 is the default key, which allows read/write/execute.
> > -	 * key 1 is recommended not to be used. PowerISA(3.0) page 1015,
> > -	 * programming note.
> > -	 */
> > +	/* Bits are in LE format. */
> >  	initial_allocation_mask = ~0x0;
> >
> >  	/* register mask is in BE format */
> >  	pkey_amr_uamor_mask = ~0x0ul;
> >  	pkey_iamr_mask = ~0x0ul;
> >
> > -	for (i = 2; i < (pkeys_total - os_reserved); i++) {
> > +	for (i = 0; i < (pkeys_total - os_reserved); i++) {
> > +	 	/*
> 
> There's a space between the tabs here.

ok. will fix.

> 
> > +		 * key 1 is recommended not to be used.
> > +		 * PowerISA(3.0) page 1015,
> > +		 */
> > +		if (i == 1)
> > +			continue;
> > +
> >  		initial_allocation_mask &= ~(0x1 << i);
> >  		pkey_amr_uamor_mask &= ~(0x3ul << pkeyshift(i));
> >  		pkey_iamr_mask &= ~(0x1ul << pkeyshift(i));
> > @@ -145,7 +147,9 @@ void pkey_mm_init(struct mm_struct *mm)
> >  {
> >  	if (static_branch_likely(&pkey_disabled))
> >  		return;
> > -	mm_pkey_allocation_map(mm) = initial_allocation_mask;
> > +
> > +	/* allocate key-0 by default */
> > +	mm_pkey_allocation_map(mm) = initial_allocation_mask | 0x1;
> >  	/* -1 means unallocated or invalid */
> >  	mm->context.execute_only_pkey = -1;
> >  }
> 
> I think we should also set the AMOR and UAMOR bits for key 0. Otherwise,
> key 0 will be in allocated-but-not-enabled state which is yet another
> subtle way in which it will be special.

No. as explained above, it will hurt to let userspace modify
permissions on key-0.

> 
> Also, pkey_access_permitted() has a special case for key 0. Should it?

we can delete that check. though it does not hurt to leave it in place.
Access/Write/Execute on pkey-0 is always permitted.

RP

^ permalink raw reply

* Re: [PATCH 1/5] arm64: entry: isb in el1_irq
From: Mark Rutland @ 2018-04-06 17:50 UTC (permalink / raw)
  To: Yury Norov
  Cc: James Morse, Paul E. McKenney, Will Deacon, Chris Metcalf,
	Christopher Lameter, Russell King - ARM Linux, Steven Rostedt,
	Mathieu Desnoyers, Catalin Marinas, Pekka Enberg, David Rientjes,
	Joonsoo Kim, Andrew Morton, Benjamin Herrenschmidt,
	Paul Mackerras, Michael Ellerman, Alexey Klimov, linux-arm-kernel,
	linuxppc-dev, kvm-ppc, linux-mm, linux-kernel
In-Reply-To: <20180406172211.r42reit2bnpocab2@lakrids.cambridge.arm.com>

On Fri, Apr 06, 2018 at 06:22:11PM +0100, Mark Rutland wrote:
> Digging a bit, I also thing that our ct_user_exit and ct_user_enter
> usage is on dodgy ground today.
> 
> For example, in el0_dbg we call do_debug_exception() *before* calling
> ct_user_exit. Which I believe means we'd use RCU while supposedly in an
> extended quiescent period, which would be bad.

It seems this is the case. I can trigger the following by having GDB
place a SW breakpoint:

[   51.217947] =============================
[   51.217953] WARNING: suspicious RCU usage
[   51.217961] 4.16.0 #4 Not tainted
[   51.217966] -----------------------------
[   51.217974] ./include/linux/rcupdate.h:632 rcu_read_lock() used illegally while idle!
[   51.217980]
[   51.217980] other info that might help us debug this:
[   51.217980]
[   51.217987]
[   51.217987] RCU used illegally from idle CPU!
[   51.217987] rcu_scheduler_active = 2, debug_locks = 1
[   51.217992] RCU used illegally from extended quiescent state!
[   51.217999] 1 lock held by ls/2412:
[   51.218004]  #0:  (rcu_read_lock){....}, at: [<0000000092efbdd5>] brk_handler+0x0/0x198
[   51.218041]
[   51.218041] stack backtrace:
[   51.218049] CPU: 2 PID: 2412 Comm: ls Not tainted 4.16.0 #4
[   51.218055] Hardware name: ARM Juno development board (r1) (DT)
[   51.218061] Call trace:
[   51.218070]  dump_backtrace+0x0/0x1c8
[   51.218078]  show_stack+0x14/0x20
[   51.218087]  dump_stack+0xac/0xe4
[   51.218096]  lockdep_rcu_suspicious+0xcc/0x110
[   51.218103]  brk_handler+0x144/0x198
[   51.218110]  do_debug_exception+0x9c/0x190
[   51.218116]  el0_dbg+0x14/0x20

We will need to fix this before we can fiddle with kick_all_cpus_sync().

Thanks,
Mark.

^ permalink raw reply

* Re: [PATCH 1/5] arm64: entry: isb in el1_irq
From: Mark Rutland @ 2018-04-06 17:34 UTC (permalink / raw)
  To: James Morse
  Cc: Yury Norov, Paul E. McKenney, Will Deacon, Chris Metcalf,
	Christopher Lameter, Russell King - ARM Linux, Steven Rostedt,
	Mathieu Desnoyers, Catalin Marinas, Pekka Enberg, David Rientjes,
	Joonsoo Kim, Andrew Morton, Benjamin Herrenschmidt,
	Paul Mackerras, Michael Ellerman, Alexey Klimov, linux-arm-kernel,
	linuxppc-dev, kvm-ppc, linux-mm, linux-kernel
In-Reply-To: <1ef13053-c3eb-deea-a4cc-67723fdf47f8@arm.com>

On Fri, Apr 06, 2018 at 06:30:50PM +0100, James Morse wrote:
> Hi Mark,
> 
> On 06/04/18 18:22, Mark Rutland wrote:
> > Digging a bit, I also thing that our ct_user_exit and ct_user_enter
> > usage is on dodgy ground today.
> 
> [...]
> 
> > I think similar applies to SDEI; we don't negotiate with RCU prior to
> > invoking handlers, which might need RCU.
> 
> The arch code's __sdei_handler() calls nmi_enter() -> rcu_nmi_enter(), which
> does a rcu_dynticks_eqs_exit().

Ah, sorry. I missed that!

Thanks,
Mark.

^ permalink raw reply

* Re: [PATCH 1/5] arm64: entry: isb in el1_irq
From: James Morse @ 2018-04-06 17:30 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Yury Norov, Paul E. McKenney, Will Deacon, Chris Metcalf,
	Christopher Lameter, Russell King - ARM Linux, Steven Rostedt,
	Mathieu Desnoyers, Catalin Marinas, Pekka Enberg, David Rientjes,
	Joonsoo Kim, Andrew Morton, Benjamin Herrenschmidt,
	Paul Mackerras, Michael Ellerman, Alexey Klimov, linux-arm-kernel,
	linuxppc-dev, kvm-ppc, linux-mm, linux-kernel
In-Reply-To: <20180406172211.r42reit2bnpocab2@lakrids.cambridge.arm.com>

Hi Mark,

On 06/04/18 18:22, Mark Rutland wrote:
> Digging a bit, I also thing that our ct_user_exit and ct_user_enter
> usage is on dodgy ground today.

[...]

> I think similar applies to SDEI; we don't negotiate with RCU prior to
> invoking handlers, which might need RCU.

The arch code's __sdei_handler() calls nmi_enter() -> rcu_nmi_enter(), which
does a rcu_dynticks_eqs_exit().


Thanks,

James

^ permalink raw reply

* Re: [PATCH 1/5] arm64: entry: isb in el1_irq
From: Mark Rutland @ 2018-04-06 17:22 UTC (permalink / raw)
  To: Yury Norov
  Cc: James Morse, Paul E. McKenney, Will Deacon, Chris Metcalf,
	Christopher Lameter, Russell King - ARM Linux, Steven Rostedt,
	Mathieu Desnoyers, Catalin Marinas, Pekka Enberg, David Rientjes,
	Joonsoo Kim, Andrew Morton, Benjamin Herrenschmidt,
	Paul Mackerras, Michael Ellerman, Alexey Klimov, linux-arm-kernel,
	linuxppc-dev, kvm-ppc, linux-mm, linux-kernel
In-Reply-To: <20180406165402.nq3sabeku2mp3hpb@yury-thinkpad>

On Fri, Apr 06, 2018 at 07:54:02PM +0300, Yury Norov wrote:
> In general, kick_all_cpus_sync() is needed to switch contexts. But exit from
> userspace is anyway the switch of context. And while in userspace, we cannot
> do something wrong on kernel side. For me it means that we can safely drop
> IPI for all userspace modes - both normal and nohz_full. 

This *may* be true, but only if we never have to patch text in the
windows:

* between exception entry and eqs_exit()

* between eqs_enter() and exception return

* between eqs_enter() and eqs_exit() in the idle loop.

If it's possible that we need to execute patched text in any of those
paths, we must IPI all CPUs in order to correctly serialize things.

Digging a bit, I also thing that our ct_user_exit and ct_user_enter
usage is on dodgy ground today.

For example, in el0_dbg we call do_debug_exception() *before* calling
ct_user_exit. Which I believe means we'd use RCU while supposedly in an
extended quiescent period, which would be bad.

In other paths, we unmask all DAIF bits before calling ct_user_exit, so
we could similarly take an EL1 debug exception without having exited the
extended quiescent period.

I think similar applies to SDEI; we don't negotiate with RCU prior to
invoking handlers, which might need RCU.

> If it's correct, for v3 I would suggest:
>  - in kick_all_cpus_sync() mask all is_idle_task() and user_mode() CPUs;
>  - add isb() for arm64 in do_idle() path only - this path doesn't imply
>    context switch.

As mentioned in my other reply, I don't think the ISB in do_idle()
makes sense, unless that occurs *after* we exit the extended quiescent
state.

Thanks,
Mark.

^ permalink raw reply

* [PATCH] selftests/powerpc: add test to verify rfi flush across a system call
From: Naveen N. Rao @ 2018-04-06 16:55 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: Anton Blanchard, linuxppc-dev

This adds a test to verify proper functioning of the rfi flush
capability implemented to mitigate meltdown. The test works by measuring
the number of L1d cache misses encountered while loading data from
memory. Across a system call, since the L1d cache is flushed when
rfi_flush is enabled, the number of cache misses is expected to be
relative to the number of cachelines corresponding to the data being
loaded.

The current system setting is reflected via powerpc/rfi_flush under
debugfs (assumed to be /sys/kernel/debug/). This test verifies the
expected result with rfi_flush enabled as well as when it is disabled.

Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
---
 tools/testing/selftests/powerpc/Makefile           |   3 +-
 tools/testing/selftests/powerpc/include/utils.h    |  10 ++
 tools/testing/selftests/powerpc/security/Makefile  |   7 +
 .../testing/selftests/powerpc/security/rfi_flush.c | 130 +++++++++++++++++
 tools/testing/selftests/powerpc/utils.c            | 153 +++++++++++++++++++++
 5 files changed, 302 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/powerpc/security/Makefile
 create mode 100644 tools/testing/selftests/powerpc/security/rfi_flush.c

diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile
index f6b1338730db..bc0322d2d79a 100644
--- a/tools/testing/selftests/powerpc/Makefile
+++ b/tools/testing/selftests/powerpc/Makefile
@@ -29,7 +29,8 @@ SUB_DIRS = alignment		\
 	   tm			\
 	   vphn         \
 	   math		\
-	   ptrace
+	   ptrace	\
+	   security
 
 endif
 
diff --git a/tools/testing/selftests/powerpc/include/utils.h b/tools/testing/selftests/powerpc/include/utils.h
index 735815b3ad7f..72bbe5c1daf0 100644
--- a/tools/testing/selftests/powerpc/include/utils.h
+++ b/tools/testing/selftests/powerpc/include/utils.h
@@ -11,6 +11,7 @@
 #include <stdint.h>
 #include <stdbool.h>
 #include <linux/auxvec.h>
+#include <linux/perf_event.h>
 #include "reg.h"
 
 /* Avoid headaches with PRI?64 - just use %ll? always */
@@ -31,6 +32,15 @@ void *get_auxv_entry(int type);
 
 int pick_online_cpu(void);
 
+int read_debugfs_file(char *debugfs_file, int *result);
+int write_debugfs_file(char *debugfs_file, int result);
+void set_dscr(unsigned long val);
+int perf_event_open_counter(unsigned int type,
+			    unsigned long config, int group_fd);
+int perf_event_enable(int fd);
+int perf_event_disable(int fd);
+int perf_event_reset(int fd);
+
 static inline bool have_hwcap(unsigned long ftr)
 {
 	return ((unsigned long)get_auxv_entry(AT_HWCAP) & ftr) == ftr;
diff --git a/tools/testing/selftests/powerpc/security/Makefile b/tools/testing/selftests/powerpc/security/Makefile
new file mode 100644
index 000000000000..8a472e13950a
--- /dev/null
+++ b/tools/testing/selftests/powerpc/security/Makefile
@@ -0,0 +1,7 @@
+TEST_GEN_PROGS := rfi_flush
+
+CFLAGS += -I../../../../../usr/include
+
+include ../../lib.mk
+
+$(TEST_GEN_PROGS): ../harness.c ../utils.c
diff --git a/tools/testing/selftests/powerpc/security/rfi_flush.c b/tools/testing/selftests/powerpc/security/rfi_flush.c
new file mode 100644
index 000000000000..92a34da69a9b
--- /dev/null
+++ b/tools/testing/selftests/powerpc/security/rfi_flush.c
@@ -0,0 +1,130 @@
+#include <sys/types.h>
+#include <stdint.h>
+#include <malloc.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "utils.h"
+
+#define CACHELINE_SIZE	128
+
+struct perf_event_read {
+	uint64_t nr;
+	uint64_t l1d_misses;
+};
+
+static inline uint64_t load(void *addr)
+{
+	uint64_t tmp;
+
+	asm volatile("ld %0,0(%1)" : "=r"(tmp) : "b" (addr));
+
+	return tmp;
+}
+
+static void syscall_loop(char *p, unsigned long iterations, unsigned long zero_size)
+{
+	for (unsigned long i = 0; i < iterations; i++) {
+		for (unsigned long j = 0; j < zero_size; j += CACHELINE_SIZE)
+			load(p + j);
+		getppid();
+	}
+}
+
+int rfi_flush_test(void)
+{
+	char *p;
+	int repetitions = 10;
+	int fd, passes = 0, iter, rc = 0;
+	struct perf_event_read v;
+	uint64_t l1d_misses_total = 0;
+	unsigned long iterations = 100000, zero_size = 24*1024;
+	int rfi_flush_org, rfi_flush;
+
+	SKIP_IF(geteuid() != 0);
+
+	if (read_debugfs_file("powerpc/rfi_flush", &rfi_flush_org)) {
+		perror("error reading powerpc/rfi_flush debugfs file");
+	        printf("unable to determine current rfi_flush setting");
+		return 1;
+	}
+
+	rfi_flush = rfi_flush_org;
+
+	FAIL_IF((fd = perf_event_open_counter(PERF_TYPE_RAW,
+					  0x400f0, /* L1d miss */
+					  -1)) < 0);
+
+	p = (char *)memalign(zero_size, CACHELINE_SIZE);
+
+	FAIL_IF(perf_event_enable(fd));
+
+	set_dscr(1);
+
+	iter = repetitions;
+
+again:
+	FAIL_IF(perf_event_reset(fd));
+
+	syscall_loop(p, iterations, zero_size);
+
+	FAIL_IF(read(fd, &v, sizeof(v)) != sizeof(v));
+
+	/* Expect at least zero_size/CACHELINE_SIZE misses per iteration */
+	if (v.l1d_misses >= (iterations * zero_size / CACHELINE_SIZE) &&
+			rfi_flush)
+		passes++;
+	else if (v.l1d_misses < iterations && !rfi_flush)
+		passes++;
+
+	l1d_misses_total += v.l1d_misses;
+
+	while (--iter)
+		goto again;
+
+	if (passes < repetitions) {
+		printf("FAIL (%lu misses, %c %lu expected) [%d/%d failures]\n",
+			l1d_misses_total,
+			rfi_flush ? '>' : '<',
+			rfi_flush ? (repetitions * iterations * zero_size/CACHELINE_SIZE) :
+				iterations,
+			repetitions - passes, repetitions);
+		rc = 1;
+	} else
+		printf("PASS (%lu misses, %c %lu expected) [%d/%d pass]\n",
+			l1d_misses_total,
+			rfi_flush ? '>' : '<',
+			rfi_flush ? (repetitions * iterations * zero_size/CACHELINE_SIZE) :
+				iterations,
+			passes, repetitions);
+
+	if (rfi_flush == rfi_flush_org) {
+		rfi_flush = !rfi_flush_org;
+		if (write_debugfs_file("powerpc/rfi_flush", rfi_flush) < 0) {
+			perror("error writing to powerpc/rfi_flush debugfs file");
+			return 1;
+		}
+		iter = repetitions;
+		l1d_misses_total = 0;
+		passes = 0;
+		goto again;
+	}
+
+	perf_event_disable(fd);
+	close(fd);
+
+	set_dscr(0);
+
+	if (write_debugfs_file("powerpc/rfi_flush", rfi_flush_org) < 0) {
+		perror("unable to restore original value of powerpc/rfi_flush debugfs file");
+		return 1;
+	}
+
+	return rc;
+}
+
+int main(int argc, char *argv[])
+{
+	return test_harness(rfi_flush_test, "rfi_flush_test");
+}
diff --git a/tools/testing/selftests/powerpc/utils.c b/tools/testing/selftests/powerpc/utils.c
index d46916867a6f..c6b1d20ed3ba 100644
--- a/tools/testing/selftests/powerpc/utils.c
+++ b/tools/testing/selftests/powerpc/utils.c
@@ -11,13 +11,20 @@
 #include <link.h>
 #include <sched.h>
 #include <stdio.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <sys/ioctl.h>
 #include <unistd.h>
+#include <asm/unistd.h>
+#include <linux/limits.h>
 
 #include "utils.h"
 
 static char auxv[4096];
+extern unsigned int dscr_insn[];
 
 int read_auxv(char *buf, ssize_t buf_size)
 {
@@ -104,3 +111,149 @@ int pick_online_cpu(void)
 	printf("No cpus in affinity mask?!\n");
 	return -1;
 }
+
+int read_debugfs_file(char *debugfs_file, int *result)
+{
+	int rc = -1, fd;
+	char path[PATH_MAX];
+	char value[16];
+
+	strcpy(path, "/sys/kernel/debug/");
+	strncat(path, debugfs_file, PATH_MAX - strlen(path) - 1);
+
+	if ((fd = open(path, O_RDONLY)) < 0)
+		return rc;
+
+	if ((rc = read(fd, value, sizeof(value))) < 0)
+		return rc;
+
+	value[15] = 0;
+	*result = atoi(value);
+	close(fd);
+
+	return 0;
+}
+
+int write_debugfs_file(char *debugfs_file, int result)
+{
+	int rc = -1, fd;
+	char path[PATH_MAX];
+	char value[16];
+
+	strcpy(path, "/sys/kernel/debug/");
+	strncat(path, debugfs_file, PATH_MAX - strlen(path) - 1);
+
+	if ((fd = open(path, O_WRONLY)) < 0)
+		return rc;
+
+	snprintf(value, 16, "%d", result);
+
+	if ((rc = write(fd, value, strlen(value))) < 0)
+		return rc;
+
+	close(fd);
+
+	return 0;
+}
+
+static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
+		int cpu, int group_fd, unsigned long flags)
+{
+	return syscall(__NR_perf_event_open, hw_event, pid, cpu,
+		      group_fd, flags);
+}
+
+static void perf_event_attr_init(struct perf_event_attr *event_attr,
+					unsigned int type,
+					unsigned long config)
+{
+	memset(event_attr, 0, sizeof(*event_attr));
+
+	event_attr->type = type;
+	event_attr->size = sizeof(struct perf_event_attr);
+	event_attr->config = config;
+	event_attr->read_format = PERF_FORMAT_GROUP;
+	event_attr->disabled = 1;
+	event_attr->exclude_kernel = 1;
+	event_attr->exclude_hv = 1;
+	event_attr->exclude_guest = 1;
+}
+
+int perf_event_open_counter(unsigned int type,
+			    unsigned long config, int group_fd)
+{
+	int fd;
+	struct perf_event_attr event_attr;
+
+	perf_event_attr_init(&event_attr, type, config);
+
+	fd = perf_event_open(&event_attr, 0, -1, group_fd, 0);
+
+	if (fd < 0)
+		perror("perf_event_open() failed");
+
+	return fd;
+}
+
+int perf_event_enable(int fd)
+{
+	if (ioctl(fd, PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP) == -1) {
+		perror("error while enabling perf events");
+		return -1;
+	}
+
+	return 0;
+}
+
+int perf_event_disable(int fd)
+{
+	if (ioctl(fd, PERF_EVENT_IOC_DISABLE, PERF_IOC_FLAG_GROUP) == -1) {
+		perror("error disabling perf events");
+		return -1;
+	}
+
+	return 0;
+}
+
+int perf_event_reset(int fd)
+{
+	if (ioctl(fd, PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP) == -1) {
+		perror("error resetting perf events");
+		return -1;
+	}
+
+	return 0;
+}
+
+static void sigill_handler(int signr, siginfo_t *info, void *unused)
+{
+	static int warned = 0;
+	ucontext_t *ctx = (ucontext_t *)unused;
+	unsigned int *pc = (unsigned int *)ctx->uc_mcontext.gp_regs[PT_NIP];
+
+	if (pc == dscr_insn) {
+		if (!warned++)
+			printf("WARNING: Skipping over dscr setup. Consider running 'ppc64_cpu --dscr=1' manually.\n");
+		ctx->uc_mcontext.gp_regs[PT_NIP] += 4;
+	} else {
+		printf("SIGILL at %p\n", pc);
+		abort();
+	}
+}
+
+void set_dscr(unsigned long val)
+{
+	static int init = 0;
+	struct sigaction sa;
+
+	if (!init) {
+		memset(&sa, 0, sizeof(sa));
+		sa.sa_sigaction = sigill_handler;
+		sa.sa_flags = SA_SIGINFO;
+		if (sigaction(SIGILL, &sa, NULL))
+			perror("sigill_handler");
+		init = 1;
+	}
+
+	asm volatile("dscr_insn: mtspr %1,%0" : : "r" (val), "i" (SPRN_DSCR));
+}
-- 
2.16.2

^ permalink raw reply related

* Re: [PATCH 1/5] arm64: entry: isb in el1_irq
From: Yury Norov @ 2018-04-06 16:54 UTC (permalink / raw)
  To: James Morse
  Cc: Paul E. McKenney, Mark Rutland, Will Deacon, Chris Metcalf,
	Christopher Lameter, Russell King - ARM Linux, Steven Rostedt,
	Mathieu Desnoyers, Catalin Marinas, Pekka Enberg, David Rientjes,
	Joonsoo Kim, Andrew Morton, Benjamin Herrenschmidt,
	Paul Mackerras, Michael Ellerman, Alexey Klimov, linux-arm-kernel,
	linuxppc-dev, kvm-ppc, linux-mm, linux-kernel
In-Reply-To: <5036b99a-9faa-c220-27dd-e0d73f8b3fc7@arm.com>

On Fri, Apr 06, 2018 at 11:02:56AM +0100, James Morse wrote:
> Hi Yury,
> 
> An ISB at the beginning of the vectors? This is odd, taking an IRQ to get in
> here would be a context-synchronization-event too, so the ISB is superfluous.
> 
> The ARM-ARM  has a list of 'Context-Synchronization event's (Glossary on page
> 6480 of DDI0487B.b), paraphrasing:
> * ISB
> * Taking an exception
> * ERET
> * (...loads of debug stuff...)

Hi James, Mark,

I completely forgot that taking an exception is the context synchronization
event. Sorry for your time on reviewing this crap. It means that patches 1,
2 and 3 are not needed except chunk that adds ISB in do_idle() path. 

Also it means that for arm64 we are safe to mask IPI delivering to CPUs that
run any userspace code, not only nohz_full.

In general, kick_all_cpus_sync() is needed to switch contexts. But exit from
userspace is anyway the switch of context. And while in userspace, we cannot
do something wrong on kernel side. For me it means that we can safely drop
IPI for all userspace modes - both normal and nohz_full. 

If it's correct, for v3 I would suggest:
 - in kick_all_cpus_sync() mask all is_idle_task() and user_mode() CPUs;
 - add isb() for arm64 in do_idle() path only - this path doesn't imply
   context switch.

What do you think?

Yury

^ permalink raw reply

* Re: [PATCH 3/5] powerpc/boot: Remove support for Marvell mv64x60 i2c controller
From: Dale Farnsworth @ 2018-04-06 16:37 UTC (permalink / raw)
  To: Mark Greer
  Cc: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Remi Machet, linuxppc-dev, linux-kernel
In-Reply-To: <20180406011720.7728-4-mgreer@animalcreek.com>

[-- Attachment #1: Type: text/plain, Size: 9051 bytes --]

Acked-by: Dale Farnsworth <dale@farnsworth.org>

On Thu, Apr 5, 2018 at 6:17 PM, Mark Greer <mgreer@animalcreek.com> wrote:

> There are no longer any platforms that use Marvell's mv64x60's i2c
> controller so remove its driver.
>
> Signed-off-by: Mark Greer <mgreer@animalcreek.com>
> ---
>  arch/powerpc/boot/Makefile      |   2 +-
>  arch/powerpc/boot/mv64x60_i2c.c | 204 ------------------------------
> ----------
>  2 files changed, 1 insertion(+), 205 deletions(-)
>  delete mode 100644 arch/powerpc/boot/mv64x60_i2c.c
>
> diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
> index 58f2dbfba275..bf6a46055ba7 100644
> --- a/arch/powerpc/boot/Makefile
> +++ b/arch/powerpc/boot/Makefile
> @@ -120,7 +120,7 @@ src-wlib-$(CONFIG_40x) += 4xx.c planetcore.c
>  src-wlib-$(CONFIG_44x) += 4xx.c ebony.c bamboo.c
>  src-wlib-$(CONFIG_PPC_8xx) += mpc8xx.c planetcore.c fsl-soc.c
>  src-wlib-$(CONFIG_PPC_82xx) += pq2.c fsl-soc.c planetcore.c
> -src-wlib-$(CONFIG_EMBEDDED6xx) += mv64x60.c mv64x60_i2c.c ugecon.c
> fsl-soc.c
> +src-wlib-$(CONFIG_EMBEDDED6xx) += mv64x60.c ugecon.c fsl-soc.c
>  src-wlib-$(CONFIG_XILINX_VIRTEX) += uartlite.c
>  src-wlib-$(CONFIG_CPM) += cpm-serial.c
>
> diff --git a/arch/powerpc/boot/mv64x60_i2c.c b/arch/powerpc/boot/mv64x60_
> i2c.c
> deleted file mode 100644
> index 52a3212b6638..000000000000
> --- a/arch/powerpc/boot/mv64x60_i2c.c
> +++ /dev/null
> @@ -1,204 +0,0 @@
> -/*
> - * Bootloader version of the i2c driver for the MV64x60.
> - *
> - * Author: Dale Farnsworth <dfarnsworth@mvista.com>
> - * Maintained by: Mark A. Greer <mgreer@mvista.com>
> - *
> - * 2003, 2007 (c) MontaVista, Software, Inc.  This file is licensed under
> - * the terms of the GNU General Public License version 2.  This program is
> - * licensed "as is" without any warranty of any kind, whether express or
> - * implied.
> - */
> -
> -#include <stdarg.h>
> -#include <stddef.h>
> -#include "types.h"
> -#include "elf.h"
> -#include "page.h"
> -#include "string.h"
> -#include "stdio.h"
> -#include "io.h"
> -#include "ops.h"
> -#include "mv64x60.h"
> -
> -/* Register defines */
> -#define MV64x60_I2C_REG_SLAVE_ADDR                     0x00
> -#define MV64x60_I2C_REG_DATA                           0x04
> -#define MV64x60_I2C_REG_CONTROL                                0x08
> -#define MV64x60_I2C_REG_STATUS                         0x0c
> -#define MV64x60_I2C_REG_BAUD                           0x0c
> -#define MV64x60_I2C_REG_EXT_SLAVE_ADDR                 0x10
> -#define MV64x60_I2C_REG_SOFT_RESET                     0x1c
> -
> -#define MV64x60_I2C_CONTROL_ACK                                0x04
> -#define MV64x60_I2C_CONTROL_IFLG                       0x08
> -#define MV64x60_I2C_CONTROL_STOP                       0x10
> -#define MV64x60_I2C_CONTROL_START                      0x20
> -#define MV64x60_I2C_CONTROL_TWSIEN                     0x40
> -#define MV64x60_I2C_CONTROL_INTEN                      0x80
> -
> -#define MV64x60_I2C_STATUS_BUS_ERR                     0x00
> -#define MV64x60_I2C_STATUS_MAST_START                  0x08
> -#define MV64x60_I2C_STATUS_MAST_REPEAT_START           0x10
> -#define MV64x60_I2C_STATUS_MAST_WR_ADDR_ACK            0x18
> -#define MV64x60_I2C_STATUS_MAST_WR_ADDR_NO_ACK         0x20
> -#define MV64x60_I2C_STATUS_MAST_WR_ACK                 0x28
> -#define MV64x60_I2C_STATUS_MAST_WR_NO_ACK              0x30
> -#define MV64x60_I2C_STATUS_MAST_LOST_ARB               0x38
> -#define MV64x60_I2C_STATUS_MAST_RD_ADDR_ACK            0x40
> -#define MV64x60_I2C_STATUS_MAST_RD_ADDR_NO_ACK         0x48
> -#define MV64x60_I2C_STATUS_MAST_RD_DATA_ACK            0x50
> -#define MV64x60_I2C_STATUS_MAST_RD_DATA_NO_ACK         0x58
> -#define MV64x60_I2C_STATUS_MAST_WR_ADDR_2_ACK          0xd0
> -#define MV64x60_I2C_STATUS_MAST_WR_ADDR_2_NO_ACK       0xd8
> -#define MV64x60_I2C_STATUS_MAST_RD_ADDR_2_ACK          0xe0
> -#define MV64x60_I2C_STATUS_MAST_RD_ADDR_2_NO_ACK       0xe8
> -#define MV64x60_I2C_STATUS_NO_STATUS                   0xf8
> -
> -static u8 *ctlr_base;
> -
> -static int mv64x60_i2c_wait_for_status(int wanted)
> -{
> -       int i;
> -       int status;
> -
> -       for (i=0; i<1000; i++) {
> -               udelay(10);
> -               status = in_le32((u32 *)(ctlr_base +
> MV64x60_I2C_REG_STATUS))
> -                       & 0xff;
> -               if (status == wanted)
> -                       return status;
> -       }
> -       return -status;
> -}
> -
> -static int mv64x60_i2c_control(int control, int status)
> -{
> -       out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_CONTROL), control &
> 0xff);
> -       return mv64x60_i2c_wait_for_status(status);
> -}
> -
> -static int mv64x60_i2c_read_byte(int control, int status)
> -{
> -       out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_CONTROL), control &
> 0xff);
> -       if (mv64x60_i2c_wait_for_status(status) < 0)
> -               return -1;
> -       return in_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_DATA)) & 0xff;
> -}
> -
> -static int mv64x60_i2c_write_byte(int data, int control, int status)
> -{
> -       out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_DATA), data & 0xff);
> -       out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_CONTROL), control &
> 0xff);
> -       return mv64x60_i2c_wait_for_status(status);
> -}
> -
> -int mv64x60_i2c_read(u32 devaddr, u8 *buf, u32 offset, u32 offset_size,
> -                u32 count)
> -{
> -       int i;
> -       int data;
> -       int control;
> -       int status;
> -
> -       if (ctlr_base == NULL)
> -               return -1;
> -
> -       /* send reset */
> -       out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_SOFT_RESET), 0);
> -       out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_SLAVE_ADDR), 0);
> -       out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_EXT_SLAVE_ADDR), 0);
> -       out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_BAUD), (4 << 3) |
> 0x4);
> -
> -       if (mv64x60_i2c_control(MV64x60_I2C_CONTROL_TWSIEN,
> -                               MV64x60_I2C_STATUS_NO_STATUS) < 0)
> -               return -1;
> -
> -       /* send start */
> -       control = MV64x60_I2C_CONTROL_START | MV64x60_I2C_CONTROL_TWSIEN;
> -       status = MV64x60_I2C_STATUS_MAST_START;
> -       if (mv64x60_i2c_control(control, status) < 0)
> -               return -1;
> -
> -       /* select device for writing */
> -       data = devaddr & ~0x1;
> -       control = MV64x60_I2C_CONTROL_TWSIEN;
> -       status = MV64x60_I2C_STATUS_MAST_WR_ADDR_ACK;
> -       if (mv64x60_i2c_write_byte(data, control, status) < 0)
> -               return -1;
> -
> -       /* send offset of data */
> -       control = MV64x60_I2C_CONTROL_TWSIEN;
> -       status = MV64x60_I2C_STATUS_MAST_WR_ACK;
> -       if (offset_size > 1) {
> -               if (mv64x60_i2c_write_byte(offset >> 8, control, status) <
> 0)
> -                       return -1;
> -       }
> -       if (mv64x60_i2c_write_byte(offset, control, status) < 0)
> -               return -1;
> -
> -       /* resend start */
> -       control = MV64x60_I2C_CONTROL_START | MV64x60_I2C_CONTROL_TWSIEN;
> -       status = MV64x60_I2C_STATUS_MAST_REPEAT_START;
> -       if (mv64x60_i2c_control(control, status) < 0)
> -               return -1;
> -
> -       /* select device for reading */
> -       data = devaddr | 0x1;
> -       control = MV64x60_I2C_CONTROL_TWSIEN;
> -       status = MV64x60_I2C_STATUS_MAST_RD_ADDR_ACK;
> -       if (mv64x60_i2c_write_byte(data, control, status) < 0)
> -               return -1;
> -
> -       /* read all but last byte of data */
> -       control = MV64x60_I2C_CONTROL_ACK | MV64x60_I2C_CONTROL_TWSIEN;
> -       status = MV64x60_I2C_STATUS_MAST_RD_DATA_ACK;
> -
> -       for (i=1; i<count; i++) {
> -               data = mv64x60_i2c_read_byte(control, status);
> -               if (data < 0) {
> -                       printf("errors on iteration %d\n", i);
> -                       return -1;
> -               }
> -               *buf++ = data;
> -       }
> -
> -       /* read last byte of data */
> -       control = MV64x60_I2C_CONTROL_TWSIEN;
> -       status = MV64x60_I2C_STATUS_MAST_RD_DATA_NO_ACK;
> -       data = mv64x60_i2c_read_byte(control, status);
> -       if (data < 0)
> -               return -1;
> -       *buf++ = data;
> -
> -       /* send stop */
> -       control = MV64x60_I2C_CONTROL_STOP | MV64x60_I2C_CONTROL_TWSIEN;
> -       status = MV64x60_I2C_STATUS_NO_STATUS;
> -       if (mv64x60_i2c_control(control, status) < 0)
> -               return -1;
> -
> -       return count;
> -}
> -
> -int mv64x60_i2c_open(void)
> -{
> -       u32 v;
> -       void *devp;
> -
> -       devp = find_node_by_compatible(NULL, "marvell,mv64360-i2c");
> -       if (devp == NULL)
> -               goto err_out;
> -       if (getprop(devp, "virtual-reg", &v, sizeof(v)) != sizeof(v))
> -               goto err_out;
> -
> -       ctlr_base = (u8 *)v;
> -       return 0;
> -
> -err_out:
> -       return -1;
> -}
> -
> -void mv64x60_i2c_close(void)
> -{
> -       ctlr_base = NULL;
> -}
> --
> 2.16.2
>
>

[-- Attachment #2: Type: text/html, Size: 11516 bytes --]

^ permalink raw reply

* RE: [PATCH 1/5] powerpc/embedded6xx: Remove C2K board support
From: remi @ 2018-04-06 16:23 UTC (permalink / raw)
  To: 'Mark Greer', 'Benjamin Herrenschmidt',
	'Paul Mackerras', 'Michael Ellerman'
  Cc: 'Dale Farnsworth', linuxppc-dev, linux-kernel
In-Reply-To: <20180406011720.7728-2-mgreer@animalcreek.com>

Acked-by: Remi Machet <remi@machet.us>

-----Original Message-----
From: Mark Greer <mgreer@animalcreek.com> 
Sent: Thursday, April 5, 2018 9:17 PM
To: Benjamin Herrenschmidt <benh@kernel.crashing.org>; Paul Mackerras
<paulus@samba.org>; Michael Ellerman <mpe@ellerman.id.au>
Cc: Remi Machet <rmachet@nvidia.com>; Dale Farnsworth <dale@farnsworth.org>;
linuxppc-dev@lists.ozlabs.org; linux-kernel@vger.kernel.org; Mark Greer
<mgreer@animalcreek.com>
Subject: [PATCH 1/5] powerpc/embedded6xx: Remove C2K board support

The C2K platform appears to be orphaned so remove code supporting it.

CC: Remi Machet <rmachet@nvidia.com>
Signed-off-by: Mark Greer <mgreer@animalcreek.com>
---
 arch/powerpc/boot/Makefile                  |   5 +-
 arch/powerpc/boot/cuboot-c2k.c              | 189 --------------
 arch/powerpc/boot/dts/c2k.dts               | 366
--------------------------
 arch/powerpc/configs/c2k_defconfig          | 390
----------------------------
 arch/powerpc/platforms/embedded6xx/Kconfig  |  10 -
 arch/powerpc/platforms/embedded6xx/Makefile |   1 -
 arch/powerpc/platforms/embedded6xx/c2k.c    | 148 -----------
 7 files changed, 2 insertions(+), 1107 deletions(-)  delete mode 100644
arch/powerpc/boot/cuboot-c2k.c  delete mode 100644
arch/powerpc/boot/dts/c2k.dts  delete mode 100644
arch/powerpc/configs/c2k_defconfig
 delete mode 100644 arch/powerpc/platforms/embedded6xx/c2k.c

diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index
26d5d2a5b8e9..70bf9b409fae 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -143,8 +143,8 @@ src-plat-$(CONFIG_PPC_82xx) += cuboot-pq2.c fixed-head.S
ep8248e.c cuboot-824x.c
 src-plat-$(CONFIG_PPC_83xx) += cuboot-83xx.c fixed-head.S redboot-83xx.c
 src-plat-$(CONFIG_FSL_SOC_BOOKE) += cuboot-85xx.c cuboot-85xx-cpm2.c
 src-plat-$(CONFIG_EMBEDDED6xx) += cuboot-pq2.c cuboot-mpc7448hpc2.c \
-					cuboot-c2k.c gamecube-head.S \
-					gamecube.c wii-head.S wii.c holly.c
\
+					gamecube-head.S gamecube.c \
+					wii-head.S wii.c holly.c \
 					fixed-head.S mvme5100.c
 src-plat-$(CONFIG_AMIGAONE) += cuboot-amigaone.c
 src-plat-$(CONFIG_PPC_PS3) += ps3-head.S ps3-hvcall.S ps3.c
@@ -339,7 +339,6 @@ image-$(CONFIG_MVME7100)                +=
dtbImage.mvme7100
 # Board ports in arch/powerpc/platform/embedded6xx/Kconfig
 image-$(CONFIG_STORCENTER)		+= cuImage.storcenter
 image-$(CONFIG_MPC7448HPC2)		+= cuImage.mpc7448hpc2
-image-$(CONFIG_PPC_C2K)			+= cuImage.c2k
 image-$(CONFIG_GAMECUBE)		+= dtbImage.gamecube
 image-$(CONFIG_WII)			+= dtbImage.wii
 image-$(CONFIG_MVME5100)		+= dtbImage.mvme5100
diff --git a/arch/powerpc/boot/cuboot-c2k.c b/arch/powerpc/boot/cuboot-c2k.c
deleted file mode 100644 index 9309c51f1d65..000000000000
--- a/arch/powerpc/boot/cuboot-c2k.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * GEFanuc C2K platform code.
- *
- * Author: Remi Machet <rmachet@slac.stanford.edu>
- *
- * Originated from prpmc2800.c
- *
- * 2008 (c) Stanford University
- * 2007 (c) MontaVista, Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#include "types.h"
-#include "stdio.h"
-#include "io.h"
-#include "ops.h"
-#include "elf.h"
-#include "mv64x60.h"
-#include "cuboot.h"
-#include "ppcboot.h"
-
-static u8 *bridge_base;
-
-static void c2k_bridge_setup(u32 mem_size) -{
-	u32 i, v[30], enables, acc_bits;
-	u32 pci_base_hi, pci_base_lo, size, buf[2];
-	unsigned long cpu_base;
-	int rc;
-	void *devp, *mv64x60_devp;
-	u8 *bridge_pbase, is_coherent;
-	struct mv64x60_cpu2pci_win *tbl;
-	int bus;
-
-	bridge_pbase = mv64x60_get_bridge_pbase();
-	is_coherent = mv64x60_is_coherent();
-
-	if (is_coherent)
-		acc_bits = MV64x60_PCI_ACC_CNTL_SNOOP_WB
-			| MV64x60_PCI_ACC_CNTL_SWAP_NONE
-			| MV64x60_PCI_ACC_CNTL_MBURST_32_BYTES
-			| MV64x60_PCI_ACC_CNTL_RDSIZE_32_BYTES;
-	else
-		acc_bits = MV64x60_PCI_ACC_CNTL_SNOOP_NONE
-			| MV64x60_PCI_ACC_CNTL_SWAP_NONE
-			| MV64x60_PCI_ACC_CNTL_MBURST_128_BYTES
-			| MV64x60_PCI_ACC_CNTL_RDSIZE_256_BYTES;
-
-	mv64x60_config_ctlr_windows(bridge_base, bridge_pbase, is_coherent);
-	mv64x60_devp = find_node_by_compatible(NULL, "marvell,mv64360");
-	if (mv64x60_devp == NULL)
-		fatal("Error: Missing marvell,mv64360 device tree
node\n\r");
-
-	enables = in_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE));
-	enables |= 0x007ffe00; /* Disable all cpu->pci windows */
-	out_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE), enables);
-
-	/* Get the cpu -> pci i/o & mem mappings from the device tree */
-	devp = NULL;
-	for (bus = 0; ; bus++) {
-		char name[] = "pci ";
-
-		name[strlen(name)-1] = bus+'0';
-
-		devp = find_node_by_alias(name);
-		if (devp == NULL)
-			break;
-
-		if (bus >= 2)
-			fatal("Error: Only 2 PCI controllers are supported
at" \
-				" this time.\n");
-
-		mv64x60_config_pci_windows(bridge_base, bridge_pbase, bus,
0,
-				mem_size, acc_bits);
-
-		rc = getprop(devp, "ranges", v, sizeof(v));
-		if (rc == 0)
-			fatal("Error: Can't find marvell,mv64360-pci ranges"
-				" property\n\r");
-
-		/* Get the cpu -> pci i/o & mem mappings from the device
tree */
-
-		for (i = 0; i < rc; i += 6) {
-			switch (v[i] & 0xff000000) {
-			case 0x01000000: /* PCI I/O Space */
-				tbl = mv64x60_cpu2pci_io;
-				break;
-			case 0x02000000: /* PCI MEM Space */
-				tbl = mv64x60_cpu2pci_mem;
-				break;
-			default:
-				continue;
-			}
-
-			pci_base_hi = v[i+1];
-			pci_base_lo = v[i+2];
-			cpu_base = v[i+3];
-			size = v[i+5];
-
-			buf[0] = cpu_base;
-			buf[1] = size;
-
-			if (!dt_xlate_addr(devp, buf, sizeof(buf),
&cpu_base))
-				fatal("Error: Can't translate PCI address "
\
-						"0x%x\n\r", (u32)cpu_base);
-
-			mv64x60_config_cpu2pci_window(bridge_base, bus,
-				pci_base_hi, pci_base_lo, cpu_base, size,
tbl);
-		}
-
-		enables &= ~(3<<(9+bus*5)); /* Enable cpu->pci<bus> i/o,
-						cpu->pci<bus> mem0 */
-		out_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE),
-			enables);
-	};
-}
-
-static void c2k_fixups(void)
-{
-	u32 mem_size;
-
-	mem_size = mv64x60_get_mem_size(bridge_base);
-	c2k_bridge_setup(mem_size); /* Do necessary bridge setup */
-}
-
-#define MV64x60_MPP_CNTL_0	0xf000
-#define MV64x60_MPP_CNTL_2	0xf008
-#define MV64x60_GPP_IO_CNTL	0xf100
-#define MV64x60_GPP_LEVEL_CNTL	0xf110
-#define MV64x60_GPP_VALUE_SET	0xf118
-
-static void c2k_reset(void)
-{
-	u32 temp;
-
-	udelay(5000000);
-
-	if (bridge_base != 0) {
-		temp = in_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_0));
-		temp &= 0xFFFF0FFF;
-		out_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_0), temp);
-
-		temp = in_le32((u32 *)(bridge_base +
MV64x60_GPP_LEVEL_CNTL));
-		temp |= 0x00000004;
-		out_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL),
temp);
-
-		temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL));
-		temp |= 0x00000004;
-		out_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL), temp);
-
-		temp = in_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_2));
-		temp &= 0xFFFF0FFF;
-		out_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_2), temp);
-
-		temp = in_le32((u32 *)(bridge_base +
MV64x60_GPP_LEVEL_CNTL));
-		temp |= 0x00080000;
-		out_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL),
temp);
-
-		temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL));
-		temp |= 0x00080000;
-		out_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL), temp);
-
-		out_le32((u32 *)(bridge_base + MV64x60_GPP_VALUE_SET),
-				0x00080004);
-	}
-
-	for (;;);
-}
-
-static bd_t bd;
-
-void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
-			unsigned long r6, unsigned long r7)
-{
-	CUBOOT_INIT();
-
-	fdt_init(_dtb_start);
-
-	bridge_base = mv64x60_get_bridge_base();
-
-	platform_ops.fixups = c2k_fixups;
-	platform_ops.exit = c2k_reset;
-
-	if (serial_console_init() < 0)
-		exit();
-}
diff --git a/arch/powerpc/boot/dts/c2k.dts b/arch/powerpc/boot/dts/c2k.dts
deleted file mode 100644 index c5beb72d18b7..000000000000
--- a/arch/powerpc/boot/dts/c2k.dts
+++ /dev/null
@@ -1,366 +0,0 @@
-/* Device Tree Source for GEFanuc C2K
- *
- * Author: Remi Machet <rmachet@slac.stanford.edu>
- *
- * Originated from prpmc2800.dts
- *
- * 2008 (c) Stanford University
- * 2007 (c) MontaVista, Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-/dts-v1/;
-
-/ {
-	#address-cells = <1>;
-	#size-cells = <1>;
-	model = "C2K";
-	compatible = "GEFanuc,C2K";
-	coherency-off;
-
-	aliases {
-		pci0 = &PCI0;
-		pci1 = &PCI1;
-	};
-
-	cpus {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		cpu@0 {
-			device_type = "cpu";
-			compatible = "PowerPC,7447";
-			reg = <0>;
-			clock-frequency = <996000000>;	/* 996 MHz */
-			bus-frequency = <166666667>;	/* 166.6666 MHz */
-			timebase-frequency = <41666667>;	/*
166.6666/4 MHz */
-			i-cache-line-size = <32>;
-			d-cache-line-size = <32>;
-			i-cache-size = <32768>;
-			d-cache-size = <32768>;
-		};
-	};
-
-	memory {
-		device_type = "memory";
-		reg = <0x00000000 0x40000000>;	/* 1GB */
-	};
-
-	system-controller@d8000000 { /* Marvell Discovery */
-		#address-cells = <1>;
-		#size-cells = <1>;
-		model = "mv64460";
-		compatible = "marvell,mv64360";
-		clock-frequency = <166666667>;		/* 166.66... MHz */
-		reg = <0xd8000000 0x00010000>;
-		virtual-reg = <0xd8000000>;
-		ranges = <0xd4000000 0xd4000000 0x01000000	/* PCI 0 I/O
Space */
-			  0x80000000 0x80000000 0x08000000	/* PCI 0 MEM
Space */
-			  0xd0000000 0xd0000000 0x01000000	/* PCI 1 I/O
Space */
-			  0xa0000000 0xa0000000 0x08000000	/* PCI 1 MEM
Space */
-			  0xd8100000 0xd8100000 0x00010000	/* FPGA */
-			  0xd8110000 0xd8110000 0x00010000	/* FPGA
USARTs */
-			  0xf8000000 0xf8000000 0x08000000	/* User
FLASH */
-			  0x00000000 0xd8000000 0x00010000	/* Bridge's
regs */
-			  0xd8140000 0xd8140000 0x00040000>;	/*
Integrated SRAM */
-
-		mdio@2000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "marvell,mv64360-mdio";
-			reg = <0x2000 4>;
-			PHY0: ethernet-phy@0 {
-				interrupts = <76>;	/* GPP 12 */
-				interrupt-parent = <&PIC>;
-				reg = <0>;
-			};
-			PHY1: ethernet-phy@1 {
-				interrupts = <76>;	/* GPP 12 */
-				interrupt-parent = <&PIC>;
-				reg = <1>;
-			};
-			PHY2: ethernet-phy@2 {
-				interrupts = <76>;	/* GPP 12 */
-				interrupt-parent = <&PIC>;
-				reg = <2>;
-			};
-		};
-
-		ethernet-group@2000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "marvell,mv64360-eth-group";
-			reg = <0x2000 0x2000>;
-			ethernet@0 {
-				device_type = "network";
-				compatible = "marvell,mv64360-eth";
-				reg = <0>;
-				interrupts = <32>;
-				interrupt-parent = <&PIC>;
-				phy = <&PHY0>;
-				local-mac-address = [ 00 00 00 00 00 00 ];
-			};
-			ethernet@1 {
-				device_type = "network";
-				compatible = "marvell,mv64360-eth";
-				reg = <1>;
-				interrupts = <33>;
-				interrupt-parent = <&PIC>;
-				phy = <&PHY1>;
-				local-mac-address = [ 00 00 00 00 00 00 ];
-			};
-			ethernet@2 {
-				device_type = "network";
-				compatible = "marvell,mv64360-eth";
-				reg = <2>;
-				interrupts = <34>;
-				interrupt-parent = <&PIC>;
-				phy = <&PHY2>;
-				local-mac-address = [ 00 00 00 00 00 00 ];
-			};
-		};
-
-		SDMA0: sdma@4000 {
-			compatible = "marvell,mv64360-sdma";
-			reg = <0x4000 0xc18>;
-			virtual-reg = <0xd8004000>;
-			interrupt-base = <0>;
-			interrupts = <36>;
-			interrupt-parent = <&PIC>;
-		};
-
-		SDMA1: sdma@6000 {
-			compatible = "marvell,mv64360-sdma";
-			reg = <0x6000 0xc18>;
-			virtual-reg = <0xd8006000>;
-			interrupt-base = <0>;
-			interrupts = <38>;
-			interrupt-parent = <&PIC>;
-		};
-
-		BRG0: brg@b200 {
-			compatible = "marvell,mv64360-brg";
-			reg = <0xb200 0x8>;
-			clock-src = <8>;
-			clock-frequency = <133333333>;
-			current-speed = <115200>;
-		};
-
-		BRG1: brg@b208 {
-			compatible = "marvell,mv64360-brg";
-			reg = <0xb208 0x8>;
-			clock-src = <8>;
-			clock-frequency = <133333333>;
-			current-speed = <115200>;
-		};
-
-		CUNIT: cunit@f200 {
-			reg = <0xf200 0x200>;
-		};
-
-		MPSCROUTING: mpscrouting@b400 {
-			reg = <0xb400 0xc>;
-		};
-
-		MPSCINTR: mpscintr@b800 {
-			reg = <0xb800 0x100>;
-			virtual-reg = <0xd800b800>;
-		};
-
-		MPSC0: mpsc@8000 {
-			compatible = "marvell,mv64360-mpsc";
-			reg = <0x8000 0x38>;
-			virtual-reg = <0xd8008000>;
-			sdma = <&SDMA0>;
-			brg = <&BRG0>;
-			cunit = <&CUNIT>;
-			mpscrouting = <&MPSCROUTING>;
-			mpscintr = <&MPSCINTR>;
-			cell-index = <0>;
-			interrupts = <40>;
-			interrupt-parent = <&PIC>;
-		};
-
-		MPSC1: mpsc@9000 {
-			compatible = "marvell,mv64360-mpsc";
-			reg = <0x9000 0x38>;
-			virtual-reg = <0xd8009000>;
-			sdma = <&SDMA1>;
-			brg = <&BRG1>;
-			cunit = <&CUNIT>;
-			mpscrouting = <&MPSCROUTING>;
-			mpscintr = <&MPSCINTR>;
-			cell-index = <1>;
-			interrupts = <42>;
-			interrupt-parent = <&PIC>;
-		};
-
-		wdt@b410 {			/* watchdog timer */
-			compatible = "marvell,mv64360-wdt";
-			reg = <0xb410 0x8>;
-		};
-
-		i2c@c000 {
-			compatible = "marvell,mv64360-i2c";
-			reg = <0xc000 0x20>;
-			virtual-reg = <0xd800c000>;
-			interrupts = <37>;
-			interrupt-parent = <&PIC>;
-		};
-
-		PIC: pic {
-			#interrupt-cells = <1>;
-			#address-cells = <0>;
-			compatible = "marvell,mv64360-pic";
-			reg = <0x0000 0x88>;
-			interrupt-controller;
-		};
-
-		mpp@f000 {
-			compatible = "marvell,mv64360-mpp";
-			reg = <0xf000 0x10>;
-		};
-
-		gpp@f100 {
-			compatible = "marvell,mv64360-gpp";
-			reg = <0xf100 0x20>;
-		};
-
-		PCI0: pci@80000000 {
-			#address-cells = <3>;
-			#size-cells = <2>;
-			#interrupt-cells = <1>;
-			device_type = "pci";
-			compatible = "marvell,mv64360-pci";
-			reg = <0x0cf8 0x8>;
-			ranges = <0x01000000 0x0 0x00000000 0xd4000000 0x0
0x01000000
-				  0x02000000 0x0 0x80000000 0x80000000 0x0
0x08000000>;
-			bus-range = <0 255>;
-			clock-frequency = <66000000>;
-			interrupt-pci-iack = <0x0c34>;
-			interrupt-parent = <&PIC>;
-			interrupt-map-mask = <0x0000 0x0 0x0 0x7>;
-			interrupt-map = <
-				/* Only one interrupt line for PMC0 slot
(INTA) */
-				0x0000 0 0 1 &PIC 88
-			>;
-		};
-
-
-		PCI1: pci@a0000000 {
-			#address-cells = <3>;
-			#size-cells = <2>;
-			#interrupt-cells = <1>;
-			device_type = "pci";
-			compatible = "marvell,mv64360-pci";
-			reg = <0x0c78 0x8>;
-			ranges = <0x01000000 0x0 0x00000000 0xd0000000 0x0
0x01000000
-				  0x02000000 0x0 0x80000000 0xa0000000 0x0
0x08000000>;
-			bus-range = <0 255>;
-			clock-frequency = <66000000>;
-			interrupt-pci-iack = <0x0cb4>;
-			interrupt-parent = <&PIC>;
-			interrupt-map-mask = <0xf800 0x00 0x00 0x7>;
-			interrupt-map = <
-				/* IDSEL 0x01: PMC1 ? */
-				0x0800 0 0 1 &PIC 88
-				/* IDSEL 0x02: cPCI bridge */
-				0x1000 0 0 1 &PIC 88
-				/* IDSEL 0x03: USB controller */
-				0x1800 0 0 1 &PIC 91
-				/* IDSEL 0x04: SATA controller */
-				0x2000 0 0 1 &PIC 95
-			>;
-		};
-
-		cpu-error@70 {
-			compatible = "marvell,mv64360-cpu-error";
-			reg = <0x0070 0x10 0x0128 0x28>;
-			interrupts = <3>;
-			interrupt-parent = <&PIC>;
-		};
-
-		sram-ctrl@380 {
-			compatible = "marvell,mv64360-sram-ctrl";
-			reg = <0x0380 0x80>;
-			interrupts = <13>;
-			interrupt-parent = <&PIC>;
-		};
-
-		pci-error@1d40 {
-			compatible = "marvell,mv64360-pci-error";
-			reg = <0x1d40 0x40 0x0c28 0x4>;
-			interrupts = <12>;
-			interrupt-parent = <&PIC>;
-		};
-
-		pci-error@1dc0 {
-			compatible = "marvell,mv64360-pci-error";
-			reg = <0x1dc0 0x40 0x0ca8 0x4>;
-			interrupts = <16>;
-			interrupt-parent = <&PIC>;
-		};
-
-		mem-ctrl@1400 {
-			compatible = "marvell,mv64360-mem-ctrl";
-			reg = <0x1400 0x60>;
-			interrupts = <17>;
-			interrupt-parent = <&PIC>;
-		};
-		/* Devices attached to the device controller */
-		devicebus@45c {
-			#address-cells = <2>;
-			#size-cells = <1>;
-			compatible = "marvell,mv64306-devctrl";
-			reg = <0x45C 0x88>;
-			interrupts = <1>;
-			interrupt-parent = <&PIC>;
-			ranges = 	<0 0 0xd8100000 0x10000
-					 2 0 0xd8110000 0x10000
-					 4 0 0xf8000000 0x8000000>;
-			fpga@0,0 {
-				compatible = "sbs,fpga-c2k";
-				reg = <0 0 0x10000>;
-			};
-			fpga_usart@2,0 {
-				compatible = "sbs,fpga_usart-c2k";
-				reg = <2 0 0x10000>;
-			};
-			nor_flash@4,0 {
-				compatible = "cfi-flash";
-				reg = <4 0 0x8000000>; /* 128MB */
-				bank-width = <4>;
-				device-width = <1>;
-				#address-cells = <1>;
-				#size-cells = <1>;
-				partition@0 {
-					label = "boot";
-					reg = <0x00000000 0x00080000>;
-				};
-				partition@40000 {
-					label = "kernel";
-					reg = <0x00080000 0x00400000>;
-				};
-				partition@440000 {
-					label = "initrd";
-					reg = <0x00480000 0x00B80000>;
-				};
-				partition@1000000 {
-					label = "rootfs";
-					reg = <0x01000000 0x06800000>;
-				};
-				partition@7800000 {
-					label = "recovery";
-					reg = <0x07800000 0x00800000>;
-					read-only;
-				};
-			};
-		};
-	};
-	chosen {
-		stdout-path = &MPSC0;
-	};
-};
diff --git a/arch/powerpc/configs/c2k_defconfig
b/arch/powerpc/configs/c2k_defconfig
deleted file mode 100644
index 4bb832a41d55..000000000000
--- a/arch/powerpc/configs/c2k_defconfig
+++ /dev/null
@@ -1,390 +0,0 @@
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_AUDIT=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
-CONFIG_KPROBES=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_OSF_PARTITION=y
-CONFIG_MAC_PARTITION=y
-CONFIG_BSD_DISKLABEL=y
-CONFIG_MINIX_SUBPARTITION=y
-CONFIG_SOLARIS_X86_PARTITION=y
-CONFIG_UNIXWARE_DISKLABEL=y
-CONFIG_SGI_PARTITION=y
-CONFIG_SUN_PARTITION=y
-# CONFIG_PPC_CHRP is not set
-# CONFIG_PPC_PMAC is not set
-CONFIG_EMBEDDED6xx=y
-CONFIG_PPC_C2K=y
-CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
-CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
-CONFIG_CPU_FREQ_GOV_POWERSAVE=m
-CONFIG_CPU_FREQ_GOV_ONDEMAND=m
-CONFIG_GEN_RTC=y
-CONFIG_HIGHMEM=y
-CONFIG_PREEMPT_VOLUNTARY=y
-CONFIG_BINFMT_MISC=y
-CONFIG_PM=y
-CONFIG_PCI_MSI=y
-CONFIG_HOTPLUG_PCI=y
-CONFIG_HOTPLUG_PCI_SHPC=m
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_XFRM_USER=y
-CONFIG_NET_KEY=m
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_VERBOSE=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_NET_IPIP=m
-CONFIG_IP_MROUTE=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-CONFIG_SYN_COOKIES=y
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_IPV6_TUNNEL=m
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_XT_MATCH_SCTP is not set -CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_IP6_NF_IPTABLES=m -CONFIG_IP6_NF_MATCH_EUI64=m
-CONFIG_IP6_NF_MATCH_FRAG=m -CONFIG_IP6_NF_MATCH_OPTS=m
-CONFIG_IP6_NF_MATCH_HL=m -CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_MATCH_RT=m -CONFIG_IP6_NF_FILTER=m -CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_RAW=m -CONFIG_BRIDGE_NF_EBTABLES=m
-CONFIG_BRIDGE_EBT_BROUTE=m -CONFIG_BRIDGE_EBT_T_FILTER=m
-CONFIG_BRIDGE_EBT_T_NAT=m -CONFIG_BRIDGE_EBT_802_3=m
-CONFIG_BRIDGE_EBT_AMONG=m -CONFIG_BRIDGE_EBT_ARP=m -CONFIG_BRIDGE_EBT_IP=m
-CONFIG_BRIDGE_EBT_LIMIT=m -CONFIG_BRIDGE_EBT_MARK=m
-CONFIG_BRIDGE_EBT_PKTTYPE=m -CONFIG_BRIDGE_EBT_STP=m
-CONFIG_BRIDGE_EBT_VLAN=m -CONFIG_BRIDGE_EBT_ARPREPLY=m
-CONFIG_BRIDGE_EBT_DNAT=m -CONFIG_BRIDGE_EBT_MARK_T=m
-CONFIG_BRIDGE_EBT_REDIRECT=m -CONFIG_BRIDGE_EBT_SNAT=m
-CONFIG_BRIDGE_EBT_LOG=m -CONFIG_IP_SCTP=m -CONFIG_ATM=m -CONFIG_ATM_CLIP=m
-CONFIG_ATM_LANE=m -CONFIG_ATM_BR2684=m -CONFIG_BRIDGE=m
-CONFIG_VLAN_8021Q=m -CONFIG_NET_SCHED=y -CONFIG_NET_SCH_CBQ=m
-CONFIG_NET_SCH_HTB=m -CONFIG_NET_SCH_HFSC=m -CONFIG_NET_SCH_ATM=m
-CONFIG_NET_SCH_PRIO=m -CONFIG_NET_SCH_RED=m -CONFIG_NET_SCH_SFQ=m
-CONFIG_NET_SCH_TEQL=m -CONFIG_NET_SCH_TBF=m -CONFIG_NET_SCH_GRED=m
-CONFIG_NET_SCH_DSMARK=m -CONFIG_NET_SCH_NETEM=m -CONFIG_NET_CLS_TCINDEX=m
-CONFIG_NET_CLS_ROUTE4=m -CONFIG_NET_CLS_FW=m -CONFIG_NET_CLS_U32=m
-CONFIG_CLS_U32_PERF=y -CONFIG_NET_CLS_RSVP=m -CONFIG_NET_CLS_RSVP6=m
-CONFIG_NET_CLS_IND=y -CONFIG_BT=m -CONFIG_BT_RFCOMM=m
-CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=m -CONFIG_BT_BNEP_MC_FILTER=y
-CONFIG_BT_BNEP_PROTO_FILTER=y -CONFIG_BT_HIDP=m -CONFIG_BT_HCIUART=m
-CONFIG_BT_HCIUART_H4=y -CONFIG_BT_HCIUART_BCSP=y -CONFIG_BT_HCIBCM203X=m
-CONFIG_BT_HCIBFUSB=m -CONFIG_BT_HCIVHCI=m
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_COMPLEX_MAPPINGS=y
-CONFIG_MTD_PHYSMAP_OF=y
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_SCSI=m
-CONFIG_BLK_DEV_SD=m
-CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
-CONFIG_BLK_DEV_SR=m
-CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=m
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-CONFIG_SCSI_ISCSI_ATTRS=m
-CONFIG_BLK_DEV_3W_XXXX_RAID=m
-CONFIG_SCSI_3W_9XXX=m
-CONFIG_SCSI_ACARD=m
-CONFIG_SCSI_AACRAID=m
-CONFIG_SCSI_AIC7XXX=m
-CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
-CONFIG_AIC7XXX_RESET_DELAY_MS=15000
-# CONFIG_AIC7XXX_DEBUG_ENABLE is not set -# CONFIG_AIC7XXX_REG_PRETTY_PRINT
is not set -CONFIG_SCSI_AIC79XX=m
-CONFIG_AIC79XX_CMDS_PER_DEVICE=4
-CONFIG_AIC79XX_RESET_DELAY_MS=15000
-# CONFIG_AIC79XX_DEBUG_ENABLE is not set -# CONFIG_AIC79XX_REG_PRETTY_PRINT
is not set -CONFIG_SCSI_ARCMSR=m -CONFIG_MEGARAID_NEWGEN=y
-CONFIG_MEGARAID_MM=m -CONFIG_MEGARAID_MAILBOX=m -CONFIG_MEGARAID_SAS=m
-CONFIG_SCSI_FUTURE_DOMAIN=m -CONFIG_SCSI_GDTH=m -CONFIG_SCSI_IPS=m
-CONFIG_SCSI_INITIO=m -CONFIG_SCSI_SYM53C8XX_2=m -CONFIG_SCSI_QLOGIC_1280=m
-CONFIG_NETDEVICES=y -CONFIG_BONDING=m -CONFIG_DUMMY=m -CONFIG_NETCONSOLE=m
-CONFIG_TUN=m -# CONFIG_ATM_DRIVERS is not set -CONFIG_MV643XX_ETH=y
-CONFIG_VITESSE_PHY=y -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_KEYBOARD is not
set -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_MISC=y
-CONFIG_INPUT_UINPUT=m -# CONFIG_SERIO is not set -# CONFIG_LEGACY_PTYS is
not set -CONFIG_SERIAL_NONSTANDARD=y -CONFIG_SERIAL_MPSC=y
-CONFIG_SERIAL_MPSC_CONSOLE=y -CONFIG_NVRAM=m -CONFIG_RAW_DRIVER=y
-CONFIG_MAX_RAW_DEVS=8192
-CONFIG_I2C=m
-CONFIG_I2C_CHARDEV=m
-CONFIG_I2C_MV64XXX=m
-CONFIG_HWMON=m
-CONFIG_SENSORS_ADM1021=m
-CONFIG_SENSORS_ADM1025=m
-CONFIG_SENSORS_ADM1026=m
-CONFIG_SENSORS_ADM1031=m
-CONFIG_SENSORS_DS1621=m
-CONFIG_SENSORS_GL518SM=m
-CONFIG_SENSORS_MAX1619=m
-CONFIG_SENSORS_LM75=m
-CONFIG_SENSORS_LM77=m
-CONFIG_SENSORS_LM78=m
-CONFIG_SENSORS_LM80=m
-CONFIG_SENSORS_LM83=m
-CONFIG_SENSORS_LM85=m
-CONFIG_SENSORS_LM87=m
-CONFIG_SENSORS_LM90=m
-CONFIG_SENSORS_PCF8591=m
-CONFIG_SENSORS_VIA686A=m
-CONFIG_SENSORS_W83781D=m
-CONFIG_SENSORS_W83L785TS=m
-CONFIG_WATCHDOG=y
-CONFIG_SOFT_WATCHDOG=m
-CONFIG_PCIPCWATCHDOG=m
-CONFIG_WDTPCI=m
-CONFIG_USBPCWATCHDOG=m
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_USB=m
-CONFIG_USB_MON=m
-CONFIG_USB_EHCI_HCD=m
-CONFIG_USB_EHCI_ROOT_HUB_TT=y
-CONFIG_USB_OHCI_HCD=m
-CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
-CONFIG_USB_UHCI_HCD=m
-CONFIG_USB_ACM=m
-CONFIG_USB_PRINTER=m
-CONFIG_USB_STORAGE=m
-CONFIG_USB_STORAGE_DATAFAB=m
-CONFIG_USB_STORAGE_FREECOM=m
-CONFIG_USB_STORAGE_ISD200=m
-CONFIG_USB_STORAGE_SDDR09=m
-CONFIG_USB_STORAGE_SDDR55=m
-CONFIG_USB_STORAGE_JUMPSHOT=m
-CONFIG_USB_MDC800=m
-CONFIG_USB_MICROTEK=m
-CONFIG_USB_SERIAL=m
-CONFIG_USB_SERIAL_GENERIC=y
-CONFIG_USB_SERIAL_BELKIN=m
-CONFIG_USB_SERIAL_WHITEHEAT=m
-CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
-CONFIG_USB_SERIAL_EMPEG=m
-CONFIG_USB_SERIAL_FTDI_SIO=m
-CONFIG_USB_SERIAL_VISOR=m
-CONFIG_USB_SERIAL_IPAQ=m
-CONFIG_USB_SERIAL_IR=m
-CONFIG_USB_SERIAL_EDGEPORT=m
-CONFIG_USB_SERIAL_EDGEPORT_TI=m
-CONFIG_USB_SERIAL_KEYSPAN_PDA=m
-CONFIG_USB_SERIAL_KEYSPAN=m
-CONFIG_USB_SERIAL_KLSI=m
-CONFIG_USB_SERIAL_KOBIL_SCT=m
-CONFIG_USB_SERIAL_MCT_U232=m
-CONFIG_USB_SERIAL_PL2303=m
-CONFIG_USB_SERIAL_SAFE=m
-CONFIG_USB_SERIAL_SAFE_PADDED=y
-CONFIG_USB_SERIAL_CYBERJACK=m
-CONFIG_USB_SERIAL_XIRCOM=m
-CONFIG_USB_SERIAL_OMNINET=m
-CONFIG_USB_EMI62=m
-CONFIG_USB_RIO500=m
-CONFIG_USB_LEGOTOWER=m
-CONFIG_USB_LCD=m
-CONFIG_USB_LED=m
-CONFIG_USB_TEST=m
-CONFIG_USB_ATM=m
-CONFIG_USB_SPEEDTOUCH=m
-CONFIG_INFINIBAND=m
-CONFIG_INFINIBAND_USER_MAD=m
-CONFIG_INFINIBAND_USER_ACCESS=m
-CONFIG_INFINIBAND_MTHCA=m
-CONFIG_INFINIBAND_IPOIB=m
-CONFIG_INFINIBAND_IPOIB_CM=y
-CONFIG_INFINIBAND_SRP=m
-CONFIG_DMADEVICES=y
-CONFIG_EXT4_FS=m
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
-CONFIG_QUOTA=y
-CONFIG_QFMT_V2=y
-CONFIG_AUTOFS4_FS=m
-CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_HFS_FS=m
-CONFIG_HFSPLUS_FS=m
-CONFIG_JFFS2_FS=y
-CONFIG_CRAMFS=m
-CONFIG_VXFS_FS=m
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_CIFS=m
-CONFIG_CIFS_XATTR=y
-CONFIG_CIFS_POSIX=y
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="utf8"
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_CODEPAGE_1250=m
-CONFIG_NLS_CODEPAGE_1251=m
-CONFIG_NLS_ASCII=y
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_13=m
-CONFIG_NLS_ISO8859_14=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_KOI8_U=m
-CONFIG_CRC_CCITT=m
-CONFIG_CRC_T10DIF=m
-CONFIG_DEBUG_INFO=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_STACK_USAGE=y
-CONFIG_DEBUG_HIGHMEM=y
-CONFIG_DEBUG_STACKOVERFLOW=y
-CONFIG_DETECT_HUNG_TASK=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_BOOTX_TEXT=y
-CONFIG_PPC_EARLY_DEBUG=y
-CONFIG_SECURITY=y
-CONFIG_SECURITY_NETWORK=y
-CONFIG_SECURITY_SELINUX=y
-CONFIG_SECURITY_SELINUX_BOOTPARAM=y
-CONFIG_SECURITY_SELINUX_DISABLE=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_SHA1=y
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_TWOFISH=m
diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig
b/arch/powerpc/platforms/embedded6xx/Kconfig
index 9fb2d5912c5a..8ea16db5ff48 100644
--- a/arch/powerpc/platforms/embedded6xx/Kconfig
+++ b/arch/powerpc/platforms/embedded6xx/Kconfig
@@ -48,16 +48,6 @@ config PPC_HOLLY
 	  Select PPC_HOLLY if configuring for an IBM 750GX/CL Eval
 	  Board with TSI108/9 bridge (Hickory/Holly)
 
-config PPC_C2K
-	bool "SBS/GEFanuc C2K board"
-	depends on EMBEDDED6xx
-	select MV64X60
-	select NOT_COHERENT_CACHE
-	select MTD_CFI_I4
-	help
-	  This option enables support for the GE Fanuc C2K board (formerly
-	  an SBS board).
-
 config MVME5100
 	bool "Motorola/Emerson MVME5100"
 	depends on EMBEDDED6xx
diff --git a/arch/powerpc/platforms/embedded6xx/Makefile
b/arch/powerpc/platforms/embedded6xx/Makefile
index 12154e3257ad..e656ae9f23c6 100644
--- a/arch/powerpc/platforms/embedded6xx/Makefile
+++ b/arch/powerpc/platforms/embedded6xx/Makefile
@@ -6,7 +6,6 @@ obj-$(CONFIG_MPC7448HPC2)	+= mpc7448_hpc2.o
 obj-$(CONFIG_LINKSTATION)	+= linkstation.o ls_uart.o
 obj-$(CONFIG_STORCENTER)	+= storcenter.o
 obj-$(CONFIG_PPC_HOLLY)		+= holly.o
-obj-$(CONFIG_PPC_C2K)		+= c2k.o
 obj-$(CONFIG_USBGECKO_UDBG)	+= usbgecko_udbg.o
 obj-$(CONFIG_GAMECUBE_COMMON)	+= flipper-pic.o
 obj-$(CONFIG_GAMECUBE)		+= gamecube.o
diff --git a/arch/powerpc/platforms/embedded6xx/c2k.c
b/arch/powerpc/platforms/embedded6xx/c2k.c
deleted file mode 100644
index d19e4e759597..000000000000
--- a/arch/powerpc/platforms/embedded6xx/c2k.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Board setup routines for the GEFanuc C2K board
- *
- * Author: Remi Machet <rmachet@slac.stanford.edu>
- *
- * Originated from prpmc2800.c
- *
- * 2008 (c) Stanford University
- * 2007 (c) MontaVista, Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#include <linux/stddef.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/seq_file.h>
-#include <linux/time.h>
-#include <linux/of.h>
-
-#include <asm/machdep.h>
-#include <asm/prom.h>
-#include <asm/time.h>
-
-#include <mm/mmu_decl.h>
-
-#include <sysdev/mv64x60.h>
-
-#define MV64x60_MPP_CNTL_0	0x0000
-#define MV64x60_MPP_CNTL_2	0x0008
-
-#define MV64x60_GPP_IO_CNTL	0x0000
-#define MV64x60_GPP_LEVEL_CNTL	0x0010
-#define MV64x60_GPP_VALUE_SET	0x0018
-
-static void __iomem *mv64x60_mpp_reg_base; -static void __iomem
*mv64x60_gpp_reg_base;
-
-static void __init c2k_setup_arch(void) -{
-	struct device_node *np;
-	phys_addr_t paddr;
-	const unsigned int *reg;
-
-	/*
-	 * ioremap mpp and gpp registers in case they are later
-	 * needed by c2k_reset_board().
-	 */
-	np = of_find_compatible_node(NULL, NULL, "marvell,mv64360-mpp");
-	reg = of_get_property(np, "reg", NULL);
-	paddr = of_translate_address(np, reg);
-	of_node_put(np);
-	mv64x60_mpp_reg_base = ioremap(paddr, reg[1]);
-
-	np = of_find_compatible_node(NULL, NULL, "marvell,mv64360-gpp");
-	reg = of_get_property(np, "reg", NULL);
-	paddr = of_translate_address(np, reg);
-	of_node_put(np);
-	mv64x60_gpp_reg_base = ioremap(paddr, reg[1]);
-
-#ifdef CONFIG_PCI
-	mv64x60_pci_init();
-#endif
-}
-
-static void c2k_reset_board(void)
-{
-	u32 temp;
-
-	local_irq_disable();
-
-	temp = in_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_0);
-	temp &= 0xFFFF0FFF;
-	out_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_0, temp);
-
-	temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL);
-	temp |= 0x00000004;
-	out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL, temp);
-
-	temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL);
-	temp |= 0x00000004;
-	out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL, temp);
-
-	temp = in_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_2);
-	temp &= 0xFFFF0FFF;
-	out_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_2, temp);
-
-	temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL);
-	temp |= 0x00080000;
-	out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL, temp);
-
-	temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL);
-	temp |= 0x00080000;
-	out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL, temp);
-
-	out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_VALUE_SET, 0x00080004);
-}
-
-static void __noreturn c2k_restart(char *cmd) -{
-	c2k_reset_board();
-	msleep(100);
-	panic("restart failed\n");
-}
-
-#ifdef CONFIG_NOT_COHERENT_CACHE
-#define COHERENCY_SETTING "off"
-#else
-#define COHERENCY_SETTING "on"
-#endif
-
-void c2k_show_cpuinfo(struct seq_file *m) -{
-	seq_printf(m, "Vendor\t\t: GEFanuc\n");
-	seq_printf(m, "coherency\t: %s\n", COHERENCY_SETTING);
-}
-
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init c2k_probe(void)
-{
-	if (!of_machine_is_compatible("GEFanuc,C2K"))
-		return 0;
-
-	printk(KERN_INFO "Detected a GEFanuc C2K board\n");
-
-	_set_L2CR(0);
-	_set_L2CR(L2CR_L2E | L2CR_L2PE | L2CR_L2I);
-
-	mv64x60_init_early();
-
-	return 1;
-}
-
-define_machine(c2k) {
-	.name			= "C2K",
-	.probe			= c2k_probe,
-	.setup_arch		= c2k_setup_arch,
-	.show_cpuinfo		= c2k_show_cpuinfo,
-	.init_IRQ		= mv64x60_init_irq,
-	.get_irq		= mv64x60_get_irq,
-	.restart		= c2k_restart,
-	.calibrate_decr		= generic_calibrate_decr,
-};
--
2.16.2

^ permalink raw reply related

* RE: [RESEND 2/3] powerpc/memcpy: Add memcpy_mcsafe for pmem
From: Luck, Tony @ 2018-04-06 15:46 UTC (permalink / raw)
  To: Balbir Singh, Nicholas Piggin
  Cc: Jeff Moyer, Matthew Wilcox, Michael Ellerman, linux-nvdimm,
	linuxppc-dev, Christoph Hellwig
In-Reply-To: <CAKTCnz=LD_uO7bdwFHDHy9KHHJ_dPA1LdxF1Pm7OUFFGr4s_VA@mail.gmail.com>

PiBJIHRob3VnaHQgdGhlIGNhY2hlLWFsaWduZWQgbWlnaHQgbWFrZSBzZW5zZSwgc2luY2UgdXN1
YWxseSB3ZSdkIGV4cGVjdCB0aGUNCj4gZmFpbHVyZSB0byBiZSBhdCBhIGNhY2hlLWxpbmUgbGV2
ZWwsIGJ1dCBvdXIgY29weV90b2Zyb21fdXNlciBkb2VzIGFjY3VyYXRlDQo+IGFjY291bnRpbmcN
Cg0KVGhhdCdzIG9uZSBvZiB0aGUgd3JpbmtsZXMgaW4gdGhlIGN1cnJlbnQgeDg2IG1lbWNweV9t
Y3NhZmUoKS4gSXQgc3RhcnRzIGJ5DQpjaGVja2luZyBhbGlnbm1lbnQgb2YgdGhlIHNvdXJjZSBh
ZGRyZXNzLCBhbmQgbW92ZXMgYSBieXRlIGF0IGEgdGltZSB1bnRpbA0KaXQgaXMgOC1ieXRlIGFs
aWduZWQuIFdlIGRvIHRoaXMgYmVjYXVzZSBjdXJyZW50IHg4NiBpbXBsZW1lbnRhdGlvbnMgZG8g
bm90DQpncmFjZWZ1bGx5IGhhbmRsZSBhbiB1bmFsaWduZWQgcmVhZCB0aGF0IHNwYW5zIGZyb20g
YSBnb29kIGNhY2hlLWxpbmUgaW50bw0KYSBwb2lzb25lZCBvbmUuDQoNClRoaXMgaXMgZGlmZmVy
ZW50IGZyb20gY29weV90b2Zyb21fdXNlciB3aGljaCBhbGlnbnMgdGhlIGRlc3RpbmF0aW9uIGZv
ciBzcGVlZA0KcmVhc29ucyAodW5hbGlnbmVkIHJlYWRzIGhhdmUgYSBsb3dlciBwZW5hbHR5IHRo
YW4gdW5hbGlnbmVkIHdyaXRlcykuDQoNCi1Ub255DQo=

^ permalink raw reply

* Re: [PATCH v4 03/19] powerpc: Mark variable `l` as unused, remove `path`
From: LEROY Christophe @ 2018-04-06 15:33 UTC (permalink / raw)
  To: Mathieu Malaterre
  Cc: linux-kernel, linuxppc-dev, Paul Mackerras,
	Benjamin Herrenschmidt, Michael Ellerman
In-Reply-To: <20180405202648.2836-1-malat@debian.org>

Mathieu Malaterre <malat@debian.org> a =C3=A9crit=C2=A0:

> Add gcc attribute unused for `l` variable, replace `path` variable direct=
ly
> with prom_scratch. Fix warnings treated as errors with W=3D1:
>
>   arch/powerpc/kernel/prom_init.c:607:6: error: variable =E2=80=98l=E2=80=
=99 set but=20=20
>=20not used [-Werror=3Dunused-but-set-variable]
>   arch/powerpc/kernel/prom_init.c:1388:8: error: variable =E2=80=98path=
=E2=80=99 set=20=20
>=20but not used [-Werror=3Dunused-but-set-variable]
>
> Suggested-by: Michael Ellerman <mpe@ellerman.id.au>
> Signed-off-by: Mathieu Malaterre <malat@debian.org>
> ---
> v4: redo v3 since path variable can be avoided
> v3: really move path within ifdef DEBUG_PROM
> v2: move path within ifdef DEBUG_PROM
>
>  arch/powerpc/kernel/prom_init.c | 11 +++++------
>  1 file changed, 5 insertions(+), 6 deletions(-)
>
> diff --git a/arch/powerpc/kernel/prom_init.c=20=20
>=20b/arch/powerpc/kernel/prom_init.c
> index f8a9a50ff9b5..4b223a9470be 100644
> --- a/arch/powerpc/kernel/prom_init.c
> +++ b/arch/powerpc/kernel/prom_init.c
> @@ -604,7 +604,7 @@ static void __init early_cmdline_parse(void)
>  	const char *opt;
>
>  	char *p;
> -	int l =3D 0;
> +	int l __maybe_unused =3D 0;

Instead of hiding the problem with __maybe_unused, I think we could=20=20
replace=20the
#ifdef CONFIG_CMDLINE
by a
if (IS_ENABLED(CONFIG_CMDLINE_BOOL))

This is recommanded by Linux codying style

Christophe

>
>  	prom_cmd_line[0] =3D 0;
>  	p =3D prom_cmd_line;
> @@ -1386,7 +1386,7 @@ static void __init reserve_mem(u64 base, u64 size)
>  static void __init prom_init_mem(void)
>  {
>  	phandle node;
> -	char *path, type[64];
> +	char type[64];
>  	unsigned int plen;
>  	cell_t *p, *endp;
>  	__be32 val;
> @@ -1407,7 +1407,6 @@ static void __init prom_init_mem(void)
>  	prom_debug("root_size_cells: %x\n", rsc);
>
>  	prom_debug("scanning memory:\n");
> -	path =3D prom_scratch;
>
>  	for (node =3D 0; prom_next_node(&node); ) {
>  		type[0] =3D 0;
> @@ -1432,9 +1431,9 @@ static void __init prom_init_mem(void)
>  		endp =3D p + (plen / sizeof(cell_t));
>
>  #ifdef DEBUG_PROM
> -		memset(path, 0, PROM_SCRATCH_SIZE);
> -		call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
> -		prom_debug("  node %s :\n", path);
> +		memset(prom_scratch, 0, PROM_SCRATCH_SIZE);
> +		call_prom("package-to-path", 3, 1, node, prom_scratch,=20=20
>=20PROM_SCRATCH_SIZE - 1);
> +		prom_debug("  node %s :\n", prom_scratch);
>  #endif /* DEBUG_PROM */
>
>  		while ((endp - p) >=3D (rac + rsc)) {
> --
> 2.11.0

^ permalink raw reply

* Re: [PATCH v9 17/24] mm: Protect mm_rb tree with a rwlock
From: Laurent Dufour @ 2018-04-06 14:23 UTC (permalink / raw)
  To: David Rientjes
  Cc: paulmck, peterz, akpm, kirill, ak, mhocko, dave, jack,
	Matthew Wilcox, benh, mpe, paulus, Thomas Gleixner, Ingo Molnar,
	hpa, Will Deacon, Sergey Senozhatsky, Andrea Arcangeli,
	Alexei Starovoitov, kemi.wang, sergey.senozhatsky.work,
	Daniel Jordan, linux-kernel, linux-mm, haren, khandual, npiggin,
	bsingharora, Tim Chen, linuxppc-dev, x86
In-Reply-To: <alpine.DEB.2.20.1804021711090.34466@chino.kir.corp.google.com>



On 03/04/2018 02:11, David Rientjes wrote:
> On Tue, 13 Mar 2018, Laurent Dufour wrote:
> 
>> This change is inspired by the Peter's proposal patch [1] which was
>> protecting the VMA using SRCU. Unfortunately, SRCU is not scaling well in
>> that particular case, and it is introducing major performance degradation
>> due to excessive scheduling operations.
>>
>> To allow access to the mm_rb tree without grabbing the mmap_sem, this patch
>> is protecting it access using a rwlock.  As the mm_rb tree is a O(log n)
>> search it is safe to protect it using such a lock.  The VMA cache is not
>> protected by the new rwlock and it should not be used without holding the
>> mmap_sem.
>>
>> To allow the picked VMA structure to be used once the rwlock is released, a
>> use count is added to the VMA structure. When the VMA is allocated it is
>> set to 1.  Each time the VMA is picked with the rwlock held its use count
>> is incremented. Each time the VMA is released it is decremented. When the
>> use count hits zero, this means that the VMA is no more used and should be
>> freed.
>>
>> This patch is preparing for 2 kind of VMA access :
>>  - as usual, under the control of the mmap_sem,
>>  - without holding the mmap_sem for the speculative page fault handler.
>>
>> Access done under the control the mmap_sem doesn't require to grab the
>> rwlock to protect read access to the mm_rb tree, but access in write must
>> be done under the protection of the rwlock too. This affects inserting and
>> removing of elements in the RB tree.
>>
>> The patch is introducing 2 new functions:
>>  - vma_get() to find a VMA based on an address by holding the new rwlock.
>>  - vma_put() to release the VMA when its no more used.
>> These services are designed to be used when access are made to the RB tree
>> without holding the mmap_sem.
>>
>> When a VMA is removed from the RB tree, its vma->vm_rb field is cleared and
>> we rely on the WMB done when releasing the rwlock to serialize the write
>> with the RMB done in a later patch to check for the VMA's validity.
>>
>> When free_vma is called, the file associated with the VMA is closed
>> immediately, but the policy and the file structure remained in used until
>> the VMA's use count reach 0, which may happens later when exiting an
>> in progress speculative page fault.
>>
>> [1] https://patchwork.kernel.org/patch/5108281/
>>
>> Cc: Peter Zijlstra (Intel) <peterz@infradead.org>
>> Cc: Matthew Wilcox <willy@infradead.org>
>> Signed-off-by: Laurent Dufour <ldufour@linux.vnet.ibm.com>
> 
> Can __free_vma() be generalized for mm/nommu.c's delete_vma() and 
> do_mmap()?

To be honest I didn't look at mm/nommu.c assuming that such architecture would
probably be monothreaded. Am I wrong ?

^ permalink raw reply

* [RFC linux] init: make all setup_arch() output string to boot_command_line[]
From: yuan linyu @ 2018-04-06 11:11 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-alpha, linux-snps-arc, linux-arm-kernel, linux-c6x-dev,
	uclinux-h8-devel, linux-hexagon, linux-ia64, linux-m68k,
	Michal Simek, linux-mips, Greentime Hu, nios2-dev, openrisc,
	linux-parisc, linuxppc-dev, linux-riscv, linux-s390, linux-sh,
	sparclinux, user-mode-linux-devel, user-mode-linux-user,
	Guan Xuetao, linux-xtensa, yuan linyu

From: yuan linyu <Linyu.Yuan@alcatel-sbell.com.cn>

then all arch boot parameter handled in the same way in start_kernel()

Signed-off-by: yuan linyu <Linyu.Yuan@alcatel-sbell.com.cn>
---
 arch/alpha/kernel/setup.c          |  4 +---
 arch/arc/kernel/setup.c            |  5 +----
 arch/arm/kernel/setup.c            |  7 +------
 arch/arm64/kernel/setup.c          |  4 +---
 arch/c6x/kernel/setup.c            |  5 +----
 arch/h8300/kernel/setup.c          |  3 +--
 arch/hexagon/kernel/setup.c        | 16 +---------------
 arch/ia64/kernel/setup.c           | 15 ++++++++-------
 arch/m68k/kernel/setup_mm.c        |  5 ++---
 arch/m68k/kernel/setup_no.c        |  3 +--
 arch/microblaze/kernel/setup.c     |  4 +---
 arch/mips/kernel/setup.c           | 11 +++--------
 arch/nds32/kernel/setup.c          |  3 +--
 arch/nios2/kernel/setup.c          |  5 +----
 arch/openrisc/kernel/setup.c       |  4 +---
 arch/parisc/kernel/setup.c         |  9 ++-------
 arch/powerpc/kernel/setup-common.c |  4 +---
 arch/riscv/kernel/setup.c          |  4 +---
 arch/s390/kernel/setup.c           |  6 +-----
 arch/sh/kernel/setup.c             |  7 ++++---
 arch/sparc/kernel/setup_32.c       |  9 +++++----
 arch/sparc/kernel/setup_64.c       |  8 ++++----
 arch/um/kernel/um_arch.c           |  3 +--
 arch/unicore32/kernel/setup.c      |  8 +-------
 arch/x86/kernel/setup.c            |  6 +-----
 arch/xtensa/kernel/setup.c         |  9 +++++----
 include/linux/init.h               |  2 +-
 init/main.c                        | 14 +++++++-------
 28 files changed, 59 insertions(+), 124 deletions(-)

diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index 5576f7646fb6..c74675cf7129 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -505,8 +505,7 @@ register_cpus(void)
 
 arch_initcall(register_cpus);
 
-void __init
-setup_arch(char **cmdline_p)
+void __init setup_arch(void)
 {
 	extern char _end[];
 
@@ -566,7 +565,6 @@ setup_arch(char **cmdline_p)
 		strlcpy(command_line, COMMAND_LINE, sizeof command_line);
 	}
 	strcpy(boot_command_line, command_line);
-	*cmdline_p = command_line;
 
 	/* 
 	 * Process command-line arguments.
diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
index b2cae79a25d7..9cfdcf42bf28 100644
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
@@ -456,7 +456,7 @@ static inline int is_kernel(unsigned long addr)
 	return 0;
 }
 
-void __init setup_arch(char **cmdline_p)
+void __init setup_arch(void)
 {
 #ifdef CONFIG_ARC_UBOOT_SUPPORT
 	/* make sure that uboot passed pointer to cmdline/dtb is valid */
@@ -487,9 +487,6 @@ void __init setup_arch(char **cmdline_p)
 		}
 	}
 
-	/* Save unparsed command line copy for /proc/cmdline */
-	*cmdline_p = boot_command_line;
-
 	/* To force early parsing of things like mem=xxx */
 	parse_early_param();
 
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index fc40a2b40595..1025e3a37689 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -153,7 +153,6 @@ EXPORT_SYMBOL(elf_platform);
 
 static const char *cpu_name;
 static const char *machine_name;
-static char __initdata cmd_line[COMMAND_LINE_SIZE];
 const struct machine_desc *machine_desc __initdata;
 
 static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
@@ -1061,7 +1060,7 @@ void __init hyp_mode_check(void)
 #endif
 }
 
-void __init setup_arch(char **cmdline_p)
+void __init setup_arch(void)
 {
 	const struct machine_desc *mdesc;
 
@@ -1091,10 +1090,6 @@ void __init setup_arch(char **cmdline_p)
 	init_mm.end_data   = (unsigned long) _edata;
 	init_mm.brk	   = (unsigned long) _end;
 
-	/* populate cmd_line too for later use, preserving boot_command_line */
-	strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
-	*cmdline_p = cmd_line;
-
 	early_fixmap_init();
 	early_ioremap_init();
 
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 30ad2f085d1f..c7ba4d32e7f7 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -243,15 +243,13 @@ static void __init request_standard_resources(void)
 
 u64 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID };
 
-void __init setup_arch(char **cmdline_p)
+void __init setup_arch(void)
 {
 	init_mm.start_code = (unsigned long) _text;
 	init_mm.end_code   = (unsigned long) _etext;
 	init_mm.end_data   = (unsigned long) _edata;
 	init_mm.brk	   = (unsigned long) _end;
 
-	*cmdline_p = boot_command_line;
-
 	early_fixmap_init();
 	early_ioremap_init();
 
diff --git a/arch/c6x/kernel/setup.c b/arch/c6x/kernel/setup.c
index 786e36e2f61d..012c8e746889 100644
--- a/arch/c6x/kernel/setup.c
+++ b/arch/c6x/kernel/setup.c
@@ -294,16 +294,13 @@ notrace void __init machine_init(unsigned long dt_ptr)
 	parse_early_param();
 }
 
-void __init setup_arch(char **cmdline_p)
+void __init setup_arch(void)
 {
 	int bootmap_size;
 	struct memblock_region *reg;
 
 	printk(KERN_INFO "Initializing kernel\n");
 
-	/* Initialize command line */
-	*cmdline_p = boot_command_line;
-
 	memory_end = ram_end;
 	memory_end &= ~(PAGE_SIZE - 1);
 
diff --git a/arch/h8300/kernel/setup.c b/arch/h8300/kernel/setup.c
index a4d0470c10a9..bb54c2087f13 100644
--- a/arch/h8300/kernel/setup.c
+++ b/arch/h8300/kernel/setup.c
@@ -117,7 +117,7 @@ static void __init bootmem_init(void)
 	}
 }
 
-void __init setup_arch(char **cmdline_p)
+void __init setup_arch(void)
 {
 	unflatten_and_copy_device_tree();
 
@@ -131,7 +131,6 @@ void __init setup_arch(char **cmdline_p)
 
 	if (*command_line)
 		strcpy(boot_command_line, command_line);
-	*cmdline_p = boot_command_line;
 
 	parse_early_param();
 
diff --git a/arch/hexagon/kernel/setup.c b/arch/hexagon/kernel/setup.c
index 6981949f5df3..a0348dfad265 100644
--- a/arch/hexagon/kernel/setup.c
+++ b/arch/hexagon/kernel/setup.c
@@ -34,7 +34,6 @@
 #include <asm/vm_mmu.h>
 #include <asm/time.h>
 
-char cmd_line[COMMAND_LINE_SIZE];
 static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
 
 int on_simulator;
@@ -44,12 +43,7 @@ void calibrate_delay(void)
 	loops_per_jiffy = thread_freq_mhz * 1000000 / HZ;
 }
 
-/*
- * setup_arch -  high level architectural setup routine
- * @cmdline_p: pointer to pointer to command-line arguments
- */
-
-void __init setup_arch(char **cmdline_p)
+void __init setup_arch(void)
 {
 	char *p = &external_cmdline_buffer;
 
@@ -84,14 +78,6 @@ void __init setup_arch(char **cmdline_p)
 		strlcpy(boot_command_line, default_command_line,
 			COMMAND_LINE_SIZE);
 
-	/*
-	 * boot_command_line and the value set up by setup_arch
-	 * are both picked up by the init code. If no reason to
-	 * make them different, pass the same pointer back.
-	 */
-	strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
-	*cmdline_p = cmd_line;
-
 	parse_early_param();
 
 	setup_arch_memory();
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index dee56bcb993d..75196264dd4e 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -527,15 +527,16 @@ int __init reserve_elfcorehdr(u64 *start, u64 *end)
 
 #endif /* CONFIG_PROC_VMCORE */
 
-void __init
-setup_arch (char **cmdline_p)
+void __init setup_arch (void)
 {
+	char *cmdline_p;
+
 	unw_init();
 
 	ia64_patch_vtop((u64) __start___vtop_patchlist, (u64) __end___vtop_patchlist);
 
-	*cmdline_p = __va(ia64_boot_param->command_line);
-	strlcpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE);
+	cmdline_p = __va(ia64_boot_param->command_line);
+	strlcpy(boot_command_line, cmdline_p, COMMAND_LINE_SIZE);
 
 	efi_init();
 	io_port_init();
@@ -546,12 +547,12 @@ setup_arch (char **cmdline_p)
 	 * that ia64_mv is initialised before any command line
 	 * settings may cause console setup to occur
 	 */
-	machvec_init_from_cmdline(*cmdline_p);
+	machvec_init_from_cmdline(cmdline_p);
 #endif
 
 	parse_early_param();
 
-	if (early_console_setup(*cmdline_p) == 0)
+	if (early_console_setup(cmdline_p) == 0)
 		mark_bsp_online();
 
 #ifdef CONFIG_ACPI
@@ -618,7 +619,7 @@ setup_arch (char **cmdline_p)
 	if (!nomca)
 		ia64_mca_init();
 
-	platform_setup(cmdline_p);
+	platform_setup(&cmdline_p);
 #ifndef CONFIG_IA64_HP_SIM
 	check_sal_cache_flush();
 #endif
diff --git a/arch/m68k/kernel/setup_mm.c b/arch/m68k/kernel/setup_mm.c
index dd25bfc22fb4..38ccaf3e0274 100644
--- a/arch/m68k/kernel/setup_mm.c
+++ b/arch/m68k/kernel/setup_mm.c
@@ -222,7 +222,7 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record)
 #endif
 }
 
-void __init setup_arch(char **cmdline_p)
+void __init setup_arch(void)
 {
 #ifndef CONFIG_SUN3
 	int i;
@@ -272,8 +272,7 @@ void __init setup_arch(char **cmdline_p)
 	m68k_command_line[CL_SIZE - 1] = 0;
 #endif /* CONFIG_BOOTPARAM */
 	process_uboot_commandline(&m68k_command_line[0], CL_SIZE);
-	*cmdline_p = m68k_command_line;
-	memcpy(boot_command_line, *cmdline_p, CL_SIZE);
+	memcpy(boot_command_line, m68k_command_line, CL_SIZE);
 
 	parse_early_param();
 
diff --git a/arch/m68k/kernel/setup_no.c b/arch/m68k/kernel/setup_no.c
index a98af1018201..8b244d4ea603 100644
--- a/arch/m68k/kernel/setup_no.c
+++ b/arch/m68k/kernel/setup_no.c
@@ -84,7 +84,7 @@ void (*mach_power_off)(void);
 #define	CPU_INSTR_PER_JIFFY	16
 #endif
 
-void __init setup_arch(char **cmdline_p)
+void __init setup_arch(void)
 {
 	int bootmap_size;
 
@@ -143,7 +143,6 @@ void __init setup_arch(char **cmdline_p)
 		 __bss_stop, memory_start, memory_start, memory_end);
 
 	/* Keep a copy of command line */
-	*cmdline_p = &command_line[0];
 	memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
 	boot_command_line[COMMAND_LINE_SIZE-1] = 0;
 
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c
index be98ffe28ca8..632b7546effc 100644
--- a/arch/microblaze/kernel/setup.c
+++ b/arch/microblaze/kernel/setup.c
@@ -50,10 +50,8 @@ unsigned int boot_cpuid;
  */
 char cmd_line[COMMAND_LINE_SIZE] __attribute__ ((section(".data")));
 
-void __init setup_arch(char **cmdline_p)
+void __init setup_arch(void)
 {
-	*cmdline_p = boot_command_line;
-
 	console_verbose();
 
 	unflatten_device_tree();
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 5f8b0a9e30b3..2bff67be95d6 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -64,7 +64,6 @@ EXPORT_SYMBOL(mips_machtype);
 
 struct boot_mem_map boot_mem_map;
 
-static char __initdata command_line[COMMAND_LINE_SIZE];
 char __initdata arcs_cmdline[COMMAND_LINE_SIZE];
 
 #ifdef CONFIG_CMDLINE_BOOL
@@ -829,7 +828,7 @@ static void __init request_crashkernel(struct resource *res)
 #define BUILTIN_EXTEND_WITH_PROM	\
 	IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND)
 
-static void __init arch_mem_init(char **cmdline_p)
+static void __init arch_mem_init(void)
 {
 	struct memblock_region *reg;
 	extern void plat_mem_setup(void);
@@ -881,10 +880,6 @@ static void __init arch_mem_init(char **cmdline_p)
 	pr_info("Determined physical RAM map:\n");
 	print_memory_map();
 
-	strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
-
-	*cmdline_p = command_line;
-
 	parse_early_param();
 
 	if (usermem) {
@@ -1002,7 +997,7 @@ static void __init prefill_possible_map(void)
 static inline void prefill_possible_map(void) {}
 #endif
 
-void __init setup_arch(char **cmdline_p)
+void __init setup_arch(void)
 {
 	cpu_probe();
 	mips_cm_probe();
@@ -1023,7 +1018,7 @@ void __init setup_arch(char **cmdline_p)
 #endif
 #endif
 
-	arch_mem_init(cmdline_p);
+	arch_mem_init();
 
 	resource_init();
 	plat_smp_setup();
diff --git a/arch/nds32/kernel/setup.c b/arch/nds32/kernel/setup.c
index ba910e9e4ecb..7df72753dd9a 100644
--- a/arch/nds32/kernel/setup.c
+++ b/arch/nds32/kernel/setup.c
@@ -276,7 +276,7 @@ static void __init setup_memory(void)
 	memblock_dump_all();
 }
 
-void __init setup_arch(char **cmdline_p)
+void __init setup_arch(void)
 {
 	early_init_devtree( __dtb_start);
 
@@ -303,7 +303,6 @@ void __init setup_arch(char **cmdline_p)
 			conswitchp = &dummy_con;
 	}
 
-	*cmdline_p = boot_command_line;
 	early_trap_init();
 }
 
diff --git a/arch/nios2/kernel/setup.c b/arch/nios2/kernel/setup.c
index 926a02b17b31..e8d140f1d40c 100644
--- a/arch/nios2/kernel/setup.c
+++ b/arch/nios2/kernel/setup.c
@@ -141,7 +141,7 @@ asmlinkage void __init nios2_boot_init(unsigned r4, unsigned r5, unsigned r6,
 	parse_early_param();
 }
 
-void __init setup_arch(char **cmdline_p)
+void __init setup_arch(void)
 {
 	int bootmap_size;
 
@@ -156,9 +156,6 @@ void __init setup_arch(char **cmdline_p)
 	init_mm.brk = (unsigned long) _end;
 	init_task.thread.kregs = &fake_regs;
 
-	/* Keep a copy of command line */
-	*cmdline_p = boot_command_line;
-
 	min_low_pfn = PFN_UP(memory_start);
 	max_low_pfn = PFN_DOWN(memory_end);
 	max_mapnr = max_low_pfn;
diff --git a/arch/openrisc/kernel/setup.c b/arch/openrisc/kernel/setup.c
index 9d28ab14d139..d73e1faa88d1 100644
--- a/arch/openrisc/kernel/setup.c
+++ b/arch/openrisc/kernel/setup.c
@@ -283,7 +283,7 @@ void calibrate_delay(void)
 		(loops_per_jiffy / (5000 / HZ)) % 100, loops_per_jiffy);
 }
 
-void __init setup_arch(char **cmdline_p)
+void __init setup_arch(void)
 {
 	unflatten_and_copy_device_tree();
 
@@ -320,8 +320,6 @@ void __init setup_arch(char **cmdline_p)
 		conswitchp = &dummy_con;
 #endif
 
-	*cmdline_p = boot_command_line;
-
 	printk(KERN_INFO "OpenRISC Linux -- http://openrisc.io\n");
 }
 
diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c
index 0e9675f857a5..7756a6110b83 100644
--- a/arch/parisc/kernel/setup.c
+++ b/arch/parisc/kernel/setup.c
@@ -51,8 +51,6 @@
 #include <asm/unwind.h>
 #include <asm/smp.h>
 
-static char __initdata command_line[COMMAND_LINE_SIZE];
-
 /* Intended for ccio/sba/cpu statistics under /proc/bus/{runway|gsc} */
 struct proc_dir_entry * proc_runway_root __read_mostly = NULL;
 struct proc_dir_entry * proc_gsc_root __read_mostly = NULL;
@@ -63,7 +61,7 @@ int parisc_bus_is_phys __read_mostly = 1;	/* Assume no IOMMU is present */
 EXPORT_SYMBOL(parisc_bus_is_phys);
 #endif
 
-void __init setup_cmdline(char **cmdline_p)
+void __init setup_cmdline(void)
 {
 	extern unsigned int boot_args[];
 
@@ -85,9 +83,6 @@ void __init setup_cmdline(char **cmdline_p)
 		}
 #endif
 	}
-
-	strcpy(command_line, boot_command_line);
-	*cmdline_p = command_line;
 }
 
 #ifdef CONFIG_PA11
@@ -119,7 +114,7 @@ void __init dma_ops_init(void)
 
 extern void collect_boot_cpu_data(void);
 
-void __init setup_arch(char **cmdline_p)
+void __init setup_arch(void)
 {
 #ifdef CONFIG_64BIT
 	extern int parisc_narrow_firmware;
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index d73ec518ef80..b88ce4afaafd 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -839,10 +839,8 @@ static __init void print_system_info(void)
  * Called into from start_kernel this initializes memblock, which is used
  * to manage page allocation until mem_init is called.
  */
-void __init setup_arch(char **cmdline_p)
+void __init setup_arch(void)
 {
-	*cmdline_p = boot_command_line;
-
 	/* Set a half-reasonable default so udelay does something sensible */
 	loops_per_jiffy = 500000000 / HZ;
 
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
index c11f40c1b2a8..dee21fd2f5c2 100644
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -192,10 +192,8 @@ static void __init setup_bootmem(void)
 	}
 }
 
-void __init setup_arch(char **cmdline_p)
+void __init setup_arch(void)
 {
-	*cmdline_p = boot_command_line;
-
 	parse_early_param();
 
 	init_mm.start_code = (unsigned long) _stext;
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index a6a91f01a17a..6addb5afc59e 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -867,7 +867,7 @@ static void __init setup_task_size(void)
  * was printed.
  */
 
-void __init setup_arch(char **cmdline_p)
+void __init setup_arch(void)
 {
         /*
          * print what head.S has found out about the machine
@@ -880,10 +880,6 @@ void __init setup_arch(char **cmdline_p)
 	else if (MACHINE_IS_LPAR)
 		pr_info("Linux is running natively in 64-bit mode\n");
 
-	/* Have one command line that is parsed and saved in /proc/cmdline */
-	/* boot_command_line has been already set up in early.c */
-	*cmdline_p = boot_command_line;
-
         ROOT_DEV = Root_RAM0;
 
 	/* Is init_mm really needed? */
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index b95c411d0333..c46646f0c3c5 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -270,8 +270,10 @@ void __ref sh_fdt_init(phys_addr_t dt_phys)
 }
 #endif
 
-void __init setup_arch(char **cmdline_p)
+void __init setup_arch(void)
 {
+	char *cmdline_p = command_line;
+
 	enable_mmu();
 
 	ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
@@ -319,7 +321,6 @@ void __init setup_arch(char **cmdline_p)
 
 	/* Save unparsed command line copy for /proc/cmdline */
 	memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
-	*cmdline_p = command_line;
 
 	parse_early_param();
 
@@ -338,7 +339,7 @@ void __init setup_arch(char **cmdline_p)
 
 	/* Perform the machine specific initialisation */
 	if (likely(sh_mv.mv_setup))
-		sh_mv.mv_setup(cmdline_p);
+		sh_mv.mv_setup(&cmdline_p);
 
 	plat_smp_setup();
 }
diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c
index 13664c377196..5bced97cc5f8 100644
--- a/arch/sparc/kernel/setup_32.c
+++ b/arch/sparc/kernel/setup_32.c
@@ -294,19 +294,20 @@ void __init sparc32_start_kernel(struct linux_romvec *rp)
 	start_kernel();
 }
 
-void __init setup_arch(char **cmdline_p)
+void __init setup_arch(void)
 {
 	int i;
+	char *cmdline_p;
 	unsigned long highest_paddr;
 
 	sparc_ttable = &trapbase;
 
 	/* Initialize PROM console and command line. */
-	*cmdline_p = prom_getbootargs();
-	strlcpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE);
+	cmdline_p = prom_getbootargs();
+	strlcpy(boot_command_line, cmdline_p, COMMAND_LINE_SIZE);
 	parse_early_param();
 
-	boot_flags_init(*cmdline_p);
+	boot_flags_init(cmdline_p);
 
 	register_console(&prom_early_console);
 
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c
index 7944b3ca216a..9f6edffa6a4b 100644
--- a/arch/sparc/kernel/setup_64.c
+++ b/arch/sparc/kernel/setup_64.c
@@ -630,14 +630,14 @@ void __init alloc_irqstack_bootmem(void)
 	}
 }
 
-void __init setup_arch(char **cmdline_p)
+void __init setup_arch(void)
 {
 	/* Initialize PROM console and command line. */
-	*cmdline_p = prom_getbootargs();
-	strlcpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE);
+	char *cmdline_p = prom_getbootargs();
+	strlcpy(boot_command_line, cmdline_p, COMMAND_LINE_SIZE);
 	parse_early_param();
 
-	boot_flags_init(*cmdline_p);
+	boot_flags_init(cmdline_p);
 #ifdef CONFIG_EARLYFB
 	if (btext_find_display())
 #endif
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index a818ccef30ca..73d62cf96149 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -339,7 +339,7 @@ int __init __weak read_initrd(void)
 	return 0;
 }
 
-void __init setup_arch(char **cmdline_p)
+void __init setup_arch(void)
 {
 	stack_protections((unsigned long) &init_thread_info);
 	setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem);
@@ -348,7 +348,6 @@ void __init setup_arch(char **cmdline_p)
 
 	paging_init();
 	strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
-	*cmdline_p = command_line;
 	setup_hostinfo(host_info, sizeof host_info);
 }
 
diff --git a/arch/unicore32/kernel/setup.c b/arch/unicore32/kernel/setup.c
index c2bffa5614a4..c13a07eeed0b 100644
--- a/arch/unicore32/kernel/setup.c
+++ b/arch/unicore32/kernel/setup.c
@@ -60,8 +60,6 @@ struct screen_info screen_info;
 char elf_platform[ELF_PLATFORM_SIZE];
 EXPORT_SYMBOL(elf_platform);
 
-static char __initdata cmd_line[COMMAND_LINE_SIZE];
-
 static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
 
 /*
@@ -235,7 +233,7 @@ static int __init customize_machine(void)
 }
 arch_initcall(customize_machine);
 
-void __init setup_arch(char **cmdline_p)
+void __init setup_arch(void)
 {
 	char *from = default_command_line;
 
@@ -249,10 +247,6 @@ void __init setup_arch(char **cmdline_p)
 	/* parse_early_param needs a boot_command_line */
 	strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
 
-	/* populate cmd_line too for later use, preserving boot_command_line */
-	strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
-	*cmdline_p = cmd_line;
-
 	parse_early_param();
 
 	uc32_memblock_init(&meminfo);
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 6285697b6e56..6e3347dde550 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -219,7 +219,6 @@ unsigned long saved_video_mode;
 #define RAMDISK_PROMPT_FLAG		0x8000
 #define RAMDISK_LOAD_FLAG		0x4000
 
-static char __initdata command_line[COMMAND_LINE_SIZE];
 #ifdef CONFIG_CMDLINE_BOOL
 static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE;
 #endif
@@ -812,7 +811,7 @@ dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p)
  * Note: On x86_64, fixmaps are ready for use even before this is called.
  */
 
-void __init setup_arch(char **cmdline_p)
+void __init setup_arch(void)
 {
 	memblock_reserve(__pa_symbol(_text),
 			 (unsigned long)__bss_stop - (unsigned long)_text);
@@ -933,9 +932,6 @@ void __init setup_arch(char **cmdline_p)
 #endif
 #endif
 
-	strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
-	*cmdline_p = command_line;
-
 	/*
 	 * x86_configure_nx() is called before parse_early_param() to detect
 	 * whether hardware doesn't support NX (so that the early EHCI debug
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
index 686a27444bba..0409fa85bfdd 100644
--- a/arch/xtensa/kernel/setup.c
+++ b/arch/xtensa/kernel/setup.c
@@ -309,8 +309,10 @@ static inline int mem_reserve(unsigned long start, unsigned long end)
 	return memblock_reserve(start, end - start);
 }
 
-void __init setup_arch(char **cmdline_p)
+void __init setup_arch(void)
 {
+	char *cmdline_p = command_line;
+
 	pr_info("config ID: %08x:%08x\n",
 		get_sr(SREG_EPC), get_sr(SREG_EXCSAVE));
 	if (get_sr(SREG_EPC) != XCHAL_HW_CONFIGID0 ||
@@ -318,9 +320,8 @@ void __init setup_arch(char **cmdline_p)
 		pr_info("built for config ID: %08x:%08x\n",
 			XCHAL_HW_CONFIGID0, XCHAL_HW_CONFIGID1);
 
-	*cmdline_p = command_line;
-	platform_setup(cmdline_p);
-	strlcpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE);
+	platform_setup(&cmdline_p);
+	strlcpy(boot_command_line, cmdline_p, COMMAND_LINE_SIZE);
 
 	/* Reserve some memory regions */
 
diff --git a/include/linux/init.h b/include/linux/init.h
index bc27cf03c41e..206b98d77cb4 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -129,7 +129,7 @@ extern char *saved_command_line;
 extern unsigned int reset_devices;
 
 /* used by init/main.c */
-void setup_arch(char **);
+void setup_arch(void);
 void prepare_namespace(void);
 void __init load_default_modules(void);
 int __init init_rootfs(void);
diff --git a/init/main.c b/init/main.c
index e4a3160991ea..8df5917867b1 100644
--- a/init/main.c
+++ b/init/main.c
@@ -367,15 +367,16 @@ static inline void smp_prepare_cpus(unsigned int maxcpus) { }
  * parsing is performed in place, and we should allow a component to
  * store reference of name/value for future reference.
  */
-static void __init setup_command_line(char *command_line)
+static void __init setup_command_line(void)
 {
 	saved_command_line =
 		memblock_virt_alloc(strlen(boot_command_line) + 1, 0);
 	initcall_command_line =
 		memblock_virt_alloc(strlen(boot_command_line) + 1, 0);
-	static_command_line = memblock_virt_alloc(strlen(command_line) + 1, 0);
+	static_command_line =
+		memblock_virt_alloc(strlen(boot_command_line) + 1, 0);
 	strcpy(saved_command_line, boot_command_line);
-	strcpy(static_command_line, command_line);
+	strcpy(static_command_line, boot_command_line);
 }
 
 /*
@@ -514,7 +515,6 @@ static void __init mm_init(void)
 
 asmlinkage __visible void __init start_kernel(void)
 {
-	char *command_line;
 	char *after_dashes;
 
 	set_task_stack_end_magic(&init_task);
@@ -533,16 +533,16 @@ asmlinkage __visible void __init start_kernel(void)
 	boot_cpu_init();
 	page_address_init();
 	pr_notice("%s", linux_banner);
-	setup_arch(&command_line);
+	setup_arch();
 	/*
 	 * Set up the the initial canary and entropy after arch
 	 * and after adding latent and command line entropy.
 	 */
 	add_latent_entropy();
-	add_device_randomness(command_line, strlen(command_line));
+	add_device_randomness(boot_command_line, strlen(boot_command_line));
 	boot_init_stack_canary();
 	mm_init_cpumask(&init_mm);
-	setup_command_line(command_line);
+	setup_command_line();
 	setup_nr_cpu_ids();
 	setup_per_cpu_areas();
 	boot_cpu_state_init();
-- 
2.14.1

^ permalink raw reply related

* Re: [PATCH 3/5] arm64: early ISB at exit from extended quiescent state
From: Mark Rutland @ 2018-04-06 11:07 UTC (permalink / raw)
  To: Yury Norov
  Cc: Paul E. McKenney, Will Deacon, Chris Metcalf, Christopher Lameter,
	Russell King - ARM Linux, Steven Rostedt, Mathieu Desnoyers,
	Catalin Marinas, Pekka Enberg, David Rientjes, Joonsoo Kim,
	Andrew Morton, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Alexey Klimov, linux-arm-kernel, linuxppc-dev,
	kvm-ppc, linux-mm, linux-kernel
In-Reply-To: <20180405171800.5648-4-ynorov@caviumnetworks.com>

On Thu, Apr 05, 2018 at 08:17:58PM +0300, Yury Norov wrote:
> This series enables delaying of kernel memory synchronization
> for CPUs running in extended quiescent state (EQS) till the exit
> of that state.
> 
> ARM64 uses IPI mechanism to notify all cores in  SMP system that
> kernel text is changed; and IPI handler calls isb() to synchronize.
> 
> If we don't deliver IPI to EQS CPUs anymore, we should add ISB early
> in EQS exit path.
> 
> There are 2 such paths. One starts in do_idle() loop, and other
> in el0_svc entry. For do_idle(), isb() is added in
> arch_cpu_idle_exit() hook. And for SVC handler, isb is called in
> el0_svc_naked.
> 
> Suggested-by: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
> ---
>  arch/arm64/kernel/entry.S   | 16 +++++++++++++++-
>  arch/arm64/kernel/process.c |  7 +++++++
>  2 files changed, 22 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index c8d9ec363ddd..b1e1c19b4432 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -48,7 +48,7 @@
>  	.endm
>  
>  	.macro el0_svc_restore_syscall_args
> -#if defined(CONFIG_CONTEXT_TRACKING)
> +#if !defined(CONFIG_TINY_RCU) || defined(CONFIG_CONTEXT_TRACKING)
>  	restore_syscall_args
>  #endif
>  	.endm
> @@ -483,6 +483,19 @@ __bad_stack:
>  	ASM_BUG()
>  	.endm
>  
> +/*
> + * If CPU is in extended quiescent state we need isb to ensure that
> + * possible change of kernel text is visible by the core.
> + */
> +	.macro	isb_if_eqs
> +#ifndef CONFIG_TINY_RCU
> +	bl	rcu_is_watching
> +	cbnz	x0, 1f
> +	isb 					// pairs with aarch64_insn_patch_text
> +1:
> +#endif
> +	.endm
> +
>  el0_sync_invalid:
>  	inv_entry 0, BAD_SYNC
>  ENDPROC(el0_sync_invalid)
> @@ -949,6 +962,7 @@ alternative_else_nop_endif
>  
>  el0_svc_naked:					// compat entry point
>  	stp	x0, xscno, [sp, #S_ORIG_X0]	// save the original x0 and syscall number
> +	isb_if_eqs

As I mentioned before, this is too early.

If we only kick active CPUs, then until we exit a quiescent state, we
can race with concurrent modification, and cannot reliably ensure that
instructions are up-to-date. Practically speaking, that means that we
cannot patch any code used on the path to exit a quiescent state.

Also, if this were needed in the SVC path, it would be necessary for all
exceptions from EL0. Buggy userspace can always trigger a data abort,
even if it doesn't intend to.

>  	enable_daif
>  	ct_user_exit
>  	el0_svc_restore_syscall_args
> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
> index f08a2ed9db0d..74cad496b07b 100644
> --- a/arch/arm64/kernel/process.c
> +++ b/arch/arm64/kernel/process.c
> @@ -88,6 +88,13 @@ void arch_cpu_idle(void)
>  	trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
>  }
>  
> +void arch_cpu_idle_exit(void)
> +{
> +	/* Pairs with aarch64_insn_patch_text() for EQS CPUs. */
> +	if (!rcu_is_watching())
> +		isb();
> +}

Likewise, this is too early as we haven't left the extended quiescent
state yet.

Thanks,
Mark.

^ permalink raw reply

* Re: [PATCH 1/5] arm64: entry: isb in el1_irq
From: Mark Rutland @ 2018-04-06 10:57 UTC (permalink / raw)
  To: Yury Norov
  Cc: Paul E. McKenney, Will Deacon, Chris Metcalf, Christopher Lameter,
	Russell King - ARM Linux, Steven Rostedt, Mathieu Desnoyers,
	Catalin Marinas, Pekka Enberg, David Rientjes, Joonsoo Kim,
	Andrew Morton, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Alexey Klimov, linux-arm-kernel, linuxppc-dev,
	kvm-ppc, linux-mm, linux-kernel
In-Reply-To: <20180405171800.5648-2-ynorov@caviumnetworks.com>

On Thu, Apr 05, 2018 at 08:17:56PM +0300, Yury Norov wrote:
> Kernel text patching framework relies on IPI to ensure that other
> SMP cores observe the change. Target core calls isb() in IPI handler
> path, but not at the beginning of el1_irq entry. There's a chance
> that modified instruction will appear prior isb(), and so will not be
> observed.
> 
> This patch inserts isb early at el1_irq entry to avoid that chance.

As James pointed out, taking an exception is context synchronizing, so
this looks unnecessary.

Also, it's important to realise that the exception entry is not tied to a
specific interrupt. We might take an EL1 IRQ because of a timer interrupt,
then an IPI could be taken before we get to gic_handle_irq().

This means that we can race:

	CPU0				CPU1
	<take IRQ>
	ISB
					<patch text>
					<send IPI>
	<discover IPI pending>

... and thus the ISB is too early.

Only once we're in the interrupt handler can we pair an ISB with the IPI, and
any code executed before that is not guaranteed to be up-to-date.

Thanks,
Mark.

> 
> Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
> ---
>  arch/arm64/kernel/entry.S | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index ec2ee720e33e..9c06b4b80060 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -593,6 +593,7 @@ ENDPROC(el1_sync)
>  
>  	.align	6
>  el1_irq:
> +	isb					// pairs with aarch64_insn_patch_text
>  	kernel_entry 1
>  	enable_da_f
>  #ifdef CONFIG_TRACE_IRQFLAGS
> -- 
> 2.14.1
> 

^ permalink raw reply

* Re: [PATCH 3/5] arm64: early ISB at exit from extended quiescent state
From: James Morse @ 2018-04-06 10:06 UTC (permalink / raw)
  To: Yury Norov
  Cc: Paul E. McKenney, Mark Rutland, Will Deacon, Chris Metcalf,
	Christopher Lameter, Russell King - ARM Linux, Steven Rostedt,
	Mathieu Desnoyers, Catalin Marinas, Pekka Enberg, David Rientjes,
	Joonsoo Kim, Andrew Morton, Benjamin Herrenschmidt,
	Paul Mackerras, Michael Ellerman, Alexey Klimov, linux-arm-kernel,
	linuxppc-dev, kvm-ppc, linux-mm, linux-kernel
In-Reply-To: <20180405171800.5648-4-ynorov@caviumnetworks.com>

Hi Yury,

On 05/04/18 18:17, Yury Norov wrote:
> This series enables delaying of kernel memory synchronization
> for CPUs running in extended quiescent state (EQS) till the exit
> of that state.
> 
> ARM64 uses IPI mechanism to notify all cores in  SMP system that
> kernel text is changed; and IPI handler calls isb() to synchronize.
> 
> If we don't deliver IPI to EQS CPUs anymore, we should add ISB early
> in EQS exit path.
> 
> There are 2 such paths. One starts in do_idle() loop, and other
> in el0_svc entry. For do_idle(), isb() is added in
> arch_cpu_idle_exit() hook. And for SVC handler, isb is called in
> el0_svc_naked.

(I know nothing about this EQS stuff, but) there is a third path that might be
relevant.
>From include/linux/context_tracking.h:guest_enter_irqoff():
|	 * KVM does not hold any references to rcu protected data when it
|	 * switches CPU into a guest mode. In fact switching to a guest mode
|	 * is very similar to exiting to userspace from rcu point of view. In
|	 * addition CPU may stay in a guest mode for quite a long time (up to
|	 * one time slice). Lets treat guest mode as quiescent state, just like
|	 * we do with user-mode execution.

For non-VHE systems guest_enter_irqoff()() is called just before we jump to EL2.
Coming back gives us an exception-return, so we have a context-synchronisation
event there, and I assume we will never patch the hyp-text on these systems.

But with VHE on the upcoming kernel version we still go on to run code at the
same EL. Do we need an ISB on the path back from the guest once we've told RCU
we've 'exited user-space'?
If this code can be patched, do we have a problem here?


> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index c8d9ec363ddd..b1e1c19b4432 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -48,7 +48,7 @@
>  	.endm
>  
>  	.macro el0_svc_restore_syscall_args
> -#if defined(CONFIG_CONTEXT_TRACKING)
> +#if !defined(CONFIG_TINY_RCU) || defined(CONFIG_CONTEXT_TRACKING)
>  	restore_syscall_args
>  #endif
>  	.endm
> @@ -483,6 +483,19 @@ __bad_stack:
>  	ASM_BUG()
>  	.endm
>  
> +/*
> + * If CPU is in extended quiescent state we need isb to ensure that
> + * possible change of kernel text is visible by the core.
> + */
> +	.macro	isb_if_eqs
> +#ifndef CONFIG_TINY_RCU
> +	bl	rcu_is_watching
> +	cbnz	x0, 1f
> +	isb 					// pairs with aarch64_insn_patch_text
> +1:
> +#endif
> +	.endm
> +
>  el0_sync_invalid:
>  	inv_entry 0, BAD_SYNC
>  ENDPROC(el0_sync_invalid)
> @@ -949,6 +962,7 @@ alternative_else_nop_endif
>  
>  el0_svc_naked:					// compat entry point
>  	stp	x0, xscno, [sp, #S_ORIG_X0]	// save the original x0 and syscall number
> +	isb_if_eqs
>  	enable_daif
>  	ct_user_exit
>  	el0_svc_restore_syscall_args

Shouldn't this be at the point that RCU knows we've exited user-space? Otherwise
there is a gap where RCU thinks we're in user-space, we're not, and we're about
to tell it. Code-patching occurring in this gap would be missed.

This gap only contains 'enable_daif', and any exception that occurs here is
safe, but its going to give someone a nasty surprise...

Mark points out this ISB needs to be after RCU knows we're not quiescent:
https://lkml.org/lkml/2018/4/3/378

Can't this go in the rcu exit-quiescence code? Isn't this what your
rcu_dynticks_eqs_exit_sync() hook does?


Thanks,

James

^ permalink raw reply

* Re: [PATCH 1/5] arm64: entry: isb in el1_irq
From: James Morse @ 2018-04-06 10:02 UTC (permalink / raw)
  To: Yury Norov
  Cc: Paul E. McKenney, Mark Rutland, Will Deacon, Chris Metcalf,
	Christopher Lameter, Russell King - ARM Linux, Steven Rostedt,
	Mathieu Desnoyers, Catalin Marinas, Pekka Enberg, David Rientjes,
	Joonsoo Kim, Andrew Morton, Benjamin Herrenschmidt,
	Paul Mackerras, Michael Ellerman, Alexey Klimov, linux-arm-kernel,
	linuxppc-dev, kvm-ppc, linux-mm, linux-kernel
In-Reply-To: <20180405171800.5648-2-ynorov@caviumnetworks.com>

Hi Yury,

On 05/04/18 18:17, Yury Norov wrote:
> Kernel text patching framework relies on IPI to ensure that other
> SMP cores observe the change. Target core calls isb() in IPI handler

(Odd, if its just to synchronize the CPU, taking the IPI should be enough).


> path, but not at the beginning of el1_irq entry. There's a chance
> that modified instruction will appear prior isb(), and so will not be
> observed.
> 
> This patch inserts isb early at el1_irq entry to avoid that chance.


> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index ec2ee720e33e..9c06b4b80060 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -593,6 +593,7 @@ ENDPROC(el1_sync)
>  
>  	.align	6
>  el1_irq:
> +	isb					// pairs with aarch64_insn_patch_text
>  	kernel_entry 1
>  	enable_da_f
>  #ifdef CONFIG_TRACE_IRQFLAGS
> 

An ISB at the beginning of the vectors? This is odd, taking an IRQ to get in
here would be a context-synchronization-event too, so the ISB is superfluous.

The ARM-ARM  has a list of 'Context-Synchronization event's (Glossary on page
6480 of DDI0487B.b), paraphrasing:
* ISB
* Taking an exception
* ERET
* (...loads of debug stuff...)


Thanks,

James

^ permalink raw reply

* Re: [RESEND 2/3] powerpc/memcpy: Add memcpy_mcsafe for pmem
From: Balbir Singh @ 2018-04-06  9:25 UTC (permalink / raw)
  To: Nicholas Piggin
  Cc: Jeff Moyer, Luck, Tony, Matthew Wilcox, Michael Ellerman,
	linux-nvdimm, linuxppc-dev, Christoph Hellwig
In-Reply-To: <20180406112600.454432f0@roar.ozlabs.ibm.com>

On Fri, Apr 6, 2018 at 11:26 AM, Nicholas Piggin <npiggin@gmail.com> wrote:
> On Thu, 05 Apr 2018 16:40:26 -0400
> Jeff Moyer <jmoyer@redhat.com> wrote:
>
>> Nicholas Piggin <npiggin@gmail.com> writes:
>>
>> > On Thu, 5 Apr 2018 15:53:07 +1000
>> > Balbir Singh <bsingharora@gmail.com> wrote:
>> >> I'm thinking about it, I wonder what "bytes remaining" mean in pmem context
>> >> in the context of a machine check exception. Also, do we want to be byte
>> >> accurate or cache-line accurate for the bytes remaining? The former is much
>> >> easier than the latter :)
>> >
>> > The ideal would be a linear measure of how much of your copy reached
>> > (or can reach) non-volatile storage with nothing further copied. You
>> > may have to allow for some relaxing of the semantics depending on
>> > what the architecture can support.
>>
>> I think you've got that backwards.  memcpy_mcsafe is used to copy *from*
>> persistent memory.  The idea is to catch errors when reading pmem, not
>> writing to it.
>>

I know the comment in x86 says posted writes and cares for only loads, but I
don't see why both sides should not be handled.

>> > What's the problem with just counting bytes copied like usercopy --
>> > why is that harder than cacheline accuracy?
>>
>> He said the former (i.e. bytes) is easier.  So, I think you're on the
>> same page.  :)
>
> Oh well that makes a lot more sense in my mind now, thanks :)

I thought the cache-aligned might make sense, since usually we'd expect the
failure to be at a cache-line level, but our copy_tofrom_user does accurate
accounting

Balbir Singh.

^ permalink raw reply

* Re: [RFC] virtio: Use DMA MAP API for devices without an IOMMU
From: Benjamin Herrenschmidt @ 2018-04-06  8:37 UTC (permalink / raw)
  To: Christoph Hellwig, Anshuman Khandual
  Cc: Michael S. Tsirkin, robh, aik, jasowang, linux-kernel,
	virtualization, joe, david, linuxppc-dev, elfring
In-Reply-To: <20180406071634.GA31108@infradead.org>

On Fri, 2018-04-06 at 00:16 -0700, Christoph Hellwig wrote:
> On Fri, Apr 06, 2018 at 08:23:10AM +0530, Anshuman Khandual wrote:
> > On 04/06/2018 02:48 AM, Benjamin Herrenschmidt wrote:
> > > On Thu, 2018-04-05 at 21:34 +0300, Michael S. Tsirkin wrote:
> > > > > In this specific case, because that would make qemu expect an iommu,
> > > > > and there isn't one.
> > > > 
> > > > 
> > > > I think that you can set iommu_platform in qemu without an iommu.
> > > 
> > > No I mean the platform has one but it's not desirable for it to be used
> > > due to the performance hit.
> > 
> > Also the only requirement is to bounce the I/O buffers through SWIOTLB
> > implemented as DMA API which the virtio core understands. There is no
> > need for an IOMMU to be involved for the device representation in this
> > case IMHO.
> 
> This whole virtio translation issue is a mess.  I think we need to
> switch it to the dma API, and then quirk the legacy case to always
> use the direct mapping inside the dma API.

Fine with using a dma API always on the Linux side, but we do want to
special case virtio still at the arch and qemu side to have a "direct
mapping" mode. Not sure how (special flags on PCI devices) to avoid
actually going through an emulated IOMMU on the qemu side, because that
slows things down, esp. with vhost.

IE, we can't I think just treat it the same as a physical device.

Cheers,
Ben.

^ permalink raw reply

* Re: [RFC] virtio: Use DMA MAP API for devices without an IOMMU
From: Christoph Hellwig @ 2018-04-06  7:16 UTC (permalink / raw)
  To: Anshuman Khandual
  Cc: Benjamin Herrenschmidt, Michael S. Tsirkin, robh, aik, jasowang,
	linux-kernel, virtualization, joe, david, linuxppc-dev, elfring
In-Reply-To: <70cb433f-a8f7-5199-3c96-a760c7624804@linux.vnet.ibm.com>

On Fri, Apr 06, 2018 at 08:23:10AM +0530, Anshuman Khandual wrote:
> On 04/06/2018 02:48 AM, Benjamin Herrenschmidt wrote:
> > On Thu, 2018-04-05 at 21:34 +0300, Michael S. Tsirkin wrote:
> >>> In this specific case, because that would make qemu expect an iommu,
> >>> and there isn't one.
> >>
> >>
> >> I think that you can set iommu_platform in qemu without an iommu.
> > 
> > No I mean the platform has one but it's not desirable for it to be used
> > due to the performance hit.
> 
> Also the only requirement is to bounce the I/O buffers through SWIOTLB
> implemented as DMA API which the virtio core understands. There is no
> need for an IOMMU to be involved for the device representation in this
> case IMHO.

This whole virtio translation issue is a mess.  I think we need to
switch it to the dma API, and then quirk the legacy case to always
use the direct mapping inside the dma API.

^ permalink raw reply

* Re: [PATCH 2/2] KVM: PPC: Book3S HV: lockless tlbie for HPT hcalls
From: Michael Ellerman @ 2018-04-06  6:12 UTC (permalink / raw)
  To: Nicholas Piggin, kvm-ppc; +Cc: linuxppc-dev, Nicholas Piggin
In-Reply-To: <20180405175631.31381-3-npiggin@gmail.com>

Nicholas Piggin <npiggin@gmail.com> writes:
> diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
> index 78e6a392330f..0221a0f74f07 100644
> --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
> +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
> @@ -439,6 +439,9 @@ static inline int try_lock_tlbie(unsigned int *lock)
>  	unsigned int tmp, old;
>  	unsigned int token = LOCK_TOKEN;
>  
> +	if (mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE))
> +		return 1;
> +
>  	asm volatile("1:lwarx	%1,0,%2\n"
>  		     "	cmpwi	cr0,%1,0\n"
>  		     "	bne	2f\n"
> @@ -452,6 +455,12 @@ static inline int try_lock_tlbie(unsigned int *lock)
>  	return old == 0;
>  }
>  
> +static inline void unlock_tlbie_after_sync(unsigned int *lock)
> +{
> +	if (mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE))
> +		return;
> +}

So this is a bit hard to follow:

#define MMU_FTRS_DEFAULT_HPTE_ARCH_V2	\
	MMU_FTR_HPTE_TABLE | MMU_FTR_PPCAS_ARCH_V2
#define MMU_FTRS_POWER		MMU_FTRS_DEFAULT_HPTE_ARCH_V2
#define MMU_FTRS_PPC970		MMU_FTRS_POWER | MMU_FTR_TLBIE_CROP_VA			// does NOT
#define MMU_FTRS_POWER5		MMU_FTRS_POWER | MMU_FTR_LOCKLESS_TLBIE
#define MMU_FTRS_POWER6		MMU_FTRS_POWER5 | MMU_FTR_KERNEL_RO | MMU_FTR_68_BIT_VA	// includes lockless TLBIE
#define MMU_FTRS_POWER7		MMU_FTRS_POWER6						// includes lockless TLBIE
#define MMU_FTRS_POWER8		MMU_FTRS_POWER6						// includes lockless TLBIE
#define MMU_FTRS_POWER9		MMU_FTRS_POWER6						// includes lockless TLBIE
#define MMU_FTRS_CELL		MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | 			// does NOT
				MMU_FTR_CI_LARGE_PAGE
#define MMU_FTRS_PA6T		MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \			// does NOT
				MMU_FTR_CI_LARGE_PAGE | MMU_FTR_NO_SLBIE_B


So it's only 970, Cell and Pasemi that *don't* have lockless TLBIE.

And KVM HV doesn't doesn't run on any of those.

So we can just not check for the feature in the KVM HV code.

Am I right?

cheers

^ permalink raw reply

* Re: [PATCH 2/2] KVM: PPC: Book3S HV: lockless tlbie for HPT hcalls
From: Nicholas Piggin @ 2018-04-06  5:39 UTC (permalink / raw)
  To: kvm-ppc; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <20180405175631.31381-3-npiggin@gmail.com>

On Fri,  6 Apr 2018 03:56:31 +1000
Nicholas Piggin <npiggin@gmail.com> wrote:

> tlbies to an LPAR do not have to be serialised since POWER4,
> MMU_FTR_LOCKLESS_TLBIE can be used to avoid the spin lock in
> do_tlbies.
> 
> Testing was done on a POWER9 system in HPT mode, with a -smp 32 guest
> in HPT mode. 32 instances of the powerpc fork benchmark from selftests
> were run with --fork, and the results measured.
> 
> Without this patch, total throughput was about 13.5K/sec, and this is
> the top of the host profile:
> 
>    74.52%  [k] do_tlbies
>     2.95%  [k] kvmppc_book3s_hv_page_fault
>     1.80%  [k] calc_checksum
>     1.80%  [k] kvmppc_vcpu_run_hv
>     1.49%  [k] kvmppc_run_core
> 
> After this patch, throughput was about 51K/sec, with this profile:
> 
>    21.28%  [k] do_tlbies
>     5.26%  [k] kvmppc_run_core
>     4.88%  [k] kvmppc_book3s_hv_page_fault
>     3.30%  [k] _raw_spin_lock_irqsave
>     3.25%  [k] gup_pgd_range
> 
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> ---
>  arch/powerpc/kvm/book3s_hv_rm_mmu.c | 11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
> index 78e6a392330f..0221a0f74f07 100644
> --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
> +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
> @@ -439,6 +439,9 @@ static inline int try_lock_tlbie(unsigned int *lock)
>  	unsigned int tmp, old;
>  	unsigned int token = LOCK_TOKEN;
>  
> +	if (mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE))
> +		return 1;
> +
>  	asm volatile("1:lwarx	%1,0,%2\n"
>  		     "	cmpwi	cr0,%1,0\n"
>  		     "	bne	2f\n"
> @@ -452,6 +455,12 @@ static inline int try_lock_tlbie(unsigned int *lock)
>  	return old == 0;
>  }
>  
> +static inline void unlock_tlbie_after_sync(unsigned int *lock)
> +{
> +	if (mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE))
> +		return;
> +}
> +
>  static void do_tlbies(struct kvm *kvm, unsigned long *rbvalues,
>  		      long npages, int global, bool need_sync)
>  {
> @@ -483,7 +492,7 @@ static void do_tlbies(struct kvm *kvm, unsigned long *rbvalues,
>  		}
>  
>  		asm volatile("eieio; tlbsync; ptesync" : : : "memory");
> -		kvm->arch.tlbie_lock = 0;
> +		unlock_tlbie_after_sync(&kvm->arch.tlbie_lock);

Well that's a silly bug in the !LOCKLESS path, that was supposed
to move to unlock, of course. Will fix it up after some time for
comments.

Thanks,
Nick

^ permalink raw reply

* [PATCH 2/2] powerpc/mm/memtrace: Let the arch hotunplug code flush cache
From: Balbir Singh @ 2018-04-06  5:24 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: mpe, rashmica.g, benh, Balbir Singh
In-Reply-To: <20180406052424.29841-1-bsingharora@gmail.com>

Don't do this via custom code, instead now that we have support
in the arch hotplug/hotunplug code, rely on those routines
to do the right thing.

Fixes: 9d5171a8f248 ("powerpc/powernv: Enable removal of memory for in memory tracing")
because the older code uses ppc64_caches.l1d.size instead of
ppc64_caches.l1d.line_size

Signed-off-by: Balbir Singh <bsingharora@gmail.com>
---
 arch/powerpc/platforms/powernv/memtrace.c | 17 -----------------
 1 file changed, 17 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/memtrace.c b/arch/powerpc/platforms/powernv/memtrace.c
index de470caf0784..fc222a0c2ac4 100644
--- a/arch/powerpc/platforms/powernv/memtrace.c
+++ b/arch/powerpc/platforms/powernv/memtrace.c
@@ -82,19 +82,6 @@ static const struct file_operations memtrace_fops = {
 	.open	= simple_open,
 };
 
-static void flush_memory_region(u64 base, u64 size)
-{
-	unsigned long line_size = ppc64_caches.l1d.size;
-	u64 end = base + size;
-	u64 addr;
-
-	base = round_down(base, line_size);
-	end = round_up(end, line_size);
-
-	for (addr = base; addr < end; addr += line_size)
-		asm volatile("dcbf 0,%0" : "=r" (addr) :: "memory");
-}
-
 static int check_memblock_online(struct memory_block *mem, void *arg)
 {
 	if (mem->state != MEM_ONLINE)
@@ -132,10 +119,6 @@ static bool memtrace_offline_pages(u32 nid, u64 start_pfn, u64 nr_pages)
 	walk_memory_range(start_pfn, end_pfn, (void *)MEM_OFFLINE,
 			  change_memblock_state);
 
-	/* RCU grace period? */
-	flush_memory_region((u64)__va(start_pfn << PAGE_SHIFT),
-			    nr_pages << PAGE_SHIFT);
-
 	lock_device_hotplug();
 	remove_memory(nid, start_pfn << PAGE_SHIFT, nr_pages << PAGE_SHIFT);
 	unlock_device_hotplug();
-- 
2.13.6

^ permalink raw reply related

* [PATCH 1/2] powerpc/mm: Flush cache on memory hot(un)plug
From: Balbir Singh @ 2018-04-06  5:24 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: mpe, rashmica.g, benh, Balbir Singh

This patch adds support for flushing potentially dirty
cache lines when memory is hot-plugged/hot-un-plugged.
The support is currently limited to 64 bit systems.

The bug was exposed when mappings for a device were
actually hot-unplugged and plugged in back later.
A similar issue was observed during the development
of memtrace, but memtrace does it's own flushing of
region via a custom routine.

These patches do a flush both on hotplug/unplug to
clear any stale data in the cache w.r.t mappings,
there is a small race window where a clean cache
line may be created again just prior to tearing
down the mapping.

The patches were tested by disabling the flush
routines in memtrace and doing I/O on the trace
file. The system immediately checkstops (quite
reliablly if prior to the hot-unplug of the memtrace
region, we memset the regions we are about to
hot unplug). After these patches no custom flushing
is needed in the memtrace code.

Signed-off-by: Balbir Singh <bsingharora@gmail.com>
---
 arch/powerpc/mm/mem.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 85245ef97e72..0a8959b15b39 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -143,6 +143,7 @@ int __meminit arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *
 			start, start + size, rc);
 		return -EFAULT;
 	}
+	flush_inval_dcache_range(start, start + size);
 
 	return __add_pages(nid, start_pfn, nr_pages, altmap, want_memblock);
 }
@@ -169,6 +170,7 @@ int __meminit arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap
 
 	/* Remove htab bolted mappings for this section of memory */
 	start = (unsigned long)__va(start);
+	flush_inval_dcache_range(start, start + size);
 	ret = remove_section_mapping(start, start + size);
 
 	/* Ensure all vmalloc mappings are flushed in case they also
-- 
2.13.6

^ permalink raw reply related

* [PATCH v3 4/4] powerpc/powernv: Create platform devs for nvdimm buses
From: Oliver O'Halloran @ 2018-04-06  5:21 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: linux-nvdimm, Oliver O'Halloran
In-Reply-To: <20180406052116.31483-1-oohall@gmail.com>

Scan the devicetree for an nvdimm-bus compatible and create
a platform device for them.

Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
---
 arch/powerpc/platforms/powernv/opal.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index c15182765ff5..c37485a3c5c9 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -821,6 +821,9 @@ static int __init opal_init(void)
 	/* Create i2c platform devices */
 	opal_pdev_init("ibm,opal-i2c");
 
+	/* Handle non-volatile memory devices */
+	opal_pdev_init("pmem-region");
+
 	/* Setup a heatbeat thread if requested by OPAL */
 	opal_init_heartbeat();
 
-- 
2.9.5

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox