diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2016-09-01 12:33:46 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2016-09-01 12:33:46 -0400 |
commit | 0cb7bf61b1e9f05027de58c80f9b46a714d24e35 (patch) | |
tree | 41fb55cf62d07b425122f9a8b96412c0d8eb99c5 /arch/arm64/kernel | |
parent | aa877175e7a9982233ed8f10cb4bfddd78d82741 (diff) | |
parent | 3eab887a55424fc2c27553b7bfe32330df83f7b8 (diff) |
Merge branch 'linus' into smp/hotplug
Apply upstream changes to avoid conflicts with pending patches.
Diffstat (limited to 'arch/arm64/kernel')
-rw-r--r-- | arch/arm64/kernel/entry.S | 7 | ||||
-rw-r--r-- | arch/arm64/kernel/head.S | 3 | ||||
-rw-r--r-- | arch/arm64/kernel/hibernate.c | 82 | ||||
-rw-r--r-- | arch/arm64/kernel/probes/kprobes.c | 31 | ||||
-rw-r--r-- | arch/arm64/kernel/sleep.S | 10 | ||||
-rw-r--r-- | arch/arm64/kernel/smp.c | 8 |
6 files changed, 77 insertions, 64 deletions
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 96e4a2b64cc1..441420ca7d08 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S | |||
@@ -353,6 +353,8 @@ el1_sync: | |||
353 | lsr x24, x1, #ESR_ELx_EC_SHIFT // exception class | 353 | lsr x24, x1, #ESR_ELx_EC_SHIFT // exception class |
354 | cmp x24, #ESR_ELx_EC_DABT_CUR // data abort in EL1 | 354 | cmp x24, #ESR_ELx_EC_DABT_CUR // data abort in EL1 |
355 | b.eq el1_da | 355 | b.eq el1_da |
356 | cmp x24, #ESR_ELx_EC_IABT_CUR // instruction abort in EL1 | ||
357 | b.eq el1_ia | ||
356 | cmp x24, #ESR_ELx_EC_SYS64 // configurable trap | 358 | cmp x24, #ESR_ELx_EC_SYS64 // configurable trap |
357 | b.eq el1_undef | 359 | b.eq el1_undef |
358 | cmp x24, #ESR_ELx_EC_SP_ALIGN // stack alignment exception | 360 | cmp x24, #ESR_ELx_EC_SP_ALIGN // stack alignment exception |
@@ -364,6 +366,11 @@ el1_sync: | |||
364 | cmp x24, #ESR_ELx_EC_BREAKPT_CUR // debug exception in EL1 | 366 | cmp x24, #ESR_ELx_EC_BREAKPT_CUR // debug exception in EL1 |
365 | b.ge el1_dbg | 367 | b.ge el1_dbg |
366 | b el1_inv | 368 | b el1_inv |
369 | |||
370 | el1_ia: | ||
371 | /* | ||
372 | * Fall through to the Data abort case | ||
373 | */ | ||
367 | el1_da: | 374 | el1_da: |
368 | /* | 375 | /* |
369 | * Data abort handling | 376 | * Data abort handling |
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index b77f58355da1..3e7b050e99dc 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S | |||
@@ -757,6 +757,9 @@ ENTRY(__enable_mmu) | |||
757 | isb | 757 | isb |
758 | bl __create_page_tables // recreate kernel mapping | 758 | bl __create_page_tables // recreate kernel mapping |
759 | 759 | ||
760 | tlbi vmalle1 // Remove any stale TLB entries | ||
761 | dsb nsh | ||
762 | |||
760 | msr sctlr_el1, x19 // re-enable the MMU | 763 | msr sctlr_el1, x19 // re-enable the MMU |
761 | isb | 764 | isb |
762 | ic iallu // flush instructions fetched | 765 | ic iallu // flush instructions fetched |
diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c index 21ab5df9fa76..65d81f965e74 100644 --- a/arch/arm64/kernel/hibernate.c +++ b/arch/arm64/kernel/hibernate.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <asm/sections.h> | 35 | #include <asm/sections.h> |
36 | #include <asm/smp.h> | 36 | #include <asm/smp.h> |
37 | #include <asm/suspend.h> | 37 | #include <asm/suspend.h> |
38 | #include <asm/sysreg.h> | ||
38 | #include <asm/virt.h> | 39 | #include <asm/virt.h> |
39 | 40 | ||
40 | /* | 41 | /* |
@@ -217,12 +218,22 @@ static int create_safe_exec_page(void *src_start, size_t length, | |||
217 | set_pte(pte, __pte(virt_to_phys((void *)dst) | | 218 | set_pte(pte, __pte(virt_to_phys((void *)dst) | |
218 | pgprot_val(PAGE_KERNEL_EXEC))); | 219 | pgprot_val(PAGE_KERNEL_EXEC))); |
219 | 220 | ||
220 | /* Load our new page tables */ | 221 | /* |
221 | asm volatile("msr ttbr0_el1, %0;" | 222 | * Load our new page tables. A strict BBM approach requires that we |
222 | "isb;" | 223 | * ensure that TLBs are free of any entries that may overlap with the |
223 | "tlbi vmalle1is;" | 224 | * global mappings we are about to install. |
224 | "dsb ish;" | 225 | * |
225 | "isb" : : "r"(virt_to_phys(pgd))); | 226 | * For a real hibernate/resume cycle TTBR0 currently points to a zero |
227 | * page, but TLBs may contain stale ASID-tagged entries (e.g. for EFI | ||
228 | * runtime services), while for a userspace-driven test_resume cycle it | ||
229 | * points to userspace page tables (and we must point it at a zero page | ||
230 | * ourselves). Elsewhere we only (un)install the idmap with preemption | ||
231 | * disabled, so T0SZ should be as required regardless. | ||
232 | */ | ||
233 | cpu_set_reserved_ttbr0(); | ||
234 | local_flush_tlb_all(); | ||
235 | write_sysreg(virt_to_phys(pgd), ttbr0_el1); | ||
236 | isb(); | ||
226 | 237 | ||
227 | *phys_dst_addr = virt_to_phys((void *)dst); | 238 | *phys_dst_addr = virt_to_phys((void *)dst); |
228 | 239 | ||
@@ -394,6 +405,38 @@ int swsusp_arch_resume(void) | |||
394 | void *, phys_addr_t, phys_addr_t); | 405 | void *, phys_addr_t, phys_addr_t); |
395 | 406 | ||
396 | /* | 407 | /* |
408 | * Restoring the memory image will overwrite the ttbr1 page tables. | ||
409 | * Create a second copy of just the linear map, and use this when | ||
410 | * restoring. | ||
411 | */ | ||
412 | tmp_pg_dir = (pgd_t *)get_safe_page(GFP_ATOMIC); | ||
413 | if (!tmp_pg_dir) { | ||
414 | pr_err("Failed to allocate memory for temporary page tables."); | ||
415 | rc = -ENOMEM; | ||
416 | goto out; | ||
417 | } | ||
418 | rc = copy_page_tables(tmp_pg_dir, PAGE_OFFSET, 0); | ||
419 | if (rc) | ||
420 | goto out; | ||
421 | |||
422 | /* | ||
423 | * Since we only copied the linear map, we need to find restore_pblist's | ||
424 | * linear map address. | ||
425 | */ | ||
426 | lm_restore_pblist = LMADDR(restore_pblist); | ||
427 | |||
428 | /* | ||
429 | * We need a zero page that is zero before & after resume in order to | ||
430 | * to break before make on the ttbr1 page tables. | ||
431 | */ | ||
432 | zero_page = (void *)get_safe_page(GFP_ATOMIC); | ||
433 | if (!zero_page) { | ||
434 | pr_err("Failed to allocate zero page."); | ||
435 | rc = -ENOMEM; | ||
436 | goto out; | ||
437 | } | ||
438 | |||
439 | /* | ||
397 | * Locate the exit code in the bottom-but-one page, so that *NULL | 440 | * Locate the exit code in the bottom-but-one page, so that *NULL |
398 | * still has disastrous affects. | 441 | * still has disastrous affects. |
399 | */ | 442 | */ |
@@ -419,27 +462,6 @@ int swsusp_arch_resume(void) | |||
419 | __flush_dcache_area(hibernate_exit, exit_size); | 462 | __flush_dcache_area(hibernate_exit, exit_size); |
420 | 463 | ||
421 | /* | 464 | /* |
422 | * Restoring the memory image will overwrite the ttbr1 page tables. | ||
423 | * Create a second copy of just the linear map, and use this when | ||
424 | * restoring. | ||
425 | */ | ||
426 | tmp_pg_dir = (pgd_t *)get_safe_page(GFP_ATOMIC); | ||
427 | if (!tmp_pg_dir) { | ||
428 | pr_err("Failed to allocate memory for temporary page tables."); | ||
429 | rc = -ENOMEM; | ||
430 | goto out; | ||
431 | } | ||
432 | rc = copy_page_tables(tmp_pg_dir, PAGE_OFFSET, 0); | ||
433 | if (rc) | ||
434 | goto out; | ||
435 | |||
436 | /* | ||
437 | * Since we only copied the linear map, we need to find restore_pblist's | ||
438 | * linear map address. | ||
439 | */ | ||
440 | lm_restore_pblist = LMADDR(restore_pblist); | ||
441 | |||
442 | /* | ||
443 | * KASLR will cause the el2 vectors to be in a different location in | 465 | * KASLR will cause the el2 vectors to be in a different location in |
444 | * the resumed kernel. Load hibernate's temporary copy into el2. | 466 | * the resumed kernel. Load hibernate's temporary copy into el2. |
445 | * | 467 | * |
@@ -453,12 +475,6 @@ int swsusp_arch_resume(void) | |||
453 | __hyp_set_vectors(el2_vectors); | 475 | __hyp_set_vectors(el2_vectors); |
454 | } | 476 | } |
455 | 477 | ||
456 | /* | ||
457 | * We need a zero page that is zero before & after resume in order to | ||
458 | * to break before make on the ttbr1 page tables. | ||
459 | */ | ||
460 | zero_page = (void *)get_safe_page(GFP_ATOMIC); | ||
461 | |||
462 | hibernate_exit(virt_to_phys(tmp_pg_dir), resume_hdr.ttbr1_el1, | 478 | hibernate_exit(virt_to_phys(tmp_pg_dir), resume_hdr.ttbr1_el1, |
463 | resume_hdr.reenter_kernel, lm_restore_pblist, | 479 | resume_hdr.reenter_kernel, lm_restore_pblist, |
464 | resume_hdr.__hyp_stub_vectors, virt_to_phys(zero_page)); | 480 | resume_hdr.__hyp_stub_vectors, virt_to_phys(zero_page)); |
diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c index bf9768588288..c6b0f40620d8 100644 --- a/arch/arm64/kernel/probes/kprobes.c +++ b/arch/arm64/kernel/probes/kprobes.c | |||
@@ -41,18 +41,6 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); | |||
41 | static void __kprobes | 41 | static void __kprobes |
42 | post_kprobe_handler(struct kprobe_ctlblk *, struct pt_regs *); | 42 | post_kprobe_handler(struct kprobe_ctlblk *, struct pt_regs *); |
43 | 43 | ||
44 | static inline unsigned long min_stack_size(unsigned long addr) | ||
45 | { | ||
46 | unsigned long size; | ||
47 | |||
48 | if (on_irq_stack(addr, raw_smp_processor_id())) | ||
49 | size = IRQ_STACK_PTR(raw_smp_processor_id()) - addr; | ||
50 | else | ||
51 | size = (unsigned long)current_thread_info() + THREAD_START_SP - addr; | ||
52 | |||
53 | return min(size, FIELD_SIZEOF(struct kprobe_ctlblk, jprobes_stack)); | ||
54 | } | ||
55 | |||
56 | static void __kprobes arch_prepare_ss_slot(struct kprobe *p) | 44 | static void __kprobes arch_prepare_ss_slot(struct kprobe *p) |
57 | { | 45 | { |
58 | /* prepare insn slot */ | 46 | /* prepare insn slot */ |
@@ -489,20 +477,15 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | |||
489 | { | 477 | { |
490 | struct jprobe *jp = container_of(p, struct jprobe, kp); | 478 | struct jprobe *jp = container_of(p, struct jprobe, kp); |
491 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 479 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
492 | long stack_ptr = kernel_stack_pointer(regs); | ||
493 | 480 | ||
494 | kcb->jprobe_saved_regs = *regs; | 481 | kcb->jprobe_saved_regs = *regs; |
495 | /* | 482 | /* |
496 | * As Linus pointed out, gcc assumes that the callee | 483 | * Since we can't be sure where in the stack frame "stacked" |
497 | * owns the argument space and could overwrite it, e.g. | 484 | * pass-by-value arguments are stored we just don't try to |
498 | * tailcall optimization. So, to be absolutely safe | 485 | * duplicate any of the stack. Do not use jprobes on functions that |
499 | * we also save and restore enough stack bytes to cover | 486 | * use more than 64 bytes (after padding each to an 8 byte boundary) |
500 | * the argument area. | 487 | * of arguments, or pass individual arguments larger than 16 bytes. |
501 | */ | 488 | */ |
502 | kasan_disable_current(); | ||
503 | memcpy(kcb->jprobes_stack, (void *)stack_ptr, | ||
504 | min_stack_size(stack_ptr)); | ||
505 | kasan_enable_current(); | ||
506 | 489 | ||
507 | instruction_pointer_set(regs, (unsigned long) jp->entry); | 490 | instruction_pointer_set(regs, (unsigned long) jp->entry); |
508 | preempt_disable(); | 491 | preempt_disable(); |
@@ -554,10 +537,6 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | |||
554 | } | 537 | } |
555 | unpause_graph_tracing(); | 538 | unpause_graph_tracing(); |
556 | *regs = kcb->jprobe_saved_regs; | 539 | *regs = kcb->jprobe_saved_regs; |
557 | kasan_disable_current(); | ||
558 | memcpy((void *)stack_addr, kcb->jprobes_stack, | ||
559 | min_stack_size(stack_addr)); | ||
560 | kasan_enable_current(); | ||
561 | preempt_enable_no_resched(); | 540 | preempt_enable_no_resched(); |
562 | return 1; | 541 | return 1; |
563 | } | 542 | } |
diff --git a/arch/arm64/kernel/sleep.S b/arch/arm64/kernel/sleep.S index 9a3aec97ac09..ccf79d849e0a 100644 --- a/arch/arm64/kernel/sleep.S +++ b/arch/arm64/kernel/sleep.S | |||
@@ -101,12 +101,20 @@ ENTRY(cpu_resume) | |||
101 | bl el2_setup // if in EL2 drop to EL1 cleanly | 101 | bl el2_setup // if in EL2 drop to EL1 cleanly |
102 | /* enable the MMU early - so we can access sleep_save_stash by va */ | 102 | /* enable the MMU early - so we can access sleep_save_stash by va */ |
103 | adr_l lr, __enable_mmu /* __cpu_setup will return here */ | 103 | adr_l lr, __enable_mmu /* __cpu_setup will return here */ |
104 | ldr x27, =_cpu_resume /* __enable_mmu will branch here */ | 104 | adr_l x27, _resume_switched /* __enable_mmu will branch here */ |
105 | adrp x25, idmap_pg_dir | 105 | adrp x25, idmap_pg_dir |
106 | adrp x26, swapper_pg_dir | 106 | adrp x26, swapper_pg_dir |
107 | b __cpu_setup | 107 | b __cpu_setup |
108 | ENDPROC(cpu_resume) | 108 | ENDPROC(cpu_resume) |
109 | 109 | ||
110 | .pushsection ".idmap.text", "ax" | ||
111 | _resume_switched: | ||
112 | ldr x8, =_cpu_resume | ||
113 | br x8 | ||
114 | ENDPROC(_resume_switched) | ||
115 | .ltorg | ||
116 | .popsection | ||
117 | |||
110 | ENTRY(_cpu_resume) | 118 | ENTRY(_cpu_resume) |
111 | mrs x1, mpidr_el1 | 119 | mrs x1, mpidr_el1 |
112 | adrp x8, mpidr_hash | 120 | adrp x8, mpidr_hash |
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 76a6d9263908..d93d43352504 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c | |||
@@ -661,9 +661,9 @@ void __init smp_init_cpus(void) | |||
661 | acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT, | 661 | acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT, |
662 | acpi_parse_gic_cpu_interface, 0); | 662 | acpi_parse_gic_cpu_interface, 0); |
663 | 663 | ||
664 | if (cpu_count > NR_CPUS) | 664 | if (cpu_count > nr_cpu_ids) |
665 | pr_warn("no. of cores (%d) greater than configured maximum of %d - clipping\n", | 665 | pr_warn("Number of cores (%d) exceeds configured maximum of %d - clipping\n", |
666 | cpu_count, NR_CPUS); | 666 | cpu_count, nr_cpu_ids); |
667 | 667 | ||
668 | if (!bootcpu_valid) { | 668 | if (!bootcpu_valid) { |
669 | pr_err("missing boot CPU MPIDR, not enabling secondaries\n"); | 669 | pr_err("missing boot CPU MPIDR, not enabling secondaries\n"); |
@@ -677,7 +677,7 @@ void __init smp_init_cpus(void) | |||
677 | * with entries in cpu_logical_map while initializing the cpus. | 677 | * with entries in cpu_logical_map while initializing the cpus. |
678 | * If the cpu set-up fails, invalidate the cpu_logical_map entry. | 678 | * If the cpu set-up fails, invalidate the cpu_logical_map entry. |
679 | */ | 679 | */ |
680 | for (i = 1; i < NR_CPUS; i++) { | 680 | for (i = 1; i < nr_cpu_ids; i++) { |
681 | if (cpu_logical_map(i) != INVALID_HWID) { | 681 | if (cpu_logical_map(i) != INVALID_HWID) { |
682 | if (smp_cpu_setup(i)) | 682 | if (smp_cpu_setup(i)) |
683 | cpu_logical_map(i) = INVALID_HWID; | 683 | cpu_logical_map(i) = INVALID_HWID; |