P9 ldmx support
All -
These are patches based on next to support the forthcoming ldmx instruction through the existing P8 EBB infrastructure. Obviously it doesn't actually *work* without some other patches and a P9 system, but with the context switch change to FSCR it makes sense to get this upstream for testing ASAP.
The first patch context switches FSCR per thread so that the second patch can lazily enable this feature (FSCR.LM) with a facility unavailable exception and context switch two new ldmx registers (LMRR / LMSER) per thread as well. Third patch is a couple of basic tests.
Any comments welcome.
- Jack
PATCH 1/3 powerpc: Complete FSCR context switch
Previously we just saved the FSCR, but only restored it in some settings, and never copied it thread to thread. This patch always restores the FSCR and formalizes new threads inheriting its setting so that later we can manipulate FSCR bits in start_thread.
--- arch/powerpc/kernel/process.c | 7 +++++++ 1 file changed, 7 insertions(+)
arch/powerpc/kernel/process.c +7 -0
@@ -1043,6 +1043,10 @@ static inline void restore_sprs(struct thread_struct *old_thread,if (old_thread->tar != new_thread->tar)mtspr (SPRN_TAR , new_thread->tar); + +if (old_thread->fscr != new_thread->fscr) + mtspr(SPRN_FSCR, new_thread->fscr); + }#endif }
@@ -1478,6 +1482,9 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, }if (cpu_has_feature (CPU_FTR_HAS_PPR )) p->thread.ppr =INIT_PPR ; + +if (cpu_has_feature (CPU_FTR_ARCH_207S )) + p->thread.fscr =mfspr (SPRN_FSCR );#endif kregs->nip =ppc_function_entry (f);return 0 ;
Signature · 1 line
2.8.0
Michael Ellerman
reviewerRe: [1/3] powerpc: Complete FSCR context switch
Quoted 4 lines · Jack Miller
Previously we just saved the FSCR, but only restored it in some settings, and never copied it thread to thread. This patch always restores the FSCR and formalizes new threads inheriting its setting so that later we can manipulate FSCR bits in
start_thread.
This seems like it's a bug in the current code?
cheers
Re: [PATCH 1/3] powerpc: Complete FSCR context switch
In reply to Jack MillerHi Jack,
Quoted 4 lines
Previously we just saved the FSCR, but only restored it in some settings, and never copied it thread to thread. This patch always restores the FSCR and formalizes new threads inheriting its setting so that later we can manipulate FSCR bits in
start_thread.
Will this break the existing FSCR_DSCR bit handling?
if (cpu_has_feature(CPU_FTR_DSCR)) {
u64 dscr = get_paca()->dscr_default;
u64 fscr = old_thread->fscr & ~FSCR_DSCR;
if (new_thread->dscr_inherit) {
dscr = new_thread->dscr;
fscr |= FSCR_DSCR;
}
if (old_thread->dscr != dscr)
mtspr(SPRN_DSCR, dscr);
if (old_thread->fscr != fscr)
mtspr(SPRN_FSCR, fscr);
}If not, we should modify the above so we don't write the FSCR twice.
Anton
Re: [PATCH 1/3] powerpc: Complete FSCR context switch
Hi Anton.
Quoted 25 lines · Anton Blanchard
Hi Jack,
Quoted 4 lines
Previously we just saved the FSCR, but only restored it in some settings, and never copied it thread to thread. This patch always restores the FSCR and formalizes new threads inheriting its setting so that later we can manipulate FSCR bits in
start_thread.Will this break the existing
FSCR_DSCRbit handling?if (cpu_has_feature(CPU_FTR_DSCR)) { u64 dscr = get_paca()->dscr_default; u64 fscr = old_thread->fscr & ~FSCR_DSCR; if (new_thread->dscr_inherit) { dscr = new_thread->dscr; fscr |= FSCR_DSCR; } if (old_thread->dscr != dscr) mtspr(SPRN_DSCR, dscr); if (old_thread->fscr != fscr) mtspr(SPRN_FSCR, fscr); }
Quoted 1 line
If not, we should modify the above so we don't write the FSCR twice.
I think this code is just partially redundant. I think it's trying to predict the right FSCR value based on this dscr_inherit flag. Now that we fully switch it, we could skip setting FSCR here, and just set DSCR if FSCR.DSCR is set (similar to what my patches do with FSCR.LM). In fact, we might be able to just entirely get rid of the dscr_inherit flag, but I'd have to look harder at that.
Right now the FSCR switch is conditional on FTR_ARCH_207S which is more exclusive than FTR_DSCR, but I guess the actual FSCR register is universal to PPC64 like the fscr field in the thread struct? If so, I can just move the FSCR save/restore out of the 207 conditional.
Anyway, I'll clean this up a bit, add the little asm tweak from Segher, and put another spin on the list.
- Jack
Re: [PATCH 1/3] powerpc: Complete FSCR context switch
Quoted 10 lines · Jack Miller
Hi Anton.
=20Quoted 6 lines · Anton Blanchard
Hi Jack,
=20Quoted 3 lines
Previously we just saved the FSCR, but only restored it in some settings, and never copied it thread to thread. This patch always restores the FSCR and formalizes new threads inheriting its setting s=
o
Quoted 21 lines
Quoted 19 lines
Quoted 1 line
that later we can manipulate FSCR bits in
start_thread.=20
Will this break the existingFSCR_DSCRbit handling? =20if (cpu_has_feature(CPU_FTR_DSCR)) { u64 dscr =3D get_paca()->dscr_default; u64 fscr =3D old_thread->fscr & ~FSCR_DSCR; =20 if (new_thread->dscr_inherit) { dscr =3D new_thread->dscr; fscr |=3D FSCR_DSCR; } =20 if (old_thread->dscr !=3D dscr) mtspr(SPRN_DSCR, dscr); =20 if (old_thread->fscr !=3D fscr) mtspr(SPRN_FSCR, fscr); }Quoted 2 lines
=20
If not, we should modify the above so we don't write the FSCR twice.
Quoted 7 lines
=20
I think this code is just partially redundant. I think it's trying to predict the right FSCR value based on thisdscr_inheritflag. Now that we fully switch it, we could skip setting FSCR here, and just set DSCR if FSCR.DSCR is set (similar to what my patches do with FSCR.LM). In fact, we might be able to just entirely get rid of thedscr_inheritflag, but I'd have to look harder at that.
I'm not sure that works on processes before power8.
There DSCR SPR number 0x11 will always trap and emulate from userspace (see arch/powerpc/kernel/traps.c:emulate_instruction()). That is not controlled by FSCR and should work on POWER7 where FSCR is not present. We need to set the inherit bit there too.
DSCR SPR number 0x3 is controlled by fscr, but it's only avaliable on POWER8.
Quoted 4 lines
Right now the FSCR switch is conditional on
FTR_ARCH_207Swhich is more exclusive thanFTR_DSCR, but I guess the actual FSCR register is universal to PPC64 like the fscr field in the thread struct? If so, I can just move the FSCR save/restore out of the 207 conditional.
FSCR was only introduced in power8, so it needs to be 207 conditional
Mikey
Quoted 6 lines
=20
Anyway, I'll clean this up a bit, add the little asm tweak from Segher, and put another spin on the list.
=20
- Jack
=20
Re: [PATCH 1/3] powerpc: Complete FSCR context switch
Quoted 10 lines
I'm not sure that works on processes before power8.
There DSCR SPR number
0x11will always trap and emulate from userspace (see arch/powerpc/kernel/traps.c:emulate_instruction()). That is not controlled by FSCR and should work on POWER7 where FSCR is not present. We need to set the inherit bit there too.DSCR SPR number
0x3is controlled by fscr, but it's only avaliable on POWER8.
Quoted 7 lines
Quoted 4 lines
Right now the FSCR switch is conditional on
FTR_ARCH_207Swhich is more exclusive thanFTR_DSCR, but I guess the actual FSCR register is universal to PPC64 like the fscr field in the thread struct? If so, I can just move the FSCR save/restore out of the 207 conditional.FSCR was only introduced in power8, so it needs to be 207 conditional
So on P6/P7 (which have FTR_DSCR) set we're potentially mtspr'ing to a non-existent register? Yuck. Can at least strip that logic out thanks to the full context switch, I think, even if dscr_inherit actually has a use.
- Jack
Re: [PATCH 1/3] powerpc: Complete FSCR context switch
Quoted 15 lines · Jack Miller
Quoted 15 lines
I'm not sure that works on processes before power8.
=20
There DSCR SPR number0x11will always trap and emulate from userspace (see arch/powerpc/kernel/traps.c:emulate_instruction()). That is not controlled by FSCR and should work on POWER7 where FSCR is not present. We need to set the inherit bit there too.
=20
DSCR SPR number0x3is controlled by fscr, but it's only avaliable on POWER8.
=20Quoted 4 lines
Right now the FSCR switch is conditional on
FTR_ARCH_207Swhich is more exclusive thanFTR_DSCR, but I guess the actual FSCR register is universal to PPC64 like the fscr field in the thread struct? If so, I can just move the FSCR save/restore out of the 207 conditional.
Quoted 8 lines
Quoted 3 lines
=20
FSCR was only introduced in power8, so it needs to be 207 conditional =20=20
So on P6/P7 (which haveFTR_DSCR) set we're potentially mtspr'ing to a non-existent register? Yuck. Can at least strip that logic out thanks to the full context switch, I think, even ifdscr_inheritactually has a use.
Yeah, welcome to DSCR... it's horrible. :-(
It's not actually non-existent. It's just OS only privileged.
Not that that makes much difference, as we still trap and emulate (and set the inherent bit).
Mikey
PATCH 2/3 powerpc: Load Monitor Register Support
In reply to Jack MillerThis enables new registers, LMRR and LMSER, that can trigger an EBB in userspace code when a monitored load (via the new ldmx instruction) loads memory from a monitored space. This facility is controlled by a new FSCR bit, LM.
This patch disables the control bit on CPU setup and enables that bit when a facility unavailable exception is taken for using it. On context switch, this bit is then used to determine whether the two relevant registers are saved and restored. This is done lazily for performance reasons.
--- arch/powerpc/include/asm/processor.h | 2 ++ arch/powerpc/include/asm/reg.h | 5 +++++ arch/powerpc/kernel/cpu_setup_power.S | 1 + arch/powerpc/kernel/process.c | 19 +++++++++++++++++++ arch/powerpc/kernel/traps.c | 4 ++++ 5 files changed, 31 insertions(+)
arch/powerpc/include/asm/processor.h +2 -0
@@ -314,6 +314,8 @@ struct thread_struct {unsigned long mmcr2;unsigned mmcr0;unsigned used_ebb; +unsigned long lmrr; +unsigned long lmser;#endif };
arch/powerpc/include/asm/reg.h +5 -0
@@ -282,6 +282,8 @@#define SPRN_HRMOR 0x139/* Real mode offset register */ #define SPRN_HSRR0 0x13A/* Hypervisor Save/Restore 0 */ #define SPRN_HSRR1 0x13B/* Hypervisor Save/Restore 1 */ +#define SPRN_LMRR 0x32D/* Load Monitor Region Register */ +#define SPRN_LMSER 0x32E/* Load Monitor Section Enable Register */ #define SPRN_IC 0x350/* Virtual Instruction Count */ #define SPRN_VTB 0x351/* Virtual Time Base */ #define SPRN_LDBAR 0x352/* LD Base Address Register */
@@ -291,6 +293,7 @@#define SPRN_PMCR 0x374/* Power Management Control Register */ /* HFSCR and FSCR bit numbers are the same */ +#define FSCR_LM_LG 11/* Enable Load Monitor Registers */ #define FSCR_TAR_LG 8/* Enable Target Address Register */ #define FSCR_EBB_LG 7/* Enable Event Based Branching */ #define FSCR_TM_LG 5/* Enable Transactional Memory */
@@ -300,10 +303,12 @@#define FSCR_VECVSX_LG 1/* Enable VMX/VSX */ #define FSCR_FP_LG 0/* Enable Floating Point */ #define SPRN_FSCR 0x099/* Facility Status & Control Register */ +#define FSCR_LM __MASK(FSCR_LM_LG)#define FSCR_TAR __MASK(FSCR_TAR_LG)#define FSCR_EBB __MASK(FSCR_EBB_LG)#define FSCR_DSCR __MASK(FSCR_DSCR_LG)#define SPRN_HFSCR 0xbe/* HV=1 Facility Status & Control Register */ +#define HFSCR_LM __MASK(FSCR_LM_LG)#define HFSCR_TAR __MASK(FSCR_TAR_LG)#define HFSCR_EBB __MASK(FSCR_EBB_LG)#define HFSCR_TM __MASK(FSCR_TM_LG)
arch/powerpc/kernel/cpu_setup_power.S +1 -0
@@ -157,6 +157,7 @@ __init_LPCR: __init_FSCR: mfspr r3,SPRN_FSCR + andi. r3,r3,(~FSCR_LM)@L ori r3,r3,FSCR_TAR|FSCR_DSCR|FSCR_EBB mtspr SPRN_FSCR,r3 blr
arch/powerpc/kernel/process.c +19 -0
@@ -1005,6 +1005,14 @@ static inline void save_sprs(struct thread_struct *t)*/ t->tar = mfspr(SPRN_TAR); } + +if (cpu_has_feature (CPU_FTR_ARCH_300 )) { +/* Conditionally save Load Monitor registers, if enabled */ +if (t->fscr &FSCR_LM ) { + t->lmrr =mfspr (SPRN_LMRR ); + t->lmser =mfspr (SPRN_LMSER ); + } + }#endif }
@@ -1046,7 +1054,16 @@ static inline void restore_sprs(struct thread_struct *old_thread,if (old_thread->fscr != new_thread->fscr) mtspr(SPRN_FSCR, new_thread->fscr); + } +if (cpu_has_feature (CPU_FTR_ARCH_300 )) { +/* Conditionally restore Load Monitor registers, if enabled */ +if (new_thread->fscr &FSCR_LM ) { +if (old_thread->lmrr != new_thread->lmrr); +mtspr (SPRN_LMRR , new_thread->lmrr); +if (old_thread->lmser != new_thread->lmser); +mtspr (SPRN_LMSER , new_thread->lmser); + } }#endif }
@@ -1573,6 +1590,8 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) regs->gpr[2 ] =0 ; regs->msr = MSR_USER32; } + + current->thread.fscr &= ~FSCR_LM ;#endif #ifdef CONFIG_VSX current->thread.used_vsr =0 ;
arch/powerpc/kernel/traps.c +4 -0
@@ -1376,6 +1376,7 @@ void facility_unavailable_exception(struct pt_regs *regs) [FSCR_TM_LG] = "TM", [FSCR_EBB_LG] = "EBB", [FSCR_TAR_LG] = "TAR", + [FSCR_LM_LG] = "LM", };char *facility ="unknown" ;u64 value;
@@ -1432,6 +1433,9 @@ void facility_unavailable_exception(struct pt_regs *regs)emulate_single_step (regs); }return ; + }else if ((status ==FSCR_LM_LG ) &&cpu_has_feature (CPU_FTR_ARCH_300 )) { +mtspr (SPRN_FSCR , value |FSCR_LM ); +return ; } if ((status < ARRAY_SIZE(facility_strings)) &&
Signature · 1 line
2.8.0
Re: [PATCH 2/3] powerpc: Load Monitor Register Support
Hi,
arch/powerpc/kernel/cpu_setup_power.S __init_LPCR: · line 163
Quoted 6 lines · Jack Miller
__init_FSCR:arch/powerpc/kernel/cpu_setup_power.S +1
-0mfspr r3,SPRN_FSCR + andi. r3,r3,(~FSCR_LM)@L ori r3,r3,FSCR_TAR|FSCR_DSCR|FSCR_EBB mtspr SPRN_FSCR,r3 blr
This clears the top 48 bits as well. Shouldn't matter currently; but more robust (and easier to read, if you know the idiom) is
ori r3,r3,FSCR_LM|FSCR_TAR|FSCR_DSCR|FSCR_EBB xori r3,r3,FSCR_LM
Segher
Re: [PATCH 2/3] powerpc: Load Monitor Register Support
Thanks, yeah, that's more readable and more correct. I'll change it in the next spin.
- Jack
Quoted 18 lines · Segher Boessenkool
Hi,
Quoted 6 lines · Jack Miller
__init_FSCR:mfspr r3,SPRN_FSCR + andi. r3,r3,(~FSCR_LM)@L ori r3,r3,FSCR_TAR|FSCR_DSCR|FSCR_EBB mtspr SPRN_FSCR,r3blr
This clears the top 48 bits as well. Shouldn't matter currently; but more robust (and easier to read, if you know the idiom) is
ori r3,r3,FSCR_LM|FSCR_TAR|FSCR_DSCR|FSCR_EBB
xori r3,r3,FSCR_LMSegher
PATCH 3/3 powerpc: Load Monitor Register Tests
In reply to Jack MillerAdds two tests. One is a simple test to ensure that the new registers LMRR and LMSER are properly maintained. The other actually uses the existing EBB test infrastructure to test that LMRR and LMSER behave as documented.
--- tools/testing/selftests/powerpc/pmu/ebb/Makefile | 2 +- tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.c | 144 +++++++++++++++++++++ tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.h | 39 ++++++ .../selftests/powerpc/pmu/ebb/ebb_lmr_regs.c | 38 ++++++ tools/testing/selftests/powerpc/pmu/ebb/reg.h | 5 + 5 files changed, 227 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.c create mode 100644 tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.h create mode 100644 tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr_regs.c
tools/testing/selftests/powerpc/pmu/ebb/Makefile +1 -1
@@ -14,7 +14,7 @@ TEST_PROGS := reg_access_test event_attributes_test cycles_test \ fork_cleanup_test ebb_on_child_test \ ebb_on_willing_child_test back_to_back_ebbs_test \ lost_exception_test no_handler_test \ - cycles_with_mmcr2_test + cycles_with_mmcr2_test ebb_lmr ebb_lmr_regs all: $(TEST_PROGS)
tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.c new file +144 -0
144 lines not on this page · raw message
tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.h new file +39 -0
@@ -0,0 +1,39 @@ +#ifndef _SELFTESTS_POWERPC_PMU_EBB_LMR_H +#define _SELFTESTS_POWERPC_PMU_EBB_LMR_H + +#include "reg.h" + +#ifndef PPC_FEATURE2_ARCH_3_00 +#define PPC_FEATURE2_ARCH_3_00 0x00800000 +#endif + +#define lmr_is_supported () have_hwcap2(PPC_FEATURE2_ARCH_3_00) + +static inline void ebb_lmr_reset (void ) +{ +unsigned long bescr =mfspr (SPRN_BESCR ); + bescr &= ~(BESCR_LMEO ); + bescr |=BESCR_LME ; +mtspr (SPRN_BESCR , bescr); +} + +#define LDMX (t, a, b)\ + (0x7c00026a |\ + ((t & 0x1f) << 21) |\ + ((a & 0x1f) << 16) |\ + ((b & 0x1f) << 11)) + +static inline unsigned long ldmx (unsigned long address) +{ +unsigned long ret; + + asmvolatile ("mr 9, %1\r\n" + ".long " __stringify(LDMX(9, 0, 9)) "\r\n" + "mr %0, 9\r\n":"=r"(ret) + :"r"(address) + :"r9"); + +return ret; +} + +#endif
tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr_regs.c new file +38 -0
@@ -0,0 +1,38 @@ +/* +* Copyright 2016, Jack Miller, IBM Corp. +* Licensed under GPLv2. +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> + +#include "ebb.h" +#include "ebb_lmr.h" + +#define CHECKS 10000 + +int ebb_lmr_regs (void ) +{ +int i; + +SKIP_IF (!ebb_is_supported ()); +SKIP_IF (!lmr_is_supported ()); + +ebb_global_enable (); + +for (i =0 ; i <CHECKS ; i++) { +mtspr (SPRN_LMRR , i <<25 );// skip size and rsvd bits +mtspr (SPRN_LMSER , i); + +FAIL_IF (mfspr (SPRN_LMRR ) != (i <<25 )); +FAIL_IF (mfspr (SPRN_LMSER ) != i); + } + +return 0 ; +} + +int main (void ) +{ +return test_harness (ebb_lmr_regs,"ebb_lmr_regs" ); +}
tools/testing/selftests/powerpc/pmu/ebb/reg.h +5 -0
@@ -34,6 +34,11 @@#define BESCR_PMEO 0x1/* PMU Event-based exception Occurred */ #define BESCR_PME (0x1ul << 32)/* PMU Event-based exception Enable */ +#define BESCR_LME (0x1ul << 34)/* Load Monitor Enable */ +#define BESCR_LMEO (0x1ul << 2)/* Load Monitor Exception Occurred */ + +#define SPRN_LMRR 813/* Load Monitor Region Register */ +#define SPRN_LMSER 814/* Load Monitor Section Enable Register */ #define SPRN_PMC1 771#define SPRN_PMC2 772
Signature · 1 line
2.8.0
Re: [PATCH 3/3] powerpc: Load Monitor Register Tests
Quoted 123 lines · Jack Miller
Adds two tests. One is a simple test to ensure that the new registers LMRR and LMSER are properly maintained. The other actually uses the existing EBB test infrastructure to test that LMRR and LMSER behave as documented.
Signed-off-by Jack Miller <[email protected]>--- tools/testing/selftests/powerpc/pmu/ebb/Makefile | 2 +- tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.c | 144 +++++++++++++++++++++ tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.h | 39 ++++++ .../selftests/powerpc/pmu/ebb/ebb_lmr_regs.c | 38 ++++++ tools/testing/selftests/powerpc/pmu/ebb/reg.h | 5 + 5 files changed, 227 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.c create mode 100644 tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.h create mode 100644 tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr_regs.ctools/testing/selftests/powerpc/pmu/ebb/Makefile +1
-1@@ -14,7 +14,7 @@ TEST_PROGS := reg_access_test event_attributes_test cycles_test \ fork_cleanup_test ebb_on_child_test \ ebb_on_willing_child_test back_to_back_ebbs_test \ lost_exception_test no_handler_test \ - cycles_with_mmcr2_test + cycles_with_mmcr2_test ebb_lmr ebb_lmr_regs all: $(TEST_PROGS)tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.c new file +87
-0@@ -0,0 +1,144 @@ +/* +* Copyright 2016, Jack Miller, IBM Corp. +* Licensed under GPLv2. +*/ + +#include <stdlib.h> +#include <stdio.h> + +#include "ebb.h" +#include "ebb_lmr.h" + +#define SIZE (32 * 1024 * 1024)/* 32M */ +#define LM_SIZE 0/* Smallest encoding, 32M */ + +#define SECTIONS 64/* 1 per bit in LMSER */ +#define SECTION_SIZE (SIZE / SECTIONS) +#define SECTION_LONGS (SECTION_SIZE / sizeof(long)) + +static unsigned long *test_mem; + +static int lmr_count =0 ; + +void ebb_lmr_handler (void ) +{ + lmr_count++; +} + +void ldmx_full_section (unsigned long *mem,int section) +{ +unsigned long *ptr; +int i; + +for (i =0 ; i <SECTION_LONGS ; i++) { + ptr = &mem[(SECTION_LONGS * section) + i]; +ldmx ((unsigned long ) &ptr); +ebb_lmr_reset (); + } +} + +unsigned long section_masks[] = { +0x8000000000000000 , +0xFF00000000000000 , +0x0000000F70000000 , +0x8000000000000001 , +0xF0F0F0F0F0F0F0F0 , +0x0F0F0F0F0F0F0F0F , +0x0 +}; + +int ebb_lmr_section_test (unsigned long *mem) +{ +unsigned long *mask = section_masks; +int i; + +for (; *mask; mask++) { +mtspr (SPRN_LMSER , *mask); +printf ("Testing mask 0x%016lx\n" ,mfspr (SPRN_LMSER )); + +for (i =0 ; i <64 ; i++) { + lmr_count =0 ; +ldmx_full_section (mem, i); +if (*mask & (1UL << (63 - i))) +FAIL_IF (lmr_count !=SECTION_LONGS ); +else +FAIL_IF (lmr_count); + } + } + +return 0 ; +} + +int ebb_lmr (void ) +{ +int i; + +SKIP_IF (!ebb_is_supported ()); +SKIP_IF (!lmr_is_supported ()); + +setup_ebb_handler (ebb_lmr_handler); + +ebb_global_enable (); + +FAIL_IF (posix_memalign ((void **)&test_mem,SIZE ,SIZE ) !=0 ); + +mtspr (SPRN_LMSER ,0 ); + +FAIL_IF (mfspr (SPRN_LMSER ) !=0 );
tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.c line 97
Quoted 10 lines
tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.c new file +10
-0+ +mtspr (SPRN_LMRR , ((unsigned long )test_mem |LM_SIZE )); + +FAIL_IF (mfspr (SPRN_LMRR ) != ((unsigned long )test_mem |LM_SIZE )); + +/* Read every single byte to ensure we get no false positives */ +for (i =0 ; i <SECTIONS ; i++) +ldmx_full_section (test_mem, i); + +FAIL_IF (lmr_count !=0 );
Another possible addition is to have EBB enabled with LMSER set to zero?
Quoted 152 lines
tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.c new file +47
-0+ +/* Turn on the first section */ + +mtspr (SPRN_LMSER , (1UL <<63 )); +FAIL_IF (mfspr (SPRN_LMSER ) != (1UL <<63 )); + +/* Enable LM (BESCR) */ + +mtspr (SPRN_BESCR ,mfspr (SPRN_BESCR ) |BESCR_LME ); +FAIL_IF (!(mfspr (SPRN_BESCR ) &BESCR_LME )); + +ldmx ((unsigned long )&test_mem); + +FAIL_IF (lmr_count !=1 );// exactly one exception +FAIL_IF (mfspr (SPRN_BESCR ) &BESCR_LME );// LM now disabled +FAIL_IF (!(mfspr (SPRN_BESCR ) &BESCR_LMEO ));// occurred bit set + +printf ("Simple LMR EBB OK\n" ); + +/* This shouldn't cause an EBB since it's been disabled */ +ldmx ((unsigned long )&test_mem); +FAIL_IF (lmr_count !=1 ); + +printf ("LMR disable on EBB OK\n" ); + +ebb_lmr_reset (); + +/* This should cause an EBB or reset is broken */ +ldmx ((unsigned long )&test_mem); +FAIL_IF (lmr_count !=2 ); + +printf ("LMR reset EBB OK\n" ); + +ebb_lmr_reset (); + +return ebb_lmr_section_test (test_mem); +} + +int main (void ) +{ +int ret =test_harness (ebb_lmr,"ebb_lmr" ); + +if (test_mem) +free (test_mem); + +return ret; +}tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.h new file +39
-0@@ -0,0 +1,39 @@ +#ifndef _SELFTESTS_POWERPC_PMU_EBB_LMR_H +#define _SELFTESTS_POWERPC_PMU_EBB_LMR_H + +#include "reg.h" + +#ifndef PPC_FEATURE2_ARCH_3_00 +#define PPC_FEATURE2_ARCH_3_00 0x00800000 +#endif + +#define lmr_is_supported () have_hwcap2(PPC_FEATURE2_ARCH_3_00) + +static inline void ebb_lmr_reset (void ) +{ +unsigned long bescr =mfspr (SPRN_BESCR ); + bescr &= ~(BESCR_LMEO ); + bescr |=BESCR_LME ; +mtspr (SPRN_BESCR , bescr); +} + +#define LDMX (t, a, b)\ + (0x7c00026a |\ + ((t & 0x1f) << 21) |\ + ((a & 0x1f) << 16) |\ + ((b & 0x1f) << 11)) + +static inline unsigned long ldmx (unsigned long address) +{ +unsigned long ret; + + asmvolatile ("mr 9, %1\r\n" + ".long " __stringify(LDMX(9, 0, 9)) "\r\n" + "mr %0, 9\r\n":"=r"(ret) + :"r"(address) + :"r9"); + +return ret; +} + +#endif tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr_regs.c new file +38
-0@@ -0,0 +1,38 @@ +/* +* Copyright 2016, Jack Miller, IBM Corp. +* Licensed under GPLv2. +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> + +#include "ebb.h" +#include "ebb_lmr.h" + +#define CHECKS 10000 + +int ebb_lmr_regs (void ) +{ +int i; + +SKIP_IF (!ebb_is_supported ()); +SKIP_IF (!lmr_is_supported ()); + +ebb_global_enable (); + +for (i =0 ; i <CHECKS ; i++) { +mtspr (SPRN_LMRR , i <<25 );// skip size and rsvd bits +mtspr (SPRN_LMSER , i); + +FAIL_IF (mfspr (SPRN_LMRR ) != (i <<25 )); +FAIL_IF (mfspr (SPRN_LMSER ) != i); + } + +return 0 ; +} + +int main (void ) +{ +return test_harness (ebb_lmr_regs,"ebb_lmr_regs" ); +}tools/testing/selftests/powerpc/pmu/ebb/reg.h +5
-0@@ -34,6 +34,11 @@#define BESCR_PMEO 0x1/* PMU Event-based exception Occurred */ #define BESCR_PME (0x1ul << 32)/* PMU Event-based exception Enable */ +#define BESCR_LME (0x1ul << 34)/* Load Monitor Enable */ +#define BESCR_LMEO (0x1ul << 2)/* Load Monitor Exception Occurred */ + +#define SPRN_LMRR 813/* Load Monitor Region Register */ +#define SPRN_LMSER 814/* Load Monitor Section Enable Register */ #define SPRN_PMC1 771#define SPRN_PMC2 772
Quoted 2 lines
Re: [RFC] P9 ldmx support
These are good to go and don't need to be marked as RFC.
FWIW, we've been testing these internally and they've been solid.
Quoted 5 lines
These are patches based on next to support the forthcoming ldmx instruction through the existing P8 EBB infrastructure. Obviously it doesn't actually *work* without some other patches and a P9 system, but with the context switch change to FSCR it makes sense to get this upstream for testing ASAP.
Yep.
Thanks,
Mikey
Quoted 1 line
The first patch context switches FSCR per thread so that the second patch=
can
Quoted 1 line
lazily enable this feature (FSCR.LM) with a facility unavailable exceptio=
n
Quoted 1 line
and context switch two new ldmx registers (LMRR / LMSER) per thread as we=
ll.
Quoted 1 line
Third patch is a couple of basic tests.