LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 2/2] uio: add an of_genirq driver
From: Wolfram Sang @ 2009-06-16  9:04 UTC (permalink / raw)
  To: Grant Likely
  Cc: devicetree-discuss, Hans J. Koch, linux-kernel, linuxppc-dev,
	Greg KH
In-Reply-To: <fa686aa40906140740m43e9dd8am4d242310f681c95c@mail.gmail.com>

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


> > diff --git a/Documentation/powerpc/dts-bindings/uio-generic.txt b/Documentation/powerpc/dts-bindings/uio-generic.txt
> > new file mode 100644
> > index 0000000..8ad9861
> > --- /dev/null
> > +++ b/Documentation/powerpc/dts-bindings/uio-generic.txt
> > @@ -0,0 +1,16 @@
> > +UIO for custom devices
> > +
> > +A device which will be mapped using the UIO subsystem.
> > +
> > +Properties:
> > + - compatible : should contain the specific model used, followed by
> > +                "generic-uio".
> > + - reg : address range(s) of the device (up to MAX_UIO_MAPS)
> > + - interrupts : interrupt of the device
> > +
> > +Example:
> > +        c64fpga@0 {
> > +                compatible = "ptx,c64fpga001", "generic-uio";
> > +                reg = <0x0 0x10000>;
> > +                interrupts = <0 0 3>;
> > +        };
> 
> Hmmm, I'm not happy about this.  The device tree describes the
> hardware, not the way Linux uses the hardware.  UIO definitely falls
> into the category of Linux implementation detail.

Yes, I am aware of that. I just started with the mechanisms which are available
today and hoped we could find some compatible-value which will suit all needs.

> This should be approached from the other way around.  Either the
> generic-uio of_platform driver should contain an explicit list of
> devices to be handled by UIO,

Well, that could lead to a quite huge match_table over time.

> or the OF infrastructure should be modified to allow things like force
> binding of_devices to of_drivers at runtime.

That is an interesting idea. I could imagine something like a 'new_compatible"
entry in the sysfs-section of the driver similar to 'new_id' for PCI. After
writing a new compatible-string into it, matching will triggered again with the
new entry added. That could (should?) also be placed at the of-core-level. Or
did you have something else in mind?

Regards,

   Wolfram

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

^ permalink raw reply

* Re: [PATCH 2.6.31 try 2] ehca: Tolerate dynamic memory operations and huge pages
From: Alexander Schmidt @ 2009-06-16  7:10 UTC (permalink / raw)
  To: Hannes Hering
  Cc: rdreier, linux-kernel, ossrosch, linuxppc-dev, raisch, ewg,
	Hoang-Nam Nguyen
In-Reply-To: <200906091559.24661.hannes.hering@linux.vnet.ibm.com>

From: Hannes Hering <hering2@de.ibm.com>

This patch implements toleration of dynamic memory operations and 16 GB
gigantic pages. "Toleration" means that the driver can cope with dynamic
memory operations that happened before the driver was loaded. While using the
ehca driver, dynamic memory operations are still prohibited. On module load the
driver walks through available system memory, checks for available memory ranges
and then registers the kernel internal memory region accordingly. The
translation of address ranges is implemented via a 3-level busmap.

Signed-off-by: Hannes Hering <hering2@de.ibm.com>

---
This patch is built and tested against infiniband.git. Please apply for 2.6.31.

 drivers/infiniband/hw/ehca/ehca_main.c |   20 +
 drivers/infiniband/hw/ehca/ehca_mrmw.c |  508 ++++++++++++++++++++++++++++++++-
 drivers/infiniband/hw/ehca/ehca_mrmw.h |   13 
 3 files changed, 523 insertions(+), 18 deletions(-)

--- infiniband.git.orig/drivers/infiniband/hw/ehca/ehca_main.c
+++ infiniband.git/drivers/infiniband/hw/ehca/ehca_main.c
@@ -52,7 +52,7 @@
 #include "ehca_tools.h"
 #include "hcp_if.h"
 
