linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/6] powerpc/powernv: Use uint64_t instead of size_t in OPAL APIs
@ 2014-04-22  5:01 Anton Blanchard
  2014-04-22  5:01 ` [PATCH 2/6] powerpc/powernv: Remove some OPAL function declaration duplication Anton Blanchard
                   ` (4 more replies)
  0 siblings, 5 replies; 12+ messages in thread
From: Anton Blanchard @ 2014-04-22  5:01 UTC (permalink / raw)
  To: benh, paulus, hegdevasant, stewart; +Cc: linuxppc-dev

Using size_t in our APIs is asking for trouble, especially
when some OPAL calls use size_t pointers.

Signed-off-by: Anton Blanchard <anton@samba.org>
Reviewed-by: Stewart Smith <stewart@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/opal.h            | 12 ++++++------
 arch/powerpc/platforms/powernv/opal-elog.c |  2 +-
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index a2efdaa..2a34485 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -858,8 +858,8 @@ int64_t opal_lpc_write(uint32_t chip_id, enum OpalLPCAddressType addr_type,
 int64_t opal_lpc_read(uint32_t chip_id, enum OpalLPCAddressType addr_type,
 		      uint32_t addr, __be32 *data, uint32_t sz);
 
-int64_t opal_read_elog(uint64_t buffer, size_t size, uint64_t log_id);
-int64_t opal_get_elog_size(uint64_t *log_id, size_t *size, uint64_t *elog_type);
+int64_t opal_read_elog(uint64_t buffer, uint64_t size, uint64_t log_id);
+int64_t opal_get_elog_size(uint64_t *log_id, uint64_t *size, uint64_t *elog_type);
 int64_t opal_write_elog(uint64_t buffer, uint64_t size, uint64_t offset);
 int64_t opal_send_ack_elog(uint64_t log_id);
 void opal_resend_pending_logs(void);
@@ -874,13 +874,13 @@ int64_t opal_dump_read(uint32_t dump_id, uint64_t buffer);
 int64_t opal_dump_ack(uint32_t dump_id);
 int64_t opal_dump_resend_notification(void);
 
-int64_t opal_get_msg(uint64_t buffer, size_t size);
-int64_t opal_check_completion(uint64_t buffer, size_t size, uint64_t token);
+int64_t opal_get_msg(uint64_t buffer, uint64_t size);
+int64_t opal_check_completion(uint64_t buffer, uint64_t size, uint64_t token);
 int64_t opal_sync_host_reboot(void);
 int64_t opal_get_param(uint64_t token, uint32_t param_id, uint64_t buffer,
-		size_t length);
+		uint64_t length);
 int64_t opal_set_param(uint64_t token, uint32_t param_id, uint64_t buffer,
-		size_t length);
+		uint64_t length);
 int64_t opal_sensor_read(uint32_t sensor_hndl, int token, __be32 *sensor_data);
 
 /* Internal functions */
diff --git a/arch/powerpc/platforms/powernv/opal-elog.c b/arch/powerpc/platforms/powernv/opal-elog.c
index ef7bc2a..7e3821e 100644
--- a/arch/powerpc/platforms/powernv/opal-elog.c
+++ b/arch/powerpc/platforms/powernv/opal-elog.c
@@ -238,7 +238,7 @@ static struct elog_obj *create_elog_obj(uint64_t id, size_t size, uint64_t type)
 
 static void elog_work_fn(struct work_struct *work)
 {
-	size_t elog_size;
+	uint64_t elog_size;
 	uint64_t log_id;
 	uint64_t elog_type;
 	int rc;
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/6] powerpc/powernv: Remove some OPAL function declaration duplication
  2014-04-22  5:01 [PATCH 1/6] powerpc/powernv: Use uint64_t instead of size_t in OPAL APIs Anton Blanchard
@ 2014-04-22  5:01 ` Anton Blanchard
  2014-04-22  5:01 ` [PATCH 3/6] powerpc/powernv: Fix little endian issues with opal_do_notifier calls Anton Blanchard
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 12+ messages in thread
From: Anton Blanchard @ 2014-04-22  5:01 UTC (permalink / raw)
  To: benh, paulus, hegdevasant, stewart; +Cc: linuxppc-dev

We had some duplication of the internal OPAL functions.

Signed-off-by: Anton Blanchard <anton@samba.org>
---
 arch/powerpc/include/asm/opal.h | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 2a34485..cb7d52e 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -884,7 +884,8 @@ int64_t opal_set_param(uint64_t token, uint32_t param_id, uint64_t buffer,
 int64_t opal_sensor_read(uint32_t sensor_hndl, int token, __be32 *sensor_data);
 
 /* Internal functions */
-extern int early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data);
+extern int early_init_dt_scan_opal(unsigned long node, const char *uname,
+				   int depth, void *data);
 extern int early_init_dt_scan_recoverable_ranges(unsigned long node,
 				 const char *uname, int depth, void *data);
 
@@ -893,10 +894,6 @@ extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len);
 
 extern void hvc_opal_init_early(void);
 
-/* Internal functions */
-extern int early_init_dt_scan_opal(unsigned long node, const char *uname,
-				   int depth, void *data);
-
 extern int opal_notifier_register(struct notifier_block *nb);
 extern int opal_notifier_unregister(struct notifier_block *nb);
 
@@ -906,9 +903,6 @@ extern void opal_notifier_enable(void);
 extern void opal_notifier_disable(void);
 extern void opal_notifier_update_evt(uint64_t evt_mask, uint64_t evt_val);
 
-extern int opal_get_chars(uint32_t vtermno, char *buf, int count);
-extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len);
-
 extern int __opal_async_get_token(void);
 extern int opal_async_get_token_interruptible(void);
 extern int __opal_async_release_token(int token);
@@ -916,8 +910,6 @@ extern int opal_async_release_token(int token);
 extern int opal_async_wait_response(uint64_t token, struct opal_msg *msg);
 extern int opal_get_sensor_data(u32 sensor_hndl, u32 *sensor_data);
 
