LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [V6 00/11] perf: New conditional branch filter
From: Stephane Eranian @ 2014-06-02 16:25 UTC (permalink / raw)
  To: Anshuman Khandual
  Cc: Michael Neuling, ak@linux.intel.com, Peter Zijlstra, LKML,
	Michael Ellerman, Linux PPC dev, Arnaldo Carvalho de Melo,
	Sukadev Bhattiprolu, Ingo Molnar
In-Reply-To: <538CA096.20709@linux.vnet.ibm.com>

On Mon, Jun 2, 2014 at 6:04 PM, Anshuman Khandual
<khandual@linux.vnet.ibm.com> wrote:
> On 06/02/2014 06:29 PM, Stephane Eranian wrote:
>> On Wed, May 28, 2014 at 10:04 AM, Anshuman Khandual
>> <khandual@linux.vnet.ibm.com> wrote:
>>> On 05/27/2014 05:39 PM, Stephane Eranian wrote:
>>>> I have been looking at those patches and ran some tests.
>>>> And I found a few issues so far.
>>>>
>>>> I am running:
>>>> $ perf record -j any_ret -e cycles:u test_program
>>>> $ perf report -D
>>>>
>>>> Most entries are okay and match the filter, however some do not make sense:
>>>>
>>>> 3642586996762 0x15d0 [0x108]: PERF_RECORD_SAMPLE(IP, 2): 17921/17921:
>>>> 0x10001170 period: 613678 addr: 0
>>>> .... branch stack: nr:9
>>>> .....  0: 00000000100011cc -> 0000000010000e38
>>>> .....  1: 0000000010001150 -> 00000000100011bc
>>>> .....  2: 0000000010001208 -> 0000000010000e38
>>>> .....  3: 0000000010001160 -> 00000000100011f8
>>>> .....  4: 00000000100011cc -> 0000000010000e38
>>>> .....  5: 0000000010001150 -> 00000000100011bc
>>>> .....  6: 0000000010001208 -> 0000000010000e38
>>>> .....  7: 0000000010001160 -> 00000000100011f8
>>>> .....  8: 0000000000000000 -> 0000000010001160
>>>> ^^^^^^
>>>> Entry 8 does not make sense, unless 0x0 is a valid return branch
>>>> instruction address.
>>>> If an address is invalid, the whole entry needs to be eliminated. It
>>>> is okay to have
>>>> less than the max number of entries supported by HW.
>>>
>>> Hey Stephane,
>>>
>>> Okay. The same behaviour is also reflected in the test results what I have
>>> shared in the patchset. Here is that section.
>>>
>>> (3) perf record -j any_ret -e branch-misses:u ./cprog
>>>
>>> # Overhead  Command  Source Shared Object          Source Symbol  Target Shared Object          Target Symbol
>>> # ........  .......  ....................  .....................  ....................  .....................
>>> #
>>>     15.61%    cprog  [unknown]             [.] 00000000           cprog                 [.] sw_3_1
>>>      6.28%    cprog  cprog                 [.] symbol2            cprog                 [.] hw_1_2
>>>      6.28%    cprog  cprog                 [.] ctr_addr           cprog                 [.] sw_4_1
>>>      6.26%    cprog  cprog                 [.] success_3_1_3      cprog                 [.] sw_3_1
>>>      6.24%    cprog  cprog                 [.] symbol1            cprog                 [.] hw_1_1
>>>      6.24%    cprog  cprog                 [.] sw_4_2             cprog                 [.] callme
>>>      6.21%    cprog  [unknown]             [.] 00000000           cprog                 [.] callme
>>>      6.19%    cprog  cprog                 [.] lr_addr            cprog                 [.] sw_4_2
>>>      3.16%    cprog  cprog                 [.] hw_1_2             cprog                 [.] callme
>>>      3.15%    cprog  cprog                 [.] success_3_1_1      cprog                 [.] sw_3_1
>>>      3.15%    cprog  cprog                 [.] sw_4_1             cprog                 [.] callme
>>>      3.14%    cprog  cprog                 [.] callme             cprog                 [.] main
>>>      3.13%    cprog  cprog                 [.] hw_1_1             cprog                 [.] callme
>>>
>>> So a lot of samples above have 0x0 as the "from" address. This originates from the code
>>> section here inside the function "power_pmu_bhrb_read", where we hit two back to back
>>
>> Could you explain the back-to-back case a bit more here?
>> Back-to-back returns to me means something like:
>>
>> int foo()
>> {
>>   ...
>>    return bar();
>> }
>>
>> int bar()
>> {
>>   return 0;
>> }
>>
>> Not counting the leaf optimization here, bar return to foo which
>> immediately returns: 2 back-2-back returns.
>> Is that the case you're talking about here?
>>
>
> No. Filtering of return branches has been implemented in SW only. So PMU as such does not capture
> return only branches. It captures all the branches what it encounters. During the capture process
> PMU might *record* two back to back "target addresses" (without capturing the from address for the
> first one) for which we are unable to figure out the "from address". This leaves us with one branch
> record where we have the target address not from address and so we make it zero. With the current
> logic all branch records with "from address" as zero get filtered through and become the part of the
> final set. I was not too sure how to deal with these cases.
>
So PPC8 captures all branches, no HW filter. But then in SW you filter
out non return branches.
Given you're description, I have to believe that sometimes the HW does
not even capture the
from address. If so, then in that case, I think it is best to drop the
sample. Because the target
address may be the target of an indirect branch for which there is no
way to find the source.
In other words, the record cannot be exploited.

But why does the HW not capture some from addresses?
I am worried this might create some bias in the samples.

>>> target addresses. So we zero out the from address for the first target address and re-read
>>> the second address over again. So thats how we get zero as the from address. This is how the
>>> HW capture the samples. I was reluctant to drop these samples but I agree that these kind of
>>> samples can be dropped if we need to.
>>>
>> I think we need to make it as simple as possible for tools, i.e.,
>> avoid having to decode the
>> disassembly to figure out what happened. Here address 0 is not exploitable.
>
> Thats right. Dropping the branch record where we have only the target address not the from address
> might just solve this problem.
>

^ permalink raw reply

* Re: [PATCH v2] powerpc/booke64: wrap tlb lock and search in htw miss with FTR_SMT
From: Scott Wood @ 2014-06-02 16:45 UTC (permalink / raw)
  To: Tudor Laurentiu; +Cc: Laurentiu Tudor, linuxppc-dev
In-Reply-To: <538C7297.4040307@freescale.com>

On Mon, 2014-06-02 at 15:48 +0300, Tudor Laurentiu wrote:
> On 05/31/2014 01:45 AM, Scott Wood wrote:
> > From: Laurentiu Tudor <Laurentiu.Tudor@freescale.com>
> >   - resent since the original didn't make it to the list archives
> >     or patchwork.
> 
> The only thing i can think of is that maybe i've misspelled the mailing 
> list address ...

It looks right to me.  Did you get a bounce?

-Scott

^ permalink raw reply

* Re: [PATCH 2/2] powerpc/powernv: Enable POWER8 doorbell IPIs
From: Anton Blanchard @ 2014-06-02 22:06 UTC (permalink / raw)
  To: Michael Neuling; +Cc: Preeti U Murthy, Paul Mackerras, linuxppc-dev
In-Reply-To: <1401692223-28337-2-git-send-email-mikey@neuling.org>

Hi,

> This patch enables POWER8 doorbell IPIs on powernv.
> 
> Since doorbells can only IPI within a core, we test to see when we
> can use doorbells and if not we fall back to XICS.  This also enables
> hypervisor doorbells to wakeup us up from nap/sleep via the LPCR
> PECEDH bit.
> 
> Based on tests by Anton, the best case IPI latency between two
> threads dropped from 894ns to 512ns.
> 
> Signed-off-by: Michael Neuling <mikey@neuling.org>

Thanks Mikey!

Tested-by: Anton Blanchard <anton@samba.org>

Anton

^ permalink raw reply

* Re: [V6 00/11] perf: New conditional branch filter
From: Michael Neuling @ 2014-06-02 22:52 UTC (permalink / raw)
  To: Stephane Eranian
  Cc: ak@linux.intel.com, Peter Zijlstra, LKML, Michael Ellerman,
	Linux PPC dev, Arnaldo Carvalho de Melo, Sukadev Bhattiprolu,
	Ingo Molnar, Anshuman Khandual
In-Reply-To: <CABPqkBSmuMth4KmdLw7Nigf5uQREQJ+xL=42xV9c8FjR2VPO5g@mail.gmail.com>

On Mon, 2014-06-02 at 14:59 +0200, Stephane Eranian wrote:
> On Wed, May 28, 2014 at 10:04 AM, Anshuman Khandual
> <khandual@linux.vnet.ibm.com> wrote:
> > On 05/27/2014 05:39 PM, Stephane Eranian wrote:
> >> I have been looking at those patches and ran some tests.
> >> And I found a few issues so far.
> >>
> >> I am running:
> >> $ perf record -j any_ret -e cycles:u test_program
> >> $ perf report -D
> >>
> >> Most entries are okay and match the filter, however some do not make s=
ense:
> >>
> >> 3642586996762 0x15d0 [0x108]: PERF_RECORD_SAMPLE(IP, 2): 17921/17921:
> >> 0x10001170 period: 613678 addr: 0
> >> .... branch stack: nr:9
> >> .....  0: 00000000100011cc -> 0000000010000e38
> >> .....  1: 0000000010001150 -> 00000000100011bc
> >> .....  2: 0000000010001208 -> 0000000010000e38
> >> .....  3: 0000000010001160 -> 00000000100011f8
> >> .....  4: 00000000100011cc -> 0000000010000e38
> >> .....  5: 0000000010001150 -> 00000000100011bc
> >> .....  6: 0000000010001208 -> 0000000010000e38
> >> .....  7: 0000000010001160 -> 00000000100011f8
> >> .....  8: 0000000000000000 -> 0000000010001160
> >> ^^^^^^
> >> Entry 8 does not make sense, unless 0x0 is a valid return branch
> >> instruction address.
> >> If an address is invalid, the whole entry needs to be eliminated. It
> >> is okay to have
> >> less than the max number of entries supported by HW.
> >
> > Hey Stephane,
> >
> > Okay. The same behaviour is also reflected in the test results what I h=
ave
> > shared in the patchset. Here is that section.
> >
> > (3) perf record -j any_ret -e branch-misses:u ./cprog
> >
> > # Overhead  Command  Source Shared Object          Source Symbol  Targe=
t Shared Object          Target Symbol
> > # ........  .......  ....................  .....................  .....=
...............  .....................
> > #
> >     15.61%    cprog  [unknown]             [.] 00000000           cprog=
                 [.] sw_3_1
> >      6.28%    cprog  cprog                 [.] symbol2            cprog=
                 [.] hw_1_2
> >      6.28%    cprog  cprog                 [.] ctr_addr           cprog=
                 [.] sw_4_1
> >      6.26%    cprog  cprog                 [.] success_3_1_3      cprog=
                 [.] sw_3_1
> >      6.24%    cprog  cprog                 [.] symbol1            cprog=
                 [.] hw_1_1
> >      6.24%    cprog  cprog                 [.] sw_4_2             cprog=
                 [.] callme
> >      6.21%    cprog  [unknown]             [.] 00000000           cprog=
                 [.] callme
> >      6.19%    cprog  cprog                 [.] lr_addr            cprog=
                 [.] sw_4_2
> >      3.16%    cprog  cprog                 [.] hw_1_2             cprog=
                 [.] callme
> >      3.15%    cprog  cprog                 [.] success_3_1_1      cprog=
                 [.] sw_3_1
> >      3.15%    cprog  cprog                 [.] sw_4_1             cprog=
                 [.] callme
> >      3.14%    cprog  cprog                 [.] callme             cprog=
                 [.] main
> >      3.13%    cprog  cprog                 [.] hw_1_1             cprog=
                 [.] callme
> >
> > So a lot of samples above have 0x0 as the "from" address. This originat=
es from the code
> > section here inside the function "power_pmu_bhrb_read", where we hit tw=
o back to back
>=20
> Could you explain the back-to-back case a bit more here?
> Back-to-back returns to me means something like:
>=20
> int foo()
> {
>   ...
>    return bar();
> }
>=20
> int bar()
> {
>   return 0;
> }
>=20
> Not counting the leaf optimization here, bar return to foo which
> immediately returns: 2 back-2-back returns.
> Is that the case you're talking about here?
>=20
> > target addresses. So we zero out the from address for the first target =
address and re-read
> > the second address over again. So thats how we get zero as the from add=
ress. This is how the
> > HW capture the samples. I was reluctant to drop these samples but I agr=
ee that these kind of
> > samples can be dropped if we need to.
> >
> I think we need to make it as simple as possible for tools, i.e.,
> avoid having to decode the
> disassembly to figure out what happened. Here address 0 is not exploitabl=
e.

This was my fault.  I figured if we only had partial information from
the hardware, it was best to at least export that to the tools.  If you
disagree then we can we remove them.  There was a discussion a while
back on this here:
  https://lkml.org/lkml/2013/5/8/543

Because of the way the branch buffer is structured, we can certainly
lose the from address of the oldest branch in the buffer.  I've not seen
the hardware lose the from branches in the middle of the buffer but I
guess it's possible.  We'll have to get back to you on how or why this
would occur (and associated bias) after talking to some hardware folk.

FWIW, there was some discussion on how the POWER8 branch buffer works a
while back here (same thread as before):
  https://lkml.org/lkml/2013/5/8/541

Mikey

^ permalink raw reply

* [RFC PATCH 0/3] CMA: generalize CMA reserved area management code
From: Joonsoo Kim @ 2014-06-03  1:11 UTC (permalink / raw)
  To: Andrew Morton, Aneesh Kumar K.V, Marek Szyprowski,
	Michal Nazarewicz
  Cc: Russell King - ARM Linux, kvm, linux-mm, Gleb Natapov,
	Greg Kroah-Hartman, Alexander Graf, kvm-ppc, linux-kernel,
	Minchan Kim, Paul Mackerras, Paolo Bonzini, Joonsoo Kim,
	linuxppc-dev, linux-arm-kernel

Currently, there are two users on CMA functionality, one is the DMA
subsystem and the other is the kvm on powerpc. They have their own code
to manage CMA reserved area even if they looks really similar.
>From my guess, it is caused by some needs on bitmap management. Kvm side
wants to maintain bitmap not for 1 page, but for more size. Eventually it
use bitmap where one bit represents 64 pages.

