diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-26 17:11:54 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-26 17:11:54 -0500 |
commit | 02fc87b117a9b9ec325089d098fce86ed11966bd (patch) | |
tree | 537176c1c32b25c781bf8974af854a4ee4dbc77a /tools | |
parent | 6830c8db58c2616d8ba2bf45e7d98dca5f69b07f (diff) | |
parent | 12a78d43de767eaf8fb272facb7a7b6f2dc6a9df (diff) |
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull misc x86 fixes from Ingo Molnar:
- topology enumeration fixes
- KASAN fix
- two entry fixes (not yet the big series related to KASLR)
- remove obsolete code
- instruction decoder fix
- better /dev/mem sanity checks, hopefully working better this time
- pkeys fixes
- two ACPI fixes
- 5-level paging related fixes
- UMIP fixes that should make application visible faults more debuggable
- boot fix for weird virtualization environment
* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (24 commits)
x86/decoder: Add new TEST instruction pattern
x86/PCI: Remove unused HyperTransport interrupt support
x86/umip: Fix insn_get_code_seg_params()'s return value
x86/boot/KASLR: Remove unused variable
x86/entry/64: Add missing irqflags tracing to native_load_gs_index()
x86/mm/kasan: Don't use vmemmap_populate() to initialize shadow
x86/entry/64: Fix entry_SYSCALL_64_after_hwframe() IRQ tracing
x86/pkeys/selftests: Fix protection keys write() warning
x86/pkeys/selftests: Rename 'si_pkey' to 'siginfo_pkey'
x86/mpx/selftests: Fix up weird arrays
x86/pkeys: Update documentation about availability
x86/umip: Print a warning into the syslog if UMIP-protected instructions are used
x86/smpboot: Fix __max_logical_packages estimate
x86/topology: Avoid wasting 128k for package id array
perf/x86/intel/uncore: Cache logical pkg id in uncore driver
x86/acpi: Reduce code duplication in mp_override_legacy_irq()
x86/acpi: Handle SCI interrupts above legacy space gracefully
x86/boot: Fix boot failure when SMP MP-table is based at 0
x86/mm: Limit mmap() of /dev/mem to valid physical addresses
x86/selftests: Add test for mapping placement for 5-level paging
...
Diffstat (limited to 'tools')
-rw-r--r-- | tools/testing/selftests/x86/5lvl.c | 177 | ||||
-rw-r--r-- | tools/testing/selftests/x86/Makefile | 2 | ||||
-rw-r--r-- | tools/testing/selftests/x86/mpx-hw.h | 4 | ||||
-rw-r--r-- | tools/testing/selftests/x86/pkey-helpers.h | 5 | ||||
-rw-r--r-- | tools/testing/selftests/x86/protection_keys.c | 10 |
5 files changed, 189 insertions, 9 deletions
diff --git a/tools/testing/selftests/x86/5lvl.c b/tools/testing/selftests/x86/5lvl.c new file mode 100644 index 000000000000..2eafdcd4c2b3 --- /dev/null +++ b/tools/testing/selftests/x86/5lvl.c | |||
@@ -0,0 +1,177 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <sys/mman.h> | ||
3 | |||
4 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) | ||
5 | |||
6 | #define PAGE_SIZE 4096 | ||
7 | #define LOW_ADDR ((void *) (1UL << 30)) | ||
8 | #define HIGH_ADDR ((void *) (1UL << 50)) | ||
9 | |||
10 | struct testcase { | ||
11 | void *addr; | ||
12 | unsigned long size; | ||
13 | unsigned long flags; | ||
14 | const char *msg; | ||
15 | unsigned int low_addr_required:1; | ||
16 | unsigned int keep_mapped:1; | ||
17 | }; | ||
18 | |||
19 | static struct testcase testcases[] = { | ||
20 | { | ||
21 | .addr = NULL, | ||
22 | .size = 2 * PAGE_SIZE, | ||
23 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
24 | .msg = "mmap(NULL)", | ||
25 | .low_addr_required = 1, | ||
26 | }, | ||
27 | { | ||
28 | .addr = LOW_ADDR, | ||
29 | .size = 2 * PAGE_SIZE, | ||
30 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
31 | .msg = "mmap(LOW_ADDR)", | ||
32 | .low_addr_required = 1, | ||
33 | }, | ||
34 | { | ||
35 | .addr = HIGH_ADDR, | ||
36 | .size = 2 * PAGE_SIZE, | ||
37 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
38 | .msg = "mmap(HIGH_ADDR)", | ||
39 | .keep_mapped = 1, | ||
40 | }, | ||
41 | { | ||
42 | .addr = HIGH_ADDR, | ||
43 | .size = 2 * PAGE_SIZE, | ||
44 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
45 | .msg = "mmap(HIGH_ADDR) again", | ||
46 | .keep_mapped = 1, | ||
47 | }, | ||
48 | { | ||
49 | .addr = HIGH_ADDR, | ||
50 | .size = 2 * PAGE_SIZE, | ||
51 | .flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, | ||
52 | .msg = "mmap(HIGH_ADDR, MAP_FIXED)", | ||
53 | }, | ||
54 | { | ||
55 | .addr = (void*) -1, | ||
56 | .size = 2 * PAGE_SIZE, | ||
57 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
58 | .msg = "mmap(-1)", | ||
59 | .keep_mapped = 1, | ||
60 | }, | ||
61 | { | ||
62 | .addr = (void*) -1, | ||
63 | .size = 2 * PAGE_SIZE, | ||
64 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
65 | .msg = "mmap(-1) again", | ||
66 | }, | ||
67 | { | ||
68 | .addr = (void *)((1UL << 47) - PAGE_SIZE), | ||
69 | .size = 2 * PAGE_SIZE, | ||
70 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
71 | .msg = "mmap((1UL << 47), 2 * PAGE_SIZE)", | ||
72 | .low_addr_required = 1, | ||
73 | .keep_mapped = 1, | ||
74 | }, | ||
75 | { | ||
76 | .addr = (void *)((1UL << 47) - PAGE_SIZE / 2), | ||
77 | .size = 2 * PAGE_SIZE, | ||
78 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
79 | .msg = "mmap((1UL << 47), 2 * PAGE_SIZE / 2)", | ||
80 | .low_addr_required = 1, | ||
81 | .keep_mapped = 1, | ||
82 | }, | ||
83 | { | ||
84 | .addr = (void *)((1UL << 47) - PAGE_SIZE), | ||
85 | .size = 2 * PAGE_SIZE, | ||
86 | .flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, | ||
87 | .msg = "mmap((1UL << 47) - PAGE_SIZE, 2 * PAGE_SIZE, MAP_FIXED)", | ||
88 | }, | ||
89 | { | ||
90 | .addr = NULL, | ||
91 | .size = 2UL << 20, | ||
92 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | ||
93 | .msg = "mmap(NULL, MAP_HUGETLB)", | ||
94 | .low_addr_required = 1, | ||
95 | }, | ||
96 | { | ||
97 | .addr = LOW_ADDR, | ||
98 | .size = 2UL << 20, | ||
99 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | ||
100 | .msg = "mmap(LOW_ADDR, MAP_HUGETLB)", | ||
101 | .low_addr_required = 1, | ||
102 | }, | ||
103 | { | ||
104 | .addr = HIGH_ADDR, | ||
105 | .size = 2UL << 20, | ||
106 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | ||
107 | .msg = "mmap(HIGH_ADDR, MAP_HUGETLB)", | ||
108 | .keep_mapped = 1, | ||
109 | }, | ||
110 | { | ||
111 | .addr = HIGH_ADDR, | ||
112 | .size = 2UL << 20, | ||
113 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | ||
114 | .msg = "mmap(HIGH_ADDR, MAP_HUGETLB) again", | ||
115 | .keep_mapped = 1, | ||
116 | }, | ||
117 | { | ||
118 | .addr = HIGH_ADDR, | ||
119 | .size = 2UL << 20, | ||
120 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, | ||
121 | .msg = "mmap(HIGH_ADDR, MAP_FIXED | MAP_HUGETLB)", | ||
122 | }, | ||
123 | { | ||
124 | .addr = (void*) -1, | ||
125 | .size = 2UL << 20, | ||
126 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | ||
127 | .msg = "mmap(-1, MAP_HUGETLB)", | ||
128 | .keep_mapped = 1, | ||
129 | }, | ||
130 | { | ||
131 | .addr = (void*) -1, | ||
132 | .size = 2UL << 20, | ||
133 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | ||
134 | .msg = "mmap(-1, MAP_HUGETLB) again", | ||
135 | }, | ||
136 | { | ||
137 | .addr = (void *)((1UL << 47) - PAGE_SIZE), | ||
138 | .size = 4UL << 20, | ||
139 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | ||
140 | .msg = "mmap((1UL << 47), 4UL << 20, MAP_HUGETLB)", | ||
141 | .low_addr_required = 1, | ||
142 | .keep_mapped = 1, | ||
143 | }, | ||
144 | { | ||
145 | .addr = (void *)((1UL << 47) - (2UL << 20)), | ||
146 | .size = 4UL << 20, | ||
147 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, | ||
148 | .msg = "mmap((1UL << 47) - (2UL << 20), 4UL << 20, MAP_FIXED | MAP_HUGETLB)", | ||
149 | }, | ||
150 | }; | ||
151 | |||
152 | int main(int argc, char **argv) | ||
153 | { | ||
154 | int i; | ||
155 | void *p; | ||
156 | |||
157 | for (i = 0; i < ARRAY_SIZE(testcases); i++) { | ||
158 | struct testcase *t = testcases + i; | ||
159 | |||
160 | p = mmap(t->addr, t->size, PROT_NONE, t->flags, -1, 0); | ||
161 | |||
162 | printf("%s: %p - ", t->msg, p); | ||
163 | |||
164 | if (p == MAP_FAILED) { | ||
165 | printf("FAILED\n"); | ||
166 | continue; | ||
167 | } | ||
168 | |||
169 | if (t->low_addr_required && p >= (void *)(1UL << 47)) | ||
170 | printf("FAILED\n"); | ||
171 | else | ||
172 | printf("OK\n"); | ||
173 | if (!t->keep_mapped) | ||
174 | munmap(p, t->size); | ||
175 | } | ||
176 | return 0; | ||
177 | } | ||
diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index 7b1adeee4b0f..939a337128db 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile | |||
@@ -11,7 +11,7 @@ TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_sysc | |||
11 | TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \ | 11 | TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \ |
12 | test_FCMOV test_FCOMI test_FISTTP \ | 12 | test_FCMOV test_FCOMI test_FISTTP \ |
13 | vdso_restorer | 13 | vdso_restorer |
14 | TARGETS_C_64BIT_ONLY := fsgsbase sysret_rip | 14 | TARGETS_C_64BIT_ONLY := fsgsbase sysret_rip 5lvl |
15 | 15 | ||
16 | TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY) | 16 | TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY) |
17 | TARGETS_C_64BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_64BIT_ONLY) | 17 | TARGETS_C_64BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_64BIT_ONLY) |
diff --git a/tools/testing/selftests/x86/mpx-hw.h b/tools/testing/selftests/x86/mpx-hw.h index 3f0093911f03..d1b61ab870f8 100644 --- a/tools/testing/selftests/x86/mpx-hw.h +++ b/tools/testing/selftests/x86/mpx-hw.h | |||
@@ -52,14 +52,14 @@ | |||
52 | struct mpx_bd_entry { | 52 | struct mpx_bd_entry { |
53 | union { | 53 | union { |
54 | char x[MPX_BOUNDS_DIR_ENTRY_SIZE_BYTES]; | 54 | char x[MPX_BOUNDS_DIR_ENTRY_SIZE_BYTES]; |
55 | void *contents[1]; | 55 | void *contents[0]; |
56 | }; | 56 | }; |
57 | } __attribute__((packed)); | 57 | } __attribute__((packed)); |
58 | 58 | ||
59 | struct mpx_bt_entry { | 59 | struct mpx_bt_entry { |
60 | union { | 60 | union { |
61 | char x[MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTES]; | 61 | char x[MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTES]; |
62 | unsigned long contents[1]; | 62 | unsigned long contents[0]; |
63 | }; | 63 | }; |
64 | } __attribute__((packed)); | 64 | } __attribute__((packed)); |
65 | 65 | ||
diff --git a/tools/testing/selftests/x86/pkey-helpers.h b/tools/testing/selftests/x86/pkey-helpers.h index 3818f25391c2..b3cb7670e026 100644 --- a/tools/testing/selftests/x86/pkey-helpers.h +++ b/tools/testing/selftests/x86/pkey-helpers.h | |||
@@ -30,6 +30,7 @@ static inline void sigsafe_printf(const char *format, ...) | |||
30 | if (!dprint_in_signal) { | 30 | if (!dprint_in_signal) { |
31 | vprintf(format, ap); | 31 | vprintf(format, ap); |
32 | } else { | 32 | } else { |
33 | int ret; | ||
33 | int len = vsnprintf(dprint_in_signal_buffer, | 34 | int len = vsnprintf(dprint_in_signal_buffer, |
34 | DPRINT_IN_SIGNAL_BUF_SIZE, | 35 | DPRINT_IN_SIGNAL_BUF_SIZE, |
35 | format, ap); | 36 | format, ap); |
@@ -39,7 +40,9 @@ static inline void sigsafe_printf(const char *format, ...) | |||
39 | */ | 40 | */ |
40 | if (len > DPRINT_IN_SIGNAL_BUF_SIZE) | 41 | if (len > DPRINT_IN_SIGNAL_BUF_SIZE) |
41 | len = DPRINT_IN_SIGNAL_BUF_SIZE; | 42 | len = DPRINT_IN_SIGNAL_BUF_SIZE; |
42 | write(1, dprint_in_signal_buffer, len); | 43 | ret = write(1, dprint_in_signal_buffer, len); |
44 | if (ret < 0) | ||
45 | abort(); | ||
43 | } | 46 | } |
44 | va_end(ap); | 47 | va_end(ap); |
45 | } | 48 | } |
diff --git a/tools/testing/selftests/x86/protection_keys.c b/tools/testing/selftests/x86/protection_keys.c index 7a1cc0e56d2d..bc1b0735bb50 100644 --- a/tools/testing/selftests/x86/protection_keys.c +++ b/tools/testing/selftests/x86/protection_keys.c | |||
@@ -250,7 +250,7 @@ void signal_handler(int signum, siginfo_t *si, void *vucontext) | |||
250 | unsigned long ip; | 250 | unsigned long ip; |
251 | char *fpregs; | 251 | char *fpregs; |
252 | u32 *pkru_ptr; | 252 | u32 *pkru_ptr; |
253 | u64 si_pkey; | 253 | u64 siginfo_pkey; |
254 | u32 *si_pkey_ptr; | 254 | u32 *si_pkey_ptr; |
255 | int pkru_offset; | 255 | int pkru_offset; |
256 | fpregset_t fpregset; | 256 | fpregset_t fpregset; |
@@ -292,9 +292,9 @@ void signal_handler(int signum, siginfo_t *si, void *vucontext) | |||
292 | si_pkey_ptr = (u32 *)(((u8 *)si) + si_pkey_offset); | 292 | si_pkey_ptr = (u32 *)(((u8 *)si) + si_pkey_offset); |
293 | dprintf1("si_pkey_ptr: %p\n", si_pkey_ptr); | 293 | dprintf1("si_pkey_ptr: %p\n", si_pkey_ptr); |
294 | dump_mem(si_pkey_ptr - 8, 24); | 294 | dump_mem(si_pkey_ptr - 8, 24); |
295 | si_pkey = *si_pkey_ptr; | 295 | siginfo_pkey = *si_pkey_ptr; |
296 | pkey_assert(si_pkey < NR_PKEYS); | 296 | pkey_assert(siginfo_pkey < NR_PKEYS); |
297 | last_si_pkey = si_pkey; | 297 | last_si_pkey = siginfo_pkey; |
298 | 298 | ||
299 | if ((si->si_code == SEGV_MAPERR) || | 299 | if ((si->si_code == SEGV_MAPERR) || |
300 | (si->si_code == SEGV_ACCERR) || | 300 | (si->si_code == SEGV_ACCERR) || |
@@ -306,7 +306,7 @@ void signal_handler(int signum, siginfo_t *si, void *vucontext) | |||
306 | dprintf1("signal pkru from xsave: %08x\n", *pkru_ptr); | 306 | dprintf1("signal pkru from xsave: %08x\n", *pkru_ptr); |
307 | /* need __rdpkru() version so we do not do shadow_pkru checking */ | 307 | /* need __rdpkru() version so we do not do shadow_pkru checking */ |
308 | dprintf1("signal pkru from pkru: %08x\n", __rdpkru()); | 308 | dprintf1("signal pkru from pkru: %08x\n", __rdpkru()); |
309 | dprintf1("si_pkey from siginfo: %jx\n", si_pkey); | 309 | dprintf1("pkey from siginfo: %jx\n", siginfo_pkey); |
310 | *(u64 *)pkru_ptr = 0x00000000; | 310 | *(u64 *)pkru_ptr = 0x00000000; |
311 | dprintf1("WARNING: set PRKU=0 to allow faulting instruction to continue\n"); | 311 | dprintf1("WARNING: set PRKU=0 to allow faulting instruction to continue\n"); |
312 | pkru_faults++; | 312 | pkru_faults++; |