LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* RE: [PATCH 2/2] Make the diu driver work without board level initilization
From: Jason.Jin @ 2014-04-01  7:28 UTC (permalink / raw)
  To: Li.Xiubo@freescale.com, Scott Wood, timur@tabi.org
  Cc: linux-fbdev@vger.kernel.org, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1305603ae9b846d9bc4c78f21a8c0494@BY2PR03MB505.namprd03.prod.outlook.com>

> > +	if (!diu_ops.set_pixel_clock) {
> > +		data->pixelclk_reg =3D of_iomap(np, 1);
> > +		if (!data->pixelclk_reg) {
> > +			dev_err(&pdev->dev, "Cannot map pixelclk registers,
> please \
> > +				provide the diu_ops for pixclk setting
> instead.\n");
>=20
> The error message should be in one line if possible, or it will hard to
> grep.
> If cannot, should split it into two or more lines, like:
>  +			dev_err(&pdev->dev, "Cannot map pixelclk registers,\n"
>  +				"please provide the diu_ops for pixclk setting
> instead.\n");
Thanks, This has been fixed in the update version, please help to review it=
 at:
http://patchwork.ozlabs.org/patch/335225/
I forgot to add the V2 information in the subject in the update patch so th=
is may confuse the reviewer, sorry for that.

Best Regards,
Jason=20

^ permalink raw reply

* [PATCH 2/2] powerpc: Enable NO_BOOTMEM
From: Emil Medve @ 2014-04-01  7:21 UTC (permalink / raw)
  To: benh, paulus, linuxppc-dev; +Cc: Emil Medve
In-Reply-To: <1396336891-13480-1-git-send-email-Emilian.Medve@Freescale.com>

Currently bootmem is just a wrapper around memblock. This gets rid of
the wrapper code just as other ARHC(es) did: x86, arm, etc.

Signed-off-by: Emil Medve <Emilian.Medve@Freescale.com>
---
 arch/powerpc/Kconfig  | 3 +++
 arch/powerpc/mm/mem.c | 8 ++++++++
 2 files changed, 11 insertions(+)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 957d3e5..2a2d4b3 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -471,6 +471,9 @@ config SYS_SUPPORTS_HUGETLBFS
 
 source "mm/Kconfig"
 
+config NO_BOOTMEM
+	def_bool y
+
 config ARCH_MEMORY_PROBE
 	def_bool y
 	depends on MEMORY_HOTPLUG
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index eaf5d1d8..d3e1d5f 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -187,10 +187,12 @@ EXPORT_SYMBOL_GPL(walk_system_ram_range);
 #ifndef CONFIG_NEED_MULTIPLE_NODES
 void __init do_init_bootmem(void)
 {
+#ifndef CONFIG_NO_BOOTMEM
 	unsigned long start, bootmap_pages;
 	struct memblock_region *reg;
 	int boot_mapsize;
 	phys_addr_t _total_lowmem;
+#endif
 	phys_addr_t _lowmem_end_addr;
 
 #ifndef CONFIG_HIGHMEM
@@ -203,6 +205,7 @@ void __init do_init_bootmem(void)
 	max_low_pfn = _lowmem_end_addr >> PAGE_SHIFT;
 	min_low_pfn = MEMORY_START >> PAGE_SHIFT;
 
+#ifndef CONFIG_NO_BOOTMEM
 	/*
 	 * Find an area to use for the bootmem bitmap.  Calculate the size of
 	 * bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE.
@@ -214,12 +217,14 @@ void __init do_init_bootmem(void)
 	start = memblock_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE);
 
 	boot_mapsize = init_bootmem_node(NODE_DATA(0), start >> PAGE_SHIFT, min_low_pfn, max_low_pfn);
+#endif
 
 	/* Place all memblock_regions in the same node and merge contiguous
 	 * memblock_regions
 	 */
 	memblock_set_node(0, (phys_addr_t)ULLONG_MAX, &memblock.memory, 0);
 
+#ifndef CONFIG_NO_BOOTMEM
 	/* Add all physical memory to the bootmem map, mark each area
 	 * present.
 	 */
@@ -234,11 +239,14 @@ void __init do_init_bootmem(void)
 			reserve_bootmem(reg->base, trunc_size, BOOTMEM_DEFAULT);
 		}
 	}
+#endif
 
 	/* XXX need to clip this if using highmem? */
 	sparse_memory_present_with_active_regions(0);
 
+#ifndef CONFIG_NO_BOOTMEM
 	init_bootmem_done = 1;
+#endif
 }
 
 /* mark pages that don't exist as nosave */
-- 
1.9.1

^ permalink raw reply related

* [PATCH 1/2] bootmem/powerpc: Unify bootmem initialization
From: Emil Medve @ 2014-04-01  7:21 UTC (permalink / raw)
  To: benh, paulus, linuxppc-dev; +Cc: Emil Medve

Unify the low/highmem code path from do_init_bootmem() by using (the)
lowmem related variables/parameters even when the low/highmem split
is not needed (64-bit) or configured. In such cases the "lowmem"
variables/parameters continue to observe the definition by referring
to memory directly mapped by the kernel

Signed-off-by: Emil Medve <Emilian.Medve@Freescale.com>
---
 arch/powerpc/mm/mem.c | 36 ++++++++++++++++--------------------
 1 file changed, 16 insertions(+), 20 deletions(-)

diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 32202c9..eaf5d1d8 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -188,27 +188,31 @@ EXPORT_SYMBOL_GPL(walk_system_ram_range);
 void __init do_init_bootmem(void)
 {
 	unsigned long start, bootmap_pages;
-	unsigned long total_pages;
 	struct memblock_region *reg;
 	int boot_mapsize;
+	phys_addr_t _total_lowmem;
+	phys_addr_t _lowmem_end_addr;
 
-	max_low_pfn = max_pfn = memblock_end_of_DRAM() >> PAGE_SHIFT;
-	total_pages = (memblock_end_of_DRAM() - memstart_addr) >> PAGE_SHIFT;
-#ifdef CONFIG_HIGHMEM
-	total_pages = total_lowmem >> PAGE_SHIFT;
-	max_low_pfn = lowmem_end_addr >> PAGE_SHIFT;
+#ifndef CONFIG_HIGHMEM
+	_lowmem_end_addr = memblock_end_of_DRAM();
+#else
+	_lowmem_end_addr = lowmem_end_addr;
 #endif
 
+	max_pfn = memblock_end_of_DRAM() >> PAGE_SHIFT;
+	max_low_pfn = _lowmem_end_addr >> PAGE_SHIFT;
+	min_low_pfn = MEMORY_START >> PAGE_SHIFT;
+
 	/*
 	 * Find an area to use for the bootmem bitmap.  Calculate the size of
 	 * bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE.
 	 * Add 1 additional page in case the address isn't page-aligned.
 	 */
-	bootmap_pages = bootmem_bootmap_pages(total_pages);
+	_total_lowmem = _lowmem_end_addr - memstart_addr;
+	bootmap_pages = bootmem_bootmap_pages(_total_lowmem >> PAGE_SHIFT);
 
 	start = memblock_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE);
 
-	min_low_pfn = MEMORY_START >> PAGE_SHIFT;
 	boot_mapsize = init_bootmem_node(NODE_DATA(0), start >> PAGE_SHIFT, min_low_pfn, max_low_pfn);
 
 	/* Place all memblock_regions in the same node and merge contiguous
@@ -219,26 +223,18 @@ void __init do_init_bootmem(void)
 	/* Add all physical memory to the bootmem map, mark each area
 	 * present.
 	 */
-#ifdef CONFIG_HIGHMEM
-	free_bootmem_with_active_regions(0, lowmem_end_addr >> PAGE_SHIFT);
+	free_bootmem_with_active_regions(0, max_low_pfn);
 
 	/* reserve the sections we're already using */
 	for_each_memblock(reserved, reg) {
-		unsigned long top = reg->base + reg->size - 1;
-		if (top < lowmem_end_addr)
+		if (reg->base + reg->size - 1 < _lowmem_end_addr)
 			reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
-		else if (reg->base < lowmem_end_addr) {
-			unsigned long trunc_size = lowmem_end_addr - reg->base;
+		else if (reg->base < _lowmem_end_addr) {
+			unsigned long trunc_size = _lowmem_end_addr - reg->base;
 			reserve_bootmem(reg->base, trunc_size, BOOTMEM_DEFAULT);
 		}
 	}
-#else
-	free_bootmem_with_active_regions(0, max_pfn);
 
-	/* reserve the sections we're already using */
-	for_each_memblock(reserved, reg)
-		reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
-#endif
 	/* XXX need to clip this if using highmem? */
 	sparse_memory_present_with_active_regions(0);
 
-- 
1.9.1

^ permalink raw reply related

* [PATCH] spi: add "spi-lsb-first" to devicetree
From: Zhao Qiang @ 2014-04-01  7:55 UTC (permalink / raw)
  To: linuxppc-dev, broonie, devicetree, linux-spi, B07421
  Cc: Zhao Qiang, baruch, R63061, wangyuhang2014

add optional property devicetree for SPI slave nodes
into devicetree so that LSB mode can be enabled by devicetree.

Signed-off-by: Zhao Qiang <B45475@freescale.com>
---
 Documentation/devicetree/bindings/spi/spi-bus.txt | 4 ++++
 drivers/spi/spi.c                                 | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/spi/spi-bus.txt b/Documentation/devicetree/bindings/spi/spi-bus.txt
index e5a4d1b..fdd9f15 100644
--- a/Documentation/devicetree/bindings/spi/spi-bus.txt
+++ b/Documentation/devicetree/bindings/spi/spi-bus.txt
@@ -55,11 +55,15 @@ contain the following properties.
     		chip select active high
 - spi-3wire       - (optional) Empty property indicating device requires
     		    3-wire mode.
+- spi-lsb-first   - (optional) Empty property indicating device requires
+		LSB first mode.
 - spi-tx-bus-width - (optional) The bus width(number of data wires) that
                       used for MOSI. Defaults to 1 if not present.
 - spi-rx-bus-width - (optional) The bus width(number of data wires) that
                       used for MISO. Defaults to 1 if not present.
 
+- spi-rx-bus-width - (optional) The bus width(number of data wires) that
+                      used for MISO. Defaults to 1 if not present.
 Some SPI controllers and devices support Dual and Quad SPI transfer mode.
 It allows data in SPI system transfered in 2 wires(DUAL) or 4 wires(QUAD).
 Now the value that spi-tx-bus-width and spi-rx-bus-width can receive is
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 23756b0..0a20a90 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1050,6 +1050,8 @@ static void of_register_spi_devices(struct spi_master *master)
 			spi->mode |= SPI_CS_HIGH;
 		if (of_find_property(nc, "spi-3wire", NULL))
 			spi->mode |= SPI_3WIRE;
+		if (of_find_property(nc, "spi-lsb-first", NULL))
+			spi->mode |= SPI_LSB_FIRST;
 
 		/* Device DUAL/QUAD mode */
 		if (!of_property_read_u32(nc, "spi-tx-bus-width", &value)) {
-- 
1.8.5

^ permalink raw reply related

* Re: Build regressions/improvements in v3.14
From: Geert Uytterhoeven @ 2014-04-01  8:01 UTC (permalink / raw)
  To: linux-kernel@vger.kernel.org
  Cc: the arch/x86 maintainers, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1396339078-22125-1-git-send-email-geert@linux-m68k.org>

On Tue, Apr 1, 2014 at 9:57 AM, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> JFYI, when comparing v3.14[1]  to v3.14-rc8[3], the summaries are:
>   - build errors: +2/-10

  + error: No rule to make target include/config/auto.conf:  => N/A

powerpc-randconfig

  + error: initramfs.c: undefined reference to `__stack_chk_guard':
=> .init.text+0x1067)

x86_64-randconfig

> [1] http://kisskb.ellerman.id.au/kisskb/head/7320/ (all 119 configs)
> [3] http://kisskb.ellerman.id.au/kisskb/head/7303/ (all 119 configs)

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torval

^ permalink raw reply

* [PATCH] cpuidle: add freescale e500 family porcessors idle support
From: Dongsheng Wang @ 2014-04-01  8:33 UTC (permalink / raw)
  To: daniel.lezcano, scottwood
  Cc: chenhui.zhao, linux-pm, Wang Dongsheng, rjw, jason.jin,
	linuxppc-dev

From: Wang Dongsheng <dongsheng.wang@freescale.com>

Add cpuidle support for e500 family, using cpuidle framework to
manage various low power modes. The new implementation will remain
compatible with original idle method.

I have done test about power consumption and latency. Cpuidle framework
will make CPU response time faster than original method, but power
consumption is higher than original method.

Power consumption:
The original method, power consumption is 10.51202 (W).
The cpuidle framework, power consumption is 10.5311 (W).

Latency:
The original method, avg latency is 6782 (us).
The cpuidle framework, avg latency is 6482 (us).

Initially, this supports PW10, PW20 and subsequent patches will support
DOZE/NAP and PH10, PH20.

Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>

diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index 5b6c03f..9301420 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -294,6 +294,15 @@ extern void power7_idle(void);
 extern void ppc6xx_idle(void);
 extern void book3e_idle(void);
 
+static inline void cpuidle_wait(void)
+{
+#ifdef CONFIG_PPC64
+	book3e_idle();
+#else
+	e500_idle();
+#endif
+}
+
 /*
  * ppc_md contains a copy of the machine description structure for the
  * current platform. machine_id contains the initial address where the
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 97e1dc9..edd193f 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -190,6 +190,9 @@ static ssize_t show_pw20_wait_time(struct device *dev,
 	return sprintf(buf, "%llu\n", time > 0 ? time : 0);
 }
 
+#ifdef CONFIG_CPU_IDLE_E500
+u32 cpuidle_entry_bit;
+#endif
 static void set_pw20_wait_entry_bit(void *val)
 {
 	u32 *value = val;
@@ -204,7 +207,11 @@ static void set_pw20_wait_entry_bit(void *val)
 	/* set count */
 	pw20_idle |= ((MAX_BIT - *value) << PWRMGTCR0_PW20_ENT_SHIFT);
 
+#ifdef CONFIG_CPU_IDLE_E500
+	cpuidle_entry_bit = *value;
+#else
 	mtspr(SPRN_PWRMGTCR0, pw20_idle);
+#endif
 }
 
 static ssize_t store_pw20_wait_time(struct device *dev,
diff --git a/drivers/cpuidle/Kconfig.powerpc b/drivers/cpuidle/Kconfig.powerpc
index 66c3a09..0949dbf 100644
--- a/drivers/cpuidle/Kconfig.powerpc
+++ b/drivers/cpuidle/Kconfig.powerpc
@@ -18,3 +18,10 @@ config POWERNV_CPUIDLE
 	help
 	  Select this option to enable processor idle state management
 	  through cpuidle subsystem.
+
+config CPU_IDLE_E500
+	bool "CPU Idle Driver for E500 family processors"
+	depends on CPU_IDLE
+	depends on FSL_SOC_BOOKE
+	help
+	  Select this to enable cpuidle on e500 family processors.
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index f71ae1b..7e6adea 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -18,3 +18,4 @@ obj-$(CONFIG_ARM_AT91_CPUIDLE)          += cpuidle-at91.o
 # POWERPC drivers
 obj-$(CONFIG_PSERIES_CPUIDLE)		+= cpuidle-pseries.o
 obj-$(CONFIG_POWERNV_CPUIDLE)		+= cpuidle-powernv.o
+obj-$(CONFIG_CPU_IDLE_E500)		+= cpuidle-e500.o
diff --git a/drivers/cpuidle/cpuidle-e500.c b/drivers/cpuidle/cpuidle-e500.c
new file mode 100644
index 0000000..ddc0def
--- /dev/null
+++ b/drivers/cpuidle/cpuidle-e500.c
@@ -0,0 +1,194 @@
+/*
+ * CPU Idle driver for Freescale PowerPC e500 family processors.
+ *
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ *
+ * Author: Dongsheng Wang <dongsheng.wang@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/cpu.h>
+#include <linux/cpuidle.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/notifier.h>
+
+#include <asm/cputable.h>
+#include <asm/machdep.h>
+#include <asm/mpc85xx.h>
+
+static unsigned int max_idle_state;
+static struct cpuidle_state *cpuidle_state_table;
+
+struct cpuidle_driver e500_idle_driver = {
+	.name = "e500_idle",
+	.owner = THIS_MODULE,
+};
+
+static void e500_cpuidle(void)
+{
+	if (cpuidle_idle_call())
+		cpuidle_wait();
+}
+
+static int pw10_enter(struct cpuidle_device *dev,
+			struct cpuidle_driver *drv, int index)
+{
+	cpuidle_wait();
+	return index;
+}
+
+#define MAX_BIT	63
+#define MIN_BIT	1
+extern u32 cpuidle_entry_bit;
+static int pw20_enter(struct cpuidle_device *dev,
+		struct cpuidle_driver *drv, int index)
+{
+	u32 pw20_idle;
+	u32 entry_bit;
+	pw20_idle = mfspr(SPRN_PWRMGTCR0);
+	if ((pw20_idle & PWRMGTCR0_PW20_ENT) != PWRMGTCR0_PW20_ENT) {
+		pw20_idle &= ~PWRMGTCR0_PW20_ENT;
+		entry_bit = MAX_BIT - cpuidle_entry_bit;
+		pw20_idle |= (entry_bit << PWRMGTCR0_PW20_ENT_SHIFT);
+		mtspr(SPRN_PWRMGTCR0, pw20_idle);
+	}
+
+	cpuidle_wait();
+
+	pw20_idle &= ~PWRMGTCR0_PW20_ENT;
+	pw20_idle |= (MIN_BIT << PWRMGTCR0_PW20_ENT_SHIFT);
+	mtspr(SPRN_PWRMGTCR0, pw20_idle);
+
+	return index;
+}
+
+static struct cpuidle_state pw_idle_states[] = {
+	{
+		.name = "pw10",
+		.desc = "pw10",
+		.flags = CPUIDLE_FLAG_TIME_VALID,
+		.exit_latency = 0,
+		.target_residency = 0,
+		.enter = &pw10_enter
+	},
+
+	{
+		.name = "pw20",
+		.desc = "pw20-core-idle",
+		.flags = CPUIDLE_FLAG_TIME_VALID,
+		.exit_latency = 1,
+		.target_residency = 50,
+		.enter = &pw20_enter
+	},
+};
+
+static int cpu_hotplug_notify(struct notifier_block *n,
+			unsigned long action, void *hcpu)
+{
+	unsigned long hotcpu = (unsigned long)hcpu;
+	struct cpuidle_device *dev =
+			per_cpu_ptr(cpuidle_devices, hotcpu);
+
+	if (dev && cpuidle_get_driver()) {
+		switch (action) {
+		case CPU_ONLINE:
+		case CPU_ONLINE_FROZEN:
+			cpuidle_pause_and_lock();
+			cpuidle_enable_device(dev);
+			cpuidle_resume_and_unlock();
+			break;
+
+		case CPU_DEAD:
+		case CPU_DEAD_FROZEN:
+			cpuidle_pause_and_lock();
+			cpuidle_disable_device(dev);
+			cpuidle_resume_and_unlock();
+			break;
+
+		default:
+			return NOTIFY_DONE;
+		}
+	}
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block cpu_hotplug_notifier = {
+	.notifier_call = cpu_hotplug_notify,
+};
+
+static void e500_cpuidle_driver_init(void)
+{
+	int idle_state;
+	struct cpuidle_driver *drv = &e500_idle_driver;
+
+	drv->state_count = 0;
+
+	for (idle_state = 0; idle_state < max_idle_state; ++idle_state) {
+		if (!cpuidle_state_table[idle_state].enter)
+			break;
+
+		drv->states[drv->state_count] = cpuidle_state_table[idle_state];
+		drv->state_count++;
+	}
+}
+
+static int e500_idle_state_probe(void)
+{
+	if (cpuidle_disable != IDLE_NO_OVERRIDE)
+		return -ENODEV;
+
+	cpuidle_state_table = pw_idle_states;
+	max_idle_state = ARRAY_SIZE(pw_idle_states);
+
+	/* Disable PW20 feature for e500mc, e5500 */
+	if (PVR_VER(cur_cpu_spec->pvr_value) != PVR_VER_E6500)
+		cpuidle_state_table[1].enter = NULL;
+
+	if (!cpuidle_state_table || !max_idle_state)
+		return -ENODEV;
+
+	return 0;
+}
+
+static void replace_orig_idle(void *dummy)
+{
+	return;
+}
+
+static int __init e500_idle_init(void)
+{
+	struct cpuidle_driver *drv = &e500_idle_driver;
+	int err;
+
+	if (e500_idle_state_probe())
+		return -ENODEV;
+
+	e500_cpuidle_driver_init();
+	if (!drv->state_count)
+		return -ENODEV;
+
+	err = cpuidle_register(drv, NULL);
+	if (err) {
+		pr_err("Register e500 family cpuidle driver failed.\n");
+
+		return err;
+	}
+
+	err = register_cpu_notifier(&cpu_hotplug_notifier);
+	if (err)
+		pr_warn("Cpuidle driver: register cpu notifier failed.\n");
+
+	/* Replace the original way of idle after cpuidle registered. */
+	ppc_md.power_save = e500_cpuidle;
+	on_each_cpu(replace_orig_idle, NULL, 1);
+
+	pr_info("e500_idle_driver registered.\n");
+
+	return 0;
+}
+late_initcall(e500_idle_init);
-- 
1.8.5

^ permalink raw reply related

* Re: [PATCH] spi: add "spi-lsb-first" to devicetree
From: Baruch Siach @ 2014-04-01  8:42 UTC (permalink / raw)
  To: Zhao Qiang
  Cc: B07421, devicetree, linux-spi, broonie, R63061, linuxppc-dev,
	wangyuhang2014
In-Reply-To: <1396338931-10887-1-git-send-email-B45475@freescale.com>

Hi Zhao Qiang,

On Tue, Apr 01, 2014 at 03:55:31PM +0800, Zhao Qiang wrote:
> add optional property devicetree for SPI slave nodes
> into devicetree so that LSB mode can be enabled by devicetree.
> 
> Signed-off-by: Zhao Qiang <B45475@freescale.com>
> ---
>  Documentation/devicetree/bindings/spi/spi-bus.txt | 4 ++++
>  drivers/spi/spi.c                                 | 2 ++
>  2 files changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/spi/spi-bus.txt b/Documentation/devicetree/bindings/spi/spi-bus.txt
> index e5a4d1b..fdd9f15 100644
> --- a/Documentation/devicetree/bindings/spi/spi-bus.txt
> +++ b/Documentation/devicetree/bindings/spi/spi-bus.txt
> @@ -55,11 +55,15 @@ contain the following properties.
>      		chip select active high
>  - spi-3wire       - (optional) Empty property indicating device requires
>      		    3-wire mode.
> +- spi-lsb-first   - (optional) Empty property indicating device requires
> +		LSB first mode.
>  - spi-tx-bus-width - (optional) The bus width(number of data wires) that
>                        used for MOSI. Defaults to 1 if not present.
>  - spi-rx-bus-width - (optional) The bus width(number of data wires) that
>                        used for MISO. Defaults to 1 if not present.
>  
> +- spi-rx-bus-width - (optional) The bus width(number of data wires) that
> +                      used for MISO. Defaults to 1 if not present.

Is this part intentionally here? It is not mentioned in the commit log, and 
seems to merit a separate patch.

baruch

>  Some SPI controllers and devices support Dual and Quad SPI transfer mode.
>  It allows data in SPI system transfered in 2 wires(DUAL) or 4 wires(QUAD).
>  Now the value that spi-tx-bus-width and spi-rx-bus-width can receive is
> diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
> index 23756b0..0a20a90 100644
> --- a/drivers/spi/spi.c
> +++ b/drivers/spi/spi.c
> @@ -1050,6 +1050,8 @@ static void of_register_spi_devices(struct spi_master *master)
>  			spi->mode |= SPI_CS_HIGH;
>  		if (of_find_property(nc, "spi-3wire", NULL))
>  			spi->mode |= SPI_3WIRE;
> +		if (of_find_property(nc, "spi-lsb-first", NULL))
> +			spi->mode |= SPI_LSB_FIRST;
>  
>  		/* Device DUAL/QUAD mode */
>  		if (!of_property_read_u32(nc, "spi-tx-bus-width", &value)) {

-- 
     http://baruch.siach.name/blog/                  ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch@tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -

^ permalink raw reply

* [PATCH v2] spi: add "spi-lsb-first" to devicetree
From: Zhao Qiang @ 2014-04-01  9:10 UTC (permalink / raw)
  To: linuxppc-dev, broonie, devicetree, linux-spi, B07421
  Cc: Zhao Qiang, baruch, R63061, wangyuhang2014

add optional property devicetree for SPI slave nodes
into devicetree so that LSB mode can be enabled by devicetree.

Signed-off-by: Zhao Qiang <B45475@freescale.com>
---
changs for v2:
	- remove duplicate "spi-rx-bus-width" 
 Documentation/devicetree/bindings/spi/spi-bus.txt | 2 ++
 drivers/spi/spi.c                                 | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/spi/spi-bus.txt b/Documentation/devicetree/bindings/spi/spi-bus.txt
index e5a4d1b..22d5740 100644
--- a/Documentation/devicetree/bindings/spi/spi-bus.txt
+++ b/Documentation/devicetree/bindings/spi/spi-bus.txt
@@ -55,6 +55,8 @@ contain the following properties.
     		chip select active high
 - spi-3wire       - (optional) Empty property indicating device requires
     		    3-wire mode.
+- spi-lsb-first   - (optional) Empty property indicating device requires
+		LSB first mode.
 - spi-tx-bus-width - (optional) The bus width(number of data wires) that
                       used for MOSI. Defaults to 1 if not present.
 - spi-rx-bus-width - (optional) The bus width(number of data wires) that
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 23756b0..0a20a90 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1050,6 +1050,8 @@ static void of_register_spi_devices(struct spi_master *master)
 			spi->mode |= SPI_CS_HIGH;
 		if (of_find_property(nc, "spi-3wire", NULL))
 			spi->mode |= SPI_3WIRE;
+		if (of_find_property(nc, "spi-lsb-first", NULL))
+			spi->mode |= SPI_LSB_FIRST;
 
 		/* Device DUAL/QUAD mode */
 		if (!of_property_read_u32(nc, "spi-tx-bus-width", &value)) {
-- 
1.8.5

^ permalink raw reply related

* Re: [PATCH REPOST v5 1/3] powernv, cpufreq: Select CPUFreq related Kconfig options for powernv
From: Benjamin Herrenschmidt @ 2014-04-01  9:46 UTC (permalink / raw)
  To: Gautham R. Shenoy
  Cc: Linux PM list, Viresh Kumar, rjw, linux-kernel, cpufreq,
	linuxppc-dev, Anton Blanchard, srivatsa.bhat
In-Reply-To: <1396336408-20954-3-git-send-email-ego@linux.vnet.ibm.com>

On Tue, 2014-04-01 at 12:43 +0530, Gautham R. Shenoy 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.

Rafael, are you going to take these or should I send them to Linus ?

(I'd rather you take them :-)

Cheers,
Ben.

> 
> 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(+)
> 
> diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
> index 9ea8342b..a905063 100644
> --- a/arch/powerpc/configs/pseries_defconfig
> +++ b/arch/powerpc/configs/pseries_defconfig
> @@ -306,3 +306,4 @@ CONFIG_KVM_BOOK3S_64=m
>  CONFIG_KVM_BOOK3S_64_HV=y
>  CONFIG_TRANSPARENT_HUGEPAGE=y
>  CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
> +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
> diff --git a/arch/powerpc/configs/pseries_le_defconfig b/arch/powerpc/configs/pseries_le_defconfig
> index 3c84f9d..58e3dbf 100644
> --- a/arch/powerpc/configs/pseries_le_defconfig
> +++ b/arch/powerpc/configs/pseries_le_defconfig
> @@ -301,3 +301,4 @@ CONFIG_CRYPTO_LZO=m
>  # CONFIG_CRYPTO_ANSI_CPRNG is not set
>  CONFIG_CRYPTO_DEV_NX=y
>  CONFIG_CRYPTO_DEV_NX_ENCRYPT=m
> +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
> diff --git a/arch/powerpc/platforms/powernv/Kconfig b/arch/powerpc/platforms/powernv/Kconfig
> index 895e8a2..c252ee9 100644
> --- a/arch/powerpc/platforms/powernv/Kconfig
> +++ b/arch/powerpc/platforms/powernv/Kconfig
> @@ -11,6 +11,12 @@ config PPC_POWERNV
>  	select PPC_UDBG_16550
>  	select PPC_SCOM
>  	select ARCH_RANDOM
> +	select CPU_FREQ
> +	select CPU_FREQ_GOV_PERFORMANCE
> +	select CPU_FREQ_GOV_POWERSAVE
> +	select CPU_FREQ_GOV_USERSPACE
> +	select CPU_FREQ_GOV_ONDEMAND
> +	select CPU_FREQ_GOV_CONSERVATIVE
>  	default y
>  
>  config PPC_POWERNV_RTAS

^ permalink raw reply

* Re: [RFC PATCH] powerpc/le: enable RTAS events support
From: Geert Uytterhoeven @ 2014-04-01 10:26 UTC (permalink / raw)
  To: Nathan Fontenot
  Cc: linux-kernel@vger.kernel.org, Paul Mackerras, Anton Blanchard,
	linuxppc-dev@lists.ozlabs.org, Greg Kurz
In-Reply-To: <53398379.8000203@linux.vnet.ibm.com>

On Mon, Mar 31, 2014 at 5:02 PM, Nathan Fontenot
<nfont@linux.vnet.ibm.com> wrote:
>  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 */

Now the bitfields are gone, things like the above can become __be32,
so we get extra type checking from sparse ("make C=1").

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* Re: [PATCH bisect 0/2] ASoC: fsl_sai: Overwrite trigger()
From: Mark Brown @ 2014-04-01 11:04 UTC (permalink / raw)
  To: Nicolin Chen; +Cc: alsa-devel, Li.Xiubo, linuxppc-dev, linux-kernel, timur
In-Reply-To: <1396322227-482-1-git-send-email-Guangyu.Chen@freescale.com>

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

On Tue, Apr 01, 2014 at 11:17:05AM +0800, Nicolin Chen wrote:

> * The patches are generated by using '-U2' because the default '-U3'
>   would conflict the baseline without fsl_sai_isr patches.

What are these "fsi_sai_isr patches"?

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

^ permalink raw reply

* Re: [PATCH bisect 0/2] ASoC: fsl_sai: Overwrite trigger()
From: Nicolin Chen @ 2014-04-01 10:54 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel, Li.Xiubo, linuxppc-dev, linux-kernel, timur
In-Reply-To: <20140401110412.GJ2269@sirena.org.uk>

On Tue, Apr 01, 2014 at 12:04:12PM +0100, Mark Brown wrote:
> On Tue, Apr 01, 2014 at 11:17:05AM +0800, Nicolin Chen wrote:
> 
> > * The patches are generated by using '-U2' because the default '-U3'
> >   would conflict the baseline without fsl_sai_isr patches.
> 
> What are these "fsi_sai_isr patches"?

Ah..I should have mentioned the full patch name:
e2681a1 ASoC: fsl_sai: Add isr to deal with error flag

The patch conflicts against that asoc-3.15-4 tag at the fsl_sai.h because
this isr patch added some new macros to it.

Thank you,
Nicolin Chen

^ permalink raw reply

* [RFC] powerpc, ptrace: Add few more ptrace request macros
From: Anshuman Khandual @ 2014-04-01 11:14 UTC (permalink / raw)
  To: linuxppc-dev, linux-kernel; +Cc: mikey, Anshuman Khandual

This patch adds few more ptrace request macros expanding
the existing capability. These ptrace requests macros can
be classified into two categories.

(1) Transactional memory

	/* TM special purpose registers */
	PTRACE_GETTM_SPRREGS
	PTRACE_SETTM_SPRREGS

	/* Checkpointed GPR registers */
	PTRACE_GETTM_CGPRREGS
	PTRACE_SETTM_CGPRREGS

	/* Checkpointed FPR registers */
	PTRACE_GETTM_CFPRREGS
	PTRACE_SETTM_CFPRREGS

	/* Checkpointed VMX registers */
	PTRACE_GETTM_CVMXREGS
	PTRACE_SETTM_CVMXREGS

(2) Miscellaneous

	/* TAR, PPR, DSCR registers */
	PTRACE_GETMSCREGS
	PTRACE_SETMSCREGS

This patch also adds mutliple new generic ELF core note sections in
this regard which can be listed as follows.

	NT_PPC_TM_SPR	/* Transactional memory specific registers */
	NT_PPC_TM_CGPR	/* Transactional memory checkpointed GPR */
	NT_PPC_TM_CFPR	/* Transactional memory checkpointed FPR */
	NT_PPC_TM_CVMX	/* Transactional memory checkpointed VMX */
	NT_PPC_MISC	/* Miscellaneous registers */

Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/switch_to.h   |   8 +
 arch/powerpc/include/uapi/asm/ptrace.h |  61 +++
 arch/powerpc/kernel/process.c          |  24 ++
 arch/powerpc/kernel/ptrace.c           | 658 +++++++++++++++++++++++++++++++--
 include/uapi/linux/elf.h               |   5 +
 5 files changed, 729 insertions(+), 27 deletions(-)

diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h
index 0e83e7d..73e2601 100644
--- a/arch/powerpc/include/asm/switch_to.h
+++ b/arch/powerpc/include/asm/switch_to.h
@@ -80,6 +80,14 @@ static inline void flush_spe_to_thread(struct task_struct *t)
 }
 #endif
 
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+extern void flush_tmreg_to_thread(struct task_struct *);
+#else
+static inline void flush_tmreg_to_thread(struct task_struct *t)
+{
+}
+#endif
+
 static inline void clear_task_ebb(struct task_struct *t)
 {
 #ifdef CONFIG_PPC_BOOK3S_64
diff --git a/arch/powerpc/include/uapi/asm/ptrace.h b/arch/powerpc/include/uapi/asm/ptrace.h
index 77d2ed3..fd962d6 100644
--- a/arch/powerpc/include/uapi/asm/ptrace.h
+++ b/arch/powerpc/include/uapi/asm/ptrace.h
@@ -190,6 +190,67 @@ struct pt_regs {
 #define PPC_PTRACE_SETHWDEBUG	0x88
 #define PPC_PTRACE_DELHWDEBUG	0x87
 
+/* Transactional memory registers */
+
+/*
+ * SPR
+ *
+ * struct data {
+ * 	u64		tm_tfhar;
+ *	u64		tm_texasr;
+ *	u64		tm_tfiar;
+ *	unsigned long   tm_orig_msr;
+ *	u64		tm_tar;
+ *	u64		tm_ppr;
+ *	u64		tm_dscr;
+ * };
+ */
+#define PTRACE_GETTM_SPRREGS	0x70
+#define PTRACE_SETTM_SPRREGS	0x71
+
+/* 
+ * Checkpointed GPR
+ *
+ * struct data {
+ *	struct pt_regs	ckpt_regs;
+ * };
+ */
+#define PTRACE_GETTM_CGPRREGS	0x72
+#define PTRACE_SETTM_CGPRREGS	0x73
+
+/*
+ * Checkpointed FPR
+ *
+ * struct data {
+ * 	u64	fpr[32];
+ * 	u64	fpscr;
+ * };
+ */
+#define PTRACE_GETTM_CFPRREGS	0x74
+#define PTRACE_SETTM_CFPRREGS	0x75
+
+/* 
+ * Checkpointed VMX
+ *
+ * struct data {
+ *	vector128	vr[32];
+ *	vector128	vscr;
+ *	unsigned long	vrsave; 
+ *};
+ */
+#define PTRACE_GETTM_CVMXREGS	0x76
+#define PTRACE_SETTM_CVMXREGS	0x77
+
+/* Miscellaneous registers */
+#define PTRACE_GETMSCREGS	0x78
+#define PTRACE_SETMSCREGS	0x79
+
+/*
+ * XXX: A note to application developers. The existing data layout
+ * of the above four ptrace requests can change when new registers
+ * are available for each category in forthcoming processors.
+ */
+
 #ifndef __ASSEMBLY__
 
 struct ppc_debug_info {
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index af064d2..e5dfd8e 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -673,6 +673,30 @@ static inline void __switch_to_tm(struct task_struct *prev)
 	}
 }
 
+void flush_tmreg_to_thread(struct task_struct *tsk)
+{
+	/*
+ 	 * If task is not current, it should have been flushed
+ 	 * already to it's thread_struct during __switch_to().
+ 	 */
+	if (tsk != current)
+		return;
+
+	preempt_disable();
+	if (tsk->thread.regs) {
+		/* 
+ 		 * If we are still current, the TM state need to
+ 		 * be flushed to thread_struct as it will be still
+ 		 * present in the current cpu
+ 		 */
+		if (MSR_TM_ACTIVE(tsk->thread.regs->msr)) {
+			__switch_to_tm(tsk);
+			tm_recheckpoint_new_task(tsk);
+		}
+	}
+	preempt_enable();
+}
+
 /*
  * This is called if we are on the way out to userspace and the
  * TIF_RESTORE_TM flag is set.  It checks if we need to reload
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 2e3d2bf..cb4d5bf 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -357,6 +357,17 @@ static int gpr_set(struct task_struct *target, const struct user_regset *regset,
 	return ret;
 }
 
+/*
+ * When any transaction is active, thread_struct->transact_fp holds
+ * the current running value of all FPR registers and thread_struct->
+ * fp_state hold the last checkpointed FPR state for the given
+ * transaction.
+ *
+ * struct data {
+ * 	u64	fpr[32];
+ * 	u64	fpscr;	
+ * };
+ */
 static int fpr_get(struct task_struct *target, const struct user_regset *regset,
 		   unsigned int pos, unsigned int count,
 		   void *kbuf, void __user *ubuf)
@@ -365,21 +376,41 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset,
 	u64 buf[33];
 	int i;
 #endif
-	flush_fp_to_thread(target);
+	if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
+		flush_fp_to_thread(target);
+		flush_altivec_to_thread(target);
+		flush_tmreg_to_thread(target);
+	} else {
+		flush_fp_to_thread(target);
+	}
 
 #ifdef CONFIG_VSX
 	/* copy to local buffer then write that out */
-	for (i = 0; i < 32 ; i++)
-		buf[i] = target->thread.TS_FPR(i);
-	buf[32] = target->thread.fp_state.fpscr;
+	if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
+		for (i = 0; i < 32 ; i++)
+			buf[i] = target->thread.TS_TRANS_FPR(i);
+		buf[32] = target->thread.transact_fp.fpscr;
+	} else {
+		for (i = 0; i < 32 ; i++)
+			buf[i] = target->thread.TS_FPR(i);
+		buf[32] = target->thread.fp_state.fpscr;
+	}
 	return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
 
 #else
-	BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
-		     offsetof(struct thread_fp_state, fpr[32][0]));
+	if (MSR_TM_ACTIVE(tsk->thread.regs->msr)) {
+		BUILD_BUG_ON(offsetof(struct transact_fp, fpscr) !=
+				offsetof(struct transact_fp, fpr[32][0]));
 
-	return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+		return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+				   &target->thread.transact_fp, 0, -1);
+	} esle {
+		BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
+			     offsetof(struct thread_fp_state, fpr[32][0]));
+
+		return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
 				   &target->thread.fp_state, 0, -1);
+	}
 #endif
 }
 
@@ -391,23 +422,44 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset,
 	u64 buf[33];
 	int i;
 #endif
-	flush_fp_to_thread(target);
+	if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
+		flush_fp_to_thread(target);
+		flush_altivec_to_thread(target);
+		flush_tmreg_to_thread(target);
+	} else {
+		flush_fp_to_thread(target);
+	}
 
 #ifdef CONFIG_VSX
 	/* copy to local buffer then write that out */
 	i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
 	if (i)
 		return i;
-	for (i = 0; i < 32 ; i++)
-		target->thread.TS_FPR(i) = buf[i];
-	target->thread.fp_state.fpscr = buf[32];
+	for (i = 0; i < 32 ; i++) {
+		if (MSR_TM_ACTIVE(target->thread.regs->msr))
+			target->thread.TS_TRANS_FPR(i) = buf[i];
+		else
+			target->thread.TS_FPR(i) = buf[i];
+	}
+	if (MSR_TM_ACTIVE(target->thread.regs->msr))
+		target->thread.transact_fp.fpscr = buf[32];
+	else
+		target->thread.fp_state.fpscr = buf[32];
 	return 0;
 #else
-	BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
-		     offsetof(struct thread_fp_state, fpr[32][0]));
+	if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
+		BUILD_BUG_ON(offsetof(struct transact_fp, fpscr) !=
+			     offsetof(struct transact_fp, fpr[32][0]));
 
-	return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
-				  &target->thread.fp_state, 0, -1);
+		return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+					  &target->thread.transact_fp, 0, -1);
+	} else {
+		BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
+			     offsetof(struct thread_fp_state, fpr[32][0]));
+
+		return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				&target->thread.fp_state, 0, -1);
+	}
 #endif
 }
 
@@ -432,20 +484,44 @@ static int vr_active(struct task_struct *target,
 	return target->thread.used_vr ? regset->n : 0;
 }
 
+/*
+ * When any transaction is active, thread_struct->transact_vr holds
+ * the current running value of all VMX registers and thread_struct->
+ * vr_state hold the last checkpointed VMX state for the given
+ * transaction.
+ *
+ * struct data {
+ * 	vector128	vr[32];
+ * 	vector128	vscr;
+ * 	vector128	vrsave;
+ * };
+ */
 static int vr_get(struct task_struct *target, const struct user_regset *regset,
 		  unsigned int pos, unsigned int count,
 		  void *kbuf, void __user *ubuf)
 {
 	int ret;
+	struct thread_vr_state *addr;
 
-	flush_altivec_to_thread(target);
+	if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
+		flush_fp_to_thread(target);
+		flush_altivec_to_thread(target);
+		flush_tmreg_to_thread(target);
+	} else {
+		flush_altivec_to_thread(target);
+	}
 
 	BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
 		     offsetof(struct thread_vr_state, vr[32]));
 
+	if (MSR_TM_ACTIVE(target->thread.regs->msr))
+		addr = &target->thread.transact_vr;
+	else
+		addr = &target->thread.vr_state;
+
 	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-				  &target->thread.vr_state, 0,
-				  33 * sizeof(vector128));
+				addr, 0, 33 * sizeof(vector128));
+
 	if (!ret) {
 		/*
 		 * Copy out only the low-order word of vrsave.
@@ -455,11 +531,14 @@ static int vr_get(struct task_struct *target, const struct user_regset *regset,
 			u32 word;
 		} vrsave;
 		memset(&vrsave, 0, sizeof(vrsave));
-		vrsave.word = target->thread.vrsave;
+		if (MSR_TM_ACTIVE(target->thread.regs->msr))
+			vrsave.word = target->thread.transact_vrsave;
+		else
+			vrsave.word = target->thread.vrsave;
+
 		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave,
 					  33 * sizeof(vector128), -1);
 	}
-
 	return ret;
 }
 
@@ -467,16 +546,27 @@ static int vr_set(struct task_struct *target, const struct user_regset *regset,
 		  unsigned int pos, unsigned int count,
 		  const void *kbuf, const void __user *ubuf)
 {
+	struct thread_vr_state *addr;
 	int ret;
 
-	flush_altivec_to_thread(target);
+	if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
+		flush_fp_to_thread(target);
+		flush_altivec_to_thread(target);
+		flush_tmreg_to_thread(target);
+	} else {
+		flush_altivec_to_thread(target);
+	}
 
 	BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
 		     offsetof(struct thread_vr_state, vr[32]));
 
+	if (MSR_TM_ACTIVE(target->thread.regs->msr))
+		addr = &target->thread.transact_vr;
+	else
+		addr = &target->thread.vr_state;
 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
-				 &target->thread.vr_state, 0,
-				 33 * sizeof(vector128));
+			addr, 0, 33 * sizeof(vector128));
+
 	if (!ret && count > 0) {
 		/*
 		 * We use only the first word of vrsave.
@@ -486,13 +576,21 @@ static int vr_set(struct task_struct *target, const struct user_regset *regset,
 			u32 word;
 		} vrsave;
 		memset(&vrsave, 0, sizeof(vrsave));
-		vrsave.word = target->thread.vrsave;
+
+		if (MSR_TM_ACTIVE(target->thread.regs->msr))
+			vrsave.word = target->thread.transact_vrsave;
+		else
+			vrsave.word = target->thread.vrsave;
+
 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
 					 33 * sizeof(vector128), -1);
-		if (!ret)
-			target->thread.vrsave = vrsave.word;
+		if (!ret) {
+			if (MSR_TM_ACTIVE(target->thread.regs->msr))
+				target->thread.transact_vrsave = vrsave.word;
+			else
+				target->thread.vrsave = vrsave.word;
+		}
 	}
-
 	return ret;
 }
 #endif /* CONFIG_ALTIVEC */
@@ -613,6 +711,417 @@ static int evr_set(struct task_struct *target, const struct user_regset *regset,
 }
 #endif /* CONFIG_SPE */
 
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+
+/*
+ *  Transactional SPR
+ *
+ * struct {
+ * 	u64		tm_tfhar;
+ *	u64		tm_texasr;
+ *	u64		tm_tfiar;
+ *	unsigned long	tm_orig_msr;
+ * 	unsigned long	tm_tar;
+ *	unsigned long	tm_ppr;
+ *	unsigned long	tm_dscr;
+ * };
+ */
+static int tm_spr_get(struct task_struct *target, const struct user_regset *regset,
+		   unsigned int pos, unsigned int count,
+		   void *kbuf, void __user *ubuf)
+{
+	int ret;
+
+	flush_fp_to_thread(target);
+	flush_altivec_to_thread(target);
+	flush_tmreg_to_thread(target);
+
+	/* TFHAR register */
+	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+			&target->thread.tm_tfhar, 0, sizeof(u64));
+
+	BUILD_BUG_ON(offsetof(struct thread_struct, tm_tfhar) +
+			sizeof(u64) != offsetof(struct thread_struct, tm_texasr));
+
+	/* TEXASR register */
+	if (!ret)
+		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+			&target->thread.tm_texasr, sizeof(u64), 2 * sizeof(u64));
+
+	BUILD_BUG_ON(offsetof(struct thread_struct, tm_texasr) +
+			sizeof(u64) != offsetof(struct thread_struct, tm_tfiar));
+
+	/* TFIAR register */
+	if (!ret)
+		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+			&target->thread.tm_tfiar, 2 * sizeof(u64), 3 * sizeof(u64));
+
+	BUILD_BUG_ON(offsetof(struct thread_struct, tm_tfiar) +
+			sizeof(u64) != offsetof(struct thread_struct, tm_orig_msr));
+
+	/* TM checkpointed original MSR */
+	if (!ret)
+		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+			&target->thread.tm_orig_msr, 3 * sizeof(u64),
+				3 * sizeof(u64) + sizeof(unsigned long));
+
+	BUILD_BUG_ON(offsetof(struct thread_struct, tm_orig_msr) +
+			sizeof(unsigned long) + sizeof(struct pt_regs)
+				!= offsetof(struct thread_struct, tm_tar));
+
+	/* TM checkpointed TAR register */
+	if (!ret)
+		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+			&target->thread.tm_tar, 3 * sizeof(u64) +
+				sizeof(unsigned long) , 3 * sizeof(u64) +
+					2 * sizeof(unsigned long));
+
+	BUILD_BUG_ON(offsetof(struct thread_struct, tm_tar)
+			+ sizeof(unsigned long) !=
+				offsetof(struct thread_struct, tm_ppr));
+
+	/* TM checkpointed PPR register */
+	if (!ret)
+		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, 
+				&target->thread.tm_ppr, 3 * sizeof(u64) +
+					2 * sizeof(unsigned long), 3 * sizeof(u64) +
+						3 * sizeof(unsigned long));
+
+	BUILD_BUG_ON(offsetof(struct thread_struct, tm_ppr) +
+			sizeof(unsigned long) !=
+				offsetof(struct thread_struct, tm_dscr));
+
+	/* TM checkpointed DSCR register */
+	if (!ret)
+		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+			&target->thread.tm_dscr, 3 * sizeof(u64)
+				+ 3 * sizeof(unsigned long), 3 * sizeof(u64)
+						+ 4 * sizeof(unsigned long));
+	return ret;
+}
+
+static int tm_spr_set(struct task_struct *target, const struct user_regset *regset,
+		   unsigned int pos, unsigned int count,
+		   const void *kbuf, const void __user *ubuf)
+{
+	int ret;
+
+	flush_fp_to_thread(target);
+	flush_altivec_to_thread(target);
+	flush_tmreg_to_thread(target);
+
+	/* TFHAR register */
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				&target->thread.tm_tfhar, 0, sizeof(u64));
+
+	BUILD_BUG_ON(offsetof(struct thread_struct, tm_tfhar)
+		+ sizeof(u64) != offsetof(struct thread_struct, tm_texasr));
+
+	/* TEXASR register */
+	if (!ret)
+		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+			&target->thread.tm_texasr, sizeof(u64), 2 * sizeof(u64));
+
+	BUILD_BUG_ON(offsetof(struct thread_struct, tm_texasr)
+		+ sizeof(u64) != offsetof(struct thread_struct, tm_tfiar));
+
+	/* TFIAR register */
+	if (!ret)
+		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+			&target->thread.tm_tfiar, 2 * sizeof(u64), 3 * sizeof(u64));
+
+	BUILD_BUG_ON(offsetof(struct thread_struct, tm_tfiar)
+		+ sizeof(u64) != offsetof(struct thread_struct, tm_orig_msr));
+
+	/* TM checkpointed orig MSR */
+	if (!ret)
+		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+			&target->thread.tm_orig_msr, 3 * sizeof(u64),
+				3 * sizeof(u64) + sizeof(unsigned long));
+	
+	BUILD_BUG_ON(offsetof(struct thread_struct, tm_orig_msr)
+		+ sizeof(unsigned long) + sizeof(struct pt_regs) !=
+			offsetof(struct thread_struct, tm_tar));
+
+	/* TM checkpointed TAR register */
+	if (!ret)
+		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+			&target->thread.tm_tar, 3 * sizeof(u64) +
+				sizeof(unsigned long), 3 * sizeof(u64) +
+					2 * sizeof(unsigned long));
+
+	BUILD_BUG_ON(offsetof(struct thread_struct, tm_tar)
+			+ sizeof(unsigned long) != offsetof(struct thread_struct, tm_ppr));
+
+	/* TM checkpointed PPR register */
+	if (!ret)
+		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				&target->thread.tm_ppr, 3 * sizeof(u64)
+					+ 2 * sizeof(unsigned long), 3 * sizeof(u64)
+					+ 3 * sizeof(unsigned long));
+
+	BUILD_BUG_ON(offsetof(struct thread_struct, tm_ppr) +
+			sizeof(unsigned long) !=
+				offsetof(struct thread_struct, tm_dscr));
+
+	/* TM checkpointed DSCR register */
+	if (!ret)
+		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				&target->thread.tm_dscr,
+					3 * sizeof(u64) + 3 * sizeof(unsigned long),
+					3 * sizeof(u64) + 4 * sizeof(unsigned long));
+
+	return ret;
+}
+
+/*
+ * Checkpointed GPR
+ *
+ * struct data {
+ * 	struct pt_regs ckpt_regs;
+ * };
+ */
+static int tm_cgpr_get(struct task_struct *target, const struct user_regset *regset,
+		   unsigned int pos, unsigned int count,
+		   void *kbuf, void __user *ubuf)
+{
+	int ret;
+
+	flush_fp_to_thread(target);
+	flush_altivec_to_thread(target);
+	flush_tmreg_to_thread(target);
+	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+			&target->thread.ckpt_regs, 0,
+				sizeof(struct pt_regs));
+	return ret;
+}
+
+static int tm_cgpr_set(struct task_struct *target, const struct user_regset *regset,
+		   unsigned int pos, unsigned int count,
+		   const void *kbuf, const void __user *ubuf)
+{
+	int ret;
+
+	flush_fp_to_thread(target);
+	flush_altivec_to_thread(target);
+	flush_tmreg_to_thread(target);
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+					&target->thread.ckpt_regs, 0,
+						sizeof(struct pt_regs));
+	return ret;
+}
+
+/*
+ * Checkpointed FPR
+ *
+ * struct data {
+ * 	u64	fpr[32];
+ * 	u64	fpscr;
+ * };
+ */
+static int tm_cfpr_get(struct task_struct *target, const struct user_regset *regset,
+		   unsigned int pos, unsigned int count,
+		   void *kbuf, void __user *ubuf)
+{
+#ifdef CONFIG_VSX
+	u64 buf[33];
+	int i;
+#endif
+	flush_fp_to_thread(target);
+	flush_altivec_to_thread(target);
+	flush_tmreg_to_thread(target);
+
+#ifdef CONFIG_VSX
+	/* copy to local buffer then write that out */
+	for (i = 0; i < 32 ; i++)
+		buf[i] = target->thread.TS_FPR(i);
+	buf[32] = target->thread.fp_state.fpscr;
+	return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
+
+#else
+	BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
+		offsetof(struct thread_fp_state, fpr[32][0]));
+
+	return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+			&target->thread.thread_fp_state, 0, -1);
+#endif
+}
+
+static int tm_cfpr_set(struct task_struct *target, const struct user_regset *regset,
+		   unsigned int pos, unsigned int count,
+		   const void *kbuf, const void __user *ubuf)
+{
+#ifdef CONFIG_VSX
+	u64 buf[33];
+	int i;
+#endif
+	flush_fp_to_thread(target);
+	flush_altivec_to_thread(target);
+	flush_tmreg_to_thread(target);
+
+#ifdef CONFIG_VSX
+	/* copy to local buffer then write that out */
+	i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
+	if (i)
+		return i;
+	for (i = 0; i < 32 ; i++)
+		target->thread.TS_FPR(i) = buf[i];
+	target->thread.fp_state.fpscr = buf[32];
+        return 0;
+#else
+	BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
+		      offsetof(struct thread_fp_state, fpr[32][0]));
+
+	return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				&target->thread.fp_state, 0, -1);
+#endif
+}
+
+/*
+ * Checkpointed VMX
+ *
+ * struct data {
+ * 	vector128	vr[32];
+ * 	vector128	vscr;
+ * 	vector128	vrsave;	
+ *};
+ */
+static int tm_cvmx_get(struct task_struct *target, const struct user_regset *regset,
+		   unsigned int pos, unsigned int count,
+		   void *kbuf, void __user *ubuf)
+{
+	int ret;
+
+	flush_fp_to_thread(target);
+	flush_altivec_to_thread(target);
+	flush_tmreg_to_thread(target);
+
+	BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
+		     offsetof(struct thread_vr_state, vr[32]));
+
+	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+				  &target->thread.vr_state, 0,
+				  33 * sizeof(vector128));
+	if (!ret) {
+		/*
+		 * Copy out only the low-order word of vrsave.
+		 */
+		union {
+			elf_vrreg_t reg;
+			u32 word;
+		} vrsave;
+		memset(&vrsave, 0, sizeof(vrsave));
+		vrsave.word = target->thread.vrsave;
+		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave,
+					  33 * sizeof(vector128), -1);
+	}
+	return ret;
+}
+
+static int tm_cvmx_set(struct task_struct *target, const struct user_regset *regset,
+		   unsigned int pos, unsigned int count,
+		   const void *kbuf, const void __user *ubuf)
+{
+	int ret;
+
+	flush_fp_to_thread(target);
+	flush_altivec_to_thread(target);
+	flush_tmreg_to_thread(target);
+
+	BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
+		offsetof(struct thread_vr_state, vr[32]));
+
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				 &target->thread.vr_state, 0,
+				 33 * sizeof(vector128));
+	if (!ret && count > 0) {
+		/*
+		 * We use only the first word of vrsave.
+		 */
+		union {
+			elf_vrreg_t reg;
+			u32 word;
+		} vrsave;
+		memset(&vrsave, 0, sizeof(vrsave));
+		vrsave.word = target->thread.vrsave;
+		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
+					 33 * sizeof(vector128), -1);
+		if (!ret)
+			target->thread.vrsave = vrsave.word;
+	}
+	return ret;
+}
+#endif	/* CONFIG_PPC_TRANSACTIONAL_MEM */
+
+/*
+ * Miscellaneous Registers
+ *
+ * struct {
+ * 	unsigned long dscr;
+ *	unsigned long ppr;
+ * 	unsigned long tar;
+ * };
+ */
+static int misc_get(struct task_struct *target, const struct user_regset *regset,
+		   unsigned int pos, unsigned int count,
+		   void *kbuf, void __user *ubuf)
+{
+	int ret;
+
+	/* DSCR register */
+	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+					&target->thread.dscr, 0,
+					sizeof(unsigned long));
+
+	BUILD_BUG_ON(offsetof(struct thread_struct, dscr) + sizeof(unsigned long) +
+		     		sizeof(unsigned long) != offsetof(struct thread_struct, ppr));
+
+	/* PPR register */
+	if (!ret)
+		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+					  &target->thread.ppr, sizeof(unsigned long),
+					  2 * sizeof(unsigned long));
+
+	BUILD_BUG_ON(offsetof(struct thread_struct, ppr) + sizeof(unsigned long)
+		     			!= offsetof(struct thread_struct, tar));
+	/* TAR register */
+	if (!ret)
+		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+					  &target->thread.tar, 2 * sizeof(unsigned long),
+					  3 * sizeof(unsigned long));
+	return ret;
+}
+
+static int misc_set(struct task_struct *target, const struct user_regset *regset,
+		   unsigned int pos, unsigned int count,
+		   const void *kbuf, const void __user *ubuf)
+{
+	int ret;
+
+	/* DSCR register */
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+					&target->thread.dscr, 0,
+					sizeof(unsigned long));
+
+	BUILD_BUG_ON(offsetof(struct thread_struct, dscr) + sizeof(unsigned long) +
+		     	sizeof(unsigned long) != offsetof(struct thread_struct, ppr));
+
+	/* PPR register */
+	if (!ret)
+		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+						&target->thread.ppr, sizeof(unsigned long),
+						2 * sizeof(unsigned long));
+
+	BUILD_BUG_ON(offsetof(struct thread_struct, ppr) + sizeof(unsigned long)
+						!= offsetof(struct thread_struct, tar));
+
+	/* TAR register */
+	if (!ret)
+		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+						&target->thread.tar, 2 * sizeof(unsigned long),
+						3 * sizeof(unsigned long));
+	return ret;
+}
 
 /*
  * These are our native regset flavors.
@@ -629,6 +1138,13 @@ enum powerpc_regset {
 #ifdef CONFIG_SPE
 	REGSET_SPE,
 #endif
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+	REGSET_TM_SPR,		/* TM generic SPR */
+	REGSET_TM_CGPR,		/* TM checkpointed GPR */
+	REGSET_TM_CFPR,		/* TM checkpointed FPR */
+	REGSET_TM_CVMX,		/* TM checkpointed VMX */
+#endif
+	REGSET_MISC		/* Miscellaneous */
 };
 
 static const struct user_regset native_regsets[] = {
@@ -663,6 +1179,33 @@ static const struct user_regset native_regsets[] = {
 		.active = evr_active, .get = evr_get, .set = evr_set
 	},
 #endif
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+	[REGSET_TM_SPR] = {
+		.core_note_type = NT_PPC_TM_SPR, .n = 7,
+		.size = sizeof(u64), .align = sizeof(u64),
+		.get = tm_spr_get, .set = tm_spr_set
+	},
+	[REGSET_TM_CGPR] = {
+		.core_note_type = NT_PPC_TM_CGPR, .n = 14,
+		.size = sizeof(u64), .align = sizeof(u64),
+		.get = tm_cgpr_get, .set = tm_cgpr_set
+	},
+	[REGSET_TM_CFPR] = {
+		.core_note_type = NT_PPC_TM_CFPR, .n = ELF_NFPREG,
+		.size = sizeof(double), .align = sizeof(double),
+		.get = tm_cfpr_get, .set = tm_cfpr_set
+	},
+	[REGSET_TM_CVMX] = {
+		.core_note_type = NT_PPC_TM_CVMX, .n = 34,
+		.size = sizeof(vector128), .align = sizeof(vector128),
+		.get = tm_cvmx_get, .set = tm_cvmx_set
+	},
+#endif
+	[REGSET_MISC] = {
+		.core_note_type = NT_PPC_MISC, .n = 3,
+		.size = sizeof(u64), .align = sizeof(u64),
+		.get = misc_get, .set = misc_set
+	},
 };
 
 static const struct user_regset_view user_ppc_native_view = {
@@ -831,6 +1374,33 @@ static const struct user_regset compat_regsets[] = {
 		.active = evr_active, .get = evr_get, .set = evr_set
 	},
 #endif
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+	[REGSET_TM_SPR] = {
+		.core_note_type = NT_PPC_TM_SPR, .n = 7,
+		.size = sizeof(u64), .align = sizeof(u64),
+		.get = tm_spr_get, .set = tm_spr_set
+	},
+	[REGSET_TM_CGPR] = {
+		.core_note_type = NT_PPC_TM_CGPR, .n = 14,
+		.size = sizeof(u64), .align = sizeof(u64),
+		.get = tm_cgpr_get, .set = tm_cgpr_set
+	},
+	[REGSET_TM_CFPR] = {
+		.core_note_type = NT_PPC_TM_CFPR, .n = ELF_NFPREG,
+		.size = sizeof(double), .align = sizeof(double),
+		.get = tm_cfpr_get, .set = tm_cfpr_set
+	},
+	[REGSET_TM_CVMX] = {
+		.core_note_type = NT_PPC_TM_CVMX, .n = 34,
+		.size = sizeof(vector128), .align = sizeof(vector128),
+		.get = tm_cvmx_get, .set = tm_cvmx_set
+	},
+#endif
+	[REGSET_MISC] = {
+		.core_note_type = NT_PPC_MISC, .n = 3,
+		.size = sizeof(u64), .align = sizeof(u64),
+		.get = misc_get, .set = misc_set
+	},
 };
 
 static const struct user_regset_view user_ppc_compat_view = {
@@ -1754,7 +2324,41 @@ long arch_ptrace(struct task_struct *child, long request,
 					     REGSET_SPE, 0, 35 * sizeof(u32),
 					     datavp);
 #endif
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+	case PTRACE_GETTM_SPRREGS:
+		return copy_regset_to_user(child, &user_ppc_native_view,
+					   REGSET_TM_SPR, 0, 6 * sizeof(u64) + sizeof(unsigned long), datavp);
+	case PTRACE_SETTM_SPRREGS:
+		return copy_regset_from_user(child, &user_ppc_native_view,
+					   REGSET_TM_SPR, 0, 6 * sizeof(u64) + sizeof(unsigned long), datavp);
+	case PTRACE_GETTM_CGPRREGS:
+		return copy_regset_to_user(child, &user_ppc_native_view,
+					   REGSET_TM_CGPR, 0, sizeof(struct pt_regs), datavp);
+	case PTRACE_SETTM_CGPRREGS:
+		return copy_regset_from_user(child, &user_ppc_native_view,
+					   REGSET_TM_CGPR, 0, sizeof(struct pt_regs), datavp);
+	case PTRACE_GETTM_CFPRREGS:
+		return copy_regset_to_user(child, &user_ppc_native_view,
+					   REGSET_TM_CFPR, 0, sizeof(elf_fpregset_t), datavp);
+	case PTRACE_SETTM_CFPRREGS:
+		return copy_regset_from_user(child, &user_ppc_native_view,
+					   REGSET_TM_CFPR, 0, sizeof(elf_fpregset_t), datavp);
+	case PTRACE_GETTM_CVMXREGS:
+		return copy_regset_to_user(child, &user_ppc_native_view,
+					   REGSET_TM_CVMX, 0, (33 * sizeof(vector128) + sizeof(u32)), datavp);
+	case PTRACE_SETTM_CVMXREGS:
+		return copy_regset_from_user(child, &user_ppc_native_view,
+					   REGSET_TM_CVMX, 0, (33 * sizeof(vector128) + sizeof(u32)), datavp);
+#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
 
+	case PTRACE_GETMSCREGS:
+		return copy_regset_to_user(child, &user_ppc_native_view,
+					   REGSET_MISC, 0, 3 * sizeof(u64),
+					   datavp);
+	case PTRACE_SETMSCREGS:
+		return copy_regset_from_user(child, &user_ppc_native_view,
+					   REGSET_MISC, 0, 3 * sizeof(u64),
+					   datavp);
 	default:
 		ret = ptrace_request(child, request, addr, data);
 		break;
diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
index ef6103b..13090e3 100644
--- a/include/uapi/linux/elf.h
+++ b/include/uapi/linux/elf.h
@@ -379,6 +379,11 @@ typedef struct elf64_shdr {
 #define NT_PPC_VMX	0x100		/* PowerPC Altivec/VMX registers */
 #define NT_PPC_SPE	0x101		/* PowerPC SPE/EVR registers */
 #define NT_PPC_VSX	0x102		/* PowerPC VSX registers */
+#define NT_PPC_TM_SPR	0x103		/* PowerPC transactional memory specific registers */
+#define NT_PPC_TM_CGPR	0x104		/* PowerpC transactional memory checkpointed GPR */
+#define NT_PPC_TM_CFPR	0x105		/* PowerPC transactional memory checkpointed FPR */
+#define NT_PPC_TM_CVMX	0x106		/* PowerPC transactional memory checkpointed VMX */
+#define NT_PPC_MISC	0x107		/* PowerPC miscellaneous registers */
 #define NT_386_TLS	0x200		/* i386 TLS slots (struct user_desc) */
 #define NT_386_IOPERM	0x201		/* x86 io permission bitmap (1=deny) */
 #define NT_X86_XSTATE	0x202		/* x86 extended state using xsave */
-- 
1.7.11.7

^ permalink raw reply related

* [PATCH] ASoC: fsl_sai: Add imx6sx platform support
From: Nicolin Chen @ 2014-04-01 11:34 UTC (permalink / raw)
  To: broonie
  Cc: mark.rutland, devicetree, alsa-devel, pawel.moll, linux-doc,
	ijc+devicetree, linux-kernel, robh+dt, timur, Li.Xiubo, rob,
	galak, linuxppc-dev

The next coming i.MX6 Solo X SoC also contains SAI module while we use
imp_pcm_init() for i.MX platform.

So this patch adds one compatible route for imx6sx and updates the DT
doc accordingly.

Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com>
---
 Documentation/devicetree/bindings/sound/fsl-sai.txt |  2 +-
 sound/soc/fsl/fsl_sai.c                             | 12 ++++++++++--
 sound/soc/fsl/fsl_sai.h                             |  1 +
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/fsl-sai.txt b/Documentation/devicetree/bindings/sound/fsl-sai.txt
index 98611a6..35c09fe 100644
--- a/Documentation/devicetree/bindings/sound/fsl-sai.txt
+++ b/Documentation/devicetree/bindings/sound/fsl-sai.txt
@@ -7,7 +7,7 @@ codec/DSP interfaces.
 
 
 Required properties:
-- compatible: Compatible list, contains "fsl,vf610-sai".
+- compatible: Compatible list, contains "fsl,vf610-sai" or "fsl,imx6sx-sai".
 - reg: Offset and length of the register set for the device.
 - clocks: Must contain an entry for each entry in clock-names.
 - clock-names : Must include the "sai" entry.
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index d64c33f..9ed6795 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -22,6 +22,7 @@
 #include <sound/pcm_params.h>
 
 #include "fsl_sai.h"
+#include "imx-pcm.h"
 
 #define FSL_SAI_FLAGS (FSL_SAI_CSR_SEIE |\
 		       FSL_SAI_CSR_FEIE)
@@ -592,6 +593,9 @@ static int fsl_sai_probe(struct platform_device *pdev)
 
 	sai->pdev = pdev;
 
+	if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx6sx-sai"))
+		sai->sai_on_imx = true;
+
 	sai->big_endian_regs = of_property_read_bool(np, "big-endian-regs");
 	if (sai->big_endian_regs)
 		fsl_sai_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG;
@@ -634,12 +638,16 @@ static int fsl_sai_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
-			SND_DMAENGINE_PCM_FLAG_NO_RESIDUE);
+	if (sai->sai_on_imx)
+		return imx_pcm_dma_init(pdev);
+	else
+		return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
+				SND_DMAENGINE_PCM_FLAG_NO_RESIDUE);
 }
 
 static const struct of_device_id fsl_sai_ids[] = {
 	{ .compatible = "fsl,vf610-sai", },
+	{ .compatible = "fsl,imx6sx-sai", },
 	{ /* sentinel */ }
 };
 
diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h
index be26d46..677670d 100644
--- a/sound/soc/fsl/fsl_sai.h
+++ b/sound/soc/fsl/fsl_sai.h
@@ -130,6 +130,7 @@ struct fsl_sai {
 	bool big_endian_regs;
 	bool big_endian_data;
 	bool is_dsp_mode;
+	bool sai_on_imx;
 
 	struct snd_dmaengine_dai_dma_data dma_params_rx;
 	struct snd_dmaengine_dai_dma_data dma_params_tx;
-- 
1.8.4

^ permalink raw reply related

* [PATCH 1/2] ASoC: fsl_sai: Add clock control for SAI
From: Nicolin Chen @ 2014-04-01 11:52 UTC (permalink / raw)
  To: broonie, shawn.guo
  Cc: mark.rutland, devicetree, alsa-devel, pawel.moll, linux-doc,
	ijc+devicetree, linux-kernel, robh+dt, timur, Li.Xiubo, rob,
	galak, linuxppc-dev
In-Reply-To: <cover.1396352401.git.Guangyu.Chen@freescale.com>

The SAI mainly has two clocks:
ipg_clock -- registers access for SoC or DMA to read and write.
sai_clock -- providing DAI format bit clock and frame clock.

Thus this patch adds these two clocks to the driver with their clock
controls and replaces the regmap clock 'sai_clock' with 'ipg_clock'.

Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com>
---
 .../devicetree/bindings/sound/fsl-sai.txt          |  7 ++--
 sound/soc/fsl/fsl_sai.c                            | 37 ++++++++++++++++++++--
 sound/soc/fsl/fsl_sai.h                            |  2 ++
 3 files changed, 41 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/fsl-sai.txt b/Documentation/devicetree/bindings/sound/fsl-sai.txt
index 35c09fe..bad4453 100644
--- a/Documentation/devicetree/bindings/sound/fsl-sai.txt
+++ b/Documentation/devicetree/bindings/sound/fsl-sai.txt
@@ -11,5 +11,6 @@ Required properties:
 - reg: Offset and length of the register set for the device.
 - clocks: Must contain an entry for each entry in clock-names.
-- clock-names : Must include the "sai" entry.
+- clock-names : Must include the "ipg" for register access and "sai" for bit
+  clock and frame clock providing.
 - dmas : Generic dma devicetree binding as described in
   Documentation/devicetree/bindings/dma/dma.txt.
@@ -31,6 +32,6 @@ sai2: sai@40031000 {
 	      pinctrl-names = "default";
 	      pinctrl-0 = <&pinctrl_sai2_1>;
-	      clocks = <&clks VF610_CLK_SAI2>;
-	      clock-names = "sai";
+	      clocks = <&clks VF610_CLK_SAI2>, <&clks VF610_CLK_SAI2>;
+	      clock-names = "ipg", "sai";
 	      dma-names = "tx", "rx";
 	      dmas = <&edma0 0 VF610_EDMA_MUXID0_SAI2_TX>,
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 3847d2a..2d749df 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -428,5 +428,18 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream,
 {
 	struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
-	u32 reg;
+	struct device *dev = &sai->pdev->dev;
+	u32 reg, ret;
+
+	ret = clk_prepare_enable(sai->ipg_clk);
+	if (ret) {
+		dev_err(dev, "failed to prepare and enable ipg clock\n");
+		return ret;
+	}
+
+	ret = clk_prepare_enable(sai->sai_clk);
+	if (ret) {
+		dev_err(dev, "failed to prepare and enable sai clock\n");
+		goto err;
+	}
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -439,4 +452,9 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream,
 
 	return 0;
+
+err:
+	clk_disable_unprepare(sai->ipg_clk);
+
+	return ret;
 }
 
@@ -454,4 +472,7 @@ static void fsl_sai_shutdown(struct snd_pcm_substream *substream,
 	regmap_update_bits(sai->regmap, reg, FSL_SAI_CR3_TRCE,
 			   ~FSL_SAI_CR3_TRCE);
+
+	clk_disable_unprepare(sai->sai_clk);
+	clk_disable_unprepare(sai->ipg_clk);
 }
 
@@ -609,5 +630,5 @@ static int fsl_sai_probe(struct platform_device *pdev)
 
 	sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
-			"sai", base, &fsl_sai_regmap_config);
+			"ipg", base, &fsl_sai_regmap_config);
 	if (IS_ERR(sai->regmap)) {
 		dev_err(&pdev->dev, "regmap init failed\n");
@@ -615,4 +636,16 @@ static int fsl_sai_probe(struct platform_device *pdev)
 	}
 
+	sai->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
+	if (IS_ERR(sai->ipg_clk)) {
+		dev_err(&pdev->dev, "failed to get ipg clock\n");
+		return PTR_ERR(sai->ipg_clk);
+	}
+
+	sai->sai_clk = devm_clk_get(&pdev->dev, "sai");
+	if (IS_ERR(sai->sai_clk)) {
+		dev_err(&pdev->dev, "failed to get sai clock\n");
+		return PTR_ERR(sai->sai_clk);
+	}
+
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h
index 677670d..cbaf114 100644
--- a/sound/soc/fsl/fsl_sai.h
+++ b/sound/soc/fsl/fsl_sai.h
@@ -127,4 +127,6 @@ struct fsl_sai {
 	struct platform_device *pdev;
 	struct regmap *regmap;
+	struct clk *ipg_clk;
+	struct clk *sai_clk;
 
 	bool big_endian_regs;
-- 
1.8.4

^ permalink raw reply related

* [PATCH 0/2] Add ipg clock control to sai driver
From: Nicolin Chen @ 2014-04-01 11:52 UTC (permalink / raw)
  To: broonie, shawn.guo
  Cc: mark.rutland, devicetree, alsa-devel, pawel.moll, linux-doc,
	ijc+devicetree, linux-kernel, robh+dt, timur, Li.Xiubo, rob,
	galak, linuxppc-dev

This series of patches add ipg clock control to fsl_sai driver and updates
the vf610.dtsi accordingly.

@Shawn
I'm not sure if VF610 currently does full works with SAI audio function.
The PATCH-2 is based on broonie/for-next.

Nicolin Chen (2):
  ASoC: fsl_sai: Add clock control for SAI
  ARM: dts: Add ipg clock for sai2 on VF610 platform

 .../devicetree/bindings/sound/fsl-sai.txt          |  7 ++--
 arch/arm/boot/dts/vf610.dtsi                       |  4 +--
 sound/soc/fsl/fsl_sai.c                            | 37 ++++++++++++++++++++--
 sound/soc/fsl/fsl_sai.h                            |  2 ++
 4 files changed, 43 insertions(+), 7 deletions(-)

-- 
1.8.4

^ permalink raw reply

* [PATCH 2/2] ARM: dts: Add ipg clock for sai2 on VF610 platform
From: Nicolin Chen @ 2014-04-01 11:52 UTC (permalink / raw)
  To: broonie, shawn.guo
  Cc: mark.rutland, devicetree, alsa-devel, pawel.moll, linux-doc,
	ijc+devicetree, linux-kernel, robh+dt, timur, Li.Xiubo, rob,
	galak, linuxppc-dev
In-Reply-To: <cover.1396352401.git.Guangyu.Chen@freescale.com>

Since we added ipg clock to the DT binding, we should update the current
SAI dts/dtsi so as not to break their functions.

Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com>
---
 arch/arm/boot/dts/vf610.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi
index d31ce1b..493c498 100644
--- a/arch/arm/boot/dts/vf610.dtsi
+++ b/arch/arm/boot/dts/vf610.dtsi
@@ -140,6 +140,6 @@
 				reg = <0x40031000 0x1000>;
 				interrupts = <0 86 0x04>;
-				clocks = <&clks VF610_CLK_SAI2>;
-				clock-names = "sai";
+				clocks = <&clks VF610_CLK_SAI2>, <&clks VF610_CLK_SAI2>;
+				clock-names = "ipg", "sai";
 				status = "disabled";
 			};
-- 
1.8.4

^ permalink raw reply related

* Re: [PATCH bisect 1/2] ASoC: fsl_sai: Fix buggy configurations in trigger()
From: Mark Brown @ 2014-04-01 11:56 UTC (permalink / raw)
  To: Nicolin Chen; +Cc: alsa-devel, Li.Xiubo, linuxppc-dev, linux-kernel, timur
In-Reply-To: <1396322227-482-2-git-send-email-Guangyu.Chen@freescale.com>

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

On Tue, Apr 01, 2014 at 11:17:06AM +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.

Applied, thanks.

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

^ permalink raw reply

* Re: [PATCH bisect 2/2] ASoC: fsl_sai: Separately enable interrupts for Tx and Rx streams
From: Mark Brown @ 2014-04-01 12:07 UTC (permalink / raw)
  To: Nicolin Chen; +Cc: alsa-devel, Li.Xiubo, linuxppc-dev, linux-kernel, timur
In-Reply-To: <1396322227-482-3-git-send-email-Guangyu.Chen@freescale.com>

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

On Tue, Apr 01, 2014 at 11:17:07AM +0800, Nicolin Chen wrote:
> We only enable one side interrupt for each stream since over/underrun
> on the opposite stream would be resulted from what we previously did,
> enabling TERE but remaining FRDE disabled, even though the xrun on the
> opposite direction will not break the current stream.

This still doesn't apply against fsl-sai (nor for-next).

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

^ permalink raw reply

* Re: [PATCH bisect 2/2] ASoC: fsl_sai: Separately enable interrupts for Tx and Rx streams
From: Nicolin Chen @ 2014-04-01 13:21 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel, Li.Xiubo, linuxppc-dev, linux-kernel, timur
In-Reply-To: <20140401120715.GR2269@sirena.org.uk>

On Tue, Apr 01, 2014 at 01:07:15PM +0100, Mark Brown wrote:
> On Tue, Apr 01, 2014 at 11:17:07AM +0800, Nicolin Chen wrote:
> > We only enable one side interrupt for each stream since over/underrun
> > on the opposite stream would be resulted from what we previously did,
> > enabling TERE but remaining FRDE disabled, even though the xrun on the
> > opposite direction will not break the current stream.
> 
> This still doesn't apply against fsl-sai (nor for-next).

Sir, I just rebased my for-next branch again and found that it's missing
two applied patches: "ASoC: fsl_sai: Add isr to deal with error flag" and
"ASoC: fsl_sai: Improve fsl_sai_isr()", so that's why this PATCH-2 could
not be applied against it as it needs the macro that's included in the
patch "ASoC: fsl_sai: Add isr to deal with error flag".

What should I do now?

Thank you,
Nicolin

^ permalink raw reply

* [PATCH] powerpc: Use 64k io pages when we never see an HEA
From: Alexander Graf @ 2014-04-01 13:46 UTC (permalink / raw)
  To: linuxppc-dev

When we never get around to seeing an HEA ethernet adapter, there's
no point in restricting ourselves to 4k IO page size.

This speeds up IO maps when CONFIG_IBMEBUS is disabled.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 arch/powerpc/mm/hash_utils_64.c | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index d766d6e..c0ef976 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -445,6 +445,20 @@ static void mmu_psize_set_default_penc(void)
 			mmu_psize_defs[bpsize].penc[apsize] = -1;
 }
 
+static bool might_have_hea(void)
+{
+	/*
+	 * The HEA ethernet adapter requires awareness of the
+	 * GX bus. Without that awareness we can easily assume
+	 * we will never see an HEA ethernet device.
+	 */
+#ifdef CONFIG_IBMEBUS
+	return true;
+#else
+	return false;
+#endif
+}
+
 static void __init htab_init_page_sizes(void)
 {
 	int rc;
@@ -499,10 +513,11 @@ static void __init htab_init_page_sizes(void)
 			mmu_linear_psize = MMU_PAGE_64K;
 		if (mmu_has_feature(MMU_FTR_CI_LARGE_PAGE)) {
 			/*
-			 * Don't use 64k pages for ioremap on pSeries, since
-			 * that would stop us accessing the HEA ethernet.
+			 * When running on pSeries using 64k pages for ioremap
+			 * would stop us accessing the HEA ethernet. So if we
+			 * have the chance of ever seeing one, stay at 4k.
 			 */
-			if (!machine_is(pseries))
+			if (!might_have_hea() || !machine_is(pseries))
 				mmu_io_psize = MMU_PAGE_64K;
 		} else
 			mmu_ci_restrictions = 1;
-- 
1.8.1.4

^ permalink raw reply related

* Re: [PATCH 15/33] powerpc: Fix ABIv2 issues with stack offsets in assembly code
From: Philippe Bergheaud @ 2014-04-01 13:54 UTC (permalink / raw)
  To: Anton Blanchard
  Cc: mikey, amodra, rusty, ulrich.weigand, paulus, mjw, linuxppc-dev
In-Reply-To: <1395747879-5948-16-git-send-email-anton@samba.org>

Anton Blanchard wrote:
> diff --git a/arch/powerpc/lib/memcpy_64.S b/arch/powerpc/lib/memcpy_64.S
> index 72ad055..01da956 100644
> --- a/arch/powerpc/lib/memcpy_64.S
> +++ b/arch/powerpc/lib/memcpy_64.S
> @@ -12,7 +12,7 @@
>  	.align	7
>  _GLOBAL(memcpy)
>  BEGIN_FTR_SECTION
> -	std	r3,48(r1)	/* save destination pointer for return value */
> +	std	r3,STK_PARAM(R3)(r1)	/* save destination pointer for return value */
>  FTR_SECTION_ELSE
>  #ifndef SELFTEST
>  	b	memcpy_power7

This chunk is rejected when applied to linux-3.14, because of the reference to SELTEST.
The last three context lines should rather read:

  FTR_SECTION_ELSE
  	b	memcpy_power7
  ALT_FTR_SECTION_END_IFCLR(CPU_FTR_VMX_COPY)

Same issue with [PATCH 16/33] powerpc: Fix unsafe accesses to parameter area in ELFv2.

Philippe

^ permalink raw reply

* Re: [PATCH bisect 2/2] ASoC: fsl_sai: Separately enable interrupts for Tx and Rx streams
From: Mark Brown @ 2014-04-01 16:42 UTC (permalink / raw)
  To: Nicolin Chen; +Cc: alsa-devel, Li.Xiubo, linuxppc-dev, linux-kernel, timur
In-Reply-To: <20140401132156.GB27586@MrMyself>

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

On Tue, Apr 01, 2014 at 09:21:57PM +0800, Nicolin Chen wrote:

> Sir, I just rebased my for-next branch again and found that it's missing
> two applied patches: "ASoC: fsl_sai: Add isr to deal with error flag" and
> "ASoC: fsl_sai: Improve fsl_sai_isr()", so that's why this PATCH-2 could
> not be applied against it as it needs the macro that's included in the
> patch "ASoC: fsl_sai: Add isr to deal with error flag".

Ah, those dropped out of -next due to the merge window.  I've applied
your new patch now.

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

^ permalink raw reply

* Re: [PATCH 4/4] KVM: PPC: Bookehv: Get vcpu's last instruction for emulation
From: Scott Wood @ 2014-04-01 16:58 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Mihai Caraman, <linuxppc-dev@lists.ozlabs.org>,
	<kvm@vger.kernel.org>, <kvm-ppc@vger.kernel.org>
In-Reply-To: <9EA94FFE-EC8B-40BE-A6BE-1D0FCF81F2E9@suse.de>

On Tue, 2014-04-01 at 07:47 +0200, Alexander Graf wrote:
> 
> > Am 01.04.2014 um 01:03 schrieb Scott Wood <scottwood@freescale.com>:
> > 
> >> On Mon, 2014-03-31 at 15:41 +0200, Alexander Graf wrote:
> >>> On 03/26/2014 10:17 PM, Scott Wood wrote:
> >>>> On Thu, 2014-02-20 at 18:30 +0200, Mihai Caraman wrote:
> >>>> +    /*
> >>>> +     * 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?
> > 
> > If another thread rewrites the TLB entry, then we use the new TLB entry,
> > just as if it had raced in hardware.  This check ensures that we don't
> > execute from the new TLB entry if it doesn't have execute permissions
> > (just as hardware would).
> > 
> > What happens if the new TLB entry is valid and executable, and the
> > instruction pointed to is valid, but doesn't trap (and thus we don't
> > have emulation for it)?
> > 
> >> There has to be a good way to detect such a race and deal with it, no?
> > 
> > How would you detect it?  We don't get any information from the trap
> > about what physical address the instruction was fetched from, or what
> > the instruction was.
> 
> Ah, this is a guest race where the guest modifies exactly the TLB in question. I see.
> 
> Why would this ever happen in practice (in a case where we're not executing malicious code)?

I don't know.  It probably wouldn't.  But it seems wrong to not check
the exec bit.

-Scott

^ permalink raw reply

* Re: [PATCH 4/4] KVM: PPC: Bookehv: Get vcpu's last instruction for emulation
From: Alexander Graf @ 2014-04-01 17:11 UTC (permalink / raw)
  To: Scott Wood
  Cc: Mihai Caraman, <linuxppc-dev@lists.ozlabs.org>,
	<kvm@vger.kernel.org>, <kvm-ppc@vger.kernel.org>
In-Reply-To: <1396371496.20849.51.camel@snotra.buserror.net>

On 04/01/2014 06:58 PM, Scott Wood wrote:
> On Tue, 2014-04-01 at 07:47 +0200, Alexander Graf wrote:
>>> Am 01.04.2014 um 01:03 schrieb Scott Wood <scottwood@freescale.com>:
>>>
>>>> On Mon, 2014-03-31 at 15:41 +0200, Alexander Graf wrote:
>>>>> On 03/26/2014 10:17 PM, Scott Wood wrote:
>>>>>> On Thu, 2014-02-20 at 18:30 +0200, Mihai Caraman wrote:
>>>>>> +    /*
>>>>>> +     * 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?
>>> If another thread rewrites the TLB entry, then we use the new TLB entry,
>>> just as if it had raced in hardware.  This check ensures that we don't
>>> execute from the new TLB entry if it doesn't have execute permissions
>>> (just as hardware would).
>>>
>>> What happens if the new TLB entry is valid and executable, and the
>>> instruction pointed to is valid, but doesn't trap (and thus we don't
>>> have emulation for it)?
>>>
>>>> There has to be a good way to detect such a race and deal with it, no?
>>> How would you detect it?  We don't get any information from the trap
>>> about what physical address the instruction was fetched from, or what
>>> the instruction was.
>> Ah, this is a guest race where the guest modifies exactly the TLB in question. I see.
>>
>> Why would this ever happen in practice (in a case where we're not executing malicious code)?
> I don't know.  It probably wouldn't.  But it seems wrong to not check
> the exec bit.

Right, I'm just saying that a program interrupt is not too bad of an 
answer in case the guest does something as stupid as this in kernel 
space :). It's definitely good practice to check for the exec bit.


Alex

^ 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