Skip to content

Commit 367b51a

Browse files
Automatic merge of 'fixes' into merge (2026-03-13 12:43)
2 parents 06f8e2d + 82f73ef commit 367b51a

14 files changed

Lines changed: 107 additions & 77 deletions

File tree

arch/powerpc/include/asm/uaccess.h

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
#define TASK_SIZE_MAX TASK_SIZE_USER64
1616
#endif
1717

18+
/* Threshold above which VMX copy path is used */
19+
#define VMX_COPY_THRESHOLD 3328
20+
1821
#include <asm-generic/access_ok.h>
1922

2023
/*
@@ -326,40 +329,62 @@ do { \
326329
extern unsigned long __copy_tofrom_user(void __user *to,
327330
const void __user *from, unsigned long size);
328331

329-
#ifdef __powerpc64__
330-
static inline unsigned long
331-
raw_copy_in_user(void __user *to, const void __user *from, unsigned long n)
332+
unsigned long __copy_tofrom_user_base(void __user *to,
333+
const void __user *from, unsigned long size);
334+
335+
unsigned long __copy_tofrom_user_power7_vmx(void __user *to,
336+
const void __user *from, unsigned long size);
337+
338+
static __always_inline bool will_use_vmx(unsigned long n)
339+
{
340+
return IS_ENABLED(CONFIG_ALTIVEC) && cpu_has_feature(CPU_FTR_VMX_COPY) &&
341+
n > VMX_COPY_THRESHOLD;
342+
}
343+
344+
static __always_inline unsigned long
345+
raw_copy_tofrom_user(void __user *to, const void __user *from,
346+
unsigned long n, unsigned long dir)
332347
{
333348
unsigned long ret;
334349

335-
barrier_nospec();
336-
allow_user_access(to, KUAP_READ_WRITE);
350+
if (will_use_vmx(n) && enter_vmx_usercopy()) {
351+
allow_user_access(to, dir);
352+
ret = __copy_tofrom_user_power7_vmx(to, from, n);
353+
prevent_user_access(dir);
354+
exit_vmx_usercopy();
355+
356+
if (unlikely(ret)) {
357+
allow_user_access(to, dir);
358+
ret = __copy_tofrom_user_base(to, from, n);
359+
prevent_user_access(dir);
360+
}
361+
return ret;
362+
}
363+
364+
allow_user_access(to, dir);
337365
ret = __copy_tofrom_user(to, from, n);
338-
prevent_user_access(KUAP_READ_WRITE);
366+
prevent_user_access(dir);
339367
return ret;
340368
}
341-
#endif /* __powerpc64__ */
342369

343-
static inline unsigned long raw_copy_from_user(void *to,
344-
const void __user *from, unsigned long n)
370+
#ifdef CONFIG_PPC64
371+
static inline unsigned long
372+
raw_copy_in_user(void __user *to, const void __user *from, unsigned long n)
345373
{
346-
unsigned long ret;
374+
barrier_nospec();
375+
return raw_copy_tofrom_user(to, from, n, KUAP_READ_WRITE);
376+
}
377+
#endif /* CONFIG_PPC64 */
347378

348-
allow_user_access(NULL, KUAP_READ);
349-
ret = __copy_tofrom_user((__force void __user *)to, from, n);
350-
prevent_user_access(KUAP_READ);
351-
return ret;
379+
static inline unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n)
380+
{
381+
return raw_copy_tofrom_user((__force void __user *)to, from, n, KUAP_READ);
352382
}
353383

354384
static inline unsigned long
355385
raw_copy_to_user(void __user *to, const void *from, unsigned long n)
356386
{
357-
unsigned long ret;
358-
359-
allow_user_access(to, KUAP_WRITE);
360-
ret = __copy_tofrom_user(to, (__force const void __user *)from, n);
361-
prevent_user_access(KUAP_WRITE);
362-
return ret;
387+
return raw_copy_tofrom_user(to, (__force const void __user *)from, n, KUAP_WRITE);
363388
}
364389

365390
unsigned long __arch_clear_user(void __user *addr, unsigned long size);

