aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/entry
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2016-08-18 12:41:12 -0400
committerIngo Molnar <mingo@kernel.org>2016-08-18 12:41:12 -0400
commitf594d0b9b34aeb8e3ffa524eaa8a4085afb56d22 (patch)
tree7ef81ad042bcfe78dc0f41e05cebfdbc268871c4 /arch/x86/entry
parentb3830e8d478cd9fe33e820425ce431c8ef280967 (diff)
parent7b0501b1e7cddd32b265178e32d332bdfbb532d4 (diff)
Merge branch 'x86/urgent' into x86/asm, to pick up fixes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86/entry')
-rw-r--r--arch/x86/entry/Makefile2
-rw-r--r--arch/x86/entry/common.c6
-rw-r--r--arch/x86/entry/entry_64.S25
-rw-r--r--arch/x86/entry/syscalls/syscall_32.tbl2
-rw-r--r--arch/x86/entry/vdso/Makefile3
-rw-r--r--arch/x86/entry/vdso/vclock_gettime.c25
-rw-r--r--arch/x86/entry/vdso/vdso2c.h6
7 files changed, 41 insertions, 28 deletions
diff --git a/arch/x86/entry/Makefile b/arch/x86/entry/Makefile
index fe91c25092da..77f28ce9c646 100644
--- a/arch/x86/entry/Makefile
+++ b/arch/x86/entry/Makefile
@@ -5,6 +5,8 @@
5OBJECT_FILES_NON_STANDARD_entry_$(BITS).o := y 5OBJECT_FILES_NON_STANDARD_entry_$(BITS).o := y
6OBJECT_FILES_NON_STANDARD_entry_64_compat.o := y 6OBJECT_FILES_NON_STANDARD_entry_64_compat.o := y
7 7
8CFLAGS_syscall_64.o += -Wno-override-init
9CFLAGS_syscall_32.o += -Wno-override-init
8obj-y := entry_$(BITS).o thunk_$(BITS).o syscall_$(BITS).o 10obj-y := entry_$(BITS).o thunk_$(BITS).o syscall_$(BITS).o
9obj-y += common.o 11obj-y += common.o
10 12
diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c
index a1e71d431fed..1433f6b4607d 100644
--- a/arch/x86/entry/common.c
+++ b/arch/x86/entry/common.c
@@ -204,8 +204,12 @@ __visible inline void prepare_exit_to_usermode(struct pt_regs *regs)
204 * handling, because syscall restart has a fixup for compat 204 * handling, because syscall restart has a fixup for compat
205 * syscalls. The fixup is exercised by the ptrace_syscall_32 205 * syscalls. The fixup is exercised by the ptrace_syscall_32
206 * selftest. 206 * selftest.
207 *
208 * We also need to clear TS_REGS_POKED_I386: the 32-bit tracer
209 * special case only applies after poking regs and before the
210 * very next return to user mode.
207 */ 211 */
208 ti->status &= ~TS_COMPAT; 212 ti->status &= ~(TS_COMPAT|TS_I386_REGS_POKED);
209#endif 213#endif
210 214
211 user_enter_irqoff(); 215 user_enter_irqoff();
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 8956eae04c25..f6b40e5c88f1 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -288,11 +288,15 @@ return_from_SYSCALL_64:
288 jne opportunistic_sysret_failed 288 jne opportunistic_sysret_failed
289 289
290 /* 290 /*
291 * SYSRET can't restore RF. SYSRET can restore TF, but unlike IRET, 291 * SYSCALL clears RF when it saves RFLAGS in R11 and SYSRET cannot
292 * restoring TF results in a trap from userspace immediately after 292 * restore RF properly. If the slowpath sets it for whatever reason, we
293 * SYSRET. This would cause an infinite loop whenever #DB happens 293 * need to restore it correctly.
294 * with register state that satisfies the opportunistic SYSRET 294 *
295 * conditions. For example, single-stepping this user code: 295 * SYSRET can restore TF, but unlike IRET, restoring TF results in a
296 * trap from userspace immediately after SYSRET. This would cause an
297 * infinite loop whenever #DB happens with register state that satisfies
298 * the opportunistic SYSRET conditions. For example, single-stepping
299 * this user code:
296 * 300 *
297 * movq $stuck_here, %rcx 301 * movq $stuck_here, %rcx
298 * pushfq 302 * pushfq
@@ -600,9 +604,20 @@ apicinterrupt3 \num trace(\sym) smp_trace(\sym)
600.endm 604.endm
601#endif 605#endif
602 606
607/* Make sure APIC interrupt handlers end up in the irqentry section: */
608#if defined(CONFIG_FUNCTION_GRAPH_TRACER) || defined(CONFIG_KASAN)
609# define PUSH_SECTION_IRQENTRY .pushsection .irqentry.text, "ax"
610# define POP_SECTION_IRQENTRY .popsection
611#else
612# define PUSH_SECTION_IRQENTRY
613# define POP_SECTION_IRQENTRY
614#endif
615
603.macro apicinterrupt num sym do_sym 616.macro apicinterrupt num sym do_sym
617PUSH_SECTION_IRQENTRY
604apicinterrupt3 \num \sym \do_sym 618apicinterrupt3 \num \sym \do_sym
605trace_apicinterrupt \num \sym 619trace_apicinterrupt \num \sym
620POP_SECTION_IRQENTRY
606.endm 621.endm
607 622
608#ifdef CONFIG_SMP 623#ifdef CONFIG_SMP
diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl
index 4cddd17153fb..f848572169ea 100644
--- a/arch/x86/entry/syscalls/syscall_32.tbl
+++ b/arch/x86/entry/syscalls/syscall_32.tbl
@@ -294,7 +294,7 @@
294# 285 sys_setaltroot 294# 285 sys_setaltroot
295286 i386 add_key sys_add_key 295286 i386 add_key sys_add_key
296287 i386 request_key sys_request_key 296287 i386 request_key sys_request_key
297288 i386 keyctl sys_keyctl 297288 i386 keyctl sys_keyctl compat_sys_keyctl
298289 i386 ioprio_set sys_ioprio_set 298289 i386 ioprio_set sys_ioprio_set
299290 i386 ioprio_get sys_ioprio_get 299290 i386 ioprio_get sys_ioprio_get
300291 i386 inotify_init sys_inotify_init 300291 i386 inotify_init sys_inotify_init
diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile
index 6ba89a1ab0e5..d5409660f5de 100644
--- a/arch/x86/entry/vdso/Makefile
+++ b/arch/x86/entry/vdso/Makefile
@@ -75,7 +75,7 @@ CFL := $(PROFILING) -mcmodel=small -fPIC -O2 -fasynchronous-unwind-tables -m64 \
75 -fno-omit-frame-pointer -foptimize-sibling-calls \ 75 -fno-omit-frame-pointer -foptimize-sibling-calls \
76 -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO 76 -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO
77 77
78$(vobjs): KBUILD_CFLAGS += $(CFL) 78$(vobjs): KBUILD_CFLAGS := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS)) $(CFL)
79 79
80# 80#
81# vDSO code runs in userspace and -pg doesn't help with profiling anyway. 81# vDSO code runs in userspace and -pg doesn't help with profiling anyway.
@@ -145,6 +145,7 @@ KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS))
145KBUILD_CFLAGS_32 := $(filter-out -mcmodel=kernel,$(KBUILD_CFLAGS_32)) 145KBUILD_CFLAGS_32 := $(filter-out -mcmodel=kernel,$(KBUILD_CFLAGS_32))
146KBUILD_CFLAGS_32 := $(filter-out -fno-pic,$(KBUILD_CFLAGS_32)) 146KBUILD_CFLAGS_32 := $(filter-out -fno-pic,$(KBUILD_CFLAGS_32))
147KBUILD_CFLAGS_32 := $(filter-out -mfentry,$(KBUILD_CFLAGS_32)) 147KBUILD_CFLAGS_32 := $(filter-out -mfentry,$(KBUILD_CFLAGS_32))
148KBUILD_CFLAGS_32 := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS_32))
148KBUILD_CFLAGS_32 += -m32 -msoft-float -mregparm=0 -fpic 149KBUILD_CFLAGS_32 += -m32 -msoft-float -mregparm=0 -fpic
149KBUILD_CFLAGS_32 += $(call cc-option, -fno-stack-protector) 150KBUILD_CFLAGS_32 += $(call cc-option, -fno-stack-protector)
150KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls) 151KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls)
diff --git a/arch/x86/entry/vdso/vclock_gettime.c b/arch/x86/entry/vdso/vclock_gettime.c
index 2f02d23a05ef..94d54d0defa7 100644
--- a/arch/x86/entry/vdso/vclock_gettime.c
+++ b/arch/x86/entry/vdso/vclock_gettime.c
@@ -96,9 +96,8 @@ static notrace cycle_t vread_pvclock(int *mode)
96{ 96{
97 const struct pvclock_vcpu_time_info *pvti = &get_pvti0()->pvti; 97 const struct pvclock_vcpu_time_info *pvti = &get_pvti0()->pvti;
98 cycle_t ret; 98 cycle_t ret;
99 u64 tsc, pvti_tsc; 99 u64 last;
100 u64 last, delta, pvti_system_time; 100 u32 version;
101 u32 version, pvti_tsc_to_system_mul, pvti_tsc_shift;
102 101
103 /* 102 /*
104 * Note: The kernel and hypervisor must guarantee that cpu ID 103 * Note: The kernel and hypervisor must guarantee that cpu ID
@@ -123,29 +122,15 @@ static notrace cycle_t vread_pvclock(int *mode)
123 */ 122 */
124 123
125 do { 124 do {
126 version = pvti->version; 125 version = pvclock_read_begin(pvti);
127
128 smp_rmb();
129 126
130 if (unlikely(!(pvti->flags & PVCLOCK_TSC_STABLE_BIT))) { 127 if (unlikely(!(pvti->flags & PVCLOCK_TSC_STABLE_BIT))) {
131 *mode = VCLOCK_NONE; 128 *mode = VCLOCK_NONE;
132 return 0; 129 return 0;
133 } 130 }
134 131
135 tsc = rdtsc_ordered(); 132 ret = __pvclock_read_cycles(pvti);
136 pvti_tsc_to_system_mul = pvti->tsc_to_system_mul; 133 } while (pvclock_read_retry(pvti, version));
137 pvti_tsc_shift = pvti->tsc_shift;
138 pvti_system_time = pvti->system_time;
139 pvti_tsc = pvti->tsc_timestamp;
140
141 /* Make sure that the version double-check is last. */
142 smp_rmb();
143 } while (unlikely((version & 1) || version != pvti->version));
144
145 delta = tsc - pvti_tsc;
146 ret = pvti_system_time +
147 pvclock_scale_delta(delta, pvti_tsc_to_system_mul,
148 pvti_tsc_shift);
149 134
150 /* refer to vread_tsc() comment for rationale */ 135 /* refer to vread_tsc() comment for rationale */
151 last = gtod->cycle_last; 136 last = gtod->cycle_last;
diff --git a/arch/x86/entry/vdso/vdso2c.h b/arch/x86/entry/vdso/vdso2c.h
index 63a03bb91497..4f741192846d 100644
--- a/arch/x86/entry/vdso/vdso2c.h
+++ b/arch/x86/entry/vdso/vdso2c.h
@@ -22,6 +22,9 @@ static void BITSFUNC(go)(void *raw_addr, size_t raw_len,
22 22
23 ELF(Phdr) *pt = (ELF(Phdr) *)(raw_addr + GET_LE(&hdr->e_phoff)); 23 ELF(Phdr) *pt = (ELF(Phdr) *)(raw_addr + GET_LE(&hdr->e_phoff));
24 24
25 if (hdr->e_type != ET_DYN)
26 fail("input is not a shared object\n");
27
25 /* Walk the segment table. */ 28 /* Walk the segment table. */
26 for (i = 0; i < GET_LE(&hdr->e_phnum); i++) { 29 for (i = 0; i < GET_LE(&hdr->e_phnum); i++) {
27 if (GET_LE(&pt[i].p_type) == PT_LOAD) { 30 if (GET_LE(&pt[i].p_type) == PT_LOAD) {
@@ -49,6 +52,9 @@ static void BITSFUNC(go)(void *raw_addr, size_t raw_len,
49 if (stripped_len < load_size) 52 if (stripped_len < load_size)
50 fail("stripped input is too short\n"); 53 fail("stripped input is too short\n");
51 54
55 if (!dyn)
56 fail("input has no PT_DYNAMIC section -- your toolchain is buggy\n");
57
52 /* Walk the dynamic table */ 58 /* Walk the dynamic table */
53 for (i = 0; dyn + i < dyn_end && 59 for (i = 0; dyn + i < dyn_end &&
54 GET_LE(&dyn[i].d_tag) != DT_NULL; i++) { 60 GET_LE(&dyn[i].d_tag) != DT_NULL; i++) {