LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 5/8] powerpc/powernv: Sync OPAL header file with firmware
From: Gavin Shan @ 2014-05-14  4:11 UTC (permalink / raw)
  To: kvm-ppc; +Cc: aik, agraf, Gavin Shan, alex.williamson, qiudayu, linuxppc-dev
In-Reply-To: <1400040722-29608-1-git-send-email-gwshan@linux.vnet.ibm.com>

The patch synchronizes OPAL header file with firmware so that the
host kernel can make OPAL call to do error injection.

Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/opal.h                | 65 ++++++++++++++++++++++++++
 arch/powerpc/platforms/powernv/opal-wrappers.S |  1 +
 2 files changed, 66 insertions(+)

diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 66ad7a7..ca55d9c 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -175,6 +175,7 @@ extern int opal_enter_rtas(struct rtas_args *args,
 #define OPAL_SET_PARAM				90
 #define OPAL_DUMP_RESEND			91
 #define OPAL_DUMP_INFO2				94
+#define OPAL_ERR_INJECT				96
 
 #ifndef __ASSEMBLY__
 
@@ -219,6 +220,69 @@ enum OpalPciErrorSeverity {
 	OPAL_EEH_SEV_INF	= 5
 };
 
+enum OpalErrinjctType {
+	OpalErrinjctTypeFirst			= 0,
+	OpalErrinjctTypeFatal			= 1,
+	OpalErrinjctTypeRecoverRandomEvent	= 2,
+	OpalErrinjctTypeRecoverSpecialEvent	= 3,
+	OpalErrinjctTypeCorruptedPage		= 4,
+	OpalErrinjctTypeCorruptedSlb		= 5,
+	OpalErrinjctTypeTranslatorFailure	= 6,
+	OpalErrinjctTypeIoaBusError		= 7,
+	OpalErrinjctTypeIoaBusError64		= 8,
+	OpalErrinjctTypePlatformSpecific	= 9,
+	OpalErrinjctTypeDcacheStart		= 10,
+	OpalErrinjctTypeDcacheEnd		= 11,
+	OpalErrinjctTypeIcacheStart		= 12,
+	OpalErrinjctTypeIcacheEnd		= 13,
+	OpalErrinjctTypeTlbStart		= 14,
+	OpalErrinjctTypeTlbEnd			= 15,
+	OpalErrinjctTypeUpstreamIoError		= 16,
+	OpalErrinjctTypeLast			= 17,
+
+	/* IoaBusError & IoaBusError64 */
+	OpalEjtIoaLoadMemAddr			= 0,
+	OpalEjtIoaLoadMemData			= 1,
+	OpalEjtIoaLoadIoAddr			= 2,
+	OpalEjtIoaLoadIoData			= 3,
+	OpalEjtIoaLoadConfigAddr		= 4,
+	OpalEjtIoaLoadConfigData		= 5,
+	OpalEjtIoaStoreMemAddr			= 6,
+	OpalEjtIoaStoreMemData			= 7,
+	OpalEjtIoaStoreIoAddr			= 8,
+	OpalEjtIoaStoreIoData			= 9,
+	OpalEjtIoaStoreConfigAddr		= 10,
+	OpalEjtIoaStoreConfigData		= 11,
+	OpalEjtIoaDmaReadMemAddr		= 12,
+	OpalEjtIoaDmaReadMemData		= 13,
+	OpalEjtIoaDmaReadMemMaster		= 14,
+	OpalEjtIoaDmaReadMemTarget		= 15,
+	OpalEjtIoaDmaWriteMemAddr		= 16,
+	OpalEjtIoaDmaWriteMemData		= 17,
+	OpalEjtIoaDmaWriteMemMaster		= 18,
+	OpalEjtIoaDmaWriteMemTarget		= 19,
+};
+
+struct OpalErrinjct {
+	int32_t type;
+	union {
+		struct {
+			uint32_t addr;
+			uint32_t mask;
+			uint64_t phb_id;
+			uint32_t pe;
+			uint32_t function;
+		}ioa;
+		struct {
+			uint64_t addr;
+			uint64_t mask;
+			uint64_t phb_id;
+			uint32_t pe;
+			uint32_t function;
+		}ioa64;
+	};
+};
+
 enum OpalShpcAction {
 	OPAL_SHPC_GET_LINK_STATE = 0,
 	OPAL_SHPC_GET_SLOT_STATE = 1
@@ -839,6 +903,7 @@ int64_t opal_pci_get_phb_diag_data(uint64_t phb_id, void *diag_buffer,
 				   uint64_t diag_buffer_len);
 int64_t opal_pci_get_phb_diag_data2(uint64_t phb_id, void *diag_buffer,
 				    uint64_t diag_buffer_len);
+int64_t opal_err_injct(void *data);
 int64_t opal_pci_fence_phb(uint64_t phb_id);
 int64_t opal_pci_reinit(uint64_t phb_id, uint64_t reinit_scope, uint64_t data);
 int64_t opal_pci_mask_pe_error(uint64_t phb_id, uint16_t pe_number, uint8_t error_type, uint8_t mask_action);
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S
index f531ffe..46265de 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -119,6 +119,7 @@ OPAL_CALL(opal_pci_next_error,			OPAL_PCI_NEXT_ERROR);
 OPAL_CALL(opal_pci_poll,			OPAL_PCI_POLL);
 OPAL_CALL(opal_pci_msi_eoi,			OPAL_PCI_MSI_EOI);
 OPAL_CALL(opal_pci_get_phb_diag_data2,		OPAL_PCI_GET_PHB_DIAG_DATA2);
+OPAL_CALL(opal_err_injct,			OPAL_ERR_INJECT);
 OPAL_CALL(opal_xscom_read,			OPAL_XSCOM_READ);
 OPAL_CALL(opal_xscom_write,			OPAL_XSCOM_WRITE);
 OPAL_CALL(opal_lpc_read,			OPAL_LPC_READ);
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH 1/8] drivers/vfio: Introduce CONFIG_VFIO_EEH
From: Gavin Shan @ 2014-05-14  4:11 UTC (permalink / raw)
  To: kvm-ppc; +Cc: aik, agraf, Gavin Shan, alex.williamson, qiudayu, linuxppc-dev
In-Reply-To: <1400040722-29608-1-git-send-email-gwshan@linux.vnet.ibm.com>

The patch introduces CONFIG_VFIO_EEH for more IOCTL commands on
tce_iommu_driver_ops to support EEH funtionality for PCI devices
that are passed through from host to guest.

Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
 drivers/vfio/Kconfig | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig
index af7b204..4f3293b 100644
--- a/drivers/vfio/Kconfig
+++ b/drivers/vfio/Kconfig
@@ -8,11 +8,17 @@ config VFIO_IOMMU_SPAPR_TCE
 	depends on VFIO && SPAPR_TCE_IOMMU
 	default n
 
+config VFIO_EEH
+	tristate
+	depends on EEH && VFIO_IOMMU_SPAPR_TCE
+	default n
+
 menuconfig VFIO
 	tristate "VFIO Non-Privileged userspace driver framework"
 	depends on IOMMU_API
 	select VFIO_IOMMU_TYPE1 if X86
 	select VFIO_IOMMU_SPAPR_TCE if (PPC_POWERNV || PPC_PSERIES)
+	select VFIO_EEH if PPC_POWERNV
 	select ANON_INODES
 	help
 	  VFIO provides a framework for secure userspace device drivers.
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH RFC v3 0/8] EEH Support for VFIO PCI device
From: Gavin Shan @ 2014-05-14  4:11 UTC (permalink / raw)
  To: kvm-ppc; +Cc: aik, agraf, Gavin Shan, alex.williamson, qiudayu, linuxppc-dev

The series of patches intends to support EEH for PCI devices, which are
passed through to PowerKVM based guest via VFIO. The implementation is
straightforward based on the issues or problems we have to resolve to
support EEH for PowerKVM based guest.

- Emulation for EEH RTAS requests. All EEH RTAS requests goes to QEMU firstly.
  If QEMU can't handle it, the request will be sent to host via newly introduced
  VFIO container IOCTL command (VFIO_EEH_INFO) and gets handled in host kernel.

- The error injection infrastructure need support request from the userland
  utility "errinjct" and PowerKVM based guest. The userland utility "errinjct"
  works on pSeries platform well with dedicated syscall, which helps invoking
  RTAS service to fulfil error injection in kernel. From the perspective, it's
  reasonable to extend the syscall to support PowerNV platform so that OPAL call
  can be invoked in host kernel for injecting errors. The data transported
  between userland and kerenl is still following "struct rtas_args" for both
  cases of PowerNV (OPAL) and pSeries (RTAS).

The series of patches requires corresponding firmware changes from Mike Qiu to
support error injection and QEMU changes to support EEH for guest. QEMU patchset
will be sent separately.

Change log
==========
v1 -> v2:
	* EEH RTAS requests are routed to QEMU, and then possiblly to host kerenl.
	  The mechanism KVM in-kernel handling is dropped.
	* Error injection is reimplemented based syscall, instead of KVM in-kerenl
	  handling. The logic for error injection token management is moved to
	  QEMU. The error injection request is routed to QEMU and then possiblly
	  to host kernel.
v2 -> v3:
	* Make the fields in struct eeh_vfio_pci_addr, struct vfio_eeh_info based
	  on the comments from Alexey.
	* Define macros for EEH VFIO operations (Alexey).
	* Clear frozen state after successful PE reset.
	* Merge original [PATCH 1/2/3] to one.

Testing on P7
=============

- Emulex adapter

Testing on P8
=============

- Need more testing after design is finalized.

-----

Gavin Shan (8):
  drivers/vfio: Introduce CONFIG_VFIO_EEH
  powerpc/eeh: Info to trace passed devices
  drivers/vfio: New IOCTL command VFIO_EEH_INFO
  powerpc/eeh: Avoid event on passed PE
  powerpc/powernv: Sync OPAL header file with firmware
  powerpc: Extend syscall ppc_rtas()
  powerpc/powernv: Implement ppc_call_opal()
  powerpc/powernv: Error injection infrastructure

 arch/powerpc/include/asm/eeh.h                 |  52 +++
 arch/powerpc/include/asm/opal.h                |  74 ++-
 arch/powerpc/include/asm/rtas.h                |  10 +-
 arch/powerpc/include/asm/syscalls.h            |   2 +-
 arch/powerpc/include/asm/systbl.h              |   2 +-
 arch/powerpc/include/uapi/asm/unistd.h         |   2 +-
 arch/powerpc/kernel/eeh.c                      |   8 +
 arch/powerpc/kernel/eeh_pe.c                   |  80 ++++
 arch/powerpc/kernel/rtas.c                     |  57 +--
 arch/powerpc/kernel/syscalls.c                 |  50 +++
 arch/powerpc/platforms/powernv/Makefile        |   3 +-
 arch/powerpc/platforms/powernv/eeh-ioda.c      |   3 +-
 arch/powerpc/platforms/powernv/eeh-vfio.c      | 593 +++++++++++++++++++++++++
 arch/powerpc/platforms/powernv/errinject.c     | 224 ++++++++++
 arch/powerpc/platforms/powernv/opal-wrappers.S |   1 +
 arch/powerpc/platforms/powernv/opal.c          |  93 ++++
 drivers/vfio/Kconfig                           |   6 +
 drivers/vfio/vfio_iommu_spapr_tce.c            |  12 +
 include/uapi/linux/vfio.h                      |  57 +++
 kernel/sys_ni.c                                |   2 +-
 20 files changed, 1278 insertions(+), 53 deletions(-)
 create mode 100644 arch/powerpc/platforms/powernv/eeh-vfio.c
 create mode 100644 arch/powerpc/platforms/powernv/errinject.c

Thanks,
Gavin

^ permalink raw reply

* Re: powerpc/ppc64: Allow allmodconfig to build (finally !)
From: Stephen Rothwell @ 2014-05-14  3:34 UTC (permalink / raw)
  To: Guenter Roeck; +Cc: linuxppc-dev, Alan Modra
In-Reply-To: <20140513171749.GA9440@roeck-us.net>

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

Hi Guenter,

On Tue, 13 May 2014 10:17:49 -0700 Guenter Roeck <linux@roeck-us.net> wrote:
>
> On Tue, May 13, 2014 at 07:16:41PM +1000, Benjamin Herrenschmidt wrote:
> > On Mon, 2014-05-12 at 17:28 -0700, Guenter Roeck wrote:
> > 
> > > After applying this patch, I get
> > > 
> > > arch/powerpc/kernel/exceptions-64s.S:269: Error: operand out of range
> > > (0x000000000000814c is not between 0xffffffffffff8000 and 0x0000000000007ffc)
> > > arch/powerpc/kernel/exceptions-64s.S:729: Error: operand out of range
> > > (0x000000000000814c is not between 0xffffffffffff8000 and 0x0000000000007ffc)
> > > 
> > > with powerpc:defconfig, powerpc:allmodconfig, powerpc:cell_defconfig, and
> > > powerpc:maple_defconfig.
> > > 
> > > This is on top of v3.15-rc5. Any idea what is going on ?
> > > 
> > > Compiler is powerpc64-poky-linux-gcc (GCC) 4.7.2 (from poky 1.4.0-1).
> > 
> > Interesting... works with all my test configs using 4.7.3...
> > 
> > I don't have my tree at hand right now, I'll check what that means
> > tomorrow see if I can find a workaround.
> > 
> It works for me with gcc 4.8.2 (build from yocto 1.6.0).
> 
> Is asking people to use gcc 4.7.3 or later acceptable ?

