diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-11 18:58:16 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-11 18:58:16 -0500 |
commit | 88cbfd07119e394b9cbb1a4a764056c4b37e8378 (patch) | |
tree | 87f1aa9bb8de1bf88305a4cc0751f4996c40150f | |
parent | 4f19b8803bddbecbd8c3ac44a2cfadd9d2b85b8f (diff) | |
parent | 8705d603edd49f1cff165cd3b7998f4c7f098d27 (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
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" |
335 | 2: movl $0, PT_FS(%esp) | 336 | 2: 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) |
554 | END(native_iret) | 555 | END(native_iret) |
555 | |||
556 | ENTRY(native_irq_enable_sysexit) | ||
557 | sti | ||
558 | sysexit | ||
559 | END(native_irq_enable_sysexit) | ||
560 | #endif | 556 | #endif |
561 | 557 | ||
562 | ENTRY(overflow) | 558 | ENTRY(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 | ||
527 | 1: | 525 | 1: |
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 | ||
22 | ENTRY(native_usergs_sysret32) | ||
23 | swapgs | ||
24 | sysretl | ||
25 | ENDPROC(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 |
114 | sysenter_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 | ||
129 | sysenter_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 |
133 | ENDPROC(entry_SYSENTER_compat) | 126 | ENDPROC(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 | ||
242 | END(entry_SYSCALL_compat) | 236 | END(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 |
42 | extern 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 | ||
46 | notrace static long vdso_fallback_gettime(long clock, struct timespec *ts) | 48 | notrace 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 | |||
65 | static 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 | |||
79 | static 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 |
101 | static notrace const struct pvclock_vsyscall_time_info *get_pvti0(void) | ||
102 | { | ||
103 | return (const struct pvclock_vsyscall_time_info *)&pvclock_page; | ||
104 | } | ||
166 | 105 | ||
167 | static notrace cycle_t vread_pvclock(int *mode) | 106 | static 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 | ||
176 | notrace static cycle_t vread_tsc(void) | 171 | notrace 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 { | |||
80 | const int special_pages[] = { | 81 | const 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 | ||
85 | struct vdso_sym { | 87 | struct 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 | |||
172 | up_fail: | 186 | up_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 | |||
19 | static __always_inline bool arch_static_branch(struct static_key *key, bool branch) | 33 | static __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 | ||
8 | extern struct pvclock_vsyscall_time_info *pvclock_pvti_cpu0_va(void); | ||
9 | #else | ||
10 | static 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 */ |
8 | cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src); | 17 | cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src); |
9 | u8 pvclock_read_flags(struct pvclock_vcpu_time_info *src); | 18 | u8 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 | |||
96 | int __init pvclock_init_vsyscall(struct pvclock_vsyscall_time_info *i, | ||
97 | int size); | ||
98 | struct 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); | |||
45 | static struct pvclock_vsyscall_time_info *hv_clock; | 45 | static struct pvclock_vsyscall_time_info *hv_clock; |
46 | static struct pvclock_wall_clock wall_clock; | 46 | static struct pvclock_wall_clock wall_clock; |
47 | 47 | ||
48 | struct 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 */ |
222 | extern void native_iret(void); | 218 | extern void native_iret(void); |
223 | extern void native_irq_enable_sysexit(void); | ||
224 | extern void native_usergs_sysret32(void); | ||
225 | extern void native_usergs_sysret64(void); | 219 | extern void native_usergs_sysret64(void); |
226 | 220 | ||
227 | static struct resource reserve_ioports = { | 221 | static 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"); | |||
5 | DEF_NATIVE(pv_irq_ops, restore_fl, "push %eax; popf"); | 5 | DEF_NATIVE(pv_irq_ops, restore_fl, "push %eax; popf"); |
6 | DEF_NATIVE(pv_irq_ops, save_fl, "pushf; pop %eax"); | 6 | DEF_NATIVE(pv_irq_ops, save_fl, "pushf; pop %eax"); |
7 | DEF_NATIVE(pv_cpu_ops, iret, "iret"); | 7 | DEF_NATIVE(pv_cpu_ops, iret, "iret"); |
8 | DEF_NATIVE(pv_cpu_ops, irq_enable_sysexit, "sti; sysexit"); | ||
9 | DEF_NATIVE(pv_mmu_ops, read_cr2, "mov %cr2, %eax"); | 8 | DEF_NATIVE(pv_mmu_ops, read_cr2, "mov %cr2, %eax"); |
10 | DEF_NATIVE(pv_mmu_ops, write_cr3, "mov %eax, %cr3"); | 9 | DEF_NATIVE(pv_mmu_ops, write_cr3, "mov %eax, %cr3"); |
11 | DEF_NATIVE(pv_mmu_ops, read_cr3, "mov %cr3, %eax"); | 10 | DEF_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)"); | |||
13 | DEF_NATIVE(pv_cpu_ops, clts, "clts"); | 13 | DEF_NATIVE(pv_cpu_ops, clts, "clts"); |
14 | DEF_NATIVE(pv_cpu_ops, wbinvd, "wbinvd"); | 14 | DEF_NATIVE(pv_cpu_ops, wbinvd, "wbinvd"); |
15 | 15 | ||
16 | DEF_NATIVE(pv_cpu_ops, irq_enable_sysexit, "swapgs; sti; sysexit"); | ||
17 | DEF_NATIVE(pv_cpu_ops, usergs_sysret64, "swapgs; sysretq"); | 16 | DEF_NATIVE(pv_cpu_ops, usergs_sysret64, "swapgs; sysretq"); |
18 | DEF_NATIVE(pv_cpu_ops, usergs_sysret32, "swapgs; sysretl"); | ||
19 | DEF_NATIVE(pv_cpu_ops, swapgs, "swapgs"); | 17 | DEF_NATIVE(pv_cpu_ops, swapgs, "swapgs"); |
20 | 18 | ||
21 | DEF_NATIVE(, mov32, "mov %edi, %eax"); | 19 | DEF_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 | |||
151 | int __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 | */ | ||
43 | ENTRY(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 | ||
49 | ENDPROC(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) | |||
68 | ENDPATCH(xen_sysret64) | 68 | ENDPATCH(xen_sysret64) |
69 | RELOC(xen_sysret64, 1b+1) | 69 | RELOC(xen_sysret64, 1b+1) |
70 | 70 | ||
71 | ENTRY(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 | ||
86 | 1: jmp hypercall_iret | ||
87 | ENDPATCH(xen_sysret32) | ||
88 | RELOC(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 |
25 | extern struct static_key context_tracking_enabled; | 25 | extern struct static_key_false context_tracking_enabled; |
26 | DECLARE_PER_CPU(struct context_tracking, context_tracking); | 26 | DECLARE_PER_CPU(struct context_tracking, context_tracking); |
27 | 27 | ||
28 | static inline bool context_tracking_is_enabled(void) | 28 | static 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 | ||
33 | static inline bool context_tracking_cpu_is_enabled(void) | 33 | static 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 | ||
27 | struct static_key context_tracking_enabled = STATIC_KEY_INIT_FALSE; | 27 | DEFINE_STATIC_KEY_FALSE(context_tracking_enabled); |
28 | EXPORT_SYMBOL_GPL(context_tracking_enabled); | 28 | EXPORT_SYMBOL_GPL(context_tracking_enabled); |
29 | 29 | ||
30 | DEFINE_PER_CPU(struct context_tracking, context_tracking); | 30 | DEFINE_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) |