Skip to content

Commit 8a5f060

Browse files
committed
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Thomas Gleixner: "A set of fixes for x86: - Fix the swapped outb() parameters in the KASLR code - Fix the PKEY handling at fork which missed to preserve the pkey state for the child. Comes with a test case to validate that. - Fix the entry stack handling for XEN PV to respect that XEN PV systems enter the function already on the current thread stack and not on the trampoline. - Fix kexec load failure caused by using a stale value when the kexec_buf structure is reused for subsequent allocations. - Fix a bogus sizeof() in the memory encryption code - Enforce PCI dependency for the Intel Low Power Subsystem - Enforce PCI_LOCKLESS_CONFIG when PCI is enabled" * 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/Kconfig: Select PCI_LOCKLESS_CONFIG if PCI is enabled x86/entry/64/compat: Fix stack switching for XEN PV x86/kexec: Fix a kexec_file_load() failure x86/mm/mem_encrypt: Fix erroneous sizeof() x86/selftests/pkeys: Fork() to check for state being preserved x86/pkeys: Properly copy pkey state at fork() x86/kaslr: Fix incorrect i8254 outb() parameters x86/intel/lpss: Make PCI dependency explicit
2 parents 351e1aa + 625210c commit 8a5f060

File tree

8 files changed

+61
-17
lines changed

8 files changed

+61
-17
lines changed

arch/x86/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ config X86
198198
select IRQ_FORCED_THREADING
199199
select NEED_SG_DMA_LENGTH
200200
select PCI_DOMAINS if PCI
201-
select PCI_LOCKLESS_CONFIG
201+
select PCI_LOCKLESS_CONFIG if PCI
202202
select PERF_EVENTS
203203
select RTC_LIB
204204
select RTC_MC146818_LIB

arch/x86/entry/entry_64_compat.S

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,8 @@ ENTRY(entry_INT80_compat)
361361

362362
/* Need to switch before accessing the thread stack. */
363363
SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi
364-
movq %rsp, %rdi
364+
/* In the Xen PV case we already run on the thread stack. */
365+
ALTERNATIVE "movq %rsp, %rdi", "jmp .Lint80_keep_stack", X86_FEATURE_XENPV
365366
movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
366367

367368
pushq 6*8(%rdi) /* regs->ss */
@@ -370,8 +371,9 @@ ENTRY(entry_INT80_compat)
370371
pushq 3*8(%rdi) /* regs->cs */
371372
pushq 2*8(%rdi) /* regs->ip */
372373
pushq 1*8(%rdi) /* regs->orig_ax */
373-
374374
pushq (%rdi) /* pt_regs->di */
375+
.Lint80_keep_stack:
376+
375377
pushq %rsi /* pt_regs->si */
376378
xorl %esi, %esi /* nospec si */
377379
pushq %rdx /* pt_regs->dx */

arch/x86/include/asm/mmu_context.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,10 @@ static inline void switch_ldt(struct mm_struct *prev, struct mm_struct *next)
178178

179179
void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk);
180180

181+
/*
182+
* Init a new mm. Used on mm copies, like at fork()
183+
* and on mm's that are brand-new, like at execve().
184+
*/
181185
static inline int init_new_context(struct task_struct *tsk,
182186
struct mm_struct *mm)
183187
{
@@ -228,8 +232,22 @@ do { \
228232
} while (0)
229233
#endif
230234

235+
static inline void arch_dup_pkeys(struct mm_struct *oldmm,
236+
struct mm_struct *mm)
237+
{
238+
#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
239+
if (!cpu_feature_enabled(X86_FEATURE_OSPKE))
240+
return;
241+
242+
/* Duplicate the oldmm pkey state in mm: */
243+
mm->context.pkey_allocation_map = oldmm->context.pkey_allocation_map;
244+
mm->context.execute_only_pkey = oldmm->context.execute_only_pkey;
245+
#endif
246+
}
247+
231248
static inline int arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm)
232249
{
250+
arch_dup_pkeys(oldmm, mm);
233251
paravirt_arch_dup_mmap(oldmm, mm);
234252
return ldt_dup_context(oldmm, mm);
235253
}

arch/x86/kernel/crash.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,7 @@ int crash_load_segments(struct kimage *image)
470470