-extern void hvc_opal_init_early(void);
-
 struct rtc_time;
 extern int opal_set_rtc_time(struct rtc_time *tm);
 extern void opal_get_rtc_time(struct rtc_time *tm);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/6] powerpc/powernv: Fix little endian issues with opal_do_notifier calls
  2014-04-22  5:01 [PATCH 1/6] powerpc/powernv: Use uint64_t instead of size_t in OPAL APIs Anton Blanchard
  2014-04-22  5:01 ` [PATCH 2/6] powerpc/powernv: Remove some OPAL function declaration duplication Anton Blanchard
@ 2014-04-22  5:01 ` Anton Blanchard
  2014-04-22  5:01 ` [PATCH 4/6] powerpc/powernv: Fix little endian issues in OPAL error log code Anton Blanchard
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 12+ messages in thread
From: Anton Blanchard @ 2014-04-22  5:01 UTC (permalink / raw)
  To: benh, paulus, hegdevasant, stewart; +Cc: linuxppc-dev

The bitmap in opal_poll_events and opal_handle_interrupt is
big endian, so we need to byteswap it on little endian builds.

Signed-off-by: Anton Blanchard <anton@samba.org>
---
 arch/powerpc/platforms/powernv/opal.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 49d2f00..17cfc70 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -242,14 +242,14 @@ void opal_notifier_update_evt(uint64_t evt_mask,
 void opal_notifier_enable(void)
 {
 	int64_t rc;
-	uint64_t evt = 0;
+	__be64 evt = 0;
 
 	atomic_set(&opal_notifier_hold, 0);
 
 	/* Process pending events */
 	rc = opal_poll_events(&evt);
 	if (rc == OPAL_SUCCESS && evt)
-		opal_do_notifier(evt);
+		opal_do_notifier(be64_to_cpu(evt));
 }
 
 void opal_notifier_disable(void)
@@ -529,7 +529,7 @@ static irqreturn_t opal_interrupt(int irq, void *data)
 
 	opal_handle_interrupt(virq_to_hw(irq), &events);
 
-	opal_do_notifier(events);
+	opal_do_notifier(be64_to_cpu(events));
 
 	return IRQ_HANDLED;
 }
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 4/6] powerpc/powernv: Fix little endian issues in OPAL error log code
  2014-04-22  5:01 [PATCH 1/6] powerpc/powernv: Use uint64_t instead of size_t in OPAL APIs Anton Blanchard
  2014-04-22  5:01 ` [PATCH 2/6] powerpc/powernv: Remove some OPAL function declaration duplication Anton Blanchard
  2014-04-22  5:01 ` [PATCH 3/6] powerpc/powernv: Fix little endian issues with opal_do_notifier calls Anton Blanchard
@ 2014-04-22  5:01 ` Anton Blanchard
  2014-04-22  8:10   ` Vasant Hegde
  2014-04-22  5:01 ` [PATCH 5/6] powerpc/powernv: Create OPAL sglist helper functions and fix endian issues Anton Blanchard
  2014-04-22  5:01 ` [PATCH 6/6] powerpc/powernv: Fix little endian issues in OPAL dump code Anton Blanchard
  4 siblings, 1 reply; 12+ messages in thread
From: Anton Blanchard @ 2014-04-22  5:01 UTC (permalink / raw)
  To: benh, paulus, hegdevasant, stewart; +Cc: linuxppc-dev

Fix little endian issues with the OPAL error log code.

Signed-off-by: Anton Blanchard <anton@samba.org>
Reviewed-by: Stewart Smith <stewart@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/opal.h            | 2 +-
 arch/powerpc/platforms/powernv/opal-elog.c | 9 ++++++++-
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index cb7d52e..1a752ac 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -859,7 +859,7 @@ int64_t opal_lpc_read(uint32_t chip_id, enum OpalLPCAddressType addr_type,
 		      uint32_t addr, __be32 *data, uint32_t sz);
 
 int64_t opal_read_elog(uint64_t buffer, uint64_t size, uint64_t log_id);
-int64_t opal_get_elog_size(uint64_t *log_id, uint64_t *size, uint64_t *elog_type);
+int64_t opal_get_elog_size(__be64 *log_id, __be64 *size, __be64 *elog_type);
 int64_t opal_write_elog(uint64_t buffer, uint64_t size, uint64_t offset);
 int64_t opal_send_ack_elog(uint64_t log_id);
 void opal_resend_pending_logs(void);
diff --git a/arch/powerpc/platforms/powernv/opal-elog.c b/arch/powerpc/platforms/powernv/opal-elog.c
index 7e3821e..10268c4 100644
--- a/arch/powerpc/platforms/powernv/opal-elog.c
+++ b/arch/powerpc/platforms/powernv/opal-elog.c
@@ -238,18 +238,25 @@ static struct elog_obj *create_elog_obj(uint64_t id, size_t size, uint64_t type)
 
 static void elog_work_fn(struct work_struct *work)
 {
+	__be64 size;
+	__be64 id;
+	__be64 type;
 	uint64_t elog_size;
 	uint64_t log_id;
 	uint64_t elog_type;
 	int rc;
 	char name[2+16+1];
 
-	rc = opal_get_elog_size(&log_id, &elog_size, &elog_type);
+	rc = opal_get_elog_size(&id, &size, &type);
 	if (rc != OPAL_SUCCESS) {
 		pr_err("ELOG: Opal log read failed\n");
 		return;
 	}
 
+	elog_size = be64_to_cpu(size);
+	log_id = be64_to_cpu(id);
+	elog_type = be64_to_cpu(type);
+
 	BUG_ON(elog_size > OPAL_MAX_ERRLOG_SIZE);
 
 	if (elog_size >= OPAL_MAX_ERRLOG_SIZE)
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 5/6] powerpc/powernv: Create OPAL sglist helper functions and fix endian issues
  2014-04-22  5:01 [PATCH 1/6] powerpc/powernv: Use uint64_t instead of size_t in OPAL APIs Anton Blanchard
                   ` (2 preceding siblings ...)
  2014-04-22  5:01 ` [PATCH 4/6] powerpc/powernv: Fix little endian issues in OPAL error log code Anton Blanchard
@ 2014-04-22  5:01 ` Anton Blanchard
  2014-04-22  9:16   ` Vasant Hegde
  2014-04-22  5:01 ` [PATCH 6/6] powerpc/powernv: Fix little endian issues in OPAL dump code Anton Blanchard
  4 siblings, 1 reply; 12+ messages in thread
From: Anton Blanchard @ 2014-04-22  5:01 UTC (permalink / raw)
  To: benh, paulus, hegdevasant, stewart; +Cc: linuxppc-dev

We have two copies of code that creates an OPAL sg list. Consolidate
these into a common set of helpers and fix the endian issues.

The flash interface embedded a version number in the num_entries
field, whereas the dump interface did did not. Since versioning
wasn't added to the flash interface and it is impossible to add
this in a backwards compatible way, just remove it.

