LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 3/4] perf/POWER7: Make event translations available in sysfs
From: Sukadev Bhattiprolu @ 2012-11-14 18:20 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Peter Zijlstra, robert.richter, Anton Blanchard, linux-kernel,
	linuxppc-dev, Ingo Molnar, Paul Mackerras,
	Arnaldo Carvalho de Melo
In-Reply-To: <20121114102534.GA2220@krava.brq.redhat.com>

Jiri Olsa [jolsa@redhat.com] wrote:
| On Wed, Nov 07, 2012 at 11:19:28AM -0800, Sukadev Bhattiprolu wrote:
| 
| SNIP
| 
| > +struct perf_pmu_events_attr {
| > +	struct device_attribute attr;
| > +	u64 id;
| > +};
| > +
| > +extern ssize_t power_events_sysfs_show(struct device *dev,
| > +				struct device_attribute *attr, char *page);
| > +
| > +#define EVENT_VAR(_id)	event_attr_##_id
| > +#define EVENT_PTR(_id) &event_attr_##_id.attr.attr
| > +
| > +#define EVENT_ATTR(_name, _id)                                             \
| > +	static struct perf_pmu_events_attr EVENT_VAR(_id) = {              \
| > +		.attr = __ATTR(_name, 0444, power_events_sysfs_show, NULL),\
| > +		.id   = PM_##_id,                                               \
| > +	};
| 
| this is duplicating the x86 code, perhaps it could be moved
| to include/linux/perf_event.h and shared globaly

Ok.

Can we remove the assumption that the event id is a generic event that
has PERF_COUNT_HW_ prefix and also let the architectures pass in a "show"
function ? This would allow architectures to display any arch specific
events that don't yet have a generic counterpart.

IOW, can we do something like this (untested) and make PERF_EVENT_ATTR global:



diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 4428fd1..25298f7 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -1354,12 +1354,15 @@ static ssize_t events_sysfs_show(struct device *dev, struct device_attribute *at
 #define EVENT_VAR(_id)  event_attr_##_id
 #define EVENT_PTR(_id) &event_attr_##_id.attr.attr

-#define EVENT_ATTR(_name, _id)                                 \
+#define PERF_EVENT_ATTR(_name, _id, _show)                     \
 static struct perf_pmu_events_attr EVENT_VAR(_id) = {          \
-       .attr = __ATTR(_name, 0444, events_sysfs_show, NULL),   \
-       .id   =  PERF_COUNT_HW_##_id,                           \
+       .attr = __ATTR(_name, 0444, _show, NULL),               \
+       .id   =  _id,                                           \
 };

+#define EVENT_ATTR(_name, _id)                                         \
+       PERF_EVENT_ATTR(_name, PERF_COUNT_HW_##_id, events_sysfs_show)
+
 EVENT_ATTR(cpu-cycles,                 CPU_CYCLES              );
 EVENT_ATTR(instructions,               INSTRUCTIONS            );
 EVENT_ATTR(cache-references,           CACHE_REFERENCES        );

| 
| 
| > diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
| > index aa2465e..19b23bd 100644
| > --- a/arch/powerpc/perf/core-book3s.c
| > +++ b/arch/powerpc/perf/core-book3s.c
| > @@ -1305,6 +1305,16 @@ static int power_pmu_event_idx(struct perf_event *event)
| >  	return event->hw.idx;
| >  }
| >  
| > +ssize_t power_events_sysfs_show(struct device *dev,
| > +				struct device_attribute *attr, char *page)
| > +{
| > +       struct perf_pmu_events_attr *pmu_attr;
| > +       
| > +       pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
| > +        
| > +       return sprintf(page, "event=0x%02llx\n", pmu_attr->id);
| 
| whitespace issues

Will fix. Thanks for the review.

Sukadev

^ permalink raw reply related

* Re: [PATCH] TTY: hvc_console, fix port reference count going to zero prematurely
From: Benjamin Herrenschmidt @ 2012-11-14 20:48 UTC (permalink / raw)
  To: Greg KH; +Cc: linuxppc-dev, Paul Mackerras, Jiri Slaby, anton, alan
In-Reply-To: <20121114150901.GA2371@kroah.com>

On Wed, 2012-11-14 at 07:09 -0800, Greg KH wrote:
> > So who's merging it ?
> 
> Give me a chance to at least wake up please :)

Sure ;-) Just asking since I'm about to cook up a powerpc batch :-)

> I will.

Thanks ! It should go into stable 3.6 as well.

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH] TTY: hvc_console, fix port reference count going to zero prematurely
From: Greg KH @ 2012-11-14 20:54 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linuxppc-dev, Paul Mackerras, Jiri Slaby, anton, alan
In-Reply-To: <1352926097.23412.24.camel@pasglop>

On Thu, Nov 15, 2012 at 07:48:17AM +1100, Benjamin Herrenschmidt wrote:
> On Wed, 2012-11-14 at 07:09 -0800, Greg KH wrote:
> > > So who's merging it ?
> > 
> > Give me a chance to at least wake up please :)
> 
> Sure ;-) Just asking since I'm about to cook up a powerpc batch :-)

It's now in my tree, and will get to Linus in time for 3.7.

> > I will.
> 
> Thanks ! It should go into stable 3.6 as well.

Why?  The offending patch didn't show up until 3.7-rc1.

thanks,

greg k-h

^ permalink raw reply

* Re: [PATCH] TTY: hvc_console, fix port reference count going to zero prematurely
From: Benjamin Herrenschmidt @ 2012-11-14 20:57 UTC (permalink / raw)
  To: Greg KH; +Cc: linuxppc-dev, Paul Mackerras, Jiri Slaby, anton, alan
In-Reply-To: <20121114205407.GA7937@kroah.com>

On Wed, 2012-11-14 at 12:54 -0800, Greg KH wrote:
> > Thanks ! It should go into stable 3.6 as well.
> 
> Why?  The offending patch didn't show up until 3.7-rc1.

Ah, my bad, I though Paulus had observed the problem with 3.6 as well
but it looks like you are right. So 3.7 then.

Thanks.

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH] TTY: hvc_console, fix port reference count going to zero prematurely
From: Paul Mackerras @ 2012-11-14 23:02 UTC (permalink / raw)
  To: Greg KH; +Cc: linuxppc-dev, Jiri Slaby, anton, alan
In-Reply-To: <20121114205407.GA7937@kroah.com>

On Wed, Nov 14, 2012 at 12:54:07PM -0800, Greg KH wrote:
> On Thu, Nov 15, 2012 at 07:48:17AM +1100, Benjamin Herrenschmidt wrote:
> > On Wed, 2012-11-14 at 07:09 -0800, Greg KH wrote:
> > > > So who's merging it ?
> > > 
> > > Give me a chance to at least wake up please :)
> > 
> > Sure ;-) Just asking since I'm about to cook up a powerpc batch :-)
> 
> It's now in my tree, and will get to Linus in time for 3.7.

Turns out I stuffed up the commit message a bit, I talk about kref_put
and tty_kref_put when I should be talking about tty_port_put.  If
there is still a chance to update the commit message, that would be
good.  The patch itself is correct.

> > > I will.
> > 
> > Thanks ! It should go into stable 3.6 as well.
> 
> Why?  The offending patch didn't show up until 3.7-rc1.

Yes.  I had thought it was in 3.6 but it isn't.

Paul.

^ permalink raw reply

* Re: [PATCH 1/6] powerpc: Move branch instruction from ACCOUNT_CPU_USER_ENTRY to caller
From: Benjamin Herrenschmidt @ 2012-11-15  0:40 UTC (permalink / raw)
  To: Haren Myneni; +Cc: linuxppc-dev, mikey, anton, paulus
In-Reply-To: <1351666269.32304.12.camel@hbabu-laptop>

On Tue, 2012-10-30 at 23:51 -0700, Haren Myneni wrote:
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -159,8 +159,9 @@ exc_##n##_common:                                                       \
        std     r9,GPR9(r1);            /* save r9 in stackframe */         \
        std     r10,_NIP(r1);           /* save SRR0 to stackframe */       \
        std     r11,_MSR(r1);           /* save SRR1 to stackframe */       \
+       beq     1f                      /* if from kernel mode */

Missing semicolon

        ACCOUNT_CPU_USER_ENTRY(r10,r11);/* accounting (uses cr0+eq) */      \
-       ld      r3,excf+EX_R10(r13);    /* get back r10 */                  \
+1:     ld      r3,excf+EX_R10(r13);    /* get back r10 */                  \
        ld      r4,excf+EX_R11(r13);    /* get back r11 */                  \
        mfspr   r5,SPRN_SPRG_GEN_SCRATCH;/* get back r13 */                 \
        std     r12,GPR12(r1);          /* save r12 in stackframe */        \


