Skip to content

Commit ccaeeec

Browse files
committed
Merge branch 'for-next/lpa2-prep' into for-next/core
* for-next/lpa2-prep: arm64: mm: get rid of kimage_vaddr global variable arm64: mm: Take potential load offset into account when KASLR is off arm64: kernel: Disable latent_entropy GCC plugin in early C runtime arm64: Add ARM64_HAS_LPA2 CPU capability arm64/mm: Add FEAT_LPA2 specific ID_AA64MMFR0.TGRAN[2] arm64/mm: Update tlb invalidation routines for FEAT_LPA2 arm64/mm: Add lpa2_is_enabled() kvm_lpa2_is_enabled() stubs arm64/mm: Modify range-based tlbi to decrement scale
2 parents 8861952 + 376f5a3 commit ccaeeec

File tree

13 files changed

+137
-71
lines changed

13 files changed

+137
-71
lines changed

arch/arm64/include/asm/cpufeature.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,11 @@ static inline bool system_supports_tlb_range(void)
820820
return alternative_has_cap_unlikely(ARM64_HAS_TLB_RANGE);
821821
}
822822

823+
static inline bool system_supports_lpa2(void)
824+
{
825+
return cpus_have_final_cap(ARM64_HAS_LPA2);
826+
}
827+
823828
int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt);
824829
bool try_emulate_mrs(struct pt_regs *regs, u32 isn);
825830

arch/arm64/include/asm/kernel-pgtable.h

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -37,27 +37,12 @@
3737

3838

3939
/*
40-
* If KASLR is enabled, then an offset K is added to the kernel address
41-
* space. The bottom 21 bits of this offset are zero to guarantee 2MB
42-
* alignment for PA and VA.
43-
*
44-
* For each pagetable level of the swapper, we know that the shift will
45-
* be larger than 21 (for the 4KB granule case we use section maps thus
46-
* the smallest shift is actually 30) thus there is the possibility that
47-
* KASLR can increase the number of pagetable entries by 1, so we make
48-
* room for this extra entry.
49-
*
50-
* Note KASLR cannot increase the number of required entries for a level
51-
* by more than one because it increments both the virtual start and end
52-
* addresses equally (the extra entry comes from the case where the end
53-
* address is just pushed over a boundary and the start address isn't).
40+
* A relocatable kernel may execute from an address that differs from the one at
41+
* which it was linked. In the worst case, its runtime placement may intersect
42+
* with two adjacent PGDIR entries, which means that an additional page table
43+
* may be needed at each subordinate level.
5444
*/
55-
56-
#ifdef CONFIG_RANDOMIZE_BASE
57-
#define EARLY_KASLR (1)
58-
#else
59-
#define EARLY_KASLR (0)
60-
#endif
45+
#define EXTRA_PAGE __is_defined(CONFIG_RELOCATABLE)
6146

6247
#define SPAN_NR_ENTRIES(vstart, vend, shift) \
6348
((((vend) - 1) >> (shift)) - ((vstart) >> (shift)) + 1)
@@ -83,7 +68,7 @@
8368
+ EARLY_PGDS((vstart), (vend), add) /* each PGDIR needs a next level page table */ \
8469
+ EARLY_PUDS((vstart), (vend), add) /* each PUD needs a next level page table */ \
8570
+ EARLY_PMDS((vstart), (vend), add)) /* each PMD needs a next level page table */
86-
#define INIT_DIR_SIZE (PAGE_SIZE * EARLY_PAGES(KIMAGE_VADDR, _end, EARLY_KASLR))
71+
#define INIT_DIR_SIZE (PAGE_SIZE * EARLY_PAGES(KIMAGE_VADDR, _end, EXTRA_PAGE))
8772

8873
/* the initial ID map may need two extra pages if it needs to be extended */
8974
#if VA_BITS < 48

arch/arm64/include/asm/kvm_pgtable.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
#define KVM_PGTABLE_MIN_BLOCK_LEVEL 2U
2626
#endif
2727

