diff mbox

powerpc: Keep track of emulated instructions

Message ID alpine.LRH.2.00.0904031404450.32353@vixen.sonytel.be (mailing list archive)
State Changes Requested, archived
Headers show

Commit Message

Geert Uytterhoeven April 3, 2009, 12:08 p.m. UTC
Hi Ben, Kumar,

Finally (after ca. 1.5 years), he're an updated version of my patch to keep
track of emulated instructions.  In the light of Kumar's `Emulate enough of SPE
instructions to make gcc happy' patch, he probably also wants to keep track of
the actual runtime overhead.

Changes since last version:
  - arch/powerpc/kernel/sysfs.c is now compiled on ppc32, so we can provide
    counters in sysfs on ppc32, too,
  - WARN_EMULATED() is a no-op if CONFIG_SYSCTL is disabled,
  - Add warnings for altivec,
  - Add warnings for recently introduced emulation of vsx and isel
    instructions.

Tested with `mfpvr' on PS3 and AMCC `Sequoia' EV-440EPX.
---
From 8df6f7d77f28c9a5b82c9512b9dd7688d94d4e33 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Date: Thu, 26 Mar 2009 17:00:12 +0100
Subject: [PATCH] powerpc: Keep track of emulated instructions

Counters for the various classes of emulated instructions are available under
/sys/devices/system/cpu/cpu*/emulated/.
Optionally (controlled by /proc/sys/kernel/cpu_emulation_warnings, if
CONFIG_SYSCTL=y), rate-limited warnings can be printed to the console when
instructions are emulated.

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 arch/powerpc/include/asm/emulated_ops.h |   63 +++++++++++++++++++++++++
 arch/powerpc/kernel/align.c             |   18 ++++++--
 arch/powerpc/kernel/sysfs.c             |   78 ++++++++++++++++++++++++++++++-
 arch/powerpc/kernel/traps.c             |   60 +++++++++++++++++++++++-
 4 files changed, 212 insertions(+), 7 deletions(-)
 create mode 100644 arch/powerpc/include/asm/emulated_ops.h

Comments

Kumar Gala April 3, 2009, 2:15 p.m. UTC | #1
On Apr 3, 2009, at 7:08 AM, Geert Uytterhoeven wrote:

> 	Hi Ben, Kumar,
>
> Finally (after ca. 1.5 years), he're an updated version of my patch  
> to keep
> track of emulated instructions.  In the light of Kumar's `Emulate  
> enough of SPE
> instructions to make gcc happy' patch, he probably also wants to  
> keep track of
> the actual runtime overhead.
>
> Changes since last version:
>  - arch/powerpc/kernel/sysfs.c is now compiled on ppc32, so we can  
> provide
>    counters in sysfs on ppc32, too,
>  - WARN_EMULATED() is a no-op if CONFIG_SYSCTL is disabled,
>  - Add warnings for altivec,
>  - Add warnings for recently introduced emulation of vsx and isel
>    instructions.

pretty cool.  Do we think counters should be sysfs or debugfs?

Also it would be nice to be able to zero out the counters.

- k
Michael Ellerman April 4, 2009, 4:37 a.m. UTC | #2
On Fri, 2009-04-03 at 14:08 +0200, Geert Uytterhoeven wrote:
> 	Hi Ben, Kumar,
> 
> Finally (after ca. 1.5 years), he're an updated version of my patch to keep
> track of emulated instructions.  In the light of Kumar's `Emulate enough of SPE
> instructions to make gcc happy' patch, he probably also wants to keep track of
> the actual runtime overhead.
> 
> Changes since last version:
>   - arch/powerpc/kernel/sysfs.c is now compiled on ppc32, so we can provide
>     counters in sysfs on ppc32, too,
>   - WARN_EMULATED() is a no-op if CONFIG_SYSCTL is disabled,
>   - Add warnings for altivec,
>   - Add warnings for recently introduced emulation of vsx and isel
>     instructions.

You don't count instructions that fall through to the bottom of
fix_alignment()?