Please , please, please ... at the very least TEST BUILD the stuff you
change... I'm fixing that one up here this time.

Ben.

^ permalink raw reply

* Re: [PATCH 1/6] powerpc: Move branch instruction from ACCOUNT_CPU_USER_ENTRY to caller
From: Benjamin Herrenschmidt @ 2012-11-15  1:03 UTC (permalink / raw)
  To: Haren Myneni; +Cc: linuxppc-dev, mikey, anton, paulus
In-Reply-To: <1352940045.23412.38.camel@pasglop>

On Thu, 2012-11-15 at 11:40 +1100, Benjamin Herrenschmidt wrote:
On Tue, 2012-10-30 at 23:51 -0700, Haren Myneni wrote:
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -159,8 +159,9 @@ exc_##n##_common:                                                       \
        std     r9,GPR9(r1);            /* save r9 in stackframe */         \
        std     r10,_NIP(r1);           /* save SRR0 to stackframe */       \
        std     r11,_MSR(r1);           /* save SRR1 to stackframe */       \
+       beq     1f                      /* if from kernel mode */

Missing semicolon 

Ok, that's not enough. Please test & fix & resend.

Cheers,
Ben.

^ permalink raw reply

* [PATCH] cpuidle: Measure idle state durations with monotonic clock
From: Julius Werner @ 2012-11-15  1:56 UTC (permalink / raw)
  To: linux-kernel
  Cc: Kevin Hilman, Deepthi Dharwar, Trinabh Gupta, Lists Linaro-dev,
	linux-pm, Daniel Lezcano, Rafael J. Wysocki, linux-acpi,
	Srivatsa S. Bhat, Julius Werner, Andrew Morton, linuxppc-dev,
	Sameer Nanda, Len Brown
In-Reply-To: <CAODwPW873M32d9zFT9fpJT9+PuMbz8htzUxdF1TNE+J1zR3jYA@mail.gmail.com>

Many cpuidle drivers measure their time spent in an idle state by
reading the wallclock time before and after idling and calculating the
difference. This leads to erroneous results when the wallclock time gets
updated by another processor in the meantime, adding that clock
adjustment to the idle state's time counter.

If the clock adjustment was negative, the result is even worse due to an
erroneous cast from int to unsigned long long of the last_residency
variable. The negative 32 bit integer will zero-extend and result in a
forward time jump of roughly four billion milliseconds or 1.3 hours on
the idle state residency counter.

This patch changes all affected cpuidle drivers to either use the
monotonic clock for their measurements or make use of the generic time
measurement wrapper in cpuidle.c, which was already working correctly.
Some superfluous CLIs/STIs in the ACPI code are removed (interrupts
should always already be disabled before entering the idle function, and
not get reenabled until the generic wrapper has performed its second
measurement). It also removes the erroneous cast, making sure that
negative residency values are applied correctly even though they should
not appear anymore.

Signed-off-by: Julius Werner <jwerner@chromium.org>
---
 arch/powerpc/platforms/pseries/processor_idle.c |    4 +-
 drivers/acpi/processor_idle.c                   |   57 +---------------------
 drivers/cpuidle/cpuidle.c                       |    3 +-
 drivers/idle/intel_idle.c                       |   14 +-----
 4 files changed, 7 insertions(+), 71 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c
index 45d00e5..4d806b4 100644
--- a/arch/powerpc/platforms/pseries/processor_idle.c
+++ b/arch/powerpc/platforms/pseries/processor_idle.c
@@ -36,7 +36,7 @@ static struct cpuidle_state *cpuidle_state_table;
 static inline void idle_loop_prolog(unsigned long *in_purr, ktime_t *kt_before)
 {
 
-	*kt_before = ktime_get_real();
+	*kt_before = ktime_get();
 	*in_purr = mfspr(SPRN_PURR);
 	/*
 	 * Indicate to the HV that we are idle. Now would be
@@ -50,7 +50,7 @@ static inline  s64 idle_loop_epilog(unsigned long in_purr, ktime_t kt_before)
 	get_lppaca()->wait_state_cycles += mfspr(SPRN_PURR) - in_purr;
 	get_lppaca()->idle = 0;
 
-	return ktime_to_us(ktime_sub(ktime_get_real(), kt_before));
+	return ktime_to_us(ktime_sub(ktime_get(), kt_before));
 }
 
 static int snooze_loop(struct cpuidle_device *dev,
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index e8086c7..f1a5da4 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -735,31 +735,18 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx)
 static int acpi_idle_enter_c1(struct cpuidle_device *dev,
 		struct cpuidle_driver *drv, int index)
 {
-	ktime_t  kt1, kt2;
-	s64 idle_time;
 	struct acpi_processor *pr;
 	struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
 	struct acpi_processor_cx *cx = cpuidle_get_statedata(state_usage);
 
 	pr = __this_cpu_read(processors);
-	dev->last_residency = 0;
 
 	if (unlikely(!pr))
 		return -EINVAL;
 
-	local_irq_disable();
-
-
 	lapic_timer_state_broadcast(pr, cx, 1);
-	kt1 = ktime_get_real();
 	acpi_idle_do_entry(cx);
-	kt2 = ktime_get_real();
-	idle_time =  ktime_to_us(ktime_sub(kt2, kt1));
-
-	/* Update device last_residency*/
-	dev->last_residency = (int)idle_time;
 
-	local_irq_enable();
 	lapic_timer_state_broadcast(pr, cx, 0);
 
 	return index;
@@ -806,19 +793,12 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
 	struct acpi_processor *pr;
 	struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
 	struct acpi_processor_cx *cx = cpuidle_get_statedata(state_usage);
-	ktime_t  kt1, kt2;
-	s64 idle_time_ns;
-	s64 idle_time;
 
 	pr = __this_cpu_read(processors);
-	dev->last_residency = 0;
 
 	if (unlikely(!pr))
 		return -EINVAL;
 
-	local_irq_disable();
-
-
 	if (cx->entry_method != ACPI_CSTATE_FFH) {
 		current_thread_info()->status &= ~TS_POLLING;
 		/*
@@ -829,7 +809,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
 
 		if (unlikely(need_resched())) {
 			current_thread_info()->status |= TS_POLLING;
-			local_irq_enable();
 			return -EINVAL;
 		}
 	}
@@ -843,22 +822,12 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
 	if (cx->type == ACPI_STATE_C3)
 		ACPI_FLUSH_CPU_CACHE();
 
-	kt1 = ktime_get_real();
 	/* Tell the scheduler that we are going deep-idle: */
 	sched_clock_idle_sleep_event();
 	acpi_idle_do_entry(cx);
-	kt2 = ktime_get_real();
-	idle_time_ns = ktime_to_ns(ktime_sub(kt2, kt1));
-	idle_time = idle_time_ns;
-	do_div(idle_time, NSEC_PER_USEC);
 
-	/* Update device last_residency*/
-	dev->last_residency = (int)idle_time;
+	sched_clock_idle_wakeup_event(0);
 
-	/* Tell the scheduler how much we idled: */
-	sched_clock_idle_wakeup_event(idle_time_ns);
-
-	local_irq_enable();
 	if (cx->entry_method != ACPI_CSTATE_FFH)
 		current_thread_info()->status |= TS_POLLING;
 
@@ -883,13 +852,8 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
 	struct acpi_processor *pr;
 	struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
 	struct acpi_processor_cx *cx = cpuidle_get_statedata(state_usage);
-	ktime_t  kt1, kt2;
-	s64 idle_time_ns;
-	s64 idle_time;
-
 
 	pr = __this_cpu_read(processors);
-	dev->last_residency = 0;
 
 	if (unlikely(!pr))
 		return -EINVAL;
@@ -899,16 +863,11 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
 			return drv->states[drv->safe_state_index].enter(dev,
 						drv, drv->safe_state_index);
 		} else {
-			local_irq_disable();
 			acpi_safe_halt();
-			local_irq_enable();
 			return -EBUSY;
 		}
 	}
 