Signed-off-by: Anton Blanchard <anton@samba.org>
---
 arch/powerpc/include/asm/opal.h             |  14 ++--
 arch/powerpc/platforms/powernv/opal-dump.c  |  81 +--------------------
 arch/powerpc/platforms/powernv/opal-flash.c | 106 +---------------------------
 arch/powerpc/platforms/powernv/opal.c       |  63 +++++++++++++++++
 4 files changed, 76 insertions(+), 188 deletions(-)

diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 1a752ac..afb0fed 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -41,14 +41,14 @@ struct opal_takeover_args {
  * size except the last one in the list to be as well.
  */
 struct opal_sg_entry {
-	void    *data;
-	long    length;
+	__be64 data;
+	__be64 length;
 };
 
-/* sg list */
+/* SG list */
 struct opal_sg_list {
-	unsigned long num_entries;
-	struct opal_sg_list *next;
+	__be64 length;
+	__be64 next;
 	struct opal_sg_entry entry[];
 };
 
@@ -929,6 +929,10 @@ extern int opal_resync_timebase(void);
 
 extern void opal_lpc_init(void);
 
+struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr,
+					     unsigned long vmalloc_size);
+void opal_free_sg_list(struct opal_sg_list *sg);
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __OPAL_H */
diff --git a/arch/powerpc/platforms/powernv/opal-dump.c b/arch/powerpc/platforms/powernv/opal-dump.c
index b9827b0..f0b4724 100644
--- a/arch/powerpc/platforms/powernv/opal-dump.c
+++ b/arch/powerpc/platforms/powernv/opal-dump.c
@@ -209,80 +209,6 @@ static struct kobj_type dump_ktype = {
 	.default_attrs = dump_default_attrs,
 };
 
-static void free_dump_sg_list(struct opal_sg_list *list)
-{
-	struct opal_sg_list *sg1;
-	while (list) {
-		sg1 = list->next;
-		kfree(list);
-		list = sg1;
-	}
-	list = NULL;
-}
-
-static struct opal_sg_list *dump_data_to_sglist(struct dump_obj *dump)
-{
-	struct opal_sg_list *sg1, *list = NULL;
-	void *addr;
-	int64_t size;
-
-	addr = dump->buffer;
-	size = dump->size;
-
-	sg1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
-	if (!sg1)
-		goto nomem;
-
-	list = sg1;
-	sg1->num_entries = 0;
-	while (size > 0) {
-		/* Translate virtual address to physical address */
-		sg1->entry[sg1->num_entries].data =
-			(void *)(vmalloc_to_pfn(addr) << PAGE_SHIFT);
-
-		if (size > PAGE_SIZE)
-			sg1->entry[sg1->num_entries].length = PAGE_SIZE;
-		else
-			sg1->entry[sg1->num_entries].length = size;
-
-		sg1->num_entries++;
-		if (sg1->num_entries >= SG_ENTRIES_PER_NODE) {
-			sg1->next = kzalloc(PAGE_SIZE, GFP_KERNEL);
-			if (!sg1->next)
-				goto nomem;
-
-			sg1 = sg1->next;
-			sg1->num_entries = 0;
-		}
-		addr += PAGE_SIZE;
-		size -= PAGE_SIZE;
-	}
-	return list;
-
-nomem:
-	pr_err("%s : Failed to allocate memory\n", __func__);
-	free_dump_sg_list(list);
-	return NULL;
-}
-
-static void sglist_to_phy_addr(struct opal_sg_list *list)
-{
-	struct opal_sg_list *sg, *next;
-
-	for (sg = list; sg; sg = next) {
-		next = sg->next;
-		/* Don't translate NULL pointer for last entry */
-		if (sg->next)
-			sg->next = (struct opal_sg_list *)__pa(sg->next);
-		else
-			sg->next = NULL;
-
-		/* Convert num_entries to length */
-		sg->num_entries =
-			sg->num_entries * sizeof(struct opal_sg_entry) + 16;
-	}
-}
-
 static int64_t dump_read_info(uint32_t *id, uint32_t *size, uint32_t *type)
 {
 	int rc;
@@ -314,15 +240,12 @@ static int64_t dump_read_data(struct dump_obj *dump)
 	}
 
 	/* Generate SG list */
-	list = dump_data_to_sglist(dump);
+	list = opal_vmalloc_to_sg_list(dump->buffer, dump->size);
 	if (!list) {
 		rc = -ENOMEM;
 		goto out;
 	}
 
-	/* Translate sg list addr to real address */
-	sglist_to_phy_addr(list);
-
 	/* First entry address */
 	addr = __pa(list);
 
@@ -341,7 +264,7 @@ static int64_t dump_read_data(struct dump_obj *dump)
 			__func__, dump->id);
 
 	/* Free SG list */
-	free_dump_sg_list(list);
+	opal_free_sg_list(list);
 
 out:
 	return rc;
diff --git a/arch/powerpc/platforms/powernv/opal-flash.c b/arch/powerpc/platforms/powernv/opal-flash.c
index 714ef97..0ae9e5f 100644
--- a/arch/powerpc/platforms/powernv/opal-flash.c
+++ b/arch/powerpc/platforms/powernv/opal-flash.c
@@ -79,9 +79,6 @@
 /* XXX: Assume candidate image size is <= 1GB */
 #define MAX_IMAGE_SIZE	0x40000000
 
