LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 6/7] DMA: Freescale: use spin_lock_bh instead of spin_lock_irqsave
From: Vinod Koul @ 2014-03-29 13:45 UTC (permalink / raw)
  To: Hongbo Zhang
  Cc: Vinod Koul, linux-kernel, scottwood, dmaengine, dan.j.williams,
	linuxppc-dev
In-Reply-To: <533517C1.8080208@freescale.com>

On Fri, Mar 28, 2014 at 02:33:37PM +0800, Hongbo Zhang wrote:
> 
> On 03/26/2014 03:01 PM, Vinod Koul wrote:
> >On Thu, 2014-01-16 at 13:47 +0800, hongbo.zhang@freescale.com wrote:
> >>From: Hongbo Zhang <hongbo.zhang@freescale.com>
> >>
> >>The usage of spin_lock_irqsave() is a stronger locking mechanism than is
> >>required throughout the driver. The minimum locking required should be used
> >>instead. Interrupts will be turned off and context will be saved, it is
> >>unnecessary to use irqsave.
> >>
> >>This patch changes all instances of spin_lock_irqsave() to spin_lock_bh(). All
> >>manipulation of protected fields is done using tasklet context or weaker, which
> >>makes spin_lock_bh() the correct choice.
> >>


> >>  /**
> >>@@ -1124,11 +1120,10 @@ static irqreturn_t fsldma_chan_irq(int irq, void *data)
> >>  static void dma_do_tasklet(unsigned long data)
> >>  {
> >>  	struct fsldma_chan *chan = (struct fsldma_chan *)data;
> >>-	unsigned long flags;
> >>  	chan_dbg(chan, "tasklet entry\n");
> >>-	spin_lock_irqsave(&chan->desc_lock, flags);
> >>+	spin_lock_bh(&chan->desc_lock);
> >okay here is the problem :(
> >
> >You moved to _bh variant. So if you grab the lock in rest of the code
> >and irq gets triggered then here we will be spinning to grab the lock.
> >So effectively you made right locking solution into deadlock situation!
> 
> If the rest code grabs lock by spin_lock_bh(), and if irq raised,
> the tasklet could not be executed because it has been disabled by
> the _bh variant function.
yes if you are accessing resources only in tasklet and rest of the code, then
_bh variant works well. The problem here is usage in irq handler

-- 
~Vinod

^ permalink raw reply

* Re: [PATCH v2] phy/at8031: enable at8031 to work on interrupt mode
From: David Miller @ 2014-03-29 22:20 UTC (permalink / raw)
  To: B45475
  Cc: mugunthanvnm, B07421, netdev, helmut.schaa, linux-kernel, zonque,
	R63061, linuxppc-dev
In-Reply-To: <1395992381-23094-1-git-send-email-B45475@freescale.com>

From: Zhao Qiang <B45475@freescale.com>
Date: Fri, 28 Mar 2014 15:39:41 +0800

> The at8031 can work on polling mode and interrupt mode.
> Add ack_interrupt and config intr funcs to enable
> interrupt mode for it.
> 
> Signed-off-by: Zhao Qiang <B45475@freescale.com>
> ---
> changes for v2:
> 	- when interrupt is not enabled, write 0 to interrupt enbale register
> 	- delete a inner parens not needed

Applied to net-next, thanks.

^ permalink raw reply

* [PATCH] gpio: ge: Convert to platform driver
From: Alexander Shiyan @ 2014-03-30  5:14 UTC (permalink / raw)
  To: linux-gpio
  Cc: Alexandre Courbot, Linus Walleij, linuxppc-dev, Alexander Shiyan

This patch converts GE I/O FPGA GPIO driver to platform driver.

Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
---
Only compile tested.
---
 drivers/gpio/gpio-ge.c | 176 ++++++++++++++++---------------------------------
 1 file changed, 58 insertions(+), 118 deletions(-)

diff --git a/drivers/gpio/gpio-ge.c b/drivers/gpio/gpio-ge.c
index 7b95a4a..93efb29 100644
--- a/drivers/gpio/gpio-ge.c
+++ b/drivers/gpio/gpio-ge.c
@@ -18,15 +18,9 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/compiler.h>
-#include <linux/init.h>
 #include <linux/io.h>
-#include <linux/of.h>
 #include <linux/of_device.h>
-#include <linux/of_platform.h>
 #include <linux/of_gpio.h>
-#include <linux/gpio.h>
-#include <linux/slab.h>
 #include <linux/module.h>
 
 #define GEF_GPIO_DIRECT		0x00
@@ -39,28 +33,28 @@
 #define GEF_GPIO_OVERRUN	0x1C
 #define GEF_GPIO_MODE		0x20
 
-static void _gef_gpio_set(void __iomem *reg, unsigned int offset, int value)
+static void gef_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 {
+	struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
 	unsigned int data;
 
-	data = ioread32be(reg);
+	data = ioread32be(mmchip->regs + GEF_GPIO_OUT);
 	/* value: 0=low; 1=high */
-	if (value & 0x1)
-		data = data | (0x1 << offset);
+	if (value)
+		data = data | BIT(offset);
 	else
-		data = data & ~(0x1 << offset);
+		data = data & ~BIT(offset);
 
-	iowrite32be(data, reg);
+	iowrite32be(data, mmchip->regs + GEF_GPIO_OUT);
 }
 
-
 static int gef_gpio_dir_in(struct gpio_chip *chip, unsigned offset)
 {
 	unsigned int data;
 	struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
 
 	data = ioread32be(mmchip->regs + GEF_GPIO_DIRECT);
-	data = data | (0x1 << offset);
+	data = data | BIT(offset);
 	iowrite32be(data, mmchip->regs + GEF_GPIO_DIRECT);
 
 	return 0;
@@ -71,11 +65,11 @@ static int gef_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int value)
 	unsigned int data;
 	struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
 
-	/* Set direction before switching to input */
-	_gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value);
+	/* Set value before switching to output */
+	gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value);
 
 	data = ioread32be(mmchip->regs + GEF_GPIO_DIRECT);
-	data = data & ~(0x1 << offset);
+	data = data & ~BIT(offset);
 	iowrite32be(data, mmchip->regs + GEF_GPIO_DIRECT);
 
 	return 0;
@@ -83,116 +77,62 @@ static int gef_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int value)
 
 static int gef_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
-	unsigned int data;
-	int state = 0;
 	struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
 
-	data = ioread32be(mmchip->regs + GEF_GPIO_IN);
-	state = (int)((data >> offset) & 0x1);
-
-	return state;
+	return !!(ioread32be(mmchip->regs + GEF_GPIO_IN) & BIT(offset));
 }
 
-static void gef_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+static const struct of_device_id gef_gpio_ids[] = {
+	{
+		.compatible	= "gef,sbc610-gpio",
+		.data		= (void *)19,
+	}, {
+		.compatible	= "gef,sbc310-gpio",
+		.data		= (void *)6,
+	}, {
+		.compatible	= "ge,imp3a-gpio",
+		.data		= (void *)16,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, gef_gpio_ids);
+
+static int gef_gpio_probe(struct platform_device *pdev)
 {
-	struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
+	const struct of_device_id *of_id =
+		of_match_device(gef_gpio_ids, &pdev->dev);
+	struct of_mm_gpio_chip *mmchip;
 
-	_gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value);
-}
+	if (!of_id)
+		return -ENOSYS;
 
-static int __init gef_gpio_init(void)
-{
-	struct device_node *np;
-	int retval;
-	struct of_mm_gpio_chip *gef_gpio_chip;
-
-	for_each_compatible_node(np, NULL, "gef,sbc610-gpio") {
-
-		pr_debug("%s: Initialising GEF GPIO\n", np->full_name);
-
-		/* Allocate chip structure */
-		gef_gpio_chip = kzalloc(sizeof(*gef_gpio_chip), GFP_KERNEL);
-		if (!gef_gpio_chip) {
-			pr_err("%s: Unable to allocate structure\n",
-				np->full_name);
-			continue;
-		}
-
-		/* Setup pointers to chip functions */
-		gef_gpio_chip->gc.of_gpio_n_cells = 2;
-		gef_gpio_chip->gc.ngpio = 19;
-		gef_gpio_chip->gc.direction_input = gef_gpio_dir_in;
-		gef_gpio_chip->gc.direction_output = gef_gpio_dir_out;
-		gef_gpio_chip->gc.get = gef_gpio_get;
-		gef_gpio_chip->gc.set = gef_gpio_set;
-
-		/* This function adds a memory mapped GPIO chip */
-		retval = of_mm_gpiochip_add(np, gef_gpio_chip);
-		if (retval) {
-			kfree(gef_gpio_chip);
-			pr_err("%s: Unable to add GPIO\n", np->full_name);
-		}
-	}
-
-	for_each_compatible_node(np, NULL, "gef,sbc310-gpio") {
-
-		pr_debug("%s: Initialising GEF GPIO\n", np->full_name);
-
-		/* Allocate chip structure */
-		gef_gpio_chip = kzalloc(sizeof(*gef_gpio_chip), GFP_KERNEL);
-		if (!gef_gpio_chip) {
-			pr_err("%s: Unable to allocate structure\n",
-				np->full_name);
-			continue;
-		}
-
-		/* Setup pointers to chip functions */
-		gef_gpio_chip->gc.of_gpio_n_cells = 2;
-		gef_gpio_chip->gc.ngpio = 6;
-		gef_gpio_chip->gc.direction_input = gef_gpio_dir_in;
-		gef_gpio_chip->gc.direction_output = gef_gpio_dir_out;
-		gef_gpio_chip->gc.get = gef_gpio_get;
-		gef_gpio_chip->gc.set = gef_gpio_set;
-
-		/* This function adds a memory mapped GPIO chip */
-		retval = of_mm_gpiochip_add(np, gef_gpio_chip);
-		if (retval) {
-			kfree(gef_gpio_chip);
-			pr_err("%s: Unable to add GPIO\n", np->full_name);
-		}
-	}
-
-	for_each_compatible_node(np, NULL, "ge,imp3a-gpio") {
-
-		pr_debug("%s: Initialising GE GPIO\n", np->full_name);
-
-		/* Allocate chip structure */
-		gef_gpio_chip = kzalloc(sizeof(*gef_gpio_chip), GFP_KERNEL);
-		if (!gef_gpio_chip) {
-			pr_err("%s: Unable to allocate structure\n",
-				np->full_name);
-			continue;
-		}
-
-		/* Setup pointers to chip functions */
-		gef_gpio_chip->gc.of_gpio_n_cells = 2;
-		gef_gpio_chip->gc.ngpio = 16;
-		gef_gpio_chip->gc.direction_input = gef_gpio_dir_in;
-		gef_gpio_chip->gc.direction_output = gef_gpio_dir_out;
-		gef_gpio_chip->gc.get = gef_gpio_get;
-		gef_gpio_chip->gc.set = gef_gpio_set;
-
-		/* This function adds a memory mapped GPIO chip */
-		retval = of_mm_gpiochip_add(np, gef_gpio_chip);
-		if (retval) {
-			kfree(gef_gpio_chip);
-			pr_err("%s: Unable to add GPIO\n", np->full_name);
-		}
-	}
+	mmchip = devm_kzalloc(&pdev->dev, sizeof(*mmchip), GFP_KERNEL);
+	if (!mmchip)
+		return -ENOMEM;
 
-	return 0;
+	/* Setup pointers to chip functions */
+	mmchip->gc.ngpio = (u16)(uintptr_t)of_id->data;
+	mmchip->gc.of_gpio_n_cells = 2;
+	mmchip->gc.direction_input = gef_gpio_dir_in;
+	mmchip->gc.direction_output = gef_gpio_dir_out;
+	mmchip->gc.get = gef_gpio_get;
+	mmchip->gc.set = gef_gpio_set;
+
+	platform_set_drvdata(pdev, mmchip);
+
+	/* This function adds a memory mapped GPIO chip */
+	return of_mm_gpiochip_add(pdev->dev.of_node, mmchip);
+};
+
+static struct platform_driver gef_gpio_driver = {
+	.driver	= {
+		.name		= "gef-gpio",
+		.owner		= THIS_MODULE,
+		.of_match_table	= gef_gpio_ids,
+	},
+	.probe	= gef_gpio_probe,
 };
-arch_initcall(gef_gpio_init);
+module_platform_driver(gef_gpio_driver);
 
 MODULE_DESCRIPTION("GE I/O FPGA GPIO driver");
 MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com");
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH] powerpc/book3s: Fix mc_recoverable_range buffer overrun issue.
From: Mahesh J Salgaonkar @ 2014-03-30  5:33 UTC (permalink / raw)
  To: linuxppc-dev, Benjamin Herrenschmidt; +Cc: Paul Mackerras, Anton Blanchard

From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>

Currently we wrongly allocate mc_recoverable_range buffer (to hold
recoverable ranges) based on size of the property "mcheck-recoverable-ranges".
This results in allocating less memory to hold available recoverable range
entries from /proc/device-tree/ibm,opal/mcheck-recoverable-ranges.