-	local_irq_disable();
-
-
 	if (cx->entry_method != ACPI_CSTATE_FFH) {
 		current_thread_info()->status &= ~TS_POLLING;
 		/*
@@ -919,7 +878,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
 
 		if (unlikely(need_resched())) {
 			current_thread_info()->status |= TS_POLLING;
-			local_irq_enable();
 			return -EINVAL;
 		}
 	}
@@ -934,7 +892,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
 	 */
 	lapic_timer_state_broadcast(pr, cx, 1);
 
-	kt1 = ktime_get_real();
 	/*
 	 * disable bus master
 	 * bm_check implies we need ARB_DIS
@@ -965,18 +922,9 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
 		c3_cpu_count--;
 		raw_spin_unlock(&c3_lock);
 	}
-	kt2 = ktime_get_real();
-	idle_time_ns = ktime_to_ns(ktime_sub(kt2, kt1));
-	idle_time = idle_time_ns;
-	do_div(idle_time, NSEC_PER_USEC);
-
-	/* Update device last_residency*/
-	dev->last_residency = (int)idle_time;
 
-	/* Tell the scheduler how much we idled: */
-	sched_clock_idle_wakeup_event(idle_time_ns);
+	sched_clock_idle_wakeup_event(0);
 
-	local_irq_enable();
 	if (cx->entry_method != ACPI_CSTATE_FFH)
 		current_thread_info()->status |= TS_POLLING;
 
@@ -987,6 +935,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
 struct cpuidle_driver acpi_idle_driver = {
 	.name =		"acpi_idle",
 	.owner =	THIS_MODULE,
+	.en_core_tk_irqen = 1,
 };
 
 /**
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 7f15b85..1536edd 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -109,8 +109,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
 		/* This can be moved to within driver enter routine
 		 * but that results in multiple copies of same code.
 		 */
-		dev->states_usage[entered_state].time +=
-				(unsigned long long)dev->last_residency;
+		dev->states_usage[entered_state].time += dev->last_residency;
 		dev->states_usage[entered_state].usage++;
 	} else {
 		dev->last_residency = 0;
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index b0f6b4c..c49c04d 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -56,7 +56,6 @@
 #include <linux/kernel.h>
 #include <linux/cpuidle.h>
 #include <linux/clockchips.h>
-#include <linux/hrtimer.h>	/* ktime_get_real() */
 #include <trace/events/power.h>
 #include <linux/sched.h>
 #include <linux/notifier.h>
@@ -72,6 +71,7 @@
 static struct cpuidle_driver intel_idle_driver = {
 	.name = "intel_idle",
 	.owner = THIS_MODULE,
+	.en_core_tk_irqen = 1,
 };
 /* intel_idle.max_cstate=0 disables driver */
 static int max_cstate = MWAIT_MAX_NUM_CSTATES - 1;
@@ -281,8 +281,6 @@ static int intel_idle(struct cpuidle_device *dev,
 	struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
 	unsigned long eax = (unsigned long)cpuidle_get_statedata(state_usage);
 	unsigned int cstate;
-	ktime_t kt_before, kt_after;
-	s64 usec_delta;
 	int cpu = smp_processor_id();
 
 	cstate = (((eax) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK) + 1;
@@ -297,8 +295,6 @@ static int intel_idle(struct cpuidle_device *dev,
 	if (!(lapic_timer_reliable_states & (1 << (cstate))))
 		clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
 
-	kt_before = ktime_get_real();
-
 	stop_critical_timings();
 	if (!need_resched()) {
 
@@ -310,17 +306,9 @@ static int intel_idle(struct cpuidle_device *dev,
 
 	start_critical_timings();
 
-	kt_after = ktime_get_real();
-	usec_delta = ktime_to_us(ktime_sub(kt_after, kt_before));
-
-	local_irq_enable();
-
 	if (!(lapic_timer_reliable_states & (1 << (cstate))))
 		clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
 
-	/* Update cpuidle counters */
-	dev->last_residency = (int)usec_delta;
-
 	return index;
 }
 
-- 
1.7.8.6

^ permalink raw reply related

* [PATCH] powerpc/pseries: Fix IBM_ARCH_VEC_NRCORES_OFFSET for POWER8 updates
From: Michael Neuling @ 2012-11-15  3:53 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <30008.1352442191@neuling.org>

In supporting POWER8 we added 16 bytes to the start of the
ibm_architecture_vec, but forgot to add this to
IBM_ARCH_VEC_NRCORES_OFFSET.

This caused us to hit this warning in early boot:
  WARNING ! ibm_architecture_vec structure inconsistent: 805372128

This add this extra 16 bytes of offset.  

Signed-off-by: Michael Neuling <mikey@neuling.org>

diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 9ffb542..779f340 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -773,7 +773,7 @@ static unsigned char ibm_architecture_vec[] = {
 	 * must match by the macro below. Update the definition if
 	 * the structure layout changes.
 	 */
-#define IBM_ARCH_VEC_NRCORES_OFFSET	101
+#define IBM_ARCH_VEC_NRCORES_OFFSET	117
 	W(NR_CPUS),			/* number of cores supported */
 	0,
 	0,

^ permalink raw reply related

* [PATCH 1/7] powerpc: Define differences between doorbells on book3e and book3s
From: Ian Munsie @ 2012-11-15  4:49 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Michael Neuling, linuxppc-dev, Ian Munsie
In-Reply-To: <1352954990-2858-1-git-send-email-imunsie@au1.ibm.com>

From: Ian Munsie <imunsie@au1.ibm.com>

There are a few key differences between doorbells on server compared
with embedded that we care about on Linux, namely:

- We have a new msgsndp instruction for directed privileged doorbells.
  msgsnd is used for directed hypervisor doorbells.
- The tag we use in the instruction is the Thread Identification
  Register of the recipient thread (since server doorbells can only
  occur between threads within a single core), and is only 7 bits wide.
- A new message type is introduced for server doorbells (none of the
  existing book3e message types are currently supported on book3s).

Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>
Tested-by: Michael Neuling <mikey@neuling.org>
---
 arch/powerpc/include/asm/dbell.h      |   15 +++++++++++++++
 arch/powerpc/include/asm/ppc-opcode.h |    3 +++
 arch/powerpc/include/asm/reg.h        |    1 +
 arch/powerpc/kernel/dbell.c           |    4 ++--
 4 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/dbell.h b/arch/powerpc/include/asm/dbell.h
index 607e4ee..3b33856 100644
--- a/arch/powerpc/include/asm/dbell.h
+++ b/arch/powerpc/include/asm/dbell.h
@@ -28,8 +28,23 @@ enum ppc_dbell {
 	PPC_G_DBELL = 2,	/* guest doorbell */
 	PPC_G_DBELL_CRIT = 3,	/* guest critical doorbell */
 	PPC_G_DBELL_MC = 4,	/* guest mcheck doorbell */
+	PPC_DBELL_SERVER = 5,	/* doorbell on server */
 };
 
+#ifdef CONFIG_PPC_BOOK3S
+
+#define PPC_DBELL_MSGTYPE		PPC_DBELL_SERVER
+#define SPRN_DOORBELL_CPUTAG		SPRN_TIR
+#define PPC_DBELL_TAG_MASK		0x7f
+
+#else /* CONFIG_PPC_BOOK3S */
+
+#define PPC_DBELL_MSGTYPE		PPC_DBELL
+#define SPRN_DOORBELL_CPUTAG		SPRN_PIR
+#define PPC_DBELL_TAG_MASK		0x3fff
+
+#endif /* CONFIG_PPC_BOOK3S */
+
 extern void doorbell_cause_ipi(int cpu, unsigned long data);
 extern void doorbell_exception(struct pt_regs *regs);
 extern void doorbell_setup_this_cpu(void);
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index e434d8b..45fd394 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -100,6 +100,7 @@
 #define PPC_INST_MFSPR_PVR		0x7c1f42a6
 #define PPC_INST_MFSPR_PVR_MASK		0xfc1fffff
 #define PPC_INST_MSGSND			0x7c00019c
+#define PPC_INST_MSGSNDP		0x7c00011c
 #define PPC_INST_NOP			0x60000000
 #define PPC_INST_POPCNTB		0x7c0000f4
 #define PPC_INST_POPCNTB_MASK		0xfc0007fe
@@ -224,6 +225,8 @@
 					___PPC_RB(b) | __PPC_EH(eh))
 #define PPC_MSGSND(b)		stringify_in_c(.long PPC_INST_MSGSND | \
 					___PPC_RB(b))
+#define PPC_MSGSNDP(b)		stringify_in_c(.long PPC_INST_MSGSNDP | \
+					___PPC_RB(b))
 #define PPC_POPCNTB(a, s)	stringify_in_c(.long PPC_INST_POPCNTB | \
 					__PPC_RA(a) | __PPC_RS(s))
 #define PPC_POPCNTD(a, s)	stringify_in_c(.long PPC_INST_POPCNTD | \
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 1b853f7..736c6af 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -483,6 +483,7 @@
 #ifndef SPRN_PIR
 #define SPRN_PIR	0x3FF	/* Processor Identification Register */
 #endif
+#define SPRN_TIR	0x1BE	/* Thread Identification Register */
 #define SPRN_PTEHI	0x3D5	/* 981 7450 PTE HI word (S/W TLB load) */
 #define SPRN_PTELO	0x3D6	/* 982 7450 PTE LO word (S/W TLB load) */
 #define SPRN_PURR	0x135	/* Processor Utilization of Resources Reg */
diff --git a/arch/powerpc/kernel/dbell.c b/arch/powerpc/kernel/dbell.c
index a892680..9ebbc24 100644
--- a/arch/powerpc/kernel/dbell.c
+++ b/arch/powerpc/kernel/dbell.c
@@ -21,7 +21,7 @@
 #ifdef CONFIG_SMP
 void doorbell_setup_this_cpu(void)
 {
-	unsigned long tag = mfspr(SPRN_PIR) & 0x3fff;
+	unsigned long tag = mfspr(SPRN_DOORBELL_CPUTAG) & PPC_DBELL_TAG_MASK;
 
 	smp_muxed_ipi_set_data(smp_processor_id(), tag);
 }
@@ -30,7 +30,7 @@ void doorbell_cause_ipi(int cpu, unsigned long data)
 {
 	/* Order previous accesses vs. msgsnd, which is treated as a store */
 	mb();
-	ppc_msgsnd(PPC_DBELL, 0, data);
+	ppc_msgsnd(PPC_DBELL_MSGTYPE, 0, data);
 }
 
 void doorbell_exception(struct pt_regs *regs)
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 3/7] powerpc: Add book3s privileged doorbell exception vectors
From: Ian Munsie @ 2012-11-15  4:49 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Michael Neuling, linuxppc-dev, Ian Munsie
In-Reply-To: <1352954990-2858-1-git-send-email-imunsie@au1.ibm.com>

From: Ian Munsie <imunsie@au1.ibm.com>

Directed Privileged Doorbell Interrupts come in at 0xa00 (or
0xc000000000004a00 if relocation on exception is enabled), so add
exception vectors at these locations.

If doorbell support is not compiled in we handle it as an
unknown_exception.

Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>
Tested-by: Michael Neuling <mikey@neuling.org>
---
 arch/powerpc/include/asm/exception-64s.h |    1 +
 arch/powerpc/kernel/exceptions-64s.S     |    9 +++++++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index 9d5367e..b1edd80 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -305,6 +305,7 @@ label##_relon_hv:					\
 #define SOFTEN_VALUE_0x502	PACA_IRQ_EE
 #define SOFTEN_VALUE_0x900	PACA_IRQ_DEC
 #define SOFTEN_VALUE_0x982	PACA_IRQ_DEC
+#define SOFTEN_VALUE_0xa00	PACA_IRQ_DBELL
 #define SOFTEN_VALUE_0xe80	PACA_IRQ_DBELL
 #define SOFTEN_VALUE_0xe82	PACA_IRQ_DBELL
 
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index d08a3cd..176bf99 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -252,7 +252,7 @@ hardware_interrupt_hv:
 	MASKABLE_EXCEPTION_PSERIES(0x900, 0x900, decrementer)
 	STD_EXCEPTION_HV(0x980, 0x982, hdecrementer)
 
-	STD_EXCEPTION_PSERIES(0xa00, 0xa00, trap_0a)
+	MASKABLE_EXCEPTION_PSERIES(0xa00, 0xa00, doorbell_super)
 	KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xa00)
 
 	STD_EXCEPTION_PSERIES(0xb00, 0xb00, trap_0b)