arch/powerpc/kernel/iommu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1159,7 +1159,7 @@ spapr_tce_platform_iommu_attach_dev(struct iommu_domain *platform_domain,
11591159
struct device *dev,
11601160
struct iommu_domain *old)
11611161
{
1162-
struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
1162+
struct iommu_domain *domain = iommu_driver_get_domain_for_dev(dev);
11631163
struct iommu_table_group *table_group;
11641164
struct iommu_group *grp;
11651165

arch/powerpc/kernel/setup-common.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
#include <linux/of_irq.h>
3636
#include <linux/hugetlb.h>
3737
#include <linux/pgtable.h>
38-
#include <asm/kexec.h>
3938
#include <asm/io.h>
4039
#include <asm/paca.h>
4140
#include <asm/processor.h>
@@ -995,15 +994,6 @@ void __init setup_arch(char **cmdline_p)
995994

996995
initmem_init();
997996

998-
/*
999-
* Reserve large chunks of memory for use by CMA for kdump, fadump, KVM and
1000-
* hugetlb. These must be called after initmem_init(), so that
1001-
* pageblock_order is initialised.
1002-
*/
1003-
fadump_cma_init();
1004-
kdump_cma_reserve();
1005-
kvm_cma_reserve();
1006-
1007997
early_memtest(min_low_pfn << PAGE_SHIFT, max_low_pfn << PAGE_SHIFT);
1008998

1009999
if (ppc_md.setup_arch)

arch/powerpc/lib/copyuser_64.S

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,3 +562,4 @@ exc; std r10,32(3)
562562
li r5,4096
563563
b .Ldst_aligned
564564
EXPORT_SYMBOL(__copy_tofrom_user)
565+
EXPORT_SYMBOL(__copy_tofrom_user_base)

arch/powerpc/lib/copyuser_power7.S

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,9 @@
55
*
66
* Author: Anton Blanchard <anton@au.ibm.com>
77
*/
8+
#include <linux/export.h>
89
#include <asm/ppc_asm.h>
910

10-
#ifndef SELFTEST_CASE
11-
/* 0 == don't use VMX, 1 == use VMX */
12-
#define SELFTEST_CASE 0
13-
#endif
14-
1511
#ifdef __BIG_ENDIAN__
1612
#define LVS(VRT,RA,RB) lvsl VRT,RA,RB
1713
#define VPERM(VRT,VRA,VRB,VRC) vperm VRT,VRA,VRB,VRC
@@ -47,10 +43,14 @@
4743
ld r15,STK_REG(R15)(r1)
4844
ld r14,STK_REG(R14)(r1)
4945
.Ldo_err3:
50-
bl CFUNC(exit_vmx_usercopy)
46+
ld r6,STK_REG(R31)(r1) /* original destination pointer */
47+
ld r5,STK_REG(R29)(r1) /* original number of bytes */
48+
subf r7,r6,r3 /* #bytes copied */
49+
subf r3,r7,r5 /* #bytes not copied in r3 */
5150
ld r0,STACKFRAMESIZE+16(r1)
5251
mtlr r0
53-
b .Lexit
52+
addi r1,r1,STACKFRAMESIZE
53+
blr
5454
#endif /* CONFIG_ALTIVEC */
5555

5656
.Ldo_err2:
@@ -74,20 +74,13 @@
7474

7575
_GLOBAL(__copy_tofrom_user_power7)
7676
cmpldi r5,16
77-
cmpldi cr1,r5,3328
7877

7978
std r3,-STACKFRAMESIZE+STK_REG(R31)(r1)
8079
std r4,-STACKFRAMESIZE+STK_REG(R30)(r1)
8180
std r5,-STACKFRAMESIZE+STK_REG(R29)(r1)
8281

8382
blt .Lshort_copy
8483

85-
#ifdef CONFIG_ALTIVEC
86-
test_feature = SELFTEST_CASE
87-
BEGIN_FTR_SECTION
88-
bgt cr1,.Lvmx_copy
89-
END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
90-
#endif
9184

9285
.Lnonvmx_copy:
9386
/* Get the source 8B aligned */
@@ -263,23 +256,14 @@ err1; stb r0,0(r3)
263256
15: li r3,0
264257
blr
265258

266-
.Lunwind_stack_nonvmx_copy:
267-
addi r1,r1,STACKFRAMESIZE
268-
b .Lnonvmx_copy
269-
270-
.Lvmx_copy:
271259
#ifdef CONFIG_ALTIVEC
260+
_GLOBAL(__copy_tofrom_user_power7_vmx)
272261
mflr r0
273262
std r0,16(r1)
274263
stdu r1,-STACKFRAMESIZE(r1)
275-
bl CFUNC(enter_vmx_usercopy)
276-
cmpwi cr1,r3,0
277-
ld r0,STACKFRAMESIZE+16(r1)
278-
ld r3,STK_REG(R31)(r1)
279-
ld r4,STK_REG(R30)(r1)
280-
ld r5,STK_REG(R29)(r1)
281-
mtlr r0
282264

265+
std r3,STK_REG(R31)(r1)
266+
std r5,STK_REG(R29)(r1)
283267
/*
284268
* We prefetch both the source and destination using enhanced touch
285269
* instructions. We use a stream ID of 0 for the load side and
@@ -300,8 +284,6 @@ err1; stb r0,0(r3)
300284

301285
DCBT_SETUP_STREAMS(r6, r7, r9, r10, r8)
302286

303-
beq cr1,.Lunwind_stack_nonvmx_copy
304-
305287
/*
306288
* If source and destination are not relatively aligned we use a
307289
* slower permute loop.
@@ -478,7 +460,8 @@ err3; lbz r0,0(r4)
478460
err3; stb r0,0(r3)
479461

480462
15: addi r1,r1,STACKFRAMESIZE
481-
b CFUNC(exit_vmx_usercopy) /* tail call optimise */
463+
li r3,0
464+
blr
482465

483466
.Lvmx_unaligned_copy:
484467
/* Get the destination 16B aligned */
@@ -681,5 +664,7 @@ err3; lbz r0,0(r4)
681664
err3; stb r0,0(r3)
682665

683666
15: addi r1,r1,STACKFRAMESIZE
684-
b CFUNC(exit_vmx_usercopy) /* tail call optimise */
667+
li r3,0
668+
blr
669+
EXPORT_SYMBOL(__copy_tofrom_user_power7_vmx)
685670
#endif /* CONFIG_ALTIVEC */

arch/powerpc/lib/vmx-helper.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ int enter_vmx_usercopy(void)
2727

2828
return 1;
2929
}
30+
EXPORT_SYMBOL(enter_vmx_usercopy);
3031

3132
/*
3233
* This function must return 0 because we tail call optimise when calling
@@ -49,6 +50,7 @@ int exit_vmx_usercopy(void)
4950
set_dec(1);
5051
return 0;
5152
}
53+
EXPORT_SYMBOL(exit_vmx_usercopy);
5254

5355
int enter_vmx_ops(void)
5456
{

arch/powerpc/mm/mem.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
#include <asm/setup.h>
3131
#include <asm/fixmap.h>
3232

33+
#include <asm/fadump.h>
34+
#include <asm/kexec.h>
35+
#include <asm/kvm_ppc.h>
36+
3337
#include <mm/mmu_decl.h>
3438

3539
unsigned long long memory_limit __initdata;
@@ -268,6 +272,16 @@ void __init paging_init(void)
268272

269273
void __init arch_mm_preinit(void)
270274
{
275+
276+
/*
277+
* Reserve large chunks of memory for use by CMA for kdump, fadump, KVM
278+
* and hugetlb. These must be called after pageblock_order is
279+
* initialised.
280+
*/
281+
fadump_cma_init();
282+
kdump_cma_reserve();
283+
kvm_cma_reserve();
284+
271285
/*
272286
* book3s is limited to 16 page sizes due to encoding this in
273287
* a 4-bit field for slices.

arch/powerpc/perf/callchain.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re
103103
void
104104
perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
105105
{
106+
perf_callchain_store(entry, perf_arch_instruction_pointer(regs));
107+
108+
if (!current->mm)
109+
return;
110+
106111
if (!is_32bit_task())
107112
perf_callchain_user_64(entry, regs);
108113
else

arch/powerpc/perf/callchain_32.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,6 @@ void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
142142
next_ip = perf_arch_instruction_pointer(regs);
143143
lr = regs->link;
144144
sp = regs->gpr[1];
145-
perf_callchain_store(entry, next_ip);
146145

147146
while (entry->nr < entry->max_stack) {
148147
fp = (unsigned int __user *) (unsigned long) sp;

arch/powerpc/perf/callchain_64.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
7777
next_ip = perf_arch_instruction_pointer(regs);
7878
lr = regs->link;
7979
sp = regs->gpr[1];
80-
perf_callchain_store(entry, next_ip);
8180

8281
while (entry->nr < entry->max_stack) {
8382
fp = (unsigned long __user *) sp;

0 commit comments

Comments
 (0)