* Re: [PATCH] tools/perf: Fix powerpc gap between kernel end and module start
From: Athira Rajeev @ 2021-02-02 10:32 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: linuxppc-dev, Madhavan Srinivasan, Jiri Olsa, Jiri Olsa,
Kajol Jain
In-Reply-To: <dd8b772b-fa13-975b-be42-2b7bdf14b46d@linux.ibm.com>
[-- Attachment #1: Type: text/html, Size: 4876 bytes --]
^ permalink raw reply
* Re: [RFC PATCH 1/6] selftest/mremap_test: Update the test to handle pagesize other than 4K
From: Li Xinhai @ 2021-02-02 13:29 UTC (permalink / raw)
To: Aneesh Kumar K.V, linux-mm, akpm; +Cc: peterz, linuxppc-dev, joel, kaleshsingh
In-Reply-To: <20210202091116.196134-1-aneesh.kumar@linux.ibm.com>
what is the overall purpose of this patch set? maybe need a cover
letter?
On 2/2/21 5:11 PM, Aneesh Kumar K.V wrote:
> Instead of hardcoding 4K page size fetch it using sysconf(). For the performance
> measurements test still assume 2M and 1G are hugepage sizes.
>
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
> ---
> tools/testing/selftests/vm/mremap_test.c | 113 ++++++++++++-----------
> 1 file changed, 61 insertions(+), 52 deletions(-)
>
> diff --git a/tools/testing/selftests/vm/mremap_test.c b/tools/testing/selftests/vm/mremap_test.c
> index 9c391d016922..c9a5461eb786 100644
> --- a/tools/testing/selftests/vm/mremap_test.c
> +++ b/tools/testing/selftests/vm/mremap_test.c
> @@ -45,14 +45,15 @@ enum {
> _4MB = 4ULL << 20,
> _1GB = 1ULL << 30,
> _2GB = 2ULL << 30,
> - PTE = _4KB,
> PMD = _2MB,
> PUD = _1GB,
> };
>
> +#define PTE page_size
> +
> #define MAKE_TEST(source_align, destination_align, size, \
> overlaps, should_fail, test_name) \
> -{ \
> +(struct test){ \
> .name = test_name, \
> .config = { \
> .src_alignment = source_align, \
> @@ -252,12 +253,17 @@ static int parse_args(int argc, char **argv, unsigned int *threshold_mb,
> return 0;
> }
>
> +#define MAX_TEST 13
> +#define MAX_PERF_TEST 3
> int main(int argc, char **argv)
> {
> int failures = 0;
> int i, run_perf_tests;
> unsigned int threshold_mb = VALIDATION_DEFAULT_THRESHOLD;
> unsigned int pattern_seed;
> + struct test test_cases[MAX_TEST];
> + struct test perf_test_cases[MAX_PERF_TEST];
> + int page_size;
> time_t t;
>
> pattern_seed = (unsigned int) time(&t);
> @@ -268,56 +274,59 @@ int main(int argc, char **argv)
> ksft_print_msg("Test configs:\n\tthreshold_mb=%u\n\tpattern_seed=%u\n\n",
> threshold_mb, pattern_seed);
>
> - struct test test_cases[] = {
> - /* Expected mremap failures */
> - MAKE_TEST(_4KB, _4KB, _4KB, OVERLAPPING, EXPECT_FAILURE,
> - "mremap - Source and Destination Regions Overlapping"),
> - MAKE_TEST(_4KB, _1KB, _4KB, NON_OVERLAPPING, EXPECT_FAILURE,
> - "mremap - Destination Address Misaligned (1KB-aligned)"),
> - MAKE_TEST(_1KB, _4KB, _4KB, NON_OVERLAPPING, EXPECT_FAILURE,
> - "mremap - Source Address Misaligned (1KB-aligned)"),
> -
> - /* Src addr PTE aligned */
> - MAKE_TEST(PTE, PTE, _8KB, NON_OVERLAPPING, EXPECT_SUCCESS,
> - "8KB mremap - Source PTE-aligned, Destination PTE-aligned"),
> -
> - /* Src addr 1MB aligned */
> - MAKE_TEST(_1MB, PTE, _2MB, NON_OVERLAPPING, EXPECT_SUCCESS,
> - "2MB mremap - Source 1MB-aligned, Destination PTE-aligned"),
> - MAKE_TEST(_1MB, _1MB, _2MB, NON_OVERLAPPING, EXPECT_SUCCESS,
> - "2MB mremap - Source 1MB-aligned, Destination 1MB-aligned"),
> -
> - /* Src addr PMD aligned */
> - MAKE_TEST(PMD, PTE, _4MB, NON_OVERLAPPING, EXPECT_SUCCESS,
> - "4MB mremap - Source PMD-aligned, Destination PTE-aligned"),
> - MAKE_TEST(PMD, _1MB, _4MB, NON_OVERLAPPING, EXPECT_SUCCESS,
> - "4MB mremap - Source PMD-aligned, Destination 1MB-aligned"),
> - MAKE_TEST(PMD, PMD, _4MB, NON_OVERLAPPING, EXPECT_SUCCESS,
> - "4MB mremap - Source PMD-aligned, Destination PMD-aligned"),
> -
> - /* Src addr PUD aligned */
> - MAKE_TEST(PUD, PTE, _2GB, NON_OVERLAPPING, EXPECT_SUCCESS,
> - "2GB mremap - Source PUD-aligned, Destination PTE-aligned"),
> - MAKE_TEST(PUD, _1MB, _2GB, NON_OVERLAPPING, EXPECT_SUCCESS,
> - "2GB mremap - Source PUD-aligned, Destination 1MB-aligned"),
> - MAKE_TEST(PUD, PMD, _2GB, NON_OVERLAPPING, EXPECT_SUCCESS,
> - "2GB mremap - Source PUD-aligned, Destination PMD-aligned"),
> - MAKE_TEST(PUD, PUD, _2GB, NON_OVERLAPPING, EXPECT_SUCCESS,
> - "2GB mremap - Source PUD-aligned, Destination PUD-aligned"),
> - };
> -
> - struct test perf_test_cases[] = {
> - /*
> - * mremap 1GB region - Page table level aligned time
> - * comparison.
> - */
> - MAKE_TEST(PTE, PTE, _1GB, NON_OVERLAPPING, EXPECT_SUCCESS,
> - "1GB mremap - Source PTE-aligned, Destination PTE-aligned"),
> - MAKE_TEST(PMD, PMD, _1GB, NON_OVERLAPPING, EXPECT_SUCCESS,
> - "1GB mremap - Source PMD-aligned, Destination PMD-aligned"),
> - MAKE_TEST(PUD, PUD, _1GB, NON_OVERLAPPING, EXPECT_SUCCESS,
> - "1GB mremap - Source PUD-aligned, Destination PUD-aligned"),
> - };
> + page_size = sysconf(_SC_PAGESIZE);
> +
> + /* Expected mremap failures */
> + test_cases[0] = MAKE_TEST(page_size, page_size, page_size,
> + OVERLAPPING, EXPECT_FAILURE,
> + "mremap - Source and Destination Regions Overlapping");
> +
> + test_cases[1] = MAKE_TEST(page_size, page_size/4, page_size,
> + NON_OVERLAPPING, EXPECT_FAILURE,
> + "mremap - Destination Address Misaligned (1KB-aligned)");
> + test_cases[2] = MAKE_TEST(page_size/4, page_size, page_size,
> + NON_OVERLAPPING, EXPECT_FAILURE,
> + "mremap - Source Address Misaligned (1KB-aligned)");
> +
> + /* Src addr PTE aligned */
> + test_cases[3] = MAKE_TEST(PTE, PTE, PTE * 2,
> + NON_OVERLAPPING, EXPECT_SUCCESS,
> + "8KB mremap - Source PTE-aligned, Destination PTE-aligned");
> +
> + /* Src addr 1MB aligned */
> + test_cases[4] = MAKE_TEST(_1MB, PTE, _2MB, NON_OVERLAPPING, EXPECT_SUCCESS,
> + "2MB mremap - Source 1MB-aligned, Destination PTE-aligned");
> + test_cases[5] = MAKE_TEST(_1MB, _1MB, _2MB, NON_OVERLAPPING, EXPECT_SUCCESS,
> + "2MB mremap - Source 1MB-aligned, Destination 1MB-aligned");
> +
> + /* Src addr PMD aligned */
> + test_cases[6] = MAKE_TEST(PMD, PTE, _4MB, NON_OVERLAPPING, EXPECT_SUCCESS,
> + "4MB mremap - Source PMD-aligned, Destination PTE-aligned");
> + test_cases[7] = MAKE_TEST(PMD, _1MB, _4MB, NON_OVERLAPPING, EXPECT_SUCCESS,
> + "4MB mremap - Source PMD-aligned, Destination 1MB-aligned");
> + test_cases[8] = MAKE_TEST(PMD, PMD, _4MB, NON_OVERLAPPING, EXPECT_SUCCESS,
> + "4MB mremap - Source PMD-aligned, Destination PMD-aligned");
> +
> + /* Src addr PUD aligned */
> + test_cases[9] = MAKE_TEST(PUD, PTE, _2GB, NON_OVERLAPPING, EXPECT_SUCCESS,
> + "2GB mremap - Source PUD-aligned, Destination PTE-aligned");
> + test_cases[10] = MAKE_TEST(PUD, _1MB, _2GB, NON_OVERLAPPING, EXPECT_SUCCESS,
> + "2GB mremap - Source PUD-aligned, Destination 1MB-aligned");
> + test_cases[11] = MAKE_TEST(PUD, PMD, _2GB, NON_OVERLAPPING, EXPECT_SUCCESS,
> + "2GB mremap - Source PUD-aligned, Destination PMD-aligned");
> + test_cases[12] = MAKE_TEST(PUD, PUD, _2GB, NON_OVERLAPPING, EXPECT_SUCCESS,
> + "2GB mremap - Source PUD-aligned, Destination PUD-aligned");
> +
> + perf_test_cases[0] = MAKE_TEST(page_size, page_size, _1GB, NON_OVERLAPPING, EXPECT_SUCCESS,
> + "1GB mremap - Source PTE-aligned, Destination PTE-aligned");
> + /*
> + * mremap 1GB region - Page table level aligned time
> + * comparison.
> + */
> + perf_test_cases[1] = MAKE_TEST(PMD, PMD, _1GB, NON_OVERLAPPING, EXPECT_SUCCESS,
> + "1GB mremap - Source PMD-aligned, Destination PMD-aligned");
> + perf_test_cases[2] = MAKE_TEST(PUD, PUD, _1GB, NON_OVERLAPPING, EXPECT_SUCCESS,
> + "1GB mremap - Source PUD-aligned, Destination PUD-aligned");
>
> run_perf_tests = (threshold_mb == VALIDATION_NO_THRESHOLD) ||
> (threshold_mb * _1MB >= _1GB);
>
^ permalink raw reply
* [PATCH] arch: powerpc: kernel: Fix the spelling mismach to mismatch in head.44x.S
From: Bhaskar Chowdhury @ 2021-02-02 9:37 UTC (permalink / raw)
To: mpe, benh, paulus, akpm, rppt, linuxppc-dev, linux-kernel
Cc: rdunlap, Bhaskar Chowdhury
s/mismach/mismatch/
Signed-off-by: Bhaskar Chowdhury <unixbhaskar@gmail.com>
---
arch/powerpc/kernel/head_44x.S | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index 8e36718f3167..813fa305c33b 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -376,7 +376,7 @@ interrupt_base:
/* Load the next available TLB index */
lwz r13,tlb_44x_index@l(r10)
- bne 2f /* Bail if permission mismach */
+ bne 2f /* Bail if permission mismatch */
/* Increment, rollover, and store TLB index */
addi r13,r13,1
@@ -471,7 +471,7 @@ interrupt_base:
/* Load the next available TLB index */
lwz r13,tlb_44x_index@l(r10)
- bne 2f /* Bail if permission mismach */
+ bne 2f /* Bail if permission mismatch */
/* Increment, rollover, and store TLB index */
addi r13,r13,1
--
2.26.2
^ permalink raw reply related
* [powerpc:next-test 102/117] arch/powerpc/kernel/tau_6xx.c:103:1: error: no previous prototype for function 'DEFINE_INTERRUPT_HANDLER_ASYNC'
From: kernel test robot @ 2021-02-03 4:03 UTC (permalink / raw)
To: Nicholas Piggin; +Cc: clang-built-linux, kbuild-all, linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 2750 bytes --]
tree: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next-test
head: a4d002e384ba1909c1c03799603f00c5909d6097
commit: f779391282ff7a95222000321b41823d86cf9aa1 [102/117] powerpc: convert interrupt handlers to use wrappers
config: powerpc64-randconfig-r035-20210202 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 275c6af7d7f1ed63a03d05b4484413e447133269)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install powerpc64 cross compiling tool for clang build
# apt-get install binutils-powerpc64-linux-gnu
# https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/commit/?id=f779391282ff7a95222000321b41823d86cf9aa1
git remote add powerpc https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git
git fetch --no-tags powerpc next-test
git checkout f779391282ff7a95222000321b41823d86cf9aa1
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=powerpc64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
>> arch/powerpc/kernel/tau_6xx.c:103:1: error: no previous prototype for function 'DEFINE_INTERRUPT_HANDLER_ASYNC' [-Werror,-Wmissing-prototypes]
DEFINE_INTERRUPT_HANDLER_ASYNC(TAUException)
^
arch/powerpc/kernel/tau_6xx.c:103:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
DEFINE_INTERRUPT_HANDLER_ASYNC(TAUException)
^
static
arch/powerpc/kernel/tau_6xx.c:103:31: error: this old-style function definition is not preceded by a prototype [-Werror,-Wstrict-prototypes]
DEFINE_INTERRUPT_HANDLER_ASYNC(TAUException)
^
arch/powerpc/kernel/tau_6xx.c:113:1: error: non-void function does not return a value [-Werror,-Wreturn-type]
}
^
3 errors generated.
vim +/DEFINE_INTERRUPT_HANDLER_ASYNC +103 arch/powerpc/kernel/tau_6xx.c
96
97 #ifdef CONFIG_TAU_INT
98 /*
99 * TAU interrupts - called when we have a thermal assist unit interrupt
100 * with interrupts disabled
101 */
102
> 103 DEFINE_INTERRUPT_HANDLER_ASYNC(TAUException)
104 {
105 int cpu = smp_processor_id();
106
107 irq_enter();
108 tau[cpu].interrupts++;
109
110 TAUupdate(cpu);
111
112 irq_exit();
113 }
114 #endif /* CONFIG_TAU_INT */
115
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 33373 bytes --]
^ permalink raw reply
* [PATCH 1/3] powerpc/mm: Enable compound page check for both THP and HugeTLB
From: Aneesh Kumar K.V @ 2021-02-03 4:58 UTC (permalink / raw)
To: linuxppc-dev, mpe; +Cc: Aneesh Kumar K.V
THP config results in compound pages. Make sure the kernel enables
the PageCompound() check with CONFIG_HUGETLB_PAGE disabled and
CONFIG_TRANSPARENT_HUGEPAGE enabled.
This makes sure we correctly flush the icache with THP pages.
flush_dcache_icache_page only matter for platforms that don't support
COHERENT_ICACHE.
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
arch/powerpc/include/asm/hugetlb.h | 2 --
arch/powerpc/mm/hugetlbpage.c | 18 ------------------
arch/powerpc/mm/mem.c | 28 ++++++++++++++++++++++------
3 files changed, 22 insertions(+), 26 deletions(-)
diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
index 013165e62618..f18c543bc01d 100644
--- a/arch/powerpc/include/asm/hugetlb.h
+++ b/arch/powerpc/include/asm/hugetlb.h
@@ -17,8 +17,6 @@ extern bool hugetlb_disabled;
void hugetlbpage_init_default(void);
-void flush_dcache_icache_hugepage(struct page *page);
-
int slice_is_hugepage_only_range(struct mm_struct *mm, unsigned long addr,
unsigned long len);
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 8b3cc4d688e8..7bdcb93eebae 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -663,24 +663,6 @@ static int __init hugetlbpage_init(void)
arch_initcall(hugetlbpage_init);
-void flush_dcache_icache_hugepage(struct page *page)
-{
- int i;
- void *start;
-
- BUG_ON(!PageCompound(page));
-
- for (i = 0; i < compound_nr(page); i++) {
- if (!PageHighMem(page)) {
- __flush_dcache_icache(page_address(page+i));
- } else {
- start = kmap_atomic(page+i);
- __flush_dcache_icache(start);
- kunmap_atomic(start);
- }
- }
-}
-
void __init gigantic_hugetlb_cma_reserve(void)
{
unsigned long order = 0;
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index afab328d0887..ed64ca80d5fd 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -494,14 +494,30 @@ void flush_dcache_page(struct page *page)
}
EXPORT_SYMBOL(flush_dcache_page);
-void flush_dcache_icache_page(struct page *page)
+static void flush_dcache_icache_hugepage(struct page *page)
{
-#ifdef CONFIG_HUGETLB_PAGE
- if (PageCompound(page)) {
- flush_dcache_icache_hugepage(page);
- return;
+ int i;
+ void *start;
+
+ BUG_ON(!PageCompound(page));
+
+ for (i = 0; i < compound_nr(page); i++) {
+ if (!PageHighMem(page)) {
+ __flush_dcache_icache(page_address(page+i));
+ } else {
+ start = kmap_atomic(page+i);
+ __flush_dcache_icache(start);
+ kunmap_atomic(start);
+ }
}
-#endif
+}
+
+void flush_dcache_icache_page(struct page *page)
+{
+
+ if (PageCompound(page))
+ return flush_dcache_icache_hugepage(page);
+
#if defined(CONFIG_PPC_8xx) || defined(CONFIG_PPC64)
/* On 8xx there is no need to kmap since highmem is not supported */
__flush_dcache_icache(page_address(page));
--
2.29.2
^ permalink raw reply related
* [PATCH 2/3] powerpc/mm: Add PG_dcache_clean to indicate dcache clean state
From: Aneesh Kumar K.V @ 2021-02-03 4:58 UTC (permalink / raw)
To: linuxppc-dev, mpe; +Cc: Aneesh Kumar K.V
In-Reply-To: <20210203045812.234439-1-aneesh.kumar@linux.ibm.com>
This just add a better name for PG_arch_1. No functional change in this patch.
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
arch/powerpc/include/asm/cacheflush.h | 6 ++++++
arch/powerpc/include/asm/kvm_ppc.h | 4 ++--
arch/powerpc/mm/book3s64/hash_utils.c | 4 ++--
arch/powerpc/mm/mem.c | 4 ++--
arch/powerpc/mm/pgtable.c | 14 +++++++-------
5 files changed, 19 insertions(+), 13 deletions(-)
diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h
index 138e46d8c04e..f63495109f63 100644
--- a/arch/powerpc/include/asm/cacheflush.h
+++ b/arch/powerpc/include/asm/cacheflush.h
@@ -8,6 +8,12 @@
#include <asm/cputable.h>
#include <asm/cpu_has_feature.h>
+/*
+ * This flag is used to indicate that the page pointed to by a pte is clean
+ * and does not require cleaning before returning it to the user.
+ */
+#define PG_dcache_clean PG_arch_1
+
#ifdef CONFIG_PPC_BOOK3S_64
/*
* Book3s has no ptesync after setting a pte, so without this ptesync it's
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 0a056c64c317..c90d4b128b66 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -881,9 +881,9 @@ static inline void kvmppc_mmu_flush_icache(kvm_pfn_t pfn)
/* Clear i-cache for new pages */
page = pfn_to_page(pfn);
- if (!test_bit(PG_arch_1, &page->flags)) {
+ if (!test_bit(PG_dcache_clean, &page->flags)) {
flush_dcache_icache_page(page);
- set_bit(PG_arch_1, &page->flags);
+ set_bit(PG_dcache_clean, &page->flags);
}
}
diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c
index 73b06adb6eeb..5358c397f6c7 100644
--- a/arch/powerpc/mm/book3s64/hash_utils.c
+++ b/arch/powerpc/mm/book3s64/hash_utils.c
@@ -1143,10 +1143,10 @@ unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap)
page = pte_page(pte);
/* page is dirty */
- if (!test_bit(PG_arch_1, &page->flags) && !PageReserved(page)) {
+ if (!test_bit(PG_dcache_clean, &page->flags) && !PageReserved(page)) {
if (trap == 0x400) {
flush_dcache_icache_page(page);
- set_bit(PG_arch_1, &page->flags);
+ set_bit(PG_dcache_clean, &page->flags);
} else
pp |= HPTE_R_N;
}
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index ed64ca80d5fd..883e67d37bbc 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -489,8 +489,8 @@ void flush_dcache_page(struct page *page)
if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
return;
/* avoid an atomic op if possible */
- if (test_bit(PG_arch_1, &page->flags))
- clear_bit(PG_arch_1, &page->flags);
+ if (test_bit(PG_dcache_clean, &page->flags))
+ clear_bit(PG_dcache_clean, &page->flags);
}
EXPORT_SYMBOL(flush_dcache_page);
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index 15555c95cebc..7d997caccfa5 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -81,9 +81,9 @@ static pte_t set_pte_filter_hash(pte_t pte)
struct page *pg = maybe_pte_to_page(pte);
if (!pg)
return pte;
- if (!test_bit(PG_arch_1, &pg->flags)) {
+ if (!test_bit(PG_dcache_clean, &pg->flags)) {
flush_dcache_icache_page(pg);
- set_bit(PG_arch_1, &pg->flags);
+ set_bit(PG_dcache_clean, &pg->flags);
}
}
return pte;
@@ -116,13 +116,13 @@ static inline pte_t set_pte_filter(pte_t pte)
return pte;
/* If the page clean, we move on */
- if (test_bit(PG_arch_1, &pg->flags))
+ if (test_bit(PG_dcache_clean, &pg->flags))
return pte;
/* If it's an exec fault, we flush the cache and make it clean */
if (is_exec_fault()) {
flush_dcache_icache_page(pg);
- set_bit(PG_arch_1, &pg->flags);
+ set_bit(PG_dcache_clean, &pg->flags);
return pte;
}
@@ -161,12 +161,12 @@ static pte_t set_access_flags_filter(pte_t pte, struct vm_area_struct *vma,
goto bail;
/* If the page is already clean, we move on */
- if (test_bit(PG_arch_1, &pg->flags))
+ if (test_bit(PG_dcache_clean, &pg->flags))
goto bail;
- /* Clean the page and set PG_arch_1 */
+ /* Clean the page and set PG_dcache_clean */
flush_dcache_icache_page(pg);
- set_bit(PG_arch_1, &pg->flags);
+ set_bit(PG_dcache_clean, &pg->flags);
bail:
return pte_mkexec(pte);
--
2.29.2
^ permalink raw reply related
* [PATCH 3/3] powerpc/mm: Remove dcache flush from memory remove.
From: Aneesh Kumar K.V @ 2021-02-03 4:58 UTC (permalink / raw)
To: linuxppc-dev, mpe; +Cc: Aneesh Kumar K.V
In-Reply-To: <20210203045812.234439-1-aneesh.kumar@linux.ibm.com>
We added dcache flush on memory add/remove in
commit fb5924fddf9e ("powerpc/mm: Flush cache on memory hot(un)plug")
to handle crashes on GPU hotplug. Instead of adding dcache flush in
generic memory add/remove routine which is used even for regular
memory, we should handle these devices specific flush in the device
driver code.
memtrace did handle this in the driver and that was removed by
commit 7fd6641de28f ("powerpc/powernv/memtrace: Let the arch
hotunplug code flush cache"). This patch reverts that commit.
The dcache flush in memory add was removed by
Fixes: ea458effa88e ("powerpc: Don't flush caches when adding memory")
which I don't think is correct. The reason why we require dcache flush
in memtrace is to make sure we don't have a dirty cache when we remap
a pfn to cache inhibited. We should do that when the memtrace module
removes the memory and make the pfn available for HTM traces to map it
as cache inhibited.
The other device mentioned in
commit fb5924fddf9e ("powerpc/mm: Flush cache on memory hot(un)plug") is
nvlink device with coherent memory. The support for that was removed in
commit 3182215dd0b2 ("powerpc/powernv/npu: Remove NPU DMA ops")
and commit 25b2995a35b6 ("mm: remove MEMORY_DEVICE_PUBLIC support")
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
arch/powerpc/mm/mem.c | 22 -----------------
arch/powerpc/platforms/powernv/memtrace.c | 29 +++++++++++++++++++++++
2 files changed, 29 insertions(+), 22 deletions(-)
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 883e67d37bbc..4e8ce6d85232 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -91,27 +91,6 @@ int __weak remove_section_mapping(unsigned long start, unsigned long end)
return -ENODEV;
}
-#define FLUSH_CHUNK_SIZE SZ_1G
-/**
- * flush_dcache_range_chunked(): Write any modified data cache blocks out to
- * memory and invalidate them, in chunks of up to FLUSH_CHUNK_SIZE
- * Does not invalidate the corresponding instruction cache blocks.
- *
- * @start: the start address
- * @stop: the stop address (exclusive)
- * @chunk: the max size of the chunks
- */
-static void flush_dcache_range_chunked(unsigned long start, unsigned long stop,
- unsigned long chunk)
-{
- unsigned long i;
-
- for (i = start; i < stop; i += chunk) {
- flush_dcache_range(i, min(stop, i + chunk));
- cond_resched();
- }
-}
-
int __ref arch_create_linear_mapping(int nid, u64 start, u64 size,
struct mhp_params *params)
{
@@ -136,7 +115,6 @@ void __ref arch_remove_linear_mapping(u64 start, u64 size)
/* Remove htab bolted mappings for this section of memory */
start = (unsigned long)__va(start);
- flush_dcache_range_chunked(start, start + size, FLUSH_CHUNK_SIZE);
mutex_lock(&linear_mapping_mutex);
ret = remove_section_mapping(start, start + size);
diff --git a/arch/powerpc/platforms/powernv/memtrace.c b/arch/powerpc/platforms/powernv/memtrace.c
index 5fc9408bb0b3..019669eb21d2 100644
--- a/arch/powerpc/platforms/powernv/memtrace.c
+++ b/arch/powerpc/platforms/powernv/memtrace.c
@@ -19,6 +19,7 @@
#include <linux/numa.h>
#include <asm/machdep.h>
#include <asm/debugfs.h>
+#include <asm/cacheflush.h>
/* This enables us to keep track of the memory removed from each node. */
struct memtrace_entry {
@@ -51,6 +52,27 @@ static const struct file_operations memtrace_fops = {
.open = simple_open,
};
+#define FLUSH_CHUNK_SIZE SZ_1G
+/**
+ * flush_dcache_range_chunked(): Write any modified data cache blocks out to
+ * memory and invalidate them, in chunks of up to FLUSH_CHUNK_SIZE
+ * Does not invalidate the corresponding instruction cache blocks.
+ *
+ * @start: the start address
+ * @stop: the stop address (exclusive)
+ * @chunk: the max size of the chunks
+ */
+static void flush_dcache_range_chunked(unsigned long start, unsigned long stop,
+ unsigned long chunk)
+{
+ unsigned long i;
+
+ for (i = start; i < stop; i += chunk) {
+ flush_dcache_range(i, min(stop, i + chunk));
+ cond_resched();
+ }
+}
+
static void memtrace_clear_range(unsigned long start_pfn,
unsigned long nr_pages)
{
@@ -62,6 +84,13 @@ static void memtrace_clear_range(unsigned long start_pfn,
cond_resched();
clear_page(__va(PFN_PHYS(pfn)));
}
+ /*
+ * Before we go ahead and use this range as cache inhibited range
+ * flush the cache.
+ */
+ flush_dcache_range_chunked(PFN_PHYS(start_pfn),
+ PFN_PHYS(start_pfn + nr_pages),
+ FLUSH_CHUNK_SIZE);
}
static u64 memtrace_alloc_node(u32 nid, u64 size)
--
2.29.2
^ permalink raw reply related
* [PATCH 1/2] powerpc/64s: Fix pte update for kernel memory on radix
From: Jordan Niethe @ 2021-02-03 6:18 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Jordan Niethe, npiggin, cmr
The recommended sequence for updating a PTE from ISA Book III 6.10
Translation Update Synchronization Requirements is:
*ptep = pte
eieio
tlbsync
ptesync
This needs to be done to order the update of the pte with subsequent
accesses otherwise a spurious fault may be raised.
radix__set_pte_at() does not do this for performance gains. For
non-kernel memory this is not an issue as any faults of this kind are
corrected by the page fault handler. For kernel memory these faults are
not handled. The current solution is that there is a ptesync in
flush_cache_vmap() which should be called when mapping from the vmalloc
region.
However, map_kernel_page() does not call flush_cache_vmap(). This is
troublesome in particular for code patching with Strict RWX on radix. In
do_patch_instruction() the page frame that contains the instruction to
be patched is mapped and then immediately patched. With no ordering or
synchronization between setting up the pte and writing to the page it is
possible for faults.
As the code patching is done using __put_user_asm_goto() the resulting
fault is obscured - but using a normal store instead it can be seen:
[ 418.498768][ T757] BUG: Unable to handle kernel data access on write at 0xc008000008f24a3c
[ 418.498790][ T757] Faulting instruction address: 0xc00000000008bd74
[ 418.498805][ T757] Oops: Kernel access of bad area, sig: 11 [#1]
[ 418.498828][ T757] LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA PowerNV
[ 418.498843][ T757] Modules linked in: nop_module(PO+) [last unloaded: nop_module]
[ 418.498872][ T757] CPU: 4 PID: 757 Comm: sh Tainted: P O 5.10.0-rc5-01361-ge3c1b78c8440-dirty #43
[ 418.498936][ T757] NIP: c00000000008bd74 LR: c00000000008bd50 CTR: c000000000025810
[ 418.498979][ T757] REGS: c000000016f634a0 TRAP: 0300 Tainted: P O (5.10.0-rc5-01361-ge3c1b78c8440-dirty)
[ 418.499033][ T757] MSR: 9000000000009033 <SF,HV,EE,ME,IR,DR,RI,LE> CR: 44002884 XER: 00000000
[ 418.499084][ T757] CFAR: c00000000007c68c DAR: c008000008f24a3c DSISR: 42000000 IRQMASK: 1
This results in the kind of issue reported here:
https://lore.kernel.org/linuxppc-dev/15AC5B0E-A221-4B8C-9039-FA96B8EF7C88@lca.pw/
Chris Riedl suggested a reliable way to reproduce the issue:
$ mount -t debugfs none /sys/kernel/debug
$ (while true; do echo function > /sys/kernel/debug/tracing/current_tracer ; echo nop > /sys/kernel/debug/tracing/current_tracer ; done)&
Turning ftrace on and off does a large amount of code patching which in
usually less then 5min will crash giving a trace like:
[ 146.668988][ T809] ftrace-powerpc: (____ptrval____): replaced (4b473b11) != old (60000000)
[ 146.668995][ T809] ------------[ ftrace bug ]------------
[ 146.669031][ T809] ftrace failed to modify
[ 146.669039][ T809] [<c000000000bf8e5c>] napi_busy_loop+0xc/0x390
[ 146.669045][ T809] actual: 11:3b:47:4b
[ 146.669070][ T809] Setting ftrace call site to call ftrace function
[ 146.669075][ T809] ftrace record flags: 80000001
[ 146.669081][ T809] (1)
[ 146.669081][ T809] expected tramp: c00000000006c96c
[ 146.669096][ T809] ------------[ cut here ]------------
[ 146.669104][ T809] WARNING: CPU: 4 PID: 809 at kernel/trace/ftrace.c:2065 ftrace_bug+0x28c/0x2e8
[ 146.669109][ T809] Modules linked in: nop_module(PO-) [last unloaded: nop_module]
[ 146.669130][ T809] CPU: 4 PID: 809 Comm: sh Tainted: P O 5.10.0-rc5-01360-gf878ccaf250a #1
[ 146.669136][ T809] NIP: c00000000024f334 LR: c00000000024f330 CTR: c0000000001a5af0
[ 146.669142][ T809] REGS: c000000004c8b760 TRAP: 0700 Tainted: P O (5.10.0-rc5-01360-gf878ccaf250a)
[ 146.669147][ T809] MSR: 900000000282b033 <SF,HV,VEC,VSX,EE,FP,ME,IR,DR,RI,LE> CR: 28008848 XER: 20040000
[ 146.669208][ T809] CFAR: c0000000001a9c98 IRQMASK: 0
[ 146.669208][ T809] GPR00: c00000000024f330 c000000004c8b9f0 c000000002770600 0000000000000022
[ 146.669208][ T809] GPR04: 00000000ffff7fff c000000004c8b6d0 0000000000000027 c0000007fe9bcdd8
[ 146.669208][ T809] GPR08: 0000000000000023 ffffffffffffffd8 0000000000000027 c000000002613118
[ 146.669208][ T809] GPR12: 0000000000008000 c0000007fffdca00 0000000000000000 0000000000000000
[ 146.669208][ T809] GPR16: 0000000023ec37c5 0000000000000000 0000000000000000 0000000000000008
[ 146.669208][ T809] GPR20: c000000004c8bc90 c0000000027a2d20 c000000004c8bcd0 c000000002612fe8
[ 146.669208][ T809] GPR24: 0000000000000038 0000000000000030 0000000000000028 0000000000000020
[ 146.669208][ T809] GPR28: c000000000ff1b68 c000000000bf8e5c c00000000312f700 c000000000fbb9b0
[ 146.669384][ T809] NIP [c00000000024f334] ftrace_bug+0x28c/0x2e8
[ 146.669391][ T809] LR [c00000000024f330] ftrace_bug+0x288/0x2e8
[ 146.669396][ T809] Call Trace:
[ 146.669403][ T809] [c000000004c8b9f0] [c00000000024f330] ftrace_bug+0x288/0x2e8 (unreliable)
[ 146.669418][ T809] [c000000004c8ba80] [c000000000248778] ftrace_modify_all_code+0x168/0x210
[ 146.669429][ T809] [c000000004c8bab0] [c00000000006c528] arch_ftrace_update_code+0x18/0x30
[ 146.669440][ T809] [c000000004c8bad0] [c000000000248954] ftrace_run_update_code+0x44/0xc0
[ 146.669451][ T809] [c000000004c8bb00] [c00000000024dc88] ftrace_startup+0xf8/0x1c0
[ 146.669461][ T809] [c000000004c8bb40] [c00000000024dd9c] register_ftrace_function+0x4c/0xc0
[ 146.669472][ T809] [c000000004c8bb70] [c00000000026e750] function_trace_init+0x80/0xb0
[ 146.669484][ T809] [c000000004c8bba0] [c000000000266b84] tracing_set_tracer+0x2a4/0x4f0
[ 146.669495][ T809] [c000000004c8bc70] [c000000000266ea4] tracing_set_trace_write+0xd4/0x130
[ 146.669506][ T809] [c000000004c8bd20] [c000000000422790] vfs_write+0xf0/0x330
[ 146.669518][ T809] [c000000004c8bd70] [c000000000422bb4] ksys_write+0x84/0x140
[ 146.669529][ T809] [c000000004c8bdc0] [c00000000003499c] system_call_exception+0x14c/0x230
[ 146.669540][ T809] [c000000004c8be20] [c00000000000d860] system_call_common+0xf0/0x27c
[ 146.669549][ T809] Instruction dump:
[ 146.669558][ T809] 48000014 3c62fe88 38631718 4bf5a941 60000000 7fc3f378 4bff877d 7c641b78
[ 146.669598][ T809] 3c62fe88 38631730 4bf5a925 60000000 <0fe00000> 38210090 3d22fd90 39000001
[ 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 <jniethe5@gmail.com>
---
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(&init_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(&init_mm, ea, ptep, pfn_pte(pfn, flags));
- smp_wmb();
+ asm volatile("eieio; tlbsync; ptesync": : :"memory");
return 0;
}
--
2.25.1
^ permalink raw reply related
* [PATCH 2/2] Revert "powerpc/64s: Disable STRICT_KERNEL_RWX"
From: Jordan Niethe @ 2021-02-03 6:18 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Jordan Niethe, npiggin, cmr
In-Reply-To: <20210203061829.879868-1-jniethe5@gmail.com>
This reverts commit 8659a0e0efdd975c73355dbc033f79ba3b31e82c.
Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
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
^ permalink raw reply related
* [PATCH v2 1/3] powerpc: sstep: Fix load and update emulation
From: Sandipan Das @ 2021-02-03 6:38 UTC (permalink / raw)
To: mpe
Cc: ravi.bangoria, ananth, jniethe5, paulus, naveen.n.rao,
linuxppc-dev, dja
The Power ISA says that the fixed-point load and update
instructions must neither use R0 for the base address (RA)
nor have the destination (RT) and the base address (RA) as
the same register. In these cases, the instruction is
invalid. This applies to the following instructions.
* Load Byte and Zero with Update (lbzu)
* Load Byte and Zero with Update Indexed (lbzux)
* Load Halfword and Zero with Update (lhzu)
* Load Halfword and Zero with Update Indexed (lhzux)
* Load Halfword Algebraic with Update (lhau)
* Load Halfword Algebraic with Update Indexed (lhaux)
* Load Word and Zero with Update (lwzu)
* Load Word and Zero with Update Indexed (lwzux)
* Load Word Algebraic with Update Indexed (lwaux)
* Load Doubleword with Update (ldu)
* Load Doubleword with Update Indexed (ldux)
However, the following behaviour is observed using some
invalid opcodes where RA = RT.
An userspace program using an invalid instruction word like
0xe9ce0001, i.e. "ldu r14, 0(r14)", runs and exits without
getting terminated abruptly. The instruction performs the
load operation but does not write the effective address to
the base address register. Attaching an uprobe at that
instruction's address results in emulation which writes the
effective address to the base register. Thus, the final value
of the base address register is different.
To remove any inconsistencies, this adds an additional check
for the aforementioned instructions to make sure that they
are treated as unknown by the emulation infrastructure when
RA = 0 or RA = RT. The kernel will then fallback to executing
the instruction on hardware.
Fixes: 0016a4cf5582 ("powerpc: Emulate most Book I instructions in emulate_step()")
Reviewed-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
Signed-off-by: Sandipan Das <sandipan@linux.ibm.com>
---
Previous versions can be found at:
v1: https://lore.kernel.org/linuxppc-dev/20201119054139.244083-1-sandipan@linux.ibm.com/
Changes in v2:
- Jump to unknown_opcode instead of returning -1 for invalid
instruction forms.
---
arch/powerpc/lib/sstep.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index e96cff845ef7..db824fec6165 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -2232,11 +2232,15 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
case 23: /* lwzx */
case 55: /* lwzux */
+ if (u && (ra == 0 || ra == rd))
+ goto unknown_opcode;
op->type = MKOP(LOAD, u, 4);
break;
case 87: /* lbzx */
case 119: /* lbzux */
+ if (u && (ra == 0 || ra == rd))
+ goto unknown_opcode;
op->type = MKOP(LOAD, u, 1);
break;
@@ -2290,6 +2294,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
#ifdef __powerpc64__
case 21: /* ldx */
case 53: /* ldux */
+ if (u && (ra == 0 || ra == rd))
+ goto unknown_opcode;
op->type = MKOP(LOAD, u, 8);
break;
@@ -2311,18 +2317,24 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
case 279: /* lhzx */
case 311: /* lhzux */
+ if (u && (ra == 0 || ra == rd))
+ goto unknown_opcode;
op->type = MKOP(LOAD, u, 2);
break;
#ifdef __powerpc64__
case 341: /* lwax */
case 373: /* lwaux */
+ if (u && (ra == 0 || ra == rd))
+ goto unknown_opcode;
op->type = MKOP(LOAD, SIGNEXT | u, 4);
break;
#endif
case 343: /* lhax */
case 375: /* lhaux */
+ if (u && (ra == 0 || ra == rd))
+ goto unknown_opcode;
op->type = MKOP(LOAD, SIGNEXT | u, 2);
break;
@@ -2656,12 +2668,16 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
case 32: /* lwz */
case 33: /* lwzu */
+ if (u && (ra == 0 || ra == rd))
+ goto unknown_opcode;
op->type = MKOP(LOAD, u, 4);
op->ea = dform_ea(word, regs);
break;
case 34: /* lbz */
case 35: /* lbzu */
+ if (u && (ra == 0 || ra == rd))
+ goto unknown_opcode;
op->type = MKOP(LOAD, u, 1);
op->ea = dform_ea(word, regs);
break;
@@ -2680,12 +2696,16 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
case 40: /* lhz */
case 41: /* lhzu */
+ if (u && (ra == 0 || ra == rd))
+ goto unknown_opcode;
op->type = MKOP(LOAD, u, 2);
op->ea = dform_ea(word, regs);
break;
case 42: /* lha */
case 43: /* lhau */
+ if (u && (ra == 0 || ra == rd))
+ goto unknown_opcode;
op->type = MKOP(LOAD, SIGNEXT | u, 2);
op->ea = dform_ea(word, regs);
break;
@@ -2779,6 +2799,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
op->type = MKOP(LOAD, 0, 8);
break;
case 1: /* ldu */
+ if (ra == 0 || ra == rd)
+ goto unknown_opcode;
op->type = MKOP(LOAD, UPDATE, 8);
break;
case 2: /* lwa */
--
2.25.1
^ permalink raw reply related
* [PATCH v2 2/3] powerpc: sstep: Fix store and update emulation
From: Sandipan Das @ 2021-02-03 6:38 UTC (permalink / raw)
To: mpe
Cc: ravi.bangoria, ananth, jniethe5, paulus, naveen.n.rao,
linuxppc-dev, dja
In-Reply-To: <20210203063841.431063-1-sandipan@linux.ibm.com>
The Power ISA says that the fixed-point store and update
instructions must not use R0 for the base address (RA).
In this case, the instruction is invalid. This applies
to the following instructions.
* Store Byte with Update (stbu)
* Store Byte with Update Indexed (stbux)
* Store Halfword with Update (sthu)
* Store Halfword with Update Indexed (sthux)
* Store Word with Update (stwu)
* Store Word with Update Indexed (stwux)
* Store Doubleword with Update (stdu)
* Store Doubleword with Update Indexed (stdux)
To remove any inconsistencies, this adds an additional check
for the aforementioned instructions to make sure that they
are treated as unknown by the emulation infrastructure when
RA = 0. The kernel will then fallback to executing the
instruction on hardware.
Fixes: 0016a4cf5582 ("powerpc: Emulate most Book I instructions in emulate_step()")
Reviewed-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
Signed-off-by: Sandipan Das <sandipan@linux.ibm.com>
---
Previous versions can be found at:
v1: https://lore.kernel.org/linuxppc-dev/20201119054139.244083-2-sandipan@linux.ibm.com/
Changes in v2:
- Jump to unknown_opcode instead of returning -1 for invalid
instruction forms.
---
arch/powerpc/lib/sstep.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index db824fec6165..230d1ae77ef5 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -2301,17 +2301,23 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
case 149: /* stdx */
case 181: /* stdux */
+ if (u && ra == 0)
+ goto unknown_opcode;
op->type = MKOP(STORE, u, 8);
break;
#endif
case 151: /* stwx */
case 183: /* stwux */
+ if (u && ra == 0)
+ goto unknown_opcode;
op->type = MKOP(STORE, u, 4);
break;
case 215: /* stbx */
case 247: /* stbux */
+ if (u && ra == 0)
+ goto unknown_opcode;
op->type = MKOP(STORE, u, 1);
break;
@@ -2340,6 +2346,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
case 407: /* sthx */
case 439: /* sthux */
+ if (u && ra == 0)
+ goto unknown_opcode;
op->type = MKOP(STORE, u, 2);
break;
@@ -2684,12 +2692,16 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
case 36: /* stw */
case 37: /* stwu */
+ if (u && ra == 0)
+ goto unknown_opcode;
op->type = MKOP(STORE, u, 4);
op->ea = dform_ea(word, regs);
break;
case 38: /* stb */
case 39: /* stbu */
+ if (u && ra == 0)
+ goto unknown_opcode;
op->type = MKOP(STORE, u, 1);
op->ea = dform_ea(word, regs);
break;
@@ -2712,6 +2724,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
case 44: /* sth */
case 45: /* sthu */
+ if (u && ra == 0)
+ goto unknown_opcode;
op->type = MKOP(STORE, u, 2);
op->ea = dform_ea(word, regs);
break;
@@ -2890,6 +2904,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
op->type = MKOP(STORE, 0, 8);
break;
case 1: /* stdu */
+ if (ra == 0)
+ goto unknown_opcode;
op->type = MKOP(STORE, UPDATE, 8);
break;
case 2: /* stq */
--
2.25.1
^ permalink raw reply related
* [PATCH v2 3/3] powerpc: sstep: Fix darn emulation
From: Sandipan Das @ 2021-02-03 6:38 UTC (permalink / raw)
To: mpe
Cc: ravi.bangoria, ananth, jniethe5, paulus, naveen.n.rao,
linuxppc-dev, dja
In-Reply-To: <20210203063841.431063-1-sandipan@linux.ibm.com>
Commit 8813ff49607e ("powerpc/sstep: Check instruction
validity against ISA version before emulation") introduced
a proper way to skip unknown instructions. This makes sure
that the same is used for the darn instruction when the
range selection bits have a reserved value.
Fixes: a23987ef267a ("powerpc: sstep: Add support for darn instruction")
Signed-off-by: Sandipan Das <sandipan@linux.ibm.com>
---
arch/powerpc/lib/sstep.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 230d1ae77ef5..9ea6822f4c55 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -1916,7 +1916,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
goto compute_done;
}
- return -1;
+ goto unknown_opcode;
#ifdef __powerpc64__
case 777: /* modsd */
if (!cpu_has_feature(CPU_FTR_ARCH_300))
--
2.25.1
^ permalink raw reply related
* [PATCH] scsi: ibmvfc: convert sysfs sprintf/snprintf family to sysfs_emit
From: Jiapeng Chong @ 2021-02-03 6:27 UTC (permalink / raw)
To: tyreld
Cc: Jiapeng Chong, martin.petersen, linux-scsi, jejb, linux-kernel,
paulus, linuxppc-dev
Fix the following coccicheck warning:
./drivers/scsi/ibmvscsi/ibmvfc.c: WARNING: use scnprintf or
sprintf.
Reported-by: Abaci Robot<abaci@linux.alibaba.com>
Signed-off-by: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
---
drivers/scsi/ibmvscsi/ibmvfc.c | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 65f168c..99f5575 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -3038,8 +3038,7 @@ static ssize_t ibmvfc_show_host_partition_name(struct device *dev,
struct Scsi_Host *shost = class_to_shost(dev);
struct ibmvfc_host *vhost = shost_priv(shost);
- return snprintf(buf, PAGE_SIZE, "%s\n",
- vhost->login_buf->resp.partition_name);
+ return sysfs_emit(buf, "%s\n", vhost->login_buf->resp.partition_name);
}
static ssize_t ibmvfc_show_host_device_name(struct device *dev,
@@ -3048,8 +3047,7 @@ static ssize_t ibmvfc_show_host_device_name(struct device *dev,
struct Scsi_Host *shost = class_to_shost(dev);
struct ibmvfc_host *vhost = shost_priv(shost);
- return snprintf(buf, PAGE_SIZE, "%s\n",
- vhost->login_buf->resp.device_name);
+ return sysfs_emit(buf, "%s\n", vhost->login_buf->resp.device_name);
}
static ssize_t ibmvfc_show_host_loc_code(struct device *dev,
@@ -3058,8 +3056,7 @@ static ssize_t ibmvfc_show_host_loc_code(struct device *dev,
struct Scsi_Host *shost = class_to_shost(dev);
struct ibmvfc_host *vhost = shost_priv(shost);
- return snprintf(buf, PAGE_SIZE, "%s\n",
- vhost->login_buf->resp.port_loc_code);
+ return sysfs_emit(buf, "%s\n", vhost->login_buf->resp.port_loc_code);
}
static ssize_t ibmvfc_show_host_drc_name(struct device *dev,
@@ -3068,8 +3065,7 @@ static ssize_t ibmvfc_show_host_drc_name(struct device *dev,
struct Scsi_Host *shost = class_to_shost(dev);
struct ibmvfc_host *vhost = shost_priv(shost);
- return snprintf(buf, PAGE_SIZE, "%s\n",
- vhost->login_buf->resp.drc_name);
+ return sysfs_emit(buf, "%s\n", vhost->login_buf->resp.drc_name);
}
static ssize_t ibmvfc_show_host_npiv_version(struct device *dev,
@@ -3077,7 +3073,7 @@ static ssize_t ibmvfc_show_host_npiv_version(struct device *dev,
{
struct Scsi_Host *shost = class_to_shost(dev);
struct ibmvfc_host *vhost = shost_priv(shost);
- return snprintf(buf, PAGE_SIZE, "%d\n", be32_to_cpu(vhost->login_buf->resp.version));
+ return sysfs_emit(buf, "%d\n", be32_to_cpu(vhost->login_buf->resp.version));
}
static ssize_t ibmvfc_show_host_capabilities(struct device *dev,
@@ -3085,7 +3081,7 @@ static ssize_t ibmvfc_show_host_capabilities(struct device *dev,
{
struct Scsi_Host *shost = class_to_shost(dev);
struct ibmvfc_host *vhost = shost_priv(shost);
- return snprintf(buf, PAGE_SIZE, "%llx\n", be64_to_cpu(vhost->login_buf->resp.capabilities));
+ return sysfs_emit(buf, "%llx\n", be64_to_cpu(vhost->login_buf->resp.capabilities));
}
/**
@@ -3105,7 +3101,7 @@ static ssize_t ibmvfc_show_log_level(struct device *dev,
int len;
spin_lock_irqsave(shost->host_lock, flags);
- len = snprintf(buf, PAGE_SIZE, "%d\n", vhost->log_level);
+ len = sysfs_emit(buf, "%d\n", vhost->log_level);
spin_unlock_irqrestore(shost->host_lock, flags);
return len;
}
--
1.8.3.1
^ permalink raw reply related
* [PATCH 0/3] powerpc/perf: Add Performance Monitor Counters to extended regs
From: Athira Rajeev @ 2021-02-03 6:55 UTC (permalink / raw)
To: mpe, acme, jolsa; +Cc: kjain, maddy, linuxppc-dev
Patch set to add Performance Monitor Counter SPR's as
part of extended regs in powerpc.
Patch 1/3 saves the PMC values in the perf interrupt
handler as part of per-cpu array.
Patch 2/3 adds PMC1 to PMC6 as part of the extended
regs mask.
Patch 3/3 includes perf tools side changes to add
PMC1 to PMC6 to sample_reg_mask to use with -I? option.
Athira Rajeev (3):
powerpc/perf: Include PMCs as part of per-cpu cpuhw_events struct
powerpc/perf: Expose Performance Monitor Counter SPR's as part of
extended regs
tools/perf: Add perf tools support to expose Performance Monitor
Counter SPRs as part of extended regs
arch/powerpc/include/asm/perf_event.h | 2 ++
arch/powerpc/include/uapi/asm/perf_regs.h | 28 +++++++++++++++++++------
arch/powerpc/perf/core-book3s.c | 28 +++++++++++++++++++------
arch/powerpc/perf/perf_regs.c | 13 ++++--------
tools/arch/powerpc/include/uapi/asm/perf_regs.h | 28 +++++++++++++++++++------
tools/perf/arch/powerpc/include/perf_regs.h | 6 ++++++
tools/perf/arch/powerpc/util/perf_regs.c | 6 ++++++
7 files changed, 84 insertions(+), 27 deletions(-)
--
1.8.3.1
^ permalink raw reply
* [PATCH 1/3] powerpc/perf: Include PMCs as part of per-cpu cpuhw_events struct
From: Athira Rajeev @ 2021-02-03 6:55 UTC (permalink / raw)
To: mpe, acme, jolsa; +Cc: kjain, maddy, linuxppc-dev
In-Reply-To: <1612335337-1888-1-git-send-email-atrajeev@linux.vnet.ibm.com>
To support capturing of PMC's as part of extended registers, the
value of SPR's PMC1 to PMC6 has to be saved in the starting of PMI
interrupt handler. This is needed since we are resetting the
overflown PMC before creating sample and hence directly reading
SPRN_PMCx in 'perf_reg_value' will be capturing the modified value.
To solve this, add a per-cpu array as part of structure cpu_hw_events
and use this array to capture PMC values in the perf interrupt handler.
Patch also re-factor's the interrupt handler code to use this per-cpu
array instead of current local array.
Signed-off-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
---
arch/powerpc/perf/core-book3s.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 28206b1fe172..436af496e3aa 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -54,6 +54,9 @@ struct cpu_hw_events {
struct perf_branch_stack bhrb_stack;
struct perf_branch_entry bhrb_entries[BHRB_MAX_ENTRIES];
u64 ic_init;
+
+ /* Store the PMC values */
+ unsigned long pmcs[MAX_HWEVENTS];
};
static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
@@ -2277,7 +2280,6 @@ static void __perf_event_interrupt(struct pt_regs *regs)
int i, j;
struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
struct perf_event *event;
- unsigned long val[8];
int found, active;
int nmi;
@@ -2301,12 +2303,12 @@ static void __perf_event_interrupt(struct pt_regs *regs)
/* Read all the PMCs since we'll need them a bunch of times */
for (i = 0; i < ppmu->n_counter; ++i)
- val[i] = read_pmc(i + 1);
+ cpuhw->pmcs[i] = read_pmc(i + 1);
/* Try to find what caused the IRQ */
found = 0;
for (i = 0; i < ppmu->n_counter; ++i) {
- if (!pmc_overflow(val[i]))
+ if (!pmc_overflow(cpuhw->pmcs[i]))
continue;
if (is_limited_pmc(i + 1))
continue; /* these won't generate IRQs */
@@ -2321,7 +2323,7 @@ static void __perf_event_interrupt(struct pt_regs *regs)
event = cpuhw->event[j];
if (event->hw.idx == (i + 1)) {
active = 1;
- record_and_restart(event, val[i], regs);
+ record_and_restart(event, cpuhw->pmcs[i], regs);
break;
}
}
@@ -2335,11 +2337,11 @@ static void __perf_event_interrupt(struct pt_regs *regs)
event = cpuhw->event[i];
if (!event->hw.idx || is_limited_pmc(event->hw.idx))
continue;
- if (pmc_overflow_power7(val[event->hw.idx - 1])) {
+ if (pmc_overflow_power7(cpuhw->pmcs[event->hw.idx - 1])) {
/* event has overflowed in a buggy way*/
found = 1;
record_and_restart(event,
- val[event->hw.idx - 1],
+ cpuhw->pmcs[event->hw.idx - 1],
regs);
}
}
@@ -2356,6 +2358,9 @@ static void __perf_event_interrupt(struct pt_regs *regs)
*/
write_mmcr0(cpuhw, cpuhw->mmcr.mmcr0);
+ /* Clear the cpuhw->pmcs */
+ memset(&cpuhw->pmcs, 0, sizeof(cpuhw->pmcs));
+
if (nmi)
nmi_exit();
else
--
1.8.3.1
^ permalink raw reply related
* [PATCH 2/3] powerpc/perf: Expose Performance Monitor Counter SPR's as part of extended regs
From: Athira Rajeev @ 2021-02-03 6:55 UTC (permalink / raw)
To: mpe, acme, jolsa; +Cc: kjain, maddy, linuxppc-dev
In-Reply-To: <1612335337-1888-1-git-send-email-atrajeev@linux.vnet.ibm.com>
Currently Monitor Mode Control Registers and Sampling registers are
part of extended regs. Patch adds support to include Performance Monitor
Counter Registers (PMC1 to PMC6 ) as part of extended registers.
PMCs are saved in the perf interrupt handler as part of
per-cpu array 'pmcs' in struct cpu_hw_events. While capturing
the register values for extended regs, fetch these saved PMC values.
Simplified the PERF_REG_PMU_MASK_300/31 definition to include PMU
SPRs MMCR0 to PMC6. Exclude the unsupported SPRs (MMCR3, SIER2, SIER3)
from extended mask value for CPU_FTR_ARCH_300 in the new definition.
PERF_REG_EXTENDED_MAX is used to check if any index beyond the extended
registers is requested in the sample. Have one PERF_REG_EXTENDED_MAX
for CPU_FTR_ARCH_300/CPU_FTR_ARCH_31 since perf_reg_validate function
already checks the extended mask for the presence of any unsupported
register.
Signed-off-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/perf_event.h | 2 ++
arch/powerpc/include/uapi/asm/perf_regs.h | 28 ++++++++++++++++++++++------
arch/powerpc/perf/core-book3s.c | 11 +++++++++++
arch/powerpc/perf/perf_regs.c | 13 ++++---------
4 files changed, 39 insertions(+), 15 deletions(-)
diff --git a/arch/powerpc/include/asm/perf_event.h b/arch/powerpc/include/asm/perf_event.h
index daec64d41b44..164e910bf654 100644
--- a/arch/powerpc/include/asm/perf_event.h
+++ b/arch/powerpc/include/asm/perf_event.h
@@ -14,6 +14,7 @@
#include <asm/perf_event_server.h>
#else
static inline bool is_sier_available(void) { return false; }
+static inline unsigned long get_pmcs_ext_regs(int idx) { return 0; }
#endif
#ifdef CONFIG_FSL_EMB_PERF_EVENT
@@ -40,6 +41,7 @@
/* To support perf_regs sier update */
extern bool is_sier_available(void);
+extern unsigned long get_pmcs_ext_regs(int idx);
/* To define perf extended regs mask value */
extern u64 PERF_REG_EXTENDED_MASK;
#define PERF_REG_EXTENDED_MASK PERF_REG_EXTENDED_MASK
diff --git a/arch/powerpc/include/uapi/asm/perf_regs.h b/arch/powerpc/include/uapi/asm/perf_regs.h
index bdf5f10f8b9f..578b3ee86105 100644
--- a/arch/powerpc/include/uapi/asm/perf_regs.h
+++ b/arch/powerpc/include/uapi/asm/perf_regs.h
@@ -55,17 +55,33 @@ enum perf_event_powerpc_regs {
PERF_REG_POWERPC_MMCR3,
PERF_REG_POWERPC_SIER2,
PERF_REG_POWERPC_SIER3,
+ PERF_REG_POWERPC_PMC1,
+ PERF_REG_POWERPC_PMC2,
+ PERF_REG_POWERPC_PMC3,
+ PERF_REG_POWERPC_PMC4,
+ PERF_REG_POWERPC_PMC5,
+ PERF_REG_POWERPC_PMC6,
/* Max regs without the extended regs */
PERF_REG_POWERPC_MAX = PERF_REG_POWERPC_MMCRA + 1,
};
#define PERF_REG_PMU_MASK ((1ULL << PERF_REG_POWERPC_MAX) - 1)
-/* PERF_REG_EXTENDED_MASK value for CPU_FTR_ARCH_300 */
-#define PERF_REG_PMU_MASK_300 (((1ULL << (PERF_REG_POWERPC_MMCR2 + 1)) - 1) - PERF_REG_PMU_MASK)
-/* PERF_REG_EXTENDED_MASK value for CPU_FTR_ARCH_31 */
-#define PERF_REG_PMU_MASK_31 (((1ULL << (PERF_REG_POWERPC_SIER3 + 1)) - 1) - PERF_REG_PMU_MASK)
+/* Exclude MMCR3, SIER2, SIER3 for CPU_FTR_ARCH_300 */
+#define PERF_EXCLUDE_REG_EXT_300 (7ULL << PERF_REG_POWERPC_MMCR3)
-#define PERF_REG_MAX_ISA_300 (PERF_REG_POWERPC_MMCR2 + 1)
-#define PERF_REG_MAX_ISA_31 (PERF_REG_POWERPC_SIER3 + 1)
+/*
+ * PERF_REG_EXTENDED_MASK value for CPU_FTR_ARCH_300
+ * includes 9 SPRS from MMCR0 to PMC6 excluding the
+ * unsupported SPRS in PERF_EXCLUDE_REG_EXT_300.
+ */
+#define PERF_REG_PMU_MASK_300 ((0xfffULL << PERF_REG_POWERPC_MMCR0) - PERF_EXCLUDE_REG_EXT_300)
+
+/*
+ * PERF_REG_EXTENDED_MASK value for CPU_FTR_ARCH_31
+ * includes 12 SPRs from MMCR0 to PMC6.
+ */
+#define PERF_REG_PMU_MASK_31 (0xfffULL << PERF_REG_POWERPC_MMCR0)
+
+#define PERF_REG_EXTENDED_MAX (PERF_REG_POWERPC_PMC6 + 1)
#endif /* _UAPI_ASM_POWERPC_PERF_REGS_H */
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 436af496e3aa..6ffc18b7e80b 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -150,6 +150,17 @@ bool is_sier_available(void)
return false;
}
+/*
+ * Return PMC value corresponding to the
+ * index passed.
+ */
+unsigned long get_pmcs_ext_regs(int idx)
+{
+ struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
+
+ return cpuhw->pmcs[idx];
+}
+
static bool regs_use_siar(struct pt_regs *regs)
{
/*
diff --git a/arch/powerpc/perf/perf_regs.c b/arch/powerpc/perf/perf_regs.c
index 6f681b105eec..b931eed482c9 100644
--- a/arch/powerpc/perf/perf_regs.c
+++ b/arch/powerpc/perf/perf_regs.c
@@ -75,6 +75,8 @@
static u64 get_ext_regs_value(int idx)
{
switch (idx) {
+ case PERF_REG_POWERPC_PMC1 ... PERF_REG_POWERPC_PMC6:
+ return get_pmcs_ext_regs(idx - PERF_REG_POWERPC_PMC1);
case PERF_REG_POWERPC_MMCR0:
return mfspr(SPRN_MMCR0);
case PERF_REG_POWERPC_MMCR1:
@@ -95,13 +97,6 @@ static u64 get_ext_regs_value(int idx)
u64 perf_reg_value(struct pt_regs *regs, int idx)
{
- u64 perf_reg_extended_max = PERF_REG_POWERPC_MAX;
-
- if (cpu_has_feature(CPU_FTR_ARCH_31))
- perf_reg_extended_max = PERF_REG_MAX_ISA_31;
- else if (cpu_has_feature(CPU_FTR_ARCH_300))
- perf_reg_extended_max = PERF_REG_MAX_ISA_300;
-
if (idx == PERF_REG_POWERPC_SIER &&
(IS_ENABLED(CONFIG_FSL_EMB_PERF_EVENT) ||
IS_ENABLED(CONFIG_PPC32) ||
@@ -113,14 +108,14 @@ u64 perf_reg_value(struct pt_regs *regs, int idx)
IS_ENABLED(CONFIG_PPC32)))
return 0;
- if (idx >= PERF_REG_POWERPC_MAX && idx < perf_reg_extended_max)
+ if (idx >= PERF_REG_POWERPC_MAX && idx < PERF_REG_EXTENDED_MAX)
return get_ext_regs_value(idx);
/*
* If the idx is referring to value beyond the
* supported registers, return 0 with a warning
*/
- if (WARN_ON_ONCE(idx >= perf_reg_extended_max))
+ if (WARN_ON_ONCE(idx >= PERF_REG_EXTENDED_MAX))
return 0;
return regs_get_register(regs, pt_regs_offset[idx]);
--
1.8.3.1
^ permalink raw reply related
* [PATCH 3/3] tools/perf: Add perf tools support to expose Performance Monitor Counter SPRs as part of extended regs
From: Athira Rajeev @ 2021-02-03 6:55 UTC (permalink / raw)
To: mpe, acme, jolsa; +Cc: kjain, maddy, linuxppc-dev
In-Reply-To: <1612335337-1888-1-git-send-email-atrajeev@linux.vnet.ibm.com>
To enable presenting of Performance Monitor Counter Registers
(PMC1 to PMC6) as part of extended regsiters, patch adds these
to sample_reg_mask in the tool side (to use with -I? option).
Simplified the PERF_REG_PMU_MASK_300/31 definition. Excluded the
unsupported SPRs (MMCR3, SIER2, SIER3) from extended mask value for
CPU_FTR_ARCH_300.
Signed-off-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
---
tools/arch/powerpc/include/uapi/asm/perf_regs.h | 28 +++++++++++++++++++------
tools/perf/arch/powerpc/include/perf_regs.h | 6 ++++++
tools/perf/arch/powerpc/util/perf_regs.c | 6 ++++++
3 files changed, 34 insertions(+), 6 deletions(-)
diff --git a/tools/arch/powerpc/include/uapi/asm/perf_regs.h b/tools/arch/powerpc/include/uapi/asm/perf_regs.h
index bdf5f10f8b9f..578b3ee86105 100644
--- a/tools/arch/powerpc/include/uapi/asm/perf_regs.h
+++ b/tools/arch/powerpc/include/uapi/asm/perf_regs.h
@@ -55,17 +55,33 @@ enum perf_event_powerpc_regs {
PERF_REG_POWERPC_MMCR3,
PERF_REG_POWERPC_SIER2,
PERF_REG_POWERPC_SIER3,
+ PERF_REG_POWERPC_PMC1,
+ PERF_REG_POWERPC_PMC2,
+ PERF_REG_POWERPC_PMC3,
+ PERF_REG_POWERPC_PMC4,
+ PERF_REG_POWERPC_PMC5,
+ PERF_REG_POWERPC_PMC6,
/* Max regs without the extended regs */
PERF_REG_POWERPC_MAX = PERF_REG_POWERPC_MMCRA + 1,
};
#define PERF_REG_PMU_MASK ((1ULL << PERF_REG_POWERPC_MAX) - 1)
-/* PERF_REG_EXTENDED_MASK value for CPU_FTR_ARCH_300 */
-#define PERF_REG_PMU_MASK_300 (((1ULL << (PERF_REG_POWERPC_MMCR2 + 1)) - 1) - PERF_REG_PMU_MASK)
-/* PERF_REG_EXTENDED_MASK value for CPU_FTR_ARCH_31 */
-#define PERF_REG_PMU_MASK_31 (((1ULL << (PERF_REG_POWERPC_SIER3 + 1)) - 1) - PERF_REG_PMU_MASK)
+/* Exclude MMCR3, SIER2, SIER3 for CPU_FTR_ARCH_300 */
+#define PERF_EXCLUDE_REG_EXT_300 (7ULL << PERF_REG_POWERPC_MMCR3)
-#define PERF_REG_MAX_ISA_300 (PERF_REG_POWERPC_MMCR2 + 1)
-#define PERF_REG_MAX_ISA_31 (PERF_REG_POWERPC_SIER3 + 1)
+/*
+ * PERF_REG_EXTENDED_MASK value for CPU_FTR_ARCH_300
+ * includes 9 SPRS from MMCR0 to PMC6 excluding the
+ * unsupported SPRS in PERF_EXCLUDE_REG_EXT_300.
+ */
+#define PERF_REG_PMU_MASK_300 ((0xfffULL << PERF_REG_POWERPC_MMCR0) - PERF_EXCLUDE_REG_EXT_300)
+
+/*
+ * PERF_REG_EXTENDED_MASK value for CPU_FTR_ARCH_31
+ * includes 12 SPRs from MMCR0 to PMC6.
+ */
+#define PERF_REG_PMU_MASK_31 (0xfffULL << PERF_REG_POWERPC_MMCR0)
+
+#define PERF_REG_EXTENDED_MAX (PERF_REG_POWERPC_PMC6 + 1)
#endif /* _UAPI_ASM_POWERPC_PERF_REGS_H */
diff --git a/tools/perf/arch/powerpc/include/perf_regs.h b/tools/perf/arch/powerpc/include/perf_regs.h
index 63f3ac91049f..98b6f9eabfc3 100644
--- a/tools/perf/arch/powerpc/include/perf_regs.h
+++ b/tools/perf/arch/powerpc/include/perf_regs.h
@@ -71,6 +71,12 @@
[PERF_REG_POWERPC_MMCR3] = "mmcr3",
[PERF_REG_POWERPC_SIER2] = "sier2",
[PERF_REG_POWERPC_SIER3] = "sier3",
+ [PERF_REG_POWERPC_PMC1] = "pmc1",
+ [PERF_REG_POWERPC_PMC2] = "pmc2",
+ [PERF_REG_POWERPC_PMC3] = "pmc3",
+ [PERF_REG_POWERPC_PMC4] = "pmc4",
+ [PERF_REG_POWERPC_PMC5] = "pmc5",
+ [PERF_REG_POWERPC_PMC6] = "pmc6",
};
static inline const char *perf_reg_name(int id)
diff --git a/tools/perf/arch/powerpc/util/perf_regs.c b/tools/perf/arch/powerpc/util/perf_regs.c
index 2b6d4704e3aa..8116a253f91f 100644
--- a/tools/perf/arch/powerpc/util/perf_regs.c
+++ b/tools/perf/arch/powerpc/util/perf_regs.c
@@ -68,6 +68,12 @@
SMPL_REG(mmcr3, PERF_REG_POWERPC_MMCR3),
SMPL_REG(sier2, PERF_REG_POWERPC_SIER2),
SMPL_REG(sier3, PERF_REG_POWERPC_SIER3),
+ SMPL_REG(pmc1, PERF_REG_POWERPC_PMC1),
+ SMPL_REG(pmc2, PERF_REG_POWERPC_PMC2),
+ SMPL_REG(pmc3, PERF_REG_POWERPC_PMC3),
+ SMPL_REG(pmc4, PERF_REG_POWERPC_PMC4),
+ SMPL_REG(pmc5, PERF_REG_POWERPC_PMC5),
+ SMPL_REG(pmc6, PERF_REG_POWERPC_PMC6),
SMPL_REG_END
};
--
1.8.3.1
^ permalink raw reply related
* [powerpc:fixes-test] BUILD SUCCESS 24321ac668e452a4942598533d267805f291fdc9
From: kernel test robot @ 2021-02-03 7:30 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git fixes-test
branch HEAD: 24321ac668e452a4942598533d267805f291fdc9 powerpc/64/signal: Fix regression in __kernel_sigtramp_rt64() semantics
elapsed time: 725m
configs tested: 171
configs skipped: 4
The following configs have been built successfully.
More configs may be tested in the coming days.
gcc tested configs:
arm defconfig
arm64 allyesconfig
arm64 defconfig
arm allyesconfig
arm allmodconfig
arm omap2plus_defconfig
h8300 edosk2674_defconfig
arm ep93xx_defconfig
h8300 defconfig
arm viper_defconfig
c6x evmc6457_defconfig
powerpc mgcoge_defconfig
mips qi_lb60_defconfig
mips nlm_xlr_defconfig
powerpc kilauea_defconfig
arm socfpga_defconfig
mips malta_kvm_defconfig
powerpc klondike_defconfig
powerpc ep8248e_defconfig
parisc generic-32bit_defconfig
riscv defconfig
powerpc mpc5200_defconfig
arm pxa_defconfig
powerpc acadia_defconfig
m68k m5272c3_defconfig
arm neponset_defconfig
powerpc tqm8xx_defconfig
m68k m5407c3_defconfig
arm lubbock_defconfig
arm dove_defconfig
mips vocore2_defconfig
mips loongson1c_defconfig
mips malta_defconfig
sh apsh4ad0a_defconfig
alpha allyesconfig
powerpc ge_imp3a_defconfig
xtensa xip_kc705_defconfig
m68k mvme16x_defconfig
arm collie_defconfig
openrisc or1ksim_defconfig
arm cm_x300_defconfig
sh se7206_defconfig
powerpc pq2fads_defconfig
mips allyesconfig
arm integrator_defconfig
mips bcm63xx_defconfig
sh landisk_defconfig
m68k q40_defconfig
arc vdk_hs38_smp_defconfig
arc tb10x_defconfig
c6x evmc6474_defconfig
openrisc or1klitex_defconfig
arm pcm027_defconfig
powerpc64 alldefconfig
powerpc adder875_defconfig
powerpc mpc8313_rdb_defconfig
mips mtx1_defconfig
riscv allyesconfig
arm keystone_defconfig
powerpc mpc85xx_cds_defconfig
m68k m5208evb_defconfig
powerpc warp_defconfig
xtensa audio_kc705_defconfig
sh magicpanelr2_defconfig
sh ap325rxa_defconfig
arc haps_hs_defconfig
powerpc katmai_defconfig
arm h5000_defconfig
powerpc tqm8560_defconfig
arm multi_v7_defconfig
nios2 3c120_defconfig
arm pleb_defconfig
sh se7343_defconfig
arm badge4_defconfig
powerpc holly_defconfig
mips rbtx49xx_defconfig
mips ip32_defconfig
mips maltasmvp_defconfig
nios2 10m50_defconfig
mips e55_defconfig
sh migor_defconfig
sh espt_defconfig
arm stm32_defconfig
powerpc tqm8555_defconfig
c6x evmc6472_defconfig
c6x alldefconfig
microblaze mmu_defconfig
m68k hp300_defconfig
powerpc pasemi_defconfig
m68k amiga_defconfig
sh secureedge5410_defconfig
um i386_defconfig
powerpc storcenter_defconfig
mips maltaup_xpa_defconfig
mips lemote2f_defconfig
arm realview_defconfig
m68k mvme147_defconfig
mips bmips_stb_defconfig
powerpc cm5200_defconfig
powerpc skiroot_defconfig
microblaze defconfig
powerpc allyesconfig
powerpc mpc832x_rdb_defconfig
powerpc fsp2_defconfig
powerpc ppc40x_defconfig
ia64 allmodconfig
ia64 defconfig
ia64 allyesconfig
m68k allmodconfig
m68k defconfig
m68k allyesconfig
nios2 defconfig
arc allyesconfig
nds32 allnoconfig
c6x allyesconfig
nds32 defconfig
nios2 allyesconfig
csky defconfig
alpha defconfig
xtensa allyesconfig
h8300 allyesconfig
arc defconfig
sh allmodconfig
parisc defconfig
s390 allyesconfig
parisc allyesconfig
s390 defconfig
i386 allyesconfig
sparc allyesconfig
sparc defconfig
i386 tinyconfig
i386 defconfig
mips allmodconfig
powerpc allmodconfig
powerpc allnoconfig
i386 randconfig-a001-20210202
i386 randconfig-a005-20210202
i386 randconfig-a003-20210202
i386 randconfig-a006-20210202
i386 randconfig-a002-20210202
i386 randconfig-a004-20210202
x86_64 randconfig-a013-20210202
x86_64 randconfig-a014-20210202
x86_64 randconfig-a015-20210202
x86_64 randconfig-a016-20210202
x86_64 randconfig-a011-20210202
x86_64 randconfig-a012-20210202
i386 randconfig-a013-20210202
i386 randconfig-a016-20210202
i386 randconfig-a014-20210202
i386 randconfig-a012-20210202
i386 randconfig-a015-20210202
i386 randconfig-a011-20210202
riscv nommu_k210_defconfig
riscv nommu_virt_defconfig
riscv allnoconfig
riscv rv32_defconfig
riscv allmodconfig
x86_64 rhel
x86_64 allyesconfig
x86_64 rhel-7.6-kselftests
x86_64 defconfig
x86_64 rhel-8.3
x86_64 rhel-8.3-kbuiltin
x86_64 kexec
clang tested configs:
x86_64 randconfig-a006-20210202
x86_64 randconfig-a001-20210202
x86_64 randconfig-a005-20210202
x86_64 randconfig-a002-20210202
x86_64 randconfig-a004-20210202
x86_64 randconfig-a003-20210202
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
^ permalink raw reply
* [powerpc:next-test] BUILD REGRESSION a4d002e384ba1909c1c03799603f00c5909d6097
From: kernel test robot @ 2021-02-03 7:32 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next-test
branch HEAD: a4d002e384ba1909c1c03799603f00c5909d6097 powerpc: remove unneeded semicolons
Error/Warning reports:
https://lore.kernel.org/linuxppc-dev/202102030601.iJkLZMTX-lkp@intel.com
https://lore.kernel.org/linuxppc-dev/202102031026.HFU4AdQ8-lkp@intel.com
https://lore.kernel.org/linuxppc-dev/202102031251.hW2Tyxj2-lkp@intel.com
Error/Warning in current branch:
arch/powerpc/kernel/pci-common.c:1704:12: error: no previous prototype for function 'discover_phbs' [-Werror,-Wmissing-prototypes]
arch/powerpc/kernel/tau_6xx.c:103:1: error: no previous prototype for function 'DEFINE_INTERRUPT_HANDLER_ASYNC' [-Werror,-Wmissing-prototypes]
arch/powerpc/kernel/tau_6xx.c:103:1: warning: no previous prototype for function 'DEFINE_INTERRUPT_HANDLER_ASYNC' [-Wmissing-prototypes]
arch/powerpc/kernel/tau_6xx.c:103:31: error: this old-style function definition is not preceded by a prototype [-Werror,-Wstrict-prototypes]
arch/powerpc/kernel/tau_6xx.c:110:1: error: non-void function does not return a value [-Werror,-Wreturn-type]
arch/powerpc/kernel/tau_6xx.c:113:1: error: non-void function does not return a value [-Werror,-Wreturn-type]
Error/Warning ids grouped by kconfigs:
clang_recent_errors
|-- powerpc-randconfig-r003-20210202
| |-- arch-powerpc-kernel-tau_6xx.c:error:non-void-function-does-not-return-a-value-Werror-Wreturn-type
| |-- arch-powerpc-kernel-tau_6xx.c:error:this-old-style-function-definition-is-not-preceded-by-a-prototype-Werror-Wstrict-prototypes
| `-- arch-powerpc-kernel-tau_6xx.c:warning:no-previous-prototype-for-function-DEFINE_INTERRUPT_HANDLER_ASYNC
`-- powerpc64-randconfig-r035-20210202
|-- arch-powerpc-kernel-pci-common.c:error:no-previous-prototype-for-function-discover_phbs-Werror-Wmissing-prototypes
|-- arch-powerpc-kernel-tau_6xx.c:error:no-previous-prototype-for-function-DEFINE_INTERRUPT_HANDLER_ASYNC-Werror-Wmissing-prototypes
|-- arch-powerpc-kernel-tau_6xx.c:error:non-void-function-does-not-return-a-value-Werror-Wreturn-type
`-- arch-powerpc-kernel-tau_6xx.c:error:this-old-style-function-definition-is-not-preceded-by-a-prototype-Werror-Wstrict-prototypes
elapsed time: 727m
configs tested: 164
configs skipped: 3
gcc tested configs:
arm defconfig
arm64 allyesconfig
arm64 defconfig
arm allyesconfig
arm allmodconfig
arm omap2plus_defconfig
h8300 edosk2674_defconfig
arm ep93xx_defconfig
h8300 defconfig
arm viper_defconfig
c6x evmc6457_defconfig
powerpc mgcoge_defconfig
mips qi_lb60_defconfig
mips nlm_xlr_defconfig
powerpc kilauea_defconfig
arm socfpga_defconfig
mips malta_kvm_defconfig
powerpc klondike_defconfig
powerpc ep8248e_defconfig
parisc generic-32bit_defconfig
powerpc mpc5200_defconfig
arm pxa_defconfig
powerpc acadia_defconfig
m68k m5272c3_defconfig
arm neponset_defconfig
powerpc tqm8xx_defconfig
m68k m5407c3_defconfig
arm lubbock_defconfig
arm dove_defconfig
mips vocore2_defconfig
mips loongson1c_defconfig
mips malta_defconfig
sh apsh4ad0a_defconfig
powerpc ge_imp3a_defconfig
xtensa xip_kc705_defconfig
m68k mvme16x_defconfig
arm collie_defconfig
arm cm_x300_defconfig
sh se7206_defconfig
powerpc pq2fads_defconfig
mips allyesconfig
arm integrator_defconfig
mips bcm63xx_defconfig
sh landisk_defconfig
m68k q40_defconfig
arc vdk_hs38_smp_defconfig
arc tb10x_defconfig
c6x evmc6474_defconfig
openrisc or1klitex_defconfig
arm pcm027_defconfig
powerpc adder875_defconfig
powerpc mpc8313_rdb_defconfig
mips mtx1_defconfig
riscv allyesconfig
arm keystone_defconfig
powerpc mpc85xx_cds_defconfig
m68k m5208evb_defconfig
powerpc warp_defconfig
xtensa audio_kc705_defconfig
sh magicpanelr2_defconfig
sh ap325rxa_defconfig
arc haps_hs_defconfig
powerpc katmai_defconfig
arm h5000_defconfig
powerpc tqm8560_defconfig
arm multi_v7_defconfig
nios2 3c120_defconfig
arm pleb_defconfig
sh se7343_defconfig
arm badge4_defconfig
powerpc holly_defconfig
mips rbtx49xx_defconfig
mips ip32_defconfig
mips maltasmvp_defconfig
sh espt_defconfig
arm stm32_defconfig
powerpc tqm8555_defconfig
c6x evmc6472_defconfig
c6x alldefconfig
microblaze mmu_defconfig
um i386_defconfig
powerpc storcenter_defconfig
mips maltaup_xpa_defconfig
mips lemote2f_defconfig
arm realview_defconfig
m68k mvme147_defconfig
powerpc64 alldefconfig
mips bmips_stb_defconfig
powerpc cm5200_defconfig
powerpc skiroot_defconfig
microblaze defconfig
powerpc allyesconfig
powerpc mpc832x_rdb_defconfig
powerpc fsp2_defconfig
powerpc ppc40x_defconfig
sh migor_defconfig
ia64 allmodconfig
ia64 defconfig
ia64 allyesconfig
m68k allmodconfig
m68k defconfig
m68k allyesconfig
nios2 defconfig
arc allyesconfig
nds32 allnoconfig
c6x allyesconfig
nds32 defconfig
nios2 allyesconfig
csky defconfig
alpha defconfig
alpha allyesconfig
xtensa allyesconfig
h8300 allyesconfig
arc defconfig
sh allmodconfig
parisc defconfig
s390 allyesconfig
parisc allyesconfig
s390 defconfig
i386 allyesconfig
sparc allyesconfig
sparc defconfig
i386 tinyconfig
i386 defconfig
mips allmodconfig
powerpc allmodconfig
powerpc allnoconfig
i386 randconfig-a001-20210202
i386 randconfig-a005-20210202
i386 randconfig-a003-20210202
i386 randconfig-a006-20210202
i386 randconfig-a002-20210202
i386 randconfig-a004-20210202
x86_64 randconfig-a013-20210202
x86_64 randconfig-a014-20210202
x86_64 randconfig-a015-20210202
x86_64 randconfig-a016-20210202
x86_64 randconfig-a011-20210202
x86_64 randconfig-a012-20210202
i386 randconfig-a013-20210202
i386 randconfig-a016-20210202
i386 randconfig-a014-20210202
i386 randconfig-a012-20210202
i386 randconfig-a015-20210202
i386 randconfig-a011-20210202
riscv nommu_k210_defconfig
riscv nommu_virt_defconfig
riscv allnoconfig
riscv defconfig
riscv rv32_defconfig
riscv allmodconfig
x86_64 rhel
x86_64 allyesconfig
x86_64 rhel-7.6-kselftests
x86_64 defconfig
x86_64 rhel-8.3
x86_64 rhel-8.3-kbuiltin
x86_64 kexec
clang tested configs:
x86_64 randconfig-a006-20210202
x86_64 randconfig-a001-20210202
x86_64 randconfig-a005-20210202
x86_64 randconfig-a002-20210202
x86_64 randconfig-a004-20210202
x86_64 randconfig-a003-20210202
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
^ permalink raw reply
* Re: [PATCH kernel] powerpc/kuap: Restore AMR after replaying soft interrupts
From: Michal Suchánek @ 2021-02-03 8:45 UTC (permalink / raw)
To: Alexey Kardashevskiy; +Cc: linuxppc-dev, Nicholas Piggin
In-Reply-To: <20210202091541.36499-1-aik@ozlabs.ru>
Hello,
On Tue, Feb 02, 2021 at 08:15:41PM +1100, Alexey Kardashevskiy wrote:
> Since de78a9c "powerpc: Add a framework for Kernel Userspace Access
> Protection", user access helpers call user_{read|write}_access_{begin|end}
> when user space access is allowed.
>
> 890274c "powerpc/64s: Implement KUAP for Radix MMU" made the mentioned
> helpers program a AMR special register to allow such access for a short
> period of time, most of the time AMR is expected to block user memory
> access by the kernel.
>
> Since the code accesses the user space memory, unsafe_get_user()
> calls might_fault() which calls arch_local_irq_restore() if either
> CONFIG_PROVE_LOCKING or CONFIG_DEBUG_ATOMIC_SLEEP is enabled.
> arch_local_irq_restore() then attempts to replay pending soft interrupts
> as KUAP regions have hardware interrupts enabled.
> If a pending interrupt happens to do user access (performance interrupts
> do that), it enables access for a short period of time so after returning
> from the replay, the user access state remains blocked and if a user page
> fault happens - "Bug: Read fault blocked by AMR!" appears and SIGSEGV is
> sent.
>
> This saves/restores AMR when replaying interrupts.
>
> This adds a check if AMR was not blocked when before replaying interrupts.
>
> Found by syzkaller. The call stack for the bug is:
>
> copy_from_user_nofault+0xf8/0x250
> perf_callchain_user_64+0x3d8/0x8d0
> perf_callchain_user+0x38/0x50
> get_perf_callchain+0x28c/0x300
> perf_callchain+0xb0/0x130
> perf_prepare_sample+0x364/0xbf0
> perf_event_output_forward+0xe0/0x280
> __perf_event_overflow+0xa4/0x240
> perf_swevent_hrtimer+0x1d4/0x1f0
> __hrtimer_run_queues+0x328/0x900
> hrtimer_interrupt+0x128/0x350
> timer_interrupt+0x180/0x600
> replay_soft_interrupts+0x21c/0x4f0
> arch_local_irq_restore+0x94/0x150
> lock_is_held_type+0x140/0x200
> ___might_sleep+0x220/0x330
> __might_fault+0x88/0x120
> do_strncpy_from_user+0x108/0x2b0
> strncpy_from_user+0x1d0/0x2a0
> getname_flags+0x88/0x2c0
> do_sys_openat2+0x2d4/0x5f0
> do_sys_open+0xcc/0x140
> system_call_exception+0x160/0x240
> system_call_common+0xf0/0x27c
>
Can we get a Fixes tag?
Thanks
Michal
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
> ---
> Changes:
> v3:
> * do not block/unblock if AMR was blocked
> * reverted move of AMR_KUAP_***
> * added pr_warn
>
> v2:
> * fixed compile on hash
> * moved get/set to arch_local_irq_restore
> * block KUAP before replaying
>
> ---
>
> This is an example:
>
> ------------[ cut here ]------------
> Bug: Read fault blocked by AMR!
> WARNING: CPU: 0 PID: 1603 at /home/aik/p/kernel/arch/powerpc/include/asm/book3s/64/kup-radix.h:145 __do_page_fau
>
> Modules linked in:
> CPU: 0 PID: 1603 Comm: amr Not tainted 5.10.0-rc6_v5.10-rc6_a+fstn1 #24
> NIP: c00000000009ece8 LR: c00000000009ece4 CTR: 0000000000000000
> REGS: c00000000dc63560 TRAP: 0700 Not tainted (5.10.0-rc6_v5.10-rc6_a+fstn1)
> MSR: 8000000000021033 <SF,ME,IR,DR,RI,LE> CR: 28002888 XER: 20040000
> CFAR: c0000000001fa928 IRQMASK: 1
> GPR00: c00000000009ece4 c00000000dc637f0 c000000002397600 000000000000001f
> GPR04: c0000000020eb318 0000000000000000 c00000000dc63494 0000000000000027
> GPR08: c00000007fe4de68 c00000000dfe9180 0000000000000000 0000000000000001
> GPR12: 0000000000002000 c0000000030a0000 0000000000000000 0000000000000000
> GPR16: 0000000000000000 0000000000000000 0000000000000000 bfffffffffffffff
> GPR20: 0000000000000000 c0000000134a4020 c0000000019c2218 0000000000000fe0
> GPR24: 0000000000000000 0000000000000000 c00000000d106200 0000000040000000
> GPR28: 0000000000000000 0000000000000300 c00000000dc63910 c000000001946730
> NIP [c00000000009ece8] __do_page_fault+0xb38/0xde0
> LR [c00000000009ece4] __do_page_fault+0xb34/0xde0
> Call Trace:
> [c00000000dc637f0] [c00000000009ece4] __do_page_fault+0xb34/0xde0 (unreliable)
> [c00000000dc638a0] [c00000000000c968] handle_page_fault+0x10/0x2c
> --- interrupt: 300 at strncpy_from_user+0x290/0x440
> LR = strncpy_from_user+0x284/0x440
> [c00000000dc63ba0] [c000000000c3dcb0] strncpy_from_user+0x2f0/0x440 (unreliable)
> [c00000000dc63c30] [c00000000068b888] getname_flags+0x88/0x2c0
> [c00000000dc63c90] [c000000000662a44] do_sys_openat2+0x2d4/0x5f0
> [c00000000dc63d30] [c00000000066560c] do_sys_open+0xcc/0x140
> [c00000000dc63dc0] [c000000000045e10] system_call_exception+0x160/0x240
> [c00000000dc63e20] [c00000000000da60] system_call_common+0xf0/0x27c
> Instruction dump:
> 409c0048 3fe2ff5b 3bfff128 fac10060 fae10068 482f7a85 60000000 3c62ff5b
> 7fe4fb78 3863f250 4815bbd9 60000000 <0fe00000> 3c62ff5b 3863f2b8 4815c8b5
> irq event stamp: 254
> hardirqs last enabled at (253): [<c000000000019550>] arch_local_irq_restore+0xa0/0x150
> hardirqs last disabled at (254): [<c000000000008a10>] data_access_common_virt+0x1b0/0x1d0
> softirqs last enabled at (0): [<c0000000001f6d5c>] copy_process+0x78c/0x2120
> softirqs last disabled at (0): [<0000000000000000>] 0x0
> ---[ end trace ba98aec5151f3aeb ]---
> ---
> arch/powerpc/kernel/irq.c | 27 ++++++++++++++++++++++++++-
> 1 file changed, 26 insertions(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
> index cc7a6271b6b4..592abc798826 100644
> --- a/arch/powerpc/kernel/irq.c
> +++ b/arch/powerpc/kernel/irq.c
> @@ -269,6 +269,23 @@ void replay_soft_interrupts(void)
> }
> }
>
> +#if defined(CONFIG_PPC_BOOK3S_64) && defined(CONFIG_PPC_KUAP)
> +static inline void replay_soft_interrupts_irqrestore(void)
> +{
> + unsigned long kuap_state = get_kuap();
> +
> + if (kuap_state != AMR_KUAP_BLOCKED)
> + set_kuap(AMR_KUAP_BLOCKED);
> +
> + replay_soft_interrupts();
> +
> + if (kuap_state != AMR_KUAP_BLOCKED)
> + set_kuap(kuap_state);
> +}
> +#else
> +#define replay_soft_interrupts_irqrestore() replay_soft_interrupts()
> +#endif
> +
> notrace void arch_local_irq_restore(unsigned long mask)
> {
> unsigned char irq_happened;
> @@ -278,6 +295,14 @@ notrace void arch_local_irq_restore(unsigned long mask)
> if (mask)
> return;
>
> + /*
> + * It fires if anything calls local_irq_enable or restore when
> + * KUAP is enabled, and the code handles that just fine by saving
> + * and re-locking AMR but we would like to remove those calls,
> + * hence the warning.
> + */
> + kuap_check_amr();
> +
> /*
> * From this point onward, we can take interrupts, preempt,
> * etc... unless we got hard-disabled. We check if an event
> @@ -332,7 +357,7 @@ notrace void arch_local_irq_restore(unsigned long mask)
> irq_soft_mask_set(IRQS_ALL_DISABLED);
> trace_hardirqs_off();
>
> - replay_soft_interrupts();
> + replay_soft_interrupts_irqrestore();
> local_paca->irq_happened = 0;
>
> trace_hardirqs_on();
> --
> 2.17.1
>
^ permalink raw reply
* [PATCH] powerpc/perf: Record counter overflow always if SAMPLE_IP is unset
From: Athira Rajeev @ 2021-02-03 8:54 UTC (permalink / raw)
To: mpe; +Cc: maddy, linuxppc-dev
While sampling for marked events, currently we record the sample only
if the SIAR valid bit of Sampled Instruction Event Register (SIER) is
set. SIAR_VALID bit is used for fetching the instruction address from
Sampled Instruction Address Register(SIAR). But there are some usecases,
where the user is interested only in the PMU stats at each counter
overflow and the exact IP of the overflow event is not required.
Dropping SIAR invalid samples will fail to record some of the counter
overflows in such cases.
Example of such usecase is dumping the PMU stats (event counts)
after some regular amount of instructions/events from the userspace
(ex: via ptrace). Here counter overflow is indicated to userspace via
signal handler, and captured by monitoring and enabling I/O
signaling on the event file descriptor. In these cases, we expect to
get sample/overflow indication after each specified sample_period.
Perf event attribute will not have PERF_SAMPLE_IP set in the
sample_type if exact IP of the overflow event is not requested. So
while profiling if SAMPLE_IP is not set, just record the counter overflow
irrespective of SIAR_VALID check.
Signed-off-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
---
arch/powerpc/perf/core-book3s.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 28206b1fe172..bb4828a05e4d 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -2166,10 +2166,16 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
* address even when freeze on supervisor state (kernel) is set in
* MMCR2. Check attr.exclude_kernel and address to drop the sample in
* these cases.
+ *
+ * If address is not requested in the sample
+ * via PERF_SAMPLE_IP, just record that sample
+ * irrespective of SIAR valid check.
*/
- if (event->attr.exclude_kernel && record)
- if (is_kernel_addr(mfspr(SPRN_SIAR)))
+ if (event->attr.exclude_kernel && record) {
+ if (is_kernel_addr(mfspr(SPRN_SIAR)) && (event->attr.sample_type & PERF_SAMPLE_IP))
record = 0;
+ } else if (!record && !(event->attr.sample_type & PERF_SAMPLE_IP))
+ record = 1;
/*
* Finally record data if requested.
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH 05/13] kallsyms: refactor {,module_}kallsyms_on_each_symbol
From: Petr Mladek @ 2021-02-03 8:58 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Jiri Kosina, Andrew Donnellan, linux-kbuild, David Airlie,
Masahiro Yamada, Josh Poimboeuf, Maarten Lankhorst, linux-kernel,
Maxime Ripard, live-patching, Michal Marek, Joe Lawrence,
dri-devel, Thomas Zimmermann, Jessica Yu, Frederic Barrat,
Daniel Vetter, Miroslav Benes, linuxppc-dev
In-Reply-To: <20210202121334.1361503-6-hch@lst.de>
On Tue 2021-02-02 13:13:26, Christoph Hellwig wrote:
> Require an explicit call to module_kallsyms_on_each_symbol to look
> for symbols in modules instead of the call from kallsyms_on_each_symbol,
> and acquire module_mutex inside of module_kallsyms_on_each_symbol instead
> of leaving that up to the caller. Note that this slightly changes the
> behavior for the livepatch code in that the symbols from vmlinux are not
> iterated anymore if objname is set, but that actually is the desired
> behavior in this case.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Acked-by: Miroslav Benes <mbenes@suse.cz>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Best Regards,
Petr
^ permalink raw reply
* Re: [PATCH 10/13] module: pass struct find_symbol_args to find_symbol
From: Christoph Hellwig @ 2021-02-03 9:04 UTC (permalink / raw)
To: Miroslav Benes
Cc: Petr Mladek, Jiri Kosina, Andrew Donnellan, linux-kbuild,
David Airlie, Masahiro Yamada, Josh Poimboeuf, Maarten Lankhorst,
linux-kernel, Maxime Ripard, live-patching, Michal Marek,
Joe Lawrence, dri-devel, Thomas Zimmermann, Jessica Yu,
Frederic Barrat, Daniel Vetter, linuxppc-dev, Christoph Hellwig
In-Reply-To: <alpine.LSU.2.21.2102021504550.570@pobox.suse.cz>
FYI, this is the updated version:
---
From 664ca3378deac7530fe8fc15fe73d583d3333df2 Mon Sep 17 00:00:00 2001
From: Christoph Hellwig <hch@lst.de>
Date: Wed, 20 Jan 2021 14:58:27 +0100
Subject: module: pass struct find_symbol_args to find_symbol
Simplify the calling convention by passing the find_symbol_args structure
to find_symbol instead of initializing it inside the function.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
kernel/module.c | 113 ++++++++++++++++++++++--------------------------
1 file changed, 52 insertions(+), 61 deletions(-)
diff --git a/kernel/module.c b/kernel/module.c
index ab219a16f35068..e63b16b85da68b 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -531,12 +531,7 @@ static bool find_exported_symbol_in_section(const struct symsearch *syms,
* Find an exported symbol and return it, along with, (optional) crc and
* (optional) module which owns it. Needs preempt disabled or module_mutex.
*/
-static const struct kernel_symbol *find_symbol(const char *name,
- struct module **owner,
- const s32 **crc,
- enum mod_license *license,
- bool gplok,
- bool warn)
+static bool find_symbol(struct find_symbol_arg *fsa)
{
static const struct symsearch arr[] = {
{ __start___ksymtab, __stop___ksymtab, __start___kcrctab,
@@ -556,19 +551,14 @@ static const struct kernel_symbol *find_symbol(const char *name,
GPL_ONLY, true },
#endif
};
- struct find_symbol_arg fsa = {
- .name = name,
- .gplok = gplok,
- .warn = warn,
- };
struct module *mod;
unsigned int i;
module_assert_mutex_or_preempt();
for (i = 0; i < ARRAY_SIZE(arr); i++)
- if (find_exported_symbol_in_section(&arr[i], NULL, &fsa))
- goto found;
+ if (find_exported_symbol_in_section(&arr[i], NULL, fsa))
+ return true;
list_for_each_entry_rcu(mod, &modules, list,
lockdep_is_held(&module_mutex)) {
@@ -598,21 +588,12 @@ static const struct kernel_symbol *find_symbol(const char *name,
continue;
for (i = 0; i < ARRAY_SIZE(arr); i++)
- if (find_exported_symbol_in_section(&arr[i], mod, &fsa))
- goto found;
+ if (find_exported_symbol_in_section(&arr[i], mod, fsa))
+ return true;
}
- pr_debug("Failed to find symbol %s\n", name);
- return NULL;
-
-found:
- if (owner)
- *owner = fsa.owner;
- if (crc)
- *crc = fsa.crc;
- if (license)
- *license = fsa.license;
- return fsa.sym;
+ pr_debug("Failed to find symbol %s\n", fsa->name);
+ return false;
}
/*
@@ -1074,12 +1055,15 @@ static inline void print_unload_info(struct seq_file *m, struct module *mod)
void __symbol_put(const char *symbol)
{
- struct module *owner;
+ struct find_symbol_arg fsa = {
+ .name = symbol,
+ .gplok = true,
+ };
preempt_disable();
- if (!find_symbol(symbol, &owner, NULL, NULL, true, false))
+ if (!find_symbol(&fsa))
BUG();
- module_put(owner);
+ module_put(fsa.owner);
preempt_enable();
}
EXPORT_SYMBOL(__symbol_put);
@@ -1348,19 +1332,22 @@ static int check_version(const struct load_info *info,
static inline int check_modstruct_version(const struct load_info *info,
struct module *mod)
{
- const s32 *crc;
+ struct find_symbol_arg fsa = {
+ .name = "module_layout",
+ .gplok = true,
+ };
/*
* Since this should be found in kernel (which can't be removed), no
* locking is necessary -- use preempt_disable() to placate lockdep.
*/
preempt_disable();
- if (!find_symbol("module_layout", NULL, &crc, NULL, true, false)) {
+ if (!find_symbol(&fsa)) {
preempt_enable();
BUG();
}
preempt_enable();
- return check_version(info, "module_layout", mod, crc);
+ return check_version(info, "module_layout", mod, fsa.crc);
}
/* First part is kernel version, which we ignore if module has crcs. */
@@ -1454,10 +1441,11 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,
const char *name,
char ownername[])
{
- struct module *owner;
- const struct kernel_symbol *sym;
- const s32 *crc;
- enum mod_license license;
+ struct find_symbol_arg fsa = {
+ .name = name,
+ .gplok = !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)),
+ .warn = true,
+ };
int err;
/*
@@ -1467,42 +1455,40 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,
*/
sched_annotate_sleep();
mutex_lock(&module_mutex);
- sym = find_symbol(name, &owner, &crc, &license,
- !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true);
- if (!sym)
+ if (!find_symbol(&fsa))
goto unlock;
- if (license == GPL_ONLY)
+ if (fsa.license == GPL_ONLY)
mod->using_gplonly_symbols = true;
- if (!inherit_taint(mod, owner)) {
- sym = NULL;
+ if (!inherit_taint(mod, fsa.owner)) {
+ fsa.sym = NULL;
goto getname;
}
- if (!check_version(info, name, mod, crc)) {
- sym = ERR_PTR(-EINVAL);
+ if (!check_version(info, name, mod, fsa.crc)) {
+ fsa.sym = ERR_PTR(-EINVAL);
goto getname;
}
- err = verify_namespace_is_imported(info, sym, mod);
+ err = verify_namespace_is_imported(info, fsa.sym, mod);
if (err) {
- sym = ERR_PTR(err);
+ fsa.sym = ERR_PTR(err);
goto getname;
}
- err = ref_module(mod, owner);
+ err = ref_module(mod, fsa.owner);
if (err) {
- sym = ERR_PTR(err);
+ fsa.sym = ERR_PTR(err);
goto getname;
}
getname:
/* We must make copy under the lock if we failed to get ref. */
- strncpy(ownername, module_name(owner), MODULE_NAME_LEN);
+ strncpy(ownername, module_name(fsa.owner), MODULE_NAME_LEN);
unlock:
mutex_unlock(&module_mutex);
- return sym;
+ return fsa.sym;
}
static const struct kernel_symbol *
@@ -2263,16 +2249,19 @@ static void free_module(struct module *mod)
void *__symbol_get(const char *symbol)
{
- struct module *owner;
- const struct kernel_symbol *sym;
+ struct find_symbol_arg fsa = {
+ .name = symbol,
+ .gplok = true,
+ .warn = true,
+ };
preempt_disable();
- sym = find_symbol(symbol, &owner, NULL, NULL, true, true);
- if (sym && strong_try_module_get(owner))
- sym = NULL;
+ if (!find_symbol(&fsa) || strong_try_module_get(fsa.owner)) {
+ preempt_enable();
+ return NULL;
+ }
preempt_enable();
-
- return sym ? (void *)kernel_symbol_value(sym) : NULL;
+ return (void *)kernel_symbol_value(fsa.sym);
}
EXPORT_SYMBOL_GPL(__symbol_get);
@@ -2285,7 +2274,6 @@ EXPORT_SYMBOL_GPL(__symbol_get);
static int verify_exported_symbols(struct module *mod)
{
unsigned int i;
- struct module *owner;
const struct kernel_symbol *s;
struct {
const struct kernel_symbol *sym;
@@ -2302,12 +2290,15 @@ static int verify_exported_symbols(struct module *mod)
for (i = 0; i < ARRAY_SIZE(arr); i++) {
for (s = arr[i].sym; s < arr[i].sym + arr[i].num; s++) {
- if (find_symbol(kernel_symbol_name(s), &owner, NULL,
- NULL, true, false)) {
+ struct find_symbol_arg fsa = {
+ .name = kernel_symbol_name(s),
+ .gplok = true,
+ };
+ if (find_symbol(&fsa)) {
pr_err("%s: exports duplicate symbol %s"
" (owned by %s)\n",
mod->name, kernel_symbol_name(s),
- module_name(owner));
+ module_name(fsa.owner));
return -ENOEXEC;
}
}
--
2.29.2
^ permalink raw reply related
* Re: [PATCH 10/13] module: pass struct find_symbol_args to find_symbol
From: Miroslav Benes @ 2021-02-03 9:31 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Petr Mladek, Jiri Kosina, Andrew Donnellan, linux-kbuild,
David Airlie, Masahiro Yamada, Josh Poimboeuf, Maarten Lankhorst,
linux-kernel, Maxime Ripard, live-patching, Michal Marek,
Joe Lawrence, dri-devel, Thomas Zimmermann, Jessica Yu,
Frederic Barrat, Daniel Vetter, linuxppc-dev
In-Reply-To: <20210203090418.GA7833@lst.de>
On Wed, 3 Feb 2021, Christoph Hellwig wrote:
> FYI, this is the updated version:
>
> ---
> >From 664ca3378deac7530fe8fc15fe73d583d3333df2 Mon Sep 17 00:00:00 2001
> From: Christoph Hellwig <hch@lst.de>
> Date: Wed, 20 Jan 2021 14:58:27 +0100
> Subject: module: pass struct find_symbol_args to find_symbol
>
> Simplify the calling convention by passing the find_symbol_args structure
> to find_symbol instead of initializing it inside the function.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Miroslav Benes <mbenes@suse.cz>
M
^ permalink raw reply
* Re: [PATCH v2 1/3] powerpc: sstep: Fix load and update emulation
From: Naveen N. Rao @ 2021-02-03 9:49 UTC (permalink / raw)
To: Sandipan Das; +Cc: ravi.bangoria, ananth, jniethe5, paulus, linuxppc-dev, dja
In-Reply-To: <20210203063841.431063-1-sandipan@linux.ibm.com>
On 2021/02/03 12:08PM, Sandipan Das wrote:
> The Power ISA says that the fixed-point load and update
> instructions must neither use R0 for the base address (RA)
> nor have the destination (RT) and the base address (RA) as
> the same register. In these cases, the instruction is
> invalid. This applies to the following instructions.
> * Load Byte and Zero with Update (lbzu)
> * Load Byte and Zero with Update Indexed (lbzux)
> * Load Halfword and Zero with Update (lhzu)
> * Load Halfword and Zero with Update Indexed (lhzux)
> * Load Halfword Algebraic with Update (lhau)
> * Load Halfword Algebraic with Update Indexed (lhaux)
> * Load Word and Zero with Update (lwzu)
> * Load Word and Zero with Update Indexed (lwzux)
> * Load Word Algebraic with Update Indexed (lwaux)
> * Load Doubleword with Update (ldu)
> * Load Doubleword with Update Indexed (ldux)
>
> However, the following behaviour is observed using some
> invalid opcodes where RA = RT.
>
> An userspace program using an invalid instruction word like
> 0xe9ce0001, i.e. "ldu r14, 0(r14)", runs and exits without
> getting terminated abruptly. The instruction performs the
> load operation but does not write the effective address to
> the base address register.
While the processor (p8 in my test) doesn't seem to be throwing an
exception, I don't think it is necessarily loading the value. Qemu
throws an exception though. It's probably best to term the behavior as
being undefined.
> Attaching an uprobe at that
> instruction's address results in emulation which writes the
> effective address to the base register. Thus, the final value
> of the base address register is different.
>
> To remove any inconsistencies, this adds an additional check
> for the aforementioned instructions to make sure that they
> are treated as unknown by the emulation infrastructure when
> RA = 0 or RA = RT. The kernel will then fallback to executing
> the instruction on hardware.
>
> Fixes: 0016a4cf5582 ("powerpc: Emulate most Book I instructions in emulate_step()")
> Reviewed-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
> Signed-off-by: Sandipan Das <sandipan@linux.ibm.com>
> ---
> Previous versions can be found at:
> v1: https://lore.kernel.org/linuxppc-dev/20201119054139.244083-1-sandipan@linux.ibm.com/
>
> Changes in v2:
> - Jump to unknown_opcode instead of returning -1 for invalid
> instruction forms.
>
> ---
> arch/powerpc/lib/sstep.c | 22 ++++++++++++++++++++++
> 1 file changed, 22 insertions(+)
Wouldn't it be easier to just do the below at the end? Or, am I missing something?
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index ede093e9623472..a2d726d2a5e9d1 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -2980,6 +2980,10 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
}
#endif /* CONFIG_VSX */
+ if (GETTYPE(op->type) == LOAD && (op->type & UPDATE) &&
+ (ra == 0 || ra == rd))
+ goto unknown_opcode;
+
return 0;
logical_done:
- Naveen
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox