Skip to content

Commit d96095e

Browse files
Automatic merge of 'next-test' into merge-test (2026-03-17 14:03)
2 parents 4f37907 + 217e0d3 commit d96095e

File tree

13 files changed

+111
-82
lines changed

13 files changed

+111
-82
lines changed

Documentation/rust/arch-support.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Architecture Level of support Constraints
1818
``arm`` Maintained ARMv7 Little Endian only.
1919
``arm64`` Maintained Little Endian only.
2020
``loongarch`` Maintained \-
21+
``powerpc`` Maintained 64-bit Little Endian. 32-bit Big Endian.
2122
``riscv`` Maintained ``riscv64`` and LLVM/Clang only.
2223
``um`` Maintained \-
2324
``x86`` Maintained ``x86_64`` only.

arch/powerpc/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,8 @@ config PPC
284284
select HAVE_REGS_AND_STACK_ACCESS_API
285285
select HAVE_RELIABLE_STACKTRACE
286286
select HAVE_RSEQ
287+
select HAVE_RUST if PPC32
288+
select HAVE_RUST if PPC64 && CPU_LITTLE_ENDIAN
287289
select HAVE_SAMPLE_FTRACE_DIRECT if HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
288290
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI if HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
289291
select HAVE_SETUP_PER_CPU_AREA if PPC64

arch/powerpc/Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ else
6161
KBUILD_LDFLAGS_MODULE += $(objtree)/arch/powerpc/lib/crtsavres.o
6262
endif
6363

64+
ifdef CONFIG_PPC64
65+
KBUILD_RUSTFLAGS += --target=powerpc64le-unknown-linux-gnu
66+
KBUILD_RUSTFLAGS += -Ctarget-feature=-mma,-vsx,-hard-float,-altivec
67+
else
68+
KBUILD_RUSTFLAGS += --target=powerpc-unknown-linux-gnu
69+
endif
70+
6471
ifdef CONFIG_CPU_LITTLE_ENDIAN
6572
KBUILD_CPPFLAGS += -mlittle-endian
6673
KBUILD_LDFLAGS += -EL

arch/powerpc/include/asm/book3s/64/pgtable.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@
107107
* in here, on radix we expect them to be zero.
108108
*/
109109
#define _HPAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \
110-
_PAGE_ACCESSED | H_PAGE_THP_HUGE | _PAGE_PTE | \
111-
_PAGE_SOFT_DIRTY)
110+
_PAGE_ACCESSED | H_PAGE_THP_HUGE | _PAGE_SPECIAL | \
111+
_PAGE_PTE | _PAGE_SOFT_DIRTY)
112112
/*
113113
* user access blocked by key
114114
*/
@@ -1313,12 +1313,27 @@ static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
13131313
{
13141314
pmd_t old_pmd;
13151315

1316+
/*
1317+
* Non-present PMDs can be migration entries or device-private THP
1318+
* entries. This can happen at 2 places:
1319+
* - When the address space is being unmapped zap_huge_pmd(), and we
1320+
* encounter non-present pmds.
1321+
* - migrate_vma_collect_huge_pmd() could calls this during migration
1322+
* of device-private pmd entries.
1323+
*/
1324+
if (!pmd_present(*pmdp)) {
1325+
old_pmd = READ_ONCE(*pmdp);
1326+
pmd_clear(pmdp);
1327+
goto out;
1328+
}
1329+
13161330
if (radix_enabled()) {
13171331
old_pmd = radix__pmdp_huge_get_and_clear(mm, addr, pmdp);
13181332
} else {
13191333
old_pmd = hash__pmdp_huge_get_and_clear(mm, addr, pmdp);
13201334
}
13211335

1336+
out:
13221337
page_table_check_pmd_clear(mm, addr, old_pmd);
13231338

13241339
return old_pmd;
@@ -1400,7 +1415,6 @@ static inline bool arch_needs_pgtable_deposit(void)
14001415
return false;
14011416
return true;
14021417
}
1403-
extern void serialize_against_pte_lookup(struct mm_struct *mm);
14041418

14051419
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
14061420

