Skip to content

Commit 982a847

Browse files
committed
Merge branch 'for-next/poe' into for-next/core
* for-next/poe: (31 commits) arm64: pkeys: remove redundant WARN kselftest/arm64: Add test case for POR_EL0 signal frame records kselftest/arm64: parse POE_MAGIC in a signal frame kselftest/arm64: add HWCAP test for FEAT_S1POE selftests: mm: make protection_keys test work on arm64 selftests: mm: move fpregs printing kselftest/arm64: move get_header() arm64: add Permission Overlay Extension Kconfig arm64: enable PKEY support for CPUs with S1POE arm64: enable POE and PIE to coexist arm64/ptrace: add support for FEAT_POE arm64: add POE signal support arm64: implement PKEYS support arm64: add pte_access_permitted_no_overlay() arm64: handle PKEY/POE faults arm64: mask out POIndex when modifying a PTE arm64: convert protection key into vm_flags and pgprot values arm64: add POIndex defines arm64: re-order MTE VM_ flags arm64: enable the Permission Overlay Extension for EL0 ...
2 parents 3175e05 + 10166c2 commit 982a847

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1053
-62
lines changed

Documentation/arch/arm64/elf_hwcaps.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,8 @@ HWCAP2_SME_SF8DP2
365365
HWCAP2_SME_SF8DP4
366366
Functionality implied by ID_AA64SMFR0_EL1.SF8DP4 == 0b1.
367367

368+
HWCAP2_POE
369+
Functionality implied by ID_AA64MMFR3_EL1.S1POE == 0b0001.
368370

369371
4. Unused AT_HWCAP bits
370372
-----------------------

arch/arm64/Kconfig

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2138,6 +2138,29 @@ config ARM64_EPAN
21382138
if the cpu does not implement the feature.
21392139
endmenu # "ARMv8.7 architectural features"
21402140

2141+
menu "ARMv8.9 architectural features"
2142+
2143+
config ARM64_POE
2144+
prompt "Permission Overlay Extension"
2145+
def_bool y
2146+
select ARCH_USES_HIGH_VMA_FLAGS
2147+
select ARCH_HAS_PKEYS
2148+
help
2149+
The Permission Overlay Extension is used to implement Memory
2150+
Protection Keys. Memory Protection Keys provides a mechanism for
2151+
enforcing page-based protections, but without requiring modification
2152+
of the page tables when an application changes protection domains.
2153+
2154+
For details, see Documentation/core-api/protection-keys.rst
2155+
2156+
If unsure, say y.
2157+
2158+
config ARCH_PKEY_BITS
2159+
int
2160+
default 3
2161+
2162+
endmenu # "ARMv8.9 architectural features"
2163+
21412164
config ARM64_SVE
21422165
bool "ARM Scalable Vector Extension support"
21432166
default y

arch/arm64/include/asm/cpufeature.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,12 @@ static inline bool system_supports_lpa2(void)
832832
return cpus_have_final_cap(ARM64_HAS_LPA2);
833833
}
834834

835+
static inline bool system_supports_poe(void)
836+
{
837+
return IS_ENABLED(CONFIG_ARM64_POE) &&
838+
alternative_has_cap_unlikely(ARM64_HAS_S1POE);
839+
}
840+
835841
int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt);
836842
bool try_emulate_mrs(struct pt_regs *regs, u32 isn);
837843

arch/arm64/include/asm/el2_setup.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,14 @@
192192
orr x0, x0, #HFGxTR_EL2_nPIRE0_EL1
193193

194194
.Lskip_pie_fgt_\@:
195+
mrs_s x1, SYS_ID_AA64MMFR3_EL1
196+
ubfx x1, x1, #ID_AA64MMFR3_EL1_S1POE_SHIFT, #4
197+
cbz x1, .Lskip_poe_fgt_\@
198+
199+
/* Disable trapping of POR_EL0 */
200+
orr x0, x0, #HFGxTR_EL2_nPOR_EL0
201+
202+
.Lskip_poe_fgt_\@:
195203
msr_s SYS_HFGRTR_EL2, x0
196204
msr_s SYS_HFGWTR_EL2, x0
197205
msr_s SYS_HFGITR_EL2, xzr

arch/arm64/include/asm/hwcap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@
157157
#define KERNEL_HWCAP_SME_SF8FMA __khwcap2_feature(SME_SF8FMA)
158158
#define KERNEL_HWCAP_SME_SF8DP4 __khwcap2_feature(SME_SF8DP4)
159159
#define KERNEL_HWCAP_SME_SF8DP2 __khwcap2_feature(SME_SF8DP2)
160+
#define KERNEL_HWCAP_POE __khwcap2_feature(POE)
160161

161162
/*
162163
* This yields a mask that user programs can use to figure out what

arch/arm64/include/asm/kvm_asm.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <asm/hyp_image.h>
1111
#include <asm/insn.h>
1212
#include <asm/virt.h>
13+
#include <asm/sysreg.h>
1314

1415
#define ARM_EXIT_WITH_SERROR_BIT 31
1516
#define ARM_EXCEPTION_CODE(x) ((x) & ~(1U << ARM_EXIT_WITH_SERROR_BIT))
@@ -259,7 +260,7 @@ extern u64 __kvm_get_mdcr_el2(void);
259260
asm volatile( \
260261
" mrs %1, spsr_el2\n" \
261262
" mrs %2, elr_el2\n" \
262-
"1: at "at_op", %3\n" \
263+
"1: " __msr_s(at_op, "%3") "\n" \
263264
" isb\n" \
264265
" b 9f\n" \
265266
"2: msr spsr_el2, %1\n" \

arch/arm64/include/asm/kvm_host.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,8 @@ enum vcpu_sysreg {
446446
GCR_EL1, /* Tag Control Register */
447447
TFSRE0_EL1, /* Tag Fault Status Register (EL0) */
448448