-/* Flash sg list version */
-#define SG_LIST_VERSION (1UL)
-
 /* Image status */
 enum {
 	IMAGE_INVALID,
@@ -268,93 +265,11 @@ static ssize_t manage_store(struct kobject *kobj,
 }
 
 /*
- * Free sg list
- */
-static void free_sg_list(struct opal_sg_list *list)
-{
-	struct opal_sg_list *sg1;
-	while (list) {
-		sg1 = list->next;
-		kfree(list);
-		list = sg1;
-	}
-	list = NULL;
-}
-
-/*
- * Build candidate image scatter gather list
- *
- * list format:
- *   -----------------------------------
- *  |  VER (8) | Entry length in bytes  |
- *   -----------------------------------
- *  |  Pointer to next entry            |
- *   -----------------------------------
- *  |  Address of memory area 1         |
- *   -----------------------------------
- *  |  Length of memory area 1          |
- *   -----------------------------------
- *  |   .........                       |
- *   -----------------------------------
- *  |   .........                       |
- *   -----------------------------------
- *  |  Address of memory area N         |
- *   -----------------------------------
- *  |  Length of memory area N          |
- *   -----------------------------------
- */
-static struct opal_sg_list *image_data_to_sglist(void)
-{
-	struct opal_sg_list *sg1, *list = NULL;
-	void *addr;
-	int size;
-
-	addr = image_data.data;
-	size = image_data.size;
-
-	sg1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
-	if (!sg1)
-		return NULL;
-
-	list = sg1;
-	sg1->num_entries = 0;
-	while (size > 0) {
-		/* Translate virtual address to physical address */
-		sg1->entry[sg1->num_entries].data =
-			(void *)(vmalloc_to_pfn(addr) << PAGE_SHIFT);
-
-		if (size > PAGE_SIZE)
-			sg1->entry[sg1->num_entries].length = PAGE_SIZE;
-		else
-			sg1->entry[sg1->num_entries].length = size;
-
-		sg1->num_entries++;
-		if (sg1->num_entries >= SG_ENTRIES_PER_NODE) {
-			sg1->next = kzalloc(PAGE_SIZE, GFP_KERNEL);
-			if (!sg1->next) {
-				pr_err("%s : Failed to allocate memory\n",
-				       __func__);
-				goto nomem;
-			}
-
-			sg1 = sg1->next;
-			sg1->num_entries = 0;
-		}
-		addr += PAGE_SIZE;
-		size -= PAGE_SIZE;
-	}
-	return list;
-nomem:
-	free_sg_list(list);
-	return NULL;
-}
-
-/*
  * OPAL update flash
  */
 static int opal_flash_update(int op)
 {
-	struct opal_sg_list *sg, *list, *next;
+	struct opal_sg_list *list;
 	unsigned long addr;
 	int64_t rc = OPAL_PARAMETER;
 
@@ -364,30 +279,13 @@ static int opal_flash_update(int op)
 		goto flash;
 	}
 
-	list = image_data_to_sglist();
+	list = opal_vmalloc_to_sg_list(image_data.data, image_data.size);
 	if (!list)
 		goto invalid_img;
 
 	/* First entry address */
 	addr = __pa(list);
 
-	/* Translate sg list address to absolute */
-	for (sg = list; sg; sg = next) {
-		next = sg->next;
-		/* Don't translate NULL pointer for last entry */
-		if (sg->next)
-			sg->next = (struct opal_sg_list *)__pa(sg->next);
-		else
-			sg->next = NULL;
-
-		/*
-		 * Convert num_entries to version/length format
-		 * to satisfy OPAL.
-		 */
-		sg->num_entries = (SG_LIST_VERSION << 56) |
-			(sg->num_entries * sizeof(struct opal_sg_entry) + 16);
-	}
-
 	pr_alert("FLASH: Image is %u bytes\n", image_data.size);
 	pr_alert("FLASH: Image update requested\n");
 	pr_alert("FLASH: Image will be updated during system reboot\n");
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 17cfc70..360ad80c 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -638,3 +638,66 @@ void opal_shutdown(void)
 
 /* Export this so that test modules can use it */
 EXPORT_SYMBOL_GPL(opal_invalid_call);
+
+/* Convert a region of vmalloc memory to an opal sg list */
+struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr,
+					     unsigned long vmalloc_size)
+{
+	struct opal_sg_list *sg, *first = NULL;
+	unsigned long i = 0;
+
+	sg = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!sg)
+		goto nomem;
+
+	first = sg;
+
+	while (vmalloc_size > 0) {
+		uint64_t data = vmalloc_to_pfn(vmalloc_addr) << PAGE_SHIFT;
+		uint64_t length = min(vmalloc_size, PAGE_SIZE);
+
+		sg->entry[i].data = cpu_to_be64(data);
+		sg->entry[i].length = cpu_to_be64(length);
+		i++;
+
+		if (i >= SG_ENTRIES_PER_NODE) {
+			struct opal_sg_list *next;
+
+			next = kzalloc(PAGE_SIZE, GFP_KERNEL);
+			if (!next)
+				goto nomem;
+
+			sg->length = cpu_to_be64(
+					i * sizeof(struct opal_sg_entry) + 16);
+			i = 0;
+			sg->next = cpu_to_be64(__pa(next));
+			sg = next;
+		}
+
+		vmalloc_addr += length;
+		vmalloc_size -= length;
+	}
+
+	sg->length = cpu_to_be64(i * sizeof(struct opal_sg_entry) + 16);
+
+	return first;
+
+nomem:
+	pr_err("%s : Failed to allocate memory\n", __func__);
+	opal_free_sg_list(first);
+	return NULL;
+}
+
+void opal_free_sg_list(struct opal_sg_list *sg)
+{
+	while (sg) {
+		uint64_t next = be64_to_cpu(sg->next);
+
+		kfree(sg);
+
+		if (next)
+			sg = __va(next);
+		else
+			sg = NULL;
+	}
+}
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 6/6] powerpc/powernv: Fix little endian issues in OPAL dump code
  2014-04-22  5:01 [PATCH 1/6] powerpc/powernv: Use uint64_t instead of size_t in OPAL APIs Anton Blanchard
                   ` (3 preceding siblings ...)
  2014-04-22  5:01 ` [PATCH 5/6] powerpc/powernv: Create OPAL sglist helper functions and fix endian issues Anton Blanchard
@ 2014-04-22  5:01 ` Anton Blanchard
  2014-04-22  8:32   ` Vasant Hegde
  4 siblings, 1 reply; 12+ messages in thread
From: Anton Blanchard @ 2014-04-22  5:01 UTC (permalink / raw)
  To: benh, paulus, hegdevasant, stewart; +Cc: linuxppc-dev

Signed-off-by: Anton Blanchard <anton@samba.org>
---
 arch/powerpc/include/asm/opal.h            |  4 ++--
 arch/powerpc/platforms/powernv/opal-dump.c | 13 +++++++++----
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index afb0fed..66ad7a7 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -868,8 +868,8 @@ int64_t opal_validate_flash(uint64_t buffer, uint32_t *size, uint32_t *result);
 int64_t opal_manage_flash(uint8_t op);
 int64_t opal_update_flash(uint64_t blk_list);
 int64_t opal_dump_init(uint8_t dump_type);
-int64_t opal_dump_info(uint32_t *dump_id, uint32_t *dump_size);
-int64_t opal_dump_info2(uint32_t *dump_id, uint32_t *dump_size, uint32_t *dump_type);
+int64_t opal_dump_info(__be32 *dump_id, __be32 *dump_size);
+int64_t opal_dump_info2(__be32 *dump_id, __be32 *dump_size, __be32 *dump_type);
 int64_t opal_dump_read(uint32_t dump_id, uint64_t buffer);
 int64_t opal_dump_ack(uint32_t dump_id);
 int64_t opal_dump_resend_notification(void);