arch/powerpc/include/asm/book3s/64/tlbflush-radix.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ extern void radix__flush_tlb_page_psize(struct mm_struct *mm, unsigned long vmad
9292
#define radix__flush_tlb_page(vma,addr) radix__local_flush_tlb_page(vma,addr)
9393
#define radix__flush_tlb_page_psize(mm,addr,p) radix__local_flush_tlb_page_psize(mm,addr,p)
9494
#endif
95-
extern void radix__flush_tlb_pwc(struct mmu_gather *tlb, unsigned long addr);
9695
extern void radix__flush_tlb_collapsed_pmd(struct mm_struct *mm, unsigned long addr);
9796
extern void radix__flush_tlb_all(void);
9897

arch/powerpc/include/asm/jump_label.h

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,20 @@
1515
#define JUMP_ENTRY_TYPE stringify_in_c(FTR_ENTRY_LONG)
1616
#define JUMP_LABEL_NOP_SIZE 4
1717

18+
#define JUMP_TABLE_ENTRY(key, label) \
19+
".pushsection __jump_table, \"aw\" \n\t" \
20+
".long 1b - ., " label " - . \n\t" \
21+
JUMP_ENTRY_TYPE key " - . \n\t" \
22+
".popsection \n\t"
23+
24+
#define ARCH_STATIC_BRANCH_ASM(key, label) \
25+
"1: nop \n\t" \
26+
JUMP_TABLE_ENTRY(key,label)
27+
1828
static __always_inline bool arch_static_branch(struct static_key *key, bool branch)
1929
{
20-
asm goto("1:\n\t"
21-
"nop # arch_static_branch\n\t"
22-
".pushsection __jump_table, \"aw\"\n\t"
23-
".long 1b - ., %l[l_yes] - .\n\t"
24-
JUMP_ENTRY_TYPE "%c0 - .\n\t"
25-
".popsection \n\t"
30+
asm goto(
31+
ARCH_STATIC_BRANCH_ASM("%c0", "%l[l_yes]")
2632
: : "i" (&((char *)key)[branch]) : : l_yes);
2733

2834
return false;
@@ -34,10 +40,7 @@ static __always_inline bool arch_static_branch_jump(struct static_key *key, bool
3440
{
3541
asm goto("1:\n\t"
3642
"b %l[l_yes] # arch_static_branch_jump\n\t"
37-
".pushsection __jump_table, \"aw\"\n\t"
38-
".long 1b - ., %l[l_yes] - .\n\t"
39-
JUMP_ENTRY_TYPE "%c0 - .\n\t"
40-
".popsection \n\t"
43+
JUMP_TABLE_ENTRY("%c0", "%l[l_yes]")
4144
: : "i" (&((char *)key)[branch]) : : l_yes);
4245

4346
return false;

arch/powerpc/kernel/setup-common.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,10 @@ static __init void print_system_info(void)
865865
cur_cpu_spec->cpu_user_features,
866866
cur_cpu_spec->cpu_user_features2);
867867
pr_info("mmu_features = 0x%08x\n", cur_cpu_spec->mmu_features);
868+
pr_info(" possible = 0x%016lx\n",
869+
(unsigned long)MMU_FTRS_POSSIBLE);
870+
pr_info(" always = 0x%016lx\n",
871+
(unsigned long)MMU_FTRS_ALWAYS);
868872
#ifdef CONFIG_PPC64
869873
pr_info("firmware_features = 0x%016lx\n", powerpc_firmware_features);
870874
#ifdef CONFIG_PPC_BOOK3S

arch/powerpc/mm/book3s64/hash_pgtable.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,27 @@ unsigned long hash__pmd_hugepage_update(struct mm_struct *mm, unsigned long addr
221221
return old;
222222
}
223223

224+
static void do_nothing(void *arg)
225+
{
226+
227+
}
228+
229+
/*
230+
* Serialize against __find_linux_pte() which does lock-less
231+
* lookup in page tables with local interrupts disabled. For huge pages
232+
* it casts pmd_t to pte_t. Since format of pte_t is different from
233+
* pmd_t we want to prevent transit from pmd pointing to page table
234+
* to pmd pointing to huge page (and back) while interrupts are disabled.
235+
* We clear pmd to possibly replace it with page table pointer in
236+
* different code paths. So make sure we wait for the parallel
237+
* __find_linux_pte() to finish.
238+
*/
239+
static void serialize_against_pte_lookup(struct mm_struct *mm)
240+
{
241+
smp_mb();
242+
smp_call_function_many(mm_cpumask(mm), do_nothing, mm, 1);
243+
}
244+
224245
pmd_t hash__pmdp_collapse_flush(struct vm_area_struct *vma, unsigned long address,
225246
pmd_t *pmdp)
226247
{

arch/powerpc/mm/book3s64/internal.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,4 @@ static inline bool slb_preload_disabled(void)
3131

3232
void hpt_do_stress(unsigned long ea, unsigned long hpte_group);
3333

34-
void exit_lazy_flush_tlb(struct mm_struct *mm, bool always_flush);
35-
3634
#endif /* ARCH_POWERPC_MM_BOOK3S64_INTERNAL_H */

arch/powerpc/mm/book3s64/pgtable.c

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
#include <mm/mmu_decl.h>
2424
#include <trace/events/thp.h>
2525

26-
#include "internal.h"
27-
2826
struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
2927
EXPORT_SYMBOL_GPL(mmu_psize_defs);
3028

@@ -150,31 +148,6 @@ void set_pud_at(struct mm_struct *mm, unsigned long addr,
150148
return set_pte_at_unchecked(mm, addr, pudp_ptep(pudp), pud_pte(pud));
151149
}
152150

153-
static void do_serialize(void *arg)
154-
{
155-
/* We've taken the IPI, so try to trim the mask while here */
156-
if (radix_enabled()) {
157-
struct mm_struct *mm = arg;
158-
exit_lazy_flush_tlb(mm, false);
159-
}
160-
}
161-
162-
/*
163-
* Serialize against __find_linux_pte() which does lock-less
164-
* lookup in page tables with local interrupts disabled. For huge pages
165-
* it casts pmd_t to pte_t. Since format of pte_t is different from
166-
* pmd_t we want to prevent transit from pmd pointing to page table
167-
* to pmd pointing to huge page (and back) while interrupts are disabled.
168-
* We clear pmd to possibly replace it with page table pointer in
169-
* different code paths. So make sure we wait for the parallel
170-
* __find_linux_pte() to finish.
171-
*/
172-
void serialize_against_pte_lookup(struct mm_struct *mm)
173-
{
174-
smp_mb();
175-
smp_call_function_many(mm_cpumask(mm), do_serialize, mm, 1);
176-
}
177-
178151
/*
179152
* We use this to invalidate a pmdp entry before switching from a
180153
* hugepte to regular pmd entry.
@@ -209,16 +182,21 @@ pmd_t pmdp_huge_get_and_clear_full(struct vm_area_struct *vma,
209182
unsigned long addr, pmd_t *pmdp, int full)
210183
{
211184
pmd_t pmd;
185+
bool was_present = pmd_present(*pmdp);
186+
212187
VM_BUG_ON(addr & ~HPAGE_PMD_MASK);
213-
VM_BUG_ON((pmd_present(*pmdp) && !pmd_trans_huge(*pmdp)) ||
214-
!pmd_present(*pmdp));
188+
VM_BUG_ON(was_present && !pmd_trans_huge(*pmdp));
189+
/*
190+
* Check pmdp_huge_get_and_clear() for non-present pmd case.
191+
*/
215192
pmd = pmdp_huge_get_and_clear(vma->vm_mm, addr, pmdp);
216193
/*
217194
* if it not a fullmm flush, then we can possibly end up converting
218195
* this PMD pte entry to a regular level 0 PTE by a parallel page fault.
219-
* Make sure we flush the tlb in this case.
196+
* Make sure we flush the tlb in this case. TLB flush not needed for
197+
* non-present case.
220198
*/
221-
if (!full)
199+
if (was_present && !full)
222200
flush_pmd_tlb_range(vma, addr, addr + HPAGE_PMD_SIZE);
223201
return pmd;
224202
}

0 commit comments

Comments
 (0)