When I implement CMA related patches, I should change those two places
to apply my change and it seem to be painful to me. I want to change
this situation and reduce future code management overhead through
this patch.

This change could also help developer who want to use CMA in their
new feature development, since they can use CMA easily without
copying & pasting this reserved area management code.

Now, we are in merge window, so this is not for merging. I'd like to
listen opinion from people who related to this stuff before actually
trying to merge this patchset. If all agree with this change, I will
resend it after rc1.

Thanks.

Joonsoo Kim (3):
  CMA: generalize CMA reserved area management functionality
  DMA, CMA: use general CMA reserved area management framework
  PPC, KVM, CMA: use general CMA reserved area management framework

 arch/powerpc/kvm/book3s_hv_builtin.c |   17 +-
 arch/powerpc/kvm/book3s_hv_cma.c     |  240 -------------------------
 arch/powerpc/kvm/book3s_hv_cma.h     |   27 ---
 drivers/base/Kconfig                 |   10 --
 drivers/base/dma-contiguous.c        |  230 ++----------------------
 include/linux/cma.h                  |   28 +++
 include/linux/dma-contiguous.h       |    7 +-
 mm/Kconfig                           |   11 ++
 mm/Makefile                          |    1 +
 mm/cma.c                             |  329 ++++++++++++++++++++++++++++++++++
 10 files changed, 396 insertions(+), 504 deletions(-)
 delete mode 100644 arch/powerpc/kvm/book3s_hv_cma.c
 delete mode 100644 arch/powerpc/kvm/book3s_hv_cma.h
 create mode 100644 include/linux/cma.h
 create mode 100644 mm/cma.c

-- 
1.7.9.5

^ permalink raw reply

* [RFC PATCH 1/3] CMA: generalize CMA reserved area management functionality
From: Joonsoo Kim @ 2014-06-03  1:11 UTC (permalink / raw)
  To: Andrew Morton, Aneesh Kumar K.V, Marek Szyprowski,
	Michal Nazarewicz
  Cc: Russell King - ARM Linux, kvm, linux-mm, Gleb Natapov,
	Greg Kroah-Hartman, Alexander Graf, kvm-ppc, linux-kernel,
	Minchan Kim, Paul Mackerras, Paolo Bonzini, Joonsoo Kim,
	linuxppc-dev, linux-arm-kernel
In-Reply-To: <1401757919-30018-1-git-send-email-iamjoonsoo.kim@lge.com>

Currently, there are two users on CMA functionality, one is the DMA
subsystem and the other is the kvm on powerpc. They have their own code
to manage CMA reserved area even if they looks really similar.
>From my guess, it is caused by some needs on bitmap management. Kvm side
wants to maintain bitmap not for 1 page, but for more size. Eventually it
use bitmap where one bit represents 64 pages.

When I implement CMA related patches, I should change those two places
to apply my change and it seem to be painful to me. I want to change
this situation and reduce future code management overhead through
this patch.

This change could also help developer who want to use CMA in their
new feature development, since they can use CMA easily without
copying & pasting this reserved area management code.

Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>

diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 00e13ce..b3fe1cc 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -283,7 +283,7 @@ config CMA_ALIGNMENT
 
 	  If unsure, leave the default value "8".
 
-config CMA_AREAS
+config DMA_CMA_AREAS
 	int "Maximum count of the CMA device-private areas"
 	default 7
 	help
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index 83969f8..48cdac8 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -186,7 +186,7 @@ static int __init cma_activate_area(struct cma *cma)
 	return 0;
 }
 
-static struct cma cma_areas[MAX_CMA_AREAS];
+static struct cma cma_areas[MAX_DMA_CMA_AREAS];
 static unsigned cma_area_count;
 
 static int __init cma_init_reserved_areas(void)
diff --git a/include/linux/cma.h b/include/linux/cma.h
new file mode 100644
index 0000000..60ba06f
--- /dev/null
+++ b/include/linux/cma.h
@@ -0,0 +1,28 @@
+/*
+ * Contiguous Memory Allocator
+ *
+ * Copyright LG Electronics Inc., 2014
+ * Written by:
+ *	Joonsoo Kim <iamjoonsoo.kim@lge.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License or (at your optional) any later version of the license.
+ *
+ */
+
+#ifndef __CMA_H__
+#define __CMA_H__
+
+struct cma;
+
+extern struct page *cma_alloc(struct cma *cma, unsigned long count,
+				unsigned long align);
+extern bool cma_release(struct cma *cma, struct page *pages,
+				unsigned long count);
+extern int __init cma_declare_contiguous(phys_addr_t size, phys_addr_t base,
+				phys_addr_t limit, phys_addr_t alignment,
+				unsigned long bitmap_shift, bool fixed,
+				struct cma **res_cma);
+#endif
diff --git a/include/linux/dma-contiguous.h b/include/linux/dma-contiguous.h
index 772eab5..dfb1dc9 100644
--- a/include/linux/dma-contiguous.h
+++ b/include/linux/dma-contiguous.h
@@ -63,7 +63,7 @@ struct device;
  * There is always at least global CMA area and a few optional device
  * private areas configured in kernel .config.
  */
-#define MAX_CMA_AREAS	(1 + CONFIG_CMA_AREAS)
+#define MAX_DMA_CMA_AREAS  (1 + CONFIG_DMA_CMA_AREAS)
 
 extern struct cma *dma_contiguous_default_area;
 
