diff options
author | Ingo Molnar <mingo@kernel.org> | 2016-02-25 03:00:38 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2016-02-25 03:00:38 -0500 |
commit | c0853867a10f9215132dccdb84c720a5f856f4d2 (patch) | |
tree | 92d3162ea2fc6fe0276dabc869e01293325f862c | |
parent | 6dc390ad61ac8dfca5fa9b0823981fb6f7ec17a0 (diff) | |
parent | 1923f3d02768bd904dfe5607f3f93c3008b8db61 (diff) |
Merge branch 'x86/debug' into core/objtool, to pick up frame pointer fixes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
129 files changed, 1841 insertions, 1172 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 9a53c929f017..0d27a9adabf8 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -666,7 +666,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
666 | 666 | ||
667 | clearcpuid=BITNUM [X86] | 667 | clearcpuid=BITNUM [X86] |
668 | Disable CPUID feature X for the kernel. See | 668 | Disable CPUID feature X for the kernel. See |
669 | arch/x86/include/asm/cpufeature.h for the valid bit | 669 | arch/x86/include/asm/cpufeatures.h for the valid bit |
670 | numbers. Note the Linux specific bits are not necessarily | 670 | numbers. Note the Linux specific bits are not necessarily |
671 | stable over kernel options, but the vendor specific | 671 | stable over kernel options, but the vendor specific |
672 | ones should be. | 672 | ones should be. |
diff --git a/Documentation/x86/x86_64/boot-options.txt b/Documentation/x86/x86_64/boot-options.txt index 68ed3114c363..0965a71f9942 100644 --- a/Documentation/x86/x86_64/boot-options.txt +++ b/Documentation/x86/x86_64/boot-options.txt | |||
@@ -60,6 +60,8 @@ Machine check | |||
60 | threshold to 1. Enabling this may make memory predictive failure | 60 | threshold to 1. Enabling this may make memory predictive failure |
61 | analysis less effective if the bios sets thresholds for memory | 61 | analysis less effective if the bios sets thresholds for memory |
62 | errors since we will not see details for all errors. | 62 | errors since we will not see details for all errors. |
63 | mce=recovery | ||
64 | Force-enable recoverable machine check code paths | ||
63 | 65 | ||
64 | nomce (for compatibility with i386): same as mce=off | 66 | nomce (for compatibility with i386): same as mce=off |
65 | 67 | ||
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 9b18ed97a8a2..68a2d1f0a683 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug | |||
@@ -350,16 +350,6 @@ config DEBUG_IMR_SELFTEST | |||
350 | 350 | ||
351 | If unsure say N here. | 351 | If unsure say N here. |
352 | 352 | ||
353 | config X86_DEBUG_STATIC_CPU_HAS | ||
354 | bool "Debug alternatives" | ||
355 | depends on DEBUG_KERNEL | ||
356 | ---help--- | ||
357 | This option causes additional code to be generated which | ||
358 | fails if static_cpu_has() is used before alternatives have | ||
359 | run. | ||
360 | |||
361 | If unsure, say N. | ||
362 | |||
363 | config X86_DEBUG_FPU | 353 | config X86_DEBUG_FPU |
364 | bool "Debug the x86 FPU code" | 354 | bool "Debug the x86 FPU code" |
365 | depends on DEBUG_KERNEL | 355 | depends on DEBUG_KERNEL |
diff --git a/arch/x86/boot/cpuflags.h b/arch/x86/boot/cpuflags.h index ea97697e51e4..4cb404fd45ce 100644 --- a/arch/x86/boot/cpuflags.h +++ b/arch/x86/boot/cpuflags.h | |||
@@ -1,7 +1,7 @@ | |||
1 | #ifndef BOOT_CPUFLAGS_H | 1 | #ifndef BOOT_CPUFLAGS_H |
2 | #define BOOT_CPUFLAGS_H | 2 | #define BOOT_CPUFLAGS_H |
3 | 3 | ||
4 | #include <asm/cpufeature.h> | 4 | #include <asm/cpufeatures.h> |
5 | #include <asm/processor-flags.h> | 5 | #include <asm/processor-flags.h> |
6 | 6 | ||
7 | struct cpu_features { | 7 | struct cpu_features { |
diff --git a/arch/x86/boot/mkcpustr.c b/arch/x86/boot/mkcpustr.c index 637097e66a62..f72498dc90d2 100644 --- a/arch/x86/boot/mkcpustr.c +++ b/arch/x86/boot/mkcpustr.c | |||
@@ -17,7 +17,7 @@ | |||
17 | 17 | ||
18 | #include "../include/asm/required-features.h" | 18 | #include "../include/asm/required-features.h" |
19 | #include "../include/asm/disabled-features.h" | 19 | #include "../include/asm/disabled-features.h" |
20 | #include "../include/asm/cpufeature.h" | 20 | #include "../include/asm/cpufeatures.h" |
21 | #include "../kernel/cpu/capflags.c" | 21 | #include "../kernel/cpu/capflags.c" |
22 | 22 | ||
23 | int main(void) | 23 | int main(void) |
diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S index 6bd2c6c95373..383a6f84a060 100644 --- a/arch/x86/crypto/aesni-intel_asm.S +++ b/arch/x86/crypto/aesni-intel_asm.S | |||
@@ -31,6 +31,7 @@ | |||
31 | 31 | ||
32 | #include <linux/linkage.h> | 32 | #include <linux/linkage.h> |
33 | #include <asm/inst.h> | 33 | #include <asm/inst.h> |
34 | #include <asm/frame.h> | ||
34 | 35 | ||
35 | /* | 36 | /* |
36 | * The following macros are used to move an (un)aligned 16 byte value to/from | 37 | * The following macros are used to move an (un)aligned 16 byte value to/from |
@@ -1800,11 +1801,12 @@ ENDPROC(_key_expansion_256b) | |||
1800 | * unsigned int key_len) | 1801 | * unsigned int key_len) |
1801 | */ | 1802 | */ |
1802 | ENTRY(aesni_set_key) | 1803 | ENTRY(aesni_set_key) |
1804 | FRAME_BEGIN | ||
1803 | #ifndef __x86_64__ | 1805 | #ifndef __x86_64__ |
1804 | pushl KEYP | 1806 | pushl KEYP |
1805 | movl 8(%esp), KEYP # ctx | 1807 | movl (FRAME_OFFSET+8)(%esp), KEYP # ctx |
1806 | movl 12(%esp), UKEYP # in_key | 1808 | movl (FRAME_OFFSET+12)(%esp), UKEYP # in_key |
1807 | movl 16(%esp), %edx # key_len | 1809 | movl (FRAME_OFFSET+16)(%esp), %edx # key_len |
1808 | #endif | 1810 | #endif |
1809 | movups (UKEYP), %xmm0 # user key (first 16 bytes) | 1811 | movups (UKEYP), %xmm0 # user key (first 16 bytes) |
1810 | movaps %xmm0, (KEYP) | 1812 | movaps %xmm0, (KEYP) |
@@ -1905,6 +1907,7 @@ ENTRY(aesni_set_key) | |||
1905 | #ifndef __x86_64__ | 1907 | #ifndef __x86_64__ |
1906 | popl KEYP | 1908 | popl KEYP |
1907 | #endif | 1909 | #endif |
1910 | FRAME_END | ||
1908 | ret | 1911 | ret |
1909 | ENDPROC(aesni_set_key) | 1912 | ENDPROC(aesni_set_key) |
1910 | 1913 | ||
@@ -1912,12 +1915,13 @@ ENDPROC(aesni_set_key) | |||
1912 | * void aesni_enc(struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src) | 1915 | * void aesni_enc(struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src) |
1913 | */ | 1916 | */ |
1914 | ENTRY(aesni_enc) | 1917 | ENTRY(aesni_enc) |
1918 | FRAME_BEGIN | ||
1915 | #ifndef __x86_64__ | 1919 | #ifndef __x86_64__ |
1916 | pushl KEYP | 1920 | pushl KEYP |
1917 | pushl KLEN | 1921 | pushl KLEN |
1918 | movl 12(%esp), KEYP | 1922 | movl (FRAME_OFFSET+12)(%esp), KEYP # ctx |
1919 | movl 16(%esp), OUTP | 1923 | movl (FRAME_OFFSET+16)(%esp), OUTP # dst |
1920 | movl 20(%esp), INP | 1924 | movl (FRAME_OFFSET+20)(%esp), INP # src |
1921 | #endif | 1925 | #endif |
1922 | movl 480(KEYP), KLEN # key length | 1926 | movl 480(KEYP), KLEN # key length |
1923 | movups (INP), STATE # input | 1927 | movups (INP), STATE # input |
@@ -1927,6 +1931,7 @@ ENTRY(aesni_enc) | |||
1927 | popl KLEN | 1931 | popl KLEN |
1928 | popl KEYP | 1932 | popl KEYP |
1929 | #endif | 1933 | #endif |
1934 | FRAME_END | ||
1930 | ret | 1935 | ret |
1931 | ENDPROC(aesni_enc) | 1936 | ENDPROC(aesni_enc) |
1932 | 1937 | ||
@@ -2101,12 +2106,13 @@ ENDPROC(_aesni_enc4) | |||
2101 | * void aesni_dec (struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src) | 2106 | * void aesni_dec (struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src) |
2102 | */ | 2107 | */ |
2103 | ENTRY(aesni_dec) | 2108 | ENTRY(aesni_dec) |
2109 | FRAME_BEGIN | ||
2104 | #ifndef __x86_64__ | 2110 | #ifndef __x86_64__ |
2105 | pushl KEYP | 2111 | pushl KEYP |
2106 | pushl KLEN | 2112 | pushl KLEN |
2107 | movl 12(%esp), KEYP | 2113 | movl (FRAME_OFFSET+12)(%esp), KEYP # ctx |
2108 | movl 16(%esp), OUTP | 2114 | movl (FRAME_OFFSET+16)(%esp), OUTP # dst |
2109 | movl 20(%esp), INP | 2115 | movl (FRAME_OFFSET+20)(%esp), INP # src |
2110 | #endif | 2116 | #endif |
2111 | mov 480(KEYP), KLEN # key length | 2117 | mov 480(KEYP), KLEN # key length |
2112 | add $240, KEYP | 2118 | add $240, KEYP |
@@ -2117,6 +2123,7 @@ ENTRY(aesni_dec) | |||
2117 | popl KLEN | 2123 | popl KLEN |
2118 | popl KEYP | 2124 | popl KEYP |
2119 | #endif | 2125 | #endif |
2126 | FRAME_END | ||
2120 | ret | 2127 | ret |
2121 | ENDPROC(aesni_dec) | 2128 | ENDPROC(aesni_dec) |
2122 | 2129 | ||
@@ -2292,14 +2299,15 @@ ENDPROC(_aesni_dec4) | |||
2292 | * size_t len) | 2299 | * size_t len) |
2293 | */ | 2300 | */ |
2294 | ENTRY(aesni_ecb_enc) | 2301 | ENTRY(aesni_ecb_enc) |
2302 | FRAME_BEGIN | ||
2295 | #ifndef __x86_64__ | 2303 | #ifndef __x86_64__ |
2296 | pushl LEN | 2304 | pushl LEN |
2297 | pushl KEYP | 2305 | pushl KEYP |
2298 | pushl KLEN | 2306 | pushl KLEN |
2299 | movl 16(%esp), KEYP | 2307 | movl (FRAME_OFFSET+16)(%esp), KEYP # ctx |
2300 | movl 20(%esp), OUTP | 2308 | movl (FRAME_OFFSET+20)(%esp), OUTP # dst |
2301 | movl 24(%esp), INP | 2309 | movl (FRAME_OFFSET+24)(%esp), INP # src |
2302 | movl 28(%esp), LEN | 2310 | movl (FRAME_OFFSET+28)(%esp), LEN # len |
2303 | #endif | 2311 | #endif |
2304 | test LEN, LEN # check length | 2312 | test LEN, LEN # check length |
2305 | jz .Lecb_enc_ret | 2313 | jz .Lecb_enc_ret |
@@ -2342,6 +2350,7 @@ ENTRY(aesni_ecb_enc) | |||
2342 | popl KEYP | 2350 | popl KEYP |
2343 | popl LEN | 2351 | popl LEN |
2344 | #endif | 2352 | #endif |
2353 | FRAME_END | ||
2345 | ret | 2354 | ret |
2346 | ENDPROC(aesni_ecb_enc) | 2355 | ENDPROC(aesni_ecb_enc) |
2347 | 2356 | ||
@@ -2350,14 +2359,15 @@ ENDPROC(aesni_ecb_enc) | |||
2350 | * size_t len); | 2359 | * size_t len); |
2351 | */ | 2360 | */ |
2352 | ENTRY(aesni_ecb_dec) | 2361 | ENTRY(aesni_ecb_dec) |
2362 | FRAME_BEGIN | ||
2353 | #ifndef __x86_64__ | 2363 | #ifndef __x86_64__ |
2354 | pushl LEN | 2364 | pushl LEN |
2355 | pushl KEYP | 2365 | pushl KEYP |
2356 | pushl KLEN | 2366 | pushl KLEN |
2357 | movl 16(%esp), KEYP | 2367 | movl (FRAME_OFFSET+16)(%esp), KEYP # ctx |
2358 | movl 20(%esp), OUTP | 2368 | movl (FRAME_OFFSET+20)(%esp), OUTP # dst |
2359 | movl 24(%esp), INP | 2369 | movl (FRAME_OFFSET+24)(%esp), INP # src |
2360 | movl 28(%esp), LEN | 2370 | movl (FRAME_OFFSET+28)(%esp), LEN # len |
2361 | #endif | 2371 | #endif |
2362 | test LEN, LEN | 2372 | test LEN, LEN |
2363 | jz .Lecb_dec_ret | 2373 | jz .Lecb_dec_ret |
@@ -2401,6 +2411,7 @@ ENTRY(aesni_ecb_dec) | |||
2401 | popl KEYP | 2411 | popl KEYP |
2402 | popl LEN | 2412 | popl LEN |
2403 | #endif | 2413 | #endif |
2414 | FRAME_END | ||
2404 | ret | 2415 | ret |
2405 | ENDPROC(aesni_ecb_dec) | 2416 | ENDPROC(aesni_ecb_dec) |
2406 | 2417 | ||
@@ -2409,16 +2420,17 @@ ENDPROC(aesni_ecb_dec) | |||
2409 | * size_t len, u8 *iv) | 2420 | * size_t len, u8 *iv) |
2410 | */ | 2421 | */ |
2411 | ENTRY(aesni_cbc_enc) | 2422 | ENTRY(aesni_cbc_enc) |
2423 | FRAME_BEGIN | ||
2412 | #ifndef __x86_64__ | 2424 | #ifndef __x86_64__ |
2413 | pushl IVP | 2425 | pushl IVP |
2414 | pushl LEN | 2426 | pushl LEN |
2415 | pushl KEYP | 2427 | pushl KEYP |
2416 | pushl KLEN | 2428 | pushl KLEN |
2417 | movl 20(%esp), KEYP | 2429 | movl (FRAME_OFFSET+20)(%esp), KEYP # ctx |
2418 | movl 24(%esp), OUTP | 2430 | movl (FRAME_OFFSET+24)(%esp), OUTP # dst |
2419 | movl 28(%esp), INP | 2431 | movl (FRAME_OFFSET+28)(%esp), INP # src |
2420 | movl 32(%esp), LEN | 2432 | movl (FRAME_OFFSET+32)(%esp), LEN # len |
2421 | movl 36(%esp), IVP | 2433 | movl (FRAME_OFFSET+36)(%esp), IVP # iv |
2422 | #endif | 2434 | #endif |
2423 | cmp $16, LEN | 2435 | cmp $16, LEN |
2424 | jb .Lcbc_enc_ret | 2436 | jb .Lcbc_enc_ret |
@@ -2443,6 +2455,7 @@ ENTRY(aesni_cbc_enc) | |||
2443 | popl LEN | 2455 | popl LEN |
2444 | popl IVP | 2456 | popl IVP |
2445 | #endif | 2457 | #endif |
2458 | FRAME_END | ||
2446 | ret | 2459 | ret |
2447 | ENDPROC(aesni_cbc_enc) | 2460 | ENDPROC(aesni_cbc_enc) |
2448 | 2461 | ||
@@ -2451,16 +2464,17 @@ ENDPROC(aesni_cbc_enc) | |||
2451 | * size_t len, u8 *iv) | 2464 | * size_t len, u8 *iv) |
2452 | */ | 2465 | */ |
2453 | ENTRY(aesni_cbc_dec) | 2466 | ENTRY(aesni_cbc_dec) |
2467 | FRAME_BEGIN | ||
2454 | #ifndef __x86_64__ | 2468 | #ifndef __x86_64__ |
2455 | pushl IVP | 2469 | pushl IVP |
2456 | pushl LEN | 2470 | pushl LEN |
2457 | pushl KEYP | 2471 | pushl KEYP |
2458 | pushl KLEN | 2472 | pushl KLEN |
2459 | movl 20(%esp), KEYP | 2473 | movl (FRAME_OFFSET+20)(%esp), KEYP # ctx |
2460 | movl 24(%esp), OUTP | 2474 | movl (FRAME_OFFSET+24)(%esp), OUTP # dst |
2461 | movl 28(%esp), INP | 2475 | movl (FRAME_OFFSET+28)(%esp), INP # src |
2462 | movl 32(%esp), LEN | 2476 | movl (FRAME_OFFSET+32)(%esp), LEN # len |
2463 | movl 36(%esp), IVP | 2477 | movl (FRAME_OFFSET+36)(%esp), IVP # iv |
2464 | #endif | 2478 | #endif |
2465 | cmp $16, LEN | 2479 | cmp $16, LEN |
2466 | jb .Lcbc_dec_just_ret | 2480 | jb .Lcbc_dec_just_ret |
@@ -2534,13 +2548,16 @@ ENTRY(aesni_cbc_dec) | |||
2534 | popl LEN | 2548 | popl LEN |
2535 | popl IVP | 2549 | popl IVP |
2536 | #endif | 2550 | #endif |
2551 | FRAME_END | ||
2537 | ret | 2552 | ret |
2538 | ENDPROC(aesni_cbc_dec) | 2553 | ENDPROC(aesni_cbc_dec) |
2539 | 2554 | ||
2540 | #ifdef __x86_64__ | 2555 | #ifdef __x86_64__ |
2556 | .pushsection .rodata | ||
2541 | .align 16 | 2557 | .align 16 |
2542 | .Lbswap_mask: | 2558 | .Lbswap_mask: |
2543 | .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 | 2559 | .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 |
2560 | .popsection | ||
2544 | 2561 | ||
2545 | /* | 2562 | /* |
2546 | * _aesni_inc_init: internal ABI | 2563 | * _aesni_inc_init: internal ABI |
@@ -2598,6 +2615,7 @@ ENDPROC(_aesni_inc) | |||
2598 | * size_t len, u8 *iv) | 2615 | * size_t len, u8 *iv) |
2599 | */ | 2616 | */ |
2600 | ENTRY(aesni_ctr_enc) | 2617 | ENTRY(aesni_ctr_enc) |
2618 | FRAME_BEGIN | ||
2601 | cmp $16, LEN | 2619 | cmp $16, LEN |
2602 | jb .Lctr_enc_just_ret | 2620 | jb .Lctr_enc_just_ret |
2603 | mov 480(KEYP), KLEN | 2621 | mov 480(KEYP), KLEN |
@@ -2651,6 +2669,7 @@ ENTRY(aesni_ctr_enc) | |||
2651 | .Lctr_enc_ret: | 2669 | .Lctr_enc_ret: |
2652 | movups IV, (IVP) | 2670 | movups IV, (IVP) |
2653 | .Lctr_enc_just_ret: | 2671 | .Lctr_enc_just_ret: |
2672 | FRAME_END | ||
2654 | ret | 2673 | ret |
2655 | ENDPROC(aesni_ctr_enc) | 2674 | ENDPROC(aesni_ctr_enc) |
2656 | 2675 | ||
@@ -2677,6 +2696,7 @@ ENDPROC(aesni_ctr_enc) | |||
2677 | * bool enc, u8 *iv) | 2696 | * bool enc, u8 *iv) |
2678 | */ | 2697 | */ |
2679 | ENTRY(aesni_xts_crypt8) | 2698 | ENTRY(aesni_xts_crypt8) |
2699 | FRAME_BEGIN | ||
2680 | cmpb $0, %cl | 2700 | cmpb $0, %cl |
2681 | movl $0, %ecx | 2701 | movl $0, %ecx |
2682 | movl $240, %r10d | 2702 | movl $240, %r10d |
@@ -2777,6 +2797,7 @@ ENTRY(aesni_xts_crypt8) | |||
2777 | pxor INC, STATE4 | 2797 | pxor INC, STATE4 |
2778 | movdqu STATE4, 0x70(OUTP) | 2798 | movdqu STATE4, 0x70(OUTP) |
2779 | 2799 | ||
2800 | FRAME_END | ||
2780 | ret | 2801 | ret |
2781 | ENDPROC(aesni_xts_crypt8) | 2802 | ENDPROC(aesni_xts_crypt8) |
2782 | 2803 | ||
diff --git a/arch/x86/crypto/camellia-aesni-avx-asm_64.S b/arch/x86/crypto/camellia-aesni-avx-asm_64.S index ce71f9212409..aa9e8bd163f6 100644 --- a/arch/x86/crypto/camellia-aesni-avx-asm_64.S +++ b/arch/x86/crypto/camellia-aesni-avx-asm_64.S | |||
@@ -16,6 +16,7 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/linkage.h> | 18 | #include <linux/linkage.h> |
19 | #include <asm/frame.h> | ||
19 | 20 | ||
20 | #define CAMELLIA_TABLE_BYTE_LEN 272 | 21 | #define CAMELLIA_TABLE_BYTE_LEN 272 |
21 | 22 | ||
@@ -726,6 +727,7 @@ __camellia_enc_blk16: | |||
726 | * %xmm0..%xmm15: 16 encrypted blocks, order swapped: | 727 | * %xmm0..%xmm15: 16 encrypted blocks, order swapped: |
727 | * 7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8 | 728 | * 7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8 |
728 | */ | 729 | */ |
730 | FRAME_BEGIN | ||
729 | 731 | ||
730 | leaq 8 * 16(%rax), %rcx; | 732 | leaq 8 * 16(%rax), %rcx; |
731 | 733 | ||
@@ -780,6 +782,7 @@ __camellia_enc_blk16: | |||
780 | %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, | 782 | %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, |
781 | %xmm15, (key_table)(CTX, %r8, 8), (%rax), 1 * 16(%rax)); | 783 | %xmm15, (key_table)(CTX, %r8, 8), (%rax), 1 * 16(%rax)); |
782 | 784 | ||
785 | FRAME_END | ||
783 | ret; | 786 | ret; |
784 | 787 | ||
785 | .align 8 | 788 | .align 8 |
@@ -812,6 +815,7 @@ __camellia_dec_blk16: | |||
812 | * %xmm0..%xmm15: 16 plaintext blocks, order swapped: | 815 | * %xmm0..%xmm15: 16 plaintext blocks, order swapped: |
813 | * 7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8 | 816 | * 7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8 |
814 | */ | 817 | */ |
818 | FRAME_BEGIN | ||
815 | 819 | ||
816 | leaq 8 * 16(%rax), %rcx; | 820 | leaq 8 * 16(%rax), %rcx; |
817 | 821 | ||
@@ -865,6 +869,7 @@ __camellia_dec_blk16: | |||
865 | %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, | 869 | %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, |
866 | %xmm15, (key_table)(CTX), (%rax), 1 * 16(%rax)); | 870 | %xmm15, (key_table)(CTX), (%rax), 1 * 16(%rax)); |
867 | 871 | ||
872 | FRAME_END | ||
868 | ret; | 873 | ret; |
869 | 874 | ||
870 | .align 8 | 875 | .align 8 |
@@ -890,6 +895,7 @@ ENTRY(camellia_ecb_enc_16way) | |||
890 | * %rsi: dst (16 blocks) | 895 | * %rsi: dst (16 blocks) |
891 | * %rdx: src (16 blocks) | 896 | * %rdx: src (16 blocks) |
892 | */ | 897 | */ |
898 | FRAME_BEGIN | ||
893 | 899 | ||
894 | inpack16_pre(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, | 900 | inpack16_pre(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, |
895 | %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, | 901 | %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, |
@@ -904,6 +910,7 @@ ENTRY(camellia_ecb_enc_16way) | |||
904 | %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9, | 910 | %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9, |
905 | %xmm8, %rsi); | 911 | %xmm8, %rsi); |
906 | 912 | ||
913 | FRAME_END | ||
907 | ret; | 914 | ret; |
908 | ENDPROC(camellia_ecb_enc_16way) | 915 | ENDPROC(camellia_ecb_enc_16way) |
909 | 916 | ||
@@ -913,6 +920,7 @@ ENTRY(camellia_ecb_dec_16way) | |||
913 | * %rsi: dst (16 blocks) | 920 | * %rsi: dst (16 blocks) |
914 | * %rdx: src (16 blocks) | 921 | * %rdx: src (16 blocks) |
915 | */ | 922 | */ |
923 | FRAME_BEGIN | ||
916 | 924 | ||
917 | cmpl $16, key_length(CTX); | 925 | cmpl $16, key_length(CTX); |
918 | movl $32, %r8d; | 926 | movl $32, %r8d; |
@@ -932,6 +940,7 @@ ENTRY(camellia_ecb_dec_16way) | |||
932 | %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9, | 940 | %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9, |
933 | %xmm8, %rsi); | 941 | %xmm8, %rsi); |
934 | 942 | ||
943 | FRAME_END | ||
935 | ret; | 944 | ret; |
936 | ENDPROC(camellia_ecb_dec_16way) | 945 | ENDPROC(camellia_ecb_dec_16way) |
937 | 946 | ||
@@ -941,6 +950,7 @@ ENTRY(camellia_cbc_dec_16way) | |||
941 | * %rsi: dst (16 blocks) | 950 | * %rsi: dst (16 blocks) |
942 | * %rdx: src (16 blocks) | 951 | * %rdx: src (16 blocks) |
943 | */ | 952 | */ |
953 | FRAME_BEGIN | ||
944 | 954 | ||
945 | cmpl $16, key_length(CTX); | 955 | cmpl $16, key_length(CTX); |
946 | movl $32, %r8d; | 956 | movl $32, %r8d; |
@@ -981,6 +991,7 @@ ENTRY(camellia_cbc_dec_16way) | |||
981 | %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9, | 991 | %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9, |
982 | %xmm8, %rsi); | 992 | %xmm8, %rsi); |
983 | 993 | ||
994 | FRAME_END | ||
984 | ret; | 995 | ret; |
985 | ENDPROC(camellia_cbc_dec_16way) | 996 | ENDPROC(camellia_cbc_dec_16way) |
986 | 997 | ||
@@ -997,6 +1008,7 @@ ENTRY(camellia_ctr_16way) | |||
997 | * %rdx: src (16 blocks) | 1008 | * %rdx: src (16 blocks) |
998 | * %rcx: iv (little endian, 128bit) | 1009 | * %rcx: iv (little endian, 128bit) |
999 | */ | 1010 | */ |
1011 | FRAME_BEGIN | ||
1000 | 1012 | ||
1001 | subq $(16 * 16), %rsp; | 1013 | subq $(16 * 16), %rsp; |
1002 | movq %rsp, %rax; | 1014 | movq %rsp, %rax; |
@@ -1092,6 +1104,7 @@ ENTRY(camellia_ctr_16way) | |||
1092 | %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9, | 1104 | %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9, |
1093 | %xmm8, %rsi); | 1105 | %xmm8, %rsi); |
1094 | 1106 | ||
1107 | FRAME_END | ||
1095 | ret; | 1108 | ret; |
1096 | ENDPROC(camellia_ctr_16way) | 1109 | ENDPROC(camellia_ctr_16way) |
1097 | 1110 | ||
@@ -1112,6 +1125,7 @@ camellia_xts_crypt_16way: | |||
1112 | * %r8: index for input whitening key | 1125 | * %r8: index for input whitening key |
1113 | * %r9: pointer to __camellia_enc_blk16 or __camellia_dec_blk16 | 1126 | * %r9: pointer to __camellia_enc_blk16 or __camellia_dec_blk16 |
1114 | */ | 1127 | */ |
1128 | FRAME_BEGIN | ||
1115 | 1129 | ||
1116 | subq $(16 * 16), %rsp; | 1130 | subq $(16 * 16), %rsp; |
1117 | movq %rsp, %rax; | 1131 | movq %rsp, %rax; |
@@ -1234,6 +1248,7 @@ camellia_xts_crypt_16way: | |||
1234 | %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9, | 1248 | %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9, |
1235 | %xmm8, %rsi); | 1249 | %xmm8, %rsi); |
1236 | 1250 | ||
1251 | FRAME_END | ||
1237 | ret; | 1252 | ret; |
1238 | ENDPROC(camellia_xts_crypt_16way) | 1253 | ENDPROC(camellia_xts_crypt_16way) |
1239 | 1254 | ||
diff --git a/arch/x86/crypto/camellia-aesni-avx2-asm_64.S b/arch/x86/crypto/camellia-aesni-avx2-asm_64.S index 0e0b8863a34b..16186c18656d 100644 --- a/arch/x86/crypto/camellia-aesni-avx2-asm_64.S +++ b/arch/x86/crypto/camellia-aesni-avx2-asm_64.S | |||
@@ -11,6 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/linkage.h> | 13 | #include <linux/linkage.h> |
14 | #include <asm/frame.h> | ||
14 | 15 | ||
15 | #define CAMELLIA_TABLE_BYTE_LEN 272 | 16 | #define CAMELLIA_TABLE_BYTE_LEN 272 |
16 | 17 | ||
@@ -766,6 +767,7 @@ __camellia_enc_blk32: | |||
766 | * %ymm0..%ymm15: 32 encrypted blocks, order swapped: | 767 | * %ymm0..%ymm15: 32 encrypted blocks, order swapped: |
767 | * 7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8 | 768 | * 7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8 |
768 | */ | 769 | */ |
770 | FRAME_BEGIN | ||
769 | 771 | ||
770 | leaq 8 * 32(%rax), %rcx; | 772 | leaq 8 * 32(%rax), %rcx; |
771 | 773 | ||
@@ -820,6 +822,7 @@ __camellia_enc_blk32: | |||
820 | %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, | 822 | %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, |
821 | %ymm15, (key_table)(CTX, %r8, 8), (%rax), 1 * 32(%rax)); | 823 | %ymm15, (key_table)(CTX, %r8, 8), (%rax), 1 * 32(%rax)); |
822 | 824 | ||
825 | FRAME_END | ||
823 | ret; | 826 | ret; |
824 | 827 | ||
825 | .align 8 | 828 | .align 8 |
@@ -852,6 +855,7 @@ __camellia_dec_blk32: | |||
852 | * %ymm0..%ymm15: 16 plaintext blocks, order swapped: | 855 | * %ymm0..%ymm15: 16 plaintext blocks, order swapped: |
853 | * 7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8 | 856 | * 7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8 |
854 | */ | 857 | */ |
858 | FRAME_BEGIN | ||
855 | 859 | ||
856 | leaq 8 * 32(%rax), %rcx; | 860 | leaq 8 * 32(%rax), %rcx; |
857 | 861 | ||
@@ -905,6 +909,7 @@ __camellia_dec_blk32: | |||
905 | %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, | 909 | %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, |
906 | %ymm15, (key_table)(CTX), (%rax), 1 * 32(%rax)); | 910 | %ymm15, (key_table)(CTX), (%rax), 1 * 32(%rax)); |
907 | 911 | ||
912 | FRAME_END | ||
908 | ret; | 913 | ret; |
909 | 914 | ||
910 | .align 8 | 915 | .align 8 |
@@ -930,6 +935,7 @@ ENTRY(camellia_ecb_enc_32way) | |||
930 | * %rsi: dst (32 blocks) | 935 | * %rsi: dst (32 blocks) |
931 | * %rdx: src (32 blocks) | 936 | * %rdx: src (32 blocks) |
932 | */ | 937 | */ |
938 | FRAME_BEGIN | ||
933 | 939 | ||
934 | vzeroupper; | 940 | vzeroupper; |
935 | 941 | ||
@@ -948,6 +954,7 @@ ENTRY(camellia_ecb_enc_32way) | |||
948 | 954 | ||
949 | vzeroupper; | 955 | vzeroupper; |
950 | 956 | ||
957 | FRAME_END | ||
951 | ret; | 958 | ret; |
952 | ENDPROC(camellia_ecb_enc_32way) | 959 | ENDPROC(camellia_ecb_enc_32way) |
953 | 960 | ||
@@ -957,6 +964,7 @@ ENTRY(camellia_ecb_dec_32way) | |||
957 | * %rsi: dst (32 blocks) | 964 | * %rsi: dst (32 blocks) |
958 | * %rdx: src (32 blocks) | 965 | * %rdx: src (32 blocks) |
959 | */ | 966 | */ |
967 | FRAME_BEGIN | ||
960 | 968 | ||
961 | vzeroupper; | 969 | vzeroupper; |
962 | 970 | ||
@@ -980,6 +988,7 @@ ENTRY(camellia_ecb_dec_32way) | |||
980 | 988 | ||
981 | vzeroupper; | 989 | vzeroupper; |
982 | 990 | ||
991 | FRAME_END | ||
983 | ret; | 992 | ret; |
984 | ENDPROC(camellia_ecb_dec_32way) | 993 | ENDPROC(camellia_ecb_dec_32way) |
985 | 994 | ||
@@ -989,6 +998,7 @@ ENTRY(camellia_cbc_dec_32way) | |||
989 | * %rsi: dst (32 blocks) | 998 | * %rsi: dst (32 blocks) |
990 | * %rdx: src (32 blocks) | 999 | * %rdx: src (32 blocks) |
991 | */ | 1000 | */ |
1001 | FRAME_BEGIN | ||
992 | 1002 | ||
993 | vzeroupper; | 1003 | vzeroupper; |
994 | 1004 | ||
@@ -1046,6 +1056,7 @@ ENTRY(camellia_cbc_dec_32way) | |||
1046 | 1056 | ||
1047 | vzeroupper; | 1057 | vzeroupper; |
1048 | 1058 | ||
1059 | FRAME_END | ||
1049 | ret; | 1060 | ret; |
1050 | ENDPROC(camellia_cbc_dec_32way) | 1061 | ENDPROC(camellia_cbc_dec_32way) |
1051 | 1062 | ||
@@ -1070,6 +1081,7 @@ ENTRY(camellia_ctr_32way) | |||
1070 | * %rdx: src (32 blocks) | 1081 | * %rdx: src (32 blocks) |
1071 | * %rcx: iv (little endian, 128bit) | 1082 | * %rcx: iv (little endian, 128bit) |
1072 | */ | 1083 | */ |
1084 | FRAME_BEGIN | ||
1073 | 1085 | ||
1074 | vzeroupper; | 1086 | vzeroupper; |
1075 | 1087 | ||
@@ -1184,6 +1196,7 @@ ENTRY(camellia_ctr_32way) | |||
1184 | 1196 | ||
1185 | vzeroupper; | 1197 | vzeroupper; |
1186 | 1198 | ||
1199 | FRAME_END | ||
1187 | ret; | 1200 | ret; |
1188 | ENDPROC(camellia_ctr_32way) | 1201 | ENDPROC(camellia_ctr_32way) |
1189 | 1202 | ||
@@ -1216,6 +1229,7 @@ camellia_xts_crypt_32way: | |||
1216 | * %r8: index for input whitening key | 1229 | * %r8: index for input whitening key |
1217 | * %r9: pointer to __camellia_enc_blk32 or __camellia_dec_blk32 | 1230 | * %r9: pointer to __camellia_enc_blk32 or __camellia_dec_blk32 |
1218 | */ | 1231 | */ |
1232 | FRAME_BEGIN | ||
1219 | 1233 | ||
1220 | vzeroupper; | 1234 | vzeroupper; |
1221 | 1235 | ||
@@ -1349,6 +1363,7 @@ camellia_xts_crypt_32way: | |||
1349 | 1363 | ||
1350 | vzeroupper; | 1364 | vzeroupper; |
1351 | 1365 | ||
1366 | FRAME_END | ||
1352 | ret; | 1367 | ret; |
1353 | ENDPROC(camellia_xts_crypt_32way) | 1368 | ENDPROC(camellia_xts_crypt_32way) |
1354 | 1369 | ||
diff --git a/arch/x86/crypto/cast5-avx-x86_64-asm_64.S b/arch/x86/crypto/cast5-avx-x86_64-asm_64.S index c35fd5d6ecd2..14fa1966bf01 100644 --- a/arch/x86/crypto/cast5-avx-x86_64-asm_64.S +++ b/arch/x86/crypto/cast5-avx-x86_64-asm_64.S | |||
@@ -24,6 +24,7 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/linkage.h> | 26 | #include <linux/linkage.h> |
27 | #include <asm/frame.h> | ||
27 | 28 | ||
28 | .file "cast5-avx-x86_64-asm_64.S" | 29 | .file "cast5-avx-x86_64-asm_64.S" |
29 | 30 | ||
@@ -365,6 +366,7 @@ ENTRY(cast5_ecb_enc_16way) | |||
365 | * %rsi: dst | 366 | * %rsi: dst |
366 | * %rdx: src | 367 | * %rdx: src |
367 | */ | 368 | */ |
369 | FRAME_BEGIN | ||
368 | 370 | ||
369 | movq %rsi, %r11; | 371 | movq %rsi, %r11; |
370 | 372 | ||
@@ -388,6 +390,7 @@ ENTRY(cast5_ecb_enc_16way) | |||
388 | vmovdqu RR4, (6*4*4)(%r11); | 390 | vmovdqu RR4, (6*4*4)(%r11); |
389 | vmovdqu RL4, (7*4*4)(%r11); | 391 | vmovdqu RL4, (7*4*4)(%r11); |
390 | 392 | ||
393 | FRAME_END | ||
391 | ret; | 394 | ret; |
392 | ENDPROC(cast5_ecb_enc_16way) | 395 | ENDPROC(cast5_ecb_enc_16way) |
393 | 396 | ||
@@ -398,6 +401,7 @@ ENTRY(cast5_ecb_dec_16way) | |||
398 | * %rdx: src | 401 | * %rdx: src |
399 | */ | 402 | */ |
400 | 403 | ||
404 | FRAME_BEGIN | ||
401 | movq %rsi, %r11; | 405 | movq %rsi, %r11; |
402 | 406 | ||
403 | vmovdqu (0*4*4)(%rdx), RL1; | 407 | vmovdqu (0*4*4)(%rdx), RL1; |
@@ -420,6 +424,7 @@ ENTRY(cast5_ecb_dec_16way) | |||
420 | vmovdqu RR4, (6*4*4)(%r11); | 424 | vmovdqu RR4, (6*4*4)(%r11); |
421 | vmovdqu RL4, (7*4*4)(%r11); | 425 | vmovdqu RL4, (7*4*4)(%r11); |
422 | 426 | ||
427 | FRAME_END | ||
423 | ret; | 428 | ret; |
424 | ENDPROC(cast5_ecb_dec_16way) | 429 | ENDPROC(cast5_ecb_dec_16way) |
425 | 430 | ||
@@ -429,6 +434,7 @@ ENTRY(cast5_cbc_dec_16way) | |||
429 | * %rsi: dst | 434 | * %rsi: dst |
430 | * %rdx: src | 435 | * %rdx: src |
431 | */ | 436 | */ |
437 | FRAME_BEGIN | ||
432 | 438 | ||
433 | pushq %r12; | 439 | pushq %r12; |
434 | 440 | ||
@@ -469,6 +475,7 @@ ENTRY(cast5_cbc_dec_16way) | |||
469 | 475 | ||
470 | popq %r12; | 476 | popq %r12; |
471 | 477 | ||
478 | FRAME_END | ||
472 | ret; | 479 | ret; |
473 | ENDPROC(cast5_cbc_dec_16way) | 480 | ENDPROC(cast5_cbc_dec_16way) |
474 | 481 | ||
@@ -479,6 +486,7 @@ ENTRY(cast5_ctr_16way) | |||
479 | * %rdx: src | 486 | * %rdx: src |
480 | * %rcx: iv (big endian, 64bit) | 487 | * %rcx: iv (big endian, 64bit) |
481 | */ | 488 | */ |
489 | FRAME_BEGIN | ||
482 | 490 | ||
483 | pushq %r12; | 491 | pushq %r12; |
484 | 492 | ||
@@ -542,5 +550,6 @@ ENTRY(cast5_ctr_16way) | |||
542 | 550 | ||
543 | popq %r12; | 551 | popq %r12; |
544 | 552 | ||
553 | FRAME_END | ||
545 | ret; | 554 | ret; |
546 | ENDPROC(cast5_ctr_16way) | 555 | ENDPROC(cast5_ctr_16way) |
diff --git a/arch/x86/crypto/cast6-avx-x86_64-asm_64.S b/arch/x86/crypto/cast6-avx-x86_64-asm_64.S index e3531f833951..c419389889cd 100644 --- a/arch/x86/crypto/cast6-avx-x86_64-asm_64.S +++ b/arch/x86/crypto/cast6-avx-x86_64-asm_64.S | |||
@@ -24,6 +24,7 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/linkage.h> | 26 | #include <linux/linkage.h> |
27 | #include <asm/frame.h> | ||
27 | #include "glue_helper-asm-avx.S" | 28 | #include "glue_helper-asm-avx.S" |
28 | 29 | ||
29 | .file "cast6-avx-x86_64-asm_64.S" | 30 | .file "cast6-avx-x86_64-asm_64.S" |
@@ -349,6 +350,7 @@ ENTRY(cast6_ecb_enc_8way) | |||
349 | * %rsi: dst | 350 | * %rsi: dst |
350 | * %rdx: src | 351 | * %rdx: src |
351 | */ | 352 | */ |
353 | FRAME_BEGIN | ||
352 | 354 | ||
353 | movq %rsi, %r11; | 355 | movq %rsi, %r11; |
354 | 356 | ||
@@ -358,6 +360,7 @@ ENTRY(cast6_ecb_enc_8way) | |||
358 | 360 | ||
359 | store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); | 361 | store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); |
360 | 362 | ||
363 | FRAME_END | ||
361 | ret; | 364 | ret; |
362 | ENDPROC(cast6_ecb_enc_8way) | 365 | ENDPROC(cast6_ecb_enc_8way) |
363 | 366 | ||
@@ -367,6 +370,7 @@ ENTRY(cast6_ecb_dec_8way) | |||
367 | * %rsi: dst | 370 | * %rsi: dst |
368 | * %rdx: src | 371 | * %rdx: src |
369 | */ | 372 | */ |
373 | FRAME_BEGIN | ||
370 | 374 | ||
371 | movq %rsi, %r11; | 375 | movq %rsi, %r11; |
372 | 376 | ||
@@ -376,6 +380,7 @@ ENTRY(cast6_ecb_dec_8way) | |||
376 | 380 | ||
377 | store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); | 381 | store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); |
378 | 382 | ||
383 | FRAME_END | ||
379 | ret; | 384 | ret; |
380 | ENDPROC(cast6_ecb_dec_8way) | 385 | ENDPROC(cast6_ecb_dec_8way) |
381 | 386 | ||
@@ -385,6 +390,7 @@ ENTRY(cast6_cbc_dec_8way) | |||
385 | * %rsi: dst | 390 | * %rsi: dst |
386 | * %rdx: src | 391 | * %rdx: src |
387 | */ | 392 | */ |
393 | FRAME_BEGIN | ||
388 | 394 | ||
389 | pushq %r12; | 395 | pushq %r12; |
390 | 396 | ||
@@ -399,6 +405,7 @@ ENTRY(cast6_cbc_dec_8way) | |||
399 | 405 | ||
400 | popq %r12; | 406 | popq %r12; |
401 | 407 | ||
408 | FRAME_END | ||
402 | ret; | 409 | ret; |
403 | ENDPROC(cast6_cbc_dec_8way) | 410 | ENDPROC(cast6_cbc_dec_8way) |
404 | 411 | ||
@@ -409,6 +416,7 @@ ENTRY(cast6_ctr_8way) | |||
409 | * %rdx: src | 416 | * %rdx: src |
410 | * %rcx: iv (little endian, 128bit) | 417 | * %rcx: iv (little endian, 128bit) |
411 | */ | 418 | */ |
419 | FRAME_BEGIN | ||
412 | 420 | ||
413 | pushq %r12; | 421 | pushq %r12; |
414 | 422 | ||
@@ -424,6 +432,7 @@ ENTRY(cast6_ctr_8way) | |||
424 | 432 | ||
425 | popq %r12; | 433 | popq %r12; |
426 | 434 | ||
435 | FRAME_END | ||
427 | ret; | 436 | ret; |
428 | ENDPROC(cast6_ctr_8way) | 437 | ENDPROC(cast6_ctr_8way) |
429 | 438 | ||
@@ -434,6 +443,7 @@ ENTRY(cast6_xts_enc_8way) | |||
434 | * %rdx: src | 443 | * %rdx: src |
435 | * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) | 444 | * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) |
436 | */ | 445 | */ |
446 | FRAME_BEGIN | ||
437 | 447 | ||
438 | movq %rsi, %r11; | 448 | movq %rsi, %r11; |
439 | 449 | ||
@@ -446,6 +456,7 @@ ENTRY(cast6_xts_enc_8way) | |||
446 | /* dst <= regs xor IVs(in dst) */ | 456 | /* dst <= regs xor IVs(in dst) */ |
447 | store_xts_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); | 457 | store_xts_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); |
448 | 458 | ||
459 | FRAME_END | ||
449 | ret; | 460 | ret; |
450 | ENDPROC(cast6_xts_enc_8way) | 461 | ENDPROC(cast6_xts_enc_8way) |
451 | 462 | ||
@@ -456,6 +467,7 @@ ENTRY(cast6_xts_dec_8way) | |||
456 | * %rdx: src | 467 | * %rdx: src |
457 | * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) | 468 | * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) |
458 | */ | 469 | */ |
470 | FRAME_BEGIN | ||
459 | 471 | ||
460 | movq %rsi, %r11; | 472 | movq %rsi, %r11; |
461 | 473 | ||
@@ -468,5 +480,6 @@ ENTRY(cast6_xts_dec_8way) | |||
468 | /* dst <= regs xor IVs(in dst) */ | 480 | /* dst <= regs xor IVs(in dst) */ |
469 | store_xts_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); | 481 | store_xts_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); |
470 | 482 | ||
483 | FRAME_END | ||
471 | ret; | 484 | ret; |
472 | ENDPROC(cast6_xts_dec_8way) | 485 | ENDPROC(cast6_xts_dec_8way) |
diff --git a/arch/x86/crypto/crc32-pclmul_glue.c b/arch/x86/crypto/crc32-pclmul_glue.c index 07d2c6c86a54..27226df3f7d8 100644 --- a/arch/x86/crypto/crc32-pclmul_glue.c +++ b/arch/x86/crypto/crc32-pclmul_glue.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #include <linux/crc32.h> | 33 | #include <linux/crc32.h> |
34 | #include <crypto/internal/hash.h> | 34 | #include <crypto/internal/hash.h> |
35 | 35 | ||
36 | #include <asm/cpufeature.h> | 36 | #include <asm/cpufeatures.h> |
37 | #include <asm/cpu_device_id.h> | 37 | #include <asm/cpu_device_id.h> |
38 | #include <asm/fpu/api.h> | 38 | #include <asm/fpu/api.h> |
39 | 39 | ||
diff --git a/arch/x86/crypto/crc32c-intel_glue.c b/arch/x86/crypto/crc32c-intel_glue.c index 0e9871693f24..0857b1a1de3b 100644 --- a/arch/x86/crypto/crc32c-intel_glue.c +++ b/arch/x86/crypto/crc32c-intel_glue.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <crypto/internal/hash.h> | 31 | #include <crypto/internal/hash.h> |
32 | 32 | ||
33 | #include <asm/cpufeature.h> | 33 | #include <asm/cpufeatures.h> |
34 | #include <asm/cpu_device_id.h> | 34 | #include <asm/cpu_device_id.h> |
35 | #include <asm/fpu/internal.h> | 35 | #include <asm/fpu/internal.h> |
36 | 36 | ||
diff --git a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S b/arch/x86/crypto/crc32c-pcl-intel-asm_64.S index 4fe27e074194..dc05f010ca9b 100644 --- a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S +++ b/arch/x86/crypto/crc32c-pcl-intel-asm_64.S | |||
@@ -170,8 +170,8 @@ continue_block: | |||
170 | ## branch into array | 170 | ## branch into array |
171 | lea jump_table(%rip), bufp | 171 | lea jump_table(%rip), bufp |
172 | movzxw (bufp, %rax, 2), len | 172 | movzxw (bufp, %rax, 2), len |
173 | offset=crc_array-jump_table | 173 | lea crc_array(%rip), bufp |
174 | lea offset(bufp, len, 1), bufp | 174 | lea (bufp, len, 1), bufp |
175 | jmp *bufp | 175 | jmp *bufp |
176 | 176 | ||
177 | ################################################################ | 177 | ################################################################ |
@@ -310,7 +310,9 @@ do_return: | |||
310 | popq %rdi | 310 | popq %rdi |
311 | popq %rbx | 311 | popq %rbx |
312 | ret | 312 | ret |
313 | ENDPROC(crc_pcl) | ||
313 | 314 | ||
315 | .section .rodata, "a", %progbits | ||
314 | ################################################################ | 316 | ################################################################ |
315 | ## jump table Table is 129 entries x 2 bytes each | 317 | ## jump table Table is 129 entries x 2 bytes each |
316 | ################################################################ | 318 | ################################################################ |
@@ -324,13 +326,11 @@ JMPTBL_ENTRY %i | |||
324 | i=i+1 | 326 | i=i+1 |
325 | .endr | 327 | .endr |
326 | 328 | ||
327 | ENDPROC(crc_pcl) | ||
328 | 329 | ||
329 | ################################################################ | 330 | ################################################################ |
330 | ## PCLMULQDQ tables | 331 | ## PCLMULQDQ tables |
331 | ## Table is 128 entries x 2 words (8 bytes) each | 332 | ## Table is 128 entries x 2 words (8 bytes) each |
332 | ################################################################ | 333 | ################################################################ |
333 | .section .rodata, "a", %progbits | ||
334 | .align 8 | 334 | .align 8 |
335 | K_table: | 335 | K_table: |
336 | .long 0x493c7d27, 0x00000001 | 336 | .long 0x493c7d27, 0x00000001 |
diff --git a/arch/x86/crypto/crct10dif-pclmul_glue.c b/arch/x86/crypto/crct10dif-pclmul_glue.c index a3fcfc97a311..cd4df9322501 100644 --- a/arch/x86/crypto/crct10dif-pclmul_glue.c +++ b/arch/x86/crypto/crct10dif-pclmul_glue.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <linux/string.h> | 30 | #include <linux/string.h> |
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <asm/fpu/api.h> | 32 | #include <asm/fpu/api.h> |
33 | #include <asm/cpufeature.h> | 33 | #include <asm/cpufeatures.h> |
34 | #include <asm/cpu_device_id.h> | 34 | #include <asm/cpu_device_id.h> |
35 | 35 | ||
36 | asmlinkage __u16 crc_t10dif_pcl(__u16 crc, const unsigned char *buf, | 36 | asmlinkage __u16 crc_t10dif_pcl(__u16 crc, const unsigned char *buf, |
diff --git a/arch/x86/crypto/ghash-clmulni-intel_asm.S b/arch/x86/crypto/ghash-clmulni-intel_asm.S index 5d1e0075ac24..eed55c8cca4f 100644 --- a/arch/x86/crypto/ghash-clmulni-intel_asm.S +++ b/arch/x86/crypto/ghash-clmulni-intel_asm.S | |||
@@ -18,6 +18,7 @@ | |||
18 | 18 | ||
19 | #include <linux/linkage.h> | 19 | #include <linux/linkage.h> |
20 | #include <asm/inst.h> | 20 | #include <asm/inst.h> |
21 | #include <asm/frame.h> | ||
21 | 22 | ||
22 | .data | 23 | .data |
23 | 24 | ||
@@ -94,6 +95,7 @@ ENDPROC(__clmul_gf128mul_ble) | |||
94 | 95 | ||
95 | /* void clmul_ghash_mul(char *dst, const u128 *shash) */ | 96 | /* void clmul_ghash_mul(char *dst, const u128 *shash) */ |
96 | ENTRY(clmul_ghash_mul) | 97 | ENTRY(clmul_ghash_mul) |
98 | FRAME_BEGIN | ||
97 | movups (%rdi), DATA | 99 | movups (%rdi), DATA |
98 | movups (%rsi), SHASH | 100 | movups (%rsi), SHASH |
99 | movaps .Lbswap_mask, BSWAP | 101 | movaps .Lbswap_mask, BSWAP |
@@ -101,6 +103,7 @@ ENTRY(clmul_ghash_mul) | |||
101 | call __clmul_gf128mul_ble | 103 | call __clmul_gf128mul_ble |
102 | PSHUFB_XMM BSWAP DATA | 104 | PSHUFB_XMM BSWAP DATA |
103 | movups DATA, (%rdi) | 105 | movups DATA, (%rdi) |
106 | FRAME_END | ||
104 | ret | 107 | ret |
105 | ENDPROC(clmul_ghash_mul) | 108 | ENDPROC(clmul_ghash_mul) |
106 | 109 | ||
@@ -109,6 +112,7 @@ ENDPROC(clmul_ghash_mul) | |||
109 | * const u128 *shash); | 112 | * const u128 *shash); |
110 | */ | 113 | */ |
111 | ENTRY(clmul_ghash_update) | 114 | ENTRY(clmul_ghash_update) |
115 | FRAME_BEGIN | ||
112 | cmp $16, %rdx | 116 | cmp $16, %rdx |
113 | jb .Lupdate_just_ret # check length | 117 | jb .Lupdate_just_ret # check length |
114 | movaps .Lbswap_mask, BSWAP | 118 | movaps .Lbswap_mask, BSWAP |
@@ -128,5 +132,6 @@ ENTRY(clmul_ghash_update) | |||
128 | PSHUFB_XMM BSWAP DATA | 132 | PSHUFB_XMM BSWAP DATA |
129 | movups DATA, (%rdi) | 133 | movups DATA, (%rdi) |
130 | .Lupdate_just_ret: | 134 | .Lupdate_just_ret: |
135 | FRAME_END | ||
131 | ret | 136 | ret |
132 | ENDPROC(clmul_ghash_update) | 137 | ENDPROC(clmul_ghash_update) |
diff --git a/arch/x86/crypto/serpent-avx-x86_64-asm_64.S b/arch/x86/crypto/serpent-avx-x86_64-asm_64.S index 2f202f49872b..8be571808342 100644 --- a/arch/x86/crypto/serpent-avx-x86_64-asm_64.S +++ b/arch/x86/crypto/serpent-avx-x86_64-asm_64.S | |||
@@ -24,6 +24,7 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/linkage.h> | 26 | #include <linux/linkage.h> |
27 | #include <asm/frame.h> | ||
27 | #include "glue_helper-asm-avx.S" | 28 | #include "glue_helper-asm-avx.S" |
28 | 29 | ||
29 | .file "serpent-avx-x86_64-asm_64.S" | 30 | .file "serpent-avx-x86_64-asm_64.S" |
@@ -681,6 +682,7 @@ ENTRY(serpent_ecb_enc_8way_avx) | |||
681 | * %rsi: dst | 682 | * %rsi: dst |
682 | * %rdx: src | 683 | * %rdx: src |
683 | */ | 684 | */ |
685 | FRAME_BEGIN | ||
684 | 686 | ||
685 | load_8way(%rdx, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); | 687 | load_8way(%rdx, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); |
686 | 688 | ||
@@ -688,6 +690,7 @@ ENTRY(serpent_ecb_enc_8way_avx) | |||
688 | 690 | ||
689 | store_8way(%rsi, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); | 691 | store_8way(%rsi, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); |
690 | 692 | ||
693 | FRAME_END | ||
691 | ret; | 694 | ret; |
692 | ENDPROC(serpent_ecb_enc_8way_avx) | 695 | ENDPROC(serpent_ecb_enc_8way_avx) |
693 | 696 | ||
@@ -697,6 +700,7 @@ ENTRY(serpent_ecb_dec_8way_avx) | |||
697 | * %rsi: dst | 700 | * %rsi: dst |
698 | * %rdx: src | 701 | * %rdx: src |
699 | */ | 702 | */ |
703 | FRAME_BEGIN | ||
700 | 704 | ||
701 | load_8way(%rdx, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); | 705 | load_8way(%rdx, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); |
702 | 706 | ||
@@ -704,6 +708,7 @@ ENTRY(serpent_ecb_dec_8way_avx) | |||
704 | 708 | ||
705 | store_8way(%rsi, RC1, RD1, RB1, RE1, RC2, RD2, RB2, RE2); | 709 | store_8way(%rsi, RC1, RD1, RB1, RE1, RC2, RD2, RB2, RE2); |
706 | 710 | ||
711 | FRAME_END | ||
707 | ret; | 712 | ret; |
708 | ENDPROC(serpent_ecb_dec_8way_avx) | 713 | ENDPROC(serpent_ecb_dec_8way_avx) |
709 | 714 | ||
@@ -713,6 +718,7 @@ ENTRY(serpent_cbc_dec_8way_avx) | |||
713 | * %rsi: dst | 718 | * %rsi: dst |
714 | * %rdx: src | 719 | * %rdx: src |
715 | */ | 720 | */ |
721 | FRAME_BEGIN | ||
716 | 722 | ||
717 | load_8way(%rdx, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); | 723 | load_8way(%rdx, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); |
718 | 724 | ||
@@ -720,6 +726,7 @@ ENTRY(serpent_cbc_dec_8way_avx) | |||
720 | 726 | ||
721 | store_cbc_8way(%rdx, %rsi, RC1, RD1, RB1, RE1, RC2, RD2, RB2, RE2); | 727 | store_cbc_8way(%rdx, %rsi, RC1, RD1, RB1, RE1, RC2, RD2, RB2, RE2); |
722 | 728 | ||
729 | FRAME_END | ||
723 | ret; | 730 | ret; |
724 | ENDPROC(serpent_cbc_dec_8way_avx) | 731 | ENDPROC(serpent_cbc_dec_8way_avx) |
725 | 732 | ||
@@ -730,6 +737,7 @@ ENTRY(serpent_ctr_8way_avx) | |||
730 | * %rdx: src | 737 | * %rdx: src |
731 | * %rcx: iv (little endian, 128bit) | 738 | * %rcx: iv (little endian, 128bit) |
732 | */ | 739 | */ |
740 | FRAME_BEGIN | ||
733 | 741 | ||
734 | load_ctr_8way(%rcx, .Lbswap128_mask, RA1, RB1, RC1, RD1, RA2, RB2, RC2, | 742 | load_ctr_8way(%rcx, .Lbswap128_mask, RA1, RB1, RC1, RD1, RA2, RB2, RC2, |
735 | RD2, RK0, RK1, RK2); | 743 | RD2, RK0, RK1, RK2); |
@@ -738,6 +746,7 @@ ENTRY(serpent_ctr_8way_avx) | |||
738 | 746 | ||
739 | store_ctr_8way(%rdx, %rsi, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); | 747 | store_ctr_8way(%rdx, %rsi, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); |
740 | 748 | ||
749 | FRAME_END | ||
741 | ret; | 750 | ret; |
742 | ENDPROC(serpent_ctr_8way_avx) | 751 | ENDPROC(serpent_ctr_8way_avx) |
743 | 752 | ||
@@ -748,6 +757,7 @@ ENTRY(serpent_xts_enc_8way_avx) | |||
748 | * %rdx: src | 757 | * %rdx: src |
749 | * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) | 758 | * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) |
750 | */ | 759 | */ |
760 | FRAME_BEGIN | ||
751 | 761 | ||
752 | /* regs <= src, dst <= IVs, regs <= regs xor IVs */ | 762 | /* regs <= src, dst <= IVs, regs <= regs xor IVs */ |
753 | load_xts_8way(%rcx, %rdx, %rsi, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2, | 763 | load_xts_8way(%rcx, %rdx, %rsi, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2, |
@@ -758,6 +768,7 @@ ENTRY(serpent_xts_enc_8way_avx) | |||
758 | /* dst <= regs xor IVs(in dst) */ | 768 | /* dst <= regs xor IVs(in dst) */ |
759 | store_xts_8way(%rsi, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); | 769 | store_xts_8way(%rsi, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); |
760 | 770 | ||
771 | FRAME_END | ||
761 | ret; | 772 | ret; |
762 | ENDPROC(serpent_xts_enc_8way_avx) | 773 | ENDPROC(serpent_xts_enc_8way_avx) |
763 | 774 | ||
@@ -768,6 +779,7 @@ ENTRY(serpent_xts_dec_8way_avx) | |||
768 | * %rdx: src | 779 | * %rdx: src |
769 | * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) | 780 | * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) |
770 | */ | 781 | */ |
782 | FRAME_BEGIN | ||
771 | 783 | ||
772 | /* regs <= src, dst <= IVs, regs <= regs xor IVs */ | 784 | /* regs <= src, dst <= IVs, regs <= regs xor IVs */ |
773 | load_xts_8way(%rcx, %rdx, %rsi, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2, | 785 | load_xts_8way(%rcx, %rdx, %rsi, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2, |
@@ -778,5 +790,6 @@ ENTRY(serpent_xts_dec_8way_avx) | |||
778 | /* dst <= regs xor IVs(in dst) */ | 790 | /* dst <= regs xor IVs(in dst) */ |
779 | store_xts_8way(%rsi, RC1, RD1, RB1, RE1, RC2, RD2, RB2, RE2); | 791 | store_xts_8way(%rsi, RC1, RD1, RB1, RE1, RC2, RD2, RB2, RE2); |
780 | 792 | ||
793 | FRAME_END | ||
781 | ret; | 794 | ret; |
782 | ENDPROC(serpent_xts_dec_8way_avx) | 795 | ENDPROC(serpent_xts_dec_8way_avx) |
diff --git a/arch/x86/crypto/serpent-avx2-asm_64.S b/arch/x86/crypto/serpent-avx2-asm_64.S index b222085cccac..97c48add33ed 100644 --- a/arch/x86/crypto/serpent-avx2-asm_64.S +++ b/arch/x86/crypto/serpent-avx2-asm_64.S | |||
@@ -15,6 +15,7 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/linkage.h> | 17 | #include <linux/linkage.h> |
18 | #include <asm/frame.h> | ||
18 | #include "glue_helper-asm-avx2.S" | 19 | #include "glue_helper-asm-avx2.S" |
19 | 20 | ||
20 | .file "serpent-avx2-asm_64.S" | 21 | .file "serpent-avx2-asm_64.S" |
@@ -673,6 +674,7 @@ ENTRY(serpent_ecb_enc_16way) | |||
673 | * %rsi: dst | 674 | * %rsi: dst |
674 | * %rdx: src | 675 | * %rdx: src |
675 | */ | 676 | */ |
677 | FRAME_BEGIN | ||
676 | 678 | ||
677 | vzeroupper; | 679 | vzeroupper; |
678 | 680 | ||
@@ -684,6 +686,7 @@ ENTRY(serpent_ecb_enc_16way) | |||
684 | 686 | ||
685 | vzeroupper; | 687 | vzeroupper; |
686 | 688 | ||
689 | FRAME_END | ||
687 | ret; | 690 | ret; |
688 | ENDPROC(serpent_ecb_enc_16way) | 691 | ENDPROC(serpent_ecb_enc_16way) |
689 | 692 | ||
@@ -693,6 +696,7 @@ ENTRY(serpent_ecb_dec_16way) | |||
693 | * %rsi: dst | 696 | * %rsi: dst |
694 | * %rdx: src | 697 | * %rdx: src |
695 | */ | 698 | */ |
699 | FRAME_BEGIN | ||
696 | 700 | ||
697 | vzeroupper; | 701 | vzeroupper; |
698 | 702 | ||
@@ -704,6 +708,7 @@ ENTRY(serpent_ecb_dec_16way) | |||
704 | 708 | ||
705 | vzeroupper; | 709 | vzeroupper; |
706 | 710 | ||
711 | FRAME_END | ||
707 | ret; | 712 | ret; |
708 | ENDPROC(serpent_ecb_dec_16way) | 713 | ENDPROC(serpent_ecb_dec_16way) |
709 | 714 | ||
@@ -713,6 +718,7 @@ ENTRY(serpent_cbc_dec_16way) | |||
713 | * %rsi: dst | 718 | * %rsi: dst |
714 | * %rdx: src | 719 | * %rdx: src |
715 | */ | 720 | */ |
721 | FRAME_BEGIN | ||
716 | 722 | ||
717 | vzeroupper; | 723 | vzeroupper; |
718 | 724 | ||
@@ -725,6 +731,7 @@ ENTRY(serpent_cbc_dec_16way) | |||
725 | 731 | ||
726 | vzeroupper; | 732 | vzeroupper; |
727 | 733 | ||
734 | FRAME_END | ||
728 | ret; | 735 | ret; |
729 | ENDPROC(serpent_cbc_dec_16way) | 736 | ENDPROC(serpent_cbc_dec_16way) |
730 | 737 | ||
@@ -735,6 +742,7 @@ ENTRY(serpent_ctr_16way) | |||
735 | * %rdx: src (16 blocks) | 742 | * %rdx: src (16 blocks) |
736 | * %rcx: iv (little endian, 128bit) | 743 | * %rcx: iv (little endian, 128bit) |
737 | */ | 744 | */ |
745 | FRAME_BEGIN | ||
738 | 746 | ||
739 | vzeroupper; | 747 | vzeroupper; |
740 | 748 | ||
@@ -748,6 +756,7 @@ ENTRY(serpent_ctr_16way) | |||
748 | 756 | ||
749 | vzeroupper; | 757 | vzeroupper; |
750 | 758 | ||
759 | FRAME_END | ||
751 | ret; | 760 | ret; |
752 | ENDPROC(serpent_ctr_16way) | 761 | ENDPROC(serpent_ctr_16way) |
753 | 762 | ||
@@ -758,6 +767,7 @@ ENTRY(serpent_xts_enc_16way) | |||
758 | * %rdx: src (16 blocks) | 767 | * %rdx: src (16 blocks) |
759 | * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) | 768 | * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) |
760 | */ | 769 | */ |
770 | FRAME_BEGIN | ||
761 | 771 | ||
762 | vzeroupper; | 772 | vzeroupper; |
763 | 773 | ||
@@ -772,6 +782,7 @@ ENTRY(serpent_xts_enc_16way) | |||
772 | 782 | ||
773 | vzeroupper; | 783 | vzeroupper; |
774 | 784 | ||
785 | FRAME_END | ||
775 | ret; | 786 | ret; |
776 | ENDPROC(serpent_xts_enc_16way) | 787 | ENDPROC(serpent_xts_enc_16way) |
777 | 788 | ||
@@ -782,6 +793,7 @@ ENTRY(serpent_xts_dec_16way) | |||
782 | * %rdx: src (16 blocks) | 793 | * %rdx: src (16 blocks) |
783 | * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) | 794 | * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) |
784 | */ | 795 | */ |
796 | FRAME_BEGIN | ||
785 | 797 | ||
786 | vzeroupper; | 798 | vzeroupper; |
787 | 799 | ||
@@ -796,5 +808,6 @@ ENTRY(serpent_xts_dec_16way) | |||
796 | 808 | ||
797 | vzeroupper; | 809 | vzeroupper; |
798 | 810 | ||
811 | FRAME_END | ||
799 | ret; | 812 | ret; |
800 | ENDPROC(serpent_xts_dec_16way) | 813 | ENDPROC(serpent_xts_dec_16way) |
diff --git a/arch/x86/crypto/sha-mb/sha1_mb_mgr_flush_avx2.S b/arch/x86/crypto/sha-mb/sha1_mb_mgr_flush_avx2.S index 85c4e1cf7172..96df6a39d7e2 100644 --- a/arch/x86/crypto/sha-mb/sha1_mb_mgr_flush_avx2.S +++ b/arch/x86/crypto/sha-mb/sha1_mb_mgr_flush_avx2.S | |||
@@ -52,6 +52,7 @@ | |||
52 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 52 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
53 | */ | 53 | */ |
54 | #include <linux/linkage.h> | 54 | #include <linux/linkage.h> |
55 | #include <asm/frame.h> | ||
55 | #include "sha1_mb_mgr_datastruct.S" | 56 | #include "sha1_mb_mgr_datastruct.S" |
56 | 57 | ||
57 | 58 | ||
@@ -86,16 +87,6 @@ | |||
86 | #define extra_blocks %arg2 | 87 | #define extra_blocks %arg2 |
87 | #define p %arg2 | 88 | #define p %arg2 |
88 | 89 | ||
89 | |||
90 | # STACK_SPACE needs to be an odd multiple of 8 | ||
91 | _XMM_SAVE_SIZE = 10*16 | ||
92 | _GPR_SAVE_SIZE = 8*8 | ||
93 | _ALIGN_SIZE = 8 | ||
94 | |||
95 | _XMM_SAVE = 0 | ||
96 | _GPR_SAVE = _XMM_SAVE + _XMM_SAVE_SIZE | ||
97 | STACK_SPACE = _GPR_SAVE + _GPR_SAVE_SIZE + _ALIGN_SIZE | ||
98 | |||
99 | .macro LABEL prefix n | 90 | .macro LABEL prefix n |
100 | \prefix\n\(): | 91 | \prefix\n\(): |
101 | .endm | 92 | .endm |
@@ -113,16 +104,8 @@ offset = \_offset | |||
113 | # JOB* sha1_mb_mgr_flush_avx2(MB_MGR *state) | 104 | # JOB* sha1_mb_mgr_flush_avx2(MB_MGR *state) |
114 | # arg 1 : rcx : state | 105 | # arg 1 : rcx : state |
115 | ENTRY(sha1_mb_mgr_flush_avx2) | 106 | ENTRY(sha1_mb_mgr_flush_avx2) |
116 | mov %rsp, %r10 | 107 | FRAME_BEGIN |
117 | sub $STACK_SPACE, %rsp | 108 | push %rbx |
118 | and $~31, %rsp | ||
119 | mov %rbx, _GPR_SAVE(%rsp) | ||
120 | mov %r10, _GPR_SAVE+8*1(%rsp) #save rsp | ||
121 | mov %rbp, _GPR_SAVE+8*3(%rsp) | ||
122 | mov %r12, _GPR_SAVE+8*4(%rsp) | ||
123 | mov %r13, _GPR_SAVE+8*5(%rsp) | ||
124 | mov %r14, _GPR_SAVE+8*6(%rsp) | ||
125 | mov %r15, _GPR_SAVE+8*7(%rsp) | ||
126 | 109 | ||
127 | # If bit (32+3) is set, then all lanes are empty | 110 | # If bit (32+3) is set, then all lanes are empty |
128 | mov _unused_lanes(state), unused_lanes | 111 | mov _unused_lanes(state), unused_lanes |
@@ -230,16 +213,8 @@ len_is_0: | |||
230 | mov tmp2_w, offset(job_rax) | 213 | mov tmp2_w, offset(job_rax) |
231 | 214 | ||
232 | return: | 215 | return: |
233 | 216 | pop %rbx | |
234 | mov _GPR_SAVE(%rsp), %rbx | 217 | FRAME_END |
235 | mov _GPR_SAVE+8*1(%rsp), %r10 #saved rsp | ||
236 | mov _GPR_SAVE+8*3(%rsp), %rbp | ||
237 | mov _GPR_SAVE+8*4(%rsp), %r12 | ||
238 | mov _GPR_SAVE+8*5(%rsp), %r13 | ||
239 | mov _GPR_SAVE+8*6(%rsp), %r14 | ||
240 | mov _GPR_SAVE+8*7(%rsp), %r15 | ||
241 | mov %r10, %rsp | ||
242 | |||
243 | ret | 218 | ret |
244 | 219 | ||
245 | return_null: | 220 | return_null: |
diff --git a/arch/x86/crypto/sha-mb/sha1_mb_mgr_submit_avx2.S b/arch/x86/crypto/sha-mb/sha1_mb_mgr_submit_avx2.S index 2ab9560b53c8..1435acf46f22 100644 --- a/arch/x86/crypto/sha-mb/sha1_mb_mgr_submit_avx2.S +++ b/arch/x86/crypto/sha-mb/sha1_mb_mgr_submit_avx2.S | |||
@@ -53,6 +53,7 @@ | |||
53 | */ | 53 | */ |
54 | 54 | ||
55 | #include <linux/linkage.h> | 55 | #include <linux/linkage.h> |
56 | #include <asm/frame.h> | ||
56 | #include "sha1_mb_mgr_datastruct.S" | 57 | #include "sha1_mb_mgr_datastruct.S" |
57 | 58 | ||
58 | 59 | ||
@@ -86,33 +87,21 @@ job_rax = %rax | |||
86 | len = %rax | 87 | len = %rax |
87 | DWORD_len = %eax | 88 | DWORD_len = %eax |
88 | 89 | ||
89 | lane = %rbp | 90 | lane = %r12 |
90 | tmp3 = %rbp | 91 | tmp3 = %r12 |
91 | 92 | ||
92 | tmp = %r9 | 93 | tmp = %r9 |
93 | DWORD_tmp = %r9d | 94 | DWORD_tmp = %r9d |
94 | 95 | ||
95 | lane_data = %r10 | 96 | lane_data = %r10 |
96 | 97 | ||
97 | # STACK_SPACE needs to be an odd multiple of 8 | ||
98 | STACK_SPACE = 8*8 + 16*10 + 8 | ||
99 | |||
100 | # JOB* submit_mb_mgr_submit_avx2(MB_MGR *state, job_sha1 *job) | 98 | # JOB* submit_mb_mgr_submit_avx2(MB_MGR *state, job_sha1 *job) |
101 | # arg 1 : rcx : state | 99 | # arg 1 : rcx : state |
102 | # arg 2 : rdx : job | 100 | # arg 2 : rdx : job |
103 | ENTRY(sha1_mb_mgr_submit_avx2) | 101 | ENTRY(sha1_mb_mgr_submit_avx2) |
104 | 102 | FRAME_BEGIN | |
105 | mov %rsp, %r10 | 103 | push %rbx |
106 | sub $STACK_SPACE, %rsp | 104 | push %r12 |
107 | and $~31, %rsp | ||
108 | |||
109 | mov %rbx, (%rsp) | ||
110 | mov %r10, 8*2(%rsp) #save old rsp | ||
111 | mov %rbp, 8*3(%rsp) | ||
112 | mov %r12, 8*4(%rsp) | ||
113 | mov %r13, 8*5(%rsp) | ||
114 | mov %r14, 8*6(%rsp) | ||
115 | mov %r15, 8*7(%rsp) | ||
116 | 105 | ||
117 | mov _unused_lanes(state), unused_lanes | 106 | mov _unused_lanes(state), unused_lanes |
118 | mov unused_lanes, lane | 107 | mov unused_lanes, lane |
@@ -203,16 +192,9 @@ len_is_0: | |||
203 | movl DWORD_tmp, _result_digest+1*16(job_rax) | 192 | movl DWORD_tmp, _result_digest+1*16(job_rax) |
204 | 193 | ||
205 | return: | 194 | return: |
206 | 195 | pop %r12 | |
207 | mov (%rsp), %rbx | 196 | pop %rbx |
208 | mov 8*2(%rsp), %r10 #save old rsp | 197 | FRAME_END |
209 | mov 8*3(%rsp), %rbp | ||
210 | mov 8*4(%rsp), %r12 | ||
211 | mov 8*5(%rsp), %r13 | ||
212 | mov 8*6(%rsp), %r14 | ||
213 | mov 8*7(%rsp), %r15 | ||
214 | mov %r10, %rsp | ||
215 | |||
216 | ret | 198 | ret |
217 | 199 | ||
218 | return_null: | 200 | return_null: |
diff --git a/arch/x86/crypto/twofish-avx-x86_64-asm_64.S b/arch/x86/crypto/twofish-avx-x86_64-asm_64.S index 05058134c443..dc66273e610d 100644 --- a/arch/x86/crypto/twofish-avx-x86_64-asm_64.S +++ b/arch/x86/crypto/twofish-avx-x86_64-asm_64.S | |||
@@ -24,6 +24,7 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/linkage.h> | 26 | #include <linux/linkage.h> |
27 | #include <asm/frame.h> | ||
27 | #include "glue_helper-asm-avx.S" | 28 | #include "glue_helper-asm-avx.S" |
28 | 29 | ||
29 | .file "twofish-avx-x86_64-asm_64.S" | 30 | .file "twofish-avx-x86_64-asm_64.S" |
@@ -333,6 +334,7 @@ ENTRY(twofish_ecb_enc_8way) | |||
333 | * %rsi: dst | 334 | * %rsi: dst |
334 | * %rdx: src | 335 | * %rdx: src |
335 | */ | 336 | */ |
337 | FRAME_BEGIN | ||
336 | 338 | ||
337 | movq %rsi, %r11; | 339 | movq %rsi, %r11; |
338 | 340 | ||
@@ -342,6 +344,7 @@ ENTRY(twofish_ecb_enc_8way) | |||
342 | 344 | ||
343 | store_8way(%r11, RC1, RD1, RA1, RB1, RC2, RD2, RA2, RB2); | 345 | store_8way(%r11, RC1, RD1, RA1, RB1, RC2, RD2, RA2, RB2); |
344 | 346 | ||
347 | FRAME_END | ||
345 | ret; | 348 | ret; |
346 | ENDPROC(twofish_ecb_enc_8way) | 349 | ENDPROC(twofish_ecb_enc_8way) |
347 | 350 | ||
@@ -351,6 +354,7 @@ ENTRY(twofish_ecb_dec_8way) | |||
351 | * %rsi: dst | 354 | * %rsi: dst |
352 | * %rdx: src | 355 | * %rdx: src |
353 | */ | 356 | */ |
357 | FRAME_BEGIN | ||
354 | 358 | ||
355 | movq %rsi, %r11; | 359 | movq %rsi, %r11; |
356 | 360 | ||
@@ -360,6 +364,7 @@ ENTRY(twofish_ecb_dec_8way) | |||
360 | 364 | ||
361 | store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); | 365 | store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); |
362 | 366 | ||
367 | FRAME_END | ||
363 | ret; | 368 | ret; |
364 | ENDPROC(twofish_ecb_dec_8way) | 369 | ENDPROC(twofish_ecb_dec_8way) |
365 | 370 | ||
@@ -369,6 +374,7 @@ ENTRY(twofish_cbc_dec_8way) | |||
369 | * %rsi: dst | 374 | * %rsi: dst |
370 | * %rdx: src | 375 | * %rdx: src |
371 | */ | 376 | */ |
377 | FRAME_BEGIN | ||
372 | 378 | ||
373 | pushq %r12; | 379 | pushq %r12; |
374 | 380 | ||
@@ -383,6 +389,7 @@ ENTRY(twofish_cbc_dec_8way) | |||
383 | 389 | ||
384 | popq %r12; | 390 | popq %r12; |
385 | 391 | ||
392 | FRAME_END | ||
386 | ret; | 393 | ret; |
387 | ENDPROC(twofish_cbc_dec_8way) | 394 | ENDPROC(twofish_cbc_dec_8way) |
388 | 395 | ||
@@ -393,6 +400,7 @@ ENTRY(twofish_ctr_8way) | |||
393 | * %rdx: src | 400 | * %rdx: src |
394 | * %rcx: iv (little endian, 128bit) | 401 | * %rcx: iv (little endian, 128bit) |
395 | */ | 402 | */ |
403 | FRAME_BEGIN | ||
396 | 404 | ||
397 | pushq %r12; | 405 | pushq %r12; |
398 | 406 | ||
@@ -408,6 +416,7 @@ ENTRY(twofish_ctr_8way) | |||
408 | 416 | ||
409 | popq %r12; | 417 | popq %r12; |
410 | 418 | ||
419 | FRAME_END | ||
411 | ret; | 420 | ret; |
412 | ENDPROC(twofish_ctr_8way) | 421 | ENDPROC(twofish_ctr_8way) |
413 | 422 | ||
@@ -418,6 +427,7 @@ ENTRY(twofish_xts_enc_8way) | |||
418 | * %rdx: src | 427 | * %rdx: src |
419 | * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) | 428 | * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) |
420 | */ | 429 | */ |
430 | FRAME_BEGIN | ||
421 | 431 | ||
422 | movq %rsi, %r11; | 432 | movq %rsi, %r11; |
423 | 433 | ||
@@ -430,6 +440,7 @@ ENTRY(twofish_xts_enc_8way) | |||
430 | /* dst <= regs xor IVs(in dst) */ | 440 | /* dst <= regs xor IVs(in dst) */ |
431 | store_xts_8way(%r11, RC1, RD1, RA1, RB1, RC2, RD2, RA2, RB2); | 441 | store_xts_8way(%r11, RC1, RD1, RA1, RB1, RC2, RD2, RA2, RB2); |
432 | 442 | ||
443 | FRAME_END | ||
433 | ret; | 444 | ret; |
434 | ENDPROC(twofish_xts_enc_8way) | 445 | ENDPROC(twofish_xts_enc_8way) |
435 | 446 | ||
@@ -440,6 +451,7 @@ ENTRY(twofish_xts_dec_8way) | |||
440 | * %rdx: src | 451 | * %rdx: src |
441 | * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) | 452 | * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) |
442 | */ | 453 | */ |
454 | FRAME_BEGIN | ||
443 | 455 | ||
444 | movq %rsi, %r11; | 456 | movq %rsi, %r11; |
445 | 457 | ||
@@ -452,5 +464,6 @@ ENTRY(twofish_xts_dec_8way) | |||
452 | /* dst <= regs xor IVs(in dst) */ | 464 | /* dst <= regs xor IVs(in dst) */ |
453 | store_xts_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); | 465 | store_xts_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); |
454 | 466 | ||
467 | FRAME_END | ||
455 | ret; | 468 | ret; |
456 | ENDPROC(twofish_xts_dec_8way) | 469 | ENDPROC(twofish_xts_dec_8way) |
diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h index e32206e09868..9a9e5884066c 100644 --- a/arch/x86/entry/calling.h +++ b/arch/x86/entry/calling.h | |||
@@ -201,37 +201,6 @@ For 32-bit we have the following conventions - kernel is built with | |||
201 | .byte 0xf1 | 201 | .byte 0xf1 |
202 | .endm | 202 | .endm |
203 | 203 | ||
204 | #else /* CONFIG_X86_64 */ | ||
205 | |||
206 | /* | ||
207 | * For 32bit only simplified versions of SAVE_ALL/RESTORE_ALL. These | ||
208 | * are different from the entry_32.S versions in not changing the segment | ||
209 | * registers. So only suitable for in kernel use, not when transitioning | ||
210 | * from or to user space. The resulting stack frame is not a standard | ||
211 | * pt_regs frame. The main use case is calling C code from assembler | ||
212 | * when all the registers need to be preserved. | ||
213 | */ | ||
214 | |||
215 | .macro SAVE_ALL | ||
216 | pushl %eax | ||
217 | pushl %ebp | ||
218 | pushl %edi | ||
219 | pushl %esi | ||
220 | pushl %edx | ||
221 | pushl %ecx | ||
222 | pushl %ebx | ||
223 | .endm | ||
224 | |||
225 | .macro RESTORE_ALL | ||
226 | popl %ebx | ||
227 | popl %ecx | ||
228 | popl %edx | ||
229 | popl %esi | ||
230 | popl %edi | ||
231 | popl %ebp | ||
232 | popl %eax | ||
233 | .endm | ||
234 | |||
235 | #endif /* CONFIG_X86_64 */ | 204 | #endif /* CONFIG_X86_64 */ |
236 | 205 | ||
237 | /* | 206 | /* |
diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c index 03663740c866..1a000f59f04a 100644 --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <asm/traps.h> | 26 | #include <asm/traps.h> |
27 | #include <asm/vdso.h> | 27 | #include <asm/vdso.h> |
28 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
29 | #include <asm/cpufeature.h> | ||
29 | 30 | ||
30 | #define CREATE_TRACE_POINTS | 31 | #define CREATE_TRACE_POINTS |
31 | #include <trace/events/syscalls.h> | 32 | #include <trace/events/syscalls.h> |
@@ -268,6 +269,7 @@ static void exit_to_usermode_loop(struct pt_regs *regs, u32 cached_flags) | |||
268 | /* Called with IRQs disabled. */ | 269 | /* Called with IRQs disabled. */ |
269 | __visible inline void prepare_exit_to_usermode(struct pt_regs *regs) | 270 | __visible inline void prepare_exit_to_usermode(struct pt_regs *regs) |
270 | { | 271 | { |
272 | struct thread_info *ti = pt_regs_to_thread_info(regs); | ||
271 | u32 cached_flags; | 273 | u32 cached_flags; |
272 | 274 | ||
273 | if (IS_ENABLED(CONFIG_PROVE_LOCKING) && WARN_ON(!irqs_disabled())) | 275 | if (IS_ENABLED(CONFIG_PROVE_LOCKING) && WARN_ON(!irqs_disabled())) |
@@ -275,12 +277,22 @@ __visible inline void prepare_exit_to_usermode(struct pt_regs *regs) | |||
275 | 277 | ||
276 | lockdep_sys_exit(); | 278 | lockdep_sys_exit(); |
277 | 279 | ||
278 | cached_flags = | 280 | cached_flags = READ_ONCE(ti->flags); |
279 | READ_ONCE(pt_regs_to_thread_info(regs)->flags); | ||
280 | 281 | ||
281 | if (unlikely(cached_flags & EXIT_TO_USERMODE_LOOP_FLAGS)) | 282 | if (unlikely(cached_flags & EXIT_TO_USERMODE_LOOP_FLAGS)) |
282 | exit_to_usermode_loop(regs, cached_flags); | 283 | exit_to_usermode_loop(regs, cached_flags); |
283 | 284 | ||
285 | #ifdef CONFIG_COMPAT | ||
286 | /* | ||
287 | * Compat syscalls set TS_COMPAT. Make sure we clear it before | ||
288 | * returning to user mode. We need to clear it *after* signal | ||
289 | * handling, because syscall restart has a fixup for compat | ||
290 | * syscalls. The fixup is exercised by the ptrace_syscall_32 | ||
291 | * selftest. | ||
292 | */ | ||
293 | ti->status &= ~TS_COMPAT; | ||
294 | #endif | ||
295 | |||
284 | user_enter(); | 296 | user_enter(); |
285 | } | 297 | } |
286 | 298 | ||
@@ -332,17 +344,35 @@ __visible inline void syscall_return_slowpath(struct pt_regs *regs) | |||
332 | if (unlikely(cached_flags & SYSCALL_EXIT_WORK_FLAGS)) | 344 | if (unlikely(cached_flags & SYSCALL_EXIT_WORK_FLAGS)) |
333 | syscall_slow_exit_work(regs, cached_flags); | 345 | syscall_slow_exit_work(regs, cached_flags); |
334 | 346 | ||
335 | #ifdef CONFIG_COMPAT | 347 | local_irq_disable(); |
348 | prepare_exit_to_usermode(regs); | ||
349 | } | ||
350 | |||
351 | #ifdef CONFIG_X86_64 | ||
352 | __visible void do_syscall_64(struct pt_regs *regs) | ||
353 | { | ||
354 | struct thread_info *ti = pt_regs_to_thread_info(regs); | ||
355 | unsigned long nr = regs->orig_ax; | ||
356 | |||
357 | local_irq_enable(); | ||
358 | |||
359 | if (READ_ONCE(ti->flags) & _TIF_WORK_SYSCALL_ENTRY) | ||
360 | nr = syscall_trace_enter(regs); | ||
361 | |||
336 | /* | 362 | /* |
337 | * Compat syscalls set TS_COMPAT. Make sure we clear it before | 363 | * NB: Native and x32 syscalls are dispatched from the same |
338 | * returning to user mode. | 364 | * table. The only functional difference is the x32 bit in |
365 | * regs->orig_ax, which changes the behavior of some syscalls. | ||
339 | */ | 366 | */ |
340 | ti->status &= ~TS_COMPAT; | 367 | if (likely((nr & __SYSCALL_MASK) < NR_syscalls)) { |
341 | #endif | 368 | regs->ax = sys_call_table[nr & __SYSCALL_MASK]( |
369 | regs->di, regs->si, regs->dx, | ||
370 | regs->r10, regs->r8, regs->r9); | ||
371 | } | ||
342 | 372 | ||
343 | local_irq_disable(); | 373 | syscall_return_slowpath(regs); |
344 | prepare_exit_to_usermode(regs); | ||
345 | } | 374 | } |
375 | #endif | ||
346 | 376 | ||
347 | #if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION) | 377 | #if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION) |
348 | /* | 378 | /* |
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S index 77d8c5112900..4c5228352744 100644 --- a/arch/x86/entry/entry_32.S +++ b/arch/x86/entry/entry_32.S | |||
@@ -40,7 +40,7 @@ | |||
40 | #include <asm/processor-flags.h> | 40 | #include <asm/processor-flags.h> |
41 | #include <asm/ftrace.h> | 41 | #include <asm/ftrace.h> |
42 | #include <asm/irq_vectors.h> | 42 | #include <asm/irq_vectors.h> |
43 | #include <asm/cpufeature.h> | 43 | #include <asm/cpufeatures.h> |
44 | #include <asm/alternative-asm.h> | 44 | #include <asm/alternative-asm.h> |
45 | #include <asm/asm.h> | 45 | #include <asm/asm.h> |
46 | #include <asm/smap.h> | 46 | #include <asm/smap.h> |
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 9d34d3cfceb6..70eadb0ea5fa 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S | |||
@@ -145,17 +145,11 @@ GLOBAL(entry_SYSCALL_64_after_swapgs) | |||
145 | movq %rsp, PER_CPU_VAR(rsp_scratch) | 145 | movq %rsp, PER_CPU_VAR(rsp_scratch) |
146 | movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp | 146 | movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp |
147 | 147 | ||
148 | TRACE_IRQS_OFF | ||
149 | |||
148 | /* Construct struct pt_regs on stack */ | 150 | /* Construct struct pt_regs on stack */ |
149 | pushq $__USER_DS /* pt_regs->ss */ | 151 | pushq $__USER_DS /* pt_regs->ss */ |
150 | pushq PER_CPU_VAR(rsp_scratch) /* pt_regs->sp */ | 152 | pushq PER_CPU_VAR(rsp_scratch) /* pt_regs->sp */ |
151 | /* | ||
152 | * Re-enable interrupts. | ||
153 | * We use 'rsp_scratch' as a scratch space, hence irq-off block above | ||
154 | * must execute atomically in the face of possible interrupt-driven | ||
155 | * task preemption. We must enable interrupts only after we're done | ||
156 | * with using rsp_scratch: | ||
157 | */ | ||
158 | ENABLE_INTERRUPTS(CLBR_NONE) | ||
159 | pushq %r11 /* pt_regs->flags */ | 153 | pushq %r11 /* pt_regs->flags */ |
160 | pushq $__USER_CS /* pt_regs->cs */ | 154 | pushq $__USER_CS /* pt_regs->cs */ |
161 | pushq %rcx /* pt_regs->ip */ | 155 | pushq %rcx /* pt_regs->ip */ |
@@ -171,9 +165,21 @@ GLOBAL(entry_SYSCALL_64_after_swapgs) | |||
171 | pushq %r11 /* pt_regs->r11 */ | 165 | pushq %r11 /* pt_regs->r11 */ |
172 | sub $(6*8), %rsp /* pt_regs->bp, bx, r12-15 not saved */ | 166 | sub $(6*8), %rsp /* pt_regs->bp, bx, r12-15 not saved */ |
173 | 167 | ||
174 | testl $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS) | 168 | /* |
175 | jnz tracesys | 169 | * If we need to do entry work or if we guess we'll need to do |
170 | * exit work, go straight to the slow path. | ||
171 | */ | ||
172 | testl $_TIF_WORK_SYSCALL_ENTRY|_TIF_ALLWORK_MASK, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS) | ||
173 | jnz entry_SYSCALL64_slow_path | ||
174 | |||
176 | entry_SYSCALL_64_fastpath: | 175 | entry_SYSCALL_64_fastpath: |
176 | /* | ||
177 | * Easy case: enable interrupts and issue the syscall. If the syscall | ||
178 | * needs pt_regs, we'll call a stub that disables interrupts again | ||
179 | * and jumps to the slow path. | ||
180 | */ | ||
181 | TRACE_IRQS_ON | ||
182 | ENABLE_INTERRUPTS(CLBR_NONE) | ||
177 | #if __SYSCALL_MASK == ~0 | 183 | #if __SYSCALL_MASK == ~0 |
178 | cmpq $__NR_syscall_max, %rax | 184 | cmpq $__NR_syscall_max, %rax |
179 | #else | 185 | #else |
@@ -182,103 +188,56 @@ entry_SYSCALL_64_fastpath: | |||
182 | #endif | 188 | #endif |
183 | ja 1f /* return -ENOSYS (already in pt_regs->ax) */ | 189 | ja 1f /* return -ENOSYS (already in pt_regs->ax) */ |
184 | movq %r10, %rcx | 190 | movq %r10, %rcx |
191 | |||
192 | /* | ||
193 | * This call instruction is handled specially in stub_ptregs_64. | ||
194 | * It might end up jumping to the slow path. If it jumps, RAX | ||
195 | * and all argument registers are clobbered. | ||
196 | */ | ||
185 | call *sys_call_table(, %rax, 8) | 197 | call *sys_call_table(, %rax, 8) |
198 | .Lentry_SYSCALL_64_after_fastpath_call: | ||
199 | |||
186 | movq %rax, RAX(%rsp) | 200 | movq %rax, RAX(%rsp) |
187 | 1: | 201 | 1: |
188 | /* | ||
189 | * Syscall return path ending with SYSRET (fast path). | ||
190 | * Has incompletely filled pt_regs. | ||
191 | */ | ||
192 | LOCKDEP_SYS_EXIT | ||
193 | /* | ||
194 | * We do not frame this tiny irq-off block with TRACE_IRQS_OFF/ON, | ||
195 | * it is too small to ever cause noticeable irq latency. | ||
196 | */ | ||
197 | DISABLE_INTERRUPTS(CLBR_NONE) | ||
198 | 202 | ||
199 | /* | 203 | /* |
200 | * We must check ti flags with interrupts (or at least preemption) | 204 | * If we get here, then we know that pt_regs is clean for SYSRET64. |
201 | * off because we must *never* return to userspace without | 205 | * If we see that no exit work is required (which we are required |
202 | * processing exit work that is enqueued if we're preempted here. | 206 | * to check with IRQs off), then we can go straight to SYSRET64. |
203 | * In particular, returning to userspace with any of the one-shot | ||
204 | * flags (TIF_NOTIFY_RESUME, TIF_USER_RETURN_NOTIFY, etc) set is | ||
205 | * very bad. | ||
206 | */ | 207 | */ |
208 | DISABLE_INTERRUPTS(CLBR_NONE) | ||
209 | TRACE_IRQS_OFF | ||
207 | testl $_TIF_ALLWORK_MASK, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS) | 210 | testl $_TIF_ALLWORK_MASK, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS) |
208 | jnz int_ret_from_sys_call_irqs_off /* Go to the slow path */ | 211 | jnz 1f |
209 | 212 | ||
210 | RESTORE_C_REGS_EXCEPT_RCX_R11 | 213 | LOCKDEP_SYS_EXIT |
214 | TRACE_IRQS_ON /* user mode is traced as IRQs on */ | ||
211 | movq RIP(%rsp), %rcx | 215 | movq RIP(%rsp), %rcx |
212 | movq EFLAGS(%rsp), %r11 | 216 | movq EFLAGS(%rsp), %r11 |
217 | RESTORE_C_REGS_EXCEPT_RCX_R11 | ||
213 | movq RSP(%rsp), %rsp | 218 | movq RSP(%rsp), %rsp |
214 | /* | ||
215 | * 64-bit SYSRET restores rip from rcx, | ||
216 | * rflags from r11 (but RF and VM bits are forced to 0), | ||
217 | * cs and ss are loaded from MSRs. | ||
218 | * Restoration of rflags re-enables interrupts. | ||
219 | * | ||
220 | * NB: On AMD CPUs with the X86_BUG_SYSRET_SS_ATTRS bug, the ss | ||
221 | * descriptor is not reinitialized. This means that we should | ||
222 | * avoid SYSRET with SS == NULL, which could happen if we schedule, | ||
223 | * exit the kernel, and re-enter using an interrupt vector. (All | ||
224 | * interrupt entries on x86_64 set SS to NULL.) We prevent that | ||
225 | * from happening by reloading SS in __switch_to. (Actually | ||
226 | * detecting the failure in 64-bit userspace is tricky but can be | ||
227 | * done.) | ||
228 | */ | ||
229 | USERGS_SYSRET64 | 219 | USERGS_SYSRET64 |
230 | 220 | ||
231 | GLOBAL(int_ret_from_sys_call_irqs_off) | 221 | 1: |
222 | /* | ||
223 | * The fast path looked good when we started, but something changed | ||
224 | * along the way and we need to switch to the slow path. Calling | ||
225 | * raise(3) will trigger this, for example. IRQs are off. | ||
226 | */ | ||
232 | TRACE_IRQS_ON | 227 | TRACE_IRQS_ON |
233 | ENABLE_INTERRUPTS(CLBR_NONE) | 228 | ENABLE_INTERRUPTS(CLBR_NONE) |
234 | jmp int_ret_from_sys_call | ||
235 | |||
236 | /* Do syscall entry tracing */ | ||
237 | tracesys: | ||
238 | movq %rsp, %rdi | ||
239 | movl $AUDIT_ARCH_X86_64, %esi | ||
240 | call syscall_trace_enter_phase1 | ||
241 | test %rax, %rax | ||
242 | jnz tracesys_phase2 /* if needed, run the slow path */ | ||
243 | RESTORE_C_REGS_EXCEPT_RAX /* else restore clobbered regs */ | ||
244 | movq ORIG_RAX(%rsp), %rax | ||
245 | jmp entry_SYSCALL_64_fastpath /* and return to the fast path */ | ||
246 | |||
247 | tracesys_phase2: | ||
248 | SAVE_EXTRA_REGS | 229 | SAVE_EXTRA_REGS |
249 | movq %rsp, %rdi | 230 | movq %rsp, %rdi |
250 | movl $AUDIT_ARCH_X86_64, %esi | 231 | call syscall_return_slowpath /* returns with IRQs disabled */ |
251 | movq %rax, %rdx | 232 | jmp return_from_SYSCALL_64 |
252 | call syscall_trace_enter_phase2 | ||
253 | |||
254 | /* | ||
255 | * Reload registers from stack in case ptrace changed them. | ||
256 | * We don't reload %rax because syscall_trace_entry_phase2() returned | ||
257 | * the value it wants us to use in the table lookup. | ||
258 | */ | ||
259 | RESTORE_C_REGS_EXCEPT_RAX | ||
260 | RESTORE_EXTRA_REGS | ||
261 | #if __SYSCALL_MASK == ~0 | ||
262 | cmpq $__NR_syscall_max, %rax | ||
263 | #else | ||
264 | andl $__SYSCALL_MASK, %eax | ||
265 | cmpl $__NR_syscall_max, %eax | ||
266 | #endif | ||
267 | ja 1f /* return -ENOSYS (already in pt_regs->ax) */ | ||
268 | movq %r10, %rcx /* fixup for C */ | ||
269 | call *sys_call_table(, %rax, 8) | ||
270 | movq %rax, RAX(%rsp) | ||
271 | 1: | ||
272 | /* Use IRET because user could have changed pt_regs->foo */ | ||
273 | 233 | ||
274 | /* | 234 | entry_SYSCALL64_slow_path: |
275 | * Syscall return path ending with IRET. | 235 | /* IRQs are off. */ |
276 | * Has correct iret frame. | ||
277 | */ | ||
278 | GLOBAL(int_ret_from_sys_call) | ||
279 | SAVE_EXTRA_REGS | 236 | SAVE_EXTRA_REGS |
280 | movq %rsp, %rdi | 237 | movq %rsp, %rdi |
281 | call syscall_return_slowpath /* returns with IRQs disabled */ | 238 | call do_syscall_64 /* returns with IRQs disabled */ |
239 | |||
240 | return_from_SYSCALL_64: | ||
282 | RESTORE_EXTRA_REGS | 241 | RESTORE_EXTRA_REGS |
283 | TRACE_IRQS_IRETQ /* we're about to change IF */ | 242 | TRACE_IRQS_IRETQ /* we're about to change IF */ |
284 | 243 | ||
@@ -355,83 +314,45 @@ opportunistic_sysret_failed: | |||
355 | jmp restore_c_regs_and_iret | 314 | jmp restore_c_regs_and_iret |
356 | END(entry_SYSCALL_64) | 315 | END(entry_SYSCALL_64) |
357 | 316 | ||
317 | ENTRY(stub_ptregs_64) | ||
318 | /* | ||
319 | * Syscalls marked as needing ptregs land here. | ||
320 | * If we are on the fast path, we need to save the extra regs, | ||
321 | * which we achieve by trying again on the slow path. If we are on | ||
322 | * the slow path, the extra regs are already saved. | ||
323 | * | ||
324 | * RAX stores a pointer to the C function implementing the syscall. | ||
325 | * IRQs are on. | ||
326 | */ | ||
327 | cmpq $.Lentry_SYSCALL_64_after_fastpath_call, (%rsp) | ||
328 | jne 1f | ||
358 | 329 | ||
359 | .macro FORK_LIKE func | ||
360 | ENTRY(stub_\func) | ||
361 | SAVE_EXTRA_REGS 8 | ||
362 | jmp sys_\func | ||
363 | END(stub_\func) | ||
364 | .endm | ||
365 | |||
366 | FORK_LIKE clone | ||
367 | FORK_LIKE fork | ||
368 | FORK_LIKE vfork | ||
369 | |||
370 | ENTRY(stub_execve) | ||
371 | call sys_execve | ||
372 | return_from_execve: | ||
373 | testl %eax, %eax | ||
374 | jz 1f | ||
375 | /* exec failed, can use fast SYSRET code path in this case */ | ||
376 | ret | ||
377 | 1: | ||
378 | /* must use IRET code path (pt_regs->cs may have changed) */ | ||
379 | addq $8, %rsp | ||
380 | ZERO_EXTRA_REGS | ||
381 | movq %rax, RAX(%rsp) | ||
382 | jmp int_ret_from_sys_call | ||
383 | END(stub_execve) | ||
384 | /* | ||
385 | * Remaining execve stubs are only 7 bytes long. | ||
386 | * ENTRY() often aligns to 16 bytes, which in this case has no benefits. | ||
387 | */ | ||
388 | .align 8 | ||
389 | GLOBAL(stub_execveat) | ||
390 | call sys_execveat | ||
391 | jmp return_from_execve | ||
392 | END(stub_execveat) | ||
393 | |||
394 | #if defined(CONFIG_X86_X32_ABI) | ||
395 | .align 8 | ||
396 | GLOBAL(stub_x32_execve) | ||
397 | call compat_sys_execve | ||
398 | jmp return_from_execve | ||
399 | END(stub_x32_execve) | ||
400 | .align 8 | ||
401 | GLOBAL(stub_x32_execveat) | ||
402 | call compat_sys_execveat | ||
403 | jmp return_from_execve | ||
404 | END(stub_x32_execveat) | ||
405 | #endif | ||
406 | |||
407 | /* | ||
408 | * sigreturn is special because it needs to restore all registers on return. | ||
409 | * This cannot be done with SYSRET, so use the IRET return path instead. | ||
410 | */ | ||
411 | ENTRY(stub_rt_sigreturn) | ||
412 | /* | 330 | /* |
413 | * SAVE_EXTRA_REGS result is not normally needed: | 331 | * Called from fast path -- disable IRQs again, pop return address |
414 | * sigreturn overwrites all pt_regs->GPREGS. | 332 | * and jump to slow path |
415 | * But sigreturn can fail (!), and there is no easy way to detect that. | ||
416 | * To make sure RESTORE_EXTRA_REGS doesn't restore garbage on error, | ||
417 | * we SAVE_EXTRA_REGS here. | ||
418 | */ | 333 | */ |
419 | SAVE_EXTRA_REGS 8 | 334 | DISABLE_INTERRUPTS(CLBR_NONE) |
420 | call sys_rt_sigreturn | 335 | TRACE_IRQS_OFF |
421 | return_from_stub: | 336 | popq %rax |
422 | addq $8, %rsp | 337 | jmp entry_SYSCALL64_slow_path |
423 | RESTORE_EXTRA_REGS | ||
424 | movq %rax, RAX(%rsp) | ||
425 | jmp int_ret_from_sys_call | ||
426 | END(stub_rt_sigreturn) | ||
427 | 338 | ||
428 | #ifdef CONFIG_X86_X32_ABI | 339 | 1: |
429 | ENTRY(stub_x32_rt_sigreturn) | 340 | /* Called from C */ |
430 | SAVE_EXTRA_REGS 8 | 341 | jmp *%rax /* called from C */ |
431 | call sys32_x32_rt_sigreturn | 342 | END(stub_ptregs_64) |
432 | jmp return_from_stub | 343 | |
433 | END(stub_x32_rt_sigreturn) | 344 | .macro ptregs_stub func |
434 | #endif | 345 | ENTRY(ptregs_\func) |
346 | leaq \func(%rip), %rax | ||
347 | jmp stub_ptregs_64 | ||
348 | END(ptregs_\func) | ||
349 | .endm | ||
350 | |||
351 | /* Instantiate ptregs_stub for each ptregs-using syscall */ | ||
352 | #define __SYSCALL_64_QUAL_(sym) | ||
353 | #define __SYSCALL_64_QUAL_ptregs(sym) ptregs_stub sym | ||
354 | #define __SYSCALL_64(nr, sym, qual) __SYSCALL_64_QUAL_##qual(sym) | ||
355 | #include <asm/syscalls_64.h> | ||
435 | 356 | ||
436 | /* | 357 | /* |
437 | * A newly forked process directly context switches into this address. | 358 | * A newly forked process directly context switches into this address. |
@@ -439,7 +360,6 @@ END(stub_x32_rt_sigreturn) | |||
439 | * rdi: prev task we switched from | 360 | * rdi: prev task we switched from |
440 | */ | 361 | */ |
441 | ENTRY(ret_from_fork) | 362 | ENTRY(ret_from_fork) |
442 | |||
443 | LOCK ; btr $TIF_FORK, TI_flags(%r8) | 363 | LOCK ; btr $TIF_FORK, TI_flags(%r8) |
444 | 364 | ||
445 | pushq $0x0002 | 365 | pushq $0x0002 |
@@ -447,28 +367,32 @@ ENTRY(ret_from_fork) | |||
447 | 367 | ||
448 | call schedule_tail /* rdi: 'prev' task parameter */ | 368 | call schedule_tail /* rdi: 'prev' task parameter */ |
449 | 369 | ||
450 | RESTORE_EXTRA_REGS | ||
451 | |||
452 | testb $3, CS(%rsp) /* from kernel_thread? */ | 370 | testb $3, CS(%rsp) /* from kernel_thread? */ |
371 | jnz 1f | ||
453 | 372 | ||
454 | /* | 373 | /* |
455 | * By the time we get here, we have no idea whether our pt_regs, | 374 | * We came from kernel_thread. This code path is quite twisted, and |
456 | * ti flags, and ti status came from the 64-bit SYSCALL fast path, | 375 | * someone should clean it up. |
457 | * the slow path, or one of the 32-bit compat paths. | 376 | * |
458 | * Use IRET code path to return, since it can safely handle | 377 | * copy_thread_tls stashes the function pointer in RBX and the |
459 | * all of the above. | 378 | * parameter to be passed in RBP. The called function is permitted |
379 | * to call do_execve and thereby jump to user mode. | ||
460 | */ | 380 | */ |
461 | jnz int_ret_from_sys_call | 381 | movq RBP(%rsp), %rdi |
382 | call *RBX(%rsp) | ||
383 | movl $0, RAX(%rsp) | ||
462 | 384 | ||
463 | /* | 385 | /* |
464 | * We came from kernel_thread | 386 | * Fall through as though we're exiting a syscall. This makes a |
465 | * nb: we depend on RESTORE_EXTRA_REGS above | 387 | * twisted sort of sense if we just called do_execve. |
466 | */ | 388 | */ |
467 | movq %rbp, %rdi | 389 | |
468 | call *%rbx | 390 | 1: |
469 | movl $0, RAX(%rsp) | 391 | movq %rsp, %rdi |
470 | RESTORE_EXTRA_REGS | 392 | call syscall_return_slowpath /* returns with IRQs disabled */ |
471 | jmp int_ret_from_sys_call | 393 | TRACE_IRQS_ON /* user mode is traced as IRQS on */ |
394 | SWAPGS | ||
395 | jmp restore_regs_and_iret | ||
472 | END(ret_from_fork) | 396 | END(ret_from_fork) |
473 | 397 | ||
474 | /* | 398 | /* |
diff --git a/arch/x86/entry/syscall_32.c b/arch/x86/entry/syscall_32.c index 9a6649857106..8f895ee13a1c 100644 --- a/arch/x86/entry/syscall_32.c +++ b/arch/x86/entry/syscall_32.c | |||
@@ -6,17 +6,11 @@ | |||
6 | #include <asm/asm-offsets.h> | 6 | #include <asm/asm-offsets.h> |
7 | #include <asm/syscall.h> | 7 | #include <asm/syscall.h> |
8 | 8 | ||
9 | #ifdef CONFIG_IA32_EMULATION | 9 | #define __SYSCALL_I386(nr, sym, qual) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ; |
10 | #define SYM(sym, compat) compat | ||
11 | #else | ||
12 | #define SYM(sym, compat) sym | ||
13 | #endif | ||
14 | |||
15 | #define __SYSCALL_I386(nr, sym, compat) extern asmlinkage long SYM(sym, compat)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ; | ||
16 | #include <asm/syscalls_32.h> | 10 | #include <asm/syscalls_32.h> |
17 | #undef __SYSCALL_I386 | 11 | #undef __SYSCALL_I386 |
18 | 12 | ||
19 | #define __SYSCALL_I386(nr, sym, compat) [nr] = SYM(sym, compat), | 13 | #define __SYSCALL_I386(nr, sym, qual) [nr] = sym, |
20 | 14 | ||
21 | extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); | 15 | extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); |
22 | 16 | ||
diff --git a/arch/x86/entry/syscall_64.c b/arch/x86/entry/syscall_64.c index 41283d22be7a..9dbc5abb6162 100644 --- a/arch/x86/entry/syscall_64.c +++ b/arch/x86/entry/syscall_64.c | |||
@@ -6,19 +6,14 @@ | |||
6 | #include <asm/asm-offsets.h> | 6 | #include <asm/asm-offsets.h> |
7 | #include <asm/syscall.h> | 7 | #include <asm/syscall.h> |
8 | 8 | ||
9 | #define __SYSCALL_COMMON(nr, sym, compat) __SYSCALL_64(nr, sym, compat) | 9 | #define __SYSCALL_64_QUAL_(sym) sym |
10 | #define __SYSCALL_64_QUAL_ptregs(sym) ptregs_##sym | ||
10 | 11 | ||
11 | #ifdef CONFIG_X86_X32_ABI | 12 | #define __SYSCALL_64(nr, sym, qual) extern asmlinkage long __SYSCALL_64_QUAL_##qual(sym)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); |
12 | # define __SYSCALL_X32(nr, sym, compat) __SYSCALL_64(nr, sym, compat) | ||
13 | #else | ||
14 | # define __SYSCALL_X32(nr, sym, compat) /* nothing */ | ||
15 | #endif | ||
16 | |||
17 | #define __SYSCALL_64(nr, sym, compat) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ; | ||
18 | #include <asm/syscalls_64.h> | 13 | #include <asm/syscalls_64.h> |
19 | #undef __SYSCALL_64 | 14 | #undef __SYSCALL_64 |
20 | 15 | ||
21 | #define __SYSCALL_64(nr, sym, compat) [nr] = sym, | 16 | #define __SYSCALL_64(nr, sym, qual) [nr] = __SYSCALL_64_QUAL_##qual(sym), |
22 | 17 | ||
23 | extern long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); | 18 | extern long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); |
24 | 19 | ||
diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl index dc1040a50bdc..2e5b565adacc 100644 --- a/arch/x86/entry/syscalls/syscall_64.tbl +++ b/arch/x86/entry/syscalls/syscall_64.tbl | |||
@@ -21,7 +21,7 @@ | |||
21 | 12 common brk sys_brk | 21 | 12 common brk sys_brk |
22 | 13 64 rt_sigaction sys_rt_sigaction | 22 | 13 64 rt_sigaction sys_rt_sigaction |
23 | 14 common rt_sigprocmask sys_rt_sigprocmask | 23 | 14 common rt_sigprocmask sys_rt_sigprocmask |
24 | 15 64 rt_sigreturn stub_rt_sigreturn | 24 | 15 64 rt_sigreturn sys_rt_sigreturn/ptregs |
25 | 16 64 ioctl sys_ioctl | 25 | 16 64 ioctl sys_ioctl |
26 | 17 common pread64 sys_pread64 | 26 | 17 common pread64 sys_pread64 |
27 | 18 common pwrite64 sys_pwrite64 | 27 | 18 common pwrite64 sys_pwrite64 |
@@ -62,10 +62,10 @@ | |||
62 | 53 common socketpair sys_socketpair | 62 | 53 common socketpair sys_socketpair |
63 | 54 64 setsockopt sys_setsockopt | 63 | 54 64 setsockopt sys_setsockopt |
64 | 55 64 getsockopt sys_getsockopt | 64 | 55 64 getsockopt sys_getsockopt |
65 | 56 common clone stub_clone | 65 | 56 common clone sys_clone/ptregs |
66 | 57 common fork stub_fork | 66 | 57 common fork sys_fork/ptregs |
67 | 58 common vfork stub_vfork | 67 | 58 common vfork sys_vfork/ptregs |
68 | 59 64 execve stub_execve | 68 | 59 64 execve sys_execve/ptregs |
69 | 60 common exit sys_exit | 69 | 60 common exit sys_exit |
70 | 61 common wait4 sys_wait4 | 70 | 61 common wait4 sys_wait4 |
71 | 62 common kill sys_kill | 71 | 62 common kill sys_kill |
@@ -178,7 +178,7 @@ | |||
178 | 169 common reboot sys_reboot | 178 | 169 common reboot sys_reboot |
179 | 170 common sethostname sys_sethostname | 179 | 170 common sethostname sys_sethostname |
180 | 171 common setdomainname sys_setdomainname | 180 | 171 common setdomainname sys_setdomainname |
181 | 172 common iopl sys_iopl | 181 | 172 common iopl sys_iopl/ptregs |
182 | 173 common ioperm sys_ioperm | 182 | 173 common ioperm sys_ioperm |
183 | 174 64 create_module | 183 | 174 64 create_module |
184 | 175 common init_module sys_init_module | 184 | 175 common init_module sys_init_module |
@@ -328,7 +328,7 @@ | |||
328 | 319 common memfd_create sys_memfd_create | 328 | 319 common memfd_create sys_memfd_create |
329 | 320 common kexec_file_load sys_kexec_file_load | 329 | 320 common kexec_file_load sys_kexec_file_load |
330 | 321 common bpf sys_bpf | 330 | 321 common bpf sys_bpf |
331 | 322 64 execveat stub_execveat | 331 | 322 64 execveat sys_execveat/ptregs |
332 | 323 common userfaultfd sys_userfaultfd | 332 | 323 common userfaultfd sys_userfaultfd |
333 | 324 common membarrier sys_membarrier | 333 | 324 common membarrier sys_membarrier |
334 | 325 common mlock2 sys_mlock2 | 334 | 325 common mlock2 sys_mlock2 |
@@ -339,14 +339,14 @@ | |||
339 | # for native 64-bit operation. | 339 | # for native 64-bit operation. |
340 | # | 340 | # |
341 | 512 x32 rt_sigaction compat_sys_rt_sigaction | 341 | 512 x32 rt_sigaction compat_sys_rt_sigaction |
342 | 513 x32 rt_sigreturn stub_x32_rt_sigreturn | 342 | 513 x32 rt_sigreturn sys32_x32_rt_sigreturn |
343 | 514 x32 ioctl compat_sys_ioctl | 343 | 514 x32 ioctl compat_sys_ioctl |
344 | 515 x32 readv compat_sys_readv | 344 | 515 x32 readv compat_sys_readv |
345 | 516 x32 writev compat_sys_writev | 345 | 516 x32 writev compat_sys_writev |
346 | 517 x32 recvfrom compat_sys_recvfrom | 346 | 517 x32 recvfrom compat_sys_recvfrom |
347 | 518 x32 sendmsg compat_sys_sendmsg | 347 | 518 x32 sendmsg compat_sys_sendmsg |
348 | 519 x32 recvmsg compat_sys_recvmsg | 348 | 519 x32 recvmsg compat_sys_recvmsg |
349 | 520 x32 execve stub_x32_execve | 349 | 520 x32 execve compat_sys_execve/ptregs |
350 | 521 x32 ptrace compat_sys_ptrace | 350 | 521 x32 ptrace compat_sys_ptrace |
351 | 522 x32 rt_sigpending compat_sys_rt_sigpending | 351 | 522 x32 rt_sigpending compat_sys_rt_sigpending |
352 | 523 x32 rt_sigtimedwait compat_sys_rt_sigtimedwait | 352 | 523 x32 rt_sigtimedwait compat_sys_rt_sigtimedwait |
@@ -371,4 +371,4 @@ | |||
371 | 542 x32 getsockopt compat_sys_getsockopt | 371 | 542 x32 getsockopt compat_sys_getsockopt |
372 | 543 x32 io_setup compat_sys_io_setup | 372 | 543 x32 io_setup compat_sys_io_setup |
373 | 544 x32 io_submit compat_sys_io_submit | 373 | 544 x32 io_submit compat_sys_io_submit |
374 | 545 x32 execveat stub_x32_execveat | 374 | 545 x32 execveat compat_sys_execveat/ptregs |
diff --git a/arch/x86/entry/syscalls/syscalltbl.sh b/arch/x86/entry/syscalls/syscalltbl.sh index 0e7f8ec071e7..cd3d3015d7df 100644 --- a/arch/x86/entry/syscalls/syscalltbl.sh +++ b/arch/x86/entry/syscalls/syscalltbl.sh | |||
@@ -3,13 +3,63 @@ | |||
3 | in="$1" | 3 | in="$1" |
4 | out="$2" | 4 | out="$2" |
5 | 5 | ||
6 | syscall_macro() { | ||
7 | abi="$1" | ||
8 | nr="$2" | ||
9 | entry="$3" | ||
10 | |||
11 | # Entry can be either just a function name or "function/qualifier" | ||
12 | real_entry="${entry%%/*}" | ||
13 | qualifier="${entry:${#real_entry}}" # Strip the function name | ||
14 | qualifier="${qualifier:1}" # Strip the slash, if any | ||
15 | |||
16 | echo "__SYSCALL_${abi}($nr, $real_entry, $qualifier)" | ||
17 | } | ||
18 | |||
19 | emit() { | ||
20 | abi="$1" | ||
21 | nr="$2" | ||
22 | entry="$3" | ||
23 | compat="$4" | ||
24 | |||
25 | if [ "$abi" == "64" -a -n "$compat" ]; then | ||
26 | echo "a compat entry for a 64-bit syscall makes no sense" >&2 | ||
27 | exit 1 | ||
28 | fi | ||
29 | |||
30 | if [ -z "$compat" ]; then | ||
31 | if [ -n "$entry" ]; then | ||
32 | syscall_macro "$abi" "$nr" "$entry" | ||
33 | fi | ||
34 | else | ||
35 | echo "#ifdef CONFIG_X86_32" | ||
36 | if [ -n "$entry" ]; then | ||
37 | syscall_macro "$abi" "$nr" "$entry" | ||
38 | fi | ||
39 | echo "#else" | ||
40 | syscall_macro "$abi" "$nr" "$compat" | ||
41 | echo "#endif" | ||
42 | fi | ||
43 | } | ||
44 | |||
6 | grep '^[0-9]' "$in" | sort -n | ( | 45 | grep '^[0-9]' "$in" | sort -n | ( |
7 | while read nr abi name entry compat; do | 46 | while read nr abi name entry compat; do |
8 | abi=`echo "$abi" | tr '[a-z]' '[A-Z]'` | 47 | abi=`echo "$abi" | tr '[a-z]' '[A-Z]'` |
9 | if [ -n "$compat" ]; then | 48 | if [ "$abi" == "COMMON" -o "$abi" == "64" ]; then |
10 | echo "__SYSCALL_${abi}($nr, $entry, $compat)" | 49 | # COMMON is the same as 64, except that we don't expect X32 |
11 | elif [ -n "$entry" ]; then | 50 | # programs to use it. Our expectation has nothing to do with |
12 | echo "__SYSCALL_${abi}($nr, $entry, $entry)" | 51 | # any generated code, so treat them the same. |
52 | emit 64 "$nr" "$entry" "$compat" | ||
53 | elif [ "$abi" == "X32" ]; then | ||
54 | # X32 is equivalent to 64 on an X32-compatible kernel. | ||
55 | echo "#ifdef CONFIG_X86_X32_ABI" | ||
56 | emit 64 "$nr" "$entry" "$compat" | ||
57 | echo "#endif" | ||
58 | elif [ "$abi" == "I386" ]; then | ||
59 | emit "$abi" "$nr" "$entry" "$compat" | ||
60 | else | ||
61 | echo "Unknown abi $abi" >&2 | ||
62 | exit 1 | ||
13 | fi | 63 | fi |
14 | done | 64 | done |
15 | ) > "$out" | 65 | ) > "$out" |
diff --git a/arch/x86/entry/thunk_64.S b/arch/x86/entry/thunk_64.S index efb2b932b748..98df1fa8825c 100644 --- a/arch/x86/entry/thunk_64.S +++ b/arch/x86/entry/thunk_64.S | |||
@@ -8,11 +8,14 @@ | |||
8 | #include <linux/linkage.h> | 8 | #include <linux/linkage.h> |
9 | #include "calling.h" | 9 | #include "calling.h" |
10 | #include <asm/asm.h> | 10 | #include <asm/asm.h> |
11 | #include <asm/frame.h> | ||
11 | 12 | ||
12 | /* rdi: arg1 ... normal C conventions. rax is saved/restored. */ | 13 | /* rdi: arg1 ... normal C conventions. rax is saved/restored. */ |
13 | .macro THUNK name, func, put_ret_addr_in_rdi=0 | 14 | .macro THUNK name, func, put_ret_addr_in_rdi=0 |
14 | .globl \name | 15 | .globl \name |
16 | .type \name, @function | ||
15 | \name: | 17 | \name: |
18 | FRAME_BEGIN | ||
16 | 19 | ||
17 | /* this one pushes 9 elems, the next one would be %rIP */ | 20 | /* this one pushes 9 elems, the next one would be %rIP */ |
18 | pushq %rdi | 21 | pushq %rdi |
@@ -62,6 +65,7 @@ restore: | |||
62 | popq %rdx | 65 | popq %rdx |
63 | popq %rsi | 66 | popq %rsi |
64 | popq %rdi | 67 | popq %rdi |
68 | FRAME_END | ||
65 | ret | 69 | ret |
66 | _ASM_NOKPROBE(restore) | 70 | _ASM_NOKPROBE(restore) |
67 | #endif | 71 | #endif |
diff --git a/arch/x86/entry/vdso/vdso2c.h b/arch/x86/entry/vdso/vdso2c.h index 0224987556ce..abe961c7c71c 100644 --- a/arch/x86/entry/vdso/vdso2c.h +++ b/arch/x86/entry/vdso/vdso2c.h | |||
@@ -150,16 +150,9 @@ static void BITSFUNC(go)(void *raw_addr, size_t raw_len, | |||
150 | } | 150 | } |
151 | fprintf(outfile, "\n};\n\n"); | 151 | fprintf(outfile, "\n};\n\n"); |
152 | 152 | ||
153 | fprintf(outfile, "static struct page *pages[%lu];\n\n", | ||
154 | mapping_size / 4096); | ||
155 | |||
156 | fprintf(outfile, "const struct vdso_image %s = {\n", name); | 153 | fprintf(outfile, "const struct vdso_image %s = {\n", name); |
157 | fprintf(outfile, "\t.data = raw_data,\n"); | 154 | fprintf(outfile, "\t.data = raw_data,\n"); |
158 | fprintf(outfile, "\t.size = %lu,\n", mapping_size); | 155 | fprintf(outfile, "\t.size = %lu,\n", mapping_size); |
159 | fprintf(outfile, "\t.text_mapping = {\n"); | ||
160 | fprintf(outfile, "\t\t.name = \"[vdso]\",\n"); | ||
161 | fprintf(outfile, "\t\t.pages = pages,\n"); | ||
162 | fprintf(outfile, "\t},\n"); | ||
163 | if (alt_sec) { | 156 | if (alt_sec) { |
164 | fprintf(outfile, "\t.alt = %lu,\n", | 157 | fprintf(outfile, "\t.alt = %lu,\n", |
165 | (unsigned long)GET_LE(&alt_sec->sh_offset)); | 158 | (unsigned long)GET_LE(&alt_sec->sh_offset)); |
diff --git a/arch/x86/entry/vdso/vdso32-setup.c b/arch/x86/entry/vdso/vdso32-setup.c index 08a317a9ae4b..7853b53959cd 100644 --- a/arch/x86/entry/vdso/vdso32-setup.c +++ b/arch/x86/entry/vdso/vdso32-setup.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/mm_types.h> | 12 | #include <linux/mm_types.h> |
13 | 13 | ||
14 | #include <asm/cpufeature.h> | ||
15 | #include <asm/processor.h> | 14 | #include <asm/processor.h> |
16 | #include <asm/vdso.h> | 15 | #include <asm/vdso.h> |
17 | 16 | ||
diff --git a/arch/x86/entry/vdso/vdso32/system_call.S b/arch/x86/entry/vdso/vdso32/system_call.S index 3a1d9297074b..0109ac6cb79c 100644 --- a/arch/x86/entry/vdso/vdso32/system_call.S +++ b/arch/x86/entry/vdso/vdso32/system_call.S | |||
@@ -3,7 +3,7 @@ | |||
3 | */ | 3 | */ |
4 | 4 | ||
5 | #include <asm/dwarf2.h> | 5 | #include <asm/dwarf2.h> |
6 | #include <asm/cpufeature.h> | 6 | #include <asm/cpufeatures.h> |
7 | #include <asm/alternative-asm.h> | 7 | #include <asm/alternative-asm.h> |
8 | 8 | ||
9 | /* | 9 | /* |
diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c index b8f69e264ac4..10f704584922 100644 --- a/arch/x86/entry/vdso/vma.c +++ b/arch/x86/entry/vdso/vma.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <asm/page.h> | 20 | #include <asm/page.h> |
21 | #include <asm/hpet.h> | 21 | #include <asm/hpet.h> |
22 | #include <asm/desc.h> | 22 | #include <asm/desc.h> |
23 | #include <asm/cpufeature.h> | ||
23 | 24 | ||
24 | #if defined(CONFIG_X86_64) | 25 | #if defined(CONFIG_X86_64) |
25 | unsigned int __read_mostly vdso64_enabled = 1; | 26 | unsigned int __read_mostly vdso64_enabled = 1; |
@@ -27,13 +28,7 @@ unsigned int __read_mostly vdso64_enabled = 1; | |||
27 | 28 | ||
28 | void __init init_vdso_image(const struct vdso_image *image) | 29 | void __init init_vdso_image(const struct vdso_image *image) |
29 | { | 30 | { |
30 | int i; | ||
31 | int npages = (image->size) / PAGE_SIZE; | ||
32 | |||
33 | BUG_ON(image->size % PAGE_SIZE != 0); | 31 | BUG_ON(image->size % PAGE_SIZE != 0); |
34 | for (i = 0; i < npages; i++) | ||
35 | image->text_mapping.pages[i] = | ||
36 | virt_to_page(image->data + i*PAGE_SIZE); | ||
37 | 32 | ||
38 | apply_alternatives((struct alt_instr *)(image->data + image->alt), | 33 | apply_alternatives((struct alt_instr *)(image->data + image->alt), |
39 | (struct alt_instr *)(image->data + image->alt + | 34 | (struct alt_instr *)(image->data + image->alt + |
@@ -90,18 +85,87 @@ static unsigned long vdso_addr(unsigned long start, unsigned len) | |||
90 | #endif | 85 | #endif |
91 | } | 86 | } |
92 | 87 | ||
88 | static int vdso_fault(const struct vm_special_mapping *sm, | ||
89 | struct vm_area_struct *vma, struct vm_fault *vmf) | ||
90 | { | ||
91 | const struct vdso_image *image = vma->vm_mm->context.vdso_image; | ||
92 | |||
93 | if (!image || (vmf->pgoff << PAGE_SHIFT) >= image->size) | ||
94 | return VM_FAULT_SIGBUS; | ||
95 | |||
96 | vmf->page = virt_to_page(image->data + (vmf->pgoff << PAGE_SHIFT)); | ||
97 | get_page(vmf->page); | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | static const struct vm_special_mapping text_mapping = { | ||
102 | .name = "[vdso]", | ||
103 | .fault = vdso_fault, | ||
104 | }; | ||
105 | |||
106 | static int vvar_fault(const struct vm_special_mapping *sm, | ||
107 | struct vm_area_struct *vma, struct vm_fault *vmf) | ||
108 | { | ||
109 | const struct vdso_image *image = vma->vm_mm->context.vdso_image; | ||
110 | long sym_offset; | ||
111 | int ret = -EFAULT; | ||
112 | |||
113 | if (!image) | ||
114 | return VM_FAULT_SIGBUS; | ||
115 | |||
116 | sym_offset = (long)(vmf->pgoff << PAGE_SHIFT) + | ||
117 | image->sym_vvar_start; | ||
118 | |||
119 | /* | ||
120 | * Sanity check: a symbol offset of zero means that the page | ||
121 | * does not exist for this vdso image, not that the page is at | ||
122 | * offset zero relative to the text mapping. This should be | ||
123 | * impossible here, because sym_offset should only be zero for | ||
124 | * the page past the end of the vvar mapping. | ||
125 | */ | ||
126 | if (sym_offset == 0) | ||
127 | return VM_FAULT_SIGBUS; | ||
128 | |||
129 | if (sym_offset == image->sym_vvar_page) { | ||
130 | ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, | ||
131 | __pa_symbol(&__vvar_page) >> PAGE_SHIFT); | ||
132 | } else if (sym_offset == image->sym_hpet_page) { | ||
133 | #ifdef CONFIG_HPET_TIMER | ||
134 | if (hpet_address && vclock_was_used(VCLOCK_HPET)) { | ||
135 | ret = vm_insert_pfn_prot( | ||
136 | vma, | ||
137 | (unsigned long)vmf->virtual_address, | ||
138 | hpet_address >> PAGE_SHIFT, | ||
139 | pgprot_noncached(PAGE_READONLY)); | ||
140 | } | ||
141 | #endif | ||
142 | } else if (sym_offset == image->sym_pvclock_page) { | ||
143 | struct pvclock_vsyscall_time_info *pvti = | ||
144 | pvclock_pvti_cpu0_va(); | ||
145 | if (pvti && vclock_was_used(VCLOCK_PVCLOCK)) { | ||
146 | ret = vm_insert_pfn( | ||
147 | vma, | ||
148 | (unsigned long)vmf->virtual_address, | ||
149 | __pa(pvti) >> PAGE_SHIFT); | ||
150 | } | ||
151 | } | ||
152 | |||
153 | if (ret == 0 || ret == -EBUSY) | ||
154 | return VM_FAULT_NOPAGE; | ||
155 | |||
156 | return VM_FAULT_SIGBUS; | ||
157 | } | ||
158 | |||
93 | static int map_vdso(const struct vdso_image *image, bool calculate_addr) | 159 | static int map_vdso(const struct vdso_image *image, bool calculate_addr) |
94 | { | 160 | { |
95 | struct mm_struct *mm = current->mm; | 161 | struct mm_struct *mm = current->mm; |
96 | struct vm_area_struct *vma; | 162 | struct vm_area_struct *vma; |
97 | unsigned long addr, text_start; | 163 | unsigned long addr, text_start; |
98 | int ret = 0; | 164 | int ret = 0; |
99 | static struct page *no_pages[] = {NULL}; | 165 | static const struct vm_special_mapping vvar_mapping = { |
100 | static struct vm_special_mapping vvar_mapping = { | ||
101 | .name = "[vvar]", | 166 | .name = "[vvar]", |
102 | .pages = no_pages, | 167 | .fault = vvar_fault, |
103 | }; | 168 | }; |
104 | struct pvclock_vsyscall_time_info *pvti; | ||
105 | 169 | ||
106 | if (calculate_addr) { | 170 | if (calculate_addr) { |
107 | addr = vdso_addr(current->mm->start_stack, | 171 | addr = vdso_addr(current->mm->start_stack, |
@@ -121,6 +185,7 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr) | |||
121 | 185 | ||
122 | text_start = addr - image->sym_vvar_start; | 186 | text_start = addr - image->sym_vvar_start; |
123 | current->mm->context.vdso = (void __user *)text_start; | 187 | current->mm->context.vdso = (void __user *)text_start; |
188 | current->mm->context.vdso_image = image; | ||
124 | 189 | ||
125 | /* | 190 | /* |
126 | * MAYWRITE to allow gdb to COW and set breakpoints | 191 | * MAYWRITE to allow gdb to COW and set breakpoints |
@@ -130,7 +195,7 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr) | |||
130 | image->size, | 195 | image->size, |
131 | VM_READ|VM_EXEC| | 196 | VM_READ|VM_EXEC| |
132 | VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, | 197 | VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, |
133 | &image->text_mapping); | 198 | &text_mapping); |
134 | 199 | ||
135 | if (IS_ERR(vma)) { | 200 | if (IS_ERR(vma)) { |
136 | ret = PTR_ERR(vma); | 201 | ret = PTR_ERR(vma); |
@@ -140,7 +205,8 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr) | |||
140 | vma = _install_special_mapping(mm, | 205 | vma = _install_special_mapping(mm, |
141 | addr, | 206 | addr, |
142 | -image->sym_vvar_start, | 207 | -image->sym_vvar_start, |
143 | VM_READ|VM_MAYREAD, | 208 | VM_READ|VM_MAYREAD|VM_IO|VM_DONTDUMP| |
209 | VM_PFNMAP, | ||
144 | &vvar_mapping); | 210 | &vvar_mapping); |
145 | 211 | ||
146 | if (IS_ERR(vma)) { | 212 | if (IS_ERR(vma)) { |
@@ -148,41 +214,6 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr) | |||
148 | goto up_fail; | 214 | goto up_fail; |
149 | } | 215 | } |
150 | 216 | ||
151 | if (image->sym_vvar_page) | ||
152 | ret = remap_pfn_range(vma, | ||
153 | text_start + image->sym_vvar_page, | ||
154 | __pa_symbol(&__vvar_page) >> PAGE_SHIFT, | ||
155 | PAGE_SIZE, | ||
156 | PAGE_READONLY); | ||
157 | |||
158 | if (ret) | ||
159 | goto up_fail; | ||
160 | |||
161 | #ifdef CONFIG_HPET_TIMER | ||
162 | if (hpet_address && image->sym_hpet_page) { | ||
163 | ret = io_remap_pfn_range(vma, | ||
164 | text_start + image->sym_hpet_page, | ||
165 | hpet_address >> PAGE_SHIFT, | ||
166 | PAGE_SIZE, | ||
167 | pgprot_noncached(PAGE_READONLY)); | ||
168 | |||
169 | if (ret) | ||
170 | goto up_fail; | ||
171 | } | ||
172 | #endif | ||
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 | |||
186 | up_fail: | 217 | up_fail: |
187 | if (ret) | 218 | if (ret) |
188 | current->mm->context.vdso = NULL; | 219 | current->mm->context.vdso = NULL; |
@@ -254,7 +285,7 @@ static void vgetcpu_cpu_init(void *arg) | |||
254 | #ifdef CONFIG_NUMA | 285 | #ifdef CONFIG_NUMA |
255 | node = cpu_to_node(cpu); | 286 | node = cpu_to_node(cpu); |
256 | #endif | 287 | #endif |
257 | if (cpu_has(&cpu_data(cpu), X86_FEATURE_RDTSCP)) | 288 | if (static_cpu_has(X86_FEATURE_RDTSCP)) |
258 | write_rdtscp_aux((node << 12) | cpu); | 289 | write_rdtscp_aux((node << 12) | cpu); |
259 | 290 | ||
260 | /* | 291 | /* |
diff --git a/arch/x86/entry/vsyscall/vsyscall_gtod.c b/arch/x86/entry/vsyscall/vsyscall_gtod.c index 51e330416995..0fb3a104ac62 100644 --- a/arch/x86/entry/vsyscall/vsyscall_gtod.c +++ b/arch/x86/entry/vsyscall/vsyscall_gtod.c | |||
@@ -16,6 +16,8 @@ | |||
16 | #include <asm/vgtod.h> | 16 | #include <asm/vgtod.h> |
17 | #include <asm/vvar.h> | 17 | #include <asm/vvar.h> |
18 | 18 | ||
19 | int vclocks_used __read_mostly; | ||
20 | |||
19 | DEFINE_VVAR(struct vsyscall_gtod_data, vsyscall_gtod_data); | 21 | DEFINE_VVAR(struct vsyscall_gtod_data, vsyscall_gtod_data); |
20 | 22 | ||
21 | void update_vsyscall_tz(void) | 23 | void update_vsyscall_tz(void) |
@@ -26,12 +28,17 @@ void update_vsyscall_tz(void) | |||
26 | 28 | ||
27 | void update_vsyscall(struct timekeeper *tk) | 29 | void update_vsyscall(struct timekeeper *tk) |
28 | { | 30 | { |
31 | int vclock_mode = tk->tkr_mono.clock->archdata.vclock_mode; | ||
29 | struct vsyscall_gtod_data *vdata = &vsyscall_gtod_data; | 32 | struct vsyscall_gtod_data *vdata = &vsyscall_gtod_data; |
30 | 33 | ||
34 | /* Mark the new vclock used. */ | ||
35 | BUILD_BUG_ON(VCLOCK_MAX >= 32); | ||
36 | WRITE_ONCE(vclocks_used, READ_ONCE(vclocks_used) | (1 << vclock_mode)); | ||
37 | |||
31 | gtod_write_begin(vdata); | 38 | gtod_write_begin(vdata); |
32 | 39 | ||
33 | /* copy vsyscall data */ | 40 | /* copy vsyscall data */ |
34 | vdata->vclock_mode = tk->tkr_mono.clock->archdata.vclock_mode; | 41 | vdata->vclock_mode = vclock_mode; |
35 | vdata->cycle_last = tk->tkr_mono.cycle_last; | 42 | vdata->cycle_last = tk->tkr_mono.cycle_last; |
36 | vdata->mask = tk->tkr_mono.mask; | 43 | vdata->mask = tk->tkr_mono.mask; |
37 | vdata->mult = tk->tkr_mono.mult; | 44 | vdata->mult = tk->tkr_mono.mult; |
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h index 7bfc85bbb8ff..99afb665a004 100644 --- a/arch/x86/include/asm/alternative.h +++ b/arch/x86/include/asm/alternative.h | |||
@@ -152,12 +152,6 @@ static inline int alternatives_text_reserved(void *start, void *end) | |||
152 | ".popsection" | 152 | ".popsection" |
153 | 153 | ||
154 | /* | 154 | /* |
155 | * This must be included *after* the definition of ALTERNATIVE due to | ||
156 | * <asm/arch_hweight.h> | ||
157 | */ | ||
158 | #include <asm/cpufeature.h> | ||
159 | |||
160 | /* | ||
161 | * Alternative instructions for different CPU types or capabilities. | 155 | * Alternative instructions for different CPU types or capabilities. |
162 | * | 156 | * |
163 | * This allows to use optimized instructions even on generic binary | 157 | * This allows to use optimized instructions even on generic binary |
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index c80f6b6f3da2..0899cfc8dfe8 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h | |||
@@ -6,7 +6,6 @@ | |||
6 | 6 | ||
7 | #include <asm/alternative.h> | 7 | #include <asm/alternative.h> |
8 | #include <asm/cpufeature.h> | 8 | #include <asm/cpufeature.h> |
9 | #include <asm/processor.h> | ||
10 | #include <asm/apicdef.h> | 9 | #include <asm/apicdef.h> |
11 | #include <linux/atomic.h> | 10 | #include <linux/atomic.h> |
12 | #include <asm/fixmap.h> | 11 | #include <asm/fixmap.h> |
diff --git a/arch/x86/include/asm/arch_hweight.h b/arch/x86/include/asm/arch_hweight.h index 259a7c1ef709..02e799fa43d1 100644 --- a/arch/x86/include/asm/arch_hweight.h +++ b/arch/x86/include/asm/arch_hweight.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef _ASM_X86_HWEIGHT_H | 1 | #ifndef _ASM_X86_HWEIGHT_H |
2 | #define _ASM_X86_HWEIGHT_H | 2 | #define _ASM_X86_HWEIGHT_H |
3 | 3 | ||
4 | #include <asm/cpufeatures.h> | ||
5 | |||
4 | #ifdef CONFIG_64BIT | 6 | #ifdef CONFIG_64BIT |
5 | /* popcnt %edi, %eax -- redundant REX prefix for alignment */ | 7 | /* popcnt %edi, %eax -- redundant REX prefix for alignment */ |
6 | #define POPCNT32 ".byte 0xf3,0x40,0x0f,0xb8,0xc7" | 8 | #define POPCNT32 ".byte 0xf3,0x40,0x0f,0xb8,0xc7" |
diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h index cfe3b954d5e4..7766d1cf096e 100644 --- a/arch/x86/include/asm/bitops.h +++ b/arch/x86/include/asm/bitops.h | |||
@@ -91,7 +91,7 @@ set_bit(long nr, volatile unsigned long *addr) | |||
91 | * If it's called on the same region of memory simultaneously, the effect | 91 | * If it's called on the same region of memory simultaneously, the effect |
92 | * may be that only one operation succeeds. | 92 | * may be that only one operation succeeds. |
93 | */ | 93 | */ |
94 | static inline void __set_bit(long nr, volatile unsigned long *addr) | 94 | static __always_inline void __set_bit(long nr, volatile unsigned long *addr) |
95 | { | 95 | { |
96 | asm volatile("bts %1,%0" : ADDR : "Ir" (nr) : "memory"); | 96 | asm volatile("bts %1,%0" : ADDR : "Ir" (nr) : "memory"); |
97 | } | 97 | } |
@@ -128,13 +128,13 @@ clear_bit(long nr, volatile unsigned long *addr) | |||
128 | * clear_bit() is atomic and implies release semantics before the memory | 128 | * clear_bit() is atomic and implies release semantics before the memory |
129 | * operation. It can be used for an unlock. | 129 | * operation. It can be used for an unlock. |
130 | */ | 130 | */ |
131 | static inline void clear_bit_unlock(long nr, volatile unsigned long *addr) | 131 | static __always_inline void clear_bit_unlock(long nr, volatile unsigned long *addr) |
132 | { | 132 | { |
133 | barrier(); | 133 | barrier(); |
134 | clear_bit(nr, addr); | 134 | clear_bit(nr, addr); |
135 | } | 135 | } |
136 | 136 | ||
137 | static inline void __clear_bit(long nr, volatile unsigned long *addr) | 137 | static __always_inline void __clear_bit(long nr, volatile unsigned long *addr) |
138 | { | 138 | { |
139 | asm volatile("btr %1,%0" : ADDR : "Ir" (nr)); | 139 | asm volatile("btr %1,%0" : ADDR : "Ir" (nr)); |
140 | } | 140 | } |
@@ -151,7 +151,7 @@ static inline void __clear_bit(long nr, volatile unsigned long *addr) | |||
151 | * No memory barrier is required here, because x86 cannot reorder stores past | 151 | * No memory barrier is required here, because x86 cannot reorder stores past |
152 | * older loads. Same principle as spin_unlock. | 152 | * older loads. Same principle as spin_unlock. |
153 | */ | 153 | */ |
154 | static inline void __clear_bit_unlock(long nr, volatile unsigned long *addr) | 154 | static __always_inline void __clear_bit_unlock(long nr, volatile unsigned long *addr) |
155 | { | 155 | { |
156 | barrier(); | 156 | barrier(); |
157 | __clear_bit(nr, addr); | 157 | __clear_bit(nr, addr); |
@@ -166,7 +166,7 @@ static inline void __clear_bit_unlock(long nr, volatile unsigned long *addr) | |||
166 | * If it's called on the same region of memory simultaneously, the effect | 166 | * If it's called on the same region of memory simultaneously, the effect |
167 | * may be that only one operation succeeds. | 167 | * may be that only one operation succeeds. |
168 | */ | 168 | */ |
169 | static inline void __change_bit(long nr, volatile unsigned long *addr) | 169 | static __always_inline void __change_bit(long nr, volatile unsigned long *addr) |
170 | { | 170 | { |
171 | asm volatile("btc %1,%0" : ADDR : "Ir" (nr)); | 171 | asm volatile("btc %1,%0" : ADDR : "Ir" (nr)); |
172 | } | 172 | } |
@@ -180,7 +180,7 @@ static inline void __change_bit(long nr, volatile unsigned long *addr) | |||
180 | * Note that @nr may be almost arbitrarily large; this function is not | 180 | * Note that @nr may be almost arbitrarily large; this function is not |
181 | * restricted to acting on a single-word quantity. | 181 | * restricted to acting on a single-word quantity. |
182 | */ | 182 | */ |
183 | static inline void change_bit(long nr, volatile unsigned long *addr) | 183 | static __always_inline void change_bit(long nr, volatile unsigned long *addr) |
184 | { | 184 | { |
185 | if (IS_IMMEDIATE(nr)) { | 185 | if (IS_IMMEDIATE(nr)) { |
186 | asm volatile(LOCK_PREFIX "xorb %1,%0" | 186 | asm volatile(LOCK_PREFIX "xorb %1,%0" |
@@ -201,7 +201,7 @@ static inline void change_bit(long nr, volatile unsigned long *addr) | |||
201 | * This operation is atomic and cannot be reordered. | 201 | * This operation is atomic and cannot be reordered. |
202 | * It also implies a memory barrier. | 202 | * It also implies a memory barrier. |
203 | */ | 203 | */ |
204 | static inline int test_and_set_bit(long nr, volatile unsigned long *addr) | 204 | static __always_inline int test_and_set_bit(long nr, volatile unsigned long *addr) |
205 | { | 205 | { |
206 | GEN_BINARY_RMWcc(LOCK_PREFIX "bts", *addr, "Ir", nr, "%0", "c"); | 206 | GEN_BINARY_RMWcc(LOCK_PREFIX "bts", *addr, "Ir", nr, "%0", "c"); |
207 | } | 207 | } |
@@ -228,7 +228,7 @@ test_and_set_bit_lock(long nr, volatile unsigned long *addr) | |||
228 | * If two examples of this operation race, one can appear to succeed | 228 | * If two examples of this operation race, one can appear to succeed |
229 | * but actually fail. You must protect multiple accesses with a lock. | 229 | * but actually fail. You must protect multiple accesses with a lock. |
230 | */ | 230 | */ |
231 | static inline int __test_and_set_bit(long nr, volatile unsigned long *addr) | 231 | static __always_inline int __test_and_set_bit(long nr, volatile unsigned long *addr) |
232 | { | 232 | { |
233 | int oldbit; | 233 | int oldbit; |
234 | 234 | ||
@@ -247,7 +247,7 @@ static inline int __test_and_set_bit(long nr, volatile unsigned long *addr) | |||
247 | * This operation is atomic and cannot be reordered. | 247 | * This operation is atomic and cannot be reordered. |
248 | * It also implies a memory barrier. | 248 | * It also implies a memory barrier. |
249 | */ | 249 | */ |
250 | static inline int test_and_clear_bit(long nr, volatile unsigned long *addr) | 250 | static __always_inline int test_and_clear_bit(long nr, volatile unsigned long *addr) |
251 | { | 251 | { |
252 | GEN_BINARY_RMWcc(LOCK_PREFIX "btr", *addr, "Ir", nr, "%0", "c"); | 252 | GEN_BINARY_RMWcc(LOCK_PREFIX "btr", *addr, "Ir", nr, "%0", "c"); |
253 | } | 253 | } |
@@ -268,7 +268,7 @@ static inline int test_and_clear_bit(long nr, volatile unsigned long *addr) | |||
268 | * accessed from a hypervisor on the same CPU if running in a VM: don't change | 268 | * accessed from a hypervisor on the same CPU if running in a VM: don't change |
269 | * this without also updating arch/x86/kernel/kvm.c | 269 | * this without also updating arch/x86/kernel/kvm.c |
270 | */ | 270 | */ |
271 | static inline int __test_and_clear_bit(long nr, volatile unsigned long *addr) | 271 | static __always_inline int __test_and_clear_bit(long nr, volatile unsigned long *addr) |
272 | { | 272 | { |
273 | int oldbit; | 273 | int oldbit; |
274 | 274 | ||
@@ -280,7 +280,7 @@ static inline int __test_and_clear_bit(long nr, volatile unsigned long *addr) | |||
280 | } | 280 | } |
281 | 281 | ||
282 | /* WARNING: non atomic and it can be reordered! */ | 282 | /* WARNING: non atomic and it can be reordered! */ |
283 | static inline int __test_and_change_bit(long nr, volatile unsigned long *addr) | 283 | static __always_inline int __test_and_change_bit(long nr, volatile unsigned long *addr) |
284 | { | 284 | { |
285 | int oldbit; | 285 | int oldbit; |
286 | 286 | ||
@@ -300,7 +300,7 @@ static inline int __test_and_change_bit(long nr, volatile unsigned long *addr) | |||
300 | * This operation is atomic and cannot be reordered. | 300 | * This operation is atomic and cannot be reordered. |
301 | * It also implies a memory barrier. | 301 | * It also implies a memory barrier. |
302 | */ | 302 | */ |
303 | static inline int test_and_change_bit(long nr, volatile unsigned long *addr) | 303 | static __always_inline int test_and_change_bit(long nr, volatile unsigned long *addr) |
304 | { | 304 | { |
305 | GEN_BINARY_RMWcc(LOCK_PREFIX "btc", *addr, "Ir", nr, "%0", "c"); | 305 | GEN_BINARY_RMWcc(LOCK_PREFIX "btc", *addr, "Ir", nr, "%0", "c"); |
306 | } | 306 | } |
@@ -311,7 +311,7 @@ static __always_inline int constant_test_bit(long nr, const volatile unsigned lo | |||
311 | (addr[nr >> _BITOPS_LONG_SHIFT])) != 0; | 311 | (addr[nr >> _BITOPS_LONG_SHIFT])) != 0; |
312 | } | 312 | } |
313 | 313 | ||
314 | static inline int variable_test_bit(long nr, volatile const unsigned long *addr) | 314 | static __always_inline int variable_test_bit(long nr, volatile const unsigned long *addr) |
315 | { | 315 | { |
316 | int oldbit; | 316 | int oldbit; |
317 | 317 | ||
@@ -343,7 +343,7 @@ static int test_bit(int nr, const volatile unsigned long *addr); | |||
343 | * | 343 | * |
344 | * Undefined if no bit exists, so code should check against 0 first. | 344 | * Undefined if no bit exists, so code should check against 0 first. |
345 | */ | 345 | */ |
346 | static inline unsigned long __ffs(unsigned long word) | 346 | static __always_inline unsigned long __ffs(unsigned long word) |
347 | { | 347 | { |
348 | asm("rep; bsf %1,%0" | 348 | asm("rep; bsf %1,%0" |
349 | : "=r" (word) | 349 | : "=r" (word) |
@@ -357,7 +357,7 @@ static inline unsigned long __ffs(unsigned long word) | |||
357 | * | 357 | * |
358 | * Undefined if no zero exists, so code should check against ~0UL first. | 358 | * Undefined if no zero exists, so code should check against ~0UL first. |
359 | */ | 359 | */ |
360 | static inline unsigned long ffz(unsigned long word) | 360 | static __always_inline unsigned long ffz(unsigned long word) |
361 | { | 361 | { |
362 | asm("rep; bsf %1,%0" | 362 | asm("rep; bsf %1,%0" |
363 | : "=r" (word) | 363 | : "=r" (word) |
@@ -371,7 +371,7 @@ static inline unsigned long ffz(unsigned long word) | |||
371 | * | 371 | * |
372 | * Undefined if no set bit exists, so code should check against 0 first. | 372 | * Undefined if no set bit exists, so code should check against 0 first. |
373 | */ | 373 | */ |
374 | static inline unsigned long __fls(unsigned long word) | 374 | static __always_inline unsigned long __fls(unsigned long word) |
375 | { | 375 | { |
376 | asm("bsr %1,%0" | 376 | asm("bsr %1,%0" |
377 | : "=r" (word) | 377 | : "=r" (word) |
@@ -393,7 +393,7 @@ static inline unsigned long __fls(unsigned long word) | |||
393 | * set bit if value is nonzero. The first (least significant) bit | 393 | * set bit if value is nonzero. The first (least significant) bit |
394 | * is at position 1. | 394 | * is at position 1. |
395 | */ | 395 | */ |
396 | static inline int ffs(int x) | 396 | static __always_inline int ffs(int x) |
397 | { | 397 | { |
398 | int r; | 398 | int r; |
399 | 399 | ||
@@ -434,7 +434,7 @@ static inline int ffs(int x) | |||
434 | * set bit if value is nonzero. The last (most significant) bit is | 434 | * set bit if value is nonzero. The last (most significant) bit is |
435 | * at position 32. | 435 | * at position 32. |
436 | */ | 436 | */ |
437 | static inline int fls(int x) | 437 | static __always_inline int fls(int x) |
438 | { | 438 | { |
439 | int r; | 439 | int r; |
440 | 440 | ||
diff --git a/arch/x86/include/asm/clocksource.h b/arch/x86/include/asm/clocksource.h index eda81dc0f4ae..d194266acb28 100644 --- a/arch/x86/include/asm/clocksource.h +++ b/arch/x86/include/asm/clocksource.h | |||
@@ -3,10 +3,11 @@ | |||
3 | #ifndef _ASM_X86_CLOCKSOURCE_H | 3 | #ifndef _ASM_X86_CLOCKSOURCE_H |
4 | #define _ASM_X86_CLOCKSOURCE_H | 4 | #define _ASM_X86_CLOCKSOURCE_H |
5 | 5 | ||
6 | #define VCLOCK_NONE 0 /* No vDSO clock available. */ | 6 | #define VCLOCK_NONE 0 /* No vDSO clock available. */ |
7 | #define VCLOCK_TSC 1 /* vDSO should use vread_tsc. */ | 7 | #define VCLOCK_TSC 1 /* vDSO should use vread_tsc. */ |
8 | #define VCLOCK_HPET 2 /* vDSO should use vread_hpet. */ | 8 | #define VCLOCK_HPET 2 /* vDSO should use vread_hpet. */ |
9 | #define VCLOCK_PVCLOCK 3 /* vDSO should use vread_pvclock. */ | 9 | #define VCLOCK_PVCLOCK 3 /* vDSO should use vread_pvclock. */ |
10 | #define VCLOCK_MAX 3 | ||
10 | 11 | ||
11 | struct arch_clocksource_data { | 12 | struct arch_clocksource_data { |
12 | int vclock_mode; | 13 | int vclock_mode; |
diff --git a/arch/x86/include/asm/cmpxchg.h b/arch/x86/include/asm/cmpxchg.h index ad19841eddfe..9733361fed6f 100644 --- a/arch/x86/include/asm/cmpxchg.h +++ b/arch/x86/include/asm/cmpxchg.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define ASM_X86_CMPXCHG_H | 2 | #define ASM_X86_CMPXCHG_H |
3 | 3 | ||
4 | #include <linux/compiler.h> | 4 | #include <linux/compiler.h> |
5 | #include <asm/cpufeatures.h> | ||
5 | #include <asm/alternative.h> /* Provides LOCK_PREFIX */ | 6 | #include <asm/alternative.h> /* Provides LOCK_PREFIX */ |
6 | 7 | ||
7 | /* | 8 | /* |
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 7ad8c9464297..68e4e8258b84 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h | |||
@@ -1,288 +1,7 @@ | |||
1 | /* | ||
2 | * Defines x86 CPU feature bits | ||
3 | */ | ||
4 | #ifndef _ASM_X86_CPUFEATURE_H | 1 | #ifndef _ASM_X86_CPUFEATURE_H |
5 | #define _ASM_X86_CPUFEATURE_H | 2 | #define _ASM_X86_CPUFEATURE_H |
6 | 3 | ||
7 | #ifndef _ASM_X86_REQUIRED_FEATURES_H | 4 | #include <asm/processor.h> |
8 | #include <asm/required-features.h> | ||
9 | #endif | ||
10 | |||
11 | #ifndef _ASM_X86_DISABLED_FEATURES_H | ||
12 | #include <asm/disabled-features.h> | ||
13 | #endif | ||
14 | |||
15 | #define NCAPINTS 16 /* N 32-bit words worth of info */ | ||
16 | #define NBUGINTS 1 /* N 32-bit bug flags */ | ||
17 | |||
18 | /* | ||
19 | * Note: If the comment begins with a quoted string, that string is used | ||
20 | * in /proc/cpuinfo instead of the macro name. If the string is "", | ||
21 | * this feature bit is not displayed in /proc/cpuinfo at all. | ||
22 | */ | ||
23 | |||
24 | /* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */ | ||
25 | #define X86_FEATURE_FPU ( 0*32+ 0) /* Onboard FPU */ | ||
26 | #define X86_FEATURE_VME ( 0*32+ 1) /* Virtual Mode Extensions */ | ||
27 | #define X86_FEATURE_DE ( 0*32+ 2) /* Debugging Extensions */ | ||
28 | #define X86_FEATURE_PSE ( 0*32+ 3) /* Page Size Extensions */ | ||
29 | #define X86_FEATURE_TSC ( 0*32+ 4) /* Time Stamp Counter */ | ||
30 | #define X86_FEATURE_MSR ( 0*32+ 5) /* Model-Specific Registers */ | ||
31 | #define X86_FEATURE_PAE ( 0*32+ 6) /* Physical Address Extensions */ | ||
32 | #define X86_FEATURE_MCE ( 0*32+ 7) /* Machine Check Exception */ | ||
33 | #define X86_FEATURE_CX8 ( 0*32+ 8) /* CMPXCHG8 instruction */ | ||
34 | #define X86_FEATURE_APIC ( 0*32+ 9) /* Onboard APIC */ | ||
35 | #define X86_FEATURE_SEP ( 0*32+11) /* SYSENTER/SYSEXIT */ | ||
36 | #define X86_FEATURE_MTRR ( 0*32+12) /* Memory Type Range Registers */ | ||
37 | #define X86_FEATURE_PGE ( 0*32+13) /* Page Global Enable */ | ||
38 | #define X86_FEATURE_MCA ( 0*32+14) /* Machine Check Architecture */ | ||
39 | #define X86_FEATURE_CMOV ( 0*32+15) /* CMOV instructions */ | ||
40 | /* (plus FCMOVcc, FCOMI with FPU) */ | ||
41 | #define X86_FEATURE_PAT ( 0*32+16) /* Page Attribute Table */ | ||
42 | #define X86_FEATURE_PSE36 ( 0*32+17) /* 36-bit PSEs */ | ||
43 | #define X86_FEATURE_PN ( 0*32+18) /* Processor serial number */ | ||
44 | #define X86_FEATURE_CLFLUSH ( 0*32+19) /* CLFLUSH instruction */ | ||
45 | #define X86_FEATURE_DS ( 0*32+21) /* "dts" Debug Store */ | ||
46 | #define X86_FEATURE_ACPI ( 0*32+22) /* ACPI via MSR */ | ||
47 | #define X86_FEATURE_MMX ( 0*32+23) /* Multimedia Extensions */ | ||
48 | #define X86_FEATURE_FXSR ( 0*32+24) /* FXSAVE/FXRSTOR, CR4.OSFXSR */ | ||
49 | #define X86_FEATURE_XMM ( 0*32+25) /* "sse" */ | ||
50 | #define X86_FEATURE_XMM2 ( 0*32+26) /* "sse2" */ | ||
51 | #define X86_FEATURE_SELFSNOOP ( 0*32+27) /* "ss" CPU self snoop */ | ||
52 | #define X86_FEATURE_HT ( 0*32+28) /* Hyper-Threading */ | ||
53 | #define X86_FEATURE_ACC ( 0*32+29) /* "tm" Automatic clock control */ | ||
54 | #define X86_FEATURE_IA64 ( 0*32+30) /* IA-64 processor */ | ||
55 | #define X86_FEATURE_PBE ( 0*32+31) /* Pending Break Enable */ | ||
56 | |||
57 | /* AMD-defined CPU features, CPUID level 0x80000001, word 1 */ | ||
58 | /* Don't duplicate feature flags which are redundant with Intel! */ | ||
59 | #define X86_FEATURE_SYSCALL ( 1*32+11) /* SYSCALL/SYSRET */ | ||
60 | #define X86_FEATURE_MP ( 1*32+19) /* MP Capable. */ | ||
61 | #define X86_FEATURE_NX ( 1*32+20) /* Execute Disable */ | ||
62 | #define X86_FEATURE_MMXEXT ( 1*32+22) /* AMD MMX extensions */ | ||
63 | #define X86_FEATURE_FXSR_OPT ( 1*32+25) /* FXSAVE/FXRSTOR optimizations */ | ||
64 | #define X86_FEATURE_GBPAGES ( 1*32+26) /* "pdpe1gb" GB pages */ | ||
65 | #define X86_FEATURE_RDTSCP ( 1*32+27) /* RDTSCP */ | ||
66 | #define X86_FEATURE_LM ( 1*32+29) /* Long Mode (x86-64) */ | ||
67 | #define X86_FEATURE_3DNOWEXT ( 1*32+30) /* AMD 3DNow! extensions */ | ||
68 | #define X86_FEATURE_3DNOW ( 1*32+31) /* 3DNow! */ | ||
69 | |||
70 | /* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */ | ||
71 | #define X86_FEATURE_RECOVERY ( 2*32+ 0) /* CPU in recovery mode */ | ||
72 | #define X86_FEATURE_LONGRUN ( 2*32+ 1) /* Longrun power control */ | ||
73 | #define X86_FEATURE_LRTI ( 2*32+ 3) /* LongRun table interface */ | ||
74 | |||
75 | /* Other features, Linux-defined mapping, word 3 */ | ||
76 | /* This range is used for feature bits which conflict or are synthesized */ | ||
77 | #define X86_FEATURE_CXMMX ( 3*32+ 0) /* Cyrix MMX extensions */ | ||
78 | #define X86_FEATURE_K6_MTRR ( 3*32+ 1) /* AMD K6 nonstandard MTRRs */ | ||
79 | #define X86_FEATURE_CYRIX_ARR ( 3*32+ 2) /* Cyrix ARRs (= MTRRs) */ | ||
80 | #define X86_FEATURE_CENTAUR_MCR ( 3*32+ 3) /* Centaur MCRs (= MTRRs) */ | ||
81 | /* cpu types for specific tunings: */ | ||
82 | #define X86_FEATURE_K8 ( 3*32+ 4) /* "" Opteron, Athlon64 */ | ||
83 | #define X86_FEATURE_K7 ( 3*32+ 5) /* "" Athlon */ | ||
84 | #define X86_FEATURE_P3 ( 3*32+ 6) /* "" P3 */ | ||
85 | #define X86_FEATURE_P4 ( 3*32+ 7) /* "" P4 */ | ||
86 | #define X86_FEATURE_CONSTANT_TSC ( 3*32+ 8) /* TSC ticks at a constant rate */ | ||
87 | #define X86_FEATURE_UP ( 3*32+ 9) /* smp kernel running on up */ | ||
88 | /* free, was #define X86_FEATURE_FXSAVE_LEAK ( 3*32+10) * "" FXSAVE leaks FOP/FIP/FOP */ | ||
89 | #define X86_FEATURE_ARCH_PERFMON ( 3*32+11) /* Intel Architectural PerfMon */ | ||
90 | #define X86_FEATURE_PEBS ( 3*32+12) /* Precise-Event Based Sampling */ | ||
91 | #define X86_FEATURE_BTS ( 3*32+13) /* Branch Trace Store */ | ||
92 | #define X86_FEATURE_SYSCALL32 ( 3*32+14) /* "" syscall in ia32 userspace */ | ||
93 | #define X86_FEATURE_SYSENTER32 ( 3*32+15) /* "" sysenter in ia32 userspace */ | ||
94 | #define X86_FEATURE_REP_GOOD ( 3*32+16) /* rep microcode works well */ | ||
95 | #define X86_FEATURE_MFENCE_RDTSC ( 3*32+17) /* "" Mfence synchronizes RDTSC */ | ||
96 | #define X86_FEATURE_LFENCE_RDTSC ( 3*32+18) /* "" Lfence synchronizes RDTSC */ | ||
97 | /* free, was #define X86_FEATURE_11AP ( 3*32+19) * "" Bad local APIC aka 11AP */ | ||
98 | #define X86_FEATURE_NOPL ( 3*32+20) /* The NOPL (0F 1F) instructions */ | ||
99 | #define X86_FEATURE_ALWAYS ( 3*32+21) /* "" Always-present feature */ | ||
100 | #define X86_FEATURE_XTOPOLOGY ( 3*32+22) /* cpu topology enum extensions */ | ||
101 | #define X86_FEATURE_TSC_RELIABLE ( 3*32+23) /* TSC is known to be reliable */ | ||
102 | #define X86_FEATURE_NONSTOP_TSC ( 3*32+24) /* TSC does not stop in C states */ | ||
103 | /* free, was #define X86_FEATURE_CLFLUSH_MONITOR ( 3*32+25) * "" clflush reqd with monitor */ | ||
104 | #define X86_FEATURE_EXTD_APICID ( 3*32+26) /* has extended APICID (8 bits) */ | ||
105 | #define X86_FEATURE_AMD_DCM ( 3*32+27) /* multi-node processor */ | ||
106 | #define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */ | ||
107 | #define X86_FEATURE_EAGER_FPU ( 3*32+29) /* "eagerfpu" Non lazy FPU restore */ | ||
108 | #define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */ | ||
109 | |||
110 | /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ | ||
111 | #define X86_FEATURE_XMM3 ( 4*32+ 0) /* "pni" SSE-3 */ | ||
112 | #define X86_FEATURE_PCLMULQDQ ( 4*32+ 1) /* PCLMULQDQ instruction */ | ||
113 | #define X86_FEATURE_DTES64 ( 4*32+ 2) /* 64-bit Debug Store */ | ||
114 | #define X86_FEATURE_MWAIT ( 4*32+ 3) /* "monitor" Monitor/Mwait support */ | ||
115 | #define X86_FEATURE_DSCPL ( 4*32+ 4) /* "ds_cpl" CPL Qual. Debug Store */ | ||
116 | #define X86_FEATURE_VMX ( 4*32+ 5) /* Hardware virtualization */ | ||
117 | #define X86_FEATURE_SMX ( 4*32+ 6) /* Safer mode */ | ||
118 | #define X86_FEATURE_EST ( 4*32+ 7) /* Enhanced SpeedStep */ | ||
119 | #define X86_FEATURE_TM2 ( 4*32+ 8) /* Thermal Monitor 2 */ | ||
120 | #define X86_FEATURE_SSSE3 ( 4*32+ 9) /* Supplemental SSE-3 */ | ||
121 | #define X86_FEATURE_CID ( 4*32+10) /* Context ID */ | ||
122 | #define X86_FEATURE_SDBG ( 4*32+11) /* Silicon Debug */ | ||
123 | #define X86_FEATURE_FMA ( 4*32+12) /* Fused multiply-add */ | ||
124 | #define X86_FEATURE_CX16 ( 4*32+13) /* CMPXCHG16B */ | ||
125 | #define X86_FEATURE_XTPR ( 4*32+14) /* Send Task Priority Messages */ | ||
126 | #define X86_FEATURE_PDCM ( 4*32+15) /* Performance Capabilities */ | ||
127 | #define X86_FEATURE_PCID ( 4*32+17) /* Process Context Identifiers */ | ||
128 | #define X86_FEATURE_DCA ( 4*32+18) /* Direct Cache Access */ | ||
129 | #define X86_FEATURE_XMM4_1 ( 4*32+19) /* "sse4_1" SSE-4.1 */ | ||
130 | #define X86_FEATURE_XMM4_2 ( 4*32+20) /* "sse4_2" SSE-4.2 */ | ||
131 | #define X86_FEATURE_X2APIC ( 4*32+21) /* x2APIC */ | ||
132 | #define X86_FEATURE_MOVBE ( 4*32+22) /* MOVBE instruction */ | ||
133 | #define X86_FEATURE_POPCNT ( 4*32+23) /* POPCNT instruction */ | ||
134 | #define X86_FEATURE_TSC_DEADLINE_TIMER ( 4*32+24) /* Tsc deadline timer */ | ||
135 | #define X86_FEATURE_AES ( 4*32+25) /* AES instructions */ | ||
136 | #define X86_FEATURE_XSAVE ( 4*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV */ | ||
137 | #define X86_FEATURE_OSXSAVE ( 4*32+27) /* "" XSAVE enabled in the OS */ | ||
138 | #define X86_FEATURE_AVX ( 4*32+28) /* Advanced Vector Extensions */ | ||
139 | #define X86_FEATURE_F16C ( 4*32+29) /* 16-bit fp conversions */ | ||
140 | #define X86_FEATURE_RDRAND ( 4*32+30) /* The RDRAND instruction */ | ||
141 | #define X86_FEATURE_HYPERVISOR ( 4*32+31) /* Running on a hypervisor */ | ||
142 | |||
143 | /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */ | ||
144 | #define X86_FEATURE_XSTORE ( 5*32+ 2) /* "rng" RNG present (xstore) */ | ||
145 | #define X86_FEATURE_XSTORE_EN ( 5*32+ 3) /* "rng_en" RNG enabled */ | ||
146 | #define X86_FEATURE_XCRYPT ( 5*32+ 6) /* "ace" on-CPU crypto (xcrypt) */ | ||
147 | #define X86_FEATURE_XCRYPT_EN ( 5*32+ 7) /* "ace_en" on-CPU crypto enabled */ | ||
148 | #define X86_FEATURE_ACE2 ( 5*32+ 8) /* Advanced Cryptography Engine v2 */ | ||
149 | #define X86_FEATURE_ACE2_EN ( 5*32+ 9) /* ACE v2 enabled */ | ||
150 | #define X86_FEATURE_PHE ( 5*32+10) /* PadLock Hash Engine */ | ||
151 | #define X86_FEATURE_PHE_EN ( 5*32+11) /* PHE enabled */ | ||
152 | #define X86_FEATURE_PMM ( 5*32+12) /* PadLock Montgomery Multiplier */ | ||
153 | #define X86_FEATURE_PMM_EN ( 5*32+13) /* PMM enabled */ | ||
154 | |||
155 | /* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */ | ||
156 | #define X86_FEATURE_LAHF_LM ( 6*32+ 0) /* LAHF/SAHF in long mode */ | ||
157 | #define X86_FEATURE_CMP_LEGACY ( 6*32+ 1) /* If yes HyperThreading not valid */ | ||
158 | #define X86_FEATURE_SVM ( 6*32+ 2) /* Secure virtual machine */ | ||
159 | #define X86_FEATURE_EXTAPIC ( 6*32+ 3) /* Extended APIC space */ | ||
160 | #define X86_FEATURE_CR8_LEGACY ( 6*32+ 4) /* CR8 in 32-bit mode */ | ||
161 | #define X86_FEATURE_ABM ( 6*32+ 5) /* Advanced bit manipulation */ | ||
162 | #define X86_FEATURE_SSE4A ( 6*32+ 6) /* SSE-4A */ | ||
163 | #define X86_FEATURE_MISALIGNSSE ( 6*32+ 7) /* Misaligned SSE mode */ | ||
164 | #define X86_FEATURE_3DNOWPREFETCH ( 6*32+ 8) /* 3DNow prefetch instructions */ | ||
165 | #define X86_FEATURE_OSVW ( 6*32+ 9) /* OS Visible Workaround */ | ||
166 | #define X86_FEATURE_IBS ( 6*32+10) /* Instruction Based Sampling */ | ||
167 | #define X86_FEATURE_XOP ( 6*32+11) /* extended AVX instructions */ | ||
168 | #define X86_FEATURE_SKINIT ( 6*32+12) /* SKINIT/STGI instructions */ | ||
169 | #define X86_FEATURE_WDT ( 6*32+13) /* Watchdog timer */ | ||
170 | #define X86_FEATURE_LWP ( 6*32+15) /* Light Weight Profiling */ | ||
171 | #define X86_FEATURE_FMA4 ( 6*32+16) /* 4 operands MAC instructions */ | ||
172 | #define X86_FEATURE_TCE ( 6*32+17) /* translation cache extension */ | ||
173 | #define X86_FEATURE_NODEID_MSR ( 6*32+19) /* NodeId MSR */ | ||
174 | #define X86_FEATURE_TBM ( 6*32+21) /* trailing bit manipulations */ | ||
175 | #define X86_FEATURE_TOPOEXT ( 6*32+22) /* topology extensions CPUID leafs */ | ||
176 | #define X86_FEATURE_PERFCTR_CORE ( 6*32+23) /* core performance counter extensions */ | ||
177 | #define X86_FEATURE_PERFCTR_NB ( 6*32+24) /* NB performance counter extensions */ | ||
178 | #define X86_FEATURE_BPEXT (6*32+26) /* data breakpoint extension */ | ||
179 | #define X86_FEATURE_PERFCTR_L2 ( 6*32+28) /* L2 performance counter extensions */ | ||
180 | #define X86_FEATURE_MWAITX ( 6*32+29) /* MWAIT extension (MONITORX/MWAITX) */ | ||
181 | |||
182 | /* | ||
183 | * Auxiliary flags: Linux defined - For features scattered in various | ||
184 | * CPUID levels like 0x6, 0xA etc, word 7. | ||
185 | * | ||
186 | * Reuse free bits when adding new feature flags! | ||
187 | */ | ||
188 | |||
189 | #define X86_FEATURE_CPB ( 7*32+ 2) /* AMD Core Performance Boost */ | ||
190 | #define X86_FEATURE_EPB ( 7*32+ 3) /* IA32_ENERGY_PERF_BIAS support */ | ||
191 | |||
192 | #define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */ | ||
193 | #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ | ||
194 | |||
195 | #define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */ | ||
196 | |||
197 | /* Virtualization flags: Linux defined, word 8 */ | ||
198 | #define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */ | ||
199 | #define X86_FEATURE_VNMI ( 8*32+ 1) /* Intel Virtual NMI */ | ||
200 | #define X86_FEATURE_FLEXPRIORITY ( 8*32+ 2) /* Intel FlexPriority */ | ||
201 | #define X86_FEATURE_EPT ( 8*32+ 3) /* Intel Extended Page Table */ | ||
202 | #define X86_FEATURE_VPID ( 8*32+ 4) /* Intel Virtual Processor ID */ | ||
203 | |||
204 | #define X86_FEATURE_VMMCALL ( 8*32+15) /* Prefer vmmcall to vmcall */ | ||
205 | #define X86_FEATURE_XENPV ( 8*32+16) /* "" Xen paravirtual guest */ | ||
206 | |||
207 | |||
208 | /* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */ | ||
209 | #define X86_FEATURE_FSGSBASE ( 9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/ | ||
210 | #define X86_FEATURE_TSC_ADJUST ( 9*32+ 1) /* TSC adjustment MSR 0x3b */ | ||
211 | #define X86_FEATURE_BMI1 ( 9*32+ 3) /* 1st group bit manipulation extensions */ | ||
212 | #define X86_FEATURE_HLE ( 9*32+ 4) /* Hardware Lock Elision */ | ||
213 | #define X86_FEATURE_AVX2 ( 9*32+ 5) /* AVX2 instructions */ | ||
214 | #define X86_FEATURE_SMEP ( 9*32+ 7) /* Supervisor Mode Execution Protection */ | ||
215 | #define X86_FEATURE_BMI2 ( 9*32+ 8) /* 2nd group bit manipulation extensions */ | ||
216 | #define X86_FEATURE_ERMS ( 9*32+ 9) /* Enhanced REP MOVSB/STOSB */ | ||
217 | #define X86_FEATURE_INVPCID ( 9*32+10) /* Invalidate Processor Context ID */ | ||
218 | #define X86_FEATURE_RTM ( 9*32+11) /* Restricted Transactional Memory */ | ||
219 | #define X86_FEATURE_CQM ( 9*32+12) /* Cache QoS Monitoring */ | ||
220 | #define X86_FEATURE_MPX ( 9*32+14) /* Memory Protection Extension */ | ||
221 | #define X86_FEATURE_AVX512F ( 9*32+16) /* AVX-512 Foundation */ | ||
222 | #define X86_FEATURE_RDSEED ( 9*32+18) /* The RDSEED instruction */ | ||
223 | #define X86_FEATURE_ADX ( 9*32+19) /* The ADCX and ADOX instructions */ | ||
224 | #define X86_FEATURE_SMAP ( 9*32+20) /* Supervisor Mode Access Prevention */ | ||
225 | #define X86_FEATURE_PCOMMIT ( 9*32+22) /* PCOMMIT instruction */ | ||
226 | #define X86_FEATURE_CLFLUSHOPT ( 9*32+23) /* CLFLUSHOPT instruction */ | ||
227 | #define X86_FEATURE_CLWB ( 9*32+24) /* CLWB instruction */ | ||
228 | #define X86_FEATURE_AVX512PF ( 9*32+26) /* AVX-512 Prefetch */ | ||
229 | #define X86_FEATURE_AVX512ER ( 9*32+27) /* AVX-512 Exponential and Reciprocal */ | ||
230 | #define X86_FEATURE_AVX512CD ( 9*32+28) /* AVX-512 Conflict Detection */ | ||
231 | #define X86_FEATURE_SHA_NI ( 9*32+29) /* SHA1/SHA256 Instruction Extensions */ | ||
232 | |||
233 | /* Extended state features, CPUID level 0x0000000d:1 (eax), word 10 */ | ||
234 | #define X86_FEATURE_XSAVEOPT (10*32+ 0) /* XSAVEOPT */ | ||
235 | #define X86_FEATURE_XSAVEC (10*32+ 1) /* XSAVEC */ | ||
236 | #define X86_FEATURE_XGETBV1 (10*32+ 2) /* XGETBV with ECX = 1 */ | ||
237 | #define X86_FEATURE_XSAVES (10*32+ 3) /* XSAVES/XRSTORS */ | ||
238 | |||
239 | /* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:0 (edx), word 11 */ | ||
240 | #define X86_FEATURE_CQM_LLC (11*32+ 1) /* LLC QoS if 1 */ | ||
241 | |||
242 | /* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:1 (edx), word 12 */ | ||
243 | #define X86_FEATURE_CQM_OCCUP_LLC (12*32+ 0) /* LLC occupancy monitoring if 1 */ | ||
244 | |||
245 | /* AMD-defined CPU features, CPUID level 0x80000008 (ebx), word 13 */ | ||
246 | #define X86_FEATURE_CLZERO (13*32+0) /* CLZERO instruction */ | ||
247 | |||
248 | /* Thermal and Power Management Leaf, CPUID level 0x00000006 (eax), word 14 */ | ||
249 | #define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */ | ||
250 | #define X86_FEATURE_IDA (14*32+ 1) /* Intel Dynamic Acceleration */ | ||
251 | #define X86_FEATURE_ARAT (14*32+ 2) /* Always Running APIC Timer */ | ||
252 | #define X86_FEATURE_PLN (14*32+ 4) /* Intel Power Limit Notification */ | ||
253 | #define X86_FEATURE_PTS (14*32+ 6) /* Intel Package Thermal Status */ | ||
254 | #define X86_FEATURE_HWP (14*32+ 7) /* Intel Hardware P-states */ | ||
255 | #define X86_FEATURE_HWP_NOTIFY (14*32+ 8) /* HWP Notification */ | ||
256 | #define X86_FEATURE_HWP_ACT_WINDOW (14*32+ 9) /* HWP Activity Window */ | ||
257 | #define X86_FEATURE_HWP_EPP (14*32+10) /* HWP Energy Perf. Preference */ | ||
258 | #define X86_FEATURE_HWP_PKG_REQ (14*32+11) /* HWP Package Level Request */ | ||
259 | |||
260 | /* AMD SVM Feature Identification, CPUID level 0x8000000a (edx), word 15 */ | ||
261 | #define X86_FEATURE_NPT (15*32+ 0) /* Nested Page Table support */ | ||
262 | #define X86_FEATURE_LBRV (15*32+ 1) /* LBR Virtualization support */ | ||
263 | #define X86_FEATURE_SVML (15*32+ 2) /* "svm_lock" SVM locking MSR */ | ||
264 | #define X86_FEATURE_NRIPS (15*32+ 3) /* "nrip_save" SVM next_rip save */ | ||
265 | #define X86_FEATURE_TSCRATEMSR (15*32+ 4) /* "tsc_scale" TSC scaling support */ | ||
266 | #define X86_FEATURE_VMCBCLEAN (15*32+ 5) /* "vmcb_clean" VMCB clean bits support */ | ||
267 | #define X86_FEATURE_FLUSHBYASID (15*32+ 6) /* flush-by-ASID support */ | ||
268 | #define X86_FEATURE_DECODEASSISTS (15*32+ 7) /* Decode Assists support */ | ||
269 | #define X86_FEATURE_PAUSEFILTER (15*32+10) /* filtered pause intercept */ | ||
270 | #define X86_FEATURE_PFTHRESHOLD (15*32+12) /* pause filter threshold */ | ||
271 | |||
272 | /* | ||
273 | * BUG word(s) | ||
274 | */ | ||
275 | #define X86_BUG(x) (NCAPINTS*32 + (x)) | ||
276 | |||
277 | #define X86_BUG_F00F X86_BUG(0) /* Intel F00F */ | ||
278 | #define X86_BUG_FDIV X86_BUG(1) /* FPU FDIV */ | ||
279 | #define X86_BUG_COMA X86_BUG(2) /* Cyrix 6x86 coma */ | ||
280 | #define X86_BUG_AMD_TLB_MMATCH X86_BUG(3) /* "tlb_mmatch" AMD Erratum 383 */ | ||
281 | #define X86_BUG_AMD_APIC_C1E X86_BUG(4) /* "apic_c1e" AMD Erratum 400 */ | ||
282 | #define X86_BUG_11AP X86_BUG(5) /* Bad local APIC aka 11AP */ | ||
283 | #define X86_BUG_FXSAVE_LEAK X86_BUG(6) /* FXSAVE leaks FOP/FIP/FOP */ | ||
284 | #define X86_BUG_CLFLUSH_MONITOR X86_BUG(7) /* AAI65, CLFLUSH required before MONITOR */ | ||
285 | #define X86_BUG_SYSRET_SS_ATTRS X86_BUG(8) /* SYSRET doesn't fix up SS attrs */ | ||
286 | 5 | ||
287 | #if defined(__KERNEL__) && !defined(__ASSEMBLY__) | 6 | #if defined(__KERNEL__) && !defined(__ASSEMBLY__) |
288 | 7 | ||
@@ -369,8 +88,7 @@ extern const char * const x86_bug_flags[NBUGINTS*32]; | |||
369 | * is not relevant. | 88 | * is not relevant. |
370 | */ | 89 | */ |
371 | #define cpu_feature_enabled(bit) \ | 90 | #define cpu_feature_enabled(bit) \ |
372 | (__builtin_constant_p(bit) && DISABLED_MASK_BIT_SET(bit) ? 0 : \ | 91 | (__builtin_constant_p(bit) && DISABLED_MASK_BIT_SET(bit) ? 0 : static_cpu_has(bit)) |
373 | cpu_has(&boot_cpu_data, bit)) | ||
374 | 92 | ||
375 | #define boot_cpu_has(bit) cpu_has(&boot_cpu_data, bit) | 93 | #define boot_cpu_has(bit) cpu_has(&boot_cpu_data, bit) |
376 | 94 | ||
@@ -406,106 +124,19 @@ extern const char * const x86_bug_flags[NBUGINTS*32]; | |||
406 | #define cpu_has_osxsave boot_cpu_has(X86_FEATURE_OSXSAVE) | 124 | #define cpu_has_osxsave boot_cpu_has(X86_FEATURE_OSXSAVE) |
407 | #define cpu_has_hypervisor boot_cpu_has(X86_FEATURE_HYPERVISOR) | 125 | #define cpu_has_hypervisor boot_cpu_has(X86_FEATURE_HYPERVISOR) |
408 | /* | 126 | /* |
409 | * Do not add any more of those clumsy macros - use static_cpu_has_safe() for | 127 | * Do not add any more of those clumsy macros - use static_cpu_has() for |
410 | * fast paths and boot_cpu_has() otherwise! | 128 | * fast paths and boot_cpu_has() otherwise! |
411 | */ | 129 | */ |
412 | 130 | ||
413 | #if __GNUC__ >= 4 && defined(CONFIG_X86_FAST_FEATURE_TESTS) | 131 | #if defined(CC_HAVE_ASM_GOTO) && defined(CONFIG_X86_FAST_FEATURE_TESTS) |
414 | extern void warn_pre_alternatives(void); | ||
415 | extern bool __static_cpu_has_safe(u16 bit); | ||
416 | |||
417 | /* | 132 | /* |
418 | * Static testing of CPU features. Used the same as boot_cpu_has(). | 133 | * Static testing of CPU features. Used the same as boot_cpu_has(). |
419 | * These are only valid after alternatives have run, but will statically | 134 | * These will statically patch the target code for additional |
420 | * patch the target code for additional performance. | 135 | * performance. |
421 | */ | 136 | */ |
422 | static __always_inline __pure bool __static_cpu_has(u16 bit) | 137 | static __always_inline __pure bool _static_cpu_has(u16 bit) |
423 | { | ||
424 | #ifdef CC_HAVE_ASM_GOTO | ||
425 | |||
426 | #ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS | ||
427 | |||
428 | /* | ||
429 | * Catch too early usage of this before alternatives | ||
430 | * have run. | ||
431 | */ | ||
432 | asm_volatile_goto("1: jmp %l[t_warn]\n" | ||
433 | "2:\n" | ||
434 | ".section .altinstructions,\"a\"\n" | ||
435 | " .long 1b - .\n" | ||
436 | " .long 0\n" /* no replacement */ | ||
437 | " .word %P0\n" /* 1: do replace */ | ||
438 | " .byte 2b - 1b\n" /* source len */ | ||
439 | " .byte 0\n" /* replacement len */ | ||
440 | " .byte 0\n" /* pad len */ | ||
441 | ".previous\n" | ||
442 | /* skipping size check since replacement size = 0 */ | ||
443 | : : "i" (X86_FEATURE_ALWAYS) : : t_warn); | ||
444 | |||
445 | #endif | ||
446 | |||
447 | asm_volatile_goto("1: jmp %l[t_no]\n" | ||
448 | "2:\n" | ||
449 | ".section .altinstructions,\"a\"\n" | ||
450 | " .long 1b - .\n" | ||
451 | " .long 0\n" /* no replacement */ | ||
452 | " .word %P0\n" /* feature bit */ | ||
453 | " .byte 2b - 1b\n" /* source len */ | ||
454 | " .byte 0\n" /* replacement len */ | ||
455 | " .byte 0\n" /* pad len */ | ||
456 | ".previous\n" | ||
457 | /* skipping size check since replacement size = 0 */ | ||
458 | : : "i" (bit) : : t_no); | ||
459 | return true; | ||
460 | t_no: | ||
461 | return false; | ||
462 | |||
463 | #ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS | ||
464 | t_warn: | ||
465 | warn_pre_alternatives(); | ||
466 | return false; | ||
467 | #endif | ||
468 | |||
469 | #else /* CC_HAVE_ASM_GOTO */ | ||
470 | |||
471 | u8 flag; | ||
472 | /* Open-coded due to __stringify() in ALTERNATIVE() */ | ||
473 | asm volatile("1: movb $0,%0\n" | ||
474 | "2:\n" | ||
475 | ".section .altinstructions,\"a\"\n" | ||
476 | " .long 1b - .\n" | ||
477 | " .long 3f - .\n" | ||
478 | " .word %P1\n" /* feature bit */ | ||
479 | " .byte 2b - 1b\n" /* source len */ | ||
480 | " .byte 4f - 3f\n" /* replacement len */ | ||
481 | " .byte 0\n" /* pad len */ | ||
482 | ".previous\n" | ||
483 | ".section .discard,\"aw\",@progbits\n" | ||
484 | " .byte 0xff + (4f-3f) - (2b-1b)\n" /* size check */ | ||
485 | ".previous\n" | ||
486 | ".section .altinstr_replacement,\"ax\"\n" | ||
487 | "3: movb $1,%0\n" | ||
488 | "4:\n" | ||
489 | ".previous\n" | ||
490 | : "=qm" (flag) : "i" (bit)); | ||
491 | return flag; | ||
492 | |||
493 | #endif /* CC_HAVE_ASM_GOTO */ | ||
494 | } | ||
495 | |||
496 | #define static_cpu_has(bit) \ | ||
497 | ( \ | ||
498 | __builtin_constant_p(boot_cpu_has(bit)) ? \ | ||
499 | boot_cpu_has(bit) : \ | ||
500 | __builtin_constant_p(bit) ? \ | ||
501 | __static_cpu_has(bit) : \ | ||
502 | boot_cpu_has(bit) \ | ||
503 | ) | ||
504 | |||
505 | static __always_inline __pure bool _static_cpu_has_safe(u16 bit) | ||
506 | { | 138 | { |
507 | #ifdef CC_HAVE_ASM_GOTO | 139 | asm_volatile_goto("1: jmp 6f\n" |
508 | asm_volatile_goto("1: jmp %l[t_dynamic]\n" | ||
509 | "2:\n" | 140 | "2:\n" |
510 | ".skip -(((5f-4f) - (2b-1b)) > 0) * " | 141 | ".skip -(((5f-4f) - (2b-1b)) > 0) * " |
511 | "((5f-4f) - (2b-1b)),0x90\n" | 142 | "((5f-4f) - (2b-1b)),0x90\n" |
@@ -530,66 +161,34 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit) | |||
530 | " .byte 0\n" /* repl len */ | 161 | " .byte 0\n" /* repl len */ |
531 | " .byte 0\n" /* pad len */ | 162 | " .byte 0\n" /* pad len */ |
532 | ".previous\n" | 163 | ".previous\n" |
533 | : : "i" (bit), "i" (X86_FEATURE_ALWAYS) | 164 | ".section .altinstr_aux,\"ax\"\n" |
534 | : : t_dynamic, t_no); | 165 | "6:\n" |
166 | " testb %[bitnum],%[cap_byte]\n" | ||
167 | " jnz %l[t_yes]\n" | ||
168 | " jmp %l[t_no]\n" | ||
169 | ".previous\n" | ||
170 | : : "i" (bit), "i" (X86_FEATURE_ALWAYS), | ||
171 | [bitnum] "i" (1 << (bit & 7)), | ||
172 | [cap_byte] "m" (((const char *)boot_cpu_data.x86_capability)[bit >> 3]) | ||
173 | : : t_yes, t_no); | ||
174 | t_yes: | ||
535 | return true; | 175 | return true; |
536 | t_no: | 176 | t_no: |
537 | return false; | 177 | return false; |
538 | t_dynamic: | ||
539 | return __static_cpu_has_safe(bit); | ||
540 | #else | ||
541 | u8 flag; | ||
542 | /* Open-coded due to __stringify() in ALTERNATIVE() */ | ||
543 | asm volatile("1: movb $2,%0\n" | ||
544 | "2:\n" | ||
545 | ".section .altinstructions,\"a\"\n" | ||
546 | " .long 1b - .\n" /* src offset */ | ||
547 | " .long 3f - .\n" /* repl offset */ | ||
548 | " .word %P2\n" /* always replace */ | ||
549 | " .byte 2b - 1b\n" /* source len */ | ||
550 | " .byte 4f - 3f\n" /* replacement len */ | ||
551 | " .byte 0\n" /* pad len */ | ||
552 | ".previous\n" | ||
553 | ".section .discard,\"aw\",@progbits\n" | ||
554 | " .byte 0xff + (4f-3f) - (2b-1b)\n" /* size check */ | ||
555 | ".previous\n" | ||
556 | ".section .altinstr_replacement,\"ax\"\n" | ||
557 | "3: movb $0,%0\n" | ||
558 | "4:\n" | ||
559 | ".previous\n" | ||
560 | ".section .altinstructions,\"a\"\n" | ||
561 | " .long 1b - .\n" /* src offset */ | ||
562 | " .long 5f - .\n" /* repl offset */ | ||
563 | " .word %P1\n" /* feature bit */ | ||
564 | " .byte 4b - 3b\n" /* src len */ | ||
565 | " .byte 6f - 5f\n" /* repl len */ | ||
566 | " .byte 0\n" /* pad len */ | ||
567 | ".previous\n" | ||
568 | ".section .discard,\"aw\",@progbits\n" | ||
569 | " .byte 0xff + (6f-5f) - (4b-3b)\n" /* size check */ | ||
570 | ".previous\n" | ||
571 | ".section .altinstr_replacement,\"ax\"\n" | ||
572 | "5: movb $1,%0\n" | ||
573 | "6:\n" | ||
574 | ".previous\n" | ||
575 | : "=qm" (flag) | ||
576 | : "i" (bit), "i" (X86_FEATURE_ALWAYS)); | ||
577 | return (flag == 2 ? __static_cpu_has_safe(bit) : flag); | ||
578 | #endif /* CC_HAVE_ASM_GOTO */ | ||
579 | } | 178 | } |
580 | 179 | ||
581 | #define static_cpu_has_safe(bit) \ | 180 | #define static_cpu_has(bit) \ |
582 | ( \ | 181 | ( \ |
583 | __builtin_constant_p(boot_cpu_has(bit)) ? \ | 182 | __builtin_constant_p(boot_cpu_has(bit)) ? \ |
584 | boot_cpu_has(bit) : \ | 183 | boot_cpu_has(bit) : \ |
585 | _static_cpu_has_safe(bit) \ | 184 | _static_cpu_has(bit) \ |
586 | ) | 185 | ) |
587 | #else | 186 | #else |
588 | /* | 187 | /* |
589 | * gcc 3.x is too stupid to do the static test; fall back to dynamic. | 188 | * Fall back to dynamic for gcc versions which don't support asm goto. Should be |
189 | * a minority now anyway. | ||
590 | */ | 190 | */ |
591 | #define static_cpu_has(bit) boot_cpu_has(bit) | 191 | #define static_cpu_has(bit) boot_cpu_has(bit) |
592 | #define static_cpu_has_safe(bit) boot_cpu_has(bit) | ||
593 | #endif | 192 | #endif |
594 | 193 | ||
595 | #define cpu_has_bug(c, bit) cpu_has(c, (bit)) | 194 | #define cpu_has_bug(c, bit) cpu_has(c, (bit)) |
@@ -597,7 +196,6 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit) | |||
597 | #define clear_cpu_bug(c, bit) clear_cpu_cap(c, (bit)) | 196 | #define clear_cpu_bug(c, bit) clear_cpu_cap(c, (bit)) |
598 | 197 | ||
599 | #define static_cpu_has_bug(bit) static_cpu_has((bit)) | 198 | #define static_cpu_has_bug(bit) static_cpu_has((bit)) |
600 | #define static_cpu_has_bug_safe(bit) static_cpu_has_safe((bit)) | ||
601 | #define boot_cpu_has_bug(bit) cpu_has_bug(&boot_cpu_data, (bit)) | 199 | #define boot_cpu_has_bug(bit) cpu_has_bug(&boot_cpu_data, (bit)) |
602 | 200 | ||
603 | #define MAX_CPU_FEATURES (NCAPINTS * 32) | 201 | #define MAX_CPU_FEATURES (NCAPINTS * 32) |
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h new file mode 100644 index 000000000000..6663fae71b12 --- /dev/null +++ b/arch/x86/include/asm/cpufeatures.h | |||
@@ -0,0 +1,289 @@ | |||
1 | #ifndef _ASM_X86_CPUFEATURES_H | ||
2 | #define _ASM_X86_CPUFEATURES_H | ||
3 | |||
4 | #ifndef _ASM_X86_REQUIRED_FEATURES_H | ||
5 | #include <asm/required-features.h> | ||
6 | #endif | ||
7 | |||
8 | #ifndef _ASM_X86_DISABLED_FEATURES_H | ||
9 | #include <asm/disabled-features.h> | ||
10 | #endif | ||
11 | |||
12 | /* | ||
13 | * Defines x86 CPU feature bits | ||
14 | */ | ||
15 | #define NCAPINTS 16 /* N 32-bit words worth of info */ | ||
16 | #define NBUGINTS 1 /* N 32-bit bug flags */ | ||
17 | |||
18 | /* | ||
19 | * Note: If the comment begins with a quoted string, that string is used | ||
20 | * in /proc/cpuinfo instead of the macro name. If the string is "", | ||
21 | * this feature bit is not displayed in /proc/cpuinfo at all. | ||
22 | */ | ||
23 | |||
24 | /* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */ | ||
25 | #define X86_FEATURE_FPU ( 0*32+ 0) /* Onboard FPU */ | ||
26 | #define X86_FEATURE_VME ( 0*32+ 1) /* Virtual Mode Extensions */ | ||
27 | #define X86_FEATURE_DE ( 0*32+ 2) /* Debugging Extensions */ | ||
28 | #define X86_FEATURE_PSE ( 0*32+ 3) /* Page Size Extensions */ | ||
29 | #define X86_FEATURE_TSC ( 0*32+ 4) /* Time Stamp Counter */ | ||
30 | #define X86_FEATURE_MSR ( 0*32+ 5) /* Model-Specific Registers */ | ||
31 | #define X86_FEATURE_PAE ( 0*32+ 6) /* Physical Address Extensions */ | ||
32 | #define X86_FEATURE_MCE ( 0*32+ 7) /* Machine Check Exception */ | ||
33 | #define X86_FEATURE_CX8 ( 0*32+ 8) /* CMPXCHG8 instruction */ | ||
34 | #define X86_FEATURE_APIC ( 0*32+ 9) /* Onboard APIC */ | ||
35 | #define X86_FEATURE_SEP ( 0*32+11) /* SYSENTER/SYSEXIT */ | ||
36 | #define X86_FEATURE_MTRR ( 0*32+12) /* Memory Type Range Registers */ | ||
37 | #define X86_FEATURE_PGE ( 0*32+13) /* Page Global Enable */ | ||
38 | #define X86_FEATURE_MCA ( 0*32+14) /* Machine Check Architecture */ | ||
39 | #define X86_FEATURE_CMOV ( 0*32+15) /* CMOV instructions */ | ||
40 | /* (plus FCMOVcc, FCOMI with FPU) */ | ||
41 | #define X86_FEATURE_PAT ( 0*32+16) /* Page Attribute Table */ | ||
42 | #define X86_FEATURE_PSE36 ( 0*32+17) /* 36-bit PSEs */ | ||
43 | #define X86_FEATURE_PN ( 0*32+18) /* Processor serial number */ | ||
44 | #define X86_FEATURE_CLFLUSH ( 0*32+19) /* CLFLUSH instruction */ | ||
45 | #define X86_FEATURE_DS ( 0*32+21) /* "dts" Debug Store */ | ||
46 | #define X86_FEATURE_ACPI ( 0*32+22) /* ACPI via MSR */ | ||
47 | #define X86_FEATURE_MMX ( 0*32+23) /* Multimedia Extensions */ | ||
48 | #define X86_FEATURE_FXSR ( 0*32+24) /* FXSAVE/FXRSTOR, CR4.OSFXSR */ | ||
49 | #define X86_FEATURE_XMM ( 0*32+25) /* "sse" */ | ||
50 | #define X86_FEATURE_XMM2 ( 0*32+26) /* "sse2" */ | ||
51 | #define X86_FEATURE_SELFSNOOP ( 0*32+27) /* "ss" CPU self snoop */ | ||
52 | #define X86_FEATURE_HT ( 0*32+28) /* Hyper-Threading */ | ||
53 | #define X86_FEATURE_ACC ( 0*32+29) /* "tm" Automatic clock control */ | ||
54 | #define X86_FEATURE_IA64 ( 0*32+30) /* IA-64 processor */ | ||
55 | #define X86_FEATURE_PBE ( 0*32+31) /* Pending Break Enable */ | ||
56 | |||
57 | /* AMD-defined CPU features, CPUID level 0x80000001, word 1 */ | ||
58 | /* Don't duplicate feature flags which are redundant with Intel! */ | ||
59 | #define X86_FEATURE_SYSCALL ( 1*32+11) /* SYSCALL/SYSRET */ | ||
60 | #define X86_FEATURE_MP ( 1*32+19) /* MP Capable. */ | ||
61 | #define X86_FEATURE_NX ( 1*32+20) /* Execute Disable */ | ||
62 | #define X86_FEATURE_MMXEXT ( 1*32+22) /* AMD MMX extensions */ | ||
63 | #define X86_FEATURE_FXSR_OPT ( 1*32+25) /* FXSAVE/FXRSTOR optimizations */ | ||
64 | #define X86_FEATURE_GBPAGES ( 1*32+26) /* "pdpe1gb" GB pages */ | ||
65 | #define X86_FEATURE_RDTSCP ( 1*32+27) /* RDTSCP */ | ||
66 | #define X86_FEATURE_LM ( 1*32+29) /* Long Mode (x86-64) */ | ||
67 | #define X86_FEATURE_3DNOWEXT ( 1*32+30) /* AMD 3DNow! extensions */ | ||
68 | #define X86_FEATURE_3DNOW ( 1*32+31) /* 3DNow! */ | ||
69 | |||
70 | /* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */ | ||
71 | #define X86_FEATURE_RECOVERY ( 2*32+ 0) /* CPU in recovery mode */ | ||
72 | #define X86_FEATURE_LONGRUN ( 2*32+ 1) /* Longrun power control */ | ||
73 | #define X86_FEATURE_LRTI ( 2*32+ 3) /* LongRun table interface */ | ||
74 | |||
75 | /* Other features, Linux-defined mapping, word 3 */ | ||
76 | /* This range is used for feature bits which conflict or are synthesized */ | ||
77 | #define X86_FEATURE_CXMMX ( 3*32+ 0) /* Cyrix MMX extensions */ | ||
78 | #define X86_FEATURE_K6_MTRR ( 3*32+ 1) /* AMD K6 nonstandard MTRRs */ | ||
79 | #define X86_FEATURE_CYRIX_ARR ( 3*32+ 2) /* Cyrix ARRs (= MTRRs) */ | ||
80 | #define X86_FEATURE_CENTAUR_MCR ( 3*32+ 3) /* Centaur MCRs (= MTRRs) */ | ||
81 | /* cpu types for specific tunings: */ | ||
82 | #define X86_FEATURE_K8 ( 3*32+ 4) /* "" Opteron, Athlon64 */ | ||
83 | #define X86_FEATURE_K7 ( 3*32+ 5) /* "" Athlon */ | ||
84 | #define X86_FEATURE_P3 ( 3*32+ 6) /* "" P3 */ | ||
85 | #define X86_FEATURE_P4 ( 3*32+ 7) /* "" P4 */ | ||
86 | #define X86_FEATURE_CONSTANT_TSC ( 3*32+ 8) /* TSC ticks at a constant rate */ | ||
87 | #define X86_FEATURE_UP ( 3*32+ 9) /* smp kernel running on up */ | ||
88 | /* free, was #define X86_FEATURE_FXSAVE_LEAK ( 3*32+10) * "" FXSAVE leaks FOP/FIP/FOP */ | ||
89 | #define X86_FEATURE_ARCH_PERFMON ( 3*32+11) /* Intel Architectural PerfMon */ | ||
90 | #define X86_FEATURE_PEBS ( 3*32+12) /* Precise-Event Based Sampling */ | ||
91 | #define X86_FEATURE_BTS ( 3*32+13) /* Branch Trace Store */ | ||
92 | #define X86_FEATURE_SYSCALL32 ( 3*32+14) /* "" syscall in ia32 userspace */ | ||
93 | #define X86_FEATURE_SYSENTER32 ( 3*32+15) /* "" sysenter in ia32 userspace */ | ||
94 | #define X86_FEATURE_REP_GOOD ( 3*32+16) /* rep microcode works well */ | ||
95 | #define X86_FEATURE_MFENCE_RDTSC ( 3*32+17) /* "" Mfence synchronizes RDTSC */ | ||
96 | #define X86_FEATURE_LFENCE_RDTSC ( 3*32+18) /* "" Lfence synchronizes RDTSC */ | ||
97 | /* free, was #define X86_FEATURE_11AP ( 3*32+19) * "" Bad local APIC aka 11AP */ | ||
98 | #define X86_FEATURE_NOPL ( 3*32+20) /* The NOPL (0F 1F) instructions */ | ||
99 | #define X86_FEATURE_ALWAYS ( 3*32+21) /* "" Always-present feature */ | ||
100 | #define X86_FEATURE_XTOPOLOGY ( 3*32+22) /* cpu topology enum extensions */ | ||
101 | #define X86_FEATURE_TSC_RELIABLE ( 3*32+23) /* TSC is known to be reliable */ | ||
102 | #define X86_FEATURE_NONSTOP_TSC ( 3*32+24) /* TSC does not stop in C states */ | ||
103 | /* free, was #define X86_FEATURE_CLFLUSH_MONITOR ( 3*32+25) * "" clflush reqd with monitor */ | ||
104 | #define X86_FEATURE_EXTD_APICID ( 3*32+26) /* has extended APICID (8 bits) */ | ||
105 | #define X86_FEATURE_AMD_DCM ( 3*32+27) /* multi-node processor */ | ||
106 | #define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */ | ||
107 | #define X86_FEATURE_EAGER_FPU ( 3*32+29) /* "eagerfpu" Non lazy FPU restore */ | ||
108 | #define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */ | ||
109 | #define X86_FEATURE_MCE_RECOVERY ( 3*32+31) /* cpu has recoverable machine checks */ | ||
110 | |||
111 | /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ | ||
112 | #define X86_FEATURE_XMM3 ( 4*32+ 0) /* "pni" SSE-3 */ | ||
113 | #define X86_FEATURE_PCLMULQDQ ( 4*32+ 1) /* PCLMULQDQ instruction */ | ||
114 | #define X86_FEATURE_DTES64 ( 4*32+ 2) /* 64-bit Debug Store */ | ||
115 | #define X86_FEATURE_MWAIT ( 4*32+ 3) /* "monitor" Monitor/Mwait support */ | ||
116 | #define X86_FEATURE_DSCPL ( 4*32+ 4) /* "ds_cpl" CPL Qual. Debug Store */ | ||
117 | #define X86_FEATURE_VMX ( 4*32+ 5) /* Hardware virtualization */ | ||
118 | #define X86_FEATURE_SMX ( 4*32+ 6) /* Safer mode */ | ||
119 | #define X86_FEATURE_EST ( 4*32+ 7) /* Enhanced SpeedStep */ | ||
120 | #define X86_FEATURE_TM2 ( 4*32+ 8) /* Thermal Monitor 2 */ | ||
121 | #define X86_FEATURE_SSSE3 ( 4*32+ 9) /* Supplemental SSE-3 */ | ||
122 | #define X86_FEATURE_CID ( 4*32+10) /* Context ID */ | ||
123 | #define X86_FEATURE_SDBG ( 4*32+11) /* Silicon Debug */ | ||
124 | #define X86_FEATURE_FMA ( 4*32+12) /* Fused multiply-add */ | ||
125 | #define X86_FEATURE_CX16 ( 4*32+13) /* CMPXCHG16B */ | ||
126 | #define X86_FEATURE_XTPR ( 4*32+14) /* Send Task Priority Messages */ | ||
127 | #define X86_FEATURE_PDCM ( 4*32+15) /* Performance Capabilities */ | ||
128 | #define X86_FEATURE_PCID ( 4*32+17) /* Process Context Identifiers */ | ||
129 | #define X86_FEATURE_DCA ( 4*32+18) /* Direct Cache Access */ | ||
130 | #define X86_FEATURE_XMM4_1 ( 4*32+19) /* "sse4_1" SSE-4.1 */ | ||
131 | #define X86_FEATURE_XMM4_2 ( 4*32+20) /* "sse4_2" SSE-4.2 */ | ||
132 | #define X86_FEATURE_X2APIC ( 4*32+21) /* x2APIC */ | ||
133 | #define X86_FEATURE_MOVBE ( 4*32+22) /* MOVBE instruction */ | ||
134 | #define X86_FEATURE_POPCNT ( 4*32+23) /* POPCNT instruction */ | ||
135 | #define X86_FEATURE_TSC_DEADLINE_TIMER ( 4*32+24) /* Tsc deadline timer */ | ||
136 | #define X86_FEATURE_AES ( 4*32+25) /* AES instructions */ | ||
137 | #define X86_FEATURE_XSAVE ( 4*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV */ | ||
138 | #define X86_FEATURE_OSXSAVE ( 4*32+27) /* "" XSAVE enabled in the OS */ | ||
139 | #define X86_FEATURE_AVX ( 4*32+28) /* Advanced Vector Extensions */ | ||
140 | #define X86_FEATURE_F16C ( 4*32+29) /* 16-bit fp conversions */ | ||
141 | #define X86_FEATURE_RDRAND ( 4*32+30) /* The RDRAND instruction */ | ||
142 | #define X86_FEATURE_HYPERVISOR ( 4*32+31) /* Running on a hypervisor */ | ||
143 | |||
144 | /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */ | ||
145 | #define X86_FEATURE_XSTORE ( 5*32+ 2) /* "rng" RNG present (xstore) */ | ||
146 | #define X86_FEATURE_XSTORE_EN ( 5*32+ 3) /* "rng_en" RNG enabled */ | ||
147 | #define X86_FEATURE_XCRYPT ( 5*32+ 6) /* "ace" on-CPU crypto (xcrypt) */ | ||
148 | #define X86_FEATURE_XCRYPT_EN ( 5*32+ 7) /* "ace_en" on-CPU crypto enabled */ | ||
149 | #define X86_FEATURE_ACE2 ( 5*32+ 8) /* Advanced Cryptography Engine v2 */ | ||
150 | #define X86_FEATURE_ACE2_EN ( 5*32+ 9) /* ACE v2 enabled */ | ||
151 | #define X86_FEATURE_PHE ( 5*32+10) /* PadLock Hash Engine */ | ||
152 | #define X86_FEATURE_PHE_EN ( 5*32+11) /* PHE enabled */ | ||
153 | #define X86_FEATURE_PMM ( 5*32+12) /* PadLock Montgomery Multiplier */ | ||
154 | #define X86_FEATURE_PMM_EN ( 5*32+13) /* PMM enabled */ | ||
155 | |||
156 | /* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */ | ||
157 | #define X86_FEATURE_LAHF_LM ( 6*32+ 0) /* LAHF/SAHF in long mode */ | ||
158 | #define X86_FEATURE_CMP_LEGACY ( 6*32+ 1) /* If yes HyperThreading not valid */ | ||
159 | #define X86_FEATURE_SVM ( 6*32+ 2) /* Secure virtual machine */ | ||
160 | #define X86_FEATURE_EXTAPIC ( 6*32+ 3) /* Extended APIC space */ | ||
161 | #define X86_FEATURE_CR8_LEGACY ( 6*32+ 4) /* CR8 in 32-bit mode */ | ||
162 | #define X86_FEATURE_ABM ( 6*32+ 5) /* Advanced bit manipulation */ | ||
163 | #define X86_FEATURE_SSE4A ( 6*32+ 6) /* SSE-4A */ | ||
164 | #define X86_FEATURE_MISALIGNSSE ( 6*32+ 7) /* Misaligned SSE mode */ | ||
165 | #define X86_FEATURE_3DNOWPREFETCH ( 6*32+ 8) /* 3DNow prefetch instructions */ | ||
166 | #define X86_FEATURE_OSVW ( 6*32+ 9) /* OS Visible Workaround */ | ||
167 | #define X86_FEATURE_IBS ( 6*32+10) /* Instruction Based Sampling */ | ||
168 | #define X86_FEATURE_XOP ( 6*32+11) /* extended AVX instructions */ | ||
169 | #define X86_FEATURE_SKINIT ( 6*32+12) /* SKINIT/STGI instructions */ | ||
170 | #define X86_FEATURE_WDT ( 6*32+13) /* Watchdog timer */ | ||
171 | #define X86_FEATURE_LWP ( 6*32+15) /* Light Weight Profiling */ | ||
172 | #define X86_FEATURE_FMA4 ( 6*32+16) /* 4 operands MAC instructions */ | ||
173 | #define X86_FEATURE_TCE ( 6*32+17) /* translation cache extension */ | ||
174 | #define X86_FEATURE_NODEID_MSR ( 6*32+19) /* NodeId MSR */ | ||
175 | #define X86_FEATURE_TBM ( 6*32+21) /* trailing bit manipulations */ | ||
176 | #define X86_FEATURE_TOPOEXT ( 6*32+22) /* topology extensions CPUID leafs */ | ||
177 | #define X86_FEATURE_PERFCTR_CORE ( 6*32+23) /* core performance counter extensions */ | ||
178 | #define X86_FEATURE_PERFCTR_NB ( 6*32+24) /* NB performance counter extensions */ | ||
179 | #define X86_FEATURE_BPEXT (6*32+26) /* data breakpoint extension */ | ||
180 | #define X86_FEATURE_PERFCTR_L2 ( 6*32+28) /* L2 performance counter extensions */ | ||
181 | #define X86_FEATURE_MWAITX ( 6*32+29) /* MWAIT extension (MONITORX/MWAITX) */ | ||
182 | |||
183 | /* | ||
184 | * Auxiliary flags: Linux defined - For features scattered in various | ||
185 | * CPUID levels like 0x6, 0xA etc, word 7. | ||
186 | * | ||
187 | * Reuse free bits when adding new feature flags! | ||
188 | */ | ||
189 | |||
190 | #define X86_FEATURE_CPB ( 7*32+ 2) /* AMD Core Performance Boost */ | ||
191 | #define X86_FEATURE_EPB ( 7*32+ 3) /* IA32_ENERGY_PERF_BIAS support */ | ||
192 | |||
193 | #define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */ | ||
194 | #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ | ||
195 | |||
196 | #define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */ | ||
197 | |||
198 | /* Virtualization flags: Linux defined, word 8 */ | ||
199 | #define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */ | ||
200 | #define X86_FEATURE_VNMI ( 8*32+ 1) /* Intel Virtual NMI */ | ||
201 | #define X86_FEATURE_FLEXPRIORITY ( 8*32+ 2) /* Intel FlexPriority */ | ||
202 | #define X86_FEATURE_EPT ( 8*32+ 3) /* Intel Extended Page Table */ | ||
203 | #define X86_FEATURE_VPID ( 8*32+ 4) /* Intel Virtual Processor ID */ | ||
204 | |||
205 | #define X86_FEATURE_VMMCALL ( 8*32+15) /* Prefer vmmcall to vmcall */ | ||
206 | #define X86_FEATURE_XENPV ( 8*32+16) /* "" Xen paravirtual guest */ | ||
207 | |||
208 | |||
209 | /* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */ | ||
210 | #define X86_FEATURE_FSGSBASE ( 9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/ | ||
211 | #define X86_FEATURE_TSC_ADJUST ( 9*32+ 1) /* TSC adjustment MSR 0x3b */ | ||
212 | #define X86_FEATURE_BMI1 ( 9*32+ 3) /* 1st group bit manipulation extensions */ | ||
213 | #define X86_FEATURE_HLE ( 9*32+ 4) /* Hardware Lock Elision */ | ||
214 | #define X86_FEATURE_AVX2 ( 9*32+ 5) /* AVX2 instructions */ | ||
215 | #define X86_FEATURE_SMEP ( 9*32+ 7) /* Supervisor Mode Execution Protection */ | ||
216 | #define X86_FEATURE_BMI2 ( 9*32+ 8) /* 2nd group bit manipulation extensions */ | ||
217 | #define X86_FEATURE_ERMS ( 9*32+ 9) /* Enhanced REP MOVSB/STOSB */ | ||
218 | #define X86_FEATURE_INVPCID ( 9*32+10) /* Invalidate Processor Context ID */ | ||
219 | #define X86_FEATURE_RTM ( 9*32+11) /* Restricted Transactional Memory */ | ||
220 | #define X86_FEATURE_CQM ( 9*32+12) /* Cache QoS Monitoring */ | ||
221 | #define X86_FEATURE_MPX ( 9*32+14) /* Memory Protection Extension */ | ||
222 | #define X86_FEATURE_AVX512F ( 9*32+16) /* AVX-512 Foundation */ | ||
223 | #define X86_FEATURE_RDSEED ( 9*32+18) /* The RDSEED instruction */ | ||
224 | #define X86_FEATURE_ADX ( 9*32+19) /* The ADCX and ADOX instructions */ | ||
225 | #define X86_FEATURE_SMAP ( 9*32+20) /* Supervisor Mode Access Prevention */ | ||
226 | #define X86_FEATURE_PCOMMIT ( 9*32+22) /* PCOMMIT instruction */ | ||
227 | #define X86_FEATURE_CLFLUSHOPT ( 9*32+23) /* CLFLUSHOPT instruction */ | ||
228 | #define X86_FEATURE_CLWB ( 9*32+24) /* CLWB instruction */ | ||
229 | #define X86_FEATURE_AVX512PF ( 9*32+26) /* AVX-512 Prefetch */ | ||
230 | #define X86_FEATURE_AVX512ER ( 9*32+27) /* AVX-512 Exponential and Reciprocal */ | ||
231 | #define X86_FEATURE_AVX512CD ( 9*32+28) /* AVX-512 Conflict Detection */ | ||
232 | #define X86_FEATURE_SHA_NI ( 9*32+29) /* SHA1/SHA256 Instruction Extensions */ | ||
233 | |||
234 | /* Extended state features, CPUID level 0x0000000d:1 (eax), word 10 */ | ||
235 | #define X86_FEATURE_XSAVEOPT (10*32+ 0) /* XSAVEOPT */ | ||
236 | #define X86_FEATURE_XSAVEC (10*32+ 1) /* XSAVEC */ | ||
237 | #define X86_FEATURE_XGETBV1 (10*32+ 2) /* XGETBV with ECX = 1 */ | ||
238 | #define X86_FEATURE_XSAVES (10*32+ 3) /* XSAVES/XRSTORS */ | ||
239 | |||
240 | /* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:0 (edx), word 11 */ | ||
241 | #define X86_FEATURE_CQM_LLC (11*32+ 1) /* LLC QoS if 1 */ | ||
242 | |||
243 | /* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:1 (edx), word 12 */ | ||
244 | #define X86_FEATURE_CQM_OCCUP_LLC (12*32+ 0) /* LLC occupancy monitoring if 1 */ | ||
245 | |||
246 | /* AMD-defined CPU features, CPUID level 0x80000008 (ebx), word 13 */ | ||
247 | #define X86_FEATURE_CLZERO (13*32+0) /* CLZERO instruction */ | ||
248 | |||
249 | /* Thermal and Power Management Leaf, CPUID level 0x00000006 (eax), word 14 */ | ||
250 | #define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */ | ||
251 | #define X86_FEATURE_IDA (14*32+ 1) /* Intel Dynamic Acceleration */ | ||
252 | #define X86_FEATURE_ARAT (14*32+ 2) /* Always Running APIC Timer */ | ||
253 | #define X86_FEATURE_PLN (14*32+ 4) /* Intel Power Limit Notification */ | ||
254 | #define X86_FEATURE_PTS (14*32+ 6) /* Intel Package Thermal Status */ | ||
255 | #define X86_FEATURE_HWP (14*32+ 7) /* Intel Hardware P-states */ | ||
256 | #define X86_FEATURE_HWP_NOTIFY (14*32+ 8) /* HWP Notification */ | ||
257 | #define X86_FEATURE_HWP_ACT_WINDOW (14*32+ 9) /* HWP Activity Window */ | ||
258 | #define X86_FEATURE_HWP_EPP (14*32+10) /* HWP Energy Perf. Preference */ | ||
259 | #define X86_FEATURE_HWP_PKG_REQ (14*32+11) /* HWP Package Level Request */ | ||
260 | |||
261 | /* AMD SVM Feature Identification, CPUID level 0x8000000a (edx), word 15 */ | ||
262 | #define X86_FEATURE_NPT (15*32+ 0) /* Nested Page Table support */ | ||
263 | #define X86_FEATURE_LBRV (15*32+ 1) /* LBR Virtualization support */ | ||
264 | #define X86_FEATURE_SVML (15*32+ 2) /* "svm_lock" SVM locking MSR */ | ||
265 | #define X86_FEATURE_NRIPS (15*32+ 3) /* "nrip_save" SVM next_rip save */ | ||
266 | #define X86_FEATURE_TSCRATEMSR (15*32+ 4) /* "tsc_scale" TSC scaling support */ | ||
267 | #define X86_FEATURE_VMCBCLEAN (15*32+ 5) /* "vmcb_clean" VMCB clean bits support */ | ||
268 | #define X86_FEATURE_FLUSHBYASID (15*32+ 6) /* flush-by-ASID support */ | ||
269 | #define X86_FEATURE_DECODEASSISTS (15*32+ 7) /* Decode Assists support */ | ||
270 | #define X86_FEATURE_PAUSEFILTER (15*32+10) /* filtered pause intercept */ | ||
271 | #define X86_FEATURE_PFTHRESHOLD (15*32+12) /* pause filter threshold */ | ||
272 | #define X86_FEATURE_AVIC (15*32+13) /* Virtual Interrupt Controller */ | ||
273 | |||
274 | /* | ||
275 | * BUG word(s) | ||
276 | */ | ||
277 | #define X86_BUG(x) (NCAPINTS*32 + (x)) | ||
278 | |||
279 | #define X86_BUG_F00F X86_BUG(0) /* Intel F00F */ | ||
280 | #define X86_BUG_FDIV X86_BUG(1) /* FPU FDIV */ | ||
281 | #define X86_BUG_COMA X86_BUG(2) /* Cyrix 6x86 coma */ | ||
282 | #define X86_BUG_AMD_TLB_MMATCH X86_BUG(3) /* "tlb_mmatch" AMD Erratum 383 */ | ||
283 | #define X86_BUG_AMD_APIC_C1E X86_BUG(4) /* "apic_c1e" AMD Erratum 400 */ | ||
284 | #define X86_BUG_11AP X86_BUG(5) /* Bad local APIC aka 11AP */ | ||
285 | #define X86_BUG_FXSAVE_LEAK X86_BUG(6) /* FXSAVE leaks FOP/FIP/FOP */ | ||
286 | #define X86_BUG_CLFLUSH_MONITOR X86_BUG(7) /* AAI65, CLFLUSH required before MONITOR */ | ||
287 | #define X86_BUG_SYSRET_SS_ATTRS X86_BUG(8) /* SYSRET doesn't fix up SS attrs */ | ||
288 | |||
289 | #endif /* _ASM_X86_CPUFEATURES_H */ | ||
diff --git a/arch/x86/include/asm/desc_defs.h b/arch/x86/include/asm/desc_defs.h index 278441f39856..eb5deb42484d 100644 --- a/arch/x86/include/asm/desc_defs.h +++ b/arch/x86/include/asm/desc_defs.h | |||
@@ -98,4 +98,27 @@ struct desc_ptr { | |||
98 | 98 | ||
99 | #endif /* !__ASSEMBLY__ */ | 99 | #endif /* !__ASSEMBLY__ */ |
100 | 100 | ||
101 | /* Access rights as returned by LAR */ | ||
102 | #define AR_TYPE_RODATA (0 * (1 << 9)) | ||
103 | #define AR_TYPE_RWDATA (1 * (1 << 9)) | ||
104 | #define AR_TYPE_RODATA_EXPDOWN (2 * (1 << 9)) | ||
105 | #define AR_TYPE_RWDATA_EXPDOWN (3 * (1 << 9)) | ||
106 | #define AR_TYPE_XOCODE (4 * (1 << 9)) | ||
107 | #define AR_TYPE_XRCODE (5 * (1 << 9)) | ||
108 | #define AR_TYPE_XOCODE_CONF (6 * (1 << 9)) | ||
109 | #define AR_TYPE_XRCODE_CONF (7 * (1 << 9)) | ||
110 | #define AR_TYPE_MASK (7 * (1 << 9)) | ||
111 | |||
112 | #define AR_DPL0 (0 * (1 << 13)) | ||
113 | #define AR_DPL3 (3 * (1 << 13)) | ||
114 | #define AR_DPL_MASK (3 * (1 << 13)) | ||
115 | |||
116 | #define AR_A (1 << 8) /* "Accessed" */ | ||
117 | #define AR_S (1 << 12) /* If clear, "System" segment */ | ||
118 | #define AR_P (1 << 15) /* "Present" */ | ||
119 | #define AR_AVL (1 << 20) /* "AVaiLable" (no HW effect) */ | ||
120 | #define AR_L (1 << 21) /* "Long mode" for code segments */ | ||
121 | #define AR_DB (1 << 22) /* D/B, effect depends on type */ | ||
122 | #define AR_G (1 << 23) /* "Granularity" (limit in pages) */ | ||
123 | |||
101 | #endif /* _ASM_X86_DESC_DEFS_H */ | 124 | #endif /* _ASM_X86_DESC_DEFS_H */ |
diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h index 0fd440df63f1..c2e46eb96b6d 100644 --- a/arch/x86/include/asm/fpu/internal.h +++ b/arch/x86/include/asm/fpu/internal.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <asm/user.h> | 17 | #include <asm/user.h> |
18 | #include <asm/fpu/api.h> | 18 | #include <asm/fpu/api.h> |
19 | #include <asm/fpu/xstate.h> | 19 | #include <asm/fpu/xstate.h> |
20 | #include <asm/cpufeature.h> | ||
20 | 21 | ||
21 | /* | 22 | /* |
22 | * High level FPU state handling functions: | 23 | * High level FPU state handling functions: |
@@ -58,22 +59,22 @@ extern u64 fpu__get_supported_xfeatures_mask(void); | |||
58 | */ | 59 | */ |
59 | static __always_inline __pure bool use_eager_fpu(void) | 60 | static __always_inline __pure bool use_eager_fpu(void) |
60 | { | 61 | { |
61 | return static_cpu_has_safe(X86_FEATURE_EAGER_FPU); | 62 | return static_cpu_has(X86_FEATURE_EAGER_FPU); |
62 | } | 63 | } |
63 | 64 | ||
64 | static __always_inline __pure bool use_xsaveopt(void) | 65 | static __always_inline __pure bool use_xsaveopt(void) |
65 | { | 66 | { |
66 | return static_cpu_has_safe(X86_FEATURE_XSAVEOPT); | 67 | return static_cpu_has(X86_FEATURE_XSAVEOPT); |
67 | } | 68 | } |
68 | 69 | ||
69 | static __always_inline __pure bool use_xsave(void) | 70 | static __always_inline __pure bool use_xsave(void) |
70 | { | 71 | { |
71 | return static_cpu_has_safe(X86_FEATURE_XSAVE); | 72 | return static_cpu_has(X86_FEATURE_XSAVE); |
72 | } | 73 | } |
73 | 74 | ||
74 | static __always_inline __pure bool use_fxsr(void) | 75 | static __always_inline __pure bool use_fxsr(void) |
75 | { | 76 | { |
76 | return static_cpu_has_safe(X86_FEATURE_FXSR); | 77 | return static_cpu_has(X86_FEATURE_FXSR); |
77 | } | 78 | } |
78 | 79 | ||
79 | /* | 80 | /* |
@@ -300,7 +301,7 @@ static inline void copy_xregs_to_kernel_booting(struct xregs_state *xstate) | |||
300 | 301 | ||
301 | WARN_ON(system_state != SYSTEM_BOOTING); | 302 | WARN_ON(system_state != SYSTEM_BOOTING); |
302 | 303 | ||
303 | if (static_cpu_has_safe(X86_FEATURE_XSAVES)) | 304 | if (static_cpu_has(X86_FEATURE_XSAVES)) |
304 | XSTATE_OP(XSAVES, xstate, lmask, hmask, err); | 305 | XSTATE_OP(XSAVES, xstate, lmask, hmask, err); |
305 | else | 306 | else |
306 | XSTATE_OP(XSAVE, xstate, lmask, hmask, err); | 307 | XSTATE_OP(XSAVE, xstate, lmask, hmask, err); |
@@ -322,7 +323,7 @@ static inline void copy_kernel_to_xregs_booting(struct xregs_state *xstate) | |||
322 | 323 | ||
323 | WARN_ON(system_state != SYSTEM_BOOTING); | 324 | WARN_ON(system_state != SYSTEM_BOOTING); |
324 | 325 | ||
325 | if (static_cpu_has_safe(X86_FEATURE_XSAVES)) | 326 | if (static_cpu_has(X86_FEATURE_XSAVES)) |
326 | XSTATE_OP(XRSTORS, xstate, lmask, hmask, err); | 327 | XSTATE_OP(XRSTORS, xstate, lmask, hmask, err); |
327 | else | 328 | else |
328 | XSTATE_OP(XRSTOR, xstate, lmask, hmask, err); | 329 | XSTATE_OP(XRSTOR, xstate, lmask, hmask, err); |
@@ -460,7 +461,7 @@ static inline void copy_kernel_to_fpregs(union fpregs_state *fpstate) | |||
460 | * pending. Clear the x87 state here by setting it to fixed values. | 461 | * pending. Clear the x87 state here by setting it to fixed values. |
461 | * "m" is a random variable that should be in L1. | 462 | * "m" is a random variable that should be in L1. |
462 | */ | 463 | */ |
463 | if (unlikely(static_cpu_has_bug_safe(X86_BUG_FXSAVE_LEAK))) { | 464 | if (unlikely(static_cpu_has_bug(X86_BUG_FXSAVE_LEAK))) { |
464 | asm volatile( | 465 | asm volatile( |
465 | "fnclex\n\t" | 466 | "fnclex\n\t" |
466 | "emms\n\t" | 467 | "emms\n\t" |
diff --git a/arch/x86/include/asm/frame.h b/arch/x86/include/asm/frame.h index 793179cf8e21..6e4d170726b7 100644 --- a/arch/x86/include/asm/frame.h +++ b/arch/x86/include/asm/frame.h | |||
@@ -1,23 +1,44 @@ | |||
1 | #ifdef __ASSEMBLY__ | 1 | #ifndef _ASM_X86_FRAME_H |
2 | #define _ASM_X86_FRAME_H | ||
2 | 3 | ||
3 | #include <asm/asm.h> | 4 | #include <asm/asm.h> |
4 | 5 | ||
5 | /* The annotation hides the frame from the unwinder and makes it look | 6 | /* |
6 | like a ordinary ebp save/restore. This avoids some special cases for | 7 | * These are stack frame creation macros. They should be used by every |
7 | frame pointer later */ | 8 | * callable non-leaf asm function to make kernel stack traces more reliable. |
9 | */ | ||
10 | |||
8 | #ifdef CONFIG_FRAME_POINTER | 11 | #ifdef CONFIG_FRAME_POINTER |
9 | .macro FRAME | 12 | |
10 | __ASM_SIZE(push,) %__ASM_REG(bp) | 13 | #ifdef __ASSEMBLY__ |
11 | __ASM_SIZE(mov) %__ASM_REG(sp), %__ASM_REG(bp) | 14 | |
12 | .endm | 15 | .macro FRAME_BEGIN |
13 | .macro ENDFRAME | 16 | push %_ASM_BP |
14 | __ASM_SIZE(pop,) %__ASM_REG(bp) | 17 | _ASM_MOV %_ASM_SP, %_ASM_BP |
15 | .endm | 18 | .endm |
16 | #else | 19 | |
17 | .macro FRAME | 20 | .macro FRAME_END |
18 | .endm | 21 | pop %_ASM_BP |
19 | .macro ENDFRAME | 22 | .endm |
20 | .endm | 23 | |
21 | #endif | 24 | #else /* !__ASSEMBLY__ */ |
22 | 25 | ||
23 | #endif /* __ASSEMBLY__ */ | 26 | #define FRAME_BEGIN \ |
27 | "push %" _ASM_BP "\n" \ | ||
28 | _ASM_MOV "%" _ASM_SP ", %" _ASM_BP "\n" | ||
29 | |||
30 | #define FRAME_END "pop %" _ASM_BP "\n" | ||
31 | |||
32 | #endif /* __ASSEMBLY__ */ | ||
33 | |||
34 | #define FRAME_OFFSET __ASM_SEL(4, 8) | ||
35 | |||
36 | #else /* !CONFIG_FRAME_POINTER */ | ||
37 | |||
38 | #define FRAME_BEGIN | ||
39 | #define FRAME_END | ||
40 | #define FRAME_OFFSET 0 | ||
41 | |||
42 | #endif /* CONFIG_FRAME_POINTER */ | ||
43 | |||
44 | #endif /* _ASM_X86_FRAME_H */ | ||
diff --git a/arch/x86/include/asm/irq_work.h b/arch/x86/include/asm/irq_work.h index 78162f8e248b..d0afb05c84fc 100644 --- a/arch/x86/include/asm/irq_work.h +++ b/arch/x86/include/asm/irq_work.h | |||
@@ -1,7 +1,7 @@ | |||
1 | #ifndef _ASM_IRQ_WORK_H | 1 | #ifndef _ASM_IRQ_WORK_H |
2 | #define _ASM_IRQ_WORK_H | 2 | #define _ASM_IRQ_WORK_H |
3 | 3 | ||
4 | #include <asm/processor.h> | 4 | #include <asm/cpufeature.h> |
5 | 5 | ||
6 | static inline bool arch_irq_work_has_interrupt(void) | 6 | static inline bool arch_irq_work_has_interrupt(void) |
7 | { | 7 | { |
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index 2ea4527e462f..18d2ba9c8e44 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h | |||
@@ -113,6 +113,7 @@ struct mca_config { | |||
113 | bool ignore_ce; | 113 | bool ignore_ce; |
114 | bool disabled; | 114 | bool disabled; |
115 | bool ser; | 115 | bool ser; |
116 | bool recovery; | ||
116 | bool bios_cmci_threshold; | 117 | bool bios_cmci_threshold; |
117 | u8 banks; | 118 | u8 banks; |
118 | s8 bootlog; | 119 | s8 bootlog; |
diff --git a/arch/x86/include/asm/mmu.h b/arch/x86/include/asm/mmu.h index 55234d5e7160..1ea0baef1175 100644 --- a/arch/x86/include/asm/mmu.h +++ b/arch/x86/include/asm/mmu.h | |||
@@ -19,7 +19,8 @@ typedef struct { | |||
19 | #endif | 19 | #endif |
20 | 20 | ||
21 | struct mutex lock; | 21 | struct mutex lock; |
22 | void __user *vdso; | 22 | void __user *vdso; /* vdso base address */ |
23 | const struct vdso_image *vdso_image; /* vdso image in use */ | ||
23 | 24 | ||
24 | atomic_t perf_rdpmc_allowed; /* nonzero if rdpmc is allowed */ | 25 | atomic_t perf_rdpmc_allowed; /* nonzero if rdpmc is allowed */ |
25 | } mm_context_t; | 26 | } mm_context_t; |
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index b05402ef3b84..984ab75bf621 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h | |||
@@ -1,7 +1,12 @@ | |||
1 | #ifndef _ASM_X86_MSR_INDEX_H | 1 | #ifndef _ASM_X86_MSR_INDEX_H |
2 | #define _ASM_X86_MSR_INDEX_H | 2 | #define _ASM_X86_MSR_INDEX_H |
3 | 3 | ||
4 | /* CPU model specific register (MSR) numbers */ | 4 | /* |
5 | * CPU model specific register (MSR) numbers. | ||
6 | * | ||
7 | * Do not add new entries to this file unless the definitions are shared | ||
8 | * between multiple compilation units. | ||
9 | */ | ||
5 | 10 | ||
6 | /* x86-64 specific MSRs */ | 11 | /* x86-64 specific MSRs */ |
7 | #define MSR_EFER 0xc0000080 /* extended feature register */ | 12 | #define MSR_EFER 0xc0000080 /* extended feature register */ |
diff --git a/arch/x86/include/asm/mwait.h b/arch/x86/include/asm/mwait.h index c70689b5e5aa..0deeb2d26df7 100644 --- a/arch/x86/include/asm/mwait.h +++ b/arch/x86/include/asm/mwait.h | |||
@@ -3,6 +3,8 @@ | |||
3 | 3 | ||
4 | #include <linux/sched.h> | 4 | #include <linux/sched.h> |
5 | 5 | ||
6 | #include <asm/cpufeature.h> | ||
7 | |||
6 | #define MWAIT_SUBSTATE_MASK 0xf | 8 | #define MWAIT_SUBSTATE_MASK 0xf |
7 | #define MWAIT_CSTATE_MASK 0xf | 9 | #define MWAIT_CSTATE_MASK 0xf |
8 | #define MWAIT_SUBSTATE_SIZE 4 | 10 | #define MWAIT_SUBSTATE_SIZE 4 |
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index f6192502149e..601f1b8f9961 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/bug.h> | 13 | #include <linux/bug.h> |
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | #include <linux/cpumask.h> | 15 | #include <linux/cpumask.h> |
16 | #include <asm/frame.h> | ||
16 | 17 | ||
17 | static inline int paravirt_enabled(void) | 18 | static inline int paravirt_enabled(void) |
18 | { | 19 | { |
@@ -756,15 +757,19 @@ static __always_inline void __ticket_unlock_kick(struct arch_spinlock *lock, | |||
756 | * call. The return value in rax/eax will not be saved, even for void | 757 | * call. The return value in rax/eax will not be saved, even for void |
757 | * functions. | 758 | * functions. |
758 | */ | 759 | */ |
760 | #define PV_THUNK_NAME(func) "__raw_callee_save_" #func | ||
759 | #define PV_CALLEE_SAVE_REGS_THUNK(func) \ | 761 | #define PV_CALLEE_SAVE_REGS_THUNK(func) \ |
760 | extern typeof(func) __raw_callee_save_##func; \ | 762 | extern typeof(func) __raw_callee_save_##func; \ |
761 | \ | 763 | \ |
762 | asm(".pushsection .text;" \ | 764 | asm(".pushsection .text;" \ |
763 | ".globl __raw_callee_save_" #func " ; " \ | 765 | ".globl " PV_THUNK_NAME(func) ";" \ |
764 | "__raw_callee_save_" #func ": " \ | 766 | ".type " PV_THUNK_NAME(func) ", @function;" \ |
767 | PV_THUNK_NAME(func) ":" \ | ||
768 | FRAME_BEGIN \ | ||
765 | PV_SAVE_ALL_CALLER_REGS \ | 769 | PV_SAVE_ALL_CALLER_REGS \ |
766 | "call " #func ";" \ | 770 | "call " #func ";" \ |
767 | PV_RESTORE_ALL_CALLER_REGS \ | 771 | PV_RESTORE_ALL_CALLER_REGS \ |
772 | FRAME_END \ | ||
768 | "ret;" \ | 773 | "ret;" \ |
769 | ".popsection") | 774 | ".popsection") |
770 | 775 | ||
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index 77db5616a473..e8c2326478c8 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h | |||
@@ -466,8 +466,9 @@ int paravirt_disable_iospace(void); | |||
466 | * makes sure the incoming and outgoing types are always correct. | 466 | * makes sure the incoming and outgoing types are always correct. |
467 | */ | 467 | */ |
468 | #ifdef CONFIG_X86_32 | 468 | #ifdef CONFIG_X86_32 |
469 | #define PVOP_VCALL_ARGS \ | 469 | #define PVOP_VCALL_ARGS \ |
470 | unsigned long __eax = __eax, __edx = __edx, __ecx = __ecx | 470 | unsigned long __eax = __eax, __edx = __edx, __ecx = __ecx; \ |
471 | register void *__sp asm("esp") | ||
471 | #define PVOP_CALL_ARGS PVOP_VCALL_ARGS | 472 | #define PVOP_CALL_ARGS PVOP_VCALL_ARGS |
472 | 473 | ||
473 | #define PVOP_CALL_ARG1(x) "a" ((unsigned long)(x)) | 474 | #define PVOP_CALL_ARG1(x) "a" ((unsigned long)(x)) |
@@ -485,9 +486,10 @@ int paravirt_disable_iospace(void); | |||
485 | #define VEXTRA_CLOBBERS | 486 | #define VEXTRA_CLOBBERS |
486 | #else /* CONFIG_X86_64 */ | 487 | #else /* CONFIG_X86_64 */ |
487 | /* [re]ax isn't an arg, but the return val */ | 488 | /* [re]ax isn't an arg, but the return val */ |
488 | #define PVOP_VCALL_ARGS \ | 489 | #define PVOP_VCALL_ARGS \ |
489 | unsigned long __edi = __edi, __esi = __esi, \ | 490 | unsigned long __edi = __edi, __esi = __esi, \ |
490 | __edx = __edx, __ecx = __ecx, __eax = __eax | 491 | __edx = __edx, __ecx = __ecx, __eax = __eax; \ |
492 | register void *__sp asm("rsp") | ||
491 | #define PVOP_CALL_ARGS PVOP_VCALL_ARGS | 493 | #define PVOP_CALL_ARGS PVOP_VCALL_ARGS |
492 | 494 | ||
493 | #define PVOP_CALL_ARG1(x) "D" ((unsigned long)(x)) | 495 | #define PVOP_CALL_ARG1(x) "D" ((unsigned long)(x)) |
@@ -526,7 +528,7 @@ int paravirt_disable_iospace(void); | |||
526 | asm volatile(pre \ | 528 | asm volatile(pre \ |
527 | paravirt_alt(PARAVIRT_CALL) \ | 529 | paravirt_alt(PARAVIRT_CALL) \ |
528 | post \ | 530 | post \ |
529 | : call_clbr \ | 531 | : call_clbr, "+r" (__sp) \ |
530 | : paravirt_type(op), \ | 532 | : paravirt_type(op), \ |
531 | paravirt_clobber(clbr), \ | 533 | paravirt_clobber(clbr), \ |
532 | ##__VA_ARGS__ \ | 534 | ##__VA_ARGS__ \ |
@@ -536,7 +538,7 @@ int paravirt_disable_iospace(void); | |||
536 | asm volatile(pre \ | 538 | asm volatile(pre \ |
537 | paravirt_alt(PARAVIRT_CALL) \ | 539 | paravirt_alt(PARAVIRT_CALL) \ |
538 | post \ | 540 | post \ |
539 | : call_clbr \ | 541 | : call_clbr, "+r" (__sp) \ |
540 | : paravirt_type(op), \ | 542 | : paravirt_type(op), \ |
541 | paravirt_clobber(clbr), \ | 543 | paravirt_clobber(clbr), \ |
542 | ##__VA_ARGS__ \ | 544 | ##__VA_ARGS__ \ |
@@ -563,7 +565,7 @@ int paravirt_disable_iospace(void); | |||
563 | asm volatile(pre \ | 565 | asm volatile(pre \ |
564 | paravirt_alt(PARAVIRT_CALL) \ | 566 | paravirt_alt(PARAVIRT_CALL) \ |
565 | post \ | 567 | post \ |
566 | : call_clbr \ | 568 | : call_clbr, "+r" (__sp) \ |
567 | : paravirt_type(op), \ | 569 | : paravirt_type(op), \ |
568 | paravirt_clobber(clbr), \ | 570 | paravirt_clobber(clbr), \ |
569 | ##__VA_ARGS__ \ | 571 | ##__VA_ARGS__ \ |
diff --git a/arch/x86/include/asm/preempt.h b/arch/x86/include/asm/preempt.h index 01bcde84d3e4..d397deb58146 100644 --- a/arch/x86/include/asm/preempt.h +++ b/arch/x86/include/asm/preempt.h | |||
@@ -94,10 +94,19 @@ static __always_inline bool should_resched(int preempt_offset) | |||
94 | 94 | ||
95 | #ifdef CONFIG_PREEMPT | 95 | #ifdef CONFIG_PREEMPT |
96 | extern asmlinkage void ___preempt_schedule(void); | 96 | extern asmlinkage void ___preempt_schedule(void); |
97 | # define __preempt_schedule() asm ("call ___preempt_schedule") | 97 | # define __preempt_schedule() \ |
98 | ({ \ | ||
99 | register void *__sp asm(_ASM_SP); \ | ||
100 | asm volatile ("call ___preempt_schedule" : "+r"(__sp)); \ | ||
101 | }) | ||
102 | |||
98 | extern asmlinkage void preempt_schedule(void); | 103 | extern asmlinkage void preempt_schedule(void); |
99 | extern asmlinkage void ___preempt_schedule_notrace(void); | 104 | extern asmlinkage void ___preempt_schedule_notrace(void); |
100 | # define __preempt_schedule_notrace() asm ("call ___preempt_schedule_notrace") | 105 | # define __preempt_schedule_notrace() \ |
106 | ({ \ | ||
107 | register void *__sp asm(_ASM_SP); \ | ||
108 | asm volatile ("call ___preempt_schedule_notrace" : "+r"(__sp)); \ | ||
109 | }) | ||
101 | extern asmlinkage void preempt_schedule_notrace(void); | 110 | extern asmlinkage void preempt_schedule_notrace(void); |
102 | #endif | 111 | #endif |
103 | 112 | ||
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 20c11d1aa4cc..ecb410310e70 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h | |||
@@ -13,7 +13,7 @@ struct vm86; | |||
13 | #include <asm/types.h> | 13 | #include <asm/types.h> |
14 | #include <uapi/asm/sigcontext.h> | 14 | #include <uapi/asm/sigcontext.h> |
15 | #include <asm/current.h> | 15 | #include <asm/current.h> |
16 | #include <asm/cpufeature.h> | 16 | #include <asm/cpufeatures.h> |
17 | #include <asm/page.h> | 17 | #include <asm/page.h> |
18 | #include <asm/pgtable_types.h> | 18 | #include <asm/pgtable_types.h> |
19 | #include <asm/percpu.h> | 19 | #include <asm/percpu.h> |
@@ -24,7 +24,6 @@ struct vm86; | |||
24 | #include <asm/fpu/types.h> | 24 | #include <asm/fpu/types.h> |
25 | 25 | ||
26 | #include <linux/personality.h> | 26 | #include <linux/personality.h> |
27 | #include <linux/cpumask.h> | ||
28 | #include <linux/cache.h> | 27 | #include <linux/cache.h> |
29 | #include <linux/threads.h> | 28 | #include <linux/threads.h> |
30 | #include <linux/math64.h> | 29 | #include <linux/math64.h> |
diff --git a/arch/x86/include/asm/qspinlock_paravirt.h b/arch/x86/include/asm/qspinlock_paravirt.h index 9f92c180ed2f..9d55f9b6e167 100644 --- a/arch/x86/include/asm/qspinlock_paravirt.h +++ b/arch/x86/include/asm/qspinlock_paravirt.h | |||
@@ -36,8 +36,10 @@ PV_CALLEE_SAVE_REGS_THUNK(__pv_queued_spin_unlock_slowpath); | |||
36 | */ | 36 | */ |
37 | asm (".pushsection .text;" | 37 | asm (".pushsection .text;" |
38 | ".globl " PV_UNLOCK ";" | 38 | ".globl " PV_UNLOCK ";" |
39 | ".type " PV_UNLOCK ", @function;" | ||
39 | ".align 4,0x90;" | 40 | ".align 4,0x90;" |
40 | PV_UNLOCK ": " | 41 | PV_UNLOCK ": " |
42 | FRAME_BEGIN | ||
41 | "push %rdx;" | 43 | "push %rdx;" |
42 | "mov $0x1,%eax;" | 44 | "mov $0x1,%eax;" |
43 | "xor %edx,%edx;" | 45 | "xor %edx,%edx;" |
@@ -45,6 +47,7 @@ asm (".pushsection .text;" | |||
45 | "cmp $0x1,%al;" | 47 | "cmp $0x1,%al;" |
46 | "jne .slowpath;" | 48 | "jne .slowpath;" |
47 | "pop %rdx;" | 49 | "pop %rdx;" |
50 | FRAME_END | ||
48 | "ret;" | 51 | "ret;" |
49 | ".slowpath: " | 52 | ".slowpath: " |
50 | "push %rsi;" | 53 | "push %rsi;" |
@@ -52,6 +55,7 @@ asm (".pushsection .text;" | |||
52 | "call " PV_UNLOCK_SLOWPATH ";" | 55 | "call " PV_UNLOCK_SLOWPATH ";" |
53 | "pop %rsi;" | 56 | "pop %rsi;" |
54 | "pop %rdx;" | 57 | "pop %rdx;" |
58 | FRAME_END | ||
55 | "ret;" | 59 | "ret;" |
56 | ".size " PV_UNLOCK ", .-" PV_UNLOCK ";" | 60 | ".size " PV_UNLOCK ", .-" PV_UNLOCK ";" |
57 | ".popsection"); | 61 | ".popsection"); |
diff --git a/arch/x86/include/asm/sighandling.h b/arch/x86/include/asm/sighandling.h index 89db46752a8f..452c88b8ad06 100644 --- a/arch/x86/include/asm/sighandling.h +++ b/arch/x86/include/asm/sighandling.h | |||
@@ -13,7 +13,6 @@ | |||
13 | X86_EFLAGS_CF | X86_EFLAGS_RF) | 13 | X86_EFLAGS_CF | X86_EFLAGS_RF) |
14 | 14 | ||
15 | void signal_fault(struct pt_regs *regs, void __user *frame, char *where); | 15 | void signal_fault(struct pt_regs *regs, void __user *frame, char *where); |
16 | int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc); | ||
17 | int setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate, | 16 | int setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate, |
18 | struct pt_regs *regs, unsigned long mask); | 17 | struct pt_regs *regs, unsigned long mask); |
19 | 18 | ||
diff --git a/arch/x86/include/asm/smap.h b/arch/x86/include/asm/smap.h index ba665ebd17bb..db333300bd4b 100644 --- a/arch/x86/include/asm/smap.h +++ b/arch/x86/include/asm/smap.h | |||
@@ -15,7 +15,7 @@ | |||
15 | 15 | ||
16 | #include <linux/stringify.h> | 16 | #include <linux/stringify.h> |
17 | #include <asm/nops.h> | 17 | #include <asm/nops.h> |
18 | #include <asm/cpufeature.h> | 18 | #include <asm/cpufeatures.h> |
19 | 19 | ||
20 | /* "Raw" instruction opcodes */ | 20 | /* "Raw" instruction opcodes */ |
21 | #define __ASM_CLAC .byte 0x0f,0x01,0xca | 21 | #define __ASM_CLAC .byte 0x0f,0x01,0xca |
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index dfcf0727623b..20a3de5cb3b0 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h | |||
@@ -16,7 +16,6 @@ | |||
16 | #endif | 16 | #endif |
17 | #include <asm/thread_info.h> | 17 | #include <asm/thread_info.h> |
18 | #include <asm/cpumask.h> | 18 | #include <asm/cpumask.h> |
19 | #include <asm/cpufeature.h> | ||
20 | 19 | ||
21 | extern int smp_num_siblings; | 20 | extern int smp_num_siblings; |
22 | extern unsigned int num_processors; | 21 | extern unsigned int num_processors; |
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index c7b551028740..c0778fcab06d 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h | |||
@@ -49,7 +49,7 @@ | |||
49 | */ | 49 | */ |
50 | #ifndef __ASSEMBLY__ | 50 | #ifndef __ASSEMBLY__ |
51 | struct task_struct; | 51 | struct task_struct; |
52 | #include <asm/processor.h> | 52 | #include <asm/cpufeature.h> |
53 | #include <linux/atomic.h> | 53 | #include <linux/atomic.h> |
54 | 54 | ||
55 | struct thread_info { | 55 | struct thread_info { |
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h index 6df2029405a3..0bb31cb8c73b 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/sched.h> | 5 | #include <linux/sched.h> |
6 | 6 | ||
7 | #include <asm/processor.h> | 7 | #include <asm/processor.h> |
8 | #include <asm/cpufeature.h> | ||
8 | #include <asm/special_insns.h> | 9 | #include <asm/special_insns.h> |
9 | 10 | ||
10 | #ifdef CONFIG_PARAVIRT | 11 | #ifdef CONFIG_PARAVIRT |
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index a4a30e4b2d34..9bbb3b2d0372 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h | |||
@@ -179,10 +179,11 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL)) | |||
179 | ({ \ | 179 | ({ \ |
180 | int __ret_gu; \ | 180 | int __ret_gu; \ |
181 | register __inttype(*(ptr)) __val_gu asm("%"_ASM_DX); \ | 181 | register __inttype(*(ptr)) __val_gu asm("%"_ASM_DX); \ |
182 | register void *__sp asm(_ASM_SP); \ | ||
182 | __chk_user_ptr(ptr); \ | 183 | __chk_user_ptr(ptr); \ |
183 | might_fault(); \ | 184 | might_fault(); \ |
184 | asm volatile("call __get_user_%P3" \ | 185 | asm volatile("call __get_user_%P4" \ |
185 | : "=a" (__ret_gu), "=r" (__val_gu) \ | 186 | : "=a" (__ret_gu), "=r" (__val_gu), "+r" (__sp) \ |
186 | : "0" (ptr), "i" (sizeof(*(ptr)))); \ | 187 | : "0" (ptr), "i" (sizeof(*(ptr)))); \ |
187 | (x) = (__force __typeof__(*(ptr))) __val_gu; \ | 188 | (x) = (__force __typeof__(*(ptr))) __val_gu; \ |
188 | __builtin_expect(__ret_gu, 0); \ | 189 | __builtin_expect(__ret_gu, 0); \ |
diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h index b89c34c4019b..307698688fa1 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h | |||
@@ -8,7 +8,7 @@ | |||
8 | #include <linux/errno.h> | 8 | #include <linux/errno.h> |
9 | #include <linux/lockdep.h> | 9 | #include <linux/lockdep.h> |
10 | #include <asm/alternative.h> | 10 | #include <asm/alternative.h> |
11 | #include <asm/cpufeature.h> | 11 | #include <asm/cpufeatures.h> |
12 | #include <asm/page.h> | 12 | #include <asm/page.h> |
13 | 13 | ||
14 | /* | 14 | /* |
diff --git a/arch/x86/include/asm/vdso.h b/arch/x86/include/asm/vdso.h index deabaf9759b6..43dc55be524e 100644 --- a/arch/x86/include/asm/vdso.h +++ b/arch/x86/include/asm/vdso.h | |||
@@ -13,9 +13,6 @@ struct vdso_image { | |||
13 | void *data; | 13 | void *data; |
14 | unsigned long size; /* Always a multiple of PAGE_SIZE */ | 14 | unsigned long size; /* Always a multiple of PAGE_SIZE */ |
15 | 15 | ||
16 | /* text_mapping.pages is big enough for data/size page pointers */ | ||
17 | struct vm_special_mapping text_mapping; | ||
18 | |||
19 | unsigned long alt, alt_len; | 16 | unsigned long alt, alt_len; |
20 | 17 | ||
21 | long sym_vvar_start; /* Negative offset to the vvar area */ | 18 | long sym_vvar_start; /* Negative offset to the vvar area */ |
diff --git a/arch/x86/include/asm/vgtod.h b/arch/x86/include/asm/vgtod.h index f556c4843aa1..e728699db774 100644 --- a/arch/x86/include/asm/vgtod.h +++ b/arch/x86/include/asm/vgtod.h | |||
@@ -37,6 +37,12 @@ struct vsyscall_gtod_data { | |||
37 | }; | 37 | }; |
38 | extern struct vsyscall_gtod_data vsyscall_gtod_data; | 38 | extern struct vsyscall_gtod_data vsyscall_gtod_data; |
39 | 39 | ||
40 | extern int vclocks_used; | ||
41 | static inline bool vclock_was_used(int vclock) | ||
42 | { | ||
43 | return READ_ONCE(vclocks_used) & (1 << vclock); | ||
44 | } | ||
45 | |||
40 | static inline unsigned gtod_read_begin(const struct vsyscall_gtod_data *s) | 46 | static inline unsigned gtod_read_begin(const struct vsyscall_gtod_data *s) |
41 | { | 47 | { |
42 | unsigned ret; | 48 | unsigned ret; |
diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h index 3bcdcc84259d..a12a047184ee 100644 --- a/arch/x86/include/asm/xen/hypercall.h +++ b/arch/x86/include/asm/xen/hypercall.h | |||
@@ -110,9 +110,10 @@ extern struct { char _entry[32]; } hypercall_page[]; | |||
110 | register unsigned long __arg2 asm(__HYPERCALL_ARG2REG) = __arg2; \ | 110 | register unsigned long __arg2 asm(__HYPERCALL_ARG2REG) = __arg2; \ |
111 | register unsigned long __arg3 asm(__HYPERCALL_ARG3REG) = __arg3; \ | 111 | register unsigned long __arg3 asm(__HYPERCALL_ARG3REG) = __arg3; \ |
112 | register unsigned long __arg4 asm(__HYPERCALL_ARG4REG) = __arg4; \ | 112 | register unsigned long __arg4 asm(__HYPERCALL_ARG4REG) = __arg4; \ |
113 | register unsigned long __arg5 asm(__HYPERCALL_ARG5REG) = __arg5; | 113 | register unsigned long __arg5 asm(__HYPERCALL_ARG5REG) = __arg5; \ |
114 | register void *__sp asm(_ASM_SP); | ||
114 | 115 | ||
115 | #define __HYPERCALL_0PARAM "=r" (__res) | 116 | #define __HYPERCALL_0PARAM "=r" (__res), "+r" (__sp) |
116 | #define __HYPERCALL_1PARAM __HYPERCALL_0PARAM, "+r" (__arg1) | 117 | #define __HYPERCALL_1PARAM __HYPERCALL_0PARAM, "+r" (__arg1) |
117 | #define __HYPERCALL_2PARAM __HYPERCALL_1PARAM, "+r" (__arg2) | 118 | #define __HYPERCALL_2PARAM __HYPERCALL_1PARAM, "+r" (__arg2) |
118 | #define __HYPERCALL_3PARAM __HYPERCALL_2PARAM, "+r" (__arg3) | 119 | #define __HYPERCALL_3PARAM __HYPERCALL_2PARAM, "+r" (__arg3) |
diff --git a/arch/x86/include/uapi/asm/sigcontext.h b/arch/x86/include/uapi/asm/sigcontext.h index d485232f1e9f..62d4111c1c54 100644 --- a/arch/x86/include/uapi/asm/sigcontext.h +++ b/arch/x86/include/uapi/asm/sigcontext.h | |||
@@ -256,7 +256,7 @@ struct sigcontext_64 { | |||
256 | __u16 cs; | 256 | __u16 cs; |
257 | __u16 gs; | 257 | __u16 gs; |
258 | __u16 fs; | 258 | __u16 fs; |
259 | __u16 __pad0; | 259 | __u16 ss; |
260 | __u64 err; | 260 | __u64 err; |
261 | __u64 trapno; | 261 | __u64 trapno; |
262 | __u64 oldmask; | 262 | __u64 oldmask; |
@@ -341,9 +341,37 @@ struct sigcontext { | |||
341 | __u64 rip; | 341 | __u64 rip; |
342 | __u64 eflags; /* RFLAGS */ | 342 | __u64 eflags; /* RFLAGS */ |
343 | __u16 cs; | 343 | __u16 cs; |
344 | |||
345 | /* | ||
346 | * Prior to 2.5.64 ("[PATCH] x86-64 updates for 2.5.64-bk3"), | ||
347 | * Linux saved and restored fs and gs in these slots. This | ||
348 | * was counterproductive, as fsbase and gsbase were never | ||
349 | * saved, so arch_prctl was presumably unreliable. | ||
350 | * | ||
351 | * These slots should never be reused without extreme caution: | ||
352 | * | ||
353 | * - Some DOSEMU versions stash fs and gs in these slots manually, | ||
354 | * thus overwriting anything the kernel expects to be preserved | ||
355 | * in these slots. | ||
356 | * | ||
357 | * - If these slots are ever needed for any other purpose, | ||
358 | * there is some risk that very old 64-bit binaries could get | ||
359 | * confused. I doubt that many such binaries still work, | ||
360 | * though, since the same patch in 2.5.64 also removed the | ||
361 | * 64-bit set_thread_area syscall, so it appears that there | ||
362 | * is no TLS API beyond modify_ldt that works in both pre- | ||
363 | * and post-2.5.64 kernels. | ||
364 | * | ||
365 | * If the kernel ever adds explicit fs, gs, fsbase, and gsbase | ||
366 | * save/restore, it will most likely need to be opt-in and use | ||
367 | * different context slots. | ||
368 | */ | ||
344 | __u16 gs; | 369 | __u16 gs; |
345 | __u16 fs; | 370 | __u16 fs; |
346 | __u16 __pad0; | 371 | union { |
372 | __u16 ss; /* If UC_SIGCONTEXT_SS */ | ||
373 | __u16 __pad0; /* Alias name for old (!UC_SIGCONTEXT_SS) user-space */ | ||
374 | }; | ||
347 | __u64 err; | 375 | __u64 err; |
348 | __u64 trapno; | 376 | __u64 trapno; |
349 | __u64 oldmask; | 377 | __u64 oldmask; |
diff --git a/arch/x86/include/uapi/asm/ucontext.h b/arch/x86/include/uapi/asm/ucontext.h index b7c29c8017f2..e3d1ec90616e 100644 --- a/arch/x86/include/uapi/asm/ucontext.h +++ b/arch/x86/include/uapi/asm/ucontext.h | |||
@@ -1,11 +1,54 @@ | |||
1 | #ifndef _ASM_X86_UCONTEXT_H | 1 | #ifndef _ASM_X86_UCONTEXT_H |
2 | #define _ASM_X86_UCONTEXT_H | 2 | #define _ASM_X86_UCONTEXT_H |
3 | 3 | ||
4 | #define UC_FP_XSTATE 0x1 /* indicates the presence of extended state | 4 | /* |
5 | * information in the memory layout pointed | 5 | * Indicates the presence of extended state information in the memory |
6 | * by the fpstate pointer in the ucontext's | 6 | * layout pointed by the fpstate pointer in the ucontext's sigcontext |
7 | * sigcontext struct (uc_mcontext). | 7 | * struct (uc_mcontext). |
8 | */ | 8 | */ |
9 | #define UC_FP_XSTATE 0x1 | ||
10 | |||
11 | #ifdef __x86_64__ | ||
12 | /* | ||
13 | * UC_SIGCONTEXT_SS will be set when delivering 64-bit or x32 signals on | ||
14 | * kernels that save SS in the sigcontext. All kernels that set | ||
15 | * UC_SIGCONTEXT_SS will correctly restore at least the low 32 bits of esp | ||
16 | * regardless of SS (i.e. they implement espfix). | ||
17 | * | ||
18 | * Kernels that set UC_SIGCONTEXT_SS will also set UC_STRICT_RESTORE_SS | ||
19 | * when delivering a signal that came from 64-bit code. | ||
20 | * | ||
21 | * Sigreturn restores SS as follows: | ||
22 | * | ||
23 | * if (saved SS is valid || UC_STRICT_RESTORE_SS is set || | ||
24 | * saved CS is not 64-bit) | ||
25 | * new SS = saved SS (will fail IRET and signal if invalid) | ||
26 | * else | ||
27 | * new SS = a flat 32-bit data segment | ||
28 | * | ||
29 | * This behavior serves three purposes: | ||
30 | * | ||
31 | * - Legacy programs that construct a 64-bit sigcontext from scratch | ||
32 | * with zero or garbage in the SS slot (e.g. old CRIU) and call | ||
33 | * sigreturn will still work. | ||
34 | * | ||
35 | * - Old DOSEMU versions sometimes catch a signal from a segmented | ||
36 | * context, delete the old SS segment (with modify_ldt), and change | ||
37 | * the saved CS to a 64-bit segment. These DOSEMU versions expect | ||
38 | * sigreturn to send them back to 64-bit mode without killing them, | ||
39 | * despite the fact that the SS selector when the signal was raised is | ||
40 | * no longer valid. UC_STRICT_RESTORE_SS will be clear, so the kernel | ||
41 | * will fix up SS for these DOSEMU versions. | ||
42 | * | ||
43 | * - Old and new programs that catch a signal and return without | ||
44 | * modifying the saved context will end up in exactly the state they | ||
45 | * started in, even if they were running in a segmented context when | ||
46 | * the signal was raised.. Old kernels would lose track of the | ||
47 | * previous SS value. | ||
48 | */ | ||
49 | #define UC_SIGCONTEXT_SS 0x2 | ||
50 | #define UC_STRICT_RESTORE_SS 0x4 | ||
51 | #endif | ||
9 | 52 | ||
10 | #include <asm-generic/ucontext.h> | 53 | #include <asm-generic/ucontext.h> |
11 | 54 | ||
diff --git a/arch/x86/kernel/acpi/wakeup_64.S b/arch/x86/kernel/acpi/wakeup_64.S index 8c35df468104..169963f471bb 100644 --- a/arch/x86/kernel/acpi/wakeup_64.S +++ b/arch/x86/kernel/acpi/wakeup_64.S | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <asm/page_types.h> | 5 | #include <asm/page_types.h> |
6 | #include <asm/msr.h> | 6 | #include <asm/msr.h> |
7 | #include <asm/asm-offsets.h> | 7 | #include <asm/asm-offsets.h> |
8 | #include <asm/frame.h> | ||
8 | 9 | ||
9 | # Copyright 2003 Pavel Machek <pavel@suse.cz>, distribute under GPLv2 | 10 | # Copyright 2003 Pavel Machek <pavel@suse.cz>, distribute under GPLv2 |
10 | 11 | ||
@@ -39,6 +40,7 @@ bogus_64_magic: | |||
39 | jmp bogus_64_magic | 40 | jmp bogus_64_magic |
40 | 41 | ||
41 | ENTRY(do_suspend_lowlevel) | 42 | ENTRY(do_suspend_lowlevel) |
43 | FRAME_BEGIN | ||
42 | subq $8, %rsp | 44 | subq $8, %rsp |
43 | xorl %eax, %eax | 45 | xorl %eax, %eax |
44 | call save_processor_state | 46 | call save_processor_state |
@@ -109,6 +111,7 @@ ENTRY(do_suspend_lowlevel) | |||
109 | 111 | ||
110 | xorl %eax, %eax | 112 | xorl %eax, %eax |
111 | addq $8, %rsp | 113 | addq $8, %rsp |
114 | FRAME_END | ||
112 | jmp restore_processor_state | 115 | jmp restore_processor_state |
113 | ENDPROC(do_suspend_lowlevel) | 116 | ENDPROC(do_suspend_lowlevel) |
114 | 117 | ||
diff --git a/arch/x86/kernel/apic/apic_numachip.c b/arch/x86/kernel/apic/apic_numachip.c index c80c02c6ec49..ab5c2c685a3c 100644 --- a/arch/x86/kernel/apic/apic_numachip.c +++ b/arch/x86/kernel/apic/apic_numachip.c | |||
@@ -30,7 +30,7 @@ static unsigned int numachip1_get_apic_id(unsigned long x) | |||
30 | unsigned long value; | 30 | unsigned long value; |
31 | unsigned int id = (x >> 24) & 0xff; | 31 | unsigned int id = (x >> 24) & 0xff; |
32 | 32 | ||
33 | if (static_cpu_has_safe(X86_FEATURE_NODEID_MSR)) { | 33 | if (static_cpu_has(X86_FEATURE_NODEID_MSR)) { |
34 | rdmsrl(MSR_FAM10H_NODE_ID, value); | 34 | rdmsrl(MSR_FAM10H_NODE_ID, value); |
35 | id |= (value << 2) & 0xff00; | 35 | id |= (value << 2) & 0xff00; |
36 | } | 36 | } |
@@ -178,7 +178,7 @@ static void fixup_cpu_id(struct cpuinfo_x86 *c, int node) | |||
178 | this_cpu_write(cpu_llc_id, node); | 178 | this_cpu_write(cpu_llc_id, node); |
179 | 179 | ||
180 | /* Account for nodes per socket in multi-core-module processors */ | 180 | /* Account for nodes per socket in multi-core-module processors */ |
181 | if (static_cpu_has_safe(X86_FEATURE_NODEID_MSR)) { | 181 | if (static_cpu_has(X86_FEATURE_NODEID_MSR)) { |
182 | rdmsrl(MSR_FAM10H_NODE_ID, val); | 182 | rdmsrl(MSR_FAM10H_NODE_ID, val); |
183 | nodes = ((val >> 3) & 7) + 1; | 183 | nodes = ((val >> 3) & 7) + 1; |
184 | } | 184 | } |
diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c index 6ce39025f467..fdeb0ce07c16 100644 --- a/arch/x86/kernel/asm-offsets_32.c +++ b/arch/x86/kernel/asm-offsets_32.c | |||
@@ -7,7 +7,7 @@ | |||
7 | #include <linux/lguest.h> | 7 | #include <linux/lguest.h> |
8 | #include "../../../drivers/lguest/lg.h" | 8 | #include "../../../drivers/lguest/lg.h" |
9 | 9 | ||
10 | #define __SYSCALL_I386(nr, sym, compat) [nr] = 1, | 10 | #define __SYSCALL_I386(nr, sym, qual) [nr] = 1, |
11 | static char syscalls[] = { | 11 | static char syscalls[] = { |
12 | #include <asm/syscalls_32.h> | 12 | #include <asm/syscalls_32.h> |
13 | }; | 13 | }; |
diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index f2edafb5f24e..d875f97d4e0b 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c | |||
@@ -4,17 +4,11 @@ | |||
4 | 4 | ||
5 | #include <asm/ia32.h> | 5 | #include <asm/ia32.h> |
6 | 6 | ||
7 | #define __SYSCALL_64(nr, sym, compat) [nr] = 1, | 7 | #define __SYSCALL_64(nr, sym, qual) [nr] = 1, |
8 | #define __SYSCALL_COMMON(nr, sym, compat) [nr] = 1, | ||
9 | #ifdef CONFIG_X86_X32_ABI | ||
10 | # define __SYSCALL_X32(nr, sym, compat) [nr] = 1, | ||
11 | #else | ||
12 | # define __SYSCALL_X32(nr, sym, compat) /* nothing */ | ||
13 | #endif | ||
14 | static char syscalls_64[] = { | 8 | static char syscalls_64[] = { |
15 | #include <asm/syscalls_64.h> | 9 | #include <asm/syscalls_64.h> |
16 | }; | 10 | }; |
17 | #define __SYSCALL_I386(nr, sym, compat) [nr] = 1, | 11 | #define __SYSCALL_I386(nr, sym, qual) [nr] = 1, |
18 | static char syscalls_ia32[] = { | 12 | static char syscalls_ia32[] = { |
19 | #include <asm/syscalls_32.h> | 13 | #include <asm/syscalls_32.h> |
20 | }; | 14 | }; |
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index 58031303e304..faa7b5204129 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile | |||
@@ -64,7 +64,7 @@ ifdef CONFIG_X86_FEATURE_NAMES | |||
64 | quiet_cmd_mkcapflags = MKCAP $@ | 64 | quiet_cmd_mkcapflags = MKCAP $@ |
65 | cmd_mkcapflags = $(CONFIG_SHELL) $(srctree)/$(src)/mkcapflags.sh $< $@ | 65 | cmd_mkcapflags = $(CONFIG_SHELL) $(srctree)/$(src)/mkcapflags.sh $< $@ |
66 | 66 | ||
67 | cpufeature = $(src)/../../include/asm/cpufeature.h | 67 | cpufeature = $(src)/../../include/asm/cpufeatures.h |
68 | 68 | ||
69 | targets += capflags.c | 69 | targets += capflags.c |
70 | $(obj)/capflags.c: $(cpufeature) $(src)/mkcapflags.sh FORCE | 70 | $(obj)/capflags.c: $(cpufeature) $(src)/mkcapflags.sh FORCE |
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index a07956a08936..fe2f089f03d2 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
@@ -75,7 +75,10 @@ static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val) | |||
75 | */ | 75 | */ |
76 | 76 | ||
77 | extern __visible void vide(void); | 77 | extern __visible void vide(void); |
78 | __asm__(".globl vide\n\t.align 4\nvide: ret"); | 78 | __asm__(".globl vide\n" |
79 | ".type vide, @function\n" | ||
80 | ".align 4\n" | ||
81 | "vide: ret\n"); | ||
79 | 82 | ||
80 | static void init_amd_k5(struct cpuinfo_x86 *c) | 83 | static void init_amd_k5(struct cpuinfo_x86 *c) |
81 | { | 84 | { |
diff --git a/arch/x86/kernel/cpu/centaur.c b/arch/x86/kernel/cpu/centaur.c index ae20be6e483c..6608c03c2126 100644 --- a/arch/x86/kernel/cpu/centaur.c +++ b/arch/x86/kernel/cpu/centaur.c | |||
@@ -1,7 +1,7 @@ | |||
1 | #include <linux/bitops.h> | 1 | #include <linux/bitops.h> |
2 | #include <linux/kernel.h> | 2 | #include <linux/kernel.h> |
3 | 3 | ||
4 | #include <asm/processor.h> | 4 | #include <asm/cpufeature.h> |
5 | #include <asm/e820.h> | 5 | #include <asm/e820.h> |
6 | #include <asm/mtrr.h> | 6 | #include <asm/mtrr.h> |
7 | #include <asm/msr.h> | 7 | #include <asm/msr.h> |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 37830de8f60a..079d83fc6488 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -1475,20 +1475,6 @@ void cpu_init(void) | |||
1475 | } | 1475 | } |
1476 | #endif | 1476 | #endif |
1477 | 1477 | ||
1478 | #ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS | ||
1479 | void warn_pre_alternatives(void) | ||
1480 | { | ||
1481 | WARN(1, "You're using static_cpu_has before alternatives have run!\n"); | ||
1482 | } | ||
1483 | EXPORT_SYMBOL_GPL(warn_pre_alternatives); | ||
1484 | #endif | ||
1485 | |||
1486 | inline bool __static_cpu_has_safe(u16 bit) | ||
1487 | { | ||
1488 | return boot_cpu_has(bit); | ||
1489 | } | ||
1490 | EXPORT_SYMBOL_GPL(__static_cpu_has_safe); | ||
1491 | |||
1492 | static void bsp_resume(void) | 1478 | static void bsp_resume(void) |
1493 | { | 1479 | { |
1494 | if (this_cpu->c_bsp_resume) | 1480 | if (this_cpu->c_bsp_resume) |
diff --git a/arch/x86/kernel/cpu/cyrix.c b/arch/x86/kernel/cpu/cyrix.c index aaf152e79637..15e47c1cd412 100644 --- a/arch/x86/kernel/cpu/cyrix.c +++ b/arch/x86/kernel/cpu/cyrix.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/timer.h> | 8 | #include <linux/timer.h> |
9 | #include <asm/pci-direct.h> | 9 | #include <asm/pci-direct.h> |
10 | #include <asm/tsc.h> | 10 | #include <asm/tsc.h> |
11 | #include <asm/cpufeature.h> | ||
11 | 12 | ||
12 | #include "cpu.h" | 13 | #include "cpu.h" |
13 | 14 | ||
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 565648bc1a0a..9299e3bdfad6 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
@@ -8,7 +8,7 @@ | |||
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/uaccess.h> | 9 | #include <linux/uaccess.h> |
10 | 10 | ||
11 | #include <asm/processor.h> | 11 | #include <asm/cpufeature.h> |
12 | #include <asm/pgtable.h> | 12 | #include <asm/pgtable.h> |
13 | #include <asm/msr.h> | 13 | #include <asm/msr.h> |
14 | #include <asm/bugs.h> | 14 | #include <asm/bugs.h> |
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index 0b6c52388cf4..341449c49f34 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/sysfs.h> | 14 | #include <linux/sysfs.h> |
15 | #include <linux/pci.h> | 15 | #include <linux/pci.h> |
16 | 16 | ||
17 | #include <asm/processor.h> | 17 | #include <asm/cpufeature.h> |
18 | #include <asm/amd_nb.h> | 18 | #include <asm/amd_nb.h> |
19 | #include <asm/smp.h> | 19 | #include <asm/smp.h> |
20 | 20 | ||
diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c index afa9f0d487ea..fbb5e90557a5 100644 --- a/arch/x86/kernel/cpu/match.c +++ b/arch/x86/kernel/cpu/match.c | |||
@@ -1,5 +1,5 @@ | |||
1 | #include <asm/cpu_device_id.h> | 1 | #include <asm/cpu_device_id.h> |
2 | #include <asm/processor.h> | 2 | #include <asm/cpufeature.h> |
3 | #include <linux/cpu.h> | 3 | #include <linux/cpu.h> |
4 | #include <linux/module.h> | 4 | #include <linux/module.h> |
5 | #include <linux/slab.h> | 5 | #include <linux/slab.h> |
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index a006f4cd792b..b5b187c8cc07 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
@@ -1576,6 +1576,17 @@ static int __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) | |||
1576 | 1576 | ||
1577 | if (c->x86 == 6 && c->x86_model == 45) | 1577 | if (c->x86 == 6 && c->x86_model == 45) |
1578 | quirk_no_way_out = quirk_sandybridge_ifu; | 1578 | quirk_no_way_out = quirk_sandybridge_ifu; |
1579 | /* | ||
1580 | * MCG_CAP.MCG_SER_P is necessary but not sufficient to know | ||
1581 | * whether this processor will actually generate recoverable | ||
1582 | * machine checks. Check to see if this is an E7 model Xeon. | ||
1583 | * We can't do a model number check because E5 and E7 use the | ||
1584 | * same model number. E5 doesn't support recovery, E7 does. | ||
1585 | */ | ||
1586 | if (mca_cfg.recovery || (mca_cfg.ser && | ||
1587 | !strncmp(c->x86_model_id, | ||
1588 | "Intel(R) Xeon(R) CPU E7-", 24))) | ||
1589 | set_cpu_cap(c, X86_FEATURE_MCE_RECOVERY); | ||
1579 | } | 1590 | } |
1580 | if (cfg->monarch_timeout < 0) | 1591 | if (cfg->monarch_timeout < 0) |
1581 | cfg->monarch_timeout = 0; | 1592 | cfg->monarch_timeout = 0; |
@@ -2028,6 +2039,8 @@ static int __init mcheck_enable(char *str) | |||
2028 | cfg->bootlog = (str[0] == 'b'); | 2039 | cfg->bootlog = (str[0] == 'b'); |
2029 | else if (!strcmp(str, "bios_cmci_threshold")) | 2040 | else if (!strcmp(str, "bios_cmci_threshold")) |
2030 | cfg->bios_cmci_threshold = true; | 2041 | cfg->bios_cmci_threshold = true; |
2042 | else if (!strcmp(str, "recovery")) | ||
2043 | cfg->recovery = true; | ||
2031 | else if (isdigit(str[0])) { | 2044 | else if (isdigit(str[0])) { |
2032 | if (get_option(&str, &cfg->tolerant) == 2) | 2045 | if (get_option(&str, &cfg->tolerant) == 2) |
2033 | get_option(&str, &(cfg->monarch_timeout)); | 2046 | get_option(&str, &(cfg->monarch_timeout)); |
diff --git a/arch/x86/kernel/cpu/mkcapflags.sh b/arch/x86/kernel/cpu/mkcapflags.sh index 3f20710a5b23..6988c74409a8 100644 --- a/arch/x86/kernel/cpu/mkcapflags.sh +++ b/arch/x86/kernel/cpu/mkcapflags.sh | |||
@@ -1,6 +1,6 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | # | 2 | # |
3 | # Generate the x86_cap/bug_flags[] arrays from include/asm/cpufeature.h | 3 | # Generate the x86_cap/bug_flags[] arrays from include/asm/cpufeatures.h |
4 | # | 4 | # |
5 | 5 | ||
6 | IN=$1 | 6 | IN=$1 |
@@ -49,8 +49,8 @@ dump_array() | |||
49 | trap 'rm "$OUT"' EXIT | 49 | trap 'rm "$OUT"' EXIT |
50 | 50 | ||
51 | ( | 51 | ( |
52 | echo "#ifndef _ASM_X86_CPUFEATURE_H" | 52 | echo "#ifndef _ASM_X86_CPUFEATURES_H" |
53 | echo "#include <asm/cpufeature.h>" | 53 | echo "#include <asm/cpufeatures.h>" |
54 | echo "#endif" | 54 | echo "#endif" |
55 | echo "" | 55 | echo "" |
56 | 56 | ||
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c index 5c3d149ee91c..74f1d90f9c29 100644 --- a/arch/x86/kernel/cpu/mtrr/main.c +++ b/arch/x86/kernel/cpu/mtrr/main.c | |||
@@ -47,7 +47,7 @@ | |||
47 | #include <linux/smp.h> | 47 | #include <linux/smp.h> |
48 | #include <linux/syscore_ops.h> | 48 | #include <linux/syscore_ops.h> |
49 | 49 | ||
50 | #include <asm/processor.h> | 50 | #include <asm/cpufeature.h> |
51 | #include <asm/e820.h> | 51 | #include <asm/e820.h> |
52 | #include <asm/mtrr.h> | 52 | #include <asm/mtrr.h> |
53 | #include <asm/msr.h> | 53 | #include <asm/msr.h> |
diff --git a/arch/x86/kernel/cpu/transmeta.c b/arch/x86/kernel/cpu/transmeta.c index 252da7aceca6..a19a663282b5 100644 --- a/arch/x86/kernel/cpu/transmeta.c +++ b/arch/x86/kernel/cpu/transmeta.c | |||
@@ -1,6 +1,6 @@ | |||
1 | #include <linux/kernel.h> | 1 | #include <linux/kernel.h> |
2 | #include <linux/mm.h> | 2 | #include <linux/mm.h> |
3 | #include <asm/processor.h> | 3 | #include <asm/cpufeature.h> |
4 | #include <asm/msr.h> | 4 | #include <asm/msr.h> |
5 | #include "cpu.h" | 5 | #include "cpu.h" |
6 | 6 | ||
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 569c1e4f96fe..b3c2a697820a 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <asm/e820.h> | 24 | #include <asm/e820.h> |
25 | #include <asm/proto.h> | 25 | #include <asm/proto.h> |
26 | #include <asm/setup.h> | 26 | #include <asm/setup.h> |
27 | #include <asm/cpufeature.h> | ||
27 | 28 | ||
28 | /* | 29 | /* |
29 | * The e820 map is the map that gets modified e.g. with command line parameters | 30 | * The e820 map is the map that gets modified e.g. with command line parameters |
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 29408d6d6626..04f9641e0cb6 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c | |||
@@ -697,9 +697,8 @@ static inline void tramp_free(void *tramp) { } | |||
697 | #endif | 697 | #endif |
698 | 698 | ||
699 | /* Defined as markers to the end of the ftrace default trampolines */ | 699 | /* Defined as markers to the end of the ftrace default trampolines */ |
700 | extern void ftrace_caller_end(void); | ||
701 | extern void ftrace_regs_caller_end(void); | 700 | extern void ftrace_regs_caller_end(void); |
702 | extern void ftrace_return(void); | 701 | extern void ftrace_epilogue(void); |
703 | extern void ftrace_caller_op_ptr(void); | 702 | extern void ftrace_caller_op_ptr(void); |
704 | extern void ftrace_regs_caller_op_ptr(void); | 703 | extern void ftrace_regs_caller_op_ptr(void); |
705 | 704 | ||
@@ -746,7 +745,7 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size) | |||
746 | op_offset = (unsigned long)ftrace_regs_caller_op_ptr; | 745 | op_offset = (unsigned long)ftrace_regs_caller_op_ptr; |
747 | } else { | 746 | } else { |
748 | start_offset = (unsigned long)ftrace_caller; | 747 | start_offset = (unsigned long)ftrace_caller; |
749 | end_offset = (unsigned long)ftrace_caller_end; | 748 | end_offset = (unsigned long)ftrace_epilogue; |
750 | op_offset = (unsigned long)ftrace_caller_op_ptr; | 749 | op_offset = (unsigned long)ftrace_caller_op_ptr; |
751 | } | 750 | } |
752 | 751 | ||
@@ -754,7 +753,7 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size) | |||
754 | 753 | ||
755 | /* | 754 | /* |
756 | * Allocate enough size to store the ftrace_caller code, | 755 | * Allocate enough size to store the ftrace_caller code, |
757 | * the jmp to ftrace_return, as well as the address of | 756 | * the jmp to ftrace_epilogue, as well as the address of |
758 | * the ftrace_ops this trampoline is used for. | 757 | * the ftrace_ops this trampoline is used for. |
759 | */ | 758 | */ |
760 | trampoline = alloc_tramp(size + MCOUNT_INSN_SIZE + sizeof(void *)); | 759 | trampoline = alloc_tramp(size + MCOUNT_INSN_SIZE + sizeof(void *)); |
@@ -772,8 +771,8 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size) | |||
772 | 771 | ||
773 | ip = (unsigned long)trampoline + size; | 772 | ip = (unsigned long)trampoline + size; |
774 | 773 | ||
775 | /* The trampoline ends with a jmp to ftrace_return */ | 774 | /* The trampoline ends with a jmp to ftrace_epilogue */ |
776 | jmp = ftrace_jmp_replace(ip, (unsigned long)ftrace_return); | 775 | jmp = ftrace_jmp_replace(ip, (unsigned long)ftrace_epilogue); |
777 | memcpy(trampoline + size, jmp, MCOUNT_INSN_SIZE); | 776 | memcpy(trampoline + size, jmp, MCOUNT_INSN_SIZE); |
778 | 777 | ||
779 | /* | 778 | /* |
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 6bc9ae24b6d2..af1112980dd4 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <asm/setup.h> | 19 | #include <asm/setup.h> |
20 | #include <asm/processor-flags.h> | 20 | #include <asm/processor-flags.h> |
21 | #include <asm/msr-index.h> | 21 | #include <asm/msr-index.h> |
22 | #include <asm/cpufeature.h> | 22 | #include <asm/cpufeatures.h> |
23 | #include <asm/percpu.h> | 23 | #include <asm/percpu.h> |
24 | #include <asm/nops.h> | 24 | #include <asm/nops.h> |
25 | #include <asm/bootparam.h> | 25 | #include <asm/bootparam.h> |
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index ffdc0e860390..2e974680f5ad 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S | |||
@@ -38,7 +38,6 @@ | |||
38 | #define pud_index(x) (((x) >> PUD_SHIFT) & (PTRS_PER_PUD-1)) | 38 | #define pud_index(x) (((x) >> PUD_SHIFT) & (PTRS_PER_PUD-1)) |
39 | 39 | ||
40 | L4_PAGE_OFFSET = pgd_index(__PAGE_OFFSET) | 40 | L4_PAGE_OFFSET = pgd_index(__PAGE_OFFSET) |
41 | L3_PAGE_OFFSET = pud_index(__PAGE_OFFSET) | ||
42 | L4_START_KERNEL = pgd_index(__START_KERNEL_map) | 41 | L4_START_KERNEL = pgd_index(__START_KERNEL_map) |
43 | L3_START_KERNEL = pud_index(__START_KERNEL_map) | 42 | L3_START_KERNEL = pud_index(__START_KERNEL_map) |
44 | 43 | ||
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index b8e6ff5cd5d0..be0ebbb6d1d1 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/pm.h> | 12 | #include <linux/pm.h> |
13 | #include <linux/io.h> | 13 | #include <linux/io.h> |
14 | 14 | ||
15 | #include <asm/cpufeature.h> | ||
15 | #include <asm/irqdomain.h> | 16 | #include <asm/irqdomain.h> |
16 | #include <asm/fixmap.h> | 17 | #include <asm/fixmap.h> |
17 | #include <asm/hpet.h> | 18 | #include <asm/hpet.h> |
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index 1deffe6cc873..5b187dfbfc8b 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c | |||
@@ -671,38 +671,37 @@ NOKPROBE_SYMBOL(kprobe_int3_handler); | |||
671 | * When a retprobed function returns, this code saves registers and | 671 | * When a retprobed function returns, this code saves registers and |
672 | * calls trampoline_handler() runs, which calls the kretprobe's handler. | 672 | * calls trampoline_handler() runs, which calls the kretprobe's handler. |
673 | */ | 673 | */ |
674 | static void __used kretprobe_trampoline_holder(void) | 674 | asm( |
675 | { | 675 | ".global kretprobe_trampoline\n" |
676 | asm volatile ( | 676 | ".type kretprobe_trampoline, @function\n" |
677 | ".global kretprobe_trampoline\n" | 677 | "kretprobe_trampoline:\n" |
678 | "kretprobe_trampoline: \n" | ||
679 | #ifdef CONFIG_X86_64 | 678 | #ifdef CONFIG_X86_64 |
680 | /* We don't bother saving the ss register */ | 679 | /* We don't bother saving the ss register */ |
681 | " pushq %rsp\n" | 680 | " pushq %rsp\n" |
682 | " pushfq\n" | 681 | " pushfq\n" |
683 | SAVE_REGS_STRING | 682 | SAVE_REGS_STRING |
684 | " movq %rsp, %rdi\n" | 683 | " movq %rsp, %rdi\n" |
685 | " call trampoline_handler\n" | 684 | " call trampoline_handler\n" |
686 | /* Replace saved sp with true return address. */ | 685 | /* Replace saved sp with true return address. */ |
687 | " movq %rax, 152(%rsp)\n" | 686 | " movq %rax, 152(%rsp)\n" |
688 | RESTORE_REGS_STRING | 687 | RESTORE_REGS_STRING |
689 | " popfq\n" | 688 | " popfq\n" |
690 | #else | 689 | #else |
691 | " pushf\n" | 690 | " pushf\n" |
692 | SAVE_REGS_STRING | 691 | SAVE_REGS_STRING |
693 | " movl %esp, %eax\n" | 692 | " movl %esp, %eax\n" |
694 | " call trampoline_handler\n" | 693 | " call trampoline_handler\n" |
695 | /* Move flags to cs */ | 694 | /* Move flags to cs */ |
696 | " movl 56(%esp), %edx\n" | 695 | " movl 56(%esp), %edx\n" |
697 | " movl %edx, 52(%esp)\n" | 696 | " movl %edx, 52(%esp)\n" |
698 | /* Replace saved flags with true return address. */ | 697 | /* Replace saved flags with true return address. */ |
699 | " movl %eax, 56(%esp)\n" | 698 | " movl %eax, 56(%esp)\n" |
700 | RESTORE_REGS_STRING | 699 | RESTORE_REGS_STRING |
701 | " popf\n" | 700 | " popf\n" |
702 | #endif | 701 | #endif |
703 | " ret\n"); | 702 | " ret\n" |
704 | } | 703 | ".size kretprobe_trampoline, .-kretprobe_trampoline\n" |
705 | NOKPROBE_SYMBOL(kretprobe_trampoline_holder); | 704 | ); |
706 | NOKPROBE_SYMBOL(kretprobe_trampoline); | 705 | NOKPROBE_SYMBOL(kretprobe_trampoline); |
707 | 706 | ||
708 | /* | 707 | /* |
diff --git a/arch/x86/kernel/mcount_64.S b/arch/x86/kernel/mcount_64.S index 87e1762e2bca..ed48a9f465f8 100644 --- a/arch/x86/kernel/mcount_64.S +++ b/arch/x86/kernel/mcount_64.S | |||
@@ -168,12 +168,14 @@ GLOBAL(ftrace_call) | |||
168 | restore_mcount_regs | 168 | restore_mcount_regs |
169 | 169 | ||
170 | /* | 170 | /* |
171 | * The copied trampoline must call ftrace_return as it | 171 | * The copied trampoline must call ftrace_epilogue as it |
172 | * still may need to call the function graph tracer. | 172 | * still may need to call the function graph tracer. |
173 | * | ||
174 | * The code up to this label is copied into trampolines so | ||
175 | * think twice before adding any new code or changing the | ||
176 | * layout here. | ||
173 | */ | 177 | */ |
174 | GLOBAL(ftrace_caller_end) | 178 | GLOBAL(ftrace_epilogue) |
175 | |||
176 | GLOBAL(ftrace_return) | ||
177 | 179 | ||
178 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 180 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
179 | GLOBAL(ftrace_graph_call) | 181 | GLOBAL(ftrace_graph_call) |
@@ -244,14 +246,14 @@ GLOBAL(ftrace_regs_call) | |||
244 | popfq | 246 | popfq |
245 | 247 | ||
246 | /* | 248 | /* |
247 | * As this jmp to ftrace_return can be a short jump | 249 | * As this jmp to ftrace_epilogue can be a short jump |
248 | * it must not be copied into the trampoline. | 250 | * it must not be copied into the trampoline. |
249 | * The trampoline will add the code to jump | 251 | * The trampoline will add the code to jump |
250 | * to the return. | 252 | * to the return. |
251 | */ | 253 | */ |
252 | GLOBAL(ftrace_regs_caller_end) | 254 | GLOBAL(ftrace_regs_caller_end) |
253 | 255 | ||
254 | jmp ftrace_return | 256 | jmp ftrace_epilogue |
255 | 257 | ||
256 | END(ftrace_regs_caller) | 258 | END(ftrace_regs_caller) |
257 | 259 | ||
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c index 64f9616f93f1..7f3550acde1b 100644 --- a/arch/x86/kernel/msr.c +++ b/arch/x86/kernel/msr.c | |||
@@ -40,7 +40,7 @@ | |||
40 | #include <linux/uaccess.h> | 40 | #include <linux/uaccess.h> |
41 | #include <linux/gfp.h> | 41 | #include <linux/gfp.h> |
42 | 42 | ||
43 | #include <asm/processor.h> | 43 | #include <asm/cpufeature.h> |
44 | #include <asm/msr.h> | 44 | #include <asm/msr.h> |
45 | 45 | ||
46 | static struct class *msr_class; | 46 | static struct class *msr_class; |
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index cb6282c3638f..548ddf7d6fd2 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c | |||
@@ -61,7 +61,38 @@ | |||
61 | regs->seg = GET_SEG(seg) | 3; \ | 61 | regs->seg = GET_SEG(seg) | 3; \ |
62 | } while (0) | 62 | } while (0) |
63 | 63 | ||
64 | int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) | 64 | #ifdef CONFIG_X86_64 |
65 | /* | ||
66 | * If regs->ss will cause an IRET fault, change it. Otherwise leave it | ||
67 | * alone. Using this generally makes no sense unless | ||
68 | * user_64bit_mode(regs) would return true. | ||
69 | */ | ||
70 | static void force_valid_ss(struct pt_regs *regs) | ||
71 | { | ||
72 | u32 ar; | ||
73 | asm volatile ("lar %[old_ss], %[ar]\n\t" | ||
74 | "jz 1f\n\t" /* If invalid: */ | ||
75 | "xorl %[ar], %[ar]\n\t" /* set ar = 0 */ | ||
76 | "1:" | ||
77 | : [ar] "=r" (ar) | ||
78 | : [old_ss] "rm" ((u16)regs->ss)); | ||
79 | |||
80 | /* | ||
81 | * For a valid 64-bit user context, we need DPL 3, type | ||
82 | * read-write data or read-write exp-down data, and S and P | ||
83 | * set. We can't use VERW because VERW doesn't check the | ||
84 | * P bit. | ||
85 | */ | ||
86 | ar &= AR_DPL_MASK | AR_S | AR_P | AR_TYPE_MASK; | ||
87 | if (ar != (AR_DPL3 | AR_S | AR_P | AR_TYPE_RWDATA) && | ||
88 | ar != (AR_DPL3 | AR_S | AR_P | AR_TYPE_RWDATA_EXPDOWN)) | ||
89 | regs->ss = __USER_DS; | ||
90 | } | ||
91 | #endif | ||
92 | |||
93 | static int restore_sigcontext(struct pt_regs *regs, | ||
94 | struct sigcontext __user *sc, | ||
95 | unsigned long uc_flags) | ||
65 | { | 96 | { |
66 | unsigned long buf_val; | 97 | unsigned long buf_val; |
67 | void __user *buf; | 98 | void __user *buf; |
@@ -94,15 +125,18 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) | |||
94 | COPY(r15); | 125 | COPY(r15); |
95 | #endif /* CONFIG_X86_64 */ | 126 | #endif /* CONFIG_X86_64 */ |
96 | 127 | ||
97 | #ifdef CONFIG_X86_32 | ||
98 | COPY_SEG_CPL3(cs); | 128 | COPY_SEG_CPL3(cs); |
99 | COPY_SEG_CPL3(ss); | 129 | COPY_SEG_CPL3(ss); |
100 | #else /* !CONFIG_X86_32 */ | 130 | |
101 | /* Kernel saves and restores only the CS segment register on signals, | 131 | #ifdef CONFIG_X86_64 |
102 | * which is the bare minimum needed to allow mixed 32/64-bit code. | 132 | /* |
103 | * App's signal handler can save/restore other segments if needed. */ | 133 | * Fix up SS if needed for the benefit of old DOSEMU and |
104 | COPY_SEG_CPL3(cs); | 134 | * CRIU. |
105 | #endif /* CONFIG_X86_32 */ | 135 | */ |
136 | if (unlikely(!(uc_flags & UC_STRICT_RESTORE_SS) && | ||
137 | user_64bit_mode(regs))) | ||
138 | force_valid_ss(regs); | ||
139 | #endif | ||
106 | 140 | ||
107 | get_user_ex(tmpflags, &sc->flags); | 141 | get_user_ex(tmpflags, &sc->flags); |
108 | regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS); | 142 | regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS); |
@@ -165,6 +199,7 @@ int setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate, | |||
165 | put_user_ex(regs->cs, &sc->cs); | 199 | put_user_ex(regs->cs, &sc->cs); |
166 | put_user_ex(0, &sc->gs); | 200 | put_user_ex(0, &sc->gs); |
167 | put_user_ex(0, &sc->fs); | 201 | put_user_ex(0, &sc->fs); |
202 | put_user_ex(regs->ss, &sc->ss); | ||
168 | #endif /* CONFIG_X86_32 */ | 203 | #endif /* CONFIG_X86_32 */ |
169 | 204 | ||
170 | put_user_ex(fpstate, &sc->fpstate); | 205 | put_user_ex(fpstate, &sc->fpstate); |
@@ -403,6 +438,21 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig, | |||
403 | return 0; | 438 | return 0; |
404 | } | 439 | } |
405 | #else /* !CONFIG_X86_32 */ | 440 | #else /* !CONFIG_X86_32 */ |
441 | static unsigned long frame_uc_flags(struct pt_regs *regs) | ||
442 | { | ||
443 | unsigned long flags; | ||
444 | |||
445 | if (cpu_has_xsave) | ||
446 | flags = UC_FP_XSTATE | UC_SIGCONTEXT_SS; | ||
447 | else | ||
448 | flags = UC_SIGCONTEXT_SS; | ||
449 | |||
450 | if (likely(user_64bit_mode(regs))) | ||
451 | flags |= UC_STRICT_RESTORE_SS; | ||
452 | |||
453 | return flags; | ||
454 | } | ||
455 | |||
406 | static int __setup_rt_frame(int sig, struct ksignal *ksig, | 456 | static int __setup_rt_frame(int sig, struct ksignal *ksig, |
407 | sigset_t *set, struct pt_regs *regs) | 457 | sigset_t *set, struct pt_regs *regs) |
408 | { | 458 | { |
@@ -422,10 +472,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig, | |||
422 | 472 | ||
423 | put_user_try { | 473 | put_user_try { |
424 | /* Create the ucontext. */ | 474 | /* Create the ucontext. */ |
425 | if (cpu_has_xsave) | 475 | put_user_ex(frame_uc_flags(regs), &frame->uc.uc_flags); |
426 | put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags); | ||
427 | else | ||
428 | put_user_ex(0, &frame->uc.uc_flags); | ||
429 | put_user_ex(0, &frame->uc.uc_link); | 476 | put_user_ex(0, &frame->uc.uc_link); |
430 | save_altstack_ex(&frame->uc.uc_stack, regs->sp); | 477 | save_altstack_ex(&frame->uc.uc_stack, regs->sp); |
431 | 478 | ||
@@ -459,10 +506,28 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig, | |||
459 | 506 | ||
460 | regs->sp = (unsigned long)frame; | 507 | regs->sp = (unsigned long)frame; |
461 | 508 | ||
462 | /* Set up the CS register to run signal handlers in 64-bit mode, | 509 | /* |
463 | even if the handler happens to be interrupting 32-bit code. */ | 510 | * Set up the CS and SS registers to run signal handlers in |
511 | * 64-bit mode, even if the handler happens to be interrupting | ||
512 | * 32-bit or 16-bit code. | ||
513 | * | ||
514 | * SS is subtle. In 64-bit mode, we don't need any particular | ||
515 | * SS descriptor, but we do need SS to be valid. It's possible | ||
516 | * that the old SS is entirely bogus -- this can happen if the | ||
517 | * signal we're trying to deliver is #GP or #SS caused by a bad | ||
518 | * SS value. We also have a compatbility issue here: DOSEMU | ||
519 | * relies on the contents of the SS register indicating the | ||
520 | * SS value at the time of the signal, even though that code in | ||
521 | * DOSEMU predates sigreturn's ability to restore SS. (DOSEMU | ||
522 | * avoids relying on sigreturn to restore SS; instead it uses | ||
523 | * a trampoline.) So we do our best: if the old SS was valid, | ||
524 | * we keep it. Otherwise we replace it. | ||
525 | */ | ||
464 | regs->cs = __USER_CS; | 526 | regs->cs = __USER_CS; |
465 | 527 | ||
528 | if (unlikely(regs->ss != __USER_DS)) | ||
529 | force_valid_ss(regs); | ||
530 | |||
466 | return 0; | 531 | return 0; |
467 | } | 532 | } |
468 | #endif /* CONFIG_X86_32 */ | 533 | #endif /* CONFIG_X86_32 */ |
@@ -489,10 +554,7 @@ static int x32_setup_rt_frame(struct ksignal *ksig, | |||
489 | 554 | ||
490 | put_user_try { | 555 | put_user_try { |
491 | /* Create the ucontext. */ | 556 | /* Create the ucontext. */ |
492 | if (cpu_has_xsave) | 557 | put_user_ex(frame_uc_flags(regs), &frame->uc.uc_flags); |
493 | put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags); | ||
494 | else | ||
495 | put_user_ex(0, &frame->uc.uc_flags); | ||
496 | put_user_ex(0, &frame->uc.uc_link); | 558 | put_user_ex(0, &frame->uc.uc_link); |
497 | compat_save_altstack_ex(&frame->uc.uc_stack, regs->sp); | 559 | compat_save_altstack_ex(&frame->uc.uc_stack, regs->sp); |
498 | put_user_ex(0, &frame->uc.uc__pad0); | 560 | put_user_ex(0, &frame->uc.uc__pad0); |
@@ -554,7 +616,11 @@ asmlinkage unsigned long sys_sigreturn(void) | |||
554 | 616 | ||
555 | set_current_blocked(&set); | 617 | set_current_blocked(&set); |
556 | 618 | ||
557 | if (restore_sigcontext(regs, &frame->sc)) | 619 | /* |
620 | * x86_32 has no uc_flags bits relevant to restore_sigcontext. | ||
621 | * Save a few cycles by skipping the __get_user. | ||
622 | */ | ||
623 | if (restore_sigcontext(regs, &frame->sc, 0)) | ||
558 | goto badframe; | 624 | goto badframe; |
559 | return regs->ax; | 625 | return regs->ax; |
560 | 626 | ||
@@ -570,16 +636,19 @@ asmlinkage long sys_rt_sigreturn(void) | |||
570 | struct pt_regs *regs = current_pt_regs(); | 636 | struct pt_regs *regs = current_pt_regs(); |
571 | struct rt_sigframe __user *frame; | 637 | struct rt_sigframe __user *frame; |
572 | sigset_t set; | 638 | sigset_t set; |
639 | unsigned long uc_flags; | ||
573 | 640 | ||
574 | frame = (struct rt_sigframe __user *)(regs->sp - sizeof(long)); | 641 | frame = (struct rt_sigframe __user *)(regs->sp - sizeof(long)); |
575 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | 642 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) |
576 | goto badframe; | 643 | goto badframe; |
577 | if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) | 644 | if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) |
578 | goto badframe; | 645 | goto badframe; |
646 | if (__get_user(uc_flags, &frame->uc.uc_flags)) | ||
647 | goto badframe; | ||
579 | 648 | ||
580 | set_current_blocked(&set); | 649 | set_current_blocked(&set); |
581 | 650 | ||
582 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) | 651 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext, uc_flags)) |
583 | goto badframe; | 652 | goto badframe; |
584 | 653 | ||
585 | if (restore_altstack(&frame->uc.uc_stack)) | 654 | if (restore_altstack(&frame->uc.uc_stack)) |
@@ -692,12 +761,15 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs) | |||
692 | 761 | ||
693 | static inline unsigned long get_nr_restart_syscall(const struct pt_regs *regs) | 762 | static inline unsigned long get_nr_restart_syscall(const struct pt_regs *regs) |
694 | { | 763 | { |
695 | #if defined(CONFIG_X86_32) || !defined(CONFIG_X86_64) | 764 | #ifdef CONFIG_X86_64 |
765 | if (is_ia32_task()) | ||
766 | return __NR_ia32_restart_syscall; | ||
767 | #endif | ||
768 | #ifdef CONFIG_X86_X32_ABI | ||
769 | return __NR_restart_syscall | (regs->orig_ax & __X32_SYSCALL_BIT); | ||
770 | #else | ||
696 | return __NR_restart_syscall; | 771 | return __NR_restart_syscall; |
697 | #else /* !CONFIG_X86_32 && CONFIG_X86_64 */ | 772 | #endif |
698 | return test_thread_flag(TIF_IA32) ? __NR_ia32_restart_syscall : | ||
699 | __NR_restart_syscall | (regs->orig_ax & __X32_SYSCALL_BIT); | ||
700 | #endif /* CONFIG_X86_32 || !CONFIG_X86_64 */ | ||
701 | } | 773 | } |
702 | 774 | ||
703 | /* | 775 | /* |
@@ -763,6 +835,7 @@ asmlinkage long sys32_x32_rt_sigreturn(void) | |||
763 | struct pt_regs *regs = current_pt_regs(); | 835 | struct pt_regs *regs = current_pt_regs(); |
764 | struct rt_sigframe_x32 __user *frame; | 836 | struct rt_sigframe_x32 __user *frame; |
765 | sigset_t set; | 837 | sigset_t set; |
838 | unsigned long uc_flags; | ||
766 | 839 | ||
767 | frame = (struct rt_sigframe_x32 __user *)(regs->sp - 8); | 840 | frame = (struct rt_sigframe_x32 __user *)(regs->sp - 8); |
768 | 841 | ||
@@ -770,10 +843,12 @@ asmlinkage long sys32_x32_rt_sigreturn(void) | |||
770 | goto badframe; | 843 | goto badframe; |
771 | if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) | 844 | if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) |
772 | goto badframe; | 845 | goto badframe; |
846 | if (__get_user(uc_flags, &frame->uc.uc_flags)) | ||
847 | goto badframe; | ||
773 | 848 | ||
774 | set_current_blocked(&set); | 849 | set_current_blocked(&set); |
775 | 850 | ||
776 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) | 851 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext, uc_flags)) |
777 | goto badframe; | 852 | goto badframe; |
778 | 853 | ||
779 | if (compat_restore_altstack(&frame->uc.uc_stack)) | 854 | if (compat_restore_altstack(&frame->uc.uc_stack)) |
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index ade185a46b1d..410e8e2700c5 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
@@ -83,30 +83,16 @@ gate_desc idt_table[NR_VECTORS] __page_aligned_bss; | |||
83 | DECLARE_BITMAP(used_vectors, NR_VECTORS); | 83 | DECLARE_BITMAP(used_vectors, NR_VECTORS); |
84 | EXPORT_SYMBOL_GPL(used_vectors); | 84 | EXPORT_SYMBOL_GPL(used_vectors); |
85 | 85 | ||
86 | static inline void conditional_sti(struct pt_regs *regs) | 86 | static inline void cond_local_irq_enable(struct pt_regs *regs) |
87 | { | 87 | { |
88 | if (regs->flags & X86_EFLAGS_IF) | 88 | if (regs->flags & X86_EFLAGS_IF) |
89 | local_irq_enable(); | 89 | local_irq_enable(); |
90 | } | 90 | } |
91 | 91 | ||
92 | static inline void preempt_conditional_sti(struct pt_regs *regs) | 92 | static inline void cond_local_irq_disable(struct pt_regs *regs) |
93 | { | ||
94 | preempt_count_inc(); | ||
95 | if (regs->flags & X86_EFLAGS_IF) | ||
96 | local_irq_enable(); | ||
97 | } | ||
98 | |||
99 | static inline void conditional_cli(struct pt_regs *regs) | ||
100 | { | ||
101 | if (regs->flags & X86_EFLAGS_IF) | ||
102 | local_irq_disable(); | ||
103 | } | ||
104 | |||
105 | static inline void preempt_conditional_cli(struct pt_regs *regs) | ||
106 | { | 93 | { |
107 | if (regs->flags & X86_EFLAGS_IF) | 94 | if (regs->flags & X86_EFLAGS_IF) |
108 | local_irq_disable(); | 95 | local_irq_disable(); |
109 | preempt_count_dec(); | ||
110 | } | 96 | } |
111 | 97 | ||
112 | void ist_enter(struct pt_regs *regs) | 98 | void ist_enter(struct pt_regs *regs) |
@@ -286,7 +272,7 @@ static void do_error_trap(struct pt_regs *regs, long error_code, char *str, | |||
286 | 272 | ||
287 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) != | 273 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) != |
288 | NOTIFY_STOP) { | 274 | NOTIFY_STOP) { |
289 | conditional_sti(regs); | 275 | cond_local_irq_enable(regs); |
290 | do_trap(trapnr, signr, str, regs, error_code, | 276 | do_trap(trapnr, signr, str, regs, error_code, |
291 | fill_trap_info(regs, signr, trapnr, &info)); | 277 | fill_trap_info(regs, signr, trapnr, &info)); |
292 | } | 278 | } |
@@ -368,7 +354,7 @@ dotraplinkage void do_bounds(struct pt_regs *regs, long error_code) | |||
368 | if (notify_die(DIE_TRAP, "bounds", regs, error_code, | 354 | if (notify_die(DIE_TRAP, "bounds", regs, error_code, |
369 | X86_TRAP_BR, SIGSEGV) == NOTIFY_STOP) | 355 | X86_TRAP_BR, SIGSEGV) == NOTIFY_STOP) |
370 | return; | 356 | return; |
371 | conditional_sti(regs); | 357 | cond_local_irq_enable(regs); |
372 | 358 | ||
373 | if (!user_mode(regs)) | 359 | if (!user_mode(regs)) |
374 | die("bounds", regs, error_code); | 360 | die("bounds", regs, error_code); |
@@ -443,7 +429,7 @@ do_general_protection(struct pt_regs *regs, long error_code) | |||
443 | struct task_struct *tsk; | 429 | struct task_struct *tsk; |
444 | 430 | ||
445 | RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU"); | 431 | RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU"); |
446 | conditional_sti(regs); | 432 | cond_local_irq_enable(regs); |
447 | 433 | ||
448 | if (v8086_mode(regs)) { | 434 | if (v8086_mode(regs)) { |
449 | local_irq_enable(); | 435 | local_irq_enable(); |
@@ -517,9 +503,11 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code) | |||
517 | * as we may switch to the interrupt stack. | 503 | * as we may switch to the interrupt stack. |
518 | */ | 504 | */ |
519 | debug_stack_usage_inc(); | 505 | debug_stack_usage_inc(); |
520 | preempt_conditional_sti(regs); | 506 | preempt_disable(); |
507 | cond_local_irq_enable(regs); | ||
521 | do_trap(X86_TRAP_BP, SIGTRAP, "int3", regs, error_code, NULL); | 508 | do_trap(X86_TRAP_BP, SIGTRAP, "int3", regs, error_code, NULL); |
522 | preempt_conditional_cli(regs); | 509 | cond_local_irq_disable(regs); |
510 | preempt_enable_no_resched(); | ||
523 | debug_stack_usage_dec(); | 511 | debug_stack_usage_dec(); |
524 | exit: | 512 | exit: |
525 | ist_exit(regs); | 513 | ist_exit(regs); |
@@ -648,12 +636,14 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code) | |||
648 | debug_stack_usage_inc(); | 636 | debug_stack_usage_inc(); |
649 | 637 | ||
650 | /* It's safe to allow irq's after DR6 has been saved */ | 638 | /* It's safe to allow irq's after DR6 has been saved */ |
651 | preempt_conditional_sti(regs); | 639 | preempt_disable(); |
640 | cond_local_irq_enable(regs); | ||
652 | 641 | ||
653 | if (v8086_mode(regs)) { | 642 | if (v8086_mode(regs)) { |
654 | handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, | 643 | handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, |
655 | X86_TRAP_DB); | 644 | X86_TRAP_DB); |
656 | preempt_conditional_cli(regs); | 645 | cond_local_irq_disable(regs); |
646 | preempt_enable_no_resched(); | ||
657 | debug_stack_usage_dec(); | 647 | debug_stack_usage_dec(); |
658 | goto exit; | 648 | goto exit; |
659 | } | 649 | } |
@@ -673,7 +663,8 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code) | |||
673 | si_code = get_si_code(tsk->thread.debugreg6); | 663 | si_code = get_si_code(tsk->thread.debugreg6); |
674 | if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS) || user_icebp) | 664 | if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS) || user_icebp) |
675 | send_sigtrap(tsk, regs, error_code, si_code); | 665 | send_sigtrap(tsk, regs, error_code, si_code); |
676 | preempt_conditional_cli(regs); | 666 | cond_local_irq_disable(regs); |
667 | preempt_enable_no_resched(); | ||
677 | debug_stack_usage_dec(); | 668 | debug_stack_usage_dec(); |
678 | 669 | ||
679 | exit: | 670 | exit: |
@@ -696,7 +687,7 @@ static void math_error(struct pt_regs *regs, int error_code, int trapnr) | |||
696 | 687 | ||
697 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, SIGFPE) == NOTIFY_STOP) | 688 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, SIGFPE) == NOTIFY_STOP) |
698 | return; | 689 | return; |
699 | conditional_sti(regs); | 690 | cond_local_irq_enable(regs); |
700 | 691 | ||
701 | if (!user_mode(regs)) { | 692 | if (!user_mode(regs)) { |
702 | if (!fixup_exception(regs)) { | 693 | if (!fixup_exception(regs)) { |
@@ -743,7 +734,7 @@ do_simd_coprocessor_error(struct pt_regs *regs, long error_code) | |||
743 | dotraplinkage void | 734 | dotraplinkage void |
744 | do_spurious_interrupt_bug(struct pt_regs *regs, long error_code) | 735 | do_spurious_interrupt_bug(struct pt_regs *regs, long error_code) |
745 | { | 736 | { |
746 | conditional_sti(regs); | 737 | cond_local_irq_enable(regs); |
747 | } | 738 | } |
748 | 739 | ||
749 | dotraplinkage void | 740 | dotraplinkage void |
@@ -756,7 +747,7 @@ do_device_not_available(struct pt_regs *regs, long error_code) | |||
756 | if (read_cr0() & X86_CR0_EM) { | 747 | if (read_cr0() & X86_CR0_EM) { |
757 | struct math_emu_info info = { }; | 748 | struct math_emu_info info = { }; |
758 | 749 | ||
759 | conditional_sti(regs); | 750 | cond_local_irq_enable(regs); |
760 | 751 | ||
761 | info.regs = regs; | 752 | info.regs = regs; |
762 | math_emulate(&info); | 753 | math_emulate(&info); |
@@ -765,7 +756,7 @@ do_device_not_available(struct pt_regs *regs, long error_code) | |||
765 | #endif | 756 | #endif |
766 | fpu__restore(¤t->thread.fpu); /* interrupts still off */ | 757 | fpu__restore(¤t->thread.fpu); /* interrupts still off */ |
767 | #ifdef CONFIG_X86_32 | 758 | #ifdef CONFIG_X86_32 |
768 | conditional_sti(regs); | 759 | cond_local_irq_enable(regs); |
769 | #endif | 760 | #endif |
770 | } | 761 | } |
771 | NOKPROBE_SYMBOL(do_device_not_available); | 762 | NOKPROBE_SYMBOL(do_device_not_available); |
diff --git a/arch/x86/kernel/verify_cpu.S b/arch/x86/kernel/verify_cpu.S index 07efb35ee4bc..014ea59aa153 100644 --- a/arch/x86/kernel/verify_cpu.S +++ b/arch/x86/kernel/verify_cpu.S | |||
@@ -30,7 +30,7 @@ | |||
30 | * appropriately. Either display a message or halt. | 30 | * appropriately. Either display a message or halt. |
31 | */ | 31 | */ |
32 | 32 | ||
33 | #include <asm/cpufeature.h> | 33 | #include <asm/cpufeatures.h> |
34 | #include <asm/msr-index.h> | 34 | #include <asm/msr-index.h> |
35 | 35 | ||
36 | verify_cpu: | 36 | verify_cpu: |
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c index e574b8546518..3dce1ca0a653 100644 --- a/arch/x86/kernel/vm86_32.c +++ b/arch/x86/kernel/vm86_32.c | |||
@@ -362,7 +362,7 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus) | |||
362 | /* make room for real-mode segments */ | 362 | /* make room for real-mode segments */ |
363 | tsk->thread.sp0 += 16; | 363 | tsk->thread.sp0 += 16; |
364 | 364 | ||
365 | if (static_cpu_has_safe(X86_FEATURE_SEP)) | 365 | if (static_cpu_has(X86_FEATURE_SEP)) |
366 | tsk->thread.sysenter_cs = 0; | 366 | tsk->thread.sysenter_cs = 0; |
367 | 367 | ||
368 | load_sp0(tss, &tsk->thread); | 368 | load_sp0(tss, &tsk->thread); |
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 74e4bf11f562..92dc211c11db 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S | |||
@@ -195,6 +195,17 @@ SECTIONS | |||
195 | :init | 195 | :init |
196 | #endif | 196 | #endif |
197 | 197 | ||
198 | /* | ||
199 | * Section for code used exclusively before alternatives are run. All | ||
200 | * references to such code must be patched out by alternatives, normally | ||
201 | * by using X86_FEATURE_ALWAYS CPU feature bit. | ||
202 | * | ||
203 | * See static_cpu_has() for an example. | ||
204 | */ | ||
205 | .altinstr_aux : AT(ADDR(.altinstr_aux) - LOAD_OFFSET) { | ||
206 | *(.altinstr_aux) | ||
207 | } | ||
208 | |||
198 | INIT_DATA_SECTION(16) | 209 | INIT_DATA_SECTION(16) |
199 | 210 | ||
200 | .x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) { | 211 | .x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) { |
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 1505587d06e9..80363ebfd0a6 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -309,23 +309,29 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt) | |||
309 | 309 | ||
310 | static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *)); | 310 | static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *)); |
311 | 311 | ||
312 | #define FOP_ALIGN ".align " __stringify(FASTOP_SIZE) " \n\t" | 312 | #define FOP_FUNC(name) \ |
313 | ".align " __stringify(FASTOP_SIZE) " \n\t" \ | ||
314 | ".type " name ", @function \n\t" \ | ||
315 | name ":\n\t" | ||
316 | |||
313 | #define FOP_RET "ret \n\t" | 317 | #define FOP_RET "ret \n\t" |
314 | 318 | ||
315 | #define FOP_START(op) \ | 319 | #define FOP_START(op) \ |
316 | extern void em_##op(struct fastop *fake); \ | 320 | extern void em_##op(struct fastop *fake); \ |
317 | asm(".pushsection .text, \"ax\" \n\t" \ | 321 | asm(".pushsection .text, \"ax\" \n\t" \ |
318 | ".global em_" #op " \n\t" \ | 322 | ".global em_" #op " \n\t" \ |
319 | FOP_ALIGN \ | 323 | FOP_FUNC("em_" #op) |
320 | "em_" #op ": \n\t" | ||
321 | 324 | ||
322 | #define FOP_END \ | 325 | #define FOP_END \ |
323 | ".popsection") | 326 | ".popsection") |
324 | 327 | ||
325 | #define FOPNOP() FOP_ALIGN FOP_RET | 328 | #define FOPNOP() \ |
329 | FOP_FUNC(__stringify(__UNIQUE_ID(nop))) \ | ||
330 | FOP_RET | ||
326 | 331 | ||
327 | #define FOP1E(op, dst) \ | 332 | #define FOP1E(op, dst) \ |
328 | FOP_ALIGN "10: " #op " %" #dst " \n\t" FOP_RET | 333 | FOP_FUNC(#op "_" #dst) \ |
334 | "10: " #op " %" #dst " \n\t" FOP_RET | ||
329 | 335 | ||
330 | #define FOP1EEX(op, dst) \ | 336 | #define FOP1EEX(op, dst) \ |
331 | FOP1E(op, dst) _ASM_EXTABLE(10b, kvm_fastop_exception) | 337 | FOP1E(op, dst) _ASM_EXTABLE(10b, kvm_fastop_exception) |
@@ -357,7 +363,8 @@ static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *)); | |||
357 | FOP_END | 363 | FOP_END |
358 | 364 | ||
359 | #define FOP2E(op, dst, src) \ | 365 | #define FOP2E(op, dst, src) \ |
360 | FOP_ALIGN #op " %" #src ", %" #dst " \n\t" FOP_RET | 366 | FOP_FUNC(#op "_" #dst "_" #src) \ |
367 | #op " %" #src ", %" #dst " \n\t" FOP_RET | ||
361 | 368 | ||
362 | #define FASTOP2(op) \ | 369 | #define FASTOP2(op) \ |
363 | FOP_START(op) \ | 370 | FOP_START(op) \ |
@@ -395,7 +402,8 @@ static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *)); | |||
395 | FOP_END | 402 | FOP_END |
396 | 403 | ||
397 | #define FOP3E(op, dst, src, src2) \ | 404 | #define FOP3E(op, dst, src, src2) \ |
398 | FOP_ALIGN #op " %" #src2 ", %" #src ", %" #dst " \n\t" FOP_RET | 405 | FOP_FUNC(#op "_" #dst "_" #src "_" #src2) \ |
406 | #op " %" #src2 ", %" #src ", %" #dst " \n\t" FOP_RET | ||
399 | 407 | ||
400 | /* 3-operand, word-only, src2=cl */ | 408 | /* 3-operand, word-only, src2=cl */ |
401 | #define FASTOP3WCL(op) \ | 409 | #define FASTOP3WCL(op) \ |
@@ -407,7 +415,12 @@ static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *)); | |||
407 | FOP_END | 415 | FOP_END |
408 | 416 | ||
409 | /* Special case for SETcc - 1 instruction per cc */ | 417 | /* Special case for SETcc - 1 instruction per cc */ |
410 | #define FOP_SETCC(op) ".align 4; " #op " %al; ret \n\t" | 418 | #define FOP_SETCC(op) \ |
419 | ".align 4 \n\t" \ | ||
420 | ".type " #op ", @function \n\t" \ | ||
421 | #op ": \n\t" \ | ||
422 | #op " %al \n\t" \ | ||
423 | FOP_RET | ||
411 | 424 | ||
412 | asm(".global kvm_fastop_exception \n" | 425 | asm(".global kvm_fastop_exception \n" |
413 | "kvm_fastop_exception: xor %esi, %esi; ret"); | 426 | "kvm_fastop_exception: xor %esi, %esi; ret"); |
@@ -956,7 +969,7 @@ static int em_bsr_c(struct x86_emulate_ctxt *ctxt) | |||
956 | return fastop(ctxt, em_bsr); | 969 | return fastop(ctxt, em_bsr); |
957 | } | 970 | } |
958 | 971 | ||
959 | static u8 test_cc(unsigned int condition, unsigned long flags) | 972 | static __always_inline u8 test_cc(unsigned int condition, unsigned long flags) |
960 | { | 973 | { |
961 | u8 rc; | 974 | u8 rc; |
962 | void (*fop)(void) = (void *)em_setcc + 4 * (condition & 0xf); | 975 | void (*fop)(void) = (void *)em_setcc + 4 * (condition & 0xf); |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index e2951b6edbbc..e1535225bc1d 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -8356,6 +8356,7 @@ static void vmx_complete_atomic_exit(struct vcpu_vmx *vmx) | |||
8356 | static void vmx_handle_external_intr(struct kvm_vcpu *vcpu) | 8356 | static void vmx_handle_external_intr(struct kvm_vcpu *vcpu) |
8357 | { | 8357 | { |
8358 | u32 exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO); | 8358 | u32 exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO); |
8359 | register void *__sp asm(_ASM_SP); | ||
8359 | 8360 | ||
8360 | /* | 8361 | /* |
8361 | * If external interrupt exists, IF bit is set in rflags/eflags on the | 8362 | * If external interrupt exists, IF bit is set in rflags/eflags on the |
@@ -8388,8 +8389,9 @@ static void vmx_handle_external_intr(struct kvm_vcpu *vcpu) | |||
8388 | "call *%[entry]\n\t" | 8389 | "call *%[entry]\n\t" |
8389 | : | 8390 | : |
8390 | #ifdef CONFIG_X86_64 | 8391 | #ifdef CONFIG_X86_64 |
8391 | [sp]"=&r"(tmp) | 8392 | [sp]"=&r"(tmp), |
8392 | #endif | 8393 | #endif |
8394 | "+r"(__sp) | ||
8393 | : | 8395 | : |
8394 | [entry]"r"(entry), | 8396 | [entry]"r"(entry), |
8395 | [ss]"i"(__KERNEL_DS), | 8397 | [ss]"i"(__KERNEL_DS), |
diff --git a/arch/x86/lib/clear_page_64.S b/arch/x86/lib/clear_page_64.S index a2fe51b00cce..65be7cfaf947 100644 --- a/arch/x86/lib/clear_page_64.S +++ b/arch/x86/lib/clear_page_64.S | |||
@@ -1,5 +1,5 @@ | |||
1 | #include <linux/linkage.h> | 1 | #include <linux/linkage.h> |
2 | #include <asm/cpufeature.h> | 2 | #include <asm/cpufeatures.h> |
3 | #include <asm/alternative-asm.h> | 3 | #include <asm/alternative-asm.h> |
4 | 4 | ||
5 | /* | 5 | /* |
diff --git a/arch/x86/lib/copy_page_64.S b/arch/x86/lib/copy_page_64.S index 009f98216b7e..24ef1c2104d4 100644 --- a/arch/x86/lib/copy_page_64.S +++ b/arch/x86/lib/copy_page_64.S | |||
@@ -1,7 +1,7 @@ | |||
1 | /* Written 2003 by Andi Kleen, based on a kernel by Evandro Menezes */ | 1 | /* Written 2003 by Andi Kleen, based on a kernel by Evandro Menezes */ |
2 | 2 | ||
3 | #include <linux/linkage.h> | 3 | #include <linux/linkage.h> |
4 | #include <asm/cpufeature.h> | 4 | #include <asm/cpufeatures.h> |
5 | #include <asm/alternative-asm.h> | 5 | #include <asm/alternative-asm.h> |
6 | 6 | ||
7 | /* | 7 | /* |
diff --git a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S index 27f89c79a44b..2b0ef26da0bd 100644 --- a/arch/x86/lib/copy_user_64.S +++ b/arch/x86/lib/copy_user_64.S | |||
@@ -10,7 +10,7 @@ | |||
10 | #include <asm/current.h> | 10 | #include <asm/current.h> |
11 | #include <asm/asm-offsets.h> | 11 | #include <asm/asm-offsets.h> |
12 | #include <asm/thread_info.h> | 12 | #include <asm/thread_info.h> |
13 | #include <asm/cpufeature.h> | 13 | #include <asm/cpufeatures.h> |
14 | #include <asm/alternative-asm.h> | 14 | #include <asm/alternative-asm.h> |
15 | #include <asm/asm.h> | 15 | #include <asm/asm.h> |
16 | #include <asm/smap.h> | 16 | #include <asm/smap.h> |
diff --git a/arch/x86/lib/memcpy_64.S b/arch/x86/lib/memcpy_64.S index 16698bba87de..a0de849435ad 100644 --- a/arch/x86/lib/memcpy_64.S +++ b/arch/x86/lib/memcpy_64.S | |||
@@ -1,7 +1,7 @@ | |||
1 | /* Copyright 2002 Andi Kleen */ | 1 | /* Copyright 2002 Andi Kleen */ |
2 | 2 | ||
3 | #include <linux/linkage.h> | 3 | #include <linux/linkage.h> |
4 | #include <asm/cpufeature.h> | 4 | #include <asm/cpufeatures.h> |
5 | #include <asm/alternative-asm.h> | 5 | #include <asm/alternative-asm.h> |
6 | 6 | ||
7 | /* | 7 | /* |
diff --git a/arch/x86/lib/memmove_64.S b/arch/x86/lib/memmove_64.S index ca2afdd6d98e..90ce01bee00c 100644 --- a/arch/x86/lib/memmove_64.S +++ b/arch/x86/lib/memmove_64.S | |||
@@ -6,7 +6,7 @@ | |||
6 | * - Copyright 2011 Fenghua Yu <fenghua.yu@intel.com> | 6 | * - Copyright 2011 Fenghua Yu <fenghua.yu@intel.com> |
7 | */ | 7 | */ |
8 | #include <linux/linkage.h> | 8 | #include <linux/linkage.h> |
9 | #include <asm/cpufeature.h> | 9 | #include <asm/cpufeatures.h> |
10 | #include <asm/alternative-asm.h> | 10 | #include <asm/alternative-asm.h> |
11 | 11 | ||
12 | #undef memmove | 12 | #undef memmove |
diff --git a/arch/x86/lib/memset_64.S b/arch/x86/lib/memset_64.S index 2661fad05827..c9c81227ea37 100644 --- a/arch/x86/lib/memset_64.S +++ b/arch/x86/lib/memset_64.S | |||
@@ -1,7 +1,7 @@ | |||
1 | /* Copyright 2002 Andi Kleen, SuSE Labs */ | 1 | /* Copyright 2002 Andi Kleen, SuSE Labs */ |
2 | 2 | ||
3 | #include <linux/linkage.h> | 3 | #include <linux/linkage.h> |
4 | #include <asm/cpufeature.h> | 4 | #include <asm/cpufeatures.h> |
5 | #include <asm/alternative-asm.h> | 5 | #include <asm/alternative-asm.h> |
6 | 6 | ||
7 | .weak memset | 7 | .weak memset |
diff --git a/arch/x86/lib/rwsem.S b/arch/x86/lib/rwsem.S index 40027db99140..be110efa0096 100644 --- a/arch/x86/lib/rwsem.S +++ b/arch/x86/lib/rwsem.S | |||
@@ -15,6 +15,7 @@ | |||
15 | 15 | ||
16 | #include <linux/linkage.h> | 16 | #include <linux/linkage.h> |
17 | #include <asm/alternative-asm.h> | 17 | #include <asm/alternative-asm.h> |
18 | #include <asm/frame.h> | ||
18 | 19 | ||
19 | #define __ASM_HALF_REG(reg) __ASM_SEL(reg, e##reg) | 20 | #define __ASM_HALF_REG(reg) __ASM_SEL(reg, e##reg) |
20 | #define __ASM_HALF_SIZE(inst) __ASM_SEL(inst##w, inst##l) | 21 | #define __ASM_HALF_SIZE(inst) __ASM_SEL(inst##w, inst##l) |
@@ -84,24 +85,29 @@ | |||
84 | 85 | ||
85 | /* Fix up special calling conventions */ | 86 | /* Fix up special calling conventions */ |
86 | ENTRY(call_rwsem_down_read_failed) | 87 | ENTRY(call_rwsem_down_read_failed) |
88 | FRAME_BEGIN | ||
87 | save_common_regs | 89 | save_common_regs |
88 | __ASM_SIZE(push,) %__ASM_REG(dx) | 90 | __ASM_SIZE(push,) %__ASM_REG(dx) |
89 | movq %rax,%rdi | 91 | movq %rax,%rdi |
90 | call rwsem_down_read_failed | 92 | call rwsem_down_read_failed |
91 | __ASM_SIZE(pop,) %__ASM_REG(dx) | 93 | __ASM_SIZE(pop,) %__ASM_REG(dx) |
92 | restore_common_regs | 94 | restore_common_regs |
95 | FRAME_END | ||
93 | ret | 96 | ret |
94 | ENDPROC(call_rwsem_down_read_failed) | 97 | ENDPROC(call_rwsem_down_read_failed) |
95 | 98 | ||
96 | ENTRY(call_rwsem_down_write_failed) | 99 | ENTRY(call_rwsem_down_write_failed) |
100 | FRAME_BEGIN | ||
97 | save_common_regs | 101 | save_common_regs |
98 | movq %rax,%rdi | 102 | movq %rax,%rdi |
99 | call rwsem_down_write_failed | 103 | call rwsem_down_write_failed |
100 | restore_common_regs | 104 | restore_common_regs |
105 | FRAME_END | ||
101 | ret | 106 | ret |
102 | ENDPROC(call_rwsem_down_write_failed) | 107 | ENDPROC(call_rwsem_down_write_failed) |
103 | 108 | ||
104 | ENTRY(call_rwsem_wake) | 109 | ENTRY(call_rwsem_wake) |
110 | FRAME_BEGIN | ||
105 | /* do nothing if still outstanding active readers */ | 111 | /* do nothing if still outstanding active readers */ |
106 | __ASM_HALF_SIZE(dec) %__ASM_HALF_REG(dx) | 112 | __ASM_HALF_SIZE(dec) %__ASM_HALF_REG(dx) |
107 | jnz 1f | 113 | jnz 1f |
@@ -109,15 +115,18 @@ ENTRY(call_rwsem_wake) | |||
109 | movq %rax,%rdi | 115 | movq %rax,%rdi |
110 | call rwsem_wake | 116 | call rwsem_wake |
111 | restore_common_regs | 117 | restore_common_regs |
112 | 1: ret | 118 | 1: FRAME_END |
119 | ret | ||
113 | ENDPROC(call_rwsem_wake) | 120 | ENDPROC(call_rwsem_wake) |
114 | 121 | ||
115 | ENTRY(call_rwsem_downgrade_wake) | 122 | ENTRY(call_rwsem_downgrade_wake) |
123 | FRAME_BEGIN | ||
116 | save_common_regs | 124 | save_common_regs |
117 | __ASM_SIZE(push,) %__ASM_REG(dx) | 125 | __ASM_SIZE(push,) %__ASM_REG(dx) |
118 | movq %rax,%rdi | 126 | movq %rax,%rdi |
119 | call rwsem_downgrade_wake | 127 | call rwsem_downgrade_wake |
120 | __ASM_SIZE(pop,) %__ASM_REG(dx) | 128 | __ASM_SIZE(pop,) %__ASM_REG(dx) |
121 | restore_common_regs | 129 | restore_common_regs |
130 | FRAME_END | ||
122 | ret | 131 | ret |
123 | ENDPROC(call_rwsem_downgrade_wake) | 132 | ENDPROC(call_rwsem_downgrade_wake) |
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index f4ae536b0914..04e2e7144bee 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c | |||
@@ -943,7 +943,7 @@ int track_pfn_remap(struct vm_area_struct *vma, pgprot_t *prot, | |||
943 | return -EINVAL; | 943 | return -EINVAL; |
944 | } | 944 | } |
945 | 945 | ||
946 | *prot = __pgprot((pgprot_val(vma->vm_page_prot) & (~_PAGE_CACHE_MASK)) | | 946 | *prot = __pgprot((pgprot_val(*prot) & (~_PAGE_CACHE_MASK)) | |
947 | cachemode2protval(pcm)); | 947 | cachemode2protval(pcm)); |
948 | 948 | ||
949 | return 0; | 949 | return 0; |
@@ -959,7 +959,7 @@ int track_pfn_insert(struct vm_area_struct *vma, pgprot_t *prot, | |||
959 | 959 | ||
960 | /* Set prot based on lookup */ | 960 | /* Set prot based on lookup */ |
961 | pcm = lookup_memtype(pfn_t_to_phys(pfn)); | 961 | pcm = lookup_memtype(pfn_t_to_phys(pfn)); |
962 | *prot = __pgprot((pgprot_val(vma->vm_page_prot) & (~_PAGE_CACHE_MASK)) | | 962 | *prot = __pgprot((pgprot_val(*prot) & (~_PAGE_CACHE_MASK)) | |
963 | cachemode2protval(pcm)); | 963 | cachemode2protval(pcm)); |
964 | 964 | ||
965 | return 0; | 965 | return 0; |
diff --git a/arch/x86/mm/setup_nx.c b/arch/x86/mm/setup_nx.c index 92e2eacb3321..f65a33f505b6 100644 --- a/arch/x86/mm/setup_nx.c +++ b/arch/x86/mm/setup_nx.c | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | #include <asm/pgtable.h> | 5 | #include <asm/pgtable.h> |
6 | #include <asm/proto.h> | 6 | #include <asm/proto.h> |
7 | #include <asm/cpufeature.h> | ||
7 | 8 | ||
8 | static int disable_nx; | 9 | static int disable_nx; |
9 | 10 | ||
diff --git a/arch/x86/net/bpf_jit.S b/arch/x86/net/bpf_jit.S index 4093216b3791..f2a7faf4706e 100644 --- a/arch/x86/net/bpf_jit.S +++ b/arch/x86/net/bpf_jit.S | |||
@@ -8,6 +8,7 @@ | |||
8 | * of the License. | 8 | * of the License. |
9 | */ | 9 | */ |
10 | #include <linux/linkage.h> | 10 | #include <linux/linkage.h> |
11 | #include <asm/frame.h> | ||
11 | 12 | ||
12 | /* | 13 | /* |
13 | * Calling convention : | 14 | * Calling convention : |
@@ -22,15 +23,16 @@ | |||
22 | 32 /* space for rbx,r13,r14,r15 */ + \ | 23 | 32 /* space for rbx,r13,r14,r15 */ + \ |
23 | 8 /* space for skb_copy_bits */) | 24 | 8 /* space for skb_copy_bits */) |
24 | 25 | ||
25 | sk_load_word: | 26 | #define FUNC(name) \ |
26 | .globl sk_load_word | 27 | .globl name; \ |
28 | .type name, @function; \ | ||
29 | name: | ||
27 | 30 | ||
31 | FUNC(sk_load_word) | ||
28 | test %esi,%esi | 32 | test %esi,%esi |
29 | js bpf_slow_path_word_neg | 33 | js bpf_slow_path_word_neg |
30 | 34 | ||
31 | sk_load_word_positive_offset: | 35 | FUNC(sk_load_word_positive_offset) |
32 | .globl sk_load_word_positive_offset | ||
33 | |||
34 | mov %r9d,%eax # hlen | 36 | mov %r9d,%eax # hlen |
35 | sub %esi,%eax # hlen - offset | 37 | sub %esi,%eax # hlen - offset |
36 | cmp $3,%eax | 38 | cmp $3,%eax |
@@ -39,15 +41,11 @@ sk_load_word_positive_offset: | |||
39 | bswap %eax /* ntohl() */ | 41 | bswap %eax /* ntohl() */ |
40 | ret | 42 | ret |
41 | 43 | ||
42 | sk_load_half: | 44 | FUNC(sk_load_half) |
43 | .globl sk_load_half | ||
44 | |||
45 | test %esi,%esi | 45 | test %esi,%esi |
46 | js bpf_slow_path_half_neg | 46 | js bpf_slow_path_half_neg |
47 | 47 | ||
48 | sk_load_half_positive_offset: | 48 | FUNC(sk_load_half_positive_offset) |
49 | .globl sk_load_half_positive_offset | ||
50 | |||
51 | mov %r9d,%eax | 49 | mov %r9d,%eax |
52 | sub %esi,%eax # hlen - offset | 50 | sub %esi,%eax # hlen - offset |
53 | cmp $1,%eax | 51 | cmp $1,%eax |
@@ -56,15 +54,11 @@ sk_load_half_positive_offset: | |||
56 | rol $8,%ax # ntohs() | 54 | rol $8,%ax # ntohs() |
57 | ret | 55 | ret |
58 | 56 | ||
59 | sk_load_byte: | 57 | FUNC(sk_load_byte) |
60 | .globl sk_load_byte | ||
61 | |||
62 | test %esi,%esi | 58 | test %esi,%esi |
63 | js bpf_slow_path_byte_neg | 59 | js bpf_slow_path_byte_neg |
64 | 60 | ||
65 | sk_load_byte_positive_offset: | 61 | FUNC(sk_load_byte_positive_offset) |
66 | .globl sk_load_byte_positive_offset | ||
67 | |||
68 | cmp %esi,%r9d /* if (offset >= hlen) goto bpf_slow_path_byte */ | 62 | cmp %esi,%r9d /* if (offset >= hlen) goto bpf_slow_path_byte */ |
69 | jle bpf_slow_path_byte | 63 | jle bpf_slow_path_byte |
70 | movzbl (SKBDATA,%rsi),%eax | 64 | movzbl (SKBDATA,%rsi),%eax |
@@ -72,16 +66,18 @@ sk_load_byte_positive_offset: | |||
72 | 66 | ||
73 | /* rsi contains offset and can be scratched */ | 67 | /* rsi contains offset and can be scratched */ |
74 | #define bpf_slow_path_common(LEN) \ | 68 | #define bpf_slow_path_common(LEN) \ |
69 | lea -MAX_BPF_STACK + 32(%rbp), %rdx;\ | ||
70 | FRAME_BEGIN; \ | ||
75 | mov %rbx, %rdi; /* arg1 == skb */ \ | 71 | mov %rbx, %rdi; /* arg1 == skb */ \ |
76 | push %r9; \ | 72 | push %r9; \ |
77 | push SKBDATA; \ | 73 | push SKBDATA; \ |
78 | /* rsi already has offset */ \ | 74 | /* rsi already has offset */ \ |
79 | mov $LEN,%ecx; /* len */ \ | 75 | mov $LEN,%ecx; /* len */ \ |
80 | lea - MAX_BPF_STACK + 32(%rbp),%rdx; \ | ||
81 | call skb_copy_bits; \ | 76 | call skb_copy_bits; \ |
82 | test %eax,%eax; \ | 77 | test %eax,%eax; \ |
83 | pop SKBDATA; \ | 78 | pop SKBDATA; \ |
84 | pop %r9; | 79 | pop %r9; \ |
80 | FRAME_END | ||
85 | 81 | ||
86 | 82 | ||
87 | bpf_slow_path_word: | 83 | bpf_slow_path_word: |
@@ -106,6 +102,7 @@ bpf_slow_path_byte: | |||
106 | ret | 102 | ret |
107 | 103 | ||
108 | #define sk_negative_common(SIZE) \ | 104 | #define sk_negative_common(SIZE) \ |
105 | FRAME_BEGIN; \ | ||
109 | mov %rbx, %rdi; /* arg1 == skb */ \ | 106 | mov %rbx, %rdi; /* arg1 == skb */ \ |
110 | push %r9; \ | 107 | push %r9; \ |
111 | push SKBDATA; \ | 108 | push SKBDATA; \ |
@@ -115,13 +112,14 @@ bpf_slow_path_byte: | |||
115 | test %rax,%rax; \ | 112 | test %rax,%rax; \ |
116 | pop SKBDATA; \ | 113 | pop SKBDATA; \ |
117 | pop %r9; \ | 114 | pop %r9; \ |
115 | FRAME_END; \ | ||
118 | jz bpf_error | 116 | jz bpf_error |
119 | 117 | ||
120 | bpf_slow_path_word_neg: | 118 | bpf_slow_path_word_neg: |
121 | cmp SKF_MAX_NEG_OFF, %esi /* test range */ | 119 | cmp SKF_MAX_NEG_OFF, %esi /* test range */ |
122 | jl bpf_error /* offset lower -> error */ | 120 | jl bpf_error /* offset lower -> error */ |
123 | sk_load_word_negative_offset: | 121 | |
124 | .globl sk_load_word_negative_offset | 122 | FUNC(sk_load_word_negative_offset) |
125 | sk_negative_common(4) | 123 | sk_negative_common(4) |
126 | mov (%rax), %eax | 124 | mov (%rax), %eax |
127 | bswap %eax | 125 | bswap %eax |
@@ -130,8 +128,8 @@ sk_load_word_negative_offset: | |||
130 | bpf_slow_path_half_neg: | 128 | bpf_slow_path_half_neg: |
131 | cmp SKF_MAX_NEG_OFF, %esi | 129 | cmp SKF_MAX_NEG_OFF, %esi |
132 | jl bpf_error | 130 | jl bpf_error |
133 | sk_load_half_negative_offset: | 131 | |
134 | .globl sk_load_half_negative_offset | 132 | FUNC(sk_load_half_negative_offset) |
135 | sk_negative_common(2) | 133 | sk_negative_common(2) |
136 | mov (%rax),%ax | 134 | mov (%rax),%ax |
137 | rol $8,%ax | 135 | rol $8,%ax |
@@ -141,8 +139,8 @@ sk_load_half_negative_offset: | |||
141 | bpf_slow_path_byte_neg: | 139 | bpf_slow_path_byte_neg: |
142 | cmp SKF_MAX_NEG_OFF, %esi | 140 | cmp SKF_MAX_NEG_OFF, %esi |
143 | jl bpf_error | 141 | jl bpf_error |
144 | sk_load_byte_negative_offset: | 142 | |
145 | .globl sk_load_byte_negative_offset | 143 | FUNC(sk_load_byte_negative_offset) |
146 | sk_negative_common(1) | 144 | sk_negative_common(1) |
147 | movzbl (%rax), %eax | 145 | movzbl (%rax), %eax |
148 | ret | 146 | ret |
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index 50d86c0e9ba4..660a83c8287b 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <asm/nmi.h> | 24 | #include <asm/nmi.h> |
25 | #include <asm/apic.h> | 25 | #include <asm/apic.h> |
26 | #include <asm/processor.h> | 26 | #include <asm/processor.h> |
27 | #include <asm/cpufeature.h> | ||
28 | 27 | ||
29 | #include "op_x86_model.h" | 28 | #include "op_x86_model.h" |
30 | #include "op_counter.h" | 29 | #include "op_counter.h" |
diff --git a/arch/x86/platform/efi/efi_stub_64.S b/arch/x86/platform/efi/efi_stub_64.S index 86d0f9e08dd9..0df2dcc18404 100644 --- a/arch/x86/platform/efi/efi_stub_64.S +++ b/arch/x86/platform/efi/efi_stub_64.S | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <asm/msr.h> | 11 | #include <asm/msr.h> |
12 | #include <asm/processor-flags.h> | 12 | #include <asm/processor-flags.h> |
13 | #include <asm/page_types.h> | 13 | #include <asm/page_types.h> |
14 | #include <asm/frame.h> | ||
14 | 15 | ||
15 | #define SAVE_XMM \ | 16 | #define SAVE_XMM \ |
16 | mov %rsp, %rax; \ | 17 | mov %rsp, %rax; \ |
@@ -74,6 +75,7 @@ | |||
74 | .endm | 75 | .endm |
75 | 76 | ||
76 | ENTRY(efi_call) | 77 | ENTRY(efi_call) |
78 | FRAME_BEGIN | ||
77 | SAVE_XMM | 79 | SAVE_XMM |
78 | mov (%rsp), %rax | 80 | mov (%rsp), %rax |
79 | mov 8(%rax), %rax | 81 | mov 8(%rax), %rax |
@@ -88,6 +90,7 @@ ENTRY(efi_call) | |||
88 | RESTORE_PGT | 90 | RESTORE_PGT |
89 | addq $48, %rsp | 91 | addq $48, %rsp |
90 | RESTORE_XMM | 92 | RESTORE_XMM |
93 | FRAME_END | ||
91 | ret | 94 | ret |
92 | ENDPROC(efi_call) | 95 | ENDPROC(efi_call) |
93 | 96 | ||
diff --git a/arch/x86/power/hibernate_asm_64.S b/arch/x86/power/hibernate_asm_64.S index e2386cb4e0c3..4400a43b9e28 100644 --- a/arch/x86/power/hibernate_asm_64.S +++ b/arch/x86/power/hibernate_asm_64.S | |||
@@ -21,8 +21,10 @@ | |||
21 | #include <asm/page_types.h> | 21 | #include <asm/page_types.h> |
22 | #include <asm/asm-offsets.h> | 22 | #include <asm/asm-offsets.h> |
23 | #include <asm/processor-flags.h> | 23 | #include <asm/processor-flags.h> |
24 | #include <asm/frame.h> | ||
24 | 25 | ||
25 | ENTRY(swsusp_arch_suspend) | 26 | ENTRY(swsusp_arch_suspend) |
27 | FRAME_BEGIN | ||
26 | movq $saved_context, %rax | 28 | movq $saved_context, %rax |
27 | movq %rsp, pt_regs_sp(%rax) | 29 | movq %rsp, pt_regs_sp(%rax) |
28 | movq %rbp, pt_regs_bp(%rax) | 30 | movq %rbp, pt_regs_bp(%rax) |
@@ -50,7 +52,9 @@ ENTRY(swsusp_arch_suspend) | |||
50 | movq %rax, restore_cr3(%rip) | 52 | movq %rax, restore_cr3(%rip) |
51 | 53 | ||
52 | call swsusp_save | 54 | call swsusp_save |
55 | FRAME_END | ||
53 | ret | 56 | ret |
57 | ENDPROC(swsusp_arch_suspend) | ||
54 | 58 | ||
55 | ENTRY(restore_image) | 59 | ENTRY(restore_image) |
56 | /* switch to temporary page tables */ | 60 | /* switch to temporary page tables */ |
@@ -107,6 +111,7 @@ ENTRY(core_restore_code) | |||
107 | */ | 111 | */ |
108 | 112 | ||
109 | ENTRY(restore_registers) | 113 | ENTRY(restore_registers) |
114 | FRAME_BEGIN | ||
110 | /* go back to the original page tables */ | 115 | /* go back to the original page tables */ |
111 | movq %rbx, %cr3 | 116 | movq %rbx, %cr3 |
112 | 117 | ||
@@ -147,4 +152,6 @@ ENTRY(restore_registers) | |||
147 | /* tell the hibernation core that we've just restored the memory */ | 152 | /* tell the hibernation core that we've just restored the memory */ |
148 | movq %rax, in_suspend(%rip) | 153 | movq %rax, in_suspend(%rip) |
149 | 154 | ||
155 | FRAME_END | ||
150 | ret | 156 | ret |
157 | ENDPROC(restore_registers) | ||
diff --git a/arch/x86/um/asm/barrier.h b/arch/x86/um/asm/barrier.h index 174781a404ff..00c319048d52 100644 --- a/arch/x86/um/asm/barrier.h +++ b/arch/x86/um/asm/barrier.h | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | #include <asm/asm.h> | 4 | #include <asm/asm.h> |
5 | #include <asm/segment.h> | 5 | #include <asm/segment.h> |
6 | #include <asm/cpufeature.h> | 6 | #include <asm/cpufeatures.h> |
7 | #include <asm/cmpxchg.h> | 7 | #include <asm/cmpxchg.h> |
8 | #include <asm/nops.h> | 8 | #include <asm/nops.h> |
9 | 9 | ||
diff --git a/arch/x86/um/sys_call_table_32.c b/arch/x86/um/sys_call_table_32.c index 439c0994b696..bfce503dffae 100644 --- a/arch/x86/um/sys_call_table_32.c +++ b/arch/x86/um/sys_call_table_32.c | |||
@@ -25,11 +25,11 @@ | |||
25 | 25 | ||
26 | #define old_mmap sys_old_mmap | 26 | #define old_mmap sys_old_mmap |
27 | 27 | ||
28 | #define __SYSCALL_I386(nr, sym, compat) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ; | 28 | #define __SYSCALL_I386(nr, sym, qual) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ; |
29 | #include <asm/syscalls_32.h> | 29 | #include <asm/syscalls_32.h> |
30 | 30 | ||
31 | #undef __SYSCALL_I386 | 31 | #undef __SYSCALL_I386 |
32 | #define __SYSCALL_I386(nr, sym, compat) [ nr ] = sym, | 32 | #define __SYSCALL_I386(nr, sym, qual) [ nr ] = sym, |
33 | 33 | ||
34 | extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); | 34 | extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); |
35 | 35 | ||
diff --git a/arch/x86/um/sys_call_table_64.c b/arch/x86/um/sys_call_table_64.c index b74ea6c2c0e7..f306413d3eb6 100644 --- a/arch/x86/um/sys_call_table_64.c +++ b/arch/x86/um/sys_call_table_64.c | |||
@@ -35,14 +35,11 @@ | |||
35 | #define stub_execveat sys_execveat | 35 | #define stub_execveat sys_execveat |
36 | #define stub_rt_sigreturn sys_rt_sigreturn | 36 | #define stub_rt_sigreturn sys_rt_sigreturn |
37 | 37 | ||
38 | #define __SYSCALL_COMMON(nr, sym, compat) __SYSCALL_64(nr, sym, compat) | 38 | #define __SYSCALL_64(nr, sym, qual) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ; |
39 | #define __SYSCALL_X32(nr, sym, compat) /* Not supported */ | ||
40 | |||
41 | #define __SYSCALL_64(nr, sym, compat) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ; | ||
42 | #include <asm/syscalls_64.h> | 39 | #include <asm/syscalls_64.h> |
43 | 40 | ||
44 | #undef __SYSCALL_64 | 41 | #undef __SYSCALL_64 |
45 | #define __SYSCALL_64(nr, sym, compat) [ nr ] = sym, | 42 | #define __SYSCALL_64(nr, sym, qual) [ nr ] = sym, |
46 | 43 | ||
47 | extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); | 44 | extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); |
48 | 45 | ||
diff --git a/arch/x86/um/user-offsets.c b/arch/x86/um/user-offsets.c index ce7e3607a870..470564bbd08e 100644 --- a/arch/x86/um/user-offsets.c +++ b/arch/x86/um/user-offsets.c | |||
@@ -9,14 +9,12 @@ | |||
9 | #include <asm/types.h> | 9 | #include <asm/types.h> |
10 | 10 | ||
11 | #ifdef __i386__ | 11 | #ifdef __i386__ |
12 | #define __SYSCALL_I386(nr, sym, compat) [nr] = 1, | 12 | #define __SYSCALL_I386(nr, sym, qual) [nr] = 1, |
13 | static char syscalls[] = { | 13 | static char syscalls[] = { |
14 | #include <asm/syscalls_32.h> | 14 | #include <asm/syscalls_32.h> |
15 | }; | 15 | }; |
16 | #else | 16 | #else |
17 | #define __SYSCALL_64(nr, sym, compat) [nr] = 1, | 17 | #define __SYSCALL_64(nr, sym, qual) [nr] = 1, |
18 | #define __SYSCALL_COMMON(nr, sym, compat) [nr] = 1, | ||
19 | #define __SYSCALL_X32(nr, sym, compat) /* Not supported */ | ||
20 | static char syscalls[] = { | 18 | static char syscalls[] = { |
21 | #include <asm/syscalls_64.h> | 19 | #include <asm/syscalls_64.h> |
22 | }; | 20 | }; |
diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S index 3e45aa000718..eff224df813f 100644 --- a/arch/x86/xen/xen-asm.S +++ b/arch/x86/xen/xen-asm.S | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <asm/asm-offsets.h> | 14 | #include <asm/asm-offsets.h> |
15 | #include <asm/percpu.h> | 15 | #include <asm/percpu.h> |
16 | #include <asm/processor-flags.h> | 16 | #include <asm/processor-flags.h> |
17 | #include <asm/frame.h> | ||
17 | 18 | ||
18 | #include "xen-asm.h" | 19 | #include "xen-asm.h" |
19 | 20 | ||
@@ -23,6 +24,7 @@ | |||
23 | * then enter the hypervisor to get them handled. | 24 | * then enter the hypervisor to get them handled. |
24 | */ | 25 | */ |
25 | ENTRY(xen_irq_enable_direct) | 26 | ENTRY(xen_irq_enable_direct) |
27 | FRAME_BEGIN | ||
26 | /* Unmask events */ | 28 | /* Unmask events */ |
27 | movb $0, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask | 29 | movb $0, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask |
28 | 30 | ||
@@ -39,6 +41,7 @@ ENTRY(xen_irq_enable_direct) | |||
39 | 2: call check_events | 41 | 2: call check_events |
40 | 1: | 42 | 1: |
41 | ENDPATCH(xen_irq_enable_direct) | 43 | ENDPATCH(xen_irq_enable_direct) |
44 | FRAME_END | ||
42 | ret | 45 | ret |
43 | ENDPROC(xen_irq_enable_direct) | 46 | ENDPROC(xen_irq_enable_direct) |
44 | RELOC(xen_irq_enable_direct, 2b+1) | 47 | RELOC(xen_irq_enable_direct, 2b+1) |
@@ -82,6 +85,7 @@ ENDPATCH(xen_save_fl_direct) | |||
82 | * enters the hypervisor to get them delivered if so. | 85 | * enters the hypervisor to get them delivered if so. |
83 | */ | 86 | */ |
84 | ENTRY(xen_restore_fl_direct) | 87 | ENTRY(xen_restore_fl_direct) |
88 | FRAME_BEGIN | ||
85 | #ifdef CONFIG_X86_64 | 89 | #ifdef CONFIG_X86_64 |
86 | testw $X86_EFLAGS_IF, %di | 90 | testw $X86_EFLAGS_IF, %di |
87 | #else | 91 | #else |
@@ -100,6 +104,7 @@ ENTRY(xen_restore_fl_direct) | |||
100 | 2: call check_events | 104 | 2: call check_events |
101 | 1: | 105 | 1: |
102 | ENDPATCH(xen_restore_fl_direct) | 106 | ENDPATCH(xen_restore_fl_direct) |
107 | FRAME_END | ||
103 | ret | 108 | ret |
104 | ENDPROC(xen_restore_fl_direct) | 109 | ENDPROC(xen_restore_fl_direct) |
105 | RELOC(xen_restore_fl_direct, 2b+1) | 110 | RELOC(xen_restore_fl_direct, 2b+1) |
@@ -109,7 +114,8 @@ ENDPATCH(xen_restore_fl_direct) | |||
109 | * Force an event check by making a hypercall, but preserve regs | 114 | * Force an event check by making a hypercall, but preserve regs |
110 | * before making the call. | 115 | * before making the call. |
111 | */ | 116 | */ |
112 | check_events: | 117 | ENTRY(check_events) |
118 | FRAME_BEGIN | ||
113 | #ifdef CONFIG_X86_32 | 119 | #ifdef CONFIG_X86_32 |
114 | push %eax | 120 | push %eax |
115 | push %ecx | 121 | push %ecx |
@@ -139,4 +145,6 @@ check_events: | |||
139 | pop %rcx | 145 | pop %rcx |
140 | pop %rax | 146 | pop %rax |
141 | #endif | 147 | #endif |
148 | FRAME_END | ||
142 | ret | 149 | ret |
150 | ENDPROC(check_events) | ||
diff --git a/arch/x86/xen/xen-asm_64.S b/arch/x86/xen/xen-asm_64.S index cc8acc410ddb..c3df43141e70 100644 --- a/arch/x86/xen/xen-asm_64.S +++ b/arch/x86/xen/xen-asm_64.S | |||
@@ -26,6 +26,7 @@ ENTRY(xen_adjust_exception_frame) | |||
26 | mov 8+0(%rsp), %rcx | 26 | mov 8+0(%rsp), %rcx |
27 | mov 8+8(%rsp), %r11 | 27 | mov 8+8(%rsp), %r11 |
28 | ret $16 | 28 | ret $16 |
29 | ENDPROC(xen_adjust_exception_frame) | ||
29 | 30 | ||
30 | hypercall_iret = hypercall_page + __HYPERVISOR_iret * 32 | 31 | hypercall_iret = hypercall_page + __HYPERVISOR_iret * 32 |
31 | /* | 32 | /* |
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index cd83d477e32d..3a4b39afc0ab 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -1431,7 +1431,7 @@ static int __init intel_pstate_init(void) | |||
1431 | if (!all_cpu_data) | 1431 | if (!all_cpu_data) |
1432 | return -ENOMEM; | 1432 | return -ENOMEM; |
1433 | 1433 | ||
1434 | if (static_cpu_has_safe(X86_FEATURE_HWP) && !no_hwp) { | 1434 | if (static_cpu_has(X86_FEATURE_HWP) && !no_hwp) { |
1435 | pr_info("intel_pstate: HWP enabled\n"); | 1435 | pr_info("intel_pstate: HWP enabled\n"); |
1436 | hwp_active++; | 1436 | hwp_active++; |
1437 | } | 1437 | } |
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index 92443c319e59..8fc284cdce4e 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <asm/cacheflush.h> | 37 | #include <asm/cacheflush.h> |
38 | #endif /* CONFIG_HPWDT_NMI_DECODING */ | 38 | #endif /* CONFIG_HPWDT_NMI_DECODING */ |
39 | #include <asm/nmi.h> | 39 | #include <asm/nmi.h> |
40 | #include <asm/frame.h> | ||
40 | 41 | ||
41 | #define HPWDT_VERSION "1.3.3" | 42 | #define HPWDT_VERSION "1.3.3" |
42 | #define SECS_TO_TICKS(secs) ((secs) * 1000 / 128) | 43 | #define SECS_TO_TICKS(secs) ((secs) * 1000 / 128) |
@@ -353,10 +354,10 @@ static int detect_cru_service(void) | |||
353 | 354 | ||
354 | asm(".text \n\t" | 355 | asm(".text \n\t" |
355 | ".align 4 \n\t" | 356 | ".align 4 \n\t" |
356 | ".globl asminline_call \n" | 357 | ".globl asminline_call \n\t" |
358 | ".type asminline_call, @function \n\t" | ||
357 | "asminline_call: \n\t" | 359 | "asminline_call: \n\t" |
358 | "pushq %rbp \n\t" | 360 | FRAME_BEGIN |
359 | "movq %rsp, %rbp \n\t" | ||
360 | "pushq %rax \n\t" | 361 | "pushq %rax \n\t" |
361 | "pushq %rbx \n\t" | 362 | "pushq %rbx \n\t" |
362 | "pushq %rdx \n\t" | 363 | "pushq %rdx \n\t" |
@@ -386,7 +387,7 @@ asm(".text \n\t" | |||
386 | "popq %rdx \n\t" | 387 | "popq %rdx \n\t" |
387 | "popq %rbx \n\t" | 388 | "popq %rbx \n\t" |
388 | "popq %rax \n\t" | 389 | "popq %rax \n\t" |
389 | "leave \n\t" | 390 | FRAME_END |
390 | "ret \n\t" | 391 | "ret \n\t" |
391 | ".previous"); | 392 | ".previous"); |
392 | 393 | ||
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 4545e2e2ad45..5699bbc23feb 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -931,7 +931,7 @@ static int check_async_write(struct inode *inode, unsigned long bio_flags) | |||
931 | if (bio_flags & EXTENT_BIO_TREE_LOG) | 931 | if (bio_flags & EXTENT_BIO_TREE_LOG) |
932 | return 0; | 932 | return 0; |
933 | #ifdef CONFIG_X86 | 933 | #ifdef CONFIG_X86 |
934 | if (static_cpu_has_safe(X86_FEATURE_XMM4_2)) | 934 | if (static_cpu_has(X86_FEATURE_XMM4_2)) |
935 | return 0; | 935 | return 0; |
936 | #endif | 936 | #endif |
937 | return 1; | 937 | return 1; |
diff --git a/include/linux/mm.h b/include/linux/mm.h index 516e14944339..b1d4b8c7f7cd 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -2138,6 +2138,8 @@ int remap_pfn_range(struct vm_area_struct *, unsigned long addr, | |||
2138 | int vm_insert_page(struct vm_area_struct *, unsigned long addr, struct page *); | 2138 | int vm_insert_page(struct vm_area_struct *, unsigned long addr, struct page *); |
2139 | int vm_insert_pfn(struct vm_area_struct *vma, unsigned long addr, | 2139 | int vm_insert_pfn(struct vm_area_struct *vma, unsigned long addr, |
2140 | unsigned long pfn); | 2140 | unsigned long pfn); |
2141 | int vm_insert_pfn_prot(struct vm_area_struct *vma, unsigned long addr, | ||
2142 | unsigned long pfn, pgprot_t pgprot); | ||
2141 | int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, | 2143 | int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, |
2142 | pfn_t pfn); | 2144 | pfn_t pfn); |
2143 | int vm_iomap_memory(struct vm_area_struct *vma, phys_addr_t start, unsigned long len); | 2145 | int vm_iomap_memory(struct vm_area_struct *vma, phys_addr_t start, unsigned long len); |
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 624b78b848b8..944b2b37313b 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h | |||
@@ -566,10 +566,26 @@ static inline void clear_tlb_flush_pending(struct mm_struct *mm) | |||
566 | } | 566 | } |
567 | #endif | 567 | #endif |
568 | 568 | ||
569 | struct vm_special_mapping | 569 | struct vm_fault; |
570 | { | 570 | |
571 | const char *name; | 571 | struct vm_special_mapping { |
572 | const char *name; /* The name, e.g. "[vdso]". */ | ||
573 | |||
574 | /* | ||
575 | * If .fault is not provided, this points to a | ||
576 | * NULL-terminated array of pages that back the special mapping. | ||
577 | * | ||
578 | * This must not be NULL unless .fault is provided. | ||
579 | */ | ||
572 | struct page **pages; | 580 | struct page **pages; |
581 | |||
582 | /* | ||
583 | * If non-NULL, then this is called to resolve page faults | ||
584 | * on the special mapping. If used, .pages is not checked. | ||
585 | */ | ||
586 | int (*fault)(const struct vm_special_mapping *sm, | ||
587 | struct vm_area_struct *vma, | ||
588 | struct vm_fault *vmf); | ||
573 | }; | 589 | }; |
574 | 590 | ||
575 | enum tlb_flush_reason { | 591 | enum tlb_flush_reason { |
diff --git a/lib/atomic64_test.c b/lib/atomic64_test.c index d62de8bf022d..123481814320 100644 --- a/lib/atomic64_test.c +++ b/lib/atomic64_test.c | |||
@@ -17,7 +17,7 @@ | |||
17 | #include <linux/atomic.h> | 17 | #include <linux/atomic.h> |
18 | 18 | ||
19 | #ifdef CONFIG_X86 | 19 | #ifdef CONFIG_X86 |
20 | #include <asm/processor.h> /* for boot_cpu_has below */ | 20 | #include <asm/cpufeature.h> /* for boot_cpu_has below */ |
21 | #endif | 21 | #endif |
22 | 22 | ||
23 | #define TEST(bit, op, c_op, val) \ | 23 | #define TEST(bit, op, c_op, val) \ |
diff --git a/mm/memory.c b/mm/memory.c index 635451abc8f7..38090ca37a08 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -1551,8 +1551,29 @@ out: | |||
1551 | int vm_insert_pfn(struct vm_area_struct *vma, unsigned long addr, | 1551 | int vm_insert_pfn(struct vm_area_struct *vma, unsigned long addr, |
1552 | unsigned long pfn) | 1552 | unsigned long pfn) |
1553 | { | 1553 | { |
1554 | return vm_insert_pfn_prot(vma, addr, pfn, vma->vm_page_prot); | ||
1555 | } | ||
1556 | EXPORT_SYMBOL(vm_insert_pfn); | ||
1557 | |||
1558 | /** | ||
1559 | * vm_insert_pfn_prot - insert single pfn into user vma with specified pgprot | ||
1560 | * @vma: user vma to map to | ||
1561 | * @addr: target user address of this page | ||
1562 | * @pfn: source kernel pfn | ||
1563 | * @pgprot: pgprot flags for the inserted page | ||
1564 | * | ||
1565 | * This is exactly like vm_insert_pfn, except that it allows drivers to | ||
1566 | * to override pgprot on a per-page basis. | ||
1567 | * | ||
1568 | * This only makes sense for IO mappings, and it makes no sense for | ||
1569 | * cow mappings. In general, using multiple vmas is preferable; | ||
1570 | * vm_insert_pfn_prot should only be used if using multiple VMAs is | ||
1571 | * impractical. | ||
1572 | */ | ||
1573 | int vm_insert_pfn_prot(struct vm_area_struct *vma, unsigned long addr, | ||
1574 | unsigned long pfn, pgprot_t pgprot) | ||
1575 | { | ||
1554 | int ret; | 1576 | int ret; |
1555 | pgprot_t pgprot = vma->vm_page_prot; | ||
1556 | /* | 1577 | /* |
1557 | * Technically, architectures with pte_special can avoid all these | 1578 | * Technically, architectures with pte_special can avoid all these |
1558 | * restrictions (same for remap_pfn_range). However we would like | 1579 | * restrictions (same for remap_pfn_range). However we would like |
@@ -1574,7 +1595,7 @@ int vm_insert_pfn(struct vm_area_struct *vma, unsigned long addr, | |||
1574 | 1595 | ||
1575 | return ret; | 1596 | return ret; |
1576 | } | 1597 | } |
1577 | EXPORT_SYMBOL(vm_insert_pfn); | 1598 | EXPORT_SYMBOL(vm_insert_pfn_prot); |
1578 | 1599 | ||
1579 | int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, | 1600 | int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, |
1580 | pfn_t pfn) | 1601 | pfn_t pfn) |
@@ -3066,11 +3066,16 @@ static int special_mapping_fault(struct vm_area_struct *vma, | |||
3066 | pgoff_t pgoff; | 3066 | pgoff_t pgoff; |
3067 | struct page **pages; | 3067 | struct page **pages; |
3068 | 3068 | ||
3069 | if (vma->vm_ops == &legacy_special_mapping_vmops) | 3069 | if (vma->vm_ops == &legacy_special_mapping_vmops) { |
3070 | pages = vma->vm_private_data; | 3070 | pages = vma->vm_private_data; |
3071 | else | 3071 | } else { |
3072 | pages = ((struct vm_special_mapping *)vma->vm_private_data)-> | 3072 | struct vm_special_mapping *sm = vma->vm_private_data; |
3073 | pages; | 3073 | |
3074 | if (sm->fault) | ||
3075 | return sm->fault(sm, vma, vmf); | ||
3076 | |||
3077 | pages = sm->pages; | ||
3078 | } | ||
3074 | 3079 | ||
3075 | for (pgoff = vmf->pgoff; pgoff && *pages; ++pages) | 3080 | for (pgoff = vmf->pgoff; pgoff && *pages; ++pages) |
3076 | pgoff--; | 3081 | pgoff--; |
diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index d0c473f65850..d5ce7d7aae3e 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile | |||
@@ -4,15 +4,16 @@ include ../lib.mk | |||
4 | 4 | ||
5 | .PHONY: all all_32 all_64 warn_32bit_failure clean | 5 | .PHONY: all all_32 all_64 warn_32bit_failure clean |
6 | 6 | ||
7 | TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall | 7 | TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall \ |
8 | TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault sigreturn test_syscall_vdso unwind_vdso \ | 8 | check_initial_reg_state sigreturn ldt_gdt |
9 | TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \ | ||
9 | test_FCMOV test_FCOMI test_FISTTP \ | 10 | test_FCMOV test_FCOMI test_FISTTP \ |
10 | ldt_gdt \ | ||
11 | vdso_restorer | 11 | vdso_restorer |
12 | 12 | ||
13 | TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY) | 13 | TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY) |
14 | TARGETS_C_64BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_64BIT_ONLY) | ||
14 | BINARIES_32 := $(TARGETS_C_32BIT_ALL:%=%_32) | 15 | BINARIES_32 := $(TARGETS_C_32BIT_ALL:%=%_32) |
15 | BINARIES_64 := $(TARGETS_C_BOTHBITS:%=%_64) | 16 | BINARIES_64 := $(TARGETS_C_64BIT_ALL:%=%_64) |
16 | 17 | ||
17 | CFLAGS := -O2 -g -std=gnu99 -pthread -Wall | 18 | CFLAGS := -O2 -g -std=gnu99 -pthread -Wall |
18 | 19 | ||
@@ -40,7 +41,7 @@ clean: | |||
40 | $(TARGETS_C_32BIT_ALL:%=%_32): %_32: %.c | 41 | $(TARGETS_C_32BIT_ALL:%=%_32): %_32: %.c |
41 | $(CC) -m32 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl -lm | 42 | $(CC) -m32 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl -lm |
42 | 43 | ||
43 | $(TARGETS_C_BOTHBITS:%=%_64): %_64: %.c | 44 | $(TARGETS_C_64BIT_ALL:%=%_64): %_64: %.c |
44 | $(CC) -m64 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl | 45 | $(CC) -m64 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl |
45 | 46 | ||
46 | # x86_64 users should be encouraged to install 32-bit libraries | 47 | # x86_64 users should be encouraged to install 32-bit libraries |
@@ -65,3 +66,9 @@ endif | |||
65 | sysret_ss_attrs_64: thunks.S | 66 | sysret_ss_attrs_64: thunks.S |
66 | ptrace_syscall_32: raw_syscall_helper_32.S | 67 | ptrace_syscall_32: raw_syscall_helper_32.S |
67 | test_syscall_vdso_32: thunks_32.S | 68 | test_syscall_vdso_32: thunks_32.S |
69 | |||
70 | # check_initial_reg_state is special: it needs a custom entry, and it | ||
71 | # needs to be static so that its interpreter doesn't destroy its initial | ||
72 | # state. | ||
73 | check_initial_reg_state_32: CFLAGS += -Wl,-ereal_start -static | ||
74 | check_initial_reg_state_64: CFLAGS += -Wl,-ereal_start -static | ||
diff --git a/tools/testing/selftests/x86/check_initial_reg_state.c b/tools/testing/selftests/x86/check_initial_reg_state.c new file mode 100644 index 000000000000..6aaed9b85baf --- /dev/null +++ b/tools/testing/selftests/x86/check_initial_reg_state.c | |||
@@ -0,0 +1,109 @@ | |||
1 | /* | ||
2 | * check_initial_reg_state.c - check that execve sets the correct state | ||
3 | * Copyright (c) 2014-2016 Andrew Lutomirski | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but | ||
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | * General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #define _GNU_SOURCE | ||
16 | |||
17 | #include <stdio.h> | ||
18 | |||
19 | unsigned long ax, bx, cx, dx, si, di, bp, sp, flags; | ||
20 | unsigned long r8, r9, r10, r11, r12, r13, r14, r15; | ||
21 | |||
22 | asm ( | ||
23 | ".pushsection .text\n\t" | ||
24 | ".type real_start, @function\n\t" | ||
25 | ".global real_start\n\t" | ||
26 | "real_start:\n\t" | ||
27 | #ifdef __x86_64__ | ||
28 | "mov %rax, ax\n\t" | ||
29 | "mov %rbx, bx\n\t" | ||
30 | "mov %rcx, cx\n\t" | ||
31 | "mov %rdx, dx\n\t" | ||
32 | "mov %rsi, si\n\t" | ||
33 | "mov %rdi, di\n\t" | ||
34 | "mov %rbp, bp\n\t" | ||
35 | "mov %rsp, sp\n\t" | ||
36 | "mov %r8, r8\n\t" | ||
37 | "mov %r9, r9\n\t" | ||
38 | "mov %r10, r10\n\t" | ||
39 | "mov %r11, r11\n\t" | ||
40 | "mov %r12, r12\n\t" | ||
41 | "mov %r13, r13\n\t" | ||
42 | "mov %r14, r14\n\t" | ||
43 | "mov %r15, r15\n\t" | ||
44 | "pushfq\n\t" | ||
45 | "popq flags\n\t" | ||
46 | #else | ||
47 | "mov %eax, ax\n\t" | ||
48 | "mov %ebx, bx\n\t" | ||
49 | "mov %ecx, cx\n\t" | ||
50 | "mov %edx, dx\n\t" | ||
51 | "mov %esi, si\n\t" | ||
52 | "mov %edi, di\n\t" | ||
53 | "mov %ebp, bp\n\t" | ||
54 | "mov %esp, sp\n\t" | ||
55 | "pushfl\n\t" | ||
56 | "popl flags\n\t" | ||
57 | #endif | ||
58 | "jmp _start\n\t" | ||
59 | ".size real_start, . - real_start\n\t" | ||
60 | ".popsection"); | ||
61 | |||
62 | int main() | ||
63 | { | ||
64 | int nerrs = 0; | ||
65 | |||
66 | if (sp == 0) { | ||
67 | printf("[FAIL]\tTest was built incorrectly\n"); | ||
68 | return 1; | ||
69 | } | ||
70 | |||
71 | if (ax || bx || cx || dx || si || di || bp | ||
72 | #ifdef __x86_64__ | ||
73 | || r8 || r9 || r10 || r11 || r12 || r13 || r14 || r15 | ||
74 | #endif | ||
75 | ) { | ||
76 | printf("[FAIL]\tAll GPRs except SP should be 0\n"); | ||
77 | #define SHOW(x) printf("\t" #x " = 0x%lx\n", x); | ||
78 | SHOW(ax); | ||
79 | SHOW(bx); | ||
80 | SHOW(cx); | ||
81 | SHOW(dx); | ||
82 | SHOW(si); | ||
83 | SHOW(di); | ||
84 | SHOW(bp); | ||
85 | SHOW(sp); | ||
86 | #ifdef __x86_64__ | ||
87 | SHOW(r8); | ||
88 | SHOW(r9); | ||
89 | SHOW(r10); | ||
90 | SHOW(r11); | ||
91 | SHOW(r12); | ||
92 | SHOW(r13); | ||
93 | SHOW(r14); | ||
94 | SHOW(r15); | ||
95 | #endif | ||
96 | nerrs++; | ||
97 | } else { | ||
98 | printf("[OK]\tAll GPRs except SP are 0\n"); | ||
99 | } | ||
100 | |||
101 | if (flags != 0x202) { | ||
102 | printf("[FAIL]\tFLAGS is 0x%lx, but it should be 0x202\n", flags); | ||
103 | nerrs++; | ||
104 | } else { | ||
105 | printf("[OK]\tFLAGS is 0x202\n"); | ||
106 | } | ||
107 | |||
108 | return nerrs ? 1 : 0; | ||
109 | } | ||
diff --git a/tools/testing/selftests/x86/ptrace_syscall.c b/tools/testing/selftests/x86/ptrace_syscall.c index 5105b49cd8aa..421456784bc6 100644 --- a/tools/testing/selftests/x86/ptrace_syscall.c +++ b/tools/testing/selftests/x86/ptrace_syscall.c | |||
@@ -103,6 +103,17 @@ static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), | |||
103 | err(1, "sigaction"); | 103 | err(1, "sigaction"); |
104 | } | 104 | } |
105 | 105 | ||
106 | static void setsigign(int sig, int flags) | ||
107 | { | ||
108 | struct sigaction sa; | ||
109 | memset(&sa, 0, sizeof(sa)); | ||
110 | sa.sa_sigaction = (void *)SIG_IGN; | ||
111 | sa.sa_flags = flags; | ||
112 | sigemptyset(&sa.sa_mask); | ||
113 | if (sigaction(sig, &sa, 0)) | ||
114 | err(1, "sigaction"); | ||
115 | } | ||
116 | |||
106 | static void clearhandler(int sig) | 117 | static void clearhandler(int sig) |
107 | { | 118 | { |
108 | struct sigaction sa; | 119 | struct sigaction sa; |
@@ -187,7 +198,7 @@ static void test_ptrace_syscall_restart(void) | |||
187 | 198 | ||
188 | printf("[RUN]\tSYSEMU\n"); | 199 | printf("[RUN]\tSYSEMU\n"); |
189 | if (ptrace(PTRACE_SYSEMU, chld, 0, 0) != 0) | 200 | if (ptrace(PTRACE_SYSEMU, chld, 0, 0) != 0) |
190 | err(1, "PTRACE_SYSCALL"); | 201 | err(1, "PTRACE_SYSEMU"); |
191 | wait_trap(chld); | 202 | wait_trap(chld); |
192 | 203 | ||
193 | if (ptrace(PTRACE_GETREGS, chld, 0, ®s) != 0) | 204 | if (ptrace(PTRACE_GETREGS, chld, 0, ®s) != 0) |
@@ -218,7 +229,7 @@ static void test_ptrace_syscall_restart(void) | |||
218 | err(1, "PTRACE_SETREGS"); | 229 | err(1, "PTRACE_SETREGS"); |
219 | 230 | ||
220 | if (ptrace(PTRACE_SYSEMU, chld, 0, 0) != 0) | 231 | if (ptrace(PTRACE_SYSEMU, chld, 0, 0) != 0) |
221 | err(1, "PTRACE_SYSCALL"); | 232 | err(1, "PTRACE_SYSEMU"); |
222 | wait_trap(chld); | 233 | wait_trap(chld); |
223 | 234 | ||
224 | if (ptrace(PTRACE_GETREGS, chld, 0, ®s) != 0) | 235 | if (ptrace(PTRACE_GETREGS, chld, 0, ®s) != 0) |
@@ -250,7 +261,7 @@ static void test_ptrace_syscall_restart(void) | |||
250 | err(1, "PTRACE_SETREGS"); | 261 | err(1, "PTRACE_SETREGS"); |
251 | 262 | ||
252 | if (ptrace(PTRACE_SYSEMU, chld, 0, 0) != 0) | 263 | if (ptrace(PTRACE_SYSEMU, chld, 0, 0) != 0) |
253 | err(1, "PTRACE_SYSCALL"); | 264 | err(1, "PTRACE_SYSEMU"); |
254 | wait_trap(chld); | 265 | wait_trap(chld); |
255 | 266 | ||
256 | if (ptrace(PTRACE_GETREGS, chld, 0, ®s) != 0) | 267 | if (ptrace(PTRACE_GETREGS, chld, 0, ®s) != 0) |
@@ -277,6 +288,119 @@ static void test_ptrace_syscall_restart(void) | |||
277 | } | 288 | } |
278 | } | 289 | } |
279 | 290 | ||
291 | static void test_restart_under_ptrace(void) | ||
292 | { | ||
293 | printf("[RUN]\tkernel syscall restart under ptrace\n"); | ||
294 | pid_t chld = fork(); | ||
295 | if (chld < 0) | ||
296 | err(1, "fork"); | ||
297 | |||
298 | if (chld == 0) { | ||
299 | if (ptrace(PTRACE_TRACEME, 0, 0, 0) != 0) | ||
300 | err(1, "PTRACE_TRACEME"); | ||
301 | |||
302 | printf("\tChild will take a nap until signaled\n"); | ||
303 | setsigign(SIGUSR1, SA_RESTART); | ||
304 | raise(SIGSTOP); | ||
305 | |||
306 | syscall(SYS_pause, 0, 0, 0, 0, 0, 0); | ||
307 | _exit(0); | ||
308 | } | ||
309 | |||
310 | int status; | ||
311 | |||
312 | /* Wait for SIGSTOP. */ | ||
313 | if (waitpid(chld, &status, 0) != chld || !WIFSTOPPED(status)) | ||
314 | err(1, "waitpid"); | ||
315 | |||
316 | struct user_regs_struct regs; | ||
317 | |||
318 | printf("[RUN]\tSYSCALL\n"); | ||
319 | if (ptrace(PTRACE_SYSCALL, chld, 0, 0) != 0) | ||
320 | err(1, "PTRACE_SYSCALL"); | ||
321 | wait_trap(chld); | ||
322 | |||
323 | /* We should be stopped at pause(2) entry. */ | ||
324 | |||
325 | if (ptrace(PTRACE_GETREGS, chld, 0, ®s) != 0) | ||
326 | err(1, "PTRACE_GETREGS"); | ||
327 | |||
328 | if (regs.user_syscall_nr != SYS_pause || | ||
329 | regs.user_arg0 != 0 || regs.user_arg1 != 0 || | ||
330 | regs.user_arg2 != 0 || regs.user_arg3 != 0 || | ||
331 | regs.user_arg4 != 0 || regs.user_arg5 != 0) { | ||
332 | printf("[FAIL]\tInitial args are wrong (nr=%lu, args=%lu %lu %lu %lu %lu %lu)\n", (unsigned long)regs.user_syscall_nr, (unsigned long)regs.user_arg0, (unsigned long)regs.user_arg1, (unsigned long)regs.user_arg2, (unsigned long)regs.user_arg3, (unsigned long)regs.user_arg4, (unsigned long)regs.user_arg5); | ||
333 | nerrs++; | ||
334 | } else { | ||
335 | printf("[OK]\tInitial nr and args are correct\n"); | ||
336 | } | ||
337 | |||
338 | /* Interrupt it. */ | ||
339 | kill(chld, SIGUSR1); | ||
340 | |||
341 | /* Advance. We should be stopped at exit. */ | ||
342 | printf("[RUN]\tSYSCALL\n"); | ||
343 | if (ptrace(PTRACE_SYSCALL, chld, 0, 0) != 0) | ||
344 | err(1, "PTRACE_SYSCALL"); | ||
345 | wait_trap(chld); | ||
346 | |||
347 | if (ptrace(PTRACE_GETREGS, chld, 0, ®s) != 0) | ||
348 | err(1, "PTRACE_GETREGS"); | ||
349 | |||
350 | if (regs.user_syscall_nr != SYS_pause || | ||
351 | regs.user_arg0 != 0 || regs.user_arg1 != 0 || | ||
352 | regs.user_arg2 != 0 || regs.user_arg3 != 0 || | ||
353 | regs.user_arg4 != 0 || regs.user_arg5 != 0) { | ||
354 | printf("[FAIL]\tArgs after SIGUSR1 are wrong (nr=%lu, args=%lu %lu %lu %lu %lu %lu)\n", (unsigned long)regs.user_syscall_nr, (unsigned long)regs.user_arg0, (unsigned long)regs.user_arg1, (unsigned long)regs.user_arg2, (unsigned long)regs.user_arg3, (unsigned long)regs.user_arg4, (unsigned long)regs.user_arg5); | ||
355 | nerrs++; | ||
356 | } else { | ||
357 | printf("[OK]\tArgs after SIGUSR1 are correct (ax = %ld)\n", | ||
358 | (long)regs.user_ax); | ||
359 | } | ||
360 | |||
361 | /* Poke the regs back in. This must not break anything. */ | ||
362 | if (ptrace(PTRACE_SETREGS, chld, 0, ®s) != 0) | ||
363 | err(1, "PTRACE_SETREGS"); | ||
364 | |||
365 | /* Catch the (ignored) SIGUSR1. */ | ||
366 | if (ptrace(PTRACE_CONT, chld, 0, 0) != 0) | ||
367 | err(1, "PTRACE_CONT"); | ||
368 | if (waitpid(chld, &status, 0) != chld) | ||
369 | err(1, "waitpid"); | ||
370 | if (!WIFSTOPPED(status)) { | ||
371 | printf("[FAIL]\tChild was stopped for SIGUSR1 (status = 0x%x)\n", status); | ||
372 | nerrs++; | ||
373 | } else { | ||
374 | printf("[OK]\tChild got SIGUSR1\n"); | ||
375 | } | ||
376 | |||
377 | /* The next event should be pause(2) again. */ | ||
378 | printf("[RUN]\tStep again\n"); | ||
379 | if (ptrace(PTRACE_SYSCALL, chld, 0, 0) != 0) | ||
380 | err(1, "PTRACE_SYSCALL"); | ||
381 | wait_trap(chld); | ||
382 | |||
383 | /* We should be stopped at pause(2) entry. */ | ||
384 | |||
385 | if (ptrace(PTRACE_GETREGS, chld, 0, ®s) != 0) | ||
386 | err(1, "PTRACE_GETREGS"); | ||
387 | |||
388 | if (regs.user_syscall_nr != SYS_pause || | ||
389 | regs.user_arg0 != 0 || regs.user_arg1 != 0 || | ||
390 | regs.user_arg2 != 0 || regs.user_arg3 != 0 || | ||
391 | regs.user_arg4 != 0 || regs.user_arg5 != 0) { | ||
392 | printf("[FAIL]\tpause did not restart (nr=%lu, args=%lu %lu %lu %lu %lu %lu)\n", (unsigned long)regs.user_syscall_nr, (unsigned long)regs.user_arg0, (unsigned long)regs.user_arg1, (unsigned long)regs.user_arg2, (unsigned long)regs.user_arg3, (unsigned long)regs.user_arg4, (unsigned long)regs.user_arg5); | ||
393 | nerrs++; | ||
394 | } else { | ||
395 | printf("[OK]\tpause(2) restarted correctly\n"); | ||
396 | } | ||
397 | |||
398 | /* Kill it. */ | ||
399 | kill(chld, SIGKILL); | ||
400 | if (waitpid(chld, &status, 0) != chld) | ||
401 | err(1, "waitpid"); | ||
402 | } | ||
403 | |||
280 | int main() | 404 | int main() |
281 | { | 405 | { |
282 | printf("[RUN]\tCheck int80 return regs\n"); | 406 | printf("[RUN]\tCheck int80 return regs\n"); |
@@ -290,5 +414,7 @@ int main() | |||
290 | 414 | ||
291 | test_ptrace_syscall_restart(); | 415 | test_ptrace_syscall_restart(); |
292 | 416 | ||
417 | test_restart_under_ptrace(); | ||
418 | |||
293 | return 0; | 419 | return 0; |
294 | } | 420 | } |
diff --git a/tools/testing/selftests/x86/sigreturn.c b/tools/testing/selftests/x86/sigreturn.c index b5aa1bab7416..8a577e7070c6 100644 --- a/tools/testing/selftests/x86/sigreturn.c +++ b/tools/testing/selftests/x86/sigreturn.c | |||
@@ -54,6 +54,37 @@ | |||
54 | #include <sys/ptrace.h> | 54 | #include <sys/ptrace.h> |
55 | #include <sys/user.h> | 55 | #include <sys/user.h> |
56 | 56 | ||
57 | /* Pull in AR_xyz defines. */ | ||
58 | typedef unsigned int u32; | ||
59 | typedef unsigned short u16; | ||
60 | #include "../../../../arch/x86/include/asm/desc_defs.h" | ||
61 | |||
62 | /* | ||
63 | * Copied from asm/ucontext.h, as asm/ucontext.h conflicts badly with the glibc | ||
64 | * headers. | ||
65 | */ | ||
66 | #ifdef __x86_64__ | ||
67 | /* | ||
68 | * UC_SIGCONTEXT_SS will be set when delivering 64-bit or x32 signals on | ||
69 | * kernels that save SS in the sigcontext. All kernels that set | ||
70 | * UC_SIGCONTEXT_SS will correctly restore at least the low 32 bits of esp | ||
71 | * regardless of SS (i.e. they implement espfix). | ||
72 | * | ||
73 | * Kernels that set UC_SIGCONTEXT_SS will also set UC_STRICT_RESTORE_SS | ||
74 | * when delivering a signal that came from 64-bit code. | ||
75 | * | ||
76 | * Sigreturn restores SS as follows: | ||
77 | * | ||
78 | * if (saved SS is valid || UC_STRICT_RESTORE_SS is set || | ||
79 | * saved CS is not 64-bit) | ||
80 | * new SS = saved SS (will fail IRET and signal if invalid) | ||
81 | * else | ||
82 | * new SS = a flat 32-bit data segment | ||
83 | */ | ||
84 | #define UC_SIGCONTEXT_SS 0x2 | ||
85 | #define UC_STRICT_RESTORE_SS 0x4 | ||
86 | #endif | ||
87 | |||
57 | /* | 88 | /* |
58 | * In principle, this test can run on Linux emulation layers (e.g. | 89 | * In principle, this test can run on Linux emulation layers (e.g. |
59 | * Illumos "LX branded zones"). Solaris-based kernels reserve LDT | 90 | * Illumos "LX branded zones"). Solaris-based kernels reserve LDT |
@@ -267,6 +298,9 @@ static gregset_t initial_regs, requested_regs, resulting_regs; | |||
267 | /* Instructions for the SIGUSR1 handler. */ | 298 | /* Instructions for the SIGUSR1 handler. */ |
268 | static volatile unsigned short sig_cs, sig_ss; | 299 | static volatile unsigned short sig_cs, sig_ss; |
269 | static volatile sig_atomic_t sig_trapped, sig_err, sig_trapno; | 300 | static volatile sig_atomic_t sig_trapped, sig_err, sig_trapno; |
301 | #ifdef __x86_64__ | ||
302 | static volatile sig_atomic_t sig_corrupt_final_ss; | ||
303 | #endif | ||
270 | 304 | ||
271 | /* Abstractions for some 32-bit vs 64-bit differences. */ | 305 | /* Abstractions for some 32-bit vs 64-bit differences. */ |
272 | #ifdef __x86_64__ | 306 | #ifdef __x86_64__ |
@@ -305,9 +339,105 @@ static greg_t *csptr(ucontext_t *ctx) | |||
305 | } | 339 | } |
306 | #endif | 340 | #endif |
307 | 341 | ||
342 | /* | ||
343 | * Checks a given selector for its code bitness or returns -1 if it's not | ||
344 | * a usable code segment selector. | ||
345 | */ | ||
346 | int cs_bitness(unsigned short cs) | ||
347 | { | ||
348 | uint32_t valid = 0, ar; | ||
349 | asm ("lar %[cs], %[ar]\n\t" | ||
350 | "jnz 1f\n\t" | ||
351 | "mov $1, %[valid]\n\t" | ||
352 | "1:" | ||
353 | : [ar] "=r" (ar), [valid] "+rm" (valid) | ||
354 | : [cs] "r" (cs)); | ||
355 | |||
356 | if (!valid) | ||
357 | return -1; | ||
358 | |||
359 | bool db = (ar & (1 << 22)); | ||
360 | bool l = (ar & (1 << 21)); | ||
361 | |||
362 | if (!(ar & (1<<11))) | ||
363 | return -1; /* Not code. */ | ||
364 | |||
365 | if (l && !db) | ||
366 | return 64; | ||
367 | else if (!l && db) | ||
368 | return 32; | ||
369 | else if (!l && !db) | ||
370 | return 16; | ||
371 | else | ||
372 | return -1; /* Unknown bitness. */ | ||
373 | } | ||
374 | |||
375 | /* | ||
376 | * Checks a given selector for its code bitness or returns -1 if it's not | ||
377 | * a usable code segment selector. | ||
378 | */ | ||
379 | bool is_valid_ss(unsigned short cs) | ||
380 | { | ||
381 | uint32_t valid = 0, ar; | ||
382 | asm ("lar %[cs], %[ar]\n\t" | ||
383 | "jnz 1f\n\t" | ||
384 | "mov $1, %[valid]\n\t" | ||
385 | "1:" | ||
386 | : [ar] "=r" (ar), [valid] "+rm" (valid) | ||
387 | : [cs] "r" (cs)); | ||
388 | |||
389 | if (!valid) | ||
390 | return false; | ||
391 | |||
392 | if ((ar & AR_TYPE_MASK) != AR_TYPE_RWDATA && | ||
393 | (ar & AR_TYPE_MASK) != AR_TYPE_RWDATA_EXPDOWN) | ||
394 | return false; | ||
395 | |||
396 | return (ar & AR_P); | ||
397 | } | ||
398 | |||
308 | /* Number of errors in the current test case. */ | 399 | /* Number of errors in the current test case. */ |
309 | static volatile sig_atomic_t nerrs; | 400 | static volatile sig_atomic_t nerrs; |
310 | 401 | ||
402 | static void validate_signal_ss(int sig, ucontext_t *ctx) | ||
403 | { | ||
404 | #ifdef __x86_64__ | ||
405 | bool was_64bit = (cs_bitness(*csptr(ctx)) == 64); | ||
406 | |||
407 | if (!(ctx->uc_flags & UC_SIGCONTEXT_SS)) { | ||
408 | printf("[FAIL]\tUC_SIGCONTEXT_SS was not set\n"); | ||
409 | nerrs++; | ||
410 | |||
411 | /* | ||
412 | * This happens on Linux 4.1. The rest will fail, too, so | ||
413 | * return now to reduce the noise. | ||
414 | */ | ||
415 | return; | ||
416 | } | ||
417 | |||
418 | /* UC_STRICT_RESTORE_SS is set iff we came from 64-bit mode. */ | ||
419 | if (!!(ctx->uc_flags & UC_STRICT_RESTORE_SS) != was_64bit) { | ||
420 | printf("[FAIL]\tUC_STRICT_RESTORE_SS was wrong in signal %d\n", | ||
421 | sig); | ||
422 | nerrs++; | ||
423 | } | ||
424 | |||
425 | if (is_valid_ss(*ssptr(ctx))) { | ||
426 | /* | ||
427 | * DOSEMU was written before 64-bit sigcontext had SS, and | ||
428 | * it tries to figure out the signal source SS by looking at | ||
429 | * the physical register. Make sure that keeps working. | ||
430 | */ | ||
431 | unsigned short hw_ss; | ||
432 | asm ("mov %%ss, %0" : "=rm" (hw_ss)); | ||
433 | if (hw_ss != *ssptr(ctx)) { | ||
434 | printf("[FAIL]\tHW SS didn't match saved SS\n"); | ||
435 | nerrs++; | ||
436 | } | ||
437 | } | ||
438 | #endif | ||
439 | } | ||
440 | |||
311 | /* | 441 | /* |
312 | * SIGUSR1 handler. Sets CS and SS as requested and points IP to the | 442 | * SIGUSR1 handler. Sets CS and SS as requested and points IP to the |
313 | * int3 trampoline. Sets SP to a large known value so that we can see | 443 | * int3 trampoline. Sets SP to a large known value so that we can see |
@@ -317,6 +447,8 @@ static void sigusr1(int sig, siginfo_t *info, void *ctx_void) | |||
317 | { | 447 | { |
318 | ucontext_t *ctx = (ucontext_t*)ctx_void; | 448 | ucontext_t *ctx = (ucontext_t*)ctx_void; |
319 | 449 | ||
450 | validate_signal_ss(sig, ctx); | ||
451 | |||
320 | memcpy(&initial_regs, &ctx->uc_mcontext.gregs, sizeof(gregset_t)); | 452 | memcpy(&initial_regs, &ctx->uc_mcontext.gregs, sizeof(gregset_t)); |
321 | 453 | ||
322 | *csptr(ctx) = sig_cs; | 454 | *csptr(ctx) = sig_cs; |
@@ -334,13 +466,16 @@ static void sigusr1(int sig, siginfo_t *info, void *ctx_void) | |||
334 | } | 466 | } |
335 | 467 | ||
336 | /* | 468 | /* |
337 | * Called after a successful sigreturn. Restores our state so that | 469 | * Called after a successful sigreturn (via int3) or from a failed |
338 | * the original raise(SIGUSR1) returns. | 470 | * sigreturn (directly by kernel). Restores our state so that the |
471 | * original raise(SIGUSR1) returns. | ||
339 | */ | 472 | */ |
340 | static void sigtrap(int sig, siginfo_t *info, void *ctx_void) | 473 | static void sigtrap(int sig, siginfo_t *info, void *ctx_void) |
341 | { | 474 | { |
342 | ucontext_t *ctx = (ucontext_t*)ctx_void; | 475 | ucontext_t *ctx = (ucontext_t*)ctx_void; |
343 | 476 | ||
477 | validate_signal_ss(sig, ctx); | ||
478 | |||
344 | sig_err = ctx->uc_mcontext.gregs[REG_ERR]; | 479 | sig_err = ctx->uc_mcontext.gregs[REG_ERR]; |
345 | sig_trapno = ctx->uc_mcontext.gregs[REG_TRAPNO]; | 480 | sig_trapno = ctx->uc_mcontext.gregs[REG_TRAPNO]; |
346 | 481 | ||
@@ -358,41 +493,62 @@ static void sigtrap(int sig, siginfo_t *info, void *ctx_void) | |||
358 | memcpy(&resulting_regs, &ctx->uc_mcontext.gregs, sizeof(gregset_t)); | 493 | memcpy(&resulting_regs, &ctx->uc_mcontext.gregs, sizeof(gregset_t)); |
359 | memcpy(&ctx->uc_mcontext.gregs, &initial_regs, sizeof(gregset_t)); | 494 | memcpy(&ctx->uc_mcontext.gregs, &initial_regs, sizeof(gregset_t)); |
360 | 495 | ||
496 | #ifdef __x86_64__ | ||
497 | if (sig_corrupt_final_ss) { | ||
498 | if (ctx->uc_flags & UC_STRICT_RESTORE_SS) { | ||
499 | printf("[FAIL]\tUC_STRICT_RESTORE_SS was set inappropriately\n"); | ||
500 | nerrs++; | ||
501 | } else { | ||
502 | /* | ||
503 | * DOSEMU transitions from 32-bit to 64-bit mode by | ||
504 | * adjusting sigcontext, and it requires that this work | ||
505 | * even if the saved SS is bogus. | ||
506 | */ | ||
507 | printf("\tCorrupting SS on return to 64-bit mode\n"); | ||
508 | *ssptr(ctx) = 0; | ||
509 | } | ||
510 | } | ||
511 | #endif | ||
512 | |||
361 | sig_trapped = sig; | 513 | sig_trapped = sig; |
362 | } | 514 | } |
363 | 515 | ||
364 | /* | 516 | #ifdef __x86_64__ |
365 | * Checks a given selector for its code bitness or returns -1 if it's not | 517 | /* Tests recovery if !UC_STRICT_RESTORE_SS */ |
366 | * a usable code segment selector. | 518 | static void sigusr2(int sig, siginfo_t *info, void *ctx_void) |
367 | */ | ||
368 | int cs_bitness(unsigned short cs) | ||
369 | { | 519 | { |
370 | uint32_t valid = 0, ar; | 520 | ucontext_t *ctx = (ucontext_t*)ctx_void; |
371 | asm ("lar %[cs], %[ar]\n\t" | ||
372 | "jnz 1f\n\t" | ||
373 | "mov $1, %[valid]\n\t" | ||
374 | "1:" | ||
375 | : [ar] "=r" (ar), [valid] "+rm" (valid) | ||
376 | : [cs] "r" (cs)); | ||
377 | 521 | ||
378 | if (!valid) | 522 | if (!(ctx->uc_flags & UC_STRICT_RESTORE_SS)) { |
379 | return -1; | 523 | printf("[FAIL]\traise(2) didn't set UC_STRICT_RESTORE_SS\n"); |
524 | nerrs++; | ||
525 | return; /* We can't do the rest. */ | ||
526 | } | ||
380 | 527 | ||
381 | bool db = (ar & (1 << 22)); | 528 | ctx->uc_flags &= ~UC_STRICT_RESTORE_SS; |
382 | bool l = (ar & (1 << 21)); | 529 | *ssptr(ctx) = 0; |
383 | 530 | ||
384 | if (!(ar & (1<<11))) | 531 | /* Return. The kernel should recover without sending another signal. */ |
385 | return -1; /* Not code. */ | 532 | } |
386 | 533 | ||
387 | if (l && !db) | 534 | static int test_nonstrict_ss(void) |
388 | return 64; | 535 | { |
389 | else if (!l && db) | 536 | clearhandler(SIGUSR1); |
390 | return 32; | 537 | clearhandler(SIGTRAP); |
391 | else if (!l && !db) | 538 | clearhandler(SIGSEGV); |
392 | return 16; | 539 | clearhandler(SIGILL); |
393 | else | 540 | sethandler(SIGUSR2, sigusr2, 0); |
394 | return -1; /* Unknown bitness. */ | 541 | |
542 | nerrs = 0; | ||
543 | |||
544 | printf("[RUN]\tClear UC_STRICT_RESTORE_SS and corrupt SS\n"); | ||
545 | raise(SIGUSR2); | ||
546 | if (!nerrs) | ||
547 | printf("[OK]\tIt worked\n"); | ||
548 | |||
549 | return nerrs; | ||
395 | } | 550 | } |
551 | #endif | ||
396 | 552 | ||
397 | /* Finds a usable code segment of the requested bitness. */ | 553 | /* Finds a usable code segment of the requested bitness. */ |
398 | int find_cs(int bitness) | 554 | int find_cs(int bitness) |
@@ -576,6 +732,12 @@ static int test_bad_iret(int cs_bits, unsigned short ss, int force_cs) | |||
576 | errdesc, strsignal(sig_trapped)); | 732 | errdesc, strsignal(sig_trapped)); |
577 | return 0; | 733 | return 0; |
578 | } else { | 734 | } else { |
735 | /* | ||
736 | * This also implicitly tests UC_STRICT_RESTORE_SS: | ||
737 | * We check that these signals set UC_STRICT_RESTORE_SS and, | ||
738 | * if UC_STRICT_RESTORE_SS doesn't cause strict behavior, | ||
739 | * then we won't get SIGSEGV. | ||
740 | */ | ||
579 | printf("[FAIL]\tDid not get SIGSEGV\n"); | 741 | printf("[FAIL]\tDid not get SIGSEGV\n"); |
580 | return 1; | 742 | return 1; |
581 | } | 743 | } |
@@ -632,6 +794,14 @@ int main() | |||
632 | GDT3(gdt_data16_idx)); | 794 | GDT3(gdt_data16_idx)); |
633 | } | 795 | } |
634 | 796 | ||
797 | #ifdef __x86_64__ | ||
798 | /* Nasty ABI case: check SS corruption handling. */ | ||
799 | sig_corrupt_final_ss = 1; | ||
800 | total_nerrs += test_valid_sigreturn(32, false, -1); | ||
801 | total_nerrs += test_valid_sigreturn(32, true, -1); | ||
802 | sig_corrupt_final_ss = 0; | ||
803 | #endif | ||
804 | |||
635 | /* | 805 | /* |
636 | * We're done testing valid sigreturn cases. Now we test states | 806 | * We're done testing valid sigreturn cases. Now we test states |
637 | * for which sigreturn itself will succeed but the subsequent | 807 | * for which sigreturn itself will succeed but the subsequent |
@@ -680,5 +850,9 @@ int main() | |||
680 | if (gdt_npdata32_idx) | 850 | if (gdt_npdata32_idx) |
681 | test_bad_iret(32, GDT3(gdt_npdata32_idx), -1); | 851 | test_bad_iret(32, GDT3(gdt_npdata32_idx), -1); |
682 | 852 | ||
853 | #ifdef __x86_64__ | ||
854 | total_nerrs += test_nonstrict_ss(); | ||
855 | #endif | ||
856 | |||
683 | return total_nerrs ? 1 : 0; | 857 | return total_nerrs ? 1 : 0; |
684 | } | 858 | } |