@@ -655,7 +655,11 @@ machine_check_common:
 	STD_EXCEPTION_COMMON_ASYNC(0x500, hardware_interrupt, do_IRQ)
 	STD_EXCEPTION_COMMON_ASYNC(0x900, decrementer, .timer_interrupt)
 	STD_EXCEPTION_COMMON(0x980, hdecrementer, .hdec_interrupt)
-	STD_EXCEPTION_COMMON(0xa00, trap_0a, .unknown_exception)
+#ifdef CONFIG_PPC_DOORBELL
+	STD_EXCEPTION_COMMON_ASYNC(0xa00, doorbell_super, .doorbell_exception)
+#else
+	STD_EXCEPTION_COMMON_ASYNC(0xa00, doorbell_super, .unknown_exception)
+#endif
 	STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
 	STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
 	STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
@@ -755,6 +759,7 @@ hardware_interrupt_relon_hv:
 	STD_RELON_EXCEPTION_PSERIES(0x4800, 0x800, fp_unavailable)
 	MASKABLE_RELON_EXCEPTION_PSERIES(0x4900, 0x900, decrementer)
 	STD_RELON_EXCEPTION_HV(0x4980, 0x982, hdecrementer)
+	MASKABLE_RELON_EXCEPTION_PSERIES(0x4a00, 0xa00, doorbell_super)
 	STD_RELON_EXCEPTION_PSERIES(0x4b00, 0xb00, trap_0b)
 
 	. = 0x4c00
-- 
1.7.10.4

^ permalink raw reply related

* powerpc: Add support for POWER8 directed doorbell interrupts
From: Ian Munsie @ 2012-11-15  4:49 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Michael Neuling, linuxppc-dev

This patch series adds support for using directed doorbell interrupts for IPIs
between threads within a core, which is supported by POWER8.

This should avoid the overhead of using XICS to deliver an IPI within a core,
though delivering IPIs between threads of different cores must still use XICS
as before.

Please note that this series depends on this series posted by Michael Neuling,
as it adds additional relocation on exception vectors:
https://lists.ozlabs.org/pipermail/linuxppc-dev/2012-November/101910.html

^ permalink raw reply

* [PATCH 4/7] powerpc: Select either privileged or hypervisor doorbell when sending
From: Ian Munsie @ 2012-11-15  4:49 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Michael Neuling, linuxppc-dev, Ian Munsie
In-Reply-To: <1352954990-2858-1-git-send-email-imunsie@au1.ibm.com>

From: Ian Munsie <imunsie@au1.ibm.com>

On book3s we have two msgsnd instructions with differing privilege
levels. This patch selects the appropriate instruction to use whenever
we send a doorbell interrupt.

Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>
Tested-by: Michael Neuling <mikey@neuling.org>
---
 arch/powerpc/include/asm/dbell.h |   15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/dbell.h b/arch/powerpc/include/asm/dbell.h
index 3b33856..5fa6b20 100644
--- a/arch/powerpc/include/asm/dbell.h
+++ b/arch/powerpc/include/asm/dbell.h
@@ -37,12 +37,25 @@ enum ppc_dbell {
 #define SPRN_DOORBELL_CPUTAG		SPRN_TIR
 #define PPC_DBELL_TAG_MASK		0x7f
 
+static inline void _ppc_msgsnd(u32 msg)
+{
+	if (cpu_has_feature(CPU_FTR_HVMODE))
+		__asm__ __volatile__ (PPC_MSGSND(%0) : : "r" (msg));
+	else
+		__asm__ __volatile__ (PPC_MSGSNDP(%0) : : "r" (msg));
+}
+
 #else /* CONFIG_PPC_BOOK3S */
 
 #define PPC_DBELL_MSGTYPE		PPC_DBELL
 #define SPRN_DOORBELL_CPUTAG		SPRN_PIR
 #define PPC_DBELL_TAG_MASK		0x3fff
 
+static inline void _ppc_msgsnd(u32 msg)
+{
+	__asm__ __volatile__ (PPC_MSGSND(%0) : : "r" (msg));
+}
+
 #endif /* CONFIG_PPC_BOOK3S */
 
 extern void doorbell_cause_ipi(int cpu, unsigned long data);
@@ -54,7 +67,7 @@ static inline void ppc_msgsnd(enum ppc_dbell type, u32 flags, u32 tag)
 	u32 msg = PPC_DBELL_TYPE(type) | (flags & PPC_DBELL_MSG_BRDCAST) |
 			(tag & 0x07ffffff);
 
-	__asm__ __volatile__ (PPC_MSGSND(%0) : : "r" (msg));
+	_ppc_msgsnd(msg);
 }
 
 #endif /* _ASM_POWERPC_DBELL_H */
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 7/7] powerpc: Hook up doorbells on server
From: Ian Munsie @ 2012-11-15  4:49 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Michael Neuling, linuxppc-dev, Ian Munsie
In-Reply-To: <1352954990-2858-1-git-send-email-imunsie@au1.ibm.com>

From: Ian Munsie <imunsie@au1.ibm.com>

This patch actually hooks up doorbell interrupts on POWER8:

- Select the PPC_DOORBELL Kconfig option from PPC_PSERIES

- Add the doorbell CPU feature bit to POWER8

- We define a new pSeries_cause_ipi_mux() function that issues a
  doorbell interrupt if the recipient is another thread within the same
  core as the sender. If the recipient is in a different core it falls
  back to using XICS to deliver the IPI as before.