OK, this appears to be an assembler bug.

$ cat test.s
	.text
x:
	.pushsection	b, "a"
	beq y
	.popsection
	.=0x80000
y:
$ /opt/cross/gcc-4.6.3-nolibc/powerpc64-linux/bin/powerpc64-linux-as --version
GNU assembler (GNU Binutils) 2.22
This assembler was configured for a target of `powerpc64-linux'.
$ /opt/cross/gcc-4.6.3-nolibc/powerpc64-linux/bin/powerpc64-linux-as -o test.o test.s 
test.s: Assembler messages:
test.s:4: Error: operand out of range (0x0000000000080000 is not between 0xffffffffffff8000 and 0x0000000000007ffc)
$ /opt/cross/gcc-4.8.1-nolibc/powerpc64-linux/bin/powerpc64-linux-as --version
GNU assembler (GNU Binutils) 2.23.52.20130512
This assembler was configured for a target of `powerpc64-linux'.
$ /opt/cross/gcc-4.8.1-nolibc/powerpc64-linux/bin/powerpc64-linux-as -o test.o test.s 
(no error)

Alan, can you shed light on when it was fixed?

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

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

^ permalink raw reply

* Re: [PATCH] powerpc/pseries: relocate "config DTL" so KConfig nests properly
From: Michael Neuling @ 2014-05-13 23:04 UTC (permalink / raw)
  To: Cody P Schafer
  Cc: Deepthi Dharwar, Paul Bolle, Gavin Shan, Li Zhong, linux-kernel,
	Paul Mackerras, Srivatsa S. Bhat, linuxppc-dev
In-Reply-To: <5371C5E5.6070701@linux.vnet.ibm.com>

On Tue, 2014-05-13 at 00:12 -0700, Cody P Schafer wrote:
> On 05/12/2014 11:23 PM, Michael Neuling wrote:
> >> powerpc/pseries: relocate "config DTL" so KConfig nests properly
> >
> > I don't know what that means.  Can you describe it in more detail?
> >
>=20
> So the "config DTL" refers to the configuration entry.
>=20
> The "nests properly" refers to the indent that 'make menuconfig' shows=
=20
> when a config-option that depends on the config-option proceeding it.
>=20
> In this case, moving config DTL up so it is below config PPC_SPLPAR=20
> means that menuconfig will show config DTL nicely indented right below=
=20
> config PPC_SPLPAR when PPC_SPLPAR is enabled.
>=20
> To contrast that, right now if I enable PPC_SPLPAR in menuconfig, all I=
=20
> can immediately tell is that "something showed up further down the list=
=20
> where I wasn't looking", and I end up having to toggle the option a few=
=20
> times to figure out what showed up, or look at the KConfig to find out=
=20
> that config DTL depends on config PPC_SPLPAR.
>=20
> Essentially, this enables menuconfig to provide a visual hint about the=
=20
> dependencies between options.

Sounds like a good idea.  Can you repost the patch with that same info
in the commit log.

Mikey


> > Mikey
> >
> >
> > On Mon, 2014-05-12 at 20:09 -0700, Cody P Schafer wrote:
> >> Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>
> >> ---
> >>   arch/powerpc/platforms/pseries/Kconfig | 20 ++++++++++----------
> >>   1 file changed, 10 insertions(+), 10 deletions(-)
> >>
> >> diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/pla=
tforms/pseries/Kconfig
> >> index 2cb8b77..e00dd4d 100644
> >> --- a/arch/powerpc/platforms/pseries/Kconfig
> >> +++ b/arch/powerpc/platforms/pseries/Kconfig
> >> @@ -33,6 +33,16 @@ config PPC_SPLPAR
> >>   	  processors, that is, which share physical processors between
> >>   	  two or more partitions.
> >>
> >> +config DTL
> >> +	bool "Dispatch Trace Log"
> >> +	depends on PPC_SPLPAR && DEBUG_FS
> >> +	help
> >> +	  SPLPAR machines can log hypervisor preempt & dispatch events to a
> >> +	  kernel buffer. Saying Y here will enable logging these events,
> >> +	  which are accessible through a debugfs file.
> >> +
> >> +	  Say N if you are unsure.
> >> +
> >>   config PSERIES_MSI
> >>          bool
> >>          depends on PCI_MSI && PPC_PSERIES && EEH
> >> @@ -122,13 +132,3 @@ config HV_PERF_CTRS
> >>   	  systems. 24x7 is available on Power 8 systems.
> >>
> >>             If unsure, select Y.
> >> -
> >> -config DTL
> >> -	bool "Dispatch Trace Log"
> >> -	depends on PPC_SPLPAR && DEBUG_FS
> >> -	help
> >> -	  SPLPAR machines can log hypervisor preempt & dispatch events to a
> >> -	  kernel buffer. Saying Y here will enable logging these events,
> >> -	  which are accessible through a debugfs file.
> >> -
> >> -	  Say N if you are unsure.
> >
>=20

^ permalink raw reply

* Re: [PATCH] printk/of_serial: fix serial console cessation part way through boot.
From: Stephen Chivers @ 2014-05-13 22:04 UTC (permalink / raw)
  To: geert, jslaby, gregkh
  Cc: devicetree, linux-serial, linux-kernel, rob+dt, schivers,
	grant.likely, linuxppc-dev, cproctor

Commit 5f5c9ae56c38942623f69c3e6dc6ec78e4da2076
"serial_core: Unregister console in uart_remove_one_port()"
fixed a crash where a serial port was removed but
not deregistered as a console.

There is a side effect of that commit for platforms having serial consoles
and of_serial configured (CONFIG_SERIAL_OF_PLATFORM). The serial console
is disabled midway through the boot process.

This cessation of the serial console affects PowerPC computers
such as the MVME5100 and SAM440EP.

The sequence is:

	bootconsole [udbg0] enabled
	....
	serial8250/16550 driver initialises and registers its UARTS,
	one of these is the serial console.
	console [ttyS0] enabled
	....
	of_serial probes "platform" devices, registering them as it goes.
	One of these is the serial console.
	console [ttyS0] disabled.

The disabling of the serial console is due to:

	a.  unregister_console in printk not clearing the
	    CONS_ENABLED bit in the console flags,
	    even though it has announced that the console is disabled; and

	b.  of_platform_serial_probe in of_serial not setting the port type
	    before it registers with serial8250_register_8250_port.

This patch ensures that the serial console is re-enabled when of_serial
registers a serial port that corresponds to the designated console.

Signed-off-by: Stephen Chivers <schivers@csc.com>
Tested-by: Stephen Chivers <schivers@csc.com>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org> [unregister_console]

===
The above failure was identified in Linux-3.15-rc2.

Tested using MVME5100 and SAM440EP PowerPC computers with
kernels built from Linux-3.15-rc5 and tty-next.

The continued operation of the serial console is vital for computers
such as the MVME5100 as that Single Board Computer does not
have any grapical/display hardware.

---
 drivers/tty/serial/of_serial.c |    1 +
 kernel/printk/printk.c         |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c
