Skip to content

Commit 9fb71c2

Browse files
committed
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Thomas Gleixner: "A set of fixes and updates for x86: - Address a swiotlb regression which was caused by the recent DMA rework and made driver fail because dma_direct_supported() returned false - Fix a signedness bug in the APIC ID validation which caused invalid APIC IDs to be detected as valid thereby bloating the CPU possible space. - Fix inconsisten config dependcy/select magic for the MFD_CS5535 driver. - Fix a corruption of the physical address space bits when encryption has reduced the address space and late cpuinfo updates overwrite the reduced bit information with the original value. - Dominiks syscall rework which consolidates the architecture specific syscall functions so all syscalls can be wrapped with the same macros. This allows to switch x86/64 to struct pt_regs based syscalls. Extend the clearing of user space controlled registers in the entry patch to the lower registers" * 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/apic: Fix signedness bug in APIC ID validity checks x86/cpu: Prevent cpuinfo_x86::x86_phys_bits adjustment corruption x86/olpc: Fix inconsistent MFD_CS5535 configuration swiotlb: Use dma_direct_supported() for swiotlb_ops syscalls/x86: Adapt syscall_wrapper.h to the new syscall stub naming convention syscalls/core, syscalls/x86: Rename struct pt_regs-based sys_*() to __x64_sys_*() syscalls/core, syscalls/x86: Clean up compat syscall stub naming convention syscalls/core, syscalls/x86: Clean up syscall stub naming convention syscalls/x86: Extend register clearing on syscall entry to lower registers syscalls/x86: Unconditionally enable 'struct pt_regs' based syscalls on x86_64 syscalls/x86: Use 'struct pt_regs' based syscall calling for IA32_EMULATION and x32 syscalls/core: Prepare CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y for compat syscalls syscalls/x86: Use 'struct pt_regs' based syscall calling convention for 64-bit syscalls syscalls/core: Introduce CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y x86/syscalls: Don't pointlessly reload the system call number x86/mm: Fix documentation of module mapping range with 4-level paging x86/cpuid: Switch to 'static const' specifier
2 parents 6b0a02e + ef389b7 commit 9fb71c2

33 files changed

+1150
-802
lines changed

Documentation/process/adding-syscalls.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ First, the entry in ``arch/x86/entry/syscalls/syscall_32.tbl`` gets an extra
360360
column to indicate that a 32-bit userspace program running on a 64-bit kernel
361361
should hit the compat entry point::
362362

363-
380 i386 xyzzy sys_xyzzy compat_sys_xyzzy
363+
380 i386 xyzzy sys_xyzzy __ia32_compat_sys_xyzzy
364364

365365
Second, you need to figure out what should happen for the x32 ABI version of
366366
the new system call. There's a choice here: the layout of the arguments
@@ -373,7 +373,7 @@ the compatibility wrapper::
373373

374374
333 64 xyzzy sys_xyzzy
375375
...
376-
555 x32 xyzzy compat_sys_xyzzy
376+
555 x32 xyzzy __x32_compat_sys_xyzzy
377377