@@ -123,7 +123,7 @@ bool dma_release_from_contiguous(struct device *dev, struct page *pages,
 
 #else
 
-#define MAX_CMA_AREAS	(0)
+#define MAX_DMA_CMA_AREAS	(0)
 
 static inline struct cma *dev_get_cma_area(struct device *dev)
 {
diff --git a/mm/Kconfig b/mm/Kconfig
index 7511b4a..0877ddc 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -515,6 +515,17 @@ config CMA_DEBUG
 	  processing calls such as dma_alloc_from_contiguous().
 	  This option does not affect warning and error messages.
 
+config CMA_AREAS
+	int "Maximum count of the CMA areas"
+	depends on CMA
+	default 7
+	help
+	  CMA allows to create CMA areas for particular purpose, mainly,
+	  used as device private area. This parameter sets the maximum
+	  number of CMA area in the system.
+
+	  If unsure, leave the default value "7".
+
 config ZBUD
 	tristate
 	default n
diff --git a/mm/Makefile b/mm/Makefile
index 1eaa70b..bc0422b 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -62,3 +62,4 @@ obj-$(CONFIG_MEMORY_ISOLATION) += page_isolation.o
 obj-$(CONFIG_ZBUD)	+= zbud.o
 obj-$(CONFIG_ZSMALLOC)	+= zsmalloc.o
 obj-$(CONFIG_GENERIC_EARLY_IOREMAP) += early_ioremap.o
+obj-$(CONFIG_CMA)	+= cma.o
diff --git a/mm/cma.c b/mm/cma.c
new file mode 100644
index 0000000..0dae88d
--- /dev/null
+++ b/mm/cma.c
@@ -0,0 +1,329 @@
+/*
+ * Contiguous Memory Allocator
+ *
+ * Copyright (c) 2010-2011 by Samsung Electronics.
+ * Copyright IBM Corporation, 2013
+ * Copyright LG Electronics Inc., 2014
+ * Written by:
+ *	Marek Szyprowski <m.szyprowski@samsung.com>
+ *	Michal Nazarewicz <mina86@mina86.com>
+ *	Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+ *	Joonsoo Kim <iamjoonsoo.kim@lge.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License or (at your optional) any later version of the license.
+ */
+
+#define pr_fmt(fmt) "cma: " fmt
+
+#ifdef CONFIG_CMA_DEBUG
+#ifndef DEBUG
+#  define DEBUG
+#endif
+#endif
+
+#include <linux/memblock.h>
+#include <linux/err.h>
+#include <linux/mm.h>
+#include <linux/mutex.h>
+#include <linux/sizes.h>
+#include <linux/slab.h>
+
+struct cma {
+	unsigned long	base_pfn;
+	unsigned long	count;
+	unsigned long	*bitmap;
+	unsigned long	bitmap_shift;
+	struct mutex	lock;
+};
+
+/*
+ * There is always at least global CMA area and a few optional
+ * areas configured in kernel .config.
+ */
+#define MAX_CMA_AREAS	(1 + CONFIG_CMA_AREAS)
+
+static struct cma cma_areas[MAX_CMA_AREAS];
+static unsigned cma_area_count;
+static DEFINE_MUTEX(cma_mutex);
+
+static unsigned long cma_bitmap_mask(struct cma *cma,
+				unsigned long align_order)
+{
+	return (1 << (align_order >> cma->bitmap_shift)) - 1;
+}
+
+static unsigned long cma_bitmap_max_no(struct cma *cma)
+{
+	return cma->count >> cma->bitmap_shift;
+}
+
+static unsigned long cma_bitmap_pages_to_bits(struct cma *cma,
+						unsigned long pages)
+{
+	return ALIGN(pages, 1 << cma->bitmap_shift) >> cma->bitmap_shift;
+}
+
+static void clear_cma_bitmap(struct cma *cma, unsigned long pfn, int count)
+{
+	unsigned long bitmapno, nr_bits;
+
+	bitmapno = (pfn - cma->base_pfn) >> cma->bitmap_shift;
+	nr_bits = cma_bitmap_pages_to_bits(cma, count);
+
+	mutex_lock(&cma->lock);
+	bitmap_clear(cma->bitmap, bitmapno, nr_bits);
+	mutex_unlock(&cma->lock);
+}
+
+static int __init cma_activate_area(struct cma *cma)
+{
+	int max_bitmapno = cma_bitmap_max_no(cma);
+	int bitmap_size = BITS_TO_LONGS(max_bitmapno) * sizeof(long);
+	unsigned long base_pfn = cma->base_pfn, pfn = base_pfn;
+	unsigned i = cma->count >> pageblock_order;
+	struct zone *zone;
+
+	pr_debug("%s()\n", __func__);
+	if (!cma->count)
+		return 0;
+
+	cma->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
+	if (!cma->bitmap)
+		return -ENOMEM;
+
+	WARN_ON_ONCE(!pfn_valid(pfn));
+	zone = page_zone(pfn_to_page(pfn));
+
+	do {
+		unsigned j;
+
+		base_pfn = pfn;
+		for (j = pageblock_nr_pages; j; --j, pfn++) {
+			WARN_ON_ONCE(!pfn_valid(pfn));
+			/*
+			 * alloc_contig_range requires the pfn range
+			 * specified to be in the same zone. Make this
+			 * simple by forcing the entire CMA resv range
+			 * to be in the same zone.
+			 */
+			if (page_zone(pfn_to_page(pfn)) != zone)
+				goto err;
+		}
+		init_cma_reserved_pageblock(pfn_to_page(base_pfn));
+	} while (--i);
+
+	mutex_init(&cma->lock);
+	return 0;
+
+err:
+	kfree(cma->bitmap);
+	return -EINVAL;
+}
+
+static int __init cma_init_reserved_areas(void)
+{
+	int i;
+
+	for (i = 0; i < cma_area_count; i++) {
+		int ret = cma_activate_area(&cma_areas[i]);
+
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+core_initcall(cma_init_reserved_areas);
+
+/**
+ * cma_declare_contiguous() - reserve custom contiguous area
+ * @size: Size of the reserved area (in bytes),
+ * @base: Base address of the reserved area optional, use 0 for any
+ * @limit: End address of the reserved memory (optional, 0 for any).
+ * @bitmap_shift: Order of pages represented by one bit on bitmap.
+ * @fixed: hint about where to place the reserved area
+ * @res_cma: Pointer to store the created cma region.
+ *
+ * This function reserves memory from early allocator. It should be
+ * called by arch specific code once the early allocator (memblock or bootmem)
+ * has been activated and all other subsystems have already allocated/reserved
+ * memory. This function allows to create custom reserved areas.
+ *
+ * If @fixed is true, reserve contiguous area at exactly @base.  If false,
+ * reserve in range from @base to @limit.
+ */
+int __init cma_declare_contiguous(phys_addr_t size, phys_addr_t base,
+				phys_addr_t limit, phys_addr_t alignment,
+				unsigned long bitmap_shift, bool fixed,
+				struct cma **res_cma)
+{
+	struct cma *cma = &cma_areas[cma_area_count];
+	int ret = 0;
+
+	pr_debug("%s(size %lx, base %08lx, limit %08lx, alignment %08lx)\n",
+			__func__, (unsigned long)size, (unsigned long)base,
+			(unsigned long)limit, (unsigned long)alignment);
+
+	/* Sanity checks */
+	if (cma_area_count == ARRAY_SIZE(cma_areas)) {
+		pr_err("Not enough slots for CMA reserved regions!\n");
+		return -ENOSPC;
+	}
+
+	if (!size)
+		return -EINVAL;
+
+	/*
+	 * Sanitise input arguments.
+	 * CMA area should be at least MAX_ORDER - 1 aligned. Otherwise,
+	 * CMA area could be merged into other MIGRATE_TYPE by buddy mechanism
+	 * and CMA property will be broken.
+	 */
+	alignment >>= PAGE_SHIFT;
+	alignment = PAGE_SIZE << max3(MAX_ORDER - 1, pageblock_order,
+						(int)alignment);
+	base = ALIGN(base, alignment);
+	size = ALIGN(size, alignment);
+	limit &= ~(alignment - 1);
+	/* size should be aligned with bitmap_shift */
+	BUG_ON(!IS_ALIGNED(size >> PAGE_SHIFT, 1 << cma->bitmap_shift));
+
+	/* Reserve memory */
+	if (base && fixed) {
+		if (memblock_is_region_reserved(base, size) ||
+		    memblock_reserve(base, size) < 0) {
+			ret = -EBUSY;
+			goto err;
+		}
+	} else {
+		phys_addr_t addr = memblock_alloc_range(size, alignment, base,
+							limit);
+		if (!addr) {
+			ret = -ENOMEM;
+			goto err;
+		} else {
+			base = addr;
+		}
+	}
+
+	/*
+	 * Each reserved area must be initialised later, when more kernel
+	 * subsystems (like slab allocator) are available.
+	 */
+	cma->base_pfn = PFN_DOWN(base);
+	cma->count = size >> PAGE_SHIFT;
+	cma->bitmap_shift = bitmap_shift;
+	*res_cma = cma;
+	cma_area_count++;
+
+	pr_info("CMA: reserved %ld MiB at %08lx\n", (unsigned long)size / SZ_1M,
+		(unsigned long)base);
+
+	return 0;
+
+err:
+	pr_err("CMA: failed to reserve %ld MiB\n", (unsigned long)size / SZ_1M);
+	return ret;
+}
+
+/**
+ * cma_alloc() - allocate pages from contiguous area
+ * @cma:   Contiguous memory region for which the allocation is performed.
+ * @count: Requested number of pages.
+ * @align: Requested alignment of pages (in PAGE_SIZE order).
+ *
+ * This function allocates part of contiguous memory on specific
+ * contiguous memory area.
+ */
+struct page *cma_alloc(struct cma *cma, unsigned long count,
+				       unsigned long align)
+{
+	unsigned long mask, pfn, start = 0;
+	unsigned long max_bitmapno, bitmapno, nr_bits;
+	struct page *page = NULL;
+	int ret;
+
+	if (!cma || !cma->count)
+		return NULL;
+
+	pr_debug("%s(cma %p, count %ld, align %ld)\n", __func__, (void *)cma,
+		 count, align);
+
+	if (!count)
+		return NULL;
+
+	mask = cma_bitmap_mask(cma, align);
+	max_bitmapno = cma_bitmap_max_no(cma);
+	nr_bits = cma_bitmap_pages_to_bits(cma, count);
+
+	for (;;) {
+		mutex_lock(&cma->lock);
+		bitmapno = bitmap_find_next_zero_area(cma->bitmap,
+					max_bitmapno, start, nr_bits, mask);
+		if (bitmapno >= max_bitmapno) {
+			mutex_unlock(&cma->lock);
+			break;
+		}
+		bitmap_set(cma->bitmap, bitmapno, nr_bits);
+		/*
+		 * It's safe to drop the lock here. We've marked this region for
+		 * our exclusive use. If the migration fails we will take the
+		 * lock again and unmark it.
+		 */
+		mutex_unlock(&cma->lock);
+
+		pfn = cma->base_pfn + (bitmapno << cma->bitmap_shift);
+		mutex_lock(&cma_mutex);
+		ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA);
+		mutex_unlock(&cma_mutex);
+		if (ret == 0) {
+			page = pfn_to_page(pfn);
+			break;
+		}
+		clear_cma_bitmap(cma, pfn, count);
+		if (ret != -EBUSY)
+			break;
+
+		pr_debug("%s(): memory range at %p is busy, retrying\n",
+			 __func__, pfn_to_page(pfn));
+		/* try again with a bit different memory target */
+		start = bitmapno + mask + 1;
+	}
+
+	pr_debug("%s(): returned %p\n", __func__, page);
+	return page;
+}
+
+/**
+ * cma_release() - release allocated pages
+ * @cma:   Contiguous memory region for which the allocation is performed.
+ * @pages: Allocated pages.
+ * @count: Number of allocated pages.
+ *
+ * This function releases memory allocated by alloc_cma().
+ * It returns false when provided pages do not belong to contiguous area and
+ * true otherwise.
+ */
+bool cma_release(struct cma *cma, struct page *pages, unsigned long count)
+{
+	unsigned long pfn;
+
+	if (!cma || !pages)
+		return false;
+
+	pr_debug("%s(page %p)\n", __func__, (void *)pages);
+
+	pfn = page_to_pfn(pages);
+	if (pfn < cma->base_pfn || pfn >= cma->base_pfn + cma->count)
+		return false;
+
+	VM_BUG_ON(pfn + count > cma->base_pfn + cma->count);
+
+	free_contig_range(pfn, count);
+	clear_cma_bitmap(cma, pfn, count);
+
+	return true;
+}
-- 
1.7.9.5

^ permalink raw reply related

* [RFC PATCH 2/3] DMA, CMA: use general CMA reserved area management framework
From: Joonsoo Kim @ 2014-06-03  1:11 UTC (permalink / raw)
  To: Andrew Morton, Aneesh Kumar K.V, Marek Szyprowski,
	Michal Nazarewicz
  Cc: Russell King - ARM Linux, kvm, linux-mm, Gleb Natapov,
	Greg Kroah-Hartman, Alexander Graf, kvm-ppc, linux-kernel,
	Minchan Kim, Paul Mackerras, Paolo Bonzini, Joonsoo Kim,
	linuxppc-dev, linux-arm-kernel
In-Reply-To: <1401757919-30018-1-git-send-email-iamjoonsoo.kim@lge.com>

Now, we have general CMA reserved area management framework,
so use it for future maintainabilty. There is no functional change.

Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>

diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index b3fe1cc..4eac559 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -283,16 +283,6 @@ config CMA_ALIGNMENT
 
 	  If unsure, leave the default value "8".
 
-config DMA_CMA_AREAS
-	int "Maximum count of the CMA device-private areas"
-	default 7
-	help
-	  CMA allows to create CMA areas for particular devices. This parameter
-	  sets the maximum number of such device private CMA areas in the
-	  system.
-
-	  If unsure, leave the default value "7".
-
 endif
 
 endmenu
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index 48cdac8..4bce4e1 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -24,23 +24,9 @@
 
 #include <linux/memblock.h>
 #include <linux/err.h>
-#include <linux/mm.h>
-#include <linux/mutex.h>
-#include <linux/page-isolation.h>
 #include <linux/sizes.h>
-#include <linux/slab.h>
-#include <linux/swap.h>
-#include <linux/mm_types.h>
 #include <linux/dma-contiguous.h>
-
-struct cma {
-	unsigned long	base_pfn;
-	unsigned long	count;
-	unsigned long	*bitmap;
-	struct mutex	lock;
-};
-
-struct cma *dma_contiguous_default_area;
+#include <linux/cma.h>
 
 #ifdef CONFIG_CMA_SIZE_MBYTES
 #define CMA_SIZE_MBYTES CONFIG_CMA_SIZE_MBYTES
@@ -48,6 +34,8 @@ struct cma *dma_contiguous_default_area;
 #define CMA_SIZE_MBYTES 0
 #endif
 
+struct cma *dma_contiguous_default_area;
+
 /*
  * Default global CMA area size can be defined in kernel's .config.
  * This is useful mainly for distro maintainers to create a kernel
@@ -154,55 +142,6 @@ void __init dma_contiguous_reserve(phys_addr_t limit)
 	}
 }
 
-static DEFINE_MUTEX(cma_mutex);
-
-static int __init cma_activate_area(struct cma *cma)
-{
-	int bitmap_size = BITS_TO_LONGS(cma->count) * sizeof(long);
-	unsigned long base_pfn = cma->base_pfn, pfn = base_pfn;
-	unsigned i = cma->count >> pageblock_order;
-	struct zone *zone;
-
-	cma->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
-
-	if (!cma->bitmap)
-		return -ENOMEM;
-
-	WARN_ON_ONCE(!pfn_valid(pfn));
-	zone = page_zone(pfn_to_page(pfn));
-
-	do {
-		unsigned j;
-		base_pfn = pfn;
-		for (j = pageblock_nr_pages; j; --j, pfn++) {
-			WARN_ON_ONCE(!pfn_valid(pfn));
-			if (page_zone(pfn_to_page(pfn)) != zone)
-				return -EINVAL;
-		}
-		init_cma_reserved_pageblock(pfn_to_page(base_pfn));
-	} while (--i);
-
-	mutex_init(&cma->lock);
-	return 0;
-}
-
-static struct cma cma_areas[MAX_DMA_CMA_AREAS];
-static unsigned cma_area_count;
-
-static int __init cma_init_reserved_areas(void)
-{
-	int i;
-
-	for (i = 0; i < cma_area_count; i++) {
-		int ret = cma_activate_area(&cma_areas[i]);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-core_initcall(cma_init_reserved_areas);
-
 /**
  * dma_contiguous_reserve_area() - reserve custom contiguous area
  * @size: Size of the reserved area (in bytes),
@@ -224,176 +163,31 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
 				       phys_addr_t limit, struct cma **res_cma,
 				       bool fixed)
 {
-	struct cma *cma = &cma_areas[cma_area_count];
-	phys_addr_t alignment;
-	int ret = 0;
-
-	pr_debug("%s(size %lx, base %08lx, limit %08lx)\n", __func__,
-		 (unsigned long)size, (unsigned long)base,
-		 (unsigned long)limit);
-
-	/* Sanity checks */
-	if (cma_area_count == ARRAY_SIZE(cma_areas)) {
-		pr_err("Not enough slots for CMA reserved regions!\n");
-		return -ENOSPC;
-	}
-
-	if (!size)
-		return -EINVAL;
-
-	/* Sanitise input arguments */
-	alignment = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order);
-	base = ALIGN(base, alignment);
-	size = ALIGN(size, alignment);
-	limit &= ~(alignment - 1);
-
-	/* Reserve memory */
-	if (base && fixed) {
-		if (memblock_is_region_reserved(base, size) ||
-		    memblock_reserve(base, size) < 0) {
-			ret = -EBUSY;
-			goto err;
-		}
-	} else {
-		phys_addr_t addr = memblock_alloc_range(size, alignment, base,
-							limit);
-		if (!addr) {
-			ret = -ENOMEM;
-			goto err;
-		} else {
-			base = addr;
-		}
-	}
-
-	/*
-	 * Each reserved area must be initialised later, when more kernel
-	 * subsystems (like slab allocator) are available.
-	 */
-	cma->base_pfn = PFN_DOWN(base);
-	cma->count = size >> PAGE_SHIFT;
-	*res_cma = cma;
-	cma_area_count++;
+	int ret;
+	struct cma *cma;
 
-	pr_info("CMA: reserved %ld MiB at %08lx\n", (unsigned long)size / SZ_1M,
-		(unsigned long)base);
+	ret = cma_declare_contiguous(size, base, limit, 0, 0, fixed, &cma);
+	if (ret)
+		return ret;
 
 	/* Architecture specific contiguous memory fixup. */
 	dma_contiguous_early_fixup(base, size);
-	return 0;
-err:
-	pr_err("CMA: failed to reserve %ld MiB\n", (unsigned long)size / SZ_1M);
-	return ret;
-}
+	*res_cma = cma;
 
-static void clear_cma_bitmap(struct cma *cma, unsigned long pfn, int count)
-{
-	mutex_lock(&cma->lock);
-	bitmap_clear(cma->bitmap, pfn - cma->base_pfn, count);
-	mutex_unlock(&cma->lock);
+	return 0;
 }
 
-/**
- * dma_alloc_from_contiguous() - allocate pages from contiguous area
- * @dev:   Pointer to device for which the allocation is performed.
- * @count: Requested number of pages.
- * @align: Requested alignment of pages (in PAGE_SIZE order).
- *
- * This function allocates memory buffer for specified device. It uses
- * device specific contiguous memory area if available or the default
- * global one. Requires architecture specific dev_get_cma_area() helper
- * function.
- */
 struct page *dma_alloc_from_contiguous(struct device *dev, int count,
 				       unsigned int align)
 {
-	unsigned long mask, pfn, pageno, start = 0;
-	struct cma *cma = dev_get_cma_area(dev);
-	struct page *page = NULL;
-	int ret;
-
-	if (!cma || !cma->count)
-		return NULL;
-
 	if (align > CONFIG_CMA_ALIGNMENT)
 		align = CONFIG_CMA_ALIGNMENT;
 
-	pr_debug("%s(cma %p, count %d, align %d)\n", __func__, (void *)cma,
-		 count, align);
-
-	if (!count)
-		return NULL;
-
-	mask = (1 << align) - 1;
-
-
-	for (;;) {
-		mutex_lock(&cma->lock);
-		pageno = bitmap_find_next_zero_area(cma->bitmap, cma->count,
-						    start, count, mask);
-		if (pageno >= cma->count) {
-			mutex_unlock(&cma->lock);
-			break;
-		}
-		bitmap_set(cma->bitmap, pageno, count);
-		/*
-		 * It's safe to drop the lock here. We've marked this region for
-		 * our exclusive use. If the migration fails we will take the
-		 * lock again and unmark it.
-		 */
-		mutex_unlock(&cma->lock);
-
-		pfn = cma->base_pfn + pageno;
-		mutex_lock(&cma_mutex);
-		ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA);
-		mutex_unlock(&cma_mutex);
-		if (ret == 0) {
-			page = pfn_to_page(pfn);
-			break;
-		} else if (ret != -EBUSY) {
-			clear_cma_bitmap(cma, pfn, count);
-			break;
-		}
-		clear_cma_bitmap(cma, pfn, count);
-		pr_debug("%s(): memory range at %p is busy, retrying\n",
-			 __func__, pfn_to_page(pfn));
-		/* try again with a bit different memory target */
-		start = pageno + mask + 1;
-	}
-
-	pr_debug("%s(): returned %p\n", __func__, page);
-	return page;
+	return cma_alloc(dev_get_cma_area(dev), count, align);
 }
 
-/**
- * dma_release_from_contiguous() - release allocated pages
- * @dev:   Pointer to device for which the pages were allocated.
- * @pages: Allocated pages.
- * @count: Number of allocated pages.
- *
- * This function releases memory allocated by dma_alloc_from_contiguous().
- * It returns false when provided pages do not belong to contiguous area and
- * true otherwise.
- */
 bool dma_release_from_contiguous(struct device *dev, struct page *pages,
 				 int count)
 {
-	struct cma *cma = dev_get_cma_area(dev);
-	unsigned long pfn;
-
-	if (!cma || !pages)
-		return false;
-
-	pr_debug("%s(page %p)\n", __func__, (void *)pages);
-
-	pfn = page_to_pfn(pages);
-
-	if (pfn < cma->base_pfn || pfn >= cma->base_pfn + cma->count)
-		return false;
-
-	VM_BUG_ON(pfn + count > cma->base_pfn + cma->count);
-
-	free_contig_range(pfn, count);
-	clear_cma_bitmap(cma, pfn, count);
-
-	return true;
+	return cma_release(dev_get_cma_area(dev), pages, count);
 }
diff --git a/include/linux/dma-contiguous.h b/include/linux/dma-contiguous.h
index dfb1dc9..ecb85ac 100644
--- a/include/linux/dma-contiguous.h
+++ b/include/linux/dma-contiguous.h
@@ -53,9 +53,10 @@
 
 #ifdef __KERNEL__
 
+#include <linux/device.h>
+
 struct cma;
 struct page;
-struct device;
 
 #ifdef CONFIG_DMA_CMA
 
-- 
1.7.9.5