This patch fixes this issue by allocating mc_recoverable_range buffer based
on number of entries of recoverable ranges instead of device property size.
Without this change we end up allocating less memory and run into memory
corruption issue.

Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/powernv/opal.c |   28 ++++++++++++++++++++--------
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index d5f11d6..f4c011f 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -102,13 +102,13 @@ int __init early_init_dt_scan_opal(unsigned long node,
 int __init early_init_dt_scan_recoverable_ranges(unsigned long node,
 				   const char *uname, int depth, void *data)
 {
-	unsigned long i, size;
+	unsigned long i, psize, size;
 	const __be32 *prop;
 
 	if (depth != 1 || strcmp(uname, "ibm,opal") != 0)
 		return 0;
 
-	prop = of_get_flat_dt_prop(node, "mcheck-recoverable-ranges", &size);
+	prop = of_get_flat_dt_prop(node, "mcheck-recoverable-ranges", &psize);
 
 	if (!prop)
 		return 1;
@@ -116,6 +116,23 @@ int __init early_init_dt_scan_recoverable_ranges(unsigned long node,
 	pr_debug("Found machine check recoverable ranges.\n");
 
 	/*
+	 * Calculate number of available entries.
+	 *
+	 * Each recoverable address range entry is (start address, len,
+	 * recovery address), 2 cells each for start and recovery address,
+	 * 1 cell for len, totalling 5 cells per entry.
+	 */
+	mc_recoverable_range_len = psize / (sizeof(*prop) * 5);
+
+	/* Sanity check */
+	if (!mc_recoverable_range_len)
+		return 1;
+
+	/* Size required to hold all the entries. */
+	size = mc_recoverable_range_len *
+			sizeof(struct mcheck_recoverable_range);
+
+	/*
 	 * Allocate a buffer to hold the MC recoverable ranges. We would be
 	 * accessing them in real mode, hence it needs to be within
 	 * RMO region.
@@ -124,11 +141,7 @@ int __init early_init_dt_scan_recoverable_ranges(unsigned long node,
 							ppc64_rma_size));
 	memset(mc_recoverable_range, 0, size);
 
-	/*
-	 * Each recoverable address entry is an (start address,len,
-	 * recover address) pair, * 2 cells each, totalling 4 cells per entry.
-	 */
-	for (i = 0; i < size / (sizeof(*prop) * 5); i++) {
+	for (i = 0; i < mc_recoverable_range_len; i++) {
 		mc_recoverable_range[i].start_addr =
 					of_read_number(prop + (i * 5) + 0, 2);
 		mc_recoverable_range[i].end_addr =
@@ -142,7 +155,6 @@ int __init early_init_dt_scan_recoverable_ranges(unsigned long node,
 				mc_recoverable_range[i].end_addr,
 				mc_recoverable_range[i].recover_addr);
 	}
-	mc_recoverable_range_len = i;
 	return 1;
 }
 

^ permalink raw reply related

* Re: [PATCH 1/2] powerpc/powernv: Add OPAL message log interface
From: Stewart Smith @ 2014-03-30 22:21 UTC (permalink / raw)
  To: Joel Stanley, benh, paulus, anton, shangw, hegdevasant, michael
  Cc: linuxppc-dev
In-Reply-To: <1395964240-8305-2-git-send-email-joel@jms.id.au>

Joel Stanley <joel@jms.id.au> writes:
> OPAL provides an in-memory circular buffer containing a message log
> populated with various runtime messages produced by the firmware.
>
> Provide a sysfs interface /sys/firmware/opal/messages for userspace to
> view the messages.

Acked-by: Stewart Smith <stewart@linux.vnet.ibm.com>

> Signed-off-by: Joel Stanley <joel@jms.id.au>
> ---
>  arch/powerpc/include/asm/opal.h                |  4 ++
>  arch/powerpc/platforms/powernv/Makefile        |  1 +
>  arch/powerpc/platforms/powernv/opal-messages.c | 97 ++++++++++++++++++++++++++
>  arch/powerpc/platforms/powernv/opal.c          |  4 +-
>  4 files changed, 105 insertions(+), 1 deletion(-)
>  create mode 100644 arch/powerpc/platforms/powernv/opal-messages.c
>
> diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
> index ffafab0..6aa757e 100644
> --- a/arch/powerpc/include/asm/opal.h
> +++ b/arch/powerpc/include/asm/opal.h
> @@ -729,6 +729,9 @@ typedef struct oppanel_line {
>  /* /sys/firmware/opal */
>  extern struct kobject *opal_kobj;
>
> +/* /ibm,opal */
> +extern struct device_node *opal_node;
> +
>  /* API functions */
>  int64_t opal_console_write(int64_t term_number, __be64 *length,
>  			   const uint8_t *buffer);
> @@ -918,6 +921,7 @@ extern void opal_flash_init(void);
>  extern int opal_elog_init(void);
>  extern void opal_platform_dump_init(void);
>  extern void opal_sys_param_init(void);
> +extern void opal_messages_init(void);
>
>  extern int opal_machine_check(struct pt_regs *regs);
>  extern bool opal_mce_check_early_recovery(struct pt_regs *regs);
> diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile
> index f324ea0..e2ba418 100644
> --- a/arch/powerpc/platforms/powernv/Makefile
> +++ b/arch/powerpc/platforms/powernv/Makefile
> @@ -1,6 +1,7 @@
>  obj-y			+= setup.o opal-takeover.o opal-wrappers.o opal.o opal-async.o
>  obj-y			+= opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o
>  obj-y			+= rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o
> +obj-y			+= opal-messages.o
>
>  obj-$(CONFIG_SMP)	+= smp.o
>  obj-$(CONFIG_PCI)	+= pci.o pci-p5ioc2.o pci-ioda.o
> diff --git a/arch/powerpc/platforms/powernv/opal-messages.c b/arch/powerpc/platforms/powernv/opal-messages.c
> new file mode 100644
> index 0000000..3a863e8
> --- /dev/null
> +++ b/arch/powerpc/platforms/powernv/opal-messages.c
> @@ -0,0 +1,97 @@
> +/*
> + * PowerNV OPAL in-memory console interface
> + *
> + * Copyright 2014 IBM Corp.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +
> +#include <asm/io.h>
> +#include <asm/opal.h>
> +#include <linux/debugfs.h>
> +#include <linux/of.h>
> +#include <linux/types.h>
> +
> +/* OPAL in-memory console. Defined in OPAL source at core/console.c */
> +struct memcons {
> +	__be64 magic;
> +#define MEMCONS_MAGIC	0x6630696567726173L
> +	__be64 obuf_phys;
> +	__be64 ibuf_phys;
> +	__be32 obuf_size;
> +	__be32 ibuf_size;
> +	__be32 out_pos;
> +#define MEMCONS_OUT_POS_WRAP	0x80000000u
> +#define MEMCONS_OUT_POS_MASK	0x00ffffffu
> +	__be32 in_prod;
> +	__be32 in_cons;
> +};
> +
> +static ssize_t opal_messages_read(struct file *file, struct kobject *kobj,
> +	struct bin_attribute *bin_attr, char *to, loff_t pos, size_t count)
> +{
> +	struct memcons *mc = bin_attr->private;
> +	const char *conbuf;
> +	bool wrapped;
> +	size_t num_read;
> +	int out_pos;
> +
> +	if (!mc)
> +		return -ENODEV;
> +
> +	conbuf = phys_to_virt(be64_to_cpu(mc->obuf_phys));
> +	wrapped = be32_to_cpu(mc->out_pos) & MEMCONS_OUT_POS_WRAP;
> +	out_pos = be32_to_cpu(mc->out_pos) & MEMCONS_OUT_POS_MASK;
> +
> +	if (!wrapped) {
> +		num_read = memory_read_from_buffer(to, count, &pos, conbuf,
> +				out_pos);
> +	} else {
> +		num_read = memory_read_from_buffer(to, count, &pos,
> +				conbuf + out_pos,
> +				be32_to_cpu(mc->obuf_size) - out_pos);
> +
> +		if (num_read < 0)
> +			goto out;
> +
> +		num_read += memory_read_from_buffer(to + num_read,
> +				count - num_read, &pos, conbuf, out_pos);
> +	}
> +out:
> +	return num_read;
> +}
> +
> +static struct bin_attribute messages_attr = {
> +	.attr = {.name = "messages", .mode = 0444},
> +	.read = opal_messages_read
> +};
> +
> +void __init opal_messages_init(void)
> +{
> +	u64 mcaddr;
> +	struct memcons *mc;
> +
> +	if (of_property_read_u64(opal_node, "ibm,opal-memcons", &mcaddr)) {
> +		pr_warn("OPAL: Property ibm,opal-memcons not found, no message log\n");
> +		return;
> +	}
> +
> +	mc = phys_to_virt(mcaddr);
> +	if (!mc) {
> +		pr_warn("OPAL: memory console address is invalid\n");
> +		return;
> +	}
> +
> +	if (be64_to_cpu(mc->magic) != MEMCONS_MAGIC) {
> +		pr_warn("OPAL: memory console version is invalid\n");
> +		return;
> +	}
> +
> +	messages_attr.private = mc;
> +
> +	if (sysfs_create_bin_file(opal_kobj, &messages_attr) != 0)
> +		pr_warn("OPAL: sysfs file creation failed\n");
> +}
> diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
> index e92f2f6..2bc032a 100644
> --- a/arch/powerpc/platforms/powernv/opal.c
> +++ b/arch/powerpc/platforms/powernv/opal.c
> @@ -46,7 +46,7 @@ struct mcheck_recoverable_range {
>  static struct mcheck_recoverable_range *mc_recoverable_range;
>  static int mc_recoverable_range_len;
>
> -static struct device_node *opal_node;
> +struct device_node *opal_node;
>  static DEFINE_SPINLOCK(opal_write_lock);
>  extern u64 opal_mc_secondary_handler[];
>  static unsigned int *opal_irqs;
> @@ -574,6 +574,8 @@ static int __init opal_init(void)
>  		opal_platform_dump_init();
>  		/* Setup system parameters interface */
>  		opal_sys_param_init();
> +		/* Setup message log interface. */
> +		opal_messages_init();
>  	}
>
>  	return 0;
> -- 
> 1.9.1

^ permalink raw reply

* Re: [PATCH] powerpc/le: enable RTAS events support
From: Stewart Smith @ 2014-03-30 22:27 UTC (permalink / raw)
  To: Greg Kurz, benh; +Cc: nfont, linuxppc-dev, paulus, linux-kernel, anton
In-Reply-To: <20140328073344.26823.32931.stgit@bahia.local>

Greg Kurz <gkurz@linux.vnet.ibm.com> writes:
>  struct rtas_error_log {
> +#ifdef __BIG_ENDIAN__
> +	/* Byte 0 */
>  	unsigned long version:8;		/* Architectural version */
> +	/* Byte 1 */

I think it would be great if we got rid of the usage of bitfields. As
soon as the mood of the compiler changes, this code is going to break.

^ permalink raw reply

* Re: [PATCH 1/2] powerpc/powernv: Add OPAL message log interface
From: Michael Neuling @ 2014-03-31  4:08 UTC (permalink / raw)
  To: Joel Stanley
  Cc: stewart, michael, shangw, hegdevasant, paulus, anton,
	linuxppc-dev
In-Reply-To: <1395964240-8305-2-git-send-email-joel@jms.id.au>

Joel Stanley <joel@jms.id.au> wrote:

> OPAL provides an in-memory circular buffer containing a message log
> populated with various runtime messages produced by the firmware.
> 
> Provide a sysfs interface /sys/firmware/opal/messages for userspace to
> view the messages.
> 
> Signed-off-by: Joel Stanley <joel@jms.id.au>
> ---
>  arch/powerpc/include/asm/opal.h                |  4 ++
>  arch/powerpc/platforms/powernv/Makefile        |  1 +
>  arch/powerpc/platforms/powernv/opal-messages.c | 97 ++++++++++++++++++++++++++
>  arch/powerpc/platforms/powernv/opal.c          |  4 +-
>  4 files changed, 105 insertions(+), 1 deletion(-)
>  create mode 100644 arch/powerpc/platforms/powernv/opal-messages.c
> 
> diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
> index ffafab0..6aa757e 100644
> --- a/arch/powerpc/include/asm/opal.h
> +++ b/arch/powerpc/include/asm/opal.h
> @@ -729,6 +729,9 @@ typedef struct oppanel_line {
>  /* /sys/firmware/opal */
>  extern struct kobject *opal_kobj;
>  
> +/* /ibm,opal */
> +extern struct device_node *opal_node;
> +
>  /* API functions */
>  int64_t opal_console_write(int64_t term_number, __be64 *length,
>  			   const uint8_t *buffer);
> @@ -918,6 +921,7 @@ extern void opal_flash_init(void);
>  extern int opal_elog_init(void);
>  extern void opal_platform_dump_init(void);
>  extern void opal_sys_param_init(void);
> +extern void opal_messages_init(void);
>  
>  extern int opal_machine_check(struct pt_regs *regs);
>  extern bool opal_mce_check_early_recovery(struct pt_regs *regs);
> diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile
> index f324ea0..e2ba418 100644
> --- a/arch/powerpc/platforms/powernv/Makefile
> +++ b/arch/powerpc/platforms/powernv/Makefile
> @@ -1,6 +1,7 @@
>  obj-y			+= setup.o opal-takeover.o opal-wrappers.o opal.o opal-async.o
>  obj-y			+= opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o
>  obj-y			+= rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o
> +obj-y			+= opal-messages.o
>  
>  obj-$(CONFIG_SMP)	+= smp.o
>  obj-$(CONFIG_PCI)	+= pci.o pci-p5ioc2.o pci-ioda.o
> diff --git a/arch/powerpc/platforms/powernv/opal-messages.c b/arch/powerpc/platforms/powernv/opal-messages.c
> new file mode 100644
> index 0000000..3a863e8
> --- /dev/null
> +++ b/arch/powerpc/platforms/powernv/opal-messages.c
> @@ -0,0 +1,97 @@
> +/*
> + * PowerNV OPAL in-memory console interface
> + *
> + * Copyright 2014 IBM Corp.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +
> +#include <asm/io.h>
> +#include <asm/opal.h>
> +#include <linux/debugfs.h>
> +#include <linux/of.h>
> +#include <linux/types.h>
> +
> +/* OPAL in-memory console. Defined in OPAL source at core/console.c */
> +struct memcons {
> +	__be64 magic;
> +#define MEMCONS_MAGIC	0x6630696567726173L

0x6630696567726173 == f0iegras ... Ben!!! :-P

> +	__be64 obuf_phys;
> +	__be64 ibuf_phys;
> +	__be32 obuf_size;
> +	__be32 ibuf_size;
> +	__be32 out_pos;
> +#define MEMCONS_OUT_POS_WRAP	0x80000000u
> +#define MEMCONS_OUT_POS_MASK	0x00ffffffu
> +	__be32 in_prod;
> +	__be32 in_cons;
> +};
> +
> +static ssize_t opal_messages_read(struct file *file, struct kobject *kobj,
> +	struct bin_attribute *bin_attr, char *to, loff_t pos, size_t count)
> +{
> +	struct memcons *mc = bin_attr->private;
> +	const char *conbuf;
> +	bool wrapped;
> +	size_t num_read;
> +	int out_pos;
> +
> +	if (!mc)
> +		return -ENODEV;
> +
> +	conbuf = phys_to_virt(be64_to_cpu(mc->obuf_phys));
> +	wrapped = be32_to_cpu(mc->out_pos) & MEMCONS_OUT_POS_WRAP;
> +	out_pos = be32_to_cpu(mc->out_pos) & MEMCONS_OUT_POS_MASK;
> +

Are there ordering issues we need to think about here with reading
these?  Can the messages be written on another CPU at the same time as
these are being read?

What happens if in between reading wrapped and out_pos the buffer wraps?
You'd end up getting only a few bytes of console?  Maybe you need to
read wrapped before and after out_pos to make should it's not wrapped in
between.

> +	if (!wrapped) {

Why the negative case first?  Just make it:

   if (wrapped) {
      wrapped case
   } else {
      not wrapped case
   }

Also, no curlies needed for single statement.


> +		num_read = memory_read_from_buffer(to, count, &pos, conbuf,
> +				out_pos);

This is probably not necessary, but do we need to sanity check out_pos <
obuf_size?  I guess we don't generally sanity check numbers from OPAL as
it can screw us in many other ways anyway.

> +	} else {
> +		num_read = memory_read_from_buffer(to, count, &pos,
> +				conbuf + out_pos,
> +				be32_to_cpu(mc->obuf_size) - out_pos);
> +
> +		if (num_read < 0)
> +			goto out;
> +
> +		num_read += memory_read_from_buffer(to + num_read,
> +				count - num_read, &pos, conbuf,
>                out_pos);

What if this second read returns an error?  num_read += -ERRNO?  I think
you need to check this return independently.

Mikey

> +	}
> +out:
> +	return num_read;
> +}
> +
> +static struct bin_attribute messages_attr = {
> +	.attr = {.name = "messages", .mode = 0444},
> +	.read = opal_messages_read
> +};
> +
> +void __init opal_messages_init(void)
> +{
> +	u64 mcaddr;
> +	struct memcons *mc;
> +
> +	if (of_property_read_u64(opal_node, "ibm,opal-memcons", &mcaddr)) {
> +		pr_warn("OPAL: Property ibm,opal-memcons not found, no message log\n");
> +		return;
> +	}
> +
> +	mc = phys_to_virt(mcaddr);
> +	if (!mc) {
> +		pr_warn("OPAL: memory console address is invalid\n");
> +		return;
> +	}
> +
> +	if (be64_to_cpu(mc->magic) != MEMCONS_MAGIC) {
> +		pr_warn("OPAL: memory console version is invalid\n");
> +		return;
> +	}
> +
> +	messages_attr.private = mc;
> +
> +	if (sysfs_create_bin_file(opal_kobj, &messages_attr) != 0)
> +		pr_warn("OPAL: sysfs file creation failed\n");
> +}
> diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
> index e92f2f6..2bc032a 100644
> --- a/arch/powerpc/platforms/powernv/opal.c
> +++ b/arch/powerpc/platforms/powernv/opal.c
> @@ -46,7 +46,7 @@ struct mcheck_recoverable_range {
>  static struct mcheck_recoverable_range *mc_recoverable_range;
>  static int mc_recoverable_range_len;
>  
> -static struct device_node *opal_node;
> +struct device_node *opal_node;
>  static DEFINE_SPINLOCK(opal_write_lock);
>  extern u64 opal_mc_secondary_handler[];
>  static unsigned int *opal_irqs;
> @@ -574,6 +574,8 @@ static int __init opal_init(void)
>  		opal_platform_dump_init();
>  		/* Setup system parameters interface */
>  		opal_sys_param_init();
> +		/* Setup message log interface. */
> +		opal_messages_init();
>  	}
>  
>  	return 0;
> -- 
> 1.9.1
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

^ permalink raw reply

* Re: [PATCH 6/7] DMA: Freescale: use spin_lock_bh instead of spin_lock_irqsave
From: Hongbo Zhang @ 2014-03-31  4:08 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Vinod Koul, linux-kernel, scottwood, dmaengine, dan.j.williams,
	linuxppc-dev
In-Reply-To: <20140329134528.GQ1976@intel.com>


On 03/29/2014 09:45 PM, Vinod Koul wrote:
> On Fri, Mar 28, 2014 at 02:33:37PM +0800, Hongbo Zhang wrote:
>> On 03/26/2014 03:01 PM, Vinod Koul wrote:
>>> On Thu, 2014-01-16 at 13:47 +0800, hongbo.zhang@freescale.com wrote:
>>>> From: Hongbo Zhang <hongbo.zhang@freescale.com>
>>>>
>>>> The usage of spin_lock_irqsave() is a stronger locking mechanism than is
>>>> required throughout the driver. The minimum locking required should be used
>>>> instead. Interrupts will be turned off and context will be saved, it is
>>>> unnecessary to use irqsave.
>>>>
>>>> This patch changes all instances of spin_lock_irqsave() to spin_lock_bh(). All
>>>> manipulation of protected fields is done using tasklet context or weaker, which
>>>> makes spin_lock_bh() the correct choice.
>>>>
>
>>>>   /**
>>>> @@ -1124,11 +1120,10 @@ static irqreturn_t fsldma_chan_irq(int irq, void *data)
>>>>   static void dma_do_tasklet(unsigned long data)
>>>>   {
>>>>   	struct fsldma_chan *chan = (struct fsldma_chan *)data;
>>>> -	unsigned long flags;
>>>>   	chan_dbg(chan, "tasklet entry\n");
>>>> -	spin_lock_irqsave(&chan->desc_lock, flags);
>>>> +	spin_lock_bh(&chan->desc_lock);
>>> okay here is the problem :(
>>>
>>> You moved to _bh variant. So if you grab the lock in rest of the code
>>> and irq gets triggered then here we will be spinning to grab the lock.
>>> So effectively you made right locking solution into deadlock situation!
>> If the rest code grabs lock by spin_lock_bh(), and if irq raised,
>> the tasklet could not be executed because it has been disabled by
>> the _bh variant function.
> yes if you are accessing resources only in tasklet and rest of the code, then
> _bh variant works well. The problem here is usage in irq handler
>

The name dma_do_tasklet may mislead, it is tasklet handler, not irq 
handler, not a trigger to load tasklet.
the irq handler is fsldma_chan_irq, and I don't use lock in it.

If it is the problem, I would like to change dma_do_tasklet to 
dma_tasklet to eliminate misleading.

^ permalink raw reply

* Re: [PATCH v5 1/3] powernv, cpufreq: Select CPUFreq related Kconfig options for powernv
From: Viresh Kumar @ 2014-03-31  4:21 UTC (permalink / raw)
  To: Gautham R. Shenoy
  Cc: Linux PM list, Rafael J. Wysocki, Linux Kernel Mailing List,
	cpufreq@vger.kernel.org, linuxppc-dev@ozlabs.org, Anton Blanchard,
	Srivatsa S. Bhat
In-Reply-To: <1396037484-23907-2-git-send-email-ego@linux.vnet.ibm.com>

On 29 March 2014 01:41, Gautham R. Shenoy <ego@linux.vnet.ibm.com> wrote:
> From: "Gautham R. Shenoy" <ego@linux.vnet.ibm.com>
>
> Enable CPUFreq for PowerNV. Select "performance", "powersave",
> "userspace" and "ondemand" governors. Choose "ondemand" to be the
> default governor.
>
> Signed-off-by: Gautham R. Shenoy <ego@linux.vnet.ibm.com>
> Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
> ---
>  arch/powerpc/configs/pseries_defconfig    | 1 +
>  arch/powerpc/configs/pseries_le_defconfig | 1 +
>  arch/powerpc/platforms/powernv/Kconfig    | 6 ++++++
>  3 files changed, 8 insertions(+)

Probably it doesn't make much sense to keep this as the first patch
as you still don't have the driver available yet.

^ permalink raw reply

* Re: [PATCH 1/2] powerpc/powernv: Add OPAL message log interface
From: Michael Neuling @ 2014-03-31  4:21 UTC (permalink / raw)
  Cc: stewart, michael, shangw, hegdevasant, paulus, Joel Stanley,
	linuxppc-dev, anton
In-Reply-To: <21604.1396238935@ale.ozlabs.ibm.com>

Michael Neuling <mikey@neuling.org> wrote:

> Joel Stanley <joel@jms.id.au> wrote:
> 
> > OPAL provides an in-memory circular buffer containing a message log
> > populated with various runtime messages produced by the firmware.
> > 
> > Provide a sysfs interface /sys/firmware/opal/messages for userspace to
> > view the messages.
> > 
> > Signed-off-by: Joel Stanley <joel@jms.id.au>
> > ---
> >  arch/powerpc/include/asm/opal.h                |  4 ++
> >  arch/powerpc/platforms/powernv/Makefile        |  1 +
> >  arch/powerpc/platforms/powernv/opal-messages.c | 97 ++++++++++++++++++++++++++
> >  arch/powerpc/platforms/powernv/opal.c          |  4 +-
> >  4 files changed, 105 insertions(+), 1 deletion(-)
> >  create mode 100644 arch/powerpc/platforms/powernv/opal-messages.c
> > 
> > diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
> > index ffafab0..6aa757e 100644
> > --- a/arch/powerpc/include/asm/opal.h
> > +++ b/arch/powerpc/include/asm/opal.h
> > @@ -729,6 +729,9 @@ typedef struct oppanel_line {
> >  /* /sys/firmware/opal */
> >  extern struct kobject *opal_kobj;
> >  
> > +/* /ibm,opal */
> > +extern struct device_node *opal_node;
> > +
> >  /* API functions */
> >  int64_t opal_console_write(int64_t term_number, __be64 *length,
> >  			   const uint8_t *buffer);
> > @@ -918,6 +921,7 @@ extern void opal_flash_init(void);
> >  extern int opal_elog_init(void);
> >  extern void opal_platform_dump_init(void);
> >  extern void opal_sys_param_init(void);
> > +extern void opal_messages_init(void);
> >  
> >  extern int opal_machine_check(struct pt_regs *regs);
> >  extern bool opal_mce_check_early_recovery(struct pt_regs *regs);
> > diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile
> > index f324ea0..e2ba418 100644
> > --- a/arch/powerpc/platforms/powernv/Makefile
> > +++ b/arch/powerpc/platforms/powernv/Makefile
> > @@ -1,6 +1,7 @@
> >  obj-y			+= setup.o opal-takeover.o opal-wrappers.o opal.o opal-async.o
> >  obj-y			+= opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o
> >  obj-y			+= rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o
> > +obj-y			+= opal-messages.o
> >  
> >  obj-$(CONFIG_SMP)	+= smp.o
> >  obj-$(CONFIG_PCI)	+= pci.o pci-p5ioc2.o pci-ioda.o
> > diff --git a/arch/powerpc/platforms/powernv/opal-messages.c b/arch/powerpc/platforms/powernv/opal-messages.c
> > new file mode 100644
> > index 0000000..3a863e8
> > --- /dev/null
> > +++ b/arch/powerpc/platforms/powernv/opal-messages.c
> > @@ -0,0 +1,97 @@
> > +/*
> > + * PowerNV OPAL in-memory console interface
> > + *
> > + * Copyright 2014 IBM Corp.
> > + *
> > + * This program is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU General Public License
> > + * as published by the Free Software Foundation; either version
> > + * 2 of the License, or (at your option) any later version.
> > + */
> > +
> > +#include <asm/io.h>
> > +#include <asm/opal.h>
> > +#include <linux/debugfs.h>
> > +#include <linux/of.h>
> > +#include <linux/types.h>
> > +
> > +/* OPAL in-memory console. Defined in OPAL source at core/console.c */
> > +struct memcons {
> > +	__be64 magic;
> > +#define MEMCONS_MAGIC	0x6630696567726173L
> 
> 0x6630696567726173 == f0iegras ... Ben!!! :-P
> 
> > +	__be64 obuf_phys;
> > +	__be64 ibuf_phys;
> > +	__be32 obuf_size;
> > +	__be32 ibuf_size;
> > +	__be32 out_pos;
> > +#define MEMCONS_OUT_POS_WRAP	0x80000000u
> > +#define MEMCONS_OUT_POS_MASK	0x00ffffffu
> > +	__be32 in_prod;
> > +	__be32 in_cons;
> > +};
> > +
> > +static ssize_t opal_messages_read(struct file *file, struct kobject *kobj,
> > +	struct bin_attribute *bin_attr, char *to, loff_t pos, size_t count)
> > +{
> > +	struct memcons *mc = bin_attr->private;
> > +	const char *conbuf;
> > +	bool wrapped;
> > +	size_t num_read;
> > +	int out_pos;
> > +
> > +	if (!mc)
> > +		return -ENODEV;
> > +
> > +	conbuf = phys_to_virt(be64_to_cpu(mc->obuf_phys));
> > +	wrapped = be32_to_cpu(mc->out_pos) & MEMCONS_OUT_POS_WRAP;
> > +	out_pos = be32_to_cpu(mc->out_pos) & MEMCONS_OUT_POS_MASK;
> > +
> 
> Are there ordering issues we need to think about here with reading
> these?  Can the messages be written on another CPU at the same time as
> these are being read?
> 
> What happens if in between reading wrapped and out_pos the buffer wraps?
> You'd end up getting only a few bytes of console?  Maybe you need to
> read wrapped before and after out_pos to make should it's not wrapped in
> between.

wrapped = be32_to_cpu(mc->out_pos) & MEMCONS_OUT_POS_WRAP;
out_pos = be32_to_cpu(mc->out_pos) & MEMCONS_OUT_POS_MASK;

OK, I just realised this is reading from the same location.  So yeah,
don't do that.  Read it once and calculate wrapped and out_pos from that
single read.

> 
> > +	if (!wrapped) {
> 
> Why the negative case first?  Just make it:
> 
>    if (wrapped) {
>       wrapped case
>    } else {
>       not wrapped case
>    }
> 
> Also, no curlies needed for single statement.
> 
> 
> > +		num_read = memory_read_from_buffer(to, count, &pos, conbuf,
> > +				out_pos);
> 
> This is probably not necessary, but do we need to sanity check out_pos <
> obuf_size?  I guess we don't generally sanity check numbers from OPAL as
> it can screw us in many other ways anyway.
> 
> > +	} else {
> > +		num_read = memory_read_from_buffer(to, count, &pos,
> > +				conbuf + out_pos,
> > +				be32_to_cpu(mc->obuf_size) - out_pos);
> > +
> > +		if (num_read < 0)
> > +			goto out;
> > +
> > +		num_read += memory_read_from_buffer(to + num_read,
> > +				count - num_read, &pos, conbuf,
> >                out_pos);
> 
> What if this second read returns an error?  num_read += -ERRNO?  I think
> you need to check this return independently.
> 
> Mikey
> 
> > +	}
> > +out:
> > +	return num_read;
> > +}
> > +
> > +static struct bin_attribute messages_attr = {
> > +	.attr = {.name = "messages", .mode = 0444},
> > +	.read = opal_messages_read
> > +};
> > +
> > +void __init opal_messages_init(void)
> > +{
> > +	u64 mcaddr;
> > +	struct memcons *mc;
> > +
> > +	if (of_property_read_u64(opal_node, "ibm,opal-memcons", &mcaddr)) {
> > +		pr_warn("OPAL: Property ibm,opal-memcons not found, no message log\n");
> > +		return;
> > +	}
> > +
> > +	mc = phys_to_virt(mcaddr);
> > +	if (!mc) {
> > +		pr_warn("OPAL: memory console address is invalid\n");
> > +		return;
> > +	}
> > +
> > +	if (be64_to_cpu(mc->magic) != MEMCONS_MAGIC) {
> > +		pr_warn("OPAL: memory console version is invalid\n");
> > +		return;
> > +	}
> > +
> > +	messages_attr.private = mc;
> > +
> > +	if (sysfs_create_bin_file(opal_kobj, &messages_attr) != 0)
> > +		pr_warn("OPAL: sysfs file creation failed\n");
> > +}
> > diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
> > index e92f2f6..2bc032a 100644
> > --- a/arch/powerpc/platforms/powernv/opal.c
> > +++ b/arch/powerpc/platforms/powernv/opal.c
> > @@ -46,7 +46,7 @@ struct mcheck_recoverable_range {
> >  static struct mcheck_recoverable_range *mc_recoverable_range;
> >  static int mc_recoverable_range_len;
> >  
> > -static struct device_node *opal_node;
> > +struct device_node *opal_node;
> >  static DEFINE_SPINLOCK(opal_write_lock);
> >  extern u64 opal_mc_secondary_handler[];
> >  static unsigned int *opal_irqs;
> > @@ -574,6 +574,8 @@ static int __init opal_init(void)
> >  		opal_platform_dump_init();
> >  		/* Setup system parameters interface */
> >  		opal_sys_param_init();
> > +		/* Setup message log interface. */
> > +		opal_messages_init();
> >  	}
> >  
> >  	return 0;
> > -- 
> > 1.9.1
> > 
> > _______________________________________________
> > Linuxppc-dev mailing list
> > Linuxppc-dev@lists.ozlabs.org
> > https://lists.ozlabs.org/listinfo/linuxppc-dev

^ permalink raw reply

* Re: [PATCH v5 0/3] powernv, cpufreq: Dynamic Frequency Scaling support
From: Viresh Kumar @ 2014-03-31  4:25 UTC (permalink / raw)
  To: Gautham R. Shenoy
  Cc: Linux PM list, Rafael J. Wysocki, Linux Kernel Mailing List,
	cpufreq@vger.kernel.org, linuxppc-dev@ozlabs.org, Anton Blanchard,
	Srivatsa S. Bhat
In-Reply-To: <1396037484-23907-1-git-send-email-ego@linux.vnet.ibm.com>

On 29 March 2014 01:41, Gautham R. Shenoy <ego@linux.vnet.ibm.com> wrote:
> From: "Gautham R. Shenoy" <ego@linux.vnet.ibm.com>
>
> Hi,
>
> This is v5 of the patchset to enable dynamic frequency scaling on IBM
> PowerNV platforms. This patchset does address all the review comments
> obtained for v4 (which can be found at [1]).
>
> Changes from v4:
>
>     * Created a separate patch to select the CPUFreq related Config
>       options for PowerNV
>
>     * Dropped the per-core locking hunks in
>       drivers/cpufreq/powernv-cpufreq.c since the CPUFreq core takes
>       care of the for us after the following commit which is present in
>       linux-next:
>
>         commit 12478cf0c55e5969f740bb38a24b1a0104ae18d8
>         Author: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
>         Date:   Mon Mar 24 13:35:44 2014 +0530
>
>         cpufreq: Make sure frequency transitions are serialized
>
>     * [PATCH v5 3/3] gets rid of the powernv_pstate_ids[] array that
>       was being used to record the pstate ids. After the following
>       patch it is safe to use cpufreq_frequency_table.driver_data
>       since it is opaque to the cpufreq core:
>
>         From: Viresh Kumar <viresh.kumar@linaro.org>
>         Date: 2014-03-28 13:53:47
>         url: http://marc.info/?l=linux-pm&m=139601416804702&w=2
>
>         cpufreq: create another field .flags in cpufreq_frequency_table
>
> The patchset is based on the commit
> 201544be8c37dffbf069bb5fc9edb5674f8c1754 of the linux-next tree.
>
> While all the patches in the patchset apply cleanly on linux-next,
> [PATCH v5 3/3] requires the Viresh's patch that was mentioned
> above. Otherwise, the frequency corresponding to pstate id -3 will be
> omited while reporting the "scaling_available_frequencies" in sysfs.
>
> [1]: http://marc.info/?l=linux-pm&m=139585297620612&w=2
>
> Gautham R. Shenoy (2):
>   powernv, cpufreq: Select CPUFreq related Kconfig options for powernv

Make this patch 3/3 (Probably Rafael can do this while applying)

>   powernv,cpufreq: Use cpufreq_frequency_table.driver_data to store
>     pstate ids
>
> Vaidyanathan Srinivasan (1):
>   powernv, cpufreq: cpufreq driver for powernv platform

Otherwise,

Acked-by: Viresh Kumar <viresh.kumar@linaro.org>

^ permalink raw reply

* RE: [PATCH v2] fix wrong usage of dmaengine_unmap_put in async_xxx
From: Xuelin Shi @ 2014-03-31  6:54 UTC (permalink / raw)
  To: vinod.koul@intel.com, dan.j.williams@intel.com
  Cc: dmaengine@vger.kernel.org, Xuelin Shi,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1395303385-29461-1-git-send-email-xuelin.shi@freescale.com>

SGkgRGFuICYgdmlub2QsDQoNCkhhdmUgeW91IGdvdCBhIGNoYW5jZSB0byBzZWUgdGhpcyBwYXRj
aD8NCg0KQWxzbyB3aGF0J3MgeW91ciBjb21tZW50IGFib3V0IHRoZSAgUmFpZEVuZ2luZSBkcml2
ZXIgcGF0Y2g/DQoNClRoYW5rcywNClh1ZWxpbiBTaGkNCg0KLS0tLS1PcmlnaW5hbCBNZXNzYWdl
LS0tLS0NCkZyb206IHh1ZWxpbi5zaGlAZnJlZXNjYWxlLmNvbSBbbWFpbHRvOnh1ZWxpbi5zaGlA
ZnJlZXNjYWxlLmNvbV0gDQpTZW50OiAyMDE0xOoz1MIyMMjVIDE2OjE2DQpUbzogdmlub2Qua291
bEBpbnRlbC5jb207IGRhbi5qLndpbGxpYW1zQGludGVsLmNvbQ0KQ2M6IGRtYWVuZ2luZUB2Z2Vy
Lmtlcm5lbC5vcmc7IGxpbnV4cHBjLWRldkBsaXN0cy5vemxhYnMub3JnOyBTaGkgWHVlbGluLUIy
OTIzNw0KU3ViamVjdDogW1BBVENIIHYyXSBmaXggd3JvbmcgdXNhZ2Ugb2YgZG1hZW5naW5lX3Vu
bWFwX3B1dCBpbiBhc3luY194eHgNCg0KRnJvbTogWHVlbGluIFNoaSA8eHVlbGluLnNoaUBmcmVl
c2NhbGUuY29tPg0KDQpkbWFlbmdpbmVfdW5tYXBfcHV0IGRvZXMgYmVsb3cgdHdvIHRoaW5nczoN
CmEpIHVubWFwIHBhZ2VzIGZvciBzcmNzIGFuZCBkZXN0cw0KYikgZnJlZSB1bm1hcCBzdHJ1Y3QN
Cg0KVGhlIHVubWFwIHN0cnVjdCBkYXRhIGlzIGdlbmVyYXRlZCBidXQgb25seSBpbml0aWFsaXpl
ZCB3aGlsZSBvdGhlciBzb21lIGRtYSBjb250aW9ucyBhcmUgbWV0LCBsaWtlIGRtYSBhbGlnbm1l
bnQgZXRjLg0KSWYgdGhlIHVubWFwIGRhdGEgaXMgbm90IGluaXRpYWxpemVkLCBjYWxsIGRtYWVu
Z2luZV91bm1hcF9wdXQgd2lsbCB1bm1hcCBzb21lIHJhbmRvbSBkYXRhIGluIHVubWFwLT5hZGRy
Wy4uLl0NCg0KQWxzbyBjYWxsIGRtYWVuZ2luZV9nZXRfdW5tYXBfZGF0YSBpbW1lZGlhdGFsbHkg
YWZ0ZXIgZ2VuZXJhdGluZyB0eCBpcyBub3QgY29ycmVjdC4gTWF5YmUgdGhlIHR4IGhhcyBub3Qg
YmVlbiBmaW5pc2hlZCBieSBETUEgaGFyZHdhcmUgeWV0IGJ1dCB0aGUgc3JjcyBhbmQgZGVzdHMg
YXJlIGRtYSB1bm1hcHBlZC4NCg0KVGhpcyBwYXRjaCBmaXhlZCBhYm92ZSB0d28gaXNzdWVzIGJ5
Og0KYSkgb25seSBnZW5lcmF0ZXMgdW5tYXAgc3RydWN0IGRhdGEgd2hlbiBvdGhlciBkbWEgY29u
ZGl0aW9ucyBhcmUgbWV0Lg0KYikgZWxpbWluYXRlcyBkbWFlbmdpbmVfdW5tYXBfcHV0IHdoZW4g
dHggaXMgZ2VuZXJhdGVkIGJlY2F1c2UgdHgga25vd2VzIHRoZSBiZXN0IHRpbWUgdG8gdW5tYXAg
aXQgKGluIGludGVycnVwdCBwcm9jZXNzaW5nKS4NCg0KU2lnbmVkLW9mZi1ieTogWHVlbGluIFNo
aSA8eHVlbGluLnNoaUBmcmVlc2NhbGUuY29tPg0KLS0tDQpjaGFuZ2UgbG9nOg0KCXYxOiBpbmNs
dWRlIGNoYW5nZSBpbiBhc3luY19tZW1jcHksIGFzeW5jX3hvciwgYXN5bmNfcHENCiAJdjI6IGFk
ZCBjaGFuZ2UgaW4gYXN5bmNfcmFpZDZfcmVjb3YuYyBhbmQgZml4IHNvbWUgc3R5bGUgaXNzdWUN
Cg0KIGNyeXB0by9hc3luY190eC9hc3luY19tZW1jcHkuYyAgICAgIHwgIDgwICsrKysrKysrLS0t
LS0tLQ0KIGNyeXB0by9hc3luY190eC9hc3luY19wcS5jICAgICAgICAgIHwgMTg5ICsrKysrKysr
KysrKysrKysrKystLS0tLS0tLS0tLS0tLS0tLQ0KIGNyeXB0by9hc3luY190eC9hc3luY19yYWlk
Nl9yZWNvdi5jIHwgMTA4ICsrKysrKysrKysrLS0tLS0tLS0tLQ0KIGNyeXB0by9hc3luY190eC9h
c3luY194b3IuYyAgICAgICAgIHwgMTY0ICsrKysrKysrKysrKysrKystLS0tLS0tLS0tLS0tLS0N
CiA0IGZpbGVzIGNoYW5nZWQsIDI4NiBpbnNlcnRpb25zKCspLCAyNTUgZGVsZXRpb25zKC0pDQoN
CmRpZmYgLS1naXQgYS9jcnlwdG8vYXN5bmNfdHgvYXN5bmNfbWVtY3B5LmMgYi9jcnlwdG8vYXN5
bmNfdHgvYXN5bmNfbWVtY3B5LmMgaW5kZXggZjhjMGI4ZC4uNjU0NmU4NyAxMDA2NDQNCi0tLSBh
L2NyeXB0by9hc3luY190eC9hc3luY19tZW1jcHkuYw0KKysrIGIvY3J5cHRvL2FzeW5jX3R4L2Fz
eW5jX21lbWNweS5jDQpAQCAtNTEsMTEgKzUxLDEwIEBAIGFzeW5jX21lbWNweShzdHJ1Y3QgcGFn
ZSAqZGVzdCwgc3RydWN0IHBhZ2UgKnNyYywgdW5zaWduZWQgaW50IGRlc3Rfb2Zmc2V0LA0KIAlz
dHJ1Y3QgZG1hX2RldmljZSAqZGV2aWNlID0gY2hhbiA/IGNoYW4tPmRldmljZSA6IE5VTEw7DQog
CXN0cnVjdCBkbWFfYXN5bmNfdHhfZGVzY3JpcHRvciAqdHggPSBOVUxMOw0KIAlzdHJ1Y3QgZG1h
ZW5naW5lX3VubWFwX2RhdGEgKnVubWFwID0gTlVMTDsNCisJdm9pZCAqZGVzdF9idWYsICpzcmNf
YnVmOw0KIA0KLQlpZiAoZGV2aWNlKQ0KLQkJdW5tYXAgPSBkbWFlbmdpbmVfZ2V0X3VubWFwX2Rh
dGEoZGV2aWNlLT5kZXYsIDIsIEdGUF9OT0lPKTsNCi0NCi0JaWYgKHVubWFwICYmIGlzX2RtYV9j
b3B5X2FsaWduZWQoZGV2aWNlLCBzcmNfb2Zmc2V0LCBkZXN0X29mZnNldCwgbGVuKSkgew0KKwlp
ZiAoZGV2aWNlICYmDQorCSAgICBpc19kbWFfY29weV9hbGlnbmVkKGRldmljZSwgc3JjX29mZnNl
dCwgZGVzdF9vZmZzZXQsIGxlbikpIHsNCiAJCXVuc2lnbmVkIGxvbmcgZG1hX3ByZXBfZmxhZ3Mg
PSAwOw0KIA0KIAkJaWYgKHN1Ym1pdC0+Y2JfZm4pDQpAQCAtNjMsNDUgKzYyLDU2IEBAIGFzeW5j
X21lbWNweShzdHJ1Y3QgcGFnZSAqZGVzdCwgc3RydWN0IHBhZ2UgKnNyYywgdW5zaWduZWQgaW50
IGRlc3Rfb2Zmc2V0LA0KIAkJaWYgKHN1Ym1pdC0+ZmxhZ3MgJiBBU1lOQ19UWF9GRU5DRSkNCiAJ
CQlkbWFfcHJlcF9mbGFncyB8PSBETUFfUFJFUF9GRU5DRTsNCiANCi0JCXVubWFwLT50b19jbnQg
PSAxOw0KLQkJdW5tYXAtPmFkZHJbMF0gPSBkbWFfbWFwX3BhZ2UoZGV2aWNlLT5kZXYsIHNyYywg
c3JjX29mZnNldCwgbGVuLA0KLQkJCQkJICAgICAgRE1BX1RPX0RFVklDRSk7DQotCQl1bm1hcC0+
ZnJvbV9jbnQgPSAxOw0KLQkJdW5tYXAtPmFkZHJbMV0gPSBkbWFfbWFwX3BhZ2UoZGV2aWNlLT5k
ZXYsIGRlc3QsIGRlc3Rfb2Zmc2V0LCBsZW4sDQotCQkJCQkgICAgICBETUFfRlJPTV9ERVZJQ0Up
Ow0KLQkJdW5tYXAtPmxlbiA9IGxlbjsNCi0NCi0JCXR4ID0gZGV2aWNlLT5kZXZpY2VfcHJlcF9k
bWFfbWVtY3B5KGNoYW4sIHVubWFwLT5hZGRyWzFdLA0KLQkJCQkJCSAgICB1bm1hcC0+YWRkclsw
XSwgbGVuLA0KLQkJCQkJCSAgICBkbWFfcHJlcF9mbGFncyk7DQorCQl1bm1hcCA9IGRtYWVuZ2lu
ZV9nZXRfdW5tYXBfZGF0YShkZXZpY2UtPmRldiwgMiwgR0ZQX05PSU8pOw0KKwkJaWYgKHVubWFw
KSB7DQorCQkJdW5tYXAtPnRvX2NudCA9IDE7DQorCQkJdW5tYXAtPmFkZHJbMF0gPSBkbWFfbWFw
X3BhZ2UoZGV2aWNlLT5kZXYsIHNyYywNCisJCQkJCQkgICAgICBzcmNfb2Zmc2V0LCBsZW4sDQor
CQkJCQkJICAgICAgRE1BX1RPX0RFVklDRSk7DQorCQkJdW5tYXAtPmZyb21fY250ID0gMTsNCisJ
CQl1bm1hcC0+YWRkclsxXSA9IGRtYV9tYXBfcGFnZShkZXZpY2UtPmRldiwgZGVzdCwNCisJCQkJ
CQkgICAgICBkZXN0X29mZnNldCwgbGVuLA0KKwkJCQkJCSAgICAgIERNQV9GUk9NX0RFVklDRSk7
DQorCQkJdW5tYXAtPmxlbiA9IGxlbjsNCisNCisJCQl0eCA9IGRldmljZS0+ZGV2aWNlX3ByZXBf
ZG1hX21lbWNweShjaGFuLA0KKwkJCQkJCQkgICAgdW5tYXAtPmFkZHJbMV0sDQorCQkJCQkJCSAg
ICB1bm1hcC0+YWRkclswXSwNCisJCQkJCQkJICAgIGxlbiwNCisJCQkJCQkJICAgIGRtYV9wcmVw
X2ZsYWdzKTsNCisJCQlpZiAodHgpIHsNCisJCQkJcHJfZGVidWcoIiVzOiAoYXN5bmMpIGxlbjog
JXp1XG4iLCBfX2Z1bmNfXywNCisJCQkJCSBsZW4pOw0KKw0KKwkJCQlkbWFfc2V0X3VubWFwKHR4
LCB1bm1hcCk7DQorCQkJCWFzeW5jX3R4X3N1Ym1pdChjaGFuLCB0eCwgc3VibWl0KTsNCisJCQkJ
cmV0dXJuIHR4Ow0KKwkJCX0NCisNCisJCQkvKiBjb3VsZCBub3QgZ2V0IGEgZGVzY3JpcHRvciwg
dW5tYXAgYW5kIGZhbGwgdGhyb3VnaCB0bw0KKwkJCSAqIHRoZSBzeW5jaHJvbm91cyBwYXRoDQor
CQkJICovDQorCQkJZG1hZW5naW5lX3VubWFwX3B1dCh1bm1hcCk7DQorCQl9DQogCX0NCiANCi0J
aWYgKHR4KSB7DQotCQlwcl9kZWJ1ZygiJXM6IChhc3luYykgbGVuOiAlenVcbiIsIF9fZnVuY19f
LCBsZW4pOw0KKwkvKiBydW4gdGhlIG9wZXJhdGlvbiBzeW5jaHJvbm91c2x5ICovDQorCXByX2Rl
YnVnKCIlczogKHN5bmMpIGxlbjogJXp1XG4iLCBfX2Z1bmNfXywgbGVuKTsNCiANCi0JCWRtYV9z
ZXRfdW5tYXAodHgsIHVubWFwKTsNCi0JCWFzeW5jX3R4X3N1Ym1pdChjaGFuLCB0eCwgc3VibWl0
KTsNCi0JfSBlbHNlIHsNCi0JCXZvaWQgKmRlc3RfYnVmLCAqc3JjX2J1ZjsNCi0JCXByX2RlYnVn
KCIlczogKHN5bmMpIGxlbjogJXp1XG4iLCBfX2Z1bmNfXywgbGVuKTsNCisJLyogd2FpdCBmb3Ig
YW55IHByZXJlcXVpc2l0ZSBvcGVyYXRpb25zICovDQorCWFzeW5jX3R4X3F1aWVzY2UoJnN1Ym1p
dC0+ZGVwZW5kX3R4KTsNCiANCi0JCS8qIHdhaXQgZm9yIGFueSBwcmVyZXF1aXNpdGUgb3BlcmF0
aW9ucyAqLw0KLQkJYXN5bmNfdHhfcXVpZXNjZSgmc3VibWl0LT5kZXBlbmRfdHgpOw0KKwlkZXN0
X2J1ZiA9IGttYXBfYXRvbWljKGRlc3QpICsgZGVzdF9vZmZzZXQ7DQorCXNyY19idWYgPSBrbWFw
X2F0b21pYyhzcmMpICsgc3JjX29mZnNldDsNCiANCi0JCWRlc3RfYnVmID0ga21hcF9hdG9taWMo
ZGVzdCkgKyBkZXN0X29mZnNldDsNCi0JCXNyY19idWYgPSBrbWFwX2F0b21pYyhzcmMpICsgc3Jj
X29mZnNldDsNCisJbWVtY3B5KGRlc3RfYnVmLCBzcmNfYnVmLCBsZW4pOw0KIA0KLQkJbWVtY3B5
KGRlc3RfYnVmLCBzcmNfYnVmLCBsZW4pOw0KLQ0KLQkJa3VubWFwX2F0b21pYyhzcmNfYnVmKTsN
Ci0JCWt1bm1hcF9hdG9taWMoZGVzdF9idWYpOw0KLQ0KLQkJYXN5bmNfdHhfc3luY19lcGlsb2co
c3VibWl0KTsNCi0JfQ0KKwlrdW5tYXBfYXRvbWljKHNyY19idWYpOw0KKwlrdW5tYXBfYXRvbWlj
KGRlc3RfYnVmKTsNCiANCi0JZG1hZW5naW5lX3VubWFwX3B1dCh1bm1hcCk7DQorCWFzeW5jX3R4
X3N5bmNfZXBpbG9nKHN1Ym1pdCk7DQogDQotCXJldHVybiB0eDsNCisJcmV0dXJuIE5VTEw7DQog
fQ0KIEVYUE9SVF9TWU1CT0xfR1BMKGFzeW5jX21lbWNweSk7DQogDQpkaWZmIC0tZ2l0IGEvY3J5
cHRvL2FzeW5jX3R4L2FzeW5jX3BxLmMgYi9jcnlwdG8vYXN5bmNfdHgvYXN5bmNfcHEuYyBpbmRl
eCBkMDUzMjdjLi5mNDQ2Y2RhIDEwMDY0NA0KLS0tIGEvY3J5cHRvL2FzeW5jX3R4L2FzeW5jX3Bx
LmMNCisrKyBiL2NyeXB0by9hc3luY190eC9hc3luY19wcS5jDQpAQCAtMTc1LDEwICsxNzUsNyBA
QCBhc3luY19nZW5fc3luZHJvbWUoc3RydWN0IHBhZ2UgKipibG9ja3MsIHVuc2lnbmVkIGludCBv
ZmZzZXQsIGludCBkaXNrcywNCiANCiAJQlVHX09OKGRpc2tzID4gMjU1IHx8ICEoUChibG9ja3Ms
IGRpc2tzKSB8fCBRKGJsb2NrcywgZGlza3MpKSk7DQogDQotCWlmIChkZXZpY2UpDQotCQl1bm1h
cCA9IGRtYWVuZ2luZV9nZXRfdW5tYXBfZGF0YShkZXZpY2UtPmRldiwgZGlza3MsIEdGUF9OT0lP
KTsNCi0NCi0JaWYgKHVubWFwICYmDQorCWlmIChkZXZpY2UgJiYNCiAJICAgIChzcmNfY250IDw9
IGRtYV9tYXhwcShkZXZpY2UsIDApIHx8DQogCSAgICAgZG1hX21heHBxKGRldmljZSwgRE1BX1BS
RVBfQ09OVElOVUUpID4gMCkgJiYNCiAJICAgIGlzX2RtYV9wcV9hbGlnbmVkKGRldmljZSwgb2Zm
c2V0LCAwLCBsZW4pKSB7IEBAIC0xOTQsNDYgKzE5MSw1NCBAQCBhc3luY19nZW5fc3luZHJvbWUo
c3RydWN0IHBhZ2UgKipibG9ja3MsIHVuc2lnbmVkIGludCBvZmZzZXQsIGludCBkaXNrcywNCiAJ
CS8qIGNvbnZlcnQgc291cmNlIGFkZHJlc3NlcyBiZWluZyBjYXJlZnVsIHRvIGNvbGxhcHNlICdl
bXB0eScNCiAJCSAqIHNvdXJjZXMgYW5kIHVwZGF0ZSB0aGUgY29lZmZpY2llbnRzIGFjY29yZGlu
Z2x5DQogCQkgKi8NCi0JCXVubWFwLT5sZW4gPSBsZW47DQotCQlmb3IgKGkgPSAwLCBqID0gMDsg
aSA8IHNyY19jbnQ7IGkrKykgew0KLQkJCWlmIChibG9ja3NbaV0gPT0gTlVMTCkNCi0JCQkJY29u
dGludWU7DQotCQkJdW5tYXAtPmFkZHJbal0gPSBkbWFfbWFwX3BhZ2UoZGV2aWNlLT5kZXYsIGJs
b2Nrc1tpXSwgb2Zmc2V0LA0KLQkJCQkJCSAgICAgIGxlbiwgRE1BX1RPX0RFVklDRSk7DQotCQkJ
Y29lZnNbal0gPSByYWlkNl9nZmV4cFtpXTsNCi0JCQl1bm1hcC0+dG9fY250Kys7DQotCQkJaisr
Ow0KLQkJfQ0KKwkJdW5tYXAgPSBkbWFlbmdpbmVfZ2V0X3VubWFwX2RhdGEoZGV2aWNlLT5kZXYs
IGRpc2tzLCBHRlBfTk9JTyk7DQorCQlpZiAodW5tYXApIHsNCisJCQl1bm1hcC0+bGVuID0gbGVu
Ow0KKwkJCWZvciAoaSA9IDAsIGogPSAwOyBpIDwgc3JjX2NudDsgaSsrKSB7DQorCQkJCWlmIChi
bG9ja3NbaV0gPT0gTlVMTCkNCisJCQkJCWNvbnRpbnVlOw0KKwkJCQl1bm1hcC0+YWRkcltqXSA9
IGRtYV9tYXBfcGFnZShkZXZpY2UtPmRldiwNCisJCQkJCQkJICAgICAgYmxvY2tzW2ldLA0KKwkJ
CQkJCQkgICAgICBvZmZzZXQsDQorCQkJCQkJCSAgICAgIGxlbiwNCisJCQkJCQkJICAgICAgRE1B
X1RPX0RFVklDRSk7DQorCQkJCWNvZWZzW2pdID0gcmFpZDZfZ2ZleHBbaV07DQorCQkJCXVubWFw
LT50b19jbnQrKzsNCisJCQkJaisrOw0KKwkJCX0NCiANCi0JCS8qDQotCQkgKiBETUFzIHVzZSBk
ZXN0aW5hdGlvbnMgYXMgc291cmNlcywNCi0JCSAqIHNvIHVzZSBCSURJUkVDVElPTkFMIG1hcHBp
bmcNCi0JCSAqLw0KLQkJdW5tYXAtPmJpZGlfY250Kys7DQotCQlpZiAoUChibG9ja3MsIGRpc2tz
KSkNCi0JCQl1bm1hcC0+YWRkcltqKytdID0gZG1hX21hcF9wYWdlKGRldmljZS0+ZGV2LCBQKGJs
b2NrcywgZGlza3MpLA0KLQkJCQkJCQlvZmZzZXQsIGxlbiwgRE1BX0JJRElSRUNUSU9OQUwpOw0K
LQkJZWxzZSB7DQotCQkJdW5tYXAtPmFkZHJbaisrXSA9IDA7DQotCQkJZG1hX2ZsYWdzIHw9IERN
QV9QUkVQX1BRX0RJU0FCTEVfUDsNCi0JCX0NCisJCQkvKg0KKwkJCSAqIERNQXMgdXNlIGRlc3Rp
bmF0aW9ucyBhcyBzb3VyY2VzLA0KKwkJCSAqIHNvIHVzZSBCSURJUkVDVElPTkFMIG1hcHBpbmcN
CisJCQkgKi8NCisJCQl1bm1hcC0+YmlkaV9jbnQrKzsNCisJCQlpZiAoUChibG9ja3MsIGRpc2tz
KSkNCisJCQkJdW5tYXAtPmFkZHJbaisrXSA9IGRtYV9tYXBfcGFnZShkZXZpY2UtPmRldiwNCisJ
CQkJCQkJUChibG9ja3MsIGRpc2tzKSwNCisJCQkJCQkJb2Zmc2V0LCBsZW4sDQorCQkJCQkJCURN
QV9CSURJUkVDVElPTkFMKTsNCisJCQllbHNlIHsNCisJCQkJdW5tYXAtPmFkZHJbaisrXSA9IDA7
DQorCQkJCWRtYV9mbGFncyB8PSBETUFfUFJFUF9QUV9ESVNBQkxFX1A7DQorCQkJfQ0KIA0KLQkJ
dW5tYXAtPmJpZGlfY250Kys7DQotCQlpZiAoUShibG9ja3MsIGRpc2tzKSkNCi0JCQl1bm1hcC0+
YWRkcltqKytdID0gZG1hX21hcF9wYWdlKGRldmljZS0+ZGV2LCBRKGJsb2NrcywgZGlza3MpLA0K
LQkJCQkJCSAgICAgICBvZmZzZXQsIGxlbiwgRE1BX0JJRElSRUNUSU9OQUwpOw0KLQkJZWxzZSB7
DQotCQkJdW5tYXAtPmFkZHJbaisrXSA9IDA7DQotCQkJZG1hX2ZsYWdzIHw9IERNQV9QUkVQX1BR
X0RJU0FCTEVfUTsNCi0JCX0NCisJCQl1bm1hcC0+YmlkaV9jbnQrKzsNCisJCQlpZiAoUShibG9j
a3MsIGRpc2tzKSkNCisJCQkJdW5tYXAtPmFkZHJbaisrXSA9IGRtYV9tYXBfcGFnZShkZXZpY2Ut
PmRldiwNCisJCQkJCQkJUShibG9ja3MsIGRpc2tzKSwNCisJCQkJCQkJb2Zmc2V0LCBsZW4sDQor
CQkJCQkJCURNQV9CSURJUkVDVElPTkFMKTsNCisJCQllbHNlIHsNCisJCQkJdW5tYXAtPmFkZHJb
aisrXSA9IDA7DQorCQkJCWRtYV9mbGFncyB8PSBETUFfUFJFUF9QUV9ESVNBQkxFX1E7DQorCQkJ
fQ0KIA0KLQkJdHggPSBkb19hc3luY19nZW5fc3luZHJvbWUoY2hhbiwgY29lZnMsIGosIHVubWFw
LCBkbWFfZmxhZ3MsIHN1Ym1pdCk7DQotCQlkbWFlbmdpbmVfdW5tYXBfcHV0KHVubWFwKTsNCi0J
CXJldHVybiB0eDsNCisJCQl0eCA9IGRvX2FzeW5jX2dlbl9zeW5kcm9tZShjaGFuLCBjb2Vmcywg
aiwgdW5tYXAsDQorCQkJCQkJICAgZG1hX2ZsYWdzLCBzdWJtaXQpOw0KKwkJCXJldHVybiB0eDsN
CisJCX0NCiAJfQ0KIA0KLQlkbWFlbmdpbmVfdW5tYXBfcHV0KHVubWFwKTsNCi0NCiAJLyogcnVu
IHRoZSBwcSBzeW5jaHJvbm91c2x5ICovDQogCXByX2RlYnVnKCIlczogKHN5bmMpIGRpc2tzOiAl
ZCBsZW46ICV6dVxuIiwgX19mdW5jX18sIGRpc2tzLCBsZW4pOw0KIA0KQEAgLTI5MywxMCArMjk4
LDcgQEAgYXN5bmNfc3luZHJvbWVfdmFsKHN0cnVjdCBwYWdlICoqYmxvY2tzLCB1bnNpZ25lZCBp
bnQgb2Zmc2V0LCBpbnQgZGlza3MsDQogDQogCUJVR19PTihkaXNrcyA8IDQpOw0KIA0KLQlpZiAo
ZGV2aWNlKQ0KLQkJdW5tYXAgPSBkbWFlbmdpbmVfZ2V0X3VubWFwX2RhdGEoZGV2aWNlLT5kZXYs
IGRpc2tzLCBHRlBfTk9JTyk7DQotDQotCWlmICh1bm1hcCAmJiBkaXNrcyA8PSBkbWFfbWF4cHEo
ZGV2aWNlLCAwKSAmJg0KKwlpZiAoZGV2aWNlICYmIGRpc2tzIDw9IGRtYV9tYXhwcShkZXZpY2Us
IDApICYmDQogCSAgICBpc19kbWFfcHFfYWxpZ25lZChkZXZpY2UsIG9mZnNldCwgMCwgbGVuKSkg
ew0KIAkJc3RydWN0IGRldmljZSAqZGV2ID0gZGV2aWNlLT5kZXY7DQogCQlkbWFfYWRkcl90IHBx
WzJdOw0KQEAgLTMwNSw1OCArMzA3LDYzIEBAIGFzeW5jX3N5bmRyb21lX3ZhbChzdHJ1Y3QgcGFn
ZSAqKmJsb2NrcywgdW5zaWduZWQgaW50IG9mZnNldCwgaW50IGRpc2tzLA0KIAkJcHJfZGVidWco
IiVzOiAoYXN5bmMpIGRpc2tzOiAlZCBsZW46ICV6dVxuIiwNCiAJCQkgX19mdW5jX18sIGRpc2tz
LCBsZW4pOw0KIA0KLQkJdW5tYXAtPmxlbiA9IGxlbjsNCi0JCWZvciAoaSA9IDA7IGkgPCBkaXNr
cy0yOyBpKyspDQotCQkJaWYgKGxpa2VseShibG9ja3NbaV0pKSB7DQotCQkJCXVubWFwLT5hZGRy
W2pdID0gZG1hX21hcF9wYWdlKGRldiwgYmxvY2tzW2ldLA0KLQkJCQkJCQkgICAgICBvZmZzZXQs
IGxlbiwNCisJCXVubWFwID0gZG1hZW5naW5lX2dldF91bm1hcF9kYXRhKGRldmljZS0+ZGV2LCBk
aXNrcywgR0ZQX05PSU8pOw0KKwkJaWYgKHVubWFwKSB7DQorCQkJdW5tYXAtPmxlbiA9IGxlbjsN
CisJCQlmb3IgKGkgPSAwOyBpIDwgZGlza3MtMjsgaSsrKQ0KKwkJCQlpZiAobGlrZWx5KGJsb2Nr
c1tpXSkpIHsNCisJCQkJCXVubWFwLT5hZGRyW2pdID0gZG1hX21hcF9wYWdlKGRldiwNCisJCQkJ
CQkJICAgICAgYmxvY2tzW2ldLA0KKwkJCQkJCQkgICAgICBvZmZzZXQsDQorCQkJCQkJCSAgICAg
IGxlbiwNCiAJCQkJCQkJICAgICAgRE1BX1RPX0RFVklDRSk7DQotCQkJCWNvZWZzW2pdID0gcmFp
ZDZfZ2ZleHBbaV07DQorCQkJCQljb2Vmc1tqXSA9IHJhaWQ2X2dmZXhwW2ldOw0KKwkJCQkJdW5t
YXAtPnRvX2NudCsrOw0KKwkJCQkJc3JjX2NudCsrOw0KKwkJCQkJaisrOw0KKwkJCQl9DQorDQor
CQkJaWYgKCFQKGJsb2NrcywgZGlza3MpKSB7DQorCQkJCXBxWzBdID0gMDsNCisJCQkJZG1hX2Zs
YWdzIHw9IERNQV9QUkVQX1BRX0RJU0FCTEVfUDsNCisJCQl9IGVsc2Ugew0KKwkJCQlwcVswXSA9
IGRtYV9tYXBfcGFnZShkZXYsIFAoYmxvY2tzLCBkaXNrcyksDQorCQkJCQkJICAgICBvZmZzZXQs
IGxlbiwNCisJCQkJCQkgICAgIERNQV9UT19ERVZJQ0UpOw0KKwkJCQl1bm1hcC0+YWRkcltqKytd
ID0gcHFbMF07DQorCQkJCXVubWFwLT50b19jbnQrKzsNCisJCQl9DQorCQkJaWYgKCFRKGJsb2Nr
cywgZGlza3MpKSB7DQorCQkJCXBxWzFdID0gMDsNCisJCQkJZG1hX2ZsYWdzIHw9IERNQV9QUkVQ
X1BRX0RJU0FCTEVfUTsNCisJCQl9IGVsc2Ugew0KKwkJCQlwcVsxXSA9IGRtYV9tYXBfcGFnZShk
ZXYsIFEoYmxvY2tzLCBkaXNrcyksDQorCQkJCQkJICAgICBvZmZzZXQsIGxlbiwNCisJCQkJCQkg
ICAgIERNQV9UT19ERVZJQ0UpOw0KKwkJCQl1bm1hcC0+YWRkcltqKytdID0gcHFbMV07DQogCQkJ
CXVubWFwLT50b19jbnQrKzsNCi0JCQkJc3JjX2NudCsrOw0KLQkJCQlqKys7DQogCQkJfQ0KIA0K
LQkJaWYgKCFQKGJsb2NrcywgZGlza3MpKSB7DQotCQkJcHFbMF0gPSAwOw0KLQkJCWRtYV9mbGFn
cyB8PSBETUFfUFJFUF9QUV9ESVNBQkxFX1A7DQotCQl9IGVsc2Ugew0KLQkJCXBxWzBdID0gZG1h
X21hcF9wYWdlKGRldiwgUChibG9ja3MsIGRpc2tzKSwNCi0JCQkJCSAgICAgb2Zmc2V0LCBsZW4s
DQotCQkJCQkgICAgIERNQV9UT19ERVZJQ0UpOw0KLQkJCXVubWFwLT5hZGRyW2orK10gPSBwcVsw
XTsNCi0JCQl1bm1hcC0+dG9fY250Kys7DQotCQl9DQotCQlpZiAoIVEoYmxvY2tzLCBkaXNrcykp
IHsNCi0JCQlwcVsxXSA9IDA7DQotCQkJZG1hX2ZsYWdzIHw9IERNQV9QUkVQX1BRX0RJU0FCTEVf
UTsNCi0JCX0gZWxzZSB7DQotCQkJcHFbMV0gPSBkbWFfbWFwX3BhZ2UoZGV2LCBRKGJsb2Nrcywg
ZGlza3MpLA0KLQkJCQkJICAgICBvZmZzZXQsIGxlbiwNCi0JCQkJCSAgICAgRE1BX1RPX0RFVklD
RSk7DQotCQkJdW5tYXAtPmFkZHJbaisrXSA9IHBxWzFdOw0KLQkJCXVubWFwLT50b19jbnQrKzsN
Ci0JCX0NCi0NCi0JCWlmIChzdWJtaXQtPmZsYWdzICYgQVNZTkNfVFhfRkVOQ0UpDQotCQkJZG1h
X2ZsYWdzIHw9IERNQV9QUkVQX0ZFTkNFOw0KLQkJZm9yICg7Oykgew0KLQkJCXR4ID0gZGV2aWNl
LT5kZXZpY2VfcHJlcF9kbWFfcHFfdmFsKGNoYW4sIHBxLA0KLQkJCQkJCQkgICAgdW5tYXAtPmFk
ZHIsDQotCQkJCQkJCSAgICBzcmNfY250LA0KLQkJCQkJCQkgICAgY29lZnMsDQotCQkJCQkJCSAg
ICBsZW4sIHBxcmVzLA0KLQkJCQkJCQkgICAgZG1hX2ZsYWdzKTsNCi0JCQlpZiAobGlrZWx5KHR4
KSkNCi0JCQkJYnJlYWs7DQotCQkJYXN5bmNfdHhfcXVpZXNjZSgmc3VibWl0LT5kZXBlbmRfdHgp
Ow0KLQkJCWRtYV9hc3luY19pc3N1ZV9wZW5kaW5nKGNoYW4pOw0KLQkJfQ0KKwkJCWlmIChzdWJt
aXQtPmZsYWdzICYgQVNZTkNfVFhfRkVOQ0UpDQorCQkJCWRtYV9mbGFncyB8PSBETUFfUFJFUF9G
RU5DRTsNCisJCQlmb3IgKDs7KSB7DQorCQkJCXR4ID0gZGV2aWNlLT5kZXZpY2VfcHJlcF9kbWFf
cHFfdmFsKGNoYW4sIHBxLA0KKwkJCQkJCQkJICAgIHVubWFwLT5hZGRyLA0KKwkJCQkJCQkJICAg
IHNyY19jbnQsDQorCQkJCQkJCQkgICAgY29lZnMsDQorCQkJCQkJCQkgICAgbGVuLCBwcXJlcywN
CisJCQkJCQkJCSAgICBkbWFfZmxhZ3MpOw0KKwkJCQlpZiAobGlrZWx5KHR4KSkNCisJCQkJCWJy
ZWFrOw0KKwkJCQlhc3luY190eF9xdWllc2NlKCZzdWJtaXQtPmRlcGVuZF90eCk7DQorCQkJCWRt
YV9hc3luY19pc3N1ZV9wZW5kaW5nKGNoYW4pOw0KKwkJCX0NCiANCi0JCWRtYV9zZXRfdW5tYXAo
dHgsIHVubWFwKTsNCi0JCWFzeW5jX3R4X3N1Ym1pdChjaGFuLCB0eCwgc3VibWl0KTsNCisJCQlk
bWFfc2V0X3VubWFwKHR4LCB1bm1hcCk7DQorCQkJYXN5bmNfdHhfc3VibWl0KGNoYW4sIHR4LCBz
dWJtaXQpOw0KIA0KLQkJcmV0dXJuIHR4Ow0KKwkJCXJldHVybiB0eDsNCisJCX0NCiAJfSBlbHNl
IHsNCiAJCXN0cnVjdCBwYWdlICpwX3NyYyA9IFAoYmxvY2tzLCBkaXNrcyk7DQogCQlzdHJ1Y3Qg
cGFnZSAqcV9zcmMgPSBRKGJsb2NrcywgZGlza3MpOyBAQCAtNDExLDkgKzQxOCw5IEBAIGFzeW5j
X3N5bmRyb21lX3ZhbChzdHJ1Y3QgcGFnZSAqKmJsb2NrcywgdW5zaWduZWQgaW50IG9mZnNldCwg
aW50IGRpc2tzLA0KIAkJc3VibWl0LT5jYl9wYXJhbSA9IGNiX3BhcmFtX29yaWc7DQogCQlzdWJt
aXQtPmZsYWdzID0gZmxhZ3Nfb3JpZzsNCiAJCWFzeW5jX3R4X3N5bmNfZXBpbG9nKHN1Ym1pdCk7
DQotDQotCQlyZXR1cm4gTlVMTDsNCiAJfQ0KKw0KKwlyZXR1cm4gTlVMTDsNCiB9DQogRVhQT1JU
X1NZTUJPTF9HUEwoYXN5bmNfc3luZHJvbWVfdmFsKTsNCiANCmRpZmYgLS1naXQgYS9jcnlwdG8v
YXN5bmNfdHgvYXN5bmNfcmFpZDZfcmVjb3YuYyBiL2NyeXB0by9hc3luY190eC9hc3luY19yYWlk
Nl9yZWNvdi5jDQppbmRleCA5MzRhODQ5Li5jNTVkOGYxIDEwMDY0NA0KLS0tIGEvY3J5cHRvL2Fz
eW5jX3R4L2FzeW5jX3JhaWQ2X3JlY292LmMNCisrKyBiL2NyeXB0by9hc3luY190eC9hc3luY19y
YWlkNl9yZWNvdi5jDQpAQCAtNDAsMTAgKzQwLDcgQEAgYXN5bmNfc3VtX3Byb2R1Y3Qoc3RydWN0
IHBhZ2UgKmRlc3QsIHN0cnVjdCBwYWdlICoqc3JjcywgdW5zaWduZWQgY2hhciAqY29lZiwNCiAJ
dTggYXgsIGJ4Ow0KIAl1OCAqYSwgKmIsICpjOw0KIA0KLQlpZiAoZG1hKQ0KLQkJdW5tYXAgPSBk
bWFlbmdpbmVfZ2V0X3VubWFwX2RhdGEoZG1hLT5kZXYsIDMsIEdGUF9OT0lPKTsNCi0NCi0JaWYg
KHVubWFwKSB7DQorCWlmIChkbWEpIHsNCiAJCXN0cnVjdCBkZXZpY2UgKmRldiA9IGRtYS0+ZGV2
Ow0KIAkJZG1hX2FkZHJfdCBwcVsyXTsNCiAJCXN0cnVjdCBkbWFfYXN5bmNfdHhfZGVzY3JpcHRv
ciAqdHg7DQpAQCAtNTEsMjkgKzQ4LDM1IEBAIGFzeW5jX3N1bV9wcm9kdWN0KHN0cnVjdCBwYWdl
ICpkZXN0LCBzdHJ1Y3QgcGFnZSAqKnNyY3MsIHVuc2lnbmVkIGNoYXIgKmNvZWYsDQogDQogCQlp
ZiAoc3VibWl0LT5mbGFncyAmIEFTWU5DX1RYX0ZFTkNFKQ0KIAkJCWRtYV9mbGFncyB8PSBETUFf
UFJFUF9GRU5DRTsNCi0JCXVubWFwLT5hZGRyWzBdID0gZG1hX21hcF9wYWdlKGRldiwgc3Jjc1sw
XSwgMCwgbGVuLCBETUFfVE9fREVWSUNFKTsNCi0JCXVubWFwLT5hZGRyWzFdID0gZG1hX21hcF9w
YWdlKGRldiwgc3Jjc1sxXSwgMCwgbGVuLCBETUFfVE9fREVWSUNFKTsNCi0JCXVubWFwLT50b19j
bnQgPSAyOw0KLQ0KLQkJdW5tYXAtPmFkZHJbMl0gPSBkbWFfbWFwX3BhZ2UoZGV2LCBkZXN0LCAw
LCBsZW4sIERNQV9CSURJUkVDVElPTkFMKTsNCi0JCXVubWFwLT5iaWRpX2NudCA9IDE7DQotCQkv
KiBlbmdpbmUgb25seSBsb29rcyBhdCBRLCBidXQgZXhwZWN0cyBpdCB0byBmb2xsb3cgUCAqLw0K
LQkJcHFbMV0gPSB1bm1hcC0+YWRkclsyXTsNCi0NCi0JCXVubWFwLT5sZW4gPSBsZW47DQotCQl0
eCA9IGRtYS0+ZGV2aWNlX3ByZXBfZG1hX3BxKGNoYW4sIHBxLCB1bm1hcC0+YWRkciwgMiwgY29l
ZiwNCi0JCQkJCSAgICAgbGVuLCBkbWFfZmxhZ3MpOw0KLQkJaWYgKHR4KSB7DQotCQkJZG1hX3Nl
dF91bm1hcCh0eCwgdW5tYXApOw0KLQkJCWFzeW5jX3R4X3N1Ym1pdChjaGFuLCB0eCwgc3VibWl0
KTsNCisNCisJCXVubWFwID0gZG1hZW5naW5lX2dldF91bm1hcF9kYXRhKGRtYS0+ZGV2LCAzLCBH
RlBfTk9JTyk7DQorCQlpZiAodW5tYXApIHsNCisJCQl1bm1hcC0+YWRkclswXSA9IGRtYV9tYXBf
cGFnZShkZXYsIHNyY3NbMF0sIDAsIGxlbiwNCisJCQkJCQkgICAgICBETUFfVE9fREVWSUNFKTsN
CisJCQl1bm1hcC0+YWRkclsxXSA9IGRtYV9tYXBfcGFnZShkZXYsIHNyY3NbMV0sIDAsIGxlbiwN
CisJCQkJCQkgICAgICBETUFfVE9fREVWSUNFKTsNCisJCQl1bm1hcC0+dG9fY250ID0gMjsNCisN
CisJCQl1bm1hcC0+YWRkclsyXSA9IGRtYV9tYXBfcGFnZShkZXYsIGRlc3QsIDAsIGxlbiwNCisJ
CQkJCQkgICAgICBETUFfQklESVJFQ1RJT05BTCk7DQorCQkJdW5tYXAtPmJpZGlfY250ID0gMTsN
CisJCQkvKiBlbmdpbmUgb25seSBsb29rcyBhdCBRLCBidXQgZXhwZWN0cyBpdCB0byBmb2xsb3cg
UCAqLw0KKwkJCXBxWzFdID0gdW5tYXAtPmFkZHJbMl07DQorDQorCQkJdW5tYXAtPmxlbiA9IGxl
bjsNCisJCQl0eCA9IGRtYS0+ZGV2aWNlX3ByZXBfZG1hX3BxKGNoYW4sIHBxLCB1bm1hcC0+YWRk
ciwgMiwNCisJCQkJCQkgICAgIGNvZWYsIGxlbiwgZG1hX2ZsYWdzKTsNCisJCQlpZiAodHgpIHsN
CisJCQkJZG1hX3NldF91bm1hcCh0eCwgdW5tYXApOw0KKwkJCQlhc3luY190eF9zdWJtaXQoY2hh
biwgdHgsIHN1Ym1pdCk7DQorCQkJCXJldHVybiB0eDsNCisJCQl9DQorDQorCQkJLyogY291bGQg
bm90IGdldCBhIGRlc2NyaXB0b3IsIHVubWFwIGFuZCBmYWxsIHRocm91Z2ggdG8NCisJCQkgKiB0
aGUgc3luY2hyb25vdXMgcGF0aA0KKwkJCSAqLw0KIAkJCWRtYWVuZ2luZV91bm1hcF9wdXQodW5t
YXApOw0KLQkJCXJldHVybiB0eDsNCiAJCX0NCi0NCi0JCS8qIGNvdWxkIG5vdCBnZXQgYSBkZXNj
cmlwdG9yLCB1bm1hcCBhbmQgZmFsbCB0aHJvdWdoIHRvDQotCQkgKiB0aGUgc3luY2hyb25vdXMg
cGF0aA0KLQkJICovDQotCQlkbWFlbmdpbmVfdW5tYXBfcHV0KHVubWFwKTsNCiAJfQ0KIA0KIAkv
KiBydW4gdGhlIG9wZXJhdGlvbiBzeW5jaHJvbm91c2x5ICovDQpAQCAtMTA0LDEwICsxMDcsNyBA
QCBhc3luY19tdWx0KHN0cnVjdCBwYWdlICpkZXN0LCBzdHJ1Y3QgcGFnZSAqc3JjLCB1OCBjb2Vm
LCBzaXplX3QgbGVuLA0KIAljb25zdCB1OCAqcW11bDsgLyogUSBtdWx0aXBsaWVyIHRhYmxlICov
DQogCXU4ICpkLCAqczsNCiANCi0JaWYgKGRtYSkNCi0JCXVubWFwID0gZG1hZW5naW5lX2dldF91
bm1hcF9kYXRhKGRtYS0+ZGV2LCAzLCBHRlBfTk9JTyk7DQotDQotCWlmICh1bm1hcCkgew0KKwlp
ZiAoZG1hKSB7DQogCQlkbWFfYWRkcl90IGRtYV9kZXN0WzJdOw0KIAkJc3RydWN0IGRldmljZSAq
ZGV2ID0gZG1hLT5kZXY7DQogCQlzdHJ1Y3QgZG1hX2FzeW5jX3R4X2Rlc2NyaXB0b3IgKnR4Ow0K
QEAgLTExNSwzMSArMTE1LDM3IEBAIGFzeW5jX211bHQoc3RydWN0IHBhZ2UgKmRlc3QsIHN0cnVj
dCBwYWdlICpzcmMsIHU4IGNvZWYsIHNpemVfdCBsZW4sDQogDQogCQlpZiAoc3VibWl0LT5mbGFn
cyAmIEFTWU5DX1RYX0ZFTkNFKQ0KIAkJCWRtYV9mbGFncyB8PSBETUFfUFJFUF9GRU5DRTsNCi0J
CXVubWFwLT5hZGRyWzBdID0gZG1hX21hcF9wYWdlKGRldiwgc3JjLCAwLCBsZW4sIERNQV9UT19E
RVZJQ0UpOw0KLQkJdW5tYXAtPnRvX2NudCsrOw0KLQkJdW5tYXAtPmFkZHJbMV0gPSBkbWFfbWFw
X3BhZ2UoZGV2LCBkZXN0LCAwLCBsZW4sIERNQV9CSURJUkVDVElPTkFMKTsNCi0JCWRtYV9kZXN0
WzFdID0gdW5tYXAtPmFkZHJbMV07DQotCQl1bm1hcC0+YmlkaV9jbnQrKzsNCi0JCXVubWFwLT5s
ZW4gPSBsZW47DQotDQotCQkvKiB0aGlzIGxvb2tzIGZ1bm55LCBidXQgdGhlIGVuZ2luZSBsb29r
cyBmb3IgUSBhdA0KLQkJICogZG1hX2Rlc3RbMV0gYW5kIGlnbm9yZXMgZG1hX2Rlc3RbMF0gYXMg
YSBkZXN0DQotCQkgKiBkdWUgdG8gRE1BX1BSRVBfUFFfRElTQUJMRV9QDQotCQkgKi8NCi0JCXR4
ID0gZG1hLT5kZXZpY2VfcHJlcF9kbWFfcHEoY2hhbiwgZG1hX2Rlc3QsIHVubWFwLT5hZGRyLA0K
LQkJCQkJICAgICAxLCAmY29lZiwgbGVuLCBkbWFfZmxhZ3MpOw0KIA0KLQkJaWYgKHR4KSB7DQot
CQkJZG1hX3NldF91bm1hcCh0eCwgdW5tYXApOw0KKwkJdW5tYXAgPSBkbWFlbmdpbmVfZ2V0X3Vu
bWFwX2RhdGEoZG1hLT5kZXYsIDMsIEdGUF9OT0lPKTsNCisJCWlmICh1bm1hcCkgew0KKwkJCXVu
bWFwLT5hZGRyWzBdID0gZG1hX21hcF9wYWdlKGRldiwgc3JjLCAwLCBsZW4sDQorCQkJCQkJICAg
ICAgRE1BX1RPX0RFVklDRSk7DQorCQkJdW5tYXAtPnRvX2NudCsrOw0KKwkJCXVubWFwLT5hZGRy
WzFdID0gZG1hX21hcF9wYWdlKGRldiwgZGVzdCwgMCwgbGVuLA0KKwkJCQkJCSAgICAgIERNQV9C
SURJUkVDVElPTkFMKTsNCisJCQlkbWFfZGVzdFsxXSA9IHVubWFwLT5hZGRyWzFdOw0KKwkJCXVu
bWFwLT5iaWRpX2NudCsrOw0KKwkJCXVubWFwLT5sZW4gPSBsZW47DQorDQorCQkJLyogdGhpcyBs
b29rcyBmdW5ueSwgYnV0IHRoZSBlbmdpbmUgbG9va3MgZm9yIFEgYXQNCisJCQkgKiBkbWFfZGVz
dFsxXSBhbmQgaWdub3JlcyBkbWFfZGVzdFswXSBhcyBhIGRlc3QNCisJCQkgKiBkdWUgdG8gRE1B
X1BSRVBfUFFfRElTQUJMRV9QDQorCQkJICovDQorCQkJdHggPSBkbWEtPmRldmljZV9wcmVwX2Rt
YV9wcShjaGFuLCBkbWFfZGVzdCwNCisJCQkJCQkgICAgIHVubWFwLT5hZGRyLCAxLCAmY29lZiwN
CisJCQkJCQkgICAgIGxlbiwgZG1hX2ZsYWdzKTsNCisNCisJCQlpZiAodHgpIHsNCisJCQkJZG1h
X3NldF91bm1hcCh0eCwgdW5tYXApOw0KKwkJCQlhc3luY190eF9zdWJtaXQoY2hhbiwgdHgsIHN1
Ym1pdCk7DQorCQkJCXJldHVybiB0eDsNCisJCQl9DQorDQorCQkJLyogY291bGQgbm90IGdldCBh
IGRlc2NyaXB0b3IsIHVubWFwIGFuZCBmYWxsIHRocm91Z2ggdG8NCisJCQkgKiB0aGUgc3luY2hy
b25vdXMgcGF0aA0KKwkJCSAqLw0KIAkJCWRtYWVuZ2luZV91bm1hcF9wdXQodW5tYXApOw0KLQkJ
CWFzeW5jX3R4X3N1Ym1pdChjaGFuLCB0eCwgc3VibWl0KTsNCi0JCQlyZXR1cm4gdHg7DQogCQl9
DQotDQotCQkvKiBjb3VsZCBub3QgZ2V0IGEgZGVzY3JpcHRvciwgdW5tYXAgYW5kIGZhbGwgdGhy
b3VnaCB0bw0KLQkJICogdGhlIHN5bmNocm9ub3VzIHBhdGgNCi0JCSAqLw0KLQkJZG1hZW5naW5l
X3VubWFwX3B1dCh1bm1hcCk7DQogCX0NCiANCiAJLyogbm8gY2hhbm5lbCBhdmFpbGFibGUsIG9y
IGZhaWxlZCB0byBhbGxvY2F0ZSBhIGRlc2NyaXB0b3IsIHNvIGRpZmYgLS1naXQgYS9jcnlwdG8v
YXN5bmNfdHgvYXN5bmNfeG9yLmMgYi9jcnlwdG8vYXN5bmNfdHgvYXN5bmNfeG9yLmMgaW5kZXgg
M2M1NjJmNS4uMDE5ZTQ2OSAxMDA2NDQNCi0tLSBhL2NyeXB0by9hc3luY190eC9hc3luY194b3Iu
Yw0KKysrIGIvY3J5cHRvL2FzeW5jX3R4L2FzeW5jX3hvci5jDQpAQCAtMTgyLDU1ICsxODIsNTcg
QEAgYXN5bmNfeG9yKHN0cnVjdCBwYWdlICpkZXN0LCBzdHJ1Y3QgcGFnZSAqKnNyY19saXN0LCB1
bnNpZ25lZCBpbnQgb2Zmc2V0LA0KIA0KIAlCVUdfT04oc3JjX2NudCA8PSAxKTsNCiANCi0JaWYg
KGRldmljZSkNCi0JCXVubWFwID0gZG1hZW5naW5lX2dldF91bm1hcF9kYXRhKGRldmljZS0+ZGV2
LCBzcmNfY250KzEsIEdGUF9OT0lPKTsNCi0NCi0JaWYgKHVubWFwICYmIGlzX2RtYV94b3JfYWxp
Z25lZChkZXZpY2UsIG9mZnNldCwgMCwgbGVuKSkgew0KKwlpZiAoZGV2aWNlICYmIGlzX2RtYV94
b3JfYWxpZ25lZChkZXZpY2UsIG9mZnNldCwgMCwgbGVuKSkgew0KIAkJc3RydWN0IGRtYV9hc3lu
Y190eF9kZXNjcmlwdG9yICp0eDsNCiAJCWludCBpLCBqOw0KIA0KIAkJLyogcnVuIHRoZSB4b3Ig
YXN5bmNocm9ub3VzbHkgKi8NCiAJCXByX2RlYnVnKCIlcyAoYXN5bmMpOiBsZW46ICV6dVxuIiwg
X19mdW5jX18sIGxlbik7DQogDQotCQl1bm1hcC0+bGVuID0gbGVuOw0KLQkJZm9yIChpID0gMCwg
aiA9IDA7IGkgPCBzcmNfY250OyBpKyspIHsNCi0JCQlpZiAoIXNyY19saXN0W2ldKQ0KLQkJCQlj
b250aW51ZTsNCi0JCQl1bm1hcC0+dG9fY250Kys7DQotCQkJdW5tYXAtPmFkZHJbaisrXSA9IGRt
YV9tYXBfcGFnZShkZXZpY2UtPmRldiwgc3JjX2xpc3RbaV0sDQotCQkJCQkJCW9mZnNldCwgbGVu
LCBETUFfVE9fREVWSUNFKTsNCi0JCX0NCisJCXVubWFwID0gZG1hZW5naW5lX2dldF91bm1hcF9k
YXRhKGRldmljZS0+ZGV2LCBzcmNfY250ICsgMSwNCisJCQkJCQkgR0ZQX05PSU8pOw0KKwkJaWYg
KHVubWFwKSB7DQorCQkJdW5tYXAtPmxlbiA9IGxlbjsNCisJCQlmb3IgKGkgPSAwLCBqID0gMDsg
aSA8IHNyY19jbnQ7IGkrKykgew0KKwkJCQlpZiAoIXNyY19saXN0W2ldKQ0KKwkJCQkJY29udGlu
dWU7DQorCQkJCXVubWFwLT50b19jbnQrKzsNCisJCQkJdW5tYXAtPmFkZHJbaisrXSA9IGRtYV9t
YXBfcGFnZShkZXZpY2UtPmRldiwNCisJCQkJCQkJCXNyY19saXN0W2ldLA0KKwkJCQkJCQkJb2Zm
c2V0LCBsZW4sDQorCQkJCQkJCQlETUFfVE9fREVWSUNFKTsNCisJCQl9DQogDQotCQkvKiBtYXAg
aXQgYmlkaXJlY3Rpb25hbCBhcyBpdCBtYXkgYmUgcmUtdXNlZCBhcyBhIHNvdXJjZSAqLw0KLQkJ
dW5tYXAtPmFkZHJbal0gPSBkbWFfbWFwX3BhZ2UoZGV2aWNlLT5kZXYsIGRlc3QsIG9mZnNldCwg
bGVuLA0KLQkJCQkJICAgICAgRE1BX0JJRElSRUNUSU9OQUwpOw0KLQkJdW5tYXAtPmJpZGlfY250
ID0gMTsNCi0NCi0JCXR4ID0gZG9fYXN5bmNfeG9yKGNoYW4sIHVubWFwLCBzdWJtaXQpOw0KLQkJ
ZG1hZW5naW5lX3VubWFwX3B1dCh1bm1hcCk7DQotCQlyZXR1cm4gdHg7DQotCX0gZWxzZSB7DQot
CQlkbWFlbmdpbmVfdW5tYXBfcHV0KHVubWFwKTsNCi0JCS8qIHJ1biB0aGUgeG9yIHN5bmNocm9u
b3VzbHkgKi8NCi0JCXByX2RlYnVnKCIlcyAoc3luYyk6IGxlbjogJXp1XG4iLCBfX2Z1bmNfXywg
bGVuKTsNCi0JCVdBUk5fT05DRShjaGFuLCAiJXM6IG5vIHNwYWNlIGZvciBkbWEgYWRkcmVzcyBj
b252ZXJzaW9uXG4iLA0KLQkJCSAgX19mdW5jX18pOw0KLQ0KLQkJLyogaW4gdGhlIHN5bmMgY2Fz
ZSB0aGUgZGVzdCBpcyBhbiBpbXBsaWVkIHNvdXJjZQ0KLQkJICogKGFzc3VtZXMgdGhlIGRlc3Qg
aXMgdGhlIGZpcnN0IHNvdXJjZSkNCi0JCSAqLw0KLQkJaWYgKHN1Ym1pdC0+ZmxhZ3MgJiBBU1lO
Q19UWF9YT1JfRFJPUF9EU1QpIHsNCi0JCQlzcmNfY250LS07DQotCQkJc3JjX2xpc3QrKzsNCisJ
CQkvKiBtYXAgaXQgYmlkaXJlY3Rpb25hbCBhcyBpdCBtYXkgYmUgcmUtdXNlZA0KKwkJCSAgIGFz
IGEgc291cmNlICovDQorCQkJdW5tYXAtPmFkZHJbal0gPSBkbWFfbWFwX3BhZ2UoZGV2aWNlLT5k
ZXYsIGRlc3QsIG9mZnNldCwNCisJCQkJCQkgICAgICBsZW4sIERNQV9CSURJUkVDVElPTkFMKTsN
CisJCQl1bm1hcC0+YmlkaV9jbnQgPSAxOw0KKw0KKwkJCXR4ID0gZG9fYXN5bmNfeG9yKGNoYW4s
IHVubWFwLCBzdWJtaXQpOw0KKwkJCXJldHVybiB0eDsNCiAJCX0NCisJfQ0KIA0KLQkJLyogd2Fp
dCBmb3IgYW55IHByZXJlcXVpc2l0ZSBvcGVyYXRpb25zICovDQotCQlhc3luY190eF9xdWllc2Nl
KCZzdWJtaXQtPmRlcGVuZF90eCk7DQorCS8qIHJ1biB0aGUgeG9yIHN5bmNocm9ub3VzbHkgKi8N
CisJcHJfZGVidWcoIiVzIChzeW5jKTogbGVuOiAlenVcbiIsIF9fZnVuY19fLCBsZW4pOw0KKwlX
QVJOX09OQ0UoY2hhbiwgIiVzOiBubyBzcGFjZSBmb3IgZG1hIGFkZHJlc3MgY29udmVyc2lvblxu
IiwNCisJCSAgX19mdW5jX18pOw0KKw0KKwkvKiBpbiB0aGUgc3luYyBjYXNlIHRoZSBkZXN0IGlz
IGFuIGltcGxpZWQgc291cmNlDQorCSAqIChhc3N1bWVzIHRoZSBkZXN0IGlzIHRoZSBmaXJzdCBz
b3VyY2UpDQorCSAqLw0KKwlpZiAoc3VibWl0LT5mbGFncyAmIEFTWU5DX1RYX1hPUl9EUk9QX0RT
VCkgew0KKwkJc3JjX2NudC0tOw0KKwkJc3JjX2xpc3QrKzsNCisJfQ0KIA0KLQkJZG9fc3luY194
b3IoZGVzdCwgc3JjX2xpc3QsIG9mZnNldCwgc3JjX2NudCwgbGVuLCBzdWJtaXQpOw0KKwkvKiB3
YWl0IGZvciBhbnkgcHJlcmVxdWlzaXRlIG9wZXJhdGlvbnMgKi8NCisJYXN5bmNfdHhfcXVpZXNj
ZSgmc3VibWl0LT5kZXBlbmRfdHgpOw0KIA0KLQkJcmV0dXJuIE5VTEw7DQotCX0NCisJZG9fc3lu
Y194b3IoZGVzdCwgc3JjX2xpc3QsIG9mZnNldCwgc3JjX2NudCwgbGVuLCBzdWJtaXQpOw0KKw0K
KwlyZXR1cm4gTlVMTDsNCiB9DQogRVhQT1JUX1NZTUJPTF9HUEwoYXN5bmNfeG9yKTsNCiANCkBA
IC0yNzUsMTMgKzI3NywxMSBAQCBhc3luY194b3JfdmFsKHN0cnVjdCBwYWdlICpkZXN0LCBzdHJ1
Y3QgcGFnZSAqKnNyY19saXN0LCB1bnNpZ25lZCBpbnQgb2Zmc2V0LA0KIAlzdHJ1Y3QgZG1hX2Rl
dmljZSAqZGV2aWNlID0gY2hhbiA/IGNoYW4tPmRldmljZSA6IE5VTEw7DQogCXN0cnVjdCBkbWFf
YXN5bmNfdHhfZGVzY3JpcHRvciAqdHggPSBOVUxMOw0KIAlzdHJ1Y3QgZG1hZW5naW5lX3VubWFw
X2RhdGEgKnVubWFwID0gTlVMTDsNCisJZW51bSBhc3luY190eF9mbGFncyBmbGFnc19vcmlnID0g
c3VibWl0LT5mbGFnczsNCiANCiAJQlVHX09OKHNyY19jbnQgPD0gMSk7DQogDQotCWlmIChkZXZp
Y2UpDQotCQl1bm1hcCA9IGRtYWVuZ2luZV9nZXRfdW5tYXBfZGF0YShkZXZpY2UtPmRldiwgc3Jj
X2NudCwgR0ZQX05PSU8pOw0KLQ0KLQlpZiAodW5tYXAgJiYgc3JjX2NudCA8PSBkZXZpY2UtPm1h
eF94b3IgJiYNCisJaWYgKGRldmljZSAmJiBzcmNfY250IDw9IGRldmljZS0+bWF4X3hvciAmJg0K
IAkgICAgaXNfZG1hX3hvcl9hbGlnbmVkKGRldmljZSwgb2Zmc2V0LCAwLCBsZW4pKSB7DQogCQl1
bnNpZ25lZCBsb25nIGRtYV9wcmVwX2ZsYWdzID0gMDsNCiAJCWludCBpOw0KQEAgLTI5Myw1MSAr
MjkzLDU5IEBAIGFzeW5jX3hvcl92YWwoc3RydWN0IHBhZ2UgKmRlc3QsIHN0cnVjdCBwYWdlICoq
c3JjX2xpc3QsIHVuc2lnbmVkIGludCBvZmZzZXQsDQogCQlpZiAoc3VibWl0LT5mbGFncyAmIEFT
WU5DX1RYX0ZFTkNFKQ0KIAkJCWRtYV9wcmVwX2ZsYWdzIHw9IERNQV9QUkVQX0ZFTkNFOw0KIA0K
LQkJZm9yIChpID0gMDsgaSA8IHNyY19jbnQ7IGkrKykgew0KLQkJCXVubWFwLT5hZGRyW2ldID0g
ZG1hX21hcF9wYWdlKGRldmljZS0+ZGV2LCBzcmNfbGlzdFtpXSwNCi0JCQkJCQkgICAgICBvZmZz
ZXQsIGxlbiwgRE1BX1RPX0RFVklDRSk7DQotCQkJdW5tYXAtPnRvX2NudCsrOw0KLQkJfQ0KLQkJ
dW5tYXAtPmxlbiA9IGxlbjsNCi0NCi0JCXR4ID0gZGV2aWNlLT5kZXZpY2VfcHJlcF9kbWFfeG9y
X3ZhbChjaGFuLCB1bm1hcC0+YWRkciwgc3JjX2NudCwNCi0JCQkJCQkgICAgIGxlbiwgcmVzdWx0
LA0KLQkJCQkJCSAgICAgZG1hX3ByZXBfZmxhZ3MpOw0KLQkJaWYgKHVubGlrZWx5KCF0eCkpIHsN
Ci0JCQlhc3luY190eF9xdWllc2NlKCZzdWJtaXQtPmRlcGVuZF90eCk7DQotDQotCQkJd2hpbGUg
KCF0eCkgew0KLQkJCQlkbWFfYXN5bmNfaXNzdWVfcGVuZGluZyhjaGFuKTsNCi0JCQkJdHggPSBk
ZXZpY2UtPmRldmljZV9wcmVwX2RtYV94b3JfdmFsKGNoYW4sDQotCQkJCQl1bm1hcC0+YWRkciwg
c3JjX2NudCwgbGVuLCByZXN1bHQsDQotCQkJCQlkbWFfcHJlcF9mbGFncyk7DQorCQl1bm1hcCA9
IGRtYWVuZ2luZV9nZXRfdW5tYXBfZGF0YShkZXZpY2UtPmRldiwgc3JjX2NudCwNCisJCQkJCQkg
R0ZQX05PSU8pOw0KKwkJaWYgKHVubWFwKSB7DQorCQkJZm9yIChpID0gMDsgaSA8IHNyY19jbnQ7
IGkrKykgew0KKwkJCQl1bm1hcC0+YWRkcltpXSA9IGRtYV9tYXBfcGFnZShkZXZpY2UtPmRldiwN
CisJCQkJCQkJICAgICAgc3JjX2xpc3RbaV0sDQorCQkJCQkJCSAgICAgIG9mZnNldCwgbGVuLA0K
KwkJCQkJCQkgICAgICBETUFfVE9fREVWSUNFKTsNCisJCQkJdW5tYXAtPnRvX2NudCsrOw0KKwkJ
CX0NCisJCQl1bm1hcC0+bGVuID0gbGVuOw0KKw0KKwkJCXR4ID0gZGV2aWNlLT5kZXZpY2VfcHJl
cF9kbWFfeG9yX3ZhbChjaGFuLCB1bm1hcC0+YWRkciwNCisJCQkJCQkJICAgICBzcmNfY250LA0K
KwkJCQkJCQkgICAgIGxlbiwgcmVzdWx0LA0KKwkJCQkJCQkgICAgIGRtYV9wcmVwX2ZsYWdzKTsN
CisJCQlpZiAodW5saWtlbHkoIXR4KSkgew0KKwkJCQlhc3luY190eF9xdWllc2NlKCZzdWJtaXQt
PmRlcGVuZF90eCk7DQorDQorCQkJCXdoaWxlICghdHgpIHsNCisJCQkJCWRtYV9hc3luY19pc3N1
ZV9wZW5kaW5nKGNoYW4pOw0KKwkJCQkJdHggPSBkZXZpY2UtPmRldmljZV9wcmVwX2RtYV94b3Jf
dmFsKA0KKwkJCQkJCQljaGFuLCB1bm1hcC0+YWRkciwNCisJCQkJCQkJc3JjX2NudCwgbGVuLA0K
KwkJCQkJCQlyZXN1bHQsIGRtYV9wcmVwX2ZsYWdzKTsNCisJCQkJfQ0KIAkJCX0NCisJCQlkbWFf
c2V0X3VubWFwKHR4LCB1bm1hcCk7DQorCQkJYXN5bmNfdHhfc3VibWl0KGNoYW4sIHR4LCBzdWJt
aXQpOw0KKw0KKwkJCXJldHVybiB0eDsNCiAJCX0NCi0JCWRtYV9zZXRfdW5tYXAodHgsIHVubWFw
KTsNCi0JCWFzeW5jX3R4X3N1Ym1pdChjaGFuLCB0eCwgc3VibWl0KTsNCi0JfSBlbHNlIHsNCi0J
CWVudW0gYXN5bmNfdHhfZmxhZ3MgZmxhZ3Nfb3JpZyA9IHN1Ym1pdC0+ZmxhZ3M7DQorCX0NCiAN
Ci0JCXByX2RlYnVnKCIlczogKHN5bmMpIGxlbjogJXp1XG4iLCBfX2Z1bmNfXywgbGVuKTsNCi0J
CVdBUk5fT05DRShkZXZpY2UgJiYgc3JjX2NudCA8PSBkZXZpY2UtPm1heF94b3IsDQotCQkJICAi
JXM6IG5vIHNwYWNlIGZvciBkbWEgYWRkcmVzcyBjb252ZXJzaW9uXG4iLA0KLQkJCSAgX19mdW5j
X18pOw0KKwkvKiBydW4gdGhlIHhvcl92YWwgc3luY2hyb25vdXNseSAqLw0KKwlwcl9kZWJ1Zygi
JXM6IChzeW5jKSBsZW46ICV6dVxuIiwgX19mdW5jX18sIGxlbik7DQorCVdBUk5fT05DRShkZXZp
Y2UgJiYgc3JjX2NudCA8PSBkZXZpY2UtPm1heF94b3IsDQorCQkgICIlczogbm8gc3BhY2UgZm9y
IGRtYSBhZGRyZXNzIGNvbnZlcnNpb25cbiIsDQorCQkgIF9fZnVuY19fKTsNCiANCi0JCXN1Ym1p
dC0+ZmxhZ3MgfD0gQVNZTkNfVFhfWE9SX0RST1BfRFNUOw0KLQkJc3VibWl0LT5mbGFncyAmPSB+
QVNZTkNfVFhfQUNLOw0KKwlzdWJtaXQtPmZsYWdzIHw9IEFTWU5DX1RYX1hPUl9EUk9QX0RTVDsN
CisJc3VibWl0LT5mbGFncyAmPSB+QVNZTkNfVFhfQUNLOw0KIA0KLQkJdHggPSBhc3luY194b3Io
ZGVzdCwgc3JjX2xpc3QsIG9mZnNldCwgc3JjX2NudCwgbGVuLCBzdWJtaXQpOw0KKwl0eCA9IGFz
eW5jX3hvcihkZXN0LCBzcmNfbGlzdCwgb2Zmc2V0LCBzcmNfY250LCBsZW4sIHN1Ym1pdCk7DQog
DQotCQlhc3luY190eF9xdWllc2NlKCZ0eCk7DQorCWFzeW5jX3R4X3F1aWVzY2UoJnR4KTsNCiAN
Ci0JCSpyZXN1bHQgPSAhcGFnZV9pc196ZXJvKGRlc3QsIG9mZnNldCwgbGVuKSA8PCBTVU1fQ0hF
Q0tfUDsNCisJKnJlc3VsdCA9ICFwYWdlX2lzX3plcm8oZGVzdCwgb2Zmc2V0LCBsZW4pIDw8IFNV
TV9DSEVDS19QOw0KIA0KLQkJYXN5bmNfdHhfc3luY19lcGlsb2coc3VibWl0KTsNCi0JCXN1Ym1p
dC0+ZmxhZ3MgPSBmbGFnc19vcmlnOw0KLQl9DQotCWRtYWVuZ2luZV91bm1hcF9wdXQodW5tYXAp
Ow0KKwlhc3luY190eF9zeW5jX2VwaWxvZyhzdWJtaXQpOw0KKwlzdWJtaXQtPmZsYWdzID0gZmxh
Z3Nfb3JpZzsNCiANCi0JcmV0dXJuIHR4Ow0KKwlyZXR1cm4gTlVMTDsNCiB9DQogRVhQT1JUX1NZ
TUJPTF9HUEwoYXN5bmNfeG9yX3ZhbCk7DQogDQotLQ0KMS44LjMuMg0KDQoNCg==

^ permalink raw reply

* Re: [PATCH] powerpc/le: enable RTAS events support
From: Greg Kurz @ 2014-03-31  8:47 UTC (permalink / raw)
  To: Stewart Smith; +Cc: linux-kernel, paulus, anton, nfont, linuxppc-dev
In-Reply-To: <87vbuv9vaz.fsf@river.i-did-not-set--mail-host-address--so-tickle-me>

On Mon, 31 Mar 2014 09:27:16 +1100
Stewart Smith <stewart@linux.vnet.ibm.com> wrote:
> Greg Kurz <gkurz@linux.vnet.ibm.com> writes:
> >  struct rtas_error_log {
> > +#ifdef __BIG_ENDIAN__
> > +	/* Byte 0 */
> >  	unsigned long version:8;		/* Architectural version */
> > +	/* Byte 1 */
> 
> I think it would be great if we got rid of the usage of bitfields. As
> soon as the mood of the compiler changes, this code is going to break.

True... even though I am not so sure the compiler is likely to break
things in this specific case where no bitfield crosses the byte boundary.
Anyway, Nathan has done some work in the direction you suggest.

Nathan,

Could you send your patch to the list ?

Thanks.

-- 
Gregory Kurz                                     kurzgreg@fr.ibm.com
                                                 gkurz@linux.vnet.ibm.com
Software Engineer @ IBM/Meiosys                  http://www.ibm.com
Tel +33 (0)562 165 496

"Anarchy is about taking complete responsibility for yourself."
        Alan Moore.

^ permalink raw reply

* [PATCH] ASoC: fsl_sai: Fix buggy configurations in trigger()
From: Nicolin Chen @ 2014-03-31 11:39 UTC (permalink / raw)
  To: broonie; +Cc: alsa-devel, Li.Xiubo, linuxppc-dev, linux-kernel, timur

The current trigger() has two crucial problems:
1) The DMA request enabling operations (FSL_SAI_CSR_FRDE) for Tx and Rx are
   now totally exclusive: It would fail to run simultaneous Tx-Rx cases.
2) The TERE disabling operation depends on an incorrect condition -- active
   reference count that only gets increased in snd_pcm_open() and decreased
   in snd_pcm_close(): The TERE would never get cleared.

So this patch overwrites the trigger function by following these rules:
A) We continue to support tx-async-while-rx-sync-to-tx case alone, which's
   originally limited by this fsl_sai driver, but we make the code easy to
   modify for the further support of the opposite case.
B) We enable both TE and RE for PLAYBACK stream or CAPTURE stream but only
   enabling the DMA request bit (FSL_SAI_CSR_FRDE) of the current direction
   due to the requirement of SAI -- For tx-async-while-rx-sync-to-tx case,
   the receiver is enabled only when both the transmitter and receiver are
   enabled.
C) We only enable one side interrupt for each stream since over/underrun
   on the opposite stream would be resulted from what we've done in rule B:
   enabling TERE but remaining FRDE disabled, even though the xrun on the
   opposite direction will not break the current stream.

Tested cases:
a) aplay test.wav -d5
b) arecord -r44100 -c2 -fS16_LE test.wav -d5
c) arecord -r44100 -c2 -fS16_LE -d5 | aplay
d) (aplay test2.wav &); sleep 1; arecord -r44100 -c2 -fS16_LE test.wav -d1
e) (arecord -r44100 -c2 -fS16_LE test.wav -d5 &); sleep 1; aplay test.wav -d1

Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com>
---
 sound/soc/fsl/fsl_sai.c | 43 +++++++++++++++++++++++--------------------
 sound/soc/fsl/fsl_sai.h | 11 +++++++++++
 2 files changed, 34 insertions(+), 20 deletions(-)

diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index f088545..d64c33f 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -365,6 +365,7 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
 		struct snd_soc_dai *cpu_dai)
 {
 	struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
+	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
 	u32 tcsr, rcsr;
 
 	/*
@@ -379,14 +380,6 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
 	regmap_read(sai->regmap, FSL_SAI_TCSR, &tcsr);
 	regmap_read(sai->regmap, FSL_SAI_RCSR, &rcsr);
 
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		tcsr |= FSL_SAI_CSR_FRDE;
-		rcsr &= ~FSL_SAI_CSR_FRDE;
-	} else {
-		rcsr |= FSL_SAI_CSR_FRDE;
-		tcsr &= ~FSL_SAI_CSR_FRDE;
-	}
-
 	/*
 	 * It is recommended that the transmitter is the last enabled
 	 * and the first disabled.
@@ -395,22 +388,32 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		tcsr |= FSL_SAI_CSR_TERE;
-		rcsr |= FSL_SAI_CSR_TERE;
+		if (!(tcsr & FSL_SAI_CSR_FRDE || rcsr & FSL_SAI_CSR_FRDE)) {
+			regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
+					   FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
+			regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
+					   FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
+		}
 
-		regmap_write(sai->regmap, FSL_SAI_RCSR, rcsr);
-		regmap_write(sai->regmap, FSL_SAI_TCSR, tcsr);
+		regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
+				   FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS);
+		regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
+				   FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		if (!(cpu_dai->playback_active || cpu_dai->capture_active)) {
-			tcsr &= ~FSL_SAI_CSR_TERE;
-			rcsr &= ~FSL_SAI_CSR_TERE;
+		regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
+				   FSL_SAI_CSR_FRDE, 0);
+		regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
+				   FSL_SAI_CSR_xIE_MASK, 0);
+
+		if (!(tcsr & FSL_SAI_CSR_FRDE || rcsr & FSL_SAI_CSR_FRDE)) {
+			regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
+					   FSL_SAI_CSR_TERE, 0);
+			regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
+					   FSL_SAI_CSR_TERE, 0);
 		}
-
-		regmap_write(sai->regmap, FSL_SAI_TCSR, tcsr);
-		regmap_write(sai->regmap, FSL_SAI_RCSR, rcsr);
 		break;
 	default:
 		return -EINVAL;
@@ -464,8 +467,8 @@ static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai)
 {
 	struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);
 
-	regmap_update_bits(sai->regmap, FSL_SAI_TCSR, 0xffffffff, FSL_SAI_FLAGS);
-	regmap_update_bits(sai->regmap, FSL_SAI_RCSR, 0xffffffff, FSL_SAI_FLAGS);
+	regmap_update_bits(sai->regmap, FSL_SAI_TCSR, 0xffffffff, 0x0);
+	regmap_update_bits(sai->regmap, FSL_SAI_RCSR, 0xffffffff, 0x0);
 	regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK,
 			   FSL_SAI_MAXBURST_TX * 2);
 	regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK,
diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h
index a264185..be26d46 100644
--- a/sound/soc/fsl/fsl_sai.h
+++ b/sound/soc/fsl/fsl_sai.h
@@ -35,6 +35,16 @@
 #define FSL_SAI_RFR	0xc0 /* SAI Receive FIFO */
 #define FSL_SAI_RMR	0xe0 /* SAI Receive Mask */
 
+#define FSL_SAI_xCSR(tx)	(tx ? FSL_SAI_TCSR : FSL_SAI_RCSR)
+#define FSL_SAI_xCR1(tx)	(tx ? FSL_SAI_TCR1 : FSL_SAI_RCR1)
+#define FSL_SAI_xCR2(tx)	(tx ? FSL_SAI_TCR2 : FSL_SAI_RCR2)
+#define FSL_SAI_xCR3(tx)	(tx ? FSL_SAI_TCR3 : FSL_SAI_RCR3)
+#define FSL_SAI_xCR4(tx)	(tx ? FSL_SAI_TCR4 : FSL_SAI_RCR4)
+#define FSL_SAI_xCR5(tx)	(tx ? FSL_SAI_TCR5 : FSL_SAI_RCR5)
+#define FSL_SAI_xDR(tx)		(tx ? FSL_SAI_TDR : FSL_SAI_RDR)
+#define FSL_SAI_xFR(tx)		(tx ? FSL_SAI_TFR : FSL_SAI_RFR)
+#define FSL_SAI_xMR(tx)		(tx ? FSL_SAI_TMR : FSL_SAI_RMR)
+
 /* SAI Transmit/Recieve Control Register */
 #define FSL_SAI_CSR_TERE	BIT(31)
 #define FSL_SAI_CSR_FR		BIT(25)
@@ -48,6 +58,7 @@
 #define FSL_SAI_CSR_FWF		BIT(17)
 #define FSL_SAI_CSR_FRF		BIT(16)
 #define FSL_SAI_CSR_xIE_SHIFT	8
+#define FSL_SAI_CSR_xIE_MASK	(0x1f << FSL_SAI_CSR_xIE_SHIFT)
 #define FSL_SAI_CSR_WSIE	BIT(12)
 #define FSL_SAI_CSR_SEIE	BIT(11)
 #define FSL_SAI_CSR_FEIE	BIT(10)
-- 
1.8.4

^ permalink raw reply related

* Re: [PATCH] powerpc/le: enable RTAS events support
From: Benjamin Herrenschmidt @ 2014-03-31 11:56 UTC (permalink / raw)
  To: Stewart Smith; +Cc: linux-kernel, paulus, anton, nfont, linuxppc-dev, Greg Kurz
In-Reply-To: <87vbuv9vaz.fsf@river.i-did-not-set--mail-host-address--so-tickle-me>

On Mon, 2014-03-31 at 09:27 +1100, Stewart Smith wrote:
> Greg Kurz <gkurz@linux.vnet.ibm.com> writes:
> >  struct rtas_error_log {
> > +#ifdef __BIG_ENDIAN__
> > +	/* Byte 0 */
> >  	unsigned long version:8;		/* Architectural version */
> > +	/* Byte 1 */
> 
> I think it would be great if we got rid of the usage of bitfields. As
> soon as the mood of the compiler changes, this code is going to break.

 ... as would a whole pile of kernel code including filesystems :)

Now, don't get me wrong, I hate bitfields as much as you do for the same
reasons. However (unfortunately ?) we've somewhat painted ourselves into
a corner here in kernel-land and I suspect gcc would have a very hard
time changing the format considering how many people did just the same
we did.

Now if we were a userspace program, I would still insist on fixing it on
the ground on not depending on gcc but this is the kernel ... we have
more gcc'isms than spots on the face of a 14 yrs old..

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH 1/2] powerpc/powernv: Add OPAL message log interface
From: Benjamin Herrenschmidt @ 2014-03-31 11:59 UTC (permalink / raw)
  To: Michael Neuling
  Cc: stewart, michael, shangw, hegdevasant, paulus, Joel Stanley,
	linuxppc-dev, anton