diff --git a/arch/powerpc/platforms/powernv/opal-dump.c b/arch/powerpc/platforms/powernv/opal-dump.c
index f0b4724..788a197 100644
--- a/arch/powerpc/platforms/powernv/opal-dump.c
+++ b/arch/powerpc/platforms/powernv/opal-dump.c
@@ -209,15 +209,20 @@ static struct kobj_type dump_ktype = {
 	.default_attrs = dump_default_attrs,
 };
 
-static int64_t dump_read_info(uint32_t *id, uint32_t *size, uint32_t *type)
+static int64_t dump_read_info(uint32_t *dump_id, uint32_t *dump_size, uint32_t *dump_type)
 {
+	__be32 id, size, type;
 	int rc;
-	*type = 0xffffffff;
 
-	rc = opal_dump_info2(id, size, type);
+	type = cpu_to_be32(0xffffffff);
 
+	rc = opal_dump_info2(&id, &size, &type);
 	if (rc == OPAL_PARAMETER)
-		rc = opal_dump_info(id, size);
+		rc = opal_dump_info(&id, &size);
+
+	*dump_id = be32_to_cpu(id);
+	*dump_size = be32_to_cpu(size);
+	*dump_type = be32_to_cpu(type);
 
 	if (rc)
 		pr_warn("%s: Failed to get dump info (%d)\n",
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 4/6] powerpc/powernv: Fix little endian issues in OPAL error log code
  2014-04-22  5:01 ` [PATCH 4/6] powerpc/powernv: Fix little endian issues in OPAL error log code Anton Blanchard
@ 2014-04-22  8:10   ` Vasant Hegde
  0 siblings, 0 replies; 12+ messages in thread
From: Vasant Hegde @ 2014-04-22  8:10 UTC (permalink / raw)
  To: Anton Blanchard, benh, paulus, stewart; +Cc: linuxppc-dev

On 04/22/2014 10:31 AM, Anton Blanchard wrote:
> Fix little endian issues with the OPAL error log code.
>
> Signed-off-by: Anton Blanchard <anton@samba.org>
> Reviewed-by: Stewart Smith <stewart@linux.vnet.ibm.com>
> ---
>   arch/powerpc/include/asm/opal.h            | 2 +-
>   arch/powerpc/platforms/powernv/opal-elog.c | 9 ++++++++-
>   2 files changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
> index cb7d52e..1a752ac 100644
> --- a/arch/powerpc/include/asm/opal.h
> +++ b/arch/powerpc/include/asm/opal.h
> @@ -859,7 +859,7 @@ int64_t opal_lpc_read(uint32_t chip_id, enum OpalLPCAddressType addr_type,
>   		      uint32_t addr, __be32 *data, uint32_t sz);
>
>   int64_t opal_read_elog(uint64_t buffer, uint64_t size, uint64_t log_id);
> -int64_t opal_get_elog_size(uint64_t *log_id, uint64_t *size, uint64_t *elog_type);
> +int64_t opal_get_elog_size(__be64 *log_id, __be64 *size, __be64 *elog_type);
>   int64_t opal_write_elog(uint64_t buffer, uint64_t size, uint64_t offset);
>   int64_t opal_send_ack_elog(uint64_t log_id);
>   void opal_resend_pending_logs(void);
> diff --git a/arch/powerpc/platforms/powernv/opal-elog.c b/arch/powerpc/platforms/powernv/opal-elog.c
> index 7e3821e..10268c4 100644
> --- a/arch/powerpc/platforms/powernv/opal-elog.c
> +++ b/arch/powerpc/platforms/powernv/opal-elog.c
> @@ -238,18 +238,25 @@ static struct elog_obj *create_elog_obj(uint64_t id, size_t size, uint64_t type)
>
>   static void elog_work_fn(struct work_struct *work)
>   {
> +	__be64 size;
> +	__be64 id;
> +	__be64 type;
>   	uint64_t elog_size;
>   	uint64_t log_id;
>   	uint64_t elog_type;
>   	int rc;
>   	char name[2+16+1];
>
> -	rc = opal_get_elog_size(&log_id, &elog_size, &elog_type);
> +	rc = opal_get_elog_size(&id, &size, &type);
>   	if (rc != OPAL_SUCCESS) {
>   		pr_err("ELOG: Opal log read failed\n");
>   		return;
>   	}
>
> +	elog_size = be64_to_cpu(size);
> +	log_id = be64_to_cpu(id);

Anton,

Shouldn't we covert Log ID back to BE format in ACK function (elog_ack_store() ) ?

Rest looks good.

-Vasant

> +	elog_type = be64_to_cpu(type);
> +
>   	BUG_ON(elog_size > OPAL_MAX_ERRLOG_SIZE);
>
>   	if (elog_size >= OPAL_MAX_ERRLOG_SIZE)
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 6/6] powerpc/powernv: Fix little endian issues in OPAL dump code
  2014-04-22  5:01 ` [PATCH 6/6] powerpc/powernv: Fix little endian issues in OPAL dump code Anton Blanchard
@ 2014-04-22  8:32   ` Vasant Hegde
  2014-04-22 21:31     ` Anton Blanchard
  0 siblings, 1 reply; 12+ messages in thread
From: Vasant Hegde @ 2014-04-22  8:32 UTC (permalink / raw)
  To: Anton Blanchard, benh, paulus, stewart; +Cc: linuxppc-dev

On 04/22/2014 10:31 AM, Anton Blanchard wrote:
> Signed-off-by: Anton Blanchard <anton@samba.org>
> ---
>   arch/powerpc/include/asm/opal.h            |  4 ++--
>   arch/powerpc/platforms/powernv/opal-dump.c | 13 +++++++++----
>   2 files changed, 11 insertions(+), 6 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
> index afb0fed..66ad7a7 100644
> --- a/arch/powerpc/include/asm/opal.h
> +++ b/arch/powerpc/include/asm/opal.h
> @@ -868,8 +868,8 @@ int64_t opal_validate_flash(uint64_t buffer, uint32_t *size, uint32_t *result);
>   int64_t opal_manage_flash(uint8_t op);
>   int64_t opal_update_flash(uint64_t blk_list);
>   int64_t opal_dump_init(uint8_t dump_type);
> -int64_t opal_dump_info(uint32_t *dump_id, uint32_t *dump_size);
> -int64_t opal_dump_info2(uint32_t *dump_id, uint32_t *dump_size, uint32_t *dump_type);
> +int64_t opal_dump_info(__be32 *dump_id, __be32 *dump_size);
> +int64_t opal_dump_info2(__be32 *dump_id, __be32 *dump_size, __be32 *dump_type);
>   int64_t opal_dump_read(uint32_t dump_id, uint64_t buffer);
>   int64_t opal_dump_ack(uint32_t dump_id);

Shouldn't we change above two functions as well ?

>   int64_t opal_dump_resend_notification(void);
> diff --git a/arch/powerpc/platforms/powernv/opal-dump.c b/arch/powerpc/platforms/powernv/opal-dump.c
> index f0b4724..788a197 100644
> --- a/arch/powerpc/platforms/powernv/opal-dump.c
> +++ b/arch/powerpc/platforms/powernv/opal-dump.c
> @@ -209,15 +209,20 @@ static struct kobj_type dump_ktype = {
>   	.default_attrs = dump_default_attrs,
>   };
>
> -static int64_t dump_read_info(uint32_t *id, uint32_t *size, uint32_t *type)
> +static int64_t dump_read_info(uint32_t *dump_id, uint32_t *dump_size, uint32_t *dump_type)
>   {
> +	__be32 id, size, type;
>   	int rc;
> -	*type = 0xffffffff;
>
> -	rc = opal_dump_info2(id, size, type);
> +	type = cpu_to_be32(0xffffffff);
>
> +	rc = opal_dump_info2(&id, &size, &type);
>   	if (rc == OPAL_PARAMETER)
> -		rc = opal_dump_info(id, size);
> +		rc = opal_dump_info(&id, &size);
> +
> +	*dump_id = be32_to_cpu(id);
> +	*dump_size = be32_to_cpu(size);
> +	*dump_type = be32_to_cpu(type);
>

Should we convert ID back to BE format in dump_send_ack()  ?

-Vasant


>   	if (rc)
>   		pr_warn("%s: Failed to get dump info (%d)\n",
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 5/6] powerpc/powernv: Create OPAL sglist helper functions and fix endian issues
  2014-04-22  5:01 ` [PATCH 5/6] powerpc/powernv: Create OPAL sglist helper functions and fix endian issues Anton Blanchard
@ 2014-04-22  9:16   ` Vasant Hegde
  2014-04-22 21:34     ` Anton Blanchard
  0 siblings, 1 reply; 12+ messages in thread
From: Vasant Hegde @ 2014-04-22  9:16 UTC (permalink / raw)
  To: Anton Blanchard, benh, paulus, stewart; +Cc: linuxppc-dev

On 04/22/2014 10:31 AM, Anton Blanchard wrote:
> We have two copies of code that creates an OPAL sg list. Consolidate
> these into a common set of helpers and fix the endian issues.
>
> The flash interface embedded a version number in the num_entries
> field, whereas the dump interface did did not. Since versioning
> wasn't added to the flash interface and it is impossible to add
> this in a backwards compatible way, just remove it.
>
> Signed-off-by: Anton Blanchard <anton@samba.org>
> ---
>   arch/powerpc/include/asm/opal.h             |  14 ++--
>   arch/powerpc/platforms/powernv/opal-dump.c  |  81 +--------------------
>   arch/powerpc/platforms/powernv/opal-flash.c | 106 +---------------------------
>   arch/powerpc/platforms/powernv/opal.c       |  63 +++++++++++++++++
>   4 files changed, 76 insertions(+), 188 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
> index 1a752ac..afb0fed 100644
> --- a/arch/powerpc/include/asm/opal.h
> +++ b/arch/powerpc/include/asm/opal.h
> @@ -41,14 +41,14 @@ struct opal_takeover_args {
>    * size except the last one in the list to be as well.
>    */
>   struct opal_sg_entry {
> -	void    *data;
> -	long    length;
> +	__be64 data;
> +	__be64 length;
>   };
>
> -/* sg list */
> +/* SG list */
>   struct opal_sg_list {
> -	unsigned long num_entries;
> -	struct opal_sg_list *next;
> +	__be64 length;
> +	__be64 next;
>   	struct opal_sg_entry entry[];
>   };
>
> @@ -929,6 +929,10 @@ extern int opal_resync_timebase(void);
>
>   extern void opal_lpc_init(void);
>
> +struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr,
> +					     unsigned long vmalloc_size);
> +void opal_free_sg_list(struct opal_sg_list *sg);
> +
>   #endif /* __ASSEMBLY__ */
>
>   #endif /* __OPAL_H */
> diff --git a/arch/powerpc/platforms/powernv/opal-dump.c b/arch/powerpc/platforms/powernv/opal-dump.c
> index b9827b0..f0b4724 100644
> --- a/arch/powerpc/platforms/powernv/opal-dump.c
> +++ b/arch/powerpc/platforms/powernv/opal-dump.c
> @@ -209,80 +209,6 @@ static struct kobj_type dump_ktype = {
>   	.default_attrs = dump_default_attrs,
>   };
>
> -static void free_dump_sg_list(struct opal_sg_list *list)
> -{
> -	struct opal_sg_list *sg1;
> -	while (list) {
> -		sg1 = list->next;
> -		kfree(list);
> -		list = sg1;
> -	}
> -	list = NULL;
> -}
> -
> -static struct opal_sg_list *dump_data_to_sglist(struct dump_obj *dump)
> -{
> -	struct opal_sg_list *sg1, *list = NULL;
> -	void *addr;
> -	int64_t size;
> -
> -	addr = dump->buffer;
> -	size = dump->size;
> -
> -	sg1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
> -	if (!sg1)
> -		goto nomem;
> -
> -	list = sg1;
> -	sg1->num_entries = 0;
> -	while (size > 0) {
> -		/* Translate virtual address to physical address */
> -		sg1->entry[sg1->num_entries].data =
> -			(void *)(vmalloc_to_pfn(addr) << PAGE_SHIFT);
> -
> -		if (size > PAGE_SIZE)
> -			sg1->entry[sg1->num_entries].length = PAGE_SIZE;
> -		else
> -			sg1->entry[sg1->num_entries].length = size;
> -
> -		sg1->num_entries++;
> -		if (sg1->num_entries >= SG_ENTRIES_PER_NODE) {
> -			sg1->next = kzalloc(PAGE_SIZE, GFP_KERNEL);
> -			if (!sg1->next)
> -				goto nomem;
> -
> -			sg1 = sg1->next;
> -			sg1->num_entries = 0;
> -		}
> -		addr += PAGE_SIZE;
> -		size -= PAGE_SIZE;
> -	}
> -	return list;
> -
> -nomem:
> -	pr_err("%s : Failed to allocate memory\n", __func__);
> -	free_dump_sg_list(list);
> -	return NULL;
> -}
> -
> -static void sglist_to_phy_addr(struct opal_sg_list *list)
> -{
> -	struct opal_sg_list *sg, *next;
> -
> -	for (sg = list; sg; sg = next) {
> -		next = sg->next;
> -		/* Don't translate NULL pointer for last entry */
> -		if (sg->next)
> -			sg->next = (struct opal_sg_list *)__pa(sg->next);
> -		else
> -			sg->next = NULL;
> -
> -		/* Convert num_entries to length */
> -		sg->num_entries =
> -			sg->num_entries * sizeof(struct opal_sg_entry) + 16;
> -	}
> -}
> -
>   static int64_t dump_read_info(uint32_t *id, uint32_t *size, uint32_t *type)
>   {
>   	int rc;
> @@ -314,15 +240,12 @@ static int64_t dump_read_data(struct dump_obj *dump)
>   	}
>
>   	/* Generate SG list */
> -	list = dump_data_to_sglist(dump);
> +	list = opal_vmalloc_to_sg_list(dump->buffer, dump->size);
>   	if (!list) {
>   		rc = -ENOMEM;
>   		goto out;
>   	}
>
> -	/* Translate sg list addr to real address */
> -	sglist_to_phy_addr(list);
> -
>   	/* First entry address */
>   	addr = __pa(list);
>
> @@ -341,7 +264,7 @@ static int64_t dump_read_data(struct dump_obj *dump)
>   			__func__, dump->id);
>

