diff options
| author | Ingo Molnar <mingo@kernel.org> | 2016-08-18 12:41:12 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2016-08-18 12:41:12 -0400 |
| commit | f594d0b9b34aeb8e3ffa524eaa8a4085afb56d22 (patch) | |
| tree | 7ef81ad042bcfe78dc0f41e05cebfdbc268871c4 /arch/x86/entry | |
| parent | b3830e8d478cd9fe33e820425ce431c8ef280967 (diff) | |
| parent | 7b0501b1e7cddd32b265178e32d332bdfbb532d4 (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/Makefile | 2 | ||||
| -rw-r--r-- | arch/x86/entry/common.c | 6 | ||||
| -rw-r--r-- | arch/x86/entry/entry_64.S | 25 | ||||
| -rw-r--r-- | arch/x86/entry/syscalls/syscall_32.tbl | 2 | ||||
| -rw-r--r-- | arch/x86/entry/vdso/Makefile | 3 | ||||
| -rw-r--r-- | arch/x86/entry/vdso/vclock_gettime.c | 25 | ||||
| -rw-r--r-- | arch/x86/entry/vdso/vdso2c.h | 6 |
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 @@ | |||
| 5 | OBJECT_FILES_NON_STANDARD_entry_$(BITS).o := y | 5 | OBJECT_FILES_NON_STANDARD_entry_$(BITS).o := y |
| 6 | OBJECT_FILES_NON_STANDARD_entry_64_compat.o := y | 6 | OBJECT_FILES_NON_STANDARD_entry_64_compat.o := y |
| 7 | 7 | ||
| 8 | CFLAGS_syscall_64.o += -Wno-override-init | ||
| 9 | CFLAGS_syscall_32.o += -Wno-override-init | ||
| 8 | obj-y := entry_$(BITS).o thunk_$(BITS).o syscall_$(BITS).o | 10 | obj-y := entry_$(BITS).o thunk_$(BITS).o syscall_$(BITS).o |
| 9 | obj-y += common.o | 11 | obj-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 |
| 617 | PUSH_SECTION_IRQENTRY | ||
| 604 | apicinterrupt3 \num \sym \do_sym | 618 | apicinterrupt3 \num \sym \do_sym |
| 605 | trace_apicinterrupt \num \sym | 619 | trace_apicinterrupt \num \sym |
| 620 | POP_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 |
| 295 | 286 i386 add_key sys_add_key | 295 | 286 i386 add_key sys_add_key |
| 296 | 287 i386 request_key sys_request_key | 296 | 287 i386 request_key sys_request_key |
| 297 | 288 i386 keyctl sys_keyctl | 297 | 288 i386 keyctl sys_keyctl compat_sys_keyctl |
| 298 | 289 i386 ioprio_set sys_ioprio_set | 298 | 289 i386 ioprio_set sys_ioprio_set |
| 299 | 290 i386 ioprio_get sys_ioprio_get | 299 | 290 i386 ioprio_get sys_ioprio_get |
| 300 | 291 i386 inotify_init sys_inotify_init | 300 | 291 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)) | |||
| 145 | KBUILD_CFLAGS_32 := $(filter-out -mcmodel=kernel,$(KBUILD_CFLAGS_32)) | 145 | KBUILD_CFLAGS_32 := $(filter-out -mcmodel=kernel,$(KBUILD_CFLAGS_32)) |
| 146 | KBUILD_CFLAGS_32 := $(filter-out -fno-pic,$(KBUILD_CFLAGS_32)) | 146 | KBUILD_CFLAGS_32 := $(filter-out -fno-pic,$(KBUILD_CFLAGS_32)) |
| 147 | KBUILD_CFLAGS_32 := $(filter-out -mfentry,$(KBUILD_CFLAGS_32)) | 147 | KBUILD_CFLAGS_32 := $(filter-out -mfentry,$(KBUILD_CFLAGS_32)) |
| 148 | KBUILD_CFLAGS_32 := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS_32)) | ||
| 148 | KBUILD_CFLAGS_32 += -m32 -msoft-float -mregparm=0 -fpic | 149 | KBUILD_CFLAGS_32 += -m32 -msoft-float -mregparm=0 -fpic |
| 149 | KBUILD_CFLAGS_32 += $(call cc-option, -fno-stack-protector) | 150 | KBUILD_CFLAGS_32 += $(call cc-option, -fno-stack-protector) |
| 150 | KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls) | 151 | KBUILD_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++) { |