cheers
Geert Uytterhoeven April 6, 2009, 12:30 p.m. UTC | #3
On Sat, 4 Apr 2009, Michael Ellerman wrote:
> On Fri, 2009-04-03 at 14:08 +0200, Geert Uytterhoeven wrote:
> > Finally (after ca. 1.5 years), he're an updated version of my patch to keep
> > track of emulated instructions.  In the light of Kumar's `Emulate enough of SPE
> > instructions to make gcc happy' patch, he probably also wants to keep track of
> > the actual runtime overhead.
> > 
> > Changes since last version:
> >   - arch/powerpc/kernel/sysfs.c is now compiled on ppc32, so we can provide
> >     counters in sysfs on ppc32, too,
> >   - WARN_EMULATED() is a no-op if CONFIG_SYSCTL is disabled,
> >   - Add warnings for altivec,
> >   - Add warnings for recently introduced emulation of vsx and isel
> >     instructions.
> 
> You don't count instructions that fall through to the bottom of
> fix_alignment()?

Thanks! I add a generic unaligned counter for the fall through case.

With kind regards,

Geert Uytterhoeven
Software Architect

Sony Techsoft Centre Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium

Phone:    +32 (0)2 700 8453
Fax:      +32 (0)2 700 8622
E-mail:   Geert.Uytterhoeven@sonycom.com
Internet: http://www.sony-europe.com/

A division of Sony Europe (Belgium) N.V.
VAT BE 0413.825.160 · RPR Brussels
Fortis · BIC GEBABEBB · IBAN BE41293037680010
Geert Uytterhoeven April 6, 2009, 12:33 p.m. UTC | #4
On Fri, 3 Apr 2009, Kumar Gala wrote:
> On Apr 3, 2009, at 7:08 AM, Geert Uytterhoeven wrote:
> >Finally (after ca. 1.5 years), he're an updated version of my patch to keep
> >track of emulated instructions.  In the light of Kumar's `Emulate enough of
> >SPE
> >instructions to make gcc happy' patch, he probably also wants to keep track
> >of
> >the actual runtime overhead.
> >
> >Changes since last version:
> > - arch/powerpc/kernel/sysfs.c is now compiled on ppc32, so we can provide
> >   counters in sysfs on ppc32, too,
> > - WARN_EMULATED() is a no-op if CONFIG_SYSCTL is disabled,
> > - Add warnings for altivec,
> > - Add warnings for recently introduced emulation of vsx and isel
> >   instructions.
> 
> pretty cool.  Do we think counters should be sysfs or debugfs?

What do you prefer?

On MIPS, unaligned exception handling control is in debugfs.

> Also it would be nice to be able to zero out the counters.

By writing to the individual counters, or by writing to a global `clear' file?

BTW, should the individual counters be readable by everybody? Currently they're
readable by root only.

With kind regards,

Geert Uytterhoeven
Software Architect

Sony Techsoft Centre Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium

Phone:    +32 (0)2 700 8453
Fax:      +32 (0)2 700 8622
E-mail:   Geert.Uytterhoeven@sonycom.com
Internet: http://www.sony-europe.com/

A division of Sony Europe (Belgium) N.V.
VAT BE 0413.825.160 · RPR Brussels
Fortis · BIC GEBABEBB · IBAN BE41293037680010
Michael Neuling April 6, 2009, 10:43 p.m. UTC | #5
In message <alpine.LRH.2.00.0904061430090.11076@vixen.sonytel.be> you wrote:
> On Fri, 3 Apr 2009, Kumar Gala wrote:
> > On Apr 3, 2009, at 7:08 AM, Geert Uytterhoeven wrote:
> > >Finally (after ca. 1.5 years), he're an updated version of my patch to k=
> eep
> > >track of emulated instructions.  In the light of Kumar's `Emulate enough=
>  of
> > >SPE
> > >instructions to make gcc happy' patch, he probably also wants to keep tr=
> ack
> > >of
> > >the actual runtime overhead.
> > >
> > >Changes since last version:
> > > - arch/powerpc/kernel/sysfs.c is now compiled on ppc32, so we can provi=
> de
> > >   counters in sysfs on ppc32, too,
> > > - WARN_EMULATED() is a no-op if CONFIG_SYSCTL is disabled,
> > > - Add warnings for altivec,
> > > - Add warnings for recently introduced emulation of vsx and isel
> > >   instructions.
> > =
> 
> > pretty cool.  Do we think counters should be sysfs or debugfs?
> 
> What do you prefer?
> 
> On MIPS, unaligned exception handling control is in debugfs.