^ permalink raw reply related

* [RFC PATCH 3/3] PPC, KVM, CMA: use general CMA reserved area management framework
From: Joonsoo Kim @ 2014-06-03  1:11 UTC (permalink / raw)
  To: Andrew Morton, Aneesh Kumar K.V, Marek Szyprowski,
	Michal Nazarewicz
  Cc: Russell King - ARM Linux, kvm, linux-mm, Gleb Natapov,
	Greg Kroah-Hartman, Alexander Graf, kvm-ppc, linux-kernel,
	Minchan Kim, Paul Mackerras, Paolo Bonzini, Joonsoo Kim,
	linuxppc-dev, linux-arm-kernel
In-Reply-To: <1401757919-30018-1-git-send-email-iamjoonsoo.kim@lge.com>

Now, we have general CMA reserved area management framework,
so use it for future maintainabilty. There is no functional change.

Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>

diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c
index 8cd0dae..43c3f81 100644
--- a/arch/powerpc/kvm/book3s_hv_builtin.c
+++ b/arch/powerpc/kvm/book3s_hv_builtin.c
@@ -15,12 +15,14 @@
 #include <linux/init.h>
 #include <linux/memblock.h>
 #include <linux/sizes.h>
+#include <linux/cma.h>
 
 #include <asm/cputable.h>
 #include <asm/kvm_ppc.h>
 #include <asm/kvm_book3s.h>
 
-#include "book3s_hv_cma.h"
+#define KVM_CMA_CHUNK_ORDER	18
+
 /*
  * Hash page table alignment on newer cpus(CPU_FTR_ARCH_206)
  * should be power of 2.
@@ -42,6 +44,8 @@ static unsigned long kvm_cma_resv_ratio = 5;
 unsigned long kvm_rma_pages = (1 << 27) >> PAGE_SHIFT;	/* 128MB */
 EXPORT_SYMBOL_GPL(kvm_rma_pages);
 
+static struct cma *kvm_cma;
+
 /* Work out RMLS (real mode limit selector) field value for a given RMA size.
    Assumes POWER7 or PPC970. */
 static inline int lpcr_rmls(unsigned long rma_size)
@@ -96,7 +100,7 @@ struct kvm_rma_info *kvm_alloc_rma()
 	ri = kmalloc(sizeof(struct kvm_rma_info), GFP_KERNEL);
 	if (!ri)
 		return NULL;
-	page = kvm_alloc_cma(kvm_rma_pages, kvm_rma_pages);
+	page = cma_alloc(kvm_cma, kvm_rma_pages, get_order(kvm_rma_pages));
 	if (!page)
 		goto err_out;
 	atomic_set(&ri->use_count, 1);
@@ -111,7 +115,7 @@ EXPORT_SYMBOL_GPL(kvm_alloc_rma);
 void kvm_release_rma(struct kvm_rma_info *ri)
 {
 	if (atomic_dec_and_test(&ri->use_count)) {
-		kvm_release_cma(pfn_to_page(ri->base_pfn), kvm_rma_pages);
+		cma_release(kvm_cma, pfn_to_page(ri->base_pfn), kvm_rma_pages);
 		kfree(ri);
 	}
 }
@@ -133,13 +137,13 @@ struct page *kvm_alloc_hpt(unsigned long nr_pages)
 	/* Old CPUs require HPT aligned on a multiple of its size */
 	if (!cpu_has_feature(CPU_FTR_ARCH_206))
 		align_pages = nr_pages;
-	return kvm_alloc_cma(nr_pages, align_pages);
+	return cma_alloc(kvm_cma, nr_pages, get_order(align_pages));
 }
 EXPORT_SYMBOL_GPL(kvm_alloc_hpt);
 
 void kvm_release_hpt(struct page *page, unsigned long nr_pages)
 {
-	kvm_release_cma(page, nr_pages);
+	cma_release(kvm_cma, page, nr_pages);
 }
 EXPORT_SYMBOL_GPL(kvm_release_hpt);
 
@@ -178,6 +182,7 @@ void __init kvm_cma_reserve(void)
 			align_size = HPT_ALIGN_PAGES << PAGE_SHIFT;
 
 		align_size = max(kvm_rma_pages << PAGE_SHIFT, align_size);
-		kvm_cma_declare_contiguous(selected_size, align_size);
+		cma_declare_contiguous(selected_size, 0, 0, align_size,
+			KVM_CMA_CHUNK_ORDER - PAGE_SHIFT, false, &kvm_cma);
 	}
 }
diff --git a/arch/powerpc/kvm/book3s_hv_cma.c b/arch/powerpc/kvm/book3s_hv_cma.c
deleted file mode 100644
index d9d3d85..0000000
--- a/arch/powerpc/kvm/book3s_hv_cma.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Contiguous Memory Allocator for ppc KVM hash pagetable  based on CMA
- * for DMA mapping framework
- *
- * Copyright IBM Corporation, 2013
- * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License or (at your optional) any later version of the license.
- *
- */
-#define pr_fmt(fmt) "kvm_cma: " fmt
-
-#ifdef CONFIG_CMA_DEBUG
-#ifndef DEBUG
-#  define DEBUG
-#endif
-#endif
-
-#include <linux/memblock.h>
-#include <linux/mutex.h>
-#include <linux/sizes.h>
-#include <linux/slab.h>
-
-#include "book3s_hv_cma.h"
-
-struct kvm_cma {
-	unsigned long	base_pfn;
-	unsigned long	count;
-	unsigned long	*bitmap;
-};
-
-static DEFINE_MUTEX(kvm_cma_mutex);
-static struct kvm_cma kvm_cma_area;
-
-/**
- * kvm_cma_declare_contiguous() - reserve area for contiguous memory handling
- *			          for kvm hash pagetable
- * @size:  Size of the reserved memory.
- * @alignment:  Alignment for the contiguous memory area
- *
- * This function reserves memory for kvm cma area. It should be
- * called by arch code when early allocator (memblock or bootmem)
- * is still activate.
- */
-long __init kvm_cma_declare_contiguous(phys_addr_t size, phys_addr_t alignment)
-{
-	long base_pfn;
-	phys_addr_t addr;
-	struct kvm_cma *cma = &kvm_cma_area;
-
-	pr_debug("%s(size %lx)\n", __func__, (unsigned long)size);
-
-	if (!size)
-		return -EINVAL;
-	/*
-	 * Sanitise input arguments.
-	 * We should be pageblock aligned for CMA.
-	 */
-	alignment = max(alignment, (phys_addr_t)(PAGE_SIZE << pageblock_order));
-	size = ALIGN(size, alignment);
-	/*
-	 * Reserve memory
-	 * Use __memblock_alloc_base() since
-	 * memblock_alloc_base() panic()s.
-	 */
-	addr = __memblock_alloc_base(size, alignment, 0);
-	if (!addr) {
-		base_pfn = -ENOMEM;
-		goto err;
-	} else
-		base_pfn = PFN_DOWN(addr);
-
-	/*
-	 * Each reserved area must be initialised later, when more kernel
-	 * subsystems (like slab allocator) are available.
-	 */
-	cma->base_pfn = base_pfn;
-	cma->count    = size >> PAGE_SHIFT;
-	pr_info("CMA: reserved %ld MiB\n", (unsigned long)size / SZ_1M);
-	return 0;
-err:
-	pr_err("CMA: failed to reserve %ld MiB\n", (unsigned long)size / SZ_1M);
-	return base_pfn;
-}
-
-/**
- * kvm_alloc_cma() - allocate pages from contiguous area
- * @nr_pages: Requested number of pages.
- * @align_pages: Requested alignment in number of pages
- *
- * This function allocates memory buffer for hash pagetable.
- */
-struct page *kvm_alloc_cma(unsigned long nr_pages, unsigned long align_pages)
-{
-	int ret;
-	struct page *page = NULL;
-	struct kvm_cma *cma = &kvm_cma_area;
-	unsigned long chunk_count, nr_chunk;
-	unsigned long mask, pfn, pageno, start = 0;
-
-
-	if (!cma || !cma->count)
-		return NULL;
-
-	pr_debug("%s(cma %p, count %lu, align pages %lu)\n", __func__,
-		 (void *)cma, nr_pages, align_pages);
-
-	if (!nr_pages)
-		return NULL;
-	/*
-	 * align mask with chunk size. The bit tracks pages in chunk size
-	 */
-	VM_BUG_ON(!is_power_of_2(align_pages));
-	mask = (align_pages >> (KVM_CMA_CHUNK_ORDER - PAGE_SHIFT)) - 1;
-	BUILD_BUG_ON(PAGE_SHIFT > KVM_CMA_CHUNK_ORDER);
-
-	chunk_count = cma->count >>  (KVM_CMA_CHUNK_ORDER - PAGE_SHIFT);
-	nr_chunk = nr_pages >> (KVM_CMA_CHUNK_ORDER - PAGE_SHIFT);
-
-	mutex_lock(&kvm_cma_mutex);
-	for (;;) {
-		pageno = bitmap_find_next_zero_area(cma->bitmap, chunk_count,
-						    start, nr_chunk, mask);
-		if (pageno >= chunk_count)
-			break;
-
-		pfn = cma->base_pfn + (pageno << (KVM_CMA_CHUNK_ORDER - PAGE_SHIFT));
-		ret = alloc_contig_range(pfn, pfn + nr_pages, MIGRATE_CMA);
-		if (ret == 0) {
-			bitmap_set(cma->bitmap, pageno, nr_chunk);
-			page = pfn_to_page(pfn);
-			memset(pfn_to_kaddr(pfn), 0, nr_pages << PAGE_SHIFT);
-			break;
-		} else if (ret != -EBUSY) {
-			break;
-		}
-		pr_debug("%s(): memory range at %p is busy, retrying\n",
-			 __func__, pfn_to_page(pfn));
-		/* try again with a bit different memory target */
-		start = pageno + mask + 1;
-	}
-	mutex_unlock(&kvm_cma_mutex);
-	pr_debug("%s(): returned %p\n", __func__, page);
-	return page;
-}
-
-/**
- * kvm_release_cma() - release allocated pages for hash pagetable
- * @pages: Allocated pages.
- * @nr_pages: Number of allocated pages.
- *
- * This function releases memory allocated by kvm_alloc_cma().
- * It returns false when provided pages do not belong to contiguous area and
- * true otherwise.
- */
-bool kvm_release_cma(struct page *pages, unsigned long nr_pages)
-{
-	unsigned long pfn;
-	unsigned long nr_chunk;
-	struct kvm_cma *cma = &kvm_cma_area;
-
-	if (!cma || !pages)
-		return false;
-
-	pr_debug("%s(page %p count %lu)\n", __func__, (void *)pages, nr_pages);
-
-	pfn = page_to_pfn(pages);
-
-	if (pfn < cma->base_pfn || pfn >= cma->base_pfn + cma->count)
-		return false;
-
-	VM_BUG_ON(pfn + nr_pages > cma->base_pfn + cma->count);
-	nr_chunk = nr_pages >>  (KVM_CMA_CHUNK_ORDER - PAGE_SHIFT);
-
-	mutex_lock(&kvm_cma_mutex);
-	bitmap_clear(cma->bitmap,
-		     (pfn - cma->base_pfn) >> (KVM_CMA_CHUNK_ORDER - PAGE_SHIFT),
-		     nr_chunk);
-	free_contig_range(pfn, nr_pages);
-	mutex_unlock(&kvm_cma_mutex);
-
-	return true;
-}
-
-static int __init kvm_cma_activate_area(unsigned long base_pfn,
-					unsigned long count)
-{
-	unsigned long pfn = base_pfn;
-	unsigned i = count >> pageblock_order;
-	struct zone *zone;
-
-	WARN_ON_ONCE(!pfn_valid(pfn));
-	zone = page_zone(pfn_to_page(pfn));
-	do {
-		unsigned j;
-		base_pfn = pfn;
-		for (j = pageblock_nr_pages; j; --j, pfn++) {
-			WARN_ON_ONCE(!pfn_valid(pfn));
-			/*
-			 * alloc_contig_range requires the pfn range
-			 * specified to be in the same zone. Make this
-			 * simple by forcing the entire CMA resv range
-			 * to be in the same zone.
-			 */
-			if (page_zone(pfn_to_page(pfn)) != zone)
-				return -EINVAL;
-		}
-		init_cma_reserved_pageblock(pfn_to_page(base_pfn));
-	} while (--i);
-	return 0;
-}
-
-static int __init kvm_cma_init_reserved_areas(void)
-{
-	int bitmap_size, ret;
-	unsigned long chunk_count;
-	struct kvm_cma *cma = &kvm_cma_area;
-
-	pr_debug("%s()\n", __func__);
-	if (!cma->count)
-		return 0;
-	chunk_count = cma->count >> (KVM_CMA_CHUNK_ORDER - PAGE_SHIFT);
-	bitmap_size = BITS_TO_LONGS(chunk_count) * sizeof(long);
-	cma->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
-	if (!cma->bitmap)
-		return -ENOMEM;
-
-	ret = kvm_cma_activate_area(cma->base_pfn, cma->count);
-	if (ret)
-		goto error;
-	return 0;
-
-error:
-	kfree(cma->bitmap);
-	return ret;
-}
-core_initcall(kvm_cma_init_reserved_areas);
diff --git a/arch/powerpc/kvm/book3s_hv_cma.h b/arch/powerpc/kvm/book3s_hv_cma.h
deleted file mode 100644
index 655144f..0000000
--- a/arch/powerpc/kvm/book3s_hv_cma.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Contiguous Memory Allocator for ppc KVM hash pagetable  based on CMA
- * for DMA mapping framework
- *
- * Copyright IBM Corporation, 2013
- * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License or (at your optional) any later version of the license.
- *
- */
-
-#ifndef __POWERPC_KVM_CMA_ALLOC_H__
-#define __POWERPC_KVM_CMA_ALLOC_H__
-/*
- * Both RMA and Hash page allocation will be multiple of 256K.
- */
-#define KVM_CMA_CHUNK_ORDER	18
-
-extern struct page *kvm_alloc_cma(unsigned long nr_pages,
-				  unsigned long align_pages);
-extern bool kvm_release_cma(struct page *pages, unsigned long nr_pages);
-extern long kvm_cma_declare_contiguous(phys_addr_t size,
-				       phys_addr_t alignment) __init;
-#endif
-- 
1.7.9.5

^ permalink raw reply related

* Re: [PATCH 4/4] powerpc/eeh: Avoid event on passed PE
From: Paul Mackerras @ 2014-06-03  5:54 UTC (permalink / raw)
  To: Alexander Graf
  Cc: aik, Gavin Shan, kvm-ppc, alex.williamson, qiudayu, linuxppc-dev
In-Reply-To: <537B3B97.3020100@suse.de>

On Tue, May 20, 2014 at 01:25:11PM +0200, Alexander Graf wrote:
> 
> On 20.05.14 10:30, Gavin Shan wrote:
> >If we detects frozen state on PE that has been passed to guest, we
> >needn't handle it. Instead, we rely on the guest to detect and recover
> >it. The patch avoid EEH event on the frozen passed PE so that the guest
> >can have chance to handle that.
> >
> >Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
> 
> How does the guest learn about this failure? We'd need to inject an error
> into it, no?
> 
> I think what you want is an irqfd that the in-kernel eeh code notifies when
> it sees a failure. When such an fd exists, the kernel skips its own error
> handling.

Well... we don't have irqfd support for book3s HV upstream yet.  The
way the current code is, we have to turn on GSI routing, which puts a
hard and relatively small limit on the hardware IRQ numbers we can use
as it uses a flat array indexed by hardware IRQ number.  Which is a
problem that I need to solve somehow, but it makes using an irqfd
unattractive in the short term.

Paul.

^ permalink raw reply

* Re: [PATCH] powerpc, xmon: Enable hardware instruction breakpoint support on POWER8
From: Anshuman Khandual @ 2014-06-03  6:03 UTC (permalink / raw)
  To: Aneesh Kumar K.V; +Cc: linuxppc-dev, mikey
In-Reply-To: <8761knl6x5.fsf@linux.vnet.ibm.com>

On 05/30/2014 07:12 PM, Aneesh Kumar K.V wrote:
> Anshuman Khandual <khandual@linux.vnet.ibm.com> writes:
> 
>> This patch enables support for hardware instruction breakpoints on POWER8 with
>> the help of a new register called CIABR (Completed Instruction Address Breakpoint
>> Register). With this patch, single hardware instruction breakpoint can be added
>> and cleared during any active xmon debug session. This hardware based instruction
>> breakpoint mechanism works correctly along with the existing TRAP based instruction
>> breakpoints available on xmon. Example usage as follows.
>>
>> (A) Start xmon:
>> $echo x > /proc/sysrq-trigger
>> SysRq : Entering xmon
>> cpu 0x0: Vector: 0  at [c000001f6c67f960]
>>     pc: c000000000072078: .sysrq_handle_xmon+0x58/0x60
>>     lr: c000000000072078: .sysrq_handle_xmon+0x58/0x60
>>     sp: c000001f6c67fac0
>>    msr: 9000000000009032
>>   current = 0xc000001f6e709ac0
>>   paca    = 0xc00000000fffa000   softe: 0        irq_happened: 0x00
>>     pid   = 3250, comm = bash
>> enter ? for help
>> 0:mon> b
>>    type            address
>>
>> (B) Set the breakpoint:
>> 0:mon> ls .power_pmu_add
>> .power_pmu_add: c000000000078f50
>> 0:mon> bi c000000000078f50
>> 0:mon> b
>>    type            address
>>  1 inst   c000000000078f50  .power_pmu_add+0x0/0x2e0
>> 0:mon> ls .perf_event_interrupt
>> .perf_event_interrupt: c00000000007aee0
>> 0:mon> bi c00000000007aee0
>> One instruction breakpoint possible with CIABR
>> 0:mon> x
>>
>> (C) Run the workload (with the breakpoint):
>> $./perf record ls
>> cpu 0x2: Vector: d00 (Single Step) at [c000001f718133a0]
>>     pc: c000000000078f54: .power_pmu_add+0x4/0x2e0
>>     lr: c000000000155be0: .event_sched_in+0x90/0x1d0
>>     sp: c000001f71813620
>>    msr: 9000000040109032
>>   current = 0xc000001f6ce30000
>>   paca    = 0xc00000000fffa600   softe: 0        irq_happened: 0x01
>>     pid   = 3270, comm = ls
>>         std     r22,-80(r1)
>> enter ? for help
>>
>> (D) Clear the breakpoint:
>> 2:mon> bc
>> All breakpoints cleared
>> 2:mon> x
>> [ perf record: Woken up 1 times to write data ]
>> [ perf record: Captured and wrote 0.002 MB perf.data (~66 samples) ]
>>
>> (E) Run the workload again (without any breakpoints):
>> $./perf record ls
>> [ perf record: Woken up 1 times to write data ]
>> [ perf record: Captured and wrote 0.001 MB perf.data (~61 samples) ]
>>
>> Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
>> ---
>>  arch/powerpc/xmon/xmon.c | 62 ++++++++++++++++++++++++++++++++++++++++++++----
>>  1 file changed, 58 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
>> index 3fd1d9a..f74ec83 100644
>> --- a/arch/powerpc/xmon/xmon.c
>> +++ b/arch/powerpc/xmon/xmon.c
>> @@ -48,6 +48,7 @@
>>  #ifdef CONFIG_PPC64
>>  #include <asm/hvcall.h>
>>  #include <asm/paca.h>
>> +#include <asm/plpar_wrappers.h>
>>  #endif
>>  
>>  #include "nonstdio.h"
>> @@ -89,6 +90,7 @@ struct bpt {
>>  /* Bits in bpt.enabled */
>>  #define BP_IABR_TE	1		/* IABR translation enabled */
>>  #define BP_IABR		2
>> +#define BP_CIABR	4
>>  #define BP_TRAP		8
>>  #define BP_DABR		0x10
>>  
>> @@ -97,6 +99,7 @@ static struct bpt bpts[NBPTS];
>>  static struct bpt dabr;
>>  static struct bpt *iabr;
>>  static unsigned bpinstr = 0x7fe00008;	/* trap */
>> +static bool ciabr_used = false;		/* CIABR instruction breakpoint */
>>  
>>  #define BP_NUM(bp)	((bp) - bpts + 1)
>>  
>> @@ -269,6 +272,34 @@ static inline void cinval(void *p)
>>  	asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
>>  }
>>  
>> +static void write_ciabr(unsigned long ciabr)
>> +{
>> +	if (cpu_has_feature(CPU_FTR_HVMODE)) {
>> +		mtspr(SPRN_CIABR, ciabr);
>> +		return;
>> +	}
>> +
>> +#ifdef CONFIG_PPC64
>> +	plapr_set_ciabr(ciabr);
>> +#endif
>> +}
>> +
>> +static void set_ciabr(unsigned long addr)
>> +{
>> +	addr &= ~CIABR_PRIV;
>> +	if (cpu_has_feature(CPU_FTR_HVMODE))
>> +		addr |= CIABR_PRIV_HYPER;
>> +	else
>> +		addr |= CIABR_PRIV_SUPER;
>> +	write_ciabr(addr);
>> +}
>> +
>> +static void clear_ciabr(void)
>> +{
>> +	if (cpu_has_feature(CPU_FTR_ARCH_207S))
>> +		write_ciabr(0);
>> +}
>> +
>>  /*
>>   * Disable surveillance (the service processor watchdog function)
>>   * while we are in xmon.
>> @@ -764,6 +795,9 @@ static void insert_cpu_bpts(void)
>>  	if (iabr && cpu_has_feature(CPU_FTR_IABR))
>>  		mtspr(SPRN_IABR, iabr->address
>>  			 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
>> +
>> +	if (iabr && cpu_has_feature(CPU_FTR_ARCH_207S))
>> +		set_ciabr(iabr->address);
>>  }
>>  
>>  static void remove_bpts(void)
>> @@ -791,6 +825,7 @@ static void remove_cpu_bpts(void)
>>  	hw_breakpoint_disable();
>>  	if (cpu_has_feature(CPU_FTR_IABR))
>>  		mtspr(SPRN_IABR, 0);
>> +	clear_ciabr();
>>  }
>>  
>>  /* Command interpreting routine */
>> @@ -1124,7 +1159,7 @@ static char *breakpoint_help_string =
>>      "b <addr> [cnt]   set breakpoint at given instr addr\n"
>>      "bc               clear all breakpoints\n"
>>      "bc <n/addr>      clear breakpoint number n or at addr\n"
>> -    "bi <addr> [cnt]  set hardware instr breakpoint (POWER3/RS64 only)\n"
>> +    "bi <addr> [cnt]  set hardware instr breakpoint (POWER3/RS64/POWER8 only)\n"
>>      "bd <addr> [cnt]  set hardware data breakpoint\n"
>>      "";
>>  
>> @@ -1163,11 +1198,20 @@ bpt_cmds(void)
>>  		break;
>>  
>>  	case 'i':	/* bi - hardware instr breakpoint */
>> -		if (!cpu_has_feature(CPU_FTR_IABR)) {
>> +		if (!cpu_has_feature(CPU_FTR_IABR) && !cpu_has_feature(CPU_FTR_ARCH_207S)) {
>>  			printf("Hardware instruction breakpoint "
>>  			       "not supported on this cpu\n");
>>  			break;
>>  		}
>> +
>> +		if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
>> +			if (ciabr_used) {
>> +				printf("One instruction breakpoint "
>> +					"possible with CIABR\n");
>> +				break;
>> +			}
> 
> We don't seem to do that with iabr ? Why keep ciabr different 

Right now with the IABR implementation if we try to set hardware instruction
breakpoint while one is already there, it just get overridden with the new
address without complaining. I thought with this at least for CIABR cases,
it will complain about it and require the user to clear the breakpoint
explicitly before allowing a new breakpoint. Okay will remove this.
 
> 
>> +		}
> 
> 
> Why is this implemented different than existing iabr, You could do this
> with iabr and iabr->enabled = BP_CIABR right ?

Did not get it, yeah its implemented in that way only. 

^ permalink raw reply

* FMD15 and t104x
From: Tony @ 2014-06-03  6:43 UTC (permalink / raw)
  To: linuxppc-dev

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

Hi,

I am working with 3.0.x kernel with fmd15. I could bringup the t1040qsd but
the ethernet is not getting detected. Is t104x devices required backporting
of FMD19 ? OR modifying the dts file is enough ?

Thanks
Alan

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

^ permalink raw reply

* Re: [RFC PATCH 1/3] CMA: generalize CMA reserved area management functionality
From: Michal Nazarewicz @ 2014-06-03  6:56 UTC (permalink / raw)
  To: Joonsoo Kim, Andrew Morton, Aneesh Kumar K.V, Marek Szyprowski
  Cc: Russell King - ARM Linux, kvm, linux-mm, Gleb Natapov,
	Greg Kroah-Hartman, Alexander Graf, kvm-ppc, linux-kernel,
	Minchan Kim, Paul Mackerras, Paolo Bonzini, Joonsoo Kim,
	linuxppc-dev, linux-arm-kernel
In-Reply-To: <1401757919-30018-2-git-send-email-iamjoonsoo.kim@lge.com>

On Tue, Jun 03 2014, Joonsoo Kim wrote:
> Currently, there are two users on CMA functionality, one is the DMA
> subsystem and the other is the kvm on powerpc. They have their own code
> to manage CMA reserved area even if they looks really similar.
> From my guess, it is caused by some needs on bitmap management. Kvm side
> wants to maintain bitmap not for 1 page, but for more size. Eventually it
> use bitmap where one bit represents 64 pages.
>
> When I implement CMA related patches, I should change those two places
> to apply my change and it seem to be painful to me. I want to change
> this situation and reduce future code management overhead through
> this patch.
>
> This change could also help developer who want to use CMA in their
> new feature development, since they can use CMA easily without
> copying & pasting this reserved area management code.
>
> Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>

Some small comments below, but in general

Acked-by: Michal Nazarewicz <mina86@mina86.com>

>
> diff --git a/include/linux/cma.h b/include/linux/cma.h
> new file mode 100644
> index 0000000..60ba06f
> --- /dev/null
> +++ b/include/linux/cma.h
> @@ -0,0 +1,28 @@
> +/*
> + * Contiguous Memory Allocator
> + *
> + * Copyright LG Electronics Inc., 2014
> + * Written by:
> + *	Joonsoo Kim <iamjoonsoo.kim@lge.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of the
> + * License or (at your optional) any later version of the license.
> + *

Superfluous empty comment line.

Also, I'm not certain whether this copyright notice is appropriate here,
but that's another story.

> + */
> +
> +#ifndef __CMA_H__
> +#define __CMA_H__
> +
> +struct cma;
> +
> +extern struct page *cma_alloc(struct cma *cma, unsigned long count,
> +				unsigned long align);
> +extern bool cma_release(struct cma *cma, struct page *pages,
> +				unsigned long count);
> +extern int __init cma_declare_contiguous(phys_addr_t size, phys_addr_t b=
ase,
> +				phys_addr_t limit, phys_addr_t alignment,
> +				unsigned long bitmap_shift, bool fixed,
> +				struct cma **res_cma);
> +#endif

> diff --git a/mm/cma.c b/mm/cma.c
> new file mode 100644
> index 0000000..0dae88d
> --- /dev/null
> +++ b/mm/cma.c
> @@ -0,0 +1,329 @@

> +static int __init cma_activate_area(struct cma *cma)
> +{
> +	int max_bitmapno =3D cma_bitmap_max_no(cma);
> +	int bitmap_size =3D BITS_TO_LONGS(max_bitmapno) * sizeof(long);
> +	unsigned long base_pfn =3D cma->base_pfn, pfn =3D base_pfn;
> +	unsigned i =3D cma->count >> pageblock_order;
> +	struct zone *zone;
> +
> +	pr_debug("%s()\n", __func__);
> +	if (!cma->count)
> +		return 0;

Alternatively:

+	if (!i)
+		return 0;

> +
> +	cma->bitmap =3D kzalloc(bitmap_size, GFP_KERNEL);
> +	if (!cma->bitmap)
> +		return -ENOMEM;
> +
> +	WARN_ON_ONCE(!pfn_valid(pfn));
> +	zone =3D page_zone(pfn_to_page(pfn));
> +
> +	do {
> +		unsigned j;
> +
> +		base_pfn =3D pfn;
> +		for (j =3D pageblock_nr_pages; j; --j, pfn++) {
> +			WARN_ON_ONCE(!pfn_valid(pfn));
> +			/*
> +			 * alloc_contig_range requires the pfn range
> +			 * specified to be in the same zone. Make this
> +			 * simple by forcing the entire CMA resv range
> +			 * to be in the same zone.
> +			 */
> +			if (page_zone(pfn_to_page(pfn)) !=3D zone)
> +				goto err;
> +		}
> +		init_cma_reserved_pageblock(pfn_to_page(base_pfn));
> +	} while (--i);
> +
> +	mutex_init(&cma->lock);
> +	return 0;
> +
> +err:
> +	kfree(cma->bitmap);
> +	return -EINVAL;
> +}