- During pSeries_smp_probe() at boot, we check if doorbell interrupts
  are supported. If they are we set the cause_ipi function pointer to
  the above mentioned function, otherwise we leave it as whichever XICS
  cause_ipi function was determined by xics_smp_probe().

Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>
Tested-by: Michael Neuling <mikey@neuling.org>
---
 arch/powerpc/include/asm/cputable.h    |    3 ++-
 arch/powerpc/platforms/pseries/Kconfig |    1 +
 arch/powerpc/platforms/pseries/smp.c   |   33 ++++++++++++++++++++++++++++++--
 3 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 76f81bd..fc4d2c5 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -408,7 +408,8 @@ extern const char *powerpc_base_platform;
 	    CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
 	    CPU_FTR_DSCR | CPU_FTR_SAO  | \
 	    CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
-	    CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY)
+	    CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
+	    CPU_FTR_DBELL)
 #define CPU_FTRS_CELL	(CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
 	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
 	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
index 837cf49..9a0941b 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -17,6 +17,7 @@ config PPC_PSERIES
 	select PPC_NATIVE
 	select PPC_PCI_CHOICE if EXPERT
 	select ZLIB_DEFLATE
+	select PPC_DOORBELL
 	default y
 
 config PPC_SPLPAR
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index 9fc0a49..32c82c2 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -42,6 +42,7 @@
 #include <asm/vdso_datapage.h>
 #include <asm/cputhreads.h>
 #include <asm/xics.h>
+#include <asm/dbell.h>
 
 #include "plpar_wrappers.h"
 #include "pseries.h"
@@ -54,6 +55,11 @@
  */
 static cpumask_var_t of_spin_mask;
 
+/*
+ * If we multiplex IPI mechanisms, store the appropriate XICS IPI mechanism here
+ */
+static void  (*xics_cause_ipi)(int cpu, unsigned long data);
+
 /* Query where a cpu is now.  Return codes #defined in plpar_wrappers.h */
 int smp_query_cpu_stopped(unsigned int pcpu)
 {
@@ -137,6 +143,8 @@ static void __devinit smp_xics_setup_cpu(int cpu)
 {
 	if (cpu != boot_cpuid)
 		xics_setup_cpu();
+	if (cpu_has_feature(CPU_FTR_DBELL))
+		doorbell_setup_this_cpu();
 
 	if (firmware_has_feature(FW_FEATURE_SPLPAR))
 		vpa_init(cpu);
@@ -195,6 +203,27 @@ static int smp_pSeries_cpu_bootable(unsigned int nr)
 	return 1;
 }
 
+/* Only used on systems that support multiple IPI mechanisms */
+static void pSeries_cause_ipi_mux(int cpu, unsigned long data)
+{
+	if (cpumask_test_cpu(cpu, cpu_sibling_mask(smp_processor_id())))
+		doorbell_cause_ipi(cpu, data);
+	else
+		xics_cause_ipi(cpu, data);
+}
+
+static __init int pSeries_smp_probe(void)
+{
+	int ret = xics_smp_probe();
+
+	if (cpu_has_feature(CPU_FTR_DBELL)) {
+		xics_cause_ipi = smp_ops->cause_ipi;
+		smp_ops->cause_ipi = pSeries_cause_ipi_mux;
+	}
+
+	return ret;
+}
+
 static struct smp_ops_t pSeries_mpic_smp_ops = {
 	.message_pass	= smp_mpic_message_pass,
 	.probe		= smp_mpic_probe,
@@ -204,8 +233,8 @@ static struct smp_ops_t pSeries_mpic_smp_ops = {
 
 static struct smp_ops_t pSeries_xics_smp_ops = {
 	.message_pass	= NULL,	/* Use smp_muxed_ipi_message_pass */
-	.cause_ipi	= NULL,	/* Filled at runtime by xics_smp_probe() */
-	.probe		= xics_smp_probe,
+	.cause_ipi	= NULL,	/* Filled at runtime by pSeries_smp_probe() */
+	.probe		= pSeries_smp_probe,
 	.kick_cpu	= smp_pSeries_kick_cpu,
 	.setup_cpu	= smp_xics_setup_cpu,
 	.cpu_bootable	= smp_pSeries_cpu_bootable,
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 2/7] powerpc: Add book3s hypervisor doorbell exception vectors
From: Ian Munsie @ 2012-11-15  4:49 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Michael Neuling, linuxppc-dev, Ian Munsie
In-Reply-To: <1352954990-2858-1-git-send-email-imunsie@au1.ibm.com>

From: Ian Munsie <imunsie@au1.ibm.com>

Directed Hypervisor Doorbell Interrupts come in at 0xe80 (or
0xc000000000004e80 if relocation on exceptions is enabled), so add
exception vectors at these locations.

If doorbell support is not compiled in we handle it as an
unknown_exception.

Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>
Tested-by: Michael Neuling <mikey@neuling.org>
---
 arch/powerpc/include/asm/exception-64s.h |    2 ++
 arch/powerpc/kernel/exceptions-64s.S     |   16 +++++++++++++---
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index ad708dd..9d5367e 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -305,6 +305,8 @@ label##_relon_hv:					\
 #define SOFTEN_VALUE_0x502	PACA_IRQ_EE
 #define SOFTEN_VALUE_0x900	PACA_IRQ_DEC
 #define SOFTEN_VALUE_0x982	PACA_IRQ_DEC
+#define SOFTEN_VALUE_0xe80	PACA_IRQ_DBELL
+#define SOFTEN_VALUE_0xe82	PACA_IRQ_DBELL
 
 #define __SOFTEN_TEST(h, vec)						\
 	lbz	r10,PACASOFTIRQEN(r13);					\
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 4665e82..d08a3cd 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -293,6 +293,8 @@ hv_exception_trampoline:
 	b	hmi_exception_hv
 	. = 0xe60
 	b	hmi_exception_hv
+	. = 0xe80
+	b	h_doorbell_hv
 
 	/* We need to deal with the Altivec unavailable exception
 	 * here which is at 0xf20, thus in the middle of the
@@ -514,6 +516,8 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_206)
 	KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe42)
 	STD_EXCEPTION_HV(., 0xe62, hmi_exception) /* need to flush cache ? */
 	KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe62)
+	MASKABLE_EXCEPTION_HV(., 0xe82, h_doorbell)
+	KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe82)
 
 	/* moved from 0xf00 */
 	STD_EXCEPTION_PSERIES(., 0xf00, performance_monitor)
@@ -657,6 +661,11 @@ machine_check_common:
 	STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
 	STD_EXCEPTION_COMMON(0xe40, emulation_assist, .program_check_exception)
 	STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception)
+#ifdef CONFIG_PPC_DOORBELL
+	STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, .doorbell_exception)
+#else
+	STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, .unknown_exception)
+#endif
 	STD_EXCEPTION_COMMON_ASYNC(0xf00, performance_monitor, .performance_monitor_exception)
 	STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
 	STD_EXCEPTION_COMMON(0x1502, denorm, .unknown_exception)
@@ -773,9 +782,8 @@ system_call_relon_pSeries:
 	. = 0x4e60
 	b	hmi_exception_relon_hv
 
-	/* For when we support the doorbell interrupt:
-	STD_RELON_EXCEPTION_HYPERVISOR(0x4e80, 0xe80, doorbell_hyper)
-	*/
+	. = 0x4e80
+	b	h_doorbell_relon_hv
 
 performance_monitor_relon_pSeries_1:
 	. = 0x4f00
@@ -1355,6 +1363,8 @@ _GLOBAL(do_stab_bolted)
 	KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe40)
 	STD_RELON_EXCEPTION_HV(., 0xe60, hmi_exception)
 	KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe60)
+	MASKABLE_RELON_EXCEPTION_HV(., 0xe80, h_doorbell)
+	KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe80)
 
 	STD_RELON_EXCEPTION_PSERIES(., 0xf00, performance_monitor)
 	STD_RELON_EXCEPTION_PSERIES(., 0xf20, altivec_unavailable)
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 5/7] powerpc: Add code to handle soft-disabled doorbells on server
From: Ian Munsie @ 2012-11-15  4:49 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Michael Neuling, linuxppc-dev, Ian Munsie
In-Reply-To: <1352954990-2858-1-git-send-email-imunsie@au1.ibm.com>

From: Ian Munsie <imunsie@au1.ibm.com>

This patch adds the logic to properly handle doorbells that come in when
interrupts have been soft disabled and to replay them when interrupts
are re-enabled:

- masked_##_H##interrupt is modified to leave interrupts enabled when a
  doorbell has come in since doorbells are edge sensitive and as such
  won't be automatically re-raised.

- __check_irq_replay now tests if a doorbell happened on book3s, and
  returns either 0xe80 or 0xa00 depending on whether we are the
  hypervisor or not.

- restore_check_irq_replay now tests for the two possible server
  doorbell vector numbers to replay.

- __replay_interrupt also adds tests for the two server doorbell vector
  numbers, and is modified to use a compare instruction rather than an
  andi. on the single bit difference between 0x500 and 0x900.