Would per process counters be too hard?  Stick them in the thread_struct
and export them via /proc/<pid>/emulated. 

Mikey

> 
> > Also it would be nice to be able to zero out the counters.
> 
> By writing to the individual counters, or by writing to a global `clear' fi=
> le?
> 
> BTW, should the individual counters be readable by everybody? Currently the=
> y're
> readable by root only.
> 
> With kind regards,
> 
> Geert Uytterhoeven
> Software Architect
> 
> Sony Techsoft Centre Europe
> The Corporate Village =B7 Da Vincilaan 7-D1 =B7 B-1935 Zaventem =B7 Belgium
> 
> Phone:    +32 (0)2 700 8453
> Fax:      +32 (0)2 700 8622
> E-mail:   Geert.Uytterhoeven@sonycom.com
> Internet: http://www.sony-europe.com/
> 
> A division of Sony Europe (Belgium) N.V.
> VAT BE 0413.825.160 =B7 RPR Brussels
> Fortis =B7 BIC GEBABEBB =B7 IBAN BE41293037680010
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
>
Geert Uytterhoeven April 7, 2009, 7:26 a.m. UTC | #6
On Tue, 7 Apr 2009, Michael Neuling wrote:
> In message <alpine.LRH.2.00.0904061430090.11076@vixen.sonytel.be> you wrote:
> > On Fri, 3 Apr 2009, Kumar Gala wrote:
> > > On Apr 3, 2009, at 7:08 AM, Geert Uytterhoeven wrote:
> > > >Finally (after ca. 1.5 years), he're an updated version of my patch to k=
> > eep
> > > >track of emulated instructions.  In the light of Kumar's `Emulate enough=
> >  of
> > > >SPE
> > > >instructions to make gcc happy' patch, he probably also wants to keep tr=
> > ack
> > > >of
> > > >the actual runtime overhead.
> > > >
> > > >Changes since last version:
> > > > - arch/powerpc/kernel/sysfs.c is now compiled on ppc32, so we can provi=
> > de
> > > >   counters in sysfs on ppc32, too,
> > > > - WARN_EMULATED() is a no-op if CONFIG_SYSCTL is disabled,
> > > > - Add warnings for altivec,
> > > > - Add warnings for recently introduced emulation of vsx and isel
> > > >   instructions.
> > > =
> > 
> > > pretty cool.  Do we think counters should be sysfs or debugfs?
> > 
> > What do you prefer?
> > 
> > On MIPS, unaligned exception handling control is in debugfs.
> 
> Would per process counters be too hard?  Stick them in the thread_struct
> and export them via /proc/<pid>/emulated. 

But they go away as soon as the process exits, right?

With kind regards,

Geert Uytterhoeven
Software Architect

Sony Techsoft Centre Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium

Phone:    +32 (0)2 700 8453
Fax:      +32 (0)2 700 8622
E-mail:   Geert.Uytterhoeven@sonycom.com
Internet: http://www.sony-europe.com/

A division of Sony Europe (Belgium) N.V.
VAT BE 0413.825.160 · RPR Brussels
Fortis · BIC GEBABEBB · IBAN BE41293037680010
Michael Neuling April 7, 2009, 8:05 a.m. UTC | #7
In message <alpine.LRH.2.00.0904070926001.17130@vixen.sonytel.be> you wrote:
> On Tue, 7 Apr 2009, Michael Neuling wrote:
> > In message <alpine.LRH.2.00.0904061430090.11076@vixen.sonytel.be> you wrote
:
> > > On Fri, 3 Apr 2009, Kumar Gala wrote:
> > > > On Apr 3, 2009, at 7:08 AM, Geert Uytterhoeven wrote:
> > > > >Finally (after ca. 1.5 years), he're an updated version of my patch to
 k=