378378
If no pointers are involved, then it is preferable to re-use the 64-bit system
379379
call for the x32 ABI (and consequently the entry in

Documentation/x86/x86_64/mm.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks
2020
ffffffef00000000 - fffffffeffffffff (=64 GB) EFI region mapping space
2121
... unused hole ...
2222
ffffffff80000000 - ffffffff9fffffff (=512 MB) kernel text mapping, from phys 0
23-
ffffffffa0000000 - [fixmap start] (~1526 MB) module mapping space (variable)
23+
ffffffffa0000000 - fffffffffeffffff (1520 MB) module mapping space
2424
[fixmap start] - ffffffffff5fffff kernel-internal fixmap range
2525
ffffffffff600000 - ffffffffff600fff (=4 kB) legacy vsyscall ABI
2626
ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole

arch/x86/Kconfig

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ config X86_64
2929
select HAVE_ARCH_SOFT_DIRTY
3030
select MODULES_USE_ELF_RELA
3131
select X86_DEV_DMA_OPS
32+
select ARCH_HAS_SYSCALL_WRAPPER
3233

3334
#
3435
# Arch settings
@@ -2763,11 +2764,9 @@ config OLPC_XO1_RTC
27632764

27642765
config OLPC_XO1_SCI
27652766
bool "OLPC XO-1 SCI extras"
2766-
depends on OLPC && OLPC_XO1_PM
2767+
depends on OLPC && OLPC_XO1_PM && GPIO_CS5535=y
27672768
depends on INPUT=y
27682769
select POWER_SUPPLY
2769-
select GPIO_CS5535
2770-
select MFD_CORE
27712770
---help---
27722771
Add support for SCI-based features of the OLPC XO-1 laptop:
27732772
- EC-driven system wakeups

arch/x86/entry/calling.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,9 @@ For 32-bit we have the following conventions - kernel is built with
114114
pushq %rsi /* pt_regs->si */
115115
.endif
116116
pushq \rdx /* pt_regs->dx */
117+
xorl %edx, %edx /* nospec dx */
117118
pushq %rcx /* pt_regs->cx */
119+
xorl %ecx, %ecx /* nospec cx */
118120
pushq \rax /* pt_regs->ax */
119121
pushq %r8 /* pt_regs->r8 */
120122
xorl %r8d, %r8d /* nospec r8 */

arch/x86/entry/common.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -266,14 +266,13 @@ __visible inline void syscall_return_slowpath(struct pt_regs *regs)
266266
}
267267