> +static int __init cma_init_reserved_areas(void)
> +{
> +	int i;
> +
> +	for (i =3D 0; i < cma_area_count; i++) {
> +		int ret =3D cma_activate_area(&cma_areas[i]);
> +
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}

Or even:

static int __init cma_init_reserved_areas(void)
{
	int i, ret =3D 0;
	for (i =3D 0; !ret && i < cma_area_count; ++i)
		ret =3D cma_activate_area(&cma_areas[i]);
	return ret;
}

> +int __init cma_declare_contiguous(phys_addr_t size, phys_addr_t base,
> +				phys_addr_t limit, phys_addr_t alignment,
> +				unsigned long bitmap_shift, bool fixed,
> +				struct cma **res_cma)
> +{
> +	struct cma *cma =3D &cma_areas[cma_area_count];

Perhaps it would make sense to move this initialisation to the far end
of this function?

> +	int ret =3D 0;
> +
> +	pr_debug("%s(size %lx, base %08lx, limit %08lx, alignment %08lx)\n",
> +			__func__, (unsigned long)size, (unsigned long)base,
> +			(unsigned long)limit, (unsigned long)alignment);
> +
> +	/* Sanity checks */
> +	if (cma_area_count =3D=3D ARRAY_SIZE(cma_areas)) {
> +		pr_err("Not enough slots for CMA reserved regions!\n");
> +		return -ENOSPC;
> +	}
> +
> +	if (!size)
> +		return -EINVAL;
> +
> +	/*
> +	 * Sanitise input arguments.
> +	 * CMA area should be at least MAX_ORDER - 1 aligned. Otherwise,
> +	 * CMA area could be merged into other MIGRATE_TYPE by buddy mechanism
> +	 * and CMA property will be broken.
> +	 */
> +	alignment >>=3D PAGE_SHIFT;
> +	alignment =3D PAGE_SIZE << max3(MAX_ORDER - 1, pageblock_order,
> +						(int)alignment);
> +	base =3D ALIGN(base, alignment);
> +	size =3D ALIGN(size, alignment);
> +	limit &=3D ~(alignment - 1);
> +	/* size should be aligned with bitmap_shift */
> +	BUG_ON(!IS_ALIGNED(size >> PAGE_SHIFT, 1 << cma->bitmap_shift));

cma->bitmap_shift is not yet initialised thus the above line should be:

	BUG_ON(!IS_ALIGNED(size >> PAGE_SHIFT, 1 << bitmap_shift));

> +
> +	/* Reserve memory */
> +	if (base && fixed) {
> +		if (memblock_is_region_reserved(base, size) ||
> +		    memblock_reserve(base, size) < 0) {
> +			ret =3D -EBUSY;
> +			goto err;
> +		}
> +	} else {
> +		phys_addr_t addr =3D memblock_alloc_range(size, alignment, base,
> +							limit);
> +		if (!addr) {
> +			ret =3D -ENOMEM;
> +			goto err;
> +		} else {
> +			base =3D addr;
> +		}
> +	}
> +
> +	/*
> +	 * Each reserved area must be initialised later, when more kernel
> +	 * subsystems (like slab allocator) are available.
> +	 */
> +	cma->base_pfn =3D PFN_DOWN(base);
> +	cma->count =3D size >> PAGE_SHIFT;
> +	cma->bitmap_shift =3D bitmap_shift;
> +	*res_cma =3D cma;
> +	cma_area_count++;
> +
> +	pr_info("CMA: reserved %ld MiB at %08lx\n", (unsigned long)size / SZ_1M,
> +		(unsigned long)base);

Doesn't this message end up being: =E2=80=9Ccma: CMA: reserved =E2=80=A6=E2=
=80=9D? pr_fmt adds
=E2=80=9Ccma:=E2=80=9D at the beginning, doesn't it?  So we should probably=
 drop =E2=80=9CCMA:=E2=80=9D
here.

> +
> +	return 0;
> +
> +err:
> +	pr_err("CMA: failed to reserve %ld MiB\n", (unsigned long)size / SZ_1M);
> +	return ret;
> +}

--=20
Best regards,                                         _     _
.o. | Liege of Serenely Enlightened Majesty of      o' \,=3D./ `o
..o | Computer Science,  Micha=C5=82 =E2=80=9Cmina86=E2=80=9D Nazarewicz   =
 (o o)
ooo +--<mpn@google.com>--<xmpp:mina86@jabber.org>--ooO--(_)--Ooo--

^ permalink raw reply

* Re: [RFC PATCH 2/3] DMA, CMA: use general CMA reserved area management framework
From: Michal Nazarewicz @ 2014-06-03  7:00 UTC (permalink / raw)
  To: Joonsoo Kim, Andrew Morton, Aneesh Kumar K.V, Marek Szyprowski
  Cc: Russell King - ARM Linux, kvm, linux-mm, Gleb Natapov,
	Greg Kroah-Hartman, Alexander Graf, kvm-ppc, linux-kernel,
	Minchan Kim, Paul Mackerras, Paolo Bonzini, Joonsoo Kim,
	linuxppc-dev, linux-arm-kernel
In-Reply-To: <1401757919-30018-3-git-send-email-iamjoonsoo.kim@lge.com>

On Tue, Jun 03 2014, Joonsoo Kim wrote:
> Now, we have general CMA reserved area management framework,
> so use it for future maintainabilty. There is no functional change.
>
> Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>

Acked-by: Michal Nazarewicz <mina86@mina86.com>

> diff --git a/include/linux/dma-contiguous.h b/include/linux/dma-contiguou=
s.h
> index dfb1dc9..ecb85ac 100644
> --- a/include/linux/dma-contiguous.h
> +++ b/include/linux/dma-contiguous.h
> @@ -53,9 +53,10 @@
>=20=20
>  #ifdef __KERNEL__
>=20=20
> +#include <linux/device.h>
> +

Why is this suddenly required?

>  struct cma;
>  struct page;
> -struct device;
>=20=20
>  #ifdef CONFIG_DMA_CMA

--=20
Best regards,                                         _     _
.o. | Liege of Serenely Enlightened Majesty of      o' \,=3D./ `o
..o | Computer Science,  Micha=C5=82 =E2=80=9Cmina86=E2=80=9D Nazarewicz   =
 (o o)
ooo +--<mpn@google.com>--<xmpp:mina86@jabber.org>--ooO--(_)--Ooo--

^ permalink raw reply

* Re: [RFC PATCH 3/3] PPC, KVM, CMA: use general CMA reserved area management framework
From: Michal Nazarewicz @ 2014-06-03  7:02 UTC (permalink / raw)
  To: Joonsoo Kim, Andrew Morton, Aneesh Kumar K.V, Marek Szyprowski
  Cc: Russell King - ARM Linux, kvm, linux-mm, Gleb Natapov,
	Greg Kroah-Hartman, Alexander Graf, kvm-ppc, linux-kernel,
	Minchan Kim, Paul Mackerras, Paolo Bonzini, Joonsoo Kim,
	linuxppc-dev, linux-arm-kernel
In-Reply-To: <1401757919-30018-4-git-send-email-iamjoonsoo.kim@lge.com>

On Tue, Jun 03 2014, Joonsoo Kim wrote:
> Now, we have general CMA reserved area management framework,
> so use it for future maintainabilty. There is no functional change.
>
> Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>

Acked-by: Michal Nazarewicz <mina86@mina86.com>

--=20
Best regards,                                         _     _
.o. | Liege of Serenely Enlightened Majesty of      o' \,=3D./ `o
..o | Computer Science,  Micha=C5=82 =E2=80=9Cmina86=E2=80=9D Nazarewicz   =
 (o o)
ooo +--<mpn@google.com>--<xmpp:mina86@jabber.org>--ooO--(_)--Ooo--

^ permalink raw reply

* [PATCH] powerpc/serial: Use saner flags when creating legacy ports
From: Benjamin Herrenschmidt @ 2014-06-03  7:33 UTC (permalink / raw)
  To: linuxppc-dev list

>From 6679ffd7d85fe8155172774d0ba3370be5e82d1d Mon Sep 17 00:00:00 2001
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Date: Sat, 29 Mar 2014 08:38:36 +1100
Subject: 

We had a mix & match of flags used when creating legacy ports
depending on where we found them in the device-tree. Among others
we were missing UPF_SKIP_TEST for some kind of ISA ports which is
a problem as quite a few UARTs out there don't support the loopback
test (such as a lot of BMCs).

Let's pick the set of flags used by the SoC code and generalize it
which means autoconf, no loopback test, irq maybe shared and fixed
port.

Sending to stable as the lack of UPF_SKIP_TEST is breaking
serial on some machines so I want this back into distros

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: stable@vger.kernel.org
---
 arch/powerpc/kernel/legacy_serial.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index 6f2a15c..085c919 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -48,6 +48,9 @@ static struct __initdata of_device_id legacy_serial_parents[] = {
 static unsigned int legacy_serial_count;
 static int legacy_serial_console = -1;
 
+static const upf_t legacy_port_flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+	UPF_SHARE_IRQ | UPF_FIXED_PORT;
+
 static unsigned int tsi_serial_in(struct uart_port *p, int offset)
 {
 	unsigned int tmp;
@@ -153,8 +156,6 @@ static int __init add_legacy_soc_port(struct device_node *np,
 {
 	u64 addr;
 	const u32 *addrp;
-	upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ
-		| UPF_FIXED_PORT;
 	struct device_node *tsi = of_get_parent(np);
 
 	/* We only support ports that have a clock frequency properly
@@ -185,9 +186,11 @@ static int __init add_legacy_soc_port(struct device_node *np,
 	 * IO port value. It will be fixed up later along with the irq
 	 */
 	if (tsi && !strcmp(tsi->type, "tsi-bridge"))
-		return add_legacy_port(np, -1, UPIO_TSI, addr, addr, NO_IRQ, flags, 0);
+		return add_legacy_port(np, -1, UPIO_TSI, addr, addr,
+				       NO_IRQ, legacy_port_flags, 0);
 	else
-		return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags, 0);
+		return add_legacy_port(np, -1, UPIO_MEM, addr, addr,
+				       NO_IRQ, legacy_port_flags, 0);
 }
 
 static int __init add_legacy_isa_port(struct device_node *np,
@@ -233,7 +236,7 @@ static int __init add_legacy_isa_port(struct device_node *np,
 
 	/* Add port, irq will be dealt with later */
 	return add_legacy_port(np, index, UPIO_PORT, be32_to_cpu(reg[1]),
-			       taddr, NO_IRQ, UPF_BOOT_AUTOCONF, 0);
+			       taddr, NO_IRQ, legacy_port_flags, 0);
 
 }
 
@@ -306,7 +309,7 @@ static int __init add_legacy_pci_port(struct device_node *np,
 	 * IO port value. It will be fixed up later along with the irq
 	 */
 	return add_legacy_port(np, index, iotype, base, addr, NO_IRQ,
-			       UPF_BOOT_AUTOCONF, np != pci_dev);
+			       legacy_port_flags, np != pci_dev);
 }
 #endif
 

^ permalink raw reply related

* Re: [PATCH 4/4] powerpc/eeh: Avoid event on passed PE
From: Alexander Graf @ 2014-06-03  7:45 UTC (permalink / raw)
  To: Paul Mackerras
  Cc: aik@ozlabs.ru, Gavin Shan, kvm-ppc@vger.kernel.org,
	alex.williamson@redhat.com, qiudayu@linux.vnet.ibm.com,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <20140603055415.GA24370@iris.ozlabs.ibm.com>



> Am 03.06.2014 um 07:54 schrieb Paul Mackerras <paulus@samba.org>:
>=20
>> On Tue, May 20, 2014 at 01:25:11PM +0200, Alexander Graf wrote:
>>=20
>>> On 20.05.14 10:30, Gavin Shan wrote:
>>> If we detects frozen state on PE that has been passed to guest, we
>>> needn't handle it. Instead, we rely on the guest to detect and recover
>>> it. The patch avoid EEH event on the frozen passed PE so that the guest
>>> can have chance to handle that.
>>>=20
>>> Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
>>=20
>> How does the guest learn about this failure? We'd need to inject an error=

>> into it, no?
>>=20
>> I think what you want is an irqfd that the in-kernel eeh code notifies wh=
en
>> it sees a failure. When such an fd exists, the kernel skips its own error=

>> handling.
>=20
> Well... we don't have irqfd support for book3s HV upstream yet.  The
> way the current code is, we have to turn on GSI routing, which puts a
> hard and relatively small limit on the hardware IRQ numbers we can use
> as it uses a flat array indexed by hardware IRQ number.  Which is a
> problem that I need to solve somehow,

Please sync up with the ARM folks on this - they were also unhappy about the=
 routing requirements for irqfd ;).

> but it makes using an irqfd
> unattractive in the short term.

For EEH it could as well be a dumb eventfd - really just a side channel that=
 can tell user space that something happened asynchronously :).


Alex

^ permalink raw reply

* Re: [PATCH 4/4] powerpc/eeh: Avoid event on passed PE
From: Benjamin Herrenschmidt @ 2014-06-03  7:52 UTC (permalink / raw)
  To: Alexander Graf
  Cc: aik@ozlabs.ru, Gavin Shan, kvm-ppc@vger.kernel.org,
	alex.williamson@redhat.com, Paul Mackerras,
	qiudayu@linux.vnet.ibm.com, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <5C4E374F-0BE1-4BE3-991C-E6BD64E90E6A@suse.de>

On Tue, 2014-06-03 at 09:45 +0200, Alexander Graf wrote:
> For EEH it could as well be a dumb eventfd - really just a side
> channel that can tell user space that something happened
> asynchronously :).

Which the host kernel may have no way to detect without actively poking
at the device (fences in powernv or anything in PAPR host) and the only
user of this for now has no use for.

I insist don't bother.

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH] powerpc, xmon: Enable hardware instruction breakpoint support on POWER8
From: Anshuman Khandual @ 2014-06-03  8:31 UTC (permalink / raw)
  To: Michael Neuling; +Cc: linuxppc-dev