The last two use a CPU feature section to avoid needlessly testing
against the hypervisor vector if it is not the hypervisor, and vice
versa.

Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>
---
 arch/powerpc/kernel/entry_64.S       |   13 ++++++++++--
 arch/powerpc/kernel/exceptions-64s.S |   37 +++++++++++++++++++++++-----------
 arch/powerpc/kernel/irq.c            |   11 ++++++++--
 3 files changed, 45 insertions(+), 16 deletions(-)

diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index ad76666..df6857f 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -842,13 +842,22 @@ restore_check_irq_replay:
 	addi	r3,r1,STACK_FRAME_OVERHEAD;
 	bl	.timer_interrupt
 	b	.ret_from_except
+#ifdef CONFIG_PPC_DOORBELL
+1:
 #ifdef CONFIG_PPC_BOOK3E
-1:	cmpwi	cr0,r3,0x280
+	cmpwi	cr0,r3,0x280
+#else
+	BEGIN_FTR_SECTION
+		cmpwi	cr0,r3,0xe80
+	FTR_SECTION_ELSE
+		cmpwi	cr0,r3,0xa00
+	ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
+#endif /* CONFIG_PPC_BOOK3E */
 	bne	1f
 	addi	r3,r1,STACK_FRAME_OVERHEAD;
 	bl	.doorbell_exception
 	b	.ret_from_except
-#endif /* CONFIG_PPC_BOOK3E */
+#endif /* CONFIG_PPC_DOORBELL */
 1:	b	.ret_from_except /* What else to do here ? */
  
 unrecov_restore:
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 176bf99..32fc04f 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -528,10 +528,12 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_206)
 	KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf40)
 
 /*
- * An interrupt came in while soft-disabled. We set paca->irq_happened,
- * then, if it was a decrementer interrupt, we bump the dec to max and
- * and return, else we hard disable and return. This is called with
- * r10 containing the value to OR to the paca field.
+ * An interrupt came in while soft-disabled. We set paca->irq_happened, then:
+ * - If it was a decrementer interrupt, we bump the dec to max and and return.
+ * - If it was a doorbell we return immediately since doorbells are edge
+ *   triggered and won't automatically refire.
+ * - else we hard disable and return.
+ * This is called with r10 containing the value to OR to the paca field.
  */
 #define MASKED_INTERRUPT(_H)				\
 masked_##_H##interrupt:					\
@@ -539,13 +541,15 @@ masked_##_H##interrupt:					\
 	lbz	r11,PACAIRQHAPPENED(r13);		\
 	or	r11,r11,r10;				\
 	stb	r11,PACAIRQHAPPENED(r13);		\
-	andi.	r10,r10,PACA_IRQ_DEC;			\
-	beq	1f;					\
+	cmpwi	r10,PACA_IRQ_DEC;			\
+	bne	1f;					\
 	lis	r10,0x7fff;				\
 	ori	r10,r10,0xffff;				\
 	mtspr	SPRN_DEC,r10;				\
 	b	2f;					\
-1:	mfspr	r10,SPRN_##_H##SRR1;			\
+1:	cmpwi	r10,PACA_IRQ_DBELL;			\
+	beq	2f;					\
+	mfspr	r10,SPRN_##_H##SRR1;			\
 	rldicl	r10,r10,48,1; /* clear MSR_EE */	\
 	rotldi	r10,r10,16;				\
 	mtspr	SPRN_##_H##SRR1,r10;			\
@@ -562,8 +566,8 @@ masked_##_H##interrupt:					\
 
 /*
  * Called from arch_local_irq_enable when an interrupt needs
- * to be resent. r3 contains 0x500 or 0x900 to indicate which
- * kind of interrupt. MSR:EE is already off. We generate a
+ * to be resent. r3 contains 0x500, 0x900, 0xa00 or 0xe80 to indicate
+ * which kind of interrupt. MSR:EE is already off. We generate a
  * stackframe like if a real interrupt had happened.
  *
  * Note: While MSR:EE is off, we need to make sure that _MSR
@@ -579,9 +583,18 @@ _GLOBAL(__replay_interrupt)
 	mflr	r11
 	mfcr	r9
 	ori	r12,r12,MSR_EE
-	andi.	r3,r3,0x0800
-	bne	decrementer_common
-	b	hardware_interrupt_common
+	cmpwi	r3,0x900
+	beq	decrementer_common
+	cmpwi	r3,0x500
+	beq	hardware_interrupt_common
+BEGIN_FTR_SECTION
+	cmpwi	r3,0xe80
+	beq	h_doorbell_common
+FTR_SECTION_ELSE
+	cmpwi	r3,0xa00
+	beq	doorbell_super_common
+ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
+	blr
 
 #ifdef CONFIG_PPC_PSERIES
 /*
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 71413f4..4f97fe3 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -122,8 +122,8 @@ static inline notrace int decrementer_check_overflow(void)
 }
 
 /* This is called whenever we are re-enabling interrupts
- * and returns either 0 (nothing to do) or 500/900 if there's
- * either an EE or a DEC to generate.
+ * and returns either 0 (nothing to do) or 500/900/280/a00/e80 if
+ * there's an EE, DEC or DBELL to generate.
  *
  * This is called in two contexts: From arch_local_irq_restore()
  * before soft-enabling interrupts, and from the exception exit
@@ -182,6 +182,13 @@ notrace unsigned int __check_irq_replay(void)
 	local_paca->irq_happened &= ~PACA_IRQ_DBELL;
 	if (happened & PACA_IRQ_DBELL)
 		return 0x280;
+#else
+	local_paca->irq_happened &= ~PACA_IRQ_DBELL;
+	if (happened & PACA_IRQ_DBELL) {
+		if (cpu_has_feature(CPU_FTR_HVMODE))
+			return 0xe80;
+		return 0xa00;
+	}
 #endif /* CONFIG_PPC_BOOK3E */
 
 	/* There should be nothing left ! */
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 6/7] powerpc: Update Kconfig + Makefile to prepare for server doorbells
From: Ian Munsie @ 2012-11-15  4:49 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Michael Neuling, linuxppc-dev, Ian Munsie
In-Reply-To: <1352954990-2858-1-git-send-email-imunsie@au1.ibm.com>

From: Ian Munsie <imunsie@au1.ibm.com>

Move the rule to build doorbell support out of the Makefile and into a
new Kconfig boolean that platforms can select.

We will add doorbell support to pseries as well in the next patch.

Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>
Tested-by: Michael Neuling <mikey@neuling.org>
---
 arch/powerpc/kernel/Makefile           |    4 ++--
 arch/powerpc/platforms/Kconfig.cputype |    6 ++++++
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 8f61934..44fbbea 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -75,8 +75,8 @@ endif
 obj64-$(CONFIG_HIBERNATION)	+= swsusp_asm64.o
 obj-$(CONFIG_MODULES)		+= module.o module_$(CONFIG_WORD_SIZE).o
 obj-$(CONFIG_44x)		+= cpu_setup_44x.o
-obj-$(CONFIG_PPC_FSL_BOOK3E)	+= cpu_setup_fsl_booke.o dbell.o
-obj-$(CONFIG_PPC_BOOK3E_64)	+= dbell.o
+obj-$(CONFIG_PPC_FSL_BOOK3E)	+= cpu_setup_fsl_booke.o
+obj-$(CONFIG_PPC_DOORBELL)	+= dbell.o
 obj-$(CONFIG_JUMP_LABEL)	+= jump_label.o
 
 extra-y				:= head_$(CONFIG_WORD_SIZE).o
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 72afd28..cea2f09 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -76,6 +76,7 @@ config PPC_BOOK3E_64
 	bool "Embedded processors"
 	select PPC_FPU # Make it a choice ?
 	select PPC_SMP_MUXED_IPI
+	select PPC_DOORBELL
 
 endchoice
 
@@ -208,6 +209,7 @@ config PPC_FSL_BOOK3E
 	select FSL_EMB_PERFMON
 	select PPC_SMP_MUXED_IPI
 	select SYS_SUPPORTS_HUGETLBFS if PHYS_64BIT || PPC64
+	select PPC_DOORBELL
 	default y if FSL_BOOKE
 
 config PTE_64BIT
@@ -382,4 +384,8 @@ config NOT_COHERENT_CACHE
 config CHECK_CACHE_COHERENCY
 	bool
 
+config PPC_DOORBELL
+	bool
+	default n
+
 endmenu
-- 
1.7.10.4

^ permalink raw reply related

* [powerpc:dt 10/10] lib/pSeries-reconfig-notifier-error-inject.c:4:34: fatal error: asm/pSeries_reconfig.h: No such file or directory
From: kbuild test robot @ 2012-11-15  5:26 UTC (permalink / raw)
  To: Nathan Fontenot; +Cc: linuxppc-dev