471471
kbuf.memsz = kbuf.bufsz;
472472
kbuf.buf_align = ELF_CORE_HEADER_ALIGN;
473+
kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
473474
ret = kexec_add_buffer(&kbuf);
474475
if (ret) {
475476
vfree((void *)image->arch.elf_headers);

arch/x86/kernel/kexec-bzimage64.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ static void *bzImage64_load(struct kimage *image, char *kernel,
434434
kbuf.memsz = PAGE_ALIGN(header->init_size);
435435
kbuf.buf_align = header->kernel_alignment;
436436
kbuf.buf_min = MIN_KERNEL_LOAD_ADDR;
437+
kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
437438
ret = kexec_add_buffer(&kbuf);
438439
if (ret)
439440
goto out_free_params;
@@ -448,6 +449,7 @@ static void *bzImage64_load(struct kimage *image, char *kernel,
448449
kbuf.bufsz = kbuf.memsz = initrd_len;
449450
kbuf.buf_align = PAGE_SIZE;
450451
kbuf.buf_min = MIN_INITRD_LOAD_ADDR;
452+
kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
451453
ret = kexec_add_buffer(&kbuf);
452454
if (ret)
453455
goto out_free_params;

arch/x86/lib/kaslr.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ static inline u16 i8254(void)
3636
u16 status, timer;
3737

3838
do {
39-
outb(I8254_PORT_CONTROL,
40-
I8254_CMD_READBACK | I8254_SELECT_COUNTER0);
39+
outb(I8254_CMD_READBACK | I8254_SELECT_COUNTER0,
40+
I8254_PORT_CONTROL);
4141
status = inb(I8254_PORT_COUNTER0);
4242
timer = inb(I8254_PORT_COUNTER0);
4343
timer |= inb(I8254_PORT_COUNTER0) << 8;

arch/x86/mm/mem_encrypt_identity.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,8 @@ static void __init sme_populate_pgd(struct sme_populate_pgd_data *ppd)
158158
pmd = pmd_offset(pud, ppd->vaddr);
159159
if (pmd_none(*pmd)) {
160160
pte = ppd->pgtable_area;
161-
memset(pte, 0, sizeof(pte) * PTRS_PER_PTE);
162-
ppd->pgtable_area += sizeof(pte) * PTRS_PER_PTE;
161+
memset(pte, 0, sizeof(*pte) * PTRS_PER_PTE);
162+
ppd->pgtable_area += sizeof(*pte) * PTRS_PER_PTE;
163163
set_pmd(pmd, __pmd(PMD_FLAGS | __pa(pte)));
164164
}
165165

tools/testing/selftests/x86/protection_keys.c

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,6 +1133,21 @@ void test_pkey_syscalls_bad_args(int *ptr, u16 pkey)
11331133
pkey_assert(err);
11341134
}
11351135

1136+
void become_child(void)
1137+
{
1138+
pid_t forkret;
1139+
1140+
forkret = fork();
1141+
pkey_assert(forkret >= 0);
1142+
dprintf3("[%d] fork() ret: %d\n", getpid(), forkret);
1143+
1144+
if (!forkret) {
1145+
/* in the child */
1146+
return;
1147+
}
1148+
exit(0);
1149+
}
1150+
11361151
/* Assumes that all pkeys other than 'pkey' are unallocated */
11371152
void test_pkey_alloc_exhaust(int *ptr, u16 pkey)
11381153
{
@@ -1141,7 +1156,7 @@ void test_pkey_alloc_exhaust(int *ptr, u16 pkey)
11411156
int nr_allocated_pkeys = 0;
11421157
int i;
11431158

1144-
for (i = 0; i < NR_PKEYS*2; i++) {
1159+
for (i = 0; i < NR_PKEYS*3; i++) {
11451160
int new_pkey;
11461161
dprintf1("%s() alloc loop: %d\n", __func__, i);
11471162
new_pkey = alloc_pkey();
@@ -1152,20 +1167,26 @@ void test_pkey_alloc_exhaust(int *ptr, u16 pkey)
11521167
if ((new_pkey == -1) && (errno == ENOSPC)) {
11531168
dprintf2("%s() failed to allocate pkey after %d tries\n",
11541169
__func__, nr_allocated_pkeys);
1155-
break;
1170+
} else {
1171+
/*
1172+
* Ensure the number of successes never
1173+
* exceeds the number of keys supported
1174+
* in the hardware.
1175+
*/
1176+
pkey_assert(nr_allocated_pkeys < NR_PKEYS);
1177+
allocated_pkeys[nr_allocated_pkeys++] = new_pkey;
11561178
}
1157-
pkey_assert(nr_allocated_pkeys < NR_PKEYS);
1158-
allocated_pkeys[nr_allocated_pkeys++] = new_pkey;
1179+
1180+
/*
1181+
* Make sure that allocation state is properly
1182+
* preserved across fork().
1183+
*/
1184+
if (i == NR_PKEYS*2)
1185+
become_child();
11591186
}
11601187

11611188
dprintf3("%s()::%d\n", __func__, __LINE__);
11621189

1163-
/*
1164-
* ensure it did not reach the end of the loop without
1165-
* failure:
1166-
*/
1167-
pkey_assert(i < NR_PKEYS*2);
1168-
11691190
/*
11701191
* There are 16 pkeys supported in hardware. Three are
11711192
* allocated by the time we get here:

0 commit comments

Comments
 (0)