index 9924660..27981e2 100644
--- a/drivers/tty/serial/of_serial.c
+++ b/drivers/tty/serial/of_serial.c
@@ -173,6 +173,7 @@ static int of_platform_serial_probe(struct platform_device *ofdev)
 	{
 		struct uart_8250_port port8250;
 		memset(&port8250, 0, sizeof(port8250));
+		port.type = port_type;
 		port8250.port = port;
 
 		if (port.fifosize)
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 7228258..221229c 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -2413,6 +2413,7 @@ int unregister_console(struct console *console)
 	if (console_drivers != NULL && console->flags & CON_CONSDEV)
 		console_drivers->flags |= CON_CONSDEV;
 
+	console->flags &= ~CON_ENABLED;
 	console_unlock();
 	console_sysfs_notify();
 	return res;

^ permalink raw reply related

* Re: [PATCH] [resend] net: get rid of SET_ETHTOOL_OPS
From: David Miller @ 2014-05-13 21:43 UTC (permalink / raw)
  To: w-lkml
  Cc: devel, linux-s390, b.a.t.m.a.n, trivial, xen-devel, linux-rdma,
	netdev, linux-usb, linux-wireless, linux-kernel, virtualization,
	e1000-devel, bridge, devel, nios2-dev, dev, linuxppc-dev,
	linux-acenic
In-Reply-To: <20140511001231.GC7875@kaos.lebenslange-mailadresse.de>

From: Wilfried Klaebe <w-lkml@lebenslange-mailadresse.de>
Date: Sun, 11 May 2014 00:12:32 +0000

> net: get rid of SET_ETHTOOL_OPS
> 
> Dave Miller mentioned he'd like to see SET_ETHTOOL_OPS gone.
> This does that.
> 
> Mostly done via coccinelle script:
> @@
> struct ethtool_ops *ops;
> struct net_device *dev;
> @@
> -       SET_ETHTOOL_OPS(dev, ops);
> +       dev->ethtool_ops = ops;
> 
> Compile tested only, but I'd seriously wonder if this broke anything.
> 
> Suggested-by: Dave Miller <davem@davemloft.net>
> Signed-off-by: Wilfried Klaebe <w-lkml@lebenslange-mailadresse.de>

Applied to net-next, thanks.

^ permalink raw reply

* Re: powerpc/ppc64: Allow allmodconfig to build (finally !)
From: Guenter Roeck @ 2014-05-13 19:41 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <1399972601.17624.169.camel@pasglop>

On Tue, May 13, 2014 at 07:16:41PM +1000, Benjamin Herrenschmidt wrote:
> On Mon, 2014-05-12 at 17:28 -0700, Guenter Roeck wrote:
> 
> > After applying this patch, I get
> > 
> > arch/powerpc/kernel/exceptions-64s.S:269: Error: operand out of range
> > (0x000000000000814c is not between 0xffffffffffff8000 and 0x0000000000007ffc)
> > arch/powerpc/kernel/exceptions-64s.S:729: Error: operand out of range
> > (0x000000000000814c is not between 0xffffffffffff8000 and 0x0000000000007ffc)
> > 
> > with powerpc:defconfig, powerpc:allmodconfig, powerpc:cell_defconfig, and
> > powerpc:maple_defconfig.
> > 
> > This is on top of v3.15-rc5. Any idea what is going on ?
> > 
> > Compiler is powerpc64-poky-linux-gcc (GCC) 4.7.2 (from poky 1.4.0-1).
> 
> Interesting... works with all my test configs using 4.7.3...
> 
> I don't have my tree at hand right now, I'll check what that means
> tomorrow see if I can find a workaround.
> 

Drives me crazy. With gcc 4.8.2, powerpc:allmodconfig builds, but now I get
failures with ppc64e_defconfig and chroma_defconfig:

arch/powerpc/kernel/built-in.o: In function `exc_debug_crit_book3e':
(.text+0x165ee): relocation truncated to fit: R_PPC64_ADDR16_HI against symbol
`interrupt_base_book3e' defined in .text section in
arch/powerpc/kernel/built-in.o
arch/powerpc/kernel/built-in.o: In function `exc_debug_crit_book3e':
(.text+0x16602): relocation truncated to fit: R_PPC64_ADDR16_HI against symbol
`interrupt_end_book3e' defined in .text section in
arch/powerpc/kernel/built-in.o
arch/powerpc/kernel/built-in.o: In function `exc_debug_debug_book3e':
(.text+0x1679e): relocation truncated to fit: R_PPC64_ADDR16_HI against symbol
`interrupt_base_book3e' defined in .text section in
arch/powerpc/kernel/built-in.o
arch/powerpc/kernel/built-in.o: In function `exc_debug_debug_book3e':
(.text+0x167b2): relocation truncated to fit: R_PPC64_ADDR16_HI against symbol
`interrupt_end_book3e' defined in .text section in
arch/powerpc/kernel/built-in.o
arch/powerpc/kernel/built-in.o: In function `skpinv':
arch/powerpc/kernel/exceptions-64e.o:(.text+0x178c6): relocation truncated to
fit: R_PPC64_ADDR16_HI against `.text'+178e0
arch/powerpc/kernel/built-in.o: In function `a2_tlbinit_after_linear_map':
(.text+0x17966): relocation truncated to fit: R_PPC64_ADDR16_HI against
`.text'+17974
arch/powerpc/kernel/built-in.o: In function `.init_core_book3e':
arch/powerpc/kernel/exceptions-64e.o:(.text+0x17a7e): relocation truncated to
fit: R_PPC64_ADDR16_HI against symbol `interrupt_base_book3e' defined in .text
section in arch/powerpc/kernel/built-in.o

Worse, that happens even without your patch applied, and the patch does not
make a difference :-(.

Guenter

^ permalink raw reply

* Re: [PATCH V2 2/3] powerpc, ptrace: Enable support for transactional memory register sets
From: Pedro Alves @ 2014-05-13 17:21 UTC (permalink / raw)
  To: Anshuman Khandual, linuxppc-dev, linux-kernel
  Cc: michael, mikey, Roland McGrath, avagin, oleg
In-Reply-To: <1399276469-13541-3-git-send-email-khandual@linux.vnet.ibm.com>

I wonder whether people are getting Roland's address from?

It's frequent that ptrace related patches end up CCed to
roland@redhat.com, but, he's not been at Red Hat for a few years
now.  Roland, do you still want to be CCed on ptrace-related
issues?  If so, there's probably a script somewhere in the
kernel that needs updating.  If not, well, it'd be good
if it were updated anyway.  :-)

It's a little annoying, as Red Hat's servers outright reject
email sent from a @redhat.com address if one tries to send
an email that includes a CC/FROM to a user that no longer
exists in the @redhat.com domain.

-- 
Pedro Alves

On 05/05/14 08:54, Anshuman Khandual wrote:
> This patch enables get and set of transactional memory related register
> sets through PTRACE_GETREGSET/PTRACE_SETREGSET interface by implementing
> four new powerpc specific register sets i.e REGSET_TM_SPR, REGSET_TM_CGPR,
> REGSET_TM_CFPR, REGSET_CVMX support corresponding to these following new
> ELF core note types added previously in this regard.
> 
> 	(1) NT_PPC_TM_SPR
> 	(2) NT_PPC_TM_CGPR
> 	(3) NT_PPC_TM_CFPR
> 	(4) NT_PPC_TM_CVMX
> 
> Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
> ---
>  arch/powerpc/include/asm/switch_to.h |   8 +
>  arch/powerpc/kernel/process.c        |  24 ++
>  arch/powerpc/kernel/ptrace.c         | 683 +++++++++++++++++++++++++++++++++--
>  3 files changed, 687 insertions(+), 28 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h
> index 0e83e7d..2737f46 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_tmregs_to_thread(struct task_struct *);
> +#else
> +static inline void flush_tmregs_to_thread(struct task_struct *t)
> +{
> +}
> +#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
> +
>  static inline void clear_task_ebb(struct task_struct *t)
>  {
>  #ifdef CONFIG_PPC_BOOK3S_64
> diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
> index 31d0215..e247898 100644
> --- a/arch/powerpc/kernel/process.c
> +++ b/arch/powerpc/kernel/process.c
> @@ -695,6 +695,30 @@ static inline void __switch_to_tm(struct task_struct *prev)
>  	}
>  }
>  
> +void flush_tmregs_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..92faded 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" holds the last checkpointed FPR registers state for the
> + * current 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_tmregs_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_tmregs_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" holds the last checkpointed value of VMX registers for the
> + * current 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_tmregs_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_tmregs_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,347 @@ static int evr_set(struct task_struct *target, const struct user_regset *regset,
>  }
>  #endif /* CONFIG_SPE */
>  
> +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> +
> +/*
> + *  Transactional memory 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_tmregs_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_tmregs_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;
> +}
> +
> +/*
> + * TM 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_tmregs_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_tmregs_to_thread(target);
> +	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> +					&target->thread.ckpt_regs, 0,
> +						sizeof(struct pt_regs));
> +	return ret;
> +}
> +
> +/*
> + * TM 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_tmregs_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_tmregs_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
> +}
> +
> +/*
> + * TM 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_tmregs_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_tmregs_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 */
>  
>  /*
>   * These are our native regset flavors.
> @@ -629,6 +1068,12 @@ enum powerpc_regset {
>  #ifdef CONFIG_SPE
>  	REGSET_SPE,
>  #endif
> +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> +	REGSET_TM_SPR,		/* TM specific SPR */
> +	REGSET_TM_CGPR,		/* TM checkpointed GPR */
> +	REGSET_TM_CFPR,		/* TM checkpointed FPR */
> +	REGSET_TM_CVMX,		/* TM checkpointed VMX */
> +#endif
>  };
>  
>  static const struct user_regset native_regsets[] = {
> @@ -663,6 +1108,28 @@ 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 = ELF_NGREG,
> +		.size = sizeof(long), .align = sizeof(long),
> +		.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
>  };
>  
>  static const struct user_regset_view user_ppc_native_view = {
> @@ -803,6 +1270,145 @@ static int gpr32_set(struct task_struct *target,
>  					 (PT_TRAP + 1) * sizeof(reg), -1);
>  }
>  
> +static int tm_cgpr32_get(struct task_struct *target,
> +		     const struct user_regset *regset,
> +		     unsigned int pos, unsigned int count,
> +		     void *kbuf, void __user *ubuf)
> +{
> +	const unsigned long *regs = &target->thread.ckpt_regs.gpr[0];
> +	compat_ulong_t *k = kbuf;
> +	compat_ulong_t __user *u = ubuf;
> +	compat_ulong_t reg;
> +	int i;
> +
> +	flush_fp_to_thread(target);
> +	flush_altivec_to_thread(target);
> +	flush_tmregs_to_thread(target);
> +
> +	if (target->thread.regs == NULL)
> +		return -EIO;
> +
> +	if (!FULL_REGS(target->thread.regs)) {
> +		/* We have a partial register set.  Fill 14-31 with bogus values */
> +		for (i = 14; i < 32; i++)
> +			target->thread.regs->gpr[i] = NV_REG_POISON; 
> +	}
> +
> +	pos /= sizeof(reg);
> +	count /= sizeof(reg);
> +
> +	if (kbuf)
> +		for (; count > 0 && pos < PT_MSR; --count)
> +			*k++ = regs[pos++];
> +	else
> +		for (; count > 0 && pos < PT_MSR; --count)
> +			if (__put_user((compat_ulong_t) regs[pos++], u++))
> +				return -EFAULT;
> +
> +	if (count > 0 && pos == PT_MSR) {
> +		reg = get_user_msr(target);
> +		if (kbuf)
> +			*k++ = reg;
> +		else if (__put_user(reg, u++))
> +			return -EFAULT;
> +		++pos;
> +		--count;
> +	}
> +
> +	if (kbuf)
> +		for (; count > 0 && pos < PT_REGS_COUNT; --count)
> +			*k++ = regs[pos++];
> +	else
> +		for (; count > 0 && pos < PT_REGS_COUNT; --count)
> +			if (__put_user((compat_ulong_t) regs[pos++], u++))
> +				return -EFAULT;
> +
> +	kbuf = k;
> +	ubuf = u;
> +	pos *= sizeof(reg);
> +	count *= sizeof(reg);
> +	return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
> +					PT_REGS_COUNT * sizeof(reg), -1);
> +}
> +
> +static int tm_cgpr32_set(struct task_struct *target,
> +		     const struct user_regset *regset,
> +		     unsigned int pos, unsigned int count,
> +		     const void *kbuf, const void __user *ubuf)
> +{
> +	unsigned long *regs = &target->thread.ckpt_regs.gpr[0];
> +	const compat_ulong_t *k = kbuf;
> +	const compat_ulong_t __user *u = ubuf;
> +	compat_ulong_t reg;
> +
> +	flush_fp_to_thread(target);
> +	flush_altivec_to_thread(target);
> +	flush_tmregs_to_thread(target);
> +
> +	if (target->thread.regs == NULL)
> +		return -EIO;
> +
> +	CHECK_FULL_REGS(target->thread.regs);
> +
> +	pos /= sizeof(reg);
> +	count /= sizeof(reg);
> +
> +	if (kbuf)
> +		for (; count > 0 && pos < PT_MSR; --count)
> +			regs[pos++] = *k++;
> +	else
> +		for (; count > 0 && pos < PT_MSR; --count) {
> +			if (__get_user(reg, u++))
> +				return -EFAULT;
> +			regs[pos++] = reg;
> +		}
> +
> +
> +	if (count > 0 && pos == PT_MSR) {
> +		if (kbuf)
> +			reg = *k++;
> +		else if (__get_user(reg, u++))
> +			return -EFAULT;
> +		set_user_msr(target, reg);
> +		++pos;
> +		--count;
> +	}
> +
> +	if (kbuf) {
> +		for (; count > 0 && pos <= PT_MAX_PUT_REG; --count)
> +			regs[pos++] = *k++;
> +		for (; count > 0 && pos < PT_TRAP; --count, ++pos)
> +			++k;
> +	} else {
> +		for (; count > 0 && pos <= PT_MAX_PUT_REG; --count) {
> +			if (__get_user(reg, u++))
> +				return -EFAULT;
> +			regs[pos++] = reg;
> +		}
> +		for (; count > 0 && pos < PT_TRAP; --count, ++pos)
> +			if (__get_user(reg, u++))
> +				return -EFAULT;
> +	}
> +
> +	if (count > 0 && pos == PT_TRAP) {
> +		if (kbuf)
> +			reg = *k++;
> +		else if (__get_user(reg, u++))
> +			return -EFAULT;
> +		set_user_trap(target, reg);
> +		++pos;
> +		--count;
> +	}
> +
> +	kbuf = k;
> +	ubuf = u;
> +	pos *= sizeof(reg);
> +	count *= sizeof(reg);
> +	return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
> +					 (PT_TRAP + 1) * sizeof(reg), -1);
> +}
> +
> +
>  /*
>   * These are the regset flavors matching the CONFIG_PPC32 native set.
>   */
> @@ -831,6 +1437,28 @@ 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 = ELF_NGREG,
> +		.size = sizeof(long), .align = sizeof(long),
> +		.get = tm_cgpr32_get, .set = tm_cgpr32_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
>  };
>  
>  static const struct user_regset_view user_ppc_compat_view = {
> @@ -1754,7 +2382,6 @@ long arch_ptrace(struct task_struct *child, long request,
>  					     REGSET_SPE, 0, 35 * sizeof(u32),
>  					     datavp);
>  #endif
> -
>  	default:
>  		ret = ptrace_request(child, request, addr, data);
>  		break;
> 

^ permalink raw reply

* Re: powerpc/ppc64: Allow allmodconfig to build (finally !)
From: Guenter Roeck @ 2014-05-13 17:17 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <1399972601.17624.169.camel@pasglop>

On Tue, May 13, 2014 at 07:16:41PM +1000, Benjamin Herrenschmidt wrote:
> On Mon, 2014-05-12 at 17:28 -0700, Guenter Roeck wrote:
> 
> > After applying this patch, I get
> > 
> > arch/powerpc/kernel/exceptions-64s.S:269: Error: operand out of range
> > (0x000000000000814c is not between 0xffffffffffff8000 and 0x0000000000007ffc)
> > arch/powerpc/kernel/exceptions-64s.S:729: Error: operand out of range
> > (0x000000000000814c is not between 0xffffffffffff8000 and 0x0000000000007ffc)
> > 
> > with powerpc:defconfig, powerpc:allmodconfig, powerpc:cell_defconfig, and
> > powerpc:maple_defconfig.
> > 
> > This is on top of v3.15-rc5. Any idea what is going on ?
> > 
> > Compiler is powerpc64-poky-linux-gcc (GCC) 4.7.2 (from poky 1.4.0-1).
> 
> Interesting... works with all my test configs using 4.7.3...
> 
> I don't have my tree at hand right now, I'll check what that means
> tomorrow see if I can find a workaround.
> 
It works for me with gcc 4.8.2 (build from yocto 1.6.0).

Is asking people to use gcc 4.7.3 or later acceptable ?

Guenter

^ permalink raw reply

* Re: [PATCH V2 2/3] powerpc, ptrace: Enable support for transactional memory register sets
From: Pedro Alves @ 2014-05-13 17:13 UTC (permalink / raw)
  To: Anshuman Khandual, linuxppc-dev, linux-kernel
  Cc: michael, mikey, avagin, oleg
In-Reply-To: <1399276469-13541-3-git-send-email-khandual@linux.vnet.ibm.com>

On 05/05/14 08:54, Anshuman Khandual wrote:
> This patch enables get and set of transactional memory related register
> sets through PTRACE_GETREGSET/PTRACE_SETREGSET interface by implementing
> four new powerpc specific register sets i.e REGSET_TM_SPR, REGSET_TM_CGPR,
> REGSET_TM_CFPR, REGSET_CVMX support corresponding to these following new
> ELF core note types added previously in this regard.
> 
> 	(1) NT_PPC_TM_SPR
> 	(2) NT_PPC_TM_CGPR
> 	(3) NT_PPC_TM_CFPR
> 	(4) NT_PPC_TM_CVMX

Sorry that I couldn't tell this from the code, but, what does the
kernel return when the ptracer requests these registers and the
program is not in a transaction?  Specifically I'm wondering whether
this follows the same semantics as the s390 port.

-- 
Pedro Alves

^ permalink raw reply

* Re: [PATCH 1/1] powerpc/perf: Adjust callchain based on DWARF debug info
From: Sukadev Bhattiprolu @ 2014-05-13 16:49 UTC (permalink / raw)
  To: Maynard Johnson
  Cc: maynardj, Michael Ellerman, Anton Blanchard, linux-kernel,
	Ulrich.Weigand, Arnaldo Carvalho de Melo, linuxppc-dev
In-Reply-To: <OF1EBFFD42.19D89CD2-ON86257CD7.00591CE2-86257CD7.00594B52@us.ibm.com>

Maynard Johnson [mpjohn@us.ibm.com] wrote:
| > [PATCH 1/1] powerpc/perf: Adjust callchain based on DWARF debug info
| 
| Acked-by: Maynard Johnson <maynardj@us.ibm.com>
| 
| Reviewed and tested.  Thanks, Suka.

Thanks Maynard.  This updated patch also fixes whitespace damage.

From: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Date: Fri, 9 May 2014 19:00:35 -0500
Subject: [PATCH 1/1] powerpc/perf: Adjust callchain based on DWARF debug info

When saving the callchain on Power, the kernel conservatively saves excess
entries in the callchain. A few of these entries are needed in some cases
but not others. We should use the DWARF debug information to determine
when the entries are  needed.

Eg: the value in the link register (LR) is needed only when it holds the
return address of a function. At other times it must be ignored.

If the unnecessary entries are not ignored, we end up with duplicate arcs
in the call-graphs.

Use the DWARF debug information to determine if any callchain entries
should be ignored when building call-graphs.

Callgraph before the patch:

    14.67%          2234  sprintft  libc-2.18.so       [.] __random
            |
            --- __random
               |
               |--61.12%-- __random
               |          |
               |          |--97.15%-- rand
               |          |          do_my_sprintf
               |          |          main
               |          |          generic_start_main.isra.0
               |          |          __libc_start_main
               |          |          0x0
               |          |
               |           --2.85%-- do_my_sprintf
               |                     main
               |                     generic_start_main.isra.0
               |                     __libc_start_main
               |                     0x0
               |
                --38.88%-- rand
                          |
                          |--94.01%-- rand
                          |          do_my_sprintf
                          |          main
                          |          generic_start_main.isra.0
                          |          __libc_start_main
                          |          0x0
                          |
                           --5.99%-- do_my_sprintf
                                     main
                                     generic_start_main.isra.0
                                     __libc_start_main
                                     0x0

Callgraph after the patch:

    14.67%          2234  sprintft  libc-2.18.so       [.] __random
            |
            --- __random
               |
               |--95.93%-- rand
               |          do_my_sprintf
               |          main
               |          generic_start_main.isra.0
               |          __libc_start_main
               |          0x0
               |
                --4.07%-- do_my_sprintf
                          main
                          generic_start_main.isra.0
                          __libc_start_main
                          0x0

TODO:	For split-debug info objects like glibc, we can only determine
	the call-frame-address only when both .eh_frame and .debug_info
	sections are available. We should be able to determin the CFA
	even without the .eh_frame section.

Fix suggested by Anton Blanchard.

Thanks to valuable input on DWARF debug information from Ulrich Weigand.

Reported-by: Maynard Johnson <maynard@us.ibm.com>
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Tested-by: Maynard Johnson <maynardj@us.ibm.com>
Acked-by: Maynard Johnson <maynardj@us.ibm.com>
---
 tools/perf/arch/powerpc/Makefile                |   1 +
 tools/perf/arch/powerpc/util/adjust-callchain.c | 276 ++++++++++++++++++++++++
 tools/perf/config/Makefile                      |   5 +
 tools/perf/util/callchain.h                     |  12 ++
 tools/perf/util/machine.c                       |  16 +-
 5 files changed, 308 insertions(+), 2 deletions(-)
 create mode 100644 tools/perf/arch/powerpc/util/adjust-callchain.c

diff --git a/tools/perf/arch/powerpc/Makefile b/tools/perf/arch/powerpc/Makefile
index 744e629..512cc8d 100644
--- a/tools/perf/arch/powerpc/Makefile
+++ b/tools/perf/arch/powerpc/Makefile
@@ -3,3 +3,4 @@ PERF_HAVE_DWARF_REGS := 1
 LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
 endif
 LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/header.o
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/adjust-callchain.o
diff --git a/tools/perf/arch/powerpc/util/adjust-callchain.c b/tools/perf/arch/powerpc/util/adjust-callchain.c
new file mode 100644
index 0000000..0689dd8
--- /dev/null
+++ b/tools/perf/arch/powerpc/util/adjust-callchain.c
@@ -0,0 +1,276 @@
+/*
+ * Use DWARF Debug information to skip unnecessary callchain entries.
+ *
+ * Copyright (C) 2014 Sukadev Bhattiprolu, IBM Corporation.
+ * Copyright (C) 2014 Ulrich Weigand, IBM Corporation.
+ *
+ * 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 <inttypes.h>
+#include <dwarf.h>
+#include <elfutils/libdwfl.h>
+
+#include "util/thread.h"
+#include "util/callchain.h"
+
+/*
+ * When saving the callchain on Power, the kernel conservatively saves
+ * excess entries in the callchain. A few of these entries are needed
+ * in some cases but not others. If the unnecessary entries are not
+ * ignored, we end up with duplicate arcs in the call-graphs. Use
+ * DWARF debug information to skip over any unnecessary callchain
+ * entries.
+ *
+ * See function header for arch_adjust_callchain() below for more details.
+ *
+ * The libdwfl code in this file is based on code from elfutils
+ * (libdwfl/argp-std.c, libdwfl/tests/addrcfi.c, etc).
+ */
+static char *debuginfo_path;
+
+static const Dwfl_Callbacks offline_callbacks = {
+	.debuginfo_path = &debuginfo_path,
+	.find_debuginfo = dwfl_standard_find_debuginfo,
+	.section_address = dwfl_offline_section_address,
+};
+
+
+/*
+ * Use the DWARF expression for the Call-frame-address and determine
+ * if return address is in LR and if a new frame was allocated.
+ */
+static int check_return_reg(int ra_regno, Dwarf_Frame *frame)
+{
+	Dwarf_Op ops_mem[2];
+	Dwarf_Op dummy;
+	Dwarf_Op *ops = &dummy;
+	size_t nops;
+	int result;
+
+	result = dwarf_frame_register(frame, ra_regno, ops_mem, &ops, &nops);
+	if (result < 0) {
+		pr_debug("dwarf_frame_register() %s\n", dwarf_errmsg(-1));
+		return -1;
+	}
+
+	/*
+	 * Check if return address is on the stack.
+	 */
+	if (nops != 0 || ops != NULL)
+		return 0;
+
+	/*
+	 * Return address is in LR. Check if a frame was allocated
+	 * but not-yet used.
+	 */
+	result = dwarf_frame_cfa(frame, &ops, &nops);
+	if (result < 0) {
+		pr_debug("dwarf_frame_cfa() returns %d, %s\n", result,
+					dwarf_errmsg(-1));
+		return -1;
+	}
+
+	/*
+	 * If call frame address is in r1, no new frame was allocated.
+	 */
+	if (nops == 1 && ops[0].atom == DW_OP_bregx && ops[0].number == 1 &&
+				ops[0].number2 == 0)
+		return 1;
+
+	/*
+	 * A new frame was allocated but has not yet been used.
+	 */
+	return 2;
+}
+
+/*
+ * Get the DWARF frame from the .eh_frame section.
+ */
+static Dwarf_Frame *get_eh_frame(Dwfl_Module *mod, Dwarf_Addr pc)
+{
+	int		result;
+	Dwarf_Addr	bias;
+	Dwarf_CFI	*cfi;
+	Dwarf_Frame	*frame;
+
+	cfi = dwfl_module_eh_cfi(mod, &bias);
+	if (!cfi) {
+		pr_debug("%s(): no CFI - %s\n", __func__, dwfl_errmsg(-1));
+		return NULL;
+	}
+
+	result = dwarf_cfi_addrframe(cfi, pc, &frame);
+	if (result) {
+		pr_debug("%s(): %s\n", __func__, dwfl_errmsg(-1));
+		return NULL;
+	}
+
+	return frame;
+}
+
+/*
+ * Get the DWARF frame from the .debug_frame section.
+ */
+static Dwarf_Frame *get_dwarf_frame(Dwfl_Module *mod, Dwarf_Addr pc)
+{
+	Dwarf_CFI       *cfi;
+	Dwarf_Addr      bias;
+	Dwarf_Frame     *frame;
+	int             result;
+
+	cfi = dwfl_module_dwarf_cfi(mod, &bias);
+	if (!cfi) {
+		pr_debug("%s(): no CFI - %s\n", __func__, dwfl_errmsg(-1));
+		return NULL;
+	}
+
+	result = dwarf_cfi_addrframe(cfi, pc, &frame);
+	if (result) {
+		printf("%s(): %s\n", __func__, dwfl_errmsg(-1));
+		return NULL;
+	}
+
+	return frame;
+}
+
+/*
+ * Return:
+ *	0 if return address for the program counter @pc is on stack
+ *	1 if return address is in LR and no new stack frame was allocated
+ *	2 if return address is in LR and a new frame was allocated (but not
+ *		yet used)
+ *	-1 in case of errors
+ */
+static int check_return_addr(const char *exec_file, Dwarf_Addr pc)
+{
+	Dwfl		*dwfl;
+	Dwfl_Module	*mod;
+	Dwarf_Frame	*frame;
+	int		ra_regno;
+	Dwarf_Addr	start = pc;
+	Dwarf_Addr	end = pc;
+	bool		signalp;
+
+	dwfl = dwfl_begin(&offline_callbacks);
+	if (!dwfl) {
+		pr_debug("dwfl_begin() failed: %s\n", dwarf_errmsg(-1));
+		return -1;
+	}
+
+	if (dwfl_report_offline(dwfl, "",  exec_file, -1) == NULL) {
+		pr_debug("dwfl_report_offline() failed %s\n", dwarf_errmsg(-1));
+		return -1;
+	}
+
+	mod = dwfl_addrmodule(dwfl, pc);
+	if (!mod) {
+		pr_debug("dwfl_addrmodule() failed, %s\n", dwarf_errmsg(-1));
+		return -1;
+	}
+
+	/*
+	 * To work with split debug info files (eg: glibc), check both
+	 * .eh_frame and .debug_frame sections of the ELF header.
+	 */
+	frame = get_eh_frame(mod, pc);
+	if (!frame) {
+		frame = get_dwarf_frame(mod, pc);
+		if (!frame)
+			return -1;
+	}
+
+	ra_regno = dwarf_frame_info(frame, &start, &end, &signalp);
+	if (ra_regno < 0) {
+		pr_debug("Return address register unavailable: %s\n",
+				dwarf_errmsg(-1));
+		return -1;
+	}
+
+	return check_return_reg(ra_regno, frame);
+}
+
+/*
+ * The callchain saved by the kernel always includes the link register (LR).
+ *
+ *	0:	PERF_CONTEXT_USER
+ *	1:	Program counter (Next instruction pointer)
+ *	2:	LR value
+ *	3:	Caller's caller
+ *	4:	...
+ *
+ * The value in LR is only needed when it holds a return address. If the
+ * return address is on the stack, we should ignore the LR value.
+ *
+ * Further, when the return address is in the LR, if a new frame was just
+ * allocated but the LR was not saved into it, then the LR contains the
+ * caller, slot 4: contains the caller's caller and the contents of slot 3:
+ * (chain->ips[3]) is undefined and must be ignored.
+ *
+ * Use DWARF debug information to determine if any entries need to be skipped.
+ *
+ * Return:
+ *	index:	of callchain entry that needs to be ignored (if any)
+ *	-1	if no entry needs to be ignored or in case of errors
+ *
+ * TODO:
+ *	Rather than returning an index into the callchain and have the
+ *	caller skip that entry, we could modify the callchain in-place
+ *	by putting a PERF_CONTEXT_IGNORE marker in the affected entry.
+ *
+ *	But @chain points to read-only mmap, so the caller needs to
+ *	duplicate the callchain to modify in-place - something like:
+ *
+ *		new_callchain = arch_duplicate_callchain()
+ *		arch_adjust_callchain(new_callchain)
+ *		arch_free_callchain(new_callchain)
+ *
+ *	Since we only expect to adjust <= 1 entry for now, just return
+ *	the index.
+ */
+int arch_adjust_callchain(struct machine *machine, struct thread *thread,
+				struct ip_callchain *chain)
+{
+	struct addr_location al;
+	struct dso *dso = NULL;
+	int rc;
+	u64 ip;
+	u64 skip_slot = -1;
+
+	if (chain->nr < 3)
+		return skip_slot;
+
+	ip = chain->ips[2];
+
+	thread__find_addr_location(thread, machine, PERF_RECORD_MISC_USER,
+			MAP__FUNCTION, ip, &al);
+
+	if (al.map)
+		dso = al.map->dso;
+
+	if (!dso) {
+		pr_debug("%" PRIx64 " dso is NULL\n", ip);
+		return skip_slot;
+	}
+
+	rc = check_return_addr(dso->long_name, ip);
+
+	pr_debug("DSO %s, nr %" PRIx64 ", ip 0x%" PRIx64 "rc %d\n",
+				dso->long_name, chain->nr, ip, rc);
+
+	if (rc == 0) {
+		/*
+		 * Return address on stack. Ignore LR value in callchain
+		 */
+		skip_slot = 2;
+	} else if (rc == 2) {
+		/*
+		 * New frame allocated but return address still in LR.
+		 * Ignore the caller's caller entry in callchain.
+		 */
+		skip_slot = 3;
+	}
+	return skip_slot;
+}
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 5a3c452..7e93877 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -29,11 +29,16 @@ ifeq ($(ARCH),x86)
   endif
   NO_PERF_REGS := 0
 endif
+
 ifeq ($(ARCH),arm)
   NO_PERF_REGS := 0
   LIBUNWIND_LIBS = -lunwind -lunwind-arm
 endif
 
+ifeq ($(ARCH),powerpc)
+  CFLAGS += -DHAVE_ADJUST_CALLCHAIN
+endif
+
 ifeq ($(LIBUNWIND_LIBS),)
   NO_LIBUNWIND := 1
 else
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 8ad97e9..81ecb90 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -157,4 +157,16 @@ int sample__resolve_callchain(struct perf_sample *sample, struct symbol **parent
 int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample);
 
 extern const char record_callchain_help[];
+
+#ifdef HAVE_ADJUST_CALLCHAIN
+extern int arch_adjust_callchain(struct machine *machine,
+			struct thread *thread, struct ip_callchain *chain);
+#else
+static inline int arch_adjust_callchain(struct machine *machine,
+			struct thread *thread, struct ip_callchain *chain)
+{
+	return -1;
+}
+#endif
+
 #endif	/* __PERF_CALLCHAIN_H */
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index a53cd0b..dce3bf0 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1271,6 +1271,7 @@ static int machine__resolve_callchain_sample(struct machine *machine,
 	int chain_nr = min(max_stack, (int)chain->nr);
 	int i;
 	int err;
+	int skip_slot;
 
 	callchain_cursor_reset(&callchain_cursor);
 
@@ -1279,14 +1280,25 @@ static int machine__resolve_callchain_sample(struct machine *machine,
 		return 0;
 	}
 
+	/*
+	 * Based on DWARF debug information, some architectures skip
+	 * some of the callchain entries saved by the kernel.
+	 */
+	skip_slot = arch_adjust_callchain(machine, thread, chain);
+
 	for (i = 0; i < chain_nr; i++) {
 		u64 ip;
 		struct addr_location al;
 
-		if (callchain_param.order == ORDER_CALLEE)
+		if (callchain_param.order == ORDER_CALLEE) {
+			if (i == skip_slot)
+				continue;
 			ip = chain->ips[i];
-		else
+		} else {
+			if ((int)(chain->nr - i - 1) == skip_slot)
+				continue;
 			ip = chain->ips[chain->nr - i - 1];
+		}
 
 		if (ip >= PERF_CONTEXT_MAX) {
 			switch (ip) {
-- 
1.8.4.2

^ permalink raw reply related

* Re: [PATCH 1/1] powerpc/perf: Adjust callchain based on DWARF debug info
From: Maynard Johnson @ 2014-05-13 16:15 UTC (permalink / raw)
  To: Sukadev Bhattiprolu
  Cc: maynardj, Michael Ellerman, Anton Blanchard, linux-kernel,
	Ulrich.Weigand, Arnaldo Carvalho de Melo, linuxppc-dev
In-Reply-To: <20140510024638.GA27540@us.ibm.com>

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

Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com> wrote on 05/09/2014
09:46:38 PM:

> From: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
> To: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>,
> Cc: linux-kernel@vger.kernel.org, Anton Blanchard
> <anton@au1.ibm.com>, Ulrich.Weigand@de.ibm.com, Michael Ellerman
> <michaele@au1.ibm.com>, Maynard Johnson/Rochester/IBM@IBMUS,
> linuxppc-dev@lists.ozlabs.org
> Date: 05/09/2014 09:46 PM
> Subject: [PATCH 1/1] powerpc/perf: Adjust callchain based on DWARF debug
info
>
> [PATCH 1/1] powerpc/perf: Adjust callchain based on DWARF debug info

Acked-by: Maynard Johnson <maynardj@us.ibm.com>

Reviewed and tested.  Thanks, Suka.

-Maynard

>
> When saving the callchain on Power, the kernel conservatively saves
excess
> entries in the callchain. A few of these entries are needed in some cases
> but not others.
>
> Eg: the value in the link register (LR) is needed only when it holds the
> return address of a function. At other times it must be ignored.
>
> If the unnecessary entries are not ignored, we end up with duplicate arcs
> in the call-graphs.
>
> Use DWARF debug information to ignore the unnecessary entries.
>
> Callgraph before the patch:
>
>     14.67%          2234  sprintft  libc-2.18.so       [.] __random
>             |
>             --- __random
>                |
>                |--61.12%-- __random
>                |          |
>                |          |--97.15%-- rand
>                |          |          do_my_sprintf
>                |          |          main
>                |          |          generic_start_main.isra.0
>                |          |          __libc_start_main
>                |          |          0x0
>                |          |
>                |           --2.85%-- do_my_sprintf
>                |                     main
>                |                     generic_start_main.isra.0
>                |                     __libc_start_main
>                |                     0x0
>                |
>                 --38.88%-- rand
>                           |
>                           |--94.01%-- rand
>                           |          do_my_sprintf
>                           |          main
>                           |          generic_start_main.isra.0
>                           |          __libc_start_main
>                           |          0x0
>                           |
>                            --5.99%-- do_my_sprintf
>                                      main
>                                      generic_start_main.isra.0
>                                      __libc_start_main
>                                      0x0
>
> Callgraph after the patch:
>
>     14.67%          2234  sprintft  libc-2.18.so       [.] __random
>             |
>             --- __random
>                |
>                |--95.93%-- rand
>                |          do_my_sprintf
>                |          main
>                |          generic_start_main.isra.0
>                |          __libc_start_main
>                |          0x0
>                |
>                 --4.07%-- do_my_sprintf
>                           main
>                           generic_start_main.isra.0
>                           __libc_start_main
>                           0x0
>
> TODO:   For split-debug info objects like glibc, we can only determine
>    the call-frame-address only when both .eh_frame and .debug_info
>    sections are available. We should be able to determin the CFA
>    even without the .eh_frame section.
>
> Thanks to Ulrich Weigand for help with DWARF debug information.
>
> Fix suggested by Anton Blanchard.
>
> Reported-by: Maynard Johnson <maynard@us.ibm.com>
> Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
> ---
>  tools/perf/arch/powerpc/Makefile                |   1 +
>  tools/perf/arch/powerpc/util/adjust-callchain.c | 278 +++++++++++++
> +++++++++++
>  tools/perf/config/Makefile                      |   5 +
>  tools/perf/util/callchain.h                     |  12 +
>  tools/perf/util/machine.c                       |  16 +-
>  5 files changed, 310 insertions(+), 2 deletions(-)
>  create mode 100644 tools/perf/arch/powerpc/util/adjust-callchain.c
>
[snip]

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

^ permalink raw reply

* Re: powerpc/ppc64: Allow allmodconfig to build (finally !)
From: Guenter Roeck @ 2014-05-13 12:35 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <1399972601.17624.169.camel@pasglop>

On 05/13/2014 02:16 AM, Benjamin Herrenschmidt wrote:
> On Mon, 2014-05-12 at 17:28 -0700, Guenter Roeck wrote:
>
>> After applying this patch, I get
>>
>> arch/powerpc/kernel/exceptions-64s.S:269: Error: operand out of range
>> (0x000000000000814c is not between 0xffffffffffff8000 and 0x0000000000007ffc)
>> arch/powerpc/kernel/exceptions-64s.S:729: Error: operand out of range
>> (0x000000000000814c is not between 0xffffffffffff8000 and 0x0000000000007ffc)
>>
>> with powerpc:defconfig, powerpc:allmodconfig, powerpc:cell_defconfig, and
>> powerpc:maple_defconfig.
>>
>> This is on top of v3.15-rc5. Any idea what is going on ?
>>
>> Compiler is powerpc64-poky-linux-gcc (GCC) 4.7.2 (from poky 1.4.0-1).
>
> Interesting... works with all my test configs using 4.7.3...
>
> I don't have my tree at hand right now, I'll check what that means
> tomorrow see if I can find a workaround.
>

Maybe something is wrong with my toolchain. I'll try to find a more recent one.

Guenter

^ permalink raw reply

* Boot problems with a PA6T board
From: Christian Zigotzky @ 2014-05-13 12:06 UTC (permalink / raw)
  To: Michael Ellerman, linuxppc-dev
In-Reply-To: <1399268891.4600.3.camel@concordia>

On 05.05.2014 07:48, Michael Ellerman wrote:
> On Sun, 2014-05-04 at 18:02 +0200, Christian Zigotzky wrote:
>> Hi All,
>>
>> The RC 1, 2, and 3 of the kernel 3.15 don't boot on my PA6T board with a
>> Radeon HD 6870 graphics card.
>>
>> Screenshot:
>> http://forum.hyperion-entertainment.biz/download/file.php?id=1060&mode=view
>>
>> The kernel 3.14 starts without any problems. Has anyone a tip for me,
>> please?
> The line that says "starting cpu hw idx 0... failed" looks a little worrying.
> Do you see that on 3.14 as well?
>
> Otherwise bisection is probably your best bet.
>
> cheers
Hi All,

I have found out which patch is responsible for the boot problems. It's 
patch 9000c17dc0f9c910267d2661225c9d33a227b27e. Link: 
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=9000c17dc0f9c910267d2661225c9d33a227b27e

Experimental protocol:

git checkout -f 01d8885785a60ae8f4c37b0ed75bdc96d0fc6a44; git clean -fdx 
(from 02/04/14) -> Kernel boots
git checkout -f f1553174a207f68a4ec19d436003097e0a4dc405; git clean -fdx 
(from 03/04/14) -> Kernel boots
git checkout -f d40326f4b9f9617cdfd30f83a2db57d47e9c5bac; git clean -fdx 
(from 04/04/14) -> Kernel boots
git checkout -f 930b440cd8256f3861bdb0a59d26efaadac7941a; git clean -fdx 
(from 05/04/14) -> doesn't boot (rtc error)
git checkout -f 2b3a8fd735f86ebeb2b9d061054003000c36b654; git clean -fdx 
(from 06/04/14) -> doesn't boot (rtc error)
git checkout -f 26c12d93348f0bda0756aff83f4867d9ae58a5a6; git clean -fdx 
(from 07/04/14) -> doesn't boot (rtc error)
git checkout -f a6c8aff022d4d06e4b41455ae9b2a5d3d503bf76; git clean -fdx 
(from 08/04/14) -> Kernel boots
git checkout -f 035328c202d26a824b8632fd3b00635db5aee5a2; git clean -fdx 
(from 08/04/14) -> Kernel boots
git checkout -f 9000c17dc0f9c910267d2661225c9d33a227b27e; git clean -fdx 
(from 08/04/14) powerpc/powernv: Fix endian issues with sensor code
One OPAL call and one device tree property needed byte swapping. -> 
doesn't boot (prom_init)
git checkout -f d3d35d957a9d0733dc51f14b5abc0bff5d3c5f3a; git clean -fdx 
(from 08/04/14) -> doesn't boot (prom_init)
git checkout -f c4586256f0c440bc2bdb29d2cbb915f0ca785d26; git clean -fdx 
(from 09/04/14) -> doesn't boot (prom_init)

I'm not a programmer but what can I do to solve this boot problem?

Cheers,

Christian

^ permalink raw reply

* Re: [PATCH] pci-scan: Fix setting the limit
From: Alexey Kardashevskiy @ 2014-05-13 11:16 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Paul Mackerras, Thomas Huth, Nikunj A Dadhania
In-Reply-To: <1399978118-10298-1-git-send-email-aik@ozlabs.ru>

On 05/13/2014 08:48 PM, Alexey Kardashevskiy wrote:
> PCI spec says that lower 20 bits are assumed 0xFFFFF. The existing code
> seems to get it right in pci-bridge-set-mem-limit.
> 
> However pci-bridge-set-mem-base does not account 0xFFFFF and poison
> the limit. Since the limit is not stored anywhere in SLOF and only
> besides in the config space, it remains broken.
> 
> This fixes pci-bridge-set-mem-base.
> 
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> ---
> 
> I have doubts this is the right fix as I tried to "fix"
> pci-bridge-set-mmio-base (while I am here) and it broke the guest.
> 
> The problem I am fixing by this is that QEMU started as below is
> unable to initialize virtio-net device because there are overlapping
> virtio's BAR and bridge's "ranges" property. Note that virtio-net is
> attached to the PHB, not that additional bridge.
> 
> /home/aik/qemu-system-ppc64 \
> -enable-kvm \
> -m 1024 \
> -machine pseries \
> -nographic \
> -vga none \
> -device pci-bridge,id=id0,bus=pci.0,addr=5.0,chassis_nr=7 \
> -netdev tap,id=id1,ifname=tap1,script=ifup.sh,downscript=ifdown.sh \
> -device virtio-net-pci,id=id2,netdev=id1 \
> -initrd 1.cpio \
> -kernel vml315rc3 \
> 
> This is from the guest:
> 
> PCI host bridge /pci@800000020000000  ranges:
>   IO 0x0000010080000000..0x000001008000ffff -> 0x0000000000000000
>  MEM 0x00000100a0000000..0x00000100bfffffff -> 0x0000000080000000
> 
> PCI:0000:00:00.0 Resource 0 0000000000010020-000000000001003f [40101]
> PCI:0000:00:00.0 Resource 1 00000100b0000000-00000100b0000fff [40200]
> PCI:0000:00:00.0 Resource 6 00000100b0040000-00000100b007ffff [4c200]
> 
> PCI:0000:00:05.0 Bus rsrc 1 0000000090100000-00000000a00fffff [40200]
> PCI:0000:00:05.0 Bus rsrc 2 00000100a0000000-00000100b00fffff [42208]
> PCI: PHB (bus 0) bridge rsrc 4: 0000000000010000-000000000001ffff [0x100], parent c000000000f765b8 (PCI IO)
> PCI: PHB (bus 0) bridge rsrc 5: 00000100a0000000-00000100bfffffff [0x200], parent c000000000f76580 (PCI mem)
> PCI: Allocating 0000:00:00.0: Resource 0: 0000000000010020..000000000001003f [40101]
> PCI: Allocating 0000:00:00.0: Resource 1: 00000100b0000000..00000100b0000fff [40200]
> PCI: Cannot allocate resource region 1 of device 0000:00:00.0, will remap
> 
> This are PHB and bridge "ranges":
> [root@erif_root ~]# hexdump -e '7/4 "%08x "' -e '"\n"' /proc/device-tree/pci@800000020000000/ranges
> 01000000 00000000 00000000 00000100 80000000 00000000 00010000
> 02000000 00000000 80000000 00000100 a0000000 00000000 20000000
> [root@erif_root ~]# hexdump -e '8/4 "%08x "' -e '"\n"' /proc/device-tree/pci@800000020000000/pci@5/ranges
> 02000000 00000000 90100000 02000000 00000000 90100000 00000000 10000000
> 42000000 00000000 80000000 42000000 00000000 80000000 00000000 10100000
> 
> And virtio-net BARs:
> [root@erif_root ~]# hexdump -e '5/4 "%08x "' -e '"\n"' /proc/device-tree/pci@800000020000000/ethernet@0/reg
> 00000000 00000000 00000000 00000000 00000000
> 01000010 00000000 00000000 00000000 00000020
> 02000014 00000000 00000000 00000000 00001000
> 02000030 00000000 00000000 00000000 00040000
> [root@erif_root ~]# hexdump -e '5/4 "%08x "' -e '"\n"' /proc/device-tree/pci@800000020000000/ethernet@0/assigned-addres
> es
> 82000030 00000000 90040000 00000000 00040000
> 81000010 00000000 00000020 00000000 00000020
> 82000014 00000000 90000000 00000000 00001000

Hm. The patch seems to remove non-prefetch range from the PCI bridge
(pci@5/ranges) and made weird start address. So it is wrong. Oh...

[root@erif_root ~]# hexdump -e '7/4 "%08x "' -e '"\n"'
/proc/device-tree/pci@800000020000000/ranges
01000000 00000000 00000000 00000100 80000000 00000000 00010000
02000000 00000000 80000000 00000100 a0000000 00000000 20000000
[root@erif_root ~]# hexdump -e '8/4 "%08x "' -e '"\n"'
/proc/device-tree/pci@800000020000000/pci@5/ranges
42000000 00000000 7ff00000 42000000 00000000 7ff00000 00000000 00100000
[root@erif_root ~]# hexdump -e '5/4 "%08x "' -e '"\n"'
/proc/device-tree/pci@800000020000000/ethernet@0/reg
00000000 00000000 00000000 00000000 00000000
01000010 00000000 00000000 00000000 00000020
02000014 00000000 00000000 00000000 00001000
02000030 00000000 00000000 00000000 00040000
es ot@erif_root ~]# hexdump -e '5/4 "%08x "' -e '"\n"'
/proc/device-tree/pci@800000020000000/ethernet@0/assigned-addresse
82000030 00000000 90040000 00000000 00040000
81000010 00000000 00000020 00000000 00000020
82000014 00000000 90000000 00000000 00001000



> ---
>  slof/fs/pci-scan.fs | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/slof/fs/pci-scan.fs b/slof/fs/pci-scan.fs
> index ec9bd27..53b3b2c 100644
> --- a/slof/fs/pci-scan.fs
> +++ b/slof/fs/pci-scan.fs
> @@ -115,6 +115,7 @@ here 100 allot CONSTANT pci-device-vec
>          THEN                                    \ FI
>          10 rshift                               \ keep upper 16 bits
>          pci-max-mem @ FFFF0000 and or           \ and Insert mmem Limit (set it to max)
> +        1-
>          swap 24 + rtas-config-l!                \ and write it into the bridge
>  ;
>  
> 


-- 
Alexey

^ permalink raw reply

* [PATCH] powerpc/pseries: hcall functions are exported to modules, need _GLOBAL_TOC()
From: Anton Blanchard @ 2014-05-13 10:48 UTC (permalink / raw)
  To: benh, paulus; +Cc: linuxppc-dev

The hcall macros may call out to c code for tracing, so we need
to set up a valid r2. This fixes an oops found when testing
ibmvscsi as a module.

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

diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S
index 7891a86..99ecf0a 100644
--- a/arch/powerpc/platforms/pseries/hvCall.S
+++ b/arch/powerpc/platforms/pseries/hvCall.S
@@ -106,7 +106,7 @@ END_FTR_SECTION(0, 1);						\
 
 	.text
 
-_GLOBAL(plpar_hcall_norets)
+_GLOBAL_TOC(plpar_hcall_norets)
 	HMT_MEDIUM
 
 	mfcr	r0
@@ -122,7 +122,7 @@ _GLOBAL(plpar_hcall_norets)
 	mtcrf	0xff,r0
 	blr				/* return r3 = status */
 
-_GLOBAL(plpar_hcall)
+_GLOBAL_TOC(plpar_hcall)
 	HMT_MEDIUM
 
 	mfcr	r0
@@ -188,7 +188,7 @@ _GLOBAL(plpar_hcall_raw)
 
 	blr				/* return r3 = status */
 
-_GLOBAL(plpar_hcall9)
+_GLOBAL_TOC(plpar_hcall9)
 	HMT_MEDIUM
 
 	mfcr	r0

^ permalink raw reply related

* [PATCH] pci-scan: Fix setting the limit
From: Alexey Kardashevskiy @ 2014-05-13 10:48 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Alexey Kardashevskiy, Paul Mackerras, Thomas Huth,
	Nikunj A Dadhania

PCI spec says that lower 20 bits are assumed 0xFFFFF. The existing code
seems to get it right in pci-bridge-set-mem-limit.

However pci-bridge-set-mem-base does not account 0xFFFFF and poison
the limit. Since the limit is not stored anywhere in SLOF and only
besides in the config space, it remains broken.

This fixes pci-bridge-set-mem-base.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---

I have doubts this is the right fix as I tried to "fix"
pci-bridge-set-mmio-base (while I am here) and it broke the guest.

The problem I am fixing by this is that QEMU started as below is
unable to initialize virtio-net device because there are overlapping
virtio's BAR and bridge's "ranges" property. Note that virtio-net is
attached to the PHB, not that additional bridge.

/home/aik/qemu-system-ppc64 \
-enable-kvm \
-m 1024 \
-machine pseries \
-nographic \
-vga none \
-device pci-bridge,id=id0,bus=pci.0,addr=5.0,chassis_nr=7 \
-netdev tap,id=id1,ifname=tap1,script=ifup.sh,downscript=ifdown.sh \
-device virtio-net-pci,id=id2,netdev=id1 \
-initrd 1.cpio \
-kernel vml315rc3 \

This is from the guest:

PCI host bridge /pci@800000020000000  ranges:
  IO 0x0000010080000000..0x000001008000ffff -> 0x0000000000000000
 MEM 0x00000100a0000000..0x00000100bfffffff -> 0x0000000080000000

PCI:0000:00:00.0 Resource 0 0000000000010020-000000000001003f [40101]
PCI:0000:00:00.0 Resource 1 00000100b0000000-00000100b0000fff [40200]
PCI:0000:00:00.0 Resource 6 00000100b0040000-00000100b007ffff [4c200]

PCI:0000:00:05.0 Bus rsrc 1 0000000090100000-00000000a00fffff [40200]
PCI:0000:00:05.0 Bus rsrc 2 00000100a0000000-00000100b00fffff [42208]
PCI: PHB (bus 0) bridge rsrc 4: 0000000000010000-000000000001ffff [0x100], parent c000000000f765b8 (PCI IO)
PCI: PHB (bus 0) bridge rsrc 5: 00000100a0000000-00000100bfffffff [0x200], parent c000000000f76580 (PCI mem)
PCI: Allocating 0000:00:00.0: Resource 0: 0000000000010020..000000000001003f [40101]
PCI: Allocating 0000:00:00.0: Resource 1: 00000100b0000000..00000100b0000fff [40200]
PCI: Cannot allocate resource region 1 of device 0000:00:00.0, will remap

This are PHB and bridge "ranges":
[root@erif_root ~]# hexdump -e '7/4 "%08x "' -e '"\n"' /proc/device-tree/pci@800000020000000/ranges
01000000 00000000 00000000 00000100 80000000 00000000 00010000
02000000 00000000 80000000 00000100 a0000000 00000000 20000000
[root@erif_root ~]# hexdump -e '8/4 "%08x "' -e '"\n"' /proc/device-tree/pci@800000020000000/pci@5/ranges
02000000 00000000 90100000 02000000 00000000 90100000 00000000 10000000
42000000 00000000 80000000 42000000 00000000 80000000 00000000 10100000

And virtio-net BARs:
[root@erif_root ~]# hexdump -e '5/4 "%08x "' -e '"\n"' /proc/device-tree/pci@800000020000000/ethernet@0/reg
00000000 00000000 00000000 00000000 00000000
01000010 00000000 00000000 00000000 00000020
02000014 00000000 00000000 00000000 00001000
02000030 00000000 00000000 00000000 00040000
[root@erif_root ~]# hexdump -e '5/4 "%08x "' -e '"\n"' /proc/device-tree/pci@800000020000000/ethernet@0/assigned-addres
es
82000030 00000000 90040000 00000000 00040000
81000010 00000000 00000020 00000000 00000020
82000014 00000000 90000000 00000000 00001000
---
 slof/fs/pci-scan.fs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/slof/fs/pci-scan.fs b/slof/fs/pci-scan.fs
index ec9bd27..53b3b2c 100644
--- a/slof/fs/pci-scan.fs
+++ b/slof/fs/pci-scan.fs
@@ -115,6 +115,7 @@ here 100 allot CONSTANT pci-device-vec
         THEN                                    \ FI
         10 rshift                               \ keep upper 16 bits
         pci-max-mem @ FFFF0000 and or           \ and Insert mmem Limit (set it to max)
+        1-
         swap 24 + rtas-config-l!                \ and write it into the bridge
 ;
 
-- 
1.9.rc0

^ permalink raw reply related

* Re: powerpc/ppc64: Allow allmodconfig to build (finally !)
From: Benjamin Herrenschmidt @ 2014-05-13  9:16 UTC (permalink / raw)
  To: Guenter Roeck; +Cc: linuxppc-dev
In-Reply-To: <20140513002846.GA29753@roeck-us.net>

On Mon, 2014-05-12 at 17:28 -0700, Guenter Roeck wrote:

> After applying this patch, I get
> 
> arch/powerpc/kernel/exceptions-64s.S:269: Error: operand out of range
> (0x000000000000814c is not between 0xffffffffffff8000 and 0x0000000000007ffc)
> arch/powerpc/kernel/exceptions-64s.S:729: Error: operand out of range
> (0x000000000000814c is not between 0xffffffffffff8000 and 0x0000000000007ffc)
> 
> with powerpc:defconfig, powerpc:allmodconfig, powerpc:cell_defconfig, and
> powerpc:maple_defconfig.
> 
> This is on top of v3.15-rc5. Any idea what is going on ?
> 
> Compiler is powerpc64-poky-linux-gcc (GCC) 4.7.2 (from poky 1.4.0-1).

Interesting... works with all my test configs using 4.7.3...

I don't have my tree at hand right now, I'll check what that means
tomorrow see if I can find a workaround.

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH] powerpc/pseries: relocate "config DTL" so KConfig nests properly
From: Cody P Schafer @ 2014-05-13  7:12 UTC (permalink / raw)
  To: Michael Neuling
  Cc: Deepthi Dharwar, Paul Bolle, Gavin Shan, Li Zhong, linux-kernel,
	Paul Mackerras, Srivatsa S. Bhat, linuxppc-dev
In-Reply-To: <1399962216.7554.63.camel@ale.ozlabs.ibm.com>

On 05/12/2014 11:23 PM, Michael Neuling wrote:
>> powerpc/pseries: relocate "config DTL" so KConfig nests properly
>
> I don't know what that means.  Can you describe it in more detail?
>

So the "config DTL" refers to the configuration entry.

The "nests properly" refers to the indent that 'make menuconfig' shows 
when a config-option that depends on the config-option proceeding it.

In this case, moving config DTL up so it is below config PPC_SPLPAR 
means that menuconfig will show config DTL nicely indented right below 
config PPC_SPLPAR when PPC_SPLPAR is enabled.

To contrast that, right now if I enable PPC_SPLPAR in menuconfig, all I 
can immediately tell is that "something showed up further down the list 
where I wasn't looking", and I end up having to toggle the option a few 
times to figure out what showed up, or look at the KConfig to find out 
that config DTL depends on config PPC_SPLPAR.

Essentially, this enables menuconfig to provide a visual hint about the 
dependencies between options.

> Mikey
>
>
> On Mon, 2014-05-12 at 20:09 -0700, Cody P Schafer wrote:
>> Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>
>> ---
>>   arch/powerpc/platforms/pseries/Kconfig | 20 ++++++++++----------
>>   1 file changed, 10 insertions(+), 10 deletions(-)
>>
>> diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
>> index 2cb8b77..e00dd4d 100644
>> --- a/arch/powerpc/platforms/pseries/Kconfig
>> +++ b/arch/powerpc/platforms/pseries/Kconfig
>> @@ -33,6 +33,16 @@ config PPC_SPLPAR
>>   	  processors, that is, which share physical processors between
>>   	  two or more partitions.
>>
>> +config DTL
>> +	bool "Dispatch Trace Log"
>> +	depends on PPC_SPLPAR && DEBUG_FS
>> +	help
>> +	  SPLPAR machines can log hypervisor preempt & dispatch events to a
>> +	  kernel buffer. Saying Y here will enable logging these events,
>> +	  which are accessible through a debugfs file.
>> +
>> +	  Say N if you are unsure.
>> +
>>   config PSERIES_MSI
>>          bool
>>          depends on PCI_MSI && PPC_PSERIES && EEH
>> @@ -122,13 +132,3 @@ config HV_PERF_CTRS
>>   	  systems. 24x7 is available on Power 8 systems.
>>
>>             If unsure, select Y.
>> -
>> -config DTL
>> -	bool "Dispatch Trace Log"
>> -	depends on PPC_SPLPAR && DEBUG_FS
>> -	help
>> -	  SPLPAR machines can log hypervisor preempt & dispatch events to a
>> -	  kernel buffer. Saying Y here will enable logging these events,
>> -	  which are accessible through a debugfs file.
>> -
>> -	  Say N if you are unsure.
>

^ permalink raw reply

* [PATCH] booke/powerpc: define wimge shift mask to fix compilation error
From: Bharat Bhushan @ 2014-05-13  6:48 UTC (permalink / raw)
  To: linuxppc-dev, scottwood; +Cc: Bharat Bhushan, kvm, kvm-ppc, agraf

This fixes below compilation error on SOCs where CONFIG_PHYS_64BIT
is not defined:

 arch/powerpc/kvm/e500_mmu_host.c: In function 'kvmppc_e500_shadow_map':
| arch/powerpc/kvm/e500_mmu_host.c:631:20: error: 'PTE_WIMGE_SHIFT' undeclared (first use in this function)
|    wimg = (*ptep >> PTE_WIMGE_SHIFT) & MAS2_WIMGE_MASK;
|                     ^
| arch/powerpc/kvm/e500_mmu_host.c:631:20: note: each undeclared identifier is reported only once for each function it appears in
| make[1]: *** [arch/powerpc/kvm/e500_mmu_host.o] Error 1

Signed-off-by: Bharat Bhushan <Bharat.Bhushan@freescale.com>
---
 arch/powerpc/include/asm/pte-fsl-booke.h |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/pte-fsl-booke.h b/arch/powerpc/include/asm/pte-fsl-booke.h
index 2c12be5..e84dd7e 100644
--- a/arch/powerpc/include/asm/pte-fsl-booke.h
+++ b/arch/powerpc/include/asm/pte-fsl-booke.h
@@ -37,5 +37,7 @@
 #define _PMD_PRESENT_MASK (PAGE_MASK)
 #define _PMD_BAD	(~PAGE_MASK)
 
+#define PTE_WIMGE_SHIFT (6)
+
 #endif /* __KERNEL__ */
 #endif /*  _ASM_POWERPC_PTE_FSL_BOOKE_H */
-- 
1.7.0.4

^ permalink raw reply related

* Re: [PATCH] powerpc/pseries: relocate "config DTL" so KConfig nests properly
From: Michael Neuling @ 2014-05-13  6:23 UTC (permalink / raw)
  To: Cody P Schafer
  Cc: Deepthi Dharwar, Paul Bolle, Gavin Shan, Li Zhong, linux-kernel,
	Paul Mackerras, Srivatsa S. Bhat, linuxppc-dev
In-Reply-To: <1399950599-24826-1-git-send-email-cody@linux.vnet.ibm.com>

> powerpc/pseries: relocate "config DTL" so KConfig nests properly

I don't know what that means.  Can you describe it in more detail?

Mikey


On Mon, 2014-05-12 at 20:09 -0700, Cody P Schafer wrote:
> Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>
> ---
>  arch/powerpc/platforms/pseries/Kconfig | 20 ++++++++++----------
>  1 file changed, 10 insertions(+), 10 deletions(-)
>=20
> diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platfo=
rms/pseries/Kconfig
> index 2cb8b77..e00dd4d 100644
> --- a/arch/powerpc/platforms/pseries/Kconfig
> +++ b/arch/powerpc/platforms/pseries/Kconfig
> @@ -33,6 +33,16 @@ config PPC_SPLPAR
>  	  processors, that is, which share physical processors between
>  	  two or more partitions.
> =20
> +config DTL
> +	bool "Dispatch Trace Log"
> +	depends on PPC_SPLPAR && DEBUG_FS
> +	help
> +	  SPLPAR machines can log hypervisor preempt & dispatch events to a
> +	  kernel buffer. Saying Y here will enable logging these events,
> +	  which are accessible through a debugfs file.
> +
> +	  Say N if you are unsure.
> +
>  config PSERIES_MSI
>         bool
>         depends on PCI_MSI && PPC_PSERIES && EEH
> @@ -122,13 +132,3 @@ config HV_PERF_CTRS
>  	  systems. 24x7 is available on Power 8 systems.
> =20
>            If unsure, select Y.
> -
> -config DTL
> -	bool "Dispatch Trace Log"
> -	depends on PPC_SPLPAR && DEBUG_FS
> -	help
> -	  SPLPAR machines can log hypervisor preempt & dispatch events to a
> -	  kernel buffer. Saying Y here will enable logging these events,
> -	  which are accessible through a debugfs file.
> -
> -	  Say N if you are unsure.

^ permalink raw reply

* [PATCH] powerpc/pseries: relocate "config DTL" so KConfig nests properly
From: Cody P Schafer @ 2014-05-13  3:09 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Cody P Schafer, Deepthi Dharwar,
	Gavin Shan, Li Zhong, Michael Ellerman, Paul Bolle,
	Srivatsa S. Bhat
  Cc: Paul Mackerras, linuxppc-dev, linux-kernel

Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/pseries/Kconfig | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
index 2cb8b77..e00dd4d 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -33,6 +33,16 @@ config PPC_SPLPAR
 	  processors, that is, which share physical processors between
 	  two or more partitions.
 
+config DTL
+	bool "Dispatch Trace Log"
+	depends on PPC_SPLPAR && DEBUG_FS
+	help
+	  SPLPAR machines can log hypervisor preempt & dispatch events to a
+	  kernel buffer. Saying Y here will enable logging these events,
+	  which are accessible through a debugfs file.
+
+	  Say N if you are unsure.
+
 config PSERIES_MSI
        bool
        depends on PCI_MSI && PPC_PSERIES && EEH
@@ -122,13 +132,3 @@ config HV_PERF_CTRS
 	  systems. 24x7 is available on Power 8 systems.
 
           If unsure, select Y.
-
-config DTL
-	bool "Dispatch Trace Log"
-	depends on PPC_SPLPAR && DEBUG_FS
-	help
-	  SPLPAR machines can log hypervisor preempt & dispatch events to a
-	  kernel buffer. Saying Y here will enable logging these events,
-	  which are accessible through a debugfs file.
-
-	  Say N if you are unsure.
-- 
1.9.3

^ permalink raw reply related

* linux-next: manual merge of the powerpc tree with the fixes tree
From: Stephen Rothwell @ 2014-05-13  2:01 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, linuxppc-dev
  Cc: linux-next, linux-kernel, Anton Blanchard

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

Hi all,

Today's linux-next merge of the powerpc tree got a conflict in
arch/powerpc/kernel/exceptions-64s.S between commit 0be9d8b61c0c
("powerpc/ppc64: Allow allmodconfig to build (finally !)") from the
fixes tree and commits b1576fec7f4d ("powerpc: No need to use dot
symbols when branching to a function") and 354255014a90 ("powerpc:
Remove dot symbol usage in exception macros") from the powerpc tree.

I fixed it up (see below) and can carry the fix as necessary (no action
is required).

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --cc arch/powerpc/kernel/exceptions-64s.S
index 833a68dc4cc8,20f11eb4dff7..000000000000
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@@ -891,186 -1025,14 +891,186 @@@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR
  	std	r12,RESULT(r1)
  	std	r11,STACK_FRAME_OVERHEAD-16(r1)
  1:	addi	r3,r1,STACK_FRAME_OVERHEAD
- 	bl	.kernel_bad_stack
+ 	bl	kernel_bad_stack
  	b	1b
  
 +
 +#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
 +/*
 + * Data area reserved for FWNMI option.
 + * This address (0x7000) is fixed by the RPA.
 + */
 +	.= 0x7000
 +	.globl fwnmi_data_area
 +fwnmi_data_area:
 +
 +	/* pseries and powernv need to keep the whole page from
 +	 * 0x7000 to 0x8000 free for use by the firmware
 +	 */
 +	. = 0x8000
 +#endif /* defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) */
 +
  /*
 - * Here r13 points to the paca, r9 contains the saved CR,
 - * SRR0 and SRR1 are saved in r11 and r12,
 - * r9 - r13 are saved in paca->exgen.
 + * Denorm interrupt assist moved out of line to here, where it remains
 + * close enough to the call site which uses a small conditional branch
   */
 +#ifdef CONFIG_PPC_DENORMALISATION
 +denorm_assist:
 +BEGIN_FTR_SECTION
 +/*
 + * To denormalise we need to move a copy of the register to itself.
 + * For POWER6 do that here for all FP regs.
 + */
 +	mfmsr	r10
 +	ori	r10,r10,(MSR_FP|MSR_FE0|MSR_FE1)
 +	xori	r10,r10,(MSR_FE0|MSR_FE1)
 +	mtmsrd	r10
 +	sync
 +
 +#define FMR2(n)  fmr (n), (n) ; fmr n+1, n+1
 +#define FMR4(n)  FMR2(n) ; FMR2(n+2)
 +#define FMR8(n)  FMR4(n) ; FMR4(n+4)
 +#define FMR16(n) FMR8(n) ; FMR8(n+8)
 +#define FMR32(n) FMR16(n) ; FMR16(n+16)
 +	FMR32(0)
 +
 +FTR_SECTION_ELSE
 +/*
 + * To denormalise we need to move a copy of the register to itself.
 + * For POWER7 do that here for the first 32 VSX registers only.
 + */
 +	mfmsr	r10
 +	oris	r10,r10,MSR_VSX@h
 +	mtmsrd	r10
 +	sync
 +
 +#define XVCPSGNDP2(n) XVCPSGNDP(n,n,n) ; XVCPSGNDP(n+1,n+1,n+1)
 +#define XVCPSGNDP4(n) XVCPSGNDP2(n) ; XVCPSGNDP2(n+2)
 +#define XVCPSGNDP8(n) XVCPSGNDP4(n) ; XVCPSGNDP4(n+4)
 +#define XVCPSGNDP16(n) XVCPSGNDP8(n) ; XVCPSGNDP8(n+8)
 +#define XVCPSGNDP32(n) XVCPSGNDP16(n) ; XVCPSGNDP16(n+16)
 +	XVCPSGNDP32(0)
 +
 +ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_206)
 +
 +BEGIN_FTR_SECTION
 +	b	denorm_done
 +END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
 +/*
 + * To denormalise we need to move a copy of the register to itself.
 + * For POWER8 we need to do that for all 64 VSX registers
 + */
 +	XVCPSGNDP32(32)
 +denorm_done:
 +	mtspr	SPRN_HSRR0,r11
 +	mtcrf	0x80,r9
 +	ld	r9,PACA_EXGEN+EX_R9(r13)
 +	RESTORE_PPR_PACA(PACA_EXGEN, r10)
 +BEGIN_FTR_SECTION
 +	ld	r10,PACA_EXGEN+EX_CFAR(r13)
 +	mtspr	SPRN_CFAR,r10
 +END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
 +	ld	r10,PACA_EXGEN+EX_R10(r13)
 +	ld	r11,PACA_EXGEN+EX_R11(r13)
 +	ld	r12,PACA_EXGEN+EX_R12(r13)
 +	ld	r13,PACA_EXGEN+EX_R13(r13)
 +	HRFID
 +	b	.
 +#endif
 +
 +/*
 + * An interrupt came in while soft-disabled. We set paca->irq_happened, then:
 + * - If it was a decrementer interrupt, we bump the dec to max and and return.
 + * - If it was a doorbell we return immediately since doorbells are edge
 + *   triggered and won't automatically refire.
 + * - else we hard disable and return.
 + * This is called with r10 containing the value to OR to the paca field.
 + *
 + * Warning: This code is reached using a (small) conditional branch from both
 + * the 1st level exception handlers below 0x8000 and the alternate feature
 + * sections of that file which the linker puts right after the text in here.
 + *
 + * For that to work, we thus need this code to be roughly near the "middle"
 + * so that we can reach it with <32k offsets. Here works... for now.
 + */
 +#define MASKED_INTERRUPT(_H)				\
 +masked_##_H##interrupt:					\
 +	std	r11,PACA_EXGEN+EX_R11(r13);		\
 +	lbz	r11,PACAIRQHAPPENED(r13);		\
 +	or	r11,r11,r10;				\
 +	stb	r11,PACAIRQHAPPENED(r13);		\
 +	cmpwi	r10,PACA_IRQ_DEC;			\
 +	bne	1f;					\
 +	lis	r10,0x7fff;				\
 +	ori	r10,r10,0xffff;				\
 +	mtspr	SPRN_DEC,r10;				\
 +	b	2f;					\
 +1:	cmpwi	r10,PACA_IRQ_DBELL;			\
 +	beq	2f;					\
 +	mfspr	r10,SPRN_##_H##SRR1;			\
 +	rldicl	r10,r10,48,1; /* clear MSR_EE */	\
 +	rotldi	r10,r10,16;				\
 +	mtspr	SPRN_##_H##SRR1,r10;			\
 +2:	mtcrf	0x80,r9;				\
 +	ld	r9,PACA_EXGEN+EX_R9(r13);		\
 +	ld	r10,PACA_EXGEN+EX_R10(r13);		\
 +	ld	r11,PACA_EXGEN+EX_R11(r13);		\
 +	GET_SCRATCH0(r13);				\
 +	##_H##rfid;					\
 +	b	.
 +
 +	MASKED_INTERRUPT()
 +	MASKED_INTERRUPT(H)
 +
 +/*
 + * Code from here down to __end_handlers is invoked from the
 + * exception prologs above.  Because the prologs assemble the
 + * addresses of these handlers using the LOAD_HANDLER macro,
 + * which uses an ori instruction, these handlers must be in
 + * the first 64k of the kernel image.
 + */
 +
 +/*** Common interrupt handlers ***/
 +
- 	STD_EXCEPTION_COMMON(0x100, system_reset, .system_reset_exception)
++	STD_EXCEPTION_COMMON(0x100, system_reset, system_reset_exception)
 +
 +	STD_EXCEPTION_COMMON_ASYNC(0x500, hardware_interrupt, do_IRQ)
- 	STD_EXCEPTION_COMMON_ASYNC(0x900, decrementer, .timer_interrupt)
- 	STD_EXCEPTION_COMMON(0x980, hdecrementer, .hdec_interrupt)
++	STD_EXCEPTION_COMMON_ASYNC(0x900, decrementer, timer_interrupt)
++	STD_EXCEPTION_COMMON(0x980, hdecrementer, hdec_interrupt)
 +#ifdef CONFIG_PPC_DOORBELL
- 	STD_EXCEPTION_COMMON_ASYNC(0xa00, doorbell_super, .doorbell_exception)
++	STD_EXCEPTION_COMMON_ASYNC(0xa00, doorbell_super, doorbell_exception)
 +#else
- 	STD_EXCEPTION_COMMON_ASYNC(0xa00, doorbell_super, .unknown_exception)
++	STD_EXCEPTION_COMMON_ASYNC(0xa00, doorbell_super, unknown_exception)
 +#endif
- 	STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
- 	STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
- 	STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
- 	STD_EXCEPTION_COMMON(0xe40, emulation_assist, .emulation_assist_interrupt)
- 	STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception)
++	STD_EXCEPTION_COMMON(0xb00, trap_0b, unknown_exception)
++	STD_EXCEPTION_COMMON(0xd00, single_step, single_step_exception)
++	STD_EXCEPTION_COMMON(0xe00, trap_0e, unknown_exception)
++	STD_EXCEPTION_COMMON(0xe40, emulation_assist, emulation_assist_interrupt)
++	STD_EXCEPTION_COMMON(0xe60, hmi_exception, unknown_exception)
 +#ifdef CONFIG_PPC_DOORBELL
- 	STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, .doorbell_exception)
++	STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, doorbell_exception)
 +#else