In-Reply-To: <21604.1396238935@ale.ozlabs.ibm.com>

On Mon, 2014-03-31 at 15:08 +1100, Michael Neuling wrote:

> > +/* OPAL in-memory console. Defined in OPAL source at core/console.c */
> > +struct memcons {
> > +	__be64 magic;
> > +#define MEMCONS_MAGIC	0x6630696567726173L
> 
> 0x6630696567726173 == f0iegras ... Ben!!! :-P

Yummy ! :-)

> > +	__be64 obuf_phys;
> > +	__be64 ibuf_phys;
> > +	__be32 obuf_size;
> > +	__be32 ibuf_size;
> > +	__be32 out_pos;
> > +#define MEMCONS_OUT_POS_WRAP	0x80000000u
> > +#define MEMCONS_OUT_POS_MASK	0x00ffffffu
> > +	__be32 in_prod;
> > +	__be32 in_cons;
> > +};
> > +
> > +static ssize_t opal_messages_read(struct file *file, struct kobject *kobj,
> > +	struct bin_attribute *bin_attr, char *to, loff_t pos, size_t count)
> > +{
> > +	struct memcons *mc = bin_attr->private;
> > +	const char *conbuf;
> > +	bool wrapped;
> > +	size_t num_read;
> > +	int out_pos;
> > +
> > +	if (!mc)
> > +		return -ENODEV;
> > +
> > +	conbuf = phys_to_virt(be64_to_cpu(mc->obuf_phys));
> > +	wrapped = be32_to_cpu(mc->out_pos) & MEMCONS_OUT_POS_WRAP;
> > +	out_pos = be32_to_cpu(mc->out_pos) & MEMCONS_OUT_POS_MASK;
> > +
> 
> Are there ordering issues we need to think about here with reading
> these?  Can the messages be written on another CPU at the same time as
> these are being read?

Good point. out_pos should probably be read only once into a local
variable using the ACCESS_ONCE macro, and then only be broken up.

> What happens if in between reading wrapped and out_pos the buffer wraps?
> You'd end up getting only a few bytes of console?  Maybe you need to
> read wrapped before and after out_pos to make should it's not wrapped in
> between.

Unlikely but yes, it can happen.

> > +	if (!wrapped) {
> 
> Why the negative case first?  Just make it:
> 
>    if (wrapped) {
>       wrapped case
>    } else {
>       not wrapped case
>    }
> 
> Also, no curlies needed for single statement.
> 
> 
> > +		num_read = memory_read_from_buffer(to, count, &pos, conbuf,
> > +				out_pos);
> 
> This is probably not necessary, but do we need to sanity check out_pos <
> obuf_size?  I guess we don't generally sanity check numbers from OPAL as
> it can screw us in many other ways anyway.

On the other hand it doesn't cost much and if the FW goes bonkers it
will give us a better handle to debug from.

> > +	} else {
> > +		num_read = memory_read_from_buffer(to, count, &pos,
> > +				conbuf + out_pos,
> > +				be32_to_cpu(mc->obuf_size) - out_pos);
> > +
> > +		if (num_read < 0)
> > +			goto out;
> > +
> > +		num_read += memory_read_from_buffer(to + num_read,
> > +				count - num_read, &pos, conbuf,
> >                out_pos);
> 
> What if this second read returns an error?  num_read += -ERRNO?  I think
> you need to check this return independently.

Cheers,
Ben.

> Mikey
> 
> > +	}
> > +out:
> > +	return num_read;
> > +}
> > +
> > +static struct bin_attribute messages_attr = {
> > +	.attr = {.name = "messages", .mode = 0444},
> > +	.read = opal_messages_read
> > +};
> > +
> > +void __init opal_messages_init(void)
> > +{
> > +	u64 mcaddr;
> > +	struct memcons *mc;
> > +
> > +	if (of_property_read_u64(opal_node, "ibm,opal-memcons", &mcaddr)) {
> > +		pr_warn("OPAL: Property ibm,opal-memcons not found, no message log\n");
> > +		return;
> > +	}
> > +
> > +	mc = phys_to_virt(mcaddr);
> > +	if (!mc) {
> > +		pr_warn("OPAL: memory console address is invalid\n");
> > +		return;
> > +	}
> > +
> > +	if (be64_to_cpu(mc->magic) != MEMCONS_MAGIC) {
> > +		pr_warn("OPAL: memory console version is invalid\n");
> > +		return;
> > +	}
> > +
> > +	messages_attr.private = mc;
> > +
> > +	if (sysfs_create_bin_file(opal_kobj, &messages_attr) != 0)
> > +		pr_warn("OPAL: sysfs file creation failed\n");
> > +}
> > diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
> > index e92f2f6..2bc032a 100644
> > --- a/arch/powerpc/platforms/powernv/opal.c
> > +++ b/arch/powerpc/platforms/powernv/opal.c
> > @@ -46,7 +46,7 @@ struct mcheck_recoverable_range {
> >  static struct mcheck_recoverable_range *mc_recoverable_range;
> >  static int mc_recoverable_range_len;
> >  
> > -static struct device_node *opal_node;
> > +struct device_node *opal_node;
> >  static DEFINE_SPINLOCK(opal_write_lock);
> >  extern u64 opal_mc_secondary_handler[];
> >  static unsigned int *opal_irqs;
> > @@ -574,6 +574,8 @@ static int __init opal_init(void)
> >  		opal_platform_dump_init();
> >  		/* Setup system parameters interface */
> >  		opal_sys_param_init();
> > +		/* Setup message log interface. */
> > +		opal_messages_init();
> >  	}
> >  
> >  	return 0;
> > -- 
> > 1.9.1
> > 
> > _______________________________________________
> > Linuxppc-dev mailing list
> > Linuxppc-dev@lists.ozlabs.org
> > https://lists.ozlabs.org/listinfo/linuxppc-dev

