diff options
| -rw-r--r-- | arch/powerpc/include/asm/module.h | 4 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/page.h | 12 | ||||
| -rw-r--r-- | arch/powerpc/kernel/idle_book3s.S | 2 | ||||
| -rw-r--r-- | arch/powerpc/kernel/kprobes.c | 3 | ||||
| -rw-r--r-- | arch/powerpc/kernel/process.c | 19 | ||||
| -rw-r--r-- | arch/powerpc/mm/dump_linuxpagetables.c | 7 | ||||
| -rw-r--r-- | tools/testing/selftests/powerpc/tm/.gitignore | 1 | ||||
| -rw-r--r-- | tools/testing/selftests/powerpc/tm/Makefile | 4 | ||||
| -rw-r--r-- | tools/testing/selftests/powerpc/tm/tm-vmx-unavail.c | 118 |
9 files changed, 164 insertions, 6 deletions
diff --git a/arch/powerpc/include/asm/module.h b/arch/powerpc/include/asm/module.h index 53885512b8d3..6c0132c7212f 100644 --- a/arch/powerpc/include/asm/module.h +++ b/arch/powerpc/include/asm/module.h | |||
| @@ -14,6 +14,10 @@ | |||
| 14 | #include <asm-generic/module.h> | 14 | #include <asm-generic/module.h> |
| 15 | 15 | ||
| 16 | 16 | ||
| 17 | #ifdef CC_USING_MPROFILE_KERNEL | ||
| 18 | #define MODULE_ARCH_VERMAGIC "mprofile-kernel" | ||
| 19 | #endif | ||
| 20 | |||
| 17 | #ifndef __powerpc64__ | 21 | #ifndef __powerpc64__ |
| 18 | /* | 22 | /* |
| 19 | * Thanks to Paul M for explaining this. | 23 | * Thanks to Paul M for explaining this. |
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h index 2a32483c7b6c..8da5d4c1cab2 100644 --- a/arch/powerpc/include/asm/page.h +++ b/arch/powerpc/include/asm/page.h | |||
| @@ -132,7 +132,19 @@ extern long long virt_phys_offset; | |||
| 132 | #define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) | 132 | #define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) |
| 133 | #define virt_to_page(kaddr) pfn_to_page(virt_to_pfn(kaddr)) | 133 | #define virt_to_page(kaddr) pfn_to_page(virt_to_pfn(kaddr)) |
| 134 | #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) | 134 | #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) |
| 135 | |||
| 136 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
| 137 | /* | ||
| 138 | * On hash the vmalloc and other regions alias to the kernel region when passed | ||
| 139 | * through __pa(), which virt_to_pfn() uses. That means virt_addr_valid() can | ||
| 140 | * return true for some vmalloc addresses, which is incorrect. So explicitly | ||
| 141 | * check that the address is in the kernel region. | ||
| 142 | */ | ||
| 143 | #define virt_addr_valid(kaddr) (REGION_ID(kaddr) == KERNEL_REGION_ID && \ | ||
| 144 | pfn_valid(virt_to_pfn(kaddr))) | ||
| 145 | #else | ||
| 135 | #define virt_addr_valid(kaddr) pfn_valid(virt_to_pfn(kaddr)) | 146 | #define virt_addr_valid(kaddr) pfn_valid(virt_to_pfn(kaddr)) |
| 147 | #endif | ||
| 136 | 148 | ||
| 137 | /* | 149 | /* |
| 138 | * On Book-E parts we need __va to parse the device tree and we can't | 150 | * On Book-E parts we need __va to parse the device tree and we can't |
diff --git a/arch/powerpc/kernel/idle_book3s.S b/arch/powerpc/kernel/idle_book3s.S index 07d4e0ad60db..4898d676dcae 100644 --- a/arch/powerpc/kernel/idle_book3s.S +++ b/arch/powerpc/kernel/idle_book3s.S | |||
| @@ -416,7 +416,7 @@ power9_dd1_recover_paca: | |||
| 416 | * which needs to be restored from the stack. | 416 | * which needs to be restored from the stack. |
| 417 | */ | 417 | */ |
| 418 | li r3, 1 | 418 | li r3, 1 |
| 419 | stb r0,PACA_NAPSTATELOST(r13) | 419 | stb r3,PACA_NAPSTATELOST(r13) |
| 420 | blr | 420 | blr |
| 421 | 421 | ||
| 422 | /* | 422 | /* |
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index 160ae0fa7d0d..fc4343514bed 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c | |||
| @@ -305,16 +305,17 @@ int kprobe_handler(struct pt_regs *regs) | |||
| 305 | save_previous_kprobe(kcb); | 305 | save_previous_kprobe(kcb); |
| 306 | set_current_kprobe(p, regs, kcb); | 306 | set_current_kprobe(p, regs, kcb); |
| 307 | kprobes_inc_nmissed_count(p); | 307 | kprobes_inc_nmissed_count(p); |
| 308 | prepare_singlestep(p, regs); | ||
| 309 | kcb->kprobe_status = KPROBE_REENTER; | 308 | kcb->kprobe_status = KPROBE_REENTER; |
| 310 | if (p->ainsn.boostable >= 0) { | 309 | if (p->ainsn.boostable >= 0) { |
| 311 | ret = try_to_emulate(p, regs); | 310 | ret = try_to_emulate(p, regs); |
| 312 | 311 | ||
| 313 | if (ret > 0) { | 312 | if (ret > 0) { |
| 314 | restore_previous_kprobe(kcb); | 313 | restore_previous_kprobe(kcb); |
| 314 | preempt_enable_no_resched(); | ||
| 315 | return 1; | 315 | return 1; |
| 316 | } | 316 | } |
| 317 | } | 317 | } |
| 318 | prepare_singlestep(p, regs); | ||
| 318 | return 1; | 319 | return 1; |
| 319 | } else { | 320 | } else { |
| 320 | if (*addr != BREAKPOINT_INSTRUCTION) { | 321 | if (*addr != BREAKPOINT_INSTRUCTION) { |
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index d645da302bf2..baae104b16c7 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
| @@ -864,6 +864,25 @@ static void tm_reclaim_thread(struct thread_struct *thr, | |||
| 864 | if (!MSR_TM_SUSPENDED(mfmsr())) | 864 | if (!MSR_TM_SUSPENDED(mfmsr())) |
| 865 | return; | 865 | return; |
| 866 | 866 | ||
| 867 | /* | ||
| 868 | * If we are in a transaction and FP is off then we can't have | ||
| 869 | * used FP inside that transaction. Hence the checkpointed | ||
| 870 | * state is the same as the live state. We need to copy the | ||
| 871 | * live state to the checkpointed state so that when the | ||
| 872 | * transaction is restored, the checkpointed state is correct | ||
| 873 | * and the aborted transaction sees the correct state. We use | ||
| 874 | * ckpt_regs.msr here as that's what tm_reclaim will use to | ||
| 875 | * determine if it's going to write the checkpointed state or | ||
| 876 | * not. So either this will write the checkpointed registers, | ||
| 877 | * or reclaim will. Similarly for VMX. | ||
| 878 | */ | ||
| 879 | if ((thr->ckpt_regs.msr & MSR_FP) == 0) | ||
| 880 | memcpy(&thr->ckfp_state, &thr->fp_state, | ||
| 881 | sizeof(struct thread_fp_state)); | ||
| 882 | if ((thr->ckpt_regs.msr & MSR_VEC) == 0) | ||
| 883 | memcpy(&thr->ckvr_state, &thr->vr_state, | ||
| 884 | sizeof(struct thread_vr_state)); | ||
| 885 | |||
| 867 | giveup_all(container_of(thr, struct task_struct, thread)); | 886 | giveup_all(container_of(thr, struct task_struct, thread)); |
| 868 | 887 | ||
| 869 | tm_reclaim(thr, thr->ckpt_regs.msr, cause); | 888 | tm_reclaim(thr, thr->ckpt_regs.msr, cause); |
diff --git a/arch/powerpc/mm/dump_linuxpagetables.c b/arch/powerpc/mm/dump_linuxpagetables.c index d659345a98d6..44fe4833910f 100644 --- a/arch/powerpc/mm/dump_linuxpagetables.c +++ b/arch/powerpc/mm/dump_linuxpagetables.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | */ | 16 | */ |
| 17 | #include <linux/debugfs.h> | 17 | #include <linux/debugfs.h> |
| 18 | #include <linux/fs.h> | 18 | #include <linux/fs.h> |
| 19 | #include <linux/hugetlb.h> | ||
| 19 | #include <linux/io.h> | 20 | #include <linux/io.h> |
| 20 | #include <linux/mm.h> | 21 | #include <linux/mm.h> |
| 21 | #include <linux/sched.h> | 22 | #include <linux/sched.h> |
| @@ -391,7 +392,7 @@ static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start) | |||
| 391 | 392 | ||
| 392 | for (i = 0; i < PTRS_PER_PMD; i++, pmd++) { | 393 | for (i = 0; i < PTRS_PER_PMD; i++, pmd++) { |
| 393 | addr = start + i * PMD_SIZE; | 394 | addr = start + i * PMD_SIZE; |
| 394 | if (!pmd_none(*pmd)) | 395 | if (!pmd_none(*pmd) && !pmd_huge(*pmd)) |
| 395 | /* pmd exists */ | 396 | /* pmd exists */ |
| 396 | walk_pte(st, pmd, addr); | 397 | walk_pte(st, pmd, addr); |
| 397 | else | 398 | else |
| @@ -407,7 +408,7 @@ static void walk_pud(struct pg_state *st, pgd_t *pgd, unsigned long start) | |||
| 407 | 408 | ||
| 408 | for (i = 0; i < PTRS_PER_PUD; i++, pud++) { | 409 | for (i = 0; i < PTRS_PER_PUD; i++, pud++) { |
| 409 | addr = start + i * PUD_SIZE; | 410 | addr = start + i * PUD_SIZE; |
| 410 | if (!pud_none(*pud)) | 411 | if (!pud_none(*pud) && !pud_huge(*pud)) |
| 411 | /* pud exists */ | 412 | /* pud exists */ |
| 412 | walk_pmd(st, pud, addr); | 413 | walk_pmd(st, pud, addr); |
| 413 | else | 414 | else |
| @@ -427,7 +428,7 @@ static void walk_pagetables(struct pg_state *st) | |||
| 427 | */ | 428 | */ |
| 428 | for (i = 0; i < PTRS_PER_PGD; i++, pgd++) { | 429 | for (i = 0; i < PTRS_PER_PGD; i++, pgd++) { |
| 429 | addr = KERN_VIRT_START + i * PGDIR_SIZE; | 430 | addr = KERN_VIRT_START + i * PGDIR_SIZE; |
| 430 | if (!pgd_none(*pgd)) | 431 | if (!pgd_none(*pgd) && !pgd_huge(*pgd)) |
| 431 | /* pgd exists */ | 432 | /* pgd exists */ |
| 432 | walk_pud(st, pgd, addr); | 433 | walk_pud(st, pgd, addr); |
| 433 | else | 434 | else |
diff --git a/tools/testing/selftests/powerpc/tm/.gitignore b/tools/testing/selftests/powerpc/tm/.gitignore index 427621792229..2f1f7b013293 100644 --- a/tools/testing/selftests/powerpc/tm/.gitignore +++ b/tools/testing/selftests/powerpc/tm/.gitignore | |||
| @@ -11,3 +11,4 @@ tm-signal-context-chk-fpu | |||
| 11 | tm-signal-context-chk-gpr | 11 | tm-signal-context-chk-gpr |
| 12 | tm-signal-context-chk-vmx | 12 | tm-signal-context-chk-vmx |
| 13 | tm-signal-context-chk-vsx | 13 | tm-signal-context-chk-vsx |
| 14 | tm-vmx-unavail | ||
diff --git a/tools/testing/selftests/powerpc/tm/Makefile b/tools/testing/selftests/powerpc/tm/Makefile index 5576ee6a51f2..958c11c14acd 100644 --- a/tools/testing/selftests/powerpc/tm/Makefile +++ b/tools/testing/selftests/powerpc/tm/Makefile | |||
| @@ -2,7 +2,8 @@ SIGNAL_CONTEXT_CHK_TESTS := tm-signal-context-chk-gpr tm-signal-context-chk-fpu | |||
| 2 | tm-signal-context-chk-vmx tm-signal-context-chk-vsx | 2 | tm-signal-context-chk-vmx tm-signal-context-chk-vsx |
| 3 | 3 | ||
| 4 | TEST_GEN_PROGS := tm-resched-dscr tm-syscall tm-signal-msr-resv tm-signal-stack \ | 4 | TEST_GEN_PROGS := tm-resched-dscr tm-syscall tm-signal-msr-resv tm-signal-stack \ |
| 5 | tm-vmxcopy tm-fork tm-tar tm-tmspr $(SIGNAL_CONTEXT_CHK_TESTS) | 5 | tm-vmxcopy tm-fork tm-tar tm-tmspr tm-vmx-unavail \ |
| 6 | $(SIGNAL_CONTEXT_CHK_TESTS) | ||
| 6 | 7 | ||
| 7 | include ../../lib.mk | 8 | include ../../lib.mk |
| 8 | 9 | ||
| @@ -13,6 +14,7 @@ CFLAGS += -mhtm | |||
| 13 | $(OUTPUT)/tm-syscall: tm-syscall-asm.S | 14 | $(OUTPUT)/tm-syscall: tm-syscall-asm.S |
| 14 | $(OUTPUT)/tm-syscall: CFLAGS += -I../../../../../usr/include | 15 | $(OUTPUT)/tm-syscall: CFLAGS += -I../../../../../usr/include |
| 15 | $(OUTPUT)/tm-tmspr: CFLAGS += -pthread | 16 | $(OUTPUT)/tm-tmspr: CFLAGS += -pthread |
| 17 | $(OUTPUT)/tm-vmx-unavail: CFLAGS += -pthread -m64 | ||
| 16 | 18 | ||