In-Reply-To: <538C3A49.8030601@linux.vnet.ibm.com>

On 06/02/2014 02:18 PM, Anshuman Khandual wrote:
> On 06/01/2014 11:48 AM, Michael Neuling wrote:
>> > On Fri, 2014-05-30 at 17:40 +0530, Anshuman Khandual wrote:
>>> >> This patch enables support for hardware instruction breakpoints on POWER8 with
>>> >> the help of a new register called CIABR (Completed Instruction Address Breakpoint
>>> >> Register). With this patch, single hardware instruction breakpoint can be added
>>> >> and cleared during any active xmon debug session. This hardware based instruction
>>> >> breakpoint mechanism works correctly along with the existing TRAP based instruction
>>> >> breakpoints available on xmon. Example usage as follows.
>> > 
>> > Have you actually tried this on a guest?
>> > 
> Yeah on a guest which runs on PVM.
> 
>> > Please also compile with a range of configs.  It doesn't compile with
>> > ppc64e_defconfig.
> Yeah. Need to change the way we get the "plapr_set_ciabr" function from plpar_wrappers.h
> header file. Will add this hunk of code in "xmon.h" header and remove the CONFIG_PPC64 ifdef
> code from the function write_ciabr.
> 
> +#ifdef CONFIG_PPC_BOOK3S_64

"#if defined(CONFIG_PPC_BOOK3S_64) && defined(CONFIG_PPC_SPLPAR)" here actually makes it build
on all these configurations listed below.

pseries_defconfig
ppc64_defconfig
ppc64e_defconfig
pmac32_defconfig
ppc44x_defconfig
ppc6xx_defconfig
mpc85xx_smp_defconfig
mpc85xx_defconfig
chroma_defconfig
ps3_defconfig
celleb_defconfig
allnoconfig

^ permalink raw reply

* Re: [PATCH] powerpc/85xx: Add T4240RDB board support
From: Chunhe Lan @ 2014-06-03  8:57 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev, Chunhe Lan
In-Reply-To: <1401485104.6603.221.camel@snotra.buserror.net>

On 05/31/2014 05:25 AM, Scott Wood wrote:
> On Wed, 2014-05-28 at 16:11 +0800, Chunhe Lan wrote:
>> diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c
>> index 8e4b1e1..2f50526 100644
>> --- a/arch/powerpc/platforms/85xx/corenet_generic.c
>> +++ b/arch/powerpc/platforms/85xx/corenet_generic.c
>> @@ -119,6 +119,7 @@ static const char * const boards[] __initconst = {
>>   	"fsl,P5020DS",
>>   	"fsl,P5040DS",
>>   	"fsl,T4240QDS",
>> +	"fsl,T4240RDB",
>>   	"fsl,B4860QDS",
>>   	"fsl,B4420QDS",
>>   	"fsl,B4220QDS",
> What about hv_boards?
     Does not have hv boards. So does not support hv.

Thanks,
-Chunhe
>
> -Scott
>
>

^ permalink raw reply

* [PATCH v2] powerpc/85xx: Add T4240RDB board support
From: Chunhe Lan @ 2014-06-03  9:10 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Scott Wood, Chunhe Lan

T4240RDB board Specification
----------------------------
Memory subsystem:
     6GB DDR3
     128MB NOR flash
     2GB NAND flash
Ethernet:
     Eight 1G SGMII ports
     Four 10Gbps SFP+ ports
PCIe:
     Two PCIe slots
USB:
     Two USB2.0 Type A ports
SDHC:
     One SD-card port
SATA:
     One SATA port
UART:
     Dual RJ45 ports

Signed-off-by: Chunhe Lan <Chunhe.Lan@freescale.com>
Cc: Scott Wood <scottwood@freescale.com>
---
 arch/powerpc/boot/dts/t4240rdb.dts            |  186 +++++++++++++++++++++++++
 arch/powerpc/configs/corenet64_smp_defconfig  |    4 +
 arch/powerpc/platforms/85xx/Kconfig           |    2 +-
 arch/powerpc/platforms/85xx/corenet_generic.c |    1 +
 4 files changed, 192 insertions(+), 1 deletions(-)
 create mode 100644 arch/powerpc/boot/dts/t4240rdb.dts

diff --git a/arch/powerpc/boot/dts/t4240rdb.dts b/arch/powerpc/boot/dts/t4240rdb.dts
new file mode 100644
index 0000000..53761d4
--- /dev/null
+++ b/arch/powerpc/boot/dts/t4240rdb.dts
@@ -0,0 +1,186 @@
+/*
+ * T4240RDB Device Tree Source
+ *
+ * Copyright 2014 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *	 notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *	 notice, this list of conditions and the following disclaimer in the
+ *	 documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *	 names of its contributors may be used to endorse or promote products
+ *	 derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/include/ "fsl/t4240si-pre.dtsi"
+
+/ {
+	model = "fsl,T4240RDB";
+	compatible = "fsl,T4240RDB";
+	#address-cells = <2>;
+	#size-cells = <2>;
+	interrupt-parent = <&mpic>;
+
+	ifc: localbus@ffe124000 {
+		reg = <0xf 0xfe124000 0 0x2000>;
+		ranges = <0 0 0xf 0xe8000000 0x08000000
+			  2 0 0xf 0xff800000 0x00010000
+			  3 0 0xf 0xffdf0000 0x00008000>;
+
+		nor@0,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "cfi-flash";
+			reg = <0x0 0x0 0x8000000>;
+
+			bank-width = <2>;
+			device-width = <1>;
+		};
+
+		nand@2,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,ifc-nand";
+			reg = <0x2 0x0 0x10000>;
+		};
+	};
+
+	memory {
+		device_type = "memory";
+	};
+
+	dcsr: dcsr@f00000000 {
+		ranges = <0x00000000 0xf 0x00000000 0x01072000>;
+	};
+
+	soc: soc@ffe000000 {
+		ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+		reg = <0xf 0xfe000000 0 0x00001000>;
+		spi@110000 {
+			flash@0 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				compatible = "sst,sst25wf040";
+				reg = <0>;
+				spi-max-frequency = <40000000>; /* input clock */
+			};
+		};
+
+		i2c@118000 {
+			eeprom@52 {
+				compatible = "at24,24c256";
+				reg = <0x52>;
+			};
+			eeprom@54 {
+				compatible = "at24,24c256";
+				reg = <0x54>;
+			};
+			eeprom@56 {
+				compatible = "at24,24c256";
+				reg = <0x56>;
+			};
+			rtc@68 {
+				compatible = "dallas,ds1374";
+				reg = <0x68>;
+				interrupts = <0x1 0x1 0 0>;
+			};
+		};
+
+		sdhc@114000 {
+			voltage-ranges = <1800 1800 3300 3300>;
+		};
+	};
+
+	pci0: pcie@ffe240000 {
+		reg = <0xf 0xfe240000 0 0x10000>;
+		ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+			  0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
+		pcie@0 {
+			ranges = <0x02000000 0 0xe0000000
+				  0x02000000 0 0xe0000000
+				  0 0x20000000
+
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00010000>;
+		};
+	};
+
+	pci1: pcie@ffe250000 {
+		reg = <0xf 0xfe250000 0 0x10000>;
+		ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
+			  0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
+		pcie@0 {
+			ranges = <0x02000000 0 0xe0000000
+				  0x02000000 0 0xe0000000
+				  0 0x20000000
+
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00010000>;
+		};
+	};
+
+	pci2: pcie@ffe260000 {
+		reg = <0xf 0xfe260000 0 0x1000>;
+		ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
+			  0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
+		pcie@0 {
+			ranges = <0x02000000 0 0xe0000000
+				  0x02000000 0 0xe0000000
+				  0 0x20000000
+
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00010000>;
+		};
+	};
+
+	pci3: pcie@ffe270000 {
+		reg = <0xf 0xfe270000 0 0x10000>;
+		ranges = <0x02000000 0 0xe0000000 0xc 0x60000000 0 0x20000000
+			  0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
+		pcie@0 {
+			ranges = <0x02000000 0 0xe0000000
+				  0x02000000 0 0xe0000000
+				  0 0x20000000
+
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00010000>;
+		};
+	};
+
+	rio: rapidio@ffe0c0000 {
+		reg = <0xf 0xfe0c0000 0 0x11000>;
+
+		port1 {
+			ranges = <0 0 0xc 0x20000000 0 0x10000000>;
+		};
+		port2 {
+			ranges = <0 0 0xc 0x30000000 0 0x10000000>;
+		};
+	};
+};
+
+/include/ "fsl/t4240si-post.dtsi"
diff --git a/arch/powerpc/configs/corenet64_smp_defconfig b/arch/powerpc/configs/corenet64_smp_defconfig
index 5c7fa19..4f17b3d 100644
--- a/arch/powerpc/configs/corenet64_smp_defconfig
+++ b/arch/powerpc/configs/corenet64_smp_defconfig
@@ -96,6 +96,8 @@ CONFIG_SATA_SIL24=y
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=y
 CONFIG_E1000E=y
+CONFIG_PHYLIB=y
+CONFIG_VITESSE_PHY=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_KEYBOARD is not set
@@ -125,6 +127,8 @@ CONFIG_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_EDAC=y
 CONFIG_EDAC_MM_EDAC=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1374=y
 CONFIG_DMADEVICES=y
 CONFIG_FSL_DMA=y
 CONFIG_EXT2_FS=y
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index c17aae8..d66321e 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -265,7 +265,7 @@ config CORENET_GENERIC
 	  For 32bit kernel, the following boards are supported:
 	    P2041 RDB, P3041 DS and P4080 DS
 	  For 64bit kernel, the following boards are supported:
-	    T4240 QDS and B4 QDS
+	    T4240 QDS/RDB and B4 QDS
 	  The following boards are supported for both 32bit and 64bit kernel:
 	    P5020 DS and P5040 DS
 
diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c
index 8e4b1e1..2f50526 100644
--- a/arch/powerpc/platforms/85xx/corenet_generic.c
+++ b/arch/powerpc/platforms/85xx/corenet_generic.c
@@ -119,6 +119,7 @@ static const char * const boards[] __initconst = {
 	"fsl,P5020DS",
 	"fsl,P5040DS",
 	"fsl,T4240QDS",
+	"fsl,T4240RDB",
 	"fsl,B4860QDS",
 	"fsl,B4420QDS",
 	"fsl,B4220QDS",
-- 
1.7.6.5

^ permalink raw reply related

* Re: [RFC PATCH 3/3] PPC, KVM, CMA: use general CMA reserved area management framework
From: Paolo Bonzini @ 2014-06-03  9:20 UTC (permalink / raw)
  To: Michal Nazarewicz, Joonsoo Kim, Andrew Morton, Aneesh Kumar K.V,
	Marek Szyprowski
  Cc: Russell King - ARM Linux, kvm, linux-mm, Gleb Natapov,
	Alexander Graf, kvm-ppc, linux-kernel, Minchan Kim,
	Paul Mackerras, Greg Kroah-Hartman, linuxppc-dev,
	linux-arm-kernel
In-Reply-To: <xa1ttx82jx1i.fsf@mina86.com>

Il 03/06/2014 09:02, Michal Nazarewicz ha scritto:
> On Tue, Jun 03 2014, Joonsoo Kim wrote:
>> Now, we have general CMA reserved area management framework,
>> so use it for future maintainabilty. There is no functional change.
>>
>> Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
>
> Acked-by: Michal Nazarewicz <mina86@mina86.com>
>

Acked-by: Paolo Bonzini <pbonzini@redhat.com>

Aneesh, can you test this series?

Paolo

^ permalink raw reply

* Re: [PATCH v2] powerpc/85xx: Add T4240RDB board support
From: Tudor Laurentiu @ 2014-06-03  9:59 UTC (permalink / raw)
  To: Chunhe Lan; +Cc: Scott Wood, linuxppc-dev
In-Reply-To: <1401786611-30378-1-git-send-email-Chunhe.Lan@freescale.com>

Hi Chunhe

Comment inline ...

On 06/03/2014 12:10 PM, Chunhe Lan wrote:
> T4240RDB board Specification
> ----------------------------
> Memory subsystem:
>       6GB DDR3
>       128MB NOR flash
>       2GB NAND flash
> Ethernet:
>       Eight 1G SGMII ports
>       Four 10Gbps SFP+ ports
> PCIe:
>       Two PCIe slots
> USB:
>       Two USB2.0 Type A ports
> SDHC:
>       One SD-card port
> SATA:
>       One SATA port
> UART:
>       Dual RJ45 ports
>
> Signed-off-by: Chunhe Lan <Chunhe.Lan@freescale.com>
> Cc: Scott Wood <scottwood@freescale.com>
> ---

[snip]

>
> diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c
> index 8e4b1e1..2f50526 100644
> --- a/arch/powerpc/platforms/85xx/corenet_generic.c
> +++ b/arch/powerpc/platforms/85xx/corenet_generic.c
> @@ -119,6 +119,7 @@ static const char * const boards[] __initconst = {
>   	"fsl,P5020DS",
>   	"fsl,P5040DS",
>   	"fsl,T4240QDS",
> +	"fsl,T4240RDB",

T4240RDB is supported & tested under hypervisor so please also add the 
hypervisor compatible in the "hv_boards" array below.

---
Thanks & Best Regards, Laurentiu

^ permalink raw reply

* [PATCH] powerpc/powernv: Provide debugfs access to the LPC bus via OPAL
From: Benjamin Herrenschmidt @ 2014-06-03 10:07 UTC (permalink / raw)
  To: linuxppc-dev list; +Cc: Rob Lippert

This provides debugfs files to access the LPC bus on Power8
non-virtualized using the appropriate OPAL firmware calls.

The usage is simple: one file per space (IO, MEM and FW),
lseek to the address and read/write the data. IO and MEM always
generate series of byte accesses. FW can generate word and dword
accesses if aligned properly.

Based on an original patch from Rob Lippert and reworked.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 arch/powerpc/platforms/powernv/opal-lpc.c |  150 +++++++++++++++++++++++++++++
 1 file changed, 150 insertions(+)

diff --git a/arch/powerpc/platforms/powernv/opal-lpc.c b/arch/powerpc/platforms/powernv/opal-lpc.c
index 79d83ca..70eff22 100644
--- a/arch/powerpc/platforms/powernv/opal-lpc.c
+++ b/arch/powerpc/platforms/powernv/opal-lpc.c
@@ -12,12 +12,16 @@
 #include <linux/kernel.h>
 #include <linux/of.h>
 #include <linux/bug.h>
+#include <linux/debugfs.h>
+#include <linux/io.h>
+#include <linux/slab.h>
 
 #include <asm/machdep.h>
 #include <asm/firmware.h>
 #include <asm/xics.h>
 #include <asm/opal.h>
 #include <asm/prom.h>
+#include <asm/uaccess.h>
 
 static int opal_lpc_chip_id = -1;
 
@@ -176,6 +180,152 @@ static const struct ppc_pci_io opal_lpc_io = {
 	.outsl	= opal_lpc_outsl,
 };
 
+#ifdef CONFIG_DEBUG_FS
+struct lpc_debugfs_entry {
+	enum OpalLPCAddressType lpc_type;
+};
+
+static ssize_t lpc_debug_read(struct file *filp, char __user *ubuf,
+			      size_t count, loff_t *ppos)
+{
+	struct lpc_debugfs_entry *lpc = filp->private_data;
+	u32 data, pos, len, todo;
+	int rc;
+
+	if (!access_ok(VERIFY_WRITE, ubuf, count))
+		return -EFAULT;
+
+	todo = count;
+	while (todo) {
+		pos = *ppos;
+
+		/*
+		 * Select access size based on count and alignment and
+		 * access type. IO and MEM only support byte acceses,
+		 * FW supports all 3.
+		 */
+		len = 1;
+		if (lpc->lpc_type == OPAL_LPC_FW) {
+			if (todo > 3 && (pos & 3) == 0)
+				len = 4;
+			else if (todo > 1 && (pos & 1) == 0)
+				len = 2;
+		}
+		rc = opal_lpc_read(opal_lpc_chip_id, lpc->lpc_type, pos,
+				   &data, len);
+		if (rc)
+			return -ENXIO;
+		switch(len) {
+		case 4:
+			rc = __put_user((u32)data, (u32 __user *)ubuf);
+			break;
+		case 2:
+			rc = __put_user((u16)data, (u16 __user *)ubuf);
+			break;
+		default:
+			rc = __put_user((u8)data, (u8 __user *)ubuf);
+			break;
+		}
+		if (rc)
+			return -EFAULT;
+		*ppos += len;
+		ubuf += len;
+		todo -= len;
+	}
+
+	return count;
+}
+
+static ssize_t lpc_debug_write(struct file *filp, const char __user *ubuf,
+			       size_t count, loff_t *ppos)
+{
+	struct lpc_debugfs_entry *lpc = filp->private_data;
+	u32 data, pos, len, todo;
+	int rc;
+
+	if (!access_ok(VERIFY_READ, ubuf, count))
+		return -EFAULT;
+
+	todo = count;
+	while (todo) {
+		pos = *ppos;
+
+		/*
+		 * Select access size based on count and alignment and
+		 * access type. IO and MEM only support byte acceses,
+		 * FW supports all 3.
+		 */
+		len = 1;
+		if (lpc->lpc_type == OPAL_LPC_FW) {
+			if (todo > 3 && (pos & 3) == 0)
+				len = 4;
+			else if (todo > 1 && (pos & 1) == 0)
+				len = 2;
+		}
+		switch(len) {
+		case 4:
+			rc = __get_user(data, (u32 __user *)ubuf);
+			break;
+		case 2:
+			rc = __get_user(data, (u16 __user *)ubuf);
+			break;
+		default:
+			rc = __get_user(data, (u8 __user *)ubuf);
+			break;
+		}
+		if (rc)
+			return -EFAULT;
+
+		rc = opal_lpc_write(opal_lpc_chip_id, lpc->lpc_type, pos,
+				    data, len);
+		if (rc)
+			return -ENXIO;
+		*ppos += len;
+		ubuf += len;
+		todo -= len;
+	}
+
+	return count;
+}
+
+static const struct file_operations lpc_fops = {
+	.read =		lpc_debug_read,
+	.write =	lpc_debug_write,
+	.open =		simple_open,
+	.llseek =	default_llseek,
+};
+
+static int opal_lpc_debugfs_create_type(struct dentry *folder,
+					const char *fname,
+					enum OpalLPCAddressType type)
+{
+	struct lpc_debugfs_entry *entry;
+	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry)
+		return -ENOMEM;
+	entry->lpc_type = type;
+	debugfs_create_file(fname, 0600, folder, entry, &lpc_fops);
+	return 0;
+}
+
+static int opal_lpc_init_debugfs(void)
+{
+	struct dentry *root;
+	int rc = 0;
+
+	if (opal_lpc_chip_id < 0)
+		return -ENODEV;
+
+	root = debugfs_create_dir("lpc", powerpc_debugfs_root);
+
+	rc |= opal_lpc_debugfs_create_type(root, "io", OPAL_LPC_IO);
+	rc |= opal_lpc_debugfs_create_type(root, "mem", OPAL_LPC_MEM);
+	rc |= opal_lpc_debugfs_create_type(root, "fw", OPAL_LPC_FW);
+	return rc;
+}
+device_initcall(opal_lpc_init_debugfs);
+#endif  /* CONFIG_DEBUG_FS */
+
 void opal_lpc_init(void)
 {
 	struct device_node *np;

^ permalink raw reply related

* Re: [PATCH v2] powerpc/85xx: Add T4240RDB board support
From: Chunhe Lan @ 2014-06-03 10:11 UTC (permalink / raw)
  To: Tudor Laurentiu; +Cc: Scott Wood, linuxppc-dev, Chunhe Lan
In-Reply-To: <538D9C79.20903@freescale.com>

On 06/03/2014 05:59 PM, Tudor Laurentiu wrote:
> Hi Chunhe
>
> Comment inline ...
>
> On 06/03/2014 12:10 PM, Chunhe Lan wrote:
>
>
>>
>> diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c 
>> b/arch/powerpc/platforms/85xx/corenet_generic.c
>> index 8e4b1e1..2f50526 100644
>> --- a/arch/powerpc/platforms/85xx/corenet_generic.c
>> +++ b/arch/powerpc/platforms/85xx/corenet_generic.c
>> @@ -119,6 +119,7 @@ static const char * const boards[] __initconst = {
>>       "fsl,P5020DS",
>>       "fsl,P5040DS",
>>       "fsl,T4240QDS",
>> +    "fsl,T4240RDB",
>
> T4240RDB is supported & tested under hypervisor so please also add the 
> hypervisor compatible in the "hv_boards" array below.
>
      I never use under hypervisor of T4240RDB. Thank you that you 
provide this information.
      I will add T4240RDB hv support.

Thanks,
-Chunhe
> ---
> Thanks & Best Regards, Laurentiu

^ permalink raw reply

* [PATCH v3] powerpc/85xx: Add T4240RDB board support
From: Chunhe Lan @ 2014-06-03 10:25 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Scott Wood, Chunhe Lan

T4240RDB board Specification
----------------------------
Memory subsystem:
     6GB DDR3
     128MB NOR flash
     2GB NAND flash
Ethernet:
     Eight 1G SGMII ports
     Four 10Gbps SFP+ ports
PCIe:
     Two PCIe slots
USB:
     Two USB2.0 Type A ports
SDHC:
     One SD-card port
SATA:
     One SATA port
UART:
     Dual RJ45 ports

Signed-off-by: Chunhe Lan <Chunhe.Lan@freescale.com>
Cc: Scott Wood <scottwood@freescale.com>
---
 arch/powerpc/boot/dts/t4240rdb.dts            |  186 +++++++++++++++++++++++++
 arch/powerpc/configs/corenet64_smp_defconfig  |    4 +
 arch/powerpc/platforms/85xx/Kconfig           |    2 +-
 arch/powerpc/platforms/85xx/corenet_generic.c |    2 +
 4 files changed, 193 insertions(+), 1 deletions(-)
 create mode 100644 arch/powerpc/boot/dts/t4240rdb.dts

diff --git a/arch/powerpc/boot/dts/t4240rdb.dts b/arch/powerpc/boot/dts/t4240rdb.dts
new file mode 100644
index 0000000..53761d4
--- /dev/null
+++ b/arch/powerpc/boot/dts/t4240rdb.dts
@@ -0,0 +1,186 @@
+/*
+ * T4240RDB Device Tree Source
+ *
+ * Copyright 2014 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *	 notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *	 notice, this list of conditions and the following disclaimer in the
+ *	 documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *	 names of its contributors may be used to endorse or promote products
+ *	 derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/include/ "fsl/t4240si-pre.dtsi"
+
+/ {
+	model = "fsl,T4240RDB";
+	compatible = "fsl,T4240RDB";
+	#address-cells = <2>;
+	#size-cells = <2>;
+	interrupt-parent = <&mpic>;
+
+	ifc: localbus@ffe124000 {
+		reg = <0xf 0xfe124000 0 0x2000>;
+		ranges = <0 0 0xf 0xe8000000 0x08000000
+			  2 0 0xf 0xff800000 0x00010000
+			  3 0 0xf 0xffdf0000 0x00008000>;
+
+		nor@0,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "cfi-flash";
+			reg = <0x0 0x0 0x8000000>;
+
+			bank-width = <2>;
+			device-width = <1>;
+		};
+
+		nand@2,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,ifc-nand";
+			reg = <0x2 0x0 0x10000>;
+		};
+	};
+
+	memory {
+		device_type = "memory";
+	};
+
+	dcsr: dcsr@f00000000 {
+		ranges = <0x00000000 0xf 0x00000000 0x01072000>;
+	};
+
+	soc: soc@ffe000000 {
+		ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+		reg = <0xf 0xfe000000 0 0x00001000>;
+		spi@110000 {
+			flash@0 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				compatible = "sst,sst25wf040";
+				reg = <0>;
+				spi-max-frequency = <40000000>; /* input clock */
+			};
+		};
+
+		i2c@118000 {
+			eeprom@52 {
+				compatible = "at24,24c256";
+				reg = <0x52>;
+			};
+			eeprom@54 {
+				compatible = "at24,24c256";
+				reg = <0x54>;
+			};
+			eeprom@56 {
+				compatible = "at24,24c256";
+				reg = <0x56>;
+			};
+			rtc@68 {
+				compatible = "dallas,ds1374";
+				reg = <0x68>;
+				interrupts = <0x1 0x1 0 0>;
+			};
+		};
+
+		sdhc@114000 {
+			voltage-ranges = <1800 1800 3300 3300>;
+		};
+	};
+
+	pci0: pcie@ffe240000 {
+		reg = <0xf 0xfe240000 0 0x10000>;
+		ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+			  0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
+		pcie@0 {
+			ranges = <0x02000000 0 0xe0000000
+				  0x02000000 0 0xe0000000
+				  0 0x20000000
+
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00010000>;
+		};
+	};
+
+	pci1: pcie@ffe250000 {
+		reg = <0xf 0xfe250000 0 0x10000>;
+		ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
+			  0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
+		pcie@0 {
+			ranges = <0x02000000 0 0xe0000000
+				  0x02000000 0 0xe0000000
+				  0 0x20000000
+
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00010000>;
+		};
+	};
+
+	pci2: pcie@ffe260000 {
+		reg = <0xf 0xfe260000 0 0x1000>;
+		ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
+			  0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
+		pcie@0 {
+			ranges = <0x02000000 0 0xe0000000
+				  0x02000000 0 0xe0000000
+				  0 0x20000000
+
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00010000>;
+		};
+	};
+
+	pci3: pcie@ffe270000 {
+		reg = <0xf 0xfe270000 0 0x10000>;
+		ranges = <0x02000000 0 0xe0000000 0xc 0x60000000 0 0x20000000
+			  0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
+		pcie@0 {
+			ranges = <0x02000000 0 0xe0000000
+				  0x02000000 0 0xe0000000
+				  0 0x20000000
+
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00010000>;
+		};
+	};
+
+	rio: rapidio@ffe0c0000 {
+		reg = <0xf 0xfe0c0000 0 0x11000>;
+
+		port1 {
+			ranges = <0 0 0xc 0x20000000 0 0x10000000>;
+		};
+		port2 {
+			ranges = <0 0 0xc 0x30000000 0 0x10000000>;
+		};
+	};
+};
+
+/include/ "fsl/t4240si-post.dtsi"
diff --git a/arch/powerpc/configs/corenet64_smp_defconfig b/arch/powerpc/configs/corenet64_smp_defconfig
index 5c7fa19..4f17b3d 100644
--- a/arch/powerpc/configs/corenet64_smp_defconfig
+++ b/arch/powerpc/configs/corenet64_smp_defconfig
@@ -96,6 +96,8 @@ CONFIG_SATA_SIL24=y
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=y
 CONFIG_E1000E=y
+CONFIG_PHYLIB=y
+CONFIG_VITESSE_PHY=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_KEYBOARD is not set
@@ -125,6 +127,8 @@ CONFIG_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_EDAC=y
 CONFIG_EDAC_MM_EDAC=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1374=y
 CONFIG_DMADEVICES=y
 CONFIG_FSL_DMA=y
 CONFIG_EXT2_FS=y
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index c17aae8..d66321e 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -265,7 +265,7 @@ config CORENET_GENERIC
 	  For 32bit kernel, the following boards are supported:
 	    P2041 RDB, P3041 DS and P4080 DS
 	  For 64bit kernel, the following boards are supported:
-	    T4240 QDS and B4 QDS
+	    T4240 QDS/RDB and B4 QDS
 	  The following boards are supported for both 32bit and 64bit kernel:
 	    P5020 DS and P5040 DS
 
diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c
index 8e4b1e1..3d91a26 100644
--- a/arch/powerpc/platforms/85xx/corenet_generic.c
+++ b/arch/powerpc/platforms/85xx/corenet_generic.c
@@ -119,6 +119,7 @@ static const char * const boards[] __initconst = {
 	"fsl,P5020DS",
 	"fsl,P5040DS",
 	"fsl,T4240QDS",
+	"fsl,T4240RDB",
 	"fsl,B4860QDS",
 	"fsl,B4420QDS",
 	"fsl,B4220QDS",
@@ -132,6 +133,7 @@ static const char * const hv_boards[] __initconst = {
 	"fsl,P5020DS-hv",
 	"fsl,P5040DS-hv",
 	"fsl,T4240QDS-hv",
+	"fsl,T4240RDB-hv",
 	"fsl,B4860QDS-hv",
 	"fsl,B4420QDS-hv",
 	"fsl,B4220QDS-hv",
-- 
1.7.6.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