tree:   git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git dt
head:   f459d63e1689b16a2f5a965557e19b25bad5dbdc
commit: f459d63e1689b16a2f5a965557e19b25bad5dbdc [10/10] powerpc+of: Remove the pSeries_reconfig.h file
config: make ARCH=powerpc allmodconfig

All error/warnings:

lib/pSeries-reconfig-notifier-error-inject.c:4:34: fatal error: asm/pSeries_reconfig.h: No such file or directory
compilation terminated.

vim +4 lib/pSeries-reconfig-notifier-error-inject.c

08dfb4dd Akinobu Mita 2012-07-30   1  #include <linux/kernel.h>
08dfb4dd Akinobu Mita 2012-07-30   2  #include <linux/module.h>
08dfb4dd Akinobu Mita 2012-07-30   3  
08dfb4dd Akinobu Mita 2012-07-30  @4  #include <asm/pSeries_reconfig.h>
08dfb4dd Akinobu Mita 2012-07-30   5  
08dfb4dd Akinobu Mita 2012-07-30   6  #include "notifier-error-inject.h"
08dfb4dd Akinobu Mita 2012-07-30   7  
08dfb4dd Akinobu Mita 2012-07-30   8  static int priority;
08dfb4dd Akinobu Mita 2012-07-30   9  module_param(priority, int, 0);
08dfb4dd Akinobu Mita 2012-07-30  10  MODULE_PARM_DESC(priority, "specify pSeries reconfig notifier priority");
08dfb4dd Akinobu Mita 2012-07-30  11  
08dfb4dd Akinobu Mita 2012-07-30  12  static struct notifier_err_inject reconfig_err_inject = {

---
0-DAY kernel build testing backend         Open Source Technology Center
Fengguang Wu, Yuanhan Liu                              Intel Corporation

^ permalink raw reply

* linux-next: manual merge of the powerpc tree with the signal tree
From: Stephen Rothwell @ 2012-11-15  6:03 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, linuxppc-dev
  Cc: linux-next, linux-kernel, Li Zhong, Al Viro

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

Hi all,

Today's linux-next merge of the powerpc tree got a conflict in
arch/powerpc/kernel/entry_64.S between commits 40792104b255 ("powerpc:
don't mess with r2 in copy_thread() and friends") and 53b50f9483cc
("powerpc: take dereferencing to ret_from_kernel_thread()") from the
signal tree and commit 12660b170253 ("powerpc: Fix
MAX_STACK_TRACE_ENTRIES too low warning !") from the powerpc tree.

I fixed it up (see below) and can carry the fix as necessary (no action
is required).

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --cc arch/powerpc/kernel/entry_64.S
index e9a906c,ad76666..0000000
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@@ -373,7 -373,9 +373,9 @@@ _GLOBAL(ret_from_fork
  _GLOBAL(ret_from_kernel_thread)
  	bl	.schedule_tail
  	REST_NVGPRS(r1)
 -	REST_GPR(2,r1)
 +	ld	r14, 0(r14)
+ 	li	r3,0
+ 	std	r3,0(r1)
  	mtlr	r14
  	mr	r3,r15
  	blrl

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: hoo boy, interrupt Handling on BGQ
From: Segher Boessenkool @ 2012-11-15  6:50 UTC (permalink / raw)
  To: Jimi Xenidis; +Cc: Kumar Gala, linuxppc-dev
In-Reply-To: <9FB7F97D-D988-495B-93C8-746963DFF15C@pobox.com>

> So interrupts need to go to FW before Linux, please let not talk  
> about how silly that is.
> Lets talk about something far more silly...
> In order to get to the Linux exception handlers, we have to tell FW  
> where the interrupt page is, and then it _copies_ it.
>
> IFAICT, this means that each vectors on the "copied" page must:
> 1) construct an 64-bit absolute address to a per vector stub
> 2) leap at the (with bctr or blr)
> 3) restore CTR or LR and anything else that (1) messed up
> 4) normal branch to the actual vector
>
> This is what I'll be working on, but I'd love to hear any other ideas.

If you Linux exception handlers are at low (or high) real addresses, as
usual, you can just "ba" to them?


Segher

^ permalink raw reply

* linux-next: build failure after merge of the final tree (powercp tree related)
From: Stephen Rothwell @ 2012-11-15  7:06 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, linuxppc-dev
  Cc: Nathan Fontenot, linux-next, linux-kernel

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

Hi all,

After merging the final tree, today's linux-next build (powerpc
allyesconfig) failed like this:

lib/pSeries-reconfig-notifier-error-inject.c:4:34: fatal error: asm/pSeries_reconfig.h: No such file or directory

