aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-01-11 18:58:16 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-01-11 18:58:16 -0500
commit88cbfd07119e394b9cbb1a4a764056c4b37e8378 (patch)
tree87f1aa9bb8de1bf88305a4cc0751f4996c40150f
parent4f19b8803bddbecbd8c3ac44a2cfadd9d2b85b8f (diff)
parent8705d603edd49f1cff165cd3b7998f4c7f098d27 (diff)
Merge branch 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 asm updates from Ingo Molnar: "The main changes in this cycle were: - vDSO and asm entry improvements (Andy Lutomirski) - Xen paravirt entry enhancements (Boris Ostrovsky) - asm entry labels enhancement (Borislav Petkov) - and other misc changes (Thomas Gleixner, me)" * 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/vsdo: Fix build on PARAVIRT_CLOCK=y, KVM_GUEST=n Revert "x86/kvm: On KVM re-enable (e.g. after suspend), update clocks" x86/entry/64_compat: Make labels local x86/platform/uv: Include clocksource.h for clocksource_touch_watchdog() x86/vdso: Enable vdso pvclock access on all vdso variants x86/vdso: Remove pvclock fixmap machinery x86/vdso: Get pvclock data from the vvar VMA instead of the fixmap x86, vdso, pvclock: Simplify and speed up the vdso pvclock reader x86/kvm: On KVM re-enable (e.g. after suspend), update clocks x86/entry/64: Bypass enter_from_user_mode on non-context-tracking boots x86/asm: Add asm macros for static keys/jump labels x86/asm: Error out if asm/jump_label.h is included inappropriately context_tracking: Switch to new static_branch API x86/entry, x86/paravirt: Remove the unused usergs_sysret32 PV op x86/paravirt: Remove the unused irq_enable_sysexit pv op x86/xen: Avoid fast syscall path for Xen PV guests
-rw-r--r--arch/x86/entry/calling.h15
-rw-r--r--arch/x86/entry/entry_32.S8
-rw-r--r--arch/x86/entry/entry_64.S8
-rw-r--r--arch/x86/entry/entry_64_compat.S20
-rw-r--r--arch/x86/entry/vdso/vclock_gettime.c151
-rw-r--r--arch/x86/entry/vdso/vdso-layout.lds.S3
-rw-r--r--arch/x86/entry/vdso/vdso2c.c3
-rw-r--r--arch/x86/entry/vdso/vma.c14
-rw-r--r--arch/x86/include/asm/fixmap.h5
-rw-r--r--arch/x86/include/asm/jump_label.h63
-rw-r--r--arch/x86/include/asm/paravirt.h12
-rw-r--r--arch/x86/include/asm/paravirt_types.h17
-rw-r--r--arch/x86/include/asm/pvclock.h14
-rw-r--r--arch/x86/include/asm/vdso.h1
-rw-r--r--arch/x86/kernel/asm-offsets.c3
-rw-r--r--arch/x86/kernel/asm-offsets_64.c1
-rw-r--r--arch/x86/kernel/kvmclock.c11
-rw-r--r--arch/x86/kernel/paravirt.c12
-rw-r--r--arch/x86/kernel/paravirt_patch_32.c2
-rw-r--r--arch/x86/kernel/paravirt_patch_64.c3
-rw-r--r--arch/x86/kernel/pvclock.c24
-rw-r--r--arch/x86/platform/uv/uv_nmi.c1
-rw-r--r--arch/x86/xen/enlighten.c3
-rw-r--r--arch/x86/xen/xen-asm_32.S14
-rw-r--r--arch/x86/xen/xen-asm_64.S19
-rw-r--r--arch/x86/xen/xen-ops.h3
-rw-r--r--include/linux/context_tracking_state.h4
-rw-r--r--kernel/context_tracking.c4
28 files changed, 194 insertions, 244 deletions
diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h
index 3c71dd947c7b..e32206e09868 100644
--- a/arch/x86/entry/calling.h
+++ b/arch/x86/entry/calling.h
@@ -1,3 +1,5 @@
1#include <linux/jump_label.h>
2
1/* 3/*
2 4
3 x86 function call convention, 64-bit: 5 x86 function call convention, 64-bit:
@@ -232,3 +234,16 @@ For 32-bit we have the following conventions - kernel is built with
232 234
233#endif /* CONFIG_X86_64 */ 235#endif /* CONFIG_X86_64 */
234 236
237/*
238 * This does 'call enter_from_user_mode' unless we can avoid it based on
239 * kernel config or using the static jump infrastructure.
240 */
241.macro CALL_enter_from_user_mode
242#ifdef CONFIG_CONTEXT_TRACKING
243#ifdef HAVE_JUMP_LABEL
244 STATIC_JUMP_IF_FALSE .Lafter_call_\@, context_tracking_enabled, def=0
245#endif
246 call enter_from_user_mode
247.Lafter_call_\@:
248#endif
249.endm
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
index f3b6d54e0042..77d8c5112900 100644
--- a/arch/x86/entry/entry_32.S
+++ b/arch/x86/entry/entry_32.S
@@ -329,7 +329,8 @@ sysenter_past_esp:
329 * Return back to the vDSO, which will pop ecx and edx. 329 * Return back to the vDSO, which will pop ecx and edx.
330 * Don't bother with DS and ES (they already contain __USER_DS). 330 * Don't bother with DS and ES (they already contain __USER_DS).
331 */ 331 */
332 ENABLE_INTERRUPTS_SYSEXIT 332 sti
333 sysexit
333 334
334.pushsection .fixup, "ax" 335.pushsection .fixup, "ax"
3352: movl $0, PT_FS(%esp) 3362: movl $0, PT_FS(%esp)
@@ -552,11 +553,6 @@ ENTRY(native_iret)
552 iret 553 iret
553 _ASM_EXTABLE(native_iret, iret_exc) 554 _ASM_EXTABLE(native_iret, iret_exc)
554END(native_iret) 555END(native_iret)
555
556ENTRY(native_irq_enable_sysexit)
557 sti
558 sysexit
559END(native_irq_enable_sysexit)
560#endif 556#endif
561 557
562ENTRY(overflow) 558ENTRY(overflow)
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index a55697d19824..9d34d3cfceb6 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -520,9 +520,7 @@ END(irq_entries_start)
520 */ 520 */
521 TRACE_IRQS_OFF 521 TRACE_IRQS_OFF
522 522
523#ifdef CONFIG_CONTEXT_TRACKING 523 CALL_enter_from_user_mode
524 call enter_from_user_mode
525#endif
526 524
5271: 5251:
528 /* 526 /*
@@ -1066,9 +1064,7 @@ ENTRY(error_entry)
1066 * (which can take locks). 1064 * (which can take locks).
1067 */ 1065 */
1068 TRACE_IRQS_OFF 1066 TRACE_IRQS_OFF
1069#ifdef CONFIG_CONTEXT_TRACKING 1067 CALL_enter_from_user_mode
1070 call enter_from_user_mode
1071#endif
1072 ret 1068 ret
1073 1069
1074.Lerror_entry_done: 1070.Lerror_entry_done:
diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S
index 6a1ae3751e82..ff1c6d61f332 100644
--- a/arch/x86/entry/entry_64_compat.S
+++ b/arch/x86/entry/entry_64_compat.S
@@ -18,13 +18,6 @@
18 18
19 .section .entry.text, "ax" 19 .section .entry.text, "ax"
20 20
21#ifdef CONFIG_PARAVIRT
22ENTRY(native_usergs_sysret32)
23 swapgs
24 sysretl
25ENDPROC(native_usergs_sysret32)
26#endif
27
28/* 21/*
29 * 32-bit SYSENTER instruction entry. 22 * 32-bit SYSENTER instruction entry.
30 * 23 *
@@ -103,15 +96,15 @@ ENTRY(entry_SYSENTER_compat)
103 * This needs to happen before enabling interrupts so that 96 * This needs to happen before enabling interrupts so that
104 * we don't get preempted with NT set. 97 * we don't get preempted with NT set.
105 * 98 *
106 * NB.: sysenter_fix_flags is a label with the code under it moved 99 * NB.: .Lsysenter_fix_flags is a label with the code under it moved
107 * out-of-line as an optimization: NT is unlikely to be set in the 100 * out-of-line as an optimization: NT is unlikely to be set in the
108 * majority of the cases and instead of polluting the I$ unnecessarily, 101 * majority of the cases and instead of polluting the I$ unnecessarily,
109 * we're keeping that code behind a branch which will predict as 102 * we're keeping that code behind a branch which will predict as
110 * not-taken and therefore its instructions won't be fetched. 103 * not-taken and therefore its instructions won't be fetched.
111 */ 104 */
112 testl $X86_EFLAGS_NT, EFLAGS(%rsp) 105 testl $X86_EFLAGS_NT, EFLAGS(%rsp)
113 jnz sysenter_fix_flags 106 jnz .Lsysenter_fix_flags
114sysenter_flags_fixed: 107.Lsysenter_flags_fixed:
115 108
116 /* 109 /*
117 * User mode is traced as though IRQs are on, and SYSENTER 110 * User mode is traced as though IRQs are on, and SYSENTER
@@ -126,10 +119,10 @@ sysenter_flags_fixed:
126 "jmp .Lsyscall_32_done", X86_FEATURE_XENPV 119 "jmp .Lsyscall_32_done", X86_FEATURE_XENPV
127 jmp sysret32_from_system_call 120 jmp sysret32_from_system_call
128 121
129sysenter_fix_flags: 122.Lsysenter_fix_flags:
130 pushq $X86_EFLAGS_FIXED 123 pushq $X86_EFLAGS_FIXED
131 popfq 124 popfq
132 jmp sysenter_flags_fixed 125 jmp .Lsysenter_flags_fixed
133ENDPROC(entry_SYSENTER_compat) 126ENDPROC(entry_SYSENTER_compat)
134 127
135/* 128/*
@@ -238,7 +231,8 @@ sysret32_from_system_call:
238 xorq %r9, %r9 231 xorq %r9, %r9
239 xorq %r10, %r10 232 xorq %r10, %r10
240 movq RSP-ORIG_RAX(%rsp), %rsp 233 movq RSP-ORIG_RAX(%rsp), %rsp
241 USERGS_SYSRET32 234 swapgs
235 sysretl
242END(entry_SYSCALL_compat) 236END(entry_SYSCALL_compat)
243 237
244/* 238/*
diff --git a/arch/x86/entry/vdso/vclock_gettime.c b/arch/x86/entry/vdso/vclock_gettime.c
index ca94fa649251..8602f06c759f 100644
--- a/arch/x86/entry/vdso/vclock_gettime.c
+++ b/arch/x86/entry/vdso/vclock_gettime.c
@@ -17,8 +17,10 @@
17#include <asm/vvar.h> 17#include <asm/vvar.h>
18#include <asm/unistd.h> 18#include <asm/unistd.h>
19#include <asm/msr.h> 19#include <asm/msr.h>
20#include <asm/pvclock.h>
20#include <linux/math64.h> 21#include <linux/math64.h>
21#include <linux/time.h> 22#include <linux/time.h>
23#include <linux/kernel.h>
22 24
23#define gtod (&VVAR(vsyscall_gtod_data)) 25#define gtod (&VVAR(vsyscall_gtod_data))
24 26
@@ -36,12 +38,12 @@ static notrace cycle_t vread_hpet(void)
36} 38}
37#endif 39#endif
38 40
39#ifndef BUILD_VDSO32 41#ifdef CONFIG_PARAVIRT_CLOCK
42extern u8 pvclock_page
43 __attribute__((visibility("hidden")));
44#endif
40 45
41#include <linux/kernel.h> 46#ifndef BUILD_VDSO32
42#include <asm/vsyscall.h>
43#include <asm/fixmap.h>
44#include <asm/pvclock.h>
45 47
46notrace static long vdso_fallback_gettime(long clock, struct timespec *ts) 48notrace static long vdso_fallback_gettime(long clock, struct timespec *ts)
47{ 49{
@@ -60,75 +62,6 @@ notrace static long vdso_fallback_gtod(struct timeval *tv, struct timezone *tz)
60 return ret; 62 return ret;
61} 63}
62 64
63#ifdef CONFIG_PARAVIRT_CLOCK
64
65static notrace const struct pvclock_vsyscall_time_info *get_pvti(int cpu)
66{
67 const struct pvclock_vsyscall_time_info *pvti_base;
68 int idx = cpu / (PAGE_SIZE/PVTI_SIZE);
69 int offset = cpu % (PAGE_SIZE/PVTI_SIZE);
70
71 BUG_ON(PVCLOCK_FIXMAP_BEGIN + idx > PVCLOCK_FIXMAP_END);
72
73 pvti_base = (struct pvclock_vsyscall_time_info *)
74 __fix_to_virt(PVCLOCK_FIXMAP_BEGIN+idx);
75
76 return &pvti_base[offset];
77}
78
79static notrace cycle_t vread_pvclock(int *mode)
80{
81 const struct pvclock_vsyscall_time_info *pvti;
82 cycle_t ret;
83 u64 last;
84 u32 version;
85 u8 flags;
86 unsigned cpu, cpu1;
87
88
89 /*
90 * Note: hypervisor must guarantee that:
91 * 1. cpu ID number maps 1:1 to per-CPU pvclock time info.
92 * 2. that per-CPU pvclock time info is updated if the
93 * underlying CPU changes.
94 * 3. that version is increased whenever underlying CPU
95 * changes.
96 *
97 */
98 do {
99 cpu = __getcpu() & VGETCPU_CPU_MASK;
100 /* TODO: We can put vcpu id into higher bits of pvti.version.
101 * This will save a couple of cycles by getting rid of
102 * __getcpu() calls (Gleb).
103 */
104
105 pvti = get_pvti(cpu);
106
107 version = __pvclock_read_cycles(&pvti->pvti, &ret, &flags);
108
109 /*
110 * Test we're still on the cpu as well as the version.
111 * We could have been migrated just after the first
112 * vgetcpu but before fetching the version, so we
113 * wouldn't notice a version change.
114 */
115 cpu1 = __getcpu() & VGETCPU_CPU_MASK;
116 } while (unlikely(cpu != cpu1 ||
117 (pvti->pvti.version & 1) ||
118 pvti->pvti.version != version));
119
120 if (unlikely(!(flags & PVCLOCK_TSC_STABLE_BIT)))
121 *mode = VCLOCK_NONE;
122
123 /* refer to tsc.c read_tsc() comment for rationale */
124 last = gtod->cycle_last;
125
126 if (likely(ret >= last))
127 return ret;
128
129 return last;
130}
131#endif
132 65
133#else 66#else
134 67
@@ -162,15 +95,77 @@ notrace static long vdso_fallback_gtod(struct timeval *tv, struct timezone *tz)
162 return ret; 95 return ret;
163} 96}
164 97
98#endif
99
165#ifdef CONFIG_PARAVIRT_CLOCK 100#ifdef CONFIG_PARAVIRT_CLOCK
101static notrace const struct pvclock_vsyscall_time_info *get_pvti0(void)
102{
103 return (const struct pvclock_vsyscall_time_info *)&pvclock_page;
104}
166 105
167static notrace cycle_t vread_pvclock(int *mode) 106static notrace cycle_t vread_pvclock(int *mode)
168{ 107{
169 *mode = VCLOCK_NONE; 108 const struct pvclock_vcpu_time_info *pvti = &get_pvti0()->pvti;
170 return 0; 109 cycle_t ret;
171} 110 u64 tsc, pvti_tsc;
172#endif 111 u64 last, delta, pvti_system_time;
112 u32 version, pvti_tsc_to_system_mul, pvti_tsc_shift;
113
114 /*
115 * Note: The kernel and hypervisor must guarantee that cpu ID
116 * number maps 1:1 to per-CPU pvclock time info.
117 *
118 * Because the hypervisor is entirely unaware of guest userspace
119 * preemption, it cannot guarantee that per-CPU pvclock time
120 * info is updated if the underlying CPU changes or that that
121 * version is increased whenever underlying CPU changes.
122 *
123 * On KVM, we are guaranteed that pvti updates for any vCPU are
124 * atomic as seen by *all* vCPUs. This is an even stronger
125 * guarantee than we get with a normal seqlock.
126 *
127 * On Xen, we don't appear to have that guarantee, but Xen still
128 * supplies a valid seqlock using the version field.
129
130 * We only do pvclock vdso timing at all if
131 * PVCLOCK_TSC_STABLE_BIT is set, and we interpret that bit to
132 * mean that all vCPUs have matching pvti and that the TSC is
133 * synced, so we can just look at vCPU 0's pvti.
134 */
173 135
136 if (unlikely(!(pvti->flags & PVCLOCK_TSC_STABLE_BIT))) {
137 *mode = VCLOCK_NONE;
138 return 0;
139 }
140
141 do {
142 version = pvti->version;
143
144 smp_rmb();
145
146 tsc = rdtsc_ordered();
147 pvti_tsc_to_system_mul = pvti->tsc_to_system_mul;
148 pvti_tsc_shift = pvti->tsc_shift;
149 pvti_system_time = pvti->system_time;
150 pvti_tsc = pvti->tsc_timestamp;
151
152 /* Make sure that the version double-check is last. */
153 smp_rmb();
154 } while (unlikely((version & 1) || version != pvti->version));
155
156 delta = tsc - pvti_tsc;
157 ret = pvti_system_time +
158 pvclock_scale_delta(delta, pvti_tsc_to_system_mul,
159 pvti_tsc_shift);
160
161 /* refer to vread_tsc() comment for rationale */
162 last = gtod->cycle_last;
163
164 if (likely(ret >= last))
165 return ret;
166
167 return last;
168}
174#endif 169#endif
175 170
176notrace static cycle_t vread_tsc(void) 171notrace static cycle_t vread_tsc(void)
diff --git a/arch/x86/entry/vdso/vdso-layout.lds.S b/arch/x86/entry/vdso/vdso-layout.lds.S
index de2c921025f5..4158acc17df0 100644
--- a/arch/x86/entry/vdso/vdso-layout.lds.S
+++ b/arch/x86/entry/vdso/vdso-layout.lds.S
@@ -25,7 +25,7 @@ SECTIONS
25 * segment. 25 * segment.
26 */ 26 */
27 27
28 vvar_start = . - 2 * PAGE_SIZE; 28 vvar_start = . - 3 * PAGE_SIZE;
29 vvar_page = vvar_start; 29 vvar_page = vvar_start;
30 30
31 /* Place all vvars at the offsets in asm/vvar.h. */ 31 /* Place all vvars at the offsets in asm/vvar.h. */
@@ -36,6 +36,7 @@ SECTIONS
36#undef EMIT_VVAR 36#undef EMIT_VVAR
37 37
38 hpet_page = vvar_start + PAGE_SIZE; 38 hpet_page = vvar_start + PAGE_SIZE;
39 pvclock_page = vvar_start + 2 * PAGE_SIZE;
39 40
40 . = SIZEOF_HEADERS; 41 . = SIZEOF_HEADERS;
41 42
diff --git a/arch/x86/entry/vdso/vdso2c.c b/arch/x86/entry/vdso/vdso2c.c
index 785d9922b106..491020b2826d 100644
--- a/arch/x86/entry/vdso/vdso2c.c
+++ b/arch/x86/entry/vdso/vdso2c.c
@@ -73,6 +73,7 @@ enum {
73 sym_vvar_start, 73 sym_vvar_start,
74 sym_vvar_page, 74 sym_vvar_page,
75 sym_hpet_page, 75 sym_hpet_page,
76 sym_pvclock_page,
76 sym_VDSO_FAKE_SECTION_TABLE_START, 77 sym_VDSO_FAKE_SECTION_TABLE_START,
77 sym_VDSO_FAKE_SECTION_TABLE_END, 78 sym_VDSO_FAKE_SECTION_TABLE_END,
78}; 79};
@@ -80,6 +81,7 @@ enum {
80const int special_pages[] = { 81const int special_pages[] = {
81 sym_vvar_page, 82 sym_vvar_page,
82 sym_hpet_page, 83 sym_hpet_page,
84 sym_pvclock_page,
83}; 85};
84 86
85struct vdso_sym { 87struct vdso_sym {
@@ -91,6 +93,7 @@ struct vdso_sym required_syms[] = {
91 [sym_vvar_start] = {"vvar_start", true}, 93 [sym_vvar_start] = {"vvar_start", true},
92 [sym_vvar_page] = {"vvar_page", true}, 94 [sym_vvar_page] = {"vvar_page", true},
93 [sym_hpet_page] = {"hpet_page", true}, 95 [sym_hpet_page] = {"hpet_page", true},
96 [sym_pvclock_page] = {"pvclock_page", true},
94 [sym_VDSO_FAKE_SECTION_TABLE_START] = { 97 [sym_VDSO_FAKE_SECTION_TABLE_START] = {
95 "VDSO_FAKE_SECTION_TABLE_START", false 98 "VDSO_FAKE_SECTION_TABLE_START", false
96 }, 99 },
diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
index 64df47148160..b8f69e264ac4 100644
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -12,6 +12,7 @@
12#include <linux/random.h> 12#include <linux/random.h>
13#include <linux/elf.h> 13#include <linux/elf.h>
14#include <linux/cpu.h> 14#include <linux/cpu.h>
15#include <asm/pvclock.h>
15#include <asm/vgtod.h> 16#include <asm/vgtod.h>
16#include <asm/proto.h> 17#include <asm/proto.h>
17#include <asm/vdso.h> 18#include <asm/vdso.h>
@@ -100,6 +101,7 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr)
100 .name = "[vvar]", 101 .name = "[vvar]",
101 .pages = no_pages, 102 .pages = no_pages,
102 }; 103 };
104 struct pvclock_vsyscall_time_info *pvti;
103 105
104 if (calculate_addr) { 106 if (calculate_addr) {
105 addr = vdso_addr(current->mm->start_stack, 107 addr = vdso_addr(current->mm->start_stack,
@@ -169,6 +171,18 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr)
169 } 171 }
170#endif 172#endif
171 173
174 pvti = pvclock_pvti_cpu0_va();
175 if (pvti && image->sym_pvclock_page) {
176 ret = remap_pfn_range(vma,
177 text_start + image->sym_pvclock_page,
178 __pa(pvti) >> PAGE_SHIFT,
179 PAGE_SIZE,
180 PAGE_READONLY);
181
182 if (ret)
183 goto up_fail;
184 }
185
172up_fail: 186up_fail:
173 if (ret) 187 if (ret)
174 current->mm->context.vdso = NULL; 188 current->mm->context.vdso = NULL;
diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h
index f80d70009ff8..6d7d0e52ed5a 100644
--- a/arch/x86/include/asm/fixmap.h
+++ b/arch/x86/include/asm/fixmap.h
@@ -19,7 +19,6 @@
19#include <asm/acpi.h> 19#include <asm/acpi.h>
20#include <asm/apicdef.h> 20#include <asm/apicdef.h>
21#include <asm/page.h> 21#include <asm/page.h>
22#include <asm/pvclock.h>
23#ifdef CONFIG_X86_32 22#ifdef CONFIG_X86_32
24#include <linux/threads.h> 23#include <linux/threads.h>
25#include <asm/kmap_types.h> 24#include <asm/kmap_types.h>
@@ -72,10 +71,6 @@ enum fixed_addresses {
72#ifdef CONFIG_X86_VSYSCALL_EMULATION 71#ifdef CONFIG_X86_VSYSCALL_EMULATION
73 VSYSCALL_PAGE = (FIXADDR_TOP - VSYSCALL_ADDR) >> PAGE_SHIFT, 72 VSYSCALL_PAGE = (FIXADDR_TOP - VSYSCALL_ADDR) >> PAGE_SHIFT,
74#endif 73#endif
75#ifdef CONFIG_PARAVIRT_CLOCK
76 PVCLOCK_FIXMAP_BEGIN,
77 PVCLOCK_FIXMAP_END = PVCLOCK_FIXMAP_BEGIN+PVCLOCK_VSYSCALL_NR_PAGES-1,
78#endif
79#endif 74#endif
80 FIX_DBGP_BASE, 75 FIX_DBGP_BASE,
81 FIX_EARLYCON_MEM_BASE, 76 FIX_EARLYCON_MEM_BASE,
diff --git a/arch/x86/include/asm/jump_label.h b/arch/x86/include/asm/jump_label.h
index 5daeca3d0f9e..adc54c12cbd1 100644
--- a/arch/x86/include/asm/jump_label.h
+++ b/arch/x86/include/asm/jump_label.h
@@ -1,12 +1,18 @@
1#ifndef _ASM_X86_JUMP_LABEL_H 1#ifndef _ASM_X86_JUMP_LABEL_H
2#define _ASM_X86_JUMP_LABEL_H 2#define _ASM_X86_JUMP_LABEL_H
3 3
4#ifndef __ASSEMBLY__ 4#ifndef HAVE_JUMP_LABEL
5 5/*
6#include <linux/stringify.h> 6 * For better or for worse, if jump labels (the gcc extension) are missing,
7#include <linux/types.h> 7 * then the entire static branch patching infrastructure is compiled out.
8#include <asm/nops.h> 8 * If that happens, the code in here will malfunction. Raise a compiler
9#include <asm/asm.h> 9 * error instead.
10 *
11 * In theory, jump labels and the static branch patching infrastructure
12 * could be decoupled to fix this.
13 */
14#error asm/jump_label.h included on a non-jump-label kernel
15#endif
10 16
11#define JUMP_LABEL_NOP_SIZE 5 17#define JUMP_LABEL_NOP_SIZE 5
12 18
@@ -16,6 +22,14 @@
16# define STATIC_KEY_INIT_NOP GENERIC_NOP5_ATOMIC 22# define STATIC_KEY_INIT_NOP GENERIC_NOP5_ATOMIC
17#endif 23#endif
18 24
25#include <asm/asm.h>
26#include <asm/nops.h>
27
28#ifndef __ASSEMBLY__
29
30#include <linux/stringify.h>
31#include <linux/types.h>
32
19static __always_inline bool arch_static_branch(struct static_key *key, bool branch) 33static __always_inline bool arch_static_branch(struct static_key *key, bool branch)
20{ 34{
21 asm_volatile_goto("1:" 35 asm_volatile_goto("1:"
@@ -59,5 +73,40 @@ struct jump_entry {
59 jump_label_t key; 73 jump_label_t key;
60}; 74};
61 75
62#endif /* __ASSEMBLY__ */ 76#else /* __ASSEMBLY__ */
77
78.macro STATIC_JUMP_IF_TRUE target, key, def
79.Lstatic_jump_\@:
80 .if \def
81 /* Equivalent to "jmp.d32 \target" */
82 .byte 0xe9
83 .long \target - .Lstatic_jump_after_\@
84.Lstatic_jump_after_\@:
85 .else
86 .byte STATIC_KEY_INIT_NOP
87 .endif
88 .pushsection __jump_table, "aw"
89 _ASM_ALIGN
90 _ASM_PTR .Lstatic_jump_\@, \target, \key
91 .popsection
92.endm
93
94.macro STATIC_JUMP_IF_FALSE target, key, def
95.Lstatic_jump_\@:
96 .if \def
97 .byte STATIC_KEY_INIT_NOP
98 .else
99 /* Equivalent to "jmp.d32 \target" */
100 .byte 0xe9
101 .long \target - .Lstatic_jump_after_\@
102.Lstatic_jump_after_\@:
103 .endif
104 .pushsection __jump_table, "aw"
105 _ASM_ALIGN
106 _ASM_PTR .Lstatic_jump_\@, \target, \key + 1
107 .popsection
108.endm
109
110#endif /* __ASSEMBLY__ */
111
63#endif 112#endif
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index c759b3cca663..8f28d8412a6d 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -928,23 +928,11 @@ extern void default_banner(void);
928 call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_enable); \ 928 call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_enable); \
929 PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);) 929 PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);)
930 930
931#define USERGS_SYSRET32 \
932 PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_usergs_sysret32), \
933 CLBR_NONE, \
934 jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_usergs_sysret32))
935
936#ifdef CONFIG_X86_32 931#ifdef CONFIG_X86_32
937#define GET_CR0_INTO_EAX \ 932#define GET_CR0_INTO_EAX \
938 push %ecx; push %edx; \ 933 push %ecx; push %edx; \
939 call PARA_INDIRECT(pv_cpu_ops+PV_CPU_read_cr0); \ 934 call PARA_INDIRECT(pv_cpu_ops+PV_CPU_read_cr0); \
940 pop %edx; pop %ecx 935 pop %edx; pop %ecx
941
942#define ENABLE_INTERRUPTS_SYSEXIT \
943 PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_sysexit), \
944 CLBR_NONE, \
945 jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_irq_enable_sysexit))
946
947
948#else /* !CONFIG_X86_32 */ 936#else /* !CONFIG_X86_32 */
949 937
950/* 938/*
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
index 3d44191185f8..4752ff8c0704 100644
--- a/arch/x86/include/asm/paravirt_types.h
+++ b/arch/x86/include/asm/paravirt_types.h
@@ -162,15 +162,6 @@ struct pv_cpu_ops {
162 162
163 u64 (*read_pmc)(int counter); 163 u64 (*read_pmc)(int counter);
164 164
165#ifdef CONFIG_X86_32
166 /*
167 * Atomically enable interrupts and return to userspace. This
168 * is only used in 32-bit kernels. 64-bit kernels use
169 * usergs_sysret32 instead.
170 */
171 void (*irq_enable_sysexit)(void);
172#endif
173
174 /* 165 /*
175 * Switch to usermode gs and return to 64-bit usermode using 166 * Switch to usermode gs and return to 64-bit usermode using
176 * sysret. Only used in 64-bit kernels to return to 64-bit 167 * sysret. Only used in 64-bit kernels to return to 64-bit
@@ -179,14 +170,6 @@ struct pv_cpu_ops {
179 */ 170 */
180 void (*usergs_sysret64)(void); 171 void (*usergs_sysret64)(void);
181 172
182 /*
183 * Switch to usermode gs and return to 32-bit usermode using
184 * sysret. Used to return to 32-on-64 compat processes.
185 * Other usermode register state, including %esp, must already
186 * be restored.
187 */
188 void (*usergs_sysret32)(void);
189
190 /* Normal iret. Jump to this with the standard iret stack 173 /* Normal iret. Jump to this with the standard iret stack
191 frame set up. */ 174 frame set up. */
192 void (*iret)(void); 175 void (*iret)(void);
diff --git a/arch/x86/include/asm/pvclock.h b/arch/x86/include/asm/pvclock.h
index 7a6bed5c08bc..fdcc04020636 100644
--- a/arch/x86/include/asm/pvclock.h
+++ b/arch/x86/include/asm/pvclock.h
@@ -4,6 +4,15 @@
4#include <linux/clocksource.h> 4#include <linux/clocksource.h>
5#include <asm/pvclock-abi.h> 5#include <asm/pvclock-abi.h>
6 6
7#ifdef CONFIG_KVM_GUEST
8extern struct pvclock_vsyscall_time_info *pvclock_pvti_cpu0_va(void);
9#else
10static inline struct pvclock_vsyscall_time_info *pvclock_pvti_cpu0_va(void)
11{
12 return NULL;
13}
14#endif
15
7/* some helper functions for xen and kvm pv clock sources */ 16/* some helper functions for xen and kvm pv clock sources */
8cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src); 17cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src);
9u8 pvclock_read_flags(struct pvclock_vcpu_time_info *src); 18u8 pvclock_read_flags(struct pvclock_vcpu_time_info *src);
@@ -91,10 +100,5 @@ struct pvclock_vsyscall_time_info {
91} __attribute__((__aligned__(SMP_CACHE_BYTES))); 100} __attribute__((__aligned__(SMP_CACHE_BYTES)));
92 101
93#define PVTI_SIZE sizeof(struct pvclock_vsyscall_time_info) 102#define PVTI_SIZE sizeof(struct pvclock_vsyscall_time_info)
94#define PVCLOCK_VSYSCALL_NR_PAGES (((NR_CPUS-1)/(PAGE_SIZE/PVTI_SIZE))+1)
95
96int __init pvclock_init_vsyscall(struct pvclock_vsyscall_time_info *i,
97 int size);
98struct pvclock_vcpu_time_info *pvclock_get_vsyscall_time_info(int cpu);
99 103
100#endif /* _ASM_X86_PVCLOCK_H */ 104#endif /* _ASM_X86_PVCLOCK_H */
diff --git a/arch/x86/include/asm/vdso.h b/arch/x86/include/asm/vdso.h
index 756de9190aec..deabaf9759b6 100644
--- a/arch/x86/include/asm/vdso.h
+++ b/arch/x86/include/asm/vdso.h
@@ -22,6 +22,7 @@ struct vdso_image {
22 22
23 long sym_vvar_page; 23 long sym_vvar_page;
24 long sym_hpet_page; 24 long sym_hpet_page;
25 long sym_pvclock_page;
25 long sym_VDSO32_NOTE_MASK; 26 long sym_VDSO32_NOTE_MASK;
26 long sym___kernel_sigreturn; 27 long sym___kernel_sigreturn;
27 long sym___kernel_rt_sigreturn; 28 long sym___kernel_rt_sigreturn;
diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c
index 439df975bc7a..84a7524b202c 100644
--- a/arch/x86/kernel/asm-offsets.c
+++ b/arch/x86/kernel/asm-offsets.c
@@ -65,9 +65,6 @@ void common(void) {
65 OFFSET(PV_IRQ_irq_disable, pv_irq_ops, irq_disable); 65 OFFSET(PV_IRQ_irq_disable, pv_irq_ops, irq_disable);
66 OFFSET(PV_IRQ_irq_enable, pv_irq_ops, irq_enable); 66 OFFSET(PV_IRQ_irq_enable, pv_irq_ops, irq_enable);
67 OFFSET(PV_CPU_iret, pv_cpu_ops, iret); 67 OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
68#ifdef CONFIG_X86_32
69 OFFSET(PV_CPU_irq_enable_sysexit, pv_cpu_ops, irq_enable_sysexit);
70#endif
71 OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0); 68 OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
72 OFFSET(PV_MMU_read_cr2, pv_mmu_ops, read_cr2); 69 OFFSET(PV_MMU_read_cr2, pv_mmu_ops, read_cr2);
73#endif 70#endif
diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c
index d8f42f902a0f..f2edafb5f24e 100644
--- a/arch/x86/kernel/asm-offsets_64.c
+++ b/arch/x86/kernel/asm-offsets_64.c
@@ -23,7 +23,6 @@ int main(void)
23{ 23{
24#ifdef CONFIG_PARAVIRT 24#ifdef CONFIG_PARAVIRT
25 OFFSET(PV_IRQ_adjust_exception_frame, pv_irq_ops, adjust_exception_frame); 25 OFFSET(PV_IRQ_adjust_exception_frame, pv_irq_ops, adjust_exception_frame);
26 OFFSET(PV_CPU_usergs_sysret32, pv_cpu_ops, usergs_sysret32);
27 OFFSET(PV_CPU_usergs_sysret64, pv_cpu_ops, usergs_sysret64); 26 OFFSET(PV_CPU_usergs_sysret64, pv_cpu_ops, usergs_sysret64);
28 OFFSET(PV_CPU_swapgs, pv_cpu_ops, swapgs); 27 OFFSET(PV_CPU_swapgs, pv_cpu_ops, swapgs);
29 BLANK(); 28 BLANK();
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
index 2bd81e302427..72cef58693c7 100644
--- a/arch/x86/kernel/kvmclock.c
+++ b/arch/x86/kernel/kvmclock.c
@@ -45,6 +45,11 @@ early_param("no-kvmclock", parse_no_kvmclock);
45static struct pvclock_vsyscall_time_info *hv_clock; 45static struct pvclock_vsyscall_time_info *hv_clock;
46static struct pvclock_wall_clock wall_clock; 46static struct pvclock_wall_clock wall_clock;
47 47
48struct pvclock_vsyscall_time_info *pvclock_pvti_cpu0_va(void)
49{
50 return hv_clock;
51}
52
48/* 53/*
49 * The wallclock is the time of day when we booted. Since then, some time may 54 * The wallclock is the time of day when we booted. Since then, some time may
50 * have elapsed since the hypervisor wrote the data. So we try to account for 55 * have elapsed since the hypervisor wrote the data. So we try to account for
@@ -305,7 +310,6 @@ int __init kvm_setup_vsyscall_timeinfo(void)
305{ 310{
306#ifdef CONFIG_X86_64 311#ifdef CONFIG_X86_64
307 int cpu; 312 int cpu;
308 int ret;
309 u8 flags; 313 u8 flags;
310 struct pvclock_vcpu_time_info *vcpu_time; 314 struct pvclock_vcpu_time_info *vcpu_time;
311 unsigned int size; 315 unsigned int size;
@@ -325,11 +329,6 @@ int __init kvm_setup_vsyscall_timeinfo(void)
325 return 1; 329 return 1;
326 } 330 }
327 331
328 if ((ret = pvclock_init_vsyscall(hv_clock, size))) {
329 put_cpu();
330 return ret;
331 }
332
333 put_cpu(); 332 put_cpu();
334 333
335 kvm_clock.archdata.vclock_mode = VCLOCK_PVCLOCK; 334 kvm_clock.archdata.vclock_mode = VCLOCK_PVCLOCK;
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index c2130aef3f9d..8c19b4d5e719 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -162,10 +162,6 @@ unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf,
162 ret = paravirt_patch_ident_64(insnbuf, len); 162 ret = paravirt_patch_ident_64(insnbuf, len);
163 163
164 else if (type == PARAVIRT_PATCH(pv_cpu_ops.iret) || 164 else if (type == PARAVIRT_PATCH(pv_cpu_ops.iret) ||
165#ifdef CONFIG_X86_32
166 type == PARAVIRT_PATCH(pv_cpu_ops.irq_enable_sysexit) ||
167#endif
168 type == PARAVIRT_PATCH(pv_cpu_ops.usergs_sysret32) ||
169 type == PARAVIRT_PATCH(pv_cpu_ops.usergs_sysret64)) 165 type == PARAVIRT_PATCH(pv_cpu_ops.usergs_sysret64))
170 /* If operation requires a jmp, then jmp */ 166 /* If operation requires a jmp, then jmp */
171 ret = paravirt_patch_jmp(insnbuf, opfunc, addr, len); 167 ret = paravirt_patch_jmp(insnbuf, opfunc, addr, len);
@@ -220,8 +216,6 @@ static u64 native_steal_clock(int cpu)
220 216
221/* These are in entry.S */ 217/* These are in entry.S */
222extern void native_iret(void); 218extern void native_iret(void);
223extern void native_irq_enable_sysexit(void);
224extern void native_usergs_sysret32(void);
225extern void native_usergs_sysret64(void); 219extern void native_usergs_sysret64(void);
226 220
227static struct resource reserve_ioports = { 221static struct resource reserve_ioports = {
@@ -379,13 +373,7 @@ __visible struct pv_cpu_ops pv_cpu_ops = {
379 373
380 .load_sp0 = native_load_sp0, 374 .load_sp0 = native_load_sp0,
381 375
382#if defined(CONFIG_X86_32)
383 .irq_enable_sysexit = native_irq_enable_sysexit,
384#endif
385#ifdef CONFIG_X86_64 376#ifdef CONFIG_X86_64
386#ifdef CONFIG_IA32_EMULATION
387 .usergs_sysret32 = native_usergs_sysret32,
388#endif
389 .usergs_sysret64 = native_usergs_sysret64, 377 .usergs_sysret64 = native_usergs_sysret64,
390#endif 378#endif
391 .iret = native_iret, 379 .iret = native_iret,
diff --git a/arch/x86/kernel/paravirt_patch_32.c b/arch/x86/kernel/paravirt_patch_32.c
index c89f50a76e97..158dc0650d5d 100644
--- a/arch/x86/kernel/paravirt_patch_32.c
+++ b/arch/x86/kernel/paravirt_patch_32.c
@@ -5,7 +5,6 @@ DEF_NATIVE(pv_irq_ops, irq_enable, "sti");
5DEF_NATIVE(pv_irq_ops, restore_fl, "push %eax; popf"); 5DEF_NATIVE(pv_irq_ops, restore_fl, "push %eax; popf");
6DEF_NATIVE(pv_irq_ops, save_fl, "pushf; pop %eax"); 6DEF_NATIVE(pv_irq_ops, save_fl, "pushf; pop %eax");
7DEF_NATIVE(pv_cpu_ops, iret, "iret"); 7DEF_NATIVE(pv_cpu_ops, iret, "iret");
8DEF_NATIVE(pv_cpu_ops, irq_enable_sysexit, "sti; sysexit");
9DEF_NATIVE(pv_mmu_ops, read_cr2, "mov %cr2, %eax"); 8DEF_NATIVE(pv_mmu_ops, read_cr2, "mov %cr2, %eax");
10DEF_NATIVE(pv_mmu_ops, write_cr3, "mov %eax, %cr3"); 9DEF_NATIVE(pv_mmu_ops, write_cr3, "mov %eax, %cr3");
11DEF_NATIVE(pv_mmu_ops, read_cr3, "mov %cr3, %eax"); 10DEF_NATIVE(pv_mmu_ops, read_cr3, "mov %cr3, %eax");
@@ -46,7 +45,6 @@ unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
46 PATCH_SITE(pv_irq_ops, restore_fl); 45 PATCH_SITE(pv_irq_ops, restore_fl);
47 PATCH_SITE(pv_irq_ops, save_fl); 46 PATCH_SITE(pv_irq_ops, save_fl);
48 PATCH_SITE(pv_cpu_ops, iret); 47 PATCH_SITE(pv_cpu_ops, iret);
49 PATCH_SITE(pv_cpu_ops, irq_enable_sysexit);
50 PATCH_SITE(pv_mmu_ops, read_cr2); 48 PATCH_SITE(pv_mmu_ops, read_cr2);
51 PATCH_SITE(pv_mmu_ops, read_cr3); 49 PATCH_SITE(pv_mmu_ops, read_cr3);
52 PATCH_SITE(pv_mmu_ops, write_cr3); 50 PATCH_SITE(pv_mmu_ops, write_cr3);
diff --git a/arch/x86/kernel/paravirt_patch_64.c b/arch/x86/kernel/paravirt_patch_64.c
index 8aa05583bc42..e70087a04cc8 100644
--- a/arch/x86/kernel/paravirt_patch_64.c
+++ b/arch/x86/kernel/paravirt_patch_64.c
@@ -13,9 +13,7 @@ DEF_NATIVE(pv_mmu_ops, flush_tlb_single, "invlpg (%rdi)");
13DEF_NATIVE(pv_cpu_ops, clts, "clts"); 13DEF_NATIVE(pv_cpu_ops, clts, "clts");
14DEF_NATIVE(pv_cpu_ops, wbinvd, "wbinvd"); 14DEF_NATIVE(pv_cpu_ops, wbinvd, "wbinvd");
15 15
16DEF_NATIVE(pv_cpu_ops, irq_enable_sysexit, "swapgs; sti; sysexit");
17DEF_NATIVE(pv_cpu_ops, usergs_sysret64, "swapgs; sysretq"); 16DEF_NATIVE(pv_cpu_ops, usergs_sysret64, "swapgs; sysretq");
18DEF_NATIVE(pv_cpu_ops, usergs_sysret32, "swapgs; sysretl");
19DEF_NATIVE(pv_cpu_ops, swapgs, "swapgs"); 17DEF_NATIVE(pv_cpu_ops, swapgs, "swapgs");
20 18
21DEF_NATIVE(, mov32, "mov %edi, %eax"); 19DEF_NATIVE(, mov32, "mov %edi, %eax");
@@ -55,7 +53,6 @@ unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
55 PATCH_SITE(pv_irq_ops, save_fl); 53 PATCH_SITE(pv_irq_ops, save_fl);
56 PATCH_SITE(pv_irq_ops, irq_enable); 54 PATCH_SITE(pv_irq_ops, irq_enable);
57 PATCH_SITE(pv_irq_ops, irq_disable); 55 PATCH_SITE(pv_irq_ops, irq_disable);
58 PATCH_SITE(pv_cpu_ops, usergs_sysret32);
59 PATCH_SITE(pv_cpu_ops, usergs_sysret64); 56 PATCH_SITE(pv_cpu_ops, usergs_sysret64);
60 PATCH_SITE(pv_cpu_ops, swapgs); 57 PATCH_SITE(pv_cpu_ops, swapgs);
61 PATCH_SITE(pv_mmu_ops, read_cr2); 58 PATCH_SITE(pv_mmu_ops, read_cr2);
diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c
index 2f355d229a58..99bfc025111d 100644
--- a/arch/x86/kernel/pvclock.c
+++ b/arch/x86/kernel/pvclock.c
@@ -140,27 +140,3 @@ void pvclock_read_wallclock(struct pvclock_wall_clock *wall_clock,
140 140
141 set_normalized_timespec(ts, now.tv_sec, now.tv_nsec); 141 set_normalized_timespec(ts, now.tv_sec, now.tv_nsec);
142} 142}
143
144#ifdef CONFIG_X86_64
145/*
146 * Initialize the generic pvclock vsyscall state. This will allocate
147 * a/some page(s) for the per-vcpu pvclock information, set up a
148 * fixmap mapping for the page(s)
149 */
150
151int __init pvclock_init_vsyscall(struct pvclock_vsyscall_time_info *i,
152 int size)
153{
154 int idx;
155
156 WARN_ON (size != PVCLOCK_VSYSCALL_NR_PAGES*PAGE_SIZE);
157
158 for (idx = 0; idx <= (PVCLOCK_FIXMAP_END-PVCLOCK_FIXMAP_BEGIN); idx++) {
159 __set_fixmap(PVCLOCK_FIXMAP_BEGIN + idx,
160 __pa(i) + (idx*PAGE_SIZE),
161 PAGE_KERNEL_VVAR);
162 }
163
164 return 0;
165}
166#endif
diff --git a/arch/x86/platform/uv/uv_nmi.c b/arch/x86/platform/uv/uv_nmi.c
index 327f21c3bde1..8dd80050d705 100644
--- a/arch/x86/platform/uv/uv_nmi.c
+++ b/arch/x86/platform/uv/uv_nmi.c
@@ -28,6 +28,7 @@
28#include <linux/nmi.h> 28#include <linux/nmi.h>
29#include <linux/sched.h> 29#include <linux/sched.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/clocksource.h>
31 32
32#include <asm/apic.h> 33#include <asm/apic.h>
33#include <asm/current.h> 34#include <asm/current.h>
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index b7de78bdc09c..dd37ccabcacc 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1229,10 +1229,7 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = {
1229 1229
1230 .iret = xen_iret, 1230 .iret = xen_iret,
1231#ifdef CONFIG_X86_64 1231#ifdef CONFIG_X86_64
1232 .usergs_sysret32 = xen_sysret32,
1233 .usergs_sysret64 = xen_sysret64, 1232 .usergs_sysret64 = xen_sysret64,
1234#else
1235 .irq_enable_sysexit = xen_sysexit,
1236#endif 1233#endif
1237 1234
1238 .load_tr_desc = paravirt_nop, 1235 .load_tr_desc = paravirt_nop,
diff --git a/arch/x86/xen/xen-asm_32.S b/arch/x86/xen/xen-asm_32.S
index fd92a64d748e..feb6d40a0860 100644
--- a/arch/x86/xen/xen-asm_32.S
+++ b/arch/x86/xen/xen-asm_32.S
@@ -35,20 +35,6 @@ check_events:
35 ret 35 ret
36 36
37/* 37/*
38 * We can't use sysexit directly, because we're not running in ring0.
39 * But we can easily fake it up using iret. Assuming xen_sysexit is
40 * jumped to with a standard stack frame, we can just strip it back to
41 * a standard iret frame and use iret.
42 */
43ENTRY(xen_sysexit)
44 movl PT_EAX(%esp), %eax /* Shouldn't be necessary? */
45 orl $X86_EFLAGS_IF, PT_EFLAGS(%esp)
46 lea PT_EIP(%esp), %esp
47
48 jmp xen_iret
49ENDPROC(xen_sysexit)
50
51/*
52 * This is run where a normal iret would be run, with the same stack setup: 38 * This is run where a normal iret would be run, with the same stack setup:
53 * 8: eflags 39 * 8: eflags
54 * 4: cs 40 * 4: cs
diff --git a/arch/x86/xen/xen-asm_64.S b/arch/x86/xen/xen-asm_64.S
index f22667abf7b9..cc8acc410ddb 100644
--- a/arch/x86/xen/xen-asm_64.S
+++ b/arch/x86/xen/xen-asm_64.S
@@ -68,25 +68,6 @@ ENTRY(xen_sysret64)
68ENDPATCH(xen_sysret64) 68ENDPATCH(xen_sysret64)
69RELOC(xen_sysret64, 1b+1) 69RELOC(xen_sysret64, 1b+1)
70 70
71ENTRY(xen_sysret32)
72 /*
73 * We're already on the usermode stack at this point, but
74 * still with the kernel gs, so we can easily switch back
75 */
76 movq %rsp, PER_CPU_VAR(rsp_scratch)
77 movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
78
79 pushq $__USER32_DS
80 pushq PER_CPU_VAR(rsp_scratch)
81 pushq %r11
82 pushq $__USER32_CS
83 pushq %rcx
84
85 pushq $0
861: jmp hypercall_iret
87ENDPATCH(xen_sysret32)
88RELOC(xen_sysret32, 1b+1)
89
90/* 71/*
91 * Xen handles syscall callbacks much like ordinary exceptions, which 72 * Xen handles syscall callbacks much like ordinary exceptions, which
92 * means we have: 73 * means we have:
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
index 1399423f3418..4140b070f2e9 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -139,9 +139,6 @@ DECL_ASM(void, xen_restore_fl_direct, unsigned long);
139 139
140/* These are not functions, and cannot be called normally */ 140/* These are not functions, and cannot be called normally */
141__visible void xen_iret(void); 141__visible void xen_iret(void);
142#ifdef CONFIG_X86_32
143__visible void xen_sysexit(void);
144#endif
145__visible void xen_sysret32(void); 142__visible void xen_sysret32(void);
146__visible void xen_sysret64(void); 143__visible void xen_sysret64(void);
147__visible void xen_adjust_exception_frame(void); 144__visible void xen_adjust_exception_frame(void);
diff --git a/include/linux/context_tracking_state.h b/include/linux/context_tracking_state.h
index ee956c528fab..1d34fe68f48a 100644
--- a/include/linux/context_tracking_state.h
+++ b/include/linux/context_tracking_state.h
@@ -22,12 +22,12 @@ struct context_tracking {
22}; 22};
23 23
24#ifdef CONFIG_CONTEXT_TRACKING 24#ifdef CONFIG_CONTEXT_TRACKING
25extern struct static_key context_tracking_enabled; 25extern struct static_key_false context_tracking_enabled;
26DECLARE_PER_CPU(struct context_tracking, context_tracking); 26DECLARE_PER_CPU(struct context_tracking, context_tracking);
27 27
28static inline bool context_tracking_is_enabled(void) 28static inline bool context_tracking_is_enabled(void)
29{ 29{
30 return static_key_false(&context_tracking_enabled); 30 return static_branch_unlikely(&context_tracking_enabled);
31} 31}
32 32
33static inline bool context_tracking_cpu_is_enabled(void) 33static inline bool context_tracking_cpu_is_enabled(void)
diff --git a/kernel/context_tracking.c b/kernel/context_tracking.c
index d8560ee3bab7..9ad37b9e44a7 100644
--- a/kernel/context_tracking.c
+++ b/kernel/context_tracking.c
@@ -24,7 +24,7 @@
24#define CREATE_TRACE_POINTS 24#define CREATE_TRACE_POINTS
25#include <trace/events/context_tracking.h> 25#include <trace/events/context_tracking.h>
26 26
27struct static_key context_tracking_enabled = STATIC_KEY_INIT_FALSE; 27DEFINE_STATIC_KEY_FALSE(context_tracking_enabled);
28EXPORT_SYMBOL_GPL(context_tracking_enabled); 28EXPORT_SYMBOL_GPL(context_tracking_enabled);
29 29
30DEFINE_PER_CPU(struct context_tracking, context_tracking); 30DEFINE_PER_CPU(struct context_tracking, context_tracking);
@@ -191,7 +191,7 @@ void __init context_tracking_cpu_set(int cpu)
191 191
192 if (!per_cpu(context_tracking.active, cpu)) { 192 if (!per_cpu(context_tracking.active, cpu)) {
193 per_cpu(context_tracking.active, cpu) = true; 193 per_cpu(context_tracking.active, cpu) = true;
194 static_key_slow_inc(&context_tracking_enabled); 194 static_branch_inc(&context_tracking_enabled);
195 } 195 }
196 196
197 if (initialized) 197 if (initialized)