> > > eep
> > > > >track of emulated instructions.  In the light of Kumar's `Emulate enou
gh=
> > >  of
> > > > >SPE
> > > > >instructions to make gcc happy' patch, he probably also wants to keep 
tr=
> > > ack
> > > > >of
> > > > >the actual runtime overhead.
> > > > >
> > > > >Changes since last version:
> > > > > - arch/powerpc/kernel/sysfs.c is now compiled on ppc32, so we can pro
vi=
> > > de
> > > > >   counters in sysfs on ppc32, too,
> > > > > - WARN_EMULATED() is a no-op if CONFIG_SYSCTL is disabled,
> > > > > - Add warnings for altivec,
> > > > > - Add warnings for recently introduced emulation of vsx and isel
> > > > >   instructions.
> > > > =
> > > 
> > > > pretty cool.  Do we think counters should be sysfs or debugfs?
> > > 
> > > What do you prefer?
> > > 
> > > On MIPS, unaligned exception handling control is in debugfs.
> > 
> > Would per process counters be too hard?  Stick them in the thread_struct
> > and export them via /proc/<pid>/emulated. 
> 
> But they go away as soon as the process exits, right?

True.  

taskstats would be better then but you'd have to start touching generic
code for that.

Mikey
Geert Uytterhoeven April 29, 2009, 12:43 p.m. UTC | #8
On Mon, 6 Apr 2009, Geert Uytterhoeven wrote:
> On Fri, 3 Apr 2009, Kumar Gala wrote:
> > On Apr 3, 2009, at 7:08 AM, Geert Uytterhoeven wrote:
> > >Finally (after ca. 1.5 years), he're an updated version of my patch to keep
> > >track of emulated instructions.  In the light of Kumar's `Emulate enough of
> > >SPE
> > >instructions to make gcc happy' patch, he probably also wants to keep track
> > >of
> > >the actual runtime overhead.
> > >
> > >Changes since last version:
> > > - arch/powerpc/kernel/sysfs.c is now compiled on ppc32, so we can provide
> > >   counters in sysfs on ppc32, too,
> > > - WARN_EMULATED() is a no-op if CONFIG_SYSCTL is disabled,
> > > - Add warnings for altivec,
> > > - Add warnings for recently introduced emulation of vsx and isel
> > >   instructions.
> > 
> > pretty cool.  Do we think counters should be sysfs or debugfs?
> 
> What do you prefer?
> 
> On MIPS, unaligned exception handling control is in debugfs.

And probably debugfs is better, so it's disabled on production systems.
But I would drop the per-CPU counters, and keep global counters only, for
simplicity.