268268
#ifdef CONFIG_X86_64
269-
__visible void do_syscall_64(struct pt_regs *regs)
269+
__visible void do_syscall_64(unsigned long nr, struct pt_regs *regs)
270270
{
271-
struct thread_info *ti = current_thread_info();
272-
unsigned long nr = regs->orig_ax;
271+
struct thread_info *ti;
273272

274273
enter_from_user_mode();
275274
local_irq_enable();
276-
275+
ti = current_thread_info();
277276
if (READ_ONCE(ti->flags) & _TIF_WORK_SYSCALL_ENTRY)
278277
nr = syscall_trace_enter(regs);
279278

@@ -282,11 +281,10 @@ __visible void do_syscall_64(struct pt_regs *regs)
282281
* table. The only functional difference is the x32 bit in
283282
* regs->orig_ax, which changes the behavior of some syscalls.
284283
*/
285-
if (likely((nr & __SYSCALL_MASK) < NR_syscalls)) {
286-
nr = array_index_nospec(nr & __SYSCALL_MASK, NR_syscalls);
287-
regs->ax = sys_call_table[nr](
288-
regs->di, regs->si, regs->dx,
289-
regs->r10, regs->r8, regs->r9);
284+
nr &= __SYSCALL_MASK;
285+
if (likely(nr < NR_syscalls)) {
286+
nr = array_index_nospec(nr, NR_syscalls);
287+
regs->ax = sys_call_table[nr](regs);
290288
}
291289

292290
syscall_return_slowpath(regs);
@@ -321,6 +319,9 @@ static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs)
321319

322320
if (likely(nr < IA32_NR_syscalls)) {
323321
nr = array_index_nospec(nr, IA32_NR_syscalls);
322+
#ifdef CONFIG_IA32_EMULATION
323+
regs->ax = ia32_sys_call_table[nr](regs);
324+
#else
324325
/*
325326
* It's possible that a 32-bit syscall implementation
326327
* takes a 64-bit parameter but nonetheless assumes that
@@ -331,6 +332,7 @@ static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs)
331332
(unsigned int)regs->bx, (unsigned int)regs->cx,
332333
(unsigned int)regs->dx, (unsigned int)regs->si,
333334
(unsigned int)regs->di, (unsigned int)regs->bp);
335+
#endif /* CONFIG_IA32_EMULATION */
334336
}
335337

336338
syscall_return_slowpath(regs);

arch/x86/entry/entry_64.S

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,8 @@ GLOBAL(entry_SYSCALL_64_after_hwframe)
233233
TRACE_IRQS_OFF
234234

235235
/* IRQs are off. */
236-
movq %rsp, %rdi
236+
movq %rax, %rdi
237+
movq %rsp, %rsi
237238
call do_syscall_64 /* returns with IRQs disabled */
238239

239240
TRACE_IRQS_IRETQ /* we're about to change IF */

arch/x86/entry/entry_64_compat.S

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,11 @@ GLOBAL(entry_SYSCALL_compat_after_hwframe)
220220
pushq %rax /* pt_regs->orig_ax */
221221
pushq %rdi /* pt_regs->di */
222222
pushq %rsi /* pt_regs->si */
223+
xorl %esi, %esi /* nospec si */
223224
pushq %rdx /* pt_regs->dx */
225+
xorl %edx, %edx /* nospec dx */
224226
pushq %rbp /* pt_regs->cx (stashed in bp) */
227+
xorl %ecx, %ecx /* nospec cx */
225228
pushq $-ENOSYS /* pt_regs->ax */
226229
pushq $0 /* pt_regs->r8 = 0 */
227230
xorl %r8d, %r8d /* nospec r8 */
@@ -365,8 +368,11 @@ ENTRY(entry_INT80_compat)
365368

366369
pushq (%rdi) /* pt_regs->di */
367370
pushq %rsi /* pt_regs->si */
371+
xorl %esi, %esi /* nospec si */
368372
pushq %rdx /* pt_regs->dx */
373+
xorl %edx, %edx /* nospec dx */
369374
pushq %rcx /* pt_regs->cx */
375+
xorl %ecx, %ecx /* nospec cx */
370376
pushq $-ENOSYS /* pt_regs->ax */
371377
pushq $0 /* pt_regs->r8 = 0 */
372378
xorl %r8d, %r8d /* nospec r8 */

arch/x86/entry/syscall_32.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,23 @@
77
#include <asm/asm-offsets.h>
88
#include <asm/syscall.h>
99

10-
#define __SYSCALL_I386(nr, sym, qual) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ;
10+
#ifdef CONFIG_IA32_EMULATION
11+
/* On X86_64, we use struct pt_regs * to pass parameters to syscalls */
12+
#define __SYSCALL_I386(nr, sym, qual) extern asmlinkage long sym(const struct pt_regs *);
13+
14+
/* this is a lie, but it does not hurt as sys_ni_syscall just returns -EINVAL */
15+
extern asmlinkage long sys_ni_syscall(const struct pt_regs *);
16+
17+
#else /* CONFIG_IA32_EMULATION */
18+
#define __SYSCALL_I386(nr, sym, qual) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
19+
extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
20+
#endif /* CONFIG_IA32_EMULATION */
21+
1122
#include <asm/syscalls_32.h>
1223
#undef __SYSCALL_I386
1324

1425
#define __SYSCALL_I386(nr, sym, qual) [nr] = sym,
1526

16-
extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
17-
1827
__visible const sys_call_ptr_t ia32_sys_call_table[__NR_syscall_compat_max+1] = {
1928
/*
2029
* Smells like a compiler bug -- it doesn't work

arch/x86/entry/syscall_64.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
#include <asm/asm-offsets.h>
88
#include <asm/syscall.h>
99

10-
#define __SYSCALL_64(nr, sym, qual) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
10+
/* this is a lie, but it does not hurt as sys_ni_syscall just returns -EINVAL */
11+
extern asmlinkage long sys_ni_syscall(const struct pt_regs *);
12+
#define __SYSCALL_64(nr, sym, qual) extern asmlinkage long sym(const struct pt_regs *);
1113
#include <asm/syscalls_64.h>
1214
#undef __SYSCALL_64
1315

1416
#define __SYSCALL_64(nr, sym, qual) [nr] = sym,
1517

16-
extern long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
17-
1818
asmlinkage const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = {
1919
/*
2020
* Smells like a compiler bug -- it doesn't work

0 commit comments

Comments
 (0)