Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/powerpc/lib/vmx-helper.c
26444 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
*
4
* Copyright (C) IBM Corporation, 2011
5
*
6
* Authors: Sukadev Bhattiprolu <[email protected]>
7
* Anton Blanchard <[email protected]>
8
*/
9
#include <linux/uaccess.h>
10
#include <linux/hardirq.h>
11
#include <asm/switch_to.h>
12
13
int enter_vmx_usercopy(void)
14
{
15
if (in_interrupt())
16
return 0;
17
18
preempt_disable();
19
/*
20
* We need to disable page faults as they can call schedule and
21
* thus make us lose the VMX context. So on page faults, we just
22
* fail which will cause a fallback to the normal non-vmx copy.
23
*/
24
pagefault_disable();
25
26
enable_kernel_altivec();
27
28
return 1;
29
}
30
31
/*
32
* This function must return 0 because we tail call optimise when calling
33
* from __copy_tofrom_user_power7 which returns 0 on success.
34
*/
35
int exit_vmx_usercopy(void)
36
{
37
disable_kernel_altivec();
38
pagefault_enable();
39
preempt_enable_no_resched();
40
/*
41
* Must never explicitly call schedule (including preempt_enable())
42
* while in a kuap-unlocked user copy, because the AMR register will
43
* not be saved and restored across context switch. However preempt
44
* kernels need to be preempted as soon as possible if need_resched is
45
* set and we are preemptible. The hack here is to schedule a
46
* decrementer to fire here and reschedule for us if necessary.
47
*/
48
if (need_irq_preemption() && need_resched())
49
set_dec(1);
50
return 0;
51
}
52
53
int enter_vmx_ops(void)
54
{
55
if (in_interrupt())
56
return 0;
57
58
preempt_disable();
59
60
enable_kernel_altivec();
61
62
return 1;
63
}
64
65
/*
66
* All calls to this function will be optimised into tail calls. We are
67
* passed a pointer to the destination which we return as required by a
68
* memcpy implementation.
69
*/
70
void *exit_vmx_ops(void *dest)
71
{
72
disable_kernel_altivec();
73
preempt_enable();
74
return dest;
75
}
76
77