28+
#define kvm_lpa2_is_enabled() false
29+
2830
static inline u64 kvm_get_parange(u64 mmfr0)
2931
{
3032
u64 parange = cpuid_feature_extract_unsigned_field(mmfr0,

arch/arm64/include/asm/memory.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@
182182
#include <linux/types.h>
183183
#include <asm/boot.h>
184184
#include <asm/bug.h>
185+
#include <asm/sections.h>
185186

186187
#if VA_BITS > 48
187188
extern u64 vabits_actual;
@@ -193,15 +194,12 @@ extern s64 memstart_addr;
193194
/* PHYS_OFFSET - the physical address of the start of memory. */
194195
#define PHYS_OFFSET ({ VM_BUG_ON(memstart_addr & 1); memstart_addr; })
195196

196-
/* the virtual base of the kernel image */
197-
extern u64 kimage_vaddr;
198-
199197
/* the offset between the kernel virtual and physical mappings */
200198
extern u64 kimage_voffset;
201199

202200
static inline unsigned long kaslr_offset(void)
203201
{
204-
return kimage_vaddr - KIMAGE_VADDR;
202+
return (u64)&_text - KIMAGE_VADDR;
205203
}
206204

207205
#ifdef CONFIG_RANDOMIZE_BASE

arch/arm64/include/asm/pgtable-prot.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ extern bool arm64_use_ng_mappings;
7171
#define PTE_MAYBE_NG (arm64_use_ng_mappings ? PTE_NG : 0)
7272
#define PMD_MAYBE_NG (arm64_use_ng_mappings ? PMD_SECT_NG : 0)
7373

74+
#define lpa2_is_enabled() false
75+
7476
/*
7577
* If we have userspace only BTI we don't want to mark kernel pages
7678
* guarded even if the system does support BTI.

arch/arm64/include/asm/sysreg.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,17 +871,20 @@
871871

872872
/* id_aa64mmfr0 */
873873
#define ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED_MIN 0x0
874+
#define ID_AA64MMFR0_EL1_TGRAN4_LPA2 ID_AA64MMFR0_EL1_TGRAN4_52_BIT
874875
#define ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED_MAX 0x7
875876
#define ID_AA64MMFR0_EL1_TGRAN64_SUPPORTED_MIN 0x0
876877
#define ID_AA64MMFR0_EL1_TGRAN64_SUPPORTED_MAX 0x7
877878
#define ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED_MIN 0x1
879+
#define ID_AA64MMFR0_EL1_TGRAN16_LPA2 ID_AA64MMFR0_EL1_TGRAN16_52_BIT
878880
#define ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED_MAX 0xf
879881

880882
#define ARM64_MIN_PARANGE_BITS 32
881883

882884
#define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_DEFAULT 0x0
883885
#define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_NONE 0x1
884886
#define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_MIN 0x2
887+
#define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_LPA2 0x3
885888
#define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_MAX 0x7
886889

887890
#ifdef CONFIG_ARM64_PA_BITS_52
@@ -892,11 +895,13 @@
892895

893896
#if defined(CONFIG_ARM64_4K_PAGES)
894897
#define ID_AA64MMFR0_EL1_TGRAN_SHIFT ID_AA64MMFR0_EL1_TGRAN4_SHIFT
898+
#define ID_AA64MMFR0_EL1_TGRAN_LPA2 ID_AA64MMFR0_EL1_TGRAN4_52_BIT
895899
#define ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MIN ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED_MIN
896900
#define ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MAX ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED_MAX
897901
#define ID_AA64MMFR0_EL1_TGRAN_2_SHIFT ID_AA64MMFR0_EL1_TGRAN4_2_SHIFT
898902
#elif defined(CONFIG_ARM64_16K_PAGES)
899903
#define ID_AA64MMFR0_EL1_TGRAN_SHIFT ID_AA64MMFR0_EL1_TGRAN16_SHIFT
904+
#define ID_AA64MMFR0_EL1_TGRAN_LPA2 ID_AA64MMFR0_EL1_TGRAN16_52_BIT
900905
#define ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MIN ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED_MIN
901906
#define ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MAX ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED_MAX
902907
#define ID_AA64MMFR0_EL1_TGRAN_2_SHIFT ID_AA64MMFR0_EL1_TGRAN16_2_SHIFT

arch/arm64/include/asm/tlb.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ static void tlb_flush(struct mmu_gather *tlb);
2222
#include <asm-generic/tlb.h>
2323

2424
/*
25-
* get the tlbi levels in arm64. Default value is 0 if more than one
26-
* of cleared_* is set or neither is set.
27-
* Arm64 doesn't support p4ds now.
25+
* get the tlbi levels in arm64. Default value is TLBI_TTL_UNKNOWN if more than
26+
* one of cleared_* is set or neither is set - this elides the level hinting to
27+
* the hardware.
2828
*/
2929
static inline int tlb_get_level(struct mmu_gather *tlb)
3030
{
3131
/* The TTL field is only valid for the leaf entry. */
3232
if (tlb->freed_tables)
33-
return 0;
33+
return TLBI_TTL_UNKNOWN;
3434

3535
if (tlb->cleared_ptes && !(tlb->cleared_pmds ||
3636
tlb->cleared_puds ||
@@ -47,7 +47,12 @@ static inline int tlb_get_level(struct mmu_gather *tlb)
4747
tlb->cleared_p4ds))
4848
return 1;
4949

50-
return 0;
50+
if (tlb->cleared_p4ds && !(tlb->cleared_ptes ||
51+
tlb->cleared_pmds ||
52+
tlb->cleared_puds))
53+
return 0;
54+
55+
return TLBI_TTL_UNKNOWN;
5156
}
5257

5358
static inline void tlb_flush(struct mmu_gather *tlb)

arch/arm64/include/asm/tlbflush.h

Lines changed: 63 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -94,19 +94,22 @@ static inline unsigned long get_trans_granule(void)
9494
* When ARMv8.4-TTL exists, TLBI operations take an additional hint for
9595
* the level at which the invalidation must take place. If the level is
9696
* wrong, no invalidation may take place. In the case where the level
97-
* cannot be easily determined, a 0 value for the level parameter will
98-
* perform a non-hinted invalidation.
97+
* cannot be easily determined, the value TLBI_TTL_UNKNOWN will perform
98+
* a non-hinted invalidation. Any provided level outside the hint range
99+
* will also cause fall-back to non-hinted invalidation.
99100
*
100101
* For Stage-2 invalidation, use the level values provided to that effect
101102
* in asm/stage2_pgtable.h.
102103
*/
103104
#define TLBI_TTL_MASK GENMASK_ULL(47, 44)
104105

106+
#define TLBI_TTL_UNKNOWN INT_MAX
107+
105108
#define __tlbi_level(op, addr, level) do { \
106109
u64 arg = addr; \
107110
\
108111
if (alternative_has_cap_unlikely(ARM64_HAS_ARMv8_4_TTL) && \
109-
level) { \
112+
level >= 0 && level <= 3) { \
110113
u64 ttl = level & 3; \
111114
ttl |= get_trans_granule() << 2; \
112115
arg &= ~TLBI_TTL_MASK; \
@@ -122,28 +125,34 @@ static inline unsigned long get_trans_granule(void)
122125
} while (0)
123126

124127
/*
125-
* This macro creates a properly formatted VA operand for the TLB RANGE.
126-
* The value bit assignments are:
128+
* This macro creates a properly formatted VA operand for the TLB RANGE. The
129+
* value bit assignments are:
127130
*
128131
* +----------+------+-------+-------+-------+----------------------+
129132
* | ASID | TG | SCALE | NUM | TTL | BADDR |
130133
* +-----------------+-------+-------+-------+----------------------+
131134
* |63 48|47 46|45 44|43 39|38 37|36 0|
132135
*
133-
* The address range is determined by below formula:
134-
* [BADDR, BADDR + (NUM + 1) * 2^(5*SCALE + 1) * PAGESIZE)
136+
* The address range is determined by below formula: [BADDR, BADDR + (NUM + 1) *
137+
* 2^(5*SCALE + 1) * PAGESIZE)
138+
*
139+
* Note that the first argument, baddr, is pre-shifted; If LPA2 is in use, BADDR
140+
* holds addr[52:16]. Else BADDR holds page number. See for example ARM DDI
141+
* 0487J.a section C5.5.60 "TLBI VAE1IS, TLBI VAE1ISNXS, TLB Invalidate by VA,
142+
* EL1, Inner Shareable".
135143
*
136144
*/
137-
#define __TLBI_VADDR_RANGE(addr, asid, scale, num, ttl) \
138-
({ \
139-
unsigned long __ta = (addr) >> PAGE_SHIFT; \
140-
__ta &= GENMASK_ULL(36, 0); \
141-
__ta |= (unsigned long)(ttl) << 37; \
142-
__ta |= (unsigned long)(num) << 39; \
143-
__ta |= (unsigned long)(scale) << 44; \
144-
__ta |= get_trans_granule() << 46; \
145-
__ta |= (unsigned long)(asid) << 48; \
146-
__ta; \
145+
#define __TLBI_VADDR_RANGE(baddr, asid, scale, num, ttl) \
146+
({ \
147+
unsigned long __ta = (baddr); \
148+
unsigned long __ttl = (ttl >= 1 && ttl <= 3) ? ttl : 0; \
149+
__ta &= GENMASK_ULL(36, 0); \
150+
__ta |= __ttl << 37; \
151+
__ta |= (unsigned long)(num) << 39; \
152+
__ta |= (unsigned long)(scale) << 44; \
153+
__ta |= get_trans_granule() << 46; \
154+
__ta |= (unsigned long)(asid) << 48; \
155+
__ta; \
147156
})
148157

149158
/* These macros are used by the TLBI RANGE feature. */
@@ -216,12 +225,16 @@ static inline unsigned long get_trans_granule(void)
216225
* CPUs, ensuring that any walk-cache entries associated with the
217226
* translation are also invalidated.
218227
*
219-
* __flush_tlb_range(vma, start, end, stride, last_level)
228+
* __flush_tlb_range(vma, start, end, stride, last_level, tlb_level)
220229
* Invalidate the virtual-address range '[start, end)' on all
221230
* CPUs for the user address space corresponding to 'vma->mm'.
222231
* The invalidation operations are issued at a granularity
223232
* determined by 'stride' and only affect any walk-cache entries
224-
* if 'last_level' is equal to false.
233+
* if 'last_level' is equal to false. tlb_level is the level at
234+
* which the invalidation must take place. If the level is wrong,
235+
* no invalidation may take place. In the case where the level
236+
* cannot be easily determined, the value TLBI_TTL_UNKNOWN will
237+
* perform a non-hinted invalidation.
225238
*
226239
*
227240
* Finally, take a look at asm/tlb.h to see how tlb_flush() is implemented
@@ -345,34 +358,44 @@ static inline void arch_tlbbatch_flush(struct arch_tlbflush_unmap_batch *batch)
345358
* @tlb_level: Translation Table level hint, if known
346359
* @tlbi_user: If 'true', call an additional __tlbi_user()
347360
* (typically for user ASIDs). 'flase' for IPA instructions
361+
* @lpa2: If 'true', the lpa2 scheme is used as set out below
348362
*
349363
* When the CPU does not support TLB range operations, flush the TLB
350364
* entries one by one at the granularity of 'stride'. If the TLB
351365
* range ops are supported, then:
352366
*
353-
* 1. If 'pages' is odd, flush the first page through non-range
354-
* operations;
367+
* 1. If FEAT_LPA2 is in use, the start address of a range operation must be
368+
* 64KB aligned, so flush pages one by one until the alignment is reached
369+
* using the non-range operations. This step is skipped if LPA2 is not in
370+
* use.
371+
*
372+
* 2. The minimum range granularity is decided by 'scale', so multiple range
373+
* TLBI operations may be required. Start from scale = 3, flush the largest
374+
* possible number of pages ((num+1)*2^(5*scale+1)) that fit into the
375+
* requested range, then decrement scale and continue until one or zero pages
376+
* are left. We must start from highest scale to ensure 64KB start alignment
377+
* is maintained in the LPA2 case.
355378
*
356-
* 2. For remaining pages: the minimum range granularity is decided
357-
* by 'scale', so multiple range TLBI operations may be required.
358-
* Start from scale = 0, flush the corresponding number of pages
359-
* ((num+1)*2^(5*scale+1) starting from 'addr'), then increase it
360-
* until no pages left.
379+
* 3. If there is 1 page remaining, flush it through non-range operations. Range
380+
* operations can only span an even number of pages. We save this for last to
381+
* ensure 64KB start alignment is maintained for the LPA2 case.
361382
*
362383
* Note that certain ranges can be represented by either num = 31 and
363384
* scale or num = 0 and scale + 1. The loop below favours the latter
364385
* since num is limited to 30 by the __TLBI_RANGE_NUM() macro.
365386
*/
366387
#define __flush_tlb_range_op(op, start, pages, stride, \
367-
asid, tlb_level, tlbi_user) \
388+
asid, tlb_level, tlbi_user, lpa2) \
368389
do { \
369390
int num = 0; \
370-
int scale = 0; \
391+
int scale = 3; \
392+
int shift = lpa2 ? 16 : PAGE_SHIFT; \
371393
unsigned long addr; \
372394
\
373395
while (pages > 0) { \
374396
if (!system_supports_tlb_range() || \
375-
pages % 2 == 1) { \
397+
pages == 1 || \
398+
(lpa2 && start != ALIGN(start, SZ_64K))) { \
376399
addr = __TLBI_VADDR(start, asid); \
377400
__tlbi_level(op, addr, tlb_level); \
378401
if (tlbi_user) \
@@ -384,20 +407,20 @@ do { \
384407
\
385408
num = __TLBI_RANGE_NUM(pages, scale); \
386409
if (num >= 0) { \
387-
addr = __TLBI_VADDR_RANGE(start, asid, scale, \
388-
num, tlb_level); \
410+
addr = __TLBI_VADDR_RANGE(start >> shift, asid, \
411+
scale, num, tlb_level); \
389412
__tlbi(r##op, addr); \
390413
if (tlbi_user) \
391414
__tlbi_user(r##op, addr); \
392415
start += __TLBI_RANGE_PAGES(num, scale) << PAGE_SHIFT; \
393416
pages -= __TLBI_RANGE_PAGES(num, scale); \
394417
} \
395-
scale++; \
418+
scale--; \
396419
} \
397420
} while (0)
398421

399422
#define __flush_s2_tlb_range_op(op, start, pages, stride, tlb_level) \
400-
__flush_tlb_range_op(op, start, pages, stride, 0, tlb_level, false)
423+
__flush_tlb_range_op(op, start, pages, stride, 0, tlb_level, false, kvm_lpa2_is_enabled());
401424

402425
static inline void __flush_tlb_range(struct vm_area_struct *vma,
403426
unsigned long start, unsigned long end,
@@ -427,9 +450,11 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,
427450
asid = ASID(vma->vm_mm);
428451

429452
if (last_level)
430-
__flush_tlb_range_op(vale1is, start, pages, stride, asid, tlb_level, true);
453+
__flush_tlb_range_op(vale1is, start, pages, stride, asid,
454+
tlb_level, true, lpa2_is_enabled());
431455
else
432-
__flush_tlb_range_op(vae1is, start, pages, stride, asid, tlb_level, true);
456+
__flush_tlb_range_op(vae1is, start, pages, stride, asid,
457+
tlb_level, true, lpa2_is_enabled());
433458

434459
dsb(ish);
435460
mmu_notifier_arch_invalidate_secondary_tlbs(vma->vm_mm, start, end);
@@ -441,9 +466,10 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
441466
/*
442467
* We cannot use leaf-only invalidation here, since we may be invalidating
443468
* table entries as part of collapsing hugepages or moving page tables.
444-
* Set the tlb_level to 0 because we can not get enough information here.
469+
* Set the tlb_level to TLBI_TTL_UNKNOWN because we can not get enough
470+
* information here.
445471
*/
446-
__flush_tlb_range(vma, start, end, PAGE_SIZE, false, 0);
472+
__flush_tlb_range(vma, start, end, PAGE_SIZE, false, TLBI_TTL_UNKNOWN);
447473
}
448474

449475
static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end)

0 commit comments

Comments
 (0)