^ permalink raw reply

* Re: [PATCH 3/4] KVM: PPC: Alow kvmppc_get_last_inst() to fail
From: Alexander Graf @ 2014-03-31 13:32 UTC (permalink / raw)
  To: Scott Wood; +Cc: Mihai Caraman, linuxppc-dev, kvm, kvm-ppc
In-Reply-To: <1395867121.12738.56.camel@snotra.buserror.net>

On 03/26/2014 09:52 PM, Scott Wood wrote:
> On Thu, 2014-02-20 at 18:30 +0200, Mihai Caraman wrote:
>> diff --git a/arch/powerpc/kvm/book3s_paired_singles.c b/arch/powerpc/kvm/book3s_paired_singles.c
>> index a59a25a..80c533e 100644
>> --- a/arch/powerpc/kvm/book3s_paired_singles.c
>> +++ b/arch/powerpc/kvm/book3s_paired_singles.c
>> @@ -640,19 +640,24 @@ static int kvmppc_ps_one_in(struct kvm_vcpu *vcpu, bool rc,
>>   
>>   int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu)
>>   {
>> -	u32 inst = kvmppc_get_last_inst(vcpu);
>> +	u32 inst;
>>   	enum emulation_result emulated = EMULATE_DONE;
>> -
>> -	int ax_rd = inst_get_field(inst, 6, 10);
>> -	int ax_ra = inst_get_field(inst, 11, 15);
>> -	int ax_rb = inst_get_field(inst, 16, 20);
>> -	int ax_rc = inst_get_field(inst, 21, 25);
>> -	short full_d = inst_get_field(inst, 16, 31);
>> -
>> -	u64 *fpr_d = &vcpu->arch.fpr[ax_rd];
>> -	u64 *fpr_a = &vcpu->arch.fpr[ax_ra];
>> -	u64 *fpr_b = &vcpu->arch.fpr[ax_rb];
>> -	u64 *fpr_c = &vcpu->arch.fpr[ax_rc];
>> +	int ax_rd, ax_ra, ax_rb, ax_rc;
>> +	short full_d;
>> +	u64 *fpr_d, *fpr_a, *fpr_b, *fpr_c;
>> +
>> +	kvmppc_get_last_inst(vcpu, &inst);
> Should probably check for failure here and elsewhere -- even though it
> can't currently fail on book3s, the interface now allows it.
>
>> diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
>> index 5b9e906..b0d884d 100644
>> --- a/arch/powerpc/kvm/book3s_pr.c
>> +++ b/arch/powerpc/kvm/book3s_pr.c
>> @@ -624,9 +624,10 @@ void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr)
>>   static int kvmppc_read_inst(struct kvm_vcpu *vcpu)
>>   {
>>   	ulong srr0 = kvmppc_get_pc(vcpu);
>> -	u32 last_inst = kvmppc_get_last_inst(vcpu);
>> +	u32 last_inst;
>>   	int ret;
>>   
>> +	kvmppc_get_last_inst(vcpu, &last_inst);
>>   	ret = kvmppc_ld(vcpu, &srr0, sizeof(u32), &last_inst, false);
> This isn't new, but this function looks odd to me -- calling
> kvmppc_get_last_inst() but ignoring last_inst, then calling kvmppc_ld()
> and ignoring anything but failure.  last_inst itself is never read.  And
> no comments to explain the weirdness. :-)
>
> I get that kvmppc_get_last_inst() is probably being used for the side
> effect of filling in vcpu->arch.last_inst, but why store the return
> value without using it?  Why pass the address of it to kvmppc_ld(),
> which seems to be used only as an indirect way of determining whether
> kvmppc_get_last_inst() failed?  And that whole mechanism becomes
> stranger once it becomes possible for kvmppc_get_last_inst() to directly
> return failure.