> > Also it would be nice to be able to zero out the counters.
> 
> By writing to the individual counters, or by writing to a global `clear' file?

With debugfs, it's quite easy to make them writable, so you can easily clear
them by writing zeroes to the virtual files.

If people agree, I'll find a time hole and start updating the code...

With kind regards,

Geert Uytterhoeven
Software Architect
Techsoft Centre

Technology and Software Centre Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium

Phone:    +32 (0)2 700 8453
Fax:      +32 (0)2 700 8622
E-mail:   Geert.Uytterhoeven@sonycom.com
Internet: http://www.sony-europe.com/

A division of Sony Europe (Belgium) N.V.
VAT BE 0413.825.160 · RPR Brussels
Fortis · BIC GEBABEBB · IBAN BE41293037680010
diff mbox

Patch

diff --git a/arch/powerpc/include/asm/emulated_ops.h b/arch/powerpc/include/asm/emulated_ops.h
new file mode 100644
index 0000000..e655034
--- /dev/null
+++ b/arch/powerpc/include/asm/emulated_ops.h
@@ -0,0 +1,63 @@ 
+/*
+ *  Copyright 2007 Sony Corp.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _ASM_POWERPC_EMULATED_OPS_H
+#define _ASM_POWERPC_EMULATED_OPS_H
+
+#include <linux/percpu.h>
+
+#include <asm/atomic.h>
+
+#ifdef CONFIG_ALTIVEC
+DECLARE_PER_CPU(atomic_long_t, emulated_altivec);
+#endif
+DECLARE_PER_CPU(atomic_long_t, emulated_dcba);
+DECLARE_PER_CPU(atomic_long_t, emulated_dcbz);
+DECLARE_PER_CPU(atomic_long_t, emulated_fp_pair);
+DECLARE_PER_CPU(atomic_long_t, emulated_isel);
+DECLARE_PER_CPU(atomic_long_t, emulated_mcrxr);
+DECLARE_PER_CPU(atomic_long_t, emulated_mfpvr);
+DECLARE_PER_CPU(atomic_long_t, emulated_multiple);
+DECLARE_PER_CPU(atomic_long_t, emulated_popcntb);
+DECLARE_PER_CPU(atomic_long_t, emulated_spe);
+DECLARE_PER_CPU(atomic_long_t, emulated_string);
+#ifdef CONFIG_MATH_EMULATION
+DECLARE_PER_CPU(atomic_long_t, emulated_math);
+#elif defined(CONFIG_8XX_MINIMAL_FPEMU)
+DECLARE_PER_CPU(atomic_long_t, emulated_8xx);
+#endif
+#ifdef CONFIG_VSX
+DECLARE_PER_CPU(atomic_long_t, emulated_vsx);
+#endif
+
+extern void warn_emulated_print(const char *type);
+
+#ifdef CONFIG_SYSCTL
+extern int sysctl_warn_emulated;
+#else
+#define sysctl_warn_emulated		0
+#endif
+
+#define WARN_EMULATED(type)						\
+	do {								\
+		atomic_long_inc(&per_cpu(emulated_ ## type,		\
+					 raw_smp_processor_id()));	\
+		if (sysctl_warn_emulated)				\
+			warn_emulated_print(#type);			\
+	} while (0)
+
+#endif /* _ASM_POWERPC_EMULATED_OPS_H */
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index 5ffcfaa..0f3c31b 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -24,6 +24,7 @@ 
 #include <asm/system.h>
 #include <asm/cache.h>
 #include <asm/cputable.h>
+#include <asm/emulated_ops.h>
 
 struct aligninfo {
 	unsigned char len;
@@ -730,8 +731,10 @@  int fix_alignment(struct pt_regs *regs)
 	areg = dsisr & 0x1f;		/* register to update */
 
 #ifdef CONFIG_SPE
-	if ((instr >> 26) == 0x4)
+	if ((instr >> 26) == 0x4) {
+		WARN_EMULATED(spe);
 		return emulate_spe(regs, reg, instr);
+	}
 #endif
 
 	instr = (dsisr >> 10) & 0x7f;
@@ -783,23 +786,28 @@  int fix_alignment(struct pt_regs *regs)
 			flags |= SPLT;
 			nb = 8;
 		}
+		WARN_EMULATED(vsx);
 		return emulate_vsx(addr, reg, areg, regs, flags, nb);
 	}
 #endif
 	/* A size of 0 indicates an instruction we don't support, with
 	 * the exception of DCBZ which is handled as a special case here
 	 */
-	if (instr == DCBZ)
+	if (instr == DCBZ) {
+		WARN_EMULATED(dcbz);
 		return emulate_dcbz(regs, addr);
+	}
 	if (unlikely(nb == 0))
 		return 0;
 
 	/* Load/Store Multiple instructions are handled in their own
 	 * function
 	 */
-	if (flags & M)
+	if (flags & M) {
+		WARN_EMULATED(multiple);
 		return emulate_multiple(regs, addr, reg, nb,
 					flags, instr, swiz);
+	}
 
 	/* Verify the address of the operand */
 	if (unlikely(user_mode(regs) &&
@@ -816,8 +824,10 @@  int fix_alignment(struct pt_regs *regs)
 	}
 
 	/* Special case for 16-byte FP loads and stores */
-	if (nb == 16)
+	if (nb == 16) {
+		WARN_EMULATED(fp_pair);
 		return emulate_fp_pair(addr, reg, flags);
+	}
 
 	/* If we are loading, get the data from user space, else
 	 * get it from register values
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index f41aec8..344d03f 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -17,6 +17,7 @@ 
 #include <asm/prom.h>
 #include <asm/machdep.h>
 #include <asm/smp.h>
+#include <asm/emulated_ops.h>
 
 #include "cacheinfo.h"
 
@@ -322,12 +323,82 @@  static struct sysdev_attribute pa6t_attrs[] = {
 #endif /* HAS_PPC_PMC_PA6T */
 #endif /* HAS_PPC_PMC_CLASSIC */
 
+#define SYSFS_EMULATED_SETUP(type)					\
+DEFINE_PER_CPU(atomic_long_t, emulated_ ## type);			\
+static ssize_t show_emulated_ ## type (struct sys_device *dev,		\
+				       struct sysdev_attribute *attr,	\
+				       char *buf)			\
+{									\
+	struct cpu *cpu = container_of(dev, struct cpu, sysdev);	\
+									\
+	return sprintf(buf, "%lu\n",					\
+		       atomic_long_read(&per_cpu(emulated_ ## type,	\
+					cpu->sysdev.id)));		\
+}									\
+									\
+static struct sysdev_attribute emulated_ ## type ## _attr = {		\
+	.attr = { .name = #type, .mode = 0400 },			\
+	.show = show_emulated_ ## type,					\
+};
+
+#ifdef CONFIG_ALTIVEC
+SYSFS_EMULATED_SETUP(altivec);
+#endif
+SYSFS_EMULATED_SETUP(dcba);
+SYSFS_EMULATED_SETUP(dcbz);
+SYSFS_EMULATED_SETUP(fp_pair);
+SYSFS_EMULATED_SETUP(isel);
+SYSFS_EMULATED_SETUP(mcrxr);
+SYSFS_EMULATED_SETUP(mfpvr);
+SYSFS_EMULATED_SETUP(multiple);
+SYSFS_EMULATED_SETUP(popcntb);
+SYSFS_EMULATED_SETUP(spe);
+SYSFS_EMULATED_SETUP(string);
+#ifdef CONFIG_MATH_EMULATION
+SYSFS_EMULATED_SETUP(math);
+#elif defined(CONFIG_8XX_MINIMAL_FPEMU)
+SYSFS_EMULATED_SETUP(8xx);
+#endif
+#ifdef CONFIG_VSX
+SYSFS_EMULATED_SETUP(vsx);
+#endif
+
+static struct attribute *emulated_attrs[] = {
+#ifdef CONFIG_ALTIVEC
+	&emulated_altivec_attr.attr,
+#endif
+	&emulated_dcba_attr.attr,
+	&emulated_dcbz_attr.attr,
+	&emulated_fp_pair_attr.attr,
+	&emulated_isel_attr.attr,
+	&emulated_mcrxr_attr.attr,
+	&emulated_mfpvr_attr.attr,
+	&emulated_multiple_attr.attr,
+	&emulated_popcntb_attr.attr,
+	&emulated_spe_attr.attr,
+	&emulated_string_attr.attr,
+#ifdef CONFIG_MATH_EMULATION
+	&emulated_math_attr.attr,
+#elif defined(CONFIG_8XX_MINIMAL_FPEMU)
+	&emulated_8xx_attr.attr,
+#endif
+#ifdef CONFIG_VSX
+	&emulated_vsx_attr.attr,
+#endif
+	NULL
+};
+
+static struct attribute_group emulated_attr_group = {
+	.attrs = emulated_attrs,
+	.name = "emulated"
+};
+
 static void __cpuinit register_cpu_online(unsigned int cpu)
 {
 	struct cpu *c = &per_cpu(cpu_devices, cpu);
 	struct sys_device *s = &c->sysdev;
 	struct sysdev_attribute *attrs, *pmc_attrs;
-	int i, nattrs;
+	int i, nattrs, res;
 
 #ifdef CONFIG_PPC64
 	if (!firmware_has_feature(FW_FEATURE_ISERIES) &&
@@ -387,6 +458,11 @@  static void __cpuinit register_cpu_online(unsigned int cpu)
 #endif /* CONFIG_PPC64 */
 
 	cacheinfo_cpu_online(cpu);
+
+	res = sysfs_create_group(&s->kobj, &emulated_attr_group);
+	if (res)
+		pr_warning("Cannot create emulated sysfs group for cpu %u\n",
+			   cpu);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 678fbff..6cf1e13 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -33,7 +33,9 @@ 
 #include <linux/backlight.h>
 #include <linux/bug.h>
 #include <linux/kdebug.h>
+#include <linux/sysctl.h>
 
+#include <asm/emulated_ops.h>
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -757,36 +759,44 @@  static int emulate_instruction(struct pt_regs *regs)
 
 	/* Emulate the mfspr rD, PVR. */
 	if ((instword & PPC_INST_MFSPR_PVR_MASK) == PPC_INST_MFSPR_PVR) {
+		WARN_EMULATED(mfpvr);
 		rd = (instword >> 21) & 0x1f;
 		regs->gpr[rd] = mfspr(SPRN_PVR);
 		return 0;
 	}
 
 	/* Emulating the dcba insn is just a no-op.  */
-	if ((instword & PPC_INST_DCBA_MASK) == PPC_INST_DCBA)
+	if ((instword & PPC_INST_DCBA_MASK) == PPC_INST_DCBA) {
+		WARN_EMULATED(dcba);
 		return 0;
+	}
 
 	/* Emulate the mcrxr insn.  */
 	if ((instword & PPC_INST_MCRXR_MASK) == PPC_INST_MCRXR) {
 		int shift = (instword >> 21) & 0x1c;
 		unsigned long msk = 0xf0000000UL >> shift;
 
+		WARN_EMULATED(mcrxr);
 		regs->ccr = (regs->ccr & ~msk) | ((regs->xer >> shift) & msk);
 		regs->xer &= ~0xf0000000UL;
 		return 0;
 	}
 
 	/* Emulate load/store string insn. */
-	if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING)
+	if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING) {
+		WARN_EMULATED(string);
 		return emulate_string_inst(regs, instword);
+	}
 
 	/* Emulate the popcntb (Population Count Bytes) instruction. */
 	if ((instword & PPC_INST_POPCNTB_MASK) == PPC_INST_POPCNTB) {
+		WARN_EMULATED(popcntb);
 		return emulate_popcntb_inst(regs, instword);
 	}
 
 	/* Emulate isel (Integer Select) instruction */
 	if ((instword & PPC_INST_ISEL_MASK) == PPC_INST_ISEL) {
+		WARN_EMULATED(isel);
 		return emulate_isel(regs, instword);
 	}
 
@@ -984,6 +994,8 @@  void SoftwareEmulation(struct pt_regs *regs)
 
 #ifdef CONFIG_MATH_EMULATION
 	errcode = do_mathemu(regs);
+	if (errcode >= 0)
+		WARN_EMULATED(math);
 
 	switch (errcode) {
 	case 0:
@@ -1005,6 +1017,9 @@  void SoftwareEmulation(struct pt_regs *regs)
 
 #elif defined(CONFIG_8XX_MINIMAL_FPEMU)
 	errcode = Soft_emulate_8xx(regs);
+	if (errcode >= 0)
+		WARN_EMULATED(8xx);
+
 	switch (errcode) {
 	case 0:
 		emulate_single_step(regs);
@@ -1088,6 +1103,7 @@  void altivec_assist_exception(struct pt_regs *regs)
 
 	flush_altivec_to_thread(current);
 
+	WARN_EMULATED(altivec);
 	err = emulate_altivec(regs);
 	if (err == 0) {
 		regs->nip += 4;		/* skip emulated instruction */
@@ -1286,3 +1302,43 @@  void kernel_bad_stack(struct pt_regs *regs)
 void __init trap_init(void)
 {
 }
+
+#ifdef CONFIG_SYSCTL
+int sysctl_warn_emulated;
+
+static ctl_table warn_emulated_ctl_table[] = {
+	{
+		.procname	= "cpu_emulation_warnings",
+		.data		= &sysctl_warn_emulated,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
+	{}
+};
+
+static ctl_table warn_emulated_sysctl_root[] = {
+	{
+		.ctl_name	= CTL_KERN,
+		.procname	= "kernel",
+		.mode		= 0555,
+		.child		= warn_emulated_ctl_table,
+	},
+	{}
+};
+
+void warn_emulated_print(const char *type)
+{
+	if (printk_ratelimit())
+		pr_warning("%s used emulated %s instruction\n", current->comm,
+			   type);
+}
+
+static inline int __init warn_emulated_sysctl_register(void)
+{
+	register_sysctl_table(warn_emulated_sysctl_root);
+	return 0;
+}
+
+device_initcall(warn_emulated_sysctl_register);
+#endif /* !CONFIG_SYSCTL */