Caused by commit f459d63e1689 ("powerpc+of: Remove the pSeries_reconfig.h
file") and even if the file existed, things were removed by commit
1cf3d8b3d24c ("powerpc+of: Add of node/property notification chain for
adds and removes") that would cause
lib/pSeries-reconfig-notifier-error-inject.c to fail to build.  I have
marked it as broken for now using this patch:

From: Stephen Rothwell <sfr@canb.auug.org.au>
Date: Thu, 15 Nov 2012 18:02:13 +1100
Subject: [PATCH] lib: disable PSERIES_RECONFIG_NOTIFIER_ERROR_INJECT

It has been fundamentally broken by other changes.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 lib/Kconfig.debug |    1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 41faf0b..ad84944 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1195,6 +1195,7 @@ config MEMORY_NOTIFIER_ERROR_INJECT
 config PSERIES_RECONFIG_NOTIFIER_ERROR_INJECT
 	tristate "pSeries reconfig notifier error injection module"
 	depends on PPC_PSERIES && NOTIFIER_ERROR_INJECTION
+	depends on BROKEN
 	help
 	  This option provides the ability to inject artifical errors to
 	  pSeries reconfig notifier chain callbacks.  It is controlled
-- 
1.7.10.280.gaa39

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply related

* Re: linux-next: build failure after merge of the final tree (powercp tree related)
From: Benjamin Herrenschmidt @ 2012-11-15  7:11 UTC (permalink / raw)
  To: Stephen Rothwell
  Cc: linuxppc-dev, linux-next, Paul Mackerras, linux-kernel,
	Nathan Fontenot
In-Reply-To: <20121115180607.4a545ad6b6b6c8e3481a11e9@canb.auug.org.au>

On Thu, 2012-11-15 at 18:06 +1100, Stephen Rothwell wrote:
> Hi all,
> 
> After merging the final tree, today's linux-next build (powerpc
> allyesconfig) failed like this:
> 
> lib/pSeries-reconfig-notifier-error-inject.c:4:34: fatal error: asm/pSeries_reconfig.h: No such file or directory
> 
> Caused by commit f459d63e1689 ("powerpc+of: Remove the pSeries_reconfig.h
> file") and even if the file existed, things were removed by commit
> 1cf3d8b3d24c ("powerpc+of: Add of node/property notification chain for
> adds and removes") that would cause
> lib/pSeries-reconfig-notifier-error-inject.c to fail to build.  I have
> marked it as broken for now using this patch:

My bad, didn't notice, I don't have error injection enabled in my test
configs. I think that stuff went in after the original patches were
written I think.

Not a big deal, nobody actually enables that error inject test stuff
just yet, I'll put a fix patch into my "dt" and my "next" branch asap.

Cheers,
Ben.
 
> From: Stephen Rothwell <sfr@canb.auug.org.au>
> Date: Thu, 15 Nov 2012 18:02:13 +1100
> Subject: [PATCH] lib: disable PSERIES_RECONFIG_NOTIFIER_ERROR_INJECT
> 
> It has been fundamentally broken by other changes.
> 
> Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
> ---
>  lib/Kconfig.debug |    1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
> index 41faf0b..ad84944 100644
> --- a/lib/Kconfig.debug
> +++ b/lib/Kconfig.debug
> @@ -1195,6 +1195,7 @@ config MEMORY_NOTIFIER_ERROR_INJECT
>  config PSERIES_RECONFIG_NOTIFIER_ERROR_INJECT
>  	tristate "pSeries reconfig notifier error injection module"
>  	depends on PPC_PSERIES && NOTIFIER_ERROR_INJECTION
> +	depends on BROKEN
>  	help
>  	  This option provides the ability to inject artifical errors to
>  	  pSeries reconfig notifier chain callbacks.  It is controlled
> -- 
> 1.7.10.280.gaa39
> 

^ permalink raw reply

* Re: [PATCH] cpuidle: Measure idle state durations with monotonic clock
From: Preeti Murthy @ 2012-11-15  9:04 UTC (permalink / raw)
  To: Julius Werner
  Cc: Kevin Hilman, Deepthi Dharwar, Trinabh Gupta, Lists Linaro-dev,
	Peter Zijlstra, linux-pm, Daniel Lezcano, linux-kernel,
	Rafael J. Wysocki, linux-acpi, Srivatsa S. Bhat, Andrew Morton,
	linuxppc-dev, Sameer Nanda, Len Brown
In-Reply-To: <1352944590-8776-1-git-send-email-jwerner@chromium.org>

Hi all,

The code looks correct and inviting to me as it has led to good cleanups.
I dont think passing 0 as the argument to the function
sched_clock_idle_wakeup_event()
should lead to problems,as it does not do anything useful with the
passed arguments.

My only curiosity is what was the purpose of passing idle residency time to
sched_clock_idle_wakeup_event() when this data could always be retrieved from
dev->last_residency for each cpu,which gets almost immediately updated.

But this does not seem to come in way of this patch for now.Anyway I
have added Peter to
the list so that he can opine about this issue if possible and needed.

Reviewed-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>


Regards
Preeti U Murthy

^ permalink raw reply

* [PATCH 0/6] powerpc/book3e: support kexec and kdump
From: Tiejun Chen @ 2012-11-15  9:39 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev, linux-kernel

This patchset is used to support kexec and kdump on book3e.

Tested on fsl-p5040 DS.

Tiejun Chen (6):
      powerpc/book3e: support CONFIG_RELOCATABLE
      book3e/kexec/kdump: enable kexec for kernel
      book3e/kexec/kdump: create a 1:1 TLB mapping
      book3e/kexec/kdump: introduce a kexec kernel flag
      book3e/kexec/kdump: skip ppc32 kexec specfic
      book3e/kexec/kdump: redefine VIRT_PHYS_OFFSET

 arch/powerpc/Kconfig                     |    2 +-
 arch/powerpc/include/asm/exception-64e.h |    8 ++++
 arch/powerpc/include/asm/page.h          |    2 +
 arch/powerpc/include/asm/smp.h           |    3 ++
 arch/powerpc/kernel/exceptions-64e.S     |   15 ++++++-
 arch/powerpc/kernel/head_64.S            |   43 +++++++++++++++++--
 arch/powerpc/kernel/machine_kexec_64.c   |    6 +++
 arch/powerpc/kernel/misc_64.S            |   67 +++++++++++++++++++++++++++++-
 arch/powerpc/lib/feature-fixups.c        |    7 ++++
 arch/powerpc/platforms/85xx/smp.c        |   26 ++++++++++++
 10 files changed, 173 insertions(+), 6 deletions(-)

Tiejun

^ permalink raw reply

* [PATCH 1/6] powerpc/book3e: support CONFIG_RELOCATABLE
From: Tiejun Chen @ 2012-11-15  9:39 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1352972396-13489-1-git-send-email-tiejun.chen@windriver.com>

book3e is different with book3s since 3s includes the exception
vectors code in head_64.S as it relies on absolute addressing
which is only possible within this compilation unit. So we have
to get that label address with got.

And when boot a relocated kernel, we should reset ipvr properly again
after .relocate.

Signed-off-by: Tiejun Chen <tiejun.chen@windriver.com>
---
 arch/powerpc/include/asm/exception-64e.h |    8 ++++++++
 arch/powerpc/kernel/exceptions-64e.S     |   15 ++++++++++++++-
 arch/powerpc/kernel/head_64.S            |   22 ++++++++++++++++++++++
 arch/powerpc/lib/feature-fixups.c        |    7 +++++++
 4 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/exception-64e.h b/arch/powerpc/include/asm/exception-64e.h
index 51fa43e..89e940d 100644
--- a/arch/powerpc/include/asm/exception-64e.h
+++ b/arch/powerpc/include/asm/exception-64e.h
@@ -214,10 +214,18 @@ exc_##label##_book3e:
 #define TLB_MISS_STATS_SAVE_INFO_BOLTED
 #endif
 
+#ifndef CONFIG_RELOCATABLE
 #define SET_IVOR(vector_number, vector_offset)	\
 	li	r3,vector_offset@l; 		\
 	ori	r3,r3,interrupt_base_book3e@l;	\
 	mtspr	SPRN_IVOR##vector_number,r3;
+#else
+#define SET_IVOR(vector_number, vector_offset)	\
+	LOAD_REG_ADDR(r3,interrupt_base_book3e);\
+	rlwinm	r3,r3,0,15,0;			\
+	ori	r3,r3,vector_offset@l;		\
+	mtspr	SPRN_IVOR##vector_number,r3;
+#endif
 
 #endif /* _ASM_POWERPC_EXCEPTION_64E_H */
 
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
index 4e7083e..82be30b 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -1104,7 +1104,15 @@ skpinv:	addi	r6,r6,1				/* Increment */
  * r4 = MAS0 w/TLBSEL & ESEL for the temp mapping
  */
 	/* Now we branch the new virtual address mapped by this entry */
+#ifdef CONFIG_RELOCATABLE
+	/* We have to find out address from lr. */
+	bl	1f		/* Find our address */
+1:	mflr	r6
+	addi	r6,r6,(2f - 1b)
+	tovirt(r6,r6)
+#else
 	LOAD_REG_IMMEDIATE(r6,2f)
+#endif
 	lis	r7,MSR_KERNEL@h
 	ori	r7,r7,MSR_KERNEL@l
 	mtspr	SPRN_SRR0,r6
@@ -1355,9 +1363,14 @@ _GLOBAL(book3e_secondary_thread_init)
 	mflr	r28
 	b	3b
 
-_STATIC(init_core_book3e)
+_GLOBAL(init_core_book3e)
 	/* Establish the interrupt vector base */
+#ifdef CONFIG_RELOCATABLE
+	tovirt(r2,r2)
+	LOAD_REG_ADDR(r3, interrupt_base_book3e)
+#else
 	LOAD_REG_IMMEDIATE(r3, interrupt_base_book3e)
+#endif
 	mtspr	SPRN_IVPR,r3
 	sync
 	blr
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 9e07bd0..aa7df52 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -395,12 +395,22 @@ _STATIC(__after_prom_start)
 	/* process relocations for the final address of the kernel */
 	lis	r25,PAGE_OFFSET@highest	/* compute virtual base of kernel */
 	sldi	r25,r25,32
+#if defined(CONFIG_PPC_BOOK3E)
+	tovirt(r26,r26)			/* on booke, we already run at PAGE_OFFSET */
+#endif
 	lwz	r7,__run_at_load-_stext(r26)
+#if defined(CONFIG_PPC_BOOK3E)
+	tophys(r26,r26)			/* Restore for the remains. */
+#endif
 	cmplwi	cr0,r7,1	/* flagged to stay where we are ? */
 	bne	1f
 	add	r25,r25,r26
 1:	mr	r3,r25
 	bl	.relocate
+#if defined(CONFIG_PPC_BOOK3E)
+	/* We should set ivpr again after .relocate. */
+	bl	.init_core_book3e
+#endif
 #endif
 
 /*
@@ -428,11 +438,23 @@ _STATIC(__after_prom_start)
  * variable __run_at_load, if it is set the kernel is treated as relocatable
  * kernel, otherwise it will be moved to PHYSICAL_START
  */
+#if defined(CONFIG_PPC_BOOK3E)
+	tovirt(r26,r26)			/* on booke, we already run at PAGE_OFFSET */
+#endif
 	lwz	r7,__run_at_load-_stext(r26)
+#if defined(CONFIG_PPC_BOOK3E)
+	tophys(r26,r26)			/* Restore for the remains. */
+#endif
 	cmplwi	cr0,r7,1
 	bne	3f
 
+#ifdef CONFIG_PPC_BOOK3E
+	LOAD_REG_ADDR(r5, interrupt_end_book3e)
+	LOAD_REG_ADDR(r11, _stext)
+	sub	r5,r5,r11
+#else
 	li	r5,__end_interrupts - _stext	/* just copy interrupts */
+#endif
 	b	5f
 3:
 #endif
diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c
index 7a8a748..13f20ed 100644
--- a/arch/powerpc/lib/feature-fixups.c
+++ b/arch/powerpc/lib/feature-fixups.c
@@ -135,13 +135,20 @@ void do_final_fixups(void)
 #if defined(CONFIG_PPC64) && defined(CONFIG_RELOCATABLE)
 	int *src, *dest;
 	unsigned long length;
+#ifdef CONFIG_PPC_BOOK3E
+	extern char interrupt_end_book3e[];
+#endif
 
 	if (PHYSICAL_START == 0)
 		return;
 
 	src = (int *)(KERNELBASE + PHYSICAL_START);
 	dest = (int *)KERNELBASE;
+#ifdef CONFIG_PPC_BOOK3E
+	length = (interrupt_end_book3e - _stext) / sizeof(int);
+#else
 	length = (__end_interrupts - _stext) / sizeof(int);
+#endif
 
 	while (length--) {
 		patch_instruction(dest, *src);
-- 
1.7.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