If you're interested in the history of this, here's the patch :)

https://github.com/mirrors/linux-2.6/commit/c7f38f46f2a98d232147e47284cb4e7363296a3e

The idea is that we need 2 things to be good after this function:

   1) vcpu->arch.last_inst is valid
   2) if the last instruction is not readable, return failure

Hence this weird construct. I don't think it's really necessary though - 
just remove the kvmppc_ld() call and only fail read_inst() when the 
caching didn't work and we can't translate the address.


Alex

^ permalink raw reply

* Re: [PATCH 4/4] KVM: PPC: Bookehv: Get vcpu's last instruction for emulation
From: Alexander Graf @ 2014-03-31 13:41 UTC (permalink / raw)
  To: Scott Wood; +Cc: Mihai Caraman, linuxppc-dev, kvm, kvm-ppc
In-Reply-To: <1395868664.12738.68.camel@snotra.buserror.net>

On 03/26/2014 10:17 PM, Scott Wood wrote:
> On Thu, 2014-02-20 at 18:30 +0200, Mihai Caraman wrote:
>> Load external pid (lwepx) instruction faults (when called from
>> KVM with guest context) needs to be handled by KVM. This implies
>> additional code in DO_KVM macro to identify the source of the
>> exception (which oiginate from KVM host rather than the guest).
>> The hook requires to check the Exception Syndrome Register
>> ESR[EPID] and External PID Load Context Register EPLC[EGS] for
>> some exceptions (DTLB_MISS, DSI and LRAT). Doing this on Data TLB
>> miss exception is obvious intrusive for the host.
>>
>> Get rid of lwepx and acquire last instuction in kvmppc_get_last_inst()
>> by searching for the physical address and kmap it. This fixes an
>> infinite loop caused by lwepx's data TLB miss handled in the host
>> and the TODO for TLB eviction and execute-but-not-read entries.
>>
>> Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
>> ---
>>   arch/powerpc/kvm/bookehv_interrupts.S |   37 +++----------
>>   arch/powerpc/kvm/e500_mmu_host.c      |   93 +++++++++++++++++++++++++++++++++
>>   2 files changed, 102 insertions(+), 28 deletions(-)
>>
>> diff --git a/arch/powerpc/kvm/bookehv_interrupts.S b/arch/powerpc/kvm/bookehv_interrupts.S
>> index 20c7a54..c50490c 100644
>> --- a/arch/powerpc/kvm/bookehv_interrupts.S
>> +++ b/arch/powerpc/kvm/bookehv_interrupts.S
>> @@ -119,38 +119,14 @@
>>   1:
>>   
>>   	.if	\flags & NEED_EMU
>> -	/*
>> -	 * This assumes you have external PID support.
>> -	 * To support a bookehv CPU without external PID, you'll
>> -	 * need to look up the TLB entry and create a temporary mapping.
>> -	 *
>> -	 * FIXME: we don't currently handle if the lwepx faults.  PR-mode
>> -	 * booke doesn't handle it either.  Since Linux doesn't use
>> -	 * broadcast tlbivax anymore, the only way this should happen is
>> -	 * if the guest maps its memory execute-but-not-read, or if we
>> -	 * somehow take a TLB miss in the middle of this entry code and
>> -	 * evict the relevant entry.  On e500mc, all kernel lowmem is
>> -	 * bolted into TLB1 large page mappings, and we don't use
>> -	 * broadcast invalidates, so we should not take a TLB miss here.
>> -	 *
>> -	 * Later we'll need to deal with faults here.  Disallowing guest
>> -	 * mappings that are execute-but-not-read could be an option on
>> -	 * e500mc, but not on chips with an LRAT if it is used.
>> -	 */
>> -
>> -	mfspr	r3, SPRN_EPLC	/* will already have correct ELPID and EGS */
>>   	PPC_STL	r15, VCPU_GPR(R15)(r4)
>>   	PPC_STL	r16, VCPU_GPR(R16)(r4)
>>   	PPC_STL	r17, VCPU_GPR(R17)(r4)
>>   	PPC_STL	r18, VCPU_GPR(R18)(r4)
>>   	PPC_STL	r19, VCPU_GPR(R19)(r4)
>> -	mr	r8, r3
>>   	PPC_STL	r20, VCPU_GPR(R20)(r4)
>> -	rlwimi	r8, r6, EPC_EAS_SHIFT - MSR_IR_LG, EPC_EAS
>>   	PPC_STL	r21, VCPU_GPR(R21)(r4)
>> -	rlwimi	r8, r6, EPC_EPR_SHIFT - MSR_PR_LG, EPC_EPR
>>   	PPC_STL	r22, VCPU_GPR(R22)(r4)
>> -	rlwimi	r8, r10, EPC_EPID_SHIFT, EPC_EPID
>>   	PPC_STL	r23, VCPU_GPR(R23)(r4)
>>   	PPC_STL	r24, VCPU_GPR(R24)(r4)
>>   	PPC_STL	r25, VCPU_GPR(R25)(r4)
>> @@ -160,10 +136,15 @@
>>   	PPC_STL	r29, VCPU_GPR(R29)(r4)
>>   	PPC_STL	r30, VCPU_GPR(R30)(r4)
>>   	PPC_STL	r31, VCPU_GPR(R31)(r4)
>> -	mtspr	SPRN_EPLC, r8
>> -	isync
>> -	lwepx   r9, 0, r5
>> -	mtspr	SPRN_EPLC, r3
>> +
>> +	/*
>> +	 * We don't use external PID support. lwepx faults would need to be
>> +	 * handled by KVM and this implies aditional code in DO_KVM (for
>> +	 * DTB_MISS, DSI and LRAT) to check ESR[EPID] and EPLC[EGS] which
>> +	 * is too intrusive for the host. Get last instuction in
>> +	 * kvmppc_get_last_inst().
>> +	 */
>> +	li	r9, KVM_INST_FETCH_FAILED
>>   	stw	r9, VCPU_LAST_INST(r4)
>>   	.endif
>>   
>> diff --git a/arch/powerpc/kvm/e500_mmu_host.c b/arch/powerpc/kvm/e500_mmu_host.c
>> index 6025cb7..1b4cb41 100644
>> --- a/arch/powerpc/kvm/e500_mmu_host.c
>> +++ b/arch/powerpc/kvm/e500_mmu_host.c
>> @@ -598,9 +598,102 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 eaddr, gpa_t gpaddr,
>>   	}
>>   }
>>   
>> +#ifdef CONFIG_KVM_BOOKE_HV
>> +int kvmppc_ld_inst(struct kvm_vcpu *vcpu, u32 *instr)
> It'd be interesting to see what the performance impact of doing this on
> non-HV would be -- it would eliminate divergent code, eliminate the
> MSR_DS hack, and make exec-only mappings work.