Shouldn't we convert addr and id before passing to opal_dump_read() here ?


>   	/* Free SG list */
> -	free_dump_sg_list(list);
> +	opal_free_sg_list(list);
>
>   out:
>   	return rc;
> diff --git a/arch/powerpc/platforms/powernv/opal-flash.c b/arch/powerpc/platforms/powernv/opal-flash.c
> index 714ef97..0ae9e5f 100644
> --- a/arch/powerpc/platforms/powernv/opal-flash.c
> +++ b/arch/powerpc/platforms/powernv/opal-flash.c
> @@ -79,9 +79,6 @@
>   /* XXX: Assume candidate image size is <= 1GB */
>   #define MAX_IMAGE_SIZE	0x40000000
>
> -/* Flash sg list version */
> -#define SG_LIST_VERSION (1UL)
> -
>   /* Image status */
>   enum {
>   	IMAGE_INVALID,
> @@ -268,93 +265,11 @@ static ssize_t manage_store(struct kobject *kobj,
>   }
>
>   /*
> - * Free sg list
> - */
> -static void free_sg_list(struct opal_sg_list *list)
> -{
> -	struct opal_sg_list *sg1;
> -	while (list) {
> -		sg1 = list->next;
> -		kfree(list);
> -		list = sg1;
> -	}
> -	list = NULL;
> -}
> -
> -/*
> - * Build candidate image scatter gather list
> - *
> - * list format:
> - *   -----------------------------------
> - *  |  VER (8) | Entry length in bytes  |
> - *   -----------------------------------
> - *  |  Pointer to next entry            |
> - *   -----------------------------------
> - *  |  Address of memory area 1         |
> - *   -----------------------------------
> - *  |  Length of memory area 1          |
> - *   -----------------------------------
> - *  |   .........                       |
> - *   -----------------------------------
> - *  |   .........                       |
> - *   -----------------------------------
> - *  |  Address of memory area N         |
> - *   -----------------------------------
> - *  |  Length of memory area N          |
> - *   -----------------------------------
> - */
> -static struct opal_sg_list *image_data_to_sglist(void)
> -{
> -	struct opal_sg_list *sg1, *list = NULL;
> -	void *addr;
> -	int size;
> -
> -	addr = image_data.data;
> -	size = image_data.size;
> -
> -	sg1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
> -	if (!sg1)
> -		return NULL;
> -
> -	list = sg1;
> -	sg1->num_entries = 0;
> -	while (size > 0) {
> -		/* Translate virtual address to physical address */
> -		sg1->entry[sg1->num_entries].data =
> -			(void *)(vmalloc_to_pfn(addr) << PAGE_SHIFT);
> -
> -		if (size > PAGE_SIZE)
> -			sg1->entry[sg1->num_entries].length = PAGE_SIZE;
> -		else
> -			sg1->entry[sg1->num_entries].length = size;
> -
> -		sg1->num_entries++;
> -		if (sg1->num_entries >= SG_ENTRIES_PER_NODE) {
> -			sg1->next = kzalloc(PAGE_SIZE, GFP_KERNEL);
> -			if (!sg1->next) {
> -				pr_err("%s : Failed to allocate memory\n",
> -				       __func__);
> -				goto nomem;
> -			}
> -
> -			sg1 = sg1->next;
> -			sg1->num_entries = 0;
> -		}
> -		addr += PAGE_SIZE;
> -		size -= PAGE_SIZE;
> -	}
> -	return list;
> -nomem:
> -	free_sg_list(list);
> -	return NULL;
> -}
> -
> -/*
>    * OPAL update flash
>    */
>   static int opal_flash_update(int op)
>   {
> -	struct opal_sg_list *sg, *list, *next;
> +	struct opal_sg_list *list;
>   	unsigned long addr;
>   	int64_t rc = OPAL_PARAMETER;
>
> @@ -364,30 +279,13 @@ static int opal_flash_update(int op)
>   		goto flash;
>   	}
>
> -	list = image_data_to_sglist();
> +	list = opal_vmalloc_to_sg_list(image_data.data, image_data.size);
>   	if (!list)
>   		goto invalid_img;
>
>   	/* First entry address */
>   	addr = __pa(list);
>
> -	/* Translate sg list address to absolute */
> -	for (sg = list; sg; sg = next) {
> -		next = sg->next;
> -		/* Don't translate NULL pointer for last entry */
> -		if (sg->next)
> -			sg->next = (struct opal_sg_list *)__pa(sg->next);
> -		else
> -			sg->next = NULL;
> -
> -		/*
> -		 * Convert num_entries to version/length format
> -		 * to satisfy OPAL.
> -		 */
> -		sg->num_entries = (SG_LIST_VERSION << 56) |
> -			(sg->num_entries * sizeof(struct opal_sg_entry) + 16);
> -	}
> -
>   	pr_alert("FLASH: Image is %u bytes\n", image_data.size);
>   	pr_alert("FLASH: Image update requested\n");
>   	pr_alert("FLASH: Image will be updated during system reboot\n");
> diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
> index 17cfc70..360ad80c 100644
> --- a/arch/powerpc/platforms/powernv/opal.c
> +++ b/arch/powerpc/platforms/powernv/opal.c
> @@ -638,3 +638,66 @@ void opal_shutdown(void)
>
>   /* Export this so that test modules can use it */
>   EXPORT_SYMBOL_GPL(opal_invalid_call);
> +
> +/* Convert a region of vmalloc memory to an opal sg list */
> +struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr,
> +					     unsigned long vmalloc_size)
> +{
> +	struct opal_sg_list *sg, *first = NULL;
> +	unsigned long i = 0;
> +
> +	sg = kzalloc(PAGE_SIZE, GFP_KERNEL);
> +	if (!sg)
> +		goto nomem;
> +
> +	first = sg;
> +
> +	while (vmalloc_size > 0) {
> +		uint64_t data = vmalloc_to_pfn(vmalloc_addr) << PAGE_SHIFT;
> +		uint64_t length = min(vmalloc_size, PAGE_SIZE);
> +
> +		sg->entry[i].data = cpu_to_be64(data);
> +		sg->entry[i].length = cpu_to_be64(length);
> +		i++;
> +
> +		if (i >= SG_ENTRIES_PER_NODE) {
> +			struct opal_sg_list *next;
> +
> +			next = kzalloc(PAGE_SIZE, GFP_KERNEL);
> +			if (!next)
> +				goto nomem;
> +
> +			sg->length = cpu_to_be64(
> +					i * sizeof(struct opal_sg_entry) + 16);
> +			i = 0;
> +			sg->next = cpu_to_be64(__pa(next));
> +			sg = next;
> +		}
> +
> +		vmalloc_addr += length;
> +		vmalloc_size -= length;
> +	}
> +
> +	sg->length = cpu_to_be64(i * sizeof(struct opal_sg_entry) + 16);
> +
> +	return first;
> +
> +nomem:
> +	pr_err("%s : Failed to allocate memory\n", __func__);
> +	opal_free_sg_list(first);
> +	return NULL;
> +}
> +
> +void opal_free_sg_list(struct opal_sg_list *sg)
> +{
> +	while (sg) {
> +		uint64_t next = be64_to_cpu(sg->next);
> +
> +		kfree(sg);
> +
> +		if (next)
> +			sg = __va(next);

This for this fix..

-Vasant

> +		else
> +			sg = NULL;
> +	}
> +}
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 6/6] powerpc/powernv: Fix little endian issues in OPAL dump code
  2014-04-22  8:32   ` Vasant Hegde
@ 2014-04-22 21:31     ` Anton Blanchard
  2014-04-23  4:36       ` Vasant Hegde
  0 siblings, 1 reply; 12+ messages in thread
From: Anton Blanchard @ 2014-04-22 21:31 UTC (permalink / raw)
  To: Vasant Hegde; +Cc: stewart, paulus, linuxppc-dev

Hi,

> -int64_t opal_dump_info(uint32_t *dump_id, uint32_t *dump_size);
> -int64_t opal_dump_info2(uint32_t *dump_id, uint32_t *dump_size, uint32_t *dump_type);
> +int64_t opal_dump_info(__be32 *dump_id, __be32 *dump_size);
> +int64_t opal_dump_info2(__be32 *dump_id, __be32 *dump_size, __be32 *dump_type);
>  int64_t opal_dump_read(uint32_t dump_id, uint64_t buffer);
>  int64_t opal_dump_ack(uint32_t dump_id);  
>
> Shouldn't we change above two functions as well ?

No, there are no endian issues here because we pass the values via
register. The only endian issues are for values we pass via pointer.

> Should we convert ID back to BE format in dump_send_ack()  ?

Same as above.

Anton

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 5/6] powerpc/powernv: Create OPAL sglist helper functions and fix endian issues
  2014-04-22  9:16   ` Vasant Hegde
