1 /* Helper functions for manipulating memory protection keys, for powerpc64.
2    Copyright (C) 2017-2022 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <http://www.gnu.org/licenses/>.  */
18 
19 #ifndef _ARCH_PKEY_H
20 #define _ARCH_PKEY_H
21 
22 /* Read and write access bits in the AMR register.  Needs to be
23    translated from and to PKEY_DISABLE_* flags.  */
24 #define PKEY_AMR_READ 1UL
25 #define PKEY_AMR_WRITE 2UL
26 
27 /* Return the value of the AMR register.  */
28 static inline unsigned long int
pkey_read(void)29 pkey_read (void)
30 {
31   unsigned long int result;
32   __asm__ volatile ("mfspr %0, 13" : "=r" (result));
33   return result;
34 }
35 
36 /* Overwrite the AMR register with VALUE.  */
37 static inline void
pkey_write(unsigned long int value)38 pkey_write (unsigned long int value)
39 {
40   __asm__ volatile ("isync; mtspr 13, %0; isync" : : "r" (value));
41 }
42 
43 /* Number of the largest supported key.  This depends on the width of
44    the AMR register.  */
45 #define PKEY_MAX (sizeof (unsigned long int) * 8 / 2 - 1)
46 _Static_assert (PKEY_MAX == 15 || PKEY_MAX == 31, "PKEY_MAX value");
47 
48 /* Translate key number into AMR index position.  */
49 static inline int
pkey_index(int key)50 pkey_index (int key)
51 {
52   return 2 * (PKEY_MAX - key);
53 }
54 
55 #endif /* _ARCH_PKEY_H */
56