We hit the instruction emulation path a lot more often on non-HV, so 
even a slight performance impact that might not be a major bummer for HV 
would become critical for PR.

But I agree - it'd be interesting to see numbers.

>
>> +{
>> +	gva_t geaddr;
>> +	hpa_t addr;
>> +	hfn_t pfn;
>> +	hva_t eaddr;
>> +	u32 mas0, mas1, mas2, mas3;
>> +	u64 mas7_mas3;
>> +	struct page *page;
>> +	unsigned int addr_space, psize_shift;
>> +	bool pr;
>> +	unsigned long flags;
>> +
>> +	/* Search TLB for guest pc to get the real address */
>> +	geaddr = kvmppc_get_pc(vcpu);
>> +	addr_space = (vcpu->arch.shared->msr & MSR_IS) >> MSR_IR_LG;
>> +
>> +	local_irq_save(flags);
>> +	mtspr(SPRN_MAS6, (vcpu->arch.pid << MAS6_SPID_SHIFT) | addr_space);
>> +	mtspr(SPRN_MAS5, MAS5_SGS | vcpu->kvm->arch.lpid);
>> +	isync();
>> +	asm volatile("tlbsx 0, %[geaddr]\n" : : [geaddr] "r" (geaddr));
> We can probably get away without that isync, despite what the manual
> says.  We've been doing it in other contexts on e500 since forever, and
> tlbsx has presync serialization which means it already waits for all
> previous instructions to complete before beginning execution.
>
>> +	mtspr(SPRN_MAS5, 0);
>> +	mtspr(SPRN_MAS8, 0);
>> +	mas0 = mfspr(SPRN_MAS0);
>> +	mas1 = mfspr(SPRN_MAS1);
>> +	mas2 = mfspr(SPRN_MAS2);
>> +	mas3 = mfspr(SPRN_MAS3);
>> +	mas7_mas3 = (((u64) mfspr(SPRN_MAS7)) << 32) | mfspr(SPRN_MAS3);
> Why read mas3 twice?
>
>> +	local_irq_restore(flags);
>> +
>> +	/*
>> +	 * If the TLB entry for guest pc was evicted, return to the guest.
>> +	 * There are high chances to find a valid TLB entry next time.
>> +	 */
>> +	if (!(mas1 & MAS1_VALID))
>> +		return EMULATE_AGAIN;
>> +
>> +	/*
>> +	 * Another thread may rewrite the TLB entry in parallel, don't
>> +	 * execute from the address if the execute permission is not set
>> +	 */

What happens when another thread rewrites the TLB entry in parallel? 
Does tlbsx succeed? Does it fail? Do we see failure indicated somehow? 
Are the contents of the MAS registers consistent at this point or 
inconsistent?

There has to be a good way to detect such a race and deal with it, no?

>> +	pr = vcpu->arch.shared->msr & MSR_PR;
>> +	if ((pr && (!(mas3 & MAS3_UX))) || ((!pr) && (!(mas3 & MAS3_SX)))) {
>> +		kvmppc_core_queue_inst_storage(vcpu, 0);
>> +		return EMULATE_AGAIN;
>> +	}
> s/(!foo)/!foo/g
>
>> +	/*
>> +	 * We will map the real address through a cacheable page, so we will
>> +	 * not support cache-inhibited guest pages. Fortunately emulated
>> +	 * instructions should not live there.
>> +	 */
>> +	if (mas2 & MAS2_I) {
>> +		printk(KERN_CRIT "Instuction emulation from cache-inhibited "
>> +				"guest pages is not supported\n");
>> +		return EMULATE_FAIL;
>> +	}
> This message needs to be ratelimited, and use pr_err() (or maybe even
> pr_debug()).

I'd go for pr_debug(). If anything we'd want a trace point indicating 
whether instruction fetching worked.


Alex

^ permalink raw reply

* Re: [PATCH v6 00/11] reserved-memory regions/CMA in devicetree, again
From: Grant Likely @ 2014-03-31 13:52 UTC (permalink / raw)
  To: Marek Szyprowski, Benjamin Herrenschmidt,
	Russell King - ARM Linux, Catalin Marinas
  Cc: devicetree@vger.kernel.org, Rob Herring,
	Linux Kernel Mailing List, linux-arm-kernel@lists.infradead.org,
	linuxppc-dev
In-Reply-To: <CACxGe6vbEMgZf6LvpHqsW353rcGVZ9iGFVuir4eP5qreC_eXpQ@mail.gmail.com>

On Tue, Mar 11, 2014 at 10:37 AM, Grant Likely <grant.likely@linaro.org> wrote:
> Hi Ben, Russell and Catalin,
>
> I've got this series queued up, and I'd like to be ready to merge it
> in the next merge window. I'm going to queue it up in linux-next. If
> you have any concerns, please shout and it can be removed. I won't ask
> Linus to pull it without you giving the okay.

Hi Ben and Russell.

Any feedback on this? The arch/powerpc and arch/arm patches are a
single line change each and are easy to revert if they cause problems.
I'm going to send Linus a pull request tomorrow morning if I don't
hear anything before then.

g.

> On Fri, Feb 28, 2014 at 1:42 PM, Marek Szyprowski
> <m.szyprowski@samsung.com> wrote:
>> Hello again!
>>
>> Here is another update of the support for reserved memory regions in
>> device tree. I've fixes a few more minor issues pointed by Grant. See
>> changelog for more details.
>>
>> The initial code for this feature were posted here [1], merged as commit
>> 9d8eab7af79cb4ce2de5de39f82c455b1f796963 ("drivers: of: add
>> initialization code for dma reserved memory") and later reverted by
>> commit 1931ee143b0ab72924944bc06e363d837ba05063. For more information,
>> see [2]. Finally a new bindings has been proposed [3] and Josh
>> Cartwright a few days ago prepared some code which implements those
>> bindings [4]. This finally pushed me again to find some time to finish
>> this task and review the code. Josh agreed to give me the ownership of
>> this series to continue preparing them for mainline inclusion.
>>
>> For more information please refer to the changlelog and links below.
>>
>> [1]: http://lkml.kernel.org/g/1377527959-5080-1-git-send-email-m.szyprowski@samsung.com
>> [2]: http://lkml.kernel.org/g/1381476448-14548-1-git-send-email-m.szyprowski@samsung.com
>> [3]: http://lkml.kernel.org/g/20131030134702.19B57C402A0@trevor.secretlab.ca
>> [4]: http://thread.gmane.org/gmane.linux.documentation/19579
>>
>> Changelog:
>>
>> v6:
>> - removed the need for "#memory-region-cells" property
>> - fixed compilation issues on some systems
>> - some other minor code cleanups
>>
>> v5: https://lkml.org/lkml/2014/2/21/147
>> - sliced main patch into several smaller patches on Grant's request
>> - fixed coding style issues pointed by Grant
>> - use node->phandle value directly instead of parsing properties manually
>>
>> v4: https://lkml.org/lkml/2014/2/20/150
>> - dynamic allocations are processed after all static reservations has been
>>   done
>> - moved code for handling static reservations to drivers/of/fdt.c
>> - removed node matching by string comparison, now phandle values are used
>>   directly
>> - moved code for DMA and CMA handling directly to
>>   drivers/base/dma-{coherent,contiguous}.c
>> - added checks for proper #size-cells, #address-cells, ranges properties
>>   in /reserved-memory node
>> - even more code cleanup
>> - added init code for ARM64 and PowerPC
>>
>> v3: http://article.gmane.org/gmane.linux.documentation/20169/
>> - refactored memory reservation code, created common code to parse reg, size,
>>   align, alloc-ranges properties
>> - added support for multiple tuples in 'reg' property
>> - memory is reserved regardless of presence of the driver for its compatible
>> - prepared arch specific hooks for memory reservation (defaults use memblock
>>   calls)
>> - removed node matching by string during device initialization
>> - CMA init code: added checks for required region alignment
>> - more code cleanup here and there
>>
>> v2: http://thread.gmane.org/gmane.linux.documentation/19870/
>> - removed copying of the node name
>> - split shared-dma-pool handling into separate files (one for CMA and one
>>   for dma_declare_coherent based implementations) for making the code easier
>>   to understand
>> - added support for AMBA devices, changed prototypes to use struct decice
>>   instead of struct platform_device
>> - renamed some functions to better match other names used in drivers/of/
>> - restructured the rest of the code a bit for better readability
>> - added 'reusable' property to exmaple linux,cma node in documentation
>> - exclusive dma (dma_coherent) is used for only handling 'shared-dma-pool'
>>   regions without 'reusable' property and CMA is used only for handling
>>   'shared-dma-pool' regions with 'reusable' property.
>>
>> v1: http://thread.gmane.org/gmane.linux.documentation/19579
>> - initial version prepared by Josh Cartwright
>>
>> Summary:
>>
>> Grant Likely (1):
>>   of: document bindings for reserved-memory nodes
>>
>> Marek Szyprowski (10):
>>   drivers: of: add initialization code for static reserved memory
>>   drivers: of: add initialization code for dynamic reserved memory
>>   drivers: of: add support for custom reserved memory drivers
>>   drivers: of: add automated assignment of reserved regions to client
>>     devices
>>   drivers: of: initialize and assign reserved memory to newly created
>>     devices
>>   drivers: dma-coherent: add initialization from device tree
>>   drivers: dma-contiguous: add initialization from device tree
>>   arm: add support for reserved memory defined by device tree
>>   arm64: add support for reserved memory defined by device tree
>>   powerpc: add support for reserved memory defined by device tree
>>
>>  .../bindings/reserved-memory/reserved-memory.txt   |  136 ++++++++++
>>  arch/arm/Kconfig                                   |    1 +
>>  arch/arm/mm/init.c                                 |    2 +
>>  arch/arm64/Kconfig                                 |    1 +
>>  arch/arm64/mm/init.c                               |    1 +
>>  arch/powerpc/Kconfig                               |    1 +
>>  arch/powerpc/kernel/prom.c                         |    3 +
>>  drivers/base/dma-coherent.c                        |   40 +++
>>  drivers/base/dma-contiguous.c                      |  129 +++++++--
>>  drivers/of/Kconfig                                 |    6 +
>>  drivers/of/Makefile                                |    1 +
>>  drivers/of/fdt.c                                   |  140 ++++++++++
>>  drivers/of/of_reserved_mem.c                       |  287 ++++++++++++++++++++
>>  drivers/of/platform.c                              |    7 +
>>  include/asm-generic/vmlinux.lds.h                  |   11 +
>>  include/linux/of_fdt.h                             |    3 +
>>  include/linux/of_reserved_mem.h                    |   60 ++++
>>  17 files changed, 807 insertions(+), 22 deletions(-)
>>  create mode 100644 Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
>>  create mode 100644 drivers/of/of_reserved_mem.c
>>  create mode 100644 include/linux/of_reserved_mem.h
>>
>> --
>> 1.7.9.5
>>

^ permalink raw reply

* Re: [RFC PATCH] powerpc/le: enable RTAS events support
From: Nathan Fontenot @ 2014-03-31 15:02 UTC (permalink / raw)
  To: Greg Kurz, benh; +Cc: linuxppc-dev, paulus, linux-kernel, anton
In-Reply-To: <20140328073344.26823.32931.stgit@bahia.local>

This is the patch that I worked up at the same time as Greg, the
biggest difference being that I took the approach of doing and's,
and shifting as opposed to re-defining the bit fields for LE.

One other difference is that I left out defines for bits in the
error log structures that we currently do not use. I did leave the
comments in the structs describing the bit layout for future reference
but did not feel we needed to provide a define for all of them.

NOTE: This patch has not been tested.

-Nathan

---
 arch/powerpc/include/asm/rtas.h           |   92 +++++++++++++++++++---------
 arch/powerpc/kernel/rtas.c                |   24 ++++++--
 arch/powerpc/kernel/rtasd.c               |   11 ++--
 arch/powerpc/platforms/pseries/mobility.c |    2 +-
 arch/powerpc/platforms/pseries/ras.c      |   18 ++++--
 5 files changed, 97 insertions(+), 50 deletions(-)

diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index a0e1add..6efa1b6 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -150,19 +150,45 @@ struct rtas_suspend_me_data {
 #define RTAS_VECTOR_EXTERNAL_INTERRUPT	0x500
 
 struct rtas_error_log {
-	unsigned long version:8;		/* Architectural version */
-	unsigned long severity:3;		/* Severity level of error */
-	unsigned long disposition:2;		/* Degree of recovery */
-	unsigned long extended:1;		/* extended log present? */
-	unsigned long /* reserved */ :2;	/* Reserved for future use */
-	unsigned long initiator:4;		/* Initiator of event */
-	unsigned long target:4;			/* Target of failed operation */
-	unsigned long type:8;			/* General event or error*/
-	unsigned long extended_log_length:32;	/* length in bytes */
-	unsigned char buffer[1];		/* Start of extended log */
+	/* Byte 0 */
+	uint8_t		version;		/* Architectural version */
+
+	/* Byte 1 */
+	uint8_t		severity;
+	/* XXXXXXXX
+	 * XXX		3: Severity level of error
+	 *    XX	2: Degree of recovery
+	 *      X	1: Extended log present?
+	 *       XX	2: Reserved
+	 */
+	
+	/* Byte 2 */
+	uint8_t		:8;
+	/* XXXXXXXX
+	 * XXXX		4: Initiator of event
+	 *     XXXX	4: Target of failed operation
+	 */
+	uint8_t		type;			/* General event or error*/
+	uint32_t	extended_log_length;	/* length in bytes */
+	unsigned char	buffer[1];		/* Start of extended log */
 						/* Variable length.      */
 };
 
+static inline uint8_t rtas_error_severity(struct rtas_error_log *elog)
+{
+	return (elog->severity & 0xE0) >> 5;
+}
+
+static inline uint8_t rtas_error_disposition(struct rtas_error_log *elog)
+{
+	return (elog->severity & 0x18) >> 3;
+}
+
+static inline uint8_t rtas_error_extended(struct rtas_error_log *elog)
+{
+	return elog->severity & 0x04;
+}
+
 #define RTAS_V6EXT_LOG_FORMAT_EVENT_LOG	14
 
 #define RTAS_V6EXT_COMPANY_ID_IBM	(('I' << 24) | ('B' << 16) | ('M' << 8))
@@ -172,34 +198,40 @@ struct rtas_error_log {
  */
 struct rtas_ext_event_log_v6 {
 	/* Byte 0 */
-	uint32_t log_valid:1;		/* 1:Log valid */
-	uint32_t unrecoverable_error:1;	/* 1:Unrecoverable error */
-	uint32_t recoverable_error:1;	/* 1:recoverable (correctable	*/
-					/*   or successfully retried)	*/
-	uint32_t degraded_operation:1;	/* 1:Unrecoverable err, bypassed*/
-					/*   - degraded operation (e.g.	*/
-					/*   CPU or mem taken off-line)	*/
-	uint32_t predictive_error:1;
-	uint32_t new_log:1;		/* 1:"New" log (Always 1 for	*/
-					/*   data returned from RTAS	*/
-	uint32_t big_endian:1;		/* 1: Big endian */
-	uint32_t :1;			/* reserved */
+	uint8_t	:8;
+	/* XXXXXXXX
+	 * X		1: Log valid
+	 *  X		1: Unrecoverable error
+	 *   X		1: Recoverable (correctable or successfully retried)
+	 *    X		1: Unrecoverable err, bypassed - degraded operation
+	 *		   (e.g. CPU or mem taken off-line)
+	 *     X	1: Preduictive error
+	 *      X	1: "New" log (Always 1 for data returned from RTAS)
+	 *       X	1: Big endian
+	 *        X	1: reserved
+	 */
+	
 	/* Byte 1 */
-	uint32_t :8;			/* reserved */
+	uint8_t :8;			/* reserved */
 	/* Byte 2 */
-	uint32_t powerpc_format:1;	/* Set to 1 (indicating log is	*/
-					/* in PowerPC format		*/
-	uint32_t :3;			/* reserved */
-	uint32_t log_format:4;		/* Log format indicator. Define	*/
-					/* format used for byte 12-2047	*/
+	uint8_t	format;
+	/* XXXXXXXX
+	 * X		1: Set to 1 (indicating log is in PowerPC format)
+	 *  XXX		3: Reserved
+	 *     XXXX	4: Log format indicator. Define format used for
+	 *		   byte 12-2047
+	 */
+	
 	/* Byte 3 */
-	uint32_t :8;			/* reserved */
+	uint8_t :8;			/* reserved */
 	/* Byte 4-11 */
 	uint8_t reserved[8];		/* reserved */
+	
 	/* Byte 12-15 */
-	uint32_t company_id;		/* Company ID of the company	*/
+	char	company_id[4];		/* Company ID of the company	*/
 					/* that defines the format for	*/
 					/* the vendor specific log type	*/
+
 	/* Byte 16-end of log */
 	uint8_t vendor_log[1];		/* Start of vendor specific log	*/
 					/* Variable length.		*/
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index f386296..314e3c9 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -979,6 +979,17 @@ int rtas_ibm_suspend_me(struct rtas_args *args)
 }
 #endif
 
+const char *rtas_v6ext_company_id = "IBM";
+/**
+ * Validate the company_id specified in the rtas extended event log
+ */
+static int rtas_valid_extv6_company_id(struct rtas_ext_event_log_v6 *extlog)
+{
+	return (extlog->company_id[0] == 'I' &&
+		extlog->company_id[1] == 'B' &&
+		extlog->company_id[2] == 'M');
+}
+
 /**
  * Find a specific pseries error log in an RTAS extended event log.
  * @log: RTAS error/event log
@@ -993,21 +1004,22 @@ struct pseries_errorlog *get_pseries_errorlog(struct rtas_error_log *log,
 		(struct rtas_ext_event_log_v6 *)log->buffer;
 	struct pseries_errorlog *sect;
 	unsigned char *p, *log_end;
+	uint32_t ext_log_length = be32_to_cpu(log->extended_log_length);
 
 	/* Check that we understand the format */
-	if (log->extended_log_length < sizeof(struct rtas_ext_event_log_v6) ||
-	    ext_log->log_format != RTAS_V6EXT_LOG_FORMAT_EVENT_LOG ||
-	    ext_log->company_id != RTAS_V6EXT_COMPANY_ID_IBM)
+	if (ext_log_length < sizeof(struct rtas_ext_event_log_v6) ||
+	    (ext_log->format & 0x0f) != RTAS_V6EXT_LOG_FORMAT_EVENT_LOG ||
+	    !rtas_valid_extv6_company_id(ext_log))
 		return NULL;
 
-	log_end = log->buffer + log->extended_log_length;
+	log_end = log->buffer + ext_log_length;
 	p = ext_log->vendor_log;
 
 	while (p < log_end) {
 		sect = (struct pseries_errorlog *)p;
-		if (sect->id == section_id)
+		if (be16_to_cpu(sect->id) == section_id)
 			return sect;
-		p += sect->length;
+		p += be16_to_cpu(sect->length);
 	}
 
 	return NULL;
diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c
index 1130c53..6940e26 100644
--- a/arch/powerpc/kernel/rtasd.c
+++ b/arch/powerpc/kernel/rtasd.c
@@ -151,7 +151,7 @@ static void printk_log_rtas(char *buf, int len)
 
 		printk(RTAS_DEBUG "event: %d, Type: %s, Severity: %d\n",
 		       error_log_cnt, rtas_event_type(errlog->type),
-		       errlog->severity);
+		       rtas_error_severity(errlog));
 	}
 }
 
@@ -163,10 +163,10 @@ static int log_rtas_len(char * buf)
 	/* rtas fixed header */
 	len = 8;
 	err = (struct rtas_error_log *)buf;
-	if (err->extended && err->extended_log_length) {
+	if (rtas_error_extended(err) && err->extended_log_length) {
 
 		/* extended header */
-		len += err->extended_log_length;
+		len += be32_to_cpu(err->extended_log_length);
 	}
 
 	if (rtas_error_log_max == 0)
@@ -293,12 +293,11 @@ void prrn_schedule_update(u32 scope)
 
 static void handle_rtas_event(const struct rtas_error_log *log)
 {
-	if (log->type == RTAS_TYPE_PRRN) {
+	if (log->type == RTAS_TYPE_PRRN && prrn_is_enabled()) {
 		/* For PRRN Events the extended log length is used to denote
 		 * the scope for calling rtas update-nodes.
 		 */
-		if (prrn_is_enabled())
-			prrn_schedule_update(log->extended_log_length);
+		prrn_schedule_update(be32_to_cpu(log->extended_log_length));
 	}
 
 	return;
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
index bde7eba..ef08cda 100644
--- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -46,7 +46,7 @@ static int mobility_rtas_call(int token, char *buf, s32 scope)
 	spin_lock(&rtas_data_buf_lock);
 
 	memcpy(rtas_data_buf, buf, RTAS_DATA_BUF_SIZE);
-	rc = rtas_call(token, 2, 1, NULL, rtas_data_buf, scope);
+	rc = rtas_call(token, 2, 1, NULL, rtas_data_buf, cpu_to_be32(scope));
 	memcpy(buf, rtas_data_buf, RTAS_DATA_BUF_SIZE);
 
 	spin_unlock(&rtas_data_buf_lock);
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index 721c058..0940734 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -236,7 +236,8 @@ static irqreturn_t ras_error_interrupt(int irq, void *dev_id)
 
 	rtas_elog = (struct rtas_error_log *)ras_log_buf;
 
-	if ((status == 0) && (rtas_elog->severity >= RTAS_SEVERITY_ERROR_SYNC))
+	if ((status == 0) &&
+	    (rtas_error_severity(rtas_elog) >= RTAS_SEVERITY_ERROR_SYNC))
 		fatal = 1;
 	else
 		fatal = 0;
@@ -300,13 +301,15 @@ static struct rtas_error_log *fwnmi_get_errinfo(struct pt_regs *regs)
 
 	/* If it isn't an extended log we can use the per cpu 64bit buffer */
 	h = (struct rtas_error_log *)&savep[1];
-	if (!h->extended) {
+	if (!rtas_error_extended(h)) {
 		memcpy(&__get_cpu_var(mce_data_buf), h, sizeof(__u64));
 		errhdr = (struct rtas_error_log *)&__get_cpu_var(mce_data_buf);
 	} else {
-		int len;
+		int len, error_log_length;
+
+		error_log_length = 8 + be32_to_cpu(h->extended_log_length);
+		len = max_t(int, error_log_length, RTAS_ERROR_LOG_MAX);
 
-		len = max_t(int, 8+h->extended_log_length, RTAS_ERROR_LOG_MAX);
 		memset(global_mce_data_buf, 0, RTAS_ERROR_LOG_MAX);
 		memcpy(global_mce_data_buf, h, len);
 		errhdr = (struct rtas_error_log *)global_mce_data_buf;
@@ -350,23 +353,24 @@ int pSeries_system_reset_exception(struct pt_regs *regs)
 static int recover_mce(struct pt_regs *regs, struct rtas_error_log *err)
 {
 	int recovered = 0;
+	int disposition = rtas_error_disposition(err);
 
 	if (!(regs->msr & MSR_RI)) {
 		/* If MSR_RI isn't set, we cannot recover */
 		recovered = 0;
 
-	} else if (err->disposition == RTAS_DISP_FULLY_RECOVERED) {
+	} else if (disposition == RTAS_DISP_FULLY_RECOVERED) {
 		/* Platform corrected itself */
 		recovered = 1;
 
-	} else if (err->disposition == RTAS_DISP_LIMITED_RECOVERY) {
+	} else if (disposition == RTAS_DISP_LIMITED_RECOVERY) {
 		/* Platform corrected itself but could be degraded */
 		printk(KERN_ERR "MCE: limited recovery, system may "
 		       "be degraded\n");
 		recovered = 1;
 
 	} else if (user_mode(regs) && !is_global_init(current) &&
-		   err->severity == RTAS_SEVERITY_ERROR_SYNC) {
+		   rtas_error_severity(err) == RTAS_SEVERITY_ERROR_SYNC) {
 
 		/*
 		 * If we received a synchronous error when in userspace

^ permalink raw reply related

* Re: [PATCH] ASoC: fsl_sai: Fix buggy configurations in trigger()
From: Mark Brown @ 2014-03-31 18:20 UTC (permalink / raw)
  To: Nicolin Chen; +Cc: alsa-devel, Li.Xiubo, linuxppc-dev, linux-kernel, timur
In-Reply-To: <1396265962-19343-1-git-send-email-Guangyu.Chen@freescale.com>

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

On Mon, Mar 31, 2014 at 07:39:22PM +0800, Nicolin Chen wrote:
> The current trigger() has two crucial problems:
> 1) The DMA request enabling operations (FSL_SAI_CSR_FRDE) for Tx and Rx are
>    now totally exclusive: It would fail to run simultaneous Tx-Rx cases.
> 2) The TERE disabling operation depends on an incorrect condition -- active
>    reference count that only gets increased in snd_pcm_open() and decreased
>    in snd_pcm_close(): The TERE would never get cleared.

Can you please check that this against my asoc-v3.15-4 tag - it doesn't
seem to apply there?

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

^ permalink raw reply

* Re: [PATCH] powerpc/le: enable RTAS events support
From: Stewart Smith @ 2014-03-31 22:15 UTC (permalink / raw)
  To: Greg Kurz; +Cc: linux-kernel, paulus, anton, nfont, linuxppc-dev
In-Reply-To: <20140331104716.1385b516@bahia.local>

Greg Kurz <gkurz@linux.vnet.ibm.com> writes:
> On Mon, 31 Mar 2014 09:27:16 +1100
> Stewart Smith <stewart@linux.vnet.ibm.com> wrote:
>> Greg Kurz <gkurz@linux.vnet.ibm.com> writes:
>> >  struct rtas_error_log {
>> > +#ifdef __BIG_ENDIAN__
>> > +	/* Byte 0 */
>> >  	unsigned long version:8;		/* Architectural version */
>> > +	/* Byte 1 */
>> 
>> I think it would be great if we got rid of the usage of bitfields. As
>> soon as the mood of the compiler changes, this code is going to break.
>
> True... even though I am not so sure the compiler is likely to break
> things in this specific case where no bitfield crosses the byte boundary.
> Anyway, Nathan has done some work in the direction you suggest.

It's allowed to, and it's allowed to based on compiler flags or phase of
the moon (and I've seen odd things because of this in the past) and my
bet is that there's no automated regression test that actually checks
that a newly built kernel from all distros actually works for parsing RTAS.

Besides, for things like unsigned long version:8 can easily be replaced
by uint8_t and teh problem goes away (at least for that bit).

I just hope the code we're getting this from doesn't also use bitfields :)

^ permalink raw reply

* OOPS in hvc / virtconsole
From: Andy Lutomirski @ 2014-03-31 22:31 UTC (permalink / raw)
  To: linux-kernel@vger.kernel.org, linuxppc-dev, virtio-dev,
	virtualization

I'm running a Fedora distro kernel (3.13.7-200.fc20.x86_64) in kvm
with these options:

-chardev null,id=hvc0,signal=off
-device virtio-serial-pci
-device virtconsole,chardev=hvc0,name=virtme_console
-append console=hvc0 console=ttyS0
-nographic

(There are more, but these are the interesting ones, I think.)

Note that virtio_console is modular, which might be a problem.

It blows up like this:

[    0.443591] kernel tried to execute NX-protected page - exploit
attempt? (uid: 0)
[    0.444004] BUG: unable to handle kernel paging request at ffffffff81d69c60
[    0.444004] IP: [<ffffffff81d69c60>] hvc_console_setup+0x0/0x24
[    0.444004] PGD 1c0f067 PUD 1c10063 PMD 7bcb9063 PTE 8000000001d69163
[    0.444004] Oops: 0011 [#1] SMP
[    0.444004] Modules linked in: virtio_pci virtio_console
9pnet_virtio virtio_ring virtio 9p 9pnet fscache
[    0.444004] CPU: 0 PID: 71 Comm: kworker/0:3 Not tainted
3.13.7-200.fc20.x86_64 #1
[    0.444004] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
[    0.444004] Workqueue: events control_work_handler [virtio_console]
[    0.444004] task: ffff88007bc04500 ti: ffff88007bcca000 task.ti:
ffff88007bcca000
[    0.444004] RIP: 0010:[<ffffffff81d69c60>]  [<ffffffff81d69c60>]
hvc_console_setup+0x0/0x24
[    0.444004] RSP: 0018:ffff88007bccbd40  EFLAGS: 00010246
[    0.444004] RAX: 0000000000000000 RBX: ffffffff81ca8a60 RCX: 0000000000000010
[    0.444004] RDX: ffffffff81d69c60 RSI: 0000000000000000 RDI: ffffffff81ca8a60
[    0.444004] RBP: ffff88007bccbd68 R08: ffffffff81ca8b10 R09: ffff88007c704000
[    0.444004] R10: ffffffff813f1d24 R11: 0000000000000000 R12: ffffffff81f155a0
[    0.444004] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[    0.444004] FS:  0000000000000000(0000) GS:ffff88007fc00000(0000)
knlGS:0000000000000000
[    0.444004] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[    0.444004] CR2: ffffffff81d69c60 CR3: 000000007bcc4000 CR4: 00000000000407f0
[    0.444004] Stack:
[    0.444004]  ffffffff810bfdbb ffff88007c704000 0000000000000000
0000000000000000
[    0.444004]  ffffffffa0050880 ffff88007bccbda8 ffffffff813f1e84
ffff88007c704000
[    0.444004]  ffff88007bd4a300 ffff88007c6deac4 ffff88007c6dea90
ffff88007c481000
[    0.444004] Call Trace:
[    0.444004]  [<ffffffff810bfdbb>] ? register_console+0x11b/0x370
[    0.444004]  [<ffffffff813f1e84>] hvc_alloc+0x1a4/0x330
[    0.444004]  [<ffffffffa004eb1b>] init_port_console+0x2b/0xe0
[virtio_console]
[    0.444004]  [<ffffffffa004fb2f>] control_work_handler+0x19f/0x3bc
[virtio_console]
[    0.444004]  [<ffffffff81087b76>] process_one_work+0x176/0x430
[    0.444004]  [<ffffffff810887ab>] worker_thread+0x11b/0x3a0
[    0.444004]  [<ffffffff81088690>] ? rescuer_thread+0x350/0x350
[    0.444004]  [<ffffffff8108f272>] kthread+0xd2/0xf0
[    0.444004]  [<ffffffff8108f1a0>] ? insert_kthread_work+0x40/0x40
[    0.444004]  [<ffffffff8169663c>] ret_from_fork+0x7c/0xb0
[    0.444004]  [<ffffffff8108f1a0>] ? insert_kthread_work+0x40/0x40
[    0.444004] Code: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc
cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc
cc cc cc cc <cc> cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc
cc cc
[    0.444004] RIP  [<ffffffff81d69c60>] hvc_console_setup+0x0/0x24
[    0.444004]  RSP <ffff88007bccbd40>
[    0.444004] CR2: ffffffff81d69c60
[    0.444004] ---[ end trace c5e5a6cab58be5c6 ]---
[    0.473583] BUG: unable to handle kernel paging request at ffffffffffffffd8
[    0.474098] IP: [<ffffffff8108f810>] kthread_data+0x10/0x20
[    0.474098] PGD 1c0f067 PUD 1c11067 PMD 0
[    0.474098] Oops: 0000 [#2] SMP
[    0.474098] Modules linked in: virtio_pci virtio_console
9pnet_virtio virtio_ring virtio 9p 9pnet fscache
[    0.474098] CPU: 0 PID: 71 Comm: kworker/0:3 Tainted: G      D
3.13.7-200.fc20.x86_64 #1
[    0.474098] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
[    0.474098] task: ffff88007bc04500 ti: ffff88007bcca000 task.ti:
ffff88007bcca000
[    0.474098] RIP: 0010:[<ffffffff8108f810>]  [<ffffffff8108f810>]
kthread_data+0x10/0x20
[    0.474098] RSP: 0018:ffff88007bccb990  EFLAGS: 00010002
[    0.474098] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 000000000000000a
[    0.474098] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff88007bc04500
[    0.474098] RBP: ffff88007bccb990 R08: ffff88007bc04590 R09: ffff88007fc17980
[    0.474098] R10: ffffffff8106af9c R11: ffffea0001f1f800 R12: ffff88007fc14580
[    0.474098] R13: 0000000000000000 R14: ffff88007bc044f0 R15: ffff88007bc04500
[    0.474098] FS:  0000000000000000(0000) GS:ffff88007fc00000(0000)
knlGS:0000000000000000
[    0.474098] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[    0.474098] CR2: 0000000000000028 CR3: 000000007bcc4000 CR4: 00000000000407f0
[    0.474098] Stack:
[    0.474098]  ffff88007bccb9a8 ffffffff81088e01 ffff88007bc04500
ffff88007bccba08
[    0.474098]  ffffffff8168ae09 ffff88007bc04500 ffff88007bccbfd8
0000000000014580
[    0.474098]  0000000000014580 ffff88007bc04500 ffff88007bc04ab8
ffff88007bccb7b0
[    0.474098] Call Trace:
[    0.474098]  [<ffffffff81088e01>] wq_worker_sleeping+0x11/0x90
[    0.474098]  [<ffffffff8168ae09>] __schedule+0x4a9/0x740
[    0.474098]  [<ffffffff8168b0c9>] schedule+0x29/0x70
[    0.474098]  [<ffffffff8106fca7>] do_exit+0x6a7/0xa20
[    0.474098]  [<ffffffff810be9f8>] ? console_unlock+0x1e8/0x3f0
[    0.474098]  [<ffffffff81d69c60>] ? vty_init+0x174/0x174
[    0.474098]  [<ffffffff8168f4ac>] oops_end+0x9c/0xe0
[    0.474098]  [<ffffffff81683092>] no_context+0x27e/0x28b
[    0.474098]  [<ffffffff81d69c60>] ? vty_init+0x174/0x174
[    0.474098]  [<ffffffff81683112>] __bad_area_nosemaphore+0x73/0x1ca
[    0.474098]  [<ffffffff813173af>] ? add_uevent_var+0x6f/0x110
[    0.474098]  [<ffffffff81d69c60>] ? vty_init+0x174/0x174
[    0.474098]  [<ffffffff8168327c>] bad_area_nosemaphore+0x13/0x15
[    0.474098]  [<ffffffff81691cda>] __do_page_fault+0x9a/0x530
[    0.474098]  [<ffffffff81413467>] ? get_device+0x17/0x30
[    0.474098]  [<ffffffff81418a45>] ? klist_class_dev_get+0x15/0x20
[    0.474098]  [<ffffffff81678cf2>] ? klist_add_tail+0x32/0x40
[    0.474098]  [<ffffffff81414c19>] ? device_add+0x219/0x640
[    0.474098]  [<ffffffff8169217e>] do_page_fault+0xe/0x10
[    0.474098]  [<ffffffff81691878>] do_async_page_fault+0x28/0xa0
[    0.474098]  [<ffffffff8168e938>] async_page_fault+0x28/0x30
[    0.474098]  [<ffffffff813f1d24>] ? hvc_alloc+0x44/0x330
[    0.474098]  [<ffffffff81d69c60>] ? vty_init+0x174/0x174
[    0.474098]  [<ffffffff81d69c60>] ? vty_init+0x174/0x174
[    0.474098]  [<ffffffff810bfdbb>] ? register_console+0x11b/0x370
[    0.474098]  [<ffffffff813f1e84>] hvc_alloc+0x1a4/0x330
[    0.474098]  [<ffffffffa004eb1b>] init_port_console+0x2b/0xe0
[virtio_console]
[    0.474098]  [<ffffffffa004fb2f>] control_work_handler+0x19f/0x3bc
[virtio_console]
[    0.474098]  [<ffffffff81087b76>] process_one_work+0x176/0x430
[    0.474098]  [<ffffffff810887ab>] worker_thread+0x11b/0x3a0
[    0.474098]  [<ffffffff81088690>] ? rescuer_thread+0x350/0x350
[    0.474098]  [<ffffffff8108f272>] kthread+0xd2/0xf0
[    0.474098]  [<ffffffff8108f1a0>] ? insert_kthread_work+0x40/0x40
[    0.474098]  [<ffffffff8169663c>] ret_from_fork+0x7c/0xb0
[    0.474098]  [<ffffffff8108f1a0>] ? insert_kthread_work+0x40/0x40
[    0.474098] Code: 00 48 89 e5 5d 48 8b 40 c8 48 c1 e8 02 83 e0 01
c3 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 48 8b 87 48 03 00 00
55 48 89 e5 <48> 8b 40 d8 5d c3 66 2e 0f 1f 84 00 00 00 00 00 66 66 66
66 90
[    0.474098] RIP  [<ffffffff8108f810>] kthread_data+0x10/0x20
[    0.474098]  RSP <ffff88007bccb990>
[    0.474098] CR2: ffffffffffffffd8
[    0.474098] ---[ end trace c5e5a6cab58be5c7 ]---
[    0.474098] Fixing recursive fault but reboot is needed!

^ permalink raw reply

* Re: [PATCH] powerpc/le: enable RTAS events support
From: Stewart Smith @ 2014-03-31 22:49 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linux-kernel, paulus, anton, nfont, linuxppc-dev, Greg Kurz
In-Reply-To: <1396266973.11529.77.camel@pasglop>

Benjamin Herrenschmidt <benh@kernel.crashing.org> writes:
> On Mon, 2014-03-31 at 09:27 +1100, Stewart Smith wrote:
>> Greg Kurz <gkurz@linux.vnet.ibm.com> writes:
>> >  struct rtas_error_log {
>> > +#ifdef __BIG_ENDIAN__
>> > +	/* Byte 0 */
>> >  	unsigned long version:8;		/* Architectural version */
>> > +	/* Byte 1 */
>> 
>> I think it would be great if we got rid of the usage of bitfields. As
>> soon as the mood of the compiler changes, this code is going to break.
>
>  ... as would a whole pile of kernel code including filesystems :)
>
> Now, don't get me wrong, I hate bitfields as much as you do for the same
> reasons. However (unfortunately ?) we've somewhat painted ourselves into
> a corner here in kernel-land and I suspect gcc would have a very hard
> time changing the format considering how many people did just the same
> we did.
>
> Now if we were a userspace program, I would still insist on fixing it on
> the ground on not depending on gcc but this is the kernel ... we have
> more gcc'isms than spots on the face of a 14 yrs old..

A quick grep didn't show up anything that looked like on disk
formats... at least for anything I care about :)

Maybe I've spent too long writing code for more than one compiler :)

^ permalink raw reply

* Re: [PATCH 1/2] powerpc/powernv: Add OPAL message log interface
From: Joel Stanley @ 2014-03-31 22:52 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Stewart Smith, michael, Michael Neuling, shangw, hegdevasant,
	paulus, Anton Blanchard, linuxppc-dev
In-Reply-To: <1396267178.11529.80.camel@pasglop>

On Mon, Mar 31, 2014 at 10:29 PM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
>> > +   conbuf = phys_to_virt(be64_to_cpu(mc->obuf_phys));
>> > +   wrapped = be32_to_cpu(mc->out_pos) & MEMCONS_OUT_POS_WRAP;
>> > +   out_pos = be32_to_cpu(mc->out_pos) & MEMCONS_OUT_POS_MASK;
>> > +
>>
>> Are there ordering issues we need to think about here with reading
>> these?  Can the messages be written on another CPU at the same time as
>> these are being read?
>
> Good point. out_pos should probably be read only once into a local
> variable using the ACCESS_ONCE macro, and then only be broken up.

I've got a V2 that fixes this and the other issues Mikey pointed out.

I found that the log would get corrupted from Linux's point of view
once full. Dumping the memory suggests that the contents of the
circular buffer is fine, and it's just our pointer (out_pos) that is
incorrect. It's not clear why this is happening; I'll do some more
testing before sending out the updated patch.

Cheers,

Joel

^ 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