Commit eb95d016 authored by Ram Pai's avatar Ram Pai Committed by Michael Ellerman

powerpc: map vma key-protection bits to pte key bits.

Map  the  key  protection  bits of the vma to the pkey bits in
the PTE.

The PTE  bits used  for pkey  are  3,4,5,6  and 57. The  first
four bits are the same four bits that were freed up  initially
in this patch series. remember? :-) Without those four bits
this patch wouldn't be possible.

BUT, on 4k kernel, bit 3, and 4 could not be freed up. remember?
Hence we have to be satisfied with 5, 6 and 7.
Signed-off-by: default avatarRam Pai <linuxram@us.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 87bbabbe
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#define _RPAGE_RSV2 0x0800000000000000UL #define _RPAGE_RSV2 0x0800000000000000UL
#define _RPAGE_RSV3 0x0400000000000000UL #define _RPAGE_RSV3 0x0400000000000000UL
#define _RPAGE_RSV4 0x0200000000000000UL #define _RPAGE_RSV4 0x0200000000000000UL
#define _RPAGE_RSV5 0x00040UL
#define _PAGE_PTE 0x4000000000000000UL /* distinguishes PTEs from pointers */ #define _PAGE_PTE 0x4000000000000000UL /* distinguishes PTEs from pointers */
#define _PAGE_PRESENT 0x8000000000000000UL /* pte contains a translation */ #define _PAGE_PRESENT 0x8000000000000000UL /* pte contains a translation */
...@@ -59,6 +60,25 @@ ...@@ -59,6 +60,25 @@
/* Max physical address bit as per radix table */ /* Max physical address bit as per radix table */
#define _RPAGE_PA_MAX 57 #define _RPAGE_PA_MAX 57
#ifdef CONFIG_PPC_MEM_KEYS
#ifdef CONFIG_PPC_64K_PAGES
#define H_PTE_PKEY_BIT0 _RPAGE_RSV1
#define H_PTE_PKEY_BIT1 _RPAGE_RSV2
#else /* CONFIG_PPC_64K_PAGES */
#define H_PTE_PKEY_BIT0 0 /* _RPAGE_RSV1 is not available */
#define H_PTE_PKEY_BIT1 0 /* _RPAGE_RSV2 is not available */
#endif /* CONFIG_PPC_64K_PAGES */
#define H_PTE_PKEY_BIT2 _RPAGE_RSV3
#define H_PTE_PKEY_BIT3 _RPAGE_RSV4
#define H_PTE_PKEY_BIT4 _RPAGE_RSV5
#else /* CONFIG_PPC_MEM_KEYS */
#define H_PTE_PKEY_BIT0 0
#define H_PTE_PKEY_BIT1 0
#define H_PTE_PKEY_BIT2 0
#define H_PTE_PKEY_BIT3 0
#define H_PTE_PKEY_BIT4 0
#endif /* CONFIG_PPC_MEM_KEYS */
/* /*
* Max physical address bit we will use for now. * Max physical address bit we will use for now.
* *
...@@ -122,13 +142,16 @@ ...@@ -122,13 +142,16 @@
#define _PAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \ #define _PAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \
_PAGE_ACCESSED | _PAGE_SPECIAL | _PAGE_PTE | \ _PAGE_ACCESSED | _PAGE_SPECIAL | _PAGE_PTE | \
_PAGE_SOFT_DIRTY) _PAGE_SOFT_DIRTY)
#define H_PTE_PKEY (H_PTE_PKEY_BIT0 | H_PTE_PKEY_BIT1 | H_PTE_PKEY_BIT2 | \
H_PTE_PKEY_BIT3 | H_PTE_PKEY_BIT4)
/* /*
* Mask of bits returned by pte_pgprot() * Mask of bits returned by pte_pgprot()
*/ */
#define PAGE_PROT_BITS (_PAGE_SAO | _PAGE_NON_IDEMPOTENT | _PAGE_TOLERANT | \ #define PAGE_PROT_BITS (_PAGE_SAO | _PAGE_NON_IDEMPOTENT | _PAGE_TOLERANT | \
H_PAGE_4K_PFN | _PAGE_PRIVILEGED | _PAGE_ACCESSED | \ H_PAGE_4K_PFN | _PAGE_PRIVILEGED | _PAGE_ACCESSED | \
_PAGE_READ | _PAGE_WRITE | _PAGE_DIRTY | _PAGE_EXEC | \ _PAGE_READ | _PAGE_WRITE | _PAGE_DIRTY | _PAGE_EXEC | \
_PAGE_SOFT_DIRTY) _PAGE_SOFT_DIRTY | H_PTE_PKEY)
/* /*
* We define 2 sets of base prot bits, one for basic pages (ie, * We define 2 sets of base prot bits, one for basic pages (ie,
* cacheable kernel and user pages) and one for non cacheable * cacheable kernel and user pages) and one for non cacheable
......
...@@ -33,7 +33,13 @@ static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot, ...@@ -33,7 +33,13 @@ static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot,
static inline pgprot_t arch_vm_get_page_prot(unsigned long vm_flags) static inline pgprot_t arch_vm_get_page_prot(unsigned long vm_flags)
{ {
#ifdef CONFIG_PPC_MEM_KEYS
return (vm_flags & VM_SAO) ?
__pgprot(_PAGE_SAO | vmflag_to_pte_pkey_bits(vm_flags)) :
__pgprot(0 | vmflag_to_pte_pkey_bits(vm_flags));
#else
return (vm_flags & VM_SAO) ? __pgprot(_PAGE_SAO) : __pgprot(0); return (vm_flags & VM_SAO) ? __pgprot(_PAGE_SAO) : __pgprot(0);
#endif
} }
#define arch_vm_get_page_prot(vm_flags) arch_vm_get_page_prot(vm_flags) #define arch_vm_get_page_prot(vm_flags) arch_vm_get_page_prot(vm_flags)
......
...@@ -41,6 +41,18 @@ static inline u64 pkey_to_vmflag_bits(u16 pkey) ...@@ -41,6 +41,18 @@ static inline u64 pkey_to_vmflag_bits(u16 pkey)
return (((u64)pkey << VM_PKEY_SHIFT) & ARCH_VM_PKEY_FLAGS); return (((u64)pkey << VM_PKEY_SHIFT) & ARCH_VM_PKEY_FLAGS);
} }
static inline u64 vmflag_to_pte_pkey_bits(u64 vm_flags)
{
if (static_branch_likely(&pkey_disabled))
return 0x0UL;
return (((vm_flags & VM_PKEY_BIT0) ? H_PTE_PKEY_BIT4 : 0x0UL) |
((vm_flags & VM_PKEY_BIT1) ? H_PTE_PKEY_BIT3 : 0x0UL) |
((vm_flags & VM_PKEY_BIT2) ? H_PTE_PKEY_BIT2 : 0x0UL) |
((vm_flags & VM_PKEY_BIT3) ? H_PTE_PKEY_BIT1 : 0x0UL) |
((vm_flags & VM_PKEY_BIT4) ? H_PTE_PKEY_BIT0 : 0x0UL));
}
static inline int vma_pkey(struct vm_area_struct *vma) static inline int vma_pkey(struct vm_area_struct *vma)
{ {
if (static_branch_likely(&pkey_disabled)) if (static_branch_likely(&pkey_disabled))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment