[PATCH 3/3] powerpc/sstep: Always test lmw and stmw

2021-02-24 Thread Jordan Niethe
Load Multiple Word (lmw) and Store Multiple Word (stmw) will raise an
Alignment Exception:
  - Little Endian mode: always
  - Big Endian mode: address not word aligned

These conditions do not depend on cache inhibited memory. Test the
alignment handler emulation of these instructions regardless of if there
is cache inhibited memory available or not.

Signed-off-by: Jordan Niethe 
---
 .../powerpc/alignment/alignment_handler.c | 96 ++-
 1 file changed, 94 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/powerpc/alignment/alignment_handler.c 
b/tools/testing/selftests/powerpc/alignment/alignment_handler.c
index f5eb5b85a2cf..c3003f95e043 100644
--- a/tools/testing/selftests/powerpc/alignment/alignment_handler.c
+++ b/tools/testing/selftests/powerpc/alignment/alignment_handler.c
@@ -45,6 +45,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "utils.h"
 #include "instructions.h"
@@ -434,7 +435,6 @@ int test_alignment_handler_integer(void)
LOAD_DFORM_TEST(ldu);
LOAD_XFORM_TEST(ldx);
LOAD_XFORM_TEST(ldux);
-   LOAD_DFORM_TEST(lmw);
STORE_DFORM_TEST(stb);
STORE_XFORM_TEST(stbx);
STORE_DFORM_TEST(stbu);
@@ -453,7 +453,6 @@ int test_alignment_handler_integer(void)
STORE_XFORM_TEST(stdx);
STORE_DFORM_TEST(stdu);
STORE_XFORM_TEST(stdux);
-   STORE_DFORM_TEST(stmw);
 
return rc;
 }
@@ -599,6 +598,97 @@ int test_alignment_handler_fp_prefix(void)
return rc;
 }
 
+int test_alignment_handler_multiple(void)
+{
+   int offset, width, r, rc = 0;
+   void *src1, *dst1, *src2, *dst2;
+
+   rc = posix_memalign(, bufsize, bufsize);
+   if (rc) {
+   printf("\n");
+   return rc;
+   }
+
+   rc = posix_memalign(, bufsize, bufsize);
+   if (rc) {
+   printf("\n");
+   free(src1);
+   return rc;
+   }
+
+   src2 = malloc(bufsize);
+   if (!src2) {
+   printf("\n");
+   free(src1);
+   free(dst1);
+   return -ENOMEM;
+   }
+
+   dst2 = malloc(bufsize);
+   if (!dst2) {
+   printf("\n");
+   free(src1);
+   free(dst1);
+   free(src2);
+   return -ENOMEM;
+   }
+
+   /* lmw */
+   width = 4;
+   printf("\tDoing lmw:\t");
+   for (offset = 0; offset < width; offset++) {
+   preload_data(src1, offset, width);
+   preload_data(src2, offset, width);
+
+   asm volatile("lmw  31, 0(%0) ; std 31, 0(%1)"
+:: "r"(src1 + offset), "r"(dst1 + offset), "r"(0)
+: "memory", "r31");
+
+   memcpy(dst2 + offset, src1 + offset, width);
+
+   r = test_memcmp(dst1, dst2, width, offset, "test_lmw");
+   if (r && !debug) {
+   printf("FAILED: Wrong Data\n");
+   break;
+   }
+   }
+
+   if (!r)
+   printf("PASSED\n");
+   else
+   rc |= 1;
+
+   /* stmw */
+   width = 4;
+   printf("\tDoing stmw:\t");
+   for (offset = 0; offset < width; offset++) {
+   preload_data(src1, offset, width);
+   preload_data(src2, offset, width);
+
+   asm volatile("ld  31, 0(%0) ; stmw 31, 0(%1)"
+:: "r"(src1 + offset), "r"(dst1 + offset), "r"(0)
+: "memory", "r31");
+
+   memcpy(dst2 + offset, src1 + offset, width);
+
+   r = test_memcmp(dst1, dst2, width, offset, "test_stmw");
+   if (r && !debug) {
+   printf("FAILED: Wrong Data\n");
+   break;
+   }
+   }
+   if (!r)
+   printf("PASSED\n");
+   else
+   rc |= 1;
+
+   free(src1);
+   free(src2);
+   free(dst1);
+   free(dst2);
+   return rc;
+}
+
 void usage(char *prog)
 {
printf("Usage: %s [options] [path [offset]]\n", prog);
@@ -673,5 +763,7 @@ int main(int argc, char *argv[])
   "test_alignment_handler_fp_206");
rc |= test_harness(test_alignment_handler_fp_prefix,
   "test_alignment_handler_fp_prefix");
+   rc |= test_harness(test_alignment_handler_multiple,
+  "test_alignment_handler_multiple");
return rc;
 }
-- 
2.25.1



[PATCH 2/3] selftests/powerpc: Suggest memtrace instead of /dev/mem for ci memory

2021-02-24 Thread Jordan Niethe
The suggested alternative for getting cache-inhibited memory with 'mem='
and /dev/mem is pretty hacky. Also, PAPR guests do not allow system
memory to be mapped cache-inhibited so despite /dev/mem being available
this will not work which can cause confusion.  Instead recommend using
the memtrace buffers. memtrace is only available on powernv so there
will not be any chance of trying to do this in a guest.

Signed-off-by: Jordan Niethe 
---
 .../selftests/powerpc/alignment/alignment_handler.c   | 11 +--
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/tools/testing/selftests/powerpc/alignment/alignment_handler.c 
b/tools/testing/selftests/powerpc/alignment/alignment_handler.c
index cb53a8b777e6..f5eb5b85a2cf 100644
--- a/tools/testing/selftests/powerpc/alignment/alignment_handler.c
+++ b/tools/testing/selftests/powerpc/alignment/alignment_handler.c
@@ -10,16 +10,7 @@
  *
  * We create two sets of source and destination buffers, one in regular memory,
  * the other cache-inhibited (by default we use /dev/fb0 for this, but an
- * alterative path for cache-inhibited memory may be provided).
- *
- * One way to get cache-inhibited memory is to use the "mem" kernel parameter
- * to limit the kernel to less memory than actually exists.  Addresses above
- * the limit may still be accessed but will be treated as cache-inhibited. For
- * example, if there is actually 4GB of memory and the parameter "mem=3GB" is
- * used, memory from address 0xC000 onwards is treated as cache-inhibited.
- * To access this region /dev/mem is used. The kernel should be configured
- * without CONFIG_STRICT_DEVMEM. In this case use:
- * ./alignment_handler /dev/mem 0xc000
+ * alterative path for cache-inhibited memory may be provided, e.g. memtrace).
  *
  * We initialise the source buffers, then use whichever set of load/store
  * instructions is under test to copy bytes from the source buffers to the
-- 
2.25.1



[PATCH 1/3] powernv/memtrace: Allow mmaping trace buffers

2021-02-24 Thread Jordan Niethe
Let the memory removed from the linear mapping to be used for the trace
buffers be mmaped. This is a useful way of providing cache-inhibited
memory for the alignment_handler selftest.

Signed-off-by: Jordan Niethe 
---
 arch/powerpc/platforms/powernv/memtrace.c | 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powernv/memtrace.c 
b/arch/powerpc/platforms/powernv/memtrace.c
index 5fc9408bb0b3..8a1df39305e9 100644
--- a/arch/powerpc/platforms/powernv/memtrace.c
+++ b/arch/powerpc/platforms/powernv/memtrace.c
@@ -45,10 +45,26 @@ static ssize_t memtrace_read(struct file *filp, char __user 
*ubuf,
return simple_read_from_buffer(ubuf, count, ppos, ent->mem, ent->size);
 }
 
+int memtrace_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+   struct memtrace_entry *ent = filp->private_data;
+
+   if (ent->size < vma->vm_end - vma->vm_start)
+   return -EINVAL;
+
+   if (vma->vm_pgoff << PAGE_SHIFT >= ent->size)
+   return -EINVAL;
+
+   vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+   return remap_pfn_range(vma, vma->vm_start, PHYS_PFN(ent->start) + 
vma->vm_pgoff,
+  vma->vm_end - vma->vm_start, vma->vm_page_prot);
+}
+
 static const struct file_operations memtrace_fops = {
.llseek = default_llseek,
.read   = memtrace_read,
.open   = simple_open,
+   .mmap   = memtrace_mmap,
 };
 
 static void memtrace_clear_range(unsigned long start_pfn,
@@ -158,7 +174,7 @@ static int memtrace_init_debugfs(void)
dir = debugfs_create_dir(ent->name, memtrace_debugfs_dir);
 
ent->dir = dir;
-   debugfs_create_file("trace", 0400, dir, ent, _fops);
+   debugfs_create_file_unsafe("trace", 0600, dir, ent, 
_fops);
debugfs_create_x64("start", 0400, dir, >start);
debugfs_create_x64("size", 0400, dir, >size);
}
-- 
2.25.1



[PATCH] powerpc/sstep: Fix VSX instruction emulation

2021-02-24 Thread Jordan Niethe
Commit af99da74333b ("powerpc/sstep: Support VSX vector paired storage
access instructions") added loading and storing 32 word long data into
adjacent VSRs. However the calculation used to determine if two VSRs
needed to be loaded/stored inadvertently prevented the load/storing
taking place for instructions with a data length less than 16 words.

This causes the emulation to not function correctly, which can be seen
by the alignment_handler selftest:

$ ./alignment_handler
[snip]
test: test_alignment_handler_vsx_207
tags: git_version:powerpc-5.12-1-0-g82d2c16b350f
VSX: 2.07B
Doing lxsspx:   PASSED
Doing lxsiwax:  FAILED: Wrong Data
Doing lxsiwzx:  PASSED
Doing stxsspx:  PASSED
Doing stxsiwx:  PASSED
failure: test_alignment_handler_vsx_207
test: test_alignment_handler_vsx_300
tags: git_version:powerpc-5.12-1-0-g82d2c16b350f
VSX: 3.00B
Doing lxsd: PASSED
Doing lxsibzx:  PASSED
Doing lxsihzx:  PASSED
Doing lxssp:FAILED: Wrong Data
Doing lxv:  PASSED
Doing lxvb16x:  PASSED
Doing lxvh8x:   PASSED
Doing lxvx: PASSED
Doing lxvwsx:   FAILED: Wrong Data
Doing lxvl: PASSED
Doing lxvll:PASSED
Doing stxsd:PASSED
Doing stxsibx:  PASSED
Doing stxsihx:  PASSED
Doing stxssp:   PASSED
Doing stxv: PASSED
Doing stxvb16x: PASSED
Doing stxvh8x:  PASSED
Doing stxvx:PASSED
Doing stxvl:PASSED
Doing stxvll:   PASSED
failure: test_alignment_handler_vsx_300
[snip]

Fix this by making sure all VSX instruction emulation correctly
load/store from the VSRs.

Fixes: af99da74333b ("powerpc/sstep: Support VSX vector paired storage access 
instructions")
Signed-off-by: Jordan Niethe 
---
 arch/powerpc/lib/sstep.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 683f7c20f74b..3953e63bbba5 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -902,7 +902,7 @@ static nokprobe_inline int do_vsx_load(struct 
instruction_op *op,
if (!address_ok(regs, ea, size) || copy_mem_in(mem, ea, size, regs))
return -EFAULT;
 
-   nr_vsx_regs = size / sizeof(__vector128);
+   nr_vsx_regs = max(1ul, size / sizeof(__vector128));
emulate_vsx_load(op, buf, mem, cross_endian);
preempt_disable();
if (reg < 32) {
@@ -949,7 +949,7 @@ static nokprobe_inline int do_vsx_store(struct 
instruction_op *op,
if (!address_ok(regs, ea, size))
return -EFAULT;
 
-   nr_vsx_regs = size / sizeof(__vector128);
+   nr_vsx_regs = max(1ul, size / sizeof(__vector128));
preempt_disable();
if (reg < 32) {
/* FP regs + extensions */
-- 
2.25.1



[PATCH v3 2/2] selftests/powerpc: Test for spurious kernel memory faults on radix

2021-02-07 Thread Jordan Niethe
Previously when mapping kernel memory on radix, no ptesync was included
which would periodically lead to unhandled spurious faults. Mapping
kernel memory is used when code patching with Strict RWX enabled.  As
suggested by Chris Riedl, turning ftrace on and off does a large amount
of code patching so is a convenient way to see this kind of fault.

Add a selftest to try and trigger this kind of a spurious fault. It
tests for 30 seconds which is usually long enough for the issue to show
up.

Signed-off-by: Jordan Niethe 
---
v3: New to series
---
 tools/testing/selftests/powerpc/mm/Makefile   |  1 +
 .../selftests/powerpc/mm/spurious_fault.sh| 49 +++
 2 files changed, 50 insertions(+)
 create mode 100755 tools/testing/selftests/powerpc/mm/spurious_fault.sh

diff --git a/tools/testing/selftests/powerpc/mm/Makefile 
b/tools/testing/selftests/powerpc/mm/Makefile
index defe488d6bf1..56c2896bed53 100644
--- a/tools/testing/selftests/powerpc/mm/Makefile
+++ b/tools/testing/selftests/powerpc/mm/Makefile
@@ -5,6 +5,7 @@ noarg:
 TEST_GEN_PROGS := hugetlb_vs_thp_test subpage_prot prot_sao segv_errors 
wild_bctr \
  large_vm_fork_separation bad_accesses pkey_exec_prot \
  pkey_siginfo stack_expansion_signal stack_expansion_ldst
+TEST_PROGS := spurious_fault.sh
 
 TEST_GEN_PROGS_EXTENDED := tlbie_test
 TEST_GEN_FILES := tempfile
diff --git a/tools/testing/selftests/powerpc/mm/spurious_fault.sh 
b/tools/testing/selftests/powerpc/mm/spurious_fault.sh
new file mode 100755
index ..e454509659f6
--- /dev/null
+++ b/tools/testing/selftests/powerpc/mm/spurious_fault.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+TIMEOUT=30
+
+DEBUFS_DIR=`cat /proc/mounts | grep debugfs | awk '{print $2}'`
+if [ ! -e "$DEBUFS_DIR" ]
+then
+   echo "debugfs not found, skipping" 1>&2
+   exit 4
+fi
+
+if [ ! -e "$DEBUFS_DIR/tracing/current_tracer" ]
+then
+   echo "Tracing files not found, skipping" 1>&2
+   exit 4
+fi
+
+
+echo "Testing for spurious faults when mapping kernel memory..."
+
+if grep -q "FUNCTION TRACING IS CORRUPTED" "$DEBUFS_DIR/tracing/trace"
+then
+   echo "FAILED: Ftrace already dead. Probably due to a spurious fault" 
1>&2
+   exit 1
+fi
+
+dmesg -C
+START_TIME=`date +%s`
+END_TIME=`expr $START_TIME + $TIMEOUT`
+while [ `date +%s` -lt $END_TIME ]
+do
+   echo function > $DEBUFS_DIR/tracing/current_tracer
+   echo nop > $DEBUFS_DIR/tracing/current_tracer
+   if dmesg | grep -q 'ftrace bug'
+   then
+   break
+   fi
+done
+
+echo nop > $DEBUFS_DIR/tracing/current_tracer
+if dmesg | grep -q 'ftrace bug'
+then
+   echo "FAILED: Mapping kernel memory causes spurious faults" 1>&2
+   exit 1
+else
+   echo "OK: Mapping kernel memory does not cause spurious faults"
+   exit 0
+fi
-- 
2.25.1



[PATCH v3 1/2] powerpc/64s: Fix pte update for kernel memory on radix

2021-02-07 Thread Jordan Niethe
+0x44/0xc0
[  146.669451][  T809] [c4c8bb00] [c024dc88] 
ftrace_startup+0xf8/0x1c0
[  146.669461][  T809] [c4c8bb40] [c024dd9c] 
register_ftrace_function+0x4c/0xc0
[  146.669472][  T809] [c4c8bb70] [c026e750] 
function_trace_init+0x80/0xb0
[  146.669484][  T809] [c4c8bba0] [c0266b84] 
tracing_set_tracer+0x2a4/0x4f0
[  146.669495][  T809] [c4c8bc70] [c0266ea4] 
tracing_set_trace_write+0xd4/0x130
[  146.669506][  T809] [c4c8bd20] [c0422790] 
vfs_write+0xf0/0x330
[  146.669518][  T809] [c4c8bd70] [c0422bb4] 
ksys_write+0x84/0x140
[  146.669529][  T809] [c4c8bdc0] [c003499c] 
system_call_exception+0x14c/0x230
[  146.669540][  T809] [c4c8be20] [c000d860] 
system_call_common+0xf0/0x27c
[  146.669549][  T809] Instruction dump:
[  146.669558][  T809] 4814 3c62fe88 38631718 4bf5a941 6000 7fc3f378 
4bff877d 7c641b78
[  146.669598][  T809] 3c62fe88 38631730 4bf5a925 6000 <0fe0> 38210090 
3d22fd90 3901
[  146.669638][  T809] ---[ end trace 5ea7076ea28c0fbd ]---

To fix this when updating kernel memory ptes using ptesync.

Fixes: f1cb8f9beba8 ("powerpc/64s/radix: avoid ptesync after set_pte and 
ptep_set_access_flags")
Reviewed-by: Nicholas Piggin 
Signed-off-by: Jordan Niethe 
---
v2: Only ptesync is needed
v3: Fix Fixes tag
---
 arch/powerpc/include/asm/book3s/64/radix.h | 6 --
 arch/powerpc/mm/book3s64/radix_pgtable.c   | 4 ++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/64/radix.h 
b/arch/powerpc/include/asm/book3s/64/radix.h
index c7813dc628fc..59cab558e2f0 100644
--- a/arch/powerpc/include/asm/book3s/64/radix.h
+++ b/arch/powerpc/include/asm/book3s/64/radix.h
@@ -222,8 +222,10 @@ static inline void radix__set_pte_at(struct mm_struct *mm, 
unsigned long addr,
 * from ptesync, it should probably go into update_mmu_cache, rather
 * than set_pte_at (which is used to set ptes unrelated to faults).
 *
-* Spurious faults to vmalloc region are not tolerated, so there is
-* a ptesync in flush_cache_vmap.
+* Spurious faults from the kernel memory are not tolerated, so there
+* is a ptesync in flush_cache_vmap, and __map_kernel_page() follows
+* the pte update sequence from ISA Book III 6.10 Translation Table
+* Update Synchronization Requirements.
 */
 }
 
diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c 
b/arch/powerpc/mm/book3s64/radix_pgtable.c
index 3adcf730f478..1d5eec847b88 100644
--- a/arch/powerpc/mm/book3s64/radix_pgtable.c
+++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
@@ -108,7 +108,7 @@ static int early_map_kernel_page(unsigned long ea, unsigned 
long pa,
 
 set_the_pte:
set_pte_at(_mm, ea, ptep, pfn_pte(pfn, flags));
-   smp_wmb();
+   asm volatile("ptesync": : :"memory");
return 0;
 }
 
@@ -168,7 +168,7 @@ static int __map_kernel_page(unsigned long ea, unsigned 
long pa,
 
 set_the_pte:
set_pte_at(_mm, ea, ptep, pfn_pte(pfn, flags));
-   smp_wmb();
+   asm volatile("ptesync": : :"memory");
return 0;
 }
 
-- 
2.25.1



Re: [PATCH v2] powerpc/64s: Fix pte update for kernel memory on radix

2021-02-03 Thread Jordan Niethe
000
> > [  146.669208][  T809] GPR16: 23ec37c5  
> >  0008
> > [  146.669208][  T809] GPR20: c4c8bc90 c27a2d20 
> > c4c8bcd0 c2612fe8
> > [  146.669208][  T809] GPR24: 0038 0030 
> > 0028 0020
> > [  146.669208][  T809] GPR28: c0ff1b68 c0bf8e5c 
> > c312f700 c0fbb9b0
> > [  146.669384][  T809] NIP [c024f334] ftrace_bug+0x28c/0x2e8
> > [  146.669391][  T809] LR [c024f330] ftrace_bug+0x288/0x2e8
> > [  146.669396][  T809] Call Trace:
> > [  146.669403][  T809] [c4c8b9f0] [c024f330] 
> > ftrace_bug+0x288/0x2e8 (unreliable)
> > [  146.669418][  T809] [c4c8ba80] [c0248778] 
> > ftrace_modify_all_code+0x168/0x210
> > [  146.669429][  T809] [c4c8bab0] [c006c528] 
> > arch_ftrace_update_code+0x18/0x30
> > [  146.669440][  T809] [c4c8bad0] [c0248954] 
> > ftrace_run_update_code+0x44/0xc0
> > [  146.669451][  T809] [c4c8bb00] [c024dc88] 
> > ftrace_startup+0xf8/0x1c0
> > [  146.669461][  T809] [c4c8bb40] [c024dd9c] 
> > register_ftrace_function+0x4c/0xc0
> > [  146.669472][  T809] [c4c8bb70] [c026e750] 
> > function_trace_init+0x80/0xb0
> > [  146.669484][  T809] [c4c8bba0] [c0266b84] 
> > tracing_set_tracer+0x2a4/0x4f0
> > [  146.669495][  T809] [c4c8bc70] [c0266ea4] 
> > tracing_set_trace_write+0xd4/0x130
> > [  146.669506][  T809] [c4c8bd20] [c0422790] 
> > vfs_write+0xf0/0x330
> > [  146.669518][  T809] [c4c8bd70] [c0422bb4] 
> > ksys_write+0x84/0x140
> > [  146.669529][  T809] [c4c8bdc0] [c003499c] 
> > system_call_exception+0x14c/0x230
> > [  146.669540][  T809] [c4c8be20] [c000d860] 
> > system_call_common+0xf0/0x27c
> > [  146.669549][  T809] Instruction dump:
> > [  146.669558][  T809] 4814 3c62fe88 38631718 4bf5a941 6000 
> > 7fc3f378 4bff877d 7c641b78
> > [  146.669598][  T809] 3c62fe88 38631730 4bf5a925 6000 <0fe0> 
> > 38210090 3d22fd90 3901
> > [  146.669638][  T809] ---[ end trace 5ea7076ea28c0fbd ]---
> >
> > To fix this when updating kernel memory ptes using ptesync.
> >
> > Fixes: 37bc3e5fd764 ("powerpc/lib/code-patching: Use alternate map for 
> > patch_instruction()")
> > Fixes: f1cb8f9beba8 ("powerpc/64s/radix: avoid ptesync after set_pte and 
> > ptep_set_access_flags")
> > Signed-off-by: Jordan Niethe 
>
> Good catch. I would say it just fixes the latter patch doesn't it? The
> previous one just happens to break because it's using the broken API?
Yes that is true. I will send another revision that removes that from
the 'Fixes' and also add a self test.
>
> Anyhow,
>
> Reviewed-by: Nicholas Piggin 
>
> > ---
> > v2: Only ptesync is needed
> > ---
> >  arch/powerpc/include/asm/book3s/64/radix.h | 6 --
> >  arch/powerpc/mm/book3s64/radix_pgtable.c   | 4 ++--
> >  2 files changed, 6 insertions(+), 4 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/book3s/64/radix.h 
> > b/arch/powerpc/include/asm/book3s/64/radix.h
> > index c7813dc628fc..59cab558e2f0 100644
> > --- a/arch/powerpc/include/asm/book3s/64/radix.h
> > +++ b/arch/powerpc/include/asm/book3s/64/radix.h
> > @@ -222,8 +222,10 @@ static inline void radix__set_pte_at(struct mm_struct 
> > *mm, unsigned long addr,
> >* from ptesync, it should probably go into update_mmu_cache, rather
> >* than set_pte_at (which is used to set ptes unrelated to faults).
> >*
> > -  * Spurious faults to vmalloc region are not tolerated, so there is
> > -  * a ptesync in flush_cache_vmap.
> > +  * Spurious faults from the kernel memory are not tolerated, so there
> > +  * is a ptesync in flush_cache_vmap, and __map_kernel_page() follows
> > +  * the pte update sequence from ISA Book III 6.10 Translation Table
> > +  * Update Synchronization Requirements.
> >*/
> >  }
> >
> > diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c 
> > b/arch/powerpc/mm/book3s64/radix_pgtable.c
> > index 3adcf730f478..1d5eec847b88 100644
> > --- a/arch/powerpc/mm/book3s64/radix_pgtable.c
> > +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
> > @@ -108,7 +108,7 @@ static int early_map_kernel_page(unsigned long ea, 
> > unsigned long pa,
> >
> >  set_the_pte:
> >   set_pte_at(_mm, ea, ptep, pfn_pte(pfn, flags));
> > - smp_wmb();
> > + asm volatile("ptesync": : :"memory");
> >   return 0;
> >  }
> >
> > @@ -168,7 +168,7 @@ static int __map_kernel_page(unsigned long ea, unsigned 
> > long pa,
> >
> >  set_the_pte:
> >   set_pte_at(_mm, ea, ptep, pfn_pte(pfn, flags));
> > - smp_wmb();
> > + asm volatile("ptesync": : :"memory");
> >   return 0;
> >  }
> >
> > --
> > 2.25.1
> >
> >


[PATCH v2] powerpc/64s: Fix pte update for kernel memory on radix

2021-02-03 Thread Jordan Niethe
+0x44/0xc0
[  146.669451][  T809] [c4c8bb00] [c024dc88] 
ftrace_startup+0xf8/0x1c0
[  146.669461][  T809] [c4c8bb40] [c024dd9c] 
register_ftrace_function+0x4c/0xc0
[  146.669472][  T809] [c4c8bb70] [c026e750] 
function_trace_init+0x80/0xb0
[  146.669484][  T809] [c4c8bba0] [c0266b84] 
tracing_set_tracer+0x2a4/0x4f0
[  146.669495][  T809] [c4c8bc70] [c0266ea4] 
tracing_set_trace_write+0xd4/0x130
[  146.669506][  T809] [c4c8bd20] [c0422790] 
vfs_write+0xf0/0x330
[  146.669518][  T809] [c4c8bd70] [c0422bb4] 
ksys_write+0x84/0x140
[  146.669529][  T809] [c4c8bdc0] [c003499c] 
system_call_exception+0x14c/0x230
[  146.669540][  T809] [c4c8be20] [c000d860] 
system_call_common+0xf0/0x27c
[  146.669549][  T809] Instruction dump:
[  146.669558][  T809] 4814 3c62fe88 38631718 4bf5a941 6000 7fc3f378 
4bff877d 7c641b78
[  146.669598][  T809] 3c62fe88 38631730 4bf5a925 6000 <0fe0> 38210090 
3d22fd90 3901
[  146.669638][  T809] ---[ end trace 5ea7076ea28c0fbd ]---

To fix this when updating kernel memory ptes using ptesync.

Fixes: 37bc3e5fd764 ("powerpc/lib/code-patching: Use alternate map for 
patch_instruction()")
Fixes: f1cb8f9beba8 ("powerpc/64s/radix: avoid ptesync after set_pte and 
ptep_set_access_flags")
Signed-off-by: Jordan Niethe 
---
v2: Only ptesync is needed
---
 arch/powerpc/include/asm/book3s/64/radix.h | 6 --
 arch/powerpc/mm/book3s64/radix_pgtable.c   | 4 ++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/64/radix.h 
b/arch/powerpc/include/asm/book3s/64/radix.h
index c7813dc628fc..59cab558e2f0 100644
--- a/arch/powerpc/include/asm/book3s/64/radix.h
+++ b/arch/powerpc/include/asm/book3s/64/radix.h
@@ -222,8 +222,10 @@ static inline void radix__set_pte_at(struct mm_struct *mm, 
unsigned long addr,
 * from ptesync, it should probably go into update_mmu_cache, rather
 * than set_pte_at (which is used to set ptes unrelated to faults).
 *
-* Spurious faults to vmalloc region are not tolerated, so there is
-* a ptesync in flush_cache_vmap.
+* Spurious faults from the kernel memory are not tolerated, so there
+* is a ptesync in flush_cache_vmap, and __map_kernel_page() follows
+* the pte update sequence from ISA Book III 6.10 Translation Table
+* Update Synchronization Requirements.
 */
 }
 
diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c 
b/arch/powerpc/mm/book3s64/radix_pgtable.c
index 3adcf730f478..1d5eec847b88 100644
--- a/arch/powerpc/mm/book3s64/radix_pgtable.c
+++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
@@ -108,7 +108,7 @@ static int early_map_kernel_page(unsigned long ea, unsigned 
long pa,
 
 set_the_pte:
set_pte_at(_mm, ea, ptep, pfn_pte(pfn, flags));
-   smp_wmb();
+   asm volatile("ptesync": : :"memory");
return 0;
 }
 
@@ -168,7 +168,7 @@ static int __map_kernel_page(unsigned long ea, unsigned 
long pa,
 
 set_the_pte:
set_pte_at(_mm, ea, ptep, pfn_pte(pfn, flags));
-   smp_wmb();
+   asm volatile("ptesync": : :"memory");
return 0;
 }
 
-- 
2.25.1



[PATCH 2/2] Revert "powerpc/64s: Disable STRICT_KERNEL_RWX"

2021-02-02 Thread Jordan Niethe
This reverts commit 8659a0e0efdd975c73355dbc033f79ba3b31e82c.

Signed-off-by: Jordan Niethe 
---
 arch/powerpc/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 294108e0e5c6..a7113ee85994 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -135,7 +135,7 @@ config PPC
select ARCH_HAS_MEMBARRIER_CALLBACKS
select ARCH_HAS_MEMBARRIER_SYNC_CORE
select ARCH_HAS_SCALED_CPUTIME  if VIRT_CPU_ACCOUNTING_NATIVE 
&& PPC_BOOK3S_64
-   select ARCH_HAS_STRICT_KERNEL_RWX   if (PPC32 && !HIBERNATION)
+   select ARCH_HAS_STRICT_KERNEL_RWX   if ((PPC_BOOK3S_64 || PPC32) && 
!HIBERNATION)
select ARCH_HAS_TICK_BROADCAST  if GENERIC_CLOCKEVENTS_BROADCAST
select ARCH_HAS_UACCESS_FLUSHCACHE
select ARCH_HAS_COPY_MC if PPC64
-- 
2.25.1



[PATCH 1/2] powerpc/64s: Fix pte update for kernel memory on radix

2021-02-02 Thread Jordan Niethe
0004c8bab0] [c006c528] 
arch_ftrace_update_code+0x18/0x30
[  146.669440][  T809] [c4c8bad0] [c0248954] 
ftrace_run_update_code+0x44/0xc0
[  146.669451][  T809] [c4c8bb00] [c024dc88] 
ftrace_startup+0xf8/0x1c0
[  146.669461][  T809] [c4c8bb40] [c024dd9c] 
register_ftrace_function+0x4c/0xc0
[  146.669472][  T809] [c4c8bb70] [c026e750] 
function_trace_init+0x80/0xb0
[  146.669484][  T809] [c4c8bba0] [c0266b84] 
tracing_set_tracer+0x2a4/0x4f0
[  146.669495][  T809] [c4c8bc70] [c0266ea4] 
tracing_set_trace_write+0xd4/0x130
[  146.669506][  T809] [c4c8bd20] [c0422790] 
vfs_write+0xf0/0x330
[  146.669518][  T809] [c4c8bd70] [c0422bb4] 
ksys_write+0x84/0x140
[  146.669529][  T809] [c4c8bdc0] [c003499c] 
system_call_exception+0x14c/0x230
[  146.669540][  T809] [c4c8be20] [c000d860] 
system_call_common+0xf0/0x27c
[  146.669549][  T809] Instruction dump:
[  146.669558][  T809] 4814 3c62fe88 38631718 4bf5a941 6000 7fc3f378 
4bff877d 7c641b78
[  146.669598][  T809] 3c62fe88 38631730 4bf5a925 6000 <0fe0> 38210090 
3d22fd90 3901
[  146.669638][  T809] ---[ end trace 5ea7076ea28c0fbd ]---

To fix this when updating kernel memory ptes, follow the ISA recommended 
sequence.

Fixes: 37bc3e5fd764 ("powerpc/lib/code-patching: Use alternate map for 
patch_instruction()")
Fixes: f1cb8f9beba8 ("powerpc/64s/radix: avoid ptesync after set_pte and 
ptep_set_access_flags")
Signed-off-by: Jordan Niethe 
---
 arch/powerpc/include/asm/book3s/64/radix.h | 6 --
 arch/powerpc/mm/book3s64/radix_pgtable.c   | 4 ++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/64/radix.h 
b/arch/powerpc/include/asm/book3s/64/radix.h
index c7813dc628fc..59cab558e2f0 100644
--- a/arch/powerpc/include/asm/book3s/64/radix.h
+++ b/arch/powerpc/include/asm/book3s/64/radix.h
@@ -222,8 +222,10 @@ static inline void radix__set_pte_at(struct mm_struct *mm, 
unsigned long addr,
 * from ptesync, it should probably go into update_mmu_cache, rather
 * than set_pte_at (which is used to set ptes unrelated to faults).
 *
-* Spurious faults to vmalloc region are not tolerated, so there is
-* a ptesync in flush_cache_vmap.
+* Spurious faults from the kernel memory are not tolerated, so there
+* is a ptesync in flush_cache_vmap, and __map_kernel_page() follows
+* the pte update sequence from ISA Book III 6.10 Translation Table
+* Update Synchronization Requirements.
 */
 }
 
diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c 
b/arch/powerpc/mm/book3s64/radix_pgtable.c
index 3adcf730f478..001e2350bc51 100644
--- a/arch/powerpc/mm/book3s64/radix_pgtable.c
+++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
@@ -108,7 +108,7 @@ static int early_map_kernel_page(unsigned long ea, unsigned 
long pa,
 
 set_the_pte:
set_pte_at(_mm, ea, ptep, pfn_pte(pfn, flags));
-   smp_wmb();
+   asm volatile("eieio; tlbsync; ptesync": : :"memory");
return 0;
 }
 
@@ -168,7 +168,7 @@ static int __map_kernel_page(unsigned long ea, unsigned 
long pa,
 
 set_the_pte:
set_pte_at(_mm, ea, ptep, pfn_pte(pfn, flags));
-   smp_wmb();
+   asm volatile("eieio; tlbsync; ptesync": : :"memory");
return 0;
 }
 
-- 
2.25.1



[PATCH 2/2] powerpc/powernv/idle: Restore CIABR after idle for Power9

2020-12-06 Thread Jordan Niethe
On Power9, CIABR is lost after idle. This means that instruction
breakpoints set by xmon which use CIABR do not work. Fix this by
restoring CIABR after idle.

Signed-off-by: Jordan Niethe 
---
 arch/powerpc/platforms/powernv/idle.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/powerpc/platforms/powernv/idle.c 
b/arch/powerpc/platforms/powernv/idle.c
index 1ed7c5286487..e6f461812856 100644
--- a/arch/powerpc/platforms/powernv/idle.c
+++ b/arch/powerpc/platforms/powernv/idle.c
@@ -589,6 +589,7 @@ struct p9_sprs {
u64 spurr;
u64 dscr;
u64 wort;
+   u64 ciabr;
 
u64 mmcra;
u32 mmcr0;
@@ -668,6 +669,7 @@ static unsigned long power9_idle_stop(unsigned long psscr, 
bool mmu_on)
sprs.spurr  = mfspr(SPRN_SPURR);
sprs.dscr   = mfspr(SPRN_DSCR);
sprs.wort   = mfspr(SPRN_WORT);
+   sprs.ciabr  = mfspr(SPRN_CIABR);
 
sprs.mmcra  = mfspr(SPRN_MMCRA);
sprs.mmcr0  = mfspr(SPRN_MMCR0);
@@ -785,6 +787,7 @@ static unsigned long power9_idle_stop(unsigned long psscr, 
bool mmu_on)
mtspr(SPRN_SPURR,   sprs.spurr);
mtspr(SPRN_DSCR,sprs.dscr);
mtspr(SPRN_WORT,sprs.wort);
+   mtspr(SPRN_CIABR,   sprs.ciabr);
 
mtspr(SPRN_MMCRA,   sprs.mmcra);
mtspr(SPRN_MMCR0,   sprs.mmcr0);
-- 
2.17.1



[PATCH 1/2] powerpc/book3s64/kexec: Clear CIABR on kexec

2020-12-06 Thread Jordan Niethe
The value in CIABR persists across kexec which can lead to unintended
results when the new kernel hits the old kernel's breakpoint. For
example:

0:mon> bi $loadavg_proc_show
0:mon> b
   typeaddress
1 inst   c0519060  loadavg_proc_show+0x0/0x130
0:mon> x

$ kexec -l /mnt/vmlinux --initrd=/mnt/rootfs.cpio.gz --append='xmon=off'
$ kexec -e

$ cat /proc/loadavg
Trace/breakpoint trap

Make sure CIABR is cleared so this does not happen.

Signed-off-by: Jordan Niethe 
---
 arch/powerpc/include/asm/book3s/64/kexec.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/powerpc/include/asm/book3s/64/kexec.h 
b/arch/powerpc/include/asm/book3s/64/kexec.h
index 6b5c3a248ba2..d4b9d476ecba 100644
--- a/arch/powerpc/include/asm/book3s/64/kexec.h
+++ b/arch/powerpc/include/asm/book3s/64/kexec.h
@@ -3,6 +3,7 @@
 #ifndef _ASM_POWERPC_BOOK3S_64_KEXEC_H_
 #define _ASM_POWERPC_BOOK3S_64_KEXEC_H_
 
+#include 
 
 #define reset_sprs reset_sprs
 static inline void reset_sprs(void)
@@ -14,6 +15,10 @@ static inline void reset_sprs(void)
 
if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
mtspr(SPRN_IAMR, 0);
+   if (cpu_has_feature(CPU_FTR_HVMODE))
+   mtspr(SPRN_CIABR, 0);
+   else
+   plpar_set_ciabr(0);
}
 
/*  Do we need isync()? We are going via a kexec reset */
-- 
2.17.1



[PATCH v2] powerpc: Allow relative pointers in bug table entries

2020-11-30 Thread Jordan Niethe
This enables GENERIC_BUG_RELATIVE_POINTERS on Power so that 32-bit
offsets are stored in the bug entries rather than 64-bit pointers.
While this doesn't save space for 32-bit machines, use it anyway so
there is only one code path.

Signed-off-by: Jordan Niethe 
---
v2: Remove non-relative pointers code
---
 arch/powerpc/Kconfig   | 4 
 arch/powerpc/include/asm/bug.h | 8 
 arch/powerpc/xmon/xmon.c   | 4 ++--
 3 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index e9f13fe08492..294108e0e5c6 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -311,6 +311,10 @@ config GENERIC_BUG
default y
depends on BUG
 
+config GENERIC_BUG_RELATIVE_POINTERS
+   def_bool y
+   depends on GENERIC_BUG
+
 config SYS_SUPPORTS_APM_EMULATION
default y if PMAC_APM_EMU
bool
diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h
index 338f36cd9934..ba0500872cce 100644
--- a/arch/powerpc/include/asm/bug.h
+++ b/arch/powerpc/include/asm/bug.h
@@ -12,7 +12,7 @@
 #ifdef CONFIG_DEBUG_BUGVERBOSE
 .macro EMIT_BUG_ENTRY addr,file,line,flags
 .section __bug_table,"aw"
-5001:   PPC_LONG \addr, 5002f
+5001:   .4byte \addr - 5001b, 5002f - 5001b
 .short \line, \flags
 .org 5001b+BUG_ENTRY_SIZE
 .previous
@@ -23,7 +23,7 @@
 #else
 .macro EMIT_BUG_ENTRY addr,file,line,flags
 .section __bug_table,"aw"
-5001:   PPC_LONG \addr
+5001:   .4byte \addr - 5001b
 .short \flags
 .org 5001b+BUG_ENTRY_SIZE
 .previous
@@ -36,14 +36,14 @@
 #ifdef CONFIG_DEBUG_BUGVERBOSE
 #define _EMIT_BUG_ENTRY\
".section __bug_table,\"aw\"\n" \
-   "2:\t" PPC_LONG "1b, %0\n"  \
+   "2:\t.4byte 1b - 2b, %0 - 2b\n" \
"\t.short %1, %2\n" \
".org 2b+%3\n"  \
".previous\n"
 #else
 #define _EMIT_BUG_ENTRY\
".section __bug_table,\"aw\"\n" \
-   "2:\t" PPC_LONG "1b\n"  \
+   "2:\t.4byte 1b - 2b\n"  \
"\t.short %2\n" \
".org 2b+%3\n"  \
".previous\n"
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 55c43a6c9111..9704c81aff7d 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -1745,9 +1745,9 @@ static void print_bug_trap(struct pt_regs *regs)
 
 #ifdef CONFIG_DEBUG_BUGVERBOSE
printf("kernel BUG at %s:%u!\n",
-  bug->file, bug->line);
+  (char *)bug + bug->file_disp, bug->line);
 #else
-   printf("kernel BUG at %px!\n", (void *)bug->bug_addr);
+   printf("kernel BUG at %px!\n", (void *)bug + bug->bug_addr_disp);
 #endif
 #endif /* CONFIG_BUG */
 }
-- 
2.17.1



Re: [PATCH] powerpc: Allow relative pointers in bug table entries

2020-11-29 Thread Jordan Niethe
On Mon, Nov 30, 2020 at 12:42 PM Michael Ellerman  wrote:
>
> Christophe Leroy  writes:
> > Le 27/11/2020 à 04:02, Jordan Niethe a écrit :
> >> This enables GENERIC_BUG_RELATIVE_POINTERS on Power so that 32-bit
> >> offsets are stored in the bug entries rather than 64-bit pointers.
> >>
> >> Signed-off-by: Jordan Niethe 
> >> ---
> >>   arch/powerpc/Kconfig   |  4 
> >>   arch/powerpc/include/asm/bug.h | 37 --
> >>   arch/powerpc/xmon/xmon.c   | 17 ++--
> >>   3 files changed, 54 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> >> index e9f13fe08492..294108e0e5c6 100644
> >> --- a/arch/powerpc/Kconfig
> >> +++ b/arch/powerpc/Kconfig
> >> @@ -311,6 +311,10 @@ config GENERIC_BUG
> >>  default y
> >>  depends on BUG
> >>
> >> +config GENERIC_BUG_RELATIVE_POINTERS
> >> +def_bool y
> >> +depends on GENERIC_BUG
> >> +
> >>   config SYS_SUPPORTS_APM_EMULATION
> >>  default y if PMAC_APM_EMU
> >>  bool
> >> diff --git a/arch/powerpc/include/asm/bug.h 
> >> b/arch/powerpc/include/asm/bug.h
> >> index 338f36cd9934..d03d834042a1 100644
> >> --- a/arch/powerpc/include/asm/bug.h
> >> +++ b/arch/powerpc/include/asm/bug.h
> >> @@ -12,7 +12,11 @@
> >>   #ifdef CONFIG_DEBUG_BUGVERBOSE
> >>   .macro EMIT_BUG_ENTRY addr,file,line,flags
> >>   .section __bug_table,"aw"
> >> +#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
> >
> > As far as I understand, as soon as CONFIG_BUG is selected, GENERIC_BUG is 
> > automatically selected so
> > GENERIC_BUG_RELATIVE_POINTERS is selected as well. Therefore this #ifndef 
> > is never possible.
>
> Yeah.
>
> There is one place in the generic code that has an ifndef 
> CONFIG_GENERIC_BUG_RELATIVE_POINTERS
> but that's because it has to support arches that don't select it.
>
> In the arch code we know that it's enabled, so there should be no need
> for any ifdefs.
For 32bit, pointers are 4 bytes anyway so it would be pointless to
store a displacement, so won't we need some ifdefs for that?
>
> cheers


Re: [PATCH] powerpc: Allow relative pointers in bug table entries

2020-11-29 Thread Jordan Niethe
On Sun, Nov 29, 2020 at 6:00 AM Christophe Leroy
 wrote:
>
>
>
> Le 27/11/2020 à 04:02, Jordan Niethe a écrit :
> > This enables GENERIC_BUG_RELATIVE_POINTERS on Power so that 32-bit
> > offsets are stored in the bug entries rather than 64-bit pointers.
> >
> > Signed-off-by: Jordan Niethe 
> > ---
> >   arch/powerpc/Kconfig   |  4 
> >   arch/powerpc/include/asm/bug.h | 37 --
> >   arch/powerpc/xmon/xmon.c   | 17 ++--
> >   3 files changed, 54 insertions(+), 4 deletions(-)
> >
> > diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> > index e9f13fe08492..294108e0e5c6 100644
> > --- a/arch/powerpc/Kconfig
> > +++ b/arch/powerpc/Kconfig
> > @@ -311,6 +311,10 @@ config GENERIC_BUG
> >   default y
> >   depends on BUG
> >
> > +config GENERIC_BUG_RELATIVE_POINTERS
> > + def_bool y
> > + depends on GENERIC_BUG
> > +
> >   config SYS_SUPPORTS_APM_EMULATION
> >   default y if PMAC_APM_EMU
> >   bool
> > diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h
> > index 338f36cd9934..d03d834042a1 100644
> > --- a/arch/powerpc/include/asm/bug.h
> > +++ b/arch/powerpc/include/asm/bug.h
> > @@ -12,7 +12,11 @@
> >   #ifdef CONFIG_DEBUG_BUGVERBOSE
> >   .macro EMIT_BUG_ENTRY addr,file,line,flags
> >.section __bug_table,"aw"
> > +#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
>
> As far as I understand, as soon as CONFIG_BUG is selected, GENERIC_BUG is 
> automatically selected so
> GENERIC_BUG_RELATIVE_POINTERS is selected as well. Therefore this #ifndef is 
> never possible.
Thanks, you are right. I'll fix that up.
>
> >   5001:PPC_LONG \addr, 5002f
> > +#else
> > +5001: .4byte \addr - 5001b, 5002f - 5001b
> > +#endif /* CONFIG_GENERIC_BUG_RELATIVE_POINTERS */
> >.short \line, \flags
> >.org 5001b+BUG_ENTRY_SIZE
> >.previous
> > @@ -23,7 +27,11 @@
> >   #else
> >   .macro EMIT_BUG_ENTRY addr,file,line,flags
> >.section __bug_table,"aw"
> > +#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
>
> Same
>
> >   5001:PPC_LONG \addr
> > +#else
> > +5001: .4byte \addr - 5001b
> > +#endif /* CONFIG_GENERIC_BUG_RELATIVE_POINTERS */
> >.short \flags
> >.org 5001b+BUG_ENTRY_SIZE
> >.previous
> > @@ -34,20 +42,45 @@
> >   /* _EMIT_BUG_ENTRY expects args %0,%1,%2,%3 to be FILE, LINE, flags and
> >  sizeof(struct bug_entry), respectively */
> >   #ifdef CONFIG_DEBUG_BUGVERBOSE
> > +#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
>
> Same
>
> >   #define _EMIT_BUG_ENTRY \
> >   ".section __bug_table,\"aw\"\n" \
> >   "2:\t" PPC_LONG "1b, %0\n"  \
> >   "\t.short %1, %2\n" \
> >   ".org 2b+%3\n"  \
> >   ".previous\n"
> > -#else
> > +
> > +#else /* relative pointers */
> > +
> > +#define _EMIT_BUG_ENTRY  \
> > + ".section __bug_table,\"aw\"\n" \
> > + "2:\t.4byte 1b - 2b, %0 - 2b\n" \
> > + "\t.short %1, %2\n" \
> > + ".org 2b+%3\n"  \
> > + ".previous\n"
> > +#endif /* relative pointers */
> > +
> > +#else /* verbose */
> > +
> > +#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
>
> Same
>
> >   #define _EMIT_BUG_ENTRY \
> >   ".section __bug_table,\"aw\"\n" \
> >   "2:\t" PPC_LONG "1b\n"  \
> >   "\t.short %2\n" \
> >   ".org 2b+%3\n"  \
> >   ".previous\n"
> > -#endif
> > +
> > +#else /* relative pointers */
> > +
> > +#define _EMIT_BUG_ENTRY  \
> > + ".section __bug_table,\"aw\"\n" \
> > + "2:\t.4byte 1b - 2b\n"  \
> > + "\t.short %2\n" \
> > + ".org 2b+%3\n"  \
> > + ".previous\n"
> > +
> > +#endif /* relative pointers */
> > +#endif /* verbose */
> >
> >   #define BUG_ENTR

[PATCH] powerpc/64: Fix an EMIT_BUG_ENTRY in head_64.S

2020-11-29 Thread Jordan Niethe
Commit 63ce271b5e37 ("powerpc/prom: convert PROM_BUG() to standard
trap") added an EMIT_BUG_ENTRY for the trap after the branch to
start_kernel(). The EMIT_BUG_ENTRY was for the address "0b", however the
trap was not labeled with "0". Hence the address used for bug is in
relative_toc() where the previous "0" label is. Label the trap as "0" so
the correct address is used.

Fixes: 63ce271b5e37 ("powerpc/prom: convert PROM_BUG() to standard trap")
Signed-off-by: Jordan Niethe 
---
 arch/powerpc/kernel/head_64.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 3bae6286c17c..f63d01c78398 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -995,7 +995,7 @@ start_here_common:
bl  start_kernel
 
/* Not reached */
-   trap
+0: trap
EMIT_BUG_ENTRY 0b, __FILE__, __LINE__, 0
.previous
 
-- 
2.17.1



[PATCH] powerpc: Allow relative pointers in bug table entries

2020-11-26 Thread Jordan Niethe
This enables GENERIC_BUG_RELATIVE_POINTERS on Power so that 32-bit
offsets are stored in the bug entries rather than 64-bit pointers.

Signed-off-by: Jordan Niethe 
---
 arch/powerpc/Kconfig   |  4 
 arch/powerpc/include/asm/bug.h | 37 --
 arch/powerpc/xmon/xmon.c   | 17 ++--
 3 files changed, 54 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index e9f13fe08492..294108e0e5c6 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -311,6 +311,10 @@ config GENERIC_BUG
default y
depends on BUG
 
+config GENERIC_BUG_RELATIVE_POINTERS
+   def_bool y
+   depends on GENERIC_BUG
+
 config SYS_SUPPORTS_APM_EMULATION
default y if PMAC_APM_EMU
bool
diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h
index 338f36cd9934..d03d834042a1 100644
--- a/arch/powerpc/include/asm/bug.h
+++ b/arch/powerpc/include/asm/bug.h
@@ -12,7 +12,11 @@
 #ifdef CONFIG_DEBUG_BUGVERBOSE
 .macro EMIT_BUG_ENTRY addr,file,line,flags
 .section __bug_table,"aw"
+#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
 5001:   PPC_LONG \addr, 5002f
+#else
+5001:   .4byte \addr - 5001b, 5002f - 5001b
+#endif /* CONFIG_GENERIC_BUG_RELATIVE_POINTERS */
 .short \line, \flags
 .org 5001b+BUG_ENTRY_SIZE
 .previous
@@ -23,7 +27,11 @@
 #else
 .macro EMIT_BUG_ENTRY addr,file,line,flags
 .section __bug_table,"aw"
+#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
 5001:   PPC_LONG \addr
+#else
+5001:   .4byte \addr - 5001b
+#endif /* CONFIG_GENERIC_BUG_RELATIVE_POINTERS */
 .short \flags
 .org 5001b+BUG_ENTRY_SIZE
 .previous
@@ -34,20 +42,45 @@
 /* _EMIT_BUG_ENTRY expects args %0,%1,%2,%3 to be FILE, LINE, flags and
sizeof(struct bug_entry), respectively */
 #ifdef CONFIG_DEBUG_BUGVERBOSE
+#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
 #define _EMIT_BUG_ENTRY\
".section __bug_table,\"aw\"\n" \
"2:\t" PPC_LONG "1b, %0\n"  \
"\t.short %1, %2\n" \
".org 2b+%3\n"  \
".previous\n"
-#else
+
+#else /* relative pointers */
+
+#define _EMIT_BUG_ENTRY\
+   ".section __bug_table,\"aw\"\n" \
+   "2:\t.4byte 1b - 2b, %0 - 2b\n" \
+   "\t.short %1, %2\n" \
+   ".org 2b+%3\n"  \
+   ".previous\n"
+#endif /* relative pointers */
+
+#else /* verbose */
+
+#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
 #define _EMIT_BUG_ENTRY\
".section __bug_table,\"aw\"\n" \
"2:\t" PPC_LONG "1b\n"  \
"\t.short %2\n" \
".org 2b+%3\n"  \
".previous\n"
-#endif
+
+#else /* relative pointers */
+
+#define _EMIT_BUG_ENTRY\
+   ".section __bug_table,\"aw\"\n" \
+   "2:\t.4byte 1b - 2b\n"  \
+   "\t.short %2\n" \
+   ".org 2b+%3\n"  \
+   ".previous\n"
+
+#endif /* relative pointers */
+#endif /* verbose */
 
 #define BUG_ENTRY(insn, flags, ...)\
__asm__ __volatile__(   \
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 55c43a6c9111..5f7cf7e95767 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -1731,6 +1731,9 @@ static void print_bug_trap(struct pt_regs *regs)
 #ifdef CONFIG_BUG
const struct bug_entry *bug;
unsigned long addr;
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+   char *file;
+#endif
 
if (regs->msr & MSR_PR)
return; /* not in kernel */
@@ -1744,10 +1747,20 @@ static void print_bug_trap(struct pt_regs *regs)
return;
 
 #ifdef CONFIG_DEBUG_BUGVERBOSE
+#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
+   file = bug->file;
+#else /* relative pointers */
+   file = (char *)bug + bug->file_disp;
+#endif /* relative pointers */
printf("kernel BUG at %s:%u!\n",
-  bug->file, bug->line);
+  file, bug->line);
 #else
-   printf("kernel BUG at %px!\n", (void *)bug->bug_addr);
+#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
+   addr = bug->addr;
+#else /* relative pointers */
+   addr = (unsigned long)bug + bug->bug_addr_disp;
+#endif /* relative pointers */
+   printf("kernel BUG at %px!\n", (void *)addr);
 #endif
 #endif /* CONFIG_BUG */
 }
-- 
2.17.1



Re: [PATCH] powerpc/powernv/memtrace: Fake non-memblock aligned sized traces

2020-11-16 Thread Jordan Niethe
On Mon, Nov 16, 2020 at 11:02 PM Michael Ellerman  wrote:
>
> Jordan Niethe  writes:
> > The hardware trace macros which use the memory provided by memtrace are
> > able to use trace sizes as small as 16MB. Only memblock aligned values
> > can be removed from each NUMA node by writing that value to
> > memtrace/enable in debugfs.  This means setting up, say, a 16MB trace is
> > not possible.  To allow such a trace size, instead align whatever value
> > is written to memtrace/enable to the memblock size for the purpose of
> > removing it from each NUMA node but report the written value from
> > memtrace/enable and memtrace/x/size in debugfs.
>
> Why does it matter if the size that's removed is larger than the size
> that was requested?
>
> Is it about constraining the size of the trace? If so that seems like it
> should be the job of the tracing tools, not the kernel.
Yeah about constraining the size, I'll just do it in the trace tools.
>
> cheers


[PATCH] powerpc/powernv/memtrace: Fake non-memblock aligned sized traces

2020-11-10 Thread Jordan Niethe
The hardware trace macros which use the memory provided by memtrace are
able to use trace sizes as small as 16MB. Only memblock aligned values
can be removed from each NUMA node by writing that value to
memtrace/enable in debugfs.  This means setting up, say, a 16MB trace is
not possible.  To allow such a trace size, instead align whatever value
is written to memtrace/enable to the memblock size for the purpose of
removing it from each NUMA node but report the written value from
memtrace/enable and memtrace/x/size in debugfs.

Signed-off-by: Jordan Niethe 
---
 arch/powerpc/platforms/powernv/memtrace.c | 20 ++--
 1 file changed, 6 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/memtrace.c 
b/arch/powerpc/platforms/powernv/memtrace.c
index 6828108486f8..1188bc8fd090 100644
--- a/arch/powerpc/platforms/powernv/memtrace.c
+++ b/arch/powerpc/platforms/powernv/memtrace.c
@@ -191,7 +191,7 @@ static int memtrace_init_debugfs(void)
ent->dir = dir;
debugfs_create_file("trace", 0400, dir, ent, _fops);
debugfs_create_x64("start", 0400, dir, >start);
-   debugfs_create_x64("size", 0400, dir, >size);
+   debugfs_create_x64("size", 0400, dir, _size);
}
 
return ret;
@@ -259,33 +259,25 @@ static int memtrace_enable_set(void *data, u64 val)
 {
u64 bytes;
 
-   /*
-* Don't attempt to do anything if size isn't aligned to a memory
-* block or equal to zero.
-*/
-   bytes = memory_block_size_bytes();
-   if (val & (bytes - 1)) {
-   pr_err("Value must be aligned with 0x%llx\n", bytes);
-   return -EINVAL;
-   }
-
/* Re-add/online previously removed/offlined memory */
if (memtrace_size) {
if (memtrace_online())
return -EAGAIN;
}
 
+   memtrace_size = val;
+
if (!val)
return 0;
 
-   /* Offline and remove memory */
-   if (memtrace_init_regions_runtime(val))
+   /* Offline and remove memory aligned to memory blocks */
+   bytes = memory_block_size_bytes();
+   if (memtrace_init_regions_runtime(ALIGN(val, bytes)))
return -EINVAL;
 
if (memtrace_init_debugfs())
return -EINVAL;
 
-   memtrace_size = val;
 
return 0;
 }
-- 
2.17.1



Re: [PATCH v2 1/2] powerpc: Introduce POWER10_DD1 feature

2020-10-22 Thread Jordan Niethe
On Thu, Oct 22, 2020 at 4:33 PM Ravi Bangoria
 wrote:
>
>
>
> On 10/22/20 10:41 AM, Jordan Niethe wrote:
> > On Thu, Oct 22, 2020 at 2:40 PM Ravi Bangoria
> >  wrote:
> >>
> >> POWER10_DD1 feature flag will be needed while adding
> >> conditional code that applies only for Power10 DD1.
> >>
> >> Signed-off-by: Ravi Bangoria 
> >> ---
> >>   arch/powerpc/include/asm/cputable.h | 8 ++--
> >>   arch/powerpc/kernel/dt_cpu_ftrs.c   | 3 +++
> >>   arch/powerpc/kernel/prom.c  | 9 +
> >>   3 files changed, 18 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/arch/powerpc/include/asm/cputable.h 
> >> b/arch/powerpc/include/asm/cputable.h
> >> index 93bc70d4c9a1..d486f56c0d33 100644
> >> --- a/arch/powerpc/include/asm/cputable.h
> >> +++ b/arch/powerpc/include/asm/cputable.h
> >> @@ -216,6 +216,7 @@ static inline void cpu_feature_keys_init(void) { }
> >>   #define CPU_FTR_P9_RADIX_PREFETCH_BUG  LONG_ASM_CONST(0x0002)
> >>   #define CPU_FTR_ARCH_31
> >> LONG_ASM_CONST(0x0004)
> >>   #define CPU_FTR_DAWR1  LONG_ASM_CONST(0x0008)
> >> +#define CPU_FTR_POWER10_DD1LONG_ASM_CONST(0x0010)
> >>
> >>   #ifndef __ASSEMBLY__
> >>
> >> @@ -479,6 +480,7 @@ static inline void cpu_feature_keys_init(void) { }
> >>  CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_ARCH_207S | \
> >>  CPU_FTR_TM_COMP | CPU_FTR_ARCH_300 | CPU_FTR_ARCH_31 | \
> >>  CPU_FTR_DAWR | CPU_FTR_DAWR1)
> >> +#define CPU_FTRS_POWER10_DD1   (CPU_FTRS_POWER10 | CPU_FTR_POWER10_DD1)
> >>   #define CPU_FTRS_CELL  (CPU_FTR_LWSYNC | \
> >>  CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
> >>  CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
> >> @@ -497,14 +499,16 @@ static inline void cpu_feature_keys_init(void) { }
> >>   #define CPU_FTRS_POSSIBLE  \
> >>  (CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | CPU_FTRS_POWER8 | \
> >>   CPU_FTR_ALTIVEC_COMP | CPU_FTR_VSX_COMP | CPU_FTRS_POWER9 | \
> >> -CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2 | 
> >> CPU_FTRS_POWER10)
> >> +CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2 | 
> >> CPU_FTRS_POWER10 | \
> >> +CPU_FTRS_POWER10_DD1)
> >>   #else
> >>   #define CPU_FTRS_POSSIBLE  \
> >>  (CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | \
> >>   CPU_FTRS_POWER6 | CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | \
> >>   CPU_FTRS_POWER8 | CPU_FTRS_CELL | CPU_FTRS_PA6T | \
> >>   CPU_FTR_VSX_COMP | CPU_FTR_ALTIVEC_COMP | CPU_FTRS_POWER9 | \
> >> -CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2 | 
> >> CPU_FTRS_POWER10)
> >> +CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2 | 
> >> CPU_FTRS_POWER10 | \
> >> +CPU_FTRS_POWER10_DD1)
> >>   #endif /* CONFIG_CPU_LITTLE_ENDIAN */
> >>   #endif
> >>   #else
> >> diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c 
> >> b/arch/powerpc/kernel/dt_cpu_ftrs.c
> >> index 1098863e17ee..b2327f2967ff 100644
> >> --- a/arch/powerpc/kernel/dt_cpu_ftrs.c
> >> +++ b/arch/powerpc/kernel/dt_cpu_ftrs.c
> >> @@ -811,6 +811,9 @@ static __init void cpufeatures_cpu_quirks(void)
> >>  }
> >>
> >>  update_tlbie_feature_flag(version);
> >> +
> >> +   if ((version & 0x) == 0x00800100)
> >> +   cur_cpu_spec->cpu_features |= CPU_FTR_POWER10_DD1;
> >>   }
> >>
> >>   static void __init cpufeatures_setup_finished(void)
> >> diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
> >> index c1545f22c077..c778c81284f7 100644
> >> --- a/arch/powerpc/kernel/prom.c
> >> +++ b/arch/powerpc/kernel/prom.c
> >> @@ -305,6 +305,14 @@ static void __init 
> >> check_cpu_feature_properties(unsigned long node)
> >>  }
> >>   }
> >>
> >> +static void __init fixup_cpu_features(void)
> >> +{
> >> +   unsigned long version = mfspr(SPRN_PVR);
> >> +
> >> +   if ((version & 0x) == 0x00800100)
> >> +   cur_cpu_spec->cpu_features |= CPU_FTR_POWER10_DD1;
> >> +}
> >> +
> > I am just wondering why this is needed here, but the same thing is not
&g

Re: [PATCH v2 1/2] powerpc: Introduce POWER10_DD1 feature

2020-10-21 Thread Jordan Niethe
On Thu, Oct 22, 2020 at 2:40 PM Ravi Bangoria
 wrote:
>
> POWER10_DD1 feature flag will be needed while adding
> conditional code that applies only for Power10 DD1.
>
> Signed-off-by: Ravi Bangoria 
> ---
>  arch/powerpc/include/asm/cputable.h | 8 ++--
>  arch/powerpc/kernel/dt_cpu_ftrs.c   | 3 +++
>  arch/powerpc/kernel/prom.c  | 9 +
>  3 files changed, 18 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/cputable.h 
> b/arch/powerpc/include/asm/cputable.h
> index 93bc70d4c9a1..d486f56c0d33 100644
> --- a/arch/powerpc/include/asm/cputable.h
> +++ b/arch/powerpc/include/asm/cputable.h
> @@ -216,6 +216,7 @@ static inline void cpu_feature_keys_init(void) { }
>  #define CPU_FTR_P9_RADIX_PREFETCH_BUG  LONG_ASM_CONST(0x0002)
>  #define CPU_FTR_ARCH_31
> LONG_ASM_CONST(0x0004)
>  #define CPU_FTR_DAWR1  LONG_ASM_CONST(0x0008)
> +#define CPU_FTR_POWER10_DD1LONG_ASM_CONST(0x0010)
>
>  #ifndef __ASSEMBLY__
>
> @@ -479,6 +480,7 @@ static inline void cpu_feature_keys_init(void) { }
> CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_ARCH_207S | \
> CPU_FTR_TM_COMP | CPU_FTR_ARCH_300 | CPU_FTR_ARCH_31 | \
> CPU_FTR_DAWR | CPU_FTR_DAWR1)
> +#define CPU_FTRS_POWER10_DD1   (CPU_FTRS_POWER10 | CPU_FTR_POWER10_DD1)
>  #define CPU_FTRS_CELL  (CPU_FTR_LWSYNC | \
> CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
> CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
> @@ -497,14 +499,16 @@ static inline void cpu_feature_keys_init(void) { }
>  #define CPU_FTRS_POSSIBLE  \
> (CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | CPU_FTRS_POWER8 | \
>  CPU_FTR_ALTIVEC_COMP | CPU_FTR_VSX_COMP | CPU_FTRS_POWER9 | \
> -CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2 | CPU_FTRS_POWER10)
> +CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2 | CPU_FTRS_POWER10 
> | \
> +CPU_FTRS_POWER10_DD1)
>  #else
>  #define CPU_FTRS_POSSIBLE  \
> (CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | \
>  CPU_FTRS_POWER6 | CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | \
>  CPU_FTRS_POWER8 | CPU_FTRS_CELL | CPU_FTRS_PA6T | \
>  CPU_FTR_VSX_COMP | CPU_FTR_ALTIVEC_COMP | CPU_FTRS_POWER9 | \
> -CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2 | CPU_FTRS_POWER10)
> +CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2 | CPU_FTRS_POWER10 
> | \
> +CPU_FTRS_POWER10_DD1)
>  #endif /* CONFIG_CPU_LITTLE_ENDIAN */
>  #endif
>  #else
> diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c 
> b/arch/powerpc/kernel/dt_cpu_ftrs.c
> index 1098863e17ee..b2327f2967ff 100644
> --- a/arch/powerpc/kernel/dt_cpu_ftrs.c
> +++ b/arch/powerpc/kernel/dt_cpu_ftrs.c
> @@ -811,6 +811,9 @@ static __init void cpufeatures_cpu_quirks(void)
> }
>
> update_tlbie_feature_flag(version);
> +
> +   if ((version & 0x) == 0x00800100)
> +   cur_cpu_spec->cpu_features |= CPU_FTR_POWER10_DD1;
>  }
>
>  static void __init cpufeatures_setup_finished(void)
> diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
> index c1545f22c077..c778c81284f7 100644
> --- a/arch/powerpc/kernel/prom.c
> +++ b/arch/powerpc/kernel/prom.c
> @@ -305,6 +305,14 @@ static void __init check_cpu_feature_properties(unsigned 
> long node)
> }
>  }
>
> +static void __init fixup_cpu_features(void)
> +{
> +   unsigned long version = mfspr(SPRN_PVR);
> +
> +   if ((version & 0x) == 0x00800100)
> +   cur_cpu_spec->cpu_features |= CPU_FTR_POWER10_DD1;
> +}
> +
I am just wondering why this is needed here, but the same thing is not
done for, say, CPU_FTR_POWER9_DD2_1?
And should we get a /* Power10 DD 1 */ added to cpu_specs[]?

>  static int __init early_init_dt_scan_cpus(unsigned long node,
>   const char *uname, int depth,
>   void *data)
> @@ -378,6 +386,7 @@ static int __init early_init_dt_scan_cpus(unsigned long 
> node,
>
> check_cpu_feature_properties(node);
> check_cpu_pa_features(node);
> +   fixup_cpu_features();
> }
>
> identical_pvr_fixup(node);
> --
> 2.25.1
>


[PATCH v4 2/2] powerpc/64s: Convert some cpu_setup() and cpu_restore() functions to C

2020-10-14 Thread Jordan Niethe
The only thing keeping the cpu_setup() and cpu_restore() functions used
in the cputable entries for Power7, Power8, Power9 and Power10 in
assembly was cpu_restore() being called before there was a stack in
generic_secondary_smp_init(). Commit ("powerpc/64: Set up a kernel stack
for secondaries before cpu_restore()") means that it is now possible to
use C.

Rewrite the functions in C so they are a little bit easier to read. This
is not changing their functionality.

Signed-off-by: Jordan Niethe 
---
 arch/powerpc/include/asm/cpu_setup_power.h |  12 +
 arch/powerpc/kernel/cpu_setup_power.S  | 252 ---
 arch/powerpc/kernel/cpu_setup_power.c  | 269 +
 arch/powerpc/kernel/cputable.c |  12 +-
 4 files changed, 285 insertions(+), 260 deletions(-)
 create mode 100644 arch/powerpc/include/asm/cpu_setup_power.h
 delete mode 100644 arch/powerpc/kernel/cpu_setup_power.S
 create mode 100644 arch/powerpc/kernel/cpu_setup_power.c

diff --git a/arch/powerpc/include/asm/cpu_setup_power.h 
b/arch/powerpc/include/asm/cpu_setup_power.h
new file mode 100644
index ..24be9131f803
--- /dev/null
+++ b/arch/powerpc/include/asm/cpu_setup_power.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2020 IBM Corporation
+ */
+void __setup_cpu_power7(unsigned long offset, struct cpu_spec *spec);
+void __restore_cpu_power7(void);
+void __setup_cpu_power8(unsigned long offset, struct cpu_spec *spec);
+void __restore_cpu_power8(void);
+void __setup_cpu_power9(unsigned long offset, struct cpu_spec *spec);
+void __restore_cpu_power9(void);
+void __setup_cpu_power10(unsigned long offset, struct cpu_spec *spec);
+void __restore_cpu_power10(void);
diff --git a/arch/powerpc/kernel/cpu_setup_power.S 
b/arch/powerpc/kernel/cpu_setup_power.S
deleted file mode 100644
index 704e8b9501ee..
--- a/arch/powerpc/kernel/cpu_setup_power.S
+++ /dev/null
@@ -1,252 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * This file contains low level CPU setup functions.
- *Copyright (C) 2003 Benjamin Herrenschmidt (b...@kernel.crashing.org)
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-/* Entry: r3 = crap, r4 = ptr to cputable entry
- *
- * Note that we can be called twice for pseudo-PVRs
- */
-_GLOBAL(__setup_cpu_power7)
-   mflrr11
-   bl  __init_hvmode_206
-   mtlrr11
-   beqlr
-   li  r0,0
-   mtspr   SPRN_LPID,r0
-   LOAD_REG_IMMEDIATE(r0, PCR_MASK)
-   mtspr   SPRN_PCR,r0
-   mfspr   r3,SPRN_LPCR
-   li  r4,(LPCR_LPES1 >> LPCR_LPES_SH)
-   bl  __init_LPCR_ISA206
-   mtlrr11
-   blr
-
-_GLOBAL(__restore_cpu_power7)
-   mflrr11
-   mfmsr   r3
-   rldicl. r0,r3,4,63
-   beqlr
-   li  r0,0
-   mtspr   SPRN_LPID,r0
-   LOAD_REG_IMMEDIATE(r0, PCR_MASK)
-   mtspr   SPRN_PCR,r0
-   mfspr   r3,SPRN_LPCR
-   li  r4,(LPCR_LPES1 >> LPCR_LPES_SH)
-   bl  __init_LPCR_ISA206
-   mtlrr11
-   blr
-
-_GLOBAL(__setup_cpu_power8)
-   mflrr11
-   bl  __init_FSCR
-   bl  __init_PMU
-   bl  __init_PMU_ISA207
-   bl  __init_hvmode_206
-   mtlrr11
-   beqlr
-   li  r0,0
-   mtspr   SPRN_LPID,r0
-   LOAD_REG_IMMEDIATE(r0, PCR_MASK)
-   mtspr   SPRN_PCR,r0
-   mfspr   r3,SPRN_LPCR
-   ori r3, r3, LPCR_PECEDH
-   li  r4,0 /* LPES = 0 */
-   bl  __init_LPCR_ISA206
-   bl  __init_HFSCR
-   bl  __init_PMU_HV
-   bl  __init_PMU_HV_ISA207
-   mtlrr11
-   blr
-
-_GLOBAL(__restore_cpu_power8)
-   mflrr11
-   bl  __init_FSCR
-   bl  __init_PMU
-   bl  __init_PMU_ISA207
-   mfmsr   r3
-   rldicl. r0,r3,4,63
-   mtlrr11
-   beqlr
-   li  r0,0
-   mtspr   SPRN_LPID,r0
-   LOAD_REG_IMMEDIATE(r0, PCR_MASK)
-   mtspr   SPRN_PCR,r0
-   mfspr   r3,SPRN_LPCR
-   ori r3, r3, LPCR_PECEDH
-   li  r4,0 /* LPES = 0 */
-   bl  __init_LPCR_ISA206
-   bl  __init_HFSCR
-   bl  __init_PMU_HV
-   bl  __init_PMU_HV_ISA207
-   mtlrr11
-   blr
-
-_GLOBAL(__setup_cpu_power10)
-   mflrr11
-   bl  __init_FSCR_power10
-   bl  __init_PMU
-   bl  __init_PMU_ISA31
-   b   1f
-
-_GLOBAL(__setup_cpu_power9)
-   mflrr11
-   bl  __init_FSCR_power9
-   bl  __init_PMU
-1: bl  __init_hvmode_206
-   mtlrr11
-   beqlr
-   li  r0,0
-   mtspr   SPRN_PSSCR,r0
-   mtspr   SPRN_LPID,r0
-   mtspr   SPRN_PID,r0
-   LOAD_REG_IMMEDIATE(r0, PCR_MASK)
-   mtspr   SPRN_PCR,r0
-   mfspr   r3,SPRN_LPCR
-   LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE  | 
LPCR_HEIC)
-   or  r3, r3, r4
-  

[PATCH v4 1/2] powerpc/64: Set up a kernel stack for secondaries before cpu_restore()

2020-10-14 Thread Jordan Niethe
Currently in generic_secondary_smp_init(), cur_cpu_spec->cpu_restore()
is called before a stack has been set up in r1. This was previously fine
as the cpu_restore() functions were implemented in assembly and did not
use a stack. However commit 5a61ef74f269 ("powerpc/64s: Support new
device tree binding for discovering CPU features") used
__restore_cpu_cpufeatures() as the cpu_restore() function for a
device-tree features based cputable entry. This is a C function and
hence uses a stack in r1.

generic_secondary_smp_init() is entered on the secondary cpus via the
primary cpu using the OPAL call opal_start_cpu(). In OPAL, each hardware
thread has its own stack. The OPAL call is ran in the primary's hardware
thread. During the call, a job is scheduled on a secondary cpu that will
start executing at the address of generic_secondary_smp_init().  Hence
the value that will be left in r1 when the secondary cpu enters the
kernel is part of that secondary cpu's individual OPAL stack. This means
that __restore_cpu_cpufeatures() will write to that OPAL stack. This is
not horribly bad as each hardware thread has its own stack and the call
that enters the kernel from OPAL never returns, but it is still wrong
and should be corrected.

Create the temp kernel stack before calling cpu_restore().

As noted by mpe, for a kexec boot, the secondary CPUs are released from
the spin loop at address 0x60 by smp_release_cpus() and then jump to
generic_secondary_smp_init(). The call to smp_release_cpus() is in
setup_arch(), and it comes before the call to emergency_stack_init().
emergency_stack_init() allocates an emergency stack in the PACA for each
CPU.  This address in the PACA is what is used to set up the temp kernel
stack in generic_secondary_smp_init(). Move releasing the secondary CPUs
to after the PACAs have been allocated an emergency stack, otherwise the
PACA stack pointer will contain garbage and hence the temp kernel stack
created from it will be broken.

Fixes: 5a61ef74f269 ("powerpc/64s: Support new device tree binding for 
discovering CPU features")
Signed-off-by: Jordan Niethe 
---
v2: Add more detail to the commit message
v3: Release secondary CPUs after the emergency stack is created
v4: No need to guard smp_release_cpus() with #ifdef CONFIG_SMP
---
 arch/powerpc/kernel/head_64.S  | 8 
 arch/powerpc/kernel/setup-common.c | 4 ++--
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 0e05a9a47a4b..4b7f4c6c2600 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -420,6 +420,10 @@ generic_secondary_common_init:
/* From now on, r24 is expected to be logical cpuid */
mr  r24,r5
 
+   /* Create a temp kernel stack for use before relocation is on.  */
+   ld  r1,PACAEMERGSP(r13)
+   subir1,r1,STACK_FRAME_OVERHEAD
+
/* See if we need to call a cpu state restore handler */
LOAD_REG_ADDR(r23, cur_cpu_spec)
ld  r23,0(r23)
@@ -448,10 +452,6 @@ generic_secondary_common_init:
sync/* order paca.run and cur_cpu_spec */
isync   /* In case code patching happened */
 
-   /* Create a temp kernel stack for use before relocation is on.  */
-   ld  r1,PACAEMERGSP(r13)
-   subir1,r1,STACK_FRAME_OVERHEAD
-
b   __secondary_start
 #endif /* SMP */
 
diff --git a/arch/powerpc/kernel/setup-common.c 
b/arch/powerpc/kernel/setup-common.c
index 808ec9fab605..da8c71f321ad 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -919,8 +919,6 @@ void __init setup_arch(char **cmdline_p)
 
/* On BookE, setup per-core TLB data structures. */
setup_tlb_core_data();
-
-   smp_release_cpus();
 #endif
 
/* Print various info about the machine that has been gathered so far. 
*/
@@ -944,6 +942,8 @@ void __init setup_arch(char **cmdline_p)
exc_lvl_early_init();
emergency_stack_init();
 
+   smp_release_cpus();
+
initmem_init();
 
early_memtest(min_low_pfn << PAGE_SHIFT, max_low_pfn << PAGE_SHIFT);
-- 
2.17.1



Re: [PATCH v3 1/2] powerpc/64: Set up a kernel stack for secondaries before cpu_restore()

2020-09-22 Thread Jordan Niethe
On Tue, Sep 22, 2020 at 3:59 PM Christophe Leroy
 wrote:
>
>
>
> Le 22/09/2020 à 07:53, Jordan Niethe a écrit :
> > Currently in generic_secondary_smp_init(), cur_cpu_spec->cpu_restore()
> > is called before a stack has been set up in r1. This was previously fine
> > as the cpu_restore() functions were implemented in assembly and did not
> > use a stack. However commit 5a61ef74f269 ("powerpc/64s: Support new
> > device tree binding for discovering CPU features") used
> > __restore_cpu_cpufeatures() as the cpu_restore() function for a
> > device-tree features based cputable entry. This is a C function and
> > hence uses a stack in r1.
> >
> > generic_secondary_smp_init() is entered on the secondary cpus via the
> > primary cpu using the OPAL call opal_start_cpu(). In OPAL, each hardware
> > thread has its own stack. The OPAL call is ran in the primary's hardware
> > thread. During the call, a job is scheduled on a secondary cpu that will
> > start executing at the address of generic_secondary_smp_init().  Hence
> > the value that will be left in r1 when the secondary cpu enters the
> > kernel is part of that secondary cpu's individual OPAL stack. This means
> > that __restore_cpu_cpufeatures() will write to that OPAL stack. This is
> > not horribly bad as each hardware thread has its own stack and the call
> > that enters the kernel from OPAL never returns, but it is still wrong
> > and should be corrected.
> >
> > Create the temp kernel stack before calling cpu_restore().
> >
> > As noted by mpe, for a kexec boot, the secondary CPUs are released from
> > the spin loop at address 0x60 by smp_release_cpus() and then jump to
> > generic_secondary_smp_init(). The call to smp_release_cpus() is in
> > setup_arch(), and it comes before the call to emergency_stack_init().
> > emergency_stack_init() allocates an emergency stack in the PACA for each
> > CPU.  This address in the PACA is what is used to set up the temp kernel
> > stack in generic_secondary_smp_init(). Move releasing the secondary CPUs
> > to after the PACAs have been allocated an emergency stack, otherwise the
> > PACA stack pointer will contain garbage and hence the temp kernel stack
> > created from it will be broken.
> >
> > Fixes: 5a61ef74f269 ("powerpc/64s: Support new device tree binding for 
> > discovering CPU features")
> > Signed-off-by: Jordan Niethe 
> > ---
> > v2: Add more detail to the commit message
> > v3: Release secondary CPUs after the emergency stack is created
> > ---
> >   arch/powerpc/kernel/head_64.S  | 8 
> >   arch/powerpc/kernel/setup-common.c | 6 --
> >   2 files changed, 8 insertions(+), 6 deletions(-)
> >
> > diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
> > index 0e05a9a47a4b..4b7f4c6c2600 100644
> > --- a/arch/powerpc/kernel/head_64.S
> > +++ b/arch/powerpc/kernel/head_64.S
> > @@ -420,6 +420,10 @@ generic_secondary_common_init:
> >   /* From now on, r24 is expected to be logical cpuid */
> >   mr  r24,r5
> >
> > + /* Create a temp kernel stack for use before relocation is on.  */
> > + ld  r1,PACAEMERGSP(r13)
> > + subir1,r1,STACK_FRAME_OVERHEAD
> > +
> >   /* See if we need to call a cpu state restore handler */
> >   LOAD_REG_ADDR(r23, cur_cpu_spec)
> >   ld  r23,0(r23)
> > @@ -448,10 +452,6 @@ generic_secondary_common_init:
> >   sync/* order paca.run and cur_cpu_spec */
> >   isync   /* In case code patching happened */
> >
> > - /* Create a temp kernel stack for use before relocation is on.  */
> > - ld  r1,PACAEMERGSP(r13)
> > - subir1,r1,STACK_FRAME_OVERHEAD
> > -
> >   b   __secondary_start
> >   #endif /* SMP */
> >
> > diff --git a/arch/powerpc/kernel/setup-common.c 
> > b/arch/powerpc/kernel/setup-common.c
> > index 808ec9fab605..fff714e36b37 100644
> > --- a/arch/powerpc/kernel/setup-common.c
> > +++ b/arch/powerpc/kernel/setup-common.c
> > @@ -919,8 +919,6 @@ void __init setup_arch(char **cmdline_p)
> >
> >   /* On BookE, setup per-core TLB data structures. */
> >   setup_tlb_core_data();
> > -
> > - smp_release_cpus();
> >   #endif
> >
> >   /* Print various info about the machine that has been gathered so 
> > far. */
> > @@ -944,6 +942,10 @@ void __init setup_arch(char **cmdline_p)
> >   exc_lvl_early_init();
> >   emergency_stack_init();
> >
> > +#ifdef CONFIG_SMP
> > + smp_release_cpus();
> > +#endif
>
> Are you sure you need that #ifdef ?
Thanks, you are right, should not be necessary.
>
> In asm/smp.h, we have:
>
> #if defined(CONFIG_PPC64) && (defined(CONFIG_SMP) ||
> defined(CONFIG_KEXEC_CORE))
> extern void smp_release_cpus(void);
> #else
> static inline void smp_release_cpus(void) { };
> #endif
>
>
> > +
> >   initmem_init();
> >
> >   early_memtest(min_low_pfn << PAGE_SHIFT, max_low_pfn << PAGE_SHIFT);
> >
>
> Christophe


[PATCH v3 2/2] powerpc/64s: Convert some cpu_setup() and cpu_restore() functions to C

2020-09-21 Thread Jordan Niethe
The only thing keeping the cpu_setup() and cpu_restore() functions used
in the cputable entries for Power7, Power8, Power9 and Power10 in
assembly was cpu_restore() being called before there was a stack in
generic_secondary_smp_init(). Commit ("powerpc/64: Set up a kernel stack
for secondaries before cpu_restore()") means that it is now possible to
use C.

Rewrite the functions in C so they are a little bit easier to read. This
is not changing their functionality.

Signed-off-by: Jordan Niethe 
---
 arch/powerpc/include/asm/cpu_setup_power.h |  12 +
 arch/powerpc/kernel/cpu_setup_power.S  | 252 ---
 arch/powerpc/kernel/cpu_setup_power.c  | 269 +
 arch/powerpc/kernel/cputable.c |  12 +-
 4 files changed, 285 insertions(+), 260 deletions(-)
 create mode 100644 arch/powerpc/include/asm/cpu_setup_power.h
 delete mode 100644 arch/powerpc/kernel/cpu_setup_power.S
 create mode 100644 arch/powerpc/kernel/cpu_setup_power.c

diff --git a/arch/powerpc/include/asm/cpu_setup_power.h 
b/arch/powerpc/include/asm/cpu_setup_power.h
new file mode 100644
index ..24be9131f803
--- /dev/null
+++ b/arch/powerpc/include/asm/cpu_setup_power.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2020 IBM Corporation
+ */
+void __setup_cpu_power7(unsigned long offset, struct cpu_spec *spec);
+void __restore_cpu_power7(void);
+void __setup_cpu_power8(unsigned long offset, struct cpu_spec *spec);
+void __restore_cpu_power8(void);
+void __setup_cpu_power9(unsigned long offset, struct cpu_spec *spec);
+void __restore_cpu_power9(void);
+void __setup_cpu_power10(unsigned long offset, struct cpu_spec *spec);
+void __restore_cpu_power10(void);
diff --git a/arch/powerpc/kernel/cpu_setup_power.S 
b/arch/powerpc/kernel/cpu_setup_power.S
deleted file mode 100644
index 704e8b9501ee..
--- a/arch/powerpc/kernel/cpu_setup_power.S
+++ /dev/null
@@ -1,252 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * This file contains low level CPU setup functions.
- *Copyright (C) 2003 Benjamin Herrenschmidt (b...@kernel.crashing.org)
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-/* Entry: r3 = crap, r4 = ptr to cputable entry
- *
- * Note that we can be called twice for pseudo-PVRs
- */
-_GLOBAL(__setup_cpu_power7)
-   mflrr11
-   bl  __init_hvmode_206
-   mtlrr11
-   beqlr
-   li  r0,0
-   mtspr   SPRN_LPID,r0
-   LOAD_REG_IMMEDIATE(r0, PCR_MASK)
-   mtspr   SPRN_PCR,r0
-   mfspr   r3,SPRN_LPCR
-   li  r4,(LPCR_LPES1 >> LPCR_LPES_SH)
-   bl  __init_LPCR_ISA206
-   mtlrr11
-   blr
-
-_GLOBAL(__restore_cpu_power7)
-   mflrr11
-   mfmsr   r3
-   rldicl. r0,r3,4,63
-   beqlr
-   li  r0,0
-   mtspr   SPRN_LPID,r0
-   LOAD_REG_IMMEDIATE(r0, PCR_MASK)
-   mtspr   SPRN_PCR,r0
-   mfspr   r3,SPRN_LPCR
-   li  r4,(LPCR_LPES1 >> LPCR_LPES_SH)
-   bl  __init_LPCR_ISA206
-   mtlrr11
-   blr
-
-_GLOBAL(__setup_cpu_power8)
-   mflrr11
-   bl  __init_FSCR
-   bl  __init_PMU
-   bl  __init_PMU_ISA207
-   bl  __init_hvmode_206
-   mtlrr11
-   beqlr
-   li  r0,0
-   mtspr   SPRN_LPID,r0
-   LOAD_REG_IMMEDIATE(r0, PCR_MASK)
-   mtspr   SPRN_PCR,r0
-   mfspr   r3,SPRN_LPCR
-   ori r3, r3, LPCR_PECEDH
-   li  r4,0 /* LPES = 0 */
-   bl  __init_LPCR_ISA206
-   bl  __init_HFSCR
-   bl  __init_PMU_HV
-   bl  __init_PMU_HV_ISA207
-   mtlrr11
-   blr
-
-_GLOBAL(__restore_cpu_power8)
-   mflrr11
-   bl  __init_FSCR
-   bl  __init_PMU
-   bl  __init_PMU_ISA207
-   mfmsr   r3
-   rldicl. r0,r3,4,63
-   mtlrr11
-   beqlr
-   li  r0,0
-   mtspr   SPRN_LPID,r0
-   LOAD_REG_IMMEDIATE(r0, PCR_MASK)
-   mtspr   SPRN_PCR,r0
-   mfspr   r3,SPRN_LPCR
-   ori r3, r3, LPCR_PECEDH
-   li  r4,0 /* LPES = 0 */
-   bl  __init_LPCR_ISA206
-   bl  __init_HFSCR
-   bl  __init_PMU_HV
-   bl  __init_PMU_HV_ISA207
-   mtlrr11
-   blr
-
-_GLOBAL(__setup_cpu_power10)
-   mflrr11
-   bl  __init_FSCR_power10
-   bl  __init_PMU
-   bl  __init_PMU_ISA31
-   b   1f
-
-_GLOBAL(__setup_cpu_power9)
-   mflrr11
-   bl  __init_FSCR_power9
-   bl  __init_PMU
-1: bl  __init_hvmode_206
-   mtlrr11
-   beqlr
-   li  r0,0
-   mtspr   SPRN_PSSCR,r0
-   mtspr   SPRN_LPID,r0
-   mtspr   SPRN_PID,r0
-   LOAD_REG_IMMEDIATE(r0, PCR_MASK)
-   mtspr   SPRN_PCR,r0
-   mfspr   r3,SPRN_LPCR
-   LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE  | 
LPCR_HEIC)
-   or  r3, r3, r4
-  

[PATCH v3 1/2] powerpc/64: Set up a kernel stack for secondaries before cpu_restore()

2020-09-21 Thread Jordan Niethe
Currently in generic_secondary_smp_init(), cur_cpu_spec->cpu_restore()
is called before a stack has been set up in r1. This was previously fine
as the cpu_restore() functions were implemented in assembly and did not
use a stack. However commit 5a61ef74f269 ("powerpc/64s: Support new
device tree binding for discovering CPU features") used
__restore_cpu_cpufeatures() as the cpu_restore() function for a
device-tree features based cputable entry. This is a C function and
hence uses a stack in r1.

generic_secondary_smp_init() is entered on the secondary cpus via the
primary cpu using the OPAL call opal_start_cpu(). In OPAL, each hardware
thread has its own stack. The OPAL call is ran in the primary's hardware
thread. During the call, a job is scheduled on a secondary cpu that will
start executing at the address of generic_secondary_smp_init().  Hence
the value that will be left in r1 when the secondary cpu enters the
kernel is part of that secondary cpu's individual OPAL stack. This means
that __restore_cpu_cpufeatures() will write to that OPAL stack. This is
not horribly bad as each hardware thread has its own stack and the call
that enters the kernel from OPAL never returns, but it is still wrong
and should be corrected.

Create the temp kernel stack before calling cpu_restore().

As noted by mpe, for a kexec boot, the secondary CPUs are released from
the spin loop at address 0x60 by smp_release_cpus() and then jump to
generic_secondary_smp_init(). The call to smp_release_cpus() is in
setup_arch(), and it comes before the call to emergency_stack_init().
emergency_stack_init() allocates an emergency stack in the PACA for each
CPU.  This address in the PACA is what is used to set up the temp kernel
stack in generic_secondary_smp_init(). Move releasing the secondary CPUs
to after the PACAs have been allocated an emergency stack, otherwise the
PACA stack pointer will contain garbage and hence the temp kernel stack
created from it will be broken.

Fixes: 5a61ef74f269 ("powerpc/64s: Support new device tree binding for 
discovering CPU features")
Signed-off-by: Jordan Niethe 
---
v2: Add more detail to the commit message
v3: Release secondary CPUs after the emergency stack is created
---
 arch/powerpc/kernel/head_64.S  | 8 
 arch/powerpc/kernel/setup-common.c | 6 --
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 0e05a9a47a4b..4b7f4c6c2600 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -420,6 +420,10 @@ generic_secondary_common_init:
/* From now on, r24 is expected to be logical cpuid */
mr  r24,r5
 
+   /* Create a temp kernel stack for use before relocation is on.  */
+   ld  r1,PACAEMERGSP(r13)
+   subir1,r1,STACK_FRAME_OVERHEAD
+
/* See if we need to call a cpu state restore handler */
LOAD_REG_ADDR(r23, cur_cpu_spec)
ld  r23,0(r23)
@@ -448,10 +452,6 @@ generic_secondary_common_init:
sync/* order paca.run and cur_cpu_spec */
isync   /* In case code patching happened */
 
-   /* Create a temp kernel stack for use before relocation is on.  */
-   ld  r1,PACAEMERGSP(r13)
-   subir1,r1,STACK_FRAME_OVERHEAD
-
b   __secondary_start
 #endif /* SMP */
 
diff --git a/arch/powerpc/kernel/setup-common.c 
b/arch/powerpc/kernel/setup-common.c
index 808ec9fab605..fff714e36b37 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -919,8 +919,6 @@ void __init setup_arch(char **cmdline_p)
 
/* On BookE, setup per-core TLB data structures. */
setup_tlb_core_data();
-
-   smp_release_cpus();
 #endif
 
/* Print various info about the machine that has been gathered so far. 
*/
@@ -944,6 +942,10 @@ void __init setup_arch(char **cmdline_p)
exc_lvl_early_init();
emergency_stack_init();
 
+#ifdef CONFIG_SMP
+   smp_release_cpus();
+#endif
+
initmem_init();
 
early_memtest(min_low_pfn << PAGE_SHIFT, max_low_pfn << PAGE_SHIFT);
-- 
2.17.1



Re: [PATCH v2 1/2] powerpc/64: Set up a kernel stack for secondaries before cpu_restore()

2020-09-21 Thread Jordan Niethe
On Fri, Sep 18, 2020 at 5:21 PM Michael Ellerman  wrote:
>
> Hi Jordan,
>
> Jordan Niethe  writes:
> > Currently in generic_secondary_smp_init(), cur_cpu_spec->cpu_restore()
> > is called before a stack has been set up in r1. This was previously fine
> > as the cpu_restore() functions were implemented in assembly and did not
> > use a stack. However commit 5a61ef74f269 ("powerpc/64s: Support new
> > device tree binding for discovering CPU features") used
> > __restore_cpu_cpufeatures() as the cpu_restore() function for a
> > device-tree features based cputable entry. This is a C function and
> > hence uses a stack in r1.
> >
> > generic_secondary_smp_init() is entered on the secondary cpus via the
> > primary cpu using the OPAL call opal_start_cpu(). In OPAL, each hardware
> > thread has its own stack. The OPAL call is ran in the primary's hardware
> > thread. During the call, a job is scheduled on a secondary cpu that will
> > start executing at the address of generic_secondary_smp_init().  Hence
> > the value that will be left in r1 when the secondary cpu enters the
> > kernel is part of that secondary cpu's individual OPAL stack. This means
> > that __restore_cpu_cpufeatures() will write to that OPAL stack. This is
> > not horribly bad as each hardware thread has its own stack and the call
> > that enters the kernel from OPAL never returns, but it is still wrong
> > and should be corrected.
> >
> > Create the temp kernel stack before calling cpu_restore().
> >
> > Fixes: 5a61ef74f269 ("powerpc/64s: Support new device tree binding for 
> > discovering CPU features")
> > Signed-off-by: Jordan Niethe 
> > ---
> > v2: Add more detail to the commit message
> > ---
> >  arch/powerpc/kernel/head_64.S | 8 
> >  1 file changed, 4 insertions(+), 4 deletions(-)
>
> Unfortunately this breaks booting via kexec.
>
> In that case the secondaries come in to 0x60 and spin until they're
> released by smp_release_cpus(), which is before emergency_stack_init()
> has run. That means they pick up a bad r1 value and crash/get stuck.
>
> I'm not sure what the best solution is.
Would it be simplest to just call smp_release_cpus() after setting up the stack?
>
> I've thought in the past that it would be nicer if the CPU setup didn't
> run until the secondary is told to start (via PACAPROCSTART), ie. more
> the CPU setup call below there.
>
> But that opens the possibility that we run threads with different
> settings of some SPRs until SMP bringup, and if the user has said not to
> start secondaries then possibly for ever. And I haven't though hard
> enough about whether that's actually problematic (running with different
> SPR values).
>
> cheers
>
>
> > diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
> > index 0e05a9a47a4b..4b7f4c6c2600 100644
> > --- a/arch/powerpc/kernel/head_64.S
> > +++ b/arch/powerpc/kernel/head_64.S
> > @@ -420,6 +420,10 @@ generic_secondary_common_init:
> >   /* From now on, r24 is expected to be logical cpuid */
> >   mr  r24,r5
> >
> > + /* Create a temp kernel stack for use before relocation is on.  */
> > + ld  r1,PACAEMERGSP(r13)
> > + subir1,r1,STACK_FRAME_OVERHEAD
> > +
> >   /* See if we need to call a cpu state restore handler */
> >   LOAD_REG_ADDR(r23, cur_cpu_spec)
> >   ld  r23,0(r23)
> > @@ -448,10 +452,6 @@ generic_secondary_common_init:
> >   sync/* order paca.run and cur_cpu_spec */
> >   isync   /* In case code patching happened */
> >
> > - /* Create a temp kernel stack for use before relocation is on.  */
> > - ld  r1,PACAEMERGSP(r13)
> > - subir1,r1,STACK_FRAME_OVERHEAD
> > -
> >   b   __secondary_start
> >  #endif /* SMP */
> >
> > --
> > 2.17.1


[PATCH v2 2/2] powerpc/64s: Convert some cpu_setup() and cpu_restore() functions to C

2020-09-17 Thread Jordan Niethe
The only thing keeping the cpu_setup() and cpu_restore() functions used
in the cputable entries for Power7, Power8, Power9 and Power10 in
assembly was cpu_restore() being called before there was a stack in
generic_secondary_smp_init(). Commit ("powerpc/64: Set up a kernel stack
for secondaries before cpu_restore()") means that it is now possible to
use C.

Rewrite the functions in C so they are a little bit easier to read. This
is not changing their functionality.

Signed-off-by: Jordan Niethe 
---
 arch/powerpc/include/asm/cpu_setup_power.h |  12 +
 arch/powerpc/kernel/cpu_setup_power.S  | 252 ---
 arch/powerpc/kernel/cpu_setup_power.c  | 269 +
 arch/powerpc/kernel/cputable.c |   9 +-
 4 files changed, 282 insertions(+), 260 deletions(-)
 create mode 100644 arch/powerpc/include/asm/cpu_setup_power.h
 delete mode 100644 arch/powerpc/kernel/cpu_setup_power.S
 create mode 100644 arch/powerpc/kernel/cpu_setup_power.c

diff --git a/arch/powerpc/include/asm/cpu_setup_power.h 
b/arch/powerpc/include/asm/cpu_setup_power.h
new file mode 100644
index ..24be9131f803
--- /dev/null
+++ b/arch/powerpc/include/asm/cpu_setup_power.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2020 IBM Corporation
+ */
+void __setup_cpu_power7(unsigned long offset, struct cpu_spec *spec);
+void __restore_cpu_power7(void);
+void __setup_cpu_power8(unsigned long offset, struct cpu_spec *spec);
+void __restore_cpu_power8(void);
+void __setup_cpu_power9(unsigned long offset, struct cpu_spec *spec);
+void __restore_cpu_power9(void);
+void __setup_cpu_power10(unsigned long offset, struct cpu_spec *spec);
+void __restore_cpu_power10(void);
diff --git a/arch/powerpc/kernel/cpu_setup_power.S 
b/arch/powerpc/kernel/cpu_setup_power.S
deleted file mode 100644
index 704e8b9501ee..
--- a/arch/powerpc/kernel/cpu_setup_power.S
+++ /dev/null
@@ -1,252 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * This file contains low level CPU setup functions.
- *Copyright (C) 2003 Benjamin Herrenschmidt (b...@kernel.crashing.org)
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-/* Entry: r3 = crap, r4 = ptr to cputable entry
- *
- * Note that we can be called twice for pseudo-PVRs
- */
-_GLOBAL(__setup_cpu_power7)
-   mflrr11
-   bl  __init_hvmode_206
-   mtlrr11
-   beqlr
-   li  r0,0
-   mtspr   SPRN_LPID,r0
-   LOAD_REG_IMMEDIATE(r0, PCR_MASK)
-   mtspr   SPRN_PCR,r0
-   mfspr   r3,SPRN_LPCR
-   li  r4,(LPCR_LPES1 >> LPCR_LPES_SH)
-   bl  __init_LPCR_ISA206
-   mtlrr11
-   blr
-
-_GLOBAL(__restore_cpu_power7)
-   mflrr11
-   mfmsr   r3
-   rldicl. r0,r3,4,63
-   beqlr
-   li  r0,0
-   mtspr   SPRN_LPID,r0
-   LOAD_REG_IMMEDIATE(r0, PCR_MASK)
-   mtspr   SPRN_PCR,r0
-   mfspr   r3,SPRN_LPCR
-   li  r4,(LPCR_LPES1 >> LPCR_LPES_SH)
-   bl  __init_LPCR_ISA206
-   mtlrr11
-   blr
-
-_GLOBAL(__setup_cpu_power8)
-   mflrr11
-   bl  __init_FSCR
-   bl  __init_PMU
-   bl  __init_PMU_ISA207
-   bl  __init_hvmode_206
-   mtlrr11
-   beqlr
-   li  r0,0
-   mtspr   SPRN_LPID,r0
-   LOAD_REG_IMMEDIATE(r0, PCR_MASK)
-   mtspr   SPRN_PCR,r0
-   mfspr   r3,SPRN_LPCR
-   ori r3, r3, LPCR_PECEDH
-   li  r4,0 /* LPES = 0 */
-   bl  __init_LPCR_ISA206
-   bl  __init_HFSCR
-   bl  __init_PMU_HV
-   bl  __init_PMU_HV_ISA207
-   mtlrr11
-   blr
-
-_GLOBAL(__restore_cpu_power8)
-   mflrr11
-   bl  __init_FSCR
-   bl  __init_PMU
-   bl  __init_PMU_ISA207
-   mfmsr   r3
-   rldicl. r0,r3,4,63
-   mtlrr11
-   beqlr
-   li  r0,0
-   mtspr   SPRN_LPID,r0
-   LOAD_REG_IMMEDIATE(r0, PCR_MASK)
-   mtspr   SPRN_PCR,r0
-   mfspr   r3,SPRN_LPCR
-   ori r3, r3, LPCR_PECEDH
-   li  r4,0 /* LPES = 0 */
-   bl  __init_LPCR_ISA206
-   bl  __init_HFSCR
-   bl  __init_PMU_HV
-   bl  __init_PMU_HV_ISA207
-   mtlrr11
-   blr
-
-_GLOBAL(__setup_cpu_power10)
-   mflrr11
-   bl  __init_FSCR_power10
-   bl  __init_PMU
-   bl  __init_PMU_ISA31
-   b   1f
-
-_GLOBAL(__setup_cpu_power9)
-   mflrr11
-   bl  __init_FSCR_power9
-   bl  __init_PMU
-1: bl  __init_hvmode_206
-   mtlrr11
-   beqlr
-   li  r0,0
-   mtspr   SPRN_PSSCR,r0
-   mtspr   SPRN_LPID,r0
-   mtspr   SPRN_PID,r0
-   LOAD_REG_IMMEDIATE(r0, PCR_MASK)
-   mtspr   SPRN_PCR,r0
-   mfspr   r3,SPRN_LPCR
-   LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE  | 
LPCR_HEIC)
-   or  r3, r3, r4
-  

[PATCH v2 1/2] powerpc/64: Set up a kernel stack for secondaries before cpu_restore()

2020-09-17 Thread Jordan Niethe
Currently in generic_secondary_smp_init(), cur_cpu_spec->cpu_restore()
is called before a stack has been set up in r1. This was previously fine
as the cpu_restore() functions were implemented in assembly and did not
use a stack. However commit 5a61ef74f269 ("powerpc/64s: Support new
device tree binding for discovering CPU features") used
__restore_cpu_cpufeatures() as the cpu_restore() function for a
device-tree features based cputable entry. This is a C function and
hence uses a stack in r1.

generic_secondary_smp_init() is entered on the secondary cpus via the
primary cpu using the OPAL call opal_start_cpu(). In OPAL, each hardware
thread has its own stack. The OPAL call is ran in the primary's hardware
thread. During the call, a job is scheduled on a secondary cpu that will
start executing at the address of generic_secondary_smp_init().  Hence
the value that will be left in r1 when the secondary cpu enters the
kernel is part of that secondary cpu's individual OPAL stack. This means
that __restore_cpu_cpufeatures() will write to that OPAL stack. This is
not horribly bad as each hardware thread has its own stack and the call
that enters the kernel from OPAL never returns, but it is still wrong
and should be corrected.

Create the temp kernel stack before calling cpu_restore().

Fixes: 5a61ef74f269 ("powerpc/64s: Support new device tree binding for 
discovering CPU features")
Signed-off-by: Jordan Niethe 
---
v2: Add more detail to the commit message
---
 arch/powerpc/kernel/head_64.S | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 0e05a9a47a4b..4b7f4c6c2600 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -420,6 +420,10 @@ generic_secondary_common_init:
/* From now on, r24 is expected to be logical cpuid */
mr  r24,r5
 
+   /* Create a temp kernel stack for use before relocation is on.  */
+   ld  r1,PACAEMERGSP(r13)
+   subir1,r1,STACK_FRAME_OVERHEAD
+
/* See if we need to call a cpu state restore handler */
LOAD_REG_ADDR(r23, cur_cpu_spec)
ld  r23,0(r23)
@@ -448,10 +452,6 @@ generic_secondary_common_init:
sync/* order paca.run and cur_cpu_spec */
isync   /* In case code patching happened */
 
-   /* Create a temp kernel stack for use before relocation is on.  */
-   ld  r1,PACAEMERGSP(r13)
-   subir1,r1,STACK_FRAME_OVERHEAD
-
b   __secondary_start
 #endif /* SMP */
 
-- 
2.17.1



[PATCH 2/2] powerpc/64s: Convert some cpu_setup() and cpu_restore() functions to C

2020-09-16 Thread Jordan Niethe
The only thing keeping the cpu_setup() and cpu_restore() functions used
in the cputable entries for Power7, Power8, Power9 and Power10 in
assembly was cpu_restore() being called before there was a stack in
generic_secondary_smp_init(). Commit ("powerpc/64: Set up a kernel stack
for secondaries before cpu_restore()") means that it is now possible to
use C.

Rewrite the functions in C so they are a little bit easier to read. This
is not changing their functionality.

Signed-off-by: Jordan Niethe 
---
 arch/powerpc/include/asm/cpu_setup_power.h |  12 +
 arch/powerpc/kernel/cpu_setup_power.S  | 252 ---
 arch/powerpc/kernel/cpu_setup_power.c  | 269 +
 arch/powerpc/kernel/cputable.c |   9 +-
 4 files changed, 282 insertions(+), 260 deletions(-)
 create mode 100644 arch/powerpc/include/asm/cpu_setup_power.h
 delete mode 100644 arch/powerpc/kernel/cpu_setup_power.S
 create mode 100644 arch/powerpc/kernel/cpu_setup_power.c

diff --git a/arch/powerpc/include/asm/cpu_setup_power.h 
b/arch/powerpc/include/asm/cpu_setup_power.h
new file mode 100644
index ..24be9131f803
--- /dev/null
+++ b/arch/powerpc/include/asm/cpu_setup_power.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2020 IBM Corporation
+ */
+void __setup_cpu_power7(unsigned long offset, struct cpu_spec *spec);
+void __restore_cpu_power7(void);
+void __setup_cpu_power8(unsigned long offset, struct cpu_spec *spec);
+void __restore_cpu_power8(void);
+void __setup_cpu_power9(unsigned long offset, struct cpu_spec *spec);
+void __restore_cpu_power9(void);
+void __setup_cpu_power10(unsigned long offset, struct cpu_spec *spec);
+void __restore_cpu_power10(void);
diff --git a/arch/powerpc/kernel/cpu_setup_power.S 
b/arch/powerpc/kernel/cpu_setup_power.S
deleted file mode 100644
index 704e8b9501ee..
--- a/arch/powerpc/kernel/cpu_setup_power.S
+++ /dev/null
@@ -1,252 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * This file contains low level CPU setup functions.
- *Copyright (C) 2003 Benjamin Herrenschmidt (b...@kernel.crashing.org)
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-/* Entry: r3 = crap, r4 = ptr to cputable entry
- *
- * Note that we can be called twice for pseudo-PVRs
- */
-_GLOBAL(__setup_cpu_power7)
-   mflrr11
-   bl  __init_hvmode_206
-   mtlrr11
-   beqlr
-   li  r0,0
-   mtspr   SPRN_LPID,r0
-   LOAD_REG_IMMEDIATE(r0, PCR_MASK)
-   mtspr   SPRN_PCR,r0
-   mfspr   r3,SPRN_LPCR
-   li  r4,(LPCR_LPES1 >> LPCR_LPES_SH)
-   bl  __init_LPCR_ISA206
-   mtlrr11
-   blr
-
-_GLOBAL(__restore_cpu_power7)
-   mflrr11
-   mfmsr   r3
-   rldicl. r0,r3,4,63
-   beqlr
-   li  r0,0
-   mtspr   SPRN_LPID,r0
-   LOAD_REG_IMMEDIATE(r0, PCR_MASK)
-   mtspr   SPRN_PCR,r0
-   mfspr   r3,SPRN_LPCR
-   li  r4,(LPCR_LPES1 >> LPCR_LPES_SH)
-   bl  __init_LPCR_ISA206
-   mtlrr11
-   blr
-
-_GLOBAL(__setup_cpu_power8)
-   mflrr11
-   bl  __init_FSCR
-   bl  __init_PMU
-   bl  __init_PMU_ISA207
-   bl  __init_hvmode_206
-   mtlrr11
-   beqlr
-   li  r0,0
-   mtspr   SPRN_LPID,r0
-   LOAD_REG_IMMEDIATE(r0, PCR_MASK)
-   mtspr   SPRN_PCR,r0
-   mfspr   r3,SPRN_LPCR
-   ori r3, r3, LPCR_PECEDH
-   li  r4,0 /* LPES = 0 */
-   bl  __init_LPCR_ISA206
-   bl  __init_HFSCR
-   bl  __init_PMU_HV
-   bl  __init_PMU_HV_ISA207
-   mtlrr11
-   blr
-
-_GLOBAL(__restore_cpu_power8)
-   mflrr11
-   bl  __init_FSCR
-   bl  __init_PMU
-   bl  __init_PMU_ISA207
-   mfmsr   r3
-   rldicl. r0,r3,4,63
-   mtlrr11
-   beqlr
-   li  r0,0
-   mtspr   SPRN_LPID,r0
-   LOAD_REG_IMMEDIATE(r0, PCR_MASK)
-   mtspr   SPRN_PCR,r0
-   mfspr   r3,SPRN_LPCR
-   ori r3, r3, LPCR_PECEDH
-   li  r4,0 /* LPES = 0 */
-   bl  __init_LPCR_ISA206
-   bl  __init_HFSCR
-   bl  __init_PMU_HV
-   bl  __init_PMU_HV_ISA207
-   mtlrr11
-   blr
-
-_GLOBAL(__setup_cpu_power10)
-   mflrr11
-   bl  __init_FSCR_power10
-   bl  __init_PMU
-   bl  __init_PMU_ISA31
-   b   1f
-
-_GLOBAL(__setup_cpu_power9)
-   mflrr11
-   bl  __init_FSCR_power9
-   bl  __init_PMU
-1: bl  __init_hvmode_206
-   mtlrr11
-   beqlr
-   li  r0,0
-   mtspr   SPRN_PSSCR,r0
-   mtspr   SPRN_LPID,r0
-   mtspr   SPRN_PID,r0
-   LOAD_REG_IMMEDIATE(r0, PCR_MASK)
-   mtspr   SPRN_PCR,r0
-   mfspr   r3,SPRN_LPCR
-   LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE  | 
LPCR_HEIC)
-   or  r3, r3, r4
-  

[PATCH 1/2] powerpc/64: Set up a kernel stack for secondaries before cpu_restore()

2020-09-16 Thread Jordan Niethe
Currently in generic_secondary_smp_init(), cur_cpu_spec->cpu_restore()
is called before a stack has been set up in r1. This was previously fine
as the cpu_restore() functions were implemented in assembly and did not
use a stack. However commit 5a61ef74f269 ("powerpc/64s: Support new
device tree binding for discovering CPU features") used
__restore_cpu_cpufeatures() as the cpu_restore() function for a
device-tree features based cputable entry.  This is a nonleaf C function
and hence requires a stack in r1.

Create the temp kernel stack before calling cpu_restore().

Fixes: 5a61ef74f269 ("powerpc/64s: Support new device tree binding for 
discovering CPU features")
Signed-off-by: Jordan Niethe 
---
 arch/powerpc/kernel/head_64.S | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 0e05a9a47a4b..4b7f4c6c2600 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -420,6 +420,10 @@ generic_secondary_common_init:
/* From now on, r24 is expected to be logical cpuid */
mr  r24,r5
 
+   /* Create a temp kernel stack for use before relocation is on.  */
+   ld  r1,PACAEMERGSP(r13)
+   subir1,r1,STACK_FRAME_OVERHEAD
+
/* See if we need to call a cpu state restore handler */
LOAD_REG_ADDR(r23, cur_cpu_spec)
ld  r23,0(r23)
@@ -448,10 +452,6 @@ generic_secondary_common_init:
sync/* order paca.run and cur_cpu_spec */
isync   /* In case code patching happened */
 
-   /* Create a temp kernel stack for use before relocation is on.  */
-   ld  r1,PACAEMERGSP(r13)
-   subir1,r1,STACK_FRAME_OVERHEAD
-
b   __secondary_start
 #endif /* SMP */
 
-- 
2.17.1



Re: [RFC PATCH 2/2] KVM: PPC: Book3S HV: Support prefixed instructions

2020-09-02 Thread Jordan Niethe
On Wed, Sep 2, 2020 at 4:18 PM Paul Mackerras  wrote:
>
> On Thu, Aug 20, 2020 at 01:39:22PM +1000, Jordan Niethe wrote:
> > There are two main places where instructions are loaded from the guest:
> > * Emulate loadstore - such as when performing MMIO emulation
> >   triggered by an HDSI
> > * After an HV emulation assistance interrupt (e40)
> >
> > If it is a prefixed instruction that triggers these cases, its suffix
> > must be loaded. Use the SRR1_PREFIX bit to decide if a suffix needs to
> > be loaded. Make sure if this bit is set inject_interrupt() also sets it
> > when giving an interrupt to the guest.
> >
> > ISA v3.10 extends the Hypervisor Emulation Instruction Register (HEIR)
> > to 64 bits long to accommodate prefixed instructions. For interrupts
> > caused by a word instruction the instruction is loaded into bits 32:63
> > and bits 0:31 are zeroed. When caused by a prefixed instruction the
> > prefix and suffix are loaded into bits 0:63.
> >
> > Signed-off-by: Jordan Niethe 
> > ---
> >  arch/powerpc/kvm/book3s.c   | 15 +--
> >  arch/powerpc/kvm/book3s_64_mmu_hv.c | 10 +++---
> >  arch/powerpc/kvm/book3s_hv_builtin.c|  3 +++
> >  arch/powerpc/kvm/book3s_hv_rmhandlers.S | 14 ++
> >  4 files changed, 37 insertions(+), 5 deletions(-)
> >
> > diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
> > index 70d8967acc9b..18b1928a571b 100644
> > --- a/arch/powerpc/kvm/book3s.c
> > +++ b/arch/powerpc/kvm/book3s.c
> > @@ -456,13 +456,24 @@ int kvmppc_load_last_inst(struct kvm_vcpu *vcpu,
> >  {
> >   ulong pc = kvmppc_get_pc(vcpu);
> >   u32 word;
> > + u64 doubleword;
> >   int r;
> >
> >   if (type == INST_SC)
> >   pc -= 4;
> >
> > - r = kvmppc_ld(vcpu, , sizeof(u32), , false);
> > - *inst = ppc_inst(word);
> > + if ((kvmppc_get_msr(vcpu) & SRR1_PREFIXED)) {
> > + r = kvmppc_ld(vcpu, , sizeof(u64), , false);
>
> Should we also have a check here that the doubleword is not crossing a
> page boundary?  I can't think of a way to get this code to cross a
> page boundary, assuming the hardware is working correctly, but it
> makes me just a little nervous.
I didn't think it could happen but I will add a check to be safe.
>
> > +#ifdef CONFIG_CPU_LITTLE_ENDIAN
> > + *inst = ppc_inst_prefix(doubleword & 0x, doubleword 
> > >> 32);
> > +#else
> > + *inst = ppc_inst_prefix(doubleword >> 32, doubleword & 
> > 0x);
> > +#endif
>
> Ick.  Is there a cleaner way to do this?
Would it be nicer to read the prefix as u32 then the suffix as a u32 too?
>
> > + } else {
> > + r = kvmppc_ld(vcpu, , sizeof(u32), , false);
> > + *inst = ppc_inst(word);
> > + }
> > +
> >   if (r == EMULATE_DONE)
> >   return r;
> >   else
> > diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c 
> > b/arch/powerpc/kvm/book3s_64_mmu_hv.c
> > index 775ce41738ce..0802471f4856 100644
> > --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
> > +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
> > @@ -411,9 +411,13 @@ static int instruction_is_store(struct ppc_inst instr)
> >   unsigned int mask;
> >
> >   mask = 0x1000;
> > - if ((ppc_inst_val(instr) & 0xfc00) == 0x7c00)
> > - mask = 0x100;   /* major opcode 31 */
> > - return (ppc_inst_val(instr) & mask) != 0;
> > + if (ppc_inst_prefixed(instr)) {
> > + return (ppc_inst_suffix(instr) & mask) != 0;
> > + } else {
> > + if ((ppc_inst_val(instr) & 0xfc00) == 0x7c00)
> > + mask = 0x100;   /* major opcode 31 */
> > + return (ppc_inst_val(instr) & mask) != 0;
> > + }
>
> The way the code worked before, the mask depended on whether the
> instruction was a D-form (or DS-form or other variant) instruction,
> where you can tell loads and stores apart by looking at the major
> opcode, or an X-form instruction, where you look at the minor opcode.
>
> Now we are only looking at the minor opcode if it is not a prefixed
> instruction.  Are there no X-form prefixed loads or stores?
I could not see an X-form load/stores so I went with just that.
But checking the ISA it does mention  "..X-form instructions that are
preceded by an MLS-form or MMLS-form prefix..." so I shall use the
other mask too.
>
> Paul.
Thank you for the comments and suggestions.


Re: [RFC PATCH 1/2] KVM: PPC: Use the ppc_inst type

2020-09-02 Thread Jordan Niethe
On Wed, Sep 2, 2020 at 4:18 PM Paul Mackerras  wrote:
>
> On Thu, Aug 20, 2020 at 01:39:21PM +1000, Jordan Niethe wrote:
> > The ppc_inst type was added to help cope with the addition of prefixed
> > instructions to the ISA. Convert KVM to use this new type for dealing
> > wiht instructions. For now do not try to add further support for
> > prefixed instructions.
>
> This change does seem to splatter itself across a lot of code that
> mostly or exclusively runs on machines which are not POWER10 and will
> never need to handle prefixed instructions, unfortunately.  I wonder
> if there is a less invasive way to approach this.
Something less invasive would be good.
>
> In particular we are inflicting this 64-bit struct on 32-bit platforms
> unnecessarily (I assume, correct me if I am wrong here).
No, that is something that I wanted to to avoid, on 32 bit platforms
it is a 32bit struct:

struct ppc_inst {
u32 val;
#ifdef CONFIG_PPC64
u32 suffix;
#endif
} __packed;
>
> How would it be to do something like:
>
> typedef unsigned long ppc_inst_t;
>
> so it is 32 bits on 32-bit platforms and 64 bits on 64-bit platforms,
> and then use that instead of 'struct ppc_inst'?  You would still need
> to change the function declarations but I think most of the function
> bodies would not need to be changed.  In particular you would avoid a
> lot of the churn related to having to add ppc_inst_val() and suchlike.

Would the idea be to get rid of `struct ppc_inst` entirely or just not
use it in kvm?
In an earlier series I did something similar (at least code shared
between 32bit and 64bit would need helpers, but 32bit only code need
not change):

#ifdef __powerpc64__

typedef struct ppc_inst {
union {
struct {
u32 word;
u32 pad;
} __packed;
struct {
u32 prefix;
u32 suffix;
} __packed;
};
} ppc_inst;

#else /* !__powerpc64__ */

typedef u32 ppc_inst;
#endif

However mpe wanted to avoid using a typedef
(https://patchwork.ozlabs.org/comment/2391845/)

We did also talk about just using a u64 for instructions
(https://lore.kernel.org/linuxppc-dev/1585028462.t27rstc2uf.astr...@bobo.none/)
but the concern was that as prefixed instructions act as two separate
u32s (prefix is always before the suffix regardless of endianess)
keeping it as a u64 would lead to lot of macros and potential
confusion.
But it does seem if that can avoid a lot of needless churn it might
worth the trade off.
>
> > -static inline unsigned make_dsisr(unsigned instr)
> > +static inline unsigned make_dsisr(struct ppc_inst instr)
> >  {
> >   unsigned dsisr;
> > + u32 word = ppc_inst_val(instr);
> >
> >
> >   /* bits  6:15 --> 22:31 */
> > - dsisr = (instr & 0x03ff) >> 16;
> > + dsisr = (word & 0x03ff) >> 16;
> >
> >   if (IS_XFORM(instr)) {
> >   /* bits 29:30 --> 15:16 */
> > - dsisr |= (instr & 0x0006) << 14;
> > + dsisr |= (word & 0x0006) << 14;
> >   /* bit 25 -->17 */
> > - dsisr |= (instr & 0x0040) << 8;
> > + dsisr |= (word & 0x0040) << 8;
> >   /* bits 21:24 --> 18:21 */
> > - dsisr |= (instr & 0x0780) << 3;
> > + dsisr |= (word & 0x0780) << 3;
> >   } else {
> >   /* bit  5 -->17 */
> > - dsisr |= (instr & 0x0400) >> 12;
> > + dsisr |= (word & 0x0400) >> 12;
> >   /* bits  1: 4 --> 18:21 */
> > - dsisr |= (instr & 0x7800) >> 17;
> > + dsisr |= (word & 0x7800) >> 17;
> >   /* bits 30:31 --> 12:13 */
> >   if (IS_DSFORM(instr))
> > - dsisr |= (instr & 0x0003) << 18;
> > + dsisr |= (word & 0x0003) << 18;
>
> Here I would have done something like:
>
> > -static inline unsigned make_dsisr(unsigned instr)
> > +static inline unsigned make_dsisr(struct ppc_inst pi)
> >  {
> >   unsigned dsisr;
> > + u32 instr = ppc_inst_val(pi);
>
> and left the rest of the function unchanged.
That is better.
>
> At first I wondered why we still had that function, since IBM Power
> CPUs have not set DSISR on an alignment interrupt since POWER3 days.
> It turns out it this function is used by PR KVM when it is emulating
> one of the old 32-bit PowerPC CPUs (601, 603, 604, 750, 7450 etc.).
>
> > diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
>
> Despite the file name, this code is not used on IBM Power servers.
> It is for platforms which run under an ePAPR (not server PAPR)
> hypervisor (which would be a KVM variant, but generally book E KVM not
> book 3S).
>
> Paul.


Re: [PATCH v2] powerpc: Update documentation of ISA versions for Power10

2020-08-26 Thread Jordan Niethe
On Thu, Aug 27, 2020 at 2:49 PM Christophe Leroy
 wrote:
>
>
>
> Le 27/08/2020 à 06:05, Jordan Niethe a écrit :
> > Update the CPU to ISA Version Mapping document to include Power10 and
> > ISA v3.1.
>
> Maybe Documentation/powerpc/cpu_families.rst should be updated as well.
Good idea it still needs Power9 too.
>
> Christophe
>
>
>
> >
> > Signed-off-by: Jordan Niethe 
> > ---
> > v2: Transactional Memory = No
> > ---
> >   Documentation/powerpc/isa-versions.rst | 4 
> >   1 file changed, 4 insertions(+)
> >
> > diff --git a/Documentation/powerpc/isa-versions.rst 
> > b/Documentation/powerpc/isa-versions.rst
> > index a363d8c1603c..3873bbba183a 100644
> > --- a/Documentation/powerpc/isa-versions.rst
> > +++ b/Documentation/powerpc/isa-versions.rst
> > @@ -7,6 +7,7 @@ Mapping of some CPU versions to relevant ISA versions.
> >   = 
> > 
> >   CPU   Architecture version
> >   = 
> > 
> > +Power10   Power ISA v3.1
> >   Power9Power ISA v3.0B
> >   Power8Power ISA v2.07
> >   Power7Power ISA v2.06
> > @@ -32,6 +33,7 @@ Key Features
> >   == ==
> >   CPUVMX (aka. Altivec)
> >   == ==
> > +Power10Yes
> >   Power9 Yes
> >   Power8 Yes
> >   Power7 Yes
> > @@ -47,6 +49,7 @@ PPC970 Yes
> >   == 
> >   CPUVSX
> >   == 
> > +Power10Yes
> >   Power9 Yes
> >   Power8 Yes
> >   Power7 Yes
> > @@ -62,6 +65,7 @@ PPC970 No
> >   == 
> >   CPUTransactional Memory
> >   == 
> > +Power10No  (* see Power ISA v3.1 Appendix A.)
> >   Power9 Yes (* see transactional_memory.txt)
> >   Power8 Yes
> >   Power7 No
> >


[PATCH v2] powerpc: Update documentation of ISA versions for Power10

2020-08-26 Thread Jordan Niethe
Update the CPU to ISA Version Mapping document to include Power10 and
ISA v3.1.

Signed-off-by: Jordan Niethe 
---
v2: Transactional Memory = No
---
 Documentation/powerpc/isa-versions.rst | 4 
 1 file changed, 4 insertions(+)

diff --git a/Documentation/powerpc/isa-versions.rst 
b/Documentation/powerpc/isa-versions.rst
index a363d8c1603c..3873bbba183a 100644
--- a/Documentation/powerpc/isa-versions.rst
+++ b/Documentation/powerpc/isa-versions.rst
@@ -7,6 +7,7 @@ Mapping of some CPU versions to relevant ISA versions.
 = 
 CPU   Architecture version
 = 
+Power10   Power ISA v3.1
 Power9Power ISA v3.0B
 Power8Power ISA v2.07
 Power7Power ISA v2.06
@@ -32,6 +33,7 @@ Key Features
 == ==
 CPUVMX (aka. Altivec)
 == ==
+Power10Yes
 Power9 Yes
 Power8 Yes
 Power7 Yes
@@ -47,6 +49,7 @@ PPC970 Yes
 == 
 CPUVSX
 == 
+Power10Yes
 Power9 Yes
 Power8 Yes
 Power7 Yes
@@ -62,6 +65,7 @@ PPC970 No
 == 
 CPUTransactional Memory
 == 
+Power10No  (* see Power ISA v3.1 Appendix A.)
 Power9 Yes (* see transactional_memory.txt)
 Power8 Yes
 Power7 No
-- 
2.17.1



[PATCH] powerpc/64s: Remove TM from Power10 features

2020-08-26 Thread Jordan Niethe
ISA v3.1 removes transactional memory and hence it should not be present
in cpu_features or cpu_user_features2. Remove CPU_FTR_TM_COMP from
CPU_FTRS_POWER10. Remove PPC_FEATURE2_HTM_COMP and
PPC_FEATURE2_HTM_NOSC_COMP from COMMON_USER2_POWER10.

Fixes: a3ea40d5c736 ("powerpc: Add POWER10 architected mode")
Signed-off-by: Jordan Niethe 
---
 arch/powerpc/include/asm/cputable.h |  2 +-
 arch/powerpc/kernel/cputable.c  | 13 ++---
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/include/asm/cputable.h 
b/arch/powerpc/include/asm/cputable.h
index fdddb822d564..5322fec6d413 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -478,7 +478,7 @@ static inline void cpu_feature_keys_init(void) { }
CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_ARCH_207S | \
-   CPU_FTR_TM_COMP | CPU_FTR_ARCH_300 | CPU_FTR_ARCH_31 | \
+   CPU_FTR_ARCH_300 | CPU_FTR_ARCH_31 | \
CPU_FTR_DAWR | CPU_FTR_DAWR1)
 #define CPU_FTRS_CELL  (CPU_FTR_LWSYNC | \
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 2f10a874e849..23f9bb51edc3 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -123,9 +123,16 @@ extern void __restore_cpu_e6500(void);
 PPC_FEATURE2_DARN | \
 PPC_FEATURE2_SCV)
 #define COMMON_USER_POWER10COMMON_USER_POWER9
-#define COMMON_USER2_POWER10   (COMMON_USER2_POWER9 | \
-PPC_FEATURE2_ARCH_3_1 | \
-PPC_FEATURE2_MMA)
+#define COMMON_USER2_POWER10   (PPC_FEATURE2_ARCH_3_1 | \
+PPC_FEATURE2_MMA | \
+PPC_FEATURE2_ARCH_3_00 | \
+PPC_FEATURE2_HAS_IEEE128 | \
+PPC_FEATURE2_DARN | \
+PPC_FEATURE2_SCV | \
+PPC_FEATURE2_ARCH_2_07 | \
+PPC_FEATURE2_DSCR | \
+PPC_FEATURE2_ISEL | PPC_FEATURE2_TAR | \
+PPC_FEATURE2_VEC_CRYPTO)
 
 #ifdef CONFIG_PPC_BOOK3E_64
 #define COMMON_USER_BOOKE  (COMMON_USER_PPC64 | PPC_FEATURE_BOOKE)
-- 
2.17.1



Re: [PATCH] selftests/powerpc: Fix prefixes in alignment_handler signal handler

2020-08-26 Thread Jordan Niethe
On Mon, Aug 24, 2020 at 11:12 PM Jordan Niethe  wrote:
>
> The signal handler in the alignment handler self test has the ability to
> jump over the instruction that triggered the signal. It does this by
> incrementing the PT_NIP in the user context by 4. If it were a prefixed
> instruction this will mean that the suffix is then executed which is
> incorrect. Instead check if the major opcode indicates a prefixed
> instruction (e.g. it is 1) and if so increment PT_NIP by 8.
>
> If ISA v3.1 is not available treat it as a word instruction even if the
> major opcode is 1.
>
> Fixes: 620a6473df36 ("selftests/powerpc: Add prefixed loads/stores to
> alignment_handler test")
> Signed-off-by: Jordan Niethe 
> ---
>  .../selftests/powerpc/alignment/alignment_handler.c   | 11 ++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/tools/testing/selftests/powerpc/alignment/alignment_handler.c 
> b/tools/testing/selftests/powerpc/alignment/alignment_handler.c
> index 55ef15184057..c197ff828120 100644
> --- a/tools/testing/selftests/powerpc/alignment/alignment_handler.c
> +++ b/tools/testing/selftests/powerpc/alignment/alignment_handler.c
> @@ -64,12 +64,14 @@ int bufsize;
>  int debug;
>  int testing;
>  volatile int gotsig;
> +bool haveprefixes;
>  char *cipath = "/dev/fb0";
>  long cioffset;
>
>  void sighandler(int sig, siginfo_t *info, void *ctx)
>  {
> ucontext_t *ucp = ctx;
> +   u32 inst;
Oh this should be befine __powerpc64__/CONFIG_PPC64 (thank you patchwork).
>
> if (!testing) {
> signal(sig, SIG_DFL);
> @@ -77,7 +79,12 @@ void sighandler(int sig, siginfo_t *info, void *ctx)
> }
> gotsig = sig;
>  #ifdef __powerpc64__
> -   ucp->uc_mcontext.gp_regs[PT_NIP] += 4;
> +   if (haveprefixes) {
> +   inst = *(u32 *)ucp->uc_mcontext.gp_regs[PT_NIP];
> +   ucp->uc_mcontext.gp_regs[PT_NIP] += ((inst >> 26 == 1) ? 8 : 
> 4);
> +   } else {
> +   ucp->uc_mcontext.gp_regs[PT_NIP] += 4;
> +   }
>  #else
> ucp->uc_mcontext.uc_regs->gregs[PT_NIP] += 4;
>  #endif
> @@ -648,6 +655,8 @@ int main(int argc, char *argv[])
> exit(1);
> }
>
> +   haveprefixes = have_hwcap2(PPC_FEATURE2_ARCH_3_1);
> +
> rc |= test_harness(test_alignment_handler_vsx_206,
>"test_alignment_handler_vsx_206");
> rc |= test_harness(test_alignment_handler_vsx_207,
> --
> 2.17.1
>


Re: [PATCH] powerpc: Update documentation of ISA versions for Power10

2020-08-25 Thread Jordan Niethe
On Tue, Aug 25, 2020 at 10:41 PM Gabriel Paubert  wrote:
>
> On Tue, Aug 25, 2020 at 09:45:07PM +1000, Jordan Niethe wrote:
> > Update the CPU to ISA Version Mapping document to include Power10 and
> > ISA v3.1.
> >
> > Signed-off-by: Jordan Niethe 
> > ---
> >  Documentation/powerpc/isa-versions.rst | 4 
> >  1 file changed, 4 insertions(+)
> >
> > diff --git a/Documentation/powerpc/isa-versions.rst 
> > b/Documentation/powerpc/isa-versions.rst
> > index a363d8c1603c..72aff1eaaea1 100644
> > --- a/Documentation/powerpc/isa-versions.rst
> > +++ b/Documentation/powerpc/isa-versions.rst
> > @@ -7,6 +7,7 @@ Mapping of some CPU versions to relevant ISA versions.
> >  = 
> > 
> >  CPU   Architecture version
> >  = 
> > 
> > +Power10   Power ISA v3.1
> >  Power9Power ISA v3.0B
> >  Power8Power ISA v2.07
> >  Power7Power ISA v2.06
> > @@ -32,6 +33,7 @@ Key Features
> >  == ==
> >  CPUVMX (aka. Altivec)
> >  == ==
> > +Power10Yes
> >  Power9 Yes
> >  Power8 Yes
> >  Power7 Yes
> > @@ -47,6 +49,7 @@ PPC970 Yes
> >  == 
> >  CPUVSX
> >  == 
> > +Power10Yes
> >  Power9 Yes
> >  Power8 Yes
> >  Power7 Yes
> > @@ -62,6 +65,7 @@ PPC970 No
> >  == 
> >  CPUTransactional Memory
> >  == 
> > +Power10Yes
> >  Power9 Yes (* see transactional_memory.txt)
> >  Power8 Yes
> >  Power7 No
>
> Huh?
>
> Transactional memory has been removed from the architecture for Power10.
Yeah you're right, I confused myself looking at CPU_FTRS_POWER10...
#define CPU_FTRS_POWER10 (CPU_FTR_LWSYNC | \
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\
CPU_FTR_MMCRA | CPU_FTR_SMT | \
CPU_FTR_COHERENT_ICACHE | \
CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
CPU_FTR_DSCR | \
CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_ARCH_207S | \
CPU_FTR_TM_COMP | CPU_FTR_ARCH_300 | CPU_FTR_ARCH_31 | \
CPU_FTR_DAWR | CPU_FTR_DAWR1)

CPU_FTR_TM_COMP should not be in there.

>
> Gabriel
>
>


[PATCH] powerpc: Update documentation of ISA versions for Power10

2020-08-25 Thread Jordan Niethe
Update the CPU to ISA Version Mapping document to include Power10 and
ISA v3.1.

Signed-off-by: Jordan Niethe 
---
 Documentation/powerpc/isa-versions.rst | 4 
 1 file changed, 4 insertions(+)

diff --git a/Documentation/powerpc/isa-versions.rst 
b/Documentation/powerpc/isa-versions.rst
index a363d8c1603c..72aff1eaaea1 100644
--- a/Documentation/powerpc/isa-versions.rst
+++ b/Documentation/powerpc/isa-versions.rst
@@ -7,6 +7,7 @@ Mapping of some CPU versions to relevant ISA versions.
 = 
 CPU   Architecture version
 = 
+Power10   Power ISA v3.1
 Power9Power ISA v3.0B
 Power8Power ISA v2.07
 Power7Power ISA v2.06
@@ -32,6 +33,7 @@ Key Features
 == ==
 CPUVMX (aka. Altivec)
 == ==
+Power10Yes
 Power9 Yes
 Power8 Yes
 Power7 Yes
@@ -47,6 +49,7 @@ PPC970 Yes
 == 
 CPUVSX
 == 
+Power10Yes
 Power9 Yes
 Power8 Yes
 Power7 Yes
@@ -62,6 +65,7 @@ PPC970 No
 == 
 CPUTransactional Memory
 == 
+Power10Yes
 Power9 Yes (* see transactional_memory.txt)
 Power8 Yes
 Power7 No
-- 
2.17.1



[PATCH] powerpc/boot: Update Makefile comment for 64bit wrapper

2020-08-24 Thread Jordan Niethe
As of commit 147c05168fc8 ("powerpc/boot: Add support for 64bit little
endian wrapper") the comment in the Makefile is misleading. The wrapper
packaging 64bit kernel may built as a 32 or 64 bit elf. Update the
comment to reflect this.

Signed-off-by: Jordan Niethe 
---
 arch/powerpc/boot/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index b88fd27a45f0..f8ce6d2dde7b 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -7,7 +7,7 @@
 # Based on coffboot by Paul Mackerras
 # Simplified for ppc64 by Todd Inglett
 #
-# NOTE:this code is built for 32 bit in ELF32 format even though
+# NOTE:this code may be built for 32 bit in ELF32 format even though
 #  it packages a 64 bit kernel.  We do this to simplify the
 #  bootloader and increase compatibility with OpenFirmware.
 #
-- 
2.17.1



[PATCH] selftests/powerpc: Fix prefixes in alignment_handler signal handler

2020-08-24 Thread Jordan Niethe
The signal handler in the alignment handler self test has the ability to
jump over the instruction that triggered the signal. It does this by
incrementing the PT_NIP in the user context by 4. If it were a prefixed
instruction this will mean that the suffix is then executed which is
incorrect. Instead check if the major opcode indicates a prefixed
instruction (e.g. it is 1) and if so increment PT_NIP by 8.

If ISA v3.1 is not available treat it as a word instruction even if the
major opcode is 1.

Fixes: 620a6473df36 ("selftests/powerpc: Add prefixed loads/stores to
alignment_handler test")
Signed-off-by: Jordan Niethe 
---
 .../selftests/powerpc/alignment/alignment_handler.c   | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/powerpc/alignment/alignment_handler.c 
b/tools/testing/selftests/powerpc/alignment/alignment_handler.c
index 55ef15184057..c197ff828120 100644
--- a/tools/testing/selftests/powerpc/alignment/alignment_handler.c
+++ b/tools/testing/selftests/powerpc/alignment/alignment_handler.c
@@ -64,12 +64,14 @@ int bufsize;
 int debug;
 int testing;
 volatile int gotsig;
+bool haveprefixes;
 char *cipath = "/dev/fb0";
 long cioffset;
 
 void sighandler(int sig, siginfo_t *info, void *ctx)
 {
ucontext_t *ucp = ctx;
+   u32 inst;
 
if (!testing) {
signal(sig, SIG_DFL);
@@ -77,7 +79,12 @@ void sighandler(int sig, siginfo_t *info, void *ctx)
}
gotsig = sig;
 #ifdef __powerpc64__
-   ucp->uc_mcontext.gp_regs[PT_NIP] += 4;
+   if (haveprefixes) {
+   inst = *(u32 *)ucp->uc_mcontext.gp_regs[PT_NIP];
+   ucp->uc_mcontext.gp_regs[PT_NIP] += ((inst >> 26 == 1) ? 8 : 4);
+   } else {
+   ucp->uc_mcontext.gp_regs[PT_NIP] += 4;
+   }
 #else
ucp->uc_mcontext.uc_regs->gregs[PT_NIP] += 4;
 #endif
@@ -648,6 +655,8 @@ int main(int argc, char *argv[])
exit(1);
}
 
+   haveprefixes = have_hwcap2(PPC_FEATURE2_ARCH_3_1);
+
rc |= test_harness(test_alignment_handler_vsx_206,
   "test_alignment_handler_vsx_206");
rc |= test_harness(test_alignment_handler_vsx_207,
-- 
2.17.1



[RFC PATCH 2/2] KVM: PPC: Book3S HV: Support prefixed instructions

2020-08-19 Thread Jordan Niethe
There are two main places where instructions are loaded from the guest:
* Emulate loadstore - such as when performing MMIO emulation
  triggered by an HDSI
* After an HV emulation assistance interrupt (e40)

If it is a prefixed instruction that triggers these cases, its suffix
must be loaded. Use the SRR1_PREFIX bit to decide if a suffix needs to
be loaded. Make sure if this bit is set inject_interrupt() also sets it
when giving an interrupt to the guest.

ISA v3.10 extends the Hypervisor Emulation Instruction Register (HEIR)
to 64 bits long to accommodate prefixed instructions. For interrupts
caused by a word instruction the instruction is loaded into bits 32:63
and bits 0:31 are zeroed. When caused by a prefixed instruction the
prefix and suffix are loaded into bits 0:63.

Signed-off-by: Jordan Niethe 
---
 arch/powerpc/kvm/book3s.c   | 15 +--
 arch/powerpc/kvm/book3s_64_mmu_hv.c | 10 +++---
 arch/powerpc/kvm/book3s_hv_builtin.c|  3 +++
 arch/powerpc/kvm/book3s_hv_rmhandlers.S | 14 ++
 4 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 70d8967acc9b..18b1928a571b 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -456,13 +456,24 @@ int kvmppc_load_last_inst(struct kvm_vcpu *vcpu,
 {
ulong pc = kvmppc_get_pc(vcpu);
u32 word;
+   u64 doubleword;
int r;
 
if (type == INST_SC)
pc -= 4;
 
-   r = kvmppc_ld(vcpu, , sizeof(u32), , false);
-   *inst = ppc_inst(word);
+   if ((kvmppc_get_msr(vcpu) & SRR1_PREFIXED)) {
+   r = kvmppc_ld(vcpu, , sizeof(u64), , false);
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+   *inst = ppc_inst_prefix(doubleword & 0x, doubleword >> 
32);
+#else
+   *inst = ppc_inst_prefix(doubleword >> 32, doubleword & 
0x);
+#endif
+   } else {
+   r = kvmppc_ld(vcpu, , sizeof(u32), , false);
+   *inst = ppc_inst(word);
+   }
+
if (r == EMULATE_DONE)
return r;
else
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c 
b/arch/powerpc/kvm/book3s_64_mmu_hv.c
index 775ce41738ce..0802471f4856 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -411,9 +411,13 @@ static int instruction_is_store(struct ppc_inst instr)
unsigned int mask;
 
mask = 0x1000;
-   if ((ppc_inst_val(instr) & 0xfc00) == 0x7c00)
-   mask = 0x100;   /* major opcode 31 */
-   return (ppc_inst_val(instr) & mask) != 0;
+   if (ppc_inst_prefixed(instr)) {
+   return (ppc_inst_suffix(instr) & mask) != 0;
+   } else {
+   if ((ppc_inst_val(instr) & 0xfc00) == 0x7c00)
+   mask = 0x100;   /* major opcode 31 */
+   return (ppc_inst_val(instr) & mask) != 0;
+   }
 }
 
 int kvmppc_hv_emulate_mmio(struct kvm_vcpu *vcpu,
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c 
b/arch/powerpc/kvm/book3s_hv_builtin.c
index 073617ce83e0..41e07e63104b 100644
--- a/arch/powerpc/kvm/book3s_hv_builtin.c
+++ b/arch/powerpc/kvm/book3s_hv_builtin.c
@@ -807,6 +807,9 @@ static void inject_interrupt(struct kvm_vcpu *vcpu, int 
vec, u64 srr1_flags)
new_pc += 0xC0004000ULL;
}
 
+   if (msr & SRR1_PREFIXED)
+   srr1_flags |= SRR1_PREFIXED;
+
kvmppc_set_srr0(vcpu, pc);
kvmppc_set_srr1(vcpu, (msr & SRR1_MSR_BITS) | srr1_flags);
kvmppc_set_pc(vcpu, new_pc);
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S 
b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 4853b3444c5f..f2a609413621 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -1365,6 +1365,16 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
cmpwi   r12,BOOK3S_INTERRUPT_H_EMUL_ASSIST
bne 11f
mfspr   r3,SPRN_HEIR
+   andis.  r0,r11,SRR1_PREFIXED@h
+   cmpwi   r0,0
+   beq 12f
+   rldicl  r4,r3,0,32  /* Suffix */
+   srdir3,r3,32/* Prefix */
+   b   11f
+12:
+BEGIN_FTR_SECTION
+   rldicl  r3,r3,0,32  /* Word */
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_31)
 11:stw r3,VCPU_HEIR(r9)
stw r4,VCPU_HEIR+4(r9)
 
@@ -2175,6 +2185,10 @@ fast_interrupt_c_return:
ori r4, r3, MSR_DR  /* Enable paging for data */
mtmsrd  r4
lwz r8, 0(r10)
+   andis.  r7, r11, SRR1_PREFIXED@h
+   cmpwi   r7,0
+   beq +4
+   lwz r5, 4(r10)
mtmsrd  r3
 
/* Store the result */
-- 
2.17.1



[RFC PATCH 1/2] KVM: PPC: Use the ppc_inst type

2020-08-19 Thread Jordan Niethe
The ppc_inst type was added to help cope with the addition of prefixed
instructions to the ISA. Convert KVM to use this new type for dealing
wiht instructions. For now do not try to add further support for
prefixed instructions.

Signed-off-by: Jordan Niethe 
---
 arch/powerpc/include/asm/disassemble.h| 80 +-
 arch/powerpc/include/asm/kvm_book3s.h |  4 +-
 arch/powerpc/include/asm/kvm_book3s_asm.h |  3 +-
 arch/powerpc/include/asm/kvm_host.h   |  5 +-
 arch/powerpc/include/asm/kvm_ppc.h| 14 ++--
 arch/powerpc/kernel/asm-offsets.c |  2 +
 arch/powerpc/kernel/kvm.c | 99 +++
 arch/powerpc/kvm/book3s.c |  6 +-
 arch/powerpc/kvm/book3s.h |  2 +-
 arch/powerpc/kvm/book3s_64_mmu_hv.c   |  8 +-
 arch/powerpc/kvm/book3s_emulate.c | 30 +++
 arch/powerpc/kvm/book3s_hv.c  | 19 ++---
 arch/powerpc/kvm/book3s_hv_nested.c   |  4 +-
 arch/powerpc/kvm/book3s_hv_rmhandlers.S   |  5 ++
 arch/powerpc/kvm/book3s_hv_tm.c   | 17 ++--
 arch/powerpc/kvm/book3s_hv_tm_builtin.c   | 12 +--
 arch/powerpc/kvm/book3s_paired_singles.c  | 15 ++--
 arch/powerpc/kvm/book3s_pr.c  | 20 ++---
 arch/powerpc/kvm/booke.c  | 18 ++---
 arch/powerpc/kvm/booke.h  |  4 +-
 arch/powerpc/kvm/booke_emulate.c  |  4 +-
 arch/powerpc/kvm/e500_emulate.c   |  6 +-
 arch/powerpc/kvm/e500_mmu_host.c  |  6 +-
 arch/powerpc/kvm/emulate.c| 15 ++--
 arch/powerpc/kvm/emulate_loadstore.c  |  8 +-
 arch/powerpc/kvm/powerpc.c|  4 +-
 arch/powerpc/kvm/trace.h  |  9 ++-
 arch/powerpc/kvm/trace_booke.h|  8 +-
 arch/powerpc/kvm/trace_pr.h   |  8 +-
 arch/powerpc/lib/inst.c   |  4 +-
 arch/powerpc/lib/sstep.c  |  4 +-
 arch/powerpc/sysdev/fsl_pci.c |  4 +-
 32 files changed, 237 insertions(+), 210 deletions(-)

diff --git a/arch/powerpc/include/asm/disassemble.h 
b/arch/powerpc/include/asm/disassemble.h
index 8d2ebc36d5e3..91dbe8e5cd13 100644
--- a/arch/powerpc/include/asm/disassemble.h
+++ b/arch/powerpc/include/asm/disassemble.h
@@ -10,75 +10,82 @@
 #define __ASM_PPC_DISASSEMBLE_H__
 
 #include 
+#include 
 
-static inline unsigned int get_op(u32 inst)
+static inline unsigned int get_op(struct ppc_inst inst)
 {
-   return inst >> 26;
+   return ppc_inst_val(inst) >> 26;
 }
 
-static inline unsigned int get_xop(u32 inst)
+static inline unsigned int get_xop(struct ppc_inst inst)
 {
-   return (inst >> 1) & 0x3ff;
+   return (ppc_inst_val(inst) >> 1) & 0x3ff;
 }
 
-static inline unsigned int get_sprn(u32 inst)
+static inline unsigned int get_sprn(struct ppc_inst inst)
 {
-   return ((inst >> 16) & 0x1f) | ((inst >> 6) & 0x3e0);
+   u32 word = ppc_inst_val(inst);
+
+   return ((word >> 16) & 0x1f) | ((word >> 6) & 0x3e0);
 }
 
-static inline unsigned int get_dcrn(u32 inst)
+static inline unsigned int get_dcrn(struct ppc_inst inst)
 {
-   return ((inst >> 16) & 0x1f) | ((inst >> 6) & 0x3e0);
+   u32 word = ppc_inst_val(inst);
+
+   return ((word >> 16) & 0x1f) | ((word >> 6) & 0x3e0);
 }
 
-static inline unsigned int get_tmrn(u32 inst)
+static inline unsigned int get_tmrn(struct ppc_inst inst)
 {
-   return ((inst >> 16) & 0x1f) | ((inst >> 6) & 0x3e0);
+   u32 word = ppc_inst_val(inst);
+
+   return ((word >> 16) & 0x1f) | ((word >> 6) & 0x3e0);
 }
 
-static inline unsigned int get_rt(u32 inst)
+static inline unsigned int get_rt(struct ppc_inst inst)
 {
-   return (inst >> 21) & 0x1f;
+   return (ppc_inst_val(inst) >> 21) & 0x1f;
 }
 
-static inline unsigned int get_rs(u32 inst)
+static inline unsigned int get_rs(struct ppc_inst inst)
 {
-   return (inst >> 21) & 0x1f;
+   return (ppc_inst_val(inst) >> 21) & 0x1f;
 }
 
-static inline unsigned int get_ra(u32 inst)
+static inline unsigned int get_ra(struct ppc_inst inst)
 {
-   return (inst >> 16) & 0x1f;
+   return (ppc_inst_val(inst) >> 16) & 0x1f;
 }
 
-static inline unsigned int get_rb(u32 inst)
+static inline unsigned int get_rb(struct ppc_inst inst)
 {
-   return (inst >> 11) & 0x1f;
+   return (ppc_inst_val(inst) >> 11) & 0x1f;
 }
 
-static inline unsigned int get_rc(u32 inst)
+static inline unsigned int get_rc(struct ppc_inst inst)
 {
-   return inst & 0x1;
+   return ppc_inst_val(inst) & 0x1;
 }
 
-static inline unsigned int get_ws(u32 inst)
+static inline unsigned int get_ws(struct ppc_inst inst)
 {
-   return (inst >> 11) & 0x1f;
+   return (ppc_inst_val(inst) >> 11) & 0x1f;
 }
 
-static inline unsigned int get_d(u32 inst)
+st

Re: [v4] powerpc/perf: Initialize power10 PMU registers in cpu setup routine

2020-07-23 Thread Jordan Niethe
On Thu, Jul 23, 2020 at 5:32 PM Athira Rajeev
 wrote:
>
> Initialize Monitor Mode Control Register 3 (MMCR3)
> SPR which is new in power10. For PowerISA v3.1, BHRB disable
> is controlled via Monitor Mode Control Register A (MMCRA) bit,
> namely "BHRB Recording Disable (BHRBRD)". This patch also initializes
> MMCRA BHRBRD to disable BHRB feature at boot for power10.
>
> Signed-off-by: Athira Rajeev 
Reviewed-by: Jordan Niethe 
> ---
> Dependency:
> - On power10 PMU base enablement series V3:
>   https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=190462
>
> Changes from v3 -> v4
> - Addressed review comments from Jordan and Michael Ellerman.
>   This patch was initially part of Power10 PMU base enablement
>   series. Moving this as separate patch as suggested by Michael
>   Ellerman. Hence dependency of initial series Patch 7 which defines
>   MMCRA_BHRB_DISABLE. Addressed review comments from Jordan to make
>   sure existing PMU function (__INIT_PMU) will not overwrite ISA 3.1
>   updates
>
> Changes from v2 -> v3
> - Addressed review comment from Michael Ellerman to
>   call PMU init from __setup_cpu_power10
>
>  arch/powerpc/kernel/cpu_setup_power.S | 19 +++
>  1 file changed, 15 insertions(+), 4 deletions(-)
>
> diff --git a/arch/powerpc/kernel/cpu_setup_power.S 
> b/arch/powerpc/kernel/cpu_setup_power.S
> index efdcfa7..3fa6eef 100644
> --- a/arch/powerpc/kernel/cpu_setup_power.S
> +++ b/arch/powerpc/kernel/cpu_setup_power.S
> @@ -94,13 +94,15 @@ _GLOBAL(__restore_cpu_power8)
>  _GLOBAL(__setup_cpu_power10)
> mflrr11
> bl  __init_FSCR_power10
> +   bl  __init_PMU
> +   bl  __init_PMU_ISA31
> b   1f
>
>  _GLOBAL(__setup_cpu_power9)
> mflrr11
> bl  __init_FSCR
> -1: bl  __init_PMU
> -   bl  __init_hvmode_206
> +   bl  __init_PMU
> +1: bl  __init_hvmode_206
> mtlrr11
> beqlr
> li  r0,0
> @@ -124,13 +126,15 @@ _GLOBAL(__setup_cpu_power9)
>  _GLOBAL(__restore_cpu_power10)
> mflrr11
> bl  __init_FSCR_power10
> +   bl  __init_PMU
> +   bl  __init_PMU_ISA31
> b   1f
>
>  _GLOBAL(__restore_cpu_power9)
> mflrr11
> bl  __init_FSCR
> -1: bl  __init_PMU
> -   mfmsr   r3
> +   bl  __init_PMU
> +1: mfmsr   r3
> rldicl. r0,r3,4,63
> mtlrr11
> beqlr
> @@ -233,3 +237,10 @@ __init_PMU_ISA207:
> li  r5,0
> mtspr   SPRN_MMCRS,r5
> blr
> +
> +__init_PMU_ISA31:
> +   li  r5,0
> +   mtspr   SPRN_MMCR3,r5
> +   LOAD_REG_IMMEDIATE(r5, MMCRA_BHRB_DISABLE)
> +   mtspr   SPRN_MMCRA,r5
> +   blr
> --
> 1.8.3.1
>


Re: [v3 11/15] powerpc/perf: BHRB control to disable BHRB logic when not used

2020-07-22 Thread Jordan Niethe
On Thu, Jul 23, 2020 at 11:26 AM Jordan Niethe  wrote:
>
> On Sat, Jul 18, 2020 at 1:26 AM Athira Rajeev
>  wrote:
> >
> > PowerISA v3.1 has few updates for the Branch History Rolling Buffer(BHRB).
> >
> > BHRB disable is controlled via Monitor Mode Control Register A (MMCRA)
> > bit, namely "BHRB Recording Disable (BHRBRD)". This field controls
> > whether BHRB entries are written when BHRB recording is enabled by other
> > bits. This patch implements support for this BHRB disable bit.
> >
> > By setting 0b1 to this bit will disable the BHRB and by setting 0b0
> > to this bit will have BHRB enabled. This addresses backward
> > compatibility (for older OS), since this bit will be cleared and
> > hardware will be writing to BHRB by default.
> >
> > This patch addresses changes to set MMCRA (BHRBRD) at boot for power10
> > ( there by the core will run faster) and enable this feature only on
> > runtime ie, on explicit need from user. Also save/restore MMCRA in the
> > restore path of state-loss idle state to make sure we keep BHRB disabled
> > if it was not enabled on request at runtime.
> >
> > Signed-off-by: Athira Rajeev 
> > ---
> >  arch/powerpc/perf/core-book3s.c   | 20 
> >  arch/powerpc/perf/isa207-common.c | 12 
> >  arch/powerpc/platforms/powernv/idle.c | 22 --
> >  3 files changed, 48 insertions(+), 6 deletions(-)
> >
> > diff --git a/arch/powerpc/perf/core-book3s.c 
> > b/arch/powerpc/perf/core-book3s.c
> > index bd125fe..31c0535 100644
> > --- a/arch/powerpc/perf/core-book3s.c
> > +++ b/arch/powerpc/perf/core-book3s.c
> > @@ -1218,7 +1218,7 @@ static void write_mmcr0(struct cpu_hw_events *cpuhw, 
> > unsigned long mmcr0)
> >  static void power_pmu_disable(struct pmu *pmu)
> >  {
> > struct cpu_hw_events *cpuhw;
> > -   unsigned long flags, mmcr0, val;
> > +   unsigned long flags, mmcr0, val, mmcra;
> >
> > if (!ppmu)
> > return;
> > @@ -1251,12 +1251,24 @@ static void power_pmu_disable(struct pmu *pmu)
> > mb();
> > isync();
> >
> > +   val = mmcra = cpuhw->mmcr.mmcra;
> > +
> > /*
> >  * Disable instruction sampling if it was enabled
> >  */
> > -   if (cpuhw->mmcr.mmcra & MMCRA_SAMPLE_ENABLE) {
> > -   mtspr(SPRN_MMCRA,
> > - cpuhw->mmcr.mmcra & ~MMCRA_SAMPLE_ENABLE);
> > +   if (cpuhw->mmcr.mmcra & MMCRA_SAMPLE_ENABLE)
> > +   val &= ~MMCRA_SAMPLE_ENABLE;
> > +
> > +   /* Disable BHRB via mmcra (BHRBRD) for p10 */
> > +   if (ppmu->flags & PPMU_ARCH_310S)
> > +   val |= MMCRA_BHRB_DISABLE;
> > +
> > +   /*
> > +* Write SPRN_MMCRA if mmcra has either disabled
> > +* instruction sampling or BHRB.
> > +*/
> > +   if (val != mmcra) {
> > +   mtspr(SPRN_MMCRA, mmcra);
> > mb();
> > isync();
> > }
> > diff --git a/arch/powerpc/perf/isa207-common.c 
> > b/arch/powerpc/perf/isa207-common.c
> > index 77643f3..964437a 100644
> > --- a/arch/powerpc/perf/isa207-common.c
> > +++ b/arch/powerpc/perf/isa207-common.c
> > @@ -404,6 +404,13 @@ int isa207_compute_mmcr(u64 event[], int n_ev,
> >
> > mmcra = mmcr1 = mmcr2 = mmcr3 = 0;
> >
> > +   /*
> > +* Disable bhrb unless explicitly requested
> > +* by setting MMCRA (BHRBRD) bit.
> > +*/
> > +   if (cpu_has_feature(CPU_FTR_ARCH_31))
> > +   mmcra |= MMCRA_BHRB_DISABLE;
> > +
> > /* Second pass: assign PMCs, set all MMCR1 fields */
> > for (i = 0; i < n_ev; ++i) {
> > pmc = (event[i] >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK;
> > @@ -479,6 +486,11 @@ int isa207_compute_mmcr(u64 event[], int n_ev,
> > mmcra |= val << MMCRA_IFM_SHIFT;
> > }
> >
> > +   /* set MMCRA (BHRBRD) to 0 if there is user request for 
> > BHRB */
> > +   if (cpu_has_feature(CPU_FTR_ARCH_31) &&
> > +   (has_branch_stack(pevents[i]) || (event[i] 
> > & EVENT_WANTS_BHRB)))
> >

Re: [v3 11/15] powerpc/perf: BHRB control to disable BHRB logic when not used

2020-07-22 Thread Jordan Niethe
On Sat, Jul 18, 2020 at 1:26 AM Athira Rajeev
 wrote:
>
> PowerISA v3.1 has few updates for the Branch History Rolling Buffer(BHRB).
>
> BHRB disable is controlled via Monitor Mode Control Register A (MMCRA)
> bit, namely "BHRB Recording Disable (BHRBRD)". This field controls
> whether BHRB entries are written when BHRB recording is enabled by other
> bits. This patch implements support for this BHRB disable bit.
>
> By setting 0b1 to this bit will disable the BHRB and by setting 0b0
> to this bit will have BHRB enabled. This addresses backward
> compatibility (for older OS), since this bit will be cleared and
> hardware will be writing to BHRB by default.
>
> This patch addresses changes to set MMCRA (BHRBRD) at boot for power10
> ( there by the core will run faster) and enable this feature only on
> runtime ie, on explicit need from user. Also save/restore MMCRA in the
> restore path of state-loss idle state to make sure we keep BHRB disabled
> if it was not enabled on request at runtime.
>
> Signed-off-by: Athira Rajeev 
> ---
>  arch/powerpc/perf/core-book3s.c   | 20 
>  arch/powerpc/perf/isa207-common.c | 12 
>  arch/powerpc/platforms/powernv/idle.c | 22 --
>  3 files changed, 48 insertions(+), 6 deletions(-)
>
> diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
> index bd125fe..31c0535 100644
> --- a/arch/powerpc/perf/core-book3s.c
> +++ b/arch/powerpc/perf/core-book3s.c
> @@ -1218,7 +1218,7 @@ static void write_mmcr0(struct cpu_hw_events *cpuhw, 
> unsigned long mmcr0)
>  static void power_pmu_disable(struct pmu *pmu)
>  {
> struct cpu_hw_events *cpuhw;
> -   unsigned long flags, mmcr0, val;
> +   unsigned long flags, mmcr0, val, mmcra;
>
> if (!ppmu)
> return;
> @@ -1251,12 +1251,24 @@ static void power_pmu_disable(struct pmu *pmu)
> mb();
> isync();
>
> +   val = mmcra = cpuhw->mmcr.mmcra;
> +
> /*
>  * Disable instruction sampling if it was enabled
>  */
> -   if (cpuhw->mmcr.mmcra & MMCRA_SAMPLE_ENABLE) {
> -   mtspr(SPRN_MMCRA,
> - cpuhw->mmcr.mmcra & ~MMCRA_SAMPLE_ENABLE);
> +   if (cpuhw->mmcr.mmcra & MMCRA_SAMPLE_ENABLE)
> +   val &= ~MMCRA_SAMPLE_ENABLE;
> +
> +   /* Disable BHRB via mmcra (BHRBRD) for p10 */
> +   if (ppmu->flags & PPMU_ARCH_310S)
> +   val |= MMCRA_BHRB_DISABLE;
> +
> +   /*
> +* Write SPRN_MMCRA if mmcra has either disabled
> +* instruction sampling or BHRB.
> +*/
> +   if (val != mmcra) {
> +   mtspr(SPRN_MMCRA, mmcra);
> mb();
> isync();
> }
> diff --git a/arch/powerpc/perf/isa207-common.c 
> b/arch/powerpc/perf/isa207-common.c
> index 77643f3..964437a 100644
> --- a/arch/powerpc/perf/isa207-common.c
> +++ b/arch/powerpc/perf/isa207-common.c
> @@ -404,6 +404,13 @@ int isa207_compute_mmcr(u64 event[], int n_ev,
>
> mmcra = mmcr1 = mmcr2 = mmcr3 = 0;
>
> +   /*
> +* Disable bhrb unless explicitly requested
> +* by setting MMCRA (BHRBRD) bit.
> +*/
> +   if (cpu_has_feature(CPU_FTR_ARCH_31))
> +   mmcra |= MMCRA_BHRB_DISABLE;
> +
> /* Second pass: assign PMCs, set all MMCR1 fields */
> for (i = 0; i < n_ev; ++i) {
> pmc = (event[i] >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK;
> @@ -479,6 +486,11 @@ int isa207_compute_mmcr(u64 event[], int n_ev,
> mmcra |= val << MMCRA_IFM_SHIFT;
> }
>
> +   /* set MMCRA (BHRBRD) to 0 if there is user request for BHRB 
> */
> +   if (cpu_has_feature(CPU_FTR_ARCH_31) &&
> +   (has_branch_stack(pevents[i]) || (event[i] & 
> EVENT_WANTS_BHRB)))
> +   mmcra &= ~MMCRA_BHRB_DISABLE;
> +
> if (pevents[i]->attr.exclude_user)
> mmcr2 |= MMCR2_FCP(pmc);
>
> diff --git a/arch/powerpc/platforms/powernv/idle.c 
> b/arch/powerpc/platforms/powernv/idle.c
> index 2dd4673..1c9d0a9 100644
> --- a/arch/powerpc/platforms/powernv/idle.c
> +++ b/arch/powerpc/platforms/powernv/idle.c
> @@ -611,6 +611,7 @@ static unsigned long power9_idle_stop(unsigned long 
> psscr, bool mmu_on)
> unsigned long srr1;
> unsigned long pls;
> unsigned long mmcr0 = 0;
> +   unsigned long mmcra = 0;
> struct p9_sprs sprs = {}; /* avoid false used-uninitialised */
> bool sprs_saved = false;
>
> @@ -657,6 +658,21 @@ static unsigned long power9_idle_stop(unsigned long 
> psscr, bool mmu_on)
>   */
> mmcr0   = mfspr(SPRN_MMCR0);
> }
> +
> +   if 

Re: [v3 04/15] powerpc/perf: Add support for ISA3.1 PMU SPRs

2020-07-22 Thread Jordan Niethe
On Wed, Jul 22, 2020 at 6:07 PM Athira Rajeev
 wrote:
>
>
>
> On 22-Jul-2020, at 9:48 AM, Jordan Niethe  wrote:
>
> On Sat, Jul 18, 2020 at 1:02 AM Athira Rajeev
>  wrote:
>
>
> From: Madhavan Srinivasan 
>
> PowerISA v3.1 includes new performance monitoring unit(PMU)
> special purpose registers (SPRs). They are
>
> Monitor Mode Control Register 3 (MMCR3)
> Sampled Instruction Event Register 2 (SIER2)
> Sampled Instruction Event Register 3 (SIER3)
>
> MMCR3 is added for further sampling related configuration
> control. SIER2/SIER3 are added to provide additional
> information about the sampled instruction.
>
> Patch adds new PPMU flag called "PPMU_ARCH_310S" to support
> handling of these new SPRs, updates the struct thread_struct
> to include these new SPRs, include MMCR3 in struct mmcr_regs.
> This is needed to support programming of MMCR3 SPR during
> event_[enable/disable]. Patch also adds the sysfs support
> for the MMCR3 SPR along with SPRN_ macros for these new pmu sprs.
>
> Signed-off-by: Madhavan Srinivasan 
> ---
> arch/powerpc/include/asm/perf_event_server.h |  2 ++
> arch/powerpc/include/asm/processor.h |  4 
> arch/powerpc/include/asm/reg.h   |  6 ++
> arch/powerpc/kernel/sysfs.c  |  8 
> arch/powerpc/perf/core-book3s.c  | 29 
> 5 files changed, 49 insertions(+)
>
> diff --git a/arch/powerpc/include/asm/perf_event_server.h 
> b/arch/powerpc/include/asm/perf_event_server.h
> index 14b8dc1..832450a 100644
> --- a/arch/powerpc/include/asm/perf_event_server.h
> +++ b/arch/powerpc/include/asm/perf_event_server.h
> @@ -22,6 +22,7 @@ struct mmcr_regs {
>unsigned long mmcr1;
>unsigned long mmcr2;
>unsigned long mmcra;
> +   unsigned long mmcr3;
> };
> /*
>  * This struct provides the constants and functions needed to
> @@ -75,6 +76,7 @@ struct power_pmu {
> #define PPMU_HAS_SIER  0x0040 /* Has SIER */
> #define PPMU_ARCH_207S 0x0080 /* PMC is architecture v2.07S */
> #define PPMU_NO_SIAR   0x0100 /* Do not use SIAR */
> +#define PPMU_ARCH_310S 0x0200 /* Has MMCR3, SIER2 and SIER3 */
>
> We elsewhere have CPU_FTR_ARCH_31, so should this be PPMU_ARCH_31S to
> be consistent.
>
>
>
> Ok,
> This change will need to be done in all places which are currently using 
> PPMU_ARCH_310S
>
> /*
>  * Values for flags to get_alternatives()
> diff --git a/arch/powerpc/include/asm/processor.h 
> b/arch/powerpc/include/asm/processor.h
> index 52a6783..a466e94 100644
> --- a/arch/powerpc/include/asm/processor.h
> +++ b/arch/powerpc/include/asm/processor.h
> @@ -272,6 +272,10 @@ struct thread_struct {
>unsignedmmcr0;
>
>unsignedused_ebb;
> +   unsigned long   mmcr3;
> +   unsigned long   sier2;
> +   unsigned long   sier3;
> +
> #endif
> };
>
> diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
> index 88e6c78..21a1b2d 100644
> --- a/arch/powerpc/include/asm/reg.h
> +++ b/arch/powerpc/include/asm/reg.h
> @@ -876,7 +876,9 @@
> #define   MMCR0_FCHV   0x0001UL /* freeze conditions in hypervisor mode */
> #define SPRN_MMCR1 798
> #define SPRN_MMCR2 785
> +#define SPRN_MMCR3 754
> #define SPRN_UMMCR2769
> +#define SPRN_UMMCR3738
> #define SPRN_MMCRA 0x312
> #define   MMCRA_SDSYNC 0x8000UL /* SDAR synced with SIAR */
> #define   MMCRA_SDAR_DCACHE_MISS 0x4000UL
> @@ -918,6 +920,10 @@
> #define   SIER_SIHV0x100   /* Sampled MSR_HV */
> #define   SIER_SIAR_VALID  0x040   /* SIAR contents valid */
> #define   SIER_SDAR_VALID  0x020   /* SDAR contents valid */
> +#define SPRN_SIER2 752
> +#define SPRN_SIER3 753
> +#define SPRN_USIER2736
> +#define SPRN_USIER3737
> #define SPRN_SIAR  796
> #define SPRN_SDAR  797
> #define SPRN_TACR  888
> diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
> index 571b325..46b4ebc 100644
> --- a/arch/powerpc/kernel/sysfs.c
> +++ b/arch/powerpc/kernel/sysfs.c
> @@ -622,8 +622,10 @@ void ppc_enable_pmcs(void)
> SYSFS_PMCSETUP(pmc8, SPRN_PMC8);
>
> SYSFS_PMCSETUP(mmcra, SPRN_MMCRA);
> +SYSFS_PMCSETUP(mmcr3, SPRN_MMCR3);
>
> static DEVICE_ATTR(mmcra, 0600, show_mmcra, store_mmcra);
> +static DEVICE_ATTR(mmcr3, 0600, show_mmcr3, store_mmcr3);
> #endif /* HAS_PPC_PMC56 */
>
>
> @@ -886,6 +888,9 @@ static int register_cpu_online(unsigned int cpu)
> #ifdef CONFIG_PMU_SYSFS
>if (cpu_has_feature(CPU_FTR_MMCRA))
>device_create_file(s, 

Re: [v3 07/15] powerpc/perf: Add power10_feat to dt_cpu_ftrs

2020-07-22 Thread Jordan Niethe
On Wed, Jul 22, 2020 at 5:55 PM Athira Rajeev
 wrote:
>
>
>
> On 22-Jul-2020, at 10:11 AM, Jordan Niethe  wrote:
>
> On Sat, Jul 18, 2020 at 1:13 AM Athira Rajeev
>  wrote:
>
>
> From: Madhavan Srinivasan 
>
> Add power10 feature function to dt_cpu_ftrs.c along
> with a power10 specific init() to initialize pmu sprs,
> sets the oprofile_cpu_type and cpu_features. This will
> enable performance monitoring unit(PMU) for Power10
> in CPU features with "performance-monitor-power10".
>
> For PowerISA v3.1, BHRB disable is controlled via Monitor Mode
> Control Register A (MMCRA) bit, namely "BHRB Recording Disable
> (BHRBRD)". This patch initializes MMCRA BHRBRD to disable BHRB
> feature at boot for power10.
>
> Signed-off-by: Madhavan Srinivasan 
> ---
> arch/powerpc/include/asm/reg.h|  3 +++
> arch/powerpc/kernel/cpu_setup_power.S |  8 
> arch/powerpc/kernel/dt_cpu_ftrs.c | 26 ++
> 3 files changed, 37 insertions(+)
>
> diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
> index 21a1b2d..900ada1 100644
> --- a/arch/powerpc/include/asm/reg.h
> +++ b/arch/powerpc/include/asm/reg.h
> @@ -1068,6 +1068,9 @@
> #define MMCR0_PMC2_LOADMISSTIME0x5
> #endif
>
> +/* BHRB disable bit for PowerISA v3.10 */
> +#define MMCRA_BHRB_DISABLE 0x0020
>
> Shouldn't this go under SPRN_MMCRA with the other MMCRA_*.
>
>
>
> Hi Jordan
>
> Ok, the definition of MMCRA is under #ifdef for 64 bit .  if I move 
> definition of MMCRA_BHRB_DISABLE along with other SPR's, I also
> need to define this for 32-bit to satisfy core-book3s to compile as below:
>
> diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
> index 900ada10762c..7e271657b412 100644
> --- a/arch/powerpc/include/asm/reg.h
> +++ b/arch/powerpc/include/asm/reg.h
> @@ -888,6 +888,8 @@
>  #define   MMCRA_SLOT   0x0700UL /* SLOT bits (37-39) */
>  #define   MMCRA_SLOT_SHIFT 24
>  #define   MMCRA_SAMPLE_ENABLE 0x0001UL /* enable sampling */
> +/* BHRB disable bit for PowerISA v3.10 */
> +#define   MMCRA_BHRB_DISABLE  0x0020
>  #define   POWER6_MMCRA_SDSYNC 0x0800ULL/* SDAR/SIAR synced */
>  #define   POWER6_MMCRA_SIHV   0x0400ULL
>  #define   POWER6_MMCRA_SIPR   0x0200ULL
> @@ -1068,9 +1070,6 @@
>  #define MMCR0_PMC2_LOADMISSTIME0x5
>  #endif
>
>
>
> -/* BHRB disable bit for PowerISA v3.10 */
> -#define MMCRA_BHRB_DISABLE 0x0020
> -
>  /*
>   * SPRG usage:
>   *
> diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
> index 36baae666387..88068f20827c 100644
> --- a/arch/powerpc/perf/core-book3s.c
> +++ b/arch/powerpc/perf/core-book3s.c
> @@ -94,6 +94,7 @@ static unsigned int freeze_events_kernel = MMCR0_FCS;
>  #define SPRN_SIER2 0
>  #define SPRN_SIER3 0
>  #define MMCRA_SAMPLE_ENABLE0
> +#define MMCRA_BHRB_DISABLE 0
>
>
>
>  static inline unsigned long perf_ip_adjust(struct pt_regs *regs)
>  {
>
>
>
> +
> /*
>  * SPRG usage:
>  *
> diff --git a/arch/powerpc/kernel/cpu_setup_power.S 
> b/arch/powerpc/kernel/cpu_setup_power.S
> index efdcfa7..b8e0d1e 100644
> --- a/arch/powerpc/kernel/cpu_setup_power.S
> +++ b/arch/powerpc/kernel/cpu_setup_power.S
> @@ -94,6 +94,7 @@ _GLOBAL(__restore_cpu_power8)
> _GLOBAL(__setup_cpu_power10)
>mflrr11
>bl  __init_FSCR_power10
> +   bl  __init_PMU_ISA31
>
> So we set MMCRA here but then aren't we still going to call __init_PMU
> which will overwrite that?
> Would this setting MMCRA also need to be handled in __restore_cpu_power10?
>
>
> Thanks for this nice catch !  When I rebased code initial phase, we didn’t 
> had power10 part filled in.
> It was a miss from my side in adding PMu init functions and thanks for 
> pointing this out.
> Below patch will call __init_PMU functions in setup and restore. Please check 
> if this looks good
>
> --
> diff --git a/arch/powerpc/kernel/cpu_setup_power.S 
> b/arch/powerpc/kernel/cpu_setup_power.S
> index efdcfa714106..e672a6c5fd7c 100644
> --- a/arch/powerpc/kernel/cpu_setup_power.S
> +++ b/arch/powerpc/kernel/cpu_setup_power.S
> @@ -94,6 +94,9 @@ _GLOBAL(__restore_cpu_power8)
>  _GLOBAL(__setup_cpu_power10)
>   mflr r11
>   bl __init_FSCR_power10
> + bl __init_PMU
> + bl __init_PMU_ISA31
> + bl __init_PMU_HV
>   b 1f
>
>  _GLOBAL(__setup_cpu_power9)

Won't you also need to change where the label 1 is:
--- a/arch/powerpc/kernel/cpu_setup_power.S
+++ b/arch/powerpc/kernel/cpu_setup_power.S
@@ -100,8

Re: [v3 07/15] powerpc/perf: Add power10_feat to dt_cpu_ftrs

2020-07-21 Thread Jordan Niethe
On Sat, Jul 18, 2020 at 1:13 AM Athira Rajeev
 wrote:
>
> From: Madhavan Srinivasan 
>
> Add power10 feature function to dt_cpu_ftrs.c along
> with a power10 specific init() to initialize pmu sprs,
> sets the oprofile_cpu_type and cpu_features. This will
> enable performance monitoring unit(PMU) for Power10
> in CPU features with "performance-monitor-power10".
>
> For PowerISA v3.1, BHRB disable is controlled via Monitor Mode
> Control Register A (MMCRA) bit, namely "BHRB Recording Disable
> (BHRBRD)". This patch initializes MMCRA BHRBRD to disable BHRB
> feature at boot for power10.
>
> Signed-off-by: Madhavan Srinivasan 
> ---
>  arch/powerpc/include/asm/reg.h|  3 +++
>  arch/powerpc/kernel/cpu_setup_power.S |  8 
>  arch/powerpc/kernel/dt_cpu_ftrs.c | 26 ++
>  3 files changed, 37 insertions(+)
>
> diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
> index 21a1b2d..900ada1 100644
> --- a/arch/powerpc/include/asm/reg.h
> +++ b/arch/powerpc/include/asm/reg.h
> @@ -1068,6 +1068,9 @@
>  #define MMCR0_PMC2_LOADMISSTIME0x5
>  #endif
>
> +/* BHRB disable bit for PowerISA v3.10 */
> +#define MMCRA_BHRB_DISABLE 0x0020
Shouldn't this go under SPRN_MMCRA with the other MMCRA_*.
> +
>  /*
>   * SPRG usage:
>   *
> diff --git a/arch/powerpc/kernel/cpu_setup_power.S 
> b/arch/powerpc/kernel/cpu_setup_power.S
> index efdcfa7..b8e0d1e 100644
> --- a/arch/powerpc/kernel/cpu_setup_power.S
> +++ b/arch/powerpc/kernel/cpu_setup_power.S
> @@ -94,6 +94,7 @@ _GLOBAL(__restore_cpu_power8)
>  _GLOBAL(__setup_cpu_power10)
> mflrr11
> bl  __init_FSCR_power10
> +   bl  __init_PMU_ISA31
So we set MMCRA here but then aren't we still going to call __init_PMU
which will overwrite that?
Would this setting MMCRA also need to be handled in __restore_cpu_power10?
> b   1f
>
>  _GLOBAL(__setup_cpu_power9)
> @@ -233,3 +234,10 @@ __init_PMU_ISA207:
> li  r5,0
> mtspr   SPRN_MMCRS,r5
> blr
> +
> +__init_PMU_ISA31:
> +   li  r5,0
> +   mtspr   SPRN_MMCR3,r5
> +   LOAD_REG_IMMEDIATE(r5, MMCRA_BHRB_DISABLE)
> +   mtspr   SPRN_MMCRA,r5
> +   blr
> diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c 
> b/arch/powerpc/kernel/dt_cpu_ftrs.c
> index 3a40951..f482286 100644
> --- a/arch/powerpc/kernel/dt_cpu_ftrs.c
> +++ b/arch/powerpc/kernel/dt_cpu_ftrs.c
> @@ -450,6 +450,31 @@ static int __init feat_enable_pmu_power9(struct 
> dt_cpu_feature *f)
> return 1;
>  }
>
> +static void init_pmu_power10(void)
> +{
> +   init_pmu_power9();
> +
> +   mtspr(SPRN_MMCR3, 0);
> +   mtspr(SPRN_MMCRA, MMCRA_BHRB_DISABLE);
> +}
> +
> +static int __init feat_enable_pmu_power10(struct dt_cpu_feature *f)
> +{
> +   hfscr_pmu_enable();
> +
> +   init_pmu_power10();
> +   init_pmu_registers = init_pmu_power10;
> +
> +   cur_cpu_spec->cpu_features |= CPU_FTR_MMCRA;
> +   cur_cpu_spec->cpu_user_features |= PPC_FEATURE_PSERIES_PERFMON_COMPAT;
> +
> +   cur_cpu_spec->num_pmcs  = 6;
> +   cur_cpu_spec->pmc_type  = PPC_PMC_IBM;
> +   cur_cpu_spec->oprofile_cpu_type = "ppc64/power10";
> +
> +   return 1;
> +}
> +
>  static int __init feat_enable_tm(struct dt_cpu_feature *f)
>  {
>  #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> @@ -639,6 +664,7 @@ struct dt_cpu_feature_match {
> {"pc-relative-addressing", feat_enable, 0},
> {"machine-check-power9", feat_enable_mce_power9, 0},
> {"performance-monitor-power9", feat_enable_pmu_power9, 0},
> +   {"performance-monitor-power10", feat_enable_pmu_power10, 0},
> {"event-based-branch-v3", feat_enable, 0},
> {"random-number-generator", feat_enable, 0},
> {"system-call-vectored", feat_disable, 0},
> --
> 1.8.3.1
>


Re: [v3 04/15] powerpc/perf: Add support for ISA3.1 PMU SPRs

2020-07-21 Thread Jordan Niethe
On Sat, Jul 18, 2020 at 1:02 AM Athira Rajeev
 wrote:
>
> From: Madhavan Srinivasan 
>
> PowerISA v3.1 includes new performance monitoring unit(PMU)
> special purpose registers (SPRs). They are
>
> Monitor Mode Control Register 3 (MMCR3)
> Sampled Instruction Event Register 2 (SIER2)
> Sampled Instruction Event Register 3 (SIER3)
>
> MMCR3 is added for further sampling related configuration
> control. SIER2/SIER3 are added to provide additional
> information about the sampled instruction.
>
> Patch adds new PPMU flag called "PPMU_ARCH_310S" to support
> handling of these new SPRs, updates the struct thread_struct
> to include these new SPRs, include MMCR3 in struct mmcr_regs.
> This is needed to support programming of MMCR3 SPR during
> event_[enable/disable]. Patch also adds the sysfs support
> for the MMCR3 SPR along with SPRN_ macros for these new pmu sprs.
>
> Signed-off-by: Madhavan Srinivasan 
> ---
>  arch/powerpc/include/asm/perf_event_server.h |  2 ++
>  arch/powerpc/include/asm/processor.h |  4 
>  arch/powerpc/include/asm/reg.h   |  6 ++
>  arch/powerpc/kernel/sysfs.c  |  8 
>  arch/powerpc/perf/core-book3s.c  | 29 
> 
>  5 files changed, 49 insertions(+)
>
> diff --git a/arch/powerpc/include/asm/perf_event_server.h 
> b/arch/powerpc/include/asm/perf_event_server.h
> index 14b8dc1..832450a 100644
> --- a/arch/powerpc/include/asm/perf_event_server.h
> +++ b/arch/powerpc/include/asm/perf_event_server.h
> @@ -22,6 +22,7 @@ struct mmcr_regs {
> unsigned long mmcr1;
> unsigned long mmcr2;
> unsigned long mmcra;
> +   unsigned long mmcr3;
>  };
>  /*
>   * This struct provides the constants and functions needed to
> @@ -75,6 +76,7 @@ struct power_pmu {
>  #define PPMU_HAS_SIER  0x0040 /* Has SIER */
>  #define PPMU_ARCH_207S 0x0080 /* PMC is architecture v2.07S */
>  #define PPMU_NO_SIAR   0x0100 /* Do not use SIAR */
> +#define PPMU_ARCH_310S 0x0200 /* Has MMCR3, SIER2 and SIER3 */
We elsewhere have CPU_FTR_ARCH_31, so should this be PPMU_ARCH_31S to
be consistent.
>
>  /*
>   * Values for flags to get_alternatives()
> diff --git a/arch/powerpc/include/asm/processor.h 
> b/arch/powerpc/include/asm/processor.h
> index 52a6783..a466e94 100644
> --- a/arch/powerpc/include/asm/processor.h
> +++ b/arch/powerpc/include/asm/processor.h
> @@ -272,6 +272,10 @@ struct thread_struct {
> unsignedmmcr0;
>
> unsignedused_ebb;
> +   unsigned long   mmcr3;
> +   unsigned long   sier2;
> +   unsigned long   sier3;
> +
>  #endif
>  };
>
> diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
> index 88e6c78..21a1b2d 100644
> --- a/arch/powerpc/include/asm/reg.h
> +++ b/arch/powerpc/include/asm/reg.h
> @@ -876,7 +876,9 @@
>  #define   MMCR0_FCHV   0x0001UL /* freeze conditions in hypervisor mode 
> */
>  #define SPRN_MMCR1 798
>  #define SPRN_MMCR2 785
> +#define SPRN_MMCR3 754
>  #define SPRN_UMMCR2769
> +#define SPRN_UMMCR3738
>  #define SPRN_MMCRA 0x312
>  #define   MMCRA_SDSYNC 0x8000UL /* SDAR synced with SIAR */
>  #define   MMCRA_SDAR_DCACHE_MISS 0x4000UL
> @@ -918,6 +920,10 @@
>  #define   SIER_SIHV0x100   /* Sampled MSR_HV */
>  #define   SIER_SIAR_VALID  0x040   /* SIAR contents valid */
>  #define   SIER_SDAR_VALID  0x020   /* SDAR contents valid */
> +#define SPRN_SIER2 752
> +#define SPRN_SIER3 753
> +#define SPRN_USIER2736
> +#define SPRN_USIER3737
>  #define SPRN_SIAR  796
>  #define SPRN_SDAR  797
>  #define SPRN_TACR  888
> diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
> index 571b325..46b4ebc 100644
> --- a/arch/powerpc/kernel/sysfs.c
> +++ b/arch/powerpc/kernel/sysfs.c
> @@ -622,8 +622,10 @@ void ppc_enable_pmcs(void)
>  SYSFS_PMCSETUP(pmc8, SPRN_PMC8);
>
>  SYSFS_PMCSETUP(mmcra, SPRN_MMCRA);
> +SYSFS_PMCSETUP(mmcr3, SPRN_MMCR3);
>
>  static DEVICE_ATTR(mmcra, 0600, show_mmcra, store_mmcra);
> +static DEVICE_ATTR(mmcr3, 0600, show_mmcr3, store_mmcr3);
>  #endif /* HAS_PPC_PMC56 */
>
>
> @@ -886,6 +888,9 @@ static int register_cpu_online(unsigned int cpu)
>  #ifdef CONFIG_PMU_SYSFS
> if (cpu_has_feature(CPU_FTR_MMCRA))
> device_create_file(s, _attr_mmcra);
> +
> +   if (cpu_has_feature(CPU_FTR_ARCH_31))
> +   device_create_file(s, _attr_mmcr3);
>  #endif /* CONFIG_PMU_SYSFS */
>
> if (cpu_has_feature(CPU_FTR_PURR)) {
> @@ -980,6 +985,9 @@ static int unregister_cpu_online(unsigned int cpu)
>  #ifdef CONFIG_PMU_SYSFS
> if (cpu_has_feature(CPU_FTR_MMCRA))
> device_remove_file(s, _attr_mmcra);
> +
> +   if (cpu_has_feature(CPU_FTR_ARCH_31))
> +   device_remove_file(s, _attr_mmcr3);
>  #endif /* CONFIG_PMU_SYSFS */
>
> if 

Re: [PATCH 5/5] powerpc sstep: Add tests for Prefixed Add Immediate

2020-07-21 Thread Jordan Niethe
On Mon, May 25, 2020 at 1:00 PM Jordan Niethe  wrote:
>
> Use the existing support for testing compute type instructions to test
> Prefixed Add Immediate (paddi).  The R bit of the paddi instruction
> controls whether current instruction address is used. Add test cases for
> when R=1 and for R=0. paddi has a 34 bit immediate field formed by
> concatenating si0 and si1. Add tests for the extreme values of this
> field.
>
> Skip the paddi tests if ISA v3.1 is unsupported.
>
> Some of these test cases were added by Balamuruhan S.
>
> Signed-off-by: Jordan Niethe 
> ---
>  arch/powerpc/lib/test_emulate_step.c  | 127 ++
>  .../lib/test_emulate_step_exec_instr.S|   1 +
>  2 files changed, 128 insertions(+)
>
> diff --git a/arch/powerpc/lib/test_emulate_step.c 
> b/arch/powerpc/lib/test_emulate_step.c
> index 579b5db80674..33a72b7d2764 100644
> --- a/arch/powerpc/lib/test_emulate_step.c
> +++ b/arch/powerpc/lib/test_emulate_step.c
> @@ -105,6 +105,13 @@
> ___PPC_RA(a) | ___PPC_RB(b))
>  #define TEST_ADDC_DOT(t, a, b) ppc_inst(PPC_INST_ADDC | ___PPC_RT(t) |   
>   \
> ___PPC_RA(a) | ___PPC_RB(b) | 0x1)
> +#define TEST_PADDI(t, a, i, pr)ppc_inst_prefix(PPC_PREFIX_MLS | 
> __PPC_PRFX_R(pr) | \
> +   IMM_H(i),   \
> +   PPC_INST_ADDI | \
> +   ___PPC_RT(t) | ___PPC_RA(a) |   \
> +   IMM_L(i))
> +
> +
>
>  #define MAX_SUBTESTS   16
>
> @@ -699,6 +706,11 @@ struct compute_test {
> } subtests[MAX_SUBTESTS + 1];
>  };
>
> +/* Extreme values for si0||si1 (the MLS:D-form 34 bit immediate field) */
> +#define SI_MIN BIT(33)
> +#define SI_MAX (BIT(33) - 1)
> +#define SI_UMAX (BIT(34) - 1)
> +
>  static struct compute_test compute_tests[] = {
> {
> .mnemonic = "nop",
> @@ -1071,6 +1083,121 @@ static struct compute_test compute_tests[] = {
> }
> }
> }
> +   },
> +   {
> +   .mnemonic = "paddi",
> +   .cpu_feature = CPU_FTR_ARCH_31,
> +   .subtests = {
> +   {
> +   .descr = "RA = LONG_MIN, SI = SI_MIN, R = 0",
> +   .instr = TEST_PADDI(21, 22, SI_MIN, 0),
> +   .regs = {
> +   .gpr[21] = 0,
> +   .gpr[22] = LONG_MIN,
> +   }
> +   },
> +   {
> +   .descr = "RA = LONG_MIN, SI = SI_MAX, R = 0",
> +   .instr = TEST_PADDI(21, 22, SI_MAX, 0),
> +   .regs = {
> +   .gpr[21] = 0,
> +   .gpr[22] = LONG_MIN,
> +   }
> +   },
> +   {
> +   .descr = "RA = LONG_MAX, SI = SI_MAX, R = 0",
> +   .instr = TEST_PADDI(21, 22, SI_MAX, 0),
> +   .regs = {
> +   .gpr[21] = 0,
> +   .gpr[22] = LONG_MAX,
> +   }
> +   },
> +   {
> +   .descr = "RA = ULONG_MAX, SI = SI_UMAX, R = 
> 0",
> +   .instr = TEST_PADDI(21, 22, SI_UMAX, 0),
> +   .regs = {
> +   .gpr[21] = 0,
> +   .gpr[22] = ULONG_MAX,
> +   }
> +   },
> +   {
> +   .descr = "RA = ULONG_MAX, SI = 0x1, R = 0",
> +   .instr = TEST_PADDI(21, 22, 0x1, 0),
> +   .regs = {
> +   .gpr[21] = 0,
> +   .gpr[22] = ULONG_MAX,
> +   }
> +   },
> +   {
> +   .descr = "RA = INT_MIN, SI = SI_MIN, R = 0",
> +   .instr = TEST_PADDI(21, 22, SI_MIN, 0),
> +   

Re: [PATCH v4 09/10] powerpc/watchpoint: Return available watchpoints dynamically

2020-07-20 Thread Jordan Niethe
On Tue, Jul 21, 2020 at 1:57 PM Ravi Bangoria
 wrote:
>
>
>
> On 7/20/20 9:12 AM, Jordan Niethe wrote:
> > On Fri, Jul 17, 2020 at 2:11 PM Ravi Bangoria
> >  wrote:
> >>
> >> So far Book3S Powerpc supported only one watchpoint. Power10 is
> >> introducing 2nd DAWR. Enable 2nd DAWR support for Power10.
> >> Availability of 2nd DAWR will depend on CPU_FTR_DAWR1.
> >>
> >> Signed-off-by: Ravi Bangoria 
> >> ---
> >>   arch/powerpc/include/asm/cputable.h  | 4 +++-
> >>   arch/powerpc/include/asm/hw_breakpoint.h | 5 +++--
> >>   2 files changed, 6 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/arch/powerpc/include/asm/cputable.h 
> >> b/arch/powerpc/include/asm/cputable.h
> >> index 3445c86e1f6f..36a0851a7a9b 100644
> >> --- a/arch/powerpc/include/asm/cputable.h
> >> +++ b/arch/powerpc/include/asm/cputable.h
> >> @@ -633,7 +633,9 @@ enum {
> >>* Maximum number of hw breakpoint supported on powerpc. Number of
> >>* breakpoints supported by actual hw might be less than this.
> >>*/
> >> -#define HBP_NUM_MAX1
> >> +#define HBP_NUM_MAX2
> >> +#define HBP_NUM_ONE1
> >> +#define HBP_NUM_TWO2
> > I wonder if these defines are necessary - has it any advantage over
> > just using the literal?
>
> No, not really. Initially I had something like:
>
> #define HBP_NUM_MAX2
> #define HBP_NUM_P8_P9  1
> #define HBP_NUM_P102
>
> But then I thought it's also not right. So I made it _ONE and _TWO.
> Now the function that decides nr watchpoints dynamically (nr_wp_slots)
> is in different file, I thought to keep it like this so it would be
> easier to figure out why _MAX is 2.
>
> >>
> >>   #endif /* !__ASSEMBLY__ */
> >>
> >> diff --git a/arch/powerpc/include/asm/hw_breakpoint.h 
> >> b/arch/powerpc/include/asm/hw_breakpoint.h
> >> index cb424799da0d..d4eab1694bcd 100644
> >> --- a/arch/powerpc/include/asm/hw_breakpoint.h
> >> +++ b/arch/powerpc/include/asm/hw_breakpoint.h
> >> @@ -5,10 +5,11 @@
> >>* Copyright 2010, IBM Corporation.
> >>* Author: K.Prasad 
> >>*/
> >> -
> > Was removing this line deliberate?
>
> Nah. Will remove that hunk.
>
> >>   #ifndef _PPC_BOOK3S_64_HW_BREAKPOINT_H
> >>   #define _PPC_BOOK3S_64_HW_BREAKPOINT_H
> >>
> >> +#include 
> >> +
> >>   #ifdef __KERNEL__
> >>   struct arch_hw_breakpoint {
> >>  unsigned long   address;
> >> @@ -46,7 +47,7 @@ struct arch_hw_breakpoint {
> >>
> >>   static inline int nr_wp_slots(void)
> >>   {
> >> -   return HBP_NUM_MAX;
> >> +   return cpu_has_feature(CPU_FTR_DAWR1) ? HBP_NUM_TWO : HBP_NUM_ONE;
> > So it'd be something like:
> > +   return cpu_has_feature(CPU_FTR_DAWR1) ? HBP_NUM_MAX : 1;
> > But thinking that there might be more slots added in the future, it
> > may be better to make the number of slots a variable that is set
> > during the init and then have this function return that.
>
> Not sure I follow. What do you mean by setting number of slots a
> variable that is set during the init?
Sorry I was unclear there.
I was just looking and saw arm also has a variable number of hw breakpoints.
If we did something like how they handle it, it might look something like:

static int num_wp_slots __ro_after_init;

int nr_wp_slots(void) {
return num_wp_slots;
}

static int __init arch_hw_breakpoint_init(void) {
num_wp_slots = work out how many wp_slots
}
arch_initcall(arch_hw_breakpoint_init);

Then we wouldn't have to calculate everytime nr_wp_slots() is called.
In the future if more wp's are added nr_wp_slots() will get more complicated.
But just an idea, feel free to ignore.

>
> Thanks,
> Ravi


Re: [v3 01/15] powerpc/perf: Update cpu_hw_event to use `struct` for storing MMCR registers

2020-07-20 Thread Jordan Niethe
On Sat, Jul 18, 2020 at 12:48 AM Athira Rajeev
 wrote:
>
> core-book3s currently uses array to store the MMCR registers as part
> of per-cpu `cpu_hw_events`. This patch does a clean up to use `struct`
> to store mmcr regs instead of array. This will make code easier to read
> and reduces chance of any subtle bug that may come in the future, say
> when new registers are added. Patch updates all relevant code that was
> using MMCR array ( cpuhw->mmcr[x]) to use newly introduced `struct`.
> This includes the PMU driver code for supported platforms (power5
> to power9) and ISA macros for counter support functions.
>
> Signed-off-by: Athira Rajeev 
> ---
>  arch/powerpc/include/asm/perf_event_server.h | 10 --
>  arch/powerpc/perf/core-book3s.c  | 53 
> +---
>  arch/powerpc/perf/isa207-common.c| 20 +--
>  arch/powerpc/perf/isa207-common.h|  4 +--
>  arch/powerpc/perf/mpc7450-pmu.c  | 21 +++
>  arch/powerpc/perf/power5+-pmu.c  | 17 -
>  arch/powerpc/perf/power5-pmu.c   | 17 -
>  arch/powerpc/perf/power6-pmu.c   | 16 -
>  arch/powerpc/perf/power7-pmu.c   | 17 -
>  arch/powerpc/perf/ppc970-pmu.c   | 24 ++---
>  10 files changed, 105 insertions(+), 94 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/perf_event_server.h 
> b/arch/powerpc/include/asm/perf_event_server.h
> index 3e9703f..f9a3668 100644
> --- a/arch/powerpc/include/asm/perf_event_server.h
> +++ b/arch/powerpc/include/asm/perf_event_server.h
> @@ -17,6 +17,12 @@
>
>  struct perf_event;
>
> +struct mmcr_regs {
> +   unsigned long mmcr0;
> +   unsigned long mmcr1;
> +   unsigned long mmcr2;
> +   unsigned long mmcra;
> +};
>  /*
>   * This struct provides the constants and functions needed to
>   * describe the PMU on a particular POWER-family CPU.
> @@ -28,7 +34,7 @@ struct power_pmu {
> unsigned long   add_fields;
> unsigned long   test_adder;
> int (*compute_mmcr)(u64 events[], int n_ev,
> -   unsigned int hwc[], unsigned long mmcr[],
> +   unsigned int hwc[], struct mmcr_regs *mmcr,
> struct perf_event *pevents[]);
> int (*get_constraint)(u64 event_id, unsigned long *mskp,
> unsigned long *valp);
> @@ -41,7 +47,7 @@ struct power_pmu {
> unsigned long   group_constraint_val;
> u64 (*bhrb_filter_map)(u64 branch_sample_type);
> void(*config_bhrb)(u64 pmu_bhrb_filter);
> -   void(*disable_pmc)(unsigned int pmc, unsigned long 
> mmcr[]);
> +   void(*disable_pmc)(unsigned int pmc, struct mmcr_regs 
> *mmcr);
> int (*limited_pmc_event)(u64 event_id);
> u32 flags;
> const struct attribute_group**attr_groups;
> diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
> index cd6a742..18b1b6a 100644
> --- a/arch/powerpc/perf/core-book3s.c
> +++ b/arch/powerpc/perf/core-book3s.c
> @@ -37,12 +37,7 @@ struct cpu_hw_events {
> struct perf_event *event[MAX_HWEVENTS];
> u64 events[MAX_HWEVENTS];
> unsigned int flags[MAX_HWEVENTS];
> -   /*
> -* The order of the MMCR array is:
> -*  - 64-bit, MMCR0, MMCR1, MMCRA, MMCR2
> -*  - 32-bit, MMCR0, MMCR1, MMCR2
> -*/
> -   unsigned long mmcr[4];
> +   struct mmcr_regs mmcr;
> struct perf_event *limited_counter[MAX_LIMITED_HWCOUNTERS];
> u8  limited_hwidx[MAX_LIMITED_HWCOUNTERS];
> u64 alternatives[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES];
> @@ -121,7 +116,7 @@ static void ebb_event_add(struct perf_event *event) { }
>  static void ebb_switch_out(unsigned long mmcr0) { }
>  static unsigned long ebb_switch_in(bool ebb, struct cpu_hw_events *cpuhw)
>  {
> -   return cpuhw->mmcr[0];
> +   return cpuhw->mmcr.mmcr0;
>  }
>
>  static inline void power_pmu_bhrb_enable(struct perf_event *event) {}
> @@ -590,7 +585,7 @@ static void ebb_switch_out(unsigned long mmcr0)
>
>  static unsigned long ebb_switch_in(bool ebb, struct cpu_hw_events *cpuhw)
>  {
> -   unsigned long mmcr0 = cpuhw->mmcr[0];
> +   unsigned long mmcr0 = cpuhw->mmcr.mmcr0;
>
> if (!ebb)
> goto out;
> @@ -624,7 +619,7 @@ static unsigned long ebb_switch_in(bool ebb, struct 
> cpu_hw_events *cpuhw)
>  * unfreeze counters, it should not set exclude_xxx in its events and
>  * instead manage the MMCR2 entirely by itself.
>  */
> -   mtspr(SPRN_MMCR2, cpuhw->mmcr[3] | current->thread.mmcr2);
> +   mtspr(SPRN_MMCR2, cpuhw->mmcr.mmcr2 | current->thread.mmcr2);
>  out:
> return mmcr0;
>  }
> @@ -1232,9 +1227,9 @@ static void power_pmu_disable(struct pmu *pmu)
> /*

Re: [PATCH 04/11] powerpc/smp: Enable small core scheduling sooner

2020-07-20 Thread Jordan Niethe
On Tue, Jul 14, 2020 at 2:44 PM Srikar Dronamraju
 wrote:
>
> Enable small core scheduling as soon as we detect that we are in a
> system that supports thread group. Doing so would avoid a redundant
> check.
>
> Cc: linuxppc-dev 
> Cc: Michael Ellerman 
> Cc: Nick Piggin 
> Cc: Oliver OHalloran 
> Cc: Nathan Lynch 
> Cc: Michael Neuling 
> Cc: Anton Blanchard 
> Cc: Gautham R Shenoy 
> Cc: Vaidyanathan Srinivasan 
> Signed-off-by: Srikar Dronamraju 
> ---
>  arch/powerpc/kernel/smp.c | 12 ++--
>  1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
> index 24529f6134aa..7d430fc536cc 100644
> --- a/arch/powerpc/kernel/smp.c
> +++ b/arch/powerpc/kernel/smp.c
> @@ -892,6 +892,12 @@ static int init_big_cores(void)
> }
>
> has_big_cores = true;
> +
> +#ifdef CONFIG_SCHED_SMT
> +   pr_info("Big cores detected. Using small core scheduling\n");
Why change the wording from "Big cores detected but using small core
scheduling\n"?
> +   powerpc_topology[0].mask = smallcore_smt_mask;
> +#endif
> +
> return 0;
>  }
>
> @@ -1383,12 +1389,6 @@ void __init smp_cpus_done(unsigned int max_cpus)
>
> dump_numa_cpu_topology();
>
> -#ifdef CONFIG_SCHED_SMT
> -   if (has_big_cores) {
> -   pr_info("Big cores detected but using small core 
> scheduling\n");
> -   powerpc_topology[0].mask = smallcore_smt_mask;
> -   }
> -#endif
> set_sched_topology(powerpc_topology);
>  }
>
> --
> 2.17.1
>


Re: [PATCH v4 10/10] powerpc/watchpoint: Remove 512 byte boundary

2020-07-20 Thread Jordan Niethe
On Fri, Jul 17, 2020 at 2:11 PM Ravi Bangoria
 wrote:
>
> Power10 has removed 512 bytes boundary from match criteria. i.e. The watch
> range can cross 512 bytes boundary.
It looks like this change is not mentioned in ISA v3.1 Book III 9.4
Data Address Watchpoint. It could be useful to mention that in the
commit message.
Also I wonder if could add a test for this to the ptrace-hwbreak selftest?

>
> Signed-off-by: Ravi Bangoria 
> ---
>  arch/powerpc/kernel/hw_breakpoint.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/kernel/hw_breakpoint.c 
> b/arch/powerpc/kernel/hw_breakpoint.c
> index c55e67bab271..1f4a1efa0074 100644
> --- a/arch/powerpc/kernel/hw_breakpoint.c
> +++ b/arch/powerpc/kernel/hw_breakpoint.c
> @@ -418,8 +418,9 @@ static int hw_breakpoint_validate_len(struct 
> arch_hw_breakpoint *hw)
>
> if (dawr_enabled()) {
> max_len = DAWR_MAX_LEN;
> -   /* DAWR region can't cross 512 bytes boundary */
> -   if (ALIGN_DOWN(start_addr, SZ_512) != ALIGN_DOWN(end_addr - 
> 1, SZ_512))
> +   /* DAWR region can't cross 512 bytes boundary on p10 
> predecessors */
> +   if (!cpu_has_feature(CPU_FTR_ARCH_31) &&
> +   (ALIGN_DOWN(start_addr, SZ_512) != ALIGN_DOWN(end_addr - 
> 1, SZ_512)))
> return -EINVAL;
> } else if (IS_ENABLED(CONFIG_PPC_8xx)) {
> /* 8xx can setup a range without limitation */
> --
> 2.26.2
>


Re: [PATCH v4 09/10] powerpc/watchpoint: Return available watchpoints dynamically

2020-07-19 Thread Jordan Niethe
On Fri, Jul 17, 2020 at 2:11 PM Ravi Bangoria
 wrote:
>
> So far Book3S Powerpc supported only one watchpoint. Power10 is
> introducing 2nd DAWR. Enable 2nd DAWR support for Power10.
> Availability of 2nd DAWR will depend on CPU_FTR_DAWR1.
>
> Signed-off-by: Ravi Bangoria 
> ---
>  arch/powerpc/include/asm/cputable.h  | 4 +++-
>  arch/powerpc/include/asm/hw_breakpoint.h | 5 +++--
>  2 files changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/cputable.h 
> b/arch/powerpc/include/asm/cputable.h
> index 3445c86e1f6f..36a0851a7a9b 100644
> --- a/arch/powerpc/include/asm/cputable.h
> +++ b/arch/powerpc/include/asm/cputable.h
> @@ -633,7 +633,9 @@ enum {
>   * Maximum number of hw breakpoint supported on powerpc. Number of
>   * breakpoints supported by actual hw might be less than this.
>   */
> -#define HBP_NUM_MAX1
> +#define HBP_NUM_MAX2
> +#define HBP_NUM_ONE1
> +#define HBP_NUM_TWO2
I wonder if these defines are necessary - has it any advantage over
just using the literal?
>
>  #endif /* !__ASSEMBLY__ */
>
> diff --git a/arch/powerpc/include/asm/hw_breakpoint.h 
> b/arch/powerpc/include/asm/hw_breakpoint.h
> index cb424799da0d..d4eab1694bcd 100644
> --- a/arch/powerpc/include/asm/hw_breakpoint.h
> +++ b/arch/powerpc/include/asm/hw_breakpoint.h
> @@ -5,10 +5,11 @@
>   * Copyright 2010, IBM Corporation.
>   * Author: K.Prasad 
>   */
> -
Was removing this line deliberate?
>  #ifndef _PPC_BOOK3S_64_HW_BREAKPOINT_H
>  #define _PPC_BOOK3S_64_HW_BREAKPOINT_H
>
> +#include 
> +
>  #ifdef __KERNEL__
>  struct arch_hw_breakpoint {
> unsigned long   address;
> @@ -46,7 +47,7 @@ struct arch_hw_breakpoint {
>
>  static inline int nr_wp_slots(void)
>  {
> -   return HBP_NUM_MAX;
> +   return cpu_has_feature(CPU_FTR_DAWR1) ? HBP_NUM_TWO : HBP_NUM_ONE;
So it'd be something like:
+   return cpu_has_feature(CPU_FTR_DAWR1) ? HBP_NUM_MAX : 1;
But thinking that there might be more slots added in the future, it
may be better to make the number of slots a variable that is set
during the init and then have this function return that.
>  }
>
>  #ifdef CONFIG_HAVE_HW_BREAKPOINT
> --
> 2.26.2
>


Re: [PATCH v4 07/10] powerpc/watchpoint: Rename current H_SET_MODE DAWR macro

2020-07-19 Thread Jordan Niethe
On Fri, Jul 17, 2020 at 2:11 PM Ravi Bangoria
 wrote:
>
> Current H_SET_MODE hcall macro name for setting/resetting DAWR0 is
> H_SET_MODE_RESOURCE_SET_DAWR. Add suffix 0 to macro name as well.
>
> Signed-off-by: Ravi Bangoria 
Reviewed-by: Jordan Niethe 
> ---
>  arch/powerpc/include/asm/hvcall.h | 2 +-
>  arch/powerpc/include/asm/plpar_wrappers.h | 2 +-
>  arch/powerpc/kvm/book3s_hv.c  | 2 +-
>  3 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/hvcall.h 
> b/arch/powerpc/include/asm/hvcall.h
> index 43486e773bd6..b785e9f0071c 100644
> --- a/arch/powerpc/include/asm/hvcall.h
> +++ b/arch/powerpc/include/asm/hvcall.h
> @@ -355,7 +355,7 @@
>
>  /* Values for 2nd argument to H_SET_MODE */
>  #define H_SET_MODE_RESOURCE_SET_CIABR  1
> -#define H_SET_MODE_RESOURCE_SET_DAWR   2
> +#define H_SET_MODE_RESOURCE_SET_DAWR0  2
>  #define H_SET_MODE_RESOURCE_ADDR_TRANS_MODE3
>  #define H_SET_MODE_RESOURCE_LE 4
>
> diff --git a/arch/powerpc/include/asm/plpar_wrappers.h 
> b/arch/powerpc/include/asm/plpar_wrappers.h
> index 4293c5d2ddf4..d12c3680d946 100644
> --- a/arch/powerpc/include/asm/plpar_wrappers.h
> +++ b/arch/powerpc/include/asm/plpar_wrappers.h
> @@ -312,7 +312,7 @@ static inline long plpar_set_ciabr(unsigned long ciabr)
>
>  static inline long plpar_set_watchpoint0(unsigned long dawr0, unsigned long 
> dawrx0)
>  {
> -   return plpar_set_mode(0, H_SET_MODE_RESOURCE_SET_DAWR, dawr0, dawrx0);
> +   return plpar_set_mode(0, H_SET_MODE_RESOURCE_SET_DAWR0, dawr0, 
> dawrx0);
>  }
>
>  static inline long plpar_signal_sys_reset(long cpu)
> diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
> index 6bf66649ab92..7ad692c2d7c7 100644
> --- a/arch/powerpc/kvm/book3s_hv.c
> +++ b/arch/powerpc/kvm/book3s_hv.c
> @@ -764,7 +764,7 @@ static int kvmppc_h_set_mode(struct kvm_vcpu *vcpu, 
> unsigned long mflags,
> return H_P3;
> vcpu->arch.ciabr  = value1;
> return H_SUCCESS;
> -   case H_SET_MODE_RESOURCE_SET_DAWR:
> +   case H_SET_MODE_RESOURCE_SET_DAWR0:
> if (!kvmppc_power8_compatible(vcpu))
> return H_P2;
> if (!ppc_breakpoint_available())
> --
> 2.26.2
>


Re: [PATCH v4 06/10] powerpc/watchpoint: Set CPU_FTR_DAWR1 based on pa-features bit

2020-07-19 Thread Jordan Niethe
On Fri, Jul 17, 2020 at 2:10 PM Ravi Bangoria
 wrote:
>
> As per the PAPR, bit 0 of byte 64 in pa-features property indicates
> availability of 2nd DAWR registers. i.e. If this bit is set, 2nd
> DAWR is present, otherwise not. Host generally uses "cpu-features",
> which masks "pa-features". But "cpu-features" are still not used for
> guests and thus this change is mostly applicable for guests only.
>
> Signed-off-by: Ravi Bangoria 
I checked those PAPR values are correct and checked running a powernv
kernel in p10 mambo with dt_cpu_ftrs=off and it does set the
CPU_FTR_DAWR1 bit.
(using p10 skiboot).
Tested-by: Jordan Niethe 
> ---
>  arch/powerpc/kernel/prom.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
> index 9cc49f265c86..c76c09b97bc8 100644
> --- a/arch/powerpc/kernel/prom.c
> +++ b/arch/powerpc/kernel/prom.c
> @@ -175,6 +175,8 @@ static struct ibm_pa_feature {
>  */
> { .pabyte = 22, .pabit = 0, .cpu_features = CPU_FTR_TM_COMP,
>   .cpu_user_ftrs2 = PPC_FEATURE2_HTM_COMP | 
> PPC_FEATURE2_HTM_NOSC_COMP },
> +
> +   { .pabyte = 64, .pabit = 0, .cpu_features = CPU_FTR_DAWR1 },
>  };
>
>  static void __init scan_features(unsigned long node, const unsigned char 
> *ftrs,
> --
> 2.26.2
>


Re: [PATCH v4 05/10] powerpc/dt_cpu_ftrs: Add feature for 2nd DAWR

2020-07-16 Thread Jordan Niethe
On Fri, Jul 17, 2020 at 2:10 PM Ravi Bangoria
 wrote:
>
> Add new device-tree feature for 2nd DAWR. If this feature is present,
> 2nd DAWR is supported, otherwise not.
>
> Signed-off-by: Ravi Bangoria 
> ---
>  arch/powerpc/include/asm/cputable.h | 7 +--
>  arch/powerpc/kernel/dt_cpu_ftrs.c   | 7 +++
>  2 files changed, 12 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/cputable.h 
> b/arch/powerpc/include/asm/cputable.h
> index e506d429b1af..3445c86e1f6f 100644
> --- a/arch/powerpc/include/asm/cputable.h
> +++ b/arch/powerpc/include/asm/cputable.h
> @@ -214,6 +214,7 @@ static inline void cpu_feature_keys_init(void) { }
>  #define CPU_FTR_P9_TLBIE_ERAT_BUG  LONG_ASM_CONST(0x0001)
>  #define CPU_FTR_P9_RADIX_PREFETCH_BUG  LONG_ASM_CONST(0x0002)
>  #define CPU_FTR_ARCH_31
> LONG_ASM_CONST(0x0004)
> +#define CPU_FTR_DAWR1  LONG_ASM_CONST(0x0008)
>
>  #ifndef __ASSEMBLY__
>
> @@ -497,14 +498,16 @@ static inline void cpu_feature_keys_init(void) { }
>  #define CPU_FTRS_POSSIBLE  \
> (CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | CPU_FTRS_POWER8 | \
>  CPU_FTR_ALTIVEC_COMP | CPU_FTR_VSX_COMP | CPU_FTRS_POWER9 | \
> -CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2 | CPU_FTRS_POWER10)
> +CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2 | CPU_FTRS_POWER10 
> | \
> +CPU_FTR_DAWR1)
>  #else
>  #define CPU_FTRS_POSSIBLE  \
> (CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | \
>  CPU_FTRS_POWER6 | CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | \
>  CPU_FTRS_POWER8 | CPU_FTRS_CELL | CPU_FTRS_PA6T | \
>  CPU_FTR_VSX_COMP | CPU_FTR_ALTIVEC_COMP | CPU_FTRS_POWER9 | \
> -CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2 | CPU_FTRS_POWER10)
> +CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2 | CPU_FTRS_POWER10 
> | \
> +CPU_FTR_DAWR1)
Instead of putting CPU_FTR_DAWR1 into CPU_FTRS_POSSIBLE should it go
into CPU_FTRS_POWER10?
Then it will be picked up by CPU_FTRS_POSSIBLE.
>  #endif /* CONFIG_CPU_LITTLE_ENDIAN */
>  #endif
>  #else
> diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c 
> b/arch/powerpc/kernel/dt_cpu_ftrs.c
> index ac650c233cd9..c78cd3596ec4 100644
> --- a/arch/powerpc/kernel/dt_cpu_ftrs.c
> +++ b/arch/powerpc/kernel/dt_cpu_ftrs.c
> @@ -574,6 +574,12 @@ static int __init feat_enable_mma(struct dt_cpu_feature 
> *f)
> return 1;
>  }
>
> +static int __init feat_enable_debug_facilities_v31(struct dt_cpu_feature *f)
> +{
> +   cur_cpu_spec->cpu_features |= CPU_FTR_DAWR1;
> +   return 1;
> +}
> +
>  struct dt_cpu_feature_match {
> const char *name;
> int (*enable)(struct dt_cpu_feature *f);
> @@ -649,6 +655,7 @@ static struct dt_cpu_feature_match __initdata
> {"wait-v3", feat_enable, 0},
> {"prefix-instructions", feat_enable, 0},
> {"matrix-multiply-assist", feat_enable_mma, 0},
> +   {"debug-facilities-v31", feat_enable_debug_facilities_v31, 0},
Since all feat_enable_debug_facilities_v31() does is set
CPU_FTR_DAWR1, if you just have:
{"debug-facilities-v31", feat_enable, CPU_FTR_DAWR1},
I think cpufeatures_process_feature() should set it in for you at this point:
if (m->enable(f)) {
cur_cpu_spec->cpu_features |= m->cpu_ftr_bit_mask;
break;
}

>  };
>
>  static bool __initdata using_dt_cpu_ftrs;
> --
> 2.26.2
>


Re: [PATCH v4 04/10] powerpc/watchpoint: Enable watchpoint functionality on power10 guest

2020-07-16 Thread Jordan Niethe
On Fri, Jul 17, 2020 at 2:10 PM Ravi Bangoria
 wrote:
>
> CPU_FTR_DAWR is by default enabled for host via CPU_FTRS_DT_CPU_BASE
> (controlled by CONFIG_PPC_DT_CPU_FTRS). But cpu-features device-tree
> node is not PAPR compatible and thus not yet used by kvm or pHyp
> guests. Enable watchpoint functionality on power10 guest (both kvm
> and powervm) by adding CPU_FTR_DAWR to CPU_FTRS_POWER10. Note that
> this change does not enable 2nd DAWR support.
>
> Signed-off-by: Ravi Bangoria 
I ran the ptrace-hwbreak selftest successfully within a power10 kvm guest.
Tested-by: Jordan Niethe 
> ---
>  arch/powerpc/include/asm/cputable.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/include/asm/cputable.h 
> b/arch/powerpc/include/asm/cputable.h
> index bac2252c839e..e506d429b1af 100644
> --- a/arch/powerpc/include/asm/cputable.h
> +++ b/arch/powerpc/include/asm/cputable.h
> @@ -478,7 +478,7 @@ static inline void cpu_feature_keys_init(void) { }
> CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
> CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_ARCH_207S | \
> CPU_FTR_TM_COMP | CPU_FTR_ARCH_300 | CPU_FTR_PKEY | \
> -   CPU_FTR_ARCH_31)
> +   CPU_FTR_ARCH_31 | CPU_FTR_DAWR)
>  #define CPU_FTRS_CELL  (CPU_FTR_LWSYNC | \
> CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
> CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
> --
> 2.26.2
>


Re: [PATCH v3 2/9] powerpc/watchpoint: Fix DAWR exception constraint

2020-07-14 Thread Jordan Niethe
On Wed, Jul 8, 2020 at 2:52 PM Ravi Bangoria
 wrote:
>
> Pedro Miraglia Franco de Carvalho noticed that on p8, DAR value is
> inconsistent with different type of load/store. Like for byte,word
> etc. load/stores, DAR is set to the address of the first byte of
> overlap between watch range and real access. But for quadword load/
> store it's set to the address of the first byte of real access. This
> issue has been fixed in p10. In p10(ISA 3.1), DAR is always set to
> the address of the first byte of overlap. Commit 27985b2a640e
> ("powerpc/watchpoint: Don't ignore extraneous exceptions blindly")
> wrongly assumes that DAR is set to the address of the first byte of
> overlap for all load/stores on p8 as well. Fix that. With the fix,
> we now rely on 'ea' provided by analyse_instr(). If analyse_instr()
> fails, generate event unconditionally on p8, and on p10 generate
> event only if DAR is within a DAWR range.
>
> Note: 8xx is not affected.
>
> Fixes: 27985b2a640e ("powerpc/watchpoint: Don't ignore extraneous exceptions 
> blindly")
> Fixes: 74c6881019b7 ("powerpc/watchpoint: Prepare handler to handle more than 
> one watchpoint")
> Reported-by: Pedro Miraglia Franco de Carvalho 
> Signed-off-by: Ravi Bangoria 
> ---
>  arch/powerpc/kernel/hw_breakpoint.c | 93 +++--
>  1 file changed, 63 insertions(+), 30 deletions(-)
>
> diff --git a/arch/powerpc/kernel/hw_breakpoint.c 
> b/arch/powerpc/kernel/hw_breakpoint.c
> index 031e6defc08e..7a66c370a105 100644
> --- a/arch/powerpc/kernel/hw_breakpoint.c
> +++ b/arch/powerpc/kernel/hw_breakpoint.c
> @@ -498,11 +498,11 @@ static bool dar_in_user_range(unsigned long dar, struct 
> arch_hw_breakpoint *info
> return ((info->address <= dar) && (dar - info->address < info->len));
>  }
>
> -static bool dar_user_range_overlaps(unsigned long dar, int size,
> -   struct arch_hw_breakpoint *info)
> +static bool ea_user_range_overlaps(unsigned long ea, int size,
> +  struct arch_hw_breakpoint *info)
>  {
> -   return ((dar < info->address + info->len) &&
> -   (dar + size > info->address));
> +   return ((ea < info->address + info->len) &&
> +   (ea + size > info->address));
>  }
>
>  static bool dar_in_hw_range(unsigned long dar, struct arch_hw_breakpoint 
> *info)
> @@ -515,20 +515,22 @@ static bool dar_in_hw_range(unsigned long dar, struct 
> arch_hw_breakpoint *info)
> return ((hw_start_addr <= dar) && (hw_end_addr > dar));
>  }
>
> -static bool dar_hw_range_overlaps(unsigned long dar, int size,
> - struct arch_hw_breakpoint *info)
> +static bool ea_hw_range_overlaps(unsigned long ea, int size,
> +struct arch_hw_breakpoint *info)
>  {
> unsigned long hw_start_addr, hw_end_addr;
>
> hw_start_addr = ALIGN_DOWN(info->address, HW_BREAKPOINT_SIZE);
> hw_end_addr = ALIGN(info->address + info->len, HW_BREAKPOINT_SIZE);
>
> -   return ((dar < hw_end_addr) && (dar + size > hw_start_addr));
> +   return ((ea < hw_end_addr) && (ea + size > hw_start_addr));
>  }
>
>  /*
>   * If hw has multiple DAWR registers, we also need to check all
>   * dawrx constraint bits to confirm this is _really_ a valid event.
> + * If type is UNKNOWN, but privilege level matches, consider it as
> + * a positive match.
>   */
>  static bool check_dawrx_constraints(struct pt_regs *regs, int type,
> struct arch_hw_breakpoint *info)
> @@ -536,7 +538,12 @@ static bool check_dawrx_constraints(struct pt_regs 
> *regs, int type,
> if (OP_IS_LOAD(type) && !(info->type & HW_BRK_TYPE_READ))
> return false;
>
> -   if (OP_IS_STORE(type) && !(info->type & HW_BRK_TYPE_WRITE))
> +   /*
> +* The Cache Management instructions other than dcbz never
> +* cause a match. i.e. if type is CACHEOP, the instruction
> +* is dcbz, and dcbz is treated as Store.
> +*/
> +   if ((OP_IS_STORE(type) || type == CACHEOP) && !(info->type & 
> HW_BRK_TYPE_WRITE))
> return false;
This change seems seperate to this commit?
>
> if (is_kernel_addr(regs->nip) && !(info->type & HW_BRK_TYPE_KERNEL))
> @@ -553,7 +560,8 @@ static bool check_dawrx_constraints(struct pt_regs *regs, 
> int type,
>   * including extraneous exception. Otherwise return false.
>   */
>  static bool check_constraints(struct pt_regs *regs, struct ppc_inst instr,
> - int type, int size, struct arch_hw_breakpoint 
> *info)
> + unsigned long ea, int type, int size,
> + struct arch_hw_breakpoint *info)
>  {
> bool in_user_range = dar_in_user_range(regs->dar, info);
> bool dawrx_constraints;
> @@ -569,11 +577,10 @@ static bool check_constraints(struct pt_regs *regs, 
> struct ppc_inst instr,
> }
>
> if 

Re: [PATCH v3 1/9] powerpc/watchpoint: Fix 512 byte boundary limit

2020-07-14 Thread Jordan Niethe
On Wed, Jul 8, 2020 at 2:53 PM Ravi Bangoria
 wrote:
>
> Milton Miller reported that we are aligning start and end address to
> wrong size SZ_512M. It should be SZ_512. Fix that.
>
> While doing this change I also found a case where ALIGN() comparison
> fails. Within a given aligned range, ALIGN() of two addresses does not
> match when start address is pointing to the first byte and end address
> is pointing to any other byte except the first one. But that's not true
> for ALIGN_DOWN(). ALIGN_DOWN() of any two addresses within that range
> will always point to the first byte. So use ALIGN_DOWN() instead of
> ALIGN().
>
> Fixes: e68ef121c1f4 ("powerpc/watchpoint: Use builtin ALIGN*() macros")
> Reported-by: Milton Miller 
> Signed-off-by: Ravi Bangoria 
I tested this with the ptrace-hwbreak selftest. Can confirm without
also changing to ALIGN_DOWN() then these tests will fail.
Tested-by: Jordan Niethe 
> ---
>  arch/powerpc/kernel/hw_breakpoint.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/kernel/hw_breakpoint.c 
> b/arch/powerpc/kernel/hw_breakpoint.c
> index daf0e1da..031e6defc08e 100644
> --- a/arch/powerpc/kernel/hw_breakpoint.c
> +++ b/arch/powerpc/kernel/hw_breakpoint.c
> @@ -419,7 +419,7 @@ static int hw_breakpoint_validate_len(struct 
> arch_hw_breakpoint *hw)
> if (dawr_enabled()) {
> max_len = DAWR_MAX_LEN;
> /* DAWR region can't cross 512 bytes boundary */
> -   if (ALIGN(start_addr, SZ_512M) != ALIGN(end_addr - 1, 
> SZ_512M))
> +   if (ALIGN_DOWN(start_addr, SZ_512) != ALIGN_DOWN(end_addr - 
> 1, SZ_512))
> return -EINVAL;
> } else if (IS_ENABLED(CONFIG_PPC_8xx)) {
> /* 8xx can setup a range without limitation */
> --
> 2.26.2
>


Re: [PATCH v3 1/9] powerpc/watchpoint: Fix 512 byte boundary limit

2020-07-08 Thread Jordan Niethe
On Wed, Jul 8, 2020 at 2:53 PM Ravi Bangoria
 wrote:
>
> Milton Miller reported that we are aligning start and end address to
> wrong size SZ_512M. It should be SZ_512. Fix that.
>
> While doing this change I also found a case where ALIGN() comparison
> fails. Within a given aligned range, ALIGN() of two addresses does not
> match when start address is pointing to the first byte and end address
> is pointing to any other byte except the first one. But that's not true
> for ALIGN_DOWN(). ALIGN_DOWN() of any two addresses within that range
> will always point to the first byte. So use ALIGN_DOWN() instead of
> ALIGN().
>
> Fixes: e68ef121c1f4 ("powerpc/watchpoint: Use builtin ALIGN*() macros")
> Reported-by: Milton Miller 
> Signed-off-by: Ravi Bangoria 
> ---
>  arch/powerpc/kernel/hw_breakpoint.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/kernel/hw_breakpoint.c 
> b/arch/powerpc/kernel/hw_breakpoint.c
> index daf0e1da..031e6defc08e 100644
> --- a/arch/powerpc/kernel/hw_breakpoint.c
> +++ b/arch/powerpc/kernel/hw_breakpoint.c
> @@ -419,7 +419,7 @@ static int hw_breakpoint_validate_len(struct 
> arch_hw_breakpoint *hw)
> if (dawr_enabled()) {
> max_len = DAWR_MAX_LEN;
> /* DAWR region can't cross 512 bytes boundary */
> -   if (ALIGN(start_addr, SZ_512M) != ALIGN(end_addr - 1, 
> SZ_512M))
> +   if (ALIGN_DOWN(start_addr, SZ_512) != ALIGN_DOWN(end_addr - 
> 1, SZ_512))
I wonder if you should use end_addr - 1, but rather end_addr. For example:
512 -> 1023, because of the -1, 1024 will now be included in this
range meaning 513 bytes?

> return -EINVAL;
> } else if (IS_ENABLED(CONFIG_PPC_8xx)) {
> /* 8xx can setup a range without limitation */
> --
> 2.26.2
>


Re: [PATCH 2/6] powerpc test_emulate_step: fix pr_info() to print 8-byte for prefixed instruction

2020-06-22 Thread Jordan Niethe
On Mon, Jun 22, 2020 at 5:10 PM Balamuruhan S  wrote:
>
> On test failure, `pr_log()` prints 4 bytes instruction
> irrespective of word/prefix instruction, fix it by printing
> them appropriately.
This patch to add a ppc_inst_as_str() function should help with this,
https://patchwork.ozlabs.org/project/linuxppc-dev/patch/20200602052728.18227-1-jniet...@gmail.com/
>
> Signed-off-by: Balamuruhan S 
> ---
>  arch/powerpc/lib/test_emulate_step.c | 9 -
>  1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/lib/test_emulate_step.c 
> b/arch/powerpc/lib/test_emulate_step.c
> index d5902b7b4e5c..e3b1797adfae 100644
> --- a/arch/powerpc/lib/test_emulate_step.c
> +++ b/arch/powerpc/lib/test_emulate_step.c
> @@ -1225,7 +1225,14 @@ static int __init emulate_compute_instr(struct pt_regs 
> *regs,
>
> if (analyse_instr(, regs, instr) != 1 ||
> GETTYPE(op.type) != COMPUTE) {
> -   pr_info("emulation failed, instruction = 0x%08x\n", 
> ppc_inst_val(instr));
> +   if (!ppc_inst_prefixed(instr)) {
> +   pr_info("emulation failed, instruction = 0x%08x\n",
> +   ppc_inst_val(instr));
> +   } else {
> +   pr_info("emulation failed, instruction = 0x%08x 
> 0x%08x\n",
> +   ppc_inst_val(instr),
> +   ppc_inst_suffix(instr));
> +   }
> return -EFAULT;
> }
>
> --
> 2.24.1
>


Re: [PATCH 1/6] powerpc test_emulate_step: update nip with patched instruction address

2020-06-22 Thread Jordan Niethe
On Mon, Jun 22, 2020 at 5:10 PM Balamuruhan S  wrote:
>
> pt_regs are initialized to zero in the test infrastructure, R bit
> in prefixed instruction form is used to specify whether the effective
> address of the storage operand is computed relative to the address
> of the instruction.
>
> If R = 1 and RA = R0|0, the sum of the address of the instruction
> and the value SI is placed into register RT. So to assert the emulated
> instruction with executed instruction, update nip of emulated pt_regs.
>
> Signed-off-by: Balamuruhan S 
> ---
>  arch/powerpc/lib/test_emulate_step.c | 13 -
>  1 file changed, 12 insertions(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/lib/test_emulate_step.c 
> b/arch/powerpc/lib/test_emulate_step.c
> index 33a72b7d2764..d5902b7b4e5c 100644
> --- a/arch/powerpc/lib/test_emulate_step.c
> +++ b/arch/powerpc/lib/test_emulate_step.c
> @@ -1204,13 +1204,24 @@ static struct compute_test compute_tests[] = {
>  static int __init emulate_compute_instr(struct pt_regs *regs,
> struct ppc_inst instr)
>  {
> +   int prefix_r, ra;
> extern s32 patch__exec_instr;
> struct instruction_op op;
>
> if (!regs || !ppc_inst_val(instr))
> return -EINVAL;
>
> -   regs->nip = patch_site_addr(__exec_instr);
Is there any harm in just always setting the NIP like this instead of
only setting it for relative prefixed instructions?
> +   /*
> +* If R=1 and RA=0 in Prefixed instruction form, calculate the address
> +* of the instruction and update nip to assert with executed
> +* instruction
> +*/
> +   if (ppc_inst_prefixed(instr)) {
> +   prefix_r = ppc_inst_val(instr) & (1UL << 20);
> +   ra = (ppc_inst_suffix(instr) >> 16) & 0x1f;
> +   if (prefix_r && !ra)
> +   regs->nip = patch_site_addr(__exec_instr);
> +   }
>
> if (analyse_instr(, regs, instr) != 1 ||
> GETTYPE(op.type) != COMPUTE) {
> --
> 2.24.1
>


Re: [PATCH] powerpc/kvm: Enable support for ISA v3.1 guests

2020-06-02 Thread Jordan Niethe
On Tue, Jun 2, 2020 at 3:55 PM Alistair Popple  wrote:
>
> Adds support for emulating ISAv3.1 guests by adding the appropriate PCR
> and FSCR bits.
>
> Signed-off-by: Alistair Popple 
> ---
>  arch/powerpc/include/asm/reg.h |  1 +
>  arch/powerpc/kvm/book3s_hv.c   | 11 ---
>  2 files changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
> index 773f76402392..d77040d0588a 100644
> --- a/arch/powerpc/include/asm/reg.h
> +++ b/arch/powerpc/include/asm/reg.h
> @@ -1348,6 +1348,7 @@
>  #define PVR_ARCH_206p  0x0f13
>  #define PVR_ARCH_207   0x0f04
>  #define PVR_ARCH_300   0x0f05
> +#define PVR_ARCH_310x0f06
>
>  /* Macros for setting and retrieving special purpose registers */
>  #ifndef __ASSEMBLY__
> diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
> index 93493f0cbfe8..359bb2ed43e1 100644
> --- a/arch/powerpc/kvm/book3s_hv.c
> +++ b/arch/powerpc/kvm/book3s_hv.c
> @@ -345,7 +345,7 @@ static void kvmppc_set_pvr_hv(struct kvm_vcpu *vcpu, u32 
> pvr)
>  }
>
>  /* Dummy value used in computing PCR value below */
> -#define PCR_ARCH_300   (PCR_ARCH_207 << 1)
> +#define PCR_ARCH_31(PCR_ARCH_300 << 1)
>
>  static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat)
>  {
> @@ -353,7 +353,9 @@ static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, 
> u32 arch_compat)
> struct kvmppc_vcore *vc = vcpu->arch.vcore;
>
> /* We can (emulate) our own architecture version and anything older */
> -   if (cpu_has_feature(CPU_FTR_ARCH_300))
> +   if (cpu_has_feature(CPU_FTR_ARCH_31))
> +   host_pcr_bit = PCR_ARCH_31;
> +   else if (cpu_has_feature(CPU_FTR_ARCH_300))
> host_pcr_bit = PCR_ARCH_300;
> else if (cpu_has_feature(CPU_FTR_ARCH_207S))
> host_pcr_bit = PCR_ARCH_207;
> @@ -379,6 +381,9 @@ static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, 
> u32 arch_compat)
> case PVR_ARCH_300:
> guest_pcr_bit = PCR_ARCH_300;
> break;
> +   case PVR_ARCH_31:
> +   guest_pcr_bit = PCR_ARCH_31;
> +   break;
> default:
> return -EINVAL;
> }
> @@ -2318,7 +2323,7 @@ static int kvmppc_core_vcpu_create_hv(struct kvm_vcpu 
> *vcpu)
>  * to trap and then we emulate them.
>  */
The comment above this:
"...
 * Set the default HFSCR for the guest from the host value.
 * This value is only used on POWER9..."
would need to be updated.
> vcpu->arch.hfscr = HFSCR_TAR | HFSCR_EBB | HFSCR_PM | HFSCR_BHRB |
> -   HFSCR_DSCR | HFSCR_VECVSX | HFSCR_FP;
> +   HFSCR_DSCR | HFSCR_VECVSX | HFSCR_FP | HFSCR_PREFIX;
> if (cpu_has_feature(CPU_FTR_HVMODE)) {
> vcpu->arch.hfscr &= mfspr(SPRN_HFSCR);
> if (cpu_has_feature(CPU_FTR_P9_TM_HV_ASSIST))
> --
> 2.20.1
>


[PATCH 4/4] powerpc: Handle prefixed instructions in show_instructions()

2020-06-01 Thread Jordan Niethe
Currently show_instructions() treats prefixed instructions as two
separate word instructions. '<' and '>' are placed around the
instruction at the NIP, but as a result they only wrap around the
prefix. Make '<' and '>' straddle the whole prefixed instruction.

Currently showing a prefixed instruction looks like:

Instruction dump:
6000 6000 6000 6000 6000 6000 6000 6000
6000 6000 6000 6000 <0400>  6000 6000

Make it look like:
Instruction dump:
0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 0x6000 
0x6000
0x6000 0x6000 0x6000 0x6000 <0x0400 0x> 0x6000 
0x6000 0x6000

Signed-off-by: Jordan Niethe 
---
 arch/powerpc/kernel/process.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index b3f73e398d00..bcd7277a9395 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1258,7 +1258,7 @@ static void show_instructions(struct pt_regs *regs)
printk("Instruction dump:");
 
for (i = 0; i < NR_INSN_TO_PRINT; i++) {
-   int instr;
+   struct ppc_inst instr;
 
if (!(i % 8))
pr_cont("\n");
@@ -1272,16 +1272,17 @@ static void show_instructions(struct pt_regs *regs)
 #endif
 
if (!__kernel_text_address(pc) ||
-   probe_kernel_address((const void *)pc, instr)) {
+   probe_kernel_read_inst(, (struct ppc_inst *)pc)) {
+   instr = ppc_inst(PPC_INST_NOP);
pr_cont(" ");
} else {
if (regs->nip == pc)
-   pr_cont("<%08x> ", instr);
+   pr_cont("<%s> ", ppc_inst_as_str(instr));
else
-   pr_cont("%08x ", instr);
+   pr_cont("%s ", ppc_inst_as_str(instr));
}
 
-   pc += sizeof(int);
+   pc += ppc_inst_len(instr);
}
 
pr_cont("\n");
-- 
2.17.1



[PATCH 3/4] powerpc: Handle prefixed instructions in show_user_instructions()

2020-06-01 Thread Jordan Niethe
Currently prefixed instructions are treated as two word instructions by
show_user_instructions(), treat them as a single instruction. '<' and
'>' are placed around the instruction at the NIP, and for prefixed
instructions this is placed around the prefix only. Make the '<' and '>'
wrap the prefix and suffix.

Currently showing a prefixed instruction looks like:
fbe1fff8 3920 0600 a3e3 <0400> f7e4 ebe1fff8 4e800020

Make it look like:
0xfbe1fff8 0x3920 0x0600 0xa3e3 <0x0400 0xf7e4> 0xebe1fff8 
0x4e800020 0x 0x0000

Signed-off-by: Jordan Niethe 
---
 arch/powerpc/kernel/process.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 048d64c4e115..b3f73e398d00 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1292,7 +1292,8 @@ void show_user_instructions(struct pt_regs *regs)
unsigned long pc;
int n = NR_INSN_TO_PRINT;
struct seq_buf s;
-   char buf[96]; /* enough for 8 times 9 + 2 chars */
+   char buf[8 * sizeof("0x 0x") + 2];
+   struct ppc_inst instr;
 
pc = regs->nip - (NR_INSN_TO_PRINT * 3 / 4 * sizeof(int));
 
@@ -1303,14 +1304,15 @@ void show_user_instructions(struct pt_regs *regs)
 
seq_buf_clear();
 
-   for (i = 0; i < 8 && n; i++, n--, pc += sizeof(int)) {
-   int instr;
+   for (i = 0; i < 8 && n; i++, n--, pc += ppc_inst_len(instr)) {
 
-   if (probe_user_read(, (void __user *)pc, 
sizeof(instr))) {
+   if (probe_user_read_inst(, (void __user *)pc)) {
seq_buf_printf(, " ");
+   instr = ppc_inst(PPC_INST_NOP);
continue;
}
-   seq_buf_printf(, regs->nip == pc ? "<%08x> " : "%08x 
", instr);
+   seq_buf_printf(, regs->nip == pc ? "<%s> " : "%s ",
+  ppc_inst_as_str(instr));
}
 
if (!seq_buf_has_overflowed())
-- 
2.17.1



[PATCH 2/4] powerpc/xmon: Improve dumping prefixed instructions

2020-06-01 Thread Jordan Niethe
Currently prefixed instructions are dumped as two separate word
instructions. Use mread_instr() so that prefixed instructions are read
as such and update the incrementor in the loop to take this into
account.

'dump_func' is print_insn_powerpc() which comes from ppc-dis.c which is
taken from binutils. When this is updated prefixed instructions will be
disassembled.

Currently dumping prefixed instructions looks like this:
0:mon> di c0094168
c0094168  0x0600.long 0x600
c009416c  0x392a0003addir9,r10,3
c0094170  0x913f0028stw r9,40(r31)
c0094174  0xe93f002alwa r9,40(r31)
c0094178  0x7d234b78mr  r3,r9
c009417c  0x383f0040addir1,r31,64
c0094180  0xebe1fff8ld  r31,-8(r1)
c0094184  0x4e800020blr
c0094188  0x6000nop
 ...
c0094190  0x3c4c0121addis   r2,r12,289
c0094194  0x38429670addir2,r2,-27024
c0094198  0x7c0802a6mflrr0
c009419c  0x6000nop
c00941a0  0xe9240100ld  r9,256(r4)
c00941a4  0x3941li  r10,1

After this it looks like:
0:mon> di c0094168
c0094168  0x0600 0x392a0003 .long 0x392a00030600
c0094170  0x913f0028stw r9,40(r31)
c0094174  0xe93f002alwa r9,40(r31)
c0094178  0x7d234b78mr  r3,r9
c009417c  0x383f0040addir1,r31,64
c0094180  0xebe1fff8ld  r31,-8(r1)
c0094184  0x4e800020blr
c0094188  0x6000nop
 ...
c0094190  0x3c4c0121addis   r2,r12,289
c0094194  0x38429570addir2,r2,-27280
c0094198  0x7c0802a6mflrr0
c009419c  0x6000nop
c00941a0  0xe9240100ld  r9,256(r4)
c00941a4  0x3941li  r10,1
c00941a8  0x3d02000baddis   r8,r2,11

Signed-off-by: Jordan Niethe 
---
 arch/powerpc/xmon/xmon.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 1dd3bf02021b..548571536bd1 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -2935,11 +2935,10 @@ generic_inst_dump(unsigned long adr, long count, int 
praddr,
int nr, dotted;
unsigned long first_adr;
struct ppc_inst inst, last_inst = ppc_inst(0);
-   unsigned char val[4];
 
dotted = 0;
-   for (first_adr = adr; count > 0; --count, adr += 4) {
-   nr = mread(adr, val, 4);
+   for (first_adr = adr; count > 0; --count, adr += ppc_inst_len(inst)) {
+   nr = mread_instr(adr, );
if (nr == 0) {
if (praddr) {
const char *x = fault_chars[fault_type];
@@ -2947,7 +2946,6 @@ generic_inst_dump(unsigned long adr, long count, int 
praddr,
}
break;
}
-   inst = ppc_inst(GETWORD(val));
if (adr > first_adr && ppc_inst_equal(inst, last_inst)) {
if (!dotted) {
printf(" ...\n");
@@ -2960,7 +2958,10 @@ generic_inst_dump(unsigned long adr, long count, int 
praddr,
if (praddr)
printf(REG"  %s", adr, ppc_inst_as_str(inst));
printf("\t");
-   dump_func(ppc_inst_val(inst), adr);
+   if (!ppc_inst_prefixed(inst))
+   dump_func(ppc_inst_val(inst), adr);
+   else
+   dump_func(ppc_inst_as_u64(inst), adr);
printf("\n");
}
return adr - first_adr;
-- 
2.17.1



[PATCH 1/4] powerpc: Add a ppc_inst_as_str() helper

2020-06-01 Thread Jordan Niethe
There are quite a few places where instructions are printed, this is
done using a '%x' format specifier. With the introduction of prefixed
instructions, this does not work well. Currently in these places,
ppc_inst_val() is used for the value for %x so only the first word of
prefixed instructions are printed.

When the instructions are word instructions, only a single word should
be printed. For prefixed instructions both the prefix and suffix should
be printed. To accommodate both of these situations, instead of a '%x'
specifier use '%s' and introduce a helper, __ppc_inst_as_str() which
returns a char *. The char * __ppc_inst_as_str() returns is buffer that
is passed to it by the caller.

It is cumbersome to require every caller of __ppc_inst_as_str() to now
declare a buffer. To make it more convenient to use __ppc_inst_as_str(),
wrap it in a macro that uses a compound statement to allocate a buffer
on the caller's stack before calling it.

Signed-off-by: Jordan Niethe 
---
 arch/powerpc/include/asm/inst.h  | 19 +++
 arch/powerpc/kernel/kprobes.c|  2 +-
 arch/powerpc/kernel/trace/ftrace.c   | 26 +-
 arch/powerpc/lib/test_emulate_step.c |  4 ++--
 arch/powerpc/xmon/xmon.c |  2 +-
 5 files changed, 36 insertions(+), 17 deletions(-)

diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h
index 45f3ec868258..3df7806e6dc3 100644
--- a/arch/powerpc/include/asm/inst.h
+++ b/arch/powerpc/include/asm/inst.h
@@ -122,6 +122,25 @@ static inline u64 ppc_inst_as_u64(struct ppc_inst x)
 #endif
 }
 
+#define PPC_INST_STR_LEN sizeof("0x 0x")
+
+static inline char *__ppc_inst_as_str(char str[PPC_INST_STR_LEN], struct 
ppc_inst x)
+{
+   if (ppc_inst_prefixed(x))
+   sprintf(str, "0x%08x 0x%08x", ppc_inst_val(x), 
ppc_inst_suffix(x));
+   else
+   sprintf(str, "0x%08x", ppc_inst_val(x));
+
+   return str;
+}
+
+#define ppc_inst_as_str(x) \
+({ \
+   char __str[PPC_INST_STR_LEN];   \
+   __ppc_inst_as_str(__str, x);\
+   __str;  \
+})
+
 int probe_user_read_inst(struct ppc_inst *inst,
 struct ppc_inst __user *nip);
 
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 227510df8c55..d0797171dba3 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -244,7 +244,7 @@ static int try_to_emulate(struct kprobe *p, struct pt_regs 
*regs)
 * So, we should never get here... but, its still
 * good to catch them, just in case...
 */
-   printk("Can't step on instruction %x\n", ppc_inst_val(insn));
+   printk("Can't step on instruction %s\n", ppc_inst_as_str(insn));
BUG();
} else {
/*
diff --git a/arch/powerpc/kernel/trace/ftrace.c 
b/arch/powerpc/kernel/trace/ftrace.c
index 5e399628f51a..da11a26d8213 100644
--- a/arch/powerpc/kernel/trace/ftrace.c
+++ b/arch/powerpc/kernel/trace/ftrace.c
@@ -73,8 +73,8 @@ ftrace_modify_code(unsigned long ip, struct ppc_inst old, 
struct ppc_inst new)
 
/* Make sure it is what we expect it to be */
if (!ppc_inst_equal(replaced, old)) {
-   pr_err("%p: replaced (%#x) != old (%#x)",
-   (void *)ip, ppc_inst_val(replaced), ppc_inst_val(old));
+   pr_err("%p: replaced (%s) != old (%s)",
+   (void *)ip, ppc_inst_as_str(replaced), ppc_inst_as_str(old));
return -EINVAL;
}
 
@@ -137,7 +137,7 @@ __ftrace_make_nop(struct module *mod,
 
/* Make sure that that this is still a 24bit jump */
if (!is_bl_op(op)) {
-   pr_err("Not expected bl: opcode is %x\n", ppc_inst_val(op));
+   pr_err("Not expected bl: opcode is %s\n", ppc_inst_as_str(op));
return -EINVAL;
}
 
@@ -172,8 +172,8 @@ __ftrace_make_nop(struct module *mod,
/* We expect either a mflr r0, or a std r0, LRSAVE(r1) */
if (!ppc_inst_equal(op, ppc_inst(PPC_INST_MFLR)) &&
!ppc_inst_equal(op, ppc_inst(PPC_INST_STD_LR))) {
-   pr_err("Unexpected instruction %08x around bl _mcount\n",
-  ppc_inst_val(op));
+   pr_err("Unexpected instruction %s around bl _mcount\n",
+  ppc_inst_as_str(op));
return -EINVAL;
}
 #else
@@ -203,7 +203,7 @@ __ftrace_make_nop(struct module *mod,
}
 
if (!ppc_inst_equal(op,  ppc_inst(PPC_INST_LD_TOC))) {
-   pr_err("Expected %08x found %08x\n", PPC_INST_LD_TOC, 
ppc_inst_val(op));
+   pr_err("Expected %08x found %s\n", PPC_INST_LD_TOC, 
ppc_inst_as_str(op));
retur

Re: [PATCH] powerpc/64: Remove unused generic_secondary_thread_init()

2020-05-27 Thread Jordan Niethe
On Tue, May 26, 2020 at 4:36 PM Michael Ellerman  wrote:
>
> The last caller was removed in 2014 in commit fb5a515704d7 ("powerpc:
> Remove platforms/wsp and associated pieces").
>
> Once generic_secondary_thread_init() is removed there are no longer
> any uses of book3e_secondary_thread_init() or
> generic_secondary_common_init so remove them too.
>
> Signed-off-by: Michael Ellerman 
> ---
>  arch/powerpc/include/asm/smp.h   |  1 -
>  arch/powerpc/kernel/exceptions-64e.S |  4 
>  arch/powerpc/kernel/head_64.S| 18 --
>  3 files changed, 23 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
> index 49a25e2400f2..81a49566ccd8 100644
> --- a/arch/powerpc/include/asm/smp.h
> +++ b/arch/powerpc/include/asm/smp.h
> @@ -243,7 +243,6 @@ extern void arch_send_call_function_ipi_mask(const struct 
> cpumask *mask);
>   * 64-bit but defining them all here doesn't harm
>   */
>  extern void generic_secondary_smp_init(void);
> -extern void generic_secondary_thread_init(void);
>  extern unsigned long __secondary_hold_spinloop;
>  extern unsigned long __secondary_hold_acknowledge;
>  extern char __secondary_hold;
> diff --git a/arch/powerpc/kernel/exceptions-64e.S 
> b/arch/powerpc/kernel/exceptions-64e.S
> index d9ed79415100..9f9e8686798b 100644
> --- a/arch/powerpc/kernel/exceptions-64e.S
> +++ b/arch/powerpc/kernel/exceptions-64e.S
> @@ -1814,10 +1814,6 @@ _GLOBAL(book3e_secondary_core_init)
>  1: mtlrr28
> blr
>
> -_GLOBAL(book3e_secondary_thread_init)
> -   mflrr28
> -   b   3b
> -
> .globl init_core_book3e
>  init_core_book3e:
> /* Establish the interrupt vector base */
> diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
> index 0e05a9a47a4b..4ae2c18c5fc6 100644
> --- a/arch/powerpc/kernel/head_64.S
> +++ b/arch/powerpc/kernel/head_64.S
> @@ -302,23 +302,6 @@ _GLOBAL(fsl_secondary_thread_init)
>  1:
>  #endif

Nothing directly calls generic_secondary_thread_init() but I think
fsl_secondary_thread_init() which is directly above "falls through"
into it. fsl_secondary_thread_init() still has callers.

>
> -_GLOBAL(generic_secondary_thread_init)
> -   mr  r24,r3
> -
> -   /* turn on 64-bit mode */
> -   bl  enable_64b_mode
> -
> -   /* get a valid TOC pointer, wherever we're mapped at */
> -   bl  relative_toc
> -   tovirt(r2,r2)
> -
> -#ifdef CONFIG_PPC_BOOK3E
> -   /* Book3E initialization */
> -   mr  r3,r24
> -   bl  book3e_secondary_thread_init
> -#endif
> -   b   generic_secondary_common_init
> -
>  /*
>   * On pSeries and most other platforms, secondary processors spin
>   * in the following code.
> @@ -385,7 +368,6 @@ _GLOBAL(generic_secondary_smp_init)
>  20:
>  #endif
>
> -generic_secondary_common_init:
> /* Set up a paca value for this processor. Since we have the
>  * physical cpu id in r24, we need to search the pacas to find
>  * which logical id maps to our physical one.
> --
> 2.25.1
>


Re: [PATCH] powerpc: Add ppc_inst_as_u64()

2020-05-25 Thread Jordan Niethe
On Mon, May 25, 2020 at 3:49 PM Michael Ellerman  wrote:
>
> The code patching code wants to get the value of a struct ppc_inst as
Might need to change the wording here as it also gets used in
arch_prepare_optimized_kprobe()
> a u64 when the instruction is prefixed, so we can pass the u64 down to
> __put_user_asm() and write it with a single store.
>
> This is a bit awkward because the value differs based on the CPU
> endianness, so add a helper to do the conversion.
>
> Signed-off-by: Michael Ellerman 
> ---
>  arch/powerpc/include/asm/inst.h  | 9 +
>  arch/powerpc/kernel/optprobes.c  | 3 +--
>  arch/powerpc/lib/code-patching.c | 8 +---
>  3 files changed, 11 insertions(+), 9 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h
> index d82e0c99cfa1..d61e07fb2937 100644
> --- a/arch/powerpc/include/asm/inst.h
> +++ b/arch/powerpc/include/asm/inst.h
> @@ -100,6 +100,15 @@ static inline int ppc_inst_len(struct ppc_inst x)
> return ppc_inst_prefixed(x) ? 8 : 4;
>  }
>
> +static inline u64 ppc_inst_as_u64(struct ppc_inst x)
> +{
> +#ifdef CONFIG_CPU_LITTLE_ENDIAN
> +   return (u64)ppc_inst_suffix(x) << 32 | ppc_inst_val(x);
> +#else
> +   return (u64)ppc_inst_val(x) << 32 | ppc_inst_suffix(x);
> +#endif
> +}
> +
>  int probe_user_read_inst(struct ppc_inst *inst,
>  struct ppc_inst __user *nip);
>
> diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c
> index 3ac105e7faae..69bfe96884e2 100644
> --- a/arch/powerpc/kernel/optprobes.c
> +++ b/arch/powerpc/kernel/optprobes.c
> @@ -283,8 +283,7 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe 
> *op, struct kprobe *p)
>  * 3. load instruction to be emulated into relevant register, and
>  */
> temp = ppc_inst_read((struct ppc_inst *)p->ainsn.insn);
> -   patch_imm64_load_insns(ppc_inst_val(temp) | 
> ((u64)ppc_inst_suffix(temp) << 32),
> -  4, buff + TMPL_INSN_IDX);
> +   patch_imm64_load_insns(ppc_inst_as_u64(temp), 4, buff + 
> TMPL_INSN_IDX);
>
> /*
>  * 4. branch back from trampoline
> diff --git a/arch/powerpc/lib/code-patching.c 
> b/arch/powerpc/lib/code-patching.c
> index 64cf621e5b00..5ecf0d635a8d 100644
> --- a/arch/powerpc/lib/code-patching.c
> +++ b/arch/powerpc/lib/code-patching.c
> @@ -27,13 +27,7 @@ static int __patch_instruction(struct ppc_inst *exec_addr, 
> struct ppc_inst instr
> if (!ppc_inst_prefixed(instr)) {
> __put_user_asm(ppc_inst_val(instr), patch_addr, err, "stw");
> } else {
> -#ifdef CONFIG_CPU_LITTLE_ENDIAN
> -   __put_user_asm((u64)ppc_inst_suffix(instr) << 32 |
> -  ppc_inst_val(instr), patch_addr, err, "std");
> -#else
> -   __put_user_asm((u64)ppc_inst_val(instr) << 32 |
> -  ppc_inst_suffix(instr), patch_addr, err, 
> "std");
> -#endif
> +   __put_user_asm(ppc_inst_as_u64(instr), patch_addr, err, 
> "std");
> }
>
> if (err)
> --
> 2.25.1
>
I booted a BE and LE kernel - test_prefixed_patching() worked on both.
Also on BE and LE kernels I put optprobes on prefixed and non prefixed
instructions.
The correct value was passed via r4 to emulate_step().

Tested-by: Jordan Niethe 


Re: [PATCH v2] powerpc: Add ppc_inst_next()

2020-05-24 Thread Jordan Niethe
P);
> +   for (; dest < end; dest = ppc_inst_next(dest, ))
> +   raw_patch_instruction(dest, nop);
>
> return 0;
>  }
> @@ -405,8 +406,8 @@ static void do_final_fixups(void)
> while (src < end) {
> inst = ppc_inst_read(src);
> raw_patch_instruction(dest, inst);
> -   src = (void *)src + ppc_inst_len(inst);
> -   dest = (void *)dest + ppc_inst_len(inst);
> +   src = ppc_inst_next(src, src);
> +   dest = ppc_inst_next(dest, dest);
> }
>  #endif
>  }
> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> index fb135f2cd6b0..65cf853a4d26 100644
> --- a/arch/powerpc/xmon/xmon.c
> +++ b/arch/powerpc/xmon/xmon.c
> @@ -939,7 +939,7 @@ static void insert_bpts(void)
> }
>
> patch_instruction(bp->instr, instr);
> -   patch_instruction((void *)bp->instr + ppc_inst_len(instr),
> +   patch_instruction(ppc_inst_next(bp->instr, ),
>   ppc_inst(bpinstr));
> if (bp->enabled & BP_CIABR)
> continue;
> --
> 2.25.1
>
Reviewed-by: Jordan Niethe 


[PATCH 5/5] powerpc sstep: Add tests for Prefixed Add Immediate

2020-05-24 Thread Jordan Niethe
Use the existing support for testing compute type instructions to test
Prefixed Add Immediate (paddi).  The R bit of the paddi instruction
controls whether current instruction address is used. Add test cases for
when R=1 and for R=0. paddi has a 34 bit immediate field formed by
concatenating si0 and si1. Add tests for the extreme values of this
field.

Skip the paddi tests if ISA v3.1 is unsupported.

Some of these test cases were added by Balamuruhan S.

Signed-off-by: Jordan Niethe 
---
 arch/powerpc/lib/test_emulate_step.c  | 127 ++
 .../lib/test_emulate_step_exec_instr.S|   1 +
 2 files changed, 128 insertions(+)

diff --git a/arch/powerpc/lib/test_emulate_step.c 
b/arch/powerpc/lib/test_emulate_step.c
index 579b5db80674..33a72b7d2764 100644
--- a/arch/powerpc/lib/test_emulate_step.c
+++ b/arch/powerpc/lib/test_emulate_step.c
@@ -105,6 +105,13 @@
___PPC_RA(a) | ___PPC_RB(b))
 #define TEST_ADDC_DOT(t, a, b) ppc_inst(PPC_INST_ADDC | ___PPC_RT(t) | 
\
___PPC_RA(a) | ___PPC_RB(b) | 0x1)
+#define TEST_PADDI(t, a, i, pr)ppc_inst_prefix(PPC_PREFIX_MLS | 
__PPC_PRFX_R(pr) | \
+   IMM_H(i),   \
+   PPC_INST_ADDI | \
+   ___PPC_RT(t) | ___PPC_RA(a) |   \
+   IMM_L(i))
+
+
 
 #define MAX_SUBTESTS   16
 
@@ -699,6 +706,11 @@ struct compute_test {
} subtests[MAX_SUBTESTS + 1];
 };
 
+/* Extreme values for si0||si1 (the MLS:D-form 34 bit immediate field) */
+#define SI_MIN BIT(33)
+#define SI_MAX (BIT(33) - 1)
+#define SI_UMAX (BIT(34) - 1)
+
 static struct compute_test compute_tests[] = {
{
.mnemonic = "nop",
@@ -1071,6 +1083,121 @@ static struct compute_test compute_tests[] = {
}
}
}
+   },
+   {
+   .mnemonic = "paddi",
+   .cpu_feature = CPU_FTR_ARCH_31,
+   .subtests = {
+   {
+   .descr = "RA = LONG_MIN, SI = SI_MIN, R = 0",
+   .instr = TEST_PADDI(21, 22, SI_MIN, 0),
+   .regs = {
+   .gpr[21] = 0,
+   .gpr[22] = LONG_MIN,
+   }
+   },
+   {
+   .descr = "RA = LONG_MIN, SI = SI_MAX, R = 0",
+   .instr = TEST_PADDI(21, 22, SI_MAX, 0),
+   .regs = {
+   .gpr[21] = 0,
+   .gpr[22] = LONG_MIN,
+   }
+   },
+   {
+   .descr = "RA = LONG_MAX, SI = SI_MAX, R = 0",
+   .instr = TEST_PADDI(21, 22, SI_MAX, 0),
+   .regs = {
+   .gpr[21] = 0,
+   .gpr[22] = LONG_MAX,
+   }
+   },
+   {
+   .descr = "RA = ULONG_MAX, SI = SI_UMAX, R = 0",
+   .instr = TEST_PADDI(21, 22, SI_UMAX, 0),
+   .regs = {
+   .gpr[21] = 0,
+   .gpr[22] = ULONG_MAX,
+   }
+   },
+   {
+   .descr = "RA = ULONG_MAX, SI = 0x1, R = 0",
+   .instr = TEST_PADDI(21, 22, 0x1, 0),
+   .regs = {
+   .gpr[21] = 0,
+   .gpr[22] = ULONG_MAX,
+   }
+   },
+   {
+   .descr = "RA = INT_MIN, SI = SI_MIN, R = 0",
+   .instr = TEST_PADDI(21, 22, SI_MIN, 0),
+   .regs = {
+   .gpr[21] = 0,
+   .gpr[22] = INT_MIN,
+   }
+   },
+   {
+   .descr = "RA = INT_MIN, SI = SI_MAX, R = 0",
+   .instr = TEST_PADDI(21, 22, SI_MAX, 0),
+   .regs = {
+   .gpr[21] = 0,
+   .gpr[22] = INT_MIN,
+   }
+

[PATCH 4/5] powerpc sstep: Let compute tests specify a required cpu feature

2020-05-24 Thread Jordan Niethe
An a array of struct compute_test's are used to declare tests for
compute instructions. Add a cpu_feature field to struct compute_test as
an optional way to specify a cpu feature that must be present. If not
present then skip the test.

Signed-off-by: Jordan Niethe 
---
 arch/powerpc/lib/test_emulate_step.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/arch/powerpc/lib/test_emulate_step.c 
b/arch/powerpc/lib/test_emulate_step.c
index 427c2ca8191e..579b5db80674 100644
--- a/arch/powerpc/lib/test_emulate_step.c
+++ b/arch/powerpc/lib/test_emulate_step.c
@@ -690,6 +690,7 @@ static void __init run_tests_load_store(void)
 
 struct compute_test {
char *mnemonic;
+   unsigned long cpu_feature;
struct {
char *descr;
unsigned long flags;
@@ -1133,6 +1134,11 @@ static void __init run_tests_compute(void)
for (i = 0; i < ARRAY_SIZE(compute_tests); i++) {
test = _tests[i];
 
+   if (test->cpu_feature && 
!early_cpu_has_feature(test->cpu_feature)) {
+   show_result(test->mnemonic, "SKIP (!CPU_FTR)");
+   continue;
+   }
+
for (j = 0; j < MAX_SUBTESTS && test->subtests[j].descr; j++) {
instr = test->subtests[j].instr;
flags = test->subtests[j].flags;
-- 
2.17.1



[PATCH 3/5] powerpc sstep: Set NIP in instruction emulation tests

2020-05-24 Thread Jordan Niethe
The tests for emulation of compute instructions execute and
emulate an instruction and then compare the results to verify the
emulation. In ISA v3.1 there are instructions that operate relative to
the NIP. Therefore set the NIP in the regs used for the emulated
instruction to the location of the executed instruction so they will
give the same result.

This is a rework of a patch by Balamuruhan S.

Signed-off-by: Jordan Niethe 
---
 arch/powerpc/lib/test_emulate_step.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/powerpc/lib/test_emulate_step.c 
b/arch/powerpc/lib/test_emulate_step.c
index 9599f3a03ca1..427c2ca8191e 100644
--- a/arch/powerpc/lib/test_emulate_step.c
+++ b/arch/powerpc/lib/test_emulate_step.c
@@ -1076,11 +1076,14 @@ static struct compute_test compute_tests[] = {
 static int __init emulate_compute_instr(struct pt_regs *regs,
struct ppc_inst instr)
 {
+   extern s32 patch__exec_instr;
struct instruction_op op;
 
if (!regs || !ppc_inst_val(instr))
return -EINVAL;
 
+   regs->nip = patch_site_addr(__exec_instr);
+
if (analyse_instr(, regs, instr) != 1 ||
GETTYPE(op.type) != COMPUTE) {
pr_info("emulation failed, instruction = 0x%08x\n", 
ppc_inst_val(instr));
-- 
2.17.1



[PATCH 2/5] powerpc sstep: Add tests for prefixed floating-point load/stores

2020-05-24 Thread Jordan Niethe
Add tests for the prefixed versions of the floating-point load/stores
that are currently tested. This includes the following instructions:
  * Prefixed Load Floating-Point Single (plfs)
  * Prefixed Load Floating-Point Double (plfd)
  * Prefixed Store Floating-Point Single (pstfs)
  * Prefixed Store Floating-Point Double (pstfd)

Skip the new tests if ISA v3.10 is unsupported.

Signed-off-by: Jordan Niethe 
---
 arch/powerpc/include/asm/ppc-opcode.h |   4 +
 arch/powerpc/lib/test_emulate_step.c  | 136 ++
 2 files changed, 140 insertions(+)

diff --git a/arch/powerpc/include/asm/ppc-opcode.h 
b/arch/powerpc/include/asm/ppc-opcode.h
index 9e3ecb42597e..6b5edec0e347 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -371,9 +371,13 @@
 #define PPC_INST_LBZCIX0x7c0006aa
 #define PPC_INST_STBCIX0x7c0007aa
 #define PPC_INST_LWZX  0x7c2e
+#define PPC_INST_LFS   0xc000
 #define PPC_INST_LFSX  0x7c00042e
+#define PPC_INST_STFS  0xd000
 #define PPC_INST_STFSX 0x7c00052e
+#define PPC_INST_LFD   0xc800
 #define PPC_INST_LFDX  0x7c0004ae
+#define PPC_INST_STFD  0xd800
 #define PPC_INST_STFDX 0x7c0005ae
 #define PPC_INST_LVX   0x7cce
 #define PPC_INST_STVX  0x7c0001ce
diff --git a/arch/powerpc/lib/test_emulate_step.c 
b/arch/powerpc/lib/test_emulate_step.c
index 8d8953b5fe90..9599f3a03ca1 100644
--- a/arch/powerpc/lib/test_emulate_step.c
+++ b/arch/powerpc/lib/test_emulate_step.c
@@ -57,12 +57,40 @@
___PPC_RA(a) | ___PPC_RB(b))
 #define TEST_LFSX(t, a, b) ppc_inst(PPC_INST_LFSX | ___PPC_RT(t) | 
\
___PPC_RA(a) | ___PPC_RB(b))
+#define TEST_PLFS(r, base, i, pr)  ppc_inst_prefix(PPC_PREFIX_MLS |
\
+   __PPC_PRFX_R(pr) |  \
+   IMM_H(i),   \
+   PPC_INST_LFS |  \
+   ___PPC_RT(r) |  \
+   ___PPC_RA(base) |   \
+   IMM_L(i))
 #define TEST_STFSX(s, a, b)ppc_inst(PPC_INST_STFSX | ___PPC_RS(s) |
\
___PPC_RA(a) | ___PPC_RB(b))
+#define TEST_PSTFS(r, base, i, pr) ppc_inst_prefix(PPC_PREFIX_MLS |
\
+   __PPC_PRFX_R(pr) |  \
+   IMM_H(i),   \
+   PPC_INST_STFS | \
+   ___PPC_RT(r) |  \
+   ___PPC_RA(base) |   \
+   IMM_L(i))
 #define TEST_LFDX(t, a, b) ppc_inst(PPC_INST_LFDX | ___PPC_RT(t) | 
\
___PPC_RA(a) | ___PPC_RB(b))
+#define TEST_PLFD(r, base, i, pr)  ppc_inst_prefix(PPC_PREFIX_MLS |
\
+   __PPC_PRFX_R(pr) |  \
+   IMM_H(i),   \
+   PPC_INST_LFD |  \
+   ___PPC_RT(r) |  \
+   ___PPC_RA(base) |   \
+   IMM_L(i))
 #define TEST_STFDX(s, a, b)ppc_inst(PPC_INST_STFDX | ___PPC_RS(s) |
\
___PPC_RA(a) | ___PPC_RB(b))
+#define TEST_PSTFD(r, base, i, pr) ppc_inst_prefix(PPC_PREFIX_MLS |
\
+   __PPC_PRFX_R(pr) |  \
+   IMM_H(i),   \
+   PPC_INST_STFD | \
+   ___PPC_RT(r) |  \
+   ___PPC_RA(base) |   \
+   IMM_L(i))
 #define TEST_LVX(t, a, b)  ppc_inst(PPC_INST_LVX | ___PPC_RT(t) |  
\
___PPC_RA(a) | ___PPC_RB(b))
 #define TEST_STVX(s, a, b) ppc_inst(PPC_INST_STVX | ___PPC_RS(s) | 
\
@@ -357,6 +385,53 @@ static void __init test_lfsx_stfsx(void)
show_result("stfsx", "FAIL");
 }
 
+static void __init test_plfs_pstfs(void)
+{
+   struct pt_regs regs;
+   union {
+   float a;
+   int b;
+   } c;
+   int cached_b;
+   

[PATCH 1/5] powerpc sstep: Add tests for prefixed integer load/stores

2020-05-24 Thread Jordan Niethe
Add tests for the prefixed versions of the integer load/stores that are
currently tested. This includes the following instructions:
  * Prefixed Load Doubleword (pld)
  * Prefixed Load Word and Zero (plwz)
  * Prefixed Store Doubleword (pstd)

Skip the new tests if ISA v3.1 is unsupported.

Signed-off-by: Jordan Niethe 
---
 arch/powerpc/include/asm/ppc-opcode.h |  9 +++
 arch/powerpc/lib/test_emulate_step.c  | 95 +++
 2 files changed, 104 insertions(+)

diff --git a/arch/powerpc/include/asm/ppc-opcode.h 
b/arch/powerpc/include/asm/ppc-opcode.h
index 2a39c716c343..9e3ecb42597e 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -380,6 +380,14 @@
 #define PPC_INST_VCMPEQUD  0x10c7
 #define PPC_INST_VCMPEQUB  0x1006
 
+/* Prefixes */
+#define PPC_PREFIX_MLS 0x0600
+#define PPC_PREFIX_8LS 0x0400
+
+/* Prefixed instructions */
+#define PPC_INST_PLD   0xe400
+#define PPC_INST_PSTD  0xf400
+
 /* macros to insert fields into opcodes */
 #define ___PPC_RA(a)   (((a) & 0x1f) << 16)
 #define ___PPC_RB(b)   (((b) & 0x1f) << 11)
@@ -411,6 +419,7 @@
 #define __PPC_CT(t)(((t) & 0x0f) << 21)
 #define __PPC_SPR(r)   r) & 0x1f) << 16) | r) >> 5) & 0x1f) << 11))
 #define __PPC_RC21 (0x1 << 10)
+#define __PPC_PRFX_R(r)(((r) & 0x1) << 20)
 
 /*
  * Both low and high 16 bits are added as SIGNED additions, so if low 16 bits
diff --git a/arch/powerpc/lib/test_emulate_step.c 
b/arch/powerpc/lib/test_emulate_step.c
index 46af80279ebc..8d8953b5fe90 100644
--- a/arch/powerpc/lib/test_emulate_step.c
+++ b/arch/powerpc/lib/test_emulate_step.c
@@ -15,6 +15,7 @@
 
 #define IMM_L(i)   ((uintptr_t)(i) & 0x)
 #define IMM_DS(i)  ((uintptr_t)(i) & 0xfffc)
+#define IMM_H(i)   (((uintptr_t)(i) >> 16) & 0x3)
 
 /*
  * Defined with TEST_ prefix so it does not conflict with other
@@ -22,12 +23,33 @@
  */
 #define TEST_LD(r, base, i)ppc_inst(PPC_INST_LD | ___PPC_RT(r) |   
\
___PPC_RA(base) | IMM_DS(i))
+#define TEST_PLD(r, base, i, pr)   ppc_inst_prefix(PPC_PREFIX_8LS |
\
+   __PPC_PRFX_R(pr) |  \
+   IMM_H(i),   \
+   PPC_INST_PLD |  \
+   ___PPC_RT(r) |  \
+   ___PPC_RA(base) |   \
+   IMM_L(i))
 #define TEST_LWZ(r, base, i)   ppc_inst(PPC_INST_LWZ | ___PPC_RT(r) |  
\
___PPC_RA(base) | IMM_L(i))
+#define TEST_PLWZ(r, base, i, pr)  ppc_inst_prefix(PPC_PREFIX_MLS |
\
+   __PPC_PRFX_R(pr) |  \
+   IMM_H(i),   \
+   PPC_INST_LWZ |  \
+   ___PPC_RT(r) |  \
+   ___PPC_RA(base) |   \
+   IMM_L(i))
 #define TEST_LWZX(t, a, b) ppc_inst(PPC_INST_LWZX | ___PPC_RT(t) | 
\
___PPC_RA(a) | ___PPC_RB(b))
 #define TEST_STD(r, base, i)   ppc_inst(PPC_INST_STD | ___PPC_RS(r) |  
\
___PPC_RA(base) | IMM_DS(i))
+#define TEST_PSTD(r, base, i, pr)  ppc_inst_prefix(PPC_PREFIX_8LS |
\
+   __PPC_PRFX_R(pr) |  \
+   IMM_H(i),   \
+   PPC_INST_PSTD | \
+   ___PPC_RT(r) |  \
+   ___PPC_RA(base) |   \
+   IMM_L(i))
 #define TEST_LDARX(t, a, b, eh)ppc_inst(PPC_INST_LDARX | ___PPC_RT(t) 
|\
___PPC_RA(a) | ___PPC_RB(b) |   \
__PPC_EH(eh))
@@ -113,6 +135,29 @@ static void __init test_ld(void)
show_result("ld", "FAIL");
 }
 
+static void __init test_pld(void)
+{
+   struct pt_regs regs;
+   unsigned long a = 0x23;
+   int stepped = -1;
+
+   if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
+   show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
+   return;
+   }
+
+   init_pt_regs();
+   regs.gpr[3] = (unsigned long)

Re: [PATCH] powerpc: Add ppc_inst_next()

2020-05-20 Thread Jordan Niethe
On Wed, May 20, 2020 at 9:44 PM Michael Ellerman  wrote:
>
> In a few places we want to calculate the address of the next
> instruction. Previously that was simple, we just added 4 bytes, or if
> using a u32 * we incremented that pointer by 1.
>
> But prefixed instructions make it more complicated, we need to advance
> by either 4 or 8 bytes depending on the actual instruction. We also
> can't do pointer arithmetic using struct ppc_inst, because it is
> always 8 bytes in size on 64-bit, even though we might only need to
> advance by 4 bytes.
>
> So add a ppc_inst_next() helper which calculates the location of the
> next instruction, if the given instruction was located at the given
> address. Note the instruction doesn't need to actually be at the
> address in memory.
>
> Convert several locations to use it.
>
> Signed-off-by: Michael Ellerman 
> ---
>  arch/powerpc/include/asm/inst.h   |  9 +
>  arch/powerpc/kernel/uprobes.c |  2 +-
>  arch/powerpc/lib/feature-fixups.c | 10 +-
>  arch/powerpc/xmon/xmon.c  |  2 +-
>  4 files changed, 16 insertions(+), 7 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h
> index d82e0c99cfa1..7d5ee1309b92 100644
> --- a/arch/powerpc/include/asm/inst.h
> +++ b/arch/powerpc/include/asm/inst.h
> @@ -100,6 +100,15 @@ static inline int ppc_inst_len(struct ppc_inst x)
> return ppc_inst_prefixed(x) ? 8 : 4;
>  }
>
> +/*
> + * Return the address of the next instruction, if the instruction @value was
> + * located at @location.
> + */
> +static inline struct ppc_inst *ppc_inst_next(void *location, struct ppc_inst 
> value)
> +{
> +   return location + ppc_inst_len(value);
> +}
I think this is a good idea. I tried something similar in the initial
post for an instruction type. I had:
+#define PPC_INST_NEXT(ptr) ((ptr) += PPC_INST_LEN(DEREF_PPC_INST_PTR((ptr
but how you've got it is much more clear/usable.
I wonder why not
+static inline struct ppc_inst *ppc_inst_next(void *location)
+{
+   return location + ppc_inst_len(ppc_inst_read((struct ppc_inst
*)location);
+}

> +
>  int probe_user_read_inst(struct ppc_inst *inst,
>  struct ppc_inst __user *nip);
>
> diff --git a/arch/powerpc/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c
> index 83e883e1a42d..683ba76919a7 100644
> --- a/arch/powerpc/kernel/uprobes.c
> +++ b/arch/powerpc/kernel/uprobes.c
> @@ -112,7 +112,7 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, 
> struct pt_regs *regs)
>  * support doesn't exist and have to fix-up the next instruction
>  * to be executed.
>  */
> -   regs->nip = utask->vaddr + 
> ppc_inst_len(ppc_inst_read(>insn));
> +   regs->nip = (unsigned long)ppc_inst_next((void *)utask->vaddr, 
> auprobe->insn);
>
> user_disable_single_step(current);
> return 0;
> diff --git a/arch/powerpc/lib/feature-fixups.c 
> b/arch/powerpc/lib/feature-fixups.c
> index 80f320c2e189..0ad01eebf112 100644
> --- a/arch/powerpc/lib/feature-fixups.c
> +++ b/arch/powerpc/lib/feature-fixups.c
> @@ -84,13 +84,13 @@ static int patch_feature_section(unsigned long value, 
> struct fixup_entry *fcur)
> src = alt_start;
> dest = start;
>
> -   for (; src < alt_end; src = (void *)src + 
> ppc_inst_len(ppc_inst_read(src)),
> -(dest = (void *)dest + ppc_inst_len(ppc_inst_read(dest {
> +   for (; src < alt_end; src = ppc_inst_next(src, *src),
> + dest = ppc_inst_next(dest, *dest)) {
The reason to maybe use ppc_inst_read() in the helper instead of just
*dest would be we don't always need to read 8 bytes.
> if (patch_alt_instruction(src, dest, alt_start, alt_end))
> return 1;
> }
>
> -   for (; dest < end; dest = (void *)dest + 
> ppc_inst_len(ppc_inst(PPC_INST_NOP)))
> +   for (; dest < end; dest = ppc_inst_next(dest, ppc_inst(PPC_INST_NOP)))
But then you wouldn't be able to do this as easily I guess.
> raw_patch_instruction(dest, ppc_inst(PPC_INST_NOP));
>
> return 0;
> @@ -405,8 +405,8 @@ static void do_final_fixups(void)
> while (src < end) {
> inst = ppc_inst_read(src);
> raw_patch_instruction(dest, inst);
> -   src = (void *)src + ppc_inst_len(inst);
> -   dest = (void *)dest + ppc_inst_len(inst);
> +   src = ppc_inst_next(src, *src);
> +   dest = ppc_inst_next(dest, *dest);
> }
>  #endif
>  }
> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> index fb135f2cd6b0..aa123f56b7d4 100644
> --- a/arch/powerpc/xmon/xmon.c
> +++ b/arch/powerpc/xmon/xmon.c
> @@ -939,7 +939,7 @@ static void insert_bpts(void)
> }
>
> patch_instruction(bp->instr, instr);
> -   patch_instruction((void *)bp->instr + ppc_inst_len(instr),
> +   patch_instruction(ppc_inst_next(bp->instr, 

[PATCH 2/2] selftests/powerpc: Add prefixed loads/stores to alignment_handler test

2020-05-19 Thread Jordan Niethe
Extend the alignment handler selftest to exercise prefixed load store
instructions. Add tests for prefixed VSX, floating point and integer
instructions.

Skip prefix tests if ISA version does not support prefixed instructions.

Signed-off-by: Jordan Niethe 
---
 .../powerpc/alignment/alignment_handler.c | 93 ++-
 .../selftests/powerpc/include/instructions.h  | 77 +++
 .../testing/selftests/powerpc/include/utils.h |  5 +
 3 files changed, 172 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/powerpc/alignment/alignment_handler.c 
b/tools/testing/selftests/powerpc/alignment/alignment_handler.c
index eb6aba323f8b..e582e68b3b5b 100644
--- a/tools/testing/selftests/powerpc/alignment/alignment_handler.c
+++ b/tools/testing/selftests/powerpc/alignment/alignment_handler.c
@@ -58,6 +58,7 @@
 #include 
 
 #include "utils.h"
+#include "instructions.h"
 
 int bufsize;
 int debug;
@@ -96,6 +97,17 @@ void sighandler(int sig, siginfo_t *info, void *ctx)
}   \
rc |= do_test(#name, test_##name)
 
+#define TESTP(name, ld_op, st_op, ld_reg, st_reg)  \
+   void test_##name(char *s, char *d)  \
+   {   \
+   asm volatile(   \
+   ld_op(ld_reg, %0, 0, 0) \
+   st_op(st_reg, %1, 0, 0) \
+   :: "r"(s), "r"(d), "r"(0)   \
+   : "memory", "vs0", "vs32", "r31");  \
+   }   \
+   rc |= do_test(#name, test_##name)
+
 #define LOAD_VSX_XFORM_TEST(op) TEST(op, op, stxvd2x, XFORM, 32, 32)
 #define STORE_VSX_XFORM_TEST(op) TEST(op, lxvd2x, op, XFORM, 32, 32)
 #define LOAD_VSX_DFORM_TEST(op) TEST(op, op, stxv, DFORM, 32, 32)
@@ -115,6 +127,17 @@ void sighandler(int sig, siginfo_t *info, void *ctx)
 #define LOAD_FLOAT_XFORM_TEST(op)  TEST(op, op, stfdx, XFORM, 0, 0)
 #define STORE_FLOAT_XFORM_TEST(op) TEST(op, lfdx, op, XFORM, 0, 0)
 
+#define LOAD_MLS_PREFIX_TEST(op) TESTP(op, op, PSTD, 31, 31)
+#define STORE_MLS_PREFIX_TEST(op) TESTP(op, PLD, op, 31, 31)
+
+#define LOAD_8LS_PREFIX_TEST(op) TESTP(op, op, PSTD, 31, 31)
+#define STORE_8LS_PREFIX_TEST(op) TESTP(op, PLD, op, 31, 31)
+
+#define LOAD_FLOAT_MLS_PREFIX_TEST(op) TESTP(op, op, PSTFD, 0, 0)
+#define STORE_FLOAT_MLS_PREFIX_TEST(op) TESTP(op, PLFD, op, 0, 0)
+
+#define LOAD_VSX_8LS_PREFIX_TEST(op, tail) TESTP(op, op, PSTXV ## tail, 0, 32)
+#define STORE_VSX_8LS_PREFIX_TEST(op, tail) TESTP(op, PLXV ## tail, op, 32, 0)
 
 /* FIXME: Unimplemented tests: */
 // STORE_DFORM_TEST(stq)   /* FIXME: need two registers for quad */
@@ -361,6 +384,25 @@ int test_alignment_handler_vsx_300(void)
return rc;
 }
 
+int test_alignment_handler_vsx_prefix(void)
+{
+   int rc = 0;
+
+   SKIP_IF(!can_open_cifile());
+   SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_10));
+
+   printf("VSX: PREFIX\n");
+   LOAD_VSX_8LS_PREFIX_TEST(PLXSD, 0);
+   LOAD_VSX_8LS_PREFIX_TEST(PLXSSP, 0);
+   LOAD_VSX_8LS_PREFIX_TEST(PLXV0, 0);
+   LOAD_VSX_8LS_PREFIX_TEST(PLXV1, 1);
+   STORE_VSX_8LS_PREFIX_TEST(PSTXSD, 0);
+   STORE_VSX_8LS_PREFIX_TEST(PSTXSSP, 0);
+   STORE_VSX_8LS_PREFIX_TEST(PSTXV0, 0);
+   STORE_VSX_8LS_PREFIX_TEST(PSTXV1, 1);
+   return rc;
+}
+
 int test_alignment_handler_integer(void)
 {
int rc = 0;
@@ -432,6 +474,27 @@ int test_alignment_handler_integer_206(void)
return rc;
 }
 
+int test_alignment_handler_integer_prefix(void)
+{
+   int rc = 0;
+
+   SKIP_IF(!can_open_cifile());
+   SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_10));
+
+   printf("Integer: PREFIX\n");
+   LOAD_MLS_PREFIX_TEST(PLBZ);
+   LOAD_MLS_PREFIX_TEST(PLHZ);
+   LOAD_MLS_PREFIX_TEST(PLHA);
+   LOAD_MLS_PREFIX_TEST(PLWZ);
+   LOAD_8LS_PREFIX_TEST(PLWA);
+   LOAD_8LS_PREFIX_TEST(PLD);
+   STORE_MLS_PREFIX_TEST(PSTB);
+   STORE_MLS_PREFIX_TEST(PSTH);
+   STORE_MLS_PREFIX_TEST(PSTW);
+   STORE_8LS_PREFIX_TEST(PSTD);
+   return rc;
+}
+
 int test_alignment_handler_vmx(void)
 {
int rc = 0;
@@ -520,14 +583,32 @@ int test_alignment_handler_fp_206(void)
return rc;
 }
 
+
+int test_alignment_handler_fp_prefix(void)
+{
+   int rc = 0;
+
+   SKIP_IF(!can_open_cifile());
+   SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_10));
+
+   printf("Floating point: PREFIX\n");
+   LOAD_FLOAT_DFORM_TEST(lfs);
+   LOAD_FLOAT_MLS_PREFIX_TEST(PLFS);
+   LOAD_FLOAT_MLS_PREFIX_TEST(PLFD);
+   STORE_FLOAT_MLS_PREFIX_TEST(PSTFS);
+   STORE_FLOAT_MLS_PREFIX_TEST(PSTFD);
+   return rc;
+}
+
 void usage(char *prog)
 {
printf(&

[PATCH 1/2] selftests/powerpc: Allow choice of CI memory location in alignment_handler test

2020-05-19 Thread Jordan Niethe
The alignment handler selftest needs cache-inhibited memory and
currently /dev/fb0 is relied on to provided this. This prevents running
the test on systems without /dev/fb0 (e.g., mambo). Read the commandline
arguments for an optional path to be used instead, as well as an
optional offset to be for mmaping this path.

Signed-off-by: Jordan Niethe 
---
 .../powerpc/alignment/alignment_handler.c | 63 ---
 1 file changed, 42 insertions(+), 21 deletions(-)

diff --git a/tools/testing/selftests/powerpc/alignment/alignment_handler.c 
b/tools/testing/selftests/powerpc/alignment/alignment_handler.c
index 0453c50c949c..eb6aba323f8b 100644
--- a/tools/testing/selftests/powerpc/alignment/alignment_handler.c
+++ b/tools/testing/selftests/powerpc/alignment/alignment_handler.c
@@ -9,7 +9,17 @@
  * This selftest exercises the powerpc alignment fault handler.
  *
  * We create two sets of source and destination buffers, one in regular memory,
- * the other cache-inhibited (we use /dev/fb0 for this).
+ * the other cache-inhibited (by default we use /dev/fb0 for this, but an
+ * alterative path for cache-inhibited memory may be provided).
+ *
+ * One way to get cache-inhibited memory is to use the "mem" kernel parameter
+ * to limit the kernel to less memory than actually exists.  Addresses above
+ * the limit may still be accessed but will be treated as cache-inhibited. For
+ * example, if there is actually 4GB of memory and the parameter "mem=3GB" is
+ * used, memory from address 0xC000 onwards is treated as cache-inhibited.
+ * To access this region /dev/mem is used. The kernel should be configured
+ * without CONFIG_STRICT_DEVMEM. In this case use:
+ * ./alignment_handler /dev/mem 0xc000
  *
  * We initialise the source buffers, then use whichever set of load/store
  * instructions is under test to copy bytes from the source buffers to the
@@ -53,6 +63,8 @@ int bufsize;
 int debug;
 int testing;
 volatile int gotsig;
+char *cipath = "/dev/fb0";
+long cioffset;
 
 void sighandler(int sig, siginfo_t *info, void *ctx)
 {
@@ -195,17 +207,18 @@ int do_test(char *test_name, void (*test_func)(char *, 
char *))
 
printf("\tDoing %s:\t", test_name);
 
-   fd = open("/dev/fb0", O_RDWR);
+   fd = open(cipath, O_RDWR);
if (fd < 0) {
printf("\n");
-   perror("Can't open /dev/fb0 now?");
+   perror("Can't open ci file now?");
return 1;
}
 
-   ci0 = mmap(NULL, bufsize, PROT_WRITE, MAP_SHARED,
-  fd, 0x0);
-   ci1 = mmap(NULL, bufsize, PROT_WRITE, MAP_SHARED,
-  fd, bufsize);
+   ci0 = mmap(NULL, bufsize, PROT_WRITE | PROT_READ, MAP_SHARED,
+  fd, cioffset);
+   ci1 = mmap(NULL, bufsize, PROT_WRITE | PROT_READ, MAP_SHARED,
+  fd, cioffset + bufsize);
+
if ((ci0 == MAP_FAILED) || (ci1 == MAP_FAILED)) {
printf("\n");
perror("mmap failed");
@@ -270,11 +283,11 @@ int do_test(char *test_name, void (*test_func)(char *, 
char *))
return rc;
 }
 
-static bool can_open_fb0(void)
+static bool can_open_cifile(void)
 {
int fd;
 
-   fd = open("/dev/fb0", O_RDWR);
+   fd = open(cipath, O_RDWR);
if (fd < 0)
return false;
 
@@ -286,7 +299,7 @@ int test_alignment_handler_vsx_206(void)
 {
int rc = 0;
 
-   SKIP_IF(!can_open_fb0());
+   SKIP_IF(!can_open_cifile());
SKIP_IF(!have_hwcap(PPC_FEATURE_ARCH_2_06));
 
printf("VSX: 2.06B\n");
@@ -304,7 +317,7 @@ int test_alignment_handler_vsx_207(void)
 {
int rc = 0;
 
-   SKIP_IF(!can_open_fb0());
+   SKIP_IF(!can_open_cifile());
SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_2_07));
 
printf("VSX: 2.07B\n");
@@ -320,7 +333,7 @@ int test_alignment_handler_vsx_300(void)
 {
int rc = 0;
 
-   SKIP_IF(!can_open_fb0());
+   SKIP_IF(!can_open_cifile());
 
SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_00));
printf("VSX: 3.00B\n");
@@ -352,7 +365,7 @@ int test_alignment_handler_integer(void)
 {
int rc = 0;
 
-   SKIP_IF(!can_open_fb0());
+   SKIP_IF(!can_open_cifile());
 
printf("Integer\n");
LOAD_DFORM_TEST(lbz);
@@ -408,7 +421,7 @@ int test_alignment_handler_integer_206(void)
 {
int rc = 0;
 
-   SKIP_IF(!can_open_fb0());
+   SKIP_IF(!can_open_cifile());
SKIP_IF(!have_hwcap(PPC_FEATURE_ARCH_2_06));
 
printf("Integer: 2.06\n");
@@ -423,7 +436,7 @@ int test_alignment_handler_vmx(void)
 {
int rc = 0;
 
-   SKIP_IF(!can_open_fb0());
+   SKIP_IF(!can_open_cifile());
SKIP_IF(!have_hwcap(PPC_FEATURE_HAS_ALTIVEC));
 
printf("VMX\n");
@@ -451,7 +464,7 @@ int test_alignment_handler_

Re: [PATCH v2 2/7] powerpc: Add support for ISA v3.1

2020-05-18 Thread Jordan Niethe
On Tue, May 19, 2020 at 10:39 AM Alistair Popple  wrote:
>
> Newer ISA versions are enabled by clearing all bits in the PCR
> associated with previous versions of the ISA. Enable ISA v3.1 support
> by updating the PCR mask to include ISA v3.0. This ensures all PCR
> bits corresponding to earlier architecture versions get cleared
> thereby enabling ISA v3.1 if supported by the hardware.
>
> Signed-off-by: Alistair Popple 
> ---
>  arch/powerpc/include/asm/cputable.h | 1 +
>  arch/powerpc/include/asm/reg.h  | 3 ++-
>  arch/powerpc/kvm/book3s_hv.c| 3 ---
>  3 files changed, 3 insertions(+), 4 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/cputable.h 
> b/arch/powerpc/include/asm/cputable.h
> index 40a4d3c6fd99..36f894dea9e7 100644
> --- a/arch/powerpc/include/asm/cputable.h
> +++ b/arch/powerpc/include/asm/cputable.h
> @@ -213,6 +213,7 @@ static inline void cpu_feature_keys_init(void) { }
>  #define CPU_FTR_P9_TIDR
> LONG_ASM_CONST(0x8000)
>  #define CPU_FTR_P9_TLBIE_ERAT_BUG  LONG_ASM_CONST(0x0001)
>  #define CPU_FTR_P9_RADIX_PREFETCH_BUG  LONG_ASM_CONST(0x0002)
> +#define CPU_FTR_ARCH_31
> LONG_ASM_CONST(0x0004)
>
>  #ifndef __ASSEMBLY__
>
> diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
> index 773f76402392..1931b1142599 100644
> --- a/arch/powerpc/include/asm/reg.h
> +++ b/arch/powerpc/include/asm/reg.h
> @@ -485,10 +485,11 @@
>   * determine both the compatibility level which we want to emulate and the
>   * compatibility level which the host is capable of emulating.
>   */
> +#define   PCR_ARCH_300 0x10/* Architecture 3.00 */
>  #define   PCR_ARCH_207 0x8 /* Architecture 2.07 */
>  #define   PCR_ARCH_206 0x4 /* Architecture 2.06 */
>  #define   PCR_ARCH_205 0x2 /* Architecture 2.05 */
> -#define   PCR_LOW_BITS (PCR_ARCH_207 | PCR_ARCH_206 | PCR_ARCH_205)
> +#define   PCR_LOW_BITS (PCR_ARCH_207 | PCR_ARCH_206 | PCR_ARCH_205 | 
> PCR_ARCH_300)
>  #define   PCR_MASK ~(PCR_HIGH_BITS | PCR_LOW_BITS) /* PCR Reserved Bits 
> */
>  #defineSPRN_HEIR   0x153   /* Hypervisor Emulated Instruction 
> Register */
>  #define SPRN_TLBINDEXR 0x154   /* P7 TLB control register */
> diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
> index 93493f0cbfe8..532215040f3e 100644
> --- a/arch/powerpc/kvm/book3s_hv.c
> +++ b/arch/powerpc/kvm/book3s_hv.c
> @@ -344,9 +344,6 @@ static void kvmppc_set_pvr_hv(struct kvm_vcpu *vcpu, u32 
> pvr)
> vcpu->arch.pvr = pvr;
>  }
>
> -/* Dummy value used in computing PCR value below */
> -#define PCR_ARCH_300   (PCR_ARCH_207 << 1)
> -
Later will we need
+/* Dummy value used in computing PCR value below */
+#define PCR_ARCH_310   (PCR_ARCH_300 << 1)
?
>  static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat)
>  {
> unsigned long host_pcr_bit = 0, guest_pcr_bit = 0;
> --
> 2.20.1
>


Re: [PATCH v2 7/7] powerpc: Add POWER10 architected mode

2020-05-18 Thread Jordan Niethe
On Tue, May 19, 2020 at 10:48 AM Alistair Popple  wrote:
>
> PVR value of 0x0F06 means we are arch v3.1 compliant (i.e. POWER10).
> This is used by phyp and kvm when booting as a pseries guest to detect
> the presence of new P10 features and to enable the appropriate hwcap and
> facility bits.
>
> Signed-off-by: Alistair Popple 
> Signed-off-by: Cédric Le Goater 
> ---
>  arch/powerpc/include/asm/cputable.h   | 15 --
>  arch/powerpc/include/asm/mmu.h|  1 +
>  arch/powerpc/include/asm/prom.h   |  1 +
>  arch/powerpc/kernel/cpu_setup_power.S | 20 --
>  arch/powerpc/kernel/cputable.c| 30 +++
>  arch/powerpc/kernel/prom_init.c   | 12 +--
>  6 files changed, 73 insertions(+), 6 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/cputable.h 
> b/arch/powerpc/include/asm/cputable.h
> index 36f894dea9e7..10b6d93c9d0b 100644
> --- a/arch/powerpc/include/asm/cputable.h
> +++ b/arch/powerpc/include/asm/cputable.h
> @@ -468,6 +468,17 @@ static inline void cpu_feature_keys_init(void) { }
>  #define CPU_FTRS_POWER9_DD2_2 (CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD2_1 | \
>CPU_FTR_P9_TM_HV_ASSIST | \
>CPU_FTR_P9_TM_XER_SO_BUG)
> +#define CPU_FTRS_POWER10 (CPU_FTR_LWSYNC | \
> +   CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\
> +   CPU_FTR_MMCRA | CPU_FTR_SMT | \
> +   CPU_FTR_COHERENT_ICACHE | \
> +   CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
> +   CPU_FTR_DSCR | CPU_FTR_SAO  | \
> +   CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | 
> \
> +   CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
> +   CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_ARCH_207S | \
> +   CPU_FTR_TM_COMP | CPU_FTR_ARCH_300 | CPU_FTR_PKEY | \
> +   CPU_FTR_ARCH_31)
>  #define CPU_FTRS_CELL  (CPU_FTR_LWSYNC | \
> CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
> CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
> @@ -486,14 +497,14 @@ static inline void cpu_feature_keys_init(void) { }
>  #define CPU_FTRS_POSSIBLE  \
> (CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | CPU_FTRS_POWER8 | \
>  CPU_FTR_ALTIVEC_COMP | CPU_FTR_VSX_COMP | CPU_FTRS_POWER9 | \
> -CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2)
> +CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2 | CPU_FTRS_POWER10)
>  #else
>  #define CPU_FTRS_POSSIBLE  \
> (CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | \
>  CPU_FTRS_POWER6 | CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | \
>  CPU_FTRS_POWER8 | CPU_FTRS_CELL | CPU_FTRS_PA6T | \
>  CPU_FTR_VSX_COMP | CPU_FTR_ALTIVEC_COMP | CPU_FTRS_POWER9 | \
> -CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2)
> +CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2 | CPU_FTRS_POWER10)
>  #endif /* CONFIG_CPU_LITTLE_ENDIAN */
>  #endif
>  #else
> diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
> index 0699cfeeb8c9..17b19510f204 100644
> --- a/arch/powerpc/include/asm/mmu.h
> +++ b/arch/powerpc/include/asm/mmu.h
> @@ -122,6 +122,7 @@
>  #define MMU_FTRS_POWER7MMU_FTRS_POWER6
>  #define MMU_FTRS_POWER8MMU_FTRS_POWER6
>  #define MMU_FTRS_POWER9MMU_FTRS_POWER6
> +#define MMU_FTRS_POWER10   MMU_FTRS_POWER6
>  #define MMU_FTRS_CELL  MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
> MMU_FTR_CI_LARGE_PAGE
>  #define MMU_FTRS_PA6T  MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
> diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
> index 94e3fd54f2c8..324a13351749 100644
> --- a/arch/powerpc/include/asm/prom.h
> +++ b/arch/powerpc/include/asm/prom.h
> @@ -117,6 +117,7 @@ extern int of_read_drc_info_cell(struct property **prop,
>  #define OV1_PPC_2_07   0x01/* set if we support PowerPC 2.07 */
>
>  #define OV1_PPC_3_00   0x80/* set if we support PowerPC 3.00 */
> +#define OV1_PPC_3_10x40/* set if we support PowerPC 
> 3.1 */
>
>  /* Option vector 2: Open Firmware options supported */
>  #define OV2_REAL_MODE  0x20/* set if we want OF in real mode */
> diff --git a/arch/powerpc/kernel/cpu_setup_power.S 
> b/arch/powerpc/kernel/cpu_setup_power.S
> index a460298c7ddb..f3730cf904fa 100644
> --- a/arch/powerpc/kernel/cpu_setup_power.S
> +++ b/arch/powerpc/kernel/cpu_setup_power.S
> @@ -91,10 +91,15 @@ _GLOBAL(__restore_cpu_power8)
> mtlrr11
> blr
>
> +_GLOBAL(__setup_cpu_power10)
> +   mflrr11
> +   bl  __init_FSCR_P10
> +   b   1f
> +
>  _GLOBAL(__setup_cpu_power9)
> mflrr11
> bl  __init_FSCR
> -   bl  __init_PMU
> +1: bl  __init_PMU
> bl  __init_hvmode_206
> mtlrr11
> beqlr
> @@ -116,10 +121,15 @@ 

Re: [PATCH v8 11/30] powerpc: Use a datatype for instructions

2020-05-17 Thread Jordan Niethe
mpe, this is to go with the fixup I posted for mmu_patch_addis() in
[PATCH v8 12/30] powerpc: Use a function for reading instructions.
Thanks to Christophe pointing it out.

diff --git a/arch/powerpc/mm/nohash/8xx.c b/arch/powerpc/mm/nohash/8xx.c
--- a/arch/powerpc/mm/nohash/8xx.c
+++ b/arch/powerpc/mm/nohash/8xx.c
@@ -98,11 +98,12 @@ static void mmu_patch_cmp_limit(s32 *site,
unsigned long mapped)

 static void mmu_patch_addis(s32 *site, long simm)
 {
-unsigned int instr = *(unsigned int *)patch_site_addr(site);
+struct ppc_inst instr = *(struct ppc_inst *)patch_site_addr(site);
+unsigned int val = ppc_inst_val(instr);

-instr &= 0x;
-instr |= ((unsigned long)simm) >> 16;
-patch_instruction_site(site, ppc_inst(instr));
+val &= 0x;
+val |= ((unsigned long)simm) >> 16;
+patch_instruction_site(site, ppc_inst(val));
 }

 static void mmu_mapin_ram_chunk(unsigned long offset, unsigned long
top, pgprot_t prot)
--


Re: [PATCH v8 12/30] powerpc: Use a function for reading instructions

2020-05-17 Thread Jordan Niethe
On Sun, May 17, 2020 at 4:39 AM Christophe Leroy
 wrote:
>
>
>
> Le 06/05/2020 à 05:40, Jordan Niethe a écrit :
> > Prefixed instructions will mean there are instructions of different
> > length. As a result dereferencing a pointer to an instruction will not
> > necessarily give the desired result. Introduce a function for reading
> > instructions from memory into the instruction data type.
>
>
> Shouldn't this function be used in mmu_patch_addis() in mm/nohash/8xx.c ?
>
> Christophe
Yes, that would be a good idea. mpe here is a fix, along with one I'll
post for [PATCH v8 11/30] powerpc: Use a datatype for instructions.

diff --git a/arch/powerpc/mm/nohash/8xx.c b/arch/powerpc/mm/nohash/8xx.c
--- a/arch/powerpc/mm/nohash/8xx.c
+++ b/arch/powerpc/mm/nohash/8xx.c
@@ -98,7 +98,7 @@ static void mmu_patch_cmp_limit(s32 *site, unsigned
long mapped)

 static void mmu_patch_addis(s32 *site, long simm)
 {
-struct ppc_inst instr = *(struct ppc_inst *)patch_site_addr(site);
+struct ppc_inst instr = ppc_inst_read((struct ppc_inst
*)patch_site_addr(site));
 unsigned int val = ppc_inst_val(instr);

 val &= 0x;
-- 
>
> >
> > Reviewed-by: Alistair Popple 
> > Signed-off-by: Jordan Niethe 
> > ---
> > v4: New to series
> > v5: - Rename read_inst() -> probe_kernel_read_inst()
> >  - No longer modify uprobe probe type in this patch
> > v6: - feature-fixups.c: do_final_fixups(): Use here
> >  - arch_prepare_kprobe(): patch_instruction(): no longer part of this
> >patch
> >  - Move probe_kernel_read_inst() out of this patch
> >  - Use in uprobes
> > v8: style
> > ---
> >   arch/powerpc/include/asm/inst.h|  5 +
> >   arch/powerpc/kernel/kprobes.c  |  6 +++---
> >   arch/powerpc/kernel/mce_power.c|  2 +-
> >   arch/powerpc/kernel/optprobes.c|  4 ++--
> >   arch/powerpc/kernel/trace/ftrace.c |  4 ++--
> >   arch/powerpc/kernel/uprobes.c  |  2 +-
> >   arch/powerpc/lib/code-patching.c   | 26 ++
> >   arch/powerpc/lib/feature-fixups.c  |  4 ++--
> >   arch/powerpc/xmon/xmon.c   |  6 +++---
> >   9 files changed, 33 insertions(+), 26 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/inst.h 
> > b/arch/powerpc/include/asm/inst.h
> > index 19d8bb7a1c2b..552e953bf04f 100644
> > --- a/arch/powerpc/include/asm/inst.h
> > +++ b/arch/powerpc/include/asm/inst.h
> > @@ -27,6 +27,11 @@ static inline struct ppc_inst ppc_inst_swab(struct 
> > ppc_inst x)
> >   return ppc_inst(swab32(ppc_inst_val(x)));
> >   }
> >
> > +static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
> > +{
> > + return *ptr;
> > +}
> > +
> >   static inline bool ppc_inst_equal(struct ppc_inst x, struct ppc_inst y)
> >   {
> >   return ppc_inst_val(x) == ppc_inst_val(y);
> > diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> > index a08ae5803622..f64312dca84f 100644
> > --- a/arch/powerpc/kernel/kprobes.c
> > +++ b/arch/powerpc/kernel/kprobes.c
> > @@ -106,7 +106,7 @@ kprobe_opcode_t *kprobe_lookup_name(const char *name, 
> > unsigned int offset)
> >   int arch_prepare_kprobe(struct kprobe *p)
> >   {
> >   int ret = 0;
> > - struct ppc_inst insn = *(struct ppc_inst *)p->addr;
> > + struct ppc_inst insn = ppc_inst_read((struct ppc_inst *)p->addr);
> >
> >   if ((unsigned long)p->addr & 0x03) {
> >   printk("Attempt to register kprobe at an unaligned 
> > address\n");
> > @@ -127,7 +127,7 @@ int arch_prepare_kprobe(struct kprobe *p)
> >   if (!ret) {
> >   memcpy(p->ainsn.insn, p->addr,
> >   MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
> > - p->opcode = *p->addr;
> > + p->opcode = ppc_inst_val(insn);
> >   flush_icache_range((unsigned long)p->ainsn.insn,
> >   (unsigned long)p->ainsn.insn + 
> > sizeof(kprobe_opcode_t));
> >   }
> > @@ -217,7 +217,7 @@ NOKPROBE_SYMBOL(arch_prepare_kretprobe);
> >   static int try_to_emulate(struct kprobe *p, struct pt_regs *regs)
> >   {
> >   int ret;
> > - struct ppc_inst insn = *(struct ppc_inst *)p->ainsn.insn;
> > + struct ppc_inst insn = ppc_inst_read((struct ppc_inst 
> > *)p->ainsn.insn);
> >
> >   /* regs->nip is also adjusted if emulate_step returns 1 */
> >   ret = emulate_step(regs, insn);
> > diff --git a/arch

Re: [PATCH v8 08/30] powerpc: Use a function for getting the instruction op code

2020-05-17 Thread Jordan Niethe
On Sat, May 16, 2020 at 9:08 PM Michael Ellerman  wrote:
>
> Jordan Niethe  writes:
> > mpe, as suggested by Christophe could you please add this.
>
> I did that and ...
>
> > diff --git a/arch/powerpc/include/asm/inst.h 
> > b/arch/powerpc/include/asm/inst.h
> > --- a/arch/powerpc/include/asm/inst.h
> > +++ b/arch/powerpc/include/asm/inst.h
> > @@ -2,6 +2,8 @@
> >  #ifndef _ASM_INST_H
> >  #define _ASM_INST_H
> >
> > +#include 
>
> .. this eventually breaks the build in some driver, because get_ra() is
> redefined.
>
> So I've backed out this change for now.
Thanks, that is fine with me.
>
> If we want to use the macros in disassemble.h we'll need to namespace
> them better, eg. make them ppc_get_ra() and so on.
>
> cheers
>
> >  /*
> >   * Instruction data type for POWER
> >   */
> > @@ -15,7 +17,7 @@ static inline u32 ppc_inst_val(u32 x)
> >
> >  static inline int ppc_inst_primary_opcode(u32 x)
> >  {
> > -return ppc_inst_val(x) >> 26;
> > +return get_op(ppc_inst_val(x));
> >  }
> >
> >  #endif /* _ASM_INST_H */
> > --
> > 2.17.1


Re: [PATCH v8 30/30] powerpc sstep: Add support for prefixed fixed-point arithmetic

2020-05-15 Thread Jordan Niethe
mpe, and this thanks.
---
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -1343,7 +1343,7 @@ int analyse_instr(struct instruction_op *op,
const struct pt_regs *regs,
 rd = (suffix >> 21) & 0x1f;
 op->reg = rd;
 op->val = regs->gpr[rd];
-suffixopcode = suffix >> 26;
+suffixopcode = get_op(suffix);
 prefixtype = (word >> 24) & 0x3;
 switch (prefixtype) {
 case 2:
-- 
2.17.1


Re: [PATCH v8 29/30] powerpc sstep: Add support for prefixed load/stores

2020-05-15 Thread Jordan Niethe
mpe, and this thanks.

diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -1204,7 +1204,7 @@ int analyse_instr(struct instruction_op *op,
const struct pt_regs *regs,
   struct ppc_inst instr)
 {
 unsigned int opcode, ra, rb, rc, rd, spr, u;
-#ifdef __powerpc64__
+#ifdef CONFIG_PPC64
 unsigned int suffixopcode, prefixtype, prefix_r;
 #endif
 unsigned long int imm;
@@ -2701,7 +2701,7 @@ int analyse_instr(struct instruction_op *op,
const struct pt_regs *regs,
 op->reg = rd;
 op->val = regs->gpr[rd];

-suffixopcode = suffix >> 26;
+suffixopcode = get_op(suffix);
 prefixtype = (word >> 24) & 0x3;
 switch (prefixtype) {
 case 0: /* Type 00  Eight-Byte Load/Store */
-- 
2.17.1


Re: [PATCH v8 25/30] powerpc: Test prefixed instructions in feature fixups

2020-05-15 Thread Jordan Niethe
Hey mpe, could you add this thanks.
diff --git a/arch/powerpc/lib/feature-fixups.c
b/arch/powerpc/lib/feature-fixups.c
--- a/arch/powerpc/lib/feature-fixups.c
+++ b/arch/powerpc/lib/feature-fixups.c
@@ -689,7 +689,7 @@ static void test_lwsync_macros(void)
 }
 }

-#ifdef __powerpc64__
+#ifdef CONFIG_PPC64
 static void __init test_prefix_patching(void)
 {
 extern unsigned int ftr_fixup_prefix1[];
@@ -755,7 +755,7 @@ static void __init test_prefix_word_alt_patching(void)
 patch_feature_section(0, );
 check(memcmp(ftr_fixup_prefix3, ftr_fixup_prefix3_orig, size) != 0);
 }
-#endif /* __powerpc64__ */
+#endif /* CONFIG_PPC64 */

 static int __init test_feature_fixups(void)
 {
@@ -771,7 +771,7 @@ static int __init test_feature_fixups(void)
 test_cpu_macros();
 test_fw_macros();
 test_lwsync_macros();
-#ifdef __powerpc64__
+#ifdef CONFIG_PPC64
 test_prefix_patching();
 test_prefix_alt_patching();
 test_prefix_word_alt_patching();
--


Re: [PATCH v8 24/30] powerpc: Test prefixed code patching

2020-05-15 Thread Jordan Niethe
Hey mpe could you add this please.
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -707,7 +707,7 @@ static void __init test_translate_branch(void)
 vfree(buf);
 }

-#ifdef __powerpc64__
+#ifdef CONFIG_PPC64
 static void __init test_prefixed_patching(void)
 {
 extern unsigned int code_patching_test1[];
@@ -733,7 +733,7 @@ static int __init test_code_patching(void)
 test_branch_bform();
 test_create_function_call();
 test_translate_branch();
-#ifdef __powerpc64__
+#ifdef CONFIG_PPC64
 test_prefixed_patching();
 #endif

-- 
2.17.1


Re: [PATCH v8 23/30] powerpc: Add prefixed instructions to instruction data type

2020-05-15 Thread Jordan Niethe
Hey mpe, fixes for the issues highlighted by Christophe, except KUAP
as discussed. Will make the optprobe change as a preceding patch.

diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h
--- a/arch/powerpc/include/asm/inst.h
+++ b/arch/powerpc/include/asm/inst.h
@@ -11,9 +11,9 @@

 struct ppc_inst {
 u32 val;
-#ifdef __powerpc64__
+#ifdef CONFIG_PPC64
 u32 suffix;
-#endif /* __powerpc64__ */
+#endif /* CONFIG_PPC64 */
 } __packed;

 static inline u32 ppc_inst_val(struct ppc_inst x)
@@ -26,7 +26,7 @@ static inline int ppc_inst_primary_opcode(struct ppc_inst x)
 return get_op(ppc_inst_val(x));
 }

-#ifdef __powerpc64__
+#ifdef CONFIG_PPC64
 #define ppc_inst(x) ((struct ppc_inst){ .val = (x), .suffix = 0xff })

 #define ppc_inst_prefix(x, y) ((struct ppc_inst){ .val = (x), .suffix = (y) })
@@ -52,7 +52,7 @@ static inline struct ppc_inst ppc_inst_read(const
struct ppc_inst *ptr)
 u32 val, suffix;

 val = *(u32 *)ptr;
-if ((val >> 26) == 1) {
+if ((get_op(val)) == OP_PREFIX) {
 suffix = *((u32 *)ptr + 1);
 return ppc_inst_prefix(val, suffix);
 } else {
@@ -94,7 +94,7 @@ static inline bool ppc_inst_equal(struct ppc_inst x,
struct ppc_inst y)
 return ppc_inst_val(x) == ppc_inst_val(y);
 }

-#endif /* __powerpc64__ */
+#endif /* CONFIG_PPC64 */

 static inline int ppc_inst_len(struct ppc_inst x)
 {
diff --git a/arch/powerpc/include/asm/uaccess.h
b/arch/powerpc/include/asm/uaccess.h
index e9027b3c641a..ac36a82321d4 100644
--- a/arch/powerpc/include/asm/uaccess.h
+++ b/arch/powerpc/include/asm/uaccess.h
@@ -105,7 +105,7 @@ static inline int __access_ok(unsigned long addr,
unsigned long size,
 #define __put_user_inatomic(x, ptr) \
 __put_user_nosleep((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))

-#ifdef __powerpc64__
+#ifdef CONFIG_PPC64
 #define __get_user_instr(x, ptr)\
 ({\
 long __gui_ret = 0;\
@@ -113,7 +113,7 @@ static inline int __access_ok(unsigned long addr,
unsigned long size,
 struct ppc_inst __gui_inst;\
 unsigned int prefix, suffix;\
 __gui_ret = __get_user(prefix, (unsigned int __user *)__gui_ptr);\
-if (!__gui_ret && (prefix >> 26) == OP_PREFIX) {\
+if (!__gui_ret && (get_op(prefix)) == OP_PREFIX) {\
 __gui_ret = __get_user(suffix,\
(unsigned int __user *)__gui_ptr + 1);\
 __gui_inst = ppc_inst_prefix(prefix, suffix);\
@@ -131,7 +131,7 @@ static inline int __access_ok(unsigned long addr,
unsigned long size,
 struct ppc_inst __gui_inst;\
 unsigned int prefix, suffix;\
 __gui_ret = __get_user_inatomic(prefix, (unsigned int __user
*)__gui_ptr);\
-if (!__gui_ret && (prefix >> 26) == OP_PREFIX) {\
+if (!__gui_ret && (get_op(prefix)) == OP_PREFIX) {\
 __gui_ret = __get_user_inatomic(suffix,\
 (unsigned int __user *)__gui_ptr + 1);\
 __gui_inst = ppc_inst_prefix(prefix, suffix);\
diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c
index a8e66603d12b..3ac105e7faae 100644
--- a/arch/powerpc/kernel/optprobes.c
+++ b/arch/powerpc/kernel/optprobes.c
@@ -283,10 +283,8 @@ int arch_prepare_optimized_kprobe(struct
optimized_kprobe *op, struct kprobe *p)
  * 3. load instruction to be emulated into relevant register, and
  */
 temp = ppc_inst_read((struct ppc_inst *)p->ainsn.insn);
-patch_imm64_load_insns(ppc_inst_val(temp) |
-   ((u64)ppc_inst_suffix(temp) << 32),
-   4,
-   buff + TMPL_INSN_IDX);
+patch_imm64_load_insns(ppc_inst_val(temp) |
((u64)ppc_inst_suffix(temp) << 32),
+   4, buff + TMPL_INSN_IDX);

 /*
  * 4. branch back from trampoline
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index 58b67b62d5d3..bfd4e1dae0fb 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -26,8 +26,6 @@ static int __patch_instruction(struct ppc_inst
*exec_addr, struct ppc_inst instr

 if (!ppc_inst_prefixed(instr)) {
 __put_user_asm(ppc_inst_val(instr), patch_addr, err, "stw");
-if (err)
-return err;
 } else {
 #ifdef CONFIG_CPU_LITTLE_ENDIAN
 __put_user_asm((u64)ppc_inst_suffix(instr) << 32 |
@@ -36,12 +34,13 @@ static int __patch_instruction(struct ppc_inst
*exec_addr, struct ppc_inst instr
 __put_user_asm((u64)ppc_inst_val(instr) << 32 |
ppc_inst_suffix(instr), patch_addr, err, "std");
 #endif /* CONFIG_CPU_LITTLE_ENDIAN */
-if (err)
-return err;
 }
+if (err)
+return err;

 asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr),
 "r" (exec_addr));
+
 return 0;
 }

diff --git a/arch/powerpc/lib/inst.c 

Re: [PATCH v8 08/30] powerpc: Use a function for getting the instruction op code

2020-05-15 Thread Jordan Niethe
mpe, as suggested by Christophe could you please add this.
diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h
--- a/arch/powerpc/include/asm/inst.h
+++ b/arch/powerpc/include/asm/inst.h
@@ -2,6 +2,8 @@
 #ifndef _ASM_INST_H
 #define _ASM_INST_H

+#include 
+
 /*
  * Instruction data type for POWER
  */
@@ -15,7 +17,7 @@ static inline u32 ppc_inst_val(u32 x)

 static inline int ppc_inst_primary_opcode(u32 x)
 {
-return ppc_inst_val(x) >> 26;
+return get_op(ppc_inst_val(x));
 }

 #endif /* _ASM_INST_H */
-- 
2.17.1


Re: [PATCH v8 13/30] powerpc: Add a probe_user_read_inst() function

2020-05-14 Thread Jordan Niethe
On Thu, May 14, 2020 at 3:46 PM Christophe Leroy
 wrote:
>
>
>
> Le 06/05/2020 à 05:40, Jordan Niethe a écrit :
> > Introduce a probe_user_read_inst() function to use in cases where
> > probe_user_read() is used for getting an instruction. This will be more
> > useful for prefixed instructions.
> >
> > Reviewed-by: Alistair Popple 
> > Signed-off-by: Jordan Niethe 
> > ---
> > v6: - New to series
> > ---
> >   arch/powerpc/include/asm/inst.h |  3 +++
> >   arch/powerpc/lib/Makefile   |  2 +-
> >   arch/powerpc/lib/inst.c | 18 ++
> >   arch/powerpc/mm/fault.c |  2 +-
> >   4 files changed, 23 insertions(+), 2 deletions(-)
> >   create mode 100644 arch/powerpc/lib/inst.c
> >
> > diff --git a/arch/powerpc/include/asm/inst.h 
> > b/arch/powerpc/include/asm/inst.h
> > index 552e953bf04f..3e9a58420151 100644
> > --- a/arch/powerpc/include/asm/inst.h
> > +++ b/arch/powerpc/include/asm/inst.h
> > @@ -37,4 +37,7 @@ static inline bool ppc_inst_equal(struct ppc_inst x, 
> > struct ppc_inst y)
> >   return ppc_inst_val(x) == ppc_inst_val(y);
> >   }
> >
> > +int probe_user_read_inst(struct ppc_inst *inst,
> > +  struct ppc_inst *nip);
> > +
> >   #endif /* _ASM_INST_H */
> > diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
> > index b8de3be10eb4..546591848219 100644
> > --- a/arch/powerpc/lib/Makefile
> > +++ b/arch/powerpc/lib/Makefile
> > @@ -16,7 +16,7 @@ CFLAGS_code-patching.o += -DDISABLE_BRANCH_PROFILING
> >   CFLAGS_feature-fixups.o += -DDISABLE_BRANCH_PROFILING
> >   endif
> >
> > -obj-y += alloc.o code-patching.o feature-fixups.o pmem.o
> > +obj-y += alloc.o code-patching.o feature-fixups.o pmem.o inst.o
> >
> >   ifndef CONFIG_KASAN
> >   obj-y   +=  string.o memcmp_$(BITS).o
> > diff --git a/arch/powerpc/lib/inst.c b/arch/powerpc/lib/inst.c
> > new file mode 100644
> > index ..eaf786afad2b
> > --- /dev/null
> > +++ b/arch/powerpc/lib/inst.c
> > @@ -0,0 +1,18 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + *  Copyright 2020, IBM Corporation.
> > + */
> > +
> > +#include 
> > +#include 
> > +
> > +int probe_user_read_inst(struct ppc_inst *inst,
> > +  struct ppc_inst *nip)
> > +{
> > + unsigned int val;
> > + int err;
> > +
> > + err = probe_user_read(, nip, sizeof(val));
> > + *inst = ppc_inst(val);
> > + return err;
> > +}
> > diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
> > index 4a50f125ec18..f3a943eae305 100644
> > --- a/arch/powerpc/mm/fault.c
> > +++ b/arch/powerpc/mm/fault.c
> > @@ -281,7 +281,7 @@ static bool bad_stack_expansion(struct pt_regs *regs, 
> > unsigned long address,
> >   access_ok(nip, sizeof(*nip))) {
> >   struct ppc_inst inst;
> >
> > - if (!probe_user_read(, nip, sizeof(inst)))
> > + if (!probe_user_read_inst(, (struct ppc_inst 
> > __user *)nip))
>
> Shouldn't 'nip' become de 'struct ppc_inst __user *' instead of casting ?
>
> >   return !store_updates_sp(inst);
> >   *must_retry = true;
> >   }
> >
Yeah it would make more sense to do it like this.
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -256,7 +256,7 @@ static bool bad_stack_expansion(struct pt_regs
*regs, unsigned long address,
  * expand to 1MB without further checks.
  */
 if (address + 0x10 < vma->vm_end) {
-unsigned int __user *nip = (unsigned int __user *)regs->nip;
+struct ppc_inst __user *nip = (struct ppc_inst __user *)regs->nip;
 /* get user regs even if this fault is in kernel mode */
 struct pt_regs *uregs = current->thread.regs;
 if (uregs == NULL)
@@ -281,7 +281,7 @@ static bool bad_stack_expansion(struct pt_regs
*regs, unsigned long address,
 access_ok(nip, sizeof(*nip))) {
 struct ppc_inst inst;

-if (!probe_user_read_inst(, (struct ppc_inst __user *)nip))
+if (!probe_user_read_inst(, nip))
 return !store_updates_sp(inst);
 *must_retry = true;
 }
-- 
2.17.1
>
> Christophe


Re: [PATCH v8 23/30] powerpc: Add prefixed instructions to instruction data type

2020-05-14 Thread Jordan Niethe
On Thu, May 14, 2020 at 10:06 PM Alistair Popple  wrote:
>
> On Thursday, 14 May 2020 4:11:43 PM AEST Christophe Leroy wrote:
> > @@ -249,7 +249,7 @@ int arch_prepare_optimized_kprobe(struct
> > optimized_kprobe *op, struct kprobe *p)
> > > * Fixup the template with instructions to:
> > > * 1. load the address of the actual probepoint
> > > */
> > > -   patch_imm64_load_insns((unsigned long)op, buff + TMPL_OP_IDX);
> > > +   patch_imm64_load_insns((unsigned long)op, 3, buff + TMPL_OP_IDX);
> > >
> > > /*
> > > * 2. branch to optimized_callback() and emulate_step()
> > > @@ -282,7 +282,11 @@ int arch_prepare_optimized_kprobe(struct
> > > optimized_kprobe *op, struct kprobe *p) /*
> > > * 3. load instruction to be emulated into relevant register, and
> > > */
> > > -   patch_imm32_load_insns(*p->ainsn.insn, buff + TMPL_INSN_IDX);
> > > +   temp = ppc_inst_read((struct ppc_inst *)p->ainsn.insn);
> > > +   patch_imm64_load_insns(ppc_inst_val(temp) |
> > > +  ((u64)ppc_inst_suffix(temp) << 32),
> > > +  4,
> >
> > So now we are also using r4 ? Any explanation somewhere on the way it
> > works ? This change seems unrelated to this patch, nothing in the
> > description about it. Can we suddenly use a new register without problem ?
>
> Unless I missed something there is no change in register usage here that I
> could see. patch_imm32_load_insns() was/is hardcoded to use register r4.
Yes, that is right.
>
> - Alistair
>
>


Re: [PATCH v8 23/30] powerpc: Add prefixed instructions to instruction data type

2020-05-14 Thread Jordan Niethe
On Thu, May 14, 2020 at 4:12 PM Christophe Leroy
 wrote:
>
>
>
> Le 06/05/2020 à 05:40, Jordan Niethe a écrit :
> > For powerpc64, redefine the ppc_inst type so both word and prefixed
> > instructions can be represented. On powerpc32 the type will remain the
> > same.  Update places which had assumed instructions to be 4 bytes long.
> >
> > Reviewed-by: Alistair Popple 
> > Signed-off-by: Jordan Niethe 
> > ---
> > v4: New to series
> > v5:  - Distinguish normal instructions from prefixed instructions with a
> > 0xff marker for the suffix.
> >   - __patch_instruction() using std for prefixed instructions
> > v6:  - Return false instead of 0 in ppc_inst_prefixed()
> >   - Fix up types for ppc32 so it compiles
> >   - remove ppc_inst_write()
> >   - __patching_instruction(): move flush out of condition
> > v8:  - style
> >   - Define and use OP_PREFIX instead of '1' (back from v3)
> >   - __patch_instruction() fix for big endian
> > ---
> >   arch/powerpc/include/asm/inst.h   | 69 ---
> >   arch/powerpc/include/asm/kprobes.h|  2 +-
> >   arch/powerpc/include/asm/ppc-opcode.h |  3 ++
> >   arch/powerpc/include/asm/uaccess.h| 40 +++-
> >   arch/powerpc/include/asm/uprobes.h|  2 +-
> >   arch/powerpc/kernel/crash_dump.c  |  2 +-
> >   arch/powerpc/kernel/optprobes.c   | 42 
> >   arch/powerpc/kernel/optprobes_head.S  |  3 ++
> >   arch/powerpc/lib/code-patching.c  | 19 ++--
> >   arch/powerpc/lib/feature-fixups.c |  5 +-
> >   arch/powerpc/lib/inst.c   | 41 
> >   arch/powerpc/lib/sstep.c  |  4 +-
> >   arch/powerpc/xmon/xmon.c  |  4 +-
> >   arch/powerpc/xmon/xmon_bpts.S |  2 +
> >   14 files changed, 200 insertions(+), 38 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/inst.h 
> > b/arch/powerpc/include/asm/inst.h
> > index 2f3c9d5bcf7c..7868b80b610e 100644
> > --- a/arch/powerpc/include/asm/inst.h
> > +++ b/arch/powerpc/include/asm/inst.h
> > @@ -2,29 +2,79 @@
> >   #ifndef _ASM_INST_H
> >   #define _ASM_INST_H
> >
> > +#include 
> >   /*
> >* Instruction data type for POWER
> >*/
> >
> >   struct ppc_inst {
> >   u32 val;
> > +#ifdef __powerpc64__
>
> CONFIG_PPC64 should be used instead. This is also reported by checkpatch.
Sure will use that instead.
>
> > + u32 suffix;
> > +#endif /* __powerpc64__ */
> >   } __packed;
> >
> > -#define ppc_inst(x) ((struct ppc_inst){ .val = x })
> > -
> >   static inline u32 ppc_inst_val(struct ppc_inst x)
> >   {
> >   return x.val;
> >   }
> >
> > -static inline int ppc_inst_len(struct ppc_inst x)
> > +static inline int ppc_inst_primary_opcode(struct ppc_inst x)
> >   {
> > - return sizeof(struct ppc_inst);
> > + return ppc_inst_val(x) >> 26;
>
> What about using get_op() from asm/disassemble.h instead of hardcodiing ?
Okay will use it here and the other places you point out.
>
> >   }
> >
> > -static inline int ppc_inst_primary_opcode(struct ppc_inst x)
> > +#ifdef __powerpc64__
>
> Use CONFIG_PPC64
>
> > +#define ppc_inst(x) ((struct ppc_inst){ .val = (x), .suffix = 0xff })
> > +
> > +#define ppc_inst_prefix(x, y) ((struct ppc_inst){ .val = (x), .suffix = 
> > (y) })
> > +
> > +static inline u32 ppc_inst_suffix(struct ppc_inst x)
> >   {
> > - return ppc_inst_val(x) >> 26;
> > + return x.suffix;
> > +}
> > +
> > +static inline bool ppc_inst_prefixed(struct ppc_inst x)
> > +{
> > + return (ppc_inst_primary_opcode(x) == 1) && ppc_inst_suffix(x) != 
> > 0xff;
> > +}
> > +
> > +static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
> > +{
> > + return ppc_inst_prefix(swab32(ppc_inst_val(x)),
> > +swab32(ppc_inst_suffix(x)));
> > +}
> > +
> > +static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
> > +{
> > + u32 val, suffix;
> > +
> > + val = *(u32 *)ptr;
> > + if ((val >> 26) == 1) {
>
> Don't hardcode, use ppc_inst_primary_opcode() and compare it to OP_PREFIX
> Or use get_op() from asm/disassemble.h
>
>
> > + suffix = *((u32 *)ptr + 1);
> > + return ppc_inst_prefix(val, suffix);
> > + } else {
> > + return ppc_inst(val);
> > +

Re: [PATCH v8 00/30] Initial Prefixed Instruction support

2020-05-14 Thread Jordan Niethe
On Thu, May 14, 2020 at 3:31 PM Christophe Leroy
 wrote:
>
>
>
> Le 06/05/2020 à 05:40, Jordan Niethe a écrit :
> > A future revision of the ISA will introduce prefixed instructions. A
> > prefixed instruction is composed of a 4-byte prefix followed by a
> > 4-byte suffix.
> >
> > All prefixes have the major opcode 1. A prefix will never be a valid
> > word instruction. A suffix may be an existing word instruction or a
> > new instruction.
> >
> > This series enables prefixed instructions and extends the instruction
> > emulation to support them. Then the places where prefixed instructions
> > might need to be emulated are updated.
> >
> > v8 incorporates feedback from Alistair Popple and Balamuruhan Suriyakumar.
> > The major changes:
> >  - Fix some style issues
> >  - Fix __patch_instruction() on big endian
> >  - Reintroduce v3's forbidding breakpoints on second word of prefix
> >instructions for kprobes and xmon. Missed this when changing to
> >using a data type.
> >  - Use the data type in some places that were missed.
>
> Checkpatch seems to report the following warnings for pmac32_defconfig,
> are they harmless ?
>
> +arch/powerpc/kernel/align.c:307:13: warning: cast removes address space
> '' of expression
> +arch/powerpc/kernel/align.c:307:13: warning: cast removes address space
> '' of expression
> +arch/powerpc/kernel/align.c:307:13: warning: cast removes address space
> '' of expression
> +arch/powerpc/kernel/align.c:307:13: warning: cast removes address space
> '' of expression
> +arch/powerpc/kernel/align.c:307:13: warning: cast removes address space
> '' of expression
> +arch/powerpc/kernel/align.c:307:13: warning: incorrect type in argument
> 1 (different address spaces) expected void const volatile [noderef]
>  * got unsigned int [usertype] *
> +arch/powerpc/kernel/align.c:307:13: warning: incorrect type in
> initializer (different address spaces) expected unsigned int [noderef]
>  *__gu_addr got unsigned int [usertype] *
> +arch/powerpc/kernel/hw_breakpoint.c:XX:13: warning: cast removes
> address space '' of expression
> +arch/powerpc/kernel/hw_breakpoint.c:XX:13: warning: cast removes
> address space '' of expression
> +arch/powerpc/kernel/hw_breakpoint.c:XX:13: warning: cast removes
> address space '' of expression
> +arch/powerpc/kernel/hw_breakpoint.c:XX:13: warning: cast removes
> address space '' of expression
> +arch/powerpc/kernel/hw_breakpoint.c:XX:13: warning: cast removes
> address space '' of expression
> -arch/powerpc/kernel/hw_breakpoint.c:XX:13: warning: incorrect type in
> argument 1 (different address spaces) expected void const volatile
> [noderef]  * got unsigned int *
> +arch/powerpc/kernel/hw_breakpoint.c:XX:13: warning: incorrect type in
> argument 1 (different address spaces) expected void const volatile
> [noderef]  * got unsigned int [usertype] *
> -arch/powerpc/kernel/hw_breakpoint.c:XX:13: warning: incorrect type in
> initializer (different address spaces) expected unsigned int [noderef]
>  *__gu_addr got unsigned int *
> +arch/powerpc/kernel/hw_breakpoint.c:XX:13: warning: incorrect type in
> initializer (different address spaces) expected unsigned int [noderef]
>  *__gu_addr got unsigned int [usertype] *
> +arch/powerpc/kernel/vecemu.c:269:13: warning: cast removes address
> space '' of expression
> +arch/powerpc/kernel/vecemu.c:269:13: warning: cast removes address
> space '' of expression
> +arch/powerpc/kernel/vecemu.c:269:13: warning: cast removes address
> space '' of expression
> +arch/powerpc/kernel/vecemu.c:269:13: warning: cast removes address
> space '' of expression
> +arch/powerpc/kernel/vecemu.c:269:13: warning: cast removes address
> space '' of expression
> +arch/powerpc/kernel/vecemu.c:269:13: warning: incorrect type in
> argument 1 (different address spaces) expected void const volatile
> [noderef]  * got unsigned int [usertype] *
> +arch/powerpc/kernel/vecemu.c:269:13: warning: incorrect type in
> initializer (different address spaces) expected unsigned int [noderef]
>  *__gu_addr got unsigned int [usertype] *
> +arch/powerpc/lib/inst.c:55:37: warning: incorrect type in argument 2
> (different address spaces) expected void const [noderef]  *src
> got struct ppc_inst *nip
> +arch/powerpc/mm/fault.c:284:59: warning: incorrect type in argument 2
> (different address spaces) expected struct ppc_inst *nip got struct
> ppc_inst [noderef]  *
Thanks, I was missing some __user.
--- a/arch/powerpc/include/asm/uaccess.h
+++ b/arch/powerpc/include/asm/uaccess.h
@@ -106,10 +106,10 @@ static inline int __access_ok(unsigned long
addr, unsigned long size,
__put_user_nosleep((__typeof__(

Re: [PATCH v8 16/30] powerpc: Define and use __get_user_instr{, inatomic}()

2020-05-13 Thread Jordan Niethe
Hi mpe, could you please take this.

 arch/powerpc/include/asm/uaccess.h | 3 +++
 arch/powerpc/kernel/vecemu.c   | 2 +-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/uaccess.h
b/arch/powerpc/include/asm/uaccess.h
--- a/arch/powerpc/include/asm/uaccess.h
+++ b/arch/powerpc/include/asm/uaccess.h
@@ -105,6 +105,9 @@ static inline int __access_ok(unsigned long addr,
unsigned long size,
 #define __put_user_inatomic(x, ptr) \
 __put_user_nosleep((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))

+#define get_user_instr(x, ptr) \
+get_user((x).val, (u32 *)(ptr))
+
 #define __get_user_instr(x, ptr) \
 __get_user_nocheck((x).val, (u32 *)(ptr), sizeof(u32), true)

diff --git a/arch/powerpc/kernel/vecemu.c b/arch/powerpc/kernel/vecemu.c
index 60ed5aea8d4e..ae632569446f 100644
--- a/arch/powerpc/kernel/vecemu.c
+++ b/arch/powerpc/kernel/vecemu.c
@@ -266,7 +266,7 @@ int emulate_altivec(struct pt_regs *regs)
 unsigned int va, vb, vc, vd;
 vector128 *vrs;

-if (__get_user_instr(instr, (void __user *)regs->nip))
+if (get_user_instr(instr, (void __user *)regs->nip))
 return -EFAULT;

 word = ppc_inst_val(instr);


Re: [PATCH v8 23/30] powerpc: Add prefixed instructions to instruction data type

2020-05-13 Thread Jordan Niethe
Hi mpe,
Relating to your message on [PATCH v8 16/30] powerpc: Define and use
__get_user_instr{,inatomic}() - could you please take this.

diff --git a/arch/powerpc/include/asm/uaccess.h
b/arch/powerpc/include/asm/uaccess.h
--- a/arch/powerpc/include/asm/uaccess.h
+++ b/arch/powerpc/include/asm/uaccess.h
@@ -106,6 +106,24 @@ static inline int __access_ok(unsigned long addr,
unsigned long size,
 __put_user_nosleep((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))

 #ifdef __powerpc64__
+#define get_user_instr(x, ptr) \
+({\
+long __gui_ret = 0;\
+unsigned long __gui_ptr = (unsigned long)ptr;\
+struct ppc_inst __gui_inst;\
+unsigned int prefix, suffix;\
+__gui_ret = get_user(prefix, (unsigned int __user *)__gui_ptr);\
+if (!__gui_ret && (prefix >> 26) == OP_PREFIX) {\
+__gui_ret = get_user(suffix,\
+   (unsigned int __user *)__gui_ptr + 1);\
+__gui_inst = ppc_inst_prefix(prefix, suffix);\
+} else {\
+__gui_inst = ppc_inst(prefix);\
+}\
+(x) = __gui_inst;\
+__gui_ret;\
+})
+
 #define __get_user_instr(x, ptr)\
 ({\
 long __gui_ret = 0;\
@@ -142,6 +160,8 @@ static inline int __access_ok(unsigned long addr,
unsigned long size,
 __gui_ret;\
 })
 #else
+#define get_user_instr(x, ptr) \
+get_user((x).val, (u32 *)(ptr))
 #define __get_user_instr(x, ptr) \
 __get_user_nocheck((x).val, (u32 *)(ptr), sizeof(u32), true)
 #define __get_user_instr_inatomic(x, ptr) \


Re: [PATCH v8 16/30] powerpc: Define and use __get_user_instr{, inatomic}()

2020-05-13 Thread Jordan Niethe
On Thu, May 14, 2020 at 12:17 AM Michael Ellerman  wrote:
>
> Jordan Niethe  writes:
> > Define specific __get_user_instr() and __get_user_instr_inatomic()
> > macros for reading instructions from user space.
>
> At least for fix_alignment() we could be coming from the kernel, not
> sure about the other cases.
>
> I can tweak the change log.
>
> > diff --git a/arch/powerpc/include/asm/uaccess.h 
> > b/arch/powerpc/include/asm/uaccess.h
> > index 2f500debae21..c0a35e4586a5 100644
> > --- a/arch/powerpc/include/asm/uaccess.h
> > +++ b/arch/powerpc/include/asm/uaccess.h
> > @@ -105,6 +105,11 @@ static inline int __access_ok(unsigned long addr, 
> > unsigned long size,
> >  #define __put_user_inatomic(x, ptr) \
> >   __put_user_nosleep((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
> >
> > +#define __get_user_instr(x, ptr) \
> > + __get_user_nocheck((x).val, (u32 *)(ptr), sizeof(u32), true)
> > +
> > +#define __get_user_instr_inatomic(x, ptr) \
> > + __get_user_nosleep((x).val, (u32 *)(ptr), sizeof(u32))
>
> I'm not super keen on adding new __ versions, which lack the access_ok()
> check, but I guess we have to.
>
> > diff --git a/arch/powerpc/kernel/vecemu.c b/arch/powerpc/kernel/vecemu.c
> > index 3dd70eeb10c5..60ed5aea8d4e 100644
> > --- a/arch/powerpc/kernel/vecemu.c
> > +++ b/arch/powerpc/kernel/vecemu.c
> > @@ -266,7 +266,7 @@ int emulate_altivec(struct pt_regs *regs)
> >   unsigned int va, vb, vc, vd;
> >   vector128 *vrs;
> >
> > - if (get_user(instr.val, (unsigned int __user *)regs->nip))
> > + if (__get_user_instr(instr, (void __user *)regs->nip))
> >   return -EFAULT;
>
> That drops the access_ok() check, which is not OK, at least without a
> reasonable justification.
>
> Given it's regs->nip I guess it should be safe, but it should still be
> called out. Or preferably switched to __get_user() in a precursor patch.
Or should I add a get_user_instr() that includes the check?
>
> cheers


Re: [PATCH v8 13/30] powerpc: Add a probe_user_read_inst() function

2020-05-13 Thread Jordan Niethe
On Wed, May 13, 2020 at 10:52 PM Michael Ellerman  wrote:
>
> Jordan Niethe  writes:
> > diff --git a/arch/powerpc/lib/inst.c b/arch/powerpc/lib/inst.c
> > new file mode 100644
> > index ..eaf786afad2b
> > --- /dev/null
> > +++ b/arch/powerpc/lib/inst.c
> > @@ -0,0 +1,18 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + *  Copyright 2020, IBM Corporation.
> > + */
> > +
> > +#include 
> > +#include 
> > +
> > +int probe_user_read_inst(struct ppc_inst *inst,
> > +  struct ppc_inst *nip)
> > +{
> > + unsigned int val;
> > + int err;
> > +
> > + err = probe_user_read(, nip, sizeof(val));
> > + *inst = ppc_inst(val);
>
> We shouldn't be storing to *inst if the read failed?
Good point.
>
> I changed it to:
>
> +   if (!err)
> +   *inst = ppc_inst(val);
> +
>
> Similarly for probe_kernel_read_inst().
Thanks.
>
> cheers


  1   2   3   4   >