@ 2014-04-22 21:34     ` Anton Blanchard
  0 siblings, 0 replies; 12+ messages in thread
From: Anton Blanchard @ 2014-04-22 21:34 UTC (permalink / raw)
  To: Vasant Hegde; +Cc: stewart, paulus, linuxppc-dev


Hi,

> Shouldn't we convert addr and id before passing to opal_dump_read()
> here ?

int64_t opal_dump_read(uint32_t dump_id, uint64_t buffer);

All arguments are passed via register, so byteswaping the arguments
would break it.

Anton

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 6/6] powerpc/powernv: Fix little endian issues in OPAL dump code
  2014-04-22 21:31     ` Anton Blanchard
@ 2014-04-23  4:36       ` Vasant Hegde
  0 siblings, 0 replies; 12+ messages in thread
From: Vasant Hegde @ 2014-04-23  4:36 UTC (permalink / raw)
  To: Anton Blanchard; +Cc: stewart, paulus, linuxppc-dev

On 04/23/2014 03:01 AM, Anton Blanchard wrote:
> Hi,
>
>> -int64_t opal_dump_info(uint32_t *dump_id, uint32_t *dump_size);
>> -int64_t opal_dump_info2(uint32_t *dump_id, uint32_t *dump_size, uint32_t *dump_type);
>> +int64_t opal_dump_info(__be32 *dump_id, __be32 *dump_size);
>> +int64_t opal_dump_info2(__be32 *dump_id, __be32 *dump_size, __be32 *dump_type);
>>   int64_t opal_dump_read(uint32_t dump_id, uint64_t buffer);
>>   int64_t opal_dump_ack(uint32_t dump_id);
>>
>> Shouldn't we change above two functions as well ?
>
> No, there are no endian issues here because we pass the values via
> register. The only endian issues are for values we pass via pointer.
>

Anton,

Thanks for the clarification..


-Vasant

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2014-04-23  4:36 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-04-22  5:01 [PATCH 1/6] powerpc/powernv: Use uint64_t instead of size_t in OPAL APIs Anton Blanchard
2014-04-22  5:01 ` [PATCH 2/6] powerpc/powernv: Remove some OPAL function declaration duplication Anton Blanchard
2014-04-22  5:01 ` [PATCH 3/6] powerpc/powernv: Fix little endian issues with opal_do_notifier calls Anton Blanchard
2014-04-22  5:01 ` [PATCH 4/6] powerpc/powernv: Fix little endian issues in OPAL error log code Anton Blanchard
2014-04-22  8:10   ` Vasant Hegde
2014-04-22  5:01 ` [PATCH 5/6] powerpc/powernv: Create OPAL sglist helper functions and fix endian issues Anton Blanchard
2014-04-22  9:16   ` Vasant Hegde
2014-04-22 21:34     ` Anton Blanchard
2014-04-22  5:01 ` [PATCH 6/6] powerpc/powernv: Fix little endian issues in OPAL dump code Anton Blanchard
2014-04-22  8:32   ` Vasant Hegde
2014-04-22 21:31     ` Anton Blanchard
2014-04-23  4:36       ` Vasant Hegde

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).