- 	STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, .unknown_exception)
++	STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, unknown_exception)
 +#endif
- 	STD_EXCEPTION_COMMON_ASYNC(0xf00, performance_monitor, .performance_monitor_exception)
- 	STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
- 	STD_EXCEPTION_COMMON(0x1502, denorm, .unknown_exception)
++	STD_EXCEPTION_COMMON_ASYNC(0xf00, performance_monitor, performance_monitor_exception)
++	STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, instruction_breakpoint_exception)
++	STD_EXCEPTION_COMMON(0x1502, denorm, unknown_exception)
 +#ifdef CONFIG_ALTIVEC
- 	STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception)
++	STD_EXCEPTION_COMMON(0x1700, altivec_assist, altivec_assist_exception)
 +#else
- 	STD_EXCEPTION_COMMON(0x1700, altivec_assist, .unknown_exception)
++	STD_EXCEPTION_COMMON(0x1700, altivec_assist, unknown_exception)
 +#endif
 +#ifdef CONFIG_CBE_RAS
- 	STD_EXCEPTION_COMMON(0x1200, cbe_system_error, .cbe_system_error_exception)
- 	STD_EXCEPTION_COMMON(0x1600, cbe_maintenance, .cbe_maintenance_exception)
- 	STD_EXCEPTION_COMMON(0x1800, cbe_thermal, .cbe_thermal_exception)
++	STD_EXCEPTION_COMMON(0x1200, cbe_system_error, cbe_system_error_exception)
++	STD_EXCEPTION_COMMON(0x1600, cbe_maintenance, cbe_maintenance_exception)
++	STD_EXCEPTION_COMMON(0x1800, cbe_thermal, cbe_thermal_exception)
 +#endif /* CONFIG_CBE_RAS */
 +
 +	/*
 +	 * Here r13 points to the paca, r9 contains the saved CR,
 +	 * SRR0 and SRR1 are saved in r11 and r12,
 +	 * r9 - r13 are saved in paca->exgen.
 +	 */
  	.align	7
  	.globl data_access_common
  data_access_common:
@@@ -1109,10 -1071,73 +1109,10 @@@ instruction_access_common
  	ld	r3,_NIP(r1)
  	andis.	r4,r12,0x5820
  	li	r5,0x400
- 	b	.do_hash_page		/* Try to handle as hpte fault */
+ 	b	do_hash_page		/* Try to handle as hpte fault */
  
- 	STD_EXCEPTION_COMMON(0xe20, h_instr_storage, .unknown_exception)
+ 	STD_EXCEPTION_COMMON(0xe20, h_instr_storage, unknown_exception)
  
 -/*
 - * Here is the common SLB miss user that is used when going to virtual
 - * mode for SLB misses, that is currently not used
 - */
 -#ifdef __DISABLED__
 -	.align	7
 -	.globl	slb_miss_user_common
 -slb_miss_user_common:
 -	mflr	r10
 -	std	r3,PACA_EXGEN+EX_DAR(r13)
 -	stw	r9,PACA_EXGEN+EX_CCR(r13)
 -	std	r10,PACA_EXGEN+EX_LR(r13)
 -	std	r11,PACA_EXGEN+EX_SRR0(r13)
 -	bl	slb_allocate_user
 -
 -	ld	r10,PACA_EXGEN+EX_LR(r13)
 -	ld	r3,PACA_EXGEN+EX_R3(r13)
 -	lwz	r9,PACA_EXGEN+EX_CCR(r13)
 -	ld	r11,PACA_EXGEN+EX_SRR0(r13)
 -	mtlr	r10
 -	beq-	slb_miss_fault
 -
 -	andi.	r10,r12,MSR_RI		/* check for unrecoverable exception */
 -	beq-	unrecov_user_slb
 -	mfmsr	r10
 -
 -.machine push
 -.machine "power4"
 -	mtcrf	0x80,r9
 -.machine pop
 -
 -	clrrdi	r10,r10,2		/* clear RI before setting SRR0/1 */
 -	mtmsrd	r10,1
 -
 -	mtspr	SRR0,r11
 -	mtspr	SRR1,r12
 -
 -	ld	r9,PACA_EXGEN+EX_R9(r13)
 -	ld	r10,PACA_EXGEN+EX_R10(r13)
 -	ld	r11,PACA_EXGEN+EX_R11(r13)
 -	ld	r12,PACA_EXGEN+EX_R12(r13)
 -	ld	r13,PACA_EXGEN+EX_R13(r13)
 -	rfid
 -	b	.
 -
 -slb_miss_fault:
 -	EXCEPTION_PROLOG_COMMON(0x380, PACA_EXGEN)
 -	ld	r4,PACA_EXGEN+EX_DAR(r13)
 -	li	r5,0
 -	std	r4,_DAR(r1)
 -	std	r5,_DSISR(r1)
 -	b	handle_page_fault
 -
 -unrecov_user_slb:
 -	EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN)
 -	DISABLE_INTS
 -	bl	save_nvgprs
 -1:	addi	r3,r1,STACK_FRAME_OVERHEAD
 -	bl	unrecoverable_exception
 -	b	1b
 -
 -#endif /* __DISABLED__ */
 -
  
  	/*
  	 * Machine check is different because we use a different

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

^ permalink raw reply

* Re: powerpc/ppc64: Allow allmodconfig to build (finally !)
From: Guenter Roeck @ 2014-05-13  0:28 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <1399874254.17624.85.camel@pasglop>

On Mon, May 12, 2014 at 03:57:34PM +1000, Benjamin Herrenschmidt wrote:
> This shuffles code around in exceptions-64s.S in order to
> allow an allmodconfig build to succeed.
> 
> The main problems were:
> 
>  - We have a fixed hole from 0x7000 to 0x8000 for use by FW,
> under some circumstances the code before that would grow too
> big and hit the . = 0x7000
> 
>  - The various attempts at making space in there would trigger
> cases where short conditional branches from assembly would no
> longer be able to reach their target. This is especially nasty
> when these branches reside in alternate feature sections which
> are appended at the end of each .o file
> 
> This fixes it by essentially moving all the "second level"
> exception handlers to after the hole and moving a couple of
> functions near the hole itself so they sit at reachable distance
> of both the first level handlers (before the hole) and the alternate
> feature sections (end of file).
> 
> In the long run, if we start hitting this again, we'll probably
> have to split the file in two, probably at the hole location,
> to keep the alt sections used by the first level handlers close
> to them, and move everything else further away.
> 
> But for now, this will do.
> 
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> 
Ben,

After applying this patch, I get

arch/powerpc/kernel/exceptions-64s.S:269: Error: operand out of range
(0x000000000000814c is not between 0xffffffffffff8000 and 0x0000000000007ffc)
arch/powerpc/kernel/exceptions-64s.S:729: Error: operand out of range
(0x000000000000814c is not between 0xffffffffffff8000 and 0x0000000000007ffc)

with powerpc:defconfig, powerpc:allmodconfig, powerpc:cell_defconfig, and
powerpc:maple_defconfig.

This is on top of v3.15-rc5. Any idea what is going on ?

Compiler is powerpc64-poky-linux-gcc (GCC) 4.7.2 (from poky 1.4.0-1).

Thanks,
Guenter

^ 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