[PATCH v9 44/51] selftest/vm: powerpc implementation for generic abstraction
Introduce powerpc implementation for the different abstactions. Signed-off-by: Ram Pai --- tools/testing/selftests/vm/pkey-helpers.h| 109 ++ tools/testing/selftests/vm/protection_keys.c | 38 ++ 2 files changed, 117 insertions(+), 30 deletions(-) diff --git a/tools/testing/selftests/vm/pkey-helpers.h b/tools/testing/selftests/vm/pkey-helpers.h index 30755be..f764d66 100644 --- a/tools/testing/selftests/vm/pkey-helpers.h +++ b/tools/testing/selftests/vm/pkey-helpers.h @@ -18,27 +18,54 @@ #define u16 uint16_t #define u32 uint32_t #define u64 uint64_t -#define pkey_reg_t u32 -#ifdef __i386__ +#if defined(__i386__) || defined(__x86_64__) /* arch */ + +#ifdef __i386__ /* arch */ #define SYS_mprotect_key 380 -#define SYS_pkey_alloc 381 -#define SYS_pkey_free 382 +#define SYS_pkey_alloc 381 +#define SYS_pkey_free382 #define REG_IP_IDX REG_EIP #define si_pkey_offset 0x14 -#else +#elif __x86_64__ #define SYS_mprotect_key 329 -#define SYS_pkey_alloc 330 -#define SYS_pkey_free 331 +#define SYS_pkey_alloc 330 +#define SYS_pkey_free331 #define REG_IP_IDX REG_RIP #define si_pkey_offset 0x20 -#endif +#endif /* __x86_64__ */ + +#define NR_PKEYS 16 +#define NR_RESERVED_PKEYS 1 +#define PKEY_BITS_PER_PKEY 2 +#define PKEY_DISABLE_ACCESS0x1 +#define PKEY_DISABLE_WRITE 0x2 +#define HPAGE_SIZE (1UL<<21) +#define pkey_reg_t u32 -#define NR_PKEYS 16 -#define PKEY_BITS_PER_PKEY 2 -#define PKEY_DISABLE_ACCESS0x1 -#define PKEY_DISABLE_WRITE 0x2 -#define HPAGE_SIZE (1UL<<21) +#elif __powerpc64__ /* arch */ + +#define SYS_mprotect_key 386 +#define SYS_pkey_alloc 384 +#define SYS_pkey_free 385 +#define si_pkey_offset 0x20 +#define REG_IP_IDX PT_NIP +#define REG_TRAPNO PT_TRAP +#define gregs gp_regs +#define fpregs fp_regs + +#define NR_PKEYS 32 +#define NR_RESERVED_PKEYS_4K 26 +#define NR_RESERVED_PKEYS_64K 3 +#define PKEY_BITS_PER_PKEY 2 +#define PKEY_DISABLE_ACCESS0x3 /* disable read and write */ +#define PKEY_DISABLE_WRITE 0x2 +#define HPAGE_SIZE (1UL<<24) +#define pkey_reg_t u64 + +#else /* arch */ + NOT SUPPORTED +#endif /* arch */ #ifndef DEBUG_LEVEL #define DEBUG_LEVEL 0 @@ -47,7 +74,11 @@ static inline u32 pkey_to_shift(int pkey) { +#if defined(__i386__) || defined(__x86_64__) /* arch */ return pkey * PKEY_BITS_PER_PKEY; +#elif __powerpc64__ /* arch */ + return (NR_PKEYS - pkey - 1) * PKEY_BITS_PER_PKEY; +#endif /* arch */ } static inline pkey_reg_t reset_bits(int pkey, pkey_reg_t bits) @@ -108,6 +139,7 @@ static inline void sigsafe_printf(const char *format, ...) extern pkey_reg_t shadow_pkey_reg; static inline pkey_reg_t __rdpkey_reg(void) { +#if defined(__i386__) || defined(__x86_64__) /* arch */ unsigned int eax, edx; unsigned int ecx = 0; pkey_reg_t pkey_reg; @@ -115,7 +147,13 @@ static inline pkey_reg_t __rdpkey_reg(void) asm volatile(".byte 0x0f,0x01,0xee\n\t" : "=a" (eax), "=d" (edx) : "c" (ecx)); - pkey_reg = eax; +#elif __powerpc64__ /* arch */ + pkey_reg_t eax; + pkey_reg_t pkey_reg; + + asm volatile("mfspr %0, 0xd" : "=r" ((pkey_reg_t)(eax))); +#endif /* arch */ + pkey_reg = (pkey_reg_t)eax; return pkey_reg; } @@ -135,6 +173,7 @@ static inline pkey_reg_t _rdpkey_reg(int line) static inline void __wrpkey_reg(pkey_reg_t pkey_reg) { pkey_reg_t eax = pkey_reg; +#if defined(__i386__) || defined(__x86_64__) /* arch */ pkey_reg_t ecx = 0; pkey_reg_t edx = 0; @@ -143,6 +182,14 @@ static inline void __wrpkey_reg(pkey_reg_t pkey_reg) asm volatile(".byte 0x0f,0x01,0xef\n\t" : : "a" (eax), "c" (ecx), "d" (edx)); assert(pkey_reg == __rdpkey_reg()); + +#elif __powerpc64__ /* arch */ + dprintf4("%s() changing %llx to %llx\n", +__func__, __rdpkey_reg(), pkey_reg); + asm volatile("mtspr 0xd, %0" : : "r" ((unsigned long)(eax)) : "memory"); +#endif /* arch */ + dprintf4("%s() pkey register after changing %016lx to %016lx\n", +__func__, __rdpkey_reg(), pkey_reg); } static inline void wrpkey_reg(pkey_reg_t pkey_reg) @@ -189,6 +236,8 @@ static inline void __pkey_write_allow(int pkey, int do_allow_write) dprintf4("pkey_reg now: %08x\n", rdpkey_reg()); } +#if defined(__i386__) || defined(__x86_64__) /* arch */ + #define PAGE_SIZE 4096 #define MB (1<<20) @@ -271,8 +320,18 @@ static inline void __page_o_noops(void) /* 8-bytes of instruction * 512 bytes = 1 page */ asm(".rept 512 ; nopl 0x7eee(%eax) ; .endr"); } +#elif __powerpc64__ /* arch */ -#endif /* _PKEYS_HELPER_H */ +#define PAGE_SIZE (0x1UL << 16) +static inline int cpu_has_pku(void) +{ + return 1; +} + +/* 8-bytes of instruction * 16384bytes = 1 page */ +#define __page_o_noops() asm(
Re: [PATCH v9 44/51] selftest/vm: powerpc implementation for generic abstraction
Hi Ram, On Mon, Nov 06, 2017 at 12:57:36AM -0800, Ram Pai wrote: > @@ -206,12 +209,14 @@ void signal_handler(int signum, siginfo_t *si, void > *vucontext) > > trapno = uctxt->uc_mcontext.gregs[REG_TRAPNO]; > ip = uctxt->uc_mcontext.gregs[REG_IP_IDX]; > - fpregset = uctxt->uc_mcontext.fpregs; > - fpregs = (void *)fpregset; Since you removed all references for fpregset now, you probably want to remove the declaration of the variable above. > @@ -219,20 +224,21 @@ void signal_handler(int signum, siginfo_t *si, void > *vucontext) >* state. We just assume that it is here. >*/ > fpregs += 0x70; > -#endif > - pkey_reg_offset = pkey_reg_xstate_offset(); With this code, you removed all the reference for variable pkey_reg_offset, thus, its declaration could be removed also. > - *(u64 *)pkey_reg_ptr = 0x; > + dprintf1("si_pkey from siginfo: %lx\n", si_pkey); > +#if defined(__i386__) || defined(__x86_64__) /* arch */ > + dprintf1("signal pkey_reg from xsave: %016lx\n", *pkey_reg_ptr); > + *(u64 *)pkey_reg_ptr &= reset_bits(si_pkey, PKEY_DISABLE_ACCESS); > +#elif __powerpc64__ Since the variable pkey_reg_ptr is only used for Intel code (inside #ifdefs), you probably want to #ifdef the variable declaration also, avoid triggering "unused variable" warning on non-Intel machines. -- To unsubscribe from this list: send the line "unsubscribe linux-doc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v9 44/51] selftest/vm: powerpc implementation for generic abstraction
On Thu, Nov 09, 2017 at 04:47:15PM -0200, Breno Leitao wrote: > Hi Ram, > > On Mon, Nov 06, 2017 at 12:57:36AM -0800, Ram Pai wrote: > > @@ -206,12 +209,14 @@ void signal_handler(int signum, siginfo_t *si, void > > *vucontext) > > > > trapno = uctxt->uc_mcontext.gregs[REG_TRAPNO]; > > ip = uctxt->uc_mcontext.gregs[REG_IP_IDX]; > > - fpregset = uctxt->uc_mcontext.fpregs; > > - fpregs = (void *)fpregset; > > Since you removed all references for fpregset now, you probably want to > remove the declaration of the variable above. fpregs is still needed. > > > @@ -219,20 +224,21 @@ void signal_handler(int signum, siginfo_t *si, void > > *vucontext) > > * state. We just assume that it is here. > > */ > > fpregs += 0x70; > > -#endif > > - pkey_reg_offset = pkey_reg_xstate_offset(); > > With this code, you removed all the reference for variable > pkey_reg_offset, thus, its declaration could be removed also. yes. will fix it. > > > - *(u64 *)pkey_reg_ptr = 0x; > > + dprintf1("si_pkey from siginfo: %lx\n", si_pkey); > > +#if defined(__i386__) || defined(__x86_64__) /* arch */ > > + dprintf1("signal pkey_reg from xsave: %016lx\n", *pkey_reg_ptr); > > + *(u64 *)pkey_reg_ptr &= reset_bits(si_pkey, PKEY_DISABLE_ACCESS); > > +#elif __powerpc64__ > > Since the variable pkey_reg_ptr is only used for Intel code (inside > #ifdefs), you probably want to #ifdef the variable declaration also, > avoid triggering "unused variable" warning on non-Intel machines. yes. Actually it will trigger the warning on intel machines. Fixed it. Thanks Breno! RP -- To unsubscribe from this list: send the line "unsubscribe linux-doc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v9 44/51] selftest/vm: powerpc implementation for generic abstraction
Hi Ram, On Thu, Nov 09, 2017 at 03:37:46PM -0800, Ram Pai wrote: > On Thu, Nov 09, 2017 at 04:47:15PM -0200, Breno Leitao wrote: > > On Mon, Nov 06, 2017 at 12:57:36AM -0800, Ram Pai wrote: > > > @@ -206,12 +209,14 @@ void signal_handler(int signum, siginfo_t *si, void > > > *vucontext) > > > > > > trapno = uctxt->uc_mcontext.gregs[REG_TRAPNO]; > > > ip = uctxt->uc_mcontext.gregs[REG_IP_IDX]; > > > - fpregset = uctxt->uc_mcontext.fpregs; > > > - fpregs = (void *)fpregset; > > > > Since you removed all references for fpregset now, you probably want to > > remove the declaration of the variable above. > > fpregs is still needed. Right, fpregs is still needed, but not fpregset. Every reference for this variable was removed with your patch. Grepping this variable identifier on a tree with your patches, I see: $ grep fpregset protection_keys.c fpregset_t fpregset; -- To unsubscribe from this list: send the line "unsubscribe linux-doc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html