-#define HCAD_VERSION "0026"
+#define HCAD_VERSION "0027"
 
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>");
@@ -506,6 +506,7 @@ static int ehca_init_device(struct ehca_
 	shca->ib_device.detach_mcast	    = ehca_detach_mcast;
 	shca->ib_device.process_mad	    = ehca_process_mad;
 	shca->ib_device.mmap		    = ehca_mmap;
+	shca->ib_device.dma_ops		    = &ehca_dma_mapping_ops;
 
 	if (EHCA_BMASK_GET(HCA_CAP_SRQ, shca->hca_cap)) {
 		shca->ib_device.uverbs_cmd_mask |=
@@ -1028,17 +1029,23 @@ static int __init ehca_module_init(void)
 		goto module_init1;
 	}
 
+	ret = ehca_create_busmap();
+	if (ret) {
+		ehca_gen_err("Cannot create busmap.");
+		goto module_init2;
+	}
+
 	ret = ibmebus_register_driver(&ehca_driver);
 	if (ret) {
 		ehca_gen_err("Cannot register eHCA device driver");
 		ret = -EINVAL;
-		goto module_init2;
+		goto module_init3;
 	}
 
 	ret = register_memory_notifier(&ehca_mem_nb);
 	if (ret) {
 		ehca_gen_err("Failed registering memory add/remove notifier");
-		goto module_init3;
+		goto module_init4;
 	}
 
 	if (ehca_poll_all_eqs != 1) {
@@ -1053,9 +1060,12 @@ static int __init ehca_module_init(void)
 
 	return 0;
 
-module_init3:
+module_init4:
 	ibmebus_unregister_driver(&ehca_driver);
 
+module_init3:
+	ehca_destroy_busmap();
+
 module_init2:
 	ehca_destroy_slab_caches();
 
@@ -1073,6 +1083,8 @@ static void __exit ehca_module_exit(void
 
 	unregister_memory_notifier(&ehca_mem_nb);
 
+	ehca_destroy_busmap();
+
 	ehca_destroy_slab_caches();
 
 	ehca_destroy_comp_pool();
--- infiniband.git.orig/drivers/infiniband/hw/ehca/ehca_mrmw.c
+++ infiniband.git/drivers/infiniband/hw/ehca/ehca_mrmw.c
@@ -53,6 +53,38 @@
 /* max number of rpages (per hcall register_rpages) */
 #define MAX_RPAGES 512
 
+/* DMEM toleration management */
+#define EHCA_SECTSHIFT        SECTION_SIZE_BITS
+#define EHCA_SECTSIZE          (1UL << EHCA_SECTSHIFT)
+#define EHCA_HUGEPAGESHIFT     34
+#define EHCA_HUGEPAGE_SIZE     (1UL << EHCA_HUGEPAGESHIFT)
+#define EHCA_HUGEPAGE_PFN_MASK ((EHCA_HUGEPAGE_SIZE - 1) >> PAGE_SHIFT)
+#define EHCA_INVAL_ADDR        0xFFFFFFFFFFFFFFFFULL
+#define EHCA_DIR_INDEX_SHIFT 13                   /* 8k Entries in 64k block */
+#define EHCA_TOP_INDEX_SHIFT (EHCA_DIR_INDEX_SHIFT * 2)
+#define EHCA_MAP_ENTRIES (1 << EHCA_DIR_INDEX_SHIFT)
+#define EHCA_TOP_MAP_SIZE (0x10000)               /* currently fixed map size */
+#define EHCA_DIR_MAP_SIZE (0x10000)
+#define EHCA_ENT_MAP_SIZE (0x10000)
+#define EHCA_INDEX_MASK (EHCA_MAP_ENTRIES - 1)
+
+static unsigned long ehca_mr_len;
+
+/*
+ * Memory map data structures
+ */
+struct ehca_dir_bmap {
+	u64 ent[EHCA_MAP_ENTRIES];
+};
+struct ehca_top_bmap {
+	struct ehca_dir_bmap *dir[EHCA_MAP_ENTRIES];
+};
+struct ehca_bmap {
+	struct ehca_top_bmap *top[EHCA_MAP_ENTRIES];
+};
+
+static struct ehca_bmap *ehca_bmap;
+
 static struct kmem_cache *mr_cache;
 static struct kmem_cache *mw_cache;
 
@@ -68,6 +100,8 @@ enum ehca_mr_pgsize {
 #define EHCA_MR_PGSHIFT1M  20
 #define EHCA_MR_PGSHIFT16M 24
 
+static u64 ehca_map_vaddr(void *caddr);
+
 static u32 ehca_encode_hwpage_size(u32 pgsize)
 {
 	int log = ilog2(pgsize);
@@ -135,7 +169,8 @@ struct ib_mr *ehca_get_dma_mr(struct ib_
 			goto get_dma_mr_exit0;
 		}
 
-		ret = ehca_reg_maxmr(shca, e_maxmr, (u64 *)KERNELBASE,
+		ret = ehca_reg_maxmr(shca, e_maxmr,
+				     (void *)ehca_map_vaddr((void *)KERNELBASE),
 				     mr_access_flags, e_pd,
 				     &e_maxmr->ib.ib_mr.lkey,
 				     &e_maxmr->ib.ib_mr.rkey);
@@ -251,7 +286,7 @@ struct ib_mr *ehca_reg_phys_mr(struct ib
 
 		ret = ehca_reg_mr(shca, e_mr, iova_start, size, mr_access_flags,
 				  e_pd, &pginfo, &e_mr->ib.ib_mr.lkey,
-				  &e_mr->ib.ib_mr.rkey);
+				  &e_mr->ib.ib_mr.rkey, EHCA_REG_MR);
 		if (ret) {
 			ib_mr = ERR_PTR(ret);
 			goto reg_phys_mr_exit1;
@@ -370,7 +405,7 @@ reg_user_mr_fallback:
 
 	ret = ehca_reg_mr(shca, e_mr, (u64 *)virt, length, mr_access_flags,
 			  e_pd, &pginfo, &e_mr->ib.ib_mr.lkey,
-			  &e_mr->ib.ib_mr.rkey);
+			  &e_mr->ib.ib_mr.rkey, EHCA_REG_MR);
 	if (ret == -EINVAL && pginfo.hwpage_size > PAGE_SIZE) {
 		ehca_warn(pd->device, "failed to register mr "
 			  "with hwpage_size=%llx", hwpage_size);
@@ -794,7 +829,7 @@ struct ib_fmr *ehca_alloc_fmr(struct ib_
 	ret = ehca_reg_mr(shca, e_fmr, NULL,
 			  fmr_attr->max_pages * (1 << fmr_attr->page_shift),
 			  mr_access_flags, e_pd, &pginfo,
-			  &tmp_lkey, &tmp_rkey);
+			  &tmp_lkey, &tmp_rkey, EHCA_REG_MR);
 	if (ret) {
 		ib_fmr = ERR_PTR(ret);
 		goto alloc_fmr_exit1;
@@ -983,6 +1018,10 @@ free_fmr_exit0:
 
 /*----------------------------------------------------------------------*/
 
+static int ehca_reg_bmap_mr_rpages(struct ehca_shca *shca,
+				   struct ehca_mr *e_mr,
+				   struct ehca_mr_pginfo *pginfo);
+
 int ehca_reg_mr(struct ehca_shca *shca,
 		struct ehca_mr *e_mr,
 		u64 *iova_start,
@@ -991,7 +1030,8 @@ int ehca_reg_mr(struct ehca_shca *shca,
 		struct ehca_pd *e_pd,
 		struct ehca_mr_pginfo *pginfo,
 		u32 *lkey, /*OUT*/
-		u32 *rkey) /*OUT*/
+		u32 *rkey, /*OUT*/
+		enum ehca_reg_type reg_type)
 {
 	int ret;
 	u64 h_ret;
@@ -1015,7 +1055,13 @@ int ehca_reg_mr(struct ehca_shca *shca,
 
 	e_mr->ipz_mr_handle = hipzout.handle;
 
-	ret = ehca_reg_mr_rpages(shca, e_mr, pginfo);
+	if (reg_type == EHCA_REG_BUSMAP_MR)
+		ret = ehca_reg_bmap_mr_rpages(shca, e_mr, pginfo);
+	else if (reg_type == EHCA_REG_MR)
+		ret = ehca_reg_mr_rpages(shca, e_mr, pginfo);
+	else
+		ret = -EINVAL;
+
 	if (ret)
 		goto ehca_reg_mr_exit1;
 
@@ -1316,7 +1362,7 @@ int ehca_rereg_mr(struct ehca_shca *shca
 		e_mr->fmr_map_cnt = save_mr.fmr_map_cnt;
 
 		ret = ehca_reg_mr(shca, e_mr, iova_start, size, acl,
-				  e_pd, pginfo, lkey, rkey);
+				  e_pd, pginfo, lkey, rkey, EHCA_REG_MR);
 		if (ret) {
 			u32 offset = (u64)(&e_mr->flags) - (u64)e_mr;
 			memcpy(&e_mr->flags, &(save_mr.flags),
@@ -1409,7 +1455,7 @@ int ehca_unmap_one_fmr(struct ehca_shca 
 	ret = ehca_reg_mr(shca, e_fmr, NULL,
 			  (e_fmr->fmr_max_pages * e_fmr->fmr_page_size),
 			  e_fmr->acl, e_pd, &pginfo, &tmp_lkey,
-			  &tmp_rkey);
+			  &tmp_rkey, EHCA_REG_MR);
 	if (ret) {
 		u32 offset = (u64)(&e_fmr->flags) - (u64)e_fmr;
 		memcpy(&e_fmr->flags, &(save_mr.flags),
@@ -1478,6 +1524,90 @@ ehca_reg_smr_exit0:
 } /* end ehca_reg_smr() */
 
 /*----------------------------------------------------------------------*/
+static inline void *ehca_calc_sectbase(int top, int dir, int idx)
+{
+	unsigned long ret = idx;
+	ret |= dir << EHCA_DIR_INDEX_SHIFT;
+	ret |= top << EHCA_TOP_INDEX_SHIFT;
+	return abs_to_virt(ret << SECTION_SIZE_BITS);
+}
+
+#define ehca_bmap_valid(entry) \
+	((u64)entry != (u64)EHCA_INVAL_ADDR)
+
+static u64 ehca_reg_mr_section(int top, int dir, int idx, u64 *kpage,
+			       struct ehca_shca *shca, struct ehca_mr *mr,
+			       struct ehca_mr_pginfo *pginfo)
+{
+	u64 h_ret = 0;
+	unsigned long page = 0;
+	u64 rpage = virt_to_abs(kpage);
+	int page_count;
+
+	void *sectbase = ehca_calc_sectbase(top, dir, idx);
+	if ((unsigned long)sectbase & (pginfo->hwpage_size - 1)) {
+		ehca_err(&shca->ib_device, "reg_mr_section will probably fail:"
+					   "hwpage_size does not fit to "
+					   "section start address");
+	}
+	page_count = EHCA_SECTSIZE / pginfo->hwpage_size;
+
+	while (page < page_count) {
+		u64 rnum;
+		for (rnum = 0; (rnum < MAX_RPAGES) && (page < page_count);
+		     rnum++) {
+			void *pg = sectbase + ((page++) * pginfo->hwpage_size);
+			kpage[rnum] = virt_to_abs(pg);
+		}
+
+		h_ret = hipz_h_register_rpage_mr(shca->ipz_hca_handle, mr,
+			ehca_encode_hwpage_size(pginfo->hwpage_size),
+			0, rpage, rnum);
+
+		if ((h_ret != H_SUCCESS) && (h_ret != H_PAGE_REGISTERED)) {
+			ehca_err(&shca->ib_device, "register_rpage_mr failed");
+			return h_ret;
+		}
+	}
+	return h_ret;
+}
+
+static u64 ehca_reg_mr_sections(int top, int dir, u64 *kpage,
+				struct ehca_shca *shca, struct ehca_mr *mr,
+				struct ehca_mr_pginfo *pginfo)
+{
+	u64 hret = H_SUCCESS;
+	int idx;
+
+	for (idx = 0; idx < EHCA_MAP_ENTRIES; idx++) {
+		if (!ehca_bmap_valid(ehca_bmap->top[top]->dir[dir]->ent[idx]))
+			continue;
+
+		hret = ehca_reg_mr_section(top, dir, idx, kpage, shca, mr,
+					   pginfo);
+		if ((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED))
+				return hret;
+	}
+	return hret;
+}
+
+static u64 ehca_reg_mr_dir_sections(int top, u64 *kpage, struct ehca_shca *shca,
+				    struct ehca_mr *mr,
+				    struct ehca_mr_pginfo *pginfo)
+{
+	u64 hret = H_SUCCESS;
+	int dir;
+
+	for (dir = 0; dir < EHCA_MAP_ENTRIES; dir++) {
+		if (!ehca_bmap_valid(ehca_bmap->top[top]->dir[dir]))
+			continue;
+
+		hret = ehca_reg_mr_sections(top, dir, kpage, shca, mr, pginfo);
+		if ((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED))
+				return hret;
+	}
+	return hret;
+}
 
 /* register internal max-MR to internal SHCA */
 int ehca_reg_internal_maxmr(
@@ -1495,6 +1625,11 @@ int ehca_reg_internal_maxmr(
 	u32 num_hwpages;
 	u64 hw_pgsize;
 
+	if (!ehca_bmap) {
+		ret = -EFAULT;
+		goto ehca_reg_internal_maxmr_exit0;
+	}
+
 	e_mr = ehca_mr_new();
 	if (!e_mr) {
 		ehca_err(&shca->ib_device, "out of memory");
@@ -1504,8 +1639,8 @@ int ehca_reg_internal_maxmr(
 	e_mr->flags |= EHCA_MR_FLAG_MAXMR;
 
 	/* register internal max-MR on HCA */
-	size_maxmr = (u64)high_memory - PAGE_OFFSET;
-	iova_start = (u64 *)KERNELBASE;
+	size_maxmr = ehca_mr_len;
+	iova_start = (u64 *)ehca_map_vaddr((void *)KERNELBASE);
 	ib_pbuf.addr = 0;
 	ib_pbuf.size = size_maxmr;
 	num_kpages = NUM_CHUNKS(((u64)iova_start % PAGE_SIZE) + size_maxmr,
@@ -1524,7 +1659,7 @@ int ehca_reg_internal_maxmr(
 
 	ret = ehca_reg_mr(shca, e_mr, iova_start, size_maxmr, 0, e_pd,
 			  &pginfo, &e_mr->ib.ib_mr.lkey,
-			  &e_mr->ib.ib_mr.rkey);
+			  &e_mr->ib.ib_mr.rkey, EHCA_REG_BUSMAP_MR);
 	if (ret) {
 		ehca_err(&shca->ib_device, "reg of internal max MR failed, "
 			 "e_mr=%p iova_start=%p size_maxmr=%llx num_kpages=%x "
@@ -2077,8 +2212,8 @@ int ehca_mr_is_maxmr(u64 size,
 		     u64 *iova_start)
 {
 	/* a MR is treated as max-MR only if it fits following: */
-	if ((size == ((u64)high_memory - PAGE_OFFSET)) &&
-	    (iova_start == (void *)KERNELBASE)) {
+	if ((size == ehca_mr_len) &&
+	    (iova_start == (void *)ehca_map_vaddr((void *)KERNELBASE))) {
 		ehca_gen_dbg("this is a max-MR");
 		return 1;
 	} else
@@ -2184,3 +2319,350 @@ void ehca_cleanup_mrmw_cache(void)
 	if (mw_cache)
 		kmem_cache_destroy(mw_cache);
 }
+
+static inline int ehca_init_top_bmap(struct ehca_top_bmap *ehca_top_bmap,
+				     int dir)
+{
+	if (!ehca_bmap_valid(ehca_top_bmap->dir[dir])) {
+		ehca_top_bmap->dir[dir] =
+			kmalloc(sizeof(struct ehca_dir_bmap), GFP_KERNEL);
+		if (!ehca_top_bmap->dir[dir])
+			return -ENOMEM;
+		/* Set map block to 0xFF according to EHCA_INVAL_ADDR */
+		memset(ehca_top_bmap->dir[dir], 0xFF, EHCA_ENT_MAP_SIZE);
+	}
+	return 0;
+}
+
+static inline int ehca_init_bmap(struct ehca_bmap *ehca_bmap, int top, int dir)
+{
+	if (!ehca_bmap_valid(ehca_bmap->top[top])) {
+		ehca_bmap->top[top] =
+			kmalloc(sizeof(struct ehca_top_bmap), GFP_KERNEL);
+		if (!ehca_bmap->top[top])
+			return -ENOMEM;
+		/* Set map block to 0xFF according to EHCA_INVAL_ADDR */
+		memset(ehca_bmap->top[top], 0xFF, EHCA_DIR_MAP_SIZE);
+	}
+	return ehca_init_top_bmap(ehca_bmap->top[top], dir);
+}
+
+static inline int ehca_calc_index(unsigned long i, unsigned long s)
+{
+	return (i >> s) & EHCA_INDEX_MASK;
+}
+
+void ehca_destroy_busmap(void)
+{
+	int top, dir;
+
+	if (!ehca_bmap)
+		return;
+
+	for (top = 0; top < EHCA_MAP_ENTRIES; top++) {
+		if (!ehca_bmap_valid(ehca_bmap->top[top]))
+			continue;
+		for (dir = 0; dir < EHCA_MAP_ENTRIES; dir++) {
+			if (!ehca_bmap_valid(ehca_bmap->top[top]->dir[dir]))
+				continue;
+
+			kfree(ehca_bmap->top[top]->dir[dir]);
+		}
+
+		kfree(ehca_bmap->top[top]);
+	}
+
+	kfree(ehca_bmap);
+	ehca_bmap = NULL;
+}
+
+static int ehca_update_busmap(unsigned long pfn, unsigned long nr_pages)
+{
+	unsigned long i, start_section, end_section;
+	int top, dir, idx;
+
+	if (!nr_pages)
+		return 0;
+
+	if (!ehca_bmap) {
+		ehca_bmap = kmalloc(sizeof(struct ehca_bmap), GFP_KERNEL);
+		if (!ehca_bmap)
+			return -ENOMEM;
+		/* Set map block to 0xFF according to EHCA_INVAL_ADDR */
+		memset(ehca_bmap, 0xFF, EHCA_TOP_MAP_SIZE);
+	}
+
+	start_section = phys_to_abs(pfn * PAGE_SIZE) / EHCA_SECTSIZE;
+	end_section = phys_to_abs((pfn + nr_pages) * PAGE_SIZE) / EHCA_SECTSIZE;
+	for (i = start_section; i < end_section; i++) {
+		int ret;
+		top = ehca_calc_index(i, EHCA_TOP_INDEX_SHIFT);
+		dir = ehca_calc_index(i, EHCA_DIR_INDEX_SHIFT);
+		idx = i & EHCA_INDEX_MASK;
+
+		ret = ehca_init_bmap(ehca_bmap, top, dir);
+		if (ret) {
+			ehca_destroy_busmap();
+			return ret;
+		}
+		ehca_bmap->top[top]->dir[dir]->ent[idx] = ehca_mr_len;
+		ehca_mr_len += EHCA_SECTSIZE;
+	}
+	return 0;
+}
+
+static int ehca_is_hugepage(unsigned long pfn)
+{
+	int page_order;
+
+	if (pfn & EHCA_HUGEPAGE_PFN_MASK)
+		return 0;
+
+	page_order = compound_order(pfn_to_page(pfn));
+	if (page_order + PAGE_SHIFT != EHCA_HUGEPAGESHIFT)
+		return 0;
+
+	return 1;
+}
+
+static int ehca_create_busmap_callback(unsigned long initial_pfn,
+				       unsigned long total_nr_pages, void *arg)
+{
+	int ret;
+	unsigned long pfn, start_pfn, end_pfn, nr_pages;
+
+	if ((total_nr_pages * PAGE_SIZE) < EHCA_HUGEPAGE_SIZE)
+		return ehca_update_busmap(initial_pfn, total_nr_pages);
+
+	/* Given chunk is >= 16GB -> check for hugepages */
+	start_pfn = initial_pfn;
+	end_pfn = initial_pfn + total_nr_pages;
+	pfn = start_pfn;
+
+	while (pfn < end_pfn) {
+		if (ehca_is_hugepage(pfn)) {
+			/* Add mem found in front of the hugepage */
+			nr_pages = pfn - start_pfn;
+			ret = ehca_update_busmap(start_pfn, nr_pages);
+			if (ret)
+				return ret;
+			/* Skip the hugepage */
+			pfn += (EHCA_HUGEPAGE_SIZE / PAGE_SIZE);
+			start_pfn = pfn;
+		} else
+			pfn += (EHCA_SECTSIZE / PAGE_SIZE);
+	}
+
+	/* Add mem found behind the hugepage(s)  */
+	nr_pages = pfn - start_pfn;
+	return ehca_update_busmap(start_pfn, nr_pages);
+}
+
+int ehca_create_busmap(void)
+{
+	int ret;
+
+	ehca_mr_len = 0;
+	ret = walk_memory_resource(0, 1ULL << MAX_PHYSMEM_BITS, NULL,
+				   ehca_create_busmap_callback);
+	return ret;
+}
+
+static int ehca_reg_bmap_mr_rpages(struct ehca_shca *shca,
+				   struct ehca_mr *e_mr,
+				   struct ehca_mr_pginfo *pginfo)
+{
+	int top;
+	u64 hret, *kpage;
+
+	kpage = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
+	if (!kpage) {
+		ehca_err(&shca->ib_device, "kpage alloc failed");
+		return -ENOMEM;
+	}
+	for (top = 0; top < EHCA_MAP_ENTRIES; top++) {
+		if (!ehca_bmap_valid(ehca_bmap->top[top]))
+			continue;
+		hret = ehca_reg_mr_dir_sections(top, kpage, shca, e_mr, pginfo);
+		if ((hret != H_PAGE_REGISTERED) && (hret != H_SUCCESS))
+			break;
+	}
+
+	ehca_free_fw_ctrlblock(kpage);
+
+	if (hret == H_SUCCESS)
+		return 0; /* Everything is fine */
+	else {
+		ehca_err(&shca->ib_device, "ehca_reg_bmap_mr_rpages failed, "
+				 "h_ret=%lli e_mr=%p top=%x lkey=%x "
+				 "hca_hndl=%llx mr_hndl=%llx", hret, e_mr, top,
+				 e_mr->ib.ib_mr.lkey,
+				 shca->ipz_hca_handle.handle,
+				 e_mr->ipz_mr_handle.handle);
+		return ehca2ib_return_code(hret);
+	}
+}
+
+static u64 ehca_map_vaddr(void *caddr)
+{
+	int top, dir, idx;
+	unsigned long abs_addr, offset;
+	u64 entry;
+
+	if (!ehca_bmap)
+		return EHCA_INVAL_ADDR;
+
+	abs_addr = virt_to_abs(caddr);
+	top = ehca_calc_index(abs_addr, EHCA_TOP_INDEX_SHIFT + EHCA_SECTSHIFT);
+	if (!ehca_bmap_valid(ehca_bmap->top[top]))
+		return EHCA_INVAL_ADDR;
+
+	dir = ehca_calc_index(abs_addr, EHCA_DIR_INDEX_SHIFT + EHCA_SECTSHIFT);
+	if (!ehca_bmap_valid(ehca_bmap->top[top]->dir[dir]))
+		return EHCA_INVAL_ADDR;
+
+	idx = ehca_calc_index(abs_addr, EHCA_SECTSHIFT);
+
+	entry = ehca_bmap->top[top]->dir[dir]->ent[idx];
+	if (ehca_bmap_valid(entry)) {
+		offset = (unsigned long)caddr & (EHCA_SECTSIZE - 1);
+		return entry | offset;
+	} else
+		return EHCA_INVAL_ADDR;
+}
+
+static int ehca_dma_mapping_error(struct ib_device *dev, u64 dma_addr)
+{
+	return dma_addr == EHCA_INVAL_ADDR;
+}
+
+static u64 ehca_dma_map_single(struct ib_device *dev, void *cpu_addr,
+			       size_t size, enum dma_data_direction direction)
+{
+	if (cpu_addr)
+		return ehca_map_vaddr(cpu_addr);
+	else
+		return EHCA_INVAL_ADDR;
+}
+
+static void ehca_dma_unmap_single(struct ib_device *dev, u64 addr, size_t size,
+				  enum dma_data_direction direction)
+{
+	/* This is only a stub; nothing to be done here */
+}
+
+static u64 ehca_dma_map_page(struct ib_device *dev, struct page *page,
+			     unsigned long offset, size_t size,
+			     enum dma_data_direction direction)
+{
+	u64 addr;
+
+	if (offset + size > PAGE_SIZE)
+		return EHCA_INVAL_ADDR;
+
+	addr = ehca_map_vaddr(page_address(page));
+	if (!ehca_dma_mapping_error(dev, addr))
+		addr += offset;
+
+	return addr;
+}
+
+static void ehca_dma_unmap_page(struct ib_device *dev, u64 addr, size_t size,
+				enum dma_data_direction direction)
+{
+	/* This is only a stub; nothing to be done here */
+}
+
+static int ehca_dma_map_sg(struct ib_device *dev, struct scatterlist *sgl,
+			   int nents, enum dma_data_direction direction)
+{
+	struct scatterlist *sg;
+	int i;
+
+	for_each_sg(sgl, sg, nents, i) {
+		u64 addr;
+		addr = ehca_map_vaddr(sg_virt(sg));
+		if (ehca_dma_mapping_error(dev, addr))
+			return 0;
+
+		sg->dma_address = addr;
+		sg->dma_length = sg->length;
+	}
+	return nents;
+}
+
+static void ehca_dma_unmap_sg(struct ib_device *dev, struct scatterlist *sg,
+			      int nents, enum dma_data_direction direction)
+{
+	/* This is only a stub; nothing to be done here */
+}
+
+static u64 ehca_dma_address(struct ib_device *dev, struct scatterlist *sg)
+{
+	return sg->dma_address;
+}
+
+static unsigned int ehca_dma_len(struct ib_device *dev, struct scatterlist *sg)
+{
+	return sg->length;
+}
+
+static void ehca_dma_sync_single_for_cpu(struct ib_device *dev, u64 addr,
+					 size_t size,
+					 enum dma_data_direction dir)
+{
+	dma_sync_single_for_cpu(dev->dma_device, addr, size, dir);
+}
+
+static void ehca_dma_sync_single_for_device(struct ib_device *dev, u64 addr,
+					    size_t size,
+					    enum dma_data_direction dir)
+{
+	dma_sync_single_for_device(dev->dma_device, addr, size, dir);
+}
+
+static void *ehca_dma_alloc_coherent(struct ib_device *dev, size_t size,
+				     u64 *dma_handle, gfp_t flag)
+{
+	struct page *p;
+	void *addr = NULL;
+	u64 dma_addr;
+
+	p = alloc_pages(flag, get_order(size));
+	if (p) {
+		addr = page_address(p);
+		dma_addr = ehca_map_vaddr(addr);
+		if (ehca_dma_mapping_error(dev, dma_addr)) {
+			free_pages((unsigned long)addr,	get_order(size));
+			return NULL;
+		}
+		if (dma_handle)
+			*dma_handle = dma_addr;
+		return addr;
+	}
+	return NULL;
+}
+
+static void ehca_dma_free_coherent(struct ib_device *dev, size_t size,
+				   void *cpu_addr, u64 dma_handle)
+{
+	if (cpu_addr && size)
+		free_pages((unsigned long)cpu_addr, get_order(size));
+}
+
+
+struct ib_dma_mapping_ops ehca_dma_mapping_ops = {
+	.mapping_error          = ehca_dma_mapping_error,
+	.map_single             = ehca_dma_map_single,
+	.unmap_single           = ehca_dma_unmap_single,
+	.map_page               = ehca_dma_map_page,
+	.unmap_page             = ehca_dma_unmap_page,
+	.map_sg                 = ehca_dma_map_sg,
+	.unmap_sg               = ehca_dma_unmap_sg,
+	.dma_address            = ehca_dma_address,
+	.dma_len                = ehca_dma_len,
+	.sync_single_for_cpu    = ehca_dma_sync_single_for_cpu,
+	.sync_single_for_device = ehca_dma_sync_single_for_device,
+	.alloc_coherent         = ehca_dma_alloc_coherent,
+	.free_coherent          = ehca_dma_free_coherent,
+};
--- infiniband.git.orig/drivers/infiniband/hw/ehca/ehca_mrmw.h
+++ infiniband.git/drivers/infiniband/hw/ehca/ehca_mrmw.h
@@ -42,6 +42,11 @@
 #ifndef _EHCA_MRMW_H_
 #define _EHCA_MRMW_H_
 
+enum ehca_reg_type {
+	EHCA_REG_MR,
+	EHCA_REG_BUSMAP_MR
+};
+
 int ehca_reg_mr(struct ehca_shca *shca,
 		struct ehca_mr *e_mr,
 		u64 *iova_start,
@@ -50,7 +55,8 @@ int ehca_reg_mr(struct ehca_shca *shca,
 		struct ehca_pd *e_pd,
 		struct ehca_mr_pginfo *pginfo,
 		u32 *lkey,
-		u32 *rkey);
+		u32 *rkey,
+		enum ehca_reg_type reg_type);
 
 int ehca_reg_mr_rpages(struct ehca_shca *shca,
 		       struct ehca_mr *e_mr,
@@ -118,4 +124,9 @@ void ehca_mrmw_reverse_map_acl(const u32
 
 void ehca_mr_deletenew(struct ehca_mr *mr);
 
+int ehca_create_busmap(void);
+
+void ehca_destroy_busmap(void);
+
+extern struct ib_dma_mapping_ops ehca_dma_mapping_ops;
 #endif  /*_EHCA_MRMW_H_*/

^ permalink raw reply

* Re: [PATCH 2.6.31] ehca: Tolerate dynamic memory operations and huge pages
From: Alexander Schmidt @ 2009-06-16  7:08 UTC (permalink / raw)
  To: Roland Dreier
  Cc: Hannes Hering, linux-kernel, ossrosch, linuxppc-dev, raisch, ewg,
	Hoang-Nam Nguyen
In-Reply-To: <adar5xoybwt.fsf@cisco.com>

Hi Roland,

thank you for taking a look at the code!

On Fri, 12 Jun 2009 21:50:58 -0700
Roland Dreier <rdreier@cisco.com> wrote:

> OK, one major issue with this patch and a few minor nits.
> 
> First, the major issue is that I don't see anything in the patch that
> changes the code in ehca_mem_notifier() in ehca_main.c:
> 
> 	case MEM_GOING_ONLINE:
> 	case MEM_GOING_OFFLINE:
> 		/* only ok if no hca is attached to the lpar */
> 		spin_lock_irqsave(&shca_list_lock, flags);
> 		if (list_empty(&shca_list)) {
> 			spin_unlock_irqrestore(&shca_list_lock, flags);
> 			return NOTIFY_OK;
> 		} else {
> 			spin_unlock_irqrestore(&shca_list_lock, flags);
> 			if (printk_timed_ratelimit(&ehca_dmem_warn_time,
> 						   30 * 1000))
> 				ehca_gen_err("DMEM operations are not allowed"
> 					     "in conjunction with eHCA");
> 			return NOTIFY_BAD;
> 		}
> 
> But your patch description says:
> 
>  > This patch implements toleration of dynamic memory operations....
> 
> But it seems you're still going to hit the same NOTIFY_BAD case above
> after your patch.  So something doesn't compute for me.  Could you
> explain more?

Yeah, the notifier code remains untouched as we still do not allow dynamic
memory operations _while_ our module is loaded. The patch allows the driver to
cope with DMEM operations that happened before the module was loaded, which
might result in a non-contiguous memory layout. When the driver registers
its global memory region in the system, the memory layout must be considered.

We chose the term "toleration" instead of "support" to illustrate this.

I'll put some more details into the changelog, incorporate the other comments
and send out a second version of the patch.

Thanks,
Alex

> 
> Second, a nit:
> 
>  > +#define EHCA_REG_MR 0
>  > +#define EHCA_REG_BUSMAP_MR (~0)
> 
> and you pass these as the reg_busmap parm in:
> 
>  >  int ehca_reg_mr(struct ehca_shca *shca,
>  >  		struct ehca_mr *e_mr,
>  >  		u64 *iova_start,
>  > @@ -991,7 +1031,8 @@
>  >  		struct ehca_pd *e_pd,
>  >  		struct ehca_mr_pginfo *pginfo,
>  >  		u32 *lkey, /*OUT*/
>  > -		u32 *rkey) /*OUT*/
>  > +		u32 *rkey, /*OUT*/
>  > +		int reg_busmap)
> 
> and test it as:
> 
>  > +	if (reg_busmap)
>  > +		ret = ehca_reg_bmap_mr_rpages(shca, e_mr, pginfo);
>  > +	else
>  > +		ret = ehca_reg_mr_rpages(shca, e_mr, pginfo);
> 
> So the ~0 for true looks a bit odd.  One option would be to make
> reg_busmap a bool, since that's how you're using it, but then you lose
> the nice self-documenting macro where you call things.
> 
> So I think it would be cleaner to do something like
> 
> enum ehca_reg_type {
> 	EHCA_REG_MR,
> 	EHCA_REG_BUSMAP_MR
> };
> 
> and make the "int reg_busmap" parameter into "enum ehca_reg_type reg_type"
> and have the code become
> 
> +	if (reg_type == EHCA_REG_BUSMAP_MR)
> +		ret = ehca_reg_bmap_mr_rpages(shca, e_mr, pginfo);
> +	else if (reg_type == EHCA_REG_MR)
> +		ret = ehca_reg_mr_rpages(shca, e_mr, pginfo);
> +	else
> +		ret = -EINVAL
> 
> or something like that.
> 
>  > +struct ib_dma_mapping_ops ehca_dma_mapping_ops = {
>  > +	.mapping_error = ehca_dma_mapping_error,
>  > +	.map_single = ehca_dma_map_single,
>  > +	.unmap_single = ehca_dma_unmap_single,
>  > +	.map_page = ehca_dma_map_page,
>  > +	.unmap_page = ehca_dma_unmap_page,
>  > +	.map_sg = ehca_dma_map_sg,
>  > +	.unmap_sg = ehca_dma_unmap_sg,
>  > +	.dma_address = ehca_dma_address,
>  > +	.dma_len = ehca_dma_len,
>  > +	.sync_single_for_cpu = ehca_dma_sync_single_for_cpu,
>  > +	.sync_single_for_device = ehca_dma_sync_single_for_device,
>  > +	.alloc_coherent = ehca_dma_alloc_coherent,
>  > +	.free_coherent = ehca_dma_free_coherent,
>  > +};
> 
> I always think structures like this are easier to read if you align the
> '=' signs.  But no big deal.
> 
>  > +	ret = ehca_create_busmap();
>  > +	if (ret) {
>  > +		ehca_gen_err("Cannot create busmap.");
>  > +		goto module_init2;
>  > +	}
>  > +
>  >  	ret = ibmebus_register_driver(&ehca_driver);
>  >  	if (ret) {
>  >  		ehca_gen_err("Cannot register eHCA device driver");
>  >  		ret = -EINVAL;
>  > -		goto module_init2;
>  > +		goto module_init3;
>  >  	}
>  >  
>  >  	ret = register_memory_notifier(&ehca_mem_nb);
>  >  	if (ret) {
>  >  		ehca_gen_err("Failed registering memory add/remove notifier");
>  > -		goto module_init3;
>  > +		goto module_init4;
> 
> Having to renumber unrelated things is when something changes is why I
> don't like this style of error path labels.  But I think it's well and
> truly too late to fix that in ehca.

^ permalink raw reply

* Re: linux-next: Linus/powerpc tree build warning
From: Benjamin Herrenschmidt @ 2009-06-16  6:59 UTC (permalink / raw)
  To: Stephen Rothwell
  Cc: Suneel, linux-kernel, linuxppc-dev, linux-next, John Linn
In-Reply-To: <20090616162429.07e74e75.sfr@canb.auug.org.au>

On Tue, 2009-06-16 at 16:24 +1000, Stephen Rothwell wrote:
> Hi Ben,
> 
> Today's linux-next build (powerpc ppc44x_defconfig) produced this warning:
> 
> drivers/video/xilinxfb.c: In function 'xilinxfb_assign':
> drivers/video/xilinxfb.c:328: warning: cast to pointer from integer of different size
> 
> Introduced by commit dac4ccfb64bcdd5b4c248ccc22903d67486573cd ("fbdev:
> Add PLB support and cleanup DCR in xilinxfb driver").

Known problem, a fix is currently being polished by Grant and John.

Cheers,
Ben.

^ permalink raw reply

* Re: linux-next: manual merge of the driver-core tree with the powerpc tree
From: Stephen Rothwell @ 2009-06-16  6:42 UTC (permalink / raw)
  To: Greg KH; +Cc: Roel Kluin, linux-kernel, ppc-dev, linux-next, Geert,
	Uytterhoeven
In-Reply-To: <20090616061849.GA32109@kroah.com>

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

Hi Greg,

On Mon, 15 Jun 2009 23:18:49 -0700 Greg KH <greg@kroah.com> wrote:
>
> I pushed out an update a number of hours ago (like 6+), so you should
> have gotten it with this update.
> 
> When did you pull from my tree?  I also just sent a merge request to
> Linus, so everything should be fixed up now.

OK, thanks.  I fetch the trees usually between 8:30am and 10:00am UTC
+1000 (or +1100 in summer), so about 7 hours ago :-)

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

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

^ permalink raw reply

* linux-next: Linus/powerpc tree build warning
From: Stephen Rothwell @ 2009-06-16  6:24 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Suneel, linux-kernel, linuxppc-dev, linux-next, Stephen,
	John Linn

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

Hi Ben,

Today's linux-next build (powerpc ppc44x_defconfig) produced this warning:

drivers/video/xilinxfb.c: In function 'xilinxfb_assign':
drivers/video/xilinxfb.c:328: warning: cast to pointer from integer of different size

Introduced by commit dac4ccfb64bcdd5b4c248ccc22903d67486573cd ("fbdev:
Add PLB support and cleanup DCR in xilinxfb driver").
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

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

^ permalink raw reply

* Re: linux-next: manual merge of the driver-core tree with the powerpc tree
From: Greg KH @ 2009-06-16  6:18 UTC (permalink / raw)
  To: Stephen Rothwell
  Cc: Roel Kluin, linux-kernel, ppc-dev, linux-next, Geert Uytterhoeven
In-Reply-To: <20090616155317.d1f1217e.sfr@canb.auug.org.au>

On Tue, Jun 16, 2009 at 03:53:17PM +1000, Stephen Rothwell wrote:
> Hi Greg,
> 
> Today's linux-next merge of the driver-core tree got a conflict in
> drivers/block/ps3disk.c between commits
> 6dee2c87ebbe5d7ce8c4c163966a0bd9c02c75ef ("block/ps3: remove driver_data
> direct access of struct device") and
> 03fa68c245cccbcb99035cbabaa13b408ba91ab5 ("ps3: shorten ps3_system_bus_
> [gs]et_driver_data to ps3_system_bus_[gs]et_drvdata") from the powerpc
> tree and commit db7afa200c4ef6823a2a40e4ea1dd747775be01a ("block/ps3:
> remove driver_data direct access of struct device") from the driver-core
> tree.
> 
> I fixed it up (I used the version from the powerpc tree).  Greg, I think
> the driver-core patch is no longer relevant.

I pushed out an update a number of hours ago (like 6+), so you should
have gotten it with this update.

When did you pull from my tree?  I also just sent a merge request to
Linus, so everything should be fixed up now.

thanks,

greg k-h

^ permalink raw reply

* linux-next: manual merge of the driver-core tree with the powerpc tree
From: Stephen Rothwell @ 2009-06-16  5:58 UTC (permalink / raw)
  To: Greg KH; +Cc: Roel Kluin, linux-kernel, ppc-dev, linux-next, Geert,
	Uytterhoeven

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

Hi Greg,

Today's linux-next merge of the driver-core tree got a conflict in
drivers/block/ps3vram.c between commits
6dee2c87ebbe5d7ce8c4c163966a0bd9c02c75ef ("block/ps3: remove driver_data
direct access of struct device") and
03fa68c245cccbcb99035cbabaa13b408ba91ab5 ("ps3: shorten ps3_system_bus_
[gs]et_driver_data to ps3_system_bus_[gs]et_drvdata") from the powerpc
tree and commit db7afa200c4ef6823a2a40e4ea1dd747775be01a ("block/ps3:
remove driver_data direct access of struct device") from the driver-core
tree.

I fixed it up (used the powerpc tree version).  Again, Greg, I think the
driver-core tree version is no longer relevant.
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

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

^ permalink raw reply

* linux-next: manual merge of the driver-core tree with the powerpc tree
From: Stephen Rothwell @ 2009-06-16  5:53 UTC (permalink / raw)
  To: Greg KH; +Cc: Roel Kluin, linux-kernel, ppc-dev, linux-next, Geert,
	Uytterhoeven

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

Hi Greg,

Today's linux-next merge of the driver-core tree got a conflict in
drivers/block/ps3disk.c between commits
6dee2c87ebbe5d7ce8c4c163966a0bd9c02c75ef ("block/ps3: remove driver_data
direct access of struct device") and
03fa68c245cccbcb99035cbabaa13b408ba91ab5 ("ps3: shorten ps3_system_bus_
[gs]et_driver_data to ps3_system_bus_[gs]et_drvdata") from the powerpc
tree and commit db7afa200c4ef6823a2a40e4ea1dd747775be01a ("block/ps3:
remove driver_data direct access of struct device") from the driver-core
tree.

I fixed it up (I used the version from the powerpc tree).  Greg, I think
the driver-core patch is no longer relevant.
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

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

^ permalink raw reply

* Re: [PATCH] Fix oprofile sampling of marked events on POWER7
From: Benjamin Herrenschmidt @ 2009-06-16  4:12 UTC (permalink / raw)
  To: Maynard Johnson; +Cc: linuxppc-dev, Anton Blanchard
In-Reply-To: <4A364F4A.6060300@us.ibm.com>

On Mon, 2009-06-15 at 08:40 -0500, Maynard Johnson wrote:
> Looks like this posting got overlooked, so I'm re-posting the original patch.  Ben, can you please review?  BTW, Anton reported the problem that this patch fixes.

It was merged upstream after 2.6.30 -rc6, see commit e5fc948b...

Cheers,
Ben.

> Thanks.
> -Maynard
> 
> ==============================================================
> 
> 
> Description
> -----------
> Change ppc64 oprofile kernel driver to use the SLOT bits (MMCRA[37:39]only on 
> older processors where those bits are defined.
> 
> Background
> ----------
> The performance monitor unit of the 64-bit POWER processor family has the 
> ability to collect accurate instruction-level samples when profiling on marked 
> events (i.e., "PM_MRK_<event-name>").  In processors prior to POWER6, the MMCRA 
> register contained "slot information" that the oprofile kernel driver used to 
> adjust the value latched in the SIAR at the time of a PMU interrupt.  But as of 
> POWER6, these slot bits in MMCRA are no longer necessary for oprofile to use, 
> since the SIAR itself holds the accurate sampled instruction address.  With 
> POWER6, these MMCRA slot bits were zero'ed out by hardware so oprofile's use of 
> these slot bits was, in effect, a NOP.  But with POWER7, these bits are no 
> longer zero'ed out; however, they serve some other purpose rather than slot 
> information.  Thus, using these bits on POWER7 to adjust the SIAR value results 
> in samples being attributed to the wrong instructions.  The attached patch 
> changes the oprofile kernel driver to ignore these slot bits on all newer 
> processors starting with POWER6.
> 
> Thanks.
> -Maynard
> 
> Signed-off-by: Maynard Johnson <maynardj@us.ibm.com>
> 
> 
> 
> diff -paur linux/arch/powerpc/oprofile/op_model_power4.c linux-p7-oprofile-patch//arch/powerpc/oprofile/op_model_power4.c
> --- linux/arch/powerpc/oprofile/op_model_power4.c	2009-05-01 08:20:21.000000000 -0500
> +++ linux-p7-oprofile-patch//arch/powerpc/oprofile/op_model_power4.c	2009-05-01 08:20:05.000000000 -0500
> @@ -26,6 +26,7 @@
>  static unsigned long reset_value[OP_MAX_COUNTER];
> 
>  static int oprofile_running;
> +static int use_slot_nums;
> 
>  /* mmcr values are set in power4_reg_setup, used in power4_cpu_setup */
>  static u32 mmcr0_val;
> @@ -61,6 +62,12 @@ static int power4_reg_setup(struct op_co
>  	else
>  		mmcr0_val |= MMCR0_PROBLEM_DISABLE;
> 
> +	if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p) ||
> +	    __is_processor(PV_970) || __is_processor(PV_970FX) ||
> +	    __is_processor(PV_970MP) || __is_processor(PV_970GX) ||
> +	    __is_processor(PV_POWER5) || __is_processor(PV_POWER5p))
> +		use_slot_nums = 1;
> +
>  	return 0;
>  }
> 
> @@ -206,7 +213,7 @@ static unsigned long get_pc(struct pt_re
> 
>  	mmcra = mfspr(SPRN_MMCRA);
> 
> -	if (mmcra & MMCRA_SAMPLE_ENABLE) {
> +	if (use_slot_nums && (mmcra & MMCRA_SAMPLE_ENABLE)) {
>  		slot = ((mmcra & MMCRA_SLOT) >> MMCRA_SLOT_SHIFT);
>  		if (slot > 1)
>  			pc += 4 * (slot - 1);
> 
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

^ permalink raw reply

* Re: [PATCH] RFC: powerpc: expose the multi-bit ops that underlie single-bit ops.
From: Benjamin Herrenschmidt @ 2009-06-16  3:53 UTC (permalink / raw)
  To: Geoff Thorpe; +Cc: linuxppc-dev
In-Reply-To: <1243361946-6771-1-git-send-email-Geoff.Thorpe@freescale.com>

On Tue, 2009-05-26 at 14:19 -0400, Geoff Thorpe wrote:
> NOT FOR COMMIT, THIS IS A REQUEST FOR FEEDBACK.
> 
> The bitops.h functions that operate on a single bit in a bitfield are
> implemented by operating on the corresponding word location. In all cases
> the inner logic appears to be valid if the mask being applied has more
> than one bit set, so this patch exposes those inner operations. Indeed,
> set_bits() was already available, but it duplicated code from set_bit()
> (rather than making the latter a wrapper) - it was also missing the
> PPC405_ERR77() workaround and the "volatile" address qualifier present in
> other APIs. This corrects that, and exposes the other multi-bit
> equivalents.
> 
> One advantage of these multi-bit forms is that they allow word-sized
> variables to essentially be their own spinlocks.

Hi ! Sorry for the delay, that was on my "have a look one of these days,
low priority" list for a bit too long :-)

> NB, the same factoring is possible in asm-generic/bitops/[non-]atomic.h.
> I would be happy to provide corresponding patches if this approach is
> deemed appropriate. Feedback would be most welcome.
> 
> Signed-off-by: Geoff Thorpe <Geoff.Thorpe@freescale.com>
> ---
>  arch/powerpc/include/asm/bitops.h |  111 +++++++++++++++++++++++--------------
>  1 files changed, 69 insertions(+), 42 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h
> index 897eade..72de28c 100644
> --- a/arch/powerpc/include/asm/bitops.h
> +++ b/arch/powerpc/include/asm/bitops.h
> @@ -56,11 +56,10 @@
>  #define BITOP_WORD(nr)		((nr) / BITS_PER_LONG)
>  #define BITOP_LE_SWIZZLE	((BITS_PER_LONG-1) & ~0x7)
>  
> -static __inline__ void set_bit(int nr, volatile unsigned long *addr)
> +static __inline__ void set_bits(unsigned long mask, volatile unsigned long *_p)
>  {
>  	unsigned long old;
> -	unsigned long mask = BITOP_MASK(nr);
> -	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
> +	unsigned long *p = (unsigned long *)_p;
>  
>  	__asm__ __volatile__(
>  "1:"	PPC_LLARX "%0,0,%3	# set_bit\n"
> @@ -73,11 +72,16 @@ static __inline__ void set_bit(int nr, volatile unsigned long *addr)
>  	: "cc" );
>  }
>  
> -static __inline__ void clear_bit(int nr, volatile unsigned long *addr)
> +static __inline__ void set_bit(int nr, volatile unsigned long *addr)
> +{
> +	set_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr));
> +}

No objection with the above.

> +static __inline__ void clear_bits(unsigned long mask,
> +				volatile unsigned long *_p)
>  {
>  	unsigned long old;
> -	unsigned long mask = BITOP_MASK(nr);
> -	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
> +	unsigned long *p = (unsigned long *)_p;
>  
>  	__asm__ __volatile__(
>  "1:"	PPC_LLARX "%0,0,%3	# clear_bit\n"
> @@ -90,11 +94,16 @@ static __inline__ void clear_bit(int nr, volatile unsigned long *addr)
>  	: "cc" );
>  }
>  
> -static __inline__ void clear_bit_unlock(int nr, volatile unsigned long *addr)
> +static __inline__ void clear_bit(int nr, volatile unsigned long *addr)
> +{
> +	clear_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr));
> +}

Looks good too.

> +static __inline__ void clear_bits_unlock(unsigned long mask,
> +					volatile unsigned long *_p)
>  {
>  	unsigned long old;
> -	unsigned long mask = BITOP_MASK(nr);
> -	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
> +	unsigned long *p = (unsigned long *)_p;
>  
>  	__asm__ __volatile__(
>  	LWSYNC_ON_SMP
> @@ -108,11 +117,16 @@ static __inline__ void clear_bit_unlock(int nr, volatile unsigned long *addr)
>  	: "cc", "memory");
>  }
>  
> -static __inline__ void change_bit(int nr, volatile unsigned long *addr)
> +static __inline__ void clear_bit_unlock(int nr, volatile unsigned long *addr)
> +{
> +	clear_bits_unlock(BITOP_MASK(nr), addr + BITOP_WORD(nr));
> +}

I'm not sure it's useful to provide a multi-bit variant of the
"lock" and "unlock" primitives. Do other archs do ?

> +static __inline__ void change_bits(unsigned long mask,
> +				volatile unsigned long *_p)
>  {
>  	unsigned long old;
> -	unsigned long mask = BITOP_MASK(nr);
> -	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
> +	unsigned long *p = (unsigned long *)_p;
>  
>  	__asm__ __volatile__(
>  "1:"	PPC_LLARX "%0,0,%3	# change_bit\n"
> @@ -125,12 +139,16 @@ static __inline__ void change_bit(int nr, volatile unsigned long *addr)
>  	: "cc" );
>  }
>  
> -static __inline__ int test_and_set_bit(unsigned long nr,
> -				       volatile unsigned long *addr)
> +static __inline__ void change_bit(int nr, volatile unsigned long *addr)
> +{
> +	change_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr));
> +}

Ah, patch is getting confused between change_bit and
test_and_set_bit :-)

Now, you know what I'm thinking is ... Those are all the same except
for:

 - Barriers for lock and unlock variants
 - Barriers for "return" (aka test_and_set) variants
 - Actual op done on the mask

Maybe we can shrink that file significantly (and avoid the risk for
typos etc...) by generating them all from a macro.

Something like (typed directly into the mailer :-)

#define DEFINE_BITOP(op, prefix, postfix) \
	asm volatile (			  \
	prefix				  \
"1:"    PPC_LLARX "%0,0,%3\n"		  \
	__stringify(op) "%1,%0,%2\n"	  \
	PPC405_ERR77(0,%3)		  \
	PPC_STLCX "%1,0,%3\n"		  \
	"bne- 1b\n"			  \
	postfix				  \
	 : "=&r" (old), "=&r" (t)
	 : "r" (mask), "r" (p)
	 : "cc", "memory")

and so:

static inline void set_bits(unsigned long mask, volatile unsigned long *addr)
{
	unsigned long old, t;

	DEFINE_BITOP(or, "", "");
}

static inline void test_and_set_bits(unsigned long mask, volatile unsigned long *addr)
{
	unsigned long old, t;

	DEFINE_BITOP(or, LWSYNC_ON_SMP, ISYNC_ON_SMP);

	return (old & mask) != 0;
}

etc...

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH v2] drivers/hvc: add missing __devexit_p()
From: Benjamin Herrenschmidt @ 2009-06-16  3:30 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: linuxppc-dev, Andrew Morton, linux-kernel
In-Reply-To: <1242632661-16198-1-git-send-email-vapier@gentoo.org>

On Mon, 2009-05-18 at 03:44 -0400, Mike Frysinger wrote:
> The remove function uses __devexit, so the .remove assignment needs
> __devexit_p() to fix a build error with hotplug disabled.
> 
> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
> CC: linuxppc-dev@ozlabs.org
> ---
> v2

Thanks. Andrew, I'm picking this one up.

Cheers,
Ben.

> 	- include all hvc files
> 
>  drivers/char/hvc_iseries.c |    2 +-
>  drivers/char/hvc_vio.c     |    2 +-
>  drivers/char/hvcs.c        |    2 +-
>  3 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/char/hvc_iseries.c b/drivers/char/hvc_iseries.c
> index 449727b..936d05b 100644
> --- a/drivers/char/hvc_iseries.c
> +++ b/drivers/char/hvc_iseries.c
> @@ -241,7 +241,7 @@ static int __devexit hvc_vio_remove(struct vio_dev *vdev)
>  static struct vio_driver hvc_vio_driver = {
>  	.id_table	= hvc_driver_table,
>  	.probe		= hvc_vio_probe,
> -	.remove		= hvc_vio_remove,
> +	.remove		= __devexit_p(hvc_vio_remove),
>  	.driver		= {
>  		.name	= hvc_driver_name,
>  		.owner	= THIS_MODULE,
> diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c
> index bd62dc8..c72b994 100644
> --- a/drivers/char/hvc_vio.c
> +++ b/drivers/char/hvc_vio.c
> @@ -113,7 +113,7 @@ static int __devexit hvc_vio_remove(struct vio_dev *vdev)
>  static struct vio_driver hvc_vio_driver = {
>  	.id_table	= hvc_driver_table,
>  	.probe		= hvc_vio_probe,
> -	.remove		= hvc_vio_remove,
> +	.remove		= __devexit_p(hvc_vio_remove),
>  	.driver		= {
>  		.name	= hvc_driver_name,
>  		.owner	= THIS_MODULE,
> diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c
> index c76bccf..2724d62 100644
> --- a/drivers/char/hvcs.c
> +++ b/drivers/char/hvcs.c
> @@ -868,7 +868,7 @@ static int __devexit hvcs_remove(struct vio_dev *dev)
>  static struct vio_driver hvcs_vio_driver = {
>  	.id_table	= hvcs_driver_table,
>  	.probe		= hvcs_probe,
> -	.remove		= hvcs_remove,
> +	.remove		= __devexit_p(hvcs_remove),
>  	.driver		= {
>  		.name	= hvcs_driver_name,
>  		.owner	= THIS_MODULE,

^ permalink raw reply

* Re: UIO: uio_mem does not handle devices above 4 GB address
From: Benjamin Herrenschmidt @ 2009-06-16  3:25 UTC (permalink / raw)
  To: Steven A. Falco
  Cc: linuxppc-dev@ozlabs.org, hjk, Herrera-Bendezu, Luis, linux-kernel
In-Reply-To: <49D4BB9F.8050903@harris.com>

On Thu, 2009-04-02 at 09:20 -0400, Steven A. Falco wrote:

> struct uio_mem {
> 	phys_addr_t		addr;
> 	phys_addr_t		size;
> 	int			memtype;
> 	void __iomem		*internal_addr;
> 	struct uio_map		*map;
> };
> 
> A few other changes would be needed.  We'd have to use something
> other than

Use a struct resource instead.

> 	return sprintf(buf, "0x%lx\n", mem->addr);
> 

The struct resource has a printk format string.

Cheers,
Ben.
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

^ permalink raw reply

* Please pull from 'next' branch for 2.6.31
From: Kumar Gala @ 2009-06-16  3:25 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev

Please pull from 'next' branch of

	master.kernel.org:/pub/scm/linux/kernel/git/galak/powerpc.git next

to receive the following updates:

 arch/powerpc/boot/cuboot-85xx.c                 |    2
 arch/powerpc/boot/dts/asp834x-redboot.dts       |    2
 arch/powerpc/boot/dts/gef_sbc610.dts            |   10
 arch/powerpc/boot/dts/kmeter1.dts               |  520 ++++++
 arch/powerpc/boot/dts/mpc8272ads.dts            |   19
 arch/powerpc/boot/dts/mpc8315erdb.dts           |   15
 arch/powerpc/boot/dts/mpc8349emitx.dts          |    2
 arch/powerpc/boot/dts/mpc834x_mds.dts           |    2
 arch/powerpc/boot/dts/mpc8377_mds.dts           |    2
 arch/powerpc/boot/dts/mpc8377_rdb.dts           |    2
 arch/powerpc/boot/dts/mpc8378_mds.dts           |    2
 arch/powerpc/boot/dts/mpc8378_rdb.dts           |    2
 arch/powerpc/boot/dts/mpc8379_mds.dts           |    2
 arch/powerpc/boot/dts/mpc8379_rdb.dts           |    2
 arch/powerpc/boot/dts/mpc8569mds.dts            |   87 +
 arch/powerpc/boot/dts/sbc8349.dts               |    2
 arch/powerpc/boot/dts/xcalibur1501.dts          |  696 +++++++++
 arch/powerpc/boot/dts/xpedite5200.dts           |  466 ++++++
 arch/powerpc/boot/dts/xpedite5200_xmon.dts      |  506 ++++++
 arch/powerpc/boot/dts/xpedite5301.dts           |  640 ++++++++
 arch/powerpc/boot/dts/xpedite5330.dts           |  707 +++++++++
 arch/powerpc/boot/dts/xpedite5370.dts           |  638 ++++++++
 arch/powerpc/boot/wrapper                       |    4
 arch/powerpc/configs/83xx/kmeter1_defconfig     |  908 +++++++++++
 arch/powerpc/configs/85xx/xes_mpc85xx_defconfig | 1821 ++++++++++++++++++++++++
 arch/powerpc/include/asm/fsl_lbc.h              |    4
 arch/powerpc/include/asm/reg_booke.h            |    2
 arch/powerpc/kernel/cpu_setup_6xx.S             |    3
 arch/powerpc/kernel/cpu_setup_fsl_booke.S       |   49
 arch/powerpc/platforms/83xx/Kconfig             |    7
 arch/powerpc/platforms/83xx/Makefile            |    1
 arch/powerpc/platforms/83xx/kmeter1.c           |  191 ++
 arch/powerpc/platforms/83xx/mpc83xx.h           |    4
 arch/powerpc/platforms/83xx/usb.c               |   10
 arch/powerpc/platforms/85xx/Kconfig             |   13
 arch/powerpc/platforms/85xx/Makefile            |    1
 arch/powerpc/platforms/85xx/mpc8536_ds.c        |   17
 arch/powerpc/platforms/85xx/mpc85xx_ds.c        |   19
 arch/powerpc/platforms/85xx/mpc85xx_mds.c       |   20
 arch/powerpc/platforms/85xx/xes_mpc85xx.c       |  282 +++
 arch/powerpc/platforms/86xx/Kconfig             |    1
 arch/powerpc/platforms/86xx/mpc86xx_hpcn.c      |   15
 drivers/rapidio/rio-scan.c                      |   43
 drivers/rapidio/rio-sysfs.c                     |    6
 drivers/serial/ucc_uart.c                       |   19
 45 files changed, 7713 insertions(+), 53 deletions(-)

Anton Vorontsov (1):
      powerpc/83xx: Update sdhci nodes per new bindings

Becky Bruce (1):
      powerpc: Add 86xx support for SWIOTLB

Dave Liu (1):
      serial: Make ucc_uart work in HW UART mode

Gerhard Pircher (1):
      powerpc: Enable additional BAT registers in setup_745x_specifics()

Haiying Wang (1):
      powerpc/85xx: Add UCC6 and UCC8 nodes in SGMII mode for MPC8569MDS

Heiko Schocher (1):
      83xx: add support for the kmeter1 board.

Kevin Hao (1):
      powerpc/85xx: Add nor flash partitions for mpc8569mds

Kumar Gala (1):
      powerpc/85xx: Add SWIOTLB support to FSL boards

Martyn Welch (1):
      powerpc/86xx: Add I2C device mappings in DTS for SBC610

Nate Case (6):
      powerpc/fsl-booke: Enable L1 cache on e500v1/e500v2/e500mc CPUs
      powerpc/85xx: cuboot - Fix up ethernet3 MAC address on MPC85xx
      powerpc/85xx: Add platform support for X-ES MPC85xx boards
      powerpc/85xx: Add dts files for X-ES MPC85xx boards
      powerpc/85xx: Add defconfig for X-ES MPC85xx boards
      powerpc/bootwrapper: Custom build options for XPedite52xx targets

Peter Korsgaard (1):
      powerpc/mpc83xx: Fix usb mux setup for mpc834x

Wolfgang Denk (1):
      powerpc/mpc8272ads: fix device tree for 8 MB flash size

Yang Li (1):
      rio: warn_unused_result warnings fix

leon.woestenberg@gmail.com (1):
      powerpc/83xx: Add MSI interrupts to DTS of MPC8315E-RDB

mware@internode.on.net (1):
      powerpc/fsl: Increase the number of possible localbus banks

^ permalink raw reply

* Re: [PATCH v5] 83xx: add support for the kmeter1 board.
From: Kumar Gala @ 2009-06-16  3:16 UTC (permalink / raw)
  To: hs; +Cc: Scott Wood, linuxppc-dev
In-Reply-To: <4A35FA6A.60004@denx.de>


On Jun 15, 2009, at 2:38 AM, Heiko Schocher wrote:

> The following series implements basic board support for
> the kmeter1 board from keymile, based on a MPC8360.
>
> This series provides the following functionality:
>
> - The board can boot with a serial console on UART1
> - Ethernet:
>    UCC1 in RGMII mode
>    UCC2 in RGMII mode
>    UCC4 in RMII mode
>    UCC5 in RMII mode
>    UCC6 in RMII mode
>    UCC7 in RMII mode
>    UCC8 in RMII mode
>
>    following patch is necessary for working UCC in RMII mode:
>
>    http://lists.ozlabs.org/pipermail/linuxppc-dev/2009-April/070804.html
>
> - Flash accessed via MTD layer
>
>  On this hardware there is an Intel P30 flash, following patch
>  series is necessary for working with this hardware:
>
>  http://lists.ozlabs.org/pipermail/linuxppc-dev/2009-April/070624.html
>
> - I2C using I2C Bus 1 from the MPC8360 cpu
>
> Signed-off-by: Heiko Schocher <hs@denx.de>
> ---
> changes since v1:
> - added comments from Kumar Gala and Scott Wood
> - get rid of using get_immrbase() in board specific code
>
> changes since v2:
> - added comments from Kumar Gala
> - rebased against 1406de8e11eb043681297adf86d6892ff8efc27a
>  from git://git.kernel.org/pub/scm/linux/kernel/git/galak/powerpc.git
>
> changes since v3:
> - updated mailinglistarchivelinks for necessary patches in commit  
> text.
>
> changes since v4:
> - added comments from David Gibson
>
> $ ./scripts/checkpatch.pl 0001--83xx-add-support-for-the-kmeter1- 
> board.patch
> total: 0 errors, 0 warnings, 1636 lines checked
>
> 0001--83xx-add-support-for-the-kmeter1-board.patch has no obvious  
> style problems and is ready for submission.
> $
>
> Signed-off-by: Heiko Schocher <hs@denx.de>
> ---
> arch/powerpc/boot/dts/kmeter1.dts           |  520 +++++++++++++++
> arch/powerpc/configs/83xx/kmeter1_defconfig |  908 ++++++++++++++++++ 
> +++++++++
> arch/powerpc/platforms/83xx/Kconfig         |    7 +
> arch/powerpc/platforms/83xx/Makefile        |    1 +
> arch/powerpc/platforms/83xx/kmeter1.c       |  191 ++++++
> 5 files changed, 1627 insertions(+), 0 deletions(-)
> create mode 100644 arch/powerpc/boot/dts/kmeter1.dts
> create mode 100644 arch/powerpc/configs/83xx/kmeter1_defconfig
> create mode 100644 arch/powerpc/platforms/83xx/kmeter1.c

applied to next

- k

^ permalink raw reply

* Re: [PATCH -next 4/4] powerpc/bootwrapper: Custom build options for XPedite52xx targets
From: Kumar Gala @ 2009-06-16  3:16 UTC (permalink / raw)
  To: Nate Case; +Cc: linuxppc-dev, David Gibson
In-Reply-To: <1244749381-17429-5-git-send-email-ncase@xes-inc.com>


On Jun 11, 2009, at 2:43 PM, Nate Case wrote:

> Some XPedite52xx boards have a legacy boot loader requiring some  
> special
> care in the boot wrapper.  The use of cuboot-85xx is needed to fix
> up embedded device trees, and a custom link address is specified to
> accommodate the boot loader and larger kernel image sizes used on X-ES
> MPC85xx platforms.
>
> Signed-off-by: Nate Case <ncase@xes-inc.com>
> ---
> arch/powerpc/boot/wrapper |    4 ++++
> 1 files changed, 4 insertions(+), 0 deletions(-)


applied to next

- k

^ permalink raw reply

* Re: [PATCH -next 3/4] powerpc/85xx: Add defconfig for X-ES MPC85xx boards
From: Kumar Gala @ 2009-06-16  3:16 UTC (permalink / raw)
  To: Nate Case; +Cc: linuxppc-dev, David Gibson
In-Reply-To: <1244749381-17429-4-git-send-email-ncase@xes-inc.com>


On Jun 11, 2009, at 2:43 PM, Nate Case wrote:

> Signed-off-by: Nate Case <ncase@xes-inc.com>
> ---
> arch/powerpc/configs/85xx/xes_mpc85xx_defconfig | 1821 ++++++++++++++ 
> +++++++++
> 1 files changed, 1821 insertions(+), 0 deletions(-)
> create mode 100644 arch/powerpc/configs/85xx/xes_mpc85xx_defconfig


applied to next

- k

^ permalink raw reply

* Re: [PATCH -next 2/4] powerpc/85xx: Add dts files for X-ES MPC85xx boards
From: Kumar Gala @ 2009-06-16  3:16 UTC (permalink / raw)
  To: Nate Case; +Cc: linuxppc-dev, David Gibson
In-Reply-To: <1244749381-17429-3-git-send-email-ncase@xes-inc.com>


On Jun 11, 2009, at 2:42 PM, Nate Case wrote:

> Add device tree source files for various MPC85xx boards from Extreme
> Engineering Solutions.  Supported boards include XPedite5370,
> XPedite5200, XPedite5301, XPedite5330, and XCalibur1501.
>
> Signed-off-by: Nate Case <ncase@xes-inc.com>
> ---
> arch/powerpc/boot/dts/xcalibur1501.dts     |  696 +++++++++++++++++++ 
> ++++++++
> arch/powerpc/boot/dts/xpedite5200.dts      |  466 ++++++++++++++++++
> arch/powerpc/boot/dts/xpedite5200_xmon.dts |  506 ++++++++++++++++++++
> arch/powerpc/boot/dts/xpedite5301.dts      |  640 +++++++++++++++++++ 
> ++++++
> arch/powerpc/boot/dts/xpedite5330.dts      |  707 +++++++++++++++++++ 
> +++++++++
> arch/powerpc/boot/dts/xpedite5370.dts      |  638 +++++++++++++++++++ 
> ++++++
> 6 files changed, 3653 insertions(+), 0 deletions(-)
> create mode 100644 arch/powerpc/boot/dts/xcalibur1501.dts
> create mode 100644 arch/powerpc/boot/dts/xpedite5200.dts
> create mode 100644 arch/powerpc/boot/dts/xpedite5200_xmon.dts
> create mode 100644 arch/powerpc/boot/dts/xpedite5301.dts
> create mode 100644 arch/powerpc/boot/dts/xpedite5330.dts
> create mode 100644 arch/powerpc/boot/dts/xpedite5370.dts


applied to next

- k

^ permalink raw reply

* Re: [PATCH -next 1/4] powerpc/85xx: Add platform support for X-ES MPC85xx boards
From: Kumar Gala @ 2009-06-16  3:16 UTC (permalink / raw)
  To: Nate Case; +Cc: linuxppc-dev, David Gibson
In-Reply-To: <1244749381-17429-2-git-send-email-ncase@xes-inc.com>


On Jun 11, 2009, at 2:42 PM, Nate Case wrote:

> Add support for X-ES single-board computers based on the Freescale
> MPC85xx processors.
>
> Signed-off-by: Nate Case <ncase@xes-inc.com>
> ---
> arch/powerpc/platforms/85xx/Kconfig       |   10 +
> arch/powerpc/platforms/85xx/Makefile      |    1 +
> arch/powerpc/platforms/85xx/xes_mpc85xx.c |  282 ++++++++++++++++++++ 
> +++++++++
> 3 files changed, 293 insertions(+), 0 deletions(-)
> create mode 100644 arch/powerpc/platforms/85xx/xes_mpc85xx.c


applied to next

- k

^ permalink raw reply

* [git pull] Please pull powerpc.git merge branch
From: Benjamin Herrenschmidt @ 2009-06-16  3:05 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linuxppc-dev list, Andrew Morton, Linux Kernel list

Hi Linus !

Here's the other batch of powerpc stuff, including adding a small
accessor to the generic BIO code (acked by Jens) and Paulus generic
atomic64 implementation. A lot of PS3 updates in there, though I held
back a couple for some purely mechanical merge reasons, so expect a 3rd
batch with these plus some bug fixes before the end of the merge window.

The following changes since commit 03347e2592078a90df818670fddf97a33eec70fb:
  Linus Torvalds (1):
        Merge branch 'release' of git://git.kernel.org/.../aegl/linux-2.6

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git merge

Benjamin Herrenschmidt (2):
      Merge commit 'origin/master' into next
      powerpc: Don't do generic calibrate_delay()

Geert Uytterhoeven (24):
      ps3vram: Fix error path (return -EIO) for short read/write
      ps3vram: Use proc_create_data() instead of proc_create()
      ps3fb: Remove useless debug checks in ps3fb_shutdown()
      ps3fb: Inline functions in ps3fb_probe(), to ease cleanup in the error path
      ps3fb: Correct handling of device opening in ps3fb_probe()
      powerpc/cell: Extract duplicated IOPTE_* to <asm/iommu.h>
      ps3fb: GPU memory mapping cleanup
      ps3vram: GPU memory mapping cleanup
      ps3fb/vram: Extract common GPU stuff into <asm/ps3gpu.h>
      ps3fb: Tear down FB setup during cleanup
      block: Add bio_list_peek()
      ps3vram: Replace mutex by spinlock + bio_list
      ps3vram: Remove no longer used ps3vram_priv.ddr_base
      ps3vram: Make ps3vram_priv.reports a void *
      ps3: Use dev_[gs]et_drvdata() instead of direct access for system bus devices
      ps3: shorten ps3_system_bus_[gs]et_driver_data to ps3_system_bus_[gs]et_drvdata
      ps3flash: Use ps3_system_bus_[gs]et_drvdata() instead of direct access
      ps3fb: Use ps3_system_bus_[gs]et_drvdata() instead of direct access
      drivers/ps3: Add missing annotations
      ps3: Correct debug message in dma_ioc0_map_pages()
      ps3: Switch ps3_os_area_[gs]et_rtc_diff to EXPORT_SYMBOL_GPL()
      ps3: Replace direct file operations by callback
      ps3flash: Cache the last accessed FLASH chunk
      ps3flash: Always read chunks of 256 KiB, and cache them

Grant Likely (1):
      powerpc/install: Bail with error code on error in install script

Jim Paris (1):
      ps3vram: Correct exchanged gotos in ps3vram_probe() error path

Michael Ellerman (5):
      powerpc: Fix warning in setup_64.c when CONFIG_RELOCATABLE=y
      powerpc/cell: Use driver_data acessors, not platform_data in Axon MSI
      powerpc: Only build prom_init.o when CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
      powerpc/iseries: Fix unused function warning in iSeries DT code
      powerpc/iseries: Mark signal_vsp_instruction() as maybe unused

Paul Mackerras (3):
      powerpc: Add compiler memory barrier to mtmsr macro
      lib: Provide generic atomic64_t implementation
      powerpc: Use generic atomic64_t implementation on 32-bit processors

Roel Kluin (1):
      block/ps3: remove driver_data direct access of struct device

Stephen Rothwell (1):
      powerpc: Wire up sys_rt_tgsigqueueinfo

sebastian.blanes@gmail.com (1):
      ps3av: Set 16:9 aspect ratio for 720p video modes

 Documentation/kernel-parameters.txt                |    7 +
 Documentation/powerpc/dts-bindings/ecm.txt         |   64 ++
 .../powerpc/dts-bindings/fsl/cpm_qe/qe.txt         |    3 +
 Documentation/powerpc/dts-bindings/fsl/esdhc.txt   |    5 +-
 Documentation/powerpc/dts-bindings/fsl/mcm.txt     |   64 ++
 arch/powerpc/Kconfig                               |   21 +-
 arch/powerpc/Kconfig.debug                         |   13 +
 arch/powerpc/Makefile                              |    1 +
 arch/powerpc/boot/dts/gef_ppc9a.dts                |   14 +-
 arch/powerpc/boot/dts/gef_sbc310.dts               |   14 +-
 arch/powerpc/boot/dts/gef_sbc610.dts               |   14 +-
 arch/powerpc/boot/dts/ksi8560.dts                  |   13 +
 arch/powerpc/boot/dts/mpc832x_mds.dts              |    3 +-
 arch/powerpc/boot/dts/mpc832x_rdb.dts              |    3 +-
 arch/powerpc/boot/dts/mpc8349emitx.dts             |    2 -
 arch/powerpc/boot/dts/mpc8349emitxgp.dts           |    1 -
 arch/powerpc/boot/dts/mpc834x_mds.dts              |    2 -
 arch/powerpc/boot/dts/mpc836x_mds.dts              |    3 +-
 arch/powerpc/boot/dts/mpc836x_rdk.dts              |    2 +
 arch/powerpc/boot/dts/mpc8377_mds.dts              |    1 -
 arch/powerpc/boot/dts/mpc8378_mds.dts              |    1 -
 arch/powerpc/boot/dts/mpc8379_mds.dts              |    1 -
 arch/powerpc/boot/dts/mpc8536ds.dts                |   18 +-
 arch/powerpc/boot/dts/mpc8540ads.dts               |   15 +-
 arch/powerpc/boot/dts/mpc8541cds.dts               |   16 +-
 arch/powerpc/boot/dts/mpc8544ds.dts                |   18 +-
 arch/powerpc/boot/dts/mpc8548cds.dts               |   17 +-
 arch/powerpc/boot/dts/mpc8555cds.dts               |   16 +-
 arch/powerpc/boot/dts/mpc8560ads.dts               |   15 +-
 arch/powerpc/boot/dts/mpc8568mds.dts               |   51 +-
 arch/powerpc/boot/dts/mpc8569mds.dts               |  583 +++++++++++
 arch/powerpc/boot/dts/mpc8572ds.dts                |   17 +-
 arch/powerpc/boot/dts/mpc8572ds_36b.dts            |   39 +-
 arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts     |   16 +-
 arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts     |    2 -
 arch/powerpc/boot/dts/mpc8610_hpcd.dts             |   16 +-
 arch/powerpc/boot/dts/mpc8641_hpcn.dts             |   16 +-
 arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts         |  609 +++++++++++
 arch/powerpc/boot/dts/p2020ds.dts                  |  704 +++++++++++++
 arch/powerpc/boot/dts/sbc8349.dts                  |    1 -
 arch/powerpc/boot/dts/sbc8548.dts                  |   16 +-
 arch/powerpc/boot/dts/sbc8560.dts                  |   15 +-
 arch/powerpc/boot/dts/sbc8641d.dts                 |   16 +-
 arch/powerpc/boot/dts/sequoia.dts                  |   22 +
 arch/powerpc/boot/dts/socrates.dts                 |   15 +-
 arch/powerpc/boot/dts/stx_gp3_8560.dts             |   15 +-
 arch/powerpc/boot/dts/tqm8540.dts                  |   15 +-
 arch/powerpc/boot/dts/tqm8541.dts                  |   15 +-
 arch/powerpc/boot/dts/tqm8548-bigflash.dts         |   16 +-
 arch/powerpc/boot/dts/tqm8548.dts                  |   16 +-
 arch/powerpc/boot/dts/tqm8555.dts                  |   15 +-
 arch/powerpc/boot/dts/tqm8560.dts                  |   15 +-
 arch/powerpc/boot/dts/virtex440-ml510.dts          |  465 +++++++++
 arch/powerpc/boot/dts/warp.dts                     |   27 +-
 arch/powerpc/boot/install.sh                       |    3 +
 arch/powerpc/configs/40x/acadia_defconfig          |    2 +-
 arch/powerpc/configs/40x/ep405_defconfig           |    2 +-
 arch/powerpc/configs/40x/kilauea_defconfig         |   81 ++-
 arch/powerpc/configs/40x/makalu_defconfig          |   81 ++-
 arch/powerpc/configs/40x/virtex_defconfig          |    2 +-
 arch/powerpc/configs/44x/arches_defconfig          |    2 +-
 arch/powerpc/configs/44x/bamboo_defconfig          |    2 +-
 arch/powerpc/configs/44x/canyonlands_defconfig     |    6 +-
 arch/powerpc/configs/44x/ebony_defconfig           |    2 +-
 arch/powerpc/configs/44x/katmai_defconfig          |    2 +-
 arch/powerpc/configs/44x/rainier_defconfig         |    2 +-
 arch/powerpc/configs/44x/redwood_defconfig         |    2 +-
 arch/powerpc/configs/44x/sam440ep_defconfig        |    2 +-
 arch/powerpc/configs/44x/sequoia_defconfig         |  111 ++-
 arch/powerpc/configs/44x/taishan_defconfig         |    2 +-
 arch/powerpc/configs/44x/virtex5_defconfig         |    2 +-
 arch/powerpc/include/asm/atomic.h                  |    3 +
 arch/powerpc/include/asm/cpm2.h                    |    4 -
 arch/powerpc/include/asm/dma-mapping.h             |   11 +
 arch/powerpc/include/asm/elf.h                     |    4 +-
 arch/powerpc/include/asm/emulated_ops.h            |   73 ++
 arch/powerpc/include/asm/feature-fixups.h          |   25 +-
 arch/powerpc/include/asm/hw_irq.h                  |    5 +-
 arch/powerpc/include/asm/iommu.h                   |   10 +
 arch/powerpc/include/asm/lppaca.h                  |    6 +
 arch/powerpc/include/asm/machdep.h                 |    4 +
 arch/powerpc/include/asm/mmu.h                     |    9 +-
 arch/powerpc/include/asm/mpc86xx.h                 |   33 -
 arch/powerpc/include/asm/paca.h                    |   12 +-
 arch/powerpc/include/asm/page.h                    |    5 +
 arch/powerpc/include/asm/pci-bridge.h              |   13 +-
 arch/powerpc/include/asm/pgtable-ppc64.h           |    5 +
 arch/powerpc/include/asm/ppc-opcode.h              |   25 +-
 arch/powerpc/include/asm/ppc_asm.h                 |   10 -
 arch/powerpc/include/asm/ps3.h                     |   18 +-
 arch/powerpc/include/asm/ps3gpu.h                  |   86 ++
 arch/powerpc/include/asm/ptrace.h                  |    4 +
 arch/powerpc/include/asm/qe.h                      |   21 +-
 arch/powerpc/include/asm/reg.h                     |    4 +-
 arch/powerpc/include/asm/scatterlist.h             |    6 +-
 arch/powerpc/include/asm/swiotlb.h                 |   27 +
 arch/powerpc/include/asm/systbl.h                  |    1 +
 arch/powerpc/include/asm/system.h                  |    2 +-
 arch/powerpc/include/asm/unistd.h                  |    3 +-
 arch/powerpc/include/asm/xilinx_pci.h              |   21 +
 arch/powerpc/kernel/Makefile                       |    6 +-
 arch/powerpc/kernel/align.c                        |   20 +-
 arch/powerpc/kernel/asm-offsets.c                  |   32 +-
 arch/powerpc/kernel/cputable.c                     |    6 +-
 arch/powerpc/kernel/dma-swiotlb.c                  |  163 +++
 arch/powerpc/kernel/dma.c                          |    2 +-
 arch/powerpc/kernel/exceptions-64s.S               |  978 +++++++++++++++++
 arch/powerpc/kernel/ftrace.c                       |   29 +-
 arch/powerpc/kernel/head_32.S                      |  101 +--
 arch/powerpc/kernel/head_64.S                      | 1095 +-------------------
 arch/powerpc/kernel/head_booke.h                   |   10 +-
 arch/powerpc/kernel/irq.c                          |  127 ++--
 arch/powerpc/kernel/lparcfg.c                      |   40 +-
 arch/powerpc/kernel/misc_64.S                      |   92 --
 arch/powerpc/kernel/paca.c                         |   14 +-
 arch/powerpc/kernel/pci-common.c                   |    3 +-
 arch/powerpc/kernel/pci_32.c                       |   19 -
 arch/powerpc/kernel/pci_64.c                       |   17 +-
 arch/powerpc/kernel/pci_dn.c                       |   28 +-
 arch/powerpc/kernel/process.c                      |    2 +-
 arch/powerpc/kernel/prom.c                         |    2 +-
 arch/powerpc/kernel/ptrace.c                       |   23 +-
 arch/powerpc/kernel/rtas_pci.c                     |   10 +-
 arch/powerpc/kernel/setup_32.c                     |    6 +
 arch/powerpc/kernel/setup_64.c                     |   15 +-
 arch/powerpc/kernel/time.c                         |   31 +-
 arch/powerpc/kernel/traps.c                        |  130 +++-
 arch/powerpc/kernel/vector.S                       |  210 ++++
 arch/powerpc/mm/Makefile                           |    7 +-
 arch/powerpc/mm/hash_native_64.c                   |   13 +-
 arch/powerpc/mm/init_64.c                          |    2 +
 arch/powerpc/mm/mmu_context_nohash.c               |   19 +-
 arch/powerpc/mm/numa.c                             |    2 +
 arch/powerpc/oprofile/op_model_fsl_emb.c           |   14 -
 arch/powerpc/platforms/40x/Kconfig                 |    2 +
 arch/powerpc/platforms/40x/Makefile                |    2 -
 arch/powerpc/platforms/40x/kilauea.c               |   60 --
 arch/powerpc/platforms/40x/makalu.c                |   60 --
 arch/powerpc/platforms/40x/ppc40x_simple.c         |    5 +-
 arch/powerpc/platforms/40x/virtex.c                |    2 +
 arch/powerpc/platforms/44x/Kconfig                 |   13 +-
 arch/powerpc/platforms/44x/Makefile                |    1 +
 arch/powerpc/platforms/44x/virtex.c                |    2 +
 arch/powerpc/platforms/44x/virtex_ml510.c          |   29 +
 arch/powerpc/platforms/44x/warp.c                  |   76 +-
 arch/powerpc/platforms/52xx/efika.c                |    4 +-
 arch/powerpc/platforms/52xx/mpc52xx_pci.c          |    4 +-
 arch/powerpc/platforms/82xx/pq2ads.h               |   13 -
 arch/powerpc/platforms/85xx/Kconfig                |    1 +
 arch/powerpc/platforms/85xx/mpc85xx_ds.c           |   43 +-
 arch/powerpc/platforms/85xx/mpc85xx_mds.c          |   52 +-
 arch/powerpc/platforms/86xx/gef_ppc9a.c            |    1 -
 arch/powerpc/platforms/86xx/gef_sbc310.c           |    1 -
 arch/powerpc/platforms/86xx/gef_sbc610.c           |    1 -
 arch/powerpc/platforms/86xx/mpc8610_hpcd.c         |    1 -
 arch/powerpc/platforms/86xx/mpc86xx_hpcn.c         |    1 -
 arch/powerpc/platforms/86xx/mpc86xx_smp.c          |    8 +-
 arch/powerpc/platforms/86xx/sbc8641d.c             |    1 -
 arch/powerpc/platforms/8xx/mpc885ads.h             |    4 -
 arch/powerpc/platforms/Kconfig                     |    4 +
 arch/powerpc/platforms/Kconfig.cputype             |   26 +-
 arch/powerpc/platforms/cell/axon_msi.c             |    4 +-
 arch/powerpc/platforms/cell/celleb_pci.c           |   10 +-
 arch/powerpc/platforms/cell/celleb_scc_epci.c      |   13 +-
 arch/powerpc/platforms/cell/celleb_scc_pciex.c     |   12 +-
 arch/powerpc/platforms/cell/iommu.c                |   37 +-
 arch/powerpc/platforms/cell/spufs/inode.c          |    6 -
 arch/powerpc/platforms/chrp/pci.c                  |    8 +-
 arch/powerpc/platforms/fsl_uli1575.c               |   24 +-
 arch/powerpc/platforms/iseries/dt.c                |    3 +-
 arch/powerpc/platforms/iseries/iommu.c             |    2 +-
 arch/powerpc/platforms/iseries/mf.c                |    3 +-
 arch/powerpc/platforms/iseries/pci.c               |    8 +-
 arch/powerpc/platforms/powermac/pic.c              |    2 +-
 arch/powerpc/platforms/powermac/setup.c            |    2 +-
 arch/powerpc/platforms/ps3/mm.c                    |   12 +-
 arch/powerpc/platforms/ps3/os-area.c               |  142 ++--
 arch/powerpc/platforms/ps3/platform.h              |   10 -
 arch/powerpc/platforms/ps3/setup.c                 |    1 +
 arch/powerpc/platforms/ps3/smp.c                   |   16 +-
 arch/powerpc/platforms/ps3/system-bus.c            |   15 +-
 arch/powerpc/platforms/pseries/iommu.c             |    4 +-
 arch/powerpc/platforms/pseries/lpar.c              |   52 +
 arch/powerpc/platforms/pseries/rtasd.c             |   76 +-
 arch/powerpc/platforms/pseries/setup.c             |   25 +
 arch/powerpc/sysdev/Makefile                       |    1 +
 arch/powerpc/sysdev/cpm2.c                         |    2 +-
 arch/powerpc/sysdev/fsl_msi.c                      |    9 +-
 arch/powerpc/sysdev/fsl_pci.c                      |  138 +++-
 arch/powerpc/sysdev/fsl_pci.h                      |    6 +-
 arch/powerpc/sysdev/fsl_rio.c                      |   15 +-
 arch/powerpc/sysdev/fsl_soc.c                      |   14 +-
 arch/powerpc/sysdev/indirect_pci.c                 |    4 +-
 arch/powerpc/sysdev/mpic.c                         |   23 +-
 arch/powerpc/sysdev/ppc4xx_pci.c                   |    4 +-
 arch/powerpc/sysdev/qe_lib/qe.c                    |   75 ++-
 arch/powerpc/sysdev/tsi108_pci.c                   |    4 +-
 arch/powerpc/sysdev/xilinx_intc.c                  |   81 ++-
 arch/powerpc/sysdev/xilinx_pci.c                   |  132 +++
 arch/powerpc/xmon/xmon.c                           |   47 +
 drivers/block/ps3disk.c                            |   18 +-
 drivers/block/ps3vram.c                            |  168 ++--
 drivers/char/ps3flash.c                            |  296 +++---
 drivers/char/viotape.c                             |    2 +-
 drivers/i2c/busses/i2c-ibm_iic.c                   |    6 +-
 drivers/macintosh/therm_adt746x.c                  |    4 +-
 drivers/net/ps3_gelic_net.c                        |    8 +-
 drivers/net/ucc_geth.c                             |   24 +-
 drivers/net/ucc_geth.h                             |    4 +-
 drivers/of/base.c                                  |    1 +
 drivers/pci/Makefile                               |    1 -
 drivers/ps3/ps3-sys-manager.c                      |    2 +-
 drivers/ps3/ps3av.c                                |    8 +-
 drivers/ps3/ps3av_cmd.c                            |    3 +-
 drivers/rapidio/rio-scan.c                         |    6 +-
 drivers/usb/host/ehci-ps3.c                        |    7 +-
 drivers/usb/host/ohci-ps3.c                        |    7 +-
 drivers/video/ps3fb.c                              |  272 ++---
 drivers/video/xilinxfb.c                           |  290 +++---
 include/asm-generic/atomic64.h                     |   42 +
 include/linux/bio.h                                |    5 +
 include/linux/pci_ids.h                            |    4 +
 lib/Kconfig                                        |    6 +
 lib/Makefile                                       |    2 +
 lib/atomic64.c                                     |  175 ++++
 225 files changed, 7064 insertions(+), 2884 deletions(-)
 create mode 100644 Documentation/powerpc/dts-bindings/ecm.txt
 create mode 100644 Documentation/powerpc/dts-bindings/fsl/mcm.txt
 create mode 100644 arch/powerpc/boot/dts/mpc8569mds.dts
 create mode 100644 arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts
 create mode 100644 arch/powerpc/boot/dts/p2020ds.dts
 create mode 100644 arch/powerpc/boot/dts/virtex440-ml510.dts
 create mode 100644 arch/powerpc/include/asm/emulated_ops.h
 delete mode 100644 arch/powerpc/include/asm/mpc86xx.h
 create mode 100644 arch/powerpc/include/asm/ps3gpu.h
 create mode 100644 arch/powerpc/include/asm/swiotlb.h
 create mode 100644 arch/powerpc/include/asm/xilinx_pci.h
 create mode 100644 arch/powerpc/kernel/dma-swiotlb.c
 create mode 100644 arch/powerpc/kernel/exceptions-64s.S
 delete mode 100644 arch/powerpc/platforms/40x/kilauea.c
 delete mode 100644 arch/powerpc/platforms/40x/makalu.c
 create mode 100644 arch/powerpc/platforms/44x/virtex_ml510.c
 create mode 100644 arch/powerpc/sysdev/xilinx_pci.c
 create mode 100644 include/asm-generic/atomic64.h
 create mode 100644 lib/atomic64.c

^ permalink raw reply

* [PATCH] powerpc/mm: Fix potential access to freed pages when using hugetlbfs
From: Benjamin Herrenschmidt @ 2009-06-16  2:53 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Paul Mackerras

When using 64k page sizes, our PTE pages are split in two halves,
the second half containing the "extension" used to keep track of
individual 4k pages when not using HW 64k pages.

However, our page tables used for hugetlb have a slightly different
format and don't carry that "second half".

Our code that batched PTEs to be invalidated unconditionally reads
the "second half" (to put it into the batch), which means that when
called to invalidate hugetlb PTEs, it will access unrelated memory.

It breaks when CONFIG_DEBUG_PAGEALLOC is enabled.

This fixes it by only accessing the second half when the _PAGE_COMBO
bit is set in the first half, which indicates that we are dealing with
a "combo" page which represents 16x4k subpages. Anything else shouldn't
have this bit set and thus not require loading from the second half.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---


 arch/powerpc/include/asm/pte-hash64-64k.h |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

--- linux-work.orig/arch/powerpc/include/asm/pte-hash64-64k.h	2009-06-16 11:27:05.000000000 +1000
+++ linux-work/arch/powerpc/include/asm/pte-hash64-64k.h	2009-06-16 12:03:29.000000000 +1000
@@ -47,7 +47,8 @@
  * generic accessors and iterators here
  */
 #define __real_pte(e,p) 	((real_pte_t) { \
-	(e), pte_val(*((p) + PTRS_PER_PTE)) })
+			(e), ((e) & _PAGE_COMBO) ? \
+				(pte_val(*((p) + PTRS_PER_PTE))) : 0 })
 #define __rpte_to_hidx(r,index)	((pte_val((r).pte) & _PAGE_COMBO) ? \
         (((r).hidx >> ((index)<<2)) & 0xf) : ((pte_val((r).pte) >> 12) & 0xf))
 #define __rpte_to_pte(r)	((r).pte)

^ permalink raw reply

* Re: [OOPS] hugetlbfs tests with 2.6.30-rc8-git1
From: Benjamin Herrenschmidt @ 2009-06-16  1:30 UTC (permalink / raw)
  To: Sachin Sant; +Cc: Mel Gorman, linuxppc-dev
In-Reply-To: <4A3645EE.5060103@in.ibm.com>

On Mon, 2009-06-15 at 18:30 +0530, Sachin Sant wrote:

>  278:   2f 80 00 00     cmpwi   cr7,r0,0
>         } else {
>                 vsid = get_kernel_vsid(addr, mmu_kernel_ssize);
>                 ssize = mmu_kernel_ssize;
>         }
>         vaddr = hpt_va(addr, vsid, ssize);
>         rpte = __real_pte(__pte(pte), ptep);
>  27c:   eb 89 80 00     ld      r28,-32768(r9)  

I think I know what the problem is. I'll send a tentative patch as soon
as I got to test it a bit here.

Cheers,
Ben.

^ permalink raw reply

* Re: [OOPS] hugetlbfs tests with 2.6.30-rc8-git1
From: Benjamin Herrenschmidt @ 2009-06-15 21:26 UTC (permalink / raw)
  To: Sachin Sant; +Cc: Mel Gorman, linuxppc-dev
In-Reply-To: <4A3645EE.5060103@in.ibm.com>

On Mon, 2009-06-15 at 18:30 +0530, Sachin Sant wrote:

> The corresponding C code is :
> 
>  278:   2f 80 00 00     cmpwi   cr7,r0,0
>         } else {
>                 vsid = get_kernel_vsid(addr, mmu_kernel_ssize);
>                 ssize = mmu_kernel_ssize;
>         }
>         vaddr = hpt_va(addr, vsid, ssize);
>         rpte = __real_pte(__pte(pte), ptep);

That's interesting... __real_pte() is used to reconstruct
a PTE two halves but maybe our huge pages page tables don't have
the second half ! In which case we are just going to peek into
la-la-land. I'm also worried by the negative offset since the second
halves are at +0x8000 iirc, unless it flipped the pointers around but
that would be strange....

I'll have a look later today.

Cheers,
Ben.

>  27c:   eb 89 80 00     ld      r28,-32768(r9)  
> ^^^^ %pc points to the above line. ^^^^^
>          * Check if we have an active batch on this CPU. If not, just
>          * flush now and return. For now, we don global invalidates
>          * in that case, might be worth testing the mm cpu mask though
>          * and decide to use local invalidates instead...
> 
> I have attached the objdump o/p for tlb_hash64.o.
> 
> I could not recreate this issue with git8 kernel
> (45e3e1935e2857c54783291107d33323b3ef33c8).
> 
> Thanks
> -Sachin
> 
> plain text document attachment (tlb_hash64_objlist)
> arch/powerpc/mm/tlb_hash64.o:     file format elf64-powerpc
> 
> 
> Disassembly of section .text:
> 
> 0000000000000000 <.__flush_tlb_pending>:
>  * in a batch.
>  *
>  * Must be called from within some kind of spinlock/non-preempt region...
>  */
> void __flush_tlb_pending(struct ppc64_tlb_batch *batch)
> {
>    0:	fb e1 ff f8 	std     r31,-8(r1)
>    4:	7c 08 02 a6 	mflr    r0
>    8:	f8 01 00 10 	std     r0,16(r1)
> extern const unsigned long
> 	cpu_bit_bitmap[BITS_PER_LONG+1][BITS_TO_LONGS(NR_CPUS)];
> 
> static inline const struct cpumask *get_cpu_mask(unsigned int cpu)
> {
> 	const unsigned long *p = cpu_bit_bitmap[1 + cpu % BITS_PER_LONG];
>    c:	e8 02 00 00 	ld      r0,0(r2)
>   10:	7c 7f 1b 78 	mr      r31,r3
>   14:	fb c1 ff f0 	std     r30,-16(r1)
> 			const unsigned long *src2, int nbits)
> {
> 	if (small_const_nbits(nbits))
> 		return ! ((*src1 ^ *src2) & BITMAP_LAST_WORD_MASK(nbits));
> 	else
> 		return __bitmap_equal(src1, src2, nbits);
>   18:	38 a0 04 00 	li      r5,1024
>   1c:	f8 21 ff 81 	stdu    r1,-128(r1)
> 	const struct cpumask *tmp;
> 	int i, local = 0;
> 
> 	i = batch->index;
> 	tmp = cpumask_of(smp_processor_id());
>   20:	a0 8d 00 0a 	lhz     r4,10(r13)
>   24:	e8 63 00 10 	ld      r3,16(r3)
>   28:	78 89 06 a0 	clrldi  r9,r4,58
>   2c:	78 84 d1 82 	rldicl  r4,r4,58,6
>   30:	39 29 00 01 	addi    r9,r9,1
>   34:	78 84 1f 24 	rldicr  r4,r4,3,60
>   38:	79 29 3e 24 	rldicr  r9,r9,7,56
>   3c:	38 63 03 10 	addi    r3,r3,784
>   40:	7c 00 4a 14 	add     r0,r0,r9
> void __flush_tlb_pending(struct ppc64_tlb_batch *batch)
> {
> 	const struct cpumask *tmp;
> 	int i, local = 0;
> 
> 	i = batch->index;
>   44:	eb df 00 0e 	lwa     r30,12(r31)
>   48:	7c 84 00 50 	subf    r4,r4,r0
>   4c:	48 00 00 01 	bl      4c <.__flush_tlb_pending+0x4c>
>   50:	60 00 00 00 	nop
>   54:	7c 69 fe 70 	srawi   r9,r3,31
> 	tmp = cpumask_of(smp_processor_id());
> 	if (cpumask_equal(mm_cpumask(batch->mm), tmp))
> 		local = 1;
> 	if (i == 1)
>   58:	2f 9e 00 01 	cmpwi   cr7,r30,1
>   5c:	7d 20 1a 78 	xor     r0,r9,r3
>   60:	7c 00 48 50 	subf    r0,r0,r9
>   64:	54 00 0f fe 	rlwinm  r0,r0,1,31,31
>   68:	7c 04 07 b4 	extsw   r4,r0
>   6c:	40 9e 00 28 	bne-    cr7,94 <.__flush_tlb_pending+0x94>
> 		flush_hash_page(batch->vaddr[0], batch->pte[0],
>   70:	7c 88 23 78 	mr      r8,r4
>   74:	e8 7f 0c 18 	ld      r3,3096(r31)
>   78:	e8 df 12 1a 	lwa     r6,4632(r31)
>   7c:	e8 ff 12 1e 	lwa     r7,4636(r31)
>   80:	e8 9f 00 18 	ld      r4,24(r31)
>   84:	e8 bf 00 20 	ld      r5,32(r31)
>   88:	48 00 00 01 	bl      88 <.__flush_tlb_pending+0x88>
>   8c:	60 00 00 00 	nop
>   90:	48 00 00 10 	b       a0 <.__flush_tlb_pending+0xa0>
> 				batch->psize, batch->ssize, local);
> 	else
> 		flush_hash_range(i, local);
>   94:	7f c3 f3 78 	mr      r3,r30
>   98:	48 00 00 01 	bl      98 <.__flush_tlb_pending+0x98>
>   9c:	60 00 00 00 	nop
> 	batch->index = 0;
> }
>   a0:	38 21 00 80 	addi    r1,r1,128
> 	if (i == 1)
> 		flush_hash_page(batch->vaddr[0], batch->pte[0],
> 				batch->psize, batch->ssize, local);
> 	else
> 		flush_hash_range(i, local);
> 	batch->index = 0;
>   a4:	38 00 00 00 	li      r0,0
>   a8:	f8 1f 00 08 	std     r0,8(r31)
> }
>   ac:	e8 01 00 10 	ld      r0,16(r1)
>   b0:	eb c1 ff f0 	ld      r30,-16(r1)
>   b4:	7c 08 03 a6 	mtlr    r0
>   b8:	eb e1 ff f8 	ld      r31,-8(r1)
>   bc:	4e 80 00 20 	blr
> 
> 00000000000000c0 <.hpte_need_flush>:
>  *
>  * Must be called from within some kind of spinlock/non-preempt region...
>  */
> void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
> 		     pte_t *ptep, unsigned long pte, int huge)
> {
>   c0:	fa c1 ff b0 	std     r22,-80(r1)
>   c4:	7c 08 02 a6 	mflr    r0
>   c8:	f8 01 00 10 	std     r0,16(r1)
> 	 * NOTE: when using special 64K mappings in 4K environment like
> 	 * for SPEs, we obtain the page size from the slice, which thus
> 	 * must still exist (and thus the VMA not reused) at the time
> 	 * of this call
> 	 */
> 	if (huge) {
>   cc:	2f a7 00 00 	cmpdi   cr7,r7,0
>  *
>  * Must be called from within some kind of spinlock/non-preempt region...
>  */
> void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
> 		     pte_t *ptep, unsigned long pte, int huge)
> {
>   d0:	fb 21 ff c8 	std     r25,-56(r1)
> #else
> 		BUG();
> 		psize = pte_pagesize_index(mm, addr, pte); /* shutup gcc */
> #endif
> 	} else
> 		psize = pte_pagesize_index(mm, addr, pte);
>   d4:	6c c0 10 00 	xoris   r0,r6,4096
>  *
>  * Must be called from within some kind of spinlock/non-preempt region...
>  */
> void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
> 		     pte_t *ptep, unsigned long pte, int huge)
> {
>   d8:	fb 41 ff d0 	std     r26,-48(r1)
>   dc:	7c d9 33 78 	mr      r25,r6
>   e0:	fb 61 ff d8 	std     r27,-40(r1)
>   e4:	7c b6 2b 78 	mr      r22,r5
>   e8:	fb 81 ff e0 	std     r28,-32(r1)
> 	struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
>   ec:	eb 82 00 08 	ld      r28,8(r2)
>  *
>  * Must be called from within some kind of spinlock/non-preempt region...
>  */
> void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
> 		     pte_t *ptep, unsigned long pte, int huge)
> {
>   f0:	fb c1 ff f0 	std     r30,-16(r1)
> #else
> 		BUG();
> 		psize = pte_pagesize_index(mm, addr, pte); /* shutup gcc */
> #endif
> 	} else
> 		psize = pte_pagesize_index(mm, addr, pte);
>   f4:	78 1b 27 e2 	rldicl  r27,r0,36,63
>  *
>  * Must be called from within some kind of spinlock/non-preempt region...
>  */
> void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
> 		     pte_t *ptep, unsigned long pte, int huge)
> {
>   f8:	fb e1 ff f8 	std     r31,-8(r1)
>   fc:	7c 7a 1b 78 	mr      r26,r3
>  100:	fa e1 ff b8 	std     r23,-72(r1)
> 	i = batch->index;
> 
> 	/* We mask the address for the base page size. Huge pages will
> 	 * have applied their own masking already
> 	 */
> 	addr &= PAGE_MASK;
>  104:	78 9f 03 e4 	rldicr  r31,r4,0,47
>  *
>  * Must be called from within some kind of spinlock/non-preempt region...
>  */
> void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
> 		     pte_t *ptep, unsigned long pte, int huge)
> {
>  108:	fb 01 ff c0 	std     r24,-64(r1)
>  10c:	fb a1 ff e8 	std     r29,-24(r1)
>  110:	f8 21 ff 41 	stdu    r1,-192(r1)
> 	struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
>  114:	ea ed 00 40 	ld      r23,64(r13)
>  118:	7f dc ba 14 	add     r30,r28,r23
> 	unsigned int psize;
> 	int ssize;
> 	real_pte_t rpte;
> 	int i;
> 
> 	i = batch->index;
>  11c:	eb 1e 00 08 	ld      r24,8(r30)
> 	 * NOTE: when using special 64K mappings in 4K environment like
> 	 * for SPEs, we obtain the page size from the slice, which thus
> 	 * must still exist (and thus the VMA not reused) at the time
> 	 * of this call
> 	 */
> 	if (huge) {
>  120:	41 9e 00 14 	beq-    cr7,134 <.hpte_need_flush+0x74>
> #ifdef CONFIG_HUGETLB_PAGE
> 		psize = get_slice_psize(mm, addr);;
>  124:	7f e4 fb 78 	mr      r4,r31
>  128:	48 00 00 01 	bl      128 <.hpte_need_flush+0x68>
>  12c:	60 00 00 00 	nop
>  130:	7c 7b 1b 78 	mr      r27,r3
> #endif
> 	} else
> 		psize = pte_pagesize_index(mm, addr, pte);
> 
> 	/* Build full vaddr */
> 	if (!is_kernel_addr(addr)) {
>  134:	e8 02 00 10 	ld      r0,16(r2)
>  138:	7f bf 00 40 	cmpld   cr7,r31,r0
>  13c:	41 9d 00 a8 	bgt-    cr7,1e4 <.hpte_need_flush+0x124>
> 
> /* Returns the segment size indicator for a user address */
> static inline int user_segment_size(unsigned long addr)
> {
> 	/* Use 1T segments if possible for addresses >= 1T */
> 	if (addr >= (1UL << SID_SHIFT_1T))
>  140:	38 00 ff ff 	li      r0,-1
>  144:	3b a0 00 00 	li      r29,0
>  148:	78 00 06 00 	clrldi  r0,r0,24
>  14c:	7f bf 00 40 	cmpld   cr7,r31,r0
>  150:	40 9d 00 0c 	ble-    cr7,15c <.hpte_need_flush+0x9c>
> 		return mmu_highuser_ssize;
>  154:	e9 22 00 18 	ld      r9,24(r2)
>  158:	eb a9 00 02 	lwa     r29,0(r9)
> 
> /* This is only valid for user addresses (which are below 2^44) */
> static inline unsigned long get_vsid(unsigned long context, unsigned long ea,
> 				     int ssize)
> {
> 	if (ssize == MMU_SEGSIZE_256M)
>  15c:	2f bd 00 00 	cmpdi   cr7,r29,0
> 		ssize = user_segment_size(addr);
> 		vsid = get_vsid(mm->context.id, addr, ssize);
>  160:	e9 7a 03 90 	ld      r11,912(r26)
>  164:	40 9e 00 3c 	bne-    cr7,1a0 <.hpte_need_flush+0xe0>
> 		return vsid_scramble((context << USER_ESID_BITS)
>  168:	79 6b 83 e4 	rldicr  r11,r11,16,47
>  16c:	7b e0 27 02 	rldicl  r0,r31,36,28
>  170:	3d 20 0b f6 	lis     r9,3062
>  174:	7c 00 5b 78 	or      r0,r0,r11
>  178:	61 29 e6 1b 	ori     r9,r9,58907
>  17c:	7c 00 49 d2 	mulld   r0,r0,r9
> 				     | (ea >> SID_SHIFT), 256M);
>  180:	78 09 07 00 	clrldi  r9,r0,28
>  184:	78 00 e1 20 	rldicl  r0,r0,28,36
>  188:	7d 29 02 14 	add     r9,r9,r0
>  18c:	38 09 00 01 	addi    r0,r9,1
>  190:	78 00 e1 20 	rldicl  r0,r0,28,36
>  194:	7c 00 4a 14 	add     r0,r0,r9
>  198:	78 09 07 00 	clrldi  r9,r0,28
>  19c:	48 00 00 38 	b       1d4 <.hpte_need_flush+0x114>
> 	return vsid_scramble((context << USER_ESID_BITS_1T)
>  1a0:	79 6b 26 e4 	rldicr  r11,r11,4,59
>  1a4:	7b e0 c2 20 	rldicl  r0,r31,24,40
>  1a8:	3d 20 00 bf 	lis     r9,191
>  1ac:	7c 00 5b 78 	or      r0,r0,r11
>  1b0:	61 29 50 d9 	ori     r9,r9,20697
>  1b4:	7c 00 49 d2 	mulld   r0,r0,r9
> 			     | (ea >> SID_SHIFT_1T), 1T);
>  1b8:	78 09 02 20 	clrldi  r9,r0,40
>  1bc:	78 00 46 02 	rldicl  r0,r0,40,24
>  1c0:	7d 29 02 14 	add     r9,r9,r0
>  1c4:	38 09 00 01 	addi    r0,r9,1
>  1c8:	78 00 46 02 	rldicl  r0,r0,40,24
>  1cc:	7c 00 4a 14 	add     r0,r0,r9
>  1d0:	78 09 02 20 	clrldi  r9,r0,40
> 		WARN_ON(vsid == 0);
>  1d4:	7d 20 00 74 	cntlzd  r0,r9
>  1d8:	78 00 d1 82 	rldicl  r0,r0,58,6
>  1dc:	0b 00 00 00 	tdnei   r0,0
>  1e0:	48 00 00 70 	b       250 <.hpte_need_flush+0x190>
> 	} else {
> 		vsid = get_kernel_vsid(addr, mmu_kernel_ssize);
>  1e4:	e9 22 00 20 	ld      r9,32(r2)
>  1e8:	eb a9 00 02 	lwa     r29,0(r9)
> #endif /* 1 */
> 
> /* This is only valid for addresses >= PAGE_OFFSET */
> static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize)
> {
> 	if (ssize == MMU_SEGSIZE_256M)
>  1ec:	2f bd 00 00 	cmpdi   cr7,r29,0
>  1f0:	40 9e 00 34 	bne-    cr7,224 <.hpte_need_flush+0x164>
> 		return vsid_scramble(ea >> SID_SHIFT, 256M);
>  1f4:	3d 20 0b f6 	lis     r9,3062
>  1f8:	7b e0 27 02 	rldicl  r0,r31,36,28
>  1fc:	61 29 e6 1b 	ori     r9,r9,58907
>  200:	7c 00 49 d2 	mulld   r0,r0,r9
>  204:	78 09 07 00 	clrldi  r9,r0,28
>  208:	78 00 e1 20 	rldicl  r0,r0,28,36
>  20c:	7d 29 02 14 	add     r9,r9,r0
>  210:	38 09 00 01 	addi    r0,r9,1
>  214:	78 00 e1 20 	rldicl  r0,r0,28,36
>  218:	7c 00 4a 14 	add     r0,r0,r9
>  21c:	78 09 07 00 	clrldi  r9,r0,28
>  220:	48 00 00 38 	b       258 <.hpte_need_flush+0x198>
> 	return vsid_scramble(ea >> SID_SHIFT_1T, 1T);
>  224:	3d 20 00 bf 	lis     r9,191
>  228:	7b e0 c2 20 	rldicl  r0,r31,24,40
>  22c:	61 29 50 d9 	ori     r9,r9,20697
>  230:	7c 00 49 d2 	mulld   r0,r0,r9
>  234:	78 09 02 20 	clrldi  r9,r0,40
>  238:	78 00 46 02 	rldicl  r0,r0,40,24
>  23c:	7d 29 02 14 	add     r9,r9,r0
>  240:	38 09 00 01 	addi    r0,r9,1
>  244:	78 00 46 02 	rldicl  r0,r0,40,24
>  248:	7c 00 4a 14 	add     r0,r0,r9
>  24c:	78 09 02 20 	clrldi  r9,r0,40
>  * Build a VA given VSID, EA and segment size
>  */
> static inline unsigned long hpt_va(unsigned long ea, unsigned long vsid,
> 				   int ssize)
> {
> 	if (ssize == MMU_SEGSIZE_256M)
>  250:	2f bd 00 00 	cmpdi   cr7,r29,0
>  254:	40 9e 00 10 	bne-    cr7,264 <.hpte_need_flush+0x1a4>
> 		return (vsid << 28) | (ea & 0xfffffffUL);
>  258:	79 29 e0 e4 	rldicr  r9,r9,28,35
>  25c:	7b e0 01 20 	clrldi  r0,r31,36
>  260:	48 00 00 0c 	b       26c <.hpte_need_flush+0x1ac>
> 	return (vsid << 40) | (ea & 0xffffffffffUL);
>  264:	79 29 45 c6 	rldicr  r9,r9,40,23
>  268:	7b e0 06 00 	clrldi  r0,r31,24
>  26c:	7d 3f 03 78 	or      r31,r9,r0
> 	 * Check if we have an active batch on this CPU. If not, just
> 	 * flush now and return. For now, we don global invalidates
> 	 * in that case, might be worth testing the mm cpu mask though
> 	 * and decide to use local invalidates instead...
> 	 */
> 	if (!batch->active) {
>  270:	7c 1c b8 2e 	lwzx    r0,r28,r23
> 	} else {
> 		vsid = get_kernel_vsid(addr, mmu_kernel_ssize);
> 		ssize = mmu_kernel_ssize;
> 	}
> 	vaddr = hpt_va(addr, vsid, ssize);
> 	rpte = __real_pte(__pte(pte), ptep);
>  274:	3d 36 00 01 	addis   r9,r22,1
> 	 * Check if we have an active batch on this CPU. If not, just
> 	 * flush now and return. For now, we don global invalidates
> 	 * in that case, might be worth testing the mm cpu mask though
> 	 * and decide to use local invalidates instead...
> 	 */
> 	if (!batch->active) {
>  278:	2f 80 00 00 	cmpwi   cr7,r0,0
> 	} else {
> 		vsid = get_kernel_vsid(addr, mmu_kernel_ssize);
> 		ssize = mmu_kernel_ssize;
> 	}
> 	vaddr = hpt_va(addr, vsid, ssize);
> 	rpte = __real_pte(__pte(pte), ptep);
>  27c:	eb 89 80 00 	ld      r28,-32768(r9)
> 	 * Check if we have an active batch on this CPU. If not, just
> 	 * flush now and return. For now, we don global invalidates
> 	 * in that case, might be worth testing the mm cpu mask though
> 	 * and decide to use local invalidates instead...
> 	 */
> 	if (!batch->active) {
>  280:	40 9e 00 28 	bne-    cr7,2a8 <.hpte_need_flush+0x1e8>
> 		flush_hash_page(vaddr, rpte, psize, ssize, 0);
>  284:	7f e3 fb 78 	mr      r3,r31
>  288:	7f 24 cb 78 	mr      r4,r25
>  28c:	7f 85 e3 78 	mr      r5,r28
>  290:	7f 66 07 b4 	extsw   r6,r27
>  294:	7f a7 eb 78 	mr      r7,r29
>  298:	39 00 00 00 	li      r8,0
>  29c:	48 00 00 01 	bl      29c <.hpte_need_flush+0x1dc>
>  2a0:	60 00 00 00 	nop
>  2a4:	48 00 00 bc 	b       360 <.hpte_need_flush+0x2a0>
> 	 * will change mid stream.
> 	 *
> 	 * We also need to ensure only one page size is present in a given
> 	 * batch
> 	 */
> 	if (i != 0 && (mm != batch->mm || batch->psize != psize ||
>  2a8:	7f 0b 07 b5 	extsw.  r11,r24
>  2ac:	41 82 00 30 	beq-    2dc <.hpte_need_flush+0x21c>
>  2b0:	e8 1e 00 10 	ld      r0,16(r30)
>  2b4:	7f ba 00 00 	cmpd    cr7,r26,r0
>  2b8:	40 9e 00 1c 	bne-    cr7,2d4 <.hpte_need_flush+0x214>
>  2bc:	80 1e 12 18 	lwz     r0,4632(r30)
>  2c0:	7f 80 d8 00 	cmpw    cr7,r0,r27
>  2c4:	40 9e 00 10 	bne-    cr7,2d4 <.hpte_need_flush+0x214>
>  2c8:	80 1e 12 1c 	lwz     r0,4636(r30)
>  2cc:	7f 80 e8 00 	cmpw    cr7,r0,r29
>  2d0:	41 9e 00 1c 	beq-    cr7,2ec <.hpte_need_flush+0x22c>
> 		       batch->ssize != ssize)) {
> 		__flush_tlb_pending(batch);
>  2d4:	7f c3 f3 78 	mr      r3,r30
>  2d8:	48 00 00 01 	bl      2d8 <.hpte_need_flush+0x218>
> 		i = 0;
> 	}
> 	if (i == 0) {
> 		batch->mm = mm;
> 		batch->psize = psize;
> 		batch->ssize = ssize;
>  2dc:	39 60 00 00 	li      r11,0
> 		       batch->ssize != ssize)) {
> 		__flush_tlb_pending(batch);
> 		i = 0;
> 	}
> 	if (i == 0) {
> 		batch->mm = mm;
>  2e0:	fb 5e 00 10 	std     r26,16(r30)
> 		batch->psize = psize;
>  2e4:	93 7e 12 18 	stw     r27,4632(r30)
> 		batch->ssize = ssize;
>  2e8:	93 be 12 1c 	stw     r29,4636(r30)
> 	}
> 	batch->pte[i] = rpte;
> 	batch->vaddr[i] = vaddr;
> 	batch->index = ++i;
>  2ec:	38 0b 00 01 	addi    r0,r11,1
> 	if (i == 0) {
> 		batch->mm = mm;
> 		batch->psize = psize;
> 		batch->ssize = ssize;
> 	}
> 	batch->pte[i] = rpte;
>  2f0:	39 2b 00 01 	addi    r9,r11,1
> 	batch->vaddr[i] = vaddr;
>  2f4:	39 6b 01 82 	addi    r11,r11,386
> 	batch->index = ++i;
>  2f8:	7c 00 07 b4 	extsw   r0,r0
> 	if (i == 0) {
> 		batch->mm = mm;
> 		batch->psize = psize;
> 		batch->ssize = ssize;
> 	}
> 	batch->pte[i] = rpte;
>  2fc:	79 29 26 e4 	rldicr  r9,r9,4,59
> 	batch->vaddr[i] = vaddr;
>  300:	79 6b 1f 24 	rldicr  r11,r11,3,60
> 	if (i == 0) {
> 		batch->mm = mm;
> 		batch->psize = psize;
> 		batch->ssize = ssize;
> 	}
> 	batch->pte[i] = rpte;
>  304:	7d 3e 4a 14 	add     r9,r30,r9
> 	batch->vaddr[i] = vaddr;
>  308:	7d 7e 5a 14 	add     r11,r30,r11
> 	if (i == 0) {
> 		batch->mm = mm;
> 		batch->psize = psize;
> 		batch->ssize = ssize;
> 	}
> 	batch->pte[i] = rpte;
>  30c:	fb 29 00 08 	std     r25,8(r9)
> 	batch->vaddr[i] = vaddr;
> 	batch->index = ++i;
> 	if (i >= PPC64_TLB_BATCH_NR)
>  310:	2f 80 00 bf 	cmpwi   cr7,r0,191
> 	if (i == 0) {
> 		batch->mm = mm;
> 		batch->psize = psize;
> 		batch->ssize = ssize;
> 	}
> 	batch->pte[i] = rpte;
>  314:	fb 89 00 10 	std     r28,16(r9)
> 	batch->vaddr[i] = vaddr;
>  318:	fb eb 00 08 	std     r31,8(r11)
> 	batch->index = ++i;
>  31c:	f8 1e 00 08 	std     r0,8(r30)
> 	if (i >= PPC64_TLB_BATCH_NR)
>  320:	40 9d 00 40 	ble-    cr7,360 <.hpte_need_flush+0x2a0>
> 		__flush_tlb_pending(batch);
> }
>  324:	38 21 00 c0 	addi    r1,r1,192
> 	}
> 	batch->pte[i] = rpte;
> 	batch->vaddr[i] = vaddr;
> 	batch->index = ++i;
> 	if (i >= PPC64_TLB_BATCH_NR)
> 		__flush_tlb_pending(batch);
>  328:	7f c3 f3 78 	mr      r3,r30
> }
>  32c:	e8 01 00 10 	ld      r0,16(r1)
>  330:	ea c1 ff b0 	ld      r22,-80(r1)
>  334:	7c 08 03 a6 	mtlr    r0
>  338:	ea e1 ff b8 	ld      r23,-72(r1)
>  33c:	eb 01 ff c0 	ld      r24,-64(r1)
>  340:	eb 21 ff c8 	ld      r25,-56(r1)
>  344:	eb 41 ff d0 	ld      r26,-48(r1)
>  348:	eb 61 ff d8 	ld      r27,-40(r1)
>  34c:	eb 81 ff e0 	ld      r28,-32(r1)
>  350:	eb a1 ff e8 	ld      r29,-24(r1)
>  354:	eb c1 ff f0 	ld      r30,-16(r1)
>  358:	eb e1 ff f8 	ld      r31,-8(r1)
> 	}
> 	batch->pte[i] = rpte;
> 	batch->vaddr[i] = vaddr;
> 	batch->index = ++i;
> 	if (i >= PPC64_TLB_BATCH_NR)
> 		__flush_tlb_pending(batch);
>  35c:	48 00 00 00 	b       35c <.hpte_need_flush+0x29c>
> }
>  360:	38 21 00 c0 	addi    r1,r1,192
>  364:	e8 01 00 10 	ld      r0,16(r1)
>  368:	ea c1 ff b0 	ld      r22,-80(r1)
>  36c:	7c 08 03 a6 	mtlr    r0
>  370:	ea e1 ff b8 	ld      r23,-72(r1)
>  374:	eb 01 ff c0 	ld      r24,-64(r1)
>  378:	eb 21 ff c8 	ld      r25,-56(r1)
>  37c:	eb 41 ff d0 	ld      r26,-48(r1)
>  380:	eb 61 ff d8 	ld      r27,-40(r1)
>  384:	eb 81 ff e0 	ld      r28,-32(r1)
>  388:	eb a1 ff e8 	ld      r29,-24(r1)
>  38c:	eb c1 ff f0 	ld      r30,-16(r1)
>  390:	eb e1 ff f8 	ld      r31,-8(r1)
>  394:	4e 80 00 20 	blr
> 
> 0000000000000398 <.__flush_hash_table_range>:
>  */
> #ifdef CONFIG_HOTPLUG
> 
> void __flush_hash_table_range(struct mm_struct *mm, unsigned long start,
> 			      unsigned long end)
> {
>  398:	fb 81 ff e0 	std     r28,-32(r1)
>  39c:	7c 08 02 a6 	mflr    r0
>  3a0:	fb c1 ff f0 	std     r30,-16(r1)
> 	unsigned long flags;
> 
> 	start = _ALIGN_DOWN(start, PAGE_SIZE);
> 	end = _ALIGN_UP(end, PAGE_SIZE);
>  3a4:	3c a5 00 01 	addis   r5,r5,1
>  */
> #ifdef CONFIG_HOTPLUG
> 
> void __flush_hash_table_range(struct mm_struct *mm, unsigned long start,
> 			      unsigned long end)
> {
>  3a8:	f8 01 00 10 	std     r0,16(r1)
>  3ac:	7c 7e 1b 78 	mr      r30,r3
>  3b0:	fb a1 ff e8 	std     r29,-24(r1)
> 	unsigned long flags;
> 
> 	start = _ALIGN_DOWN(start, PAGE_SIZE);
> 	end = _ALIGN_UP(end, PAGE_SIZE);
>  3b4:	38 a5 ff ff 	addi    r5,r5,-1
>  */
> #ifdef CONFIG_HOTPLUG
> 
> void __flush_hash_table_range(struct mm_struct *mm, unsigned long start,
> 			      unsigned long end)
> {
>  3b8:	fb e1 ff f8 	std     r31,-8(r1)
>  3bc:	f8 21 ff 71 	stdu    r1,-144(r1)
> 	unsigned long flags;
> 
> 	start = _ALIGN_DOWN(start, PAGE_SIZE);
> 	end = _ALIGN_UP(end, PAGE_SIZE);
>  3c0:	78 bc 03 e4 	rldicr  r28,r5,0,47
> 
> 	BUG_ON(!mm->pgd);
>  3c4:	e8 03 00 48 	ld      r0,72(r3)
>  3c8:	7c 00 00 74 	cntlzd  r0,r0
>  3cc:	78 00 d1 82 	rldicl  r0,r0,58,6
>  3d0:	0b 00 00 00 	tdnei   r0,0
> void __flush_hash_table_range(struct mm_struct *mm, unsigned long start,
> 			      unsigned long end)
> {
> 	unsigned long flags;
> 
> 	start = _ALIGN_DOWN(start, PAGE_SIZE);
>  3d4:	78 9f 03 e4 	rldicr  r31,r4,0,47
> 
> static inline unsigned long raw_local_irq_disable(void)
> {
> 	unsigned long flags, zero;
> 
> 	__asm__ __volatile__("li %1,0; lbz %0,%2(13); stb %1,%2(13)"
>  3d8:	38 00 00 00 	li      r0,0
>  3dc:	8b ad 01 da 	lbz     r29,474(r13)
>  3e0:	98 0d 01 da 	stb     r0,474(r13)
> 
> static inline void arch_enter_lazy_mmu_mode(void)
> {
> 	struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
> 
> 	batch->active = 1;
>  3e4:	38 00 00 01 	li      r0,1
>  3e8:	e9 6d 00 40 	ld      r11,64(r13)
> 
> #define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
> 
> static inline void arch_enter_lazy_mmu_mode(void)
> {
> 	struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
>  3ec:	e9 22 00 08 	ld      r9,8(r2)
> 
> 	batch->active = 1;
>  3f0:	7c 09 59 2e 	stwx    r0,r9,r11
>  3f4:	48 00 00 58 	b       44c <.__flush_hash_table_range+0xb4>
> 	pte_t *pt = NULL;
> 
> 	pg = pgdir + pgd_index(ea);
> 	if (!pgd_none(*pg)) {
> 		pu = pud_offset(pg, ea);
> 		if (!pud_none(*pu)) {
>  3f8:	e9 3e 00 48 	ld      r9,72(r30)
>  3fc:	7c 09 00 2a 	ldx     r0,r9,r0
>  400:	2f a0 00 00 	cmpdi   cr7,r0,0
> 			pm = pmd_offset(pu, ea);
> 			if (pmd_present(*pm))
>  404:	78 09 05 a4 	rldicr  r9,r0,0,54
> 	pte_t *pt = NULL;
> 
> 	pg = pgdir + pgd_index(ea);
> 	if (!pgd_none(*pg)) {
> 		pu = pud_offset(pg, ea);
> 		if (!pud_none(*pu)) {
>  408:	41 9e 00 40 	beq-    cr7,448 <.__flush_hash_table_range+0xb0>
> 			pm = pmd_offset(pu, ea);
> 			if (pmd_present(*pm))
>  40c:	7d 2b 48 2a 	ldx     r9,r11,r9
> 				pt = pte_offset_kernel(pm, ea);
>  410:	7b e0 85 22 	rldicl  r0,r31,48,52
> 	pg = pgdir + pgd_index(ea);
> 	if (!pgd_none(*pg)) {
> 		pu = pud_offset(pg, ea);
> 		if (!pud_none(*pu)) {
> 			pm = pmd_offset(pu, ea);
> 			if (pmd_present(*pm))
>  414:	2f a9 00 00 	cmpdi   cr7,r9,0
> 				pt = pte_offset_kernel(pm, ea);
>  418:	78 0b 1f 24 	rldicr  r11,r0,3,60
>  41c:	79 26 05 a4 	rldicr  r6,r9,0,54
> 	arch_enter_lazy_mmu_mode();
> 	for (; start < end; start += PAGE_SIZE) {
> 		pte_t *ptep = find_linux_pte(mm->pgd, start);
> 		unsigned long pte;
> 
> 		if (ptep == NULL)
>  420:	7c a6 5a 15 	add.    r5,r6,r11
> 	pg = pgdir + pgd_index(ea);
> 	if (!pgd_none(*pg)) {
> 		pu = pud_offset(pg, ea);
> 		if (!pud_none(*pu)) {
> 			pm = pmd_offset(pu, ea);
> 			if (pmd_present(*pm))
>  424:	41 9e 00 24 	beq-    cr7,448 <.__flush_hash_table_range+0xb0>
>  428:	41 c2 00 20 	beq-    448 <.__flush_hash_table_range+0xb0>
> 			continue;
> 		pte = pte_val(*ptep);
>  42c:	7c c6 58 2a 	ldx     r6,r6,r11
> 		if (!(pte & _PAGE_HASHPTE))
>  430:	54 c0 01 27 	rlwinm. r0,r6,0,4,19
>  434:	41 82 00 14 	beq-    448 <.__flush_hash_table_range+0xb0>
> 			continue;
> 		hpte_need_flush(mm, start, ptep, pte, 0);
>  438:	7f e4 fb 78 	mr      r4,r31
>  43c:	7f c3 f3 78 	mr      r3,r30
>  440:	38 e0 00 00 	li      r7,0
>  444:	48 00 00 01 	bl      444 <.__flush_hash_table_range+0xac>
> 	 * to being hashed). This is not the most performance oriented
> 	 * way to do things but is fine for our needs here.
> 	 */
> 	local_irq_save(flags);
> 	arch_enter_lazy_mmu_mode();
> 	for (; start < end; start += PAGE_SIZE) {
>  448:	3f ff 00 01 	addis   r31,r31,1
>  44c:	7f bf e0 40 	cmpld   cr7,r31,r28
> 	pte_t *pt = NULL;
> 
> 	pg = pgdir + pgd_index(ea);
> 	if (!pgd_none(*pg)) {
> 		pu = pud_offset(pg, ea);
> 		if (!pud_none(*pu)) {
>  450:	7b e0 c5 e0 	rldicl  r0,r31,24,55
> 			pm = pmd_offset(pu, ea);
> 			if (pmd_present(*pm))
>  454:	7b e9 25 22 	rldicl  r9,r31,36,52
> 	pte_t *pt = NULL;
> 
> 	pg = pgdir + pgd_index(ea);
> 	if (!pgd_none(*pg)) {
> 		pu = pud_offset(pg, ea);
> 		if (!pud_none(*pu)) {
>  458:	78 00 1f 24 	rldicr  r0,r0,3,60
> 			pm = pmd_offset(pu, ea);
> 			if (pmd_present(*pm))
>  45c:	79 2b 1f 24 	rldicr  r11,r9,3,60
>  460:	41 9c ff 98 	blt+    cr7,3f8 <.__flush_hash_table_range+0x60>
> }
> 
> static inline void arch_leave_lazy_mmu_mode(void)
> {
> 	struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
>  464:	eb cd 00 40 	ld      r30,64(r13)
>  468:	eb e2 00 08 	ld      r31,8(r2)
>  46c:	7c 7f f2 14 	add     r3,r31,r30
> 
> 	if (batch->index)
>  470:	e8 03 00 08 	ld      r0,8(r3)
>  474:	2f a0 00 00 	cmpdi   cr7,r0,0
>  478:	41 9e 00 08 	beq-    cr7,480 <.__flush_hash_table_range+0xe8>
> 		__flush_tlb_pending(batch);
>  47c:	48 00 00 01 	bl      47c <.__flush_hash_table_range+0xe4>
> 		if (!(pte & _PAGE_HASHPTE))
> 			continue;
> 		hpte_need_flush(mm, start, ptep, pte, 0);
> 	}
> 	arch_leave_lazy_mmu_mode();
> 	local_irq_restore(flags);
>  480:	2f bd 00 00 	cmpdi   cr7,r29,0
> 	batch->active = 0;
>  484:	38 00 00 00 	li      r0,0
>  488:	38 60 00 00 	li      r3,0
>  48c:	7c 1f f1 2e 	stwx    r0,r31,r30
>  490:	41 9e 00 08 	beq-    cr7,498 <.__flush_hash_table_range+0x100>
>  494:	7f a3 eb 78 	mr      r3,r29
>  498:	48 00 00 01 	bl      498 <.__flush_hash_table_range+0x100>
>  49c:	60 00 00 00 	nop
> }
>  4a0:	38 21 00 90 	addi    r1,r1,144
>  4a4:	e8 01 00 10 	ld      r0,16(r1)
>  4a8:	eb 81 ff e0 	ld      r28,-32(r1)
>  4ac:	7c 08 03 a6 	mtlr    r0
>  4b0:	eb a1 ff e8 	ld      r29,-24(r1)
>  4b4:	eb c1 ff f0 	ld      r30,-16(r1)
>  4b8:	eb e1 ff f8 	ld      r31,-8(r1)
>  4bc:	4e 80 00 20 	blr

^ permalink raw reply

* Re: [PATCH] powerpc: Add configurable -Werror for arch/powerpc
From: Benjamin Herrenschmidt @ 2009-06-15 21:23 UTC (permalink / raw)
  To: michael; +Cc: linuxppc-dev list
In-Reply-To: <1245069362.8735.15.camel@concordia>


> Yeah that occured to me, someone with a chrp machine would need to test
> it, do we have one?

Yup, I think we do. I'll check that when I'm in the office.

> > We can have a closer look tomorrow. In any case, stack alloc for that is
> > indeed fishy.
> 
> The obvious patch to make it static doesn't fly because it's called on
> every cpu via a timer, so it needs to be a per-cpu at least I think. Or
> borrow the pseries trick of calling it on each cpu in succession, or
> just borrow the pseries code.

Right.

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH V2 2/2] mtd/maps/mtd-ram: add an of-platform driver
From: Albrecht Dreß @ 2009-06-15 17:43 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: linuxppc-dev, devicetree-discuss, linux-mtd, David Woodhouse,
	Ben Dooks
In-Reply-To: <1244203514-12516-3-git-send-email-w.sang@pengutronix.de>

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

Am 05.06.09 14:05 schrieb(en) Wolfram Sang:
> Create an of-aware driver using the now exported generic functions  
> from plat-ram.c. Also add the documentation for the binding.  
> Partitions are not yet supported. Tested on a phyCORE-MPC5200B-IO.

Dumb question: what is the current status of this patch?  I ask because  
I re-wrote my '5200 16-bit Local Plus Bus patch' according to Grant's  
suggestions, and I believe of_ram_probe() of your patch is the right  
place to check if it's attached to "fsl,mpc5200-lpb", and to change the  
write cb if the bankwidth equals 2.

Thanks, Albrecht.

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

^ permalink raw reply


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