449+
POR_EL0, /* Permission Overlay Register 0 (EL0) */
450+
449451
/* 32bit specific registers. */
450452
DACR32_EL2, /* Domain Access Control Register */
451453
IFSR32_EL2, /* Instruction Fault Status Register */
@@ -517,6 +519,8 @@ enum vcpu_sysreg {
517519
VNCR(PIR_EL1), /* Permission Indirection Register 1 (EL1) */
518520
VNCR(PIRE0_EL1), /* Permission Indirection Register 0 (EL1) */
519521

522+
VNCR(POR_EL1), /* Permission Overlay Register 1 (EL1) */
523+
520524
VNCR(HFGRTR_EL2),
521525
VNCR(HFGWTR_EL2),
522526
VNCR(HFGITR_EL2),

arch/arm64/include/asm/mman.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#include <uapi/asm/mman.h>
88

99
static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot,
10-
unsigned long pkey __always_unused)
10+
unsigned long pkey)
1111
{
1212
unsigned long ret = 0;
1313

@@ -17,6 +17,14 @@ static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot,
1717
if (system_supports_mte() && (prot & PROT_MTE))
1818
ret |= VM_MTE;
1919

20+
#ifdef CONFIG_ARCH_HAS_PKEYS
21+
if (system_supports_poe()) {
22+
ret |= pkey & BIT(0) ? VM_PKEY_BIT0 : 0;
23+
ret |= pkey & BIT(1) ? VM_PKEY_BIT1 : 0;
24+
ret |= pkey & BIT(2) ? VM_PKEY_BIT2 : 0;
25+
}
26+
#endif
27+
2028
return ret;
2129
}
2230
#define arch_calc_vm_prot_bits(prot, pkey) arch_calc_vm_prot_bits(prot, pkey)

arch/arm64/include/asm/mmu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ typedef struct {
2525
refcount_t pinned;
2626
void *vdso;
2727
unsigned long flags;
28+
u8 pkey_allocation_map;
2829
} mm_context_t;
2930

3031
/*

arch/arm64/include/asm/mmu_context.h

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@
1515
#include <linux/sched/hotplug.h>
1616
#include <linux/mm_types.h>
1717
#include <linux/pgtable.h>
18+
#include <linux/pkeys.h>
1819

1920
#include <asm/cacheflush.h>
2021
#include <asm/cpufeature.h>
2122
#include <asm/daifflags.h>
2223
#include <asm/proc-fns.h>
23-
#include <asm-generic/mm_hooks.h>
2424
#include <asm/cputype.h>
2525
#include <asm/sysreg.h>
2626
#include <asm/tlbflush.h>
@@ -175,9 +175,36 @@ init_new_context(struct task_struct *tsk, struct mm_struct *mm)
175175
{
176176
atomic64_set(&mm->context.id, 0);
177177
refcount_set(&mm->context.pinned, 0);
178+
179+
/* pkey 0 is the default, so always reserve it. */
180+
mm->context.pkey_allocation_map = BIT(0);
181+
182+
return 0;
183+
}
184+
185+
static inline void arch_dup_pkeys(struct mm_struct *oldmm,
186+
struct mm_struct *mm)
187+
{
188+
/* Duplicate the oldmm pkey state in mm: */
189+
mm->context.pkey_allocation_map = oldmm->context.pkey_allocation_map;
190+
}
191+
192+
static inline int arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm)
193+
{
194+
arch_dup_pkeys(oldmm, mm);
195+
178196
return 0;
179197
}
180198

199+
static inline void arch_exit_mmap(struct mm_struct *mm)
200+
{
201+
}
202+
203+
static inline void arch_unmap(struct mm_struct *mm,
204+
unsigned long start, unsigned long end)
205+
{
206+
}
207+
181208
#ifdef CONFIG_ARM64_SW_TTBR0_PAN
182209
static inline void update_saved_ttbr0(struct task_struct *tsk,
183210
struct mm_struct *mm)
@@ -267,6 +294,23 @@ static inline unsigned long mm_untag_mask(struct mm_struct *mm)
267294
return -1UL >> 8;
268295
}
269296

297+
/*
298+
* Only enforce protection keys on the current process, because there is no
299+
* user context to access POR_EL0 for another address space.
300+
*/
301+
static inline bool arch_vma_access_permitted(struct vm_area_struct *vma,
302+
bool write, bool execute, bool foreign)
303+
{
304+
if (!system_supports_poe())
305+
return true;
306+
307+
/* allow access if the VMA is not one from this process */
308+
if (foreign || vma_is_foreign(vma))
309+
return true;
310+
311+
return por_el0_allows_pkey(vma_pkey(vma), write, execute);
312+
}
313+
270314
#include <asm-generic/mmu_context.h>
271315

272316
#endif /* !__ASSEMBLY__ */

0 commit comments

Comments
 (0)