Re: [RFC v5 14/38] powerpc: initial plumbing for key management
On Fri, Jul 14, 2017 at 6:37 AM, Ram Paiwrote: > On Thu, Jul 13, 2017 at 12:45:00AM -0700, Ram Pai wrote: >> On Wed, Jul 12, 2017 at 01:28:25PM +1000, Balbir Singh wrote: >> > On Wed, 5 Jul 2017 14:21:51 -0700 >> > Ram Pai wrote: >> > >> > > Initial plumbing to manage all the keys supported by the >> > > hardware. >> > > >> > > Total 32 keys are supported on powerpc. However pkey 0,1 >> > > and 31 are reserved. So effectively we have 29 pkeys. >> > > >> > > This patch keeps track of reserved keys, allocated keys >> > > and keys that are currently free. >> > >> > It looks like this patch will only work in guest mode? >> > Is that an assumption we've made? What happens if I use >> > keys when running in hypervisor mode? >> >> It works in supervisor mode, as a guest aswell as a bare-metal >> kernel. Whatever needs to be done in hypervisor mode >> is already there in power-kvm. > > I realize i did not answer your question accurately... > "What happens if I use keys when running in hypervisor mode?" > > Its not clear what happens. As far as I can tell the MMU does > not check key violation when in hypervisor mode. So effectively > I think, keys are ineffective when in hypervisor mode. keys are honored in hypervisor mode. I was just stating that we need a mechanism used by the hypervisor to partition the key space between guests and hypervisor. Balbir Singh
Re: [RFC v5 14/38] powerpc: initial plumbing for key management
On Fri, Jul 14, 2017 at 6:37 AM, Ram Pai wrote: > On Thu, Jul 13, 2017 at 12:45:00AM -0700, Ram Pai wrote: >> On Wed, Jul 12, 2017 at 01:28:25PM +1000, Balbir Singh wrote: >> > On Wed, 5 Jul 2017 14:21:51 -0700 >> > Ram Pai wrote: >> > >> > > Initial plumbing to manage all the keys supported by the >> > > hardware. >> > > >> > > Total 32 keys are supported on powerpc. However pkey 0,1 >> > > and 31 are reserved. So effectively we have 29 pkeys. >> > > >> > > This patch keeps track of reserved keys, allocated keys >> > > and keys that are currently free. >> > >> > It looks like this patch will only work in guest mode? >> > Is that an assumption we've made? What happens if I use >> > keys when running in hypervisor mode? >> >> It works in supervisor mode, as a guest aswell as a bare-metal >> kernel. Whatever needs to be done in hypervisor mode >> is already there in power-kvm. > > I realize i did not answer your question accurately... > "What happens if I use keys when running in hypervisor mode?" > > Its not clear what happens. As far as I can tell the MMU does > not check key violation when in hypervisor mode. So effectively > I think, keys are ineffective when in hypervisor mode. keys are honored in hypervisor mode. I was just stating that we need a mechanism used by the hypervisor to partition the key space between guests and hypervisor. Balbir Singh
Re: [RFC v5 14/38] powerpc: initial plumbing for key management
On Thu, Jul 13, 2017 at 12:45:00AM -0700, Ram Pai wrote: > On Wed, Jul 12, 2017 at 01:28:25PM +1000, Balbir Singh wrote: > > On Wed, 5 Jul 2017 14:21:51 -0700 > > Ram Paiwrote: > > > > > Initial plumbing to manage all the keys supported by the > > > hardware. > > > > > > Total 32 keys are supported on powerpc. However pkey 0,1 > > > and 31 are reserved. So effectively we have 29 pkeys. > > > > > > This patch keeps track of reserved keys, allocated keys > > > and keys that are currently free. > > > > It looks like this patch will only work in guest mode? > > Is that an assumption we've made? What happens if I use > > keys when running in hypervisor mode? > > It works in supervisor mode, as a guest aswell as a bare-metal > kernel. Whatever needs to be done in hypervisor mode > is already there in power-kvm. I realize i did not answer your question accurately... "What happens if I use keys when running in hypervisor mode?" Its not clear what happens. As far as I can tell the MMU does not check key violation when in hypervisor mode. So effectively I think, keys are ineffective when in hypervisor mode. RP
Re: [RFC v5 14/38] powerpc: initial plumbing for key management
On Thu, Jul 13, 2017 at 12:45:00AM -0700, Ram Pai wrote: > On Wed, Jul 12, 2017 at 01:28:25PM +1000, Balbir Singh wrote: > > On Wed, 5 Jul 2017 14:21:51 -0700 > > Ram Pai wrote: > > > > > Initial plumbing to manage all the keys supported by the > > > hardware. > > > > > > Total 32 keys are supported on powerpc. However pkey 0,1 > > > and 31 are reserved. So effectively we have 29 pkeys. > > > > > > This patch keeps track of reserved keys, allocated keys > > > and keys that are currently free. > > > > It looks like this patch will only work in guest mode? > > Is that an assumption we've made? What happens if I use > > keys when running in hypervisor mode? > > It works in supervisor mode, as a guest aswell as a bare-metal > kernel. Whatever needs to be done in hypervisor mode > is already there in power-kvm. I realize i did not answer your question accurately... "What happens if I use keys when running in hypervisor mode?" Its not clear what happens. As far as I can tell the MMU does not check key violation when in hypervisor mode. So effectively I think, keys are ineffective when in hypervisor mode. RP
Re: [RFC v5 14/38] powerpc: initial plumbing for key management
On Wed, Jul 12, 2017 at 01:28:25PM +1000, Balbir Singh wrote: > On Wed, 5 Jul 2017 14:21:51 -0700 > Ram Paiwrote: > > > Initial plumbing to manage all the keys supported by the > > hardware. > > > > Total 32 keys are supported on powerpc. However pkey 0,1 > > and 31 are reserved. So effectively we have 29 pkeys. > > > > This patch keeps track of reserved keys, allocated keys > > and keys that are currently free. > > It looks like this patch will only work in guest mode? > Is that an assumption we've made? What happens if I use > keys when running in hypervisor mode? It works in supervisor mode, as a guest aswell as a bare-metal kernel. Whatever needs to be done in hypervisor mode is already there in power-kvm. > > > > > Also it adds skeletal functions and macros, that the > > architecture-independent code expects to be available. > > > > Signed-off-by: Ram Pai > > --- > > arch/powerpc/Kconfig | 16 + > > arch/powerpc/include/asm/book3s/64/mmu.h |9 +++ > > arch/powerpc/include/asm/pkeys.h | 106 > > ++ > > arch/powerpc/mm/mmu_context_book3s64.c |5 ++ > > 4 files changed, 136 insertions(+), 0 deletions(-) > > create mode 100644 arch/powerpc/include/asm/pkeys.h > > > > diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig > > index f7c8f99..a2480b6 100644 > > --- a/arch/powerpc/Kconfig > > +++ b/arch/powerpc/Kconfig > > @@ -871,6 +871,22 @@ config SECCOMP > > > > If unsure, say Y. Only embedded should say N here. > > > > +config PPC64_MEMORY_PROTECTION_KEYS > > + prompt "PowerPC Memory Protection Keys" > > + def_bool y > > + # Note: only available in 64-bit mode > > + depends on PPC64 && PPC_64K_PAGES > > + select ARCH_USES_HIGH_VMA_FLAGS > > + select ARCH_HAS_PKEYS > > + ---help--- > > + Memory Protection Keys provides a mechanism for enforcing > > + page-based protections, but without requiring modification of the > > + page tables when an application changes protection domains. > > + > > + For details, see Documentation/powerpc/protection-keys.txt > > + > > + If unsure, say y. > > + > > endmenu > > > > config ISA_DMA_API > > diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h > > b/arch/powerpc/include/asm/book3s/64/mmu.h > > index 77529a3..104ad72 100644 > > --- a/arch/powerpc/include/asm/book3s/64/mmu.h > > +++ b/arch/powerpc/include/asm/book3s/64/mmu.h > > @@ -108,6 +108,15 @@ struct patb_entry { > > #ifdef CONFIG_SPAPR_TCE_IOMMU > > struct list_head iommu_group_mem_list; > > #endif > > + > > +#ifdef CONFIG_PPC64_MEMORY_PROTECTION_KEYS > > + /* > > +* Each bit represents one protection key. > > +* bit set -> key allocated > > +* bit unset -> key available for allocation > > +*/ > > + u32 pkey_allocation_map; > > +#endif > > } mm_context_t; > > > > /* > > diff --git a/arch/powerpc/include/asm/pkeys.h > > b/arch/powerpc/include/asm/pkeys.h > > new file mode 100644 > > index 000..9345767 > > --- /dev/null > > +++ b/arch/powerpc/include/asm/pkeys.h > > @@ -0,0 +1,106 @@ > > +#ifndef _ASM_PPC64_PKEYS_H > > +#define _ASM_PPC64_PKEYS_H > > + > > +#define arch_max_pkey() 32 > > +#define ARCH_VM_PKEY_FLAGS (VM_PKEY_BIT0 | VM_PKEY_BIT1 | VM_PKEY_BIT2 | \ > > + VM_PKEY_BIT3 | VM_PKEY_BIT4) > > +/* > > + * Bits are in BE format. > > + * NOTE: key 31, 1, 0 are not used. > > + * key 0 is used by default. It give read/write/execute permission. > > + * key 31 is reserved by the hypervisor. > > + * key 1 is recommended to be not used. > > + * PowerISA(3.0) page 1015, programming note. > > + */ > > +#define PKEY_INITIAL_ALLOCAION 0xc001 > > Shouldn't this be exchanged via CAS for guests? Have you seen > ibm,processor-storage-keys? Yes. Was one of my TODOs to initilize this using the device-tree interface. A brief look at that did not show the reserved keys properly enumerated. But I may be wrong. > > > + > > +#define pkeybit_mask(pkey) (0x1 << (arch_max_pkey() - pkey - 1)) > > + > > +#define mm_pkey_allocation_map(mm) (mm->context.pkey_allocation_map) > > + > > +#define mm_set_pkey_allocated(mm, pkey) { \ > > + mm_pkey_allocation_map(mm) |= pkeybit_mask(pkey); \ > > +} > > + > > +#define mm_set_pkey_free(mm, pkey) { \ > > + mm_pkey_allocation_map(mm) &= ~pkeybit_mask(pkey); \ > > +} > > + > > +#define mm_set_pkey_is_allocated(mm, pkey) \ > > + (mm_pkey_allocation_map(mm) & pkeybit_mask(pkey)) > > + > > +#define mm_set_pkey_is_reserved(mm, pkey) (PKEY_INITIAL_ALLOCAION & \ > > + pkeybit_mask(pkey)) > > + > > +static inline bool mm_pkey_is_allocated(struct mm_struct *mm, int pkey) > > +{ > > + /* a reserved key is never considered as 'explicitly allocated' */ > > + return (!mm_set_pkey_is_reserved(mm, pkey) && > > + mm_set_pkey_is_allocated(mm, pkey)); > > +} > > + > > +/* > > + * Returns a
Re: [RFC v5 14/38] powerpc: initial plumbing for key management
On Wed, Jul 12, 2017 at 01:28:25PM +1000, Balbir Singh wrote: > On Wed, 5 Jul 2017 14:21:51 -0700 > Ram Pai wrote: > > > Initial plumbing to manage all the keys supported by the > > hardware. > > > > Total 32 keys are supported on powerpc. However pkey 0,1 > > and 31 are reserved. So effectively we have 29 pkeys. > > > > This patch keeps track of reserved keys, allocated keys > > and keys that are currently free. > > It looks like this patch will only work in guest mode? > Is that an assumption we've made? What happens if I use > keys when running in hypervisor mode? It works in supervisor mode, as a guest aswell as a bare-metal kernel. Whatever needs to be done in hypervisor mode is already there in power-kvm. > > > > > Also it adds skeletal functions and macros, that the > > architecture-independent code expects to be available. > > > > Signed-off-by: Ram Pai > > --- > > arch/powerpc/Kconfig | 16 + > > arch/powerpc/include/asm/book3s/64/mmu.h |9 +++ > > arch/powerpc/include/asm/pkeys.h | 106 > > ++ > > arch/powerpc/mm/mmu_context_book3s64.c |5 ++ > > 4 files changed, 136 insertions(+), 0 deletions(-) > > create mode 100644 arch/powerpc/include/asm/pkeys.h > > > > diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig > > index f7c8f99..a2480b6 100644 > > --- a/arch/powerpc/Kconfig > > +++ b/arch/powerpc/Kconfig > > @@ -871,6 +871,22 @@ config SECCOMP > > > > If unsure, say Y. Only embedded should say N here. > > > > +config PPC64_MEMORY_PROTECTION_KEYS > > + prompt "PowerPC Memory Protection Keys" > > + def_bool y > > + # Note: only available in 64-bit mode > > + depends on PPC64 && PPC_64K_PAGES > > + select ARCH_USES_HIGH_VMA_FLAGS > > + select ARCH_HAS_PKEYS > > + ---help--- > > + Memory Protection Keys provides a mechanism for enforcing > > + page-based protections, but without requiring modification of the > > + page tables when an application changes protection domains. > > + > > + For details, see Documentation/powerpc/protection-keys.txt > > + > > + If unsure, say y. > > + > > endmenu > > > > config ISA_DMA_API > > diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h > > b/arch/powerpc/include/asm/book3s/64/mmu.h > > index 77529a3..104ad72 100644 > > --- a/arch/powerpc/include/asm/book3s/64/mmu.h > > +++ b/arch/powerpc/include/asm/book3s/64/mmu.h > > @@ -108,6 +108,15 @@ struct patb_entry { > > #ifdef CONFIG_SPAPR_TCE_IOMMU > > struct list_head iommu_group_mem_list; > > #endif > > + > > +#ifdef CONFIG_PPC64_MEMORY_PROTECTION_KEYS > > + /* > > +* Each bit represents one protection key. > > +* bit set -> key allocated > > +* bit unset -> key available for allocation > > +*/ > > + u32 pkey_allocation_map; > > +#endif > > } mm_context_t; > > > > /* > > diff --git a/arch/powerpc/include/asm/pkeys.h > > b/arch/powerpc/include/asm/pkeys.h > > new file mode 100644 > > index 000..9345767 > > --- /dev/null > > +++ b/arch/powerpc/include/asm/pkeys.h > > @@ -0,0 +1,106 @@ > > +#ifndef _ASM_PPC64_PKEYS_H > > +#define _ASM_PPC64_PKEYS_H > > + > > +#define arch_max_pkey() 32 > > +#define ARCH_VM_PKEY_FLAGS (VM_PKEY_BIT0 | VM_PKEY_BIT1 | VM_PKEY_BIT2 | \ > > + VM_PKEY_BIT3 | VM_PKEY_BIT4) > > +/* > > + * Bits are in BE format. > > + * NOTE: key 31, 1, 0 are not used. > > + * key 0 is used by default. It give read/write/execute permission. > > + * key 31 is reserved by the hypervisor. > > + * key 1 is recommended to be not used. > > + * PowerISA(3.0) page 1015, programming note. > > + */ > > +#define PKEY_INITIAL_ALLOCAION 0xc001 > > Shouldn't this be exchanged via CAS for guests? Have you seen > ibm,processor-storage-keys? Yes. Was one of my TODOs to initilize this using the device-tree interface. A brief look at that did not show the reserved keys properly enumerated. But I may be wrong. > > > + > > +#define pkeybit_mask(pkey) (0x1 << (arch_max_pkey() - pkey - 1)) > > + > > +#define mm_pkey_allocation_map(mm) (mm->context.pkey_allocation_map) > > + > > +#define mm_set_pkey_allocated(mm, pkey) { \ > > + mm_pkey_allocation_map(mm) |= pkeybit_mask(pkey); \ > > +} > > + > > +#define mm_set_pkey_free(mm, pkey) { \ > > + mm_pkey_allocation_map(mm) &= ~pkeybit_mask(pkey); \ > > +} > > + > > +#define mm_set_pkey_is_allocated(mm, pkey) \ > > + (mm_pkey_allocation_map(mm) & pkeybit_mask(pkey)) > > + > > +#define mm_set_pkey_is_reserved(mm, pkey) (PKEY_INITIAL_ALLOCAION & \ > > + pkeybit_mask(pkey)) > > + > > +static inline bool mm_pkey_is_allocated(struct mm_struct *mm, int pkey) > > +{ > > + /* a reserved key is never considered as 'explicitly allocated' */ > > + return (!mm_set_pkey_is_reserved(mm, pkey) && > > + mm_set_pkey_is_allocated(mm, pkey)); > > +} > > + > > +/* > > + * Returns a positive, 5-bit key on success, or -1 on
Re: [RFC v5 14/38] powerpc: initial plumbing for key management
On Wed, 5 Jul 2017 14:21:51 -0700 Ram Paiwrote: > Initial plumbing to manage all the keys supported by the > hardware. > > Total 32 keys are supported on powerpc. However pkey 0,1 > and 31 are reserved. So effectively we have 29 pkeys. > > This patch keeps track of reserved keys, allocated keys > and keys that are currently free. It looks like this patch will only work in guest mode? Is that an assumption we've made? What happens if I use keys when running in hypervisor mode? > > Also it adds skeletal functions and macros, that the > architecture-independent code expects to be available. > > Signed-off-by: Ram Pai > --- > arch/powerpc/Kconfig | 16 + > arch/powerpc/include/asm/book3s/64/mmu.h |9 +++ > arch/powerpc/include/asm/pkeys.h | 106 > ++ > arch/powerpc/mm/mmu_context_book3s64.c |5 ++ > 4 files changed, 136 insertions(+), 0 deletions(-) > create mode 100644 arch/powerpc/include/asm/pkeys.h > > diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig > index f7c8f99..a2480b6 100644 > --- a/arch/powerpc/Kconfig > +++ b/arch/powerpc/Kconfig > @@ -871,6 +871,22 @@ config SECCOMP > > If unsure, say Y. Only embedded should say N here. > > +config PPC64_MEMORY_PROTECTION_KEYS > + prompt "PowerPC Memory Protection Keys" > + def_bool y > + # Note: only available in 64-bit mode > + depends on PPC64 && PPC_64K_PAGES > + select ARCH_USES_HIGH_VMA_FLAGS > + select ARCH_HAS_PKEYS > + ---help--- > + Memory Protection Keys provides a mechanism for enforcing > + page-based protections, but without requiring modification of the > + page tables when an application changes protection domains. > + > + For details, see Documentation/powerpc/protection-keys.txt > + > + If unsure, say y. > + > endmenu > > config ISA_DMA_API > diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h > b/arch/powerpc/include/asm/book3s/64/mmu.h > index 77529a3..104ad72 100644 > --- a/arch/powerpc/include/asm/book3s/64/mmu.h > +++ b/arch/powerpc/include/asm/book3s/64/mmu.h > @@ -108,6 +108,15 @@ struct patb_entry { > #ifdef CONFIG_SPAPR_TCE_IOMMU > struct list_head iommu_group_mem_list; > #endif > + > +#ifdef CONFIG_PPC64_MEMORY_PROTECTION_KEYS > + /* > + * Each bit represents one protection key. > + * bit set -> key allocated > + * bit unset -> key available for allocation > + */ > + u32 pkey_allocation_map; > +#endif > } mm_context_t; > > /* > diff --git a/arch/powerpc/include/asm/pkeys.h > b/arch/powerpc/include/asm/pkeys.h > new file mode 100644 > index 000..9345767 > --- /dev/null > +++ b/arch/powerpc/include/asm/pkeys.h > @@ -0,0 +1,106 @@ > +#ifndef _ASM_PPC64_PKEYS_H > +#define _ASM_PPC64_PKEYS_H > + > +#define arch_max_pkey() 32 > +#define ARCH_VM_PKEY_FLAGS (VM_PKEY_BIT0 | VM_PKEY_BIT1 | VM_PKEY_BIT2 | \ > + VM_PKEY_BIT3 | VM_PKEY_BIT4) > +/* > + * Bits are in BE format. > + * NOTE: key 31, 1, 0 are not used. > + * key 0 is used by default. It give read/write/execute permission. > + * key 31 is reserved by the hypervisor. > + * key 1 is recommended to be not used. > + * PowerISA(3.0) page 1015, programming note. > + */ > +#define PKEY_INITIAL_ALLOCAION 0xc001 Shouldn't this be exchanged via CAS for guests? Have you seen ibm,processor-storage-keys? > + > +#define pkeybit_mask(pkey) (0x1 << (arch_max_pkey() - pkey - 1)) > + > +#define mm_pkey_allocation_map(mm) (mm->context.pkey_allocation_map) > + > +#define mm_set_pkey_allocated(mm, pkey) {\ > + mm_pkey_allocation_map(mm) |= pkeybit_mask(pkey); \ > +} > + > +#define mm_set_pkey_free(mm, pkey) { \ > + mm_pkey_allocation_map(mm) &= ~pkeybit_mask(pkey); \ > +} > + > +#define mm_set_pkey_is_allocated(mm, pkey) \ > + (mm_pkey_allocation_map(mm) & pkeybit_mask(pkey)) > + > +#define mm_set_pkey_is_reserved(mm, pkey) (PKEY_INITIAL_ALLOCAION & \ > + pkeybit_mask(pkey)) > + > +static inline bool mm_pkey_is_allocated(struct mm_struct *mm, int pkey) > +{ > + /* a reserved key is never considered as 'explicitly allocated' */ > + return (!mm_set_pkey_is_reserved(mm, pkey) && > + mm_set_pkey_is_allocated(mm, pkey)); > +} > + > +/* > + * Returns a positive, 5-bit key on success, or -1 on failure. > + */ > +static inline int mm_pkey_alloc(struct mm_struct *mm) > +{ > + /* > + * Note: this is the one and only place we make sure > + * that the pkey is valid as far as the hardware is > + * concerned. The rest of the kernel trusts that > + * only good, valid pkeys come out of here. > + */ > + u32 all_pkeys_mask = (u32)(~(0x0)); > + int ret; > + > + /* > + * Are we out of pkeys? We must handle this specially > + * because ffz() behavior is undefined if there are no > + * zeros. >
Re: [RFC v5 14/38] powerpc: initial plumbing for key management
On Wed, 5 Jul 2017 14:21:51 -0700 Ram Pai wrote: > Initial plumbing to manage all the keys supported by the > hardware. > > Total 32 keys are supported on powerpc. However pkey 0,1 > and 31 are reserved. So effectively we have 29 pkeys. > > This patch keeps track of reserved keys, allocated keys > and keys that are currently free. It looks like this patch will only work in guest mode? Is that an assumption we've made? What happens if I use keys when running in hypervisor mode? > > Also it adds skeletal functions and macros, that the > architecture-independent code expects to be available. > > Signed-off-by: Ram Pai > --- > arch/powerpc/Kconfig | 16 + > arch/powerpc/include/asm/book3s/64/mmu.h |9 +++ > arch/powerpc/include/asm/pkeys.h | 106 > ++ > arch/powerpc/mm/mmu_context_book3s64.c |5 ++ > 4 files changed, 136 insertions(+), 0 deletions(-) > create mode 100644 arch/powerpc/include/asm/pkeys.h > > diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig > index f7c8f99..a2480b6 100644 > --- a/arch/powerpc/Kconfig > +++ b/arch/powerpc/Kconfig > @@ -871,6 +871,22 @@ config SECCOMP > > If unsure, say Y. Only embedded should say N here. > > +config PPC64_MEMORY_PROTECTION_KEYS > + prompt "PowerPC Memory Protection Keys" > + def_bool y > + # Note: only available in 64-bit mode > + depends on PPC64 && PPC_64K_PAGES > + select ARCH_USES_HIGH_VMA_FLAGS > + select ARCH_HAS_PKEYS > + ---help--- > + Memory Protection Keys provides a mechanism for enforcing > + page-based protections, but without requiring modification of the > + page tables when an application changes protection domains. > + > + For details, see Documentation/powerpc/protection-keys.txt > + > + If unsure, say y. > + > endmenu > > config ISA_DMA_API > diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h > b/arch/powerpc/include/asm/book3s/64/mmu.h > index 77529a3..104ad72 100644 > --- a/arch/powerpc/include/asm/book3s/64/mmu.h > +++ b/arch/powerpc/include/asm/book3s/64/mmu.h > @@ -108,6 +108,15 @@ struct patb_entry { > #ifdef CONFIG_SPAPR_TCE_IOMMU > struct list_head iommu_group_mem_list; > #endif > + > +#ifdef CONFIG_PPC64_MEMORY_PROTECTION_KEYS > + /* > + * Each bit represents one protection key. > + * bit set -> key allocated > + * bit unset -> key available for allocation > + */ > + u32 pkey_allocation_map; > +#endif > } mm_context_t; > > /* > diff --git a/arch/powerpc/include/asm/pkeys.h > b/arch/powerpc/include/asm/pkeys.h > new file mode 100644 > index 000..9345767 > --- /dev/null > +++ b/arch/powerpc/include/asm/pkeys.h > @@ -0,0 +1,106 @@ > +#ifndef _ASM_PPC64_PKEYS_H > +#define _ASM_PPC64_PKEYS_H > + > +#define arch_max_pkey() 32 > +#define ARCH_VM_PKEY_FLAGS (VM_PKEY_BIT0 | VM_PKEY_BIT1 | VM_PKEY_BIT2 | \ > + VM_PKEY_BIT3 | VM_PKEY_BIT4) > +/* > + * Bits are in BE format. > + * NOTE: key 31, 1, 0 are not used. > + * key 0 is used by default. It give read/write/execute permission. > + * key 31 is reserved by the hypervisor. > + * key 1 is recommended to be not used. > + * PowerISA(3.0) page 1015, programming note. > + */ > +#define PKEY_INITIAL_ALLOCAION 0xc001 Shouldn't this be exchanged via CAS for guests? Have you seen ibm,processor-storage-keys? > + > +#define pkeybit_mask(pkey) (0x1 << (arch_max_pkey() - pkey - 1)) > + > +#define mm_pkey_allocation_map(mm) (mm->context.pkey_allocation_map) > + > +#define mm_set_pkey_allocated(mm, pkey) {\ > + mm_pkey_allocation_map(mm) |= pkeybit_mask(pkey); \ > +} > + > +#define mm_set_pkey_free(mm, pkey) { \ > + mm_pkey_allocation_map(mm) &= ~pkeybit_mask(pkey); \ > +} > + > +#define mm_set_pkey_is_allocated(mm, pkey) \ > + (mm_pkey_allocation_map(mm) & pkeybit_mask(pkey)) > + > +#define mm_set_pkey_is_reserved(mm, pkey) (PKEY_INITIAL_ALLOCAION & \ > + pkeybit_mask(pkey)) > + > +static inline bool mm_pkey_is_allocated(struct mm_struct *mm, int pkey) > +{ > + /* a reserved key is never considered as 'explicitly allocated' */ > + return (!mm_set_pkey_is_reserved(mm, pkey) && > + mm_set_pkey_is_allocated(mm, pkey)); > +} > + > +/* > + * Returns a positive, 5-bit key on success, or -1 on failure. > + */ > +static inline int mm_pkey_alloc(struct mm_struct *mm) > +{ > + /* > + * Note: this is the one and only place we make sure > + * that the pkey is valid as far as the hardware is > + * concerned. The rest of the kernel trusts that > + * only good, valid pkeys come out of here. > + */ > + u32 all_pkeys_mask = (u32)(~(0x0)); > + int ret; > + > + /* > + * Are we out of pkeys? We must handle this specially > + * because ffz() behavior is undefined if there are no > + * zeros. > + */ > + if
[RFC v5 14/38] powerpc: initial plumbing for key management
Initial plumbing to manage all the keys supported by the hardware. Total 32 keys are supported on powerpc. However pkey 0,1 and 31 are reserved. So effectively we have 29 pkeys. This patch keeps track of reserved keys, allocated keys and keys that are currently free. Also it adds skeletal functions and macros, that the architecture-independent code expects to be available. Signed-off-by: Ram Pai--- arch/powerpc/Kconfig | 16 + arch/powerpc/include/asm/book3s/64/mmu.h |9 +++ arch/powerpc/include/asm/pkeys.h | 106 ++ arch/powerpc/mm/mmu_context_book3s64.c |5 ++ 4 files changed, 136 insertions(+), 0 deletions(-) create mode 100644 arch/powerpc/include/asm/pkeys.h diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index f7c8f99..a2480b6 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -871,6 +871,22 @@ config SECCOMP If unsure, say Y. Only embedded should say N here. +config PPC64_MEMORY_PROTECTION_KEYS + prompt "PowerPC Memory Protection Keys" + def_bool y + # Note: only available in 64-bit mode + depends on PPC64 && PPC_64K_PAGES + select ARCH_USES_HIGH_VMA_FLAGS + select ARCH_HAS_PKEYS + ---help--- + Memory Protection Keys provides a mechanism for enforcing + page-based protections, but without requiring modification of the + page tables when an application changes protection domains. + + For details, see Documentation/powerpc/protection-keys.txt + + If unsure, say y. + endmenu config ISA_DMA_API diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h b/arch/powerpc/include/asm/book3s/64/mmu.h index 77529a3..104ad72 100644 --- a/arch/powerpc/include/asm/book3s/64/mmu.h +++ b/arch/powerpc/include/asm/book3s/64/mmu.h @@ -108,6 +108,15 @@ struct patb_entry { #ifdef CONFIG_SPAPR_TCE_IOMMU struct list_head iommu_group_mem_list; #endif + +#ifdef CONFIG_PPC64_MEMORY_PROTECTION_KEYS + /* +* Each bit represents one protection key. +* bit set -> key allocated +* bit unset -> key available for allocation +*/ + u32 pkey_allocation_map; +#endif } mm_context_t; /* diff --git a/arch/powerpc/include/asm/pkeys.h b/arch/powerpc/include/asm/pkeys.h new file mode 100644 index 000..9345767 --- /dev/null +++ b/arch/powerpc/include/asm/pkeys.h @@ -0,0 +1,106 @@ +#ifndef _ASM_PPC64_PKEYS_H +#define _ASM_PPC64_PKEYS_H + +#define arch_max_pkey() 32 +#define ARCH_VM_PKEY_FLAGS (VM_PKEY_BIT0 | VM_PKEY_BIT1 | VM_PKEY_BIT2 | \ + VM_PKEY_BIT3 | VM_PKEY_BIT4) +/* + * Bits are in BE format. + * NOTE: key 31, 1, 0 are not used. + * key 0 is used by default. It give read/write/execute permission. + * key 31 is reserved by the hypervisor. + * key 1 is recommended to be not used. + * PowerISA(3.0) page 1015, programming note. + */ +#define PKEY_INITIAL_ALLOCAION 0xc001 + +#define pkeybit_mask(pkey) (0x1 << (arch_max_pkey() - pkey - 1)) + +#define mm_pkey_allocation_map(mm) (mm->context.pkey_allocation_map) + +#define mm_set_pkey_allocated(mm, pkey) { \ + mm_pkey_allocation_map(mm) |= pkeybit_mask(pkey); \ +} + +#define mm_set_pkey_free(mm, pkey) { \ + mm_pkey_allocation_map(mm) &= ~pkeybit_mask(pkey); \ +} + +#define mm_set_pkey_is_allocated(mm, pkey) \ + (mm_pkey_allocation_map(mm) & pkeybit_mask(pkey)) + +#define mm_set_pkey_is_reserved(mm, pkey) (PKEY_INITIAL_ALLOCAION & \ + pkeybit_mask(pkey)) + +static inline bool mm_pkey_is_allocated(struct mm_struct *mm, int pkey) +{ + /* a reserved key is never considered as 'explicitly allocated' */ + return (!mm_set_pkey_is_reserved(mm, pkey) && + mm_set_pkey_is_allocated(mm, pkey)); +} + +/* + * Returns a positive, 5-bit key on success, or -1 on failure. + */ +static inline int mm_pkey_alloc(struct mm_struct *mm) +{ + /* +* Note: this is the one and only place we make sure +* that the pkey is valid as far as the hardware is +* concerned. The rest of the kernel trusts that +* only good, valid pkeys come out of here. +*/ + u32 all_pkeys_mask = (u32)(~(0x0)); + int ret; + + /* +* Are we out of pkeys? We must handle this specially +* because ffz() behavior is undefined if there are no +* zeros. +*/ + if (mm_pkey_allocation_map(mm) == all_pkeys_mask) + return -1; + + ret = arch_max_pkey() - + ffz((u32)mm_pkey_allocation_map(mm)) + - 1; + mm_set_pkey_allocated(mm, ret); + return ret; +} + +static inline int mm_pkey_free(struct mm_struct *mm, int pkey) +{ + if (!mm_pkey_is_allocated(mm, pkey)) + return -EINVAL; + + mm_set_pkey_free(mm, pkey); + + return 0; +} + +/* + * Try to dedicate one
[RFC v5 14/38] powerpc: initial plumbing for key management
Initial plumbing to manage all the keys supported by the hardware. Total 32 keys are supported on powerpc. However pkey 0,1 and 31 are reserved. So effectively we have 29 pkeys. This patch keeps track of reserved keys, allocated keys and keys that are currently free. Also it adds skeletal functions and macros, that the architecture-independent code expects to be available. Signed-off-by: Ram Pai --- arch/powerpc/Kconfig | 16 + arch/powerpc/include/asm/book3s/64/mmu.h |9 +++ arch/powerpc/include/asm/pkeys.h | 106 ++ arch/powerpc/mm/mmu_context_book3s64.c |5 ++ 4 files changed, 136 insertions(+), 0 deletions(-) create mode 100644 arch/powerpc/include/asm/pkeys.h diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index f7c8f99..a2480b6 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -871,6 +871,22 @@ config SECCOMP If unsure, say Y. Only embedded should say N here. +config PPC64_MEMORY_PROTECTION_KEYS + prompt "PowerPC Memory Protection Keys" + def_bool y + # Note: only available in 64-bit mode + depends on PPC64 && PPC_64K_PAGES + select ARCH_USES_HIGH_VMA_FLAGS + select ARCH_HAS_PKEYS + ---help--- + Memory Protection Keys provides a mechanism for enforcing + page-based protections, but without requiring modification of the + page tables when an application changes protection domains. + + For details, see Documentation/powerpc/protection-keys.txt + + If unsure, say y. + endmenu config ISA_DMA_API diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h b/arch/powerpc/include/asm/book3s/64/mmu.h index 77529a3..104ad72 100644 --- a/arch/powerpc/include/asm/book3s/64/mmu.h +++ b/arch/powerpc/include/asm/book3s/64/mmu.h @@ -108,6 +108,15 @@ struct patb_entry { #ifdef CONFIG_SPAPR_TCE_IOMMU struct list_head iommu_group_mem_list; #endif + +#ifdef CONFIG_PPC64_MEMORY_PROTECTION_KEYS + /* +* Each bit represents one protection key. +* bit set -> key allocated +* bit unset -> key available for allocation +*/ + u32 pkey_allocation_map; +#endif } mm_context_t; /* diff --git a/arch/powerpc/include/asm/pkeys.h b/arch/powerpc/include/asm/pkeys.h new file mode 100644 index 000..9345767 --- /dev/null +++ b/arch/powerpc/include/asm/pkeys.h @@ -0,0 +1,106 @@ +#ifndef _ASM_PPC64_PKEYS_H +#define _ASM_PPC64_PKEYS_H + +#define arch_max_pkey() 32 +#define ARCH_VM_PKEY_FLAGS (VM_PKEY_BIT0 | VM_PKEY_BIT1 | VM_PKEY_BIT2 | \ + VM_PKEY_BIT3 | VM_PKEY_BIT4) +/* + * Bits are in BE format. + * NOTE: key 31, 1, 0 are not used. + * key 0 is used by default. It give read/write/execute permission. + * key 31 is reserved by the hypervisor. + * key 1 is recommended to be not used. + * PowerISA(3.0) page 1015, programming note. + */ +#define PKEY_INITIAL_ALLOCAION 0xc001 + +#define pkeybit_mask(pkey) (0x1 << (arch_max_pkey() - pkey - 1)) + +#define mm_pkey_allocation_map(mm) (mm->context.pkey_allocation_map) + +#define mm_set_pkey_allocated(mm, pkey) { \ + mm_pkey_allocation_map(mm) |= pkeybit_mask(pkey); \ +} + +#define mm_set_pkey_free(mm, pkey) { \ + mm_pkey_allocation_map(mm) &= ~pkeybit_mask(pkey); \ +} + +#define mm_set_pkey_is_allocated(mm, pkey) \ + (mm_pkey_allocation_map(mm) & pkeybit_mask(pkey)) + +#define mm_set_pkey_is_reserved(mm, pkey) (PKEY_INITIAL_ALLOCAION & \ + pkeybit_mask(pkey)) + +static inline bool mm_pkey_is_allocated(struct mm_struct *mm, int pkey) +{ + /* a reserved key is never considered as 'explicitly allocated' */ + return (!mm_set_pkey_is_reserved(mm, pkey) && + mm_set_pkey_is_allocated(mm, pkey)); +} + +/* + * Returns a positive, 5-bit key on success, or -1 on failure. + */ +static inline int mm_pkey_alloc(struct mm_struct *mm) +{ + /* +* Note: this is the one and only place we make sure +* that the pkey is valid as far as the hardware is +* concerned. The rest of the kernel trusts that +* only good, valid pkeys come out of here. +*/ + u32 all_pkeys_mask = (u32)(~(0x0)); + int ret; + + /* +* Are we out of pkeys? We must handle this specially +* because ffz() behavior is undefined if there are no +* zeros. +*/ + if (mm_pkey_allocation_map(mm) == all_pkeys_mask) + return -1; + + ret = arch_max_pkey() - + ffz((u32)mm_pkey_allocation_map(mm)) + - 1; + mm_set_pkey_allocated(mm, ret); + return ret; +} + +static inline int mm_pkey_free(struct mm_struct *mm, int pkey) +{ + if (!mm_pkey_is_allocated(mm, pkey)) + return -EINVAL; + + mm_set_pkey_free(mm, pkey); + + return 0; +} + +/* + * Try to dedicate one of the protection